summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--3rdparty/clucene/APACHE.license201
-rw-r--r--3rdparty/clucene/AUTHORS22
-rw-r--r--3rdparty/clucene/COPYING30
-rw-r--r--3rdparty/clucene/ChangeLog0
-rw-r--r--3rdparty/clucene/LGPL.license475
-rw-r--r--3rdparty/clucene/README92
-rw-r--r--3rdparty/clucene/src/CLucene.h38
-rw-r--r--3rdparty/clucene/src/CLucene/CLBackwards.h87
-rw-r--r--3rdparty/clucene/src/CLucene/CLConfig.h304
-rw-r--r--3rdparty/clucene/src/CLucene/CLMonolithic.cpp115
-rw-r--r--3rdparty/clucene/src/CLucene/LuceneThreads.h72
-rw-r--r--3rdparty/clucene/src/CLucene/StdHeader.cpp134
-rw-r--r--3rdparty/clucene/src/CLucene/StdHeader.h501
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/AnalysisHeader.cpp200
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/AnalysisHeader.h234
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/Analyzers.cpp389
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/Analyzers.h309
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/standard/StandardAnalyzer.cpp46
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/standard/StandardAnalyzer.h47
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/standard/StandardFilter.cpp58
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/standard/StandardFilter.h37
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizer.cpp446
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizer.h88
-rw-r--r--3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizerConstants.h30
-rw-r--r--3rdparty/clucene/src/CLucene/config/CompilerAcc.h166
-rw-r--r--3rdparty/clucene/src/CLucene/config/CompilerBcb.h68
-rw-r--r--3rdparty/clucene/src/CLucene/config/CompilerGcc.h175
-rw-r--r--3rdparty/clucene/src/CLucene/config/CompilerMsvc.h136
-rw-r--r--3rdparty/clucene/src/CLucene/config/PlatformMac.h19
-rw-r--r--3rdparty/clucene/src/CLucene/config/PlatformUnix.h12
-rw-r--r--3rdparty/clucene/src/CLucene/config/PlatformWin32.h11
-rw-r--r--3rdparty/clucene/src/CLucene/config/compiler.h259
-rw-r--r--3rdparty/clucene/src/CLucene/config/define_std.h113
-rw-r--r--3rdparty/clucene/src/CLucene/config/gunichartables.cpp386
-rw-r--r--3rdparty/clucene/src/CLucene/config/gunichartables.h11264
-rw-r--r--3rdparty/clucene/src/CLucene/config/repl_lltot.cpp47
-rw-r--r--3rdparty/clucene/src/CLucene/config/repl_tchar.h126
-rw-r--r--3rdparty/clucene/src/CLucene/config/repl_tcscasecmp.cpp21
-rw-r--r--3rdparty/clucene/src/CLucene/config/repl_tcslwr.cpp15
-rw-r--r--3rdparty/clucene/src/CLucene/config/repl_tcstod.cpp23
-rw-r--r--3rdparty/clucene/src/CLucene/config/repl_tcstoll.cpp46
-rw-r--r--3rdparty/clucene/src/CLucene/config/repl_tprintf.cpp149
-rw-r--r--3rdparty/clucene/src/CLucene/config/repl_wchar.h121
-rw-r--r--3rdparty/clucene/src/CLucene/config/threadCSection.h71
-rw-r--r--3rdparty/clucene/src/CLucene/config/threadPthread.h59
-rw-r--r--3rdparty/clucene/src/CLucene/config/threads.cpp162
-rw-r--r--3rdparty/clucene/src/CLucene/config/utf8.cpp237
-rw-r--r--3rdparty/clucene/src/CLucene/debug/condition.cpp80
-rw-r--r--3rdparty/clucene/src/CLucene/debug/condition.h64
-rw-r--r--3rdparty/clucene/src/CLucene/debug/error.cpp73
-rw-r--r--3rdparty/clucene/src/CLucene/debug/error.h74
-rw-r--r--3rdparty/clucene/src/CLucene/debug/lucenebase.h75
-rw-r--r--3rdparty/clucene/src/CLucene/debug/mem.h130
-rw-r--r--3rdparty/clucene/src/CLucene/debug/memtracking.cpp371
-rw-r--r--3rdparty/clucene/src/CLucene/document/DateField.cpp60
-rw-r--r--3rdparty/clucene/src/CLucene/document/DateField.h64
-rw-r--r--3rdparty/clucene/src/CLucene/document/Document.cpp237
-rw-r--r--3rdparty/clucene/src/CLucene/document/Document.h158
-rw-r--r--3rdparty/clucene/src/CLucene/document/Field.cpp315
-rw-r--r--3rdparty/clucene/src/CLucene/document/Field.h261
-rw-r--r--3rdparty/clucene/src/CLucene/index/CompoundFile.cpp380
-rw-r--r--3rdparty/clucene/src/CLucene/index/CompoundFile.h219
-rw-r--r--3rdparty/clucene/src/CLucene/index/DocumentWriter.cpp571
-rw-r--r--3rdparty/clucene/src/CLucene/index/DocumentWriter.h107
-rw-r--r--3rdparty/clucene/src/CLucene/index/FieldInfo.h16
-rw-r--r--3rdparty/clucene/src/CLucene/index/FieldInfos.cpp236
-rw-r--r--3rdparty/clucene/src/CLucene/index/FieldInfos.h171
-rw-r--r--3rdparty/clucene/src/CLucene/index/FieldsReader.cpp231
-rw-r--r--3rdparty/clucene/src/CLucene/index/FieldsReader.h60
-rw-r--r--3rdparty/clucene/src/CLucene/index/FieldsWriter.cpp186
-rw-r--r--3rdparty/clucene/src/CLucene/index/FieldsWriter.h49
-rw-r--r--3rdparty/clucene/src/CLucene/index/IndexModifier.cpp254
-rw-r--r--3rdparty/clucene/src/CLucene/index/IndexModifier.h316
-rw-r--r--3rdparty/clucene/src/CLucene/index/IndexReader.cpp668
-rw-r--r--3rdparty/clucene/src/CLucene/index/IndexReader.h485
-rw-r--r--3rdparty/clucene/src/CLucene/index/IndexWriter.cpp697
-rw-r--r--3rdparty/clucene/src/CLucene/index/IndexWriter.h425
-rw-r--r--3rdparty/clucene/src/CLucene/index/MultiReader.cpp722
-rw-r--r--3rdparty/clucene/src/CLucene/index/MultiReader.h202
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentHeader.h314
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp259
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentInfos.h128
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentMergeInfo.cpp104
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentMergeInfo.h47
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentMergeQueue.cpp74
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentMergeQueue.h38
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentMerger.cpp723
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentMerger.h169
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentReader.cpp816
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentTermDocs.cpp216
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentTermEnum.cpp389
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentTermEnum.h138
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentTermPositions.cpp101
-rw-r--r--3rdparty/clucene/src/CLucene/index/SegmentTermVector.cpp188
-rw-r--r--3rdparty/clucene/src/CLucene/index/Term.cpp182
-rw-r--r--3rdparty/clucene/src/CLucene/index/Term.h146
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermInfo.cpp53
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermInfo.h61
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermInfosReader.cpp443
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermInfosReader.h106
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermInfosWriter.cpp185
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermInfosWriter.h89
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermVector.h418
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermVectorReader.cpp393
-rw-r--r--3rdparty/clucene/src/CLucene/index/TermVectorWriter.cpp349
-rw-r--r--3rdparty/clucene/src/CLucene/index/Terms.h174
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/Lexer.cpp371
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/Lexer.h67
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.cpp215
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.h136
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/QueryParser.cpp509
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/QueryParser.h165
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/QueryParserBase.cpp369
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/QueryParserBase.h204
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/QueryToken.cpp73
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/QueryToken.h76
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/TokenList.cpp79
-rw-r--r--3rdparty/clucene/src/CLucene/queryParser/TokenList.h38
-rw-r--r--3rdparty/clucene/src/CLucene/search/BooleanClause.h90
-rw-r--r--3rdparty/clucene/src/CLucene/search/BooleanQuery.cpp363
-rw-r--r--3rdparty/clucene/src/CLucene/search/BooleanQuery.h126
-rw-r--r--3rdparty/clucene/src/CLucene/search/BooleanScorer.cpp248
-rw-r--r--3rdparty/clucene/src/CLucene/search/BooleanScorer.h99
-rw-r--r--3rdparty/clucene/src/CLucene/search/CachingWrapperFilter.cpp86
-rw-r--r--3rdparty/clucene/src/CLucene/search/CachingWrapperFilter.h80
-rw-r--r--3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp213
-rw-r--r--3rdparty/clucene/src/CLucene/search/ChainedFilter.h86
-rw-r--r--3rdparty/clucene/src/CLucene/search/Compare.h161
-rw-r--r--3rdparty/clucene/src/CLucene/search/ConjunctionScorer.cpp144
-rw-r--r--3rdparty/clucene/src/CLucene/search/ConjunctionScorer.h50
-rw-r--r--3rdparty/clucene/src/CLucene/search/DateFilter.cpp93
-rw-r--r--3rdparty/clucene/src/CLucene/search/DateFilter.h59
-rw-r--r--3rdparty/clucene/src/CLucene/search/ExactPhraseScorer.cpp85
-rw-r--r--3rdparty/clucene/src/CLucene/search/ExactPhraseScorer.h31
-rw-r--r--3rdparty/clucene/src/CLucene/search/Explanation.cpp133
-rw-r--r--3rdparty/clucene/src/CLucene/search/Explanation.h66
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldCache.cpp55
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldCache.h182
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldCacheImpl.cpp529
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldCacheImpl.h144
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldDoc.h70
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldDocSortedHitQueue.cpp171
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldDocSortedHitQueue.h159
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldSortedHitQueue.cpp212
-rw-r--r--3rdparty/clucene/src/CLucene/search/FieldSortedHitQueue.h216
-rw-r--r--3rdparty/clucene/src/CLucene/search/Filter.h46
-rw-r--r--3rdparty/clucene/src/CLucene/search/FilteredTermEnum.cpp136
-rw-r--r--3rdparty/clucene/src/CLucene/search/FilteredTermEnum.h61
-rw-r--r--3rdparty/clucene/src/CLucene/search/FuzzyQuery.cpp357
-rw-r--r--3rdparty/clucene/src/CLucene/search/FuzzyQuery.h156
-rw-r--r--3rdparty/clucene/src/CLucene/search/HitQueue.cpp107
-rw-r--r--3rdparty/clucene/src/CLucene/search/HitQueue.h55
-rw-r--r--3rdparty/clucene/src/CLucene/search/Hits.cpp174
-rw-r--r--3rdparty/clucene/src/CLucene/search/IndexSearcher.cpp362
-rw-r--r--3rdparty/clucene/src/CLucene/search/IndexSearcher.h73
-rw-r--r--3rdparty/clucene/src/CLucene/search/MultiSearcher.cpp227
-rw-r--r--3rdparty/clucene/src/CLucene/search/MultiSearcher.h95
-rw-r--r--3rdparty/clucene/src/CLucene/search/MultiTermQuery.cpp98
-rw-r--r--3rdparty/clucene/src/CLucene/search/MultiTermQuery.h62
-rw-r--r--3rdparty/clucene/src/CLucene/search/PhrasePositions.cpp116
-rw-r--r--3rdparty/clucene/src/CLucene/search/PhrasePositions.h41
-rw-r--r--3rdparty/clucene/src/CLucene/search/PhraseQuery.cpp463
-rw-r--r--3rdparty/clucene/src/CLucene/search/PhraseQuery.h127
-rw-r--r--3rdparty/clucene/src/CLucene/search/PhraseQueue.h36
-rw-r--r--3rdparty/clucene/src/CLucene/search/PhraseScorer.cpp225
-rw-r--r--3rdparty/clucene/src/CLucene/search/PhraseScorer.h65
-rw-r--r--3rdparty/clucene/src/CLucene/search/PrefixQuery.cpp273
-rw-r--r--3rdparty/clucene/src/CLucene/search/PrefixQuery.h75
-rw-r--r--3rdparty/clucene/src/CLucene/search/QueryFilter.cpp73
-rw-r--r--3rdparty/clucene/src/CLucene/search/QueryFilter.h44
-rw-r--r--3rdparty/clucene/src/CLucene/search/RangeFilter.cpp150
-rw-r--r--3rdparty/clucene/src/CLucene/search/RangeFilter.h51
-rw-r--r--3rdparty/clucene/src/CLucene/search/RangeQuery.cpp204
-rw-r--r--3rdparty/clucene/src/CLucene/search/RangeQuery.h71
-rw-r--r--3rdparty/clucene/src/CLucene/search/Scorer.h80
-rw-r--r--3rdparty/clucene/src/CLucene/search/SearchHeader.cpp141
-rw-r--r--3rdparty/clucene/src/CLucene/search/SearchHeader.h456
-rw-r--r--3rdparty/clucene/src/CLucene/search/Similarity.cpp233
-rw-r--r--3rdparty/clucene/src/CLucene/search/Similarity.h268
-rw-r--r--3rdparty/clucene/src/CLucene/search/SloppyPhraseScorer.cpp106
-rw-r--r--3rdparty/clucene/src/CLucene/search/SloppyPhraseScorer.h34
-rw-r--r--3rdparty/clucene/src/CLucene/search/Sort.cpp345
-rw-r--r--3rdparty/clucene/src/CLucene/search/Sort.h356
-rw-r--r--3rdparty/clucene/src/CLucene/search/TermQuery.cpp213
-rw-r--r--3rdparty/clucene/src/CLucene/search/TermQuery.h81
-rw-r--r--3rdparty/clucene/src/CLucene/search/TermScorer.cpp120
-rw-r--r--3rdparty/clucene/src/CLucene/search/TermScorer.h53
-rw-r--r--3rdparty/clucene/src/CLucene/search/WildcardQuery.cpp147
-rw-r--r--3rdparty/clucene/src/CLucene/search/WildcardQuery.h69
-rw-r--r--3rdparty/clucene/src/CLucene/search/WildcardTermEnum.cpp150
-rw-r--r--3rdparty/clucene/src/CLucene/search/WildcardTermEnum.h67
-rw-r--r--3rdparty/clucene/src/CLucene/store/Directory.h108
-rw-r--r--3rdparty/clucene/src/CLucene/store/FSDirectory.cpp662
-rw-r--r--3rdparty/clucene/src/CLucene/store/FSDirectory.h216
-rw-r--r--3rdparty/clucene/src/CLucene/store/IndexInput.cpp233
-rw-r--r--3rdparty/clucene/src/CLucene/store/IndexInput.h190
-rw-r--r--3rdparty/clucene/src/CLucene/store/IndexOutput.cpp163
-rw-r--r--3rdparty/clucene/src/CLucene/store/IndexOutput.h152
-rw-r--r--3rdparty/clucene/src/CLucene/store/InputStream.h21
-rw-r--r--3rdparty/clucene/src/CLucene/store/Lock.cpp27
-rw-r--r--3rdparty/clucene/src/CLucene/store/Lock.h106
-rw-r--r--3rdparty/clucene/src/CLucene/store/MMapInput.cpp203
-rw-r--r--3rdparty/clucene/src/CLucene/store/OutputStream.h23
-rw-r--r--3rdparty/clucene/src/CLucene/store/RAMDirectory.cpp446
-rw-r--r--3rdparty/clucene/src/CLucene/store/RAMDirectory.h195
-rw-r--r--3rdparty/clucene/src/CLucene/store/TransactionalRAMDirectory.cpp212
-rw-r--r--3rdparty/clucene/src/CLucene/store/TransactionalRAMDirectory.h76
-rw-r--r--3rdparty/clucene/src/CLucene/util/Arrays.h164
-rw-r--r--3rdparty/clucene/src/CLucene/util/BitSet.cpp119
-rw-r--r--3rdparty/clucene/src/CLucene/util/BitSet.h62
-rw-r--r--3rdparty/clucene/src/CLucene/util/Equators.cpp180
-rw-r--r--3rdparty/clucene/src/CLucene/util/Equators.h274
-rw-r--r--3rdparty/clucene/src/CLucene/util/FastCharStream.cpp107
-rw-r--r--3rdparty/clucene/src/CLucene/util/FastCharStream.h55
-rw-r--r--3rdparty/clucene/src/CLucene/util/Misc.cpp295
-rw-r--r--3rdparty/clucene/src/CLucene/util/Misc.h75
-rw-r--r--3rdparty/clucene/src/CLucene/util/PriorityQueue.h177
-rw-r--r--3rdparty/clucene/src/CLucene/util/Reader.cpp186
-rw-r--r--3rdparty/clucene/src/CLucene/util/Reader.h138
-rw-r--r--3rdparty/clucene/src/CLucene/util/StringBuffer.cpp335
-rw-r--r--3rdparty/clucene/src/CLucene/util/StringBuffer.h77
-rw-r--r--3rdparty/clucene/src/CLucene/util/StringIntern.cpp158
-rw-r--r--3rdparty/clucene/src/CLucene/util/StringIntern.h61
-rw-r--r--3rdparty/clucene/src/CLucene/util/ThreadLocal.cpp55
-rw-r--r--3rdparty/clucene/src/CLucene/util/ThreadLocal.h143
-rw-r--r--3rdparty/clucene/src/CLucene/util/VoidList.h175
-rw-r--r--3rdparty/clucene/src/CLucene/util/VoidMap.h270
-rw-r--r--3rdparty/clucene/src/CLucene/util/bufferedstream.h157
-rw-r--r--3rdparty/clucene/src/CLucene/util/dirent.cpp221
-rw-r--r--3rdparty/clucene/src/CLucene/util/dirent.h105
-rw-r--r--3rdparty/clucene/src/CLucene/util/fileinputstream.cpp103
-rw-r--r--3rdparty/clucene/src/CLucene/util/fileinputstream.h38
-rw-r--r--3rdparty/clucene/src/CLucene/util/inputstreambuffer.h126
-rw-r--r--3rdparty/clucene/src/CLucene/util/jstreamsconfig.h9
-rw-r--r--3rdparty/clucene/src/CLucene/util/streambase.h148
-rw-r--r--3rdparty/clucene/src/CLucene/util/stringreader.h124
-rw-r--r--3rdparty/clucene/src/CLucene/util/subinputstream.h141
-rw-r--r--demos/arthurplugin/arthur_plugin.qrc7
-rw-r--r--demos/arthurplugin/arthurplugin.pro54
-rw-r--r--demos/arthurplugin/bg1.jpgbin0 -> 23771 bytes
-rw-r--r--demos/arthurplugin/flower.jpgbin0 -> 49616 bytes
-rw-r--r--demos/arthurplugin/flower_alpha.jpgbin0 -> 67326 bytes
-rw-r--r--demos/arthurplugin/plugin.cpp296
-rw-r--r--demos/shared/arthurstyle.cpp452
-rw-r--r--demos/shared/arthurstyle.h79
-rw-r--r--demos/shared/arthurwidgets.cpp371
-rw-r--r--demos/shared/arthurwidgets.h137
-rw-r--r--demos/shared/hoverpoints.cpp415
-rw-r--r--demos/shared/hoverpoints.h162
-rw-r--r--demos/shared/images/bg_pattern.pngbin0 -> 104 bytes
-rw-r--r--demos/shared/images/button_normal_cap_left.pngbin0 -> 654 bytes
-rw-r--r--demos/shared/images/button_normal_cap_right.pngbin0 -> 674 bytes
-rw-r--r--demos/shared/images/button_normal_stretch.pngbin0 -> 185 bytes
-rw-r--r--demos/shared/images/button_pressed_cap_left.pngbin0 -> 710 bytes
-rw-r--r--demos/shared/images/button_pressed_cap_right.pngbin0 -> 785 bytes
-rw-r--r--demos/shared/images/button_pressed_stretch.pngbin0 -> 217 bytes
-rw-r--r--demos/shared/images/curve_thing_edit-6.pngbin0 -> 58097 bytes
-rw-r--r--demos/shared/images/frame_bottom.pngbin0 -> 166 bytes
-rw-r--r--demos/shared/images/frame_bottomleft.pngbin0 -> 602 bytes
-rw-r--r--demos/shared/images/frame_bottomright.pngbin0 -> 553 bytes
-rw-r--r--demos/shared/images/frame_left.pngbin0 -> 182 bytes
-rw-r--r--demos/shared/images/frame_right.pngbin0 -> 175 bytes
-rw-r--r--demos/shared/images/frame_top.pngbin0 -> 188 bytes
-rw-r--r--demos/shared/images/frame_topleft.pngbin0 -> 801 bytes
-rw-r--r--demos/shared/images/frame_topright.pngbin0 -> 851 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_left.pngbin0 -> 397 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_right.pngbin0 -> 383 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_stretch.pngbin0 -> 141 bytes
-rw-r--r--demos/shared/images/groupframe_left_stretch.pngbin0 -> 132 bytes
-rw-r--r--demos/shared/images/groupframe_right_stretch.pngbin0 -> 113 bytes
-rw-r--r--demos/shared/images/groupframe_top_stretch.pngbin0 -> 115 bytes
-rw-r--r--demos/shared/images/groupframe_topleft.pngbin0 -> 412 bytes
-rw-r--r--demos/shared/images/groupframe_topright.pngbin0 -> 449 bytes
-rw-r--r--demos/shared/images/line_dash_dot.pngbin0 -> 151 bytes
-rw-r--r--demos/shared/images/line_dash_dot_dot.pngbin0 -> 155 bytes
-rw-r--r--demos/shared/images/line_dashed.pngbin0 -> 121 bytes
-rw-r--r--demos/shared/images/line_dotted.pngbin0 -> 116 bytes
-rw-r--r--demos/shared/images/line_solid.pngbin0 -> 110 bytes
-rw-r--r--demos/shared/images/radiobutton-off.pngbin0 -> 442 bytes
-rw-r--r--demos/shared/images/radiobutton-on.pngbin0 -> 474 bytes
-rw-r--r--demos/shared/images/radiobutton_off.pngbin0 -> 442 bytes
-rw-r--r--demos/shared/images/radiobutton_on.pngbin0 -> 499 bytes
-rw-r--r--demos/shared/images/slider_bar.pngbin0 -> 748 bytes
-rw-r--r--demos/shared/images/slider_thumb_off.pngbin0 -> 823 bytes
-rw-r--r--demos/shared/images/slider_thumb_on.pngbin0 -> 798 bytes
-rw-r--r--demos/shared/images/title_cap_left.pngbin0 -> 179 bytes
-rw-r--r--demos/shared/images/title_cap_right.pngbin0 -> 184 bytes
-rw-r--r--demos/shared/images/title_stretch.pngbin0 -> 106 bytes
-rw-r--r--demos/shared/shared.pri21
-rw-r--r--demos/shared/shared.pro38
-rw-r--r--demos/shared/shared.qrc39
-rw-r--r--examples/designer/README37
-rw-r--r--examples/designer/calculatorbuilder/calculatorbuilder.pro16
-rw-r--r--examples/designer/calculatorbuilder/calculatorbuilder.qrc5
-rw-r--r--examples/designer/calculatorbuilder/calculatorform.cpp91
-rw-r--r--examples/designer/calculatorbuilder/calculatorform.h70
-rw-r--r--examples/designer/calculatorbuilder/calculatorform.ui303
-rw-r--r--examples/designer/calculatorbuilder/main.cpp53
-rw-r--r--examples/designer/calculatorform/calculatorform.cpp65
-rw-r--r--examples/designer/calculatorform/calculatorform.h65
-rw-r--r--examples/designer/calculatorform/calculatorform.pro15
-rw-r--r--examples/designer/calculatorform/calculatorform.ui284
-rw-r--r--examples/designer/calculatorform/main.cpp52
-rw-r--r--examples/designer/containerextension/containerextension.pro28
-rw-r--r--examples/designer/containerextension/multipagewidget.cpp130
-rw-r--r--examples/designer/containerextension/multipagewidget.h87
-rw-r--r--examples/designer/containerextension/multipagewidgetcontainerextension.cpp100
-rw-r--r--examples/designer/containerextension/multipagewidgetcontainerextension.h74
-rw-r--r--examples/designer/containerextension/multipagewidgetextensionfactory.cpp64
-rw-r--r--examples/designer/containerextension/multipagewidgetextensionfactory.h63
-rw-r--r--examples/designer/containerextension/multipagewidgetplugin.cpp196
-rw-r--r--examples/designer/containerextension/multipagewidgetplugin.h80
-rw-r--r--examples/designer/customwidgetplugin/analogclock.cpp110
-rw-r--r--examples/designer/customwidgetplugin/analogclock.h58
-rw-r--r--examples/designer/customwidgetplugin/customwidgetplugin.cpp155
-rw-r--r--examples/designer/customwidgetplugin/customwidgetplugin.h72
-rw-r--r--examples/designer/customwidgetplugin/customwidgetplugin.pro23
-rw-r--r--examples/designer/designer.pro21
-rw-r--r--examples/designer/taskmenuextension/taskmenuextension.pro27
-rw-r--r--examples/designer/taskmenuextension/tictactoe.cpp175
-rw-r--r--examples/designer/taskmenuextension/tictactoe.h82
-rw-r--r--examples/designer/taskmenuextension/tictactoedialog.cpp98
-rw-r--r--examples/designer/taskmenuextension/tictactoedialog.h72
-rw-r--r--examples/designer/taskmenuextension/tictactoeplugin.cpp141
-rw-r--r--examples/designer/taskmenuextension/tictactoeplugin.h77
-rw-r--r--examples/designer/taskmenuextension/tictactoetaskmenu.cpp103
-rw-r--r--examples/designer/taskmenuextension/tictactoetaskmenu.h87
-rw-r--r--examples/designer/worldtimeclockbuilder/form.ui162
-rw-r--r--examples/designer/worldtimeclockbuilder/main.cpp69
-rw-r--r--examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.pro13
-rw-r--r--examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.qrc5
-rw-r--r--examples/designer/worldtimeclockplugin/worldtimeclock.cpp121
-rw-r--r--examples/designer/worldtimeclockplugin/worldtimeclock.h72
-rw-r--r--examples/designer/worldtimeclockplugin/worldtimeclockplugin.cpp123
-rw-r--r--examples/designer/worldtimeclockplugin/worldtimeclockplugin.h73
-rw-r--r--examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro23
-rw-r--r--examples/examples.pro2
-rw-r--r--examples/help/README38
-rw-r--r--examples/help/contextsensitivehelp/contextsensitivehelp.pro20
-rw-r--r--examples/help/contextsensitivehelp/doc/amount.html11
-rw-r--r--examples/help/contextsensitivehelp/doc/filter.html12
-rw-r--r--examples/help/contextsensitivehelp/doc/plants.html44
-rw-r--r--examples/help/contextsensitivehelp/doc/rain.html11
-rw-r--r--examples/help/contextsensitivehelp/doc/source.html33
-rw-r--r--examples/help/contextsensitivehelp/doc/temperature.html13
-rw-r--r--examples/help/contextsensitivehelp/doc/time.html11
-rw-r--r--examples/help/contextsensitivehelp/doc/wateringmachine.qchbin0 -> 25600 bytes
-rw-r--r--examples/help/contextsensitivehelp/doc/wateringmachine.qhcbin0 -> 8192 bytes
-rw-r--r--examples/help/contextsensitivehelp/doc/wateringmachine.qhcp14
-rw-r--r--examples/help/contextsensitivehelp/doc/wateringmachine.qhp25
-rw-r--r--examples/help/contextsensitivehelp/helpbrowser.cpp80
-rw-r--r--examples/help/contextsensitivehelp/helpbrowser.h64
-rw-r--r--examples/help/contextsensitivehelp/main.cpp50
-rw-r--r--examples/help/contextsensitivehelp/wateringconfigdialog.cpp68
-rw-r--r--examples/help/contextsensitivehelp/wateringconfigdialog.h61
-rw-r--r--examples/help/contextsensitivehelp/wateringconfigdialog.ui446
-rw-r--r--examples/help/help.pro13
-rw-r--r--examples/help/remotecontrol/enter.pngbin0 -> 315 bytes
-rw-r--r--examples/help/remotecontrol/main.cpp53
-rw-r--r--examples/help/remotecontrol/remotecontrol.cpp174
-rw-r--r--examples/help/remotecontrol/remotecontrol.h78
-rw-r--r--examples/help/remotecontrol/remotecontrol.pro15
-rw-r--r--examples/help/remotecontrol/remotecontrol.qrc5
-rw-r--r--examples/help/remotecontrol/remotecontrol.ui228
-rw-r--r--examples/help/simpletextviewer/assistant.cpp109
-rw-r--r--examples/help/simpletextviewer/assistant.h62
-rw-r--r--examples/help/simpletextviewer/documentation/about.txt9
-rw-r--r--examples/help/simpletextviewer/documentation/browse.html34
-rw-r--r--examples/help/simpletextviewer/documentation/filedialog.html48
-rw-r--r--examples/help/simpletextviewer/documentation/findfile.html32
-rw-r--r--examples/help/simpletextviewer/documentation/images/browse.pngbin0 -> 21553 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/images/fadedfilemenu.pngbin0 -> 9589 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/images/filedialog.pngbin0 -> 12318 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/images/handbook.pngbin0 -> 1060 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/images/icon.pngbin0 -> 5513 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/images/mainwindow.pngbin0 -> 12769 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/images/open.pngbin0 -> 11697 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/images/wildcard.pngbin0 -> 11266 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/index.html41
-rw-r--r--examples/help/simpletextviewer/documentation/intro.html28
-rw-r--r--examples/help/simpletextviewer/documentation/openfile.html36
-rw-r--r--examples/help/simpletextviewer/documentation/simpletextviewer.qchbin0 -> 108544 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/simpletextviewer.qhcbin0 -> 18432 bytes
-rw-r--r--examples/help/simpletextviewer/documentation/simpletextviewer.qhcp30
-rw-r--r--examples/help/simpletextviewer/documentation/simpletextviewer.qhp49
-rw-r--r--examples/help/simpletextviewer/documentation/wildcardmatching.html57
-rw-r--r--examples/help/simpletextviewer/findfiledialog.cpp221
-rw-r--r--examples/help/simpletextviewer/findfiledialog.h98
-rw-r--r--examples/help/simpletextviewer/main.cpp51
-rw-r--r--examples/help/simpletextviewer/mainwindow.cpp146
-rw-r--r--examples/help/simpletextviewer/mainwindow.h83
-rw-r--r--examples/help/simpletextviewer/simpletextviewer.pro18
-rw-r--r--examples/help/simpletextviewer/textedit.cpp74
-rw-r--r--examples/help/simpletextviewer/textedit.h60
-rw-r--r--qttools.pro12
-rw-r--r--src/assistant/assistant.pro6
-rw-r--r--src/assistant/lib/fulltextsearch/fulltextsearch.pri161
-rw-r--r--src/assistant/lib/fulltextsearch/fulltextsearch.pro50
-rw-r--r--src/assistant/lib/fulltextsearch/license.txt503
-rw-r--r--src/assistant/lib/fulltextsearch/qanalyzer.cpp219
-rw-r--r--src/assistant/lib/fulltextsearch/qanalyzer_p.h152
-rw-r--r--src/assistant/lib/fulltextsearch/qclucene-config_p.h557
-rw-r--r--src/assistant/lib/fulltextsearch/qclucene_global_p.h134
-rw-r--r--src/assistant/lib/fulltextsearch/qdocument.cpp180
-rw-r--r--src/assistant/lib/fulltextsearch/qdocument_p.h100
-rw-r--r--src/assistant/lib/fulltextsearch/qfield.cpp171
-rw-r--r--src/assistant/lib/fulltextsearch/qfield_p.h119
-rw-r--r--src/assistant/lib/fulltextsearch/qfilter.cpp57
-rw-r--r--src/assistant/lib/fulltextsearch/qfilter_p.h75
-rw-r--r--src/assistant/lib/fulltextsearch/qhits.cpp94
-rw-r--r--src/assistant/lib/fulltextsearch/qhits_p.h86
-rw-r--r--src/assistant/lib/fulltextsearch/qindexreader.cpp169
-rw-r--r--src/assistant/lib/fulltextsearch/qindexreader_p.h115
-rw-r--r--src/assistant/lib/fulltextsearch/qindexwriter.cpp191
-rw-r--r--src/assistant/lib/fulltextsearch/qindexwriter_p.h124
-rw-r--r--src/assistant/lib/fulltextsearch/qquery.cpp358
-rw-r--r--src/assistant/lib/fulltextsearch/qquery_p.h188
-rw-r--r--src/assistant/lib/fulltextsearch/qqueryparser.cpp176
-rw-r--r--src/assistant/lib/fulltextsearch/qqueryparser_p.h109
-rw-r--r--src/assistant/lib/fulltextsearch/qreader.cpp101
-rw-r--r--src/assistant/lib/fulltextsearch/qreader_p.h104
-rw-r--r--src/assistant/lib/fulltextsearch/qsearchable.cpp203
-rw-r--r--src/assistant/lib/fulltextsearch/qsearchable_p.h135
-rw-r--r--src/assistant/lib/fulltextsearch/qsort.cpp97
-rw-r--r--src/assistant/lib/fulltextsearch/qsort_p.h84
-rw-r--r--src/assistant/lib/fulltextsearch/qterm.cpp134
-rw-r--r--src/assistant/lib/fulltextsearch/qterm_p.h100
-rw-r--r--src/assistant/lib/fulltextsearch/qtoken.cpp150
-rw-r--r--src/assistant/lib/fulltextsearch/qtoken_p.h112
-rw-r--r--src/assistant/lib/fulltextsearch/qtokenizer.cpp117
-rw-r--r--src/assistant/lib/fulltextsearch/qtokenizer_p.h97
-rw-r--r--src/assistant/lib/fulltextsearch/qtokenstream.cpp67
-rw-r--r--src/assistant/lib/fulltextsearch/qtokenstream_p.h95
-rw-r--r--src/assistant/lib/helpsystem.qrc8
-rw-r--r--src/assistant/lib/images/1leftarrow.pngbin0 -> 669 bytes
-rw-r--r--src/assistant/lib/images/1rightarrow.pngbin0 -> 706 bytes
-rw-r--r--src/assistant/lib/images/3leftarrow.pngbin0 -> 832 bytes
-rw-r--r--src/assistant/lib/images/3rightarrow.pngbin0 -> 820 bytes
-rw-r--r--src/assistant/lib/lib.pro71
-rw-r--r--src/assistant/lib/qclucenefieldnames.cpp57
-rw-r--r--src/assistant/lib/qclucenefieldnames_p.h63
-rw-r--r--src/assistant/lib/qhelp_global.cpp114
-rw-r--r--src/assistant/lib/qhelp_global.h78
-rw-r--r--src/assistant/lib/qhelpcollectionhandler.cpp603
-rw-r--r--src/assistant/lib/qhelpcollectionhandler_p.h124
-rw-r--r--src/assistant/lib/qhelpcontentwidget.cpp586
-rw-r--r--src/assistant/lib/qhelpcontentwidget.h146
-rw-r--r--src/assistant/lib/qhelpdatainterface.cpp273
-rw-r--r--src/assistant/lib/qhelpdatainterface_p.h155
-rw-r--r--src/assistant/lib/qhelpdbreader.cpp583
-rw-r--r--src/assistant/lib/qhelpdbreader_p.h128
-rw-r--r--src/assistant/lib/qhelpengine.cpp213
-rw-r--r--src/assistant/lib/qhelpengine.h84
-rw-r--r--src/assistant/lib/qhelpengine_p.h144
-rw-r--r--src/assistant/lib/qhelpenginecore.cpp737
-rw-r--r--src/assistant/lib/qhelpenginecore.h136
-rw-r--r--src/assistant/lib/qhelpgenerator.cpp909
-rw-r--r--src/assistant/lib/qhelpgenerator_p.h118
-rw-r--r--src/assistant/lib/qhelpindexwidget.cpp444
-rw-r--r--src/assistant/lib/qhelpindexwidget.h114
-rw-r--r--src/assistant/lib/qhelpprojectdata.cpp450
-rw-r--r--src/assistant/lib/qhelpprojectdata_p.h89
-rw-r--r--src/assistant/lib/qhelpsearchengine.cpp450
-rw-r--r--src/assistant/lib/qhelpsearchengine.h125
-rw-r--r--src/assistant/lib/qhelpsearchindex_default.cpp60
-rw-r--r--src/assistant/lib/qhelpsearchindex_default_p.h149
-rw-r--r--src/assistant/lib/qhelpsearchindexreader.cpp104
-rw-r--r--src/assistant/lib/qhelpsearchindexreader_clucene.cpp481
-rw-r--r--src/assistant/lib/qhelpsearchindexreader_clucene_p.h114
-rw-r--r--src/assistant/lib/qhelpsearchindexreader_default.cpp612
-rw-r--r--src/assistant/lib/qhelpsearchindexreader_default_p.h131
-rw-r--r--src/assistant/lib/qhelpsearchindexreader_p.h106
-rw-r--r--src/assistant/lib/qhelpsearchindexwriter_clucene.cpp898
-rw-r--r--src/assistant/lib/qhelpsearchindexwriter_clucene_p.h124
-rw-r--r--src/assistant/lib/qhelpsearchindexwriter_default.cpp384
-rw-r--r--src/assistant/lib/qhelpsearchindexwriter_default_p.h130
-rw-r--r--src/assistant/lib/qhelpsearchquerywidget.cpp587
-rw-r--r--src/assistant/lib/qhelpsearchquerywidget.h92
-rw-r--r--src/assistant/lib/qhelpsearchresultwidget.cpp447
-rw-r--r--src/assistant/lib/qhelpsearchresultwidget.h85
-rw-r--r--src/assistant/tools/assistant/Info_mac.plist18
-rw-r--r--src/assistant/tools/assistant/aboutdialog.cpp184
-rw-r--r--src/assistant/tools/assistant/aboutdialog.h91
-rw-r--r--src/assistant/tools/assistant/assistant.icnsbin0 -> 162568 bytes
-rw-r--r--src/assistant/tools/assistant/assistant.icobin0 -> 355574 bytes
-rw-r--r--src/assistant/tools/assistant/assistant.pro118
-rw-r--r--src/assistant/tools/assistant/assistant.qchbin0 -> 364544 bytes
-rw-r--r--src/assistant/tools/assistant/assistant.qrc5
-rw-r--r--src/assistant/tools/assistant/assistant.rc32
-rw-r--r--src/assistant/tools/assistant/assistant_images.qrc37
-rw-r--r--src/assistant/tools/assistant/bookmarkdialog.cpp237
-rw-r--r--src/assistant/tools/assistant/bookmarkdialog.h89
-rw-r--r--src/assistant/tools/assistant/bookmarkdialog.ui156
-rw-r--r--src/assistant/tools/assistant/bookmarkfiltermodel.cpp321
-rw-r--r--src/assistant/tools/assistant/bookmarkfiltermodel.h118
-rw-r--r--src/assistant/tools/assistant/bookmarkitem.cpp184
-rw-r--r--src/assistant/tools/assistant/bookmarkitem.h91
-rw-r--r--src/assistant/tools/assistant/bookmarkmanager.cpp559
-rw-r--r--src/assistant/tools/assistant/bookmarkmanager.h160
-rw-r--r--src/assistant/tools/assistant/bookmarkmanagerwidget.cpp321
-rw-r--r--src/assistant/tools/assistant/bookmarkmanagerwidget.h103
-rw-r--r--src/assistant/tools/assistant/bookmarkmanagerwidget.ui137
-rw-r--r--src/assistant/tools/assistant/bookmarkmodel.cpp461
-rw-r--r--src/assistant/tools/assistant/bookmarkmodel.h117
-rw-r--r--src/assistant/tools/assistant/bookmarkwidget.ui85
-rw-r--r--src/assistant/tools/assistant/centralwidget.cpp636
-rw-r--r--src/assistant/tools/assistant/centralwidget.h172
-rw-r--r--src/assistant/tools/assistant/cmdlineparser.cpp376
-rw-r--r--src/assistant/tools/assistant/cmdlineparser.h117
-rw-r--r--src/assistant/tools/assistant/contentwindow.cpp204
-rw-r--r--src/assistant/tools/assistant/contentwindow.h86
-rw-r--r--src/assistant/tools/assistant/doc/HOWTO16
-rw-r--r--src/assistant/tools/assistant/doc/assistant.qdoc461
-rw-r--r--src/assistant/tools/assistant/doc/assistant.qdocconf16
-rw-r--r--src/assistant/tools/assistant/doc/assistant.qhp22
-rw-r--r--src/assistant/tools/assistant/doc/classic.css92
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-address-toolbar.pngbin0 -> 2899 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-assistant.pngbin0 -> 205326 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-dockwidgets.pngbin0 -> 50554 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-docwindow.pngbin0 -> 55582 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-examples.pngbin0 -> 9799 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-filter-toolbar.pngbin0 -> 1767 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-preferences-documentation.pngbin0 -> 13417 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-preferences-filters.pngbin0 -> 15561 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-preferences-fonts.pngbin0 -> 13139 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-preferences-options.pngbin0 -> 14255 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-search.pngbin0 -> 59254 bytes
-rw-r--r--src/assistant/tools/assistant/doc/images/assistant-toolbar.pngbin0 -> 6532 bytes
-rw-r--r--src/assistant/tools/assistant/filternamedialog.cpp77
-rw-r--r--src/assistant/tools/assistant/filternamedialog.h67
-rw-r--r--src/assistant/tools/assistant/filternamedialog.ui67
-rw-r--r--src/assistant/tools/assistant/findwidget.cpp234
-rw-r--r--src/assistant/tools/assistant/findwidget.h100
-rw-r--r--src/assistant/tools/assistant/globalactions.cpp246
-rw-r--r--src/assistant/tools/assistant/globalactions.h105
-rw-r--r--src/assistant/tools/assistant/helpenginewrapper.cpp844
-rw-r--r--src/assistant/tools/assistant/helpenginewrapper.h218
-rw-r--r--src/assistant/tools/assistant/helpviewer.cpp221
-rw-r--r--src/assistant/tools/assistant/helpviewer.h158
-rw-r--r--src/assistant/tools/assistant/helpviewer_p.h123
-rw-r--r--src/assistant/tools/assistant/helpviewer_qtb.cpp384
-rw-r--r--src/assistant/tools/assistant/helpviewer_qwv.cpp495
-rw-r--r--src/assistant/tools/assistant/images/assistant-128.pngbin0 -> 6448 bytes
-rw-r--r--src/assistant/tools/assistant/images/assistant.pngbin0 -> 2034 bytes
-rw-r--r--src/assistant/tools/assistant/images/bookmark.pngbin0 -> 1266 bytes
-rw-r--r--src/assistant/tools/assistant/images/closebutton.pngbin0 -> 288 bytes
-rw-r--r--src/assistant/tools/assistant/images/darkclosebutton.pngbin0 -> 319 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/addtab.pngbin0 -> 469 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/book.pngbin0 -> 1477 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/closetab.pngbin0 -> 516 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/editcopy.pngbin0 -> 1468 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/find.pngbin0 -> 1836 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/home.pngbin0 -> 1807 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/next.pngbin0 -> 1310 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/previous.pngbin0 -> 1080 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/print.pngbin0 -> 2087 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/resetzoom.pngbin0 -> 1567 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/synctoc.pngbin0 -> 1838 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/zoomin.pngbin0 -> 1696 bytes
-rw-r--r--src/assistant/tools/assistant/images/mac/zoomout.pngbin0 -> 1662 bytes
-rw-r--r--src/assistant/tools/assistant/images/trolltech-logo.pngbin0 -> 10096 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/addtab.pngbin0 -> 314 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/book.pngbin0 -> 1109 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/closetab.pngbin0 -> 375 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/editcopy.pngbin0 -> 1325 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/find.pngbin0 -> 1944 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/home.pngbin0 -> 1414 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/next.pngbin0 -> 1038 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/previous.pngbin0 -> 898 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/print.pngbin0 -> 1456 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/resetzoom.pngbin0 -> 1134 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/synctoc.pngbin0 -> 1235 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/zoomin.pngbin0 -> 1208 bytes
-rw-r--r--src/assistant/tools/assistant/images/win/zoomout.pngbin0 -> 1226 bytes
-rw-r--r--src/assistant/tools/assistant/images/wrap.pngbin0 -> 500 bytes
-rw-r--r--src/assistant/tools/assistant/indexwindow.cpp231
-rw-r--r--src/assistant/tools/assistant/indexwindow.h90
-rw-r--r--src/assistant/tools/assistant/installdialog.cpp355
-rw-r--r--src/assistant/tools/assistant/installdialog.h105
-rw-r--r--src/assistant/tools/assistant/installdialog.ui118
-rw-r--r--src/assistant/tools/assistant/main.cpp440
-rw-r--r--src/assistant/tools/assistant/mainwindow.cpp1099
-rw-r--r--src/assistant/tools/assistant/mainwindow.h172
-rw-r--r--src/assistant/tools/assistant/openpagesmanager.cpp378
-rw-r--r--src/assistant/tools/assistant/openpagesmanager.h115
-rw-r--r--src/assistant/tools/assistant/openpagesmodel.cpp119
-rw-r--r--src/assistant/tools/assistant/openpagesmodel.h76
-rw-r--r--src/assistant/tools/assistant/openpagesswitcher.cpp194
-rw-r--r--src/assistant/tools/assistant/openpagesswitcher.h85
-rw-r--r--src/assistant/tools/assistant/openpageswidget.cpp237
-rw-r--r--src/assistant/tools/assistant/openpageswidget.h92
-rw-r--r--src/assistant/tools/assistant/preferencesdialog.cpp507
-rw-r--r--src/assistant/tools/assistant/preferencesdialog.h110
-rw-r--r--src/assistant/tools/assistant/preferencesdialog.ui400
-rw-r--r--src/assistant/tools/assistant/qtdocinstaller.cpp128
-rw-r--r--src/assistant/tools/assistant/qtdocinstaller.h84
-rw-r--r--src/assistant/tools/assistant/remotecontrol.cpp388
-rw-r--r--src/assistant/tools/assistant/remotecontrol.h96
-rw-r--r--src/assistant/tools/assistant/remotecontrol_win.h68
-rw-r--r--src/assistant/tools/assistant/searchwidget.cpp237
-rw-r--r--src/assistant/tools/assistant/searchwidget.h90
-rw-r--r--src/assistant/tools/assistant/topicchooser.cpp87
-rw-r--r--src/assistant/tools/assistant/topicchooser.h73
-rw-r--r--src/assistant/tools/assistant/topicchooser.ui116
-rw-r--r--src/assistant/tools/assistant/tracer.h75
-rw-r--r--src/assistant/tools/assistant/xbelsupport.cpp233
-rw-r--r--src/assistant/tools/assistant/xbelsupport.h87
-rw-r--r--src/assistant/tools/qcollectiongenerator/main.cpp615
-rw-r--r--src/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro17
-rw-r--r--src/assistant/tools/qhelpconverter/adpreader.cpp179
-rw-r--r--src/assistant/tools/qhelpconverter/adpreader.h90
-rw-r--r--src/assistant/tools/qhelpconverter/assistant-128.pngbin0 -> 6448 bytes
-rw-r--r--src/assistant/tools/qhelpconverter/assistant.pngbin0 -> 2034 bytes
-rw-r--r--src/assistant/tools/qhelpconverter/conversionwizard.cpp265
-rw-r--r--src/assistant/tools/qhelpconverter/conversionwizard.h96
-rw-r--r--src/assistant/tools/qhelpconverter/doc/filespage.html8
-rw-r--r--src/assistant/tools/qhelpconverter/doc/filterpage.html13
-rw-r--r--src/assistant/tools/qhelpconverter/doc/generalpage.html10
-rw-r--r--src/assistant/tools/qhelpconverter/doc/identifierpage.html17
-rw-r--r--src/assistant/tools/qhelpconverter/doc/inputpage.html7
-rw-r--r--src/assistant/tools/qhelpconverter/doc/outputpage.html7
-rw-r--r--src/assistant/tools/qhelpconverter/doc/pathpage.html8
-rw-r--r--src/assistant/tools/qhelpconverter/filespage.cpp112
-rw-r--r--src/assistant/tools/qhelpconverter/filespage.h73
-rw-r--r--src/assistant/tools/qhelpconverter/filespage.ui79
-rw-r--r--src/assistant/tools/qhelpconverter/filterpage.cpp147
-rw-r--r--src/assistant/tools/qhelpconverter/filterpage.h79
-rw-r--r--src/assistant/tools/qhelpconverter/filterpage.ui125
-rw-r--r--src/assistant/tools/qhelpconverter/finishpage.cpp75
-rw-r--r--src/assistant/tools/qhelpconverter/finishpage.h65
-rw-r--r--src/assistant/tools/qhelpconverter/generalpage.cpp92
-rw-r--r--src/assistant/tools/qhelpconverter/generalpage.h66
-rw-r--r--src/assistant/tools/qhelpconverter/generalpage.ui69
-rw-r--r--src/assistant/tools/qhelpconverter/helpwindow.cpp84
-rw-r--r--src/assistant/tools/qhelpconverter/helpwindow.h65
-rw-r--r--src/assistant/tools/qhelpconverter/identifierpage.cpp71
-rw-r--r--src/assistant/tools/qhelpconverter/identifierpage.h66
-rw-r--r--src/assistant/tools/qhelpconverter/identifierpage.ui132
-rw-r--r--src/assistant/tools/qhelpconverter/inputpage.cpp103
-rw-r--r--src/assistant/tools/qhelpconverter/inputpage.h71
-rw-r--r--src/assistant/tools/qhelpconverter/inputpage.ui79
-rw-r--r--src/assistant/tools/qhelpconverter/main.cpp77
-rw-r--r--src/assistant/tools/qhelpconverter/outputpage.cpp110
-rw-r--r--src/assistant/tools/qhelpconverter/outputpage.h71
-rw-r--r--src/assistant/tools/qhelpconverter/outputpage.ui95
-rw-r--r--src/assistant/tools/qhelpconverter/pathpage.cpp112
-rw-r--r--src/assistant/tools/qhelpconverter/pathpage.h71
-rw-r--r--src/assistant/tools/qhelpconverter/pathpage.ui114
-rw-r--r--src/assistant/tools/qhelpconverter/qhcpwriter.cpp145
-rw-r--r--src/assistant/tools/qhelpconverter/qhcpwriter.h70
-rw-r--r--src/assistant/tools/qhelpconverter/qhelpconverter.pro47
-rw-r--r--src/assistant/tools/qhelpconverter/qhelpconverter.qrc13
-rw-r--r--src/assistant/tools/qhelpconverter/qhpwriter.cpp184
-rw-r--r--src/assistant/tools/qhelpconverter/qhpwriter.h85
-rw-r--r--src/assistant/tools/qhelpgenerator/main.cpp178
-rw-r--r--src/assistant/tools/qhelpgenerator/qhelpgenerator.pro14
-rw-r--r--src/assistant/tools/shared/collectionconfiguration.cpp327
-rw-r--r--src/assistant/tools/shared/collectionconfiguration.h149
-rw-r--r--src/assistant/tools/shared/helpgenerator.cpp84
-rw-r--r--src/assistant/tools/shared/helpgenerator.h73
-rw-r--r--src/assistant/tools/tools.pro8
-rw-r--r--src/checksdk/README3
-rw-r--r--src/checksdk/cesdkhandler.cpp132
-rw-r--r--src/checksdk/cesdkhandler.h111
-rw-r--r--src/checksdk/checksdk.pro36
-rw-r--r--src/checksdk/main.cpp165
-rw-r--r--src/designer/data/generate_header.xsl465
-rw-r--r--src/designer/data/generate_impl.xsl1161
-rw-r--r--src/designer/data/generate_shared.xsl331
-rw-r--r--src/designer/data/ui3.xsd353
-rw-r--r--src/designer/data/ui4.xsd589
-rw-r--r--src/designer/designer.pro5
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor.cpp446
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor.h92
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor.pri16
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor_global.h57
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor_instance.cpp50
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor_plugin.cpp133
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor_plugin.h93
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor_tool.cpp111
-rw-r--r--src/designer/src/components/buddyeditor/buddyeditor_tool.h89
-rw-r--r--src/designer/src/components/component.pri2
-rw-r--r--src/designer/src/components/components.pro3
-rw-r--r--src/designer/src/components/formeditor/brushmanagerproxy.cpp303
-rw-r--r--src/designer/src/components/formeditor/brushmanagerproxy.h77
-rw-r--r--src/designer/src/components/formeditor/default_actionprovider.cpp207
-rw-r--r--src/designer/src/components/formeditor/default_actionprovider.h131
-rw-r--r--src/designer/src/components/formeditor/default_container.cpp173
-rw-r--r--src/designer/src/components/formeditor/default_container.h213
-rw-r--r--src/designer/src/components/formeditor/default_layoutdecoration.cpp79
-rw-r--r--src/designer/src/components/formeditor/default_layoutdecoration.h69
-rw-r--r--src/designer/src/components/formeditor/defaultbrushes.xml542
-rw-r--r--src/designer/src/components/formeditor/deviceprofiledialog.cpp203
-rw-r--r--src/designer/src/components/formeditor/deviceprofiledialog.h104
-rw-r--r--src/designer/src/components/formeditor/deviceprofiledialog.ui108
-rw-r--r--src/designer/src/components/formeditor/dpi_chooser.cpp207
-rw-r--r--src/designer/src/components/formeditor/dpi_chooser.h94
-rw-r--r--src/designer/src/components/formeditor/embeddedoptionspage.cpp453
-rw-r--r--src/designer/src/components/formeditor/embeddedoptionspage.h103
-rw-r--r--src/designer/src/components/formeditor/formeditor.cpp203
-rw-r--r--src/designer/src/components/formeditor/formeditor.h69
-rw-r--r--src/designer/src/components/formeditor/formeditor.pri77
-rw-r--r--src/designer/src/components/formeditor/formeditor.qrc175
-rw-r--r--src/designer/src/components/formeditor/formeditor_global.h57
-rw-r--r--src/designer/src/components/formeditor/formeditor_optionspage.cpp191
-rw-r--r--src/designer/src/components/formeditor/formeditor_optionspage.h79
-rw-r--r--src/designer/src/components/formeditor/formwindow.cpp2981
-rw-r--r--src/designer/src/components/formeditor/formwindow.h374
-rw-r--r--src/designer/src/components/formeditor/formwindow_dnditem.cpp116
-rw-r--r--src/designer/src/components/formeditor/formwindow_dnditem.h65
-rw-r--r--src/designer/src/components/formeditor/formwindow_widgetstack.cpp217
-rw-r--r--src/designer/src/components/formeditor/formwindow_widgetstack.h102
-rw-r--r--src/designer/src/components/formeditor/formwindowcursor.cpp211
-rw-r--r--src/designer/src/components/formeditor/formwindowcursor.h93
-rw-r--r--src/designer/src/components/formeditor/formwindowmanager.cpp1036
-rw-r--r--src/designer/src/components/formeditor/formwindowmanager.h200
-rw-r--r--src/designer/src/components/formeditor/formwindowsettings.cpp282
-rw-r--r--src/designer/src/components/formeditor/formwindowsettings.h85
-rw-r--r--src/designer/src/components/formeditor/formwindowsettings.ui328
-rw-r--r--src/designer/src/components/formeditor/iconcache.cpp121
-rw-r--r--src/designer/src/components/formeditor/iconcache.h78
-rw-r--r--src/designer/src/components/formeditor/images/cleartext.pngbin0 -> 760 bytes
-rw-r--r--src/designer/src/components/formeditor/images/color.pngbin0 -> 117 bytes
-rw-r--r--src/designer/src/components/formeditor/images/configure.pngbin0 -> 1016 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/arrow.pngbin0 -> 171 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/busy.pngbin0 -> 201 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/closedhand.pngbin0 -> 147 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/cross.pngbin0 -> 130 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/hand.pngbin0 -> 159 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/hsplit.pngbin0 -> 155 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/ibeam.pngbin0 -> 124 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/no.pngbin0 -> 199 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/openhand.pngbin0 -> 160 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/sizeall.pngbin0 -> 174 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/sizeb.pngbin0 -> 161 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/sizef.pngbin0 -> 161 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/sizeh.pngbin0 -> 145 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/sizev.pngbin0 -> 141 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/uparrow.pngbin0 -> 132 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/vsplit.pngbin0 -> 161 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/wait.pngbin0 -> 172 bytes
-rw-r--r--src/designer/src/components/formeditor/images/cursors/whatsthis.pngbin0 -> 191 bytes
-rw-r--r--src/designer/src/components/formeditor/images/downplus.pngbin0 -> 562 bytes
-rw-r--r--src/designer/src/components/formeditor/images/dropdownbutton.pngbin0 -> 527 bytes
-rw-r--r--src/designer/src/components/formeditor/images/edit.pngbin0 -> 929 bytes
-rw-r--r--src/designer/src/components/formeditor/images/editdelete-16.pngbin0 -> 553 bytes
-rw-r--r--src/designer/src/components/formeditor/images/emptyicon.pngbin0 -> 108 bytes
-rw-r--r--src/designer/src/components/formeditor/images/filenew-16.pngbin0 -> 454 bytes
-rw-r--r--src/designer/src/components/formeditor/images/fileopen-16.pngbin0 -> 549 bytes
-rw-r--r--src/designer/src/components/formeditor/images/leveldown.pngbin0 -> 557 bytes
-rw-r--r--src/designer/src/components/formeditor/images/levelup.pngbin0 -> 564 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/adjustsize.pngbin0 -> 1929 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/back.pngbin0 -> 678 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/buddytool.pngbin0 -> 2046 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/down.pngbin0 -> 594 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editbreaklayout.pngbin0 -> 2067 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editcopy.pngbin0 -> 1468 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editcut.pngbin0 -> 1512 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editdelete.pngbin0 -> 1097 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editform.pngbin0 -> 621 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editgrid.pngbin0 -> 751 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/edithlayout.pngbin0 -> 1395 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/edithlayoutsplit.pngbin0 -> 1188 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editlower.pngbin0 -> 595 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editpaste.pngbin0 -> 1906 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editraise.pngbin0 -> 1213 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editvlayout.pngbin0 -> 586 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/editvlayoutsplit.pngbin0 -> 872 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/filenew.pngbin0 -> 772 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/fileopen.pngbin0 -> 904 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/filesave.pngbin0 -> 1206 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/forward.pngbin0 -> 655 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/insertimage.pngbin0 -> 1280 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/minus.pngbin0 -> 488 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/plus.pngbin0 -> 810 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/redo.pngbin0 -> 1752 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/resetproperty.pngbin0 -> 169 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/resourceeditortool.pngbin0 -> 2171 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/signalslottool.pngbin0 -> 1989 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/simplifyrichtext.pngbin0 -> 1988 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/tabordertool.pngbin0 -> 1963 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textanchor.pngbin0 -> 2543 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textbold.pngbin0 -> 1611 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textcenter.pngbin0 -> 1404 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textitalic.pngbin0 -> 1164 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textjustify.pngbin0 -> 1257 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textleft.pngbin0 -> 1235 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textright.pngbin0 -> 1406 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textsubscript.pngbin0 -> 1054 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textsuperscript.pngbin0 -> 1109 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/textunder.pngbin0 -> 1183 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/undo.pngbin0 -> 1746 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/up.pngbin0 -> 692 bytes
-rw-r--r--src/designer/src/components/formeditor/images/mac/widgettool.pngbin0 -> 1874 bytes
-rw-r--r--src/designer/src/components/formeditor/images/minus-16.pngbin0 -> 296 bytes
-rw-r--r--src/designer/src/components/formeditor/images/plus-16.pngbin0 -> 383 bytes
-rw-r--r--src/designer/src/components/formeditor/images/prefix-add.pngbin0 -> 411 bytes
-rw-r--r--src/designer/src/components/formeditor/images/qt3logo.pngbin0 -> 1101 bytes
-rw-r--r--src/designer/src/components/formeditor/images/qtlogo.pngbin0 -> 825 bytes
-rw-r--r--src/designer/src/components/formeditor/images/reload.pngbin0 -> 1363 bytes
-rw-r--r--src/designer/src/components/formeditor/images/resetproperty.pngbin0 -> 169 bytes
-rw-r--r--src/designer/src/components/formeditor/images/sort.pngbin0 -> 563 bytes
-rw-r--r--src/designer/src/components/formeditor/images/submenu.pngbin0 -> 179 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/calendarwidget.pngbin0 -> 968 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/checkbox.pngbin0 -> 817 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/columnview.pngbin0 -> 518 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/combobox.pngbin0 -> 853 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/commandlinkbutton.pngbin0 -> 1208 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/dateedit.pngbin0 -> 672 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/datetimeedit.pngbin0 -> 1132 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/dial.pngbin0 -> 978 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/dialogbuttonbox.pngbin0 -> 1003 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/dockwidget.pngbin0 -> 638 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/doublespinbox.pngbin0 -> 749 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/fontcombobox.pngbin0 -> 966 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/frame.pngbin0 -> 721 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/graphicsview.pngbin0 -> 1182 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/groupbox.pngbin0 -> 439 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/groupboxcollapsible.pngbin0 -> 702 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/hscrollbar.pngbin0 -> 408 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/hslider.pngbin0 -> 729 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/hsplit.pngbin0 -> 164 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/label.pngbin0 -> 953 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/lcdnumber.pngbin0 -> 555 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/line.pngbin0 -> 287 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/lineedit.pngbin0 -> 405 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/listbox.pngbin0 -> 797 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/listview.pngbin0 -> 756 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/mdiarea.pngbin0 -> 643 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/plaintextedit.pngbin0 -> 807 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/progress.pngbin0 -> 559 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/pushbutton.pngbin0 -> 408 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/radiobutton.pngbin0 -> 586 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/scrollarea.pngbin0 -> 548 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/spacer.pngbin0 -> 686 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/spinbox.pngbin0 -> 680 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/tabbar.pngbin0 -> 623 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/table.pngbin0 -> 483 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/tabwidget.pngbin0 -> 572 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/textedit.pngbin0 -> 823 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/timeedit.pngbin0 -> 1353 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/toolbox.pngbin0 -> 783 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/toolbutton.pngbin0 -> 1167 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/vline.pngbin0 -> 314 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/vscrollbar.pngbin0 -> 415 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/vslider.pngbin0 -> 726 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/vspacer.pngbin0 -> 677 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/widget.pngbin0 -> 716 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/widgetstack.pngbin0 -> 828 bytes
-rw-r--r--src/designer/src/components/formeditor/images/widgets/wizard.pngbin0 -> 898 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/adjustsize.pngbin0 -> 1262 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/back.pngbin0 -> 678 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/buddytool.pngbin0 -> 997 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/down.pngbin0 -> 594 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editbreaklayout.pngbin0 -> 1321 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editcopy.pngbin0 -> 1325 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editcut.pngbin0 -> 1384 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editdelete.pngbin0 -> 850 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editform.pngbin0 -> 349 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editgrid.pngbin0 -> 349 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/edithlayout.pngbin0 -> 455 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/edithlayoutsplit.pngbin0 -> 860 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editlower.pngbin0 -> 1038 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editpaste.pngbin0 -> 1482 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editraise.pngbin0 -> 1045 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editvlayout.pngbin0 -> 340 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/editvlayoutsplit.pngbin0 -> 740 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/filenew.pngbin0 -> 768 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/fileopen.pngbin0 -> 1662 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/filesave.pngbin0 -> 1205 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/forward.pngbin0 -> 655 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/insertimage.pngbin0 -> 885 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/minus.pngbin0 -> 429 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/plus.pngbin0 -> 709 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/redo.pngbin0 -> 1212 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/resourceeditortool.pngbin0 -> 1429 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/signalslottool.pngbin0 -> 1128 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/simplifyrichtext.pngbin0 -> 1933 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/tabordertool.pngbin0 -> 1205 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textanchor.pngbin0 -> 1581 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textbold.pngbin0 -> 1134 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textcenter.pngbin0 -> 627 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textitalic.pngbin0 -> 829 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textjustify.pngbin0 -> 695 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textleft.pngbin0 -> 673 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textright.pngbin0 -> 677 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textsubscript.pngbin0 -> 897 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textsuperscript.pngbin0 -> 864 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/textunder.pngbin0 -> 971 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/undo.pngbin0 -> 1181 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/up.pngbin0 -> 692 bytes
-rw-r--r--src/designer/src/components/formeditor/images/win/widgettool.pngbin0 -> 1039 bytes
-rw-r--r--src/designer/src/components/formeditor/itemview_propertysheet.cpp270
-rw-r--r--src/designer/src/components/formeditor/itemview_propertysheet.h92
-rw-r--r--src/designer/src/components/formeditor/layout_propertysheet.cpp546
-rw-r--r--src/designer/src/components/formeditor/layout_propertysheet.h82
-rw-r--r--src/designer/src/components/formeditor/line_propertysheet.cpp86
-rw-r--r--src/designer/src/components/formeditor/line_propertysheet.h71
-rw-r--r--src/designer/src/components/formeditor/previewactiongroup.cpp149
-rw-r--r--src/designer/src/components/formeditor/previewactiongroup.h90
-rw-r--r--src/designer/src/components/formeditor/qdesigner_resource.cpp2475
-rw-r--r--src/designer/src/components/formeditor/qdesigner_resource.h178
-rw-r--r--src/designer/src/components/formeditor/qdesignerundostack.cpp112
-rw-r--r--src/designer/src/components/formeditor/qdesignerundostack.h90
-rw-r--r--src/designer/src/components/formeditor/qlayoutwidget_propertysheet.cpp83
-rw-r--r--src/designer/src/components/formeditor/qlayoutwidget_propertysheet.h72
-rw-r--r--src/designer/src/components/formeditor/qmainwindow_container.cpp199
-rw-r--r--src/designer/src/components/formeditor/qmainwindow_container.h81
-rw-r--r--src/designer/src/components/formeditor/qmdiarea_container.cpp281
-rw-r--r--src/designer/src/components/formeditor/qmdiarea_container.h119
-rw-r--r--src/designer/src/components/formeditor/qtbrushmanager.cpp140
-rw-r--r--src/designer/src/components/formeditor/qtbrushmanager.h85
-rw-r--r--src/designer/src/components/formeditor/qwizard_container.cpp226
-rw-r--r--src/designer/src/components/formeditor/qwizard_container.h123
-rw-r--r--src/designer/src/components/formeditor/qworkspace_container.cpp100
-rw-r--r--src/designer/src/components/formeditor/qworkspace_container.h79
-rw-r--r--src/designer/src/components/formeditor/spacer_propertysheet.cpp82
-rw-r--r--src/designer/src/components/formeditor/spacer_propertysheet.h72
-rw-r--r--src/designer/src/components/formeditor/templateoptionspage.cpp183
-rw-r--r--src/designer/src/components/formeditor/templateoptionspage.h110
-rw-r--r--src/designer/src/components/formeditor/templateoptionspage.ui59
-rw-r--r--src/designer/src/components/formeditor/tool_widgeteditor.cpp363
-rw-r--r--src/designer/src/components/formeditor/tool_widgeteditor.h107
-rw-r--r--src/designer/src/components/formeditor/widgetselection.cpp746
-rw-r--r--src/designer/src/components/formeditor/widgetselection.h145
-rw-r--r--src/designer/src/components/lib/lib.pro77
-rw-r--r--src/designer/src/components/lib/lib_pch.h43
-rw-r--r--src/designer/src/components/lib/qdesigner_components.cpp277
-rw-r--r--src/designer/src/components/objectinspector/objectinspector.cpp835
-rw-r--r--src/designer/src/components/objectinspector/objectinspector.h95
-rw-r--r--src/designer/src/components/objectinspector/objectinspector.pri16
-rw-r--r--src/designer/src/components/objectinspector/objectinspector_global.h61
-rw-r--r--src/designer/src/components/objectinspector/objectinspectormodel.cpp516
-rw-r--r--src/designer/src/components/objectinspector/objectinspectormodel_p.h168
-rw-r--r--src/designer/src/components/propertyeditor/brushpropertymanager.cpp298
-rw-r--r--src/designer/src/components/propertyeditor/brushpropertymanager.h105
-rw-r--r--src/designer/src/components/propertyeditor/designerpropertymanager.cpp2836
-rw-r--r--src/designer/src/components/propertyeditor/designerpropertymanager.h315
-rw-r--r--src/designer/src/components/propertyeditor/fontmapping.xml73
-rw-r--r--src/designer/src/components/propertyeditor/fontpropertymanager.cpp377
-rw-r--r--src/designer/src/components/propertyeditor/fontpropertymanager.h124
-rw-r--r--src/designer/src/components/propertyeditor/newdynamicpropertydialog.cpp170
-rw-r--r--src/designer/src/components/propertyeditor/newdynamicpropertydialog.h104
-rw-r--r--src/designer/src/components/propertyeditor/newdynamicpropertydialog.ui106
-rw-r--r--src/designer/src/components/propertyeditor/paletteeditor.cpp616
-rw-r--r--src/designer/src/components/propertyeditor/paletteeditor.h204
-rw-r--r--src/designer/src/components/propertyeditor/paletteeditor.ui264
-rw-r--r--src/designer/src/components/propertyeditor/paletteeditorbutton.cpp88
-rw-r--r--src/designer/src/components/propertyeditor/paletteeditorbutton.h86
-rw-r--r--src/designer/src/components/propertyeditor/previewframe.cpp119
-rw-r--r--src/designer/src/components/propertyeditor/previewframe.h76
-rw-r--r--src/designer/src/components/propertyeditor/previewwidget.cpp59
-rw-r--r--src/designer/src/components/propertyeditor/previewwidget.h66
-rw-r--r--src/designer/src/components/propertyeditor/previewwidget.ui238
-rw-r--r--src/designer/src/components/propertyeditor/propertyeditor.cpp1294
-rw-r--r--src/designer/src/components/propertyeditor/propertyeditor.h207
-rw-r--r--src/designer/src/components/propertyeditor/propertyeditor.pri52
-rw-r--r--src/designer/src/components/propertyeditor/propertyeditor.qrc5
-rw-r--r--src/designer/src/components/propertyeditor/propertyeditor_global.h61
-rw-r--r--src/designer/src/components/propertyeditor/qlonglongvalidator.cpp153
-rw-r--r--src/designer/src/components/propertyeditor/qlonglongvalidator.h110
-rw-r--r--src/designer/src/components/propertyeditor/stringlisteditor.cpp212
-rw-r--r--src/designer/src/components/propertyeditor/stringlisteditor.h92
-rw-r--r--src/designer/src/components/propertyeditor/stringlisteditor.ui265
-rw-r--r--src/designer/src/components/propertyeditor/stringlisteditorbutton.cpp81
-rw-r--r--src/designer/src/components/propertyeditor/stringlisteditorbutton.h81
-rw-r--r--src/designer/src/components/signalsloteditor/connectdialog.cpp335
-rw-r--r--src/designer/src/components/signalsloteditor/connectdialog.ui150
-rw-r--r--src/designer/src/components/signalsloteditor/connectdialog_p.h109
-rw-r--r--src/designer/src/components/signalsloteditor/signalslot_utils.cpp334
-rw-r--r--src/designer/src/components/signalsloteditor/signalslot_utils_p.h104
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor.cpp528
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor.h98
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor.pri21
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor_global.h57
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor_instance.cpp50
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor_p.h138
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp133
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor_plugin.h92
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp123
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditor_tool.h93
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp864
-rw-r--r--src/designer/src/components/signalsloteditor/signalsloteditorwindow.h96
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor.cpp433
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor.h109
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor.pri16
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor_global.h57
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor_instance.cpp49
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor_plugin.cpp133
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor_plugin.h93
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor_tool.cpp114
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor_tool.h89
-rw-r--r--src/designer/src/components/taskmenu/button_taskmenu.cpp709
-rw-r--r--src/designer/src/components/taskmenu/button_taskmenu.h170
-rw-r--r--src/designer/src/components/taskmenu/combobox_taskmenu.cpp133
-rw-r--r--src/designer/src/components/taskmenu/combobox_taskmenu.h94
-rw-r--r--src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp348
-rw-r--r--src/designer/src/components/taskmenu/containerwidget_taskmenu.h157
-rw-r--r--src/designer/src/components/taskmenu/groupbox_taskmenu.cpp105
-rw-r--r--src/designer/src/components/taskmenu/groupbox_taskmenu.h77
-rw-r--r--src/designer/src/components/taskmenu/inplace_editor.cpp136
-rw-r--r--src/designer/src/components/taskmenu/inplace_editor.h110
-rw-r--r--src/designer/src/components/taskmenu/inplace_widget_helper.cpp120
-rw-r--r--src/designer/src/components/taskmenu/inplace_widget_helper.h88
-rw-r--r--src/designer/src/components/taskmenu/itemlisteditor.cpp478
-rw-r--r--src/designer/src/components/taskmenu/itemlisteditor.h165
-rw-r--r--src/designer/src/components/taskmenu/itemlisteditor.ui156
-rw-r--r--src/designer/src/components/taskmenu/label_taskmenu.cpp117
-rw-r--r--src/designer/src/components/taskmenu/label_taskmenu.h81
-rw-r--r--src/designer/src/components/taskmenu/layouttaskmenu.cpp93
-rw-r--r--src/designer/src/components/taskmenu/layouttaskmenu.h93
-rw-r--r--src/designer/src/components/taskmenu/lineedit_taskmenu.cpp103
-rw-r--r--src/designer/src/components/taskmenu/lineedit_taskmenu.h74
-rw-r--r--src/designer/src/components/taskmenu/listwidget_taskmenu.cpp117
-rw-r--r--src/designer/src/components/taskmenu/listwidget_taskmenu.h85
-rw-r--r--src/designer/src/components/taskmenu/listwidgeteditor.cpp138
-rw-r--r--src/designer/src/components/taskmenu/listwidgeteditor.h78
-rw-r--r--src/designer/src/components/taskmenu/menutaskmenu.cpp107
-rw-r--r--src/designer/src/components/taskmenu/menutaskmenu.h106
-rw-r--r--src/designer/src/components/taskmenu/tablewidget_taskmenu.cpp115
-rw-r--r--src/designer/src/components/taskmenu/tablewidget_taskmenu.h85
-rw-r--r--src/designer/src/components/taskmenu/tablewidgeteditor.cpp450
-rw-r--r--src/designer/src/components/taskmenu/tablewidgeteditor.h130
-rw-r--r--src/designer/src/components/taskmenu/tablewidgeteditor.ui157
-rw-r--r--src/designer/src/components/taskmenu/taskmenu.pri50
-rw-r--r--src/designer/src/components/taskmenu/taskmenu_component.cpp106
-rw-r--r--src/designer/src/components/taskmenu/taskmenu_component.h73
-rw-r--r--src/designer/src/components/taskmenu/taskmenu_global.h57
-rw-r--r--src/designer/src/components/taskmenu/textedit_taskmenu.cpp105
-rw-r--r--src/designer/src/components/taskmenu/textedit_taskmenu.h89
-rw-r--r--src/designer/src/components/taskmenu/toolbar_taskmenu.cpp111
-rw-r--r--src/designer/src/components/taskmenu/toolbar_taskmenu.h99
-rw-r--r--src/designer/src/components/taskmenu/treewidget_taskmenu.cpp114
-rw-r--r--src/designer/src/components/taskmenu/treewidget_taskmenu.h85
-rw-r--r--src/designer/src/components/taskmenu/treewidgeteditor.cpp642
-rw-r--r--src/designer/src/components/taskmenu/treewidgeteditor.h129
-rw-r--r--src/designer/src/components/taskmenu/treewidgeteditor.ui257
-rw-r--r--src/designer/src/components/widgetbox/widgetbox.cpp235
-rw-r--r--src/designer/src/components/widgetbox/widgetbox.h103
-rw-r--r--src/designer/src/components/widgetbox/widgetbox.pri14
-rw-r--r--src/designer/src/components/widgetbox/widgetbox.qrc5
-rw-r--r--src/designer/src/components/widgetbox/widgetbox.xml932
-rw-r--r--src/designer/src/components/widgetbox/widgetbox_dnditem.cpp225
-rw-r--r--src/designer/src/components/widgetbox/widgetbox_dnditem.h67
-rw-r--r--src/designer/src/components/widgetbox/widgetbox_global.h57
-rw-r--r--src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp510
-rw-r--r--src/designer/src/components/widgetbox/widgetboxcategorylistview.h118
-rw-r--r--src/designer/src/components/widgetbox/widgetboxtreewidget.cpp1001
-rw-r--r--src/designer/src/components/widgetbox/widgetboxtreewidget.h150
-rw-r--r--src/designer/src/designer/Info_mac.plist35
-rw-r--r--src/designer/src/designer/appfontdialog.cpp429
-rw-r--r--src/designer/src/designer/appfontdialog.h101
-rw-r--r--src/designer/src/designer/assistantclient.cpp175
-rw-r--r--src/designer/src/designer/assistantclient.h83
-rw-r--r--src/designer/src/designer/designer.icnsbin0 -> 154893 bytes
-rw-r--r--src/designer/src/designer/designer.icobin0 -> 355574 bytes
-rw-r--r--src/designer/src/designer/designer.pro90
-rw-r--r--src/designer/src/designer/designer.qrc5
-rw-r--r--src/designer/src/designer/designer.rc32
-rw-r--r--src/designer/src/designer/designer_enums.h52
-rw-r--r--src/designer/src/designer/images/designer.pngbin0 -> 4205 bytes
-rw-r--r--src/designer/src/designer/images/mdi.pngbin0 -> 59505 bytes
-rw-r--r--src/designer/src/designer/images/sdi.pngbin0 -> 61037 bytes
-rw-r--r--src/designer/src/designer/images/workbench.pngbin0 -> 2085 bytes
-rw-r--r--src/designer/src/designer/main.cpp58
-rw-r--r--src/designer/src/designer/mainwindow.cpp419
-rw-r--r--src/designer/src/designer/mainwindow.h187
-rw-r--r--src/designer/src/designer/newform.cpp227
-rw-r--r--src/designer/src/designer/newform.h104
-rw-r--r--src/designer/src/designer/preferencesdialog.cpp118
-rw-r--r--src/designer/src/designer/preferencesdialog.h82
-rw-r--r--src/designer/src/designer/preferencesdialog.ui91
-rw-r--r--src/designer/src/designer/qdesigner.cpp320
-rw-r--r--src/designer/src/designer/qdesigner.h102
-rw-r--r--src/designer/src/designer/qdesigner_actions.cpp1437
-rw-r--r--src/designer/src/designer/qdesigner_actions.h231
-rw-r--r--src/designer/src/designer/qdesigner_appearanceoptions.cpp167
-rw-r--r--src/designer/src/designer/qdesigner_appearanceoptions.h136
-rw-r--r--src/designer/src/designer/qdesigner_appearanceoptions.ui57
-rw-r--r--src/designer/src/designer/qdesigner_formwindow.cpp290
-rw-r--r--src/designer/src/designer/qdesigner_formwindow.h97
-rw-r--r--src/designer/src/designer/qdesigner_pch.h59
-rw-r--r--src/designer/src/designer/qdesigner_server.cpp156
-rw-r--r--src/designer/src/designer/qdesigner_server.h89
-rw-r--r--src/designer/src/designer/qdesigner_settings.cpp250
-rw-r--r--src/designer/src/designer/qdesigner_settings.h94
-rw-r--r--src/designer/src/designer/qdesigner_toolwindow.cpp438
-rw-r--r--src/designer/src/designer/qdesigner_toolwindow.h123
-rw-r--r--src/designer/src/designer/qdesigner_workbench.cpp1100
-rw-r--r--src/designer/src/designer/qdesigner_workbench.h215
-rw-r--r--src/designer/src/designer/saveformastemplate.cpp173
-rw-r--r--src/designer/src/designer/saveformastemplate.h77
-rw-r--r--src/designer/src/designer/saveformastemplate.ui166
-rw-r--r--src/designer/src/designer/uifile.icnsbin0 -> 123696 bytes
-rw-r--r--src/designer/src/designer/versiondialog.cpp191
-rw-r--r--src/designer/src/designer/versiondialog.h58
-rw-r--r--src/designer/src/lib/components/qdesigner_components.h82
-rw-r--r--src/designer/src/lib/components/qdesigner_components_global.h66
-rw-r--r--src/designer/src/lib/extension/default_extensionfactory.cpp178
-rw-r--r--src/designer/src/lib/extension/default_extensionfactory.h86
-rw-r--r--src/designer/src/lib/extension/extension.cpp186
-rw-r--r--src/designer/src/lib/extension/extension.h109
-rw-r--r--src/designer/src/lib/extension/extension.pri12
-rw-r--r--src/designer/src/lib/extension/extension_global.h64
-rw-r--r--src/designer/src/lib/extension/qextensionmanager.cpp174
-rw-r--r--src/designer/src/lib/extension/qextensionmanager.h79
-rw-r--r--src/designer/src/lib/lib.pro78
-rw-r--r--src/designer/src/lib/lib_pch.h65
-rw-r--r--src/designer/src/lib/sdk/abstractactioneditor.cpp123
-rw-r--r--src/designer/src/lib/sdk/abstractactioneditor.h76
-rw-r--r--src/designer/src/lib/sdk/abstractbrushmanager.h83
-rw-r--r--src/designer/src/lib/sdk/abstractdialoggui.cpp161
-rw-r--r--src/designer/src/lib/sdk/abstractdialoggui_p.h107
-rw-r--r--src/designer/src/lib/sdk/abstractdnditem.h75
-rw-r--r--src/designer/src/lib/sdk/abstractdnditem.qdoc98
-rw-r--r--src/designer/src/lib/sdk/abstractformeditor.cpp630
-rw-r--r--src/designer/src/lib/sdk/abstractformeditor.h159
-rw-r--r--src/designer/src/lib/sdk/abstractformeditorplugin.cpp86
-rw-r--r--src/designer/src/lib/sdk/abstractformeditorplugin.h73
-rw-r--r--src/designer/src/lib/sdk/abstractformwindow.cpp814
-rw-r--r--src/designer/src/lib/sdk/abstractformwindow.h183
-rw-r--r--src/designer/src/lib/sdk/abstractformwindowcursor.cpp252
-rw-r--r--src/designer/src/lib/sdk/abstractformwindowcursor.h109
-rw-r--r--src/designer/src/lib/sdk/abstractformwindowmanager.cpp502
-rw-r--r--src/designer/src/lib/sdk/abstractformwindowmanager.h122
-rw-r--r--src/designer/src/lib/sdk/abstractformwindowtool.cpp106
-rw-r--r--src/designer/src/lib/sdk/abstractformwindowtool.h85
-rw-r--r--src/designer/src/lib/sdk/abstracticoncache.h83
-rw-r--r--src/designer/src/lib/sdk/abstracticoncache.qdoc116
-rw-r--r--src/designer/src/lib/sdk/abstractintegration.cpp105
-rw-r--r--src/designer/src/lib/sdk/abstractintegration.h86
-rw-r--r--src/designer/src/lib/sdk/abstractintrospection.cpp548
-rw-r--r--src/designer/src/lib/sdk/abstractintrospection_p.h174
-rw-r--r--src/designer/src/lib/sdk/abstractlanguage.h100
-rw-r--r--src/designer/src/lib/sdk/abstractmetadatabase.cpp170
-rw-r--r--src/designer/src/lib/sdk/abstractmetadatabase.h99
-rw-r--r--src/designer/src/lib/sdk/abstractnewformwidget.cpp117
-rw-r--r--src/designer/src/lib/sdk/abstractnewformwidget_p.h88
-rw-r--r--src/designer/src/lib/sdk/abstractobjectinspector.cpp110
-rw-r--r--src/designer/src/lib/sdk/abstractobjectinspector.h73
-rw-r--r--src/designer/src/lib/sdk/abstractoptionspage_p.h79
-rw-r--r--src/designer/src/lib/sdk/abstractpromotioninterface.cpp113
-rw-r--r--src/designer/src/lib/sdk/abstractpromotioninterface.h91
-rw-r--r--src/designer/src/lib/sdk/abstractpropertyeditor.cpp193
-rw-r--r--src/designer/src/lib/sdk/abstractpropertyeditor.h84
-rw-r--r--src/designer/src/lib/sdk/abstractresourcebrowser.cpp57
-rw-r--r--src/designer/src/lib/sdk/abstractresourcebrowser.h75
-rw-r--r--src/designer/src/lib/sdk/abstractsettings_p.h87
-rw-r--r--src/designer/src/lib/sdk/abstractwidgetbox.cpp340
-rw-r--r--src/designer/src/lib/sdk/abstractwidgetbox.h142
-rw-r--r--src/designer/src/lib/sdk/abstractwidgetdatabase.cpp360
-rw-r--r--src/designer/src/lib/sdk/abstractwidgetdatabase.h137
-rw-r--r--src/designer/src/lib/sdk/abstractwidgetfactory.cpp112
-rw-r--r--src/designer/src/lib/sdk/abstractwidgetfactory.h79
-rw-r--r--src/designer/src/lib/sdk/dynamicpropertysheet.h81
-rw-r--r--src/designer/src/lib/sdk/dynamicpropertysheet.qdoc80
-rw-r--r--src/designer/src/lib/sdk/extrainfo.cpp116
-rw-r--r--src/designer/src/lib/sdk/extrainfo.h84
-rw-r--r--src/designer/src/lib/sdk/layoutdecoration.h99
-rw-r--r--src/designer/src/lib/sdk/layoutdecoration.qdoc149
-rw-r--r--src/designer/src/lib/sdk/membersheet.h89
-rw-r--r--src/designer/src/lib/sdk/membersheet.qdoc249
-rw-r--r--src/designer/src/lib/sdk/propertysheet.h90
-rw-r--r--src/designer/src/lib/sdk/propertysheet.qdoc288
-rw-r--r--src/designer/src/lib/sdk/script.cpp109
-rw-r--r--src/designer/src/lib/sdk/script_p.h83
-rw-r--r--src/designer/src/lib/sdk/sdk.pri58
-rw-r--r--src/designer/src/lib/sdk/sdk_global.h64
-rw-r--r--src/designer/src/lib/sdk/taskmenu.h72
-rw-r--r--src/designer/src/lib/sdk/taskmenu.qdoc138
-rw-r--r--src/designer/src/lib/shared/actioneditor.cpp823
-rw-r--r--src/designer/src/lib/shared/actioneditor_p.h168
-rw-r--r--src/designer/src/lib/shared/actionprovider_p.h108
-rw-r--r--src/designer/src/lib/shared/actionrepository.cpp665
-rw-r--r--src/designer/src/lib/shared/actionrepository_p.h269
-rw-r--r--src/designer/src/lib/shared/addlinkdialog.ui112
-rw-r--r--src/designer/src/lib/shared/codedialog.cpp262
-rw-r--r--src/designer/src/lib/shared/codedialog_p.h100
-rw-r--r--src/designer/src/lib/shared/connectionedit.cpp1612
-rw-r--r--src/designer/src/lib/shared/connectionedit_p.h324
-rw-r--r--src/designer/src/lib/shared/csshighlighter.cpp188
-rw-r--r--src/designer/src/lib/shared/csshighlighter_p.h82
-rw-r--r--src/designer/src/lib/shared/defaultgradients.xml498
-rw-r--r--src/designer/src/lib/shared/deviceprofile.cpp467
-rw-r--r--src/designer/src/lib/shared/deviceprofile_p.h152
-rw-r--r--src/designer/src/lib/shared/dialoggui.cpp265
-rw-r--r--src/designer/src/lib/shared/dialoggui_p.h107
-rw-r--r--src/designer/src/lib/shared/extensionfactory_p.h120
-rw-r--r--src/designer/src/lib/shared/filterwidget.cpp252
-rw-r--r--src/designer/src/lib/shared/filterwidget_p.h151
-rw-r--r--src/designer/src/lib/shared/formlayoutmenu.cpp534
-rw-r--r--src/designer/src/lib/shared/formlayoutmenu_p.h100
-rw-r--r--src/designer/src/lib/shared/formlayoutrowdialog.ui166
-rw-r--r--src/designer/src/lib/shared/formwindowbase.cpp502
-rw-r--r--src/designer/src/lib/shared/formwindowbase_p.h205
-rw-r--r--src/designer/src/lib/shared/grid.cpp194
-rw-r--r--src/designer/src/lib/shared/grid_p.h118
-rw-r--r--src/designer/src/lib/shared/gridpanel.cpp121
-rw-r--r--src/designer/src/lib/shared/gridpanel.ui144
-rw-r--r--src/designer/src/lib/shared/gridpanel_p.h101
-rw-r--r--src/designer/src/lib/shared/htmlhighlighter.cpp198
-rw-r--r--src/designer/src/lib/shared/htmlhighlighter_p.h101
-rw-r--r--src/designer/src/lib/shared/iconloader.cpp79
-rw-r--r--src/designer/src/lib/shared/iconloader_p.h72
-rw-r--r--src/designer/src/lib/shared/iconselector.cpp655
-rw-r--r--src/designer/src/lib/shared/iconselector_p.h172
-rw-r--r--src/designer/src/lib/shared/invisible_widget.cpp57
-rw-r--r--src/designer/src/lib/shared/invisible_widget_p.h75
-rw-r--r--src/designer/src/lib/shared/layout.cpp1332
-rw-r--r--src/designer/src/lib/shared/layout_p.h152
-rw-r--r--src/designer/src/lib/shared/layoutinfo.cpp312
-rw-r--r--src/designer/src/lib/shared/layoutinfo_p.h114
-rw-r--r--src/designer/src/lib/shared/metadatabase.cpp295
-rw-r--r--src/designer/src/lib/shared/metadatabase_p.h142
-rw-r--r--src/designer/src/lib/shared/morphmenu.cpp635
-rw-r--r--src/designer/src/lib/shared/morphmenu_p.h97
-rw-r--r--src/designer/src/lib/shared/newactiondialog.cpp199
-rw-r--r--src/designer/src/lib/shared/newactiondialog.ui313
-rw-r--r--src/designer/src/lib/shared/newactiondialog_p.h124
-rw-r--r--src/designer/src/lib/shared/newformwidget.cpp586
-rw-r--r--src/designer/src/lib/shared/newformwidget.ui192
-rw-r--r--src/designer/src/lib/shared/newformwidget_p.h143
-rw-r--r--src/designer/src/lib/shared/orderdialog.cpp188
-rw-r--r--src/designer/src/lib/shared/orderdialog.ui198
-rw-r--r--src/designer/src/lib/shared/orderdialog_p.h114
-rw-r--r--src/designer/src/lib/shared/plaintexteditor.cpp119
-rw-r--r--src/designer/src/lib/shared/plaintexteditor_p.h89
-rw-r--r--src/designer/src/lib/shared/plugindialog.cpp207
-rw-r--r--src/designer/src/lib/shared/plugindialog.ui136
-rw-r--r--src/designer/src/lib/shared/plugindialog_p.h92
-rw-r--r--src/designer/src/lib/shared/pluginmanager.cpp786
-rw-r--r--src/designer/src/lib/shared/pluginmanager_p.h159
-rw-r--r--src/designer/src/lib/shared/previewconfigurationwidget.cpp366
-rw-r--r--src/designer/src/lib/shared/previewconfigurationwidget.ui91
-rw-r--r--src/designer/src/lib/shared/previewconfigurationwidget_p.h96
-rw-r--r--src/designer/src/lib/shared/previewmanager.cpp943
-rw-r--r--src/designer/src/lib/shared/previewmanager_p.h184
-rw-r--r--src/designer/src/lib/shared/promotionmodel.cpp220
-rw-r--r--src/designer/src/lib/shared/promotionmodel_p.h98
-rw-r--r--src/designer/src/lib/shared/promotiontaskmenu.cpp361
-rw-r--r--src/designer/src/lib/shared/promotiontaskmenu_p.h151
-rw-r--r--src/designer/src/lib/shared/propertylineedit.cpp96
-rw-r--r--src/designer/src/lib/shared/propertylineedit_p.h85
-rw-r--r--src/designer/src/lib/shared/qdesigner_command.cpp2968
-rw-r--r--src/designer/src/lib/shared/qdesigner_command2.cpp221
-rw-r--r--src/designer/src/lib/shared/qdesigner_command2_p.h123
-rw-r--r--src/designer/src/lib/shared/qdesigner_command_p.h1136
-rw-r--r--src/designer/src/lib/shared/qdesigner_dnditem.cpp300
-rw-r--r--src/designer/src/lib/shared/qdesigner_dnditem_p.h147
-rw-r--r--src/designer/src/lib/shared/qdesigner_dockwidget.cpp140
-rw-r--r--src/designer/src/lib/shared/qdesigner_dockwidget_p.h87
-rw-r--r--src/designer/src/lib/shared/qdesigner_formbuilder.cpp498
-rw-r--r--src/designer/src/lib/shared/qdesigner_formbuilder_p.h181
-rw-r--r--src/designer/src/lib/shared/qdesigner_formeditorcommand.cpp64
-rw-r--r--src/designer/src/lib/shared/qdesigner_formeditorcommand_p.h83
-rw-r--r--src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp151
-rw-r--r--src/designer/src/lib/shared/qdesigner_formwindowcommand_p.h98
-rw-r--r--src/designer/src/lib/shared/qdesigner_formwindowmanager.cpp167
-rw-r--r--src/designer/src/lib/shared/qdesigner_formwindowmanager_p.h99
-rw-r--r--src/designer/src/lib/shared/qdesigner_integration.cpp496
-rw-r--r--src/designer/src/lib/shared/qdesigner_integration_p.h152
-rw-r--r--src/designer/src/lib/shared/qdesigner_introspection.cpp372
-rw-r--r--src/designer/src/lib/shared/qdesigner_introspection_p.h84
-rw-r--r--src/designer/src/lib/shared/qdesigner_membersheet.cpp371
-rw-r--r--src/designer/src/lib/shared/qdesigner_membersheet_p.h120
-rw-r--r--src/designer/src/lib/shared/qdesigner_menu.cpp1390
-rw-r--r--src/designer/src/lib/shared/qdesigner_menu_p.h208
-rw-r--r--src/designer/src/lib/shared/qdesigner_menubar.cpp979
-rw-r--r--src/designer/src/lib/shared/qdesigner_menubar_p.h179
-rw-r--r--src/designer/src/lib/shared/qdesigner_objectinspector.cpp80
-rw-r--r--src/designer/src/lib/shared/qdesigner_objectinspector_p.h103
-rw-r--r--src/designer/src/lib/shared/qdesigner_promotion.cpp373
-rw-r--r--src/designer/src/lib/shared/qdesigner_promotion_p.h98
-rw-r--r--src/designer/src/lib/shared/qdesigner_promotiondialog.cpp456
-rw-r--r--src/designer/src/lib/shared/qdesigner_promotiondialog_p.h170
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertycommand.cpp1503
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertycommand_p.h313
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertyeditor.cpp169
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertyeditor_p.h112
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertysheet.cpp1657
-rw-r--r--src/designer/src/lib/shared/qdesigner_propertysheet_p.h266
-rw-r--r--src/designer/src/lib/shared/qdesigner_qsettings.cpp94
-rw-r--r--src/designer/src/lib/shared/qdesigner_qsettings_p.h88
-rw-r--r--src/designer/src/lib/shared/qdesigner_stackedbox.cpp399
-rw-r--r--src/designer/src/lib/shared/qdesigner_stackedbox_p.h164
-rw-r--r--src/designer/src/lib/shared/qdesigner_tabwidget.cpp572
-rw-r--r--src/designer/src/lib/shared/qdesigner_tabwidget_p.h153
-rw-r--r--src/designer/src/lib/shared/qdesigner_taskmenu.cpp912
-rw-r--r--src/designer/src/lib/shared/qdesigner_taskmenu_p.h133
-rw-r--r--src/designer/src/lib/shared/qdesigner_toolbar.cpp488
-rw-r--r--src/designer/src/lib/shared/qdesigner_toolbar_p.h135
-rw-r--r--src/designer/src/lib/shared/qdesigner_toolbox.cpp437
-rw-r--r--src/designer/src/lib/shared/qdesigner_toolbox_p.h140
-rw-r--r--src/designer/src/lib/shared/qdesigner_utils.cpp848
-rw-r--r--src/designer/src/lib/shared/qdesigner_utils_p.h499
-rw-r--r--src/designer/src/lib/shared/qdesigner_widget.cpp108
-rw-r--r--src/designer/src/lib/shared/qdesigner_widget_p.h122
-rw-r--r--src/designer/src/lib/shared/qdesigner_widgetbox.cpp181
-rw-r--r--src/designer/src/lib/shared/qdesigner_widgetbox_p.h101
-rw-r--r--src/designer/src/lib/shared/qdesigner_widgetitem.cpp345
-rw-r--r--src/designer/src/lib/shared/qdesigner_widgetitem_p.h147
-rw-r--r--src/designer/src/lib/shared/qlayout_widget.cpp2107
-rw-r--r--src/designer/src/lib/shared/qlayout_widget_p.h292
-rw-r--r--src/designer/src/lib/shared/qscripthighlighter.cpp468
-rw-r--r--src/designer/src/lib/shared/qscripthighlighter_p.h84
-rw-r--r--src/designer/src/lib/shared/qsimpleresource.cpp418
-rw-r--r--src/designer/src/lib/shared/qsimpleresource_p.h164
-rw-r--r--src/designer/src/lib/shared/qtresourceeditordialog.cpp2223
-rw-r--r--src/designer/src/lib/shared/qtresourceeditordialog.ui177
-rw-r--r--src/designer/src/lib/shared/qtresourceeditordialog_p.h130
-rw-r--r--src/designer/src/lib/shared/qtresourcemodel.cpp650
-rw-r--r--src/designer/src/lib/shared/qtresourcemodel_p.h145
-rw-r--r--src/designer/src/lib/shared/qtresourceview.cpp906
-rw-r--r--src/designer/src/lib/shared/qtresourceview_p.h141
-rw-r--r--src/designer/src/lib/shared/richtexteditor.cpp906
-rw-r--r--src/designer/src/lib/shared/richtexteditor_p.h103
-rw-r--r--src/designer/src/lib/shared/scriptcommand.cpp103
-rw-r--r--src/designer/src/lib/shared/scriptcommand_p.h93
-rw-r--r--src/designer/src/lib/shared/scriptdialog.cpp130
-rw-r--r--src/designer/src/lib/shared/scriptdialog_p.h90
-rw-r--r--src/designer/src/lib/shared/scripterrordialog.cpp108
-rw-r--r--src/designer/src/lib/shared/scripterrordialog_p.h83
-rw-r--r--src/designer/src/lib/shared/selectsignaldialog.ui93
-rw-r--r--src/designer/src/lib/shared/shared.pri189
-rw-r--r--src/designer/src/lib/shared/shared.qrc20
-rw-r--r--src/designer/src/lib/shared/shared_enums_p.h99
-rw-r--r--src/designer/src/lib/shared/shared_global_p.h76
-rw-r--r--src/designer/src/lib/shared/shared_settings.cpp321
-rw-r--r--src/designer/src/lib/shared/shared_settings_p.h142
-rw-r--r--src/designer/src/lib/shared/sheet_delegate.cpp112
-rw-r--r--src/designer/src/lib/shared/sheet_delegate_p.h85
-rw-r--r--src/designer/src/lib/shared/signalslotdialog.cpp526
-rw-r--r--src/designer/src/lib/shared/signalslotdialog.ui129
-rw-r--r--src/designer/src/lib/shared/signalslotdialog_p.h173
-rw-r--r--src/designer/src/lib/shared/spacer_widget.cpp280
-rw-r--r--src/designer/src/lib/shared/spacer_widget_p.h117
-rw-r--r--src/designer/src/lib/shared/stylesheeteditor.cpp409
-rw-r--r--src/designer/src/lib/shared/stylesheeteditor_p.h144
-rw-r--r--src/designer/src/lib/shared/templates/forms/240x320/Dialog_with_Buttons_Bottom.ui67
-rw-r--r--src/designer/src/lib/shared/templates/forms/240x320/Dialog_with_Buttons_Right.ui67
-rw-r--r--src/designer/src/lib/shared/templates/forms/320x240/Dialog_with_Buttons_Bottom.ui67
-rw-r--r--src/designer/src/lib/shared/templates/forms/320x240/Dialog_with_Buttons_Right.ui67
-rw-r--r--src/designer/src/lib/shared/templates/forms/480x640/Dialog_with_Buttons_Bottom.ui67
-rw-r--r--src/designer/src/lib/shared/templates/forms/480x640/Dialog_with_Buttons_Right.ui67
-rw-r--r--src/designer/src/lib/shared/templates/forms/640x480/Dialog_with_Buttons_Bottom.ui67
-rw-r--r--src/designer/src/lib/shared/templates/forms/640x480/Dialog_with_Buttons_Right.ui67
-rw-r--r--src/designer/src/lib/shared/templates/forms/Dialog_with_Buttons_Bottom.ui71
-rw-r--r--src/designer/src/lib/shared/templates/forms/Dialog_with_Buttons_Right.ui71
-rw-r--r--src/designer/src/lib/shared/templates/forms/Dialog_without_Buttons.ui18
-rw-r--r--src/designer/src/lib/shared/templates/forms/Main_Window.ui24
-rw-r--r--src/designer/src/lib/shared/templates/forms/Widget.ui21
-rw-r--r--src/designer/src/lib/shared/textpropertyeditor.cpp430
-rw-r--r--src/designer/src/lib/shared/textpropertyeditor_p.h156
-rw-r--r--src/designer/src/lib/shared/widgetdatabase.cpp865
-rw-r--r--src/designer/src/lib/shared/widgetdatabase_p.h210
-rw-r--r--src/designer/src/lib/shared/widgetfactory.cpp899
-rw-r--r--src/designer/src/lib/shared/widgetfactory_p.h191
-rw-r--r--src/designer/src/lib/shared/zoomwidget.cpp570
-rw-r--r--src/designer/src/lib/shared/zoomwidget_p.h231
-rw-r--r--src/designer/src/plugins/activeqt/activeqt.pro32
-rw-r--r--src/designer/src/plugins/activeqt/qaxwidgetextrainfo.cpp117
-rw-r--r--src/designer/src/plugins/activeqt/qaxwidgetextrainfo.h91
-rw-r--r--src/designer/src/plugins/activeqt/qaxwidgetplugin.cpp146
-rw-r--r--src/designer/src/plugins/activeqt/qaxwidgetplugin.h77
-rw-r--r--src/designer/src/plugins/activeqt/qaxwidgetpropertysheet.cpp189
-rw-r--r--src/designer/src/plugins/activeqt/qaxwidgetpropertysheet.h99
-rw-r--r--src/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp186
-rw-r--r--src/designer/src/plugins/activeqt/qaxwidgettaskmenu.h76
-rw-r--r--src/designer/src/plugins/activeqt/qdesigneraxwidget.cpp272
-rw-r--r--src/designer/src/plugins/activeqt/qdesigneraxwidget.h142
-rw-r--r--src/designer/src/plugins/phononwidgets/images/seekslider.pngbin0 -> 444 bytes
-rw-r--r--src/designer/src/plugins/phononwidgets/images/videoplayer.pngbin0 -> 644 bytes
-rw-r--r--src/designer/src/plugins/phononwidgets/images/videowidget.pngbin0 -> 794 bytes
-rw-r--r--src/designer/src/plugins/phononwidgets/images/volumeslider.pngbin0 -> 470 bytes
-rw-r--r--src/designer/src/plugins/phononwidgets/phononcollection.cpp82
-rw-r--r--src/designer/src/plugins/phononwidgets/phononwidgets.pro24
-rw-r--r--src/designer/src/plugins/phononwidgets/phononwidgets.qrc8
-rw-r--r--src/designer/src/plugins/phononwidgets/seeksliderplugin.cpp117
-rw-r--r--src/designer/src/plugins/phononwidgets/seeksliderplugin.h75
-rw-r--r--src/designer/src/plugins/phononwidgets/videoplayerplugin.cpp135
-rw-r--r--src/designer/src/plugins/phononwidgets/videoplayerplugin.h75
-rw-r--r--src/designer/src/plugins/phononwidgets/videoplayertaskmenu.cpp154
-rw-r--r--src/designer/src/plugins/phononwidgets/videoplayertaskmenu.h83
-rw-r--r--src/designer/src/plugins/phononwidgets/volumesliderplugin.cpp117
-rw-r--r--src/designer/src/plugins/phononwidgets/volumesliderplugin.h75
-rw-r--r--src/designer/src/plugins/plugins.pri8
-rw-r--r--src/designer/src/plugins/plugins.pro10
-rw-r--r--src/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro13
-rw-r--r--src/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp132
-rw-r--r--src/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h74
-rw-r--r--src/designer/src/plugins/qwebview/images/qwebview.pngbin0 -> 1473 bytes
-rw-r--r--src/designer/src/plugins/qwebview/qwebview.pro15
-rw-r--r--src/designer/src/plugins/qwebview/qwebview_plugin.cpp137
-rw-r--r--src/designer/src/plugins/qwebview/qwebview_plugin.h74
-rw-r--r--src/designer/src/plugins/qwebview/qwebview_plugin.qrc5
-rw-r--r--src/designer/src/plugins/tools/view3d/view3d.cpp492
-rw-r--r--src/designer/src/plugins/tools/view3d/view3d.h77
-rw-r--r--src/designer/src/plugins/tools/view3d/view3d.pro17
-rw-r--r--src/designer/src/plugins/tools/view3d/view3d_global.h61
-rw-r--r--src/designer/src/plugins/tools/view3d/view3d_plugin.cpp115
-rw-r--r--src/designer/src/plugins/tools/view3d/view3d_plugin.h82
-rw-r--r--src/designer/src/plugins/tools/view3d/view3d_tool.cpp88
-rw-r--r--src/designer/src/plugins/tools/view3d/view3d_tool.h76
-rw-r--r--src/designer/src/plugins/widgets/q3iconview/q3iconview_extrainfo.cpp183
-rw-r--r--src/designer/src/plugins/widgets/q3iconview/q3iconview_extrainfo.h95
-rw-r--r--src/designer/src/plugins/widgets/q3iconview/q3iconview_plugin.cpp120
-rw-r--r--src/designer/src/plugins/widgets/q3iconview/q3iconview_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/q3listbox/q3listbox_extrainfo.cpp151
-rw-r--r--src/designer/src/plugins/widgets/q3listbox/q3listbox_extrainfo.h93
-rw-r--r--src/designer/src/plugins/widgets/q3listbox/q3listbox_plugin.cpp121
-rw-r--r--src/designer/src/plugins/widgets/q3listbox/q3listbox_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/q3listview/q3listview_extrainfo.cpp249
-rw-r--r--src/designer/src/plugins/widgets/q3listview/q3listview_extrainfo.h96
-rw-r--r--src/designer/src/plugins/widgets/q3listview/q3listview_plugin.cpp121
-rw-r--r--src/designer/src/plugins/widgets/q3listview/q3listview_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_container.cpp130
-rw-r--r--src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_container.h84
-rw-r--r--src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.cpp118
-rw-r--r--src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/q3table/q3table_extrainfo.cpp196
-rw-r--r--src/designer/src/plugins/widgets/q3table/q3table_extrainfo.h93
-rw-r--r--src/designer/src/plugins/widgets/q3table/q3table_plugin.cpp121
-rw-r--r--src/designer/src/plugins/widgets/q3table/q3table_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/q3textedit/q3textedit_extrainfo.cpp116
-rw-r--r--src/designer/src/plugins/widgets/q3textedit/q3textedit_extrainfo.h93
-rw-r--r--src/designer/src/plugins/widgets/q3textedit/q3textedit_plugin.cpp122
-rw-r--r--src/designer/src/plugins/widgets/q3textedit/q3textedit_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.cpp108
-rw-r--r--src/designer/src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.h92
-rw-r--r--src/designer/src/plugins/widgets/q3toolbar/q3toolbar_plugin.cpp128
-rw-r--r--src/designer/src/plugins/widgets/q3toolbar/q3toolbar_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/q3widgets/q3widget_plugins.cpp601
-rw-r--r--src/designer/src/plugins/widgets/q3widgets/q3widget_plugins.h287
-rw-r--r--src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_container.cpp115
-rw-r--r--src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_container.h84
-rw-r--r--src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.cpp118
-rw-r--r--src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack.cpp217
-rw-r--r--src/designer/src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack_p.h108
-rw-r--r--src/designer/src/plugins/widgets/q3wizard/q3wizard_container.cpp235
-rw-r--r--src/designer/src/plugins/widgets/q3wizard/q3wizard_container.h149
-rw-r--r--src/designer/src/plugins/widgets/q3wizard/q3wizard_plugin.cpp128
-rw-r--r--src/designer/src/plugins/widgets/q3wizard/q3wizard_plugin.h76
-rw-r--r--src/designer/src/plugins/widgets/qt3supportwidgets.cpp107
-rw-r--r--src/designer/src/plugins/widgets/widgets.pro82
-rw-r--r--src/designer/src/sharedcomponents.pri30
-rw-r--r--src/designer/src/src.pro12
-rw-r--r--src/doxygen/config/footer.html8
-rw-r--r--src/doxygen/config/header.html30
-rw-r--r--src/doxygen/config/phonon.css114
-rw-r--r--src/doxygen/config/phonon.doxyfile220
-rw-r--r--src/kmap2qmap/kmap2qmap.pro12
-rw-r--r--src/kmap2qmap/main.cpp991
-rw-r--r--src/linguist/lconvert/lconvert.pro22
-rw-r--r--src/linguist/lconvert/main.cpp301
-rw-r--r--src/linguist/linguist.pro6
-rw-r--r--src/linguist/linguist/Info_mac.plist18
-rw-r--r--src/linguist/linguist/batchtranslation.ui260
-rw-r--r--src/linguist/linguist/batchtranslationdialog.cpp194
-rw-r--r--src/linguist/linguist/batchtranslationdialog.h87
-rw-r--r--src/linguist/linguist/errorsview.cpp118
-rw-r--r--src/linguist/linguist/errorsview.h78
-rw-r--r--src/linguist/linguist/finddialog.cpp94
-rw-r--r--src/linguist/linguist/finddialog.h69
-rw-r--r--src/linguist/linguist/finddialog.ui266
-rw-r--r--src/linguist/linguist/formpreviewview.cpp537
-rw-r--r--src/linguist/linguist/formpreviewview.h128
-rw-r--r--src/linguist/linguist/globals.cpp55
-rw-r--r--src/linguist/linguist/globals.h50
-rw-r--r--src/linguist/linguist/images/appicon.pngbin0 -> 1382 bytes
-rw-r--r--src/linguist/linguist/images/down.pngbin0 -> 594 bytes
-rw-r--r--src/linguist/linguist/images/editdelete.pngbin0 -> 831 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-128-32.pngbin0 -> 5960 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-128-8.pngbin0 -> 5947 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-16-32.pngbin0 -> 537 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-16-8.pngbin0 -> 608 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-32-32.pngbin0 -> 1382 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-32-8.pngbin0 -> 1369 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-48-32.pngbin0 -> 2017 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-48-8.pngbin0 -> 1972 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-64-32.pngbin0 -> 2773 bytes
-rw-r--r--src/linguist/linguist/images/icons/linguist-64-8.pngbin0 -> 2664 bytes
-rw-r--r--src/linguist/linguist/images/mac/accelerator.pngbin0 -> 1921 bytes
-rw-r--r--src/linguist/linguist/images/mac/book.pngbin0 -> 1477 bytes
-rw-r--r--src/linguist/linguist/images/mac/doneandnext.pngbin0 -> 1590 bytes
-rw-r--r--src/linguist/linguist/images/mac/editcopy.pngbin0 -> 1468 bytes
-rw-r--r--src/linguist/linguist/images/mac/editcut.pngbin0 -> 1512 bytes
-rw-r--r--src/linguist/linguist/images/mac/editpaste.pngbin0 -> 1906 bytes
-rw-r--r--src/linguist/linguist/images/mac/filenew.pngbin0 -> 1172 bytes
-rw-r--r--src/linguist/linguist/images/mac/fileopen.pngbin0 -> 2168 bytes
-rw-r--r--src/linguist/linguist/images/mac/fileprint.pngbin0 -> 741 bytes
-rw-r--r--src/linguist/linguist/images/mac/filesave.pngbin0 -> 1206 bytes
-rw-r--r--src/linguist/linguist/images/mac/next.pngbin0 -> 1056 bytes
-rw-r--r--src/linguist/linguist/images/mac/nextunfinished.pngbin0 -> 1756 bytes
-rw-r--r--src/linguist/linguist/images/mac/phrase.pngbin0 -> 1932 bytes
-rw-r--r--src/linguist/linguist/images/mac/prev.pngbin0 -> 1080 bytes
-rw-r--r--src/linguist/linguist/images/mac/prevunfinished.pngbin0 -> 1682 bytes
-rw-r--r--src/linguist/linguist/images/mac/print.pngbin0 -> 2087 bytes
-rw-r--r--src/linguist/linguist/images/mac/punctuation.pngbin0 -> 1593 bytes
-rw-r--r--src/linguist/linguist/images/mac/redo.pngbin0 -> 1752 bytes
-rw-r--r--src/linguist/linguist/images/mac/searchfind.pngbin0 -> 1836 bytes
-rw-r--r--src/linguist/linguist/images/mac/undo.pngbin0 -> 1746 bytes
-rw-r--r--src/linguist/linguist/images/mac/validateplacemarkers.pngbin0 -> 1452 bytes
-rw-r--r--src/linguist/linguist/images/mac/whatsthis.pngbin0 -> 1586 bytes
-rw-r--r--src/linguist/linguist/images/minus.pngbin0 -> 296 bytes
-rw-r--r--src/linguist/linguist/images/plus.pngbin0 -> 383 bytes
-rw-r--r--src/linguist/linguist/images/s_check_danger.pngbin0 -> 304 bytes
-rw-r--r--src/linguist/linguist/images/s_check_empty.pngbin0 -> 404 bytes
-rw-r--r--src/linguist/linguist/images/s_check_obsolete.pngbin0 -> 192 bytes
-rw-r--r--src/linguist/linguist/images/s_check_off.pngbin0 -> 434 bytes
-rw-r--r--src/linguist/linguist/images/s_check_on.pngbin0 -> 192 bytes
-rw-r--r--src/linguist/linguist/images/s_check_warning.pngbin0 -> 192 bytes
-rw-r--r--src/linguist/linguist/images/splash.pngbin0 -> 15637 bytes
-rw-r--r--src/linguist/linguist/images/up.pngbin0 -> 692 bytes
-rw-r--r--src/linguist/linguist/images/win/accelerator.pngbin0 -> 1335 bytes
-rw-r--r--src/linguist/linguist/images/win/book.pngbin0 -> 1109 bytes
-rw-r--r--src/linguist/linguist/images/win/doneandnext.pngbin0 -> 1233 bytes
-rw-r--r--src/linguist/linguist/images/win/editcopy.pngbin0 -> 1325 bytes
-rw-r--r--src/linguist/linguist/images/win/editcut.pngbin0 -> 1384 bytes
-rw-r--r--src/linguist/linguist/images/win/editpaste.pngbin0 -> 1482 bytes
-rw-r--r--src/linguist/linguist/images/win/filenew.pngbin0 -> 768 bytes
-rw-r--r--src/linguist/linguist/images/win/fileopen.pngbin0 -> 1662 bytes
-rw-r--r--src/linguist/linguist/images/win/filesave.pngbin0 -> 1205 bytes
-rw-r--r--src/linguist/linguist/images/win/next.pngbin0 -> 1038 bytes
-rw-r--r--src/linguist/linguist/images/win/nextunfinished.pngbin0 -> 1257 bytes
-rw-r--r--src/linguist/linguist/images/win/phrase.pngbin0 -> 1371 bytes
-rw-r--r--src/linguist/linguist/images/win/prev.pngbin0 -> 898 bytes
-rw-r--r--src/linguist/linguist/images/win/prevunfinished.pngbin0 -> 1260 bytes
-rw-r--r--src/linguist/linguist/images/win/print.pngbin0 -> 1456 bytes
-rw-r--r--src/linguist/linguist/images/win/punctuation.pngbin0 -> 1508 bytes
-rw-r--r--src/linguist/linguist/images/win/redo.pngbin0 -> 1212 bytes
-rw-r--r--src/linguist/linguist/images/win/searchfind.pngbin0 -> 1944 bytes
-rw-r--r--src/linguist/linguist/images/win/undo.pngbin0 -> 1181 bytes
-rw-r--r--src/linguist/linguist/images/win/validateplacemarkers.pngbin0 -> 1994 bytes
-rw-r--r--src/linguist/linguist/images/win/whatsthis.pngbin0 -> 1040 bytes
-rw-r--r--src/linguist/linguist/linguist.icnsbin0 -> 152596 bytes
-rw-r--r--src/linguist/linguist/linguist.icobin0 -> 355574 bytes
-rw-r--r--src/linguist/linguist/linguist.pro96
-rw-r--r--src/linguist/linguist/linguist.qrc57
-rw-r--r--src/linguist/linguist/linguist.rc32
-rw-r--r--src/linguist/linguist/main.cpp121
-rw-r--r--src/linguist/linguist/mainwindow.cpp2724
-rw-r--r--src/linguist/linguist/mainwindow.h267
-rw-r--r--src/linguist/linguist/mainwindow.ui892
-rw-r--r--src/linguist/linguist/messageeditor.cpp880
-rw-r--r--src/linguist/linguist/messageeditor.h180
-rw-r--r--src/linguist/linguist/messageeditorwidgets.cpp456
-rw-r--r--src/linguist/linguist/messageeditorwidgets.h184
-rw-r--r--src/linguist/linguist/messagehighlighter.cpp210
-rw-r--r--src/linguist/linguist/messagehighlighter.h83
-rw-r--r--src/linguist/linguist/messagemodel.cpp1426
-rw-r--r--src/linguist/linguist/messagemodel.h535
-rw-r--r--src/linguist/linguist/phrase.cpp355
-rw-r--r--src/linguist/linguist/phrase.h138
-rw-r--r--src/linguist/linguist/phrasebookbox.cpp242
-rw-r--r--src/linguist/linguist/phrasebookbox.h89
-rw-r--r--src/linguist/linguist/phrasebookbox.ui236
-rw-r--r--src/linguist/linguist/phrasemodel.cpp200
-rw-r--r--src/linguist/linguist/phrasemodel.h94
-rw-r--r--src/linguist/linguist/phraseview.cpp272
-rw-r--r--src/linguist/linguist/phraseview.h120
-rw-r--r--src/linguist/linguist/printout.cpp210
-rw-r--r--src/linguist/linguist/printout.h120
-rw-r--r--src/linguist/linguist/recentfiles.cpp146
-rw-r--r--src/linguist/linguist/recentfiles.h83
-rw-r--r--src/linguist/linguist/sourcecodeview.cpp145
-rw-r--r--src/linguist/linguist/sourcecodeview.h74
-rw-r--r--src/linguist/linguist/statistics.cpp67
-rw-r--r--src/linguist/linguist/statistics.h67
-rw-r--r--src/linguist/linguist/statistics.ui211
-rw-r--r--src/linguist/linguist/translatedialog.cpp90
-rw-r--r--src/linguist/linguist/translatedialog.h89
-rw-r--r--src/linguist/linguist/translatedialog.ui260
-rw-r--r--src/linguist/linguist/translationsettings.ui137
-rw-r--r--src/linguist/linguist/translationsettingsdialog.cpp166
-rw-r--r--src/linguist/linguist/translationsettingsdialog.h81
-rw-r--r--src/linguist/lrelease/lrelease.1118
-rw-r--r--src/linguist/lrelease/lrelease.pro23
-rw-r--r--src/linguist/lrelease/main.cpp391
-rw-r--r--src/linguist/lupdate/cpp.cpp2245
-rw-r--r--src/linguist/lupdate/java.cpp645
-rw-r--r--src/linguist/lupdate/lupdate.1153
-rw-r--r--src/linguist/lupdate/lupdate.exe.manifest14
-rw-r--r--src/linguist/lupdate/lupdate.h86
-rw-r--r--src/linguist/lupdate/lupdate.pro49
-rw-r--r--src/linguist/lupdate/main.cpp730
-rw-r--r--src/linguist/lupdate/merge.cpp515
-rw-r--r--src/linguist/lupdate/qdeclarative.cpp433
-rw-r--r--src/linguist/lupdate/qscript.cpp2612
-rw-r--r--src/linguist/lupdate/qscript.g2261
-rw-r--r--src/linguist/lupdate/ui.cpp208
-rw-r--r--src/linguist/lupdate/winmanifest.rc4
-rw-r--r--src/linguist/phrasebooks/danish.qph1018
-rw-r--r--src/linguist/phrasebooks/dutch.qph1044
-rw-r--r--src/linguist/phrasebooks/finnish.qph1033
-rw-r--r--src/linguist/phrasebooks/french.qph1493
-rw-r--r--src/linguist/phrasebooks/german.qph1075
-rw-r--r--src/linguist/phrasebooks/hungarian.qph752
-rw-r--r--src/linguist/phrasebooks/italian.qph1105
-rw-r--r--src/linguist/phrasebooks/japanese.qph1021
-rw-r--r--src/linguist/phrasebooks/norwegian.qph1004
-rw-r--r--src/linguist/phrasebooks/polish.qph527
-rw-r--r--src/linguist/phrasebooks/russian.qph1219
-rw-r--r--src/linguist/phrasebooks/spanish.qph1086
-rw-r--r--src/linguist/phrasebooks/swedish.qph1010
-rw-r--r--src/linguist/qdoc.conf15
-rw-r--r--src/linguist/shared/abstractproitemvisitor.h74
-rw-r--r--src/linguist/shared/formats.pri22
-rw-r--r--src/linguist/shared/numerus.cpp404
-rw-r--r--src/linguist/shared/po.cpp902
-rw-r--r--src/linguist/shared/profileevaluator.cpp2627
-rw-r--r--src/linguist/shared/profileevaluator.h116
-rw-r--r--src/linguist/shared/proitems.cpp358
-rw-r--r--src/linguist/shared/proitems.h248
-rw-r--r--src/linguist/shared/proparser.pri12
-rw-r--r--src/linguist/shared/proparserutils.h324
-rw-r--r--src/linguist/shared/qm.cpp803
-rw-r--r--src/linguist/shared/qph.cpp207
-rw-r--r--src/linguist/shared/simtexth.cpp277
-rw-r--r--src/linguist/shared/simtexth.h100
-rw-r--r--src/linguist/shared/translator.cpp759
-rw-r--r--src/linguist/shared/translator.h246
-rw-r--r--src/linguist/shared/translatormessage.cpp187
-rw-r--r--src/linguist/shared/translatormessage.h181
-rw-r--r--src/linguist/shared/ts.cpp781
-rw-r--r--src/linguist/shared/ts.dtd100
-rw-r--r--src/linguist/shared/xliff.cpp851
-rw-r--r--src/linguist/tests/data/main.cpp75
-rw-r--r--src/linguist/tests/data/test.pro9
-rw-r--r--src/linguist/tests/tests.pro16
-rw-r--r--src/linguist/tests/tst_linguist.cpp45
-rw-r--r--src/linguist/tests/tst_linguist.h63
-rw-r--r--src/linguist/tests/tst_lupdate.cpp195
-rw-r--r--src/linguist/tests/tst_simtexth.cpp73
-rw-r--r--src/macdeployqt/macchangeqt/macchangeqt.pro9
-rw-r--r--src/macdeployqt/macchangeqt/main.cpp76
-rw-r--r--src/macdeployqt/macdeployqt.pro7
-rw-r--r--src/macdeployqt/macdeployqt/macdeployqt.pro13
-rw-r--r--src/macdeployqt/macdeployqt/main.cpp135
-rw-r--r--src/macdeployqt/shared/shared.cpp586
-rw-r--r--src/macdeployqt/shared/shared.h110
-rw-r--r--src/macdeployqt/tests/deployment_mac.pro10
-rw-r--r--src/macdeployqt/tests/tst_deployment_mac.cpp233
-rw-r--r--src/makeqpf/Blocks.txt185
-rw-r--r--src/makeqpf/README1
-rw-r--r--src/makeqpf/main.cpp183
-rw-r--r--src/makeqpf/mainwindow.cpp322
-rw-r--r--src/makeqpf/mainwindow.h80
-rw-r--r--src/makeqpf/mainwindow.ui502
-rw-r--r--src/makeqpf/makeqpf.pro20
-rw-r--r--src/makeqpf/makeqpf.qrc5
-rw-r--r--src/makeqpf/qpf2.cpp767
-rw-r--r--src/makeqpf/qpf2.h119
-rw-r--r--src/pixeltool/Info_mac.plist18
-rw-r--r--src/pixeltool/main.cpp65
-rw-r--r--src/pixeltool/pixeltool.pro25
-rw-r--r--src/pixeltool/qpixeltool.cpp536
-rw-r--r--src/pixeltool/qpixeltool.h118
-rw-r--r--src/qconfig/feature.cpp240
-rw-r--r--src/qconfig/feature.h125
-rw-r--r--src/qconfig/featuretreemodel.cpp451
-rw-r--r--src/qconfig/featuretreemodel.h104
-rw-r--r--src/qconfig/graphics.h195
-rw-r--r--src/qconfig/main.cpp544
-rw-r--r--src/qconfig/qconfig.pro9
-rw-r--r--src/qdbus/qdbus.pro3
-rw-r--r--src/qdbus/qdbus/qdbus.cpp528
-rw-r--r--src/qdbus/qdbus/qdbus.pro10
-rw-r--r--src/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp446
-rw-r--r--src/qdbus/qdbuscpp2xml/qdbuscpp2xml.pro10
-rw-r--r--src/qdbus/qdbusviewer/Info_mac.plist18
-rw-r--r--src/qdbus/qdbusviewer/images/qdbusviewer-128.pngbin0 -> 9850 bytes
-rw-r--r--src/qdbus/qdbusviewer/images/qdbusviewer.icnsbin0 -> 146951 bytes
-rw-r--r--src/qdbus/qdbusviewer/images/qdbusviewer.icobin0 -> 355574 bytes
-rw-r--r--src/qdbus/qdbusviewer/images/qdbusviewer.pngbin0 -> 1231 bytes
-rw-r--r--src/qdbus/qdbusviewer/main.cpp85
-rw-r--r--src/qdbus/qdbusviewer/propertydialog.cpp114
-rw-r--r--src/qdbus/qdbusviewer/propertydialog.h70
-rw-r--r--src/qdbus/qdbusviewer/qdbusmodel.cpp350
-rw-r--r--src/qdbus/qdbusviewer/qdbusmodel.h95
-rw-r--r--src/qdbus/qdbusviewer/qdbusviewer.cpp521
-rw-r--r--src/qdbus/qdbusviewer/qdbusviewer.h103
-rw-r--r--src/qdbus/qdbusviewer/qdbusviewer.pro30
-rw-r--r--src/qdbus/qdbusviewer/qdbusviewer.qrc6
-rw-r--r--src/qdbus/qdbusviewer/qdbusviewer.rc1
-rw-r--r--src/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp1144
-rw-r--r--src/qdbus/qdbusxml2cpp/qdbusxml2cpp.pro10
-rw-r--r--src/qev/README2
-rw-r--r--src/qev/qev.cpp66
-rw-r--r--src/qev/qev.pro11
-rw-r--r--src/qmeegographicssystemhelper/qmeegofencesync.cpp79
-rw-r--r--src/qmeegographicssystemhelper/qmeegofencesync.h101
-rw-r--r--src/qmeegographicssystemhelper/qmeegofencesync_p.h60
-rw-r--r--src/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp147
-rw-r--r--src/qmeegographicssystemhelper/qmeegographicssystemhelper.h235
-rw-r--r--src/qmeegographicssystemhelper/qmeegographicssystemhelper.pro10
-rw-r--r--src/qmeegographicssystemhelper/qmeegolivepixmap.cpp117
-rw-r--r--src/qmeegographicssystemhelper/qmeegolivepixmap.h112
-rw-r--r--src/qmeegographicssystemhelper/qmeegolivepixmap_p.h57
-rw-r--r--src/qmeegographicssystemhelper/qmeegooverlaywidget.cpp102
-rw-r--r--src/qmeegographicssystemhelper/qmeegooverlaywidget.h86
-rw-r--r--src/qmeegographicssystemhelper/qmeegoruntime.cpp302
-rw-r--r--src/qmeegographicssystemhelper/qmeegoruntime.h76
-rw-r--r--src/qmeegographicssystemhelper/qmeegoswitchevent.cpp68
-rw-r--r--src/qmeegographicssystemhelper/qmeegoswitchevent.h91
-rw-r--r--src/qtconcurrent/codegenerator/codegenerator.pri5
-rw-r--r--src/qtconcurrent/codegenerator/example/example.pro9
-rw-r--r--src/qtconcurrent/codegenerator/example/main.cpp83
-rw-r--r--src/qtconcurrent/codegenerator/src/codegenerator.cpp140
-rw-r--r--src/qtconcurrent/codegenerator/src/codegenerator.h204
-rw-r--r--src/qtconcurrent/generaterun/main.cpp418
-rw-r--r--src/qtconcurrent/generaterun/run.pro9
-rw-r--r--src/qtconfig/colorbutton.cpp207
-rw-r--r--src/qtconfig/colorbutton.h90
-rw-r--r--src/qtconfig/images/appicon.pngbin0 -> 2238 bytes
-rw-r--r--src/qtconfig/main.cpp69
-rw-r--r--src/qtconfig/mainwindow.cpp956
-rw-r--r--src/qtconfig/mainwindow.h109
-rw-r--r--src/qtconfig/mainwindow.ui1388
-rw-r--r--src/qtconfig/paletteeditoradvanced.cpp401
-rw-r--r--src/qtconfig/paletteeditoradvanced.h106
-rw-r--r--src/qtconfig/paletteeditoradvanced.ui416
-rw-r--r--src/qtconfig/previewframe.cpp104
-rw-r--r--src/qtconfig/previewframe.h83
-rw-r--r--src/qtconfig/previewwidget.cpp89
-rw-r--r--src/qtconfig/previewwidget.h70
-rw-r--r--src/qtconfig/previewwidget.ui252
-rw-r--r--src/qtconfig/qtconfig.pro28
-rw-r--r--src/qtconfig/qtconfig.qrc5
-rw-r--r--src/qtestlib/qtestlib.pro4
-rw-r--r--src/qtestlib/updater/main.cpp178
-rw-r--r--src/qtestlib/updater/updater.pro10
-rw-r--r--src/qtestlib/wince/cetcpsync/cetcpsync.pro22
-rw-r--r--src/qtestlib/wince/cetcpsync/main.cpp191
-rw-r--r--src/qtestlib/wince/cetcpsync/qtcesterconnection.cpp552
-rw-r--r--src/qtestlib/wince/cetcpsync/qtcesterconnection.h86
-rw-r--r--src/qtestlib/wince/cetcpsync/remoteconnection.cpp65
-rw-r--r--src/qtestlib/wince/cetcpsync/remoteconnection.h81
-rw-r--r--src/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro17
-rw-r--r--src/qtestlib/wince/cetcpsyncserver/commands.cpp686
-rw-r--r--src/qtestlib/wince/cetcpsyncserver/commands.h292
-rw-r--r--src/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp138
-rw-r--r--src/qtestlib/wince/cetcpsyncserver/connectionmanager.h83
-rw-r--r--src/qtestlib/wince/cetcpsyncserver/main.cpp63
-rw-r--r--src/qtestlib/wince/cetcpsyncserver/transfer_global.h159
-rw-r--r--src/qtestlib/wince/cetest/activesyncconnection.cpp640
-rw-r--r--src/qtestlib/wince/cetest/activesyncconnection.h89
-rw-r--r--src/qtestlib/wince/cetest/bootstrapped.pri45
-rw-r--r--src/qtestlib/wince/cetest/cetcpsyncconnection.cpp221
-rw-r--r--src/qtestlib/wince/cetest/cetcpsyncconnection.h85
-rw-r--r--src/qtestlib/wince/cetest/cetest.pro56
-rw-r--r--src/qtestlib/wince/cetest/deployment.cpp293
-rw-r--r--src/qtestlib/wince/cetest/deployment.h75
-rw-r--r--src/qtestlib/wince/cetest/main.cpp445
-rw-r--r--src/qtestlib/wince/cetest/qmake_include.pri13
-rw-r--r--src/qtestlib/wince/cetest/remoteconnection.cpp100
-rw-r--r--src/qtestlib/wince/cetest/remoteconnection.h84
-rw-r--r--src/qtestlib/wince/remotelib/commands.cpp212
-rw-r--r--src/qtestlib/wince/remotelib/commands.h54
-rw-r--r--src/qtestlib/wince/remotelib/remotelib.pro15
-rw-r--r--src/qtestlib/wince/wince.pro2
-rw-r--r--src/qttracereplay/main.cpp351
-rw-r--r--src/qttracereplay/qttracereplay.pro15
-rw-r--r--src/qvfb/README51
-rw-r--r--src/qvfb/config.ui2472
-rw-r--r--src/qvfb/gammaview.h59
-rw-r--r--src/qvfb/images/logo-nt.pngbin0 -> 1965 bytes
-rw-r--r--src/qvfb/images/logo.pngbin0 -> 2238 bytes
-rw-r--r--src/qvfb/main.cpp168
-rw-r--r--src/qvfb/qanimationwriter.cpp453
-rw-r--r--src/qvfb/qanimationwriter.h71
-rw-r--r--src/qvfb/qtopiakeysym.h68
-rw-r--r--src/qvfb/qvfb.cpp1147
-rw-r--r--src/qvfb/qvfb.h159
-rw-r--r--src/qvfb/qvfb.pro64
-rw-r--r--src/qvfb/qvfb.qrc7
-rw-r--r--src/qvfb/qvfbmmap.cpp222
-rw-r--r--src/qvfb/qvfbmmap.h91
-rw-r--r--src/qvfb/qvfbprotocol.cpp195
-rw-r--r--src/qvfb/qvfbprotocol.h173
-rw-r--r--src/qvfb/qvfbratedlg.cpp103
-rw-r--r--src/qvfb/qvfbratedlg.h74
-rw-r--r--src/qvfb/qvfbshmem.cpp314
-rw-r--r--src/qvfb/qvfbshmem.h90
-rw-r--r--src/qvfb/qvfbview.cpp888
-rw-r--r--src/qvfb/qvfbview.h214
-rw-r--r--src/qvfb/qvfbx11view.cpp389
-rw-r--r--src/qvfb/qvfbx11view.h122
-rw-r--r--src/qvfb/x11keyfaker.cpp627
-rw-r--r--src/qvfb/x11keyfaker.h81
-rw-r--r--src/runonphone/main.cpp277
-rw-r--r--src/runonphone/ossignalconverter.cpp121
-rw-r--r--src/runonphone/ossignalconverter.h63
-rw-r--r--src/runonphone/ossignalconverter_p.h71
-rw-r--r--src/runonphone/runonphone.pro35
-rw-r--r--src/runonphone/serenum.h56
-rw-r--r--src/runonphone/serenum_stub.cpp53
-rw-r--r--src/runonphone/serenum_unix.cpp224
-rw-r--r--src/runonphone/serenum_win.cpp105
-rw-r--r--src/runonphone/symbianutils/bluetoothlistener.cpp224
-rw-r--r--src/runonphone/symbianutils/bluetoothlistener.h103
-rw-r--r--src/runonphone/symbianutils/bluetoothlistener_gui.cpp111
-rw-r--r--src/runonphone/symbianutils/bluetoothlistener_gui.h89
-rw-r--r--src/runonphone/symbianutils/callback.h160
-rw-r--r--src/runonphone/symbianutils/communicationstarter.cpp251
-rw-r--r--src/runonphone/symbianutils/communicationstarter.h160
-rw-r--r--src/runonphone/symbianutils/json.cpp490
-rw-r--r--src/runonphone/symbianutils/json.h149
-rw-r--r--src/runonphone/symbianutils/launcher.cpp1036
-rw-r--r--src/runonphone/symbianutils/launcher.h212
-rw-r--r--src/runonphone/symbianutils/symbiandevicemanager.cpp489
-rw-r--r--src/runonphone/symbianutils/symbiandevicemanager.h178
-rw-r--r--src/runonphone/symbianutils/symbianutils.pri35
-rw-r--r--src/runonphone/symbianutils/symbianutils_global.h55
-rw-r--r--src/runonphone/symbianutils/tcftrkdevice.cpp929
-rw-r--r--src/runonphone/symbianutils/tcftrkdevice.h295
-rw-r--r--src/runonphone/symbianutils/tcftrkmessage.cpp562
-rw-r--r--src/runonphone/symbianutils/tcftrkmessage.h296
-rw-r--r--src/runonphone/symbianutils/trkdevice.cpp1184
-rw-r--r--src/runonphone/symbianutils/trkdevice.h143
-rw-r--r--src/runonphone/symbianutils/trkutils.cpp603
-rw-r--r--src/runonphone/symbianutils/trkutils.h261
-rw-r--r--src/runonphone/symbianutils/trkutils_p.h62
-rw-r--r--src/runonphone/trksignalhandler.cpp368
-rw-r--r--src/runonphone/trksignalhandler.h88
-rw-r--r--src/shared/deviceskin/deviceskin.cpp857
-rw-r--r--src/shared/deviceskin/deviceskin.h174
-rw-r--r--src/shared/deviceskin/deviceskin.pri12
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.qrc5
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin30
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.pngbin0 -> 68200 bytes
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.pngbin0 -> 113907 bytes
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.pngbin0 -> 113450 bytes
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf78
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.qrc5
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin14
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf23
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.pngbin0 -> 6183 bytes
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.pngbin0 -> 6182 bytes
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcfbin0 -> 41592 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.qrc5
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.pngbin0 -> 161184 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.pngbin0 -> 156789 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin15
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf78
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc5
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.pngbin0 -> 241501 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.pngbin0 -> 240615 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin10
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf53
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.qrc5
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.pngbin0 -> 111515 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.pngbin0 -> 101750 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin28
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf78
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.qrc5
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.pngbin0 -> 134749 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.pngbin0 -> 121915 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin25
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf52
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.qrc5
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.pngbin0 -> 103838 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.pngbin0 -> 88470 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin31
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf103
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.qrc5
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.pngbin0 -> 88599 bytes
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.pngbin0 -> 61809 bytes
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin16
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf45
-rw-r--r--src/shared/findwidget/abstractfindwidget.cpp295
-rw-r--r--src/shared/findwidget/abstractfindwidget.h115
-rw-r--r--src/shared/findwidget/findwidget.pri4
-rw-r--r--src/shared/findwidget/findwidget.qrc14
-rw-r--r--src/shared/findwidget/images/mac/closetab.pngbin0 -> 516 bytes
-rw-r--r--src/shared/findwidget/images/mac/next.pngbin0 -> 1310 bytes
-rw-r--r--src/shared/findwidget/images/mac/previous.pngbin0 -> 1080 bytes
-rw-r--r--src/shared/findwidget/images/mac/searchfind.pngbin0 -> 1836 bytes
-rw-r--r--src/shared/findwidget/images/win/closetab.pngbin0 -> 375 bytes
-rw-r--r--src/shared/findwidget/images/win/next.pngbin0 -> 1038 bytes
-rw-r--r--src/shared/findwidget/images/win/previous.pngbin0 -> 898 bytes
-rw-r--r--src/shared/findwidget/images/win/searchfind.pngbin0 -> 1944 bytes
-rw-r--r--src/shared/findwidget/images/wrap.pngbin0 -> 500 bytes
-rw-r--r--src/shared/findwidget/itemviewfindwidget.cpp317
-rw-r--r--src/shared/findwidget/itemviewfindwidget.h78
-rw-r--r--src/shared/findwidget/texteditfindwidget.cpp169
-rw-r--r--src/shared/findwidget/texteditfindwidget.h73
-rw-r--r--src/shared/fontpanel/fontpanel.cpp308
-rw-r--r--src/shared/fontpanel/fontpanel.h108
-rw-r--r--src/shared/fontpanel/fontpanel.pri3
-rw-r--r--src/shared/qtgradienteditor/images/down.pngbin0 -> 594 bytes
-rw-r--r--src/shared/qtgradienteditor/images/edit.pngbin0 -> 503 bytes
-rw-r--r--src/shared/qtgradienteditor/images/editdelete.pngbin0 -> 831 bytes
-rw-r--r--src/shared/qtgradienteditor/images/minus.pngbin0 -> 250 bytes
-rw-r--r--src/shared/qtgradienteditor/images/plus.pngbin0 -> 462 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadpad.pngbin0 -> 151 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadreflect.pngbin0 -> 165 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadrepeat.pngbin0 -> 156 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typeconical.pngbin0 -> 937 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typelinear.pngbin0 -> 145 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typeradial.pngbin0 -> 583 bytes
-rw-r--r--src/shared/qtgradienteditor/images/up.pngbin0 -> 692 bytes
-rw-r--r--src/shared/qtgradienteditor/images/zoomin.pngbin0 -> 1208 bytes
-rw-r--r--src/shared/qtgradienteditor/images/zoomout.pngbin0 -> 1226 bytes
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.cpp272
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.h86
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.pri4
-rw-r--r--src/shared/qtgradienteditor/qtcolorline.cpp1122
-rw-r--r--src/shared/qtgradienteditor/qtcolorline.h124
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.cpp353
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.h87
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.ui121
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.cpp952
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.h111
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.pri33
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.qrc18
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.ui1377
-rw-r--r--src/shared/qtgradienteditor/qtgradientmanager.cpp135
-rw-r--r--src/shared/qtgradienteditor/qtgradientmanager.h92
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopscontroller.cpp724
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopscontroller.h106
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopsmodel.cpp477
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopsmodel.h121
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopswidget.cpp1154
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopswidget.h115
-rw-r--r--src/shared/qtgradienteditor/qtgradientutils.cpp420
-rw-r--r--src/shared/qtgradienteditor/qtgradientutils.h66
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.cpp292
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.h99
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.ui135
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.cpp89
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.h75
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.ui121
-rw-r--r--src/shared/qtgradienteditor/qtgradientwidget.cpp815
-rw-r--r--src/shared/qtgradienteditor/qtgradientwidget.h120
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-arrow.pngbin0 -> 171 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-busy.pngbin0 -> 201 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-closedhand.pngbin0 -> 147 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-cross.pngbin0 -> 130 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-forbidden.pngbin0 -> 199 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-hand.pngbin0 -> 159 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-hsplit.pngbin0 -> 155 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-ibeam.pngbin0 -> 124 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-openhand.pngbin0 -> 160 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizeall.pngbin0 -> 174 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizeb.pngbin0 -> 161 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizef.pngbin0 -> 161 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizeh.pngbin0 -> 145 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizev.pngbin0 -> 141 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-uparrow.pngbin0 -> 132 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-vsplit.pngbin0 -> 161 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-wait.pngbin0 -> 172 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-whatsthis.pngbin0 -> 191 bytes
-rw-r--r--src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp627
-rw-r--r--src/shared/qtpropertybrowser/qtbuttonpropertybrowser.h85
-rw-r--r--src/shared/qtpropertybrowser/qteditorfactory.cpp2560
-rw-r--r--src/shared/qtpropertybrowser/qteditorfactory.h397
-rw-r--r--src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp529
-rw-r--r--src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h76
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.cpp1955
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.h309
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.pri19
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.qrc23
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowserutils.cpp456
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowserutils.pri4
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowserutils_p.h161
-rw-r--r--src/shared/qtpropertybrowser/qtpropertymanager.cpp6451
-rw-r--r--src/shared/qtpropertybrowser/qtpropertymanager.h746
-rw-r--r--src/shared/qtpropertybrowser/qttreepropertybrowser.cpp1042
-rw-r--r--src/shared/qtpropertybrowser/qttreepropertybrowser.h134
-rw-r--r--src/shared/qtpropertybrowser/qtvariantproperty.cpp2268
-rw-r--r--src/shared/qtpropertybrowser/qtvariantproperty.h177
-rw-r--r--src/shared/qttoolbardialog/images/back.pngbin0 -> 678 bytes
-rw-r--r--src/shared/qttoolbardialog/images/down.pngbin0 -> 594 bytes
-rw-r--r--src/shared/qttoolbardialog/images/forward.pngbin0 -> 655 bytes
-rw-r--r--src/shared/qttoolbardialog/images/minus.pngbin0 -> 250 bytes
-rw-r--r--src/shared/qttoolbardialog/images/plus.pngbin0 -> 462 bytes
-rw-r--r--src/shared/qttoolbardialog/images/up.pngbin0 -> 692 bytes
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.cpp1871
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.h138
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.pri6
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.qrc10
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.ui207
-rw-r--r--src/tools.pro49
-rw-r--r--tests/README18
-rw-r--r--tests/auto/auto.pro9
-rw-r--r--tests/auto/bic/.gitignore2
-rw-r--r--tests/auto/bic/data/QtDesigner.4.2.0.linux-gcc-ia32.txt1985
-rw-r--r--tests/auto/bic/data/QtDesigner.4.3.0.linux-gcc-ia32.txt2169
-rw-r--r--tests/auto/bic/data/QtDesigner.4.4.0.linux-gcc-ia32.txt4431
-rw-r--r--tests/auto/bic/data/QtDesigner.4.5.0.linux-gcc-amd64.txt4460
-rw-r--r--tests/auto/bic/data/QtDesigner.4.5.0.linux-gcc-ia32.txt4460
-rw-r--r--tests/auto/bic/data/QtDesigner.4.6.0.linux-gcc-amd64.txt4741
-rw-r--r--tests/auto/bic/data/QtDesigner.4.6.0.linux-gcc-ia32.txt4741
-rw-r--r--tests/auto/bic/data/QtDesigner.4.7.0.linux-gcc-ia32.txt4746
-rw-r--r--tests/auto/bic/data/QtHelp.4.5.0.linux-gcc-amd64.txt6357
-rw-r--r--tests/auto/bic/data/QtHelp.4.5.0.linux-gcc-ia32.txt6357
-rw-r--r--tests/auto/bic/data/QtHelp.4.6.0.linux-gcc-amd64.txt5492
-rw-r--r--tests/auto/bic/data/QtHelp.4.6.0.linux-gcc-ia32.txt5492
-rw-r--r--tests/auto/bic/data/QtHelp.4.7.0.linux-gcc-ia32.txt5497
-rw-r--r--tests/auto/linguist/lconvert/.gitignore2
-rw-r--r--tests/auto/linguist/lconvert/data/codec-cp1252.ts28
-rw-r--r--tests/auto/linguist/lconvert/data/codec-utf8.ts28
-rw-r--r--tests/auto/linguist/lconvert/data/dual-encoding.ts11
-rw-r--r--tests/auto/linguist/lconvert/data/endless-po-loop.ts16
-rwxr-xr-xtests/auto/linguist/lconvert/data/makeplurals.pl86
-rw-r--r--tests/auto/linguist/lconvert/data/msgid.ts27
-rw-r--r--tests/auto/linguist/lconvert/data/phrasebook.qph21
-rw-r--r--tests/auto/linguist/lconvert/data/plurals-cn.ts17
-rw-r--r--tests/auto/linguist/lconvert/data/plurals-de.ts18
-rw-r--r--tests/auto/linguist/lconvert/data/relative.ts74
-rw-r--r--tests/auto/linguist/lconvert/data/singular.po42
-rw-r--r--tests/auto/linguist/lconvert/data/test-broken-utf8.po9
-rw-r--r--tests/auto/linguist/lconvert/data/test-broken-utf8.po.out12
-rw-r--r--tests/auto/linguist/lconvert/data/test-developer-comment.po23
-rw-r--r--tests/auto/linguist/lconvert/data/test-empty-comment.po24
-rw-r--r--tests/auto/linguist/lconvert/data/test-escapes.po11
-rw-r--r--tests/auto/linguist/lconvert/data/test-escapes.po.out16
-rw-r--r--tests/auto/linguist/lconvert/data/test-kde-ctxt.po25
-rw-r--r--tests/auto/linguist/lconvert/data/test-kde-fuzzy.po31
-rw-r--r--tests/auto/linguist/lconvert/data/test-kde-multiline.po32
-rw-r--r--tests/auto/linguist/lconvert/data/test-kde-plurals.po27
-rw-r--r--tests/auto/linguist/lconvert/data/test-refs.po23
-rw-r--r--tests/auto/linguist/lconvert/data/test-slurp.po19
-rw-r--r--tests/auto/linguist/lconvert/data/test-slurp.po.out22
-rw-r--r--tests/auto/linguist/lconvert/data/test-translator-comment.po41
-rw-r--r--tests/auto/linguist/lconvert/data/test1-cn.po67
-rw-r--r--tests/auto/linguist/lconvert/data/test1-de.po75
-rw-r--r--tests/auto/linguist/lconvert/data/test11.ts32
-rw-r--r--tests/auto/linguist/lconvert/data/test20.ts171
-rw-r--r--tests/auto/linguist/lconvert/data/variants.ts24
-rw-r--r--tests/auto/linguist/lconvert/data/wrapping.po57
-rw-r--r--tests/auto/linguist/lconvert/lconvert.pro8
-rw-r--r--tests/auto/linguist/lconvert/tst_lconvert.cpp347
-rw-r--r--tests/auto/linguist/linguist.pro2
-rw-r--r--tests/auto/linguist/lrelease/.gitignore2
-rw-r--r--tests/auto/linguist/lrelease/lrelease.pro5
-rw-r--r--tests/auto/linguist/lrelease/testdata/compressed.ts46
-rw-r--r--tests/auto/linguist/lrelease/testdata/dupes.errors4
-rw-r--r--tests/auto/linguist/lrelease/testdata/dupes.ts25
-rw-r--r--tests/auto/linguist/lrelease/testdata/idbased.ts28
-rw-r--r--tests/auto/linguist/lrelease/testdata/mixedcodecs-ts11.ts18
-rw-r--r--tests/auto/linguist/lrelease/testdata/mixedcodecs-ts20.ts18
-rw-r--r--tests/auto/linguist/lrelease/testdata/translate.ts136
-rw-r--r--tests/auto/linguist/lrelease/tst_lrelease.cpp241
-rw-r--r--tests/auto/linguist/lupdate/.gitignore4
-rw-r--r--tests/auto/linguist/lupdate/lupdate.pro6
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/backslashes/lupdatecmd1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/backslashes/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/backslashes/src/main.cpp56
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/backslashes/ts/project.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/cmdline_deeppath/lupdatecmd2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/cmdline_deeppath/project.ts.result27
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/cmdline_order/a.h42
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/cmdline_order/b.h44
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/cmdline_order/lupdatecmd1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/cmdline_order/project.ts.result20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/cmdline_recurse/lupdatecmd2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/cmdline_recurse/project.ts.result115
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecforsrc/main.cpp68
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.pro7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.ts.result38
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr/main.cpp65
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr/project.pro6
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr/project.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr1/main.cpp63
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.pro6
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.ts.result38
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr2/main.cpp62
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.pro7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.ts.result33
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr3/expectedoutput.txt1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr3/main.cpp45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.pro4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.ts.before13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.ts.result12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr4/expectedoutput.txt0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr4/main.cpp45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.pro4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.ts.before13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/from_subdir/lupdatecmd1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/from_subdir/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/from_subdir/src/main.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/from_subdir/src/main.h45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/from_subdir/translations/translations.pro7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/lupdatecmd2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp62
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before38
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result22
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/lacksqobject/main.cpp88
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.ts.result40
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp69
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/lupdatecmd1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.before74
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.result82
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_versions/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.before14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.result15
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ui72
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_whitespace/main.cpp64
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.before70
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.result71
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp82
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.before70
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.result74
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/finddialog.cpp154
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/lupdatecmd1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.before44
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.result35
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/finddialog.cpp177
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.before39
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.result43
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before22
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.result23
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui/project.ui77
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.before16
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result22
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui26
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/multiple_locations/finddialog.cpp47
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/multiple_locations/main.cpp53
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.pro4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/namespaces/main.cpp198
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/namespaces/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/namespaces/project.ts.result106
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parse_special_chars/main.cpp59
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp279
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result201
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/finddialog.cpp184
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp345
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/project.pro4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result370
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp127
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.h51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp69
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp83
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result40
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejava/main.java95
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejava/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejava/project.ts.result115
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejs/main.js91
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejs/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejs/project.ts.result195
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejs2/expectedoutput.txt29
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejs2/main.js56
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejs2/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejs2/project.ts.result30
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js29
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result81
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqml/main.qml100
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqml/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseqml/project.ts.result200
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseui/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseui/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseui/project.ui72
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp56
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/prefix/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result23
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/preprocess/main.cpp78
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/preprocess/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/preprocess/project.ts.result35
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/main.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/main_mac.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/main_unix.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/main_win.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/project.pro31
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/project.ts.result64
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/vpaths/dependpath/main_dependpath.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/main1.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/mainfile.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard1.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard99.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/a45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/a.cpp45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/b45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/b.cpp45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/e45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/f/g.cpp45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/files-cc.txt1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/project.pro33
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/project.ts.result62
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/spaces/z45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/variable_with_spaces45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/with45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/x/d45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/x/variable45
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpaths/file1.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpaths/filter.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.pro5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.ts.result31
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/sub.pri3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfile1.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfilter.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/common.pri1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.pri5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/mac.pri5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/main_mac.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.ts.result37
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.pri3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub/sub.pri1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub2/sub2.pri2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/main_unix.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/unix.pri5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/main_win.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/win.pri5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.pro2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/main.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/sub1.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/common.pro2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/main.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/lupdatecmd1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/mac.pro1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/main_mac.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.pro2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.ts.result31
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/main_unix.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/unix.pro1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/main_win.cpp51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/win.pro1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full/expectedoutput.txt0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full/lupdatecmd2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full/project.ts.result20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full/project_sub.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/expectedoutput.txt2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/lupdatecmd3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project.ts.result20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project_sub.ts.before0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project_sub.ts.result0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/expectedoutput.txt0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/lupdatecmd2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/project.ts.result20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part/expectedoutput.txt1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part/lupdatecmd2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part/project.ts.before0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part/project.ts.result0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part/project_sub.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/expectedoutput.txt1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/lupdatecmd3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project.ts.result20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project_sub.ts.before0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project_sub.ts.result0
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/reloutput/lupdatecmd1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/reloutput/main.cpp50
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/reloutput/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/reloutput/translations/project.ts.result12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/respfile/lupdatecmd2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/respfile/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/respfile/source1.cpp49
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/respfile/source2.cpp49
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/respfile/sources.lst2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/respfile/tsfiles.lst1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.before16
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result22
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui26
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/main.cpp63
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/project.ui74
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.c++49
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cpp49
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cxx49
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/sub/finddialog.cpp73
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_full/project.pro4
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_full/subdir1/main.cpp46
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_full/subdir1/subdir1.pro1
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subdir2.pro2
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub1/main.cpp46
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub1/subsub1.pro1
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub2/main.cpp46
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub2/subsub2.pro4
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_part/project.pro2
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_part/subdir1/main.cpp46
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_part/subdir1/subdir1.pro1
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subdir2.pro2
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub1/main.cpp46
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub1/subsub1.pro1
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub2/main.cpp46
-rw-r--r--tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub2/subsub2.pro4
-rw-r--r--tests/auto/linguist/lupdate/tst_lupdate.cpp350
-rw-r--r--tests/auto/qhelpcontentmodel/.gitignore2
-rw-r--r--tests/auto/qhelpcontentmodel/data/collection.qhcbin0 -> 10240 bytes
-rw-r--r--tests/auto/qhelpcontentmodel/data/qmake-3.3.8.qchbin0 -> 61440 bytes
-rw-r--r--tests/auto/qhelpcontentmodel/data/qmake-4.3.0.qchbin0 -> 93184 bytes
-rw-r--r--tests/auto/qhelpcontentmodel/data/test.qchbin0 -> 22528 bytes
-rw-r--r--tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro22
-rw-r--r--tests/auto/qhelpcontentmodel/tst_qhelpcontentmodel.cpp182
-rw-r--r--tests/auto/qhelpenginecore/.gitignore3
-rw-r--r--tests/auto/qhelpenginecore/data/collection.qhcbin0 -> 10240 bytes
-rw-r--r--tests/auto/qhelpenginecore/data/collection1.qhcbin0 -> 10240 bytes
-rw-r--r--tests/auto/qhelpenginecore/data/linguist-3.3.8.qchbin0 -> 131072 bytes
-rw-r--r--tests/auto/qhelpenginecore/data/qmake-3.3.8.qchbin0 -> 61440 bytes
-rw-r--r--tests/auto/qhelpenginecore/data/qmake-4.3.0.qchbin0 -> 93184 bytes
-rw-r--r--tests/auto/qhelpenginecore/data/test.html11
-rw-r--r--tests/auto/qhelpenginecore/data/test.qchbin0 -> 22528 bytes
-rw-r--r--tests/auto/qhelpenginecore/qhelpenginecore.pro23
-rw-r--r--tests/auto/qhelpenginecore/tst_qhelpenginecore.cpp462
-rw-r--r--tests/auto/qhelpgenerator/.gitignore1
-rw-r--r--tests/auto/qhelpgenerator/data/cars.html11
-rw-r--r--tests/auto/qhelpgenerator/data/classic.css92
-rw-r--r--tests/auto/qhelpgenerator/data/fancy.html11
-rw-r--r--tests/auto/qhelpgenerator/data/people.html11
-rw-r--r--tests/auto/qhelpgenerator/data/sub/about.html11
-rw-r--r--tests/auto/qhelpgenerator/data/test.html11
-rw-r--r--tests/auto/qhelpgenerator/data/test.qhp71
-rw-r--r--tests/auto/qhelpgenerator/qhelpgenerator.pro9
-rw-r--r--tests/auto/qhelpgenerator/tst_qhelpgenerator.cpp218
-rw-r--r--tests/auto/qhelpindexmodel/.gitignore2
-rw-r--r--tests/auto/qhelpindexmodel/data/collection.qhcbin0 -> 10240 bytes
-rw-r--r--tests/auto/qhelpindexmodel/data/collection1.qhcbin0 -> 10240 bytes
-rw-r--r--tests/auto/qhelpindexmodel/data/linguist-3.3.8.qchbin0 -> 131072 bytes
-rw-r--r--tests/auto/qhelpindexmodel/data/qmake-3.3.8.qchbin0 -> 61440 bytes
-rw-r--r--tests/auto/qhelpindexmodel/data/qmake-4.3.0.qchbin0 -> 93184 bytes
-rw-r--r--tests/auto/qhelpindexmodel/data/test.html11
-rw-r--r--tests/auto/qhelpindexmodel/data/test.qchbin0 -> 22528 bytes
-rw-r--r--tests/auto/qhelpindexmodel/qhelpindexmodel.pro9
-rw-r--r--tests/auto/qhelpindexmodel/tst_qhelpindexmodel.cpp219
-rw-r--r--tests/auto/qhelpprojectdata/.gitignore1
-rw-r--r--tests/auto/qhelpprojectdata/data/test.qhp72
-rw-r--r--tests/auto/qhelpprojectdata/qhelpprojectdata.pro9
-rw-r--r--tests/auto/qhelpprojectdata/tst_qhelpprojectdata.cpp193
-rw-r--r--tests/global/.gitignore2
-rw-r--r--tests/tests.pro2
2343 files changed, 431332 insertions, 0 deletions
diff --git a/3rdparty/clucene/APACHE.license b/3rdparty/clucene/APACHE.license
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/3rdparty/clucene/APACHE.license
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/3rdparty/clucene/AUTHORS b/3rdparty/clucene/AUTHORS
new file mode 100644
index 000000000..4a7904b6d
--- /dev/null
+++ b/3rdparty/clucene/AUTHORS
@@ -0,0 +1,22 @@
+As with most development projects, contributions come from many people and in
+many forms. The CLucene project would like to thank it's many contributors.
+Omissions are merely accidental, please e-mail ustramooner@users.sourceforge.net
+if you have been left out or a contribution is not mentioned.
+
+CLucene was originally ported to C++ by Ben van Klinken (ustramooner@users.sourceforge.net)
+from Doug Cutting's popular java search engine, Lucene (see http://lucene.apache.org).
+
+Here is a list of contributors. Please send me an email at ustramooner@users.sourceforge.net
+if I have left you out.
+
+Doug Cutting cutting@users.sourceforge.net
+John Wheeler j_wheeler@users.sourceforge.net
+Robert G. Ristroph rgristroph@users.sourceforge.net
+David Rushby woodsplitter@users.sourceforge.net
+Jimmy Pritts jpritts@sdf.lonestar.org
+Peter Edwards peter@dragonstaff.co.uk
+Jorge Sabater Redondo jsabater@elderecho.com
+Daniel Glassey danglassey@ntlworld.com
+Peter Gladkikh batyi@mail.ru
+Pedja amigo@max3d.com
+Peter Hodges hodges.peter@gmail.com
diff --git a/3rdparty/clucene/COPYING b/3rdparty/clucene/COPYING
new file mode 100644
index 000000000..0e32bb4f3
--- /dev/null
+++ b/3rdparty/clucene/COPYING
@@ -0,0 +1,30 @@
+License
+
+The CLucene Core Library uses a dual license strategy for the source code.
+These licenses are the GNU Lesser General Public License (LGPL) and the Apache
+License (Version 2.0). Users can choose the license they wish to distribute
+their software under. This means that you do not need to abide by *both*
+licenses, but rather than you can choose the license which most suits your
+needs.
+
+To rephrase this and to make it perfectly clear:
+CLucene is distributed under the GNU Lesser General Public License (LGPL)
+ *or*
+the Apache License, Version 2.0
+
+However, we are an open source project, and we encourage users to use the LGPL
+license and participate fully in the free software community. Dual licensing
+of the CLucene source code provides open and free access to the technology both
+for the GPL community and for other developers or companies that cannot use the
+GPL.
+
+You can freely modify, extend, and improve the CLucene source code. The only
+question is whether or not you must provide the source code and contribute
+modifications to the community. The GNU and Apache licenses allow different
+ranges of flexibility in this regard, but in the end, regardless of the license
+used, we highly recommend that you submit any bugs, incompatibilities or
+added features.
+
+Note that this same license does *not* apply to the CLucene Contributions
+package. You should read the COPYING file in that directory or package for
+more information. \ No newline at end of file
diff --git a/3rdparty/clucene/ChangeLog b/3rdparty/clucene/ChangeLog
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/3rdparty/clucene/ChangeLog
diff --git a/3rdparty/clucene/LGPL.license b/3rdparty/clucene/LGPL.license
new file mode 100644
index 000000000..422c76072
--- /dev/null
+++ b/3rdparty/clucene/LGPL.license
@@ -0,0 +1,475 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+-------------------------------------------------------------------------------
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+-------------------------------------------------------------------------------
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+-------------------------------------------------------------------------------
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+-------------------------------------------------------------------------------
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+-------------------------------------------------------------------------------
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+-------------------------------------------------------------------------------
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+-------------------------------------------------------------------------------
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+-------------------------------------------------------------------------------
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/3rdparty/clucene/README b/3rdparty/clucene/README
new file mode 100644
index 000000000..ee4f49369
--- /dev/null
+++ b/3rdparty/clucene/README
@@ -0,0 +1,92 @@
+CLucene README
+==============
+
+------------------------------------------------------
+CLucene is a C++ port of Lucene.
+It is a high-performance, full-featured text search
+engine written in C++. CLucene is faster than lucene
+as it is written in C++.
+------------------------------------------------------
+
+CLucene has contributions from many, see AUTHORS
+
+CLucene is distributed under the GNU Lesser General Public License (LGPL)
+ *or*
+the Apache License, Version 2.0
+See the LGPL.license and APACHE.license for the respective license information.
+Read COPYING for more about the license.
+
+Installation
+------------
+* For Linux, MacOSX, cygwin and MinGW build information, read INSTALL.
+* Boost.Jam files are provided in the root directory and subdirectories.
+* Microsoft Visual Studio (6&7) are provided in the win32 folder.
+
+Mailing List
+------------
+Questions and discussion should be directed to the CLucene mailing list
+ at clucene-developers@lists.sourceforge.net
+Find subscription instructions at
+ http://lists.sourceforge.net/lists/listinfo/clucene-developers
+Suggestions and bug reports can be made on our bug tracking database
+ (http://sourceforge.net/tracker/?group_id=80013&atid=558446)
+
+The latest version
+------------------
+Details of the latest version can be found on the CLucene sourceforge project
+web site: http://www.sourceforge.net/projects/clucene
+
+Documentation
+-------------
+Documentation is provided at http://clucene.sourceforge.net/doc/doxygen/html/
+You can also build your own documentation by running doxygen from the root directory
+of clucene.
+CLucene is a very close port of Java Lucene, so you can also try looking at the
+Java Docs on http://lucene.apache.org/java/
+
+
+Performance
+-----------
+Very little benchmarking has been done on clucene. Andi Vajda posted some
+limited statistics on the clucene list a while ago with the following results.
+
+There are 250 HTML files under $JAVA_HOME/docs/api/java/util for about
+6108kb of HTML text.
+org.apache.lucene.demo.IndexFiles with java and gcj:
+on mac os x 10.3.1 (panther) powerbook g4 1ghz 1gb:
+ . running with java 1.4.1_01-99 : 20379 ms
+ . running with gcj 3.3.2 -O2 : 17842 ms
+ . running clucene 0.8.9's demo : 9930 ms
+
+I recently did some more tests and came up with these rough tests:
+663mb (797 files) of Guttenberg texts
+on a Pentium 4 running Windows XP with 1 GB of RAM. Indexing max 100,000 fields
+• Jlucene: 646453ms. peak mem usage ~72mb, avg ~14mb ram
+• Clucene: 232141. peak mem usage ~60, avg ~4mb ram
+
+Searching indexing using 10,000 single word queries
+• Jlucene: ~60078ms and used ~13mb ram
+• Clucene: ~48359ms and used ~4.2mb ram
+
+Platform notes
+--------------
+
+'Too many open files'
+Some platforms don't provide enough file handles to run CLucene properly.
+To solve this, increase the open file limit:
+
+On Solaris:
+ulimit -n 1024
+set rlim_fd_cur=1024
+
+Acknowledgments
+----------------
+
+The Apache Lucene project is the basis for this software, so the biggest
+acknoledgment goes to that project.
+
+We wish to acknowledge the following copyrighted works that
+make up portions of the CLucene software:
+
+CLucene relies heavily on the use of autoconf and libtool to provide
+a build environment.
diff --git a/3rdparty/clucene/src/CLucene.h b/3rdparty/clucene/src/CLucene.h
new file mode 100644
index 000000000..1eac800fd
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene.h
@@ -0,0 +1,38 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+//Includes some standard headers for searching and indexing.
+#ifndef _lucene_CLucene_
+#define _lucene_CLucene_
+
+#include "CLucene/StdHeader.h"
+#include "CLucene/debug/condition.h"
+#include "CLucene/debug/mem.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/index/IndexWriter.h"
+#include "CLucene/index/MultiReader.h"
+#include "CLucene/index/Term.h"
+#include "CLucene/search/IndexSearcher.h"
+#include "CLucene/search/MultiSearcher.h"
+#include "CLucene/search/DateFilter.h"
+#include "CLucene/search/WildcardQuery.h"
+#include "CLucene/search/FuzzyQuery.h"
+#include "CLucene/search/PhraseQuery.h"
+#include "CLucene/search/PrefixQuery.h"
+#include "CLucene/search/RangeQuery.h"
+#include "CLucene/search/BooleanQuery.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/document/Field.h"
+#include "CLucene/document/DateField.h"
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/FSDirectory.h"
+#include "CLucene/queryParser/QueryParser.h"
+#include "CLucene/queryParser/MultiFieldQueryParser.h"
+#include "CLucene/analysis/standard/StandardAnalyzer.h"
+#include "CLucene/analysis/Analyzers.h"
+#include "CLucene/util/Reader.h"
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/CLBackwards.h b/3rdparty/clucene/src/CLucene/CLBackwards.h
new file mode 100644
index 000000000..ffaf42824
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/CLBackwards.h
@@ -0,0 +1,87 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _clucene_backwards_h
+#define _clucene_backwards_h
+
+//In light of the recent major changes to clucene,
+//this file should help to maintain some backwards compatibility
+//include it after including StdHeader.h
+//
+//Note: I haven't tested this much, so please send me your changes
+
+//dirent is one of the most major changes that won't easily port.
+//you can use the TCHAR copying macros, STRCPY_TtoA and STRCPY_AtoT
+//to copy between different character types.
+
+//If you use stringPrintF, you will need to add the target string
+//size parameter, because it is using _sntprintf... Change this if you
+//want, but _sntprintf is much safer
+
+#define char_t TCHAR
+#define uchar_t TCHAR
+#define l_byte_t byte_t
+
+//#define stringSpn _tcsspn //not used in clucene anymore
+#define stringCSpn _tcscspn
+#define stringLength _tcslen
+//#define stringToInteger _ttoi //not used in clucene anymore, use integer w/ base
+#define stringFind _tcsstr
+#define stringFindChar _tcschr
+#define stringCompare _tcscmp
+#define stringNCopy _tcsncpy
+#define stringCopy _tcscpy
+#define stringCat _tcscat
+//#define stringToken _tcstok //not used in clucene anymore
+#define stringPrintF _sntprintf //you will have errors, because now we used printf w/ bufferlen count
+#define printFormatted _tprintf
+
+//conversion functions
+#define integerToString _i64tot
+#define stringToIntegerBase _tcstoi64
+#define stringToFloat _tcstod
+
+//file find structures
+#define Cmd_Stat fileStat
+#define Struct_Stat fileStat
+#define stringICompare _tcsicmp
+#define stringNCompare _tcsncmp
+#define stringDifference _tcscmp
+
+//character conversion functions
+#define isSpace _istspace
+#define isDigit _istwdigit
+#define isAlNum _istwalnum
+#define toLower _totlower
+#define stringUpper _tcsupr
+//#define stringLower _tcslwr //not used in clucene anymore
+
+#define _THROWX(y) _THROWT(y)
+#define _THROWC(y) _THROWA(y)
+
+//file naming stuff - remember we have changed all names to file naming lower case
+#define fileRename _rename
+#define fileFullName(abs,rel) _realpath(rel,abs)
+#define makeDirectory _tmkdir
+#define unlinkFile _unlink
+
+//no longer supported definitions
+#ifdef _UNICODE
+ #define TO_CHAR_T STRDUP_AtoT
+ #define _cout wcout
+ #define _cin wcin
+ #define _cerr wcerr
+#else
+ #define TO_CHAR_T STRDUP_WtoT
+ #define _cout cout
+ #define _cin cin
+ #define _cerr cerr
+#endif
+
+//some headers that used to be automatically included:
+#include "CLucene/util/dirent.h" //if we have dirent, then the native one will be used
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/CLConfig.h b/3rdparty/clucene/src/CLucene/CLConfig.h
new file mode 100644
index 000000000..c63c083ff
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/CLConfig.h
@@ -0,0 +1,304 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_Config_
+#define _lucene_Config_
+
+
+////////////////////////////////////////////////////////////////////
+// this settings should be set up in the compiler,
+// but are put here for reference as to what could be defined
+////////////////////////////////////////////////////////////////////
+//
+//define this if you want debugging code to be enabled
+//#define _DEBUG
+//
+//define this if you want condition debugging to be enabled
+#if defined(_DEBUG) && !defined(_CL__CND_DEBUG)
+ #define _CL__CND_DEBUG
+#endif
+//
+//define this to print out lots of information about merges, etc
+//requires __CL__CND_DEBUG to be defined
+//#define _CL_DEBUG_INFO stdout
+//
+//to disable namespaces define this
+//#define DISABLE_NAMESPACE
+//
+//This is mostly for windows. If you have put the google sparse
+//map code in your include path somewhere, then define this
+//to use it.
+//However, for msvc, there are no significant gains since there
+//is already a compatible hashmap available.
+//#define _CL_HAVE_GOOGLE_DENSE_HASH_MAP
+//
+////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////
+// These options can be set depending on the particular needs of
+// Your application
+////////////////////////////////////////////////////////////////////
+//
+//define this to force the build into ascii mode
+//#define _ASCII
+//
+//define this to force the build into ucs2 mode
+//#define _UCS2
+//
+//if a wide character is being converted to a ascii character and it
+//cannot fit, this character is used instead. Required.
+#define LUCENE_OOR_CHAR(c) ((char)(((unsigned short)c)&0xFF))
+//
+//define if you would like to force clucene to use the internal
+//character functions.
+//Tests may display unpredictable behaviour if this is not defined.
+#define LUCENE_USE_INTERNAL_CHAR_FUNCTIONS
+//
+//define this to enable mmap support in the fsdirectory IndexInput
+//todo: only available for windows so far...need to add MMapInput.cpp to project
+//EXPERIMENTAL
+//#define LUCENE_FS_MMAP
+//
+//LOCK_DIR implementation:
+//define this to set an exact directory for the lock dir (not recommended)
+//all other methods of getting the temporary directory will be ignored
+//#define LUCENE_LOCK_DIR "/tmp"
+//
+//define this to try and load the lock dir from this specified environment variable
+#define LUCENE_LOCK_DIR_ENV_1 "TEMP"
+//define this if you want to have look up this environment variable if the first one fails
+#define LUCENE_LOCK_DIR_ENV_2 "TMP"
+//define this if you want to have a fallback directory, if not defined then
+//the lockdirectory will be the index directory
+#define LUCENE_LOCK_DIR_ENV_FALLBACK "/tmp"
+//
+////////////////////////////////////////////////////////////////////
+
+
+
+////////////////////////////////////////////////////////////////////
+// The following are search query options
+// THe NO_* options can make CLucene faster and/or smaller
+// special queries sometime require longer search times or may
+// not be required
+////////////////////////////////////////////////////////////////////
+//
+//Define this to remove fuzzy query and sloppy scoring
+//#define NO_FUZZY_QUERY
+//
+//Define to remove wildcard t*m or te?m to match term
+//#define NO_WILDCARD_QUERY
+//
+//Define to remove prefix term query - ter* to match term or terms
+//#define NO_PREFIX_QUERY
+//
+//Define to remove range (exlusive and inclusive)
+//#define NO_RANGE_QUERY
+//
+//This must always be defined. They can be adjusted if required. But
+//general Wildcard string would be '*' and Wildcard Char would be '?'
+//Both are Required.
+#define LUCENE_WILDCARDTERMENUM_WILDCARD_STRING '*'
+#define LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR '?'
+//
+////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////
+// memory handling configurations
+////////////////////////////////////////////////////////////////////
+//
+//If this is defined, lucene's configurations are changed
+//to use less memory, but may run slower.
+//todo: i dont think this actualy changes speed much, just memory
+#define LUCENE_OPTIMIZE_FOR_MEMORY
+//
+//define this if you want the pointer tracking to be enabled
+//this is a useful tool for memory leak tracking
+//The LuceneBase can slow down the code a *lot*
+#if defined(_DEBUG)
+ #if !defined(LUCENE_DISABLE_MEMTRACKING) && !defined(LUCENE_ENABLE_MEMLEAKTRACKING)
+ #define LUCENE_ENABLE_MEMLEAKTRACKING
+ #endif
+#endif
+//
+//enable use of rich file/line tracking. use CL_FILELINE to pass
+//to functions like stringDuplicate (or use CL_STRDUP* functions instead) and
+//CLStringIntern::x.
+#if defined(LUCENE_ENABLE_MEMLEAKTRACKING)
+ #define LUCENE_ENABLE_FILELINEINFO
+#endif
+//
+//enable creation of clucene.log file. Logs every
+//call to new operator. Must have LUCENE_ENABLE_MEMLEAKTRACKING enabled.
+//writes log in this format.
+//action,file name,file line,allocation size
+//logging can be disabled by setting _lucene_disable_debuglogging to true
+#if defined(LUCENE_ENABLE_MEMLEAKTRACKING) && defined(_DEBUG)
+//#define LUCENE_ENABLE_CONSTRUCTOR_LOG
+#endif
+//
+//
+//enable this if you want to enable reference counting. This is
+//not necessary or useful in most cases except when implementing wrappers
+//which have reference counting. If the wrapper wraps a StringReader,
+//for example, it should expect that the wrapped StringReader should not
+//be deleted. However, when the stringreader is added into a Field,
+//the Field usually takes over the stringReader and deletes it on completion.
+//If reference counting is enabled, the wrapper can add a reference to any class
+//and when _CLDECDELETE is called, the reference is decremented and only deleted
+//if the refcount is zero.
+#define LUCENE_ENABLE_REFCOUNT
+
+
+////////////////////////////////////////////////////////////////////
+// These options allow you to remove certain implementations
+// out of clucene so that they can be implemented in the client
+// application
+////////////////////////////////////////////////////////////////////
+//
+//define this to your own setting if you would like to implement your own
+//threading locking code. it should have the same sort of functions as
+//mutex_default. If not defined, clucene will try and use posix,win32 critical
+//sections, or a timer based mutex hack.
+//#define _LUCENE_THREADMUTEX CL_NS(util)::mutex_default
+//
+//define this if you want to implement the _Cnd_OutDebug routine yourself
+//you can then easily customise in your own application how to handle debug messages
+//#define _CND_DEBUG_DONTIMPLEMENT_OUTDEBUG
+//
+//define this if you want to implement your own namespace macros
+//#define _LUCENE_DONTIMPLEMENT_NS_MACROS
+//
+//define this if you do not want clucene to include any standard libraries.
+//this could be useful if you want to use alternate libraries
+//#define LUCENE_DISABLE_INCLUDES
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+// These options will be changed depending on your compiler/platform
+// but can also be changed here if required
+////////////////////////////////////////////////////////////////////
+//
+//define this if multi-threading support is not required
+//if not defined, multi-thread locking will
+//occur (and its related processing overhead)
+//note: it is recommended to disable multithreading if you do not need it
+//there is a lot of overhead that can be avoided.
+//#define _CL_DISABLE_MULTITHREADING
+//
+//if you want to define your own default file encoding. specify it
+//here - normally defined in the platform specific headers
+//#define PLATFORM_DEFAULT_READER_ENCODING CL_NS(util)::FileReader::ENCODING_ASCII
+//
+//disable hash implementations (if available)
+//#define LUCENE_DISABLE_HASHING
+////////////////////////////////////////////////////////////////////
+
+
+
+////////////////////////////////////////////////////////////////////
+// These options should not be changed. But you can experiment with
+// them to optimize performance
+////////////////////////////////////////////////////////////////////
+//
+//some defaults, wouldn't usually need to be changed
+//Buffer size for input/output streams. Required.
+#define LUCENE_STREAM_BUFFER_SIZE 1024
+//
+// DSR:2004.08.19:
+// Formerly, StringBuffer used 1024 as the default size of its internal buffer.
+// However, StringBuffer is used primarily for token- and term-oriented
+// processing, e.g. in StandardTokenizer. I've calculated that the average
+// token (as produced by StandardTokenizer) in all .txt files distributed in
+// the Project Gutenberg CD Image (August 2003 release) has only 6 characters.
+// Although most languages are likely to have a longer average word length than
+// English due to the popularity of "non-atomized" conjugation and declension
+// mechanisms, 1024 is still vastly excessive.
+// I made two changes intended to deliver better overall performance:
+// a) Switched to a default StringBuffer character capacity of 32. Though 32
+// is longer than the average token, the high cost of realloc makes a
+// slightly liberal default size optimal. I chose the default size of 32
+// after fairly extensive experimentation on the Gutenberg e-texts. The
+// results are summarized in the following table:
+// ------------------------------------------------------------------------
+// LUCENE_DEFAULT_TOKEN_BUFFER_SIZE value | % faster than default size 1024
+// ------------------------------------------------------------------------
+// 8 : 4%
+// 16 : 7%
+// 32 : 6%
+// 64 : 3%
+// A default size of 32 is actually slightly slower than 16, but I was
+// experimenting on English text; I expect that 32 will maintain decent
+// performance in languages such as German, and in technical documents
+// with long tokens.
+//
+// b) To offset the switch to a smaller default buffer size, I implemented a
+// more aggressive growth strategy. A StringBuffer now [at least] doubles
+// the size of its internal buffer every time it needs to grow, rather
+// than [at least] increasing by LUCENE_DEFAULT_TOKEN_BUFFER_SIZE no
+// matter how many times it has already grown.
+//Required.
+#define LUCENE_DEFAULT_TOKEN_BUFFER_SIZE 32
+//todo: should implement a similar strategy in analysis/token
+//
+//Expert: The fraction of {@link TermDocs} entries stored in skip tables,
+//used to accellerate {@link TermDocs#skipTo(int)}. Larger values result in
+//smaller indices, greater acceleration, but fewer accelerable cases, while
+//smaller values result in bigger indices, less acceleration and more
+//accelerable cases. More detailed experiments would be useful here. */
+#define LUCENE_DEFAULT_TERMDOCS_SKIP_INTERVAL 16
+//
+//Size of TermScore cache. Required.
+#define LUCENE_SCORE_CACHE_SIZE 32
+//
+//analysis options
+//maximum length that the CharTokenizer uses. Required.
+//By adjusting this value, you can greatly improve the performance of searching
+//and especially indexing. Default is 255, but smaller numbers will decrease
+//the amount of memory used as well as increasing the speed.
+#define LUCENE_MAX_WORD_LEN 255
+//Maximum length of a token word.
+//Should be the same or more than LUCENE_MAX_WORD_LEN
+//if not defined, then no token limit, but may be slower
+//if defined will be faster (up to 15% in some cases), but will use more memory
+#ifndef LUCENE_OPTIMIZE_FOR_MEMORY
+ #define LUCENE_TOKEN_WORD_LENGTH LUCENE_MAX_WORD_LEN
+#endif
+//
+//maximum field length. some optimisation can be done if a maximum field
+//length is given... The smaller the better
+#define LUCENE_MAX_FIELD_LEN 100
+//
+//The initial value set to BooleanQuery::maxClauseCount. Default is 1024
+#define LUCENE_BOOLEANQUERY_MAXCLAUSECOUNT 1024
+//
+//bvk: 12.3.2005
+//==============================================================================
+//Previously the way the tokenizer has worked has been changed to optionally
+//use a a fixed word length. I have implemented this in the Term class as well.
+//It seems that by predefining the text length instead of using new TCHAR[x]
+//in the constructor greatly improves the performance by 20-30% for certain
+//operations.
+//Maximum length of a term text.
+//Should be the same or more than LUCENE_MAX_WORD_LEN
+//if not defined, then no term text limit, but may be slower
+//if defined will be faster (up to 30% in some cases), but will use more memory
+#ifndef LUCENE_OPTIMIZE_FOR_MEMORY
+ #define LUCENE_TERM_TEXT_LENGTH LUCENE_MAX_WORD_LEN
+#endif
+//
+//Size of the CharTokenizer buffersize. Required.
+#define LUCENE_IO_BUFFER_SIZE 1024
+//
+//the minimum amount the segment term enum should grow by. Must be at least 1
+#define LUCENE_SEGMENTTERMENUM_GROWSIZE 8
+//
+////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/CLMonolithic.cpp b/3rdparty/clucene/src/CLucene/CLMonolithic.cpp
new file mode 100644
index 000000000..e3c279876
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/CLMonolithic.cpp
@@ -0,0 +1,115 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+/*
+* this is a monolithic file that can be used to compile clucene using one source file.
+* it simplifies some build processes by avoiding static & dynamic compalation pitfalls.
+*
+* note: when creating a project add either this file, or all the other .cpp files, not both!
+*/
+#include "CLucene/StdHeader.cpp"
+#include "CLucene/analysis/Analyzers.cpp"
+#include "CLucene/analysis/AnalysisHeader.cpp"
+#include "CLucene/analysis/standard/StandardAnalyzer.cpp"
+#include "CLucene/analysis/standard/StandardFilter.cpp"
+#include "CLucene/analysis/standard/StandardTokenizer.cpp"
+#include "CLucene/config/gunichartables.cpp"
+#include "CLucene/config/repl_tcscasecmp.cpp"
+#include "CLucene/config/repl_tcslwr.cpp"
+#include "CLucene/config/repl_tcstod.cpp"
+#include "CLucene/config/repl_lltot.cpp"
+#include "CLucene/config/repl_tcstoll.cpp"
+#include "CLucene/config/repl_tprintf.cpp"
+#include "CLucene/config/threads.cpp"
+#include "CLucene/config/utf8.cpp"
+#include "CLucene/debug/condition.cpp"
+#include "CLucene/debug/error.cpp"
+#include "CLucene/debug/memtracking.cpp"
+#include "CLucene/document/DateField.cpp"
+#include "CLucene/document/Document.cpp"
+#include "CLucene/document/Field.cpp"
+#include "CLucene/index/CompoundFile.cpp"
+#include "CLucene/index/DocumentWriter.cpp"
+#include "CLucene/index/FieldInfos.cpp"
+#include "CLucene/index/FieldsReader.cpp"
+#include "CLucene/index/FieldsWriter.cpp"
+#include "CLucene/index/IndexWriter.cpp"
+#include "CLucene/index/IndexReader.cpp"
+#include "CLucene/index/MultiReader.cpp"
+#include "CLucene/index/SegmentInfos.cpp"
+#include "CLucene/index/SegmentMergeInfo.cpp"
+#include "CLucene/index/SegmentMergeQueue.cpp"
+#include "CLucene/index/SegmentMerger.cpp"
+#include "CLucene/index/SegmentReader.cpp"
+#include "CLucene/index/SegmentTermDocs.cpp"
+#include "CLucene/index/SegmentTermEnum.cpp"
+#include "CLucene/index/SegmentTermPositions.cpp"
+#include "CLucene/index/SegmentTermVector.cpp"
+#include "CLucene/index/Term.cpp"
+#include "CLucene/index/TermInfo.cpp"
+#include "CLucene/index/TermInfosReader.cpp"
+#include "CLucene/index/TermInfosWriter.cpp"
+#include "CLucene/index/TermVectorReader.cpp"
+#include "CLucene/index/TermVectorWriter.cpp"
+#include "CLucene/queryParser/Lexer.cpp"
+#include "CLucene/queryParser/MultiFieldQueryParser.cpp"
+#include "CLucene/queryParser/QueryParser.cpp"
+#include "CLucene/queryParser/QueryParserBase.cpp"
+#include "CLucene/queryParser/QueryToken.cpp"
+#include "CLucene/queryParser/TokenList.cpp"
+#include "CLucene/search/BooleanQuery.cpp"
+#include "CLucene/search/BooleanScorer.cpp"
+#include "CLucene/search/CachingWrapperFilter.cpp"
+#include "CLucene/search/ChainedFilter.cpp"
+#include "CLucene/search/DateFilter.cpp"
+#include "CLucene/search/ConjunctionScorer.cpp"
+#include "CLucene/search/ExactPhraseScorer.cpp"
+#include "CLucene/search/Explanation.cpp"
+#include "CLucene/search/FieldCache.cpp"
+#include "CLucene/search/FieldCacheImpl.cpp"
+#include "CLucene/search/FieldDocSortedHitQueue.cpp"
+#include "CLucene/search/FieldSortedHitQueue.cpp"
+#include "CLucene/search/FilteredTermEnum.cpp"
+#include "CLucene/search/FuzzyQuery.cpp"
+#include "CLucene/search/Hits.cpp"
+#include "CLucene/search/HitQueue.cpp"
+#include "CLucene/search/IndexSearcher.cpp"
+#include "CLucene/search/MultiSearcher.cpp"
+#include "CLucene/search/MultiTermQuery.cpp"
+#include "CLucene/search/PhrasePositions.cpp"
+#include "CLucene/search/PhraseQuery.cpp"
+#include "CLucene/search/PhraseScorer.cpp"
+#include "CLucene/search/PrefixQuery.cpp"
+#include "CLucene/search/QueryFilter.cpp"
+#include "CLucene/search/RangeQuery.cpp"
+#include "CLucene/search/RangeFilter.cpp"
+#include "CLucene/search/SearchHeader.cpp"
+#include "CLucene/search/Similarity.cpp"
+#include "CLucene/search/SloppyPhraseScorer.cpp"
+#include "CLucene/search/Sort.cpp"
+#include "CLucene/search/TermQuery.cpp"
+#include "CLucene/search/TermScorer.cpp"
+#include "CLucene/search/WildcardQuery.cpp"
+#include "CLucene/search/WildcardTermEnum.cpp"
+#include "CLucene/store/FSDirectory.cpp"
+#include "CLucene/store/IndexInput.cpp"
+#include "CLucene/store/Lock.cpp"
+#include "CLucene/store/MMapInput.cpp"
+#include "CLucene/store/IndexOutput.cpp"
+#include "CLucene/store/RAMDirectory.cpp"
+#include "CLucene/store/TransactionalRAMDirectory.cpp"
+#include "CLucene/util/BitSet.cpp"
+#include "CLucene/util/Equators.cpp"
+#include "CLucene/util/FastCharStream.cpp"
+#include "CLucene/util/fileinputstream.cpp"
+#include "CLucene/util/Misc.cpp"
+#include "CLucene/util/Reader.cpp"
+#include "CLucene/util/StringBuffer.cpp"
+#include "CLucene/util/StringIntern.cpp"
+#include "CLucene/util/dirent.cpp"
+#include "CLucene/util/ThreadLocal.cpp"
diff --git a/3rdparty/clucene/src/CLucene/LuceneThreads.h b/3rdparty/clucene/src/CLucene/LuceneThreads.h
new file mode 100644
index 000000000..cad07869f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/LuceneThreads.h
@@ -0,0 +1,72 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _LuceneThreads_h
+#define _LuceneThreads_h
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#if defined(_CL_DISABLE_MULTITHREADING)
+ #define SCOPED_LOCK_MUTEX(theMutex)
+ #define DEFINE_MUTEX(x)
+ #define STATIC_DEFINE_MUTEX(x)
+ #define _LUCENE_SLEEP(x)
+ #define _LUCENE_CURRTHREADID 1
+ #define _LUCENE_THREADID_TYPE char
+
+ CL_NS_DEF(util)
+ class CLuceneThreadIdCompare
+ {
+ public:
+ enum
+ { // parameters for hash table
+ bucket_size = 4, // 0 < bucket_size
+ min_buckets = 8
+ }; // min_buckets = 2 ^^ N, 0 < N
+
+ bool operator()( char t1, char t2 ) const{
+ return t1 < t2;
+ }
+ };
+ CL_NS_END
+#else
+
+ #if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX)
+ //do nothing
+ #elif defined(_CL_HAVE_PTHREAD)
+ #include "CLucene/config/threadPthread.h"
+ #elif defined(_CL_HAVE_WIN32_THREADS) || defined(_CLCOMPILER_MSVC) || defined(__MINGW32__) //note that mingw32 could have pthreads, so put this after.
+ #if !defined(_CL_HAVE_WIN32_THREADS)
+ #define _CL_HAVE_WIN32_THREADS
+ #endif
+ #include "CLucene/config/threadCSection.h"
+ #else
+ #error A valid thread library was not found
+ #endif //mutex types
+
+ CL_NS_DEF(util)
+ /** @internal */
+ class mutexGuard
+ {
+ private:
+ _LUCENE_THREADMUTEX* mrMutex;
+ mutexGuard(const mutexGuard& clone);
+ public:
+ mutexGuard( _LUCENE_THREADMUTEX& rMutex );
+ ~mutexGuard();
+ };
+ CL_NS_END
+
+ #define SCOPED_LOCK_MUTEX(theMutex) CL_NS(util)::mutexGuard theMutexGuard(theMutex);
+ #define DEFINE_MUTEX(theMutex) _LUCENE_THREADMUTEX theMutex;
+ #define STATIC_DEFINE_MUTEX(theMutex) static _LUCENE_THREADMUTEX theMutex;
+
+#endif //_CL_DISABLE_MULTITHREADING
+
+
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/StdHeader.cpp b/3rdparty/clucene/src/CLucene/StdHeader.cpp
new file mode 100644
index 000000000..d64c51f77
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/StdHeader.cpp
@@ -0,0 +1,134 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "CLucene/util/Misc.h"
+
+#include "CLucene/search/Sort.h"
+#include "CLucene/search/Similarity.h"
+#include "CLucene/search/FieldCache.h"
+#include "CLucene/search/FieldSortedHitQueue.h"
+
+#if defined(_CLCOMPILER_MSVC) && defined(_DEBUG)
+# define CRTDBG_MAP_ALLOC
+# include <stdlib.h>
+#ifndef UNDER_CE
+# include <crtdbg.h>
+#endif
+#endif
+
+CL_NS_USE(util)
+
+TCHAR* _LUCENE_BLANK_STRING = _T("");
+char* _LUCENE_BLANK_ASTRING = "";
+
+#ifndef Q_CC_MIPS
+#if defined(_LUCENE_THREADMUTEX_USINGDEFAULT)
+# if defined(_LUCENE_PRAGMA_WARNINGS)
+# pragma message ("==================Using clunky thread mutex!!!==================")
+# else
+# if !defined(Q_OS_SOLARIS)
+# warning "==================Using clunky thread mutex!!!=================="
+# endif
+# endif
+#endif
+
+#if defined(_ASCII)
+# if defined(_LUCENE_PRAGMA_WARNINGS)
+# pragma message ("==================Using ascii mode!!!==================")
+# else
+# if !defined(Q_OS_SOLARIS)
+# warning "==================Using ascii mode!!!=================="
+# endif
+# endif
+#endif
+
+//This causes confusion, because CLucene doesn't really need hashed maps/sets. My experience with the
+//hash maps on linux are that there are no significant improvements in using them (infact it adversely
+//affected performance... therefore we'll just silently ignore
+/*#if defined(LUCENE_DISABLE_HASHING)
+# if defined(_LUCENE_PRAGMA_WARNINGS)
+# pragma message ("==================Hashing not available or is disabled! CLucene may run slower than optimal ==================")
+# else
+# if !defined(Q_OS_SOLARIS)
+# warning "==================Hashing not available or is disabled! CLucene may run slower than optimal =================="
+# endif
+# endif
+#endif*/
+#endif
+
+//clears all static memory. do not attempt to do anything else
+//in clucene after calling this function
+void _lucene_shutdown(){
+ CL_NS(search)::FieldSortedHitQueue::Comparators.clear();
+ _CLDELETE(CL_NS(search)::Sort::RELEVANCE);
+ _CLDELETE(CL_NS(search)::Sort::INDEXORDER);
+ _CLDELETE(CL_NS(search)::ScoreDocComparator::INDEXORDER);
+ _CLDELETE(CL_NS(search)::ScoreDocComparator::RELEVANCE);
+ _CLDELETE(CL_NS(search)::SortField::FIELD_SCORE);
+ _CLDELETE(CL_NS(search)::SortField::FIELD_DOC);
+ _CLDELETE(CL_NS(search)::FieldCache::DEFAULT);
+
+ _CLLDELETE(CL_NS(search)::Similarity::getDefault());
+
+ CL_NS(util)::CLStringIntern::shutdown();
+}
+
+void CLDebugBreak(){
+ //can be used for debug breaking...
+#if defined(_CLCOMPILER_MSVC) && defined(_DEBUG)
+ _CrtDbgBreak();
+#else
+ int i=0; //a line to put breakpoint on
+#endif
+}
+
+//these are functions that lucene uses which
+//are not replacement functions
+char* lucenestrdup(const char* v CL_FILELINEPARAM){
+ size_t len = strlen(v);
+ char* ret = new char[len+1];
+ strncpy(ret,v,len+1);
+#if defined(LUCENE_ENABLE_MEMLEAKTRACKING)
+# if defined(LUCENE_ENABLE_FILELINEINFO)
+ CL_NS(debug)::LuceneBase::__cl_voidpadd((void*)ret,file,line,len);
+# else
+ CL_NS(debug)::LuceneBase::__cl_voidpadd((void*)ret,__FILE__,__LINE__,len);
+# endif
+#endif
+ return ret;
+}
+
+#ifdef _UCS2
+wchar_t* lucenewcsdup(const wchar_t* v CL_FILELINEPARAM){
+ size_t len = _tcslen(v);
+ wchar_t* ret = new wchar_t[len+1];
+ _tcsncpy(ret,v,len+1);
+#if defined(LUCENE_ENABLE_MEMLEAKTRACKING)
+# if defined(LUCENE_ENABLE_FILELINEINFO)
+ CL_NS(debug)::LuceneBase::__cl_voidpadd((void*)ret,file,line,len);
+# else
+ CL_NS(debug)::LuceneBase::__cl_voidpadd((void*)ret,__FILE__,__LINE__,len);
+# endif
+#endif
+ return ret;
+}
+#endif //ucs2
+
+
+//ok, these are the exceptions, but these never
+//exist on non-msvc platform, so lets put it here
+#ifndef _CL_HAVE_FILELENGTH
+int64_t lucene_filelength(int filehandle)
+{
+ struct fileStat info;
+ if (fileHandleStat(filehandle, &info) == -1)
+ _CLTHROWA( CL_ERR_IO,"fileStat error" );
+ return info.st_size;
+}
+#endif
diff --git a/3rdparty/clucene/src/CLucene/StdHeader.h b/3rdparty/clucene/src/CLucene/StdHeader.h
new file mode 100644
index 000000000..fbb3fd949
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/StdHeader.h
@@ -0,0 +1,501 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#ifndef lucene_stdheader_h
+#define lucene_stdheader_h
+
+#if defined(OVERRIDE_DEFAULT_CLCONFIG)
+ #include "AltCLConfig.h"
+#else
+ #include "CLucene/CLConfig.h"
+#endif
+
+//first inclusion of compiler.h (it will be called again later)
+#include "CLucene/config/compiler.h"
+
+extern void _lucene_shutdown();
+extern int _lucene_counter_break; //can set a watch on this
+#if defined(LUCENE_ENABLE_MEMLEAKTRACKING)
+ extern bool _lucene_disable_debuglogging; //if LUCENE_ENABLE_CONSTRUCTOR_LOG is on, dont do log if this is true
+#endif
+
+////////////////////////////////////////////////////////
+// default includes
+////////////////////////////////////////////////////////
+#ifndef LUCENE_DISABLE_INCLUDES
+
+#include <stdio.h>
+
+#if defined(_CL_STDC_HEADERS)
+ #include <stdlib.h>
+ #include <stddef.h>
+#else
+ #if defined(_CL_HAVE_STDLIB_H)
+ #include <stdlib.h>
+ #endif
+#endif
+
+#if defined(_CL_HAVE_STRING_H)
+ #if !defined(_CL_STDC_HEADERS) && defined(_CL_HAVE_MEMORY_H)
+ #include <memory.h>
+ #endif
+ #include <string.h>
+#elif defined(_CL_HAVE_STRINGS_H)
+ //note: as a side note, strtok is not thread-safe.. so be careful where you use it!
+ #error "strtok replacement for BSD has not been implemented"
+ #include <strings.h>
+ #if !defined(_CL_HAVE_STRCHR)
+ #define strchr index
+ #define strrchr rindex
+ #endif
+#endif
+
+#if defined(_CL_HAVE_UNISTD_H)
+ #include <unistd.h>
+#elif defined(_CL_HAVE_IO_H) && defined(_CL_HAVE_DIRECT_H)
+#ifndef UNDER_CE
+ #include <io.h>
+ #include <direct.h>
+#endif
+#else
+ #error "Neither unistd.h or (io.h & direct.h) were available"
+#endif
+
+#ifndef _CL_DISABLE_NATIVE_EXCEPTIONS
+ #ifdef _CL_HAVE_STDEXCEPT
+ #include <stdexcept>
+ #else
+ #error "CLucene can't compile with exception handling on because <stdexcept> header is not available"
+ #endif
+#endif
+
+#if defined(_CL_STAT_MACROS_BROKEN)
+ #error "Haven't implemented STAT_MACROS_BROKEN fix yet"
+#elif defined(_CL_HAVE_SYS_STAT_H)
+#ifdef UNDER_CE
+ #include <types.h>
+#else
+ #include <sys/stat.h>
+#endif
+#else
+ #error "Haven't implemented platforms with no sys/stat.h"
+#endif
+
+#if defined(_CL_HAVE_STDARG_H)
+ #include <stdarg.h>
+#else
+ #error "CLucene can compile, but some extras may not work"
+#endif
+
+#if defined(_CL_HAVE_MATH_H)
+ #include <math.h>
+#else
+ #error "CLucene can't compile without <math.h>"
+#endif
+
+#if defined(_CL_HAVE_MAP)
+ #include <map>
+#else
+ #error "CLucene can't compile without the map header"
+#endif
+
+#if defined(_CL_HAVE_LIST)
+ #include <list>
+#else
+ #error "CLucene can't compile without the list header"
+#endif
+
+#if defined(_CL_HAVE_SET)
+ #include <set>
+#else
+ #error "CLucene can't compile without the set header"
+#endif
+
+#if defined(_CL_HAVE_VECTOR)
+ #include <vector>
+#else
+ #error "CLucene can't compile without the vector header"
+#endif
+
+#if !defined(LUCENE_DISABLE_HASHING) && defined(_CL_HAVE_HASH_MAP) && defined(_CL_HAVE_HASH_SET)
+ //hashing is all or nothing!
+ #include <hash_map>
+ #include <hash_set>
+#elif !defined(LUCENE_DISABLE_HASHING) && defined(_CL_HAVE_EXT_HASH_MAP) && defined(_CL_HAVE_EXT_HASH_SET)
+ #include <ext/hash_map>
+ #include <ext/hash_set>
+#elif !defined(LUCENE_DISABLE_HASHING)
+ #define LUCENE_DISABLE_HASHING
+#endif
+#if !defined(LUCENE_DISABLE_HASHING) && !defined(CL_NS_HASHING)
+ #define CL_NS_HASHING(func) std::func
+#endif
+
+#if defined(_CL_HAVE_ALGORITHM)
+# include <algorithm>
+#else
+# error "Can't compile clucene without <algorithm>"
+#endif
+
+#if defined(_CL_HAVE_FUNCTIONAL)
+# include <functional>
+#else
+# error "Can't compile clucene without <functional>"
+#endif
+
+#if !defined(_CL_HAVE_PRINTF)
+ #error "CLucene can't compile without printf, replacements have not been implemented"
+#endif
+
+#if !defined(_CL_HAVE_SNPRINTF) && !defined(_CL_HAVE__SNPRINTF)
+ #error "CLucene can't compile without snprintf, replacements have not been implemented"
+#elif !defined(_CL_HAVE__SNPRINTF)&& defined(_CL_HAVE_SVNPRINTF)
+ #define _snprintf snprintf
+#endif
+
+#if defined(_UCS2)
+ #if defined(_CL_HAVE_WCHAR_H)
+ #include <wchar.h>
+ #else
+ //actually the repl_wchar.h replacements header will
+ //always be included. It replaces some functions
+ //that are missing in some wchar.h headers.
+ #endif
+#endif
+
+#if defined(_UCS2) && defined(_CL_HAVE_WCTYPE_H)
+ #include <wctype.h>
+#elif defined(_ASCII) && defined(_CL_HAVE_CTYPE_H)
+ #include <ctype.h>
+ #undef LUCENE_USE_INTERNAL_CHAR_FUNCTIONS
+#elif defined(_UCS2)
+ //must be in _UCS2 to use internal char functions
+ #undef LUCENE_USE_INTERNAL_CHAR_FUNCTIONS
+ #define LUCENE_USE_INTERNAL_CHAR_FUNCTIONS
+#else
+ #error "Cannot compile in _ASCII without ctype.h"
+#endif
+
+//always include replacement, some missing tchar defines
+#include "CLucene/config/repl_tchar.h"
+
+#if defined(_CL_HAVE_ERRNO_H)
+#ifndef UNDER_CE
+ #include <errno.h>
+#endif
+#else
+ #error "Haven't implemented platforms with no errno.h"
+#endif
+
+#if defined(_CL_HAVE_FCNTL_H)
+#ifndef UNDER_CE
+ #include <fcntl.h>
+#endif
+#else
+ #error "Haven't implemented platforms with no fcntl.h"
+#endif
+
+#if defined(_CL_HAVE_WINDOWS_H)
+ #include <windows.h>
+#endif
+
+#endif //LUCENE_DISABLE_INCLUDES
+//
+////////////////////////////////////////////////////////
+
+//second inclusion of compiler.h
+//this gives CompilerXXX.h a chance to include other headers
+#include "CLucene/config/compiler.h"
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// Character functions.
+// Here we decide whose character functions to use
+////////////////////////////////////////////////////////
+#if defined(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS)
+ #define stringCaseFold cl_tcscasefold
+ #define stringCaseFoldCmp cl_tcscasefoldcmp
+
+ #undef _istspace
+ #undef _istdigit
+ #undef _istalnum
+ #undef _istalpha
+ #undef _totlower
+ #undef _totupper
+ #define _istalnum cl_isalnum
+ #define _istalpha cl_isletter
+ #define _istspace cl_isspace
+ #define _istdigit cl_isdigit
+ #define _totlower cl_tolower
+ #define _totupper cl_toupper
+
+ //here are some functions to help deal with utf8/ucs2 conversions
+ //lets let the user decide what mb functions to use... we provide pure utf8 ones no matter what.
+ /*#undef _mbtowc
+ #undef _mbstowcs
+ #undef _wctomb
+ #undef _wcstombs
+ #define _mbtowc lucene_mbstowc
+ #define _mbsstowcs lucene_mbstowcs
+ #define _wctomb lucene_wcto_mb
+ #define _wcstombs lucene_wcstombs*/
+#else
+ //we are using native functions
+ //here are some functions to help deal with utf8/ucs2 conversions
+ /*#define _mbtowc mbtowc
+ #define _wctomb wctomb
+ #define _mbstowcs mbstowcs
+ #define _wcstombs wcstombs*/
+
+ //we are using native character functions
+ #if defined(_ASCII)
+ #undef _istspace
+ #undef _istdigit
+ #undef _istalnum
+ #undef _istalpha
+ #undef _totlower
+ #undef _totupper
+ #define _istspace(x) isspace((unsigned char)x)
+ #define _istdigit(x) isdigit((unsigned char)x)
+ #define _istalnum(x) isalnum((unsigned char)x)
+ #define _istalpha(x) isalpha((unsigned char)x)
+ #define _totlower(x) tolower((unsigned char)x)
+ #define _totupper(x) toupper((unsigned char)x)
+ #endif
+#endif
+
+//the methods contained in gunichartables.h
+typedef unsigned long clunichar;
+bool cl_isletter(clunichar c);
+bool cl_isalnum(clunichar c);
+bool cl_isdigit(clunichar c);
+bool cl_isspace (clunichar c);
+TCHAR cl_tolower (TCHAR c);
+TCHAR cl_toupper (TCHAR c);
+
+int cl_tcscasefoldcmp(const TCHAR * dst, const TCHAR * src);
+TCHAR* cl_tcscasefold( TCHAR * str, int len=-1 );
+
+//we provide utf8 conversion functions
+size_t lucene_utf8towc (wchar_t *ret, const char *s, size_t n);
+size_t lucene_utf8towcs(wchar_t *, const char *, size_t maxslen);
+size_t lucene_wctoutf8 (char * ret, const wchar_t str);
+size_t lucene_wcstoutf8 (char *, const wchar_t *, size_t maxslen);
+size_t lucene_utf8charlen(const char *p);
+
+///a blank string...
+extern TCHAR* _LUCENE_BLANK_STRING;
+#define LUCENE_BLANK_STRING _LUCENE_BLANK_STRING
+extern char* _LUCENE_BLANK_ASTRING;
+#define LUCENE_BLANK_ASTRING _LUCENE_BLANK_ASTRING
+
+/* Converts a string into a form that is independent of case. The
+ * result will not correspond to any particular case, but can be
+ * compared for equality or ordered with the results of calling
+ * stringCaseFold() on other strings.
+ *
+ * If we did not define this elsewhere, then just convert to lower case
+ */
+#ifndef stringCaseFold
+ #define stringCaseFold _tcslwr
+#endif
+/* Compares 2 strings using case folding (if available)
+ * If we did not define this elsewhere, then just compare
+ * using normal method
+ */
+#ifndef stringCaseFoldCmp
+ #define stringCaseFoldCmp _tcsicmp
+#endif
+
+//now that all the character routines are completed, include the
+//wchar.h replacements.
+#include "CLucene/config/repl_wchar.h" //always include replacements
+
+//a replacement for _tcsdup. This uses new TCHAR[] instead of malloc, so that we can use delete[] to free
+#if defined(LUCENE_ENABLE_FILELINEINFO)
+ #define CL_FILELINE ,__FILE__,__LINE__
+ #define CL_FILELINEREF ,file,line ///<for passing the reference along to another function
+ #define CL_FILELINEREF2 ,file,line ///<for passing the reference along to another function
+ #define CL_FILELINEPARAM ,char* file,int line
+#else
+ #define CL_FILELINE
+ #define CL_FILELINEREF
+ #define CL_FILELINEREF2 ,NULL,-1
+ #define CL_FILELINEPARAM
+#endif
+
+char* lucenestrdup(const char* v CL_FILELINEPARAM);
+#if defined(_UCS2)
+ wchar_t* lucenewcsdup(const wchar_t* v CL_FILELINEPARAM);
+ #define stringDuplicate(x) lucenewcsdup(x CL_FILELINE) //don't change this... uses [] instead of malloc
+#else
+ #define stringDuplicate(x) lucenestrdup(x CL_FILELINE) //don't change this... uses [] instead of malloc
+#endif
+
+#define STRCPY_AtoA(target,src,len) strncpy(target,src,len)
+#define STRDUP_AtoA(x) lucenestrdup(x CL_FILELINE)
+
+#if defined(_UCS2)
+ #define STRDUP_WtoW(x) lucenewcsdup(x CL_FILELINE)
+ #define STRDUP_TtoT STRDUP_WtoW
+ #define STRDUP_WtoT STRDUP_WtoW
+ #define STRDUP_TtoW STRDUP_WtoW
+
+ #define STRDUP_AtoW(x) CL_NS(util)::Misc::_charToWide(x CL_FILELINE)
+ #define STRDUP_AtoT STRDUP_AtoW
+
+ #define STRDUP_WtoA(x) CL_NS(util)::Misc::_wideToChar(x CL_FILELINE)
+ #define STRDUP_TtoA STRDUP_WtoA
+
+ #define STRCPY_WtoW(target,src,len) _tcsncpy(target,src,len)
+ #define STRCPY_TtoW STRCPY_WtoW
+ #define STRCPY_WtoT STRCPY_WtoW
+ #define STRCPY_TtoT STRCPY_WtoW
+
+ #define STRCPY_AtoW(target,src,len) CL_NS(util)::Misc::_cpycharToWide(src,target,len)
+ #define STRCPY_AtoT STRCPY_AtoW
+
+ #define STRCPY_WtoA(target,src,len) CL_NS(util)::Misc::_cpywideToChar(src,target,len)
+ #define STRCPY_TtoA STRCPY_WtoA
+#else
+ #define STRDUP_AtoT STRDUP_AtoA
+ #define STRDUP_TtoA STRDUP_AtoA
+ #define STRDUP_TtoT STRDUP_AtoA
+
+ #define STRDUP_WtoT(x) xxxxxxxxxxxxxxx //not possible
+ #define STRCPY_WtoT(target,src,len) xxxxxxxxxxxxxxx //not possible
+
+ #define STRCPY_AtoT STRCPY_AtoA
+ #define STRCPY_TtoA STRCPY_AtoA
+ #define STRCPY_TtoT STRCPY_AtoA
+#endif
+
+//
+////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////
+//namespace helper
+////////////////////////////////////////////////////////
+#if defined(_LUCENE_DONTIMPLEMENT_NS_MACROS)
+
+#elif !defined(DISABLE_NAMESPACE)
+//
+// W A R N I N G
+// -------------
+//
+// adjustments here, need to be done in
+// QTDIR/src/tools/assistant/lib/fulltextsearch/qclucene_global.h as well
+//
+# ifdef QT_NAMESPACE
+# define CL_NS_DEF(sub) namespace QT_NAMESPACE { namespace lucene{ namespace sub{
+# define CL_NS_DEF2(sub,sub2) namespace QT_NAMESPACE { namespace lucene{ namespace sub{ namespace sub2 {
+
+# define CL_NS_END }}}
+# define CL_NS_END2 }}}}
+
+# define CL_NS_USE(sub) using namespace QT_NAMESPACE::lucene::sub;
+# define CL_NS_USE2(sub,sub2) using namespace QT_NAMESPACE::lucene::sub::sub2;
+
+# define CL_NS(sub) QT_NAMESPACE::lucene::sub
+# define CL_NS2(sub,sub2) QT_NAMESPACE::lucene::sub::sub2
+# else
+# define CL_NS_DEF(sub) namespace lucene{ namespace sub{
+# define CL_NS_DEF2(sub,sub2) namespace lucene{ namespace sub{ namespace sub2 {
+
+# define CL_NS_END }}
+# define CL_NS_END2 }}}
+
+# define CL_NS_USE(sub) using namespace lucene::sub;
+# define CL_NS_USE2(sub,sub2) using namespace lucene::sub::sub2;
+
+# define CL_NS(sub) lucene::sub
+# define CL_NS2(sub,sub2) lucene::sub::sub2
+# endif
+#else
+# define CL_NS_DEF(sub)
+# define CL_NS_DEF2(sub, sub2)
+# define CL_NS_END
+# define CL_NS_END2
+# define CL_NS_USE(sub)
+# define CL_NS_USE2(sub,sub2)
+# define CL_NS(sub)
+# define CL_NS2(sub,sub2)
+#endif
+
+#if defined(LUCENE_NO_STDC_NAMESPACE)
+ //todo: haven't actually tested this on a non-stdc compliant compiler
+ #define CL_NS_STD(func) ::func
+#else
+ #define CL_NS_STD(func) std::func
+#endif
+//
+////////////////////////////////////////////////////////
+
+//
+void CLDebugBreak(); //define a debugbreak function
+
+
+////////////////////////////////////////////////////////////////
+// These are defines and functions used throughout clucene
+////////////////////////////////////////////////////////////////
+#undef _T //remove any previously defined _T - required for ppc os
+#if defined(_UCS2)
+ #define _T(x) L ## x
+#else
+ #define _T(x) x
+#endif
+
+//third inclusion of compiler.h
+//this gives CompilerXXX.h a chance to fix any of the
+//default settings
+#include "CLucene/config/compiler.h"
+
+#if defined _MSC_VER && (_MSC_VER < 1300)
+# define LUCENE_NO_STDC_NAMESPACE
+#endif
+
+//use std namespace
+#ifndef LUCENE_NO_STDC_NAMESPACE
+using namespace std;
+#endif
+
+
+////////////////////////////////////////////////////////
+//misc shortcut defines
+////////////////////////////////////////////////////////
+
+//include the headers that we need practically everywhere
+#include "CLucene/debug/error.h" //all delete/creation/mem debugging code
+#include "CLucene/debug/condition.h" //conditional debugging (like assert)
+#include "CLucene/debug/mem.h" //all delete/creation/mem debugging code
+#include "LuceneThreads.h" //lucene threading support
+
+#include "CLucene/util/Misc.h"
+#include "CLucene/util/Equators.h"
+#include "CLucene/util/VoidList.h"
+#include "CLucene/util/VoidMap.h"
+
+
+CL_NS_DEF(util)
+typedef CL_NS(util)::CLVector<TCHAR*> StringArray;
+typedef CL_NS(util)::CLVector<TCHAR*, CL_NS(util)::Deletor::tcArray > StringArrayWithDeletor;
+typedef CL_NS(util)::CLVector<const TCHAR*> StringArrayConst;
+typedef CL_NS(util)::CLVector<const TCHAR*, CL_NS(util)::Deletor::tcArray > StringArrayConstWithDeletor;
+
+typedef CL_NS(util)::CLVector<char*> AStringArray;
+typedef CL_NS(util)::CLVector<char*, CL_NS(util)::Deletor::acArray > AStringArrayWithDeletor;
+typedef CL_NS(util)::CLVector<const char*> AStringArrayConst;
+typedef CL_NS(util)::CLVector<const char*, CL_NS(util)::Deletor::acArray > AStringArrayConstWithDeletor;
+CL_NS_END
+
+//
+////////////////////////////////////////////////////////
+
+#endif // STDHEADER_H
diff --git a/3rdparty/clucene/src/CLucene/analysis/AnalysisHeader.cpp b/3rdparty/clucene/src/CLucene/analysis/AnalysisHeader.cpp
new file mode 100644
index 000000000..03f61a038
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/AnalysisHeader.cpp
@@ -0,0 +1,200 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "AnalysisHeader.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(analysis)
+
+const TCHAR* Token::defaultType=_T("word");
+
+Token::Token():
+ _startOffset (0),
+ _endOffset (0),
+ _type ( defaultType ),
+ positionIncrement (1)
+{
+ _termTextLen = 0;
+#ifndef LUCENE_TOKEN_WORD_LENGTH
+ _termText = NULL;
+ bufferTextLen = 0;
+#else
+ _termText[0] = 0; //make sure null terminated
+ bufferTextLen = LUCENE_TOKEN_WORD_LENGTH+1;
+#endif
+}
+
+Token::~Token(){
+#ifndef LUCENE_TOKEN_WORD_LENGTH
+ free(_termText);
+#endif
+}
+
+Token::Token(const TCHAR* text, const int32_t start, const int32_t end, const TCHAR* typ):
+ _startOffset (start),
+ _endOffset (end),
+ _type ( typ ),
+ positionIncrement (1)
+{
+ _termTextLen = 0;
+#ifndef LUCENE_TOKEN_WORD_LENGTH
+ _termText = NULL;
+ bufferTextLen = 0;
+#else
+ _termText[0] = 0; //make sure null terminated
+ bufferTextLen = LUCENE_TOKEN_WORD_LENGTH+1;
+#endif
+ setText(text);
+}
+
+void Token::set(const TCHAR* text, const int32_t start, const int32_t end, const TCHAR* typ){
+ _startOffset = start;
+ _endOffset = end;
+ _type = typ;
+ positionIncrement = 1;
+ setText(text);
+}
+
+void Token::setText(const TCHAR* text){
+ _termTextLen = _tcslen(text);
+
+#ifndef LUCENE_TOKEN_WORD_LENGTH
+ growBuffer(_termTextLen+1);
+ _tcsncpy(_termText,text,_termTextLen+1);
+#else
+ if ( _termTextLen > LUCENE_TOKEN_WORD_LENGTH ){
+ //in the case where this occurs, we will leave the endOffset as it is
+ //since the actual word still occupies that space.
+ _termTextLen=LUCENE_TOKEN_WORD_LENGTH;
+ }
+ _tcsncpy(_termText,text,_termTextLen+1);
+#endif
+ _termText[_termTextLen] = 0; //make sure null terminated
+}
+
+void Token::growBuffer(size_t size){
+ if(bufferTextLen>=size)
+ return;
+#ifndef LUCENE_TOKEN_WORD_LENGTH
+ if ( _termText == NULL )
+ _termText = (TCHAR*)malloc( size * sizeof(TCHAR) );
+ else
+ _termText = (TCHAR*)realloc( _termText, size * sizeof(TCHAR) );
+ bufferTextLen = size;
+#else
+ _CLTHROWA(CL_ERR_TokenMgr,"Couldn't grow Token buffer");
+#endif
+}
+
+void Token::setPositionIncrement(int32_t posIncr) {
+ if (posIncr < 0) {
+ _CLTHROWA(CL_ERR_IllegalArgument,"positionIncrement must be >= 0");
+ }
+ positionIncrement = posIncr;
+}
+
+int32_t Token::getPositionIncrement() const { return positionIncrement; }
+
+// Returns the Token's term text.
+const TCHAR* Token::termText() const{
+ return (const TCHAR*) _termText;
+}
+size_t Token::termTextLength() {
+ if ( _termTextLen == -1 ) //it was invalidated by growBuffer
+ _termTextLen = _tcslen(_termText);
+ return _termTextLen;
+}
+void Token::resetTermTextLen(){
+ _termTextLen=-1;
+}
+bool Token::OrderCompare::operator()( Token* t1, Token* t2 ) const{
+ if(t1->startOffset()>t2->startOffset())
+ return false;
+ if(t1->startOffset()<t2->startOffset())
+ return true;
+ return true;
+}
+TCHAR* Token::toString() const{
+ StringBuffer sb;
+ sb.append(_T("("));
+ sb.append( _termText );
+ sb.append(_T(","));
+ sb.appendInt( _startOffset );
+ sb.append(_T(","));
+ sb.appendInt( _endOffset );
+
+ if (!_tcscmp( _type, _T("word")) == 0 ){
+ sb.append(_T(",type="));
+ sb.append(_type);
+ }
+ if (positionIncrement != 1){
+ sb.append(_T(",posIncr="));
+ sb.appendInt(positionIncrement);
+ }
+ sb.append(_T(")"));
+
+ return sb.toString();
+}
+
+
+Token* TokenStream::next(){
+ Token* t = _CLNEW Token; //deprecated
+ if ( !next(t) )
+ _CLDELETE(t);
+ return t;
+}
+
+
+TokenFilter::TokenFilter(TokenStream* in, bool deleteTS):
+ input(in),
+ deleteTokenStream(deleteTS)
+{
+}
+TokenFilter::~TokenFilter(){
+ close();
+}
+
+// Close the input TokenStream.
+void TokenFilter::close() {
+ if ( input != NULL ){
+ input->close();
+ if ( deleteTokenStream )
+ _CLDELETE( input );
+ }
+ input = NULL;
+}
+
+
+
+Tokenizer::Tokenizer() {
+ input = NULL;
+}
+
+Tokenizer::Tokenizer(CL_NS(util)::Reader* _input):
+ input(_input)
+{
+}
+
+void Tokenizer::close(){
+ if (input != NULL) {
+ // ? delete input;
+ input = NULL;
+ }
+}
+
+Tokenizer::~Tokenizer(){
+ close();
+}
+
+
+int32_t Analyzer::getPositionIncrementGap(const TCHAR* fieldName)
+{
+ return 0;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/analysis/AnalysisHeader.h b/3rdparty/clucene/src/CLucene/analysis/AnalysisHeader.h
new file mode 100644
index 000000000..0cfd9c684
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/AnalysisHeader.h
@@ -0,0 +1,234 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_analysis_AnalysisHeader_
+#define _lucene_analysis_AnalysisHeader_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/Reader.h"
+
+CL_NS_DEF(analysis)
+
+
+/** A Token is an occurence of a term from the text of a field. It consists of
+* a term's text, the start and end offset of the term in the text of the field,
+* and a type string.
+*
+* The start and end offsets permit applications to re-associate a token with
+* its source text, e.g., to display highlighted query terms in a document
+* browser, or to show matching text fragments in a KWIC (KeyWord In Context)
+* display, etc.
+*
+* The type is an interned string, assigned by a lexical analyzer
+* (a.k.a. tokenizer), naming the lexical or syntactic class that the token
+* belongs to. For example an end of sentence marker token might be implemented
+* with type "eos". The default token type is "word".
+*/
+class Token:LUCENE_BASE{
+private:
+ int32_t _startOffset; // start in source text
+ int32_t _endOffset; // end in source text
+ const TCHAR* _type; // lexical type
+ int32_t positionIncrement;
+ size_t bufferTextLen;
+
+public:
+ #ifndef LUCENE_TOKEN_WORD_LENGTH
+ TCHAR* _termText; // the text of the term
+ #else
+ TCHAR _termText[LUCENE_TOKEN_WORD_LENGTH+1]; // the text of the term
+ #endif
+ int32_t _termTextLen;
+ static const TCHAR* defaultType;
+
+ Token();
+ ~Token();
+ // Constructs a Token with the given text, start and end offsets, & type.
+ Token(const TCHAR* text, const int32_t start, const int32_t end, const TCHAR* typ=defaultType);
+ void set(const TCHAR* text, const int32_t start, const int32_t end, const TCHAR* typ=defaultType);
+
+ size_t bufferLength(){ return bufferTextLen; }
+ void growBuffer(size_t size);
+
+ /* Set the position increment. This determines the position of this
+ * token relative to the previous Token in a TokenStream, used in
+ * phrase searching.
+ *
+ * The default value is 1.
+ *
+ * Some common uses for this are:
+ *
+ * - Set it to zero to put multiple terms in the same position. This is
+ * useful if, e.g., a word has multiple stems. Searches for phrases
+ * including either stem will match. In this case, all but the first stem's
+ * increment should be set to zero: the increment of the first instance
+ * should be one. Repeating a token with an increment of zero can also be
+ * used to boost the scores of matches on that token.
+ *
+ * - Set it to values greater than one to inhibit exact phrase matches.
+ * If, for example, one does not want phrases to match across removed stop
+ * words, then one could build a stop word filter that removes stop words and
+ * also sets the increment to the number of stop words removed before each
+ * non-stop word. Then exact phrase queries will only match when the terms
+ * occur with no intervening stop words.
+ */
+ void setPositionIncrement(int32_t posIncr);
+ int32_t getPositionIncrement() const;
+ const TCHAR* termText() const;
+ size_t termTextLength();
+ void resetTermTextLen();
+ void setText(const TCHAR* txt);
+
+ /**
+ * Returns this Token's starting offset, the position of the first character
+ * corresponding to this token in the source text.
+ *
+ * Note that the difference between endOffset() and startOffset() may not be
+ * equal to termText.length(), as the term text may have been altered by a
+ * stemmer or some other filter.
+ */
+ int32_t startOffset() const { return _startOffset; }
+ void setStartOffset(int32_t val){ _startOffset =val; }
+
+ /**
+ * Returns this Token's ending offset, one greater than the position of the
+ * last character corresponding to this token in the source text.
+ */
+ int32_t endOffset() const { return _endOffset; }
+ void setEndOffset(int32_t val){ _endOffset =val; }
+
+ // Returns this Token's lexical type. Defaults to "word".
+ const TCHAR* type() const { return _type; } ///<returns reference
+ void setType(const TCHAR* val) { _type = val; } ///<returns reference
+
+ TCHAR* toString() const;
+
+ ///Compares the Token for their order
+ class OrderCompare:LUCENE_BASE, public CL_NS(util)::Compare::_base //<Token*>
+ {
+ public:
+ bool operator()( Token* t1, Token* t2 ) const;
+ };
+};
+
+/**
+* A TokenStream enumerates the sequence of tokens, either from
+* fields of a document or from query text.
+* <p>
+* This is an abstract class. Concrete subclasses are:
+* <ul>
+* <li>{@link Tokenizer}, a TokenStream
+* whose input is a Reader; and
+* <li>{@link TokenFilter}, a TokenStream
+* whose input is another TokenStream.
+* </ul>
+*/
+class TokenStream:LUCENE_BASE {
+public:
+ /** Sets token to the next token in the stream, returns false at the EOS. */
+ virtual bool next(Token* token) = 0;
+
+ /** Releases resources associated with this stream. */
+ virtual void close() = 0;
+
+ virtual ~TokenStream(){
+ }
+
+ /* This is for backwards compatibility only. You should pass the token you want to fill
+ * to next(), this will save a lot of object construction and destructions.
+ * @deprecated. use next(token). Kept only to avoid breaking existing code.
+ */
+ _CL_DEPRECATED(next(Token)) Token* next();
+};
+
+
+/** An Analyzer builds TokenStreams, which analyze text. It thus represents a
+ * policy for extracting index terms from text.
+ * <p>
+ * Typical implementations first build a Tokenizer, which breaks the stream of
+ * characters from the Reader into raw Tokens. One or more TokenFilters may
+ * then be applied to the output of the Tokenizer.
+ * <p>
+ * WARNING: You must override one of the methods defined by this class in your
+ * subclass or the Analyzer will enter an infinite loop.
+ */
+class Analyzer:LUCENE_BASE{
+public:
+ /** Creates a TokenStream which tokenizes all the text in the provided
+ Reader. Default implementation forwards to tokenStream(Reader) for
+ compatibility with older version. Override to allow Analyzer to choose
+ strategy based on document and/or field. Must be able to handle null
+ field name for backward compatibility. */
+ virtual TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader)=0;
+
+ virtual ~Analyzer(){
+ }
+
+ /**
+ * Invoked before indexing a Field instance if
+ * terms have already been added to that field. This allows custom
+ * analyzers to place an automatic position increment gap between
+ * Field instances using the same field name. The default value
+ * position increment gap is 0. With a 0 position increment gap and
+ * the typical default token position increment of 1, all terms in a field,
+ * including across Field instances, are in successive positions, allowing
+ * exact PhraseQuery matches, for instance, across Field instance boundaries.
+ *
+ * @param fieldName Field name being indexed.
+ * @return position increment gap, added to the next token emitted from {@link #tokenStream(TCHAR*, Reader*)}
+ */
+ virtual int32_t getPositionIncrementGap(const TCHAR* fieldName);
+};
+
+
+/** A Tokenizer is a TokenStream whose input is a Reader.
+<p>
+This is an abstract class.
+*/
+class Tokenizer:public TokenStream {
+protected:
+ /** The text source for this Tokenizer. */
+ CL_NS(util)::Reader* input;
+
+public:
+ /** Construct a tokenizer with null input. */
+ Tokenizer();
+ /** Construct a token stream processing the given input. */
+ Tokenizer(CL_NS(util)::Reader* _input);
+
+ // ** By default, closes the input Reader. */
+ virtual void close();
+ virtual ~Tokenizer();
+};
+
+/** A TokenFilter is a TokenStream whose input is another token stream.
+<p>
+This is an abstract class.
+*/
+class TokenFilter:public TokenStream {
+protected:
+ /** The source of tokens for this filter. */
+ TokenStream* input;
+ /** If true then input will be deleted in the destructor */
+ bool deleteTokenStream;
+
+ /** Construct a token stream filtering the given input.
+ *
+ * @param in The TokenStream to filter from
+ * @param deleteTS If true, input will be deleted in the destructor
+ */
+ TokenFilter(TokenStream* in, bool deleteTS=false);
+ virtual ~TokenFilter();
+public:
+ /** Close the input TokenStream. */
+ void close();
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/analysis/Analyzers.cpp b/3rdparty/clucene/src/CLucene/analysis/Analyzers.cpp
new file mode 100644
index 000000000..142bbfb63
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/Analyzers.cpp
@@ -0,0 +1,389 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "Analyzers.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(analysis)
+
+CharTokenizer::CharTokenizer(Reader* in) :
+ Tokenizer(in),
+ offset(0),
+ bufferIndex(0),
+ dataLen(0),
+ ioBuffer(NULL)
+{
+ buffer[0]=0;
+}
+
+TCHAR CharTokenizer::normalize(const TCHAR c) const
+{
+ return c;
+}
+bool CharTokenizer::next(Token* token){
+ int32_t length = 0;
+ int32_t start = offset;
+ while (true) {
+ TCHAR c;
+ offset++;
+ if (bufferIndex >= dataLen) {
+ dataLen = input->read(ioBuffer, LUCENE_IO_BUFFER_SIZE);
+ if (dataLen == -1)
+ dataLen = 0;
+ bufferIndex = 0;
+ }
+ if (dataLen <= 0 ) {
+ if (length > 0)
+ break;
+ else
+ return false;
+ }else
+ c = ioBuffer[bufferIndex++];
+ if (isTokenChar(c)) { // if it's a token TCHAR
+
+ if (length == 0) // start of token
+ start = offset-1;
+
+ buffer[length++] = normalize(c); // buffer it, normalized
+
+ if (length == LUCENE_MAX_WORD_LEN) // buffer overflow!
+ break;
+
+ } else if (length > 0) // at non-Letter w/ chars
+ break; // return 'em
+
+ }
+ buffer[length]=0;
+ token->set( buffer, start, start+length);
+ return true;
+}
+
+bool LetterTokenizer::isTokenChar(const TCHAR c) const {
+ return _istalpha(c)!=0;
+}
+
+
+TCHAR LowerCaseTokenizer::normalize(const TCHAR chr) const {
+ return _totlower(chr);
+}
+
+bool WhitespaceTokenizer::isTokenChar(const TCHAR c) const{
+ return _istspace(c)==0; //(return true if NOT a space)
+}
+
+TokenStream* WhitespaceAnalyzer::tokenStream(const TCHAR* fieldName, Reader* reader) {
+ return _CLNEW WhitespaceTokenizer(reader);
+}
+
+TokenStream* SimpleAnalyzer::tokenStream(const TCHAR* fieldName, Reader* reader) {
+ return _CLNEW LowerCaseTokenizer(reader);
+}
+
+bool LowerCaseFilter::next(Token* t){
+ if (!input->next(t))
+ return false;
+ stringCaseFold( t->_termText );
+ return true;
+}
+
+StopFilter::StopFilter(TokenStream* in, bool deleteTokenStream, const TCHAR** stopWords):
+ TokenFilter(in, deleteTokenStream),
+ table(_CLNEW CLSetList<const TCHAR*>(false))
+{
+ fillStopTable( table,stopWords );
+}
+
+void StopFilter::fillStopTable(CLSetList<const TCHAR*>* stopTable,
+ const TCHAR** stopWords) {
+ for (int32_t i = 0; stopWords[i]!=NULL; i++)
+ stopTable->insert(stopWords[i]);
+}
+
+bool StopFilter::next(Token* token) {
+ // return the first non-stop word found
+ while (input->next(token)){
+ if (table->find(token->_termText)==table->end()){
+ return true;
+ }
+ }
+
+ // reached EOS -- return nothing
+ return false;
+}
+
+StopAnalyzer::StopAnalyzer():stopTable(false)
+{
+ StopFilter::fillStopTable(&stopTable,ENGLISH_STOP_WORDS);
+}
+StopAnalyzer::~StopAnalyzer()
+{
+}
+StopAnalyzer::StopAnalyzer( const TCHAR** stopWords) {
+ StopFilter::fillStopTable(&stopTable,stopWords);
+}
+TokenStream* StopAnalyzer::tokenStream(const TCHAR* fieldName, Reader* reader) {
+ return _CLNEW StopFilter(_CLNEW LowerCaseTokenizer(reader),true, &stopTable);
+}
+
+const TCHAR* StopAnalyzer::ENGLISH_STOP_WORDS[] =
+{
+ _T("a"), _T("an"), _T("and"), _T("are"), _T("as"), _T("at"), _T("be"), _T("but"), _T("by"),
+ _T("for"), _T("if"), _T("in"), _T("into"), _T("is"), _T("it"),
+ _T("no"), _T("not"), _T("of"), _T("on"), _T("or"), _T("s"), _T("such"),
+ _T("t"), _T("that"), _T("the"), _T("their"), _T("then"), _T("there"), _T("these"),
+ _T("they"), _T("this"), _T("to"), _T("was"), _T("will"), _T("with"), NULL
+};
+
+PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(Analyzer* defaultAnalyzer):
+ analyzerMap(true,true)
+{
+ this->defaultAnalyzer = defaultAnalyzer;
+}
+PerFieldAnalyzerWrapper::~PerFieldAnalyzerWrapper(){
+ analyzerMap.clear();
+ _CLDELETE(defaultAnalyzer);
+}
+
+void PerFieldAnalyzerWrapper::addAnalyzer(const TCHAR* fieldName, Analyzer* analyzer) {
+ analyzerMap.put(STRDUP_TtoT(fieldName), analyzer);
+}
+
+TokenStream* PerFieldAnalyzerWrapper::tokenStream(const TCHAR* fieldName, Reader* reader) {
+ Analyzer* analyzer = (fieldName==NULL?defaultAnalyzer:analyzerMap.get(fieldName));
+ if (analyzer == NULL) {
+ analyzer = defaultAnalyzer;
+ }
+
+ return analyzer->tokenStream(fieldName, reader);
+}
+
+
+
+bool ISOLatin1AccentFilter::next(Token* token){
+ if ( input->next(token) ){
+ int32_t l = token->termTextLength();
+ const TCHAR* chars = token->termText();
+ bool doProcess = false;
+ for (int32_t i = 0; i < l; ++i) {
+#ifdef _UCS2
+ if ( chars[i] >= 0xC0 && chars[i] <= 0x178 ) {
+#else
+ if ( (chars[i] >= 0xC0 && chars[i] <= 0xFF) || chars[i] < 0 ) {
+#endif
+ doProcess = true;
+ break;
+ }
+ }
+ if ( !doProcess ) {
+ return true;
+ }
+
+ StringBuffer output(l*2);
+ for (int32_t j = 0; j < l; j++) {
+ #ifdef _UCS2
+ TCHAR c = chars[j];
+ #else
+ unsigned char c = chars[j];
+ #endif
+ switch (c) {
+ case 0xC0 :
+ case 0xC1 :
+ case 0xC2 :
+ case 0xC3 :
+ case 0xC4 :
+ case 0xC5 :
+ output.appendChar('A');
+ break;
+ case 0xC6 :
+ output.append(_T("AE"));
+ break;
+ case 0xC7 :
+ output.appendChar('C');
+ break;
+ case 0xC8 :
+ case 0xC9 :
+ case 0xCA :
+ case 0xCB :
+ output.appendChar('E');
+ break;
+ case 0xCC :
+ case 0xCD :
+ case 0xCE :
+ case 0xCF :
+ output.appendChar('I');
+ break;
+ case 0xD0 :
+ output.appendChar('D');
+ break;
+ case 0xD1 :
+ output.appendChar('N');
+ break;
+ case 0xD2 :
+ case 0xD3 :
+ case 0xD4 :
+ case 0xD5 :
+ case 0xD6 :
+ case 0xD8 :
+ output.appendChar('O');
+ break;
+ case 0xDE :
+ output.append(_T("TH"));
+ break;
+ case 0xD9 :
+ case 0xDA :
+ case 0xDB :
+ case 0xDC :
+ output.appendChar('U');
+ break;
+ case 0xDD :
+ output.appendChar('Y');
+ break;
+ case 0xE0 :
+ case 0xE1 :
+ case 0xE2 :
+ case 0xE3 :
+ case 0xE4 :
+ case 0xE5 :
+ output.appendChar('a');
+ break;
+ case 0xE6 :
+ output.append(_T("ae"));
+ break;
+ case 0xE7 :
+ output.appendChar('c');
+ break;
+ case 0xE8 :
+ case 0xE9 :
+ case 0xEA :
+ case 0xEB :
+ output.appendChar('e');
+ break;
+ case 0xEC :
+ case 0xED :
+ case 0xEE :
+ case 0xEF :
+ output.appendChar('i');
+ break;
+ case 0xF0 :
+ output.appendChar('d');
+ break;
+ case 0xF1 :
+ output.appendChar('n');
+ break;
+ case 0xF2 :
+ case 0xF3 :
+ case 0xF4 :
+ case 0xF5 :
+ case 0xF6 :
+ case 0xF8 :
+ output.appendChar('o');
+ break;
+ case 0xDF :
+ output.append(_T("ss"));
+ break;
+ case 0xFE :
+ output.append(_T("th"));
+ break;
+ case 0xF9 :
+ case 0xFA :
+ case 0xFB :
+ case 0xFC :
+ output.appendChar('u');
+ break;
+ case 0xFD :
+ case 0xFF :
+ output.appendChar('y');
+ break;
+
+ #ifdef _UCS2
+ case 0x152 :
+ output.append(_T("OE"));
+ break;
+ case 0x153 :
+ output.append(_T("oe"));
+ break;
+ case 0x178 :
+ output.appendChar('Y');
+ break;
+ #endif
+ default :
+ output.appendChar(c);
+ break;
+ }
+ }
+ token->setText(output.getBuffer());
+ return true;
+ }
+ return false;
+}
+
+
+TokenStream* KeywordAnalyzer::tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader){
+ return _CLNEW KeywordTokenizer(reader);
+}
+
+KeywordTokenizer::KeywordTokenizer(CL_NS(util)::Reader* input, int bufferSize):
+ Tokenizer(input)
+{
+ this->done = false;
+ if ( bufferSize < 0 )
+ this->bufferSize = DEFAULT_BUFFER_SIZE;
+}
+KeywordTokenizer::~KeywordTokenizer(){
+}
+
+bool KeywordTokenizer::next(Token* token){
+ if (!done) {
+ done = true;
+ int32_t rd;
+ const TCHAR* buffer=0;
+ while (true) {
+ rd = input->read(buffer, bufferSize);
+ if (rd == -1)
+ break;
+ token->growBuffer(token->_termTextLen +rd+1);
+
+ int32_t cp = rd;
+ if ( token->_termTextLen + cp > token->bufferLength() )
+ cp = token->bufferLength() - token->_termTextLen;
+ _tcsncpy(token->_termText+token->_termTextLen,buffer,cp);
+ token->_termTextLen+=rd;
+ }
+ token->_termText[token->_termTextLen]=0;
+ token->set(token->_termText,0,token->_termTextLen);
+ return true;
+ }
+ return false;
+}
+
+
+LengthFilter::LengthFilter(TokenStream* in, int _min, int _max):
+ TokenFilter(in)
+{
+ this->_min = _min;
+ this->_max = _max;
+}
+
+bool LengthFilter::next(Token* token)
+{
+ // return the first non-stop word found
+ while ( input->next(token) )
+ {
+ size_t len = token->termTextLength();
+ if (len >= _min && len <= _max)
+ return true;
+ // note: else we ignore it but should we index each part of it?
+ }
+ // reached EOS -- return null
+ return false;
+}
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/analysis/Analyzers.h b/3rdparty/clucene/src/CLucene/analysis/Analyzers.h
new file mode 100644
index 000000000..a12bd653f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/Analyzers.h
@@ -0,0 +1,309 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_analysis_Analyzers_
+#define _lucene_analysis_Analyzers_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/Reader.h"
+#include "AnalysisHeader.h"
+#include "CLucene/util/Misc.h"
+
+CL_NS_DEF(analysis)
+
+/** An abstract base class for simple, character-oriented tokenizers.*/
+class CharTokenizer:public Tokenizer {
+private:
+ int32_t offset, bufferIndex, dataLen;
+ TCHAR buffer[LUCENE_MAX_WORD_LEN+1];
+ const TCHAR* ioBuffer;
+protected:
+
+ /** Returns true iff a character should be included in a token. This
+ * tokenizer generates as tokens adjacent sequences of characters which
+ * satisfy this predicate. Characters for which this is false are used to
+ * define token boundaries and are not included in tokens. */
+ virtual bool isTokenChar(const TCHAR c) const = 0;
+
+ /** Called on each token character to normalize it before it is added to the
+ * token. The default implementation does nothing. Subclasses may use this
+ * to, e.g., lowercase tokens. */
+ virtual TCHAR normalize(const TCHAR c) const;
+
+public:
+ CharTokenizer(CL_NS(util)::Reader* in);
+ virtual ~CharTokenizer(){
+ }
+ bool next(Token* token);
+};
+
+
+/** A LetterTokenizer is a tokenizer that divides text at non-letters. That's
+to say, it defines tokens as maximal strings of adjacent letters, as defined
+by java.lang.Character.isLetter() predicate.
+
+Note: this does a decent job for most European languages, but does a terrible
+job for some Asian languages, where words are not separated by spaces. */
+class LetterTokenizer:public CharTokenizer {
+public:
+ // Construct a new LetterTokenizer.
+ LetterTokenizer(CL_NS(util)::Reader* in):
+ CharTokenizer(in) {}
+
+ ~LetterTokenizer(){}
+protected:
+ /** Collects only characters which satisfy _istalpha.*/
+ bool isTokenChar(const TCHAR c) const;
+};
+
+
+
+/**
+* LowerCaseTokenizer performs the function of LetterTokenizer
+* and LowerCaseFilter together. It divides text at non-letters and converts
+* them to lower case. While it is functionally equivalent to the combination
+* of LetterTokenizer and LowerCaseFilter, there is a performance advantage
+* to doing the two tasks at once, hence this (redundant) implementation.
+* <P>
+* Note: this does a decent job for most European languages, but does a terrible
+* job for some Asian languages, where words are not separated by spaces.
+*/
+class LowerCaseTokenizer:public LetterTokenizer {
+public:
+ /** Construct a new LowerCaseTokenizer. */
+ LowerCaseTokenizer(CL_NS(util)::Reader* in):
+ LetterTokenizer(in) {}
+
+ ~LowerCaseTokenizer(){}
+protected:
+ /** Collects only characters which satisfy _totlower. */
+ TCHAR normalize(const TCHAR chr) const;
+};
+
+
+/** A WhitespaceTokenizer is a tokenizer that divides text at whitespace.
+ * Adjacent sequences of non-Whitespace characters form tokens. */
+class WhitespaceTokenizer: public CharTokenizer {
+public:
+ /** Construct a new WhitespaceTokenizer. */
+ WhitespaceTokenizer(CL_NS(util)::Reader* in):CharTokenizer(in) {}
+ ~WhitespaceTokenizer(){}
+protected:
+ /** Collects only characters which do not satisfy _istspace.
+ */
+ bool isTokenChar(const TCHAR c) const;
+};
+
+
+/** An Analyzer that uses WhitespaceTokenizer. */
+class WhitespaceAnalyzer: public Analyzer {
+ public:
+ TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader);
+ ~WhitespaceAnalyzer(){}
+};
+
+/** An Analyzer that filters LetterTokenizer with LowerCaseFilter. */
+class SimpleAnalyzer: public Analyzer {
+public:
+ TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader);
+ ~SimpleAnalyzer(){}
+};
+
+
+
+/**
+* Normalizes token text to lower case.
+*/
+class LowerCaseFilter: public TokenFilter {
+public:
+ LowerCaseFilter(TokenStream* in, bool deleteTokenStream):TokenFilter(in,deleteTokenStream) {}
+ ~LowerCaseFilter(){}
+ bool next(Token* token);
+};
+
+
+/**
+ * Removes stop words from a token stream.
+ */
+class StopFilter: public TokenFilter {
+private:
+ //bvk: i found this to work faster with a non-hash table. the number of items
+ //in the stop table is not like to make it worth having hashing.
+ CL_NS(util)::CLSetList<const TCHAR*>* table;
+public:
+ // Constructs a filter which removes words from the input
+ // TokenStream that are named in the array of words.
+ StopFilter(TokenStream* in, bool deleteTokenStream, const TCHAR** stopWords);
+
+ ~StopFilter(){}
+
+ /** Constructs a filter which removes words from the input
+ * TokenStream that are named in the CLSetList.
+ */
+ StopFilter(TokenStream* in, bool deleteTokenStream, CL_NS(util)::CLSetList<const TCHAR*>* stopTable):
+ TokenFilter(in, deleteTokenStream),
+ table(stopTable)
+ {}
+
+
+ /**
+ * Builds a Hashtable from an array of stop words, appropriate for passing
+ * into the StopFilter constructor. This permits this table construction to
+ * be cached once when an Analyzer is constructed.
+ * Note: the stopWords list must be a static list because the strings are not copied
+ */
+ static void fillStopTable(CL_NS(util)::CLSetList<const TCHAR*>* stopTable,
+ const TCHAR** stopWords);
+
+ /**
+ * Returns the next input Token whose termText() is not a stop word.
+ */
+ bool next(Token* token);
+};
+
+
+
+
+/** Filters LetterTokenizer with LowerCaseFilter and StopFilter. */
+class StopAnalyzer: public Analyzer {
+ CL_NS(util)::CLSetList<const TCHAR*> stopTable;
+
+public:
+ /** Builds an analyzer which removes words in ENGLISH_STOP_WORDS. */
+ StopAnalyzer();
+ ~StopAnalyzer();
+
+ /** Builds an analyzer which removes words in the provided array. */
+ StopAnalyzer( const TCHAR** stopWords );
+ /** Filters LowerCaseTokenizer with StopFilter. */
+ TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader);
+
+ /** An array containing some common English words that are not usually useful
+ for searching. */
+ static const TCHAR* ENGLISH_STOP_WORDS[];
+};
+
+
+
+/**
+ * This analyzer is used to facilitate scenarios where different
+ * fields require different analysis techniques. Use {@link #addAnalyzer}
+ * to add a non-default analyzer on a field name basis.
+ *
+ * <p>Example usage:
+ *
+ * <pre>
+ * PerFieldAnalyzerWrapper aWrapper =
+ * new PerFieldAnalyzerWrapper(new StandardAnalyzer());
+ * aWrapper.addAnalyzer("firstname", new KeywordAnalyzer());
+ * aWrapper.addAnalyzer("lastname", new KeywordAnalyzer());
+ * </pre>
+ *
+ * <p>In this example, StandardAnalyzer will be used for all fields except "firstname"
+ * and "lastname", for which KeywordAnalyzer will be used.
+ *
+ * <p>A PerFieldAnalyzerWrapper can be used like any other analyzer, for both indexing
+ * and query parsing.
+ */
+class PerFieldAnalyzerWrapper : public Analyzer {
+private:
+ Analyzer* defaultAnalyzer;
+ CL_NS(util)::CLHashMap<const TCHAR*, Analyzer*, CL_NS(util)::Compare::TChar,
+ CL_NS(util)::Equals::TChar, CL_NS(util)::Deletor::tcArray,CL_NS(util)::Deletor::Void<Analyzer> > analyzerMap;
+public:
+ /**
+ * Constructs with default analyzer.
+ *
+ * @param defaultAnalyzer Any fields not specifically
+ * defined to use a different analyzer will use the one provided here.
+ */
+ PerFieldAnalyzerWrapper(Analyzer* defaultAnalyzer);
+ ~PerFieldAnalyzerWrapper();
+
+ /**
+ * Defines an analyzer to use for the specified field.
+ *
+ * @param fieldName field name requiring a non-default analyzer
+ * @param analyzer non-default analyzer to use for field
+ */
+ void addAnalyzer(const TCHAR* fieldName, Analyzer* analyzer);
+ TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader);
+};
+
+
+/**
+ * A filter that replaces accented characters in the ISO Latin 1 character set
+ * (ISO-8859-1) by their unaccented equivalent. The case will not be altered.
+ * <p>
+ * For instance, '&agrave;' will be replaced by 'a'.
+ * <p>
+ */
+class ISOLatin1AccentFilter: public TokenFilter {
+public:
+ ISOLatin1AccentFilter(TokenStream* input, bool deleteTs):
+ TokenFilter(input,deleteTs)
+ {
+ }
+
+ /**
+ * To replace accented characters in a String by unaccented equivalents.
+ */
+ bool next(Token* token);
+};
+
+
+/**
+ * Emits the entire input as a single token.
+ */
+class KeywordTokenizer: public Tokenizer {
+private:
+ LUCENE_STATIC_CONSTANT(int, DEFAULT_BUFFER_SIZE = 256);
+ bool done;
+ int bufferSize;
+public:
+ KeywordTokenizer(CL_NS(util)::Reader* input, int bufferSize=-1);
+ virtual ~KeywordTokenizer();
+ bool next(Token* token);
+};
+
+/**
+ * "Tokenizes" the entire stream as a single token. This is useful
+ * for data like zip codes, ids, and some product names.
+ */
+class KeywordAnalyzer: public Analyzer {
+public:
+ TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader);
+ virtual ~KeywordAnalyzer(){}
+};
+
+
+/**
+ * Removes words that are too long and too short from the stream.
+ *
+ */
+class LengthFilter: public TokenFilter {
+private:
+ int _min;
+ int _max;
+public:
+ /**
+ * Build a filter that removes words that are too long or too
+ * short from the text.
+ */
+ LengthFilter(TokenStream* in, int _min, int _max);
+
+ /**
+ * Returns the next input Token whose termText() is the right len
+ */
+ bool next(Token* token);
+};
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/analysis/standard/StandardAnalyzer.cpp b/3rdparty/clucene/src/CLucene/analysis/standard/StandardAnalyzer.cpp
new file mode 100644
index 000000000..e0994c41a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/standard/StandardAnalyzer.cpp
@@ -0,0 +1,46 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "StandardAnalyzer.h"
+
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/Reader.h"
+#include "CLucene/analysis/AnalysisHeader.h"
+#include "CLucene/analysis/Analyzers.h"
+#include "StandardFilter.h"
+#include "StandardTokenizer.h"
+
+CL_NS_USE(util)
+CL_NS_USE(analysis)
+
+CL_NS_DEF2(analysis,standard)
+
+ StandardAnalyzer::StandardAnalyzer():
+ stopSet(false)
+ {
+ StopFilter::fillStopTable( &stopSet,CL_NS(analysis)::StopAnalyzer::ENGLISH_STOP_WORDS);
+ }
+
+ StandardAnalyzer::StandardAnalyzer( const TCHAR** stopWords):
+ stopSet(false)
+ {
+ StopFilter::fillStopTable( &stopSet,stopWords );
+ }
+
+ StandardAnalyzer::~StandardAnalyzer(){
+ }
+
+
+ TokenStream* StandardAnalyzer::tokenStream(const TCHAR* fieldName, Reader* reader)
+ {
+ TokenStream* ret = _CLNEW StandardTokenizer(reader);
+ ret = _CLNEW StandardFilter(ret,true);
+ ret = _CLNEW LowerCaseFilter(ret,true);
+ ret = _CLNEW StopFilter(ret,true, &stopSet);
+ return ret;
+ }
+CL_NS_END2
diff --git a/3rdparty/clucene/src/CLucene/analysis/standard/StandardAnalyzer.h b/3rdparty/clucene/src/CLucene/analysis/standard/StandardAnalyzer.h
new file mode 100644
index 000000000..9cce041df
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/standard/StandardAnalyzer.h
@@ -0,0 +1,47 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_analysis_standard_StandardAnalyzer
+#define _lucene_analysis_standard_StandardAnalyzer
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/Reader.h"
+#include "CLucene/analysis/AnalysisHeader.h"
+#include "CLucene/analysis/Analyzers.h"
+#include "StandardFilter.h"
+#include "StandardTokenizer.h"
+
+
+CL_NS_DEF2(analysis,standard)
+
+ /** Represents a standard analyzer. */
+ class StandardAnalyzer : public Analyzer
+ {
+ private:
+ CL_NS(util)::CLSetList<const TCHAR*> stopSet;
+ public:
+ /** Builds an analyzer.*/
+ StandardAnalyzer();
+
+ /** Builds an analyzer with the given stop words. */
+ StandardAnalyzer( const TCHAR** stopWords);
+
+ ~StandardAnalyzer();
+
+
+ /**
+ * Constructs a StandardTokenizer filtered by a
+ * StandardFilter, a LowerCaseFilter and a StopFilter.
+ */
+ TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader)
+ ;
+ };
+CL_NS_END2
+#endif
diff --git a/3rdparty/clucene/src/CLucene/analysis/standard/StandardFilter.cpp b/3rdparty/clucene/src/CLucene/analysis/standard/StandardFilter.cpp
new file mode 100644
index 000000000..9869d2592
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/standard/StandardFilter.cpp
@@ -0,0 +1,58 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "StandardFilter.h"
+
+#include "../AnalysisHeader.h"
+#include "../Analyzers.h"
+#include "StandardTokenizerConstants.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_USE(analysis)
+CL_NS_USE(util)
+CL_NS_DEF2(analysis,standard)
+
+ StandardFilter::StandardFilter(TokenStream* in, bool deleteTokenStream):
+ TokenFilter(in, deleteTokenStream)
+ {
+ }
+
+ StandardFilter::~StandardFilter(){
+ }
+
+ bool StandardFilter::next(Token* t) {
+ if (!input->next(t))
+ return false;
+
+ TCHAR* text = t->_termText;
+ const int32_t textLength = t->termTextLength();
+ const TCHAR* type = t->type();
+
+ if ( type == tokenImage[APOSTROPHE] && //we can compare the type directy since the type should always come from the tokenImage
+ ( textLength >= 2 && _tcsicmp(text+textLength-2, _T("'s"))==0 ) )
+ {
+ // remove 's
+ text[textLength-2]=0;
+ t->resetTermTextLen();
+
+ return true;
+
+ } else if ( type == tokenImage[ACRONYM] ) { // remove dots
+ int32_t j = 0;
+ for ( int32_t i=0;i<textLength;i++ ){
+ if ( text[i] != '.' )
+ text[j++]=text[i];
+ }
+ text[j]=0;
+ return true;
+
+ } else {
+ return true;
+ }
+ }
+
+CL_NS_END2
diff --git a/3rdparty/clucene/src/CLucene/analysis/standard/StandardFilter.h b/3rdparty/clucene/src/CLucene/analysis/standard/StandardFilter.h
new file mode 100644
index 000000000..59657fdb3
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/standard/StandardFilter.h
@@ -0,0 +1,37 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_analysis_standard_StandardFilter
+#define _lucene_analysis_standard_StandardFilter
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "../AnalysisHeader.h"
+#include "../Analyzers.h"
+#include "StandardTokenizerConstants.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_DEF2(analysis,standard)
+
+ /** Normalizes tokens extracted with {@link StandardTokenizer}. */
+ class StandardFilter: public TokenFilter{
+ public:
+ // Construct filtering <i>in</i>.
+ StandardFilter(TokenStream* in, bool deleteTokenStream);
+
+ ~StandardFilter();
+
+
+ /** Returns the next token in the stream, or NULL at EOS.
+ * <p>Removes <tt>'s</tt> from the end of words.
+ * <p>Removes dots from acronyms.
+ */
+ bool next(Token* token);
+ };
+CL_NS_END2
+#endif
diff --git a/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizer.cpp b/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizer.cpp
new file mode 100644
index 000000000..60f9a449c
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizer.cpp
@@ -0,0 +1,446 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "StandardTokenizer.h"
+
+CL_NS_USE(analysis)
+CL_NS_USE(util)
+CL_NS_DEF2(analysis,standard)
+
+ const static TCHAR* tokenImageArray[] = {
+ _T("<EOF>"),
+ _T("<UNKNOWN>"),
+ _T("<ALPHANUM>"),
+ _T("<APOSTROPHE>"),
+ _T("<ACRONYM>"),
+ _T("<COMPANY>"),
+ _T("<EMAIL>"),
+ _T("<HOST>"),
+ _T("<NUM>"),
+ _T("<CJK>")
+ };
+ const TCHAR** tokenImage = tokenImageArray;
+
+ /* A bunch of shortcut macros, many of which make assumptions about variable
+ ** names. These macros enhance readability, not just convenience! */
+ #define EOS (ch==-1 || rd->Eos())
+ #define SPACE (_istspace((TCHAR)ch) != 0)
+ #define ALPHA (_istalpha((TCHAR)ch) != 0)
+ #define ALNUM (_istalnum(ch) != 0)
+ #define DIGIT (_istdigit(ch) != 0)
+ #define UNDERSCORE (ch == '_')
+
+ #define _CJK ( (ch>=0x3040 && ch<=0x318f) || \
+ (ch>=0x3300 && ch<=0x337f) || \
+ (ch>=0x3400 && ch<=0x3d2d) || \
+ (ch>=0x4e00 && ch<=0x9fff) || \
+ (ch>=0xf900 && ch<=0xfaff) || \
+ (ch>=0xac00 && ch<=0xd7af) ) //korean
+
+
+ #define DASH (ch == '-')
+ #define NEGATIVE_SIGN_ DASH
+ //#define POSITIVE_SIGN_ (ch == '+')
+ //#define SIGN (NEGATIVE_SIGN_ || POSITIVE_SIGN_)
+
+ #define DOT (ch == '.')
+ #define DECIMAL DOT
+
+
+ //freebsd seems to have a problem with defines over multiple lines, so this has to be one long line
+ #define _CONSUME_AS_LONG_AS(conditionFails) while (true) { ch = readChar(); if (ch==-1 || (!(conditionFails) || str.len >= LUCENE_MAX_WORD_LEN)) { break; } str.appendChar(ch);}
+
+ #define CONSUME_ALPHAS _CONSUME_AS_LONG_AS(ALPHA)
+
+ #define CONSUME_DIGITS _CONSUME_AS_LONG_AS(DIGIT)
+
+ /* otherMatches is a condition (possibly compound) under which a character
+ ** that's not an ALNUM or UNDERSCORE can be considered not to break the
+ ** span. Callers should pass false if only ALNUM/UNDERSCORE are acceptable. */
+ #define CONSUME_WORD _CONSUME_AS_LONG_AS(ALNUM || UNDERSCORE)
+
+ /*
+ ** Consume CJK characters
+ */
+ #define CONSUME_CJK _CONSUME_AS_LONG_AS(_CJK)
+
+
+ /* It is considered that "nothing of value" has been read if:
+ ** a) The "read head" hasn't moved since specialCharPos was established.
+ ** or
+ ** b) The "read head" has moved by one character, but that character was
+ ** either whitespace or not among the characters found in the body of
+ ** a token (deliberately doesn't include the likes of '@'/'&'). */
+ #define CONSUMED_NOTHING_OF_VALUE (rdPos == specialCharPos || (rdPos == specialCharPos+1 && ( SPACE || !(ALNUM || DOT || DASH || UNDERSCORE) )))
+
+ #define RIGHTMOST(sb) (sb.getBuffer()[sb.len-1])
+ #define RIGHTMOST_IS(sb, c) (RIGHTMOST(sb) == c)
+ /* To discard the last character in a StringBuffer, we decrement the buffer's
+ ** length indicator and move the terminator back by one character. */
+ #define SHAVE_RIGHTMOST(sb) (sb.getBuffer()[--sb.len] = '\0')
+
+ //#define REMOVE_TRAILING_CHARS(sb, charMatchesCondition) { TCHAR* sbBuf = sb.getBuffer(); for (int32_t i = sb.len-1; i >= 0; i--) { TCHAR c = sbBuf[i]; if (charMatchesCondition) { sbBuf[--sb.len] = '\0'; } else {break;}}}
+
+ /* Does StringBuffer sb contain any of the characters in string ofThese? */
+ #define CONTAINS_ANY(sb, ofThese) (_tcscspn(sb.getBuffer(), _T(ofThese)) != static_cast<size_t>(sb.len))
+
+
+ StandardTokenizer::StandardTokenizer(Reader* reader):
+ rd(_CLNEW FastCharStream(reader)),
+ /* rdPos is zero-based. It starts at -1, and will advance to the first
+ ** position when readChar() is first called. */
+ rdPos(-1),
+ tokenStart(-1)
+ {
+ }
+
+ StandardTokenizer::~StandardTokenizer() {
+ _CLDELETE(rd);
+ }
+
+ int StandardTokenizer::readChar() {
+ /* Increment by 1 because we're speaking in terms of characters, not
+ ** necessarily bytes: */
+ rdPos++;
+ return rd->GetNext();
+ }
+
+ void StandardTokenizer::unReadChar() {
+ rd->UnGet();
+ rdPos--;
+ }
+
+ inline bool StandardTokenizer::setToken(Token* t, StringBuffer* sb, TokenTypes tokenCode) {
+ t->setStartOffset(tokenStart);
+ t->setEndOffset(tokenStart+sb->length());
+ t->setType(tokenImage[tokenCode]);
+ sb->getBuffer(); //null terminates the buffer
+ t->resetTermTextLen();
+ return true;
+ }
+
+ bool StandardTokenizer::next(Token* t) {
+ int ch=0;
+ while (!EOS) {
+ ch = readChar();
+
+ if ( ch == 0 || ch == -1 ){
+ continue;
+ } else if (SPACE) {
+ continue;
+ } else if (ALPHA || UNDERSCORE) {
+ tokenStart = rdPos;
+ return ReadAlphaNum(ch,t);
+ } else if (DIGIT || NEGATIVE_SIGN_ || DECIMAL) {
+ tokenStart = rdPos;
+ /* ReadNumber returns NULL if it fails to extract a valid number; in
+ ** that case, we just continue. */
+ if (ReadNumber(NULL, ch,t))
+ return true;
+ } else if ( _CJK ){
+ if ( ReadCJK(ch,t) )
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool StandardTokenizer::ReadNumber(const TCHAR* previousNumber, const TCHAR prev,Token* t) {
+ /* previousNumber is only non-NULL if this function already read a complete
+ ** number in a previous recursion, yet has been asked to read additional
+ ** numeric segments. For example, in the HOST "192.168.1.3", "192.168" is
+ ** a complete number, but this function will recurse to read the "1.3",
+ ** generating a single HOST token "192.168.1.3". */
+ t->growBuffer(LUCENE_MAX_WORD_LEN+1);//make sure token can hold the next word
+ StringBuffer str(t->_termText,t->bufferLength(),true); //use stringbuffer to read data onto the termText
+ TokenTypes tokenType;
+ bool decExhausted;
+ if (previousNumber != NULL) {
+ str.prepend(previousNumber);
+ tokenType = CL_NS2(analysis,standard)::HOST;
+ decExhausted = false;
+ } else {
+ tokenType = CL_NS2(analysis,standard)::NUM;
+ decExhausted = (prev == '.');
+ }
+ if ( str.len >= LUCENE_MAX_WORD_LEN ){
+ //if a number is too long, i would say there is no point
+ //storing it, because its going to be the wrong number anyway?
+ //what do people think?
+ return false;
+ }
+ str.appendChar(prev);
+
+ const bool signExhausted = (prev == '-');
+ int ch = prev;
+
+ CONSUME_DIGITS;
+
+ if (str.len < 2 /* CONSUME_DIGITS didn't find any digits. */
+ && (
+ (signExhausted && !DECIMAL)
+ || (decExhausted /* && !DIGIT is implied, since CONSUME_DIGITS stopped on a non-digit. */)
+ )
+ )
+ {
+ /* We have either:
+ ** a) a negative sign that's not followed by either digit(s) or a decimal
+ ** b) a decimal that's not followed by digit(s)
+ ** so this is not a valid number. */
+ if (!EOS) {
+ /* Unread the character that stopped CONSUME_DIGITS: */
+ unReadChar();
+ }
+ return false;
+ }
+
+ /* We just read a group of digits. Is it followed by a decimal symbol,
+ ** implying that there might be another group of digits available? */
+ if (!EOS) {
+ if (DECIMAL) {
+ if ( str.len >= LUCENE_MAX_WORD_LEN )
+ return false; //read above for rationale
+ str.appendChar(ch);
+ } else {
+ unReadChar();
+ goto SUCCESSFULLY_EXTRACTED_NUMBER;
+ }
+
+ CONSUME_DIGITS;
+ if (!DIGIT && !DECIMAL) {
+ unReadChar();
+ } else if (!EOS && DECIMAL && _istdigit(rd->Peek())) {
+ /* We just read the fractional digit group, but it's also followed by
+ ** a decimal symbol and at least one more digit, so this must be a
+ ** HOST rather than a real number. */
+ return ReadNumber(str.getBuffer(), '.',t);
+ }
+ }
+
+ SUCCESSFULLY_EXTRACTED_NUMBER:
+ TCHAR rightmost = RIGHTMOST(str);
+ /* Don't including a trailing decimal point. */
+ if (rightmost == '.') {
+ SHAVE_RIGHTMOST(str);
+ unReadChar();
+ rightmost = RIGHTMOST(str);
+ }
+ /* If all we have left is a negative sign, it's not a valid number. */
+ if (rightmost == '-') {
+ CND_PRECONDITION (str.len == 1, "Number is invalid");
+ return false;
+ }
+
+ return setToken(t,&str,tokenType);
+ }
+
+ bool StandardTokenizer::ReadAlphaNum(const TCHAR prev, Token* t) {
+ t->growBuffer(LUCENE_MAX_WORD_LEN+1);//make sure token can hold the next word
+ StringBuffer str(t->_termText,t->bufferLength(),true); //use stringbuffer to read data onto the termText
+ if ( str.len < LUCENE_MAX_WORD_LEN ){
+ str.appendChar(prev);
+ int ch = prev;
+
+ CONSUME_WORD;
+ if (!EOS && str.len < LUCENE_MAX_WORD_LEN-1 ) { //still have space for 1 more character?
+ switch(ch) { /* What follows the first alphanum segment? */
+ case '.':
+ str.appendChar('.');
+ return ReadDotted(&str, CL_NS2(analysis,standard)::UNKNOWN,t);
+ case '\'':
+ str.appendChar('\'');
+ return ReadApostrophe(&str,t);
+ case '@':
+ str.appendChar('@');
+ return ReadAt(&str,t);
+ case '&':
+ str.appendChar('&');
+ return ReadCompany(&str,t);
+ /* default: fall through to end of this function. */
+ }
+ }
+ }
+ return setToken(t,&str,CL_NS2(analysis,standard)::ALPHANUM);
+ }
+
+ bool StandardTokenizer::ReadCJK(const TCHAR prev, Token* t) {
+ t->growBuffer(LUCENE_MAX_WORD_LEN+1);//make sure token can hold the next word
+ StringBuffer str(t->_termText,t->bufferLength(),true); //use stringbuffer to read data onto the termText
+ if ( str.len < LUCENE_MAX_WORD_LEN ){
+ str.appendChar(prev);
+ int ch = prev;
+
+ CONSUME_CJK;
+ }
+ return setToken(t,&str,CL_NS2(analysis,standard)::CJK);
+ }
+
+
+ bool StandardTokenizer::ReadDotted(StringBuffer* _str, TokenTypes forcedType, Token* t) {
+ const int32_t specialCharPos = rdPos;
+ StringBuffer& str=*_str;
+
+ /* A segment of a "dotted" is not allowed to begin with another dot or a dash.
+ ** Even though hosts, e-mail addresses, etc., could have a dotted-segment
+ ** that begins with a dot or a dash, it's far more common in source text
+ ** for a pattern like "abc.--def" to be intended as two tokens. */
+ int ch = rd->Peek();
+ if (!(DOT || DASH)) {
+ bool prevWasDot;
+ bool prevWasDash;
+ if (str.len == 0) {
+ prevWasDot = false;
+ prevWasDash = false;
+ } else {
+ prevWasDot = RIGHTMOST(str) == '.';
+ prevWasDash = RIGHTMOST(str) == '-';
+ }
+ while (!EOS && str.len < LUCENE_MAX_WORD_LEN-1 ) {
+ ch = readChar();
+ const bool dot = ch == '.';
+ const bool dash = ch == '-';
+
+ if (!(ALNUM || UNDERSCORE || dot || dash)) {
+ break;
+ }
+ /* Multiple dots or dashes in succession end the token.
+ ** Consider the following inputs:
+ ** "Visit windowsupdate.microsoft.com--update today!"
+ ** "In the U.S.A.--yes, even there!" */
+ if ((dot || dash) && (prevWasDot || prevWasDash)) {
+ /* We're not going to append the character we just read, in any case.
+ ** As to the character before it (which is currently RIGHTMOST(str)):
+ ** Unless RIGHTMOST(str) is a dot, in which we need to save it so the
+ ** acronym-versus-host detection can work, we want to get rid of it. */
+ if (!prevWasDot) {
+ SHAVE_RIGHTMOST(str);
+ }
+ break;
+ }
+
+ str.appendChar(ch);
+
+ prevWasDot = dot;
+ prevWasDash = dash;
+ }
+ }
+
+ /* There's a potential StringBuffer.append call in the code above, which
+ ** could cause str to reallocate its internal buffer. We must wait to
+ ** obtain the optimization-oriented strBuf pointer until after the initial
+ ** potentially realloc-triggering operations on str.
+ ** Because there can be other such ops much later in this function, strBuf
+ ** is guarded within a block to prevent its use during or after the calls
+ ** that would potentially invalidate it. */
+ { /* Begin block-guard of strBuf */
+ TCHAR* strBuf = str.getBuffer();
+
+ bool rightmostIsDot = RIGHTMOST_IS(str, '.');
+ if (CONSUMED_NOTHING_OF_VALUE) {
+ /* No more alphanums available for this token; shave trailing dot, if any. */
+ if (rightmostIsDot) {
+ SHAVE_RIGHTMOST(str);
+ }
+ /* If there are no dots remaining, this is a generic ALPHANUM. */
+ if (_tcschr(strBuf, '.') == NULL) {
+ forcedType = CL_NS2(analysis,standard)::ALPHANUM;
+ }
+
+ /* Check the token to see if it's an acronym. An acronym must have a
+ ** letter in every even slot and a dot in every odd slot, including the
+ ** last slot (for example, "U.S.A."). */
+ } else if (rightmostIsDot) {
+ bool isAcronym = true;
+ const int32_t upperCheckLimit = str.len - 1; /* -1 b/c we already checked the last slot. */
+
+ for (int32_t i = 0; i < upperCheckLimit; i++) {
+ const bool even = (i % 2 == 0);
+ ch = strBuf[i];
+ if ( (even && !ALPHA) || (!even && !DOT) ) {
+ isAcronym = false;
+ break;
+ }
+ }
+ if (isAcronym) {
+ forcedType = CL_NS2(analysis,standard)::ACRONYM;
+ } else {
+ /* If it's not an acronym, we don't want the trailing dot. */
+ SHAVE_RIGHTMOST(str);
+ /* If there are no dots remaining, this is a generic ALPHANUM. */
+ if (_tcschr(strBuf, '.') == NULL) {
+ forcedType = CL_NS2(analysis,standard)::ALPHANUM;
+ }
+ }
+ }
+ } /* End block-guard of strBuf */
+
+ if (!EOS) {
+ if (ch == '@' && str.len < LUCENE_MAX_WORD_LEN-1) {
+ str.appendChar('@');
+ return ReadAt(&str,t);
+ } else {
+ unReadChar();
+ }
+ }
+
+ return setToken(t,&str,CL_NS2(analysis,standard)::UNKNOWN
+ ? forcedType : CL_NS2(analysis,standard)::HOST);
+ }
+
+ bool StandardTokenizer::ReadApostrophe(StringBuffer* _str, Token* t) {
+ StringBuffer& str=*_str;
+
+ TokenTypes tokenType = CL_NS2(analysis,standard)::APOSTROPHE;
+ const int32_t specialCharPos = rdPos;
+ int ch=0;
+
+ CONSUME_ALPHAS;
+ if (RIGHTMOST_IS(str, '\'') || CONSUMED_NOTHING_OF_VALUE) {
+ /* After the apostrophe, no more alphanums were available within this
+ ** token; shave trailing apostrophe and revert to generic ALPHANUM. */
+ SHAVE_RIGHTMOST(str);
+ tokenType = CL_NS2(analysis,standard)::ALPHANUM;
+ }
+ if (!EOS) {
+ unReadChar();
+ }
+
+ return setToken(t,&str,tokenType);
+ }
+
+ bool StandardTokenizer::ReadAt(StringBuffer* str, Token* t) {
+ ReadDotted(str, CL_NS2(analysis,standard)::EMAIL,t);
+ /* JLucene grammar indicates dots/digits not allowed in company name: */
+ if (!CONTAINS_ANY((*str), ".0123456789")) {
+ setToken(t,str,CL_NS2(analysis,standard)::COMPANY);
+ }
+ return true;
+ }
+
+ bool StandardTokenizer::ReadCompany(StringBuffer* _str, Token* t) {
+ StringBuffer& str = *_str;
+ const int32_t specialCharPos = rdPos;
+ int ch=0;
+
+ CONSUME_WORD;
+ if (CONSUMED_NOTHING_OF_VALUE) {
+ /* After the ampersand, no more alphanums were available within this
+ ** token; shave trailing ampersand and revert to ALPHANUM. */
+ CND_PRECONDITION(RIGHTMOST_IS(str, '&'),"ReadCompany failed");
+ SHAVE_RIGHTMOST(str);
+
+
+ return setToken(t,&str,CL_NS2(analysis,standard)::ALPHANUM);
+ }
+ if (!EOS) {
+ unReadChar();
+ }
+
+ return setToken(t,&str,CL_NS2(analysis,standard)::COMPANY);
+ }
+
+CL_NS_END2
diff --git a/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizer.h b/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizer.h
new file mode 100644
index 000000000..d4195be81
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizer.h
@@ -0,0 +1,88 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_analysis_standard_StandardTokenizer
+#define _lucene_analysis_standard_StandardTokenizer
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "../AnalysisHeader.h"
+#include "../Analyzers.h"
+#include "StandardTokenizerConstants.h"
+#include "CLucene/util/StringBuffer.h"
+#include "CLucene/util/FastCharStream.h"
+#include "CLucene/util/Reader.h"
+
+
+CL_NS_DEF2(analysis,standard)
+
+/** A grammar-based tokenizer constructed with JavaCC.
+ *
+ * <p> This should be a good tokenizer for most European-language documents:
+ *
+ * <ul>
+ * <li>Splits words at punctuation characters, removing punctuation. However, a
+ * dot that's not followed by whitespace is considered part of a token.
+ * <li>Splits words at hyphens, unless there's a number in the token, in which case
+ * the whole token is interpreted as a product number and is not split.
+ * <li>Recognizes email addresses and internet hostnames as one token.
+ * </ul>
+ *
+ * <p>Many applications have specific tokenizer needs. If this tokenizer does
+ * not suit your application, please consider copying this source code
+ * directory to your project and maintaining your own grammar-based tokenizer.
+ */
+ class StandardTokenizer: public Tokenizer {
+ private:
+ int32_t rdPos;
+ int32_t tokenStart;
+
+ // Advance by one character, incrementing rdPos and returning the character.
+ int readChar();
+ // Retreat by one character, decrementing rdPos.
+ void unReadChar();
+
+ // createToken centralizes token creation for auditing purposes.
+ //Token* createToken(CL_NS(util)::StringBuffer* sb, TokenTypes tokenCode);
+ inline bool setToken(Token* t, CL_NS(util)::StringBuffer* sb, TokenTypes tokenCode);
+
+ bool ReadDotted(CL_NS(util)::StringBuffer* str, TokenTypes forcedType,Token* t);
+
+ public:
+ CL_NS(util)::FastCharStream* rd;
+
+ // Constructs a tokenizer for this Reader.
+ StandardTokenizer(CL_NS(util)::Reader* reader);
+
+ ~StandardTokenizer();
+
+ /** Returns the next token in the stream, or false at end-of-stream.
+ * The returned token's type is set to an element of
+ * StandardTokenizerConstants::tokenImage. */
+ bool next(Token* token);
+
+ // Reads for number like "1"/"1234.567", or IP address like "192.168.1.2".
+ bool ReadNumber(const TCHAR* previousNumber, const TCHAR prev, Token* t);
+
+ bool ReadAlphaNum(const TCHAR prev, Token* t);
+
+ // Reads for apostrophe-containing word.
+ bool ReadApostrophe(CL_NS(util)::StringBuffer* str, Token* t);
+
+ // Reads for something@... it may be a COMPANY name or a EMAIL address
+ bool ReadAt(CL_NS(util)::StringBuffer* str, Token* t);
+
+ // Reads for COMPANY name like AT&T.
+ bool ReadCompany(CL_NS(util)::StringBuffer* str, Token* t);
+
+ // Reads CJK characters
+ bool ReadCJK(const TCHAR prev, Token* t);
+ };
+
+CL_NS_END2
+#endif
diff --git a/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizerConstants.h b/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizerConstants.h
new file mode 100644
index 000000000..3c95af45a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/analysis/standard/StandardTokenizerConstants.h
@@ -0,0 +1,30 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_analysis_standard_StandardTokenizerConstants
+#define _lucene_analysis_standard_StandardTokenizerConstants
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF2(analysis,standard)
+ enum TokenTypes {
+ _EOF,
+ UNKNOWN,
+ ALPHANUM,
+ APOSTROPHE,
+ ACRONYM,
+ COMPANY,
+ EMAIL,
+ HOST,
+ NUM,
+ CJK
+ };
+ extern const TCHAR** tokenImage;
+
+ CL_NS_END2
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/CompilerAcc.h b/3rdparty/clucene/src/CLucene/config/CompilerAcc.h
new file mode 100644
index 000000000..6ecd142be
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/CompilerAcc.h
@@ -0,0 +1,166 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#if !defined(_lucene_COMPILER_ACC)
+#define _lucene_COMPILER_ACC
+
+// It is internal CLucene header - DO NOT include it directly
+#if !defined(_SUPPRESS_MAKE_BASED_CONFIG)
+#if defined(_BUILD_FOR_QT_)
+#include "fulltextsearch/qclucene-config_p.h"
+#else
+#include "CLucene/clucene-config.h" //make clucene-config.h file
+#endif
+#endif
+
+#if defined(_ASCII)
+#undef _UCS2
+#elif defined(_UCS2)
+//
+#else
+#define CL_CHARSET_GUESS
+#endif
+
+//dont allow FS_MMAP if mmap is not available
+#if defined(LUCENE_FS_MMAP) && !defined(_CL_HAVE_MMAP)
+#error "LUCENE_FS_MMAP is defined and MMap doesn't appear to be available"
+#endif
+
+#ifdef _CL_HAVE_NO_FUNCTION_TRY_BLOCKS
+#undef _LUCENE_DISABLE_EXCEPTIONS
+#define _LUCENE_DISABLE_EXCEPTIONS
+
+#error "this is bad if you made it here... your compiler seems not to have try/catch blocks."
+#error "maybe you could implement an alternative solution for us? :)"
+#endif
+
+#ifndef _CL_HAVE_NAMESPACES
+#define DISABLE_NAMESPACE
+#endif
+
+#define LUCENE_DISABLE_HASHING //we could enable this, but so far test show that the hashing is slower :(
+
+//define the file functions
+#define fileSeek lseek
+#define fileSize _filelength
+#define fileStat stat
+#define fileHandleStat fstat
+#ifdef _CL_HAVE_TELL
+#define fileTell tell
+#else
+//ftell (and probably soon ftell64) are POSIX standard functions, but tell and
+//tell64 are not, so we define fileTell in terms of fileSeek.
+#define fileTell(fhandle) fileSeek(fhandle, 0, SEEK_CUR)
+#endif
+
+//this is needed early on so that CL_MAX_PATH can be correctly determined
+//in the StdHeader.h. This was earlier causing problems with macosx.
+//:: crash was due to realpath() that expects an output arguments that
+//has at least the size of PATH_MAX (even if the result has a lower size)
+#include <limits.h>
+
+#ifndef _CL_HAVE_WCHAR_T
+ typedef unsigned short wchar_t;
+#endif
+
+#if defined(__CYGWIN__)
+//cygwin seems to incorrectly define that it has wprintf???
+#undef _CL_HAVE_WPRINTF
+#elif defined(__MINGW32__)
+# ifndef _CL_HAVE_WINDOWS_H
+# define _CL_HAVE_WINDOWS_H
+# endif
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+//end _lucene_COMPILER_ACC
+#elif !defined(_lucene_COMPILER_ACC2)
+#define _lucene_COMPILER_ACC2
+//second inclusion
+
+ //types
+ #if defined(_CL_HAVE_SYS_TYPES_H)
+ #include <sys/types.h>
+ #endif
+ #if defined(_CL_HAVE_INTTYPES_H)
+ #include <inttypes.h>
+ #elif defined(_CL_HAVE_STDINT_H)
+ #include <stdint.h>
+ #else
+ #if _CL_SIZEOF_UNSIGNED_LONG_LONG==8
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ #elif _CL_SIZEOF_UNSIGNED_LONG==8
+ typedef unsigned long uint64_t;
+ typedef long int64_t;
+ #else
+ #error I do not know what to use for a uint64_t.
+ #endif
+
+ /* Give us an unsigned 32-bit data type. */
+ #if _CL_SIZEOF_UNSIGNED_LONG==4
+ typedef unsigned long uint32_t;
+ typedef long int32_t;
+ #elif _CL_SIZEOF_UNSIGNED_INT==4
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ #else
+ #error I do not know what to use for a uint32_t.
+ #endif
+
+ /* An unsigned 8-bit data type */
+ #if _CL_SIZEOF_UNSIGNED_CHAR==1
+ typedef unsigned char uint8_t;
+ #else
+ #error I do not know what to use for a uint8_t.
+ #endif
+ #endif
+
+ //second chance to fix default settings
+ //this must be defined later, otherwise it messes up
+ //the standard libraries
+ #if !defined(__MINGW32__)
+ #define _close ::close
+ #define _read ::read
+ #endif
+
+ //now that int64_t is defined, we can define this...
+ #ifndef _CL_HAVE_FILELENGTH
+ #undef fileSize
+ #define fileSize lucene_filelength
+ int64_t lucene_filelength(int handle);
+ #endif
+
+#elif !defined(_lucene_COMPILER_ACC3)
+#define _lucene_COMPILER_ACC3
+ //third inclusion
+
+ #if !defined(__MINGW32__)
+ //define replacements
+ #define O_RANDOM 0
+ #undef O_BINARY
+ #define O_BINARY 0
+ #define _S_IREAD 0444
+ #define _S_IWRITE 0333 // write and execute permissions
+
+ //some functions that are needed - not charset dependent and not tchar type functions
+ #define _open open
+ #define _write write
+ #define _snprintf snprintf
+
+ //clucene uses ascii for filename interactions
+ #define _realpath(rel,abs) realpath(rel,abs)
+ #define _mkdir(x) mkdir(x,0777)
+ #define _unlink unlink
+ #else
+ #define _realpath(rel,abs) _fullpath(abs,rel,CL_MAX_PATH)
+ #endif
+ //also required by mingw
+ #define _rename rename
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/CompilerBcb.h b/3rdparty/clucene/src/CLucene/config/CompilerBcb.h
new file mode 100644
index 000000000..f1b423b50
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/CompilerBcb.h
@@ -0,0 +1,68 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#if !defined(_lucene_COMPILER_BCB)
+#define _lucene_COMPILER_BCB
+
+// It is internal CLucene header - DO NOT include it directly
+
+#include "CLucene/config/define_std.h"
+#undef _CL_HAVE_STRTOLL
+#undef _CL_HAVE_WCSTOLL
+
+#define _LUCENE_PRAGMA_ONCE
+#define _LUCENE_PRAGMA_WARNINGS //tell lucene to display warnings using pragmas instead of #warning
+#define LUCENE_DISABLE_HASHING
+#define LUCENE_STATIC_CONSTANT(type, assignment) enum { assignment }
+
+#undef LUCENE_ENABLE_MEMLEAKTRACKING //it has been reported that this causes problems
+
+#define fileSize filelength
+#define fileSeek lseek
+#define fileTell tell
+#define fileStat stat
+#define fileHandleStat fstat
+
+#define O_RANDOM 0
+
+//java long type
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+//java int type
+typedef int int32_t;
+typedef unsigned int uint32_t;
+
+//java byte type
+typedef unsigned char uint8_t;
+
+//floating point type
+//we are going to use qreal now
+//typedef double float_t;
+
+//required type
+typedef int intptr_t;
+
+#define _CL_ILONG(x) x ## L
+#define _ILONGLONG(x) x ## i64
+
+
+#elif !defined(_lucene_COMPILER_BCB2)
+#define _lucene_COMPILER_BCB2
+ //second inclusion
+
+ #define _open open
+ #define _timeb timeb
+ #define _ftime ::ftime
+ #define _rename rename
+
+ #define _realpath(rel,abs) _fullpath(abs,rel,CL_MAX_PATH)
+
+#elif !defined(_lucene_COMPILER_BCB3)
+#define _lucene_COMPILER_BCB3
+ //third inclusion
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/CompilerGcc.h b/3rdparty/clucene/src/CLucene/config/CompilerGcc.h
new file mode 100644
index 000000000..a9120988b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/CompilerGcc.h
@@ -0,0 +1,175 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#if !defined(_lucene_COMPILER_GCC)
+#define _lucene_COMPILER_GCC
+
+// It is internal CLucene header - DO NOT include it directly
+#if !defined(_SUPPRESS_MAKE_BASED_CONFIG)
+ #if defined(_BUILD_FOR_QT_)
+ #include "fulltextsearch/qclucene-config_p.h"
+ #else
+ #include "CLucene/clucene-config.h" //make clucene-config.h file
+ #endif
+#endif
+
+#if defined(_ASCII)
+ #undef _UCS2
+#elif defined(_UCS2)
+//
+#else
+ #define CL_CHARSET_GUESS
+#endif
+
+//dont allow FS_MMAP if mmap is not available
+#if defined(LUCENE_FS_MMAP) && !defined(_CL_HAVE_MMAP)
+ #error "LUCENE_FS_MMAP is defined and MMap doesn't appear to be available"
+#endif
+
+#ifdef _CL_HAVE_NO_FUNCTION_TRY_BLOCKS
+ #undef _LUCENE_DISABLE_EXCEPTIONS
+ #define _LUCENE_DISABLE_EXCEPTIONS
+
+ #error "this is bad if you made it here... your compiler seems not to have try/catch blocks."
+ #error "maybe you could implement an alternative solution for us? :)"
+#endif
+
+#ifndef _CL_HAVE_NAMESPACES
+ #define DISABLE_NAMESPACE
+#endif
+
+#define CL_NS_HASHING(func) __gnu_cxx::func
+#define LUCENE_DISABLE_HASHING //we could enable this, but so far test show that the hashing is slower :(
+
+//define the file functions
+#define fileSeek lseek
+#define fileSize _filelength
+#define fileStat stat
+#define fileHandleStat fstat
+#ifdef _CL_HAVE_TELL
+ #define fileTell tell
+#else
+ //ftell (and probably soon ftell64) are POSIX standard functions, but tell and
+ //tell64 are not, so we define fileTell in terms of fileSeek.
+ #define fileTell(fhandle) fileSeek(fhandle, 0, SEEK_CUR)
+#endif
+
+//this is needed early on so that CL_MAX_PATH can be correctly determined
+//in the StdHeader.h. This was earlier causing problems with macosx.
+//:: crash was due to realpath() that expects an output arguments that
+//has at least the size of PATH_MAX (even if the result has a lower size)
+#include <limits.h>
+
+#ifndef _CL_HAVE_WCHAR_T
+ typedef unsigned short wchar_t;
+#endif
+
+#if defined(__CYGWIN__)
+ //cygwin seems to incorrectly define that it has wprintf???
+ #undef _CL_HAVE_WPRINTF
+#elif defined(__MINGW32__)
+ #ifndef _CL_HAVE_WINDOWS_H
+ #define _CL_HAVE_WINDOWS_H
+ #endif
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+//end _lucene_COMPILER_GCC1
+#elif !defined(_lucene_COMPILER_GCC2)
+#define _lucene_COMPILER_GCC2
+ //second inclusion
+
+ //types
+ #if defined(_CL_HAVE_SYS_TYPES_H)
+ #include <sys/types.h>
+ #endif
+ #if defined(_CL_HAVE_INTTYPES_H)
+ #include <inttypes.h>
+ #elif defined(_CL_HAVE_STDINT_H)
+ #include <stdint.h>
+ #else
+ #if _CL_SIZEOF_UNSIGNED_LONG_LONG==8
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ #elif _CL_SIZEOF_UNSIGNED_LONG==8
+ typedef unsigned long uint64_t;
+ typedef long int64_t;
+ #else
+ #error I do not know what to use for a uint64_t.
+ #endif
+
+ /* Give us an unsigned 32-bit data type. */
+ #if _CL_SIZEOF_UNSIGNED_LONG==4
+ typedef unsigned long uint32_t;
+ typedef long int32_t;
+ #elif _CL_SIZEOF_UNSIGNED_INT==4
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ #else
+ #error I do not know what to use for a uint32_t.
+ #endif
+
+ /* An unsigned 8-bit data type */
+ #if _CL_SIZEOF_UNSIGNED_CHAR==1
+ typedef unsigned char uint8_t;
+ #else
+ #error I do not know what to use for a uint8_t.
+ #endif
+ #endif
+
+ //second chance to fix default settings
+ //this must be defined later, otherwise it messes up
+ //the standard libraries
+ #if !defined(__MINGW32__)
+ #define _close ::close
+ #define _read ::read
+ #endif
+
+ //now that int64_t is defined, we can define this...
+ #ifndef _CL_HAVE_FILELENGTH
+ #undef fileSize
+ #define fileSize lucene_filelength
+ int64_t lucene_filelength(int handle);
+ #endif
+
+#elif !defined(_lucene_COMPILER_GCC3)
+#define _lucene_COMPILER_GCC3
+ //third inclusion
+
+ #if !defined(__MINGW32__)
+ //define replacements
+ #define O_RANDOM 0
+ #undef O_BINARY
+ #define O_BINARY 0
+ #define _S_IREAD 0444
+ #define _S_IWRITE 0333 // write and execute permissions
+
+ //some functions that are needed - not charset dependent and not tchar type functions
+ #define _open open
+ #define _write write
+ #define _snprintf snprintf
+
+ //clucene uses ascii for filename interactions
+ #define _realpath(rel,abs) realpath(rel,abs)
+ #define _mkdir(x) mkdir(x,0777)
+ #define _unlink unlink
+ #else
+ #define _realpath(rel,abs) _fullpath(abs,rel,CL_MAX_PATH)
+ #endif
+ //also required by mingw
+ #define _rename rename
+#endif
+
+#if defined(__GNUC__) && (defined(__sgi) || (defined(Q_OS_SOLARIS) && Q_SOLARIS_VERSION < 10))
+ #undef _CL_HAVE_FLOAT_T
+#endif
+
+#if defined(__GNUC__) && defined(Q_OS_SOLARIS) && Q_SOLARIS_VERSION < 10
+ #undef _CL_HAVE_WCSTOLL
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/CompilerMsvc.h b/3rdparty/clucene/src/CLucene/config/CompilerMsvc.h
new file mode 100644
index 000000000..0021ea368
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/CompilerMsvc.h
@@ -0,0 +1,136 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#if !defined(_lucene_COMPILER_MSVC)
+#define _lucene_COMPILER_MSVC
+
+// It is internal CLucene header - DO NOT include it directly
+
+#include "CLucene/config/define_std.h"
+
+#if (_MSC_VER >= 1300)
+//>= 7.0
+ #if defined(_BUILD_FOR_QT_)
+ # pragma warning(disable: 4100) // disable unreferenced formal parameter
+ # pragma warning(disable: 4189) // disable local variable is initialized but not referenced
+ #endif
+ # pragma warning(disable: 4512) // This would be very annoying
+ # pragma warning(disable: 4290) // Ignore exception specification warning
+ # pragma warning(disable: 4250) // Ignore 'class1' : inherits 'class2::member' via dominance (e.g. in MultiReader)
+ // Check for STLport presence
+ #include <string>
+ #if (_MSC_VER < 1310) || defined(_STLPORT_VERSION)
+ #define CL_NS_HASHING(func) std::func //the namespace is different on VC 7.0
+ #else
+ #define CL_NS_HASHING(func) stdext::func
+ #endif
+ #define LUCENE_STATIC_CONSTANT_SYNTAX 1
+
+ #if _MSC_FULL_VER >= 140050320
+ #define _CL_DEPRECATE_TEXT(_Text) __declspec(deprecated(_Text))
+ #else
+ #define _CL_DEPRECATE_TEXT(_Text) __declspec(deprecated)
+ #endif
+
+#elif (_MSC_VER >= 1200)
+//6.0
+#ifdef LUCENE_ENABLE_MEMLEAKTRACKING
+ #define _CLDELETE_CARRAY(x) if (x!=NULL){CL_NS(debug)::LuceneBase::__cl_voidpremove((void*)x,__FILE__,__LINE__);delete[] __CONST_CAST(TCHAR*,x); x=NULL;}
+ #define _CLDELETE_CaARRAY(x) if (x!=NULL){CL_NS(debug)::LuceneBase::__cl_voidpremove((void*)x,__FILE__,__LINE__);delete[] __CONST_CAST(char*,x); x=NULL;}
+ #define _CLDELETE_LCARRAY(x) if (x!=NULL){CL_NS(debug)::LuceneBase::__cl_voidpremove((void*)x,__FILE__,__LINE__);delete[] __CONST_CAST(TCHAR*,x);}
+ #define _CLDELETE_LCaARRAY(x) if (x!=NULL){CL_NS(debug)::LuceneBase::__cl_voidpremove((void*)x,__FILE__,__LINE__);delete[] __CONST_CAST(char*,x);}
+#else
+ #define _CLDELETE_CARRAY(x) if (x!=NULL){delete[] __CONST_CAST(TCHAR*,x); x=NULL;}
+ #define _CLDELETE_CaARRAY(x) if (x!=NULL){delete[] __CONST_CAST(char*,x); x=NULL;}
+ #define _CLDELETE_LCARRAY(x) if (x!=NULL){delete[] __CONST_CAST(TCHAR*,x);}
+ #define _CLDELETE_LCaARRAY(x) if (x!=NULL){delete[] __CONST_CAST(char*,x);}
+
+#endif
+ #define LUCENE_STATIC_CONSTANT_SYNTAX 2
+
+ # pragma warning(disable: 4786) // This would be very annoying
+ namespace std{
+ # undef min // just in case
+ # undef max // just in case
+
+ #define min(a,b) (a>b?b:a)
+ #define max(a,b) (a>b?a:b)
+ }
+
+ //only 7.0+ has these function
+ #undef _CL_HAVE_LLTOA
+ #undef _CL_HAVE_LLTOAW
+ #undef _CL_HAVE_INTPTR_T
+ #undef _CL_HAVE_WCSTOLL
+ #undef _CL_HAVE_STRTOLL
+ #undef _CL_HAVE_HASH_MAP
+ #undef _CL_HAVE_HASH_SET
+
+#else
+# error "This version of MSVC has not been tested. Please uncomment this line to try anyway. Please send a report to the Clucene's administration if successful"
+#endif
+
+#if _MSC_VER >= 1020
+ #define _LUCENE_PRAGMA_ONCE
+#endif
+#define _LUCENE_PRAGMA_WARNINGS //tell lucene to display warnings using pragmas instead of #warning
+
+//if we are compiling using single-threaded libraries, we can disable multi-threading stuff
+#if !defined(_MT) && !defined(_CL_DISABLE_MULTITHREADING)
+ #define _CL_DISABLE_MULTITHREADING
+#endif
+
+//msvc supports large files
+#ifdef _LARGE_FILES
+# define fileSize _filelengthi64
+# define fileSeek _lseeki64
+# define fileTell _telli64
+# define fileStat _stati64
+# define fileHandleStat _fstati64
+#else
+# define fileSize _filelength
+# define fileSeek _lseek
+# define fileTell _tell
+# define fileStat _stat
+# define fileHandleStat _fstat
+#endif
+
+//_rename is not defined???
+#define _rename rename
+
+#define CL_MAX_PATH 260 //give the windef.h value for this...
+#define _realpath(rel,abs) _fullpath(abs,rel,CL_MAX_PATH)
+
+//java long type
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+//java int type
+typedef int int32_t;
+typedef unsigned int uint32_t;
+
+//java byte type
+typedef unsigned char uint8_t;
+
+//floating point type
+//we are going to use qreal now
+//typedef double float_t;
+
+#define _CL_ILONG(x) x ## L
+#define _ILONGLONG(x) x ## i64
+
+
+#elif !defined(_lucene_COMPILER_MSVC2)
+#define _lucene_COMPILER_MSVC2
+ //second inclusion
+
+
+#elif !defined(_lucene_COMPILER_MSVC3)
+#define _lucene_COMPILER_MSVC3
+ //third inclusion
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/PlatformMac.h b/3rdparty/clucene/src/CLucene/config/PlatformMac.h
new file mode 100644
index 000000000..9f6d6f421
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/PlatformMac.h
@@ -0,0 +1,19 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+// It is internal CLucene header - DO NOT include it directly
+
+# define PATH_DELIMITER _T("/")
+# define PATH_DELIMITERA "/"
+# define PATH_DELIMITERC '/'
+
+# if (__GNUC__ < 3) && !defined( __APPLE_CC__)
+// GCC strange "ignore std" mode works better if you pretend everything
+// is in the std namespace, for the most part.
+# define LUCENE_NO_STDC_NAMESPACE
+# endif
+
+#undef _T //apple has something else strange here...
diff --git a/3rdparty/clucene/src/CLucene/config/PlatformUnix.h b/3rdparty/clucene/src/CLucene/config/PlatformUnix.h
new file mode 100644
index 000000000..202a894bd
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/PlatformUnix.h
@@ -0,0 +1,12 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+// It is internal CLucene header - DO NOT include it directly
+
+# define PATH_DELIMITER _T("/")
+# define PATH_DELIMITERA "/"
+# define PATH_DELIMITERC '/'
+
diff --git a/3rdparty/clucene/src/CLucene/config/PlatformWin32.h b/3rdparty/clucene/src/CLucene/config/PlatformWin32.h
new file mode 100644
index 000000000..8b8a1132e
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/PlatformWin32.h
@@ -0,0 +1,11 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+// It is internal CLucene header - DO NOT include it directly
+
+# define PATH_DELIMITER _T("\\")
+# define PATH_DELIMITERA "\\"
+# define PATH_DELIMITERC '\\'
diff --git a/3rdparty/clucene/src/CLucene/config/compiler.h b/3rdparty/clucene/src/CLucene/config/compiler.h
new file mode 100644
index 000000000..68f93b6e4
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/compiler.h
@@ -0,0 +1,259 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#if !defined(lucene_compiler_h)
+#define lucene_compiler_h
+
+#if defined(_MBCS) || defined(_ASCII)
+#undef _ASCII
+#undef _UCS2
+#define _ASCII
+#elif defined(_UNICODE)
+#define _UCS2
+#elif !defined(_UCS2)
+#define _UCS2
+#endif
+
+//msvc needs unicode define so that it uses unicode library
+#ifdef _UCS2
+#undef _UNICODE
+#define _UNICODE
+#undef _ASCII
+#else
+#undef _UNICODE
+#undef _UCS2
+#endif
+
+
+////////////////////////////////////////////////////////////////////
+// Figure out what compiler we are using
+////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && !defined(__MWERKS__) && !defined (__COMO__)
+#define _CLCOMPILER_MSVC _MSC_VER
+#endif
+
+#if defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__xlC__) || defined(__sgi) && defined(__EDG__)
+#include "CLucene/config/CompilerGcc.h"
+
+#elif defined(_CLCOMPILER_MSVC)
+/* Microsoft Visual C++ */
+#include "CLucene/config/CompilerMsvc.h"
+
+#elif defined (__BORLANDC__)
+#include "CLucene/config/CompilerBcb.h"
+
+#elif defined (__HP_aCC)
+#include "CLucene/config/CompilerAcc.h"
+
+#else
+ //Unable to identify the compiler, issue error diagnostic.
+ //Edit <CLucene/config/LuceneMycomp.h> to set STLport up for your compiler.
+ //Uncomment this next line
+#error "Unable to identify the compiler, issue error diagnostic. Edit <CLucene/config/CompilerMycomp.h> to set Lucene up for your compiler."
+#include "CLucene/config/LuceneMycomp.h"
+#endif /* end of compiler choice */
+////////////////////////////////////////////////////////////////////
+
+
+
+////////////////////////////////////////////////////////////////////
+// Now include platform specific definitions
+////////////////////////////////////////////////////////////////////
+
+/* Operating system recognition (basic) */
+#if defined (__unix) || defined (__linux__) || defined (__QNX__) || defined (_AIX) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__Lynx__) || defined(hpux) || defined(__hpux)
+#undef _UNIX
+#define _UNIX 1
+#include "CLucene/config/PlatformUnix.h"
+
+#elif defined(macintosh) || defined (_MAC) || defined(__APPLE__)
+#undef _MAC
+#define _MAC 1
+#include "CLucene/config/PlatformMac.h"
+
+#elif defined (_WIN32) || defined (__WIN32) || defined (WIN32) || defined (__WIN32__)
+#undef _WIN32
+#define _WIN32
+#include "CLucene/config/PlatformWin32.h"
+
+#elif defined (__WIN16) || defined (WIN16) || defined (_WIN16)
+#undef _WIN16
+#define _WIN16
+#error "CLucene has not been tested on this platform. Please send a report to the lucene administrators if you are able to successfully compile"
+#else
+#error "CLucene could not identify the platform."
+#endif /* platforms */
+
+
+
+////////////////////////////////////////////////////////////////////
+// Now we take all that we have learnt, and define some things
+////////////////////////////////////////////////////////////////////
+
+//lets just say that we can always do unicode! :)
+#ifdef CL_CHARSET_GUESS
+#define _UCS2
+#endif
+
+#if defined(_ASCII)
+#undef _UCS2
+#elif defined(_UCS2)
+#undef _ASCII
+#endif
+
+#ifndef _LUCENE_NO_NEW_STYLE_CASTS
+#define __CONST_CAST(typ,var) const_cast<typ>(var)
+#define __REINTERPRET_CAST(typ,var) reinterpret_cast<typ>(var)
+#else
+#define __CONST_CAST(typ,var) ((typ)(var))
+#define __REINTERPRET_CAST,var) ((typ)(var))
+#endif
+
+#ifndef _CL_DEPRECATE_TEXT
+#define _CL_DEPRECATE_TEXT(_Text)
+#endif
+#define _CL_DEPRECATED(_NewItem) _CL_DEPRECATE_TEXT("This function or variable has been superceded by newer library or operating system functionality. Consider using" #_NewItem "instead. See online help for details.")
+
+
+//cnd-debug exit command
+#ifndef debugFatalExit
+#define debugFatalExit(ret) exit(ret)
+#endif
+
+#ifndef _CL_ILONG
+#define _CL_ILONG(x) x ## L
+#endif
+#ifndef _ILONGLONG
+#define _ILONGLONG(x) x ## LL
+#endif
+
+//define whats the values of item intergers *should* be. we can check this in a test
+#define LUCENE_INT64_MAX_SHOULDBE _ILONGLONG(0x7FFFFFFFFFFFFFFF)
+#define LUCENE_INT32_MAX_SHOULDBE 0x7FFFFFFFL
+#define LUCENE_UINT8_MAX_SHOULDBE 0xff
+
+//maximum path length. only used for buffers that use fullpath.
+//anything else should use a dynamic length.
+#if defined(CL_MAX_PATH)
+//do nothing...
+#elif defined(PATH_MAX)
+#define CL_MAX_PATH PATH_MAX
+#elif defined(MAX_PATH)
+#define CL_MAX_PATH MAX_PATH
+#elif defined(_MAX_PATH)
+#define CL_MAX_PATH _MAX_PATH
+#else
+ #error "CL_MAX_PATH could not be determined"
+#endif
+
+//this is the max filename... for now its just the same,
+//but this could change, so we use a different name
+#define CL_MAX_NAME CL_MAX_PATH
+//this used to be CL_MAX_NAME * 32, but as Alex Hudson points out, this could come to be 128kb.
+//the above logic for CL_MAX_NAME should be correct enough to handle all file names
+#define CL_MAX_DIR CL_MAX_PATH
+
+#ifdef _LARGE_FILES
+#define LUCENE_MAX_FILELENGTH LUCENE_INT64_MAX_SHOULDBE
+#else
+#define LUCENE_MAX_FILELENGTH LUCENE_INT32_MAX_SHOULDBE
+#endif
+
+//use the LUCENE_STATIC_CONSTANT_SYNTAX to determine LUCENE_STATIC_CONSTANT
+#ifndef LUCENE_STATIC_CONSTANT
+ //autoconf is not properly detecting the correct method for this, and since there's no real big
+ //harm in always using an enum, we'll probably just make this the default.
+ /*#if LUCENE_STATIC_CONSTANT_SYNTAX == 1
+ #define LUCENE_STATIC_CONSTANT(type, assignment) static const type assignment
+ #elif LUCENE_STATIC_CONSTANT_SYNTAX == 2*/
+ #define LUCENE_STATIC_CONSTANT(type, assignment) enum { assignment }
+ /*#else
+ #error "LUCENE_STATIC_CONSTANT not defined, and/or LUCENE_STATIC_CONSTANT_SYNTAX is not defined to a valid value"
+ #endif*/
+#endif
+
+//end of lucene_compiler_h
+#elif !defined(lucene_compiler_h2)
+#define lucene_compiler_h2
+//here we include the compiler header again, this gives the header a
+//second chance at including stuff, after the main inclusions are complete
+
+#if defined (__GNUC__) || defined(__SUNPRO_CC) || defined(__xlC__) || defined(__sgi) && defined(__EDG__)
+#include "CLucene/config/CompilerGcc.h"
+
+#elif defined(_CLCOMPILER_MSVC)
+/* Microsoft Visual C++ */
+#include "CLucene/config/CompilerMsvc.h"
+
+#elif defined __BORLANDC__
+#include "CLucene/config/CompilerBcb.h"
+
+#elif defined (__HP_aCC)
+#include "CLucene/config/CompilerAcc.h"
+
+#else
+//Unable to identify the compiler, issue error diagnostic.
+//Edit <CLucene/config/LuceneMycomp.h> to set STLport up for your compiler.
+//Uncomment this next line
+#error "Unable to identify the compiler, issue error diagnostic. Edit <CLucene/config/CompilerMycomp.h> to set Lucene up for your compiler."
+#include "CLucene/config/LuceneMycomp.h"
+#endif /* end of compiler choice */
+
+#ifndef _CL_HAVE_FLOAT_T
+//#ifdef _CL_HAVE_LONG_DOUBLE
+// long double's are not working (reported by Mark Ashworth on Solaris 64)
+// typedef long double float_t; /* `float' expressions are evaluated as `long double'. */
+//#else
+// we are going to use qreal now
+// typedef double float_t;
+//#endif
+#endif
+
+/*todo: but need to define SIZEOF_VOID_P #if (SIZEOF_VOID_P > 4 && SIZEOF_VOID_P <= 8)
+#ifndef _CL_HAVE_INTPTR_T
+ typedef int64_t intptr_t;
+#endif
+#elif (SIZEOF_VOID_P > 2 && SIZEOF_VOID_P <= 4)
+# ifndef _CL_HAVE_INTPTR_T
+ typedef int32_t intptr_t;
+# endif
+#else
+#error "void * is either >8 bytes or <= 2. In either case, I am confused."
+#endif*/
+
+#ifndef _CL_HAVE_INTPTR_T
+ typedef int intptr_t;
+#endif
+
+//end of lucene_compiler_h2
+#elif !defined(lucene_compiler_h3)
+#define lucene_compiler_h3
+//here we include the compiler header again, this gives the header a
+//third chance at including stuff, after the main inclusions are complete
+
+#if defined (__GNUC__ ) || defined(__SUNPRO_CC) || defined(__xlC__) || defined(__sgi) && defined(__EDG__)
+#include "CLucene/config/CompilerGcc.h"
+
+#elif defined(_CLCOMPILER_MSVC)
+/* Microsoft Visual C++ */
+#include "CLucene/config/CompilerMsvc.h"
+
+#elif defined __BORLANDC__
+#include "CLucene/config/CompilerBcb.h"
+
+#elif defined (__HP_aCC)
+#include "CLucene/config/CompilerAcc.h"
+
+#else
+//Unable to identify the compiler, issue error diagnostic.
+//Edit <CLucene/config/LuceneMycomp.h> to set STLport up for your compiler.
+//Uncomment this next line
+#error "Unable to identify the compiler, issue error diagnostic. Edit <CLucene/config/CompilerMycomp.h> to set Lucene up for your compiler."
+#include "CLucene/config/LuceneMycomp.h"
+#endif /* end of compiler choice */
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/define_std.h b/3rdparty/clucene/src/CLucene/config/define_std.h
new file mode 100644
index 000000000..22a079053
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/define_std.h
@@ -0,0 +1,113 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef lucene_define_std
+#define lucene_define_std
+//define a standard list of defines.
+//These defines represents a fairly complete compiler.
+//Of course it is preferable to use the autoconf generated
+//list, but then not all systems can do this :)
+
+//we support long files - 64 bit file functions
+#define _LARGE_FILES
+
+//support namespaces
+#define _CL_HAVE_NAMESPACES
+
+//support try/catch blocks
+#define _CL_HAVE_FUNCTION_TRY_BLOCKS
+
+//the normal headers
+#define _CL_STDC_HEADERS
+#define _CL_HAVE_STDARG_H
+#define _CL_HAVE_ALGORITHM
+#define _CL_HAVE_FUNCTIONAL
+#define _CL_HAVE_MATH_H
+#define _CL_HAVE_STL
+#define _CL_HAVE_HASH_MAP
+#define _CL_HAVE_HASH_SET
+#define _CL_HAVE_MAP
+#define _CL_HAVE_SET
+#define _CL_HAVE_LIST
+#define _CL_HAVE_VECTOR
+#define _CL_HAVE_STDEXCEPT
+#define _CL_HAVE_ERRNO_H
+#define _CL_HAVE_SYS_STAT_H
+#define _CL_HAVE_FCNTL_H
+
+//character & std tchar support
+#define _CL_HAVE_TCHAR_H
+#ifdef _UCS2
+ #define _CL_HAVE_WCTYPE_H
+
+ #define _CL_HAVE_WCSCPY
+ #define _CL_HAVE_WCSNCPY
+ #define _CL_HAVE_WCSCAT
+ #define _CL_HAVE_WCSCHR
+ #define _CL_HAVE_WCSSTR
+ #define _CL_HAVE_WCSLEN
+ #define _CL_HAVE_WCSCMP
+ #define _CL_HAVE_WCSNCMP
+ #define _CL_HAVE_WCSCSPN
+#else
+ #define _CL_HAVE_CTYPE_H
+#endif
+
+//already have the normal structures
+#define _CL_HAVE_FLOAT_T
+#define _CL_HAVE_INTPTR_T
+
+//system dependant:
+#define _CL_HAVE_STRING_H //could be HAVE_STRINGS_H && HAVE_STRCHR
+#define _CL_HAVE_SYS_TIMEB_H
+#define _CL_HAVE_TIME_H
+
+#if defined (_WIN32) || defined (__WIN32) || defined (WIN32) || defined (__WIN32__)
+ #define _CL_HAVE_IO_H
+ #define _CL_HAVE_DIRECT_H
+ #define _CL_HAVE_WINDOWS_H
+#else
+ #define _CL_HAVE_UNISTD_H
+#endif
+#ifdef UNDER_CE
+#undef _CL_HAVE_SYS_TIMEB_H
+#endif
+
+////////////////////////////////////////////////
+//now for individual functions. some compilers
+//miss these, so must individually define what
+//we have
+////////////////////////////////////////////////
+
+//string functions
+#define _CL_HAVE_STRLWR
+#define _CL_HAVE_WCSLWR
+#define _CL_HAVE_WCSCASECMP
+#define _CL_HAVE_STRCASECMP
+
+//formatting functions
+#define _CL_HAVE_SNWPRINTF
+#define _CL_HAVE_VSNWPRINTF
+#define _CL_HAVE_WPRINTF
+#define _CL_HAVE_SNPRINTF
+#define _CL_HAVE_PRINTF
+
+
+//conversion functions
+#define _CL_HAVE_STRTOLL
+#define _CL_HAVE_WCSTOLL
+#define _CL_HAVE_WCSTOD
+#define _CL_HAVE_LLTOA
+#define _CL_HAVE_LLTOW
+#define _CL_HAVE_INTPTR_T
+
+//these ones are not standard (msvc)
+//so you will probably need to undefine
+//if you are not using msvc
+#define _CL_HAVE_FILELENGTH
+
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/gunichartables.cpp b/3rdparty/clucene/src/CLucene/config/gunichartables.cpp
new file mode 100644
index 000000000..5463936f6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/gunichartables.cpp
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 1999 Tom Tromey
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ *
+ ************************************************
+ * Also licensed with permission from Tom Tromey
+ * and Owen Taylor under the Apache license.
+ * Original location:
+ * http://cvs.gnome.org/viewcvs/glib/glib/guniprop.c?view=log
+ ************************************************
+ *
+ * Copyright 2003-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+
+#include "CLucene/StdHeader.h"
+
+typedef unsigned long gunichar;
+typedef unsigned short guint16;
+typedef short gint16;
+typedef char gchar;
+typedef unsigned char guchar;
+
+/* These are the possible character classifications.
+ * See http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
+ or http://www.unicode.org/Public/UNIDATA/UCD.html.
+
+ todo: i think there is a new version of the unicode, which we should use.
+ data is licensed like this: http://www.unicode.org/copyright.html... not sure but looks apache compatible
+ */
+typedef enum
+{
+ G_UNICODE_CONTROL,
+ G_UNICODE_FORMAT,
+ G_UNICODE_UNASSIGNED,
+ G_UNICODE_PRIVATE_USE,
+ G_UNICODE_SURROGATE,
+ G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER,
+ G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_COMBINING_MARK,
+ G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_FINAL_PUNCTUATION,
+ G_UNICODE_INITIAL_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_LINE_SEPARATOR,
+ G_UNICODE_PARAGRAPH_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR
+} GUnicodeType;
+
+
+#include "gunichartables.h"
+
+#define ATTR_TABLE(Page) (((Page) <= G_UNICODE_LAST_PAGE_PART1) \
+ ? attr_table_part1[Page] \
+ : attr_table_part2[(Page) - 0xe00])
+
+#define ATTTABLE(Page, Char) \
+ ((ATTR_TABLE(Page) == G_UNICODE_MAX_TABLE_INDEX) ? 0 : (attr_data[ATTR_TABLE(Page)][Char]))
+
+
+#define TTYPE_PART1(Page, Char) \
+ ((type_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+ ? (type_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+ : (type_data[type_table_part1[Page]][Char]))
+
+#define TTYPE_PART2(Page, Char) \
+ ((type_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+ ? (type_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+ : (type_data[type_table_part2[Page]][Char]))
+
+#define TYPE(Char) \
+ (((Char) <= G_UNICODE_LAST_CHAR_PART1) \
+ ? TTYPE_PART1 ((Char) >> 8, (Char) & 0xff) \
+ : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \
+ ? TTYPE_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \
+ : G_UNICODE_UNASSIGNED))
+
+/* Count the number of elements in an array. The array must be defined
+ * as such; using this with a dynamically allocated array will give
+ * incorrect results.
+ */
+#define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
+
+
+
+
+#if defined(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS)
+#ifdef _LUCENE_PRAGMA_WARNINGS
+ #pragma message ("===== Using internal character function =====")
+#else
+#if !(defined(Q_OS_SOLARIS) || defined(Q_CC_MIPS))
+#warning "===== Using internal character function ====="
+#endif
+#endif
+
+bool cl_isletter(gunichar c)
+{
+ int t = TYPE (c);
+ switch(t)
+ {
+ case G_UNICODE_LOWERCASE_LETTER: return true;
+ case G_UNICODE_TITLECASE_LETTER: return true;
+ case G_UNICODE_UPPERCASE_LETTER: return true;
+ case G_UNICODE_MODIFIER_LETTER: return true;
+ case G_UNICODE_OTHER_LETTER: return true;
+ default: return false;
+ }
+}
+
+bool cl_isalnum(gunichar c)
+{
+ int t = TYPE (c);
+ switch(t)
+ {
+ case G_UNICODE_LOWERCASE_LETTER: return true;
+ case G_UNICODE_TITLECASE_LETTER: return true;
+ case G_UNICODE_UPPERCASE_LETTER: return true;
+ case G_UNICODE_MODIFIER_LETTER: return true;
+ case G_UNICODE_OTHER_LETTER: return true;
+ case G_UNICODE_DECIMAL_NUMBER: return true;
+ case G_UNICODE_LETTER_NUMBER: return true;
+ case G_UNICODE_OTHER_NUMBER: return true;
+ default: return false;
+ }
+}
+
+bool cl_isdigit(gunichar c)
+{
+ int t = TYPE (c);
+ switch(t)
+ {
+ case G_UNICODE_DECIMAL_NUMBER: return true;
+ case G_UNICODE_LETTER_NUMBER: return true;
+ case G_UNICODE_OTHER_NUMBER: return true;
+ default: return false;
+ }
+}
+
+/**
+ * cl_isspace:
+ * @c: a Unicode character
+ *
+ * Determines whether a character is a space, tab, or line separator
+ * (newline, carriage return, etc.). Given some UTF-8 text, obtain a
+ * character value with lucene_utf8towc().
+ *
+ * (Note: don't use this to do word breaking; you have to use
+ * Pango or equivalent to get word breaking right, the algorithm
+ * is fairly complex.)
+ *
+ * Return value: %TRUE if @c is a punctuation character
+ **/
+bool cl_isspace (gunichar c)
+{
+ switch (c)
+ {
+ /* special-case these since Unicode thinks they are not spaces */
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\f':
+ return true;
+
+ default:
+ {
+ int t = TYPE ((gunichar)c);
+ return (t == G_UNICODE_SPACE_SEPARATOR || t == G_UNICODE_LINE_SEPARATOR
+ || t == G_UNICODE_PARAGRAPH_SEPARATOR);
+ }
+ }
+}
+
+
+
+/**
+ * cl_tolower:
+ * @c: a Unicode character.
+ *
+ * Converts a character to lower case.
+ *
+ * Return value: the result of converting @c to lower case.
+ * If @c is not an upperlower or titlecase character,
+ * or has no lowercase equivalent @c is returned unchanged.
+ **/
+TCHAR cl_tolower (TCHAR ch)
+{
+ gunichar c=ch;
+ int t = TYPE ((gunichar)c);
+ if (t == G_UNICODE_UPPERCASE_LETTER)
+ {
+ gunichar val = ATTTABLE (c >> 8, c & 0xff);
+ if (val >= 0x1000000)
+ {
+ const gchar *p = special_case_table + val - 0x1000000;
+ int len=0;
+ wchar_t ret=0;
+ lucene_utf8towc(&ret,p,6);
+#ifdef _UCS2
+ return ret;
+#else
+ return LUCENE_OOR_CHAR(ret);
+#endif
+ //return cl_utf8_get_char (p, &len);
+ }else
+ return val ? val : c;
+ }else if (t == G_UNICODE_TITLECASE_LETTER){
+ unsigned int i;
+ for (i = 0; i < G_N_ELEMENTS (title_table); ++i)
+ {
+ if (title_table[i][0] == c)
+ return title_table[i][2];
+ }
+ }
+ return c;
+}
+
+/**
+ * cl_toupper:
+ * @c: a Unicode character
+ *
+ * Converts a character to uppercase.
+ *
+ * Return value: the result of converting @c to uppercase.
+ * If @c is not an lowercase or titlecase character,
+ * or has no upper case equivalent @c is returned unchanged.
+ **/
+TCHAR cl_toupper (TCHAR ch)
+{
+ gunichar c=ch;
+ int t = TYPE (c);
+ if (t == G_UNICODE_LOWERCASE_LETTER)
+ {
+ gunichar val = ATTTABLE (c >> 8, c & 0xff);
+ if (val >= 0x1000000)
+ {
+ const gchar *p = special_case_table + val - 0x1000000;
+
+ wchar_t ret=0;
+ lucene_utf8towc(&ret,p,6);
+#ifdef _UCS2
+ return ret;
+#else
+ return LUCENE_OOR_CHAR(ret);
+#endif
+ //return lucene_utf8towc (p);
+ }
+ else
+ return val ? val : c;
+ }
+ else if (t == G_UNICODE_TITLECASE_LETTER)
+ {
+ unsigned int i;
+ for (i = 0; i < G_N_ELEMENTS (title_table); ++i)
+ {
+ if (title_table[i][0] == c)
+ return title_table[i][1];
+ }
+ }
+ return c;
+}
+
+
+
+/**
+ * cl_tcasefold:
+ * @str: a unicode string
+ *
+ * Converts a string into a form that is independent of case. The
+ * result will not correspond to any particular case, but can be
+ * compared for equality or ordered with the results of calling
+ * cl_tcasefold() on other strings.
+ *
+ * Note that calling cl_tcasefold() followed by g_utf8_collate() is
+ * only an approximation to the correct linguistic case insensitive
+ * ordering, though it is a fairly good one. Getting this exactly
+ * right would require a more sophisticated collation function that
+ * takes case sensitivity into account. GLib does not currently
+ * provide such a function.
+ *
+ * Return value: a newly allocated string, that is a
+ * case independent form of @str.
+ **/
+TCHAR cl_tcasefold(const TCHAR ch){
+ int start = 0;
+ int end = G_N_ELEMENTS (casefold_table);
+
+ if (ch >= casefold_table[start].ch &&
+ ch <= casefold_table[end - 1].ch)
+ {
+ while (1)
+ {
+ int half = (start + end) / 2;
+ if (ch == casefold_table[half].ch)
+ {
+ wchar_t ret=0;
+ lucene_utf8towc(&ret,casefold_table[half].data,6);
+
+ #ifdef _UCS2
+ return ret;
+ #else
+ LUCENE_OOR_CHAR(ret)
+ #endif
+ }else if (half == start){
+ break;
+ }else if (ch > casefold_table[half].ch){
+ start = half;
+ }else{
+ end = half;
+ }
+ }
+ }
+ return cl_tolower(ch);
+
+}
+
+
+//this function was not taken from gnome
+TCHAR* cl_tcscasefold( TCHAR * str, int len ) //len default is -1
+{
+ TCHAR *p = str;
+ while ((len < 0 || p < str + len) && *p)
+ {
+ *p = cl_tcasefold(*p);
+ p++;
+ }
+ return str;
+}
+//this function was not taken from gnome
+int cl_tcscasefoldcmp(const TCHAR * dst, const TCHAR * src){
+ TCHAR f,l;
+
+ do{
+ f = cl_tcasefold( (*(dst++)) );
+ l = cl_tcasefold( (*(src++)) );
+ } while ( (f) && (f == l) );
+
+ return (int)(f - l);
+}
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/gunichartables.h b/3rdparty/clucene/src/CLucene/config/gunichartables.h
new file mode 100644
index 000000000..182a87054
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/gunichartables.h
@@ -0,0 +1,11264 @@
+/* This file is automatically generated. DO NOT EDIT!
+ Instead, edit gen-unicode-tables.pl and re-run. */
+
+#ifndef CHARTABLES_H
+#define CHARTABLES_H
+
+#define G_UNICODE_DATA_VERSION "4.0"
+
+#define G_UNICODE_LAST_CHAR 0x10ffff
+
+#define G_UNICODE_MAX_TABLE_INDEX 10000
+
+#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF
+
+#define G_UNICODE_LAST_PAGE_PART1 762
+
+static const char type_data[][256] = {
+ { /* page 0, index 0 */
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_FORMAT,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 1, index 1 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 2, index 2 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL
+ },
+ { /* page 3, index 3 */
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 4, index 4 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 5, index 5 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 6, index 6 */
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_FORMAT, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 7, index 7 */
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 9, index 8 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 10, index 9 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 11, index 10 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 12, index 11 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 13, index 12 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 14, index 13 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 15, index 14 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 16, index 15 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 17, index 16 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 18, index 17 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 19, index 18 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 20, index 19 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 22, index 20 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 23, index 21 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 24, index 22 */
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_UNASSIGNED,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 25, index 23 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL
+ },
+ { /* page 29, index 24 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 30, index 25 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 31, index 26 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED
+ },
+ { /* page 32, index 27 */
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION,
+ G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_LINE_SEPARATOR, G_UNICODE_PARAGRAPH_SEPARATOR,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 33, index 28 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL
+ },
+ { /* page 35, index 29 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 36, index 30 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER
+ },
+ { /* page 37, index 31 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL
+ },
+ { /* page 38, index 32 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 39, index 33 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL
+ },
+ { /* page 41, index 34 */
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL
+ },
+ { /* page 43, index 35 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 46, index 36 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 47, index 37 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 48, index 38 */
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 49, index 39 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 50, index 40 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 77, index 41 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL
+ },
+ { /* page 159, index 42 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 164, index 43 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 215, index 44 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 250, index 45 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 251, index 46 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER
+ },
+ { /* page 253, index 47 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 254, index 48 */
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT
+ },
+ { /* page 255, index 49 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 256, index 50 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 257, index 51 */
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 259, index 52 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 260, index 53 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 264, index 54 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 464, index 55 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 465, index 56 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 467, index 57 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 468, index 58 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 469, index 59 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 470, index 60 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 471, index 61 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER
+ },
+ { /* page 678, index 62 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 762, index 63 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 3584, index 64 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 3585, index 65 */
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 4095, index 66 */
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 4351, index 67 */
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ }
+};
+
+/* U+0000 through U+2FAFF */
+static const gint16 type_table_part1[763] = {
+ 0 /* page 0 */,
+ 1 /* page 1 */,
+ 2 /* page 2 */,
+ 3 /* page 3 */,
+ 4 /* page 4 */,
+ 5 /* page 5 */,
+ 6 /* page 6 */,
+ 7 /* page 7 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 8 /* page 9 */,
+ 9 /* page 10 */,
+ 10 /* page 11 */,
+ 11 /* page 12 */,
+ 12 /* page 13 */,
+ 13 /* page 14 */,
+ 14 /* page 15 */,
+ 15 /* page 16 */,
+ 16 /* page 17 */,
+ 17 /* page 18 */,
+ 18 /* page 19 */,
+ 19 /* page 20 */,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 20 /* page 22 */,
+ 21 /* page 23 */,
+ 22 /* page 24 */,
+ 23 /* page 25 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 24 /* page 29 */,
+ 25 /* page 30 */,
+ 26 /* page 31 */,
+ 27 /* page 32 */,
+ 28 /* page 33 */,
+ G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+ 29 /* page 35 */,
+ 30 /* page 36 */,
+ 31 /* page 37 */,
+ 32 /* page 38 */,
+ 33 /* page 39 */,
+ G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+ 34 /* page 41 */,
+ G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+ 35 /* page 43 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 36 /* page 46 */,
+ 37 /* page 47 */,
+ 38 /* page 48 */,
+ 39 /* page 49 */,
+ 40 /* page 50 */,
+ G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 41 /* page 77 */,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 42 /* page 159 */,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 43 /* page 164 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 44 /* page 215 */,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 45 /* page 250 */,
+ 46 /* page 251 */,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 47 /* page 253 */,
+ 48 /* page 254 */,
+ 49 /* page 255 */,
+ 50 /* page 256 */,
+ 51 /* page 257 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 52 /* page 259 */,
+ 53 /* page 260 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 54 /* page 264 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 55 /* page 464 */,
+ 56 /* page 465 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 57 /* page 467 */,
+ 58 /* page 468 */,
+ 59 /* page 469 */,
+ 60 /* page 470 */,
+ 61 /* page 471 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 62 /* page 678 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 63 /* page 762 */
+};
+
+/* U+E0000 through U+10FFFF */
+static const gint16 type_table_part2[768] = {
+ 64 /* page 3584 */,
+ 65 /* page 3585 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ 66 /* page 4095 */,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ 67 /* page 4351 */
+};
+
+static const gunichar attr_data[][256] = {
+ { /* page 0, index 0 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
+ 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070,
+ 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079,
+ 0x007a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x0042,
+ 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b,
+ 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054,
+ 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x039c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5,
+ 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0000,
+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x1000000,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8,
+ 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1,
+ 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0000, 0x00d8, 0x00d9, 0x00da,
+ 0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178
+ },
+ { /* page 1, index 1 */
+ 0x0101, 0x0100, 0x0103, 0x0102, 0x0105, 0x0104, 0x0107, 0x0106, 0x0109,
+ 0x0108, 0x010b, 0x010a, 0x010d, 0x010c, 0x010f, 0x010e, 0x0111, 0x0110,
+ 0x0113, 0x0112, 0x0115, 0x0114, 0x0117, 0x0116, 0x0119, 0x0118, 0x011b,
+ 0x011a, 0x011d, 0x011c, 0x011f, 0x011e, 0x0121, 0x0120, 0x0123, 0x0122,
+ 0x0125, 0x0124, 0x0127, 0x0126, 0x0129, 0x0128, 0x012b, 0x012a, 0x012d,
+ 0x012c, 0x012f, 0x012e, 0x1000007, 0x0049, 0x0133, 0x0132, 0x0135,
+ 0x0134, 0x0137, 0x0136, 0x0000, 0x013a, 0x0139, 0x013c, 0x013b, 0x013e,
+ 0x013d, 0x0140, 0x013f, 0x0142, 0x0141, 0x0144, 0x0143, 0x0146, 0x0145,
+ 0x0148, 0x0147, 0x1000086, 0x014b, 0x014a, 0x014d, 0x014c, 0x014f,
+ 0x014e, 0x0151, 0x0150, 0x0153, 0x0152, 0x0155, 0x0154, 0x0157, 0x0156,
+ 0x0159, 0x0158, 0x015b, 0x015a, 0x015d, 0x015c, 0x015f, 0x015e, 0x0161,
+ 0x0160, 0x0163, 0x0162, 0x0165, 0x0164, 0x0167, 0x0166, 0x0169, 0x0168,
+ 0x016b, 0x016a, 0x016d, 0x016c, 0x016f, 0x016e, 0x0171, 0x0170, 0x0173,
+ 0x0172, 0x0175, 0x0174, 0x0177, 0x0176, 0x00ff, 0x017a, 0x0179, 0x017c,
+ 0x017b, 0x017e, 0x017d, 0x0053, 0x0000, 0x0253, 0x0183, 0x0182, 0x0185,
+ 0x0184, 0x0254, 0x0188, 0x0187, 0x0256, 0x0257, 0x018c, 0x018b, 0x0000,
+ 0x01dd, 0x0259, 0x025b, 0x0192, 0x0191, 0x0260, 0x0263, 0x01f6, 0x0269,
+ 0x0268, 0x0199, 0x0198, 0x0000, 0x0000, 0x026f, 0x0272, 0x0220, 0x0275,
+ 0x01a1, 0x01a0, 0x01a3, 0x01a2, 0x01a5, 0x01a4, 0x0280, 0x01a8, 0x01a7,
+ 0x0283, 0x0000, 0x0000, 0x01ad, 0x01ac, 0x0288, 0x01b0, 0x01af, 0x028a,
+ 0x028b, 0x01b4, 0x01b3, 0x01b6, 0x01b5, 0x0292, 0x01b9, 0x01b8, 0x0000,
+ 0x0000, 0x01bd, 0x01bc, 0x0000, 0x01f7, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x01c6, 0x0000, 0x01c4, 0x01c9, 0x0000, 0x01c7, 0x01cc, 0x0000, 0x01ca,
+ 0x01ce, 0x01cd, 0x01d0, 0x01cf, 0x01d2, 0x01d1, 0x01d4, 0x01d3, 0x01d6,
+ 0x01d5, 0x01d8, 0x01d7, 0x01da, 0x01d9, 0x01dc, 0x01db, 0x018e, 0x01df,
+ 0x01de, 0x01e1, 0x01e0, 0x01e3, 0x01e2, 0x01e5, 0x01e4, 0x01e7, 0x01e6,
+ 0x01e9, 0x01e8, 0x01eb, 0x01ea, 0x01ed, 0x01ec, 0x01ef, 0x01ee,
+ 0x10000ad, 0x01f3, 0x0000, 0x01f1, 0x01f5, 0x01f4, 0x0195, 0x01bf,
+ 0x01f9, 0x01f8, 0x01fb, 0x01fa, 0x01fd, 0x01fc, 0x01ff, 0x01fe
+ },
+ { /* page 2, index 2 */
+ 0x0201, 0x0200, 0x0203, 0x0202, 0x0205, 0x0204, 0x0207, 0x0206, 0x0209,
+ 0x0208, 0x020b, 0x020a, 0x020d, 0x020c, 0x020f, 0x020e, 0x0211, 0x0210,
+ 0x0213, 0x0212, 0x0215, 0x0214, 0x0217, 0x0216, 0x0219, 0x0218, 0x021b,
+ 0x021a, 0x021d, 0x021c, 0x021f, 0x021e, 0x019e, 0x0000, 0x0223, 0x0222,
+ 0x0225, 0x0224, 0x0227, 0x0226, 0x0229, 0x0228, 0x022b, 0x022a, 0x022d,
+ 0x022c, 0x022f, 0x022e, 0x0231, 0x0230, 0x0233, 0x0232, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0181, 0x0186, 0x0000, 0x0189, 0x018a, 0x0000, 0x018f,
+ 0x0000, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0193, 0x0000, 0x0000,
+ 0x0194, 0x0000, 0x0000, 0x0000, 0x0000, 0x0197, 0x0196, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x019c, 0x0000, 0x0000, 0x019d, 0x0000, 0x0000,
+ 0x019f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x01a6, 0x0000, 0x0000, 0x01a9, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x01ae, 0x0000, 0x01b1, 0x01b2, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x01b7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 3, index 3 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03ac,
+ 0x0000, 0x03ad, 0x03ae, 0x03af, 0x0000, 0x03cc, 0x0000, 0x03cd, 0x03ce,
+ 0x100008f, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0,
+ 0x03c1, 0x0000, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9,
+ 0x03ca, 0x03cb, 0x0386, 0x0388, 0x0389, 0x038a, 0x100009e, 0x0391,
+ 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a,
+ 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a3,
+ 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x038c,
+ 0x038e, 0x038f, 0x0000, 0x0392, 0x0398, 0x0000, 0x0000, 0x0000, 0x03a6,
+ 0x03a0, 0x0000, 0x03d9, 0x03d8, 0x03db, 0x03da, 0x03dd, 0x03dc, 0x03df,
+ 0x03de, 0x03e1, 0x03e0, 0x03e3, 0x03e2, 0x03e5, 0x03e4, 0x03e7, 0x03e6,
+ 0x03e9, 0x03e8, 0x03eb, 0x03ea, 0x03ed, 0x03ec, 0x03ef, 0x03ee, 0x039a,
+ 0x03a1, 0x03f9, 0x0000, 0x03b8, 0x0395, 0x0000, 0x03f8, 0x03f7, 0x03f2,
+ 0x03fb, 0x03fa, 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 4, index 4 */
+ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458,
+ 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, 0x0430, 0x0431,
+ 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a,
+ 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443,
+ 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c,
+ 0x044d, 0x044e, 0x044f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
+ 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0400,
+ 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409,
+ 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, 0x0461, 0x0460, 0x0463,
+ 0x0462, 0x0465, 0x0464, 0x0467, 0x0466, 0x0469, 0x0468, 0x046b, 0x046a,
+ 0x046d, 0x046c, 0x046f, 0x046e, 0x0471, 0x0470, 0x0473, 0x0472, 0x0475,
+ 0x0474, 0x0477, 0x0476, 0x0479, 0x0478, 0x047b, 0x047a, 0x047d, 0x047c,
+ 0x047f, 0x047e, 0x0481, 0x0480, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x048b, 0x048a, 0x048d, 0x048c, 0x048f, 0x048e,
+ 0x0491, 0x0490, 0x0493, 0x0492, 0x0495, 0x0494, 0x0497, 0x0496, 0x0499,
+ 0x0498, 0x049b, 0x049a, 0x049d, 0x049c, 0x049f, 0x049e, 0x04a1, 0x04a0,
+ 0x04a3, 0x04a2, 0x04a5, 0x04a4, 0x04a7, 0x04a6, 0x04a9, 0x04a8, 0x04ab,
+ 0x04aa, 0x04ad, 0x04ac, 0x04af, 0x04ae, 0x04b1, 0x04b0, 0x04b3, 0x04b2,
+ 0x04b5, 0x04b4, 0x04b7, 0x04b6, 0x04b9, 0x04b8, 0x04bb, 0x04ba, 0x04bd,
+ 0x04bc, 0x04bf, 0x04be, 0x0000, 0x04c2, 0x04c1, 0x04c4, 0x04c3, 0x04c6,
+ 0x04c5, 0x04c8, 0x04c7, 0x04ca, 0x04c9, 0x04cc, 0x04cb, 0x04ce, 0x04cd,
+ 0x0000, 0x04d1, 0x04d0, 0x04d3, 0x04d2, 0x04d5, 0x04d4, 0x04d7, 0x04d6,
+ 0x04d9, 0x04d8, 0x04db, 0x04da, 0x04dd, 0x04dc, 0x04df, 0x04de, 0x04e1,
+ 0x04e0, 0x04e3, 0x04e2, 0x04e5, 0x04e4, 0x04e7, 0x04e6, 0x04e9, 0x04e8,
+ 0x04eb, 0x04ea, 0x04ed, 0x04ec, 0x04ef, 0x04ee, 0x04f1, 0x04f0, 0x04f3,
+ 0x04f2, 0x04f5, 0x04f4, 0x0000, 0x0000, 0x04f9, 0x04f8, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 5, index 5 */
+ 0x0501, 0x0500, 0x0503, 0x0502, 0x0505, 0x0504, 0x0507, 0x0506, 0x0509,
+ 0x0508, 0x050b, 0x050a, 0x050d, 0x050c, 0x050f, 0x050e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565,
+ 0x0566, 0x0567, 0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e,
+ 0x056f, 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
+ 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, 0x0580,
+ 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0531, 0x0532,
+ 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, 0x0538, 0x0539, 0x053a, 0x053b,
+ 0x053c, 0x053d, 0x053e, 0x053f, 0x0540, 0x0541, 0x0542, 0x0543, 0x0544,
+ 0x0545, 0x0546, 0x0547, 0x0548, 0x0549, 0x054a, 0x054b, 0x054c, 0x054d,
+ 0x054e, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556,
+ 0x1000044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 6, index 6 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
+ 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
+ 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 9, index 7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
+ 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003,
+ 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 10, index 8 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
+ 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003,
+ 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 11, index 9 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
+ 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003,
+ 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 12, index 10 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
+ 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003,
+ 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 13, index 11 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
+ 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 14, index 12 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 15, index 13 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003,
+ 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 16, index 14 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 19, index 15 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003,
+ 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 23, index 16 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 24, index 17 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
+ 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 25, index 18 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
+ 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 30, index 19 */
+ 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06, 0x1e09,
+ 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e, 0x1e11, 0x1e10,
+ 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16, 0x1e19, 0x1e18, 0x1e1b,
+ 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e, 0x1e21, 0x1e20, 0x1e23, 0x1e22,
+ 0x1e25, 0x1e24, 0x1e27, 0x1e26, 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d,
+ 0x1e2c, 0x1e2f, 0x1e2e, 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34,
+ 0x1e37, 0x1e36, 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f,
+ 0x1e3e, 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46,
+ 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e, 0x1e51,
+ 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56, 0x1e59, 0x1e58,
+ 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e, 0x1e61, 0x1e60, 0x1e63,
+ 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66, 0x1e69, 0x1e68, 0x1e6b, 0x1e6a,
+ 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e, 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75,
+ 0x1e74, 0x1e77, 0x1e76, 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c,
+ 0x1e7f, 0x1e7e, 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87,
+ 0x1e86, 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e,
+ 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0x10000b6, 0x10000bf,
+ 0x10000c8, 0x10000d1, 0x10000da, 0x1e60, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6, 0x1ea9,
+ 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae, 0x1eb1, 0x1eb0,
+ 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6, 0x1eb9, 0x1eb8, 0x1ebb,
+ 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe, 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2,
+ 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6, 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd,
+ 0x1ecc, 0x1ecf, 0x1ece, 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4,
+ 0x1ed7, 0x1ed6, 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf,
+ 0x1ede, 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6,
+ 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee, 0x1ef1,
+ 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6, 0x1ef9, 0x1ef8,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 31, index 20 */
+ 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f00,
+ 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f18, 0x1f19,
+ 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x0000, 0x0000, 0x1f10, 0x1f11, 0x1f12,
+ 0x1f13, 0x1f14, 0x1f15, 0x0000, 0x0000, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b,
+ 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24,
+ 0x1f25, 0x1f26, 0x1f27, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d,
+ 0x1f3e, 0x1f3f, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36,
+ 0x1f37, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x0000, 0x0000,
+ 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x0000, 0x0000,
+ 0x10000e3, 0x1f59, 0x10000ee, 0x1f5b, 0x10000fd, 0x1f5d, 0x100010c,
+ 0x1f5f, 0x0000, 0x1f51, 0x0000, 0x1f53, 0x0000, 0x1f55, 0x0000, 0x1f57,
+ 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1f60,
+ 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1fba, 0x1fbb,
+ 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea,
+ 0x1feb, 0x1ffa, 0x1ffb, 0x0000, 0x0000, 0x10001b7, 0x10001c4, 0x10001d1,
+ 0x10001de, 0x10001eb, 0x10001f8, 0x1000205, 0x1000212, 0x100021f,
+ 0x1000229, 0x1000233, 0x100023d, 0x1000247, 0x1000251, 0x100025b,
+ 0x1000265, 0x100026f, 0x100027c, 0x1000289, 0x1000296, 0x10002a3,
+ 0x10002b0, 0x10002bd, 0x10002ca, 0x10002d7, 0x10002e1, 0x10002eb,
+ 0x10002f5, 0x10002ff, 0x1000309, 0x1000313, 0x100031d, 0x1000327,
+ 0x1000334, 0x1000341, 0x100034e, 0x100035b, 0x1000368, 0x1000375,
+ 0x1000382, 0x100038f, 0x1000399, 0x10003a3, 0x10003ad, 0x10003b7,
+ 0x10003c1, 0x10003cb, 0x10003d5, 0x1fb8, 0x1fb9, 0x100041e, 0x10003df,
+ 0x100042b, 0x0000, 0x100011b, 0x1000466, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71,
+ 0x10003eb, 0x0000, 0x0399, 0x0000, 0x0000, 0x0000, 0x1000436, 0x10003f4,
+ 0x1000443, 0x0000, 0x1000126, 0x1000475, 0x1f72, 0x1f73, 0x1f74, 0x1f75,
+ 0x1000400, 0x0000, 0x0000, 0x0000, 0x1fd8, 0x1fd9, 0x1000131, 0x1000140,
+ 0x0000, 0x0000, 0x100014f, 0x100015a, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x1fe8, 0x1fe9, 0x1000169, 0x1000178,
+ 0x1000187, 0x1fec, 0x1000192, 0x100019d, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b,
+ 0x1fe5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100044e, 0x1000409,
+ 0x100045b, 0x0000, 0x10001ac, 0x1000484, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d,
+ 0x1000415, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 33, index 21 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x03c9, 0x0000, 0x0000, 0x0000, 0x006b, 0x00e5, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 251, index 22 */
+ 0x100000f, 0x1000016, 0x100001d, 0x1000024, 0x100002d, 0x1000036,
+ 0x100003d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100004f, 0x100005a, 0x1000065,
+ 0x1000070, 0x100007b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000
+ },
+ { /* page 255, index 23 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
+ 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff41, 0xff42, 0xff43,
+ 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c,
+ 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55,
+ 0xff56, 0xff57, 0xff58, 0xff59, 0xff5a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27,
+ 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30,
+ 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39,
+ 0xff3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 260, index 24 */
+ 0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f,
+ 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437,
+ 0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f,
+ 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447,
+ 0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f,
+ 0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407,
+ 0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f,
+ 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417,
+ 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f,
+ 0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ },
+ { /* page 471, index 25 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006,
+ 0x0007, 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
+ 0x0006, 0x0007, 0x0008, 0x0009
+ }
+};
+
+/* U+0000 through U+2FAFF */
+static const gint16 attr_table_part1[763] = {
+ 0 /* page 0 */,
+ 1 /* page 1 */,
+ 2 /* page 2 */,
+ 3 /* page 3 */,
+ 4 /* page 4 */,
+ 5 /* page 5 */,
+ 6 /* page 6 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 7 /* page 9 */,
+ 8 /* page 10 */,
+ 9 /* page 11 */,
+ 10 /* page 12 */,
+ 11 /* page 13 */,
+ 12 /* page 14 */,
+ 13 /* page 15 */,
+ 14 /* page 16 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 15 /* page 19 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 16 /* page 23 */,
+ 17 /* page 24 */,
+ 18 /* page 25 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 19 /* page 30 */,
+ 20 /* page 31 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 21 /* page 33 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 22 /* page 251 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 23 /* page 255 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 24 /* page 260 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 25 /* page 471 */,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX
+};
+
+/* U+E0000 through U+10FFFF */
+static const gint16 attr_table_part2[768] = {
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+ 0x0000 + G_UNICODE_MAX_TABLE_INDEX
+};
+
+static const gunichar title_table[][3] = {
+ { 0x01c5, 0x01c4, 0x01c6 },
+ { 0x01c8, 0x01c7, 0x01c9 },
+ { 0x01cb, 0x01ca, 0x01cc },
+ { 0x01f2, 0x01f1, 0x01f3 },
+ { 0x1f88, 0x0000, 0x1f80 },
+ { 0x1f89, 0x0000, 0x1f81 },
+ { 0x1f8a, 0x0000, 0x1f82 },
+ { 0x1f8b, 0x0000, 0x1f83 },
+ { 0x1f8c, 0x0000, 0x1f84 },
+ { 0x1f8d, 0x0000, 0x1f85 },
+ { 0x1f8e, 0x0000, 0x1f86 },
+ { 0x1f8f, 0x0000, 0x1f87 },
+ { 0x1f98, 0x0000, 0x1f90 },
+ { 0x1f99, 0x0000, 0x1f91 },
+ { 0x1f9a, 0x0000, 0x1f92 },
+ { 0x1f9b, 0x0000, 0x1f93 },
+ { 0x1f9c, 0x0000, 0x1f94 },
+ { 0x1f9d, 0x0000, 0x1f95 },
+ { 0x1f9e, 0x0000, 0x1f96 },
+ { 0x1f9f, 0x0000, 0x1f97 },
+ { 0x1fa8, 0x0000, 0x1fa0 },
+ { 0x1fa9, 0x0000, 0x1fa1 },
+ { 0x1faa, 0x0000, 0x1fa2 },
+ { 0x1fab, 0x0000, 0x1fa3 },
+ { 0x1fac, 0x0000, 0x1fa4 },
+ { 0x1fad, 0x0000, 0x1fa5 },
+ { 0x1fae, 0x0000, 0x1fa6 },
+ { 0x1faf, 0x0000, 0x1fa7 },
+ { 0x1fbc, 0x0000, 0x1fb3 },
+ { 0x1fcc, 0x0000, 0x1fc3 },
+ { 0x1ffc, 0x0000, 0x1ff3 }
+};
+
+
+/* Table of special cases for case conversion; each record contains
+ * First, the best single character mapping to lowercase if Lu,
+ * and to uppercase if Ll, followed by the output mapping for the two cases
+ * other than the case of the codepoint, in the order [Ll],[Lu],[Lt],
+ * encoded in UTF-8, separated and terminated by a null character.
+ */
+static const gchar special_case_table[] = {
+ "\x00\x53\x53\x00\x53\x73\0" /* offset 0 */
+ "\x69\x69\xcc\x87\x00\xc4\xb0\0" /* offset 7 */
+ "\x00\x46\x46\x00\x46\x66\0" /* offset 15 */
+ "\x00\x46\x49\x00\x46\x69\0" /* offset 22 */
+ "\x00\x46\x4c\x00\x46\x6c\0" /* offset 29 */
+ "\x00\x46\x46\x49\x00\x46\x66\x69\0" /* offset 36 */
+ "\x00\x46\x46\x4c\x00\x46\x66\x6c\0" /* offset 45 */
+ "\x00\x53\x54\x00\x53\x74\0" /* offset 54 */
+ "\x00\x53\x54\x00\x53\x74\0" /* offset 61 */
+ "\x00\xd4\xb5\xd5\x92\x00\xd4\xb5\xd6\x82\0" /* offset 68 */
+ "\x00\xd5\x84\xd5\x86\x00\xd5\x84\xd5\xb6\0" /* offset 79 */
+ "\x00\xd5\x84\xd4\xb5\x00\xd5\x84\xd5\xa5\0" /* offset 90 */
+ "\x00\xd5\x84\xd4\xbb\x00\xd5\x84\xd5\xab\0" /* offset 101 */
+ "\x00\xd5\x8e\xd5\x86\x00\xd5\x8e\xd5\xb6\0" /* offset 112 */
+ "\x00\xd5\x84\xd4\xbd\x00\xd5\x84\xd5\xad\0" /* offset 123 */
+ "\x00\xca\xbc\x4e\x00\xca\xbc\x4e\0" /* offset 134 */
+ "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 143 */
+ "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 158 */
+ "\x00\x4a\xcc\x8c\x00\x4a\xcc\x8c\0" /* offset 173 */
+ "\x00\x48\xcc\xb1\x00\x48\xcc\xb1\0" /* offset 182 */
+ "\x00\x54\xcc\x88\x00\x54\xcc\x88\0" /* offset 191 */
+ "\x00\x57\xcc\x8a\x00\x57\xcc\x8a\0" /* offset 200 */
+ "\x00\x59\xcc\x8a\x00\x59\xcc\x8a\0" /* offset 209 */
+ "\x00\x41\xca\xbe\x00\x41\xca\xbe\0" /* offset 218 */
+ "\x00\xce\xa5\xcc\x93\x00\xce\xa5\xcc\x93\0" /* offset 227 */
+ "\x00\xce\xa5\xcc\x93\xcc\x80\x00\xce\xa5\xcc\x93\xcc\x80\0" /* offset 238 */
+ "\x00\xce\xa5\xcc\x93\xcc\x81\x00\xce\xa5\xcc\x93\xcc\x81\0" /* offset 253 */
+ "\x00\xce\xa5\xcc\x93\xcd\x82\x00\xce\xa5\xcc\x93\xcd\x82\0" /* offset 268 */
+ "\x00\xce\x91\xcd\x82\x00\xce\x91\xcd\x82\0" /* offset 283 */
+ "\x00\xce\x97\xcd\x82\x00\xce\x97\xcd\x82\0" /* offset 294 */
+ "\x00\xce\x99\xcc\x88\xcc\x80\x00\xce\x99\xcc\x88\xcc\x80\0" /* offset 305 */
+ "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 320 */
+ "\x00\xce\x99\xcd\x82\x00\xce\x99\xcd\x82\0" /* offset 335 */
+ "\x00\xce\x99\xcc\x88\xcd\x82\x00\xce\x99\xcc\x88\xcd\x82\0" /* offset 346 */
+ "\x00\xce\xa5\xcc\x88\xcc\x80\x00\xce\xa5\xcc\x88\xcc\x80\0" /* offset 361 */
+ "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 376 */
+ "\x00\xce\xa1\xcc\x93\x00\xce\xa1\xcc\x93\0" /* offset 391 */
+ "\x00\xce\xa5\xcd\x82\x00\xce\xa5\xcd\x82\0" /* offset 402 */
+ "\x00\xce\xa5\xcc\x88\xcd\x82\x00\xce\xa5\xcc\x88\xcd\x82\0" /* offset 413 */
+ "\x00\xce\xa9\xcd\x82\x00\xce\xa9\xcd\x82\0" /* offset 428 */
+ "\xe1\xbe\x88\xe1\xbc\x88\xce\x99\x00\xe1\xbe\x88\0" /* offset 439 */
+ "\xe1\xbe\x89\xe1\xbc\x89\xce\x99\x00\xe1\xbe\x89\0" /* offset 452 */
+ "\xe1\xbe\x8a\xe1\xbc\x8a\xce\x99\x00\xe1\xbe\x8a\0" /* offset 465 */
+ "\xe1\xbe\x8b\xe1\xbc\x8b\xce\x99\x00\xe1\xbe\x8b\0" /* offset 478 */
+ "\xe1\xbe\x8c\xe1\xbc\x8c\xce\x99\x00\xe1\xbe\x8c\0" /* offset 491 */
+ "\xe1\xbe\x8d\xe1\xbc\x8d\xce\x99\x00\xe1\xbe\x8d\0" /* offset 504 */
+ "\xe1\xbe\x8e\xe1\xbc\x8e\xce\x99\x00\xe1\xbe\x8e\0" /* offset 517 */
+ "\xe1\xbe\x8f\xe1\xbc\x8f\xce\x99\x00\xe1\xbe\x8f\0" /* offset 530 */
+ "\xe1\xbe\x80\x00\xe1\xbc\x88\xce\x99\0" /* offset 543 */
+ "\xe1\xbe\x81\x00\xe1\xbc\x89\xce\x99\0" /* offset 553 */
+ "\xe1\xbe\x82\x00\xe1\xbc\x8a\xce\x99\0" /* offset 563 */
+ "\xe1\xbe\x83\x00\xe1\xbc\x8b\xce\x99\0" /* offset 573 */
+ "\xe1\xbe\x84\x00\xe1\xbc\x8c\xce\x99\0" /* offset 583 */
+ "\xe1\xbe\x85\x00\xe1\xbc\x8d\xce\x99\0" /* offset 593 */
+ "\xe1\xbe\x86\x00\xe1\xbc\x8e\xce\x99\0" /* offset 603 */
+ "\xe1\xbe\x87\x00\xe1\xbc\x8f\xce\x99\0" /* offset 613 */
+ "\xe1\xbe\x98\xe1\xbc\xa8\xce\x99\x00\xe1\xbe\x98\0" /* offset 623 */
+ "\xe1\xbe\x99\xe1\xbc\xa9\xce\x99\x00\xe1\xbe\x99\0" /* offset 636 */
+ "\xe1\xbe\x9a\xe1\xbc\xaa\xce\x99\x00\xe1\xbe\x9a\0" /* offset 649 */
+ "\xe1\xbe\x9b\xe1\xbc\xab\xce\x99\x00\xe1\xbe\x9b\0" /* offset 662 */
+ "\xe1\xbe\x9c\xe1\xbc\xac\xce\x99\x00\xe1\xbe\x9c\0" /* offset 675 */
+ "\xe1\xbe\x9d\xe1\xbc\xad\xce\x99\x00\xe1\xbe\x9d\0" /* offset 688 */
+ "\xe1\xbe\x9e\xe1\xbc\xae\xce\x99\x00\xe1\xbe\x9e\0" /* offset 701 */
+ "\xe1\xbe\x9f\xe1\xbc\xaf\xce\x99\x00\xe1\xbe\x9f\0" /* offset 714 */
+ "\xe1\xbe\x90\x00\xe1\xbc\xa8\xce\x99\0" /* offset 727 */
+ "\xe1\xbe\x91\x00\xe1\xbc\xa9\xce\x99\0" /* offset 737 */
+ "\xe1\xbe\x92\x00\xe1\xbc\xaa\xce\x99\0" /* offset 747 */
+ "\xe1\xbe\x93\x00\xe1\xbc\xab\xce\x99\0" /* offset 757 */
+ "\xe1\xbe\x94\x00\xe1\xbc\xac\xce\x99\0" /* offset 767 */
+ "\xe1\xbe\x95\x00\xe1\xbc\xad\xce\x99\0" /* offset 777 */
+ "\xe1\xbe\x96\x00\xe1\xbc\xae\xce\x99\0" /* offset 787 */
+ "\xe1\xbe\x97\x00\xe1\xbc\xaf\xce\x99\0" /* offset 797 */
+ "\xe1\xbe\xa8\xe1\xbd\xa8\xce\x99\x00\xe1\xbe\xa8\0" /* offset 807 */
+ "\xe1\xbe\xa9\xe1\xbd\xa9\xce\x99\x00\xe1\xbe\xa9\0" /* offset 820 */
+ "\xe1\xbe\xaa\xe1\xbd\xaa\xce\x99\x00\xe1\xbe\xaa\0" /* offset 833 */
+ "\xe1\xbe\xab\xe1\xbd\xab\xce\x99\x00\xe1\xbe\xab\0" /* offset 846 */
+ "\xe1\xbe\xac\xe1\xbd\xac\xce\x99\x00\xe1\xbe\xac\0" /* offset 859 */
+ "\xe1\xbe\xad\xe1\xbd\xad\xce\x99\x00\xe1\xbe\xad\0" /* offset 872 */
+ "\xe1\xbe\xae\xe1\xbd\xae\xce\x99\x00\xe1\xbe\xae\0" /* offset 885 */
+ "\xe1\xbe\xaf\xe1\xbd\xaf\xce\x99\x00\xe1\xbe\xaf\0" /* offset 898 */
+ "\xe1\xbe\xa0\x00\xe1\xbd\xa8\xce\x99\0" /* offset 911 */
+ "\xe1\xbe\xa1\x00\xe1\xbd\xa9\xce\x99\0" /* offset 921 */
+ "\xe1\xbe\xa2\x00\xe1\xbd\xaa\xce\x99\0" /* offset 931 */
+ "\xe1\xbe\xa3\x00\xe1\xbd\xab\xce\x99\0" /* offset 941 */
+ "\xe1\xbe\xa4\x00\xe1\xbd\xac\xce\x99\0" /* offset 951 */
+ "\xe1\xbe\xa5\x00\xe1\xbd\xad\xce\x99\0" /* offset 961 */
+ "\xe1\xbe\xa6\x00\xe1\xbd\xae\xce\x99\0" /* offset 971 */
+ "\xe1\xbe\xa7\x00\xe1\xbd\xaf\xce\x99\0" /* offset 981 */
+ "\xe1\xbe\xbc\xce\x91\xce\x99\x00\xe1\xbe\xbc\0" /* offset 991 */
+ "\xe1\xbe\xb3\x00\xce\x91\xce\x99\0" /* offset 1003 */
+ "\xe1\xbf\x8c\xce\x97\xce\x99\x00\xe1\xbf\x8c\0" /* offset 1012 */
+ "\xe1\xbf\x83\x00\xce\x97\xce\x99\0" /* offset 1024 */
+ "\xe1\xbf\xbc\xce\xa9\xce\x99\x00\xe1\xbf\xbc\0" /* offset 1033 */
+ "\xe1\xbf\xb3\x00\xce\xa9\xce\x99\0" /* offset 1045 */
+ "\x00\xe1\xbe\xba\xce\x99\x00\xe1\xbe\xba\xcd\x85\0" /* offset 1054 */
+ "\x00\xce\x86\xce\x99\x00\xce\x86\xcd\x85\0" /* offset 1067 */
+ "\x00\xe1\xbf\x8a\xce\x99\x00\xe1\xbf\x8a\xcd\x85\0" /* offset 1078 */
+ "\x00\xce\x89\xce\x99\x00\xce\x89\xcd\x85\0" /* offset 1091 */
+ "\x00\xe1\xbf\xba\xce\x99\x00\xe1\xbf\xba\xcd\x85\0" /* offset 1102 */
+ "\x00\xce\x8f\xce\x99\x00\xce\x8f\xcd\x85\0" /* offset 1115 */
+ "\x00\xce\x91\xcd\x82\xce\x99\x00\xce\x91\xcd\x82\xcd\x85\0" /* offset 1126 */
+ "\x00\xce\x97\xcd\x82\xce\x99\x00\xce\x97\xcd\x82\xcd\x85\0" /* offset 1141 */
+ "\x00\xce\xa9\xcd\x82\xce\x99\x00\xce\xa9\xcd\x82\xcd\x85\0" /* offset 1156 */
+};
+
+
+/* Table of casefolding cases that can't be derived by lowercasing
+ */
+static const struct {
+ guint16 ch;
+ gchar data[7];
+} casefold_table[] = {
+ { 0x00b5, "\xce\xbc" },
+ { 0x00df, "\x73\x73" },
+ { 0x0130, "\x69\xcc\x87" },
+ { 0x0149, "\xca\xbc\x6e" },
+ { 0x017f, "\x73" },
+ { 0x01f0, "\x6a\xcc\x8c" },
+ { 0x0345, "\xce\xb9" },
+ { 0x0390, "\xce\xb9\xcc\x88\xcc\x81" },
+ { 0x03b0, "\xcf\x85\xcc\x88\xcc\x81" },
+ { 0x03c2, "\xcf\x83" },
+ { 0x03d0, "\xce\xb2" },
+ { 0x03d1, "\xce\xb8" },
+ { 0x03d5, "\xcf\x86" },
+ { 0x03d6, "\xcf\x80" },
+ { 0x03f0, "\xce\xba" },
+ { 0x03f1, "\xcf\x81" },
+ { 0x03f5, "\xce\xb5" },
+ { 0x0587, "\xd5\xa5\xd6\x82" },
+ { 0x1e96, "\x68\xcc\xb1" },
+ { 0x1e97, "\x74\xcc\x88" },
+ { 0x1e98, "\x77\xcc\x8a" },
+ { 0x1e99, "\x79\xcc\x8a" },
+ { 0x1e9a, "\x61\xca\xbe" },
+ { 0x1e9b, "\xe1\xb9\xa1" },
+ { 0x1f50, "\xcf\x85\xcc\x93" },
+ { 0x1f52, "\xcf\x85\xcc\x93\xcc\x80" },
+ { 0x1f54, "\xcf\x85\xcc\x93\xcc\x81" },
+ { 0x1f56, "\xcf\x85\xcc\x93\xcd\x82" },
+ { 0x1f80, "\xe1\xbc\x80\xce\xb9" },
+ { 0x1f81, "\xe1\xbc\x81\xce\xb9" },
+ { 0x1f82, "\xe1\xbc\x82\xce\xb9" },
+ { 0x1f83, "\xe1\xbc\x83\xce\xb9" },
+ { 0x1f84, "\xe1\xbc\x84\xce\xb9" },
+ { 0x1f85, "\xe1\xbc\x85\xce\xb9" },
+ { 0x1f86, "\xe1\xbc\x86\xce\xb9" },
+ { 0x1f87, "\xe1\xbc\x87\xce\xb9" },
+ { 0x1f88, "\xe1\xbc\x80\xce\xb9" },
+ { 0x1f89, "\xe1\xbc\x81\xce\xb9" },
+ { 0x1f8a, "\xe1\xbc\x82\xce\xb9" },
+ { 0x1f8b, "\xe1\xbc\x83\xce\xb9" },
+ { 0x1f8c, "\xe1\xbc\x84\xce\xb9" },
+ { 0x1f8d, "\xe1\xbc\x85\xce\xb9" },
+ { 0x1f8e, "\xe1\xbc\x86\xce\xb9" },
+ { 0x1f8f, "\xe1\xbc\x87\xce\xb9" },
+ { 0x1f90, "\xe1\xbc\xa0\xce\xb9" },
+ { 0x1f91, "\xe1\xbc\xa1\xce\xb9" },
+ { 0x1f92, "\xe1\xbc\xa2\xce\xb9" },
+ { 0x1f93, "\xe1\xbc\xa3\xce\xb9" },
+ { 0x1f94, "\xe1\xbc\xa4\xce\xb9" },
+ { 0x1f95, "\xe1\xbc\xa5\xce\xb9" },
+ { 0x1f96, "\xe1\xbc\xa6\xce\xb9" },
+ { 0x1f97, "\xe1\xbc\xa7\xce\xb9" },
+ { 0x1f98, "\xe1\xbc\xa0\xce\xb9" },
+ { 0x1f99, "\xe1\xbc\xa1\xce\xb9" },
+ { 0x1f9a, "\xe1\xbc\xa2\xce\xb9" },
+ { 0x1f9b, "\xe1\xbc\xa3\xce\xb9" },
+ { 0x1f9c, "\xe1\xbc\xa4\xce\xb9" },
+ { 0x1f9d, "\xe1\xbc\xa5\xce\xb9" },
+ { 0x1f9e, "\xe1\xbc\xa6\xce\xb9" },
+ { 0x1f9f, "\xe1\xbc\xa7\xce\xb9" },
+ { 0x1fa0, "\xe1\xbd\xa0\xce\xb9" },
+ { 0x1fa1, "\xe1\xbd\xa1\xce\xb9" },
+ { 0x1fa2, "\xe1\xbd\xa2\xce\xb9" },
+ { 0x1fa3, "\xe1\xbd\xa3\xce\xb9" },
+ { 0x1fa4, "\xe1\xbd\xa4\xce\xb9" },
+ { 0x1fa5, "\xe1\xbd\xa5\xce\xb9" },
+ { 0x1fa6, "\xe1\xbd\xa6\xce\xb9" },
+ { 0x1fa7, "\xe1\xbd\xa7\xce\xb9" },
+ { 0x1fa8, "\xe1\xbd\xa0\xce\xb9" },
+ { 0x1fa9, "\xe1\xbd\xa1\xce\xb9" },
+ { 0x1faa, "\xe1\xbd\xa2\xce\xb9" },
+ { 0x1fab, "\xe1\xbd\xa3\xce\xb9" },
+ { 0x1fac, "\xe1\xbd\xa4\xce\xb9" },
+ { 0x1fad, "\xe1\xbd\xa5\xce\xb9" },
+ { 0x1fae, "\xe1\xbd\xa6\xce\xb9" },
+ { 0x1faf, "\xe1\xbd\xa7\xce\xb9" },
+ { 0x1fb2, "\xe1\xbd\xb0\xce\xb9" },
+ { 0x1fb3, "\xce\xb1\xce\xb9" },
+ { 0x1fb4, "\xce\xac\xce\xb9" },
+ { 0x1fb6, "\xce\xb1\xcd\x82" },
+ { 0x1fb7, "\xce\xb1\xcd\x82\xce\xb9" },
+ { 0x1fbc, "\xce\xb1\xce\xb9" },
+ { 0x1fbe, "\xce\xb9" },
+ { 0x1fc2, "\xe1\xbd\xb4\xce\xb9" },
+ { 0x1fc3, "\xce\xb7\xce\xb9" },
+ { 0x1fc4, "\xce\xae\xce\xb9" },
+ { 0x1fc6, "\xce\xb7\xcd\x82" },
+ { 0x1fc7, "\xce\xb7\xcd\x82\xce\xb9" },
+ { 0x1fcc, "\xce\xb7\xce\xb9" },
+ { 0x1fd2, "\xce\xb9\xcc\x88\xcc\x80" },
+ { 0x1fd3, "\xce\xb9\xcc\x88\xcc\x81" },
+ { 0x1fd6, "\xce\xb9\xcd\x82" },
+ { 0x1fd7, "\xce\xb9\xcc\x88\xcd\x82" },
+ { 0x1fe2, "\xcf\x85\xcc\x88\xcc\x80" },
+ { 0x1fe3, "\xcf\x85\xcc\x88\xcc\x81" },
+ { 0x1fe4, "\xcf\x81\xcc\x93" },
+ { 0x1fe6, "\xcf\x85\xcd\x82" },
+ { 0x1fe7, "\xcf\x85\xcc\x88\xcd\x82" },
+ { 0x1ff2, "\xe1\xbd\xbc\xce\xb9" },
+ { 0x1ff3, "\xcf\x89\xce\xb9" },
+ { 0x1ff4, "\xcf\x8e\xce\xb9" },
+ { 0x1ff6, "\xcf\x89\xcd\x82" },
+ { 0x1ff7, "\xcf\x89\xcd\x82\xce\xb9" },
+ { 0x1ffc, "\xcf\x89\xce\xb9" },
+ { 0x2160, "\xe2\x85\xb0" },
+ { 0x2161, "\xe2\x85\xb1" },
+ { 0x2162, "\xe2\x85\xb2" },
+ { 0x2163, "\xe2\x85\xb3" },
+ { 0x2164, "\xe2\x85\xb4" },
+ { 0x2165, "\xe2\x85\xb5" },
+ { 0x2166, "\xe2\x85\xb6" },
+ { 0x2167, "\xe2\x85\xb7" },
+ { 0x2168, "\xe2\x85\xb8" },
+ { 0x2169, "\xe2\x85\xb9" },
+ { 0x216a, "\xe2\x85\xba" },
+ { 0x216b, "\xe2\x85\xbb" },
+ { 0x216c, "\xe2\x85\xbc" },
+ { 0x216d, "\xe2\x85\xbd" },
+ { 0x216e, "\xe2\x85\xbe" },
+ { 0x216f, "\xe2\x85\xbf" },
+ { 0x24b6, "\xe2\x93\x90" },
+ { 0x24b7, "\xe2\x93\x91" },
+ { 0x24b8, "\xe2\x93\x92" },
+ { 0x24b9, "\xe2\x93\x93" },
+ { 0x24ba, "\xe2\x93\x94" },
+ { 0x24bb, "\xe2\x93\x95" },
+ { 0x24bc, "\xe2\x93\x96" },
+ { 0x24bd, "\xe2\x93\x97" },
+ { 0x24be, "\xe2\x93\x98" },
+ { 0x24bf, "\xe2\x93\x99" },
+ { 0x24c0, "\xe2\x93\x9a" },
+ { 0x24c1, "\xe2\x93\x9b" },
+ { 0x24c2, "\xe2\x93\x9c" },
+ { 0x24c3, "\xe2\x93\x9d" },
+ { 0x24c4, "\xe2\x93\x9e" },
+ { 0x24c5, "\xe2\x93\x9f" },
+ { 0x24c6, "\xe2\x93\xa0" },
+ { 0x24c7, "\xe2\x93\xa1" },
+ { 0x24c8, "\xe2\x93\xa2" },
+ { 0x24c9, "\xe2\x93\xa3" },
+ { 0x24ca, "\xe2\x93\xa4" },
+ { 0x24cb, "\xe2\x93\xa5" },
+ { 0x24cc, "\xe2\x93\xa6" },
+ { 0x24cd, "\xe2\x93\xa7" },
+ { 0x24ce, "\xe2\x93\xa8" },
+ { 0x24cf, "\xe2\x93\xa9" },
+ { 0xfb00, "\x66\x66" },
+ { 0xfb01, "\x66\x69" },
+ { 0xfb02, "\x66\x6c" },
+ { 0xfb03, "\x66\x66\x69" },
+ { 0xfb04, "\x66\x66\x6c" },
+ { 0xfb05, "\x73\x74" },
+ { 0xfb06, "\x73\x74" },
+ { 0xfb13, "\xd5\xb4\xd5\xb6" },
+ { 0xfb14, "\xd5\xb4\xd5\xa5" },
+ { 0xfb15, "\xd5\xb4\xd5\xab" },
+ { 0xfb16, "\xd5\xbe\xd5\xb6" },
+ { 0xfb17, "\xd5\xb4\xd5\xad" },
+};
+
+static const struct {
+ gunichar ch;
+ gunichar mirrored_ch;
+} bidi_mirroring_table[] =
+{
+ { 0x0028, 0x0029 },
+ { 0x0029, 0x0028 },
+ { 0x003c, 0x003e },
+ { 0x003e, 0x003c },
+ { 0x005b, 0x005d },
+ { 0x005d, 0x005b },
+ { 0x007b, 0x007d },
+ { 0x007d, 0x007b },
+ { 0x00ab, 0x00bb },
+ { 0x00bb, 0x00ab },
+ { 0x2039, 0x203a },
+ { 0x203a, 0x2039 },
+ { 0x2045, 0x2046 },
+ { 0x2046, 0x2045 },
+ { 0x207d, 0x207e },
+ { 0x207e, 0x207d },
+ { 0x208d, 0x208e },
+ { 0x208e, 0x208d },
+ { 0x2208, 0x220b },
+ { 0x2209, 0x220c },
+ { 0x220a, 0x220d },
+ { 0x220b, 0x2208 },
+ { 0x220c, 0x2209 },
+ { 0x220d, 0x220a },
+ { 0x2215, 0x29f5 },
+ { 0x223c, 0x223d },
+ { 0x223d, 0x223c },
+ { 0x2243, 0x22cd },
+ { 0x2252, 0x2253 },
+ { 0x2253, 0x2252 },
+ { 0x2254, 0x2255 },
+ { 0x2255, 0x2254 },
+ { 0x2264, 0x2265 },
+ { 0x2265, 0x2264 },
+ { 0x2266, 0x2267 },
+ { 0x2267, 0x2266 },
+ { 0x2268, 0x2269 },
+ { 0x2269, 0x2268 },
+ { 0x226a, 0x226b },
+ { 0x226b, 0x226a },
+ { 0x226e, 0x226f },
+ { 0x226f, 0x226e },
+ { 0x2270, 0x2271 },
+ { 0x2271, 0x2270 },
+ { 0x2272, 0x2273 },
+ { 0x2273, 0x2272 },
+ { 0x2274, 0x2275 },
+ { 0x2275, 0x2274 },
+ { 0x2276, 0x2277 },
+ { 0x2277, 0x2276 },
+ { 0x2278, 0x2279 },
+ { 0x2279, 0x2278 },
+ { 0x227a, 0x227b },
+ { 0x227b, 0x227a },
+ { 0x227c, 0x227d },
+ { 0x227d, 0x227c },
+ { 0x227e, 0x227f },
+ { 0x227f, 0x227e },
+ { 0x2280, 0x2281 },
+ { 0x2281, 0x2280 },
+ { 0x2282, 0x2283 },
+ { 0x2283, 0x2282 },
+ { 0x2284, 0x2285 },
+ { 0x2285, 0x2284 },
+ { 0x2286, 0x2287 },
+ { 0x2287, 0x2286 },
+ { 0x2288, 0x2289 },
+ { 0x2289, 0x2288 },
+ { 0x228a, 0x228b },
+ { 0x228b, 0x228a },
+ { 0x228f, 0x2290 },
+ { 0x2290, 0x228f },
+ { 0x2291, 0x2292 },
+ { 0x2292, 0x2291 },
+ { 0x2298, 0x29b8 },
+ { 0x22a2, 0x22a3 },
+ { 0x22a3, 0x22a2 },
+ { 0x22a6, 0x2ade },
+ { 0x22a8, 0x2ae4 },
+ { 0x22a9, 0x2ae3 },
+ { 0x22ab, 0x2ae5 },
+ { 0x22b0, 0x22b1 },
+ { 0x22b1, 0x22b0 },
+ { 0x22b2, 0x22b3 },
+ { 0x22b3, 0x22b2 },
+ { 0x22b4, 0x22b5 },
+ { 0x22b5, 0x22b4 },
+ { 0x22b6, 0x22b7 },
+ { 0x22b7, 0x22b6 },
+ { 0x22c9, 0x22ca },
+ { 0x22ca, 0x22c9 },
+ { 0x22cb, 0x22cc },
+ { 0x22cc, 0x22cb },
+ { 0x22cd, 0x2243 },
+ { 0x22d0, 0x22d1 },
+ { 0x22d1, 0x22d0 },
+ { 0x22d6, 0x22d7 },
+ { 0x22d7, 0x22d6 },
+ { 0x22d8, 0x22d9 },
+ { 0x22d9, 0x22d8 },
+ { 0x22da, 0x22db },
+ { 0x22db, 0x22da },
+ { 0x22dc, 0x22dd },
+ { 0x22dd, 0x22dc },
+ { 0x22de, 0x22df },
+ { 0x22df, 0x22de },
+ { 0x22e0, 0x22e1 },
+ { 0x22e1, 0x22e0 },
+ { 0x22e2, 0x22e3 },
+ { 0x22e3, 0x22e2 },
+ { 0x22e4, 0x22e5 },
+ { 0x22e5, 0x22e4 },
+ { 0x22e6, 0x22e7 },
+ { 0x22e7, 0x22e6 },
+ { 0x22e8, 0x22e9 },
+ { 0x22e9, 0x22e8 },
+ { 0x22ea, 0x22eb },
+ { 0x22eb, 0x22ea },
+ { 0x22ec, 0x22ed },
+ { 0x22ed, 0x22ec },
+ { 0x22f0, 0x22f1 },
+ { 0x22f1, 0x22f0 },
+ { 0x22f2, 0x22fa },
+ { 0x22f3, 0x22fb },
+ { 0x22f4, 0x22fc },
+ { 0x22f6, 0x22fd },
+ { 0x22f7, 0x22fe },
+ { 0x22fa, 0x22f2 },
+ { 0x22fb, 0x22f3 },
+ { 0x22fc, 0x22f4 },
+ { 0x22fd, 0x22f6 },
+ { 0x22fe, 0x22f7 },
+ { 0x2308, 0x2309 },
+ { 0x2309, 0x2308 },
+ { 0x230a, 0x230b },
+ { 0x230b, 0x230a },
+ { 0x2329, 0x232a },
+ { 0x232a, 0x2329 },
+ { 0x2768, 0x2769 },
+ { 0x2769, 0x2768 },
+ { 0x276a, 0x276b },
+ { 0x276b, 0x276a },
+ { 0x276c, 0x276d },
+ { 0x276d, 0x276c },
+ { 0x276e, 0x276f },
+ { 0x276f, 0x276e },
+ { 0x2770, 0x2771 },
+ { 0x2771, 0x2770 },
+ { 0x2772, 0x2773 },
+ { 0x2773, 0x2772 },
+ { 0x2774, 0x2775 },
+ { 0x2775, 0x2774 },
+ { 0x27d5, 0x27d6 },
+ { 0x27d6, 0x27d5 },
+ { 0x27dd, 0x27de },
+ { 0x27de, 0x27dd },
+ { 0x27e2, 0x27e3 },
+ { 0x27e3, 0x27e2 },
+ { 0x27e4, 0x27e5 },
+ { 0x27e5, 0x27e4 },
+ { 0x27e6, 0x27e7 },
+ { 0x27e7, 0x27e6 },
+ { 0x27e8, 0x27e9 },
+ { 0x27e9, 0x27e8 },
+ { 0x27ea, 0x27eb },
+ { 0x27eb, 0x27ea },
+ { 0x2983, 0x2984 },
+ { 0x2984, 0x2983 },
+ { 0x2985, 0x2986 },
+ { 0x2986, 0x2985 },
+ { 0x2987, 0x2988 },
+ { 0x2988, 0x2987 },
+ { 0x2989, 0x298a },
+ { 0x298a, 0x2989 },
+ { 0x298b, 0x298c },
+ { 0x298c, 0x298b },
+ { 0x298d, 0x2990 },
+ { 0x298e, 0x298f },
+ { 0x298f, 0x298e },
+ { 0x2990, 0x298d },
+ { 0x2991, 0x2992 },
+ { 0x2992, 0x2991 },
+ { 0x2993, 0x2994 },
+ { 0x2994, 0x2993 },
+ { 0x2995, 0x2996 },
+ { 0x2996, 0x2995 },
+ { 0x2997, 0x2998 },
+ { 0x2998, 0x2997 },
+ { 0x29b8, 0x2298 },
+ { 0x29c0, 0x29c1 },
+ { 0x29c1, 0x29c0 },
+ { 0x29c4, 0x29c5 },
+ { 0x29c5, 0x29c4 },
+ { 0x29cf, 0x29d0 },
+ { 0x29d0, 0x29cf },
+ { 0x29d1, 0x29d2 },
+ { 0x29d2, 0x29d1 },
+ { 0x29d4, 0x29d5 },
+ { 0x29d5, 0x29d4 },
+ { 0x29d8, 0x29d9 },
+ { 0x29d9, 0x29d8 },
+ { 0x29da, 0x29db },
+ { 0x29db, 0x29da },
+ { 0x29f5, 0x2215 },
+ { 0x29f8, 0x29f9 },
+ { 0x29f9, 0x29f8 },
+ { 0x29fc, 0x29fd },
+ { 0x29fd, 0x29fc },
+ { 0x2a2b, 0x2a2c },
+ { 0x2a2c, 0x2a2b },
+ { 0x2a2d, 0x2a2c },
+ { 0x2a2e, 0x2a2d },
+ { 0x2a34, 0x2a35 },
+ { 0x2a35, 0x2a34 },
+ { 0x2a3c, 0x2a3d },
+ { 0x2a3d, 0x2a3c },
+ { 0x2a64, 0x2a65 },
+ { 0x2a65, 0x2a64 },
+ { 0x2a79, 0x2a7a },
+ { 0x2a7a, 0x2a79 },
+ { 0x2a7d, 0x2a7e },
+ { 0x2a7e, 0x2a7d },
+ { 0x2a7f, 0x2a80 },
+ { 0x2a80, 0x2a7f },
+ { 0x2a81, 0x2a82 },
+ { 0x2a82, 0x2a81 },
+ { 0x2a83, 0x2a84 },
+ { 0x2a84, 0x2a83 },
+ { 0x2a8b, 0x2a8c },
+ { 0x2a8c, 0x2a8b },
+ { 0x2a91, 0x2a92 },
+ { 0x2a92, 0x2a91 },
+ { 0x2a93, 0x2a94 },
+ { 0x2a94, 0x2a93 },
+ { 0x2a95, 0x2a96 },
+ { 0x2a96, 0x2a95 },
+ { 0x2a97, 0x2a98 },
+ { 0x2a98, 0x2a97 },
+ { 0x2a99, 0x2a9a },
+ { 0x2a9a, 0x2a99 },
+ { 0x2a9b, 0x2a9c },
+ { 0x2a9c, 0x2a9b },
+ { 0x2aa1, 0x2aa2 },
+ { 0x2aa2, 0x2aa1 },
+ { 0x2aa6, 0x2aa7 },
+ { 0x2aa7, 0x2aa6 },
+ { 0x2aa8, 0x2aa9 },
+ { 0x2aa9, 0x2aa8 },
+ { 0x2aaa, 0x2aab },
+ { 0x2aab, 0x2aaa },
+ { 0x2aac, 0x2aad },
+ { 0x2aad, 0x2aac },
+ { 0x2aaf, 0x2ab0 },
+ { 0x2ab0, 0x2aaf },
+ { 0x2ab3, 0x2ab4 },
+ { 0x2ab4, 0x2ab3 },
+ { 0x2abb, 0x2abc },
+ { 0x2abc, 0x2abb },
+ { 0x2abd, 0x2abe },
+ { 0x2abe, 0x2abd },
+ { 0x2abf, 0x2ac0 },
+ { 0x2ac0, 0x2abf },
+ { 0x2ac1, 0x2ac2 },
+ { 0x2ac2, 0x2ac1 },
+ { 0x2ac3, 0x2ac4 },
+ { 0x2ac4, 0x2ac3 },
+ { 0x2ac5, 0x2ac6 },
+ { 0x2ac6, 0x2ac5 },
+ { 0x2acd, 0x2ace },
+ { 0x2ace, 0x2acd },
+ { 0x2acf, 0x2ad0 },
+ { 0x2ad0, 0x2acf },
+ { 0x2ad1, 0x2ad2 },
+ { 0x2ad2, 0x2ad1 },
+ { 0x2ad3, 0x2ad4 },
+ { 0x2ad4, 0x2ad3 },
+ { 0x2ad5, 0x2ad6 },
+ { 0x2ad6, 0x2ad5 },
+ { 0x2ade, 0x22a6 },
+ { 0x2ae3, 0x22a9 },
+ { 0x2ae4, 0x22a8 },
+ { 0x2ae5, 0x22ab },
+ { 0x2aec, 0x2aed },
+ { 0x2aed, 0x2aec },
+ { 0x2af7, 0x2af8 },
+ { 0x2af8, 0x2af7 },
+ { 0x2af9, 0x2afa },
+ { 0x2afa, 0x2af9 },
+ { 0x3008, 0x3009 },
+ { 0x3009, 0x3008 },
+ { 0x300a, 0x300b },
+ { 0x300b, 0x300a },
+ { 0x300c, 0x300d },
+ { 0x300d, 0x300c },
+ { 0x300e, 0x300f },
+ { 0x300f, 0x300e },
+ { 0x3010, 0x3011 },
+ { 0x3011, 0x3010 },
+ { 0x3014, 0x3015 },
+ { 0x3015, 0x3014 },
+ { 0x3016, 0x3017 },
+ { 0x3017, 0x3016 },
+ { 0x3018, 0x3019 },
+ { 0x3019, 0x3018 },
+ { 0x301a, 0x301b },
+ { 0x301b, 0x301a },
+ { 0xff08, 0xff09 },
+ { 0xff09, 0xff08 },
+ { 0xff1c, 0xff1e },
+ { 0xff1e, 0xff1c },
+ { 0xff3b, 0xff3d },
+ { 0xff3d, 0xff3b },
+ { 0xff5b, 0xff5d },
+ { 0xff5d, 0xff5b },
+ { 0xff5f, 0xff60 },
+ { 0xff60, 0xff5f },
+ { 0xff62, 0xff63 },
+ { 0xff63, 0xff62 }
+};
+
+#endif /* CHARTABLES_H */
diff --git a/3rdparty/clucene/src/CLucene/config/repl_lltot.cpp b/3rdparty/clucene/src/CLucene/config/repl_lltot.cpp
new file mode 100644
index 000000000..05a63b887
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/repl_lltot.cpp
@@ -0,0 +1,47 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+
+TCHAR* lucene_i64tot(
+ int64_t value, /* [I] Value to be converted */
+ TCHAR* str, /* [O] Destination for the converted value */
+ int radix) /* [I] Number base for conversion */
+{
+ uint64_t val;
+ int negative;
+ TCHAR buffer[65];
+ TCHAR* pos;
+ int digit;
+
+ if (value < 0 && radix == 10) {
+ negative = 1;
+ val = -value;
+ } else {
+ negative = 0;
+ val = value;
+ } /* if */
+
+ pos = &buffer[64];
+ *pos = '\0';
+
+ do {
+ digit = val % radix;
+ val = val / radix;
+ if (digit < 10) {
+ *--pos = '0' + digit;
+ } else {
+ *--pos = 'a' + digit - 10;
+ } /* if */
+ } while (val != 0L);
+
+ if (negative) {
+ *--pos = '-';
+ } /* if */
+
+ _tcsncpy(str,pos,&buffer[64] - pos + 1); //needed for unicode to work
+ return str;
+}
diff --git a/3rdparty/clucene/src/CLucene/config/repl_tchar.h b/3rdparty/clucene/src/CLucene/config/repl_tchar.h
new file mode 100644
index 000000000..ba8aef5c6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/repl_tchar.h
@@ -0,0 +1,126 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _CL_HAVE_TCHAR_H
+#if defined(_UCS2)
+ #define TCHAR wchar_t
+
+ //note: descriptions with * in front have replacement functions
+
+ //formatting functions
+ #define _sntprintf swprintf //* make a formatted a string
+ #define _tprintf wprintf //* print a formatted string
+
+ //this one has no replacement functions yet, but it is only used in the tests
+ #define _vsntprintf vsnwprintf //* print a formatted string using variable arguments
+
+ //we are using the internal functions of the compiler here
+ //if LUCENE_USE_INTERNAL_CHAR_FUNCTIONS is defined, thesse
+ //will be replaced by internal functions
+ #define _istalnum iswalnum //* alpha/numeric char check
+ #define _istalpha iswalpha //* alpha char check
+ #define _istspace iswspace //* space char check
+ #define _istdigit iswdigit //* digit char check
+ #define _totlower towlower //* convert char to lower case
+ #define _totupper towupper //* convert char to lower case
+ #define _tcslwr wcslwr //* convert string to lower case
+
+ //these are the string handling functions
+ //we may need to create wide-character/multi-byte replacements for these
+ #define _tcscpy wcscpy //copy a string to another string
+ #define _tcsncpy wcsncpy //copy a specified amount of one string to another string.
+ #define _tcscat wcscat //copy a string onto the end of the other string
+ #define _tcschr wcschr //find location of one character
+ #define _tcsstr wcsstr //find location of a string
+ #define _tcslen wcslen //get length of a string
+ #define _tcscmp wcscmp //case sensitive compare two strings
+ #define _tcsncmp wcsncmp //case sensitive compare two strings
+ #define _tcscspn wcscspn //location of any of a set of character in a string
+
+ #ifdef _CL_HAVE_WCSICMP
+ #define _tcsicmp wcsicmp //* case insensitive compare two string
+ #else
+ #define _tcsicmp wcscasecmp //* case insensitive compare two string
+ #endif
+
+ //conversion functions
+ #define _tcstod wcstod //convert a string to a double
+ #ifdef _PA_RISC
+ #define _tcstoi64 __wcstoll //* convers a string to an 64bit bit integer
+ #else
+ #define _tcstoi64 wcstoll //* convers a string to an 64bit bit integer
+ #endif
+ #define _i64tot lltow //* converts a 64 bit integer to a string (with base)
+
+#else //if defined(_ASCII)
+ #define TCHAR char
+
+ //formatting functions
+ #define _sntprintf snprintf
+ #define _tprintf printf
+ #define _vsntprintf vsnprintf
+
+ //we are using the internal functions of the compiler here
+ //if LUCENE_USE_INTERNAL_CHAR_FUNCTIONS is defined, thesse
+ //will be replaced by internal functions
+ #define _istalnum isalnum
+ #define _istalpha isalpha
+ #define _istspace isspace
+ #define _istdigit isdigit
+ #define _totlower tolower
+ #define _totupper toupper
+ #define _tcslwr strlwr
+
+ //these are the string handling functions
+ #define _tcscpy strcpy
+ #define _tcsncpy strncpy
+ #define _tcscat strcat
+ #define _tcschr strchr
+ #define _tcsstr strstr
+ #define _tcslen strlen
+ #define _tcscmp strcmp
+ #define _tcsncmp strncmp
+ #define _tcsicmp strcasecmp
+ #define _tcscspn strcspn
+
+ //converstion methods
+ #define _tcstod strtod
+ #define _tcstoi64 strtoll
+ #define _i64tot lltoa
+#endif
+#else //HAVE_TCHAR_H
+ #include <tchar.h>
+
+#ifdef UNDER_CE
+#include <QString>
+#define _i64tot i64tot
+inline TCHAR* i64tot(__int64 value, TCHAR* str, int radix)
+{
+ QT_USE_NAMESPACE
+ _tcscpy(str, (TCHAR *) QString::number(value, radix).utf16());
+ return str;
+}
+
+#define _tcstoi64 tcstoi64
+inline __int64 tcstoi64(const TCHAR *nptr, TCHAR **endptr, int base)
+{
+ QT_USE_NAMESPACE
+ bool ok;
+ return QString::fromUtf16((ushort*) nptr).toInt(&ok, base);
+}
+
+#endif
+
+ //some tchar headers miss these...
+ #ifndef _tcstoi64
+ #if defined(_UCS2)
+ #define _tcstoi64 wcstoll //* convers a string to an 64bit bit integer
+ #else
+ #define _tcstoi64 strtoll
+ #endif
+ #endif
+
+#endif //HAVE_TCHAR_H
diff --git a/3rdparty/clucene/src/CLucene/config/repl_tcscasecmp.cpp b/3rdparty/clucene/src/CLucene/config/repl_tcscasecmp.cpp
new file mode 100644
index 000000000..1bee7b7a6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/repl_tcscasecmp.cpp
@@ -0,0 +1,21 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+
+#include "CLucene/StdHeader.h"
+
+int lucene_tcscasecmp(const TCHAR * sa, const TCHAR * sb){
+ TCHAR ca,cb;
+ if (sa == sb)
+ return 0;
+
+ do{
+ ca = _totlower( (*(sa++)) );
+ cb = _totlower( (*(sb++)) );
+ } while ( ca != L'\0' && (ca == cb) );
+
+ return (int)(ca - cb);
+}
diff --git a/3rdparty/clucene/src/CLucene/config/repl_tcslwr.cpp b/3rdparty/clucene/src/CLucene/config/repl_tcslwr.cpp
new file mode 100644
index 000000000..2ae6abca4
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/repl_tcslwr.cpp
@@ -0,0 +1,15 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+
+#include "CLucene/StdHeader.h"
+
+TCHAR* lucene_tcslwr( TCHAR* str )
+{
+ TCHAR* ret = str;
+ for ( ; *str; str++) *str = _totlower(*str);
+ return ret;
+}
diff --git a/3rdparty/clucene/src/CLucene/config/repl_tcstod.cpp b/3rdparty/clucene/src/CLucene/config/repl_tcstod.cpp
new file mode 100644
index 000000000..1fd4ca770
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/repl_tcstod.cpp
@@ -0,0 +1,23 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+
+#include "CLucene/StdHeader.h"
+
+#ifndef _ASCII
+double lucene_tcstod(const TCHAR *value, TCHAR **end){
+ int32_t len = _tcslen(value)+1;
+ char* avalue=_CL_NEWARRAY(char,len);
+ char* aend=NULL;
+ STRCPY_TtoA(avalue,value,len);
+
+ double ret = strtod(avalue,&aend);
+ *end=(TCHAR*)value+(aend-avalue);
+ _CLDELETE_CaARRAY(avalue);
+
+ return ret;
+}
+#endif
diff --git a/3rdparty/clucene/src/CLucene/config/repl_tcstoll.cpp b/3rdparty/clucene/src/CLucene/config/repl_tcstoll.cpp
new file mode 100644
index 000000000..246d66c80
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/repl_tcstoll.cpp
@@ -0,0 +1,46 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+
+#include "CLucene/StdHeader.h"
+
+int64_t lucene_tcstoi64(const TCHAR* str, TCHAR**end, int radix){
+ #define LUCENE_TCSTOI64_RADIX(x,r) ((x>=_T('0') && x<=_T('9'))?x-_T('0'):((x>=_T('a') && x<=_T('z'))?x-_T('a')+10:((x>=_T('A') && x<=_T('Z'))?x-_T('A')+10:1000)))
+
+ if (radix < 2 || radix > 36)
+ return 0;
+
+ /* Skip white space. */
+ while (_istspace (*str))
+ ++str;
+
+ int sign=1;
+ if ( str[0] == _T('+') )
+ str++;
+ else if ( str[0] == _T('-') ){
+ sign = -1;
+ str++;
+ }
+
+ *end=(TCHAR*)str;
+ long r = -1;
+ while ( (r=LUCENE_TCSTOI64_RADIX(*end[0],radix)) >=0 && r<radix )
+ (*end)++;
+
+ TCHAR* p = (*end)-1;
+ int64_t ret = 0;
+ int pos = 0;
+ for ( ;p>=str;p-- ){
+ int i=LUCENE_TCSTOI64_RADIX(p[0],radix);
+ if ( pos == 0 )
+ ret=i;
+ else
+ ret += (int64_t)pow((qreal)radix,(qreal)pos) * i; //todo: might be quicker with a different pow overload
+
+ pos++;
+ }
+ return sign*ret;
+}
diff --git a/3rdparty/clucene/src/CLucene/config/repl_tprintf.cpp b/3rdparty/clucene/src/CLucene/config/repl_tprintf.cpp
new file mode 100644
index 000000000..62cecb78b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/repl_tprintf.cpp
@@ -0,0 +1,149 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "CLucene/util/StringBuffer.h"
+
+#ifdef __CL_INCLUDE_TPRINTF
+
+CL_NS_USE(util)
+
+//print a variable argument to a stream
+//currently special number formatting is not supported. it is very minimalistic
+void lucene_vfnwprintf(StringBuffer* buffer, size_t count, const wchar_t * format, va_list& valist){
+ const wchar_t *iter = format;
+ StringBuffer* tmp = NULL;
+ if ( buffer == NULL )
+ tmp = _CLNEW StringBuffer;
+ else
+ tmp = buffer;
+
+ while (*iter)
+ {
+ while (*iter && *iter != '%')
+ {
+ tmp->appendChar(*iter++);
+ }
+ if (*iter == '%')
+ {
+ if (iter[1] == '%')
+ {
+ //just print a %
+ tmp->appendChar('%');
+ iter += 2;
+ continue;
+ }
+
+ iter++;
+ switch (*iter)
+ {
+ case 's':
+ {
+ //todo: this is faulty. it doesn't heed count
+
+ //print a string or null
+ TCHAR *wstr = va_arg(valist, TCHAR *);
+ if ( !wstr )
+ wstr = _T("(null)");
+
+ tmp->append(wstr);
+ iter++;
+ break;
+ }
+
+ case 'c':
+ tmp->appendChar((TCHAR)va_arg(valist, int));
+ iter++;
+ break;
+
+ default:
+ {
+ //todo: this is faulty. it doesn't heed count
+
+ if (*iter == 'p')
+ tmp->appendInt((int32_t)va_arg(valist, long));
+ else
+ {
+ if (*iter == 'a' || *iter == 'A' ||
+ *iter == 'e' || *iter == 'E' ||
+ *iter == 'f' || *iter == 'F' ||
+ *iter == 'g' || *iter == 'G')
+ tmp->appendFloat((qreal)va_arg(valist, double),8);
+ else if (*iter == 'd' || *iter == 'i' ){
+ tmp->appendInt((int32_t)va_arg(valist, int));
+ }else if (*iter == 'l' ){
+ TCHAR b[100];
+ _i64tot((int64_t)va_arg(valist, int64_t),b,10);
+ tmp->append(b);
+ }/*else{
+ TCHAR b[100];
+ _i64tot((int64_t)va_arg(valist, void*),b,10);
+ tmp->append(b);
+ }*/
+ }
+ iter++;
+ break;
+ }
+ }
+ }
+ }
+
+
+ if ( buffer == NULL ){
+ //we are supposed to be writing to the console
+#ifdef _UCS2
+ TCHAR* pointer = tmp->getBuffer();
+ char ob[MB_LEN_MAX];
+ size_t v;
+ size_t len = tmp->length();
+ for (size_t i=0;i<len;i++){
+ v = wctomb(ob,*pointer);
+ if ( v > 0 ){
+ ob[v]='\0';
+ fputs(ob,stdout);
+ }
+ pointer++;
+ }
+
+
+#else
+ fputs(tmp->getBuffer(),stdout);
+#endif
+ _CLDELETE(tmp);
+ }
+}
+
+//print a list of arguments to a string
+int lucene_snwprintf(wchar_t* strbuf, size_t count, const wchar_t * format, ...){
+ va_list ap;
+ va_start(ap, format);
+ StringBuffer buffer;
+ lucene_vfnwprintf(&buffer,count,format,ap);
+ va_end(ap);
+
+ size_t ret = min(count,(size_t)(buffer.length()+1));
+ _tcsncpy(strbuf,buffer.getBuffer(),ret);
+ return ret;
+}
+
+//print a list of arguments to the stdout
+void lucene_wprintf(const wchar_t * format, ...){
+ va_list ap;
+ va_start(ap, format);
+ lucene_vfnwprintf(NULL,LUCENE_INT32_MAX_SHOULDBE,format,ap);
+ va_end(ap);
+}
+
+//print a variable argument to a string
+int lucene_vsnwprintf(wchar_t * strbuf, size_t count, const wchar_t * format, va_list& ap){
+ StringBuffer buffer;
+ lucene_vfnwprintf(&buffer,count,format,ap);
+ int ret = min((int32_t)count,buffer.length()+1);
+ _tcsncpy(strbuf,buffer.getBuffer(),ret);
+ return ret;
+}
+
+#endif //__CL_INCLUDE_TPRINTF
diff --git a/3rdparty/clucene/src/CLucene/config/repl_wchar.h b/3rdparty/clucene/src/CLucene/config/repl_wchar.h
new file mode 100644
index 000000000..3e05c311c
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/repl_wchar.h
@@ -0,0 +1,121 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_repl_wchar_h
+#define _lucene_repl_wchar_h
+
+#ifdef _UCS2
+
+#ifndef _CL_HAVE_WCSCPY
+ //copy a string to another string
+ #error wcscpy is not defined, and a licensed replacement has not been written yet
+#endif
+
+#ifndef _CL_HAVE_WCSNCPY
+ //copy a specified amount of one string to another string.
+ #error wcsncpy is not defined, and a licensed replacement has not been written yet
+#endif
+
+#ifndef _CL_HAVE_WCSCAT
+ //copy a string onto the end of the other string
+ #error wcscat is not defined, and a licensed replacement has not been written yet
+#endif
+
+#ifndef _CL_HAVE_WCSCHR
+ //find location of one character
+ #error wcschr is not defined, and a licensed replacement has not been written yet
+#endif
+
+#ifndef _CL_HAVE_WCSSTR
+ //find location of a string
+ #error wcspy is not defined, and a licensed replacement has not been written yet
+#endif
+
+#ifndef _CL_HAVE_WCSLEN
+ //get length of a string
+ #error wcslen is not defined, and a licensed replacement has not been written yet
+#endif
+
+#ifndef _CL_HAVE_WCSCMP
+ //case sensitive compare two strings
+ #error wcscmp is not defined, and a licensed replacement has not been written yet
+#endif
+
+#ifndef _CL_HAVE_WCSNCMP
+ //case sensitive compare two strings of a specified length
+ #error wcsncmp is not defined, and a licensed replacement has not been written yet
+#endif
+
+#ifndef _CL_HAVE_WCSCSPN
+ //Return the length of the maximum initial segment
+ //of WCS which contains only wide-characters not in REJECT.
+ #error wcscspn is not defined, and a licensed replacement has not been written yet
+#endif
+
+#endif //_UCS2
+
+//string function replacements
+#if defined(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS) || (defined(_UCS2) && !defined(_CL_HAVE_WCSCASECMP)) || (defined(_ASCII) && !defined(_CL_HAVE_STRCASECMP))
+ int lucene_tcscasecmp(const TCHAR *, const TCHAR *);
+ #undef _tcsicmp
+ #define _tcsicmp lucene_tcscasecmp
+#endif
+#if defined(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS) || (defined(_UCS2) && !defined(_CL_HAVE_WCSLWR)) || (defined(_ASCII) && !defined(_CL_HAVE_STRLWR))
+ TCHAR* lucene_tcslwr( TCHAR* str );
+ #undef _tcslwr
+ #define _tcslwr lucene_tcslwr
+#endif
+
+//conversion functions
+#if (defined(_ASCII) && !defined(_CL_HAVE_LLTOA)) || (defined(_UCS2) && !defined(_CL_HAVE_LLTOW))
+ TCHAR* lucene_i64tot( int64_t value, TCHAR* str, int radix);
+ #undef _i64tot
+ #define _i64tot lucene_i64tot
+#endif
+#if (defined(_UCS2) && !defined(_CL_HAVE_WCSTOLL)) || (defined(_ASCII) && !defined(_CL_HAVE_STRTOLL))
+ int64_t lucene_tcstoi64(const TCHAR* str, TCHAR**end, int radix);
+ #undef _tcstoi64
+ #define _tcstoi64 lucene_tcstoi64
+#endif
+#if defined(_UCS2) && !defined(_CL_HAVE_WCSTOD)
+ double lucene_tcstod(const TCHAR *value, TCHAR **end);
+ #undef _tcstod
+ #define _tcstod lucene_tcstod
+#endif
+
+//printf functions
+#if defined(_UCS2) && (!defined(_CL_HAVE_SNWPRINTF) || defined(_CL_HAVE_SWPRINTF_BUG) )
+ #undef _sntprintf
+ #define _sntprintf lucene_snwprintf
+ int lucene_snwprintf(wchar_t* strbuf, size_t count, const wchar_t * format, ...);
+
+ #ifndef __CL_INCLUDE_TPRINTF
+ #define __CL_INCLUDE_TPRINTF
+ #endif
+#endif
+#if defined(_UCS2) && !defined(_CL_HAVE_WPRINTF)
+ #undef _tprintf
+ #define _tprintf lucene_wprintf
+ void lucene_wprintf(const wchar_t * format, ...);
+
+ #ifndef __CL_INCLUDE_TPRINTF
+ #define __CL_INCLUDE_TPRINTF
+ #endif
+#endif
+#if defined(_UCS2) && (!defined(_CL_HAVE_VSNWPRINTF) || defined(_CL_HAVE_SWPRINTF_BUG) )
+ #undef _vsntprintf
+ #define _vsntprintf lucene_vsnwprintf
+ int lucene_vsnwprintf(wchar_t * strbuf, size_t count, const wchar_t * format, va_list& ap);
+
+ #ifndef __CL_INCLUDE_TPRINTF
+ #define __CL_INCLUDE_TPRINTF
+ #endif
+#endif
+
+//todo: if _CL_HAVE_SNPRINTF_BUG fails(snprintf overflow),we should use our own
+//function. but we don't have it currently, and our functions are dubious anyway...
+
+#endif //end of _lucene_repl_wchar_h
diff --git a/3rdparty/clucene/src/CLucene/config/threadCSection.h b/3rdparty/clucene/src/CLucene/config/threadCSection.h
new file mode 100644
index 000000000..ab1842051
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/threadCSection.h
@@ -0,0 +1,71 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+//NOTE: do not include this file directly, it is included from lucene internally.
+
+#ifndef lucene_config_threadCSection_h
+#define lucene_config_threadCSection_h
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF(util)
+
+ #if !defined(LUCENE_USE_WINDOWS_H) && !defined(_WINDOWS_) && !defined(__MINGW32__)
+ //we have not explicity included windows.h and windows.h has
+ //not been included (check _WINDOWS_), then we must define
+ //our own definitions to the thread locking functions:
+ struct CRITICAL_SECTION
+ {
+ struct critical_section_debug * DebugInfo;
+ long LockCount;
+ long RecursionCount;
+ void * OwningThread;
+ void * LockSemaphore;
+ #if defined(_WIN64)
+ unsigned __int64 SpinCount;
+ #else
+ unsigned long SpinCount;
+ #endif
+ };
+ #endif
+
+ ///a windows implementation of the lock mutex
+ ///todo: boost has a InterlockedExchange way of locking too. More backwards compatible/faster???
+ class mutex_win32
+ {
+ private:
+ CRITICAL_SECTION mtx;
+ public:
+ mutex_win32(const mutex_win32& clone);
+ mutex_win32();
+ ~mutex_win32();
+ void lock();
+ void unlock();
+ };
+
+ class CLuceneThreadIdCompare
+ {
+ public:
+
+ enum
+ { // parameters for hash table
+ bucket_size = 4, // 0 < bucket_size
+ min_buckets = 8
+ }; // min_buckets = 2 ^^ N, 0 < N
+
+ bool operator()( DWORD t1, DWORD t2 ) const{
+ return t1 < t2;
+ }
+ };
+
+ #define _LUCENE_SLEEP(x) Sleep(x)
+ #define _LUCENE_THREADMUTEX CL_NS(util)::mutex_win32
+ #define _LUCENE_CURRTHREADID GetCurrentThreadId()
+ #define _LUCENE_THREADID_TYPE DWORD
+CL_NS_END
+
+#endif //lucene_config_threadCSection_h
diff --git a/3rdparty/clucene/src/CLucene/config/threadPthread.h b/3rdparty/clucene/src/CLucene/config/threadPthread.h
new file mode 100644
index 000000000..d0ed9c4c9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/threadPthread.h
@@ -0,0 +1,59 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+//NOTE: do not include this file directly, it is included from lucene internally.
+
+#ifndef lucene_config_threadPthread_h
+#define lucene_config_threadPthread_h
+
+#include <pthread.h>
+
+CL_NS_DEF(util)
+
+///a posix implementation of the lock mutex
+///todo: we need a spinlock implemenation for usage in reference counting
+class mutex_pthread
+{
+private:
+ pthread_mutex_t mtx;
+
+public:
+ mutex_pthread(const mutex_pthread& clone);
+ mutex_pthread();
+ ~mutex_pthread();
+ void lock();
+ void unlock();
+
+private:
+ #ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
+ pthread_t lockOwner;
+ unsigned int lockCount;
+ #endif
+};
+
+#define _LUCENE_SLEEP(x) usleep(x*1000) //_LUCENE_SLEEP should be in millis, usleep is in micros
+#define _LUCENE_THREADMUTEX CL_NS(util)::mutex_pthread
+#define _LUCENE_CURRTHREADID pthread_self()
+#define _LUCENE_THREADID_TYPE pthread_t
+
+class CLuceneThreadIdCompare
+{
+public:
+ enum
+ { // parameters for hash table
+ bucket_size = 4, // 0 < bucket_size
+ min_buckets = 8
+ }; // min_buckets = 2 ^^ N, 0 < N
+
+ bool operator()( pthread_t t1, pthread_t t2 ) const{
+ return t1 < t2;
+ }
+};
+
+
+CL_NS_END
+
+#endif //lucene_config_threadPthread_h
diff --git a/3rdparty/clucene/src/CLucene/config/threads.cpp b/3rdparty/clucene/src/CLucene/config/threads.cpp
new file mode 100644
index 000000000..427e58092
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/threads.cpp
@@ -0,0 +1,162 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+
+#ifndef _CL_DISABLE_MULTITHREADING
+CL_NS_DEF(util)
+
+
+mutexGuard::mutexGuard(const mutexGuard& clone){
+ //no autoclone
+ mrMutex = NULL;
+}
+mutexGuard::mutexGuard( _LUCENE_THREADMUTEX& rMutex ) :
+ mrMutex(&rMutex)
+{
+ mrMutex->lock();
+}
+mutexGuard::~mutexGuard()
+{
+ mrMutex->unlock();
+}
+
+#if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX)
+ //do nothing
+ #if defined(_LUCENE_PRAGMA_WARNINGS)
+ #pragma message ("==================Not implementing any thread mutex==================")
+ #else
+ #warning "==================Not implementing any thread mutex=================="
+ #endif
+
+
+
+#elif defined(_CL_HAVE_WIN32_THREADS)
+ #include "CLucene/config/threadCSection.h"
+
+ #if !defined(LUCENE_USE_WINDOWS_H) && !defined(_WINDOWS_)
+ //we have not explicity included windows.h and windows.h has
+ //not been included (check _WINDOWS_), then we must define
+ //our own definitions to the thread locking functions:
+ extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *);
+ extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *);
+ extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *);
+ extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *);
+ extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
+ #endif
+
+ mutex_win32::mutex_win32(const mutex_win32& clone){
+ InitializeCriticalSection(&mtx);
+ }
+ mutex_win32::mutex_win32()
+ {
+ InitializeCriticalSection(&mtx);
+ }
+
+ mutex_win32::~mutex_win32()
+ {
+ DeleteCriticalSection(&mtx);
+ }
+
+ void mutex_win32::lock()
+ {
+ EnterCriticalSection(&mtx);
+ }
+
+ void mutex_win32::unlock()
+ {
+ LeaveCriticalSection(&mtx);
+ }
+
+
+
+#elif defined(_CL_HAVE_PTHREAD)
+ #include "CLucene/config/threadPthread.h"
+
+ #ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
+ bool mutex_pthread_attr_initd=false;
+ pthread_mutexattr_t mutex_pthread_attr;
+ #endif
+
+ #ifdef _CL__CND_DEBUG
+ #define _CLPTHREAD_CHECK(c,m) CND_PRECONDITION(c==0,m)
+ #else
+ #define _CLPTHREAD_CHECK(c,m) c;
+ #endif
+
+ mutex_pthread::mutex_pthread(const mutex_pthread& clone){
+ #ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
+ _CLPTHREAD_CHECK(pthread_mutex_init(&mtx, &mutex_pthread_attr), "mutex_pthread(clone) constructor failed")
+ #else
+ #if defined(__hpux) && defined(_DECTHREADS_)
+ _CLPTHREAD_CHECK(pthread_mutex_init(&mtx, pthread_mutexattr_default), "mutex_pthread(clone) constructor failed")
+ #else
+ _CLPTHREAD_CHECK(pthread_mutex_init(&mtx, 0), "mutex_pthread(clone) constructor failed")
+ #endif
+ lockCount=0;
+ lockOwner=0;
+ #endif
+ }
+ mutex_pthread::mutex_pthread()
+ {
+ #ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
+ if ( mutex_pthread_attr_initd == false ){
+ pthread_mutexattr_init(&mutex_pthread_attr);
+ pthread_mutexattr_settype(&mutex_pthread_attr, PTHREAD_MUTEX_RECURSIVE);
+ mutex_pthread_attr_initd = true;
+ }
+ _CLPTHREAD_CHECK(pthread_mutex_init(&mtx, &mutex_pthread_attr), "mutex_pthread(clone) constructor failed")
+ #else
+ #if defined(__hpux) && defined(_DECTHREADS_)
+ _CLPTHREAD_CHECK(pthread_mutex_init(&mtx, pthread_mutexattr_default), "mutex_pthread(clone) constructor failed")
+ #else
+ _CLPTHREAD_CHECK(pthread_mutex_init(&mtx, 0), "mutex_pthread(clone) constructor failed")
+ #endif
+ lockCount=0;
+ lockOwner=0;
+ #endif
+ }
+
+ mutex_pthread::~mutex_pthread()
+ {
+ _CLPTHREAD_CHECK(pthread_mutex_destroy(&mtx), "~mutex_pthread destructor failed")
+ }
+
+ void mutex_pthread::lock()
+ {
+ #ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
+ pthread_t currentThread = pthread_self();
+ if( pthread_equal( lockOwner, currentThread ) ) {
+ ++lockCount;
+ } else {
+ _CLPTHREAD_CHECK(pthread_mutex_lock(&mtx), "mutex_pthread::lock")
+ lockOwner = currentThread;
+ lockCount = 1;
+ }
+ #else
+ _CLPTHREAD_CHECK(pthread_mutex_lock(&mtx), "mutex_pthread::lock")
+ #endif
+ }
+
+ void mutex_pthread::unlock()
+ {
+ #ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
+ --lockCount;
+ if( lockCount == 0 )
+ {
+ lockOwner = 0;
+ _CLPTHREAD_CHECK(pthread_mutex_unlock(&mtx), "mutex_pthread::unlock")
+ }
+ #else
+ _CLPTHREAD_CHECK(pthread_mutex_unlock(&mtx), "mutex_pthread::unlock")
+ #endif
+ }
+
+#endif //thread impl choice
+
+
+CL_NS_END
+#endif //!_CL_DISABLE_MULTITHREADING
diff --git a/3rdparty/clucene/src/CLucene/config/utf8.cpp b/3rdparty/clucene/src/CLucene/config/utf8.cpp
new file mode 100644
index 000000000..14ccf5aa9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/config/utf8.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 1999 Tom Tromey
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ *
+ ************************************************
+ * Also licensed with permission from Tom Tromey
+ * and Owen Taylor under the Apache license.
+ * Original location:
+ * http://cvs.gnome.org/viewcvs/glib/glib/gutf8.c?rev=1.50&view=log
+ ************************************************
+ *
+ * Copyright 2003-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ #include "CLucene/StdHeader.h"
+
+typedef unsigned long gunichar;
+typedef unsigned char guchar;
+
+#define UTF8_COMPUTE(Char, Mask, Len) \
+ if (Char < 128) \
+ { \
+ Len = 1; \
+ Mask = 0x7f; \
+ } \
+ else if ((Char & 0xe0) == 0xc0) \
+ { \
+ Len = 2; \
+ Mask = 0x1f; \
+ } \
+ else if ((Char & 0xf0) == 0xe0) \
+ { \
+ Len = 3; \
+ Mask = 0x0f; \
+ } \
+ else if ((Char & 0xf8) == 0xf0) \
+ { \
+ Len = 4; \
+ Mask = 0x07; \
+ } \
+ else if ((Char & 0xfc) == 0xf8) \
+ { \
+ Len = 5; \
+ Mask = 0x03; \
+ } \
+ else if ((Char & 0xfe) == 0xfc) \
+ { \
+ Len = 6; \
+ Mask = 0x01; \
+ } \
+ else \
+ Len = -1;
+
+/*#define UTF8_LENGTH(Char) \
+ ((Char) < 0x80 ? 1 : \
+ ((Char) < 0x800 ? 2 : \
+ ((Char) < 0x10000 ? 3 : \
+ ((Char) < 0x200000 ? 4 : \
+ ((Char) < 0x4000000 ? 5 : 6)))))*/
+
+
+#define UTF8_GET(Result, Chars, Count, Mask, Len) \
+ (Result) = (Chars)[0] & (Mask); \
+ for ((Count) = 1; (Count) < (Len); ++(Count)) \
+ { \
+ if (((Chars)[(Count)] & 0xc0) != 0x80) \
+ { \
+ (Result) = -1; \
+ break; \
+ } \
+ (Result) <<= 6; \
+ (Result) |= ((Chars)[(Count)] & 0x3f); \
+ }
+
+
+/**
+ * lucene_wctoutf8:
+ * @c: a ISO10646 character code
+ * @outbuf: output buffer, must have at least 6 bytes of space.
+ * If %NULL, the length will be computed and returned
+ * and nothing will be written to @outbuf.
+ *
+ * Converts a single character to UTF-8.
+ *
+ * Return value: number of bytes written
+ **/
+size_t lucene_wctoutf8(char * outbuf, const wchar_t ch)
+{
+ gunichar c = ch;
+ guchar len = 0;
+ int first;
+ int i;
+
+ if (c < 0x80)
+ {
+ first = 0;
+ len = 1;
+ }
+ else if (c < 0x800)
+ {
+ first = 0xc0;
+ len = 2;
+ }
+ else if (c < 0x10000)
+ {
+ first = 0xe0;
+ len = 3;
+ }
+ else if (c < 0x200000)
+ {
+ first = 0xf0;
+ len = 4;
+ }
+ else if (c < 0x4000000)
+ {
+ first = 0xf8;
+ len = 5;
+ }
+ else
+ {
+ first = 0xfc;
+ len = 6;
+ }
+
+ if (outbuf)
+ {
+ for (i = len - 1; i > 0; --i)
+ {
+ outbuf[i] = (char)((c & 0x3f) | 0x80);
+ c >>= 6;
+ }
+ outbuf[0] = c | first;
+ }
+
+ return len;
+}
+
+
+/**
+ * lucene_utf8towc:
+ * @p: a pointer to Unicode character encoded as UTF-8
+ *
+ * Converts a sequence of bytes encoded as UTF-8 to a Unicode character.
+ * If @p does not point to a valid UTF-8 encoded character, results are
+ * undefined. If you are not sure that the bytes are complete
+ * valid Unicode characters, you should use lucene_utf8towc_validated()
+ * instead.
+ *
+ * Return value: the resulting character
+ **/
+size_t lucene_utf8towc(wchar_t *pwc, const char *p, size_t n)
+{
+ int i, mask = 0;
+ int result;
+ unsigned char c = (unsigned char) *p;
+ int len=0;
+
+ UTF8_COMPUTE (c, mask, len);
+ if (len == -1)
+ return 0;
+ UTF8_GET (result, p, i, mask, len);
+
+ *pwc = result;
+ return len;
+}
+
+
+//this function was not taken from gnome
+size_t lucene_wcstoutf8(char * result, const wchar_t * str, size_t result_length){
+ char *p=result;
+ int i = 0;
+
+ while (p < result + result_length-1 && str[i] != 0)
+ p += lucene_wctoutf8(p,str[i++]);
+
+ *p = '\0';
+
+ return p-result;
+}
+//this function was not taken from gnome
+size_t lucene_utf8towcs(wchar_t * result, const char * str, size_t result_length){
+ char *sp = (char*)str;
+ wchar_t *rp = result;
+ int i = 0;
+
+ while (rp < result + result_length && *sp!=0){
+ size_t r = lucene_utf8towc(rp,sp,6);
+ if ( r == -1 )
+ return 0;
+ sp += r;
+ rp++;
+ }
+
+ if ( sp-str < result_length )
+ *rp = '\0';
+
+ size_t ret = sp-str;
+ return ret;
+}
+//get the number of bytes that make up the utf8 character.
+//this function was not taken from gnome
+size_t lucene_utf8charlen(const char *p)
+{
+ int mask = 0;
+ int len=0;
+ unsigned char c = (unsigned char) *p;
+
+ UTF8_COMPUTE (c, mask, len);
+ return len;
+}
diff --git a/3rdparty/clucene/src/CLucene/debug/condition.cpp b/3rdparty/clucene/src/CLucene/debug/condition.cpp
new file mode 100644
index 000000000..855419451
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/debug/condition.cpp
@@ -0,0 +1,80 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "condition.h"
+#include "CLucene/util/Misc.h"
+#ifdef _CL__CND_DEBUG
+
+#define __CND_STR_PRECONDITION "PRECONDITION"
+#define __CND_STR_CONDITION "CONDITION"
+#define __CND_STR_WARNING "WARNING"
+#define __CND_STR_MESSAGE "MESSAGE"
+#define __CND_STR_DEBUGMESSAGE "DEBUG MESSAGE"
+#define __CND_STR_EXIT "EXIT"
+
+#ifndef _CND_DEBUG_DONTIMPLEMENT_OUTDEBUG
+void _Cnd_OutDebug( const char* FormattedMsg, const char* StrTitle, const char* File, int32_t Line, int32_t Title, const char* Mes2, int32_t fatal ){
+ #ifdef __WINDOWS_H
+ /*Display a standard messagebox*/
+ MessageBox(NULL, FormattedMsg, StrTitle, (fatal==1 ? MB_ICONSTOP:MB_ICONEXCLAMATION) | MB_OK | MB_TASKMODAL);
+ #else
+ printf("%s\n",FormattedMsg);
+ #endif
+
+ #if defined(_CND_DEBUG_WARN_DEBUGGER) /*attempt to signal windows debugger*/
+ OutputDebugString(FormattedMsg);
+ DebugBreak(); /*Position debugger just before exit program*/
+ #endif
+
+ if ( fatal )
+ debugFatalExit(1);
+}
+#endif
+
+void __cnd_FormatDebug( const char* File, int32_t Line, int32_t Title, const char* Mes2, int32_t fatal ) {
+ char M[512];
+ char* StrTitle = NULL;
+
+ if( Mes2 )
+ _snprintf(M,512,"file:%s line:%d\n%s",File,Line,Mes2);
+ else
+ _snprintf(M,512,"file:%s line:%d",File,Line);
+
+ /*Determine which title to use*/
+ switch( Title ) {
+ case CND_STR_PRECONDITION: {
+ StrTitle = __CND_STR_PRECONDITION;
+ break;
+ }
+ case CND_STR_CONDITION: {
+ StrTitle = __CND_STR_CONDITION;
+ break;
+ }
+ case CND_STR_WARNING: {
+ StrTitle = __CND_STR_WARNING;
+ break;
+ }
+ case CND_STR_MESSAGE: {
+ StrTitle = __CND_STR_MESSAGE;
+ break;
+ }
+ case CND_STR_DEBUGMESSAGE: {
+ StrTitle = __CND_STR_DEBUGMESSAGE;
+ break;
+ }
+ case CND_STR_EXIT: {
+ StrTitle = __CND_STR_EXIT;
+ break;
+ }
+ default:
+ break;
+ }/*switch*/
+
+ _Cnd_OutDebug(M, StrTitle, File, Line, Title, Mes2, fatal);
+}
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/debug/condition.h b/3rdparty/clucene/src/CLucene/debug/condition.h
new file mode 100644
index 000000000..ab227e508
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/debug/condition.h
@@ -0,0 +1,64 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef __CONDITION_H
+#define __CONDITION_H
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+/*
+To enable condition debugging uncomment _CND_DEBUG in CLConfig.h
+*/
+
+#ifdef _CL__CND_DEBUG /* Don't include the debug code */
+ #ifndef CND_STR_DEFINES
+ #define CND_STR_DEFINES
+ #define CND_STR_PRECONDITION 1
+ #define CND_STR_CONDITION 2
+ #define CND_STR_WARNING 3
+ #define CND_STR_MESSAGE 4
+ #define CND_STR_DEBUGMESSAGE 5
+ #define CND_STR_EXIT 6
+ #endif
+
+ /* _CL__CND_DEBUG defined, include debug code */
+
+ #ifdef _CND_NODEBUGTEXT
+ #define CND_PRECONDITION(cond,usermessage) CND__EXITCONDITION(cond,__FILE__,__LINE__,CND_STR_PRECONDITION,NULL)
+ #define CND_CONDITION(cond,usermessage) CND__EXITCONDITION(cond,__FILE__,__LINE__,CND_STR_CONDITION,NULL)
+ #define CND_WARNING(cond,usermessage) CND__CONDITION(cond,__FILE__,__LINE__,CND_STR_WARNING,NULL)
+ #define CND_MESSAGE(cond,usermessage) CND__CONDITION(cond,__FILE__,__LINE__,CND_STR_MESSAGE,NULL)
+ #define CND_DEBUGMESSAGE(usermessage) CND__MESSAGE(__FILE__,__LINE__,CND_STR_DEBUGMESSAGE,NULL)
+ #else
+ #define CND_PRECONDITION(cond,usermessage) CND__EXITCONDITION(cond,__FILE__,__LINE__,CND_STR_PRECONDITION,usermessage)
+ #define CND_CONDITION(cond,usermessage) CND__EXITCONDITION(cond,__FILE__,__LINE__,CND_STR_CONDITION,usermessage)
+ #define CND_WARNING(cond,usermessage) CND__CONDITION(cond,__FILE__,__LINE__,CND_STR_WARNING,usermessage)
+ #define CND_MESSAGE(cond,usermessage) CND__CONDITION(cond,__FILE__,__LINE__,CND_STR_MESSAGE,usermessage)
+ #define CND_DEBUGMESSAGE(usermessage) CND__MESSAGE(__FILE__,__LINE__,CND_STR_DEBUGMESSAGE,usermessage)
+ #endif
+
+ //if _CND_DEBUG_DONTIMPLEMENT_OUTDEBUG is defined, then you must implement
+ //this routine in the client application. The debug callback can then
+ //be better customised to the host application.
+ //Here is the default implementation:
+ void _Cnd_OutDebug( const char* FormattedMsg, const char* StrTitle, const char* File, int32_t Line, int32_t Title, const char* Mes2, int32_t fatal );
+
+ void __cnd_FormatDebug( const char* File, int32_t Line, int32_t Title, const char* Mes2, int32_t fatal );
+ #define CND__EXIT(file,line,title,mes2) {__cnd_FormatDebug(file,line,title,mes2,1);}
+ #define CND__EXITCONDITION(cond,file,line,title,mes2) {if(!(cond)){__cnd_FormatDebug(file,line,title,mes2,1);}}
+ #define CND__CONDITION(cond,file,line,title,mes2) {if(!(cond)){__cnd_FormatDebug(file,line,title,mes2,0);}}
+ #define CND__MESSAGE(file,line,title,mes2) {__cnd_FormatDebug(file,line,title,mes2,0);}
+#else
+ #define CND_PRECONDITION(cond, usermessage)
+ #define CND_CONDITION(cond, usermessage)
+ #define CND_WARNING(cond,usermessage)
+ #define CND_MESSAGE(cond,usermessage)
+ #define CND_DEBUGMESSAGE(usermessage)
+#endif
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/debug/error.cpp b/3rdparty/clucene/src/CLucene/debug/error.cpp
new file mode 100644
index 000000000..53ea0e93b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/debug/error.cpp
@@ -0,0 +1,73 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+
+CL_NS_USE(util)
+
+
+#ifdef _LUCENE_DISABLE_EXCEPTIONS
+ #ifdef _LUCENE_PRAGMA_WARNINGS
+ #pragma message ("==================Lucene exceptions are disabled==================")
+ #else
+ #warning "==================Lucene exceptions are disabled=================="
+ #endif
+#else
+ CLuceneError::CLuceneError(int num, const char* str, bool ownstr)
+ {
+ error_number = num;
+ _awhat=STRDUP_AtoA(str);
+ _twhat=NULL;
+ if ( ownstr )
+ _CLDELETE_CaARRAY(str);
+ }
+
+ CLuceneError::CLuceneError(const CLuceneError& clone)
+ {
+ this->error_number = clone.error_number;
+ this->_awhat = NULL;
+ this->_twhat = NULL;
+
+ if ( clone._awhat != NULL )
+ this->_awhat = STRDUP_AtoA(clone._awhat);
+ if ( clone._twhat != NULL )
+ this->_twhat = STRDUP_TtoT(clone._twhat);
+ }
+ CLuceneError::~CLuceneError() throw(){
+ _CLDELETE_CARRAY(_twhat);
+ _CLDELETE_CaARRAY(_awhat);
+ }
+ char* CLuceneError::what(){
+#ifdef _ASCII
+ if ( _twhat != NULL )
+ return _twhat;
+#endif
+ if ( _awhat == NULL )
+ _awhat = STRDUP_TtoA(_twhat);
+ return _awhat;
+ }
+ TCHAR* CLuceneError::twhat(){
+#ifdef _ASCII
+ if ( _awhat != NULL )
+ return _awhat;
+#endif
+ if ( _twhat == NULL )
+ _twhat = STRDUP_AtoT(_awhat);
+ return _twhat;
+ }
+
+#ifndef _ASCII
+ CLuceneError::CLuceneError(int num, const TCHAR* str, bool ownstr)
+ {
+ error_number = 0;
+ _awhat=NULL;
+ _twhat=STRDUP_TtoT(str);
+ if ( ownstr )
+ _CLDELETE_CARRAY(str);
+ }
+#endif
+
+#endif //_LUCENE_DISABLE_EXCEPTIONS
diff --git a/3rdparty/clucene/src/CLucene/debug/error.h b/3rdparty/clucene/src/CLucene/debug/error.h
new file mode 100644
index 000000000..5abcc802c
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/debug/error.h
@@ -0,0 +1,74 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_debug_error_
+#define _lucene_debug_error_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#define CL_ERR_UNKNOWN -1
+#define CL_ERR_IO 1
+#define CL_ERR_NullPointer 2
+#define CL_ERR_Runtime 3
+#define CL_ERR_IllegalArgument 4
+#define CL_ERR_Parse 5
+#define CL_ERR_TokenMgr 6
+#define CL_ERR_UnsupportedOperation 7
+#define CL_ERR_InvalidState 8
+#define CL_ERR_IndexOutOfBounds 9
+#define CL_ERR_TooManyClauses 10
+#define CL_ERR_RAMTransaction 11
+#define CL_ERR_InvalidCast 12
+#define CL_ERR_IllegalState 13
+
+
+
+////////////////////////////////////////////////////////
+//error try/throw/catch definitions
+////////////////////////////////////////////////////////
+#ifdef _CL_DISABLE_NATIVE_EXCEPTIONS
+ /*#define try _jpr_Try
+ #define _CLCATCH _jpr_Catch
+ #define _CLFINALLY(x) xxxx
+ #define _CLTHROWA(y) _jpr_Throw
+ #define _THROWA_DEL(y) _jpr_Throw
+ #define _RETHROW(x) _jpr_Throw
+ #define _CLTHROWT(y) _jpr_Throw
+
+ #define _THROWS ,_jpr_Throws*/
+#else
+ class CLuceneError
+ {
+ int error_number;
+ char* _awhat;
+ TCHAR* _twhat;
+ public:
+ CLuceneError(const CLuceneError& clone);
+ CLuceneError(int num, const char* str, bool ownstr);
+#ifdef _UCS2
+ CLuceneError(int num, const TCHAR* str, bool ownstr);
+#endif
+ int number(){return error_number;}
+ char* what();
+ TCHAR* twhat();
+ ~CLuceneError() throw();
+ };
+
+ //#define _THROWS //does nothing
+ #define _CLFINALLY(x) catch(...){ x; throw; } x //note: code x is not run if return is called
+ #define _CLTHROWA(number, str) throw CLuceneError(number, str,false)
+ #define _CLTHROWT(number, str) throw CLuceneError(number, str,false)
+ #define _CLTHROWA_DEL(number, str) throw CLuceneError(number, str,true) //throw a string ensures the value is deleted
+ #define _CLTHROWT_DEL(number, str) throw CLuceneError(number, str,true) //throw a string ensures the value is deleted
+
+
+#endif //_LUCENE_DISABLE_EXCEPTIONS
+//
+////////////////////////////////////////////////////////
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/debug/lucenebase.h b/3rdparty/clucene/src/CLucene/debug/lucenebase.h
new file mode 100644
index 000000000..86cdae1c5
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/debug/lucenebase.h
@@ -0,0 +1,75 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_debug_lucenebase_
+#define _lucene_debug_lucenebase_
+
+#ifdef _LUCENE_PRAGMA_ONCE
+# pragma once
+#endif
+
+CL_NS_DEF(debug)
+
+//Lucenebase is the superclass of all clucene objects. It provides
+//memory debugging tracking and/or reference counting
+class LuceneBase{
+public:
+#ifdef LUCENE_ENABLE_MEMLEAKTRACKING
+ static void* operator new (size_t size);
+ static void operator delete (void *p);
+ int32_t __cl_initnum; ///< The order that the object was created at. This is then used to do a lookup in the objects list
+
+ static void* operator new (size_t size, char const * file, int32_t line);
+ static void operator delete (void *p, char const * file, int32_t line);
+
+ static void* __cl_voidpadd(void* data, const char* file, int line, size_t size); ///<add arbitary data to the lucenbase_list and returns the same data
+ static void __cl_voidpremove(const void* data, const char* file, int line);///<remove arbitary data to the lucenbase_list
+ static void __cl_unregister(const void* obj); ///<un register object from the mem leak and ref count system
+
+ static int32_t __cl_GetUnclosedObjectsCount(); ///< gets the number of unclosed objects
+ static const char* __cl_GetUnclosedObject(int32_t item); ///< get the name of the nth unclosed object
+ static char* __cl_GetUnclosedObjects(); ///< get a string with the names of the unclosed objects
+ static void __cl_PrintUnclosedObjects(); ///< print unclosed objects to the stdout
+
+ ///This will clear memory relating to refcounting
+ ///other tools can be used to more accurately identify
+ ///memory leaks. This should only be called just
+ ///before closing, and after retrieving the
+ ///unclosed object list
+ static void __cl_ClearMemory();
+
+#endif //LUCENE_ENABLE_MEMLEAKTRACKING
+
+ int __cl_refcount;
+ LuceneBase(){
+ __cl_refcount=1;
+ }
+ inline int __cl_getref(){
+ return __cl_refcount;
+ }
+ inline int __cl_addref(){
+ __cl_refcount++;
+ return __cl_refcount;
+ }
+ inline int __cl_decref(){
+ __cl_refcount--;
+ return __cl_refcount;
+ }
+ virtual ~LuceneBase(){};
+};
+
+class LuceneVoidBase{
+ public:
+ #ifdef _DEBUG
+ //a compile time check to make sure that _CLDELETE and _CLDECDELETE is being
+ //used correctly.
+ int dummy__see_mem_h_for_details;
+ #endif
+ virtual ~LuceneVoidBase(){};
+};
+
+CL_NS_END
+#endif //_lucene_debug_lucenebase_
diff --git a/3rdparty/clucene/src/CLucene/debug/mem.h b/3rdparty/clucene/src/CLucene/debug/mem.h
new file mode 100644
index 000000000..e15c3de8b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/debug/mem.h
@@ -0,0 +1,130 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_debug_mem_h
+#define _lucene_debug_mem_h
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "lucenebase.h"
+
+//Macro for creating new objects
+#if defined(LUCENE_ENABLE_MEMLEAKTRACKING)
+ #define _CLNEW new(__FILE__, __LINE__)
+ #define LUCENE_BASE public CL_NS(debug)::LuceneBase
+#elif defined(LUCENE_ENABLE_REFCOUNT)
+ #define _CLNEW new
+ #define LUCENE_BASE public CL_NS(debug)::LuceneBase
+#else
+ #define _CLNEW new
+ #define LUCENE_BASE public CL_NS(debug)::LuceneVoidBase
+ #define LUCENE_BASE_CHECK(obj) (obj)->dummy__see_mem_h_for_details
+#endif
+#define _CL_POINTER(x) (x==NULL?NULL:(x->__cl_addref()>=0?x:x)) //return a add-ref'd object
+#define LUCENE_REFBASE public CL_NS(debug)::LuceneBase //this is the base of classes who *always* need refcounting
+
+#if defined(_DEBUG)
+ #if !defined(LUCENE_BASE_CHECK)
+ #define LUCENE_BASE_CHECK(x)
+ #endif
+#else
+ #undef LUCENE_BASE_CHECK
+ #define LUCENE_BASE_CHECK(x)
+#endif
+
+//Macro for creating new arrays
+#ifdef LUCENE_ENABLE_MEMLEAKTRACKING
+ #define _CL_NEWARRAY(type,size) (type*)CL_NS(debug)::LuceneBase::__cl_voidpadd(new type[(size_t)size],__FILE__,__LINE__,(size_t)size);
+ #define _CLDELETE_ARRAY(x) if (x!=NULL){CL_NS(debug)::LuceneBase::__cl_voidpremove((const void*)x,__FILE__,__LINE__); delete [] x; x=NULL;}
+ #define _CLDELETE_LARRAY(x) if (x!=NULL){CL_NS(debug)::LuceneBase::__cl_voidpremove((const void*)x,__FILE__,__LINE__);delete [] x;}
+ #ifndef _CLDELETE_CARRAY
+ #define _CLDELETE_CARRAY(x) if (x!=NULL){CL_NS(debug)::LuceneBase::__cl_voidpremove((const void*)x,__FILE__,__LINE__);delete [] x; x=NULL;}
+ #define _CLDELETE_LCARRAY(x) if (x!=NULL){CL_NS(debug)::LuceneBase::__cl_voidpremove((const void*)x,__FILE__,__LINE__);delete [] x;}
+ #endif
+#else
+ #define _CL_NEWARRAY(type,size) new type[size]
+ #define _CLDELETE_ARRAY(x) if (x!=NULL){delete [] x; x=NULL;}
+ #define _CLDELETE_LARRAY(x) if (x!=NULL){delete [] x;}
+ #ifndef _CLDELETE_CARRAY
+ #define _CLDELETE_CARRAY(x) if (x!=NULL){delete [] x; x=NULL;}
+ #define _CLDELETE_LCARRAY(x) if (x!=NULL){delete [] x;}
+ #endif
+#endif
+//a shortcut for deleting a carray and all its contents
+#define _CLDELETE_CARRAY_ALL(x) {if ( x!=NULL ){ for(int xcda=0;x[xcda]!=NULL;xcda++)_CLDELETE_CARRAY(x[xcda]);}_CLDELETE_ARRAY(x)};
+#define _CLDELETE_ARRAY_ALL(x) {if ( x!=NULL ){ for(int xcda=0;x[xcda]!=NULL;xcda++)_CLDELETE(x[xcda]);}_CLDELETE_ARRAY(x)};
+#ifndef _CLDELETE_CaARRAY
+ #define _CLDELETE_CaARRAY _CLDELETE_CARRAY
+ #define _CLDELETE_LCaARRAY _CLDELETE_LCARRAY
+#endif
+
+//Macro for deleting
+#ifdef LUCENE_ENABLE_REFCOUNT
+ #define _CLDELETE(x) if (x!=NULL){ CND_PRECONDITION((x)->__cl_refcount>=0,"__cl_refcount was < 0"); if ((x)->__cl_decref() <= 0)delete x; x=NULL; }
+ #define _CLLDELETE(x) if (x!=NULL){ CND_PRECONDITION((x)->__cl_refcount>=0,"__cl_refcount was < 0"); if ((x)->__cl_decref() <= 0)delete x; }
+#else
+ #define _CLDELETE(x) if (x!=NULL){ LUCENE_BASE_CHECK(x); delete x; x=NULL; }
+ #define _CLLDELETE(x) if (x!=NULL){ LUCENE_BASE_CHECK(x); delete x; }
+#endif
+
+//_CLDECDELETE deletes objects which are *always* refcounted
+#define _CLDECDELETE(x) if (x!=NULL){ CND_PRECONDITION((x)->__cl_refcount>=0,"__cl_refcount was < 0"); if ((x)->__cl_decref() <= 0)delete x; x=NULL; }
+#define _CLLDECDELETE(x) if (x!=NULL){ CND_PRECONDITION((x)->__cl_refcount>=0,"__cl_refcount was < 0"); if ((x)->__cl_decref() <= 0)delete x; }
+
+//_VDelete should be used for deleting non-clucene objects.
+//when using reference counting, _CLDELETE casts the object
+//into a LuceneBase*.
+#define _CLVDELETE(x) if(x!=NULL){delete x; x=NULL;}
+
+template<typename T>
+class Array: LUCENE_BASE{
+public:
+ T* values;
+ size_t length;
+
+ void deleteAll(){
+ for (size_t i=0;i<length;i++)
+ _CLDELETE(values[i]);
+ _CLDELETE_ARRAY(values);
+ }
+ void deleteArray(){
+ _CLDELETE_ARRAY(values);
+ }
+
+ Array(){
+ values = NULL;
+ length = 0;
+ }
+ Array(T* values, size_t length){
+ this->values = values;
+ this->length = length;
+ }
+ Array(size_t length){
+ this->values = _CL_NEWARRAY(T,length);
+ this->length = length;
+ }
+ ~Array(){}
+
+ const T operator[](size_t _Pos) const
+ {
+ if (length <= _Pos){
+ _CLTHROWA(CL_ERR_IllegalArgument,"vector subscript out of range");
+ }
+ return (*(values + _Pos));
+ }
+ T operator[](size_t _Pos)
+ {
+ if (length <= _Pos){
+ _CLTHROWA(CL_ERR_IllegalArgument,"vector subscript out of range");
+ }
+ return (*(values + _Pos));
+ }
+
+};
+
+#endif //_lucene_debug_lucenebase_
diff --git a/3rdparty/clucene/src/CLucene/debug/memtracking.cpp b/3rdparty/clucene/src/CLucene/debug/memtracking.cpp
new file mode 100644
index 000000000..544a125a5
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/debug/memtracking.cpp
@@ -0,0 +1,371 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "CLucene/util/Misc.h"
+
+bool _lucene_disable_debuglogging = true; //if LUCENE_ENABLE_CONSTRUCTOR_LOG is on, dont do log if this is true
+bool _lucene_run_objectcheck = false; //run a memory check before deleting objects
+int _lucene_counter_break = -1; //to break at this item, change this
+ //and put break points at points below
+
+CL_NS_USE(util)
+CL_NS_DEF(debug)
+
+#ifdef LUCENE_ENABLE_MEMLEAKTRACKING
+int32_t _instance_counter = 0; //counter for initnumber
+
+struct _file{
+ int32_t refcount; ///times this has been used
+ char* value; ///reference to the the basefile
+}; //structure for name counting
+struct _pointers{
+ _file* file;
+ int32_t initline;
+ int32_t initnumber;
+};//structure for pointer-filename references
+
+typedef CL_NS(util)::CLSet<const char*,_file*,Compare::Char,Deletor::Dummy,Deletor::Void<_file> > defFile;
+typedef CL_NS(util)::CLSet<LuceneBase*,_pointers*,Compare::Void<LuceneBase>,Deletor::Dummy,Deletor::Void<_pointers> > defPointer;
+typedef CL_NS(util)::CLSet<const void*,_pointers*,Compare::Void<const void>,Deletor::Dummy,Deletor::Void<_pointers> > defVoid;
+
+DEFINE_MUTEX(memleak_lock)
+defFile LuceneBase_Files(false,true); //list of filenames used
+defPointer LuceneBase_Pointers(false,true); //list of pointers counted
+defVoid LuceneBase_Voids(false,true); //list of arbitary data added
+
+//variables to trim filenames to just the base names
+char _files_trim_string[CL_MAX_DIR];
+int32_t _files_trim_start=-1;
+
+//trim the filename and return the refcounted _file* structure
+_file* get_file(const char* file){
+ if ( _files_trim_start == -1 ){
+ //this trims the start of the name file name so
+ //that the whole of the filename is not stored - more asthetic :)
+ //need to find the base
+ _files_trim_start = strlen(__FILE__) - 21; //(length of debug/memtracking.cpp)
+ strcpy(_files_trim_string,__FILE__);
+ _files_trim_string[_files_trim_start] = 0;
+ }
+ if ( strncmp(file,_files_trim_string,_files_trim_start) == 0 ){
+ //this file should be within the same directory area as we found lucenebase.cpp
+ //to be, lets trim the start
+ file+=_files_trim_start;
+ }
+
+ //now return an existing files structure (with refcount++) or create a new one
+ defFile::iterator itr = LuceneBase_Files.find((const char*)file);
+ if ( itr != LuceneBase_Files.end() ){
+ _file* bf = itr->second;
+ bf->refcount++;
+ return bf;
+ }else{
+ _file* ref = new _file;
+ ref->value = new char[strlen(file)+1]; //cannot use _CL_NEWARRAY otherwise recursion
+ strcpy(ref->value,file);
+
+ ref->refcount = 1;
+ LuceneBase_Files.insert(pair<const char*,_file*>(ref->value,ref));
+ return ref;
+ }
+}
+
+void remove_file(_file* bf){
+ bf->refcount--;
+ if ( bf->refcount <= 0 ){
+ defFile::iterator fi = LuceneBase_Files.find(bf->value);
+ CND_PRECONDITION(fi!=LuceneBase_Files.end(),"fi==NULL");
+ delete[] bf->value;
+ LuceneBase_Files.removeitr(fi);
+ }
+}
+
+#ifdef LUCENE_ENABLE_CONSTRUCTOR_LOG
+ void constructor_log(const char* type,const char* file,const int line, const int size){
+ if ( _lucene_disable_debuglogging ){
+ FILE* f = fopen("clucene.log","a");
+ char buf[CL_MAX_DIR+5];
+ sprintf(buf,"%s,%s,%d,%d\n",type,file,line,size);
+ fwrite(buf,sizeof(char),strlen(buf),f);
+ fclose(f);
+ }
+ }
+ #define CONSTRUCTOR_LOG(type,file,line,size) constructor_log(type,file,line,size)
+#else
+ #define CONSTRUCTOR_LOG(type,file,line,size)
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// the _CLNEW&_CLDELETE new/delete operators
+////////////////////////////////////////////////////////////////////////////////
+void* LuceneBase::operator new (size_t size, const char * file, int32_t line)
+{
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ void* p = malloc (size);
+ LuceneBase* lb = (LuceneBase*)p;
+
+ //create the pointer struct
+ _file* br = get_file(file);
+ _pointers* bp = new _pointers;
+ bp->file = br;
+ bp->initnumber = _instance_counter++;
+ bp->initline = line;
+
+ //associate this object with the pointer
+ lb->__cl_initnum = bp->initnumber;
+
+ //break if necessary
+ if ( _lucene_counter_break == lb->__cl_initnum )
+ CLDebugBreak(); //put break point here
+
+ //add the pointer object
+ LuceneBase_Pointers.insert(pair<LuceneBase*,_pointers*>(lb, bp));
+
+ CONSTRUCTOR_LOG("newobj",file,line,size);
+ return p;
+}
+void LuceneBase::operator delete (void *p, char const * file, int32_t line)
+{
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ LuceneBase* lb=(LuceneBase*)p;
+
+ defPointer::iterator itr = LuceneBase_Pointers.find(lb);
+ if ( itr != LuceneBase_Pointers.end() ){
+ _pointers* bp = itr->second;
+ remove_file(bp->file);
+
+ LuceneBase_Pointers.removeitr(itr);
+ }else{
+ //break
+ }
+ free(p);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// the generic new/delete operators
+///////////////////////////////////////////////////////////////////////////
+void* LuceneBase::operator new (size_t size)
+{
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ void* p = malloc (size);
+ LuceneBase* lb = (LuceneBase*)p;
+
+ //create the pointer struct
+ _file* br = get_file("undefined");
+ _pointers* bp = new _pointers;
+ bp->file = br;
+ bp->initnumber = _instance_counter++;
+ bp->initline = -1;
+
+ //associate this object with the pointer
+ lb->__cl_initnum = bp->initnumber;
+
+ //break if necessary
+ if ( _lucene_counter_break == lb->__cl_initnum )
+ CLDebugBreak();
+
+ //add the pointer object
+ LuceneBase_Pointers.insert(pair<LuceneBase*,_pointers*>(lb,bp));
+
+ CONSTRUCTOR_LOG("newobj","unknown",-1,size);
+ return p;
+}
+void LuceneBase::operator delete (void *p)
+{
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ LuceneBase* lb=(LuceneBase*)p;
+
+ defPointer::iterator itr = LuceneBase_Pointers.find(lb);
+ if ( itr != LuceneBase_Pointers.end() ){
+ _pointers* bp = itr->second;
+ remove_file(bp->file);
+ LuceneBase_Pointers.removeitr(itr);
+ }else{
+ CLDebugBreak();
+ }
+ free(p);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// other memtracking functions
+///////////////////////////////////////////////////////////////////////////
+void LuceneBase::__cl_unregister(const void* obj){
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ LuceneBase* lb=(LuceneBase*)obj;
+ defPointer::iterator itr = LuceneBase_Pointers.find(lb);
+ CND_PRECONDITION(itr != LuceneBase_Pointers.end(),"__cl_unregister object not found");
+ _pointers* bp = itr->second;
+ LuceneBase_Pointers.removeitr(itr);
+}
+
+void* LuceneBase::__cl_voidpadd(void* data, const char* file, int line,size_t size){
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ _file* br = get_file(file);
+ _pointers* bp = new _pointers;
+ bp->file = br;
+ bp->initnumber = _instance_counter++;
+ bp->initline = line;
+
+ LuceneBase_Voids.insert(pair<void*,_pointers*>(data,bp));
+ CONSTRUCTOR_LOG("newarr",file,line,size);
+ return data;
+}
+void LuceneBase::__cl_voidpremove(const void* data, const char* file, int line){
+ SCOPED_LOCK_MUTEX(memleak_lock)
+ defVoid::iterator itr = LuceneBase_Voids.find(data);
+ if ( itr != LuceneBase_Voids.end() ){
+ _pointers* bp = itr->second;
+ remove_file(bp->file);
+ LuceneBase_Voids.removeitr(itr);
+ }else{
+ printf("Data deleted when not added with _CL_NEWARRAY in %s at %d\n",file,line);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+//The lucene base memory leak printout functions
+////////////////////////////////////////////////////////////
+//static
+void __internalcl_PrintUnclosedObject(bool isObject, string& sb,_pointers* bp,_file* bf, bool print){
+ TCHAR ttmp[100];
+ char atmp[100];
+
+ sb.append(" ");
+ {
+ _i64tot(bp->initnumber,ttmp,10);
+ STRCPY_TtoA(atmp,ttmp,100);
+ sb.append(atmp);
+ }
+ if ( isObject ){
+ sb.append("(obj). ");
+ }else{
+ sb.append(". ");
+ }
+ sb.append(bf->value);
+ sb.append(", line ");
+ {
+ _i64tot(bp->initline,ttmp,10);
+ STRCPY_TtoA(atmp,ttmp,100);
+ sb.append(atmp);
+ }
+ sb.append("\n");
+
+ if ( print && sb.length() > 0 ){
+ printf("%s\n", sb.c_str());
+ sb = "";
+ }
+}
+char* __internalcl_GetUnclosedObjects(bool print){
+ TCHAR ttmp[100];
+ char atmp[100];
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ string sb;
+ bool unknowns = false;
+ if ( LuceneBase_Pointers.size() > 0 ){
+ {
+ _i64tot(LuceneBase_Pointers.size(),ttmp,10);
+ STRCPY_TtoA(atmp,ttmp,100);
+ sb.append(atmp);
+ }
+ sb.append(" clucene objects are still open\n");
+
+ defPointer::iterator itr = LuceneBase_Pointers.begin();
+ while ( itr != LuceneBase_Pointers.end() ){
+ _pointers* bp = itr->second;
+ _file* bf = bp->file;
+
+ if ( bp->initline == -1 )
+ unknowns = true;
+ __internalcl_PrintUnclosedObject(true, sb,bp,bf,print);
+
+ ++itr;
+ }
+
+ defVoid::iterator itr2 = LuceneBase_Voids.begin();
+ while ( itr2 != LuceneBase_Voids.end() ){
+ _pointers* bp = itr2->second;
+ _file* bf = bp->file;
+
+ if ( bp->initline == -1 )
+ unknowns = true;
+ __internalcl_PrintUnclosedObject(false, sb,bp,bf,print);
+
+ itr2++;
+ }
+ }
+
+ if ( unknowns == true ){
+ sb.append("*** Some memory was not created with _CLNEW and was not tracked... ***\n");
+ sb.append("*** Use _CLNEW instead of new when creating CLucene objects ***\n");
+ sb.append("*** Memory may also have not been freed in the current context ***\n");
+ }
+
+ if ( print ){
+ if ( sb.length() > 0 ){
+ printf("%s\n", sb.c_str());
+ sb = "";
+ }
+ return NULL;
+ }else{
+ if ( sb.length() > 0 )
+ return STRDUP_AtoA(sb.c_str());
+ else
+ return NULL;
+ }
+}
+
+void LuceneBase::__cl_ClearMemory(){
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ while ( LuceneBase_Files.size() > 0 ){
+ defFile::iterator fi = LuceneBase_Files.begin();
+ _file* f = fi->second;
+ delete[] f->value;
+ LuceneBase_Files.removeitr (fi);
+ }
+ LuceneBase_Pointers.clear();
+ LuceneBase_Voids.clear();
+}
+char* LuceneBase::__cl_GetUnclosedObjects(){
+ return __internalcl_GetUnclosedObjects(false);
+}
+//static
+int32_t LuceneBase::__cl_GetUnclosedObjectsCount(){
+ return LuceneBase_Pointers.size();
+}
+
+const char* LuceneBase::__cl_GetUnclosedObject(int32_t item){
+ SCOPED_LOCK_MUTEX(memleak_lock)
+
+ defPointer::iterator itr=LuceneBase_Pointers.begin();
+ int32_t i=0;
+ for ( ;itr!=LuceneBase_Pointers.end() && i<item ;itr++ ){
+ ++i;
+ }
+ if ( itr != LuceneBase_Pointers.end() )
+ return itr->second->file->value;
+ else
+ return NULL;
+}
+void LuceneBase::__cl_PrintUnclosedObjects(){
+ __internalcl_GetUnclosedObjects(true);
+}
+////////////////////////////////////////////////////////////
+
+#endif //LUCENE_ENABLE_MEMLEAKTRACKING
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/document/DateField.cpp b/3rdparty/clucene/src/CLucene/document/DateField.cpp
new file mode 100644
index 000000000..ff72b12bb
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/document/DateField.cpp
@@ -0,0 +1,60 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+
+#include "DateField.h"
+#include "CLucene/util/Misc.h"
+CL_NS_USE(util)
+CL_NS_DEF(document)
+
+DateField::~DateField(){
+}
+
+TCHAR* DateField::timeToString(const int64_t time) {
+ TCHAR* buf = _CL_NEWARRAY(TCHAR,DATEFIELD_DATE_LEN + 1);
+ timeToString(time,buf);
+ return buf;
+}
+void DateField::timeToString(const int64_t time, TCHAR* buf) {
+ CND_PRECONDITION (buf, "buf == NULL");
+ *buf = '\0';
+ if (time < 0)
+ _CLTHROWA (CL_ERR_IllegalArgument,"time too early"); //todo: make richer error
+
+ if (time > DATEFIELD_DATE_MAX)
+ _CLTHROWA (CL_ERR_IllegalArgument, "time too late (past DATEFIELD_DATE_MAX"); //todo: make richer error
+
+ _i64tot(time, buf, 36);
+ int32_t bufLen = _tcslen(buf);
+
+ CND_PRECONDITION (bufLen <= DATEFIELD_DATE_LEN, "timeToString length is greater than 9");
+
+ /* Supply leading zeroes if necessary. */
+ if (bufLen < DATEFIELD_DATE_LEN) {
+ const int32_t nMissingZeroes = DATEFIELD_DATE_LEN - bufLen;
+ /* Move buffer contents forward to make room for leading zeroes. */
+ for (int32_t i = DATEFIELD_DATE_LEN - 1; i >= nMissingZeroes; i--)
+ buf[i] = buf[i - nMissingZeroes];
+
+ /* Insert leading zeroes. */
+ {// MSVC6 scoping fix
+ for (int32_t i = 0; i < nMissingZeroes; i++)
+ buf[i] = '0';
+ }
+
+ buf[DATEFIELD_DATE_LEN] = 0;
+ }
+
+ CND_PRECONDITION (_tcslen(buf) == DATEFIELD_DATE_LEN, "timeToString return is not equal to DATEFIELD_DATE_LEN");
+}
+
+int64_t DateField::stringToTime(const TCHAR* time) {
+ TCHAR* end;
+ return _tcstoi64(time, &end, 36);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/document/DateField.h b/3rdparty/clucene/src/CLucene/document/DateField.h
new file mode 100644
index 000000000..712fe9b62
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/document/DateField.h
@@ -0,0 +1,64 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_document_DateField_
+#define _lucene_document_DateField_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF(document)
+
+//here are some constants used throughout clucene
+//make date strings long enough to last a millenium
+#define DATEFIELD_DATE_MAX _ILONGLONG(31536000000000) //1000L*365*24*60*60*1000
+
+#define DATEFIELD_DATE_LEN 9 ////Long.toString(DATEFIELD_DATE_MAX, Character.MAX_RADIX).length()
+
+/**
+* Provides support for converting dates to strings and vice-versa.
+* The strings are structured so that lexicographic sorting orders by date,
+* which makes them suitable for use as field values and search terms.
+*
+* <P>Note that this class saves dates with millisecond granularity,
+* which is bad for {@link RangeQuery} and {@link PrefixQuery}, as those
+* queries are expanded to a BooleanQuery with a potentially large number
+* of terms when searching. Thus you might want to use
+* {@link DateTools} instead.
+*
+* <P>
+* Note: dates before 1970 cannot be used, and therefore cannot be
+* indexed when using this class. See {@link DateTools} for an
+* alternative without such a limitation.
+*
+* @deprecated If you build a new index, use {@link DateTools} instead. This class is included for use with existing
+* indices and will be removed in a future release.
+*/
+class DateField :LUCENE_BASE {
+public:
+ ~DateField();
+
+ /**
+ * Converts a millisecond time to a string suitable for indexing.
+ * @throws RuntimeException if the time specified in the
+ * method argument is negative, that is, before 1970
+ */
+ static TCHAR* timeToString(const int64_t time);
+
+ /**
+ * Converts a millisecond time to a string suitable for indexing.
+ * @throws CL_ERR_IllegalArgument if the time specified in the
+ * method argument is negative, that is, before 1970
+ * @param str must be a character array DATEFIELD_DATE_LEN+1 or longer
+ */
+ static void timeToString(const int64_t time, TCHAR* str);
+
+ /** Converts a string-encoded date into a millisecond time. */
+ static int64_t stringToTime(const TCHAR* s);
+};
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/document/Document.cpp b/3rdparty/clucene/src/CLucene/document/Document.cpp
new file mode 100644
index 000000000..a0ce03942
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/document/Document.cpp
@@ -0,0 +1,237 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "Document.h"
+#include "Field.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(document)
+
+ DocumentFieldEnumeration::DocumentFieldList::DocumentFieldList(Field* f, DocumentFieldList* n ) {
+ //Func - Constructor
+ //Pre - f != NULL
+ // n may be NULL
+ //Post - Instance has been created
+ CND_PRECONDITION(f != NULL, "f is NULL");
+
+ field = f;
+ next = n;
+ }
+ DocumentFieldEnumeration::DocumentFieldList::~DocumentFieldList(){
+ //Func - Destructor
+ //Pre - true
+ //Post - Instance has been destroyed
+
+ // Instead of recursively deleting the field list we do
+ // it iteratively to avoid stack overflows when
+ // dealing with several thousands of fields.
+
+ if (!field) {
+ return; // nothing to do; deleted by different invocation of dtor
+ }
+
+ DocumentFieldList* cur = next;
+ while (cur != NULL)
+ {
+ DocumentFieldList* temp = cur->next;
+ cur->next = NULL;
+
+ _CLDELETE(cur);
+ cur = temp;
+ }
+ _CLDELETE(field);
+ }
+
+
+ DocumentFieldEnumeration::DocumentFieldEnumeration(const DocumentFieldList* fl){
+ //Func - Constructor
+ //Pre - fl may be NULL
+ //Post - Instance has been created
+
+ fields = fl;
+ }
+
+ DocumentFieldEnumeration::~DocumentFieldEnumeration(){
+ //Func - Destructor
+ //Pre - true
+ //Post - Instance has been destroyed
+ }
+
+ bool DocumentFieldEnumeration::hasMoreElements() const {
+ return fields == NULL ? false : true;
+ }
+
+ Field* DocumentFieldEnumeration::nextElement() {
+ //Func - Return the next element in the enumeration
+ //Pre - true
+ //Post - The next element is returned or NULL
+
+
+ Field* result = NULL;
+ //Check if fields is still valid
+ if (fields){
+ result = fields->field;
+ fields = fields->next;
+ }
+ return result;
+ }
+
+ /** Constructs a new document with no fields. */
+ Document::Document(){
+ //Func - Constructor
+ //Pre - true
+ //Post - Instance has been created
+ boost = 1.0f;
+ fieldList = NULL;
+ }
+
+ Document::~Document(){
+ //Func - Destructor
+ //Pre - true
+ //Post - Instance has been destroyed
+ boost = 1.0f;
+ _CLDELETE(fieldList);
+ }
+
+ void Document::clear(){
+ _CLDELETE(fieldList);
+ }
+
+ void Document::add(Field& field) {
+ fieldList = _CLNEW DocumentFieldEnumeration::DocumentFieldList(&field, fieldList);
+ }
+
+ void Document::setBoost(qreal boost) {
+ this->boost = boost;
+ }
+
+ qreal Document::getBoost() const {
+ return boost;
+ }
+
+
+ Field* Document::getField(const TCHAR* name) const{
+ CND_PRECONDITION(name != NULL, "name is NULL");
+
+ for (DocumentFieldEnumeration::DocumentFieldList* list = fieldList; list != NULL; list = list->next)
+ //cannot use interning here, because name is probably not interned
+ if ( _tcscmp(list->field->name(), name) == 0 ){
+ return list->field;
+ }
+
+ return NULL;
+ }
+
+ const TCHAR* Document::get(const TCHAR* field) const {
+ CND_PRECONDITION(field != NULL, "field is NULL");
+ Field *f = getField(field);
+ if (f!=NULL)
+ return f->stringValue(); //this returns null it is a binary(reader)
+ else
+ return NULL;
+ }
+
+ DocumentFieldEnumeration* Document::fields() const {
+ return _CLNEW DocumentFieldEnumeration(fieldList);
+ }
+
+
+ TCHAR* Document::toString() const {
+ StringBuffer ret(_T("Document<"));
+ for (DocumentFieldEnumeration::DocumentFieldList* list = fieldList; list != NULL; list = list->next) {
+ TCHAR* tmp = list->field->toString();
+ ret.append( tmp );
+ if (list->next != NULL)
+ ret.append(_T(" "));
+ _CLDELETE_ARRAY( tmp );
+ }
+ ret.append(_T(">"));
+ return ret.toString();
+ }
+
+
+
+ void Document::removeField(const TCHAR* name) {
+ CND_PRECONDITION(name != NULL, "name is NULL");
+
+ DocumentFieldEnumeration::DocumentFieldList* previous = NULL;
+ DocumentFieldEnumeration::DocumentFieldList* current = fieldList;
+ while (current != NULL) {
+ //cannot use interning here, because name is probably not interned
+ if ( _tcscmp(current->field->name(),name) == 0 ){
+ if (previous){
+ previous->next = current->next;
+ }else
+ fieldList = current->next;
+ current->next=NULL; //ensure fieldlist destructor doesnt delete it
+ _CLDELETE(current);
+ return;
+ }
+ previous = current;
+ current = current->next;
+ }
+ }
+
+ void Document::removeFields(const TCHAR* name) {
+ CND_PRECONDITION(name != NULL, "name is NULL");
+
+ DocumentFieldEnumeration::DocumentFieldList* previous = NULL;
+ DocumentFieldEnumeration::DocumentFieldList* current = fieldList;
+ while (current != NULL) {
+ //cannot use interning here, because name is probably not interned
+ if ( _tcscmp(current->field->name(),name) == 0 ){
+ if (previous){
+ previous->next = current->next;
+ }else
+ fieldList = current->next;
+
+ current->next=NULL; //ensure fieldlist destructor doesnt delete it
+ _CLDELETE(current);
+
+ if ( previous )
+ current = previous->next;
+ else
+ current = fieldList;
+ }else{
+ previous = current;
+ current = current->next;
+ }
+ }
+ }
+
+ TCHAR** Document::getValues(const TCHAR* name) {
+ DocumentFieldEnumeration* it = fields();
+ int32_t count = 0;
+ while ( it->hasMoreElements() ){
+ Field* f = it->nextElement();
+ //cannot use interning here, because name is probably not interned
+ if ( _tcscmp(f->name(),name) == 0 && f->stringValue() != NULL )
+ count++;
+ }
+ _CLDELETE(it);
+ it = fields();
+
+ //todo: there must be a better way of doing this, we are doing two iterations of the fields
+ TCHAR** ret = NULL;
+ if ( count > 0 ){
+ //start again
+ ret = _CL_NEWARRAY(TCHAR*,count+1);
+ int32_t i=0;
+ while ( it->hasMoreElements() ){
+ Field* fld=it->nextElement();
+ if ( _tcscmp(fld->name(),name)== 0 && fld->stringValue() != NULL ){
+ ret[i] = stringDuplicate(fld->stringValue());
+ i++;
+ }
+ }
+ ret[count]=NULL;
+ }
+ _CLDELETE(it);
+ return ret;
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/document/Document.h b/3rdparty/clucene/src/CLucene/document/Document.h
new file mode 100644
index 000000000..ba7a283f7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/document/Document.h
@@ -0,0 +1,158 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_document_Document_
+#define _lucene_document_Document_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "Field.h"
+
+///todo: jlucene has change from using DocumentFieldList/Enumeration
+///to using a java List... do we want to do this too?
+CL_NS_DEF(document)
+
+class Document; //predefine
+class DocumentFieldEnumeration :LUCENE_BASE{
+ class DocumentFieldList :LUCENE_BASE{
+ public:
+ DocumentFieldList(Field* f, DocumentFieldList* n);
+ ~DocumentFieldList();
+ Field* field;
+ DocumentFieldList* next;
+ };
+ friend class Document;
+private:
+ const DocumentFieldList* fields;
+public:
+ DocumentFieldEnumeration(const DocumentFieldList* fl);
+ ~DocumentFieldEnumeration();
+ bool hasMoreElements() const;
+ Field* nextElement();
+};
+
+/** Documents are the unit of indexing and search.
+*
+* A Document is a set of fields. Each field has a name and a textual value.
+* A field may be {@link Field#isStored() stored} with the document, in which
+* case it is returned with search hits on the document. Thus each document
+* should typically contain one or more stored fields which uniquely identify
+* it.
+*
+* <p>Note that fields which are <i>not</i> {@link Field#isStored() stored} are
+* <i>not</i> available in documents retrieved from the index, e.g. with {@link
+* Hits#doc(int32_t, Document*)}, {@link Searcher#doc(int32_t, Document*)} or {@link
+* IndexReader#document(int32_t, Document*)}.
+*/
+class Document:LUCENE_BASE {
+private:
+ DocumentFieldEnumeration::DocumentFieldList* fieldList;
+ qreal boost;
+public:
+ Document();
+ ~Document();
+
+ /**
+ * <p>Adds a field to a document. Several fields may be added with
+ * the same name. In this case, if the fields are indexed, their text is
+ * treated as though appended for the purposes of search.</p>
+ * <p> Note that add like the removeField(s) methods only makes sense
+ * prior to adding a document to an index. These methods cannot
+ * be used to change the content of an existing index! In order to achieve this,
+ * a document has to be deleted from an index and a new changed version of that
+ * document has to be added.</p>
+ *
+ */
+ void add(Field& field);
+ /** Returns a field with the given name if any exist in this document, or
+ * null. If multiple fields exists with this name, this method returns the
+ * first value added.
+ * Note: name is case sensitive
+ */
+ Field* getField(const TCHAR* name) const;
+
+ /** Returns the string value of the field with the given name if any exist in
+ * this document, or null. If multiple fields exist with this name, this
+ * method returns the first value added. If only binary fields with this name
+ * exist, returns null.
+ * Note: name is case sensitive
+ */
+ const TCHAR* get(const TCHAR* field) const;
+
+ /** Returns an Enumeration of all the fields in a document. */
+ DocumentFieldEnumeration* fields() const;
+ /** Prints the fields of a document for human consumption. */
+ TCHAR* toString() const;
+
+ /** Sets a boost factor for hits on any field of this document. This value
+ * will be multiplied into the score of all hits on this document.
+ *
+ * <p>Values are multiplied into the value of {@link Field#getBoost()} of
+ * each field in this document. Thus, this method in effect sets a default
+ * boost for the fields of this document.
+ *
+ * @see Field#setBoost(qreal)
+ */
+ void setBoost(qreal boost);
+
+ /** Returns the boost factor for hits on any field of this document.
+ *
+ * <p>The default value is 1.0.
+ *
+ * <p>Note: This value is not stored directly with the document in the index.
+ * Documents returned from {@link IndexReader#document(int32_t, Document*)} and
+ * {@link Hits#doc(int32_t, Document*)} may thus not have the same value present as when
+ * this document was indexed.
+ *
+ * @see #setBoost(qreal)
+ */
+ qreal getBoost() const;
+
+
+ /**
+ * <p>Removes field with the specified name from the document.
+ * If multiple fields exist with this name, this method removes the first field that has been added.
+ * If there is no field with the specified name, the document remains unchanged.</p>
+ * <p> Note that the removeField(s) methods like the add method only make sense
+ * prior to adding a document to an index. These methods cannot
+ * be used to change the content of an existing index! In order to achieve this,
+ * a document has to be deleted from an index and a new changed version of that
+ * document has to be added.</p>
+ * Note: name is case sensitive
+ */
+ void removeField(const TCHAR* name);
+
+ /**
+ * <p>Removes all fields with the given name from the document.
+ * If there is no field with the specified name, the document remains unchanged.</p>
+ * <p> Note that the removeField(s) methods like the add method only make sense
+ * prior to adding a document to an index. These methods cannot
+ * be used to change the content of an existing index! In order to achieve this,
+ * a document has to be deleted from an index and a new changed version of that
+ * document has to be added.</p>
+ * Note: name is case sensitive
+ */
+ void removeFields(const TCHAR* name);
+
+ /**
+ * Returns an array of values of the field specified as the method parameter.
+ * This method can return <code>null</code>.
+ * Note: name is case sensitive
+ *
+ * @param name the name of the field
+ * @return a <code>String[]</code> of field values
+ */
+ TCHAR** getValues(const TCHAR* name);
+
+ /**
+ * Empties out the document so that it can be reused
+ */
+ void clear();
+};
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/document/Field.cpp b/3rdparty/clucene/src/CLucene/document/Field.cpp
new file mode 100644
index 000000000..8cd88a36b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/document/Field.cpp
@@ -0,0 +1,315 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "CLucene/util/Reader.h"
+#include "Field.h"
+#include "CLucene/util/Misc.h"
+#include "CLucene/util/StringIntern.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(document)
+
+Field::Field(const TCHAR* Name, const TCHAR* String, bool store, bool index, bool token, const bool storeTermVector)
+{
+//Func - Constructor
+//Pre - Name != NULL and contains the name of the field
+// String != NULL and contains the value of the field
+// store indicates if the field must be stored
+// index indicates if the field must be indexed
+// token indicates if the field must be tokenized
+//Post - The instance has been created
+
+ CND_PRECONDITION(Name != NULL, "Name is NULL");
+ CND_PRECONDITION(String != NULL,"String is NULL");
+ CND_PRECONDITION(!(!index && storeTermVector),"cannot store a term vector for fields that are not indexed.");
+
+ _name = CLStringIntern::intern( Name CL_FILELINE);
+ _stringValue = stringDuplicate( String );
+ _readerValue = NULL;
+ _streamValue = NULL;
+ boost=1.0f;
+ omitNorms = false;
+
+ int cfg = 0;
+ if ( store )
+ cfg |= STORE_YES;
+ if ( index && token )
+ cfg |= INDEX_TOKENIZED;
+ else if ( index && !token )
+ cfg |= INDEX_UNTOKENIZED;
+
+ if ( storeTermVector )
+ _CLTHROWA(CL_ERR_IllegalArgument,"Stored term vector is deprecated with using this constructor");
+
+ setConfig(cfg);
+}
+
+Field::Field(const TCHAR* Name, Reader* reader, bool store, bool index, bool token, const bool storeTermVector)
+{
+//Func - Constructor
+//Pre - Name != NULL and contains the name of the field
+// reader != NULL and contains a Reader
+// store indicates if the field must be stored
+// index indicates if the field must be indexed
+// token indicates if the field must be tokenized
+//Post - The instance has been created
+
+ CND_PRECONDITION(Name != NULL, "Name is NULL");
+ CND_PRECONDITION(reader != NULL, "reader is NULL");
+
+ _name = CLStringIntern::intern( Name CL_FILELINE);
+ _stringValue = NULL;
+ _readerValue = reader;
+ _streamValue = NULL;
+ boost=1.0f;
+ omitNorms = false;
+
+ int cfg = 0;
+ if ( store )
+ cfg |= STORE_YES;
+ if ( index && token )
+ cfg |= INDEX_TOKENIZED;
+ else if ( index && !token )
+ cfg |= INDEX_UNTOKENIZED;
+
+ if ( storeTermVector )
+ _CLTHROWA(CL_ERR_IllegalArgument,"Stored term vector is deprecated with using this constructor");
+
+ setConfig(cfg);
+}
+
+Field::Field(const TCHAR* Name, Reader* reader, int config)
+{
+ CND_PRECONDITION(Name != NULL, "Name is NULL");
+ CND_PRECONDITION(reader != NULL, "reader is NULL");
+
+ _name = CLStringIntern::intern( Name CL_FILELINE);
+ _stringValue = NULL;
+ _readerValue = reader;
+ _streamValue = NULL;
+ boost=1.0f;
+ omitNorms = false;
+
+ setConfig(config);
+}
+
+
+Field::Field(const TCHAR* Name, const TCHAR* Value, int config)
+{
+ CND_PRECONDITION(Name != NULL, "Name is NULL");
+ CND_PRECONDITION(Value != NULL, "value is NULL");
+
+ _name = CLStringIntern::intern( Name CL_FILELINE);
+ _stringValue = stringDuplicate( Value );
+ _readerValue = NULL;
+ _streamValue = NULL;
+ boost=1.0f;
+ omitNorms = false;
+
+ setConfig(config);
+}
+
+Field::Field(const TCHAR* Name, jstreams::StreamBase<char>* Value, int config)
+{
+ CND_PRECONDITION(Name != NULL, "Name is NULL");
+ CND_PRECONDITION(Value != NULL, "value is NULL");
+
+ _name = CLStringIntern::intern( Name CL_FILELINE);
+ _stringValue = NULL;
+ _readerValue = NULL;
+ _streamValue = Value;
+ boost=1.0f;
+ omitNorms = false;
+
+ setConfig(config);
+}
+
+Field::~Field(){
+//Func - Destructor
+//Pre - true
+//Post - Instance has been destroyed
+
+ CLStringIntern::unintern(_name);
+ _CLDELETE_CARRAY(_stringValue);
+ _CLDELETE(_readerValue);
+ _CLVDELETE( _streamValue );
+}
+
+
+/*===============FIELDS=======================*/
+const TCHAR* Field::name() { return _name; } ///<returns reference
+TCHAR* Field::stringValue() { return _stringValue; } ///<returns reference
+Reader* Field::readerValue() { return _readerValue; } ///<returns reference
+jstreams::StreamBase<char>* Field::streamValue() { return _streamValue; } ///<returns reference
+
+bool Field::isStored() { return (config & STORE_YES) != 0; }
+bool Field::isIndexed() { return (config & INDEX_TOKENIZED)!=0 || (config & INDEX_UNTOKENIZED)!=0; }
+bool Field::isTokenized() { return (config & INDEX_TOKENIZED) != 0; }
+bool Field::isCompressed() { return (config & STORE_COMPRESS) != 0; }
+bool Field::isBinary() { return _streamValue!=NULL; }
+
+bool Field::isTermVectorStored() { return (config & TERMVECTOR_YES) != 0; }
+bool Field::isStoreOffsetWithTermVector() { return (config & TERMVECTOR_YES) != 0 && (config & TERMVECTOR_WITH_OFFSETS) != 0; }
+bool Field::isStorePositionWithTermVector() { return (config & TERMVECTOR_YES) != 0 && (config & TERMVECTOR_WITH_POSITIONS) != 0; }
+
+bool Field::getOmitNorms() { return omitNorms; }
+void Field::setOmitNorms(bool omitNorms) { this->omitNorms=omitNorms; }
+
+void Field::setBoost(qreal boost) { this->boost = boost; }
+qreal Field::getBoost() { return boost; }
+
+void Field::setConfig(int x){
+ int newConfig=0;
+
+ //set storage settings
+ if ( (x & STORE_YES) || (x & STORE_COMPRESS) ){
+ newConfig |= STORE_YES;
+ if ( x & STORE_COMPRESS )
+ newConfig |= STORE_COMPRESS;
+ }else
+ newConfig |= STORE_NO;
+
+ if ( (x & INDEX_NO)==0 ){
+ bool index=false;
+
+ if ( x & INDEX_NONORMS ){
+ newConfig |= INDEX_NONORMS;
+ index = true;
+ }
+
+ if ( x & INDEX_TOKENIZED && x & INDEX_UNTOKENIZED )
+ _CLTHROWA(CL_ERR_IllegalArgument,"it doesn't make sense to have an untokenised and tokenised field");
+ if ( x & INDEX_TOKENIZED ){
+ newConfig |= INDEX_TOKENIZED;
+ index = true;
+ }
+ if ( x & INDEX_UNTOKENIZED ){
+ newConfig |= INDEX_UNTOKENIZED;
+ index = true;
+ }
+ if ( !index )
+ newConfig |= INDEX_NO;
+ }else
+ newConfig |= INDEX_NO;
+
+ if ( newConfig & INDEX_NO && newConfig & STORE_NO )
+ _CLTHROWA(CL_ERR_IllegalArgument,"it doesn't make sense to have a field that is neither indexed nor stored");
+
+ //set termvector settings
+ if ( (x & TERMVECTOR_NO) == 0 ){
+ bool termVector=false;
+ if ( x & TERMVECTOR_YES ){
+ termVector=true;
+ }
+ if ( x & TERMVECTOR_WITH_OFFSETS ){
+ newConfig |= TERMVECTOR_WITH_OFFSETS;
+ termVector=true;
+ }
+ if ( x & TERMVECTOR_WITH_POSITIONS ){
+ newConfig |= TERMVECTOR_WITH_POSITIONS;
+ termVector=true;
+ }
+ if ( termVector ){
+ if ( newConfig & INDEX_NO )
+ _CLTHROWA(CL_ERR_IllegalArgument,"cannot store a term vector for fields that are not indexed.");
+
+ newConfig |= TERMVECTOR_YES;
+ }else
+ newConfig |= TERMVECTOR_NO;
+ }else
+ newConfig |= TERMVECTOR_NO;
+
+ config = newConfig;
+}
+
+TCHAR* Field::toString() {
+ CL_NS(util)::StringBuffer result;
+ if (isStored()) {
+ result.append( _T("stored") );
+ }
+ if (isIndexed()) {
+ if (result.length() > 0)
+ result.append( _T(",") );
+ result.append( _T("indexed") );
+ }
+ if (isTokenized()) {
+ if (result.length() > 0)
+ result.append( _T(",") );
+ result.append( _T("tokenized") );
+ }
+ if (isTermVectorStored()) {
+ if (result.length() > 0)
+ result.append( _T(",") );
+ result.append( _T("termVector") );
+ }
+ if (isStoreOffsetWithTermVector()) {
+ if (result.length() > 0)
+ result.appendChar( ',' );
+ result.append( _T("termVectorOffsets") );
+ }
+ if (isStorePositionWithTermVector()) {
+ if (result.length() > 0)
+ result.appendChar( ',' );
+ result.append( _T("termVectorPosition") );
+ }
+ if (isBinary()) {
+ if (result.length() > 0)
+ result.appendChar( ',' );
+ result.append( _T("binary") );
+ }
+ if (getOmitNorms()) {
+ result.append( _T(",omitNorms") );
+ }
+ result.appendChar('<');
+ result.append(name());
+ result.appendChar(':');
+
+ if (_stringValue != NULL)
+ result.append(_stringValue);
+ else if ( _readerValue != NULL )
+ result.append( _T("Reader") );
+ else if ( _streamValue != NULL )
+ result.append( _T("Stream") );
+ else
+ result.append( _T("NULL") );
+
+ result.appendChar('>');
+ return result.toString();
+}
+
+
+Field* Field::Keyword(const TCHAR* Name, const TCHAR* Value) {
+ return _CLNEW Field(Name,Value,Field::STORE_YES | Field::INDEX_UNTOKENIZED);
+}
+
+Field* Field::UnIndexed(const TCHAR* Name, const TCHAR* Value) {
+ return _CLNEW Field(Name,Value,Field::STORE_YES | Field::INDEX_NO);
+}
+
+Field* Field::Text(const TCHAR* Name, const TCHAR* Value, const bool storeTermVector) {
+ if ( storeTermVector )
+ return _CLNEW Field(Name,Value,Field::STORE_YES | Field::INDEX_TOKENIZED | Field::TERMVECTOR_YES);
+ else
+ return _CLNEW Field(Name,Value,Field::STORE_YES | Field::INDEX_TOKENIZED);
+}
+
+Field* Field::UnStored(const TCHAR* Name, const TCHAR* Value, const bool storeTermVector) {
+ if ( storeTermVector )
+ return _CLNEW Field(Name,Value,Field::STORE_NO | Field::INDEX_TOKENIZED | Field::TERMVECTOR_YES);
+ else
+ return _CLNEW Field(Name,Value,Field::STORE_NO | Field::INDEX_TOKENIZED);
+}
+
+Field* Field::Text(const TCHAR* Name, Reader* Value, const bool storeTermVector) {
+ if ( storeTermVector )
+ return _CLNEW Field(Name,Value,Field::INDEX_TOKENIZED | Field::TERMVECTOR_YES);
+ else
+ return _CLNEW Field(Name,Value,Field::INDEX_TOKENIZED);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/document/Field.h b/3rdparty/clucene/src/CLucene/document/Field.h
new file mode 100644
index 000000000..771a1382b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/document/Field.h
@@ -0,0 +1,261 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_document_Field_
+#define _lucene_document_Field_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/Reader.h"
+#include "CLucene/util/streambase.h"
+
+CL_NS_DEF(document)
+/**
+A field is a section of a Document. Each field has two parts, a name and a
+value. Values may be free text, provided as a String or as a Reader, or they
+may be atomic keywords, which are not further processed. Such keywords may
+be used to represent dates, urls, etc. Fields are optionally stored in the
+index, so that they may be returned with hits on the document.
+
+PORTING: CLucene doesn't directly support compressed fields. However, it is easy
+to reproduce this functionality by using the GZip streams in the contrib package.
+Also note that binary fields are not read immediately in CLucene, a substream
+is pointed directly to the field's data, in affect creating a lazy load ability.
+This means that large fields are best saved in binary format (even if they are
+text), so that they can be loaded lazily.
+*/
+class Field :LUCENE_BASE{
+private:
+ const TCHAR* _name;
+ TCHAR* _stringValue;
+ CL_NS(util)::Reader* _readerValue;
+ jstreams::StreamBase<char>* _streamValue;
+
+ int config;
+ qreal boost;
+ bool omitNorms;
+public:
+ enum Store{
+ /** Store the original field value in the index. This is useful for short texts
+ * like a document's title which should be displayed with the results. The
+ * value is stored in its original form, i.e. no analyzer is used before it is
+ * stored.
+ */
+ STORE_YES=1,
+ /** Do not store the field value in the index. */
+ STORE_NO=2,
+
+ /** Store the original field value in the index in a compressed form. This is
+ * useful for long documents and for binary valued fields.
+ * NOTE: CLucene does not directly support compressed fields, to store a
+ * compressed field.
+ * //TODO: need better documentation on how to add a compressed field
+ * //because actually we still need to write a GZipOutputStream...
+ */
+ STORE_COMPRESS=4
+ };
+
+ enum Index{
+ /** Do not index the field value. This field can thus not be searched,
+ * but one can still access its contents provided it is
+ * {@link Field::Store stored}. */
+ INDEX_NO=16,
+ /** Index the field's value so it can be searched. An Analyzer will be used
+ * to tokenize and possibly further normalize the text before its
+ * terms will be stored in the index. This is useful for common text.
+ */
+ INDEX_TOKENIZED=32,
+ /** Index the field's value without using an Analyzer, so it can be searched.
+ * As no analyzer is used the value will be stored as a single term. This is
+ * useful for unique Ids like product numbers.
+ */
+ INDEX_UNTOKENIZED=64,
+ /** Index the field's value without an Analyzer, and disable
+ * the storing of norms. No norms means that index-time boosting
+ * and field length normalization will be disabled. The benefit is
+ * less memory usage as norms take up one byte per indexed field
+ * for every document in the index.
+ */
+ INDEX_NONORMS=128
+ };
+
+ enum TermVector{
+ /** Do not store term vectors. */
+ TERMVECTOR_NO=256,
+ /** Store the term vectors of each document. A term vector is a list
+ * of the document's terms and their number of occurences in that document. */
+ TERMVECTOR_YES=512,
+ /**
+ * Store the term vector + token position information
+ *
+ * @see #YES
+ */
+ TERMVECTOR_WITH_POSITIONS=1024,
+ /**
+ * Store the term vector + Token offset information
+ *
+ * @see #YES
+ */
+ TERMVECTOR_WITH_OFFSETS=2048
+ };
+
+ _CL_DEPRECATED( another overload ) Field(const TCHAR* name, const TCHAR* value, bool store, bool index, bool token, const bool storeTermVector=false);
+ _CL_DEPRECATED( another overload ) Field(const TCHAR* name, CL_NS(util)::Reader* reader, bool store, bool index, bool token, const bool storeTermVector=false);
+
+ Field(const TCHAR* name, const TCHAR* value, int configs);
+ Field(const TCHAR* name, CL_NS(util)::Reader* reader, int configs);
+ Field(const TCHAR* name, jstreams::StreamBase<char>* stream, int configs);
+ ~Field();
+
+ /** Constructs a String-valued Field that is not tokenized, but is indexed
+ * and stored. Useful for non-text fields, e.g. date or url.
+ * @deprecated Use new Field(name,value,Field::STORE_YES | Field::INDEX_UNTOKENIZED)
+ */
+ _CL_DEPRECATED( new Field(*) ) static Field* Keyword(const TCHAR* name, const TCHAR* value);
+
+ /** Constructs a String-valued Field that is not tokenized nor indexed,
+ * but is stored in the index, for return with hits.
+ * @deprecated Use new Field(name,value,Field::STORE_YES | Field::INDEX_NO)
+ */
+ _CL_DEPRECATED( new Field(*) ) static Field* UnIndexed(const TCHAR* name, const TCHAR* value);
+
+ /** Constructs a String-valued Field that is tokenized and indexed,
+ * and is stored in the index, for return with hits. Useful for short text
+ * fields, like "title" or "subject".
+ * @deprecated Use new Field(name,value,Field::STORE_YES | Field::INDEX_TOKENIZED)
+ */
+ _CL_DEPRECATED( new Field(*) ) static Field* Text(const TCHAR* name, const TCHAR* value, const bool storeTermVector=false);
+
+ /** Constructs a String-valued Field that is tokenized and indexed,
+ * but that is not stored in the index.
+ * @deprecated Use new Field(name,value,Field::STORE_NO | Field::INDEX_TOKENIZED)
+ */
+ _CL_DEPRECATED( new Field(*) ) static Field* UnStored(const TCHAR* name, const TCHAR* value, const bool storeTermVector=false);
+
+ /** Constructs a Reader-valued Field that is tokenized and indexed, but is
+ * *not* stored in the index verbatim. Useful for longer text fields, like
+ * "body".
+ * @deprecated Use new Field(name,value, Field::INDEX_TOKENIZED)
+ */
+ _CL_DEPRECATED( new Field(*) ) static Field* Text(const TCHAR* name, CL_NS(util)::Reader* value, const bool storeTermVector=false);
+
+ /** The name of the field (e.g., "date", "subject", "title", "body", etc.)
+ * as an interned string. */
+ const TCHAR* name(); ///<returns reference
+
+ /** The value of the field as a String, or null. If null, the Reader value
+ * or binary value is used. Exactly one of stringValue(), readerValue() and
+ * streamValue() must be set. */
+ TCHAR* stringValue(); ///<returns reference
+
+ /** The value of the field as a reader, or null. If null, the String value
+ * or stream value is used. Exactly one of stringValue(), readerValue() and
+ * streamValue() must be set. */
+ CL_NS(util)::Reader* readerValue();
+
+ /** The value of the field as a String, or null. If null, the String value
+ * or Reader value is used. Exactly one of stringValue(), readerValue() and
+ * streamValue() must be set. */
+ jstreams::StreamBase<char>* streamValue();
+
+ // True iff the value of the field is to be stored in the index for return
+ // with search hits. It is an error for this to be true if a field is
+ // Reader-valued.
+ bool isStored();
+
+ // True iff the value of the field is to be indexed, so that it may be
+ // searched on.
+ bool isIndexed();
+
+ // True iff the value of the field should be tokenized as text prior to
+ // indexing. Un-tokenized fields are indexed as a single word and may not be
+ // Reader-valued.
+ bool isTokenized();
+
+ /** True if the value of the field is stored and compressed within the index
+ * NOTE: CLucene does not actually support compressed fields, Instead, a reader
+ * will be returned with a pointer to a SubIndexInputStream. A GZipInputStream
+ * and a UTF8 reader must be used to actually read the content. This flag
+ * will only be set if the index was created by another lucene implementation.
+ */
+ bool isCompressed();
+
+ //Set configs using XOR. This resets all the settings
+ //For example, to use term vectors with positions and offsets do:
+ //object->setConfig(TERMVECTOR_WITH_POSITIONS | TERMVECTOR_WITH_OFFSETS);
+ void setConfig(int termVector);
+
+ /** True iff the term or terms used to index this field are stored as a term
+ * vector, available from {@link IndexReader#getTermFreqVector(int32_t,TCHAR*)}.
+ * These methods do not provide access to the original content of the field,
+ * only to terms used to index it. If the original content must be
+ * preserved, use the <code>stored</code> attribute instead.
+ *
+ * @see IndexReader#getTermFreqVector(int32_t, String)
+ */
+ bool isTermVectorStored();
+
+ /**
+ * True iff terms are stored as term vector together with their offsets
+ * (start and end positon in source text).
+ */
+ bool isStoreOffsetWithTermVector();
+
+ /**
+ * True iff terms are stored as term vector together with their token positions.
+ */
+ bool isStorePositionWithTermVector();
+
+ /** Returns the boost factor for hits for this field.
+ *
+ * <p>The default value is 1.0.
+ *
+ * <p>Note: this value is not stored directly with the document in the index.
+ * Documents returned from {@link IndexReader#document(int)} and
+ * {@link Hits#doc(int)} may thus not have the same value present as when
+ * this field was indexed.
+ *
+ * @see #setBoost(float)
+ */
+ qreal getBoost();
+
+ /** Sets the boost factor hits on this field. This value will be
+ * multiplied into the score of all hits on this field of this document.
+ *
+ * <p>The boost is multiplied by {@link Document#getBoost()} of the document
+ * containing this field. If a document has multiple fields with the same
+ * name, all such values are multiplied together. This product is then
+ * multipled by the value {@link Similarity#lengthNorm(String,int)}, and
+ * rounded by {@link Similarity#encodeNorm(float)} before it is stored in the
+ * index. One should attempt to ensure that this product does not overflow
+ * the range of that encoding.
+ *
+ * @see Document#setBoost(float)
+ * @see Similarity#lengthNorm(String, int)
+ * @see Similarity#encodeNorm(float)
+ */
+ void setBoost(qreal value);
+
+ /** True iff the value of the filed is stored as binary */
+ bool isBinary();
+
+ /** True if norms are omitted for this indexed field */
+ bool getOmitNorms();
+
+ /** Expert:
+ *
+ * If set, omit normalization factors associated with this indexed field.
+ * This effectively disables indexing boosts and length normalization for this field.
+ */
+ void setOmitNorms(bool omitNorms);
+
+ // Prints a Field for human consumption.
+ TCHAR* toString();
+};
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/CompoundFile.cpp b/3rdparty/clucene/src/CLucene/index/CompoundFile.cpp
new file mode 100644
index 000000000..efa0e2563
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/CompoundFile.cpp
@@ -0,0 +1,380 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "CompoundFile.h"
+#include "CLucene/util/Misc.h"
+
+CL_NS_USE(store)
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+CompoundFileReader::CSIndexInput::CSIndexInput(CL_NS(store)::IndexInput* base,
+ const int64_t fileOffset, const int64_t length)
+{
+ this->base = base;
+ this->fileOffset = fileOffset;
+ this->_length = length;
+}
+
+void CompoundFileReader::CSIndexInput::readInternal(uint8_t* b, const int32_t len)
+{
+ SCOPED_LOCK_MUTEX(base->THIS_LOCK)
+
+ int64_t start = getFilePointer();
+ if(start + len > _length)
+ _CLTHROWA(CL_ERR_IO, "read past EOF");
+ base->seek(fileOffset + start);
+ base->readBytes(b, len);
+}
+
+CompoundFileReader::CSIndexInput::~CSIndexInput()
+{
+}
+
+IndexInput* CompoundFileReader::CSIndexInput::clone() const
+{
+ return _CLNEW CSIndexInput(*this);
+}
+
+CompoundFileReader::CSIndexInput::CSIndexInput(const CSIndexInput& clone)
+ : BufferedIndexInput(clone)
+{
+ this->base = clone.base; //no need to clone this..
+ this->fileOffset = clone.fileOffset;
+ this->_length = clone._length;
+}
+
+void CompoundFileReader::CSIndexInput::close()
+{
+}
+
+CompoundFileReader::CompoundFileReader(Directory* dir, const QString& name)
+ : entries(false, true)
+{
+ directory = dir;
+ fileName = name;
+
+ bool success = false;
+ try {
+ stream = dir->openInput(name);
+
+ // read the directory and init files
+ int32_t count = stream->readVInt();
+ FileEntry* entry = NULL;
+ TCHAR tid[CL_MAX_PATH];
+ for (int32_t i = 0; i < count; i++) {
+ int64_t offset = stream->readLong();
+ int32_t read = stream->readString(tid, CL_MAX_PATH);
+ QString aid(QString::fromWCharArray(tid, read));
+
+ // set length of the previous entry
+ if (entry != NULL)
+ entry->length = offset - entry->offset;
+
+ entry = _CLNEW FileEntry(offset);
+ entries.put(aid, entry);
+ }
+
+ // set the length of the final entry
+ if (entry != NULL)
+ entry->length = stream->length() - entry->offset;
+ success = true;
+ } _CLFINALLY (
+ if (!success && (stream != NULL)) {
+ try {
+ stream->close();
+ _CLDELETE(stream);
+ } catch (CLuceneError& err) {
+ if (err.number() != CL_ERR_IO)
+ throw err;
+ }
+ }
+ )
+}
+
+CompoundFileReader::~CompoundFileReader()
+{
+ close();
+}
+
+Directory* CompoundFileReader::getDirectory()
+{
+ return directory;
+}
+
+QString CompoundFileReader::getName() const
+{
+ return fileName;
+}
+
+void CompoundFileReader::close()
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ if (stream != NULL) {
+ entries.clear();
+ stream->close();
+ _CLDELETE(stream);
+ }
+}
+
+IndexInput* CompoundFileReader::openInput(const QString& id)
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ if (stream == NULL)
+ _CLTHROWA(CL_ERR_IO, "Stream closed");
+
+ const FileEntry* entry = entries.get(id);
+ if (entry == NULL) {
+ char buf[CL_MAX_PATH + 30];
+ strcpy(buf,"No sub-file with id ");
+ strncat(buf, id.toLocal8Bit().constData(), CL_MAX_PATH);
+ strcat(buf, " found");
+ _CLTHROWA(CL_ERR_IO,buf);
+ }
+ return _CLNEW CSIndexInput(stream, entry->offset, entry->length);
+}
+
+QStringList CompoundFileReader::list() const
+{
+ // for (EntriesType::const_iterator i=entries.begin();i!=entries.end();i++){
+ // names->push_back(i->first);
+ // ++i;
+ // }
+
+ QStringList names;
+ EntriesType::const_iterator itr;
+ // TODO: verify this, see old code above ???
+ for (itr = entries.begin(); itr != entries.end(); ++itr)
+ names.push_back(itr->first);
+
+ return names;
+}
+
+bool CompoundFileReader::fileExists(const QString& name) const
+{
+ return entries.exists(name);
+}
+
+int64_t CompoundFileReader::fileModified(const QString& name) const
+{
+ return directory->fileModified(fileName);
+}
+
+void CompoundFileReader::touchFile(const QString& name)
+{
+ directory->touchFile(fileName);
+}
+
+bool CompoundFileReader::doDeleteFile(const QString& name)
+{
+ _CLTHROWA(CL_ERR_UnsupportedOperation,
+ "UnsupportedOperationException: CompoundFileReader::doDeleteFile");
+}
+
+void CompoundFileReader::renameFile(const QString& from, const QString& to)
+{
+ _CLTHROWA(CL_ERR_UnsupportedOperation,
+ "UnsupportedOperationException: CompoundFileReader::renameFile");
+}
+
+int64_t CompoundFileReader::fileLength(const QString& name) const
+{
+ FileEntry* e = entries.get(name);
+ if (e == NULL) {
+ char buf[CL_MAX_PATH + 30];
+ strcpy(buf,"File ");
+ strncat(buf, name.toLocal8Bit().constData(), CL_MAX_PATH);
+ strcat(buf," does not exist");
+ _CLTHROWA(CL_ERR_IO,buf);
+ }
+ return e->length;
+}
+
+IndexOutput* CompoundFileReader::createOutput(const QString& name)
+{
+ _CLTHROWA(CL_ERR_UnsupportedOperation,
+ "UnsupportedOperationException: CompoundFileReader::createOutput");
+}
+
+LuceneLock* CompoundFileReader::makeLock(const QString& name)
+{
+ _CLTHROWA(CL_ERR_UnsupportedOperation,
+ "UnsupportedOperationException: CompoundFileReader::makeLock");
+}
+
+QString CompoundFileReader::toString() const
+{
+ QString ret(QLatin1String("CompoundFileReader@"));
+ return ret.append(fileName);
+}
+
+CompoundFileWriter::CompoundFileWriter(Directory* dir, const QString& name)
+ : ids(false)
+ , entries(true)
+{
+ if (dir == NULL)
+ _CLTHROWA(CL_ERR_NullPointer, "directory cannot be null");
+
+ if (name.isEmpty())
+ _CLTHROWA(CL_ERR_NullPointer, "name cannot be null");
+
+ merged = false;
+ directory = dir;
+ fileName = name;
+}
+
+CompoundFileWriter::~CompoundFileWriter()
+{
+}
+
+Directory* CompoundFileWriter::getDirectory()
+{
+ return directory;
+}
+
+/** Returns the name of the compound file. */
+QString CompoundFileWriter::getName() const
+{
+ return fileName;
+}
+
+void CompoundFileWriter::addFile(const QString& file)
+{
+ if (merged)
+ _CLTHROWA(CL_ERR_IO, "Can't add extensions after merge has been called");
+
+ if (file.isEmpty())
+ _CLTHROWA(CL_ERR_NullPointer, "file cannot be null");
+
+ if (ids.find(file) != ids.end()) {
+ char buf[CL_MAX_PATH + 30];
+ strcpy(buf, "File ");
+ strncat(buf, file.toLocal8Bit().constData(), CL_MAX_PATH);
+ strcat(buf," already added");
+ _CLTHROWA(CL_ERR_IO,buf);
+ }
+ ids.insert(file);
+ entries.push_back(_CLNEW WriterFileEntry(file));
+}
+
+void CompoundFileWriter::close()
+{
+ if (merged)
+ _CLTHROWA(CL_ERR_IO, "Merge already performed");
+
+ if (entries.size() == 0) // isEmpty()
+ _CLTHROWA(CL_ERR_IO, "No entries to merge have been defined");
+
+ merged = true;
+
+ // open the compound stream
+ IndexOutput* os = NULL;
+ try {
+ os = directory->createOutput(fileName);
+
+ // Write the number of entries
+ os->writeVInt(entries.size());
+
+ // Write the directory with all offsets at 0.
+ // Remember the positions of directory entries so that we can
+ // adjust the offsets later
+ { //msvc6 for scope fix
+ TCHAR tfile[CL_MAX_PATH];
+ for (CLLinkedList<WriterFileEntry*>::iterator i = entries.begin();
+ i != entries.end(); i++) {
+ WriterFileEntry* fe = *i;
+ fe->directoryOffset = os->getFilePointer();
+ os->writeLong(0); // for now
+ tfile[fe->file.toWCharArray(tfile)] = '\0';
+ os->writeString(tfile, _tcslen(tfile));
+ }
+ }
+
+ // Open the files and copy their data into the stream.
+ // Remember the locations of each file's data section.
+ { //msvc6 for scope fix
+ int32_t bufferLength = 1024;
+ uint8_t buffer[1024];
+ for (CLLinkedList<WriterFileEntry*>::iterator i = entries.begin();
+ i != entries.end(); i++) {
+ WriterFileEntry* fe = *i;
+ fe->dataOffset = os->getFilePointer();
+ copyFile(fe, os, buffer, bufferLength);
+ }
+ }
+
+ { //msvc6 for scope fix
+ // Write the data offsets into the directory of the compound stream
+ for (CLLinkedList<WriterFileEntry*>::iterator i = entries.begin();
+ i != entries.end(); i++) {
+ WriterFileEntry* fe = *i;
+ os->seek(fe->directoryOffset);
+ os->writeLong(fe->dataOffset);
+ }
+ }
+
+
+ } _CLFINALLY (
+ if (os != NULL) {
+ try {
+ os->close();
+ _CLDELETE(os);
+ } catch (...) { }
+ }
+ );
+}
+
+void CompoundFileWriter::copyFile(WriterFileEntry* source, IndexOutput* os,
+ uint8_t* buffer, int32_t bufferLength)
+{
+ IndexInput* is = NULL;
+ try {
+ int64_t startPtr = os->getFilePointer();
+
+ is = directory->openInput(source->file);
+ int64_t length = is->length();
+ int64_t remainder = length;
+ int32_t chunk = bufferLength;
+
+ while(remainder > 0) {
+ int32_t len = (int32_t)min((int64_t)chunk, remainder);
+ is->readBytes(buffer, len);
+ os->writeBytes(buffer, len);
+ remainder -= len;
+ }
+
+ // Verify that remainder is 0
+ if (remainder != 0) {
+ TCHAR buf[CL_MAX_PATH+100];
+ _sntprintf(buf, CL_MAX_PATH + 100, _T("Non-zero remainder length ")
+ _T("after copying: %d (id: %s, length: %d, buffer size: %d)"),
+ remainder, source->file.toLocal8Bit().constData(), length, chunk);
+ _CLTHROWT(CL_ERR_IO, buf);
+ }
+
+ // Verify that the output length diff is equal to original file
+ int64_t endPtr = os->getFilePointer();
+ int64_t diff = endPtr - startPtr;
+ if (diff != length) {
+ TCHAR buf[100];
+ _sntprintf(buf, 100, _T("Difference in the output file offsets %d ")
+ _T("does not match the original file length %d"), diff, length);
+ _CLTHROWT(CL_ERR_IO,buf);
+ }
+ } _CLFINALLY (
+ if (is != NULL) {
+ is->close();
+ _CLDELETE(is);
+ }
+ );
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/CompoundFile.h b/3rdparty/clucene/src/CLucene/index/CompoundFile.h
new file mode 100644
index 000000000..84799a62f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/CompoundFile.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#ifndef _lucene_index_compoundfile_h
+#define _lucene_index_compoundfile_h
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include "CLucene/store/IndexInput.h"
+#include "CLucene/store/IndexOutput.h"
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/Lock.h"
+#include "CLucene/util/VoidList.h"
+#include "CLucene/util/VoidMap.h"
+
+CL_NS_DEF(index)
+
+// Class for accessing a compound stream.
+// This class implements a directory, but is limited to only read operations.
+// Directory methods that would normally modify data throw an exception.
+class CompoundFileReader : public CL_NS(store)::Directory
+{
+private:
+ /** Implementation of an IndexInput that reads from a portion of the
+ * compound file. The visibility is left as "package" *only* because
+ * this helps with testing since JUnit test cases in a different class
+ * can then access package fields of this class.
+ */
+ class CSIndexInput : public CL_NS(store)::BufferedIndexInput
+ {
+ private:
+ CL_NS(store)::IndexInput* base;
+ int64_t fileOffset;
+ int64_t _length;
+ protected:
+ /** Expert: implements buffer refill. Reads uint8_ts from the current
+ * position in the input.
+ * @param b the array to read uint8_ts into
+ * @param length the number of uint8_ts to read
+ */
+ void readInternal(uint8_t* b, const int32_t len);
+ void seekInternal(const int64_t pos) {}
+
+ public:
+ CSIndexInput(CL_NS(store)::IndexInput* base, const int64_t fileOffset,
+ const int64_t length);
+ CSIndexInput(const CSIndexInput& clone);
+ ~CSIndexInput();
+
+ /** Closes the stream to futher operations. */
+ void close();
+ CL_NS(store)::IndexInput* clone() const;
+
+ int64_t length() { return _length; }
+
+ QString getDirectoryType() const {
+ return CompoundFileReader::DirectoryType(); }
+ };
+
+ class FileEntry : LUCENE_BASE
+ {
+ public:
+ FileEntry()
+ : offset(0), length(0) {}
+ FileEntry(int64_t _offset)
+ : offset(_offset), length(0) {}
+ ~FileEntry() {}
+
+ int64_t offset;
+ int64_t length;
+ };
+
+ // Base info
+ CL_NS(store)::Directory* directory;
+ QString fileName;
+
+ CL_NS(store)::IndexInput* stream;
+
+ typedef CL_NS(util)::CLHashMap<QString, FileEntry*,
+ CL_NS(util)::Compare::Qstring,
+ CL_NS(util)::Equals::Qstring,
+ CL_NS(util)::Deletor::DummyQString,
+ CL_NS(util)::Deletor::Object<FileEntry> > EntriesType;
+ EntriesType entries;
+protected:
+ // Removes an existing file in the directory->
+ bool doDeleteFile(const QString& name);
+
+public:
+ CompoundFileReader(CL_NS(store)::Directory* dir, const QString& name);
+ ~CompoundFileReader();
+ CL_NS(store)::Directory* getDirectory();
+ QString getName() const;
+
+ void close();
+ CL_NS(store)::IndexInput* openInput(const QString& id);
+
+ /** Returns an array of strings, one for each file in the directory-> */
+ QStringList list() const;
+ /** Returns true iff a file with the given name exists. */
+ bool fileExists(const QString& name) const;
+ /** Returns the time the named file was last modified. */
+ int64_t fileModified(const QString& name) const;
+ /** Set the modified time of an existing file to now. */
+ void touchFile(const QString& name);
+ /** Renames an existing file in the directory->
+ If a file already exists with the new name, then it is replaced.
+ This replacement should be atomic. */
+ void renameFile(const QString& from, const QString& to);
+ /** Returns the length of a file in the directory.
+ * @throws IOException if the file does not exist */
+ int64_t fileLength(const QString& name) const;
+ /** Not implemented
+ * @throws UnsupportedOperationException */
+ CL_NS(store)::IndexOutput* createOutput(const QString& name);
+ /** Not implemented
+ * @throws UnsupportedOperationException */
+ CL_NS(store)::LuceneLock* makeLock(const QString& name);
+
+ QString toString() const;
+
+ static QString DirectoryType() { return QLatin1String("CFS"); }
+ QString getDirectoryType() const { return DirectoryType(); }
+};
+
+
+
+// Combines multiple files into a single compound file.
+// The file format:<br>
+// <ul>
+// <li>VInt fileCount</li>
+// <li>{Directory}
+// fileCount entries with the following structure:</li>
+// <ul>
+// <li>int64_t dataOffset</li>
+// <li>UTFString extension</li>
+// </ul>
+// <li>{File Data}
+// fileCount entries with the raw data of the corresponding file</li>
+// </ul>
+// The fileCount integer indicates how many files are contained in this compound
+// file. The {directory} that follows has that many entries. Each directory entry
+// contains an encoding identifier, an int64_t pointer to the start of this file's
+// data section, and a UTF String with that file's extension.
+class CompoundFileWriter : LUCENE_BASE
+{
+ class WriterFileEntry : LUCENE_BASE {
+ public:
+ WriterFileEntry()
+ : dataOffset(0), directoryOffset(0) {}
+ WriterFileEntry(const QString& _file)
+ : file(_file), dataOffset(0), directoryOffset(0) {}
+ ~WriterFileEntry() {}
+
+ QString file;
+ // temporary holder for the start of this file's data section
+ int64_t dataOffset;
+ // temporary holder for the start of directory entry for this file
+ int64_t directoryOffset;
+ };
+
+ bool merged;
+ QString fileName;
+ CL_NS(store)::Directory* directory;
+
+ CL_NS(util)::CLHashSet<QString, CL_NS(util)::Compare::Qstring,
+ CL_NS(util)::Deletor::DummyQString> ids;
+
+ CL_NS(util)::CLLinkedList<WriterFileEntry*,
+ CL_NS(util)::Deletor::Object<WriterFileEntry> > entries;
+
+ // Copy the contents of the file with specified extension into the
+ // provided output stream. Use the provided buffer for moving data
+ // to reduce memory allocation.
+ void copyFile(WriterFileEntry* source, CL_NS(store)::IndexOutput* os,
+ uint8_t* buffer, int32_t bufferLength);
+
+public:
+ // Create the compound stream in the specified file. The file name is the
+ // entire name (no extensions are added).
+ CompoundFileWriter(CL_NS(store)::Directory* dir, const QString& name);
+ ~CompoundFileWriter();
+
+ // Returns the directory of the compound file.
+ CL_NS(store)::Directory* getDirectory();
+
+ QString getName() const ;
+ /* Add a source stream. <code>file</code> is the string by which the
+ * sub-stream will be known in the compound stream.
+ *
+ * @throws IllegalStateException if this writer is closed
+ * @throws NullPointerException if <code>file</code> is null
+ * @throws IllegalArgumentException if a file with the same name
+ * has been added already
+ */
+ void addFile(const QString& file);
+ /* Merge files with the extensions added up to now.
+ * All files with these extensions are combined sequentially into the
+ * compound stream. After successful merge, the source files
+ * @throws IllegalStateException if close() had been called before or
+ * if no file has been added to this object
+ * are deleted.
+ */
+ void close();
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/DocumentWriter.cpp b/3rdparty/clucene/src/CLucene/index/DocumentWriter.cpp
new file mode 100644
index 000000000..dcbc31591
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/DocumentWriter.cpp
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+
+#include "DocumentWriter.h"
+#include "FieldInfos.h"
+#include "IndexWriter.h"
+#include "FieldsWriter.h"
+#include "Term.h"
+#include "TermInfo.h"
+#include "TermInfosWriter.h"
+
+#include "CLucene/analysis/AnalysisHeader.h"
+
+#include "CLucene/search/Similarity.h"
+#include "TermInfosWriter.h"
+#include "FieldsWriter.h"
+
+CL_NS_USE(util)
+CL_NS_USE(store)
+CL_NS_USE(analysis)
+CL_NS_USE(document)
+CL_NS_DEF(index)
+
+/*Posting*/
+
+DocumentWriter::Posting::Posting(Term* t, const int32_t position,
+ TermVectorOffsetInfo* offset)
+{
+ //Func - Constructor
+ //Pre - t contains a valid reference to a Term
+ //Post - Instance has been created
+ freq = 1;
+
+ term = _CL_POINTER(t);
+ positions.values = (int32_t*)malloc(sizeof(int32_t));
+ positions.values[0] = position;
+ positions.length = 1;
+
+ if ( offset != NULL ){
+ this->offsets.values =(TermVectorOffsetInfo*)malloc(sizeof(TermVectorOffsetInfo));
+ this->offsets.values[0] = *offset;
+ this->offsets.length = 1;
+ }
+}
+
+DocumentWriter::Posting::~Posting()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ free(positions.values);
+ if ( this->offsets.values != NULL )
+ free(this->offsets.values);
+ _CLDECDELETE(term);
+}
+
+DocumentWriter::DocumentWriter(Directory* d, Analyzer* a,
+ CL_NS(search)::Similarity* sim, const int32_t mfl)
+ : analyzer(a)
+ , directory(d)
+ , maxFieldLength(mfl)
+ , fieldInfos(NULL)
+ , fieldLengths(NULL)
+ , similarity(sim)
+ , termIndexInterval(IndexWriter::DEFAULT_TERM_INDEX_INTERVAL)
+ , fieldPositions(NULL)
+ , fieldBoosts(NULL)
+ , termBuffer(_CLNEW Term)
+{
+ //Pre - d contains a valid reference to a Directory
+ // d contains a valid reference to a Analyzer
+ // mfl > 0 and contains the maximum field length
+ //Post - Instance has been created
+
+ CND_PRECONDITION(((mfl > 0) || (mfl == IndexWriter::FIELD_TRUNC_POLICY__WARN)),
+ "mfl is 0 or smaller than IndexWriter::FIELD_TRUNC_POLICY__WARN")
+
+ fieldInfos = NULL;
+ fieldLengths = NULL;
+}
+
+DocumentWriter::DocumentWriter(CL_NS(store)::Directory* d,
+ CL_NS(analysis)::Analyzer* a, IndexWriter* writer)
+ : analyzer(a)
+ , directory(d)
+ , maxFieldLength(writer->getMaxFieldLength())
+ , fieldInfos(NULL)
+ , fieldLengths(NULL)
+ , similarity(writer->getSimilarity())
+ , termIndexInterval(writer->getTermIndexInterval())
+ , fieldPositions(NULL)
+ , fieldBoosts(NULL)
+ , termBuffer(_CLNEW Term)
+{
+ //Pre - d contains a valid reference to a Directory
+ // d contains a valid reference to a Analyzer
+ // mfl > 0 and contains the maximum field length
+ //Post - Instance has been created
+
+ CND_PRECONDITION(((maxFieldLength > 0)
+ || (maxFieldLength == IndexWriter::FIELD_TRUNC_POLICY__WARN)),
+ "mfl is 0 or smaller than IndexWriter::FIELD_TRUNC_POLICY__WARN")
+
+ fieldInfos = NULL;
+ fieldLengths = NULL;
+
+}
+
+DocumentWriter::~DocumentWriter()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+ clearPostingTable();
+ _CLDELETE( fieldInfos );
+ _CLDELETE_ARRAY(fieldLengths);
+ _CLDELETE_ARRAY(fieldPositions);
+ _CLDELETE_ARRAY(fieldBoosts);
+ _CLDELETE_ARRAY(fieldOffsets);
+
+ _CLDECDELETE(termBuffer);
+}
+
+void DocumentWriter::clearPostingTable()
+{
+ PostingTableType::iterator itr = postingTable.begin();
+ while (itr != postingTable.end()){
+ _CLDELETE(itr->second);
+ _CLLDECDELETE(itr->first);
+ ++itr;
+ }
+ postingTable.clear();
+}
+
+void DocumentWriter::addDocument(const QString& segment, Document* doc)
+{
+ CND_PRECONDITION(fieldInfos == NULL, "fieldInfos!=NULL")
+
+ // write field names
+ fieldInfos = _CLNEW FieldInfos();
+ fieldInfos->add(doc);
+
+ QString buf = Misc::segmentname(segment, QLatin1String(".fnm"));
+ fieldInfos->write(directory, buf);
+
+ // write field values
+ FieldsWriter fieldsWriter(directory, segment, fieldInfos);
+ try {
+ fieldsWriter.addDocument(doc);
+ } _CLFINALLY (
+ fieldsWriter.close()
+ );
+
+ // clear postingTable
+ clearPostingTable();
+
+ int32_t fieldInfoSize = fieldInfos->size();
+ fieldLengths = _CL_NEWARRAY(int32_t, fieldInfoSize); // init fieldLengths
+ fieldPositions = _CL_NEWARRAY(int32_t, fieldInfoSize); // init fieldPositions
+ fieldOffsets = _CL_NEWARRAY(int32_t, fieldInfoSize); // init fieldOffsets
+ fieldBoosts = _CL_NEWARRAY(qreal, fieldInfoSize); // init fieldBoosts
+
+ qreal fbd = doc->getBoost();
+ for (int32_t i = 0; i < fieldInfoSize; ++i) {
+ fieldLengths[i] = 0;
+ fieldPositions[i] = 0;
+ fieldOffsets[i] = 0;
+ //initialise fieldBoost array with default boost
+ fieldBoosts[i] = fbd;
+ }
+
+ // invert doc into postingTable
+ invertDocument(doc);
+
+ // sort postingTable into an array
+ Posting** postings = NULL;
+ int32_t postingsLength = 0;
+ sortPostingTable(postings, postingsLength);
+
+ //DEBUG:
+ /*for (int32_t i = 0; i < postingsLength; i++) {
+ Posting* posting = postings[i];
+
+ TCHAR* b = posting->term->toString();
+ _cout << b << " freq=" << posting->freq;
+ _CLDELETE(b);
+
+ _cout << " pos=" << posting->positions[0];
+ for (int32_t j = 1; j < posting->freq; j++)
+ _cout <<"," << posting->positions[j];
+
+ _cout << endl;
+ }*/
+
+
+ // write postings
+ writePostings(postings, postingsLength, segment);
+
+ // write norms of indexed fields
+ writeNorms(segment);
+ _CLDELETE_ARRAY(postings);
+}
+
+void DocumentWriter::sortPostingTable(Posting**& array, int32_t& arraySize)
+{
+ // copy postingTable into an array
+ arraySize = postingTable.size();
+ array = _CL_NEWARRAY(Posting*,arraySize);
+ PostingTableType::iterator postings = postingTable.begin();
+ int32_t i=0;
+ while ( postings != postingTable.end() ){
+ array[i] = (Posting*)postings->second;
+ postings++;
+ i++;
+ }
+ // sort the array
+ quickSort(array, 0, i - 1);
+}
+
+
+void DocumentWriter::invertDocument(const Document* doc)
+{
+ DocumentFieldEnumeration* fields = doc->fields();
+ try {
+ while (fields->hasMoreElements()) {
+ Field* field = (Field*)fields->nextElement();
+ const TCHAR* fieldName = field->name();
+ const int32_t fieldNumber = fieldInfos->fieldNumber(fieldName);
+
+ int32_t length = fieldLengths[fieldNumber]; // length of field
+ int32_t position = fieldPositions[fieldNumber]; // position in field
+ if (length>0)
+ position+=analyzer->getPositionIncrementGap(fieldName);
+ int32_t offset = fieldOffsets[fieldNumber]; // offset field
+
+ if (field->isIndexed()) {
+ if (!field->isTokenized()) { // un-tokenized field
+ //FEATURE: this is bug in java: if using a Reader, then
+ //field value will not be added. With CLucene, an untokenized
+ //field with a reader will still be added (if it isn't stored,
+ //because if it's stored, then the reader has already been read.
+ const TCHAR* charBuf = NULL;
+ int64_t dataLen = 0;
+
+ if (field->stringValue() == NULL && !field->isStored() ) {
+ CL_NS(util)::Reader* r = field->readerValue();
+ // this call tries to read the entire stream
+ // this may invalidate the string for the further calls
+ // it may be better to do this via a FilterReader
+ // TODO make a better implementation of this
+ dataLen = r->read(charBuf, LUCENE_INT32_MAX_SHOULDBE);
+ if (dataLen == -1)
+ dataLen = 0;
+ //todo: would be better to pass the string length, in case
+ //a null char is passed, but then would need to test the output too.
+ } else {
+ charBuf = field->stringValue();
+ dataLen = _tcslen(charBuf);
+ }
+
+ if(field->isStoreOffsetWithTermVector()){
+ TermVectorOffsetInfo tio;
+ tio.setStartOffset(offset);
+ tio.setEndOffset(offset + dataLen);
+ addPosition(fieldName, charBuf, position++, &tio );
+ }else
+ addPosition(fieldName, charBuf, position++, NULL);
+ offset += dataLen;
+ length++;
+ } else { // field must be tokenized
+ CL_NS(util)::Reader* reader; // find or make Reader
+ bool delReader = false;
+ if (field->readerValue() != NULL) {
+ reader = field->readerValue();
+ } else if (field->stringValue() != NULL) {
+ reader = _CLNEW CL_NS(util)::StringReader(
+ field->stringValue(),_tcslen(field->stringValue()),
+ false);
+ delReader = true;
+ } else {
+ _CLTHROWA(CL_ERR_IO,"field must have either String or Reader value");
+ }
+
+ try {
+ // Tokenize field and add to postingTable.
+ CL_NS(analysis)::TokenStream* stream =
+ analyzer->tokenStream(fieldName, reader);
+
+ try {
+ CL_NS(analysis)::Token t;
+ int32_t lastTokenEndOffset = -1;
+ while (stream->next(&t)) {
+ position += (t.getPositionIncrement() - 1);
+
+ if(field->isStoreOffsetWithTermVector()){
+ TermVectorOffsetInfo tio;
+ tio.setStartOffset(offset + t.startOffset());
+ tio.setEndOffset(offset + t.endOffset());
+ addPosition(fieldName, t.termText(), position++, &tio);
+ } else
+ addPosition(fieldName, t.termText(), position++, NULL);
+
+ lastTokenEndOffset = t.endOffset();
+ length++;
+ // Apply field truncation policy.
+ if (maxFieldLength != IndexWriter::FIELD_TRUNC_POLICY__WARN) {
+ // The client programmer has explicitly authorized us to
+ // truncate the token stream after maxFieldLength tokens.
+ if ( length > maxFieldLength)
+ break;
+ } else if (length > IndexWriter::DEFAULT_MAX_FIELD_LENGTH) {
+ const TCHAR* errMsgBase =
+ _T("Indexing a huge number of tokens from a single")
+ _T(" field (\"%s\", in this case) can cause CLucene")
+ _T(" to use memory excessively.")
+ _T(" By default, CLucene will accept only %s tokens")
+ _T(" tokens from a single field before forcing the")
+ _T(" client programmer to specify a threshold at")
+ _T(" which to truncate the token stream.")
+ _T(" You should set this threshold via")
+ _T(" IndexReader::maxFieldLength (set to LUCENE_INT32_MAX")
+ _T(" to disable truncation, or a value to specify maximum number of fields).");
+
+ TCHAR defaultMaxAsChar[34];
+ _i64tot(IndexWriter::DEFAULT_MAX_FIELD_LENGTH,
+ defaultMaxAsChar, 10
+ );
+ int32_t errMsgLen = _tcslen(errMsgBase)
+ + _tcslen(fieldName)
+ + _tcslen(defaultMaxAsChar);
+ TCHAR* errMsg = _CL_NEWARRAY(TCHAR,errMsgLen+1);
+
+ _sntprintf(errMsg, errMsgLen,errMsgBase, fieldName, defaultMaxAsChar);
+
+ _CLTHROWT_DEL(CL_ERR_Runtime,errMsg);
+ }
+ } // while token->next
+
+ if(lastTokenEndOffset != -1 )
+ offset += lastTokenEndOffset + 1;
+ } _CLFINALLY (
+ stream->close();
+ _CLDELETE(stream);
+ );
+ } _CLFINALLY (
+ if (delReader) {
+ _CLDELETE(reader);
+ }
+ );
+ } // if/else field is to be tokenized
+ fieldLengths[fieldNumber] = length; // save field length
+ fieldPositions[fieldNumber] = position; // save field position
+ fieldBoosts[fieldNumber] *= field->getBoost();
+ fieldOffsets[fieldNumber] = offset;
+ } // if field is to beindexed
+ } // while more fields available
+ } _CLFINALLY (
+ _CLDELETE(fields);
+ );
+}
+
+void DocumentWriter::addPosition(const TCHAR* field, const TCHAR* text,
+ const int32_t position, TermVectorOffsetInfo* offset)
+{
+ termBuffer->set(field,text,false);
+
+ Posting* ti = postingTable.get(termBuffer);
+ if (ti != NULL) { // word seen before
+ int32_t freq = ti->freq;
+ if (ti->positions.length == freq) {
+ // positions array is full, realloc its size
+ ti->positions.length = freq*2;
+ ti->positions.values = (int32_t*)realloc(ti->positions.values, ti->positions.length * sizeof(int32_t));
+ }
+ ti->positions.values[freq] = position; // add new position
+
+ if (offset != NULL) {
+ if (ti->offsets.length == freq){
+ ti->offsets.length = freq*2;
+ ti->offsets.values = (TermVectorOffsetInfo*)realloc(ti->offsets.values, ti->offsets.length * sizeof(TermVectorOffsetInfo));
+ }
+ ti->offsets[freq] = *offset;
+ }
+
+ ti->freq = freq + 1; // update frequency
+ } else { // word not seen before
+ Term* term = _CLNEW Term( field, text, false);
+ postingTable.put(term, _CLNEW Posting(term, position, offset));
+ }
+}
+
+//static
+void DocumentWriter::quickSort(Posting**& postings, const int32_t lo, const int32_t hi)
+{
+ if(lo >= hi)
+ return;
+
+ int32_t mid = (lo + hi) / 2;
+
+ if(postings[lo]->term->compareTo(postings[mid]->term) > 0) {
+ Posting* tmp = postings[lo];
+ postings[lo] = postings[mid];
+ postings[mid] = tmp;
+ }
+
+ if(postings[mid]->term->compareTo(postings[hi]->term) > 0) {
+ Posting* tmp = postings[mid];
+ postings[mid] = postings[hi];
+ postings[hi] = tmp;
+
+ if(postings[lo]->term->compareTo(postings[mid]->term) > 0) {
+ Posting* tmp2 = postings[lo];
+ postings[lo] = postings[mid];
+ postings[mid] = tmp2;
+ }
+ }
+
+ int32_t left = lo + 1;
+ int32_t right = hi - 1;
+
+ if (left >= right)
+ return;
+
+ const Term* partition = postings[mid]->term; //not kept, so no need to finalize
+
+ for( ;; ) {
+ while(postings[right]->term->compareTo(partition) > 0)
+ --right;
+
+ while(left < right && postings[left]->term->compareTo(partition) <= 0)
+ ++left;
+
+ if(left < right) {
+ Posting* tmp = postings[left];
+ postings[left] = postings[right];
+ postings[right] = tmp;
+ --right;
+ } else {
+ break;
+ }
+ }
+
+ quickSort(postings, lo, left);
+ quickSort(postings, left + 1, hi);
+}
+
+void DocumentWriter::writePostings(Posting** postings,
+ const int32_t postingsLength, const QString& segment)
+{
+ #define __DOCLOSE(obj) \
+ if (obj!=NULL) { \
+ try { \
+ obj->close(); \
+ _CLDELETE(obj); \
+ } catch(CLuceneError &e) { \
+ ierr = e.number(); \
+ err = e.what(); \
+ } catch(...) { \
+ err = "Unknown error while closing posting tables"; \
+ } \
+ }
+
+ IndexOutput* freq = NULL;
+ IndexOutput* prox = NULL;
+ TermInfosWriter* tis = NULL;
+ TermVectorsWriter* termVectorWriter = NULL;
+ try {
+ //open files for inverse index storage
+ QString buf = Misc::segmentname(segment, QLatin1String(".frq"));
+ freq = directory->createOutput(buf);
+
+ buf = Misc::segmentname(segment, QLatin1String(".prx"));
+ prox = directory->createOutput(buf);
+
+ tis = _CLNEW TermInfosWriter(directory, segment, fieldInfos,
+ termIndexInterval);
+ TermInfo* ti = _CLNEW TermInfo();
+ const TCHAR* currentField = NULL;
+ for (int32_t i = 0; i < postingsLength; i++) {
+ Posting* posting = postings[i];
+
+ // add an entry to the dictionary with pointers to prox and freq files
+ ti->set(1, freq->getFilePointer(), prox->getFilePointer(), -1);
+ tis->add(posting->term, ti);
+
+ // add an entry to the freq file
+ int32_t postingFreq = posting->freq;
+ if (postingFreq == 1) // optimize freq=1
+ freq->writeVInt(1); // set low bit of doc num.
+ else {
+ freq->writeVInt(0); // the document number
+ freq->writeVInt(postingFreq); // frequency in doc
+ }
+
+ int32_t lastPosition = 0; // write positions
+ for (int32_t j = 0; j < postingFreq; ++j) { // use delta-encoding
+ prox->writeVInt(posting->positions.values[j] - lastPosition);
+ lastPosition = posting->positions.values[j];
+ }
+
+ // check to see if we switched to a new field
+ const TCHAR* termField = posting->term->field();
+ if ( currentField == NULL || _tcscmp(currentField,termField) != 0 ) {
+ //todo, can we do an intern'd check?
+ // changing field - see if there is something to save
+ currentField = termField;
+ FieldInfo* fi = fieldInfos->fieldInfo(currentField);
+
+ if (fi->storeTermVector) {
+ if (termVectorWriter == NULL) {
+ termVectorWriter = _CLNEW TermVectorsWriter(directory,
+ segment, fieldInfos);
+ termVectorWriter->openDocument();
+ }
+ termVectorWriter->openField(currentField);
+ } else if (termVectorWriter != NULL) {
+ termVectorWriter->closeField();
+ }
+ }
+ if (termVectorWriter != NULL && termVectorWriter->isFieldOpen()) {
+ termVectorWriter->addTerm(posting->term->text(), postingFreq,
+ &posting->positions, &posting->offsets);
+ }
+ }
+ if (termVectorWriter != NULL)
+ termVectorWriter->closeDocument();
+ _CLDELETE(ti);
+ } _CLFINALLY (
+ const char* err = NULL;
+ int32_t ierr = 0;
+
+ // make an effort to close all streams we can but remember and re-throw
+ // the first exception encountered in this process
+ __DOCLOSE(freq);
+ __DOCLOSE(prox);
+ __DOCLOSE(tis);
+ __DOCLOSE(termVectorWriter);
+ if (err != NULL)
+ _CLTHROWA(ierr,err);
+ );
+}
+
+void DocumentWriter::writeNorms(const QString& segment)
+{
+ for(int32_t n = 0; n < fieldInfos->size(); n++){
+ FieldInfo* fi = fieldInfos->fieldInfo(n);
+ if(fi->isIndexed && !fi->omitNorms) {
+ qreal norm = fieldBoosts[n] * similarity->lengthNorm(
+ fi->name, fieldLengths[n]);
+
+ QString fn(segment + QLatin1String(".f%1"));
+ IndexOutput* norms = directory->createOutput(fn.arg(n));
+ try {
+ norms->writeByte(CL_NS(search)::Similarity::encodeNorm(norm));
+ }_CLFINALLY (
+ norms->close();
+ _CLDELETE(norms);
+ )
+ }
+ }
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/DocumentWriter.h b/3rdparty/clucene/src/CLucene/index/DocumentWriter.h
new file mode 100644
index 000000000..7096ba3ee
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/DocumentWriter.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_DocumentWriter_
+#define _lucene_index_DocumentWriter_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/analysis/AnalysisHeader.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/store/Directory.h"
+#include "FieldInfos.h"
+#include "IndexWriter.h"
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/document/Field.h"
+#include "TermInfo.h"
+#include "CLucene/search/Similarity.h"
+#include "TermInfosWriter.h"
+#include "FieldsWriter.h"
+#include "Term.h"
+
+CL_NS_DEF(index)
+
+class DocumentWriter : LUCENE_BASE
+{
+public:
+ // info about a Term in a doc
+ class Posting : LUCENE_BASE
+ {
+ public:
+ Term* term; // the Term
+ int32_t freq; // its frequency in doc
+ Array<int32_t> positions; // positions it occurs at
+ Array<TermVectorOffsetInfo> offsets;
+
+ Posting(Term* t, const int32_t position, TermVectorOffsetInfo* offset);
+ ~Posting();
+ };
+
+private:
+ CL_NS(analysis)::Analyzer* analyzer;
+ CL_NS(store)::Directory* directory;
+ FieldInfos* fieldInfos; //array
+ const int32_t maxFieldLength;
+ CL_NS(search)::Similarity* similarity;
+ int32_t termIndexInterval;
+
+ // Keys are Terms, values are Postings.
+ // Used to buffer a document before it is written to the index.
+ typedef CL_NS(util)::CLHashtable<Term*, Posting*, Term::Compare,
+ Term::Equals> PostingTableType;
+ PostingTableType postingTable;
+ int32_t* fieldLengths; //array
+ int32_t* fieldPositions; //array
+ int32_t* fieldOffsets; //array
+ qreal* fieldBoosts; //array
+
+ Term* termBuffer;
+public:
+ /** This ctor used by test code only.
+ *
+ * @param directory The directory to write the document information to
+ * @param analyzer The analyzer to use for the document
+ * @param similarity The Similarity function
+ * @param maxFieldLength The maximum number of tokens a field may have
+ */
+ DocumentWriter(CL_NS(store)::Directory* d, CL_NS(analysis)::Analyzer* a,
+ CL_NS(search)::Similarity* similarity, const int32_t maxFieldLength);
+
+ DocumentWriter(CL_NS(store)::Directory* directory,
+ CL_NS(analysis)::Analyzer* analyzer, IndexWriter* writer);
+ ~DocumentWriter();
+
+ void addDocument(const QString& segment, CL_NS(document)::Document* doc);
+
+
+private:
+ // Tokenizes the fields of a document into Postings.
+ void invertDocument(const CL_NS(document)::Document* doc);
+
+ void addPosition(const TCHAR* field, const TCHAR* text,
+ const int32_t position, TermVectorOffsetInfo* offset);
+
+ void sortPostingTable(Posting**& array, int32_t& arraySize);
+
+ static void quickSort(Posting**& postings, const int32_t lo, const int32_t hi);
+
+ void writePostings(Posting** postings, const int32_t postingsLength,
+ const QString& segment);
+
+ void writeNorms(const QString& segment);
+
+ void clearPostingTable();
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/FieldInfo.h b/3rdparty/clucene/src/CLucene/index/FieldInfo.h
new file mode 100644
index 000000000..387c4a6ac
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/FieldInfo.h
@@ -0,0 +1,16 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_index_FieldInfo_
+#define _lucene_index_FieldInfo_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#error "This header is deprecated, use FieldInfos.h instead"
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/FieldInfos.cpp b/3rdparty/clucene/src/CLucene/index/FieldInfos.cpp
new file mode 100644
index 000000000..0c66882f4
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/FieldInfos.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "FieldInfos.h"
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/document/Field.h"
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/Misc.h"
+#include "CLucene/util/StringIntern.h"
+
+CL_NS_USE(store)
+CL_NS_USE(document)
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+FieldInfo::FieldInfo(const TCHAR* _fieldName, bool _isIndexed,
+ int32_t _fieldNumber, bool _storeTermVector, bool _storeOffsetWithTermVector,
+ bool _storePositionWithTermVector, bool _omitNorms)
+ : name(CLStringIntern::intern(_fieldName CL_FILELINE))
+ , isIndexed(_isIndexed)
+ , number(_fieldNumber)
+ , storeTermVector(_storeTermVector)
+ , storeOffsetWithTermVector(_storeOffsetWithTermVector)
+ , storePositionWithTermVector(_storeTermVector)
+ , omitNorms(_omitNorms)
+{
+}
+
+FieldInfo::~FieldInfo()
+{
+ CL_NS(util)::CLStringIntern::unintern(name);
+}
+
+// #pragma mark -- FieldInfos
+
+FieldInfos::FieldInfos()
+ : byName(false, false)
+ , byNumber(true)
+{
+}
+
+FieldInfos::~FieldInfos()
+{
+ byName.clear();
+ byNumber.clear();
+}
+
+FieldInfos::FieldInfos(Directory* d, const QString& name)
+ : byName(false, false)
+ , byNumber(true)
+{
+ IndexInput* input = d->openInput(name);
+ try {
+ read(input);
+ } _CLFINALLY (
+ input->close();
+ _CLDELETE(input);
+ );
+}
+
+void FieldInfos::add(const Document* doc)
+{
+ DocumentFieldEnumeration* fields = doc->fields();
+ Field* field;
+ while (fields->hasMoreElements()) {
+ field = fields->nextElement();
+ add(field->name(), field->isIndexed(), field->isTermVectorStored());
+ }
+ _CLDELETE(fields);
+}
+
+void FieldInfos::add(const TCHAR* name, bool isIndexed, bool storeTermVector,
+ bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms)
+{
+ FieldInfo* fi = fieldInfo(name);
+ if (fi == NULL) {
+ addInternal(name, isIndexed, storeTermVector,
+ storePositionWithTermVector,
+ storeOffsetWithTermVector, omitNorms);
+ } else {
+ if (fi->isIndexed != isIndexed) {
+ // once indexed, always index
+ fi->isIndexed = true;
+ }
+
+ if (fi->storeTermVector != storeTermVector) {
+ // once vector, always vector
+ fi->storeTermVector = true;
+ }
+
+ if (fi->storePositionWithTermVector != storePositionWithTermVector) {
+ // once vector, always vector
+ fi->storePositionWithTermVector = true;
+ }
+
+ if (fi->storeOffsetWithTermVector != storeOffsetWithTermVector) {
+ // once vector, always vector
+ fi->storeOffsetWithTermVector = true;
+ }
+
+ if (fi->omitNorms != omitNorms) {
+ // once norms are stored, always store
+ fi->omitNorms = false;
+ }
+ }
+}
+
+void FieldInfos::add(const TCHAR** names, bool isIndexed, bool storeTermVectors,
+ bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms)
+{
+ int32_t i=0;
+ while (names[i] != NULL) {
+ add(names[i], isIndexed, storeTermVectors, storePositionWithTermVector,
+ storeOffsetWithTermVector, omitNorms);
+ ++i;
+ }
+}
+
+int32_t FieldInfos::fieldNumber(const TCHAR* fieldName) const
+{
+ FieldInfo* fi = fieldInfo(fieldName);
+ return (fi != NULL) ? fi->number : -1;
+}
+
+FieldInfo* FieldInfos::fieldInfo(const TCHAR* fieldName) const
+{
+ return byName.get(fieldName);
+}
+
+const TCHAR* FieldInfos::fieldName(const int32_t fieldNumber) const
+{
+ FieldInfo* fi = fieldInfo(fieldNumber);
+ return (fi == NULL) ? LUCENE_BLANK_STRING : fi->name;
+}
+
+FieldInfo* FieldInfos::fieldInfo(const int32_t fieldNumber) const
+{
+ if (fieldNumber < 0 || (size_t)fieldNumber >= byNumber.size())
+ return NULL;
+ return byNumber[fieldNumber];
+}
+
+int32_t FieldInfos::size() const
+{
+ return byNumber.size();
+}
+
+void FieldInfos::write(Directory* d, const QString& name) const
+{
+ IndexOutput* output = d->createOutput(name);
+ try {
+ write(output);
+ } _CLFINALLY (
+ output->close();
+ _CLDELETE(output);
+ );
+}
+
+void FieldInfos::write(IndexOutput* output) const
+{
+ output->writeVInt(size());
+ FieldInfo* fi;
+ uint8_t bits;
+ for (int32_t i = 0; i < size(); ++i) {
+ fi = fieldInfo(i);
+ bits = 0x0;
+ if (fi->isIndexed)
+ bits |= IS_INDEXED;
+
+ if (fi->storeTermVector)
+ bits |= STORE_TERMVECTOR;
+
+ if (fi->storePositionWithTermVector)
+ bits |= STORE_POSITIONS_WITH_TERMVECTOR;
+
+ if (fi->storeOffsetWithTermVector)
+ bits |= STORE_OFFSET_WITH_TERMVECTOR;
+
+ if (fi->omitNorms)
+ bits |= OMIT_NORMS;
+
+ output->writeString(fi->name, _tcslen(fi->name));
+ output->writeByte(bits);
+ }
+}
+
+void FieldInfos::read(IndexInput* input)
+{
+ int32_t size = input->readVInt();
+ for (int32_t i = 0; i < size; ++i) {
+ // we could read name into a string buffer, but we can't be sure what
+ // the maximum field length will be.
+ TCHAR* name = input->readString();
+ uint8_t bits = input->readByte();
+ bool isIndexed = (bits & IS_INDEXED) != 0;
+ bool storeTermVector = (bits & STORE_TERMVECTOR) != 0;
+ bool storePositionsWithTermVector =
+ (bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0;
+ bool storeOffsetWithTermVector = (bits & STORE_OFFSET_WITH_TERMVECTOR) != 0;
+ bool omitNorms = (bits & OMIT_NORMS) != 0;
+
+ addInternal(name, isIndexed, storeTermVector,
+ storePositionsWithTermVector, storeOffsetWithTermVector, omitNorms);
+ _CLDELETE_CARRAY(name);
+ }
+}
+
+void FieldInfos::addInternal(const TCHAR* name, bool isIndexed,
+ bool storeTermVector, bool storePositionWithTermVector,
+ bool storeOffsetWithTermVector, bool omitNorms)
+{
+ FieldInfo* fi = _CLNEW FieldInfo(name, isIndexed, byNumber.size(),
+ storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector,
+ omitNorms);
+ byNumber.push_back(fi);
+ byName.put(fi->name, fi);
+}
+
+bool FieldInfos::hasVectors() const
+{
+ for (int32_t i = 0; i < size(); i++) {
+ if (fieldInfo(i)->storeTermVector)
+ return true;
+ }
+ return false;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/FieldInfos.h b/3rdparty/clucene/src/CLucene/index/FieldInfos.h
new file mode 100644
index 000000000..7b6d0f56d
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/FieldInfos.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_FieldInfos_
+#define _lucene_index_FieldInfos_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/VoidList.h"
+
+CL_NS_DEF(index)
+
+class FieldInfo : LUCENE_BASE
+{
+ public:
+ //name of the field
+ const TCHAR* name;
+
+ //Is field indexed? true = yes false = no
+ bool isIndexed;
+
+ //field number
+ const int32_t number;
+
+ // true if term vector for this field should be stored
+ bool storeTermVector;
+ bool storeOffsetWithTermVector;
+ bool storePositionWithTermVector;
+
+ bool omitNorms; // omit norms associated with indexed fields
+
+ //Func - Constructor
+ // Initialises FieldInfo.
+ // na holds the name of the field
+ // tk indicates whether this field is indexed or not
+ // nu indicates its number
+ //Pre - na != NULL and holds the name of the field
+ // tk is true or false
+ // number >= 0
+ //Post - The FieldInfo instance has been created and initialized.
+ // name holds the duplicated string of na
+ // isIndexed = tk
+ // number = nu
+ FieldInfo(const TCHAR* fieldName, bool isIndexed, int32_t fieldNumber,
+ bool storeTermVector, bool storeOffsetWithTermVector,
+ bool storePositionWithTermVector, bool omitNorms);
+
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+ ~FieldInfo();
+};
+
+/* Access to the Field Info file that describes document fields and whether or
+ * not they are indexed. Each segment has a separate Field Info file. Objects
+ * of this class are thread-safe for multiple readers, but only one thread can
+ * be adding documents at a time, with no other reader or writer threads
+ * accessing this object.
+*/
+class FieldInfos : LUCENE_BASE
+{
+private:
+ // we now use internd field names, so we can use the voidCompare to
+ // directly compare the strings
+ typedef CL_NS(util)::CLHashMap<const TCHAR*, FieldInfo*,
+ CL_NS(util)::Compare::TChar,CL_NS(util)::Equals::TChar > defByName;
+ defByName byName;
+
+ CL_NS(util)::CLArrayList<FieldInfo*,
+ CL_NS(util)::Deletor::Object<FieldInfo> > byNumber;
+
+public:
+ enum {
+ IS_INDEXED = 0x1,
+ STORE_TERMVECTOR = 0x2,
+ STORE_POSITIONS_WITH_TERMVECTOR = 0x4,
+ STORE_OFFSET_WITH_TERMVECTOR = 0x8,
+ OMIT_NORMS = 0x10
+ };
+
+ FieldInfos();
+ ~FieldInfos();
+
+ // Construct a FieldInfos object using the directory and the name of the
+ // file IndexInput
+ // @param d The directory to open the IndexInput from
+ // @param name Name of the file to open the IndexInput from in the Directory
+ // @throws IOException
+ // @see #read
+ FieldInfos(CL_NS(store)::Directory* d, const QString& name);
+
+ int32_t fieldNumber(const TCHAR* fieldName)const;
+
+ // Return the fieldinfo object referenced by the fieldNumber.
+ // @param fieldNumber
+ // @return the FieldInfo object or null when the given fieldNumber
+ // doesn't exist.
+ FieldInfo* fieldInfo(const TCHAR* fieldName) const;
+
+ // Return the fieldName identified by its number.
+ // @param fieldNumber
+ // @return the fieldName or an empty string when the field
+ // with the given number doesn't exist.
+ const TCHAR* fieldName(const int32_t fieldNumber) const;
+
+ FieldInfo* fieldInfo(const int32_t fieldNumber) const;
+
+ int32_t size()const;
+
+ bool hasVectors() const;
+
+ // Adds field info for a Document.
+ void add(const CL_NS(document)::Document* doc);
+
+ // Merges in information from another FieldInfos.
+ void add(FieldInfos* other);
+
+
+ /** If the field is not yet known, adds it. If it is known, checks to make
+ * sure that the isIndexed flag is the same as was given previously for this
+ * field. If not - marks it as being indexed. Same goes for the TermVector
+ * parameters.
+ *
+ * @param name The name of the field
+ * @param isIndexed true if the field is indexed
+ * @param storeTermVector true if the term vector should be stored
+ * @param storePositionWithTermVector true if the term vector with positions should be stored
+ * @param storeOffsetWithTermVector true if the term vector with offsets should be stored
+ */
+ void add(const TCHAR* name, bool isIndexed, bool storeTermVector = false,
+ bool storePositionWithTermVector = false,
+ bool storeOffsetWithTermVector = false, bool omitNorms = false);
+
+ /**
+ * Assumes the fields are not storing term vectors
+ * @param names The names of the fields
+ * @param isIndexed true if the field is indexed
+ * @param storeTermVector true if the term vector should be stored
+ *
+ * @see #add(String, boolean)
+ */
+ void add(const TCHAR** names, bool isIndexed, bool storeTermVector = false,
+ bool storePositionWithTermVector = false,
+ bool storeOffsetWithTermVector = false, bool omitNorms = false);
+
+ void write(CL_NS(store)::Directory* d, const QString& name) const;
+ void write(CL_NS(store)::IndexOutput* output) const;
+
+private:
+ void read(CL_NS(store)::IndexInput* input);
+ void addInternal(const TCHAR* name, bool isIndexed, bool storeTermVector,
+ bool storePositionWithTermVector, bool storeOffsetWithTermVector,
+ bool omitNorms);
+
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/FieldsReader.cpp b/3rdparty/clucene/src/CLucene/index/FieldsReader.cpp
new file mode 100644
index 000000000..e3f9d1cc2
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/FieldsReader.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "FieldsReader.h"
+
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/Misc.h"
+#include "CLucene/store/Directory.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/document/Field.h"
+#include "FieldInfos.h"
+#include "FieldsWriter.h"
+
+CL_NS_USE(store)
+CL_NS_USE(document)
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+FieldsReader::FieldsReader(Directory* d, const QString& segment, FieldInfos* fn)
+ : fieldInfos(fn)
+{
+ //Func - Constructor
+ //Pre - d contains a valid reference to a Directory
+ // segment != NULL
+ // fn contains a valid reference to a FieldInfos
+ //Post - The instance has been created
+
+ CND_PRECONDITION(!segment.isEmpty(), "segment != NULL");
+
+ QString buf = Misc::segmentname(segment, QLatin1String(".fdt"));
+ fieldsStream = d->openInput(buf);
+
+ buf = Misc::segmentname(segment, QLatin1String(".fdx"));
+ indexStream = d->openInput(buf);
+
+ _size = (int32_t)indexStream->length() / 8;
+}
+
+FieldsReader::~FieldsReader()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+ close();
+}
+
+void FieldsReader::close()
+{
+ //Func - Closes the FieldsReader
+ //Pre - true
+ //Post - The FieldsReader has been closed
+ if (fieldsStream) {
+ fieldsStream->close();
+ _CLDELETE(fieldsStream);
+ }
+
+ if(indexStream) {
+ indexStream->close();
+ _CLDELETE(indexStream);
+ }
+}
+
+int32_t FieldsReader::size() const
+{
+ return _size;
+}
+
+bool FieldsReader::doc(int32_t n, Document* doc)
+{
+ if ( n * 8L > indexStream->length() )
+ return false;
+
+ indexStream->seek(n * 8L);
+ int64_t position = indexStream->readLong();
+ fieldsStream->seek(position);
+
+ int32_t numFields = fieldsStream->readVInt();
+ for (int32_t i = 0; i < numFields; i++) {
+ int32_t fieldNumber = fieldsStream->readVInt();
+ FieldInfo* fi = fieldInfos->fieldInfo(fieldNumber);
+
+ if ( fi == NULL )
+ _CLTHROWA(CL_ERR_IO, "Field stream is invalid");
+
+ uint8_t bits = fieldsStream->readByte();
+ if ((bits & FieldsWriter::FIELD_IS_BINARY) != 0) {
+ int32_t fieldLen = fieldsStream->readVInt();
+ FieldsReader::FieldsStreamHolder* subStream = new
+ FieldsReader::FieldsStreamHolder(fieldsStream, fieldLen);
+ uint8_t bits = Field::STORE_YES;
+ Field* f = _CLNEW Field(
+ fi->name, // name
+ subStream, // read value
+ bits);
+
+ doc->add(*f);
+
+ //now skip over the rest of the field
+ if (fieldsStream->getFilePointer() + fieldLen
+ == fieldsStream->length()) {
+ // set to eof
+ fieldsStream->seek(fieldsStream->getFilePointer() + fieldLen - 1);
+ fieldsStream->readByte();
+ } else {
+ fieldsStream->seek(fieldsStream->getFilePointer() + fieldLen);
+ }
+ } else {
+ uint8_t bits = Field::STORE_YES;
+ if (fi->isIndexed && (bits & FieldsWriter::FIELD_IS_TOKENIZED)!=0 )
+ bits |= Field::INDEX_TOKENIZED;
+ else if (fi->isIndexed && (bits & FieldsWriter::FIELD_IS_TOKENIZED) == 0)
+ bits |= Field::INDEX_UNTOKENIZED;
+ else
+ bits |= Field::INDEX_NO;
+
+ if (fi->storeTermVector) {
+ if (fi->storeOffsetWithTermVector) {
+ if (fi->storePositionWithTermVector) {
+ bits |= Field::TERMVECTOR_WITH_OFFSETS;
+ bits |= Field::TERMVECTOR_WITH_POSITIONS;
+ } else {
+ bits |= Field::TERMVECTOR_WITH_OFFSETS;
+ }
+ } else if (fi->storePositionWithTermVector) {
+ bits |= Field::TERMVECTOR_WITH_POSITIONS;
+ } else {
+ bits |= Field::TERMVECTOR_YES;
+ }
+ } else {
+ bits |= Field::TERMVECTOR_NO;
+ }
+
+ if ( (bits & FieldsWriter::FIELD_IS_COMPRESSED) != 0 ) {
+ bits |= Field::STORE_COMPRESS;
+ int32_t fieldLen = fieldsStream->readVInt();
+ FieldsStreamHolder* subStream = new
+ FieldsStreamHolder(fieldsStream, fieldLen);
+
+ // TODO: we dont have gzip inputstream available, must alert
+ // user to somehow use a gzip inputstream
+ Field* f = _CLNEW Field(
+ fi->name, // name
+ subStream, // read value
+ bits);
+
+ f->setOmitNorms(fi->omitNorms);
+ doc->add(*f);
+
+ // now skip over the rest of the field
+ if (fieldsStream->getFilePointer() + fieldLen
+ == fieldsStream->length()) {
+ //set to eof
+ fieldsStream->seek(fieldsStream->getFilePointer() + fieldLen - 1);
+ fieldsStream->readByte();
+ } else {
+ fieldsStream->seek(fieldsStream->getFilePointer() + fieldLen);
+ }
+ } else {
+ TCHAR* fvalue = fieldsStream->readString(true);
+ Field* f = _CLNEW Field(
+ fi->name, // name
+ fvalue, // read value
+ bits);
+ // TODO: could optimise this
+ _CLDELETE_CARRAY(fvalue);
+ f->setOmitNorms(fi->omitNorms);
+ doc->add(*f);
+ }
+ }
+ }
+ return true;
+}
+
+FieldsReader::FieldsStreamHolder::FieldsStreamHolder(IndexInput* indexInput,
+ int32_t subLength)
+{
+ this->indexInput = indexInput->clone();
+ this->indexInputStream = new IndexInputStream(this->indexInput);
+ this->subStream = new jstreams::SubInputStream<char>(indexInputStream,
+ subLength);
+
+ this->size = subStream->getSize();
+ this->position = subStream->getPosition();
+ this->error = subStream->getError();
+ this->status = subStream->getStatus();
+}
+
+FieldsReader::FieldsStreamHolder::~FieldsStreamHolder()
+{
+ delete subStream;
+ delete indexInputStream;
+
+ indexInput->close();
+ _CLDELETE(indexInput);
+}
+
+int32_t FieldsReader::FieldsStreamHolder::read(const char*& start, int32_t _min,
+ int32_t _max)
+{
+ int32_t ret = subStream->read(start,_min,_max);
+ this->position = subStream->getPosition();
+ this->error = subStream->getError();
+ this->status = subStream->getStatus();
+ return ret;
+}
+
+int64_t FieldsReader::FieldsStreamHolder::skip(int64_t ntoskip)
+{
+ int64_t ret = subStream->skip(ntoskip);
+ this->position = subStream->getPosition();
+ this->error = subStream->getError();
+ this->status = subStream->getStatus();
+ return ret;
+}
+
+int64_t FieldsReader::FieldsStreamHolder::reset(int64_t pos)
+{
+ int64_t ret = subStream->reset(pos);
+ this->position = subStream->getPosition();
+ this->error = subStream->getError();
+ this->status = subStream->getStatus();
+ return ret;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/FieldsReader.h b/3rdparty/clucene/src/CLucene/index/FieldsReader.h
new file mode 100644
index 000000000..53589a5cc
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/FieldsReader.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_FieldsReader_
+#define _lucene_index_FieldsReader_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/util/subinputstream.h"
+#include "CLucene/store/IndexInput.h"
+
+CL_NS_DEF(index)
+
+class FieldInfos;
+
+class FieldsReader : LUCENE_BASE
+{
+private:
+ const FieldInfos* fieldInfos;
+ CL_NS(store)::IndexInput* fieldsStream;
+ CL_NS(store)::IndexInput* indexStream;
+ int32_t _size;
+
+ class FieldsStreamHolder : public jstreams::StreamBase<char>
+ {
+ CL_NS(store)::IndexInput* indexInput;
+ CL_NS(store)::IndexInputStream* indexInputStream;
+ jstreams::SubInputStream<char>* subStream;
+
+ public:
+ FieldsStreamHolder(CL_NS(store)::IndexInput* indexInput, int32_t subLength);
+ ~FieldsStreamHolder();
+ int32_t read(const char*& start, int32_t _min, int32_t _max);
+ int64_t skip(int64_t ntoskip);
+ int64_t reset(int64_t pos);
+ };
+
+public:
+ FieldsReader(CL_NS(store)::Directory* d, const QString& segment, FieldInfos* fn);
+ ~FieldsReader();
+ void close();
+ int32_t size() const;
+ // loads the fields from n'th document into doc. returns true on success.
+ bool doc(int32_t n, CL_NS(document)::Document* doc);
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/FieldsWriter.cpp b/3rdparty/clucene/src/CLucene/index/FieldsWriter.cpp
new file mode 100644
index 000000000..ceb6735cb
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/FieldsWriter.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "FieldsWriter.h"
+
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/Reader.h"
+#include "CLucene/util/Misc.h"
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/IndexOutput.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/document/Field.h"
+#include "FieldInfos.h"
+
+CL_NS_USE(store)
+CL_NS_USE(util)
+CL_NS_USE(document)
+CL_NS_DEF(index)
+
+FieldsWriter::FieldsWriter(Directory* d, const QString& segment, FieldInfos* fn)
+ : fieldInfos(fn)
+{
+ //Func - Constructor
+ //Pre - d contains a valid reference to a directory
+ // segment != NULL and contains the name of the segment
+ //Post - fn contains a valid reference toa a FieldInfos
+
+ CND_PRECONDITION(!segment.isEmpty(), "segment is NULL");
+
+ QString buf = Misc::segmentname(segment, QLatin1String(".fdt"));
+ fieldsStream = d->createOutput(buf);
+
+ buf = Misc::segmentname(segment, QLatin1String(".fdx"));
+ indexStream = d->createOutput(buf);
+
+ CND_CONDITION(indexStream != NULL, "indexStream is NULL");
+}
+
+FieldsWriter::~FieldsWriter()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - Instance has been destroyed
+
+ close();
+}
+
+void FieldsWriter::close()
+{
+ //Func - Closes all streams and frees all resources
+ //Pre - true
+ //Post - All streams have been closed all resources have been freed
+
+ //Check if fieldsStream is valid
+ if (fieldsStream) {
+ //Close fieldsStream
+ fieldsStream->close();
+ _CLDELETE(fieldsStream);
+ }
+
+ //Check if indexStream is valid
+ if (indexStream) {
+ //Close indexStream
+ indexStream->close();
+ _CLDELETE(indexStream);
+ }
+}
+
+void FieldsWriter::addDocument(Document* doc)
+{
+ //Func - Adds a document
+ //Pre - doc contains a valid reference to a Document
+ // indexStream != NULL
+ // fieldsStream != NULL
+ //Post - The document doc has been added
+
+ CND_PRECONDITION(indexStream != NULL, "indexStream is NULL");
+ CND_PRECONDITION(fieldsStream != NULL, "fieldsStream is NULL");
+
+ indexStream->writeLong(fieldsStream->getFilePointer());
+
+ int32_t storedCount = 0;
+ DocumentFieldEnumeration* fields = doc->fields();
+ while (fields->hasMoreElements()) {
+ Field* field = fields->nextElement();
+ if (field->isStored())
+ storedCount++;
+ }
+ _CLDELETE(fields);
+ fieldsStream->writeVInt(storedCount);
+
+ fields = doc->fields();
+ while (fields->hasMoreElements()) {
+ Field* field = fields->nextElement();
+ if (field->isStored()) {
+ fieldsStream->writeVInt(fieldInfos->fieldNumber(field->name()));
+
+ uint8_t bits = 0;
+ if (field->isTokenized())
+ bits |= FieldsWriter::FIELD_IS_TOKENIZED;
+ if (field->isBinary())
+ bits |= FieldsWriter::FIELD_IS_BINARY;
+ if (field->isCompressed())
+ bits |= FieldsWriter::FIELD_IS_COMPRESSED;
+
+ fieldsStream->writeByte(bits);
+
+ if ( field->isCompressed()) {
+ _CLTHROWA(CL_ERR_Runtime,
+ "CLucene does not directly support compressed fields. "
+ "Write a compressed byte array instead");
+ } else {
+ // FEATURE: this problem in Java Lucene too, if using Reader,
+ // data is not stored.
+ //
+ // TODO: this is a logic bug...
+ // if the field is stored, and indexed, and is using a reader
+ // the field wont get indexed
+ //
+ // if we could write zero prefixed vints (therefore static
+ // length), then we could write a reader directly to the field
+ // indexoutput and then go back and write the data length.
+ // however this is not supported in lucene yet...
+ // if this is ever implemented, then it would make sense to
+ // also be able to combine the FieldsWriter and
+ // DocumentWriter::invertDocument process, and use a
+ // streamfilter to write the field data while the documentwrite
+ // analyses the document! how cool would that be! it would cut
+ // out all these buffers!!!
+
+ // compression is disabled for the current field
+ if (field->isBinary()) {
+ // TODO: since we currently don't support static length vints,
+ // we have to read the entire stream into memory first.... ugly!
+ jstreams::StreamBase<char>* stream = field->streamValue();
+ const char* sd;
+ // how do we make sure we read the entire index in now???
+ // TODO: we need to have a max amount, and guarantee its all
+ // in or throw an error...
+ int32_t rl = stream->read(sd,10000000,0);
+
+ if ( rl < 0 ) {
+ // TODO: could we detect this earlier and not actually
+ // write the field??
+ fieldsStream->writeVInt(0);
+ } else {
+ // TODO: if this int could be written with a constant
+ // length, then the stream could be read and written a
+ // bit at a time then the length is re-written at the end.
+ fieldsStream->writeVInt(rl);
+ fieldsStream->writeBytes((uint8_t*)sd, rl);
+ }
+ } else if (field->stringValue() == NULL ) {
+ // we must be using readerValue
+ CND_PRECONDITION(!field->isIndexed(),
+ "Cannot store reader if it is indexed too")
+ Reader* r = field->readerValue();
+
+ //read the entire string
+ const TCHAR* rv;
+ int64_t rl = r->read(rv, LUCENE_INT32_MAX_SHOULDBE);
+ if ( rl > LUCENE_INT32_MAX_SHOULDBE )
+ _CLTHROWA(CL_ERR_Runtime, "Field length too long");
+ else if ( rl < 0 )
+ rl = 0;
+
+ fieldsStream->writeString( rv, (int32_t)rl);
+ } else if (field->stringValue() != NULL ) {
+ fieldsStream->writeString(field->stringValue(),
+ _tcslen(field->stringValue()));
+ } else {
+ _CLTHROWA(CL_ERR_Runtime, "No values are set for the field");
+ }
+ }
+ }
+ }
+ _CLDELETE(fields);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/FieldsWriter.h b/3rdparty/clucene/src/CLucene/index/FieldsWriter.h
new file mode 100644
index 000000000..7dde5f225
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/FieldsWriter.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_FieldsWriter_
+#define _lucene_index_FieldsWriter_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/document/Document.h"
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/IndexOutput.h"
+
+CL_NS_DEF(index)
+
+class FieldInfos;
+
+class FieldsWriter : LUCENE_BASE
+{
+private:
+ FieldInfos* fieldInfos;
+
+ CL_NS(store)::IndexOutput* fieldsStream;
+ CL_NS(store)::IndexOutput* indexStream;
+
+public:
+ LUCENE_STATIC_CONSTANT(uint8_t, FIELD_IS_TOKENIZED = 0x1);
+ LUCENE_STATIC_CONSTANT(uint8_t, FIELD_IS_BINARY = 0x2);
+ LUCENE_STATIC_CONSTANT(uint8_t, FIELD_IS_COMPRESSED = 0x4);
+
+ FieldsWriter(CL_NS(store)::Directory* d, const QString& segment, FieldInfos* fn);
+ ~FieldsWriter();
+
+ void close();
+
+ void addDocument(CL_NS(document)::Document* doc);
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/IndexModifier.cpp b/3rdparty/clucene/src/CLucene/index/IndexModifier.cpp
new file mode 100644
index 000000000..1423cc7a8
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/IndexModifier.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "IndexModifier.h"
+
+#include "Term.h"
+#include "IndexWriter.h"
+#include "IndexReader.h"
+
+CL_NS_DEF(index)
+CL_NS_USE(util)
+CL_NS_USE(store)
+CL_NS_USE(analysis)
+CL_NS_USE(document)
+
+IndexModifier::IndexModifier(Directory* directory, Analyzer* analyzer, bool create) {
+ init(directory, analyzer, create);
+}
+
+IndexModifier::IndexModifier(const QString& dirName, Analyzer* analyzer, bool create) {
+ Directory* dir = FSDirectory::getDirectory(dirName, create);
+ init(dir, analyzer, create);
+}
+
+void IndexModifier::init(Directory* directory, Analyzer* analyzer, bool create) {
+ indexWriter = NULL;
+ indexReader = NULL;
+ this->analyzer = analyzer;
+ open = false;
+
+ useCompoundFile = true;
+ int32_t maxBufferedDocs = IndexWriter::DEFAULT_MAX_BUFFERED_DOCS;
+ this->maxFieldLength = IndexWriter::DEFAULT_MAX_FIELD_LENGTH;
+ int32_t mergeFactor = IndexWriter::DEFAULT_MERGE_FACTOR;
+
+ this->directory = _CL_POINTER(directory);
+ createIndexReader();
+ open = true;
+}
+
+IndexModifier::~IndexModifier(){
+ close();
+}
+
+void IndexModifier::assureOpen() const{
+ if (!open) {
+ _CLTHROWA(CL_ERR_IllegalState,"Index is closed");
+ }
+}
+
+void IndexModifier::createIndexWriter() {
+ if (indexWriter == NULL) {
+ if (indexReader != NULL) {
+ indexReader->close();
+ _CLDELETE(indexReader);
+ }
+ indexWriter = _CLNEW IndexWriter(directory, analyzer, false);
+ indexWriter->setUseCompoundFile(useCompoundFile);
+ //indexWriter->setMaxBufferedDocs(maxBufferedDocs);
+ indexWriter->setMaxFieldLength(maxFieldLength);
+ //indexWriter->setMergeFactor(mergeFactor);
+ }
+}
+
+void IndexModifier::createIndexReader() {
+ if (indexReader == NULL) {
+ if (indexWriter != NULL) {
+ indexWriter->close();
+ _CLDELETE(indexWriter);
+ }
+ indexReader = IndexReader::open(directory);
+ }
+}
+
+void IndexModifier::flush() {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ if (indexWriter != NULL) {
+ indexWriter->close();
+ _CLDELETE(indexWriter);
+ createIndexWriter();
+ } else {
+ indexReader->close();
+ _CLDELETE(indexReader);
+ createIndexReader();
+ }
+}
+
+void IndexModifier::addDocument(Document* doc, Analyzer* docAnalyzer) {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexWriter();
+ if (docAnalyzer != NULL)
+ indexWriter->addDocument(doc, docAnalyzer);
+ else
+ indexWriter->addDocument(doc);
+}
+
+int32_t IndexModifier::deleteDocuments(Term* term) {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexReader();
+ return indexReader->deleteDocuments(term);
+}
+
+void IndexModifier::deleteDocument(int32_t docNum) {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexReader();
+ indexReader->deleteDocument(docNum);
+}
+
+int32_t IndexModifier::docCount() {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ if (indexWriter != NULL)
+ return indexWriter->docCount();
+ else
+ return indexReader->numDocs();
+}
+
+void IndexModifier::optimize() {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexWriter();
+ indexWriter->optimize();
+}
+
+void IndexModifier::setUseCompoundFile(bool useCompoundFile) {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ if (indexWriter != NULL)
+ indexWriter->setUseCompoundFile(useCompoundFile);
+ this->useCompoundFile = useCompoundFile;
+}
+
+bool IndexModifier::getUseCompoundFile() {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexWriter();
+ return indexWriter->getUseCompoundFile();
+}
+
+void IndexModifier::setMaxFieldLength(int32_t maxFieldLength) {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ if (indexWriter != NULL)
+ indexWriter->setMaxFieldLength(maxFieldLength);
+ this->maxFieldLength = maxFieldLength;
+}
+
+int32_t IndexModifier::getMaxFieldLength() {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexWriter();
+ return indexWriter->getMaxFieldLength();
+}
+
+void IndexModifier::setMaxBufferedDocs(int32_t maxBufferedDocs) {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ if (indexWriter != NULL)
+ indexWriter->setMaxBufferedDocs(maxBufferedDocs);
+ this->maxBufferedDocs = maxBufferedDocs;
+}
+
+int32_t IndexModifier::getMaxBufferedDocs() {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexWriter();
+ return indexWriter->getMaxBufferedDocs();
+}
+void IndexModifier::setMergeFactor(int32_t mergeFactor) {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ if (indexWriter != NULL)
+ indexWriter->setMergeFactor(mergeFactor);
+ this->mergeFactor = mergeFactor;
+}
+
+int32_t IndexModifier::getMergeFactor() {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexWriter();
+ return indexWriter->getMergeFactor();
+}
+
+void IndexModifier::close() {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ if (indexWriter != NULL) {
+ indexWriter->close();
+ _CLDELETE(indexWriter);
+ } else {
+ indexReader->close();
+ _CLDELETE(indexReader);
+ }
+ _CLDECDELETE(directory)
+ open = false;
+}
+
+QString IndexModifier::toString() const
+{
+ QString ret(QLatin1String("Index@"));
+ return ret.append(directory->toString());
+}
+
+
+
+int64_t IndexModifier::getCurrentVersion() const{
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ return IndexReader::getCurrentVersion(directory);
+}
+
+TermDocs* IndexModifier::termDocs(Term* term){
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexReader();
+ return indexReader->termDocs(term);
+}
+
+TermEnum* IndexModifier::terms(Term* term){
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexReader();
+ if ( term != NULL )
+ return indexReader->terms(term);
+ else
+ return indexReader->terms();
+}
+
+
+ CL_NS(document)::Document* IndexModifier::document(const int32_t n){
+ Document* ret = _CLNEW Document;
+ if (!document(n,ret) )
+ _CLDELETE(ret);
+ return ret;
+ }
+bool IndexModifier::document(int32_t n, CL_NS(document)::Document* doc){
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ assureOpen();
+ createIndexReader();
+ return indexReader->document(n, doc);
+}
+CL_NS(store)::Directory* IndexModifier::getDirectory(){
+ return directory;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/IndexModifier.h b/3rdparty/clucene/src/CLucene/index/IndexModifier.h
new file mode 100644
index 000000000..4e9963f5a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/IndexModifier.h
@@ -0,0 +1,316 @@
+/*
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_IndexModifier_
+#define _lucene_index_IndexModifier_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/analysis/AnalysisHeader.h"
+
+CL_NS_DEF(index)
+
+class IndexReader;
+class IndexWriter;
+class Term;
+class TermDocs;
+class TermEnum;
+
+/**
+* A class to modify an index, i.e. to delete and add documents. This
+* class hides {@link IndexReader} and {@link IndexWriter} so that you
+* do not need to care about implementation details such as that adding
+* documents is done via IndexWriter and deletion is done via IndexReader.
+*
+* <p>Note that you cannot create more than one <code>IndexModifier</code> object
+* on the same directory at the same time.
+*
+* <p>Example usage:
+*
+* <div align="left" class="java">
+* <table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+* <tr>
+* <td nowrap="nowrap" valign="top" align="left">
+* <code>
+* //note this code will leak memory :)
+* Analyzer* analyzer = <b>new</b> StandardAnalyzer();<br/>
+* // create an index in /tmp/index, overwriting an existing one:<br/>
+* IndexModifier* indexModifier = <b>new</b> IndexModifier("/tmp/index", analyzer, <b>true</b>);<br/>
+* Document* doc = <b>new </b>Document*();<br/>
+* doc->add(*<b>new </b>Field("id", "1", Field::STORE_YES| Field::INDEX_UNTOKENIZED));<br/>
+* doc->add(*<b>new </b>Field("body", "a simple test", Field::STORE_YES, Field::INDEX_TOKENIZED));<br/>
+* indexModifier->addDocument(doc);<br/>
+* <b>int32_t </b>deleted = indexModifier->deleteDocuments(<b>new </b>Term("id", "1"));<br/>
+* printf("Deleted %d document", deleted);<br/>
+* indexModifier->flush();<br/>
+* printf( "$d docs in index", indexModifier->docCount() );<br/>
+* indexModifier->close();
+* </code></td>
+* </tr>
+* </table>
+* </div>
+*
+* <p>Not all methods of IndexReader and IndexWriter are offered by this
+* class. If you need access to additional methods, either use those classes
+* directly or implement your own class that extends <code>IndexModifier</code>.
+*
+* <p>Although an instance of this class can be used from more than one
+* thread, you will not get the best performance. You might want to use
+* IndexReader and IndexWriter directly for that (but you will need to
+* care about synchronization yourself then).
+*
+* <p>While you can freely mix calls to add() and delete() using this class,
+* you should batch you calls for best performance. For example, if you
+* want to update 20 documents, you should first delete all those documents,
+* then add all the new documents.
+*
+*/
+class IndexModifier : LUCENE_BASE
+{
+protected:
+ IndexWriter* indexWriter;
+ IndexReader* indexReader;
+
+ CL_NS(store)::Directory* directory;
+ CL_NS(analysis)::Analyzer* analyzer;
+ bool open;
+
+ // Lucene defaults:
+ bool useCompoundFile;
+ int32_t maxBufferedDocs;
+ int32_t maxFieldLength;
+ int32_t mergeFactor;
+
+public:
+
+ /**
+ * Open an index with write access.
+ *
+ * @param directory the index directory
+ * @param analyzer the analyzer to use for adding new documents
+ * @param create <code>true</code> to create the index or overwrite
+ * the existing one; <code>false</code> to append to the existing index
+ */
+ IndexModifier(CL_NS(store)::Directory* directory,
+ CL_NS(analysis)::Analyzer* analyzer, bool create);
+
+ ~IndexModifier();
+
+ /**
+ * Open an index with write access.
+ *
+ * @param dirName the index directory
+ * @param analyzer the analyzer to use for adding new documents
+ * @param create <code>true</code> to create the index or overwrite
+ * the existing one; <code>false</code> to append to the existing index
+ */
+ IndexModifier(const QString& dirName, CL_NS(analysis)::Analyzer* analyzer,
+ bool create);
+
+protected:
+
+ // Initialize an IndexWriter. @throws IOException
+ void init(CL_NS(store)::Directory* directory,
+ CL_NS(analysis)::Analyzer* analyzer, bool create);
+
+ // Throw an IllegalStateException if the index is closed.
+ // @throws IllegalStateException
+ void assureOpen() const;
+
+ // Close the IndexReader and open an IndexWriter. @throws IOException
+ void createIndexWriter();
+
+ // Close the IndexWriter and open an IndexReader. @throws IOException
+ void createIndexReader();
+
+public:
+ // Make sure all changes are written to disk. @throws IOException
+ void flush();
+
+ // Adds a document to this index, using the provided analyzer instead of
+ // the one specific in the constructor. If the document contains more than
+ // {@link #setMaxFieldLength(int32_t)} terms for a given field, the
+ // remainder are discarded.
+ // @see IndexWriter#addDocument(Document*, Analyzer*)
+ // @throws IllegalStateException if the index is closed
+ void addDocument(CL_NS(document)::Document* doc, CL_NS(analysis)::Analyzer*
+ docAnalyzer = NULL);
+
+
+ /**
+ * Deletes all documents containing <code>term</code>.
+ * This is useful if one uses a document field to hold a unique ID string for
+ * the document. Then to delete such a document, one merely constructs a
+ * term with the appropriate field and the unique ID string as its text and
+ * passes it to this method. Returns the number of documents deleted.
+ * @return the number of documents deleted
+ * @see IndexReader#deleteDocuments(Term*)
+ * @throws IllegalStateException if the index is closed
+ */
+ int32_t deleteDocuments(Term* term);
+
+ /**
+ * Deletes the document numbered <code>docNum</code>.
+ * @see IndexReader#deleteDocument(int32_t)
+ * @throws IllegalStateException if the index is closed
+ */
+ void deleteDocument(int32_t docNum);
+
+ /**
+ * Returns the number of documents currently in this index.
+ * @see IndexWriter#docCount()
+ * @see IndexReader#numDocs()
+ * @throws IllegalStateException if the index is closed
+ */
+ int32_t docCount();
+
+ /**
+ * Merges all segments together into a single segment, optimizing an index
+ * for search.
+ * @see IndexWriter#optimize()
+ * @throws IllegalStateException if the index is closed
+ */
+ void optimize();
+
+ /**
+ * Setting to turn on usage of a compound file. When on, multiple files
+ * for each segment are merged into a single file once the segment creation
+ * is finished. This is done regardless of what directory is in use.
+ * @see IndexWriter#setUseCompoundFile(bool)
+ * @throws IllegalStateException if the index is closed
+ */
+ void setUseCompoundFile(bool useCompoundFile);
+
+ /**
+ * @throws IOException
+ * @see IndexModifier#setUseCompoundFile(bool)
+ */
+ bool getUseCompoundFile();
+
+ /**
+ * The maximum number of terms that will be indexed for a single field in a
+ * document. This limits the amount of memory required for indexing, so that
+ * collections with very large files will not crash the indexing process by
+ * running out of memory.<p/>
+ * Note that this effectively truncates large documents, excluding from the
+ * index terms that occur further in the document. If you know your source
+ * documents are large, be sure to set this value high enough to accomodate
+ * the expected size. If you set it to Integer.MAX_VALUE, then the only limit
+ * is your memory, but you should anticipate an OutOfMemoryError.<p/>
+ * By default, no more than 10,000 terms will be indexed for a field.
+ * @see IndexWriter#setMaxFieldLength(int32_t)
+ * @throws IllegalStateException if the index is closed
+ */
+ void setMaxFieldLength(int32_t maxFieldLength);
+
+ /**
+ * @throws IOException
+ * @see IndexModifier#setMaxFieldLength(int32_t)
+ */
+ int32_t getMaxFieldLength();
+
+ /*
+ * The maximum number of terms that will be indexed for a single field in a
+ * document. This limits the amount of memory required for indexing, so that
+ * collections with very large files will not crash the indexing process by
+ * running out of memory.<p/>
+ * Note that this effectively truncates large documents, excluding from the
+ * index terms that occur further in the document. If you know your source
+ * documents are large, be sure to set this value high enough to accomodate
+ * the expected size. If you set it to Integer.MAX_VALUE, then the only limit
+ * is your memory, but you should anticipate an OutOfMemoryError.<p/>
+ * By default, no more than 10,000 terms will be indexed for a field.
+ * @see IndexWriter#setMaxBufferedDocs(int32_t)
+ * @throws IllegalStateException if the index is closed
+ */
+ void setMaxBufferedDocs(int32_t maxBufferedDocs);
+
+ // @see IndexModifier#setMaxBufferedDocs(int32_t) @throws IOException
+ int32_t getMaxBufferedDocs();
+
+ /*
+ * Determines how often segment indices are merged by addDocument(). With
+ * smaller values, less RAM is used while indexing, and searches on
+ * unoptimized indices are faster, but indexing speed is slower. With larger
+ * values, more RAM is used during indexing, and while searches on unoptimized
+ * indices are slower, indexing is faster. Thus larger values (&gt; 10) are
+ * best for batch index creation, and smaller values (&lt; 10) for indices
+ * that are interactively maintained.
+ * <p>This must never be less than 2. The default value is 10.
+ *
+ * @see IndexWriter#setMergeFactor(int32_t)
+ * @throws IllegalStateException if the index is closed
+ */
+ void setMergeFactor(int32_t mergeFactor);
+
+ /**
+ * @throws IOException
+ * @see IndexModifier#setMergeFactor(int32_t)
+ */
+ int32_t getMergeFactor();
+
+ /**
+ * Close this index, writing all pending changes to disk.
+ *
+ * @throws IllegalStateException if the index has been closed before already
+ */
+ void close();
+
+ QString toString() const;
+
+ /**
+ * Gets the version number of the currently open index.
+ */
+ int64_t getCurrentVersion() const;
+
+ /**
+ * Returns an enumeration of all the documents which contain term.
+ *
+ * Warning: This is not threadsafe. Make sure you lock the modifier object
+ * while using the TermDocs. If the IndexReader that the modifier manages
+ * is closed, the TermDocs object will fail.
+ */
+ TermDocs* termDocs(Term* term = NULL);
+
+ /**
+ * Returns an enumeration of all terms after a given term.
+ * If no term is given, an enumeration of all the terms
+ * in the index is returned.
+ * The enumeration is ordered by Term.compareTo(). Each term
+ * is greater than all that precede it in the enumeration.
+ *
+ * Warning: This is not threadsafe. Make sure you lock the modifier object
+ * while using the TermDocs. If the IndexReader that the modifier manages
+ * is closed, the Document will be invalid
+ */
+ TermEnum* terms(Term* term = NULL);
+
+ /**
+ * Returns the stored fields of the n-th Document in this index.
+ *
+ * Warning: This is not threadsafe. Make sure you lock the modifier object
+ * while using the TermDocs. If the IndexReader that the modifier manages
+ * is closed, the Document will be invalid
+ */
+ bool document(const int32_t n, CL_NS(document)::Document* doc);
+ _CL_DEPRECATED(document(i, document))
+ CL_NS(document)::Document* document(const int32_t n);
+
+ // Returns the directory used by this index.
+ CL_NS(store)::Directory* getDirectory();
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/IndexReader.cpp b/3rdparty/clucene/src/CLucene/index/IndexReader.cpp
new file mode 100644
index 000000000..91c735632
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/IndexReader.cpp
@@ -0,0 +1,668 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+# include <QtCore/QFile>
+# include <QtCore/QStringList>
+
+#include "CLucene/StdHeader.h"
+#include "IndexReader.h"
+#include "IndexWriter.h"
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/FSDirectory.h"
+#include "CLucene/store/Lock.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/search/Similarity.h"
+#include "SegmentInfos.h"
+#include "MultiReader.h"
+#include "Terms.h"
+
+CL_NS_USE(util)
+CL_NS_USE(store)
+CL_NS_DEF(index)
+
+IndexReader::IndexReader(Directory* dir)
+ : stale(false)
+ , hasChanges(false)
+ , closeDirectory(false)
+ , directoryOwner(false)
+ , segmentInfos(NULL)
+ , directory(_CL_POINTER(dir))
+ , writeLock(NULL)
+{
+}
+
+IndexReader::IndexReader(Directory* dir, SegmentInfos* infos, bool close)
+ : stale(false)
+ , hasChanges(false)
+ , closeDirectory(close)
+ , directoryOwner(true)
+ , segmentInfos(infos)
+ , directory(_CL_POINTER(dir))
+ , writeLock(NULL)
+{
+}
+
+IndexReader::~IndexReader()
+{
+ if (writeLock != NULL) {
+ writeLock->release();
+ _CLDELETE(writeLock);
+ }
+ _CLDELETE(segmentInfos);
+ _CLDECDELETE(directory);
+}
+
+IndexReader* IndexReader::open(const QString& path)
+{
+ //Func - Static method.
+ // Returns an IndexReader reading the index in an FSDirectory in the named path.
+ //Pre - path != NULL and contains the path of the index for which an IndexReader must be
+ // instantiated
+ // closeDir indicates if the directory needs to be closed
+ //Post - An IndexReader has been returned that reads tnhe index located at path
+
+ CND_PRECONDITION(!path.isEmpty(), "path is NULL");
+
+ Directory* dir = FSDirectory::getDirectory(path, false);
+ IndexReader* reader = open(dir, true);
+ //because fsdirectory will now have a refcount of 1 more than
+ //if the reader had been opened with a directory object,
+ //we need to do a refdec
+ _CLDECDELETE(dir);
+ return reader;
+}
+
+IndexReader* IndexReader::open(Directory* directory, bool closeDirectory)
+{
+ //Func - Static method.
+ // Returns an IndexReader reading the index in an FSDirectory in the named path.
+ //Pre - directory represents a directory
+ // closeDir indicates if the directory needs to be closed
+ //Post - An IndexReader has been returned that reads the index located at directory
+
+ // in- & inter-process sync
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+
+ //Instantiate an IndexReader::LockWith which can produce an IndexReader
+ LuceneLock* lock = directory->makeLock(QLatin1String("commit.lock"));
+ IndexReader::LockWith with(lock, directory);
+
+ IndexReader* ret = NULL;
+ try {
+ //Create an IndexReader reading the index
+ ret = with.runAndReturn();
+ } _CLFINALLY (
+ _CLDELETE(lock);
+ );
+
+ CND_CONDITION(ret != NULL, "ret is NULL");
+ ret->closeDirectory = closeDirectory;
+
+ return ret;
+}
+
+CL_NS(document)::Document* IndexReader::document(const int32_t n)
+{
+ CL_NS(document)::Document* ret = _CLNEW CL_NS(document)::Document;
+ if (!document(n, ret))
+ _CLDELETE(ret);
+ return ret;
+}
+
+IndexReader* IndexReader::LockWith::doBody()
+{
+ //Func - Reads the segmentinfo file and depending on the number of segments found
+ // it returns a SegmentsReader or a SegmentReader
+ //Pre - directory != NULL
+ //Post - Depending on the number of Segments present in directory this method
+ // returns an empty SegmentsReader when there are no segments, a SegmentReader when
+ // directory contains 1 segment and a nonempty SegmentsReader when directory
+ // contains multiple segements
+
+ CND_PRECONDITION(directory != NULL, "directory is NULL");
+
+ //Instantiate SegmentInfos
+ SegmentInfos* infos = _CLNEW SegmentInfos;
+ try {
+ //Have SegmentInfos read the segments file in directory
+ infos->read(directory);
+ } catch(...) {
+ //make sure infos is cleaned up
+ _CLDELETE(infos);
+ throw;
+ }
+
+ // If there is at least one segment (if infos.size() >= 1), the last
+ // SegmentReader object will close the directory when the SegmentReader
+ // object itself is closed (see SegmentReader::doClose).
+ // If there are no segments, there will be no "last SegmentReader object"
+ // to fulfill this responsibility, so we need to explicitly close the
+ // directory in the segmentsreader.close
+
+ //Count the number segments in the directory
+ const uint32_t nSegs = infos->size();
+
+ if (nSegs == 1 ) {
+ // index is optimized
+ return _CLNEW SegmentReader(infos, infos->info(0));
+ } else {
+ //Instantiate an array of pointers to SegmentReaders of size nSegs (The number of segments in the index)
+ IndexReader** readers = NULL;
+
+ if (nSegs > 0){
+ uint32_t infosize = infos->size();
+ readers = _CL_NEWARRAY(IndexReader*,infosize+1);
+ for (uint32_t i = 0; i < infosize; ++i) {
+ //Instantiate a SegementReader responsible for reading the i-th segment and store it in
+ //the readers array
+ readers[i] = _CLNEW SegmentReader(infos->info(i));
+ }
+ readers[infosize] = NULL;
+ }
+
+ //return an instance of SegmentsReader which is a reader that manages all Segments
+ return _CLNEW MultiReader(directory, infos, readers);
+ }// end if
+}
+
+uint64_t IndexReader::lastModified(const QString& directory)
+{
+ //Func - Static method
+ // Returns the time the index in the named directory was last modified.
+ //Pre - directory != NULL and contains the path name of the directory to check
+ //Post - The last modified time of the index has been returned
+
+ CND_PRECONDITION(!directory.isEmpty(), "directory is NULL");
+
+ return FSDirectory::fileModified(directory, QLatin1String("segments"));
+}
+
+int64_t IndexReader::getCurrentVersion(Directory* directory)
+{
+ // in- & inter-process sync
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+
+ int64_t ret = 0;
+ bool locked = false;
+ LuceneLock* commitLock = directory->makeLock(IndexWriter::COMMIT_LOCK_NAME);
+ try {
+ locked = commitLock->obtain(IndexWriter::COMMIT_LOCK_TIMEOUT);
+ ret = SegmentInfos::readCurrentVersion(directory);
+ } _CLFINALLY (
+ if (locked)
+ commitLock->release();
+ _CLDELETE(commitLock);
+ )
+ return ret;
+}
+
+int64_t IndexReader::getCurrentVersion(const QString& directory)
+{
+ Directory* dir = FSDirectory::getDirectory(directory, false);
+ int64_t version = getCurrentVersion(dir);
+ dir->close();
+ _CLDECDELETE(dir);
+ return version;
+}
+
+int64_t IndexReader::getVersion()
+{
+ return segmentInfos->getVersion();
+}
+
+bool IndexReader::isCurrent()
+{
+ // in- & inter-process sync
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+
+ bool ret = false;
+ bool locked = false;
+ LuceneLock* commitLock = directory->makeLock(IndexWriter::COMMIT_LOCK_NAME);
+ try {
+ locked = commitLock->obtain(IndexWriter::COMMIT_LOCK_TIMEOUT);
+ ret = SegmentInfos::readCurrentVersion(directory)
+ == segmentInfos->getVersion();
+ } _CLFINALLY(
+ if (locked)
+ commitLock->release();
+ _CLDELETE(commitLock);
+ )
+ return ret;
+}
+
+uint64_t IndexReader::lastModified(const Directory* directory)
+{
+ //Func - Static method
+ // Returns the time the index in this directory was last modified.
+ //Pre - directory contains a valid reference
+ //Post - The last modified time of the index has been returned
+
+ return directory->fileModified(QLatin1String("segments"));
+}
+
+
+bool IndexReader::indexExists(const QString& directory)
+{
+ //Func - Static method
+ // Checks if an index exists in the named directory
+ //Pre - directory != NULL
+ //Post - Returns true if an index exists at the specified directory->
+ // If the directory does not exist or if there is no index in it.
+ // false is returned.
+
+ CND_PRECONDITION(!directory.isEmpty(), "directory is NULL");
+ return QFile(directory + QLatin1String("/segments")).exists();
+}
+
+
+void IndexReader::setNorm(int32_t doc, const TCHAR* field, uint8_t value)
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ if(directoryOwner)
+ aquireWriteLock();
+ doSetNorm(doc, field, value);
+ hasChanges = true;
+}
+
+void IndexReader::aquireWriteLock()
+{
+ if (stale) {
+ _CLTHROWA(CL_ERR_IO,
+ "IndexReader out of date and no longer valid for delete, "
+ "undelete, or setNorm operations");
+ }
+
+ if (writeLock == NULL) {
+ LuceneLock* writeLock = directory->makeLock(QLatin1String("write.lock"));
+ if (!writeLock->obtain(IndexWriter::WRITE_LOCK_TIMEOUT)) // obtain write lock
+ _CLTHROWA(CL_ERR_IO,"Index locked for write"); // + writeLock
+ this->writeLock = writeLock;
+
+ // we have to check whether index has changed since this reader was opened.
+ // if so, this reader is no longer valid for deletion
+ if (SegmentInfos::readCurrentVersion(directory) > segmentInfos->getVersion()) {
+ stale = true;
+ this->writeLock->release();
+ _CLDELETE(this->writeLock);
+ _CLTHROWA(CL_ERR_IO,"IndexReader out of date and no longer valid "
+ "for delete, undelete, or setNorm operations");
+ }
+ }
+}
+
+
+void IndexReader::setNorm(int32_t doc, const TCHAR* field, qreal value)
+{
+ setNorm(doc, field, CL_NS(search)::Similarity::encodeNorm(value));
+}
+
+bool IndexReader::indexExists(const Directory* directory)
+{
+ //Func - Static method
+ // Checks if an index exists in the directory
+ //Pre - directory is a valid reference
+ //Post - Returns true if an index exists at the specified directory->
+ // If the directory does not exist or if there is no index in it.
+ // false is returned.
+
+ return directory->fileExists(QLatin1String("segments"));
+}
+
+TermDocs* IndexReader::termDocs(Term* term) const
+{
+ //Func - Returns an enumeration of all the documents which contain
+ // term. For each document, the document number, the frequency of
+ // the term in that document is also provided, for use in search scoring.
+ // Thus, this method implements the mapping:
+ //
+ // Term => <docNum, freq>*
+ // The enumeration is ordered by document number. Each document number
+ // is greater than all that precede it in the enumeration.
+ //Pre - term != NULL
+ //Post - A reference to TermDocs containing an enumeration of all found documents
+ // has been returned
+
+ CND_PRECONDITION(term != NULL, "term is NULL");
+
+ //Reference an instantiated TermDocs instance
+ TermDocs* _termDocs = termDocs();
+ //Seek all documents containing term
+ _termDocs->seek(term);
+ //return the enumaration
+ return _termDocs;
+}
+
+TermPositions* IndexReader::termPositions(Term* term) const
+{
+ //Func - Returns an enumeration of all the documents which contain term. For each
+ // document, in addition to the document number and frequency of the term in
+ // that document, a list of all of the ordinal positions of the term in the document
+ // is available. Thus, this method implements the mapping:
+ //
+ // Term => <docNum, freq,<pos 1, pos 2, ...pos freq-1>>*
+ //
+ // This positional information faciliates phrase and proximity searching.
+ // The enumeration is ordered by document number. Each document number is greater than
+ // all that precede it in the enumeration.
+ //Pre - term != NULL
+ //Post - A reference to TermPositions containing an enumeration of all found documents
+ // has been returned
+
+ CND_PRECONDITION(term != NULL, "term is NULL");
+
+ //Reference an instantiated termPositions instance
+ TermPositions* _termPositions = termPositions();
+ //Seek all documents containing term
+ _termPositions->seek(term);
+ //return the enumeration
+ return _termPositions;
+}
+
+void IndexReader::deleteDocument(const int32_t docNum)
+{
+ //Func - Deletes the document numbered docNum. Once a document is deleted it will not appear
+ // in TermDocs or TermPostitions enumerations. Attempts to read its field with the document
+ // method will result in an error. The presence of this document may still be reflected in
+ // the docFreq statistic, though this will be corrected eventually as the index is further modified.
+ //Pre - docNum >= 0
+ //Post - If successful the document identified by docNum has been deleted. If no writelock
+ // could be obtained an exception has been thrown stating that the index was locked or has no write access
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ CND_PRECONDITION(docNum >= 0, "docNum is negative");
+
+ if (directoryOwner)
+ aquireWriteLock();
+
+ //Have the document identified by docNum deleted
+ doDelete(docNum);
+ hasChanges = true;
+}
+
+/**
+* Commit changes resulting from delete, undeleteAll, or setNorm operations
+*
+* @throws IOException
+*/
+void IndexReader::commit()
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ if(hasChanges){
+ if(directoryOwner){
+ {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK) // in- & inter-process sync
+
+ LuceneLock* commitLock = directory->makeLock(QLatin1String("commit.lock"));
+ IndexReader::CommitLockWith cl(commitLock,this);
+ cl.run();
+ _CLDELETE(commitLock);
+
+ }
+ if (writeLock != NULL) {
+ writeLock->release(); // release write lock
+ _CLDELETE(writeLock);
+ }
+ }else
+ doCommit();
+ }
+ hasChanges = false;
+}
+
+
+void IndexReader::undeleteAll()
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ if(directoryOwner)
+ aquireWriteLock();
+ doUndeleteAll();
+ hasChanges = true;
+}
+
+int32_t IndexReader::deleteDocuments(Term* term)
+{
+ //Func - Deletes all documents containing term. This is useful if one uses a
+ // document field to hold a unique ID string for the document. Then to delete such
+ // a document, one merely constructs a term with the appropriate field and the unique
+ // ID string as its text and passes it to this method.
+ //Pre - term != NULL
+ //Post - All documents containing term have been deleted. The number of deleted documents
+ // has been returned
+
+ CND_PRECONDITION(term != NULL, "term is NULL");
+
+ //Search for the documents contain term
+ TermDocs* docs = termDocs(term);
+
+ //Check if documents have been found
+ if ( docs == NULL ){
+ return 0;
+ }
+
+ //initialize
+ int32_t Counter = 0;
+ try {
+ //iterate through the found documents
+ while (docs->next()) {
+ //Delete the document
+ deleteDocument(docs->doc());
+ ++Counter;
+ }
+ }_CLFINALLY(
+ //Close the enumeration
+ docs->close();
+ );
+
+ //Delete the enumeration of found documents
+ _CLDELETE( docs );
+
+ //Return the number of deleted documents
+ return Counter;
+}
+
+TCHAR** IndexReader::getFieldNames()
+{
+ CL_NS(util)::StringArrayWithDeletor array;
+ getFieldNames(IndexReader::ALL, array);
+
+ array.setDoDelete(false);
+ TCHAR** ret = _CL_NEWARRAY(TCHAR*,array.size()+1);
+ int j=0;
+ CL_NS(util)::StringArrayWithDeletor::iterator itr = array.begin();
+ while ( itr != array.end() ){
+ ret[j]=*itr;
+ ++j;++itr;
+ }
+ ret[j]=NULL;
+ return ret;
+}
+
+TCHAR** IndexReader::getFieldNames(bool indexed)
+{
+ CL_NS(util)::StringArrayWithDeletor array;
+ getFieldNames(indexed?IndexReader::INDEXED:IndexReader::UNINDEXED, array);
+
+ array.setDoDelete(false);
+ TCHAR** ret = _CL_NEWARRAY(TCHAR*,array.size()+1);
+ int j=0;
+ CL_NS(util)::StringArrayWithDeletor::iterator itr = array.begin();
+ while ( itr != array.end() ){
+ ret[j]=*itr;
+ ++j;++itr;
+ }
+ ret[j]=NULL;
+ return ret;
+}
+
+void IndexReader::close()
+{
+ //Func - Closes files associated with this index and also saves any new deletions to disk.
+ // No other methods should be called after this has been called.
+ //Pre - true
+ //Post - All files associated with this index have been deleted and new deletions have been
+ // saved to disk
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ CloseCallbackMap::iterator iter;
+ for (iter = closeCallbacks.begin(); iter != closeCallbacks.end(); iter++) {
+ CloseCallback callback = *iter->first;
+ callback(this, iter->second);
+ }
+
+ commit();
+ doClose();
+
+ if(closeDirectory) {
+ directory->close();
+ _CLDECDELETE(directory);
+ }
+}
+
+bool IndexReader::isLocked(Directory* directory)
+{
+ //Func - Static method
+ // Checks if the index in the directory is currently locked.
+ //Pre - directory is a valid reference to a directory to check for a lock
+ //Post - Returns true if the index in the named directory is locked otherwise false
+
+ //Check the existence of the file write.lock and return true when it does and false
+ //when it doesn't
+ LuceneLock* l1 = directory->makeLock(QLatin1String("write.lock"));
+ LuceneLock* l2 = directory->makeLock(QLatin1String("commit.lock"));
+
+ bool ret = l1->isLocked() || l2->isLocked();
+
+ _CLDELETE(l1);
+ _CLDELETE(l2);
+ return ret;
+}
+
+bool IndexReader::isLocked(const QString& directory)
+{
+ //Func - Static method
+ // Checks if the index in the named directory is currently locked.
+ //Pre - directory != NULL and contains the directory to check for a lock
+ //Post - Returns true if the index in the named directory is locked otherwise false
+
+ CND_PRECONDITION(!directory.isEmpty(), "directory is NULL");
+
+ Directory* dir = FSDirectory::getDirectory(directory, false);
+ bool ret = isLocked(dir);
+ dir->close();
+ _CLDECDELETE(dir);
+
+ return ret;
+}
+
+/** Returns true if there are norms stored for this field. */
+bool IndexReader::hasNorms(const TCHAR* field)
+{
+ // backward compatible implementation.
+ // SegmentReader has an efficient implementation.
+ return norms(field) != NULL;
+}
+
+void IndexReader::unlock(const QString& path)
+{
+ FSDirectory* dir = FSDirectory::getDirectory(path, false);
+ unlock(dir);
+ dir->close();
+ _CLDECDELETE(dir);
+}
+
+void IndexReader::unlock(Directory* directory)
+{
+ //Func - Static method
+ // Forcibly unlocks the index in the named directory->
+ // Caution: this should only be used by failure recovery code,
+ // when it is known that no other process nor thread is in fact
+ // currently accessing this index.
+ //Pre - directory is a valid reference to a directory
+ //Post - The directory has been forcibly unlocked
+ LuceneLock* lock;
+
+ lock = directory->makeLock(QLatin1String("write.lock"));
+ lock->release();
+ _CLDELETE(lock);
+
+ lock = directory->makeLock(QLatin1String("commit.lock"));
+ lock->release();
+ _CLDELETE(lock);
+}
+
+bool IndexReader::isLuceneFile(const QString& filename)
+{
+ if (filename.isNull() || filename.isEmpty())
+ return false;
+
+ size_t len = filename.length();
+ if (len < 6) //need at least x.frx
+ return false;
+
+ if (filename == QLatin1String("segments"))
+ return true;
+
+ if (filename == QLatin1String("segments.new"))
+ return true;
+
+ if (filename == QLatin1String("deletable"))
+ return true;
+
+ QStringList extList;
+ extList << QLatin1String(".cfs")
+ << QLatin1String(".fnm") << QLatin1String(".fdx") << QLatin1String(".fdt")
+ << QLatin1String(".tii") << QLatin1String(".tis") << QLatin1String(".frq")
+ << QLatin1String(".prx") << QLatin1String(".del") << QLatin1String(".tvx")
+ << QLatin1String(".tvd") << QLatin1String(".tvf") << QLatin1String(".tvp");
+
+ QString suffix = filename.right(4);
+ if (extList.contains(suffix, Qt::CaseInsensitive))
+ return true;
+
+ if (suffix.leftRef(2) == QLatin1String(".f")) {
+ suffix = suffix.remove(0, 2);
+ if (suffix.length() > 0) {
+ for (int i = 0; i < suffix.length(); ++i) {
+ if (!suffix.at(i).isDigit())
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+void IndexReader::addCloseCallback(CloseCallback callback, void* parameter)
+{
+ closeCallbacks.put(callback, parameter);
+}
+
+// #pragma mark -- IndexReader::LockWith
+
+IndexReader::LockWith::LockWith(CL_NS(store)::LuceneLock* lock, CL_NS(store)::Directory* dir)
+ : CL_NS(store)::LuceneLockWith<IndexReader*>(lock, IndexWriter::COMMIT_LOCK_TIMEOUT)
+{
+ this->directory = dir;
+}
+
+// #pragma mark -- IndexReader::CommitLockWith
+
+IndexReader::CommitLockWith::CommitLockWith(CL_NS(store)::LuceneLock* lock, IndexReader* r)
+ : CL_NS(store)::LuceneLockWith<void>(lock,IndexWriter::COMMIT_LOCK_TIMEOUT)
+ , reader(r)
+{
+}
+
+void IndexReader::CommitLockWith::doBody()
+{
+ reader->doCommit();
+ reader->segmentInfos->write(reader->getDirectory());
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/IndexReader.h b/3rdparty/clucene/src/CLucene/index/IndexReader.h
new file mode 100644
index 000000000..352d16e80
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/IndexReader.h
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_IndexReader_
+#define _lucene_index_IndexReader_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/FSDirectory.h"
+#include "CLucene/store/Lock.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/index/TermVector.h"
+#include "SegmentInfos.h"
+#include "Terms.h"
+
+
+CL_NS_DEF(index)
+
+
+/** IndexReader is an abstract class, providing an interface for accessing an
+ index. Search of an index is done entirely through this abstract interface,
+ so that any subclass which implements it is searchable.
+
+ <p> Concrete subclasses of IndexReader are usually constructed with a call to
+ one of the static <code>open()</code> methods, e.g. {@link #open(String)}.
+
+ <p> For efficiency, in this API documents are often referred to via
+ <i>document numbers</i>, non-negative integers which each name a unique
+ document in the index. These document numbers are ephemeral--they may change
+ as documents are added to and deleted from an index. Clients should thus not
+ rely on a given document having the same number between sessions.
+
+ <p> An IndexReader can be opened on a directory for which an IndexWriter is
+ opened already, but it cannot be used to delete documents from the index then.
+*/
+class IndexReader : LUCENE_BASE
+{
+public:
+ //Callback for classes that need to know if IndexReader is closing.
+ typedef void (*CloseCallback)(IndexReader*, void*);
+
+ class CloseCallbackCompare:public CL_NS(util)::Compare::_base{
+ public:
+ bool operator()( CloseCallback t1, CloseCallback t2 ) const{
+ return t1 > t2;
+ }
+ static void doDelete(CloseCallback dummy){
+ }
+ };
+
+
+ enum FieldOption {
+ // all fields
+ ALL = 1,
+ // all indexed fields
+ INDEXED = 2,
+ // all fields which are not indexed
+ UNINDEXED = 4,
+ // all fields which are indexed with termvectors enables
+ INDEXED_WITH_TERMVECTOR = 8,
+ // all fields which are indexed but don't have termvectors enabled
+ INDEXED_NO_TERMVECTOR = 16,
+ // all fields where termvectors are enabled. Please note that only standard termvector fields are returned
+ TERMVECTOR = 32,
+ // all field with termvectors wiht positions enabled
+ TERMVECTOR_WITH_POSITION = 64,
+ // all fields where termvectors with offset position are set
+ TERMVECTOR_WITH_OFFSET = 128,
+ // all fields where termvectors with offset and position values set
+ TERMVECTOR_WITH_POSITION_OFFSET = 256
+ };
+
+
+private:
+ bool stale;
+ bool hasChanges;
+ bool closeDirectory;
+ bool directoryOwner;
+
+ SegmentInfos* segmentInfos;
+ CL_NS(store)::Directory* directory;
+ CL_NS(store)::LuceneLock* writeLock;
+
+ typedef CL_NS(util)::CLSet<CloseCallback, void*, CloseCallbackCompare,
+ CloseCallbackCompare> CloseCallbackMap;
+ CloseCallbackMap closeCallbacks;
+
+ /** Internal use. Implements commit */
+ virtual void doCommit() = 0;
+
+ /**
+ * Tries to acquire the WriteLock on this directory.
+ * this method is only valid if this IndexReader is directory owner.
+ *
+ * @throws IOException If WriteLock cannot be acquired.
+ */
+ void aquireWriteLock();
+protected:
+ /**
+ * Constructor used if IndexReader is not owner of its directory.
+ * This is used for IndexReaders that are used within other IndexReaders that take care or locking directories.
+ *
+ * @param directory Directory where IndexReader files reside.
+ */
+ IndexReader(CL_NS(store)::Directory* dir);
+
+ /**
+ * Constructor used if IndexReader is owner of its directory.
+ * If IndexReader is owner of its directory, it locks its directory in case of write operations.
+ *
+ * @param directory Directory where IndexReader files reside.
+ * @param segmentInfos Used for write-l
+ * @param closeDirectory
+ */
+ IndexReader(CL_NS(store)::Directory* directory, SegmentInfos* segmentInfos, bool closeDirectory);
+
+
+ /// Implements close.
+ virtual void doClose() = 0;
+
+ /** Implements setNorm in subclass.*/
+ virtual void doSetNorm(int32_t doc, const TCHAR* field, uint8_t value) = 0;
+
+ /** Implements actual undeleteAll() in subclass. */
+ virtual void doUndeleteAll() = 0;
+
+
+ /** Implements deletion of the document numbered <code>docNum</code>.
+ * Applications should call {@link #deleteDocument(int32_t)} or {@link #deleteDocuments(Term*)}.
+ */
+ virtual void doDelete(const int32_t docNum) = 0;
+
+public:
+
+ DEFINE_MUTEX(THIS_LOCK)
+
+ ///Do not access this directly, only public so that MultiReader can access it
+ virtual void commit();
+
+
+ /** Undeletes all documents currently marked as deleted in this index.*/
+ void undeleteAll();
+
+ /**
+ * Get a list of unique field names that exist in this index and have the specified
+ * field option information.
+ * @param fldOption specifies which field option should be available for the returned fields
+ * @return Collection of Strings indicating the names of the fields.
+ * @see IndexReader.FieldOption
+ */
+ virtual void getFieldNames(FieldOption fldOption, CL_NS(util)::StringArrayWithDeletor& retarray) = 0;
+
+ _CL_DEPRECATED( getFieldNames(FieldOption, StringArrayWithDeletor&) ) virtual TCHAR** getFieldNames();
+ _CL_DEPRECATED( getFieldNames(FieldOption, StringArrayWithDeletor&) ) virtual TCHAR** getFieldNames(bool indexed);
+
+ /** Returns the byte-encoded normalization factor for the named field of
+ * every document. This is used by the search code to score documents.
+ *
+ * The number of bytes returned is the size of the IndexReader->maxDoc()
+ * MEMORY: The values are cached, so don't delete the returned byte array.
+ * @see Field#setBoost(qreal)
+ */
+ virtual uint8_t* norms(const TCHAR* field) = 0;
+
+
+ /** Reads the byte-encoded normalization factor for the named field of every
+ * document. This is used by the search code to score documents.
+ *
+ * @see Field#setBoost(qreal)
+ */
+ virtual void norms(const TCHAR* field, uint8_t* bytes) = 0;
+
+ /** Expert: Resets the normalization factor for the named field of the named
+ * document.
+ *
+ * @see #norms(TCHAR*)
+ * @see Similarity#decodeNorm(uint8_t)
+ */
+ void setNorm(int32_t doc, const TCHAR* field, qreal value);
+
+ /** Expert: Resets the normalization factor for the named field of the named
+ * document. The norm represents the product of the field's {@link
+ * Field#setBoost(qreal) boost} and its {@link Similarity#lengthNorm(TCHAR*,
+ * int32_t) length normalization}. Thus, to preserve the length normalization
+ * values when resetting this, one should base the new value upon the old.
+ *
+ * @see #norms(TCHAR*)
+ * @see Similarity#decodeNorm(uint8_t)
+ */
+ void setNorm(int32_t doc, const TCHAR* field, uint8_t value);
+
+ /// Release the write lock, if needed.
+ virtual ~IndexReader();
+
+ /// Returns an IndexReader reading the index in an FSDirectory in the named path.
+ static IndexReader* open(const QString& path);
+
+ /// Returns an IndexReader reading the index in the given Directory.
+ static IndexReader* open( CL_NS(store)::Directory* directory, bool closeDirectory=false);
+
+ /**
+ * Returns the time the index in the named directory was last modified.
+ * Do not use this to check whether the reader is still up-to-date, use
+ * {@link #isCurrent()} instead.
+ */
+ static uint64_t lastModified(const QString& directory);
+
+ /**
+ * Returns the time the index in the named directory was last modified.
+ * Do not use this to check whether the reader is still up-to-date, use
+ * {@link #isCurrent()} instead.
+ */
+ static uint64_t lastModified(const CL_NS(store)::Directory* directory);
+
+
+ /**
+ * Reads version number from segments files. The version number is
+ * initialized with a timestamp and then increased by one for each change of
+ * the index.
+ *
+ * @param directory where the index resides.
+ * @return version number.
+ * @throws IOException if segments file cannot be read
+ */
+ static int64_t getCurrentVersion(CL_NS(store)::Directory* directory);
+
+ /**
+ * Reads version number from segments files. The version number is
+ * initialized with a timestamp and then increased by one for each change of
+ * the index.
+ *
+ * @param directory where the index resides.
+ * @return version number.
+ * @throws IOException if segments file cannot be read
+ */
+ static int64_t getCurrentVersion(const QString& directory);
+
+ /**
+ * Version number when this IndexReader was opened.
+ */
+ int64_t getVersion();
+
+ /**
+ * Check whether this IndexReader still works on a current version of the index.
+ * If this is not the case you will need to re-open the IndexReader to
+ * make sure you see the latest changes made to the index.
+ *
+ * @throws IOException
+ */
+ bool isCurrent();
+
+
+ /**
+ * Return an array of term frequency vectors for the specified document.
+ * The array contains a vector for each vectorized field in the document.
+ * Each vector contains terms and frequencies for all terms in a given vectorized field.
+ * If no such fields existed, the method returns null. The term vectors that are
+ * returned my either be of type TermFreqVector or of type TermPositionsVector if
+ * positions or offsets have been stored.
+ *
+ * @param docNumber document for which term frequency vectors are returned
+ * @return array of term frequency vectors. May be null if no term vectors have been
+ * stored for the specified document.
+ * @throws IOException if index cannot be accessed
+ * @see org.apache.lucene.document.Field.TermVector
+ */
+ virtual bool getTermFreqVectors(int32_t docNumber, Array<TermFreqVector*>& result) =0;
+
+ /**
+ * Return a term frequency vector for the specified document and field. The
+ * returned vector contains terms and frequencies for the terms in
+ * the specified field of this document, if the field had the storeTermVector
+ * flag set. If termvectors had been stored with positions or offsets, a
+ * TermPositionsVector is returned.
+ *
+ * @param docNumber document for which the term frequency vector is returned
+ * @param field field for which the term frequency vector is returned.
+ * @return term frequency vector May be null if field does not exist in the specified
+ * document or term vector was not stored.
+ * @throws IOException if index cannot be accessed
+ * @see org.apache.lucene.document.Field.TermVector
+ */
+ virtual TermFreqVector* getTermFreqVector(int32_t docNumber, const TCHAR* field) = 0;
+
+ /**
+ * Returns <code>true</code> if an index exists at the specified directory.
+ * If the directory does not exist or if there is no index in it.
+ * @param directory the directory to check for an index
+ * @return <code>true</code> if an index exists; <code>false</code> otherwise
+ */
+ static bool indexExists(const QString& directory);
+
+ /**
+ * Returns <code>true</code> if an index exists at the specified directory.
+ * If the directory does not exist or if there is no index in it.
+ * @param directory the directory to check for an index
+ * @return <code>true</code> if an index exists; <code>false</code> otherwise
+ * @throws IOException if there is a problem with accessing the index
+ */
+ static bool indexExists(const CL_NS(store)::Directory* directory);
+
+ /** Returns the number of documents in this index. */
+ virtual int32_t numDocs() = 0;
+
+ /** Returns one greater than the largest possible document number.
+ * This may be used to, e.g., determine how big to allocate an array which
+ * will have an element for every document number in an index.
+ */
+ virtual int32_t maxDoc() const = 0;
+
+ /** Gets the stored fields of the <code>n</code><sup>th</sup>
+ * <code>Document</code> in this index.
+ * The fields are not cleared before retrieving the document, so the
+ * object should be new or just cleared.
+ */
+ virtual bool document(int32_t n, CL_NS(document)::Document*) =0;
+
+ _CL_DEPRECATED( document(i, document) ) CL_NS(document)::Document* document(const int32_t n);
+
+ /** Returns true if document <i>n</i> has been deleted */
+ virtual bool isDeleted(const int32_t n) = 0;
+
+ /** Returns true if any documents have been deleted */
+ virtual bool hasDeletions() const = 0;
+
+ /** Returns true if there are norms stored for this field. */
+ virtual bool hasNorms(const TCHAR* field);
+
+ /** Returns an enumeration of all the terms in the index.
+ * The enumeration is ordered by Term.compareTo(). Each term
+ * is greater than all that precede it in the enumeration.
+ * @memory Caller must clean up
+ */
+ virtual TermEnum* terms() const =0;
+
+ /** Returns an enumeration of all terms after a given term.
+ * The enumeration is ordered by Term.compareTo(). Each term
+ * is greater than all that precede it in the enumeration.
+ * @memory Caller must clean up
+ */
+ virtual TermEnum* terms(const Term* t) const = 0;
+
+ /** Returns the number of documents containing the term <code>t</code>. */
+ virtual int32_t docFreq(const Term* t) const = 0;
+
+ /* Returns an unpositioned TermPositions enumerator.
+ * @memory Caller must clean up
+ */
+ virtual TermPositions* termPositions() const = 0;
+
+ /** Returns an enumeration of all the documents which contain
+ * <code>term</code>. For each document, in addition to the document number
+ * and frequency of the term in that document, a list of all of the ordinal
+ * positions of the term in the document is available. Thus, this method
+ * implements the mapping:
+ *
+ * <p><ul>
+ * Term &nbsp;&nbsp; =&gt; &nbsp;&nbsp; &lt;docNum, freq,
+ * &lt;pos<sub>1</sub>, pos<sub>2</sub>, ...
+ * pos<sub>freq-1</sub>&gt;
+ * &gt;<sup>*</sup>
+ * </ul>
+ * <p> This positional information faciliates phrase and proximity searching.
+ * <p>The enumeration is ordered by document number. Each document number is
+ * greater than all that precede it in the enumeration.
+ * @memory Caller must clean up
+ */
+ TermPositions* termPositions(Term* term) const;
+
+ /** Returns an unpositioned {@link TermDocs} enumerator.
+ * @memory Caller must clean up
+ */
+ virtual TermDocs* termDocs() const = 0;
+
+ /** Returns an enumeration of all the documents which contain
+ * <code>term</code>. For each document, the document number, the frequency of
+ * the term in that document is also provided, for use in search scoring.
+ * Thus, this method implements the mapping:
+ * <p><ul>Term &nbsp;&nbsp; =&gt; &nbsp;&nbsp; &lt;docNum, freq&gt;<sup>*</sup></ul>
+ * <p>The enumeration is ordered by document number. Each document number
+ * is greater than all that precede it in the enumeration.
+ * @memory Caller must clean up
+ */
+ TermDocs* termDocs(Term* term) const;
+
+ /** Deletes the document numbered <code>docNum</code>. Once a document is
+ * deleted it will not appear in TermDocs or TermPostitions enumerations.
+ * Attempts to read its field with the {@link #document}
+ * method will result in an error. The presence of this document may still be
+ * reflected in the {@link #docFreq} statistic, though
+ * this will be corrected eventually as the index is further modified.
+ */
+ void deleteDocument(const int32_t docNum);
+
+ ///@deprecated. Use deleteDocument instead.
+ _CL_DEPRECATED( deleteDocument ) void deleteDoc(const int32_t docNum)
+ { deleteDocument(docNum); }
+
+ /** Deletes all documents containing <code>term</code>.
+ * This is useful if one uses a document field to hold a unique ID string for
+ * the document. Then to delete such a document, one merely constructs a
+ * term with the appropriate field and the unique ID string as its text and
+ * passes it to this method.
+ * See {@link #deleteDocument(int)} for information about when this deletion will
+ * become effective.
+ * @return the number of documents deleted
+ */
+ int32_t deleteDocuments(Term* term);
+
+ ///@deprecated. Use deleteDocuments instead.
+ _CL_DEPRECATED( deleteDocuments ) int32_t deleteTerm(Term* term){ return deleteDocuments(term); }
+
+ /**
+ * Closes files associated with this index and also saves any new deletions to disk.
+ * No other methods should be called after this has been called.
+ */
+ void close();
+
+ ///Checks if the index in the named directory is currently locked.
+ static bool isLocked(CL_NS(store)::Directory* directory);
+
+ ///Checks if the index in the named directory is currently locked.
+ static bool isLocked(const QString& directory);
+
+
+ ///Forcibly unlocks the index in the named directory.
+ ///Caution: this should only be used by failure recovery code,
+ ///when it is known that no other process nor thread is in fact
+ ///currently accessing this index.
+ static void unlock(CL_NS(store)::Directory* directory);
+ static void unlock(const QString& path);
+
+ /** Returns the directory this index resides in. */
+ CL_NS(store)::Directory* getDirectory() { return directory; }
+
+ /** Returns true if the file is a lucene filename (based on extension or filename) */
+ static bool isLuceneFile(const QString& filename);
+
+ /**
+ * For classes that need to know when the IndexReader closes (such as caches, etc),
+ * should pass their callback function to this.
+ */
+ void addCloseCallback(CloseCallback callback, void* parameter);
+
+protected:
+ class LockWith : public CL_NS(store)::LuceneLockWith<IndexReader*>
+ {
+ public:
+ LockWith(CL_NS(store)::LuceneLock* lock, CL_NS(store)::Directory* dir);
+
+ //Reads the segmentinfo file and depending on the number of segments found
+ //it returns a MultiReader or a SegmentReader
+ IndexReader* doBody();
+
+ private:
+ CL_NS(store)::Directory* directory;
+ };
+ friend class IndexReader::LockWith;
+
+ class CommitLockWith : public CL_NS(store)::LuceneLockWith<void>
+ {
+ public:
+ CommitLockWith(CL_NS(store)::LuceneLock* lock, IndexReader* r);
+ void doBody();
+
+ private:
+ IndexReader* reader;
+ };
+ friend class IndexReader::CommitLockWith;
+};
+
+CL_NS_END
+#endif
+
+
diff --git a/3rdparty/clucene/src/CLucene/index/IndexWriter.cpp b/3rdparty/clucene/src/CLucene/index/IndexWriter.cpp
new file mode 100644
index 000000000..5504cf6fa
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/IndexWriter.cpp
@@ -0,0 +1,697 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "IndexWriter.h"
+
+#include "CLucene/document/Document.h"
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/Lock.h"
+#include "CLucene/util/VoidList.h"
+#include "DocumentWriter.h"
+#include "SegmentInfos.h"
+#include "SegmentMerger.h"
+
+CL_NS_USE(store)
+CL_NS_USE(util)
+CL_NS_USE(document)
+CL_NS_USE(analysis)
+CL_NS_DEF(index)
+
+const QLatin1String IndexWriter::WRITE_LOCK_NAME("write.lock");
+const QLatin1String IndexWriter::COMMIT_LOCK_NAME("commit.lock");
+
+IndexWriter::IndexWriter(const QString& path, Analyzer* a, const bool create,
+ const bool _closeDir)
+ : directory(FSDirectory::getDirectory(path, create))
+ , analyzer(a)
+ , segmentInfos(true)
+ , closeDir(_closeDir)
+{
+ //Func - Constructor
+ // Constructs an IndexWriter for the index in path.
+ //Pre - path != NULL and contains a named directory path
+ // a holds a valid reference to an analyzer and analyzes the text to
+ // be indexed create indicates if the indexWriter must create a new
+ // index located at path or just open it
+ //Post - If create is true, then a new, empty index has been created in
+ // path, replacing the index already there, if any. The named
+ // directory path is owned by this Instance
+
+ CND_PRECONDITION(!path.isEmpty(), "path is NULL");
+
+ //Continue initializing the instance by _IndexWriter
+ _IndexWriter(create);
+}
+
+IndexWriter::IndexWriter(Directory* d, Analyzer* a, const bool create,
+ const bool _closeDir)
+ : directory(_CL_POINTER(d))
+ , analyzer(a)
+ , segmentInfos(true)
+ , closeDir(_closeDir)
+{
+ //Func - Constructor
+ // Constructs an IndexWriter for the index in path.
+ //Pre - d contains a valid reference to a directory
+ // a holds a valid reference to an analyzer and analyzes the text to
+ // be indexed create indicates if the indexWriter must create a new
+ // index located at path or just open it
+ //Post - If create is true, then a new, empty index has been created in
+ // path, replacing the index already there, if any. The directory d
+ // is not owned by this Instance
+
+ //Continue initializing the instance by _IndexWriter
+ _IndexWriter ( create );
+}
+
+void IndexWriter::_IndexWriter(const bool create)
+{
+ //Func - Initialises the instances
+ //Pre - create indicates if the indexWriter must create a new index
+ // located at path or just open it
+
+ similarity = CL_NS(search)::Similarity::getDefault();
+
+ useCompoundFile = true;
+ if ( directory->getDirectoryType() == RAMDirectory::DirectoryType() )
+ useCompoundFile = false;
+
+ //Create a ramDirectory
+ ramDirectory = _CLNEW TransactionalRAMDirectory;
+
+ CND_CONDITION(ramDirectory != NULL, "ramDirectory is NULL");
+
+ //Initialize the writeLock to
+ writeLock = NULL;
+
+ //initialise the settings...
+ maxFieldLength = DEFAULT_MAX_FIELD_LENGTH;
+ mergeFactor = DEFAULT_MERGE_FACTOR;
+ maxMergeDocs = DEFAULT_MAX_MERGE_DOCS;
+ writeLockTimeout = WRITE_LOCK_TIMEOUT;
+ commitLockTimeout = COMMIT_LOCK_TIMEOUT;
+ minMergeDocs = DEFAULT_MAX_BUFFERED_DOCS;
+ termIndexInterval = DEFAULT_TERM_INDEX_INTERVAL;
+
+ //Create a new lock using the name "write.lock"
+ LuceneLock* newLock = directory->makeLock(IndexWriter::WRITE_LOCK_NAME);
+
+ //Condition check to see if newLock has been allocated properly
+ CND_CONDITION(newLock != NULL,
+ "No memory could be allocated for LuceneLock newLock");
+
+ //Try to obtain a write lock
+ if (!newLock->obtain(writeLockTimeout)){
+ //Write lock could not be obtained so delete it
+ _CLDELETE(newLock);
+ //Reset the instance
+ _finalize();
+ //throw an exception because no writelock could be created or obtained
+ _CLTHROWA(CL_ERR_IO, "Index locked for write or no write access." );
+ }
+
+ //The Write Lock has been obtained so save it for later use
+ this->writeLock = newLock;
+
+ //Create a new lock using the name "commit.lock"
+ LuceneLock* lock = directory->makeLock(IndexWriter::COMMIT_LOCK_NAME);
+
+ //Condition check to see if lock has been allocated properly
+ CND_CONDITION(lock != NULL, "No memory could be allocated for LuceneLock lock");
+
+ LockWith2 with(lock, commitLockTimeout, this, NULL, create);
+ {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK) // in- & inter-process sync
+ with.run();
+ }
+
+ //Release the commit lock
+ _CLDELETE(lock);
+
+ isOpen = true;
+}
+
+IndexWriter::~IndexWriter()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+ close();
+ _finalize();
+}
+
+void IndexWriter::close()
+{
+ //Func - Flushes all changes to an index, closes all associated files, and
+ // closes the directory that the index is stored in.
+ //Pre - closeDir indicates if the directory must be closed or not
+ //Post - All the changes have been flushed to disk and the write lock has
+ // been released. The ramDirectory has also been closed. The
+ // directory has been closed if the reference count of the directory
+ // reaches zero
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ if (isOpen) {
+ //Flush the Ram Segments
+ flushRamSegments();
+ //Close the ram directory
+ if (ramDirectory != NULL) {
+ ramDirectory->close();
+ _CLDECDELETE(ramDirectory);
+ }
+
+ //Check if this instance must close the directory
+ if (closeDir)
+ directory->close();
+ _CLDECDELETE(directory);
+
+ // release write lock
+ if (writeLock != NULL) {
+ writeLock->release();
+ _CLDELETE(writeLock);
+ }
+ isOpen = false;
+ }
+}
+
+void IndexWriter::_finalize()
+{
+ //Func - Releases all the resources of the instance
+ //Pre - true
+ //Post - All the releases have been released
+
+ if(writeLock != NULL) {
+ //release write lock
+ writeLock->release();
+ _CLDELETE( writeLock );
+ }
+
+ //Delete the ramDirectory
+ if (ramDirectory != NULL) {
+ ramDirectory->close();
+ _CLDECDELETE(ramDirectory);
+ }
+}
+
+int32_t IndexWriter::docCount()
+{
+ //Func - Counts the number of documents in the index
+ //Pre - true
+ //Post - The number of documents have been returned
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ //Initialize count
+ int32_t count = 0;
+
+ //Iterate through all segmentInfos
+ for (int32_t i = 0; i < segmentInfos.size(); i++) {
+ //Get the i-th SegmentInfo
+ SegmentInfo* si = segmentInfos.info(i);
+ //Retrieve the number of documents of the segment and add it to count
+ count += si->docCount;
+ }
+ return count;
+}
+
+void IndexWriter::addDocument(Document* doc, Analyzer* analyzer)
+{
+ //Func - Adds a document to the index
+ //Pre - doc contains a valid reference to a document
+ // ramDirectory != NULL
+ //Post - The document has been added to the index of this IndexWriter
+ CND_PRECONDITION(ramDirectory != NULL, "ramDirectory is NULL");
+
+ if (analyzer == NULL)
+ analyzer = this->analyzer;
+
+ ramDirectory->transStart();
+ try {
+ QString segmentName = newSegmentName();
+ CND_CONDITION(!segmentName.isEmpty(), "segmentName is NULL");
+ try {
+ //Create the DocumentWriter using a ramDirectory and analyzer
+ // supplied by the IndexWriter (this).
+ DocumentWriter* dw = _CLNEW DocumentWriter(ramDirectory, analyzer,
+ this );
+ CND_CONDITION(dw != NULL, "dw is NULL");
+ try {
+ //Add the client-supplied document to the new segment.
+ dw->addDocument(segmentName, doc);
+ } _CLFINALLY (
+ _CLDELETE(dw);
+ );
+
+ //Create a new SegmentInfo instance about this new segment.
+ SegmentInfo* si = _CLNEW SegmentInfo(segmentName, 1, ramDirectory);
+ CND_CONDITION(si != NULL, "Si is NULL");
+ {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ //Add the info object for this particular segment to the list
+ // of all segmentInfos->
+ segmentInfos.add(si);
+
+ //Check to see if the segments must be merged
+ maybeMergeSegments();
+ }
+ } _CLFINALLY()
+ } catch (...) {
+ ramDirectory->transAbort();
+ throw;
+}
+ ramDirectory->transCommit();
+}
+
+void IndexWriter::optimize()
+{
+ //Func - Optimizes the index for which this Instance is responsible
+ //Pre - true
+ //Post -
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ //Flush the RamSegments to disk
+ flushRamSegments();
+ while (segmentInfos.size() > 1
+ || (segmentInfos.size() == 1
+ && (SegmentReader::hasDeletions(segmentInfos.info(0))
+ || segmentInfos.info(0)->getDir()!=directory
+ || (useCompoundFile
+ && (!SegmentReader::usesCompoundFile(segmentInfos.info(0))
+ || SegmentReader::hasSeparateNorms(segmentInfos.info(0))))))) {
+ int32_t minSegment = segmentInfos.size() - mergeFactor;
+ mergeSegments(minSegment < 0 ? 0 : minSegment);
+ }
+}
+
+
+QString IndexWriter::newSegmentName()
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ return QLatin1Char('_') + QString::number(segmentInfos.counter++, 36);
+}
+
+void IndexWriter::flushRamSegments()
+{
+ //Func - Merges all RAM-resident segments.
+ //Pre - ramDirectory != NULL
+ //Post - The RAM-resident segments have been merged to disk
+
+ CND_PRECONDITION(ramDirectory != NULL, "ramDirectory is NULL");
+
+ int32_t minSegment = segmentInfos.size()-1; //don't make this unsigned...
+ CND_CONDITION(minSegment >= -1, "minSegment must be >= -1");
+
+ int32_t docCount = 0;
+ //Iterate through all the segements and check if the directory is a ramDirectory
+ while (minSegment >= 0 &&
+ segmentInfos.info(minSegment)->getDir() == ramDirectory) {
+ docCount += segmentInfos.info(minSegment)->docCount;
+ minSegment--;
+ }
+ if (minSegment < 0 || // add one FS segment?
+ (docCount + segmentInfos.info(minSegment)->docCount) > mergeFactor ||
+ !(segmentInfos.info(segmentInfos.size()-1)->getDir() == ramDirectory))
+ minSegment++;
+
+ CND_CONDITION(minSegment >= 0, "minSegment must be >= 0");
+ if (minSegment >= segmentInfos.size())
+ return; // none to merge
+ mergeSegments(minSegment);
+}
+
+void IndexWriter::maybeMergeSegments() {
+ //Func - Incremental Segment Merger
+ //Pre -
+ //Post -
+
+ int64_t targetMergeDocs = minMergeDocs;
+
+ // find segments smaller than current target size
+ while (targetMergeDocs <= maxMergeDocs) {
+ int32_t minSegment = segmentInfos.size();
+ int32_t mergeDocs = 0;
+
+ while (--minSegment >= 0) {
+ SegmentInfo* si = segmentInfos.info(minSegment);
+ if (si->docCount >= targetMergeDocs)
+ break;
+ mergeDocs += si->docCount;
+ }
+
+ if (mergeDocs >= targetMergeDocs){
+ // found a merge to do
+ mergeSegments(minSegment+1);
+ }else
+ break;
+
+ //increase target size
+ targetMergeDocs *= mergeFactor;
+ }
+}
+
+void IndexWriter::mergeSegments(const uint32_t minSegment)
+{
+ mergeSegments(minSegment, segmentInfos.size());
+}
+
+void IndexWriter::mergeSegments(const uint32_t minSegment, const uint32_t end)
+{
+ CLVector<SegmentReader*> segmentsToDelete(false);
+ QString mergedName = newSegmentName();
+#ifdef _CL_DEBUG_INFO
+ fprintf(_CL_DEBUG_INFO, "merging segments\n");
+#endif
+ SegmentMerger merger(this, mergedName);
+ for (size_t i = minSegment; i < end; i++) {
+ SegmentInfo* si = segmentInfos.info(i);
+#ifdef _CL_DEBUG_INFO
+ fprintf(_CL_DEBUG_INFO, " %s (%d docs)\n",
+ si->name.toLocal8Bit().constData(), si->docCount);
+#endif
+ SegmentReader* reader = _CLNEW SegmentReader(si);
+ merger.add(reader);
+ // if we own the directory
+ if ((reader->getDirectory() == this->directory)
+ || (reader->getDirectory() == this->ramDirectory)) {
+ // queue segment for deletion
+ segmentsToDelete.push_back(reader);
+ }
+ }
+
+ int32_t mergedDocCount = merger.merge();
+
+#ifdef _CL_DEBUG_INFO
+ fprintf(_CL_DEBUG_INFO, "\n into %s (%d docs)\n",
+ mergedName.toLocal8Bit().constData(), mergedDocCount);
+#endif
+
+ segmentInfos.clearto(minSegment);// remove old infos & add new
+ segmentInfos.add(_CLNEW SegmentInfo(mergedName, mergedDocCount, directory));
+
+ // close readers before we attempt to delete now-obsolete segments
+ merger.closeReaders();
+
+ LuceneLock* lock = directory->makeLock(IndexWriter::COMMIT_LOCK_NAME);
+ LockWith2 with (lock, commitLockTimeout, this, &segmentsToDelete, true);
+ {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK) // in- & inter-process sync
+ with.run();
+ }
+ _CLDELETE( lock );
+
+ if (useCompoundFile) {
+ QStringList filesToDelete;
+ merger.createCompoundFile(mergedName + QLatin1String(".tmp"), filesToDelete);
+
+ LuceneLock* lock = directory->makeLock(IndexWriter::COMMIT_LOCK_NAME);
+ LockWithCFS with(lock, commitLockTimeout, directory, this, mergedName,
+ filesToDelete);
+ {
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK) // in- & inter-process sync
+ with.run();
+ }
+ _CLDELETE(lock);
+ }
+}
+
+void IndexWriter::deleteSegments(CLVector<SegmentReader*>* segments)
+{
+ QStringList deletable;
+
+ {//scope delete deleteArray object
+ QStringList deleteArray;
+ readDeleteableFiles(deleteArray);
+ deleteFiles(deleteArray, deletable); // try to delete deleteable
+ }
+
+ QStringList files;
+ for (uint32_t i = 0; i < segments->size(); i++) {
+ SegmentReader* reader = (*segments)[i];
+ files.clear();
+ reader->files(files);
+ if (reader->getDirectory() == this->directory)
+ deleteFiles(files, deletable); // try to delete our files
+ else
+ deleteFiles(files, reader->getDirectory()); // delete, eg, RAM files
+ }
+
+ writeDeleteableFiles(deletable); // note files we can't delete
+}
+
+void IndexWriter::deleteFiles(const QStringList& files)
+{
+ QStringList currentDeletable;
+ readDeleteableFiles(currentDeletable);
+
+ // try to delete deleteable
+ QStringList deletable;
+ deleteFiles(currentDeletable, deletable);
+
+ // try to delete our files
+ deleteFiles(files, deletable);
+
+ // note files we can't delete
+ writeDeleteableFiles(deletable);
+}
+
+void IndexWriter::readDeleteableFiles(QStringList& result)
+{
+ if (!directory->fileExists(QLatin1String("deletable")))
+ return;
+
+ IndexInput* input = directory->openInput(QLatin1String("deletable"));
+ try {
+ // read file names
+ TCHAR tname[CL_MAX_PATH];
+ for (int32_t i = input->readInt(); i > 0; i--) {
+ int32_t read = input->readString(tname, CL_MAX_PATH);
+ result.push_back(QString::fromWCharArray(tname, read));
+ }
+ } _CLFINALLY (
+ input->close();
+ _CLDELETE(input);
+ );
+}
+
+void IndexWriter::deleteFiles(const QStringList& files, QStringList& deletable)
+{
+ QStringList::const_iterator itr;
+ for (itr = files.begin(); itr != files.end(); ++itr) {
+ if (!getDirectory()->fileExists((*itr)))
+ continue;
+
+ if (!getDirectory()->deleteFile((*itr), false)) {
+ if (directory->fileExists((*itr))) {
+#ifdef _CL_DEBUG_INFO
+ fprintf(_CL_DEBUG_INFO, "%s; Will re-try later.\n", err.what());
+#endif
+ // add to deletable
+ deletable.push_back((*itr));
+ }
+ }
+ }
+}
+
+void IndexWriter::deleteFiles(const QStringList& files, Directory* directory)
+{
+ QStringList::const_iterator itr;
+ for (itr = files.begin(); itr != files.end(); ++itr)
+ directory->deleteFile((*itr), true);
+}
+
+void IndexWriter::writeDeleteableFiles(const QStringList& files)
+{
+ IndexOutput* output = directory->createOutput(QLatin1String("deleteable.new"));
+ try {
+ output->writeInt(files.size());
+
+ TCHAR tfile[CL_MAX_PATH];
+ QStringList::const_iterator itr;
+ for (itr = files.begin(); itr != files.end(); ++itr) {
+ tfile[(*itr).toWCharArray(tfile)] = '\0';
+ output->writeString(tfile, _tcslen(tfile));
+ }
+ } _CLFINALLY (
+ output->close();
+ _CLDELETE(output);
+ );
+
+ directory->renameFile(QLatin1String("deleteable.new"),
+ QLatin1String("deletable"));
+}
+
+void IndexWriter::addIndexes(Directory** dirs)
+{
+ //Func - Add several indexes located in different directories into the current
+ // one managed by this instance
+ //Pre - dirs != NULL and contains directories of several indexes
+ // dirsLength > 0 and contains the number of directories
+ //Post - The indexes located in the directories in dirs have been merged with
+ // the pre(current) index. The Resulting index has also been optimized
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ CND_PRECONDITION(dirs != NULL, "dirs is NULL");
+
+ // start with zero or 1 seg so optimize the current
+ optimize();
+
+ int32_t start = segmentInfos.size();
+
+ //Iterate through the directories
+ for (int32_t i = 0; dirs[i] != NULL; ++i) {
+ // DSR: Changed SegmentInfos constructor arg (see bug discussion below).
+ SegmentInfos sis(false);
+ sis.read(dirs[i]);
+ for (int32_t j = 0; j < sis.size(); j++)
+ segmentInfos.add(sis.info(j)); // add each info
+ }
+
+ // commented out by tbusch to solve a bug and to be conform with
+ // java lucene
+
+ // merge newly added segments in log(n) passes
+ //while (segmentInfos.size() > start + mergeFactor) {
+ // for (int32_t base = start; base < segmentInfos.size(); base++) {
+ // int32_t end = min(segmentInfos.size(), base + mergeFactor);
+ // if (end - base > 1)
+ // mergeSegments(base, end);
+ // }
+ //}
+
+ // cleanup
+ optimize();
+}
+
+
+void IndexWriter::addIndexes(IndexReader** readers)
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ optimize(); // start with zero or 1 seg
+
+ QString mergedName = newSegmentName();
+ SegmentMerger merger(this, mergedName);
+
+ CLVector<SegmentReader*> segmentsToDelete;
+ SegmentReader* sReader = NULL;
+ if (segmentInfos.size() == 1) { // add existing index, if any
+ sReader = _CLNEW SegmentReader(segmentInfos.info(0));
+ merger.add(sReader);
+ segmentsToDelete.push_back(sReader); // queue segment for deletion
+ }
+
+ int32_t readersLength = 0;
+ while (readers[readersLength] != NULL)
+ merger.add(readers[readersLength++]);
+
+ int32_t docCount = merger.merge(); // merge 'em
+
+ // pop old infos & add new
+ segmentInfos.clearto(0);
+ segmentInfos.add(_CLNEW SegmentInfo(mergedName, docCount, directory));
+
+ if (sReader != NULL) {
+ sReader->close();
+ _CLDELETE(sReader);
+ }
+
+ LuceneLock* lock = directory->makeLock(IndexWriter::COMMIT_LOCK_NAME);
+ LockWith2 with(lock, commitLockTimeout, this, &segmentsToDelete, true);
+ {
+ // in- & inter-process sync
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ with.run();
+ }
+ _CLDELETE(lock);
+
+ if (useCompoundFile) {
+ QStringList filesToDelete;
+ merger.createCompoundFile(mergedName + QLatin1String(".tmp"),
+ filesToDelete);
+
+ LuceneLock* cfslock = directory->makeLock(IndexWriter::COMMIT_LOCK_NAME);
+ LockWithCFS with(cfslock, commitLockTimeout, directory, this, mergedName,
+ filesToDelete);
+ {
+ // in- & inter-process sync
+ SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
+ with.run();
+ }
+ _CLDELETE(cfslock);
+ }
+}
+
+// #pragma mark -- IndexWriter::LockWith2
+
+IndexWriter::LockWith2::LockWith2(CL_NS(store)::LuceneLock* lock,
+ int64_t lockWaitTimeout,
+ IndexWriter* indexWriter,
+ CL_NS(util)::CLVector<SegmentReader*>* std,
+ bool _create)
+ : CL_NS(store)::LuceneLockWith<void>(lock, lockWaitTimeout)
+ , create(_create)
+ , writer(indexWriter)
+ , segmentsToDelete(std)
+{
+}
+
+void IndexWriter::LockWith2::doBody()
+{
+ //Func - Writes segmentInfos to or reads segmentInfos from disk
+ //Pre - writer != NULL
+ //Post - if create is true then segementInfos has been written to disk
+ // otherwise segmentInfos has been read from disk
+
+ CND_PRECONDITION(writer != NULL, "writer is NULL");
+
+ if (create) {
+ writer->segmentInfos.write(writer->getDirectory());
+ // delete now-unused segments
+ if (segmentsToDelete != NULL)
+ writer->deleteSegments(segmentsToDelete);
+ } else {
+ writer->segmentInfos.read(writer->getDirectory());
+ }
+}
+
+// #pragma mark -- IndexWriter::LockWithCFS
+
+IndexWriter::LockWithCFS::LockWithCFS(CL_NS(store)::LuceneLock* lock,
+ int64_t lockWaitTimeout,
+ CL_NS(store)::Directory* dir,
+ IndexWriter* indexWriter,
+ const QString& segmentName,
+ const QStringList& ftd)
+ : CL_NS(store)::LuceneLockWith<void>(lock, lockWaitTimeout)
+ , segName(segmentName)
+ , writer(indexWriter)
+ , directory(dir)
+ , filesToDelete(ftd)
+{
+}
+
+void IndexWriter::LockWithCFS::doBody()
+{
+ //Func - Writes segmentInfos to or reads segmentInfos from disk
+ //Pre - writer != NULL
+ //Post - if create is true then segementInfos has been written to disk
+ // otherwise segmentInfos has been read from disk
+
+ CND_PRECONDITION(directory != NULL, "directory is NULL");
+ CND_PRECONDITION(!segName.isEmpty(), "mergedName is NULL");
+
+ // make compound file visible for SegmentReaders
+ directory->renameFile(segName + QLatin1String(".tmp"),
+ segName + QLatin1String(".cfs"));
+ // delete now unused files of segment
+ writer->deleteFiles(filesToDelete);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/IndexWriter.h b/3rdparty/clucene/src/CLucene/index/IndexWriter.h
new file mode 100644
index 000000000..80476c864
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/IndexWriter.h
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_IndexWriter_
+#define _lucene_index_IndexWriter_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include "CLucene/analysis/AnalysisHeader.h"
+#include "CLucene/util/VoidList.h"
+#include "CLucene/search/Similarity.h"
+#include "CLucene/store/Lock.h"
+#include "CLucene/store/TransactionalRAMDirectory.h"
+
+#include "SegmentHeader.h"
+
+CL_NS_DEF(index)
+
+/**
+An IndexWriter creates and maintains an index.
+
+The third argument to the
+<a href="#IndexWriter(org.apache.lucene.store.Directory, org.apache.lucene.analysis.Analyzer, boolean)"><b>constructor</b></a>
+determines whether a new index is created, or whether an existing index is
+opened for the addition of new documents.
+
+In either case, documents are added with the <a
+href="#addDocument(org.apache.lucene.document.Document)"><b>addDocument</b></a> method.
+When finished adding documents, <a href="#close()"><b>close</b></a> should be called.
+
+<p>If an index will not have more documents added for a while and optimal search
+performance is desired, then the <a href="#optimize()"><b>optimize</b></a>
+method should be called before the index is closed.
+
+<p>Opening an IndexWriter creates a lock file for the directory in use. Trying to open
+another IndexWriter on the same directory will lead to an IOException. The IOException
+is also thrown if an IndexReader on the same directory is used to delete documents
+from the index.
+
+@see IndexModifier IndexModifier supports the important methods of IndexWriter plus deletion
+*/
+class IndexWriter : LUCENE_BASE
+{
+ class LockWith2 : public CL_NS(store)::LuceneLockWith<void>
+ {
+ public:
+ LockWith2(CL_NS(store)::LuceneLock* lock,
+ int64_t lockWaitTimeout,
+ IndexWriter* wr,
+ CL_NS(util)::CLVector<SegmentReader*>* std,
+ bool create);
+
+ ~LockWith2() {}
+
+ void doBody();
+
+ private:
+ bool create;
+ IndexWriter* writer;
+ CL_NS(util)::CLVector<SegmentReader*>* segmentsToDelete;
+ };
+ friend class LockWith2;
+
+ class LockWithCFS : public CL_NS(store)::LuceneLockWith<void>
+ {
+ public:
+ LockWithCFS(CL_NS(store)::LuceneLock* lock,
+ int64_t lockWaitTimeout,
+ CL_NS(store)::Directory* dir,
+ IndexWriter* wr,
+ const QString& segName,
+ const QStringList& ftd);
+
+ ~LockWithCFS() {}
+
+ void doBody();
+
+ private:
+ QString segName;
+ IndexWriter* writer;
+ CL_NS(store)::Directory* directory;
+ QStringList filesToDelete;
+ };
+ friend class IndexWriter::LockWithCFS;
+
+ // indicates if the writers is open - this way close can be called multiple
+ // times
+ bool isOpen;
+
+ // how to analyze text
+ CL_NS(analysis)::Analyzer* analyzer;
+
+ CL_NS(search)::Similarity* similarity; // how to normalize
+
+ /** Use compound file setting. Normally defaults to true, except when
+ * using a RAMDirectory. This minimizes the number of files used.
+ * Setting this to false may improve indexing performance, but
+ * may also cause file handle problems.
+ */
+ bool useCompoundFile;
+ bool closeDir;
+
+ // for temp segs
+ CL_NS(store)::TransactionalRAMDirectory* ramDirectory;
+
+ CL_NS(store)::LuceneLock* writeLock;
+
+ void _IndexWriter(const bool create);
+
+ void _finalize();
+
+ // where this index resides
+ CL_NS(store)::Directory* directory;
+
+
+ int32_t getSegmentsCounter() { return segmentInfos.counter; }
+ int32_t maxFieldLength;
+ int32_t mergeFactor;
+ int32_t minMergeDocs;
+ int32_t maxMergeDocs;
+ int32_t termIndexInterval;
+
+ int64_t writeLockTimeout;
+ int64_t commitLockTimeout;
+public:
+ DEFINE_MUTEX(THIS_LOCK)
+
+ // Release the write lock, if needed.
+ SegmentInfos segmentInfos;
+
+ // Release the write lock, if needed.
+ ~IndexWriter();
+
+ /**
+ * The Java implementation of Lucene silently truncates any tokenized
+ * field if the number of tokens exceeds a certain threshold. Although
+ * that threshold is adjustable, it is easy for the client programmer
+ * to be unaware that such a threshold exists, and to become its
+ * unwitting victim.
+ * CLucene implements a less insidious truncation policy. Up to
+ * DEFAULT_MAX_FIELD_LENGTH tokens, CLucene behaves just as JLucene
+ * does. If the number of tokens exceeds that threshold without any
+ * indication of a truncation preference by the client programmer,
+ * CLucene raises an exception, prompting the client programmer to
+ * explicitly set a truncation policy by adjusting maxFieldLength.
+ */
+ LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MAX_FIELD_LENGTH = 10000);
+ LUCENE_STATIC_CONSTANT(int32_t, FIELD_TRUNC_POLICY__WARN = -1);
+ int32_t getMaxFieldLength() const{ return maxFieldLength; }
+ void setMaxFieldLength(int32_t val){ maxFieldLength = val; }
+
+ /**
+ * Default value is 10. Change using {@link #setMaxBufferedDocs(int)}.
+ */
+ LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MAX_BUFFERED_DOCS = 10);
+ /** Determines the minimal number of documents required before the buffered
+ * in-memory documents are merging and a new Segment is created.
+ * Since Documents are merged in a {@link RAMDirectory},
+ * large value gives faster indexing. At the same time, mergeFactor limits
+ * the number of files open in a FSDirectory.
+ *
+ * <p> The default value is DEFAULT_MAX_BUFFERED_DOCS.*/
+ void setMaxBufferedDocs(int32_t val){ minMergeDocs = val; }
+ /**
+ * @see #setMaxBufferedDocs
+ */
+ int32_t getMaxBufferedDocs(){ return minMergeDocs; }
+
+ /**
+ * Default value for the write lock timeout (1,000).
+ */
+ LUCENE_STATIC_CONSTANT(int64_t, WRITE_LOCK_TIMEOUT = 1000);
+ /**
+ * Sets the maximum time to wait for a write lock (in milliseconds).
+ */
+ void setWriteLockTimeout(int64_t writeLockTimeout)
+ { this->writeLockTimeout = writeLockTimeout; }
+ /**
+ * @see #setWriteLockTimeout
+ */
+ int64_t getWriteLockTimeout() { return writeLockTimeout; }
+
+ /**
+ * Default value for the commit lock timeout (10,000).
+ */
+ LUCENE_STATIC_CONSTANT(int64_t, COMMIT_LOCK_TIMEOUT = 10000);
+ /**
+ * Sets the maximum time to wait for a commit lock (in milliseconds).
+ */
+ void setCommitLockTimeout(int64_t commitLockTimeout)
+ { this->commitLockTimeout = commitLockTimeout; }
+ /**
+ * @see #setCommitLockTimeout
+ */
+ int64_t getCommitLockTimeout() { return commitLockTimeout; }
+
+ static const QLatin1String WRITE_LOCK_NAME; //"write.lock";
+ static const QLatin1String COMMIT_LOCK_NAME; //"commit.lock";
+
+ /**
+ * Default value is 10. Change using {@link #setMergeFactor(int)}.
+ */
+ LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MERGE_FACTOR = 10);
+ /* Determines how often segment indices are merged by addDocument(). With
+ * smaller values, less RAM is used while indexing, and searches on
+ * unoptimized indices are faster, but indexing speed is slower. With larger
+ * values more RAM is used while indexing and searches on unoptimized indices
+ * are slower, but indexing is faster. Thus larger values (> 10) are best
+ * for batched index creation, and smaller values (< 10) for indices that are
+ * interactively maintained.
+ *
+ * <p>This must never be less than 2. The default value is 10.
+ */
+ int32_t getMergeFactor() const{ return mergeFactor; }
+ void setMergeFactor(int32_t val){ mergeFactor = val; }
+
+
+ /** Expert: The fraction of terms in the "dictionary" which should be stored
+ * in RAM. Smaller values use more memory, but make searching slightly
+ * faster, while larger values use less memory and make searching slightly
+ * slower. Searching is typically not dominated by dictionary lookup, so
+ * tweaking this is rarely useful.
+ */
+ LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_TERM_INDEX_INTERVAL = 128);
+ /** Expert: Set the interval between indexed terms. Large values cause less
+ * memory to be used by IndexReader, but slow random-access to terms. Small
+ * values cause more memory to be used by an IndexReader, and speed
+ * random-access to terms.
+ *
+ * This parameter determines the amount of computation required per query
+ * term, regardless of the number of documents that contain that term. In
+ * particular, it is the maximum number of other terms that must be
+ * scanned before a term is located and its frequency and position information
+ * may be processed. In a large index with user-entered query terms, query
+ * processing time is likely to be dominated not by term lookup but rather
+ * by the processing of frequency and positional data. In a small index
+ * or when many uncommon query terms are generated (e.g., by wildcard
+ * queries) term lookup may become a dominant cost.
+ *
+ * In particular, <code>numUniqueTerms/interval</code> terms are read into
+ * memory by an IndexReader, and, on average, <code>interval/2</code> terms
+ * must be scanned for each random term access.
+ *
+ * @see #DEFAULT_TERM_INDEX_INTERVAL
+ */
+ void setTermIndexInterval(int32_t interval) { termIndexInterval = interval; }
+ /** Expert: Return the interval between indexed terms.
+ *
+ * @see #setTermIndexInterval(int)
+ */
+ int32_t getTermIndexInterval() { return termIndexInterval; }
+
+ /** Determines the minimal number of documents required before the buffered
+ * in-memory documents are merging and a new Segment is created.
+ * Since Documents are merged in a {@link RAMDirectory},
+ * large value gives faster indexing. At the same time, mergeFactor limits
+ * the number of files open in a FSDirectory.
+ *
+ * <p> The default value is 10.*/
+ int32_t getMinMergeDocs() const{ return minMergeDocs; }
+ void setMinMergeDocs(int32_t val){ minMergeDocs = val; }
+
+ /** Determines the largest number of documents ever merged by addDocument().
+ * Small values (e.g., less than 10,000) are best for interactive indexing,
+ * as this limits the length of pauses while indexing to a few seconds.
+ * Larger values are best for batched indexing and speedier searches.
+ *
+ * <p>The default value is {@link #DEFAULT_MAX_MERGE_DOCS}.
+ */
+ LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MAX_MERGE_DOCS = LUCENE_INT32_MAX_SHOULDBE);
+ /**Determines the largest number of documents ever merged by addDocument().
+ * Small values (e.g., less than 10,000) are best for interactive indexing,
+ * as this limits the length of pauses while indexing to a few seconds.
+ * Larger values are best for batched indexing and speedier searches.
+ *
+ * <p>The default value is {@link Integer#MAX_VALUE}.
+ */
+ int32_t getMaxMergeDocs() const{ return maxMergeDocs; }
+ void setMaxMergeDocs(int32_t val){ maxMergeDocs = val; }
+
+ /**
+ * Constructs an IndexWriter for the index in <code>path</code>.
+ * Text will be analyzed with <code>a</code>. If <code>create</code>
+ * is true, then a new, empty index will be created in
+ * <code>path</code>, replacing the index already there, if any.
+ *
+ * @param path the path to the index directory
+ * @param a the analyzer to use
+ * @param create <code>true</code> to create the index or overwrite
+ * the existing one; <code>false</code> to append to the existing
+ * index
+ * @throws IOException if the directory cannot be read/written to, or
+ * if it does not exist, and <code>create</code> is
+ * <code>false</code>
+ */
+ IndexWriter(const QString& path, CL_NS(analysis)::Analyzer* a,
+ const bool create, const bool closeDir = true);
+
+
+ /**Constructs an IndexWriter for the index in <code>d</code>. Text will be
+ * analyzed with <code>a</code>. If <code>create</code> is true, then a new,
+ * empty index will be created in <code>d</code>, replacing the index already
+ * there, if any.
+ */
+ IndexWriter(CL_NS(store)::Directory* d, CL_NS(analysis)::Analyzer* a,
+ const bool create, const bool closeDir = false);
+
+ // Flushes all changes to an index, closes all associated files, and closes
+ // the directory that the index is stored in.
+ void close();
+
+ // Returns the number of documents currently in this index. synchronized
+ int32_t docCount();
+
+
+ // Adds a document to this index, using the provided analyzer instead of
+ // the value of {@link #getAnalyzer()}. If the document contains more than
+ // {@link #setMaxFieldLength(int)} terms for a given field, the remainder
+ // are discarded.
+ void addDocument(CL_NS(document)::Document* doc,
+ CL_NS(analysis)::Analyzer* analyzer = NULL);
+
+
+ // Merges all segments together into a single segment, optimizing an index
+ // for search. synchronized
+ void optimize();
+
+
+ /**Merges all segments from an array of indices into this index.
+ *
+ * <p>This may be used to parallelize batch indexing. A large document
+ * collection can be broken into sub-collections. Each sub-collection can be
+ * indexed in parallel, on a different thread, process or machine. The
+ * complete index can then be created by merging sub-collection indices
+ * with this method.
+ *
+ * <p>After this completes, the index is optimized.
+ *@synchronized
+ */
+ void addIndexes(CL_NS(store)::Directory** dirs);
+
+ /** Merges the provided indexes into this index.
+ * <p>After this completes, the index is optimized. </p>
+ * <p>The provided IndexReaders are not closed.</p>
+ */
+ void addIndexes(IndexReader** readers);
+
+
+ /** Returns the directory this index resides in. */
+ CL_NS(store)::Directory* getDirectory() { return directory; }
+
+ /** Get the current setting of whether to use the compound file format.
+ * Note that this just returns the value you set with setUseCompoundFile(boolean)
+ * or the default. You cannot use this to query the status of an existing index.
+ * @see #setUseCompoundFile(boolean)
+ */
+ bool getUseCompoundFile() { return useCompoundFile; }
+
+ /** Setting to turn on usage of a compound file. When on, multiple files
+ * for each segment are merged into a single file once the segment creation
+ * is finished. This is done regardless of what directory is in use.
+ */
+ void setUseCompoundFile(bool value) { useCompoundFile = value; }
+
+
+ /** Expert: Set the Similarity implementation used by this IndexWriter.
+ *
+ * @see Similarity#setDefault(Similarity)
+ */
+ void setSimilarity(CL_NS(search)::Similarity* similarity)
+ { this->similarity = similarity; }
+
+ /** Expert: Return the Similarity implementation used by this IndexWriter.
+ *
+ * <p>This defaults to the current value of {@link Similarity#getDefault()}.
+ */
+ CL_NS(search)::Similarity* getSimilarity() { return this->similarity; }
+
+ /** Returns the analyzer used by this index. */
+ CL_NS(analysis)::Analyzer* getAnalyzer() { return analyzer; }
+
+private:
+ /** Merges all RAM-resident segments. */
+ void flushRamSegments();
+
+ /** Incremental segment merger. */
+ void maybeMergeSegments();
+
+ // Pops segments off of segmentInfos stack down to minSegment, merges them,
+ // and pushes the merged index onto the top of the segmentInfos stack.
+ void mergeSegments(const uint32_t minSegment);
+
+ // Merges the named range of segments, replacing them in the stack with a
+ // single segment.
+ void mergeSegments(const uint32_t minSegment, const uint32_t end);
+
+ // Some operating systems (e.g. Windows) don't permit a file to be deleted
+ // while it is opened for read (e.g. by another process or thread). So we
+ // assume that when a delete fails it is because the file is open in another
+ // process, and queue the file for subsequent deletion.
+ void deleteSegments(CL_NS(util)::CLVector<SegmentReader*>* segments);
+
+ void deleteFiles(const QStringList& files);
+ void readDeleteableFiles(QStringList& files);
+ void deleteFiles(const QStringList& files, QStringList& deletable);
+ void deleteFiles(const QStringList& files, CL_NS(store)::Directory* directory);
+ void writeDeleteableFiles(const QStringList& files);
+
+ // synchronized
+ QString newSegmentName();
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/MultiReader.cpp b/3rdparty/clucene/src/CLucene/index/MultiReader.cpp
new file mode 100644
index 000000000..1260d04dc
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/MultiReader.cpp
@@ -0,0 +1,722 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "MultiReader.h"
+
+#include "IndexReader.h"
+#include "CLucene/document/Document.h"
+#include "Terms.h"
+#include "SegmentMergeQueue.h"
+
+CL_NS_USE(store)
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+MultiReader::MultiReader(IndexReader** subReaders):
+ IndexReader(subReaders == NULL || subReaders[0] == NULL ? NULL : subReaders[0]->getDirectory()),
+ normsCache(true, true)
+{
+ initialize(subReaders);
+}
+
+MultiReader::MultiReader(Directory* directory, SegmentInfos* sis, IndexReader** subReaders):
+ IndexReader(directory, sis, false),
+ normsCache(true, true)
+{
+ initialize(subReaders);
+}
+
+
+MultiReader::~MultiReader() {
+//Func - Destructor
+//Pre - true
+//Post - The instance has been destroyed all IndexReader instances
+// this instance managed have been destroyed to
+
+ _CLDELETE_ARRAY(ones);
+ _CLDELETE_ARRAY(starts);
+
+ //Iterate through the subReaders and destroy each reader
+ if (subReaders && subReadersLength > 0) {
+ for (int32_t i = 0; i < subReadersLength; i++) {
+ _CLDELETE(subReaders[i]);
+ }
+ }
+ //Destroy the subReaders array
+ _CLDELETE_ARRAY(subReaders);
+}
+
+void MultiReader::initialize(IndexReader** subReaders){
+ this->subReadersLength = 0;
+ this->subReaders = subReaders;
+
+ //count the subReaders size
+ if ( subReaders != NULL ){
+ while ( subReaders[subReadersLength] != NULL ){
+ subReadersLength++;
+ }
+ }
+ _maxDoc = 0;
+ _numDocs = -1;
+ ones = NULL;
+
+ starts = _CL_NEWARRAY(int32_t,subReadersLength + 1); // build starts array
+ for (int32_t i = 0; i < subReadersLength; i++) {
+ starts[i] = _maxDoc;
+
+ // compute maxDocs
+ _maxDoc += subReaders[i]->maxDoc();
+ if (subReaders[i]->hasDeletions())
+ _hasDeletions = true;
+ }
+ starts[subReadersLength] = _maxDoc;
+}
+
+bool MultiReader::getTermFreqVectors(int32_t n, Array<TermFreqVector*>& result){
+ int32_t i = readerIndex(n); // find segment num
+ return subReaders[i]->getTermFreqVectors(n - starts[i], result); // dispatch to segment
+}
+
+TermFreqVector* MultiReader::getTermFreqVector(int32_t n, const TCHAR* field){
+ int32_t i = readerIndex(n); // find segment num
+ return subReaders[i]->getTermFreqVector(n - starts[i], field);
+}
+
+
+int32_t MultiReader::numDocs() {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ if (_numDocs == -1) { // check cache
+ int32_t n = 0; // cache miss--recompute
+ for (int32_t i = 0; i < subReadersLength; i++)
+ n += subReaders[i]->numDocs(); // sum from readers
+ _numDocs = n;
+ }
+ return _numDocs;
+}
+
+int32_t MultiReader::maxDoc() const {
+ return _maxDoc;
+}
+
+bool MultiReader::document(int32_t n, CL_NS(document)::Document* doc){
+ int32_t i = readerIndex(n); // find segment num
+ return subReaders[i]->document(n - starts[i],doc); // dispatch to segment reader
+}
+
+bool MultiReader::isDeleted(const int32_t n) {
+ int32_t i = readerIndex(n); // find segment num
+ return subReaders[i]->isDeleted(n - starts[i]); // dispatch to segment reader
+}
+
+uint8_t* MultiReader::norms(const TCHAR* field){
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ uint8_t* bytes;
+ bytes = normsCache.get(field);
+ if (bytes != NULL){
+ return bytes; // cache hit
+ }
+
+ if ( !hasNorms(field) )
+ return fakeNorms();
+
+ bytes = _CL_NEWARRAY(uint8_t,maxDoc());
+ for (int32_t i = 0; i < subReadersLength; i++)
+ subReaders[i]->norms(field, bytes + starts[i]);
+
+ //Unfortunately the data in the normCache can get corrupted, since it's being loaded with string
+ //keys that may be deleted while still in use by the map. To prevent this field is duplicated
+ //and then stored in the normCache
+ TCHAR* key = STRDUP_TtoT(field);
+ //update cache
+ normsCache.put(key, bytes);
+
+ return bytes;
+}
+
+void MultiReader::norms(const TCHAR* field, uint8_t* result) {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ uint8_t* bytes = normsCache.get(field);
+ if (bytes==NULL && !hasNorms(field))
+ bytes=fakeNorms();
+
+ if (bytes != NULL){ // cache hit
+ int32_t len = maxDoc();
+ memcpy(result,bytes,len * sizeof(int32_t));
+ }
+
+ for (int32_t i = 0; i < subReadersLength; i++) // read from segments
+ subReaders[i]->norms(field, result + starts[i]);
+}
+
+
+void MultiReader::doSetNorm(int32_t n, const TCHAR* field, uint8_t value){
+ normsCache.remove(field); // clear cache
+ int32_t i = readerIndex(n); // find segment num
+ subReaders[i]->setNorm(n-starts[i], field, value); // dispatch
+}
+
+TermEnum* MultiReader::terms() const {
+ return _CLNEW MultiTermEnum(subReaders, starts, NULL);
+}
+
+TermEnum* MultiReader::terms(const Term* term) const {
+ return _CLNEW MultiTermEnum(subReaders, starts, term);
+}
+
+int32_t MultiReader::docFreq(const Term* t) const {
+ int32_t total = 0; // sum freqs in Multi
+ for (int32_t i = 0; i < subReadersLength; i++)
+ total += subReaders[i]->docFreq(t);
+ return total;
+}
+
+TermDocs* MultiReader::termDocs() const {
+ TermDocs* ret = _CLNEW MultiTermDocs(subReaders, starts);
+ return ret;
+}
+
+TermPositions* MultiReader::termPositions() const {
+ TermPositions* ret = (TermPositions*)_CLNEW MultiTermPositions(subReaders, starts);
+ return ret;
+}
+
+void MultiReader::doDelete(const int32_t n) {
+ _numDocs = -1; // invalidate cache
+ int32_t i = readerIndex(n); // find segment num
+ subReaders[i]->deleteDocument(n - starts[i]); // dispatch to segment reader
+ _hasDeletions = true;
+}
+
+int32_t MultiReader::readerIndex(const int32_t n) const { // find reader for doc n:
+ int32_t lo = 0; // search starts array
+ int32_t hi = subReadersLength - 1; // for first element less
+ // than n, return its index
+ while (hi >= lo) {
+ int32_t mid = (lo + hi) >> 1;
+ int32_t midValue = starts[mid];
+ if (n < midValue)
+ hi = mid - 1;
+ else if (n > midValue)
+ lo = mid + 1;
+ else{ // found a match
+ while (mid+1 < subReadersLength && starts[mid+1] == midValue) {
+ mid++; // scan to last match
+ }
+ return mid;
+ }
+ }
+ return hi;
+}
+
+bool MultiReader::hasNorms(const TCHAR* field) {
+ for (int i = 0; i < subReadersLength; i++) {
+ if (subReaders[i]->hasNorms(field))
+ return true;
+ }
+ return false;
+}
+uint8_t* MultiReader::fakeNorms() {
+ if (ones==NULL)
+ ones=SegmentReader::createFakeNorms(maxDoc());
+ return ones;
+}
+
+void MultiReader::doUndeleteAll(){
+ for (int32_t i = 0; i < subReadersLength; i++)
+ subReaders[i]->undeleteAll();
+ _hasDeletions = false;
+ _numDocs = -1;
+}
+void MultiReader::doCommit() {
+ for (int32_t i = 0; i < subReadersLength; i++)
+ subReaders[i]->commit();
+}
+
+void MultiReader::doClose() {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ for (int32_t i = 0; i < subReadersLength; i++){
+ subReaders[i]->close();
+ }
+}
+
+
+void MultiReader::getFieldNames(FieldOption fldOption, StringArrayWithDeletor& retarray){
+ StringArrayWithDeletor temp;
+ CLHashList<TCHAR*> hashList;
+ for (int32_t i = 0; i < subReadersLength; i++) {
+ IndexReader* reader = subReaders[i];
+ reader->getFieldNames(fldOption, temp);
+
+ //create a unique list of names.
+ StringArrayWithDeletor::iterator itr = temp.begin();
+ while ( itr != temp.end() ){
+ if ( hashList.find(*itr) == hashList.end() )
+ hashList.insert(STRDUP_TtoT(*itr));
+ itr++;
+ }
+ }
+ //move the items into the return
+ CLHashList<TCHAR*>::iterator itr = hashList.begin();
+ while ( itr != hashList.end() ){
+ retarray.push_back(*itr);//no need to copy, already done!
+ itr++;
+ }
+}
+
+
+MultiTermDocs::MultiTermDocs(){
+//Func - Default constructor
+// Initialises an empty MultiTermDocs.
+// This constructor is needed to allow the constructor of MultiTermPositions
+// initialise the instance by itself
+//Pre - true
+//Post - An empty
+
+ subReaders = NULL;
+ subReadersLength = 0;
+ starts = NULL;
+ base = 0;
+ pointer = 0;
+ current = NULL;
+ term = NULL;
+ readerTermDocs = NULL;
+}
+
+MultiTermDocs::MultiTermDocs(IndexReader** r, const int32_t* s){
+//Func - Constructor
+//Pre - if r is NULL then rLen must be 0 else if r != NULL then rLen > 0
+// s != NULL
+//Post - The instance has been created
+
+ //count readers
+ subReadersLength = 0;
+ subReaders = r;
+
+ CND_PRECONDITION(s != NULL, "s is NULL");
+
+ if ( subReaders != NULL ){
+ while ( subReaders[subReadersLength] != NULL )
+ subReadersLength++;
+ }
+
+ starts = s;
+ base = 0;
+ pointer = 0;
+ current = NULL;
+ term = NULL;
+
+ readerTermDocs = NULL;
+
+ //Check if there are subReaders
+ if(subReaders != NULL && subReadersLength > 0){
+ readerTermDocs = _CL_NEWARRAY(TermDocs*, subReadersLength+1);
+
+ CND_CONDITION(readerTermDocs != NULL,"No memory could be allocated for readerTermDocs");
+
+ //Initialize the readerTermDocs pointer array to NULLs
+ for ( int32_t i=0;i<subReadersLength+1;i++){
+ readerTermDocs[i]=NULL;
+ }
+ }
+}
+
+MultiTermDocs::~MultiTermDocs(){
+//Func - Destructor
+//Pre - true
+//Post - The instance has been destroyed
+
+ close();
+}
+
+
+TermPositions* MultiTermDocs::__asTermPositions(){
+ return NULL;
+}
+
+int32_t MultiTermDocs::doc() const {
+ CND_PRECONDITION(current!=NULL,"current==NULL, check that next() was called");
+ return base + current->doc();
+}
+int32_t MultiTermDocs::freq() const {
+ CND_PRECONDITION(current!=NULL,"current==NULL, check that next() was called");
+ return current->freq();
+}
+
+void MultiTermDocs::seek(TermEnum* termEnum){
+ seek(termEnum->term(false));
+}
+
+void MultiTermDocs::seek( Term* tterm) {
+//Func - Resets the instance for a new search
+//Pre - tterm != NULL
+//Post - The instance has been reset for a new search
+
+ CND_PRECONDITION(tterm != NULL, "tterm is NULL");
+
+ //Assigning tterm is done as below for a reason
+ //The construction ensures that if seek is called from within
+ //MultiTermDocs with as argument this->term (seek(this->term)) that the assignment
+ //will succeed and all referencecounters represent the correct situation
+
+ //Get a pointer from tterm and increase its reference counter
+ Term *TempTerm = _CL_POINTER(tterm);
+
+ //Finialize term to ensure we decrease the reference counter of the instance which term points to
+ _CLDECDELETE(term);
+
+ //Assign TempTerm to term
+ term = TempTerm;
+
+ base = 0;
+ pointer = 0;
+ current = NULL;
+}
+
+bool MultiTermDocs::next() {
+ if (current != NULL && current->next()) {
+ return true;
+ } else if (pointer < subReadersLength) {
+ base = starts[pointer];
+ current = termDocs(pointer++);
+ return next();
+ } else
+ return false;
+}
+
+int32_t MultiTermDocs::read(int32_t* docs, int32_t* freqs, int32_t length) {
+ while (true) {
+ while (current == NULL) {
+ if (pointer < subReadersLength) { // try next segment
+ base = starts[pointer];
+ current = termDocs(pointer++);
+ } else {
+ return 0;
+ }
+ }
+ int32_t end = current->read(docs, freqs,length);
+ if (end == 0) { // none left in segment
+ current = NULL;
+ } else { // got some
+ int32_t b = base; // adjust doc numbers
+ for (int32_t i = 0; i < end; i++)
+ docs[i] += b;
+ return end;
+ }
+ }
+}
+
+bool MultiTermDocs::skipTo(const int32_t target) {
+ do {
+ if (!next())
+ return false;
+ } while (target > doc());
+ return true;
+}
+
+void MultiTermDocs::close() {
+//Func - Closes all MultiTermDocs managed by this instance
+//Pre - true
+//Post - All the MultiTermDocs have been closed
+
+
+ //Check if readerTermDocs is valid
+ if (readerTermDocs){
+ TermDocs* curTD = NULL;
+ //iterate through the readerTermDocs array
+ for (int32_t i = 0; i < subReadersLength; i++) {
+ //Retrieve the i-th TermDocs instance
+ curTD = readerTermDocs[i];
+
+ //Check if it is a valid pointer
+ if (curTD != NULL) {
+ //Close it
+ curTD->close();
+ _CLDELETE(curTD);
+ }
+ }
+
+ _CLDELETE_ARRAY(readerTermDocs);
+ }
+
+ //current previously pointed to a member of readerTermDocs; ensure that
+ //it doesn't now point to invalid memory.
+ current = NULL;
+ base = 0;
+ pointer = 0;
+
+ _CLDECDELETE(term);
+}
+
+TermDocs* MultiTermDocs::termDocs(const IndexReader* reader) const {
+ TermDocs* ret = reader->termDocs();
+ return ret;
+}
+
+TermDocs* MultiTermDocs::termDocs(const int32_t i) const {
+ if (term == NULL)
+ return NULL;
+ TermDocs* result = readerTermDocs[i];
+ if (result == NULL){
+ readerTermDocs[i] = termDocs(subReaders[i]);
+ result = readerTermDocs[i];
+ }
+ result->seek(term);
+
+ return result;
+}
+
+
+MultiTermEnum::MultiTermEnum(
+ IndexReader** subReaders, const int32_t *starts, const Term* t){
+//Func - Constructor
+// Opens all enumerations of all readers
+//Pre - readers != NULL and contains an array of IndexReader instances each responsible for
+// reading a single segment
+// subReadersLength >= 0 and represents the number of readers in the readers array
+// starts is an array of
+//Post - An instance of has been created
+
+//Pre - if readers is NULL then subReadersLength must be 0 else if readers != NULL then subReadersLength > 0
+// s != NULL
+//Post - The instance has been created
+
+ int32_t subReadersLength = 0;
+ if ( subReaders != NULL ){
+ while ( subReaders[subReadersLength] != NULL )
+ subReadersLength++;
+ }
+ CND_PRECONDITION(starts != NULL,"starts is NULL");
+
+ //Temporary variables
+ IndexReader* reader = NULL;
+ TermEnum* termEnum = NULL;
+ SegmentMergeInfo* smi = NULL;
+ _docFreq = 0;
+ _term = NULL;
+ queue = _CLNEW SegmentMergeQueue(subReadersLength);
+
+ CND_CONDITION (queue != NULL, "Could not allocate memory for queue");
+
+ //iterate through all the readers
+ for ( int32_t i=0;i<subReadersLength;i++ ) {
+ //Get the i-th reader
+ reader = subReaders[i];
+
+ //Check if the enumeration must start from term t
+ if (t != NULL) {
+ //termEnum is an enumeration of terms starting at or after the named term t
+ termEnum = reader->terms(t);
+ }else{
+ //termEnum is an enumeration of all the Terms and TermInfos in the set.
+ termEnum = reader->terms();
+ }
+
+ //Instantiate an new SegmentMerginfo
+ smi = _CLNEW SegmentMergeInfo(starts[i], termEnum, reader);
+
+ // Note that in the call termEnum->getTerm(false) below false is required because
+ // otherwise a reference is leaked. By passing false getTerm is
+ // ordered to return an unowned reference instead. (Credits for DSR)
+ if (t == NULL ? smi->next() : termEnum->term(false) != NULL){
+ // initialize queue
+ queue->put(smi);
+ } else{
+ //Close the SegmentMergeInfo
+ smi->close();
+ //And have it deleted
+ _CLDELETE(smi);
+ }
+ }
+
+ //Check if the queue has elements
+ if (t != NULL && queue->size() > 0) {
+ next();
+ }
+}
+
+MultiTermEnum::~MultiTermEnum(){
+//Func - Destructor
+//Pre - true
+//Post - All the resource have been freed and the instance has been deleted
+
+ //Close the enumeration
+ close();
+
+ //Delete the queue
+ _CLDELETE(queue);
+}
+
+bool MultiTermEnum::next(){
+//Func - Move the current term to the next in the set of enumerations
+//Pre - true
+//Post - Returns true if term has been moved to the next in the set of enumerations
+// Returns false if this was not possible
+
+ SegmentMergeInfo* top = queue->top();
+ if (top == NULL) {
+ _CLDECDELETE(_term);
+ _term = NULL;
+ return false;
+ }
+
+ //The getTerm method requires the client programmer to indicate whether he
+ // owns the returned reference, so we can discard ours
+ // right away.
+ _CLDECDELETE(_term);
+
+ //Assign term the term of top and make sure the reference counter is increased
+ _term = _CL_POINTER(top->term);
+ _docFreq = 0;
+
+ //Find the next term
+ while (top != NULL && _term->compareTo(top->term) == 0) {
+ //don't delete, this is the top
+ queue->pop();
+ // increment freq
+ _docFreq += top->termEnum->docFreq();
+ if (top->next()){
+ // restore queue
+ queue->put(top);
+ }else{
+ // done with a segment
+ top->close();
+ _CLDELETE(top);
+ }
+ top = queue->top();
+ }
+
+ return true;
+}
+
+
+Term* MultiTermEnum::term() {
+//Func - Returns the current term of the set of enumerations
+//Pre - pointer is true or false and indicates if the reference counter
+// of term must be increased or not
+// next() must have been called once!
+//Post - pointer = true -> term has been returned with an increased reference counter
+// pointer = false -> term has been returned
+
+ return _CL_POINTER(_term);
+}
+
+Term* MultiTermEnum::term(bool pointer) {
+ if ( pointer )
+ return _CL_POINTER(_term);
+ else
+ return _term;
+}
+
+int32_t MultiTermEnum::docFreq() const {
+//Func - Returns the document frequency of the current term in the set
+//Pre - termInfo != NULL
+// next() must have been called once
+//Post - The document frequency of the current enumerated term has been returned
+
+ return _docFreq;
+}
+
+
+void MultiTermEnum::close() {
+//Func - Closes the set of enumerations in the queue
+//Pre - queue holds a valid reference to a SegmentMergeQueue
+//Post - The queue has been closed all SegmentMergeInfo instance have been deleted by
+// the closing of the queue
+// term has been finalized and reset to NULL
+
+ // Needed when this enumeration hasn't actually been exhausted yet
+ _CLDECDELETE(_term);
+
+ //Close the queue This will destroy all SegmentMergeInfo instances!
+ queue->close();
+
+}
+
+
+
+
+
+MultiTermPositions::MultiTermPositions(IndexReader** r, const int32_t* s){
+//Func - Constructor
+//Pre - if r is NULL then rLen must be 0 else if r != NULL then rLen > 0
+// s != NULL
+//Post - The instance has been created
+
+ subReaders = r;
+ subReadersLength = 0;
+ if ( subReaders != NULL ){
+ while ( subReaders[subReadersLength] != NULL )
+ subReadersLength ++ ;
+ }
+
+ CND_PRECONDITION(s != NULL, "s is NULL");
+
+ starts = s;
+ base = 0;
+ pointer = 0;
+ current = NULL;
+ term = NULL;
+
+ readerTermDocs = NULL;
+
+ //Check if there are readers
+ if(subReaders != NULL && subReadersLength > 0){
+ readerTermDocs = (TermDocs**)_CL_NEWARRAY(SegmentTermPositions*,subReadersLength);
+
+ CND_CONDITION(readerTermDocs != NULL,"No memory could be allocated for readerTermDocs");
+
+ //Initialize the readerTermDocs pointer array
+ for ( int32_t i=0;i<subReadersLength;i++){
+ readerTermDocs[i]=NULL;
+ }
+ }
+}
+
+
+TermDocs* MultiTermPositions::__asTermDocs(){
+ return (TermDocs*) this;
+}
+TermPositions* MultiTermPositions::__asTermPositions(){
+ return (TermPositions*) this;
+}
+
+
+TermDocs* MultiTermPositions::termDocs(const IndexReader* reader) const {
+// Here in the MultiTermPositions class, we want this->current to always
+// be a SegmentTermPositions rather than merely a SegmentTermDocs.
+// To that end, we override the termDocs(IndexReader&) method to produce
+// a SegmentTermPositions via the underlying reader's termPositions method
+// rather merely producing a SegmentTermDocs via the reader's termDocs
+// method.
+
+ TermPositions* tp = reader->termPositions();
+ TermDocs* ret = tp->__asTermDocs();
+
+ CND_CONDITION(ret != NULL,
+ "Dynamic downcast in MultiTermPositions::termDocs from"
+ " TermPositions to TermDocs failed."
+ );
+ return ret;
+ }
+
+int32_t MultiTermPositions::nextPosition() {
+ //Func -
+ //Pre - current != NULL
+ //Post -
+ CND_PRECONDITION(current != NULL,"current is NULL");
+
+ TermPositions* curAsTP = current->__asTermPositions();
+
+ CND_CONDITION(curAsTP != NULL,
+ "Dynamic downcast in MultiTermPositions::nextPosition from"
+ " SegmentTermDocs to TermPositions failed."
+ )
+ return curAsTP->nextPosition();
+}
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/MultiReader.h b/3rdparty/clucene/src/CLucene/index/MultiReader.h
new file mode 100644
index 000000000..1d76814e1
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/MultiReader.h
@@ -0,0 +1,202 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_index_MultiReader
+#define _lucene_index_MultiReader
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "SegmentHeader.h"
+#include "IndexReader.h"
+#include "CLucene/document/Document.h"
+#include "Terms.h"
+#include "SegmentMergeQueue.h"
+
+CL_NS_DEF(index)
+
+/** An IndexReader which reads multiple indexes, appending their content.
+*/
+class MultiTermDocs:public virtual TermDocs {
+private:
+protected:
+ TermDocs** readerTermDocs;
+
+ IndexReader** subReaders;
+ int32_t subReadersLength;
+ const int32_t* starts;
+ Term* term;
+
+ int32_t base;
+ int32_t pointer;
+
+ TermDocs* current; // == segTermDocs[pointer]
+public:
+ MultiTermDocs();
+ MultiTermDocs(IndexReader** subReaders, const int32_t* s);
+ virtual ~MultiTermDocs();
+
+ int32_t doc() const;
+ int32_t freq() const;
+
+ void seek(TermEnum* termEnum);
+ void seek(Term* tterm);
+ bool next();
+
+ /** Optimized implementation. */
+ int32_t read(int32_t* docs, int32_t* freqs, int32_t length);
+
+ /** As yet unoptimized implementation. */
+ bool skipTo(const int32_t target);
+
+ void close();
+
+ virtual TermPositions* __asTermPositions();
+protected:
+ virtual TermDocs* termDocs(const IndexReader* reader) const;
+private:
+ TermDocs* termDocs(const int32_t i) const;
+
+};
+
+
+//MultiTermEnum represents the enumeration of all terms of all readers
+class MultiTermEnum:public TermEnum {
+private:
+ SegmentMergeQueue* queue;
+
+ Term* _term;
+ int32_t _docFreq;
+public:
+ //Constructor
+ //Opens all enumerations of all readers
+ MultiTermEnum(IndexReader** subReaders, const int32_t* starts, const Term* t);
+
+ //Destructor
+ ~MultiTermEnum();
+
+ //Move the current term to the next in the set of enumerations
+ bool next();
+
+ //Returns a pointer to the current term of the set of enumerations
+ Term* term();
+ Term* term(bool pointer);
+
+ //Returns the document frequency of the current term in the set
+ int32_t docFreq() const;
+
+ //Closes the set of enumerations in the queue
+ void close();
+
+
+ const char* getObjectName(){ return MultiTermEnum::getClassName(); }
+ static const char* getClassName(){ return "MultiTermEnum"; }
+};
+
+
+class MultiTermPositions:public MultiTermDocs,public TermPositions {
+public:
+ MultiTermPositions(IndexReader** subReaders, const int32_t* s);
+ ~MultiTermPositions() {};
+ int32_t nextPosition();
+
+
+ virtual TermDocs* __asTermDocs();
+ virtual TermPositions* __asTermPositions();
+protected:
+ TermDocs* termDocs(const IndexReader* reader) const;
+};
+
+
+class MultiReader:public IndexReader{
+private:
+ bool _hasDeletions;
+ IndexReader** subReaders;
+ int32_t subReadersLength;
+ int32_t* starts; // 1st docno for each segment
+
+ CL_NS(util)::CLHashtable<const TCHAR*,uint8_t*,
+ CL_NS(util)::Compare::TChar,
+ CL_NS(util)::Equals::TChar,
+ CL_NS(util)::Deletor::tcArray,
+ CL_NS(util)::Deletor::Array<uint8_t> > normsCache;
+ int32_t _maxDoc;
+ int32_t _numDocs;
+ void initialize(IndexReader** subReaders);
+
+ int32_t readerIndex(const int32_t n) const;
+
+ bool hasNorms(const TCHAR* field);
+ uint8_t* ones;
+ uint8_t* fakeNorms();
+protected:
+ void doSetNorm(int32_t n, const TCHAR* field, uint8_t value);
+ void doUndeleteAll();
+ void doCommit();
+ // synchronized
+ void doClose();
+
+ // synchronized
+ void doDelete(const int32_t n);
+public:
+ /** Construct reading the named set of readers. */
+ MultiReader(CL_NS(store)::Directory* directory, SegmentInfos* sis, IndexReader** subReaders);
+
+ /**
+ * <p>Construct a MultiReader aggregating the named set of (sub)readers.
+ * Directory locking for delete, undeleteAll, and setNorm operations is
+ * left to the subreaders. </p>
+ * <p>Note that all subreaders are closed if this Multireader is closed.</p>
+ * @param subReaders set of (sub)readers
+ * @throws IOException
+ */
+ MultiReader(IndexReader** subReaders);
+
+ ~MultiReader();
+
+ /** Return an array of term frequency vectors for the specified document.
+ * The array contains a vector for each vectorized field in the document.
+ * Each vector vector contains term numbers and frequencies for all terms
+ * in a given vectorized field.
+ * If no such fields existed, the method returns null.
+ */
+ bool getTermFreqVectors(int32_t n, Array<TermFreqVector*>& result);
+ TermFreqVector* getTermFreqVector(int32_t n, const TCHAR* field);
+
+
+ // synchronized
+ int32_t numDocs();
+
+ int32_t maxDoc() const;
+
+ bool document(int32_t n, CL_NS(document)::Document* doc);
+
+ bool isDeleted(const int32_t n);
+ bool hasDeletions() const{ return _hasDeletions; }
+
+ // synchronized
+ uint8_t* norms(const TCHAR* field);
+ void norms(const TCHAR* field, uint8_t* result);
+
+ TermEnum* terms() const;
+ TermEnum* terms(const Term* term) const;
+
+ //Returns the document frequency of the current term in the set
+ int32_t docFreq(const Term* t=NULL) const;
+ TermDocs* termDocs() const;
+ TermPositions* termPositions() const;
+
+
+ /**
+ * @see IndexReader#getFieldNames(IndexReader.FieldOption fldOption)
+ */
+ void getFieldNames(FieldOption fldOption, CL_NS(util)::StringArrayWithDeletor& retarray);
+};
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentHeader.h b/3rdparty/clucene/src/CLucene/index/SegmentHeader.h
new file mode 100644
index 000000000..00b08991d
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentHeader.h
@@ -0,0 +1,314 @@
+/*
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_SegmentHeader_
+#define _lucene_index_SegmentHeader_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include "SegmentInfos.h"
+#include "CLucene/util/BitSet.h"
+#include "CLucene/util/VoidMap.h"
+#include "Term.h"
+#include "FieldInfos.h"
+#include "FieldsReader.h"
+#include "IndexReader.h"
+#include "TermInfosReader.h"
+#include "CompoundFile.h"
+#include "CLucene/util/ThreadLocal.h"
+
+CL_NS_DEF(index)
+
+class SegmentReader;
+
+class SegmentTermDocs : public virtual TermDocs
+{
+ int32_t _doc;
+ int32_t skipInterval;
+ int32_t numSkips;
+ int32_t skipCount;
+ CL_NS(store)::IndexInput* skipStream;
+ int32_t skipDoc;
+ int64_t freqPointer;
+ int64_t proxPointer;
+ int64_t skipPointer;
+ bool haveSkipped;
+
+protected:
+ // SegmentReader parent
+ const SegmentReader* parent;
+ CL_NS(store)::IndexInput* freqStream;
+ int32_t count;
+ int32_t df;
+ int32_t _freq;
+ CL_NS(util)::BitSet* deletedDocs;
+public:
+ virtual ~SegmentTermDocs();
+
+ virtual void seek(TermEnum* termEnum);
+ virtual void seek(Term* term);
+ virtual void seek(const TermInfo* ti);
+
+ virtual void close();
+ virtual int32_t doc()const;
+ virtual int32_t freq()const;
+
+ virtual bool next();
+
+ /** Optimized implementation. */
+ virtual int32_t read(int32_t* docs, int32_t* freqs, int32_t length);
+
+ /** Optimized implementation. */
+ virtual bool skipTo(const int32_t target);
+
+ virtual TermPositions* __asTermPositions();
+
+ // \param Parent must be a segment reader
+ SegmentTermDocs( const SegmentReader* Parent);
+protected:
+ virtual void skippingDoc(){}
+ virtual void skipProx(int64_t proxPointer){}
+};
+
+
+class SegmentTermPositions : public SegmentTermDocs, public TermPositions
+{
+private:
+ CL_NS(store)::IndexInput* proxStream;
+ int32_t proxCount;
+ int32_t position;
+
+public:
+ // \param Parent must be a segment reader
+ SegmentTermPositions(const SegmentReader* Parent);
+ ~SegmentTermPositions();
+
+ void seek(const TermInfo* ti);
+ void close();
+ int32_t nextPosition();
+ bool next();
+ int32_t read(int32_t* docs, int32_t* freqs, int32_t length);
+ virtual TermDocs* __asTermDocs();
+ virtual TermPositions* __asTermPositions();
+
+ //resolve SegmentTermDocs/TermPositions ambiguity
+ void seek(Term* term){ SegmentTermDocs::seek(term); }
+ void seek(TermEnum* termEnum){ SegmentTermDocs::seek(termEnum); }
+ int32_t doc() const{ return SegmentTermDocs::doc(); }
+ int32_t freq() const{ return SegmentTermDocs::freq(); }
+ bool skipTo(const int32_t target){ return SegmentTermDocs::skipTo(target); }
+
+protected:
+ void skippingDoc();
+ /** Called by super.skipTo(). */
+ void skipProx(int64_t proxPointer);
+};
+
+// An IndexReader responsible for reading 1 segment of an index
+class SegmentReader : public IndexReader
+{
+ /**
+ * The class Norm represents the normalizations for a field.
+ * These normalizations are read from an IndexInput in into an array of bytes called bytes
+ */
+ class Norm : LUCENE_BASE
+ {
+ int32_t number;
+ SegmentReader* reader;
+ QString segment; // segment name
+
+ public:
+ CL_NS(store)::IndexInput* in;
+ uint8_t* bytes;
+ bool dirty;
+ //Constructor
+ Norm(CL_NS(store)::IndexInput* instrm, int32_t number,
+ SegmentReader* reader, const QString& segment);
+ //Destructor
+ ~Norm();
+
+ void reWrite();
+ };
+ friend class SegmentReader::Norm;
+
+ //Holds the name of the segment that is being read
+ QString segment;
+
+ //Indicates if there are documents marked as deleted
+ bool deletedDocsDirty;
+ bool normsDirty;
+ bool undeleteAll;
+
+ //Holds all norms for all fields in the segment
+ typedef CL_NS(util)::CLHashtable<const TCHAR*,
+ Norm*,CL_NS(util)::Compare::TChar, CL_NS(util)::Equals::TChar> NormsType;
+ NormsType _norms;
+
+ uint8_t* ones;
+ uint8_t* fakeNorms();
+
+ // Compound File Reader when based on a compound file segment
+ CompoundFileReader* cfsReader;
+ // Reads the Field Info file
+ FieldsReader* fieldsReader;
+ TermVectorsReader* termVectorsReaderOrig;
+ CL_NS(util)::ThreadLocal<TermVectorsReader*,
+ CL_NS(util)::Deletor::Object<TermVectorsReader> >termVectorsLocal;
+
+ void initialize(SegmentInfo* si);
+
+ // Create a clone from the initial TermVectorsReader and store it in the
+ // ThreadLocal. @return TermVectorsReader
+ TermVectorsReader* getTermVectorsReader();
+
+protected:
+ // Marks document docNum as deleted
+ void doDelete(const int32_t docNum);
+ void doUndeleteAll();
+ void doCommit();
+ void doSetNorm(int32_t doc, const TCHAR* field, uint8_t value);
+
+ // can return null if norms aren't stored
+ uint8_t* getNorms(const TCHAR* field);
+
+public:
+ /**
+ Func - Constructor.
+ Opens all files of a segment
+ .fnm -> Field Info File
+ Field names are stored in the field info file, with suffix .fnm.
+ .frq -> Frequency File
+ The .frq file contains the lists of documents which contain
+ each term, along with the frequency of the term in that document.
+ .prx -> Prox File
+ The prox file contains the lists of positions that each term occurs
+ at within documents.
+ .tis -> Term Info File
+ This file is sorted by Term. Terms are ordered first lexicographically
+ by the term's field name, and within that lexicographically by the term's text.
+ .del -> Deletion File
+ The .del file is optional, and only exists when a segment contains deletions
+ .f[0-9]* -> Norm File
+ Contains s, for each document, a byte that encodes a value that is
+ multiplied into the score for hits on that field:
+ */
+ SegmentReader(SegmentInfo* si);
+
+ SegmentReader(SegmentInfos* sis, SegmentInfo* si);
+ // Destructor.
+ virtual ~SegmentReader();
+
+ // Closes all streams to the files of a single segment
+ void doClose();
+
+ // Checks if a segment managed by SegmentInfo si has deletions
+ static bool hasDeletions(const SegmentInfo* si);
+ bool hasDeletions() const;
+ bool hasNorms(const TCHAR* field) const;
+
+ // Returns all file names managed by this SegmentReader
+ void files(QStringList& retarray);
+ // Returns an enumeration of all the Terms and TermInfos in the set.
+ TermEnum* terms() const;
+ // Returns an enumeration of terms starting at or after the named term t
+ TermEnum* terms(const Term* t) const;
+
+ // Gets the document identified by n
+ bool document(int32_t n, CL_NS(document)::Document* doc);
+
+ // Checks if the n-th document has been marked deleted
+ bool isDeleted(const int32_t n);
+
+ // Returns an unpositioned TermDocs enumerator.
+ TermDocs* termDocs() const;
+ // Returns an unpositioned TermPositions enumerator.
+ TermPositions* termPositions() const;
+
+ // Returns the number of documents which contain the term t
+ int32_t docFreq(const Term* t) const;
+
+ // Returns the actual number of documents in the segment
+ int32_t numDocs();
+ // Returns the number of all the documents in the segment including the
+ // ones that have been marked deleted
+ int32_t maxDoc() const;
+
+ // Returns the bytes array that holds the norms of a named field.
+ // Returns fake norms if norms aren't available
+ uint8_t* norms(const TCHAR* field);
+
+ // Reads the Norms for field from disk
+ void norms(const TCHAR* field, uint8_t* bytes);
+
+ // concatenating segment with ext and x
+ QString SegmentName(const QString& ext, const int32_t x = -1);
+ // Creates a filename in buffer by concatenating segment with ext and x
+ void SegmentName(QString& buffer, int32_t bufferLen, const QString& ext,
+ const int32_t x = -1);
+
+ /**
+ * @see IndexReader#getFieldNames(IndexReader.FieldOption fldOption)
+ */
+ void getFieldNames(FieldOption fldOption, CL_NS(util)::StringArrayWithDeletor& retarray);
+
+ static bool usesCompoundFile(SegmentInfo* si);
+
+ /** Return a term frequency vector for the specified document and field. The
+ * vector returned contains term numbers and frequencies for all terms in
+ * the specified field of this document, if the field had storeTermVector
+ * flag set. If the flag was not set, the method returns null.
+ * @throws IOException
+ */
+ TermFreqVector* getTermFreqVector(int32_t docNumber, const TCHAR* field = NULL);
+
+ /** Return an array of term frequency vectors for the specified document.
+ * The array contains a vector for each vectorized field in the document.
+ * Each vector vector contains term numbers and frequencies for all terms
+ * in a given vectorized field.
+ * If no such fields existed, the method returns null.
+ * @throws IOException
+ */
+ bool getTermFreqVectors(int32_t docNumber, Array<TermFreqVector*>& result);
+
+private:
+ //Open all norms files for all fields
+ void openNorms(CL_NS(store)::Directory* cfsDir);
+ //Closes all norms files
+ void closeNorms();
+
+ // a bitVector that manages which documents have been deleted
+ CL_NS(util)::BitSet* deletedDocs;
+ // an IndexInput to the frequency file
+ CL_NS(store)::IndexInput* freqStream;
+ // For reading the fieldInfos file
+ FieldInfos* fieldInfos;
+ // For reading the Term Dictionary .tis file
+ TermInfosReader* tis;
+ // an IndexInput to the prox file
+ CL_NS(store)::IndexInput* proxStream;
+
+ static bool hasSeparateNorms(SegmentInfo* si);
+ static uint8_t* createFakeNorms(int32_t size);
+
+ // allow various classes to access the internals of this. this allows us
+ // to have a more tight idea of the package
+ friend class IndexReader;
+ friend class IndexWriter;
+ friend class SegmentTermDocs;
+ friend class SegmentTermPositions;
+ friend class MultiReader;
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp b/3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp
new file mode 100644
index 000000000..f62c4061a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#include "CLucene/StdHeader.h"
+#include "SegmentInfos.h"
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/util/Misc.h"
+
+CL_NS_USE(store)
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+SegmentInfo::SegmentInfo(const QString& Name, const int32_t DocCount,
+ CL_NS(store)::Directory* Dir)
+ : docCount(DocCount)
+ , dir(Dir)
+{
+ //Func - Constructor. Initialises SegmentInfo.
+ //Pre - Name holds the unique name in the directory Dir
+ // DocCount holds the number of documents in the segment
+ // Dir holds the Directory where the segment resides
+ //Post - The instance has been created. name contains the duplicated string
+ // Name. docCount = DocCount and dir references Dir
+ name = Name;
+}
+
+SegmentInfo::~SegmentInfo()
+{
+}
+
+SegmentInfos::SegmentInfos(bool _deleteMembers)
+ : deleteMembers(_deleteMembers)
+{
+ //Func - Constructor
+ //Pre - deleteMembers indicates if the instance to be created must delete
+ // all SegmentInfo instances it manages when the instance is destroyed
+ // or not true -> must delete, false may not delete
+ //Post - An instance of SegmentInfos has been created.
+
+ //initialize counter to 0
+ counter = 0;
+ version = Misc::currentTimeMillis();
+}
+
+SegmentInfos::~SegmentInfos()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed. Depending on the constructor used
+ // the SegmentInfo instances that this instance managed have been
+ // deleted or not.
+
+ if (deleteMembers) {
+ segmentInfosType::iterator it;
+ for (it = infos.begin(); it != infos.end(); ++it)
+ _CLLDELETE(*it);
+ }
+ //Clear the list of SegmentInfo instances - make sure everything is deleted
+ infos.clear();
+}
+
+SegmentInfo* SegmentInfos::info(int32_t i) const
+{
+ //Func - Returns a reference to the i-th SegmentInfo in the list.
+ //Pre - i >= 0
+ //Post - A reference to the i-th SegmentInfo instance has been returned
+
+ CND_PRECONDITION(i >= 0, "i contains negative number");
+
+ //Get the i-th SegmentInfo instance
+ SegmentInfo *ret = infos.value(i, 0);
+
+ //Condition check to see if the i-th SegmentInfo has been retrieved
+ CND_CONDITION(ret != NULL, "No SegmentInfo instance found");
+
+ return ret;
+}
+
+void SegmentInfos::clearto(size_t _min)
+{
+ // Make sure we actually need to remove
+ if (infos.size() > _min) {
+ segmentInfosType::iterator itr;
+ segmentInfosType::iterator eitr = infos.end();
+ segmentInfosType::iterator bitr = infos.begin() + _min;
+
+ for(itr = bitr; itr != eitr; ++itr)
+ _CLLDELETE((*itr));
+ infos.erase(bitr, eitr);
+ }
+}
+
+void SegmentInfos::add(SegmentInfo* info)
+{
+ infos.push_back(info);
+}
+
+int32_t SegmentInfos::size() const
+{
+ return infos.size();
+}
+
+void SegmentInfos::read(Directory* directory)
+{
+ //Func - Reads segments file that resides in directory.
+ //Pre - directory contains a valid reference
+ //Post - The segments file has been read and for each segment found
+ // a SegmentsInfo intance has been created and stored.
+
+ //Open an IndexInput to the segments file and check if valid
+ IndexInput* input = directory->openInput(QLatin1String("segments"));
+ if (input) {
+ try {
+ int32_t format = input->readInt();
+ // file contains explicit format info
+ if (format < 0) {
+ // check that it is a format we can understand
+ if (format < FORMAT) {
+ TCHAR err[30];
+ _sntprintf(err, 30, _T("Unknown format version: %d"), format);
+ _CLTHROWT(CL_ERR_Runtime, err);
+ }
+ // read version
+ version = input->readLong();
+ // read counter
+ counter = input->readInt();
+ } else {
+ // file is in old format without explicit format info
+ counter = format;
+ }
+
+ //Temporary variable for storing the name of the segment
+ char aname[CL_MAX_PATH] = { 0 };
+ TCHAR tname[CL_MAX_PATH] = { 0 };
+
+ //read segmentInfos
+ for (int32_t i = input->readInt(); i > 0; --i) {
+ // read the name of the segment
+ input->readString(tname, CL_MAX_PATH);
+ STRCPY_TtoA(aname, tname, CL_MAX_PATH);
+
+ //Instantiate a new SegmentInfo Instance
+ SegmentInfo* si = _CLNEW SegmentInfo(QLatin1String(aname),
+ input->readInt(), directory);
+
+ //Condition check to see if si points to an instance
+ CND_CONDITION(si != NULL, "Memory allocation for si failed") ;
+
+ //store SegmentInfo si
+ infos.push_back(si);
+ }
+
+ if (format >= 0) {
+ // in old format the version number may be at the end of the file
+ if (input->getFilePointer() >= input->length()) {
+ // old file format without version number
+ version = Misc::currentTimeMillis();
+ } else {
+ // read version
+ version = input->readLong();
+ }
+ }
+ } _CLFINALLY (
+ //destroy the inputStream input. The destructor of IndexInput will
+ //also close the Inputstream input
+ _CLDELETE(input);
+ );
+ }
+}
+
+void SegmentInfos::write(Directory* directory)
+{
+ //Func - Writes a new segments file based upon the SegmentInfo instances it manages
+ //Pre - directory is a valid reference to a Directory
+ //Post - The new segment has been written to disk
+
+ //Open an IndexOutput to the segments file and check if valid
+ IndexOutput* output = directory->createOutput(QLatin1String("segments.new"));
+ if (output) {
+ try {
+ // write FORMAT
+ output->writeInt(FORMAT);
+ // every write changes the index
+ output->writeLong(++version);
+ // Write the counter
+ output->writeInt(counter);
+
+ // Write the number of SegmentInfo Instances which is equal to the number
+ // of segments in directory as each SegmentInfo manages a single segment
+ output->writeInt(infos.size());
+
+ //temporary value for wide segment name
+ TCHAR tname[CL_MAX_PATH];
+
+ //Iterate through all the SegmentInfo instances
+ for (uint32_t i = 0; i < infos.size(); ++i) {
+ //Retrieve the SegmentInfo
+ SegmentInfo *si = infos.value(i, 0);
+ //Condition check to see if si has been retrieved
+ CND_CONDITION(si != NULL, "No SegmentInfo instance found");
+
+ //Write the name of the current segment
+ int32_t count = si->name.toWCharArray(tname);
+ tname[count] = '\0';
+ output->writeString(tname, _tcslen(tname));
+
+ //Write the number of documents in the segment
+ output->writeInt(si->docCount);
+ }
+ } _CLFINALLY(
+ output->close();
+ _CLDELETE(output);
+ );
+
+ // install new segment info
+ directory->renameFile(QLatin1String("segments.new"),
+ QLatin1String("segments"));
+ }
+}
+
+
+int64_t SegmentInfos::readCurrentVersion(Directory* directory)
+{
+ int32_t format = 0;
+ int64_t version = 0;
+ IndexInput* input = directory->openInput(QLatin1String("segments"));
+ try {
+ format = input->readInt();
+ if (format < 0){
+ if (format < FORMAT) {
+ TCHAR err[30];
+ _sntprintf(err, 30, _T("Unknown format version: %d"), format);
+ _CLTHROWT(CL_ERR_Runtime, err);
+ }
+ // read version
+ version = input->readLong();
+ }
+ } _CLFINALLY (
+ input->close();
+ _CLDELETE(input);
+ );
+
+ if (format < 0)
+ return version;
+
+ // We cannot be sure about the format of the file. Therefore we have to
+ // read the whole file and cannot simply seek to the version entry.
+ SegmentInfos segmentInfos;
+ segmentInfos.read(directory);
+ return segmentInfos.getVersion();
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentInfos.h b/3rdparty/clucene/src/CLucene/index/SegmentInfos.h
new file mode 100644
index 000000000..ce7183820
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentInfos.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#ifndef _lucene_index_SegmentInfos_
+#define _lucene_index_SegmentInfos_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+#include <QtCore/QVector>
+
+#include "CLucene/store/Directory.h"
+
+CL_NS_DEF(index)
+
+class SegmentInfo : LUCENE_BASE
+{
+public:
+ SegmentInfo(const QString& Name, const int32_t DocCount,
+ CL_NS(store)::Directory* Dir);
+ ~SegmentInfo();
+
+ ///Gets the Directory where the segment resides
+ CL_NS(store)::Directory* getDir() const { return dir; }
+
+ //Unique name in directory dir
+ QString name;
+
+ //Number of docs in the segment
+ const int32_t docCount;
+
+private:
+ //Directory where the segment resides
+ CL_NS(store)::Directory* dir;
+};
+
+typedef QVector<SegmentInfo*> segmentInfosType;
+
+//SegmentInfos manages a list of SegmentInfo instances
+//Each SegmentInfo contains information about a segment in a directory.
+//
+//The active segments in the index are stored in the segment info file.
+//An index only has a single file in this format, and it is named "segments".
+//This lists each segment by name, and also contains the size of each segment.
+//The format of the file segments is defined as follows:
+//
+// SegCount
+//Segments --> SegCount, <SegName, SegSize>
+//
+//SegCount, SegSize --> UInt32
+//
+//SegName --> String
+//
+//SegName is the name of the segment, and is used as the file name prefix
+//for all of the files that compose the segment's index.
+//
+//SegSize is the number of documents contained in the segment index.
+//
+//Note:
+//At http://jakarta.apache.org/lucene/docs/fileformats.html the definition
+//of all file formats can be found. Note that java lucene currently
+//defines Segments as follows:
+//
+//Segments --> Format, Version, SegCount, <SegName, SegSize>SegCount
+//
+//Format, SegCount, SegSize --> UInt32
+//
+//Format and Version have not been implemented yet
+class SegmentInfos : LUCENE_BASE
+{
+public:
+ SegmentInfos(bool deleteMembers = true);
+ ~SegmentInfos();
+
+ //delete and clears objects 'from' from to 'to'
+ void clearto(size_t to);
+
+ //count of segment infos
+ int32_t size() const;
+
+ //add a segment info
+ void add(SegmentInfo* info);
+
+ //Returns a reference to the i-th SegmentInfo in the list.
+ SegmentInfo* info(int32_t i) const;
+
+ // version number when this SegmentInfos was generated.
+ int64_t getVersion() const { return version; }
+
+ static int64_t readCurrentVersion(CL_NS(store)::Directory* directory);
+
+ //Reads segments file that resides in directory
+ void read(CL_NS(store)::Directory* directory);
+
+ //Writes a new segments file based upon the SegmentInfo instances it manages
+ void write(CL_NS(store)::Directory* directory);
+
+private:
+ // The file format version, a negative number.
+ // Works since counter, the old 1st entry, is always >= 0
+ LUCENE_STATIC_CONSTANT(int32_t, FORMAT = -1);
+
+ // counts how often the index has been changed by adding or deleting docs.
+ // starting with the current time in milliseconds forces to create unique
+ // version numbers.
+ int64_t version;
+
+ segmentInfosType infos;
+
+ // used to name new segments
+ int32_t counter;
+
+ // allow IndexWriter to use counter
+ friend class IndexWriter;
+
+ bool deleteMembers;
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentMergeInfo.cpp b/3rdparty/clucene/src/CLucene/index/SegmentMergeInfo.cpp
new file mode 100644
index 000000000..85ac784ad
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentMergeInfo.cpp
@@ -0,0 +1,104 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "SegmentMergeInfo.h"
+
+#include "SegmentTermEnum.h"
+#include "SegmentHeader.h"
+
+CL_NS_DEF(index)
+
+SegmentMergeInfo::SegmentMergeInfo(const int32_t b, TermEnum* te, IndexReader* r):
+ reader(r),termEnum(te),base(b), docMap(NULL) {
+//Func - Constructor
+//Pre - b >= 0
+// te contains a valid reference to a SegmentTermEnum instance
+// r contains a valid reference to a SegmentReader instance
+//Post - The instance has been created
+
+ CND_PRECONDITION(b >= 0, "b is a negative number");
+
+ postings=NULL;
+ term = te->term();
+}
+
+SegmentMergeInfo::~SegmentMergeInfo(){
+//Func - Destructor
+//Pre - true
+//Post - The instance has been destroyed
+
+ close();
+}
+
+int32_t* SegmentMergeInfo::getDocMap(){
+ if ( docMap == NULL ){
+ // build array which maps document numbers around deletions
+ if (reader->hasDeletions()) {
+ //Get the total number of documents managed by the reader including the deleted ones
+ int32_t maxDoc = reader->maxDoc();
+ //Create a map for all documents
+ docMap = _CL_NEWARRAY(int32_t,maxDoc);
+ int32_t j = 0;
+ //Iterate through all the document numbers
+ for (int32_t i = 0; i < maxDoc; i++) {
+ //Check if document i is marked deleted
+ if (reader->isDeleted(i)){
+ //Document i has not been marked deleted so assign -1
+ docMap[i] = -1;
+ }else{
+ docMap[i] = j++;
+ }
+ }
+ }
+ }
+ return docMap;
+}
+
+TermPositions* SegmentMergeInfo::getPositions() {
+ if (postings == NULL) {
+ postings = reader->termPositions();
+ }
+ return postings;
+}
+
+
+bool SegmentMergeInfo::next() {
+//Func - Moves the current term of the enumeration termEnum to the next and term
+// points to this new current term
+//Pre - true
+//Post - Returns true if the term has been moved to the next otherwise false
+ if (termEnum->next()) {
+ _CLDECDELETE(term);
+ term = termEnum->term();
+ return true;
+ } else {
+ _CLDECDELETE(term); //TODO: test HighFreqTerms errors with this
+ term = NULL;
+ return false;
+ }
+}
+
+void SegmentMergeInfo::close() {
+//Func - Closes the the resources
+//Pre - true
+//Post - The resources have been closed
+
+ //First make sure posting has been closed
+ if ( postings != NULL ){
+ postings->close();
+ _CLVDELETE(postings); //todo: not a clucene object... should be
+ }
+
+ if ( termEnum != NULL ){
+ termEnum->close();
+ _CLDELETE(termEnum);
+ }
+ _CLDECDELETE(term);
+ _CLDELETE_ARRAY(docMap);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentMergeInfo.h b/3rdparty/clucene/src/CLucene/index/SegmentMergeInfo.h
new file mode 100644
index 000000000..7ffd46ade
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentMergeInfo.h
@@ -0,0 +1,47 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_index_SegmentMergeInfo_
+#define _lucene_index_SegmentMergeInfo_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "SegmentTermEnum.h"
+#include "SegmentHeader.h"
+
+CL_NS_DEF(index)
+class SegmentMergeInfo:LUCENE_BASE {
+ int32_t* docMap; // maps around deleted docs
+ TermPositions* postings;
+public:
+ TermEnum* termEnum;
+ Term* term;
+ int32_t base;
+ IndexReader* reader;
+
+ //Constructor
+ SegmentMergeInfo(const int32_t b, TermEnum* te, IndexReader* r);
+
+ //Destructor
+ ~SegmentMergeInfo();
+
+ //Moves the current term of the enumeration termEnum to the next and term
+ //points to this new current term
+ bool next();
+
+ //Closes the the resources
+ void close();
+
+ // maps around deleted docs
+ int32_t* getDocMap();
+
+ TermPositions* getPositions();
+};
+CL_NS_END
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentMergeQueue.cpp b/3rdparty/clucene/src/CLucene/index/SegmentMergeQueue.cpp
new file mode 100644
index 000000000..879781287
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentMergeQueue.cpp
@@ -0,0 +1,74 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "SegmentMergeQueue.h"
+
+#include "SegmentMergeInfo.h"
+CL_NS_DEF(index)
+
+
+ SegmentMergeQueue::SegmentMergeQueue(const int32_t size) {
+ //Func - Constructor
+ // Creates a queue of length size
+ //Pre - size >= 0
+ //Post - The queue has been created of length size
+
+ //BVK: bug. changed condition from size > 0 to size >= 0
+ //if size is 0, as it is when retrieving a TermEnum
+ //from an empty index this should this should not fail.
+ CND_PRECONDITION(size >= 0, "size is too small");
+
+ //Call the initialize method of its superclass. The boolean value passed here
+ //indicates that the superclass PriorityQueue takes the responsibility to have its elements deleted
+ //The destructor of SegmentMergInfo will make sure that each intstance it will be closed properly
+ //before it is deleted
+ initialize(size,true);
+ }
+
+ SegmentMergeQueue::~SegmentMergeQueue(){
+ //Func - Destructor
+ // Does nothing as its parent class will clean up everything
+ //Pre - true
+ //Post - true
+ close();
+ }
+
+ void SegmentMergeQueue::close() {
+ //Func - Closes and destroyes all SegmentMergeInfo Instances in the queue
+ //Pre - true
+ //post - All SegmentMergeInfo Instances in the queue have been closed and deleted
+ // The queue is now empty but can still be used
+
+ //call the clear method of the parent class PriorityQueue
+ clear();
+ }
+
+ bool SegmentMergeQueue::lessThan(SegmentMergeInfo* stiA, SegmentMergeInfo* stiB) {
+ //Func - Overloaded method that implements the lessThan operator for the parent class
+ // This method is used by the parent class Priority queue to reorder its internal
+ // data structures. This implementation check if stiA is less than the current term of stiB.
+ //Pre - stiA != NULL
+ // stiB != NULL
+ //Post - true is returned if stiA < stiB otherwise false
+
+ CND_PRECONDITION(stiA != NULL, "stiA is NULL");
+ CND_PRECONDITION(stiB != NULL, "stiB is NULL");
+
+ //Compare the two terms
+ int32_t comparison = stiA->term->compareTo(stiB->term);
+ //Check if they match
+ if (comparison == 0){ //todo: can we do an optimized compare here? compare using equals, then compare properly?
+ //If the match check if the base of stiA is smaller than the base of stiB
+ //Note that different bases means that the terms of stiA an stiB ly in different segments
+ return stiA->base < stiB->base;
+ }else{
+ //Terms didn't match so return the difference in positions
+ return comparison < 0;
+ }
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentMergeQueue.h b/3rdparty/clucene/src/CLucene/index/SegmentMergeQueue.h
new file mode 100644
index 000000000..faa690252
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentMergeQueue.h
@@ -0,0 +1,38 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_index_SegmentMergeQueue_
+#define _lucene_index_SegmentMergeQueue_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/PriorityQueue.h"
+#include "SegmentMergeInfo.h"
+
+CL_NS_DEF(index)
+ class SegmentMergeQueue :public CL_NS(util)::PriorityQueue<SegmentMergeInfo*,CL_NS(util)::Deletor::Object<SegmentMergeInfo> > {
+ public:
+ //Constructor
+ //Creates a queue of length size
+ SegmentMergeQueue(const int32_t size);
+
+ //Destructor
+ //Does nothing as its parent class will clean up everything
+ ~SegmentMergeQueue();
+
+ //Closes and destroyes all SegmentMergeInfo Instances in the queue
+ void close();
+ protected:
+ //Overloaded method that implements the lessThan operator for the parent class
+ //This method is used by the parent class Priority queue to reorder its internal
+ //data structures. This implementation check if stiA is less than the current term of stiB.
+ bool lessThan(SegmentMergeInfo* stiA, SegmentMergeInfo* stiB);
+
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentMerger.cpp b/3rdparty/clucene/src/CLucene/index/SegmentMerger.cpp
new file mode 100644
index 000000000..40814da0c
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentMerger.cpp
@@ -0,0 +1,723 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "SegmentMerger.h"
+
+CL_NS_USE(util)
+CL_NS_USE(document)
+CL_NS_USE(store)
+CL_NS_DEF(index)
+
+// File extensions of old-style index files
+int COMPOUND_EXTENSIONS_LENGTH = 7;
+const char* COMPOUND_EXTENSIONS = "fnm\0" "frq\0" "prx\0" "fdx\0" "fdt\0" "tii\0" "tis\0";
+
+int VECTOR_EXTENSIONS_LENGTH = 3;
+const char* VECTOR_EXTENSIONS = "tvx\0" "tvd\0" "tvf\0";
+
+SegmentMerger::SegmentMerger(IndexWriter* writer, const QString& name)
+{
+ //Func - Constructor
+ //Pre - dir holds a valid reference to a Directory
+ // name != NULL
+ //Post - Instance has been created
+
+ CND_PRECONDITION(!name.isEmpty(), "name is NULL");
+
+ freqOutput = NULL;
+ proxOutput = NULL;
+ termInfosWriter = NULL;
+ queue = NULL;
+ fieldInfos = NULL;
+ useCompoundFile = writer->getUseCompoundFile();
+ skipBuffer = _CLNEW CL_NS(store)::RAMIndexOutput();
+
+ segment = name;
+ directory = writer->getDirectory();
+ termIndexInterval = writer->getTermIndexInterval();
+
+ lastSkipDoc=0;
+ lastSkipFreqPointer=0;
+ lastSkipProxPointer=0;
+ skipInterval=0;
+}
+
+SegmentMerger::~SegmentMerger()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ //Clear the readers set
+ readers.clear();
+
+ //Delete field Infos
+ _CLDELETE(fieldInfos);
+ //Close and destroy the IndexOutput to the Frequency File
+ if (freqOutput != NULL) {
+ freqOutput->close();
+ _CLDELETE(freqOutput);
+ }
+ //Close and destroy the IndexOutput to the Prox File
+ if (proxOutput != NULL) {
+ proxOutput->close();
+ _CLDELETE(proxOutput);
+ }
+ //Close and destroy the termInfosWriter
+ if (termInfosWriter != NULL) {
+ termInfosWriter->close();
+ _CLDELETE(termInfosWriter);
+ }
+ //Close and destroy the queue
+ if (queue != NULL) {
+ queue->close();
+ _CLDELETE(queue);
+ }
+ //close and destory the skipBuffer
+ if (skipBuffer != NULL) {
+ skipBuffer->close();
+ _CLDELETE(skipBuffer);
+ }
+}
+
+void SegmentMerger::add(IndexReader* reader)
+{
+ //Func - Adds a IndexReader to the set of readers
+ //Pre - reader contains a valid reference to a IndexReader
+ //Post - The SegementReader reader has been added to the set of readers
+
+ readers.push_back(reader);
+}
+
+IndexReader* SegmentMerger::segmentReader(const int32_t i)
+{
+ //Func - Returns a reference to the i-th IndexReader
+ //Pre - 0 <= i < readers.size()
+ //Post - A reference to the i-th IndexReader has been returned
+
+ CND_PRECONDITION(i >= 0, "i is a negative number");
+ CND_PRECONDITION((size_t)i < readers.size(),
+ "i is bigger than the number of IndexReader instances");
+
+ //Retrieve the i-th IndexReader
+ IndexReader* ret = readers[i];
+ CND_CONDITION(ret != NULL, "No IndexReader found");
+
+ return ret;
+}
+
+int32_t SegmentMerger::merge()
+{
+ int32_t value = mergeFields();
+ mergeTerms();
+ mergeNorms();
+
+ if (fieldInfos->hasVectors())
+ mergeVectors();
+
+ return value;
+}
+
+void SegmentMerger::closeReaders()
+{
+ for (uint32_t i = 0; i < readers.size(); i++) {
+ // close readers
+ IndexReader* reader = readers[i];
+ reader->close();
+ }
+}
+
+void SegmentMerger::createCompoundFile(const QString& filename, QStringList& files)
+{
+ CompoundFileWriter* cfsWriter = _CLNEW CompoundFileWriter(directory, filename);
+
+ { //msvc6 scope fix
+ // Basic files
+ for (int32_t i = 0; i < COMPOUND_EXTENSIONS_LENGTH; i++) {
+ files.push_back(Misc::qjoin(segment, QLatin1String("."),
+ QLatin1String(COMPOUND_EXTENSIONS+(i*4))));
+ }
+ }
+
+ { //msvc6 scope fix
+ // Field norm files
+ for (int32_t i = 0; i < fieldInfos->size(); i++) {
+ FieldInfo* fi = fieldInfos->fieldInfo(i);
+ if (fi->isIndexed && !fi->omitNorms) {
+ TCHAR tbuf[10];
+ char abuf[10];
+ _i64tot(i, tbuf, 10);
+ STRCPY_TtoA(abuf, tbuf, 10);
+
+ files.push_back(Misc::qjoin(segment, QLatin1String(".f"),
+ QLatin1String(abuf)));
+ }
+ }
+ }
+
+ // Vector files
+ if (fieldInfos->hasVectors()) {
+ for (int32_t i = 0; i < VECTOR_EXTENSIONS_LENGTH; i++) {
+ files.push_back(Misc::qjoin(segment, QLatin1String("."),
+ QLatin1String(VECTOR_EXTENSIONS+(i*4))));
+ }
+ }
+
+ { //msvc6 scope fix
+ // Now merge all added files
+ for (size_t i=0;i<files.size();i++) {
+ cfsWriter->addFile(files[i]);
+ }
+ }
+
+ // Perform the merge
+ cfsWriter->close();
+ _CLDELETE(cfsWriter);
+}
+
+void SegmentMerger::addIndexed(IndexReader* reader, FieldInfos* fieldInfos,
+ StringArrayWithDeletor& names, bool storeTermVectors,
+ bool storePositionWithTermVector, bool storeOffsetWithTermVector)
+{
+ StringArrayWithDeletor::const_iterator itr = names.begin();
+ while (itr != names.end()) {
+ fieldInfos->add(*itr, true,
+ storeTermVectors, storePositionWithTermVector,
+ storeOffsetWithTermVector, !reader->hasNorms(*itr));
+ ++itr;
+ }
+}
+
+int32_t SegmentMerger::mergeFields()
+{
+ //Func - Merge the fields of all segments
+ //Pre - true
+ //Post - The field infos and field values of all segments have been merged.
+
+ //Create a new FieldInfos
+ fieldInfos = _CLNEW FieldInfos(); // merge field names
+
+ //Condition check to see if fieldInfos points to a valid instance
+ CND_CONDITION(fieldInfos != NULL, "Memory allocation for fieldInfos failed");
+
+ IndexReader* reader = NULL;
+
+ int32_t docCount = 0;
+
+ //Iterate through all readers
+ for (uint32_t i = 0; i < readers.size(); i++) {
+ //get the i-th reader
+ reader = readers[i];
+ //Condition check to see if reader points to a valid instance
+ CND_CONDITION(reader != NULL,"No IndexReader found");
+
+ StringArrayWithDeletor tmp;
+
+ tmp.clear();
+ reader->getFieldNames(IndexReader::TERMVECTOR_WITH_POSITION_OFFSET, tmp);
+ addIndexed(reader, fieldInfos, tmp, true, true, true);
+
+ tmp.clear();
+ reader->getFieldNames(IndexReader::TERMVECTOR_WITH_POSITION, tmp);
+ addIndexed(reader, fieldInfos, tmp, true, true, false);
+
+ tmp.clear();
+ reader->getFieldNames(IndexReader::TERMVECTOR_WITH_OFFSET, tmp);
+ addIndexed(reader, fieldInfos, tmp, true, false, true);
+
+ tmp.clear();
+ reader->getFieldNames(IndexReader::TERMVECTOR, tmp);
+ addIndexed(reader, fieldInfos, tmp, true, false, false);
+
+ tmp.clear();
+ reader->getFieldNames(IndexReader::INDEXED, tmp);
+ addIndexed(reader, fieldInfos, tmp, false, false, false);
+
+ tmp.clear();
+ reader->getFieldNames(IndexReader::UNINDEXED, tmp);
+ if (tmp.size() > 0) {
+ TCHAR** arr = _CL_NEWARRAY(TCHAR*,tmp.size()+1);
+ tmp.toArray(arr);
+ fieldInfos->add((const TCHAR**)arr, false);
+ _CLDELETE_ARRAY(arr);
+ //no need to delete the contents, since tmp is responsible for it
+ }
+ }
+
+ //Create the filename of the new FieldInfos file
+ QString buf = Misc::segmentname(segment, QLatin1String(".fnm"));
+ //Write the new FieldInfos file to the directory
+ fieldInfos->write(directory, buf);
+
+ // merge field values
+ // Instantiate Fieldswriter which will write in directory for the segment
+ // name segment using the new merged fieldInfos
+ FieldsWriter* fieldsWriter = _CLNEW FieldsWriter(directory, segment, fieldInfos);
+
+ //Condition check to see if fieldsWriter points to a valid instance
+ CND_CONDITION(fieldsWriter != NULL, "Memory allocation for fieldsWriter failed");
+
+ try {
+ IndexReader* reader = NULL;
+ int32_t maxDoc = 0;
+ //Iterate through all readers
+ for (uint32_t i = 0; i < readers.size(); i++) {
+ // get the i-th reader
+ reader = readers[i];
+
+
+ // Condition check to see if reader points to a valid instance
+ CND_CONDITION(reader != NULL, "No IndexReader found");
+
+ // Get the total number documents including the documents that have
+ // been marked deleted
+ int32_t maxDoc = reader->maxDoc();
+
+ //document buffer
+ Document doc;
+
+ //Iterate through all the documents managed by the current reader
+ for (int32_t j = 0; j < maxDoc; j++) {
+ //Check if the j-th document has been deleted, if so skip it
+ if (!reader->isDeleted(j)) {
+ //Get the document
+ if (reader->document(j, &doc)) {
+ //Add the document to the new FieldsWriter
+ fieldsWriter->addDocument(&doc);
+ docCount++;
+ //doc is cleard for re-use
+ doc.clear();
+ }
+ }
+ }
+ }
+ } _CLFINALLY (
+ //Close the fieldsWriter
+ fieldsWriter->close();
+ //And have it deleted as it not used any more
+ _CLDELETE(fieldsWriter);
+ );
+
+ return docCount;
+}
+
+void SegmentMerger::mergeVectors()
+{
+ TermVectorsWriter* termVectorsWriter =
+ _CLNEW TermVectorsWriter(directory, segment, fieldInfos);
+
+ try {
+ for (uint32_t r = 0; r < readers.size(); r++) {
+ IndexReader* reader = readers[r];
+ int32_t maxDoc = reader->maxDoc();
+ for (int32_t docNum = 0; docNum < maxDoc; docNum++) {
+ // skip deleted docs
+ if (reader->isDeleted(docNum))
+ continue;
+
+ Array<TermFreqVector*> tmp;
+ if (reader->getTermFreqVectors(docNum, tmp))
+ termVectorsWriter->addAllDocVectors(tmp);
+ tmp.deleteAll();
+ }
+ }
+ } _CLFINALLY (
+ _CLDELETE(termVectorsWriter);
+ );
+}
+
+
+void SegmentMerger::mergeTerms()
+{
+ //Func - Merge the terms of all segments
+ //Pre - fieldInfos != NULL
+ //Post - The terms of all segments have been merged
+
+ CND_PRECONDITION(fieldInfos != NULL, "fieldInfos is NULL");
+
+ try{
+ //create a filename for the new Frequency File for segment
+ QString buf = Misc::segmentname(segment, QLatin1String(".frq"));
+ //Open an IndexOutput to the new Frequency File
+ freqOutput = directory->createOutput(buf);
+
+ //create a filename for the new Prox File for segment
+ buf = Misc::segmentname(segment, QLatin1String(".prx"));
+ //Open an IndexOutput to the new Prox File
+ proxOutput = directory->createOutput(buf);
+
+ //Instantiate a new termInfosWriter which will write in directory
+ //for the segment name segment using the new merged fieldInfos
+ termInfosWriter = _CLNEW TermInfosWriter(directory, segment, fieldInfos,
+ termIndexInterval);
+
+ //Condition check to see if termInfosWriter points to a valid instance
+ CND_CONDITION(termInfosWriter != NULL,
+ "Memory allocation for termInfosWriter failed");
+
+ skipInterval = termInfosWriter->skipInterval;
+ queue = _CLNEW SegmentMergeQueue(readers.size());
+
+ //And merge the Term Infos
+ mergeTermInfos();
+ } _CLFINALLY (
+ //Close and destroy the IndexOutput to the Frequency File
+ if (freqOutput != NULL) {
+ freqOutput->close(); _CLDELETE(freqOutput);
+ }
+
+ //Close and destroy the IndexOutput to the Prox File
+ if (proxOutput != NULL)
+ {
+ proxOutput->close();
+ _CLDELETE(proxOutput);
+ }
+
+ //Close and destroy the termInfosWriter
+ if (termInfosWriter != NULL) {
+ termInfosWriter->close();
+ _CLDELETE(termInfosWriter);
+ }
+
+ //Close and destroy the queue
+ if (queue != NULL) {
+ queue->close();
+ _CLDELETE(queue);
+ }
+ );
+}
+
+void SegmentMerger::mergeTermInfos()
+{
+ //Func - Merges all TermInfos into a single segment
+ //Pre - true
+ //Post - All TermInfos have been merged into a single segment
+
+ //Condition check to see if queue points to a valid instance
+ CND_CONDITION(queue != NULL, "Memory allocation for queue failed");
+
+ //base is the id of the first document in a segment
+ int32_t base = 0;
+
+ IndexReader* reader = NULL;
+ SegmentMergeInfo* smi = NULL;
+
+ //iterate through all the readers
+ for (uint32_t i = 0; i < readers.size(); i++) {
+ //Get the i-th reader
+ reader = readers[i];
+
+ //Condition check to see if reader points to a valid instance
+ CND_CONDITION(reader != NULL, "No IndexReader found");
+
+ //Get the term enumeration of the reader
+ TermEnum* termEnum = reader->terms();
+ //Instantiate a new SegmentMerginfo for the current reader and enumeration
+ smi = _CLNEW SegmentMergeInfo(base, termEnum, reader);
+
+ //Condition check to see if smi points to a valid instance
+ CND_CONDITION(smi != NULL, "Memory allocation for smi failed") ;
+
+ //Increase the base by the number of documents that have not been marked deleted
+ //so base will contain a new value for the first document of the next iteration
+ base += reader->numDocs();
+ //Get the next current term
+ if (smi->next()) {
+ //Store the SegmentMergeInfo smi with the initialized SegmentTermEnum TermEnum
+ //into the queue
+ queue->put(smi);
+ } else {
+ //Apparently the end of the TermEnum of the SegmentTerm has been reached so
+ //close the SegmentMergeInfo smi
+ smi->close();
+ //And destroy the instance and set smi to NULL (It will be used later in this method)
+ _CLDELETE(smi);
+ }
+ }
+
+ //Instantiate an array of SegmentMergeInfo instances called match
+ SegmentMergeInfo** match = _CL_NEWARRAY(SegmentMergeInfo*,readers.size()+1);
+
+ //Condition check to see if match points to a valid instance
+ CND_CONDITION(match != NULL, "Memory allocation for match failed") ;
+
+ SegmentMergeInfo* top = NULL;
+
+ //As long as there are SegmentMergeInfo instances stored in the queue
+ while (queue->size() > 0) {
+ int32_t matchSize = 0;
+
+ // pop matching terms
+
+ //Pop the first SegmentMergeInfo from the queue
+ match[matchSize++] = queue->pop();
+ //Get the Term of match[0]
+ Term* term = match[0]->term;
+
+ //Condition check to see if term points to a valid instance
+ CND_CONDITION(term != NULL,"term is NULL") ;
+
+ //Get the current top of the queue
+ top = queue->top();
+
+ //For each SegmentMergInfo still in the queue
+ //Check if term matches the term of the SegmentMergeInfo instances in the queue
+ while (top != NULL && term->equals(top->term)) {
+ //A match has been found so add the matching SegmentMergeInfo to the match array
+ match[matchSize++] = queue->pop();
+ //Get the next SegmentMergeInfo
+ top = queue->top();
+ }
+ match[matchSize]=NULL;
+
+ //add new TermInfo
+ mergeTermInfo(match); //matchSize
+
+ //Restore the SegmentTermInfo instances in the match array back into the queue
+ while (matchSize > 0) {
+ smi = match[--matchSize];
+
+ //Condition check to see if smi points to a valid instance
+ CND_CONDITION(smi != NULL, "smi is NULL");
+
+ //Move to the next term in the enumeration of SegmentMergeInfo smi
+ if (smi->next()) {
+ //There still are some terms so restore smi in the queue
+ queue->put(smi);
+
+ } else {
+ //Done with a segment
+ //No terms anymore so close this SegmentMergeInfo instance
+ smi->close();
+ _CLDELETE(smi);
+ }
+ }
+ }
+
+ _CLDELETE_ARRAY(match);
+}
+
+void SegmentMerger::mergeTermInfo(SegmentMergeInfo** smis)
+{
+ //Func - Merge the TermInfo of a term found in one or more segments.
+ //Pre - smis != NULL and it contains segments that are positioned at the same term.
+ // n is equal to the number of SegmentMergeInfo instances in smis
+ // freqOutput != NULL
+ // proxOutput != NULL
+ //Post - The TermInfo of a term has been merged
+
+ CND_PRECONDITION(smis != NULL, "smis is NULL");
+ CND_PRECONDITION(freqOutput != NULL, "freqOutput is NULL");
+ CND_PRECONDITION(proxOutput != NULL, "proxOutput is NULL");
+
+ //Get the file pointer of the IndexOutput to the Frequency File
+ int64_t freqPointer = freqOutput->getFilePointer();
+ //Get the file pointer of the IndexOutput to the Prox File
+ int64_t proxPointer = proxOutput->getFilePointer();
+
+ //Process postings from multiple segments all positioned on the same term.
+ int32_t df = appendPostings(smis);
+
+ int64_t skipPointer = writeSkip();
+
+ //df contains the number of documents across all segments where this term was found
+ if (df > 0) {
+ //add an entry to the dictionary with pointers to prox and freq files
+ termInfo.set(df, freqPointer, proxPointer, (int32_t)(skipPointer - freqPointer));
+ //Precondition check for to be sure that the reference to
+ //smis[0]->term will be valid
+ CND_PRECONDITION(smis[0]->term != NULL, "smis[0]->term is NULL");
+ //Write a new TermInfo
+ termInfosWriter->add(smis[0]->term, &termInfo);
+ }
+}
+
+
+int32_t SegmentMerger::appendPostings(SegmentMergeInfo** smis)
+{
+ //Func - Process postings from multiple segments all positioned on the
+ // same term. Writes out merged entries into freqOutput and
+ // the proxOutput streams.
+ //Pre - smis != NULL and it contains segments that are positioned at the same term.
+ // n is equal to the number of SegmentMergeInfo instances in smis
+ // freqOutput != NULL
+ // proxOutput != NULL
+ //Post - Returns number of documents across all segments where this term was found
+
+ CND_PRECONDITION(smis != NULL, "smis is NULL");
+ CND_PRECONDITION(freqOutput != NULL, "freqOutput is NULL");
+ CND_PRECONDITION(proxOutput != NULL, "proxOutput is NULL");
+
+ int32_t lastDoc = 0;
+ int32_t df = 0; //Document Counter
+
+ resetSkip();
+ SegmentMergeInfo* smi = NULL;
+
+ //Iterate through all SegmentMergeInfo instances in smis
+ int32_t i = 0;
+ while ((smi=smis[i]) != NULL) {
+ //Get the i-th SegmentMergeInfo
+
+ //Condition check to see if smi points to a valid instance
+ CND_PRECONDITION(smi != NULL, " is NULL");
+
+ //Get the term positions
+ TermPositions* postings = smi->getPositions();
+ //Get the base of this segment
+ int32_t base = smi->base;
+ //Get the docMap so we can see which documents have been deleted
+ int32_t* docMap = smi->getDocMap();
+ //Seek the termpost
+ postings->seek(smi->termEnum);
+ while (postings->next()) {
+ int32_t doc = postings->doc();
+ //Check if there are deletions
+ if (docMap != NULL)
+ doc = docMap[doc]; // map around deletions
+ doc += base; // convert to merged space
+
+ //Condition check to see doc is eaqual to or bigger than lastDoc
+ CND_CONDITION(doc >= lastDoc,"docs out of order");
+
+ //Increase the total frequency over all segments
+ df++;
+
+ if ((df % skipInterval) == 0) {
+ bufferSkip(lastDoc);
+ }
+
+ //Calculate a new docCode
+ //use low bit to flag freq=1
+ int32_t docCode = (doc - lastDoc) << 1;
+ lastDoc = doc;
+
+ //Get the frequency of the Term
+ int32_t freq = postings->freq();
+ if (freq == 1) {
+ //write doc & freq=1
+ freqOutput->writeVInt(docCode | 1);
+ } else {
+ //write doc
+ freqOutput->writeVInt(docCode);
+ //write frequency in doc
+ freqOutput->writeVInt(freq);
+ }
+
+ int32_t lastPosition = 0;
+ // write position deltas
+ for (int32_t j = 0; j < freq; j++) {
+ //Get the next position
+ int32_t position = postings->nextPosition();
+ //Write the difference between position and the last position
+ proxOutput->writeVInt(position - lastPosition);
+ lastPosition = position;
+ }
+ }
+
+ i++;
+ }
+
+ //Return total number of documents across all segments where term was found
+ return df;
+}
+
+void SegmentMerger::resetSkip()
+{
+ skipBuffer->reset();
+ lastSkipDoc = 0;
+ lastSkipFreqPointer = freqOutput->getFilePointer();
+ lastSkipProxPointer = proxOutput->getFilePointer();
+}
+
+void SegmentMerger::bufferSkip(int32_t doc)
+{
+ int64_t freqPointer = freqOutput->getFilePointer();
+ int64_t proxPointer = proxOutput->getFilePointer();
+
+ skipBuffer->writeVInt(doc - lastSkipDoc);
+ skipBuffer->writeVInt((int32_t) (freqPointer - lastSkipFreqPointer));
+ skipBuffer->writeVInt((int32_t) (proxPointer - lastSkipProxPointer));
+
+ lastSkipDoc = doc;
+ lastSkipFreqPointer = freqPointer;
+ lastSkipProxPointer = proxPointer;
+}
+
+int64_t SegmentMerger::writeSkip()
+{
+ int64_t skipPointer = freqOutput->getFilePointer();
+ skipBuffer->writeTo(freqOutput);
+ return skipPointer;
+}
+
+// Func - Merges the norms for all fields
+// Pre - fieldInfos != NULL
+// Post - The norms for all fields have been merged
+void SegmentMerger::mergeNorms()
+{
+ CND_PRECONDITION(fieldInfos != NULL, "fieldInfos is NULL");
+
+ //iterate through all the Field Infos instances
+ for (int32_t i = 0; i < fieldInfos->size(); i++) {
+ //Get the i-th FieldInfo
+ FieldInfo* fi = fieldInfos->fieldInfo(i);
+ //Is this Field indexed?
+ if (fi->isIndexed && !fi->omitNorms) {
+ //Create and Instantiate an IndexOutput to that norm file
+ QString buf = Misc::segmentname(segment, QLatin1String(".f"), i);
+ IndexOutput* output = directory->createOutput(buf);
+
+ //Condition check to see if output points to a valid instance
+ CND_CONDITION(output != NULL, "No Outputstream retrieved");
+
+ uint8_t* input = NULL;
+ try {
+ for (uint32_t j = 0; j < readers.size(); ++j) {
+ // get the next index reader + condition check
+ IndexReader* reader = readers[j];
+ CND_CONDITION(reader != NULL, "No reader found");
+
+ // Get the total number of documents including the documents
+ // that have been marked deleted
+ int32_t maxDoc = reader->maxDoc();
+ if (maxDoc > 0) {
+ // if there are docs, allocate buffer to read it's norms
+ uint8_t* data = (uint8_t*)realloc(input, maxDoc *
+ sizeof(uint8_t));
+ if (data) {
+ input = data;
+ memset(input, 0, maxDoc * sizeof(uint8_t));
+ // Get an IndexInput to the norm file for this
+ // field in this segment
+ reader->norms(fi->name, input);
+
+ //Iterate through all the documents
+ for(int32_t k = 0; k < maxDoc; k++) {
+ //Check if document k is deleted
+ if (!reader->isDeleted(k)) {
+ //write the new norm
+ output->writeByte(input[k]);
+ }
+ }
+ }
+ }
+ }
+ } _CLFINALLY (
+ if (output != NULL) {
+ output->close();
+ _CLDELETE(output);
+ }
+ free(input);
+ );
+ }
+ }
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentMerger.h b/3rdparty/clucene/src/CLucene/index/SegmentMerger.h
new file mode 100644
index 000000000..230843b00
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentMerger.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_SegmentMerger_
+#define _lucene_index_SegmentMerger_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/RAMDirectory.h"
+#include "CLucene/util/VoidList.h"
+#include "SegmentMergeInfo.h"
+#include "SegmentMergeQueue.h"
+#include "IndexWriter.h"
+#include "FieldInfos.h"
+#include "FieldsWriter.h"
+#include "TermInfosWriter.h"
+
+CL_NS_DEF(index)
+
+/**
+* The SegmentMerger class combines two or more Segments, represented by an IndexReader ({@link #add},
+* into a single Segment. After adding the appropriate readers, call the merge method to combine the
+* segments.
+*<P>
+* If the compoundFile flag is set, then the segments will be merged into a compound file.
+*
+*
+* @see #merge
+* @see #add
+*/
+class SegmentMerger : LUCENE_BASE
+{
+ bool useCompoundFile;
+
+ CL_NS(store)::RAMIndexOutput* skipBuffer;
+ int32_t lastSkipDoc;
+ int64_t lastSkipFreqPointer;
+ int64_t lastSkipProxPointer;
+
+ void resetSkip();
+ void bufferSkip(int32_t doc);
+ int64_t writeSkip();
+
+ //Directory of the segment
+ CL_NS(store)::Directory* directory;
+ //name of the new segment
+ QString segment;
+ //Set of IndexReaders
+ CL_NS(util)::CLVector<IndexReader*,
+ CL_NS(util)::Deletor::Object<IndexReader> > readers;
+ //Field Infos for t he FieldInfo instances of all fields
+ FieldInfos* fieldInfos;
+
+ //The queue that holds SegmentMergeInfo instances
+ SegmentMergeQueue* queue;
+ //IndexOutput to the new Frequency File
+ CL_NS(store)::IndexOutput* freqOutput;
+ //IndexOutput to the new Prox File
+ CL_NS(store)::IndexOutput* proxOutput;
+ //Writes Terminfos that have been merged
+ TermInfosWriter* termInfosWriter;
+ TermInfo termInfo; //(new) minimize consing
+
+ int32_t termIndexInterval;
+ int32_t skipInterval;
+
+public:
+ /**
+ *
+ * @param dir The Directory to merge the other segments into
+ * @param name The name of the new segment
+ * @param compoundFile true if the new segment should use a compoundFile
+ */
+ SegmentMerger( IndexWriter* writer, const QString& name );
+
+ //Destructor
+ ~SegmentMerger();
+
+ /**
+ * Add an IndexReader to the collection of readers that are to be merged
+ * @param reader
+ */
+ void add(IndexReader* reader);
+
+ /**
+ *
+ * @param i The index of the reader to return
+ * @return The ith reader to be merged
+ */
+ IndexReader* segmentReader(const int32_t i);
+
+ /**
+ * Merges the readers specified by the {@link #add} method into the
+ * directory passed to the constructor
+ * @return The number of documents that were merged
+ * @throws IOException
+ */
+ int32_t merge();
+ /**
+ * close all IndexReaders that have been added.
+ * Should not be called before merge().
+ * @throws IOException
+ */
+ void closeReaders();
+private:
+ void addIndexed(IndexReader* reader, FieldInfos* fieldInfos,
+ CL_NS(util)::StringArrayWithDeletor& names,
+ bool storeTermVectors, bool storePositionWithTermVector,
+ bool storeOffsetWithTermVector);
+
+ /**
+ * Merge the fields of all segments
+ * @return The number of documents in all of the readers
+ * @throws IOException
+ */
+ int32_t mergeFields();
+
+ /**
+ * Merge the TermVectors from each of the segments into the new one.
+ * @throws IOException
+ */
+ void mergeVectors();
+
+ /** Merge the terms of all segments */
+ void mergeTerms();
+
+ /** Merges all TermInfos into a single segment */
+ void mergeTermInfos();
+
+ /** Merge one term found in one or more segments. The array <code>smis</code>
+ * contains segments that are positioned at the same term. <code>N</code>
+ * is the number of cells in the array actually occupied.
+ *
+ * @param smis array of segments
+ * @param n number of cells in the array actually occupied
+ */
+ void mergeTermInfo( SegmentMergeInfo** smis);
+
+ /** Process postings from multiple segments all positioned on the
+ * same term. Writes out merged entries into freqOutput and
+ * the proxOutput streams.
+ *
+ * @param smis array of segments
+ * @param n number of cells in the array actually occupied
+ * @return number of documents across all segments where this term was found
+ */
+ int32_t appendPostings(SegmentMergeInfo** smis);
+
+ //Merges the norms for all fields
+ void mergeNorms();
+
+ void createCompoundFile(const QString& filename, QStringList& files);
+ friend class IndexWriter; //allow IndexWriter to use createCompoundFile
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentReader.cpp b/3rdparty/clucene/src/CLucene/index/SegmentReader.cpp
new file mode 100644
index 000000000..ba061714b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentReader.cpp
@@ -0,0 +1,816 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#include "CLucene/StdHeader.h"
+#include "SegmentHeader.h"
+
+#include "FieldInfos.h"
+#include "FieldsReader.h"
+#include "IndexReader.h"
+#include "TermInfosReader.h"
+#include "Terms.h"
+#include "CLucene/search/Similarity.h"
+
+CL_NS_USE(util)
+CL_NS_USE(store)
+CL_NS_USE(document)
+CL_NS_USE(search)
+CL_NS_DEF(index)
+
+SegmentReader::Norm::Norm(IndexInput* instrm, int32_t n, SegmentReader* r,
+ const QString& seg)
+ : number(n)
+ , reader(r)
+ , segment(seg)
+ , in(instrm)
+ , bytes(NULL)
+ , dirty(false)
+{
+ //Func - Constructor
+ //Pre - instrm is a valid reference to an IndexInput
+ //Post - A Norm instance has been created with an empty bytes array
+ bytes = NULL;
+ dirty = false;
+}
+
+SegmentReader::Norm::~Norm()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The IndexInput in has been deleted (and closed by its destructor)
+ // and the array too.
+
+ //Close and destroy the inputstream in-> The inputstream will be closed
+ // by its destructor. Note that the IndexInput 'in' actually is a pointer!!!!!
+ _CLDELETE(in);
+
+ //Delete the bytes array
+ _CLDELETE_ARRAY(bytes);
+
+}
+
+void SegmentReader::Norm::reWrite()
+{
+ QString buf(segment + QLatin1String(".tmp"));
+
+ // NOTE: norms are re-written in regular directory, not cfs
+ IndexOutput* out = reader->getDirectory()->createOutput(buf);
+ try {
+ out->writeBytes(bytes, reader->maxDoc());
+ } _CLFINALLY (
+ out->close();
+ _CLDELETE(out)
+ );
+
+ QString fileName(segment);
+ if (reader->cfsReader == NULL)
+ fileName.append(QLatin1String(".f%1")).arg(number);
+ else // use a different file name if we have compound format
+ fileName.append(QLatin1String(".s%1")).arg(number);
+
+ reader->getDirectory()->renameFile(buf, fileName);
+ this->dirty = false;
+}
+
+SegmentReader::SegmentReader(SegmentInfo* si)
+ : IndexReader(si->getDir())
+ , _norms(false, false)
+{
+ initialize(si);
+}
+
+SegmentReader::SegmentReader(SegmentInfos* sis, SegmentInfo* si)
+ : IndexReader(si->getDir(), sis, false)
+ , _norms(false, false)
+{
+ initialize(si);
+}
+
+void SegmentReader::initialize(SegmentInfo* si)
+{
+ //Pre - si-> is a valid reference to SegmentInfo instance
+ // identified by si->
+ //Post - All files of the segment have been read
+
+ deletedDocs = NULL;
+ ones = NULL;
+ //There are no documents yet marked as deleted
+ deletedDocsDirty = false;
+
+ normsDirty=false;
+ undeleteAll=false;
+
+ //Duplicate the name of the segment from SegmentInfo to segment
+ segment = si->name;
+ // make sure that all index files have been read or are kept open
+ // so that if an index update removes them we'll still have them
+ freqStream = NULL;
+ proxStream = NULL;
+
+ //instantiate a buffer large enough to hold a directory path
+ QString buf;
+
+ // Use compound file directory for some files, if it exists
+ Directory* cfsDir = getDirectory();
+ SegmentName(buf, CL_MAX_PATH, QLatin1String(".cfs"));
+ if (cfsDir->fileExists(buf)) {
+ cfsReader = _CLNEW CompoundFileReader(cfsDir, buf);
+ cfsDir = cfsReader;
+ }else
+ cfsReader = NULL;
+
+ // Create the name of the field info file with suffix .fnm in buf
+ SegmentName(buf, CL_MAX_PATH, QLatin1String(".fnm"));
+ fieldInfos = _CLNEW FieldInfos(cfsDir, buf );
+
+ // Condition check to see if fieldInfos points to a valid instance
+ CND_CONDITION(fieldInfos != NULL,
+ "No memory could be allocated for fieldInfos");
+
+ // Create the name of the frequence file with suffix .frq in buf
+ SegmentName(buf ,CL_MAX_PATH, QLatin1String(".frq"));
+
+ // Open an IndexInput freqStream to the frequency file
+ freqStream = cfsDir->openInput( buf );
+
+ // Condition check to see if freqStream points to a valid instance and was
+ // able to open the frequency file
+ CND_CONDITION(freqStream != NULL,
+ "IndexInput freqStream could not open the frequency file");
+
+ // Create the name of the prox file with suffix .prx in buf
+ SegmentName(buf, CL_MAX_PATH, QLatin1String(".prx"));
+
+ // Open an IndexInput proxStream to the prox file
+ proxStream = cfsDir->openInput( buf );
+
+ // Condition check to see if proxStream points to a valid instance and was
+ // able to open the prox file
+ CND_CONDITION(proxStream != NULL,
+ "IndexInput proxStream could not open proximity file");
+
+ // Instantiate a FieldsReader for reading the Field Info File
+ fieldsReader = _CLNEW FieldsReader(cfsDir, segment, fieldInfos);
+
+ // Condition check to see if fieldsReader points to a valid instance
+ CND_CONDITION(fieldsReader != NULL,
+ "No memory could be allocated for fieldsReader");
+
+ //Instantiate a TermInfosReader for reading the Term Dictionary .tis file
+ tis = _CLNEW TermInfosReader(cfsDir, segment, fieldInfos);
+
+ //Condition check to see if tis points to a valid instance
+ CND_CONDITION(tis != NULL,"No memory could be allocated for tis");
+
+ // Check if the segment has deletion according to the SegmentInfo instance
+ // si-> NOTE: the bitvector is stored using the regular directory, not cfs
+ if (hasDeletions(si)) {
+ //Create a deletion file with suffix .del
+ SegmentName(buf, CL_MAX_PATH, QLatin1String(".del"));
+ // Instantiate a BitVector that manages which documents have been deleted
+ deletedDocs = _CLNEW BitSet(getDirectory(), buf);
+ }
+
+ // Open the norm file. There's a norm file for each indexed field with a
+ // byte for each document. The .f[0-9]* file contains, for each document,
+ // a byte that encodes a value that is multiplied into the score for hits
+ // on that field
+ openNorms(cfsDir);
+
+ termVectorsReaderOrig = NULL;
+ if (fieldInfos->hasVectors()) // open term vector files only as needed
+ termVectorsReaderOrig = _CLNEW TermVectorsReader(cfsDir, segment, fieldInfos);
+}
+
+SegmentReader::~SegmentReader()
+{
+ //Func - Destructor.
+ //Pre - doClose has been invoked!
+ //Post - the instance has been destroyed
+
+ doClose(); //this means that index reader doesn't need to be closed manually
+
+ _CLDELETE(fieldInfos);
+ _CLDELETE(fieldsReader);
+ _CLDELETE(tis);
+ _CLDELETE(freqStream);
+ _CLDELETE(proxStream);
+ _CLDELETE(deletedDocs);
+ _CLDELETE_ARRAY(ones);
+ _CLDELETE(termVectorsReaderOrig);
+ _CLDECDELETE(cfsReader);
+}
+
+void SegmentReader::doCommit()
+{
+ QString bufdel(segment + QLatin1String(".del"));
+
+ if (deletedDocsDirty) { // re-write deleted
+ QString buftmp(segment + QLatin1String(".tmp"));
+ deletedDocs->write(getDirectory(), buftmp);
+ getDirectory()->renameFile(buftmp, bufdel);
+ }
+
+ if(undeleteAll && getDirectory()->fileExists(bufdel))
+ getDirectory()->deleteFile(bufdel, true);
+
+ if (normsDirty) { // re-write norms
+ NormsType::iterator itr = _norms.begin();
+ while (itr != _norms.end()) {
+ Norm* norm = itr->second;
+ if (norm->dirty) {
+ norm->reWrite();
+ }
+ ++itr;
+ }
+ }
+ deletedDocsDirty = false;
+ normsDirty = false;
+ undeleteAll = false;
+}
+
+void SegmentReader::doClose()
+{
+ //Func - Closes all streams to the files of a single segment
+ //Pre - fieldsReader != NULL
+ // tis != NULL
+ //Post - All streams to files have been closed
+
+ CND_PRECONDITION(fieldsReader != NULL, "fieldsReader is NULL");
+ CND_PRECONDITION(tis != NULL, "tis is NULL");
+
+ //Close the fieldsReader
+ fieldsReader->close();
+ //Close the TermInfosReader
+ tis->close();
+
+ //Close the frequency stream
+ if (freqStream != NULL){
+ freqStream->close();
+ }
+ //Close the prox stream
+ if (proxStream != NULL){
+ proxStream->close();
+ }
+
+ //Close the norm file
+ closeNorms();
+
+ if (termVectorsReaderOrig != NULL)
+ termVectorsReaderOrig->close();
+
+ if (cfsReader != NULL)
+ cfsReader->close();
+}
+
+bool SegmentReader::hasDeletions() const
+{
+ return deletedDocs != NULL;
+}
+
+//static
+bool SegmentReader::usesCompoundFile(SegmentInfo* si)
+{
+ return si->getDir()->fileExists(si->name + QLatin1String(".cfs"));
+}
+
+//static
+bool SegmentReader::hasSeparateNorms(SegmentInfo* si)
+{
+ QString pattern(si->name);
+ pattern.append(QLatin1String(".s"));
+ size_t patternLength = pattern.length();
+
+ QStringList names = si->getDir()->list();
+ foreach (const QString& name, names) {
+ int length = name.length();
+ if (length > patternLength && name.left(patternLength) == pattern) {
+ if (name.at(patternLength) >= QLatin1Char('0')
+ && name.at(patternLength) <= QLatin1Char('9')) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool SegmentReader::hasDeletions(const SegmentInfo* si)
+{
+ //Func - Static method
+ // Checks if a segment managed by SegmentInfo si-> has deletions
+ //Pre - si-> holds a valid reference to an SegmentInfo instance
+ //Post - if the segement contains deleteions true is returned otherwise flas
+
+ //Check if the deletion file exists and return the result
+ QString f;
+ Misc::segmentname(f, CL_MAX_PATH, si->name, QLatin1String(".del"), -1);
+ return si->getDir()->fileExists(f);
+}
+
+//synchronized
+void SegmentReader::doDelete(const int32_t docNum)
+{
+ //Func - Marks document docNum as deleted
+ //Pre - docNum >=0 and DocNum < maxDoc()
+ // docNum contains the number of the document that must be
+ // marked deleted
+ //Post - The document identified by docNum has been marked deleted
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ CND_PRECONDITION(docNum >= 0, "docNum is a negative number");
+ CND_PRECONDITION(docNum < maxDoc(),
+ "docNum is bigger than the total number of documents");
+
+ //Check if deletedDocs exists
+ if (deletedDocs == NULL) {
+ deletedDocs = _CLNEW BitSet(maxDoc());
+
+ //Condition check to see if deletedDocs points to a valid instance
+ CND_CONDITION(deletedDocs != NULL,
+ "No memory could be allocated for deletedDocs");
+ }
+ //Flag that there are documents marked deleted
+ deletedDocsDirty = true;
+ undeleteAll = false;
+ //Mark document identified by docNum as deleted
+ deletedDocs->set(docNum);
+
+}
+
+void SegmentReader::doUndeleteAll()
+{
+ _CLDELETE(deletedDocs);
+ deletedDocsDirty = false;
+ undeleteAll = true;
+}
+
+void SegmentReader::files(QStringList& retarray)
+{
+ //Func - Returns all file names managed by this SegmentReader
+ //Pre - segment != NULL
+ //Post - All filenames managed by this SegmentRead have been returned
+
+ CND_PRECONDITION(segment != NULL, "segment is NULL");
+
+ QString temp;
+ #define _ADD_SEGMENT(ext) \
+ temp = SegmentName(ext); \
+ if (getDirectory()->fileExists(temp)) \
+ retarray.push_back(temp);
+
+ //Add the name of the Field Info file
+ _ADD_SEGMENT(QLatin1String(".cfs"));
+ _ADD_SEGMENT(QLatin1String(".fnm"));
+ _ADD_SEGMENT(QLatin1String(".fdx"));
+ _ADD_SEGMENT(QLatin1String(".fdt"));
+ _ADD_SEGMENT(QLatin1String(".tii"));
+ _ADD_SEGMENT(QLatin1String(".tis"));
+ _ADD_SEGMENT(QLatin1String(".frq"));
+ _ADD_SEGMENT(QLatin1String(".prx"));
+ _ADD_SEGMENT(QLatin1String(".del"));
+ _ADD_SEGMENT(QLatin1String(".tvx"));
+ _ADD_SEGMENT(QLatin1String(".tvd"));
+ _ADD_SEGMENT(QLatin1String(".tvf"));
+ _ADD_SEGMENT(QLatin1String(".tvp"));
+
+ //iterate through the field infos
+ for (int32_t i = 0; i < fieldInfos->size(); ++i) {
+ //Get the field info for the i-th field
+ FieldInfo* fi = fieldInfos->fieldInfo(i);
+ //Check if the field has been indexed
+ if (fi->isIndexed && !fi->omitNorms) {
+ QString name;
+ if (cfsReader == NULL)
+ name = SegmentName(QLatin1String(".f"), i);
+ else
+ name = SegmentName(QLatin1String(".s"), i);
+
+ //The field has been indexed so add its norm file
+ if (getDirectory()->fileExists(name))
+ retarray.push_back(name);
+ }
+ }
+}
+
+TermEnum* SegmentReader::terms() const
+{
+ //Func - Returns an enumeration of all the Terms and TermInfos in the set.
+ //Pre - tis != NULL
+ //Post - An enumeration of all the Terms and TermInfos in the set has been returned
+
+ CND_PRECONDITION(tis != NULL, "tis is NULL");
+
+ return tis->terms();
+}
+
+TermEnum* SegmentReader::terms(const Term* t) const
+{
+ //Func - Returns an enumeration of terms starting at or after the named term t
+ //Pre - t != NULL
+ // tis != NULL
+ //Post - An enumeration of terms starting at or after the named term t
+
+ CND_PRECONDITION(t != NULL, "t is NULL");
+ CND_PRECONDITION(tis != NULL, "tis is NULL");
+
+ return tis->terms(t);
+}
+
+bool SegmentReader::document(int32_t n, Document* doc)
+{
+ //Func - Returns a document identified by n
+ //Pre - n >=0 and identifies the document n
+ //Post - if the document has been deleted then an exception has been thrown
+ // otherwise a reference to the found document has been returned
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ CND_PRECONDITION(n >= 0, "n is a negative number");
+
+ //Check if the n-th document has been marked deleted
+ if (isDeleted(n))
+ _CLTHROWA(CL_ERR_InvalidState, "attempt to access a deleted document" );
+
+ //Retrieve the n-th document
+ return fieldsReader->doc(n, doc);
+}
+
+bool SegmentReader::isDeleted(const int32_t n)
+{
+ //Func - Checks if the n-th document has been marked deleted
+ //Pre - n >=0 and identifies the document n
+ //Post - true has been returned if document n has been deleted otherwise fralse
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ CND_PRECONDITION(n >= 0, "n is a negative number");
+
+ //Is document n deleted
+ return (deletedDocs != NULL && deletedDocs->get(n));
+}
+
+TermDocs* SegmentReader::termDocs() const
+{
+ //Func - Returns an unpositioned TermDocs enumerator.
+ //Pre - true
+ //Post - An unpositioned TermDocs enumerator has been returned
+
+ return _CLNEW SegmentTermDocs(this);
+}
+
+TermPositions* SegmentReader::termPositions() const
+{
+ //Func - Returns an unpositioned TermPositions enumerator.
+ //Pre - true
+ //Post - An unpositioned TermPositions enumerator has been returned
+
+ return _CLNEW SegmentTermPositions(this);
+}
+
+int32_t SegmentReader::docFreq(const Term* t) const
+{
+ //Func - Returns the number of documents which contain the term t
+ //Pre - t holds a valid reference to a Term
+ //Post - The number of documents which contain term t has been returned
+
+ //Get the TermInfo ti for Term t in the set
+ TermInfo* ti = tis->get(t);
+ //Check if an TermInfo has been returned
+ if (ti) {
+ //Get the frequency of the term
+ int32_t ret = ti->docFreq;
+ //TermInfo ti is not needed anymore so delete it
+ _CLDELETE( ti );
+ //return the number of documents which containt term t
+ return ret;
+ }
+
+ //No TermInfo returned so return 0
+ return 0;
+}
+
+int32_t SegmentReader::numDocs()
+{
+ //Func - Returns the actual number of documents in the segment
+ //Pre - true
+ //Post - The actual number of documents in the segments
+
+ //Get the number of all the documents in the segment including the ones that have
+ //been marked deleted
+ int32_t n = maxDoc();
+
+ //Check if there any deleted docs
+ if (deletedDocs != NULL)
+ //Substract the number of deleted docs from the number returned by maxDoc
+ n -= deletedDocs->count();
+
+ //return the actual number of documents in the segment
+ return n;
+}
+
+int32_t SegmentReader::maxDoc() const
+{
+ //Func - Returns the number of all the documents in the segment including
+ // the ones that have been marked deleted
+ //Pre - true
+ //Post - The total number of documents in the segment has been returned
+
+ return fieldsReader->size();
+}
+
+void SegmentReader::getFieldNames(FieldOption fldOption,
+ StringArrayWithDeletor& retarray)
+{
+ size_t len = fieldInfos->size();
+ for (size_t i = 0; i < len; i++) {
+ bool v = false;
+ FieldInfo* fi = fieldInfos->fieldInfo(i);
+ if (fldOption & IndexReader::ALL) {
+ v = true;
+ } else {
+ if (!fi->isIndexed && (fldOption & IndexReader::UNINDEXED)) {
+ v = true;
+ }
+
+ if (fi->isIndexed && (fldOption & IndexReader::INDEXED)) {
+ v = true;
+ }
+
+ if (fi->isIndexed && fi->storeTermVector == false
+ && (fldOption & IndexReader::INDEXED_NO_TERMVECTOR)) {
+ v = true;
+ }
+
+ if ((fldOption & IndexReader::TERMVECTOR)
+ && fi->storeTermVector == true
+ && fi->storePositionWithTermVector == false
+ && fi->storeOffsetWithTermVector == false) {
+ v = true;
+ }
+
+ if (fi->isIndexed && fi->storeTermVector
+ && (fldOption & IndexReader::INDEXED_WITH_TERMVECTOR)) {
+ v = true;
+ }
+
+ if (fi->storePositionWithTermVector
+ && fi->storeOffsetWithTermVector == false
+ && (fldOption & IndexReader::TERMVECTOR_WITH_POSITION)) {
+ v = true;
+ }
+
+ if (fi->storeOffsetWithTermVector
+ && fi->storePositionWithTermVector == false
+ && (fldOption & IndexReader::TERMVECTOR_WITH_OFFSET)) {
+ v = true;
+ }
+
+ if ((fi->storeOffsetWithTermVector && fi->storePositionWithTermVector)
+ && (fldOption & IndexReader::TERMVECTOR_WITH_POSITION_OFFSET)) {
+ v = true;
+ }
+ }
+
+ if (v)
+ retarray.push_back(STRDUP_TtoT(fi->name));
+ }
+}
+
+bool SegmentReader::hasNorms(const TCHAR* field) const
+{
+ return _norms.find(field) != _norms.end();
+}
+
+
+void SegmentReader::norms(const TCHAR* field, uint8_t* bytes)
+{
+ //Func - Reads the Norms for field from disk starting at offset in the inputstream
+ //Pre - field != NULL
+ // bytes != NULL is an array of bytes which is to be used to read the norms into.
+ // it is advisable to have bytes initalized by zeroes!
+ //Post - The if an inputstream to the norm file could be retrieved the bytes have been read
+ // You are never sure whether or not the norms have been read into bytes properly!!!!!!!!!!!!!!!!!
+
+ CND_PRECONDITION(field != NULL, "field is NULL");
+ CND_PRECONDITION(bytes != NULL, "field is NULL");
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ Norm* norm = _norms.get(field);
+ if ( norm == NULL ){
+ memcpy(bytes, fakeNorms(), maxDoc());
+ return;
+ }
+
+ if (norm->bytes != NULL) { // can copy from cache
+ memcpy(bytes, norm->bytes, maxDoc());
+ return;
+ }
+
+ IndexInput* _normStream = norm->in->clone();
+ CND_PRECONDITION(_normStream != NULL, "normStream==NULL")
+
+ // read from disk
+ try {
+ _normStream->seek(0);
+ _normStream->readBytes(bytes, maxDoc());
+ } _CLFINALLY (
+ //Have the normstream closed
+ _normStream->close();
+ //Destroy the normstream
+ _CLDELETE( _normStream );
+ );
+}
+
+uint8_t* SegmentReader::createFakeNorms(int32_t size)
+{
+ uint8_t* ones = _CL_NEWARRAY(uint8_t,size);
+ memset(ones, DefaultSimilarity::encodeNorm(1.0f), size);
+ return ones;
+}
+
+uint8_t* SegmentReader::fakeNorms()
+{
+ if (ones == NULL)
+ ones = createFakeNorms(maxDoc());
+ return ones;
+}
+
+// can return null if norms aren't stored
+uint8_t* SegmentReader::getNorms(const TCHAR* field)
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ Norm* norm = _norms.get(field);
+ if (norm == NULL)
+ return NULL; // not indexed, or norms not stored
+
+ if (norm->bytes == NULL) { // value not yet read
+ uint8_t* bytes = _CL_NEWARRAY(uint8_t, maxDoc());
+ norms(field, bytes);
+ norm->bytes = bytes; // cache it
+ }
+ return norm->bytes;
+}
+
+uint8_t* SegmentReader::norms(const TCHAR* field)
+{
+ //Func - Returns the bytes array that holds the norms of a named field
+ //Pre - field != NULL and contains the name of the field for which the norms
+ // must be retrieved
+ //Post - If there was norm for the named field then a bytes array has been allocated
+ // and returned containing the norms for that field. If the named field is unknown NULL is returned.
+
+ CND_PRECONDITION(field != NULL, "field is NULL");
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ uint8_t* bytes = getNorms(field);
+ if (bytes == NULL)
+ bytes = fakeNorms();
+ return bytes;
+}
+
+void SegmentReader::doSetNorm(int32_t doc, const TCHAR* field, uint8_t value)
+{
+ Norm* norm = _norms.get(field);
+ if (norm == NULL) // not an indexed field
+ return;
+
+ norm->dirty = true; // mark it dirty
+ normsDirty = true;
+
+ uint8_t* bits = norms(field);
+ bits[doc] = value; // set the value
+}
+
+QString SegmentReader::SegmentName(const QString& ext, const int32_t x)
+{
+ //Func - Returns an allocated buffer in which it creates a filename by
+ // concatenating segment with ext and x
+ //Pre ext != NULL and holds the extension
+ // x contains a number
+ //Post - A buffer has been instantiated an when x = -1 buffer contains the concatenation of
+ // segment and ext otherwise buffer contains the contentation of segment, ext and x
+
+ CND_PRECONDITION(!ext.isEmpty(), "ext is NULL");
+
+ QString buf;
+ SegmentName(buf, CL_MAX_PATH, ext, x);
+ return buf;
+}
+
+void SegmentReader::SegmentName(QString& buffer, int32_t bufferLen,
+ const QString& ext, const int32_t x)
+{
+ //Func - Creates a filename in buffer by concatenating segment with ext and x
+ //Pre - buffer != NULL
+ // ext != NULL
+ // x contains a number
+ //Post - When x = -1 buffer contains the concatenation of segment and ext otherwise
+ // buffer contains the contentation of segment, ext and x
+
+ CND_PRECONDITION(!segment.isEmpty(), "Segment is NULL");
+
+ Misc::segmentname(buffer, bufferLen, segment, ext, x);
+}
+
+void SegmentReader::openNorms(Directory* cfsDir)
+{
+ //Func - Open all norms files for all fields
+ // Creates for each field a norm Instance with an open inputstream to
+ // a corresponding norm file ready to be read
+ //Pre - true
+ //Post - For each field a norm instance has been created with an open inputstream to
+ // a corresponding norm file ready to be read
+
+ //Iterate through all the fields
+ for (int32_t i = 0; i < fieldInfos->size(); i++) {
+ //Get the FieldInfo for the i-th field
+ FieldInfo* fi = fieldInfos->fieldInfo(i);
+ //Check if the field is indexed
+ if (fi->isIndexed && !fi->omitNorms ) {
+ //Allocate a buffer
+ QString fileName;
+
+ // look first if there are separate norms in compound format
+ SegmentName(fileName, CL_MAX_PATH, QLatin1String(".s"), fi->number);
+ Directory* d = getDirectory();
+ if(!d->fileExists(fileName)){
+ SegmentName(fileName, CL_MAX_PATH, QLatin1String(".f"), fi->number);
+ d = cfsDir;
+ }
+
+ _norms.put(fi->name, _CLNEW Norm(d->openInput(fileName),
+ fi->number, this, segment));
+ }
+ }
+}
+
+void SegmentReader::closeNorms()
+{
+ //Func - Close all the norms stored in norms
+ //Pre - true
+ //Post - All the norms have been destroyed
+
+ SCOPED_LOCK_MUTEX(_norms.THIS_LOCK)
+
+ //Create an interator initialized at the beginning of norms
+ NormsType::iterator itr = _norms.begin();
+ //Iterate through all the norms
+ while (itr != _norms.end()) {
+ // Get, delete the norm
+ _CLDELETE(itr->second);
+ // Move the interator to the next norm in the norms collection.
+ // Note ++ is an overloaded operator
+ ++itr;
+ }
+ _norms.clear(); //bvk: they're deleted, so clear them so that they are not re-used
+}
+
+TermVectorsReader* SegmentReader::getTermVectorsReader()
+{
+ TermVectorsReader* tvReader = termVectorsLocal.get();
+ if (tvReader == NULL) {
+ tvReader = termVectorsReaderOrig->clone();
+ termVectorsLocal.set(tvReader);
+ }
+ return tvReader;
+}
+
+TermFreqVector* SegmentReader::getTermFreqVector(int32_t docNumber,
+ const TCHAR* field)
+{
+ if (field) {
+ FieldInfo* fi = fieldInfos->fieldInfo(field);
+ // Check if this field is invalid or has no stored term vector
+ if (fi == NULL || !fi->storeTermVector || termVectorsReaderOrig == NULL)
+ return NULL;
+ }
+
+ TermVectorsReader* termVectorsReader = getTermVectorsReader();
+ if (termVectorsReader == NULL)
+ return NULL;
+
+ return termVectorsReader->get(docNumber, field);
+}
+
+bool SegmentReader::getTermFreqVectors(int32_t docNumber,
+ Array<TermFreqVector*>& result)
+{
+ if (termVectorsReaderOrig == NULL)
+ return false;
+
+ TermVectorsReader* termVectorsReader = getTermVectorsReader();
+ if (termVectorsReader == NULL)
+ return false;
+
+ return termVectorsReader->get(docNumber, result);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentTermDocs.cpp b/3rdparty/clucene/src/CLucene/index/SegmentTermDocs.cpp
new file mode 100644
index 000000000..50951e9ba
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentTermDocs.cpp
@@ -0,0 +1,216 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "SegmentHeader.h"
+
+#include "CLucene/store/IndexInput.h"
+#include "Term.h"
+
+CL_NS_DEF(index)
+
+ SegmentTermDocs::SegmentTermDocs(const SegmentReader* _parent){
+ //Func - Constructor
+ //Pre - Paren != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(_parent != NULL,"Parent is NULL");
+
+ parent = _parent;
+ deletedDocs = parent->deletedDocs;
+
+ _doc = 0;
+ _freq = 0;
+ count = 0;
+ df = 0;
+
+ skipInterval=0;
+ numSkips=0;
+ skipCount=0;
+ skipStream=NULL;
+ skipDoc=0;
+ freqPointer=0;
+ proxPointer=0;
+ skipPointer=0;
+ haveSkipped=false;
+
+ freqStream = parent->freqStream->clone();
+ skipInterval = parent->tis->getSkipInterval();
+ }
+
+ SegmentTermDocs::~SegmentTermDocs() {
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ close();
+ }
+
+ TermPositions* SegmentTermDocs::__asTermPositions(){
+ return NULL;
+ }
+
+ void SegmentTermDocs::seek(Term* term) {
+ TermInfo* ti = parent->tis->get(term);
+ seek(ti);
+ _CLDELETE(ti);
+ }
+
+ void SegmentTermDocs::seek(TermEnum* termEnum){
+ TermInfo* ti=NULL;
+
+ // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs
+ if ( termEnum->getObjectName() == SegmentTermEnum::getClassName() ){
+ SegmentTermEnum* te = (SegmentTermEnum*)termEnum;
+ te->fieldInfos = parent->fieldInfos;
+ ti = te->getTermInfo();
+ }else{
+ ti = parent->tis->get(termEnum->term(false));
+ }
+
+ seek(ti);
+ _CLDELETE(ti);
+ }
+ void SegmentTermDocs::seek(const TermInfo* ti) {
+ count = 0;
+ if (ti == NULL) {
+ df = 0;
+ } else {
+ df = ti->docFreq;
+ _doc = 0;
+ skipDoc = 0;
+ skipCount = 0;
+ numSkips = df / skipInterval;
+ freqPointer = ti->freqPointer;
+ proxPointer = ti->proxPointer;
+ skipPointer = freqPointer + ti->skipOffset;
+ freqStream->seek(freqPointer);
+ haveSkipped = false;
+ }
+ }
+
+ void SegmentTermDocs::close() {
+
+ //Check if freqStream still exists
+ if (freqStream != NULL){
+ freqStream->close(); //todo: items like these can probably be delete, because deleting the object also closes it...do everywhere
+ _CLDELETE( freqStream );
+ }
+ if (skipStream != NULL){
+ skipStream->close();
+ _CLDELETE( skipStream );
+ }
+ }
+
+ int32_t SegmentTermDocs::doc()const {
+ return _doc;
+ }
+ int32_t SegmentTermDocs::freq()const {
+ return _freq;
+ }
+
+
+bool SegmentTermDocs::next()
+{
+ while (true) {
+ if (count == df)
+ return false;
+
+ uint32_t docCode = freqStream->readVInt();
+ _doc += docCode >> 1; //unsigned shift
+ if ((docCode & 1) != 0) // if low bit is set
+ _freq = 1; // _freq is one
+ else
+ _freq = freqStream->readVInt(); // else read _freq
+ count++;
+
+ if (deletedDocs == NULL || (_doc >= 0 && !deletedDocs->get(_doc)))
+ break;
+ skippingDoc();
+ }
+ return true;
+}
+
+
+int32_t SegmentTermDocs::read(int32_t* docs, int32_t* freqs, int32_t length)
+{
+ int32_t i = 0;
+ // TODO: one optimization would be to get the pointer buffer for ram or mmap
+ // dirs and iterate over them instead of using readByte() intensive functions.
+ while (i < length && count < df) {
+ uint32_t docCode = freqStream->readVInt();
+ _doc += docCode >> 1;
+ if ((docCode & 1) != 0) // if low bit is set
+ _freq = 1; // _freq is one
+ else
+ _freq = freqStream->readVInt(); // else read _freq
+ count++;
+
+ if (deletedDocs == NULL || (_doc >= 0 && !deletedDocs->get(_doc))) {
+ docs[i] = _doc;
+ freqs[i] = _freq;
+ i++;
+ }
+ }
+ return i;
+}
+
+ bool SegmentTermDocs::skipTo(const int32_t target){
+ if (df >= skipInterval) { // optimized case
+ if (skipStream == NULL)
+ skipStream = freqStream->clone(); // lazily clone
+
+ if (!haveSkipped) { // lazily seek skip stream
+ skipStream->seek(skipPointer);
+ haveSkipped = true;
+ }
+
+ // scan skip data
+ int32_t lastSkipDoc = skipDoc;
+ int64_t lastFreqPointer = freqStream->getFilePointer();
+ int64_t lastProxPointer = -1;
+ int32_t numSkipped = -1 - (count % skipInterval);
+
+ while (target > skipDoc) {
+ lastSkipDoc = skipDoc;
+ lastFreqPointer = freqPointer;
+ lastProxPointer = proxPointer;
+
+ if (skipDoc != 0 && skipDoc >= _doc)
+ numSkipped += skipInterval;
+
+ if(skipCount >= numSkips)
+ break;
+
+ skipDoc += skipStream->readVInt();
+ freqPointer += skipStream->readVInt();
+ proxPointer += skipStream->readVInt();
+
+ skipCount++;
+ }
+
+ // if we found something to skip, then skip it
+ if (lastFreqPointer > freqStream->getFilePointer()) {
+ freqStream->seek(lastFreqPointer);
+ skipProx(lastProxPointer);
+
+ _doc = lastSkipDoc;
+ count += numSkipped;
+ }
+
+ }
+
+ // done skipping, now just scan
+
+ do {
+ if (!next())
+ return false;
+ } while (target > _doc);
+ return true;
+ }
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentTermEnum.cpp b/3rdparty/clucene/src/CLucene/index/SegmentTermEnum.cpp
new file mode 100644
index 000000000..20e286fd1
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentTermEnum.cpp
@@ -0,0 +1,389 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "SegmentTermEnum.h"
+
+#include "Terms.h"
+#include "FieldInfos.h"
+#include "Term.h"
+#include "TermInfo.h"
+#include "TermInfosWriter.h"
+
+CL_NS_USE(store)
+CL_NS_DEF(index)
+
+ SegmentTermEnum::SegmentTermEnum(IndexInput* i, FieldInfos* fis, const bool isi):
+ fieldInfos(fis){
+ //Func - Constructor
+ //Pre - i holds a reference to an instance of IndexInput
+ // fis holds a reference to an instance of FieldInfos
+ // isi
+ //Post - An instance of SegmentTermEnum has been created
+ input = i;
+ position = -1;
+ //Instantiate a Term with empty field, empty text and which is interned (see term.h what interned means)
+ _term = _CLNEW Term;
+ isIndex = isi;
+ termInfo = _CLNEW TermInfo();
+ indexPointer = 0;
+ buffer = NULL;
+ bufferLength = 0;
+ prev = NULL;
+ formatM1SkipInterval = 0;
+
+ //Set isClone to false as the instance is not clone of another instance
+ isClone = false;
+
+
+ int32_t firstInt = input->readInt();
+ if (firstInt >= 0) {
+ // original-format file, without explicit format version number
+ format = 0;
+ size = firstInt;
+
+ // back-compatible settings
+ indexInterval = 128;
+ skipInterval = LUCENE_INT32_MAX_SHOULDBE; // switch off skipTo optimization
+
+ } else {
+ // we have a format version number
+ format = firstInt;
+
+ // check that it is a format we can understand
+ if (format < TermInfosWriter::FORMAT){
+ TCHAR err[30];
+ _sntprintf(err,30,_T("Unknown format version: %d"), format);
+ _CLTHROWT(CL_ERR_Runtime,err);
+ }
+
+ size = input->readLong(); // read the size
+
+ if(format == -1){
+ if (!isIndex) {
+ indexInterval = input->readInt();
+ formatM1SkipInterval = input->readInt();
+ }
+ // switch off skipTo optimization for file format prior to 1.4rc2 in order to avoid a bug in
+ // skipTo implementation of these versions
+ skipInterval = LUCENE_INT32_MAX_SHOULDBE;
+ }else{
+ indexInterval = input->readInt();
+ skipInterval = input->readInt();
+ }
+ }
+ }
+
+ SegmentTermEnum::SegmentTermEnum(const SegmentTermEnum& clone):
+ fieldInfos(clone.fieldInfos)
+ {
+ //Func - Constructor
+ // The instance is created by cloning all properties of clone
+ //Pre - clone holds a valid reference to SegmentTermEnum
+ //Post - An instance of SegmentTermEnum with the same properties as clone
+
+ input = clone.input->clone();
+ //Copy the postion from the clone
+ position = clone.position;
+
+ if ( clone._term != NULL ){
+ _term = _CLNEW Term;
+ _term->set(clone._term,clone._term->text());
+ }else
+ _term = NULL;
+ isIndex = clone.isIndex;
+ termInfo = _CLNEW TermInfo(clone.termInfo);
+ indexPointer = clone.indexPointer;
+ buffer = clone.buffer==NULL?NULL:(TCHAR*)malloc(sizeof(TCHAR) * (clone.bufferLength+1));
+ bufferLength = clone.bufferLength;
+ prev = clone.prev==NULL?NULL:_CLNEW Term(clone.prev->field(),clone.prev->text(),false);
+ size = clone.size;
+
+ format = clone.format;
+ indexInterval= clone.indexInterval;
+ skipInterval = clone.skipInterval;
+ formatM1SkipInterval = clone.formatM1SkipInterval;
+ //Set isClone to true as this instance is a clone of another instance
+ isClone = true;
+
+ //Copy the contents of buffer of clone to the buffer of this instance
+ if ( clone.buffer != NULL )
+ memcpy(buffer,clone.buffer,bufferLength * sizeof(TCHAR));
+ }
+
+ SegmentTermEnum::~SegmentTermEnum(){
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed. If this instance was a clone
+ // then the inputstream is closed and deleted too.
+
+ //todo: revisit this... close() should clean up most of everything.
+
+ //Finalize prev
+ _CLDECDELETE(prev );
+ //Finalize term
+ _CLDECDELETE( _term );
+
+
+ //Delete the buffer if necessary
+ free(buffer);
+ //Delete termInfo if necessary
+ _CLDELETE(termInfo);
+
+ //Check if this instance is a clone
+ if ( isClone ){
+ //Close the inputstream
+ input->close();
+ //delete the inputstream
+ _CLDELETE(input);
+ }
+ }
+
+ bool SegmentTermEnum::next(){
+ //Func - Moves the current of the set to the next in the set
+ //Pre - true
+ //Post - If the end has been reached NULL is returned otherwise the term has
+ // become the next Term in the enumeration
+
+ //Increase position by and and check if the end has been reached
+ if (position++ >= size-1) {
+ //delete term
+ _CLDECDELETE(_term);
+ return false;
+ }
+
+ //delete the previous enumerated term
+ Term* tmp=NULL;
+ if ( prev != NULL ){
+ int32_t usage = prev->__cl_refcount;
+ if ( usage > 1 ){
+ _CLDECDELETE(prev); //todo: tune other places try and delete its term
+ }else
+ tmp = prev; //we are going to re-use this term
+ }
+ //prev becomes the current enumerated term
+ prev = _term;
+ //term becomes the next term read from inputStream input
+ _term = readTerm(tmp);
+
+ //Read docFreq, the number of documents which contain the term.
+ termInfo->docFreq = input->readVInt();
+ //Read freqPointer, a pointer into the TermFreqs file (.frq)
+ termInfo->freqPointer += input->readVLong();
+
+ //Read proxPointer, a pointer into the TermPosition file (.prx).
+ termInfo->proxPointer += input->readVLong();
+
+ if(format == -1){
+ // just read skipOffset in order to increment file pointer;
+ // value is never used since skipTo is switched off
+ if (!isIndex) {
+ if (termInfo->docFreq > formatM1SkipInterval) {
+ termInfo->skipOffset = input->readVInt();
+ }
+ }
+ }else{
+ if (termInfo->docFreq >= skipInterval)
+ termInfo->skipOffset = input->readVInt();
+ }
+
+ //Check if the enumeration is an index
+ if (isIndex)
+ //read index pointer
+ indexPointer += input->readVLong();
+
+ return true;
+ }
+
+ Term* SegmentTermEnum::term() {
+ //Func - Returns the current term.
+ //Pre - pointer is true or false and indicates if the reference counter
+ // of term must be increased or not
+ // next() must have been called once!
+ //Post - pointer = true -> term has been returned with an increased reference counter
+ // pointer = false -> term has been returned
+
+ return _CL_POINTER(_term);
+ }
+ Term* SegmentTermEnum::term(bool pointer) {
+ if ( pointer )
+ return _CL_POINTER(_term);
+ else
+ return _term;
+ }
+
+ void SegmentTermEnum::scanTo(const Term *term){
+ //Func - Scan for Term without allocating new Terms
+ //Pre - term != NULL
+ //Post - The iterator term has been moved to the position where Term is expected to be
+ // in the enumeration
+ while ( term->compareTo(this->_term) > 0 && next())
+ {
+ }
+ }
+
+ void SegmentTermEnum::close() {
+ //Func - Closes the enumeration to further activity, freeing resources.
+ //Pre - true
+ //Post - The inputStream input has been closed
+
+ input->close();
+ }
+
+ int32_t SegmentTermEnum::docFreq() const {
+ //Func - Returns the document frequency of the current term in the set
+ //Pre - termInfo != NULL
+ // next() must have been called once
+ //Post - The document frequency of the current enumerated term has been returned
+
+ return termInfo->docFreq;
+ }
+
+ void SegmentTermEnum::seek(const int64_t pointer, const int32_t p, Term* t, TermInfo* ti) {
+ //Func - Repositions term and termInfo within the enumeration
+ //Pre - pointer >= 0
+ // p >= 0 and contains the new position within the enumeration
+ // t is a valid reference to a Term and is the new current term in the enumeration
+ // ti is a valid reference to a TermInfo and is corresponding TermInfo form the new
+ // current Term
+ //Post - term and terminfo have been repositioned within the enumeration
+
+ //Reset the IndexInput input to pointer
+ input->seek(pointer);
+ //Assign the new position
+ position = p;
+
+ //finalize the current term
+ if ( _term == NULL || _term->__cl_refcount > 1 ){
+ _CLDECDELETE(_term);
+ //Get a pointer from t and increase the reference counter of t
+ _term = _CLNEW Term; //cannot use reference, because TermInfosReader uses non ref-counted array
+ }
+ _term->set(t,t->text());
+
+ //finalize prev
+ _CLDECDELETE(prev);
+
+ //Change the current termInfo so it matches the new current term
+ termInfo->set(ti);
+
+ //Have the buffer grown if needed
+ if ( bufferLength <= _term->textLength() )
+ growBuffer(_term->textLength(), true ); // copy term text into buffer
+ else
+ _tcsncpy(buffer,_term->text(),bufferLength); //just copy the buffer
+ }
+
+ TermInfo* SegmentTermEnum::getTermInfo()const {
+ //Func - Returns a clone of the current termInfo
+ //Pre - termInfo != NULL
+ // next() must have been called once
+ //Post - A clone of the current termInfo has been returned
+
+ return _CLNEW TermInfo(*termInfo); //clone
+ }
+
+ void SegmentTermEnum::getTermInfo(TermInfo* ti)const {
+ //Func - Retrieves a clone of termInfo through the reference ti
+ //Pre - ti contains a valid reference to TermInfo
+ // termInfo != NULL
+ // next() must have been called once
+ //Post - ti contains a clone of termInfo
+
+ ti->set(termInfo);
+ }
+
+ int64_t SegmentTermEnum::freqPointer()const {
+ //Func - Returns the freqpointer of the current termInfo
+ //Pre - termInfo != NULL
+ // next() must have been called once
+ //Post - The freqpointer of the current termInfo has been returned
+
+ return termInfo->freqPointer;
+ }
+
+ int64_t SegmentTermEnum::proxPointer()const {
+ //Func - Returns the proxPointer of the current termInfo
+ //Pre - termInfo != NULL
+ // next() must have been called once
+ //Post - the proxPointer of the current termInfo has been returned
+
+ return termInfo->proxPointer;
+ }
+
+ SegmentTermEnum* SegmentTermEnum::clone() const {
+ //Func - Returns a clone of this instance
+ //Pre - true
+ //Post - An clone of this instance has been returned
+
+ return _CLNEW SegmentTermEnum(*this);
+ }
+
+ Term* SegmentTermEnum::readTerm(Term* reuse) {
+ //Func - Reads the next term in the enumeration
+ //Pre - true
+ //Post - The next Term in the enumeration has been read and returned
+
+ //Read the start position from the inputStream input
+ int32_t start = input->readVInt();
+ //Read the length of term in the inputStream input
+ int32_t length = input->readVInt();
+
+ //Calculated the total lenght of bytes that buffer must be to contain the current
+ //chars in buffer and the new ones yet to be read
+ uint32_t totalLength = start + length;
+
+ if (static_cast<uint32_t>(bufferLength) < totalLength+1)
+ growBuffer(totalLength, false);
+
+ //Read a length number of characters into the buffer from position start in the inputStream input
+ input->readChars(buffer, start, length);
+ //Null terminate the string
+ buffer[totalLength] = 0;
+
+ //Return a new Term
+ int32_t field = input->readVInt();
+ const TCHAR* fieldname = fieldInfos->fieldName(field);
+ if ( reuse == NULL )
+ reuse = _CLNEW Term;
+
+ reuse->set(fieldname, buffer, false);
+ return reuse;
+ }
+
+ void SegmentTermEnum::growBuffer(const uint32_t length, bool force_copy) {
+ //Func - Instantiate a buffer of length length+1
+ //Pre - length > 0
+ //Post - pre(buffer) has been deleted with its contents. A new buffer
+ // has been allocated of length length+1 and the text of term has been copied
+ // to buffer
+ //todo: we could guess that we will need to re-grow this
+ //buffer a few times...so start off with a reasonable grow
+ //value...
+ if ( bufferLength > length )
+ return;
+
+ //Store the new bufferLength
+ if ( length - bufferLength < LUCENE_SEGMENTTERMENUM_GROWSIZE )
+ bufferLength = length+LUCENE_SEGMENTTERMENUM_GROWSIZE;
+ else
+ bufferLength = length+1;
+
+ bool copy = buffer==NULL;
+
+ //Instantiate the new buffer + 1 is needed for terminator '\0'
+ if ( buffer == NULL )
+ buffer = (TCHAR*)malloc(sizeof(TCHAR) * (bufferLength+1));
+ else
+ buffer = (TCHAR*)realloc(buffer, sizeof(TCHAR) * (bufferLength+1));
+
+ if ( copy || force_copy){
+ //Copy the text of term into buffer
+ _tcsncpy(buffer,_term->text(),bufferLength);
+ }
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentTermEnum.h b/3rdparty/clucene/src/CLucene/index/SegmentTermEnum.h
new file mode 100644
index 000000000..0d50103f3
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentTermEnum.h
@@ -0,0 +1,138 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_index_SegmentTermEnum_
+#define _lucene_index_SegmentTermEnum_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "Terms.h"
+#include "FieldInfos.h"
+#include "TermInfo.h"
+
+CL_NS_DEF(index)
+
+/**
+ * SegmentTermEnum is an enumeration of all Terms and TermInfos
+ */
+class SegmentTermEnum:public TermEnum{
+private:
+ Term* _term; ///points to the current Term in the enumeration
+ TermInfo* termInfo; ///points to the TermInfo matching the current Term in the enumeration
+
+ bool isIndex; ///Indicates if the Segment is a an index
+ bool isClone; ///Indicates if SegmentTermEnum is an orignal instance or
+ ///a clone of another SegmentTermEnum
+
+ TCHAR* buffer; ///The buffer that contains the data read from the Term Infos File
+ uint32_t bufferLength; ///Length of the buffer
+
+ int32_t format;
+ int32_t formatM1SkipInterval;
+
+ CL_NS(store)::IndexInput* input; ///The IndexInput that reads from the Term Infos File
+ FieldInfos* fieldInfos; ///contains the Field Infos for the segment
+ int64_t size; ///The size of the enumeration
+ int64_t position; ///The position of the current (term) in the enumeration
+ int64_t indexPointer;
+ Term* prev; ///The previous current
+ int32_t indexInterval;
+ int32_t skipInterval;
+
+ friend class TermInfosReader;
+ friend class SegmentTermDocs;
+protected:
+
+ /**
+ * Constructor.
+ * The instance is created by cloning all properties of clone
+ */
+ SegmentTermEnum( const SegmentTermEnum& clone);
+
+public:
+ ///Constructor
+ SegmentTermEnum(CL_NS(store)::IndexInput* i, FieldInfos* fis, const bool isi );
+
+ ///Destructor
+ ~SegmentTermEnum();
+
+ /**
+ * Moves the current of the set to the next in the set
+ */
+ bool next();
+
+ /**
+ * Returns a pointer to the current term.
+ */
+ Term* term();
+ /**
+ * Returns the current term.
+ */
+ Term* term(bool pointer);
+
+ /**
+ * Scan for Term term without allocating new Terms
+ */
+ void scanTo(const Term *term);
+
+ /**
+ * Closes the enumeration to further activity, freeing resources.
+ */
+ void close();
+
+ /**
+ * Returns the document frequency of the current term in the set
+ */
+ int32_t docFreq() const;
+
+ /**
+ * Repositions term and termInfo within the enumeration
+ */
+ void seek(const int64_t pointer, const int32_t p, Term* t, TermInfo* ti);
+
+ /**
+ * Returns a clone of the current termInfo
+ */
+ TermInfo* getTermInfo()const;
+
+ /**
+ * Retrieves a clone of termInfo through the reference ti
+ */
+ void getTermInfo(TermInfo* ti)const;
+
+ /**
+ * Returns the freqPointer from the current TermInfo in the enumeration.
+ */
+ int64_t freqPointer() const;
+
+ /**
+ * Returns the proxPointer from the current TermInfo in the enumeration.
+ */
+ int64_t proxPointer() const;
+
+ /**
+ * Returns a clone of this instance
+ */
+ SegmentTermEnum* clone() const;
+
+ const char* getObjectName(){ return SegmentTermEnum::getClassName(); }
+ static const char* getClassName(){ return "SegmentTermEnum"; }
+
+private:
+ /**
+ * Reads the next term in the enumeration
+ */
+ Term* readTerm(Term* reuse);
+ /**
+ * Instantiate a buffer of length length+1
+ */
+ void growBuffer(const uint32_t length, bool force_copy);
+
+};
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentTermPositions.cpp b/3rdparty/clucene/src/CLucene/index/SegmentTermPositions.cpp
new file mode 100644
index 000000000..e481838e9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentTermPositions.cpp
@@ -0,0 +1,101 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "SegmentHeader.h"
+
+#include "Terms.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+SegmentTermPositions::SegmentTermPositions(const SegmentReader* _parent):
+ SegmentTermDocs(_parent){
+//Func - Constructor
+//Pre - Parent != NULL
+//Post - The instance has been created
+
+ CND_PRECONDITION(_parent != NULL, "Parent is NULL");
+
+ proxStream = _parent->proxStream->clone();
+
+ CND_CONDITION(proxStream != NULL,"proxStream is NULL");
+
+ position = 0;
+ proxCount = 0;
+}
+
+SegmentTermPositions::~SegmentTermPositions() {
+//Func - Destructor
+//Pre - true
+//Post - The intance has been closed
+ close();
+}
+
+TermDocs* SegmentTermPositions::__asTermDocs(){
+ return (TermDocs*) this;
+}
+TermPositions* SegmentTermPositions::__asTermPositions(){
+ return (TermPositions*) this;
+}
+
+void SegmentTermPositions::seek(const TermInfo* ti) {
+ SegmentTermDocs::seek(ti);
+ if (ti != NULL)
+ proxStream->seek(ti->proxPointer);
+ proxCount = 0;
+}
+
+void SegmentTermPositions::close() {
+//Func - Frees the resources
+//Pre - true
+//Post - The resources have been freed
+
+ SegmentTermDocs::close();
+ //Check if proxStream still exists
+ if(proxStream){
+ proxStream->close();
+ _CLDELETE( proxStream );
+ }
+}
+
+int32_t SegmentTermPositions::nextPosition() {
+ /* DSR:CL_BUG: Should raise exception if proxCount == 0 at the
+ ** beginning of this method, as in
+ ** if (--proxCount == 0) throw ...;
+ ** The JavaDocs for TermPositions.nextPosition declare this constraint,
+ ** but CLucene doesn't enforce it. */
+ proxCount--;
+ return position += proxStream->readVInt();
+}
+
+bool SegmentTermPositions::next() {
+ for (int32_t f = proxCount; f > 0; f--) // skip unread positions
+ proxStream->readVInt();
+
+ if (SegmentTermDocs::next()) { // run super
+ proxCount = _freq; // note frequency
+ position = 0; // reset position
+ return true;
+ }
+ return false;
+}
+
+int32_t SegmentTermPositions::read(int32_t* docs, int32_t* freqs, int32_t length) {
+ _CLTHROWA(CL_ERR_InvalidState,"TermPositions does not support processing multiple documents in one call. Use TermDocs instead.");
+}
+
+void SegmentTermPositions::skippingDoc() {
+ for (int32_t f = _freq; f > 0; f--) // skip all positions
+ proxStream->readVInt();
+}
+
+void SegmentTermPositions::skipProx(int64_t proxPointer){
+ proxStream->seek(proxPointer);
+ proxCount = 0;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentTermVector.cpp b/3rdparty/clucene/src/CLucene/index/SegmentTermVector.cpp
new file mode 100644
index 000000000..5e9ac3c3b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/SegmentTermVector.cpp
@@ -0,0 +1,188 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "TermVector.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+Array<int32_t> SegmentTermPositionVector::EMPTY_TERM_POS;
+
+SegmentTermVector::SegmentTermVector(const TCHAR* field, TCHAR** terms, Array<int32_t>* termFreqs) {
+ this->field = STRDUP_TtoT(field);
+ this->terms = terms;
+ this->termsLen = -1; //lazily get the size of the terms
+ this->termFreqs = termFreqs;
+}
+
+SegmentTermVector::~SegmentTermVector(){
+ _CLDELETE_CARRAY(field);
+ _CLDELETE_CARRAY_ALL(terms);
+
+ _CLDELETE_ARRAY(termFreqs->values);
+ _CLDELETE(termFreqs);
+}
+TermPositionVector* SegmentTermVector::__asTermPositionVector(){
+ return NULL;
+}
+
+const TCHAR* SegmentTermVector::getField() {
+return field;
+}
+
+TCHAR* SegmentTermVector::toString() const{
+StringBuffer sb;
+sb.appendChar('{');
+sb.append(field);
+sb.append(_T(": "));
+
+int32_t i=0;
+while ( terms && terms[i] != NULL ){
+ if (i>0)
+ sb.append(_T(", "));
+ sb.append(terms[i]);
+ sb.appendChar('/');
+
+ sb.appendInt((*termFreqs)[i]);
+}
+sb.appendChar('}');
+return sb.toString();
+}
+
+int32_t SegmentTermVector::size() {
+if ( terms == NULL )
+ return 0;
+
+if ( termsLen == -1 ){
+ termsLen=0;
+ while ( terms[termsLen] != 0 )
+ termsLen++;
+}
+return termsLen;
+}
+
+const TCHAR** SegmentTermVector::getTerms() {
+ return (const TCHAR**)terms;
+}
+
+const Array<int32_t>* SegmentTermVector::getTermFrequencies() {
+ return termFreqs;
+}
+
+int32_t SegmentTermVector::binarySearch(TCHAR** a, const int32_t arraylen, const TCHAR* key) const
+{
+ int32_t low = 0;
+ int32_t hi = arraylen - 1;
+ int32_t mid = 0;
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+
+ int32_t c = _tcscmp(a[mid],key);
+ if (c==0)
+ return mid;
+ else if (c > 0)
+ hi = mid - 1;
+ else // This gets the insertion point right on the last loop.
+ low = ++mid;
+ }
+ return -mid - 1;
+}
+
+int32_t SegmentTermVector::indexOf(const TCHAR* termText) {
+ if(terms == NULL)
+ return -1;
+ int32_t res = binarySearch(terms, size(), termText);
+ return res >= 0 ? res : -1;
+}
+
+void SegmentTermVector::indexesOf(const TCHAR** termNumbers, const int32_t start, const int32_t len, Array<int32_t>& ret) {
+ // TODO: there must be a more efficient way of doing this.
+ // At least, we could advance the lower bound of the terms array
+ // as we find valid indexes. Also, it might be possible to leverage
+ // this even more by starting in the middle of the termNumbers array
+ // and thus dividing the terms array maybe in half with each found index.
+ ret.length = len;
+ ret.values = _CL_NEWARRAY(int32_t,len);
+ for (int32_t i=0; i<len; ++i) {
+ ret.values[i] = indexOf(termNumbers[start+ i]);
+ }
+}
+
+
+
+
+SegmentTermPositionVector::SegmentTermPositionVector(const TCHAR* field, TCHAR** terms, Array<int32_t>* termFreqs, Array< Array<int32_t> >* positions, Array< Array<TermVectorOffsetInfo> >* offsets):
+ SegmentTermVector(field,terms,termFreqs)
+{
+ this->offsets = offsets;
+ this->positions = positions;
+}
+
+SegmentTermPositionVector::~SegmentTermPositionVector(){
+ if ( offsets ){
+ for (size_t i=0;i<offsets->length;i++){
+ if ( offsets->values != NULL ){
+ Array<TermVectorOffsetInfo>& offs = offsets->values[i];
+ for ( size_t j=0;j<offs.length;j++ ){
+ _CLDELETE_ARRAY(offs.values);
+ }
+ }
+ }
+ _CLDELETE_ARRAY(offsets->values);
+ _CLDELETE(offsets);
+ }
+ if ( positions ){
+ for (size_t i=0;i<positions->length;i++){
+ if ( positions->values != NULL ){
+ Array<int32_t>& pos = positions->values[i];
+ for ( size_t j=0;j<pos.length;j++ ){
+ _CLDELETE_ARRAY(pos.values);
+ }
+ }
+ }
+ _CLDELETE_ARRAY(positions->values);
+ _CLDELETE(positions);
+ }
+}
+
+TermPositionVector* SegmentTermPositionVector::__asTermPositionVector(){
+ return this;
+}
+/**
+* Returns an array of TermVectorOffsetInfo in which the term is found.
+*
+* @param index The position in the array to get the offsets from
+* @return An array of TermVectorOffsetInfo objects or the empty list
+* @see org.apache.lucene.analysis.Token
+*/
+Array<TermVectorOffsetInfo>* SegmentTermPositionVector::getOffsets(int32_t index) {
+ if(offsets == NULL)
+ return NULL;
+ if (index >=0 && index < offsets->length)
+ return &offsets->values[index];
+ else
+ return &TermVectorOffsetInfo::EMPTY_OFFSET_INFO;
+}
+
+/**
+* Returns an array of positions in which the term is found.
+* Terms are identified by the index at which its number appears in the
+* term String array obtained from the <code>indexOf</code> method.
+*/
+Array<int32_t>* SegmentTermPositionVector::getTermPositions(int32_t index) {
+ if(positions == NULL)
+ return NULL;
+
+ if (index >=0 && index < positions->length)
+ return &positions->values[index];
+ else
+ return &EMPTY_TERM_POS;
+}
+CL_NS_END
+
diff --git a/3rdparty/clucene/src/CLucene/index/Term.cpp b/3rdparty/clucene/src/CLucene/index/Term.cpp
new file mode 100644
index 000000000..5ff7bb264
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/Term.cpp
@@ -0,0 +1,182 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+
+#include "CLucene/StdHeader.h"
+#include "Term.h"
+#include "CLucene/util/StringIntern.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+Term::Term()
+{
+ init();
+}
+
+Term::Term(const TCHAR* fld, const TCHAR* txt, bool internField)
+{
+ init();
+ set(fld, txt, internField);
+}
+
+Term::Term(const Term* fieldTerm, const TCHAR* txt)
+{
+ init();
+ set(fieldTerm, txt);
+}
+
+Term::Term(const TCHAR* fld, const TCHAR* txt)
+{
+ init();
+ set(fld, txt);
+}
+
+Term::~Term()
+{
+ if (internF)
+ CLStringIntern::unintern(_field);
+ _field = NULL;
+
+#ifndef LUCENE_TERM_TEXT_LENGTH
+ if (_text != LUCENE_BLANK_STRING)
+ _CLDELETE_CARRAY(_text);
+#endif
+}
+
+const TCHAR* Term::field() const
+{
+ return _field;
+}
+
+const TCHAR* Term::text() const
+{
+ return _text;
+}
+
+void Term::set(const Term* term, const TCHAR* txt)
+{
+ set(term->field(), txt, false);
+}
+
+void Term::set(const TCHAR* fld, const TCHAR* txt,bool internField)
+{
+ CND_PRECONDITION(fld != NULL, "fld contains NULL");
+ CND_PRECONDITION(txt != NULL, "txt contains NULL");
+
+ //save field for unintern later
+ const TCHAR* oldField = _field;
+ cachedHashCode = 0;
+ textLen = _tcslen(txt);
+
+ //Delete text if it is the owner
+#ifdef LUCENE_TERM_TEXT_LENGTH
+ if (textLen > LUCENE_TERM_TEXT_LENGTH)
+ textLen = LUCENE_TERM_TEXT_LENGTH;
+
+ _tcsncpy(_text,txt,textLen+1);
+ _text[textLen]=0;
+#else
+ //if the term text buffer is bigger than what we have
+ if (_text && textLen > textLenBuf) {
+ if (_text != LUCENE_BLANK_STRING) {
+ _CLDELETE_ARRAY(_text);
+ } else {
+ _text = NULL;
+ }
+ textLenBuf = 0;
+ }
+
+ if (_text == LUCENE_BLANK_STRING) {
+ _text = LUCENE_BLANK_STRING;
+ } else if (_text == NULL) {
+ if (txt[0] == 0) {
+ //if the string is blank and we aren't re-using the buffer...
+ _text = LUCENE_BLANK_STRING;
+ } else {
+ //duplicate the text
+ _text = stringDuplicate(txt);
+ textLenBuf = textLen;
+ }
+ } else {
+ //re-use the buffer
+ _tcscpy(_text,txt);
+ }
+#endif
+
+ //Set Term Field
+ if (internField) {
+ _field = CLStringIntern::intern(fld CL_FILELINE);
+ } else {
+ _field = fld;
+ }
+
+ //unintern old field after interning new one,
+ if (internF)
+ CLStringIntern::unintern(oldField);
+ internF = internField;
+
+ CND_PRECONDITION(_tcscmp(fld, _field) == 0, "field not equal");
+}
+
+bool Term::equals(const Term* other) const
+{
+ if (cachedHashCode != 0 && other->cachedHashCode != 0
+ && other->cachedHashCode != cachedHashCode)
+ return false;
+
+ if (_field == other->_field) {
+ if (textLen == other->textLen)
+ return (_tcscmp(_text, other->_text) == 0);
+ return false;
+ }
+
+ return false;
+}
+
+size_t Term::hashCode()
+{
+ if (cachedHashCode == 0)
+ cachedHashCode = Misc::thashCode(_field) + Misc::thashCode(_text, textLen);
+
+ return cachedHashCode;
+}
+
+int32_t Term::compareTo(const Term* other) const
+{
+ //Check ret to see if text needs to be compared
+ if (_field == other->_field)
+ return _tcscmp(_text, other->_text);
+
+ int32_t ret = _tcscmp(_field, other->_field);
+ if (ret == 0)
+ ret = _tcscmp(_text, other->_text);
+ return ret;
+}
+
+TCHAR* Term::toString() const
+{
+ return CL_NS(util)::Misc::join(_field, _T(":"), _text);
+}
+
+void Term::init()
+{
+ textLen = 0;
+ internF = false;
+ cachedHashCode = 0;
+ _field = LUCENE_BLANK_STRING;
+
+#ifdef LUCENE_TERM_TEXT_LENGTH
+ _text[0] = 0;
+#else
+ _text = LUCENE_BLANK_STRING;
+ textLenBuf = 0;
+#endif
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/Term.h b/3rdparty/clucene/src/CLucene/index/Term.h
new file mode 100644
index 000000000..68eefd194
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/Term.h
@@ -0,0 +1,146 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#ifndef _lucene_index_Term_
+#define _lucene_index_Term_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/Misc.h"
+#include "CLucene/util/StringIntern.h"
+
+CL_NS_DEF(index)
+
+/*
+A Term represents a word from text. This is the unit of search. It is
+composed of two elements, the text of the word, as a string, and the name of
+the field that the text occured in, an interned string.
+
+Note that terms may represent more than words from text fields, but also
+things like dates, email addresses, urls, etc.
+
+IMPORTANT NOTE:
+Term inherits from the template class LUCENE_REFBASE which tries to do
+some garbage collection by counting the references an instance has. As a result
+of this construction you MUST use _CLDECDELETE(obj) when you want to delete an
+of Term!
+
+ABOUT intrn
+
+intrn indicates if field and text are interned or not. Interning of Strings
+is the process of converting duplicated strings to shared ones.
+
+*/
+class Term : LUCENE_REFBASE
+{
+private:
+ const TCHAR* _field;
+ bool internF; // Indicates if Term Field is interned(and therefore must be uninternd).
+ size_t cachedHashCode;
+ size_t textLen; // a cache of text len, this allows for a preliminary comparison of text lengths
+
+#ifdef LUCENE_TERM_TEXT_LENGTH
+ TCHAR _text[LUCENE_TERM_TEXT_LENGTH + 1];
+#else
+ TCHAR* _text;
+ size_t textLenBuf; //a cache of text len, this allows for a preliminary comparison of text lengths
+#endif
+
+ void init();
+public:
+
+ //uses the specified fieldTerm's field. this saves on intern'ing time.
+ Term(const Term* fieldTerm, const TCHAR* txt);
+
+ ///Constructs a blank term
+ Term();
+
+ // TODO: need to be private, a few other things need to be changed first...
+ Term(const TCHAR* fld, const TCHAR* txt, bool internField);
+
+ /**
+ * Constructor. Constructs a Term with the given field and text. Field and
+ * text are not copied Field and text are deleted in destructor only if
+ * intern is false.
+ */
+ Term(const TCHAR* fld, const TCHAR* txt);
+
+ ///Destructor.
+ ~Term();
+
+ ///Returns the field of this term, an interned string. The field indicates
+ ///the part of a document which this term came from.
+ const TCHAR* field() const; ///<returns reference
+
+ ///Returns the text of this term. In the case of words, this is simply the
+ ///text of the word. In the case of dates and other types, this is an
+ ///encoding of the object as a string.
+ const TCHAR* text() const; ///<returns reference
+
+ ///Resets the field and text of a Term.
+ inline void set(const TCHAR* fld, const TCHAR* txt)
+ {
+ set(fld, txt, true);
+ }
+
+ /**
+ * Optimized set of Term by reusing same field as this Term
+ * - avoids field.intern() overhead
+ * @param text The text of the new term
+ * (field is implicitly same as this Term instance)
+ */
+ void set(const Term* term, const TCHAR* txt);
+
+ void set(const TCHAR* fld, const TCHAR* txt, bool internField);
+
+ /** Compares two terms, returning a negative integer if this
+ term belongs before the argument, zero if this term is equal to the
+ argument, and a positive integer if this term belongs after the argument.
+
+ The ordering of terms is first by field, then by text.*/
+ int32_t compareTo(const Term* other) const;
+
+ bool equals(const Term* other) const;
+
+ size_t textLength() const { return textLen; }
+
+ ///Forms the contents of Field and term in some kind of tuple notation
+ ///<field:text>
+ TCHAR* toString() const;
+
+ size_t hashCode();
+
+ class Equals:public CL_NS_STD(binary_function)<const Term*,const Term*,bool>
+ {
+ public:
+ bool operator()( const Term* val1, const Term* val2 ) const
+ {
+ return val1->equals(val2);
+ }
+ };
+
+ class Compare:LUCENE_BASE, public CL_NS(util)::Compare::_base //<Term*>
+ {
+ public:
+ bool operator()(Term* t1, Term* t2) const
+ {
+ return (t1->compareTo(t2) < 0);
+ }
+
+ size_t operator()(Term* t) const
+ {
+ return t->hashCode();
+ }
+ };
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/TermInfo.cpp b/3rdparty/clucene/src/CLucene/index/TermInfo.cpp
new file mode 100644
index 000000000..ac1107317
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermInfo.cpp
@@ -0,0 +1,53 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+
+#include "CLucene/StdHeader.h"
+#include "TermInfo.h"
+
+CL_NS_DEF(index)
+
+TermInfo::TermInfo()
+{
+ set(0, 0, 0, 0);
+}
+
+TermInfo::~TermInfo()
+{
+}
+
+TermInfo::TermInfo(int32_t df, int64_t fp, int64_t pp)
+{
+ set(df, fp, pp, 0);
+}
+
+TermInfo::TermInfo(const TermInfo* ti)
+{
+ if (ti)
+ set(ti);
+}
+
+void TermInfo::set(const TermInfo* ti)
+{
+ if (ti)
+ set(ti->docFreq, ti->freqPointer, ti->proxPointer, ti->skipOffset);
+}
+
+void TermInfo::set(int32_t df, int64_t fp, int64_t pp, int32_t so)
+{
+ CND_PRECONDITION(df >= 0, "df contains negative number");
+ CND_PRECONDITION(fp >= 0, "fp contains negative number");
+ CND_PRECONDITION(pp >= 0, "pp contains negative number");
+
+ docFreq = df;
+ freqPointer = fp;
+ proxPointer = pp;
+ skipOffset = so;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/TermInfo.h b/3rdparty/clucene/src/CLucene/index/TermInfo.h
new file mode 100644
index 000000000..57b7a9a76
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermInfo.h
@@ -0,0 +1,61 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#ifndef _lucene_index_TermInfo
+#define _lucene_index_TermInfo
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF(index)
+
+// A TermInfo is the record of information stored for a term.
+class TermInfo : LUCENE_BASE
+{
+public:
+ // The number of documents which contain the term.
+ int32_t docFreq;
+
+ //A pointer into the TermFreqs file (.frq)
+ //The .frq file contains the lists of documents which contain each term,
+ //along with the frequency of the term in that document.
+ int64_t freqPointer;
+
+ //A pointer into the TermPosition file (.prx).
+ //The .prx file contains the lists of positions that each term
+ //occurs at within documents.
+ int64_t proxPointer;
+
+ int32_t skipOffset;
+
+ //Constructor
+ TermInfo();
+
+ //Constructor
+ TermInfo(int32_t df, int64_t fp, int64_t pp);
+
+ //Constructor
+ //Initialises this instance by copying the values of another TermInfo ti
+ TermInfo(const TermInfo* ti);
+
+ //Destructor
+ ~TermInfo();
+
+ //Sets a new document frequency, a new freqPointer and a new proxPointer
+ void set(int32_t docFreq, int64_t freqPointer, int64_t proxPointer,
+ int32_t skipOffset);
+
+ //Sets a new document frequency, a new freqPointer and a new proxPointer
+ //by copying these values from another instance of TermInfo
+ void set(const TermInfo* ti);
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/TermInfosReader.cpp b/3rdparty/clucene/src/CLucene/index/TermInfosReader.cpp
new file mode 100644
index 000000000..8f9e43dec
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermInfosReader.cpp
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "TermInfosReader.h"
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/util/Misc.h"
+#include "FieldInfos.h"
+#include "Term.h"
+#include "Terms.h"
+#include "TermInfo.h"
+#include "TermInfosWriter.h"
+
+CL_NS_USE(store)
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+TermInfosReader::TermInfosReader(Directory* dir, const QString& seg,
+ FieldInfos* fis)
+ : directory(dir)
+ , fieldInfos (fis)
+{
+ //Func - Constructor.
+ // Reads the TermInfos file (.tis) and eventually the Term Info Index file (.tii)
+ //Pre - dir is a reference to a valid Directory
+ // Fis contains a valid reference to an FieldInfos instance
+ // seg != NULL and contains the name of the segment
+ //Post - An instance has been created and the index named seg has been read. (Remember
+ // a segment is nothing more then an independently readable index)
+
+ CND_PRECONDITION(!seg.isEmpty(), "seg is NULL");
+
+ //Initialize the name of the segment
+ segment = seg;
+ //There are no indexTerms yet
+ indexTerms = NULL;
+ //So there are no indexInfos
+ indexInfos = NULL;
+ //So there are no indexPointers
+ indexPointers = NULL;
+ //Create a filname fo a Term Info File
+ QString tisFile = Misc::segmentname(segment, QLatin1String(".tis"));
+ QString tiiFile = Misc::segmentname(segment, QLatin1String(".tii"));
+
+ //Create an SegmentTermEnum for storing all the terms read of the segment
+ origEnum = _CLNEW SegmentTermEnum( directory->openInput( tisFile ), fieldInfos, false);
+ indexEnum = _CLNEW SegmentTermEnum( directory->openInput( tiiFile ), fieldInfos, true);
+
+ //Check if enumerator points to a valid instance
+ CND_CONDITION(origEnum != NULL, "No memory could be allocated for orig enumerator");
+ CND_CONDITION(indexEnum != NULL, "No memory could be allocated for index enumerator");
+
+ //Get the size of the enumeration and store it in size
+ _size = origEnum->size;
+}
+
+TermInfosReader::~TermInfosReader()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ //Close the TermInfosReader to be absolutly sure that enumerator has been closed
+ //and the arrays indexTerms, indexPointers and indexInfos and their elements
+ //have been destroyed
+ close();
+}
+
+void TermInfosReader::close()
+{
+ //Func - Close the enumeration of TermInfos
+ //Pre - true
+ //Post - The _enumeration has been closed and the arrays
+
+ //Check if indexTerms and indexInfos exist
+ if (indexTerms && indexInfos){
+ //Iterate through arrays indexTerms and indexPointer to
+ //destroy their elements
+#ifdef _DEBUG
+ for (int32_t i = 0; i < indexTermsLength; ++i) {
+ if (indexTerms[i].__cl_refcount != 1) {
+ CND_PRECONDITION(indexTerms[i].__cl_refcount == 1,
+ "TermInfosReader term was references more than internally");
+ }
+ // _CLDECDELETE(indexTerms[i]);
+ //_CLDELETE(indexInfos[i]);
+ }
+#endif
+ //Delete the arrays
+ _CLDELETE_ARRAY(indexTerms);
+ _CLDELETE_ARRAY(indexInfos);
+ }
+
+ //Delete the arrays
+ _CLDELETE_ARRAY(indexPointers);
+
+ if (origEnum != NULL) {
+ origEnum->close();
+
+ //Get a pointer to IndexInput used by the enumeration but
+ //instantiated in the constructor by directory.open( tisFile )
+ IndexInput *is = origEnum->input;
+
+ //Delete the enumuration enumerator
+ _CLDELETE(origEnum);
+
+ //Delete the IndexInput
+ _CLDELETE(is);
+ }
+
+ if (indexEnum != NULL){
+ indexEnum->close();
+
+ //Get a pointer to IndexInput used by the enumeration but
+ //instantiated in the constructor by directory.open( tiiFile )
+ IndexInput *is = indexEnum->input;
+
+ //Delete the enumuration enumerator
+ _CLDELETE(indexEnum);
+
+ //Delete the IndexInput
+ _CLDELETE(is);
+ }
+}
+
+int64_t TermInfosReader::size() const
+{
+ //Func - Return the size of the enumeration of TermInfos
+ //Pre - true
+ //Post - size has been returened
+
+ return _size;
+}
+
+Term* TermInfosReader::get(const int32_t position)
+{
+ //Func - Returns the nth term in the set
+ //Pre - position > = 0
+ //Post - The n-th term in the set has been returned
+
+ //Check if the size is 0 because then there are no terms
+ if (_size == 0)
+ return NULL;
+
+ SegmentTermEnum* enumerator = getEnum();
+
+ if (enumerator != NULL //an enumeration exists
+ && enumerator->term(false) != NULL // term is at or past current
+ && position >= enumerator->position
+ && position < (enumerator->position + enumerator->indexInterval)) {
+ return scanEnum(position); // can avoid seek
+ }
+
+ //random-access: must seek
+ seekEnum(position / enumerator->indexInterval);
+
+ //Get the Term at position
+ return scanEnum(position);
+}
+
+// TODO: currently there is no way of cleaning up a thread, if the thread ends.
+// we are stuck with the terminfosreader of that thread. Hopefully this won't
+// be too big a problem... solutions anyone?
+SegmentTermEnum* TermInfosReader::getEnum()
+{
+ SegmentTermEnum* termEnum = enumerators.get();
+ if (termEnum == NULL) {
+ termEnum = terms();
+ enumerators.set(termEnum);
+ }
+ return termEnum;
+}
+
+TermInfo* TermInfosReader::get(const Term* term)
+{
+ //Func - Returns a TermInfo for a term
+ //Pre - term holds a valid reference to term
+ //Post - if term can be found its TermInfo has been returned otherwise NULL
+
+ //If the size of the enumeration is 0 then no Terms have been read
+ if (_size == 0)
+ return NULL;
+
+ ensureIndexIsRead();
+
+ // optimize sequential access: first try scanning cached enum w/o seeking
+ SegmentTermEnum* enumerator = getEnum();
+
+ // optimize sequential access: first try scanning cached enumerator w/o seeking
+ // if the current term of the enumeration enumerator is not at the end
+ if (enumerator->term(false) != NULL
+ // AND there exists a previous current called prev and term is
+ // positioned after this prev
+ && ((enumerator->prev != NULL && term->compareTo(enumerator->prev) > 0)
+ // OR term is positioned at the same position as the current of
+ // enumerator or at a higher position
+ || term->compareTo(enumerator->term(false)) >= 0)) {
+ //Calculate the offset for the position
+ int32_t _enumOffset = (int32_t)
+ (enumerator->position / enumerator->indexInterval) + 1;
+
+ // but before end of block the length of indexTerms (the number of
+ // terms in enumerator) equals _enum_offset
+ if (indexTermsLength == _enumOffset
+ // OR term is positioned in front of term found at _enumOffset in
+ // indexTerms
+ || term->compareTo(&indexTerms[_enumOffset]) < 0) {
+ //no need to seek, retrieve the TermInfo for term
+ return scanEnum(term);
+ }
+ }
+
+ //Reposition current term in the enumeration
+ seekEnum(getIndexOffset(term));
+ //Return the TermInfo for term
+ return scanEnum(term);
+}
+
+int64_t TermInfosReader::getPosition(const Term* term)
+{
+ //Func - Returns the position of a Term in the set
+ //Pre - term holds a valid reference to a Term
+ // enumerator != NULL
+ //Post - If term was found then its position is returned otherwise -1
+
+ //if the enumeration is empty then return -1
+ if (_size == 0)
+ return -1;
+
+ ensureIndexIsRead();
+
+ //Retrieve the indexOffset for term
+ int32_t indexOffset = getIndexOffset(term);
+ seekEnum(indexOffset);
+
+ SegmentTermEnum* enumerator = getEnum();
+
+ while(term->compareTo(enumerator->term(false)) > 0 && enumerator->next()) {}
+
+ if (term->equals(enumerator->term(false)))
+ return enumerator->position;
+
+ return -1;
+}
+
+SegmentTermEnum* TermInfosReader::terms(const Term* term)
+{
+ //Func - Returns an enumeration of terms starting at or after the named term.
+ // If term is null then enumerator is set to the beginning
+ //Pre - term holds a valid reference to a Term
+ // enumerator != NULL
+ //Post - An enumeration of terms starting at or after the named term has been returned
+
+ SegmentTermEnum* enumerator = NULL;
+ if (term != NULL) {
+ //Seek enumerator to term; delete the new TermInfo that's returned.
+ TermInfo* ti = get(term);
+ _CLDELETE(ti);
+ enumerator = getEnum();
+ } else {
+ enumerator = origEnum;
+ }
+ //Clone the entire enumeration
+ SegmentTermEnum* cln = enumerator->clone();
+
+ //Check if cln points to a valid instance
+ CND_CONDITION(cln != NULL, "cln is NULL");
+
+ return cln;
+}
+
+void TermInfosReader::ensureIndexIsRead()
+{
+ //Func - Reads the term info index file or .tti file.
+ // This file contains every IndexInterval-th entry from the .tis file,
+ // along with its location in the "tis" file. This is designed to be
+ // read entirely into memory and used to provide random access to the
+ // "tis" file.
+ //Pre - indexTerms = NULL
+ // indexInfos = NULL
+ // indexPointers = NULL
+ //Post - The term info index file has been read into memory
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ if ( indexTerms != NULL )
+ return;
+
+ try {
+ indexTermsLength = (size_t)indexEnum->size;
+
+ // Instantiate an block of Term's,so that each one doesn't have to be new'd
+ indexTerms = _CL_NEWARRAY(Term,indexTermsLength);
+
+ // Check if is indexTerms is a valid array
+ CND_CONDITION(indexTerms != NULL,
+ "No memory could be allocated for indexTerms");
+
+ // Instantiate an big block of TermInfo's, so that each one doesn't
+ // have to be new'd
+ indexInfos = _CL_NEWARRAY(TermInfo,indexTermsLength);
+
+ // Check if is indexInfos is a valid array
+ CND_CONDITION(indexInfos != NULL,
+ "No memory could be allocated for indexInfos");
+
+ // Instantiate an array indexPointers that contains pointers to the
+ // term info index file
+ indexPointers = _CL_NEWARRAY(int64_t,indexTermsLength);
+
+ // Check if is indexPointers is a valid array
+ CND_CONDITION(indexPointers != NULL,
+ "No memory could be allocated for indexPointers");
+
+ //Iterate through the terms of indexEnum
+ for (int32_t i = 0; indexEnum->next(); ++i) {
+ indexTerms[i].set(indexEnum->term(false), indexEnum->term(false)->text());
+ indexEnum->getTermInfo(&indexInfos[i]);
+ indexPointers[i] = indexEnum->indexPointer;
+ }
+ } _CLFINALLY (
+ indexEnum->close();
+ // Close and delete the IndexInput is. The close is done by the destructor.
+ _CLDELETE( indexEnum->input );
+ _CLDELETE( indexEnum );
+ );
+}
+
+int32_t TermInfosReader::getIndexOffset(const Term* term)
+{
+ //Func - Returns the offset of the greatest index entry which is less than
+ // or equal to term.
+ //Pre - term holds a reference to a valid term
+ // indexTerms != NULL
+ //Post - The new offset has been returned
+
+ //Check if is indexTerms is a valid array
+ CND_PRECONDITION(indexTerms != NULL, "indexTerms is NULL");
+
+ int32_t lo = 0;
+ int32_t hi = indexTermsLength - 1;
+ int32_t mid;
+ int32_t delta;
+
+ while (hi >= lo) {
+ //Start in the middle betwee hi and lo
+ mid = (lo + hi) >> 1;
+
+ //Check if is indexTerms[mid] is a valid instance of Term
+ CND_PRECONDITION(&indexTerms[mid] != NULL, "indexTerms[mid] is NULL");
+ CND_PRECONDITION(mid < indexTermsLength, "mid >= indexTermsLength");
+
+ //Determine if term is before mid or after mid
+ delta = term->compareTo(&indexTerms[mid]);
+ if (delta < 0) {
+ //Calculate the new hi
+ hi = mid - 1;
+ } else if (delta > 0) {
+ //Calculate the new lo
+ lo = mid + 1;
+ } else {
+ //term has been found so return its position
+ return mid;
+ }
+ }
+ // the new starting offset
+ return hi;
+}
+
+void TermInfosReader::seekEnum(const int32_t indexOffset)
+{
+ //Func - Reposition the current Term and TermInfo to indexOffset
+ //Pre - indexOffset >= 0
+ // indexTerms != NULL
+ // indexInfos != NULL
+ // indexPointers != NULL
+ //Post - The current Term and Terminfo have been repositioned to indexOffset
+
+ CND_PRECONDITION(indexOffset >= 0, "indexOffset contains a negative number");
+ CND_PRECONDITION(indexTerms != NULL, "indexTerms is NULL");
+ CND_PRECONDITION(indexInfos != NULL, "indexInfos is NULL");
+ CND_PRECONDITION(indexPointers != NULL, "indexPointers is NULL");
+
+ SegmentTermEnum* enumerator = getEnum();
+ enumerator->seek(indexPointers[indexOffset],
+ (indexOffset * enumerator->indexInterval) - 1,
+ &indexTerms[indexOffset], &indexInfos[indexOffset]);
+}
+
+TermInfo* TermInfosReader::scanEnum(const Term* term)
+{
+ //Func - Scans the Enumeration of terms for term and returns the
+ // corresponding TermInfo instance if found. The search is started
+ // from the current term.
+ //Pre - term contains a valid reference to a Term
+ // enumerator != NULL
+ //Post - if term has been found the corresponding TermInfo has been returned
+ // otherwise NULL has been returned
+
+ SegmentTermEnum* enumerator = getEnum();
+ enumerator->scanTo(term);
+
+ //Check if the at the position the Term term can be found
+ if (enumerator->term(false) != NULL && term->equals(enumerator->term(false))) {
+ //Return the TermInfo instance about term
+ return enumerator->getTermInfo();
+ }
+
+ //term was not found so no TermInfo can be returned
+ return NULL;
+}
+
+Term* TermInfosReader::scanEnum(const int32_t position)
+{
+ //Func - Scans the enumeration to the requested position and returns the
+ // Term located at that position
+ //Pre - position > = 0
+ // enumerator != NULL
+ //Post - The Term at the requested position has been returned
+
+ SegmentTermEnum* enumerator = getEnum();
+
+ // As long the position of the enumeration enumerator is smaller than the
+ // requested one
+ while(enumerator->position < position) {
+ //Move the current of enumerator to the next
+ if (!enumerator->next()) {
+ //If there is no next it means that the requested position was to big
+ return NULL;
+ }
+ }
+
+ //Return the Term a the requested position
+ return enumerator->term();
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/TermInfosReader.h b/3rdparty/clucene/src/CLucene/index/TermInfosReader.h
new file mode 100644
index 000000000..ed202e750
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermInfosReader.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_TermInfosReader_
+#define _lucene_index_TermInfosReader_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/util/ThreadLocal.h"
+#include "SegmentTermEnum.h"
+
+CL_NS_DEF(index)
+
+class FieldInfos;
+class Term;
+class TermInfo;
+class TermInfos;
+class TermInfosWriter;
+
+// PORT STATUS: 365707 (jlucene 1.9)
+// This stores a monotonically increasing set of <Term, TermInfo> pairs in a
+// Directory. Pairs are accessed either by Term or by ordinal position the set.
+class TermInfosReader : LUCENE_BASE
+{
+private:
+ CL_NS(store)::Directory* directory;
+ QString segment;
+ FieldInfos* fieldInfos;
+
+ CL_NS(util)::ThreadLocal<SegmentTermEnum*,
+ CL_NS(util)::Deletor::Object<SegmentTermEnum> > enumerators;
+
+ SegmentTermEnum* getEnum();
+ SegmentTermEnum* origEnum;
+ SegmentTermEnum* indexEnum;
+ int64_t _size;
+
+ Term* indexTerms;
+ int32_t indexTermsLength;
+ TermInfo* indexInfos;
+ int64_t* indexPointers;
+
+ DEFINE_MUTEX(THIS_LOCK)
+
+public:
+ // Reads the TermInfos file(.tis) and eventually the Term Info Index(.tii)
+ TermInfosReader(CL_NS(store)::Directory* dir, const QString& segment,
+ FieldInfos* fis);
+ ~TermInfosReader();
+
+ //Close the enumeration of TermInfos
+ void close();
+
+ //Return the size of the enumeration of TermInfos
+ int64_t size() const;
+
+ int32_t getSkipInterval() {
+ return origEnum->skipInterval; }
+
+ // Returns an enumeration of terms starting at or after the named term.
+ // If no term is specified, an enumeration of all the Terms
+ // and TermInfos in the set is returned.
+ SegmentTermEnum* terms(const Term* term = NULL);
+
+ // Returns the TermInfo for a Term in the set
+ // synchronized
+ TermInfo* get(const Term* term);
+
+private:
+ // Reads the term info index file or .tti file.
+ void ensureIndexIsRead();
+
+ // Returns the offset of the greatest index entry which is less than term.
+ int32_t getIndexOffset(const Term* term);
+
+ // Reposition the current Term and TermInfo to indexOffset
+ void seekEnum(const int32_t indexOffset);
+
+ // Scans the Enumeration of terms for term and returns the corresponding
+ // TermInfo instance if found. The search is started from the current term.
+ TermInfo* scanEnum(const Term* term);
+
+ // Scans the enumeration to the requested position and returns the Term
+ // located at that position
+ Term* scanEnum(const int32_t position);
+
+ // Returns the position of a Term in the set. synchronized
+ int64_t getPosition(const Term* term);
+
+ // Returns the nth term in the set. synchronized
+ Term* get(const int32_t position);
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/TermInfosWriter.cpp b/3rdparty/clucene/src/CLucene/index/TermInfosWriter.cpp
new file mode 100644
index 000000000..c5b5340c3
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermInfosWriter.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "TermInfosWriter.h"
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/util/Misc.h"
+#include "FieldInfos.h"
+#include "Term.h"
+#include "TermInfo.h"
+#include "IndexWriter.h"
+
+CL_NS_USE(util)
+CL_NS_USE(store)
+CL_NS_DEF(index)
+
+TermInfosWriter::TermInfosWriter(Directory* directory, const QString& segment,
+ FieldInfos* fis, int32_t interval)
+ : fieldInfos(fis)
+{
+ //Func - Constructor
+ //Pre - directory contains a valid reference to a Directory
+ // segment != NULL
+ // fis contains a valid reference to a reference FieldInfos
+ //Post - The instance has been created
+
+ CND_PRECONDITION(!segment.isEmpty(), "segment is NULL");
+ //Initialize instance
+ initialise(directory, segment, interval, false);
+
+ other = _CLNEW TermInfosWriter(directory, segment, fieldInfos, interval, true);
+
+ CND_CONDITION(other != NULL, "other is NULL");
+
+ other->other = this;
+}
+
+TermInfosWriter::TermInfosWriter(Directory* directory, const QString& segment,
+ FieldInfos* fis, int32_t interval, bool isIndex)
+ : fieldInfos(fis)
+{
+ //Func - Constructor
+ //Pre - directory contains a valid reference to a Directory
+ // segment != NULL
+ // fis contains a valid reference to a reference FieldInfos
+ // isIndex is true or false
+ //Post - The instance has been created
+
+ CND_PRECONDITION(!segment.isEmpty(), "segment is NULL");
+ initialise(directory, segment, interval, isIndex);
+}
+
+void TermInfosWriter::initialise(Directory* directory, const QString& segment,
+ int32_t interval, bool IsIndex)
+{
+ //Func - Helps constructors to initialize Instance
+ //Pre - directory contains a valid reference to a Directory
+ // segment != NULL
+ // fis contains a valid reference to a reference FieldInfos
+ //Post - The instance has been initialized
+
+ lastTerm = _CLNEW Term;
+
+ CND_CONDITION(lastTerm != NULL, "Could not allocate memory for lastTerm");
+
+ lastTi = _CLNEW TermInfo();
+
+ CND_CONDITION(lastTi != NULL, "Could not allocate memory for lastTi");
+
+ lastIndexPointer = 0;
+ size = 0;
+ isIndex = IsIndex;
+ indexInterval = interval;
+ skipInterval = LUCENE_DEFAULT_TERMDOCS_SKIP_INTERVAL;
+
+ QString buf = Misc::segmentname(segment, QLatin1String(isIndex ? ".tii" : ".tis"));
+ output = directory->createOutput(buf);
+
+ output->writeInt(FORMAT); // write format
+ output->writeLong(0); // leave space for size
+ output->writeInt(indexInterval);// write indexInterval
+ output->writeInt(skipInterval); // write skipInterval
+
+ //Set other to NULL by Default
+ other = NULL;
+}
+
+TermInfosWriter::~TermInfosWriter()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - de instance has been destroyed
+
+ close();
+}
+
+void TermInfosWriter::add(Term* term, const TermInfo* ti)
+{
+ //Func - Writes a Term and TermInfo to the outputstream
+ //Pre - Term must be lexicographically greater than all previous Terms added.
+ // Pointers of TermInfo ti (freqPointer and proxPointer) must be
+ // positive and greater than all previous.
+
+ CND_PRECONDITION(isIndex || (!isIndex && term->compareTo(lastTerm) > 0),"term out of order");
+ CND_PRECONDITION(ti->freqPointer >= lastTi->freqPointer,"freqPointer out of order");
+ CND_PRECONDITION(ti->proxPointer >= lastTi->proxPointer,"proxPointer out of order");
+
+ if (!isIndex && size % indexInterval == 0) {
+ //add an index term
+ other->add(lastTerm, lastTi);
+ }
+
+ //write term
+ writeTerm(term);
+ // write doc freq
+ output->writeVInt(ti->docFreq);
+ //write pointers
+ output->writeVLong(ti->freqPointer - lastTi->freqPointer);
+ output->writeVLong(ti->proxPointer - lastTi->proxPointer);
+ if (ti->docFreq >= skipInterval) {
+ output->writeVInt(ti->skipOffset);
+ }
+
+ if (isIndex){
+ output->writeVLong(other->output->getFilePointer() - lastIndexPointer);
+ lastIndexPointer = other->output->getFilePointer(); // write pointer
+ }
+
+ lastTi->set(ti);
+ size++;
+}
+
+void TermInfosWriter::close() {
+ //Func - Closes the TermInfosWriter
+ //Pre - true
+ //Post - The TermInfosWriter has been closed
+
+ if (output){
+ //write size at start
+ output->seek(4); // write size after format
+ output->writeLong(size);
+ output->close();
+ _CLDELETE(output);
+
+ if (!isIndex){
+ if(other){
+ other->close();
+ _CLDELETE( other );
+ }
+ }
+ _CLDECDELETE(lastTerm);
+
+ _CLDELETE(lastTi);
+ }
+}
+
+void TermInfosWriter::writeTerm(Term* term)
+{
+ int32_t start = Misc::stringDifference(lastTerm->text(),lastTerm->textLength(),
+ term->text(),term->textLength());
+ int32_t length = term->textLength() - start;
+
+ output->writeVInt(start); // write shared prefix length
+ output->writeVInt(length); // write delta length
+ output->writeChars(term->text(), start, length); // write delta chars
+
+ int32_t fieldnum = fieldInfos->fieldNumber(term->field());
+ CND_PRECONDITION(fieldnum>=-1&&fieldnum<fieldInfos->size(),"Fieldnum is out of range");
+ output->writeVInt(fieldnum); // write field num
+
+ if ( lastTerm->__cl_refcount == 1 ){
+ lastTerm->set(term,term->text());
+ }else{
+ _CLDECDELETE(lastTerm);
+ lastTerm = _CL_POINTER(term);
+ }
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/TermInfosWriter.h b/3rdparty/clucene/src/CLucene/index/TermInfosWriter.h
new file mode 100644
index 000000000..7e3c68699
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermInfosWriter.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_TermInfosWriter_
+#define _lucene_index_TermInfosWriter_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/store/Directory.h"
+#include "FieldInfos.h"
+#include "TermInfo.h"
+#include "Term.h"
+
+CL_NS_DEF(index)
+
+
+// This stores a monotonically increasing set of <Term, TermInfo> pairs in a
+// Directory. A TermInfos can be written once, in order.
+class TermInfosWriter : LUCENE_BASE
+{
+private:
+ FieldInfos* fieldInfos;
+ CL_NS(store)::IndexOutput* output;
+ Term* lastTerm;
+ TermInfo* lastTi;
+ int64_t size;
+ int64_t lastIndexPointer;
+ bool isIndex;
+ TermInfosWriter* other;
+
+ //inititalize
+ TermInfosWriter(CL_NS(store)::Directory* directory,
+ const QString& segment, FieldInfos* fis, int32_t interval, bool isIndex);
+public:
+ /** The file format version, a negative number. */
+ LUCENE_STATIC_CONSTANT(int32_t,FORMAT=-2);
+
+ /**
+ * Expert: The fraction of terms in the "dictionary" which should be stored
+ * in RAM. Smaller values use more memory, but make searching slightly
+ * faster, while larger values use less memory and make searching slightly
+ * slower. Searching is typically not dominated by dictionary lookup, so
+ * tweaking this is rarely useful.
+ */
+ int32_t indexInterval;// = 128
+
+ /**
+ * Expert: The fraction of {@link TermDocs} entries stored in skip tables,
+ * used to accellerate {@link TermDocs#SkipTo(int32_t)}. Larger values result in
+ * smaller indexes, greater acceleration, but fewer accelerable cases, while
+ * smaller values result in bigger indexes, less acceleration and more
+ * accelerable cases. More detailed experiments would be useful here.
+ */
+ int32_t skipInterval;// = 16
+
+ TermInfosWriter(CL_NS(store)::Directory* directory,
+ const QString& segment, FieldInfos* fis, int32_t interval);
+
+ ~TermInfosWriter();
+
+ /**
+ * Adds a new <Term, TermInfo> pair to the set.
+ * Term must be lexicographically greater than all previous Terms added.
+ * TermInfo pointers must be positive and greater than all previous.
+ */
+ void add(Term* term, const TermInfo* ti);
+
+ /** Called to complete TermInfos creation. */
+ void close();
+
+private:
+ /** Helps constructors to initialize instances */
+ void initialise(CL_NS(store)::Directory* directory,
+ const QString& segment, int32_t interval, bool IsIndex);
+ void writeTerm(Term* term);
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/TermVector.h b/3rdparty/clucene/src/CLucene/index/TermVector.h
new file mode 100644
index 000000000..8601fbf53
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermVector.h
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_index_termvector_h
+#define _lucene_index_termvector_h
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/store/Directory.h"
+#include "CLucene/store/IndexOutput.h"
+#include "FieldInfos.h"
+
+CL_NS_DEF(index)
+
+struct TermVectorOffsetInfo;
+class TermPositionVector;
+
+// Provides access to stored term vector of a document field.
+class TermFreqVector : LUCENE_BASE
+{
+public:
+ virtual ~TermFreqVector() {}
+
+ // @return The field this vector is associated with.
+ virtual const TCHAR* getField() = 0;
+
+ // @return The number of terms in the term vector.
+ virtual int32_t size() = 0;
+
+ // @return An Array of term texts in ascending order.
+ virtual const TCHAR** getTerms() = 0;
+
+
+ /* Array of term frequencies. Locations of the array correspond one to one
+ * to the terms in the array obtained from <code>getTerms</code>
+ * method. Each location in the array contains the number of times this
+ * term occurs in the document or the document field.
+ *
+ * The size of the returned array is size()
+ * @memory Returning a pointer to internal data. Do not delete.
+ */
+ virtual const Array<int32_t>* getTermFrequencies() = 0;
+
+
+ /* Return an index in the term numbers array returned from
+ * <code>getTerms</code> at which the term with the specified
+ * <code>term</code> appears. If this term does not appear in the array,
+ * return -1.
+ */
+ virtual int32_t indexOf(const TCHAR* term) = 0;
+
+
+ /* Just like <code>indexOf(int32_t)</code> but searches for a number of terms
+ * at the same time. Returns an array that has the same size as the number
+ * of terms searched for, each slot containing the result of searching for
+ * that term number.
+ *
+ * @param terms array containing terms to look for
+ * @param start index in the array where the list of terms starts
+ * @param len the number of terms in the list
+ */
+ virtual void indexesOf(const TCHAR** terms, const int32_t start,
+ const int32_t len, Array<int32_t>& ret) = 0;
+
+ // Solve the diamond inheritence problem by providing a reinterpret function.
+ // No dynamic casting is required and no RTTI data is needed to do this
+ virtual TermPositionVector* __asTermPositionVector() = 0;
+};
+
+
+/**
+* Writer works by opening a document and then opening the fields within the document and then
+* writing out the vectors for each field.
+*
+* Rough usage:
+*
+<CODE>
+for each document
+{
+writer.openDocument();
+for each field on the document
+{
+writer.openField(field);
+for all of the terms
+{
+writer.addTerm(...)
+}
+writer.closeField
+}
+writer.closeDocument()
+}
+</CODE>
+*/
+class TermVectorsWriter : LUCENE_BASE
+{
+private:
+ class TVField : LUCENE_BASE
+ {
+ public:
+ int32_t number;
+ int64_t tvfPointer;
+ int32_t length; // number of distinct term positions
+ bool storePositions;
+ bool storeOffsets;
+
+ TVField(int32_t number, bool storePos, bool storeOff)
+ : tvfPointer(0)
+ , length(0)
+ {
+ this->number = number;
+ this->storePositions = storePos;
+ this->storeOffsets = storeOff;
+ }
+ ~TVField() {}
+ };
+
+ class TVTerm : LUCENE_BASE
+ {
+ const TCHAR* termText;
+ int32_t termTextLen; //textlen cache
+
+ public:
+ TVTerm();
+ ~TVTerm();
+
+ int32_t freq;
+ Array<int32_t>* positions;
+ Array<TermVectorOffsetInfo>* offsets;
+
+ const TCHAR* getTermText() const;
+ size_t getTermTextLen();
+ void setTermText(const TCHAR* val);
+ };
+
+ CL_NS(store)::IndexOutput* tvx, *tvd, *tvf;
+ CL_NS(util)::CLVector<TVField*,CL_NS(util)::Deletor::Object<TVField> > fields;
+ CL_NS(util)::CLVector<TVTerm*,CL_NS(util)::Deletor::Object<TVTerm> > terms;
+ FieldInfos* fieldInfos;
+
+ TVField* currentField;
+ int64_t currentDocPointer;
+
+ void addTermInternal(const TCHAR* termText, const int32_t freq,
+ Array<int32_t>* positions, Array<TermVectorOffsetInfo>* offsets);
+
+ void writeField();
+ void writeDoc();
+
+ void openField(int32_t fieldNumber, bool storePositionWithTermVector,
+ bool storeOffsetWithTermVector);
+
+public:
+ LUCENE_STATIC_CONSTANT(int32_t, FORMAT_VERSION = 2);
+
+ // The size in bytes that the FORMAT_VERSION will take up at the beginning
+ // of each file
+ LUCENE_STATIC_CONSTANT(int32_t, FORMAT_SIZE = 4);
+
+ LUCENE_STATIC_CONSTANT(uint8_t, STORE_POSITIONS_WITH_TERMVECTOR = 0x1);
+ LUCENE_STATIC_CONSTANT(uint8_t, STORE_OFFSET_WITH_TERMVECTOR = 0x2);
+
+ static const QLatin1String LUCENE_TVX_EXTENSION;
+ static const QLatin1String LUCENE_TVD_EXTENSION;
+ static const QLatin1String LUCENE_TVF_EXTENSION;
+
+ TermVectorsWriter(CL_NS(store)::Directory* directory, const QString& segment,
+ FieldInfos* fieldInfos);
+
+ ~TermVectorsWriter();
+ void openDocument();
+ void closeDocument();
+
+ /** Close all streams. */
+ void close();
+ bool isDocumentOpen() const;
+
+ /** Start processing a field. This can be followed by a number of calls to
+ * addTerm, and a final call to closeField to indicate the end of
+ * processing of this field. If a field was previously open, it is
+ * closed automatically.
+ */
+ void openField(const TCHAR* field);
+
+ /** Finished processing current field. This should be followed by a call to
+ * openField before future calls to addTerm.
+ */
+ void closeField();
+
+ /** Return true if a field is currently open. */
+ bool isFieldOpen() const;
+
+ /**
+ * Add a complete document specified by all its term vectors. If document has no
+ * term vectors, add value for tvx.
+ *
+ * @param vectors
+ * @throws IOException
+ */
+ void addAllDocVectors(Array<TermFreqVector*>& vectors);
+
+ /** Add term to the field's term vector. Field must already be open.
+ * Terms should be added in
+ * increasing order of terms, one call per unique termNum. ProxPointer
+ * is a pointer into the TermPosition file (prx). Freq is the number of
+ * times this term appears in this field, in this document.
+ * @throws IllegalStateException if document or field is not open
+ */
+ void addTerm(const TCHAR* termText, int32_t freq,
+ Array<int32_t>* positions = NULL, Array<TermVectorOffsetInfo>* offsets = NULL);
+};
+
+class SegmentTermVector : public virtual TermFreqVector
+{
+private:
+ const TCHAR* field;
+ TCHAR** terms;
+ int32_t termsLen; //cache
+ Array<int32_t>* termFreqs;
+
+ int32_t binarySearch(TCHAR** a, const int32_t arraylen, const TCHAR* key) const;
+public:
+ //note: termFreqs must be the same length as terms
+ SegmentTermVector(const TCHAR* field, TCHAR** terms, Array<int32_t>* termFreqs);
+ virtual ~SegmentTermVector();
+
+ /**
+ *
+ * @return The number of the field this vector is associated with
+ */
+ const TCHAR* getField();
+ TCHAR* toString() const;
+ int32_t size();
+ const TCHAR** getTerms();
+ const Array<int32_t>* getTermFrequencies();
+ int32_t indexOf(const TCHAR* termText);
+ void indexesOf(const TCHAR** termNumbers, const int32_t start, const int32_t len, Array<int32_t>& ret);
+
+ virtual TermPositionVector* __asTermPositionVector();
+};
+
+class TermVectorsReader : LUCENE_BASE
+{
+private:
+ FieldInfos* fieldInfos;
+
+ CL_NS(store)::IndexInput* tvx;
+ CL_NS(store)::IndexInput* tvd;
+ CL_NS(store)::IndexInput* tvf;
+ int64_t _size;
+
+ int32_t tvdFormat;
+ int32_t tvfFormat;
+
+
+ int32_t checkValidFormat(CL_NS(store)::IndexInput* in);
+
+ void readTermVectors(const TCHAR** fields, const int64_t* tvfPointers,
+ const int32_t len, Array<TermFreqVector*>& _return);
+
+ /**
+ *
+ * @param field The field to read in
+ * @param tvfPointer The pointer within the tvf file where we should start reading
+ * @return The TermVector located at that position
+ * @throws IOException
+ */
+ SegmentTermVector* readTermVector(const TCHAR* field, const int64_t tvfPointer);
+
+ int64_t size();
+
+
+ DEFINE_MUTEX(THIS_LOCK)
+ TermVectorsReader(const TermVectorsReader& copy);
+public:
+ TermVectorsReader(CL_NS(store)::Directory* d, const QString& segment,
+ FieldInfos* fieldInfos);
+ ~TermVectorsReader();
+
+ void close();
+ TermVectorsReader* clone() const;
+
+ /**
+ * Retrieve the term vector for the given document and field
+ * @param docNum The document number to retrieve the vector for
+ * @param field The field within the document to retrieve
+ * @return The TermFreqVector for the document and field or null if there is no termVector for this field.
+ * @throws IOException if there is an error reading the term vector files
+ */
+ TermFreqVector* get(const int32_t docNum, const TCHAR* field);
+
+
+ /**
+ * Return all term vectors stored for this document or null if the could not be read in.
+ *
+ * @param docNum The document number to retrieve the vector for
+ * @return All term frequency vectors
+ * @throws IOException if there is an error reading the term vector files
+ */
+ bool get(int32_t docNum, Array<TermFreqVector*>& result);
+};
+
+
+struct TermVectorOffsetInfo
+{
+ int startOffset;
+ int endOffset;
+
+public:
+ static Array<TermVectorOffsetInfo> EMPTY_OFFSET_INFO;
+ TermVectorOffsetInfo();
+ ~TermVectorOffsetInfo();
+ TermVectorOffsetInfo(int32_t startOffset, int32_t endOffset);
+ int32_t getEndOffset() const;
+ void setEndOffset(int32_t endOffset);
+ int32_t getStartOffset() const;
+ void setStartOffset(int32_t startOffset);
+ bool equals(TermVectorOffsetInfo* o);
+ size_t hashCode() const;
+};
+
+
+/* Extends <code>TermFreqVector</code> to provide additional information about
+ * positions in which each of the terms is found. A TermPositionVector not
+ * necessarily contains both positions and offsets, but at least one of these
+ * arrays exists.
+*/
+class TermPositionVector : public virtual TermFreqVector
+{
+public:
+
+ /** Returns an array of positions in which the term is found.
+ * Terms are identified by the index at which its number appears in the
+ * term String array obtained from the <code>indexOf</code> method.
+ * May return null if positions have not been stored.
+ */
+ virtual Array<int32_t>* getTermPositions(int32_t index) = 0;
+
+ /**
+ * Returns an array of TermVectorOffsetInfo in which the term is found.
+ * May return null if offsets have not been stored.
+ *
+ * @see org.apache.lucene.analysis.Token
+ *
+ * @param index The position in the array to get the offsets from
+ * @return An array of TermVectorOffsetInfo objects or the empty list
+ */
+ virtual Array<TermVectorOffsetInfo>* getOffsets(int32_t index) = 0;
+
+ virtual ~TermPositionVector(){
+ }
+};
+
+
+class SegmentTermPositionVector: public SegmentTermVector, public TermPositionVector
+{
+protected:
+ Array< Array<int32_t> >* positions;
+ Array< Array<TermVectorOffsetInfo> >* offsets;
+ static Array<int32_t> EMPTY_TERM_POS;
+public:
+ SegmentTermPositionVector(const TCHAR* field, TCHAR** terms,
+ Array<int32_t>* termFreqs, Array< Array<int32_t> >* positions,
+ Array< Array<TermVectorOffsetInfo> >* offsets);
+ ~SegmentTermPositionVector();
+
+ /**
+ * Returns an array of TermVectorOffsetInfo in which the term is found.
+ *
+ * @param index The position in the array to get the offsets from
+ * @return An array of TermVectorOffsetInfo objects or the empty list
+ * @see org.apache.lucene.analysis.Token
+ */
+ Array<TermVectorOffsetInfo>* getOffsets(int32_t index);
+
+ /**
+ * Returns an array of positions in which the term is found.
+ * Terms are identified by the index at which its number appears in the
+ * term String array obtained from the <code>indexOf</code> method.
+ */
+ Array<int32_t>* getTermPositions(int32_t index);
+
+ const TCHAR* getField() {
+ return SegmentTermVector::getField(); }
+
+ TCHAR* toString() const {
+ return SegmentTermVector::toString(); }
+
+ int32_t size() {
+ return SegmentTermVector::size(); }
+
+ const TCHAR** getTerms() {
+ return SegmentTermVector::getTerms(); }
+
+ const Array<int32_t>* getTermFrequencies() {
+ return SegmentTermVector::getTermFrequencies(); }
+
+ int32_t indexOf(const TCHAR* termText) {
+ return SegmentTermVector::indexOf(termText); }
+
+ void indexesOf(const TCHAR** termNumbers, const int32_t start,
+ const int32_t len, Array<int32_t>& ret) {
+ SegmentTermVector::indexesOf(termNumbers, start, len, ret); }
+
+ virtual TermPositionVector* __asTermPositionVector();
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/index/TermVectorReader.cpp b/3rdparty/clucene/src/CLucene/index/TermVectorReader.cpp
new file mode 100644
index 000000000..53d909b29
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermVectorReader.cpp
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "TermVector.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+TermVectorsReader::TermVectorsReader(CL_NS(store)::Directory* d,
+ const QString& segment, FieldInfos* fieldInfos)
+{
+ if (d->fileExists(segment + TermVectorsWriter::LUCENE_TVX_EXTENSION)) {
+ tvx = d->openInput(segment + TermVectorsWriter::LUCENE_TVX_EXTENSION);
+ checkValidFormat(tvx);
+
+ tvd = d->openInput(segment + TermVectorsWriter::LUCENE_TVD_EXTENSION);
+ tvdFormat = checkValidFormat(tvd);
+
+ tvf = d->openInput(segment + TermVectorsWriter::LUCENE_TVF_EXTENSION);
+ tvfFormat = checkValidFormat(tvf);
+
+ _size = tvx->length() / 8;
+ }else{
+ tvx = NULL;
+ tvd = NULL;
+ tvf = NULL;
+ _size = 0;
+ }
+
+ this->fieldInfos = fieldInfos;
+}
+
+TermVectorsReader::TermVectorsReader(const TermVectorsReader& copy)
+{
+ tvx = copy.tvx->clone();
+ tvd = copy.tvd->clone();
+ tvf = copy.tvf->clone();
+
+ tvdFormat = copy.tvdFormat;
+ tvfFormat = copy.tvfFormat;
+ _size = copy._size;
+ fieldInfos = copy.fieldInfos;
+}
+TermVectorsReader* TermVectorsReader::clone() const{
+ if (tvx == NULL || tvd == NULL || tvf == NULL)
+ return NULL;
+ return _CLNEW TermVectorsReader(*this);
+}
+
+TermVectorsReader::~TermVectorsReader(){
+ close();
+}
+
+void TermVectorsReader::close(){
+ // why don't we trap the exception and at least make sure that
+ // all streams that we can close are closed?
+ CLuceneError keep(0,"",false);
+ bool thrown = false;
+
+ if (tvx != NULL){
+ try{
+ tvx->close();
+ }catch(CLuceneError& err){
+ if ( err.number() == CL_ERR_IO ){
+ keep = err;
+ thrown = true;
+ }else
+ throw err;
+ }
+ _CLDELETE(tvx);//delete even if error thrown
+ }
+ if (tvd != NULL){
+ try{
+ tvd->close();
+ }catch(CLuceneError& err){
+ if ( err.number() == CL_ERR_IO ){
+ keep = err;
+ thrown = true;
+ }else
+ throw err;
+ }
+ _CLDELETE(tvd);
+ }
+ if (tvf != NULL){
+ try{
+ tvf->close();
+ }catch(CLuceneError& err){
+ if ( err.number() == CL_ERR_IO ){
+ keep = err;
+ thrown = true;
+ }else
+ throw err;
+ }
+ _CLDELETE(tvf);
+ }
+
+ if ( thrown )
+ throw keep;
+}
+
+TermFreqVector* TermVectorsReader::get(const int32_t docNum, const TCHAR* field){
+ // Check if no term vectors are available for this segment at all
+ int32_t fieldNumber = fieldInfos->fieldNumber(field);
+ TermFreqVector* result = NULL;
+ if (tvx != NULL) {
+ //We need to account for the FORMAT_SIZE at when seeking in the tvx
+ //We don't need to do this in other seeks because we already have the
+ // file pointer
+ //that was written in another file
+ tvx->seek((docNum * 8L) + TermVectorsWriter::FORMAT_SIZE);
+ int64_t position = tvx->readLong();
+
+ tvd->seek(position);
+ int32_t fieldCount = tvd->readVInt();
+ // There are only a few fields per document. We opt for a full scan
+ // rather then requiring that they be ordered. We need to read through
+ // all of the fields anyway to get to the tvf pointers.
+ int32_t number = 0;
+ int32_t found = -1;
+ for (int32_t i = 0; i < fieldCount; ++i) {
+ if(tvdFormat == TermVectorsWriter::FORMAT_VERSION)
+ number = tvd->readVInt();
+ else
+ number += tvd->readVInt();
+ if (number == fieldNumber)
+ found = i;
+ }
+
+ // This field, although valid in the segment, was not found in this
+ // document
+ if (found != -1) {
+ // Compute position in the tvf file
+ position = 0;
+ for (int32_t i = 0; i <= found; ++i)
+ position += tvd->readVLong();
+ result = readTermVector(field, position);
+ }
+ }
+ return result;
+}
+
+
+bool TermVectorsReader::get(int32_t docNum, Array<TermFreqVector*>& result){
+ // Check if no term vectors are available for this segment at all
+ if (tvx != NULL) {
+ //We need to offset by
+ tvx->seek((docNum * 8L) + TermVectorsWriter::FORMAT_SIZE);
+ int64_t position = tvx->readLong();
+
+ tvd->seek(position);
+ int32_t fieldCount = tvd->readVInt();
+
+ // No fields are vectorized for this document
+ if (fieldCount != 0) {
+ int32_t number = 0;
+ const TCHAR** fields = _CL_NEWARRAY(const TCHAR*,fieldCount+1);
+
+ { //msvc6 scope fix
+ for (int32_t i = 0; i < fieldCount; ++i) {
+ if(tvdFormat == TermVectorsWriter::FORMAT_VERSION)
+ number = tvd->readVInt();
+ else
+ number += tvd->readVInt();
+ fields[i] = fieldInfos->fieldName(number);
+ }
+ }
+ fields[fieldCount]=NULL;
+
+ // Compute position in the tvf file
+ position = 0;
+ int64_t* tvfPointers = _CL_NEWARRAY(int64_t,fieldCount);
+ { //msvc6 scope fix
+ for (int32_t i = 0; i < fieldCount; ++i) {
+ position += tvd->readVLong();
+ tvfPointers[i] = position;
+ }
+ }
+
+ readTermVectors(fields, tvfPointers, fieldCount, result);
+ _CLDELETE_ARRAY(tvfPointers);
+ _CLDELETE_ARRAY(fields);
+ }
+ return true;
+ }
+ return false;
+}
+
+
+int32_t TermVectorsReader::checkValidFormat(CL_NS(store)::IndexInput* in)
+{
+ int32_t format = in->readInt();
+ if (format > TermVectorsWriter::FORMAT_VERSION)
+ {
+ CL_NS(util)::StringBuffer err;
+ err.append(_T("Incompatible format version: "));
+ err.appendInt(format);
+ err.append(_T(" expected "));
+ err.appendInt(TermVectorsWriter::FORMAT_VERSION);
+ err.append(_T(" or less"));
+ _CLTHROWT(CL_ERR_Runtime,err.getBuffer());
+ }
+ return format;
+}
+
+void TermVectorsReader::readTermVectors(const TCHAR** fields,
+ const int64_t* tvfPointers, const int32_t len, Array<TermFreqVector*>& result)
+{
+ result.length = len;
+ result.values = _CL_NEWARRAY(TermFreqVector*,len);
+ for (int32_t i = 0; i < len; ++i) {
+ result.values[i] = readTermVector(fields[i], tvfPointers[i]);
+ }
+}
+
+SegmentTermVector* TermVectorsReader::readTermVector(const TCHAR* field,
+ const int64_t tvfPointer)
+{
+ // Now read the data from specified position. We don't need to offset by
+ // the FORMAT here since the pointer already includes the offset
+ tvf->seek(tvfPointer);
+
+ int32_t numTerms = tvf->readVInt();
+ // If no terms - return a constant empty termvector. However, this should never occur!
+ if (numTerms == 0)
+ return _CLNEW SegmentTermVector(field, NULL, NULL);
+
+ bool storePositions;
+ bool storeOffsets;
+
+ if(tvfFormat == TermVectorsWriter::FORMAT_VERSION){
+ uint8_t bits = tvf->readByte();
+ storePositions = (bits & TermVectorsWriter::STORE_POSITIONS_WITH_TERMVECTOR) != 0;
+ storeOffsets = (bits & TermVectorsWriter::STORE_OFFSET_WITH_TERMVECTOR) != 0;
+ }
+ else{
+ tvf->readVInt();
+ storePositions = false;
+ storeOffsets = false;
+ }
+
+ TCHAR** terms = _CL_NEWARRAY(TCHAR*,numTerms+1);
+ Array<int32_t>* termFreqs = _CLNEW Array<int32_t>(numTerms);
+
+ // we may not need these, but declare them
+ Array< Array<int32_t> >* positions = NULL;
+ Array< Array<TermVectorOffsetInfo> >* offsets = NULL;
+ if(storePositions){
+ Array<int32_t>* tmp = _CL_NEWARRAY(Array<int32_t>,numTerms);
+ positions = _CLNEW Array< Array<int32_t> >(tmp, numTerms);
+ }
+ if(storeOffsets){
+ Array<TermVectorOffsetInfo>* tmp = _CL_NEWARRAY(Array<TermVectorOffsetInfo>,numTerms);
+ offsets = _CLNEW Array< Array<TermVectorOffsetInfo> >(tmp, numTerms);
+ }
+
+ int32_t start = 0;
+ int32_t deltaLength = 0;
+ int32_t totalLength = 0;
+ int32_t bufferLen=10; // init the buffer with a length of 10 character
+ TCHAR* buffer = (TCHAR*)malloc(bufferLen * sizeof(TCHAR));
+
+ for (int32_t i = 0; i < numTerms; ++i) {
+ start = tvf->readVInt();
+ deltaLength = tvf->readVInt();
+ totalLength = start + deltaLength;
+ if (bufferLen < totalLength) // increase buffer
+ {
+ buffer=(TCHAR*)realloc(buffer,totalLength * sizeof(TCHAR));
+ bufferLen = totalLength;
+ }
+
+ //read the term
+ tvf->readChars(buffer, start, deltaLength);
+ terms[i] = _CL_NEWARRAY(TCHAR,totalLength+1);
+ _tcsncpy(terms[i],buffer,totalLength);
+ terms[i][totalLength] = '\0'; //null terminate term
+
+ //read the frequency
+ int32_t freq = tvf->readVInt();
+ termFreqs->values[i] = freq;
+
+ if (storePositions) { //read in the positions
+ Array<int32_t>& pos = positions->values[i];
+ pos.length = freq;
+ pos.values = _CL_NEWARRAY(int32_t,freq);
+
+ int32_t prevPosition = 0;
+ for (int32_t j = 0; j < freq; ++j)
+ {
+ pos.values[j] = prevPosition + tvf->readVInt();
+ prevPosition = pos.values[j];
+ }
+ }
+
+ if (storeOffsets) {
+ Array<TermVectorOffsetInfo>& offs = offsets->values[i];
+ offs.length = freq;
+ offs.values = _CL_NEWARRAY(TermVectorOffsetInfo,freq);
+
+ int32_t prevOffset = 0;
+ for (int32_t j = 0; j < freq; ++j) {
+ int32_t startOffset = prevOffset + tvf->readVInt();
+ int32_t endOffset = startOffset + tvf->readVInt();
+ offs.values[j].setStartOffset(startOffset);
+ offs.values[j].setEndOffset(endOffset);
+ prevOffset = endOffset;
+ }
+ }
+ }
+ free(buffer);
+ terms[numTerms]=NULL; //null terminate terms array
+
+ SegmentTermVector* tv = NULL;
+ if (storePositions || storeOffsets){
+ return _CLNEW SegmentTermPositionVector(field, terms, termFreqs, positions, offsets);
+ }else {
+ return _CLNEW SegmentTermVector(field, terms, termFreqs);
+ }
+}
+
+int64_t TermVectorsReader::size()
+{
+ return _size;
+}
+
+
+
+
+Array<TermVectorOffsetInfo> TermVectorOffsetInfo::EMPTY_OFFSET_INFO;
+
+TermVectorOffsetInfo::TermVectorOffsetInfo()
+{
+ startOffset = 0;
+ endOffset=0;
+}
+
+TermVectorOffsetInfo::~TermVectorOffsetInfo()
+{
+}
+
+TermVectorOffsetInfo::TermVectorOffsetInfo(int32_t startOffset, int32_t endOffset)
+{
+ this->endOffset = endOffset;
+ this->startOffset = startOffset;
+}
+
+int32_t TermVectorOffsetInfo::getEndOffset() const
+{
+ return endOffset;
+}
+
+void TermVectorOffsetInfo::setEndOffset(int32_t endOffset)
+{
+ this->endOffset = endOffset;
+}
+
+int32_t TermVectorOffsetInfo::getStartOffset() const
+{
+ return startOffset;
+}
+
+void TermVectorOffsetInfo::setStartOffset(int32_t startOffset)
+{
+ this->startOffset = startOffset;
+}
+
+bool TermVectorOffsetInfo::equals(TermVectorOffsetInfo* termVectorOffsetInfo)
+{
+ if (this == termVectorOffsetInfo)
+ return true;
+
+ if (endOffset != termVectorOffsetInfo->endOffset) return false;
+ if (startOffset != termVectorOffsetInfo->startOffset) return false;
+
+ return true;
+}
+
+size_t TermVectorOffsetInfo::hashCode() const
+{
+ size_t result;
+ result = startOffset;
+ result = 29 * result + endOffset;
+ return result;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/TermVectorWriter.cpp b/3rdparty/clucene/src/CLucene/index/TermVectorWriter.cpp
new file mode 100644
index 000000000..276b1bbd0
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/TermVectorWriter.cpp
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "TermVector.h"
+#include "CLucene/util/Misc.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(index)
+
+const QLatin1String TermVectorsWriter::LUCENE_TVX_EXTENSION(".tvx");
+const QLatin1String TermVectorsWriter::LUCENE_TVD_EXTENSION(".tvd");
+const QLatin1String TermVectorsWriter::LUCENE_TVF_EXTENSION(".tvf");
+
+TermVectorsWriter::TermVectorsWriter(CL_NS(store)::Directory* directory,
+ const QString& segment,FieldInfos* fieldInfos)
+{
+ // Open files for TermVector storage
+ tvx = directory->createOutput(segment + LUCENE_TVX_EXTENSION);
+ tvx->writeInt(FORMAT_VERSION);
+
+ tvd = directory->createOutput(segment + LUCENE_TVD_EXTENSION);
+ tvd->writeInt(FORMAT_VERSION);
+
+ tvf = directory->createOutput(segment + LUCENE_TVF_EXTENSION);
+ tvf->writeInt(FORMAT_VERSION);
+
+ this->fieldInfos = fieldInfos;
+
+ currentField = NULL;
+ currentDocPointer = -1;
+}
+
+TermVectorsWriter::~TermVectorsWriter()
+{
+ if (tvx != NULL) {
+ tvx->close();
+ _CLDELETE(tvx);
+ }
+
+ if (tvd != NULL) {
+ tvd->close();
+ _CLDELETE(tvd);
+ }
+
+ if (tvf != NULL){
+ tvf->close();
+ _CLDELETE(tvf);
+ }
+}
+
+void TermVectorsWriter::openDocument()
+{
+ closeDocument();
+ currentDocPointer = tvd->getFilePointer();
+}
+
+void TermVectorsWriter::closeDocument()
+{
+ if (isDocumentOpen()) {
+ closeField();
+ writeDoc();
+ fields.clear();
+ currentDocPointer = -1;
+ }
+}
+
+bool TermVectorsWriter::isDocumentOpen() const
+{
+ return currentDocPointer != -1;
+}
+
+
+void TermVectorsWriter::openField(int32_t fieldNumber,
+ bool storePositionWithTermVector, bool storeOffsetWithTermVector)
+{
+ if (!isDocumentOpen())
+ _CLTHROWA(CL_ERR_InvalidState,"Cannot open field when no document is open.");
+
+ closeField();
+ currentField = _CLNEW TVField(fieldNumber, storePositionWithTermVector,
+ storeOffsetWithTermVector);
+}
+
+void TermVectorsWriter::openField(const TCHAR* field)
+{
+ FieldInfo* fieldInfo = fieldInfos->fieldInfo(field);
+ openField(fieldInfo->number, fieldInfo->storePositionWithTermVector,
+ fieldInfo->storeOffsetWithTermVector);
+}
+
+void TermVectorsWriter::closeField()
+{
+ if (isFieldOpen()) {
+ /* DEBUG */
+ //System.out.println("closeField()");
+ /* DEBUG */
+
+ // save field and terms
+ writeField();
+ fields.push_back(currentField);
+ terms.clear();
+ currentField = NULL;
+ }
+}
+
+bool TermVectorsWriter::isFieldOpen() const
+{
+ return currentField != NULL;
+}
+
+void TermVectorsWriter::addTerm(const TCHAR* termText, int32_t freq,
+ Array<int32_t>* positions, Array<TermVectorOffsetInfo>* offsets)
+{
+ if (!isDocumentOpen())
+ _CLTHROWA(CL_ERR_InvalidState, "Cannot add terms when document is not open");
+
+ if (!isFieldOpen())
+ _CLTHROWA(CL_ERR_InvalidState, "Cannot add terms when field is not open");
+
+ addTermInternal(termText, freq, positions, offsets);
+}
+
+void TermVectorsWriter::addTermInternal(const TCHAR* termText, int32_t freq,
+ Array<int32_t>* positions, Array<TermVectorOffsetInfo>* offsets)
+{
+ TVTerm* term = _CLNEW TVTerm();
+ term->setTermText(termText);
+ term->freq = freq;
+ term->positions = positions;
+ term->offsets = offsets;
+ terms.push_back(term);
+}
+
+void TermVectorsWriter::addAllDocVectors(Array<TermFreqVector*>& vectors)
+{
+ openDocument();
+
+ for (int32_t i = 0; i < vectors.length; ++i) {
+ bool storePositionWithTermVector = false;
+ bool storeOffsetWithTermVector = false;
+
+ if ( vectors[i]->__asTermPositionVector() != NULL ) {
+ TermPositionVector* tpVector = vectors[i]->__asTermPositionVector();
+
+ if (tpVector->size() > 0 && tpVector->getTermPositions(0) != NULL)
+ storePositionWithTermVector = true;
+ if (tpVector->size() > 0 && tpVector->getOffsets(0) != NULL)
+ storeOffsetWithTermVector = true;
+
+ FieldInfo* fieldInfo = fieldInfos->fieldInfo(tpVector->getField());
+ openField(fieldInfo->number, storePositionWithTermVector, storeOffsetWithTermVector);
+
+ for (int32_t j = 0; j < tpVector->size(); ++j)
+ addTermInternal(tpVector->getTerms()[j],
+ (*tpVector->getTermFrequencies())[j],
+ tpVector->getTermPositions(j),
+ tpVector->getOffsets(j));
+
+ closeField();
+
+ } else {
+ TermFreqVector* tfVector = vectors[i];
+
+ FieldInfo* fieldInfo = fieldInfos->fieldInfo(tfVector->getField());
+ openField(fieldInfo->number, storePositionWithTermVector, storeOffsetWithTermVector);
+
+ for (int32_t j = 0; j < tfVector->size(); ++j)
+ addTermInternal(tfVector->getTerms()[j],
+ (*tfVector->getTermFrequencies())[j], NULL, NULL);
+
+ closeField();
+ }
+ }
+
+ closeDocument();
+}
+
+
+void TermVectorsWriter::close()
+{
+ try {
+ closeDocument();
+
+ // make an effort to close all streams we can but remember and re-throw
+ // the first exception encountered in this process
+#define _DOTVWCLOSE(x) \
+ if (x != NULL) { \
+ try { \
+ x->close(); \
+ _CLDELETE(x) \
+ } catch (CLuceneError& e) { \
+ if ( e.number() != CL_ERR_IO ) \
+ throw e; \
+ if (ikeep == 0) \
+ ikeep = e.number(); \
+ if (keep[0] == 0) \
+ strcpy(keep,e.what()); \
+ } catch (...) { \
+ if (keep[0] == 0) \
+ strcpy(keep, "Unknown error while closing " #x);\
+ } \
+ }
+ } _CLFINALLY ( \
+ char keep[200];
+ int32_t ikeep = 0;
+ keep[0] = 0;
+ _DOTVWCLOSE(tvx);
+ _DOTVWCLOSE(tvd);
+ _DOTVWCLOSE(tvf);
+ if (keep[0] != 0)
+ _CLTHROWA(ikeep, keep);
+ );
+}
+
+void TermVectorsWriter::writeField()
+{
+ // remember where this field is written
+ currentField->tvfPointer = tvf->getFilePointer();
+ //System.out.println("Field Pointer: " + currentField.tvfPointer);
+ int32_t size = terms.size();
+
+ tvf->writeVInt(size);
+
+ bool storePositions = currentField->storePositions;
+ bool storeOffsets = currentField->storeOffsets;
+ uint8_t bits = 0x0;
+ if (storePositions)
+ bits |= STORE_POSITIONS_WITH_TERMVECTOR;
+ if (storeOffsets)
+ bits |= STORE_OFFSET_WITH_TERMVECTOR;
+ tvf->writeByte(bits);
+
+ const TCHAR* lastTermText = LUCENE_BLANK_STRING;
+ int32_t lastTermTextLen = 0;
+
+ for (int32_t i = 0; i < size; ++i) {
+ TVTerm* term = terms[i];
+ int32_t start = CL_NS(util)::Misc::stringDifference(lastTermText,
+ lastTermTextLen, term->getTermText(),term->getTermTextLen());
+ int32_t length = term->getTermTextLen() - start;
+ tvf->writeVInt(start); // write shared prefix length
+ tvf->writeVInt(length); // write delta length
+ tvf->writeChars(term->getTermText(), start, length); // write delta chars
+ tvf->writeVInt(term->freq);
+
+ lastTermText = term->getTermText();
+ lastTermTextLen = term->getTermTextLen();
+
+ if (storePositions) {
+ if(term->positions == NULL)
+ _CLTHROWA(CL_ERR_IllegalState, "Trying to write positions that are NULL!");
+
+ // use delta encoding for positions
+ int32_t position = 0;
+ for (int32_t j = 0; j < term->freq; ++j){
+ tvf->writeVInt((*term->positions)[j] - position);
+ position = (*term->positions)[j];
+ }
+ }
+
+ if (storeOffsets) {
+ if(term->offsets == NULL)
+ _CLTHROWA(CL_ERR_IllegalState, "Trying to write offsets that are NULL!");
+
+ // use delta encoding for offsets
+ int32_t position = 0;
+ for (int32_t j = 0; j < term->freq; ++j) {
+ tvf->writeVInt((*term->offsets)[j].getStartOffset() - position);
+ //Save the diff between the two.
+ tvf->writeVInt((*term->offsets)[j].getEndOffset() -
+ (*term->offsets)[j].getStartOffset());
+ position = (*term->offsets)[j].getEndOffset();
+ }
+ }
+ }
+}
+
+void TermVectorsWriter::writeDoc()
+{
+ if (isFieldOpen()) {
+ _CLTHROWA(CL_ERR_InvalidState,
+ "Field is still open while writing document");
+ }
+
+ // write document index record
+ tvx->writeLong(currentDocPointer);
+
+ // write document data record
+ int32_t size = fields.size();
+
+ // write the number of fields
+ tvd->writeVInt(size);
+
+ // write field numbers
+ for (int32_t j = 0; j < size; ++j) {
+ tvd->writeVInt(fields[j]->number);
+ }
+
+ // write field pointers
+ int64_t lastFieldPointer = 0;
+ for (int32_t i = 0; i < size; ++i) {
+ TVField* field = (TVField*) fields[i];
+ tvd->writeVLong(field->tvfPointer - lastFieldPointer);
+
+ lastFieldPointer = field->tvfPointer;
+ }
+}
+
+const TCHAR* TermVectorsWriter::TVTerm::getTermText() const
+{
+ return termText;
+}
+
+size_t TermVectorsWriter::TVTerm::getTermTextLen()
+{
+ if (termTextLen==-1)
+ termTextLen = _tcslen(termText);
+ return termTextLen;
+}
+
+void TermVectorsWriter::TVTerm::setTermText(const TCHAR* val)
+{
+ _CLDELETE_CARRAY(termText);
+ termText = STRDUP_TtoT(val);
+ termTextLen = -1;
+
+}
+
+TermVectorsWriter::TVTerm::TVTerm()
+ : freq(0)
+ , positions(NULL)
+ , offsets(NULL)
+{
+ termText=NULL;
+ termTextLen=-1;
+}
+
+TermVectorsWriter::TVTerm::~TVTerm()
+{
+ _CLDELETE_CARRAY(termText)
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/index/Terms.h b/3rdparty/clucene/src/CLucene/index/Terms.h
new file mode 100644
index 000000000..806441876
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/index/Terms.h
@@ -0,0 +1,174 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_index_Terms_
+#define _lucene_index_Terms_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "Term.h"
+CL_NS_DEF(index)
+
+class TermEnum; //predefine
+class TermPositions;
+
+/** TermDocs provides an interface for enumerating &lt;document, frequency&gt;
+ pairs for a term. <p> The document portion names each document containing
+ the term. Documents are indicated by number. The frequency portion gives
+ the number of times the term occurred in each document. <p> The pairs are
+ ordered by document number.
+
+ @see IndexReader#termDocs()
+ */
+class TermDocs: LUCENE_BASE {
+public:
+ virtual ~TermDocs(){
+ }
+
+ // Sets this to the data for a term.
+ // The enumeration is reset to the start of the data for this term.
+ virtual void seek(Term* term)=0;
+
+ /** Sets this to the data for the current term in a {@link TermEnum}.
+ * This may be optimized in some implementations.
+ */
+ virtual void seek(TermEnum* termEnum)=0;
+
+ // Returns the current document number. <p> This is invalid until {@link
+ // #next()} is called for the first time.
+ virtual int32_t doc() const=0;
+
+ // Returns the frequency of the term within the current document. <p> This
+ // is invalid until {@link #next()} is called for the first time.
+ virtual int32_t freq() const=0;
+
+ // Moves to the next pair in the enumeration. <p> Returns true iff there is
+ // such a next pair in the enumeration.
+ virtual bool next() =0;
+
+ // Attempts to read multiple entries from the enumeration, up to length of
+ // <i>docs</i>. Document numbers are stored in <i>docs</i>, and term
+ // frequencies are stored in <i>freqs</i>. The <i>freqs</i> array must be as
+ // int64_t as the <i>docs</i> array.
+ //
+ // <p>Returns the number of entries read. Zero is only returned when the
+ // stream has been exhausted.
+ virtual int32_t read(int32_t* docs, int32_t* freqs, int32_t length)=0;
+
+ // Skips entries to the first beyond the current whose document number is
+ // greater than or equal to <i>target</i>. <p>Returns true iff there is such
+ // an entry. <p>Behaves as if written: <pre>
+ // bool skipTo(int32_t target) {
+ // do {
+ // if (!next())
+ // return false;
+ // } while (target > doc());
+ // return true;
+ // }
+ // </pre>
+ // Some implementations are considerably more efficient than that.
+ virtual bool skipTo(const int32_t target)=0;
+
+ // Frees associated resources.
+ virtual void close() = 0;
+
+
+ /** Solve the diamond inheritence problem by providing a reinterpret function.
+ * No dynamic casting is required and no RTTI data is needed to do this
+ */
+ virtual TermPositions* __asTermPositions()=0;
+};
+
+
+// Abstract class for enumerating terms.
+//
+//<p>Term enumerations are always ordered by Term.compareTo(). Each term in
+//the enumeration is greater than all that precede it.
+class TermEnum: LUCENE_BASE {
+public:
+ // Increments the enumeration to the next element. True if one exists.
+ virtual bool next()=0;
+
+ // Returns a pointer to the current Term in the enumeration.
+ virtual Term* term()=0;
+
+ // Returns the current Term in the enumeration.
+ virtual Term* term(bool pointer){
+ Term* ret = term();
+ if ( !pointer )
+ ret->__cl_decref();
+ return ret;
+ }
+
+ // Returns the docFreq of the current Term in the enumeration.
+ virtual int32_t docFreq() const=0;
+
+ // Closes the enumeration to further activity, freeing resources.
+ virtual void close() =0;
+
+ virtual ~TermEnum(){
+ }
+
+ // Term Vector support
+ /** Skips terms to the first beyond the current whose value is
+ * greater or equal to <i>target</i>. <p>Returns true iff there is such
+ * an entry. <p>Behaves as if written: <pre>
+ * public boolean skipTo(Term target) {
+ * do {
+ * if (!next())
+ * return false;
+ * } while (target > term());
+ * return true;
+ * }
+ * </pre>
+ * Some implementations are considerably more efficient than that.
+ */
+ virtual bool skipTo(Term* target){
+ do {
+ if (!next())
+ return false;
+ } while (target->compareTo(term(false)) > 0);
+ return true;
+ }
+
+ /**
+ * Because we need to know how to cast the object, we need the objects name.
+ */
+ virtual const char* getObjectName() = 0;
+};
+
+
+
+/**
+ * TermPositions provides an interface for enumerating the &lt;document,
+ * frequency, &lt;position&gt;* &gt; tuples for a term. <p> The document and
+ * frequency are the same as for a TermDocs. The positions portion lists the ordinal
+ * positions of each occurrence of a term in a document.
+ *
+ * @see IndexReader#termPositions()
+ */
+class TermPositions: public virtual TermDocs {
+public:
+ // Returns next position in the current document. It is an error to call
+ // this more than {@link #freq()} times
+ // without calling {@link #next()}<p> This is
+ // invalid until {@link #next()} is called for
+ // the first time.
+ virtual int32_t nextPosition() = 0;
+
+ virtual ~TermPositions(){
+ }
+
+ /** Solve the diamond inheritence problem by providing a reinterpret function.
+ * No dynamic casting is required and no RTTI data is needed to do this
+ */
+ virtual TermDocs* __asTermDocs()=0;
+ virtual TermPositions* __asTermPositions()=0;
+};
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/queryParser/Lexer.cpp b/3rdparty/clucene/src/CLucene/queryParser/Lexer.cpp
new file mode 100644
index 000000000..861c5d3cb
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/Lexer.cpp
@@ -0,0 +1,371 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "Lexer.h"
+
+#include "CLucene/util/FastCharStream.h"
+#include "CLucene/util/Reader.h"
+#include "CLucene/util/StringBuffer.h"
+#include "TokenList.h"
+#include "QueryToken.h"
+#include "QueryParserBase.h"
+
+CL_NS_USE(util)
+
+CL_NS_DEF(queryParser)
+Lexer::Lexer(QueryParserBase* queryparser, const TCHAR* query) {
+ //Func - Constructor
+ //Pre - query != NULL and contains the query string
+ //Post - An instance of Lexer has been created
+
+ this->queryparser = queryparser;
+
+ CND_PRECONDITION(query != NULL, "query is NULL");
+
+ //The InputStream of Reader must be destroyed in the destructor
+ delSR = true;
+
+ StringReader *r = _CLNEW StringReader(query);
+
+ //Check to see if r has been created properly
+ CND_CONDITION(r != NULL, "Could not allocate memory for StringReader r");
+
+ //Instantie a FastCharStream instance using r and assign it to reader
+ reader = _CLNEW FastCharStream(r);
+
+ //Check to see if reader has been created properly
+ CND_CONDITION(reader != NULL, "Could not allocate memory for FastCharStream reader");
+
+ //The InputStream of Reader must be destroyed in the destructor
+ delSR = true;
+
+}
+
+
+Lexer::Lexer(QueryParserBase* queryparser, Reader* source) {
+ //Func - Constructor
+ // Initializes a new instance of the Lexer class with the specified
+ // TextReader to lex.
+ //Pre - Source contains a valid reference to a Reader
+ //Post - An instance of Lexer has been created using source as the reader
+
+ this->queryparser = queryparser;
+
+ //Instantie a FastCharStream instance using r and assign it to reader
+ reader = _CLNEW FastCharStream(source);
+
+ //Check to see if reader has been created properly
+ CND_CONDITION(reader != NULL, "Could not allocate memory for FastCharStream reader");
+
+ //The InputStream of Reader must not be destroyed in the destructor
+ delSR = false;
+}
+
+
+Lexer::~Lexer() {
+ //Func - Destructor
+ //Pre - true
+ //Post - if delSR was true the InputStream input of reader has been deleted
+ // The instance of Lexer has been destroyed
+
+ if (delSR) {
+ _CLDELETE(reader->input);
+ }
+
+ _CLDELETE(reader);
+}
+
+
+void Lexer::Lex(TokenList *tokenList) {
+ //Func - Breaks the input stream onto the tokens list tokens
+ //Pre - tokens != NULL and contains a TokenList in which the tokens can be stored
+ //Post - The tokens have been added to the TokenList tokens
+
+ CND_PRECONDITION(tokenList != NULL, "tokens is NULL");
+
+ //Get all the tokens
+ while(true) {
+ //Add the token to the tokens list
+
+ //Get the next token
+ QueryToken* token = _CLNEW QueryToken;
+ if ( !GetNextToken(token) ){
+ _CLDELETE(token);
+ break;
+ }
+ tokenList->add(token);
+ }
+
+ //The end has been reached so create an EOF_ token
+ //Add the final token to the TokenList _tokens
+ tokenList->add(_CLNEW QueryToken( QueryToken::EOF_));
+}
+
+
+bool Lexer::GetNextToken(QueryToken* token) {
+ while(!reader->Eos()) {
+ int ch = reader->GetNext();
+
+ if ( ch == -1 )
+ break;
+
+ // skipping whitespaces
+ if( _istspace(ch)!=0 ) {
+ continue;
+ }
+ TCHAR buf[2] = {ch,'\0'};
+ switch(ch) {
+ case '+':
+ token->set(buf, QueryToken::PLUS);
+ return true;
+ case '-':
+ token->set(buf, QueryToken::MINUS);
+ return true;
+ case '(':
+ token->set(buf, QueryToken::LPAREN);
+ return true;
+ case ')':
+ token->set(buf, QueryToken::RPAREN);
+ return true;
+ case ':':
+ token->set(buf, QueryToken::COLON);
+ return true;
+ case '!':
+ token->set(buf, QueryToken::NOT);
+ return true;
+ case '^':
+ token->set(buf, QueryToken::CARAT);
+ return true;
+ case '~':
+ if( _istdigit( reader->Peek() )!=0 ) {
+ TCHAR number[LUCENE_MAX_FIELD_LEN];
+ ReadIntegerNumber(ch, number,LUCENE_MAX_FIELD_LEN);
+ token->set(number, QueryToken::SLOP);
+ return true;
+ }else{
+ token->set(buf, QueryToken::FUZZY);
+ return true;
+ }
+ break;
+ case '"':
+ return ReadQuoted(ch, token);
+ case '[':
+ return ReadInclusiveRange(ch, token);
+ case '{':
+ return ReadExclusiveRange(ch, token);
+ case ']':
+ case '}':
+ case '*':
+ queryparser->throwParserException( _T("Unrecognized TCHAR %d at %d::%d."),
+ ch, reader->Column(), reader->Line() );
+ return false;
+ default:
+ return ReadTerm(ch, token);
+
+ // end of swith
+ }
+
+ }
+ return false;
+}
+
+
+void Lexer::ReadIntegerNumber(const TCHAR ch, TCHAR* buf, int buflen) {
+ int bp=0;
+ buf[bp++] = ch;
+
+ int c = reader->Peek();
+ while( c!=-1 && _istdigit(c)!=0 && bp<buflen-1 ) {
+ buf[bp++] = reader->GetNext();
+ c = reader->Peek();
+ }
+ buf[bp++] = 0;
+}
+
+
+bool Lexer::ReadInclusiveRange(const TCHAR prev, QueryToken* token) {
+ int ch = prev;
+ StringBuffer range;
+ range.appendChar(ch);
+
+ while(!reader->Eos()) {
+ ch = reader->GetNext();
+ if ( ch == -1 )
+ break;
+ range.appendChar(ch);
+
+ if(ch == ']'){
+ token->set(range.getBuffer(), QueryToken::RANGEIN);
+ return true;
+ }
+ }
+ queryparser->throwParserException(_T("Unterminated inclusive range! %d %d::%d"),' ',
+ reader->Column(),reader->Column());
+ return false;
+}
+
+
+bool Lexer::ReadExclusiveRange(const TCHAR prev, QueryToken* token) {
+ int ch = prev;
+ StringBuffer range;
+ range.appendChar(ch);
+
+ while(!reader->Eos()) {
+ ch = reader->GetNext();
+
+ if (ch==-1)
+ break;
+ range.appendChar(ch);
+
+ if(ch == '}'){
+ token->set(range.getBuffer(), QueryToken::RANGEEX);
+ return true;
+ }
+ }
+ queryparser->throwParserException(_T("Unterminated exclusive range! %d %d::%d"),' ',
+ reader->Column(),reader->Column() );
+ return false;
+}
+
+bool Lexer::ReadQuoted(const TCHAR prev, QueryToken* token) {
+ int ch = prev;
+ StringBuffer quoted;
+ quoted.appendChar(ch);
+
+ while(!reader->Eos()) {
+ ch = reader->GetNext();
+
+ if (ch==-1)
+ break;
+
+ quoted.appendChar(ch);
+
+ if(ch == '"'){
+ token->set(quoted.getBuffer(), QueryToken::QUOTED);
+ return true;
+ }
+ }
+ queryparser->throwParserException(_T("Unterminated string! %d %d::%d"),' ',
+ reader->Column(),reader->Column());
+ return false;
+}
+
+
+bool Lexer::ReadTerm(const TCHAR prev, QueryToken* token) {
+ int ch = prev;
+ bool completed = false;
+ int32_t asteriskCount = 0;
+ bool hasQuestion = false;
+
+ StringBuffer val;
+ TCHAR buf[3]; //used for readescaped
+
+ while(true) {
+ switch(ch) {
+ case -1:
+ break;
+ case '\\':
+ {
+ if ( ReadEscape(ch, buf) )
+ val.append( buf );
+ else
+ return false;
+ }
+ break;
+
+ case LUCENE_WILDCARDTERMENUM_WILDCARD_STRING:
+ asteriskCount++;
+ val.appendChar(ch);
+ break;
+ case LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR:
+ hasQuestion = true;
+ val.appendChar(ch);
+ break;
+ case '\n':
+ case '\t':
+ case ' ':
+ case '+':
+ case '-':
+ case '!':
+ case '(':
+ case ')':
+ case ':':
+ case '^':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ case '~':
+ case '"':
+ // create new QueryToken
+ reader->UnGet();
+ completed = true;
+ break;
+ default:
+ val.appendChar(ch);
+ break;
+ // end of switch
+ }
+
+ if(completed || ch==-1 || reader->Eos() )
+ break;
+ else
+ ch = reader->GetNext();
+ }
+
+ // create new QueryToken
+ if(hasQuestion)
+ token->set(val.getBuffer(), QueryToken::WILDTERM);
+ else if(asteriskCount == 1 && val.getBuffer()[val.length() - 1] == '*')
+ token->set(val.getBuffer(), QueryToken::PREFIXTERM);
+ else if(asteriskCount > 0)
+ token->set(val.getBuffer(), QueryToken::WILDTERM);
+ else if( _tcsicmp(val.getBuffer(), _T("AND"))==0 || _tcscmp(val.getBuffer(), _T("&&"))==0 )
+ token->set(val.getBuffer(), QueryToken::AND_);
+ else if( _tcsicmp(val.getBuffer(), _T("OR"))==0 || _tcscmp(val.getBuffer(), _T("||"))==0)
+ token->set(val.getBuffer(), QueryToken::OR);
+ else if( _tcsicmp(val.getBuffer(), _T("NOT"))==0 )
+ token->set(val.getBuffer(), QueryToken::NOT);
+ else {
+ bool isnum = true;
+ int32_t nlen=val.length();
+ for (int32_t i=0;i<nlen;++i) {
+ TCHAR ch=val.getBuffer()[i];
+ if ( _istalpha(ch) ) {
+ isnum=false;
+ break;
+ }
+ }
+
+ if ( isnum )
+ token->set(val.getBuffer(), QueryToken::NUMBER);
+ else
+ token->set(val.getBuffer(), QueryToken::TERM);
+ }
+ return true;
+}
+
+
+bool Lexer::ReadEscape(TCHAR prev, TCHAR* buf) {
+ TCHAR ch = prev;
+ int bp=0;
+ buf[bp++] = ch;
+
+ ch = reader->GetNext();
+ int32_t idx = _tcscspn( buf, _T("\\+-!():^[]{}\"~*") );
+ if(idx == 0) {
+ buf[bp++] = ch;
+ buf[bp++]=0;
+ return true;
+ }
+ queryparser->throwParserException(_T("Unrecognized escape sequence at %d %d::%d"), ' ',
+ reader->Column(),reader->Line());
+ return false;
+}
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/queryParser/Lexer.h b/3rdparty/clucene/src/CLucene/queryParser/Lexer.h
new file mode 100644
index 000000000..b3b55523e
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/Lexer.h
@@ -0,0 +1,67 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#ifndef _lucene_queryParser_Lexer_
+#define _lucene_queryParser_Lexer_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/FastCharStream.h"
+#include "CLucene/util/Reader.h"
+#include "CLucene/util/StringBuffer.h"
+
+#include "TokenList.h"
+
+CL_NS_DEF(queryParser)
+class QueryParserBase;
+ // A simple Lexer that is used by QueryParser.
+ class Lexer:LUCENE_BASE
+ {
+ private:
+ CL_NS(util)::FastCharStream* reader;
+ QueryParserBase* queryparser; //holds the queryparser so that we can do callbacks
+ bool delSR; //Indicates if the reader must be deleted or not
+
+ public:
+ // Initializes a new instance of the Lexer class with the specified
+ // query to lex.
+ Lexer(QueryParserBase* queryparser, const TCHAR* query);
+
+ // Initializes a new instance of the Lexer class with the specified
+ // TextReader to lex.
+ Lexer(QueryParserBase* queryparser, CL_NS(util)::Reader* source);
+
+ //Breaks the input stream onto the tokens list tokens
+ void Lex(TokenList *tokens);
+
+ ~Lexer();
+
+ private:
+ bool GetNextToken(QueryToken* token);
+
+ // Reads an integer number. buf should quite large, probably as large as a field should ever be
+ void ReadIntegerNumber(const TCHAR ch, TCHAR* buf, int buflen);
+
+ // Reads an inclusive range like [some words]
+ bool ReadInclusiveRange(const TCHAR prev, QueryToken* token);
+
+ // Reads an exclusive range like {some words}
+ bool ReadExclusiveRange(const TCHAR prev, QueryToken* token);
+
+ // Reads quoted string like "something else"
+ bool ReadQuoted(const TCHAR prev, QueryToken* token);
+
+ bool ReadTerm(const TCHAR prev, QueryToken* token);
+
+ //reads an escaped character into the buf. Buf requires at least 3 characters
+ bool ReadEscape(const TCHAR prev, TCHAR* buf);
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.cpp b/3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.cpp
new file mode 100644
index 000000000..b57896b66
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.cpp
@@ -0,0 +1,215 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "MultiFieldQueryParser.h"
+#include "CLucene/analysis/AnalysisHeader.h"
+#include "CLucene/search/BooleanQuery.h"
+#include "CLucene/search/PhraseQuery.h"
+#include "CLucene/search/SearchHeader.h"
+#include "QueryParser.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_USE(search)
+CL_NS_USE(analysis)
+
+CL_NS_DEF(queryParser)
+
+MultiFieldQueryParser::MultiFieldQueryParser(const TCHAR** fields,
+ CL_NS(analysis)::Analyzer* analyzer, BoostMap* boosts)
+ : QueryParser(NULL, analyzer)
+{
+ this->fields = fields;
+ this->boosts = boosts;
+}
+
+MultiFieldQueryParser::~MultiFieldQueryParser()
+{
+}
+
+//static
+Query* MultiFieldQueryParser::parse(const TCHAR* query, const TCHAR** fields,
+ Analyzer* analyzer)
+{
+ BooleanQuery* bQuery = _CLNEW BooleanQuery();
+ int32_t i = 0;
+ while (fields[i] != NULL){
+ Query* q = QueryParser::parse(query, fields[i], analyzer);
+ if (q && (q->getQueryName() != _T("BooleanQuery")
+ || ((BooleanQuery*)q)->getClauseCount() > 0)) {
+ bQuery->add(q , true, false, false);
+ } else {
+ _CLDELETE(q);
+ }
+ i++;
+ }
+ return bQuery;
+}
+
+//static
+Query* MultiFieldQueryParser::parse(const TCHAR* query, const TCHAR** fields,
+ const uint8_t* flags, Analyzer* analyzer)
+{
+ BooleanQuery* bQuery = _CLNEW BooleanQuery();
+ int32_t i = 0;
+ while ( fields[i] != NULL ) {
+ Query* q = QueryParser::parse(query, fields[i], analyzer);
+ if (q && (q->getQueryName() != _T("BooleanQuery")
+ || ((BooleanQuery*)q)->getClauseCount() > 0)) {
+ uint8_t flag = flags[i];
+ switch (flag) {
+ case MultiFieldQueryParser::REQUIRED_FIELD:
+ bQuery->add(q, true, true, false);
+ break;
+ case MultiFieldQueryParser::PROHIBITED_FIELD:
+ bQuery->add(q, true, false, true);
+ break;
+ default:
+ bQuery->add(q, true, false, false);
+ break;
+ }
+ } else {
+ _CLDELETE(q);
+ }
+ i++;
+ }
+ return bQuery;
+}
+
+
+Query* MultiFieldQueryParser::GetFieldQuery(const TCHAR* field, TCHAR* queryText, int32_t slop){
+ if (field == NULL) {
+ CL_NS_STD(vector)<BooleanClause*> clauses;
+ for (int i = 0; fields[i]!=NULL; ++i) {
+ Query* q = QueryParser::GetFieldQuery(fields[i], queryText);
+ if (q != NULL) {
+ //If the user passes a map of boosts
+ if (boosts != NULL) {
+ //Get the boost from the map and apply them
+ BoostMap::const_iterator itr = boosts->find(fields[i]);
+ if (itr != boosts->end()) {
+ q->setBoost(itr->second);
+ }
+ }
+ if (q->getQueryName() == PhraseQuery::getClassName()) {
+ ((PhraseQuery*)q)->setSlop(slop);
+ }
+ //if (q instanceof MultiPhraseQuery) {
+ // ((MultiPhraseQuery) q).setSlop(slop);
+ //}
+ q = QueryAddedCallback(fields[i], q);
+ if ( q )
+ clauses.push_back(_CLNEW BooleanClause(q, true, false,false));
+ }
+ }
+ if (clauses.size() == 0) // happens for stopwords
+ return NULL;
+ Query* q = QueryParser::GetBooleanQuery(clauses);
+ return q;
+ }else{
+ Query* q = QueryParser::GetFieldQuery(field, queryText);
+ if ( q )
+ q = QueryAddedCallback(field,q);
+ return q;
+ }
+}
+
+
+Query* MultiFieldQueryParser::GetFieldQuery(const TCHAR* field, TCHAR* queryText){
+ return GetFieldQuery(field, queryText, 0);
+}
+
+
+CL_NS(search)::Query* MultiFieldQueryParser::GetFuzzyQuery(const TCHAR* field, TCHAR* termStr){
+ if (field == NULL) {
+ CL_NS_STD(vector)<BooleanClause*> clauses;
+ for (int i = 0; fields[i]!=NULL; ++i) {
+ Query* q = QueryParser::GetFuzzyQuery(fields[i], termStr); //todo: , minSimilarity
+ if ( q ){
+ q = QueryAddedCallback(fields[i], q);
+ if ( q ){
+ clauses.push_back(_CLNEW BooleanClause(q,true,false,false) );
+ }
+ }
+ }
+ return QueryParser::GetBooleanQuery(clauses);
+ }else{
+ Query* q = QueryParser::GetFuzzyQuery(field, termStr);//todo: , minSimilarity
+ if ( q )
+ q = QueryAddedCallback(field,q);
+ return q;
+ }
+}
+
+Query* MultiFieldQueryParser::GetPrefixQuery(const TCHAR* field, TCHAR* termStr){
+ if (field == NULL) {
+ CL_NS_STD(vector)<BooleanClause*> clauses;
+ for (int i = 0; fields[i]!=NULL; ++i) {
+ Query* q = QueryParser::GetPrefixQuery(fields[i], termStr);
+ if ( q ){
+ q = QueryAddedCallback(fields[i],q);
+ if ( q ){
+ clauses.push_back(_CLNEW BooleanClause(q,true,false,false));
+ }
+ }
+ }
+ return QueryParser::GetBooleanQuery(clauses);
+ }else{
+ Query* q = QueryParser::GetPrefixQuery(field, termStr);
+ if ( q )
+ q = QueryAddedCallback(field,q);
+ return q;
+ }
+}
+
+Query* MultiFieldQueryParser::GetWildcardQuery(const TCHAR* field, TCHAR* termStr){
+ if (field == NULL) {
+ CL_NS_STD(vector)<BooleanClause*> clauses;
+ for (int i = 0; fields[i]!=NULL; ++i) {
+ Query* q = QueryParser::GetWildcardQuery(fields[i], termStr);
+ if ( q ){
+ q = QueryAddedCallback(fields[i],q);
+ if ( q ){
+ clauses.push_back(_CLNEW BooleanClause(q,true,false,false));
+ }
+ }
+ }
+ return QueryParser::GetBooleanQuery(clauses);
+ }else{
+ Query* q = QueryParser::GetWildcardQuery(field, termStr);
+ if ( q )
+ q = QueryAddedCallback(field,q);
+ return q;
+ }
+}
+
+
+Query* MultiFieldQueryParser::GetRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, bool inclusive){
+ if (field == NULL) {
+ CL_NS_STD(vector)<BooleanClause*> clauses;
+ for (int i = 0; fields[i]!=NULL; ++i) {
+ Query* q = QueryParser::GetRangeQuery(fields[i], part1, part2, inclusive);
+ if ( q ){
+ q = QueryAddedCallback(fields[i],q);
+ if ( q ){
+ clauses.push_back(_CLNEW BooleanClause(q,true,false,false));
+ }
+ }
+ }
+ return QueryParser::GetBooleanQuery(clauses);
+ }else{
+ Query* q = QueryParser::GetRangeQuery(field, part1, part2, inclusive);
+ if ( q )
+ q = QueryAddedCallback(field,q);
+ return q;
+ }
+}
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.h b/3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.h
new file mode 100644
index 000000000..bf7d652a7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.h
@@ -0,0 +1,136 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef MultiFieldQueryParser_H
+#define MultiFieldQueryParser_H
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/analysis/AnalysisHeader.h"
+#include "CLucene/search/SearchHeader.h"
+#include "QueryParser.h"
+
+
+CL_NS_DEF(queryParser)
+
+typedef CL_NS(util)::CLHashMap<const TCHAR*,
+ qreal,
+ CL_NS(util)::Compare::TChar,
+ CL_NS(util)::Equals::TChar,
+ CL_NS(util)::Deletor::tcArray,
+ CL_NS(util)::Deletor::DummyFloat
+ > BoostMap;
+
+ /**
+ * A QueryParser which constructs queries to search multiple fields.
+ *
+ */
+ class MultiFieldQueryParser: public QueryParser
+ {
+ protected:
+ const TCHAR** fields;
+ BoostMap* boosts;
+ public:
+ LUCENE_STATIC_CONSTANT(uint8_t, NORMAL_FIELD=0);
+ LUCENE_STATIC_CONSTANT(uint8_t, REQUIRED_FIELD=1);
+ LUCENE_STATIC_CONSTANT(uint8_t, PROHIBITED_FIELD=2);
+
+ /**
+ * Creates a MultiFieldQueryParser.
+ *
+ * <p>It will, when parse(String query)
+ * is called, construct a query like this (assuming the query consists of
+ * two terms and you specify the two fields <code>title</code> and <code>body</code>):</p>
+ *
+ * <code>
+ * (title:term1 body:term1) (title:term2 body:term2)
+ * </code>
+ *
+ * <p>When setDefaultOperator(AND_OPERATOR) is set, the result will be:</p>
+ *
+ * <code>
+ * +(title:term1 body:term1) +(title:term2 body:term2)
+ * </code>
+ *
+ * <p>In other words, all the query's terms must appear, but it doesn't matter in
+ * what fields they appear.</p>
+ */
+ MultiFieldQueryParser(const TCHAR** fields, CL_NS(analysis)::Analyzer* a, BoostMap* boosts = NULL);
+ virtual ~MultiFieldQueryParser();
+
+ /**
+ * <p>
+ * Parses a query which searches on the fields specified.
+ * <p>
+ * If x fields are specified, this effectively constructs:
+ * <pre>
+ * <code>
+ * (field1:query) (field2:query) (field3:query)...(fieldx:query)
+ * </code>
+ * </pre>
+ *
+ * @param query Query string to parse
+ * @param fields Fields to search on
+ * @param analyzer Analyzer to use
+ * @throws ParserException if query parsing fails
+ * @throws TokenMgrError if query parsing fails
+ */
+ static CL_NS(search)::Query* parse(const TCHAR* query, const TCHAR** fields, CL_NS(analysis)::Analyzer* analyzer);
+
+ /**
+ * <p>
+ * Parses a query, searching on the fields specified.
+ * Use this if you need to specify certain fields as required,
+ * and others as prohibited.
+ * <p><pre>
+ * Usage:
+ * <code>
+ * String[] fields = {"filename", "contents", "description"};
+ * int32_t[] flags = {MultiFieldQueryParser.NORMAL FIELD,
+ * MultiFieldQueryParser.REQUIRED FIELD,
+ * MultiFieldQueryParser.PROHIBITED FIELD,};
+ * parse(query, fields, flags, analyzer);
+ * </code>
+ * </pre>
+ *<p>
+ * The code above would construct a query:
+ * <pre>
+ * <code>
+ * (filename:query) +(contents:query) -(description:query)
+ * </code>
+ * </pre>
+ *
+ * @param query Query string to parse
+ * @param fields Fields to search on
+ * @param flags Flags describing the fields
+ * @param analyzer Analyzer to use
+ * @throws ParserException if query parsing fails
+ * @throws TokenMgrError if query parsing fails
+ */
+ static CL_NS(search)::Query* parse(const TCHAR* query, const TCHAR** fields, const uint8_t* flags, CL_NS(analysis)::Analyzer* analyzer);
+
+
+
+ protected:
+ CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, TCHAR* queryText);
+ CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, TCHAR* queryText, int32_t slop);
+ CL_NS(search)::Query* GetFuzzyQuery(const TCHAR* field, TCHAR* termStr);
+ CL_NS(search)::Query* GetRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, bool inclusive);
+ CL_NS(search)::Query* GetPrefixQuery(const TCHAR* field, TCHAR* termStr);
+ CL_NS(search)::Query* GetWildcardQuery(const TCHAR* field, TCHAR* termStr);
+
+ /**
+ * A special virtual function for the MultiFieldQueryParser which can be used
+ * to clean up queries. Once the field name is known and the query has been
+ * created, its passed to this function.
+ * An example of this usage is to set boosts.
+ */
+ virtual CL_NS(search)::Query* QueryAddedCallback(const TCHAR* field, CL_NS(search)::Query* query){ return query; }
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/queryParser/QueryParser.cpp b/3rdparty/clucene/src/CLucene/queryParser/QueryParser.cpp
new file mode 100644
index 000000000..b11eec0bb
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/QueryParser.cpp
@@ -0,0 +1,509 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "QueryParser.h"
+
+#include "CLucene/analysis/AnalysisHeader.h"
+#include "CLucene/util/Reader.h"
+#include "CLucene/search/SearchHeader.h"
+#include "CLucene/index/Term.h"
+
+#include "TokenList.h"
+#include "QueryToken.h"
+#include "QueryParserBase.h"
+#include "Lexer.h"
+
+CL_NS_USE(util)
+CL_NS_USE(index)
+CL_NS_USE(analysis)
+CL_NS_USE(search)
+
+CL_NS_DEF(queryParser)
+
+ QueryParser::QueryParser(const TCHAR* _field, Analyzer* _analyzer) : QueryParserBase(_analyzer){
+ //Func - Constructor.
+ // Instantiates a QueryParser for the named field _field
+ //Pre - _field != NULL
+ //Post - An instance has been created
+
+ if ( _field )
+ field = STRDUP_TtoT(_field);
+ else
+ field = NULL;
+ tokens = NULL;
+ lowercaseExpandedTerms = true;
+ }
+
+ QueryParser::~QueryParser() {
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ _CLDELETE_CARRAY(field);
+ }
+
+ //static
+ Query* QueryParser::parse(const TCHAR* query, const TCHAR* field, Analyzer* analyzer){
+ //Func - Returns a new instance of the Query class with a specified query, field and
+ // analyzer values.
+ //Pre - query != NULL and holds the query to parse
+ // field != NULL and holds the default field for query terms
+ // analyzer holds a valid reference to an Analyzer and is used to
+ // find terms in the query text
+ //Post - query has been parsed and an instance of Query has been returned
+
+ CND_PRECONDITION(query != NULL, "query is NULL");
+ CND_PRECONDITION(field != NULL, "field is NULL");
+
+ QueryParser parser(field, analyzer);
+ return parser.parse(query);
+ }
+
+ Query* QueryParser::parse(const TCHAR* query){
+ //Func - Returns a parsed Query instance
+ //Pre - query != NULL and contains the query value to be parsed
+ //Post - Returns a parsed Query Instance
+
+ CND_PRECONDITION(query != NULL, "query is NULL");
+
+ //Instantie a Stringer that can read the query string
+ Reader* r = _CLNEW StringReader(query);
+
+ //Check to see if r has been created properly
+ CND_CONDITION(r != NULL, "Could not allocate memory for StringReader r");
+
+ //Pointer for the return value
+ Query* ret = NULL;
+
+ try{
+ //Parse the query managed by the StringReader R and return a parsed Query instance
+ //into ret
+ ret = parse(r);
+ }_CLFINALLY (
+ _CLDELETE(r);
+ );
+
+ return ret;
+ }
+
+ Query* QueryParser::parse(Reader* reader){
+ //Func - Returns a parsed Query instance
+ //Pre - reader contains a valid reference to a Reader and manages the query string
+ //Post - A parsed Query instance has been returned or
+
+ //instantiate the TokenList tokens
+ TokenList _tokens;
+ this->tokens = &_tokens;
+
+ //Instantiate a lexer
+ Lexer lexer(this, reader);
+
+ //tokens = lexer.Lex();
+ //Lex the tokens
+ lexer.Lex(tokens);
+
+ //Peek to the first token and check if is an EOF
+ if (tokens->peek()->Type == QueryToken::EOF_){
+ // The query string failed to yield any tokens. We discard the
+ // TokenList tokens and raise an exceptioin.
+ QueryToken* token = this->tokens->extract();
+ _CLDELETE(token);
+ _CLTHROWA(CL_ERR_Parse, "No query given.");
+ }
+
+ //Return the parsed Query instance
+ Query* ret = MatchQuery(field);
+ this->tokens = NULL;
+ return ret;
+ }
+
+ int32_t QueryParser::MatchConjunction(){
+ //Func - matches for CONJUNCTION
+ // CONJUNCTION ::= <AND> | <OR>
+ //Pre - tokens != NULL
+ //Post - if the first token is an AND or an OR then
+ // the token is extracted and deleted and CONJ_AND or CONJ_OR is returned
+ // otherwise CONJ_NONE is returned
+
+ CND_PRECONDITION(tokens != NULL, "tokens is NULL");
+
+ switch(tokens->peek()->Type){
+ case QueryToken::AND_ :
+ //Delete the first token of tokenlist
+ ExtractAndDeleteToken();
+ return CONJ_AND;
+ case QueryToken::OR :
+ //Delete the first token of tokenlist
+ ExtractAndDeleteToken();
+ return CONJ_OR;
+ default :
+ return CONJ_NONE;
+ }
+ }
+
+ int32_t QueryParser::MatchModifier(){
+ //Func - matches for MODIFIER
+ // MODIFIER ::= <PLUS> | <MINUS> | <NOT>
+ //Pre - tokens != NULL
+ //Post - if the first token is a PLUS the token is extracted and deleted and MOD_REQ is returned
+ // if the first token is a MINUS or NOT the token is extracted and deleted and MOD_NOT is returned
+ // otherwise MOD_NONE is returned
+ CND_PRECONDITION(tokens != NULL, "tokens is NULL");
+
+ switch(tokens->peek()->Type){
+ case QueryToken::PLUS :
+ //Delete the first token of tokenlist
+ ExtractAndDeleteToken();
+ return MOD_REQ;
+ case QueryToken::MINUS :
+ case QueryToken::NOT :
+ //Delete the first token of tokenlist
+ ExtractAndDeleteToken();
+ return MOD_NOT;
+ default :
+ return MOD_NONE;
+ }
+ }
+
+ Query* QueryParser::MatchQuery(const TCHAR* field){
+ //Func - matches for QUERY
+ // QUERY ::= [MODIFIER] QueryParser::CLAUSE (<CONJUNCTION> [MODIFIER] CLAUSE)*
+ //Pre - field != NULL
+ //Post -
+
+ CND_PRECONDITION(tokens != NULL, "tokens is NULL");
+
+ CL_NS_STD(vector)<BooleanClause*> clauses;
+
+ Query* q = NULL;
+
+ int32_t mods = MOD_NONE;
+ int32_t conj = CONJ_NONE;
+
+ //match for MODIFIER
+ mods = MatchModifier();
+
+ //match for CLAUSE
+ q = MatchClause(field);
+ AddClause(clauses, CONJ_NONE, mods, q);
+
+ // match for CLAUSE*
+ while(true){
+ QueryToken* p = tokens->peek();
+ if(p->Type == QueryToken::EOF_){
+ QueryToken* qt = MatchQueryToken(QueryToken::EOF_);
+ _CLDELETE(qt);
+ break;
+ }
+
+ if(p->Type == QueryToken::RPAREN){
+ //MatchQueryToken(QueryToken::RPAREN);
+ break;
+ }
+
+ //match for a conjuction (AND OR NOT)
+ conj = MatchConjunction();
+ //match for a modifier
+ mods = MatchModifier();
+
+ q = MatchClause(field);
+ if ( q != NULL )
+ AddClause(clauses, conj, mods, q);
+ }
+
+ // finalize query
+ if(clauses.size() == 1){ //bvk: removed this && firstQuery != NULL
+ BooleanClause* c = clauses[0];
+ Query* q = c->query;
+
+ //Condition check to be sure clauses[0] is valid
+ CND_CONDITION(c != NULL, "c is NULL");
+
+ //Tell the boolean clause not to delete its query
+ c->deleteQuery=false;
+ //Clear the clauses list
+ clauses.clear();
+ _CLDELETE(c);
+
+ return q;
+ }else{
+ return GetBooleanQuery(clauses);
+ }
+ }
+
+ Query* QueryParser::MatchClause(const TCHAR* field){
+ //Func - matches for CLAUSE
+ // CLAUSE ::= [TERM <COLONQueryParser::>] ( TERM | (<LPAREN> QUERY <RPAREN>))
+ //Pre - field != NULL
+ //Post -
+
+ Query* q = NULL;
+ const TCHAR* sfield = field;
+ bool delField = false;
+
+ QueryToken *DelToken = NULL;
+
+ //match for [TERM <COLON>]
+ QueryToken* term = tokens->extract();
+ if(term->Type == QueryToken::TERM && tokens->peek()->Type == QueryToken::COLON){
+ DelToken = MatchQueryToken(QueryToken::COLON);
+
+ CND_CONDITION(DelToken != NULL,"DelToken is NULL");
+ _CLDELETE(DelToken);
+
+ TCHAR* tmp = STRDUP_TtoT(term->Value);
+ discardEscapeChar(tmp);
+ delField = true;
+ sfield = tmp;
+ _CLDELETE(term);
+ }else{
+ tokens->push(term);
+ term = NULL;
+ }
+
+ // match for
+ // TERM | (<LPAREN> QUERY <RPAREN>)
+ if(tokens->peek()->Type == QueryToken::LPAREN){
+ DelToken = MatchQueryToken(QueryToken::LPAREN);
+
+ CND_CONDITION(DelToken != NULL,"DelToken is NULL");
+ _CLDELETE(DelToken);
+
+ q = MatchQuery(sfield);
+ //DSR:2004.11.01:
+ //If exception is thrown while trying to match trailing parenthesis,
+ //need to prevent q from leaking.
+
+ try{
+ DelToken = MatchQueryToken(QueryToken::RPAREN);
+
+ CND_CONDITION(DelToken != NULL,"DelToken is NULL");
+ _CLDELETE(DelToken);
+
+ }catch(...) {
+ _CLDELETE(q);
+ throw;
+ }
+ }else{
+ q = MatchTerm(sfield);
+ }
+
+ if ( delField )
+ _CLDELETE_CARRAY(sfield);
+ return q;
+ }
+
+
+ Query* QueryParser::MatchTerm(const TCHAR* field){
+ //Func - matches for TERM
+ // TERM ::= TERM | PREFIXTERM | WILDTERM | NUMBER
+ // [ <FUZZY> ] [ <CARAT> <NUMBER> [<FUZZY>]]
+ // | (<RANGEIN> | <RANGEEX>) [<CARAT> <NUMBER>]
+ // | <QUOTED> [SLOP] [<CARAT> <NUMBER>]
+ //Pre - field != NULL
+ //Post -
+
+ QueryToken* term = NULL;
+ QueryToken* slop = NULL;
+ QueryToken* boost = NULL;
+
+ bool prefix = false;
+ bool wildcard = false;
+ bool fuzzy = false;
+ bool rangein = false;
+ Query* q = NULL;
+
+ term = tokens->extract();
+ QueryToken* DelToken = NULL; //Token that is about to be deleted
+
+ switch(term->Type){
+ case QueryToken::TERM:
+ case QueryToken::NUMBER:
+ case QueryToken::PREFIXTERM:
+ case QueryToken::WILDTERM:
+ { //start case
+ //Check if type of QueryToken term is a prefix term
+ if(term->Type == QueryToken::PREFIXTERM){
+ prefix = true;
+ }
+ //Check if type of QueryToken term is a wildcard term
+ if(term->Type == QueryToken::WILDTERM){
+ wildcard = true;
+ }
+ //Peek to see if the type of the next token is fuzzy term
+ if(tokens->peek()->Type == QueryToken::FUZZY){
+ DelToken = MatchQueryToken(QueryToken::FUZZY);
+
+ CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
+ _CLDELETE(DelToken);
+
+ fuzzy = true;
+ }
+ if(tokens->peek()->Type == QueryToken::CARAT){
+ DelToken = MatchQueryToken(QueryToken::CARAT);
+
+ CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
+ _CLDELETE(DelToken);
+
+ boost = MatchQueryToken(QueryToken::NUMBER);
+
+ if(tokens->peek()->Type == QueryToken::FUZZY){
+ DelToken = MatchQueryToken(QueryToken::FUZZY);
+
+ CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
+ _CLDELETE(DelToken);
+
+ fuzzy = true;
+ }
+ } //end if type==CARAT
+
+ discardEscapeChar(term->Value); //clean up
+ if(wildcard){
+ q = GetWildcardQuery(field,term->Value);
+ break;
+ }else if(prefix){
+ //Create a PrefixQuery
+ term->Value[_tcslen(term->Value)-1] = 0; //discard the *
+ q = GetPrefixQuery(field,term->Value);
+ break;
+ }else if(fuzzy){
+ //Create a FuzzyQuery
+
+ //Check if the last char is a ~
+ if(term->Value[_tcslen(term->Value)-1] == '~'){
+ //remove the ~
+ term->Value[_tcslen(term->Value)-1] = '\0';
+ }
+
+ q = GetFuzzyQuery(field,term->Value);
+ break;
+ }else{
+ q = GetFieldQuery(field, term->Value);
+ break;
+ }
+ }
+
+
+ case QueryToken::RANGEIN:
+ case QueryToken::RANGEEX:{
+ if(term->Type == QueryToken::RANGEIN){
+ rangein = true;
+ }
+
+ if(tokens->peek()->Type == QueryToken::CARAT){
+ DelToken = MatchQueryToken(QueryToken::CARAT);
+
+ CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
+ _CLDELETE(DelToken);
+
+ boost = MatchQueryToken(QueryToken::NUMBER);
+ }
+
+ TCHAR* noBrackets = term->Value + 1;
+ noBrackets[_tcslen(noBrackets)-1] = 0;
+ q = ParseRangeQuery(field, noBrackets, rangein);
+ break;
+ }
+
+
+ case QueryToken::QUOTED:{
+ if(tokens->peek()->Type == QueryToken::SLOP){
+ slop = MatchQueryToken(QueryToken::SLOP);
+ }
+
+ if(tokens->peek()->Type == QueryToken::CARAT){
+ DelToken = MatchQueryToken(QueryToken::CARAT);
+
+ CND_CONDITION(DelToken !=NULL, "DelToken is NULL");
+ _CLDELETE(DelToken);
+
+ boost = MatchQueryToken(QueryToken::NUMBER);
+ }
+
+ //remove the quotes
+ TCHAR* quotedValue = term->Value+1;
+ quotedValue[_tcslen(quotedValue)-1] = '\0';
+
+ int32_t islop = phraseSlop;
+ if(slop != NULL ){
+ try {
+ TCHAR* end; //todo: should parse using float...
+ islop = (int32_t)_tcstoi64(slop->Value+1, &end, 10);
+ }catch(...){
+ //ignored
+ }
+ }
+
+ q = GetFieldQuery(field, quotedValue, islop);
+ _CLDELETE(slop);
+ }
+ } // end of switch
+
+ _CLDELETE(term);
+
+
+ if( q!=NULL && boost != NULL ){
+ qreal f = 1.0F;
+ try {
+ TCHAR* tmp;
+ f = _tcstod(boost->Value, &tmp);
+ }catch(...){
+ //ignored
+ }
+ _CLDELETE(boost);
+
+ q->setBoost( f);
+ }
+
+ return q;
+ }
+
+ QueryToken* QueryParser::MatchQueryToken(QueryToken::Types expectedType){
+ //Func - matches for QueryToken of the specified type and returns it
+ // otherwise Exception throws
+ //Pre - tokens != NULL
+ //Post -
+
+ CND_PRECONDITION(tokens != NULL,"tokens is NULL");
+
+ if(tokens->count() == 0){
+ throwParserException(_T("Error: Unexpected end of program"),' ',0,0);
+ }
+
+ //Extract a token form the TokenList tokens
+ QueryToken* t = tokens->extract();
+ //Check if the type of the token t matches the expectedType
+ if (expectedType != t->Type){
+ TCHAR buf[200];
+ _sntprintf(buf,200,_T("Error: Unexpected QueryToken: %d, expected: %d"),t->Type,expectedType);
+ _CLDELETE(t);
+ throwParserException(buf,' ',0,0);
+ }
+
+ //Return the matched token
+ return t;
+ }
+
+ void QueryParser::ExtractAndDeleteToken(void){
+ //Func - Extracts the first token from the Tokenlist tokenlist
+ // and destroys it
+ //Pre - true
+ //Post - The first token has been extracted and destroyed
+
+ CND_PRECONDITION(tokens != NULL, "tokens is NULL");
+
+ //Extract the token from the TokenList tokens
+ QueryToken* t = tokens->extract();
+ //Condition Check Token may not be NULL
+ CND_CONDITION(t != NULL, "Token is NULL");
+ //Delete Token
+ _CLDELETE(t);
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/queryParser/QueryParser.h b/3rdparty/clucene/src/CLucene/queryParser/QueryParser.h
new file mode 100644
index 000000000..a2fc85c89
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/QueryParser.h
@@ -0,0 +1,165 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_queryParser_QueryParser_
+#define _lucene_queryParser_QueryParser_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/analysis/AnalysisHeader.h"
+#include "CLucene/util/Reader.h"
+#include "CLucene/search/SearchHeader.h"
+#include "CLucene/index/Term.h"
+
+#include "TokenList.h"
+#include "QueryToken.h"
+#include "QueryParserBase.h"
+#include "Lexer.h"
+
+CL_NS_DEF(queryParser)
+
+/**
+* @brief CLucene's default query parser.
+*
+* <p>It's a query parser.
+* The only method that clients should need to call is Parse().
+* The syntax for query const TCHAR*s is as follows:
+* A Query is a series of clauses. A clause may be prefixed by:</p>
+* <ul>
+* <li>a plus (+) or a minus (-) sign, indicating that the
+* clause is required or prohibited respectively; or</li>
+* <li>a term followed by a colon, indicating the field to be searched.
+* This enables one to construct queries which search multiple fields.</li>
+* </ul>
+* <p>
+* A clause may be either:</p>
+* <ul>
+* <li>a term, indicating all the documents that contain this term; or</li>
+* <li>a nested query, enclosed in parentheses. Note that this may be
+* used with a +/- prefix to require any of a set of terms.</li>
+* </ul>
+* <p>
+* Thus, in BNF, the query grammar is:</p>
+* <code>
+* Query ::= ( Clause )*
+* Clause ::= ["+", "-"] [&lt;TERM&gt; ":"] ( &lt;TERM&gt; | "(" Query ")" )
+* </code>
+* <p>
+* Examples of appropriately formatted queries can be found in the test cases.
+* </p>
+*/
+class QueryParser : public QueryParserBase
+{
+private:
+ const TCHAR* field;
+ TokenList* tokens;
+public:
+ /**
+ * Initializes a new instance of the QueryParser class with a specified field and
+ * analyzer values.
+ */
+ QueryParser(const TCHAR* field, CL_NS(analysis)::Analyzer* analyzer);
+ ~QueryParser();
+
+ /**
+ * Returns a parsed Query instance.
+ * Note: this call is not threadsafe, either use a seperate QueryParser for each thread, or use a thread lock
+ * <param name="query">The query value to be parsed.</param>
+ * <returns>A parsed Query instance.</returns>
+ */
+ virtual CL_NS(search)::Query* parse(const TCHAR* query);
+
+ /**
+ * Returns a parsed Query instance.
+ * Note: this call is not threadsafe, either use a seperate QueryParser for each thread, or use a thread lock
+ * <param name="reader">The TextReader value to be parsed.</param>
+ * <returns>A parsed Query instance.</returns>
+ */
+ virtual CL_NS(search)::Query* parse(CL_NS(util)::Reader* reader);
+
+ /**
+ * Returns a new instance of the Query class with a specified query, field and
+ * analyzer values.
+ */
+ static CL_NS(search)::Query* parse(const TCHAR* query, const TCHAR* field, CL_NS(analysis)::Analyzer* analyzer);
+
+ CL_NS(analysis)::Analyzer* getAnalyzer() { return analyzer; }
+
+ /**
+ * @return Returns the field.
+ */
+ const TCHAR* getField() { return field; }
+
+ //deprecated functions
+ _CL_DEPRECATED( setLowercaseExpandedTerms ) void setLowercaseWildcardTerms(bool lowercaseWildcardTerms){ setLowercaseExpandedTerms(lowercaseWildcardTerms); }
+ _CL_DEPRECATED( getLowercaseExpandedTerms ) bool getLowercaseWildcardTerms() const { return getLowercaseExpandedTerms(); }
+protected:
+ //these functions may be defined under certain compilation conditions.
+ //note that this functionality is deprecated, you should create your own queryparser
+ //if you want to remove this functionality...it will be removed... be warned!
+#ifdef NO_PREFIX_QUERY
+ virtual CL_NS(search)::Query* GetPrefixQuery(const TCHAR* field,const TCHAR* termStr){ return NULL; }
+#endif
+#ifdef NO_FUZZY_QUERY
+ virtual CL_NS(search)::Query* GetFuzzyQuery(const TCHAR* field,const TCHAR* termStr){ return NULL; }
+#endif
+#ifdef NO_RANGE_QUERY
+ virtual CL_NS(search)::Query* GetRangeQuery(const TCHAR* field, const TCHAR* part1, const TCHAR* part2, bool inclusive) { return NULL; }
+#endif
+#ifdef NO_WILDCARD_QUERY
+ virtual CL_NS(search)::Query* GetWildcardQuery(const TCHAR* field, TCHAR* termStr) { return NULL; }
+#endif
+private:
+ /**
+ * matches for CONJUNCTION
+ * CONJUNCTION ::= <AND> | <OR>
+ */
+ int32_t MatchConjunction();
+
+ /**
+ * matches for MODIFIER
+ * MODIFIER ::= <PLUS> | <MINUS> | <NOT>
+ */
+ int32_t MatchModifier();
+
+ /**
+ * matches for QUERY
+ * QUERY ::= [MODIFIER] CLAUSE (<CONJUNCTION> [MODIFIER] CLAUSE)*
+ */
+ CL_NS(search)::Query* MatchQuery(const TCHAR* field);
+
+ /**
+ * matches for CLAUSE
+ * CLAUSE ::= [TERM <COLON>] ( TERM | (<LPAREN> QUERY <RPAREN>))
+ */
+ CL_NS(search)::Query* MatchClause(const TCHAR* field);
+
+ /**
+ * matches for TERM
+ * TERM ::= TERM | PREFIXTERM | WILDTERM | NUMBER
+ * [ <FUZZY> ] [ <CARAT> <NUMBER> [<FUZZY>]]
+ *
+ * | (<RANGEIN> | <RANGEEX>) [<CARAT> <NUMBER>]
+ * | <QUOTED> [SLOP] [<CARAT> <NUMBER>]
+ */
+ CL_NS(search)::Query* MatchTerm(const TCHAR* field);
+
+ /**
+ * matches for QueryToken of the specified type and returns it
+ * otherwise Exception throws
+ */
+ QueryToken* MatchQueryToken(QueryToken::Types expectedType);
+
+ /**
+ * Extracts the first token from the Tokenlist tokenlist
+ * and destroys it
+ */
+ void ExtractAndDeleteToken(void);
+};
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/queryParser/QueryParserBase.cpp b/3rdparty/clucene/src/CLucene/queryParser/QueryParserBase.cpp
new file mode 100644
index 000000000..7b95b30f9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/QueryParserBase.cpp
@@ -0,0 +1,369 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "QueryParserBase.h"
+
+#include "CLucene/search/TermQuery.h"
+#include "CLucene/search/PhraseQuery.h"
+#include "CLucene/search/RangeQuery.h"
+#include "CLucene/search/FuzzyQuery.h"
+#include "CLucene/search/WildcardQuery.h"
+#include "CLucene/search/PrefixQuery.h"
+
+
+CL_NS_USE(search)
+CL_NS_USE(util)
+CL_NS_USE(analysis)
+CL_NS_USE(index)
+
+CL_NS_DEF(queryParser)
+
+QueryParserBase::QueryParserBase(Analyzer* analyzer){
+//Func - Constructor
+//Pre - true
+//Post - instance has been created with PhraseSlop = 0
+ this->analyzer = analyzer;
+ this->defaultOperator = OR_OPERATOR;
+ this->phraseSlop = 0;
+ this->lowercaseExpandedTerms = true;
+}
+
+QueryParserBase::~QueryParserBase(){
+//Func - Destructor
+//Pre - true
+//Post - The instance has been destroyed
+}
+
+
+void QueryParserBase::discardEscapeChar(TCHAR* source) const{
+ int len = _tcslen(source);
+ int j = 0;
+ for (int i = 0; i < len; i++) {
+ if (source[i] == '\\' && source[i+1] != '\0' ) {
+ _tcscpy(source+i,source+i+1);
+ len--;
+ }
+ }
+}
+
+void QueryParserBase::AddClause(CL_NS_STD(vector)<BooleanClause*>& clauses, int32_t conj, int32_t mods, Query* q){
+//Func - Adds the next parsed clause.
+//Pre -
+//Post -
+
+ bool required, prohibited;
+
+ // If this term is introduced by AND, make the preceding term required,
+ // unless it's already prohibited.
+ const uint32_t nPreviousClauses = clauses.size();
+ if (nPreviousClauses > 0 && conj == CONJ_AND) {
+ BooleanClause* c = clauses[nPreviousClauses-1];
+ if (!c->prohibited)
+ c->required = true;
+ }
+
+ if (nPreviousClauses > 0 && defaultOperator == AND_OPERATOR && conj == CONJ_OR) {
+ // If this term is introduced by OR, make the preceding term optional,
+ // unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b)
+ // notice if the input is a OR b, first term is parsed as required; without
+ // this modification a OR b would parse as +a OR b
+ BooleanClause* c = clauses[nPreviousClauses-1];
+ if (!c->prohibited){
+ c->required = false;
+ c->prohibited = false;
+ }
+ }
+
+ // We might have been passed a NULL query; the term might have been
+ // filtered away by the analyzer.
+ if (q == NULL)
+ return;
+
+ if (defaultOperator == OR_OPERATOR) {
+ // We set REQUIRED if we're introduced by AND or +; PROHIBITED if
+ // introduced by NOT or -; make sure not to set both.
+ prohibited = (mods == MOD_NOT);
+ required = (mods == MOD_REQ);
+ if (conj == CONJ_AND && !prohibited) {
+ required = true;
+ }
+ } else {
+ // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED
+ // if not PROHIBITED and not introduced by OR
+ prohibited = (mods == MOD_NOT);
+ required = (!prohibited && conj != CONJ_OR);
+ }
+
+ if ( required && prohibited )
+ throwParserException( _T("Clause cannot be both required and prohibited"), ' ',0,0);
+ clauses.push_back(_CLNEW BooleanClause(q,true, required, prohibited));
+}
+
+void QueryParserBase::throwParserException(const TCHAR* message, TCHAR ch, int32_t col, int32_t line )
+{
+ TCHAR msg[1024];
+ _sntprintf(msg,1024,message,ch,col,line);
+ _CLTHROWT (CL_ERR_Parse, msg );
+}
+
+
+Query* QueryParserBase::GetFieldQuery(const TCHAR* field, TCHAR* queryText, int32_t slop){
+ Query* ret = GetFieldQuery(field,queryText);
+ if ( ret && ret->getQueryName() == PhraseQuery::getClassName() )
+ ((PhraseQuery*)ret)->setSlop(slop);
+
+ return ret;
+}
+
+Query* QueryParserBase::GetFieldQuery(const TCHAR* field, TCHAR* queryText){
+//Func - Returns a query for the specified field.
+// Use the analyzer to get all the tokens, and then build a TermQuery,
+// PhraseQuery, or nothing based on the term count
+//Pre - field != NULL
+// analyzer contains a valid reference to an Analyzer
+// queryText != NULL and contains the query
+//Post - A query instance has been returned for the specified field
+
+ CND_PRECONDITION(field != NULL, "field is NULL");
+ CND_PRECONDITION(queryText != NULL, "queryText is NULL");
+
+ //Instantiate a stringReader for queryText
+ StringReader reader(queryText);
+ TokenStream* source = analyzer->tokenStream(field, &reader);
+ CND_CONDITION(source != NULL,"source is NULL");
+
+ StringArrayConstWithDeletor v;
+
+ Token t;
+ int positionCount = 0;
+ bool severalTokensAtSamePosition = false;
+
+ //Get the tokens from the source
+ try{
+ while (source->next(&t)){
+ v.push_back(STRDUP_TtoT(t.termText()));
+
+ if (t.getPositionIncrement() != 0)
+ positionCount += t.getPositionIncrement();
+ else
+ severalTokensAtSamePosition = true;
+ }
+ }catch(CLuceneError& err){
+ if ( err.number() != CL_ERR_IO )
+ throw err;
+ }
+ _CLDELETE(source);
+
+ //Check if there are any tokens retrieved
+ if (v.size() == 0){
+ return NULL;
+ }else{
+ if (v.size() == 1){
+ Term* t = _CLNEW Term(field, v[0]);
+ Query* ret = _CLNEW TermQuery( t );
+ _CLDECDELETE(t);
+ return ret;
+ }else{
+ if (severalTokensAtSamePosition) {
+ if (positionCount == 1) {
+ // no phrase query:
+ BooleanQuery* q = _CLNEW BooleanQuery; //todo: disableCoord=true here, but not implemented in BooleanQuery
+ StringArrayConst::iterator itr = v.begin();
+ while ( itr != v.end() ){
+ Term* t = _CLNEW Term(field, *itr);
+ q->add(_CLNEW TermQuery(t),true, false,false);//should occur...
+ _CLDECDELETE(t);
+ ++itr;
+ }
+ return q;
+ }else {
+ _CLTHROWA(CL_ERR_UnsupportedOperation, "MultiPhraseQuery NOT Implemented");
+ }
+ }else{
+ PhraseQuery* q = _CLNEW PhraseQuery;
+ q->setSlop(phraseSlop);
+
+ StringArrayConst::iterator itr = v.begin();
+ while ( itr != v.end() ){
+ const TCHAR* data = *itr;
+ Term* t = _CLNEW Term(field, data);
+ q->add(t);
+ _CLDECDELETE(t);
+ ++itr;
+ }
+ return q;
+ }
+ }
+ }
+}
+
+void QueryParserBase::setLowercaseExpandedTerms(bool lowercaseExpandedTerms){
+ this->lowercaseExpandedTerms = lowercaseExpandedTerms;
+}
+bool QueryParserBase::getLowercaseExpandedTerms() const {
+ return lowercaseExpandedTerms;
+}
+void QueryParserBase::setDefaultOperator(int oper){
+ this->defaultOperator=oper;
+}
+int QueryParserBase::getDefaultOperator() const{
+ return defaultOperator;
+}
+
+
+Query* QueryParserBase::ParseRangeQuery(const TCHAR* field, TCHAR* queryText, bool inclusive)
+{
+ //todo: this must be fixed, [-1--5] (-1 to -5) should yield a result, but won't parse properly
+ //because it uses an analyser, should split it up differently...
+
+ // Use the analyzer to get all the tokens. There should be 1 or 2.
+ StringReader reader(queryText);
+ TokenStream* source = analyzer->tokenStream(field, &reader);
+
+ TCHAR* terms[2];
+ terms[0]=NULL;terms[1]=NULL;
+ Token t;
+ bool tret=true;
+ bool from=true;
+ while(tret)
+ {
+ try{
+ tret = source->next(&t);
+ }catch (CLuceneError& err){
+ if ( err.number() == CL_ERR_IO )
+ tret=false;
+ else
+ throw err;
+ }
+ if (tret)
+ {
+ if ( !from && _tcscmp(t.termText(),_T("TO"))==0 )
+ continue;
+
+
+ TCHAR* tmp = STRDUP_TtoT(t.termText());
+ discardEscapeChar(tmp);
+ terms[from? 0 : 1] = tmp;
+
+ if (from)
+ from = false;
+ else
+ break;
+ }
+ }
+ Query* ret = GetRangeQuery(field, terms[0], terms[1],inclusive);
+ _CLDELETE_CARRAY(terms[0]);
+ _CLDELETE_CARRAY(terms[1]);
+ _CLDELETE(source);
+
+ return ret;
+}
+
+Query* QueryParserBase::GetPrefixQuery(const TCHAR* field, TCHAR* termStr){
+//Pre - field != NULL and field contains the name of the field that the query will use
+// termStr != NULL and is the token to use for building term for the query
+// (WITH or WITHOUT a trailing '*' character!)
+//Post - A PrefixQuery instance has been returned
+
+ CND_PRECONDITION(field != NULL,"field is NULL");
+ CND_PRECONDITION(termStr != NULL,"termStr is NULL");
+
+ if ( lowercaseExpandedTerms )
+ _tcslwr(termStr);
+
+ Term* t = _CLNEW Term(field, termStr);
+ CND_CONDITION(t != NULL,"Could not allocate memory for term t");
+
+ Query *q = _CLNEW PrefixQuery(t);
+ CND_CONDITION(q != NULL,"Could not allocate memory for PrefixQuery q");
+
+ _CLDECDELETE(t);
+ return q;
+}
+
+Query* QueryParserBase::GetFuzzyQuery(const TCHAR* field, TCHAR* termStr){
+//Func - Factory method for generating a query (similar to getPrefixQuery}). Called when parser parses
+// an input term token that has the fuzzy suffix (~) appended.
+//Pre - field != NULL and field contains the name of the field that the query will use
+// termStr != NULL and is the token to use for building term for the query
+// (WITH or WITHOUT a trailing '*' character!)
+//Post - A FuzzyQuery instance has been returned
+
+ CND_PRECONDITION(field != NULL,"field is NULL");
+ CND_PRECONDITION(termStr != NULL,"termStr is NULL");
+
+ if ( lowercaseExpandedTerms )
+ _tcslwr(termStr);
+
+ Term* t = _CLNEW Term(field, termStr);
+ CND_CONDITION(t != NULL,"Could not allocate memory for term t");
+
+ Query *q = _CLNEW FuzzyQuery(t);
+ CND_CONDITION(q != NULL,"Could not allocate memory for FuzzyQuery q");
+
+ _CLDECDELETE(t);
+ return q;
+}
+
+
+Query* QueryParserBase::GetWildcardQuery(const TCHAR* field, TCHAR* termStr){
+ CND_PRECONDITION(field != NULL,"field is NULL");
+ CND_PRECONDITION(termStr != NULL,"termStr is NULL");
+
+ if ( lowercaseExpandedTerms )
+ _tcslwr(termStr);
+
+ Term* t = _CLNEW Term(field, termStr);
+ CND_CONDITION(t != NULL,"Could not allocate memory for term t");
+ Query* q = _CLNEW WildcardQuery(t);
+ _CLDECDELETE(t);
+
+ return q;
+}
+
+Query* QueryParserBase::GetBooleanQuery(CL_NS_STD(vector)<CL_NS(search)::BooleanClause*>& clauses){
+ if ( clauses.size() == 0 )
+ return NULL;
+
+ BooleanQuery* query = _CLNEW BooleanQuery();
+ //Condition check to see if query has been allocated properly
+ CND_CONDITION(query != NULL, "No memory could be allocated for query");
+
+ //iterate through all the clauses
+ for( uint32_t i=0;i<clauses.size();i++ ){
+ //Condition check to see if clauses[i] is valdid
+ CND_CONDITION(clauses[i] != NULL, "clauses[i] is NULL");
+ //Add it to query
+ query->add(clauses[i]);
+ }
+ return query;
+}
+
+
+CL_NS(search)::Query* QueryParserBase::GetRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, bool inclusive){
+ //todo: does jlucene handle rangequeries differntly? if we are using
+ //a certain type of analyser, the terms may be filtered out, which
+ //is not necessarily what we want.
+ if (lowercaseExpandedTerms) {
+ _tcslwr(part1);
+ _tcslwr(part2);
+ }
+ //todo: should see if we can parse the strings as dates... currently we leave that up to the end-developer...
+ Term* t1 = _CLNEW Term(field,part1);
+ Term* t2 = _CLNEW Term(field,part2);
+ Query* ret = _CLNEW RangeQuery(t1, t2, inclusive);
+ _CLDECDELETE(t1);
+ _CLDECDELETE(t2);
+
+ return ret;
+}
+
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/queryParser/QueryParserBase.h b/3rdparty/clucene/src/CLucene/queryParser/QueryParserBase.h
new file mode 100644
index 000000000..261e587b0
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/QueryParserBase.h
@@ -0,0 +1,204 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_queryParser_QueryParserBase_
+#define _lucene_queryParser_QueryParserBase_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/VoidList.h"
+#include "CLucene/search/BooleanClause.h"
+#include "CLucene/analysis/Analyzers.h"
+#include "QueryToken.h"
+
+CL_NS_DEF(queryParser)
+
+ /**
+ * Contains default implementations used by QueryParser.
+ * You can override any of these to provide a customised QueryParser.
+ */
+ class QueryParserBase:LUCENE_BASE
+ {
+ protected:
+ /* The actual operator the parser uses to combine query terms */
+ int defaultOperator;
+ int32_t phraseSlop;
+
+ bool lowercaseExpandedTerms;
+
+ LUCENE_STATIC_CONSTANT(int, CONJ_NONE=0);
+ LUCENE_STATIC_CONSTANT(int, CONJ_AND=1);
+ LUCENE_STATIC_CONSTANT(int, CONJ_OR=2);
+
+ LUCENE_STATIC_CONSTANT(int, MOD_NONE=0);
+ LUCENE_STATIC_CONSTANT(int, MOD_NOT=10);
+ LUCENE_STATIC_CONSTANT(int, MOD_REQ=11);
+
+ CL_NS(analysis)::Analyzer* analyzer;
+
+ public:
+ QueryParserBase(CL_NS(analysis)::Analyzer* analyzer);
+ ~QueryParserBase();
+
+ /**
+ * Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically
+ * lower-cased or not. Default is <code>true</code>.
+ */
+ void setLowercaseExpandedTerms(bool lowercaseExpandedTerms);
+
+ /**
+ * @see #setLowercaseExpandedTerms(boolean)
+ */
+ bool getLowercaseExpandedTerms() const;
+
+ //values used for setOperator
+ LUCENE_STATIC_CONSTANT(int, OR_OPERATOR=0);
+ LUCENE_STATIC_CONSTANT(int, AND_OPERATOR=1);
+
+ /**
+ * Sets the boolean operator of the QueryParser.
+ * In default mode (<code>OR_OPERATOR</code>) terms without any modifiers
+ * are considered optional: for example <code>capital of Hungary</code> is equal to
+ * <code>capital OR of OR Hungary</code>.<br/>
+ * In <code>AND_OPERATOR</code> mode terms are considered to be in conjuction: the
+ * above mentioned query is parsed as <code>capital AND of AND Hungary</code>
+ */
+ void setDefaultOperator(int oper);
+ /**
+ * Gets implicit operator setting, which will be either AND_OPERATOR
+ * or OR_OPERATOR.
+ */
+ int getDefaultOperator() const;
+
+ //public so that the lexer can call this
+ virtual void throwParserException(const TCHAR* message, TCHAR ch, int32_t col, int32_t line );
+
+ /**
+ * Sets the default slop for phrases. If zero, then exact phrase matches
+ * are required. Default value is zero.
+ */
+ void setPhraseSlop(int phraseSlop) { this->phraseSlop = phraseSlop; }
+
+ /**
+ * Gets the default slop for phrases.
+ */
+ int getPhraseSlop() { return phraseSlop; }
+
+ protected:
+
+ /**
+ * Removes the escaped characters
+ */
+ void discardEscapeChar(TCHAR* token) const;
+
+ //Analyzes the expanded term termStr with the StandardFilter and the LowerCaseFilter.
+ TCHAR* AnalyzeExpandedTerm(const TCHAR* field, TCHAR* termStr);
+
+ // Adds the next parsed clause.
+ virtual void AddClause(std::vector<CL_NS(search)::BooleanClause*>& clauses, int32_t conj, int32_t mods, CL_NS(search)::Query* q);
+
+ /**
+ * Returns a termquery, phrasequery for the specified field.
+ * Note: this is only a partial implementation, since MultiPhraseQuery is not implemented yet
+ * return NULL to disallow
+ */
+ virtual CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, TCHAR* queryText);
+
+ /**
+ * Delegates to GetFieldQuery(string, string), and adds slop onto phrasequery.
+ * Can be used to remove slop functionality
+ */
+ virtual CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, TCHAR* queryText, int32_t slop);
+
+ /**
+ * Factory method for generating a query (similar to
+ * {@link #GetWildcardQuery}). Called when parser parses an input term
+ * token that uses prefix notation; that is, contains a single '*' wildcard
+ * character as its last character. Since this is a special case
+ * of generic wildcard term, and such a query can be optimized easily,
+ * this usually results in a different query object.
+ *<p>
+ * Depending on settings, a prefix term may be lower-cased
+ * automatically. It will not go through the default Analyzer,
+ * however, since normal Analyzers are unlikely to work properly
+ * with wildcard templates.
+ *<p>
+ * Can be overridden by extending classes, to provide custom handling for
+ * wild card queries, which may be necessary due to missing analyzer calls.
+ *
+ * @param field Name of the field query will use.
+ * @param termStr Term token to use for building term for the query
+ * (<b>without</b> trailing '*' character!)
+ *
+ * @return Resulting {@link Query} built for the term
+ * return NULL to disallow
+ */
+ virtual CL_NS(search)::Query* GetPrefixQuery(const TCHAR* field, TCHAR* termStr);
+
+ /**
+ * Factory method for generating a query. Called when parser
+ * parses an input term token that contains one or more wildcard
+ * characters (? and *), but is not a prefix term token (one
+ * that has just a single * character at the end)
+ *<p>
+ * Depending on settings, prefix term may be lower-cased
+ * automatically. It will not go through the default Analyzer,
+ * however, since normal Analyzers are unlikely to work properly
+ * with wildcard templates.
+ *<p>
+ * Can be overridden by extending classes, to provide custom handling for
+ * wildcard queries, which may be necessary due to missing analyzer calls.
+ *
+ * @param field Name of the field query will use.
+ * @param termStr Term token that contains one or more wild card
+ * characters (? or *), but is not simple prefix term
+ *
+ * @return Resulting {@link Query} built for the term
+ * return NULL to disallow
+ */
+ virtual CL_NS(search)::Query* GetWildcardQuery(const TCHAR* field, TCHAR* termStr);
+
+ /**
+ * Factory method for generating a query (similar to
+ * {@link #GetWildcardQuery}). Called when parser parses
+ * an input term token that has the fuzzy suffix (~) appended.
+ *
+ * @param field Name of the field query will use.
+ * @param termStr Term token to use for building term for the query
+ *
+ * @return Resulting {@link Query} built for the term
+ * return NULL to disallow
+ */
+ virtual CL_NS(search)::Query* GetFuzzyQuery(const TCHAR* field, TCHAR* termStr);
+
+ /**
+ * Factory method for generating query, given a set of clauses.
+ * By default creates a boolean query composed of clauses passed in.
+ *
+ * Can be overridden by extending classes, to modify query being
+ * returned.
+ *
+ * @param clauses Vector that contains {@link BooleanClause} instances
+ * to join.
+ *
+ * @return Resulting {@link Query} object.
+ * return NULL to disallow
+ *
+ * Memory: clauses must all be cleaned up by this function.
+ */
+ virtual CL_NS(search)::Query* GetBooleanQuery(std::vector<CL_NS(search)::BooleanClause*>& clauses);
+
+ /**
+ * return NULL to disallow
+ */
+ virtual CL_NS(search)::Query* GetRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, bool inclusive);
+ virtual CL_NS(search)::Query* ParseRangeQuery(const TCHAR* field, TCHAR* str, bool inclusive);
+
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/queryParser/QueryToken.cpp b/3rdparty/clucene/src/CLucene/queryParser/QueryToken.cpp
new file mode 100644
index 000000000..ee88a3cb6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/QueryToken.cpp
@@ -0,0 +1,73 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "QueryToken.h"
+
+CL_NS_DEF(queryParser)
+
+
+QueryToken::QueryToken():
+ Value(NULL)
+{
+ set(UNKNOWN_);
+}
+QueryToken::QueryToken(TCHAR* value, const int32_t start, const int32_t end, const QueryToken::Types type):
+ Value(NULL)
+{
+ set(value,start,end,type);
+}
+
+QueryToken::~QueryToken(){
+//Func - Destructor
+//Pre - true
+//Post - Instance has been destroyed
+
+ #ifndef LUCENE_TOKEN_WORD_LENGTH
+ _CLDELETE_CARRAY( Value );
+ #endif
+}
+
+// Initializes a new instance of the Token class LUCENE_EXPORT.
+//
+QueryToken::QueryToken(TCHAR* value, const QueryToken::Types type):
+ Value(NULL)
+{
+ set(value,type);
+}
+
+// Initializes a new instance of the Token class LUCENE_EXPORT.
+//
+QueryToken::QueryToken(QueryToken::Types type):
+ Value(NULL)
+{
+ set(type);
+}
+
+
+void QueryToken::set(TCHAR* value, const Types type){
+ set(value,0,-1,type);
+}
+void QueryToken::set(TCHAR* value, const int32_t start, const int32_t end, const Types type){
+ #ifndef LUCENE_TOKEN_WORD_LENGTH
+ _CLDELETE_CARRAY(Value);
+ Value = STRDUP_TtoT(value);
+ #else
+ _tcsncpy(Value,value,LUCENE_TOKEN_WORD_LENGTH);
+ Value[LUCENE_TOKEN_WORD_LENGTH];
+ #endif
+ this->Start = start;
+ this->End = end;
+ this->Type = type;
+
+ if ( this->End < 0 )
+ this->End = _tcslen(Value);
+}
+void QueryToken::set(Types type){
+ set(LUCENE_BLANK_STRING,0,0,type);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/queryParser/QueryToken.h b/3rdparty/clucene/src/CLucene/queryParser/QueryToken.h
new file mode 100644
index 000000000..739a667ba
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/QueryToken.h
@@ -0,0 +1,76 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_queryParser_QueryToken_
+#define _lucene_queryParser_QueryToken_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "QueryParserBase.h"
+
+CL_NS_DEF(queryParser)
+
+ // Token class that used by QueryParser.
+ class QueryToken:LUCENE_BASE
+ {
+ public:
+ enum Types
+ {
+ AND_,
+ OR,
+ NOT,
+ PLUS,
+ MINUS,
+ LPAREN,
+ RPAREN,
+ COLON,
+ CARAT,
+ QUOTED,
+ TERM,
+ SLOP,
+ FUZZY,
+ PREFIXTERM,
+ WILDTERM,
+ RANGEIN,
+ RANGEEX,
+ NUMBER,
+ EOF_,
+ UNKNOWN_
+ };
+
+
+ #ifdef LUCENE_TOKEN_WORD_LENGTH
+ TCHAR Value[LUCENE_TOKEN_WORD_LENGTH+1];
+ #else
+ TCHAR* Value;
+ #endif
+
+ int32_t Start;
+ int32_t End;
+ QueryToken::Types Type;
+
+ // Initializes a new instance of the Token class.
+ QueryToken(TCHAR* value, const int32_t start, const int32_t end, const Types type);
+
+ // Initializes a new instance of the Token class.
+ QueryToken(TCHAR* value, const Types type);
+
+ // Initializes a new instance of the Token class.
+ QueryToken(Types type);
+
+ // Initializes an empty instance of the Token class.
+ QueryToken();
+
+ ~QueryToken();
+
+ void set(TCHAR* value, const int32_t start, const int32_t end, const Types type);
+ void set(TCHAR* value, const Types type);
+ void set(Types type);
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/queryParser/TokenList.cpp b/3rdparty/clucene/src/CLucene/queryParser/TokenList.cpp
new file mode 100644
index 000000000..7d30b931f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/TokenList.cpp
@@ -0,0 +1,79 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "TokenList.h"
+
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/VoidList.h"
+#include "QueryToken.h"
+
+CL_NS_DEF(queryParser)
+
+ TokenList::TokenList(){
+ //Func - Constructor
+ //Pre - true
+ //Post - Instance has been created
+ }
+
+ TokenList::~TokenList(){
+ //Func - Destructor
+ //Pre - true
+ //Post - The tokenlist has been destroyed
+
+ tokens.clear();
+ }
+
+ void TokenList::add(QueryToken* token){
+ //Func - Adds a QueryToken token to the TokenList
+ //Pre - token != NULL
+ //Post - token has been added to the token list
+
+ CND_PRECONDITION(token != NULL, "token != NULL");
+
+ tokens.insert(tokens.begin(),token);
+ }
+
+ void TokenList::push(QueryToken* token){
+ //Func -
+ //Pre - token != NULL
+ //Post -
+
+ CND_PRECONDITION(token != NULL, "token is NULL");
+
+ tokens.push_back(token);
+ }
+
+ QueryToken* TokenList::peek() {
+ /* DSR:2004.11.01: Reverted my previous (circa April 2004) fix (which
+ ** raised an exception if Peek was called when there were no tokens) in
+ ** favor of returning the EOF token. This solution is much better
+ ** integrated with the rest of the code in the queryParser subsystem. */
+ size_t nTokens = tokens.size();
+ if (nTokens == 0) {
+ push(_CLNEW QueryToken(QueryToken::EOF_));
+ nTokens++;
+ }
+ return tokens[nTokens-1];
+ }
+
+ QueryToken* TokenList::extract(){
+ //Func - Extract token from the TokenList
+ //Pre - true
+ //Post - Retracted token has been returned
+
+ QueryToken* token = peek();
+ //Retract the current peeked token
+ tokens.delete_back();
+
+ return token;
+ }
+
+ int32_t TokenList::count() const
+ {
+ return tokens.size();
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/queryParser/TokenList.h b/3rdparty/clucene/src/CLucene/queryParser/TokenList.h
new file mode 100644
index 000000000..3166bba78
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/queryParser/TokenList.h
@@ -0,0 +1,38 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_queryParser_TokenList_
+#define _lucene_queryParser_TokenList_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/VoidList.h"
+#include "QueryToken.h"
+CL_NS_DEF(queryParser)
+
+ // Represents a list of the tokens.
+ class TokenList:LUCENE_BASE
+ {
+ private:
+ CL_NS(util)::CLVector<QueryToken*> tokens; //todo:,CL_NS(util)::Deletor::Object<QueryToken>
+ public:
+ TokenList();
+ ~TokenList();
+
+ void add(QueryToken* token);
+
+ void push(QueryToken* token);
+
+ QueryToken* peek();
+
+ QueryToken* extract();
+
+ int32_t count() const;
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/BooleanClause.h b/3rdparty/clucene/src/CLucene/search/BooleanClause.h
new file mode 100644
index 000000000..b89cb31d7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/BooleanClause.h
@@ -0,0 +1,90 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_BooleanClause_
+#define _lucene_search_BooleanClause_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+#include "SearchHeader.h"
+
+CL_NS_DEF(search)
+ // A clause in a BooleanQuery.
+ class BooleanClause:LUCENE_BASE {
+ public:
+ class Compare:public CL_NS_STD(binary_function)<const BooleanClause*,const BooleanClause*,bool>
+ {
+ public:
+ bool operator()( const BooleanClause* val1, const BooleanClause* val2 ) const{
+ return val1->equals(val2);
+ }
+ };
+
+ // The query whose matching documents are combined by the boolean query.
+ Query* query;
+
+ int32_t getClauseCount();
+
+ // If true, documents documents which <i>do not</i>
+ // match this sub-query will <i>not</i> match the boolean query.
+ bool required;
+
+ // If true, documents documents which <i>do</i>
+ // match this sub-query will <i>not</i> match the boolean query.
+ bool prohibited;
+
+ bool deleteQuery;
+
+ // Constructs a BooleanClause with query <code>q</code>, required
+ // <code>r</code> and prohibited <code>p</code>.
+ BooleanClause(Query* q, const bool DeleteQuery,const bool req, const bool p):
+ query(q),
+ required(req),
+ prohibited(p),
+ deleteQuery(DeleteQuery)
+ {
+ }
+
+ BooleanClause(const BooleanClause& clone):
+#if defined(LUCENE_ENABLE_MEMLEAKTRACKING)
+#elif defined(LUCENE_ENABLE_REFCOUNT)
+#else
+ LuceneVoidBase(),
+#endif
+ query(clone.query->clone()),
+ required(clone.required),
+ prohibited(clone.prohibited),
+ deleteQuery(true)
+ {
+ }
+
+ BooleanClause* clone() const{
+ BooleanClause* ret = _CLNEW BooleanClause(*this);
+ return ret;
+ }
+
+ ~BooleanClause(){
+ if ( deleteQuery )
+ _CLDELETE( query );
+ }
+
+ /** Returns true iff <code>o</code> is equal to this. */
+ bool equals(const BooleanClause* other) const {
+ return this->query->equals(other->query)
+ && (this->required == other->required)
+ && (this->prohibited == other->prohibited);
+ }
+
+ size_t hashCode() const{
+ return query->hashCode() ^ (this->required?1:0) ^ (this->prohibited?2:0);
+ }
+ };
+
+
+CL_NS_END
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/search/BooleanQuery.cpp b/3rdparty/clucene/src/CLucene/search/BooleanQuery.cpp
new file mode 100644
index 000000000..3fd36d847
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/BooleanQuery.cpp
@@ -0,0 +1,363 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "BooleanQuery.h"
+
+#include "BooleanClause.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/StringBuffer.h"
+#include "CLucene/util/Arrays.h"
+#include "SearchHeader.h"
+#include "BooleanScorer.h"
+#include "Scorer.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+ BooleanQuery::BooleanQuery():
+ clauses(true)
+ {
+ }
+
+ BooleanQuery::BooleanQuery(const BooleanQuery& clone):
+ Query(clone)
+ {
+ for ( uint32_t i=0;i<clone.clauses.size();i++ ){
+ BooleanClause* clause = clone.clauses[i]->clone();
+ clause->deleteQuery=true;
+ add(clause);
+ }
+ }
+
+ BooleanQuery::~BooleanQuery(){
+ clauses.clear();
+ }
+
+ size_t BooleanQuery::hashCode() const {
+ //todo: do cachedHashCode, and invalidate on add/remove clause
+ size_t ret = 0;
+ for (uint32_t i = 0 ; i < clauses.size(); i++) {
+ BooleanClause* c = clauses[i];
+ ret = 31 * ret + c->hashCode();
+ }
+ ret = ret ^ Similarity::floatToByte(getBoost());
+ return ret;
+ }
+
+ const TCHAR* BooleanQuery::getQueryName() const{
+ return getClassName();
+ }
+ const TCHAR* BooleanQuery::getClassName(){
+ return _T("BooleanQuery");
+ }
+
+ /**
+ * Default value is 1024. Use <code>org.apache.lucene.maxClauseCount</code>
+ * system property to override.
+ */
+ size_t BooleanQuery::maxClauseCount = LUCENE_BOOLEANQUERY_MAXCLAUSECOUNT;
+ size_t BooleanQuery::getMaxClauseCount(){
+ return maxClauseCount;
+ }
+
+ void BooleanQuery::setMaxClauseCount(size_t maxClauseCount){
+ BooleanQuery::maxClauseCount = maxClauseCount;
+ }
+
+ void BooleanQuery::add(Query* query, const bool deleteQuery, const bool required, const bool prohibited) {
+ BooleanClause* bc = _CLNEW BooleanClause(query,deleteQuery,required, prohibited);
+ try{
+ add(bc);
+ }catch(...){
+ _CLDELETE(bc);
+ throw;
+ }
+ }
+
+ void BooleanQuery::add(BooleanClause* clause) {
+ if (clauses.size() >= getMaxClauseCount())
+ _CLTHROWA(CL_ERR_TooManyClauses,"Too Many Clauses");
+
+ clauses.push_back(clause);
+ }
+
+
+ size_t BooleanQuery::getClauseCount() const {
+ return (int32_t) clauses.size();
+ }
+
+ TCHAR* BooleanQuery::toString(const TCHAR* field) const{
+ StringBuffer buffer;
+ if (getBoost() != 1.0) {
+ buffer.append(_T("("));
+ }
+
+ for (uint32_t i = 0 ; i < clauses.size(); i++) {
+ BooleanClause* c = clauses[i];
+ if (c->prohibited)
+ buffer.append(_T("-"));
+ else if (c->required)
+ buffer.append(_T("+"));
+
+ if ( c->query->instanceOf(BooleanQuery::getClassName()) ) { // wrap sub-bools in parens
+ buffer.append(_T("("));
+
+ TCHAR* buf = c->query->toString(field);
+ buffer.append(buf);
+ _CLDELETE_CARRAY( buf );
+
+ buffer.append(_T(")"));
+ } else {
+ TCHAR* buf = c->query->toString(field);
+ buffer.append(buf);
+ _CLDELETE_CARRAY( buf );
+ }
+ if (i != clauses.size()-1)
+ buffer.append(_T(" "));
+
+ if (getBoost() != 1.0) {
+ buffer.append(_T(")^"));
+ buffer.appendFloat(getBoost(),1);
+ }
+ }
+ return buffer.toString();
+ }
+
+
+
+
+ BooleanClause** BooleanQuery::getClauses() const
+ {
+ CND_MESSAGE(false, "Warning: BooleanQuery::getClauses() is deprecated")
+ BooleanClause** ret = _CL_NEWARRAY(BooleanClause*, clauses.size()+1);
+ getClauses(ret);
+ return ret;
+ }
+
+ void BooleanQuery::getClauses(BooleanClause** ret) const
+ {
+ size_t size=clauses.size();
+ for ( uint32_t i=0;i<size;i++ )
+ ret[i] = clauses[i];
+ }
+ Query* BooleanQuery::rewrite(IndexReader* reader) {
+ if (clauses.size() == 1) { // optimize 1-clause queries
+ BooleanClause* c = clauses[0];
+ if (!c->prohibited) { // just return clause
+ Query* query = c->query->rewrite(reader); // rewrite first
+
+ //if the query doesn't actually get re-written,
+ //then return a clone (because the BooleanQuery
+ //will register different to the returned query.
+ if ( query == c->query )
+ query = query->clone();
+
+ if (getBoost() != 1.0f) { // incorporate boost
+ query->setBoost(getBoost() * query->getBoost());
+ }
+
+ return query;
+ }
+ }
+
+ BooleanQuery* clone = NULL; // recursively rewrite
+ for (uint32_t i = 0 ; i < clauses.size(); i++) {
+ BooleanClause* c = clauses[i];
+ Query* query = c->query->rewrite(reader);
+ if (query != c->query) { // clause rewrote: must clone
+ if (clone == NULL)
+ clone = (BooleanQuery*)this->clone();
+ //todo: check if delete query should be on...
+ //in fact we should try and get rid of these
+ //for compatibility sake
+ clone->clauses.set (i, _CLNEW BooleanClause(query, true, c->required, c->prohibited));
+ }
+ }
+ if (clone != NULL) {
+ return clone; // some clauses rewrote
+ } else
+ return this; // no clauses rewrote
+ }
+
+
+ Query* BooleanQuery::clone() const{
+ BooleanQuery* clone = _CLNEW BooleanQuery(*this);
+ return clone;
+ }
+
+ /** Returns true iff <code>o</code> is equal to this. */
+ bool BooleanQuery::equals(Query* o)const {
+ if (!(o->instanceOf(BooleanQuery::getClassName())))
+ return false;
+ const BooleanQuery* other = (BooleanQuery*)o;
+
+ bool ret = (this->getBoost() == other->getBoost());
+ if ( ret ){
+ CLListEquals<BooleanClause,BooleanClause::Compare, const ClausesType, const ClausesType> comp;
+ ret = comp.equals(&this->clauses,&other->clauses);
+ }
+ return ret;
+ }
+
+ qreal BooleanQuery::BooleanWeight::getValue() { return parentQuery->getBoost(); }
+ Query* BooleanQuery::BooleanWeight::getQuery() { return (Query*)parentQuery; }
+
+
+
+
+
+ BooleanQuery::BooleanWeight::BooleanWeight(Searcher* searcher,
+ CLVector<BooleanClause*,Deletor::Object<BooleanClause> >* clauses, BooleanQuery* parentQuery)
+ {
+ this->searcher = searcher;
+ this->parentQuery = parentQuery;
+ this->clauses = clauses;
+ for (uint32_t i = 0 ; i < clauses->size(); i++) {
+ weights.push_back((*clauses)[i]->query->_createWeight(searcher));
+ }
+ }
+ BooleanQuery::BooleanWeight::~BooleanWeight(){
+ this->weights.clear();
+ }
+
+ qreal BooleanQuery::BooleanWeight::sumOfSquaredWeights() {
+ qreal sum = 0.0f;
+ for (uint32_t i = 0 ; i < weights.size(); i++) {
+ BooleanClause* c = (*clauses)[i];
+ Weight* w = weights[i];
+ if (!c->prohibited)
+ sum += w->sumOfSquaredWeights(); // sum sub weights
+ }
+ sum *= parentQuery->getBoost() * parentQuery->getBoost(); // boost each sub-weight
+ return sum ;
+ }
+
+ void BooleanQuery::BooleanWeight::normalize(qreal norm) {
+ norm *= parentQuery->getBoost(); // incorporate boost
+ for (uint32_t i = 0 ; i < weights.size(); i++) {
+ BooleanClause* c = (*clauses)[i];
+ Weight* w = weights[i];
+ if (!c->prohibited)
+ w->normalize(norm);
+ }
+ }
+
+ Scorer* BooleanQuery::BooleanWeight::scorer(IndexReader* reader){
+ // First see if the (faster) ConjunctionScorer will work. This can be
+ // used when all clauses are required. Also, at this point a
+ // BooleanScorer cannot be embedded in a ConjunctionScorer, as the hits
+ // from a BooleanScorer are not always sorted by document number (sigh)
+ // and hence BooleanScorer cannot implement skipTo() correctly, which is
+ // required by ConjunctionScorer.
+ bool allRequired = true;
+ bool noneBoolean = true;
+ { //msvc6 scope fix
+ for (uint32_t i = 0 ; i < weights.size(); i++) {
+ BooleanClause* c = (*clauses)[i];
+ if (!c->required)
+ allRequired = false;
+ if (c->query->instanceOf(BooleanQuery::getClassName()))
+ noneBoolean = false;
+ }
+ }
+
+ if (allRequired && noneBoolean) { // ConjunctionScorer is okay
+ ConjunctionScorer* result =
+ _CLNEW ConjunctionScorer(parentQuery->getSimilarity(searcher));
+ for (uint32_t i = 0 ; i < weights.size(); i++) {
+ Weight* w = weights[i];
+ Scorer* subScorer = w->scorer(reader);
+ if (subScorer == NULL)
+ return NULL;
+ result->add(subScorer);
+ }
+ return result;
+ }
+
+ // Use good-old BooleanScorer instead.
+ BooleanScorer* result = _CLNEW BooleanScorer(parentQuery->getSimilarity(searcher));
+
+ { //msvc6 scope fix
+ for (uint32_t i = 0 ; i < weights.size(); i++) {
+ BooleanClause* c = (*clauses)[i];
+ Weight* w = weights[i];
+ Scorer* subScorer = w->scorer(reader);
+ if (subScorer != NULL)
+ result->add(subScorer, c->required, c->prohibited);
+ else if (c->required)
+ return NULL;
+ }
+ }
+
+ return result;
+ }
+
+ void BooleanQuery::BooleanWeight::explain(IndexReader* reader, int32_t doc, Explanation* result){
+ int32_t coord = 0;
+ int32_t maxCoord = 0;
+ qreal sum = 0.0f;
+ Explanation* sumExpl = _CLNEW Explanation;
+ for (uint32_t i = 0 ; i < weights.size(); i++) {
+ BooleanClause* c = (*clauses)[i];
+ Weight* w = weights[i];
+ Explanation* e = _CLNEW Explanation;
+ w->explain(reader, doc, e);
+ if (!c->prohibited)
+ maxCoord++;
+ if (e->getValue() > 0) {
+ if (!c->prohibited) {
+ sumExpl->addDetail(e);
+ sum += e->getValue();
+ coord++;
+ e = NULL; //prevent e from being deleted
+ } else {
+ //we want to return something else...
+ _CLDELETE(sumExpl);
+ result->setValue(0.0f);
+ result->setDescription(_T("match prohibited"));
+ return;
+ }
+ } else if (c->required) {
+ _CLDELETE(sumExpl);
+ result->setValue(0.0f);
+ result->setDescription(_T("match prohibited"));
+ return;
+ }
+
+ _CLDELETE(e);
+ }
+ sumExpl->setValue(sum);
+
+ if (coord == 1){ // only one clause matched
+ Explanation* tmp = sumExpl;
+ sumExpl = sumExpl->getDetail(0)->clone(); // eliminate wrapper
+ _CLDELETE(tmp);
+ }
+
+ sumExpl->setDescription(_T("sum of:"));
+ qreal coordFactor = parentQuery->getSimilarity(searcher)->coord(coord, maxCoord);
+ if (coordFactor == 1.0f){ // coord is no-op
+ result->set(*sumExpl); // eliminate wrapper
+ _CLDELETE(sumExpl);
+ } else {
+ result->setDescription( _T("product of:"));
+ result->addDetail(sumExpl);
+
+ StringBuffer explbuf;
+ explbuf.append(_T("coord("));
+ explbuf.appendInt(coord);
+ explbuf.append(_T("/"));
+ explbuf.appendInt(maxCoord);
+ explbuf.append(_T(")"));
+ result->addDetail(_CLNEW Explanation(coordFactor, explbuf.getBuffer()));
+ result->setValue(sum*coordFactor);
+ }
+ }
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/BooleanQuery.h b/3rdparty/clucene/src/CLucene/search/BooleanQuery.h
new file mode 100644
index 000000000..27b67d1e5
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/BooleanQuery.h
@@ -0,0 +1,126 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_BooleanQuery_
+#define _lucene_search_BooleanQuery_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "ConjunctionScorer.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/StringBuffer.h"
+#include "SearchHeader.h"
+#include "BooleanClause.h"
+#include "BooleanScorer.h"
+#include "Scorer.h"
+
+CL_NS_DEF(search)
+
+
+ // A Query that matches documents matching boolean combinations of other
+ // queries, typically {@link TermQuery}s or {@link PhraseQuery}s.
+ class BooleanQuery:public Query {
+ public:
+ typedef CL_NS(util)::CLVector<BooleanClause*,CL_NS(util)::Deletor::Object<BooleanClause> > ClausesType;
+ private:
+ BooleanQuery::ClausesType clauses;
+ static size_t maxClauseCount;
+
+ class BooleanWeight: public Weight {
+ private:
+ Searcher* searcher;
+ CL_NS(util)::CLVector<Weight*,CL_NS(util)::Deletor::Object<Weight> > weights;
+ ClausesType* clauses;
+ BooleanQuery* parentQuery;
+ public:
+ BooleanWeight(Searcher* searcher,
+ CL_NS(util)::CLVector<BooleanClause*,CL_NS(util)::Deletor::Object<BooleanClause> >* clauses,
+ BooleanQuery* parentQuery);
+ ~BooleanWeight();
+ Query* getQuery();
+ qreal getValue();
+ qreal sumOfSquaredWeights();
+ void normalize(qreal norm);
+ Scorer* scorer(CL_NS(index)::IndexReader* reader);
+ void explain(CL_NS(index)::IndexReader* reader, int32_t doc, Explanation* ret);
+ };//booleanweight
+
+ protected:
+ Weight* _createWeight(Searcher* searcher) {
+ return _CLNEW BooleanWeight(searcher,&clauses,this);
+ }
+ BooleanQuery(const BooleanQuery& clone);
+ public:
+ /** Constructs an empty boolean query. */
+ BooleanQuery();
+
+ ~BooleanQuery();
+
+ const TCHAR* getQueryName() const;
+ static const TCHAR* getClassName();
+
+ /** Return the maximum number of clauses permitted, 1024 by default.
+ * Attempts to add more than the permitted number of clauses cause {@link
+ * TooManyClauses} to be thrown.*/
+ static size_t getMaxClauseCount();
+
+ /** Set the maximum number of clauses permitted. */
+ static void setMaxClauseCount(size_t maxClauseCount);
+
+ /** Adds a clause to a boolean query. Clauses may be:
+ * <ul>
+ * <li><code>required</code> which means that documents which <i>do not</i>
+ * match this sub-query will <i>not</i> match the boolean query;
+ * <li><code>prohibited</code> which means that documents which <i>do</i>
+ * match this sub-query will <i>not</i> match the boolean query; or
+ * <li>neither, in which case matched documents are neither prohibited from
+ * nor required to match the sub-query. However, a document must match at
+ * least 1 sub-query to match the boolean query.
+ * </ul>
+ * It is an error to specify a clause as both <code>required</code> and
+ * <code>prohibited</code>.
+ *
+ * @see #getMaxClauseCount()
+ */
+ void add(Query* query, const bool required, const bool prohibited){
+ add(query,false,required,prohibited);
+ }
+ void add(Query* query, const bool deleteQuery, const bool required, const bool prohibited);
+
+ /** Copies the clauses of this query into the array.
+ * The array must be at least as long as getClauseCount()
+ * If you want to use the clauses, make sure you null terminate it.
+ */
+ void getClauses(BooleanClause** clauses) const;
+
+ ///@deprecated
+ _CL_DEPRECATED( getClauses(clauses) ) BooleanClause** getClauses() const;
+
+ /**
+ * Give client code access to clauses.size() so we know how
+ * large the array returned by getClauses is.
+ */
+ size_t getClauseCount() const;
+
+ /** Adds a clause to a boolean query.
+ * @see #getMaxClauseCount()
+ */
+ void add(BooleanClause* clause);
+
+ Query* rewrite(CL_NS(index)::IndexReader* reader);
+ Query* clone() const;
+ bool equals(Query* o) const;
+
+ /** Prints a user-readable version of this query. */
+ TCHAR* toString(const TCHAR* field) const;
+ /** Returns a hash code value for this object.*/
+ size_t hashCode() const;
+ };
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/BooleanScorer.cpp b/3rdparty/clucene/src/CLucene/search/BooleanScorer.cpp
new file mode 100644
index 000000000..ae7ee40d6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/BooleanScorer.cpp
@@ -0,0 +1,248 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "BooleanScorer.h"
+
+#include "Scorer.h"
+#include "Similarity.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+ BooleanScorer::BooleanScorer(Similarity* similarity):
+ Scorer(similarity),
+ scorers(NULL),
+ maxCoord (1),
+ nextMask (1),
+ end(0),
+ current(NULL),
+ requiredMask (0),
+ prohibitedMask (0),
+ coordFactors (NULL)
+ {
+ bucketTable = _CLNEW BucketTable(this);
+ }
+
+ BooleanScorer::~BooleanScorer(){
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ _CLDELETE(bucketTable);
+ _CLDELETE_ARRAY(coordFactors);
+ _CLDELETE(scorers);
+ }
+
+
+ bool BooleanScorer::next() {
+ bool more;
+ do {
+ while (bucketTable->first != NULL) { // more queued
+ current = bucketTable->first;
+ bucketTable->first = current->next; // pop the queue
+
+ // check prohibited & required
+ if ((current->bits & prohibitedMask) == 0 &&
+ (current->bits & requiredMask) == requiredMask) {
+ return true;
+ }
+ }
+
+ // refill the queue
+ more = false;
+ end += BooleanScorer::BucketTable_SIZE;
+ for (SubScorer* sub = scorers; sub != NULL; sub = sub->next) {
+ Scorer* scorer = sub->scorer;
+ int32_t doc;
+ while (!sub->done && (doc=scorer->doc()) < end) {
+ sub->collector->collect(doc, scorer->score());
+ sub->done = !scorer->next();
+ }
+ if (!sub->done) {
+ more = true;
+ }
+ }
+ } while (bucketTable->first != NULL || more);
+
+ return false;
+ }
+
+ qreal BooleanScorer::score(){
+ if (coordFactors == NULL)
+ computeCoordFactors();
+ return current->score * coordFactors[current->coord];
+ }
+
+ bool BooleanScorer::skipTo(int32_t target) {
+ _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: BooleanScorer::skipTo");
+ }
+
+ void BooleanScorer::explain(int32_t doc, Explanation* ret) {
+ _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: BooleanScorer::explain");
+ }
+
+ TCHAR* BooleanScorer::toString() {
+ CL_NS(util)::StringBuffer buffer;
+ buffer.append(_T("boolean("));
+ for (SubScorer* sub = scorers; sub != NULL; sub = sub->next) {
+ buffer.append(sub->scorer->toString());
+ buffer.append(_T(" "));
+ }
+ buffer.appendChar(')');
+ return buffer.toString();
+ }
+
+ void BooleanScorer::add(Scorer* scorer, const bool required, const bool prohibited) {
+ int32_t mask = 0;
+ if (required || prohibited) {
+ if (nextMask == 0)
+ _CLTHROWA(CL_ERR_IndexOutOfBounds, "More than 32 required/prohibited clauses in query.");
+ mask = nextMask;
+ nextMask = ( nextMask << 1 );
+ } else
+ mask = 0;
+
+ if (!prohibited)
+ maxCoord++;
+
+ if (prohibited)
+ prohibitedMask |= mask; // update prohibited mask
+ else if (required)
+ requiredMask |= mask; // update required mask
+
+ //scorer, HitCollector, and scorers is delete in the SubScorer
+ scorers = _CLNEW SubScorer(scorer, required, prohibited,
+ bucketTable->newCollector(mask), scorers);
+ }
+
+ void BooleanScorer::computeCoordFactors(){
+ coordFactors = _CL_NEWARRAY(qreal,maxCoord);
+ for (int32_t i = 0; i < maxCoord; i++)
+ coordFactors[i] = getSimilarity()->coord(i, maxCoord-1);
+ }
+
+ /*void BooleanScorer::score(HitCollector* results, const int32_t maxDoc) {
+ if (coordFactors == NULL)
+ computeCoordFactors();
+
+ while (currentDoc < maxDoc) {
+ currentDoc = (currentDoc+BucketTable_SIZE<maxDoc?currentDoc+BucketTable_SIZE:maxDoc);
+ for (SubScorer* t = scorers; t != NULL; t = t->next)
+ t->scorer->score((t->collector), currentDoc);
+ bucketTable->collectHits(results);
+ }
+ }*/
+
+
+
+
+ BooleanScorer::SubScorer::SubScorer(Scorer* scr, const bool r, const bool p, HitCollector* c, SubScorer* nxt):
+ scorer(scr),
+ required(r),
+ prohibited(p),
+ collector(c),
+ next(nxt)
+ {
+ //Func - Constructor
+ //Pre - scr != NULL,
+ // c != NULL
+ // nxt may or may not be NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(scr != NULL,"scr is NULL");
+ CND_PRECONDITION(c != NULL,"c is NULL");
+
+ done = !scorer->next();
+ }
+
+ BooleanScorer::SubScorer::~SubScorer(){
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ for (SubScorer * ptr = next; ptr; ){
+ SubScorer* next = ptr->next;
+ ptr->next = NULL;
+ _CLDELETE(ptr);
+ ptr = next;
+ }
+ _CLDELETE(scorer);
+ _CLDELETE(collector);
+ }
+
+ BooleanScorer::Bucket::Bucket():
+ doc(-1),
+ score(0.0),
+ bits(0),
+ coord(0),
+ next(NULL)
+ {
+ }
+ BooleanScorer::Bucket::~Bucket(){
+ }
+
+
+
+
+ BooleanScorer::BucketTable::BucketTable(BooleanScorer* scr):
+ scorer(scr),
+ first(NULL)
+ {
+ buckets = _CL_NEWARRAY(Bucket,BucketTable_SIZE);
+ }
+ BooleanScorer::BucketTable::~BucketTable(){
+ clear();
+ _CLDELETE_ARRAY(buckets);
+ }
+
+ void BooleanScorer::BucketTable::clear(){
+ //delete first;
+ first = NULL;
+ }
+ int32_t BooleanScorer::BucketTable::size() const { return BooleanScorer::BucketTable_SIZE; }
+
+ HitCollector* BooleanScorer::BucketTable::newCollector(const int32_t mask) {
+ return _CLNEW Collector(mask, this);
+ }
+
+
+
+
+
+
+
+
+
+ BooleanScorer::Collector::Collector(const int32_t msk, BucketTable* bucketTbl):
+ bucketTable(bucketTbl),
+ mask(msk)
+ {
+ }
+
+ void BooleanScorer::Collector::collect(const int32_t doc, const qreal score){
+ BucketTable* table = bucketTable;
+ int32_t i = doc & (BooleanScorer::BucketTable_SIZE-1);
+ Bucket* bucket = &table->buckets[i];
+
+ if (bucket->doc != doc) { // invalid bucket
+ bucket->doc = doc; // set doc
+ bucket->score = score; // initialize score
+ bucket->bits = mask; // initialize mask
+ bucket->coord = 1; // initialize coord
+
+ bucket->next = table->first; // push onto valid list
+ table->first = bucket;
+ } else { // valid bucket
+ bucket->score += score; // increment score
+ bucket->bits |= mask; // add bits in mask
+ bucket->coord++; // increment coord
+ }
+ }
+
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/BooleanScorer.h b/3rdparty/clucene/src/CLucene/search/BooleanScorer.h
new file mode 100644
index 000000000..2147bc516
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/BooleanScorer.h
@@ -0,0 +1,99 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_BooleanScorer_
+#define _lucene_search_BooleanScorer_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "Scorer.h"
+
+CL_NS_DEF(search)
+
+class BooleanScorer : public Scorer {
+public:
+ class Bucket : LUCENE_BASE {
+ public:
+ int32_t doc; // tells if bucket is valid
+ qreal score; // incremental score
+ int32_t bits; // used for bool constraints
+ int32_t coord; // count of terms in score
+ Bucket* next; // next valid bucket
+
+ Bucket();
+ ~Bucket();
+ };
+
+ class SubScorer: LUCENE_BASE {
+ public:
+ bool done;
+ Scorer* scorer;
+ bool required;
+ bool prohibited;
+ HitCollector* collector;
+ SubScorer* next;
+ SubScorer(Scorer* scr, const bool r, const bool p, HitCollector* c, SubScorer* nxt);
+ ~SubScorer();
+ };
+
+ class BucketTable:LUCENE_BASE {
+ private:
+ BooleanScorer* scorer;
+ public:
+ Bucket* buckets;
+ Bucket* first; // head of valid list
+
+ BucketTable(BooleanScorer* scr);
+ int32_t size() const;
+ HitCollector* newCollector(const int32_t mask);
+ void clear();
+ ~BucketTable();
+
+ };
+
+ class Collector: public HitCollector {
+ private:
+ BucketTable* bucketTable;
+ int32_t mask;
+ public:
+ Collector(const int32_t mask, BucketTable* bucketTable);
+
+ void collect(const int32_t doc, const qreal score);
+ };
+
+ SubScorer* scorers;
+ BucketTable* bucketTable;
+
+ int32_t maxCoord;
+ int32_t nextMask;
+
+ int32_t end;
+ Bucket* current;
+
+public:
+ LUCENE_STATIC_CONSTANT(int32_t,BucketTable_SIZE=1024);
+ int32_t requiredMask;
+ int32_t prohibitedMask;
+ qreal* coordFactors;
+
+ BooleanScorer(Similarity* similarity);
+ ~BooleanScorer();
+ void add(Scorer* scorer, const bool required, const bool prohibited);
+ int32_t doc() const { return current->doc; }
+ bool next();
+ qreal score();
+ bool skipTo(int32_t target);
+ void explain(int32_t doc, Explanation* ret);
+ TCHAR* toString();
+ void computeCoordFactors();
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/CachingWrapperFilter.cpp b/3rdparty/clucene/src/CLucene/search/CachingWrapperFilter.cpp
new file mode 100644
index 000000000..694556ca7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/CachingWrapperFilter.cpp
@@ -0,0 +1,86 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "CachingWrapperFilter.h"
+
+CL_NS_DEF(search)
+CL_NS_USE(index)
+CL_NS_USE(util)
+
+AbstractCachingFilter::AbstractCachingFilter():
+ cache(false,true)
+{
+}
+AbstractCachingFilter::AbstractCachingFilter(const AbstractCachingFilter& copy):
+ cache(false,true)
+{
+}
+AbstractCachingFilter::~AbstractCachingFilter(){
+}
+AbstractCachingFilter::BitSetHolder::BitSetHolder(CL_NS(util)::BitSet* bits, bool deleteBs){
+ this->bits = bits;
+ this->deleteBs = deleteBs;
+}
+AbstractCachingFilter::BitSetHolder::~BitSetHolder(){
+ if ( deleteBs )
+ _CLDELETE(bits);
+}
+
+
+BitSet* AbstractCachingFilter::bits(IndexReader* reader){
+ SCOPED_LOCK_MUTEX(cache.THIS_LOCK)
+ BitSetHolder* cached = cache.get(reader);
+ if ( cached != NULL )
+ return cached->bits;
+ BitSet* bs = doBits(reader);
+ BitSetHolder* bsh = _CLNEW BitSetHolder(bs, doShouldDeleteBitSet(bs));
+ cache.put(reader,bsh);
+ return bs;
+}
+void AbstractCachingFilter::closeCallback(CL_NS(index)::IndexReader* reader, void*){
+ SCOPED_LOCK_MUTEX(cache.THIS_LOCK)
+ cache.remove(reader);
+}
+
+
+
+
+CachingWrapperFilter::CachingWrapperFilter(Filter* filter, bool deleteFilter){
+ this->filter = filter;
+ this->deleteFilter = deleteFilter;
+}
+CachingWrapperFilter::CachingWrapperFilter(const CachingWrapperFilter& copy):
+ AbstractCachingFilter(copy)
+{
+ this->filter = copy.filter->clone();
+ this->deleteFilter = true;
+}
+Filter* CachingWrapperFilter::clone() const{
+ return _CLNEW CachingWrapperFilter(*this);
+}
+TCHAR* CachingWrapperFilter::toString(){
+ TCHAR* fs = filter->toString();
+ int len = _tcslen(fs)+23;
+ TCHAR* ret = _CL_NEWARRAY(TCHAR,len);
+ _sntprintf(ret,len,_T("CachingWrapperFilter(%s)"),fs);
+ _CLDELETE_CARRAY(fs);
+ return ret;
+}
+BitSet* CachingWrapperFilter::doBits(IndexReader* reader){
+ return filter->bits(reader);
+}
+bool CachingWrapperFilter::doShouldDeleteBitSet( CL_NS(util)::BitSet* bits ){
+ return filter->shouldDeleteBitSet(bits);
+}
+CachingWrapperFilter::~CachingWrapperFilter(){
+ if ( deleteFilter ){
+ _CLDELETE(filter);
+ }else
+ filter=NULL;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/CachingWrapperFilter.h b/3rdparty/clucene/src/CLucene/search/CachingWrapperFilter.h
new file mode 100644
index 000000000..e48a18292
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/CachingWrapperFilter.h
@@ -0,0 +1,80 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_CachingWrapperFilter_
+#define _lucene_search_CachingWrapperFilter_
+
+#include "CLucene/util/BitSet.h"
+#include "CLucene/index/IndexReader.h"
+#include "Filter.h"
+
+CL_NS_DEF(search)
+/**
+ * Wraps another filter's result and caches it. The purpose is to allow
+ * filters to implement this and allow itself to be cached. Alternatively,
+ * use the CachingWrapperFilter to cache the filter.
+ */
+class AbstractCachingFilter: public Filter
+{
+ class BitSetHolder: LUCENE_BASE{
+ bool deleteBs;
+ public:
+ BitSetHolder(CL_NS(util)::BitSet* bits, bool deleteBs);
+ ~BitSetHolder();
+ CL_NS(util)::BitSet* bits;
+ };
+ void closeCallback(CL_NS(index)::IndexReader* reader, void* param);
+ typedef CL_NS(util)::CLHashMap<CL_NS(index)::IndexReader*,
+ BitSetHolder*,
+ CL_NS(util)::Compare::Void<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Equals::Void<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Deletor::Object<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Deletor::Object<BitSetHolder> > CacheType;
+
+ CacheType cache;
+
+protected:
+ AbstractCachingFilter( const AbstractCachingFilter& copy );
+ virtual CL_NS(util)::BitSet* doBits( CL_NS(index)::IndexReader* reader ) = 0;
+ virtual bool doShouldDeleteBitSet( CL_NS(util)::BitSet* bits ){ return false; }
+ AbstractCachingFilter();
+public:
+ virtual ~AbstractCachingFilter();
+
+ /** Returns a BitSet with true for documents which should be permitted in
+ search results, and false for those that should not. */
+ CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader );
+
+ virtual Filter *clone() const = 0;
+ virtual TCHAR *toString() = 0;
+
+ bool shouldDeleteBitSet( const CL_NS(util)::BitSet* bits ) const{ return false; }
+};
+
+/**
+ * Wraps another filter's result and caches it. The purpose is to allow
+ * filters to simply filter, and then wrap with this class to add
+ * caching, keeping the two concerns decoupled yet composable.
+ */
+class CachingWrapperFilter: public AbstractCachingFilter
+{
+private:
+ Filter* filter;
+ bool deleteFilter;
+protected:
+ CachingWrapperFilter( const CachingWrapperFilter& copy );
+ CL_NS(util)::BitSet* doBits( CL_NS(index)::IndexReader* reader );
+ bool doShouldDeleteBitSet( CL_NS(util)::BitSet* bits );
+public:
+ CachingWrapperFilter( Filter* filter, bool deleteFilter=true );
+ ~CachingWrapperFilter();
+
+ Filter *clone() const;
+ TCHAR *toString();
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp b/3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp
new file mode 100644
index 000000000..4b6389c0f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp
@@ -0,0 +1,213 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+
+#include <CLucene/StdHeader.h>
+#include <CLucene/util/Misc.h>
+#include "ChainedFilter.h"
+
+CL_NS_DEF(search)
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_USE(document)
+
+
+ChainedFilter::ChainedFilter( Filter ** _filters, int _op ):
+ filters(_filters),
+ logicArray(NULL),
+ logic(_op)
+{
+}
+ChainedFilter::ChainedFilter( Filter** _filters, int* _array ):
+ filters(_filters),
+ logicArray(_array),
+ logic(-1)
+{
+}
+ChainedFilter::ChainedFilter( const ChainedFilter& copy ) :
+ logicArray( copy.logicArray ),
+ logic( copy.logic )
+{
+ filters = copy.filters;
+}
+ChainedFilter::~ChainedFilter(void)
+{
+
+}
+
+Filter* ChainedFilter::clone() const {
+ return _CLNEW ChainedFilter(*this );
+}
+
+const TCHAR* ChainedFilter::getLogicString(int logic){
+ if ( logic == ChainedFilter::OR )
+ return _T("OR");
+ else if ( logic == ChainedFilter::AND )
+ return _T("AND");
+ else if ( logic == ChainedFilter::ANDNOT )
+ return _T("ANDNOT");
+ else if ( logic == ChainedFilter::XOR )
+ return _T("XOR");
+ else if ( logic >= ChainedFilter::USER ){
+ return _T("USER");
+ }
+ return _T("");
+}
+
+TCHAR* ChainedFilter::toString()
+{
+
+ Filter** filter = filters;
+
+ StringBuffer buf(_T("ChainedFilter: ["));
+ int* la = logicArray;
+ while(*filter )
+ {
+ if ( filter != filters )
+ buf.appendChar(' ');
+ buf.append(getLogicString(logic==-1?*la:logic));
+ buf.appendChar(' ');
+
+ TCHAR* filterstr = (*filter)->toString();
+ buf.append(filterstr);
+ _CLDELETE_ARRAY( filterstr );
+
+ filter++;
+ if ( logic == -1 )
+ la++;
+ }
+
+ buf.appendChar(']');
+
+ return buf.toString();
+}
+
+
+/** Returns a BitSet with true for documents which should be permitted in
+search results, and false for those that should not. */
+BitSet* ChainedFilter::bits( IndexReader* reader )
+{
+ if( logic != -1 )
+ return bits( reader, logic );
+ else if( logicArray != NULL )
+ return bits( reader, logicArray );
+ else
+ return bits( reader, DEFAULT );
+}
+
+
+BitSet* ChainedFilter::bits( IndexReader* reader, int logic )
+{
+ BitSet* bts = NULL;
+
+ Filter** filter = filters;
+
+ // see discussion at top of file
+ if( *filter ) {
+ BitSet* tmp = (*filter)->bits( reader );
+ if ( (*filter)->shouldDeleteBitSet(tmp) ) //if we are supposed to delete this BitSet, then
+ bts = tmp; //we can safely call it our own
+ else if ( tmp == NULL ){
+ int32_t len = reader->maxDoc();
+ bts = _CLNEW BitSet( len ); //bitset returned null, which means match _all_
+ for (int32_t i=0;i<len;i++ )
+ bts->set(i);
+ }else{
+ bts = tmp->clone(); //else it is probably cached, so we need to copy it before using it.
+ }
+ filter++;
+ }
+ else
+ bts = _CLNEW BitSet( reader->maxDoc() );
+
+ while( *filter ) {
+ doChain( bts, reader, logic, *filter );
+ filter++;
+ }
+
+ return bts;
+}
+
+
+BitSet* ChainedFilter::bits( IndexReader* reader, int* _logicArray )
+{
+ BitSet* bts = NULL;
+
+ Filter** filter = filters;
+ int* logic = _logicArray;
+
+ // see discussion at top of file
+ if( *filter ) {
+ BitSet* tmp = (*filter)->bits( reader );
+ if ( (*filter)->shouldDeleteBitSet(tmp) ) //if we are supposed to delete this BitSet, then
+ bts = tmp; //we can safely call it our own
+ else if ( tmp == NULL ){
+ int32_t len = reader->maxDoc();
+ bts = _CLNEW BitSet( len ); //bitset returned null, which means match _all_
+ for (int32_t i=0;i<len;i++ )
+ bts->set(i); //todo: this could mean that we can skip certain types of filters
+ }
+ else
+ {
+ bts = tmp->clone(); //else it is probably cached, so we need to copy it before using it.
+ }
+ filter++;
+ logic++;
+ }
+ else
+ bts = _CLNEW BitSet( reader->maxDoc() );
+
+ while( *filter ) {
+ doChain( bts, reader, *logic, *filter );
+ filter++;
+ logic++;
+ }
+
+ return bts;
+}
+
+void ChainedFilter::doUserChain( CL_NS(util)::BitSet* chain, CL_NS(util)::BitSet* filter, int logic ){
+ _CLTHROWA(CL_ERR_Runtime,"User chain logic not implemented by superclass");
+}
+
+BitSet* ChainedFilter::doChain( BitSet* resultset, IndexReader* reader, int logic, Filter* filter )
+{
+ BitSet* filterbits = filter->bits( reader );
+ int32_t maxDoc = reader->maxDoc();
+ int32_t i=0;
+ if ( logic >= ChainedFilter::USER ){
+ doUserChain(resultset,filterbits,logic);
+ }else{
+ switch( logic )
+ {
+ case OR:
+ for( i=0; i < maxDoc; i++ )
+ resultset->set( i, (resultset->get(i) || (filterbits==NULL || filterbits->get(i) ))?1:0 );
+ break;
+ case AND:
+ for( i=0; i < maxDoc; i++ )
+ resultset->set( i, (resultset->get(i) && (filterbits==NULL || filterbits->get(i) ))?1:0 );
+ break;
+ case ANDNOT:
+ for( i=0; i < maxDoc; i++ )
+ resultset->set( i, (resultset->get(i) && (filterbits==NULL || filterbits->get(i)))?0:1 );
+ break;
+ case XOR:
+ for( i=0; i < maxDoc; i++ )
+ resultset->set( i, resultset->get(i) ^ ((filterbits==NULL || filterbits->get(i) )?1:0) );
+ break;
+ default:
+ doChain( resultset, reader, DEFAULT, filter );
+ }
+ }
+
+ if ( filter->shouldDeleteBitSet(filterbits) )
+ _CLDELETE( filterbits );
+
+ return resultset;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/ChainedFilter.h b/3rdparty/clucene/src/CLucene/search/ChainedFilter.h
new file mode 100644
index 000000000..f4d9d0049
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/ChainedFilter.h
@@ -0,0 +1,86 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_ChainedFilter_
+#define _lucene_search_ChainedFilter_
+
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/BitSet.h"
+#include "CLucene/search/Filter.h"
+
+CL_NS_DEF(search)
+
+/*
+Discussion - brian@unixpoet.com
+
+From ChainedFilter.java:
+
+...
+
+// First AND operation takes place against a completely false
+// bitset and will always return zero results. Thanks to
+// Daniel Armbrust for pointing this out and suggesting workaround.
+
+if (logic[0] == AND)
+{
+ result = (BitSet) chain[i].bits(reader).clone();
+ ++i;
+}
+
+...
+
+The observation is correct and it was buggy. The problem is that the same
+issue remains for the ANDNOT logic op but with the inverse result: all bits
+set to 1. The result of the other ops, i.e. OR, AND, XOR for the first filter
+ends up just copying the bitset of the first filter (explicitly in the case of the AND).
+
+Why not do the same for the NAND? This will have the side effect of rendering the first op
+in the logic array superflous - not a big problem.
+
+The only "problem" is that we will return different results then the Java
+Lucene code - though I prefer CLucene to be a correct implementation and only maintain
+API compat rather than full 100% compat with Lucene.
+*/
+class ChainedFilter: public Filter
+{
+public:
+ LUCENE_STATIC_CONSTANT(int, OR = 0); //set current bit if the chain is set OR if the filter bit is set
+ LUCENE_STATIC_CONSTANT(int, AND = 1); //set current bit if the chain is set AND the filter bit is set
+ LUCENE_STATIC_CONSTANT(int, ANDNOT = 2); //set current bit if the chain is not set AND the filter bit is not set
+ LUCENE_STATIC_CONSTANT(int, XOR = 3); //set current bit if the chain is set OR the filter bit is set BUT not both is set
+
+ LUCENE_STATIC_CONSTANT(int, USER = 5); //add this value to user defined value, then override doUserChain
+
+ LUCENE_STATIC_CONSTANT(int, DEFAULT = OR);
+
+protected:
+ Filter **filters;
+ int *logicArray;
+ int logic;
+
+ ChainedFilter( const ChainedFilter& copy );
+ CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader, int logic );
+ CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader, int* logicArray );
+ CL_NS(util)::BitSet* doChain( CL_NS(util)::BitSet* result, CL_NS(index)::IndexReader* reader, int logic, Filter* filter );
+
+ virtual void doUserChain( CL_NS(util)::BitSet* chain, CL_NS(util)::BitSet* filter, int logic );
+ virtual const TCHAR* getLogicString(int logic);
+public:
+ ChainedFilter( Filter** filters, int op = DEFAULT );
+ ChainedFilter( Filter** filters, int* _array );
+ virtual ~ChainedFilter();
+
+ /** Returns a BitSet with true for documents which should be permitted in
+ search results, and false for those that should not. */
+ CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader );
+
+ virtual Filter* clone() const;
+
+ TCHAR* toString();
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/Compare.h b/3rdparty/clucene/src/CLucene/search/Compare.h
new file mode 100644
index 000000000..ab38b17f1
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Compare.h
@@ -0,0 +1,161 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_Compare_
+#define _lucene_search_Compare_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "FieldSortedHitQueue.h"
+
+CL_NS_DEF(search)
+
+
+class ScoreDocComparators:LUCENE_BASE {
+protected:
+ ScoreDocComparators(){}
+public:
+ ~ScoreDocComparators(){
+ }
+
+ class Relevance:public ScoreDocComparator {
+ public:
+ int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j) {
+ if (i->score > j->score) return -1;
+ if (i->score < j->score) return 1;
+ return 0;
+ }
+ CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i) {
+ return _CLNEW CL_NS(util)::Compare::Float (i->score);
+ }
+ int32_t sortType() {
+ return SortField::DOCSCORE;
+ }
+ };
+
+ class IndexOrder:public ScoreDocComparator{
+ public:
+ IndexOrder():
+ ScoreDocComparator()
+ {
+
+ }
+ int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j) {
+ if (i->doc < j->doc) return -1;
+ if (i->doc > j->doc) return 1;
+ return 0;
+ }
+ CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i) {
+ return _CLNEW CL_NS(util)::Compare::Int32(i->doc);
+ }
+ int32_t sortType() {
+ return SortField::DOC;
+ }
+ };
+
+
+ class String: public ScoreDocComparator {
+ FieldCache::StringIndex* index;
+#ifdef _CL__CND_DEBUG
+ int32_t length;
+#endif
+ public:
+ String(FieldCache::StringIndex* index, int32_t len)
+ {
+#ifdef _CL__CND_DEBUG
+ this->length = len;
+#endif
+ this->index = index;
+ }
+
+ int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j) {
+ CND_PRECONDITION(i->doc<length, "i->doc>=length")
+ CND_PRECONDITION(j->doc<length, "j->doc>=length")
+ if (index->order[i->doc] < index->order[j->doc]) return -1;
+ if (index->order[i->doc] > index->order[j->doc]) return 1;
+ return 0;
+ }
+
+ CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i) {
+ return _CLNEW CL_NS(util)::Compare::TChar(index->lookup[index->order[i->doc]]);
+ }
+
+ int32_t sortType() {
+ return SortField::STRING;
+ }
+ };
+
+ class Int32:public ScoreDocComparator{
+ int32_t* fieldOrder;
+#ifdef _CL__CND_DEBUG
+ int32_t length;
+#endif
+ public:
+ Int32(int32_t* fieldOrder, int32_t len)
+ {
+ this->fieldOrder = fieldOrder;
+#ifdef _CL__CND_DEBUG
+ this->length = len;
+#endif
+ }
+
+
+ int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j) {
+ CND_PRECONDITION(i->doc<length, "i->doc>=length")
+ CND_PRECONDITION(j->doc<length, "j->doc>=length")
+ if (fieldOrder[i->doc] < fieldOrder[j->doc]) return -1;
+ if (fieldOrder[i->doc] > fieldOrder[j->doc]) return 1;
+ return 0;
+ }
+
+ CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i) {
+ CND_PRECONDITION(i->doc<length, "i->doc>=length")
+ return _CLNEW CL_NS(util)::Compare::Int32(fieldOrder[i->doc]);
+ }
+
+ int32_t sortType() {
+ return SortField::INT;
+ }
+ };
+
+ class Float:public ScoreDocComparator {
+ qreal* fieldOrder;
+#ifdef _CL__CND_DEBUG
+ int32_t length;
+#endif
+ public:
+ Float(qreal* fieldOrder, int32_t len)
+ {
+ this->fieldOrder = fieldOrder;
+#ifdef _CL__CND_DEBUG
+ this->length = len;
+#endif
+ }
+
+ int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j) {
+ CND_PRECONDITION(i->doc<length, "i->doc>=length")
+ CND_PRECONDITION(j->doc<length, "j->doc>=length")
+ if (fieldOrder[i->doc] < fieldOrder[j->doc]) return -1;
+ if (fieldOrder[i->doc] > fieldOrder[j->doc]) return 1;
+ return 0;
+ }
+
+ CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i) {
+ CND_PRECONDITION(i->doc<length, "i->doc>=length")
+ return _CLNEW CL_NS(util)::Compare::Float(fieldOrder[i->doc]);
+ }
+
+ int32_t sortType() {
+ return SortField::FLOAT;
+ }
+ };
+};
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/ConjunctionScorer.cpp b/3rdparty/clucene/src/CLucene/search/ConjunctionScorer.cpp
new file mode 100644
index 000000000..9b7846f8e
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/ConjunctionScorer.cpp
@@ -0,0 +1,144 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "ConjunctionScorer.h"
+#include "CLucene/util/Arrays.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+ Scorer* ConjunctionScorer::first() const{
+ if ( scorers.end() == scorers.begin() )
+ return NULL;
+
+ return *scorers.begin();
+ } //get First
+ Scorer* ConjunctionScorer::last() {
+ if ( scorers.end() == scorers.begin() )
+ return NULL;
+
+ CL_NS_STD(list)<Scorer*>::iterator i = scorers.end();
+ --i;
+ return *i;
+ } //get Last
+
+ class _ScorerSorter:public CL_NS(util)::Arrays::_Arrays<Scorer*>{
+ public:
+ bool equals(Scorer* o1,Scorer* o2) const{
+ return o1->doc() == o2->doc();
+ }
+ int32_t compare(Scorer* o1,Scorer* o2) const{
+ return o1->doc() - o2->doc();
+ }
+ };
+ _ScorerSorter __ScorerSorter;
+
+ void ConjunctionScorer::sortScorers() {
+ // move scorers to an array
+ int32_t size = scorers.size();
+ Scorer** array = _CL_NEWARRAY(Scorer*,size+1);
+ scorers.toArray(array);
+ scorers.clear(); // empty the list
+
+ // note that this comparator is not consistent with equals!
+ __ScorerSorter.sort(array,size,0,size);
+
+ for (int32_t i = 0; i<size; i++) {
+ scorers.push_back(array[i]); // re-build list, now sorted
+ }
+ _CLDELETE_ARRAY(array);
+ }
+
+ bool ConjunctionScorer::doNext() {
+ while (more && first()->doc() < last()->doc()) { // find doc w/ all clauses
+ more = first()->skipTo(last()->doc()); // skip first upto last
+ Scorer* scorer = *scorers.begin();
+ scorers.delete_front();
+ scorers.push_back(scorer); // move first to last
+ }
+ return more; // found a doc with all clauses
+ }
+
+
+ void ConjunctionScorer::init() {
+ more = scorers.size() > 0;
+
+ // compute coord factor
+ coord = getSimilarity()->coord(scorers.size(), scorers.size());
+
+ // move each scorer to its first entry
+ CL_NS_STD(list)<Scorer*>::iterator i = scorers.begin();
+ while (more && i!=scorers.end()) {
+ more = ((Scorer*)*i)->next();
+ ++i;
+ }
+
+ if (more)
+ sortScorers(); // initial sort of list
+
+ firstTime = false;
+ }
+
+ ConjunctionScorer::ConjunctionScorer(Similarity* similarity):
+ Scorer(similarity),
+ scorers(false),
+ firstTime(true),
+ more(true),
+ coord(0.0)
+ {
+ }
+ ConjunctionScorer::~ConjunctionScorer(){
+ scorers.setDoDelete(true);
+ }
+
+ TCHAR *CL_NS(search)::Scorer::toString(void){
+ return STRDUP_TtoT(_T("ConjunctionScorer"));
+ }
+
+
+ void ConjunctionScorer::add(Scorer* scorer){
+ scorers.push_back(scorer);
+ }
+
+
+ int32_t ConjunctionScorer::doc() const{ return first()->doc(); }
+
+ bool ConjunctionScorer::next() {
+ if (firstTime) {
+ init();
+ } else if (more) {
+ more = last()->next(); // trigger further scanning
+ }
+ return doNext();
+ }
+
+ bool ConjunctionScorer::skipTo(int32_t target) {
+ CL_NS_STD(list)<Scorer*>::iterator i = scorers.begin();
+ while (more && i!=scorers.end()) {
+ more = ((Scorer*)*i)->skipTo(target);
+ ++i;
+ }
+ if (more)
+ sortScorers(); // re-sort scorers
+ return doNext();
+ }
+
+ qreal ConjunctionScorer::score(){
+ qreal score = 0.0f; // sum scores
+ CL_NS_STD(list)<Scorer*>::const_iterator i = scorers.begin();
+ while (i!=scorers.end()){
+ score += (*i)->score();
+ ++i;
+ }
+ score *= coord;
+ return score;
+ }
+
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/ConjunctionScorer.h b/3rdparty/clucene/src/CLucene/search/ConjunctionScorer.h
new file mode 100644
index 000000000..4b6807209
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/ConjunctionScorer.h
@@ -0,0 +1,50 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_ConjunctionScorer_
+#define _lucene_search_ConjunctionScorer_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+#include "Scorer.h"
+#include "Similarity.h"
+
+CL_NS_DEF(search)
+
+/** Scorer for conjunctions, sets of queries, all of which are required. */
+class ConjunctionScorer: public Scorer {
+private:
+ CL_NS(util)::CLLinkedList<Scorer*,CL_NS(util)::Deletor::Object<Scorer> > scorers;
+ bool firstTime;
+ bool more;
+ qreal coord;
+
+ Scorer* first() const;
+ Scorer* last();
+ void sortScorers();
+ bool doNext();
+ void init();
+public:
+ ConjunctionScorer(Similarity* similarity);
+ virtual ~ConjunctionScorer();
+ TCHAR* toString(void){
+ return STRDUP_TtoT(_T("ConjunctionScorer"));
+ }
+ void add(Scorer* scorer);
+ int32_t doc() const;
+ bool next();
+ bool skipTo(int32_t target);
+ qreal score();
+ virtual void explain(int32_t doc, Explanation* ret) {
+ _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: ConjunctionScorer::explain");
+ }
+
+
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/DateFilter.cpp b/3rdparty/clucene/src/CLucene/search/DateFilter.cpp
new file mode 100644
index 000000000..925858204
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/DateFilter.cpp
@@ -0,0 +1,93 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "DateFilter.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_USE(document)
+CL_NS_DEF(search)
+
+ DateFilter::~DateFilter(){
+ _CLDECDELETE( start );
+ _CLDECDELETE( end );
+ }
+
+ DateFilter::DateFilter(const DateFilter& copy):
+ start( _CL_POINTER(copy.start) ),
+ end ( _CL_POINTER(copy.end) )
+ {
+ }
+
+ /** Constructs a filter for field <code>f</code> matching times between
+ <code>from</code> and <code>to</code>. */
+ DateFilter::DateFilter(const TCHAR* f, int64_t from, int64_t to)
+ {
+ TCHAR* tmp = DateField::timeToString(from);
+ start = _CLNEW Term(f, tmp);
+ _CLDELETE_CARRAY(tmp);
+
+ tmp = DateField::timeToString(to);
+ end = _CLNEW Term(start, tmp);
+ _CLDELETE_CARRAY(tmp);
+ }
+
+ /** Constructs a filter for field <code>f</code> matching times before
+ <code>time</code>. */
+ DateFilter* DateFilter::Before(const TCHAR* field, int64_t time) {
+ return _CLNEW DateFilter(field, 0,time);
+ }
+
+ /** Constructs a filter for field <code>f</code> matching times after
+ <code>time</code>. */
+ DateFilter* DateFilter::After(const TCHAR* field, int64_t time) {
+ return _CLNEW DateFilter(field,time, DATEFIELD_DATE_MAX );
+ }
+
+ /** Returns a BitSet with true for documents which should be permitted in
+ search results, and false for those that should not. */
+ BitSet* DateFilter::bits(IndexReader* reader) {
+ BitSet* bts = _CLNEW BitSet(reader->maxDoc());
+
+ TermEnum* enumerator = reader->terms(start);
+ if (enumerator->term(false) == NULL){
+ _CLDELETE(enumerator);
+ return bts;
+ }
+ TermDocs* termDocs = reader->termDocs();
+
+ try {
+ while (enumerator->term(false)->compareTo(end) <= 0) {
+ termDocs->seek(enumerator->term(false));
+ while (termDocs->next()) {
+ bts->set(termDocs->doc());
+ }
+ if (!enumerator->next()) {
+ break;
+ }
+ }
+ } _CLFINALLY (
+ termDocs->close();
+ _CLDELETE(termDocs);
+ enumerator->close();
+ _CLDELETE(enumerator);
+ );
+ return bts;
+ }
+
+ Filter* DateFilter::clone() const{
+ return _CLNEW DateFilter(*this);
+ }
+
+ TCHAR* DateFilter::toString(){
+ size_t len = _tcslen(start->field()) + start->textLength() + end->textLength() + 8;
+ TCHAR* ret = _CL_NEWARRAY(TCHAR,len);
+ ret[0]=0;
+ _sntprintf(ret,len,_T("%s: [%s-%s]"), start->field(),start->text(),end->text());
+ return ret;
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/DateFilter.h b/3rdparty/clucene/src/CLucene/search/DateFilter.h
new file mode 100644
index 000000000..b37272b84
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/DateFilter.h
@@ -0,0 +1,59 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_DateFilter_
+#define _lucene_search_DateFilter_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/document/DateField.h"
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/BitSet.h"
+#include "Filter.h"
+
+CL_NS_DEF(search)
+ /**
+ * A Filter that restricts search results to a range of time.
+ *
+ * <p>For this to work, documents must have been indexed with a
+ * {@link DateField}.
+ */
+ class DateFilter: public Filter {
+ private:
+ CL_NS(index)::Term* start;
+ CL_NS(index)::Term* end;
+
+ protected:
+ DateFilter(const DateFilter& copy);
+ public:
+ ~DateFilter();
+
+ /** Constructs a filter for field <code>f</code> matching times between
+ <code>from</code> and <code>to</code>. */
+ DateFilter(const TCHAR* f, int64_t from, int64_t to);
+
+ /** Constructs a filter for field <code>f</code> matching times before
+ <code>time</code>. */
+ static DateFilter* Before(const TCHAR* field, int64_t time) ;
+
+ /** Constructs a filter for field <code>f</code> matching times after
+ <code>time</code>. */
+ static DateFilter* After(const TCHAR* field, int64_t time) ;
+
+ /** Returns a BitSet with true for documents which should be permitted in
+ search results, and false for those that should not. */
+ CL_NS(util)::BitSet* bits(CL_NS(index)::IndexReader* reader) ;
+
+ Filter* clone() const;
+
+ TCHAR* toString();
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/ExactPhraseScorer.cpp b/3rdparty/clucene/src/CLucene/search/ExactPhraseScorer.cpp
new file mode 100644
index 000000000..1fbf2e99d
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/ExactPhraseScorer.cpp
@@ -0,0 +1,85 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "ExactPhraseScorer.h"
+
+#include "PhraseScorer.h"
+#include "CLucene/index/Terms.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+ ExactPhraseScorer::ExactPhraseScorer(Weight* weight, TermPositions** tps,
+ int32_t* positions, Similarity* similarity, uint8_t* norms):
+ PhraseScorer(weight, tps, positions, similarity, norms){
+ //Func - Constructor
+ //Pre - tps != NULL
+ // tpsLength >= 0
+ // n != NULL
+ //Post - Instance has been created
+
+ CND_PRECONDITION(tps != NULL,"tps is NULL");
+ CND_PRECONDITION(tps[0] != NULL,"tps is NULL");
+ //CND_PRECONDITION(n != NULL,"n is NULL") =this is checked already in PhraseScorer
+
+ }
+
+ qreal ExactPhraseScorer::phraseFreq(){
+ //Func - Returns the freqency of the phrase
+ //Pre - first != NULL
+ // last != NULL
+ // pq != NULL
+ // size of the PhraseQueue pq is 0
+ //Post - The frequency of the phrase has been returned
+
+ CND_PRECONDITION(first != NULL,"first is NULL");
+ CND_PRECONDITION(last != NULL,"last is NULL");
+ CND_PRECONDITION(pq != NULL,"pq is NULL");
+ CND_PRECONDITION(pq->size()==0,"pq is not empty");
+
+ //build pq from list
+
+ //Add the nodes of the list of PhrasePositions and store them
+ //into the PhraseQueue pq so it can used to build
+ //a list of sorted nodes
+ for (PhrasePositions* pp = first; pp != NULL; pp = pp->_next) {
+ //Read the first TermPosition of the current PhrasePositions pp
+ pp->firstPosition();
+ //Store the current PhrasePositions pp into the PhraseQueue pq
+ pq->put(pp);
+ }
+ //pqToList requires that first and last be NULL when it's called.
+ //This is done at the beginning of pqToList()
+ //In this case, the nodes of the linked list are referenced by pq (see
+ //above loop), so we can clear our pointers to the head and tail of the
+ //linked list without fear of leaking the nodes.
+
+ //rebuild list from pq
+ pqToList();
+
+ //Initialize freq at 0
+ int32_t freq = 0;
+
+ //find position with all terms
+ do {
+ //scan forward in first
+ while (first->position < last->position){
+ do{
+ if (!first->nextPosition()){
+ return (qreal)freq;
+ }
+ } while (first->position < last->position);
+ //Make the current first node the last node in the list
+ firstToLast();
+ }
+ //all equal: a match has been found
+ freq++;
+ } while (last->nextPosition());
+
+ return (qreal)freq;
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/ExactPhraseScorer.h b/3rdparty/clucene/src/CLucene/search/ExactPhraseScorer.h
new file mode 100644
index 000000000..d82aa9e9a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/ExactPhraseScorer.h
@@ -0,0 +1,31 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_ExactPhraseScorer_
+#define _lucene_search_ExactPhraseScorer_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "PhraseScorer.h"
+#include "CLucene/index/Terms.h"
+
+CL_NS_DEF(search)
+
+ class ExactPhraseScorer: public PhraseScorer {
+ public:
+ ExactPhraseScorer(Weight* weight, CL_NS(index)::TermPositions** tps, int32_t* positions,
+ Similarity* similarity, uint8_t* norms );
+
+ ~ExactPhraseScorer(){
+ }
+ protected:
+ //Returns the exact freqency of the phrase
+ qreal phraseFreq();
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/Explanation.cpp b/3rdparty/clucene/src/CLucene/search/Explanation.cpp
new file mode 100644
index 000000000..87189b71b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Explanation.cpp
@@ -0,0 +1,133 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "Explanation.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+
+Explanation::Explanation(qreal value, const TCHAR* description) {
+ this->value = value;
+ _tcsncpy(this->description,description,LUCENE_SEARCH_EXPLANATION_DESC_LEN);
+}
+
+Explanation::Explanation() {
+ this->value = 0;
+ this->description[0]=0;
+}
+
+Explanation::Explanation(const Explanation& copy){
+ set(copy);
+}
+void Explanation::set(const Explanation& copy){
+ this->value = copy.value;
+ STRCPY_TtoT(description,copy.description,LUCENE_SEARCH_EXPLANATION_DESC_LEN);
+
+ details.clear();
+ typedef CL_NS(util)::Deletor::Object<Explanation> Deletor;
+ CL_NS(util)::CLArrayList<Explanation*, Deletor>::const_iterator itr;
+ itr = copy.details.begin();
+ while ( itr != copy.details.end() ){
+ details.push_back( (*itr)->clone() );
+ ++itr;
+ }
+}
+
+Explanation::~Explanation(){
+}
+
+void Explanation::setDescription(const TCHAR* description) {
+ _tcsncpy(this->description,description,LUCENE_SEARCH_EXPLANATION_DESC_LEN);
+}
+
+
+Explanation* Explanation::clone() const{
+ return _CLNEW Explanation(*this);
+}
+
+qreal Explanation::getValue() const{
+ return value;
+}
+
+void Explanation::setValue(qreal value) {
+ this->value = value;
+}
+
+const TCHAR* Explanation::getDescription() const {
+ return description;
+}
+
+///todo: mem leaks
+TCHAR* Explanation::toString(int32_t depth) {
+ StringBuffer buffer;
+ for (int32_t i = 0; i < depth; i++) {
+ buffer.append(_T(" "));
+ }
+ buffer.appendFloat(getValue(),2);
+ buffer.append(_T(" = "));
+ buffer.append(getDescription());
+ buffer.append(_T("\n"));
+
+ for ( uint32_t j=0;j<details.size();j++ ){
+ TCHAR* tmp = details[j]->toString(depth+1);
+ buffer.append(tmp);
+ _CLDELETE_CARRAY(tmp);
+ }
+ return buffer.toString();
+}
+
+int Explanation::getDetailsLength(){
+ return details.size();
+}
+Explanation* Explanation::getDetail(int i){
+ return details[i];
+}
+/** The sub-nodes of this explanation node. */
+void Explanation::getDetails(Explanation** ret) {
+ uint32_t size = details.size();
+ for ( uint32_t i=0;i<size;i++ ){
+ ret[i] = details[i]->clone();
+ }
+ ret[size] = NULL;
+}
+
+/** Adds a sub-node to this explanation node. */
+void Explanation::addDetail(Explanation* detail) {
+ details.push_back(detail);
+}
+
+/** Render an explanation as text. */
+TCHAR* Explanation::toString() {
+ return toString(0);
+}
+
+/** Render an explanation as HTML. */
+///todo: mem leaks
+TCHAR* Explanation::toHtml() {
+ StringBuffer buffer;
+ TCHAR* tmp;
+ buffer.append(_T("<ul>\n"));
+
+ buffer.append(_T("<li>"));
+ buffer.appendFloat(getValue(),2);
+ buffer.append(_T(" = "));
+
+ buffer.append(getDescription());
+ buffer.append(_T("</li>\n"));
+
+ for ( uint32_t i=0;i<details.size();i++ ){
+ tmp = details[i]->toHtml();
+ buffer.append(tmp);
+ _CLDELETE_CARRAY(tmp);
+ }
+ buffer.append(_T("</ul>\n"));
+
+ return buffer.toString();
+}
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/Explanation.h b/3rdparty/clucene/src/CLucene/search/Explanation.h
new file mode 100644
index 000000000..7c95822b6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Explanation.h
@@ -0,0 +1,66 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_Explanation
+#define _lucene_search_Explanation
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF(search)
+
+ #define LUCENE_SEARCH_EXPLANATION_DESC_LEN 200
+ class Explanation :LUCENE_BASE {
+ private:
+ qreal value; // the value of this node
+ TCHAR description[LUCENE_SEARCH_EXPLANATION_DESC_LEN]; // what it represents
+ CL_NS(util)::CLArrayList<Explanation*,CL_NS(util)::Deletor::Object<Explanation> > details; // sub-explanations
+
+ TCHAR* toString(int32_t depth);
+ protected:
+ Explanation(const Explanation& copy);
+ public:
+ Explanation();
+ ~Explanation();
+
+ Explanation(qreal value, const TCHAR* description);
+ void set(const Explanation& other);
+
+ Explanation* clone() const;
+
+ /** The value assigned to this explanation node. */
+ qreal getValue() const;
+
+ /** Sets the value assigned to this explanation node. */
+ void setValue(qreal value);
+
+ /** A description of this explanation node. */
+ const TCHAR* getDescription() const; ///<returns reference
+
+ /** Sets the description of this explanation node. */
+ void setDescription(const TCHAR* description);
+
+ /** The sub-nodes of this explanation node.
+ * @param ret this array of Explanations should be getDetailsLength()+1 in size.
+ The array will be null terminated.
+ */
+ void getDetails(Explanation** ret);
+ int getDetailsLength();
+ Explanation* getDetail(int i);
+
+ /** Adds a sub-node to this explanation node. */
+ void addDetail(Explanation* detail);
+
+ /** Render an explanation as text. */
+ TCHAR* toString();
+
+ /** Render an explanation as HTML. */
+ TCHAR* toHtml();
+ };
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/FieldCache.cpp b/3rdparty/clucene/src/CLucene/search/FieldCache.cpp
new file mode 100644
index 000000000..fae672019
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldCache.cpp
@@ -0,0 +1,55 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "FieldCache.h"
+#include "FieldCacheImpl.h"
+
+CL_NS_DEF(search)
+
+FieldCache* FieldCache::DEFAULT = _CLNEW FieldCacheImpl();
+int32_t FieldCache::STRING_INDEX = -1;
+
+FieldCacheAuto::FieldCacheAuto(int32_t len, int32_t type){
+ contentType = type;
+ contentLen = len;
+ ownContents = false;
+
+ intArray=NULL;
+ floatArray=NULL;
+ stringIndex=NULL;
+ stringArray=NULL;
+ comparableArray=NULL;
+ sortComparator=NULL;
+ scoreDocComparator=NULL;
+}
+FieldCacheAuto::~FieldCacheAuto(){
+ if ( contentType == FieldCacheAuto::INT_ARRAY ){
+ _CLDELETE_ARRAY(intArray);
+ }else if ( contentType == FieldCacheAuto::FLOAT_ARRAY ){
+ _CLDELETE_ARRAY(floatArray);
+ }else if ( contentType == FieldCacheAuto::STRING_INDEX ){
+ _CLDELETE(stringIndex);
+ }else if ( contentType == FieldCacheAuto::STRING_ARRAY ){
+ if ( ownContents ){
+ for ( int32_t i=0;i<contentLen;i++ )
+ _CLDELETE_CARRAY(stringArray[i]);
+ }
+ _CLDELETE_ARRAY(stringArray);
+ }else if ( contentType == FieldCacheAuto::COMPARABLE_ARRAY ){
+ if ( ownContents ){
+ for ( int32_t i=0;i<contentLen;i++ )
+ _CLDELETE(comparableArray[i]);
+ }
+ _CLDELETE_ARRAY(comparableArray);
+ }else if ( contentType == FieldCacheAuto::SORT_COMPARATOR ){
+ _CLDELETE(sortComparator);
+ }else if ( contentType == FieldCacheAuto::SCOREDOC_COMPARATOR ){
+ _CLDELETE(scoreDocComparator);
+ }
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/FieldCache.h b/3rdparty/clucene/src/CLucene/search/FieldCache.h
new file mode 100644
index 000000000..eeec26f33
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldCache.h
@@ -0,0 +1,182 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_FieldCache_
+#define _lucene_search_FieldCache_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/IndexReader.h"
+#include "Sort.h"
+
+
+CL_NS_DEF(search)
+
+class FieldCacheAuto; //predefine
+
+/**
+ * Expert: Maintains caches of term values.
+ *
+ */
+class FieldCache :LUCENE_BASE {
+public:
+ virtual ~FieldCache(){
+ }
+
+ /** Expert: Stores term text values and document ordering data. */
+ class StringIndex:LUCENE_BASE {
+ public:
+ /** All the term values, in natural order. */
+ TCHAR** lookup;
+
+ /** For each document, an index into the lookup array. */
+ int32_t* order;
+
+ int count;
+
+ /** Creates one of these objects
+ Consumes all memory given.
+ */
+ StringIndex (int32_t* values, TCHAR** lookup, int count) {
+ this->count = count;
+ this->order = values;
+ this->lookup = lookup;
+ }
+
+ ~StringIndex(){
+ _CLDELETE_ARRAY(order);
+
+ for ( int i=0;i<count;i++ )
+ _CLDELETE_CARRAY(lookup[i]);
+ _CLDELETE_ARRAY(lookup);
+ }
+ };
+
+
+ /** Indicator for FieldCache::StringIndex values in the cache.
+ NOTE: the value assigned to this constant must not be
+ the same as any of those in SortField!!
+ */
+ static int32_t STRING_INDEX;
+
+ /** Expert: The cache used internally by sorting and range query classes. */
+ static FieldCache* DEFAULT;
+
+ /** Checks the internal cache for an appropriate entry, and if none is
+ * found, reads the terms in <code>field</code> as integers and returns an array
+ * of size <code>reader.maxDoc()</code> of the value each document
+ * has in the given field.
+ * @param reader Used to get field values.
+ * @param field Which field contains the integers.
+ * @return The values in the given field for each document.
+ * @throws IOException If any error occurs.
+ */
+ virtual FieldCacheAuto* getInts (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0;
+
+ /** Checks the internal cache for an appropriate entry, and if
+ * none is found, reads the terms in <code>field</code> as floats and returns an array
+ * of size <code>reader.maxDoc()</code> of the value each document
+ * has in the given field.
+ * @param reader Used to get field values.
+ * @param field Which field contains the floats.
+ * @return The values in the given field for each document.
+ * @throws IOException If any error occurs.
+ */
+ virtual FieldCacheAuto* getFloats (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0;
+
+ /** Checks the internal cache for an appropriate entry, and if none
+ * is found, reads the term values in <code>field</code> and returns an array
+ * of size <code>reader.maxDoc()</code> containing the value each document
+ * has in the given field.
+ * @param reader Used to get field values.
+ * @param field Which field contains the strings.
+ * @return The values in the given field for each document.
+ * @throws IOException If any error occurs.
+ */
+ virtual FieldCacheAuto* getStrings (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0;
+
+ /** Checks the internal cache for an appropriate entry, and if none
+ * is found reads the term values in <code>field</code> and returns
+ * an array of them in natural order, along with an array telling
+ * which element in the term array each document uses.
+ * @param reader Used to get field values.
+ * @param field Which field contains the strings.
+ * @return Array of terms and index into the array for each document.
+ * @throws IOException If any error occurs.
+ */
+ virtual FieldCacheAuto* getStringIndex (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0;
+
+ /** Checks the internal cache for an appropriate entry, and if
+ * none is found reads <code>field</code> to see if it contains integers, floats
+ * or strings, and then calls one of the other methods in this class to get the
+ * values. For string values, a FieldCache::StringIndex is returned. After
+ * calling this method, there is an entry in the cache for both
+ * type <code>AUTO</code> and the actual found type.
+ * @param reader Used to get field values.
+ * @param field Which field contains the values.
+ * @return int32_t[], qreal[] or FieldCache::StringIndex.
+ * @throws IOException If any error occurs.
+ */
+ virtual FieldCacheAuto* getAuto (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0;
+
+ /** Checks the internal cache for an appropriate entry, and if none
+ * is found reads the terms out of <code>field</code> and calls the given SortComparator
+ * to get the sort values. A hit in the cache will happen if <code>reader</code>,
+ * <code>field</code>, and <code>comparator</code> are the same (using <code>equals()</code>)
+ * as a previous call to this method.
+ * @param reader Used to get field values.
+ * @param field Which field contains the values.
+ * @param comparator Used to convert terms into something to sort by.
+ * @return Array of sort objects, one for each document.
+ * @throws IOException If any error occurs.
+ */
+ virtual FieldCacheAuto* getCustom (CL_NS(index)::IndexReader* reader, const TCHAR* field, SortComparator* comparator) = 0;
+};
+
+/** A class holding an AUTO field. In java lucene an Object
+ is used, but we use this.
+ contentType:
+ 1 - integer array
+ 2 - float array
+ 3 - FieldCache::StringIndex object
+ This class is also used when returning getInt, getFloat, etc
+ because we have no way of returning the size of the array and this
+ class can be used to determine the array size
+*/
+class FieldCacheAuto:LUCENE_BASE{
+public:
+ enum{
+ INT_ARRAY=1,
+ FLOAT_ARRAY=2,
+ STRING_INDEX=3,
+ STRING_ARRAY=4,
+ COMPARABLE_ARRAY=5,
+ SORT_COMPARATOR=6,
+ SCOREDOC_COMPARATOR=7
+ };
+
+ FieldCacheAuto(int32_t len, int32_t type);
+ ~FieldCacheAuto();
+ ///if contents should be deleted too, depending on type
+ bool ownContents;
+ int32_t contentLen; //number of items in the list
+ uint8_t contentType;
+ int32_t* intArray; //item 1
+ qreal* floatArray; //item 2
+ FieldCache::StringIndex* stringIndex; //item 3
+ TCHAR** stringArray; //item 4
+ CL_NS(util)::Comparable** comparableArray; //item 5
+ SortComparator* sortComparator; //item 6
+ ScoreDocComparator* scoreDocComparator; //item 7
+
+};
+
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/FieldCacheImpl.cpp b/3rdparty/clucene/src/CLucene/search/FieldCacheImpl.cpp
new file mode 100644
index 000000000..62052097e
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldCacheImpl.cpp
@@ -0,0 +1,529 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "FieldCacheImpl.h"
+
+CL_NS_USE(util)
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+FieldCacheImpl::FieldCacheImpl():
+ cache(false,true){
+}
+FieldCacheImpl::~FieldCacheImpl(){
+ cache.clear();
+}
+
+FieldCacheImpl::FileEntry::FileEntry (const TCHAR* field, int32_t type) {
+ this->field = CLStringIntern::intern(field CL_FILELINE);
+ this->type = type;
+ this->custom = NULL;
+ this->_hashCode = 0;
+ }
+
+ /** Creates one of these objects for a custom comparator. */
+ FieldCacheImpl::FileEntry::FileEntry (const TCHAR* field, SortComparatorSource* custom) {
+ this->field = CLStringIntern::intern(field CL_FILELINE);
+ this->type = SortField::CUSTOM;
+ this->custom = custom;
+ this->_hashCode = 0;
+ }
+ FieldCacheImpl::FileEntry::~FileEntry(){
+ CLStringIntern::unintern(field);
+ }
+
+ size_t FieldCacheImpl::FileEntry::hashCode(){
+ if ( _hashCode == 0 ){
+ //todo: cache hashcode?
+ size_t ret = Misc::thashCode(field);
+ if ( custom != NULL )
+ ret = ret ^ custom->hashCode();
+ ret = ret ^ (type*7); //type with a seed
+ _hashCode = ret;
+ }
+ return _hashCode;
+ }
+ int32_t FieldCacheImpl::FileEntry::compareTo(const FieldCacheImpl::FileEntry* other) const{
+ if ( other->field == this->field ){
+ if ( other->type == this->type ){
+ if ( other->custom == NULL ){
+ if ( this->custom == NULL )
+ return 0; //both null
+ else
+ return 1;
+ }else if ( this->custom == NULL )
+ return -1;
+ else if ( other->custom < this->custom )
+ return -1;
+ else if ( other->custom > this->custom )
+ return 1;
+ else
+ return 0;
+ }else if ( other->type > this->type )
+ return 1;
+ else
+ return -1;
+
+ }else
+ return _tcscmp(other->field,this->field);
+ }
+
+ /** Two of these are equal iff they reference the same field and type. */
+ /*bool FieldCacheImpl::FileEntry::equals (FileEntry* other) {
+ if (other->field == field && other->type == type) {
+ if (other->custom == NULL) {
+ if (custom == NULL)
+ return true;
+ } else if (other->custom->equals (custom)) {
+ return true;
+ }
+ }
+ }*/
+
+ /** Composes a hashcode based on the field and type. */
+ /*size_t FieldCacheImpl::FileEntry::hashCode() {
+ return field->hashCode() ^ type ^ (custom==NULL ? 0 : custom->hashCode());
+ }*/
+
+
+
+
+
+ /** See if an object is in the cache. */
+ FieldCacheAuto* FieldCacheImpl::lookup (IndexReader* reader, const TCHAR* field, int32_t type) {
+ FieldCacheAuto* ret = NULL;
+ FileEntry* entry = _CLNEW FileEntry (field, type);
+ {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ fieldcacheCacheReaderType* readerCache = cache.get(reader);
+ if (readerCache != NULL)
+ ret = readerCache->get (entry);
+ _CLDELETE(entry);
+ }
+ return ret;
+ }
+
+
+ /** See if a custom object is in the cache. */
+ FieldCacheAuto* FieldCacheImpl::lookup (IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer) {
+ FieldCacheAuto* ret = NULL;
+ FileEntry* entry = _CLNEW FileEntry (field, comparer);
+ {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ fieldcacheCacheReaderType* readerCache = cache.get(reader);
+ if (readerCache != NULL)
+ ret = readerCache->get (entry);
+ _CLDELETE(entry);
+}
+ return ret;
+ }
+
+ void FieldCacheImpl::closeCallback(CL_NS(index)::IndexReader* reader, void* fieldCacheImpl){
+ FieldCacheImpl* fci = (FieldCacheImpl*)fieldCacheImpl;
+ SCOPED_LOCK_MUTEX(fci->THIS_LOCK)
+ fci->cache.remove(reader);
+ }
+
+ /** Put an object into the cache. */
+ void FieldCacheImpl::store (IndexReader* reader, const TCHAR* field, int32_t type, FieldCacheAuto* value) {
+ FileEntry* entry = _CLNEW FileEntry (field, type);
+ {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ fieldcacheCacheReaderType* readerCache = cache.get(reader);
+ if (readerCache == NULL) {
+ readerCache = _CLNEW fieldcacheCacheReaderType;
+ cache.put(reader,readerCache);
+ reader->addCloseCallback(closeCallback, this);
+ }
+ readerCache->put (entry, value);
+ //this is supposed to return the previous value, but it needs to be deleted!!!
+ }
+ }
+
+ /** Put a custom object into the cache. */
+ void FieldCacheImpl::store (IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer, FieldCacheAuto* value) {
+ FileEntry* entry = _CLNEW FileEntry (field, comparer);
+ {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ fieldcacheCacheReaderType* readerCache = cache.get(reader);
+ if (readerCache == NULL) {
+ readerCache = _CLNEW fieldcacheCacheReaderType;
+ cache.put(reader, readerCache);
+ reader->addCloseCallback(FieldCacheImpl::closeCallback, this);
+ }
+ readerCache->put(entry, value);
+ //this is supposed to return the previous value, but it needs to be deleted!!!
+ }
+ }
+
+
+
+
+
+ // inherit javadocs
+ FieldCacheAuto* FieldCacheImpl::getInts (IndexReader* reader, const TCHAR* field) {
+ field = CLStringIntern::intern(field CL_FILELINE);
+ FieldCacheAuto* ret = lookup (reader, field, SortField::INT);
+ if (ret == NULL) {
+ int32_t retLen = reader->maxDoc();
+ int32_t* retArray = _CL_NEWARRAY(int32_t,retLen);
+ memset(retArray,0,sizeof(int32_t)*retLen);
+ if (retLen > 0) {
+ TermDocs* termDocs = reader->termDocs();
+
+ Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false);
+ TermEnum* termEnum = reader->terms (term);
+ _CLDECDELETE(term);
+ try {
+ if (termEnum->term(false) == NULL) {
+ _CLTHROWA(CL_ERR_Runtime,"no terms in field"); //todo: add detailed error: + field);
+ }
+ do {
+ Term* term = termEnum->term(false);
+ if (term->field() != field)
+ break;
+
+ TCHAR* end;
+ int32_t termval = (int32_t)_tcstoi64(term->text(), &end, 10);
+ termDocs->seek (termEnum);
+ while (termDocs->next()) {
+ retArray[termDocs->doc()] = termval;
+ }
+ } while (termEnum->next());
+ } _CLFINALLY(
+ termDocs->close();
+ _CLDELETE(termDocs);
+ termEnum->close();
+ _CLDELETE(termEnum);
+ )
+ }
+
+ FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::INT_ARRAY);
+ fa->intArray = retArray;
+
+ store (reader, field, SortField::INT, fa);
+ CLStringIntern::unintern(field);
+ return fa;
+ }
+ CLStringIntern::unintern(field);
+ return ret;
+ }
+
+ // inherit javadocs
+ FieldCacheAuto* FieldCacheImpl::getFloats (IndexReader* reader, const TCHAR* field){
+ field = CLStringIntern::intern(field CL_FILELINE);
+ FieldCacheAuto* ret = lookup (reader, field, SortField::FLOAT);
+ if (ret == NULL) {
+ int32_t retLen = reader->maxDoc();
+ qreal* retArray = _CL_NEWARRAY(qreal,retLen);
+ memset(retArray,0,sizeof(qreal)*retLen);
+ if (retLen > 0) {
+ TermDocs* termDocs = reader->termDocs();
+
+ Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false);
+ TermEnum* termEnum = reader->terms (term);
+ _CLDECDELETE(term);
+
+ try {
+ if (termEnum->term(false) == NULL) {
+ _CLTHROWA(CL_ERR_Runtime,"no terms in field "); //todo: make richer error + field);
+ }
+ do {
+ Term* term = termEnum->term(false);
+ if (term->field() != field)
+ break;
+
+ TCHAR* tmp;
+ qreal termval = _tcstod(term->text(),&tmp);
+ termDocs->seek (termEnum);
+ while (termDocs->next()) {
+ retArray[termDocs->doc()] = termval;
+ }
+ } while (termEnum->next());
+ } _CLFINALLY(
+ termDocs->close();
+ _CLDELETE(termDocs);
+ termEnum->close();
+ _CLDELETE(termEnum);
+ )
+ }
+
+ FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::FLOAT_ARRAY);
+ fa->floatArray = retArray;
+
+ store (reader, field, SortField::FLOAT, fa);
+ CLStringIntern::unintern(field);
+ return fa;
+ }
+ CLStringIntern::unintern(field);
+ return ret;
+ }
+
+
+ // inherit javadocs
+ FieldCacheAuto* FieldCacheImpl::getStrings (IndexReader* reader, const TCHAR* field){
+ //todo: this is not really used, i think?
+ field = CLStringIntern::intern(field CL_FILELINE);
+ FieldCacheAuto* ret = lookup (reader, field, SortField::STRING);
+ if (ret == NULL) {
+ int32_t retLen = reader->maxDoc();
+ TCHAR** retArray = _CL_NEWARRAY(TCHAR*,retLen+1);
+ memset(retArray,0,sizeof(TCHAR*)*(retLen+1));
+ if (retLen > 0) {
+ TermDocs* termDocs = reader->termDocs();
+
+ Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false);
+ TermEnum* termEnum = reader->terms (term);
+ _CLDECDELETE(term);
+
+ try {
+ if (termEnum->term(false) == NULL) {
+ _CLTHROWA(CL_ERR_Runtime,"no terms in field "); //todo: extend to + field);
+ }
+ do {
+ Term* term = termEnum->term(false);
+ if (term->field() != field)
+ break;
+ const TCHAR* termval = term->text();
+ termDocs->seek (termEnum);
+ while (termDocs->next()) {
+ retArray[termDocs->doc()] = STRDUP_TtoT(termval); //todo: any better way of doing this???
+ }
+ } while (termEnum->next());
+ } _CLFINALLY(
+ retArray[retLen]=NULL;
+ termDocs->close();
+ _CLDELETE(termDocs);
+ termEnum->close();
+ _CLDELETE(termEnum);
+ )
+ }
+
+
+ FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::STRING_ARRAY);
+ fa->stringArray = retArray;
+ fa->ownContents=true;
+ store (reader, field, SortField::STRING, fa);
+ CLStringIntern::unintern(field);
+ return fa;
+ }
+ CLStringIntern::unintern(field);
+ return ret;
+ }
+
+ // inherit javadocs
+ FieldCacheAuto* FieldCacheImpl::getStringIndex (IndexReader* reader, const TCHAR* field){
+ field = CLStringIntern::intern(field CL_FILELINE);
+ FieldCacheAuto* ret = lookup (reader, field, STRING_INDEX);
+ int32_t t = 0; // current term number
+ if (ret == NULL) {
+ int32_t retLen = reader->maxDoc();
+ int32_t* retArray = _CL_NEWARRAY(int32_t,retLen);
+ memset(retArray,0,sizeof(int32_t)*retLen);
+
+ TCHAR** mterms = _CL_NEWARRAY(TCHAR*,retLen+2);
+ mterms[0]=NULL;
+ if ( retLen > 0 ) {
+ TermDocs* termDocs = reader->termDocs();
+
+ Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false);
+ TermEnum* termEnum = reader->terms (term);
+ _CLDECDELETE(term);
+
+
+ CND_PRECONDITION(t+1 <= retLen, "t out of bounds");
+
+ // an entry for documents that have no terms in this field
+ // should a document with no terms be at top or bottom?
+ // this puts them at the top - if it is changed, FieldDocSortedHitQueue
+ // needs to change as well.
+ mterms[t++] = NULL;
+
+ try {
+ if (termEnum->term(false) == NULL) {
+ _CLTHROWA(CL_ERR_Runtime,"no terms in field"); //todo: make rich message " + field);
+ }
+ do {
+ Term* term = termEnum->term(false);
+ if (term->field() != field)
+ break;
+
+ // store term text
+ // we expect that there is at most one term per document
+ if (t >= retLen+1)
+ _CLTHROWA(CL_ERR_Runtime,"there are more terms than documents in field"); //todo: rich error \"" + field + "\"");
+ mterms[t] = STRDUP_TtoT(term->text());
+
+ termDocs->seek (termEnum);
+ while (termDocs->next()) {
+ retArray[termDocs->doc()] = t;
+ }
+
+ t++;
+ } while (termEnum->next());
+ CND_PRECONDITION(t<retLen+2,"t out of bounds");
+ mterms[t] = NULL;
+ } _CLFINALLY(
+ termDocs->close();
+ _CLDELETE(termDocs);
+ termEnum->close();
+ _CLDELETE(termEnum);
+ );
+
+ if (t == 0) {
+ // if there are no terms, make the term array
+ // have a single NULL entry
+ _CLDELETE_ARRAY(mterms);
+ mterms = _CL_NEWARRAY(TCHAR*,1); //todo: delete old mterms?
+ mterms[0]=NULL;
+ } else if (t < retLen) { //todo: check, was mterms.length
+ // if there are less terms than documents,
+ // trim off the dead array space
+ //const TCHAR** terms = _CL_NEWARRAY(TCHAR,t);
+ //System.arraycopy (mterms, 0, terms, 0, t);
+ //mterms = terms;
+
+ //we simply shorten the length of the array...
+
+ }
+ }
+ FieldCache::StringIndex* value = _CLNEW FieldCache::StringIndex (retArray, mterms,t);
+
+ FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::STRING_INDEX);
+ fa->stringIndex = value;
+ fa->ownContents=true;
+ store (reader, field, STRING_INDEX, fa);
+ CLStringIntern::unintern(field);
+ return fa;
+ }
+ CLStringIntern::unintern(field);
+ return ret;
+ }
+
+ // inherit javadocs
+ FieldCacheAuto* FieldCacheImpl::getAuto (IndexReader* reader, const TCHAR* field) {
+ field = CLStringIntern::intern(field CL_FILELINE);
+ FieldCacheAuto* ret = lookup (reader, field, SortField::AUTO);
+ if (ret == NULL) {
+ Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false);
+ TermEnum* enumerator = reader->terms (term);
+ _CLDECDELETE(term);
+
+ try {
+ Term* term = enumerator->term(false);
+ if (term == NULL) {
+ _CLTHROWA(CL_ERR_Runtime,"no terms in field - cannot determine sort type"); //todo: make rich error: " + field + "
+ }
+ if (term->field() == field) {
+ const TCHAR* termtext = term->text();
+ size_t termTextLen = term->textLength();
+
+ bool isint=true;
+ for ( size_t i=0;i<termTextLen;i++ ){
+ if ( _tcschr(_T("0123456789 +-"),termtext[i]) == NULL ){
+ isint = false;
+ break;
+ }
+ }
+ if ( isint )
+ ret = getInts (reader, field);
+ else{
+ bool isfloat=true;
+
+ int32_t searchLen = termTextLen;
+ if ( termtext[termTextLen-1] == 'f' )
+ searchLen--;
+ for ( int32_t i=0;i<searchLen;i++ ){
+ if ( _tcschr(_T("0123456789 Ee.+-"),termtext[i]) == NULL ){
+ isfloat = false;
+ break;
+ }
+ }
+ if ( isfloat )
+ ret = getFloats (reader, field);
+ else{
+ ret = getStringIndex (reader, field);
+ }
+ }
+
+ if (ret != NULL) {
+ store (reader, field, SortField::AUTO, ret);
+ }
+ } else {
+ _CLTHROWA (CL_ERR_Runtime,"field does not appear to be indexed"); //todo: make rich error: \"" + field + "\"
+ }
+ } _CLFINALLY( enumerator->close(); _CLDELETE(enumerator) );
+
+ }
+ CLStringIntern::unintern(field);
+ return ret;
+ }
+
+
+ // inherit javadocs
+ FieldCacheAuto* FieldCacheImpl::getCustom (IndexReader* reader, const TCHAR* field, SortComparator* comparator){
+ field = CLStringIntern::intern(field CL_FILELINE);
+
+ FieldCacheAuto* ret = lookup (reader, field, comparator);
+ if (ret == NULL) {
+ int32_t retLen = reader->maxDoc();
+ Comparable** retArray = _CL_NEWARRAY(Comparable*,retLen);
+ memset(retArray,0,sizeof(Comparable*)*retLen);
+ if (retLen > 0) {
+ TermDocs* termDocs = reader->termDocs();
+ TermEnum* termEnum = reader->terms ();
+
+ try {
+ if (termEnum->term(false) == NULL) {
+ _CLTHROWA(CL_ERR_Runtime,"no terms in field "); //todo: make rich error + field);
+ }
+ do {
+ Term* term = termEnum->term(false);
+ if (term->field() != field)
+ break;
+ Comparable* termval = comparator->getComparable (term->text());
+ termDocs->seek (termEnum);
+ while (termDocs->next()) {
+ retArray[termDocs->doc()] = termval;
+ }
+ } while (termEnum->next());
+ } _CLFINALLY (
+ termDocs->close();
+ _CLDELETE(termDocs);
+ termEnum->close();
+ _CLDELETE(termEnum);
+ );
+ }
+
+ FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::COMPARABLE_ARRAY);
+ fa->comparableArray = retArray;
+ fa->ownContents=true;
+ store (reader, field, SortField::CUSTOM, fa);
+ CLStringIntern::unintern(field);
+ return fa;
+ }
+ CLStringIntern::unintern(field);
+ return ret;
+ }
+
+
+ FieldCacheImpl::fieldcacheCacheReaderType::fieldcacheCacheReaderType(){
+ setDeleteKey(false);
+ setDeleteValue(false);
+ }
+ FieldCacheImpl::fieldcacheCacheReaderType::~fieldcacheCacheReaderType(){
+ iterator itr = begin();
+ while ( itr != end() ){
+ FileEntry* f = itr->first;
+ if ( f->getType() != SortField::AUTO )
+ _CLDELETE( itr->second );
+ _CLDELETE( f );
+ ++itr;
+ }
+ clear();
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/FieldCacheImpl.h b/3rdparty/clucene/src/CLucene/search/FieldCacheImpl.h
new file mode 100644
index 000000000..ac3c4cabc
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldCacheImpl.h
@@ -0,0 +1,144 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_FieldCacheImpl_
+#define _lucene_search_FieldCacheImpl_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/IndexReader.h"
+#include "FieldCache.h"
+#include "Sort.h"
+
+
+CL_NS_DEF(search)
+
+
+/**
+ * Expert: The default cache implementation, storing all values in memory.
+ *
+ */
+class FieldCacheImpl: public FieldCache {
+public:
+ DEFINE_MUTEX(THIS_LOCK)
+
+ /** Expert: Every key in the internal cache is of this type. */
+ class FileEntry:LUCENE_BASE {
+ const TCHAR* field; // which Field
+ int32_t type; // which SortField type
+ SortComparatorSource* custom; // which custom comparator
+ size_t _hashCode;
+ public:
+ /** Creates one of these objects. */
+ FileEntry (const TCHAR* field, int32_t type);
+
+ /** Creates one of these objects for a custom comparator. */
+ FileEntry (const TCHAR* field, SortComparatorSource* custom);
+ ~FileEntry();
+
+ int32_t getType() const{ return type; }
+
+ /** Two of these are equal iff they reference the same field and type. */
+ bool equals (FileEntry* other) const;
+
+ /** Composes a hashcode based on the field and type. */
+ size_t hashCode();
+
+ int32_t compareTo(const FileEntry* other) const;
+
+ class Compare:LUCENE_BASE, public CL_NS(util)::Compare::_base //<Term*>
+ {
+ public:
+ bool operator()( FileEntry* f1, FileEntry* f2 ) const{
+ return ( f1->compareTo(f2) < 0 );
+ }
+ size_t operator()( FileEntry* t ) const{
+ return t->hashCode();
+ }
+ };
+ class Equals:LUCENE_BASE, public CL_NS(util)::Compare::_base //<Term*>
+ {
+ public:
+ bool operator()( FileEntry* f1, FileEntry* f2 ) const{
+ return ( f1->compareTo(f2) == 0 );
+ }
+ };
+ };
+
+ FieldCacheImpl();
+ ~FieldCacheImpl();
+private:
+
+ ///the type that is stored in the field cache. can't use a typedef because
+ ///the decorated name would become too long
+ class fieldcacheCacheReaderType: public CL_NS(util)::CLHashMap<FileEntry*,
+ FieldCacheAuto*,
+ FileEntry::Compare,
+ FileEntry::Equals,
+ CL_NS(util)::Deletor::Object<FileEntry>,
+ CL_NS(util)::Deletor::Object<FieldCacheAuto> >{
+ public:
+ fieldcacheCacheReaderType();
+ ~fieldcacheCacheReaderType();
+ };
+
+ //note: typename gets too long if using cacheReaderType as a typename
+ typedef CL_NS(util)::CLHashMap<CL_NS(index)::IndexReader*,
+ fieldcacheCacheReaderType*,
+ CL_NS(util)::Compare::Void<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Equals::Void<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Deletor::Object<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Deletor::Object<fieldcacheCacheReaderType> > fieldcacheCacheType;
+
+ /** The internal cache. Maps FileEntry to array of interpreted term values. **/
+ //todo: make indexreader remove itself from here when the reader is shut
+ fieldcacheCacheType cache;
+
+ /** See if an object is in the cache. */
+ FieldCacheAuto* lookup (CL_NS(index)::IndexReader* reader, const TCHAR* field, int32_t type) ;
+
+ /** See if a custom object is in the cache. */
+ FieldCacheAuto* lookup (CL_NS(index)::IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer);
+
+ /** Put an object into the cache. */
+ void store (CL_NS(index)::IndexReader* reader, const TCHAR* field, int32_t type, FieldCacheAuto* value);
+
+ /** Put a custom object into the cache. */
+ void store (CL_NS(index)::IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer, FieldCacheAuto* value);
+
+public:
+
+ // inherit javadocs
+ FieldCacheAuto* getInts (CL_NS(index)::IndexReader* reader, const TCHAR* field);
+
+ // inherit javadocs
+ FieldCacheAuto* getFloats (CL_NS(index)::IndexReader* reader, const TCHAR* field);
+
+ // inherit javadocs
+ FieldCacheAuto* getStrings (CL_NS(index)::IndexReader* reader, const TCHAR* field);
+
+ // inherit javadocs
+ FieldCacheAuto* getStringIndex (CL_NS(index)::IndexReader* reader, const TCHAR* field);
+
+ // inherit javadocs
+ FieldCacheAuto* getAuto (CL_NS(index)::IndexReader* reader, const TCHAR* field);
+
+ // inherit javadocs
+ FieldCacheAuto* getCustom (CL_NS(index)::IndexReader* reader, const TCHAR* field, SortComparator* comparator);
+
+
+ /**
+ * Callback for when IndexReader closes. This causes
+ * any cache to be removed for the specified reader.
+ */
+ static void closeCallback(CL_NS(index)::IndexReader* reader, void* fieldCacheImpl);
+};
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/FieldDoc.h b/3rdparty/clucene/src/CLucene/search/FieldDoc.h
new file mode 100644
index 000000000..6ce915acf
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldDoc.h
@@ -0,0 +1,70 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_FieldDoc_
+#define _lucene_search_FieldDoc_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "ScoreDoc.h"
+
+CL_NS_DEF(search)
+
+/**
+ * Expert: A ScoreDoc which also contains information about
+ * how to sort the referenced document. In addition to the
+ * document number and score, this object contains an array
+ * of values for the document from the field(s) used to sort.
+ * For example, if the sort criteria was to sort by fields
+ * "a", "b" then "c", the <code>fields</code> object array
+ * will have three elements, corresponding respectively to
+ * the term values for the document in fields "a", "b" and "c".
+ * The class of each element in the array will be either
+ * Integer, Float or String depending on the type of values
+ * in the terms of each field.
+ *
+ * @see ScoreDoc
+ * @see TopFieldDocs
+ */
+class FieldDoc: public ScoreDoc {
+public:
+
+ /** Expert: The values which are used to sort the referenced document.
+ * The order of these will match the original sort criteria given by a
+ * Sort object. Each Object will be either an Integer, Float or String,
+ * depending on the type of values in the terms of the original field.
+ * @see Sort
+ * @see Searchable#search(Query,Filter,int32_t,Sort)
+ */
+ CL_NS(util)::Comparable** fields;
+
+ /** Expert: Creates one of these objects with empty sort information. */
+ FieldDoc (int32_t doc, qreal score):
+ ScoreDoc(doc,score) {
+ fields=NULL;
+ }
+
+ /** Expert: Creates one of these objects with the given sort information. */
+ FieldDoc (int32_t doc, qreal score, CL_NS(util)::Comparable** fields):
+ ScoreDoc(doc,score)
+ {
+ this->fields = fields;
+ }
+
+ ~FieldDoc(){
+ if ( fields != NULL ){
+ for ( int i=0;fields[i]!=NULL;i++ )
+ _CLDELETE(fields[i]);
+ _CLDELETE_ARRAY(fields);
+ }
+ }
+};
+
+CL_NS_END
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/search/FieldDocSortedHitQueue.cpp b/3rdparty/clucene/src/CLucene/search/FieldDocSortedHitQueue.cpp
new file mode 100644
index 000000000..0a5210903
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldDocSortedHitQueue.cpp
@@ -0,0 +1,171 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "FieldDocSortedHitQueue.h"
+
+
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+
+FieldDoc::FieldDoc (int32_t doc, qreal score)
+{
+ this->scoreDoc.doc = doc;
+ this->scoreDoc.score = score;
+ fields=NULL;
+}
+
+FieldDoc::FieldDoc (int32_t doc, qreal score, CL_NS(util)::Comparable** fields)
+{
+ this->scoreDoc.doc = doc;
+ this->scoreDoc.score = score;
+ this->fields = fields;
+}
+
+FieldDoc::~FieldDoc(){
+ if ( fields != NULL ){
+ for ( int i=0;fields[i]!=NULL;i++ )
+ _CLDELETE(fields[i]);
+ _CLDELETE_ARRAY(fields);
+ }
+}
+
+
+
+FieldDocSortedHitQueue::FieldDocSortedHitQueue (SortField** fields, int32_t size) {
+ this->fields = fields;
+ _countsize();
+ //this->collators = hasCollators (fields);
+ initialize (size,true);
+}
+
+bool FieldDocSortedHitQueue::lessThan (FieldDoc* docA, FieldDoc* docB) {
+ int32_t n = fieldsLen;
+ int32_t c = 0;
+ qreal f1,f2,r1,r2;
+ int32_t i1,i2;
+ const TCHAR *s1, *s2;
+
+ for (int32_t i=0; i<n && c==0; ++i) {
+ int32_t type = fields[i]->getType();
+ if (fields[i]->getReverse()) {
+ switch (type) {
+ case SortField::DOCSCORE:
+ r1 = __REINTERPRET_CAST(Compare::Float*, docA->fields[i])->getValue();
+ r2 = __REINTERPRET_CAST(Compare::Float*, docB->fields[i])->getValue();
+ if (r1 < r2) c = -1;
+ if (r1 > r2) c = 1;
+ break;
+ case SortField::DOC:
+ case SortField::INT:
+ i1 = __REINTERPRET_CAST(Compare::Int32*, docA->fields[i])->getValue();
+ i2 = __REINTERPRET_CAST(Compare::Int32*, docB->fields[i])->getValue();
+ if (i1 > i2) c = -1;
+ if (i1 < i2) c = 1;
+ break;
+ case SortField::STRING:
+ s1 = __REINTERPRET_CAST(Compare::TChar*, docA->fields[i])->getValue();
+ s2 = __REINTERPRET_CAST(Compare::TChar*, docB->fields[i])->getValue();
+ if (s2 == NULL) c = -1; // could be NULL if there are
+ else if (s1 == NULL) c = 1; // no terms in the given field
+ else c = _tcscmp(s2,s1); //else if (fields[i].getLocale() == NULL) {
+
+ /*todo: collators not impl
+ } else {
+ c = collators[i].compare (s2, s1);
+ }*/
+ break;
+ case SortField::FLOAT:
+ f1 = __REINTERPRET_CAST(Compare::Float*, docA->fields[i])->getValue();
+ f2 = __REINTERPRET_CAST(Compare::Float*, docB->fields[i])->getValue();
+ if (f1 > f2) c = -1;
+ if (f1 < f2) c = 1;
+ break;
+ case SortField::CUSTOM:
+ c = docB->fields[i]->compareTo (docA->fields[i]);
+ break;
+ case SortField::AUTO:
+ // we cannot handle this - even if we determine the type of object (qreal or
+ // Integer), we don't necessarily know how to compare them (both SCORE and
+ // qreal both contain floats, but are sorted opposite of each other). Before
+ // we get here, each AUTO should have been replaced with its actual value.
+ _CLTHROWA (CL_ERR_Runtime,"FieldDocSortedHitQueue cannot use an AUTO SortField");
+ default:
+ _CLTHROWA (CL_ERR_Runtime, "invalid SortField type"); //todo: rich error... : "+type);
+ }
+ } else {
+ switch (type) {
+ case SortField::DOCSCORE:
+ r1 = __REINTERPRET_CAST(Compare::Float*, docA->fields[i])->getValue();
+ r2 = __REINTERPRET_CAST(Compare::Float*, docB->fields[i])->getValue();
+ if (r1 > r2) c = -1;
+ if (r1 < r2) c = 1;
+ break;
+ case SortField::DOC:
+ case SortField::INT:
+ i1 = __REINTERPRET_CAST(Compare::Int32*, docA->fields[i])->getValue();
+ i2 = __REINTERPRET_CAST(Compare::Int32*, docB->fields[i])->getValue();
+ if (i1 < i2) c = -1;
+ if (i1 > i2) c = 1;
+ break;
+ case SortField::STRING:
+ s1 = __REINTERPRET_CAST(Compare::TChar*, docA->fields[i])->getValue();
+ s2 = __REINTERPRET_CAST(Compare::TChar*, docB->fields[i])->getValue();
+ // NULL values need to be sorted first, because of how FieldCache.getStringIndex()
+ // works - in that routine, any documents without a value in the given field are
+ // put first.
+ if (s1 == NULL) c = -1; // could be NULL if there are
+ else if (s2 == NULL) c = 1; // no terms in the given field
+ else c = _tcscmp(s1,s2); //else if (fields[i].getLocale() == NULL) {
+
+ /* todo: collators not implemented } else {
+ c = collators[i].compare (s1, s2);
+ }*/
+ break;
+ case SortField::FLOAT:
+ f1 = __REINTERPRET_CAST(Compare::Float*, docA->fields[i])->getValue();
+ f2 = __REINTERPRET_CAST(Compare::Float*, docB->fields[i])->getValue();
+ if (f1 < f2) c = -1;
+ if (f1 > f2) c = 1;
+ break;
+ case SortField::CUSTOM:
+ c = docA->fields[i]->compareTo (docB->fields[i]);
+ break;
+ case SortField::AUTO:
+ // we cannot handle this - even if we determine the type of object (qreal or
+ // Integer), we don't necessarily know how to compare them (both SCORE and
+ // qreal both contain floats, but are sorted opposite of each other). Before
+ // we get here, each AUTO should have been replaced with its actual value.
+ _CLTHROWA (CL_ERR_Runtime,"FieldDocSortedHitQueue cannot use an AUTO SortField");
+ default:
+ _CLTHROWA (CL_ERR_Runtime,"invalid SortField type"); //todo: rich error... : "+type);
+ }
+ }
+ }
+ return c > 0;
+}
+
+void FieldDocSortedHitQueue::setFields (SortField** fields) {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ if (this->fields == NULL) {
+ this->fields = fields;
+ _countsize();
+ //this->collators = hasCollators (fields);
+ }else if ( fields == NULL )
+ this->fields = NULL;
+}
+
+FieldDocSortedHitQueue::~FieldDocSortedHitQueue(){
+ if ( fields != NULL ){
+ for ( int i=0;fields[i]!=NULL;i++ )
+ _CLDELETE(fields[i]);
+ _CLDELETE_ARRAY(fields);
+ }
+}
+
+CL_NS_END
+
diff --git a/3rdparty/clucene/src/CLucene/search/FieldDocSortedHitQueue.h b/3rdparty/clucene/src/CLucene/search/FieldDocSortedHitQueue.h
new file mode 100644
index 000000000..5a46b3b65
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldDocSortedHitQueue.h
@@ -0,0 +1,159 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_FieldDocSortedHitQueue_
+#define _lucene_search_FieldDocSortedHitQueue_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "Sort.h"
+#include "CLucene/util/PriorityQueue.h"
+
+CL_NS_DEF(search)
+
+/**
+ * Expert: A ScoreDoc which also contains information about
+ * how to sort the referenced document. In addition to the
+ * document number and score, this object contains an array
+ * of values for the document from the field(s) used to sort.
+ * For example, if the sort criteria was to sort by fields
+ * "a", "b" then "c", the <code>fields</code> object array
+ * will have three elements, corresponding respectively to
+ * the term values for the document in fields "a", "b" and "c".
+ * The class of each element in the array will be either
+ * Integer, Float or String depending on the type of values
+ * in the terms of each field.
+ *
+ * @see ScoreDoc
+ * @see TopFieldDocs
+ */
+class FieldDoc: LUCENE_BASE {
+public:
+ //FieldDoc did inherit from ScoreDoc, but now we make the scoredoc a member
+ struct ScoreDoc scoreDoc;
+
+ /** Expert: The values which are used to sort the referenced document.
+ * The order of these will match the original sort criteria given by a
+ * Sort object. Each Object will be either an Integer, Float or String,
+ * depending on the type of values in the terms of the original field.
+ * @see Sort
+ * @see Searchable#search(Query,Filter,int32_t,Sort)
+ */
+ CL_NS(util)::Comparable** fields;
+
+ /** Expert: Creates one of these objects with empty sort information. */
+ FieldDoc (int32_t doc, qreal score);
+ /** Expert: Creates one of these objects with the given sort information. */
+ FieldDoc (int32_t doc, qreal score, CL_NS(util)::Comparable** fields);
+ ~FieldDoc();
+};
+
+/**
+ * Expert: Collects sorted results from Searchable's and collates them.
+ * The elements put into this queue must be of type FieldDoc.
+ */
+class FieldDocSortedHitQueue:
+ public CL_NS(util)::PriorityQueue<FieldDoc*,CL_NS(util)::Deletor::Object<FieldDoc> >
+{
+private:
+ DEFINE_MUTEX(THIS_LOCK)
+
+ // this cannot contain AUTO fields - any AUTO fields should
+ // have been resolved by the time this class is used.
+ SortField** fields;
+ int32_t fieldsLen;
+
+ void _countsize(){
+ fieldsLen=0;
+ while(fields[fieldsLen]!=NULL)
+ fieldsLen++;
+ }
+
+ // used in the case where the fields are sorted by locale
+ // based strings
+ //todo: not implemented in clucene because locales has not been implemented
+ //Collator[] collators; //volatile
+
+public:
+ /**
+ * Creates a hit queue sorted by the given list of fields.
+ * @param fields Field names, in priority order (highest priority first).
+ * @param size The number of hits to retain. Must be greater than zero.
+ */
+ FieldDocSortedHitQueue (SortField** fields, int32_t size);
+ ~FieldDocSortedHitQueue();
+
+
+ /**
+ * Allows redefinition of sort fields if they are <code>NULL</code>.
+ * This is to handle the case using ParallelMultiSearcher where the
+ * original list contains AUTO and we don't know the actual sort
+ * type until the values come back. The fields can only be set once.
+ * This method is thread safe.
+ * @param fields
+ */
+ void setFields (SortField** fields);
+
+ /** Returns the fields being used to sort. */
+ SortField** getFields() {
+ return fields;
+ }
+
+ /** Returns an array of collators, possibly <code>NULL</code>. The collators
+ * correspond to any SortFields which were given a specific locale.
+ * @param fields Array of sort fields.
+ * @return Array, possibly <code>NULL</code>.
+
+ private Collator[] hasCollators (SortField[] fields) {
+ if (fields == NULL) return NULL;
+ Collator[] ret = new Collator[fields.length];
+ for (int32_t i=0; i<fields.length; ++i) {
+ Locale locale = fields[i].getLocale();
+ if (locale != NULL)
+ ret[i] = Collator.getInstance (locale);
+ }
+ return ret;
+ }*/
+
+protected:
+ /**
+ * Returns whether <code>a</code> is less relevant than <code>b</code>.
+ * @param a FieldDoc
+ * @param b FieldDoc
+ * @return <code>true</code> if document <code>a</code> should be sorted after document <code>b</code>.
+ */
+ bool lessThan (FieldDoc* docA, FieldDoc* docB);
+};
+
+
+/**
+* Expert: Returned by low-level sorted search implementations.
+*
+* @see Searchable#search(Query,Filter,int32_t,Sort)
+*/
+class TopFieldDocs: public TopDocs {
+public:
+ /// The fields which were used to sort results by.
+ SortField** fields;
+
+ FieldDoc** fieldDocs;
+
+ /** Creates one of these objects.
+ * @param totalHits Total number of hits for the query.
+ * @param fieldDocs The top hits for the query.
+ * @param scoreDocs The top hits for the query.
+ * @param scoreDocsLen Length of fieldDocs and scoreDocs
+ * @param fields The sort criteria used to find the top hits.
+ */
+ TopFieldDocs (int32_t totalHits, FieldDoc** fieldDocs, int32_t scoreDocsLen, SortField** fields);
+ ~TopFieldDocs();
+};
+
+CL_NS_END
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/search/FieldSortedHitQueue.cpp b/3rdparty/clucene/src/CLucene/search/FieldSortedHitQueue.cpp
new file mode 100644
index 000000000..04f45e931
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldSortedHitQueue.cpp
@@ -0,0 +1,212 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "FieldSortedHitQueue.h"
+#include "FieldDocSortedHitQueue.h"
+#include "Compare.h"
+
+CL_NS_USE(util)
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+FieldSortedHitQueue::hitqueueCacheType FieldSortedHitQueue::Comparators(false,true);
+
+FieldSortedHitQueue::FieldSortedHitQueue (IndexReader* reader, SortField** _fields, int32_t size):
+ fieldsLen(0),
+ maxscore(1.0f)
+{
+ while ( _fields[fieldsLen] != 0 )
+ fieldsLen++;
+
+ comparators = _CL_NEWARRAY(ScoreDocComparator*,fieldsLen+1);
+ SortField** tmp = _CL_NEWARRAY(SortField*,fieldsLen+1);
+ for (int32_t i=0; i<fieldsLen; ++i) {
+ const TCHAR* fieldname = _fields[i]->getField();
+ //todo: fields[i].getLocale(), not implemented
+ comparators[i] = getCachedComparator (reader, fieldname, _fields[i]->getType(), _fields[i]->getFactory());
+ tmp[i] = _CLNEW SortField (fieldname, comparators[i]->sortType(), _fields[i]->getReverse());
+ }
+ comparatorsLen = fieldsLen;
+ comparators[fieldsLen]=NULL;
+ tmp[fieldsLen] = NULL;
+ this->fields = tmp;
+
+ initialize(size,true);
+}
+
+
+bool FieldSortedHitQueue::lessThan (FieldDoc* docA, FieldDoc* docB) {
+ // keep track of maximum score
+ if (docA->scoreDoc.score > maxscore) maxscore = docA->scoreDoc.score;
+ if (docB->scoreDoc.score > maxscore) maxscore = docB->scoreDoc.score;
+
+ // run comparators
+ int32_t c = 0;
+ for ( int32_t i=0; c==0 && i<comparatorsLen; ++i ) {
+ c = (fields[i]->getReverse()) ? comparators[i]->compare (&docB->scoreDoc, &docA->scoreDoc) :
+ comparators[i]->compare (&docA->scoreDoc, &docB->scoreDoc);
+ }
+ // avoid random sort order that could lead to duplicates (bug #31241):
+ if (c == 0)
+ return docA->scoreDoc.doc > docB->scoreDoc.doc;
+ return c > 0;
+}
+
+
+//static
+ScoreDocComparator* FieldSortedHitQueue::comparatorString (IndexReader* reader, const TCHAR* field) {
+ //const TCHAR* field = CLStringIntern::intern(fieldname CL_FILELINE);
+ FieldCacheAuto* fa = FieldCache::DEFAULT->getStringIndex (reader, field);
+ //CLStringIntern::unintern(field);
+
+ CND_PRECONDITION(fa->contentType==FieldCacheAuto::STRING_INDEX,"Content type is incorrect");
+ fa->ownContents = false;
+ return _CLNEW ScoreDocComparators::String(fa->stringIndex, fa->contentLen);
+}
+
+//static
+ScoreDocComparator* FieldSortedHitQueue::comparatorInt (IndexReader* reader, const TCHAR* field){
+ //const TCHAR* field = CLStringIntern::intern(fieldname CL_FILELINE);
+ FieldCacheAuto* fa = FieldCache::DEFAULT->getInts (reader, field);
+ //CLStringIntern::unintern(field);
+
+ CND_PRECONDITION(fa->contentType==FieldCacheAuto::INT_ARRAY,"Content type is incorrect");
+ return _CLNEW ScoreDocComparators::Int32(fa->intArray, fa->contentLen);
+ }
+
+//static
+ ScoreDocComparator* FieldSortedHitQueue::comparatorFloat (IndexReader* reader, const TCHAR* field) {
+ //const TCHAR* field = CLStringIntern::intern(fieldname CL_FILELINE);
+ FieldCacheAuto* fa = FieldCache::DEFAULT->getFloats (reader, field);
+ //CLStringIntern::unintern(field);
+
+ CND_PRECONDITION(fa->contentType==FieldCacheAuto::FLOAT_ARRAY,"Content type is incorrect");
+ return _CLNEW ScoreDocComparators::Float (fa->floatArray, fa->contentLen);
+ }
+//static
+ ScoreDocComparator* FieldSortedHitQueue::comparatorAuto (IndexReader* reader, const TCHAR* field){
+ //const TCHAR* field = CLStringIntern::intern(fieldname CL_FILELINE);
+ FieldCacheAuto* fa = FieldCache::DEFAULT->getAuto (reader, field);
+ //CLStringIntern::unintern(field);
+
+ if (fa->contentType == FieldCacheAuto::STRING_INDEX ) {
+ return comparatorString (reader, field);
+ } else if (fa->contentType == FieldCacheAuto::INT_ARRAY) {
+ return comparatorInt (reader, field);
+ } else if (fa->contentType == FieldCacheAuto::FLOAT_ARRAY) {
+ return comparatorFloat (reader, field);
+ } else if (fa->contentType == FieldCacheAuto::STRING_ARRAY) {
+ return comparatorString (reader, field);
+ } else {
+ _CLTHROWA(CL_ERR_Runtime, "unknown data type in field"); //todo: rich error information: '"+field+"'");
+ }
+ }
+
+
+ //todo: Locale locale, not implemented yet
+ ScoreDocComparator* FieldSortedHitQueue::getCachedComparator (IndexReader* reader, const TCHAR* fieldname, int32_t type, SortComparatorSource* factory){
+ if (type == SortField::DOC)
+ return ScoreDocComparator::INDEXORDER;
+ if (type == SortField::DOCSCORE)
+ return ScoreDocComparator::RELEVANCE;
+ ScoreDocComparator* comparator = lookup (reader, fieldname, type, factory);
+ if (comparator == NULL) {
+ switch (type) {
+ case SortField::AUTO:
+ comparator = comparatorAuto (reader, fieldname);
+ break;
+ case SortField::INT:
+ comparator = comparatorInt (reader, fieldname);
+ break;
+ case SortField::FLOAT:
+ comparator = comparatorFloat (reader, fieldname);
+ break;
+ case SortField::STRING:
+ //if (locale != NULL)
+ // comparator = comparatorStringLocale (reader, fieldname, locale);
+ //else
+ comparator = comparatorString (reader, fieldname);
+ break;
+ case SortField::CUSTOM:
+ comparator = factory->newComparator (reader, fieldname);
+ break;
+ default:
+ _CLTHROWA(CL_ERR_Runtime,"unknown field type");
+ //todo: extend error
+ //throw _CLNEW RuntimeException ("unknown field type: "+type);
+ }
+ store (reader, fieldname, type, factory, comparator);
+ }
+ return comparator;
+ }
+
+
+ FieldDoc* FieldSortedHitQueue::fillFields (FieldDoc* doc) const{
+ int32_t n = comparatorsLen;
+ Comparable** fields = _CL_NEWARRAY(Comparable*,n+1);
+ for (int32_t i=0; i<n; ++i)
+ fields[i] = comparators[i]->sortValue(&doc->scoreDoc);
+ fields[n]=NULL;
+ doc->fields = fields;
+ if (maxscore > 1.0f)
+ doc->scoreDoc.score /= maxscore; // normalize scores
+ return doc;
+ }
+
+ ScoreDocComparator* FieldSortedHitQueue::lookup (IndexReader* reader, const TCHAR* field, int32_t type, SortComparatorSource* factory) {
+ ScoreDocComparator* sdc = NULL;
+ FieldCacheImpl::FileEntry* entry = (factory != NULL)
+ ? _CLNEW FieldCacheImpl::FileEntry (field, factory)
+ : _CLNEW FieldCacheImpl::FileEntry (field, type);
+
+ {
+ SCOPED_LOCK_MUTEX(Comparators.THIS_LOCK)
+ hitqueueCacheReaderType* readerCache = Comparators.get(reader);
+ if (readerCache == NULL){
+ _CLDELETE(entry);
+ return NULL;
+ }
+
+ sdc = readerCache->get (entry);
+ _CLDELETE(entry);
+ }
+ return sdc;
+ }
+
+ void FieldSortedHitQueue::closeCallback(CL_NS(index)::IndexReader* reader, void*){
+ SCOPED_LOCK_MUTEX(Comparators.THIS_LOCK)
+ Comparators.remove(reader);
+ }
+
+ //static
+ void FieldSortedHitQueue::store (IndexReader* reader, const TCHAR* field, int32_t type, SortComparatorSource* factory, ScoreDocComparator* value) {
+ FieldCacheImpl::FileEntry* entry = (factory != NULL)
+ ? _CLNEW FieldCacheImpl::FileEntry (field, factory)
+ : _CLNEW FieldCacheImpl::FileEntry (field, type);
+
+ {
+ SCOPED_LOCK_MUTEX(Comparators.THIS_LOCK)
+ hitqueueCacheReaderType* readerCache = Comparators.get(reader);
+ if (readerCache == NULL) {
+ readerCache = _CLNEW hitqueueCacheReaderType(true);
+ Comparators.put(reader,readerCache);
+ reader->addCloseCallback(FieldSortedHitQueue::closeCallback,NULL);
+ }
+ readerCache->put (entry, value);
+ //return NULL; //supposed to return previous value...
+ }
+ }
+
+FieldSortedHitQueue::~FieldSortedHitQueue(){
+ _CLDELETE_ARRAY(comparators);
+ if ( fields != NULL ){
+ for ( int i=0;fields[i]!=NULL;i++ )
+ _CLDELETE(fields[i]);
+ _CLDELETE_ARRAY(fields);
+ }
+}
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/FieldSortedHitQueue.h b/3rdparty/clucene/src/CLucene/search/FieldSortedHitQueue.h
new file mode 100644
index 000000000..d7b16ce9e
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FieldSortedHitQueue.h
@@ -0,0 +1,216 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_FieldSortedHitQueue_
+#define _lucene_search_FieldSortedHitQueue_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "FieldCache.h"
+#include "Sort.h"
+#include "FieldDocSortedHitQueue.h"
+#include "SearchHeader.h"
+#include "FieldCacheImpl.h"
+#include "CLucene/util/PriorityQueue.h"
+
+CL_NS_DEF(search)
+
+
+/**
+ * Expert: A hit queue for sorting by hits by terms in more than one field.
+ * Uses <code>FieldCache.DEFAULT</code> for maintaining internal term lookup tables.
+ *
+ * @see Searchable#search(Query,Filter,int32_t,Sort)
+ * @see FieldCache
+ */
+class FieldSortedHitQueue: public CL_NS(util)::PriorityQueue<FieldDoc*,
+ CL_NS(util)::Deletor::Object<FieldDoc> > {
+
+ ///the type that is stored in the field cache. can't use a typedef because
+ ///the decorated name would become too long
+ class hitqueueCacheReaderType: public CL_NS(util)::CLHashMap<FieldCacheImpl::FileEntry*,
+ ScoreDocComparator*,
+ FieldCacheImpl::FileEntry::Compare,
+ FieldCacheImpl::FileEntry::Equals,
+ CL_NS(util)::Deletor::Object<FieldCacheImpl::FileEntry>,
+ CL_NS(util)::Deletor::Object<ScoreDocComparator> >{
+
+ public:
+ hitqueueCacheReaderType(bool deleteValue){
+ setDeleteKey(true);
+ setDeleteValue(deleteValue);
+ }
+ ~hitqueueCacheReaderType(){
+ clear();
+ }
+
+ };
+
+public: //todo: remove this and below after close callback is implemented
+ //note: typename gets too long if using cacheReaderType as a typename
+ typedef CL_NS(util)::CLHashMap<CL_NS(index)::IndexReader*,
+ hitqueueCacheReaderType*,
+ CL_NS(util)::Compare::Void<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Equals::Void<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Deletor::Object<CL_NS(index)::IndexReader>,
+ CL_NS(util)::Deletor::Object<hitqueueCacheReaderType> > hitqueueCacheType;
+
+ /** Internal cache of comparators. Similar to FieldCache, only
+ * caches comparators instead of term values.
+ */
+ static hitqueueCacheType Comparators;
+private:
+
+ /** Returns a comparator if it is in the cache.*/
+ static ScoreDocComparator* lookup (CL_NS(index)::IndexReader* reader, const TCHAR* field, int32_t type, SortComparatorSource* factory);
+
+ /** Stores a comparator into the cache.
+ returns the valid ScoreDocComparator.
+ */
+ static void store (CL_NS(index)::IndexReader* reader, const TCHAR* field, int32_t type, SortComparatorSource* factory, ScoreDocComparator* value);
+
+
+ //todo: Locale locale, not implemented yet
+ static ScoreDocComparator* getCachedComparator (CL_NS(index)::IndexReader* reader,
+ const TCHAR* fieldname, int32_t type, SortComparatorSource* factory);
+
+
+ /**
+ * Returns a comparator for sorting hits according to a field containing integers.
+ * @param reader Index to use.
+ * @param fieldname Field containg integer values.
+ * @return Comparator for sorting hits.
+ * @throws IOException If an error occurs reading the index.
+ */
+ static ScoreDocComparator* comparatorInt (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname);
+
+ /**
+ * Returns a comparator for sorting hits according to a field containing floats.
+ * @param reader Index to use.
+ * @param fieldname Field containg float values.
+ * @return Comparator for sorting hits.
+ * @throws IOException If an error occurs reading the index.
+ */
+ static ScoreDocComparator* comparatorFloat (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname);
+
+ /**
+ * Returns a comparator for sorting hits according to a field containing strings.
+ * @param reader Index to use.
+ * @param fieldname Field containg string values.
+ * @return Comparator for sorting hits.
+ * @throws IOException If an error occurs reading the index.
+ */
+ static ScoreDocComparator* comparatorString (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname);
+
+
+ //todo:
+ /**
+ * Returns a comparator for sorting hits according to a field containing strings.
+ * @param reader Index to use.
+ * @param fieldname Field containg string values.
+ * @return Comparator for sorting hits.
+ * @throws IOException If an error occurs reading the index.
+
+ static ScoreDocComparator* comparatorStringLocale (IndexReader* reader, TCHAR* fieldname, Locale locale){
+ Collator collator = Collator.getInstance (locale);
+ TCHAR* field = fieldname.intern();
+ TCHAR** index = FieldCache.DEFAULT.getStrings (reader, field);
+ return _CLNEW ScoreDocComparator() {
+
+ public int32_t compare (ScoreDoc i, ScoreDoc j) {
+ return collator.compare (index[i.doc], index[j.doc]);
+ }
+
+ public Comparable sortValue (ScoreDoc i) {
+ return index[i.doc];
+ }
+
+ public int32_t sortType() {
+ return SortField.STRING;
+ }
+ };
+ }*/
+
+ /**
+ * Returns a comparator for sorting hits according to values in the given field.
+ * The terms in the field are looked at to determine whether they contain integers,
+ * floats or strings. Once the type is determined, one of the other static methods
+ * in this class is called to get the comparator.
+ * @param reader Index to use.
+ * @param fieldname Field containg values.
+ * @return Comparator for sorting hits.
+ * @throws IOException If an error occurs reading the index.
+ */
+ static ScoreDocComparator* comparatorAuto (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname);
+
+
+protected:
+ /** Stores a comparator corresponding to each field being sorted by */
+ ScoreDocComparator** comparators;
+ int32_t comparatorsLen;
+
+ /** Stores the sort criteria being used. */
+ SortField** fields;
+ int32_t fieldsLen;
+
+ /** Stores the maximum score value encountered, for normalizing.
+ * we only care about scores greater than 1.0 - if all the scores
+ * are less than 1.0, we don't have to normalize. */
+ qreal maxscore;
+
+ /**
+ * Returns whether <code>a</code> is less relevant than <code>b</code>.
+ * @param a ScoreDoc
+ * @param b ScoreDoc
+ * @return <code>true</code> if document <code>a</code> should be sorted after document <code>b</code>.
+ */
+ bool lessThan (FieldDoc* docA, FieldDoc* docB);
+public:
+
+ /**
+ * Creates a hit queue sorted by the given list of fields.
+ * @param reader Index to use.
+ * @param fields Field names, in priority order (highest priority first). Cannot be <code>null</code> or empty.
+ * @param size The number of hits to retain. Must be greater than zero.
+ * @throws IOException
+ */
+ FieldSortedHitQueue (CL_NS(index)::IndexReader* reader, SortField** fields, int32_t size);
+
+ ~FieldSortedHitQueue();
+
+ /**
+ * Callback for when IndexReader closes. This causes
+ * any Comparators to be removed for the specified reader.
+ */
+ static void closeCallback(CL_NS(index)::IndexReader* reader, void* param);
+
+ /**
+ * Given a FieldDoc object, stores the values used
+ * to sort the given document. These values are not the raw
+ * values out of the index, but the internal representation
+ * of them. This is so the given search hit can be collated
+ * by a MultiSearcher with other search hits.
+ * @param doc The FieldDoc to store sort values into.
+ * @return The same FieldDoc passed in.
+ * @see Searchable#search(Query,Filter,int32_t,Sort)
+ */
+ FieldDoc* fillFields (FieldDoc* doc) const;
+
+ void setFields (SortField** fields){
+ this->fields = fields;
+ }
+
+ /** Returns the SortFields being used by this hit queue. */
+ SortField** getFields() {
+ return fields;
+ }
+};
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/Filter.h b/3rdparty/clucene/src/CLucene/search/Filter.h
new file mode 100644
index 000000000..309c5a9d6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Filter.h
@@ -0,0 +1,46 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_Filter_
+#define _lucene_search_Filter_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/BitSet.h"
+
+CL_NS_DEF(search)
+ // Abstract base class providing a mechanism to restrict searches to a subset
+ // of an index.
+ class Filter: LUCENE_BASE {
+ public:
+ virtual ~Filter(){
+ }
+
+ virtual Filter* clone() const = 0;
+
+ /**
+ * Returns a BitSet with true for documents which should be permitted in
+ * search results, and false for those that should not.
+ * MEMORY: read shouldDeleteBitSet
+ */
+ virtual CL_NS(util)::BitSet* bits(CL_NS(index)::IndexReader* reader)=0;
+
+ /**
+ * Because of the problem of cached bitsets with the CachingWrapperFilter,
+ * CLucene has no way of knowing whether to delete the bitset returned from bits().
+ * To properly clean memory from bits(), pass the bitset to this function. The
+ * Filter should be deleted if this function returns true.
+ */
+ virtual bool shouldDeleteBitSet(const CL_NS(util)::BitSet* bs) const{ return true; }
+
+ //Creates a user-readable version of this query and returns it as as string
+ virtual TCHAR* toString()=0;
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/FilteredTermEnum.cpp b/3rdparty/clucene/src/CLucene/search/FilteredTermEnum.cpp
new file mode 100644
index 000000000..f90ceeaaf
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FilteredTermEnum.cpp
@@ -0,0 +1,136 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+
+#include "FilteredTermEnum.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+
+ FilteredTermEnum::FilteredTermEnum(){
+ //Func - Constructor
+ //Pre - true
+ //Post - Instance has been created
+
+ currentTerm = NULL;
+ actualEnum = NULL;
+ }
+
+ FilteredTermEnum::~FilteredTermEnum() {
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ close();
+ }
+
+ int32_t FilteredTermEnum::docFreq() const {
+ //Func - Returns the docFreq of the current Term in the enumeration.
+ //Pre - next() must have been called at least once
+ //Post - if actualEnum is NULL result is -1 otherwise the frequencey is returned
+
+ if (actualEnum == NULL){
+ return -1;
+ }
+ return actualEnum->docFreq();
+ }
+
+ bool FilteredTermEnum::next() {
+ //Func - Increments the enumeration to the next element.
+ //Pre - true
+ //Post - Returns True if the enumeration has been moved to the next element otherwise false
+
+ //The actual enumerator is not initialized!
+ if (actualEnum == NULL){
+ return false;
+ }
+
+ //Finalize the currentTerm and reset it to NULL
+ _CLDECDELETE( currentTerm );
+
+ //Iterate through the enumeration
+ while (currentTerm == NULL) {
+ if (endEnum())
+ return false;
+ if (actualEnum->next()) {
+ //Order term not to return reference ownership here. */
+ Term* term = actualEnum->term(false);
+ //Compare the retrieved term
+ if (termCompare(term)){
+ //Matched so finalize the current
+ _CLDECDELETE(currentTerm);
+ //Get a reference to the matched term
+ currentTerm = _CL_POINTER(term);
+ return true;
+ }
+ }else
+ return false;
+ }
+ _CLDECDELETE(currentTerm);
+ currentTerm = NULL;
+
+ return false;
+ }
+
+ Term* FilteredTermEnum::term() {
+ //Func - Returns the current Term in the enumeration.
+ //Pre - next() must have been called at least once
+ // pointer is true or false
+ //Post - if pre(pointer) is true the reference counter of currentTerm is increased
+ // and current Term is returned otherwise currentTerm is only returned
+
+ return _CL_POINTER(currentTerm);
+ }
+ Term* FilteredTermEnum::term(bool pointer) {
+ if ( pointer )
+ return _CL_POINTER(currentTerm);
+ else
+ return currentTerm;
+ }
+
+ void FilteredTermEnum::close(){
+ //Func - Closes the enumeration to further activity, freeing resources.
+ //Pre - true
+ //Post - The Enumeration has been closed
+
+ //Check if actualEnum is valid
+ if (actualEnum){
+ //Close the enumeration
+ actualEnum->close();
+ }
+
+ //Destroy the enumeration
+ _CLDELETE(actualEnum);
+
+ //Destroy currentTerm
+ _CLDECDELETE(currentTerm);
+ }
+
+ void FilteredTermEnum::setEnum(TermEnum* actualEnum) {
+ //Func - Sets the actual Enumeration
+ //Pre - actualEnum != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(actualEnum != NULL,"actualEnum is NULL");
+
+ _CLDELETE(this->actualEnum);
+
+ this->actualEnum = actualEnum;
+
+ // Find the first term that matches
+ //Ordered term not to return reference ownership here.
+ Term* term = actualEnum->term(false);
+ if (term != NULL && termCompare(term)){
+ _CLDECDELETE(currentTerm);
+ currentTerm = _CL_POINTER(term);
+ }else{
+ next();
+ }
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/FilteredTermEnum.h b/3rdparty/clucene/src/CLucene/search/FilteredTermEnum.h
new file mode 100644
index 000000000..035ae384e
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FilteredTermEnum.h
@@ -0,0 +1,61 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_FilteredTermEnum_
+#define _lucene_search_FilteredTermEnum_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+
+CL_NS_DEF(search)
+ //FilteredTermEnum is an abstract class for enumerating a subset of all terms.
+ //
+ //Term enumerations are always ordered by term->compareTo(). Each term in
+ //the enumeration is greater than all that precede it.
+
+ class FilteredTermEnum: public CL_NS(index)::TermEnum {
+ public:
+ //Constructor
+ FilteredTermEnum();
+ //Destructor
+ virtual ~FilteredTermEnum();
+
+ //Equality measure on the term
+ virtual qreal difference() = 0;
+
+ //Returns the docFreq of the current Term in the enumeration.
+ int32_t docFreq() const ;
+
+ //Increments the enumeration to the next element
+ bool next() ;
+
+ //Returns a pointer to the current Term in the enumeration.
+ CL_NS(index)::Term* term();
+ CL_NS(index)::Term* term(bool pointer);
+
+ //Closes the enumeration to further activity, freeing resources.
+ void close();
+
+ protected:
+ //Equality compare on the term */
+ virtual bool termCompare(CL_NS(index)::Term* term) = 0;
+
+ //Indiciates the end of the enumeration has been reached
+ virtual bool endEnum() = 0;
+
+ void setEnum(CL_NS(index)::TermEnum* actualEnum) ;
+
+ private:
+ CL_NS(index)::Term* currentTerm;
+ CL_NS(index)::TermEnum* actualEnum;
+
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/FuzzyQuery.cpp b/3rdparty/clucene/src/CLucene/search/FuzzyQuery.cpp
new file mode 100644
index 000000000..e95d48da3
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FuzzyQuery.cpp
@@ -0,0 +1,357 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "FuzzyQuery.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+ /**
+ * Constructor for enumeration of all terms from specified <code>reader</code> which share a prefix of
+ * length <code>prefixLength</code> with <code>term</code> and which have a fuzzy similarity &gt;
+ * <code>minSimilarity</code>.
+ *
+ * @param reader Delivers terms.
+ * @param term Pattern term.
+ * @param minSimilarity Minimum required similarity for terms from the reader. Default value is 0.5f.
+ * @param prefixLength Length of required common prefix. Default value is 0.
+ * @throws IOException
+ */
+ FuzzyTermEnum::FuzzyTermEnum(const IndexReader* reader, Term* term, qreal minSimilarity, size_t prefixLength):
+ distance(0),
+ _endEnum(false),
+ prefix(LUCENE_BLANK_STRING),
+ prefixLength(0),
+ minimumSimilarity(minSimilarity)
+ {
+ //Func - Constructor
+ //Pre - reader contains a valid reference to an IndexReader
+ // term != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(term != NULL,"term is NULL");
+
+ scale_factor = 1.0f / (1.0f - minimumSimilarity);
+ searchTerm = _CL_POINTER(term);
+
+ text = STRDUP_TtoT(term->text());
+ textLen = term->textLength();
+
+
+ //Initialize e to NULL
+ e = NULL;
+ eWidth = 0;
+ eHeight = 0;
+
+ if(prefixLength > 0 && prefixLength < textLen){
+ this->prefixLength = prefixLength;
+
+ prefix = _CL_NEWARRAY(TCHAR,prefixLength+1);
+ _tcsncpy(prefix,text,prefixLength);
+ prefix[prefixLength]='\0';
+
+ textLen = prefixLength;
+ text[textLen]='\0';
+ }
+
+
+ //Set the enumeration
+ Term* trm = _CLNEW Term(term, prefix);
+ setEnum(reader->terms(trm));
+ _CLDECDELETE(trm);
+ }
+
+ FuzzyTermEnum::~FuzzyTermEnum(){
+ //Func - Destructor
+ //Pre - true
+ //Post - FuzzyTermEnum has been destroyed
+
+ //Close the enumeration
+ close();
+ }
+
+ bool FuzzyTermEnum::endEnum() {
+ //Func - Returns the fact if the current term in the enumeration has reached the end
+ //Pre - true
+ //Post - The boolean value of endEnum has been returned
+
+ return _endEnum;
+ }
+
+ void FuzzyTermEnum::close(){
+ //Func - Close the enumeration
+ //Pre - true
+ //Post - The enumeration has been closed
+
+ FilteredTermEnum::close();
+
+ //Finalize the searchTerm
+ _CLDECDELETE(searchTerm);
+ //Destroy e
+ _CLDELETE_ARRAY(e);
+
+ _CLDELETE_CARRAY(text);
+
+ if ( prefix != LUCENE_BLANK_STRING )
+ _CLDELETE_CARRAY(prefix);
+ }
+
+ bool FuzzyTermEnum::termCompare(Term* term) {
+ //Func - Compares term with the searchTerm using the Levenshtein distance.
+ //Pre - term is NULL or term points to a Term
+ //Post - if pre(term) is NULL then false is returned otherwise
+ // if the distance of the current term in the enumeration is bigger than the FUZZY_THRESHOLD
+ // then true is returned
+
+ if (term == NULL){
+ return false; //Note that endEnum is not set to true!
+ }
+
+ const TCHAR* termText = term->text();
+ size_t termTextLen = term->textLength();
+
+ //Check if the field name of searchTerm of term match
+ //(we can use == because fields are interned)
+ if ( searchTerm->field() == term->field() &&
+ (prefixLength==0 || _tcsncmp(termText,prefix,prefixLength)==0 )) {
+
+ const TCHAR* target = termText+prefixLength;
+ size_t targetLen = termTextLen-prefixLength;
+
+ //Calculate the Levenshtein distance
+ int32_t dist = editDistance(text, target, textLen, targetLen);
+ distance = 1 - ((qreal)dist / (qreal)min(textLen, targetLen));
+ return (distance > minimumSimilarity);
+ }
+ _endEnum = true;
+ return false;
+ }
+
+ qreal FuzzyTermEnum::difference() {
+ //Func - Returns the difference between the distance and the fuzzy threshold
+ // multiplied by the scale factor
+ //Pre - true
+ //Post - The difference is returned
+
+ return (qreal)((distance - minimumSimilarity) * scale_factor );
+ }
+
+
+ /** Finds and returns the smallest of three integers
+ precondition: Must define int32_t __t for temporary storage and result
+ */
+ #define min3(a, b, c) __t = (a < b) ? a : b; __t = (__t < c) ? __t : c;
+
+ int32_t FuzzyTermEnum::editDistance(const TCHAR* s, const TCHAR* t, const int32_t n, const int32_t m) {
+ //Func - Calculates the Levenshtein distance also known as edit distance is a measure of similiarity
+ // between two strings where the distance is measured as the number of character
+ // deletions, insertions or substitutions required to transform one string to
+ // the other string.
+ //Pre - s != NULL and contains the source string
+ // t != NULL and contains the target string
+ // n >= 0 and contains the length of the source string
+ // m >= 0 and containts the length of th target string
+ //Post - The distance has been returned
+
+ CND_PRECONDITION(s != NULL, "s is NULL");
+ CND_PRECONDITION(t != NULL, "t is NULL");
+ CND_PRECONDITION(n >= 0," n is a negative number");
+ CND_PRECONDITION(n >= 0," n is a negative number");
+
+ int32_t i; // iterates through s
+ int32_t j; // iterates through t
+ TCHAR s_i; // ith character of s
+
+ if (n == 0)
+ return m;
+ if (m == 0)
+ return n;
+
+ //Check if the array must be reallocated because it is too small or does not exist
+ if (e == NULL || eWidth <= n || eHeight <= m) {
+ //Delete e if possible
+ _CLDELETE_ARRAY(e);
+ //resize e
+ eWidth = max(eWidth, n+1);
+ eHeight = max(eHeight, m+1);
+ e = _CL_NEWARRAY(int32_t,eWidth*eHeight);
+ }
+
+ CND_CONDITION(e != NULL,"e is NULL");
+
+ // init matrix e
+ for (i = 0; i <= n; i++){
+ e[i + (0*eWidth)] = i;
+ }
+ for (j = 0; j <= m; j++){
+ e[0 + (j*eWidth)] = j;
+ }
+
+ int32_t __t; //temporary variable for min3
+
+ // start computing edit distance
+ for (i = 1; i <= n; i++) {
+ s_i = s[i - 1];
+ for (j = 1; j <= m; j++) {
+ if (s_i != t[j-1]){
+ min3(e[i + (j*eWidth) - 1], e[i + ((j-1)*eWidth)], e[i + ((j-1)*eWidth)-1]);
+ e[i + (j*eWidth)] = __t+1;
+ }else{
+ min3(e[i + (j*eWidth) -1]+1, e[i + ((j-1)*eWidth)]+1, e[i + ((j-1)*eWidth)-1]);
+ e[i + (j*eWidth)] = __t;
+ }
+ }
+ }
+
+ // we got the result!
+ return e[n + ((m)*eWidth)];
+ }
+
+
+ /**
+ * Create a new FuzzyQuery that will match terms with a similarity
+ * of at least <code>minimumSimilarity</code> to <code>term</code>.
+ * If a <code>prefixLength</code> &gt; 0 is specified, a common prefix
+ * of that length is also required.
+ *
+ * @param term the term to search for
+ * @param minimumSimilarity a value between 0 and 1 to set the required similarity
+ * between the query term and the matching terms. For example, for a
+ * <code>minimumSimilarity</code> of <code>0.5</code> a term of the same length
+ * as the query term is considered similar to the query term if the edit distance
+ * between both terms is less than <code>length(term)*0.5</code>
+ * @param prefixLength length of common (non-fuzzy) prefix
+ * @throws IllegalArgumentException if minimumSimilarity is &gt; 1 or &lt; 0
+ * or if prefixLength &lt; 0 or &gt; <code>term.text().length()</code>.
+ */
+ FuzzyQuery::FuzzyQuery(Term* term, qreal minimumSimilarity, size_t prefixLength):
+ MultiTermQuery(term)
+ {
+ //Func - Constructor
+ //Pre - term != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(term != NULL,"term is NULL");
+
+ if (minimumSimilarity > 1.0f)
+ _CLTHROWA(CL_ERR_IllegalArgument,"minimumSimilarity > 1");
+ else if (minimumSimilarity < 0.0f)
+ _CLTHROWA(CL_ERR_IllegalArgument,"minimumSimilarity < 0");
+
+ this->minimumSimilarity = minimumSimilarity;
+
+ if(prefixLength >= term->textLength())
+ _CLTHROWA(CL_ERR_IllegalArgument,"prefixLength >= term.textLength()");
+ this->prefixLength = prefixLength;
+
+ }
+
+
+ qreal FuzzyQuery::defaultMinSimilarity = 0.5f;
+
+ FuzzyQuery::~FuzzyQuery(){
+ //Func - Destructor
+ //Pre - true
+ //Post - Instance has been destroyed
+ }
+
+ TCHAR* FuzzyQuery::toString(const TCHAR* field) const{
+ //Func - Returns the query string
+ //Pre - field != NULL
+ //Post - The query string has been returned
+
+ CND_PRECONDITION(field != NULL,"field is NULL");
+
+ StringBuffer buffer;
+ const TCHAR* b = MultiTermQuery::toString(field);
+
+ buffer.append ( b );
+ _CLDELETE_CARRAY(b);
+ buffer.append( _T("~") );
+
+ buffer.appendFloat(minimumSimilarity,1);
+
+ return buffer.toString();
+ }
+
+ const TCHAR* FuzzyQuery::getQueryName() const{
+ //Func - Returns the name of the query
+ //Pre - true
+ //post - The string FuzzyQuery has been returned
+
+ return getClassName();
+ }
+ const TCHAR* FuzzyQuery::getClassName(){
+ //Func - Returns the name of the query
+ //Pre - true
+ //post - The string FuzzyQuery has been returned
+
+ return _T("FuzzyQuery");
+ }
+
+
+ /**
+ * Returns the minimum similarity that is required for this query to match.
+ * @return float value between 0.0 and 1.0
+ */
+ qreal FuzzyQuery::getMinSimilarity() const {
+ return minimumSimilarity;
+ }
+
+ FuzzyQuery::FuzzyQuery(const FuzzyQuery& clone):
+ MultiTermQuery(clone)
+ {
+ this->minimumSimilarity = clone.getMinSimilarity();
+ this->prefixLength = clone.getPrefixLength();
+
+ //if(prefixLength < 0)
+ // _CLTHROWA(CL_ERR_IllegalArgument,"prefixLength < 0");
+ //else
+ if(prefixLength >= clone.getTerm()->textLength())
+ _CLTHROWA(CL_ERR_IllegalArgument,"prefixLength >= term.textLength()");
+
+ }
+
+ Query* FuzzyQuery::clone() const{
+ return _CLNEW FuzzyQuery(*this);
+ }
+ size_t FuzzyQuery::hashCode() const{
+ //todo: we should give the query a seeding value... but
+ //need to do it for all hascode functions
+ size_t val = Similarity::floatToByte(getBoost()) ^ getTerm()->hashCode();
+ val ^= Similarity::floatToByte(this->getMinSimilarity());
+ val ^= this->getPrefixLength();
+ return val;
+ }
+ bool FuzzyQuery::equals(Query* other) const{
+ if (!(other->instanceOf(FuzzyQuery::getClassName())))
+ return false;
+
+ FuzzyQuery* fq = (FuzzyQuery*)other;
+ return (this->getBoost() == fq->getBoost())
+ && this->getMinSimilarity() == fq->getMinSimilarity()
+ && this->getPrefixLength() == fq->getPrefixLength()
+ && getTerm()->equals(fq->getTerm());
+ }
+
+ /**
+ * Returns the prefix length, i.e. the number of characters at the start
+ * of a term that must be identical (not fuzzy) to the query term if the query
+ * is to match that term.
+ */
+ size_t FuzzyQuery::getPrefixLength() const {
+ return prefixLength;
+ }
+
+ FilteredTermEnum* FuzzyQuery::getEnum(IndexReader* reader){
+ Term* term = getTerm(false);
+ FuzzyTermEnum* ret = _CLNEW FuzzyTermEnum(reader, term, minimumSimilarity, prefixLength);
+ return ret;
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/FuzzyQuery.h b/3rdparty/clucene/src/CLucene/search/FuzzyQuery.h
new file mode 100644
index 000000000..e58637bb9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/FuzzyQuery.h
@@ -0,0 +1,156 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_FuzzyQuery_
+#define _lucene_search_FuzzyQuery_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/index/Term.h"
+#include "MultiTermQuery.h"
+
+
+CL_NS_DEF(search)
+
+ // class FuzzyQuery implements the fuzzy search query
+ class FuzzyQuery: public MultiTermQuery {
+ private:
+ qreal minimumSimilarity;
+ size_t prefixLength;
+ protected:
+ FuzzyQuery(const FuzzyQuery& clone);
+ public:
+ static qreal defaultMinSimilarity;
+
+ /**
+ * Create a new FuzzyQuery that will match terms with a similarity
+ * of at least <code>minimumSimilarity</code> to <code>term</code>.
+ * If a <code>prefixLength</code> &gt; 0 is specified, a common prefix
+ * of that length is also required.
+ *
+ * @param term the term to search for
+ * @param minimumSimilarity a value between 0 and 1 to set the required similarity
+ * between the query term and the matching terms. For example, for a
+ * <code>minimumSimilarity</code> of <code>0.5</code> a term of the same length
+ * as the query term is considered similar to the query term if the edit distance
+ * between both terms is less than <code>length(term)*0.5</code>
+ * @param prefixLength length of common (non-fuzzy) prefix
+ * @throws IllegalArgumentException if minimumSimilarity is &gt; 1 or &lt; 0
+ * or if prefixLength &lt; 0 or &gt; <code>term.text().length()</code>.
+ */
+ FuzzyQuery(CL_NS(index)::Term* term, qreal minimumSimilarity=defaultMinSimilarity, size_t prefixLength=0);
+ //Destructor
+ ~FuzzyQuery();
+
+ TCHAR* toString(const TCHAR* field) const;
+
+ //Returns the name "FuzzyQuery"
+ static const TCHAR* getClassName();
+ const TCHAR* getQueryName() const;
+
+ Query* clone() const;
+ bool equals(Query * other) const;
+ size_t hashCode() const;
+
+ /**
+ * Returns the minimum similarity that is required for this query to match.
+ * @return float value between 0.0 and 1.0
+ */
+ qreal getMinSimilarity() const;
+
+ /**
+ * Returns the prefix length, i.e. the number of characters at the start
+ * of a term that must be identical (not fuzzy) to the query term if the query
+ * is to match that term.
+ */
+ size_t getPrefixLength() const;
+
+ protected:
+ FilteredTermEnum* getEnum(CL_NS(index)::IndexReader* reader);
+ };
+
+ /** FuzzyTermEnum is a subclass of FilteredTermEnum for enumerating all
+ * terms that are similiar to the specified filter term.
+ *
+ * Term enumerations are always ordered by Term.compareTo(). Each term in
+ * the enumeration is greater than all that precede it.
+ */
+ class FuzzyTermEnum: public FilteredTermEnum {
+ private:
+ qreal distance;
+ bool _endEnum;
+
+ CL_NS(index)::Term* searchTerm;
+ TCHAR* text;
+ size_t textLen;
+ TCHAR* prefix;
+ size_t prefixLength;
+ qreal minimumSimilarity;
+ double scale_factor;
+
+
+ /**
+ * This static array saves us from the time required to create a new array
+ * everytime editDistance is called.
+ */
+ int32_t* e;
+ int32_t eWidth;
+ int32_t eHeight;
+
+ /******************************
+ * Compute Levenshtein distance
+ ******************************/
+
+ /**
+ Levenshtein distance also known as edit distance is a measure of similiarity
+ between two strings where the distance is measured as the number of character
+ deletions, insertions or substitutions required to transform one string to
+ the other string.
+ <p>This method takes in four parameters; two strings and their respective
+ lengths to compute the Levenshtein distance between the two strings.
+ The result is returned as an integer.
+ */
+ int32_t editDistance(const TCHAR* s, const TCHAR* t, const int32_t n, const int32_t m) ;
+
+ protected:
+ /**
+ The termCompare method in FuzzyTermEnum uses Levenshtein distance to
+ calculate the distance between the given term and the comparing term.
+ */
+ bool termCompare(CL_NS(index)::Term* term) ;
+
+ ///Returns the fact if the current term in the enumeration has reached the end
+ bool endEnum();
+ public:
+
+ /**
+ * Empty prefix and minSimilarity of 0.5f are used.
+ *
+ * @param reader
+ * @param term
+ * @throws IOException
+ * @see #FuzzyTermEnum(IndexReader, Term, qreal, int32_t)
+ */
+ FuzzyTermEnum(const CL_NS(index)::IndexReader* reader, CL_NS(index)::Term* term, qreal minSimilarity=FuzzyQuery::defaultMinSimilarity, size_t prefixLength=0);
+ /** Destructor */
+ ~FuzzyTermEnum();
+ /** Close the enumeration */
+ void close();
+
+ /** Returns the difference between the distance and the fuzzy threshold
+ * multiplied by the scale factor
+ */
+ qreal difference();
+
+
+ const char* getObjectName(){ return FuzzyTermEnum::getClassName(); }
+ static const char* getClassName(){ return "FuzzyTermEnum"; }
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/HitQueue.cpp b/3rdparty/clucene/src/CLucene/search/HitQueue.cpp
new file mode 100644
index 000000000..c9aecc6b4
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/HitQueue.cpp
@@ -0,0 +1,107 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "HitQueue.h"
+
+CL_NS_DEF(search)
+
+void HitQueue::upHeap(){
+ size_t i = _size;
+ ScoreDoc node = heap[i]; // save bottom node (WAS object)
+ int32_t j = ((uint32_t)i) >> 1;
+ while (j > 0 && lessThan(node,heap[j])) {
+ heap[i] = heap[j]; // shift parents down
+ i = j;
+ j = ((uint32_t)j) >> 1;
+ }
+ heap[i] = node; // install saved node
+}
+void HitQueue::downHeap(){
+ size_t i = 1;
+ ScoreDoc node = heap[i]; // save top node
+ size_t j = i << 1; // find smaller child
+ size_t k = j + 1;
+ if (k <= _size && lessThan(heap[k], heap[j])) {
+ j = k;
+ }
+ while (j <= _size && lessThan(heap[j],node)) {
+ heap[i] = heap[j]; // shift up child
+ i = j;
+ j = i << 1;
+ k = j + 1;
+ if (k <= _size && lessThan(heap[k], heap[j])) {
+ j = k;
+ }
+ }
+ heap[i] = node; // install saved node
+}
+
+void HitQueue::adjustTop(){
+ downHeap();
+}
+size_t HitQueue::size(){
+ return _size;
+}
+
+struct ScoreDoc& HitQueue::top(){
+ if ( _size == 0 )
+ _CLTHROWA(CL_ERR_IndexOutOfBounds, "Attempted to access empty hitqueue::top");
+ return heap[1];
+}
+
+void HitQueue::put(struct ScoreDoc& element){
+ if ( _size>=maxSize )
+ _CLTHROWA(CL_ERR_IndexOutOfBounds,"add is out of bounds");
+
+ _size++;
+ heap[_size] = element;
+ upHeap();
+}
+
+ScoreDoc HitQueue::pop(){
+ if (_size > 0) {
+ ScoreDoc result = heap[1]; // save first value
+ heap[1] = heap[_size]; // move last to first
+
+ _size--;
+ downHeap(); // adjust heap
+ return result;
+ } else
+ _CLTHROWA(CL_ERR_IndexOutOfBounds, "Attempted to access empty hitqueue::top");
+}
+
+bool HitQueue::insert(struct ScoreDoc& element){
+ if(_size < maxSize){
+ put(element);
+ return true;
+ }else if(_size > 0 && !lessThan(element, heap[1])){
+ heap[1] = element;
+ adjustTop();
+ return true;
+ }else
+ return false;
+}
+
+HitQueue::HitQueue(const int32_t maxSize){
+ _size = 0;
+ this->maxSize = maxSize;
+ int32_t heapSize = maxSize + 1;
+ heap = _CL_NEWARRAY(ScoreDoc,heapSize);
+}
+HitQueue::~HitQueue(){
+ _CLDELETE_ARRAY(heap);
+}
+
+bool HitQueue::lessThan(struct ScoreDoc& hitA, struct ScoreDoc& hitB){
+ if (hitA.score == hitB.score)
+ return hitA.doc > hitB.doc;
+ else
+ return hitA.score < hitB.score;
+}
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/HitQueue.h b/3rdparty/clucene/src/CLucene/search/HitQueue.h
new file mode 100644
index 000000000..0bd196a7f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/HitQueue.h
@@ -0,0 +1,55 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_HitQueue_
+#define _lucene_search_HitQueue_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "SearchHeader.h"
+
+CL_NS_DEF(search)
+
+/**
+* An optimised PriorityQueue which takes ScoreDoc structs. Some by-ref passing
+* and memory related optimisations have been done.
+*/
+class HitQueue: LUCENE_BASE {
+private:
+ ScoreDoc* heap;
+ size_t _size;
+ size_t maxSize;
+
+ void upHeap();
+ void downHeap();
+
+protected:
+ bool lessThan(struct ScoreDoc& hitA, struct ScoreDoc& hitB);
+
+public:
+ void adjustTop();
+ struct ScoreDoc& top();
+ void put(struct ScoreDoc& element);
+ ScoreDoc pop();
+ /**
+ * Adds element to the PriorityQueue in log(size) time if either
+ * the PriorityQueue is not full, or not lessThan(element, top()).
+ * @param element
+ * @return true if element is added, false otherwise.
+ */
+ bool insert(struct ScoreDoc& element);
+ /**
+ * Returns the number of elements currently stored in the PriorityQueue.
+ */
+ size_t size();
+ HitQueue(const int32_t maxSize);
+ ~HitQueue();
+
+};
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/Hits.cpp b/3rdparty/clucene/src/CLucene/search/Hits.cpp
new file mode 100644
index 000000000..38c489f44
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Hits.cpp
@@ -0,0 +1,174 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+
+#include "SearchHeader.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/index/IndexReader.h"
+#include "Filter.h"
+#include "CLucene/search/SearchHeader.h"
+
+CL_NS_USE(document)
+CL_NS_USE(util)
+CL_NS_USE(index)
+
+CL_NS_DEF(search)
+
+ HitDoc::HitDoc(const qreal s, const int32_t i)
+ {
+ //Func - Constructor
+ //Pre - true
+ //Post - The instance has been created
+
+ next = NULL;
+ prev = NULL;
+ doc = NULL;
+ score = s;
+ id = i;
+ }
+
+ HitDoc::~HitDoc(){
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ _CLDELETE(doc);
+ }
+
+
+ Hits::Hits(Searcher* s, Query* q, Filter* f, const Sort* _sort):
+ query(q), searcher(s), filter(f), sort(_sort)
+ {
+ //Func - Constructor
+ //Pre - s contains a valid reference to a searcher s
+ // q contains a valid reference to a Query
+ // f is NULL or contains a pointer to a filter
+ //Post - The instance has been created
+
+ _length = 0;
+ first = NULL;
+ last = NULL;
+ numDocs = 0;
+ maxDocs = 200;
+
+ //retrieve 100 initially
+ getMoreDocs(50);
+ }
+
+ Hits::~Hits(){
+
+ }
+ int32_t Hits::length() const {
+ return _length;
+ }
+
+ Document& Hits::doc(const int32_t n){
+ HitDoc* hitDoc = getHitDoc(n);
+
+ // Update LRU cache of documents
+ remove(hitDoc); // remove from list, if there
+ addToFront(hitDoc); // add to front of list
+ if (numDocs > maxDocs) { // if cache is full
+ HitDoc* oldLast = last;
+ remove(last); // flush last
+
+ _CLDELETE( oldLast->doc );
+ oldLast->doc = NULL;
+ }
+
+ if (hitDoc->doc == NULL){
+ hitDoc->doc = _CLNEW Document;
+ searcher->doc(hitDoc->id, hitDoc->doc); // cache miss: read document
+ }
+
+ return *hitDoc->doc;
+ }
+
+ int32_t Hits::id (const int32_t n){
+ return getHitDoc(n)->id;
+ }
+
+ qreal Hits::score(const int32_t n){
+ return getHitDoc(n)->score;
+ }
+
+ void Hits::getMoreDocs(const size_t m){
+ size_t _min = m;
+ {
+ size_t nHits = hitDocs.size();
+ if ( nHits > _min)
+ _min = nHits;
+ }
+
+ size_t n = _min * 2; // double # retrieved
+ TopDocs* topDocs = NULL;
+ if ( sort==NULL )
+ topDocs = (TopDocs*)((Searchable*)searcher)->_search(query, filter, n);
+ else
+ topDocs = (TopDocs*)((Searchable*)searcher)->_search(query, filter, n, sort);
+ _length = topDocs->totalHits;
+ ScoreDoc* scoreDocs = topDocs->scoreDocs;
+ int32_t scoreDocsLength = topDocs->scoreDocsLength;
+
+ qreal scoreNorm = 1.0f;
+ //Check that scoreDocs is a valid pointer before using it
+ if (scoreDocs != NULL){
+ if (_length > 0 && scoreDocs[0].score > 1.0f){
+ scoreNorm = 1.0f / scoreDocs[0].score;
+ }
+
+ int32_t end = scoreDocsLength < _length ? scoreDocsLength : _length;
+ for (int32_t i = hitDocs.size(); i < end; i++) {
+ hitDocs.push_back(_CLNEW HitDoc(scoreDocs[i].score*scoreNorm, scoreDocs[i].doc));
+ }
+ }
+
+ _CLDELETE(topDocs);
+ }
+
+ HitDoc* Hits::getHitDoc(const size_t n){
+ if (n >= _length){
+ TCHAR buf[100];
+ _sntprintf(buf, 100,_T("Not a valid hit number: %d"),n);
+ _CLTHROWT(CL_ERR_IndexOutOfBounds, buf );
+ }
+ if (n >= hitDocs.size())
+ getMoreDocs(n);
+
+ return hitDocs[n];
+ }
+
+ void Hits::addToFront(HitDoc* hitDoc) { // insert at front of cache
+ if (first == NULL)
+ last = hitDoc;
+ else
+ first->prev = hitDoc;
+
+ hitDoc->next = first;
+ first = hitDoc;
+ hitDoc->prev = NULL;
+
+ numDocs++;
+ }
+
+ void Hits::remove(const HitDoc* hitDoc) { // remove from cache
+ if (hitDoc->doc == NULL) // it's not in the list
+ return; // abort
+
+ if (hitDoc->next == NULL)
+ last = hitDoc->prev;
+ else
+ hitDoc->next->prev = hitDoc->prev;
+
+ if (hitDoc->prev == NULL)
+ first = hitDoc->next;
+ else
+ hitDoc->prev->next = hitDoc->next;
+
+ numDocs--;
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/IndexSearcher.cpp b/3rdparty/clucene/src/CLucene/search/IndexSearcher.cpp
new file mode 100644
index 000000000..c948cfa4b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/IndexSearcher.cpp
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "IndexSearcher.h"
+
+#include "SearchHeader.h"
+#include "Scorer.h"
+#include "FieldDocSortedHitQueue.h"
+#include "CLucene/store/Directory.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/index/Term.h"
+#include "CLucene/util/BitSet.h"
+#include "FieldSortedHitQueue.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_USE(document)
+
+CL_NS_DEF(search)
+
+class SimpleTopDocsCollector : public HitCollector
+{
+private:
+ qreal minScore;
+ const CL_NS(util)::BitSet* bits;
+ HitQueue* hq;
+ size_t nDocs;
+ int32_t* totalHits;
+
+public:
+ SimpleTopDocsCollector(const CL_NS(util)::BitSet* bs, HitQueue* hitQueue,
+ int32_t* totalhits, size_t ndocs, const qreal ms=-1.0f)
+ : minScore(ms),
+ bits(bs),
+ hq(hitQueue),
+ nDocs(ndocs),
+ totalHits(totalhits) {}
+ ~SimpleTopDocsCollector() {}
+
+ void collect(const int32_t doc, const qreal score)
+ {
+ if (score > 0.0f // ignore zeroed buckets
+ && (bits == NULL || bits->get(doc))) { // skip docs not in bits
+ ++totalHits[0];
+ if (hq->size() < nDocs || (minScore==-1.0f || score >= minScore)) {
+ ScoreDoc sd = {doc, score};
+ hq->insert(sd); // update hit queue
+ if ( minScore != -1.0f )
+ minScore = hq->top().score; // maintain minScore
+ }
+ }
+ }
+};
+
+class SortedTopDocsCollector : public HitCollector
+{
+private:
+ const CL_NS(util)::BitSet* bits;
+ FieldSortedHitQueue* hq;
+ size_t nDocs;
+ int32_t* totalHits;
+public:
+ SortedTopDocsCollector(const CL_NS(util)::BitSet* bs,
+ FieldSortedHitQueue* hitQueue, int32_t* totalhits, size_t _nDocs)
+ : bits(bs),
+ hq(hitQueue),
+ nDocs(_nDocs),
+ totalHits(totalhits)
+ {
+ }
+ ~SortedTopDocsCollector() {}
+
+ void collect(const int32_t doc, const qreal score)
+ {
+ if (score > 0.0f && // ignore zeroed buckets
+ (bits==NULL || bits->get(doc))) { // skip docs not in bits
+ ++totalHits[0];
+ // TODO: see jlucene way... with fields def???
+ FieldDoc* fd = _CLNEW FieldDoc(doc, score);
+ if ( !hq->insert(fd) ) // update hit queue
+ _CLDELETE(fd);
+ }
+ }
+};
+
+class SimpleFilteredCollector : public HitCollector
+{
+private:
+ CL_NS(util)::BitSet* bits;
+ HitCollector* results;
+public:
+ SimpleFilteredCollector(CL_NS(util)::BitSet* bs, HitCollector* collector)
+ : bits(bs),
+ results(collector) {}
+ ~SimpleFilteredCollector() {}
+
+protected:
+ void collect(const int32_t doc, const qreal score)
+ {
+ // skip docs not in bits
+ if (bits->get(doc))
+ results->collect(doc, score);
+ }
+};
+
+
+IndexSearcher::IndexSearcher(const QString& path)
+{
+ //Func - Constructor
+ // Creates a searcher searching the index in the named directory.
+ //Pre - path != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(!path.isEmpty(), "path is NULL");
+
+ reader = IndexReader::open(path);
+ readerOwner = true;
+}
+
+IndexSearcher::IndexSearcher(CL_NS(store)::Directory* directory)
+{
+ //Func - Constructor
+ // Creates a searcher searching the index in the specified directory.
+ //Pre - path != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(directory != NULL, "directory is NULL");
+
+ reader = IndexReader::open(directory);
+ readerOwner = true;
+}
+
+IndexSearcher::IndexSearcher(IndexReader* r)
+{
+ //Func - Constructor
+ // Creates a searcher searching the index with the provide IndexReader
+ //Pre - path != NULL
+ //Post - The instance has been created
+
+ reader = r;
+ readerOwner = false;
+}
+
+IndexSearcher::~IndexSearcher()
+{
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ close();
+}
+
+void IndexSearcher::close()
+{
+ //Func - Frees resources associated with this Searcher.
+ //Pre - true
+ //Post - The resources associated have been freed
+ if (readerOwner && reader){
+ reader->close();
+ _CLDELETE(reader);
+ }
+}
+
+// inherit javadoc
+int32_t IndexSearcher::docFreq(const Term* term) const
+{
+ //Func -
+ //Pre - reader != NULL
+ //Post -
+
+ CND_PRECONDITION(reader != NULL, "reader is NULL");
+ return reader->docFreq(term);
+}
+
+// inherit javadoc
+bool IndexSearcher::doc(int32_t i, CL_NS(document)::Document* d)
+{
+ //Func - Retrieves i-th document found
+ // For use by HitCollector implementations.
+ //Pre - reader != NULL
+ //Post - The i-th document has been returned
+
+ CND_PRECONDITION(reader != NULL, "reader is NULL");
+ return reader->document(i,d);
+}
+
+// inherit javadoc
+int32_t IndexSearcher::maxDoc() const
+{
+ //Func - Return total number of documents including the ones marked deleted
+ //Pre - reader != NULL
+ //Post - The total number of documents including the ones marked deleted
+ // has been returned
+
+ CND_PRECONDITION(reader != NULL, "reader is NULL");
+ return reader->maxDoc();
+}
+
+TopDocs* IndexSearcher::_search(Query* query, Filter* filter, const int32_t nDocs)
+{
+ //Func -
+ //Pre - reader != NULL
+ //Post -
+
+ CND_PRECONDITION(reader != NULL, "reader is NULL");
+ CND_PRECONDITION(query != NULL, "query is NULL");
+
+ Weight* weight = query->weight(this);
+ Scorer* scorer = weight->scorer(reader);
+ if (scorer == NULL){
+ return _CLNEW TopDocs(0, NULL, 0);
+ }
+
+ BitSet* bits = filter != NULL ? filter->bits(reader) : NULL;
+ HitQueue* hq = _CLNEW HitQueue(nDocs);
+
+ //Check hq has been allocated properly
+ CND_CONDITION(hq != NULL, "Could not allocate memory for HitQueue hq");
+
+ int32_t* totalHits = _CL_NEWARRAY(int32_t,1);
+ totalHits[0] = 0;
+
+ SimpleTopDocsCollector hitCol(bits,hq,totalHits,nDocs,0.0f);
+ scorer->score( &hitCol );
+ _CLDELETE(scorer);
+
+ int32_t scoreDocsLength = hq->size();
+
+ ScoreDoc* scoreDocs = _CL_NEWARRAY(ScoreDoc,scoreDocsLength);
+
+ for (int32_t i = scoreDocsLength-1; i >= 0; --i) // put docs in array
+ scoreDocs[i] = hq->pop();
+
+ int32_t totalHitsInt = totalHits[0];
+
+ _CLDELETE(hq);
+ if ( bits != NULL && filter->shouldDeleteBitSet(bits) )
+ _CLDELETE(bits);
+ _CLDELETE_ARRAY(totalHits);
+ Query* wq = weight->getQuery();
+ if ( query != wq ) //query was re-written
+ _CLLDELETE(wq);
+ _CLDELETE(weight);
+
+ return _CLNEW TopDocs(totalHitsInt, scoreDocs, scoreDocsLength);
+}
+
+// inherit javadoc
+TopFieldDocs* IndexSearcher::_search(Query* query, Filter* filter,
+ const int32_t nDocs, const Sort* sort)
+{
+ CND_PRECONDITION(reader != NULL, "reader is NULL");
+ CND_PRECONDITION(query != NULL, "query is NULL");
+
+ Weight* weight = query->weight(this);
+ Scorer* scorer = weight->scorer(reader);
+ if (scorer == NULL) {
+ return _CLNEW TopFieldDocs(0, NULL, 0, NULL );
+ }
+
+ BitSet* bits = filter != NULL ? filter->bits(reader) : NULL;
+ FieldSortedHitQueue hq(reader, sort->getSort(), nDocs);
+ int32_t* totalHits = _CL_NEWARRAY(int32_t,1);
+ totalHits[0]=0;
+
+ SortedTopDocsCollector hitCol(bits,&hq,totalHits,nDocs);
+ scorer->score(&hitCol);
+ _CLDELETE(scorer);
+
+ int32_t hqLen = hq.size();
+ FieldDoc** fieldDocs = _CL_NEWARRAY(FieldDoc*,hqLen);
+ for (int32_t i = hqLen-1; i >= 0; --i){ // put docs in array
+ fieldDocs[i] = hq.fillFields (hq.pop());
+ }
+
+ Query* wq = weight->getQuery();
+ if ( query != wq ) //query was re-written
+ _CLLDELETE(wq);
+ _CLDELETE(weight);
+
+ SortField** hqFields = hq.getFields();
+ hq.setFields(NULL); //move ownership of memory over to TopFieldDocs
+ int32_t totalHits0 = totalHits[0];
+ if ( bits != NULL && filter->shouldDeleteBitSet(bits) )
+ _CLDELETE(bits);
+ _CLDELETE_ARRAY(totalHits);
+ return _CLNEW TopFieldDocs(totalHits0, fieldDocs, hqLen, hqFields );
+}
+
+void IndexSearcher::_search(Query* query, Filter* filter, HitCollector* results)
+{
+ //Func - _search an index and fetch the results
+ // Applications should only use this if they need all of the
+ // matching documents. The high-level search API (search(Query))
+ // is usually more efficient, as it skips non-high-scoring hits.
+ //Pre - query is a valid reference to a query filter may or may not be NULL
+ // results is a valid reference to a HitCollector and used to store the results
+ //Post - filter if non-NULL, a bitset used to eliminate some documents
+
+ CND_PRECONDITION(reader != NULL, "reader is NULL");
+ CND_PRECONDITION(query != NULL, "query is NULL");
+
+ BitSet* bits = NULL;
+ SimpleFilteredCollector* fc = NULL;
+
+ if (filter != NULL){
+ bits = filter->bits(reader);
+ fc = _CLNEW SimpleFilteredCollector(bits, results);
+ }
+
+ Weight* weight = query->weight(this);
+ Scorer* scorer = weight->scorer(reader);
+ if (scorer != NULL) {
+ if (fc == NULL){
+ scorer->score(results);
+ }else{
+ scorer->score((HitCollector*)fc);
+ }
+ _CLDELETE(scorer);
+ }
+
+ _CLDELETE(fc);
+ _CLDELETE(weight);
+ if ( bits != NULL && filter->shouldDeleteBitSet(bits) )
+ _CLDELETE(bits);
+}
+
+Query* IndexSearcher::rewrite(Query* original)
+{
+ Query* query = original;
+ Query* last = original;
+ for (Query* rewrittenQuery = query->rewrite(reader);
+ rewrittenQuery != query;
+ rewrittenQuery = query->rewrite(reader)) {
+ query = rewrittenQuery;
+ if ( query != last && last != original) {
+ _CLDELETE(last);
+ }
+ last = query;
+ }
+ return query;
+}
+
+void IndexSearcher::explain(Query* query, int32_t doc, Explanation* ret)
+{
+ Weight* weight = query->weight(this);
+ weight->explain(reader, doc, ret);
+
+ Query* wq = weight->getQuery();
+ if ( query != wq ) //query was re-written
+ _CLLDELETE(wq);
+ _CLDELETE(weight);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/IndexSearcher.h b/3rdparty/clucene/src/CLucene/search/IndexSearcher.h
new file mode 100644
index 000000000..307e0266d
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/IndexSearcher.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_search_IndexSearcher_
+#define _lucene_search_IndexSearcher_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "SearchHeader.h"
+#include "CLucene/store/Directory.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/index/Term.h"
+#include "CLucene/util/BitSet.h"
+#include "HitQueue.h"
+#include "FieldSortedHitQueue.h"
+
+CL_NS_DEF(search)
+/** Implements search over a single IndexReader.
+*
+* <p>Applications usually need only call the inherited {@link search(Query*)}
+* or {@link search(Query*,Filter*)} methods.
+*/
+class IndexSearcher:public Searcher{
+ CL_NS(index)::IndexReader* reader;
+ bool readerOwner;
+
+public:
+ /// Creates a searcher searching the index in the named directory.
+ IndexSearcher(const QString& path);
+
+ /// Creates a searcher searching the index in the specified directory.
+ IndexSearcher(CL_NS(store)::Directory* directory);
+
+ /// Creates a searcher searching the provided index.
+ IndexSearcher(CL_NS(index)::IndexReader* r);
+
+ ~IndexSearcher();
+
+ /// Frees resources associated with this Searcher.
+ void close();
+
+ int32_t docFreq(const CL_NS(index)::Term* term) const;
+
+ bool doc(int32_t i, CL_NS(document)::Document* document);
+
+ int32_t maxDoc() const;
+
+ TopDocs* _search(Query* query, Filter* filter, const int32_t nDocs);
+ TopFieldDocs* _search(Query* query, Filter* filter, const int32_t nDocs,
+ const Sort* sort);
+
+ void _search(Query* query, Filter* filter, HitCollector* results);
+
+ CL_NS(index)::IndexReader* getReader() {
+ return reader; }
+
+ Query* rewrite(Query* original);
+ void explain(Query* query, int32_t doc, Explanation* ret);
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/MultiSearcher.cpp b/3rdparty/clucene/src/CLucene/search/MultiSearcher.cpp
new file mode 100644
index 000000000..bed7f0d61
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/MultiSearcher.cpp
@@ -0,0 +1,227 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "MultiSearcher.h"
+
+#include "SearchHeader.h"
+#include "HitQueue.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/index/Term.h"
+#include "FieldDocSortedHitQueue.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_USE(document)
+
+CL_NS_DEF(search)
+
+ /** Creates a searcher which searches <i>searchers</i>. */
+ MultiSearcher::MultiSearcher(Searchable** _searchables):
+ _maxDoc(0) {
+ searchablesLen = 0;
+ while ( _searchables[searchablesLen] != NULL )
+ ++searchablesLen;
+
+ searchables=_CL_NEWARRAY(Searchable*,searchablesLen+1);
+ starts = _CL_NEWARRAY(int32_t,searchablesLen + 1); // build starts array
+ for (int32_t i = 0; i < searchablesLen; ++i) {
+ searchables[i]=_searchables[i];
+ starts[i] = _maxDoc;
+ _maxDoc += searchables[i]->maxDoc(); // compute maxDocs
+ }
+ starts[searchablesLen] = _maxDoc;
+ }
+
+ MultiSearcher::~MultiSearcher() {
+ _CLDELETE_ARRAY(searchables);
+ _CLDELETE_ARRAY(starts);
+ }
+
+
+ // inherit javadoc
+ void MultiSearcher::close() {
+ for (int32_t i = 0; i < searchablesLen; ++i){
+ searchables[i]->close();
+ searchables[i]=NULL;
+ }
+ }
+
+ int32_t MultiSearcher::docFreq(const Term* term) const {
+ int32_t docFreq = 0;
+ for (int32_t i = 0; i < searchablesLen; ++i)
+ docFreq += searchables[i]->docFreq(term);
+ return docFreq;
+ }
+
+ /** For use by {@link HitCollector} implementations. */
+ bool MultiSearcher::doc(int32_t n, Document* d) {
+ int32_t i = subSearcher(n); // find searcher index
+ return searchables[i]->doc(n - starts[i], d); // dispatch to searcher
+ }
+
+ int32_t MultiSearcher::searcherIndex(int32_t n) const{
+ return subSearcher(n);
+ }
+
+ /** Returns index of the searcher for document <code>n</code> in the array
+ * used to construct this searcher. */
+ int32_t MultiSearcher::subSearcher(int32_t n) const{
+ // replace w/ call to Arrays.binarySearch in Java 1.2
+ int32_t lo = 0; // search starts array
+ int32_t hi = searchablesLen - 1; // for first element less
+ // than n, return its index
+ int32_t mid,midValue;
+ while (hi >= lo) {
+ mid = (lo + hi) >> 1;
+ midValue = starts[mid];
+ if (n < midValue)
+ hi = mid - 1;
+ else if (n > midValue)
+ lo = mid + 1;
+ else{ // found a match
+ while (mid+1 < searchablesLen && starts[mid+1] == midValue) {
+ ++mid; // scan to last match
+ }
+ return mid;
+ }
+ }
+ return hi;
+ }
+
+ /** Returns the document number of document <code>n</code> within its
+ * sub-index. */
+ int32_t MultiSearcher::subDoc(int32_t n) const{
+ return n - starts[subSearcher(n)];
+ }
+
+ int32_t MultiSearcher::maxDoc() const{
+ return _maxDoc;
+ }
+
+ TopDocs* MultiSearcher::_search(Query* query, Filter* filter, const int32_t nDocs) {
+ HitQueue* hq = _CLNEW HitQueue(nDocs);
+ int32_t totalHits = 0;
+ TopDocs* docs;
+ int32_t j;
+ ScoreDoc* scoreDocs;
+ for (int32_t i = 0; i < searchablesLen; i++) { // search each searcher
+ docs = searchables[i]->_search(query, filter, nDocs);
+ totalHits += docs->totalHits; // update totalHits
+ scoreDocs = docs->scoreDocs;
+ for ( j = 0; j <docs->scoreDocsLength; ++j) { // merge scoreDocs int_to hq
+ scoreDocs[j].doc += starts[i]; // convert doc
+ if ( !hq->insert(scoreDocs[j]))
+ break; // no more scores > minScore
+ }
+
+ _CLDELETE(docs);
+ }
+
+ int32_t scoreDocsLen = hq->size();
+ scoreDocs = _CL_NEWARRAY(ScoreDoc, scoreDocsLen);
+ {//MSVC 6 scope fix
+ for (int32_t i = scoreDocsLen-1; i >= 0; --i) // put docs in array
+ scoreDocs[i] = hq->pop();
+ }
+
+ //cleanup
+ _CLDELETE(hq);
+
+ return _CLNEW TopDocs(totalHits, scoreDocs, scoreDocsLen);
+ }
+
+ /** Lower-level search API.
+ *
+ * <p>{@link HitCollector#collect(int32_t,qreal)} is called for every non-zero
+ * scoring document.
+ *
+ * <p>Applications should only use this if they need <i>all</i> of the
+ * matching documents. The high-level search API ({@link
+ * Searcher#search(Query)}) is usually more efficient, as it skips
+ * non-high-scoring hits.
+ *
+ * @param query to match documents
+ * @param filter if non-null, a bitset used to eliminate some documents
+ * @param results to receive hits
+ */
+ void MultiSearcher::_search(Query* query, Filter* filter, HitCollector* results){
+ for (int32_t i = 0; i < searchablesLen; ++i) {
+ /* DSR:CL_BUG: Old implementation leaked and was misconceived. We need
+ ** to have the original HitCollector ($results) collect *all* hits;
+ ** the MultiHitCollector instantiated below serves only to adjust
+ ** (forward by starts[i]) the docNo passed to $results.
+ ** Old implementation instead created a sort of linked list of
+ ** MultiHitCollectors that applied the adjustments in $starts
+ ** cumulatively (and was never deleted). */
+ HitCollector *docNoAdjuster = _CLNEW MultiHitCollector(results, starts[i]);
+ searchables[i]->_search(query, filter, docNoAdjuster);
+ _CLDELETE(docNoAdjuster);
+ }
+ }
+
+ TopFieldDocs* MultiSearcher::_search (Query* query, Filter* filter, const int32_t n, const Sort* sort){
+ FieldDocSortedHitQueue* hq = NULL;
+ int32_t totalHits = 0;
+ TopFieldDocs* docs;
+ int32_t j;
+ FieldDoc** fieldDocs;
+
+ for (int32_t i = 0; i < searchablesLen; ++i) { // search each searcher
+ docs = searchables[i]->_search (query, filter, n, sort);
+ if (hq == NULL){
+ hq = _CLNEW FieldDocSortedHitQueue (docs->fields, n);
+ docs->fields = NULL; //hit queue takes fields memory
+ }
+
+ totalHits += docs->totalHits; // update totalHits
+ fieldDocs = docs->fieldDocs;
+ for(j = 0;j<docs->scoreDocsLength;++j){ // merge scoreDocs into hq
+ fieldDocs[j]->scoreDoc.doc += starts[i]; // convert doc
+ if (!hq->insert (fieldDocs[j]) )
+ break; // no more scores > minScore
+ }
+ for ( int32_t x=0;x<j;++x )
+ fieldDocs[x]=NULL; //move ownership of FieldDoc to the hitqueue
+
+ _CLDELETE(docs);
+ }
+
+ int32_t hqlen = hq->size();
+ fieldDocs = _CL_NEWARRAY(FieldDoc*,hqlen);
+ for (j = hqlen - 1; j >= 0; j--) // put docs in array
+ fieldDocs[j] = hq->pop();
+
+ SortField** hqFields = hq->getFields();
+ hq->setFields(NULL); //move ownership of memory over to TopFieldDocs
+ _CLDELETE(hq);
+
+ return _CLNEW TopFieldDocs (totalHits, fieldDocs, hqlen, hqFields);
+ }
+
+ Query* MultiSearcher::rewrite(Query* original) {
+ Query** queries = _CL_NEWARRAY(Query*,searchablesLen+1);
+ for (int32_t i = 0; i < searchablesLen; ++i)
+ queries[i] = searchables[i]->rewrite(original);
+ queries[searchablesLen]=NULL;
+ return original->combine(queries);
+ }
+
+ void MultiSearcher::explain(Query* query, int32_t doc, Explanation* ret) {
+ int32_t i = subSearcher(doc); // find searcher index
+ searchables[i]->explain(query,doc-starts[i], ret); // dispatch to searcher
+ }
+
+ MultiHitCollector::MultiHitCollector(HitCollector* _results, int32_t _start):
+ results(_results),
+ start(_start) {
+ }
+
+ void MultiHitCollector::collect(const int32_t doc, const qreal score) {
+ results->collect(doc + start, score);
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/MultiSearcher.h b/3rdparty/clucene/src/CLucene/search/MultiSearcher.h
new file mode 100644
index 000000000..1021fbbec
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/MultiSearcher.h
@@ -0,0 +1,95 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_multisearcher
+#define _lucene_search_multisearcher
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "SearchHeader.h"
+#include "CLucene/document/Document.h"
+#include "CLucene/index/Term.h"
+
+CL_NS_DEF(search)
+
+ class MultiHitCollector: public HitCollector{
+ private:
+ HitCollector* results;
+ int32_t start;
+ public:
+ MultiHitCollector(HitCollector* _results, int32_t _start);
+ void collect(const int32_t doc, const qreal score) ;
+ };
+
+
+ /** Implements search over a set of <code>Searchables</code>.
+ *
+ * <p>Applications usually need only call the inherited {@link #search(Query)}
+ * or {@link #search(Query,Filter)} methods.
+ */
+ class MultiSearcher: public Searcher {
+ private:
+ Searchable** searchables;
+ int32_t searchablesLen;
+ int32_t* starts;
+ int32_t _maxDoc;
+ protected:
+ int32_t* getStarts() {
+ return starts;
+ }
+
+ public:
+ /** Creates a searcher which searches <i>Searchables</i>. */
+ MultiSearcher(Searchable** searchables);
+
+ ~MultiSearcher();
+
+ /** Frees resources associated with this <code>Searcher</code>. */
+ void close() ;
+
+ int32_t docFreq(const CL_NS(index)::Term* term) const ;
+
+ /** For use by {@link HitCollector} implementations. */
+ bool doc(int32_t n, CL_NS(document)::Document* document);
+
+ /** For use by {@link HitCollector} implementations to identify the
+ * index of the sub-searcher that a particular hit came from. */
+ int32_t searcherIndex(int32_t n) const;
+
+ int32_t subSearcher(int32_t n) const;
+
+ int32_t subDoc(int32_t n) const;
+
+ int32_t maxDoc() const;
+
+ TopDocs* _search(Query* query, Filter* filter, const int32_t nDocs) ;
+
+ TopFieldDocs* _search (Query* query, Filter* filter, const int32_t n, const Sort* sort);
+
+ /** Lower-level search API.
+ *
+ * <p>{@link HitCollector#collect(int32_t,qreal)} is called for every non-zero
+ * scoring document.
+ *
+ * <p>Applications should only use this if they need <i>all</i> of the
+ * matching documents. The high-level search API ({@link
+ * Searcher#search(Query)}) is usually more efficient, as it skips
+ * non-high-scoring hits.
+ *
+ * @param query to match documents
+ * @param filter if non-null, a bitset used to eliminate some documents
+ * @param results to receive hits
+ */
+ void _search(Query* query, Filter* filter, HitCollector* results);
+
+ Query* rewrite(Query* original);
+ void explain(Query* query, int32_t doc, Explanation* ret);
+ };
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/MultiTermQuery.cpp b/3rdparty/clucene/src/CLucene/search/MultiTermQuery.cpp
new file mode 100644
index 000000000..3bf8d7a26
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/MultiTermQuery.cpp
@@ -0,0 +1,98 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "MultiTermQuery.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+/** Constructs a query for terms matching <code>term</code>. */
+
+ MultiTermQuery::MultiTermQuery(Term* t){
+ //Func - Constructor
+ //Pre - t != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(t != NULL, "t is NULL");
+
+ term = _CL_POINTER(t);
+
+ }
+ MultiTermQuery::MultiTermQuery(const MultiTermQuery& clone):
+ Query(clone)
+ {
+ term = _CLNEW Term(clone.getTerm(false),clone.getTerm(false)->text());
+ }
+
+ MultiTermQuery::~MultiTermQuery(){
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ _CLDECDELETE(term);
+ }
+
+ Term* MultiTermQuery::getTerm(bool pointer) const{
+ if ( pointer )
+ return _CL_POINTER(term);
+ else
+ return term;
+ }
+
+ Query* MultiTermQuery::rewrite(IndexReader* reader) {
+ FilteredTermEnum* enumerator = getEnum(reader);
+ BooleanQuery* query = _CLNEW BooleanQuery();
+ try {
+ do {
+ Term* t = enumerator->term(false);
+ if (t != NULL) {
+ TermQuery* tq = _CLNEW TermQuery(t); // found a match
+ tq->setBoost(getBoost() * enumerator->difference()); // set the boost
+ query->add(tq,true, false, false); // add to q
+ }
+ } while (enumerator->next());
+ } _CLFINALLY ( enumerator->close(); _CLDELETE(enumerator) );
+
+ //if we only added one clause and the clause is not prohibited then
+ //we can just return the query
+ if (query->getClauseCount() == 1) { // optimize 1-clause queries
+ BooleanClause* c=0;
+ query->getClauses(&c);
+
+ if (!c->prohibited) { // just return clause
+ c->deleteQuery=false;
+ Query* ret = c->query;
+
+ _CLDELETE(query);
+ return ret;
+ }
+ }
+ return query;
+ }
+
+ Query* MultiTermQuery::combine(Query** queries) {
+ return Query::mergeBooleanQueries(queries);
+ }
+
+ /** Prints a user-readable version of this query. */
+ TCHAR* MultiTermQuery::toString(const TCHAR* field) const{
+ StringBuffer buffer;
+
+ if ( field==NULL || _tcscmp(term->field(),field)!=0 ) {
+ buffer.append(term->field());
+ buffer.append( _T(":"));
+ }
+ buffer.append(term->text());
+ if (getBoost() != 1.0f) {
+ buffer.appendChar ( '^' );
+ buffer.appendFloat( getBoost(),1);
+ }
+ return buffer.toString();
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/MultiTermQuery.h b/3rdparty/clucene/src/CLucene/search/MultiTermQuery.h
new file mode 100644
index 000000000..d37645359
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/MultiTermQuery.h
@@ -0,0 +1,62 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_MultiTermQuery_
+#define _lucene_search_MultiTermQuery_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/StringBuffer.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+#include "FilteredTermEnum.h"
+#include "SearchHeader.h"
+#include "BooleanQuery.h"
+#include "TermQuery.h"
+
+CL_NS_DEF(search)
+ /**
+ * A {@link Query} that matches documents containing a subset of terms provided
+ * by a {@link FilteredTermEnum} enumeration.
+ * <P>
+ * <code>MultiTermQuery</code> is not designed to be used by itself.
+ * <BR>
+ * The reason being that it is not intialized with a {@link FilteredTermEnum}
+ * enumeration. A {@link FilteredTermEnum} enumeration needs to be provided.
+ * <P>
+ * For example, {@link WildcardQuery} and {@link FuzzyQuery} extend
+ * <code>MultiTermQuery</code> to provide {@link WildcardTermEnum} and
+ * {@link FuzzyTermEnum}, respectively.
+ */
+ class MultiTermQuery: public Query {
+ private:
+ CL_NS(index)::Term* term;
+ protected:
+ MultiTermQuery(const MultiTermQuery& clone);
+
+ /** Construct the enumeration to be used, expanding the pattern term. */
+ virtual FilteredTermEnum* getEnum(CL_NS(index)::IndexReader* reader) = 0;
+ public:
+ /** Constructs a query for terms matching <code>term</code>. */
+ MultiTermQuery(CL_NS(index)::Term* t);
+
+ virtual ~MultiTermQuery();
+
+ /** Returns the pattern term. */
+ CL_NS(index)::Term* getTerm(bool pointer=true) const;
+
+ Query* combine(Query** queries);
+
+ /** Prints a user-readable version of this query. */
+ TCHAR* toString(const TCHAR* field) const;
+
+ Query* rewrite(CL_NS(index)::IndexReader* reader);
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/PhrasePositions.cpp b/3rdparty/clucene/src/CLucene/search/PhrasePositions.cpp
new file mode 100644
index 000000000..7611056e7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PhrasePositions.cpp
@@ -0,0 +1,116 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "PhrasePositions.h"
+
+#include "CLucene/index/Terms.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+ PhrasePositions::PhrasePositions(TermPositions* Tp, const int32_t OffSet){
+ //Func - Constructor
+ //Pre - t != NULL
+ // OffSet != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(Tp != NULL,"Tp is NULL");
+ CND_PRECONDITION(OffSet >= 0 ,"OffSet is a negative number");
+
+ tp = Tp;
+ offset = OffSet;
+ position = 0;
+ count = 0;
+ doc = 0;
+
+ _next = NULL;
+ }
+
+ PhrasePositions::~PhrasePositions(){
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been deleted
+
+ //delete next Phrase position and by doing that
+ //all PhrasePositions in the list
+ _CLDELETE(_next);
+
+ //Check if tp is valid
+ if ( tp != NULL ){
+ //Close TermPositions tp
+ tp->close();
+ _CLDELETE(tp);
+ }
+ }
+
+ bool PhrasePositions::next(){
+ //Func - Increments to next doc
+ //Pre - tp != NULL
+ //Post - if there was no next then doc = INT_MAX otherwise
+ // doc contains the current document number
+
+ CND_PRECONDITION(tp != NULL,"tp is NULL");
+
+ //Move to the next in TermPositions tp
+ if (!tp->next()) {
+ //There is no next so close the stream
+ tp->close();
+ //delete tp and reset tp to NULL
+ _CLVDELETE(tp); //todo: not a clucene object... should be
+ //Assign Doc sentinel value
+ doc = INT_MAX;
+ return false;
+ }else{
+ doc = tp->doc();
+ position = 0;
+ return true;
+ }
+ }
+ bool PhrasePositions::skipTo(int32_t target){
+ if (!tp->skipTo(target)) {
+ tp->close(); // close stream
+ doc = LUCENE_INT32_MAX_SHOULDBE; // sentinel value
+ return false;
+ }
+ doc = tp->doc();
+ position = 0;
+ return true;
+ }
+ void PhrasePositions::firstPosition(){
+ //Func - Read the first TermPosition
+ //Pre - tp != NULL
+ //Post -
+
+ CND_PRECONDITION(tp != NULL,"tp is NULL");
+
+ //read first pos
+ count = tp->freq();
+ //Move to the next TermPosition
+ nextPosition();
+ }
+
+ bool PhrasePositions::nextPosition(){
+ //Func - Move to the next position
+ //Pre - tp != NULL
+ //Post -
+
+ CND_PRECONDITION(tp != NULL,"tp is NULL");
+
+ if (count-- > 0) {
+ //read subsequent pos's
+ position = tp->nextPosition() - offset;
+
+ //Check position always bigger than or equal to 0
+ //bvk: todo, bug??? position < 0 occurs, cant figure out why,
+ //old version does it too and will fail the "SearchTest" test
+ //CND_CONDITION(position >= 0, "position has become a negative number");
+ return true;
+ }else{
+ return false;
+ }
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/PhrasePositions.h b/3rdparty/clucene/src/CLucene/search/PhrasePositions.h
new file mode 100644
index 000000000..b6c8437b9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PhrasePositions.h
@@ -0,0 +1,41 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_PhrasePositions_
+#define _lucene_search_PhrasePositions_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/Terms.h"
+
+CL_NS_DEF(search)
+
+ class PhrasePositions:LUCENE_BASE {
+ public:
+ int32_t doc; // current doc
+ int32_t position; // position in doc
+ int32_t count; // remaining pos in this doc
+ int32_t offset; // position in phrase
+ CL_NS(index)::TermPositions* tp; // stream of positions
+ PhrasePositions* _next; // used to make lists
+
+
+ //Constructor
+ PhrasePositions(CL_NS(index)::TermPositions* Tp, const int32_t o);
+ //Destructor
+ ~PhrasePositions();
+
+ bool next();
+ bool skipTo(int32_t target);
+
+ void firstPosition();
+
+ bool nextPosition();
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/PhraseQuery.cpp b/3rdparty/clucene/src/CLucene/search/PhraseQuery.cpp
new file mode 100644
index 000000000..899cb3cfe
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PhraseQuery.cpp
@@ -0,0 +1,463 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "PhraseQuery.h"
+
+#include "SearchHeader.h"
+#include "Scorer.h"
+#include "BooleanQuery.h"
+#include "TermQuery.h"
+
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+#include "CLucene/index/IndexReader.h"
+
+#include "CLucene/util/StringBuffer.h"
+#include "CLucene/util/VoidList.h"
+#include "CLucene/util/Arrays.h"
+
+#include "ExactPhraseScorer.h"
+#include "SloppyPhraseScorer.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+ PhraseQuery::PhraseQuery():
+ terms(false)
+ {
+ //Func - Constructor
+ //Pre - true
+ //Post - An empty PhraseQuery has been created
+
+ slop = 0;
+
+ field = NULL;
+ }
+ PhraseQuery::PhraseQuery(const PhraseQuery& clone):
+ Query(clone), terms(false)
+ {
+ slop = clone.slop;
+ field = clone.field;
+ int32_t size=clone.positions.size();
+ { //msvc6 scope fix
+ for ( int32_t i=0;i<size;i++ ){
+ int32_t n = clone.positions[i];
+ this->positions.push_back( n );
+ }
+ }
+ size=clone.terms.size();
+ { //msvc6 scope fix
+ for ( int32_t i=0;i<size;i++ ){
+ this->terms.push_back( _CL_POINTER(clone.terms[i]));
+ }
+ }
+ }
+ Query* PhraseQuery::clone() const{
+ return _CLNEW PhraseQuery(*this);
+ }
+ bool PhraseQuery::equals(CL_NS(search)::Query *other) const{
+ if (!(other->instanceOf(PhraseQuery::getClassName())))
+ return false;
+
+ PhraseQuery* pq = (PhraseQuery*)other;
+ bool ret = (this->getBoost() == pq->getBoost())
+ && (this->slop == pq->slop);
+
+ if ( ret ){
+ CLListEquals<CL_NS(index)::Term,Term::Equals,
+ const CL_NS(util)::CLVector<CL_NS(index)::Term*>,
+ const CL_NS(util)::CLVector<CL_NS(index)::Term*> > comp;
+ ret = comp.equals(&this->terms,&pq->terms);
+ }
+
+ if ( ret ){
+ CLListEquals<int32_t,Equals::Int32,
+ const CL_NS(util)::CLVector<int32_t,CL_NS(util)::Deletor::DummyInt32>,
+ const CL_NS(util)::CLVector<int32_t,CL_NS(util)::Deletor::DummyInt32> > comp;
+ ret = comp.equals(&this->positions,&pq->positions);
+ }
+ return ret;
+ }
+
+
+ PhraseQuery::~PhraseQuery(){
+ //Func - Destructor
+ //Pre - true
+ //Post 0 The instance has been destroyed
+
+ //Iterate through all the terms
+ for (uint32_t i = 0; i < terms.size(); i++){
+ _CLLDECDELETE(terms[i]);
+ }
+ positions.clear();
+ }
+
+ size_t PhraseQuery::hashCode() const {
+ //todo: do cachedHashCode, and invalidate on add/remove clause
+ size_t ret = Similarity::floatToByte(getBoost()) ^ Similarity::floatToByte(slop);
+
+ { //msvc6 scope fix
+ for ( int32_t i=0;terms.size();i++ )
+ ret = 31 * ret + terms[i]->hashCode();
+ }
+ { //msvc6 scope fix
+ for ( int32_t i=0;positions.size();i++ )
+ ret = 31 * ret + positions[i];
+ }
+ return ret;
+ }
+
+ const TCHAR* PhraseQuery::getClassName(){
+ return _T("PhraseQuery");
+ }
+ const TCHAR* PhraseQuery::getQueryName() const{
+ //Func - Returns the string "PhraseQuery"
+ //Pre - true
+ //Post - The string "PhraseQuery" has been returned
+ return getClassName();
+ }
+
+
+ /**
+ * Adds a term to the end of the query phrase.
+ * The relative position of the term is the one immediately after the last term added.
+ */
+ void PhraseQuery::add(Term* term) {
+ CND_PRECONDITION(term != NULL,"term is NULL");
+
+ int32_t position = 0;
+
+ if(positions.size() > 0)
+ position = (positions[positions.size()-1]) + 1;
+
+ add(term, position);
+ }
+
+ void PhraseQuery::add(Term* term, int32_t position) {
+ //Func - Adds a term to the end of the query phrase.
+ //Pre - term != NULL
+ //Post - The term has been added if its field matches the field of the PhraseQuery
+ // and true is returned otherwise false is returned
+ CND_PRECONDITION(term != NULL,"term is NULL");
+
+ if (terms.size() == 0)
+ field = term->field();
+ else{
+ //Check if the field of the _CLNEW term matches the field of the PhraseQuery
+ //can use != because fields are interned
+ if ( term->field() != field){
+ //return false;
+ TCHAR buf[200];
+ _sntprintf(buf,200,_T("All phrase terms must be in the same field: %s"),term->field());
+ _CLTHROWT(CL_ERR_IllegalArgument,buf);
+ }
+ }
+ //Store the _CLNEW term
+ terms.push_back(_CL_POINTER(term));
+
+ positions.push_back(position);
+ }
+
+ void PhraseQuery::getPositions(Array<int32_t>& result) const{
+ result.length = positions.size();
+ result.values = _CL_NEWARRAY(int32_t,result.length);
+ for(int32_t i = 0; i < result.length; i++){
+ result.values[i] = positions[i];
+ }
+ }
+ int32_t* PhraseQuery::getPositions() const{
+ CND_WARNING(false,"getPositions() is deprecated")
+
+ Array<int32_t> arr;
+ getPositions(arr);
+ return arr.values;
+ }
+
+ Weight* PhraseQuery::_createWeight(Searcher* searcher) {
+ if (terms.size() == 1) { // optimize one-term case
+ Term* term = terms[0];
+ Query* termQuery = _CLNEW TermQuery(term);
+ termQuery->setBoost(getBoost());
+ Weight* ret = termQuery->_createWeight(searcher);
+ _CLDELETE(termQuery);
+ return ret;
+ }
+ return _CLNEW PhraseWeight(searcher,this);
+ }
+
+
+ Term** PhraseQuery::getTerms() const{
+ //Func - added by search highlighter
+ //Pre -
+ //Post -
+
+ //Let size contain the number of terms
+ int32_t size = terms.size();
+ Term** ret = _CL_NEWARRAY(Term*,size+1);
+
+ CND_CONDITION(ret != NULL,"Could not allocated memory for ret");
+
+ //Iterate through terms and copy each pointer to ret
+ for ( int32_t i=0;i<size;i++ ){
+ ret[i] = terms[i];
+ }
+ ret[size] = NULL;
+ return ret;
+ }
+
+ TCHAR* PhraseQuery::toString(const TCHAR* f) const{
+ //Func - Prints a user-readable version of this query.
+ //Pre - f != NULL
+ //Post - The query string has been returned
+
+ if ( terms.size()== 0 )
+ return NULL;
+
+ StringBuffer buffer;
+ if ( f==NULL || _tcscmp(field,f)!=0) {
+ buffer.append(field);
+ buffer.append( _T(":"));
+ }
+
+ buffer.append( _T("\"") );
+
+ Term *T = NULL;
+
+ //iterate through all terms
+ for (uint32_t i = 0; i < terms.size(); i++) {
+ //Get the i-th term
+ T = terms[i];
+
+ //Ensure T is a valid Term
+ CND_CONDITION(T !=NULL,"T is NULL");
+
+ buffer.append( T->text() );
+ //Check if i is at the end of terms
+ if (i != terms.size()-1){
+ buffer.append(_T(" "));
+ }
+ }
+
+ buffer.append( _T("\"") );
+
+ if (slop != 0) {
+ buffer.append(_T("~"));
+ buffer.appendFloat(slop,0);
+ }
+
+ //Check if there is an other boost factor than 1.0
+ if (getBoost() != 1.0f) {
+ buffer.append(_T("^"));
+ buffer.appendFloat( getBoost(),1 );
+ }
+
+ //return the query string
+ return buffer.toString();
+ }
+
+
+
+
+
+
+
+
+ PhraseQuery::PhraseWeight::PhraseWeight(Searcher* searcher, PhraseQuery* _this) {
+ this->_this=_this;
+ this->value = 0;
+ this->idf = 0;
+ this->queryNorm = 0;
+ this->queryWeight = 0;
+ this->searcher = searcher;
+ }
+
+ TCHAR* PhraseQuery::PhraseWeight::toString() {
+ return STRDUP_TtoT(_T("weight(PhraseQuery)"));
+ }
+ PhraseQuery::PhraseWeight::~PhraseWeight(){
+ }
+
+
+ Query* PhraseQuery::PhraseWeight::getQuery() { return _this; }
+ qreal PhraseQuery::PhraseWeight::getValue() { return value; }
+
+ qreal PhraseQuery::PhraseWeight::sumOfSquaredWeights(){
+ idf = _this->getSimilarity(searcher)->idf(&_this->terms, searcher);
+ queryWeight = idf * _this->getBoost(); // compute query weight
+ return queryWeight * queryWeight; // square it
+ }
+
+ void PhraseQuery::PhraseWeight::normalize(qreal queryNorm) {
+ this->queryNorm = queryNorm;
+ queryWeight *= queryNorm; // normalize query weight
+ value = queryWeight * idf; // idf for document
+ }
+
+ Scorer* PhraseQuery::PhraseWeight::scorer(IndexReader* reader) {
+ //Func -
+ //Pre -
+ //Post -
+
+ //Get the length of terms
+ int32_t tpsLength = _this->terms.size();
+
+ //optimize zero-term case
+ if (tpsLength == 0)
+ return NULL;
+
+ TermPositions** tps = _CL_NEWARRAY(TermPositions*,tpsLength+1);
+
+ //Check if tps has been allocated properly
+ CND_CONDITION(tps != NULL,"Could not allocate memory for tps");
+
+ TermPositions* p = NULL;
+
+ //Iterate through all terms
+ int32_t size = _this->terms.size();
+ for (int32_t i = 0; i < size; i++) {
+ //Get the termPostitions for the i-th term
+ p = reader->termPositions(_this->terms[i]);
+
+ //Check if p is valid
+ if (p == NULL) {
+ //Delete previous retrieved termPositions
+ while (--i >= 0){
+ _CLVDELETE(tps[i]); //todo: not a clucene object... should be
+ }
+ _CLDELETE_ARRAY(tps);
+ return NULL;
+ }
+
+ //Store p at i in tps
+ tps[i] = p;
+ }
+ tps[tpsLength] = NULL;
+
+ Scorer* ret = NULL;
+
+ Array<int32_t> positions;
+ _this->getPositions(positions);
+ int32_t slop = _this->getSlop();
+ if ( slop != 0)
+ // optimize exact case
+ //todo: need to pass these: this, tps,
+ ret = _CLNEW SloppyPhraseScorer(this,tps,positions.values,
+ _this->getSimilarity(searcher),
+ slop, reader->norms(_this->field));
+ else
+ ret = _CLNEW ExactPhraseScorer(this, tps, positions.values,
+ _this->getSimilarity(searcher),
+ reader->norms(_this->field));
+ positions.deleteArray();
+
+ CND_CONDITION(ret != NULL,"Could not allocate memory for ret");
+
+ //tps can be deleted safely. SloppyPhraseScorer or ExactPhraseScorer will take care
+ //of its values
+
+ _CLDELETE_ARRAY(tps);
+ return ret;
+ }
+
+ void PhraseQuery::PhraseWeight::explain(IndexReader* reader, int32_t doc, Explanation* result){
+ TCHAR descbuf[LUCENE_SEARCH_EXPLANATION_DESC_LEN+1];
+ TCHAR* tmp;
+
+ tmp = getQuery()->toString();
+ _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,_T("weight(%s in %d), product of:"),
+ tmp,doc);
+ _CLDELETE_CARRAY(tmp);
+ result->setDescription(descbuf);
+
+ StringBuffer docFreqs;
+ StringBuffer query;
+ query.appendChar('\"');
+ for (uint32_t i = 0; i < _this->terms.size(); i++) {
+ if (i != 0) {
+ docFreqs.appendChar(' ');
+ query.appendChar(' ');
+ }
+
+ Term* term = _this->terms[i];
+
+ docFreqs.append(term->text());
+ docFreqs.appendChar('=');
+ docFreqs.appendInt(searcher->docFreq(term));
+
+ query.append(term->text());
+ }
+ query.appendChar('\"');
+
+ _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("idf(%s: %s)"),_this->field,docFreqs.getBuffer());
+ Explanation* idfExpl = _CLNEW Explanation(idf, descbuf);
+
+ // explain query weight
+ Explanation* queryExpl = _CLNEW Explanation;
+ tmp = getQuery()->toString();
+ _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("queryWeight(%s), product of:"),tmp);
+ _CLDELETE_CARRAY(tmp);
+ queryExpl->setDescription(descbuf);
+
+ Explanation* boostExpl = _CLNEW Explanation(_this->getBoost(), _T("boost"));
+ if (_this->getBoost() != 1.0f)
+ queryExpl->addDetail(boostExpl);
+ queryExpl->addDetail(idfExpl);
+
+ Explanation* queryNormExpl = _CLNEW Explanation(queryNorm,_T("queryNorm"));
+ queryExpl->addDetail(queryNormExpl);
+
+ queryExpl->setValue(boostExpl->getValue() *
+ idfExpl->getValue() *
+ queryNormExpl->getValue());
+
+ result->addDetail(queryExpl);
+
+ // explain field weight
+ Explanation* fieldExpl = _CLNEW Explanation;
+ _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("fieldWeight(%s:%s in %d), product of:"),
+ _this->field,query.getBuffer(),doc);
+ fieldExpl->setDescription(descbuf);
+
+
+ Explanation* tfExpl = _CLNEW Explanation;
+ scorer(reader)->explain(doc, tfExpl);
+ fieldExpl->addDetail(tfExpl);
+ fieldExpl->addDetail(idfExpl);
+
+ Explanation* fieldNormExpl = _CLNEW Explanation();
+ uint8_t* fieldNorms = reader->norms(_this->field);
+ qreal fieldNorm =
+ fieldNorms!=NULL ? Similarity::decodeNorm(fieldNorms[doc]) : 0.0f;
+ fieldNormExpl->setValue(fieldNorm);
+
+
+ _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("fieldNorm(field=%s, doc=%d)"),_this->field,doc);
+ fieldNormExpl->setDescription(descbuf);
+ fieldExpl->addDetail(fieldNormExpl);
+
+ fieldExpl->setValue(tfExpl->getValue() *
+ idfExpl->getValue() *
+ fieldNormExpl->getValue());
+
+ result->addDetail(fieldExpl);
+
+ // combine them
+ result->setValue(queryExpl->getValue() * fieldExpl->getValue());
+
+ if (queryExpl->getValue() == 1.0f){
+ result->set(*fieldExpl);
+ _CLDELETE(fieldExpl);
+ }
+ }
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/PhraseQuery.h b/3rdparty/clucene/src/CLucene/search/PhraseQuery.h
new file mode 100644
index 000000000..6b3255822
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PhraseQuery.h
@@ -0,0 +1,127 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_PhraseQuery_
+#define _lucene_search_PhraseQuery_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "SearchHeader.h"
+#include "Scorer.h"
+#include "BooleanQuery.h"
+#include "TermQuery.h"
+
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+#include "CLucene/index/IndexReader.h"
+
+#include "CLucene/util/StringBuffer.h"
+#include "CLucene/util/VoidList.h"
+
+#include "ExactPhraseScorer.h"
+#include "SloppyPhraseScorer.h"
+
+CL_NS_DEF(search)
+ // A Query that matches documents containing a particular sequence of terms.
+ // This may be combined with other terms with a {@link BooleanQuery}.
+ class PhraseQuery: public Query {
+ private:
+ CL_NS(util)::CLVector<int32_t,CL_NS(util)::Deletor::DummyInt32> positions;
+ int32_t slop;
+
+ const TCHAR* field;
+ CL_NS(util)::CLVector<CL_NS(index)::Term*> terms;
+
+
+ class PhraseWeight: public Weight {
+ private:
+ Searcher* searcher;
+ qreal value;
+ qreal idf;
+ qreal queryNorm;
+ qreal queryWeight;
+ PhraseQuery* _this;
+ public:
+ PhraseWeight(Searcher* searcher, PhraseQuery* _this);
+ ~PhraseWeight();
+ TCHAR* toString();
+
+ Query* getQuery();
+ qreal getValue();
+
+ qreal sumOfSquaredWeights();
+ void normalize(qreal queryNorm);
+ Scorer* scorer(CL_NS(index)::IndexReader* reader);
+ void explain(CL_NS(index)::IndexReader* reader, int32_t doc, Explanation* ret);
+ TCHAR* toString(TCHAR* f);
+ bool equals(PhraseWeight* o);
+ };
+ friend class PhraseWeight;
+ protected:
+ Weight* _createWeight(Searcher* searcher);
+ PhraseQuery(const PhraseQuery& clone);
+ public:
+ //Constructor
+ PhraseQuery();
+
+ //Destructor
+ ~PhraseQuery();
+
+ //Returns the string "PhraseQuery"
+ const TCHAR* getQueryName() const;
+ static const TCHAR* getClassName();
+
+ //Sets the number of other words permitted between words in query phrase.
+ //If zero, then this is an exact phrase search. For larger values this works
+ //like a WITHIN or NEAR operator.
+ //
+ //The slop is in fact an edit-distance, where the units correspond to
+ //moves of terms in the query phrase out of position. For example, to switch
+ //the order of two words requires two moves (the first move places the words
+ //atop one another), so to permit re-orderings of phrases, the slop must be
+ //at least two.
+ //
+ //More exact matches are scored higher than sloppier matches, thus search
+ //results are sorted by exactness.
+ //
+ //The slop is zero by default, requiring exact matches.
+ void setSlop(const int32_t s) { slop = s; }
+
+ //Returns the slop. See setSlop().
+ int32_t getSlop() const { return slop; }
+
+ //Adds a term to the end of the query phrase.
+ void add(CL_NS(index)::Term* term);
+ void add(CL_NS(index)::Term* term, int32_t position);
+
+
+
+ //Returns the sum of squared weights
+ qreal sumOfSquaredWeights(Searcher* searcher);
+
+ //Normalizes the Weight
+ void normalize(const qreal norm);
+
+ Scorer* scorer(CL_NS(index)::IndexReader* reader);
+
+ //added by search highlighter
+ CL_NS(index)::Term** getTerms() const;
+ _CL_DEPRECATED( deleteDocuments ) int32_t* getPositions() const; ///@deprecated. use getPositions(Array<int32_t>& result)
+ void getPositions(Array<int32_t>& result) const;
+ const TCHAR* getFieldName() const{ return field; }
+
+ //Prints a user-readable version of this query.
+ TCHAR* toString(const TCHAR* f) const;
+
+ Query* clone() const;
+ bool equals(CL_NS(search)::Query *) const;
+
+ size_t hashCode() const;
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/PhraseQueue.h b/3rdparty/clucene/src/CLucene/search/PhraseQueue.h
new file mode 100644
index 000000000..c0682fcaf
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PhraseQueue.h
@@ -0,0 +1,36 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_PriorityQueue_
+#define _lucene_search_PriorityQueue_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/PriorityQueue.h"
+#include "PhrasePositions.h"
+
+CL_NS_DEF(search)
+ class PhraseQueue: public CL_NS(util)::PriorityQueue<PhrasePositions*,
+ CL_NS(util)::Deletor::Object<PhrasePositions> > {
+ public:
+ PhraseQueue(const int32_t size) {
+ initialize(size,false);
+ }
+ ~PhraseQueue(){
+ }
+
+ protected:
+ bool lessThan(PhrasePositions* pp1, PhrasePositions* pp2) {
+ if (pp1->doc == pp2->doc)
+ return pp1->position < pp2->position;
+ else
+ return pp1->doc < pp2->doc;
+ }
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/PhraseScorer.cpp b/3rdparty/clucene/src/CLucene/search/PhraseScorer.cpp
new file mode 100644
index 000000000..b2da2316a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PhraseScorer.cpp
@@ -0,0 +1,225 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "PhraseScorer.h"
+
+#include "PhraseQueue.h"
+#include "PhrasePositions.h"
+#include "Scorer.h"
+#include "Similarity.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+
+ PhraseScorer::PhraseScorer(Weight* weight, TermPositions** tps,
+ int32_t* positions, Similarity* similarity, uint8_t* norms):
+ Scorer(similarity)
+ {
+ //Func - Constructor
+ //Pre - tps != NULL and is an array of TermPositions
+ // tpsLength >= 0
+ // n != NULL
+ //Post - The instance has been created
+
+ CND_PRECONDITION(tps != NULL,"tps is NULL");
+
+ //norms are only used if phraseFreq returns more than 0.0
+ //phraseFreq should only return more than 0.0 if norms != NULL
+ //CND_PRECONDITION(n != NULL,"n is NULL");
+
+ firstTime = true;
+ more = true;
+ this->norms = norms;
+ this->weight = weight;
+ this->value = weight->getValue();
+
+ //reset internal pointers
+ first = NULL;
+ last = NULL;
+
+ //use pq to build a sorted list of PhrasePositions
+ int32_t i = 0;
+ while(tps[i] != NULL){
+ PhrasePositions *pp = _CLNEW PhrasePositions(tps[i], positions[i]);
+ CND_CONDITION(pp != NULL,"Could not allocate memory for pp");
+
+ //Store PhrasePos into the PhrasePos pq
+ if (last != NULL) { // add next to end of list
+ last->_next = pp;
+ } else
+ first = pp;
+ last = pp;
+
+ i++;
+ }
+
+ pq = _CLNEW PhraseQueue(i); //i==tps.length
+ CND_CONDITION(pq != NULL,"Could not allocate memory for pq");
+ }
+
+ PhraseScorer::~PhraseScorer() {
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ //The PhraseQueue pq (which is a PriorityQueue) pq is actually empty at present, the elements
+ //having been transferred by pqToList() to the linked list starting with
+ //first. The nodes of that linked list are deleted by the destructor of
+ //first, rather than the destructor of pq.
+ _CLDELETE(first);
+ _CLDELETE(pq);
+ }
+
+ bool PhraseScorer::next(){
+ if (firstTime) {
+ init();
+ firstTime = false;
+ } else if (more) {
+ more = last->next(); // trigger further scanning
+ }
+ return doNext();
+ }
+
+ // next without initial increment
+ bool PhraseScorer::doNext() {
+ while (more) {
+ while (more && first->doc < last->doc) { // find doc w/ all the terms
+ more = first->skipTo(last->doc); // skip first upto last
+ firstToLast(); // and move it to the end
+ }
+
+ if (more) {
+ // found a doc with all of the terms
+ freq = phraseFreq(); // check for phrase
+ if (freq == 0.0f) // no match
+ more = last->next(); // trigger further scanning
+ else
+ return true; // found a match
+ }
+ }
+ return false; // no more matches
+ }
+
+ qreal PhraseScorer::score(){
+ //System.out.println("scoring " + first.doc);
+ qreal raw = getSimilarity()->tf(freq) * value; // raw score
+ return raw * Similarity::decodeNorm(norms[first->doc]); // normalize
+ }
+
+ bool PhraseScorer::skipTo(int32_t target) {
+ for (PhrasePositions* pp = first; more && pp != NULL; pp = pp->_next) {
+ more = pp->skipTo(target);
+ }
+ if (more)
+ sort(); // re-sort
+ return doNext();
+ }
+
+ void PhraseScorer::init() {
+ for (PhrasePositions* pp = first; more && pp != NULL; pp = pp->_next)
+ more = pp->next();
+ if(more)
+ sort();
+ }
+
+ void PhraseScorer::sort() {
+ pq->clear();
+ for (PhrasePositions* pp = first; pp != NULL; pp = pp->_next)
+ pq->put(pp);
+ pqToList();
+ }
+
+
+
+ void PhraseScorer::pqToList(){
+ //Func - Transfers the PhrasePositions from the PhraseQueue pq to
+ // the PhrasePositions list with first as its first element
+ //Pre - pq != NULL
+ // first = NULL
+ // last = NULL
+ //Post - All PhrasePositions have been transfered to the list
+ // of PhrasePositions of which the first element is pointed to by first
+ // and the last element is pointed to by last
+
+ CND_PRECONDITION(pq != NULL,"pq is NULL");
+
+ last = first = NULL;
+
+ PhrasePositions* PhrasePos = NULL;
+
+ //As long pq is not empty
+ while (pq->top() != NULL){
+ //Pop a PhrasePositions instance
+ PhrasePos = pq->pop();
+
+ // add next to end of list
+ if (last != NULL) {
+ last->_next = PhrasePos;
+ } else {
+ first = PhrasePos;
+ }
+
+ //Let last point to the new last PhrasePositions instance just added
+ last = PhrasePos;
+ //Reset the next of last to NULL
+ last->_next = NULL;
+ }
+
+ //Check to see that pq is empty now
+ CND_CONDITION(pq->size()==0, "pq is not empty while it should be");
+ }
+
+ void PhraseScorer::firstToLast(){
+ //Func - Moves first to the end of the list
+ //Pre - first is NULL or points to an PhrasePositions Instance
+ // last is NULL or points to an PhrasePositions Instance
+ // first and last both are NULL or both are not NULL
+ //Post - The first element has become the last element in the list
+
+ CND_PRECONDITION(((first==NULL && last==NULL) ||(first !=NULL && last != NULL)),
+ "Either first or last is NULL but not both");
+
+ //Check if first and last are valid pointers
+ if(first && last){
+ last->_next = first;
+ last = first;
+ first = first->_next;
+ last->_next = NULL;
+ }
+ }
+
+
+ void PhraseScorer::explain(int32_t _doc, Explanation* tfExplanation) {
+ while (next() && doc() < _doc){
+ }
+
+ qreal phraseFreq = (doc() == _doc) ? freq : 0.0f;
+ tfExplanation->setValue(getSimilarity()->tf(phraseFreq));
+
+ StringBuffer buf;
+ buf.append(_T("tf(phraseFreq="));
+ buf.appendFloat(phraseFreq,2);
+ buf.append(_T(")"));
+ tfExplanation->setDescription(buf.getBuffer());
+ }
+
+ TCHAR* PhraseScorer::toString() {
+ StringBuffer buf;
+ buf.append(_T("scorer("));
+
+ TCHAR* tmp = weight->toString();
+ buf.append(tmp);
+ _CLDELETE_CARRAY(tmp);
+
+ buf.append(_T(")"));
+
+ return buf.toString();
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/PhraseScorer.h b/3rdparty/clucene/src/CLucene/search/PhraseScorer.h
new file mode 100644
index 000000000..89f7a1fbb
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PhraseScorer.h
@@ -0,0 +1,65 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_PhraseScorer_
+#define _lucene_search_PhraseScorer_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "PhraseQueue.h"
+#include "PhrasePositions.h"
+#include "Scorer.h"
+#include "Similarity.h"
+
+CL_NS_DEF(search)
+
+ class PhraseScorer: public Scorer {
+ private:
+ Weight* weight;
+ qreal freq;
+ bool firstTime;
+ bool more;
+
+ protected:
+ uint8_t* norms;
+ qreal value;
+
+ PhraseQueue* pq; //is used to order the list point to by first and last
+ PhrasePositions* first; //Points to the first in the list of PhrasePositions
+ PhrasePositions* last; //Points to the last in the list of PhrasePositions
+
+ public:
+ //Constructor
+ PhraseScorer(Weight* weight, CL_NS(index)::TermPositions** tps,
+ int32_t* positions, Similarity* similarity, uint8_t* norms);
+ virtual ~PhraseScorer();
+
+ int32_t doc() const { return first->doc; }
+ bool next();
+ qreal score();
+ bool skipTo(int32_t target);
+
+
+ void explain(int32_t doc, Explanation* ret);
+ TCHAR* toString();
+ protected:
+ virtual qreal phraseFreq() =0;
+
+ //Transfers the PhrasePositions from the PhraseQueue pq to
+ //the PhrasePositions list with first as its first element
+ void pqToList();
+
+ //Moves first to the end of the list
+ void firstToLast();
+ private:
+ bool doNext();
+ void init();
+ void sort();
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/PrefixQuery.cpp b/3rdparty/clucene/src/CLucene/search/PrefixQuery.cpp
new file mode 100644
index 000000000..6bb27d1ca
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PrefixQuery.cpp
@@ -0,0 +1,273 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "PrefixQuery.h"
+#include "CLucene/util/BitSet.h"
+
+CL_NS_USE(util)
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+ PrefixQuery::PrefixQuery(Term* Prefix){
+ //Func - Constructor.
+ // Constructs a query for terms starting with prefix
+ //Pre - Prefix != NULL
+ //Post - The instance has been created
+
+ //Get a pointer to Prefix
+ prefix = _CL_POINTER(Prefix);
+ }
+
+ PrefixQuery::PrefixQuery(const PrefixQuery& clone):Query(clone){
+ prefix = _CL_POINTER(clone.prefix);
+ }
+ Query* PrefixQuery::clone() const{
+ return _CLNEW PrefixQuery(*this);
+ }
+
+ Term* PrefixQuery::getPrefix(bool pointer){
+ if ( pointer )
+ return _CL_POINTER(prefix);
+ else
+ return prefix;
+ }
+
+ PrefixQuery::~PrefixQuery(){
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed.
+
+ //Delete prefix by finalizing it
+ _CLDECDELETE(prefix);
+ }
+
+
+ /** Returns a hash code value for this object.*/
+ size_t PrefixQuery::hashCode() const {
+ return Similarity::floatToByte(getBoost()) ^ prefix->hashCode();
+ }
+
+ const TCHAR* PrefixQuery::getQueryName()const{
+ //Func - Returns the name "PrefixQuery"
+ //Pre - true
+ //Post - The string "PrefixQuery" has been returned
+
+ return getClassName();
+ }
+ const TCHAR* PrefixQuery::getClassName(){
+ //Func - Returns the name "PrefixQuery"
+ //Pre - true
+ //Post - The string "PrefixQuery" has been returned
+
+ return _T("PrefixQuery");
+ }
+
+ bool PrefixQuery::equals(Query * other) const{
+ if (!(other->instanceOf(PrefixQuery::getClassName())))
+ return false;
+
+ PrefixQuery* rq = (PrefixQuery*)other;
+ bool ret = (this->getBoost() == rq->getBoost())
+ && (this->prefix->equals(rq->prefix));
+
+ return ret;
+ }
+
+ Query* PrefixQuery::rewrite(IndexReader* reader){
+ BooleanQuery* query = _CLNEW BooleanQuery();
+ TermEnum* enumerator = reader->terms(prefix);
+ Term* lastTerm = NULL;
+ try {
+ const TCHAR* prefixText = prefix->text();
+ const TCHAR* prefixField = prefix->field();
+ const TCHAR* tmp;
+ size_t i;
+ int32_t prefixLen = prefix->textLength();
+ do {
+ lastTerm = enumerator->term();
+ if (lastTerm != NULL && lastTerm->field() == prefixField ){
+
+ //now see if term->text() starts with prefixText
+ int32_t termLen = lastTerm->textLength();
+ if ( prefixLen>termLen )
+ break; //the prefix is longer than the term, can't be matched
+
+ tmp = lastTerm->text();
+
+ //check for prefix match in reverse, since most change will be at the end
+ for ( i=prefixLen-1;i!=-1;--i ){
+ if ( tmp[i] != prefixText[i] ){
+ tmp=NULL;//signals inequality
+ break;
+ }
+ }
+ if ( tmp == NULL )
+ break;
+
+ TermQuery* tq = _CLNEW TermQuery(lastTerm); // found a match
+ tq->setBoost(getBoost()); // set the boost
+ query->add(tq,true,false, false); // add to query
+ } else
+ break;
+ _CLDECDELETE(lastTerm);
+ } while (enumerator->next());
+ }_CLFINALLY(
+ enumerator->close();
+ _CLDELETE(enumerator);
+ _CLDECDELETE(lastTerm);
+ );
+ _CLDECDELETE(lastTerm);
+
+
+ //if we only added one clause and the clause is not prohibited then
+ //we can just return the query
+ if (query->getClauseCount() == 1) { // optimize 1-clause queries
+ BooleanClause* c=0;
+ query->getClauses(&c);
+
+ if (!c->prohibited) { // just return clause
+ c->deleteQuery=false;
+ Query* ret = c->query;
+
+ _CLDELETE(query);
+ return ret;
+ }
+ }
+
+ return query;
+ }
+
+ Query* PrefixQuery::combine(Query** queries) {
+ return Query::mergeBooleanQueries(queries);
+ }
+
+ TCHAR* PrefixQuery::toString(const TCHAR* field) const{
+ //Func - Creates a user-readable version of this query and returns it as as string
+ //Pre - field != NULL
+ //Post - a user-readable version of this query has been returned as as string
+
+ //Instantiate a stringbuffer buffer to store the readable version temporarily
+ CL_NS(util)::StringBuffer buffer;
+ //check if field equal to the field of prefix
+ if( field==NULL || _tcscmp(prefix->field(),field) != 0 ) {
+ //Append the field of prefix to the buffer
+ buffer.append(prefix->field());
+ //Append a colon
+ buffer.append(_T(":") );
+ }
+ //Append the text of the prefix
+ buffer.append(prefix->text());
+ //Append a wildchar character
+ buffer.append(_T("*"));
+ //if the boost factor is not eaqual to 1
+ if (getBoost() != 1.0f) {
+ //Append ^
+ buffer.append(_T("^"));
+ //Append the boost factor
+ buffer.appendFloat( getBoost(),1);
+ }
+ //Convert StringBuffer buffer to TCHAR block and return it
+ return buffer.toString();
+ }
+
+
+
+
+
+
+
+
+PrefixFilter::PrefixFilter( Term* prefix )
+{
+ this->prefix = _CL_POINTER(prefix);
+}
+
+PrefixFilter::~PrefixFilter()
+{
+ _CLDECDELETE(prefix);
+}
+
+PrefixFilter::PrefixFilter( const PrefixFilter& copy ) :
+ prefix( _CL_POINTER(copy.prefix) )
+{
+}
+
+Filter* PrefixFilter::clone() const {
+ return _CLNEW PrefixFilter(*this );
+}
+
+TCHAR* PrefixFilter::toString()
+{
+ //Instantiate a stringbuffer buffer to store the readable version temporarily
+ CL_NS(util)::StringBuffer buffer;
+ //check if field equal to the field of prefix
+ if( prefix->field() != NULL ) {
+ //Append the field of prefix to the buffer
+ buffer.append(prefix->field());
+ //Append a colon
+ buffer.append(_T(":") );
+ }
+ //Append the text of the prefix
+ buffer.append(prefix->text());
+ buffer.append(_T("*"));
+
+ //Convert StringBuffer buffer to TCHAR block and return it
+ return buffer.toString();
+}
+
+/** Returns a BitSet with true for documents which should be permitted in
+search results, and false for those that should not. */
+BitSet* PrefixFilter::bits( IndexReader* reader )
+{
+ BitSet* bts = _CLNEW BitSet( reader->maxDoc() );
+ TermEnum* enumerator = reader->terms(prefix);
+ TermDocs* docs = reader->termDocs();
+ const TCHAR* prefixText = prefix->text();
+ const TCHAR* prefixField = prefix->field();
+ const TCHAR* tmp;
+ size_t i;
+ int32_t prefixLen = prefix->textLength();
+ Term* lastTerm = NULL;
+
+ try{
+ do{
+ lastTerm = enumerator->term(false);
+ if (lastTerm != NULL && lastTerm->field() == prefixField ){
+ //now see if term->text() starts with prefixText
+ int32_t termLen = lastTerm->textLength();
+ if ( prefixLen>termLen )
+ break; //the prefix is longer than the term, can't be matched
+
+ tmp = lastTerm->text();
+
+ //check for prefix match in reverse, since most change will be at the end
+ for ( i=prefixLen-1;i!=-1;--i ){
+ if ( tmp[i] != prefixText[i] ){
+ tmp=NULL;//signals inequality
+ break;
+ }
+ }
+ if ( tmp == NULL )
+ break;
+
+ docs->seek(enumerator);
+ while (docs->next()) {
+ bts->set(docs->doc());
+ }
+ }
+ }while(enumerator->next());
+ } _CLFINALLY(
+ docs->close();
+ _CLDELETE(docs);
+ enumerator->close();
+ _CLDELETE(enumerator);
+ )
+
+ return bts;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/PrefixQuery.h b/3rdparty/clucene/src/CLucene/search/PrefixQuery.h
new file mode 100644
index 000000000..8e3f41352
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/PrefixQuery.h
@@ -0,0 +1,75 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_PrefixQuery
+#define _lucene_search_PrefixQuery
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+#include "CLucene/index/IndexReader.h"
+#include "SearchHeader.h"
+#include "BooleanQuery.h"
+#include "TermQuery.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_DEF(search)
+ //PrefixQuery is a Query that matches documents containing terms with a specified prefix.
+
+ class PrefixQuery: public Query {
+ private:
+ CL_NS(index)::Term* prefix;
+ protected:
+ PrefixQuery(const PrefixQuery& clone);
+ public:
+
+ //Constructor. Constructs a query for terms starting with prefix
+ PrefixQuery(CL_NS(index)::Term* Prefix);
+
+ //Destructor
+ ~PrefixQuery();
+
+ //Returns the name "PrefixQuery"
+ const TCHAR* getQueryName() const;
+ static const TCHAR* getClassName();
+
+ /** Returns the prefix of this query. */
+ CL_NS(index)::Term* getPrefix(bool pointer=true);
+
+ Query* combine(Query** queries);
+ Query* rewrite(CL_NS(index)::IndexReader* reader);
+ Query* clone() const;
+ bool equals(Query * other) const;
+
+ //Creates a user-readable version of this query and returns it as as string
+ TCHAR* toString(const TCHAR* field) const;
+
+ size_t hashCode() const;
+ };
+
+
+ class PrefixFilter: public Filter
+ {
+ private:
+ CL_NS(index)::Term* prefix;
+ protected:
+ PrefixFilter( const PrefixFilter& copy );
+
+ public:
+ PrefixFilter(CL_NS(index)::Term* prefix);
+ ~PrefixFilter();
+
+ /** Returns a BitSet with true for documents which should be permitted in
+ search results, and false for those that should not. */
+ CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader );
+
+ Filter* clone() const;
+ TCHAR* toString();
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/QueryFilter.cpp b/3rdparty/clucene/src/CLucene/search/QueryFilter.cpp
new file mode 100644
index 000000000..2dbe2d7cd
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/QueryFilter.cpp
@@ -0,0 +1,73 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "QueryFilter.h"
+#include "IndexSearcher.h"
+
+CL_NS_DEF(search)
+CL_NS_USE(util)
+CL_NS_USE(index)
+
+
+QueryFilter::QueryFilter( const Query* query )
+{
+ this->query = query->clone();
+}
+
+
+QueryFilter::~QueryFilter()
+{
+ _CLDELETE( query );
+}
+
+
+QueryFilter::QueryFilter( const QueryFilter& copy )
+{
+ this->query = copy.query->clone();
+}
+
+
+Filter* QueryFilter::clone() const {
+ return _CLNEW QueryFilter(*this );
+}
+
+
+TCHAR* QueryFilter::toString()
+{
+ TCHAR* qt = query->toString();
+ size_t len = _tcslen(qt) + 14;
+ TCHAR* ret = _CL_NEWARRAY( TCHAR, len );
+ ret[0] = 0;
+ _sntprintf( ret, len, _T("QueryFilter(%s)"), qt );
+ _CLDELETE_CARRAY(qt);
+ return ret;
+}
+
+
+/** Returns a BitSet with true for documents which should be permitted in
+search results, and false for those that should not. */
+BitSet* QueryFilter::bits( IndexReader* reader )
+{
+ BitSet* bits = _CLNEW BitSet(reader->maxDoc());
+
+ IndexSearcher s(reader);
+ QFHitCollector hc(bits);
+ s._search(query, NULL, &hc);
+ return bits;
+}
+
+
+QueryFilter::QFHitCollector::QFHitCollector(CL_NS(util)::BitSet* bits){
+ this->bits = bits;
+}
+
+void QueryFilter::QFHitCollector::collect(const int32_t doc, const qreal score) {
+ bits->set(doc); // set bit for hit
+}
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/QueryFilter.h b/3rdparty/clucene/src/CLucene/search/QueryFilter.h
new file mode 100644
index 000000000..8d423b2f7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/QueryFilter.h
@@ -0,0 +1,44 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_QueryFilter_
+#define _lucene_search_QueryFilter_
+
+#include "CLucene/util/BitSet.h"
+#include "CLucene/index/IndexReader.h"
+#include "SearchHeader.h"
+#include "CachingWrapperFilter.h"
+
+CL_NS_DEF(search)
+
+class QueryFilter: public Filter
+{
+private:
+ Query* query;
+
+ class QFHitCollector: public HitCollector{
+ CL_NS(util)::BitSet* bits;
+ public:
+ QFHitCollector(CL_NS(util)::BitSet* bits);
+ void collect(const int32_t doc, const qreal score);
+ };
+
+protected:
+ QueryFilter( const QueryFilter& copy );
+public:
+ QueryFilter( const Query* query );
+
+ ~QueryFilter();
+
+ CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader );
+
+ Filter *clone() const;
+
+ TCHAR *toString();
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/RangeFilter.cpp b/3rdparty/clucene/src/CLucene/search/RangeFilter.cpp
new file mode 100644
index 000000000..66ee5ce55
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/RangeFilter.cpp
@@ -0,0 +1,150 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "RangeFilter.h"
+
+CL_NS_DEF(search)
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_USE(document)
+
+
+RangeFilter::RangeFilter( const TCHAR* fieldName, const TCHAR* lowerTerm, const TCHAR* upperTerm, bool includeLower, bool includeUpper )
+{
+ this->field = STRDUP_TtoT(fieldName);
+ if ( lowerTerm != NULL )
+ this->lowerValue = STRDUP_TtoT(lowerTerm);
+ else
+ this->lowerValue = NULL;
+ if ( upperTerm != NULL )
+ this->upperValue = STRDUP_TtoT(upperTerm);
+ else
+ this->upperValue = NULL;
+ this->includeLower = includeLower;
+ this->includeUpper = includeUpper;
+}
+
+
+/**
+ * Constructs a filter for field <code>fieldName</code> matching
+ * less than or equal to <code>upperTerm</code>.
+ */
+RangeFilter* RangeFilter::Less( TCHAR* fieldName, TCHAR* upperTerm ) {
+ return new RangeFilter( fieldName, NULL, upperTerm, false, true );
+}
+
+
+/**
+* Constructs a filter for field <code>fieldName</code> matching
+* more than or equal to <code>lowerTerm</code>.
+*/
+RangeFilter* RangeFilter::More( TCHAR* fieldName, TCHAR* lowerTerm ) {
+ return new RangeFilter( fieldName, lowerTerm, NULL, true, false );
+}
+
+
+RangeFilter::~RangeFilter()
+{
+ _CLDELETE_CARRAY( lowerValue );
+ _CLDELETE_CARRAY( field );
+ _CLDELETE_CARRAY( upperValue );
+}
+
+
+RangeFilter::RangeFilter( const RangeFilter& copy ) :
+ field( STRDUP_TtoT(copy.field) ),
+ lowerValue( STRDUP_TtoT(copy.lowerValue) ),
+ upperValue( STRDUP_TtoT(copy.upperValue) ),
+ includeLower( copy.includeLower ),
+ includeUpper( copy.includeUpper )
+{
+}
+
+
+Filter* RangeFilter::clone() const {
+ return _CLNEW RangeFilter(*this );
+}
+
+
+TCHAR* RangeFilter::toString()
+{
+ size_t len = (field ? _tcslen(field) : 0) + (lowerValue ? _tcslen(lowerValue) : 0) + (upperValue ? _tcslen(upperValue) : 0) + 8;
+ TCHAR* ret = _CL_NEWARRAY( TCHAR, len );
+ ret[0] = 0;
+ _sntprintf( ret, len, _T("%s: [%s-%s]"), field, (lowerValue?lowerValue:_T("")), (upperValue?upperValue:_T("")) );
+
+ return ret;
+}
+
+
+/** Returns a BitSet with true for documents which should be permitted in
+search results, and false for those that should not. */
+BitSet* RangeFilter::bits( IndexReader* reader )
+{
+ BitSet* bts = _CLNEW BitSet( reader->maxDoc() );
+ Term* term = NULL;
+
+ Term* t = _CLNEW Term( field, (lowerValue ? lowerValue : _T("")), false );
+ TermEnum* enumerator = reader->terms( t ); // get enumeration of all terms after lowerValue
+ _CLDECDELETE( t );
+
+ if( enumerator->term(false) == NULL ) {
+ _CLDELETE( enumerator );
+ return bts;
+ }
+
+ bool checkLower = false;
+ if( !includeLower ) // make adjustments to set to exclusive
+ checkLower = true;
+
+ TermDocs* termDocs = reader->termDocs();
+
+ try
+ {
+ do
+ {
+ term = enumerator->term();
+
+ if( term == NULL || _tcscmp(term->field(), field) )
+ break;
+
+ if( !checkLower || lowerValue == NULL || _tcscmp(term->text(), lowerValue) > 0 )
+ {
+ checkLower = false;
+ if( upperValue != NULL )
+ {
+ int compare = _tcscmp( upperValue, term->text() );
+
+ /* if beyond the upper term, or is exclusive and
+ * this is equal to the upper term, break out */
+ if( (compare < 0) || (!includeUpper && compare == 0) )
+ break;
+ }
+
+ termDocs->seek( enumerator->term(false) );
+ while( termDocs->next() ) {
+ bts->set( termDocs->doc() );
+ }
+ }
+
+ _CLDECDELETE( term );
+ }
+ while( enumerator->next() );
+ }
+ _CLFINALLY
+ (
+ _CLDECDELETE( term );
+ termDocs->close();
+ _CLVDELETE( termDocs );
+ enumerator->close();
+ _CLDELETE( enumerator );
+ );
+
+ return bts;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/RangeFilter.h b/3rdparty/clucene/src/CLucene/search/RangeFilter.h
new file mode 100644
index 000000000..0865e356f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/RangeFilter.h
@@ -0,0 +1,51 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+
+#ifndef _lucene_search_RangeFilter_
+#define _lucene_search_RangeFilter_
+
+#include "CLucene/document/DateField.h"
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/BitSet.h"
+#include "CLucene/search/Filter.h"
+
+CL_NS_DEF(search)
+
+class RangeFilter: public Filter
+{
+private:
+ const TCHAR* field;
+ TCHAR* lowerValue;
+ TCHAR* upperValue;
+ bool includeLower;
+ bool includeUpper;
+
+protected:
+ RangeFilter( const RangeFilter& copy );
+
+public:
+ RangeFilter( const TCHAR* fieldName, const TCHAR* lowerValue, const TCHAR* upperValue, bool includeLower, bool includeUpper );
+
+ static RangeFilter* Less( TCHAR* fieldName, TCHAR* upperTerm );
+
+ static RangeFilter* More( TCHAR* fieldName, TCHAR* lowerTerm );
+
+ ~RangeFilter();
+
+ /** Returns a BitSet with true for documents which should be permitted in
+ search results, and false for those that should not. */
+ CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader );
+
+ Filter* clone() const;
+
+ TCHAR* toString();
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/RangeQuery.cpp b/3rdparty/clucene/src/CLucene/search/RangeQuery.cpp
new file mode 100644
index 000000000..4fc242089
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/RangeQuery.cpp
@@ -0,0 +1,204 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "RangeQuery.h"
+
+#include "SearchHeader.h"
+#include "Scorer.h"
+#include "BooleanQuery.h"
+#include "TermQuery.h"
+
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/StringBuffer.h"
+
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+ RangeQuery::RangeQuery(Term* lowerTerm, Term* upperTerm, const bool Inclusive){
+ //Func - Constructor
+ //Pre - (LowerTerm != NULL OR UpperTerm != NULL) AND
+ // if LowerTerm and UpperTerm are valid pointer then the fieldnames must be the same
+ //Post - The instance has been created
+
+ if (lowerTerm == NULL && upperTerm == NULL)
+ {
+ _CLTHROWA(CL_ERR_IllegalArgument,"At least one term must be non-null");
+ }
+ if (lowerTerm != NULL && upperTerm != NULL && lowerTerm->field() != upperTerm->field())
+ {
+ _CLTHROWA(CL_ERR_IllegalArgument,"Both terms must be for the same field");
+ }
+
+ // if we have a lowerTerm, start there. otherwise, start at beginning
+ if (lowerTerm != NULL) {
+ this->lowerTerm = _CL_POINTER(lowerTerm);
+ }
+ else {
+ this->lowerTerm = _CLNEW Term(upperTerm, LUCENE_BLANK_STRING);
+ }
+ this->upperTerm = (upperTerm != NULL ? _CL_POINTER(upperTerm) : NULL);
+ this->inclusive = Inclusive;
+ }
+ RangeQuery::RangeQuery(const RangeQuery& clone):
+ Query(clone){
+ this->inclusive = clone.inclusive;
+ this->upperTerm = (clone.upperTerm != NULL ? _CL_POINTER(clone.upperTerm) : NULL );
+ this->lowerTerm = (clone.lowerTerm != NULL ? _CL_POINTER(clone.lowerTerm) : NULL );
+ }
+ Query* RangeQuery::clone() const{
+ return _CLNEW RangeQuery(*this);
+ }
+
+ RangeQuery::~RangeQuery() {
+ //Func - Destructor
+ //Pre - true
+ //Post - The instance has been destroyed
+
+ _CLDECDELETE(lowerTerm);
+ _CLDECDELETE(upperTerm);
+ }
+
+ /** Returns a hash code value for this object.*/
+ size_t RangeQuery::hashCode() const {
+ return Similarity::floatToByte(getBoost()) ^
+ (lowerTerm != NULL ? lowerTerm->hashCode() : 0) ^
+ (upperTerm != NULL ? upperTerm->hashCode() : 0) ^
+ (this->inclusive ? 1 : 0);
+ }
+
+ const TCHAR* RangeQuery::getQueryName() const{
+ return getClassName();
+ }
+ const TCHAR* RangeQuery::getClassName(){
+ return _T("RangeQuery");
+ }
+
+ Query* RangeQuery::combine(Query** queries) {
+ return Query::mergeBooleanQueries(queries);
+ }
+
+ bool RangeQuery::equals(Query * other) const{
+ if (!(other->instanceOf(RangeQuery::getClassName())))
+ return false;
+
+ RangeQuery* rq = (RangeQuery*)other;
+ bool ret = (this->getBoost() == rq->getBoost())
+ && (this->isInclusive() == rq->isInclusive())
+ && (this->getLowerTerm()->equals(rq->getLowerTerm()))
+ && (this->getUpperTerm()->equals(rq->getUpperTerm()));
+
+ return ret;
+ }
+
+
+ /**
+ * FIXME: Describe <code>rewrite</code> method here.
+ *
+ * @param reader an <code>IndexReader</code> value
+ * @return a <code>Query</code> value
+ * @exception IOException if an error occurs
+ */
+ Query* RangeQuery::rewrite(IndexReader* reader){
+
+ BooleanQuery* query = _CLNEW BooleanQuery;
+ TermEnum* enumerator = reader->terms(lowerTerm);
+ Term* lastTerm = NULL;
+ try {
+ bool checkLower = false;
+ if (!inclusive) // make adjustments to set to exclusive
+ checkLower = true;
+
+ const TCHAR* testField = getField();
+ do {
+ lastTerm = enumerator->term();
+ if (lastTerm != NULL && lastTerm->field() == testField ) {
+ if (!checkLower || _tcscmp(lastTerm->text(),lowerTerm->text()) > 0) {
+ checkLower = false;
+ if (upperTerm != NULL) {
+ int compare = _tcscmp(upperTerm->text(),lastTerm->text());
+ /* if beyond the upper term, or is exclusive and
+ * this is equal to the upper term, break out */
+ if ((compare < 0) || (!inclusive && compare == 0))
+ break;
+ }
+ TermQuery* tq = _CLNEW TermQuery(lastTerm); // found a match
+ tq->setBoost(getBoost()); // set the boost
+ query->add(tq, true, false, false); // add to query
+ }
+ }else {
+ break;
+ }
+ _CLDECDELETE(lastTerm);
+ }
+ while (enumerator->next());
+ }catch(...){
+ _CLDECDELETE(lastTerm); //always need to delete this
+ _CLDELETE(query); //in case of error, delete the query
+ enumerator->close();
+ _CLDELETE(enumerator);
+ throw; //rethrow
+ }
+ _CLDECDELETE(lastTerm); //always need to delete this
+ enumerator->close();
+ _CLDELETE(enumerator);
+
+ return query;
+ }
+
+ /** Prints a user-readable version of this query. */
+ TCHAR* RangeQuery::toString(const TCHAR* field) const
+ {
+ StringBuffer buffer;
+ if ( field==NULL || _tcscmp(getField(),field)!=0 )
+ {
+ buffer.append( getField() );
+ buffer.append( _T(":"));
+ }
+ buffer.append(inclusive ? _T("[") : _T("{"));
+ buffer.append(lowerTerm != NULL ? lowerTerm->text() : _T("NULL"));
+ buffer.append(_T(" TO "));
+ buffer.append(upperTerm != NULL ? upperTerm->text() : _T("NULL"));
+ buffer.append(inclusive ? _T("]") : _T("}"));
+ if (getBoost() != 1.0f)
+ {
+ buffer.append( _T("^"));
+ buffer.appendFloat( getBoost(),1 );
+ }
+ return buffer.toString();
+ }
+
+
+ const TCHAR* RangeQuery::getField() const
+ {
+ return (lowerTerm != NULL ? lowerTerm->field() : upperTerm->field());
+ }
+
+ /** Returns the lower term of this range query */
+ Term* RangeQuery::getLowerTerm(bool pointer) const {
+ if ( pointer )
+ return _CL_POINTER(lowerTerm);
+ else
+ return lowerTerm;
+ }
+
+ /** Returns the upper term of this range query */
+ Term* RangeQuery::getUpperTerm(bool pointer) const {
+ if ( pointer )
+ return _CL_POINTER(upperTerm);
+ else
+ return upperTerm;
+ }
+
+ /** Returns <code>true</code> if the range query is inclusive */
+ bool RangeQuery::isInclusive() const { return inclusive; }
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/RangeQuery.h b/3rdparty/clucene/src/CLucene/search/RangeQuery.h
new file mode 100644
index 000000000..9a7733c33
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/RangeQuery.h
@@ -0,0 +1,71 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_RangeQuery_
+#define _lucene_search_RangeQuery_
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "SearchHeader.h"
+#include "Scorer.h"
+#include "TermQuery.h"
+
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+
+#include "CLucene/util/StringBuffer.h"
+
+
+CL_NS_DEF(search)
+ /** Constructs a query selecting all terms greater than
+ * <code>lowerTerm</code> but less than <code>upperTerm</code>.
+ * There must be at least one term and either term may be null,
+ * in which case there is no bound on that side, but if there are
+ * two terms, both terms <b>must</b> be for the same field.
+ */
+ class RangeQuery: public Query
+ {
+ private:
+ CL_NS(index)::Term* lowerTerm;
+ CL_NS(index)::Term* upperTerm;
+ bool inclusive;
+ protected:
+ RangeQuery(const RangeQuery& clone);
+
+ public:
+ // Constructs a query selecting all terms greater than
+ // <code>lowerTerm</code> but less than <code>upperTerm</code>.
+ // There must be at least one term and either term may be NULL--
+ // in which case there is no bound on that side, but if there are
+ // two term, both terms <b>must</b> be for the same field.
+ RangeQuery(CL_NS(index)::Term* LowerTerm, CL_NS(index)::Term* UpperTerm, const bool Inclusive);
+ ~RangeQuery();
+
+ const TCHAR* getQueryName() const;
+ static const TCHAR* getClassName();
+
+ Query* rewrite(CL_NS(index)::IndexReader* reader);
+
+ Query* combine(Query** queries);
+
+ // Prints a user-readable version of this query.
+ TCHAR* toString(const TCHAR* field) const;
+
+ Query* clone() const;
+
+ bool equals(Query * other) const;
+
+ CL_NS(index)::Term* getLowerTerm(bool pointer=true) const;
+ CL_NS(index)::Term* getUpperTerm(bool pointer=true) const;
+ bool isInclusive() const;
+ const TCHAR* getField() const;
+
+ size_t hashCode() const;
+ };
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/Scorer.h b/3rdparty/clucene/src/CLucene/search/Scorer.h
new file mode 100644
index 000000000..0d1d4355a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Scorer.h
@@ -0,0 +1,80 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_Scorer_
+#define _lucene_search_Scorer_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "Similarity.h"
+#include "SearchHeader.h"
+#include "Explanation.h"
+
+CL_NS_DEF(search)
+ /** Expert: Implements scoring for a class of queries. */
+class Scorer: LUCENE_BASE {
+ private:
+ Similarity* similarity;
+ protected:
+ /** Constructs a Scorer. */
+ Scorer(Similarity* similarity) {
+ this->similarity = similarity;
+ }
+ public:
+ virtual ~Scorer(){
+ }
+
+ /** Returns the Similarity implementation used by this scorer. */
+ Similarity* getSimilarity() const{
+ return this->similarity;
+ }
+
+ /** Scores all documents and passes them to a collector. */
+ void score(HitCollector* hc) {
+ while (next()) {
+ hc->collect(doc(), score());
+ }
+ }
+
+ /** Advance to the next document matching the query. Returns true iff there
+ * is another match. */
+ virtual bool next() = 0;
+
+ /** Returns the current document number. Initially invalid, until {@link
+ * #next()} is called the first time. */
+ virtual int32_t doc() const = 0;
+
+ /** Returns the score of the current document. Initially invalid, until
+ * {@link #next()} is called the first time. */
+ virtual qreal score() = 0;
+
+ /** Skips to the first match beyond the current whose document number is
+ * greater than or equal to <i>target</i>. <p>Returns true iff there is such
+ * a match. <p>Behaves as if written: <pre>
+ * boolean skipTo(int32_t target) {
+ * do {
+ * if (!next())
+ * return false;
+ * } while (target > doc());
+ * return true;
+ * }
+ * </pre>
+ * Most implementations are considerably more efficient than that.
+ */
+ virtual bool skipTo(int32_t target) = 0;
+
+ /** Returns an explanation of the score for <code>doc</code>. */
+ virtual void explain(int32_t doc, Explanation* ret) = 0;
+
+
+ /** Returns an string which explains the object */
+ virtual TCHAR* toString() = 0;
+
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/SearchHeader.cpp b/3rdparty/clucene/src/CLucene/search/SearchHeader.cpp
new file mode 100644
index 000000000..56e4ad585
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/SearchHeader.cpp
@@ -0,0 +1,141 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "SearchHeader.h"
+#include "BooleanQuery.h"
+#include "FieldDocSortedHitQueue.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+CL_NS(document)::Document* Searchable::doc(const int32_t i){
+ CL_NS(document)::Document* ret = _CLNEW CL_NS(document)::Document;
+ if (!doc(i,ret) )
+ _CLDELETE(ret);
+ return ret;
+}
+
+//static
+Query* Query::mergeBooleanQueries(Query** queries) {
+ CL_NS(util)::CLVector<BooleanClause*> allClauses;
+ int32_t i = 0;
+ while ( queries[i] != NULL ){
+ BooleanQuery* bq = (BooleanQuery*)queries[i];
+
+ int32_t size = bq->getClauseCount();
+ BooleanClause** clauses = _CL_NEWARRAY(BooleanClause*, size);
+ bq->getClauses(clauses);
+
+ for (int32_t j = 0;j<size;++j ){
+ allClauses.push_back(clauses[j]);
+ j++;
+ }
+ _CLDELETE_ARRAY(clauses);
+ i++;
+ }
+
+ BooleanQuery* result = _CLNEW BooleanQuery();
+ CL_NS(util)::CLVector<BooleanClause*>::iterator itr = allClauses.begin();
+ while (itr != allClauses.end() ) {
+ result->add(*itr);
+ }
+ return result;
+}
+
+Query::Query(const Query& clone):boost(clone.boost){
+ //constructor
+}
+Weight* Query::_createWeight(Searcher* searcher){
+ _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: Query::_createWeight");
+}
+
+Query::Query():
+ boost(1.0f)
+{
+ //constructor
+}
+Query::~Query(){
+}
+
+/** Expert: called to re-write queries into primitive queries. */
+Query* Query::rewrite(CL_NS(index)::IndexReader* reader){
+ return this;
+}
+
+Query* Query::combine(Query** queries){
+ _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: Query::combine");
+}
+Similarity* Query::getSimilarity(Searcher* searcher) {
+ return searcher->getSimilarity();
+}
+bool Query::instanceOf(const TCHAR* other) const{
+ const TCHAR* t = getQueryName();
+ if ( t==other || _tcscmp( t, other )==0 )
+ return true;
+ else
+ return false;
+}
+TCHAR* Query::toString() const{
+ return toString(LUCENE_BLANK_STRING);
+}
+
+void Query::setBoost(qreal b) { boost = b; }
+
+qreal Query::getBoost() const { return boost; }
+
+Weight* Query::weight(Searcher* searcher){
+ Query* query = searcher->rewrite(this);
+ Weight* weight = query->_createWeight(searcher);
+ qreal sum = weight->sumOfSquaredWeights();
+ qreal norm = getSimilarity(searcher)->queryNorm(sum);
+ weight->normalize(norm);
+ return weight;
+}
+
+TopFieldDocs::TopFieldDocs (int32_t totalHits, FieldDoc** fieldDocs, int32_t scoreDocsLen, SortField** fields):
+ TopDocs (totalHits, NULL, scoreDocsLen)
+{
+ this->fields = fields;
+ this->fieldDocs = fieldDocs;
+ this->scoreDocs = _CL_NEWARRAY(ScoreDoc,scoreDocsLen);
+ for (int32_t i=0;i<scoreDocsLen;i++ )
+ this->scoreDocs[i] = this->fieldDocs[i]->scoreDoc;
+}
+TopFieldDocs::~TopFieldDocs(){
+ if ( fieldDocs ){
+ for (int32_t i=0;i<scoreDocsLength;i++)
+ _CLDELETE(fieldDocs[i]);
+ _CLDELETE_ARRAY(fieldDocs);
+ }
+ if ( fields != NULL ){
+ for ( int i=0;fields[i]!=NULL;i++ )
+ _CLDELETE(fields[i]);
+ _CLDELETE_ARRAY(fields);
+ }
+}
+
+TopDocs::TopDocs(const int32_t th, ScoreDoc*sds, int32_t scoreDocsLen):
+ totalHits(th),
+ scoreDocsLength(scoreDocsLen),
+ scoreDocs(sds)
+{
+//Func - Constructor
+//Pre - sds may or may not be NULL
+// sdLength >= 0
+//Post - The instance has been created
+
+}
+
+TopDocs::~TopDocs(){
+//Func - Destructor
+//Pre - true
+//Post - The instance has been destroyed
+
+ _CLDELETE_ARRAY(scoreDocs);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/SearchHeader.h b/3rdparty/clucene/src/CLucene/search/SearchHeader.h
new file mode 100644
index 000000000..4a896a5c5
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/SearchHeader.h
@@ -0,0 +1,456 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_SearchHeader_
+#define _lucene_search_SearchHeader_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/index/Term.h"
+#include "Filter.h"
+#include "CLucene/document/Document.h"
+#include "Sort.h"
+#include "CLucene/util/VoidList.h"
+#include "Explanation.h"
+#include "Similarity.h"
+
+CL_NS_DEF(search)
+
+ //predefine classes
+ class Scorer;
+ class Query;
+ class Hits;
+ class Sort;
+ class FieldDoc;
+ class TopFieldDocs;
+
+ /** Expert: Returned by low-level search implementations.
+ * @see TopDocs */
+ struct ScoreDoc {
+ /** Expert: A hit document's number.
+ * @see Searcher#doc(int32_t)
+ */
+ int32_t doc;
+
+ /** Expert: The score of this document for the query. */
+ qreal score;
+ };
+
+ /** Expert: Returned by low-level search implementations.
+ * @see Searcher#search(Query,Filter,int32_t) */
+ class TopDocs:LUCENE_BASE {
+ public:
+ /** Expert: The total number of hits for the query.
+ * @see Hits#length()
+ */
+ int32_t totalHits;
+
+ /** Expert: The top hits for the query. */
+ ScoreDoc* scoreDocs;
+ int32_t scoreDocsLength;
+
+ /** Expert: Constructs a TopDocs. TopDocs takes ownership of the ScoreDoc array*/
+ TopDocs(const int32_t th, ScoreDoc* sds, int32_t scoreDocsLength);
+ ~TopDocs();
+ };
+
+ // Lower-level search API.
+ // @see Searcher#search(Query,HitCollector)
+ class HitCollector: LUCENE_BASE {
+ public:
+ /** Called once for every non-zero scoring document, with the document number
+ * and its score.
+ *
+ * <P>If, for example, an application wished to collect all of the hits for a
+ * query in a BitSet, then it might:<pre>
+ * Searcher searcher = new IndexSearcher(indexReader);
+ * final BitSet bits = new BitSet(indexReader.maxDoc());
+ * searcher.search(query, new HitCollector() {
+ * public void collect(int32_t doc, float score) {
+ * bits.set(doc);
+ * }
+ * });
+ * </pre>
+ *
+ * <p>Note: This is called in an inner search loop. For good search
+ * performance, implementations of this method should not call
+ * {@link Searcher#doc(int32_t)} or
+ * {@link IndexReader#document(int32_t)} on every
+ * document number encountered. Doing so can slow searches by an order
+ * of magnitude or more.
+ * <p>Note: The <code>score</code> passed to this method is a raw score.
+ * In other words, the score will not necessarily be a float whose value is
+ * between 0 and 1.
+ */
+ virtual void collect(const int32_t doc, const qreal score) = 0;
+ virtual ~HitCollector(){}
+ };
+
+ /** Expert: Calculate query weights and build query scorers.
+ *
+ * <p>A Weight is constructed by a query, given a Searcher ({@link
+ * Query#_createWeight(Searcher)}). The {@link #sumOfSquaredWeights()} method
+ * is then called on the top-level query to compute the query normalization
+ * factor (@link Similarity#queryNorm(qreal)}). This factor is then passed to
+ * {@link #normalize(qreal)}. At this point the weighting is complete and a
+ * scorer may be constructed by calling {@link #scorer(IndexReader)}.
+ */
+ class Weight: LUCENE_BASE {
+ public:
+ virtual ~Weight(){
+ };
+
+ /** The query that this concerns. */
+ virtual Query* getQuery() = 0;
+
+ /** The weight for this query. */
+ virtual qreal getValue() = 0;
+
+ /** The sum of squared weights of contained query clauses. */
+ virtual qreal sumOfSquaredWeights() = 0;
+
+ /** Assigns the query normalization factor to this. */
+ virtual void normalize(qreal norm) = 0;
+
+ /** Constructs a scorer for this. */
+ virtual Scorer* scorer(CL_NS(index)::IndexReader* reader) = 0;
+
+ /** An explanation of the score computation for the named document. */
+ virtual void explain(CL_NS(index)::IndexReader* reader, int32_t doc, Explanation* ret) = 0;
+
+ virtual TCHAR* toString(){
+ return STRDUP_TtoT(_T("Weight"));
+ }
+ };
+
+ class HitDoc:LUCENE_BASE {
+ public:
+ qreal score;
+ int32_t id;
+ CL_NS(document)::Document* doc;
+
+ HitDoc* next; // in doubly-linked cache
+ HitDoc* prev; // in doubly-linked cache
+
+ HitDoc(const qreal s, const int32_t i);
+ ~HitDoc();
+ };
+
+
+
+ // A ranked list of documents, used to hold search results.
+ class Hits:LUCENE_BASE {
+ private:
+ Query* query;
+ Searcher* searcher;
+ Filter* filter;
+ const Sort* sort;
+
+ size_t _length; // the total number of hits
+ CL_NS(util)::CLVector<HitDoc*, CL_NS(util)::Deletor::Object<HitDoc> > hitDocs; // cache of hits retrieved
+
+ HitDoc* first; // head of LRU cache
+ HitDoc* last; // tail of LRU cache
+ int32_t numDocs; // number cached
+ int32_t maxDocs; // max to cache
+
+ public:
+ Hits(Searcher* s, Query* q, Filter* f, const Sort* sort=NULL);
+ ~Hits();
+
+ /** Returns the total number of hits available in this set. */
+ int32_t length() const;
+
+ /** Returns the stored fields of the n<sup>th</sup> document in this set.
+ <p>Documents are cached, so that repeated requests for the same element may
+ return the same Document object.
+ *
+ * @memory Memory belongs to the hits object. Don't delete the return value.
+ */
+ CL_NS(document)::Document& doc(const int32_t n);
+
+ /** Returns the id for the nth document in this set. */
+ int32_t id (const int32_t n);
+
+ /** Returns the score for the nth document in this set. */
+ qreal score(const int32_t n);
+
+ private:
+ // Tries to add new documents to hitDocs.
+ // Ensures that the hit numbered <code>_min</code> has been retrieved.
+ void getMoreDocs(const size_t _min);
+
+ HitDoc* getHitDoc(const size_t n);
+
+ void addToFront(HitDoc* hitDoc);
+
+ void remove(const HitDoc* hitDoc);
+
+ };
+
+ /** The interface for search implementations.
+ *
+ * <p>Implementations provide search over a single index, over multiple
+ * indices, and over indices on remote servers.
+ */
+ class Searchable: LUCENE_BASE {
+ public:
+ virtual ~Searchable(){
+ }
+
+ /** Lower-level search API.
+ *
+ * <p>{@link HitCollector#collect(int32_t,qreal)} is called for every non-zero
+ * scoring document.
+ *
+ * <p>Applications should only use this if they need <i>all</i> of the
+ * matching documents. The high-level search API ({@link
+ * Searcher#search(Query*)}) is usually more efficient, as it skips
+ * non-high-scoring hits.
+ *
+ * @param query to match documents
+ * @param filter if non-null, a bitset used to eliminate some documents
+ * @param results to receive hits
+ */
+ virtual void _search(Query* query, Filter* filter, HitCollector* results) = 0;
+
+ /** Frees resources associated with this Searcher.
+ * Be careful not to call this method while you are still using objects
+ * like {@link Hits}.
+ */
+ virtual void close() = 0;
+
+ /** Expert: Returns the number of documents containing <code>term</code>.
+ * Called by search code to compute term weights.
+ * @see IndexReader#docFreq(Term).
+ */
+ virtual int32_t docFreq(const CL_NS(index)::Term* term) const = 0;
+
+ /** Expert: Returns one greater than the largest possible document number.
+ * Called by search code to compute term weights.
+ * @see IndexReader#maxDoc().
+ */
+ virtual int32_t maxDoc() const = 0;
+
+ /** Expert: Low-level search implementation. Finds the top <code>n</code>
+ * hits for <code>query</code>, applying <code>filter</code> if non-null.
+ *
+ * <p>Called by {@link Hits}.
+ *
+ * <p>Applications should usually call {@link Searcher#search(Query*)} or
+ * {@link Searcher#search(Query*,Filter*)} instead.
+ */
+ virtual TopDocs* _search(Query* query, Filter* filter, const int32_t n) = 0;
+
+ /** Expert: Returns the stored fields of document <code>i</code>.
+ * Called by {@link HitCollector} implementations.
+ * @see IndexReader#document(int32_t).
+ */
+ virtual bool doc(int32_t i, CL_NS(document)::Document* d) = 0;
+ _CL_DEPRECATED( doc(i, document) ) CL_NS(document)::Document* doc(const int32_t i);
+
+ /** Expert: called to re-write queries into primitive queries. */
+ virtual Query* rewrite(Query* query) = 0;
+
+ /** Returns an Explanation that describes how <code>doc</code> scored against
+ * <code>query</code>.
+ *
+ * <p>This is intended to be used in developing Similarity implementations,
+ * and, for good performance, should not be displayed with every hit.
+ * Computing an explanation is as expensive as executing the query over the
+ * entire index.
+ */
+ virtual void explain(Query* query, int32_t doc, Explanation* ret) = 0;
+
+ /** Expert: Low-level search implementation with arbitrary sorting. Finds
+ * the top <code>n</code> hits for <code>query</code>, applying
+ * <code>filter</code> if non-null, and sorting the hits by the criteria in
+ * <code>sort</code>.
+ *
+ * <p>Applications should usually call {@link
+ * Searcher#search(Query,Filter,Sort)} instead.
+ */
+ virtual TopFieldDocs* _search(Query* query, Filter* filter, const int32_t n, const Sort* sort) = 0;
+ };
+
+
+
+ /** An abstract base class for search implementations.
+ * Implements some common utility methods.
+ */
+ class Searcher:public Searchable {
+ private:
+ /** The Similarity implementation used by this searcher. */
+ Similarity* similarity;
+
+ public:
+ Searcher(){
+ similarity = Similarity::getDefault();
+ }
+ virtual ~Searcher(){
+ }
+
+ // Returns the documents matching <code>query</code>.
+ Hits* search(Query* query) {
+ return search(query, (Filter*)NULL );
+ }
+
+ // Returns the documents matching <code>query</code> and
+ // <code>filter</code>.
+ Hits* search(Query* query, Filter* filter) {
+ return _CLNEW Hits(this, query, filter);
+ }
+
+ /** Returns documents matching <code>query</code> sorted by
+ * <code>sort</code>.
+ */
+ Hits* search(Query* query, const Sort* sort){
+ return _CLNEW Hits(this, query, NULL, sort);
+ }
+
+ /** Returns documents matching <code>query</code> and <code>filter</code>,
+ * sorted by <code>sort</code>.
+ */
+ Hits* search(Query* query, Filter* filter, const Sort* sort){
+ return _CLNEW Hits(this, query, filter, sort);
+ }
+
+ /** Lower-level search API.
+ *
+ * <p>{@link HitCollector#collect(int32_t ,qreal)} is called for every non-zero
+ * scoring document.
+ *
+ * <p>Applications should only use this if they need <i>all</i> of the
+ * matching documents. The high-level search API ({@link
+ * Searcher#search(Query*)}) is usually more efficient, as it skips
+ * non-high-scoring hits.
+ * <p>Note: The <code>score</code> passed to this method is a raw score.
+ * In other words, the score will not necessarily be a float whose value is
+ * between 0 and 1.
+ */
+ void _search(Query* query, HitCollector* results) {
+ Searchable::_search(query, NULL, results);
+ }
+
+ /** Expert: Set the Similarity implementation used by this Searcher.
+ *
+ * @see Similarity#setDefault(Similarity)
+ */
+ void setSimilarity(Similarity* similarity) {
+ this->similarity = similarity;
+ }
+
+ /** Expert: Return the Similarity implementation used by this Searcher.
+ *
+ * <p>This defaults to the current value of {@link Similarity#getDefault()}.
+ */
+ Similarity* getSimilarity(){
+ return this->similarity;
+ }
+ };
+
+ /** The abstract base class for queries.
+ <p>Instantiable subclasses are:
+ <ul>
+ <li> {@link TermQuery}
+ <li> {@link MultiTermQuery}
+ <li> {@link BooleanQuery}
+ <li> {@link WildcardQuery}
+ <li> {@link PhraseQuery}
+ <li> {@link PrefixQuery}
+ <li> {@link PhrasePrefixQuery}
+ <li> {@link FuzzyQuery}
+ <li> {@link RangeQuery}
+ <li> {@link spans.SpanQuery}
+ </ul>
+ <p>A parser for queries is contained in:
+ <ul>
+ <li>{@link queryParser.QueryParser QueryParser}
+ </ul>
+ */
+ class Query :LUCENE_BASE {
+ private:
+ // query boost factor
+ qreal boost;
+ protected:
+ Query(const Query& clone);
+ public:
+ Query();
+ virtual ~Query();
+
+ /** Sets the boost for this query clause to <code>b</code>. Documents
+ * matching this clause will (in addition to the normal weightings) have
+ * their score multiplied by <code>b</code>.
+ */
+ void setBoost(qreal b);
+
+ /** Gets the boost for this clause. Documents matching
+ * this clause will (in addition to the normal weightings) have their score
+ * multiplied by <code>b</code>. The boost is 1.0 by default.
+ */
+ qreal getBoost() const;
+
+ /** Expert: Constructs an initializes a Weight for a top-level query. */
+ Weight* weight(Searcher* searcher);
+
+ /** Expert: called to re-write queries into primitive queries. */
+ virtual Query* rewrite(CL_NS(index)::IndexReader* reader);
+
+ /** Expert: called when re-writing queries under MultiSearcher.
+ *
+ * <p>Only implemented by derived queries, with no
+ * {@link #_createWeight(Searcher)} implementatation.
+ */
+ virtual Query* combine(Query** queries);
+
+ /** Expert: merges the clauses of a set of BooleanQuery's into a single
+ * BooleanQuery.
+ *
+ *<p>A utility for use by {@link #combine(Query[])} implementations.
+ */
+ static Query* mergeBooleanQueries(Query** queries);
+
+ /** Expert: Returns the Similarity implementation to be used for this query.
+ * Subclasses may override this method to specify their own Similarity
+ * implementation, perhaps one that delegates through that of the Searcher.
+ * By default the Searcher's Similarity implementation is returned.*/
+ Similarity* getSimilarity(Searcher* searcher);
+
+ /** Returns a clone of this query. */
+ virtual Query* clone() const = 0;
+ virtual const TCHAR* getQueryName() const = 0;
+ bool instanceOf(const TCHAR* other) const;
+
+ /** Prints a query to a string, with <code>field</code> as the default field
+ * for terms. <p>The representation used is one that is readable by
+ * {@link queryParser.QueryParser QueryParser}
+ * (although, if the query was created by the parser, the printed
+ * representation may not be exactly what was parsed).
+ */
+ virtual TCHAR* toString(const TCHAR* field) const = 0;
+
+ virtual bool equals(Query* other) const = 0;
+ virtual size_t hashCode() const = 0;
+
+ /** Prints a query to a string. */
+ TCHAR* toString() const;
+
+
+ /** Expert: Constructs an appropriate Weight implementation for this query.
+ *
+ * <p>Only implemented by primitive queries, which re-write to themselves.
+ * <i>This is an Internal function</i>
+ */
+ virtual Weight* _createWeight(Searcher* searcher);
+
+ };
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/Similarity.cpp b/3rdparty/clucene/src/CLucene/search/Similarity.cpp
new file mode 100644
index 000000000..d33a036e4
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Similarity.cpp
@@ -0,0 +1,233 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "Similarity.h"
+
+#include "CLucene/index/Term.h"
+#include "SearchHeader.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+#ifdef _CL_HAVE_NO_FLOAT_BYTE
+ #if defined(_LUCENE_PRAGMA_WARNINGS)
+ #pragma message ("==================Using fallback float<->byte encodings!!!==================")
+ #else
+ #warning "==================Using fallback float<->byte encodings!!!=================="
+ #endif
+
+ //if the autoconf figured out that we can't do the conversions properly, then
+ //we fall back on the old, inaccurate way of doing things.
+ qreal NORM_TABLE[] = {
+ 0.0,5.820766E-10,6.9849193E-10,8.1490725E-10,9.313226E-10,1.1641532E-9,1.3969839E-9,
+ 1.6298145E-9,1.8626451E-9,2.3283064E-9,2.7939677E-9,3.259629E-9,3.7252903E-9,
+ 4.656613E-9,5.5879354E-9,6.519258E-9,7.4505806E-9,9.313226E-9,1.1175871E-8,1.3038516E-8,
+ 1.4901161E-8,1.8626451E-8,2.2351742E-8,2.6077032E-8,2.9802322E-8,3.7252903E-8,4.4703484E-8,
+ 5.2154064E-8,5.9604645E-8,7.4505806E-8,8.940697E-8,1.0430813E-7,1.1920929E-7,1.4901161E-7,
+ 1.7881393E-7,2.0861626E-7,2.3841858E-7,2.9802322E-7,3.5762787E-7,4.172325E-7,4.7683716E-7,
+ 5.9604645E-7,7.1525574E-7,8.34465E-7,9.536743E-7,1.1920929E-6,1.4305115E-6,1.66893E-6,
+ 1.9073486E-6,2.3841858E-6,2.861023E-6,3.33786E-6,3.8146973E-6,4.7683716E-6,5.722046E-6,
+ 6.67572E-6,7.6293945E-6,9.536743E-6,1.1444092E-5,1.335144E-5,1.5258789E-5,1.9073486E-5,
+ 2.2888184E-5,2.670288E-5,3.0517578E-5,3.8146973E-5,4.5776367E-5,5.340576E-5,6.1035156E-5,
+ 7.6293945E-5,9.1552734E-5,1.0681152E-4,1.2207031E-4,1.5258789E-4,1.8310547E-4,2.1362305E-4,
+ 2.4414062E-4,3.0517578E-4,3.6621094E-4,4.272461E-4,4.8828125E-4,6.1035156E-4,7.324219E-4,
+ 8.544922E-4,9.765625E-4,0.0012207031,0.0014648438,0.0017089844,0.001953125,0.0024414062,
+ 0.0029296875,0.0034179688,0.00390625,0.0048828125,0.005859375,0.0068359375,
+ 0.0078125,0.009765625,0.01171875,0.013671875,0.015625,0.01953125,0.0234375,
+ 0.02734375,0.03125,0.0390625,0.046875,0.0546875,0.0625,0.078125,0.09375,0.109375,
+ 0.125,0.15625,0.1875,0.21875,0.25,0.3125,0.375,0.4375,0.5,0.625,0.75,
+ 0.875,1.0,1.25,1.5,1.75,2,2.5,3,3.5,4.0,5.0,6.0,7.0,8.0,10.0,12.0,14.0,16.0,20.0,24.0,28.0,32.0,40.0,48.0,56.0,
+ 64.0,80.0,96.0,112.0,128.0,160.0,192.0,224.0,256.0,320.0,384.0,448.0,512.0,640.0,768.0,896.0,1024.0,1280.0,1536.0,1792.0,
+ 2048.0,2560.0,3072.0,3584.0,4096.0,5120.0,6144.0,7168.0,8192.0,10240.0,12288.0,14336.0,16384.0,20480.0,24576.0,
+ 28672.0,32768.0,40960.0,49152.0,57344.0,65536.0,81920.0,98304.0,114688.0,131072.0,163840.0,196608.0,
+ 229376.0,262144.0,327680.0,393216.0,458752.0,524288.0,655360.0,786432.0,917504.0,1048576.0,1310720.0,
+ 1572864.0,1835008.0,2097152.0,2621440.0,3145728.0,3670016.0,4194304.0,5242880.0,6291456.0,7340032.0,
+ 8388608.0,10485760.0,12582912.0,14680064.0,16777216.0,20971520.0,25165824.0,29360128.0,33554432.0,
+ 41943040.0,50331648.0,58720256.0,67108864.0,83886080.0,100663296.0,117440512.0,134217728.0,
+ 167772160.0,201326592.0,234881024.0,268435456.0,335544320.0,402653184.0,469762048.0,536870912.0,
+ 671088640.0,805306368.0,939524096.0,1073741824.0,1342177280.0,1610612736.0,1879048192.0,
+ 2147483648.0,2684354560.0,3221225472.0,3758096384.0,4294967296.0,5368709120.0,6442450944.0,7516192768.0
+ };
+
+ qreal Similarity::byteToFloat(uint8_t b) {
+ return NORM_TABLE[b];
+ }
+
+ uint8_t Similarity::floatToByte(qreal f) {
+ return Similarity::encodeNorm(f);
+ }
+
+#else
+
+ /** Cache of decoded bytes. */
+ qreal NORM_TABLE[256];
+ bool NORM_TABLE_initd=false;
+
+ //float to bits conversion utilities...
+ union clvalue {
+ int32_t i;
+ float f; //must use a float type, else types dont match up
+ };
+
+ int32_t floatToIntBits(qreal value)
+ {
+ clvalue u;
+ int32_t e, f;
+ u.f = (float)value;
+ e = u.i & 0x7f800000;
+ f = u.i & 0x007fffff;
+
+ if (e == 0x7f800000 && f != 0)
+ u.i = 0x7fc00000;
+
+ return u.i;
+ }
+
+ qreal intBitsToFloat(int32_t bits)
+ {
+ clvalue u;
+ u.i = bits;
+ return u.f;
+ }
+
+
+ qreal Similarity::byteToFloat(uint8_t b) {
+ if (b == 0) // zero is a special case
+ return 0.0f;
+ int32_t mantissa = b & 7;
+ int32_t exponent = (b >> 3) & 31;
+ int32_t bits = ((exponent+(63-15)) << 24) | (mantissa << 21);
+ return intBitsToFloat(bits);
+ }
+
+ uint8_t Similarity::floatToByte(qreal f) {
+ if (f < 0.0f) // round negatives up to zero
+ f = 0.0f;
+
+ if (f == 0.0f) // zero is a special case
+ return 0;
+
+ int32_t bits = floatToIntBits(f); // parse qreal into parts
+ int32_t mantissa = (bits & 0xffffff) >> 21;
+ int32_t exponent = (((bits >> 24) & 0x7f) - 63) + 15;
+
+ if (exponent > 31) { // overflow: use max value
+ exponent = 31;
+ mantissa = 7;
+ }
+
+ if (exponent < 0) { // underflow: use min value
+ exponent = 0;
+ mantissa = 1;
+ }
+
+ return (uint8_t)((exponent << 3) | mantissa); // pack into a uint8_t
+ }
+#endif
+
+ /** The Similarity implementation used by default. */
+ Similarity* _defaultImpl=NULL;
+
+ void Similarity::setDefault(Similarity* similarity) {
+ _defaultImpl = similarity;
+ }
+
+ Similarity* Similarity::getDefault() {
+ if ( _defaultImpl == NULL ){
+ _defaultImpl = _CLNEW DefaultSimilarity();
+ }
+ return _defaultImpl;
+ }
+
+ qreal Similarity::decodeNorm(uint8_t b) {
+#ifndef _CL_HAVE_NO_FLOAT_BYTE
+ if ( !NORM_TABLE_initd ){
+ for (int i = 0; i < 256; i++)
+ NORM_TABLE[i] = byteToFloat(i);
+ NORM_TABLE_initd=true;
+ }
+#endif
+ return NORM_TABLE[b];
+ }
+
+ uint8_t Similarity::encodeNorm(qreal f) {
+#ifdef _CL_HAVE_NO_FLOAT_BYTE
+ int32_t i=0;
+ if ( f <= 0 )
+ return 0;
+
+ while ( i<256 && f > NORM_TABLE[i] ){
+ i++;
+ }
+ if ( i == 0 )
+ return 0;
+ else if ( i == 255 && f>NORM_TABLE[255] )
+ return 255;
+ else
+ return i;
+#else
+ return floatToByte(f);
+#endif
+ }
+
+
+ qreal Similarity::idf(Term* term, Searcher* searcher) {
+ return idf(searcher->docFreq(term), searcher->maxDoc());
+ }
+
+
+ qreal Similarity::idf(CL_NS(util)::CLVector<Term*>* terms, Searcher* searcher) {
+ qreal _idf = 0.0f;
+ for (CL_NS(util)::CLVector<Term*>::iterator i = terms->begin(); i != terms->end(); i++ ) {
+ _idf += idf((Term*)*i, searcher);
+ }
+ return _idf;
+ }
+
+ Similarity::~Similarity(){
+ }
+
+
+
+
+ DefaultSimilarity::DefaultSimilarity(){
+ }
+ DefaultSimilarity::~DefaultSimilarity(){
+ }
+
+ qreal DefaultSimilarity::lengthNorm(const TCHAR* fieldName, int32_t numTerms) {
+ if ( numTerms == 0 ) //prevent div by zero
+ return 0;
+ qreal ret = (qreal)(1.0 / sqrt((qreal)numTerms));
+ return ret;
+ }
+
+ qreal DefaultSimilarity::queryNorm(qreal sumOfSquaredWeights) {
+ if ( sumOfSquaredWeights == 0 ) //prevent div by zero
+ return 0.0f;
+ qreal ret = (qreal)(1.0 / sqrt(sumOfSquaredWeights));
+ return ret;
+ }
+
+ qreal DefaultSimilarity::tf(qreal freq) {
+ return sqrt(freq);
+ }
+
+ qreal DefaultSimilarity::sloppyFreq(int32_t distance) {
+ return 1.0f / (distance + 1);
+ }
+
+ qreal DefaultSimilarity::idf(int32_t docFreq, int32_t numDocs) {
+ return (qreal)(log(numDocs/(qreal)(docFreq+1)) + 1.0);
+ }
+
+ qreal DefaultSimilarity::coord(int32_t overlap, int32_t maxOverlap) {
+ if ( maxOverlap == 0 )
+ return 0.0f;
+ return overlap / (qreal)maxOverlap;
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/Similarity.h b/3rdparty/clucene/src/CLucene/search/Similarity.h
new file mode 100644
index 000000000..426af6952
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Similarity.h
@@ -0,0 +1,268 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_Similarity_
+#define _lucene_search_Similarity_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/Term.h"
+
+CL_NS_DEF(search)
+
+class Searcher;//save including the searchheader.h
+class DefaultSimilarity;
+
+/** Expert: Scoring API.
+* <p>Subclasses implement search scoring.
+*
+* <p>The score of query <code>q</code> for document <code>d</code> is defined
+* in terms of these methods as follows:
+*
+* <table cellpadding="0" cellspacing="0" border="0">
+* <tr>
+* <td valign="middle" align="right" rowspan="2">score(q,d) =<br></td>
+* <td valign="middle" align="center">
+* <big><big><big><big><big>&Sigma;</big></big></big></big></big></td>
+* <td valign="middle"><small>
+* {@link #tf(int32_t) tf}(t in d) *
+* {@link #idf(Term,Searcher) idf}(t) *
+* {@link Field#getBoost getBoost}(t.field in d) *
+* {@link #lengthNorm(TCHAR*,int32_t) lengthNorm}(t.field in d)
+* </small></td>
+* <td valign="middle" rowspan="2">&nbsp;*
+* {@link #coord(int32_t,int32_t) coord}(q,d) *
+* {@link #queryNorm(qreal) queryNorm}(q)
+* </td>
+* </tr>
+* <tr>
+* <td valign="top" align="right">
+* <small>t in q</small>
+* </td>
+* </tr>
+* </table>
+*
+* @see #setDefault(Similarity)
+* @see IndexWriter#setSimilarity(Similarity)
+* @see Searcher#setSimilarity(Similarity)
+*/
+class Similarity:LUCENE_BASE {
+public:
+ virtual ~Similarity();
+
+ /** Set the default Similarity implementation used by indexing and search
+ * code.
+ *
+ * @see Searcher#setSimilarity(Similarity)
+ * @see IndexWriter#setSimilarity(Similarity)
+ */
+ static void setDefault(Similarity* similarity);
+
+ /** Return the default Similarity implementation used by indexing and search
+ * code.
+ *
+ * <p>This is initially an instance of {@link DefaultSimilarity}.
+ *
+ * @see Searcher#setSimilarity(Similarity)
+ * @see IndexWriter#setSimilarity(Similarity)
+ */
+ static Similarity* getDefault();
+
+ /** Encodes a normalization factor for storage in an index.
+ *
+ * <p>The encoding uses a five-bit exponent and three-bit mantissa, thus
+ * representing values from around 7x10^9 to 2x10^-9 with about one
+ * significant decimal digit of accuracy. Zero is also represented.
+ * Negative numbers are rounded up to zero. Values too large to represent
+ * are rounded down to the largest representable value. Positive values too
+ * small to represent are rounded up to the smallest positive representable
+ * value.
+ *
+ * @see Field#setBoost(qreal)
+ */
+ static uint8_t encodeNorm(qreal f);
+
+ /** Decodes a normalization factor stored in an index.
+ * @see #encodeNorm(qreal)
+ */
+ static qreal decodeNorm(uint8_t b);
+
+ static uint8_t floatToByte(qreal f);
+ static qreal byteToFloat(uint8_t b);
+
+ /** Computes a score factor for a phrase.
+ *
+ * <p>The default implementation sums the {@link #idf(Term,Searcher)} factor
+ * for each term in the phrase.
+ *
+ * @param terms the terms in the phrase
+ * @param searcher the document collection being searched
+ * @return a score factor for the phrase
+ */
+ qreal idf(CL_NS(util)::CLVector<CL_NS(index)::Term*>* terms, Searcher* searcher);
+ //qreal idf(Term** terms, Searcher* searcher);
+
+
+ /** Computes a score factor for a simple term.
+ *
+ * <p>The default implementation is:<pre>
+ * return idf(searcher.docFreq(term), searcher.maxDoc());
+ * </pre>
+ *
+ * Note that {@link Searcher#maxDoc()} is used instead of
+ * {@link IndexReader#numDocs()} because it is proportional to
+ * {@link Searcher#docFreq(Term)} , i.e., when one is inaccurate,
+ * so is the other, and in the same direction.
+ *
+ * @param term the term in question
+ * @param searcher the document collection being searched
+ * @return a score factor for the term
+ */
+ qreal idf(CL_NS(index)::Term* term, Searcher* searcher);
+
+
+ /** Computes a score factor based on a term or phrase's frequency in a
+ * document. This value is multiplied by the {@link #idf(Term, Searcher)}
+ * factor for each term in the query and these products are then summed to
+ * form the initial score for a document.
+ *
+ * <p>Terms and phrases repeated in a document indicate the topic of the
+ * document, so implementations of this method usually return larger values
+ * when <code>freq</code> is large, and smaller values when <code>freq</code>
+ * is small.
+ *
+ * <p>The default implementation calls {@link #tf(qreal)}.
+ *
+ * @param freq the frequency of a term within a document
+ * @return a score factor based on a term's within-document frequency
+ */
+ inline qreal tf(int32_t freq){ return tf((qreal)freq); }
+
+ /** Computes the normalization value for a field given the total number of
+ * terms contained in a field. These values, together with field boosts, are
+ * stored in an index and multipled into scores for hits on each field by the
+ * search code.
+ *
+ * <p>Matches in longer fields are less precise, so implemenations of this
+ * method usually return smaller values when <code>numTokens</code> is large,
+ * and larger values when <code>numTokens</code> is small.
+ *
+ * <p>That these values are computed under {@link
+ * IndexWriter#addDocument(Document)} and stored then using
+ * {#encodeNorm(qreal)}. Thus they have limited precision, and documents
+ * must be re-indexed if this method is altered.
+ *
+ * @param fieldName the name of the field
+ * @param numTokens the total number of tokens contained in fields named
+ * <i>fieldName</i> of <i>doc</i>.
+ * @return a normalization factor for hits on this field of this document
+ *
+ * @see Field#setBoost(qreal)
+ */
+ virtual qreal lengthNorm(const TCHAR* fieldName, int32_t numTokens) = 0;
+
+ /** Computes the normalization value for a query given the sum of the squared
+ * weights of each of the query terms. This value is then multipled into the
+ * weight of each query term.
+ *
+ * <p>This does not affect ranking, but rather just attempts to make scores
+ * from different queries comparable.
+ *
+ * @param sumOfSquaredWeights the sum of the squares of query term weights
+ * @return a normalization factor for query weights
+ */
+ virtual qreal queryNorm(qreal sumOfSquaredWeights) = 0;
+
+ /** Computes the amount of a sloppy phrase match, based on an edit distance.
+ * This value is summed for each sloppy phrase match in a document to form
+ * the frequency that is passed to {@link #tf(qreal)}.
+ *
+ * <p>A phrase match with a small edit distance to a document passage more
+ * closely matches the document, so implementations of this method usually
+ * return larger values when the edit distance is small and smaller values
+ * when it is large.
+ *
+ * @see PhraseQuery#setSlop(int32_t)
+ * @param distance the edit distance of this sloppy phrase match
+ * @return the frequency increment for this match
+ */
+ virtual qreal sloppyFreq(int32_t distance) = 0;
+
+ /** Computes a score factor based on a term or phrase's frequency in a
+ * document. This value is multiplied by the {@link #idf(Term, Searcher)}
+ * factor for each term in the query and these products are then summed to
+ * form the initial score for a document.
+ *
+ * <p>Terms and phrases repeated in a document indicate the topic of the
+ * document, so implemenations of this method usually return larger values
+ * when <code>freq</code> is large, and smaller values when <code>freq</code>
+ * is small.
+ *
+ * @param freq the frequency of a term within a document
+ * @return a score factor based on a term's within-document frequency
+ */
+ virtual qreal tf(qreal freq) = 0;
+
+ /** Computes a score factor based on a term's document frequency (the number
+ * of documents which contain the term). This value is multiplied by the
+ * {@link #tf(int32_t)} factor for each term in the query and these products are
+ * then summed to form the initial score for a document.
+ *
+ * <p>Terms that occur in fewer documents are better indicators of topic, so
+ * implemenations of this method usually return larger values for rare terms,
+ * and smaller values for common terms.
+ *
+ * @param docFreq the number of documents which contain the term
+ * @param numDocs the total number of documents in the collection
+ * @return a score factor based on the term's document frequency
+ */
+ virtual qreal idf(int32_t docFreq, int32_t numDocs) = 0;
+
+ /** Computes a score factor based on the fraction of all query terms that a
+ * document contains. This value is multiplied into scores.
+ *
+ * <p>The presence of a large portion of the query terms indicates a better
+ * match with the query, so implemenations of this method usually return
+ * larger values when the ratio between these parameters is large and smaller
+ * values when the ratio between them is small.
+ *
+ * @param overlap the number of query terms matched in the document
+ * @param maxOverlap the total number of terms in the query
+ * @return a score factor based on term overlap with the query
+ */
+ virtual qreal coord(int32_t overlap, int32_t maxOverlap) = 0;
+};
+
+
+/** Expert: Default scoring implementation. */
+class DefaultSimilarity: public Similarity {
+public:
+ DefaultSimilarity();
+ ~DefaultSimilarity();
+
+ /** Implemented as <code>1/sqrt(numTerms)</code>. */
+ qreal lengthNorm(const TCHAR* fieldName, int32_t numTerms);
+
+ /** Implemented as <code>1/sqrt(sumOfSquaredWeights)</code>. */
+ qreal queryNorm(qreal sumOfSquaredWeights);
+
+ /** Implemented as <code>sqrt(freq)</code>. */
+ inline qreal tf(qreal freq);
+
+ /** Implemented as <code>1 / (distance + 1)</code>. */
+ qreal sloppyFreq(int32_t distance);
+
+ /** Implemented as <code>log(numDocs/(docFreq+1)) + 1</code>. */
+ qreal idf(int32_t docFreq, int32_t numDocs);
+
+ /** Implemented as <code>overlap / maxOverlap</code>. */
+ qreal coord(int32_t overlap, int32_t maxOverlap);
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/SloppyPhraseScorer.cpp b/3rdparty/clucene/src/CLucene/search/SloppyPhraseScorer.cpp
new file mode 100644
index 000000000..b7683b018
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/SloppyPhraseScorer.cpp
@@ -0,0 +1,106 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "SloppyPhraseScorer.h"
+
+#include "PhraseScorer.h"
+#include "CLucene/index/Terms.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+ SloppyPhraseScorer::SloppyPhraseScorer(Weight* weight, CL_NS(index)::TermPositions** tps,
+ int32_t* positions, Similarity* similarity,
+ int32_t slop, uint8_t* norms):
+ PhraseScorer(weight,tps,positions,similarity,norms){
+ //Func - Constructor
+ //Pre - tps != NULL
+ // tpsLength >= 0
+ // n != NULL
+ //Post - Instance has been created
+
+ CND_PRECONDITION(tps != NULL, "tps is NULL");
+ //CND_PRECONDITION(n != NULL, _T("n is NULL")) = checked in PhraseScorer;
+
+ this->slop = slop;
+ }
+
+ qreal SloppyPhraseScorer::phraseFreq() {
+ //Func - Returns the freqency of the phrase
+ //Pre - first != NULL
+ // last != NULL
+ // pq != NULL
+ //Post - The frequency of the phrase has been returned
+
+ CND_PRECONDITION(first != NULL,"first is NULL");
+ CND_PRECONDITION(last != NULL,"last is NULL");
+ CND_PRECONDITION(pq != NULL,"pq is NULL");
+
+ //Clear the PhraseQueue pq;
+ pq->clear();
+
+ int32_t end = 0;
+
+ //declare iterator
+ PhrasePositions* pp = NULL;
+
+ // build pq from list
+
+ //Sort the list of PhrasePositions using pq
+ for (pp = first; pp != NULL; pp = pp->_next) {
+ //Read the first TermPosition of the current PhrasePositions pp
+ pp->firstPosition();
+ //Check if the position of the pp is bigger than end
+ if (pp->position > end){
+ end = pp->position;
+ }
+ //Store the current PhrasePositions pp into the PhraseQueue pp
+ pq->put(pp);
+ }
+
+ qreal freq = 0.0f;
+
+ bool done = false;
+
+ do {
+ //Pop a PhrasePositions pp from the PhraseQueue pp
+ pp = pq->pop();
+ //Get start position
+ int32_t start = pp->position;
+ //Get next position
+ int32_t next = pq->top()->position;
+
+ for (int32_t pos = start; pos <= next; pos = pp->position) {
+ //advance pp to min window
+ start = pos;
+
+ if (!pp->nextPosition()) {
+ //ran out of a term -- done
+ done = true;
+ break;
+ }
+ }
+
+ //Calculate matchLength
+ int32_t matchLength = end - start;
+ //Check if matchLength is smaller than slop
+ if (matchLength <= slop){
+ // penalize longer matches
+ freq += 1.0 / (matchLength + 1);
+ }
+
+ if (pp->position > end){
+ end = pp->position;
+ }
+
+ //restore pq
+ pq->put(pp);
+ }while (!done);
+
+ return freq;
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/SloppyPhraseScorer.h b/3rdparty/clucene/src/CLucene/search/SloppyPhraseScorer.h
new file mode 100644
index 000000000..31516e393
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/SloppyPhraseScorer.h
@@ -0,0 +1,34 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_SloppyPhraseScorer_
+#define _lucene_search_SloppyPhraseScorer_
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "PhraseScorer.h"
+#include "CLucene/index/Terms.h"
+
+
+CL_NS_DEF(search)
+ class SloppyPhraseScorer: public PhraseScorer {
+ private:
+ int32_t slop;
+
+ public:
+ SloppyPhraseScorer(Weight* weight, CL_NS(index)::TermPositions** tps,
+ int32_t* positions, Similarity* similarity,
+ int32_t slop, uint8_t* norms);
+ ~SloppyPhraseScorer(){
+ }
+
+ protected:
+ qreal phraseFreq();
+ };
+CL_NS_END
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/search/Sort.cpp b/3rdparty/clucene/src/CLucene/search/Sort.cpp
new file mode 100644
index 000000000..5a17a784d
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Sort.cpp
@@ -0,0 +1,345 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "Sort.h"
+#include "Compare.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+
+
+ /** Represents sorting by document score (relevancy). */
+ SortField* SortField::FIELD_SCORE = _CLNEW SortField (NULL, DOCSCORE,false);
+
+ /** Represents sorting by document number (index order). */
+ SortField* SortField::FIELD_DOC = _CLNEW SortField (NULL, DOC,false);
+
+
+ /** Represents sorting by computed relevance. Using this sort criteria
+ * returns the same results as calling {@link Searcher#search(Query) Searcher#search()}
+ * without a sort criteria, only with slightly more overhead. */
+ Sort* Sort::RELEVANCE = _CLNEW Sort();
+
+ /** Represents sorting by index order. */
+ Sort* Sort::INDEXORDER = _CLNEW Sort (SortField::FIELD_DOC);
+
+
+
+
+ /** Creates a sort by terms in the given field where the type of term value
+ * is determined dynamically ({@link #AUTO AUTO}).
+ * @param field Name of field to sort by, cannot be <code>null</code>.
+ */
+ SortField::SortField (const TCHAR* field) {
+ this->type = AUTO;
+ this->reverse = false;
+ this->field = CLStringIntern::intern(field CL_FILELINE);
+ this->factory = NULL;
+ }
+
+ /** Creates a sort, possibly in reverse, by terms in the given field where
+ * the type of term value is determined dynamically ({@link #AUTO AUTO}).
+ * @param field Name of field to sort by, cannot be <code>null</code>.
+ * @param reverse True if natural order should be reversed.
+
+ SortField::SortField (const TCHAR* field, bool reverse) {
+ this->field = CLStringIntern::intern(field CL_FILELINE);
+ this->reverse = reverse;
+ this->type = AUTO;
+ this->factory = NULL;
+ }*/
+
+
+ /** Creates a sort, possibly in reverse, by terms in the given field with the
+ * type of term values explicitly given.
+ * @param field Name of field to sort by. Can be <code>null</code> if
+ * <code>type</code> is SCORE or DOC.
+ * @param type Type of values in the terms.
+ * @param reverse True if natural order should be reversed (default=false).
+ */
+ SortField::SortField (const TCHAR* field, int32_t type, bool reverse) {
+ this->field = (field != NULL) ? CLStringIntern::intern(field CL_FILELINE) : field;
+ this->type = type;
+ this->reverse = reverse;
+ this->factory = NULL;
+ }
+
+ SortField::SortField(const SortField& clone){
+ this->field = (clone.field != NULL) ? CLStringIntern::intern(clone.field CL_FILELINE) : clone.field;
+ this->type = clone.type;
+ this->reverse = clone.reverse;
+ this->factory = clone.factory;
+ }
+ SortField* SortField::clone() const{
+ return _CLNEW SortField(*this);
+ }
+
+ /** Creates a sort by terms in the given field sorted
+ * according to the given locale.
+ * @param field Name of field to sort by, cannot be <code>null</code>.
+ * @param locale Locale of values in the field.
+ */
+ /*SortField::SortField (TCHAR* field, Locale* locale) {
+ this->field = (field != NULL) ? CLStringIntern::intern(field): field;
+ this->type = STRING;
+ this->locale = locale;
+ }*/
+
+ /** Creates a sort, possibly in reverse, by terms in the given field sorted
+ * according to the given locale.
+ * @param field Name of field to sort by, cannot be <code>null</code>.
+ * @param locale Locale of values in the field.
+ */
+ /*SortField::SortField (TCHAR* field, Locale* locale, bool reverse) {
+ this->field = (field != NULL) ? CLStringIntern::intern(field): field;
+ this->type = STRING;
+ this->locale = locale;
+ this->reverse = reverse;
+ }*/
+
+
+ /** Creates a sort, possibly in reverse, with a custom comparison function.
+ * @param field Name of field to sort by; cannot be <code>null</code>.
+ * @param comparator Returns a comparator for sorting hits.
+ * @param reverse True if natural order should be reversed (default=false).
+ */
+ SortField::SortField (const TCHAR* field, SortComparatorSource* comparator, bool reverse) {
+ this->field = (field != NULL) ? CLStringIntern::intern(field CL_FILELINE): field;
+ this->type = CUSTOM;
+ this->reverse = reverse;
+ this->factory = comparator;
+ }
+
+ SortField::~SortField(){
+ CLStringIntern::unintern(field);
+ }
+
+ TCHAR* SortField::toString() const {
+ CL_NS(util)::StringBuffer buffer;
+ switch (type) {
+ case DOCSCORE: buffer.append(_T("<score>"));
+ break;
+
+ case DOC: buffer.append(_T("<doc>"));
+ break;
+
+ case CUSTOM: buffer.append (_T("<custom:\""));
+ buffer.append( field );
+ buffer.append( _T("\": "));
+ buffer.append(factory->getName());
+ buffer.append(_T(">"));
+ break;
+
+ default: buffer.append( _T("\""));
+ buffer.append( field );
+ buffer.append( _T("\"") );
+ break;
+ }
+
+ //if (locale != null) buffer.append ("("+locale+")"); todo:
+ if (reverse) buffer.appendChar('!');
+
+ return buffer.toString();
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /** Sorts by computed relevance. This is the same sort criteria as
+ * calling {@link Searcher#search(Query) Searcher#search()} without a sort criteria, only with
+ * slightly more overhead. */
+ Sort::Sort() {
+ fields=NULL;
+ SortField** fields=_CL_NEWARRAY(SortField*,3);
+ fields[0]=SortField::FIELD_SCORE;
+ fields[1]=SortField::FIELD_DOC;
+ fields[2]=NULL;
+ setSort (fields);
+ _CLDELETE_ARRAY(fields);
+ }
+
+ Sort::~Sort(){
+ clear();
+ }
+ void Sort::clear(){
+ if ( fields != NULL ){
+ int32_t i=0;
+ while ( fields[i] != NULL ){
+ if ( fields[i] != SortField::FIELD_SCORE &&
+ fields[i] != SortField::FIELD_DOC ){
+ _CLDELETE(fields[i]);
+ }
+ i++;
+ }
+ _CLDELETE_ARRAY(fields);
+ }
+ }
+
+ /** Sorts possibly in reverse by the terms in <code>field</code> then by
+ * index order (document number). The type of value in <code>field</code> is determined
+ * automatically.
+ * @see SortField#AUTO
+ */
+ Sort::Sort (const TCHAR* field, bool reverse) {
+ this->fields=NULL;
+ setSort (field, reverse);
+ }
+
+
+ /** Sorts in succession by the terms in each field.
+ * The type of value in <code>field</code> is determined
+ * automatically.
+ * @see SortField#AUTO
+ */
+ Sort::Sort (const TCHAR** fields) {
+ this->fields=NULL;
+ setSort (fields);
+ }
+
+
+ /** Sorts by the criteria in the given SortField. */
+ Sort::Sort (SortField* field) {
+ this->fields=NULL;
+ setSort (field);
+ }
+
+
+ /** Sorts in succession by the criteria in each SortField. */
+ Sort::Sort (SortField** fields) {
+ this->fields=NULL;
+ setSort (fields);
+ }
+
+
+ /** Sets the sort to the terms in <code>field</code> possibly in reverse,
+ * then by index order (document number). */
+ void Sort::setSort (const TCHAR* field, bool reverse) {
+ clear();
+ fields = _CL_NEWARRAY(SortField*,3);
+ fields[0] = _CLNEW SortField (field, SortField::AUTO, reverse);
+ fields[1] = SortField::FIELD_DOC;
+ fields[2] = NULL;
+ }
+
+
+ /** Sets the sort to the terms in each field in succession. */
+ void Sort::setSort (const TCHAR** fieldnames) {
+ clear();
+
+ int32_t n = 0;
+ while ( fieldnames[n] != NULL )
+ n++;
+
+ fields = _CL_NEWARRAY(SortField*,n+1);
+ for (int32_t i = 0; i < n; ++i) {
+ fields[i] = _CLNEW SortField (fieldnames[i], SortField::AUTO,false);
+ }
+ fields[n]=NULL;
+ }
+
+
+ /** Sets the sort to the given criteria. */
+ void Sort::setSort (SortField* field) {
+ clear();
+
+ this->fields = _CL_NEWARRAY(SortField*,2);
+ this->fields[0] = field;
+ this->fields[1] = NULL;
+ }
+
+
+ /** Sets the sort to the given criteria in succession. */
+ void Sort::setSort (SortField** fields) {
+ clear();
+
+ int n=0;
+ while ( fields[n] != NULL )
+ n++;
+ this->fields = _CL_NEWARRAY(SortField*,n+1);
+ for (int i=0;i<n+1;i++)
+ this->fields[i]=fields[i];
+ }
+
+ TCHAR* Sort::toString() const {
+ CL_NS(util)::StringBuffer buffer;
+
+ int32_t i = 0;
+ while ( fields[i] != NULL ){
+ if (i>0)
+ buffer.appendChar(',');
+
+ const TCHAR* p = fields[i]->toString();
+ buffer.append(p);
+ _CLDELETE_CARRAY(p);
+
+ i++;
+ }
+
+ return buffer.toString();
+ }
+
+
+
+
+
+ ScoreDocComparator* ScoreDocComparator::INDEXORDER = _CLNEW ScoreDocComparators::IndexOrder;
+ ScoreDocComparator* ScoreDocComparator::RELEVANCE = _CLNEW ScoreDocComparators::Relevance;
+
+ ScoreDocComparator::~ScoreDocComparator(){
+ }
+
+
+class ScoreDocComparatorImpl: public ScoreDocComparator{
+ Comparable** cachedValues;
+ FieldCacheAuto* fca;
+ int32_t cachedValuesLen;
+public:
+ ScoreDocComparatorImpl(FieldCacheAuto* fca){
+ this->fca = fca;
+ if ( fca->contentType != FieldCacheAuto::COMPARABLE_ARRAY )
+ _CLTHROWA(CL_ERR_InvalidCast,"Invalid field cache auto type");
+ this->cachedValues = fca->comparableArray;
+ this->cachedValuesLen = fca->contentLen;
+ }
+ ~ScoreDocComparatorImpl(){
+ }
+ int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j){
+ CND_PRECONDITION(i->doc >= 0 && i->doc < cachedValuesLen, "i->doc out of range")
+ CND_PRECONDITION(j->doc >= 0 && j->doc < cachedValuesLen, "j->doc out of range")
+ return cachedValues[i->doc]->compareTo (cachedValues[j->doc]);
+ }
+
+ CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i){
+ CND_PRECONDITION(i->doc >= 0 && i->doc < cachedValuesLen, "i->doc out of range")
+ return cachedValues[i->doc];
+ }
+
+ int32_t sortType(){
+ return SortField::CUSTOM;
+ }
+};
+
+ScoreDocComparator* SortComparator::newComparator (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname){
+ return _CLNEW ScoreDocComparatorImpl(FieldCache::DEFAULT->getCustom (reader, fieldname, this));
+}
+SortComparator::SortComparator(){
+}
+SortComparator::~SortComparator(){
+}
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/Sort.h b/3rdparty/clucene/src/CLucene/search/Sort.h
new file mode 100644
index 000000000..cfe96d56c
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/Sort.h
@@ -0,0 +1,356 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_Sort_
+#define _lucene_search_Sort_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/IndexReader.h"
+#include "SearchHeader.h"
+
+CL_NS_DEF(search)
+
+ class SortField; //predefine
+ class Sort;
+
+/**
+ * Expert: Compares two ScoreDoc objects for sorting.
+ *
+ */
+ class ScoreDocComparator:LUCENE_BASE {
+ protected:
+ ScoreDocComparator(){}
+ public:
+ virtual ~ScoreDocComparator();
+// CL_NS(util)::Comparable** cachedValues;
+// ScoreDocComparator(CL_NS(util)::Comparable** cachedValues);
+
+ /**
+ * Compares two ScoreDoc objects and returns a result indicating their
+ * sort order.
+ * @param i First ScoreDoc
+ * @param j Second ScoreDoc
+ * @return <code>-1</code> if <code>i</code> should come before <code>j</code><br><code>1</code> if <code>i</code> should come after <code>j</code><br><code>0</code> if they are equal
+ * @see java.util.Comparator
+ */
+ virtual int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j) = 0;
+
+ /**
+ * Returns the value used to sort the given document. The
+ * object returned must implement the java.io.Serializable
+ * interface. This is used by multisearchers to determine how to collate results from their searchers.
+ * @see FieldDoc
+ * @param i Document
+ * @return Serializable object
+ */
+ virtual CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i) = 0;
+
+
+ /**
+ * Returns the type of sort. Should return <code>SortField.SCORE</code>, <code>SortField.DOC</code>, <code>SortField.STRING</code>, <code>SortField.INTEGER</code>,
+ * <code>SortField::FLOAT</code> or <code>SortField.CUSTOM</code>. It is not valid to return <code>SortField.AUTO</code>.
+ * This is used by multisearchers to determine how to collate results from their searchers.
+ * @return One of the constants in SortField.
+ * @see SortField
+ */
+ virtual int32_t sortType() = 0;
+
+ /** Special comparator for sorting hits according to computed relevance (document score). */
+ static ScoreDocComparator* RELEVANCE;
+
+ /** Special comparator for sorting hits according to index order (document number). */
+ static ScoreDocComparator* INDEXORDER;
+ };
+
+/**
+ * Expert: returns a comparator for sorting ScoreDocs.
+ *
+ */
+class SortComparatorSource:LUCENE_BASE {
+public:
+ virtual ~SortComparatorSource(){
+ }
+
+ /**
+ * return a reference to a string describing the name of the comparator
+ * this is used in the explanation
+ */
+ virtual TCHAR* getName() = 0;
+
+ virtual size_t hashCode() = 0;
+
+ /**
+ * Creates a comparator for the field in the given index.
+ * @param reader Index to create comparator for.
+ * @param fieldname Field to create comparator for.
+ * @return Comparator of ScoreDoc objects.
+ * @throws IOException If an error occurs reading the index.
+ */
+ virtual ScoreDocComparator* newComparator (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname) = 0;
+};
+
+
+/**
+ * Abstract base class for sorting hits returned by a Query.
+ *
+ * <p>This class should only be used if the other SortField
+ * types (SCORE, DOC, STRING, INT, FLOAT) do not provide an
+ * adequate sorting. It maintains an internal cache of values which
+ * could be quite large. The cache is an array of Comparable,
+ * one for each document in the index. There is a distinct
+ * Comparable for each unique term in the field - if
+ * some documents have the same term in the field, the cache
+ * array will have entries which reference the same Comparable.
+ *
+ */
+class SortComparator: public SortComparatorSource {
+public:
+ virtual ScoreDocComparator* newComparator (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname);
+
+ SortComparator();
+ virtual ~SortComparator();
+
+ /**
+ * Returns an object which, when sorted according to natural order,
+ * will order the Term values in the correct order.
+ * <p>For example, if the Terms contained integer values, this method
+ * would return <code>new Integer(termtext)</code>. Note that this
+ * might not always be the most efficient implementation - for this
+ * particular example, a better implementation might be to make a
+ * ScoreDocLookupComparator that uses an internal lookup table of int.
+ * @param termtext The textual value of the term.
+ * @return An object representing <code>termtext</code> that sorts
+ * according to the natural order of <code>termtext</code>.
+ * @see Comparable
+ * @see ScoreDocComparator
+ */
+ virtual CL_NS(util)::Comparable* getComparable (const TCHAR* termtext) = 0;
+
+};
+
+
+/**
+ * Stores information about how to sort documents by terms in an individual
+ * field. Fields must be indexed in order to sort by them.
+ *
+ */
+class SortField:LUCENE_BASE {
+private:
+ const TCHAR* field;
+ int32_t type; // defaults to determining type dynamically
+ //Locale* locale; // defaults to "natural order" (no Locale)
+ bool reverse; // defaults to natural order
+ SortComparatorSource* factory;
+
+protected:
+ SortField (const SortField& clone);
+public:
+ virtual ~SortField();
+
+ /** Sort by document score (relevancy). Sort values are Float and higher
+ * values are at the front.
+ * PORTING: this is the same as SCORE in java, it had to be renamed because
+ * SCORE is a system macro on some platforms (AIX).
+ */
+ LUCENE_STATIC_CONSTANT(int32_t, DOCSCORE=0);
+
+ /** Sort by document number (index order). Sort values are Integer and lower
+ * values are at the front. */
+ LUCENE_STATIC_CONSTANT(int32_t, DOC=1);
+
+ /** Guess type of sort based on field contents. A regular expression is used
+ * to look at the first term indexed for the field and determine if it
+ * represents an integer number, a floating point number, or just arbitrary
+ * string characters. */
+ LUCENE_STATIC_CONSTANT(int32_t, AUTO=2);
+
+ /** Sort using term values as Strings. Sort values are String and lower
+ * values are at the front. */
+ LUCENE_STATIC_CONSTANT(int32_t, STRING=3);
+
+ /** Sort using term values as encoded Integers. Sort values are Integer and
+ * lower values are at the front. */
+ LUCENE_STATIC_CONSTANT(int32_t, INT=4);
+
+ /** Sort using term values as encoded Floats. Sort values are Float and
+ * lower values are at the front. */
+ LUCENE_STATIC_CONSTANT(int32_t, FLOAT=5);
+
+ /** Sort using a custom Comparator. Sort values are any Comparable and
+ * sorting is done according to natural order. */
+ LUCENE_STATIC_CONSTANT(int32_t, CUSTOM=9);
+
+ // IMPLEMENTATION NOTE: the FieldCache.STRING_INDEX is in the same "namespace"
+ // as the above static int values. Any new values must not have the same value
+ // as FieldCache.STRING_INDEX.
+
+ /** Represents sorting by document score (relevancy). */
+ static SortField* FIELD_SCORE;
+
+ /** Represents sorting by document number (index order). */
+ static SortField* FIELD_DOC;
+
+ SortField (const TCHAR* field);
+ //SortField (const TCHAR* field, bool reverse);
+ //todo: we cannot make reverse use default field of =false.
+ //because bool and int are the same type in c, overloading is not possible
+ SortField (const TCHAR* field, int32_t type, bool reverse);
+
+ /*
+ SortField (TCHAR* field, Locale* locale) {
+ SortField (TCHAR* field, Locale* locale, bool reverse);*/
+
+ SortField (const TCHAR* field, SortComparatorSource* comparator, bool reverse=false);
+
+ /** Returns the name of the field. Could return <code>null</code>
+ * if the sort is by SCORE or DOC.
+ * @return Name of field, possibly <code>null</code>.
+ */
+ const TCHAR* getField() const { return field; }
+
+ SortField* clone() const;
+
+ /** Returns the type of contents in the field.
+ * @return One of the constants SCORE, DOC, AUTO, STRING, INT or FLOAT.
+ */
+ int32_t getType() const { return type; }
+
+ /** Returns the Locale by which term values are interpreted.
+ * May return <code>null</code> if no Locale was specified.
+ * @return Locale, or <code>null</code>.
+ */
+ /*Locale getLocale() {
+ return locale;
+ }*/
+
+ /** Returns whether the sort should be reversed.
+ * @return True if natural order should be reversed.
+ */
+ bool getReverse() const { return reverse; }
+
+ SortComparatorSource* getFactory() const { return factory; }
+
+ TCHAR* toString() const;
+};
+
+
+
+/**
+ * Encapsulates sort criteria for returned hits.
+ *
+ * <p>The fields used to determine sort order must be carefully chosen.
+ * Documents must contain a single term in such a field,
+ * and the value of the term should indicate the document's relative position in
+ * a given sort order. The field must be indexed, but should not be tokenized,
+ * and does not need to be stored (unless you happen to want it back with the
+ * rest of your document data). In other words:
+ *
+ * <dl><dd><code>document.add (new Field ("byNumber", Integer.toString(x), false, true, false));</code>
+ * </dd></dl>
+ *
+ * <p><h3>Valid Types of Values</h3>
+ *
+ * <p>There are three possible kinds of term values which may be put into
+ * sorting fields: Integers, Floats, or Strings. Unless
+ * {@link SortField SortField} objects are specified, the type of value
+ * in the field is determined by parsing the first term in the field.
+ *
+ * <p>Integer term values should contain only digits and an optional
+ * preceeding negative sign. Values must be base 10 and in the range
+ * <code>Integer.MIN_VALUE</code> and <code>Integer.MAX_VALUE</code> inclusive.
+ * Documents which should appear first in the sort
+ * should have low value integers, later documents high values
+ * (i.e. the documents should be numbered <code>1..n</code> where
+ * <code>1</code> is the first and <code>n</code> the last).
+ *
+ * <p>Float term values should conform to values accepted by
+ * {@link Float Float.valueOf(String)} (except that <code>NaN</code>
+ * and <code>Infinity</code> are not supported).
+ * Documents which should appear first in the sort
+ * should have low values, later documents high values.
+ *
+ * <p>String term values can contain any valid String, but should
+ * not be tokenized. The values are sorted according to their
+ * {@link Comparable natural order}. Note that using this type
+ * of term value has higher memory requirements than the other
+ * two types.
+ *
+ * <p><h3>Object Reuse</h3>
+ *
+ * <p>One of these objects can be
+ * used multiple times and the sort order changed between usages.
+ *
+ * <p>This class is thread safe.
+ *
+ * <p><h3>Memory Usage</h3>
+ *
+ * <p>Sorting uses of caches of term values maintained by the
+ * internal HitQueue(s). The cache is static and contains an integer
+ * or float array of length <code>IndexReader.maxDoc()</code> for each field
+ * name for which a sort is performed. In other words, the size of the
+ * cache in bytes is:
+ *
+ * <p><code>4 * IndexReader.maxDoc() * (# of different fields actually used to sort)</code>
+ *
+ * <p>For String fields, the cache is larger: in addition to the
+ * above array, the value of every term in the field is kept in memory.
+ * If there are many unique terms in the field, this could
+ * be quite large.
+ *
+ * <p>Note that the size of the cache is not affected by how many
+ * fields are in the index and <i>might</i> be used to sort - only by
+ * the ones actually used to sort a result set.
+ *
+ * <p>The cache is cleared each time a new <code>IndexReader</code> is
+ * passed in, or if the value returned by <code>maxDoc()</code>
+ * changes for the current IndexReader. This class is not set up to
+ * be able to efficiently sort hits from more than one index
+ * simultaneously.
+ *
+ */
+class Sort:LUCENE_BASE {
+ // internal representation of the sort criteria
+ SortField** fields;
+ void clear();
+public:
+ ~Sort();
+
+ /** Represents sorting by computed relevance. Using this sort criteria
+ * returns the same results as calling {@link Searcher#search(Query) Searcher#search()}
+ * without a sort criteria, only with slightly more overhead. */
+ static Sort* RELEVANCE;
+
+ /** Represents sorting by index order. */
+ static Sort* INDEXORDER;
+
+ Sort();
+ Sort (const TCHAR* field, bool reverse=false);
+ Sort (const TCHAR** fields);
+ Sort (SortField* field);
+ Sort (SortField** fields);
+ void setSort (const TCHAR* field, bool reverse=false);
+ void setSort (const TCHAR** fieldnames);
+ void setSort (SortField* field);
+ void setSort (SortField** fields);
+
+ TCHAR* toString() const;
+
+ /**
+ * Representation of the sort criteria.
+ * @return a pointer to the of SortField array used in this sort criteria
+ */
+ SortField** getSort() const{ return fields; }
+};
+
+
+
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/TermQuery.cpp b/3rdparty/clucene/src/CLucene/search/TermQuery.cpp
new file mode 100644
index 000000000..a04c20fec
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/TermQuery.cpp
@@ -0,0 +1,213 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "TermQuery.h"
+
+#include "SearchHeader.h"
+#include "Scorer.h"
+#include "CLucene/index/Term.h"
+#include "TermScorer.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/StringBuffer.h"
+#include "CLucene/index/Terms.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+
+ /** Constructs a query for the term <code>t</code>. */
+ TermQuery::TermQuery(Term* t):
+ term( _CL_POINTER(t) )
+ {
+ }
+ TermQuery::TermQuery(const TermQuery& clone):
+ Query(clone){
+ this->term=_CL_POINTER(clone.term);
+ }
+ TermQuery::~TermQuery(){
+ _CLDECDELETE(term);
+ }
+
+ Query* TermQuery::clone() const{
+ return _CLNEW TermQuery(*this);
+ }
+
+ const TCHAR* TermQuery::getClassName(){
+ return _T("TermQuery");
+ }
+ const TCHAR* TermQuery::getQueryName() const{
+ return getClassName();
+ }
+ size_t TermQuery::hashCode() const {
+ return Similarity::floatToByte(getBoost()) ^ term->hashCode();
+ }
+
+
+ //added by search highlighter
+ Term* TermQuery::getTerm(bool pointer) const
+ {
+ if ( pointer )
+ return _CL_POINTER(term);
+ else
+ return term;
+ }
+
+
+ /** Prints a user-readable version of this query. */
+ TCHAR* TermQuery::toString(const TCHAR* field) const{
+ CL_NS(util)::StringBuffer buffer;
+ if ( field==NULL || _tcscmp(term->field(),field)!= 0 ) {
+ buffer.append(term->field());
+ buffer.append(_T(":"));
+ }
+ buffer.append(term->text());
+ if (getBoost() != 1.0f) {
+ buffer.append(_T("^"));
+ buffer.appendFloat( getBoost(),1 );
+ }
+ return buffer.toString();
+ }
+
+ /** Returns true iff <code>o</code> is equal to this. */
+ bool TermQuery::equals(Query* other) const {
+ if (!(other->instanceOf(TermQuery::getClassName())))
+ return false;
+
+ TermQuery* tq = (TermQuery*)other;
+ return (this->getBoost() == tq->getBoost())
+ && this->term->equals(tq->term);
+ }
+
+
+ TermQuery::TermWeight::TermWeight(Searcher* searcher, TermQuery* _this, Term* _term) {
+ this->_this = _this;
+ this->_term = _term;
+ this->searcher = searcher;
+ value=0;
+ idf=0;
+ queryNorm=0;
+ queryWeight=0;
+ }
+ TermQuery::TermWeight::~TermWeight(){
+ }
+
+ //return a *new* string describing this object
+ TCHAR* TermQuery::TermWeight::toString() {
+ int32_t size=_tcslen(_this->getQueryName()) + 10;
+ TCHAR* tmp = _CL_NEWARRAY(TCHAR, size);//_tcslen(weight())
+ _sntprintf(tmp,size,_T("weight(%s)"),_this->getQueryName());
+ return tmp;
+ }
+
+ qreal TermQuery::TermWeight::sumOfSquaredWeights() {
+ idf = _this->getSimilarity(searcher)->idf(_term, searcher); // compute idf
+ queryWeight = idf * _this->getBoost(); // compute query weight
+ return queryWeight * queryWeight; // square it
+ }
+
+ void TermQuery::TermWeight::normalize(qreal queryNorm) {
+ this->queryNorm = queryNorm;
+ queryWeight *= queryNorm; // normalize query weight
+ value = queryWeight * idf; // idf for document
+ }
+
+ Scorer* TermQuery::TermWeight::scorer(IndexReader* reader) {
+ TermDocs* termDocs = reader->termDocs(_term);
+
+ if (termDocs == NULL)
+ return NULL;
+
+ return _CLNEW TermScorer(this, termDocs, _this->getSimilarity(searcher),
+ reader->norms(_term->field()));
+ }
+
+ void TermQuery::TermWeight::explain(IndexReader* reader, int32_t doc, Explanation* result){
+ TCHAR buf[LUCENE_SEARCH_EXPLANATION_DESC_LEN];
+ TCHAR* tmp;
+
+ tmp = getQuery()->toString();
+ _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("weight(%s in %d), product of:"),tmp,doc);
+ _CLDELETE_CARRAY(tmp);
+ result->setDescription(buf);
+
+ _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("idf(docFreq=%d)"), searcher->docFreq(_term) );
+ Explanation* idfExpl = _CLNEW Explanation(idf, buf);
+
+ // explain query weight
+ Explanation* queryExpl = _CLNEW Explanation();
+ tmp = getQuery()->toString();
+ _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("queryWeight(%s), product of:"), tmp);
+ _CLDELETE_CARRAY(tmp);
+ queryExpl->setDescription(buf);
+
+ Explanation* boostExpl = _CLNEW Explanation(_this->getBoost(), _T("boost"));
+ if (_this->getBoost() != 1.0f)
+ queryExpl->addDetail(boostExpl);
+ else
+ _CLDELETE(boostExpl);
+
+ queryExpl->addDetail(idfExpl->clone());
+
+ Explanation* queryNormExpl = _CLNEW Explanation(queryNorm,_T("queryNorm"));
+ queryExpl->addDetail(queryNormExpl);
+
+ queryExpl->setValue(_this->getBoost()* // always 1.0
+ idfExpl->getValue() *
+ queryNormExpl->getValue());
+
+ // explain field weight
+ const TCHAR* field = _term->field();
+ Explanation* fieldExpl = _CLNEW Explanation();
+
+ tmp = _term->toString();
+ _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("fieldWeight(%s in %d), product of:"),tmp,doc);
+ _CLDELETE_CARRAY(tmp);
+ fieldExpl->setDescription(buf);
+
+ Scorer* sc = scorer(reader);
+ Explanation* tfExpl = _CLNEW Explanation;
+ sc->explain(doc, tfExpl);
+ _CLDELETE(sc);
+ fieldExpl->addDetail(tfExpl);
+ fieldExpl->addDetail(idfExpl);
+
+ Explanation* fieldNormExpl = _CLNEW Explanation();
+ uint8_t* fieldNorms = reader->norms(field);
+ qreal fieldNorm =
+ fieldNorms!=NULL ? Similarity::decodeNorm(fieldNorms[doc]) : 0.0f;
+ fieldNormExpl->setValue(fieldNorm);
+
+ _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,
+ _T("fieldNorm(field=%s, doc=%d)"),field,doc);
+ fieldNormExpl->setDescription(buf);
+ fieldExpl->addDetail(fieldNormExpl);
+
+ fieldExpl->setValue(tfExpl->getValue() *
+ idfExpl->getValue() *
+ fieldNormExpl->getValue());
+
+ /*if (queryExpl->getValue() == 1.0f){
+ _CLDELETE(result);
+ return fieldExpl;
+ }else{*/
+ result->addDetail(queryExpl);
+ result->addDetail(fieldExpl);
+
+ // combine them
+ result->setValue(queryExpl->getValue() * fieldExpl->getValue());
+ //}
+ }
+
+ Weight* TermQuery::_createWeight(Searcher* searcher) {
+ return _CLNEW TermWeight(searcher,this,term);
+ }
+CL_NS_END
+
diff --git a/3rdparty/clucene/src/CLucene/search/TermQuery.h b/3rdparty/clucene/src/CLucene/search/TermQuery.h
new file mode 100644
index 000000000..a7dd8039b
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/TermQuery.h
@@ -0,0 +1,81 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_TermQuery_
+#define _lucene_search_TermQuery_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "SearchHeader.h"
+#include "Scorer.h"
+#include "CLucene/index/Term.h"
+#include "TermScorer.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/StringBuffer.h"
+#include "CLucene/index/Terms.h"
+
+CL_NS_DEF(search)
+
+
+ /** A Query that matches documents containing a term.
+ This may be combined with other terms with a {@link BooleanQuery}.
+ */
+ class TermQuery: public Query {
+ private:
+ CL_NS(index)::Term* term;
+
+
+ class TermWeight: public Weight {
+ private:
+ Searcher* searcher;
+ qreal value;
+ qreal idf;
+ qreal queryNorm;
+ qreal queryWeight;
+ TermQuery* _this;
+ CL_NS(index)::Term* _term;
+
+ public:
+ TermWeight(Searcher* searcher, TermQuery* _this, CL_NS(index)::Term* _term);
+ ~TermWeight();
+ TCHAR* toString();
+ Query* getQuery() { return (Query*)_this; }
+ qreal getValue() { return value; }
+
+ qreal sumOfSquaredWeights();
+ void normalize(qreal queryNorm);
+ Scorer* scorer(CL_NS(index)::IndexReader* reader);
+ void explain(CL_NS(index)::IndexReader* reader, int32_t doc, Explanation* ret);
+ };
+
+ protected:
+ Weight* _createWeight(Searcher* searcher);
+ TermQuery(const TermQuery& clone);
+ public:
+ // Constructs a query for the term <code>t</code>.
+ TermQuery(CL_NS(index)::Term* t);
+ ~TermQuery();
+
+ static const TCHAR* getClassName();
+ const TCHAR* getQueryName() const;
+
+ //added by search highlighter
+ CL_NS(index)::Term* getTerm(bool pointer=true) const;
+
+ // Prints a user-readable version of this query.
+ TCHAR* toString(const TCHAR* field) const;
+
+ bool equals(Query* other) const;
+ Query* clone() const;
+
+ /** Returns a hash code value for this object.*/
+ size_t hashCode() const;
+ };
+CL_NS_END
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/search/TermScorer.cpp b/3rdparty/clucene/src/CLucene/search/TermScorer.cpp
new file mode 100644
index 000000000..ddd7f74ed
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/TermScorer.cpp
@@ -0,0 +1,120 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "TermScorer.h"
+
+#include "CLucene/index/Terms.h"
+#include "TermQuery.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+ //TermScorer takes TermDocs and delets it when TermScorer is cleaned up
+ TermScorer::TermScorer(Weight* w, CL_NS(index)::TermDocs* td,
+ Similarity* similarity,uint8_t* _norms):
+ Scorer(similarity),
+ termDocs(td),
+ norms(_norms),
+ weight(w),
+ weightValue(w->getValue()),
+ _doc(0),
+ pointer(0),
+ pointerMax(0)
+ {
+ memset(docs,0,32*sizeof(int32_t));
+ memset(freqs,0,32*sizeof(int32_t));
+
+ for (int32_t i = 0; i < LUCENE_SCORE_CACHE_SIZE; i++)
+ scoreCache[i] = getSimilarity()->tf(i) * weightValue;
+ }
+
+ TermScorer::~TermScorer(){
+ _CLDELETE(termDocs);
+ }
+ bool TermScorer::next(){
+ pointer++;
+ if (pointer >= pointerMax) {
+ pointerMax = termDocs->read(docs, freqs, 32); // refill buffer
+ if (pointerMax != 0) {
+ pointer = 0;
+ } else {
+ termDocs->close(); // close stream
+ _doc = LUCENE_INT32_MAX_SHOULDBE; // set to sentinel value
+ return false;
+ }
+ }
+ _doc = docs[pointer];
+ return true;
+ }
+
+ bool TermScorer::skipTo(int32_t target) {
+ // first scan in cache
+ for (pointer++; pointer < pointerMax; pointer++) {
+ if (docs[pointer] >= target) {
+ _doc = docs[pointer];
+ return true;
+ }
+ }
+
+ // not found in cache, seek underlying stream
+ bool result = termDocs->skipTo(target);
+ if (result) {
+ pointerMax = 1;
+ pointer = 0;
+ docs[pointer] = _doc = termDocs->doc();
+ freqs[pointer] = termDocs->freq();
+ } else {
+ _doc = LUCENE_INT32_MAX_SHOULDBE;
+ }
+ return result;
+ }
+
+ void TermScorer::explain(int32_t doc, Explanation* tfExplanation) {
+ TermQuery* query = (TermQuery*)weight->getQuery();
+ int32_t tf = 0;
+ while (pointer < pointerMax) {
+ if (docs[pointer] == doc)
+ tf = freqs[pointer];
+ pointer++;
+ }
+ if (tf == 0) {
+ while (termDocs->next()) {
+ if (termDocs->doc() == doc) {
+ tf = termDocs->freq();
+ }
+ }
+ }
+ termDocs->close();
+ tfExplanation->setValue(getSimilarity()->tf(tf));
+
+ TCHAR buf[LUCENE_SEARCH_EXPLANATION_DESC_LEN+1];
+ TCHAR* termToString = query->getTerm(false)->toString();
+ _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,_T("tf(termFreq(%s)=%d)"), termToString, tf);
+ _CLDELETE_CARRAY(termToString);
+ tfExplanation->setDescription(buf);
+ }
+
+ TCHAR* TermScorer::toString() {
+ TCHAR* wb = weight->toString();
+ int32_t rl = _tcslen(wb) + 9; //9=_tcslen("scorer(" ")") + 1
+ TCHAR* ret = _CL_NEWARRAY(TCHAR,rl);
+ _sntprintf(ret,rl,_T("scorer(%s)"), wb);
+ _CLDELETE_ARRAY(wb);
+ return ret;
+ }
+
+ qreal TermScorer::score(){
+ int32_t f = freqs[pointer];
+ qreal raw = // compute tf(f)*weight
+ f < LUCENE_SCORE_CACHE_SIZE // check cache
+ ? scoreCache[f] // cache hit
+ : getSimilarity()->tf(f) * weightValue; // cache miss
+
+ return raw * Similarity::decodeNorm(norms[_doc]); // normalize for field
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/TermScorer.h b/3rdparty/clucene/src/CLucene/search/TermScorer.h
new file mode 100644
index 000000000..ccbf5f7ec
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/TermScorer.h
@@ -0,0 +1,53 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_TermScorer_
+#define _lucene_search_TermScorer_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "Scorer.h"
+#include "CLucene/index/Terms.h"
+#include "CLucene/search/Similarity.h"
+#include "SearchHeader.h"
+
+CL_NS_DEF(search)
+
+ class TermScorer: public Scorer {
+ private:
+ CL_NS(index)::TermDocs* termDocs;
+ uint8_t* norms;
+ Weight* weight;
+ const qreal weightValue;
+ int32_t _doc;
+
+ int32_t docs[32]; // buffered doc numbers
+ int32_t freqs[32]; // buffered term freqs
+ int32_t pointer;
+ int32_t pointerMax;
+
+ qreal scoreCache[LUCENE_SCORE_CACHE_SIZE];
+ public:
+
+ //TermScorer takes TermDocs and delets it when TermScorer is cleaned up
+ TermScorer(Weight* weight, CL_NS(index)::TermDocs* td,
+ Similarity* similarity, uint8_t* _norms);
+
+ ~TermScorer();
+
+ int32_t doc() const { return _doc; }
+
+ bool next();
+ bool skipTo(int32_t target);
+ void explain(int32_t doc, Explanation* ret);
+ TCHAR* toString();
+
+ qreal score();
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/WildcardQuery.cpp b/3rdparty/clucene/src/CLucene/search/WildcardQuery.cpp
new file mode 100644
index 000000000..9373cef0a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/WildcardQuery.cpp
@@ -0,0 +1,147 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "WildcardQuery.h"
+#include "CLucene/util/BitSet.h"
+
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_DEF(search)
+
+
+ WildcardQuery::WildcardQuery(Term* term):
+ MultiTermQuery( term ){
+ //Func - Constructor
+ //Pre - term != NULL
+ //Post - Instance has been created
+
+ }
+
+ WildcardQuery::~WildcardQuery(){
+ //Func - Destructor
+ //Pre - true
+ //Post - true
+
+ }
+
+ const TCHAR* WildcardQuery::getQueryName() const{
+ //Func - Returns the string "WildcardQuery"
+ //Pre - true
+ //Post - The string "WildcardQuery" has been returned
+ return getClassName();
+ }
+
+ const TCHAR* WildcardQuery::getClassName(){
+ return _T("WildcardQuery");
+ }
+
+
+ FilteredTermEnum* WildcardQuery::getEnum(IndexReader* reader) {
+ return _CLNEW WildcardTermEnum(reader, getTerm(false));
+ }
+
+ WildcardQuery::WildcardQuery(const WildcardQuery& clone):
+ MultiTermQuery(clone)
+ {
+ }
+
+ Query* WildcardQuery::clone() const{
+ return _CLNEW WildcardQuery(*this);
+ }
+ size_t WildcardQuery::hashCode() const{
+ //todo: we should give the query a seeding value... but
+ //need to do it for all hascode functions
+ return Similarity::floatToByte(getBoost()) ^ getTerm()->hashCode();
+ }
+ bool WildcardQuery::equals(Query* other) const{
+ if (!(other->instanceOf(WildcardQuery::getClassName())))
+ return false;
+
+ WildcardQuery* tq = (WildcardQuery*)other;
+ return (this->getBoost() == tq->getBoost())
+ && getTerm()->equals(tq->getTerm());
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+WildcardFilter::WildcardFilter( Term* term )
+{
+ this->term = _CL_POINTER(term);
+}
+
+WildcardFilter::~WildcardFilter()
+{
+ _CLDECDELETE(term);
+}
+
+WildcardFilter::WildcardFilter( const WildcardFilter& copy ) :
+ term( _CL_POINTER(copy.term) )
+{
+}
+
+Filter* WildcardFilter::clone() const {
+ return _CLNEW WildcardFilter(*this );
+}
+
+
+TCHAR* WildcardFilter::toString()
+{
+ //Instantiate a stringbuffer buffer to store the readable version temporarily
+ CL_NS(util)::StringBuffer buffer;
+ //check if field equal to the field of prefix
+ if( term->field() != NULL ) {
+ //Append the field of prefix to the buffer
+ buffer.append(term->field());
+ //Append a colon
+ buffer.append(_T(":") );
+ }
+ //Append the text of the prefix
+ buffer.append(term->text());
+
+ //Convert StringBuffer buffer to TCHAR block and return it
+ return buffer.toString();
+}
+
+
+/** Returns a BitSet with true for documents which should be permitted in
+search results, and false for those that should not. */
+BitSet* WildcardFilter::bits( IndexReader* reader )
+{
+ BitSet* bts = _CLNEW BitSet( reader->maxDoc() );
+
+ WildcardTermEnum termEnum (reader, term);
+ if (termEnum.term(false) == NULL)
+ return bts;
+
+ TermDocs* termDocs = reader->termDocs();
+ try{
+ do{
+ termDocs->seek(&termEnum);
+
+ while (termDocs->next()) {
+ bts->set(termDocs->doc());
+ }
+ }while(termEnum.next());
+ } _CLFINALLY(
+ termDocs->close();
+ _CLDELETE(termDocs);
+ termEnum.close();
+ )
+
+ return bts;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/WildcardQuery.h b/3rdparty/clucene/src/CLucene/search/WildcardQuery.h
new file mode 100644
index 000000000..cfc38f648
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/WildcardQuery.h
@@ -0,0 +1,69 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_WildcardQuery_
+#define _lucene_search_WildcardQuery_
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/index/Term.h"
+#include "MultiTermQuery.h"
+#include "WildcardTermEnum.h"
+
+CL_NS_DEF(search)
+
+ /** Implements the wildcard search query. Supported wildcards are <code>*</code>, which
+ * matches any character sequence (including the empty one), and <code>?</code>,
+ * which matches any single character. Note this query can be slow, as it
+ * needs to iterate over all terms. In order to prevent extremely slow WildcardQueries,
+ * a Wildcard term must not start with one of the wildcards <code>*</code> or
+ * <code>?</code>.
+ *
+ * @see WildcardTermEnum
+ */
+ class WildcardQuery: public MultiTermQuery {
+ protected:
+ FilteredTermEnum* getEnum(CL_NS(index)::IndexReader* reader);
+ WildcardQuery(const WildcardQuery& clone);
+ public:
+ WildcardQuery(CL_NS(index)::Term* term);
+ ~WildcardQuery();
+
+ //Returns the string "WildcardQuery"
+ const TCHAR* getQueryName() const;
+ static const TCHAR* getClassName();
+
+ size_t hashCode() const;
+ bool equals(Query* other) const;
+ Query* clone() const;
+ };
+
+
+
+class WildcardFilter: public Filter
+{
+private:
+ CL_NS(index)::Term* term;
+protected:
+ WildcardFilter( const WildcardFilter& copy );
+
+public:
+ WildcardFilter(CL_NS(index)::Term* term);
+ ~WildcardFilter();
+
+ /** Returns a BitSet with true for documents which should be permitted in
+ search results, and false for those that should not. */
+ CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader );
+
+ Filter* clone() const;
+ TCHAR* toString();
+};
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/search/WildcardTermEnum.cpp b/3rdparty/clucene/src/CLucene/search/WildcardTermEnum.cpp
new file mode 100644
index 000000000..bed9e6e0c
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/WildcardTermEnum.cpp
@@ -0,0 +1,150 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "WildcardTermEnum.h"
+
+CL_NS_USE(index)
+CL_NS_DEF(search)
+
+ bool WildcardTermEnum::termCompare(Term* term) {
+ if ( term!=NULL && __term->field() == term->field() ) {
+ const TCHAR* searchText = term->text();
+ const TCHAR* patternText = __term->text();
+ if ( _tcsncmp( searchText, pre, preLen ) == 0 ){
+ return wildcardEquals(patternText+preLen, __term->textLength()-preLen, 0, searchText, term->textLength(), preLen);
+ }
+ }
+ _endEnum = true;
+ return false;
+ }
+
+ /** Creates new WildcardTermEnum */
+ WildcardTermEnum::WildcardTermEnum(IndexReader* reader, Term* term):
+ FilteredTermEnum(),
+ __term(_CL_POINTER(term)),
+ fieldMatch(false),
+ _endEnum(false)
+ {
+
+ pre = stringDuplicate(term->text());
+
+ const TCHAR* sidx = _tcschr( pre, LUCENE_WILDCARDTERMENUM_WILDCARD_STRING );
+ const TCHAR* cidx = _tcschr( pre, LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR );
+ const TCHAR* tidx = sidx;
+ if (tidx == NULL)
+ tidx = cidx;
+ else if ( cidx && cidx > pre)
+ tidx = min(sidx, cidx);
+ CND_PRECONDITION(tidx != NULL, "tidx==NULL");
+ int32_t idx = (int32_t)(tidx - pre);
+ preLen = idx;
+ CND_PRECONDITION(preLen<term->textLength(), "preLen >= term->textLength()");
+ pre[preLen]=0; //trim end
+
+ Term* t = _CLNEW Term(__term, pre);
+ setEnum( reader->terms(t) );
+ _CLDECDELETE(t);
+ }
+
+ void WildcardTermEnum::close()
+ {
+ if ( __term != NULL ){
+ FilteredTermEnum::close();
+
+ _CLDECDELETE(__term);
+ __term = NULL;
+
+ _CLDELETE_CARRAY( pre );
+ }
+ }
+ WildcardTermEnum::~WildcardTermEnum() {
+ close();
+ }
+
+ qreal WildcardTermEnum::difference() {
+ return 1.0f;
+ }
+
+ bool WildcardTermEnum::endEnum() {
+ return _endEnum;
+ }
+
+ bool WildcardTermEnum::wildcardEquals(const TCHAR* pattern, int32_t patternLen, int32_t patternIdx, const TCHAR* str, int32_t strLen, int32_t stringIdx)
+ {
+ for (int32_t p = patternIdx; ; ++p)
+ {
+ for (int32_t s = stringIdx; ; ++p, ++s)
+ {
+ // End of str yet?
+ bool sEnd = (s >= strLen);
+ // End of pattern yet?
+ bool pEnd = (p >= patternLen);
+
+ // If we're looking at the end of the str...
+ if (sEnd)
+ {
+ // Assume the only thing left on the pattern is/are wildcards
+ bool justWildcardsLeft = true;
+
+ // Current wildcard position
+ int32_t wildcardSearchPos = p;
+ // While we haven't found the end of the pattern,
+ // and haven't encountered any non-wildcard characters
+ while (wildcardSearchPos < patternLen && justWildcardsLeft)
+ {
+ // Check the character at the current position
+ TCHAR wildchar = pattern[wildcardSearchPos];
+ // If it's not a wildcard character, then there is more
+ // pattern information after this/these wildcards.
+
+ if (wildchar != LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR &&
+ wildchar != LUCENE_WILDCARDTERMENUM_WILDCARD_STRING){
+ justWildcardsLeft = false;
+ }else{
+ // to prevent "cat" matches "ca??"
+ if (wildchar == LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR)
+ return false;
+
+ wildcardSearchPos++; // Look at the next character
+ }
+ }
+
+ // This was a prefix wildcard search, and we've matched, so
+ // return true.
+ if (justWildcardsLeft)
+ return true;
+ }
+
+ // If we've gone past the end of the str, or the pattern,
+ // return false.
+ if (sEnd || pEnd)
+ break;
+
+ // Match a single character, so continue.
+ if (pattern[p] == LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR)
+ continue;
+
+ if (pattern[p] == LUCENE_WILDCARDTERMENUM_WILDCARD_STRING)
+ {
+ // Look at the character beyond the '*'.
+ ++p;
+ // Examine the str, starting at the last character.
+ for (int32_t i = strLen; i >= s; --i)
+ {
+ if (wildcardEquals(pattern, patternLen, p, str, strLen, i))
+ return true;
+ }
+ break;
+ }
+ if (pattern[p] != str[s])
+ break;
+ }
+ return false;
+ }
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/search/WildcardTermEnum.h b/3rdparty/clucene/src/CLucene/search/WildcardTermEnum.h
new file mode 100644
index 000000000..2a0373540
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/WildcardTermEnum.h
@@ -0,0 +1,67 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_search_WildcardTermEnum_
+#define _lucene_search_WildcardTermEnum_
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/index/Term.h"
+#include "CLucene/index/Terms.h"
+#include "FilteredTermEnum.h"
+
+CL_NS_DEF(search)
+ /**
+ * Subclass of FilteredTermEnum for enumerating all terms that match the
+ * specified wildcard filter term->
+ * <p>
+ * Term enumerations are always ordered by term->compareTo(). Each term in
+ * the enumeration is greater than all that precede it.
+ */
+ class WildcardTermEnum: public FilteredTermEnum {
+ private:
+ CL_NS(index)::Term* __term;
+ TCHAR* pre;
+ int32_t preLen;
+ bool fieldMatch;
+ bool _endEnum;
+
+ /********************************************
+ * const TCHAR* equality with support for wildcards
+ ********************************************/
+
+ protected:
+ bool termCompare(CL_NS(index)::Term* term) ;
+
+ public:
+
+ /**
+ * Creates a new <code>WildcardTermEnum</code>. Passing in a
+ * {@link Term Term} that does not contain a
+ * <code>LUCENE_WILDCARDTERMENUM_WILDCARD_STRING</code> or
+ * <code>LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR</code> will cause an exception to be thrown.
+ */
+ WildcardTermEnum(CL_NS(index)::IndexReader* reader, CL_NS(index)::Term* term);
+ ~WildcardTermEnum();
+
+ qreal difference() ;
+
+ bool endEnum() ;
+
+ /**
+ * Determines if a word matches a wildcard pattern.
+ */
+ static bool wildcardEquals(const TCHAR* pattern, int32_t patternLen, int32_t patternIdx, const TCHAR* str, int32_t strLen, int32_t stringIdx);
+
+ void close();
+
+ const char* getObjectName(){ return WildcardTermEnum::getClassName(); }
+ static const char* getClassName(){ return "WildcardTermEnum"; }
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/Directory.h b/3rdparty/clucene/src/CLucene/store/Directory.h
new file mode 100644
index 000000000..818bc7af9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/Directory.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#ifndef _lucene_store_Directory
+#define _lucene_store_Directory
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QStringList>
+
+#include "CLucene/store/Lock.h"
+#include "CLucene/util/VoidList.h"
+#include "CLucene/util/Misc.h"
+
+#include "IndexInput.h"
+#include "IndexOutput.h"
+
+CL_NS_DEF(store)
+
+/** A Directory is a flat list of files. Files may be written once, when they
+* are created. Once a file is created it may only be opened for read, or
+* deleted. Random access is permitted both when reading and writing.
+*
+* <p> Direct i/o is not used directly, but rather all i/o is
+* through this API. This permits things such as: <ul>
+* <li> implementation of RAM-based indices;
+* <li> implementation indices stored in a database, via a database;
+* <li> implementation of an index as a single file;
+* </ul>
+*
+*/
+class Directory : LUCENE_REFBASE
+{
+protected:
+ Directory() {}
+ // Removes an existing file in the directory.
+ virtual bool doDeleteFile(const QString& name) = 0;
+
+public:
+ DEFINE_MUTEX(THIS_LOCK)
+
+ virtual ~Directory() {};
+
+ // Returns an array of strings, one for each file in the directory.
+ virtual QStringList list() const = 0;
+
+ // Returns true iff a file with the given name exists.
+ virtual bool fileExists(const QString& name) const = 0;
+
+ // Returns the time the named file was last modified.
+ virtual int64_t fileModified(const QString& name) const = 0;
+
+ // Returns the length of a file in the directory.
+ virtual int64_t fileLength(const QString& name) const = 0;
+
+ // Returns a stream reading an existing file.
+ virtual IndexInput* openInput(const QString& name) = 0;
+ virtual IndexInput* openInput(const QString& name, int32_t bufferSize)
+ {
+ // didnt overload bufferSize
+ return openInput(name);
+ }
+
+ // Set the modified time of an existing file to now.
+ virtual void touchFile(const QString& name) = 0;
+
+ // Removes an existing file in the directory.
+ virtual bool deleteFile(const QString& name, const bool throwError = true) {
+ bool ret = doDeleteFile(name);
+ if (!ret && throwError) {
+ char buffer[200];
+ _snprintf(buffer, 200, "couldn't delete file %s",
+ name.toLocal8Bit().constData());
+ _CLTHROWA(CL_ERR_IO, buffer);
+ }
+ return ret;
+ }
+
+ // Renames an existing file in the directory.
+ // If a file already exists with the new name, then it is replaced.
+ virtual void renameFile(const QString& from, const QString& to) = 0;
+
+ // Creates a new, empty file in the directory with the given name.
+ // Returns a stream writing this file.
+ virtual IndexOutput* createOutput(const QString& name) = 0;
+
+ // Construct a {@link Lock}.
+ // @param name the name of the lock file
+ virtual LuceneLock* makeLock(const QString& name) = 0;
+
+ // Closes the store.
+ virtual void close() = 0;
+
+ virtual QString toString() const = 0;
+
+ virtual QString getDirectoryType() const = 0;
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/FSDirectory.cpp b/3rdparty/clucene/src/CLucene/store/FSDirectory.cpp
new file mode 100644
index 000000000..5f96e91cd
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/FSDirectory.cpp
@@ -0,0 +1,662 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#include <QtCore/QDir>
+#include <QtCore/QDateTime>
+#include <QtCore/QFileInfo>
+#include <QtCore/QByteArray>
+#include <QtCore/QCryptographicHash>
+
+#include "CLucene/StdHeader.h"
+#include "FSDirectory.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/Misc.h"
+#include "CLucene/debug/condition.h"
+
+CL_NS_DEF(store)
+CL_NS_USE(util)
+
+bool FSDirectory::disableLocks = false;
+
+// This cache of directories ensures that there is a unique Directory instance
+// per path, so that synchronization on the Directory can be used to synchronize
+// access between readers and writers.
+static CL_NS(util)::CLHashMap<QString, FSDirectory*,
+ CL_NS(util)::Compare::Qstring, CL_NS(util)::Equals::Qstring,
+ CL_NS(util)::Deletor::DummyQString> DIRECTORIES(false, false);
+
+// # pragma mark -- FSDirectory::FSLock
+
+FSDirectory::FSLock::FSLock(const QString& _lockDir, const QString& name)
+ : lockDir(_lockDir)
+ , lockFile(_lockDir + QDir::separator() + name)
+{
+}
+
+FSDirectory::FSLock::~FSLock()
+{
+}
+
+bool FSDirectory::FSLock::obtain()
+{
+ if (disableLocks)
+ return true;
+
+ if (QFile::exists(lockFile))
+ return false;
+
+ QDir dir(lockDir);
+ if (!dir.exists()) {
+ if (!dir.mkpath(lockDir)) {
+ // 34: len of "Couldn't create lock directory: "
+ char* err = _CL_NEWARRAY(
+ char, 34 + strlen(lockDir.toLocal8Bit().constData()) + 1);
+ strcpy(err, "Couldn't create lock directory: ");
+ strcat(err, lockDir.toLocal8Bit().constData());
+ _CLTHROWA_DEL(CL_ERR_IO, err);
+ }
+ }
+
+ QFile file(lockFile);
+ return file.open(QIODevice::ReadWrite);
+}
+
+void FSDirectory::FSLock::release()
+{
+ if (disableLocks)
+ return;
+
+ QFile file(lockFile);
+ file.remove();
+}
+
+bool FSDirectory::FSLock::isLocked()
+{
+ if (disableLocks)
+ return false;
+ return QFile::exists(lockFile);
+}
+
+QString FSDirectory::FSLock::toString() const
+{
+ QString ret(QLatin1String("Lock@"));
+ return ret.append(lockFile);
+}
+
+// # pragma mark -- FSDirectory::FSIndexInput
+
+FSDirectory::FSIndexInput::FSIndexInput(const QString& path, int32_t bufferSize)
+ : BufferedIndexInput(bufferSize)
+{
+ CND_PRECONDITION(!path.isEmpty(), "path is NULL");
+
+ handle = _CLNEW SharedHandle();
+ handle->fhandle.setFileName(path);
+ handle->fhandle.open(QIODevice::ReadOnly);
+
+ if (handle->fhandle.error() != QFile::NoError) {
+ switch(handle->fhandle.error()) {
+ case 1:
+ _CLTHROWA(CL_ERR_IO, "An error occurred when reading from the file");
+ break;
+ case 2:
+ _CLTHROWA(CL_ERR_IO, "An error occurred when writing to the file.");
+ break;
+ case 5:
+ _CLTHROWA(CL_ERR_IO, "The file could not be opened.");
+ break;
+ case 6:
+ _CLTHROWA(CL_ERR_IO, "The operation was aborted.");
+ break;
+ case 7:
+ _CLTHROWA(CL_ERR_IO, "A timeout occurred.");
+ break;
+ case 8:
+ _CLTHROWA(CL_ERR_IO, "An unspecified error occurred.");
+ break;
+ case 9:
+ _CLTHROWA(CL_ERR_IO, "The file could not be removed.");
+ break;
+ case 10:
+ _CLTHROWA(CL_ERR_IO, "The file could not be renamed.");
+ break;
+ case 11:
+ _CLTHROWA(CL_ERR_IO, "The position in the file could not be changed.");
+ break;
+ case 12:
+ _CLTHROWA(CL_ERR_IO, "The file could not be resized.e");
+ break;
+ case 13:
+ _CLTHROWA(CL_ERR_IO, "The file could not be accessed.");
+ break;
+ case 14:
+ _CLTHROWA(CL_ERR_IO, "The file could not be copied.");
+ break;
+ case 4:
+ default:
+ _CLTHROWA(CL_ERR_IO, "A fatal error occurred.");
+ }
+ }
+
+ //Store the file length
+ handle->_length = handle->fhandle.size();
+ handle->_fpos = 0;
+ this->_pos = 0;
+}
+
+FSDirectory::FSIndexInput::FSIndexInput(const FSIndexInput& other)
+ : BufferedIndexInput(other)
+{
+ if (other.handle == NULL)
+ _CLTHROWA(CL_ERR_NullPointer, "other handle is null");
+
+ SCOPED_LOCK_MUTEX(*other.handle->THIS_LOCK)
+
+ _pos = other.handle->_fpos;
+ handle = _CL_POINTER(other.handle);
+}
+
+FSDirectory::FSIndexInput::~FSIndexInput()
+{
+ FSIndexInput::close();
+}
+
+void FSDirectory::FSIndexInput::close()
+{
+ BufferedIndexInput::close();
+#ifdef _LUCENE_THREADMUTEX
+ if (handle != NULL) {
+ // Here we have a bit of a problem... We need to lock the handle to
+ // ensure that we can safely delete the handle... But if we delete the
+ // handle, then the scoped unlock, won't be able to unlock the mutex...
+
+ // take a reference of the lock object...
+ _LUCENE_THREADMUTEX* mutex = handle->THIS_LOCK;
+ //lock the mutex
+ mutex->lock();
+
+ // determine if we are about to delete the handle...
+ bool doUnlock = (handle->__cl_refcount > 1);
+ // decdelete (deletes if refcount is down to 0)
+ _CLDECDELETE(handle);
+
+ if (doUnlock)
+ mutex->unlock();
+ else
+ delete mutex;
+ }
+#else
+ _CLDECDELETE(handle);
+#endif
+}
+
+IndexInput* FSDirectory::FSIndexInput::clone() const
+{
+ return _CLNEW FSDirectory::FSIndexInput(*this);
+}
+
+void FSDirectory::FSIndexInput::seekInternal(const int64_t position)
+{
+ CND_PRECONDITION(position >= 0 && position < handle->_length,
+ "Seeking out of range")
+ _pos = position;
+}
+
+void FSDirectory::FSIndexInput::readInternal(uint8_t* b, const int32_t len)
+{
+ SCOPED_LOCK_MUTEX(*handle->THIS_LOCK)
+
+ CND_PRECONDITION(handle != NULL, "shared file handle has closed");
+ CND_PRECONDITION(handle->fhandle.isOpen(), "file is not open");
+
+ if (handle->_fpos != _pos) {
+ handle->fhandle.seek(_pos);
+ if (handle->fhandle.pos() != _pos)
+ _CLTHROWA( CL_ERR_IO, "File IO Seek error");
+ handle->_fpos = _pos;
+ }
+
+ bufferLength = (int32_t)handle->fhandle.read((char*)b, len);
+ if (bufferLength == 0)
+ _CLTHROWA(CL_ERR_IO, "read past EOF");
+
+ if (bufferLength == -1)
+ _CLTHROWA(CL_ERR_IO, "read error");
+
+ _pos += bufferLength;
+ handle->_fpos =_pos;
+}
+
+// # pragma mark -- FSDirectory::FSIndexInput::SharedHandle
+
+FSDirectory::FSIndexInput::SharedHandle::SharedHandle()
+ : _fpos(0)
+ , _length(0)
+{
+#ifdef _LUCENE_THREADMUTEX
+ THIS_LOCK = new _LUCENE_THREADMUTEX;
+#endif
+}
+
+FSDirectory::FSIndexInput::SharedHandle::~SharedHandle()
+{
+ if (fhandle.isOpen())
+ fhandle.close();
+}
+
+// # pragma mark -- FSDirectory::FSIndexOutput
+
+FSDirectory::FSIndexOutput::FSIndexOutput(const QString& path)
+{
+ //O_BINARY - Opens file in binary (untranslated) mode
+ //O_CREAT - Creates and opens new file for writing. Has no effect if file specified by filename exists
+ //O_RANDOM - Specifies that caching is optimized for, but not restricted to, random access from disk.
+ //O_WRONLY - Opens file for writing only;
+ fhandle.setFileName(path);
+ fhandle.open(QIODevice::ReadWrite | QIODevice::Truncate);
+
+ if (fhandle.error() != QFile::NoError) {
+ switch(fhandle.error()) {
+ case 1:
+ _CLTHROWA(CL_ERR_IO, "An error occurred when reading from the file");
+ break;
+ case 2:
+ _CLTHROWA(CL_ERR_IO, "An error occurred when writing to the file.");
+ break;
+ case 5:
+ _CLTHROWA(CL_ERR_IO, "The file could not be opened.");
+ break;
+ case 6:
+ _CLTHROWA(CL_ERR_IO, "The operation was aborted.");
+ break;
+ case 7:
+ _CLTHROWA(CL_ERR_IO, "A timeout occurred.");
+ break;
+ case 8:
+ _CLTHROWA(CL_ERR_IO, "An unspecified error occurred.");
+ break;
+ case 9:
+ _CLTHROWA(CL_ERR_IO, "The file could not be removed.");
+ break;
+ case 10:
+ _CLTHROWA(CL_ERR_IO, "The file could not be renamed.");
+ break;
+ case 11:
+ _CLTHROWA(CL_ERR_IO, "The position in the file could not be changed.");
+ break;
+ case 12:
+ _CLTHROWA(CL_ERR_IO, "The file could not be resized.e");
+ break;
+ case 13:
+ _CLTHROWA(CL_ERR_IO, "The file could not be accessed.");
+ break;
+ case 14:
+ _CLTHROWA(CL_ERR_IO, "The file could not be copied.");
+ break;
+ case 4:
+ default:
+ _CLTHROWA(CL_ERR_IO, "A fatal error occurred.");
+ }
+ }
+}
+
+FSDirectory::FSIndexOutput::~FSIndexOutput()
+{
+ if (fhandle.isOpen()) {
+ try {
+ FSIndexOutput::close();
+ } catch (CLuceneError& err) {
+ //ignore IO errors...
+ if (err.number() != CL_ERR_IO)
+ throw;
+ }
+ }
+}
+
+void FSDirectory::FSIndexOutput::close()
+{
+ try {
+ BufferedIndexOutput::close();
+ } catch (CLuceneError& err) {
+ //ignore IO errors...
+ if (err.number() != CL_ERR_IO)
+ throw;
+ }
+ fhandle.close();
+}
+
+int64_t FSDirectory::FSIndexOutput::length()
+{
+ CND_PRECONDITION(fhandle.isOpen(), "file is not open");
+ return fhandle.size();
+}
+
+void FSDirectory::FSIndexOutput::seek(const int64_t pos)
+{
+ CND_PRECONDITION(fhandle.isOpen(), "file is not open");
+
+ BufferedIndexOutput::seek(pos);
+ fhandle.seek(pos);
+ if (fhandle.pos() != pos)
+ _CLTHROWA(CL_ERR_IO, "File IO Seek error");
+}
+
+void FSDirectory::FSIndexOutput::flushBuffer(const uint8_t* b, const int32_t size)
+{
+ CND_PRECONDITION(fhandle.isOpen(), "file is not open");
+
+ if (size > 0 && fhandle.write((const char*)b, size) != size)
+ _CLTHROWA(CL_ERR_IO, "File IO Write error");
+}
+
+// # pragma mark -- FSDirectory
+
+FSDirectory::FSDirectory(const QString& path, const bool createDir)
+ : Directory()
+ , refCount(0)
+ , useMMap(false)
+{
+ //set a realpath so that if we change directory, we can still function
+ directory = QFileInfo(path).absoluteFilePath();
+ lockDir = directory;
+
+ QDir dir(lockDir);
+ if (!dir.exists()) {
+ if (!dir.mkpath(lockDir))
+ _CLTHROWA_DEL(CL_ERR_IO, "Cannot create temp directory");
+ }
+
+ QFileInfo info(lockDir);
+ if (info.isFile() || info.isSymLink())
+ _CLTHROWA(CL_ERR_IO, "Found regular file where directory expected");
+
+ if (createDir)
+ create();
+
+ dir.setPath(directory);
+ if (!dir.exists()) {
+ //19: len of " is not a directory"
+ char* err =
+ _CL_NEWARRAY(char, 19 + strlen(path.toLocal8Bit().constData()) + 1);
+ strcpy(err, path.toLocal8Bit().constData());
+ strcat(err, " is not a directory");
+ _CLTHROWA_DEL(CL_ERR_IO, err);
+ }
+}
+
+void FSDirectory::create()
+{
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ bool clear = false;
+ QDir dir(directory);
+ if (!dir.exists()) {
+ if (!dir.mkpath(directory)) {
+ char* err = _CL_NEWARRAY( // 27 len of "Couldn't create directory:"
+ char, 27 + strlen(directory.toLocal8Bit().constData()) + 1);
+ strcpy(err, "Couldn't create directory: ");
+ strcat(err, directory.toLocal8Bit().constData());
+ _CLTHROWA_DEL(CL_ERR_IO, err);
+ }
+ } else {
+ clear = true;
+ }
+
+ QFileInfo info(directory);
+ if (info.isFile() || info.isSymLink()) {
+ char tmp[1024];
+ _snprintf(tmp, 1024, "%s not a directory",
+ directory.toLocal8Bit().constData());
+ _CLTHROWA(CL_ERR_IO, tmp);
+ }
+
+ if (clear) {
+ dir.setPath(directory);
+ // clear probably existing lucene index files
+ QStringList fileList = dir.entryList(QDir::Files | QDir::Hidden
+ | QDir::NoSymLinks);
+ foreach(const QString file, fileList) {
+ if (CL_NS(index)::IndexReader::isLuceneFile(file)) {
+ if (!dir.remove(file))
+ _CLTHROWA(CL_ERR_IO, "Couldn't delete file ");
+ }
+ }
+
+ // clear probably existing file locks
+ QFileInfo dirInfo(lockDir);
+ if (dirInfo.exists() && dirInfo.isReadable() && dirInfo.isWritable()
+ && !dirInfo.isFile() && !dirInfo.isSymLink()) {
+ QDir lockDirectory(lockDir);
+ fileList = dir.entryList(QStringList() << getLockPrefix()
+ + QLatin1Char('*'), QDir::Files | QDir::Hidden | QDir::NoSymLinks);
+
+ foreach(const QString file, fileList) {
+ if (!lockDirectory.remove(file))
+ _CLTHROWA(CL_ERR_IO, "Couldn't delete file ");
+ }
+ }
+ else {
+ //todo: richer error: + lockDir.getAbsolutePath());
+ _CLTHROWA(CL_ERR_IO, "Cannot read lock directory");
+ }
+ }
+}
+
+void FSDirectory::priv_getFN(QString& buffer, const QString& name) const
+{
+ buffer.clear();
+ buffer.append(directory);
+ buffer.append(QDir::separator());
+ buffer.append(name);
+}
+
+FSDirectory::~FSDirectory()
+{
+}
+
+QStringList FSDirectory::list() const
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ QDir dir(directory);
+ return dir.entryList(QDir::Files | QDir::Hidden);
+}
+
+bool FSDirectory::fileExists(const QString& name) const
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ QDir dir(directory);
+ return dir.entryList().contains(name);
+}
+
+QString FSDirectory::getDirName() const
+{
+ return directory;
+}
+
+//static
+FSDirectory* FSDirectory::getDirectory(const QString& file, const bool _create)
+{
+ FSDirectory* dir = NULL;
+ {
+ if (file.isEmpty())
+ _CLTHROWA(CL_ERR_IO, "Invalid directory");
+
+ SCOPED_LOCK_MUTEX(DIRECTORIES.THIS_LOCK)
+ dir = DIRECTORIES.get(file);
+ if ( dir == NULL ){
+ dir = _CLNEW FSDirectory(file, _create);
+ DIRECTORIES.put(dir->directory, dir);
+ } else if (_create) {
+ dir->create();
+ }
+
+ {
+ SCOPED_LOCK_MUTEX(dir->THIS_LOCK)
+ dir->refCount++;
+ }
+ }
+
+ return _CL_POINTER(dir);
+}
+
+int64_t FSDirectory::fileModified(const QString& name) const
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ QFileInfo fInfo(directory + QDir::separator() + name);
+ return fInfo.lastModified().toTime_t();
+}
+
+//static
+int64_t FSDirectory::fileModified(const QString& dir, const QString& name)
+{
+ QFileInfo fInfo(dir + QDir::separator() + name);
+ return fInfo.lastModified().toTime_t();
+}
+
+void FSDirectory::touchFile(const QString& name)
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ QFile file(directory + QDir::separator() + name);
+ if (!file.open(QIODevice::ReadWrite))
+ _CLTHROWA(CL_ERR_IO, "IO Error while touching file");
+}
+
+int64_t FSDirectory::fileLength(const QString& name) const
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ QFileInfo fInfo(directory + QDir::separator() + name);
+ return fInfo.size();
+}
+
+IndexInput* FSDirectory::openInput(const QString& name)
+{
+ return openInput(name, CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE);
+}
+
+IndexInput* FSDirectory::openInput(const QString& name, int32_t bufferSize )
+{
+ CND_PRECONDITION(directory[0]!=0,"directory is not open")
+
+ return _CLNEW FSIndexInput(directory + QDir::separator() + name, bufferSize);
+}
+
+void FSDirectory::close()
+{
+ SCOPED_LOCK_MUTEX(DIRECTORIES.THIS_LOCK)
+ {
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ //refcount starts at 1
+ if (--refCount <= 0) {
+ Directory* dir = DIRECTORIES.get(getDirName());
+ if (dir) {
+ //this will be removed in ~FSDirectory
+ DIRECTORIES.remove(getDirName());
+ _CLDECDELETE(dir);
+ }
+ }
+ }
+}
+
+QString FSDirectory::getLockPrefix() const
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ QString dirName(QFileInfo(directory).absoluteFilePath());
+ if (dirName.isEmpty())
+ _CLTHROWA(CL_ERR_Runtime, "Invalid directory path");
+
+ // to be compatible with jlucene,
+ // we need to make some changes ...
+ if (dirName.at(1) == QLatin1Char(':'))
+ dirName[0] = dirName.at(0).toUpper();
+
+ TCHAR tBuffer[2048] = { 0 };
+ dirName.toWCharArray(tBuffer);
+
+ char aBuffer[4096] = { 0 };
+ STRCPY_TtoA(aBuffer, tBuffer, 4096);
+
+ QString string(QLatin1String("lucene-"));
+ QByteArray hash(QCryptographicHash::hash(aBuffer, QCryptographicHash::Md5));
+
+ // TODO: verify this !!!
+ return string.append(QLatin1String(hash.toHex().constData()));
+}
+
+bool FSDirectory::doDeleteFile(const QString& name)
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ QDir dir(directory);
+ return dir.remove(name);
+}
+
+void FSDirectory::renameFile(const QString& from, const QString& to)
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ if (fileExists(to))
+ deleteFile(to, false);
+
+ QFile file(directory + QDir::separator() + from);
+ QString newFile(directory + QDir::separator() + to);
+ if (!file.rename(newFile)) {
+ // try a second time if we fail
+ if (fileExists(to))
+ deleteFile(to, false);
+
+ if (!file.rename(newFile)) {
+ QString error(QLatin1String("Could not rename: %1 to %2!!!!"));
+ error.arg(from).arg(newFile);
+ QByteArray bArray(error.toLocal8Bit());
+ _CLTHROWA(CL_ERR_IO, bArray.constData());
+ }
+ }
+}
+
+IndexOutput* FSDirectory::createOutput(const QString& name)
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+ QString file = directory + QDir::separator() + name;
+ if (QFileInfo(file).exists()) {
+ if (!QFile::remove(file)) {
+ QByteArray bArray("Cannot overwrite: ");
+ bArray.append(name.toLocal8Bit());
+ _CLTHROWA(CL_ERR_IO, bArray.constData());
+ }
+ }
+ return _CLNEW FSIndexOutput(file);
+}
+
+LuceneLock* FSDirectory::makeLock(const QString& name)
+{
+ CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
+
+
+ QString lockFile(getLockPrefix());
+ lockFile.append(QLatin1Char('-')).append(name);
+
+ return _CLNEW FSLock(lockDir, lockFile);
+}
+
+QString FSDirectory::toString() const
+{
+ return QString::fromLatin1("FSDirectory@").append(directory);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/store/FSDirectory.h b/3rdparty/clucene/src/CLucene/store/FSDirectory.h
new file mode 100644
index 000000000..e967380e0
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/FSDirectory.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#ifndef _lucene_store_FSDirectory_
+#define _lucene_store_FSDirectory_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QFile>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include "Directory.h"
+#include "Lock.h"
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/StringBuffer.h"
+
+CL_NS_DEF(store)
+
+/**
+* Straightforward implementation of {@link Directory} as a directory of files.
+* <p>If the system property 'disableLuceneLocks' has the String value of
+* "true", lock creation will be disabled.
+*
+* @see Directory
+*/
+class FSDirectory : public Directory
+{
+public:
+ // Destructor - only call this if you are sure the directory
+ // is not being used anymore. Otherwise use the ref-counting
+ // facilities of _CLDECDELETE
+ ~FSDirectory();
+
+ // Get a list of strings, one for each file in the directory.
+ QStringList list() const;
+
+ // Returns true iff a file with the given name exists.
+ bool fileExists(const QString& name) const;
+
+ // Returns the text name of the directory
+ QString getDirName() const; ///<returns reference
+
+ /**
+ Returns the directory instance for the named location.
+
+ Do not delete this instance, only use close, otherwise other instances
+ will lose this instance.
+
+ <p>Directories are cached, so that, for a given canonical path, the same
+ FSDirectory instance will always be returned. This permits
+ synchronization on directories.
+
+ @param file the path to the directory.
+ @param create if true, create, or erase any existing contents.
+ @return the FSDirectory for the named file.
+ */
+ static FSDirectory* getDirectory(const QString& file, const bool create);
+
+ // Returns the time the named file was last modified.
+ int64_t fileModified(const QString& name) const;
+
+ //static
+ // Returns the time the named file was last modified.
+ static int64_t fileModified(const QString& dir, const QString& name);
+
+ // static
+ // Returns the length in bytes of a file in the directory.
+ int64_t fileLength(const QString& name) const;
+
+ // Returns a stream reading an existing file.
+ IndexInput* openInput(const QString& name);
+ IndexInput* openInput(const QString& name, int32_t bufferSize);
+
+ // Renames an existing file in the directory.
+ void renameFile(const QString& from, const QString& to);
+
+ // Set the modified time of an existing file to now.
+ void touchFile(const QString& name);
+
+ // Creates a new, empty file in the directory with the given name.
+ // Returns a stream writing this file.
+ IndexOutput* createOutput(const QString& name);
+
+ // Construct a {@link Lock}.
+ // @param name the name of the lock file
+ LuceneLock* makeLock(const QString& name);
+
+ // Decrease the ref-count to the directory by one. If the object is no
+ // longer needed, then the object is removed from the directory pool.
+ void close();
+
+ // If MMap is available, this can disable use of mmap reading.
+ void setUseMMap(bool value) { useMMap = value; }
+
+ // Gets whether the directory is using MMap for inputstreams.
+ bool getUseMMap() const { return useMMap; }
+
+ QString toString() const;
+
+ static QString DirectoryType() { return QLatin1String("FS"); }
+ QString getDirectoryType() const { return QLatin1String("FS"); }
+
+ // Set whether Lucene's use of lock files is disabled. By default,
+ // lock files are enabled. They should only be disabled if the index
+ // is on a read-only medium like a CD-ROM.
+ static void setDisableLocks(bool doDisableLocks)
+ { disableLocks = doDisableLocks; }
+
+ // Returns whether Lucene's use of lock files is disabled.
+ // @return true if locks are disabled, false if locks are enabled.
+ static bool getDisableLocks() { return disableLocks; }
+
+protected:
+ FSDirectory(const QString& path, const bool createDir);
+ // Removes an existing file in the directory.
+ bool doDeleteFile(const QString& name);
+
+private:
+ class FSLock : public LuceneLock {
+ public:
+ FSLock (const QString& lockDir, const QString& name);
+ ~FSLock();
+
+ bool obtain();
+ void release();
+ bool isLocked();
+ QString toString() const;
+
+ QString lockDir;
+ QString lockFile;
+ };
+ friend class FSDirectory::FSLock;
+
+ class FSIndexInput : public BufferedIndexInput {
+ public:
+ FSIndexInput(const QString& path, int32_t bufferSize =
+ CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE);
+ ~FSIndexInput();
+
+ void close();
+ IndexInput* clone() const;
+
+ int64_t length()
+ { return handle->_length; }
+
+ QString getDirectoryType() const
+ { return FSDirectory::DirectoryType(); }
+
+ protected:
+ FSIndexInput(const FSIndexInput& clone);
+ // Random-access methods
+ void seekInternal(const int64_t position);
+ // IndexInput methods
+ void readInternal(uint8_t* b, const int32_t len);
+
+ private:
+ // We used a shared handle between all the fsindexinput clones.
+ // This reduces number of file handles we need, and it means
+ // we dont have to use file tell (which is slow) before doing a read.
+ class SharedHandle : LUCENE_REFBASE {
+ public:
+ SharedHandle();
+ ~SharedHandle();
+
+ int64_t _fpos;
+ int64_t _length;
+
+ QFile fhandle;
+ DEFINE_MUTEX(*THIS_LOCK)
+ };
+ SharedHandle* handle;
+ int64_t _pos;
+ };
+ friend class FSDirectory::FSIndexInput;
+
+ class FSIndexOutput : public BufferedIndexOutput {
+ public:
+ FSIndexOutput(const QString& path);
+ ~FSIndexOutput();
+
+ void close();
+ int64_t length();
+ void seek(const int64_t pos);
+
+ protected:
+ void flushBuffer(const uint8_t* b, const int32_t size);
+
+ private:
+ QFile fhandle;
+ };
+ friend class FSDirectory::FSIndexOutput;
+
+private:
+ QString directory;
+ int refCount;
+ void create();
+
+ QString lockDir;
+ QString getLockPrefix() const;
+ static bool disableLocks;
+
+ void priv_getFN(QString& buffer, const QString& name) const;
+ bool useMMap;
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/IndexInput.cpp b/3rdparty/clucene/src/CLucene/store/IndexInput.cpp
new file mode 100644
index 000000000..cf7bd16b7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/IndexInput.cpp
@@ -0,0 +1,233 @@
+ /*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "IndexInput.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(store)
+
+ IndexInput::IndexInput()
+ {
+ }
+ IndexInput::IndexInput(const IndexInput& other)
+ {
+ }
+
+ int32_t IndexInput::readInt() {
+ int32_t b = (readByte() << 24);
+ b |= (readByte() << 16);
+ b |= (readByte() << 8);
+ return (b | readByte());
+ }
+
+ int32_t IndexInput::readVInt() {
+ uint8_t b = readByte();
+ int32_t i = b & 0x7F;
+ for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) {
+ b = readByte();
+ i |= (b & 0x7F) << shift;
+ }
+ return i;
+ }
+
+ int64_t IndexInput::readLong() {
+ int64_t i = ((int64_t)readInt() << 32);
+ return (i | ((int64_t)readInt() & 0xFFFFFFFFL));
+ }
+
+ int64_t IndexInput::readVLong() {
+ uint8_t b = readByte();
+ int64_t i = b & 0x7F;
+ for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) {
+ b = readByte();
+ i |= (((int64_t)b) & 0x7FL) << shift;
+ }
+ return i;
+ }
+
+ void IndexInput::skipChars( const int32_t count) {
+ for (int32_t i = 0; i < count; i++) {
+ TCHAR b = readByte();
+ if ((b & 0x80) == 0) {
+ // Do Nothing.
+ } else if ((b & 0xE0) != 0xE0) {
+ readByte();
+ } else {
+ readByte();
+ readByte();
+ }
+ }
+ }
+
+ int32_t IndexInput::readString(TCHAR* buffer, const int32_t maxLength){
+ int32_t len = readVInt();
+ int32_t ml=maxLength-1;
+ if ( len >= ml ){
+ readChars(buffer, 0, ml);
+ buffer[ml] = 0;
+ //we have to finish reading all the data for this string!
+ if ( len-ml > 0 ){
+ //seek(getFilePointer()+(len-ml)); <- that was the wrong way to "finish reading"
+ skipChars(len-ml);
+ }
+ return ml;
+ }else{
+ readChars(buffer, 0, len);
+ buffer[len] = 0;
+ return len;
+ }
+ }
+
+ TCHAR* IndexInput::readString(const bool _unique){
+ int32_t len = readVInt();
+
+ if ( len == 0){
+ if ( _unique ) //todo: does non unique ever occur?
+ return stringDuplicate(LUCENE_BLANK_STRING);
+ else
+ return LUCENE_BLANK_STRING;
+ }
+
+ TCHAR* ret = _CL_NEWARRAY(TCHAR,len+1);
+ readChars(ret, 0, len);
+ ret[len] = 0;
+
+ return ret;
+ }
+
+ void IndexInput::readChars( TCHAR* buffer, const int32_t start, const int32_t len) {
+ const int32_t end = start + len;
+ TCHAR b;
+ for (int32_t i = start; i < end; ++i) {
+ b = readByte();
+ if ((b & 0x80) == 0) {
+ b = (b & 0x7F);
+ } else if ((b & 0xE0) != 0xE0) {
+ b = (((b & 0x1F) << 6)
+ | (readByte() & 0x3F));
+ } else {
+ b = ((b & 0x0F) << 12) | ((readByte() & 0x3F) << 6);
+ b |= (readByte() & 0x3F);
+ }
+ buffer[i] = b;
+ }
+ }
+
+
+
+
+
+
+BufferedIndexInput::BufferedIndexInput(int32_t _bufferSize):
+ buffer(NULL),
+ bufferSize(_bufferSize),
+ bufferStart(0),
+ bufferLength(0),
+ bufferPosition(0)
+ {
+ }
+
+ BufferedIndexInput::BufferedIndexInput(const BufferedIndexInput& other):
+ IndexInput(other),
+ buffer(NULL),
+ bufferSize(other.bufferSize),
+ bufferStart(other.bufferStart),
+ bufferLength(other.bufferLength),
+ bufferPosition(other.bufferPosition)
+ {
+ /* DSR: Does the fact that sometime clone.buffer is not NULL even when
+ ** clone.bufferLength is zero indicate memory corruption/leakage?
+ ** if ( clone.buffer != NULL) { */
+ if (other.bufferLength != 0 && other.buffer != NULL) {
+ buffer = _CL_NEWARRAY(uint8_t,bufferLength);
+ memcpy(buffer,other.buffer,bufferLength * sizeof(uint8_t));
+ }
+ }
+
+ void BufferedIndexInput::readBytes(uint8_t* b, const int32_t len){
+ if (len < bufferSize) {
+ for (int32_t i = 0; i < len; ++i) // read byte-by-byte
+ b[i] = readByte();
+ } else { // read all-at-once
+ int64_t start = getFilePointer();
+ seekInternal(start);
+ readInternal(b, len);
+
+ bufferStart = start + len; // adjust stream variables
+ bufferPosition = 0;
+ bufferLength = 0; // trigger refill() on read
+ }
+ }
+
+ int64_t BufferedIndexInput::getFilePointer() const{
+ return bufferStart + bufferPosition;
+ }
+
+ void BufferedIndexInput::seek(const int64_t pos) {
+ if ( pos < 0 )
+ _CLTHROWA(CL_ERR_IO, "IO Argument Error. Value must be a positive value.");
+ if (pos >= bufferStart && pos < (bufferStart + bufferLength))
+ bufferPosition = (int32_t)(pos - bufferStart); // seek within buffer
+ else {
+ bufferStart = pos;
+ bufferPosition = 0;
+ bufferLength = 0; // trigger refill() on read()
+ seekInternal(pos);
+ }
+ }
+ void BufferedIndexInput::close(){
+ _CLDELETE_ARRAY(buffer);
+ bufferLength = 0;
+ bufferPosition = 0;
+ bufferStart = 0;
+ }
+
+
+ BufferedIndexInput::~BufferedIndexInput(){
+ BufferedIndexInput::close();
+ }
+
+ void BufferedIndexInput::refill() {
+ int64_t start = bufferStart + bufferPosition;
+ int64_t end = start + bufferSize;
+ if (end > length()) // don't read past EOF
+ end = length();
+ bufferLength = (int32_t)(end - start);
+ if (bufferLength == 0)
+ _CLTHROWA(CL_ERR_IO, "IndexInput read past EOF");
+
+ if (buffer == NULL){
+ buffer = _CL_NEWARRAY(uint8_t,bufferSize); // allocate buffer lazily
+ }
+ readInternal(buffer, bufferLength);
+
+
+ bufferStart = start;
+ bufferPosition = 0;
+ }
+
+
+IndexInputStream::IndexInputStream(IndexInput* input){
+ this->input = input;
+ this->size = input->length();
+ this->position = input->getFilePointer();
+}
+IndexInputStream::~IndexInputStream(){
+}
+int32_t IndexInputStream::fillBuffer(char* start, int32_t space){
+ int64_t avail = input->length()-input->getFilePointer();
+ if ( avail == 0 )
+ return -1;
+ else if ( avail<space )
+ space = (int32_t)avail;
+
+ input->readBytes((uint8_t*)start,space);
+ return space;
+}
+
+CL_NS_END
+
diff --git a/3rdparty/clucene/src/CLucene/store/IndexInput.h b/3rdparty/clucene/src/CLucene/store/IndexInput.h
new file mode 100644
index 000000000..9453b5cf1
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/IndexInput.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_store_IndexInput_
+#define _lucene_store_IndexInput_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/util/bufferedstream.h"
+#include "IndexOutput.h"
+
+CL_NS_DEF(store)
+
+ /** Abstract base class for input from a file in a {@link Directory}. A
+ * random-access input stream. Used for all Lucene index input operations.
+ * @see Directory
+ * @see IndexOutput
+ */
+ class IndexInput: LUCENE_BASE {
+ private:
+ void skipChars( const int32_t count);
+ protected:
+ IndexInput();
+ IndexInput(const IndexInput& clone);
+ public:
+ virtual ~IndexInput(){}
+ virtual IndexInput* clone() const =0;
+
+ DEFINE_MUTEX(THIS_LOCK)
+
+ /** Reads and returns a single byte.
+ * @see IndexOutput#writeByte(byte)
+ */
+ virtual uint8_t readByte() =0;
+
+ /** Reads a specified number of bytes into an array at the specified offset.
+ * @param b the array to read bytes into
+ * @param offset the offset in the array to start storing bytes
+ * @param len the number of bytes to read
+ * @see IndexOutput#writeBytes(byte[],int32_t)
+ */
+ virtual void readBytes(uint8_t* b, const int32_t len) =0;
+
+ /** Reads four bytes and returns an int.
+ * @see IndexOutput#writeInt(int32_t)
+ */
+ int32_t readInt();
+
+ /** Reads an int stored in variable-length format. Reads between one and
+ * five bytes. Smaller values take fewer bytes. Negative numbers are not
+ * supported.
+ * @see IndexOutput#writeVInt(int32_t)
+ */
+ virtual int32_t readVInt();
+
+ /** Reads eight bytes and returns a long.
+ * @see IndexOutput#writeLong(long)
+ */
+ int64_t readLong();
+
+ /** Reads a long stored in variable-length format. Reads between one and
+ * nine bytes. Smaller values take fewer bytes. Negative numbers are not
+ * supported. */
+ int64_t readVLong();
+
+ /** Reads a string.
+ * @see IndexOutput#writeString(String)
+ * maxLength is the amount read into the buffer, the whole string is still read from the stream
+ * returns the amount read
+ */
+ int32_t readString(TCHAR* buffer, const int32_t maxlength);
+
+ /** Reads a string.
+ * @see IndexOutput#writeString(String)
+ * If unique is true (default) the string will be duplicated.
+ * If false and the length is zero, LUCENE_BLANK_STRING is returned
+ */
+ TCHAR* readString(const bool unique=true);
+
+
+ /** Reads UTF-8 encoded characters into an array.
+ * @param buffer the array to read characters into
+ * @param start the offset in the array to start storing characters
+ * @param length the number of characters to read
+ * @see IndexOutput#writeChars(String,int32_t,int32_t)
+ */
+ void readChars( TCHAR* buffer, const int32_t start, const int32_t len);
+
+ /** Closes the stream to futher operations. */
+ virtual void close() =0;
+
+ /** Returns the current position in this file, where the next read will
+ * occur.
+ * @see #seek(long)
+ */
+ virtual int64_t getFilePointer() const =0;
+
+ /** Sets current position in this file, where the next read will occur.
+ * @see #getFilePointer()
+ */
+ virtual void seek(const int64_t pos) =0;
+
+ /** The number of bytes in the file. */
+ virtual int64_t length() = 0;
+
+ virtual QString getDirectoryType() const = 0;
+ };
+
+ /** Abstract base class for input from a file in a {@link Directory}. A
+ * random-access input stream. Used for all Lucene index input operations.
+ * @see Directory
+ * @see IndexOutput
+ */
+ class BufferedIndexInput: public IndexInput{
+ private:
+ uint8_t* buffer; //array of bytes
+ void refill();
+ protected:
+ int32_t bufferSize; //size of the buffer
+ int64_t bufferStart; // position in file of buffer
+ int32_t bufferLength; // end of valid l_byte_ts
+ int32_t bufferPosition; // next uint8_t to read
+
+ /** Returns a clone of this stream.
+ *
+ * <p>Clones of a stream access the same data, and are positioned at the same
+ * point as the stream they were cloned from.
+ *
+ * <p>Expert: Subclasses must ensure that clones may be positioned at
+ * different points in the input from each other and from the stream they
+ * were cloned from.
+ */
+ BufferedIndexInput(const BufferedIndexInput& clone);
+ BufferedIndexInput(int32_t bufferSize = CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE);
+ public:
+
+ virtual ~BufferedIndexInput();
+ virtual IndexInput* clone() const = 0;
+ void close();
+ inline uint8_t readByte(){
+ if (bufferPosition >= bufferLength)
+ refill();
+
+ return buffer[bufferPosition++];
+ }
+ void readBytes(uint8_t* b, const int32_t len);
+ int64_t getFilePointer() const;
+ void seek(const int64_t pos);
+
+ protected:
+ /** Expert: implements buffer refill. Reads bytes from the current position
+ * in the input.
+ * @param b the array to read bytes into
+ * @param offset the offset in the array to start storing bytes
+ * @param length the number of bytes to read
+ */
+ virtual void readInternal(uint8_t* b, const int32_t len) = 0;
+
+ /** Expert: implements seek. Sets current position in this file, where the
+ * next {@link #readInternal(byte[],int32_t,int32_t)} will occur.
+ * @see #readInternal(byte[],int32_t,int32_t)
+ */
+ virtual void seekInternal(const int64_t pos) = 0;
+ };
+
+ /**
+ * JStream InputStream which reads from an IndexInput. This class is
+ * used by the FieldReader to create binary fields. You can then use
+ * a GZipInputStream to read compressed data or any of the other
+ * JStream stream types.
+ *
+ */
+ class IndexInputStream: public jstreams::BufferedInputStream<char>{
+ IndexInput* input;
+ public:
+ IndexInputStream(IndexInput* input);
+ ~IndexInputStream();
+ int32_t fillBuffer(char* start, int32_t space);
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/IndexOutput.cpp b/3rdparty/clucene/src/CLucene/store/IndexOutput.cpp
new file mode 100644
index 000000000..04f78c348
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/IndexOutput.cpp
@@ -0,0 +1,163 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "IndexOutput.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(store)
+
+
+ IndexOutput::IndexOutput()
+ {
+ }
+
+ IndexOutput::~IndexOutput(){
+ }
+
+ BufferedIndexOutput::BufferedIndexOutput()
+ {
+ buffer = _CL_NEWARRAY(uint8_t, BUFFER_SIZE );
+ bufferStart = 0;
+ bufferPosition = 0;
+ }
+
+ BufferedIndexOutput::~BufferedIndexOutput(){
+ if ( buffer != NULL )
+ close();
+ }
+
+ void BufferedIndexOutput::close(){
+ flush();
+ _CLDELETE_ARRAY( buffer );
+
+ bufferStart = 0;
+ bufferPosition = 0;
+ }
+
+ void BufferedIndexOutput::writeByte(const uint8_t b) {
+ CND_PRECONDITION(buffer!=NULL,"IndexOutput is closed")
+ if (bufferPosition >= BUFFER_SIZE)
+ flush();
+ buffer[bufferPosition++] = b;
+ }
+
+ void BufferedIndexOutput::writeBytes(const uint8_t* b, const int32_t length) {
+ if ( length < 0 )
+ _CLTHROWA(CL_ERR_IllegalArgument, "IO Argument Error. Value must be a positive value.");
+ int32_t bytesLeft = BUFFER_SIZE - bufferPosition;
+ // is there enough space in the buffer?
+ if (bytesLeft >= length) {
+ // we add the data to the end of the buffer
+ memcpy(buffer + bufferPosition, b, length);
+ bufferPosition += length;
+ // if the buffer is full, flush it
+ if (BUFFER_SIZE - bufferPosition == 0)
+ flush();
+ } else {
+ // is data larger then buffer?
+ if (length > BUFFER_SIZE) {
+ // we flush the buffer
+ if (bufferPosition > 0)
+ flush();
+ // and write data at once
+ flushBuffer(b, length);
+ bufferStart += length;
+ } else {
+ // we fill/flush the buffer (until the input is written)
+ int64_t pos = 0; // position in the input data
+ int32_t pieceLength;
+ while (pos < length) {
+ if ( length - pos < bytesLeft )
+ pieceLength = length - pos;
+ else
+ pieceLength = bytesLeft;
+ memcpy(buffer + bufferPosition, b + pos, pieceLength);
+ pos += pieceLength;
+ bufferPosition += pieceLength;
+ // if the buffer is full, flush it
+ bytesLeft = BUFFER_SIZE - bufferPosition;
+ if (bytesLeft == 0) {
+ flush();
+ bytesLeft = BUFFER_SIZE;
+ }
+ }
+ }
+ }
+ }
+
+ void IndexOutput::writeInt(const int32_t i) {
+ writeByte((uint8_t)(i >> 24));
+ writeByte((uint8_t)(i >> 16));
+ writeByte((uint8_t)(i >> 8));
+ writeByte((uint8_t) i);
+ }
+
+ void IndexOutput::writeVInt(const int32_t vi) {
+ uint32_t i = vi;
+ while ((i & ~0x7F) != 0) {
+ writeByte((uint8_t)((i & 0x7f) | 0x80));
+ i >>= 7; //doing unsigned shift
+ }
+ writeByte( (uint8_t)i );
+ }
+
+ void IndexOutput::writeLong(const int64_t i) {
+ writeInt((int32_t) (i >> 32));
+ writeInt((int32_t) i);
+ }
+
+ void IndexOutput::writeVLong(const int64_t vi) {
+ uint64_t i = vi;
+ while ((i & ~0x7F) != 0) {
+ writeByte((uint8_t)((i & 0x7f) | 0x80));
+ i >>= 7; //doing unsigned shift
+ }
+ writeByte((uint8_t)i);
+ }
+
+ void IndexOutput::writeString(const TCHAR* s, const int32_t length ) {
+ writeVInt(length);
+ writeChars(s, 0, length);
+ }
+
+ void IndexOutput::writeChars(const TCHAR* s, const int32_t start, const int32_t length){
+ if ( length < 0 || start < 0 )
+ _CLTHROWA(CL_ERR_IllegalArgument, "IO Argument Error. Value must be a positive value.");
+
+ const int32_t end = start + length;
+ for (int32_t i = start; i < end; ++i) {
+ const int32_t code = (int32_t)s[i];
+ if (code >= 0x01 && code <= 0x7F)
+ writeByte((uint8_t)code);
+ else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0) {
+ writeByte((uint8_t)(0xC0 | (code >> 6)));
+ writeByte((uint8_t)(0x80 | (code & 0x3F)));
+ } else {
+ writeByte((uint8_t)(0xE0 | (((uint32_t)code) >> 12))); //unsigned shift
+ writeByte((uint8_t)(0x80 | ((code >> 6) & 0x3F)));
+ writeByte((uint8_t)(0x80 | (code & 0x3F)));
+ }
+ }
+ }
+
+
+ int64_t BufferedIndexOutput::getFilePointer() const{
+ return bufferStart + bufferPosition;
+ }
+
+ void BufferedIndexOutput::seek(const int64_t pos) {
+ flush();
+ bufferStart = pos;
+ }
+
+ void BufferedIndexOutput::flush() {
+ flushBuffer(buffer, bufferPosition);
+ bufferStart += bufferPosition;
+ bufferPosition = 0;
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/store/IndexOutput.h b/3rdparty/clucene/src/CLucene/store/IndexOutput.h
new file mode 100644
index 000000000..c47ee73a7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/IndexOutput.h
@@ -0,0 +1,152 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_store_IndexOutput_
+#define _lucene_store_IndexOutput_
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF(store)
+
+
+/** Abstract class for output to a file in a Directory. A random-access output
+* stream. Used for all Lucene index output operations.
+* @see Directory
+* @see IndexInput
+*/
+class IndexOutput:LUCENE_BASE{
+ bool isclosed;
+public:
+ IndexOutput();
+ virtual ~IndexOutput();
+
+ /** Writes a single byte.
+ * @see IndexInput#readByte()
+ */
+ virtual void writeByte(const uint8_t b) = 0;
+
+ /** Writes an array of bytes.
+ * @param b the bytes to write
+ * @param length the number of bytes to write
+ * @see IndexInput#readBytes(byte[],int32_t,int32_t)
+ */
+ virtual void writeBytes(const uint8_t* b, const int32_t length) = 0;
+
+ /** Writes an int as four bytes.
+ * @see IndexInput#readInt()
+ */
+ void writeInt(const int32_t i);
+
+ /** Writes an int in a variable-length format. Writes between one and
+ * five bytes. Smaller values take fewer bytes. Negative numbers are not
+ * supported.
+ * @see IndexInput#readVInt()
+ */
+ void writeVInt(const int32_t vi);
+
+ /** Writes a long as eight bytes.
+ * @see IndexInput#readLong()
+ */
+ void writeLong(const int64_t i);
+
+ /** Writes an long in a variable-length format. Writes between one and five
+ * bytes. Smaller values take fewer bytes. Negative numbers are not
+ * supported.
+ * @see IndexInput#readVLong()
+ */
+ void writeVLong(const int64_t vi);
+
+ /** Writes a string.
+ * @see IndexInput#readString()
+ */
+ void writeString(const TCHAR* s, const int32_t length);
+
+ /** Writes a sequence of UTF-8 encoded characters from a string.
+ * @param s the source of the characters
+ * @param start the first character in the sequence
+ * @param length the number of characters in the sequence
+ * @see IndexInput#readChars(char[],int32_t,int32_t)
+ */
+ void writeChars(const TCHAR* s, const int32_t start, const int32_t length);
+
+ /** Closes this stream to further operations. */
+ virtual void close() = 0;
+
+ /** Returns the current position in this file, where the next write will
+ * occur.
+ * @see #seek(long)
+ */
+ virtual int64_t getFilePointer() const = 0;
+
+ /** Sets current position in this file, where the next write will occur.
+ * @see #getFilePointer()
+ */
+ virtual void seek(const int64_t pos) = 0;
+
+ /** The number of bytes in the file. */
+ virtual int64_t length() = 0;
+
+ /** Forces any buffered output to be written. */
+ virtual void flush() = 0;
+};
+
+/** Base implementation class for buffered {@link IndexOutput}. */
+class BufferedIndexOutput : public IndexOutput{
+public:
+ LUCENE_STATIC_CONSTANT(int32_t, BUFFER_SIZE=LUCENE_STREAM_BUFFER_SIZE);
+private:
+ uint8_t* buffer;
+ int64_t bufferStart; // position in file of buffer
+ int32_t bufferPosition; // position in buffer
+
+public:
+ BufferedIndexOutput();
+ virtual ~BufferedIndexOutput();
+
+ /** Writes a single byte.
+ * @see IndexInput#readByte()
+ */
+ virtual void writeByte(const uint8_t b);
+
+ /** Writes an array of bytes.
+ * @param b the bytes to write
+ * @param length the number of bytes to write
+ * @see IndexInput#readBytes(byte[],int32_t,int32_t)
+ */
+ virtual void writeBytes(const uint8_t* b, const int32_t length);
+
+ /** Closes this stream to further operations. */
+ virtual void close();
+
+ /** Returns the current position in this file, where the next write will
+ * occur.
+ * @see #seek(long)
+ */
+ int64_t getFilePointer() const;
+
+ /** Sets current position in this file, where the next write will occur.
+ * @see #getFilePointer()
+ */
+ virtual void seek(const int64_t pos);
+
+ /** The number of bytes in the file. */
+ virtual int64_t length() = 0;
+
+ /** Forces any buffered output to be written. */
+ void flush();
+
+protected:
+ /** Expert: implements buffer write. Writes bytes at the current position in
+ * the output.
+ * @param b the bytes to write
+ * @param len the number of bytes to write
+ */
+ virtual void flushBuffer(const uint8_t* b, const int32_t len) = 0;
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/InputStream.h b/3rdparty/clucene/src/CLucene/store/InputStream.h
new file mode 100644
index 000000000..f56819eeb
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/InputStream.h
@@ -0,0 +1,21 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_store_InputStream_
+#define _lucene_store_InputStream_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF(store)
+
+deprecated... please use IndexInput.h header
+and change InputStream to IndexInput
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/Lock.cpp b/3rdparty/clucene/src/CLucene/store/Lock.cpp
new file mode 100644
index 000000000..a66e784b0
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/Lock.cpp
@@ -0,0 +1,27 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "Lock.h"
+
+CL_NS_DEF(store)
+
+ bool LuceneLock::obtain(int64_t lockWaitTimeout) {
+ bool locked = obtain();
+ int maxSleepCount = (int)(lockWaitTimeout / LOCK_POLL_INTERVAL);
+ int sleepCount = 0;
+ while (!locked) {
+ if (sleepCount++ == maxSleepCount) {
+ _CLTHROWA(CL_ERR_IO,"Lock obtain timed out");
+ }
+ _LUCENE_SLEEP(LOCK_POLL_INTERVAL);
+ locked = obtain();
+ }
+ return locked;
+ }
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/store/Lock.h b/3rdparty/clucene/src/CLucene/store/Lock.h
new file mode 100644
index 000000000..b5dda3b06
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/Lock.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_store_Lock_
+#define _lucene_store_Lock_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF(store)
+
+class LuceneLock : LUCENE_BASE
+{
+public:
+ LUCENE_STATIC_CONSTANT(int64_t, LOCK_POLL_INTERVAL = 1000);
+
+ virtual ~LuceneLock() {}
+
+ // Attempts to obtain exclusive access and immediately return upon success
+ // or failure. Return true if exclusive access is obtained.
+ virtual bool obtain() = 0;
+
+ // Attempts to obtain an exclusive lock within amount of time given.
+ // Currently polls once per second until lockWaitTimeout is passed.
+ // @param lockWaitTimeout length of time to wait in ms
+ // @return true if lock was obtained
+ // @throws IOException if lock wait times out or obtain() throws an IOException
+ bool obtain(int64_t lockWaitTimeout);
+
+ // Release exclusive access.
+ virtual void release() = 0;
+
+ // Returns true if the resource is currently locked. Note that one must
+ // still call {@link #obtain()} before using the resource.
+ virtual bool isLocked() = 0;
+
+ virtual QString toString() const = 0;
+};
+
+
+// Utility class for executing code with exclusive access.
+template<typename T>
+class LuceneLockWith
+{
+public:
+ // Constructs an executor that will grab the named lock. Defaults
+ // lockWaitTimeout to LUCENE_COMMIT_LOCK_TIMEOUT.
+ // @deprecated Kept only to avoid breaking existing code.
+ LuceneLockWith(LuceneLock* lock, int64_t lockWaitTimeout)
+ {
+ this->lock = lock;
+ this->lockWaitTimeout = lockWaitTimeout;
+ }
+
+ virtual ~LuceneLockWith() {}
+
+ // Calls {@link #doBody} while <i>lock</i> is obtained. Blocks if lock
+ // cannot be obtained immediately. Retries to obtain lock once per second
+ // until it is obtained, or until it has tried ten times. Lock is released
+ // when {@link #doBody} exits.
+ T runAndReturn()
+ {
+ bool locked = false;
+ T ret = NULL;
+ try {
+ locked = lock->obtain(lockWaitTimeout);
+ ret = doBody();
+ } _CLFINALLY (
+ if (locked)
+ lock->release();
+ );
+ return ret;
+ }
+
+ // @see runAndReturn
+ // Same as runAndReturn, except doesn't return any value. The only
+ // difference is that no void values are used
+ void run()
+ {
+ bool locked = false;
+ try {
+ locked = lock->obtain(lockWaitTimeout);
+ doBody();
+ } _CLFINALLY (
+ if (locked)
+ lock->release();
+ );
+ }
+
+protected:
+ virtual T doBody() = 0;
+
+private:
+ LuceneLock* lock;
+ int64_t lockWaitTimeout;
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/MMapInput.cpp b/3rdparty/clucene/src/CLucene/store/MMapInput.cpp
new file mode 100644
index 000000000..d660032c6
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/MMapInput.cpp
@@ -0,0 +1,203 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#if defined(LUCENE_FS_MMAP)
+
+#include "FSDirectory.h"
+#include "CLucene/util/Misc.h"
+#include "CLucene/debug/condition.h"
+
+#ifndef _CLCOMPILER_MSVC
+ #include <sys/mman.h>
+#endif
+
+CL_NS_DEF(store)
+CL_NS_USE(util)
+
+ FSDirectory::MMapIndexInput::MMapIndexInput(const char* path):
+ pos(0),
+ data(NULL),
+ _length(0),
+ isClone(false)
+ {
+ //Func - Constructor.
+ // Opens the file named path
+ //Pre - path != NULL
+ //Post - if the file could not be opened an exception is thrown.
+
+ CND_PRECONDITION(path != NULL, "path is NULL");
+
+#ifdef _CLCOMPILER_MSVC
+ mmaphandle = NULL;
+ fhandle = CreateFileA(path,GENERIC_READ,FILE_SHARE_READ, 0,OPEN_EXISTING,0,0);
+
+ //Check if a valid fhandle was retrieved
+ if (fhandle < 0){
+ DWORD err = GetLastError();
+ if ( err == ERROR_FILE_NOT_FOUND )
+ _CLTHROWA(CL_ERR_IO, "File does not exist");
+ else if ( err == EACCES )
+ _CLTHROWA(ERROR_ACCESS_DENIED, "File Access denied");
+ else if ( err == ERROR_TOO_MANY_OPEN_FILES )
+ _CLTHROWA(CL_ERR_IO, "Too many open files");
+ else
+ _CLTHROWA(CL_ERR_IO, "File IO Error");
+ }
+
+ DWORD dummy=0;
+ _length = GetFileSize(fhandle,&dummy);
+
+ if ( _length > 0 ){
+ mmaphandle = CreateFileMappingA(fhandle,NULL,PAGE_READONLY,0,0,NULL);
+ if ( mmaphandle != NULL ){
+ void* address = MapViewOfFile(mmaphandle,FILE_MAP_READ,0,0,0);
+ if ( address != NULL ){
+ data = (uint8_t*)address;
+ return; //SUCCESS!
+ }
+ }
+ CloseHandle(mmaphandle);
+
+ char* lpMsgBuf=0;
+ DWORD dw = GetLastError();
+
+ FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dw,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ lpMsgBuf,
+ 0, NULL );
+
+ char* errstr = _CL_NEWARRAY(char, strlen(lpMsgBuf)+40);
+ sprintf(errstr, "MMapIndexInput::MMapIndexInput failed with error %d: %s", dw, lpMsgBuf);
+ LocalFree(lpMsgBuf);
+
+ _CLTHROWA_DEL(CL_ERR_IO,errstr);
+ }
+
+#else //_CLCOMPILER_MSVC
+ fhandle = ::open (path, O_RDONLY);
+ if (fhandle < 0){
+ _CLTHROWA(CL_ERR_IO,strerror(errno));
+ }else{
+ // stat it
+ struct stat sb;
+ if (::fstat (fhandle, &sb)){
+ _CLTHROWA(CL_ERR_IO,strerror(errno));
+ }else{
+ // get length from stat
+ _length = sb.st_size;
+
+ // mmap the file
+ void* address = ::mmap(0, _length, PROT_READ, MAP_SHARED, fhandle, 0);
+ if (address == MAP_FAILED){
+ _CLTHROWA(CL_ERR_IO,strerror(errno));
+ }else{
+ data = (uint8_t*)address;
+ }
+ }
+ }
+#endif
+ }
+
+ FSDirectory::MMapIndexInput::MMapIndexInput(const MMapIndexInput& clone): IndexInput(clone){
+ //Func - Constructor
+ // Uses clone for its initialization
+ //Pre - clone is a valide instance of FSIndexInput
+ //Post - The instance has been created and initialized by clone
+
+#ifdef _CLCOMPILER_MSVC
+ mmaphandle = NULL;
+ fhandle = NULL;
+#endif
+
+ data = clone.data;
+ pos = clone.pos;
+
+ //clone the file length
+ _length = clone._length;
+ //Keep in mind that this instance is a clone
+ isClone = true;
+ }
+
+ uint8_t FSDirectory::MMapIndexInput::readByte(){
+ return *(data+(pos++));
+ }
+
+ void FSDirectory::MMapIndexInput::readBytes(uint8_t* b, const int32_t len){
+ memcpy(b, data+pos, len);
+ pos+=len;
+ }
+ int32_t FSDirectory::MMapIndexInput::readVInt(){
+ uint8_t b = *(data+(pos++));
+ int32_t i = b & 0x7F;
+ for (int shift = 7; (b & 0x80) != 0; shift += 7) {
+ b = *(data+(pos++));
+ i |= (b & 0x7F) << shift;
+ }
+ return i;
+ }
+ int64_t FSDirectory::MMapIndexInput::getFilePointer() const{
+ return pos;
+ }
+ void FSDirectory::MMapIndexInput::seek(const int64_t pos){
+ this->pos=pos;
+ }
+
+ FSDirectory::MMapIndexInput::~MMapIndexInput(){
+ //Func - Destructor
+ //Pre - True
+ //Post - The file for which this instance is responsible has been closed.
+ // The instance has been destroyed
+
+ close();
+ }
+
+ IndexInput* FSDirectory::MMapIndexInput::clone() const
+ {
+ return _CLNEW FSDirectory::MMapIndexInput(*this);
+ }
+ void FSDirectory::MMapIndexInput::close() {
+ //IndexInput::close();
+
+ if ( !isClone ){
+#ifdef _CLCOMPILER_MSVC
+ if ( data != NULL ){
+ if ( ! UnmapViewOfFile(data) ){
+ CND_PRECONDITION( false, "UnmapViewOfFile(data) failed"); //todo: change to rich error
+ }
+ }
+
+ if ( mmaphandle != NULL ){
+ if ( ! CloseHandle(mmaphandle) ){
+ CND_PRECONDITION( false, "CloseHandle(mmaphandle) failed");
+ }
+ }
+ if ( fhandle != NULL ){
+ if ( !CloseHandle(fhandle) ){
+ CND_PRECONDITION( false, "CloseHandle(fhandle) failed");
+ }
+ }
+ mmaphandle = NULL;
+ fhandle = NULL;
+#else
+ if ( data != NULL )
+ ::munmap(data, _length);
+ if ( fhandle > 0 )
+ ::close(fhandle);
+ fhandle = 0;
+#endif
+ }
+ data = NULL;
+ pos = 0;
+ }
+
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/OutputStream.h b/3rdparty/clucene/src/CLucene/store/OutputStream.h
new file mode 100644
index 000000000..a82d6718a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/OutputStream.h
@@ -0,0 +1,23 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_store_IndexOutput_
+#define _lucene_store_IndexOutput_
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+CL_NS_DEF(store)
+
+
+deprecated... please use IndexOutput.h header
+and change OutputStream to OutdexInput
+
+
+
+CL_NS_END
+
+#endif // _lucene_store_IndexOutput_
diff --git a/3rdparty/clucene/src/CLucene/store/RAMDirectory.cpp b/3rdparty/clucene/src/CLucene/store/RAMDirectory.cpp
new file mode 100644
index 000000000..b0a7c4d64
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/RAMDirectory.cpp
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#include "CLucene/StdHeader.h"
+#include "RAMDirectory.h"
+
+#include "Lock.h"
+#include "Directory.h"
+#include "FSDirectory.h"
+#include "CLucene/index/IndexReader.h"
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/Misc.h"
+#include "CLucene/debug/condition.h"
+
+CL_NS_USE(util)
+CL_NS_DEF(store)
+
+RAMFile::RAMFile()
+{
+ length = 0;
+ lastModified = Misc::currentTimeMillis();
+}
+
+RAMFile::~RAMFile()
+{
+}
+
+
+RAMDirectory::RAMLock::RAMLock(const QString& name, RAMDirectory* dir)
+ : directory(dir)
+{
+ fname = name;
+}
+
+RAMDirectory::RAMLock::~RAMLock()
+{
+ directory = NULL;
+}
+
+QString RAMDirectory::RAMLock::toString() const
+{
+ return QLatin1String("LockFile@RAM");
+}
+
+bool RAMDirectory::RAMLock::isLocked()
+{
+ return directory->fileExists(fname);
+}
+
+bool RAMDirectory::RAMLock::obtain()
+{
+ SCOPED_LOCK_MUTEX(directory->files_mutex);
+ if (!directory->fileExists(fname)) {
+ IndexOutput* tmp = directory->createOutput(fname);
+ tmp->close();
+ _CLDELETE(tmp);
+
+ return true;
+ }
+ return false;
+}
+
+void RAMDirectory::RAMLock::release()
+{
+ directory->deleteFile(fname);
+}
+
+RAMIndexOutput::~RAMIndexOutput()
+{
+ if (deleteFile)
+ _CLDELETE(file);
+ file = NULL;
+}
+
+RAMIndexOutput::RAMIndexOutput(RAMFile* f)
+ : file(f)
+{
+ pointer = 0;
+ deleteFile = false;
+}
+
+RAMIndexOutput::RAMIndexOutput()
+ : file(_CLNEW RAMFile)
+{
+ pointer = 0;
+ deleteFile = true;
+}
+
+void RAMIndexOutput::writeTo(IndexOutput* out)
+{
+ flush();
+ int64_t end = file->length;
+ int64_t pos = 0;
+ int32_t p = 0;
+ while (pos < end) {
+ int32_t length = CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE;
+ int64_t nextPos = pos + length;
+ if (nextPos > end) { // at the last buffer
+ length = (int32_t)(end - pos);
+ }
+ out->writeBytes((uint8_t*)file->buffers[p++], length);
+ pos = nextPos;
+ }
+}
+
+void RAMIndexOutput::reset()
+{
+ seek(_ILONGLONG(0));
+ file->length = _ILONGLONG(0);
+}
+
+void RAMIndexOutput::flushBuffer(const uint8_t* src, const int32_t len)
+{
+ uint8_t* b = NULL;
+ int32_t bufferPos = 0;
+ while (bufferPos != len) {
+ uint32_t bufferNumber = pointer/CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE;
+ int32_t bufferOffset = pointer%CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE;
+ int32_t bytesInBuffer = CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE - bufferOffset;
+ int32_t remainInSrcBuffer = len - bufferPos;
+ int32_t bytesToCopy = bytesInBuffer >= remainInSrcBuffer ? remainInSrcBuffer : bytesInBuffer;
+
+ if (bufferNumber == file->buffers.size()){
+ b = _CL_NEWARRAY(uint8_t, CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE);
+ file->buffers.push_back( b );
+ }else{
+ b = file->buffers[bufferNumber];
+ }
+ memcpy(b+bufferOffset, src+bufferPos, bytesToCopy * sizeof(uint8_t));
+ bufferPos += bytesToCopy;
+ pointer += bytesToCopy;
+ }
+ if (pointer > file->length)
+ file->length = pointer;
+
+ file->lastModified = Misc::currentTimeMillis();
+}
+
+void RAMIndexOutput::close()
+{
+ BufferedIndexOutput::close();
+}
+
+/** Random-at methods */
+void RAMIndexOutput::seek(const int64_t pos)
+{
+ BufferedIndexOutput::seek(pos);
+ pointer = (int32_t)pos;
+}
+
+int64_t RAMIndexOutput::length()
+{
+ return file->length;
+}
+
+
+RAMIndexInput::RAMIndexInput(RAMFile* f)
+ : file(f)
+{
+ pointer = 0;
+ _length = f->length;
+}
+
+RAMIndexInput::RAMIndexInput(const RAMIndexInput& other)
+ : BufferedIndexInput(other)
+{
+ file = other.file;
+ pointer = other.pointer;
+ _length = other._length;
+}
+
+RAMIndexInput::~RAMIndexInput()
+{
+ RAMIndexInput::close();
+}
+
+IndexInput* RAMIndexInput::clone() const
+{
+ return _CLNEW RAMIndexInput(*this);
+}
+
+int64_t RAMIndexInput::length()
+{
+ return _length;
+}
+
+QString RAMIndexInput::getDirectoryType() const
+{
+ return RAMDirectory::DirectoryType();
+}
+
+void RAMIndexInput::readInternal(uint8_t* dest, const int32_t len)
+{
+ const int64_t bytesAvailable = file->length - pointer;
+ int64_t remainder = len <= bytesAvailable ? len : bytesAvailable;
+ int32_t start = pointer;
+ int32_t destOffset = 0;
+ while (remainder != 0) {
+ int32_t bufferNumber = start / CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE;
+ int32_t bufferOffset = start % CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE;
+ int32_t bytesInBuffer = CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE - bufferOffset;
+
+ /* The buffer's entire length (bufferLength) is defined by IndexInput.h
+ ** as int32_t, so obviously the number of bytes in a given segment of the
+ ** buffer won't exceed the the capacity of int32_t. Therefore, the
+ ** int64_t->int32_t cast on the next line is safe. */
+ int32_t bytesToCopy = bytesInBuffer >= remainder ? static_cast<int32_t>(remainder) : bytesInBuffer;
+ uint8_t* b = file->buffers[bufferNumber];
+ memcpy(dest + destOffset, b + bufferOffset, bytesToCopy * sizeof(uint8_t));
+
+ destOffset += bytesToCopy;
+ start += bytesToCopy;
+ remainder -= bytesToCopy;
+ pointer += bytesToCopy;
+ }
+}
+
+void RAMIndexInput::close()
+{
+ BufferedIndexInput::close();
+}
+
+void RAMIndexInput::seekInternal(const int64_t pos)
+{
+ CND_PRECONDITION(pos >= 0 && pos < this->_length, "Seeking out of range")
+ pointer = (int32_t)pos;
+}
+
+// #pragma mark -- RAMDirectory
+
+QStringList RAMDirectory::list() const
+{
+ SCOPED_LOCK_MUTEX(files_mutex);
+
+ QStringList names;
+
+ FileMap::const_iterator itr;
+ for (itr = files.begin(); itr != files.end(); ++itr)
+ names.push_back(itr->first);
+
+ return names;
+}
+
+RAMDirectory::RAMDirectory()
+ : Directory()
+ , files(false, true)
+{
+}
+
+RAMDirectory::~RAMDirectory()
+{
+ //todo: should call close directory?
+}
+
+void RAMDirectory::_copyFromDir(Directory* dir, bool closeDir)
+{
+ QStringList names = dir->list();
+ uint8_t buf[CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE];
+
+ foreach (const QString& name, names) {
+ if (!CL_NS(index)::IndexReader::isLuceneFile(name))
+ continue;
+
+ // make place on ram disk
+ IndexOutput* os = createOutput(name);
+ // read current file
+ IndexInput* is = dir->openInput(name);
+
+ // and copy to ram disk
+ //todo: this could be a problem when copying from big indexes...
+ int64_t readCount = 0;
+ int64_t len = is->length();
+ while (readCount < len) {
+ int32_t toRead = CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE;
+ if ((readCount + toRead) > len)
+ toRead = int32_t(len - readCount);
+ is->readBytes(buf, toRead);
+ os->writeBytes(buf, toRead);
+ readCount += toRead;
+ }
+
+ // graceful cleanup
+ is->close();
+ _CLDELETE(is);
+ os->close();
+ _CLDELETE(os);
+ }
+ if (closeDir)
+ dir->close();
+}
+
+RAMDirectory::RAMDirectory(Directory* dir)
+ : Directory()
+ , files(false, true)
+{
+ _copyFromDir(dir, false);
+}
+
+RAMDirectory::RAMDirectory(const QString& dir)
+ : Directory()
+ , files(false, true)
+{
+ Directory* fsdir = FSDirectory::getDirectory(dir, false);
+ try {
+ _copyFromDir(fsdir, false);
+ } _CLFINALLY (
+ fsdir->close();
+ _CLDECDELETE(fsdir);
+ );
+}
+
+bool RAMDirectory::fileExists(const QString& name) const
+{
+ SCOPED_LOCK_MUTEX(files_mutex);
+ return files.exists(name);
+}
+
+int64_t RAMDirectory::fileModified(const QString& name) const
+{
+ SCOPED_LOCK_MUTEX(files_mutex);
+ const RAMFile* f = files.get(name);
+ return f->lastModified;
+}
+
+int64_t RAMDirectory::fileLength(const QString& name) const
+{
+ SCOPED_LOCK_MUTEX(files_mutex);
+ RAMFile* f = files.get(name);
+ return f->length;
+}
+
+
+IndexInput* RAMDirectory::openInput(const QString& name)
+{
+ SCOPED_LOCK_MUTEX(files_mutex);
+ RAMFile* file = files.get(name);
+ if (file == NULL) {
+ _CLTHROWA(CL_ERR_IO, // DSR:PROPOSED: Better error checking.
+ "[RAMDirectory::open] The requested file does not exist.");
+ }
+ return _CLNEW RAMIndexInput(file);
+}
+
+void RAMDirectory::close()
+{
+ SCOPED_LOCK_MUTEX(files_mutex);
+ files.clear();
+}
+
+bool RAMDirectory::doDeleteFile(const QString& name)
+{
+ SCOPED_LOCK_MUTEX(files_mutex);
+ files.remove(name);
+ return true;
+}
+
+void RAMDirectory::renameFile(const QString& from, const QString& to)
+{
+ SCOPED_LOCK_MUTEX(files_mutex);
+ FileMap::iterator itr = files.find(from);
+
+ /* DSR:CL_BUG_LEAK:
+ ** If a file named $to already existed, its old value was leaked.
+ ** My inclination would be to prevent this implicit deletion with an
+ ** exception, but it happens routinely in CLucene's internals (e.g., during
+ ** IndexWriter.addIndexes with the file named 'segments'). */
+ if (files.exists(to))
+ files.remove(to);
+
+ if (itr == files.end()) {
+ char tmp[1024];
+ _snprintf(tmp, 1024, "cannot rename %s, file does not exist",
+ from.toLocal8Bit().constData());
+ _CLTHROWT(CL_ERR_IO, tmp);
+ }
+
+ CND_PRECONDITION(itr != files.end(), "itr == files.end()")
+
+ RAMFile* file = itr->second;
+ files.removeitr(itr, true, true);
+ files.put(to, file);
+}
+
+
+void RAMDirectory::touchFile(const QString& name)
+{
+ RAMFile* file = NULL;
+ {
+ SCOPED_LOCK_MUTEX(files_mutex);
+ file = files.get(name);
+ }
+ uint64_t ts1 = file->lastModified;
+ uint64_t ts2 = Misc::currentTimeMillis();
+
+ //make sure that the time has actually changed
+ while (ts1 == ts2) {
+ _LUCENE_SLEEP(1);
+ ts2 = Misc::currentTimeMillis();
+ };
+
+ file->lastModified = ts2;
+}
+
+IndexOutput* RAMDirectory::createOutput(const QString& name)
+{
+ /* Check the $files VoidMap to see if there was a previous file named
+ ** $name. If so, delete the old RAMFile object, but reuse the existing
+ ** char buffer ($n) that holds the filename. If not, duplicate the
+ ** supplied filename buffer ($name) and pass ownership of that memory ($n)
+ ** to $files. */
+
+ SCOPED_LOCK_MUTEX(files_mutex);
+
+ QString n = files.getKey(name);
+ if (!n.isEmpty()) {
+ RAMFile* rf = files.get(name);
+ _CLDELETE(rf);
+ } else {
+ n = name;
+ }
+
+ RAMFile* file = _CLNEW RAMFile();
+#ifdef _DEBUG
+ file->filename = n;
+#endif
+ files[n] = file;
+
+ return _CLNEW RAMIndexOutput(file);
+}
+
+LuceneLock* RAMDirectory::makeLock(const QString& name)
+{
+ return _CLNEW RAMLock(name, this);
+}
+
+QString RAMDirectory::toString() const
+{
+ return QLatin1String("RAMDirectory");
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/store/RAMDirectory.h b/3rdparty/clucene/src/CLucene/store/RAMDirectory.h
new file mode 100644
index 000000000..af92e30b2
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/RAMDirectory.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*/
+#ifndef _lucene_store_RAMDirectory_
+#define _lucene_store_RAMDirectory_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include "Lock.h"
+#include "Directory.h"
+#include "CLucene/util/VoidMap.h"
+#include "CLucene/util/Arrays.h"
+
+CL_NS_DEF(store)
+
+class RAMFile : LUCENE_BASE
+{
+public:
+ CL_NS(util)::CLVector<uint8_t*, CL_NS(util)::Deletor::Array<uint8_t> > buffers;
+ int64_t length;
+ uint64_t lastModified;
+
+#ifdef _DEBUG
+ QString filename;
+#endif
+
+ RAMFile();
+ ~RAMFile();
+};
+
+class RAMIndexOutput : public BufferedIndexOutput
+{
+protected:
+ RAMFile* file;
+ int32_t pointer;
+ bool deleteFile;
+
+ // output methods:
+ void flushBuffer(const uint8_t* src, const int32_t len);
+
+public:
+ RAMIndexOutput(RAMFile* f);
+ RAMIndexOutput();
+ /** Construct an empty output buffer. */
+ virtual ~RAMIndexOutput();
+
+ virtual void close();
+
+ // Random-at methods
+ virtual void seek(const int64_t pos);
+ int64_t length();
+ /** Resets this to an empty buffer. */
+ void reset();
+ /** Copy the current contents of this buffer to the named output. */
+ void writeTo(IndexOutput* output);
+};
+
+class RAMIndexInput : public BufferedIndexInput
+{
+private:
+ RAMFile* file;
+ int32_t pointer;
+ int64_t _length;
+
+protected:
+ /** IndexInput methods */
+ RAMIndexInput(const RAMIndexInput& clone);
+ void readInternal(uint8_t *dest, const int32_t len);
+
+ /** Random-at methods */
+ void seekInternal(const int64_t pos);
+
+public:
+ RAMIndexInput(RAMFile* f);
+ ~RAMIndexInput();
+ IndexInput* clone() const;
+
+ void close();
+ int64_t length();
+ QString getDirectoryType() const;
+};
+
+
+/**
+* A memory-resident {@link Directory} implementation.
+*/
+class RAMDirectory : public Directory
+{
+ class RAMLock : public LuceneLock
+ {
+ private:
+ RAMDirectory* directory;
+ QString fname;
+ public:
+ RAMLock(const QString& name, RAMDirectory* dir);
+ virtual ~RAMLock();
+ bool obtain();
+ void release();
+ bool isLocked();
+ virtual QString toString() const;
+ };
+
+ typedef CL_NS(util)::CLHashMap<QString, RAMFile*,
+ CL_NS(util)::Compare::Qstring, CL_NS(util)::Equals::Qstring,
+ CL_NS(util)::Deletor::DummyQString,
+ CL_NS(util)::Deletor::Object<RAMFile> > FileMap;
+
+protected:
+ /// Removes an existing file in the directory.
+ virtual bool doDeleteFile(const QString& name);
+
+ /**
+ * Creates a new <code>RAMDirectory</code> instance from a different
+ * <code>Directory</code> implementation. This can be used to load
+ * a disk-based index into memory.
+ * <P>
+ * This should be used only with indices that can fit into memory.
+ *
+ * @param dir a <code>Directory</code> value
+ * @exception IOException if an error occurs
+ */
+ void _copyFromDir(Directory* dir, bool closeDir);
+ FileMap files; // unlike the java Hashtable, FileMap is not synchronized, and all access must be protected by a lock
+
+public:
+#ifndef _CL_DISABLE_MULTITHREADING //do this so that the mutable keyword still works without mt enabled
+ mutable DEFINE_MUTEX(files_mutex) // mutable: const methods must also be able to synchronize properly
+#endif
+
+ // Returns a null terminated array of strings, one for each file in the directory.
+ QStringList list() const;
+
+ /** Constructs an empty {@link Directory}. */
+ RAMDirectory();
+
+ // Destructor - only call this if you are sure the directory
+ // is not being used anymore. Otherwise use the ref-counting
+ // facilities of dir->close
+ virtual ~RAMDirectory();
+ RAMDirectory(Directory* dir);
+
+ /**
+ * Creates a new <code>RAMDirectory</code> instance from the {@link FSDirectory}.
+ *
+ * @param dir a <code>String</code> specifying the full index directory path
+ */
+ RAMDirectory(const QString& dir);
+
+ /// Returns true iff the named file exists in this directory.
+ bool fileExists(const QString& name) const;
+
+ /// Returns the time the named file was last modified.
+ int64_t fileModified(const QString& name) const;
+
+ /// Returns the length in bytes of a file in the directory.
+ int64_t fileLength(const QString& name) const;
+
+ /// Removes an existing file in the directory.
+ virtual void renameFile(const QString& from, const QString& to);
+
+ /** Set the modified time of an existing file to now. */
+ void touchFile(const QString& name);
+
+ /// Creates a new, empty file in the directory with the given name.
+ /// Returns a stream writing this file.
+ virtual IndexOutput* createOutput(const QString& name);
+
+ /// Construct a {@link Lock}.
+ /// @param name the name of the lock file
+ LuceneLock* makeLock(const QString& name);
+
+ /// Returns a stream reading an existing file.
+ IndexInput* openInput(const QString& name);
+
+ virtual void close();
+
+ QString toString() const;
+
+ static QString DirectoryType() { return QLatin1String("RAM"); }
+ QString getDirectoryType() const { return DirectoryType(); }
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/store/TransactionalRAMDirectory.cpp b/3rdparty/clucene/src/CLucene/store/TransactionalRAMDirectory.cpp
new file mode 100644
index 000000000..056fa9bc3
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/TransactionalRAMDirectory.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "TransactionalRAMDirectory.h"
+
+CL_NS_DEF(store)
+CL_NS_USE(util)
+
+TransactionalRAMDirectory::TransactionalRAMDirectory()
+ : RAMDirectory()
+ , filesToRestoreOnAbort(false, true)
+{
+ transOpen = false;
+}
+
+TransactionalRAMDirectory::~TransactionalRAMDirectory()
+{
+}
+
+bool TransactionalRAMDirectory::archiveOrigFileIfNecessary(const QString& name)
+{
+ // If a file named $name was present when the transaction started and the
+ // original RAMFile object has not been archived for restoration upon
+ // transaction abort, then do so, and return true.
+ // In any other case, return false.
+ if (fileExists(name) && filesToRemoveOnAbort.find(name) == filesToRemoveOnAbort.end()) {
+ // The file exists, but isn't recorded as having been created after the
+ // start of the transaction, so it must've been present at the start of
+ // the transaction.
+
+ // Transfer memory ownership of both the key and the value from files to
+ // filesToRestoreOnAbort.
+ QString origName = files.getKey(name);
+ RAMFile* origFile = files.get(name);
+ files.remove(name, true, true);
+ filesToRestoreOnAbort.put(origName, origFile);
+
+ CND_CONDITION(!fileExists(name),
+ "File should not exist immediately after archival.");
+ return true;
+ }
+
+ return false;
+}
+
+void TransactionalRAMDirectory::unarchiveOrigFile(const QString& name)
+{
+ QString origName = filesToRestoreOnAbort.getKey(name);
+ if (origName.isEmpty()) {
+ _CLTHROWA(CL_ERR_RAMTransaction,
+ "File submitted for unarchival was not archived.");
+ }
+ RAMFile* origFile = filesToRestoreOnAbort.get(name);
+ // Transfer memory ownership back to files from filesToRestoreOnAbort.
+ filesToRestoreOnAbort.remove(name, true, true);
+ files.put(origName, origFile);
+}
+
+bool TransactionalRAMDirectory::transIsOpen() const
+{
+ return transOpen;
+}
+
+void TransactionalRAMDirectory::transStart()
+{
+ if (transOpen) {
+ _CLTHROWA(CL_ERR_RAMTransaction,
+ "Must resolve previous transaction before starting another.");
+ }
+
+ CND_CONDITION(filesToRemoveOnAbort.size() == 0,
+ "filesToRemoveOnAbort should have been cleared by either its"
+ " constructor or transResolved.");
+
+ CND_CONDITION(filesToRestoreOnAbort.size() == 0,
+ "filesToRestoreOnAbort should have been cleared by either its"
+ " constructor or transResolved.");
+
+ transOpen = true;
+}
+
+void TransactionalRAMDirectory::transResolved()
+{
+ // This method implements actions common to both forms of transaction
+ // resolution.
+ filesToRemoveOnAbort.clear();
+ filesToRestoreOnAbort.clear();
+ transOpen = false;
+}
+
+void TransactionalRAMDirectory::transCommit()
+{
+ if (!transOpen)
+ _CLTHROWA(CL_ERR_RAMTransaction, "There is no open transaction.");
+
+ // All storage is in memory, so commit is ultra-simple.
+ transResolved();
+}
+
+void TransactionalRAMDirectory::transAbort()
+{
+ if (!transOpen)
+ _CLTHROWA(CL_ERR_RAMTransaction, "There is no open transaction.");
+
+ // Delete each file in filesToRemoveOnAbort.
+ FilenameSet::const_iterator itrDel = filesToRemoveOnAbort.begin();
+ for ( ; itrDel != filesToRemoveOnAbort.end(); ++itrDel) {
+ size_t nameLength = itrDel->first.length();
+
+ // Special exception: Refrain from deleting a lock's flag file, as that
+ // would interfere with the operation of the lock.
+ if (!(nameLength >= 5
+ && itrDel->first.rightRef(5) == QLatin1String(".lock"))) {
+ RAMDirectory::deleteFile(itrDel->first);
+ }
+ }
+ // Ownership of the memory of both the key and the value never left files,
+ // so there's no need for a special directive to filesToRemoveOnAbort.
+ filesToRemoveOnAbort.clear();
+
+ // Now that any new-since-trans-start files with the same names as
+ // already-present-at-trans-start files are out of the way, restore each
+ // file in filesToRestoreOnAbort.
+ TransFileMap::const_iterator itr = filesToRestoreOnAbort.begin();
+ for ( ; itr != filesToRestoreOnAbort.end(); ++itr) {
+ files.put(itr->first, itr->second);
+ filesToRestoreOnAbort.remove(itr->first);
+ }
+
+ CND_CONDITION(filesToRestoreOnAbort.size() == 0,
+ "filesToRestoreOnAbort should be empty.");
+
+ transResolved();
+}
+
+bool TransactionalRAMDirectory::doDeleteFile(const QString& name)
+{
+ if (!transOpen)
+ return RAMDirectory::doDeleteFile(name);
+
+ bool wasOriginalAndWasArchived = archiveOrigFileIfNecessary(name);
+ if (!wasOriginalAndWasArchived) {
+ // The file to be deleted wasn't present at transaction start, so instead
+ // of archiving it, we delete it the conventional way, making sure to
+ // erase its record in filesToRemoveOnAbort if it was listed there.
+ filesToRemoveOnAbort.remove(name);
+ return RAMDirectory::doDeleteFile(name);
+ }
+ return true;
+}
+
+void TransactionalRAMDirectory::renameFile(const QString& from, const QString& to)
+{
+ // During the review on 2005.03.18, decided not to implement transactional
+ // renameFile for two reasons:
+ // a) It's not needed in the limited scenario for which
+ // TransactionalRAMDirectory was designed (IndexWriter::addDocument and
+ // subcode).
+ // b) Supporting renaming during a transaction would add considerable
+ // bookkeeping overhead, reducing the performance of the overwhelmingly
+ // typical case (commit) in order to support the rare case (abort).
+ //
+ // This was not a thinly disguised punt due to the complication of
+ // implementing renameFile transactionally; rather, several implementations
+ // were considered, but it seemed wrongheaded to degrade the performance of
+ // the typical case based on the mere potential need to support renameFile
+ // at some future point for the benefit of the atypical case.
+ if (transOpen) {
+ _CLTHROWA(CL_ERR_RAMTransaction,
+ "TransactionalRAMDirectory disallows renameFile during a transaction.");
+ }
+ RAMDirectory::renameFile(from, to);
+}
+
+IndexOutput* TransactionalRAMDirectory::createOutput(const QString& name)
+{
+ if (!transOpen)
+ return RAMDirectory::createOutput(name);
+
+ bool wasOriginalAndWasArchived = archiveOrigFileIfNecessary(name);
+ try {
+ IndexOutput* ret = RAMDirectory::createOutput(name);
+ // Importantly, we store a pointer to the filename memory managed by
+ // files, rather than that passed in by the client (name). We don't make
+ // an additional copy of the filename's memory because the transactional
+ // metadata container filesToRemoveOnAbort is not at risk of outliving
+ // files.
+ filesToRemoveOnAbort.put(files.getKey(name), NULL);
+ return ret;
+ } catch (...) {
+ if (wasOriginalAndWasArchived) {
+ unarchiveOrigFile(name);
+ }
+ throw;
+ }
+}
+
+void TransactionalRAMDirectory::close()
+{
+ if (transOpen)
+ transAbort();
+
+ RAMDirectory::close();
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/store/TransactionalRAMDirectory.h b/3rdparty/clucene/src/CLucene/store/TransactionalRAMDirectory.h
new file mode 100644
index 000000000..44c5e8e99
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/store/TransactionalRAMDirectory.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_store_TransactionalRAMDirectory_
+#define _lucene_store_TransactionalRAMDirectory_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "RAMDirectory.h"
+#include "CLucene/util/VoidList.h"
+
+CL_NS_DEF(store)
+
+/***
+This transactional in-memory Directory was created to address a specific
+situation, and was deliberately pared down to the simplest viable
+implementation. For the sake of simplicity, this implementation imposes
+restrictions on what operations can be performed in the directory while a
+transaction is in progress (documented in TransactionalRAMDirectory.cpp).
+
+Because the Lucene Directory interface itself is rather simplistic, it
+would not be difficult to expand TransactionalRAMDirectory so that it
+provided fully general transactionality. However, the developer of this
+original implementation was of the opinion that the last thing CLucene
+needs is gratuitous features that exceed their required complexity and
+haven't been rigorously tested.
+*/
+class TransactionalRAMDirectory : public RAMDirectory
+{
+private:
+ typedef CL_NS(util)::CLSet<QString, void*, CL_NS(util)::Compare::Qstring,
+ CL_NS(util)::Deletor::DummyQString> FilenameSet;
+ FilenameSet filesToRemoveOnAbort;
+
+ typedef CL_NS(util)::CLSet<QString, RAMFile*, CL_NS(util)::Compare::Qstring,
+ CL_NS(util)::Deletor::DummyQString,
+ CL_NS(util)::Deletor::Object<RAMFile> > TransFileMap;
+ TransFileMap filesToRestoreOnAbort;
+
+ bool transOpen;
+
+ void transResolved();
+ bool archiveOrigFileIfNecessary(const QString& name);
+ void unarchiveOrigFile(const QString& name);
+
+protected:
+ bool doDeleteFile(const QString& name);
+
+public:
+ TransactionalRAMDirectory();
+ virtual ~TransactionalRAMDirectory();
+
+ bool transIsOpen() const;
+ void transStart();
+ void transCommit();
+ void transAbort();
+
+ // Constrained operations:
+ void renameFile(const QString& from, const QString& to);
+ IndexOutput* createOutput(const QString& name);
+
+ void close();
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/Arrays.h b/3rdparty/clucene/src/CLucene/util/Arrays.h
new file mode 100644
index 000000000..ba60c5638
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/Arrays.h
@@ -0,0 +1,164 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_Arrays_
+#define _lucene_util_Arrays_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "VoidList.h"
+
+CL_NS_DEF(util)
+ class Arrays{
+ public:
+ template<typename _type>
+ class _Arrays {
+ protected:
+ //used by binarySearch to check for equality
+ virtual bool equals(_type a,_type b) const = 0;
+ virtual int32_t compare(_type a,_type b) const = 0;
+ public:
+ virtual ~_Arrays(){
+ }
+
+ void sort(_type* a, int32_t alen, int32_t fromIndex, int32_t toIndex) const{
+ CND_PRECONDITION(fromIndex < toIndex,"fromIndex >= toIndex");
+ CND_PRECONDITION(fromIndex >= 0,"fromIndex < 0");
+
+ // First presort the array in chunks of length 6 with insertion
+ // sort. A mergesort would give too much overhead for this length.
+ for (int32_t chunk = fromIndex; chunk < toIndex; chunk += 6)
+ {
+ int32_t end = min(chunk + 6, toIndex);
+ for (int32_t i = chunk + 1; i < end; i++)
+ {
+ if (compare(a[i - 1], a[i]) > 0)
+ {
+ // not already sorted
+ int32_t j = i;
+ _type elem = a[j];
+ do
+ {
+ a[j] = a[j - 1];
+ j--;
+ }
+ while (j > chunk && compare(a[j - 1], elem) > 0);
+ a[j] = elem;
+ }
+ }
+ }
+
+ int32_t len = toIndex - fromIndex;
+ // If length is smaller or equal 6 we are done.
+ if (len <= 6)
+ return;
+
+ _type* src = a;
+ _type* dest = _CL_NEWARRAY(_type,alen);
+ _type* t = NULL; // t is used for swapping src and dest
+
+ // The difference of the fromIndex of the src and dest array.
+ int32_t srcDestDiff = -fromIndex;
+
+ // The merges are done in this loop
+ for (int32_t size = 6; size < len; size <<= 1)
+ {
+ for (int32_t start = fromIndex; start < toIndex; start += size << 1)
+ {
+ // mid is the start of the second sublist;
+ // end the start of the next sublist (or end of array).
+ int32_t mid = start + size;
+ int32_t end = min(toIndex, mid + size);
+
+ // The second list is empty or the elements are already in
+ // order - no need to merge
+ if (mid >= end || compare(src[mid - 1], src[mid]) <= 0)
+ {
+ memcpy(dest + start + srcDestDiff, src+start, (end-start)*sizeof(_type));
+ }// The two halves just need swapping - no need to merge
+ else if (compare(src[start], src[end - 1]) > 0)
+ {
+ memcpy(dest+end-size+srcDestDiff, src+start, size * sizeof(_type));
+ memcpy(dest+start+srcDestDiff, src+mid, (end-mid) * sizeof(_type));
+
+ }else{
+ // Declare a lot of variables to save repeating
+ // calculations. Hopefully a decent JIT will put these
+ // in registers and make this fast
+ int32_t p1 = start;
+ int32_t p2 = mid;
+ int32_t i = start + srcDestDiff;
+
+ // The main merge loop; terminates as soon as either
+ // half is ended
+ while (p1 < mid && p2 < end)
+ {
+ dest[i++] = src[(compare(src[p1], src[p2]) <= 0
+ ? p1++ : p2++)];
+ }
+
+ // Finish up by copying the remainder of whichever half
+ // wasn't finished.
+ if (p1 < mid)
+ memcpy(dest+i,src+p1, (mid-p1) * sizeof(_type));
+ else
+ memcpy(dest+i,src+p2, (end-p2) * sizeof(_type));
+ }
+ }
+ // swap src and dest ready for the next merge
+ t = src;
+ src = dest;
+ dest = t;
+ fromIndex += srcDestDiff;
+ toIndex += srcDestDiff;
+ srcDestDiff = -srcDestDiff;
+ }
+
+ // make sure the result ends up back in the right place. Note
+ // that src and dest may have been swapped above, so src
+ // contains the sorted array.
+ if (src != a)
+ {
+ // Note that fromIndex == 0.
+ memcpy(a+srcDestDiff,src,toIndex * sizeof(_type));
+ }
+ }
+ };
+ };
+
+ template <typename _kt, typename _comparator,
+ typename class1, typename class2>
+ class CLListEquals:
+ public CL_NS_STD(binary_function)<class1*,class2*,bool>
+ {
+ typedef typename class1::const_iterator _itr1;
+ typedef typename class2::const_iterator _itr2;
+ public:
+ CLListEquals(){
+ }
+ bool equals( class1* val1, class2* val2 ) const{
+ static _comparator comp;
+ if ( val1 == val2 )
+ return true;
+ size_t size = val1->size();
+ if ( size != val2->size() )
+ return false;
+
+ _itr1 itr1 = val1->begin();
+ _itr2 itr2 = val2->begin();
+ while ( --size >= 0 ){
+ if ( !comp(*itr1,*itr2) )
+ return false;
+ itr1++;
+ itr2++;
+ }
+ return true;
+ }
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/BitSet.cpp b/3rdparty/clucene/src/CLucene/util/BitSet.cpp
new file mode 100644
index 000000000..3679bd120
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/BitSet.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "BitSet.h"
+#include "CLucene/store/Directory.h"
+
+CL_NS_USE(store)
+CL_NS_DEF(util)
+
+BitSet::BitSet(const BitSet& copy)
+ : _size(copy._size)
+ , _count(-1)
+{
+ int32_t len = (_size >> 3) + 1;
+ bits = _CL_NEWARRAY(uint8_t, len);
+ memcpy(bits, copy.bits, len);
+}
+
+BitSet::BitSet(int32_t size)
+ : _size(size)
+ , _count(-1)
+{
+ int32_t len = (_size >> 3) + 1;
+ bits = _CL_NEWARRAY(uint8_t, len);
+ memset(bits, 0, len);
+}
+
+BitSet::BitSet(CL_NS(store)::Directory* d, const QString& name)
+{
+ _count = -1;
+ CL_NS(store)::IndexInput* input = d->openInput(name);
+ try {
+ _size = input->readInt(); // read size
+ _count = input->readInt(); // read count
+
+ bits = _CL_NEWARRAY(uint8_t,(_size >> 3) + 1); // allocate bits
+ input->readBytes(bits, (_size >> 3) + 1); // read bits
+ } _CLFINALLY (
+ input->close();
+ _CLDELETE(input );
+ );
+}
+
+void BitSet::write(CL_NS(store)::Directory* d, const QString& name)
+{
+ CL_NS(store)::IndexOutput* output = d->createOutput(name);
+ try {
+ output->writeInt(size()); // write size
+ output->writeInt(count()); // write count
+ output->writeBytes(bits, (_size >> 3) + 1); // write bits
+ } _CLFINALLY (
+ output->close();
+ _CLDELETE(output);
+ );
+}
+
+BitSet::~BitSet()
+{
+ _CLDELETE_ARRAY(bits);
+}
+
+void BitSet::set(int32_t bit, bool val)
+{
+ if (val)
+ bits[bit >> 3] |= 1 << (bit & 7);
+ else
+ bits[bit >> 3] &= ~(1 << (bit & 7));
+
+ _count = -1;
+}
+
+int32_t BitSet::size() const
+{
+ return _size;
+}
+
+int32_t BitSet::count()
+{
+ // if the BitSet has been modified
+ if (_count == -1) {
+ static const uint8_t BYTE_COUNTS[] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
+
+ int32_t c = 0;
+ int32_t end = (_size >> 3) + 1;
+ for (int32_t i = 0; i < end; i++)
+ c += BYTE_COUNTS[bits[i]]; // sum bits per uint8_t
+ _count = c;
+ }
+ return _count;
+}
+
+BitSet* BitSet::clone() const
+{
+ return _CLNEW BitSet(*this);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/util/BitSet.h b/3rdparty/clucene/src/CLucene/util/BitSet.h
new file mode 100644
index 000000000..e93847e98
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/BitSet.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_util_BitSet_
+#define _lucene_util_BitSet_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+#include "CLucene/store/Directory.h"
+
+CL_NS_DEF(util)
+
+class BitSet : LUCENE_BASE
+{
+public:
+ // Create a bitset with the specified size
+ BitSet (int32_t size);
+ BitSet(CL_NS(store)::Directory* d, const QString& name);
+ void write(CL_NS(store)::Directory* d, const QString& name);
+
+ // Destructor for the bit set
+ ~BitSet();
+
+ // get the value of the specified bit
+ inline bool get(const int32_t bit) const
+ {
+ return (bits[bit >> 3] & (1 << (bit & 7))) != 0;
+ }
+
+ // set the value of the specified bit
+ void set(int32_t bit, bool val = true);
+
+ ///returns the size of the bitset
+ int32_t size() const;
+
+ // Returns the total number of one bits in this BitSet. This is
+ // efficiently computed and cached, so that, if the BitSet is not changed,
+ // no recomputation is done for repeated calls.
+ int32_t count();
+ BitSet *clone() const;
+
+protected:
+ BitSet(const BitSet& copy);
+
+private:
+ int32_t _size;
+ int32_t _count;
+ uint8_t *bits;
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/Equators.cpp b/3rdparty/clucene/src/CLucene/util/Equators.cpp
new file mode 100644
index 000000000..e112bd234
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/Equators.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "Equators.h"
+
+CL_NS_DEF(util)
+
+bool Equals::Int32::operator()(const int32_t val1, const int32_t val2) const
+{
+ return (val1)==(val2);
+}
+
+bool Equals::Char::operator()(const char* val1, const char* val2) const
+{
+ if ( val1 == val2 )
+ return true;
+ return (strcmp(val1, val2) == 0);
+}
+
+#ifdef _UCS2
+bool Equals::WChar::operator()(const wchar_t* val1, const wchar_t* val2) const
+{
+ if (val1 == val2)
+ return true;
+ return (_tcscmp(val1, val2) == 0);
+}
+#endif
+
+bool Equals::Qstring::operator()(const QString& val1, const QString& val2) const
+{
+ return (val1 == val2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Comparors
+///////////////////////////////////////////////////////////////////////////////
+
+int32_t Compare::Int32::getValue() const
+{
+ return value;
+}
+
+Compare::Int32::Int32(int32_t val)
+{
+ value = val;
+}
+
+Compare::Int32::Int32()
+{
+ value = 0;
+}
+
+int32_t Compare::Int32::compareTo(void* o)
+{
+ try {
+ Int32* other = (Int32*)o;
+ if (value == other->value)
+ return 0;
+ // Returns just -1 or 1 on inequality; doing math might overflow.
+ return value > other->value ? 1 : -1;
+ } catch(...) {
+ _CLTHROWA(CL_ERR_Runtime, "Couldnt compare types");
+ }
+}
+
+bool Compare::Int32::operator()(int32_t t1, int32_t t2) const
+{
+ return t1 > t2 ? true : false;
+}
+
+size_t Compare::Int32::operator()(int32_t t) const
+{
+ return t;
+}
+
+qreal Compare::Float::getValue() const
+{
+ return value;
+}
+
+Compare::Float::Float(qreal val)
+{
+ value = val;
+}
+
+int32_t Compare::Float::compareTo(void* o)
+{
+ try {
+ Float* other = (Float*)o;
+ if (value == other->value)
+ return 0;
+ // Returns just -1 or 1 on inequality; doing math might overflow.
+ return value > other->value ? 1 : -1;
+ } catch(...) {
+ _CLTHROWA(CL_ERR_Runtime,"Couldnt compare types");
+ }
+}
+
+bool Compare::Char::operator()(const char* val1, const char* val2) const
+{
+ if ( val1 == val2)
+ return false;
+ return (strcmp(val1, val2) < 0);
+}
+
+size_t Compare::Char::operator()(const char* val1) const
+{
+ return CL_NS(util)::Misc::ahashCode(val1);
+}
+
+#ifdef _UCS2
+bool Compare::WChar::operator()(const wchar_t* val1, const wchar_t* val2) const
+{
+ if ( val1==val2)
+ return false;
+ return (_tcscmp(val1, val2) < 0);
+}
+
+size_t Compare::WChar::operator()(const wchar_t* val1) const
+{
+ return CL_NS(util)::Misc::whashCode(val1);
+}
+#endif
+
+const TCHAR* Compare::TChar::getValue() const
+{
+ return s;
+}
+
+Compare::TChar::TChar()
+{
+ s = NULL;
+}
+
+Compare::TChar::TChar(const TCHAR* str)
+{
+ this->s = str;
+}
+
+int32_t Compare::TChar::compareTo(void* o)
+{
+ try {
+ TChar* os = (TChar*)o;
+ return _tcscmp(s, os->s);
+ } catch(...) {
+ _CLTHROWA(CL_ERR_Runtime,"Couldnt compare types");
+ }
+
+}
+
+bool Compare::TChar::operator()(const TCHAR* val1, const TCHAR* val2) const
+{
+ if (val1 == val2)
+ return false;
+
+ return (_tcscmp(val1, val2) < 0);
+}
+
+size_t Compare::TChar::operator()(const TCHAR* val1) const
+{
+ return CL_NS(util)::Misc::thashCode(val1);
+}
+
+bool Compare::Qstring::operator()(const QString& val1, const QString& val2) const
+{
+ return (val1 < val2);
+}
+
+size_t Compare::Qstring::operator ()(const QString& val1) const
+{
+ return CL_NS(util)::Misc::qhashCode(val1);
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/util/Equators.h b/3rdparty/clucene/src/CLucene/util/Equators.h
new file mode 100644
index 000000000..11fcb0eaf
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/Equators.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_util_Equators_
+#define _lucene_util_Equators_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+//#ifdef QT_LINUXBASE
+// we are going to use qreal now, we basically maintain our own clucene anyway
+//// LSB doesn't define float_t - see http://bugs.linuxbase.org/show_bug.cgi?id=2374
+//typedef float float_t;
+//#endif
+
+CL_NS_DEF(util)
+
+///////////////////////////////////////////////////////////////////////////////
+// Equators
+///////////////////////////////////////////////////////////////////////////////
+
+class Equals{
+public:
+ class Int32:public CL_NS_STD(binary_function)<const int32_t*,const int32_t*,bool>
+ {
+ public:
+ bool operator()( const int32_t val1, const int32_t val2 ) const;
+ };
+
+ class Char:public CL_NS_STD(binary_function)<const char*,const char*,bool>
+ {
+ public:
+ bool operator()( const char* val1, const char* val2 ) const;
+ };
+#ifdef _UCS2
+ class WChar: public CL_NS_STD(binary_function)<const wchar_t*,const wchar_t*,bool>
+ {
+ public:
+ bool operator()( const wchar_t* val1, const wchar_t* val2 ) const;
+ };
+ class TChar: public WChar{
+ };
+#else
+ class TChar: public Char{
+ };
+#endif
+
+ template<typename _cl>
+ class Void:public CL_NS_STD(binary_function)<const void*,const void*,bool>
+ {
+ public:
+ bool operator()( _cl* val1, _cl* val2 ) const{
+ return val1==val2;
+ }
+ };
+
+ class Qstring : public CL_NS_STD(binary_function)<const QString&, const QString&, bool>
+ {
+ public:
+ bool operator() (const QString& val1, const QString& val2) const;
+ };
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Comparors
+///////////////////////////////////////////////////////////////////////////////
+
+class Comparable : LUCENE_BASE
+{
+public:
+ virtual ~Comparable(){
+ }
+
+ virtual int32_t compareTo(void* o) = 0;
+};
+
+/** @internal */
+class Compare{
+public:
+ class _base
+ { // traits class for hash containers
+ public:
+ enum
+ { // parameters for hash table
+ bucket_size = 4, // 0 < bucket_size
+ min_buckets = 8
+ }; // min_buckets = 2 ^^ N, 0 < N
+
+ _base()
+ {
+ }
+ };
+
+ class Int32:public _base, public Comparable{
+ int32_t value;
+ public:
+ int32_t getValue() const;
+ Int32(int32_t val);
+ Int32();
+ int32_t compareTo(void* o);
+ bool operator()( int32_t t1, int32_t t2 ) const;
+ size_t operator()( int32_t t ) const;
+ };
+
+
+ class Float:public Comparable{
+ qreal value;
+ public:
+ qreal getValue() const;
+ Float(qreal val);
+ int32_t compareTo(void* o);
+ };
+
+
+ class Char: public _base //<char*>
+ {
+ public:
+ bool operator()( const char* val1, const char* val2 ) const;
+ size_t operator()( const char* val1) const;
+ };
+
+#ifdef _UCS2
+ class WChar: public _base //<wchar_t*>
+ {
+ public:
+ bool operator()( const wchar_t* val1, const wchar_t* val2 ) const;
+ size_t operator()( const wchar_t* val1) const;
+ };
+#endif
+
+ class TChar: public _base, public Comparable{
+ const TCHAR* s;
+ public:
+ const TCHAR* getValue() const;
+
+ TChar();
+ TChar(const TCHAR* str);
+ int32_t compareTo(void* o);
+ bool operator()( const TCHAR* val1, const TCHAR* val2 ) const;
+ size_t operator()( const TCHAR* val1) const;
+ };
+
+
+ template<typename _cl>
+ class Void:public _base //<const void*,const void*,bool>
+ {
+ public:
+ int32_t compareTo(_cl* o){
+ if ( this == o )
+ return o;
+ else
+ return this > o ? 1 : -1;
+ }
+ bool operator()( _cl* t1, _cl* t2 ) const{
+ return t1 > t2 ? true : false;
+ }
+ size_t operator()( _cl* t ) const{
+ return (size_t)t;
+ }
+ };
+
+ class Qstring : public _base
+ {
+ public:
+ bool operator() (const QString& val1, const QString& val2) const;
+ size_t operator() (const QString& val1) const;
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// allocators
+///////////////////////////////////////////////////////////////////////////////
+
+class Deletor
+{
+public:
+
+ template<typename _kt>
+ class Array{
+ public:
+ static void doDelete(_kt* arr){
+ _CLDELETE_LARRAY(arr);
+ }
+ };
+ class tcArray{
+ public:
+ static void doDelete(const TCHAR* arr){
+ _CLDELETE_CARRAY(arr);
+ }
+ };
+ class acArray{
+ public:
+ static void doDelete(const char* arr){
+ _CLDELETE_CaARRAY(arr);
+ }
+ };
+
+ class Unintern{
+ public:
+ static void doDelete(TCHAR* arr);
+ };
+ template<typename _kt>
+ class Object{
+ public:
+ static void doDelete(_kt* obj){
+ _CLLDELETE(obj);
+ }
+ };
+ template<typename _kt>
+ class Void{
+ public:
+ static void doDelete(_kt* obj){
+ _CLVDELETE(obj);
+ }
+ };
+ class Dummy{
+ public:
+ static void doDelete(const void* nothing)
+ {
+ // TODO: remove all occurances where it hits this point
+ // CND_WARNING(false, "Deletor::Dummy::doDelete run, set deleteKey
+ // or deleteValue to false");
+ }
+ };
+ class DummyInt32{
+ public:
+ static void doDelete(const int32_t nothing){
+ }
+ };
+ class DummyFloat{
+ public:
+ static void doDelete(const qreal nothing){
+ }
+ };
+ template <typename _type>
+ class ConstNullVal{
+ public:
+ static void doDelete(const _type nothing)
+ {
+ // TODO: remove all occurances where it hits this point
+ // CND_WARNING(false, "Deletor::Dummy::doDelete run, set deleteKey
+ // or deleteValue to false");
+ }
+ };
+
+ template <typename _type>
+ class NullVal{
+ public:
+ static void doDelete(_type nothing)
+ {
+ // TODO: remove all occurances where it hits this point
+ // CND_WARNING(false, "Deletor::Dummy::doDelete run, set deleteKey
+ // or deleteValue to false");
+ }
+ };
+ class DummyQString {
+ public:
+ static void doDelete(const QString& nothing) {
+ }
+ };
+};
+////////////////////////////////////////////////////////////////////////////////
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/FastCharStream.cpp b/3rdparty/clucene/src/CLucene/util/FastCharStream.cpp
new file mode 100644
index 000000000..f9fbe9b10
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/FastCharStream.cpp
@@ -0,0 +1,107 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "FastCharStream.h"
+
+#include "CLucene/util/Reader.h"
+
+CL_NS_DEF(util)
+
+const int32_t FastCharStream::maxRewindSize = LUCENE_MAX_WORD_LEN*2;
+
+ FastCharStream::FastCharStream(Reader* reader):
+ pos(0),
+ rewindPos(0),
+ resetPos(0),
+ col(1),
+ line(1),
+ input(reader)
+ {
+ input->mark(maxRewindSize);
+ }
+ FastCharStream::~FastCharStream(){
+ }
+ void FastCharStream::readChar(TCHAR &c) {
+ try{
+ int32_t r = input->read();
+ if ( r == -1 )
+ input = NULL;
+ c = r;
+ }catch(CLuceneError& err){
+ if ( err.number() == CL_ERR_IO )
+ input = 0;
+ throw err;
+ }
+ }
+ int FastCharStream::GetNext()
+ {
+ // printf("getnext\n");
+ if (input == 0 ) // end of file
+ {
+ _CLTHROWA(CL_ERR_IO,"warning : FileReader.GetNext : Read TCHAR over EOS.");
+ }
+ // this is rather inefficient
+ // implementing the functions from the java version of
+ // charstream will be much more efficient.
+ ++pos;
+ if ( pos > resetPos + maxRewindSize && rewindPos == 0) {
+ // move the marker one position (~expensive)
+ resetPos = pos-(maxRewindSize/2);
+ if ( resetPos != input->reset(resetPos) )
+ _CLTHROWA(CL_ERR_IO,"Unexpected reset() result");
+ input->mark(maxRewindSize);
+ input->skip((maxRewindSize/2) - 1);
+ }
+ TCHAR ch;
+ readChar(ch);
+
+ if (input == NULL) { // eof
+ return -1;
+ }
+ if (rewindPos == 0) {
+ col += 1;
+ if(ch == '\n') {
+ line++;
+ col = 1;
+ }
+ } else {
+ rewindPos--;
+ }
+ return ch;
+ }
+
+ void FastCharStream::UnGet(){
+// printf("UnGet \n");
+ if (input == 0)
+ return;
+ if ( pos == 0 ) {
+ _CLTHROWA(CL_ERR_IO,"error : No character can be UnGet");
+ }
+ rewindPos++;
+
+ input->reset(pos-1);
+ pos--;
+ }
+
+ int FastCharStream::Peek() {
+ int c = GetNext();
+ UnGet();
+ return c;
+ }
+
+ bool FastCharStream::Eos() const {
+ return input==NULL;
+ }
+
+ int32_t FastCharStream::Column() const {
+ return col;
+ }
+
+ int32_t FastCharStream::Line() const {
+ return line;
+ }
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/util/FastCharStream.h b/3rdparty/clucene/src/CLucene/util/FastCharStream.h
new file mode 100644
index 000000000..24e5b5612
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/FastCharStream.h
@@ -0,0 +1,55 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_FastCharStream_
+#define _lucene_util_FastCharStream_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/Reader.h"
+
+CL_NS_DEF(util)
+
+ /** Ported implementation of the FastCharStream class. */
+ class FastCharStream:LUCENE_BASE
+ {
+ static const int32_t maxRewindSize;
+ int32_t pos;
+ int32_t rewindPos;
+ int64_t resetPos;
+ int32_t col;
+ int32_t line;
+ // read character from stream return false on error
+ void readChar(TCHAR &);
+ public:
+ Reader* input;
+
+ /// Initializes a new instance of the FastCharStream class LUCENE_EXPORT.
+ FastCharStream(Reader* reader);
+ ~FastCharStream();
+
+ /// Returns the next TCHAR from the stream.
+ int GetNext();
+
+ void UnGet();
+
+ /// Returns the current top TCHAR from the input stream without removing it.
+ int Peek();
+
+
+ /// Returns <b>True</b> if the end of stream was reached.
+ bool Eos() const;
+
+ /// Gets the current column.
+ int32_t Column() const;
+
+ /// Gets the current line.
+ int32_t Line() const;
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/Misc.cpp b/3rdparty/clucene/src/CLucene/util/Misc.cpp
new file mode 100644
index 000000000..42e3fd0a8
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/Misc.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#include "CLucene/StdHeader.h"
+#include "Misc.h"
+
+#ifdef _CL_TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if defined(_CL_HAVE_SYS_TIME_H)
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#ifdef _CL_HAVE_SYS_TIMEB_H
+# include <sys/timeb.h>
+#endif
+
+#ifdef UNDER_CE
+#include <QTime>
+#endif
+
+CL_NS_DEF(util)
+
+uint64_t Misc::currentTimeMillis()
+{
+#ifndef UNDER_CE
+#if defined(_CLCOMPILER_MSVC) || defined(__MINGW32__) || defined(__BORLANDC__)
+ struct _timeb tstruct;
+ _ftime(&tstruct);
+
+ return (((uint64_t) tstruct.time) * 1000) + tstruct.millitm;
+#else
+ struct timeval tstruct;
+ if (gettimeofday(&tstruct, NULL) < 0) {
+ _CLTHROWA(CL_ERR_Runtime,"Error in gettimeofday call.");
+ }
+
+ return (((uint64_t) tstruct.tv_sec) * 1000) + tstruct.tv_usec / 1000;
+#endif
+#else //UNDER_CE
+ QT_USE_NAMESPACE
+ QTime t = QTime::currentTime();
+ return t.second() * 1000 + t.msec();
+#endif //UNDER_CE
+}
+
+// #pragma mark -- char related utils
+
+size_t Misc::ahashCode(const char* str)
+{
+ // Compute the hash code using a local variable to be reentrant.
+ size_t hashCode = 0;
+ while (*str != 0)
+ hashCode = hashCode * 31 + *str++;
+ return hashCode;
+}
+
+size_t Misc::ahashCode(const char* str, size_t len)
+{
+ // Compute the hash code using a local variable to be reentrant.
+ size_t count = len;
+ size_t hashCode = 0;
+ for (size_t i = 0; i < count; i++)
+ hashCode = hashCode * 31 + *str++;
+ return hashCode;
+}
+
+char* Misc::ajoin(const char* a, const char* b, const char* c, const char* d,
+ const char* e, const char* f)
+{
+#define aLEN(x) (x == NULL ? 0 : strlen(x))
+ const size_t totalLen = aLEN(a) + aLEN(b) + aLEN(c) + aLEN(d) + aLEN(e)
+ + aLEN(f) + sizeof(char); /* Space for terminator. */
+
+ char* buf = _CL_NEWARRAY(char, totalLen);
+ buf[0] = 0;
+ if (a != NULL)
+ strcat(buf, a);
+
+ if (b != NULL)
+ strcat(buf, b);
+
+ if (c != NULL)
+ strcat(buf, c);
+
+ if (d != NULL)
+ strcat(buf, d);
+
+ if (e != NULL)
+ strcat(buf, e);
+
+ if (f != NULL)
+ strcat(buf, f);
+
+ return buf;
+}
+
+char* Misc::segmentname(const char* segment, const char* ext, int32_t x)
+{
+ CND_PRECONDITION(ext != NULL, "ext is NULL");
+
+ char* buf = _CL_NEWARRAY(char, CL_MAX_PATH);
+ if (x == -1)
+ _snprintf(buf, CL_MAX_PATH, "%s%s", segment, ext);
+ else
+ _snprintf(buf, CL_MAX_PATH, "%s%s%d", segment, ext, x);
+ return buf;
+}
+
+void Misc::segmentname(char* buffer, int32_t bufferLen, const char* segment,
+ const char* ext, int32_t x)
+{
+ CND_PRECONDITION(buffer != NULL, "buffer is NULL");
+ CND_PRECONDITION(segment != NULL, "segment is NULL");
+ CND_PRECONDITION(ext != NULL, "extention is NULL");
+
+ if (x == -1)
+ _snprintf(buffer, bufferLen, "%s%s", segment, ext);
+ else
+ _snprintf(buffer, bufferLen, "%s%s%d", segment, ext, x);
+}
+
+// #pragma mark -- qt related utils
+
+size_t Misc::qhashCode(const QString& str)
+{
+ size_t hashCode = 0;
+ for (int i = 0; i < str.count(); ++i)
+ hashCode = hashCode * 31 + str.at(i).unicode();
+ return hashCode;
+}
+
+size_t Misc::qhashCode(const QString& str, size_t len)
+{
+ size_t count = len;
+ size_t hashCode = 0;
+ for (size_t i = 0; i < count; ++i)
+ hashCode = hashCode * 31 + str.at(i).unicode();
+ return hashCode;
+}
+
+QString Misc::qjoin(const QString &a, const QString &b, const QString &c,
+ const QString &d, const QString &e, const QString &f)
+{
+ QString buffer;
+
+ if (!a.isNull() && !a.isEmpty())
+ buffer.append(a);
+
+ if (!b.isNull() && !b.isEmpty())
+ buffer.append(b);
+
+ if (!c.isNull() && !c.isEmpty())
+ buffer.append(c);
+
+ if (!d.isNull() && !d.isEmpty())
+ buffer.append(d);
+
+ if (!e.isNull() && !e.isEmpty())
+ buffer.append(e);
+
+ if (!f.isNull() && !f.isEmpty())
+ buffer.append(f);
+
+ return buffer;
+}
+
+QString Misc::segmentname(const QString& segment, const QString& ext, int32_t x)
+{
+ CND_PRECONDITION(!ext.isEmpty(), "ext is NULL");
+
+ if (x == -1)
+ return QString(segment + ext);
+
+ QString buf(QLatin1String("%1%2%3"));
+ return buf.arg(segment).arg(ext).arg(x);
+}
+
+void Misc::segmentname(QString& buffer, int32_t bufferLen,
+ const QString& segment, const QString& ext, int32_t x)
+{
+ CND_PRECONDITION(!segment.isEmpty(), "segment is NULL");
+ CND_PRECONDITION(!ext.isEmpty(), "extention is NULL");
+
+ buffer = segment + ext;
+ if (x != -1)
+ buffer += QString::number(x);
+}
+
+// #pragma mark -- TCHAR related utils
+
+int32_t Misc::stringDifference(const TCHAR* s1, int32_t len1, const TCHAR* s2,
+ int32_t len2)
+{
+ int32_t len = len1 < len2 ? len1 : len2;
+ for (int32_t i = 0; i < len; i++)
+ if (s1[i] != s2[i])
+ return i;
+ return len;
+}
+
+/* DSR:CL_BUG: (See comment for join method in Misc.h): */
+TCHAR* Misc::join (const TCHAR* a, const TCHAR* b, const TCHAR* c,
+ const TCHAR* d, const TCHAR* e, const TCHAR* f)
+{
+#define LEN(x) (x == NULL ? 0 : _tcslen(x))
+ const size_t totalLen = LEN(a) + LEN(b) + LEN(c) + LEN(d) + LEN(e) + LEN(f)
+ + sizeof(TCHAR); /* Space for terminator. */
+
+ TCHAR* buf = _CL_NEWARRAY(TCHAR, totalLen);
+ buf[0] = 0;
+ if (a != NULL)
+ _tcscat(buf, a);
+
+ if (b != NULL)
+ _tcscat(buf, b);
+
+ if (c != NULL)
+ _tcscat(buf, c);
+
+ if (d != NULL)
+ _tcscat(buf, d);
+
+ if (e != NULL)
+ _tcscat(buf, e);
+
+ if (f != NULL)
+ _tcscat(buf, f);
+
+ return buf;
+}
+
+#ifdef _UCS2
+
+size_t Misc::whashCode(const wchar_t* str)
+{
+ // Compute the hash code using a local variable to be reentrant.
+ size_t hashCode = 0;
+ while (*str != 0)
+ hashCode = hashCode * 31 + *str++;
+ return hashCode;
+}
+
+size_t Misc::whashCode(const wchar_t* str, size_t len)
+{
+ // Compute the hash code using a local variable to be reentrant.
+ size_t count = len;
+ size_t hashCode = 0;
+ for (size_t i = 0; i < count; i++)
+ hashCode = hashCode * 31 + *str++;
+ return hashCode;
+}
+
+char* Misc::_wideToChar(const wchar_t* s CL_FILELINEPARAM)
+{
+ size_t len = _tcslen(s);
+ char* msg = _CL_NEWARRAY(char, len + 1);
+ _cpywideToChar(s, msg, len + 1);
+ return msg;
+}
+
+void Misc::_cpywideToChar(const wchar_t* s, char* d, size_t len)
+{
+ size_t sLen = wcslen(s);
+ for (uint32_t i = 0; i < len && i < sLen + 1; i++)
+ d[i] = LUCENE_OOR_CHAR(s[i]);
+}
+
+wchar_t* Misc::_charToWide(const char* s CL_FILELINEPARAM)
+{
+ size_t len = strlen(s);
+ wchar_t* msg = _CL_NEWARRAY(wchar_t, len + 1);
+ _cpycharToWide(s, msg, len + 1);
+ return msg;
+}
+
+void Misc::_cpycharToWide(const char* s, wchar_t* d, size_t len)
+{
+ size_t sLen = strlen(s);
+ for (uint32_t i = 0; i < len && i < sLen + 1; i++)
+ d[i] = s[i];
+}
+
+#endif
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/util/Misc.h b/3rdparty/clucene/src/CLucene/util/Misc.h
new file mode 100644
index 000000000..561c6e4d9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/Misc.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+ *
+ * Distributable under the terms of either the Apache License (Version 2.0) or
+ * the GNU Lesser General Public License, as specified in the COPYING file.
+ *
+ * Changes are Copyright(C) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
+*/
+#ifndef _lucene_util_Misc_H
+#define _lucene_util_Misc_H
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <QtCore/QString>
+
+CL_NS_DEF(util)
+
+class Misc
+{
+public:
+ static uint64_t currentTimeMillis();
+
+ static size_t ahashCode(const char* str);
+ static size_t ahashCode(const char* str, size_t len);
+ static char* ajoin(const char* a, const char* b, const char* c = NULL,
+ const char* d = NULL, const char* e = NULL, const char* f = NULL);
+ static char* segmentname(const char* segment, const char* ext, int32_t x = -1);
+ static void segmentname(char* buffer, int32_t bufferLen, const char* segment,
+ const char* ext, int32_t x = -1);
+
+ static size_t qhashCode(const QString& str);
+ static size_t qhashCode(const QString& str, size_t len);
+ static QString qjoin(const QString& a, const QString& b,
+ const QString& c = QString(), const QString& d = QString(),
+ const QString& e = QString(), const QString& f = QString());
+ static QString segmentname(const QString& segment, const QString& ext,
+ int32_t x = -1 );
+ static void segmentname(QString& buffer, int32_t bufferLen,
+ const QString& Segment, const QString& ext, int32_t x = -1);
+
+ // Compares two strings, character by character, and returns the
+ // first position where the two strings differ from one another.
+ //
+ // @param s1 The first string to compare
+ // @param s1Len The length of the first string to compare
+ // @param s2 The second string to compare
+ // @param s2Len The length of the second string to compare
+ // @return The first position where the two strings differ.
+ static int32_t stringDifference(const TCHAR* s1, int32_t s1Len,
+ const TCHAR* s2, int32_t s2Len);
+ static TCHAR* join (const TCHAR* a, const TCHAR* b, const TCHAR* c = NULL,
+ const TCHAR* d = NULL, const TCHAR* e = NULL, const TCHAR* f = NULL );
+
+#ifdef _UCS2
+ static size_t whashCode(const wchar_t* str);
+ static size_t whashCode(const wchar_t* str, size_t len);
+
+# define thashCode whashCode
+
+ static char* _wideToChar(const wchar_t* s CL_FILELINEPARAM);
+ static void _cpywideToChar(const wchar_t* s, char* d, size_t len);
+
+ static wchar_t* _charToWide(const char* s CL_FILELINEPARAM);
+ static void _cpycharToWide(const char* s, wchar_t* d, size_t len);
+
+#else
+# define thashCode ahashCode
+#endif
+};
+
+CL_NS_END
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/PriorityQueue.h b/3rdparty/clucene/src/CLucene/util/PriorityQueue.h
new file mode 100644
index 000000000..45649ee7f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/PriorityQueue.h
@@ -0,0 +1,177 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_PriorityQueue_
+#define _lucene_util_PriorityQueue_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+CL_NS_DEF(util)
+
+// A PriorityQueue maintains a partial ordering of its elements such that the
+// least element can always be found in constant time. Put()'s and pop()'s
+// require log(size) time.
+template <class _type,typename _valueDeletor> class PriorityQueue:LUCENE_BASE {
+ private:
+ _type* heap; //(was object[])
+ size_t _size;
+ bool dk;
+ size_t maxSize;
+
+ void upHeap(){
+ size_t i = _size;
+ _type node = heap[i]; // save bottom node (WAS object)
+ int32_t j = ((uint32_t)i) >> 1;
+ while (j > 0 && lessThan(node,heap[j])) {
+ heap[i] = heap[j]; // shift parents down
+ i = j;
+ j = ((uint32_t)j) >> 1;
+ }
+ heap[i] = node; // install saved node
+ }
+ void downHeap(){
+ size_t i = 1;
+ _type node = heap[i]; // save top node
+ size_t j = i << 1; // find smaller child
+ size_t k = j + 1;
+ if (k <= _size && lessThan(heap[k], heap[j])) {
+ j = k;
+ }
+ while (j <= _size && lessThan(heap[j],node)) {
+ heap[i] = heap[j]; // shift up child
+ i = j;
+ j = i << 1;
+ k = j + 1;
+ if (k <= _size && lessThan(heap[k], heap[j])) {
+ j = k;
+ }
+ }
+ heap[i] = node; // install saved node
+ }
+
+ protected:
+ PriorityQueue(){
+ this->_size = 0;
+ this->dk = false;
+ this->heap = NULL;
+ this->maxSize = 0;
+ }
+
+ // Determines the ordering of objects in this priority queue. Subclasses
+ // must define this one method.
+ virtual bool lessThan(_type a, _type b)=0;
+
+ // Subclass constructors must call this.
+ void initialize(const int32_t maxSize, bool deleteOnClear){
+ _size = 0;
+ dk = deleteOnClear;
+ int32_t heapSize = maxSize + 1;
+ heap = _CL_NEWARRAY(_type,heapSize);
+ this->maxSize = maxSize;
+ }
+
+ public:
+ virtual ~PriorityQueue(){
+ clear();
+ _CLDELETE_ARRAY(heap);
+ }
+
+ /**
+ * Adds an Object to a PriorityQueue in log(size) time.
+ * If one tries to add more objects than maxSize from initialize
+ * a RuntimeException (ArrayIndexOutOfBound) is thrown.
+ */
+ void put(_type element){
+ if ( _size>=maxSize )
+ _CLTHROWA(CL_ERR_IndexOutOfBounds,"add is out of bounds");
+
+ ++_size;
+ heap[_size] = element;
+ upHeap();
+ }
+
+ /**
+ * Adds element to the PriorityQueue in log(size) time if either
+ * the PriorityQueue is not full, or not lessThan(element, top()).
+ * @param element
+ * @return true if element is added, false otherwise.
+ */
+ bool insert(_type element){
+ if(_size < maxSize){
+ put(element);
+ return true;
+ }else if(_size > 0 && !lessThan(element, top())){
+ if ( dk ){
+ _valueDeletor::doDelete(heap[1]);
+ }
+ heap[1] = element;
+ adjustTop();
+ return true;
+ }else
+ return false;
+ }
+
+ /**
+ * Returns the least element of the PriorityQueue in constant time.
+ */
+ _type top(){
+ if (_size > 0)
+ return heap[1];
+ else
+ return NULL;
+ }
+
+ /** Removes and returns the least element of the PriorityQueue in log(size)
+ * time.
+ */
+ _type pop(){
+ if (_size > 0) {
+ _type result = heap[1]; // save first value
+ heap[1] = heap[_size]; // move last to first
+
+ heap[_size] = (_type)0; // permit GC of objects
+ --_size;
+ downHeap(); // adjust heap
+ return result;
+ } else
+ return (_type)NULL;
+ }
+
+ /**Should be called when the object at top changes values. Still log(n)
+ worst case, but it's at least twice as fast to <pre>
+ { pq.top().change(); pq.adjustTop(); }
+ </pre> instead of <pre>
+ { o = pq.pop(); o.change(); pq.push(o); }
+ </pre>
+ */
+ void adjustTop(){
+ downHeap();
+ }
+
+
+ /**
+ * Returns the number of elements currently stored in the PriorityQueue.
+ */
+ size_t size(){
+ return _size;
+ }
+
+ /**
+ * Removes all entries from the PriorityQueue.
+ */
+ void clear(){
+ for (size_t i = 1; i <= _size; ++i){
+ if ( dk ){
+ _valueDeletor::doDelete(heap[i]);
+ }
+ }
+ _size = 0;
+ }
+ };
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/Reader.cpp b/3rdparty/clucene/src/CLucene/util/Reader.cpp
new file mode 100644
index 000000000..1ce97106d
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/Reader.cpp
@@ -0,0 +1,186 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "Reader.h"
+
+CL_NS_DEF(util)
+
+StringReader::StringReader ( const TCHAR* value ):
+ Reader(NULL,true){
+ reader = new jstreams::StringReader<TCHAR>(value);
+}
+StringReader::StringReader ( const TCHAR* value, const int32_t length ):
+ Reader(NULL,true){
+ reader = new jstreams::StringReader<TCHAR>(value,length);
+}
+StringReader::StringReader ( const TCHAR* value, const int32_t length, bool copyData ):
+ Reader(NULL,true){
+ reader = new jstreams::StringReader<TCHAR>(value,length, copyData);
+}
+StringReader::~StringReader(){
+}
+
+
+FileReader::FileReader ( const char* path, const char* enc,
+ const int32_t cachelen, const int32_t /*cachebuff*/ ):
+ Reader(NULL, true)
+{
+ this->input = new jstreams::FileInputStream(path, cachelen);
+ this->reader = new SimpleInputStreamReader(this->input,enc); //(this is a jstream object)
+}
+
+FileReader::~FileReader (){
+ if (input)
+ delete input;
+}
+int32_t FileReader::read(const TCHAR*& start, int32_t _min, int32_t _max) {
+ return reader->read(start, _min, _max);
+}
+int64_t FileReader::mark(int32_t readlimit) {
+ return reader->mark(readlimit);
+}
+int64_t FileReader::reset(int64_t newpos) {
+ return reader->reset(newpos);
+}
+
+
+
+SimpleInputStreamReader::SimpleInputStreamReader(jstreams::StreamBase<char> *i, const char* enc)
+{
+ finishedDecoding = false;
+ input = i;
+ charbuf.setSize(262);
+
+ if ( strcmp(enc,"ASCII")==0 )
+ encoding = ASCII;
+#ifdef _UCS2
+ else if ( strcmp(enc,"UTF-8")==0 )
+ encoding = UTF8;
+ else if ( strcmp(enc,"UCS-2LE")==0 )
+ encoding = UCS2_LE;
+#endif
+ else
+ _CLTHROWA(CL_ERR_IllegalArgument,"Unsupported encoding, use jstreams iconv based instead");
+
+ mark(262);
+ charsLeft = 0;
+}
+SimpleInputStreamReader::~SimpleInputStreamReader(){
+ input = NULL;
+}
+int32_t SimpleInputStreamReader::decode(TCHAR* start, int32_t space){
+ // decode from charbuf
+ const char *inbuf = charbuf.readPos;
+ const char *inbufend = charbuf.readPos + charbuf.avail;
+ TCHAR *outbuf = start;
+ const TCHAR *outbufend = outbuf + space;
+
+ if ( encoding == ASCII ){
+ while ( outbuf<outbufend && inbuf<inbufend ){
+ *outbuf = *inbuf;
+ outbuf++;
+ inbuf++;
+ }
+
+#ifdef _UCS2
+ }
+ else if ( encoding == UCS2_LE ){
+ while ( outbuf<outbufend && (inbuf+1)<inbufend ){
+ uint8_t c1 = *inbuf;
+ uint8_t c2 = *(inbuf+1);
+ unsigned short c = c1 | (c2<<8);
+
+ #ifdef _UCS2
+ *outbuf = c;
+ #else
+ *outbuf = LUCENE_OOR_CHAR(c);
+ #endif
+ outbuf++;
+ inbuf+=2;
+ }
+
+ }else if ( encoding == UTF8 ){
+ while ( outbuf<outbufend && inbuf<inbufend ){
+ size_t utflen = lucene_utf8charlen(inbuf);
+ if ( utflen==0 ){
+ error = "Invalid multibyte sequence.";
+ status = jstreams::Error;
+ return -1;
+ }else if ( inbuf+utflen > inbufend ){
+ break; //character incomplete
+ }else{
+ size_t rd = lucene_utf8towc(outbuf,inbuf,inbufend-inbuf);
+ if ( rd == 0 ){
+ error = "Invalid multibyte sequence.";
+ status = jstreams::Error;
+ return -1;
+ }else{
+ inbuf+=rd;
+ outbuf++;
+ }
+ }
+ }
+#endif //_UCS2
+ }else
+ _CLTHROWA(CL_ERR_Runtime,"Unexpected encoding");
+
+ if ( outbuf < outbufend ) {
+ //we had enough room to convert the entire input
+ if ( inbuf < inbufend ) {
+ // last character is incomplete
+ // move from inbuf to the end to the start of
+ // the buffer
+ memmove(charbuf.start, inbuf, inbufend-inbuf);
+ charbuf.readPos = charbuf.start;
+ charbuf.avail = inbufend-inbuf;
+ } else if ( outbuf < outbufend ) { //input sequence was completely converted
+ charbuf.readPos = charbuf.start;
+ charbuf.avail = 0;
+ if (input == NULL) {
+ finishedDecoding = true;
+ }
+ }
+ } else {
+ charbuf.readPos += charbuf.avail - (inbufend-inbuf);
+ charbuf.avail = inbufend-inbuf;
+ }
+ return outbuf-start;
+}
+
+int32_t SimpleInputStreamReader::fillBuffer(TCHAR* start, int32_t space) {
+ // fill up charbuf
+ if (input && charbuf.readPos == charbuf.start) {
+ const char *begin;
+ int32_t numRead;
+ numRead = input->read(begin, 1, charbuf.size - charbuf.avail);
+ //printf("filled up charbuf\n");
+ if (numRead < -1) {
+ error = input->getError();
+ status = jstreams::Error;
+ input = 0;
+ return numRead;
+ }
+ if (numRead < 1) {
+ // signal end of input buffer
+ input = 0;
+ if (charbuf.avail) {
+ error = "stream ends on incomplete character";
+ status = jstreams::Error;
+ }
+ return -1;
+ }
+ // copy data into other buffer
+ memmove( charbuf.start + charbuf.avail, begin, numRead * sizeof(char));
+ charbuf.avail = numRead + charbuf.avail;
+ }
+ // decode
+ int32_t n = decode(start, space);
+ //printf("decoded %i\n", n);
+ return n;
+}
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/util/Reader.h b/3rdparty/clucene/src/CLucene/util/Reader.h
new file mode 100644
index 000000000..6b018b3aa
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/Reader.h
@@ -0,0 +1,138 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_Reader_
+#define _lucene_util_Reader_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "streambase.h"
+#include "stringreader.h"
+#include "fileinputstream.h"
+#include "bufferedstream.h"
+
+CL_NS_DEF(util)
+/**
+* An inline wrapper that reads from Jos van den Oever's jstreams
+*/
+class Reader:LUCENE_BASE {
+typedef jstreams::StreamBase<TCHAR> jsReader;
+public:
+ bool deleteReader;
+ jsReader* reader;
+
+ Reader(jsReader* reader, bool deleteReader){
+ this->reader = reader;
+ this->deleteReader = deleteReader;
+ }
+ virtual ~Reader(){
+ if ( deleteReader )
+ delete reader;
+ reader = NULL;
+ }
+ inline int read(){
+ const TCHAR*b;
+ int32_t nread = reader->read(b, 1,1);
+ if ( nread < -1 ) //if not eof
+ _CLTHROWA(CL_ERR_IO,reader->getError() );
+ else if ( nread == -1 )
+ return -1;
+ else
+ return b[0];
+ }
+ /**
+ * Read at least 1 character, and as much as is conveniently available
+ */
+ inline int32_t read(const TCHAR*& start){
+ int32_t nread = reader->read(start,1,0);
+ if ( nread < -1 ) //if not eof
+ _CLTHROWA(CL_ERR_IO,reader->getError());
+ else
+ return nread;
+ }
+ inline int32_t read(const TCHAR*& start, int32_t len){
+ int32_t nread = reader->read(start, len, len);
+ if ( nread < -1 ) //if not eof
+ _CLTHROWA(CL_ERR_IO,reader->getError());
+ else
+ return nread;
+ }
+ inline int64_t skip(int64_t ntoskip){
+ int64_t skipped = reader->skip(ntoskip);
+ if ( skipped < 0 )
+ _CLTHROWA(CL_ERR_IO,reader->getError());
+ else
+ return skipped;
+ }
+ inline int64_t mark(int32_t readAheadlimit){
+ int64_t pos = reader->mark(readAheadlimit);
+ if ( pos < 0 )
+ _CLTHROWA(CL_ERR_IO,reader->getError());
+ else
+ return pos;
+ }
+ int64_t reset(int64_t pos){
+ int64_t r = reader->reset(pos);
+ if ( r < 0 )
+ _CLTHROWA(CL_ERR_IO,reader->getError());
+ else
+ return r;
+ }
+};
+
+///A helper class which constructs a the jstreams StringReader.
+class StringReader: public Reader{
+public:
+ StringReader ( const TCHAR* value );
+ StringReader ( const TCHAR* value, const int32_t length );
+ StringReader ( const TCHAR* value, const int32_t length, bool copyData );
+ ~StringReader();
+};
+
+/** A very simple inputstreamreader implementation. For a
+* more complete InputStreamReader, use the jstreams version
+* located in the contrib package
+*/
+class SimpleInputStreamReader: public jstreams::BufferedInputStream<TCHAR>{
+ int32_t decode(TCHAR* start, int32_t space);
+ int encoding;
+ enum{
+ ASCII=1,
+ UTF8=2,
+ UCS2_LE=3
+ };
+ bool finishedDecoding;
+ jstreams::StreamBase<char>* input;
+ int32_t charsLeft;
+
+ jstreams::InputStreamBuffer<char> charbuf;
+ int32_t fillBuffer(TCHAR* start, int32_t space);
+public:
+ SimpleInputStreamReader(jstreams::StreamBase<char> *i, const char* encoding);
+ ~SimpleInputStreamReader();
+};
+
+/**
+* A helper class which constructs a FileReader with a specified
+* simple encodings, or a given inputstreamreader
+*/
+class FileReader: public Reader{
+ jstreams::FileInputStream* input;
+public:
+ FileReader ( const char* path, const char* enc,
+ const int32_t cachelen = 13,
+ const int32_t cachebuff = 14 ); //todo: optimise these cache values
+ ~FileReader ();
+
+ int32_t read(const TCHAR*& start, int32_t _min, int32_t _max);
+ int64_t mark(int32_t readlimit);
+ int64_t reset(int64_t);
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/StringBuffer.cpp b/3rdparty/clucene/src/CLucene/util/StringBuffer.cpp
new file mode 100644
index 000000000..b5f1ca238
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/StringBuffer.cpp
@@ -0,0 +1,335 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "StringBuffer.h"
+#include "Misc.h"
+
+CL_NS_DEF(util)
+
+ StringBuffer::StringBuffer(TCHAR* buf,int32_t maxlen, const bool consumeBuffer){
+ buffer = buf;
+ bufferLength = maxlen;
+ bufferOwner = !consumeBuffer;
+ len = 0;
+ }
+ StringBuffer::StringBuffer(){
+ //Func - Constructor. Allocates a buffer with the default length.
+ //Pre - true
+ //Post - buffer of length bufferLength has been allocated
+
+ //Initialize
+ bufferLength = LUCENE_DEFAULT_TOKEN_BUFFER_SIZE;
+ len = 0;
+ //Allocate a buffer of length bufferLength
+ buffer = _CL_NEWARRAY(TCHAR,bufferLength);
+ bufferOwner = true;
+ }
+
+ StringBuffer::StringBuffer(const int32_t initSize){
+ //Func - Constructor. Allocates a buffer of length initSize + 1
+ //Pre - initSize > 0
+ //Post - A buffer has been allocated of length initSize + 1
+
+ //Initialize the bufferLength to initSize + 1 The +1 is for the terminator '\0'
+ bufferLength = initSize + 1;
+ len = 0;
+ //Allocate a buffer of length bufferLength
+ buffer = _CL_NEWARRAY(TCHAR,bufferLength);
+ bufferOwner = true;
+ }
+
+ StringBuffer::StringBuffer(const TCHAR* value){
+ //Func - Constructor.
+ // Creates an instance of Stringbuffer containing a copy of the string value
+ //Pre - value != NULL
+ //Post - An instance of StringBuffer has been created containing the copy of the string value
+
+ //Initialize the length of the string to be stored in buffer
+ len = (int32_t) _tcslen(value);
+
+ //Calculate the space occupied in buffer by a copy of value
+ const int32_t occupiedLength = len + 1;
+
+ // Minimum allocated buffer length is LUCENE_DEFAULT_TOKEN_BUFFER_SIZE.
+ bufferLength = (occupiedLength >= LUCENE_DEFAULT_TOKEN_BUFFER_SIZE
+ ? occupiedLength : LUCENE_DEFAULT_TOKEN_BUFFER_SIZE);
+
+ //Allocate a buffer of length bufferLength
+ buffer = _CL_NEWARRAY(TCHAR,bufferLength);
+ bufferOwner = true;
+ //Copy the string value into buffer
+ _tcsncpy(buffer, value, occupiedLength);
+ //Assert that the buffer has been terminated at the end of the string
+ CND_PRECONDITION (buffer[len] == '\0', "Buffer was not correctly terminated");
+ }
+
+ StringBuffer::~StringBuffer() {
+ // Func - Destructor
+ // Pre - true
+ // Post - Instanc has been destroyed
+
+ if( bufferOwner ){
+ _CLDELETE_CARRAY(buffer);
+ }else
+ buffer = NULL;
+ }
+ void StringBuffer::clear(){
+ //Func - Clears the Stringbuffer and resets it to it default empty state
+ //Pre - true
+ //Post - pre(buffer) has been destroyed and a new one has been allocated
+
+ //Destroy the current buffer if present
+ _CLDELETE_CARRAY(buffer);
+
+ //Initialize
+ len = 0;
+ bufferLength = LUCENE_DEFAULT_TOKEN_BUFFER_SIZE;
+ //Allocate a buffer of length bufferLength
+ buffer = _CL_NEWARRAY(TCHAR,bufferLength);
+ }
+
+ void StringBuffer::appendChar(const TCHAR character) {
+ //Func - Appends a single character
+ //Pre - true
+ //Post - The character has been appended to the string in the buffer
+
+ //Check if the current buffer length is sufficient to have the string value appended
+ if (len + 1 > bufferLength){
+ //Have the size of the current string buffer increased because it is too small
+ growBuffer(len + 1);
+ }
+ //Put character at position len which is the end of the string in the buffer
+ //Note that this action might overwrite the terminator of the string '\0', which
+ //is kind of tricky
+ buffer[len] = character;
+ //Increase the len by to represent the correct length of the string in the buffer
+ len++;
+ }
+
+ void StringBuffer::append(const TCHAR* value) {
+ //Func - Appends a copy of the string value
+ //Pre - value != NULL
+ //Post - value has been copied and appended to the string in buffer
+
+ append(value, _tcslen(value));
+ }
+ void StringBuffer::append(const TCHAR* value, size_t appendedLength) {
+ //Func - Appends a copy of the string value
+ //Pre - value != NULL
+ // appendedLength contains the length of the string value which is to be appended
+ //Post - value has been copied and appended to the string in buffer
+
+ //Check if the current buffer length is sufficient to have the string value appended
+ if (len + appendedLength + 1 > bufferLength){
+ //Have the size of the current string buffer increased because it is too small
+ growBuffer(len + appendedLength + 1);
+ }
+
+ //Copy the string value into the buffer at postion len
+ _tcsncpy(buffer + len, value, appendedLength);
+
+ //Add the length of the copied string to len to reflect the new length of the string in
+ //the buffer (Note: len is not the bufferlength!)
+ len += appendedLength;
+ }
+
+ void StringBuffer::appendInt(const int32_t value) {
+ //Func - Appends an integer (after conversion to a character string)
+ //Pre - true
+ //Post - The converted integer value has been appended to the string in buffer
+
+ //instantiate a buffer of 30 charactes for the conversion of the integer
+ TCHAR buf[30];
+ //Convert the integer value to a string buf using the radix 10 (duh)
+ _i64tot(value, buf, 10);
+ //Have the converted integer now stored in buf appended to the string in buffer
+ append(buf);
+ }
+
+ void StringBuffer::appendFloat(const qreal value, const int32_t digits){
+ //Func - Appends a qreal (after conversion to a character string)
+ //Pre - digits > 0. Indicates the minimum number of characters printed
+ //Post - The converted qreal value has been appended to the string in buffer
+
+ //using sprintf("%f" was not reliable on other plaforms... we use a custom float convertor
+ //bvk: also, using sprintf and %f seems excessivelly slow
+ if(digits>8)
+ _CLTHROWA(CL_ERR_IllegalArgument,"Too many digits...");
+
+ //the maximum number of characters that int64 will hold is 23. so we need 23*2+2
+ TCHAR buf[48]; //the buffer to hold
+ int64_t v = (int64_t)value; //the integer value of the float
+ _i64tot(v,buf,10); //add the whole number
+
+ size_t len = 99-_tcslen(buf); //how many digits we have to work with?
+ size_t dig = len< (size_t)digits ? len : digits;
+ if ( dig > 0 ){
+ _tcscat(buf,_T(".")); //add a decimal point
+
+ int64_t remi=(int64_t)((value-v)*pow((qreal)10,(qreal)(dig+1))); //take the remainder and make a whole number
+ if ( remi<0 ) remi*=-1;
+ int64_t remadj=remi/10;
+ if ( remi-(remadj*10) >=5 )
+ remadj++; //adjust remainder
+
+ // add as many zeros as necessary between the decimal point and the
+ // significant part of the number. Fixes a bug when trying to print
+ // numbers that have zeros right after the decimal point
+ if (remadj) {
+ int32_t numZeros = dig - (int32_t)log10((qreal)remadj) - 1;
+ while(numZeros-- > 0)
+ _tcscat(buf,_T("0")); //add a zero before the decimal point
+ }
+
+ _i64tot(remadj,buf+_tcslen(buf),10); //add the remainder
+ }
+
+ append(buf);
+ }
+
+ void StringBuffer::prepend(const TCHAR* value){
+ //Func - Puts a copy of the string value infront of the current string in the StringBuffer
+ //Pre - value != NULL
+ //Post - The string in pre(buffer) has been shifted n positions where n equals the length of value.
+ // The string value was then copied to the beginning of stringbuffer
+
+ prepend(value, _tcslen(value));
+ }
+
+ void StringBuffer::prepend(const TCHAR* value, const size_t prependedLength) {
+ //Func - Puts a copy of the string value in front of the string in the StringBuffer
+ //Pre - value != NULL
+ // prependedLength contains the length of the string value which is to be prepended
+ //Post - A copy of the string value is has been in front of the string in buffer
+ //todo: something is wrong with this code, i'm sure... it only grows (and therefore moves if the buffer is to small)
+ //Check if the current buffer length is sufficient to have the string value prepended
+ if (prependedLength + len + 1 > bufferLength){
+ //Have the size of the current string buffer increased because it is too small
+ //Because prependedLength is passed as the second argument to growBuffer,
+ //growBuffer will have left the first prependedLength characters empty
+ //when it recopied buffer during reallocation.
+ growBuffer(prependedLength + len + 1, prependedLength);
+ }
+
+ //Copy the string value into the buffer at postion 0
+ _tcsncpy(buffer, value, prependedLength);
+ //Add the length of the copied string to len to reflect the new length of the string in
+ //the buffer (Note: len is not the bufferlength!)
+ len += prependedLength;
+ }
+
+ int32_t StringBuffer::length() const{
+ //Func - Returns the length of the string in the StringBuffer
+ //Pre - true
+ //Post - The length len of the string in the buffer has been returned
+
+ return len;
+ }
+ TCHAR* StringBuffer::toString(){
+ //Func - Returns a copy of the current string in the StringBuffer sized equal to the length of the string
+ // in the StringBuffer.
+ //Pre - true
+ //Post - The copied string has been returned
+
+ //Instantiate a buffer equal to the length len + 1
+ TCHAR* ret = _CL_NEWARRAY(TCHAR,len + 1);
+ if (ret){
+ //Copy the string in buffer
+ _tcsncpy(ret, buffer, len);
+ //terminate the string
+ ret[len] = '\0';
+ }
+ //return the the copy
+ return ret;
+ }
+ TCHAR* StringBuffer::getBuffer() {
+ //Func - '\0' terminates the buffer and returns its pointer
+ //Pre - true
+ //Post - buffer has been '\0' terminated and returned
+
+ // Check if the current buffer is '\0' terminated
+ if (len == bufferLength){
+ //Make space for terminator, if necessary.
+ growBuffer(len + 1);
+ }
+ //'\0' buffer so it can be returned properly
+ buffer[len] = '\0';
+
+ return buffer;
+ }
+
+ void StringBuffer::reserve(const int32_t size){
+ if ( bufferLength >= size )
+ return;
+ bufferLength = size;
+
+ //Allocate a new buffer of length bufferLength
+ TCHAR* tmp = _CL_NEWARRAY(TCHAR,bufferLength);
+ _tcsncpy(tmp, buffer, len);
+ tmp[len] = '\0';
+
+ //destroy the old buffer
+ if (buffer){
+ _CLDELETE_CARRAY(buffer);
+ }
+ //Assign the new buffer tmp to buffer
+ buffer = tmp;
+ }
+
+ void StringBuffer::growBuffer(const int32_t minLength) {
+ //Func - Has the buffer grown to a minimum length of minLength or bigger
+ //Pre - minLength >= len + 1
+ //Post - The buffer has been grown to a minimum length of minLength or bigger
+
+ growBuffer(minLength, 0);
+ }
+ void StringBuffer::growBuffer(const int32_t minLength, const int32_t skippingNInitialChars) {
+ //Func - Has the buffer grown to a minimum length of minLength or bigger and shifts the
+ // current string in buffer by skippingNInitialChars forward
+ //Pre - After growth, must have at least enough room for contents + terminator so
+ // minLength >= skippingNInitialChars + len + 1
+ // skippingNInitialChars >= 0
+ //Post - The buffer has been grown to a minimum length of minLength or bigger and
+ // if skippingNInitialChars > 0, the contents of the buffer has beeen shifted
+ // forward by skippingNInitialChars positions as the buffer is reallocated,
+ // leaving the first skippingNInitialChars uninitialized (presumably to be
+ // filled immediately thereafter by the caller).
+
+ CND_PRECONDITION (skippingNInitialChars >= 0, "skippingNInitialChars is less than zero");
+ CND_PRECONDITION (minLength >= skippingNInitialChars + len + 1,"skippingNInitialChars is not large enough");
+
+ //More aggressive growth strategy to offset smaller default buffer size:
+ if ( !bufferOwner ){
+ if ( bufferLength<minLength )
+ _CLTHROWA(CL_ERR_IllegalArgument,"[StringBuffer::grow] un-owned buffer could not be grown");
+ return;
+ }
+
+ bufferLength *= 2;
+ //Check that bufferLength is bigger than minLength
+ if (bufferLength < minLength){
+ //Have bufferLength become minLength because it still was too small
+ bufferLength = minLength;
+ }
+
+ //Allocate a new buffer of length bufferLength
+ TCHAR* tmp = _CL_NEWARRAY(TCHAR,bufferLength);
+ //The old buffer might not have been null-terminated, so we _tcsncpy
+ //only len bytes, not len+1 bytes (the latter might read one char off the
+ //end of the old buffer), then apply the terminator to the new buffer.
+ _tcsncpy(tmp + skippingNInitialChars, buffer, len);
+ tmp[skippingNInitialChars + len] = '\0';
+
+ //destroy the old buffer
+ if (buffer){
+ _CLDELETE_CARRAY(buffer);
+ }
+ //Assign the new buffer tmp to buffer
+ buffer = tmp;
+ }
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/util/StringBuffer.h b/3rdparty/clucene/src/CLucene/util/StringBuffer.h
new file mode 100644
index 000000000..505b57594
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/StringBuffer.h
@@ -0,0 +1,77 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_StringBuffer_
+#define _lucene_util_StringBuffer_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+
+CL_NS_DEF(util)
+ class StringBuffer:LUCENE_BASE{
+ public:
+ ///Constructor. Allocates a buffer with the default length.
+ StringBuffer();
+ ///Constructor. Allocates a buffer of length initSize + 1
+ StringBuffer(const int32_t initSize);
+ ///Constructor. Creates an instance of Stringbuffer containing a copy of
+ ///the string value
+ StringBuffer(const TCHAR* value);
+ ///Constructs a StringBuffer using another buffer. The StringBuffer can
+ ///the be used to easily manipulate the buffer.
+ StringBuffer(TCHAR* buf,int32_t maxlen, const bool consumeBuffer);
+ ///Destructor
+ ~StringBuffer();
+ ///Clears the Stringbuffer and resets it to it default empty state
+ void clear();
+
+ ///Appends a single character
+ void appendChar(const TCHAR chr);
+ ///Appends a copy of the string value
+ void append(const TCHAR* value);
+ ///Appends a copy of the string value
+ void append(const TCHAR* value, size_t appendedLength);
+ ///Appends an integer (after conversion to a character string)
+ void appendInt(const int32_t value);
+ ///Appends a qreal (after conversion to a character string)
+ void appendFloat(const qreal value, const int32_t digits);
+ ///Puts a copy of the string value in front of the current string in the StringBuffer
+ void prepend(const TCHAR* value);
+ ///Puts a copy of the string value in front of the current string in the StringBuffer
+ void prepend(const TCHAR* value, size_t prependedLength);
+
+ ///Contains the length of string in the StringBuffer
+ ///Public so that analyzers can edit the length directly
+ int32_t len;
+ ///Returns the length of the string in the StringBuffer
+ int32_t length() const;
+ ///Returns a copy of the current string in the StringBuffer
+ TCHAR* toString();
+ ///Returns a null terminated reference to the StringBuffer's text
+ TCHAR* getBuffer();
+
+
+ ///reserve a minimum amount of data for the buffer.
+ ///no change made if the buffer is already longer than length
+ void reserve(const int32_t length);
+ private:
+ ///A buffer that contains strings
+ TCHAR* buffer;
+ ///The length of the buffer
+ int32_t bufferLength;
+ bool bufferOwner;
+
+ ///Has the buffer grown to a minimum length of minLength or bigger
+ void growBuffer(const int32_t minLength);
+ ///Has the buffer grown to a minimum length of minLength or bigger and shifts the
+ ///current string in buffer by skippingNInitialChars forward
+ void growBuffer(const int32_t minLength, const int32_t skippingNInitialChars);
+
+ };
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/StringIntern.cpp b/3rdparty/clucene/src/CLucene/util/StringIntern.cpp
new file mode 100644
index 000000000..cb7a889d1
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/StringIntern.cpp
@@ -0,0 +1,158 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "StringIntern.h"
+CL_NS_DEF(util)
+
+ __wcsintrntype::iterator wblank;
+ bool blanksinitd=false;
+ __wcsintrntype CLStringIntern::stringPool(true);
+ __strintrntype CLStringIntern::stringaPool(true);
+ DEFINE_MUTEX(CLStringIntern::THIS_LOCK)
+
+ void CLStringIntern::shutdown(){
+ #ifdef _DEBUG
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+ if ( stringaPool.size() > 0 ){
+ printf("ERROR: stringaPool still contains intern'd strings (refcounts):\n");
+ __strintrntype::iterator itr = stringaPool.begin();
+ while ( itr != stringaPool.end() ){
+ printf(" %s (%d)\n",(itr->first), (itr->second));
+ ++itr;
+ }
+ }
+
+ if ( stringPool.size() > 0 ){
+ printf("ERROR: stringPool still contains intern'd strings (refcounts):\n");
+ __wcsintrntype::iterator itr = stringPool.begin();
+ while ( itr != stringPool.end() ){
+ _tprintf(_T(" %s (%d)\n"),(itr->first), (itr->second));
+ ++itr;
+ }
+ }
+ #endif
+ }
+
+ const TCHAR* CLStringIntern::intern(const TCHAR* str CL_FILELINEPARAM){
+ if ( str == NULL )
+ return NULL;
+ if ( str[0] == 0 )
+ return LUCENE_BLANK_STRING;
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ __wcsintrntype::iterator itr = stringPool.find(str);
+ if ( itr==stringPool.end() ){
+#ifdef _UCS2
+ TCHAR* ret = lucenewcsdup(str CL_FILELINEREF);
+#else
+ TCHAR* ret = lucenestrdup(str CL_FILELINEREF);
+#endif
+ stringPool[ret]= 1;
+ return ret;
+ }else{
+ (itr->second)++;
+ return itr->first;
+ }
+ }
+
+ bool CLStringIntern::unintern(const TCHAR* str){
+ if ( str == NULL )
+ return false;
+ if ( str[0] == 0 )
+ return false;
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ __wcsintrntype::iterator itr = stringPool.find(str);
+ if ( itr != stringPool.end() ){
+ if ( (itr->second) == 1 ){
+ stringPool.removeitr(itr);
+ return true;
+ }else
+ (itr->second)--;
+ }
+ return false;
+ }
+
+ const char* CLStringIntern::internA(const char* str CL_FILELINEPARAM){
+ if ( str == NULL )
+ return NULL;
+ if ( str[0] == 0 )
+ return _LUCENE_BLANK_ASTRING;
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ __strintrntype::iterator itr = stringaPool.find(str);
+ if ( itr==stringaPool.end() ){
+ char* ret = lucenestrdup(str CL_FILELINE);
+ stringaPool[ret] = 1;
+ return ret;
+ }else{
+ (itr->second)++;
+ return itr->first;
+ }
+ }
+
+ bool CLStringIntern::uninternA(const char* str){
+ if ( str == NULL )
+ return false;
+ if ( str[0] == 0 )
+ return false;
+
+ SCOPED_LOCK_MUTEX(THIS_LOCK)
+
+ __strintrntype::iterator itr = stringaPool.find(str);
+ if ( itr!=stringaPool.end() ){
+ if ( (itr->second) == 1 ){
+ stringaPool.removeitr(itr);
+ return true;
+ }else
+ (itr->second)--;
+ }
+ return false;
+ }
+
+ /* removed because of multi-threading problems...
+ __wcsintrntype::iterator CLStringIntern::internitr(const TCHAR* str CL_FILELINEPARAM){
+ if ( str[0] == 0 ){
+ if ( !blanksinitd ){
+ CLStringIntern::stringPool.put(LUCENE_BLANK_STRING,1);
+ wblank=stringPool.find(str);
+ blanksinitd=true;
+ }
+ return wblank;
+ }
+ __wcsintrntype::iterator itr = stringPool.find(str);
+ if (itr==stringPool.end()){
+#ifdef _UCS2
+ TCHAR* ret = lucenewcsdup(str CL_FILELINEREF);
+#else
+ TCHAR* ret = lucenestrdup(str CL_FILELINEREF);
+#endif
+ stringPool.put(ret,1);
+ return stringPool.find(str);
+ }else{
+ (itr->second)++;
+ return itr;
+ }
+ }
+ bool CLStringIntern::uninternitr(__wcsintrntype::iterator itr){
+ if ( itr!=stringPool.end() ){
+ if ( itr==wblank )
+ return false;
+ if ( (itr->second) == 1 ){
+ stringPool.removeitr(itr);
+ return true;
+ }else
+ (itr->second)--;
+ }
+ return false;
+ }
+*/
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/util/StringIntern.h b/3rdparty/clucene/src/CLucene/util/StringIntern.h
new file mode 100644
index 000000000..ded060c64
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/StringIntern.h
@@ -0,0 +1,61 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_StringIntern_H
+#define _lucene_util_StringIntern_H
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "VoidMap.h"
+CL_NS_DEF(util)
+typedef CL_NS(util)::CLHashMap<const TCHAR*,int,CL_NS(util)::Compare::TChar,CL_NS(util)::Equals::TChar,CL_NS(util)::Deletor::tcArray, CL_NS(util)::Deletor::DummyInt32 > __wcsintrntype;
+typedef CL_NS(util)::CLHashMap<const char*,int,CL_NS(util)::Compare::Char,CL_NS(util)::Equals::Char,CL_NS(util)::Deletor::acArray, CL_NS(util)::Deletor::DummyInt32 > __strintrntype;
+
+ /** Functions for intern'ing strings. This
+ * is a process of pooling strings thus using less memory,
+ * and furthermore allows intern'd strings to be directly
+ * compared:
+ * string1==string2, rather than _tcscmp(string1,string2)
+ */
+ class CLStringIntern{
+ static __wcsintrntype stringPool;
+ static __strintrntype stringaPool;
+ STATIC_DEFINE_MUTEX(THIS_LOCK)
+ public:
+ /**
+ * Internalise the specified string.
+ * \return Returns a pointer to the internalised string
+ */
+ static const char* internA(const char* str CL_FILELINEPARAM);
+ /**
+ * Uninternalise the specified string. Decreases
+ * the reference count and frees the string if
+ * reference count is zero
+ * \returns true if string was destroyed, otherwise false
+ */
+ static bool uninternA(const char* str);
+
+ /**
+ * Internalise the specified string.
+ * \return Returns a pointer to the internalised string
+ */
+ static const TCHAR* intern(const TCHAR* str CL_FILELINEPARAM);
+
+ /**
+ * Uninternalise the specified string. Decreases
+ * the reference count and frees the string if
+ * reference count is zero
+ * \returns true if string was destroyed, otherwise false
+ */
+ static bool unintern(const TCHAR* str);
+
+ static void shutdown();
+ };
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/ThreadLocal.cpp b/3rdparty/clucene/src/CLucene/util/ThreadLocal.cpp
new file mode 100644
index 000000000..a54c86916
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/ThreadLocal.cpp
@@ -0,0 +1,55 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+#include "CLucene/LuceneThreads.h"
+#include "ThreadLocal.h"
+
+CL_NS_DEF(util)
+
+DEFINE_MUTEX(ThreadLocalBase::ThreadLocalBase_THIS_LOCK)
+
+ThreadLocalBase::ShutdownHooksType ThreadLocalBase::shutdownHooks(false);
+ThreadLocalBase::ThreadLocalsType ThreadLocalBase::threadLocals(false,false);
+
+ThreadLocalBase::ThreadLocalBase(){
+}
+ThreadLocalBase::~ThreadLocalBase(){
+}
+
+void ThreadLocalBase::UnregisterCurrentThread(){
+ _LUCENE_THREADID_TYPE id = _LUCENE_CURRTHREADID;
+ SCOPED_LOCK_MUTEX(ThreadLocalBase_THIS_LOCK)
+
+ ThreadLocalsType::iterator itr = threadLocals.lower_bound(id);
+ ThreadLocalsType::iterator end = threadLocals.upper_bound(id);
+ while ( itr != end ){
+ itr->second->setNull();
+ ++itr;
+ }
+}
+void ThreadLocalBase::shutdown(){
+ SCOPED_LOCK_MUTEX(ThreadLocalBase_THIS_LOCK)
+
+ ThreadLocalsType::iterator itr = threadLocals.begin();
+ while ( itr != threadLocals.end() ){
+ itr->second->setNull();
+ ++itr;
+ }
+
+ ShutdownHooksType::iterator itr2 = shutdownHooks.begin();
+ while ( itr2 != shutdownHooks.end() ){
+ ShutdownHook* hook = *itr2;
+ hook(false);
+ }
+}
+void ThreadLocalBase::registerShutdownHook(ShutdownHook* hook){
+ SCOPED_LOCK_MUTEX(ThreadLocalBase_THIS_LOCK)
+ shutdownHooks.insert(hook);
+}
+
+
+CL_NS_END
diff --git a/3rdparty/clucene/src/CLucene/util/ThreadLocal.h b/3rdparty/clucene/src/CLucene/util/ThreadLocal.h
new file mode 100644
index 000000000..f67c76ca9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/ThreadLocal.h
@@ -0,0 +1,143 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_ThreadLocal_H
+#define _lucene_util_ThreadLocal_H
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "CLucene/util/VoidMap.h"
+
+CL_NS_DEF(util)
+
+class ThreadLocalBase: LUCENE_BASE{
+public:
+ /**
+ * A hook called when CLucene is starting or shutting down,
+ * this can be used for setting up and tearing down static
+ * variables
+ */
+ typedef void ShutdownHook(bool startup);
+
+protected:
+ STATIC_DEFINE_MUTEX(ThreadLocalBase_THIS_LOCK)
+ typedef CL_NS(util)::CLMultiMap<_LUCENE_THREADID_TYPE, ThreadLocalBase*,
+ CL_NS(util)::CLuceneThreadIdCompare,
+ CL_NS(util)::Deletor::ConstNullVal<_LUCENE_THREADID_TYPE>,
+ CL_NS(util)::Deletor::ConstNullVal<ThreadLocalBase*> > ThreadLocalsType;
+ static ThreadLocalsType threadLocals;
+ //todo: using http://en.wikipedia.org/wiki/Thread-local_storage#Pthreads_implementation
+ //would work better... but lots of testing would be needed first...
+ typedef CL_NS(util)::CLSetList<ShutdownHook*,
+ CL_NS(util)::Compare::Void<ShutdownHook>,
+ CL_NS(util)::Deletor::ConstNullVal<ShutdownHook*> > ShutdownHooksType;
+ static ShutdownHooksType shutdownHooks;
+
+ ThreadLocalBase();
+public:
+ virtual ~ThreadLocalBase();
+
+ /**
+ * Call this function to clear the local thread data for this
+ * ThreadLocal. Calling set(NULL) does the same thing, except
+ * this function is virtual and can be called without knowing
+ * the template.
+ */
+ virtual void setNull() = 0;
+
+ /**
+ * If you want to clean up thread specific memory, then you should
+ * make sure this thread is called when the thread is not going to be used
+ * again. This will clean up threadlocal data which can contain quite a lot
+ * of data, so if you are creating lots of new threads, then it is a good idea
+ * to use this function, otherwise there will be many memory leaks.
+ */
+ static void UnregisterCurrentThread();
+
+ /**
+ * Call this function to shutdown CLucene
+ */
+ static void shutdown();
+
+ /**
+ * Add this function to the shutdown hook list. This function will be called
+ * when CLucene is shutdown.
+ */
+ static void registerShutdownHook(ShutdownHook* hook);
+};
+
+template<typename T,typename _deletor>
+class ThreadLocal: public ThreadLocalBase{
+ typedef CL_NS(util)::CLSet<_LUCENE_THREADID_TYPE, T,
+ CL_NS(util)::CLuceneThreadIdCompare,
+ CL_NS(util)::Deletor::ConstNullVal<_LUCENE_THREADID_TYPE>,
+ _deletor > LocalsType;
+ LocalsType locals;
+ DEFINE_MUTEX(locals_LOCK)
+public:
+ ThreadLocal();
+ ~ThreadLocal();
+ T get();
+ void setNull();
+ void set(T t);
+};
+
+template<typename T,typename _deletor>
+ThreadLocal<T,_deletor>::ThreadLocal():
+ locals(false,true)
+{
+ //add this object to the base's list of threadlocals to be
+ //notified in case of UnregisterThread()
+ _LUCENE_THREADID_TYPE id = _LUCENE_CURRTHREADID;
+ SCOPED_LOCK_MUTEX(ThreadLocalBase_THIS_LOCK)
+ threadLocals.insert( CL_NS_STD(pair)<const _LUCENE_THREADID_TYPE, ThreadLocalBase*>(id, this) );
+}
+
+template<typename T,typename _deletor>
+ThreadLocal<T,_deletor>::~ThreadLocal(){
+ //remove this object to the base's list of threadlocals
+ _LUCENE_THREADID_TYPE id = _LUCENE_CURRTHREADID;
+ SCOPED_LOCK_MUTEX(ThreadLocalBase_THIS_LOCK)
+
+ //remove all the thread local data for this object
+ locals.clear();
+
+ //remove this object from the ThreadLocalBase threadLocal list
+ ThreadLocalsType::iterator itr = threadLocals.lower_bound(id);
+ ThreadLocalsType::iterator end = threadLocals.upper_bound(id);
+ while ( itr != end ){
+ if ( itr->second == this){
+ threadLocals.erase(itr);
+ break;
+ }
+ ++itr;
+ }
+}
+
+template<typename T,typename _deletor>
+T ThreadLocal<T,_deletor>::get(){
+ return locals.get(_LUCENE_CURRTHREADID);
+}
+
+template<typename T,typename _deletor>
+void ThreadLocal<T,_deletor>::setNull(){
+ set(NULL);
+}
+
+template<typename T,typename _deletor>
+void ThreadLocal<T,_deletor>::set(T t){
+ _LUCENE_THREADID_TYPE id = _LUCENE_CURRTHREADID;
+ locals.remove(id);
+ if ( t != NULL )
+ locals.insert( CL_NS_STD(pair)<const _LUCENE_THREADID_TYPE,T>(id, t) );
+}
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/VoidList.h b/3rdparty/clucene/src/CLucene/util/VoidList.h
new file mode 100644
index 000000000..cd6908876
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/VoidList.h
@@ -0,0 +1,175 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_VoidList_
+#define _lucene_util_VoidList_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include "Equators.h"
+
+CL_NS_DEF(util)
+
+/**
+* A template to encapsulate various list type classes
+* @internal
+*/
+template<typename _kt,typename _base,typename _valueDeletor>
+class __CLList:public _base,LUCENE_BASE {
+private:
+ bool dv;
+ typedef _base base;
+public:
+ DEFINE_MUTEX(THIS_LOCK)
+
+ typedef typename _base::const_iterator const_iterator;
+ typedef typename _base::iterator iterator;
+
+ virtual ~__CLList(){
+ clear();
+ }
+
+ __CLList ( const bool deleteValue ):
+ dv(deleteValue)
+ {
+ }
+
+ void setDoDelete(bool val){ dv=val; }
+
+ //sets array to the contents of this array.
+ //array must be size+1, otherwise memory may be overwritten
+ void toArray(_kt* into) const{
+ int i=0;
+ for ( const_iterator itr=base::begin();itr!=base::end();itr++ ){
+ into[i] = *itr;
+ i++;
+ }
+ into[i] = NULL;
+ }
+
+ void set(int32_t i, _kt val) {
+ if ( dv )
+ _valueDeletor::doDelete((*this)[i]);
+ (*this)[i] = val;
+ }
+
+ //todo: check this
+ void delete_back(){
+ if ( base::size() > 0 ){
+ iterator itr = base::end();
+ if ( itr != base::begin())
+ itr --;
+ _kt key = *itr;
+ base::erase(itr);
+ if ( dv )
+ _valueDeletor::doDelete(key);
+ }
+ }
+
+ void delete_front(){
+ if ( base::size() > 0 ){
+ iterator itr = base::begin();
+ _kt key = *itr;
+ base::erase(itr);
+ if ( dv )
+ _valueDeletor::doDelete(key);
+ }
+ }
+
+ void clear(){
+ if ( dv ){
+ iterator itr = base::begin();
+ while ( itr != base::end() ){
+ _valueDeletor::doDelete(*itr);
+ ++itr;
+ }
+ }
+ base::clear();
+ }
+
+ void remove(int32_t i, bool dontDelete=false){
+ iterator itr=base::begin();
+ itr+=i;
+ _kt key = *itr;
+ base::erase( itr );
+ if ( dv && !dontDelete )
+ _valueDeletor::doDelete(key);
+ }
+ void remove(iterator itr, bool dontDelete=false){
+ _kt key = *itr;
+ base::erase( itr );
+ if ( dv && !dontDelete )
+ _valueDeletor::doDelete(key);
+ }
+
+};
+
+//growable arrays of Objects (like a collection or list)
+//a list, so can contain duplicates
+//it grows in chunks... todo: check jlucene for initial size of array, and growfactors
+template<typename _kt, typename _valueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLVector:public __CLList<_kt, CL_NS_STD(vector)<_kt> , _valueDeletor>
+{
+public:
+ CLVector ( const bool deleteValue=true ):
+ __CLList<_kt, CL_NS_STD(vector)<_kt> , _valueDeletor>(deleteValue)
+ {
+ }
+};
+
+//An array-backed implementation of the List interface
+//a list, so can contain duplicates
+//*** a very simple list - use <valarray>
+//(This class is roughly equivalent to Vector, except that it is unsynchronized.)
+#define CLArrayList CLVector
+#define CLHashSet CLHashList
+
+//implementation of the List interface, provides access to the first and last list elements in O(1)
+//no comparator is required... and so can contain duplicates
+//a simple list with no comparator
+//*** a very simple list - use <list>
+#ifdef LUCENE_DISABLE_HASHING
+ #define CLHashList CLSetList
+#else
+
+template<typename _kt,
+ typename _Comparator=CL_NS(util)::Compare::TChar,
+ typename _valueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLHashList:public __CLList<_kt, CL_NS_HASHING(hash_set)<_kt,_Comparator> , _valueDeletor>
+{
+public:
+ CLHashList ( const bool deleteValue=true ):
+ __CLList<_kt, CL_NS_HASHING(hash_set)<_kt,_Comparator> , _valueDeletor>(deleteValue)
+ {
+ }
+};
+#endif
+
+template<typename _kt, typename _valueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLLinkedList:public __CLList<_kt, CL_NS_STD(list)<_kt> , _valueDeletor>
+{
+public:
+ CLLinkedList ( const bool deleteValue=true ):
+ __CLList<_kt, CL_NS_STD(list)<_kt> , _valueDeletor>(deleteValue)
+ {
+ }
+};
+template<typename _kt,
+ typename _Comparator=CL_NS(util)::Compare::TChar,
+ typename _valueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLSetList:public __CLList<_kt, CL_NS_STD(set)<_kt,_Comparator> , _valueDeletor>
+{
+public:
+ CLSetList ( const bool deleteValue=true ):
+ __CLList<_kt, CL_NS_STD(set)<_kt,_Comparator> , _valueDeletor>(deleteValue)
+ {
+ }
+};
+
+CL_NS_END
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/VoidMap.h b/3rdparty/clucene/src/CLucene/util/VoidMap.h
new file mode 100644
index 000000000..b22b507e9
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/VoidMap.h
@@ -0,0 +1,270 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef _lucene_util_VoidMap_
+#define _lucene_util_VoidMap_
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+
+CL_NS_DEF(util)
+
+/**
+* A template to encapsulate various map type classes
+* @internal
+*/
+template<typename _kt, typename _vt,
+ typename _base,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+class __CLMap:public _base,LUCENE_BASE {
+private:
+ bool dk;
+ bool dv;
+ typedef _base base;
+public:
+ DEFINE_MUTEX(THIS_LOCK)
+
+ typedef typename _base::iterator iterator;
+ typedef typename _base::const_iterator const_iterator;
+ typedef CL_NS_STD(pair)<_kt, _vt> _pair;
+
+ ///Default constructor for the __CLMap
+ __CLMap ():
+ dk(true),
+ dv(true)
+ {
+ }
+
+ ///Deconstructor for the __CLMap
+ ~__CLMap (){
+ clear();
+ }
+
+ void setDeleteKey(bool val){ dk = val; }
+ void setDeleteValue(bool val){ dv = val; }
+
+ ///Construct the VoidMap and set the deleteTypes to the specified values
+ ///\param deleteKey if true then the key variable is deleted when an object is deleted
+ ///\param keyDelType delete the key variable using the specified type
+ ///\param deleteValue if true then the value variable is deleted when an object is deleted
+ ///\param valueDelType delete the value variable using the specified type
+ /*__CLMap ( const bool deleteKey, const bool deleteValue ):
+ dk(deleteKey),
+ dv(deleteValue)
+ {
+ }*/
+
+ ///checks to see if the specified key exists
+ ///\param k the key to check for
+ ///\returns true if the key exists
+ bool exists(_kt k)const{
+ const_iterator itr = base::find(k);
+ bool ret = itr!=base::end();
+ return ret;
+ }
+
+ ///put the specified pair into the map. remove any old items first
+ ///\param k the key
+ ///\param v the value
+ void put(_kt k,_vt v){
+ //todo: check if this is always right!
+ //must should look through code, for
+ //cases where map is not unique!!!
+ if ( dk || dv )
+ remove(k);
+
+ //todo: replacing the old item might be quicker...
+
+ base::insert(_pair(k,v));
+ }
+
+
+ ///using a non-const key, get a non-const value
+ _vt get( _kt k) const {
+ const_iterator itr = base::find(k);
+ if ( itr==base::end() )
+ return _vt();
+ else
+ return itr->second;
+ }
+ ///using a non-const key, get the actual key
+ _kt getKey( _kt k) const {
+ const_iterator itr = base::find(k);
+ if ( itr==base::end() )
+ return _kt();
+ else
+ return itr->first;
+ }
+
+ void removeitr (iterator itr, const bool dontDeleteKey = false, const bool dontDeleteValue = false){
+ //delete key&val first. This prevents potential loops (deleting object removes itself)
+ _kt key = itr->first;
+ _vt val = itr->second;
+ base::erase(itr);
+
+ //keys & vals need to be deleted after erase, because the hashvalue is still needed
+ if ( dk && !dontDeleteKey )
+ _KeyDeletor::doDelete(key);
+ if ( dv && !dontDeleteValue )
+ _ValueDeletor::doDelete(val);
+ }
+ ///delete and optionally delete the specified key and associated value
+ void remove(_kt key, const bool dontDeleteKey = false, const bool dontDeleteValue = false){
+ iterator itr = base::find(key);
+ if ( itr!=base::end() )
+ removeitr(itr,dontDeleteKey,dontDeleteValue);
+ }
+
+ ///clear all keys and values in the map
+ void clear(){
+ if ( dk || dv ){
+ iterator itr = base::begin();
+ while ( itr!=base::end() ){
+ #ifdef _CL_HAVE_EXT_HASH_MAP
+ removeitr(itr);
+ itr = base::begin();
+
+ #else
+ if ( dk )
+ _KeyDeletor::doDelete(itr->first);
+ if ( dv )
+ _ValueDeletor::doDelete(itr->second);
+ ++itr;
+
+ #endif
+ }
+ }
+ base::clear();
+ }
+};
+
+// makes no guarantees as to the order of the map
+// cannot contain duplicate keys; each key can map to at most one value
+#define CLHashtable CLHashMap
+
+#if defined(_CL_HAVE_GOOGLE_DENSE_HASH_MAP)
+//do nothing
+#elif defined(LUCENE_DISABLE_HASHING)
+
+ //a CLSet with CLHashMap traits
+template<typename _kt, typename _vt,
+ typename _Compare,
+ typename _EqualDummy,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLHashMap:public __CLMap<_kt,_vt,
+ CL_NS_STD(map)<_kt,_vt, _Compare>,
+ _KeyDeletor,_ValueDeletor>
+{
+ typedef typename CL_NS_STD(map)<_kt,_vt,_Compare> _base;
+ typedef __CLMap<_kt, _vt, CL_NS_STD(map)<_kt,_vt, _Compare>,
+ _KeyDeletor,_ValueDeletor> _this;
+public:
+ CLHashMap ( const bool deleteKey=false, const bool deleteValue=false )
+ {
+ _this::setDeleteKey(deleteKey);
+ _this::setDeleteValue(deleteValue);
+ }
+};
+#elif defined(_CL_HAVE_EXT_HASH_MAP)
+ //ext/hash_map syntax
+//HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized
+template<typename _kt, typename _vt,
+ typename _Hasher,
+ typename _Equals,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLHashMap:public __CLMap<_kt,_vt,
+ CL_NS_HASHING(hash_map)<_kt,_vt, _Hasher,_Equals>,
+ _KeyDeletor,_ValueDeletor>
+{
+ typedef __CLMap<_kt,_vt, CL_NS_HASHING(hash_map)<_kt,_vt, _Hasher,_Equals>,
+ _KeyDeletor,_ValueDeletor> _this;
+public:
+ CLHashMap ( const bool deleteKey=false, const bool deleteValue=false )
+ {
+ _this::setDeleteKey(deleteKey);
+ _this::setDeleteValue(deleteValue);
+ }
+};
+
+#else
+//HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized
+template<typename _kt, typename _vt,
+ typename _Hasher,
+ typename _Equals,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLHashMap:public __CLMap<_kt,_vt,
+ CL_NS_HASHING(hash_map)<_kt,_vt, _Hasher>,
+ _KeyDeletor,_ValueDeletor>
+{
+ typedef __CLMap<_kt,_vt, CL_NS_HASHING(hash_map)<_kt,_vt, _Hasher>,
+ _KeyDeletor,_ValueDeletor> _this;
+public:
+ CLHashMap ( const bool deleteKey=false, const bool deleteValue=false )
+ {
+ _this::setDeleteKey(deleteKey);
+ _this::setDeleteValue(deleteValue);
+ }
+};
+#endif
+
+//A collection that contains no duplicates
+//does not guarantee that the order will remain constant over time
+template<typename _kt, typename _vt,
+ typename _Compare,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLSet:public __CLMap<_kt,_vt,
+ CL_NS_STD(map)<_kt,_vt, _Compare>,
+ _KeyDeletor,_ValueDeletor>
+{
+ typedef typename CL_NS_STD(map)<_kt,_vt,_Compare> _base;
+ typedef __CLMap<_kt, _vt, CL_NS_STD(map)<_kt,_vt, _Compare>,
+ _KeyDeletor,_ValueDeletor> _this;
+public:
+ CLSet ( const bool deleteKey=false, const bool deleteValue=false )
+ {
+ _this::setDeleteKey(deleteKey);
+ _this::setDeleteValue(deleteValue);
+ }
+};
+
+
+//A collection that can contains duplicates
+template<typename _kt, typename _vt,
+ typename _Compare,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+class CLMultiMap:public __CLMap<_kt,_vt,
+ CL_NS_STD(multimap)<_kt,_vt>,
+ _KeyDeletor,_ValueDeletor>
+{
+ typedef typename CL_NS_STD(multimap)<_kt,_vt> _base;
+ typedef __CLMap<_kt, _vt, CL_NS_STD(multimap)<_kt,_vt>,
+ _KeyDeletor,_ValueDeletor> _this;
+public:
+ CLMultiMap ( const bool deleteKey=false, const bool deleteValue=false )
+ {
+ _this::setDeleteKey(deleteKey);
+ _this::setDeleteValue(deleteValue);
+ }
+};
+
+
+//*** need to create a class that allows duplicates - use <set>
+//#define CLSet __CLMap
+CL_NS_END
+
+#ifdef _CL_HAVE_GOOGLE_DENSE_HASH_MAP
+#include "GoogleSparseMap.h"
+#endif
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/bufferedstream.h b/3rdparty/clucene/src/CLucene/util/bufferedstream.h
new file mode 100644
index 000000000..d905955b1
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/bufferedstream.h
@@ -0,0 +1,157 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Jos van den Oever
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+/* This file is part of Strigi Desktop Search
+ *
+ * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef BUFFEREDSTREAM_H
+#define BUFFEREDSTREAM_H
+
+#include "streambase.h"
+#include "inputstreambuffer.h"
+
+#include <cassert>
+#include <stdio.h>
+
+namespace jstreams {
+
+template <class T>
+class BufferedInputStream : public StreamBase<T> {
+private:
+ bool finishedWritingToBuffer;
+ InputStreamBuffer<T> buffer;
+
+ void writeToBuffer(int32_t minsize);
+ int32_t read_(const T*& start, int32_t min, int32_t max);
+protected:
+ /**
+ * This function must be implemented by the subclasses.
+ * It should write a maximum of @p space characters at the buffer
+ * position pointed to by @p start. If no more data is available due to
+ * end of file, -1 should be returned. If an error occurs, the status
+ * should be set to Error, an error message should be set and the function
+ * must return -1.
+ **/
+ virtual int32_t fillBuffer(T* start, int32_t space) = 0;
+ // this function might be useful if you want to reuse a bufferedstream
+ void resetBuffer() {printf("implement 'resetBuffer'\n");}
+ BufferedInputStream<T>();
+public:
+ int32_t read(const T*& start, int32_t min, int32_t max);
+ int64_t reset(int64_t);
+ virtual int64_t skip(int64_t ntoskip);
+};
+
+template <class T>
+BufferedInputStream<T>::BufferedInputStream() {
+ finishedWritingToBuffer = false;
+}
+
+template <class T>
+void
+BufferedInputStream<T>::writeToBuffer(int32_t ntoread) {
+ int32_t missing = ntoread - buffer.avail;
+ int32_t nwritten = 0;
+ while (missing > 0 && nwritten >= 0) {
+ int32_t space;
+ space = buffer.makeSpace(missing);
+ T* start = buffer.readPos + buffer.avail;
+ nwritten = fillBuffer(start, space);
+ assert(StreamBase<T>::status != Eof);
+ if (nwritten > 0) {
+ buffer.avail += nwritten;
+ missing = ntoread - buffer.avail;
+ }
+ }
+ if (nwritten < 0) {
+ finishedWritingToBuffer = true;
+ }
+}
+template <class T>
+int32_t
+BufferedInputStream<T>::read(const T*& start, int32_t min, int32_t max) {
+ if (StreamBase<T>::status == Error) return -2;
+ if (StreamBase<T>::status == Eof) return -1;
+
+ // do we need to read data into the buffer?
+ if (!finishedWritingToBuffer && min > buffer.avail) {
+ // do we have enough space in the buffer?
+ writeToBuffer(min);
+ if (StreamBase<T>::status == Error) return -2;
+ }
+
+ int32_t nread = buffer.read(start, max);
+
+ BufferedInputStream<T>::position += nread;
+ if (BufferedInputStream<T>::position > BufferedInputStream<T>::size
+ && BufferedInputStream<T>::size > 0) {
+ // error: we read more than was specified in size
+ // this is an error because all dependent code might have been labouring
+ // under a misapprehension
+ BufferedInputStream<T>::status = Error;
+ BufferedInputStream<T>::error = "Stream is longer than specified.";
+ nread = -2;
+ } else if (BufferedInputStream<T>::status == Ok && buffer.avail == 0
+ && finishedWritingToBuffer) {
+ BufferedInputStream<T>::status = Eof;
+ if (BufferedInputStream<T>::size == -1) {
+ BufferedInputStream<T>::size = BufferedInputStream<T>::position;
+ }
+ // save one call to read() by already returning -1 if no data is there
+ if (nread == 0) nread = -1;
+ }
+ return nread;
+}
+template <class T>
+int64_t
+BufferedInputStream<T>::reset(int64_t newpos) {
+ if (StreamBase<T>::status == Error) return -2;
+ // check to see if we have this position
+ int64_t d = BufferedInputStream<T>::position - newpos;
+ if (buffer.readPos - d >= buffer.start && -d < buffer.avail) {
+ BufferedInputStream<T>::position -= d;
+ buffer.avail += (int32_t)d;
+ buffer.readPos -= d;
+ StreamBase<T>::status = Ok;
+ }
+ return StreamBase<T>::position;
+}
+template <class T>
+int64_t
+BufferedInputStream<T>::skip(int64_t ntoskip) {
+ const T *begin;
+ int32_t nread;
+ int64_t skipped = 0;
+ while (ntoskip) {
+ int32_t step = (int32_t)((ntoskip > buffer.size) ?buffer.size :ntoskip);
+ nread = read(begin, 1, step);
+ if (nread <= 0) {
+ return skipped;
+ }
+ ntoskip -= nread;
+ skipped += nread;
+ }
+ return skipped;
+}
+}
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/dirent.cpp b/3rdparty/clucene/src/CLucene/util/dirent.cpp
new file mode 100644
index 000000000..3c5c54200
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/dirent.cpp
@@ -0,0 +1,221 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Matt J. Weinstein
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#include "CLucene/StdHeader.h"
+
+#if !defined(_CL_HAVE_DIRENT_H) && !defined(_CL_HAVE_SYS_NDIR_H) && !defined(_CL_HAVE_SYS_DIR_H) && !defined(_CL_HAVE_NDIR_H)
+#include "dirent.h"
+
+DIR *
+opendir (const char *szPath)
+{
+ DIR *nd;
+ char szFullPath[CL_MAX_PATH];
+
+ errno = 0;
+
+ if (!szPath)
+ {
+ errno = EFAULT;
+ return NULL;
+ }
+
+ if (szPath[0] == '\0')
+ {
+ errno = ENOTDIR;
+ return NULL;
+ }
+
+ /* Attempt to determine if the given path really is a directory. */
+ struct _stat rcs;
+ if ( _stat(szPath,&rcs) == -1)
+ {
+ /* call GetLastError for more error info */
+ errno = ENOENT;
+ return NULL;
+ }
+ if (!(rcs.st_mode & _S_IFDIR))
+ {
+ /* Error, entry exists but not a directory. */
+ errno = ENOTDIR;
+ return NULL;
+ }
+
+ /* Make an absolute pathname. */
+ _realpath(szPath,szFullPath);
+
+ /* Allocate enough space to store DIR structure and the complete
+ * directory path given. */
+ //nd = (DIR *) malloc (sizeof (DIR) + _tcslen (szFullPath) + _tcslen (DIRENT_SLASH) +
+ // _tcslen (DIRENT_SEARCH_SUFFIX)+1);
+ nd = new DIR;
+
+ if (!nd)
+ {
+ /* Error, out of memory. */
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ /* Create the search expression. */
+ strcpy (nd->dd_name, szFullPath);
+
+ /* Add on a slash if the path does not end with one. */
+ if (nd->dd_name[0] != '\0' &&
+ nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
+ nd->dd_name[strlen (nd->dd_name) - 1] != '\\')
+ {
+ strcat (nd->dd_name, DIRENT_SLASH);
+ }
+
+ /* Add on the search pattern */
+ strcat (nd->dd_name, DIRENT_SEARCH_SUFFIX);
+
+ /* Initialize handle to -1 so that a premature closedir doesn't try
+ * to call _findclose on it. */
+ nd->dd_handle = -1;
+
+ /* Initialize the status. */
+ nd->dd_stat = 0;
+
+ /* Initialize the dirent structure. ino and reclen are invalid under
+ * Win32, and name simply points at the appropriate part of the
+ * findfirst_t structure. */
+ //nd->dd_dir.d_ino = 0;
+ //nd->dd_dir.d_reclen = 0;
+ nd->dd_dir.d_namlen = 0;
+ nd->dd_dir.d_name = nd->dd_dta.name;
+
+ return nd;
+}
+
+
+struct dirent * readdir (DIR * dirp)
+{
+ errno = 0;
+
+ /* Check for valid DIR struct. */
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return NULL;
+ }
+
+ if (dirp->dd_dir.d_name != dirp->dd_dta.name)
+ {
+ /* The structure does not seem to be set up correctly. */
+ errno = EINVAL;
+ return NULL;
+ }
+
+ bool bCallFindNext = true;
+
+ if (dirp->dd_stat < 0)
+ {
+ /* We have already returned all files in the directory
+ * (or the structure has an invalid dd_stat). */
+ return NULL;
+ }
+ else if (dirp->dd_stat == 0)
+ {
+ /* We haven't started the search yet. */
+ /* Start the search */
+ dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
+
+ if (dirp->dd_handle == -1)
+ {
+ /* Whoops! Seems there are no files in that
+ * directory. */
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ dirp->dd_stat = 1;
+ }
+
+ /* Dont call _findnext first time. */
+ bCallFindNext = false;
+ }
+
+ while (dirp->dd_stat > 0)
+ {
+ if (bCallFindNext)
+ {
+ /* Get the next search entry. */
+ if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
+ {
+ /* We are off the end or otherwise error. */
+ _findclose (dirp->dd_handle);
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ return NULL;
+ }
+ else
+ {
+ /* Update the status to indicate the correct
+ * number. */
+ dirp->dd_stat++;
+ }
+ }
+
+ /* Successfully got an entry. Everything about the file is
+ * already appropriately filled in except the length of the
+ * file name. */
+ dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
+
+ bool bThisFolderOrUpFolder = dirp->dd_dir.d_name[0] == '.' &&
+ (dirp->dd_dir.d_name[1] == 0 || (dirp->dd_dir.d_name[1] == '.' && dirp->dd_dir.d_name[2] == 0));
+
+ if (!bThisFolderOrUpFolder)
+ {
+ struct _stat buf;
+ char buffer[CL_MAX_DIR];
+ size_t bl = strlen(dirp->dd_name)-strlen(DIRENT_SEARCH_SUFFIX);
+ strncpy(buffer,dirp->dd_name,bl);
+ buffer[bl]=0;
+ strcat(buffer, dirp->dd_dir.d_name);
+ if ( _stat(buffer,&buf) == 0 )
+ {
+ /* Finally we have a valid entry. */
+ return &dirp->dd_dir;
+ }
+ }
+
+ /* Allow to find next file. */
+ bCallFindNext = true;
+ }
+
+ return NULL;
+}
+
+
+
+int32_t
+closedir (DIR * dirp)
+{
+ int32_t rc;
+
+ errno = 0;
+ rc = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ rc = _findclose (dirp->dd_handle);
+ }
+
+ /* Delete the dir structure. */
+ _CLVDELETE(dirp);
+
+ return rc;
+}
+#endif //HAVE_DIRENT_H
+
diff --git a/3rdparty/clucene/src/CLucene/util/dirent.h b/3rdparty/clucene/src/CLucene/util/dirent.h
new file mode 100644
index 000000000..71cd34c0a
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/dirent.h
@@ -0,0 +1,105 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Matt J. Weinstein
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+#ifndef lucene_util_dirent_H
+#define lucene_util_dirent_H
+
+#if defined(_LUCENE_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#if !defined(_CL_HAVE_DIRENT_H) && !defined(_CL_HAVE_SYS_NDIR_H) && !defined(_CL_HAVE_SYS_DIR_H) && !defined(_CL_HAVE_NDIR_H)
+
+/**
+\unit
+ * dirent.c
+ *
+ * Derived from DIRLIB.C by Matt J. Weinstein
+ * This note appears in the DIRLIB.H
+ * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
+ *
+ * Updated by Jeremy Bettis <jeremy@hksys.com>
+ * Significantly revised and rewinddir, seekdir and telldir added by Colin
+ * Cut down again & changed by Ben van Klinken
+ * Peters <colin@fu.is.saga-u.ac.jp>
+ *
+ */
+
+/** dirent structure - used by the dirent.h directory iteration functions */
+struct dirent
+{
+ unsigned short d_namlen; /* Length of name in d_name. */
+ char *d_name; /* File name. */
+};
+
+/** DIR structure - used by the dirent.h directory iteration functions*/
+struct DIR
+{
+ /** disk transfer area for this dir */
+ struct _finddata_t dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct dirent dd_dir;
+
+ /** _findnext handle */
+ intptr_t dd_handle;
+
+ /**
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ int32_t dd_stat;
+
+ /** given path for dir with search pattern (struct is extended) */
+ char dd_name[CL_MAX_DIR];
+
+};
+
+#define DIRENT_SEARCH_SUFFIX "*"
+#define DIRENT_SLASH PATH_DELIMITERA
+
+
+/**
+* Returns a pointer to a DIR structure appropriately filled in to begin
+* searching a directory.
+*/
+DIR* opendir (const char* filespec);
+
+/**
+* Return a pointer to a dirent structure filled with the information on the
+* next entry in the directory.
+*/
+struct dirent* readdir (DIR* dir);
+
+/**
+* Frees up resources allocated by opendir.
+*/
+int32_t closedir (DIR* dir);
+
+
+#elif defined (_CL_HAVE_DIRENT_H)
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if defined(_CL_HAVE_SYS_NDIR_H)
+# include <sys/ndir.h>
+# endif
+# if defined(_CL_HHAVE_SYS_DIR_H)
+# include <sys/dir.h>
+# endif
+# if defined(_CL_HHAVE_NDIR_H)
+# include <ndir.h>
+# endif
+
+#endif //HAVE_DIRENT_H
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/fileinputstream.cpp b/3rdparty/clucene/src/CLucene/util/fileinputstream.cpp
new file mode 100644
index 000000000..9125d8478
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/fileinputstream.cpp
@@ -0,0 +1,103 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Jos van den Oever
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+/* This file is part of Strigi Desktop Search
+ *
+ * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "jstreamsconfig.h"
+#include "fileinputstream.h"
+
+#ifndef UNDER_CE
+#include <cerrno>
+#endif
+#include <cstring>
+namespace jstreams {
+
+const int32_t FileInputStream::defaultBufferSize = 1048576;
+FileInputStream::FileInputStream(const char *filepath, int32_t buffersize) {
+ // try to open the file for reading
+ file = fopen(filepath, "rb");
+ this->filepath = filepath;
+ if (file == 0) {
+ // handle error
+ error = "Could not read file '";
+ error += filepath;
+ error += "': ";
+#ifndef UNDER_CE
+ error += strerror(errno);
+#endif
+ status = Error;
+ return;
+ }
+ // determine file size. if the stream is not seekable, the size will be -1
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ // if the file has size 0, make sure that it's really empty
+ // this is useful for filesystems like /proc that report files as size 0
+ // for files that do contain content
+ if (size == 0) {
+ char dummy[1];
+ size_t n = fread(dummy, 1, 1, file);
+ if (n == 1) {
+ size = -1;
+ fseek(file, 0, SEEK_SET);
+ } else {
+ fclose(file);
+ file = 0;
+ return;
+ }
+ }
+
+ // allocate memory in the buffer
+ int32_t bufsize = (size <= buffersize) ?size+1 :buffersize;
+ mark(bufsize);
+}
+FileInputStream::~FileInputStream() {
+ if (file) {
+ if (fclose(file)) {
+ // handle error
+ error = "Could not close file '" + filepath + "'.";
+ }
+ }
+}
+int32_t
+FileInputStream::fillBuffer(char* start, int32_t space) {
+ if (file == 0) return -1;
+ // read into the buffer
+ int32_t nwritten = fread(start, 1, space, file);
+ // check the file stream status
+ if (ferror(file)) {
+ error = "Could not read from file '" + filepath + "'.";
+ fclose(file);
+ file = 0;
+ status = Error;
+ return -1;
+ }
+ if (feof(file)) {
+ fclose(file);
+ file = 0;
+ }
+ return nwritten;
+}
+}
diff --git a/3rdparty/clucene/src/CLucene/util/fileinputstream.h b/3rdparty/clucene/src/CLucene/util/fileinputstream.h
new file mode 100644
index 000000000..144423da8
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/fileinputstream.h
@@ -0,0 +1,38 @@
+/**
+ * Copyright 2003-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef FILEINPUTSTREAM_H
+#define FILEINPUTSTREAM_H
+
+#include "bufferedstream.h"
+
+namespace jstreams {
+
+class FileInputStream : public BufferedInputStream<char> {
+private:
+ FILE *file;
+ std::string filepath;
+
+public:
+ static const int32_t defaultBufferSize;
+ FileInputStream(const char *filepath, int32_t buffersize=defaultBufferSize);
+ ~FileInputStream();
+ int32_t fillBuffer(char* start, int32_t space);
+};
+
+} // end namespace jstreams
+
+#endif
+
diff --git a/3rdparty/clucene/src/CLucene/util/inputstreambuffer.h b/3rdparty/clucene/src/CLucene/util/inputstreambuffer.h
new file mode 100644
index 000000000..873e811cd
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/inputstreambuffer.h
@@ -0,0 +1,126 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Jos van den Oever
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+/* This file is part of Strigi Desktop Search
+ *
+ * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INPUTSTREAMBUFFER_H
+#define INPUTSTREAMBUFFER_H
+
+#include <cstdlib>
+
+namespace jstreams {
+
+template <class T>
+class InputStreamBuffer {
+private:
+public:
+ T* start;
+ int32_t size;
+ T* readPos;
+ int32_t avail;
+
+ InputStreamBuffer();
+ ~InputStreamBuffer();
+ void setSize(int32_t size);
+ int32_t read(const T*& start, int32_t max=0);
+
+ /**
+ * This function prepares the buffer for a new write.
+ * returns the number of available places.
+ **/
+ int32_t makeSpace(int32_t needed);
+};
+
+template <class T>
+InputStreamBuffer<T>::InputStreamBuffer() {
+ readPos = start = 0;
+ size = avail = 0;
+}
+template <class T>
+InputStreamBuffer<T>::~InputStreamBuffer() {
+ free(start);
+}
+template <class T>
+void
+InputStreamBuffer<T>::setSize(int32_t size) {
+ // store pointer information
+ int32_t offset = (int32_t)(readPos - start);
+
+ // allocate memory in the buffer
+ if ( start == 0 )
+ start = (T*)malloc(size*sizeof(T));
+ else
+ start = (T*)realloc(start, size*sizeof(T));
+ this->size = size;
+
+ // restore pointer information
+ readPos = start + offset;
+}
+template <class T>
+int32_t
+InputStreamBuffer<T>::makeSpace(int32_t needed) {
+ // determine how much space is available for writing
+ int32_t space = size - ((int32_t)(readPos - start)) - avail;
+ if (space >= needed) {
+ // there's enough space
+ return space;
+ }
+
+ if (avail) {
+ if (readPos != start) {
+// printf("moving\n");
+ // move data to the start of the buffer
+ memmove(start, readPos, avail*sizeof(T));
+ space += (int32_t)(readPos - start);
+ readPos = start;
+ }
+ } else {
+ // we may start writing at the start of the buffer
+ readPos = start;
+ space = size;
+ }
+ if (space >= needed) {
+ // there's enough space now
+ return space;
+ }
+
+ // still not enough space, we have to allocate more
+// printf("resize %i %i %i %i %i\n", avail, needed, space, size + needed - space, size);
+ setSize(size + needed - space);
+ return needed;
+}
+template <class T>
+int32_t
+InputStreamBuffer<T>::read(const T*& start, int32_t max) {
+ start = readPos;
+ if (max <= 0 || max > avail) {
+ max = avail;
+ }
+ readPos += max;
+ avail -= max;
+ return max;
+}
+
+} // end namespace jstreams
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/jstreamsconfig.h b/3rdparty/clucene/src/CLucene/util/jstreamsconfig.h
new file mode 100644
index 000000000..2a6ce9f8d
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/jstreamsconfig.h
@@ -0,0 +1,9 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+
+//this is just a compatibility header for jstreams
+#include "CLucene/StdHeader.h"
diff --git a/3rdparty/clucene/src/CLucene/util/streambase.h b/3rdparty/clucene/src/CLucene/util/streambase.h
new file mode 100644
index 000000000..b0d9dc167
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/streambase.h
@@ -0,0 +1,148 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Jos van den Oever
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+*
+* Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+------------------------------------------------------------------------------*/
+/* This file is part of Strigi Desktop Search
+ *
+ * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef STREAMBASE_H
+#define STREAMBASE_H
+
+#include <string>
+
+#if defined(_BUILD_FOR_QT_)
+ #include "StdHeader.h"
+#endif
+
+#define INT32MAX 0x7FFFFFFFL
+
+namespace jstreams {
+
+enum StreamStatus { Ok, Eof, Error };
+
+/**
+ * @short Base class for stream read access to many different file types.
+ *
+ * This class is based on the interface java.io.InputStream. It allows
+ * for uniform access to streamed resources.
+ * The main difference with the java equivalent is a performance improvement.
+ * When reading data, data is not copied into a buffer provided by the caller,
+ * but a pointer to the read data is provided. This makes this interface
+ * especially useful for deriving from it and implementing filterers or
+ * transformers.
+ */
+// java mapping: long=int64, int=int32, byte=uint8_t
+template <class T>
+class StreamBase {
+protected:
+ int64_t size;
+ int64_t position;
+ std::string error;
+ StreamStatus status;
+public:
+ StreamBase() :size(-1), position(0), status(Ok){ }
+ virtual ~StreamBase(){}
+ /**
+ * @brief Return a string representation of the last error.
+ * If no error has occurred, an empty string is returned.
+ **/
+ const char* getError() const { return error.c_str(); }
+ StreamStatus getStatus() const { return status; }
+ /**
+ * @brief Get the current position in the stream.
+ * The value obtained from this function can be used to reset the stream.
+ **/
+ int64_t getPosition() const { return position; }
+ /**
+ * @brief Return the size of the stream.
+ * If the size of the stream is unknown, -1
+ * is returned. If the end of the stream has been reached the size is
+ * always known.
+ **/
+ int64_t getSize() const { return size; }
+ /**
+ * @brief Reads characters from the stream and sets \a start to
+ * the first character that was read.
+ *
+ * If @p ntoread is @c 0, then at least one character will be read.
+ *
+ * @param start Pointer passed by reference that will be set to point to
+ * the retrieved array of characters. If the end of the stream
+ * is encountered or an error occurs, the value of @p start
+ * is undefined.
+ * @param min The number of characters to read from the stream.
+ * @param max The maximum number of characters to read from the stream.
+ * @return the number of characters that were read. If -1 is returned, the
+ * end of the stream has been reached. If -2 is returned, an error
+ * has occurred.
+ **/
+ virtual int32_t read(const T*& start, int32_t min, int32_t max) = 0;
+ /**
+ * Skip @param ntoskip bytes. Unless an error occurs or the end of file is
+ * encountered, this amount of bytes is skipped.
+ * This function returns new position in the stream.
+ **/
+ virtual int64_t skip(int64_t ntoskip);
+ /**
+ * @brief Repositions this stream to given requested position.
+ * Reset is guaranteed to work after a successful call to read(),
+ * when the new position is in the range of the data returned by read().
+ * This means that @p pos must lie between than the position
+ * corresponding to the start parameter (x) of the read function
+ * and the position corresponding to the last position in the returned
+ * buffer (x + nread).
+ **/
+ virtual int64_t reset(int64_t pos) = 0;
+ int64_t mark(int32_t readlimit) {
+ int64_t p = getPosition();
+ const T* ptr;
+ read(ptr, readlimit, -1);
+ return reset(p);
+ }
+};
+#define SKIPSTEP 1024
+template <class T>
+int64_t
+StreamBase<T>::skip(int64_t ntoskip) {
+ const T *begin;
+ int32_t nread;
+ int64_t skipped = 0;
+ while (ntoskip) {
+ int32_t step = (int32_t)((ntoskip > SKIPSTEP) ?SKIPSTEP :ntoskip);
+ nread = read(begin, 1, step);
+ if (nread < -1 ) {
+ // an error occurred
+ return nread;
+ } else if (nread < 1) {
+ ntoskip = 0;
+ } else {
+ skipped += nread;
+ ntoskip -= nread;
+ }
+ }
+ return skipped;
+}
+
+} // end namespace jstreams
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/stringreader.h b/3rdparty/clucene/src/CLucene/util/stringreader.h
new file mode 100644
index 000000000..698d07e37
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/stringreader.h
@@ -0,0 +1,124 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Jos van den Oever
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+/* This file is part of Strigi Desktop Search
+ *
+ * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef STRINGREADER_H
+#define STRINGREADER_H
+
+/**
+ * Author: Jos van den Oever
+ * Ben van Klinken
+ **/
+
+
+#include "streambase.h"
+
+namespace jstreams {
+
+template <class T>
+class StringReader : public StreamBase<T> {
+private:
+ int64_t markpt;
+ T* data;
+ bool dataowner;
+ StringReader(const StringReader<T>&);
+ void operator=(const StringReader<T>&);
+public:
+ StringReader(const T* value, int32_t length = -1, bool copy = true);
+ ~StringReader();
+ int32_t read(const T*& start, int32_t min, int32_t max);
+ int64_t skip(int64_t ntoskip);
+ int64_t reset(int64_t pos);
+};
+
+typedef StringReader<char> StringInputStream;
+
+template <class T>
+StringReader<T>::StringReader(const T* value, int32_t length, bool copy)
+ : markpt(0), dataowner(copy) {
+ if (length < 0) {
+ length = 0;
+ while (value[length] != '\0') {
+ length++;
+ }
+ }
+ StreamBase<T>::size = length;
+ if (copy) {
+ data = new T[length+1];
+ size_t s = (size_t)(length*sizeof(T));
+ memcpy(data, value, s);
+ data[length] = 0;
+ } else {
+ // casting away const is ok, because we don't write anyway
+ data = (T*)value;
+ }
+}
+template <class T>
+StringReader<T>::~StringReader() {
+ if (dataowner) {
+ delete [] data;
+ }
+}
+template <class T>
+int32_t
+StringReader<T>::read(const T*& start, int32_t min, int32_t max) {
+ int64_t left = StreamBase<T>::size - StreamBase<T>::position;
+ if (left == 0) {
+ StreamBase<T>::status = Eof;
+ return -1;
+ }
+ if (min < 0) min = 0;
+ int32_t nread = (int32_t)((max > left || max < 1) ?left :max);
+ start = data + StreamBase<T>::position;
+ StreamBase<T>::position += nread;
+ if (StreamBase<T>::position == StreamBase<T>::size) {
+ StreamBase<T>::status = Eof;
+ }
+ return nread;
+}
+template <class T>
+int64_t
+StringReader<T>::skip(int64_t ntoskip) {
+ const T* start;
+ return read(start, ntoskip, ntoskip);
+}
+template <class T>
+int64_t
+StringReader<T>::reset(int64_t newpos) {
+ if (newpos < 0) {
+ StreamBase<T>::status = Ok;
+ StreamBase<T>::position = 0;
+ } else if (newpos < StreamBase<T>::size) {
+ StreamBase<T>::status = Ok;
+ StreamBase<T>::position = newpos;
+ } else {
+ StreamBase<T>::position = StreamBase<T>::size;
+ StreamBase<T>::status = Eof;
+ }
+ return StreamBase<T>::position;
+}
+
+} // end namespace jstreams
+
+#endif
diff --git a/3rdparty/clucene/src/CLucene/util/subinputstream.h b/3rdparty/clucene/src/CLucene/util/subinputstream.h
new file mode 100644
index 000000000..8ae3e33c7
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/util/subinputstream.h
@@ -0,0 +1,141 @@
+/*------------------------------------------------------------------------------
+* Copyright (C) 2003-2006 Jos van den Oever
+*
+* Distributable under the terms of either the Apache License (Version 2.0) or
+* the GNU Lesser General Public License, as specified in the COPYING file.
+------------------------------------------------------------------------------*/
+/* This file is part of Strigi Desktop Search
+ *
+ * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef SUBINPUTSTREAM_H
+#define SUBINPUTSTREAM_H
+
+#include "streambase.h"
+
+namespace jstreams {
+
+template<class T>
+class SubInputStream : public StreamBase<T> {
+private:
+ const int64_t offset;
+ StreamBase<T> *input;
+public:
+ SubInputStream(StreamBase<T> *input, int64_t size=-1);
+ int32_t read(const T*& start, int32_t min, int32_t max);
+ int64_t reset(int64_t newpos);
+ int64_t skip(int64_t ntoskip);
+};
+template<class T>
+SubInputStream<T>::SubInputStream(StreamBase<T> *i, int64_t length)
+ : offset(i->getPosition()), input(i) {
+ assert(length >= -1);
+// printf("substream offset: %lli\n", offset);
+ StreamBase<T>::size = length;
+}
+
+template<class T>
+int32_t SubInputStream<T>::read(const T*& start, int32_t min, int32_t max) {
+ if (StreamBase<T>::size != -1) {
+ const int64_t left = StreamBase<T>::size - StreamBase<T>::position;
+ if (left == 0) {
+ return -1;
+ }
+ // restrict the amount of data that can be read
+ if (max <= 0 || max > left) {
+ max = (int32_t)left;
+ }
+ if (min > max) min = max;
+ if (left < min) min = (int32_t)left;
+ }
+ int32_t nread = input->read(start, min, max);
+ if (nread < -1) {
+ fprintf(stderr, "substream too short.\n");
+ StreamBase<T>::status = Error;
+ StreamBase<T>::error = input->getError();
+ } else if (nread < min) {
+ if (StreamBase<T>::size == -1) {
+ StreamBase<T>::status = Eof;
+ if (nread > 0) {
+ StreamBase<T>::position += nread;
+ StreamBase<T>::size = StreamBase<T>::position;
+ }
+ } else {
+// fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! nread %i min %i max %i size %lli\n", nread, min, max, size);
+// fprintf(stderr, "pos %lli parentpos %lli\n", position, input->getPosition());
+// fprintf(stderr, "status: %i error: %s\n", input->getStatus(), input->getError());
+ // we expected data but didn't get enough so that's an error
+ StreamBase<T>::status = Error;
+ StreamBase<T>::error = "Premature end of stream\n";
+ nread = -2;
+ }
+ } else {
+ StreamBase<T>::position += nread;
+ if (StreamBase<T>::position == StreamBase<T>::size) {
+ StreamBase<T>::status = Eof;
+ }
+ }
+ return nread;
+}
+
+template<class T>
+int64_t SubInputStream<T>::reset(int64_t newpos) {
+// fprintf(stderr, "subreset pos: %lli newpos: %lli offset: %lli\n", position,
+// newpos, offset);
+ StreamBase<T>::position = input->reset(newpos + offset);
+ if (StreamBase<T>::position < offset) {
+ printf("###########\n");
+ StreamBase<T>::status = Error;
+ StreamBase<T>::error = input->getError();
+ } else {
+ StreamBase<T>::position -= offset;
+ StreamBase<T>::status = input->getStatus();
+ }
+ return StreamBase<T>::position;
+}
+
+template<class T>
+int64_t SubInputStream<T>::skip(int64_t ntoskip) {
+// printf("subskip pos: %lli ntoskip: %lli offset: %lli\n", position, ntoskip, offset);
+ if (StreamBase<T>::size == StreamBase<T>::position) {
+ StreamBase<T>::status = Eof;
+ return -1;
+ }
+ if (StreamBase<T>::size != -1) {
+ const int64_t left = StreamBase<T>::size - StreamBase<T>::position;
+ // restrict the amount of data that can be skipped
+ if (ntoskip > left) {
+ ntoskip = left;
+ }
+ }
+ int64_t skipped = input->skip(ntoskip);
+ if (input->getStatus() == Error) {
+ StreamBase<T>::status = Error;
+ StreamBase<T>::error = input->getError();
+ } else {
+ StreamBase<T>::position += skipped;
+ if (StreamBase<T>::position == StreamBase<T>::size) {
+ StreamBase<T>::status = Eof;
+ }
+ }
+ return skipped;
+}
+
+} //end namespace jstreams
+
+#endif
diff --git a/demos/arthurplugin/arthur_plugin.qrc b/demos/arthurplugin/arthur_plugin.qrc
new file mode 100644
index 000000000..e5170e63c
--- /dev/null
+++ b/demos/arthurplugin/arthur_plugin.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/arthurplugin">
+ <file>bg1.jpg</file>
+ <file>flower.jpg</file>
+ <file>flower_alpha.jpg</file>
+</qresource>
+</RCC>
diff --git a/demos/arthurplugin/arthurplugin.pro b/demos/arthurplugin/arthurplugin.pro
new file mode 100644
index 000000000..c5132b469
--- /dev/null
+++ b/demos/arthurplugin/arthurplugin.pro
@@ -0,0 +1,54 @@
+
+QTDIR = $$QT_SOURCE_TREE
+
+CONFIG += designer plugin
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(arthurplugin)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/designer
+
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+
+SHARED_FOLDER = ../shared
+include(../shared/shared.pri)
+
+DEMO_DEFORM_DIR = ../deform
+DEMO_AFFINE_DIR = ../affine
+DEMO_GRADIENT_DIR = ../gradients
+DEMO_STROKE_DIR = ../pathstroke
+DEMO_COMPOSITION_DIR = ../composition
+
+INCLUDEPATH += $$DEMO_DEFORM_DIR $$DEMO_AFFINE_DIR $$DEMO_GRADIENT_DIR $$DEMO_STROKE_DIR $$DEMO_COMPOSITION_DIR
+
+SOURCES = plugin.cpp \
+ $$DEMO_COMPOSITION_DIR/composition.cpp \
+ $$DEMO_AFFINE_DIR/xform.cpp \
+ $$DEMO_DEFORM_DIR/pathdeform.cpp \
+ $$DEMO_GRADIENT_DIR/gradients.cpp \
+ $$DEMO_STROKE_DIR/pathstroke.cpp \
+
+
+HEADERS = \
+ $$DEMO_COMPOSITION_DIR/composition.h \
+ $$DEMO_AFFINE_DIR/xform.h \
+ $$DEMO_DEFORM_DIR/pathdeform.h \
+ $$DEMO_GRADIENT_DIR/gradients.h \
+ $$DEMO_STROKE_DIR/pathstroke.h \
+
+RESOURCES += arthur_plugin.qrc
+
+# install
+target.path = $$[QT_INSTALL_PLUGINS]/designer
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.jpg *.png
+sources.path = $$[QT_INSTALL_DEMOS]/qttools/arthurplugin
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+
+win32-msvc* {
+ QMAKE_CFLAGS += /Zm500
+ QMAKE_CXXFLAGS += /Zm500
+}
+
diff --git a/demos/arthurplugin/bg1.jpg b/demos/arthurplugin/bg1.jpg
new file mode 100644
index 000000000..dfc7cee6a
--- /dev/null
+++ b/demos/arthurplugin/bg1.jpg
Binary files differ
diff --git a/demos/arthurplugin/flower.jpg b/demos/arthurplugin/flower.jpg
new file mode 100644
index 000000000..f8e022c98
--- /dev/null
+++ b/demos/arthurplugin/flower.jpg
Binary files differ
diff --git a/demos/arthurplugin/flower_alpha.jpg b/demos/arthurplugin/flower_alpha.jpg
new file mode 100644
index 000000000..6a3c2a02e
--- /dev/null
+++ b/demos/arthurplugin/flower_alpha.jpg
Binary files differ
diff --git a/demos/arthurplugin/plugin.cpp b/demos/arthurplugin/plugin.cpp
new file mode 100644
index 000000000..336e88da6
--- /dev/null
+++ b/demos/arthurplugin/plugin.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <QtGui/QPixmap>
+
+#include "xform.h"
+#include "pathdeform.h"
+#include "gradients.h"
+#include "pathstroke.h"
+#include "hoverpoints.h"
+#include "composition.h"
+
+QT_FORWARD_DECLARE_CLASS(QDesignerFormEditorInterface)
+
+// Specify "text" to be a singleline property (no richtext)
+static inline QString textSingleLinePropertyDeclaration(const QString &className)
+{
+ QString rc = QLatin1String(
+ "<customwidgets>\n"
+ " <customwidget>\n"
+ " <class>");
+ rc += className;
+ rc += QLatin1String("</class>\n"
+ " <propertyspecifications>\n"
+ " <stringpropertyspecification name=\"text\" type=\"singleline\"/>\n"
+ " </propertyspecifications>\n"
+ " </customwidget>\n"
+ "</customwidgets>\n");
+ return rc;
+}
+
+// Plain XML for a custom widget
+static inline QString customWidgetDomXml(const QString &className,
+ const QString &customSection = QString())
+{
+ QString rc = QLatin1String("<ui language=\"c++\"><widget class=\"");
+ rc += className;
+ rc += QLatin1String("\" name=\"");
+ QString objectName = className;
+ objectName[0] = objectName.at(0).toLower();
+ rc += objectName;
+ rc += QLatin1String("\"/>");
+ rc += customSection;
+ rc += QLatin1String("</ui>");
+ return rc;
+}
+
+class PathDeformRendererEx : public PathDeformRenderer
+{
+ Q_OBJECT
+public:
+ PathDeformRendererEx(QWidget *parent) : PathDeformRenderer(parent) { }
+ QSize sizeHint() const { return QSize(300, 200); }
+};
+
+class DemoPlugin : public QDesignerCustomWidgetInterface
+{
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+
+protected:
+ explicit DemoPlugin(const QString &className, const QString &customSection = QString());
+
+public:
+ QString name() const { return m_className; }
+ bool isContainer() const { return false; }
+ bool isInitialized() const { return m_initialized; }
+ QIcon icon() const { return QIcon(); }
+ QString codeTemplate() const { return QString(); }
+ QString whatsThis() const { return QString(); }
+ QString toolTip() const { return QString(); }
+ QString group() const { return "Arthur Widgets [Demo]"; }
+ void initialize(QDesignerFormEditorInterface *)
+ {
+ if (m_initialized)
+ return;
+ m_initialized = true;
+ }
+ QString domXml() const { return m_domXml; }
+
+private:
+ const QString m_className;
+ const QString m_domXml;
+ bool m_initialized;
+};
+
+DemoPlugin::DemoPlugin(const QString &className, const QString &customSection) :
+ m_className(className),
+ m_domXml(customWidgetDomXml(className, customSection)),
+ m_initialized(false)
+{
+}
+
+class DeformPlugin : public QObject, public DemoPlugin
+{
+ Q_OBJECT
+
+public:
+ explicit DeformPlugin(QObject *parent = 0);
+ QString includeFile() const { return QLatin1String("deform.h"); }
+
+ QWidget *createWidget(QWidget *parent)
+ {
+ PathDeformRenderer *deform = new PathDeformRendererEx(parent);
+ deform->setRadius(70);
+ deform->setAnimated(false);
+ deform->setFontSize(20);
+ deform->setText(QLatin1String("Arthur Widgets Demo"));
+
+ return deform;
+ }
+};
+
+DeformPlugin::DeformPlugin(QObject *parent) :
+ QObject(parent),
+ DemoPlugin(QLatin1String("PathDeformRendererEx"),
+ textSingleLinePropertyDeclaration(QLatin1String("PathDeformRendererEx")))
+{
+}
+
+class XFormRendererEx : public XFormView
+{
+ Q_OBJECT
+public:
+ XFormRendererEx(QWidget *parent) : XFormView(parent) {}
+ QSize sizeHint() const { return QSize(300, 200); }
+};
+
+class XFormPlugin : public QObject, public DemoPlugin
+{
+ Q_OBJECT
+public:
+ explicit XFormPlugin(QObject *parent = 0);
+ QString includeFile() const { return QLatin1String("xform.h"); }
+
+ QWidget *createWidget(QWidget *parent)
+ {
+ XFormRendererEx *xform = new XFormRendererEx(parent);
+ xform->setText(QLatin1String("Qt - Hello World!!"));
+ xform->setPixmap(QPixmap(QLatin1String(":/trolltech/arthurplugin/bg1.jpg")));
+ return xform;
+ }
+};
+
+XFormPlugin::XFormPlugin(QObject *parent) :
+ QObject(parent),
+ DemoPlugin(QLatin1String("XFormRendererEx"),
+ textSingleLinePropertyDeclaration(QLatin1String("XFormRendererEx")))
+{
+}
+
+class GradientEditorPlugin : public QObject, public DemoPlugin
+{
+ Q_OBJECT
+public:
+ explicit GradientEditorPlugin(QObject *parent = 0) : QObject(parent), DemoPlugin(QLatin1String("GradientEditor")) { }
+ QString includeFile() const { return "gradients.h"; }
+
+ QWidget *createWidget(QWidget *parent)
+ {
+ GradientEditor *editor = new GradientEditor(parent);
+ return editor;
+ }
+};
+
+class GradientRendererEx : public GradientRenderer
+{
+ Q_OBJECT
+public:
+ GradientRendererEx(QWidget *p) : GradientRenderer(p) { }
+ QSize sizeHint() const { return QSize(300, 200); }
+};
+
+class GradientRendererPlugin : public QObject, public DemoPlugin
+{
+ Q_OBJECT
+public:
+ GradientRendererPlugin(QObject *parent = 0) : QObject(parent), DemoPlugin(QLatin1String("GradientRendererEx")) { }
+ QString includeFile() const { return QLatin1String("gradients.h"); }
+
+ QWidget *createWidget(QWidget *parent)
+ {
+ GradientRenderer *renderer = new GradientRendererEx(parent);
+ renderer->setConicalGradient();
+ return renderer;
+ }
+};
+
+class PathStrokeRendererEx : public PathStrokeRenderer
+{
+ Q_OBJECT
+public:
+ explicit PathStrokeRendererEx(QWidget *p) : PathStrokeRenderer(p) { }
+ QSize sizeHint() const { return QSize(300, 200); }
+};
+
+class StrokeRenderPlugin : public QObject, public DemoPlugin
+{
+ Q_OBJECT
+public:
+ explicit StrokeRenderPlugin(QObject *parent = 0) : QObject(parent), DemoPlugin(QLatin1String("PathStrokeRendererEx")) { }
+ QString includeFile() const { return QLatin1String("pathstroke.h"); }
+
+ QWidget *createWidget(QWidget *parent)
+ {
+ PathStrokeRenderer *stroke = new PathStrokeRendererEx(parent);
+ return stroke;
+ }
+};
+
+
+class CompositionModePlugin : public QObject, public DemoPlugin
+{
+ Q_OBJECT
+public:
+ explicit CompositionModePlugin(QObject *parent = 0) : QObject(parent), DemoPlugin(QLatin1String("CompositionRenderer")) { }
+ QString includeFile() const { return QLatin1String("composition.h"); }
+
+ QWidget *createWidget(QWidget *parent)
+ {
+ CompositionRenderer *renderer = new CompositionRenderer(parent);
+ renderer->setAnimationEnabled(false);
+ return renderer;
+ }
+};
+
+
+class ArthurPlugins : public QObject, public QDesignerCustomWidgetCollectionInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
+
+public:
+ explicit ArthurPlugins(QObject *parent = 0);
+ QList<QDesignerCustomWidgetInterface*> customWidgets() const { return m_plugins; }
+
+private:
+ QList<QDesignerCustomWidgetInterface *> m_plugins;
+};
+
+ArthurPlugins::ArthurPlugins(QObject *parent) :
+ QObject(parent)
+{
+ m_plugins << new DeformPlugin(this)
+ << new XFormPlugin(this)
+ << new GradientEditorPlugin(this)
+ << new GradientRendererPlugin(this)
+ << new StrokeRenderPlugin(this)
+ << new CompositionModePlugin(this);
+}
+
+#include "plugin.moc"
+
+Q_EXPORT_PLUGIN2(ArthurPlugins, ArthurPlugins)
diff --git a/demos/shared/arthurstyle.cpp b/demos/shared/arthurstyle.cpp
new file mode 100644
index 000000000..e8e8a0201
--- /dev/null
+++ b/demos/shared/arthurstyle.cpp
@@ -0,0 +1,452 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "arthurstyle.h"
+#include "arthurwidgets.h"
+#include <QLayout>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPixmapCache>
+#include <QRadioButton>
+#include <QString>
+#include <QStyleOption>
+#include <QtDebug>
+
+QPixmap cached(const QString &img)
+{
+ if (QPixmap *p = QPixmapCache::find(img))
+ return *p;
+
+ QPixmap pm;
+ pm = QPixmap::fromImage(QImage(img), Qt::OrderedDither | Qt::OrderedAlphaDither);
+ if (pm.isNull())
+ return QPixmap();
+
+ QPixmapCache::insert(img, pm);
+ return pm;
+}
+
+
+ArthurStyle::ArthurStyle()
+ : QWindowsStyle()
+{
+ Q_INIT_RESOURCE(shared);
+}
+
+
+void ArthurStyle::drawHoverRect(QPainter *painter, const QRect &r) const
+{
+ qreal h = r.height();
+ qreal h2 = r.height() / qreal(2);
+ QPainterPath path;
+ path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height());
+ path.addEllipse(r.x(), r.y(), h, h);
+ path.addEllipse(r.x() + r.width() - h, r.y(), h, h);
+ path.setFillRule(Qt::WindingFill);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(QColor(191, 215, 191));
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->drawPath(path);
+}
+
+
+void ArthurStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+
+ Q_ASSERT(option);
+ switch (element) {
+ case PE_FrameFocusRect:
+ break;
+
+ case PE_IndicatorRadioButton:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
+ painter->save();
+ QPixmap radio;
+ if (hover)
+ drawHoverRect(painter, widget->rect());
+
+ if (button->state & State_Sunken)
+ radio = cached(":res/images/radiobutton-on.png");
+ else if (button->state & State_On)
+ radio = cached(":res/images/radiobutton_on.png");
+ else
+ radio = cached(":res/images/radiobutton_off.png");
+ painter->drawPixmap(button->rect.topLeft(), radio);
+
+ painter->restore();
+ }
+ break;
+
+ case PE_PanelButtonCommand:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
+
+ painter->save();
+ const QPushButton *pushButton = qobject_cast<const QPushButton *>(widget);
+ Q_ASSERT(pushButton);
+ QWidget *parent = pushButton->parentWidget();
+ if (parent && qobject_cast<QGroupBox *>(parent)) {
+ QLinearGradient lg(0, 0, 0, parent->height());
+ lg.setColorAt(0, QColor(224,224,224));
+ lg.setColorAt(1, QColor(255,255,255));
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(lg);
+ painter->setBrushOrigin(-widget->mapToParent(QPoint(0,0)));
+ painter->drawRect(button->rect);
+ painter->setBrushOrigin(0,0);
+ }
+
+ bool down = (button->state & State_Sunken) || (button->state & State_On);
+
+ QPixmap left, right, mid;
+ if (down) {
+ left = cached(":res/images/button_pressed_cap_left.png");
+ right = cached(":res/images/button_pressed_cap_right.png");
+ mid = cached(":res/images/button_pressed_stretch.png");
+ } else {
+ left = cached(":res/images/button_normal_cap_left.png");
+ right = cached(":res/images/button_normal_cap_right.png");
+ mid = cached(":res/images/button_normal_stretch.png");
+ }
+ painter->drawPixmap(button->rect.topLeft(), left);
+ painter->drawTiledPixmap(QRect(button->rect.x() + left.width(),
+ button->rect.y(),
+ button->rect.width() - left.width() - right.width(),
+ left.height()),
+ mid);
+ painter->drawPixmap(button->rect.x() + button->rect.width() - right.width(),
+ button->rect.y(),
+ right);
+ if (hover)
+ painter->fillRect(widget->rect().adjusted(3,5,-3,-5), QColor(31,127,31,63));
+ painter->restore();
+ }
+ break;
+
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrameV2 *group
+ = qstyleoption_cast<const QStyleOptionFrameV2 *>(option)) {
+ const QRect &r = group->rect;
+
+ painter->save();
+ int radius = 14;
+ int radius2 = radius*2;
+ QPainterPath clipPath;
+ clipPath.moveTo(radius, 0);
+ clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
+ clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
+ clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
+ clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
+ painter->setClipPath(clipPath);
+ QPixmap titleStretch = cached(":res/images/title_stretch.png");
+ QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
+ QPixmap topRight = cached(":res/images/groupframe_topright.png");
+ QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
+ QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
+ QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
+ QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
+ QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
+ QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
+ QLinearGradient lg(0, 0, 0, r.height());
+ lg.setColorAt(0, QColor(224,224,224));
+ lg.setColorAt(1, QColor(255,255,255));
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(lg);
+ painter->drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
+ painter->setClipping(false);
+
+ int topFrameOffset = titleStretch.height()/2 - 2;
+ painter->drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
+ painter->drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0)
+ + QPoint(0, topFrameOffset), topRight);
+ painter->drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
+ painter->drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1,
+ bottomRight.height()-1), bottomRight);
+
+ QRect left = r;
+ left.setY(r.y() + topLeft.height() + topFrameOffset);
+ left.setWidth(leftStretch.width());
+ left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
+ painter->drawTiledPixmap(left, leftStretch);
+
+ QRect top = r;
+ top.setX(r.x() + topLeft.width());
+ top.setY(r.y() + topFrameOffset);
+ top.setWidth(r.width() - topLeft.width() - topRight.width());
+ top.setHeight(topLeft.height());
+ painter->drawTiledPixmap(top, topStretch);
+
+ QRect right = r;
+ right.setX(r.right() - rightStretch.width()+1);
+ right.setY(r.y() + topRight.height() + topFrameOffset);
+ right.setWidth(rightStretch.width());
+ right.setHeight(r.height() - topRight.height()
+ - bottomRight.height() - topFrameOffset);
+ painter->drawTiledPixmap(right, rightStretch);
+
+ QRect bottom = r;
+ bottom.setX(r.x() + bottomLeft.width());
+ bottom.setY(r.bottom() - bottomStretch.height()+1);
+ bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
+ bottom.setHeight(bottomLeft.height());
+ painter->drawTiledPixmap(bottom, bottomStretch);
+ painter->restore();
+ }
+ break;
+
+ default:
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+ return;
+}
+
+
+void ArthurStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ switch (control) {
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+ QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+
+ painter->save();
+
+ bool hover = (slider->state & State_Enabled) && (slider->state & State_MouseOver);
+ if (hover) {
+ QRect moderated = widget->rect().adjusted(0, 4, 0, -4);
+ drawHoverRect(painter, moderated);
+ }
+
+ if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
+ QPixmap grv = cached(":res/images/slider_bar.png");
+ painter->drawPixmap(QRect(groove.x() + 5, groove.y(),
+ groove.width() - 10, grv.height()),
+ grv);
+ }
+ if ((option->subControls & SC_SliderHandle) && handle.isValid()) {
+ QPixmap hndl = cached(":res/images/slider_thumb_on.png");
+ painter->drawPixmap(handle.topLeft(), hndl);
+ }
+
+ painter->restore();
+ }
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox
+ = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ QStyleOptionGroupBox groupBoxCopy(*groupBox);
+ groupBoxCopy.subControls &= ~SC_GroupBoxLabel;
+ QWindowsStyle::drawComplexControl(control, &groupBoxCopy, painter, widget);
+
+ if (groupBox->subControls & SC_GroupBoxLabel) {
+ const QRect &r = groupBox->rect;
+ QPixmap titleLeft = cached(":res/images/title_cap_left.png");
+ QPixmap titleRight = cached(":res/images/title_cap_right.png");
+ QPixmap titleStretch = cached(":res/images/title_stretch.png");
+ int txt_width = groupBox->fontMetrics.width(groupBox->text) + 20;
+ painter->drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
+ QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
+ painter->drawTiledPixmap(tileRect, titleStretch);
+ painter->drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
+ int opacity = 31;
+ painter->setPen(QColor(0, 0, 0, opacity));
+ painter->drawText(tileRect.translated(0, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->drawText(tileRect.translated(2, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->setPen(QColor(0, 0, 0, opacity * 2));
+ painter->drawText(tileRect.translated(1, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->setPen(Qt::white);
+ painter->drawText(tileRect, Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ }
+ }
+ break;
+ default:
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+ return;
+}
+
+QRect ArthurStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ QRect rect;
+
+ switch (control) {
+ default:
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *group
+ = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ switch (subControl) {
+ default:
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ break;
+ case SC_GroupBoxContents:
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ rect.adjust(0, -8, 0, 0);
+ break;
+ case SC_GroupBoxFrame:
+ rect = group->rect;
+ break;
+ case SC_GroupBoxLabel:
+ QPixmap titleLeft = cached(":res/images/title_cap_left.png");
+ QPixmap titleRight = cached(":res/images/title_cap_right.png");
+ QPixmap titleStretch = cached(":res/images/title_stretch.png");
+ int txt_width = group->fontMetrics.width(group->text) + 20;
+ rect = QRect(group->rect.center().x() - txt_width/2 + titleLeft.width(), 0,
+ txt_width - titleLeft.width() - titleRight.width(),
+ titleStretch.height());
+ break;
+ }
+ }
+ break;
+ }
+
+ if (control == CC_Slider && subControl == SC_SliderHandle) {
+ rect.setWidth(13);
+ rect.setHeight(27);
+ } else if (control == CC_Slider && subControl == SC_SliderGroove) {
+ rect.setHeight(9);
+ rect.moveTop(27/2 - 9/2);
+ }
+ return rect;
+}
+
+QSize ArthurStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ QSize newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+
+
+ switch (type) {
+ case CT_RadioButton:
+ newSize += QSize(20, 0);
+ break;
+
+ case CT_PushButton:
+ newSize.setHeight(26);
+ break;
+
+ case CT_Slider:
+ newSize.setHeight(27);
+ break;
+
+ default:
+ break;
+ }
+
+ return newSize;
+}
+
+int ArthurStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
+{
+ if (pm == PM_SliderLength)
+ return 13;
+ return QWindowsStyle::pixelMetric(pm, opt, widget);
+}
+
+void ArthurStyle::polish(QWidget *widget)
+{
+ if (widget->layout() && qobject_cast<QGroupBox *>(widget)) {
+ if (widget->findChildren<QGroupBox *>().size() == 0) {
+ widget->layout()->setSpacing(0);
+ widget->layout()->setMargin(12);
+ } else {
+ widget->layout()->setMargin(13);
+ }
+ }
+
+ if (qobject_cast<QPushButton *>(widget)
+ || qobject_cast<QRadioButton *>(widget)
+ || qobject_cast<QSlider *>(widget)) {
+ widget->setAttribute(Qt::WA_Hover);
+ }
+
+ QPalette pal = widget->palette();
+ if (widget->isWindow()) {
+ pal.setColor(QPalette::Background, QColor(241, 241, 241));
+ widget->setPalette(pal);
+ }
+
+}
+
+void ArthurStyle::unpolish(QWidget *widget)
+{
+ if (qobject_cast<QPushButton *>(widget)
+ || qobject_cast<QRadioButton *>(widget)
+ || qobject_cast<QSlider *>(widget)) {
+ widget->setAttribute(Qt::WA_Hover, false);
+ }
+}
+
+void ArthurStyle::polish(QPalette &palette)
+{
+ palette.setColor(QPalette::Background, QColor(241, 241, 241));
+}
+
+QRect ArthurStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ QRect r;
+ switch(element) {
+ case SE_RadioButtonClickRect:
+ r = widget->rect();
+ break;
+ case SE_RadioButtonContents:
+ r = widget->rect().adjusted(20, 0, 0, 0);
+ break;
+ default:
+ r = QWindowsStyle::subElementRect(element, option, widget);
+ break;
+ }
+
+ if (qobject_cast<const QRadioButton*>(widget))
+ r = r.adjusted(5, 0, -5, 0);
+
+ return r;
+}
diff --git a/demos/shared/arthurstyle.h b/demos/shared/arthurstyle.h
new file mode 100644
index 000000000..9e3ada9b9
--- /dev/null
+++ b/demos/shared/arthurstyle.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ARTHURSTYLE_H
+#define ARTHURSTYLE_H
+
+#include <QWindowsStyle>
+
+QT_USE_NAMESPACE
+
+class ArthurStyle : public QWindowsStyle
+{
+public:
+ ArthurStyle();
+
+ void drawHoverRect(QPainter *painter, const QRect &rect) const;
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+// void drawControl(ControlElement element, const QStyleOption *option,
+// QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+// SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+// const QPoint &pos, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const;
+
+ void polish(QPalette &palette);
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+};
+
+#endif
diff --git a/demos/shared/arthurwidgets.cpp b/demos/shared/arthurwidgets.cpp
new file mode 100644
index 000000000..d6b8ccaba
--- /dev/null
+++ b/demos/shared/arthurwidgets.cpp
@@ -0,0 +1,371 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "arthurwidgets.h"
+#include <QApplication>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPixmapCache>
+#include <QtEvents>
+#include <QTextDocument>
+#include <QAbstractTextDocumentLayout>
+#include <QFile>
+#include <QTextBrowser>
+#include <QBoxLayout>
+
+#include <private/qpixmapdata_p.h>
+
+extern QPixmap cached(const QString &img);
+
+ArthurFrame::ArthurFrame(QWidget *parent)
+ : QWidget(parent)
+ , m_prefer_image(false)
+{
+#ifdef QT_OPENGL_SUPPORT
+ glw = 0;
+ m_use_opengl = false;
+ QGLFormat f = QGLFormat::defaultFormat();
+ f.setSampleBuffers(true);
+ f.setStencil(true);
+ f.setAlpha(true);
+ f.setAlphaBufferSize(8);
+ QGLFormat::setDefaultFormat(f);
+#endif
+ m_document = 0;
+ m_show_doc = false;
+
+ m_tile = QPixmap(128, 128);
+ m_tile.fill(Qt::white);
+ QPainter pt(&m_tile);
+ QColor color(230, 230, 230);
+ pt.fillRect(0, 0, 64, 64, color);
+ pt.fillRect(64, 64, 64, 64, color);
+ pt.end();
+
+// QPalette pal = palette();
+// pal.setBrush(backgroundRole(), m_tile);
+// setPalette(pal);
+
+#ifdef Q_WS_X11
+ QPixmap xRenderPixmap(1, 1);
+ m_prefer_image = xRenderPixmap.pixmapData()->classId() == QPixmapData::X11Class && !xRenderPixmap.x11PictureHandle();
+#endif
+}
+
+
+#ifdef QT_OPENGL_SUPPORT
+void ArthurFrame::enableOpenGL(bool use_opengl)
+{
+ m_use_opengl = use_opengl;
+
+ if (!glw) {
+ glw = new GLWidget(this);
+ glw->setAutoFillBackground(false);
+ glw->disableAutoBufferSwap();
+ QApplication::postEvent(this, new QResizeEvent(size(), size()));
+ }
+
+ if (use_opengl) {
+ glw->show();
+ } else {
+ glw->hide();
+ }
+
+ update();
+}
+#endif
+
+void ArthurFrame::paintEvent(QPaintEvent *e)
+{
+#ifdef Q_WS_QWS
+ static QPixmap *static_image = 0;
+#else
+ static QImage *static_image = 0;
+#endif
+ QPainter painter;
+ if (preferImage()
+#ifdef QT_OPENGL_SUPPORT
+ && !m_use_opengl
+#endif
+ ) {
+ if (!static_image || static_image->size() != size()) {
+ delete static_image;
+#ifdef Q_WS_QWS
+ static_image = new QPixmap(size());
+#else
+ static_image = new QImage(size(), QImage::Format_RGB32);
+#endif
+ }
+ painter.begin(static_image);
+
+ int o = 10;
+
+ QBrush bg = palette().brush(QPalette::Background);
+ painter.fillRect(0, 0, o, o, bg);
+ painter.fillRect(width() - o, 0, o, o, bg);
+ painter.fillRect(0, height() - o, o, o, bg);
+ painter.fillRect(width() - o, height() - o, o, o, bg);
+ } else {
+#ifdef QT_OPENGL_SUPPORT
+ if (m_use_opengl) {
+ painter.begin(glw);
+ painter.fillRect(QRectF(0, 0, glw->width(), glw->height()), palette().color(backgroundRole()));
+ } else {
+ painter.begin(this);
+ }
+#else
+ painter.begin(this);
+#endif
+ }
+
+ painter.setClipRect(e->rect());
+
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ QPainterPath clipPath;
+
+ QRect r = rect();
+ qreal left = r.x() + 1;
+ qreal top = r.y() + 1;
+ qreal right = r.right();
+ qreal bottom = r.bottom();
+ qreal radius2 = 8 * 2;
+
+ clipPath.moveTo(right - radius2, top);
+ clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90);
+ clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90);
+ clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90);
+ clipPath.arcTo(left, top, radius2, radius2, 180, -90);
+ clipPath.closeSubpath();
+
+ painter.save();
+ painter.setClipPath(clipPath, Qt::IntersectClip);
+
+ painter.drawTiledPixmap(rect(), m_tile);
+
+ // client painting
+
+ paint(&painter);
+
+ painter.restore();
+
+ painter.save();
+ if (m_show_doc)
+ paintDescription(&painter);
+ painter.restore();
+
+ int level = 180;
+ painter.setPen(QPen(QColor(level, level, level), 2));
+ painter.setBrush(Qt::NoBrush);
+ painter.drawPath(clipPath);
+
+ if (preferImage()
+#ifdef QT_OPENGL_SUPPORT
+ && !m_use_opengl
+#endif
+ ) {
+ painter.end();
+ painter.begin(this);
+#ifdef Q_WS_QWS
+ painter.drawPixmap(e->rect(), *static_image, e->rect());
+#else
+ painter.drawImage(e->rect(), *static_image, e->rect());
+#endif
+ }
+
+#ifdef QT_OPENGL_SUPPORT
+ if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
+ glw->swapBuffers();
+#endif
+}
+
+void ArthurFrame::resizeEvent(QResizeEvent *e)
+{
+#ifdef QT_OPENGL_SUPPORT
+ if (glw)
+ glw->setGeometry(0, 0, e->size().width()-1, e->size().height()-1);
+#endif
+ QWidget::resizeEvent(e);
+}
+
+void ArthurFrame::setDescriptionEnabled(bool enabled)
+{
+ if (m_show_doc != enabled) {
+ m_show_doc = enabled;
+ emit descriptionEnabledChanged(m_show_doc);
+ update();
+ }
+}
+
+void ArthurFrame::loadDescription(const QString &fileName)
+{
+ QFile textFile(fileName);
+ QString text;
+ if (!textFile.open(QFile::ReadOnly))
+ text = QString("Unable to load resource file: '%1'").arg(fileName);
+ else
+ text = textFile.readAll();
+ setDescription(text);
+}
+
+
+void ArthurFrame::setDescription(const QString &text)
+{
+ m_document = new QTextDocument(this);
+ m_document->setHtml(text);
+}
+
+void ArthurFrame::paintDescription(QPainter *painter)
+{
+ if (!m_document)
+ return;
+
+ int pageWidth = qMax(width() - 100, 100);
+ int pageHeight = qMax(height() - 100, 100);
+ if (pageWidth != m_document->pageSize().width()) {
+ m_document->setPageSize(QSize(pageWidth, pageHeight));
+ }
+
+ QRect textRect(width() / 2 - pageWidth / 2,
+ height() / 2 - pageHeight / 2,
+ pageWidth,
+ pageHeight);
+ int pad = 10;
+ QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(QColor(0, 0, 0, 63));
+ int shade = 10;
+ painter->drawRect(clearRect.x() + clearRect.width() + 1,
+ clearRect.y() + shade,
+ shade,
+ clearRect.height() + 1);
+ painter->drawRect(clearRect.x() + shade,
+ clearRect.y() + clearRect.height() + 1,
+ clearRect.width() - shade + 1,
+ shade);
+
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ painter->setBrush(QColor(255, 255, 255, 220));
+ painter->setPen(Qt::black);
+ painter->drawRect(clearRect);
+
+ painter->setClipRegion(textRect, Qt::IntersectClip);
+ painter->translate(textRect.topLeft());
+
+ QAbstractTextDocumentLayout::PaintContext ctx;
+
+ QLinearGradient g(0, 0, 0, textRect.height());
+ g.setColorAt(0, Qt::black);
+ g.setColorAt(0.9, Qt::black);
+ g.setColorAt(1, Qt::transparent);
+
+ QPalette pal = palette();
+ pal.setBrush(QPalette::Text, g);
+
+ ctx.palette = pal;
+ ctx.clip = QRect(0, 0, textRect.width(), textRect.height());
+ m_document->documentLayout()->draw(painter, ctx);
+}
+
+void ArthurFrame::loadSourceFile(const QString &sourceFile)
+{
+ m_sourceFileName = sourceFile;
+}
+
+void ArthurFrame::showSource()
+{
+ // Check for existing source
+ if (findChild<QTextBrowser *>())
+ return;
+
+ QString contents;
+ if (m_sourceFileName.isEmpty()) {
+ contents = QString("No source for widget: '%1'").arg(objectName());
+ } else {
+ QFile f(m_sourceFileName);
+ if (!f.open(QFile::ReadOnly))
+ contents = QString("Could not open file: '%1'").arg(m_sourceFileName);
+ else
+ contents = f.readAll();
+ }
+
+ contents.replace('&', "&amp;");
+ contents.replace('<', "&lt;");
+ contents.replace('>', "&gt;");
+
+ QStringList keywords;
+ keywords << "for " << "if " << "switch " << " int " << "#include " << "const"
+ << "void " << "uint " << "case " << "double " << "#define " << "static"
+ << "new" << "this";
+
+ foreach (QString keyword, keywords)
+ contents.replace(keyword, QLatin1String("<font color=olive>") + keyword + QLatin1String("</font>"));
+ contents.replace("(int ", "(<font color=olive><b>int </b></font>");
+
+ QStringList ppKeywords;
+ ppKeywords << "#ifdef" << "#ifndef" << "#if" << "#endif" << "#else";
+
+ foreach (QString keyword, ppKeywords)
+ contents.replace(keyword, QLatin1String("<font color=navy>") + keyword + QLatin1String("</font>"));
+
+ contents.replace(QRegExp("(\\d\\d?)"), QLatin1String("<font color=navy>\\1</font>"));
+
+ QRegExp commentRe("(//.+)\\n");
+ commentRe.setMinimal(true);
+ contents.replace(commentRe, QLatin1String("<font color=red>\\1</font>\n"));
+
+ QRegExp stringLiteralRe("(\".+\")");
+ stringLiteralRe.setMinimal(true);
+ contents.replace(stringLiteralRe, QLatin1String("<font color=green>\\1</font>"));
+
+ QString html = contents;
+ html.prepend("<html><pre>");
+ html.append("</pre></html>");
+
+ QTextBrowser *sourceViewer = new QTextBrowser(0);
+ sourceViewer->setWindowTitle("Source: " + m_sourceFileName.mid(5));
+ sourceViewer->setParent(this, Qt::Dialog);
+ sourceViewer->setAttribute(Qt::WA_DeleteOnClose);
+ sourceViewer->setLineWrapMode(QTextEdit::NoWrap);
+ sourceViewer->setHtml(html);
+ sourceViewer->resize(600, 600);
+ sourceViewer->show();
+}
diff --git a/demos/shared/arthurwidgets.h b/demos/shared/arthurwidgets.h
new file mode 100644
index 000000000..67571119f
--- /dev/null
+++ b/demos/shared/arthurwidgets.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ARTHURWIDGETS_H
+#define ARTHURWIDGETS_H
+
+#include "arthurstyle.h"
+#include <QBitmap>
+#include <QPushButton>
+#include <QGroupBox>
+
+#if defined(QT_OPENGL_SUPPORT)
+#include <QGLWidget>
+#include <QEvent>
+class GLWidget : public QGLWidget
+{
+public:
+ GLWidget(QWidget *parent)
+ : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
+ {
+ setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ void disableAutoBufferSwap() { setAutoBufferSwap(false); }
+ void paintEvent(QPaintEvent *) { parentWidget()->update(); }
+protected:
+ bool event(QEvent *event)
+ {
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ event->ignore();
+ return false;
+ break;
+ default:
+ break;
+ }
+ return QGLWidget::event(event);
+ }
+};
+#endif
+
+QT_FORWARD_DECLARE_CLASS(QTextDocument)
+QT_FORWARD_DECLARE_CLASS(QTextEdit)
+QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
+
+class ArthurFrame : public QWidget
+{
+ Q_OBJECT
+public:
+ ArthurFrame(QWidget *parent);
+ virtual void paint(QPainter *) {}
+
+
+ void paintDescription(QPainter *p);
+
+ void loadDescription(const QString &filename);
+ void setDescription(const QString &htmlDesc);
+
+ void loadSourceFile(const QString &fileName);
+
+ bool preferImage() const { return m_prefer_image; }
+
+#if defined(QT_OPENGL_SUPPORT)
+ QGLWidget *glWidget() const { return glw; }
+#endif
+
+public slots:
+ void setPreferImage(bool pi) { m_prefer_image = pi; }
+ void setDescriptionEnabled(bool enabled);
+ void showSource();
+
+#if defined(QT_OPENGL_SUPPORT)
+ void enableOpenGL(bool use_opengl);
+ bool usesOpenGL() { return m_use_opengl; }
+#endif
+
+signals:
+ void descriptionEnabledChanged(bool);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void resizeEvent(QResizeEvent *);
+
+#if defined(QT_OPENGL_SUPPORT)
+ GLWidget *glw;
+ bool m_use_opengl;
+#endif
+ QPixmap m_tile;
+
+ bool m_show_doc;
+ bool m_prefer_image;
+ QTextDocument *m_document;
+
+ QString m_sourceFileName;
+
+};
+
+#endif
diff --git a/demos/shared/hoverpoints.cpp b/demos/shared/hoverpoints.cpp
new file mode 100644
index 000000000..272f89540
--- /dev/null
+++ b/demos/shared/hoverpoints.cpp
@@ -0,0 +1,415 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef QT_OPENGL_SUPPORT
+#include <QGLWidget>
+#endif
+
+#include "arthurwidgets.h"
+#include "hoverpoints.h"
+
+#define printf
+
+HoverPoints::HoverPoints(QWidget *widget, PointShape shape)
+ : QObject(widget)
+{
+ m_widget = widget;
+ widget->installEventFilter(this);
+ widget->setAttribute(Qt::WA_AcceptTouchEvents);
+
+ m_connectionType = CurveConnection;
+ m_sortType = NoSort;
+ m_shape = shape;
+ m_pointPen = QPen(QColor(255, 255, 255, 191), 1);
+ m_connectionPen = QPen(QColor(255, 255, 255, 127), 2);
+ m_pointBrush = QBrush(QColor(191, 191, 191, 127));
+ m_pointSize = QSize(11, 11);
+ m_currentIndex = -1;
+ m_editable = true;
+ m_enabled = true;
+
+ connect(this, SIGNAL(pointsChanged(QPolygonF)),
+ m_widget, SLOT(update()));
+}
+
+
+void HoverPoints::setEnabled(bool enabled)
+{
+ if (m_enabled != enabled) {
+ m_enabled = enabled;
+ m_widget->update();
+ }
+}
+
+
+bool HoverPoints::eventFilter(QObject *object, QEvent *event)
+{
+ if (object == m_widget && m_enabled) {
+ switch (event->type()) {
+
+ case QEvent::MouseButtonPress:
+ {
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
+ QMouseEvent *me = (QMouseEvent *) event;
+
+ QPointF clickPos = me->pos();
+ int index = -1;
+ for (int i=0; i<m_points.size(); ++i) {
+ QPainterPath path;
+ if (m_shape == CircleShape)
+ path.addEllipse(pointBoundingRect(i));
+ else
+ path.addRect(pointBoundingRect(i));
+
+ if (path.contains(clickPos)) {
+ index = i;
+ break;
+ }
+ }
+
+ if (me->button() == Qt::LeftButton) {
+ if (index == -1) {
+ if (!m_editable)
+ return false;
+ int pos = 0;
+ // Insert sort for x or y
+ if (m_sortType == XSort) {
+ for (int i=0; i<m_points.size(); ++i)
+ if (m_points.at(i).x() > clickPos.x()) {
+ pos = i;
+ break;
+ }
+ } else if (m_sortType == YSort) {
+ for (int i=0; i<m_points.size(); ++i)
+ if (m_points.at(i).y() > clickPos.y()) {
+ pos = i;
+ break;
+ }
+ }
+
+ m_points.insert(pos, clickPos);
+ m_locks.insert(pos, 0);
+ m_currentIndex = pos;
+ firePointChange();
+ } else {
+ m_currentIndex = index;
+ }
+ return true;
+
+ } else if (me->button() == Qt::RightButton) {
+ if (index >= 0 && m_editable) {
+ if (m_locks[index] == 0) {
+ m_locks.remove(index);
+ m_points.remove(index);
+ }
+ firePointChange();
+ return true;
+ }
+ }
+
+ }
+ break;
+
+ case QEvent::MouseButtonRelease:
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
+ m_currentIndex = -1;
+ break;
+
+ case QEvent::MouseMove:
+ if (!m_fingerPointMapping.isEmpty())
+ return true;
+ if (m_currentIndex >= 0)
+ movePoint(m_currentIndex, ((QMouseEvent *)event)->pos());
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ {
+ const QTouchEvent *const touchEvent = static_cast<const QTouchEvent*>(event);
+ const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints();
+ const qreal pointSize = qMax(m_pointSize.width(), m_pointSize.height());
+ foreach (const QTouchEvent::TouchPoint &touchPoint, points) {
+ const int id = touchPoint.id();
+ switch (touchPoint.state()) {
+ case Qt::TouchPointPressed:
+ {
+ // find the point, move it
+ QSet<int> activePoints = QSet<int>::fromList(m_fingerPointMapping.values());
+ int activePoint = -1;
+ qreal distance = -1;
+ const int pointsCount = m_points.size();
+ const int activePointCount = activePoints.size();
+ if (pointsCount == 2 && activePointCount == 1) { // only two points
+ activePoint = activePoints.contains(0) ? 1 : 0;
+ } else {
+ for (int i=0; i<pointsCount; ++i) {
+ if (activePoints.contains(i))
+ continue;
+
+ qreal d = QLineF(touchPoint.pos(), m_points.at(i)).length();
+ if ((distance < 0 && d < 12 * pointSize) || d < distance) {
+ distance = d;
+ activePoint = i;
+ }
+
+ }
+ }
+ if (activePoint != -1) {
+ m_fingerPointMapping.insert(touchPoint.id(), activePoint);
+ movePoint(activePoint, touchPoint.pos());
+ }
+ }
+ break;
+ case Qt::TouchPointReleased:
+ {
+ // move the point and release
+ QHash<int,int>::iterator it = m_fingerPointMapping.find(id);
+ movePoint(it.value(), touchPoint.pos());
+ m_fingerPointMapping.erase(it);
+ }
+ break;
+ case Qt::TouchPointMoved:
+ {
+ // move the point
+ const int pointIdx = m_fingerPointMapping.value(id, -1);
+ if (pointIdx >= 0) // do we track this point?
+ movePoint(pointIdx, touchPoint.pos());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (m_fingerPointMapping.isEmpty()) {
+ event->ignore();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ break;
+ case QEvent::TouchEnd:
+ if (m_fingerPointMapping.isEmpty()) {
+ event->ignore();
+ return false;
+ }
+ return true;
+ break;
+
+ case QEvent::Resize:
+ {
+ QResizeEvent *e = (QResizeEvent *) event;
+ if (e->oldSize().width() == 0 || e->oldSize().height() == 0)
+ break;
+ qreal stretch_x = e->size().width() / qreal(e->oldSize().width());
+ qreal stretch_y = e->size().height() / qreal(e->oldSize().height());
+ for (int i=0; i<m_points.size(); ++i) {
+ QPointF p = m_points[i];
+ movePoint(i, QPointF(p.x() * stretch_x, p.y() * stretch_y), false);
+ }
+
+ firePointChange();
+ break;
+ }
+
+ case QEvent::Paint:
+ {
+ QWidget *that_widget = m_widget;
+ m_widget = 0;
+ QApplication::sendEvent(object, event);
+ m_widget = that_widget;
+ paintPoints();
+#ifdef QT_OPENGL_SUPPORT
+ ArthurFrame *af = qobject_cast<ArthurFrame *>(that_widget);
+ if (af && af->usesOpenGL())
+ af->glWidget()->swapBuffers();
+#endif
+ return true;
+ }
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+
+void HoverPoints::paintPoints()
+{
+ QPainter p;
+#ifdef QT_OPENGL_SUPPORT
+ ArthurFrame *af = qobject_cast<ArthurFrame *>(m_widget);
+ if (af && af->usesOpenGL())
+ p.begin(af->glWidget());
+ else
+ p.begin(m_widget);
+#else
+ p.begin(m_widget);
+#endif
+
+ p.setRenderHint(QPainter::Antialiasing);
+
+ if (m_connectionPen.style() != Qt::NoPen && m_connectionType != NoConnection) {
+ p.setPen(m_connectionPen);
+
+ if (m_connectionType == CurveConnection) {
+ QPainterPath path;
+ path.moveTo(m_points.at(0));
+ for (int i=1; i<m_points.size(); ++i) {
+ QPointF p1 = m_points.at(i-1);
+ QPointF p2 = m_points.at(i);
+ qreal distance = p2.x() - p1.x();
+
+ path.cubicTo(p1.x() + distance / 2, p1.y(),
+ p1.x() + distance / 2, p2.y(),
+ p2.x(), p2.y());
+ }
+ p.drawPath(path);
+ } else {
+ p.drawPolyline(m_points);
+ }
+ }
+
+ p.setPen(m_pointPen);
+ p.setBrush(m_pointBrush);
+
+ for (int i=0; i<m_points.size(); ++i) {
+ QRectF bounds = pointBoundingRect(i);
+ if (m_shape == CircleShape)
+ p.drawEllipse(bounds);
+ else
+ p.drawRect(bounds);
+ }
+}
+
+static QPointF bound_point(const QPointF &point, const QRectF &bounds, int lock)
+{
+ QPointF p = point;
+
+ qreal left = bounds.left();
+ qreal right = bounds.right();
+ qreal top = bounds.top();
+ qreal bottom = bounds.bottom();
+
+ if (p.x() < left || (lock & HoverPoints::LockToLeft)) p.setX(left);
+ else if (p.x() > right || (lock & HoverPoints::LockToRight)) p.setX(right);
+
+ if (p.y() < top || (lock & HoverPoints::LockToTop)) p.setY(top);
+ else if (p.y() > bottom || (lock & HoverPoints::LockToBottom)) p.setY(bottom);
+
+ return p;
+}
+
+void HoverPoints::setPoints(const QPolygonF &points)
+{
+ if (points.size() != m_points.size())
+ m_fingerPointMapping.clear();
+ m_points.clear();
+ for (int i=0; i<points.size(); ++i)
+ m_points << bound_point(points.at(i), boundingRect(), 0);
+
+ m_locks.clear();
+ if (m_points.size() > 0) {
+ m_locks.resize(m_points.size());
+
+ m_locks.fill(0);
+ }
+}
+
+
+void HoverPoints::movePoint(int index, const QPointF &point, bool emitUpdate)
+{
+ m_points[index] = bound_point(point, boundingRect(), m_locks.at(index));
+ if (emitUpdate)
+ firePointChange();
+}
+
+
+inline static bool x_less_than(const QPointF &p1, const QPointF &p2)
+{
+ return p1.x() < p2.x();
+}
+
+
+inline static bool y_less_than(const QPointF &p1, const QPointF &p2)
+{
+ return p1.y() < p2.y();
+}
+
+void HoverPoints::firePointChange()
+{
+// printf("HoverPoints::firePointChange(), current=%d\n", m_currentIndex);
+
+ if (m_sortType != NoSort) {
+
+ QPointF oldCurrent;
+ if (m_currentIndex != -1) {
+ oldCurrent = m_points[m_currentIndex];
+ }
+
+ if (m_sortType == XSort)
+ qSort(m_points.begin(), m_points.end(), x_less_than);
+ else if (m_sortType == YSort)
+ qSort(m_points.begin(), m_points.end(), y_less_than);
+
+ // Compensate for changed order...
+ if (m_currentIndex != -1) {
+ for (int i=0; i<m_points.size(); ++i) {
+ if (m_points[i] == oldCurrent) {
+ m_currentIndex = i;
+ break;
+ }
+ }
+ }
+
+// printf(" - firePointChange(), current=%d\n", m_currentIndex);
+
+ }
+
+// for (int i=0; i<m_points.size(); ++i) {
+// printf(" - point(%2d)=[%.2f, %.2f], lock=%d\n",
+// i, m_points.at(i).x(), m_points.at(i).y(), m_locks.at(i));
+// }
+
+ emit pointsChanged(m_points);
+}
diff --git a/demos/shared/hoverpoints.h b/demos/shared/hoverpoints.h
new file mode 100644
index 000000000..9c10632d8
--- /dev/null
+++ b/demos/shared/hoverpoints.h
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HOVERPOINTS_H
+#define HOVERPOINTS_H
+
+#include <QtGui>
+
+QT_FORWARD_DECLARE_CLASS(QBypassWidget)
+
+class HoverPoints : public QObject
+{
+ Q_OBJECT
+public:
+ enum PointShape {
+ CircleShape,
+ RectangleShape
+ };
+
+ enum LockType {
+ LockToLeft = 0x01,
+ LockToRight = 0x02,
+ LockToTop = 0x04,
+ LockToBottom = 0x08
+ };
+
+ enum SortType {
+ NoSort,
+ XSort,
+ YSort
+ };
+
+ enum ConnectionType {
+ NoConnection,
+ LineConnection,
+ CurveConnection
+ };
+
+ HoverPoints(QWidget *widget, PointShape shape);
+
+ bool eventFilter(QObject *object, QEvent *event);
+
+ void paintPoints();
+
+ inline QRectF boundingRect() const;
+ void setBoundingRect(const QRectF &boundingRect) { m_bounds = boundingRect; }
+
+ QPolygonF points() const { return m_points; }
+ void setPoints(const QPolygonF &points);
+
+ QSizeF pointSize() const { return m_pointSize; }
+ void setPointSize(const QSizeF &size) { m_pointSize = size; }
+
+ SortType sortType() const { return m_sortType; }
+ void setSortType(SortType sortType) { m_sortType = sortType; }
+
+ ConnectionType connectionType() const { return m_connectionType; }
+ void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; }
+
+ void setConnectionPen(const QPen &pen) { m_connectionPen = pen; }
+ void setShapePen(const QPen &pen) { m_pointPen = pen; }
+ void setShapeBrush(const QBrush &brush) { m_pointBrush = brush; }
+
+ void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; }
+
+ void setEditable(bool editable) { m_editable = editable; }
+ bool editable() const { return m_editable; }
+
+public slots:
+ void setEnabled(bool enabled);
+ void setDisabled(bool disabled) { setEnabled(!disabled); }
+
+signals:
+ void pointsChanged(const QPolygonF &points);
+
+public:
+ void firePointChange();
+
+private:
+ inline QRectF pointBoundingRect(int i) const;
+ void movePoint(int i, const QPointF &newPos, bool emitChange = true);
+
+ QWidget *m_widget;
+
+ QPolygonF m_points;
+ QRectF m_bounds;
+ PointShape m_shape;
+ SortType m_sortType;
+ ConnectionType m_connectionType;
+
+ QVector<uint> m_locks;
+
+ QSizeF m_pointSize;
+ int m_currentIndex;
+ bool m_editable;
+ bool m_enabled;
+
+ QHash<int, int> m_fingerPointMapping;
+
+ QPen m_pointPen;
+ QBrush m_pointBrush;
+ QPen m_connectionPen;
+};
+
+
+inline QRectF HoverPoints::pointBoundingRect(int i) const
+{
+ QPointF p = m_points.at(i);
+ qreal w = m_pointSize.width();
+ qreal h = m_pointSize.height();
+ qreal x = p.x() - w / 2;
+ qreal y = p.y() - h / 2;
+ return QRectF(x, y, w, h);
+}
+
+inline QRectF HoverPoints::boundingRect() const
+{
+ if (m_bounds.isEmpty())
+ return m_widget->rect();
+ else
+ return m_bounds;
+}
+
+#endif // HOVERPOINTS_H
diff --git a/demos/shared/images/bg_pattern.png b/demos/shared/images/bg_pattern.png
new file mode 100644
index 000000000..ee670266f
--- /dev/null
+++ b/demos/shared/images/bg_pattern.png
Binary files differ
diff --git a/demos/shared/images/button_normal_cap_left.png b/demos/shared/images/button_normal_cap_left.png
new file mode 100644
index 000000000..db31dd971
--- /dev/null
+++ b/demos/shared/images/button_normal_cap_left.png
Binary files differ
diff --git a/demos/shared/images/button_normal_cap_right.png b/demos/shared/images/button_normal_cap_right.png
new file mode 100644
index 000000000..38ead1c71
--- /dev/null
+++ b/demos/shared/images/button_normal_cap_right.png
Binary files differ
diff --git a/demos/shared/images/button_normal_stretch.png b/demos/shared/images/button_normal_stretch.png
new file mode 100644
index 000000000..87abe67ac
--- /dev/null
+++ b/demos/shared/images/button_normal_stretch.png
Binary files differ
diff --git a/demos/shared/images/button_pressed_cap_left.png b/demos/shared/images/button_pressed_cap_left.png
new file mode 100644
index 000000000..66bfc13cb
--- /dev/null
+++ b/demos/shared/images/button_pressed_cap_left.png
Binary files differ
diff --git a/demos/shared/images/button_pressed_cap_right.png b/demos/shared/images/button_pressed_cap_right.png
new file mode 100644
index 000000000..3d4cfe25b
--- /dev/null
+++ b/demos/shared/images/button_pressed_cap_right.png
Binary files differ
diff --git a/demos/shared/images/button_pressed_stretch.png b/demos/shared/images/button_pressed_stretch.png
new file mode 100644
index 000000000..4dd4ad11e
--- /dev/null
+++ b/demos/shared/images/button_pressed_stretch.png
Binary files differ
diff --git a/demos/shared/images/curve_thing_edit-6.png b/demos/shared/images/curve_thing_edit-6.png
new file mode 100644
index 000000000..034b474d0
--- /dev/null
+++ b/demos/shared/images/curve_thing_edit-6.png
Binary files differ
diff --git a/demos/shared/images/frame_bottom.png b/demos/shared/images/frame_bottom.png
new file mode 100644
index 000000000..889b40d30
--- /dev/null
+++ b/demos/shared/images/frame_bottom.png
Binary files differ
diff --git a/demos/shared/images/frame_bottomleft.png b/demos/shared/images/frame_bottomleft.png
new file mode 100644
index 000000000..0b3023f39
--- /dev/null
+++ b/demos/shared/images/frame_bottomleft.png
Binary files differ
diff --git a/demos/shared/images/frame_bottomright.png b/demos/shared/images/frame_bottomright.png
new file mode 100644
index 000000000..0021e3586
--- /dev/null
+++ b/demos/shared/images/frame_bottomright.png
Binary files differ
diff --git a/demos/shared/images/frame_left.png b/demos/shared/images/frame_left.png
new file mode 100644
index 000000000..40f331c29
--- /dev/null
+++ b/demos/shared/images/frame_left.png
Binary files differ
diff --git a/demos/shared/images/frame_right.png b/demos/shared/images/frame_right.png
new file mode 100644
index 000000000..023af8c70
--- /dev/null
+++ b/demos/shared/images/frame_right.png
Binary files differ
diff --git a/demos/shared/images/frame_top.png b/demos/shared/images/frame_top.png
new file mode 100644
index 000000000..001f3a714
--- /dev/null
+++ b/demos/shared/images/frame_top.png
Binary files differ
diff --git a/demos/shared/images/frame_topleft.png b/demos/shared/images/frame_topleft.png
new file mode 100644
index 000000000..58c68d407
--- /dev/null
+++ b/demos/shared/images/frame_topleft.png
Binary files differ
diff --git a/demos/shared/images/frame_topright.png b/demos/shared/images/frame_topright.png
new file mode 100644
index 000000000..6a7e8d3eb
--- /dev/null
+++ b/demos/shared/images/frame_topright.png
Binary files differ
diff --git a/demos/shared/images/groupframe_bottom_left.png b/demos/shared/images/groupframe_bottom_left.png
new file mode 100644
index 000000000..af2fe061e
--- /dev/null
+++ b/demos/shared/images/groupframe_bottom_left.png
Binary files differ
diff --git a/demos/shared/images/groupframe_bottom_right.png b/demos/shared/images/groupframe_bottom_right.png
new file mode 100644
index 000000000..fdf2e97b1
--- /dev/null
+++ b/demos/shared/images/groupframe_bottom_right.png
Binary files differ
diff --git a/demos/shared/images/groupframe_bottom_stretch.png b/demos/shared/images/groupframe_bottom_stretch.png
new file mode 100644
index 000000000..f47b67d7c
--- /dev/null
+++ b/demos/shared/images/groupframe_bottom_stretch.png
Binary files differ
diff --git a/demos/shared/images/groupframe_left_stretch.png b/demos/shared/images/groupframe_left_stretch.png
new file mode 100644
index 000000000..c122f462e
--- /dev/null
+++ b/demos/shared/images/groupframe_left_stretch.png
Binary files differ
diff --git a/demos/shared/images/groupframe_right_stretch.png b/demos/shared/images/groupframe_right_stretch.png
new file mode 100644
index 000000000..1056b7812
--- /dev/null
+++ b/demos/shared/images/groupframe_right_stretch.png
Binary files differ
diff --git a/demos/shared/images/groupframe_top_stretch.png b/demos/shared/images/groupframe_top_stretch.png
new file mode 100644
index 000000000..5746ef96f
--- /dev/null
+++ b/demos/shared/images/groupframe_top_stretch.png
Binary files differ
diff --git a/demos/shared/images/groupframe_topleft.png b/demos/shared/images/groupframe_topleft.png
new file mode 100644
index 000000000..98d9cd96b
--- /dev/null
+++ b/demos/shared/images/groupframe_topleft.png
Binary files differ
diff --git a/demos/shared/images/groupframe_topright.png b/demos/shared/images/groupframe_topright.png
new file mode 100644
index 000000000..1a0a328c2
--- /dev/null
+++ b/demos/shared/images/groupframe_topright.png
Binary files differ
diff --git a/demos/shared/images/line_dash_dot.png b/demos/shared/images/line_dash_dot.png
new file mode 100644
index 000000000..1c61442d9
--- /dev/null
+++ b/demos/shared/images/line_dash_dot.png
Binary files differ
diff --git a/demos/shared/images/line_dash_dot_dot.png b/demos/shared/images/line_dash_dot_dot.png
new file mode 100644
index 000000000..0d9bb972f
--- /dev/null
+++ b/demos/shared/images/line_dash_dot_dot.png
Binary files differ
diff --git a/demos/shared/images/line_dashed.png b/demos/shared/images/line_dashed.png
new file mode 100644
index 000000000..d5bc7ea5f
--- /dev/null
+++ b/demos/shared/images/line_dashed.png
Binary files differ
diff --git a/demos/shared/images/line_dotted.png b/demos/shared/images/line_dotted.png
new file mode 100644
index 000000000..a2f9a3592
--- /dev/null
+++ b/demos/shared/images/line_dotted.png
Binary files differ
diff --git a/demos/shared/images/line_solid.png b/demos/shared/images/line_solid.png
new file mode 100644
index 000000000..60ef3f948
--- /dev/null
+++ b/demos/shared/images/line_solid.png
Binary files differ
diff --git a/demos/shared/images/radiobutton-off.png b/demos/shared/images/radiobutton-off.png
new file mode 100644
index 000000000..af1753a3e
--- /dev/null
+++ b/demos/shared/images/radiobutton-off.png
Binary files differ
diff --git a/demos/shared/images/radiobutton-on.png b/demos/shared/images/radiobutton-on.png
new file mode 100644
index 000000000..f875838bb
--- /dev/null
+++ b/demos/shared/images/radiobutton-on.png
Binary files differ
diff --git a/demos/shared/images/radiobutton_off.png b/demos/shared/images/radiobutton_off.png
new file mode 100644
index 000000000..400906ebf
--- /dev/null
+++ b/demos/shared/images/radiobutton_off.png
Binary files differ
diff --git a/demos/shared/images/radiobutton_on.png b/demos/shared/images/radiobutton_on.png
new file mode 100644
index 000000000..50a049ec5
--- /dev/null
+++ b/demos/shared/images/radiobutton_on.png
Binary files differ
diff --git a/demos/shared/images/slider_bar.png b/demos/shared/images/slider_bar.png
new file mode 100644
index 000000000..1b3d62c00
--- /dev/null
+++ b/demos/shared/images/slider_bar.png
Binary files differ
diff --git a/demos/shared/images/slider_thumb_off.png b/demos/shared/images/slider_thumb_off.png
new file mode 100644
index 000000000..d7f141dae
--- /dev/null
+++ b/demos/shared/images/slider_thumb_off.png
Binary files differ
diff --git a/demos/shared/images/slider_thumb_on.png b/demos/shared/images/slider_thumb_on.png
new file mode 100644
index 000000000..8e1f51081
--- /dev/null
+++ b/demos/shared/images/slider_thumb_on.png
Binary files differ
diff --git a/demos/shared/images/title_cap_left.png b/demos/shared/images/title_cap_left.png
new file mode 100644
index 000000000..2d475070c
--- /dev/null
+++ b/demos/shared/images/title_cap_left.png
Binary files differ
diff --git a/demos/shared/images/title_cap_right.png b/demos/shared/images/title_cap_right.png
new file mode 100644
index 000000000..dc3ff8536
--- /dev/null
+++ b/demos/shared/images/title_cap_right.png
Binary files differ
diff --git a/demos/shared/images/title_stretch.png b/demos/shared/images/title_stretch.png
new file mode 100644
index 000000000..11043345d
--- /dev/null
+++ b/demos/shared/images/title_stretch.png
Binary files differ
diff --git a/demos/shared/shared.pri b/demos/shared/shared.pri
new file mode 100644
index 000000000..fb7b04c0b
--- /dev/null
+++ b/demos/shared/shared.pri
@@ -0,0 +1,21 @@
+INCLUDEPATH += $$SHARED_FOLDER
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+contains(CONFIG, debug_and_release_target) {
+ CONFIG(debug, debug|release) {
+ QMAKE_LIBDIR += $$SHARED_FOLDER/debug
+ } else {
+ QMAKE_LIBDIR += $$SHARED_FOLDER/release
+ }
+} else {
+ QMAKE_LIBDIR += $$SHARED_FOLDER
+}
+
+hpux-acc*:LIBS += $$SHARED_FOLDER/libdemo_shared.a
+hpuxi-acc*:LIBS += $$SHARED_FOLDER/libdemo_shared.a
+symbian:LIBS += -ldemo_shared.lib
+!hpuxi-acc*:!hpux-acc*:!symbian:LIBS += -ldemo_shared
+
diff --git a/demos/shared/shared.pro b/demos/shared/shared.pro
new file mode 100644
index 000000000..ab31b32b5
--- /dev/null
+++ b/demos/shared/shared.pro
@@ -0,0 +1,38 @@
+TEMPLATE = lib
+CONFIG += static
+
+contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+TARGET = demo_shared
+
+SOURCES += \
+ arthurstyle.cpp\
+ arthurwidgets.cpp \
+ hoverpoints.cpp
+
+HEADERS += \
+ arthurstyle.h \
+ arthurwidgets.h \
+ hoverpoints.h
+
+RESOURCES += shared.qrc
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qttools/shared
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.pri images
+sources.path = $$[QT_INSTALL_DEMOS]/qttools/shared
+INSTALLS += sources
+
+!cross_compile:INSTALLS += target
+
+symbian {
+ TARGET.UID3 = 0xA000A63C
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+}
diff --git a/demos/shared/shared.qrc b/demos/shared/shared.qrc
new file mode 100644
index 000000000..17336ecf8
--- /dev/null
+++ b/demos/shared/shared.qrc
@@ -0,0 +1,39 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res">
+ <file>images/button_normal_cap_left.png</file>
+ <file>images/button_normal_cap_right.png</file>
+ <file>images/button_normal_stretch.png</file>
+ <file>images/button_pressed_cap_left.png</file>
+ <file>images/button_pressed_cap_right.png</file>
+ <file>images/button_pressed_stretch.png</file>
+ <file>images/radiobutton-on.png</file>
+ <file>images/radiobutton_on.png</file>
+ <file>images/radiobutton_off.png</file>
+ <file>images/slider_bar.png</file>
+ <file>images/slider_thumb_on.png</file>
+ <file>images/groupframe_topleft.png</file>
+ <file>images/groupframe_topright.png</file>
+ <file>images/groupframe_bottom_left.png</file>
+ <file>images/groupframe_bottom_right.png</file>
+ <file>images/groupframe_top_stretch.png</file>
+ <file>images/groupframe_bottom_stretch.png</file>
+ <file>images/groupframe_left_stretch.png</file>
+ <file>images/groupframe_right_stretch.png</file>
+ <file>images/frame_topleft.png</file>
+ <file>images/frame_topright.png</file>
+ <file>images/frame_bottomleft.png</file>
+ <file>images/frame_bottomright.png</file>
+ <file>images/frame_left.png</file>
+ <file>images/frame_top.png</file>
+ <file>images/frame_right.png</file>
+ <file>images/frame_bottom.png</file>
+ <file>images/title_cap_left.png</file>
+ <file>images/title_cap_right.png</file>
+ <file>images/title_stretch.png</file>
+ <file>images/line_dash_dot.png</file>
+ <file>images/line_dotted.png</file>
+ <file>images/line_dashed.png</file>
+ <file>images/line_solid.png</file>
+ <file>images/line_dash_dot_dot.png</file>
+</qresource>
+</RCC>
diff --git a/examples/designer/README b/examples/designer/README
new file mode 100644
index 000000000..fb9443cae
--- /dev/null
+++ b/examples/designer/README
@@ -0,0 +1,37 @@
+Qt Designer is a capable graphical user interface designer that lets you
+create and configure forms without writing code. GUIs created with
+Qt Designer can be compiled into an application or created at run-time.
+
+
+Some of the examples in this directory can be run from the example launcher;
+others can only be used from within Qt Designer.
+
+Documentation for these examples can be found via the "Tutorial and Examples"
+link in the main Qt documentation.
+
+Finding the Qt Examples and Demos launcher
+==========================================
+
+On Windows:
+
+The launcher can be accessed via the Windows Start menu. Select the menu
+entry entitled "Qt Examples and Demos" entry in the submenu containing
+the Qt tools.
+
+On Mac OS X:
+
+For the binary distribution, the qtdemo executable is installed in the
+/Developer/Applications/Qt directory. For the source distribution, it is
+installed alongside the other Qt tools on the path specified when Qt is
+configured.
+
+On Unix/Linux:
+
+The qtdemo executable is installed alongside the other Qt tools on the path
+specified when Qt is configured.
+
+On all platforms:
+
+The source code for the launcher can be found in the demos/qtdemo directory
+in the Qt package. This example is built at the same time as the Qt libraries,
+tools, examples, and demonstrations.
diff --git a/examples/designer/calculatorbuilder/calculatorbuilder.pro b/examples/designer/calculatorbuilder/calculatorbuilder.pro
new file mode 100644
index 000000000..ca4a3ea15
--- /dev/null
+++ b/examples/designer/calculatorbuilder/calculatorbuilder.pro
@@ -0,0 +1,16 @@
+#! [0]
+CONFIG += uitools
+
+HEADERS = calculatorform.h
+RESOURCES = calculatorbuilder.qrc
+SOURCES = calculatorform.cpp \
+ main.cpp
+#! [0]
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/calculatorbuilder
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.ui *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/calculatorbuilder
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/designer/calculatorbuilder/calculatorbuilder.qrc b/examples/designer/calculatorbuilder/calculatorbuilder.qrc
new file mode 100644
index 000000000..19b39059e
--- /dev/null
+++ b/examples/designer/calculatorbuilder/calculatorbuilder.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/forms">
+ <file>calculatorform.ui</file>
+</qresource>
+</RCC>
diff --git a/examples/designer/calculatorbuilder/calculatorform.cpp b/examples/designer/calculatorbuilder/calculatorform.cpp
new file mode 100644
index 000000000..e14efa497
--- /dev/null
+++ b/examples/designer/calculatorbuilder/calculatorform.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+#include <QtUiTools>
+//! [0]
+#include <QtGui>
+
+#include "calculatorform.h"
+
+//! [1]
+CalculatorForm::CalculatorForm(QWidget *parent)
+ : QWidget(parent)
+{
+ QUiLoader loader;
+
+ QFile file(":/forms/calculatorform.ui");
+ file.open(QFile::ReadOnly);
+ QWidget *formWidget = loader.load(&file, this);
+ file.close();
+//! [1]
+
+//! [2]
+ ui_inputSpinBox1 = findChild<QSpinBox*>("inputSpinBox1");
+ ui_inputSpinBox2 = findChild<QSpinBox*>("inputSpinBox2");
+ ui_outputWidget = findChild<QLabel*>("outputWidget");
+//! [2]
+
+//! [3]
+ QMetaObject::connectSlotsByName(this);
+//! [3]
+
+//! [4]
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(formWidget);
+ setLayout(layout);
+
+ setWindowTitle(tr("Calculator Builder"));
+}
+//! [4]
+
+//! [5]
+void CalculatorForm::on_inputSpinBox1_valueChanged(int value)
+{
+ ui_outputWidget->setText(QString::number(value + ui_inputSpinBox2->value()));
+}
+//! [5] //! [6]
+
+//! [6] //! [7]
+void CalculatorForm::on_inputSpinBox2_valueChanged(int value)
+{
+ ui_outputWidget->setText(QString::number(value + ui_inputSpinBox1->value()));
+}
+//! [7]
diff --git a/examples/designer/calculatorbuilder/calculatorform.h b/examples/designer/calculatorbuilder/calculatorform.h
new file mode 100644
index 000000000..f891823fc
--- /dev/null
+++ b/examples/designer/calculatorbuilder/calculatorform.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CALCULATORFORM_H
+#define CALCULATORFORM_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QSpinBox;
+QT_END_NAMESPACE
+
+//! [0]
+class CalculatorForm : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CalculatorForm(QWidget *parent = 0);
+
+private slots:
+ void on_inputSpinBox1_valueChanged(int value);
+ void on_inputSpinBox2_valueChanged(int value);
+
+private:
+ QSpinBox *ui_inputSpinBox1;
+ QSpinBox *ui_inputSpinBox2;
+ QLabel *ui_outputWidget;
+};
+//! [0]
+
+#endif
diff --git a/examples/designer/calculatorbuilder/calculatorform.ui b/examples/designer/calculatorbuilder/calculatorform.ui
new file mode 100644
index 000000000..dda0e62dd
--- /dev/null
+++ b/examples/designer/calculatorbuilder/calculatorform.ui
@@ -0,0 +1,303 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>CalculatorForm</class>
+ <widget class="QWidget" name="CalculatorForm" >
+ <property name="objectName" >
+ <string notr="true" >CalculatorForm</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>276</width>
+ <height>98</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Calculator Builder</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="objectName" >
+ <string notr="true" >label</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>1</y>
+ <width>45</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Input 1</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="inputSpinBox1" >
+ <property name="objectName" >
+ <string notr="true" >inputSpinBox1</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>26</y>
+ <width>45</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="mouseTracking" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="objectName" >
+ <string notr="true" >label_3</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>54</x>
+ <y>1</y>
+ <width>7</width>
+ <height>52</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>+</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="objectName" >
+ <string notr="true" >label_2</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>1</y>
+ <width>45</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Input 2</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="inputSpinBox2" >
+ <property name="objectName" >
+ <string notr="true" >inputSpinBox2</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>26</y>
+ <width>45</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="mouseTracking" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3_2" >
+ <property name="objectName" >
+ <string notr="true" >label_3_2</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>120</x>
+ <y>1</y>
+ <width>7</width>
+ <height>52</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>=</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2_2_2" >
+ <property name="objectName" >
+ <string notr="true" >label_2_2_2</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>1</y>
+ <width>37</width>
+ <height>17</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Output</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="outputWidget" >
+ <property name="objectName" >
+ <string notr="true" >outputWidget</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>24</y>
+ <width>37</width>
+ <height>27</height>
+ </rect>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text" >
+ <string>0</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignAbsolute|Qt::AlignBottom|Qt::AlignCenter|Qt::AlignHCenter|Qt::AlignHorizontal_Mask|Qt::AlignJustify|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing|Qt::AlignVCenter|Qt::AlignVertical_Mask</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="objectName" >
+ <string notr="true" >verticalSpacer</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>85</x>
+ <y>69</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="1" >
+ <spacer>
+ <property name="objectName" >
+ <string notr="true" >horizontalSpacer</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>188</x>
+ <y>26</y>
+ <width>79</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/designer/calculatorbuilder/main.cpp b/examples/designer/calculatorbuilder/main.cpp
new file mode 100644
index 000000000..b5cab6bad
--- /dev/null
+++ b/examples/designer/calculatorbuilder/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "calculatorform.h"
+
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(calculatorbuilder);
+
+ QApplication app(argc, argv);
+ CalculatorForm calculator;
+ calculator.show();
+ return app.exec();
+}
diff --git a/examples/designer/calculatorform/calculatorform.cpp b/examples/designer/calculatorform/calculatorform.cpp
new file mode 100644
index 000000000..ef9022f1f
--- /dev/null
+++ b/examples/designer/calculatorform/calculatorform.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "calculatorform.h"
+
+//! [0]
+CalculatorForm::CalculatorForm(QWidget *parent)
+ : QWidget(parent)
+{
+ ui.setupUi(this);
+}
+//! [0]
+
+//! [1]
+void CalculatorForm::on_inputSpinBox1_valueChanged(int value)
+{
+ ui.outputWidget->setText(QString::number(value + ui.inputSpinBox2->value()));
+}
+//! [1]
+
+//! [2]
+void CalculatorForm::on_inputSpinBox2_valueChanged(int value)
+{
+ ui.outputWidget->setText(QString::number(value + ui.inputSpinBox1->value()));
+}
+//! [2]
diff --git a/examples/designer/calculatorform/calculatorform.h b/examples/designer/calculatorform/calculatorform.h
new file mode 100644
index 000000000..940699571
--- /dev/null
+++ b/examples/designer/calculatorform/calculatorform.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CALCULATORFORM_H
+#define CALCULATORFORM_H
+
+//! [0]
+#include "ui_calculatorform.h"
+//! [0]
+
+//! [1]
+class CalculatorForm : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CalculatorForm(QWidget *parent = 0);
+
+private slots:
+ void on_inputSpinBox1_valueChanged(int value);
+ void on_inputSpinBox2_valueChanged(int value);
+
+private:
+ Ui::CalculatorForm ui;
+};
+//! [1]
+
+#endif
diff --git a/examples/designer/calculatorform/calculatorform.pro b/examples/designer/calculatorform/calculatorform.pro
new file mode 100644
index 000000000..65a8cfe6f
--- /dev/null
+++ b/examples/designer/calculatorform/calculatorform.pro
@@ -0,0 +1,15 @@
+#! [0]
+HEADERS = calculatorform.h
+#! [0] #! [1]
+FORMS = calculatorform.ui
+#! [1]
+SOURCES = calculatorform.cpp \
+ main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/calculatorform
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/calculatorform
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/designer/calculatorform/calculatorform.ui b/examples/designer/calculatorform/calculatorform.ui
new file mode 100644
index 000000000..3a956399a
--- /dev/null
+++ b/examples/designer/calculatorform/calculatorform.ui
@@ -0,0 +1,284 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>CalculatorForm</class>
+ <widget class="QWidget" name="CalculatorForm" >
+ <property name="objectName" >
+ <string notr="true" >CalculatorForm</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Calculator Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="6" >
+ <spacer>
+ <property name="objectName" >
+ <string notr="true" >horizontalSpacer</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>239</x>
+ <y>9</y>
+ <width>152</width>
+ <height>52</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QLabel" name="label_3_2" >
+ <property name="objectName" >
+ <string notr="true" >label_3_2</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>169</x>
+ <y>9</y>
+ <width>20</width>
+ <height>52</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>=</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5" >
+ <layout class="QVBoxLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2_2_2" >
+ <property name="objectName" >
+ <string notr="true" >label_2_2_2</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>1</y>
+ <width>36</width>
+ <height>17</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Output</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="outputWidget" >
+ <property name="objectName" >
+ <string notr="true" >outputWidget</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>24</y>
+ <width>36</width>
+ <height>27</height>
+ </rect>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text" >
+ <string>0</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignAbsolute|Qt::AlignBottom|Qt::AlignCenter|Qt::AlignHCenter|Qt::AlignHorizontal_Mask|Qt::AlignJustify|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing|Qt::AlignVCenter|Qt::AlignVertical_Mask</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="objectName" >
+ <string notr="true" >verticalSpacer</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>89</x>
+ <y>67</y>
+ <width>20</width>
+ <height>224</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="3" >
+ <layout class="QVBoxLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="objectName" >
+ <string notr="true" >label_2</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>1</y>
+ <width>46</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Input 2</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="inputSpinBox2" >
+ <property name="objectName" >
+ <string notr="true" >inputSpinBox2</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>26</y>
+ <width>46</width>
+ <height>25</height>
+ </rect>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label_3" >
+ <property name="objectName" >
+ <string notr="true" >label_3</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>63</x>
+ <y>9</y>
+ <width>20</width>
+ <height>52</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>+</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <layout class="QVBoxLayout" >
+ <property name="objectName" >
+ <string notr="true" />
+ </property>
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="objectName" >
+ <string notr="true" >label</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>1</y>
+ <width>46</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Input 1</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="inputSpinBox1" >
+ <property name="objectName" >
+ <string notr="true" >inputSpinBox1</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>1</x>
+ <y>26</y>
+ <width>46</width>
+ <height>25</height>
+ </rect>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/designer/calculatorform/main.cpp b/examples/designer/calculatorform/main.cpp
new file mode 100644
index 000000000..2dd1fc11d
--- /dev/null
+++ b/examples/designer/calculatorform/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "calculatorform.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ CalculatorForm calculator;
+ calculator.show();
+ return app.exec();
+}
+
diff --git a/examples/designer/containerextension/containerextension.pro b/examples/designer/containerextension/containerextension.pro
new file mode 100644
index 000000000..6ded91737
--- /dev/null
+++ b/examples/designer/containerextension/containerextension.pro
@@ -0,0 +1,28 @@
+#! [0]
+TEMPLATE = lib
+#! [0]
+TARGET = $$qtLibraryTarget($$TARGET)
+#! [1]
+CONFIG += designer plugin
+#! [1]
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/designer
+
+#! [2]
+HEADERS += multipagewidget.h \
+ multipagewidgetplugin.h \
+ multipagewidgetcontainerextension.h \
+ multipagewidgetextensionfactory.h
+
+SOURCES += multipagewidget.cpp \
+ multipagewidgetplugin.cpp \
+ multipagewidgetcontainerextension.cpp \
+ multipagewidgetextensionfactory.cpp
+#! [2]
+
+# install
+target.path = $$[QT_INSTALL_PLUGINS]/designer
+sources.files = $$SOURCES $$HEADERS *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/containerextension
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/designer/containerextension/multipagewidget.cpp b/examples/designer/containerextension/multipagewidget.cpp
new file mode 100644
index 000000000..5b44f36d2
--- /dev/null
+++ b/examples/designer/containerextension/multipagewidget.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "multipagewidget.h"
+
+MultiPageWidget::MultiPageWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ comboBox = new QComboBox();
+ comboBox->setObjectName("__qt__passive_comboBox");
+ stackWidget = new QStackedWidget();
+
+ connect(comboBox, SIGNAL(activated(int)),
+ this, SLOT(setCurrentIndex(int)));
+
+ layout = new QVBoxLayout();
+ layout->addWidget(comboBox);
+ layout->addWidget(stackWidget);
+ setLayout(layout);
+}
+
+QSize MultiPageWidget::sizeHint() const
+{
+ return QSize(200, 150);
+}
+
+void MultiPageWidget::addPage(QWidget *page)
+{
+ insertPage(count(), page);
+}
+
+void MultiPageWidget::removePage(int index)
+{
+ QWidget *widget = stackWidget->widget(index);
+ stackWidget->removeWidget(widget);
+
+ comboBox->removeItem(index);
+}
+
+int MultiPageWidget::count() const
+{
+ return stackWidget->count();
+}
+
+int MultiPageWidget::currentIndex() const
+{
+ return stackWidget->currentIndex();
+}
+
+void MultiPageWidget::insertPage(int index, QWidget *page)
+{
+ page->setParent(stackWidget);
+
+ stackWidget->insertWidget(index, page);
+
+ QString title = page->windowTitle();
+ if (title.isEmpty()) {
+ title = tr("Page %1").arg(comboBox->count() + 1);
+ page->setWindowTitle(title);
+ }
+ comboBox->insertItem(index, title);
+}
+
+void MultiPageWidget::setCurrentIndex(int index)
+{
+ if (index != currentIndex()) {
+ stackWidget->setCurrentIndex(index);
+ comboBox->setCurrentIndex(index);
+ emit currentIndexChanged(index);
+ }
+}
+
+QWidget* MultiPageWidget::widget(int index)
+{
+ return stackWidget->widget(index);
+}
+
+QString MultiPageWidget::pageTitle() const
+{
+ if (const QWidget *currentWidget = stackWidget->currentWidget())
+ return currentWidget->windowTitle();
+ return QString();
+}
+
+void MultiPageWidget::setPageTitle(QString const &newTitle)
+{
+ comboBox->setItemText(currentIndex(), newTitle);
+ if (QWidget *currentWidget = stackWidget->currentWidget())
+ currentWidget->setWindowTitle(newTitle);
+ emit pageTitleChanged(newTitle);
+}
diff --git a/examples/designer/containerextension/multipagewidget.h b/examples/designer/containerextension/multipagewidget.h
new file mode 100644
index 000000000..b2f3b7d5d
--- /dev/null
+++ b/examples/designer/containerextension/multipagewidget.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MULTIPAGEWIDGET_H
+#define MULTIPAGEWIDGET_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QStackedWidget;
+class QVBoxLayout;
+QT_END_NAMESPACE
+
+//! [0]
+class MultiPageWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex)
+ Q_PROPERTY(QString pageTitle READ pageTitle WRITE setPageTitle STORED false)
+
+public:
+ MultiPageWidget(QWidget *parent = 0);
+
+ QSize sizeHint() const;
+
+ int count() const;
+ int currentIndex() const;
+ QWidget *widget(int index);
+ QString pageTitle() const;
+
+public slots:
+ void addPage(QWidget *page);
+ void insertPage(int index, QWidget *page);
+ void removePage(int index);
+ void setPageTitle(QString const &newTitle);
+ void setCurrentIndex(int index);
+
+signals:
+ void currentIndexChanged(int index);
+ void pageTitleChanged(const QString &title);
+
+private:
+ QStackedWidget *stackWidget;
+ QComboBox *comboBox;
+ QVBoxLayout *layout;
+};
+//! [0]
+
+#endif
diff --git a/examples/designer/containerextension/multipagewidgetcontainerextension.cpp b/examples/designer/containerextension/multipagewidgetcontainerextension.cpp
new file mode 100644
index 000000000..fe815341a
--- /dev/null
+++ b/examples/designer/containerextension/multipagewidgetcontainerextension.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "multipagewidgetcontainerextension.h"
+#include "multipagewidget.h"
+
+//! [0]
+MultiPageWidgetContainerExtension::MultiPageWidgetContainerExtension(MultiPageWidget *widget,
+ QObject *parent)
+ :QObject(parent)
+{
+ myWidget = widget;
+}
+//! [0]
+
+//! [1]
+void MultiPageWidgetContainerExtension::addWidget(QWidget *widget)
+{
+ myWidget->addPage(widget);
+}
+//! [1]
+
+//! [2]
+int MultiPageWidgetContainerExtension::count() const
+{
+ return myWidget->count();
+}
+//! [2]
+
+//! [3]
+int MultiPageWidgetContainerExtension::currentIndex() const
+{
+ return myWidget->currentIndex();
+}
+//! [3]
+
+//! [4]
+void MultiPageWidgetContainerExtension::insertWidget(int index, QWidget *widget)
+{
+ myWidget->insertPage(index, widget);
+}
+//! [4]
+
+//! [5]
+void MultiPageWidgetContainerExtension::remove(int index)
+{
+ myWidget->removePage(index);
+}
+//! [5]
+
+//! [6]
+void MultiPageWidgetContainerExtension::setCurrentIndex(int index)
+{
+ myWidget->setCurrentIndex(index);
+}
+//! [6]
+
+//! [7]
+QWidget* MultiPageWidgetContainerExtension::widget(int index) const
+{
+ return myWidget->widget(index);
+}
+//! [7]
diff --git a/examples/designer/containerextension/multipagewidgetcontainerextension.h b/examples/designer/containerextension/multipagewidgetcontainerextension.h
new file mode 100644
index 000000000..dfb10c625
--- /dev/null
+++ b/examples/designer/containerextension/multipagewidgetcontainerextension.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MULTIPAGEWIDGETCONTAINEREXTENSION_H
+#define MULTIPAGEWIDGETCONTAINEREXTENSION_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+
+QT_BEGIN_NAMESPACE
+class QExtensionManager;
+QT_END_NAMESPACE
+class MultiPageWidget;
+
+//! [0]
+class MultiPageWidgetContainerExtension: public QObject,
+ public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+
+public:
+ MultiPageWidgetContainerExtension(MultiPageWidget *widget, QObject *parent);
+
+ void addWidget(QWidget *widget);
+ int count() const;
+ int currentIndex() const;
+ void insertWidget(int index, QWidget *widget);
+ void remove(int index);
+ void setCurrentIndex(int index);
+ QWidget *widget(int index) const;
+
+private:
+ MultiPageWidget *myWidget;
+};
+//! [0]
+
+#endif
diff --git a/examples/designer/containerextension/multipagewidgetextensionfactory.cpp b/examples/designer/containerextension/multipagewidgetextensionfactory.cpp
new file mode 100644
index 000000000..36f3c8f46
--- /dev/null
+++ b/examples/designer/containerextension/multipagewidgetextensionfactory.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "multipagewidgetextensionfactory.h"
+#include "multipagewidgetcontainerextension.h"
+#include "multipagewidget.h"
+
+//! [0]
+MultiPageWidgetExtensionFactory::MultiPageWidgetExtensionFactory(QExtensionManager *parent)
+ : QExtensionFactory(parent)
+{}
+//! [0]
+
+//! [1]
+QObject *MultiPageWidgetExtensionFactory::createExtension(QObject *object,
+ const QString &iid,
+ QObject *parent) const
+{
+ MultiPageWidget *widget = qobject_cast<MultiPageWidget*>(object);
+
+ if (widget && (iid == Q_TYPEID(QDesignerContainerExtension))) {
+ return new MultiPageWidgetContainerExtension(widget, parent);
+ } else {
+ return 0;
+ }
+}
+//! [1]
diff --git a/examples/designer/containerextension/multipagewidgetextensionfactory.h b/examples/designer/containerextension/multipagewidgetextensionfactory.h
new file mode 100644
index 000000000..2ed2946f6
--- /dev/null
+++ b/examples/designer/containerextension/multipagewidgetextensionfactory.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MULTIPAGEWIDGETEXTENSIONFACTORY_H
+#define MULTIPAGEWIDGETEXTENSIONFACTORY_H
+
+#include <QtDesigner/QExtensionFactory>
+
+QT_BEGIN_NAMESPACE
+class QExtensionManager;
+QT_END_NAMESPACE
+
+//! [0]
+class MultiPageWidgetExtensionFactory: public QExtensionFactory
+{
+ Q_OBJECT
+
+public:
+ MultiPageWidgetExtensionFactory(QExtensionManager *parent = 0);
+
+protected:
+ QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+};
+//! [0]
+
+#endif
diff --git a/examples/designer/containerextension/multipagewidgetplugin.cpp b/examples/designer/containerextension/multipagewidgetplugin.cpp
new file mode 100644
index 000000000..60aab4fea
--- /dev/null
+++ b/examples/designer/containerextension/multipagewidgetplugin.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+
+#include <QIcon>
+#include <QtPlugin>
+
+#include "multipagewidget.h"
+#include "multipagewidgetplugin.h"
+#include "multipagewidgetextensionfactory.h"
+
+//! [0]
+MultiPageWidgetPlugin::MultiPageWidgetPlugin(QObject *parent)
+ :QObject(parent)
+{
+ initialized = false;
+}
+
+QString MultiPageWidgetPlugin::name() const
+{
+ return QLatin1String("MultiPageWidget");
+}
+
+QString MultiPageWidgetPlugin::group() const
+{
+ return QLatin1String("Display Widgets [Examples]");
+}
+
+QString MultiPageWidgetPlugin::toolTip() const
+{
+ return QString();
+}
+
+QString MultiPageWidgetPlugin::whatsThis() const
+{
+ return QString();
+}
+
+QString MultiPageWidgetPlugin::includeFile() const
+{
+ return QLatin1String("multipagewidget.h");
+}
+
+QIcon MultiPageWidgetPlugin::icon() const
+{
+ return QIcon();
+}
+
+//! [0] //! [1]
+bool MultiPageWidgetPlugin::isContainer() const
+{
+ return true;
+}
+
+//! [1] //! [2]
+QWidget *MultiPageWidgetPlugin::createWidget(QWidget *parent)
+{
+ MultiPageWidget *widget = new MultiPageWidget(parent);
+ connect(widget, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(currentIndexChanged(int)));
+ connect(widget, SIGNAL(pageTitleChanged(QString)),
+ this, SLOT(pageTitleChanged(QString)));
+ return widget;
+}
+
+//! [2] //! [3]
+bool MultiPageWidgetPlugin::isInitialized() const
+{
+ return initialized;
+}
+//! [3]
+
+//! [4]
+void MultiPageWidgetPlugin::initialize(QDesignerFormEditorInterface *formEditor)
+{
+ if (initialized)
+ return;
+//! [4]
+
+//! [5]
+ QExtensionManager *manager = formEditor->extensionManager();
+//! [5] //! [6]
+ QExtensionFactory *factory = new MultiPageWidgetExtensionFactory(manager);
+
+ Q_ASSERT(manager != 0);
+ manager->registerExtensions(factory, Q_TYPEID(QDesignerContainerExtension));
+
+ initialized = true;
+}
+//! [6]
+
+//! [7]
+QString MultiPageWidgetPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"MultiPageWidget\" name=\"multipagewidget\">\
+ <widget class=\"QWidget\" name=\"page\" />\
+ </widget>\
+ <customwidgets>\
+ <customwidget>\
+ <class>MultiPageWidget</class>\
+ <extends>QWidget</extends>\
+ <addpagemethod>addPage</addpagemethod>\
+ </customwidget>\
+ </customwidgets>\
+</ui>");
+}
+//! [7]
+
+//! [8]
+void MultiPageWidgetPlugin::currentIndexChanged(int index)
+{
+ Q_UNUSED(index);
+ MultiPageWidget *widget = qobject_cast<MultiPageWidget*>(sender());
+//! [8] //! [9]
+ if (widget) {
+ QDesignerFormWindowInterface *form = QDesignerFormWindowInterface::findFormWindow(widget);
+ if (form)
+ form->emitSelectionChanged();
+ }
+}
+//! [9]
+
+//! [10]
+void MultiPageWidgetPlugin::pageTitleChanged(const QString &title)
+{
+ Q_UNUSED(title);
+ MultiPageWidget *widget = qobject_cast<MultiPageWidget*>(sender());
+//! [10] //! [11]
+ if (widget) {
+ QWidget *page = widget->widget(widget->currentIndex());
+ QDesignerFormWindowInterface *form;
+ form = QDesignerFormWindowInterface::findFormWindow(widget);
+//! [11]
+ if (form) {
+//! [12]
+ QDesignerFormEditorInterface *editor = form->core();
+ QExtensionManager *manager = editor->extensionManager();
+//! [12] //! [13]
+ QDesignerPropertySheetExtension *sheet;
+ sheet = qt_extension<QDesignerPropertySheetExtension*>(manager, page);
+ const int propertyIndex = sheet->indexOf(QLatin1String("windowTitle"));
+ sheet->setChanged(propertyIndex, true);
+ }
+ }
+}
+
+//! [13]
+
+//! [14]
+Q_EXPORT_PLUGIN2(containerextension, MultiPageWidgetPlugin)
+//! [14]
diff --git a/examples/designer/containerextension/multipagewidgetplugin.h b/examples/designer/containerextension/multipagewidgetplugin.h
new file mode 100644
index 000000000..3d9ac52bf
--- /dev/null
+++ b/examples/designer/containerextension/multipagewidgetplugin.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+#ifndef MULTIPAGEWIDGETPLUGIN_H
+#define MULTIPAGEWIDGETPLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+class QIcon;
+class QWidget;
+QT_END_NAMESPACE
+
+class MultiPageWidgetPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ MultiPageWidgetPlugin(QObject *parent = 0);
+
+ QString name() const;
+ QString group() const;
+ QString toolTip() const;
+ QString whatsThis() const;
+ QString includeFile() const;
+ QIcon icon() const;
+ bool isContainer() const;
+ QWidget *createWidget(QWidget *parent);
+ bool isInitialized() const;
+ void initialize(QDesignerFormEditorInterface *formEditor);
+ QString domXml() const;
+
+private slots:
+ void currentIndexChanged(int index);
+ void pageTitleChanged(const QString &title);
+
+private:
+ bool initialized;
+};
+
+#endif
+//! [0]
diff --git a/examples/designer/customwidgetplugin/analogclock.cpp b/examples/designer/customwidgetplugin/analogclock.cpp
new file mode 100644
index 000000000..4a91e0dc0
--- /dev/null
+++ b/examples/designer/customwidgetplugin/analogclock.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "analogclock.h"
+
+AnalogClock::AnalogClock(QWidget *parent)
+ : QWidget(parent)
+{
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(update()));
+ timer->start(1000);
+
+ setWindowTitle(tr("Analog Clock"));
+ resize(200, 200);
+}
+
+void AnalogClock::paintEvent(QPaintEvent *)
+{
+ static const QPoint hourHand[3] = {
+ QPoint(7, 8),
+ QPoint(-7, 8),
+ QPoint(0, -40)
+ };
+ static const QPoint minuteHand[3] = {
+ QPoint(7, 8),
+ QPoint(-7, 8),
+ QPoint(0, -70)
+ };
+
+ QColor hourColor(127, 0, 127);
+ QColor minuteColor(0, 127, 127, 191);
+
+ int side = qMin(width(), height());
+ QTime time = QTime::currentTime();
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.translate(width() / 2, height() / 2);
+ painter.scale(side / 200.0, side / 200.0);
+
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(hourColor);
+
+ painter.save();
+ painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
+ painter.drawConvexPolygon(hourHand, 3);
+ painter.restore();
+
+ painter.setPen(hourColor);
+
+ for (int i = 0; i < 12; ++i) {
+ painter.drawLine(88, 0, 96, 0);
+ painter.rotate(30.0);
+ }
+
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(minuteColor);
+
+ painter.save();
+ painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
+ painter.drawConvexPolygon(minuteHand, 3);
+ painter.restore();
+
+ painter.setPen(minuteColor);
+
+ for (int j = 0; j < 60; ++j) {
+ if ((j % 5) != 0)
+ painter.drawLine(92, 0, 96, 0);
+ painter.rotate(6.0);
+ }
+}
diff --git a/examples/designer/customwidgetplugin/analogclock.h b/examples/designer/customwidgetplugin/analogclock.h
new file mode 100644
index 000000000..db42d5af3
--- /dev/null
+++ b/examples/designer/customwidgetplugin/analogclock.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANALOGCLOCK_H
+#define ANALOGCLOCK_H
+
+#include <QWidget>
+#include <QtDesigner/QDesignerExportWidget>
+
+class QDESIGNER_WIDGET_EXPORT AnalogClock : public QWidget
+{
+ Q_OBJECT
+
+public:
+ AnalogClock(QWidget *parent = 0);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+};
+
+#endif
diff --git a/examples/designer/customwidgetplugin/customwidgetplugin.cpp b/examples/designer/customwidgetplugin/customwidgetplugin.cpp
new file mode 100644
index 000000000..d6ab592d2
--- /dev/null
+++ b/examples/designer/customwidgetplugin/customwidgetplugin.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "analogclock.h"
+#include "customwidgetplugin.h"
+
+#include <QtPlugin>
+
+//! [0]
+AnalogClockPlugin::AnalogClockPlugin(QObject *parent)
+ : QObject(parent)
+{
+ initialized = false;
+}
+//! [0]
+
+//! [1]
+void AnalogClockPlugin::initialize(QDesignerFormEditorInterface * /* core */)
+{
+ if (initialized)
+ return;
+
+ initialized = true;
+}
+//! [1]
+
+//! [2]
+bool AnalogClockPlugin::isInitialized() const
+{
+ return initialized;
+}
+//! [2]
+
+//! [3]
+QWidget *AnalogClockPlugin::createWidget(QWidget *parent)
+{
+ return new AnalogClock(parent);
+}
+//! [3]
+
+//! [4]
+QString AnalogClockPlugin::name() const
+{
+ return "AnalogClock";
+}
+//! [4]
+
+//! [5]
+QString AnalogClockPlugin::group() const
+{
+ return "Display Widgets [Examples]";
+}
+//! [5]
+
+//! [6]
+QIcon AnalogClockPlugin::icon() const
+{
+ return QIcon();
+}
+//! [6]
+
+//! [7]
+QString AnalogClockPlugin::toolTip() const
+{
+ return "";
+}
+//! [7]
+
+//! [8]
+QString AnalogClockPlugin::whatsThis() const
+{
+ return "";
+}
+//! [8]
+
+//! [9]
+bool AnalogClockPlugin::isContainer() const
+{
+ return false;
+}
+//! [9]
+
+//! [10]
+QString AnalogClockPlugin::domXml() const
+{
+ return "<ui language=\"c++\">\n"
+ " <widget class=\"AnalogClock\" name=\"analogClock\">\n"
+//! [11]
+ " <property name=\"geometry\">\n"
+ " <rect>\n"
+ " <x>0</x>\n"
+ " <y>0</y>\n"
+ " <width>100</width>\n"
+ " <height>100</height>\n"
+ " </rect>\n"
+ " </property>\n"
+//! [11]
+ " <property name=\"toolTip\" >\n"
+ " <string>The current time</string>\n"
+ " </property>\n"
+ " <property name=\"whatsThis\" >\n"
+ " <string>The analog clock widget displays the current time.</string>\n"
+ " </property>\n"
+ " </widget>\n"
+ "</ui>\n";
+}
+//! [10]
+
+//! [12]
+QString AnalogClockPlugin::includeFile() const
+{
+ return "analogclock.h";
+}
+//! [12]
+
+//! [13]
+Q_EXPORT_PLUGIN2(customwidgetplugin, AnalogClockPlugin)
+//! [13]
diff --git a/examples/designer/customwidgetplugin/customwidgetplugin.h b/examples/designer/customwidgetplugin/customwidgetplugin.h
new file mode 100644
index 000000000..72f916b25
--- /dev/null
+++ b/examples/designer/customwidgetplugin/customwidgetplugin.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CUSTOMWIDGETPLUGIN_H
+#define CUSTOMWIDGETPLUGIN_H
+
+#include <QDesignerCustomWidgetInterface>
+
+//! [0]
+class AnalogClockPlugin : public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+
+public:
+ AnalogClockPlugin(QObject *parent = 0);
+
+ bool isContainer() const;
+ bool isInitialized() const;
+ QIcon icon() const;
+ QString domXml() const;
+ QString group() const;
+ QString includeFile() const;
+ QString name() const;
+ QString toolTip() const;
+ QString whatsThis() const;
+ QWidget *createWidget(QWidget *parent);
+ void initialize(QDesignerFormEditorInterface *core);
+
+private:
+ bool initialized;
+};
+//! [0]
+
+#endif
diff --git a/examples/designer/customwidgetplugin/customwidgetplugin.pro b/examples/designer/customwidgetplugin/customwidgetplugin.pro
new file mode 100644
index 000000000..0d37874b7
--- /dev/null
+++ b/examples/designer/customwidgetplugin/customwidgetplugin.pro
@@ -0,0 +1,23 @@
+#! [0] #! [1]
+CONFIG += designer plugin
+#! [0]
+TARGET = $$qtLibraryTarget($$TARGET)
+#! [2]
+TEMPLATE = lib
+#! [1] #! [2]
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/designer
+
+#! [3]
+HEADERS = analogclock.h \
+ customwidgetplugin.h
+SOURCES = analogclock.cpp \
+ customwidgetplugin.cpp
+#! [3]
+
+# install
+target.path = $$[QT_INSTALL_PLUGINS]/designer
+sources.files = $$SOURCES $$HEADERS *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/customwidgetplugin
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/designer/designer.pro b/examples/designer/designer.pro
new file mode 100644
index 000000000..0c1d637c8
--- /dev/null
+++ b/examples/designer/designer.pro
@@ -0,0 +1,21 @@
+TEMPLATE = subdirs
+SUBDIRS = calculatorform
+
+!static:SUBDIRS += calculatorbuilder \
+ containerextension \
+ customwidgetplugin \
+ taskmenuextension \
+ worldtimeclockbuilder \
+ worldtimeclockplugin
+
+# the sun cc compiler has a problem with the include lines for the form.prf
+solaris-cc*:SUBDIRS -= calculatorbuilder \
+ worldtimeclockbuilder
+
+
+# install
+sources.files = README *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer
+INSTALLS += sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/designer/taskmenuextension/taskmenuextension.pro b/examples/designer/taskmenuextension/taskmenuextension.pro
new file mode 100644
index 000000000..ab0b36d2b
--- /dev/null
+++ b/examples/designer/taskmenuextension/taskmenuextension.pro
@@ -0,0 +1,27 @@
+#! [0]
+TEMPLATE = lib
+#! [0]
+TARGET = $$qtLibraryTarget($$TARGET)
+#! [1]
+CONFIG += designer plugin
+#! [1]
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/designer
+
+#! [2]
+HEADERS += tictactoe.h \
+ tictactoedialog.h \
+ tictactoeplugin.h \
+ tictactoetaskmenu.h
+SOURCES += tictactoe.cpp \
+ tictactoedialog.cpp \
+ tictactoeplugin.cpp \
+ tictactoetaskmenu.cpp
+#! [2]
+
+# install
+target.path = $$[QT_INSTALL_PLUGINS]/designer
+sources.files = $$SOURCES $$HEADERS *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/taskmenuextension
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/designer/taskmenuextension/tictactoe.cpp b/examples/designer/taskmenuextension/tictactoe.cpp
new file mode 100644
index 000000000..6a258933a
--- /dev/null
+++ b/examples/designer/taskmenuextension/tictactoe.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "tictactoe.h"
+
+TicTacToe::TicTacToe(QWidget *parent)
+ : QWidget(parent)
+{
+}
+
+QSize TicTacToe::minimumSizeHint() const
+{
+ return QSize(200, 200);
+}
+
+QSize TicTacToe::sizeHint() const
+{
+ return QSize(200, 200);
+}
+
+void TicTacToe::setState(const QString &newState)
+{
+ turnNumber = 0;
+ myState = "---------";
+ int position = 0;
+ while (position < 9 && position < newState.length()) {
+ QChar mark = newState.at(position);
+ if (mark == Cross || mark == Nought) {
+ ++turnNumber;
+ myState.replace(position, 1, mark);
+ }
+ position++;
+ }
+ update();
+}
+
+QString TicTacToe::state() const
+{
+ return myState;
+}
+
+void TicTacToe::clearBoard()
+{
+ myState = "---------";
+ turnNumber = 0;
+ update();
+}
+
+void TicTacToe::mousePressEvent(QMouseEvent *event)
+{
+ if (turnNumber == 9) {
+ clearBoard();
+ update();
+ } else {
+ for (int position = 0; position < 9; ++position) {
+ QRect cell = cellRect(position / 3, position % 3);
+ if (cell.contains(event->pos())) {
+ if (myState.at(position) == Empty) {
+ if (turnNumber % 2 == 0)
+ myState.replace(position, 1, Cross);
+ else
+ myState.replace(position, 1, Nought);
+ ++turnNumber;
+ update();
+ }
+ }
+ }
+ }
+}
+
+void TicTacToe::paintEvent(QPaintEvent * /* event */)
+{
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ painter.setPen(QPen(Qt::darkGreen, 1));
+ painter.drawLine(cellWidth(), 0, cellWidth(), height());
+ painter.drawLine(2 * cellWidth(), 0, 2 * cellWidth(), height());
+ painter.drawLine(0, cellHeight(), width(), cellHeight());
+ painter.drawLine(0, 2 * cellHeight(), width(), 2 * cellHeight());
+
+ painter.setPen(QPen(Qt::darkBlue, 2));
+
+ for (int position = 0; position < 9; ++position) {
+ QRect cell = cellRect(position / 3, position % 3);
+
+ if (myState.at(position) == Cross) {
+ painter.drawLine(cell.topLeft(), cell.bottomRight());
+ painter.drawLine(cell.topRight(), cell.bottomLeft());
+ } else if (myState.at(position) == Nought) {
+ painter.drawEllipse(cell);
+ }
+ }
+
+ painter.setPen(QPen(Qt::yellow, 3));
+
+ for (int position = 0; position < 9; position = position + 3) {
+ if (myState.at(position) != Empty
+ && myState.at(position + 1) == myState.at(position)
+ && myState.at(position + 2) == myState.at(position)) {
+ int y = cellRect((position / 3), 0).center().y();
+ painter.drawLine(0, y, width(), y);
+ turnNumber = 9;
+ }
+ }
+
+ for (int position = 0; position < 3; ++position) {
+ if (myState.at(position) != Empty
+ && myState.at(position + 3) == myState.at(position)
+ && myState.at(position + 6) == myState.at(position)) {
+ int x = cellRect(0, position).center().x();
+ painter.drawLine(x, 0, x, height());
+ turnNumber = 9;
+ }
+ }
+ if (myState.at(0) != Empty && myState.at(4) == myState.at(0)
+ && myState.at(8) == myState.at(0)) {
+ painter.drawLine(0, 0, width(), height());
+ turnNumber = 9;
+ }
+ if (myState.at(2) != Empty && myState.at(4) == myState.at(2)
+ && myState.at(6) == myState.at(2)) {
+ painter.drawLine(0, height(), width(), 0);
+ turnNumber = 9;
+ }
+}
+
+QRect TicTacToe::cellRect(int row, int column) const
+{
+ const int HMargin = width() / 30;
+ const int VMargin = height() / 30;
+ return QRect(column * cellWidth() + HMargin,
+ row * cellHeight() + VMargin,
+ cellWidth() - 2 * HMargin,
+ cellHeight() - 2 * VMargin);
+}
diff --git a/examples/designer/taskmenuextension/tictactoe.h b/examples/designer/taskmenuextension/tictactoe.h
new file mode 100644
index 000000000..53ccf0472
--- /dev/null
+++ b/examples/designer/taskmenuextension/tictactoe.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TICTACTOE_H
+#define TICTACTOE_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QRect;
+class QSize;
+QT_END_NAMESPACE
+
+//! [0]
+class TicTacToe : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QString state READ state WRITE setState)
+
+public:
+ TicTacToe(QWidget *parent = 0);
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+ void setState(const QString &newState);
+ QString state() const;
+ void clearBoard();
+
+protected:
+ void mousePressEvent(QMouseEvent *event);
+ void paintEvent(QPaintEvent *event);
+
+private:
+ enum { Empty = '-', Cross = 'X', Nought = 'O' };
+
+ QRect cellRect(int row, int col) const;
+ int cellWidth() const { return width() / 3; }
+ int cellHeight() const { return height() / 3; }
+
+ QString myState;
+ int turnNumber;
+};
+//! [0]
+
+#endif
diff --git a/examples/designer/taskmenuextension/tictactoedialog.cpp b/examples/designer/taskmenuextension/tictactoedialog.cpp
new file mode 100644
index 000000000..5af3c6f30
--- /dev/null
+++ b/examples/designer/taskmenuextension/tictactoedialog.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include <QtDesigner>
+
+#include "tictactoe.h"
+#include "tictactoedialog.h"
+
+//! [0]
+TicTacToeDialog::TicTacToeDialog(TicTacToe *tic, QWidget *parent)
+ : QDialog(parent)
+{
+ ticTacToe = tic;
+ editor = new TicTacToe;
+ editor->setState(ticTacToe->state());
+
+ buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
+ | QDialogButtonBox::Cancel
+ | QDialogButtonBox::Reset);
+
+ connect(buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()),
+ this, SLOT(resetState()));
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(saveState()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(editor);
+ mainLayout->addWidget(buttonBox);
+
+ setLayout(mainLayout);
+ setWindowTitle(tr("Edit State"));
+}
+//! [0]
+
+//! [1]
+QSize TicTacToeDialog::sizeHint() const
+{
+ return QSize(250, 250);
+}
+//! [1]
+
+//! [2]
+void TicTacToeDialog::resetState()
+{
+ editor->clearBoard();
+}
+//! [2]
+
+//! [3]
+void TicTacToeDialog::saveState()
+{
+//! [3] //! [4]
+ if (QDesignerFormWindowInterface *formWindow
+ = QDesignerFormWindowInterface::findFormWindow(ticTacToe)) {
+ formWindow->cursor()->setProperty("state", editor->state());
+ }
+//! [4] //! [5]
+ accept();
+}
+//! [5]
diff --git a/examples/designer/taskmenuextension/tictactoedialog.h b/examples/designer/taskmenuextension/tictactoedialog.h
new file mode 100644
index 000000000..163ab8966
--- /dev/null
+++ b/examples/designer/taskmenuextension/tictactoedialog.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TICTACTOEDIALOG_H
+#define TICTACTOEDIALOG_H
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+class QDialogButtonBox;
+QT_END_NAMESPACE
+class TicTacToe;
+
+//! [0]
+class TicTacToeDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit TicTacToeDialog(TicTacToe *plugin = 0, QWidget *parent = 0);
+
+ QSize sizeHint() const;
+
+private slots:
+ void resetState();
+ void saveState();
+
+private:
+ TicTacToe *editor;
+ TicTacToe *ticTacToe;
+ QDialogButtonBox *buttonBox;
+};
+//! [0]
+
+#endif
diff --git a/examples/designer/taskmenuextension/tictactoeplugin.cpp b/examples/designer/taskmenuextension/tictactoeplugin.cpp
new file mode 100644
index 000000000..45c078c98
--- /dev/null
+++ b/examples/designer/taskmenuextension/tictactoeplugin.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner>
+#include <QtGui>
+#include <QtPlugin>
+
+#include "tictactoe.h"
+#include "tictactoeplugin.h"
+#include "tictactoetaskmenu.h"
+
+//! [0]
+TicTacToePlugin::TicTacToePlugin(QObject *parent)
+ : QObject(parent)
+{
+ initialized = false;
+}
+
+QString TicTacToePlugin::name() const
+{
+ return "TicTacToe";
+}
+
+QString TicTacToePlugin::group() const
+{
+ return "Display Widgets [Examples]";
+}
+
+QString TicTacToePlugin::toolTip() const
+{
+ return "";
+}
+
+QString TicTacToePlugin::whatsThis() const
+{
+ return "";
+}
+
+QString TicTacToePlugin::includeFile() const
+{
+ return "tictactoe.h";
+}
+
+QIcon TicTacToePlugin::icon() const
+{
+ return QIcon();
+}
+
+bool TicTacToePlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *TicTacToePlugin::createWidget(QWidget *parent)
+{
+ TicTacToe *ticTacToe = new TicTacToe(parent);
+ ticTacToe->setState("-X-XO----");
+ return ticTacToe;
+}
+
+bool TicTacToePlugin::isInitialized() const
+{
+ return initialized;
+}
+
+//! [0] //! [1]
+void TicTacToePlugin::initialize(QDesignerFormEditorInterface *formEditor)
+{
+//! [1] //! [2]
+ if (initialized)
+ return;
+
+ QExtensionManager *manager = formEditor->extensionManager();
+ Q_ASSERT(manager != 0);
+//! [2]
+
+//! [3]
+ manager->registerExtensions(new TicTacToeTaskMenuFactory(manager),
+ Q_TYPEID(QDesignerTaskMenuExtension));
+
+ initialized = true;
+}
+
+QString TicTacToePlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"TicTacToe\" name=\"ticTacToe\"/>\
+ <customwidgets>\
+ <customwidget>\
+ <class>TicTacToe</class>\
+ <propertyspecifications>\
+ <stringpropertyspecification name=\"state\" notr=\"true\" type=\"singleline\"/>\
+ </propertyspecifications>\
+ </customwidget>\
+ </customwidgets>\
+</ui>");
+}
+
+//! [3]
+
+//! [4]
+Q_EXPORT_PLUGIN2(taskmenuextension, TicTacToePlugin)
+//! [4]
diff --git a/examples/designer/taskmenuextension/tictactoeplugin.h b/examples/designer/taskmenuextension/tictactoeplugin.h
new file mode 100644
index 000000000..6bd6065ab
--- /dev/null
+++ b/examples/designer/taskmenuextension/tictactoeplugin.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+#ifndef TICTACTOEPLUGIN_H
+#define TICTACTOEPLUGIN_H
+
+#include <QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+class QIcon;
+class QWidget;
+QT_END_NAMESPACE
+
+class TicTacToePlugin : public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+
+public:
+ TicTacToePlugin(QObject *parent = 0);
+
+ QString name() const;
+ QString group() const;
+ QString toolTip() const;
+ QString whatsThis() const;
+ QString includeFile() const;
+ QIcon icon() const;
+ bool isContainer() const;
+ QWidget *createWidget(QWidget *parent);
+ bool isInitialized() const;
+ void initialize(QDesignerFormEditorInterface *formEditor);
+ QString domXml() const;
+
+private:
+ bool initialized;
+};
+
+#endif
+//! [0]
diff --git a/examples/designer/taskmenuextension/tictactoetaskmenu.cpp b/examples/designer/taskmenuextension/tictactoetaskmenu.cpp
new file mode 100644
index 000000000..79fe88e88
--- /dev/null
+++ b/examples/designer/taskmenuextension/tictactoetaskmenu.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner>
+#include <QtGui>
+
+#include "tictactoe.h"
+#include "tictactoedialog.h"
+#include "tictactoetaskmenu.h"
+
+//! [0]
+TicTacToeTaskMenu::TicTacToeTaskMenu(TicTacToe *tic, QObject *parent)
+ : QObject(parent)
+{
+ ticTacToe = tic;
+
+ editStateAction = new QAction(tr("Edit State..."), this);
+ connect(editStateAction, SIGNAL(triggered()), this, SLOT(editState()));
+}
+//! [0]
+
+//! [1]
+void TicTacToeTaskMenu::editState()
+{
+ TicTacToeDialog dialog(ticTacToe);
+ dialog.exec();
+}
+//! [1]
+
+//! [2]
+QAction *TicTacToeTaskMenu::preferredEditAction() const
+{
+ return editStateAction;
+}
+//! [2]
+
+//! [3]
+QList<QAction *> TicTacToeTaskMenu::taskActions() const
+{
+ QList<QAction *> list;
+ list.append(editStateAction);
+ return list;
+}
+//! [3]
+
+//! [4]
+TicTacToeTaskMenuFactory::TicTacToeTaskMenuFactory(QExtensionManager *parent)
+ : QExtensionFactory(parent)
+{
+}
+//! [4]
+
+//! [5]
+QObject *TicTacToeTaskMenuFactory::createExtension(QObject *object,
+ const QString &iid,
+ QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerTaskMenuExtension))
+ return 0;
+
+ if (TicTacToe *tic = qobject_cast<TicTacToe*>(object))
+ return new TicTacToeTaskMenu(tic, parent);
+
+ return 0;
+}
+//! [5]
diff --git a/examples/designer/taskmenuextension/tictactoetaskmenu.h b/examples/designer/taskmenuextension/tictactoetaskmenu.h
new file mode 100644
index 000000000..8e203d0d9
--- /dev/null
+++ b/examples/designer/taskmenuextension/tictactoetaskmenu.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TICTACTOETASKMENU_H
+#define TICTACTOETASKMENU_H
+
+#include <QDesignerTaskMenuExtension>
+#include <QExtensionFactory>
+
+QT_BEGIN_NAMESPACE
+class QAction;
+class QExtensionManager;
+QT_END_NAMESPACE
+class TicTacToe;
+
+//! [0]
+class TicTacToeTaskMenu : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+
+public:
+ TicTacToeTaskMenu(TicTacToe *tic, QObject *parent);
+
+ QAction *preferredEditAction() const;
+ QList<QAction *> taskActions() const;
+
+private slots:
+ void editState();
+
+private:
+ QAction *editStateAction;
+ TicTacToe *ticTacToe;
+};
+//! [0]
+
+//! [1]
+class TicTacToeTaskMenuFactory : public QExtensionFactory
+{
+ Q_OBJECT
+
+public:
+ TicTacToeTaskMenuFactory(QExtensionManager *parent = 0);
+
+protected:
+ QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+};
+//! [1]
+
+#endif
diff --git a/examples/designer/worldtimeclockbuilder/form.ui b/examples/designer/worldtimeclockbuilder/form.ui
new file mode 100644
index 000000000..e5be1d911
--- /dev/null
+++ b/examples/designer/worldtimeclockbuilder/form.ui
@@ -0,0 +1,162 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>WorldTimeForm</class>
+ <widget class="QWidget" name="WorldTimeForm" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>World Time Clock</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="WorldTimeClock" name="worldTimeClock" />
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Current time:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTimeEdit" name="timeEdit" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Set time zone:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBox" >
+ <property name="maximum" >
+ <number>12</number>
+ </property>
+ <property name="minimum" >
+ <number>-12</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <customwidgets>
+ <customwidget>
+ <class>WorldTimeClock</class>
+ <extends></extends>
+ <header>worldtimeclock.h</header>
+ <container>0</container>
+ <pixmap></pixmap>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>spinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>worldTimeClock</receiver>
+ <slot>setTimeZone(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>339</x>
+ <y>166</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>230</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>worldTimeClock</sender>
+ <signal>updated(QTime)</signal>
+ <receiver>timeEdit</receiver>
+ <slot>setTime(QTime)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>141</x>
+ <y>59</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>291</x>
+ <y>133</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/designer/worldtimeclockbuilder/main.cpp b/examples/designer/worldtimeclockbuilder/main.cpp
new file mode 100644
index 000000000..680394190
--- /dev/null
+++ b/examples/designer/worldtimeclockbuilder/main.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+#include <QtUiTools>
+//! [0]
+#include <QtGui>
+
+//! [1]
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(worldtimeclockbuilder);
+
+ QApplication app(argc, argv);
+
+ QUiLoader loader;
+//! [1]
+
+//! [2]
+ QFile file(":/forms/form.ui");
+ file.open(QFile::ReadOnly);
+
+ QWidget *widget = loader.load(&file);
+
+ file.close();
+ widget->show();
+//! [2]
+
+//! [3]
+ return app.exec();
+}
+//! [3]
diff --git a/examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.pro b/examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.pro
new file mode 100644
index 000000000..94fa49766
--- /dev/null
+++ b/examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.pro
@@ -0,0 +1,13 @@
+#! [0]
+CONFIG += uitools
+SOURCES = main.cpp
+RESOURCES = worldtimeclockbuilder.qrc
+#! [0]
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/worldtimeclockbuilder
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.ui *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/worldtimeclockbuilder
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.qrc b/examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.qrc
new file mode 100644
index 000000000..89d5ac3c2
--- /dev/null
+++ b/examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/forms">
+ <file>form.ui</file>
+</qresource>
+</RCC>
diff --git a/examples/designer/worldtimeclockplugin/worldtimeclock.cpp b/examples/designer/worldtimeclockplugin/worldtimeclock.cpp
new file mode 100644
index 000000000..088c6e97e
--- /dev/null
+++ b/examples/designer/worldtimeclockplugin/worldtimeclock.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "worldtimeclock.h"
+
+WorldTimeClock::WorldTimeClock(QWidget *parent)
+ : QWidget(parent)
+{
+ timeZoneOffset = 0;
+
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(update()));
+ timer->start(1000);
+
+ setWindowTitle(tr("World Time Clock"));
+ resize(200, 200);
+}
+
+void WorldTimeClock::paintEvent(QPaintEvent *)
+{
+ static const QPoint hourHand[3] = {
+ QPoint(7, 8),
+ QPoint(-7, 8),
+ QPoint(0, -40)
+ };
+ static const QPoint minuteHand[3] = {
+ QPoint(7, 8),
+ QPoint(-7, 8),
+ QPoint(0, -70)
+ };
+
+ QColor hourColor(127, 0, 127);
+ QColor minuteColor(0, 127, 127, 191);
+
+ int side = qMin(width(), height());
+ QTime time = QTime::currentTime();
+ time = time.addSecs(timeZoneOffset);
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.translate(width() / 2, height() / 2);
+ painter.scale(side / 200.0, side / 200.0);
+
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(hourColor);
+
+ painter.save();
+ painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
+ painter.drawConvexPolygon(hourHand, 3);
+ painter.restore();
+
+ painter.setPen(hourColor);
+
+ for (int i = 0; i < 12; ++i) {
+ painter.drawLine(88, 0, 96, 0);
+ painter.rotate(30.0);
+ }
+
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(minuteColor);
+
+ painter.save();
+ painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
+ painter.drawConvexPolygon(minuteHand, 3);
+ painter.restore();
+
+ painter.setPen(minuteColor);
+
+ for (int j = 0; j < 60; ++j) {
+ if ((j % 5) != 0)
+ painter.drawLine(92, 0, 96, 0);
+ painter.rotate(6.0);
+ }
+
+ emit updated(time);
+}
+
+void WorldTimeClock::setTimeZone(int hourOffset)
+{
+ timeZoneOffset = qMin(qMax(-12, hourOffset), 12) * 3600;
+ update();
+}
diff --git a/examples/designer/worldtimeclockplugin/worldtimeclock.h b/examples/designer/worldtimeclockplugin/worldtimeclock.h
new file mode 100644
index 000000000..dc5933c33
--- /dev/null
+++ b/examples/designer/worldtimeclockplugin/worldtimeclock.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WORLDTIMECLOCK_H
+#define WORLDTIMECLOCK_H
+
+#include <QTime>
+#include <QWidget>
+#include <QtDesigner/QDesignerExportWidget>
+
+//! [0] //! [1]
+class QDESIGNER_WIDGET_EXPORT WorldTimeClock : public QWidget
+{
+ Q_OBJECT
+//! [0]
+
+public:
+ WorldTimeClock(QWidget *parent = 0);
+
+public slots:
+ void setTimeZone(int hourOffset);
+
+signals:
+ void updated(QTime currentTime);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ int timeZoneOffset;
+//! [2]
+};
+//! [1] //! [2]
+
+#endif
diff --git a/examples/designer/worldtimeclockplugin/worldtimeclockplugin.cpp b/examples/designer/worldtimeclockplugin/worldtimeclockplugin.cpp
new file mode 100644
index 000000000..88b8d45b0
--- /dev/null
+++ b/examples/designer/worldtimeclockplugin/worldtimeclockplugin.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "worldtimeclock.h"
+#include "worldtimeclockplugin.h"
+
+#include <QtPlugin>
+
+WorldTimeClockPlugin::WorldTimeClockPlugin(QObject *parent)
+ : QObject(parent)
+{
+ initialized = false;
+}
+
+void WorldTimeClockPlugin::initialize(QDesignerFormEditorInterface * /* core */)
+{
+ if (initialized)
+ return;
+
+ initialized = true;
+}
+
+bool WorldTimeClockPlugin::isInitialized() const
+{
+ return initialized;
+}
+
+QWidget *WorldTimeClockPlugin::createWidget(QWidget *parent)
+{
+ return new WorldTimeClock(parent);
+}
+
+QString WorldTimeClockPlugin::name() const
+{
+ return "WorldTimeClock";
+}
+
+QString WorldTimeClockPlugin::group() const
+{
+ return "Display Widgets [Examples]";
+}
+
+QIcon WorldTimeClockPlugin::icon() const
+{
+ return QIcon();
+}
+
+QString WorldTimeClockPlugin::toolTip() const
+{
+ return "";
+}
+
+QString WorldTimeClockPlugin::whatsThis() const
+{
+ return "";
+}
+
+bool WorldTimeClockPlugin::isContainer() const
+{
+ return false;
+}
+
+QString WorldTimeClockPlugin::domXml() const
+{
+ return "<ui language=\"c++\">\n"
+ " <widget class=\"WorldTimeClock\" name=\"worldTimeClock\">\n"
+ " <property name=\"geometry\">\n"
+ " <rect>\n"
+ " <x>0</x>\n"
+ " <y>0</y>\n"
+ " <width>100</width>\n"
+ " <height>100</height>\n"
+ " </rect>\n"
+ " </property>\n"
+ " </widget>\n"
+ "</ui>";
+}
+
+QString WorldTimeClockPlugin::includeFile() const
+{
+ return "worldtimeclock.h";
+}
+
+//! [0]
+Q_EXPORT_PLUGIN2(worldtimeclockplugin, WorldTimeClockPlugin)
+//! [0]
diff --git a/examples/designer/worldtimeclockplugin/worldtimeclockplugin.h b/examples/designer/worldtimeclockplugin/worldtimeclockplugin.h
new file mode 100644
index 000000000..91c4b5202
--- /dev/null
+++ b/examples/designer/worldtimeclockplugin/worldtimeclockplugin.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WORLDTIMECLOCKPLUGIN_H
+#define WORLDTIMECLOCKPLUGIN_H
+
+#include <QDesignerCustomWidgetInterface>
+
+//! [0]
+class WorldTimeClockPlugin : public QObject,
+ public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+
+public:
+ WorldTimeClockPlugin(QObject *parent = 0);
+
+ bool isContainer() const;
+ bool isInitialized() const;
+ QIcon icon() const;
+ QString domXml() const;
+ QString group() const;
+ QString includeFile() const;
+ QString name() const;
+ QString toolTip() const;
+ QString whatsThis() const;
+ QWidget *createWidget(QWidget *parent);
+ void initialize(QDesignerFormEditorInterface *core);
+
+private:
+ bool initialized;
+};
+//! [0]
+
+#endif
diff --git a/examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro b/examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro
new file mode 100644
index 000000000..01340e873
--- /dev/null
+++ b/examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro
@@ -0,0 +1,23 @@
+#! [0]
+CONFIG += designer plugin
+#! [0]
+TARGET = $$qtLibraryTarget($$TARGET)
+#! [1]
+TEMPLATE = lib
+#! [1]
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/designer
+
+#! [2]
+HEADERS = worldtimeclock.h \
+ worldtimeclockplugin.h
+SOURCES = worldtimeclock.cpp \
+ worldtimeclockplugin.cpp
+#! [2]
+
+# install
+target.path = $$[QT_INSTALL_PLUGINS]/designer
+sources.files = $$SOURCES $$HEADERS *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/designer/worldtimeclockplugin
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/examples.pro b/examples/examples.pro
new file mode 100644
index 000000000..e2f2c617f
--- /dev/null
+++ b/examples/examples.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += help designer
diff --git a/examples/help/README b/examples/help/README
new file mode 100644
index 000000000..85f5a4373
--- /dev/null
+++ b/examples/help/README
@@ -0,0 +1,38 @@
+Support for interactive help is provided by the Qt Assistant application.
+Developers can take advantages of the facilities it offers to display
+specially-prepared documentation to users of their applications.
+
+
+The example launcher provided with Qt can be used to explore each of the
+examples in this directory.
+
+Documentation for these examples can be found via the Tutorial and Examples
+link in the main Qt documentation.
+
+
+Finding the Qt Examples and Demos launcher
+==========================================
+
+On Windows:
+
+The launcher can be accessed via the Windows Start menu. Select the menu
+entry entitled "Qt Examples and Demos" entry in the submenu containing
+the Qt tools.
+
+On Mac OS X:
+
+For the binary distribution, the qtdemo executable is installed in the
+/Developer/Applications/Qt directory. For the source distribution, it is
+installed alongside the other Qt tools on the path specified when Qt is
+configured.
+
+On Unix/Linux:
+
+The qtdemo executable is installed alongside the other Qt tools on the path
+specified when Qt is configured.
+
+On all platforms:
+
+The source code for the launcher can be found in the demos/qtdemo directory
+in the Qt package. This example is built at the same time as the Qt libraries,
+tools, examples, and demonstrations.
diff --git a/examples/help/contextsensitivehelp/contextsensitivehelp.pro b/examples/help/contextsensitivehelp/contextsensitivehelp.pro
new file mode 100644
index 000000000..ef85c840d
--- /dev/null
+++ b/examples/help/contextsensitivehelp/contextsensitivehelp.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+
+CONFIG += help
+
+SOURCES += main.cpp \
+ wateringconfigdialog.cpp \
+ helpbrowser.cpp
+
+HEADERS += wateringconfigdialog.h \
+ helpbrowser.h
+
+FORMS += wateringconfigdialog.ui
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qttools/help/contextsensitivehelp
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro *.png *.doc doc
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/help/contextsensitivehelp
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/help/contextsensitivehelp/doc/amount.html b/examples/help/contextsensitivehelp/doc/amount.html
new file mode 100644
index 000000000..7a02a6fd5
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/amount.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>Water amount</title>
+ </head>
+ <body>
+ Depending on the plant, temperature and rain fall the amount needs to be larger
+ or smaller. On a really hot day without rain, the suggested <a href="plants.html">amount</a>
+ can be increased by about 10%.
+ </body>
+</html>
diff --git a/examples/help/contextsensitivehelp/doc/filter.html b/examples/help/contextsensitivehelp/doc/filter.html
new file mode 100644
index 000000000..64861126d
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/filter.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>Filter</title>
+</head>
+<body>
+Depending on the source of water, it needs to be filtered or not. Filtering
+is strongly recommened for the river and lake.
+
+
+</body>
+</html>
diff --git a/examples/help/contextsensitivehelp/doc/plants.html b/examples/help/contextsensitivehelp/doc/plants.html
new file mode 100644
index 000000000..2d2bb6788
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/plants.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>Plants</title>
+ </head>
+ <body>
+ Different kind of plants need different amounts of water. Here's a short
+ overview over the most common grown plants and their avarage need of water:
+ <br>
+ <table border=1>
+ <tr>
+ <td>Kind</td>
+ <td>Amount</td>
+ </tr>
+ <tr>
+ <td>Squash</td>
+ <td>2000</td>
+ </tr>
+ <tr>
+ <td>Bean</td>
+ <td>1500</td>
+ </tr>
+ <tr>
+ <td>Carrot</td>
+ <td>1200</td>
+ </tr>
+ <tr>
+ <td>Strawberry</td>
+ <td>1300</td>
+ </tr>
+ <tr>
+ <td>Raspberry</td>
+ <td>1000</td>
+ </tr>
+ <tr>
+ <td>Blueberry</td>
+ <td>1100</td>
+ </tr>
+ </table>
+ <br><br>
+ <font color="#ff0000">Warning:</font> Watering them too much or too little will
+ cause irreversible damage!
+ </body>
+</html>
diff --git a/examples/help/contextsensitivehelp/doc/rain.html b/examples/help/contextsensitivehelp/doc/rain.html
new file mode 100644
index 000000000..1ffe45240
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/rain.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>Rain</title>
+ </head>
+ <body>
+ Depending on the rain fall, the automated watering system should not be
+ switched on at all. Also, the <a href="./temperature.html">temperature</a> should be
+ considered.
+ </body>
+</html>
diff --git a/examples/help/contextsensitivehelp/doc/source.html b/examples/help/contextsensitivehelp/doc/source.html
new file mode 100644
index 000000000..68b2f8c71
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/source.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>Water Source</title>
+ </head>
+ <body>
+ The current pipe system connects to four different sources. Be aware
+ that only a limited amount of water can be taken from some sources.
+ <br>
+ <table border=1>
+ <tr>
+ <td>Source</td>
+ <td>Amount</td>
+ </tr>
+ <tr>
+ <td>Fountain</td>
+ <td>4000</td>
+ </tr>
+ <tr>
+ <td>River</td>
+ <td>6000</td>
+ </tr>
+ <tr>
+ <td>Lake</td>
+ <td>10000</td>
+ </tr>
+ <tr>
+ <td>Public Water System</td>
+ <td>unlimited</td>
+ </tr>
+ </table>
+ </body>
+</html>
diff --git a/examples/help/contextsensitivehelp/doc/temperature.html b/examples/help/contextsensitivehelp/doc/temperature.html
new file mode 100644
index 000000000..4145ed725
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/temperature.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>Temperature</title>
+ </head>
+ <body>
+ Depending on the temperature, the plants need more or less water. The higher
+ the temperature the higher the need for water. If the temperature does not
+ reach a certain level, maybe no automatic watering should be done at all.<br>
+ Before setting this parameter for good, you should also take the amount of <a href="./rain.html">
+ rain</a> into account.
+ </body>
+</html>
diff --git a/examples/help/contextsensitivehelp/doc/time.html b/examples/help/contextsensitivehelp/doc/time.html
new file mode 100644
index 000000000..0cc81f4d0
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/time.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>Starting time</title>
+</head>
+<body>
+Starting the watering too early may be ineffective since most water
+will evaporate.
+
+</body>
+</html>
diff --git a/examples/help/contextsensitivehelp/doc/wateringmachine.qch b/examples/help/contextsensitivehelp/doc/wateringmachine.qch
new file mode 100644
index 000000000..35d29be22
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/wateringmachine.qch
Binary files differ
diff --git a/examples/help/contextsensitivehelp/doc/wateringmachine.qhc b/examples/help/contextsensitivehelp/doc/wateringmachine.qhc
new file mode 100644
index 000000000..b5653c3ff
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/wateringmachine.qhc
Binary files differ
diff --git a/examples/help/contextsensitivehelp/doc/wateringmachine.qhcp b/examples/help/contextsensitivehelp/doc/wateringmachine.qhcp
new file mode 100644
index 000000000..eebf6520e
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/wateringmachine.qhcp
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<QHelpCollectionProject version="1.0">
+ <docFiles>
+ <generate>
+ <file>
+ <input>wateringmachine.qhp</input>
+ <output>wateringmachine.qch</output>
+ </file>
+ </generate>
+ <register>
+ <file>wateringmachine.qch</file>
+ </register>
+ </docFiles>
+</QHelpCollectionProject> \ No newline at end of file
diff --git a/examples/help/contextsensitivehelp/doc/wateringmachine.qhp b/examples/help/contextsensitivehelp/doc/wateringmachine.qhp
new file mode 100644
index 000000000..6dd08e7ae
--- /dev/null
+++ b/examples/help/contextsensitivehelp/doc/wateringmachine.qhp
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<QtHelpProject version="1.0">
+ <virtualFolder>wateringmachine</virtualFolder>
+ <namespace>wateringcompany.com.1-0-0.premium</namespace>
+ <filterSection>
+ <keywords>
+ <keyword name="plants" id="plants" ref="plants.html"/>
+ <keyword name="temperature" id="temperature" ref="temperature.html"/>
+ <keyword name="rain" id="rain" ref="rain.html"/>
+ <keyword name="time" id="time" ref="time.html"/>
+ <keyword name="amount" id="amount" ref="amount.html"/>
+ <keyword name="source" id="source" ref="source.html"/>
+ <keyword name="filtering" id="filtering" ref="filter.html"/>
+ </keywords>
+ <files>
+ <file>plants.html</file>
+ <file>temperature.html</file>
+ <file>rain.html</file>
+ <file>time.html</file>
+ <file>amount.html</file>
+ <file>source.html</file>
+ <file>filter.html</file>
+ </files>
+ </filterSection>
+</QtHelpProject>
diff --git a/examples/help/contextsensitivehelp/helpbrowser.cpp b/examples/help/contextsensitivehelp/helpbrowser.cpp
new file mode 100644
index 000000000..d37a72f3b
--- /dev/null
+++ b/examples/help/contextsensitivehelp/helpbrowser.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QLibraryInfo>
+#include <QtGui/QApplication>
+#include <QtHelp/QHelpEngineCore>
+
+#include "helpbrowser.h"
+
+HelpBrowser::HelpBrowser(QWidget *parent)
+ : QTextBrowser(parent)
+{
+ QString collectionFile = QLibraryInfo::location(QLibraryInfo::ExamplesPath)
+ + QLatin1String("/help/contextsensitivehelp/doc/wateringmachine.qhc");
+
+ m_helpEngine = new QHelpEngineCore(collectionFile, this);
+ if (!m_helpEngine->setupData()) {
+ delete m_helpEngine;
+ m_helpEngine = 0;
+ }
+}
+
+void HelpBrowser::showHelpForKeyword(const QString &id)
+{
+ if (m_helpEngine) {
+ QMap<QString, QUrl> links = m_helpEngine->linksForIdentifier(id);
+ if (links.count())
+ setSource(links.constBegin().value());
+ }
+}
+
+QVariant HelpBrowser::loadResource(int type, const QUrl &name)
+{
+ QByteArray ba;
+ if (type < 4 && m_helpEngine) {
+ QUrl url(name);
+ if (name.isRelative())
+ url = source().resolved(url);
+ ba = m_helpEngine->fileData(url);
+ }
+ return ba;
+}
+
diff --git a/examples/help/contextsensitivehelp/helpbrowser.h b/examples/help/contextsensitivehelp/helpbrowser.h
new file mode 100644
index 000000000..684ed6827
--- /dev/null
+++ b/examples/help/contextsensitivehelp/helpbrowser.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPBROWSER_H
+#define HELPBROWSER_H
+
+#include <QtGui/QTextBrowser>
+
+QT_BEGIN_NAMESPACE
+class QHelpEngineCore;
+QT_END_NAMESPACE;
+
+class HelpBrowser : public QTextBrowser
+{
+ Q_OBJECT
+
+public:
+ HelpBrowser(QWidget *parent);
+ void showHelpForKeyword(const QString &id);
+
+private:
+ QVariant loadResource(int type, const QUrl &name);
+
+ QHelpEngineCore *m_helpEngine;
+};
+
+#endif
diff --git a/examples/help/contextsensitivehelp/main.cpp b/examples/help/contextsensitivehelp/main.cpp
new file mode 100644
index 000000000..ca15d9fb6
--- /dev/null
+++ b/examples/help/contextsensitivehelp/main.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QApplication>
+
+#include "wateringconfigdialog.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ WateringConfigDialog dia;
+ return dia.exec();
+}
diff --git a/examples/help/contextsensitivehelp/wateringconfigdialog.cpp b/examples/help/contextsensitivehelp/wateringconfigdialog.cpp
new file mode 100644
index 000000000..0529bfcfc
--- /dev/null
+++ b/examples/help/contextsensitivehelp/wateringconfigdialog.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "wateringconfigdialog.h"
+
+WateringConfigDialog::WateringConfigDialog()
+{
+ m_ui.setupUi(this);
+ m_widgetInfo.insert(m_ui.plantComboBox, tr("plants"));
+ m_widgetInfo.insert(m_ui.temperatureCheckBox, tr("temperature"));
+ m_widgetInfo.insert(m_ui.temperatureSpinBox, tr("temperature"));
+ m_widgetInfo.insert(m_ui.rainCheckBox, tr("rain"));
+ m_widgetInfo.insert(m_ui.rainSpinBox, tr("rain"));
+ m_widgetInfo.insert(m_ui.startTimeEdit, tr("starting time"));
+ m_widgetInfo.insert(m_ui.amountSpinBox, tr("water amount"));
+ m_widgetInfo.insert(m_ui.sourceComboBox, tr("water source"));
+ m_widgetInfo.insert(m_ui.filterCheckBox, tr("water filtering"));
+
+ connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)),
+ this, SLOT(focusChanged(QWidget*,QWidget*)));
+}
+
+void WateringConfigDialog::focusChanged(QWidget *, QWidget *now)
+{
+ if (m_widgetInfo.contains(now)) {
+ m_ui.helpLabel->setText(tr("Information about %1:").arg(m_widgetInfo.value(now)));
+ QStringList lst = m_widgetInfo.value(now).split(QLatin1Char(' '));
+ m_ui.helpBrowser->showHelpForKeyword(lst.last());
+ }
+}
+
diff --git a/examples/help/contextsensitivehelp/wateringconfigdialog.h b/examples/help/contextsensitivehelp/wateringconfigdialog.h
new file mode 100644
index 000000000..d1fd98643
--- /dev/null
+++ b/examples/help/contextsensitivehelp/wateringconfigdialog.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WATERINGCONFIGDIALOG_H
+#define WATERINGCONFIGDIALOG_H
+
+#include <QtGui/QDialog>
+#include "ui_wateringconfigdialog.h"
+
+class WateringConfigDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ WateringConfigDialog();
+
+private slots:
+ void focusChanged(QWidget *old, QWidget *now);
+
+private:
+ Ui::WateringConfigDialog m_ui;
+ QMap<QWidget*, QString> m_widgetInfo;
+};
+
+#endif
diff --git a/examples/help/contextsensitivehelp/wateringconfigdialog.ui b/examples/help/contextsensitivehelp/wateringconfigdialog.ui
new file mode 100644
index 000000000..d7a473a3c
--- /dev/null
+++ b/examples/help/contextsensitivehelp/wateringconfigdialog.ui
@@ -0,0 +1,446 @@
+<ui version="4.0" >
+ <class>WateringConfigDialog</class>
+ <widget class="QDialog" name="WateringConfigDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>334</width>
+ <height>550</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Watering Configuration</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Plant:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3" >
+ <widget class="QComboBox" name="plantComboBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Squash</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Bean</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Carrot</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Strawberry</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Raspberry</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Blueberry</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>67</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Water when:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="3" >
+ <widget class="QCheckBox" name="temperatureCheckBox" >
+ <property name="text" >
+ <string>Temperature is higher than:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="2" >
+ <widget class="QSpinBox" name="temperatureSpinBox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="specialValueText" >
+ <string/>
+ </property>
+ <property name="suffix" >
+ <string>C</string>
+ </property>
+ <property name="minimum" >
+ <number>10</number>
+ </property>
+ <property name="maximum" >
+ <number>60</number>
+ </property>
+ <property name="value" >
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="1" colspan="3" >
+ <widget class="QCheckBox" name="rainCheckBox" >
+ <property name="text" >
+ <string>Rain less than:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="2" >
+ <widget class="QSpinBox" name="rainSpinBox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="specialValueText" >
+ <string/>
+ </property>
+ <property name="suffix" >
+ <string>mm</string>
+ </property>
+ <property name="minimum" >
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="7" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="8" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Starting Time:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1" colspan="3" >
+ <widget class="QTimeEdit" name="startTimeEdit" />
+ </item>
+ <item row="9" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Amount:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1" colspan="3" >
+ <widget class="QSpinBox" name="amountSpinBox" >
+ <property name="suffix" >
+ <string>l</string>
+ </property>
+ <property name="minimum" >
+ <number>100</number>
+ </property>
+ <property name="maximum" >
+ <number>10000</number>
+ </property>
+ <property name="singleStep" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>1000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Source:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="1" colspan="3" >
+ <widget class="QComboBox" name="sourceComboBox" >
+ <item>
+ <property name="text" >
+ <string>Fountain</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>River</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Lake</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Public Water System</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="11" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="text" >
+ <string>Filter:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1" colspan="2" >
+ <widget class="QCheckBox" name="filterCheckBox" >
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="4" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" >
+ <item row="0" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="HelpBrowser" name="helpBrowser" />
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="helpLabel" >
+ <property name="text" >
+ <string>&lt;a href="test">Show Details&lt;/a></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>HelpBrowser</class>
+ <extends>QTextBrowser</extends>
+ <header>helpbrowser.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>WateringConfigDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>227</x>
+ <y>372</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>WateringConfigDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>286</x>
+ <y>378</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>temperatureCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>temperatureSpinBox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>132</x>
+ <y>101</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>132</x>
+ <y>125</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>rainCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>rainSpinBox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>110</x>
+ <y>154</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>113</x>
+ <y>169</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/help/help.pro b/examples/help/help.pro
new file mode 100644
index 000000000..f03ec01f4
--- /dev/null
+++ b/examples/help/help.pro
@@ -0,0 +1,13 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS += contextsensitivehelp \
+ remotecontrol \
+ simpletextviewer
+
+# install
+sources.files = README *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/help
+INSTALLS += sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/help/remotecontrol/enter.png b/examples/help/remotecontrol/enter.png
new file mode 100644
index 000000000..f397f4b9c
--- /dev/null
+++ b/examples/help/remotecontrol/enter.png
Binary files differ
diff --git a/examples/help/remotecontrol/main.cpp b/examples/help/remotecontrol/main.cpp
new file mode 100644
index 000000000..ad561ce4f
--- /dev/null
+++ b/examples/help/remotecontrol/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QApplication>
+#include "remotecontrol.h"
+
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(remotecontrol);
+
+ QApplication a(argc, argv);
+ RemoteControl w;
+ w.show();
+ a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
+ return a.exec();
+}
diff --git a/examples/help/remotecontrol/remotecontrol.cpp b/examples/help/remotecontrol/remotecontrol.cpp
new file mode 100644
index 000000000..45d3fde82
--- /dev/null
+++ b/examples/help/remotecontrol/remotecontrol.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QDir>
+#include <QtCore/QProcess>
+#include <QtCore/QTextStream>
+#include <QtCore/QLibraryInfo>
+
+#include <QtGui/QMessageBox>
+
+#include "remotecontrol.h"
+
+RemoteControl::RemoteControl(QWidget *parent, Qt::WFlags flags)
+ : QMainWindow(parent, flags)
+{
+ ui.setupUi(this);
+ connect(ui.indexLineEdit, SIGNAL(returnPressed()),
+ this, SLOT(on_indexButton_clicked()));
+ connect(ui.identifierLineEdit, SIGNAL(returnPressed()),
+ this, SLOT(on_identifierButton_clicked()));
+ connect(ui.urlLineEdit, SIGNAL(returnPressed()),
+ this, SLOT(on_urlButton_clicked()));
+
+ QString rc;
+ QTextStream(&rc) << QLatin1String("qthelp://com.trolltech.qt.")
+ << (QT_VERSION >> 16) << ((QT_VERSION >> 8) & 0xFF)
+ << (QT_VERSION & 0xFF)
+ << QLatin1String("/qdoc/index.html");
+
+ ui.startUrlLineEdit->setText(rc);
+
+ process = new QProcess(this);
+ connect(process, SIGNAL(finished(int,QProcess::ExitStatus)),
+ this, SLOT(helpViewerClosed()));
+}
+
+RemoteControl::~RemoteControl()
+{
+ if (process->state() == QProcess::Running) {
+ process->terminate();
+ process->waitForFinished(3000);
+ }
+}
+
+void RemoteControl::on_actionQuit_triggered()
+{
+ close();
+}
+
+void RemoteControl::on_launchButton_clicked()
+{
+ if (process->state() == QProcess::Running)
+ return;
+
+ QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator();
+#if !defined(Q_OS_MAC)
+ app += QLatin1String("assistant");
+#else
+ app += QLatin1String("Assistant.app/Contents/MacOS/Assistant");
+#endif
+
+ ui.contentsCheckBox->setChecked(true);
+ ui.indexCheckBox->setChecked(true);
+ ui.bookmarksCheckBox->setChecked(true);
+
+ QStringList args;
+ args << QLatin1String("-enableRemoteControl");
+ process->start(app, args);
+ if (!process->waitForStarted()) {
+ QMessageBox::critical(this, tr("Remote Control"),
+ tr("Could not start Qt Assistant from %1.").arg(app));
+ return;
+ }
+
+ if (!ui.startUrlLineEdit->text().isEmpty())
+ sendCommand(QLatin1String("SetSource ")
+ + ui.startUrlLineEdit->text());
+
+ ui.launchButton->setEnabled(false);
+ ui.startUrlLineEdit->setEnabled(false);
+ ui.actionGroupBox->setEnabled(true);
+}
+
+void RemoteControl::sendCommand(const QString &cmd)
+{
+ if (process->state() != QProcess::Running)
+ return;
+ process->write(cmd.toLocal8Bit() + '\n');
+}
+
+void RemoteControl::on_indexButton_clicked()
+{
+ sendCommand(QLatin1String("ActivateKeyword ")
+ + ui.indexLineEdit->text());
+}
+
+void RemoteControl::on_identifierButton_clicked()
+{
+ sendCommand(QLatin1String("ActivateIdentifier ")
+ + ui.identifierLineEdit->text());
+}
+
+void RemoteControl::on_urlButton_clicked()
+{
+ sendCommand(QLatin1String("SetSource ")
+ + ui.urlLineEdit->text());
+}
+
+void RemoteControl::on_syncContentsButton_clicked()
+{
+ sendCommand(QLatin1String("SyncContents"));
+}
+
+void RemoteControl::on_contentsCheckBox_toggled(bool checked)
+{
+ sendCommand(checked ?
+ QLatin1String("Show Contents") : QLatin1String("Hide Contents"));
+}
+
+void RemoteControl::on_indexCheckBox_toggled(bool checked)
+{
+ sendCommand(checked ?
+ QLatin1String("Show Index") : QLatin1String("Hide Index"));
+}
+
+void RemoteControl::on_bookmarksCheckBox_toggled(bool checked)
+{
+ sendCommand(checked ?
+ QLatin1String("Show Bookmarks") : QLatin1String("Hide Bookmarks"));
+}
+
+void RemoteControl::helpViewerClosed()
+{
+ ui.launchButton->setEnabled(true);
+ ui.startUrlLineEdit->setEnabled(true);
+ ui.actionGroupBox->setEnabled(false);
+}
diff --git a/examples/help/remotecontrol/remotecontrol.h b/examples/help/remotecontrol/remotecontrol.h
new file mode 100644
index 000000000..e440add3f
--- /dev/null
+++ b/examples/help/remotecontrol/remotecontrol.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef REMOTECONTROL_H
+#define REMOTECONTROL_H
+
+#include <QtGui/QMainWindow>
+#include "ui_remotecontrol.h"
+
+QT_BEGIN_NAMESPACE
+class QProcess;
+QT_END_NAMESPACE;
+
+class RemoteControl : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ RemoteControl(QWidget *parent = 0, Qt::WFlags flags = 0);
+ ~RemoteControl();
+
+private:
+ Ui::RemoteControlClass ui;
+ QProcess *process;
+
+private slots:
+ void on_launchButton_clicked();
+ void on_actionQuit_triggered();
+ void on_indexButton_clicked();
+ void on_identifierButton_clicked();
+ void on_urlButton_clicked();
+ void on_syncContentsButton_clicked();
+ void on_contentsCheckBox_toggled(bool checked);
+ void on_indexCheckBox_toggled(bool checked);
+ void on_bookmarksCheckBox_toggled(bool checked);
+ void helpViewerClosed();
+
+ void sendCommand(const QString &cmd);
+};
+
+#endif // REMOTECONTROL_H
diff --git a/examples/help/remotecontrol/remotecontrol.pro b/examples/help/remotecontrol/remotecontrol.pro
new file mode 100644
index 000000000..f080b3c0b
--- /dev/null
+++ b/examples/help/remotecontrol/remotecontrol.pro
@@ -0,0 +1,15 @@
+TEMPLATE = app
+
+HEADERS += remotecontrol.h
+SOURCES += main.cpp \
+ remotecontrol.cpp
+FORMS += remotecontrol.ui
+RESOURCES += remotecontrol.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qttools/help/remotecontrol
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro *.png *.doc doc
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/help/remotecontrol
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
diff --git a/examples/help/remotecontrol/remotecontrol.qrc b/examples/help/remotecontrol/remotecontrol.qrc
new file mode 100644
index 000000000..9b4299d21
--- /dev/null
+++ b/examples/help/remotecontrol/remotecontrol.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/remotecontrol" >
+ <file>enter.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/help/remotecontrol/remotecontrol.ui b/examples/help/remotecontrol/remotecontrol.ui
new file mode 100644
index 000000000..1cfc7f540
--- /dev/null
+++ b/examples/help/remotecontrol/remotecontrol.ui
@@ -0,0 +1,228 @@
+<ui version="4.0" >
+ <class>RemoteControlClass</class>
+ <widget class="QMainWindow" name="RemoteControlClass" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>344</width>
+ <height>364</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>RemoteControl</string>
+ </property>
+ <widget class="QWidget" name="centralWidget" >
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Start URL:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <widget class="QLineEdit" name="startUrlLineEdit" />
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="launchButton" >
+ <property name="text" >
+ <string>Launch Qt HelpViewer</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>101</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>113</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0" colspan="3" >
+ <widget class="QGroupBox" name="actionGroupBox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="title" >
+ <string>Actions</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Search in Index:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="indexLineEdit" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="indexButton" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="remotecontrol.qrc" >:/remotecontrol/enter.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Identifier:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="identifierLineEdit" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="identifierButton" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="remotecontrol.qrc" >:/remotecontrol/enter.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Show URL:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="urlLineEdit" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="urlButton" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="remotecontrol.qrc" >:/remotecontrol/enter.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QPushButton" name="syncContentsButton" >
+ <property name="text" >
+ <string>Sync Contents</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>81</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="0" colspan="3" >
+ <widget class="QCheckBox" name="contentsCheckBox" >
+ <property name="text" >
+ <string>Show Contents</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QCheckBox" name="indexCheckBox" >
+ <property name="text" >
+ <string>Show Index</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="3" >
+ <widget class="QCheckBox" name="bookmarksCheckBox" >
+ <property name="text" >
+ <string>Show Bookmarks</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menuBar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>344</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile" >
+ <property name="title" >
+ <string>File</string>
+ </property>
+ <addaction name="actionQuit" />
+ </widget>
+ <addaction name="menuFile" />
+ </widget>
+ <widget class="QStatusBar" name="statusBar" />
+ <action name="actionQuit" >
+ <property name="text" >
+ <string>Quit</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources>
+ <include location="remotecontrol.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/examples/help/simpletextviewer/assistant.cpp b/examples/help/simpletextviewer/assistant.cpp
new file mode 100644
index 000000000..2223b4bbf
--- /dev/null
+++ b/examples/help/simpletextviewer/assistant.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QByteArray>
+#include <QtCore/QDir>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QProcess>
+
+#include <QtGui/QMessageBox>
+
+#include "assistant.h"
+
+Assistant::Assistant()
+ : proc(0)
+{
+}
+
+//! [0]
+Assistant::~Assistant()
+{
+ if (proc && proc->state() == QProcess::Running) {
+ proc->terminate();
+ proc->waitForFinished(3000);
+ }
+ delete proc;
+}
+//! [0]
+
+//! [1]
+void Assistant::showDocumentation(const QString &page)
+{
+ if (!startAssistant())
+ return;
+
+ QByteArray ba("SetSource ");
+ ba.append("qthelp://com.trolltech.examples.simpletextviewer/doc/");
+
+ proc->write(ba + page.toLocal8Bit() + '\n');
+}
+//! [1]
+
+//! [2]
+bool Assistant::startAssistant()
+{
+ if (!proc)
+ proc = new QProcess();
+
+ if (proc->state() != QProcess::Running) {
+ QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator();
+#if !defined(Q_OS_MAC)
+ app += QLatin1String("assistant");
+#else
+ app += QLatin1String("Assistant.app/Contents/MacOS/Assistant");
+#endif
+
+ QStringList args;
+ args << QLatin1String("-collectionFile")
+ << QLibraryInfo::location(QLibraryInfo::ExamplesPath)
+ + QLatin1String("/help/simpletextviewer/documentation/simpletextviewer.qhc")
+ << QLatin1String("-enableRemoteControl");
+
+ proc->start(app, args);
+
+ if (!proc->waitForStarted()) {
+ QMessageBox::critical(0, QObject::tr("Simple Text Viewer"),
+ QObject::tr("Unable to launch Qt Assistant (%1)").arg(app));
+ return false;
+ }
+ }
+ return true;
+}
+//! [2]
diff --git a/examples/help/simpletextviewer/assistant.h b/examples/help/simpletextviewer/assistant.h
new file mode 100644
index 000000000..3f508dd82
--- /dev/null
+++ b/examples/help/simpletextviewer/assistant.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ASSISTANT_H
+#define ASSISTANT_H
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+class QProcess;
+QT_END_NAMESPACE
+
+class Assistant
+{
+public:
+ Assistant();
+ ~Assistant();
+ void showDocumentation(const QString &file);
+
+private:
+ bool startAssistant();
+ QProcess *proc;
+};
+
+#endif
diff --git a/examples/help/simpletextviewer/documentation/about.txt b/examples/help/simpletextviewer/documentation/about.txt
new file mode 100644
index 000000000..eeab35f4a
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/about.txt
@@ -0,0 +1,9 @@
+The Simple Text Viewer enables the user to select and view existing
+files.
+
+HTML files is displayed using rich text, while other files are
+presented as plain text. The application provides a file dialog
+allowing the user to search for files using wildcard matching. The
+search is performed within in the specified directory, and the user is
+given an option to browse the existing file system to find the
+relevant directory.
diff --git a/examples/help/simpletextviewer/documentation/browse.html b/examples/help/simpletextviewer/documentation/browse.html
new file mode 100644
index 000000000..987abf31f
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/browse.html
@@ -0,0 +1,34 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Browse</title>
+ </head>
+ <body style="font-size:12pt;font-family:helvetica">
+
+ <p><center><h2>Browse</h2></center></p>
+
+ <p>
+ The file dialog let you browse the current file system to
+ specify the directory in which the file you want to open
+ resides.
+ Note that only the specified directory will be searched, any
+ subdirectories will simply be ignored.
+ </p>
+
+ <br />
+ <br />
+ <table align="center" cellpadding="2" cellspacing="1" border="0" width="100%">
+ <tr valign="top" bgcolor="#f0f0f0">
+ <td><center><img src="images/browse.png" /></center></td>
+ </tr>
+ </table>
+
+ <br />
+ <br />
+ <p>
+ See also: <a href="filedialog.html">File Dialog</a>, <a href="wildcardmatching.html">Wildcard Matching</a>,
+ <a href="findfile.html">Find File</a>
+ </p>
+ </body>
+</html>
+
diff --git a/examples/help/simpletextviewer/documentation/filedialog.html b/examples/help/simpletextviewer/documentation/filedialog.html
new file mode 100644
index 000000000..afa65ed57
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/filedialog.html
@@ -0,0 +1,48 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>File Dialog</title>
+ </head>
+ <body style="font-size:12pt;font-family:helvetica">
+
+ <p><center><h2>File Dialog</h2></center></p>
+
+ <p>
+ In the file dialog you can name a particular file name, or
+ search for files using wildcard matching, i.e. specify a
+ file name containing wildcards. In addition you must specify
+ the directory in which the file you search for resides.
+ </p>
+
+ <br />
+ <br />
+ <table align="center" cellpadding="2" cellspacing="1" border="0" width="100%">
+ <tr valign="top" bgcolor="#f0f0f0">
+ <td><center><img src="images/filedialog.png" /></center></td>
+ </tr>
+ </table>
+
+ <br />
+ <br />
+ <p>
+ By default the dialog will search for all files (*) in the
+ current directory (the directory the application is run from).
+ </p>
+
+ <p>
+ When editing the file name and directory parameters, an
+ overview of the matching files are displayed in the
+ dialog. The overview is updated whenever the parameters
+ change.
+ </p>
+
+ <br />
+ <br />
+ <p>
+ See also: <a href="browse.html">Browse</a>, <a href="wildcardmatching.html">Wildcard Matching</a>,
+ <a href="findfile.html">Find File</a>
+ </p>
+ </body>
+</html>
+
+
diff --git a/examples/help/simpletextviewer/documentation/findfile.html b/examples/help/simpletextviewer/documentation/findfile.html
new file mode 100644
index 000000000..32e014718
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/findfile.html
@@ -0,0 +1,32 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Find File</title>
+ </head>
+ <body style="font-size:12pt;font-family:helvetica">
+
+ <p><center><h2>Find File</h2></center></p>
+
+ <p>
+ To open and view a file in the Simple Text Viewer, select the
+ 'Open...' option in the 'File' menu. The application will then
+ provide you with a file dialog that you can use to search for
+ any existing file.
+ </p>
+
+ <br />
+ <br />
+ <table align="center" cellpadding="2" cellspacing="1" border="0" width="100%">
+ <tr valign="top" bgcolor="#f0f0f0">
+ <td><center><img src="images/fadedfilemenu.png" /></center></td>
+ </tr>
+ </table>
+
+ <br />
+ <br />
+ <p>
+ See also: <a href="openfile.html">Open File</a>, <a href="filedialog.html">File Dialog</a>
+ </p>
+ </body>
+</html>
+
diff --git a/examples/help/simpletextviewer/documentation/images/browse.png b/examples/help/simpletextviewer/documentation/images/browse.png
new file mode 100644
index 000000000..86db6b19e
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/images/browse.png
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/images/fadedfilemenu.png b/examples/help/simpletextviewer/documentation/images/fadedfilemenu.png
new file mode 100644
index 000000000..fde0e43f6
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/images/fadedfilemenu.png
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/images/filedialog.png b/examples/help/simpletextviewer/documentation/images/filedialog.png
new file mode 100644
index 000000000..883a33a26
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/images/filedialog.png
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/images/handbook.png b/examples/help/simpletextviewer/documentation/images/handbook.png
new file mode 100644
index 000000000..3bd2b928b
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/images/handbook.png
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/images/icon.png b/examples/help/simpletextviewer/documentation/images/icon.png
new file mode 100644
index 000000000..6daec0ade
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/images/icon.png
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/images/mainwindow.png b/examples/help/simpletextviewer/documentation/images/mainwindow.png
new file mode 100644
index 000000000..c28d5e9ff
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/images/mainwindow.png
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/images/open.png b/examples/help/simpletextviewer/documentation/images/open.png
new file mode 100644
index 000000000..1e5bba3c8
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/images/open.png
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/images/wildcard.png b/examples/help/simpletextviewer/documentation/images/wildcard.png
new file mode 100644
index 000000000..6e83a56cc
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/images/wildcard.png
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/index.html b/examples/help/simpletextviewer/documentation/index.html
new file mode 100644
index 000000000..5a7b1d5fa
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/index.html
@@ -0,0 +1,41 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Manual</title>
+ </head>
+ <body style="font-size:12pt;font-family:helvetica">
+
+ <p><center><h2>Simple Text Viewer</h2></center></p>
+
+ <p>
+ The Simple Text Viewer enables the user to select and view
+ existing files.
+ </p>
+
+ <p><center>
+ <img src="images/mainwindow.png" />
+ </center></p>
+
+ <p>
+ HTML files is displayed using rich text, while
+ other files are presented as plain text. The application
+ provides a file dialog allowing the user to search for files
+ using wildcard matching. The search is performed within in the
+ specified directory, and the user is given an option to browse
+ the existing file system to find the relevant directory.
+ </p>
+
+ <ul>
+ <li><a href="findfile.html">Find File</a></li>
+ <ul>
+ <li><a href="filedialog.html">File Dialog</a></li>
+ <li><a href="wildcardmatching.html">WildCard Matching</a></li>
+ <li><a href="browse.html">Browse</a></li>
+ </ul>
+ <li><a href="openfile.html">Open File</a></li>
+ </ul>
+ </body>
+</html>
+
+
+
diff --git a/examples/help/simpletextviewer/documentation/intro.html b/examples/help/simpletextviewer/documentation/intro.html
new file mode 100644
index 000000000..2e2aa40de
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/intro.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Manual</title>
+ </head>
+ <body style="font-size:12pt;font-family:helvetica">
+
+ <p><center><h2>Simple Text Viewer</h2></center></p>
+
+ <p>
+ The Simple Text Viewer enables the user to select and view
+ existing files.
+ </p>
+
+ <p><center>
+ <img src="images/mainwindow.png" />
+ </center></p>
+
+ <p>
+ The application provides its own custom documentation that is
+ available through the <b>Help</b> menu in the main window's menubar
+ and through the <b>Help</b> button in the application's find file
+ dialog.
+ </p>
+
+ </body>
+</html>
+
diff --git a/examples/help/simpletextviewer/documentation/openfile.html b/examples/help/simpletextviewer/documentation/openfile.html
new file mode 100644
index 000000000..e172de95e
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/openfile.html
@@ -0,0 +1,36 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Open File</title>
+ </head>
+ <body style="font-size:12pt;font-family:helvetica">
+
+ <p><center><h2>Open File</h2></center></p>
+
+ <p>
+ Once the file you want to view appears in the dialog's
+ display, you can open it in two different ways.
+ </p>
+
+ <p>
+ By pressing the 'Open' button the currently selected file will
+ be opened. By default, the first file in the list of matching
+ files is selected. Another way of opening a file is to simply
+ double click the displayed file name.
+ </p>
+
+ <br />
+ <br />
+ <table align="center" cellpadding="2" cellspacing="1" border="0" width="100%">
+ <tr valign="top" bgcolor="#f0f0f0">
+ <td><center><img src="images/open.png" /></center></td>
+ </tr>
+ </table>
+
+ <br />
+ <br />
+ <p>
+ See also: <a href="findfile.html">Find File</a>
+ </p>
+ </body>
+</html>
diff --git a/examples/help/simpletextviewer/documentation/simpletextviewer.qch b/examples/help/simpletextviewer/documentation/simpletextviewer.qch
new file mode 100644
index 000000000..c40132803
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/simpletextviewer.qch
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/simpletextviewer.qhc b/examples/help/simpletextviewer/documentation/simpletextviewer.qhc
new file mode 100644
index 000000000..db380cabf
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/simpletextviewer.qhc
Binary files differ
diff --git a/examples/help/simpletextviewer/documentation/simpletextviewer.qhcp b/examples/help/simpletextviewer/documentation/simpletextviewer.qhcp
new file mode 100644
index 000000000..e7c23210b
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/simpletextviewer.qhcp
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<QHelpCollectionProject version="1.0">
+ <assistant>
+ <title>Simple Text Viewer</title>
+ <applicationIcon>images/handbook.png</applicationIcon>
+ <cacheDirectory>Trolltech/SimpleTextViewer</cacheDirectory>
+ <startPage>qthelp://com.trolltech.examples.simpletextviewer/doc/index.html</startPage>
+ <aboutMenuText>
+ <text>About Simple Text Viewer</text>
+ </aboutMenuText>
+ <aboutDialog>
+ <file>about.txt</file>
+ <icon>images/icon.png</icon>
+ </aboutDialog>
+ <enableDocumentationManager>false</enableDocumentationManager>
+ <enableAddressBar>false</enableAddressBar>
+ <enableFilterFunctionality>false</enableFilterFunctionality>
+ </assistant>
+ <docFiles>
+ <generate>
+ <file>
+ <input>simpletextviewer.qhp</input>
+ <output>simpletextviewer.qch</output>
+ </file>
+ </generate>
+ <register>
+ <file>simpletextviewer.qch</file>
+ </register>
+ </docFiles>
+ </QHelpCollectionProject>
diff --git a/examples/help/simpletextviewer/documentation/simpletextviewer.qhp b/examples/help/simpletextviewer/documentation/simpletextviewer.qhp
new file mode 100644
index 000000000..4cb83a5f3
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/simpletextviewer.qhp
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<QtHelpProject version="1.0">
+ <namespace>com.trolltech.examples.simpletextviewer</namespace>
+ <virtualFolder>doc</virtualFolder>
+ <filterSection>
+ <toc>
+ <section title="Simple Text Viewer" ref="index.html">
+ <section title="Find File" ref="./findfile.html">
+ <section title="File Dialog" ref="./filedialog.html"></section>
+ <section title="Wildcard Matching" ref="./wildcardmatching.html"></section>
+ <section title="Browse" ref="./browse.html"></section>
+ </section>
+ <section title="Open File" ref="./openfile.html"></section>
+ </section>
+ </toc>
+ <keywords>
+ <keyword name="Display" ref="./index.html"/>
+ <keyword name="Rich text" ref="./index.html"/>
+ <keyword name="Plain text" ref="./index.html"/>
+ <keyword name="Find" ref="./findfile.html"/>
+ <keyword name="File menu" ref="./findfile.html"/>
+ <keyword name="File name" ref="./filedialog.html"/>
+ <keyword name="File dialog" ref="./filedialog.html"/>
+ <keyword name="File globbing" ref="./wildcardmatching.html"/>
+ <keyword name="Wildcard matching" ref="./wildcardmatching.html"/>
+ <keyword name="Wildcard syntax" ref="./wildcardmatching.html"/>
+ <keyword name="Browse" ref="./browse.html"/>
+ <keyword name="Directory" ref="./browse.html"/>
+ <keyword name="Open" ref="./openfile.html"/>
+ <keyword name="Select" ref="./openfile.html"/>
+ </keywords>
+ <files>
+ <file>browse.html</file>
+ <file>filedialog.html</file>
+ <file>findfile.html</file>
+ <file>index.html</file>
+ <file>intro.html</file>
+ <file>openfile.html</file>
+ <file>wildcardmatching.html</file>
+ <file>images/browse.png</file>
+ <file>images/fadedfilemenu.png</file>
+ <file>images/filedialog.png</file>
+ <file>images/handbook.png</file>
+ <file>images/mainwindow.png</file>
+ <file>images/open.png</file>
+ <file>images/wildcard.png</file>
+ </files>
+ </filterSection>
+ </QtHelpProject>
diff --git a/examples/help/simpletextviewer/documentation/wildcardmatching.html b/examples/help/simpletextviewer/documentation/wildcardmatching.html
new file mode 100644
index 000000000..eb1839a06
--- /dev/null
+++ b/examples/help/simpletextviewer/documentation/wildcardmatching.html
@@ -0,0 +1,57 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Wildcard Matching</title>
+ </head>
+ <body style="font-size:12pt;font-family:helvetica">
+
+ <p><center><h2>Wildcard Matching</h2></center></p>
+
+ <p>
+ Most command shells such as bash or cmd.exe support "file
+ globbing", the ability to identify a group of files by using
+ wildcards.
+
+ <br />
+ <br />
+ <table align="center" cellpadding="2" cellspacing="1" border="0" width="100%">
+ <tr valign="top" bgcolor="#f0f0f0">
+ <td><center><img src="images/wildcard.png" /></center></td>
+ </tr>
+ </table>
+
+ <br />
+ <br />
+ <p>
+ Wildcard matching provides four features:
+ </p>
+
+ <ul>
+ <li>Any character represents itself apart from those
+ mentioned below. Thus 'c' matches the character 'c'.
+ </li>
+ <li>The '?' character matches any single character.</li>
+ <li>The '*' matches zero or more of any characters.</li>
+ <li>Sets of characters can be represented in square brackets.
+ Within the character class, like outside, backslash
+ has no special meaning.
+ </li>
+ </ul>
+
+ <p>
+ For example we could identify HTML files with
+ <code>*.html</code>. This will match zero or more characters
+ followed by a dot followed by 'h', 't', 'm' and 'l'.
+ </p>
+
+ <br />
+ <br />
+ <p>
+ See also: <a href="browse.html">Browse</a>, <a href="filedialog.html">File Dialog</a>,
+ <a href="findfile.html">Find File</a>
+ </p>
+ </body>
+</html>
+
+
+
diff --git a/examples/help/simpletextviewer/findfiledialog.cpp b/examples/help/simpletextviewer/findfiledialog.cpp
new file mode 100644
index 000000000..086be965d
--- /dev/null
+++ b/examples/help/simpletextviewer/findfiledialog.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QDir>
+#include <QtGui/QLayout>
+#include <QtGui/QComboBox>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QLayout>
+#include <QtGui/QFileDialog>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QToolButton>
+#include <QtGui/QPushButton>
+#include <QtGui/QLabel>
+
+#include "findfiledialog.h"
+#include "assistant.h"
+#include "textedit.h"
+
+//! [0]
+FindFileDialog::FindFileDialog(TextEdit *editor, Assistant *assistant)
+ : QDialog(editor)
+{
+ currentAssistant = assistant;
+ currentEditor = editor;
+//! [0]
+
+ createButtons();
+ createComboBoxes();
+ createFilesTree();
+ createLabels();
+ createLayout();
+
+ directoryComboBox->addItem(QDir::toNativeSeparators(QDir::currentPath()));
+ fileNameComboBox->addItem("*");
+ findFiles();
+
+ setWindowTitle(tr("Find File"));
+//! [1]
+}
+//! [1]
+
+void FindFileDialog::browse()
+{
+ QString currentDirectory = directoryComboBox->currentText();
+ QString newDirectory = QFileDialog::getExistingDirectory(this,
+ tr("Select Directory"), currentDirectory);
+ if (!newDirectory.isEmpty()) {
+ directoryComboBox->addItem(QDir::toNativeSeparators(newDirectory));
+ directoryComboBox->setCurrentIndex(directoryComboBox->count() - 1);
+ update();
+ }
+}
+
+//! [2]
+void FindFileDialog::help()
+{
+ currentAssistant->showDocumentation("filedialog.html");
+}
+//! [2]
+
+void FindFileDialog::openFile(QTreeWidgetItem *item)
+{
+ if (!item) {
+ item = foundFilesTree->currentItem();
+ if (!item)
+ return;
+ }
+
+ QString fileName = item->text(0);
+ QString path = directoryComboBox->currentText() + QDir::separator();
+
+ currentEditor->setContents(path + fileName);
+ close();
+}
+
+void FindFileDialog::update()
+{
+ findFiles();
+ buttonBox->button(QDialogButtonBox::Open)->setEnabled(
+ foundFilesTree->topLevelItemCount() > 0);
+}
+
+void FindFileDialog::findFiles()
+{
+ QRegExp filePattern(fileNameComboBox->currentText() + "*");
+ filePattern.setPatternSyntax(QRegExp::Wildcard);
+
+ QDir directory(directoryComboBox->currentText());
+
+ QStringList allFiles = directory.entryList(QDir::Files | QDir::NoSymLinks);
+ QStringList matchingFiles;
+
+ foreach (QString file, allFiles) {
+ if (filePattern.exactMatch(file))
+ matchingFiles << file;
+ }
+ showFiles(matchingFiles);
+}
+
+void FindFileDialog::showFiles(const QStringList &files)
+{
+ foundFilesTree->clear();
+
+ for (int i = 0; i < files.count(); ++i) {
+ QTreeWidgetItem *item = new QTreeWidgetItem(foundFilesTree);
+ item->setText(0, files[i]);
+ }
+
+ if (files.count() > 0)
+ foundFilesTree->setCurrentItem(foundFilesTree->topLevelItem(0));
+}
+
+void FindFileDialog::createButtons()
+{
+ browseButton = new QToolButton;
+ browseButton->setText(tr("..."));
+ connect(browseButton, SIGNAL(clicked()), this, SLOT(browse()));
+
+ buttonBox = new QDialogButtonBox(QDialogButtonBox::Open
+ | QDialogButtonBox::Cancel
+ | QDialogButtonBox::Help);
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(openFile()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(buttonBox, SIGNAL(helpRequested()), this, SLOT(help()));
+}
+
+void FindFileDialog::createComboBoxes()
+{
+ directoryComboBox = new QComboBox;
+ fileNameComboBox = new QComboBox;
+
+ fileNameComboBox->setEditable(true);
+ fileNameComboBox->setSizePolicy(QSizePolicy::Expanding,
+ QSizePolicy::Preferred);
+
+ directoryComboBox->setMinimumContentsLength(30);
+ directoryComboBox->setSizeAdjustPolicy(
+ QComboBox::AdjustToMinimumContentsLength);
+ directoryComboBox->setSizePolicy(QSizePolicy::Expanding,
+ QSizePolicy::Preferred);
+
+ connect(fileNameComboBox, SIGNAL(editTextChanged(QString)),
+ this, SLOT(update()));
+ connect(directoryComboBox, SIGNAL(currentIndexChanged(QString)),
+ this, SLOT(update()));
+}
+
+void FindFileDialog::createFilesTree()
+{
+ foundFilesTree = new QTreeWidget;
+ foundFilesTree->setColumnCount(1);
+ foundFilesTree->setHeaderLabels(QStringList(tr("Matching Files")));
+ foundFilesTree->setRootIsDecorated(false);
+ foundFilesTree->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ connect(foundFilesTree, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
+ this, SLOT(openFile(QTreeWidgetItem*)));
+}
+
+void FindFileDialog::createLabels()
+{
+ directoryLabel = new QLabel(tr("Search in:"));
+ fileNameLabel = new QLabel(tr("File name (including wildcards):"));
+}
+
+void FindFileDialog::createLayout()
+{
+ QHBoxLayout *fileLayout = new QHBoxLayout;
+ fileLayout->addWidget(fileNameLabel);
+ fileLayout->addWidget(fileNameComboBox);
+
+ QHBoxLayout *directoryLayout = new QHBoxLayout;
+ directoryLayout->addWidget(directoryLabel);
+ directoryLayout->addWidget(directoryComboBox);
+ directoryLayout->addWidget(browseButton);
+
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addLayout(fileLayout);
+ mainLayout->addLayout(directoryLayout);
+ mainLayout->addWidget(foundFilesTree);
+ mainLayout->addStretch();
+ mainLayout->addWidget(buttonBox);
+ setLayout(mainLayout);
+}
diff --git a/examples/help/simpletextviewer/findfiledialog.h b/examples/help/simpletextviewer/findfiledialog.h
new file mode 100644
index 000000000..71abd4aac
--- /dev/null
+++ b/examples/help/simpletextviewer/findfiledialog.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FINDFILEDIALOG_H
+#define FINDFILEDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QDialogButtonBox;
+class QLabel;
+class QToolButton;
+class QTreeWidget;
+class QTreeWidgetItem;
+QT_END_NAMESPACE
+
+class Assistant;
+class TextEdit;
+
+//! [0]
+class FindFileDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ FindFileDialog(TextEdit *editor, Assistant *assistant);
+
+private slots:
+ void browse();
+ void help();
+ void openFile(QTreeWidgetItem *item = 0);
+ void update();
+
+private:
+ void findFiles();
+ void showFiles(const QStringList &files);
+
+ void createButtons();
+ void createComboBoxes();
+ void createFilesTree();
+ void createLabels();
+ void createLayout();
+
+ Assistant *currentAssistant;
+ TextEdit *currentEditor;
+ QTreeWidget *foundFilesTree;
+
+ QComboBox *directoryComboBox;
+ QComboBox *fileNameComboBox;
+
+ QLabel *directoryLabel;
+ QLabel *fileNameLabel;
+
+ QDialogButtonBox *buttonBox;
+
+ QToolButton *browseButton;
+};
+//! [0]
+
+#endif
diff --git a/examples/help/simpletextviewer/main.cpp b/examples/help/simpletextviewer/main.cpp
new file mode 100644
index 000000000..4c8aab9c8
--- /dev/null
+++ b/examples/help/simpletextviewer/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ MainWindow window;
+ window.show();
+ return app.exec();
+}
diff --git a/examples/help/simpletextviewer/mainwindow.cpp b/examples/help/simpletextviewer/mainwindow.cpp
new file mode 100644
index 000000000..61fbdf3cb
--- /dev/null
+++ b/examples/help/simpletextviewer/mainwindow.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QLibraryInfo>
+#include <QtGui/QApplication>
+#include <QtGui/QAction>
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QMessageBox>
+
+#include "mainwindow.h"
+#include "findfiledialog.h"
+#include "assistant.h"
+#include "textedit.h"
+
+// ![0]
+MainWindow::MainWindow()
+{
+ assistant = new Assistant;
+// ![0]
+ textViewer = new TextEdit;
+ textViewer->setContents(QLibraryInfo::location(QLibraryInfo::ExamplesPath)
+ + QLatin1String("/help/simpletextviewer/documentation/intro.html"));
+ setCentralWidget(textViewer);
+
+ createActions();
+ createMenus();
+
+ setWindowTitle(tr("Simple Text Viewer"));
+ resize(750, 400);
+// ![1]
+}
+//! [1]
+
+//! [2]
+void MainWindow::closeEvent(QCloseEvent *)
+{
+ delete assistant;
+}
+//! [2]
+
+void MainWindow::about()
+{
+ QMessageBox::about(this, tr("About Simple Text Viewer"),
+ tr("This example demonstrates how to use\n"
+ "Qt Assistant as help system for your\n"
+ "own application."));
+}
+
+//! [3]
+void MainWindow::showDocumentation()
+{
+ assistant->showDocumentation("index.html");
+}
+//! [3]
+
+void MainWindow::open()
+{
+ FindFileDialog dialog(textViewer, assistant);
+ dialog.exec();
+}
+
+//! [4]
+void MainWindow::createActions()
+{
+ assistantAct = new QAction(tr("Help Contents"), this);
+ assistantAct->setShortcut(QKeySequence::HelpContents);
+ connect(assistantAct, SIGNAL(triggered()), this, SLOT(showDocumentation()));
+//! [4]
+
+ openAct = new QAction(tr("&Open..."), this);
+ openAct->setShortcut(QKeySequence::Open);
+ connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
+
+ clearAct = new QAction(tr("&Clear"), this);
+ clearAct->setShortcut(tr("Ctrl+C"));
+ connect(clearAct, SIGNAL(triggered()), textViewer, SLOT(clear()));
+
+ exitAct = new QAction(tr("E&xit"), this);
+ exitAct->setShortcuts(QKeySequence::Quit);
+ connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
+
+ aboutAct = new QAction(tr("&About"), this);
+ connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
+
+ aboutQtAct = new QAction(tr("About &Qt"), this);
+ connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+//! [5]
+}
+//! [5]
+
+void MainWindow::createMenus()
+{
+ fileMenu = new QMenu(tr("&File"), this);
+ fileMenu->addAction(openAct);
+ fileMenu->addAction(clearAct);
+ fileMenu->addSeparator();
+ fileMenu->addAction(exitAct);
+
+ helpMenu = new QMenu(tr("&Help"), this);
+ helpMenu->addAction(assistantAct);
+ helpMenu->addSeparator();
+ helpMenu->addAction(aboutAct);
+ helpMenu->addAction(aboutQtAct);
+
+
+ menuBar()->addMenu(fileMenu);
+ menuBar()->addMenu(helpMenu);
+}
diff --git a/examples/help/simpletextviewer/mainwindow.h b/examples/help/simpletextviewer/mainwindow.h
new file mode 100644
index 000000000..4fab382f2
--- /dev/null
+++ b/examples/help/simpletextviewer/mainwindow.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtGui/QMainWindow>
+
+class Assistant;
+class TextEdit;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow();
+ void showDocumentation(const QString &file);
+
+private slots:
+ void about();
+ void showDocumentation();
+ void open();
+
+protected:
+ void closeEvent(QCloseEvent *event);
+
+private:
+ void createActions();
+ void createMenus();
+
+ Assistant *assistant;
+ TextEdit *textViewer;
+
+ QMenu *fileMenu;
+ QMenu *helpMenu;
+
+ QAction *assistantAct;
+ QAction *clearAct;
+ QAction *openAct;
+ QAction *exitAct;
+ QAction *aboutAct;
+ QAction *aboutQtAct;
+};
+
+#endif
diff --git a/examples/help/simpletextviewer/simpletextviewer.pro b/examples/help/simpletextviewer/simpletextviewer.pro
new file mode 100644
index 000000000..46bda4cef
--- /dev/null
+++ b/examples/help/simpletextviewer/simpletextviewer.pro
@@ -0,0 +1,18 @@
+HEADERS = mainwindow.h \
+ findfiledialog.h \
+ assistant.h \
+ textedit.h
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ findfiledialog.cpp \
+ assistant.cpp \
+ textedit.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qttools/help/simpletextviewer
+sources.files = $$SOURCES $$HEADERS $$RESOURCES documentation *.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qttools/help/simpletextviewer
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
+
diff --git a/examples/help/simpletextviewer/textedit.cpp b/examples/help/simpletextviewer/textedit.cpp
new file mode 100644
index 000000000..52d85b380
--- /dev/null
+++ b/examples/help/simpletextviewer/textedit.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QFile>
+
+#include "textedit.h"
+
+TextEdit::TextEdit(QWidget *parent)
+ : QTextEdit(parent)
+{
+ setReadOnly(true);
+}
+
+void TextEdit::setContents(const QString &fileName)
+{
+ QFileInfo fi(fileName);
+ srcUrl = QUrl::fromLocalFile(fi.absoluteFilePath());
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly)) {
+ QString data(file.readAll());
+ if (fileName.endsWith(".html"))
+ setHtml(data);
+ else
+ setPlainText(data);
+ }
+}
+
+QVariant TextEdit::loadResource(int type, const QUrl &name)
+{
+ if (type == QTextDocument::ImageResource) {
+ QFile file(srcUrl.resolved(name).toLocalFile());
+ if (file.open(QIODevice::ReadOnly))
+ return file.readAll();
+ }
+ return QTextEdit::loadResource(type, name);
+}
diff --git a/examples/help/simpletextviewer/textedit.h b/examples/help/simpletextviewer/textedit.h
new file mode 100644
index 000000000..b9ecabd1d
--- /dev/null
+++ b/examples/help/simpletextviewer/textedit.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTEDIT_H
+#define TEXTEDIT_H
+
+#include <QtCore/QUrl>
+#include <QtGui/QTextEdit>
+
+class TextEdit : public QTextEdit
+{
+ Q_OBJECT
+
+public:
+ TextEdit(QWidget *parent = 0);
+ void setContents(const QString &fileName);
+
+private:
+ QVariant loadResource(int type, const QUrl &name);
+ QUrl srcUrl;
+};
+
+#endif
diff --git a/qttools.pro b/qttools.pro
new file mode 100644
index 000000000..871d8cc99
--- /dev/null
+++ b/qttools.pro
@@ -0,0 +1,12 @@
+TEMPLATE = subdirs
+
+module_qttools_src.subdir = src
+module_qttools_src.target = module-qttools-src
+
+module_qttools_tests.subdir = tests
+module_qttools_tests.target = module-qttools-tests
+module_qttools_tests.depends = module_qttools_src
+module_qttools_tests.CONFIG = no_default_target no_default_install
+
+SUBDIRS += module_qttools_src \
+ module_qttools_tests \
diff --git a/src/assistant/assistant.pro b/src/assistant/assistant.pro
new file mode 100644
index 000000000..97196b253
--- /dev/null
+++ b/src/assistant/assistant.pro
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS += lib/fulltextsearch \
+ lib \
+ tools
diff --git a/src/assistant/lib/fulltextsearch/fulltextsearch.pri b/src/assistant/lib/fulltextsearch/fulltextsearch.pri
new file mode 100644
index 000000000..134678feb
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/fulltextsearch.pri
@@ -0,0 +1,161 @@
+DEFINES += _BUILD_FOR_QT_ LUCENE_DISABLE_MEMTRACKING
+win32:DEFINES += _CRT_SECURE_NO_DEPRECATE _MT
+
+CLUCENEDIR = ../../../../src/3rdparty/clucene/src/CLucene
+
+INCLUDEPATH += . .. \
+ $$CLUCENEDIR \
+ $$CLUCENEDIR/../ \
+ $$CLUCENEDIR/analysis \
+ $$CLUCENEDIR/analysis/standard \
+ $$CLUCENEDIR/config \
+ $$CLUCENEDIR/debug \
+ $$CLUCENEDIR/document \
+ $$CLUCENEDIR/index \
+ $$CLUCENEDIR/queryParser \
+ $$CLUCENEDIR/search \
+ $$CLUCENEDIR/store \
+ $$CLUCENEDIR/util
+
+
+SOURCES += $$CLUCENEDIR/StdHeader.cpp \
+ $$CLUCENEDIR/analysis/AnalysisHeader.cpp \
+ $$CLUCENEDIR/analysis/Analyzers.cpp \
+ $$CLUCENEDIR/config/gunichartables.cpp \
+ $$CLUCENEDIR/config/repl_lltot.cpp \
+ $$CLUCENEDIR/config/repl_tcscasecmp.cpp \
+ $$CLUCENEDIR/config/repl_tcslwr.cpp \
+ $$CLUCENEDIR/config/repl_tcstod.cpp \
+ $$CLUCENEDIR/config/repl_tcstoll.cpp \
+ $$CLUCENEDIR/config/repl_tprintf.cpp \
+ $$CLUCENEDIR/config/threads.cpp \
+ $$CLUCENEDIR/config/utf8.cpp \
+ $$CLUCENEDIR/debug/condition.cpp \
+ $$CLUCENEDIR/debug/error.cpp \
+ $$CLUCENEDIR/debug/memtracking.cpp \
+ $$CLUCENEDIR/document/DateField.cpp \
+ $$CLUCENEDIR/document/Document.cpp \
+ $$CLUCENEDIR/document/Field.cpp \
+ $$CLUCENEDIR/index/CompoundFile.cpp \
+ $$CLUCENEDIR/index/DocumentWriter.cpp \
+ $$CLUCENEDIR/index/FieldInfos.cpp \
+ $$CLUCENEDIR/index/FieldsReader.cpp \
+ $$CLUCENEDIR/index/FieldsWriter.cpp \
+ $$CLUCENEDIR/index/IndexModifier.cpp \
+ $$CLUCENEDIR/index/IndexReader.cpp \
+ $$CLUCENEDIR/index/IndexWriter.cpp \
+ $$CLUCENEDIR/index/MultiReader.cpp \
+ $$CLUCENEDIR/index/SegmentInfos.cpp \
+ $$CLUCENEDIR/index/SegmentMergeInfo.cpp \
+ $$CLUCENEDIR/index/SegmentMergeQueue.cpp \
+ $$CLUCENEDIR/index/SegmentMerger.cpp \
+ $$CLUCENEDIR/index/SegmentReader.cpp \
+ $$CLUCENEDIR/index/SegmentTermDocs.cpp \
+ $$CLUCENEDIR/index/SegmentTermEnum.cpp \
+ $$CLUCENEDIR/index/SegmentTermPositions.cpp \
+ $$CLUCENEDIR/index/SegmentTermVector.cpp \
+ $$CLUCENEDIR/index/Term.cpp \
+ $$CLUCENEDIR/index/TermInfo.cpp \
+ $$CLUCENEDIR/index/TermInfosReader.cpp \
+ $$CLUCENEDIR/index/TermInfosWriter.cpp \
+ $$CLUCENEDIR/index/TermVectorReader.cpp \
+ $$CLUCENEDIR/index/TermVectorWriter.cpp \
+ $$CLUCENEDIR/queryParser/Lexer.cpp \
+ $$CLUCENEDIR/queryParser/MultiFieldQueryParser.cpp \
+ $$CLUCENEDIR/queryParser/QueryParser.cpp \
+ $$CLUCENEDIR/queryParser/QueryParserBase.cpp \
+ $$CLUCENEDIR/queryParser/QueryToken.cpp \
+ $$CLUCENEDIR/queryParser/TokenList.cpp \
+ $$CLUCENEDIR/search/BooleanQuery.cpp \
+ $$CLUCENEDIR/search/BooleanScorer.cpp \
+ $$CLUCENEDIR/search/CachingWrapperFilter.cpp \
+ $$CLUCENEDIR/search/ChainedFilter.cpp \
+ $$CLUCENEDIR/search/ConjunctionScorer.cpp \
+ $$CLUCENEDIR/search/DateFilter.cpp \
+ $$CLUCENEDIR/search/ExactPhraseScorer.cpp \
+ $$CLUCENEDIR/search/Explanation.cpp \
+ $$CLUCENEDIR/search/FieldCache.cpp \
+ $$CLUCENEDIR/search/FieldCacheImpl.cpp \
+ $$CLUCENEDIR/search/FieldDocSortedHitQueue.cpp \
+ $$CLUCENEDIR/search/FieldSortedHitQueue.cpp \
+ $$CLUCENEDIR/search/FilteredTermEnum.cpp \
+ $$CLUCENEDIR/search/FuzzyQuery.cpp \
+ $$CLUCENEDIR/search/HitQueue.cpp \
+ $$CLUCENEDIR/search/Hits.cpp \
+ $$CLUCENEDIR/search/IndexSearcher.cpp \
+ $$CLUCENEDIR/search/MultiSearcher.cpp \
+ $$CLUCENEDIR/search/MultiTermQuery.cpp \
+ $$CLUCENEDIR/search/PhrasePositions.cpp \
+ $$CLUCENEDIR/search/PhraseQuery.cpp \
+ $$CLUCENEDIR/search/PhraseScorer.cpp \
+ $$CLUCENEDIR/search/PrefixQuery.cpp \
+ $$CLUCENEDIR/search/QueryFilter.cpp \
+ $$CLUCENEDIR/search/RangeFilter.cpp \
+ $$CLUCENEDIR/search/RangeQuery.cpp \
+ $$CLUCENEDIR/search/SearchHeader.cpp \
+ $$CLUCENEDIR/search/Similarity.cpp \
+ $$CLUCENEDIR/search/SloppyPhraseScorer.cpp \
+ $$CLUCENEDIR/search/Sort.cpp \
+ $$CLUCENEDIR/search/TermQuery.cpp \
+ $$CLUCENEDIR/search/TermScorer.cpp \
+ $$CLUCENEDIR/search/WildcardQuery.cpp \
+ $$CLUCENEDIR/search/WildcardTermEnum.cpp \
+ $$CLUCENEDIR/store/FSDirectory.cpp \
+ $$CLUCENEDIR/store/IndexInput.cpp \
+ $$CLUCENEDIR/store/IndexOutput.cpp \
+ $$CLUCENEDIR/store/Lock.cpp \
+ $$CLUCENEDIR/store/MMapInput.cpp \
+ $$CLUCENEDIR/store/RAMDirectory.cpp \
+ $$CLUCENEDIR/store/TransactionalRAMDirectory.cpp \
+ $$CLUCENEDIR/util/BitSet.cpp \
+ $$CLUCENEDIR/util/Equators.cpp \
+ $$CLUCENEDIR/util/FastCharStream.cpp \
+ $$CLUCENEDIR/util/fileinputstream.cpp \
+ $$CLUCENEDIR/util/Misc.cpp \
+ $$CLUCENEDIR/util/Reader.cpp \
+ $$CLUCENEDIR/util/StringBuffer.cpp \
+ $$CLUCENEDIR/util/StringIntern.cpp \
+ $$CLUCENEDIR/util/ThreadLocal.cpp \
+ $$CLUCENEDIR/analysis/standard/StandardAnalyzer.cpp \
+ $$CLUCENEDIR/analysis/standard/StandardFilter.cpp \
+ $$CLUCENEDIR/analysis/standard/StandardTokenizer.cpp
+
+
+#Header files
+HEADERS += qclucene_global_p.h \
+ qclucene-config_p.h \
+ qanalyzer_p.h \
+ qtokenizer_p.h \
+ qtoken_p.h \
+ qtokenstream_p.h \
+ qdocument_p.h \
+ qfield_p.h \
+ qindexreader_p.h \
+ qindexwriter_p.h \
+ qterm_p.h \
+ qqueryparser_p.h \
+ qfilter_p.h \
+ qhits_p.h \
+ qsearchable_p.h \
+ qsort_p.h \
+ qquery_p.h \
+ qreader_p.h
+
+
+#Source files
+SOURCES += qanalyzer.cpp \
+ qtokenizer.cpp \
+ qtoken.cpp \
+ qtokenstream.cpp \
+ qdocument.cpp \
+ qfield.cpp \
+ qindexreader.cpp \
+ qindexwriter.cpp \
+ qterm.cpp \
+ qqueryparser.cpp \
+ qfilter.cpp \
+ qhits.cpp \
+ qsearchable.cpp \
+ qsort.cpp \
+ qquery.cpp \
+ qreader.cpp
diff --git a/src/assistant/lib/fulltextsearch/fulltextsearch.pro b/src/assistant/lib/fulltextsearch/fulltextsearch.pro
new file mode 100644
index 000000000..d0e7a8796
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/fulltextsearch.pro
@@ -0,0 +1,50 @@
+
+QMAKE_TARGET_PRODUCT = QtCLucene
+QMAKE_TARGET_DESCRIPTION = QtCLucene full text search library wrapper.
+#if qt is built with frameworks in debug, we must build QtCLucene in debug and release
+#that's a similar logic as in qbase.pri
+mac:!static:contains(QT_CONFIG, qt_framework) {
+ CONFIG(debug, debug|release) {
+ !build_pass:CONFIG += build_all
+ }
+}
+QT_CONFIG -= qt_framework
+QT -= gui
+TEMPLATE = lib
+TARGET = QtCLucene
+DEFINES += QHELP_LIB
+include(../../../../src/qbase.pri)
+include(fulltextsearch.pri)
+
+CONFIG += qt warn_off
+contains(QT_CONFIG, reduce_exports) {
+ CONFIG += hide_symbols
+ # workaround for compiler errors on Ubuntu
+ linux*-g++*:DEFINES += _GLIBCXX_EXTERN_TEMPLATE=0
+}
+
+unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore
+
+# impossible to disable exceptions in clucene atm
+CONFIG(exceptions_off) {
+ CONFIG -= exceptions_off
+ CONFIG += exceptions
+ !win32|win32-g++* {
+ QMAKE_CFLAGS -= -fno-exceptions
+ QMAKE_CXXFLAGS -= -fno-exceptions
+ QMAKE_LFLAGS -= -fno-exceptions
+ QMAKE_CFLAGS += -fexceptions
+ QMAKE_CXXFLAGS += -fexceptions
+ QMAKE_LFLAGS += -fexceptions
+ }
+}
+
+win32-msvc.net | win32-msvc2* {
+ QMAKE_CFLAGS_RELEASE -= -O2
+ QMAKE_CXXFLAGS_RELEASE -= -O2
+}
+
+# the following define could be set globally in case we need it elsewhere
+solaris* {
+ DEFINES += Q_SOLARIS_VERSION=$$system(uname -r | sed -e 's/5\\.//')
+}
diff --git a/src/assistant/lib/fulltextsearch/license.txt b/src/assistant/lib/fulltextsearch/license.txt
new file mode 100644
index 000000000..9ef3d701d
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/license.txt
@@ -0,0 +1,503 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
diff --git a/src/assistant/lib/fulltextsearch/qanalyzer.cpp b/src/assistant/lib/fulltextsearch/qanalyzer.cpp
new file mode 100644
index 000000000..71dd2c972
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qanalyzer.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qanalyzer_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneAnalyzerPrivate::QCLuceneAnalyzerPrivate()
+ : QSharedData()
+{
+ analyzer = 0;
+ deleteCLuceneAnalyzer = true;
+}
+
+QCLuceneAnalyzerPrivate::QCLuceneAnalyzerPrivate(const QCLuceneAnalyzerPrivate &other)
+ : QSharedData()
+{
+ analyzer = _CL_POINTER(other.analyzer);
+ deleteCLuceneAnalyzer = other.deleteCLuceneAnalyzer;
+}
+
+QCLuceneAnalyzerPrivate::~QCLuceneAnalyzerPrivate()
+{
+ if (deleteCLuceneAnalyzer)
+ _CLDECDELETE(analyzer);
+}
+
+
+QCLuceneAnalyzer::QCLuceneAnalyzer()
+ : d(new QCLuceneAnalyzerPrivate())
+{
+ //nothing todo, private
+}
+
+QCLuceneAnalyzer::~QCLuceneAnalyzer()
+{
+ // nothing todo
+}
+
+qint32 QCLuceneAnalyzer::positionIncrementGap(const QString &fieldName) const
+{
+ Q_UNUSED(fieldName);
+ return 0;
+}
+
+QCLuceneTokenStream QCLuceneAnalyzer::tokenStream(const QString &fieldName,
+ const QCLuceneReader &reader) const
+{
+ TCHAR *fName = QStringToTChar(fieldName);
+ QCLuceneTokenStream tokenStream;
+ tokenStream.d->tokenStream = d->analyzer->tokenStream(fName, reader.d->reader);
+ delete [] fName;
+
+ return tokenStream;
+}
+
+
+QCLuceneStandardAnalyzer::QCLuceneStandardAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::standard::StandardAnalyzer();
+}
+
+QCLuceneStandardAnalyzer::~QCLuceneStandardAnalyzer()
+{
+ // nothing todo
+}
+
+QCLuceneStandardAnalyzer::QCLuceneStandardAnalyzer(const QStringList &stopWords)
+{
+ const TCHAR **tArray = new const TCHAR*[stopWords.count() +1];
+
+ for(int i = 0; i < stopWords.count(); ++i) {
+ TCHAR *stopWord = QStringToTChar(stopWords.at(i));
+ tArray[i] = STRDUP_TtoT(stopWord);
+ delete [] stopWord;
+ }
+ tArray[stopWords.count()] = 0;
+
+ d->analyzer = new lucene::analysis::standard::StandardAnalyzer(tArray);
+
+ for (int i = 0; i < stopWords.count(); ++i)
+ delete [] tArray[i];
+
+ delete [] tArray;
+}
+
+
+QCLuceneWhitespaceAnalyzer::QCLuceneWhitespaceAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::WhitespaceAnalyzer();
+}
+
+QCLuceneWhitespaceAnalyzer::~QCLuceneWhitespaceAnalyzer()
+{
+ // nothing todo
+}
+
+
+QCLuceneSimpleAnalyzer::QCLuceneSimpleAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::SimpleAnalyzer();
+}
+
+QCLuceneSimpleAnalyzer::~QCLuceneSimpleAnalyzer()
+{
+ // nothing todo
+}
+
+
+QCLuceneStopAnalyzer::QCLuceneStopAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::StopAnalyzer();
+}
+
+QCLuceneStopAnalyzer::~QCLuceneStopAnalyzer()
+{
+ // nothing todo
+}
+
+QCLuceneStopAnalyzer::QCLuceneStopAnalyzer(const QStringList &stopWords)
+ : QCLuceneAnalyzer()
+{
+ const TCHAR **tArray = new const TCHAR*[stopWords.count() +1];
+
+ for(int i = 0; i < stopWords.count(); ++i) {
+ TCHAR *stopWord = QStringToTChar(stopWords.at(i));
+ tArray[i] = STRDUP_TtoT(stopWord);
+ delete [] stopWord;
+ }
+ tArray[stopWords.count()] = 0;
+
+ d->analyzer = new lucene::analysis::StopAnalyzer(tArray);
+
+ for (int i = 0; i < stopWords.count(); ++i)
+ delete [] tArray[i];
+
+ delete [] tArray;
+}
+
+QStringList QCLuceneStopAnalyzer::englishStopWords() const
+{
+ QStringList stopWordList;
+
+ const TCHAR** stopWords = lucene::analysis::StopAnalyzer::ENGLISH_STOP_WORDS;
+ for (qint32 i = 0; stopWords[i] != 0; ++i)
+ stopWordList.append(TCharToQString(stopWords[i]));
+
+ return stopWordList;
+}
+
+
+QCLuceneKeywordAnalyzer::QCLuceneKeywordAnalyzer()
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new lucene::analysis::KeywordAnalyzer();
+}
+
+QCLuceneKeywordAnalyzer::~QCLuceneKeywordAnalyzer()
+{
+ // nothing todo
+}
+
+
+QCLucenePerFieldAnalyzerWrapper::QCLucenePerFieldAnalyzerWrapper(
+ QCLuceneAnalyzer *defaultAnalyzer)
+ : QCLuceneAnalyzer()
+{
+ d->analyzer = new
+ lucene::analysis::PerFieldAnalyzerWrapper(defaultAnalyzer->d->analyzer);
+
+ analyzers.append(defaultAnalyzer);
+ defaultAnalyzer->d->deleteCLuceneAnalyzer = false;
+}
+
+QCLucenePerFieldAnalyzerWrapper::~QCLucenePerFieldAnalyzerWrapper()
+{
+ qDeleteAll(analyzers);
+}
+
+void QCLucenePerFieldAnalyzerWrapper::addAnalyzer(const QString &fieldName,
+ QCLuceneAnalyzer *analyzer)
+{
+ lucene::analysis::PerFieldAnalyzerWrapper *analyzerWrapper =
+ static_cast<lucene::analysis::PerFieldAnalyzerWrapper*> (d->analyzer);
+
+ if (analyzerWrapper == 0)
+ return;
+
+ analyzers.append(analyzer);
+ analyzer->d->deleteCLuceneAnalyzer = false;
+
+ TCHAR *fName = QStringToTChar(fieldName);
+ analyzerWrapper->addAnalyzer(fName, analyzer->d->analyzer);
+ delete [] fName;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qanalyzer_p.h b/src/assistant/lib/fulltextsearch/qanalyzer_p.h
new file mode 100644
index 000000000..162d6799b
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qanalyzer_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QANALYZER_P_H
+#define QANALYZER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qreader_p.h"
+#include "qtokenstream_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(analysis)
+ class Analyzer;
+CL_NS_END
+CL_NS_USE(analysis)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneIndexWriter;
+class QCLuceneQueryParser;
+class QCLuceneStopAnalyzer;
+class QCLuceneSimpleAnalyzer;
+class QCLuceneKeywordAnalyzer;
+class QCLuceneStandardAnalyzer;
+class QCLuceneWhitespaceAnalyzer;
+class QCLucenePerFieldAnalyzerWrapper;
+
+class QHELP_EXPORT QCLuceneAnalyzerPrivate : public QSharedData
+{
+public:
+ QCLuceneAnalyzerPrivate();
+ QCLuceneAnalyzerPrivate(const QCLuceneAnalyzerPrivate &other);
+
+ ~QCLuceneAnalyzerPrivate();
+
+ Analyzer *analyzer;
+ bool deleteCLuceneAnalyzer;
+
+private:
+ QCLuceneAnalyzerPrivate &operator=(const QCLuceneAnalyzerPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneAnalyzer
+{
+public:
+ virtual ~QCLuceneAnalyzer();
+
+ qint32 positionIncrementGap(const QString &fieldName) const;
+ QCLuceneTokenStream tokenStream(const QString &fieldName,
+ const QCLuceneReader &reader) const;
+
+protected:
+ friend class QCLuceneIndexWriter;
+ friend class QCLuceneQueryParser;
+ friend class QCLuceneStopAnalyzer;
+ friend class QCLuceneSimpleAnalyzer;
+ friend class QCLuceneKeywordAnalyzer;
+ friend class QCLuceneStandardAnalyzer;
+ friend class QCLuceneWhitespaceAnalyzer;
+ friend class QCLucenePerFieldAnalyzerWrapper;
+ QSharedDataPointer<QCLuceneAnalyzerPrivate> d;
+
+private:
+ QCLuceneAnalyzer();
+};
+
+class QHELP_EXPORT QCLuceneStandardAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneStandardAnalyzer();
+ QCLuceneStandardAnalyzer(const QStringList &stopWords);
+
+ ~QCLuceneStandardAnalyzer();
+};
+
+class QHELP_EXPORT QCLuceneWhitespaceAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneWhitespaceAnalyzer();
+ ~QCLuceneWhitespaceAnalyzer();
+};
+
+class QHELP_EXPORT QCLuceneSimpleAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneSimpleAnalyzer();
+ ~QCLuceneSimpleAnalyzer();
+};
+
+class QHELP_EXPORT QCLuceneStopAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneStopAnalyzer();
+ QCLuceneStopAnalyzer(const QStringList &stopWords);
+
+ ~QCLuceneStopAnalyzer();
+
+ QStringList englishStopWords() const;
+};
+
+class QHELP_EXPORT QCLuceneKeywordAnalyzer : public QCLuceneAnalyzer
+{
+public:
+ QCLuceneKeywordAnalyzer();
+ ~QCLuceneKeywordAnalyzer();
+};
+
+class QHELP_EXPORT QCLucenePerFieldAnalyzerWrapper : public QCLuceneAnalyzer
+{
+public:
+ QCLucenePerFieldAnalyzerWrapper(QCLuceneAnalyzer *defaultAnalyzer);
+ ~QCLucenePerFieldAnalyzerWrapper();
+
+ void addAnalyzer(const QString &fieldName, QCLuceneAnalyzer *analyzer);
+
+private:
+ QList<QCLuceneAnalyzer*> analyzers;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANALYZER_P_H
diff --git a/src/assistant/lib/fulltextsearch/qclucene-config_p.h b/src/assistant/lib/fulltextsearch/qclucene-config_p.h
new file mode 100644
index 000000000..476296cf5
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qclucene-config_p.h
@@ -0,0 +1,557 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QCLUCENE_CONFIG_P_H
+#define QCLUCENE_CONFIG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+#ifndef _SRC_CLUCENE_CLUCENE_CONFIG_H
+#define _SRC_CLUCENE_CLUCENE_CONFIG_H 1
+
+/*
+src/CLucene/clucene-config.h.
+Generated
+automatically
+at
+end
+of
+configure.
+*/
+/* config.h.tmp. Generated by configure. */
+/* config.h.tmp.in. Generated from configure.ac by autoheader. */
+
+/* Disable multithreading */
+/* #undef _CL_DISABLE_MULTITHREADING */
+
+/* Define to 1 if you have the <algorithm> header file. */
+#ifndef _CL_HAVE_ALGORITHM
+#define _CL_HAVE_ALGORITHM 1
+#endif
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#ifndef _CL_HAVE_CTYPE_H
+#define _CL_HAVE_CTYPE_H 1
+#endif
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#ifndef _CL_HAVE_DIRENT_H
+#define _CL_HAVE_DIRENT_H 1
+#endif
+
+#if !defined (__MINGW32__)
+ /* Define to 1 if you have the <dlfcn.h> header file. */
+# ifndef _CL_HAVE_DLFCN_H
+# define _CL_HAVE_DLFCN_H 1
+# endif
+#endif
+
+/* Define to 1 if you have the <errno.h> header file. */
+#ifndef _CL_HAVE_ERRNO_H
+#define _CL_HAVE_ERRNO_H 1
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C)
+ /* Define to 1 if you have the <ext/hash_map> header file. */
+# ifndef _CL_HAVE_EXT_HASH_MAP
+# define _CL_HAVE_EXT_HASH_MAP 1
+# endif
+
+ /* Define to 1 if you have the <ext/hash_set> header file. */
+# ifndef _CL_HAVE_EXT_HASH_SET
+# define _CL_HAVE_EXT_HASH_SET 1
+# endif
+#endif
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#ifndef _CL_HAVE_FCNTL_H
+#define _CL_HAVE_FCNTL_H 1
+#endif
+
+#if !defined(__xlC__) && !defined(__xlc__) && !defined (__MINGW32__) && \
+ !defined(__HP_aCC) && !defined(__SUNPRO_C) && !defined(__SUNPRO_CC) || \
+ defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x550) || (defined(__HP_aCC) && defined(__ia64))
+ /* Define to 1 if the system has the type `float_t'. */
+# ifndef _CL_HAVE_FLOAT_T
+# define _CL_HAVE_FLOAT_T 1
+# endif
+#endif
+
+/* Define to 1 if you have the <functional> header file. */
+#ifndef _CL_HAVE_FUNCTIONAL
+#define _CL_HAVE_FUNCTIONAL 1
+#endif
+
+/* Does not support new float byte<->float conversions */
+#ifndef _CL_HAVE_FUNCTIONING_FLOAT_BYTE
+#define _CL_HAVE_FUNCTIONING_FLOAT_BYTE
+#endif
+
+/* Define to 1 if you have the `getpagesize' function. */
+#ifndef _CL_HAVE_GETPAGESIZE
+#define _CL_HAVE_GETPAGESIZE 1
+#endif
+
+/* Define to 1 if you have the <hash_map> header file. */
+/* #undef _CL_HAVE_HASH_MAP */
+
+/* Define to 1 if you have the <hash_set> header file. */
+/* #undef _CL_HAVE_HASH_SET */
+
+/* Define to 1 if the system has the type `intptr_t'. */
+#ifndef _CL_HAVE_INTPTR_T
+#define _CL_HAVE_INTPTR_T 1
+#endif
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#ifndef _CL_HAVE_INTTYPES_H
+#define _CL_HAVE_INTTYPES_H 1
+#endif
+
+/* Define to 1 if you have the <list> header file. */
+#ifndef _CL_HAVE_LIST
+#define _CL_HAVE_LIST 1
+#endif
+
+/* Define to 1 if you have the `lltoa' function. */
+/* #undef _CL_HAVE_LLTOA */
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the `lltow' function. */
+# ifndef _CL_HAVE_LLTOW
+# define _CL_HAVE_LLTOW 1
+# endif
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C) && !defined(__xlC__) && !defined(__xlc__)
+ /* Define to 1 if long double works and has more range or precision than double. */
+# ifndef _CL_HAVE_LONG_DOUBLE
+# define _CL_HAVE_LONG_DOUBLE 1
+# endif
+#endif
+
+/* Define to 1 if you have the <map> header file. */
+#ifndef _CL_HAVE_MAP
+#define _CL_HAVE_MAP 1
+#endif
+
+/* Define to 1 if you have the <math.h> header file. */
+#ifndef _CL_HAVE_MATH_H
+#define _CL_HAVE_MATH_H 1
+#endif
+
+/* Define to 1 if you have the <memory.h> header file. */
+#ifndef _CL_HAVE_MEMORY_H
+#define _CL_HAVE_MEMORY_H 1
+#endif
+
+#if !defined(__MINGW32__) && !defined(__HP_aCC) && !defined(__xlC__) && !defined(__xlc__)
+ /* Define to 1 if you have a working `mmap' system call. */
+# ifndef _CL_HAVE_MMAP
+# define _CL_HAVE_MMAP 1
+# endif
+#endif
+
+/* define if the compiler implements namespaces */
+#ifndef _CL_HAVE_NAMESPACES
+#define _CL_HAVE_NAMESPACES
+#endif
+
+#if defined(__SUNPRO_CC) || defined(__SUNPRO_C) || defined(__HP_aCC) || defined(__xlC__) || defined(__xlc__)
+ /* Define if you have the nanosleep function */
+# ifndef _CL_HAVE_NANOSLEEP
+# define _CL_HAVE_NANOSLEEP 1
+# endif
+#endif
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef _CL_HAVE_NDIR_H */
+
+/* Does not support new float byte<->float conversions */
+/* #undef _CL_HAVE_NO_FLOAT_BYTE */
+
+/* Does not support try/catch blocks */
+/* #undef _CL_HAVE_NO_FUNCTION_TRY_BLOCKS */
+
+/* Define to 1 if you have the `printf' function. */
+#ifndef _CL_HAVE_PRINTF
+#define _CL_HAVE_PRINTF 1
+#endif
+
+#if !defined(__MINGW32__)
+ /* Define if you have POSIX threads libraries and header files. */
+# ifndef _CL_HAVE_PTHREAD
+# define _CL_HAVE_PTHREAD 1
+# endif
+#endif
+
+/* Define if recursive pthread mutexes are available */
+/* #undef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE */
+
+/* Define to 1 if you have the <set> header file. */
+#ifndef _CL_HAVE_SET
+#define _CL_HAVE_SET 1
+#endif
+
+/* Define to 1 if you have the `snprintf' function. */
+#ifndef _CL_HAVE_SNPRINTF
+#define _CL_HAVE_SNPRINTF 1
+#endif
+
+/* Defined if the snprintf overflow test fails */
+/* #undef _CL_HAVE_SNPRINTF_BUG */
+
+/* Define to 1 if you have the `snwprintf' function. */
+/* #undef _CL_HAVE_SNWPRINTF */
+
+#if !defined(__HP_aCC) && !defined(__SUNPRO_CC) && !defined(__SUNPRO_C)
+ /* define if the compiler supports ISO C++ standard library */
+# ifndef _CL_HAVE_STD
+# define _CL_HAVE_STD
+# endif
+#endif
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#ifndef _CL_HAVE_STDARG_H
+#define _CL_HAVE_STDARG_H 1
+#endif
+
+/* x */
+#ifndef _CL_HAVE_STDEXCEPT
+#define _CL_HAVE_STDEXCEPT
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C) && !defined(__HP_aCC) && \
+ !defined(__xlC__) && !defined(__xlc__)
+ /* Define to 1 if you have the <stdint.h> header file. */
+# ifndef _CL_HAVE_STDINT_H
+# define _CL_HAVE_STDINT_H 1
+# endif
+#endif
+
+#if !defined(__HP_aCC)
+ /* Define to 1 if you have the <stdlib.h> header file. */
+# ifndef _CL_HAVE_STDLIB_H
+# define _CL_HAVE_STDLIB_H 1
+# endif
+
+ /* define if the compiler supports Standard Template Library */
+# ifndef _CL_HAVE_STL
+# define _CL_HAVE_STL
+# endif
+#endif
+
+/* Define to 1 if you have the <strings.h> header file. */
+#ifndef _CL_HAVE_STRINGS_H
+#define _CL_HAVE_STRINGS_H 1
+#endif
+
+/* Define to 1 if you have the <string.h> header file. */
+#ifndef _CL_HAVE_STRING_H
+#define _CL_HAVE_STRING_H 1
+#endif
+
+/* Define to 1 if you have the `strlwr' function. */
+/* #undef _CL_HAVE_STRLWR */
+
+/* Define to 1 if you have the `strtoll' function. */
+/* #undef _CL_HAVE_STRTOLL */
+
+/* Define to 1 if you have the `strupr' function. */
+/* #undef _CL_HAVE_STRUPR */
+
+/* Defined if the swprintf test fails */
+#ifndef _CL_HAVE_SWPRINTF_BUG
+#define _CL_HAVE_SWPRINTF_BUG
+#endif
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef _CL_HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef _CL_HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#ifndef _CL_HAVE_SYS_STAT_H
+#define _CL_HAVE_SYS_STAT_H 1
+#endif
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#ifndef _CL_HAVE_SYS_TIMEB_H
+#define _CL_HAVE_SYS_TIMEB_H 1
+#endif
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#ifndef _CL_HAVE_SYS_TYPES_H
+#define _CL_HAVE_SYS_TYPES_H 1
+#endif
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the <tchar.h> header file. */
+ # ifndef _CL_HAVE_TCHAR_H
+ # define _CL_HAVE_TCHAR_H 1
+ # endif
+#endif
+
+#if defined(__MINGW32__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+ /* Define to 1 if you have the `tell' function. */
+# ifndef _CL_HAVE_TELL
+# define _CL_HAVE_TELL 1
+# endif
+#endif
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#ifndef _CL_HAVE_UNISTD_H
+#define _CL_HAVE_UNISTD_H 1
+#endif
+
+/* Define to 1 if you have the <vector> header file. */
+#ifndef _CL_HAVE_VECTOR
+#define _CL_HAVE_VECTOR 1
+#endif
+
+/* Define to 1 if you have the `vsnwprintf' function. */
+/* #undef _CL_HAVE_VSNWPRINTF */
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#ifndef _CL_HAVE_WCHAR_H
+#define _CL_HAVE_WCHAR_H 1
+#endif
+
+/* Define to 1 if the system has the type `wchar_t'. */
+#ifndef _CL_HAVE_WCHAR_T
+#define _CL_HAVE_WCHAR_T 1
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C) && !defined(__MINGW32__) && \
+ !defined(Q_OS_MAC) && !defined(__HP_aCC)
+ /* Define to 1 if you have the `wcscasecmp' function. */
+# ifndef _CL_HAVE_WCSCASECMP
+# define _CL_HAVE_WCSCASECMP 1
+# endif
+#endif
+
+/* Define to 1 if you have the `wcscat' function. */
+#ifndef _CL_HAVE_WCSCAT
+#define _CL_HAVE_WCSCAT 1
+#endif
+
+/* Define to 1 if you have the `wcschr' function. */
+#ifndef _CL_HAVE_WCSCHR
+#define _CL_HAVE_WCSCHR 1
+#endif
+
+/* Define to 1 if you have the `wcscmp' function. */
+#ifndef _CL_HAVE_WCSCMP
+#define _CL_HAVE_WCSCMP 1
+#endif
+
+/* Define to 1 if you have the `wcscpy' function. */
+#ifndef _CL_HAVE_WCSCPY
+#define _CL_HAVE_WCSCPY 1
+#endif
+
+/* Define to 1 if you have the `wcscspn' function. */
+#ifndef _CL_HAVE_WCSCSPN
+#define _CL_HAVE_WCSCSPN 1
+#endif
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the `wcsicmp' function. */
+# ifndef _CL_HAVE_WCSICMP
+# define _CL_HAVE_WCSICMP 1
+# endif
+#endif
+
+/* Define to 1 if you have the `wcslen' function. */
+#ifndef _CL_HAVE_WCSLEN
+#define _CL_HAVE_WCSLEN 1
+#endif
+
+/* Define to 1 if you have the `wcsncmp' function. */
+#ifndef _CL_HAVE_WCSNCMP
+#define _CL_HAVE_WCSNCMP 1
+#endif
+
+/* Define to 1 if you have the `wcsncpy' function. */
+#ifndef _CL_HAVE_WCSNCPY
+#define _CL_HAVE_WCSNCPY 1
+#endif
+
+/* Define to 1 if you have the `wcsstr' function. */
+#ifndef _CL_HAVE_WCSSTR
+#define _CL_HAVE_WCSSTR 1
+#endif
+
+/* Define to 1 if you have the `wcstod' function. */
+#ifndef _CL_HAVE_WCSTOD
+#define _CL_HAVE_WCSTOD 1
+#endif
+
+#if !defined(__SUNPRO_CC) && !defined(__SUNPRO_C) && !defined(__HP_aCC)
+ /* Define to 1 if you have the `wcstoll' function. */
+# ifndef _CL_HAVE_WCSTOLL
+# define _CL_HAVE_WCSTOLL 1
+# endif
+#endif
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the `wcsupr' function. */
+# ifndef _CL_HAVE_WCSUPR
+# define _CL_HAVE_WCSUPR 1
+# endif
+#endif
+
+#if defined(__SUNPRO_CC) || defined(__SUNPRO_C) || defined(__HP_aCC)
+ /* Define to 1 if you have a functioning <wchar.h> header file. */
+# ifndef _CL_HAVE_WCTYPE_H
+# define _CL_HAVE_WCTYPE_H
+# endif
+#endif
+
+/* Define to 1 if you have the `wprintf' function. */
+/* #undef _CL_HAVE_WPRINTF */
+
+#if defined(__MINGW32__)
+ /* Define to 1 if you have the `_filelength' function. */
+# ifndef _CL_HAVE__FILELENGTH
+# define _CL_HAVE__FILELENGTH 1
+# endif
+#endif
+
+/* How to define a static const in a class */
+#ifndef LUCENE_STATIC_CONSTANT_SYNTAX
+#define LUCENE_STATIC_CONSTANT_SYNTAX 1
+#endif
+
+/* Name of package */
+#ifndef _CL_PACKAGE
+#define _CL_PACKAGE "clucene-core"
+#endif
+
+/* Define to the address where bug reports for this package should be sent. */
+#ifndef _CL_PACKAGE_BUGREPORT
+#define _CL_PACKAGE_BUGREPORT ""
+#endif
+
+/* Define to the full name of this package. */
+#ifndef _CL_PACKAGE_NAME
+#define _CL_PACKAGE_NAME ""
+#endif
+
+/* Define to the full name and version of this package. */
+#ifndef _CL_PACKAGE_STRING
+#define _CL_PACKAGE_STRING ""
+#endif
+
+/* Define to the one symbol short name of this package. */
+#ifndef _CL_PACKAGE_TARNAME
+#define _CL_PACKAGE_TARNAME ""
+#endif
+
+/* Define to the version of this package. */
+#ifndef _CL_PACKAGE_VERSION
+#define _CL_PACKAGE_VERSION ""
+#endif
+
+/* Define to the necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef _CL_PTHREAD_CREATE_JOINABLE */
+
+/* The size of a `unsigned char', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED_CHAR */
+
+/* The size of a `unsigned int', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED_INT */
+
+/* The size of a `unsigned long', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED_LONG */
+
+/* The size of a `unsigned long long', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED_LONG_LONG */
+
+/* The size of a `unsigned __int64', as computed by sizeof. */
+/* #undef _CL_SIZEOF_UNSIGNED___INT64 */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef _CL_STAT_MACROS_BROKEN */
+
+#if !defined(__HP_aCC)
+ /* Define to 1 if you have the ANSI C header files. */
+# ifndef _CL_STDC_HEADERS
+# define _CL_STDC_HEADERS 1
+# endif
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+# ifndef _CL_TIME_WITH_SYS_TIME
+# define _CL_TIME_WITH_SYS_TIME 1
+# endif
+#endif
+
+/* Version number of package */
+#ifndef _CL_VERSION
+#define _CL_VERSION "0.9.17"
+#endif
+
+/* Forces into Ascii mode */
+/* #undef _ASCII */
+
+/* Conditional Debugging */
+/* #undef _CL__CND_DEBUG */
+
+/* debugging option */
+/* #undef _DEBUG */
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* If not already defined, then define as a datatype of *exactly* 32 bits. */
+/* #undef uint32_t */
+
+/* If not already defined, then define as a datatype of *exactly* 64 bits. */
+/* #undef uint64_t */
+
+/* If not already defined, then define as a datatype of *exactly* 8 bits. */
+/* #undef uint8_t */
+
+/* once:
+_SRC_CLUCENE_CLUCENE_CONFIG_H
+*/
+#endif
+
+
+#if defined Q_CC_MSVC && _MSC_VER < 1300
+# define LUCENE_NO_STDC_NAMESPACE
+#endif
+
+
+#endif // QCLUCENE_CONFIG_P_H
+
diff --git a/src/assistant/lib/fulltextsearch/qclucene_global_p.h b/src/assistant/lib/fulltextsearch/qclucene_global_p.h
new file mode 100644
index 000000000..887b113e5
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qclucene_global_p.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QCLUCENE_GLOBAL_P_H
+#define QCLUCENE_GLOBAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#if !defined(_MSC_VER)
+# include "qclucene-config_p.h"
+#endif
+
+#include <QtCore/QChar>
+#include <QtCore/QString>
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__) && defined(_CL_HAVE_WCHAR_H) && defined(_CL_HAVE_WCHAR_T)
+# if !defined(TCHAR)
+# define TCHAR wchar_t
+# endif
+#else
+# include <windows.h>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_SHARED) && !defined(QT_DLL)
+# define QHELP_EXPORT
+#elif defined(QHELP_LIB)
+# define QHELP_EXPORT Q_DECL_EXPORT
+#else
+# define QHELP_EXPORT Q_DECL_IMPORT
+#endif
+
+//
+// W A R N I N G
+// -------------
+//
+// adjustments here, need to be done in
+// QTDIR/src/3rdparty/clucene/src/CLucene/StdHeader.h as well
+//
+#if defined(_LUCENE_DONTIMPLEMENT_NS_MACROS)
+
+#elif !defined(DISABLE_NAMESPACE)
+# ifdef QT_NAMESPACE
+# define CL_NS_DEF(sub) namespace QT_NAMESPACE { namespace lucene{ namespace sub{
+# define CL_NS_DEF2(sub,sub2) namespace QT_NAMESPACE { namespace lucene{ namespace sub{ namespace sub2 {
+
+# define CL_NS_END }}}
+# define CL_NS_END2 }}}}
+
+# define CL_NS_USE(sub) using namespace QT_NAMESPACE::lucene::sub;
+# define CL_NS_USE2(sub,sub2) using namespace QT_NAMESPACE::lucene::sub::sub2;
+
+# define CL_NS(sub) QT_NAMESPACE::lucene::sub
+# define CL_NS2(sub,sub2) QT_NAMESPACE::lucene::sub::sub2
+# else
+# define CL_NS_DEF(sub) namespace lucene{ namespace sub{
+# define CL_NS_DEF2(sub,sub2) namespace lucene{ namespace sub{ namespace sub2 {
+
+# define CL_NS_END }}
+# define CL_NS_END2 }}}
+
+# define CL_NS_USE(sub) using namespace lucene::sub;
+# define CL_NS_USE2(sub,sub2) using namespace lucene::sub::sub2;
+
+# define CL_NS(sub) lucene::sub
+# define CL_NS2(sub,sub2) lucene::sub::sub2
+# endif
+#else
+# define CL_NS_DEF(sub)
+# define CL_NS_DEF2(sub, sub2)
+# define CL_NS_END
+# define CL_NS_END2
+# define CL_NS_USE(sub)
+# define CL_NS_USE2(sub,sub2)
+# define CL_NS(sub)
+# define CL_NS2(sub,sub2)
+#endif
+
+namespace {
+ TCHAR* QStringToTChar(const QString &str)
+ {
+ TCHAR *string = new TCHAR[(str.length() +1) * sizeof(TCHAR)];
+ memset(string, 0, (str.length() +1) * sizeof(TCHAR));
+ #if defined(UNICODE) || defined(_CL_HAVE_WCHAR_H) && defined(_CL_HAVE_WCHAR_T)
+ str.toWCharArray(string);
+ #else
+ const QByteArray ba = str.toAscii();
+ strcpy(string, ba.constData());
+ #endif
+ return string;
+ }
+
+ QString TCharToQString(const TCHAR *string)
+ {
+ #if defined(UNICODE) || defined(_CL_HAVE_WCHAR_H) && defined(_CL_HAVE_WCHAR_T)
+ QString retValue = QString::fromWCharArray(string);
+ return retValue;
+ #else
+ return QString(QLatin1String(string));
+ #endif
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCLUCENE_GLOBAL_P_H
diff --git a/src/assistant/lib/fulltextsearch/qdocument.cpp b/src/assistant/lib/fulltextsearch/qdocument.cpp
new file mode 100644
index 000000000..3c4cc068d
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qdocument.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qdocument_p.h"
+#include "qreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/util/Reader.h>
+#include <CLucene/document/Document.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneDocumentPrivate::QCLuceneDocumentPrivate()
+ : QSharedData()
+{
+ document = 0;
+ deleteCLuceneDocument = true;
+}
+
+QCLuceneDocumentPrivate::QCLuceneDocumentPrivate(const QCLuceneDocumentPrivate &other)
+ : QSharedData()
+{
+ document = _CL_POINTER(other.document);
+ deleteCLuceneDocument = other.deleteCLuceneDocument;
+}
+
+QCLuceneDocumentPrivate::~QCLuceneDocumentPrivate()
+{
+ if (deleteCLuceneDocument)
+ _CLDECDELETE(document);
+}
+
+
+QCLuceneDocument::QCLuceneDocument()
+ : d(new QCLuceneDocumentPrivate())
+{
+ // nothing todo
+ d->document = new lucene::document::Document();
+}
+
+QCLuceneDocument::~QCLuceneDocument()
+{
+ qDeleteAll(fieldList);
+ fieldList.clear();
+}
+
+void QCLuceneDocument::add(QCLuceneField *field)
+{
+ field->d->deleteCLuceneField = false;
+ d->document->add(*field->d->field);
+ fieldList.append(field);
+}
+
+QCLuceneField* QCLuceneDocument::getField(const QString &name) const
+{
+ QCLuceneField* field = 0;
+ foreach (field, fieldList) {
+ if (field->name() == name && field->d->field != 0)
+ return field;
+ }
+
+ field = 0;
+ TCHAR *fieldName = QStringToTChar(name);
+ lucene::document::Field *f = d->document->getField(fieldName);
+ if (f) {
+ field = new QCLuceneField();
+ field->d->field = f;
+ fieldList.append(field);
+ field->d->deleteCLuceneField = false;
+
+ lucene::util::Reader *r = f->readerValue();
+ if (r) {
+ field->reader->d->reader = r;
+ field->reader->d->deleteCLuceneReader = false;
+ }
+ }
+ delete [] fieldName;
+
+ return field;
+}
+
+QString QCLuceneDocument::get(const QString &name) const
+{
+ QCLuceneField* field = getField(name);
+ if (field)
+ return field->stringValue();
+
+ return QString();
+}
+
+QString QCLuceneDocument::toString() const
+{
+ return TCharToQString(d->document->toString());
+}
+
+void QCLuceneDocument::setBoost(qreal boost)
+{
+ d->document->setBoost(qreal(boost));
+}
+
+qreal QCLuceneDocument::getBoost() const
+{
+ return qreal(d->document->getBoost());
+}
+
+void QCLuceneDocument::removeField(const QString &name)
+{
+ TCHAR *fieldName = QStringToTChar(name);
+ d->document->removeField(fieldName);
+ delete [] fieldName;
+
+ QList<QCLuceneField*> tmp;
+ lucene::document::DocumentFieldEnumeration *dfe = d->document->fields();
+ while (dfe->hasMoreElements()) {
+ const lucene::document::Field* f = dfe->nextElement();
+ foreach (QCLuceneField* field, fieldList) {
+ if (f == field->d->field) {
+ tmp.append(field);
+ break;
+ }
+ }
+ }
+ _CLDELETE(dfe);
+ fieldList = tmp;
+}
+
+void QCLuceneDocument::removeFields(const QString &name)
+{
+ for (qint32 i = fieldList.count() -1; i >= 0; --i) {
+ QCLuceneField* field = fieldList.at(i);
+ if (field->name() == name)
+ delete fieldList.takeAt(i);
+ }
+
+ TCHAR *fieldName = QStringToTChar(name);
+ d->document->removeFields(fieldName);
+ delete [] fieldName;
+}
+
+QStringList QCLuceneDocument::getValues(const QString &name) const
+{
+ TCHAR *fieldName = QStringToTChar(name);
+ TCHAR **values = d->document->getValues(fieldName);
+
+ QStringList retValue;
+ if (values) {
+ for (qint32 i = 0; 0 != values[i]; ++i) {
+ retValue.append(TCharToQString((const TCHAR*)values[i]));
+ delete [] values[i]; values[i] = 0;
+ }
+ delete values;
+ }
+
+ delete [] fieldName;
+ return retValue;
+}
+
+void QCLuceneDocument::clear()
+{
+ d->document->clear();
+ qDeleteAll(fieldList);
+ fieldList.clear();
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qdocument_p.h b/src/assistant/lib/fulltextsearch/qdocument_p.h
new file mode 100644
index 000000000..31369af2a
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qdocument_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QDOCUMENT_P_H
+#define QDOCUMENT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qfield_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(document)
+ class Document;
+CL_NS_END
+CL_NS_USE(document)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneIndexReader;
+class QCLuceneIndexWriter;
+class QCLuceneIndexSearcher;
+class QCLuceneMultiSearcher;
+
+class QHELP_EXPORT QCLuceneDocumentPrivate : public QSharedData
+{
+public:
+ QCLuceneDocumentPrivate();
+ QCLuceneDocumentPrivate(const QCLuceneDocumentPrivate &other);
+
+ ~QCLuceneDocumentPrivate();
+
+ Document *document;
+ bool deleteCLuceneDocument;
+
+private:
+ QCLuceneDocumentPrivate &operator=(const QCLuceneDocumentPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneDocument
+{
+public:
+ QCLuceneDocument();
+ ~QCLuceneDocument();
+
+ void add(QCLuceneField *field);
+ QCLuceneField* getField(const QString &name) const;
+ QString get(const QString &name) const;
+ QString toString() const;
+ void setBoost(qreal boost);
+ qreal getBoost() const;
+ void removeField(const QString &name);
+ void removeFields(const QString &name);
+ QStringList getValues(const QString &name) const;
+ void clear();
+
+protected:
+ friend class QCLuceneHits;
+ friend class QCLuceneIndexReader;
+ friend class QCLuceneIndexWriter;
+ friend class QCLuceneIndexSearcher;
+ friend class QCLuceneMultiSearcher;
+ QSharedDataPointer<QCLuceneDocumentPrivate> d;
+
+private:
+ mutable QList<QCLuceneField*> fieldList;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDOCUMENT_P_H
diff --git a/src/assistant/lib/fulltextsearch/qfield.cpp b/src/assistant/lib/fulltextsearch/qfield.cpp
new file mode 100644
index 000000000..448acf0e6
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qfield.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qfield_p.h"
+#include "qreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/document/Field.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneFieldPrivate::QCLuceneFieldPrivate()
+ : QSharedData()
+{
+ field = 0;
+ deleteCLuceneField = true;
+}
+
+QCLuceneFieldPrivate::QCLuceneFieldPrivate(const QCLuceneFieldPrivate &other)
+ : QSharedData()
+{
+ field = _CL_POINTER(other.field);
+ deleteCLuceneField = other.deleteCLuceneField;
+}
+
+QCLuceneFieldPrivate::~QCLuceneFieldPrivate()
+{
+ if (deleteCLuceneField)
+ _CLDECDELETE(field);
+}
+
+
+QCLuceneField::QCLuceneField()
+ : d(new QCLuceneFieldPrivate())
+ , reader(0)
+{
+ // nothing todo
+}
+
+QCLuceneField::QCLuceneField(const QString &name, const QString &value, int configs)
+ : d(new QCLuceneFieldPrivate())
+ , reader(0)
+{
+ TCHAR* fieldName = QStringToTChar(name);
+ TCHAR* fieldValue = QStringToTChar(value);
+
+ d->field = new lucene::document::Field(fieldName, fieldValue, configs);
+
+ delete [] fieldName;
+ delete [] fieldValue;
+}
+
+QCLuceneField::QCLuceneField(const QString &name, QCLuceneReader *reader,
+ int configs)
+ : d(new QCLuceneFieldPrivate())
+ , reader(reader)
+{
+ TCHAR* fieldName = QStringToTChar(name);
+
+ reader->d->deleteCLuceneReader = false; // clucene takes ownership
+ d->field = new lucene::document::Field(fieldName, reader->d->reader, configs);
+
+ delete [] fieldName;
+}
+
+QCLuceneField::~QCLuceneField()
+{
+ delete reader;
+}
+
+QString QCLuceneField::name() const
+{
+ return TCharToQString(d->field->name());
+}
+
+QString QCLuceneField::stringValue() const
+{
+ return TCharToQString((const TCHAR*)d->field->stringValue());
+}
+
+QCLuceneReader* QCLuceneField::readerValue() const
+{
+ return reader;
+}
+
+bool QCLuceneField::isStored() const
+{
+ return d->field->isStored();
+}
+
+bool QCLuceneField::isIndexed() const
+{
+ return d->field->isIndexed();
+}
+
+bool QCLuceneField::isTokenized() const
+{
+ return d->field->isTokenized();
+}
+
+bool QCLuceneField::isCompressed() const
+{
+ return d->field->isCompressed();
+}
+
+void QCLuceneField::setConfig(int termVector)
+{
+ d->field->setConfig(termVector);
+}
+
+bool QCLuceneField::isTermVectorStored() const
+{
+ return d->field->isTermVectorStored();
+}
+
+bool QCLuceneField::isStoreOffsetWithTermVector() const
+{
+ return d->field->isStoreOffsetWithTermVector();
+}
+
+bool QCLuceneField::isStorePositionWithTermVector() const
+{
+ return d->field->isStorePositionWithTermVector();
+}
+
+qreal QCLuceneField::getBoost() const
+{
+ return qreal(d->field->getBoost());
+}
+
+void QCLuceneField::setBoost(qreal value)
+{
+ d->field->setBoost(qreal(value));
+}
+
+bool QCLuceneField::isBinary() const
+{
+ return d->field->isBinary();
+}
+
+bool QCLuceneField::getOmitNorms() const
+{
+ return d->field->getOmitNorms();
+}
+
+void QCLuceneField::setOmitNorms(bool omitNorms)
+{
+ d->field->setOmitNorms(omitNorms);
+}
+
+QString QCLuceneField::toString() const
+{
+ return TCharToQString(d->field->toString());
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qfield_p.h b/src/assistant/lib/fulltextsearch/qfield_p.h
new file mode 100644
index 000000000..39f2ff308
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qfield_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QFIELD_P_H
+#define QFIELD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(document)
+ class Field;
+CL_NS_END
+CL_NS_USE(document)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneReader;
+class QCLuceneDocument;
+
+class QHELP_EXPORT QCLuceneFieldPrivate : public QSharedData
+{
+public:
+ QCLuceneFieldPrivate();
+ QCLuceneFieldPrivate(const QCLuceneFieldPrivate &other);
+
+ ~QCLuceneFieldPrivate();
+
+ Field *field;
+ bool deleteCLuceneField;
+
+private:
+ QCLuceneFieldPrivate &operator=(const QCLuceneFieldPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneField
+{
+public:
+ enum Store {
+ STORE_YES = 1,
+ STORE_NO = 2,
+ STORE_COMPRESS = 4
+ };
+
+ enum Index {
+ INDEX_NO = 16,
+ INDEX_TOKENIZED = 32,
+ INDEX_UNTOKENIZED = 64,
+ INDEX_NONORMS = 128
+ };
+
+ enum TermVector {
+ TERMVECTOR_NO = 256,
+ TERMVECTOR_YES = 512,
+ TERMVECTOR_WITH_POSITIONS = 1024,
+ TERMVECTOR_WITH_OFFSETS = 2048
+ };
+
+ QCLuceneField(const QString &name, const QString &value, int configs);
+ QCLuceneField(const QString &name, QCLuceneReader *reader, int configs);
+ ~QCLuceneField();
+
+ QString name() const;
+ QString stringValue() const;
+ QCLuceneReader* readerValue() const;
+ bool isStored() const;
+ bool isIndexed() const;
+ bool isTokenized() const;
+ bool isCompressed() const;
+ void setConfig(int termVector);
+ bool isTermVectorStored() const;
+ bool isStoreOffsetWithTermVector() const;
+ bool isStorePositionWithTermVector() const;
+ qreal getBoost() const;
+ void setBoost(qreal value);
+ bool isBinary() const;
+ bool getOmitNorms() const;
+ void setOmitNorms(bool omitNorms);
+ QString toString() const;
+
+protected:
+ QCLuceneField();
+ friend class QCLuceneDocument;
+ QSharedDataPointer<QCLuceneFieldPrivate> d;
+
+private:
+ QCLuceneReader* reader;
+};
+
+QT_END_NAMESPACE
+
+#endif // QFIELD_P_H
diff --git a/src/assistant/lib/fulltextsearch/qfilter.cpp b/src/assistant/lib/fulltextsearch/qfilter.cpp
new file mode 100644
index 000000000..4807193ff
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qfilter.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qfilter_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/Filter.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneFilterPrivate::QCLuceneFilterPrivate()
+ : QSharedData()
+{
+ filter = 0;
+ deleteCLuceneFilter = true;
+}
+
+QCLuceneFilterPrivate::QCLuceneFilterPrivate(const QCLuceneFilterPrivate &other)
+ : QSharedData()
+{
+ filter = _CL_POINTER(other.filter);
+ deleteCLuceneFilter = other.deleteCLuceneFilter;
+}
+
+QCLuceneFilterPrivate::~QCLuceneFilterPrivate ()
+{
+ if (deleteCLuceneFilter)
+ _CLDECDELETE(filter);
+}
+
+
+QCLuceneFilter::QCLuceneFilter()
+ : d(new QCLuceneFilterPrivate())
+{
+ // nothing todo
+}
+
+QCLuceneFilter::~QCLuceneFilter()
+{
+ // nothing todo
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qfilter_p.h b/src/assistant/lib/fulltextsearch/qfilter_p.h
new file mode 100644
index 000000000..67f6615b1
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qfilter_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QFilter_P_H
+#define QFilter_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QSharedData>
+#include <QtCore/QSharedDataPointer>
+
+CL_NS_DEF(search)
+ class Filter;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneSearcher;
+
+class QHELP_EXPORT QCLuceneFilterPrivate : public QSharedData
+{
+public:
+ QCLuceneFilterPrivate();
+ QCLuceneFilterPrivate(const QCLuceneFilterPrivate &other);
+
+ ~QCLuceneFilterPrivate ();
+
+ Filter *filter;
+ bool deleteCLuceneFilter;
+
+private:
+ QCLuceneFilterPrivate &operator=(const QCLuceneFilterPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneFilter
+{
+ QCLuceneFilter();
+ virtual ~QCLuceneFilter();
+
+protected:
+ friend class QCLuceneHits;
+ friend class QCLuceneSearcher;
+ QSharedDataPointer<QCLuceneFilterPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QFilter_P_H
diff --git a/src/assistant/lib/fulltextsearch/qhits.cpp b/src/assistant/lib/fulltextsearch/qhits.cpp
new file mode 100644
index 000000000..5223a743d
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qhits.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qhits_p.h"
+#include "qsearchable_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/SearchHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneHitsPrivate::QCLuceneHitsPrivate()
+ : QSharedData()
+{
+ hits = 0;
+ deleteCLuceneHits = true;
+}
+
+QCLuceneHitsPrivate::QCLuceneHitsPrivate(const QCLuceneHitsPrivate &other)
+ : QSharedData()
+{
+ hits = _CL_POINTER(other.hits);
+ deleteCLuceneHits = other.deleteCLuceneHits;
+}
+
+QCLuceneHitsPrivate::~QCLuceneHitsPrivate()
+{
+ if (deleteCLuceneHits)
+ _CLDECDELETE(hits);
+}
+
+
+QCLuceneHits::QCLuceneHits(const QCLuceneSearcher &searcher,
+ const QCLuceneQuery &query, const QCLuceneFilter &filter)
+ : d(new QCLuceneHitsPrivate())
+{
+ d->hits = new lucene::search::Hits(searcher.d->searchable, query.d->query,
+ filter.d->filter);
+}
+
+QCLuceneHits::QCLuceneHits(const QCLuceneSearcher &searcher, const QCLuceneQuery &query,
+ const QCLuceneFilter &filter, const QCLuceneSort &sort)
+ : d(new QCLuceneHitsPrivate())
+{
+ d->hits = new lucene::search::Hits(searcher.d->searchable, query.d->query,
+ filter.d->filter, sort.d->sort);
+}
+
+QCLuceneHits::~QCLuceneHits()
+{
+ // nothing todo
+}
+
+QCLuceneDocument QCLuceneHits::document(const qint32 index)
+{
+ // TODO: check this
+ QCLuceneDocument document;
+ document.d->deleteCLuceneDocument = false;
+ lucene::document::Document &doc = d->hits->doc(int32_t(index));
+ document.d->document = &doc;
+
+ return document;
+}
+
+qint32 QCLuceneHits::length() const
+{
+ return qint32(d->hits->length());
+}
+
+qint32 QCLuceneHits::id(const qint32 index)
+{
+ return qint32(d->hits->id(int32_t(index)));
+}
+
+qreal QCLuceneHits::score(const qint32 index)
+{
+ return qreal(d->hits->score(int32_t(index)));
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qhits_p.h b/src/assistant/lib/fulltextsearch/qhits_p.h
new file mode 100644
index 000000000..98cd7021a
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qhits_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QHITS_P_H
+#define QHITS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsort_p.h"
+#include "qquery_p.h"
+#include "qfilter_p.h"
+#include "qdocument_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(search)
+ class Hits;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneSearcher;
+
+class QHELP_EXPORT QCLuceneHitsPrivate : public QSharedData
+{
+public:
+ QCLuceneHitsPrivate();
+ QCLuceneHitsPrivate(const QCLuceneHitsPrivate &other);
+
+ ~QCLuceneHitsPrivate();
+
+ Hits *hits;
+ bool deleteCLuceneHits;
+
+private:
+ QCLuceneHitsPrivate &operator=(const QCLuceneHitsPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneHits
+{
+public:
+ QCLuceneHits(const QCLuceneSearcher &searcher, const QCLuceneQuery &query,
+ const QCLuceneFilter &filter);
+ QCLuceneHits(const QCLuceneSearcher &searcher, const QCLuceneQuery &query,
+ const QCLuceneFilter &filter, const QCLuceneSort &sort);
+ virtual ~QCLuceneHits();
+
+ QCLuceneDocument document(const qint32 index);
+ qint32 length() const;
+ qint32 id (const qint32 index);
+ qreal score(const qint32 index);
+
+protected:
+ friend class QCLuceneSearcher;
+ QSharedDataPointer<QCLuceneHitsPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QHITS_P_H
diff --git a/src/assistant/lib/fulltextsearch/qindexreader.cpp b/src/assistant/lib/fulltextsearch/qindexreader.cpp
new file mode 100644
index 000000000..285a96334
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qindexreader.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qindexreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/index/IndexReader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneIndexReaderPrivate::QCLuceneIndexReaderPrivate()
+ : QSharedData()
+{
+ reader = 0;
+ deleteCLuceneIndexReader = true;
+}
+
+QCLuceneIndexReaderPrivate::QCLuceneIndexReaderPrivate(const QCLuceneIndexReaderPrivate &other)
+ : QSharedData()
+{
+ reader = _CL_POINTER(other.reader);
+ deleteCLuceneIndexReader = other.deleteCLuceneIndexReader;
+}
+
+QCLuceneIndexReaderPrivate::~QCLuceneIndexReaderPrivate()
+{
+ if (deleteCLuceneIndexReader)
+ _CLDECDELETE(reader);
+}
+
+
+QCLuceneIndexReader::QCLuceneIndexReader()
+ : d(new QCLuceneIndexReaderPrivate())
+{
+ // nothing todo, private
+}
+
+QCLuceneIndexReader::~QCLuceneIndexReader()
+{
+ // nothing todo
+}
+
+bool QCLuceneIndexReader::isLuceneFile(const QString &filename)
+{
+ using namespace lucene::index;
+
+ return IndexReader::isLuceneFile(filename);
+}
+
+bool QCLuceneIndexReader::indexExists(const QString &directory)
+{
+ using namespace lucene::index;
+ return IndexReader::indexExists(directory);
+}
+
+QCLuceneIndexReader QCLuceneIndexReader::open(const QString &path)
+{
+ using namespace lucene::index;
+
+ QCLuceneIndexReader indexReader;
+ indexReader.d->reader = IndexReader::open(path);
+
+ return indexReader;
+}
+
+void QCLuceneIndexReader::unlock(const QString &path)
+{
+ using namespace lucene::index;
+ IndexReader::unlock(path);
+}
+
+bool QCLuceneIndexReader::isLocked(const QString &directory)
+{
+ using namespace lucene::index;
+ return IndexReader::isLocked(directory);
+}
+
+quint64 QCLuceneIndexReader::lastModified(const QString &directory)
+{
+ using namespace lucene::index;
+ return quint64(IndexReader::lastModified(directory));
+}
+
+qint64 QCLuceneIndexReader::getCurrentVersion(const QString &directory)
+{
+ using namespace lucene::index;
+ return qint64(IndexReader::getCurrentVersion(directory));
+}
+
+void QCLuceneIndexReader::close()
+{
+ d->reader->close();
+}
+
+bool QCLuceneIndexReader::isCurrent()
+{
+ return d->reader->isCurrent();
+}
+
+void QCLuceneIndexReader::undeleteAll()
+{
+ d->reader->undeleteAll();
+}
+
+qint64 QCLuceneIndexReader::getVersion()
+{
+ return qint64(d->reader->getVersion());
+}
+
+void QCLuceneIndexReader::deleteDocument(qint32 docNum)
+{
+ d->reader->deleteDocument(int32_t(docNum));
+}
+
+bool QCLuceneIndexReader::hasNorms(const QString &field)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ bool retValue = d->reader->hasNorms(fieldName);
+ delete [] fieldName;
+
+ return retValue;
+}
+
+qint32 QCLuceneIndexReader::deleteDocuments(const QCLuceneTerm &term)
+{
+ return d->reader->deleteDocuments(term.d->term);
+}
+
+bool QCLuceneIndexReader::document(qint32 index, QCLuceneDocument &document)
+{
+ if (!document.d->document)
+ document.d->document = new lucene::document::Document();
+
+ if (d->reader->document(int32_t(index), document.d->document))
+ return true;
+
+ return false;
+}
+
+void QCLuceneIndexReader::setNorm(qint32 doc, const QString &field, qreal value)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ d->reader->setNorm(int32_t(doc), fieldName, qreal(value));
+ delete [] fieldName;
+}
+
+void QCLuceneIndexReader::setNorm(qint32 doc, const QString &field, quint8 value)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ d->reader->setNorm(int32_t(doc), fieldName, uint8_t(value));
+ delete [] fieldName;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qindexreader_p.h b/src/assistant/lib/fulltextsearch/qindexreader_p.h
new file mode 100644
index 000000000..7421daa17
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qindexreader_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QINDEXREADER_P_H
+#define QINDEXREADER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qterm_p.h"
+#include "qdocument_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(index)
+ class IndexReader;
+CL_NS_END
+CL_NS_USE(index)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneIndexWriter;
+class QCLuceneIndexSearcher;
+
+class QHELP_EXPORT QCLuceneIndexReaderPrivate : public QSharedData
+{
+public:
+ QCLuceneIndexReaderPrivate();
+ QCLuceneIndexReaderPrivate(const QCLuceneIndexReaderPrivate &other);
+
+ ~QCLuceneIndexReaderPrivate();
+
+ IndexReader *reader;
+ bool deleteCLuceneIndexReader;
+
+private:
+ QCLuceneIndexReaderPrivate &operator=(const QCLuceneIndexReaderPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneIndexReader
+{
+public:
+ enum FieldOption {
+ ALL = 1,
+ INDEXED = 2,
+ UNINDEXED = 4,
+ INDEXED_WITH_TERMVECTOR = 8,
+ INDEXED_NO_TERMVECTOR = 16,
+ TERMVECTOR = 32,
+ TERMVECTOR_WITH_POSITION = 64,
+ TERMVECTOR_WITH_OFFSET = 128,
+ TERMVECTOR_WITH_POSITION_OFFSET = 256
+ };
+
+ virtual ~QCLuceneIndexReader();
+
+ static bool isLuceneFile(const QString &filename);
+ static bool indexExists(const QString &directory);
+ static QCLuceneIndexReader open(const QString &path);
+
+ static void unlock(const QString &path);
+ static bool isLocked(const QString &directory);
+
+ static quint64 lastModified(const QString &directory);
+ static qint64 getCurrentVersion(const QString &directory);
+
+ void close();
+ bool isCurrent();
+ void undeleteAll();
+ qint64 getVersion();
+ void deleteDocument(qint32 docNum);
+ bool hasNorms(const QString &field);
+ qint32 deleteDocuments(const QCLuceneTerm &term);
+ bool document(qint32 index, QCLuceneDocument &document);
+ void setNorm(qint32 doc, const QString &field, qreal value);
+ void setNorm(qint32 doc, const QString &field, quint8 value);
+
+protected:
+ friend class QCLuceneIndexWriter;
+ friend class QCLuceneIndexSearcher;
+ QSharedDataPointer<QCLuceneIndexReaderPrivate> d;
+
+private:
+ QCLuceneIndexReader();
+};
+
+QT_END_NAMESPACE
+
+#endif // QINDEXREADER_P_H
diff --git a/src/assistant/lib/fulltextsearch/qindexwriter.cpp b/src/assistant/lib/fulltextsearch/qindexwriter.cpp
new file mode 100644
index 000000000..1f579eb65
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qindexwriter.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qindexwriter_p.h"
+#include "qindexreader_p.h"
+
+#include <CLucene.h>
+#include <CLucene/index/IndexWriter.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneIndexWriterPrivate::QCLuceneIndexWriterPrivate()
+ : QSharedData()
+{
+ writer = 0;
+ deleteCLuceneIndexWriter = true;
+}
+
+QCLuceneIndexWriterPrivate::QCLuceneIndexWriterPrivate(const QCLuceneIndexWriterPrivate &other)
+ : QSharedData()
+{
+ writer = _CL_POINTER(other.writer);
+ deleteCLuceneIndexWriter = other.deleteCLuceneIndexWriter;
+}
+
+QCLuceneIndexWriterPrivate::~QCLuceneIndexWriterPrivate()
+{
+ if (deleteCLuceneIndexWriter)
+ _CLDECDELETE(writer);
+}
+
+
+QCLuceneIndexWriter::QCLuceneIndexWriter(const QString &path,
+ QCLuceneAnalyzer &analyzer,
+ bool create, bool closeDir)
+ : d(new QCLuceneIndexWriterPrivate())
+ , analyzer(analyzer)
+{
+ d->writer = new lucene::index::IndexWriter(path,
+ analyzer.d->analyzer, create, closeDir);
+}
+
+QCLuceneIndexWriter::~QCLuceneIndexWriter()
+{
+ // nothing todo
+}
+
+void QCLuceneIndexWriter::close()
+{
+ d->writer->close();
+}
+
+void QCLuceneIndexWriter::optimize()
+{
+ d->writer->optimize();
+}
+
+qint32 QCLuceneIndexWriter::docCount()
+{
+ return qint32(d->writer->docCount());
+}
+
+QCLuceneAnalyzer QCLuceneIndexWriter::getAnalyzer()
+{
+ return analyzer;
+}
+
+void QCLuceneIndexWriter::addIndexes(const QList<QCLuceneIndexReader*> &readers)
+{
+ using namespace lucene::index;
+ IndexReader** readerArray = new IndexReader*[readers.count()];
+
+ for (int i = 0; i < readers.count(); ++i)
+ readerArray[i] = (readers.at(i))->d->reader;
+
+ d->writer->addIndexes(readerArray);
+ delete [] readerArray;
+}
+
+void QCLuceneIndexWriter::addDocument(QCLuceneDocument &doc,
+ QCLuceneAnalyzer &analyzer)
+{
+ if (doc.d->document)
+ d->writer->addDocument(doc.d->document, analyzer.d->analyzer);
+}
+
+qint32 QCLuceneIndexWriter::getMaxFieldLength() const
+{
+ return qint32(d->writer->getMaxFieldLength());
+}
+
+void QCLuceneIndexWriter::setMaxFieldLength(qint32 value)
+{
+ d->writer->setMaxFieldLength(int32_t(value));
+}
+
+qint32 QCLuceneIndexWriter::getMaxBufferedDocs() const
+{
+ return qint32(d->writer->getMaxBufferedDocs());
+}
+
+void QCLuceneIndexWriter::setMaxBufferedDocs(qint32 value)
+{
+ d->writer->setMaxBufferedDocs(int32_t(value));
+}
+
+qint64 QCLuceneIndexWriter::getWriteLockTimeout() const
+{
+ return qint64(d->writer->getWriteLockTimeout());
+}
+
+void QCLuceneIndexWriter::setWriteLockTimeout(qint64 writeLockTimeout)
+{
+ d->writer->setWriteLockTimeout(int64_t(writeLockTimeout));
+}
+
+qint64 QCLuceneIndexWriter::getCommitLockTimeout() const
+{
+ return qint64(d->writer->getCommitLockTimeout());
+}
+
+void QCLuceneIndexWriter::setCommitLockTimeout(qint64 commitLockTimeout)
+{
+ d->writer->setCommitLockTimeout(int64_t(commitLockTimeout));
+}
+
+qint32 QCLuceneIndexWriter::getMergeFactor() const
+{
+ return qint32(d->writer->getMergeFactor());
+}
+
+void QCLuceneIndexWriter::setMergeFactor(qint32 value)
+{
+ d->writer->setMergeFactor(int32_t(value));
+}
+
+qint32 QCLuceneIndexWriter::getTermIndexInterval() const
+{
+ return qint32(d->writer->getTermIndexInterval());
+}
+
+void QCLuceneIndexWriter::setTermIndexInterval(qint32 interval)
+{
+ d->writer->setTermIndexInterval(int32_t(interval));
+}
+
+qint32 QCLuceneIndexWriter::getMinMergeDocs() const
+{
+ return qint32(d->writer->getMinMergeDocs());
+}
+
+void QCLuceneIndexWriter::setMinMergeDocs(qint32 value)
+{
+ d->writer->setMinMergeDocs(int32_t(value));
+}
+
+qint32 QCLuceneIndexWriter::getMaxMergeDocs() const
+{
+ return qint32(d->writer->getMaxMergeDocs());
+}
+
+void QCLuceneIndexWriter::setMaxMergeDocs(qint32 value)
+{
+ d->writer->setMaxMergeDocs(int32_t(value));
+}
+
+bool QCLuceneIndexWriter::getUseCompoundFile() const
+{
+ return d->writer->getUseCompoundFile();
+}
+
+void QCLuceneIndexWriter::setUseCompoundFile(bool value)
+{
+ d->writer->setUseCompoundFile(value);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qindexwriter_p.h b/src/assistant/lib/fulltextsearch/qindexwriter_p.h
new file mode 100644
index 000000000..1f9c86115
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qindexwriter_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QINDEXWRITER_P_H
+#define QINDEXWRITER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qanalyzer_p.h"
+#include "qdocument_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(index)
+ class IndexWriter;
+CL_NS_END
+CL_NS_USE(index)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneIndexReader;
+
+class QHELP_EXPORT QCLuceneIndexWriterPrivate : public QSharedData
+{
+public:
+ QCLuceneIndexWriterPrivate();
+ QCLuceneIndexWriterPrivate(const QCLuceneIndexWriterPrivate &other);
+
+ ~QCLuceneIndexWriterPrivate();
+
+ IndexWriter *writer;
+ bool deleteCLuceneIndexWriter;
+
+private:
+ QCLuceneIndexWriterPrivate &operator=(const QCLuceneIndexWriterPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneIndexWriter
+{
+public:
+ enum {
+ DEFAULT_MERGE_FACTOR = 10,
+ COMMIT_LOCK_TIMEOUT = 10000,
+ DEFAULT_MAX_BUFFERED_DOCS = 10,
+ DEFAULT_MAX_FIELD_LENGTH = 10000,
+ DEFAULT_TERM_INDEX_INTERVAL = 128,
+ DEFAULT_MAX_MERGE_DOCS = 0x7FFFFFFFL
+ };
+
+ QCLuceneIndexWriter(const QString &path, QCLuceneAnalyzer &analyzer,
+ bool create, bool closeDir = true);
+ virtual ~QCLuceneIndexWriter();
+
+ void close();
+ void optimize();
+ qint32 docCount();
+ QCLuceneAnalyzer getAnalyzer();
+
+ void addIndexes(const QList<QCLuceneIndexReader*> &readers);
+ void addDocument(QCLuceneDocument &doc, QCLuceneAnalyzer &analyzer);
+
+ qint32 getMaxFieldLength() const;
+ void setMaxFieldLength(qint32 value);
+
+ qint32 getMaxBufferedDocs() const;
+ void setMaxBufferedDocs(qint32 value);
+
+ qint64 getWriteLockTimeout() const;
+ void setWriteLockTimeout(qint64 writeLockTimeout);
+
+ qint64 getCommitLockTimeout() const;
+ void setCommitLockTimeout(qint64 commitLockTimeout);
+
+ qint32 getMergeFactor() const;
+ void setMergeFactor(qint32 value);
+
+ qint32 getTermIndexInterval() const;
+ void setTermIndexInterval(qint32 interval);
+
+ qint32 getMinMergeDocs() const;
+ void setMinMergeDocs(qint32 value);
+
+ qint32 getMaxMergeDocs() const;
+ void setMaxMergeDocs(qint32 value);
+
+ bool getUseCompoundFile() const;
+ void setUseCompoundFile(bool value);
+
+protected:
+ QSharedDataPointer<QCLuceneIndexWriterPrivate> d;
+
+private:
+ QCLuceneAnalyzer analyzer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QINDEXWRITER_P_H
diff --git a/src/assistant/lib/fulltextsearch/qquery.cpp b/src/assistant/lib/fulltextsearch/qquery.cpp
new file mode 100644
index 000000000..170341cdd
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qquery.cpp
@@ -0,0 +1,358 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qquery_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/PhraseQuery.h>
+#include <CLucene/search/SearchHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneQueryPrivate::QCLuceneQueryPrivate()
+ : QSharedData()
+{
+ query = 0;
+ deleteCLuceneQuery = true;
+}
+
+QCLuceneQueryPrivate::QCLuceneQueryPrivate(const QCLuceneQueryPrivate &other)
+ : QSharedData()
+{
+ query = _CL_POINTER(other.query);
+ deleteCLuceneQuery = other.deleteCLuceneQuery;
+}
+
+QCLuceneQueryPrivate::~QCLuceneQueryPrivate()
+{
+ if (deleteCLuceneQuery)
+ _CLDECDELETE(query);
+}
+
+
+QCLuceneQuery::QCLuceneQuery()
+ : d(new QCLuceneQueryPrivate())
+{
+ // nothing todo, private
+}
+
+QCLuceneQuery::~QCLuceneQuery()
+{
+ // nothing todo
+}
+
+void QCLuceneQuery::setBoost(qreal boost)
+{
+ d->query->setBoost(qreal(boost));
+}
+
+qreal QCLuceneQuery::getBoost() const
+{
+ return qreal(d->query->getBoost());
+}
+
+QString QCLuceneQuery::getQueryName() const
+{
+ return TCharToQString(d->query->getQueryName());
+}
+
+bool QCLuceneQuery::instanceOf(const QString &other) const
+{
+ if (other == getQueryName())
+ return true;
+
+ return false;
+}
+
+QString QCLuceneQuery::toString(const QString &field) const
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ QString retValue = TCharToQString(d->query->toString(fieldName));
+ delete [] fieldName;
+
+ return retValue;
+}
+
+quint32 QCLuceneQuery::hashCode() const
+{
+ return quint32(d->query->hashCode());
+}
+
+QString QCLuceneQuery::toString() const
+{
+ return TCharToQString(d->query->toString());
+}
+
+bool QCLuceneQuery::equals(const QCLuceneQuery &other) const
+{
+ return d->query->equals(other.d->query);
+}
+
+
+QCLucenePrefixQuery::QCLucenePrefixQuery(const QCLuceneTerm &prefix)
+ : QCLuceneQuery()
+ , prefix(prefix)
+{
+ d->query = new lucene::search::PrefixQuery(prefix.d->term);
+}
+
+QCLucenePrefixQuery::~QCLucenePrefixQuery()
+{
+ // nothing todo
+}
+
+QString QCLucenePrefixQuery::getClassName()
+{
+ return TCharToQString(lucene::search::PrefixQuery::getClassName());
+}
+
+QCLuceneTerm QCLucenePrefixQuery::getPrefix() const
+{
+ return prefix;
+}
+
+
+QCLuceneRangeQuery::QCLuceneRangeQuery(const QCLuceneTerm &lowerTerm,
+ const QCLuceneTerm &upperTerm,
+ bool inclusive)
+ : QCLuceneQuery()
+ , lowerTerm(lowerTerm)
+ , upperTerm(upperTerm)
+{
+ d->query = new lucene::search::RangeQuery(lowerTerm.d->term,
+ upperTerm.d->term, inclusive);
+}
+
+QCLuceneRangeQuery::~QCLuceneRangeQuery()
+{
+ // nothing todo
+}
+
+QString QCLuceneRangeQuery::getClassName()
+{
+ return TCharToQString(lucene::search::RangeQuery::getClassName());
+}
+
+QCLuceneTerm QCLuceneRangeQuery::getLowerTerm() const
+{
+ return lowerTerm;
+}
+
+QCLuceneTerm QCLuceneRangeQuery::getUpperTerm() const
+{
+ return upperTerm;
+}
+
+bool QCLuceneRangeQuery::isInclusive() const
+{
+ lucene::search::RangeQuery *query =
+ static_cast<lucene::search::RangeQuery*> (d->query);
+
+ if (query == 0)
+ return false;
+
+ return query->isInclusive();
+}
+
+QString QCLuceneRangeQuery::getField() const
+{
+ lucene::search::RangeQuery *query =
+ static_cast<lucene::search::RangeQuery*> (d->query);
+
+ if (query == 0)
+ return QString();
+
+ return TCharToQString(query->getField());
+}
+
+
+QCLuceneTermQuery::QCLuceneTermQuery(const QCLuceneTerm &term)
+ : QCLuceneQuery()
+ , term(term)
+{
+ d->query = new lucene::search::TermQuery(term.d->term);
+}
+
+QCLuceneTermQuery::~QCLuceneTermQuery()
+{
+ // nothing todo
+}
+
+QString QCLuceneTermQuery::getClassName()
+{
+ return TCharToQString(lucene::search::TermQuery::getClassName());
+}
+
+QCLuceneTerm QCLuceneTermQuery::getTerm() const
+{
+ return term;
+}
+
+
+QCLuceneBooleanQuery::QCLuceneBooleanQuery()
+ : QCLuceneQuery()
+{
+ d->query = new lucene::search::BooleanQuery();
+}
+
+QCLuceneBooleanQuery::~QCLuceneBooleanQuery()
+{
+ qDeleteAll(queries);
+}
+
+QString QCLuceneBooleanQuery::getClassName()
+{
+ return TCharToQString(lucene::search::BooleanQuery::getClassName());
+}
+
+quint32 QCLuceneBooleanQuery::getClauseCount() const
+{
+ lucene::search::BooleanQuery *query =
+ static_cast<lucene::search::BooleanQuery*> (d->query);
+
+ if (query == 0)
+ return 1024;
+
+ return quint32(query->getClauseCount());
+}
+
+quint32 QCLuceneBooleanQuery::getMaxClauseCount() const
+{
+ lucene::search::BooleanQuery *query =
+ static_cast<lucene::search::BooleanQuery*> (d->query);
+
+ if (query == 0)
+ return 1024;
+
+ return quint32(query->getMaxClauseCount());
+}
+
+void QCLuceneBooleanQuery::setMaxClauseCount(quint32 maxClauseCount)
+{
+ lucene::search::BooleanQuery *query =
+ static_cast<lucene::search::BooleanQuery*> (d->query);
+
+ if (query == 0)
+ return;
+
+ query->setMaxClauseCount(size_t(maxClauseCount));
+}
+
+void QCLuceneBooleanQuery::add(QCLuceneQuery *query, bool required, bool prohibited)
+{
+ add(query, false, required, prohibited);
+}
+
+void QCLuceneBooleanQuery::add(QCLuceneQuery *query, bool delQuery,
+ bool required, bool prohibited)
+{
+ lucene::search::BooleanQuery *booleanQuery =
+ static_cast<lucene::search::BooleanQuery*> (d->query);
+
+ if (booleanQuery == 0)
+ return;
+
+ booleanQuery->add(query->d->query, delQuery, required, prohibited);
+
+ if (delQuery) {
+ queries.append(query);
+ query->d->deleteCLuceneQuery = false;
+ }
+}
+
+
+QCLucenePhraseQuery::QCLucenePhraseQuery()
+ : QCLuceneQuery()
+{
+ d->query = new lucene::search::PhraseQuery();
+}
+
+QCLucenePhraseQuery::~QCLucenePhraseQuery()
+{
+ termList.clear();
+}
+
+QString QCLucenePhraseQuery::getClassName()
+{
+ return TCharToQString(lucene::search::RangeQuery::getClassName());
+}
+
+qint32 QCLucenePhraseQuery::getSlop() const
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return 0;
+
+ return qint32(phraseQuery->getSlop());
+}
+
+void QCLucenePhraseQuery::setSlop(const qint32 slop)
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return;
+
+ phraseQuery->setSlop(int32_t(slop));
+}
+
+void QCLucenePhraseQuery::addTerm(const QCLuceneTerm &term)
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return;
+
+ termList.append(term);
+ phraseQuery->add(term.d->term);
+}
+
+void QCLucenePhraseQuery::addTerm(const QCLuceneTerm &term, qint32 position)
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return;
+
+ termList.insert(position, term);
+ phraseQuery->add(term.d->term, int32_t(position));
+
+}
+
+QString QCLucenePhraseQuery::getFieldName() const
+{
+ lucene::search::PhraseQuery *phraseQuery =
+ static_cast<lucene::search::PhraseQuery*> (d->query);
+
+ if (phraseQuery == 0)
+ return QString();
+
+ return TCharToQString(phraseQuery->getFieldName());
+}
+
+QList<QCLuceneTerm> QCLucenePhraseQuery::getTerms() const
+{
+ return termList;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qquery_p.h b/src/assistant/lib/fulltextsearch/qquery_p.h
new file mode 100644
index 000000000..3268b7c42
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qquery_p.h
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QQUERY_P_H
+#define QQUERY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qterm_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(search)
+ class Query;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneTermQuery;
+class QCLuceneRangeQuery;
+class QCLuceneQueryParser;
+class QCLucenePrefixQuery;
+class QCLuceneBooleanQuery;
+class QCLucenePhraseQuery;
+
+class QHELP_EXPORT QCLuceneQueryPrivate : public QSharedData
+{
+public:
+ QCLuceneQueryPrivate();
+ QCLuceneQueryPrivate(const QCLuceneQueryPrivate &other);
+
+ ~QCLuceneQueryPrivate();
+
+ Query *query;
+ bool deleteCLuceneQuery;
+
+private:
+ QCLuceneQueryPrivate &operator=(const QCLuceneQueryPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneQuery
+{
+public:
+ virtual ~QCLuceneQuery();
+
+ void setBoost(qreal boost);
+ qreal getBoost() const;
+ QString getQueryName() const;
+ bool instanceOf(const QString &other) const;
+ QString toString(const QString &field) const;
+ quint32 hashCode() const;
+ QString toString() const;
+ bool equals(const QCLuceneQuery &other) const;
+
+protected:
+ friend class QCLuceneHits;
+ friend class QCLuceneTermQuery;
+ friend class QCLuceneRangeQuery;
+ friend class QCLucenePrefixQuery;
+ friend class QCLuceneQueryParser;
+ friend class QCLuceneBooleanQuery;
+ friend class QCLucenePhraseQuery;
+ QSharedDataPointer<QCLuceneQueryPrivate> d;
+
+private:
+ QCLuceneQuery();
+};
+
+class QHELP_EXPORT QCLucenePrefixQuery : public QCLuceneQuery
+{
+public:
+ QCLucenePrefixQuery(const QCLuceneTerm &prefix);
+ ~QCLucenePrefixQuery();
+
+ static QString getClassName();
+
+ QCLuceneTerm getPrefix() const;
+
+private:
+ QCLuceneTerm prefix;
+};
+
+class QHELP_EXPORT QCLuceneRangeQuery : public QCLuceneQuery
+{
+public:
+ QCLuceneRangeQuery(const QCLuceneTerm &lowerTerm,
+ const QCLuceneTerm &upperTerm, bool inclusive);
+ ~QCLuceneRangeQuery();
+
+ static QString getClassName();
+
+ QCLuceneTerm getLowerTerm() const;
+ QCLuceneTerm getUpperTerm() const;
+
+ bool isInclusive() const;
+ QString getField() const;
+
+private:
+ QCLuceneTerm lowerTerm;
+ QCLuceneTerm upperTerm;
+};
+
+class QHELP_EXPORT QCLuceneTermQuery : public QCLuceneQuery
+{
+public:
+ QCLuceneTermQuery(const QCLuceneTerm &term);
+ ~QCLuceneTermQuery();
+
+ static QString getClassName();
+
+ QCLuceneTerm getTerm() const;
+
+private:
+ QCLuceneTerm term;
+};
+
+class QHELP_EXPORT QCLuceneBooleanQuery : public QCLuceneQuery
+{
+public:
+ QCLuceneBooleanQuery();
+ ~QCLuceneBooleanQuery();
+
+ static QString getClassName();
+
+ quint32 getClauseCount() const;
+ quint32 getMaxClauseCount() const;
+ void setMaxClauseCount(quint32 maxClauseCount);
+
+ void add(QCLuceneQuery *query, bool required, bool prohibited);
+ void add(QCLuceneQuery *query, bool delQuery, bool required, bool prohibited);
+
+private:
+ QList<QCLuceneQuery*> queries;
+};
+
+class QHELP_EXPORT QCLucenePhraseQuery : public QCLuceneQuery
+{
+public:
+ QCLucenePhraseQuery();
+ ~QCLucenePhraseQuery();
+
+ static QString getClassName();
+
+ qint32 getSlop() const;
+ void setSlop(const qint32 slop);
+
+ void addTerm(const QCLuceneTerm &term);
+ void addTerm(const QCLuceneTerm &term, qint32 position);
+
+ QString getFieldName() const;
+ QList<QCLuceneTerm> getTerms() const;
+
+private:
+ QList<QCLuceneTerm> termList;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUERY_P_H
diff --git a/src/assistant/lib/fulltextsearch/qqueryparser.cpp b/src/assistant/lib/fulltextsearch/qqueryparser.cpp
new file mode 100644
index 000000000..f306a041b
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qqueryparser.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qqueryparser_p.h"
+#include "qquery_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/queryParser/QueryParser.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneQueryParserPrivate::QCLuceneQueryParserPrivate()
+ : QSharedData()
+{
+ queryParser = 0;
+ deleteCLuceneQueryParser = true;
+}
+
+QCLuceneQueryParserPrivate::QCLuceneQueryParserPrivate(const QCLuceneQueryParserPrivate &other)
+ : QSharedData()
+{
+ queryParser = _CL_POINTER(other.queryParser);
+ deleteCLuceneQueryParser = other.deleteCLuceneQueryParser;
+}
+
+QCLuceneQueryParserPrivate::~QCLuceneQueryParserPrivate()
+{
+ if (deleteCLuceneQueryParser)
+ _CLDECDELETE(queryParser);
+}
+
+
+QCLuceneQueryParser::QCLuceneQueryParser(const QString &field,
+ QCLuceneAnalyzer &analyzer)
+ : d(new QCLuceneQueryParserPrivate())
+ , field(field)
+ , analyzer(analyzer)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+
+ d->queryParser = new lucene::queryParser::QueryParser(fieldName,
+ analyzer.d->analyzer);
+
+ delete [] fieldName;
+}
+
+QCLuceneQueryParser::~QCLuceneQueryParser()
+{
+ // nothing todo
+}
+
+QCLuceneQuery* QCLuceneQueryParser::parse(const QString &query)
+{
+ TCHAR *string = QStringToTChar(query);
+
+ QCLuceneQuery *retValue = 0;
+ lucene::search::Query* q = d->queryParser->parse(string);
+ if (q) {
+ retValue = new QCLuceneQuery();
+ retValue->d->query = q;
+ }
+
+ delete [] string;
+ return retValue;
+}
+
+QCLuceneQuery* QCLuceneQueryParser::parse(QCLuceneReader &reader)
+{
+ QCLuceneQuery *retValue = 0;
+ lucene::search::Query* q = d->queryParser->parse(reader.d->reader);
+ if (q) {
+ retValue = new QCLuceneQuery();
+ retValue->d->query = q;
+ }
+
+ return retValue;
+}
+
+QCLuceneQuery* QCLuceneQueryParser::parse(const QString &query, const QString &field,
+ QCLuceneAnalyzer &analyzer)
+{
+ QCLuceneQueryParser parser(field, analyzer);
+ return parser.parse(query);
+}
+
+QCLuceneAnalyzer QCLuceneQueryParser::getAnalyzer()
+{
+ return analyzer;
+}
+
+QString QCLuceneQueryParser::getField()
+{
+ return field;
+}
+
+
+QCLuceneMultiFieldQueryParser::QCLuceneMultiFieldQueryParser(
+ const QStringList &fieldList, QCLuceneAnalyzer &analyzer)
+ : QCLuceneQueryParser(QLatin1String(""), analyzer)
+{
+ Q_UNUSED(fieldList)
+}
+
+QCLuceneMultiFieldQueryParser::~QCLuceneMultiFieldQueryParser()
+{
+ // nothing todo
+}
+
+QCLuceneQuery* QCLuceneMultiFieldQueryParser::parse(const QString &query,
+ const QStringList &fieldList,
+ QCLuceneAnalyzer &analyzer)
+{
+ QCLuceneBooleanQuery *retValue = new QCLuceneBooleanQuery();
+ foreach (const QString &field, fieldList) {
+ QCLuceneQuery *q = QCLuceneQueryParser::parse(query, field, analyzer);
+ if (!q) {
+ delete retValue;
+ retValue = 0; break;
+ } else {
+ retValue->add(q, true, false, false);
+ }
+ }
+
+ return retValue;
+}
+
+QCLuceneQuery* QCLuceneMultiFieldQueryParser::parse(const QString &query,
+ const QStringList &fieldList,
+ QList<FieldFlags> flags,
+ QCLuceneAnalyzer &analyzer)
+{
+ QCLuceneBooleanQuery *retValue = new QCLuceneBooleanQuery();
+ qint32 i = 0;
+ foreach (const QString &field, fieldList) {
+ QCLuceneQuery *q = QCLuceneQueryParser::parse(query, field, analyzer);
+ if (q) {
+ qint32 flag = flags.at(i);
+ switch (flag) {
+ case QCLuceneMultiFieldQueryParser::REQUIRED_FIELD: {
+ retValue->add(q, true, true, false);
+ } break;
+
+ case QCLuceneMultiFieldQueryParser::PROHIBITED_FIELD: {
+ retValue->add(q, true, false, true);
+ } break;
+
+ default: {
+ retValue->add(q, true, false, false);
+ } break;
+ }
+
+ ++i;
+ } else {
+ delete retValue;
+ retValue = 0; break;
+ }
+ }
+ return retValue;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qqueryparser_p.h b/src/assistant/lib/fulltextsearch/qqueryparser_p.h
new file mode 100644
index 000000000..e1b8c74eb
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qqueryparser_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QQUERYPARSER_P_H
+#define QQUERYPARSER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qreader_p.h"
+#include "qanalyzer_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(queryParser)
+ class QueryParser;
+CL_NS_END
+CL_NS_USE(queryParser)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneQuery;
+class QCLuceneMultiFieldQueryParser;
+
+class QHELP_EXPORT QCLuceneQueryParserPrivate : public QSharedData
+{
+public:
+ QCLuceneQueryParserPrivate();
+ QCLuceneQueryParserPrivate(const QCLuceneQueryParserPrivate &other);
+
+ ~QCLuceneQueryParserPrivate();
+
+ QueryParser *queryParser;
+ bool deleteCLuceneQueryParser;
+
+private:
+ QCLuceneQueryParserPrivate &operator=(const QCLuceneQueryParserPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneQueryParser
+{
+public:
+ QCLuceneQueryParser(const QString &field, QCLuceneAnalyzer &analyzer);
+ virtual ~QCLuceneQueryParser();
+
+ QCLuceneQuery* parse(const QString &query);
+ QCLuceneQuery* parse(QCLuceneReader &reader);
+ static QCLuceneQuery* parse(const QString &query, const QString &field,
+ QCLuceneAnalyzer &analyzer);
+ QCLuceneAnalyzer getAnalyzer();
+ QString getField();
+
+protected:
+ friend class QCLuceneMultiFieldQueryParser;
+ QSharedDataPointer<QCLuceneQueryParserPrivate> d;
+
+private:
+ QString field;
+ QCLuceneAnalyzer analyzer;
+};
+
+class QHELP_EXPORT QCLuceneMultiFieldQueryParser : public QCLuceneQueryParser
+{
+public:
+ enum FieldFlags {
+ NORMAL_FIELD = 0,
+ REQUIRED_FIELD = 1,
+ PROHIBITED_FIELD = 2
+ };
+
+ QCLuceneMultiFieldQueryParser(const QStringList &fieldList,
+ QCLuceneAnalyzer &analyzer);
+ ~QCLuceneMultiFieldQueryParser();
+
+ static QCLuceneQuery *parse(const QString &query, const QStringList &fieldList,
+ QCLuceneAnalyzer &analyzer);
+ static QCLuceneQuery *parse(const QString &query, const QStringList &fieldList,
+ QList<FieldFlags> flags, QCLuceneAnalyzer &analyzer);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUERYPARSER_P_H
diff --git a/src/assistant/lib/fulltextsearch/qreader.cpp b/src/assistant/lib/fulltextsearch/qreader.cpp
new file mode 100644
index 000000000..0a8b7accf
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qreader.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/util/Reader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneReaderPrivate::QCLuceneReaderPrivate()
+ : QSharedData()
+{
+ reader = 0;
+ deleteCLuceneReader = true;
+}
+
+QCLuceneReaderPrivate::QCLuceneReaderPrivate(const QCLuceneReaderPrivate &other)
+ : QSharedData()
+{
+ reader = _CL_POINTER(other.reader);
+ deleteCLuceneReader = other.deleteCLuceneReader;
+}
+
+QCLuceneReaderPrivate::~QCLuceneReaderPrivate()
+{
+ if (deleteCLuceneReader)
+ _CLDECDELETE(reader);
+}
+
+QCLuceneReader::QCLuceneReader()
+ : d(new QCLuceneReaderPrivate())
+{
+ // nothing todo
+}
+
+QCLuceneReader::~QCLuceneReader()
+{
+ // nothing todo
+}
+
+
+QCLuceneStringReader::QCLuceneStringReader(const QString &value)
+ : QCLuceneReader()
+ , string(QStringToTChar(value))
+{
+ d->reader = new lucene::util::StringReader(string);
+}
+
+QCLuceneStringReader::QCLuceneStringReader(const QString &value, qint32 length)
+ : QCLuceneReader()
+ , string(QStringToTChar(value))
+{
+ d->reader = new lucene::util::StringReader(string, int32_t(length));
+}
+
+QCLuceneStringReader::QCLuceneStringReader(const QString &value, qint32 length,
+ bool copyData)
+ : QCLuceneReader()
+ , string(QStringToTChar(value))
+{
+ d->reader = new lucene::util::StringReader(string, int32_t(length), copyData);
+}
+
+QCLuceneStringReader::~QCLuceneStringReader()
+{
+ delete [] string;
+}
+
+
+QCLuceneFileReader::QCLuceneFileReader(const QString &path, const QString &encoding,
+ qint32 cacheLength, qint32 cacheBuffer)
+ : QCLuceneReader()
+{
+ const QByteArray tmpPath = path.toLocal8Bit();
+ const QByteArray tmpEncoding = encoding.toAscii();
+ d->reader = new lucene::util::FileReader(tmpPath.constData(),
+ tmpEncoding.constData(), int32_t(cacheLength), int32_t(cacheBuffer));
+}
+
+QCLuceneFileReader::~QCLuceneFileReader()
+{
+ // nothing todo
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qreader_p.h b/src/assistant/lib/fulltextsearch/qreader_p.h
new file mode 100644
index 000000000..e24e9d836
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qreader_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QREADER_P_H
+#define QREADER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(util)
+ class Reader;
+CL_NS_END
+CL_NS_USE(util)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneField;
+class QCLuceneAnalyzer;
+class QCLuceneDocument;
+class QCLuceneQueryParser;
+class QCLuceneStandardTokenizer;
+
+class QHELP_EXPORT QCLuceneReaderPrivate : public QSharedData
+{
+public:
+ QCLuceneReaderPrivate();
+ QCLuceneReaderPrivate(const QCLuceneReaderPrivate &other);
+
+ ~QCLuceneReaderPrivate();
+
+ Reader* reader;
+ bool deleteCLuceneReader;
+
+private:
+ QCLuceneReaderPrivate &operator=(const QCLuceneReaderPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneReader
+{
+public:
+ QCLuceneReader();
+ virtual ~QCLuceneReader();
+
+protected:
+ friend class QCLuceneField;
+ friend class QCLuceneAnalyzer;
+ friend class QCLuceneDocument;
+ friend class QCLuceneQueryParser;
+ friend class QCLuceneStandardTokenizer;
+ QSharedDataPointer<QCLuceneReaderPrivate> d;
+};
+
+class QCLuceneStringReader : public QCLuceneReader
+{
+public:
+ QCLuceneStringReader(const QString &value);
+ QCLuceneStringReader(const QString &value, qint32 length);
+ QCLuceneStringReader(const QString &value, qint32 length, bool copyData);
+
+ ~QCLuceneStringReader();
+
+private:
+ TCHAR *string;
+};
+
+class QHELP_EXPORT QCLuceneFileReader : public QCLuceneReader
+{
+public:
+ QCLuceneFileReader(const QString &path, const QString &encoding,
+ qint32 cacheLength = 13, qint32 cacheBuffer = 14);
+ ~QCLuceneFileReader();
+};
+
+QT_END_NAMESPACE
+
+#endif // QREADER_P_H
diff --git a/src/assistant/lib/fulltextsearch/qsearchable.cpp b/src/assistant/lib/fulltextsearch/qsearchable.cpp
new file mode 100644
index 000000000..508fc05f6
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qsearchable.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qsearchable_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/SearchHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneSearchablePrivate::QCLuceneSearchablePrivate()
+ : QSharedData()
+{
+ searchable = 0;
+ deleteCLuceneSearchable = true;
+}
+
+QCLuceneSearchablePrivate::QCLuceneSearchablePrivate(const QCLuceneSearchablePrivate &other)
+ : QSharedData()
+{
+ searchable = _CL_POINTER(other.searchable);
+ deleteCLuceneSearchable = other.deleteCLuceneSearchable;
+}
+
+QCLuceneSearchablePrivate::~QCLuceneSearchablePrivate()
+{
+ if (deleteCLuceneSearchable)
+ _CLDECDELETE(searchable);
+}
+
+
+QCLuceneSearchable::QCLuceneSearchable()
+ : d(new QCLuceneSearchablePrivate())
+{
+ // nothing todo
+}
+
+QCLuceneSearchable::~QCLuceneSearchable()
+{
+ // nothing todo
+}
+
+
+QCLuceneSearcher::QCLuceneSearcher()
+ : QCLuceneSearchable()
+{
+ // nothing todo
+}
+
+QCLuceneSearcher::~QCLuceneSearcher()
+{
+ // nothing todo;
+}
+
+QCLuceneHits QCLuceneSearcher::search(const QCLuceneQuery &query)
+{
+ return search(query, QCLuceneFilter());
+}
+
+QCLuceneHits QCLuceneSearcher::search(const QCLuceneQuery &query,
+ const QCLuceneFilter &filter)
+{
+ return QCLuceneHits(*this, query, filter);
+}
+
+QCLuceneHits QCLuceneSearcher::search(const QCLuceneQuery &query,
+ const QCLuceneSort &sort)
+{
+ return QCLuceneHits(*this, query, QCLuceneFilter(), sort);
+}
+
+QCLuceneHits QCLuceneSearcher::search(const QCLuceneQuery &query,
+ const QCLuceneFilter &filter,
+ const QCLuceneSort &sort)
+{
+ return QCLuceneHits(*this, query, filter, sort);
+}
+
+
+QCLuceneIndexSearcher::QCLuceneIndexSearcher(const QString &path)
+ : QCLuceneSearcher()
+{
+ lucene::search::IndexSearcher *searcher =
+ new lucene::search::IndexSearcher(path);
+
+ reader.d->reader = searcher->getReader();
+ reader.d->deleteCLuceneIndexReader = false;
+
+ d->searchable = searcher;
+}
+
+QCLuceneIndexSearcher::QCLuceneIndexSearcher(const QCLuceneIndexReader &reader)
+ : QCLuceneSearcher()
+ , reader(reader)
+{
+ d->searchable = new lucene::search::IndexSearcher(reader.d->reader);
+}
+
+QCLuceneIndexSearcher::~QCLuceneIndexSearcher()
+{
+ // nothing todo
+}
+
+void QCLuceneIndexSearcher::close()
+{
+ d->searchable->close();
+}
+
+qint32 QCLuceneIndexSearcher::maxDoc() const
+{
+ return qint32(d->searchable->maxDoc());
+}
+
+QCLuceneIndexReader QCLuceneIndexSearcher::getReader()
+{
+ return reader;
+}
+
+bool QCLuceneIndexSearcher::doc(qint32 i, QCLuceneDocument &document)
+{
+ return d->searchable->doc(int32_t(i), document.d->document);
+}
+
+
+QCLuceneMultiSearcher::QCLuceneMultiSearcher(const QList<QCLuceneSearchable> searchables)
+: QCLuceneSearcher()
+{
+ lucene::search::Searchable** list=
+ _CL_NEWARRAY(lucene::search::Searchable*, searchables.count());
+
+ d->searchable = new lucene::search::MultiSearcher(list);
+
+ _CLDELETE_ARRAY(list);
+}
+
+QCLuceneMultiSearcher::~QCLuceneMultiSearcher()
+{
+ // nothing todo
+}
+
+void QCLuceneMultiSearcher::close()
+{
+ d->searchable->close();
+}
+
+qint32 QCLuceneMultiSearcher::maxDoc() const
+{
+ return qint32(d->searchable->maxDoc());
+}
+
+qint32 QCLuceneMultiSearcher::subDoc(qint32 index) const
+{
+ lucene::search::MultiSearcher *searcher =
+ static_cast<lucene::search::MultiSearcher*> (d->searchable);
+
+ if (searcher == 0)
+ return 0;
+
+ return qint32(searcher->subDoc(int32_t(index)));
+}
+
+qint32 QCLuceneMultiSearcher::subSearcher(qint32 index) const
+{
+ lucene::search::MultiSearcher *searcher =
+ static_cast<lucene::search::MultiSearcher*> (d->searchable);
+
+ if (searcher == 0)
+ return 0;
+
+ return qint32(searcher->subSearcher(int32_t(index)));
+}
+
+qint32 QCLuceneMultiSearcher::searcherIndex(qint32 index) const
+{
+ lucene::search::MultiSearcher *searcher =
+ static_cast<lucene::search::MultiSearcher*> (d->searchable);
+
+ if (searcher == 0)
+ return 0;
+
+ return qint32(searcher->searcherIndex(int32_t(index)));
+}
+
+bool QCLuceneMultiSearcher::doc(qint32 i, QCLuceneDocument &document)
+{
+ return d->searchable->doc(int32_t(i), document.d->document);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qsearchable_p.h b/src/assistant/lib/fulltextsearch/qsearchable_p.h
new file mode 100644
index 000000000..149cfb049
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qsearchable_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QSEARCHABLE_P_H
+#define QSEARCHABLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhits_p.h"
+#include "qsort_p.h"
+#include "qquery_p.h"
+#include "qfilter_p.h"
+#include "qdocument_p.h"
+#include "qindexreader_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(search)
+ class Searcher;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneSearcher;
+class QCLuceneIndexSearcher;
+class QCLuceneMultiSearcher;
+
+class QHELP_EXPORT QCLuceneSearchablePrivate : public QSharedData
+{
+public:
+ QCLuceneSearchablePrivate();
+ QCLuceneSearchablePrivate(const QCLuceneSearchablePrivate &other);
+
+ ~QCLuceneSearchablePrivate();
+
+ Searcher *searchable;
+ bool deleteCLuceneSearchable;
+
+private:
+ QCLuceneSearchablePrivate &operator=(const QCLuceneSearchablePrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneSearchable
+{
+public:
+ virtual ~QCLuceneSearchable();
+
+protected:
+ friend class QCLuceneSearcher;
+ friend class QCLuceneIndexSearcher;
+ friend class QCLuceneMultiSearcher;
+ QSharedDataPointer<QCLuceneSearchablePrivate> d;
+
+private:
+ QCLuceneSearchable();
+};
+
+class QHELP_EXPORT QCLuceneSearcher : public QCLuceneSearchable
+{
+public:
+ QCLuceneSearcher();
+ virtual ~QCLuceneSearcher();
+
+ QCLuceneHits search(const QCLuceneQuery &query);
+ QCLuceneHits search(const QCLuceneQuery &query, const QCLuceneFilter &filter);
+ QCLuceneHits search(const QCLuceneQuery &query, const QCLuceneSort &sort);
+ QCLuceneHits search(const QCLuceneQuery &query, const QCLuceneFilter &filter,
+ const QCLuceneSort &sort);
+
+protected:
+ friend class QCLuceneHits;
+};
+
+class QHELP_EXPORT QCLuceneIndexSearcher : public QCLuceneSearcher
+{
+public:
+ QCLuceneIndexSearcher(const QString &path);
+ QCLuceneIndexSearcher(const QCLuceneIndexReader &reader);
+ ~QCLuceneIndexSearcher();
+
+ void close();
+ qint32 maxDoc() const;
+ QCLuceneIndexReader getReader();
+ bool doc(qint32 i, QCLuceneDocument &document);
+
+private:
+ QCLuceneIndexReader reader;
+};
+
+class QHELP_EXPORT QCLuceneMultiSearcher : public QCLuceneSearcher
+{
+public:
+ QCLuceneMultiSearcher(const QList<QCLuceneSearchable> searchables);
+ ~QCLuceneMultiSearcher();
+
+ void close();
+ qint32 maxDoc() const;
+ qint32 subDoc(qint32 index) const;
+ qint32 subSearcher(qint32 index) const;
+ qint32 searcherIndex(qint32 index) const;
+ bool doc(qint32 i, QCLuceneDocument &document);
+};
+
+QT_END_NAMESPACE
+
+#endif // QSEARCHABLE_P_H
diff --git a/src/assistant/lib/fulltextsearch/qsort.cpp b/src/assistant/lib/fulltextsearch/qsort.cpp
new file mode 100644
index 000000000..4dface005
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qsort.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qsort_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/search/Sort.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneSortPrivate::QCLuceneSortPrivate()
+ : QSharedData()
+{
+ sort = 0;
+ deleteCLuceneSort = true;
+}
+
+QCLuceneSortPrivate::QCLuceneSortPrivate (const QCLuceneSortPrivate &other)
+ : QSharedData()
+{
+ sort = _CL_POINTER(other.sort);
+ deleteCLuceneSort = other.deleteCLuceneSort;
+}
+
+QCLuceneSortPrivate::~QCLuceneSortPrivate()
+{
+ if (deleteCLuceneSort)
+ _CLDECDELETE(sort);
+}
+
+
+QCLuceneSort::QCLuceneSort()
+ : d(new QCLuceneSortPrivate())
+{
+ d->sort = new lucene::search::Sort();
+}
+
+QCLuceneSort::QCLuceneSort(const QStringList &fieldNames)
+ : d(new QCLuceneSortPrivate())
+{
+ d->sort = new lucene::search::Sort();
+ setSort(fieldNames);
+}
+
+QCLuceneSort::QCLuceneSort(const QString &field, bool reverse)
+ : d(new QCLuceneSortPrivate())
+{
+ d->sort = new lucene::search::Sort();
+ setSort(field, reverse);
+}
+
+QCLuceneSort::~QCLuceneSort()
+{
+ // nothing todo
+}
+
+QString QCLuceneSort::toString() const
+{
+ return TCharToQString(d->sort->toString());
+}
+
+void QCLuceneSort::setSort(const QStringList &fieldNames)
+{
+ TCHAR **nameArray = new TCHAR*[fieldNames.count()];
+ for (int i = 0; i < fieldNames.count(); ++i)
+ nameArray[i] = QStringToTChar(fieldNames.at(i));
+
+ d->sort->setSort((const TCHAR**)nameArray);
+
+ for (int i = 0; i < fieldNames.count(); ++i)
+ delete [] nameArray[i];
+ delete [] nameArray;
+}
+
+void QCLuceneSort::setSort(const QString &field, bool reverse)
+{
+ TCHAR *name = QStringToTChar(field);
+ d->sort->setSort(name, reverse);
+ delete [] name;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qsort_p.h b/src/assistant/lib/fulltextsearch/qsort_p.h
new file mode 100644
index 000000000..5d9372b11
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qsort_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QSORT_P_H
+#define QSORT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(search)
+ class Sort;
+CL_NS_END
+CL_NS_USE(search)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneHits;
+class QCLuceneField;
+
+class QHELP_EXPORT QCLuceneSortPrivate : public QSharedData
+{
+public:
+ QCLuceneSortPrivate();
+ QCLuceneSortPrivate (const QCLuceneSortPrivate &other);
+
+ ~QCLuceneSortPrivate();
+
+ Sort *sort;
+ bool deleteCLuceneSort;
+
+private:
+ QCLuceneSortPrivate &operator=(const QCLuceneSortPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneSort
+{
+public:
+ QCLuceneSort();
+ explicit QCLuceneSort(const QStringList &fieldNames);
+ explicit QCLuceneSort(const QString &field, bool reverse = false);
+
+ virtual ~QCLuceneSort();
+
+ QString toString() const;
+ void setSort(const QStringList &fieldNames);
+ void setSort(const QString &field, bool reverse = false);
+
+protected:
+ friend class QCLuceneHits;
+ QSharedDataPointer<QCLuceneSortPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSORT_P_H
diff --git a/src/assistant/lib/fulltextsearch/qterm.cpp b/src/assistant/lib/fulltextsearch/qterm.cpp
new file mode 100644
index 000000000..eeebf53c8
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qterm.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qterm_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/index/IndexReader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneTermPrivate::QCLuceneTermPrivate()
+ : QSharedData()
+{
+ term = 0;
+ deleteCLuceneTerm = true;
+}
+
+QCLuceneTermPrivate::QCLuceneTermPrivate(const QCLuceneTermPrivate &other)
+ : QSharedData()
+{
+ term = _CL_POINTER(other.term);
+ deleteCLuceneTerm = other.deleteCLuceneTerm;
+}
+
+QCLuceneTermPrivate::~QCLuceneTermPrivate()
+{
+ if (deleteCLuceneTerm)
+ _CLDECDELETE(term);
+}
+
+
+QCLuceneTerm::QCLuceneTerm()
+ : d(new QCLuceneTermPrivate())
+{
+ d->term = new lucene::index::Term();
+}
+
+QCLuceneTerm::QCLuceneTerm(const QString &field, const QString &text)
+ : d(new QCLuceneTermPrivate())
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ TCHAR *termText = QStringToTChar(text);
+
+ d->term = new lucene::index::Term(fieldName, termText);
+
+ delete [] fieldName;
+ delete [] termText;
+}
+
+QCLuceneTerm::QCLuceneTerm(const QCLuceneTerm &fieldTerm, const QString &text)
+ : d(new QCLuceneTermPrivate())
+{
+ TCHAR *termText = QStringToTChar(text);
+ d->term = new lucene::index::Term(fieldTerm.d->term, termText);
+ delete [] termText;
+}
+
+QCLuceneTerm::~QCLuceneTerm()
+{
+ // nothing todo
+}
+
+QString QCLuceneTerm::field() const
+{
+ return TCharToQString(d->term->field());
+}
+
+QString QCLuceneTerm::text() const
+{
+ return TCharToQString(d->term->text());
+}
+
+void QCLuceneTerm::set(const QString &field, const QString &text)
+{
+ set(field, text, true);
+}
+
+void QCLuceneTerm::set(const QCLuceneTerm &fieldTerm, const QString &text)
+{
+ set(fieldTerm.field(), text, false);
+}
+
+void QCLuceneTerm::set(const QString &field, const QString &text, bool internField)
+{
+ TCHAR *fieldName = QStringToTChar(field);
+ TCHAR *termText = QStringToTChar(text);
+
+ d->term->set(fieldName, termText, internField);
+
+ delete [] fieldName;
+ delete [] termText;
+}
+
+bool QCLuceneTerm::equals(const QCLuceneTerm &other) const
+{
+ return d->term->equals(other.d->term);
+}
+
+qint32 QCLuceneTerm::compareTo(const QCLuceneTerm &other) const
+{
+ return quint32(d->term->compareTo(other.d->term));
+}
+
+QString QCLuceneTerm::toString() const
+{
+ return TCharToQString(d->term->toString());
+}
+
+quint32 QCLuceneTerm::hashCode() const
+{
+ return quint32(d->term->hashCode());
+}
+
+quint32 QCLuceneTerm::textLength() const
+{
+ return quint32(d->term->textLength());
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qterm_p.h b/src/assistant/lib/fulltextsearch/qterm_p.h
new file mode 100644
index 000000000..5b981dc53
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qterm_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QTERM_P_H
+#define QTERM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QSharedData>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+
+CL_NS_DEF(index)
+ class Term;
+CL_NS_END
+CL_NS_USE(index)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneTermQuery;
+class QCLuceneRangeQuery;
+class QCLucenePrefixQuery;
+class QCLuceneIndexReader;
+class QCLucenePhraseQuery;
+
+class QHELP_EXPORT QCLuceneTermPrivate : public QSharedData
+{
+public:
+ QCLuceneTermPrivate();
+ QCLuceneTermPrivate(const QCLuceneTermPrivate &other);
+
+ ~QCLuceneTermPrivate();
+
+ Term *term;
+ bool deleteCLuceneTerm;
+
+private:
+ QCLuceneTermPrivate &operator=(const QCLuceneTermPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneTerm
+{
+public:
+ QCLuceneTerm();
+ QCLuceneTerm(const QString &field, const QString &text);
+ QCLuceneTerm(const QCLuceneTerm &fieldTerm, const QString &text);
+
+ virtual ~QCLuceneTerm();
+
+ QString field() const;
+ QString text() const;
+
+ void set(const QString &field, const QString &text);
+ void set(const QCLuceneTerm &fieldTerm, const QString &text);
+ void set(const QString &field, const QString &text, bool internField);
+
+ bool equals(const QCLuceneTerm &other) const;
+ qint32 compareTo(const QCLuceneTerm &other) const;
+
+ QString toString() const;
+ quint32 hashCode() const;
+ quint32 textLength() const;
+
+protected:
+ friend class QCLuceneTermQuery;
+ friend class QCLuceneRangeQuery;
+ friend class QCLucenePrefixQuery;
+ friend class QCLuceneIndexReader;
+ friend class QCLucenePhraseQuery;
+ QSharedDataPointer<QCLuceneTermPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTERM_P_H
diff --git a/src/assistant/lib/fulltextsearch/qtoken.cpp b/src/assistant/lib/fulltextsearch/qtoken.cpp
new file mode 100644
index 000000000..537d9e675
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qtoken.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qtoken_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneTokenPrivate::QCLuceneTokenPrivate()
+ : QSharedData()
+{
+ token = 0;
+ deleteCLuceneToken = true;
+}
+
+QCLuceneTokenPrivate::QCLuceneTokenPrivate(const QCLuceneTokenPrivate &other)
+ : QSharedData()
+{
+ token = _CL_POINTER(other.token);
+ deleteCLuceneToken = other.deleteCLuceneToken;
+}
+
+QCLuceneTokenPrivate::~QCLuceneTokenPrivate()
+{
+ if (deleteCLuceneToken)
+ _CLDECDELETE(token);
+}
+
+
+QCLuceneToken::QCLuceneToken()
+ : d(new QCLuceneTokenPrivate())
+ , tokenText(0)
+ , tokenType(0)
+{
+ d->token = new lucene::analysis::Token();
+}
+
+QCLuceneToken::QCLuceneToken(const QString &text, qint32 startOffset,
+ qint32 endOffset, const QString &defaultTyp)
+ : d(new QCLuceneTokenPrivate())
+ , tokenText(QStringToTChar(text))
+ , tokenType(QStringToTChar(defaultTyp))
+{
+ d->token = new lucene::analysis::Token(tokenText, int32_t(startOffset),
+ int32_t(endOffset), tokenType);
+}
+
+QCLuceneToken::~QCLuceneToken()
+{
+ delete [] tokenText;
+ delete [] tokenType;
+}
+
+quint32 QCLuceneToken::bufferLength() const
+{
+ return quint32(d->token->bufferLength());
+}
+
+void QCLuceneToken::growBuffer(quint32 size)
+{
+ d->token->growBuffer(size_t(size));
+}
+
+qint32 QCLuceneToken::positionIncrement() const
+{
+ return qint32(d->token->getPositionIncrement());
+}
+
+void QCLuceneToken::setPositionIncrement(qint32 positionIncrement)
+{
+ d->token->setPositionIncrement(int32_t(positionIncrement));
+}
+
+QString QCLuceneToken::termText() const
+{
+ return TCharToQString(d->token->termText());
+}
+
+void QCLuceneToken::setTermText(const QString &text)
+{
+ delete [] tokenText;
+ tokenText = QStringToTChar(text);
+ d->token->setText(tokenText);
+}
+
+quint32 QCLuceneToken::termTextLength() const
+{
+ return quint32(d->token->termTextLength());
+}
+
+void QCLuceneToken::resetTermTextLength() const
+{
+ d->token->resetTermTextLen();
+}
+
+qint32 QCLuceneToken::startOffset() const
+{
+ return quint32(d->token->startOffset());
+}
+
+void QCLuceneToken::setStartOffset(qint32 value)
+{
+ d->token->setStartOffset(int32_t(value));
+}
+
+qint32 QCLuceneToken::endOffset() const
+{
+ return quint32(d->token->endOffset());
+}
+
+void QCLuceneToken::setEndOffset(qint32 value)
+{
+ d->token->setEndOffset(int32_t(value));
+}
+
+QString QCLuceneToken::type() const
+{
+ return TCharToQString(d->token->type());
+}
+
+void QCLuceneToken::setType(const QString &type)
+{
+ delete [] tokenType;
+ tokenType = QStringToTChar(type);
+ d->token->setType(tokenType);
+}
+
+QString QCLuceneToken::toString() const
+{
+ return TCharToQString(d->token->toString());
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qtoken_p.h b/src/assistant/lib/fulltextsearch/qtoken_p.h
new file mode 100644
index 000000000..f3d25c4ff
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qtoken_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QTOKEN_P_H
+#define QTOKEN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(analysis)
+ class Token;
+CL_NS_END
+CL_NS_USE(analysis)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneTokenizer;
+class QCLuceneTokenStream;
+class QCLuceneStandardTokenizer;
+
+class QHELP_EXPORT QCLuceneTokenPrivate : public QSharedData
+{
+public:
+ QCLuceneTokenPrivate();
+ QCLuceneTokenPrivate(const QCLuceneTokenPrivate &other);
+
+ ~QCLuceneTokenPrivate();
+
+ Token *token;
+ bool deleteCLuceneToken;
+
+private:
+ QCLuceneTokenPrivate &operator=(const QCLuceneTokenPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneToken
+{
+public:
+ QCLuceneToken();
+ QCLuceneToken(const QString &text, qint32 startOffset,
+ qint32 endOffset, const QString &defaultTyp = QLatin1String("word"));
+
+ virtual ~QCLuceneToken();
+
+ void set(const QString &text, qint32 startOffset,
+ qint32 endOffset, const QString &defaultTyp = QLatin1String("word"));
+
+ quint32 bufferLength() const;
+ void growBuffer(quint32 size);
+
+ qint32 positionIncrement() const;
+ void setPositionIncrement(qint32 positionIncrement);
+
+ QString termText() const;
+ void setTermText(const QString &text);
+
+ quint32 termTextLength() const;
+ void resetTermTextLength() const;
+
+ qint32 startOffset() const;
+ void setStartOffset(qint32 value);
+
+ qint32 endOffset() const;
+ void setEndOffset(qint32 value);
+
+ QString type() const;
+ void setType(const QString &type);
+
+ QString toString() const;
+
+protected:
+ friend class QCLuceneTokenizer;
+ friend class QCLuceneTokenStream;
+ friend class QCLuceneStandardTokenizer;
+ QSharedDataPointer<QCLuceneTokenPrivate> d;
+
+private:
+ TCHAR *tokenText;
+ TCHAR *tokenType;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTOKEN_P_H
diff --git a/src/assistant/lib/fulltextsearch/qtokenizer.cpp b/src/assistant/lib/fulltextsearch/qtokenizer.cpp
new file mode 100644
index 000000000..8a79b21e6
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qtokenizer.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qtokenizer_p.h"
+#include "qclucene_global_p.h"
+
+#include <CLucene.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneTokenizer::QCLuceneTokenizer()
+ : QCLuceneTokenStream()
+{
+ // nothing todo
+}
+
+QCLuceneTokenizer::QCLuceneTokenizer(const QCLuceneReader &reader)
+ : QCLuceneTokenStream()
+ , reader(reader)
+{
+ // nothing todo
+}
+
+QCLuceneTokenizer::~QCLuceneTokenizer()
+{
+ close();
+}
+
+void QCLuceneTokenizer::close()
+{
+ d->tokenStream->close();
+}
+
+bool QCLuceneTokenizer::next(QCLuceneToken &token)
+{
+ return d->tokenStream->next(token.d->token);
+}
+
+
+QCLuceneStandardTokenizer::QCLuceneStandardTokenizer(const QCLuceneReader &reader)
+ : QCLuceneTokenizer(reader)
+{
+ d->tokenStream =
+ new lucene::analysis::standard::StandardTokenizer(reader.d->reader);
+}
+
+QCLuceneStandardTokenizer::~QCLuceneStandardTokenizer()
+{
+ // nothing todo
+}
+
+bool QCLuceneStandardTokenizer::readApostrophe(const QString &string,
+ QCLuceneToken &token)
+{
+ lucene::analysis::standard::StandardTokenizer *stdTokenizer =
+ static_cast<lucene::analysis::standard::StandardTokenizer*> (d->tokenStream);
+
+ if (stdTokenizer == 0)
+ return false;
+
+ TCHAR* value = QStringToTChar(string);
+ lucene::util::StringBuffer buffer(value);
+ bool retValue = stdTokenizer->ReadApostrophe(&buffer, token.d->token);
+ delete [] value;
+
+ return retValue;
+}
+
+bool QCLuceneStandardTokenizer::readAt(const QString &string, QCLuceneToken &token)
+{
+ lucene::analysis::standard::StandardTokenizer *stdTokenizer =
+ static_cast<lucene::analysis::standard::StandardTokenizer*> (d->tokenStream);
+
+ if (stdTokenizer == 0)
+ return false;
+
+ TCHAR* value = QStringToTChar(string);
+ lucene::util::StringBuffer buffer(value);
+ bool retValue = stdTokenizer->ReadAt(&buffer, token.d->token);
+ delete [] value;
+
+ return retValue;
+}
+
+bool QCLuceneStandardTokenizer::readCompany(const QString &string,
+ QCLuceneToken &token)
+{
+ lucene::analysis::standard::StandardTokenizer *stdTokenizer =
+ static_cast<lucene::analysis::standard::StandardTokenizer*> (d->tokenStream);
+
+ if (stdTokenizer == 0)
+ return false;
+
+ TCHAR* value = QStringToTChar(string);
+ lucene::util::StringBuffer buffer(value);
+ bool retValue = stdTokenizer->ReadCompany(&buffer, token.d->token);
+ delete [] value;
+
+ return retValue;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qtokenizer_p.h b/src/assistant/lib/fulltextsearch/qtokenizer_p.h
new file mode 100644
index 000000000..0c6e8ea1d
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qtokenizer_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QTOKENIZER_P_H
+#define QTOKENIZER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtoken_p.h"
+#include "qreader_p.h"
+#include "qtokenstream_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QChar>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+class QHELP_EXPORT QCLuceneTokenizer : public QCLuceneTokenStream
+{
+public:
+ QCLuceneTokenizer(const QCLuceneReader &reader);
+ virtual ~QCLuceneTokenizer();
+
+ void close();
+ bool next(QCLuceneToken &token);
+
+protected:
+ friend class QCLuceneStandardTokenizer;
+
+private:
+ QCLuceneTokenizer();
+ QCLuceneReader reader;
+};
+
+class QHELP_EXPORT QCLuceneStandardTokenizer : public QCLuceneTokenizer
+{
+public:
+ QCLuceneStandardTokenizer(const QCLuceneReader &reader);
+ ~QCLuceneStandardTokenizer();
+
+ bool readApostrophe(const QString &string, QCLuceneToken &token);
+ bool readAt(const QString &string, QCLuceneToken &token);
+ bool readCompany(const QString &string, QCLuceneToken &token);
+};
+
+class QCLuceneCharTokenizer : public QCLuceneTokenizer
+{
+
+};
+
+class QCLuceneLetterTokenizer : public QCLuceneCharTokenizer
+{
+
+};
+
+class QCLuceneLowerCaseTokenizer : public QCLuceneLetterTokenizer
+{
+
+};
+
+class QCLuceneWhitespaceTokenizer : public QCLuceneCharTokenizer
+{
+
+};
+
+class QCLuceneKeywordTokenizer : public QCLuceneTokenizer
+{
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QTOKENIZER_P_H
diff --git a/src/assistant/lib/fulltextsearch/qtokenstream.cpp b/src/assistant/lib/fulltextsearch/qtokenstream.cpp
new file mode 100644
index 000000000..337ebf1e3
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qtokenstream.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#include "qtokenstream_p.h"
+
+#include <CLucene.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+
+QT_BEGIN_NAMESPACE
+
+QCLuceneTokenStreamPrivate::QCLuceneTokenStreamPrivate()
+ : QSharedData()
+{
+ tokenStream = 0;
+ deleteCLuceneTokenStream = true;
+}
+
+QCLuceneTokenStreamPrivate::QCLuceneTokenStreamPrivate(const QCLuceneTokenStreamPrivate &other)
+ : QSharedData()
+{
+ tokenStream = _CL_POINTER(other.tokenStream);
+ deleteCLuceneTokenStream = other.deleteCLuceneTokenStream;
+}
+
+QCLuceneTokenStreamPrivate::~QCLuceneTokenStreamPrivate()
+{
+ if (deleteCLuceneTokenStream)
+ _CLDECDELETE(tokenStream);
+}
+
+
+QCLuceneTokenStream::QCLuceneTokenStream()
+ : d(new QCLuceneTokenStreamPrivate())
+{
+ // nothing todo
+}
+
+QCLuceneTokenStream::~QCLuceneTokenStream()
+{
+ // nothing todo
+}
+
+void QCLuceneTokenStream::close()
+{
+ d->tokenStream->close();
+}
+
+bool QCLuceneTokenStream::next(QCLuceneToken &token)
+{
+ return d->tokenStream->next(token.d->token);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/fulltextsearch/qtokenstream_p.h b/src/assistant/lib/fulltextsearch/qtokenstream_p.h
new file mode 100644
index 000000000..8f4b9d06a
--- /dev/null
+++ b/src/assistant/lib/fulltextsearch/qtokenstream_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
+** All rights reserved.
+**
+** Portion Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+****************************************************************************/
+
+#ifndef QTOKENSTREAM_P_H
+#define QTOKENSTREAM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtoken_p.h"
+#include "qclucene_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedData>
+
+CL_NS_DEF(analysis)
+ class TokenStream;
+CL_NS_END
+CL_NS_USE(analysis)
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneAnalyzer;
+class QCLuceneTokenizer;
+class QCLuceneStopAnalyzer;
+class QCLuceneSimpleAnalyzer;
+class QCLuceneKeywordAnalyzer;
+class QCLuceneStandardAnalyzer;
+class QCLuceneWhitespaceAnalyzer;
+class QCLucenePerFieldAnalyzerWrapper;
+
+class QHELP_EXPORT QCLuceneTokenStreamPrivate : public QSharedData
+{
+public:
+ QCLuceneTokenStreamPrivate();
+ QCLuceneTokenStreamPrivate(const QCLuceneTokenStreamPrivate &other);
+
+ ~QCLuceneTokenStreamPrivate();
+
+ TokenStream *tokenStream;
+ bool deleteCLuceneTokenStream;
+
+private:
+ QCLuceneTokenStreamPrivate &operator=(const QCLuceneTokenStreamPrivate &other);
+};
+
+class QHELP_EXPORT QCLuceneTokenStream
+{
+public:
+ virtual ~QCLuceneTokenStream();
+
+ void close();
+ bool next(QCLuceneToken &token);
+
+protected:
+ friend class QCLuceneAnalyzer;
+ friend class QCLuceneTokenizer;
+ friend class QCLuceneStopAnalyzer;
+ friend class QCLuceneSimpleAnalyzer;
+ friend class QCLuceneKeywordAnalyzer;
+ friend class QCLuceneStandardAnalyzer;
+ friend class QCLuceneWhitespaceAnalyzer;
+ friend class QCLucenePerFieldAnalyzerWrapper;
+ QSharedDataPointer<QCLuceneTokenStreamPrivate> d;
+
+private:
+ QCLuceneTokenStream();
+};
+
+QT_END_NAMESPACE
+
+#endif // QTOKENSTREAM_P_H
diff --git a/src/assistant/lib/helpsystem.qrc b/src/assistant/lib/helpsystem.qrc
new file mode 100644
index 000000000..10efc6df1
--- /dev/null
+++ b/src/assistant/lib/helpsystem.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/trolltech/assistant" >
+ <file>images/1leftarrow.png</file>
+ <file>images/1rightarrow.png</file>
+ <file>images/3leftarrow.png</file>
+ <file>images/3rightarrow.png</file>
+ </qresource>
+</RCC>
diff --git a/src/assistant/lib/images/1leftarrow.png b/src/assistant/lib/images/1leftarrow.png
new file mode 100644
index 000000000..bd1a5a249
--- /dev/null
+++ b/src/assistant/lib/images/1leftarrow.png
Binary files differ
diff --git a/src/assistant/lib/images/1rightarrow.png b/src/assistant/lib/images/1rightarrow.png
new file mode 100644
index 000000000..0c0c44ae6
--- /dev/null
+++ b/src/assistant/lib/images/1rightarrow.png
Binary files differ
diff --git a/src/assistant/lib/images/3leftarrow.png b/src/assistant/lib/images/3leftarrow.png
new file mode 100644
index 000000000..8d38b0f57
--- /dev/null
+++ b/src/assistant/lib/images/3leftarrow.png
Binary files differ
diff --git a/src/assistant/lib/images/3rightarrow.png b/src/assistant/lib/images/3rightarrow.png
new file mode 100644
index 000000000..c2faf501c
--- /dev/null
+++ b/src/assistant/lib/images/3rightarrow.png
Binary files differ
diff --git a/src/assistant/lib/lib.pro b/src/assistant/lib/lib.pro
new file mode 100644
index 000000000..03821b2a7
--- /dev/null
+++ b/src/assistant/lib/lib.pro
@@ -0,0 +1,71 @@
+QT += sql \
+ xml \
+ network
+TEMPLATE = lib
+TARGET = QtHelp
+DEFINES += QHELP_LIB \
+ QT_CLUCENE_SUPPORT
+CONFIG += qt \
+ warn_on
+include(../../../src/qbase.pri)
+QMAKE_TARGET_PRODUCT = Help
+QMAKE_TARGET_DESCRIPTION = Help \
+ application \
+ framework.
+DEFINES -= QT_ASCII_CAST_WARNINGS
+qclucene = QtCLucene$${QT_LIBINFIX}
+if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
+ mac:qclucene = $${qclucene}_debug
+ win32:qclucene = $${qclucene}d
+}
+linux-lsb-g++:LIBS_PRIVATE += --lsb-shared-libs=$$qclucene
+unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES += QtNetwork \
+ QtSql \
+ QtXml
+LIBS_PRIVATE += -l$$qclucene
+RESOURCES += helpsystem.qrc
+SOURCES += qhelpenginecore.cpp \
+ qhelpengine.cpp \
+ qhelpdbreader.cpp \
+ qhelpcontentwidget.cpp \
+ qhelpindexwidget.cpp \
+ qhelpgenerator.cpp \
+ qhelpdatainterface.cpp \
+ qhelpprojectdata.cpp \
+ qhelpcollectionhandler.cpp \
+ qhelpsearchengine.cpp \
+ qhelpsearchquerywidget.cpp \
+ qhelpsearchresultwidget.cpp \
+ qhelpsearchindex_default.cpp \
+ qhelpsearchindexwriter_default.cpp \
+ qhelpsearchindexreader_default.cpp \
+ qhelpsearchindexreader.cpp \
+ qclucenefieldnames.cpp \
+ qhelp_global.cpp
+
+# access to clucene
+SOURCES += qhelpsearchindexwriter_clucene.cpp \
+ qhelpsearchindexreader_clucene.cpp
+HEADERS += qhelpenginecore.h \
+ qhelpengine.h \
+ qhelpengine_p.h \
+ qhelp_global.h \
+ qhelpdbreader_p.h \
+ qhelpcontentwidget.h \
+ qhelpindexwidget.h \
+ qhelpgenerator_p.h \
+ qhelpdatainterface_p.h \
+ qhelpprojectdata_p.h \
+ qhelpcollectionhandler_p.h \
+ qhelpsearchengine.h \
+ qhelpsearchquerywidget.h \
+ qhelpsearchresultwidget.h \
+ qhelpsearchindex_default_p.h \
+ qhelpsearchindexwriter_default_p.h \
+ qhelpsearchindexreader_default_p.h \
+ qhelpsearchindexreader_p.h \
+ qclucenefieldnames_p.h
+
+# access to clucene
+HEADERS += qhelpsearchindexwriter_clucene_p.h \
+ qhelpsearchindexreader_clucene_p.h
diff --git a/src/assistant/lib/qclucenefieldnames.cpp b/src/assistant/lib/qclucenefieldnames.cpp
new file mode 100644
index 000000000..31ef415af
--- /dev/null
+++ b/src/assistant/lib/qclucenefieldnames.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qclucenefieldnames_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace clucene {
+const QString AttributeField(QLatin1String("attribute"));
+const QString ContentField(QLatin1String("content"));
+const QString NamespaceField(QLatin1String("namespace"));
+const QString PathField(QLatin1String("path"));
+const QString TitleField(QLatin1String("title"));
+const QString TitleTokenizedField(QLatin1String("titleTokenized"));
+} // namespace clucene
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qclucenefieldnames_p.h b/src/assistant/lib/qclucenefieldnames_p.h
new file mode 100644
index 000000000..733e27121
--- /dev/null
+++ b/src/assistant/lib/qclucenefieldnames_p.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLUCENEFIELDNAMES_P_H
+#define QCLUCENEFIELDNAMES_P_H
+
+#include <QtCore/QtGlobal>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace clucene {
+ extern const QString AttributeField;
+ extern const QString ContentField;
+ extern const QString NamespaceField;
+ extern const QString PathField;
+ extern const QString TitleField;
+ extern const QString TitleTokenizedField;
+} // namespace clucene
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
+
+#endif // QCLUCENEFIELDNAMES_P_H
diff --git a/src/assistant/lib/qhelp_global.cpp b/src/assistant/lib/qhelp_global.cpp
new file mode 100644
index 000000000..2c7ca6214
--- /dev/null
+++ b/src/assistant/lib/qhelp_global.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QRegExp>
+#include <QtCore/QMutexLocker>
+#include <QtGui/QTextDocument>
+
+#include "qhelp_global.h"
+
+QString QHelpGlobal::uniquifyConnectionName(const QString &name, void *pointer)
+{
+ static int counter = 0;
+ static QMutex mutex;
+
+ QMutexLocker locker(&mutex);
+ if (++counter > 1000)
+ counter = 0;
+
+ return QString::fromLatin1("%1-%2-%3").
+ arg(name).arg(quintptr(pointer)).arg(counter);
+}
+
+QString QHelpGlobal::documentTitle(const QString &content)
+{
+ QString title = QCoreApplication::translate("QHelp", "Untitled");
+ if (!content.isEmpty()) {
+ int start = content.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7;
+ int end = content.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive);
+ if ((end - start) > 0) {
+ title = content.mid(start, end - start);
+ if (Qt::mightBeRichText(title) || title.contains(QLatin1Char('&'))) {
+ QTextDocument doc;
+ doc.setHtml(title);
+ title = doc.toPlainText();
+ }
+ }
+ }
+ return title;
+}
+
+QString QHelpGlobal::codecFromData(const QByteArray &data)
+{
+ QString codec = codecFromXmlData(data);
+ if (codec.isEmpty())
+ codec = codecFromHtmlData(data);
+ return codec.isEmpty() ? QLatin1String("utf-8") : codec;
+}
+
+QString QHelpGlobal::codecFromHtmlData(const QByteArray &data)
+{
+ QString head = QString::fromUtf8(data.constData(), qMin(1000, data.size()));
+ int start = head.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive);
+ if (start > 0) {
+ QRegExp r(QLatin1String("charset=([^\"\\s]+)"));
+ while (start != -1) {
+ const int end = head.indexOf(QLatin1Char('>'), start) + 1;
+ if (end <= start)
+ break;
+ const QString &meta = head.mid(start, end - start).toLower();
+ if (r.indexIn(meta) != -1)
+ return r.cap(1);
+ start = head.indexOf(QLatin1String("<meta"), end,
+ Qt::CaseInsensitive);
+ }
+ }
+ return QString();
+}
+
+QString QHelpGlobal::codecFromXmlData(const QByteArray &data)
+{
+ QString head = QString::fromUtf8(data.constData(), qMin(1000, data.size()));
+ const QRegExp encodingExp(QLatin1String("^\\s*<\\?xml version="
+ "\"\\d\\.\\d\" encoding=\"([^\"]+)\"\\?>.*"));
+ return encodingExp.exactMatch(head) ? encodingExp.cap(1) : QString();
+}
diff --git a/src/assistant/lib/qhelp_global.h b/src/assistant/lib/qhelp_global.h
new file mode 100644
index 000000000..182298fc2
--- /dev/null
+++ b/src/assistant/lib/qhelp_global.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELP_GLOBAL_H
+#define QHELP_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/QString>
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+#if !defined(QT_SHARED) && !defined(QT_DLL)
+# define QHELP_EXPORT
+#elif defined(QHELP_LIB)
+# define QHELP_EXPORT Q_DECL_EXPORT
+#else
+# define QHELP_EXPORT Q_DECL_IMPORT
+#endif
+
+class QHelpGlobal {
+public:
+ static QString uniquifyConnectionName(const QString &name, void *pointer);
+ static QString documentTitle(const QString &content);
+ static QString codecFromData(const QByteArray &data);
+
+private:
+ static QString codecFromHtmlData(const QByteArray &data);
+ static QString codecFromXmlData(const QByteArray &data);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELP_GLOBAL_H
diff --git a/src/assistant/lib/qhelpcollectionhandler.cpp b/src/assistant/lib/qhelpcollectionhandler.cpp
new file mode 100644
index 000000000..169d37e05
--- /dev/null
+++ b/src/assistant/lib/qhelpcollectionhandler.cpp
@@ -0,0 +1,603 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpcollectionhandler_p.h"
+#include "qhelp_global.h"
+#include "qhelpdbreader_p.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDebug>
+
+#include <QtSql/QSqlError>
+#include <QtSql/QSqlDriver>
+
+QT_BEGIN_NAMESPACE
+
+QHelpCollectionHandler::QHelpCollectionHandler(const QString &collectionFile, QObject *parent)
+ : QObject(parent)
+ , m_dbOpened(false)
+ , m_collectionFile(collectionFile)
+ , m_connectionName(QString())
+{
+ QFileInfo fi(m_collectionFile);
+ if (!fi.isAbsolute())
+ m_collectionFile = fi.absoluteFilePath();
+ m_query.clear();
+}
+
+QHelpCollectionHandler::~QHelpCollectionHandler()
+{
+ m_query.clear();
+ if (m_dbOpened)
+ QSqlDatabase::removeDatabase(m_connectionName);
+}
+
+bool QHelpCollectionHandler::isDBOpened()
+{
+ if (m_dbOpened)
+ return true;
+ emit error(tr("The collection file '%1' is not set up yet!").
+ arg(m_collectionFile));
+ return false;
+}
+
+QString QHelpCollectionHandler::collectionFile() const
+{
+ return m_collectionFile;
+}
+
+bool QHelpCollectionHandler::openCollectionFile()
+{
+ if (m_dbOpened)
+ return m_dbOpened;
+
+ m_connectionName = QHelpGlobal::uniquifyConnectionName(
+ QLatin1String("QHelpCollectionHandler"), this);
+ bool openingOk = true;
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"),
+ m_connectionName);
+ if (db.driver()
+ && db.driver()->lastError().type() == QSqlError::ConnectionError) {
+ emit error(tr("Cannot load sqlite database driver!"));
+ return false;
+ }
+
+ db.setDatabaseName(collectionFile());
+ openingOk = db.open();
+ if (openingOk)
+ m_query = QSqlQuery(db);
+ }
+ if (!openingOk) {
+ QSqlDatabase::removeDatabase(m_connectionName);
+ emit error(tr("Cannot open collection file: %1").arg(collectionFile()));
+ return false;
+ }
+
+ m_query.exec(QLatin1String("PRAGMA synchronous=OFF"));
+ m_query.exec(QLatin1String("PRAGMA cache_size=3000"));
+
+ m_query.exec(QLatin1String("SELECT COUNT(*) FROM sqlite_master WHERE TYPE=\'table\'"
+ "AND Name=\'NamespaceTable\'"));
+ m_query.next();
+ if (m_query.value(0).toInt() < 1) {
+ if (!createTables(&m_query)) {
+ emit error(tr("Cannot create tables in file %1!").arg(collectionFile()));
+ return false;
+ }
+ }
+
+ m_dbOpened = true;
+ return m_dbOpened;
+}
+
+bool QHelpCollectionHandler::copyCollectionFile(const QString &fileName)
+{
+ if (!m_dbOpened)
+ return false;
+
+ QFileInfo fi(fileName);
+ if (fi.exists()) {
+ emit error(tr("The collection file '%1' already exists!").
+ arg(fileName));
+ return false;
+ }
+
+ if (!fi.absoluteDir().exists() && !QDir().mkpath(fi.absolutePath())) {
+ emit error(tr("Cannot create directory: %1").arg(fi.absolutePath()));
+ return false;
+ }
+
+ QString colFile = fi.absoluteFilePath();
+ QString connectionName = QHelpGlobal::uniquifyConnectionName(
+ QLatin1String("QHelpCollectionHandlerCopy"), this);
+ QSqlQuery *copyQuery = 0;
+ bool openingOk = true;
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), connectionName);
+ db.setDatabaseName(colFile);
+ openingOk = db.open();
+ if (openingOk)
+ copyQuery = new QSqlQuery(db);
+ }
+
+ if (!openingOk) {
+ emit error(tr("Cannot open collection file: %1").arg(colFile));
+ return false;
+ }
+
+ copyQuery->exec(QLatin1String("PRAGMA synchronous=OFF"));
+ copyQuery->exec(QLatin1String("PRAGMA cache_size=3000"));
+
+ if (!createTables(copyQuery)) {
+ emit error(tr("Cannot copy collection file: %1").arg(colFile));
+ return false;
+ }
+
+ QString oldBaseDir = QFileInfo(collectionFile()).absolutePath();
+ QString oldFilePath;
+ QFileInfo newColFi(colFile);
+ m_query.exec(QLatin1String("SELECT Name, FilePath FROM NamespaceTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO NamespaceTable VALUES(NULL, ?, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ oldFilePath = m_query.value(1).toString();
+ if (!QDir::isAbsolutePath(oldFilePath))
+ oldFilePath = oldBaseDir + QDir::separator() + oldFilePath;
+ copyQuery->bindValue(1, newColFi.absoluteDir().relativeFilePath(oldFilePath));
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT NamespaceId, Name FROM FolderTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO FolderTable VALUES(NULL, ?, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ copyQuery->bindValue(1, m_query.value(1).toString());
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT Name FROM FilterNameTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO FilterNameTable VALUES(NULL, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT NameId, FilterAttributeId FROM FilterTable"));
+ while (m_query.next()) {
+ copyQuery->prepare(QLatin1String("INSERT INTO FilterTable VALUES(?, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toInt());
+ copyQuery->bindValue(1, m_query.value(1).toInt());
+ copyQuery->exec();
+ }
+
+ m_query.exec(QLatin1String("SELECT Key, Value FROM SettingsTable"));
+ while (m_query.next()) {
+ if (m_query.value(0).toString() == QLatin1String("CluceneSearchNamespaces"))
+ continue;
+ copyQuery->prepare(QLatin1String("INSERT INTO SettingsTable VALUES(?, ?)"));
+ copyQuery->bindValue(0, m_query.value(0).toString());
+ copyQuery->bindValue(1, m_query.value(1));
+ copyQuery->exec();
+ }
+
+ copyQuery->clear();
+ delete copyQuery;
+ QSqlDatabase::removeDatabase(connectionName);
+ return true;
+}
+
+bool QHelpCollectionHandler::createTables(QSqlQuery *query)
+{
+ QStringList tables;
+ tables << QLatin1String("CREATE TABLE NamespaceTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT, "
+ "FilePath TEXT )")
+ << QLatin1String("CREATE TABLE FolderTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "NamespaceId INTEGER, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterAttributeTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterNameTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterTable ("
+ "NameId INTEGER, "
+ "FilterAttributeId INTEGER )")
+ << QLatin1String("CREATE TABLE SettingsTable ("
+ "Key TEXT PRIMARY KEY, "
+ "Value BLOB )");
+
+ foreach (const QString &q, tables) {
+ if (!query->exec(q))
+ return false;
+ }
+ return true;
+}
+
+QStringList QHelpCollectionHandler::customFilters() const
+{
+ QStringList list;
+ if (m_dbOpened) {
+ m_query.exec(QLatin1String("SELECT Name FROM FilterNameTable"));
+ while (m_query.next())
+ list.append(m_query.value(0).toString());
+ }
+ return list;
+}
+
+bool QHelpCollectionHandler::removeCustomFilter(const QString &filterName)
+{
+ if (!isDBOpened() || filterName.isEmpty())
+ return false;
+
+ int filterNameId = -1;
+ m_query.prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
+ m_query.bindValue(0, filterName);
+ m_query.exec();
+ if (m_query.next())
+ filterNameId = m_query.value(0).toInt();
+
+ if (filterNameId < 0) {
+ emit error(tr("Unknown filter '%1'!").arg(filterName));
+ return false;
+ }
+
+ m_query.prepare(QLatin1String("DELETE FROM FilterTable WHERE NameId=?"));
+ m_query.bindValue(0, filterNameId);
+ m_query.exec();
+
+ m_query.prepare(QLatin1String("DELETE FROM FilterNameTable WHERE Id=?"));
+ m_query.bindValue(0, filterNameId);
+ m_query.exec();
+
+ return true;
+}
+
+bool QHelpCollectionHandler::addCustomFilter(const QString &filterName,
+ const QStringList &attributes)
+{
+ if (!isDBOpened() || filterName.isEmpty())
+ return false;
+
+ int nameId = -1;
+ m_query.prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
+ m_query.bindValue(0, filterName);
+ m_query.exec();
+ if (m_query.next())
+ nameId = m_query.value(0).toInt();
+
+ m_query.exec(QLatin1String("SELECT Id, Name FROM FilterAttributeTable"));
+ QStringList idsToInsert = attributes;
+ QMap<QString, int> attributeMap;
+ while (m_query.next()) {
+ attributeMap.insert(m_query.value(1).toString(),
+ m_query.value(0).toInt());
+ if (idsToInsert.contains(m_query.value(1).toString()))
+ idsToInsert.removeAll(m_query.value(1).toString());
+ }
+
+ foreach (const QString &id, idsToInsert) {
+ m_query.prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ m_query.bindValue(0, id);
+ m_query.exec();
+ attributeMap.insert(id, m_query.lastInsertId().toInt());
+ }
+
+ if (nameId < 0) {
+ m_query.prepare(QLatin1String("INSERT INTO FilterNameTable VALUES(NULL, ?)"));
+ m_query.bindValue(0, filterName);
+ if (m_query.exec())
+ nameId = m_query.lastInsertId().toInt();
+ }
+
+ if (nameId < 0) {
+ emit error(tr("Cannot register filter %1!").arg(filterName));
+ return false;
+ }
+
+ m_query.prepare(QLatin1String("DELETE FROM FilterTable WHERE NameId=?"));
+ m_query.bindValue(0, nameId);
+ m_query.exec();
+
+ foreach (const QString &att, attributes) {
+ m_query.prepare(QLatin1String("INSERT INTO FilterTable VALUES(?, ?)"));
+ m_query.bindValue(0, nameId);
+ m_query.bindValue(1, attributeMap[att]);
+ if (!m_query.exec())
+ return false;
+ }
+ return true;
+}
+
+QHelpCollectionHandler::DocInfoList QHelpCollectionHandler::registeredDocumentations() const
+{
+ DocInfoList list;
+ if (m_dbOpened) {
+ m_query.exec(QLatin1String("SELECT a.Name, a.FilePath, b.Name "
+ "FROM NamespaceTable a, FolderTable b WHERE a.Id=b.NamespaceId"));
+
+ while (m_query.next()) {
+ DocInfo info;
+ info.fileName = m_query.value(1).toString();
+ info.folderName = m_query.value(2).toString();
+ info.namespaceName = m_query.value(0).toString();
+ list.append(info);
+ }
+ }
+ return list;
+}
+
+bool QHelpCollectionHandler::registerDocumentation(const QString &fileName)
+{
+ if (!isDBOpened())
+ return false;
+
+ QHelpDBReader reader(fileName, QHelpGlobal::uniquifyConnectionName(
+ QLatin1String("QHelpCollectionHandler"), this), 0);
+ if (!reader.init()) {
+ emit error(tr("Cannot open documentation file %1!").arg(fileName));
+ return false;
+ }
+
+ QString ns = reader.namespaceName();
+ if (ns.isEmpty()) {
+ emit error(tr("Invalid documentation file '%1'!").arg(fileName));
+ return false;
+ }
+
+ int nsId = registerNamespace(ns, fileName);
+ if (nsId < 1)
+ return false;
+
+ if (!registerVirtualFolder(reader.virtualFolder(), nsId))
+ return false;
+
+ addFilterAttributes(reader.filterAttributes());
+ foreach (const QString &filterName, reader.customFilters())
+ addCustomFilter(filterName, reader.filterAttributes(filterName));
+
+ optimizeDatabase(fileName);
+
+ return true;
+}
+
+bool QHelpCollectionHandler::unregisterDocumentation(const QString &namespaceName)
+{
+ if (!isDBOpened())
+ return false;
+
+ m_query.prepare(QLatin1String("SELECT Id FROM NamespaceTable WHERE Name=?"));
+ m_query.bindValue(0, namespaceName);
+ m_query.exec();
+
+ int nsId = -1;
+ if (m_query.next())
+ nsId = m_query.value(0).toInt();
+
+ if (nsId < 0) {
+ emit error(tr("The namespace %1 was not registered!").arg(namespaceName));
+ return false;
+ }
+
+ m_query.prepare(QLatin1String("DELETE FROM NamespaceTable WHERE Id=?"));
+ m_query.bindValue(0, nsId);
+ m_query.exec();
+
+ m_query.prepare(QLatin1String("DELETE FROM FolderTable WHERE NamespaceId=?"));
+ m_query.bindValue(0, nsId);
+ return m_query.exec();
+}
+
+bool QHelpCollectionHandler::removeCustomValue(const QString &key)
+{
+ if (!isDBOpened())
+ return false;
+
+ m_query.prepare(QLatin1String("DELETE FROM SettingsTable WHERE Key=?"));
+ m_query.bindValue(0, key);
+ return m_query.exec();
+}
+
+QVariant QHelpCollectionHandler::customValue(const QString &key,
+ const QVariant &defaultValue) const
+{
+ QVariant value = defaultValue;
+ if (m_dbOpened) {
+ m_query.prepare(QLatin1String("SELECT COUNT(Key) FROM SettingsTable WHERE Key=?"));
+ m_query.bindValue(0, key);
+ if (!m_query.exec() || !m_query.next() || !m_query.value(0).toInt()) {
+ m_query.clear();
+ return defaultValue;
+ }
+
+ m_query.clear();
+ m_query.prepare(QLatin1String("SELECT Value FROM SettingsTable WHERE Key=?"));
+ m_query.bindValue(0, key);
+ if (m_query.exec() && m_query.next())
+ value = m_query.value(0);
+ m_query.clear();
+ }
+ return value;
+}
+
+bool QHelpCollectionHandler::setCustomValue(const QString &key,
+ const QVariant &value)
+{
+ if (!isDBOpened())
+ return false;
+
+ m_query.prepare(QLatin1String("SELECT Value FROM SettingsTable WHERE Key=?"));
+ m_query.bindValue(0, key);
+ m_query.exec();
+ if (m_query.next()) {
+ m_query.prepare(QLatin1String("UPDATE SettingsTable SET Value=? where Key=?"));
+ m_query.bindValue(0, value);
+ m_query.bindValue(1, key);
+ }
+ else {
+ m_query.prepare(QLatin1String("INSERT INTO SettingsTable VALUES(?, ?)"));
+ m_query.bindValue(0, key);
+ m_query.bindValue(1, value);
+ }
+ return m_query.exec();
+}
+
+bool QHelpCollectionHandler::addFilterAttributes(const QStringList &attributes)
+{
+ if (!isDBOpened())
+ return false;
+
+ m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ QSet<QString> atts;
+ while (m_query.next())
+ atts.insert(m_query.value(0).toString());
+
+ foreach (const QString &s, attributes) {
+ if (!atts.contains(s)) {
+ m_query.prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ m_query.bindValue(0, s);
+ m_query.exec();
+ }
+ }
+ return true;
+}
+
+QStringList QHelpCollectionHandler::filterAttributes() const
+{
+ QStringList list;
+ if (m_dbOpened) {
+ m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ while (m_query.next())
+ list.append(m_query.value(0).toString());
+ }
+ return list;
+}
+
+QStringList QHelpCollectionHandler::filterAttributes(const QString &filterName) const
+{
+ QStringList list;
+ if (m_dbOpened) {
+ m_query.prepare(QLatin1String("SELECT a.Name FROM FilterAttributeTable a, "
+ "FilterTable b, FilterNameTable c WHERE a.Id=b.FilterAttributeId "
+ "AND b.NameId=c.Id AND c.Name=?"));
+ m_query.bindValue(0, filterName);
+ m_query.exec();
+ while (m_query.next())
+ list.append(m_query.value(0).toString());
+ }
+ return list;
+}
+
+int QHelpCollectionHandler::registerNamespace(const QString &nspace, const QString &fileName)
+{
+ m_query.prepare(QLatin1String("SELECT COUNT(Id) FROM NamespaceTable WHERE Name=?"));
+ m_query.bindValue(0, nspace);
+ m_query.exec();
+ while (m_query.next()) {
+ if (m_query.value(0).toInt() > 0) {
+ emit error(tr("Namespace %1 already exists!").arg(nspace));
+ return -1;
+ }
+ }
+
+ QFileInfo fi(m_collectionFile);
+ m_query.prepare(QLatin1String("INSERT INTO NamespaceTable VALUES(NULL, ?, ?)"));
+ m_query.bindValue(0, nspace);
+ m_query.bindValue(1, fi.absoluteDir().relativeFilePath(fileName));
+ int namespaceId = -1;
+ if (m_query.exec())
+ namespaceId = m_query.lastInsertId().toInt();
+ if (namespaceId < 1) {
+ emit error(tr("Cannot register namespace '%1'!").arg(nspace));
+ return -1;
+ }
+ return namespaceId;
+}
+
+bool QHelpCollectionHandler::registerVirtualFolder(const QString &folderName, int namespaceId)
+{
+ m_query.prepare(QLatin1String("INSERT INTO FolderTable VALUES(NULL, ?, ?)"));
+ m_query.bindValue(0, namespaceId);
+ m_query.bindValue(1, folderName);
+ return m_query.exec();
+}
+
+void QHelpCollectionHandler::optimizeDatabase(const QString &fileName)
+{
+ if (!QFile::exists(fileName))
+ return;
+
+ { // according to removeDatabase() documentation
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), QLatin1String("optimize"));
+ db.setDatabaseName(fileName);
+ if (!db.open()) {
+ QSqlDatabase::removeDatabase(QLatin1String("optimize"));
+ emit error(tr("Cannot open database '%1' to optimize!").arg(fileName));
+ return;
+ }
+
+ QSqlQuery query(db);
+ db.exec(QLatin1String("PRAGMA synchronous=OFF"));
+ db.exec(QLatin1String("PRAGMA cache_size=3000"));
+ db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS NameIndex ON IndexTable(Name)"));
+ db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS FileNameIndex ON FileNameTable(Name)"));
+ db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS FileIdIndex ON FileNameTable(FileId)"));
+
+ db.close();
+ }
+
+ QSqlDatabase::removeDatabase(QLatin1String("optimize"));
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpcollectionhandler_p.h b/src/assistant/lib/qhelpcollectionhandler_p.h
new file mode 100644
index 000000000..a97af8fa9
--- /dev/null
+++ b/src/assistant/lib/qhelpcollectionhandler_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPCOLLECTIONHANDLER_H
+#define QHELPCOLLECTIONHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+#include <QtCore/QStringList>
+
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpCollectionHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ struct DocInfo
+ {
+ QString fileName;
+ QString folderName;
+ QString namespaceName;
+ };
+ typedef QList<DocInfo> DocInfoList;
+
+ explicit QHelpCollectionHandler(const QString &collectionFile,
+ QObject *parent = 0);
+ ~QHelpCollectionHandler();
+
+ QString collectionFile() const;
+
+ bool openCollectionFile();
+ bool copyCollectionFile(const QString &fileName);
+
+ QStringList customFilters() const;
+ bool removeCustomFilter(const QString &filterName);
+ bool addCustomFilter(const QString &filterName,
+ const QStringList &attributes);
+
+ DocInfoList registeredDocumentations() const;
+ bool registerDocumentation(const QString &fileName);
+ bool unregisterDocumentation(const QString &namespaceName);
+
+ bool removeCustomValue(const QString &key);
+ QVariant customValue(const QString &key, const QVariant &defaultValue) const;
+ bool setCustomValue(const QString &key, const QVariant &value);
+
+ bool addFilterAttributes(const QStringList &attributes);
+ QStringList filterAttributes() const;
+ QStringList filterAttributes(const QString &filterName) const;
+
+ int registerNamespace(const QString &nspace, const QString &fileName);
+ bool registerVirtualFolder(const QString &folderName, int namespaceId);
+ void optimizeDatabase(const QString &fileName);
+
+signals:
+ void error(const QString &msg);
+
+private:
+ bool isDBOpened();
+ bool createTables(QSqlQuery *query);
+
+ bool m_dbOpened;
+ QString m_collectionFile;
+ QString m_connectionName;
+ mutable QSqlQuery m_query;
+};
+
+QT_END_NAMESPACE
+
+#endif //QHELPCOLLECTIONHANDLER_H
diff --git a/src/assistant/lib/qhelpcontentwidget.cpp b/src/assistant/lib/qhelpcontentwidget.cpp
new file mode 100644
index 000000000..988a909e0
--- /dev/null
+++ b/src/assistant/lib/qhelpcontentwidget.cpp
@@ -0,0 +1,586 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpcontentwidget.h"
+#include "qhelpenginecore.h"
+#include "qhelpengine_p.h"
+#include "qhelpdbreader_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QStack>
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtGui/QHeaderView>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpContentItemPrivate
+{
+public:
+ QHelpContentItemPrivate(const QString &t, const QString &l,
+ QHelpDBReader *r, QHelpContentItem *p)
+ {
+ parent = p;
+ title = t;
+ link = l;
+ helpDBReader = r;
+ }
+
+ QList<QHelpContentItem*> childItems;
+ QHelpContentItem *parent;
+ QString title;
+ QString link;
+ QHelpDBReader *helpDBReader;
+};
+
+class QHelpContentProvider : public QThread
+{
+public:
+ QHelpContentProvider(QHelpEnginePrivate *helpEngine);
+ ~QHelpContentProvider();
+ void collectContents(const QString &customFilterName);
+ void stopCollecting();
+ QHelpContentItem *rootItem();
+ int nextChildCount() const;
+
+private:
+ void run();
+
+ QHelpEnginePrivate *m_helpEngine;
+ QHelpContentItem *m_rootItem;
+ QStringList m_filterAttributes;
+ QQueue<QHelpContentItem*> m_rootItems;
+ QMutex m_mutex;
+ bool m_abort;
+};
+
+class QHelpContentModelPrivate
+{
+public:
+ QHelpContentItem *rootItem;
+ QHelpContentProvider *qhelpContentProvider;
+};
+
+
+
+/*!
+ \class QHelpContentItem
+ \inmodule QtHelp
+ \brief The QHelpContentItem class provides an item for use with QHelpContentModel.
+ \since 4.4
+*/
+
+QHelpContentItem::QHelpContentItem(const QString &name, const QString &link,
+ QHelpDBReader *reader, QHelpContentItem *parent)
+{
+ d = new QHelpContentItemPrivate(name, link, reader, parent);
+}
+
+/*!
+ Destroys the help content item.
+*/
+QHelpContentItem::~QHelpContentItem()
+{
+ qDeleteAll(d->childItems);
+ delete d;
+}
+
+void QHelpContentItem::appendChild(QHelpContentItem *item)
+{
+ d->childItems.append(item);
+}
+
+/*!
+ Returns the child of the content item in the give \a row.
+
+ \sa parent()
+*/
+QHelpContentItem *QHelpContentItem::child(int row) const
+{
+ if (row >= childCount())
+ return 0;
+ return d->childItems.value(row);
+}
+
+/*!
+ Returns the number of child items.
+*/
+int QHelpContentItem::childCount() const
+{
+ return d->childItems.count();
+}
+
+/*!
+ Returns the row of this item from its parents view.
+*/
+int QHelpContentItem::row() const
+{
+ if (d->parent)
+ return d->parent->d->childItems.indexOf(const_cast<QHelpContentItem*>(this));
+ return 0;
+}
+
+/*!
+ Returns the title of the content item.
+*/
+QString QHelpContentItem::title() const
+{
+ return d->title;
+}
+
+/*!
+ Returns the URL of this content item.
+*/
+QUrl QHelpContentItem::url() const
+{
+ return d->helpDBReader->urlOfPath(d->link);
+}
+
+/*!
+ Returns the parent content item.
+*/
+QHelpContentItem *QHelpContentItem::parent() const
+{
+ return d->parent;
+}
+
+/*!
+ Returns the position of a given \a child.
+*/
+int QHelpContentItem::childPosition(QHelpContentItem *child) const
+{
+ return d->childItems.indexOf(child);
+}
+
+
+
+QHelpContentProvider::QHelpContentProvider(QHelpEnginePrivate *helpEngine)
+ : QThread(helpEngine)
+{
+ m_helpEngine = helpEngine;
+ m_rootItem = 0;
+ m_abort = false;
+}
+
+QHelpContentProvider::~QHelpContentProvider()
+{
+ stopCollecting();
+}
+
+void QHelpContentProvider::collectContents(const QString &customFilterName)
+{
+ m_mutex.lock();
+ m_filterAttributes = m_helpEngine->q->filterAttributes(customFilterName);
+ m_mutex.unlock();
+ if (!isRunning()) {
+ start(LowPriority);
+ } else {
+ stopCollecting();
+ start(LowPriority);
+ }
+}
+
+void QHelpContentProvider::stopCollecting()
+{
+ if (!isRunning())
+ return;
+ m_mutex.lock();
+ m_abort = true;
+ m_mutex.unlock();
+ wait();
+}
+
+QHelpContentItem *QHelpContentProvider::rootItem()
+{
+ QMutexLocker locker(&m_mutex);
+ return m_rootItems.dequeue();
+}
+
+int QHelpContentProvider::nextChildCount() const
+{
+ return m_rootItems.head()->childCount();
+}
+
+void QHelpContentProvider::run()
+{
+ QString title;
+ QString link;
+ int depth = 0;
+ QHelpContentItem *item = 0;
+
+ m_mutex.lock();
+ m_rootItem = new QHelpContentItem(QString(), QString(), 0);
+ m_rootItems.enqueue(m_rootItem);
+ QStringList atts = m_filterAttributes;
+ const QStringList fileNames = m_helpEngine->orderedFileNameList;
+ m_mutex.unlock();
+
+ foreach (const QString &dbFileName, fileNames) {
+ m_mutex.lock();
+ if (m_abort) {
+ m_abort = false;
+ m_mutex.unlock();
+ break;
+ }
+ m_mutex.unlock();
+ QHelpDBReader reader(dbFileName,
+ QHelpGlobal::uniquifyConnectionName(dbFileName +
+ QLatin1String("FromQHelpContentProvider"),
+ QThread::currentThread()), 0);
+ if (!reader.init())
+ continue;
+ foreach (const QByteArray& ba, reader.contentsForFilter(atts)) {
+ if (ba.size() < 1)
+ continue;
+
+ int _depth = 0;
+ bool _root = false;
+ QStack<QHelpContentItem*> stack;
+
+ QDataStream s(ba);
+ for (;;) {
+ s >> depth;
+ s >> link;
+ s >> title;
+ if (title.isEmpty())
+ break;
+CHECK_DEPTH:
+ if (depth == 0) {
+ m_mutex.lock();
+ item = new QHelpContentItem(title, link,
+ m_helpEngine->fileNameReaderMap.value(dbFileName), m_rootItem);
+ m_rootItem->appendChild(item);
+ m_mutex.unlock();
+ stack.push(item);
+ _depth = 1;
+ _root = true;
+ } else {
+ if (depth > _depth && _root) {
+ _depth = depth;
+ stack.push(item);
+ }
+ if (depth == _depth) {
+ item = new QHelpContentItem(title, link,
+ m_helpEngine->fileNameReaderMap.value(dbFileName), stack.top());
+ stack.top()->appendChild(item);
+ } else if (depth < _depth) {
+ stack.pop();
+ --_depth;
+ goto CHECK_DEPTH;
+ }
+ }
+ }
+ }
+ }
+ m_mutex.lock();
+ m_abort = false;
+ m_mutex.unlock();
+}
+
+
+
+/*!
+ \class QHelpContentModel
+ \inmodule QtHelp
+ \brief The QHelpContentModel class provides a model that supplies content to views.
+ \since 4.4
+*/
+
+/*!
+ \fn void QHelpContentModel::contentsCreationStarted()
+
+ This signal is emitted when the creation of the contents has
+ started. The current contents are invalid from this point on
+ until the signal contentsCreated() is emitted.
+
+ \sa isCreatingContents()
+*/
+
+/*!
+ \fn void QHelpContentModel::contentsCreated()
+
+ This signal is emitted when the contents have been created.
+*/
+
+QHelpContentModel::QHelpContentModel(QHelpEnginePrivate *helpEngine)
+ : QAbstractItemModel(helpEngine)
+{
+ d = new QHelpContentModelPrivate();
+ d->rootItem = 0;
+ d->qhelpContentProvider = new QHelpContentProvider(helpEngine);
+
+ connect(d->qhelpContentProvider, SIGNAL(finished()),
+ this, SLOT(insertContents()), Qt::QueuedConnection);
+ connect(helpEngine->q, SIGNAL(setupStarted()), this, SLOT(invalidateContents()));
+}
+
+/*!
+ Destroys the help content model.
+*/
+QHelpContentModel::~QHelpContentModel()
+{
+ delete d->rootItem;
+ delete d;
+}
+
+void QHelpContentModel::invalidateContents(bool onShutDown)
+{
+ if (onShutDown)
+ disconnect(this, SLOT(insertContents()));
+ d->qhelpContentProvider->stopCollecting();
+ if (d->rootItem) {
+ delete d->rootItem;
+ d->rootItem = 0;
+ }
+ if (!onShutDown)
+ reset();
+}
+
+/*!
+ Creates new contents by querying the help system
+ for contents specified for the \a customFilterName.
+*/
+void QHelpContentModel::createContents(const QString &customFilterName)
+{
+ d->qhelpContentProvider->collectContents(customFilterName);
+ emit contentsCreationStarted();
+}
+
+void QHelpContentModel::insertContents()
+{
+ int count;
+ if (d->rootItem) {
+ count = d->rootItem->childCount() - 1;
+ beginRemoveRows(QModelIndex(), 0, count > 0 ? count : 0);
+ delete d->rootItem;
+ d->rootItem = 0;
+ endRemoveRows();
+ }
+
+ count = d->qhelpContentProvider->nextChildCount() - 1;
+ beginInsertRows(QModelIndex(), 0, count > 0 ? count : 0);
+ d->rootItem = d->qhelpContentProvider->rootItem();
+ endInsertRows();
+ reset();
+ emit contentsCreated();
+}
+
+/*!
+ Returns true if the contents are currently rebuilt, otherwise
+ false.
+*/
+bool QHelpContentModel::isCreatingContents() const
+{
+ return d->qhelpContentProvider->isRunning();
+}
+
+/*!
+ Returns the help content item at the model index position
+ \a index.
+*/
+QHelpContentItem *QHelpContentModel::contentItemAt(const QModelIndex &index) const
+{
+ if (index.isValid())
+ return static_cast<QHelpContentItem*>(index.internalPointer());
+ else
+ return d->rootItem;
+}
+
+/*!
+ Returns the index of the item in the model specified by
+ the given \a row, \a column and \a parent index.
+*/
+QModelIndex QHelpContentModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (!d->rootItem)
+ return QModelIndex();
+
+ QHelpContentItem *parentItem = contentItemAt(parent);
+ QHelpContentItem *item = parentItem->child(row);
+ if (!item)
+ return QModelIndex();
+ return createIndex(row, column, item);
+}
+
+/*!
+ Returns the parent of the model item with the given
+ \a index, or QModelIndex() if it has no parent.
+*/
+QModelIndex QHelpContentModel::parent(const QModelIndex &index) const
+{
+ QHelpContentItem *item = contentItemAt(index);
+ if (!item)
+ return QModelIndex();
+
+ QHelpContentItem *parentItem = static_cast<QHelpContentItem*>(item->parent());
+ if (!parentItem)
+ return QModelIndex();
+
+ QHelpContentItem *grandparentItem = static_cast<QHelpContentItem*>(parentItem->parent());
+ if (!grandparentItem)
+ return QModelIndex();
+
+ int row = grandparentItem->childPosition(parentItem);
+ return createIndex(row, index.column(), parentItem);
+}
+
+/*!
+ Returns the number of rows under the given \a parent.
+*/
+int QHelpContentModel::rowCount(const QModelIndex &parent) const
+{
+ QHelpContentItem *parentItem = contentItemAt(parent);
+ if (!parentItem)
+ return 0;
+ return parentItem->childCount();
+}
+
+/*!
+ Returns the number of columns under the given \a parent. Currently returns always 1.
+*/
+int QHelpContentModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent)
+
+ return 1;
+}
+
+/*!
+ Returns the data stored under the given \a role for
+ the item referred to by the \a index.
+*/
+QVariant QHelpContentModel::data(const QModelIndex &index, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ QHelpContentItem *item = contentItemAt(index);
+ if (!item)
+ return QVariant();
+ return item->title();
+}
+
+
+
+/*!
+ \class QHelpContentWidget
+ \inmodule QtHelp
+ \brief The QHelpContentWidget class provides a tree view for displaying help content model items.
+ \since 4.4
+*/
+
+/*!
+ \fn void QHelpContentWidget::linkActivated(const QUrl &link)
+
+ This signal is emitted when a content item is activated and
+ its associated \a link should be shown.
+*/
+
+QHelpContentWidget::QHelpContentWidget()
+ : QTreeView(0)
+{
+ header()->hide();
+ setUniformRowHeights(true);
+ connect(this, SIGNAL(activated(QModelIndex)),
+ this, SLOT(showLink(QModelIndex)));
+}
+
+/*!
+ Returns the index of the content item with the \a link.
+ An invalid index is returned if no such an item exists.
+*/
+QModelIndex QHelpContentWidget::indexOf(const QUrl &link)
+{
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(model());
+ if (!contentModel || link.scheme() != QLatin1String("qthelp"))
+ return QModelIndex();
+
+ m_syncIndex = QModelIndex();
+ for (int i=0; i<contentModel->rowCount(); ++i) {
+ QHelpContentItem *itm =
+ contentModel->contentItemAt(contentModel->index(i, 0));
+ if (itm && itm->url().host() == link.host()) {
+ QString path = link.path();
+ if (path.startsWith(QLatin1Char('/')))
+ path = path.mid(1);
+ if (searchContentItem(contentModel, contentModel->index(i, 0), path)) {
+ return m_syncIndex;
+ }
+ }
+ }
+ return QModelIndex();
+}
+
+bool QHelpContentWidget::searchContentItem(QHelpContentModel *model,
+ const QModelIndex &parent, const QString &path)
+{
+ QHelpContentItem *parentItem = model->contentItemAt(parent);
+ if (!parentItem)
+ return false;
+
+ if (QDir::cleanPath(parentItem->url().path()) == path) {
+ m_syncIndex = parent;
+ return true;
+ }
+
+ for (int i=0; i<parentItem->childCount(); ++i) {
+ if (searchContentItem(model, model->index(i, 0, parent), path))
+ return true;
+ }
+ return false;
+}
+
+void QHelpContentWidget::showLink(const QModelIndex &index)
+{
+ QHelpContentModel *contentModel = qobject_cast<QHelpContentModel*>(model());
+ if (!contentModel)
+ return;
+
+ QHelpContentItem *item = contentModel->contentItemAt(index);
+ if (!item)
+ return;
+ QUrl url = item->url();
+ if (url.isValid())
+ emit linkActivated(url);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpcontentwidget.h b/src/assistant/lib/qhelpcontentwidget.h
new file mode 100644
index 000000000..0e7567e20
--- /dev/null
+++ b/src/assistant/lib/qhelpcontentwidget.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPCONTENTWIDGET_H
+#define QHELPCONTENTWIDGET_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QQueue>
+#include <QtCore/QString>
+#include <QtGui/QTreeView>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpEnginePrivate;
+class QHelpDBReader;
+class QHelpContentItemPrivate;
+class QHelpContentModelPrivate;
+class QHelpEngine;
+class QHelpContentProvider;
+
+class QHELP_EXPORT QHelpContentItem
+{
+public:
+ ~QHelpContentItem();
+
+ QHelpContentItem *child(int row) const;
+ int childCount() const;
+ QString title() const;
+ QUrl url() const;
+ int row() const;
+ QHelpContentItem *parent() const;
+ int childPosition(QHelpContentItem *child) const;
+
+private:
+ QHelpContentItem(const QString &name, const QString &link,
+ QHelpDBReader *reader, QHelpContentItem *parent = 0);
+ void appendChild(QHelpContentItem *child);
+
+ QHelpContentItemPrivate *d;
+ friend class QHelpContentProvider;
+};
+
+class QHELP_EXPORT QHelpContentModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ ~QHelpContentModel();
+
+ void createContents(const QString &customFilterName);
+ QHelpContentItem *contentItemAt(const QModelIndex &index) const;
+
+ QVariant data(const QModelIndex &index, int role) const;
+ QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &index) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ bool isCreatingContents() const;
+
+Q_SIGNALS:
+ void contentsCreationStarted();
+ void contentsCreated();
+
+private Q_SLOTS:
+ void insertContents();
+ void invalidateContents(bool onShutDown = false);
+
+private:
+ QHelpContentModel(QHelpEnginePrivate *helpEngine);
+ QHelpContentModelPrivate *d;
+ friend class QHelpEnginePrivate;
+};
+
+class QHELP_EXPORT QHelpContentWidget : public QTreeView
+{
+ Q_OBJECT
+
+public:
+ QModelIndex indexOf(const QUrl &link);
+
+Q_SIGNALS:
+ void linkActivated(const QUrl &link);
+
+private Q_SLOTS:
+ void showLink(const QModelIndex &index);
+
+private:
+ bool searchContentItem(QHelpContentModel *model,
+ const QModelIndex &parent, const QString &path);
+ QModelIndex m_syncIndex;
+
+private:
+ QHelpContentWidget();
+ friend class QHelpEngine;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/assistant/lib/qhelpdatainterface.cpp b/src/assistant/lib/qhelpdatainterface.cpp
new file mode 100644
index 000000000..d3f07c756
--- /dev/null
+++ b/src/assistant/lib/qhelpdatainterface.cpp
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpdatainterface_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QHelpDataContentItem
+ \since 4.4
+ \brief The QHelpDataContentItem class provides an item which represents
+ a topic or section of the contents.
+
+ Every item holds several pieces of information, most notably the title
+ which can later be displayed in a contents overview. The reference is used
+ to store a relative file link to the corresponding section in the
+ documentation.
+*/
+
+/*!
+ Constructs a new content item with \a parent as parent item.
+ The constucted item has the title \a title and links to the
+ location specified by \a reference.
+*/
+QHelpDataContentItem::QHelpDataContentItem(QHelpDataContentItem *parent,
+ const QString &title, const QString &reference)
+ : m_title(title), m_reference(reference)
+{
+ if (parent)
+ parent->m_children.append(this);
+}
+
+/*!
+ Destructs the item and its children.
+*/
+QHelpDataContentItem::~QHelpDataContentItem()
+{
+ qDeleteAll(m_children);
+}
+
+/*!
+ Returns the title of the item.
+*/
+QString QHelpDataContentItem::title() const
+{
+ return m_title;
+}
+
+/*!
+ Returns the file reference of the item.
+*/
+QString QHelpDataContentItem::reference() const
+{
+ return m_reference;
+}
+
+/*!
+ Returns a list of all its child items.
+*/
+QList<QHelpDataContentItem*> QHelpDataContentItem::children() const
+{
+ return m_children;
+}
+
+bool QHelpDataIndexItem::operator==(const QHelpDataIndexItem & other) const
+{
+ return (other.name == name)
+ && (other.reference == reference);
+}
+
+
+
+/*!
+ \internal
+ \class QHelpDataFilterSection
+ \since 4.4
+*/
+
+/*!
+ Constructs a help data filter section.
+*/
+QHelpDataFilterSection::QHelpDataFilterSection()
+{
+ d = new QHelpDataFilterSectionData();
+}
+
+/*!
+ Adds the filter attribute \a filter to the filter attributes of
+ this section.
+*/
+void QHelpDataFilterSection::addFilterAttribute(const QString &filter)
+{
+ d->filterAttributes.append(filter);
+}
+
+/*!
+ Returns a list of all filter attributes defined for this section.
+*/
+QStringList QHelpDataFilterSection::filterAttributes() const
+{
+ return d->filterAttributes;
+}
+
+/*!
+ Adds the index item \a index to the list of indices.
+*/
+void QHelpDataFilterSection::addIndex(const QHelpDataIndexItem &index)
+{
+ d->indices.append(index);
+}
+
+/*!
+ Sets the filter sections list of indices to \a indices.
+*/
+void QHelpDataFilterSection::setIndices(const QList<QHelpDataIndexItem> &indices)
+{
+ d->indices = indices;
+}
+
+/*!
+ Returns the list of indices.
+*/
+QList<QHelpDataIndexItem> QHelpDataFilterSection::indices() const
+{
+ return d->indices;
+}
+
+/*!
+ Adds the top level content item \a content to the filter section.
+*/
+void QHelpDataFilterSection::addContent(QHelpDataContentItem *content)
+{
+ d->contents.append(content);
+}
+
+/*!
+ Sets the list of top level content items of the filter section to
+ \a contents.
+*/
+void QHelpDataFilterSection::setContents(const QList<QHelpDataContentItem*> &contents)
+{
+ qDeleteAll(d->contents);
+ d->contents = contents;
+}
+
+/*!
+ Returns a list of top level content items.
+*/
+QList<QHelpDataContentItem*> QHelpDataFilterSection::contents() const
+{
+ return d->contents;
+}
+
+/*!
+ Adds the file \a file to the filter section.
+*/
+void QHelpDataFilterSection::addFile(const QString &file)
+{
+ d->files.append(file);
+}
+
+/*!
+ Set the list of files to \a files.
+*/
+void QHelpDataFilterSection::setFiles(const QStringList &files)
+{
+ d->files = files;
+}
+
+/*!
+ Returns the list of files.
+*/
+QStringList QHelpDataFilterSection::files() const
+{
+ return d->files;
+}
+
+/*!
+ \internal
+ \class QHelpDataInterface
+ \since 4.4
+*/
+
+/*!
+ \fn QHelpDataInterface::QHelpDataInterface()
+
+ Constructs a new help data interface.
+*/
+
+/*!
+ \fn QHelpDataInterface::~QHelpDataInterface()
+
+ Destroys the help data interface.
+*/
+
+/*!
+ \fn QString QHelpDataInterface::namespaceName() const = 0
+
+ Returns the namespace name of the help data set.
+*/
+
+/*!
+ \fn QString QHelpDataInterface::virtualFolder() const = 0
+
+ Returns the virtual folder of the help data set.
+*/
+
+/*!
+ \fn QList<QHelpDataCustomFilter> QHelpDataInterface::customFilters () const = 0
+
+ Returns a list of custom filters. Defining custom filters is optional.
+*/
+
+/*!
+ \fn QList<QHelpDataFilterSection> QHelpDataInterface::filterSections() const = 0
+
+ Returns a list of filter sections.
+*/
+
+/*!
+ \fn QMap<QString, QVariant> QHelpDataInterface::metaData() const = 0
+
+ Returns a map of meta data. A meta data item can hold almost any data
+ and is identified by its name.
+*/
+
+/*!
+ \fn QString QHelpDataInterface::rootPath() const = 0
+
+ Returns the root file path of the documentation data. All referenced file
+ path or links of content items are relative to this path.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpdatainterface_p.h b/src/assistant/lib/qhelpdatainterface_p.h
new file mode 100644
index 000000000..886d68650
--- /dev/null
+++ b/src/assistant/lib/qhelpdatainterface_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPDATAINTERFACE_H
+#define QHELPDATAINTERFACE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelp_global.h"
+
+#include <QtCore/QStringList>
+#include <QtCore/QSharedData>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QHELP_EXPORT QHelpDataContentItem
+{
+public:
+ QHelpDataContentItem(QHelpDataContentItem *parent, const QString &title,
+ const QString &reference);
+ ~QHelpDataContentItem();
+
+ QString title() const;
+ QString reference() const;
+ QList<QHelpDataContentItem*> children() const;
+
+private:
+ QString m_title;
+ QString m_reference;
+ QList<QHelpDataContentItem*> m_children;
+};
+
+struct QHELP_EXPORT QHelpDataIndexItem {
+ QHelpDataIndexItem() {}
+ QHelpDataIndexItem(const QString &n, const QString &id, const QString &r)
+ : name(n), identifier(id), reference(r) {}
+
+ QString name;
+ QString identifier;
+ QString reference;
+
+ bool operator==(const QHelpDataIndexItem & other) const;
+};
+
+class QHelpDataFilterSectionData : public QSharedData
+{
+public:
+ ~QHelpDataFilterSectionData()
+ {
+ qDeleteAll(contents);
+ }
+
+ QStringList filterAttributes;
+ QList<QHelpDataIndexItem> indices;
+ QList<QHelpDataContentItem*> contents;
+ QStringList files;
+};
+
+class QHELP_EXPORT QHelpDataFilterSection
+{
+public:
+ QHelpDataFilterSection();
+
+ void addFilterAttribute(const QString &filter);
+ QStringList filterAttributes() const;
+
+ void addIndex(const QHelpDataIndexItem &index);
+ void setIndices(const QList<QHelpDataIndexItem> &indices);
+ QList<QHelpDataIndexItem> indices() const;
+
+ void addContent(QHelpDataContentItem *content);
+ void setContents(const QList<QHelpDataContentItem*> &contents);
+ QList<QHelpDataContentItem*> contents() const;
+
+ void addFile(const QString &file);
+ void setFiles(const QStringList &files);
+ QStringList files() const;
+
+private:
+ QSharedDataPointer<QHelpDataFilterSectionData> d;
+};
+
+struct QHELP_EXPORT QHelpDataCustomFilter {
+ QStringList filterAttributes;
+ QString name;
+};
+
+class QHELP_EXPORT QHelpDataInterface
+{
+public:
+ QHelpDataInterface() {}
+ virtual ~QHelpDataInterface() {}
+
+ virtual QString namespaceName() const = 0;
+ virtual QString virtualFolder() const = 0;
+ virtual QList<QHelpDataCustomFilter> customFilters() const = 0;
+ virtual QList<QHelpDataFilterSection> filterSections() const = 0;
+ virtual QMap<QString, QVariant> metaData() const = 0;
+ virtual QString rootPath() const = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPDATAINTERFACE_H
diff --git a/src/assistant/lib/qhelpdbreader.cpp b/src/assistant/lib/qhelpdbreader.cpp
new file mode 100644
index 000000000..c4735f8b8
--- /dev/null
+++ b/src/assistant/lib/qhelpdbreader.cpp
@@ -0,0 +1,583 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpdbreader_p.h"
+#include "qhelp_global.h"
+
+#include <QtCore/QVariant>
+#include <QtCore/QFile>
+#include <QtSql/QSqlError>
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+QHelpDBReader::QHelpDBReader(const QString &dbName)
+ : QObject(0)
+{
+ initObject(dbName,
+ QHelpGlobal::uniquifyConnectionName(QLatin1String("QHelpDBReader"),
+ this));
+}
+
+QHelpDBReader::QHelpDBReader(const QString &dbName, const QString &uniqueId,
+ QObject *parent)
+ : QObject(parent)
+{
+ initObject(dbName, uniqueId);
+}
+
+void QHelpDBReader::initObject(const QString &dbName, const QString &uniqueId)
+{
+ m_dbName = dbName;
+ m_uniqueId = uniqueId;
+ m_initDone = false;
+ m_query = 0;
+ m_useAttributesCache = false;
+}
+
+QHelpDBReader::~QHelpDBReader()
+{
+ if (m_initDone) {
+ delete m_query;
+ QSqlDatabase::removeDatabase(m_uniqueId);
+ }
+}
+
+bool QHelpDBReader::init()
+{
+ if (m_initDone)
+ return true;
+
+ if (!QFile::exists(m_dbName))
+ return false;
+
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), m_uniqueId);
+ db.setDatabaseName(m_dbName);
+ if (!db.open()) {
+ /*: The placeholders are: %1 - The name of the database which cannot be opened
+ %2 - The unique id for the connection
+ %3 - The actual error string */
+ m_error = tr("Cannot open database '%1' '%2': %3").arg(m_dbName, m_uniqueId, db.lastError().text());
+ QSqlDatabase::removeDatabase(m_uniqueId);
+ return false;
+ }
+
+ m_initDone = true;
+ m_query = new QSqlQuery(db);
+
+ return true;
+}
+
+QString QHelpDBReader::databaseName() const
+{
+ return m_dbName;
+}
+
+QString QHelpDBReader::errorMessage() const
+{
+ return m_error;
+}
+
+QString QHelpDBReader::namespaceName() const
+{
+ if (!m_namespace.isEmpty())
+ return m_namespace;
+ if (m_query) {
+ m_query->exec(QLatin1String("SELECT Name FROM NamespaceTable"));
+ if (m_query->next())
+ m_namespace = m_query->value(0).toString();
+ }
+ return m_namespace;
+}
+
+QString QHelpDBReader::virtualFolder() const
+{
+ if (m_query) {
+ m_query->exec(QLatin1String("SELECT Name FROM FolderTable WHERE Id=1"));
+ if (m_query->next())
+ return m_query->value(0).toString();
+ }
+ return QString();
+}
+
+QList<QStringList> QHelpDBReader::filterAttributeSets() const
+{
+ QList<QStringList> result;
+ if (m_query) {
+ m_query->exec(QLatin1String("SELECT a.Id, b.Name FROM FileAttributeSetTable a, "
+ "FilterAttributeTable b WHERE a.FilterAttributeId=b.Id ORDER BY a.Id"));
+ int oldId = -1;
+ while (m_query->next()) {
+ int id = m_query->value(0).toInt();
+ if (id != oldId) {
+ result.append(QStringList());
+ oldId = id;
+ }
+ result.last().append(m_query->value(1).toString());
+ }
+ }
+ return result;
+}
+
+bool QHelpDBReader::fileExists(const QString &virtualFolder,
+ const QString &filePath,
+ const QStringList &filterAttributes) const
+{
+ if (virtualFolder.isEmpty() || filePath.isEmpty() || !m_query)
+ return false;
+
+//SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b, FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id AND b.Name='qtdoc' AND a.Name='qstring.html' AND a.FileId=c.FileId AND c.FilterAttributeId=d.Id AND d.Name='qtrefdoc'
+
+ QString query;
+ namespaceName();
+ if (filterAttributes.isEmpty()) {
+ query = QString(QLatin1String("SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b "
+ "WHERE a.FolderId=b.Id AND b.Name=\'%1\' AND a.Name=\'%2\'")).arg(quote(virtualFolder)).arg(quote(filePath));
+ } else {
+ query = QString(QLatin1String("SELECT COUNT(a.Name) FROM FileNameTable a, FolderTable b, "
+ "FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id "
+ "AND b.Name=\'%1\' AND a.Name=\'%2\' AND a.FileId=c.FileId AND "
+ "c.FilterAttributeId=d.Id AND d.Name=\'%3\'"))
+ .arg(quote(virtualFolder)).arg(quote(filePath))
+ .arg(quote(filterAttributes.first()));
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT COUNT(a.Name) FROM FileNameTable a, "
+ "FolderTable b, FileFilterTable c, FilterAttributeTable d WHERE a.FolderId=b.Id "
+ "AND b.Name=\'%1\' AND a.Name=\'%2\' AND a.FileId=c.FileId AND "
+ "c.FilterAttributeId=d.Id AND d.Name=\'%3\'"))
+ .arg(quote(virtualFolder)).arg(quote(filePath))
+ .arg(quote(filterAttributes.at(i))));
+ }
+ }
+ m_query->exec(query);
+ if (m_query->next() && m_query->isValid() && m_query->value(0).toInt())
+ return true;
+ return false;
+}
+
+QByteArray QHelpDBReader::fileData(const QString &virtualFolder,
+ const QString &filePath) const
+{
+ QByteArray ba;
+ if (virtualFolder.isEmpty() || filePath.isEmpty() || !m_query)
+ return ba;
+
+ namespaceName();
+ m_query->prepare(QLatin1String("SELECT a.Data FROM FileDataTable a, FileNameTable b, FolderTable c, "
+ "NamespaceTable d WHERE a.Id=b.FileId AND (b.Name=? OR b.Name=?) AND b.FolderId=c.Id "
+ "AND c.Name=? AND c.NamespaceId=d.Id AND d.Name=?"));
+ m_query->bindValue(0, filePath);
+ m_query->bindValue(1, QString(QLatin1String("./") + filePath));
+ m_query->bindValue(2, virtualFolder);
+ m_query->bindValue(3, m_namespace);
+ m_query->exec();
+ if (m_query->next() && m_query->isValid())
+ ba = qUncompress(m_query->value(0).toByteArray());
+ return ba;
+}
+
+QStringList QHelpDBReader::customFilters() const
+{
+ QStringList lst;
+ if (m_query) {
+ m_query->exec(QLatin1String("SELECT Name FROM FilterNameTable"));
+ while (m_query->next())
+ lst.append(m_query->value(0).toString());
+ }
+ return lst;
+}
+
+QStringList QHelpDBReader::filterAttributes(const QString &filterName) const
+{
+ QStringList lst;
+ if (m_query) {
+ if (filterName.isEmpty()) {
+ m_query->prepare(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ } else {
+ m_query->prepare(QLatin1String("SELECT a.Name FROM FilterAttributeTable a, "
+ "FilterTable b, FilterNameTable c WHERE c.Name=? "
+ "AND c.Id=b.NameId AND b.FilterAttributeId=a.Id"));
+ m_query->bindValue(0, filterName);
+ }
+ m_query->exec();
+ while (m_query->next())
+ lst.append(m_query->value(0).toString());
+ }
+ return lst;
+}
+
+QStringList QHelpDBReader::indicesForFilter(const QStringList &filterAttributes) const
+{
+ QStringList indices;
+ if (!m_query)
+ return indices;
+
+ //SELECT DISTINCT a.Name FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId AND b.FilterAttributeId=c.Id AND c.Name in ('4.2.3', 'qt')
+
+ QString query;
+ if (filterAttributes.isEmpty()) {
+ query = QLatin1String("SELECT DISTINCT Name FROM IndexTable");
+ } else {
+ query = QString(QLatin1String("SELECT DISTINCT a.Name FROM IndexTable a, "
+ "IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId "
+ "AND b.FilterAttributeId=c.Id AND c.Name='%1'")).arg(quote(filterAttributes.first()));
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT DISTINCT a.Name FROM IndexTable a, "
+ "IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId "
+ "AND b.FilterAttributeId=c.Id AND c.Name='%1'"))
+ .arg(quote(filterAttributes.at(i))));
+ }
+ }
+
+ m_query->exec(query);
+ while (m_query->next()) {
+ if (!m_query->value(0).toString().isEmpty())
+ indices.append(m_query->value(0).toString());
+ }
+ return indices;
+}
+
+void QHelpDBReader::linksForKeyword(const QString &keyword, const QStringList &filterAttributes,
+ QMap<QString, QUrl> &linkMap) const
+{
+ if (!m_query)
+ return;
+
+ QString query;
+ if (filterAttributes.isEmpty()) {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, FileNameTable d, "
+ "FolderTable e, NamespaceTable f WHERE "
+ "a.FileId=d.FileId AND d.FolderId=e.Id AND a.NamespaceId=f.Id "
+ "AND a.Name='%1'")).arg(quote(keyword));
+ } else if (m_useAttributesCache) {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor, a.Id "
+ "FROM IndexTable a, "
+ "FileNameTable d, FolderTable e, NamespaceTable f WHERE "
+ "a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND a.Name='%1'"))
+ .arg(quote(keyword));
+ m_query->exec(query);
+ while (m_query->next()) {
+ if (m_indicesCache.contains(m_query->value(5).toInt())) {
+ linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(), m_query->value(3).toString(),
+ m_query->value(4).toString()));
+ }
+ }
+ return;
+ } else {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, "
+ "FileNameTable d, FolderTable e, NamespaceTable f "
+ "WHERE a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id "
+ "AND a.Name='%1' AND c.Name='%2'")).arg(quote(keyword))
+ .arg(quote(filterAttributes.first()));
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, "
+ "FileNameTable d, FolderTable e, NamespaceTable f "
+ "WHERE a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id "
+ "AND a.Name='%1' AND c.Name='%2'")).arg(quote(keyword))
+ .arg(quote(filterAttributes.at(i))));
+ }
+ }
+
+ QString title;
+ m_query->exec(query);
+ while (m_query->next()) {
+ title = m_query->value(0).toString();
+ if (title.isEmpty()) // generate a title + corresponding path
+ title = keyword + QLatin1String(" : ") + m_query->value(3).toString();
+ linkMap.insertMulti(title, buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(), m_query->value(3).toString(),
+ m_query->value(4).toString()));
+ }
+}
+
+void QHelpDBReader::linksForIdentifier(const QString &id,
+ const QStringList &filterAttributes,
+ QMap<QString, QUrl> &linkMap) const
+{
+ if (!m_query)
+ return;
+
+ QString query;
+ if (filterAttributes.isEmpty()) {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, FileNameTable d, FolderTable e, "
+ "NamespaceTable f WHERE a.FileId=d.FileId AND "
+ "d.FolderId=e.Id AND a.NamespaceId=f.Id AND a.Identifier='%1'"))
+ .arg(quote(id));
+ } else if (m_useAttributesCache) {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor, a.Id "
+ "FROM IndexTable a,"
+ "FileNameTable d, FolderTable e, NamespaceTable f WHERE "
+ "a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND a.Identifier='%1'"))
+ .arg(quote(id));
+ m_query->exec(query);
+ while (m_query->next()) {
+ if (m_indicesCache.contains(m_query->value(5).toInt())) {
+ linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(), m_query->value(3).toString(),
+ m_query->value(4).toString()));
+ }
+ }
+ return;
+ } else {
+ query = QString(QLatin1String("SELECT d.Title, f.Name, e.Name, d.Name, a.Anchor "
+ "FROM IndexTable a, IndexFilterTable b, FilterAttributeTable c, "
+ "FileNameTable d, FolderTable e, NamespaceTable f "
+ "WHERE a.FileId=d.FileId AND d.FolderId=e.Id "
+ "AND a.NamespaceId=f.Id AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id "
+ "AND a.Identifier='%1' AND c.Name='%2'")).arg(quote(id))
+ .arg(quote(filterAttributes.first()));
+ for (int i=0; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT d.Title, f.Name, e.Name, "
+ "d.Name, a.Anchor FROM IndexTable a, IndexFilterTable b, "
+ "FilterAttributeTable c, FileNameTable d, "
+ "FolderTable e, NamespaceTable f WHERE "
+ "a.FileId=d.FileId AND d.FolderId=e.Id AND a.NamespaceId=f.Id "
+ "AND b.IndexId=a.Id AND b.FilterAttributeId=c.Id AND "
+ "a.Identifier='%1' AND c.Name='%2'")).arg(quote(id))
+ .arg(quote(filterAttributes.at(i))));
+ }
+ }
+
+ m_query->exec(query);
+ while (m_query->next()) {
+ linkMap.insertMulti(m_query->value(0).toString(), buildQUrl(m_query->value(1).toString(),
+ m_query->value(2).toString(), m_query->value(3).toString(),
+ m_query->value(4).toString()));
+ }
+}
+
+QUrl QHelpDBReader::buildQUrl(const QString &ns, const QString &folder,
+ const QString &relFileName, const QString &anchor) const
+{
+ QUrl url;
+ url.setScheme(QLatin1String("qthelp"));
+ url.setAuthority(ns);
+ url.setPath(folder + QLatin1Char('/') + relFileName);
+ url.setFragment(anchor);
+ return url;
+}
+
+QList<QByteArray> QHelpDBReader::contentsForFilter(const QStringList &filterAttributes) const
+{
+ QList<QByteArray> contents;
+ if (!m_query)
+ return contents;
+
+ //SELECT DISTINCT a.Data FROM ContentsTable a, ContentsFilterTable b, FilterAttributeTable c WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id AND c.Name='qt' INTERSECT SELECT DISTINCT a.Data FROM ContentsTable a, ContentsFilterTable b, FilterAttributeTable c WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id AND c.Name='3.3.8';
+
+ QString query;
+ if (filterAttributes.isEmpty()) {
+ query = QLatin1String("SELECT Data from ContentsTable");
+ } else {
+ query = QString(QLatin1String("SELECT a.Data FROM ContentsTable a, "
+ "ContentsFilterTable b, FilterAttributeTable c "
+ "WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id "
+ "AND c.Name='%1'")).arg(quote(filterAttributes.first()));
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT a.Data FROM ContentsTable a, "
+ "ContentsFilterTable b, FilterAttributeTable c "
+ "WHERE a.Id=b.ContentsId AND b.FilterAttributeId=c.Id "
+ "AND c.Name='%1'")).arg(quote(filterAttributes.at(i))));
+ }
+ }
+
+ m_query->exec(query);
+ while (m_query->next()) {
+ contents.append(m_query->value(0).toByteArray());
+ }
+ return contents;
+}
+
+QUrl QHelpDBReader::urlOfPath(const QString &relativePath) const
+{
+ QUrl url;
+ if (!m_query)
+ return url;
+
+ m_query->exec(QLatin1String("SELECT a.Name, b.Name FROM NamespaceTable a, "
+ "FolderTable b WHERE a.id=b.NamespaceId and a.Id=1"));
+ if (m_query->next()) {
+ QString rp = relativePath;
+ QString anchor;
+ int i = rp.indexOf(QLatin1Char('#'));
+ if (i > -1) {
+ rp = relativePath.left(i);
+ anchor = relativePath.mid(i+1);
+ }
+ url = buildQUrl(m_query->value(0).toString(),
+ m_query->value(1).toString(), rp, anchor);
+ }
+ return url;
+}
+
+QStringList QHelpDBReader::files(const QStringList &filterAttributes,
+ const QString &extensionFilter) const
+{
+ QStringList lst;
+ if (!m_query)
+ return lst;
+
+ QString query;
+ QString extension;
+ if (!extensionFilter.isEmpty())
+ extension = QString(QLatin1String("AND b.Name like \'%.%1\'")).arg(extensionFilter);
+
+ if (filterAttributes.isEmpty()) {
+ query = QString(QLatin1String("SELECT a.Name, b.Name FROM FolderTable a, "
+ "FileNameTable b WHERE b.FolderId=a.Id %1"))
+ .arg(extension);
+ } else {
+ query = QString(QLatin1String("SELECT a.Name, b.Name FROM FolderTable a, "
+ "FileNameTable b, FileFilterTable c, FilterAttributeTable d "
+ "WHERE b.FolderId=a.Id AND b.FileId=c.FileId "
+ "AND c.FilterAttributeId=d.Id AND d.Name=\'%1\' %2"))
+ .arg(quote(filterAttributes.first())).arg(extension);
+ for (int i=1; i<filterAttributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT a.Name, b.Name FROM "
+ "FolderTable a, FileNameTable b, FileFilterTable c, "
+ "FilterAttributeTable d WHERE b.FolderId=a.Id AND "
+ "b.FileId=c.FileId AND c.FilterAttributeId=d.Id AND "
+ "d.Name=\'%1\' %2")).arg(quote(filterAttributes.at(i)))
+ .arg(extension));
+ }
+ }
+ m_query->exec(query);
+ while (m_query->next()) {
+ lst.append(m_query->value(0).toString() + QLatin1Char('/')
+ + m_query->value(1).toString());
+ }
+
+ return lst;
+}
+
+QVariant QHelpDBReader::metaData(const QString &name) const
+{
+ QVariant v;
+ if (!m_query)
+ return v;
+
+ m_query->prepare(QLatin1String("SELECT COUNT(Value), Value FROM MetaDataTable "
+ "WHERE Name=?"));
+ m_query->bindValue(0, name);
+ if (m_query->exec() && m_query->next()
+ && m_query->value(0).toInt() == 1)
+ v = m_query->value(1);
+ return v;
+}
+
+QString QHelpDBReader::mergeList(const QStringList &list) const
+{
+ QString str;
+ foreach (const QString &s, list)
+ str.append(QLatin1Char('\'') + quote(s) + QLatin1String("\', "));
+ if (str.endsWith(QLatin1String(", ")))
+ str = str.left(str.length()-2);
+ return str;
+}
+
+QString QHelpDBReader::quote(const QString &string) const
+{
+ QString s = string;
+ s.replace(QLatin1Char('\''), QLatin1String("\'\'"));
+ return s;
+}
+
+QSet<int> QHelpDBReader::indexIds(const QStringList &attributes) const
+{
+ QSet<int> ids;
+
+ if (attributes.isEmpty())
+ return ids;
+
+ QString query = QString(QLatin1String("SELECT a.IndexId FROM IndexFilterTable a, "
+ "FilterAttributeTable b WHERE a.FilterAttributeId=b.Id "
+ "AND b.Name='%1'")).arg(attributes.first());
+ for (int i=0; i<attributes.count(); ++i) {
+ query.append(QString(QLatin1String(" INTERSECT SELECT a.IndexId FROM "
+ "IndexFilterTable a, FilterAttributeTable b WHERE "
+ "a.FilterAttributeId=b.Id AND b.Name='%1'"))
+ .arg(attributes.at(i)));
+ }
+
+ if (!m_query->exec(query))
+ return ids;
+
+ while (m_query->next())
+ ids.insert(m_query->value(0).toInt());
+
+ return ids;
+}
+
+bool QHelpDBReader::createAttributesCache(const QStringList &attributes,
+ const QSet<int> &indexIds)
+{
+ m_useAttributesCache = false;
+
+ if (attributes.count() < 2) {
+ m_viewAttributes.clear();
+ return true;
+ }
+
+ bool needUpdate = !m_viewAttributes.count();
+
+ foreach (const QString &s, attributes)
+ m_viewAttributes.remove(s);
+
+ if (m_viewAttributes.count() || needUpdate) {
+ m_viewAttributes.clear();
+ m_indicesCache = indexIds;
+ }
+ foreach (const QString &s, attributes)
+ m_viewAttributes.insert(s);
+ m_useAttributesCache = true;
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpdbreader_p.h b/src/assistant/lib/qhelpdbreader_p.h
new file mode 100644
index 000000000..5fdf2e90b
--- /dev/null
+++ b/src/assistant/lib/qhelpdbreader_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPDBREADER_H
+#define QHELPDBREADER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QUrl>
+#include <QtCore/QByteArray>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+class QSqlQuery;
+
+class QHelpDBReader : public QObject
+{
+ Q_OBJECT
+
+public:
+ QHelpDBReader(const QString &dbName);
+ QHelpDBReader(const QString &dbName, const QString &uniqueId,
+ QObject *parent);
+ ~QHelpDBReader();
+
+ bool init();
+
+ QString errorMessage() const;
+
+ QString databaseName() const;
+ QString namespaceName() const;
+ QString virtualFolder() const;
+ QList<QStringList> filterAttributeSets() const;
+ QStringList files(const QStringList &filterAttributes,
+ const QString &extensionFilter = QString()) const;
+ bool fileExists(const QString &virtualFolder, const QString &filePath,
+ const QStringList &filterAttributes = QStringList()) const;
+ QByteArray fileData(const QString &virtualFolder,
+ const QString &filePath) const;
+
+ QStringList customFilters() const;
+ QStringList filterAttributes(const QString &filterName = QString()) const;
+ QStringList indicesForFilter(const QStringList &filterAttributes) const;
+ void linksForKeyword(const QString &keyword, const QStringList &filterAttributes,
+ QMap<QString, QUrl> &linkMap) const;
+
+ void linksForIdentifier(const QString &id, const QStringList &filterAttributes,
+ QMap<QString, QUrl> &linkMap) const;
+
+ QList<QByteArray> contentsForFilter(const QStringList &filterAttributes) const;
+ QUrl urlOfPath(const QString &relativePath) const;
+
+ QSet<int> indexIds(const QStringList &attributes) const;
+ bool createAttributesCache(const QStringList &attributes,
+ const QSet<int> &indexIds);
+ QVariant metaData(const QString &name) const;
+
+private:
+ void initObject(const QString &dbName, const QString &uniqueId);
+ QUrl buildQUrl(const QString &ns, const QString &folder,
+ const QString &relFileName, const QString &anchor) const;
+ QString mergeList(const QStringList &list) const;
+ QString quote(const QString &string) const;
+
+ bool m_initDone;
+ QString m_dbName;
+ QString m_uniqueId;
+ QString m_error;
+ QSqlQuery *m_query;
+ mutable QString m_namespace;
+ QSet<QString> m_viewAttributes;
+ bool m_useAttributesCache;
+ QSet<int> m_indicesCache;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/lib/qhelpengine.cpp b/src/assistant/lib/qhelpengine.cpp
new file mode 100644
index 000000000..f11b52a9c
--- /dev/null
+++ b/src/assistant/lib/qhelpengine.cpp
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpengine.h"
+#include "qhelpengine_p.h"
+#include "qhelpdbreader_p.h"
+#include "qhelpcontentwidget.h"
+#include "qhelpindexwidget.h"
+#include "qhelpsearchengine.h"
+#include "qhelpcollectionhandler_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QLibrary>
+#include <QtCore/QPluginLoader>
+#include <QtGui/QApplication>
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+QHelpEnginePrivate::QHelpEnginePrivate()
+ : QHelpEngineCorePrivate()
+ , contentModel(0)
+ , contentWidget(0)
+ , indexModel(0)
+ , indexWidget(0)
+ , searchEngine(0)
+{
+}
+
+QHelpEnginePrivate::~QHelpEnginePrivate()
+{
+}
+
+void QHelpEnginePrivate::init(const QString &collectionFile,
+ QHelpEngineCore *helpEngineCore)
+{
+ QHelpEngineCorePrivate::init(collectionFile, helpEngineCore);
+
+ if (!contentModel)
+ contentModel = new QHelpContentModel(this);
+ if (!indexModel)
+ indexModel = new QHelpIndexModel(this);
+
+ connect(helpEngineCore, SIGNAL(setupFinished()), this,
+ SLOT(applyCurrentFilter()));
+ connect(helpEngineCore, SIGNAL(currentFilterChanged(QString)), this,
+ SLOT(applyCurrentFilter()));
+}
+
+void QHelpEnginePrivate::applyCurrentFilter()
+{
+ if (!error.isEmpty())
+ return;
+ contentModel->createContents(currentFilter);
+ indexModel->createIndex(currentFilter);
+}
+
+void QHelpEnginePrivate::setContentsWidgetBusy()
+{
+ contentWidget->setCursor(Qt::WaitCursor);
+}
+
+void QHelpEnginePrivate::unsetContentsWidgetBusy()
+{
+ contentWidget->unsetCursor();
+}
+
+void QHelpEnginePrivate::setIndexWidgetBusy()
+{
+ indexWidget->setCursor(Qt::WaitCursor);
+}
+
+void QHelpEnginePrivate::unsetIndexWidgetBusy()
+{
+ indexWidget->unsetCursor();
+}
+
+void QHelpEnginePrivate::stopDataCollection()
+{
+ contentModel->invalidateContents(true);
+ indexModel->invalidateIndex(true);
+}
+
+
+
+/*!
+ \class QHelpEngine
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpEngine class provides access to contents and
+ indices of the help engine.
+
+
+*/
+
+/*!
+ Constructs a new help engine with the given \a parent. The help
+ engine uses the information stored in the \a collectionFile for
+ providing help. If the collection file does not already exist,
+ it will be created.
+*/
+QHelpEngine::QHelpEngine(const QString &collectionFile, QObject *parent)
+ : QHelpEngineCore(d = new QHelpEnginePrivate(), parent)
+{
+ d->init(collectionFile, this);
+}
+
+/*!
+ Destroys the help engine object.
+*/
+QHelpEngine::~QHelpEngine()
+{
+ d->stopDataCollection();
+}
+
+/*!
+ Returns the content model.
+*/
+QHelpContentModel *QHelpEngine::contentModel() const
+{
+ return d->contentModel;
+}
+
+/*!
+ Returns the index model.
+*/
+QHelpIndexModel *QHelpEngine::indexModel() const
+{
+ return d->indexModel;
+}
+
+/*!
+ Returns the content widget.
+*/
+QHelpContentWidget *QHelpEngine::contentWidget()
+{
+ if (!d->contentWidget) {
+ d->contentWidget = new QHelpContentWidget();
+ d->contentWidget->setModel(d->contentModel);
+ connect(d->contentModel, SIGNAL(contentsCreationStarted()),
+ d, SLOT(setContentsWidgetBusy()));
+ connect(d->contentModel, SIGNAL(contentsCreated()),
+ d, SLOT(unsetContentsWidgetBusy()));
+ }
+ return d->contentWidget;
+}
+
+/*!
+ Returns the index widget.
+*/
+QHelpIndexWidget *QHelpEngine::indexWidget()
+{
+ if (!d->indexWidget) {
+ d->indexWidget = new QHelpIndexWidget();
+ d->indexWidget->setModel(d->indexModel);
+ connect(d->indexModel, SIGNAL(indexCreationStarted()),
+ d, SLOT(setIndexWidgetBusy()));
+ connect(d->indexModel, SIGNAL(indexCreated()),
+ d, SLOT(unsetIndexWidgetBusy()));
+ }
+ return d->indexWidget;
+}
+
+/*!
+ Returns the default search engine.
+*/
+QHelpSearchEngine* QHelpEngine::searchEngine()
+{
+ if (!d->searchEngine)
+ d->searchEngine = new QHelpSearchEngine(this, this);
+ return d->searchEngine;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpengine.h b/src/assistant/lib/qhelpengine.h
new file mode 100644
index 000000000..cc0bca299
--- /dev/null
+++ b/src/assistant/lib/qhelpengine.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPENGINE_H
+#define QHELPENGINE_H
+
+#include <QtHelp/qhelpenginecore.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpContentModel;
+class QHelpContentWidget;
+class QHelpIndexModel;
+class QHelpIndexWidget;
+class QHelpEnginePrivate;
+class QHelpSearchEngine;
+
+class QHELP_EXPORT QHelpEngine : public QHelpEngineCore
+{
+ Q_OBJECT
+
+public:
+ explicit QHelpEngine(const QString &collectionFile, QObject *parent = 0);
+ ~QHelpEngine();
+
+ QHelpContentModel *contentModel() const;
+ QHelpIndexModel *indexModel() const;
+
+ QHelpContentWidget *contentWidget();
+ QHelpIndexWidget *indexWidget();
+
+ QHelpSearchEngine *searchEngine();
+
+private:
+ QHelpEnginePrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/assistant/lib/qhelpengine_p.h b/src/assistant/lib/qhelpengine_p.h
new file mode 100644
index 000000000..5a7c30184
--- /dev/null
+++ b/src/assistant/lib/qhelpengine_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPENGINE_P_H
+#define QHELPENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QMap>
+#include <QtCore/QStringList>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QSqlQuery;
+
+class QHelpEngineCore;
+class QHelpDBReader;
+class QHelpContentModel;
+class QHelpContentWidget;
+class QHelpIndexModel;
+class QHelpIndexWidget;
+class QHelpSearchEngine;
+class QHelpCollectionHandler;
+
+class QHelpEngineCorePrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QHelpEngineCorePrivate();
+ virtual ~QHelpEngineCorePrivate();
+
+ virtual void init(const QString &collectionFile,
+ QHelpEngineCore *helpEngineCore);
+
+ void clearMaps();
+ bool setup();
+
+ QMap<QString, QHelpDBReader*> readerMap;
+ QMap<QString, QHelpDBReader*> fileNameReaderMap;
+ QMultiMap<QString, QHelpDBReader*> virtualFolderMap;
+ QStringList orderedFileNameList;
+
+ QHelpCollectionHandler *collectionHandler;
+ QString currentFilter;
+ QString error;
+ bool needsSetup;
+ bool autoSaveFilter;
+
+protected:
+ QHelpEngineCore *q;
+
+private slots:
+ void errorReceived(const QString &msg);
+};
+
+
+class QHelpEnginePrivate : public QHelpEngineCorePrivate
+{
+ Q_OBJECT
+
+public:
+ QHelpEnginePrivate();
+ ~QHelpEnginePrivate();
+
+ void init(const QString &collectionFile,
+ QHelpEngineCore *helpEngineCore);
+
+ QHelpContentModel *contentModel;
+ QHelpContentWidget *contentWidget;
+
+ QHelpIndexModel *indexModel;
+ QHelpIndexWidget *indexWidget;
+
+ QHelpSearchEngine *searchEngine;
+
+ void stopDataCollection();
+
+ friend class QHelpContentProvider;
+ friend class QHelpContentModel;
+ friend class QHelpIndexProvider;
+ friend class QHelpIndexModel;
+
+public slots:
+ void setContentsWidgetBusy();
+ void unsetContentsWidgetBusy();
+ void setIndexWidgetBusy();
+ void unsetIndexWidgetBusy();
+
+private slots:
+ void applyCurrentFilter();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/lib/qhelpenginecore.cpp b/src/assistant/lib/qhelpenginecore.cpp
new file mode 100644
index 000000000..1fd22428d
--- /dev/null
+++ b/src/assistant/lib/qhelpenginecore.cpp
@@ -0,0 +1,737 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpenginecore.h"
+#include "qhelpengine_p.h"
+#include "qhelpdbreader_p.h"
+#include "qhelpcollectionhandler_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QLibrary>
+#include <QtCore/QPluginLoader>
+#include <QtCore/QFileInfo>
+#include <QtCore/QThread>
+#include <QtGui/QApplication>
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+QHelpEngineCorePrivate::QHelpEngineCorePrivate()
+{
+ QHelpGlobal::uniquifyConnectionName(QString(), this);
+ autoSaveFilter = true;
+}
+
+void QHelpEngineCorePrivate::init(const QString &collectionFile,
+ QHelpEngineCore *helpEngineCore)
+{
+ q = helpEngineCore;
+ collectionHandler = new QHelpCollectionHandler(collectionFile, helpEngineCore);
+ connect(collectionHandler, SIGNAL(error(QString)),
+ this, SLOT(errorReceived(QString)));
+ needsSetup = true;
+}
+
+QHelpEngineCorePrivate::~QHelpEngineCorePrivate()
+{
+ delete collectionHandler;
+ clearMaps();
+}
+
+void QHelpEngineCorePrivate::clearMaps()
+{
+ QMap<QString, QHelpDBReader*>::iterator it = readerMap.begin();
+ while (it != readerMap.end()) {
+ delete it.value();
+ ++it;
+ }
+ readerMap.clear();
+ fileNameReaderMap.clear();
+ virtualFolderMap.clear();
+ orderedFileNameList.clear();
+}
+
+bool QHelpEngineCorePrivate::setup()
+{
+ error.clear();
+ if (!needsSetup)
+ return true;
+
+ needsSetup = false;
+ emit q->setupStarted();
+ clearMaps();
+
+ if (!collectionHandler->openCollectionFile()) {
+ emit q->setupFinished();
+ return false;
+ }
+
+ const QHelpCollectionHandler::DocInfoList docList =
+ collectionHandler->registeredDocumentations();
+ QFileInfo fi(collectionHandler->collectionFile());
+ QString absFileName;
+ foreach(const QHelpCollectionHandler::DocInfo &info, docList) {
+ if (QDir::isAbsolutePath(info.fileName)) {
+ absFileName = info.fileName;
+ } else {
+ absFileName = QFileInfo(fi.absolutePath() + QDir::separator() + info.fileName)
+ .absoluteFilePath();
+ }
+ QHelpDBReader *reader = new QHelpDBReader(absFileName,
+ QHelpGlobal::uniquifyConnectionName(info.fileName, this), this);
+ if (!reader->init()) {
+ emit q->warning(QHelpEngineCore::tr("Cannot open documentation file %1: %2!")
+ .arg(absFileName, reader->errorMessage()));
+ continue;
+ }
+
+ readerMap.insert(info.namespaceName, reader);
+ fileNameReaderMap.insert(absFileName, reader);
+ virtualFolderMap.insert(info.folderName, reader);
+ orderedFileNameList.append(absFileName);
+ }
+ q->currentFilter();
+ emit q->setupFinished();
+ return true;
+}
+
+void QHelpEngineCorePrivate::errorReceived(const QString &msg)
+{
+ error = msg;
+}
+
+
+
+/*!
+ \class QHelpEngineCore
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpEngineCore class provides the core functionality
+ of the help system.
+
+ Before the help engine can be used, it must be initialized by
+ calling setupData(). At the beginning of the setup process the
+ signal setupStarted() is emitted. From this point on until
+ the signal setupFinished() is emitted, is the help data in an
+ undefined meaning unusable state.
+
+ The core help engine can be used to perform different tasks.
+ By calling linksForIdentifier() the engine returns
+ urls specifying the file locations inside the help system. The
+ actual file data can then be retrived by calling fileData(). In
+ contrast to all other functions in this class, linksForIdentifier()
+ depends on the currently set custom filter. Depending on the filter,
+ the function may return different hits.
+
+ Every help engine can contain any number of custom filters. A custom
+ filter is defined by a name and set of filter attributes and can be
+ added to the help engine by calling addCustomFilter(). Analogous,
+ it is removed by calling removeCustomFilter(). customFilters() returns
+ all defined filters.
+
+ The help engine also offers the possibility to set and read values
+ in a persistant way comparable to ini files or Windows registry
+ entries. For more information see setValue() or value().
+
+ This class does not offer any GUI components or functionality for
+ indices or contents. If you need one of those use QHelpEngine
+ instead.
+
+ When creating a custom help viewer the viewer can be
+ configured by writing a custom collection file which could contain various
+ keywords to be used to configure the help engine. These keywords and values
+ and their meaning can be found in the help information for
+ \l{assistant-custom-help-viewer.html#creating-a-custom-help-collection-file}
+ {creating a custom help collection file} for Assistant.
+*/
+
+/*!
+ \fn void QHelpEngineCore::setupStarted()
+
+ This signal is emitted when setup is started.
+*/
+
+/*!
+ \fn void QHelpEngineCore::setupFinished()
+
+ This signal is emitted when the setup is complete.
+*/
+
+/*!
+ \fn void QHelpEngineCore::currentFilterChanged(const QString &newFilter)
+
+ This signal is emitted when the current filter is changed to
+ \a newFilter.
+*/
+
+/*!
+ \fn void QHelpEngineCore::warning(const QString &msg)
+
+ This signal is emitted when a non critical error occurs.
+ The warning message is stored in \a msg.
+*/
+
+/*!
+ Constructs a new core help engine with a \a parent. The help engine
+ uses the information stored in the \a collectionFile to provide help.
+ If the collection file does not exist yet, it'll be created.
+*/
+QHelpEngineCore::QHelpEngineCore(const QString &collectionFile, QObject *parent)
+ : QObject(parent)
+{
+ d = new QHelpEngineCorePrivate();
+ d->init(collectionFile, this);
+}
+
+/*!
+ \internal
+*/
+QHelpEngineCore::QHelpEngineCore(QHelpEngineCorePrivate *helpEngineCorePrivate,
+ QObject *parent)
+ : QObject(parent)
+{
+ d = helpEngineCorePrivate;
+}
+
+/*!
+ Destructs the help engine.
+*/
+QHelpEngineCore::~QHelpEngineCore()
+{
+ delete d;
+}
+
+/*!
+ \property QHelpEngineCore::collectionFile
+ \brief the absolute file name of the collection file currently used.
+ \since 4.5
+
+ Setting this property leaves the help engine in an invalid state. It is
+ important to invoke setupData() or any getter function in order to setup
+ the help engine again.
+*/
+QString QHelpEngineCore::collectionFile() const
+{
+ return d->collectionHandler->collectionFile();
+}
+
+void QHelpEngineCore::setCollectionFile(const QString &fileName)
+{
+ if (fileName == collectionFile())
+ return;
+
+ if (d->collectionHandler) {
+ delete d->collectionHandler;
+ d->collectionHandler = 0;
+ d->clearMaps();
+ }
+ d->init(fileName, this);
+ d->needsSetup = true;
+}
+
+/*!
+ Sets up the help engine by processing the information found
+ in the collection file and returns true if successful; otherwise
+ returns false.
+
+ By calling the function, the help
+ engine is forced to initialize itself immediately. Most of
+ the times, this function does not have to be called
+ explicitly because getter functions which depend on a correctly
+ set up help engine do that themselves.
+
+ \note \c{qsqlite4.dll} needs to be deployed with the application as the
+ help system uses the sqlite driver when loading help collections.
+*/
+bool QHelpEngineCore::setupData()
+{
+ d->needsSetup = true;
+ return d->setup();
+}
+
+/*!
+ Creates the file \a fileName and copies all contents from
+ the current collection file into the newly created file,
+ and returns true if successful; otherwise returns false.
+
+ The copying process makes sure that file references to Qt
+ Collection files (\c{.qch}) files are updated accordingly.
+*/
+bool QHelpEngineCore::copyCollectionFile(const QString &fileName)
+{
+ if (!d->setup())
+ return false;
+ return d->collectionHandler->copyCollectionFile(fileName);
+}
+
+/*!
+ Returns the namespace name defined for the Qt compressed help file (.qch)
+ specified by its \a documentationFileName. If the file is not valid, an
+ empty string is returned.
+
+ \sa documentationFileName()
+*/
+QString QHelpEngineCore::namespaceName(const QString &documentationFileName)
+{
+ QHelpDBReader reader(documentationFileName,
+ QHelpGlobal::uniquifyConnectionName(QLatin1String("GetNamespaceName"),
+ QThread::currentThread()), 0);
+ if (reader.init())
+ return reader.namespaceName();
+ return QString();
+}
+
+/*!
+ Registers the Qt compressed help file (.qch) contained in the file
+ \a documentationFileName. One compressed help file, uniquely
+ identified by its namespace can only be registered once.
+ True is returned if the registration was successful, otherwise
+ false.
+
+ \sa unregisterDocumentation(), error()
+*/
+bool QHelpEngineCore::registerDocumentation(const QString &documentationFileName)
+{
+ d->error.clear();
+ d->needsSetup = true;
+ return d->collectionHandler->registerDocumentation(documentationFileName);
+}
+
+/*!
+ Unregisters the Qt compressed help file (.qch) identified by its
+ \a namespaceName from the help collection. Returns true
+ on success, otherwise false.
+
+ \sa registerDocumentation(), error()
+*/
+bool QHelpEngineCore::unregisterDocumentation(const QString &namespaceName)
+{
+ d->error.clear();
+ d->needsSetup = true;
+ return d->collectionHandler->unregisterDocumentation(namespaceName);
+}
+
+/*!
+ Returns the absolute file name of the Qt compressed help file (.qch)
+ identified by the \a namespaceName. If there is no Qt compressed help file
+ with the specified namespace registered, an empty string is returned.
+
+ \sa namespaceName()
+*/
+QString QHelpEngineCore::documentationFileName(const QString &namespaceName)
+{
+ if (d->setup()) {
+ const QHelpCollectionHandler::DocInfoList docList =
+ d->collectionHandler->registeredDocumentations();
+ foreach(const QHelpCollectionHandler::DocInfo &info, docList) {
+ if (info.namespaceName == namespaceName) {
+ if (QDir::isAbsolutePath(info.fileName))
+ return QDir::cleanPath(info.fileName);
+
+ QFileInfo fi(d->collectionHandler->collectionFile());
+ fi.setFile(fi.absolutePath() + QDir::separator() + info.fileName);
+ return QDir::cleanPath(fi.absoluteFilePath());
+ }
+ }
+ }
+ return QString();
+}
+
+/*!
+ Returns a list of all registered Qt compressed help files of the current collection file.
+ The returned names are the namespaces of the registered Qt compressed help files (.qch).
+*/
+QStringList QHelpEngineCore::registeredDocumentations() const
+{
+ QStringList list;
+ if (!d->setup())
+ return list;
+ const QHelpCollectionHandler::DocInfoList docList = d->collectionHandler->registeredDocumentations();
+ foreach(const QHelpCollectionHandler::DocInfo &info, docList) {
+ list.append(info.namespaceName);
+ }
+ return list;
+}
+
+/*!
+ Returns a list of custom filters.
+
+ \sa addCustomFilter(), removeCustomFilter()
+*/
+QStringList QHelpEngineCore::customFilters() const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->collectionHandler->customFilters();
+}
+
+/*!
+ Adds the new custom filter \a filterName. The filter attributes
+ are specified by \a attributes. If the filter already exists,
+ its attribute set is replaced. The function returns true if
+ the operation succeeded, otherwise it returns false.
+
+ \sa customFilters(), removeCustomFilter()
+*/
+bool QHelpEngineCore::addCustomFilter(const QString &filterName,
+ const QStringList &attributes)
+{
+ d->error.clear();
+ d->needsSetup = true;
+ return d->collectionHandler->addCustomFilter(filterName,
+ attributes);
+}
+
+/*!
+ Returns true if the filter \a filterName was removed successfully,
+ otherwise false.
+
+ \sa addCustomFilter(), customFilters()
+*/
+bool QHelpEngineCore::removeCustomFilter(const QString &filterName)
+{
+ d->error.clear();
+ d->needsSetup = true;
+ return d->collectionHandler->removeCustomFilter(filterName);
+}
+
+/*!
+ Returns a list of all defined filter attributes.
+*/
+QStringList QHelpEngineCore::filterAttributes() const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->collectionHandler->filterAttributes();
+}
+
+/*!
+ Returns a list of filter attributes used by the custom
+ filter \a filterName.
+*/
+QStringList QHelpEngineCore::filterAttributes(const QString &filterName) const
+{
+ if (!d->setup())
+ return QStringList();
+ return d->collectionHandler->filterAttributes(filterName);
+}
+
+/*!
+ \property QHelpEngineCore::currentFilter
+ \brief the name of the custom filter currently applied.
+ \since 4.5
+
+ Setting this property will save the new custom filter permanently in the
+ help collection file. To set a custom filter without saving it
+ permanently, disable the auto save filter mode.
+
+ \sa autoSaveFilter()
+*/
+QString QHelpEngineCore::currentFilter() const
+{
+ if (!d->setup())
+ return QString();
+
+ if (d->currentFilter.isEmpty()) {
+ QString filter =
+ d->collectionHandler->customValue(QLatin1String("CurrentFilter"),
+ QString()).toString();
+ if (!filter.isEmpty()
+ && d->collectionHandler->customFilters().contains(filter))
+ d->currentFilter = filter;
+ }
+ return d->currentFilter;
+}
+
+void QHelpEngineCore::setCurrentFilter(const QString &filterName)
+{
+ if (!d->setup() || filterName == d->currentFilter)
+ return;
+ d->currentFilter = filterName;
+ if (d->autoSaveFilter) {
+ d->collectionHandler->setCustomValue(QLatin1String("CurrentFilter"),
+ d->currentFilter);
+ }
+ emit currentFilterChanged(d->currentFilter);
+}
+
+/*!
+ Returns a list of filter attributes for the different filter sections
+ defined in the Qt compressed help file with the given namespace
+ \a namespaceName.
+*/
+QList<QStringList> QHelpEngineCore::filterAttributeSets(const QString &namespaceName) const
+{
+ if (d->setup()) {
+ QHelpDBReader *reader = d->readerMap.value(namespaceName);
+ if (reader)
+ return reader->filterAttributeSets();
+ }
+ return QList<QStringList>();
+}
+
+/*!
+ Returns a list of files contained in the Qt compressed help file \a
+ namespaceName. The files can be filtered by \a filterAttributes as
+ well as by their extension \a extensionFilter (e.g. 'html').
+*/
+QList<QUrl> QHelpEngineCore::files(const QString namespaceName,
+ const QStringList &filterAttributes,
+ const QString &extensionFilter)
+{
+ QList<QUrl> res;
+ if (!d->setup())
+ return res;
+ QHelpDBReader *reader = d->readerMap.value(namespaceName);
+ if (!reader) {
+ d->error = tr("The specified namespace does not exist!");
+ return res;
+ }
+
+ QUrl url;
+ url.setScheme(QLatin1String("qthelp"));
+ url.setAuthority(namespaceName);
+
+ const QStringList files = reader->files(filterAttributes, extensionFilter);
+ foreach (const QString &file, files) {
+ url.setPath(QLatin1String("/") + file);
+ res.append(url);
+ }
+ return res;
+}
+
+/*!
+ Returns an invalid URL if the file \a url cannot be found.
+ If the file exists, either the same url is returned or a
+ different url if the file is located in a different namespace
+ which is merged via a common virtual folder.
+*/
+QUrl QHelpEngineCore::findFile(const QUrl &url) const
+{
+ QUrl res;
+ if (!d->setup() || !url.isValid() || url.toString().count(QLatin1Char('/')) < 4
+ || url.scheme() != QLatin1String("qthelp"))
+ return res;
+
+ QString ns = url.authority();
+ QString filePath = QDir::cleanPath(url.path());
+ if (filePath.startsWith(QLatin1Char('/')))
+ filePath = filePath.mid(1);
+ QString virtualFolder = filePath.mid(0, filePath.indexOf(QLatin1Char('/'), 1));
+ filePath = filePath.mid(virtualFolder.length()+1);
+
+ QHelpDBReader *defaultReader = 0;
+ if (d->readerMap.contains(ns)) {
+ defaultReader = d->readerMap.value(ns);
+ if (defaultReader->fileExists(virtualFolder, filePath))
+ return url;
+ }
+
+ QStringList filterAtts = filterAttributes(currentFilter());
+ foreach (QHelpDBReader *reader, d->virtualFolderMap.values(virtualFolder)) {
+ if (reader == defaultReader)
+ continue;
+ if (reader->fileExists(virtualFolder, filePath, filterAtts)) {
+ res = url;
+ res.setAuthority(reader->namespaceName());
+ return res;
+ }
+ }
+
+ foreach (QHelpDBReader *reader, d->virtualFolderMap.values(virtualFolder)) {
+ if (reader == defaultReader)
+ continue;
+ if (reader->fileExists(virtualFolder, filePath)) {
+ res = url;
+ res.setAuthority(reader->namespaceName());
+ break;
+ }
+ }
+
+ return res;
+}
+
+/*!
+ Returns the data of the file specified by \a url. If the
+ file does not exist, an empty QByteArray is returned.
+
+ \sa findFile()
+*/
+QByteArray QHelpEngineCore::fileData(const QUrl &url) const
+{
+ if (!d->setup() || !url.isValid() || url.toString().count(QLatin1Char('/')) < 4
+ || url.scheme() != QLatin1String("qthelp"))
+ return QByteArray();
+
+ QString ns = url.authority();
+ QString filePath = QDir::cleanPath(url.path());
+ if (filePath.startsWith(QLatin1Char('/')))
+ filePath = filePath.mid(1);
+ QString virtualFolder = filePath.mid(0, filePath.indexOf(QLatin1Char('/'), 1));
+ filePath = filePath.mid(virtualFolder.length()+1);
+
+ QByteArray ba;
+ QHelpDBReader *defaultReader = 0;
+ if (d->readerMap.contains(ns)) {
+ defaultReader = d->readerMap.value(ns);
+ ba = defaultReader->fileData(virtualFolder, filePath);
+ }
+
+ if (ba.isEmpty()) {
+ foreach (QHelpDBReader *reader, d->virtualFolderMap.values(virtualFolder)) {
+ if (reader == defaultReader)
+ continue;
+ ba = reader->fileData(virtualFolder, filePath);
+ if (!ba.isEmpty())
+ return ba;
+ }
+ }
+ return ba;
+}
+
+/*!
+ Returns a map of hits found for the \a id. A hit contains the
+ title of the document and the url where the keyword is located.
+ The result depends on the current filter, meaning only the keywords
+ registered for the current filter will be returned.
+*/
+QMap<QString, QUrl> QHelpEngineCore::linksForIdentifier(const QString &id) const
+{
+ QMap<QString, QUrl> linkMap;
+ if (!d->setup())
+ return linkMap;
+
+ QStringList atts = filterAttributes(d->currentFilter);
+ foreach (QHelpDBReader *reader, d->readerMap)
+ reader->linksForIdentifier(id, atts, linkMap);
+
+ return linkMap;
+}
+
+/*!
+ Removes the \a key from the settings section in the
+ collection file. Returns true if the value was removed
+ successfully, otherwise false.
+
+ \sa customValue(), setCustomValue()
+*/
+bool QHelpEngineCore::removeCustomValue(const QString &key)
+{
+ d->error.clear();
+ return d->collectionHandler->removeCustomValue(key);
+}
+
+/*!
+ Returns the value assigned to the \a key. If the requested
+ key does not exist, the specified \a defaultValue is
+ returned.
+
+ \sa setCustomValue(), removeCustomValue()
+*/
+QVariant QHelpEngineCore::customValue(const QString &key, const QVariant &defaultValue) const
+{
+ if (!d->setup())
+ return QVariant();
+ return d->collectionHandler->customValue(key, defaultValue);
+}
+
+/*!
+ Save the \a value under the \a key. If the key already exist,
+ the value will be overwritten. Returns true if the value was
+ saved successfully, otherwise false.
+
+ \sa customValue(), removeCustomValue()
+*/
+bool QHelpEngineCore::setCustomValue(const QString &key, const QVariant &value)
+{
+ d->error.clear();
+ return d->collectionHandler->setCustomValue(key, value);
+}
+
+/*!
+ Returns the meta data for the Qt compressed help file \a
+ documentationFileName. If there is no data available for
+ \a name, an invalid QVariant() is returned. The meta
+ data is defined when creating the Qt compressed help file and
+ cannot be modified later. Common meta data includes e.g.
+ the author of the documentation.
+*/
+QVariant QHelpEngineCore::metaData(const QString &documentationFileName,
+ const QString &name)
+{
+ QHelpDBReader reader(documentationFileName, QLatin1String("GetMetaData"), 0);
+
+ if (reader.init())
+ return reader.metaData(name);
+ return QVariant();
+}
+
+/*!
+ Returns a description of the last error that occurred.
+*/
+QString QHelpEngineCore::error() const
+{
+ return d->error;
+}
+
+/*!
+ \property QHelpEngineCore::autoSaveFilter
+ \brief whether QHelpEngineCore is in auto save filter mode or not.
+ \since 4.5
+
+ If QHelpEngineCore is in auto save filter mode, the current filter is
+ automatically saved when it is changed by the setCurrentFilter()
+ function. The filter is saved persistently in the help collection file.
+
+ By default, this mode is on.
+*/
+void QHelpEngineCore::setAutoSaveFilter(bool save)
+{
+ d->autoSaveFilter = save;
+}
+
+bool QHelpEngineCore::autoSaveFilter() const
+{
+ return d->autoSaveFilter;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpenginecore.h b/src/assistant/lib/qhelpenginecore.h
new file mode 100644
index 000000000..fbfb8a0e8
--- /dev/null
+++ b/src/assistant/lib/qhelpenginecore.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPENGINECORE_H
+#define QHELPENGINECORE_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QUrl>
+#include <QtCore/QMap>
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpEngineCorePrivate;
+
+class QHELP_EXPORT QHelpEngineCore : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool autoSaveFilter READ autoSaveFilter WRITE setAutoSaveFilter)
+ Q_PROPERTY(QString collectionFile READ collectionFile WRITE setCollectionFile)
+ Q_PROPERTY(QString currentFilter READ currentFilter WRITE setCurrentFilter)
+
+public:
+ explicit QHelpEngineCore(const QString &collectionFile, QObject *parent = 0);
+ virtual ~QHelpEngineCore();
+
+ bool setupData();
+
+ QString collectionFile() const;
+ void setCollectionFile(const QString &fileName);
+
+ bool copyCollectionFile(const QString &fileName);
+
+ static QString namespaceName(const QString &documentationFileName);
+ bool registerDocumentation(const QString &documentationFileName);
+ bool unregisterDocumentation(const QString &namespaceName);
+ QString documentationFileName(const QString &namespaceName);
+
+ QStringList customFilters() const;
+ bool removeCustomFilter(const QString &filterName);
+ bool addCustomFilter(const QString &filterName,
+ const QStringList &attributes);
+
+ QStringList filterAttributes() const;
+ QStringList filterAttributes(const QString &filterName) const;
+
+ QString currentFilter() const;
+ void setCurrentFilter(const QString &filterName);
+
+ QStringList registeredDocumentations() const;
+ QList<QStringList> filterAttributeSets(const QString &namespaceName) const;
+ QList<QUrl> files(const QString namespaceName,
+ const QStringList &filterAttributes,
+ const QString &extensionFilter = QString());
+ QUrl findFile(const QUrl &url) const;
+ QByteArray fileData(const QUrl &url) const;
+
+ QMap<QString, QUrl> linksForIdentifier(const QString &id) const;
+
+ bool removeCustomValue(const QString &key);
+ QVariant customValue(const QString &key,
+ const QVariant &defaultValue = QVariant()) const;
+ bool setCustomValue(const QString &key, const QVariant &value);
+
+ static QVariant metaData(const QString &documentationFileName,
+ const QString &name);
+
+ QString error() const;
+
+ void setAutoSaveFilter(bool save);
+ bool autoSaveFilter() const;
+
+Q_SIGNALS:
+ void setupStarted();
+ void setupFinished();
+ void currentFilterChanged(const QString &newFilter);
+ void warning(const QString &msg);
+
+protected:
+ QHelpEngineCore(QHelpEngineCorePrivate *helpEngineCorePrivate,
+ QObject *parent);
+
+private:
+ QHelpEngineCorePrivate *d;
+ friend class QHelpEngineCorePrivate;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPENGINECORE_H
diff --git a/src/assistant/lib/qhelpgenerator.cpp b/src/assistant/lib/qhelpgenerator.cpp
new file mode 100644
index 000000000..ce9c8562d
--- /dev/null
+++ b/src/assistant/lib/qhelpgenerator.cpp
@@ -0,0 +1,909 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpgenerator_p.h"
+#include "qhelpdatainterface_p.h"
+
+#include <math.h>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QSet>
+#include <QtCore/QVariant>
+#include <QtCore/QDateTime>
+#include <QtCore/QTextCodec>
+#include <QtSql/QSqlQuery>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpGeneratorPrivate
+{
+public:
+ QHelpGeneratorPrivate();
+ ~QHelpGeneratorPrivate();
+
+ QString error;
+ QSqlQuery *query;
+
+ int namespaceId;
+ int virtualFolderId;
+
+ QMap<QString, int> fileMap;
+ QMap<int, QSet<int> > fileFilterMap;
+
+ double progress;
+ double oldProgress;
+ double contentStep;
+ double fileStep;
+ double indexStep;
+};
+
+QHelpGeneratorPrivate::QHelpGeneratorPrivate()
+{
+ query = 0;
+ namespaceId = -1;
+ virtualFolderId = -1;
+}
+
+QHelpGeneratorPrivate::~QHelpGeneratorPrivate()
+{
+}
+
+
+
+/*!
+ \internal
+ \class QHelpGenerator
+ \since 4.4
+ \brief The QHelpGenerator class generates a new
+ Qt compressed help file (.qch).
+
+ The help generator takes a help data structure as
+ input for generating a new Qt compressed help files. Since
+ the generation may takes some time, the generator emits
+ various signals to inform about its current state.
+*/
+
+/*!
+ \fn void QHelpGenerator::statusChanged(const QString &msg)
+
+ This signal is emitted when the generation status changes.
+ The status is basically a specific task like inserting
+ files or building up the keyword index. The parameter
+ \a msg contains the detailed status description.
+*/
+
+/*!
+ \fn void QHelpGenerator::progressChanged(double progress)
+
+ This signal is emitted when the progress changes. The
+ \a progress ranges from 0 to 100.
+*/
+
+/*!
+ \fn void QHelpGenerator::warning(const QString &msg)
+
+ This signal is emitted when a non critical error occurs,
+ e.g. when a referenced file cannot be found. \a msg
+ contains the exact warning message.
+*/
+
+/*!
+ Constructs a new help generator with the give \a parent.
+*/
+QHelpGenerator::QHelpGenerator(QObject *parent)
+ : QObject(parent)
+{
+ d = new QHelpGeneratorPrivate;
+}
+
+/*!
+ Destructs the help generator.
+*/
+QHelpGenerator::~QHelpGenerator()
+{
+ delete d;
+}
+
+/*!
+ Takes the \a helpData and generates a new documentation
+ set from it. The Qt compressed help file is written to \a
+ outputFileName. Returns true on success, otherwise false.
+*/
+bool QHelpGenerator::generate(QHelpDataInterface *helpData,
+ const QString &outputFileName)
+{
+ emit progressChanged(0);
+ d->error.clear();
+ if (!helpData || helpData->namespaceName().isEmpty()) {
+ d->error = tr("Invalid help data!");
+ return false;
+ }
+
+ QString outFileName = outputFileName;
+ if (outFileName.isEmpty()) {
+ d->error = tr("No output file name specified!");
+ return false;
+ }
+
+ QFileInfo fi(outFileName);
+ if (fi.exists()) {
+ if (!fi.dir().remove(fi.fileName())) {
+ d->error = tr("The file %1 cannot be overwritten!").arg(outFileName);
+ return false;
+ }
+ }
+
+ setupProgress(helpData);
+
+ emit statusChanged(tr("Building up file structure..."));
+ bool openingOk = true;
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), QLatin1String("builder"));
+ db.setDatabaseName(outFileName);
+ openingOk = db.open();
+ if (openingOk)
+ d->query = new QSqlQuery(db);
+ }
+
+ if (!openingOk) {
+ d->error = tr("Cannot open data base file %1!").arg(outFileName);
+ cleanupDB();
+ return false;
+ }
+
+ d->query->exec(QLatin1String("PRAGMA synchronous=OFF"));
+ d->query->exec(QLatin1String("PRAGMA cache_size=3000"));
+
+ addProgress(1.0);
+ createTables();
+ insertFileNotFoundFile();
+ insertMetaData(helpData->metaData());
+
+ if (!registerVirtualFolder(helpData->virtualFolder(), helpData->namespaceName())) {
+ d->error = tr("Cannot register namespace %1!").arg(helpData->namespaceName());
+ cleanupDB();
+ return false;
+ }
+ addProgress(1.0);
+
+ emit statusChanged(tr("Insert custom filters..."));
+ foreach (const QHelpDataCustomFilter &f, helpData->customFilters()) {
+ if (!registerCustomFilter(f.name, f.filterAttributes, true)) {
+ cleanupDB();
+ return false;
+ }
+ }
+ addProgress(1.0);
+
+ int i = 1;
+ QList<QHelpDataFilterSection>::const_iterator it = helpData->filterSections().constBegin();
+ while (it != helpData->filterSections().constEnd()) {
+ emit statusChanged(tr("Insert help data for filter section (%1 of %2)...")
+ .arg(i++).arg(helpData->filterSections().count()));
+ insertFilterAttributes((*it).filterAttributes());
+ QByteArray ba;
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ foreach (QHelpDataContentItem *itm, (*it).contents())
+ writeTree(s, itm, 0);
+ if (!insertFiles((*it).files(), helpData->rootPath(), (*it).filterAttributes())
+ || !insertContents(ba, (*it).filterAttributes())
+ || !insertKeywords((*it).indices(), (*it).filterAttributes())) {
+ cleanupDB();
+ return false;
+ }
+ ++it;
+ }
+
+ cleanupDB();
+ emit progressChanged(100);
+ emit statusChanged(tr("Documentation successfully generated."));
+ return true;
+}
+
+void QHelpGenerator::setupProgress(QHelpDataInterface *helpData)
+{
+ d->progress = 0;
+ d->oldProgress = 0;
+
+ int numberOfFiles = 0;
+ int numberOfIndices = 0;
+ QList<QHelpDataFilterSection>::const_iterator it = helpData->filterSections().constBegin();
+ while (it != helpData->filterSections().constEnd()) {
+ numberOfFiles += (*it).files().count();
+ numberOfIndices += (*it).indices().count();
+ ++it;
+ }
+ // init 2%
+ // filters 1%
+ // contents 10%
+ // files 60%
+ // indices 27%
+ d->contentStep = 10.0/(double)helpData->customFilters().count();
+ d->fileStep = 60.0/(double)numberOfFiles;
+ d->indexStep = 27.0/(double)numberOfIndices;
+}
+
+void QHelpGenerator::addProgress(double step)
+{
+ d->progress += step;
+ if ((d->progress-d->oldProgress) >= 1.0 && d->progress <= 100.0) {
+ d->oldProgress = d->progress;
+ emit progressChanged(ceil(d->progress));
+ }
+}
+
+void QHelpGenerator::cleanupDB()
+{
+ if (d->query) {
+ d->query->clear();
+ delete d->query;
+ d->query = 0;
+ }
+ QSqlDatabase::removeDatabase(QLatin1String("builder"));
+}
+
+void QHelpGenerator::writeTree(QDataStream &s, QHelpDataContentItem *item, int depth)
+{
+ QString fReference = QDir::cleanPath(item->reference());
+ if (fReference.startsWith(QLatin1String("./")))
+ fReference = fReference.mid(2);
+
+ s << depth;
+ s << fReference;
+ s << item->title();
+ foreach (QHelpDataContentItem *i, item->children())
+ writeTree(s, i, depth+1);
+}
+
+/*!
+ Returns the last error message.
+*/
+QString QHelpGenerator::error() const
+{
+ return d->error;
+}
+
+bool QHelpGenerator::createTables()
+{
+ if (!d->query)
+ return false;
+
+ d->query->exec(QLatin1String("SELECT COUNT(*) FROM sqlite_master WHERE TYPE=\'table\'"
+ "AND Name=\'NamespaceTable\'"));
+ d->query->next();
+ if (d->query->value(0).toInt() > 0) {
+ d->error = tr("Some tables already exist!");
+ return false;
+ }
+
+ QStringList tables;
+ tables << QLatin1String("CREATE TABLE NamespaceTable ("
+ "Id INTEGER PRIMARY KEY,"
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterAttributeTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterNameTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT )")
+ << QLatin1String("CREATE TABLE FilterTable ("
+ "NameId INTEGER, "
+ "FilterAttributeId INTEGER )")
+ << QLatin1String("CREATE TABLE IndexTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Name TEXT, "
+ "Identifier TEXT, "
+ "NamespaceId INTEGER, "
+ "FileId INTEGER, "
+ "Anchor TEXT )")
+ << QLatin1String("CREATE TABLE IndexItemTable ("
+ "Id INTEGER, "
+ "IndexId INTEGER )")
+ << QLatin1String("CREATE TABLE IndexFilterTable ("
+ "FilterAttributeId INTEGER, "
+ "IndexId INTEGER )")
+ << QLatin1String("CREATE TABLE ContentsTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "NamespaceId INTEGER, "
+ "Data BLOB )")
+ << QLatin1String("CREATE TABLE ContentsFilterTable ("
+ "FilterAttributeId INTEGER, "
+ "ContentsId INTEGER )")
+ << QLatin1String("CREATE TABLE FileAttributeSetTable ("
+ "Id INTEGER, "
+ "FilterAttributeId INTEGER )")
+ << QLatin1String("CREATE TABLE FileDataTable ("
+ "Id INTEGER PRIMARY KEY, "
+ "Data BLOB )")
+ << QLatin1String("CREATE TABLE FileFilterTable ("
+ "FilterAttributeId INTEGER, "
+ "FileId INTEGER )")
+ << QLatin1String("CREATE TABLE FileNameTable ("
+ "FolderId INTEGER, "
+ "Name TEXT, "
+ "FileId INTEGER, "
+ "Title TEXT )")
+ << QLatin1String("CREATE TABLE FolderTable("
+ "Id INTEGER PRIMARY KEY, "
+ "Name Text, "
+ "NamespaceID INTEGER )")
+ << QLatin1String("CREATE TABLE MetaDataTable("
+ "Name Text, "
+ "Value BLOB )");
+
+ foreach (const QString &q, tables) {
+ if (!d->query->exec(q)) {
+ d->error = tr("Cannot create tables!");
+ return false;
+ }
+ }
+
+ d->query->exec(QLatin1String("INSERT INTO MetaDataTable VALUES('qchVersion', '1.0')"));
+
+ d->query->prepare(QLatin1String("INSERT INTO MetaDataTable VALUES('CreationDate', ?)"));
+ d->query->bindValue(0, QDateTime::currentDateTime().toString(Qt::ISODate));
+ d->query->exec();
+
+ return true;
+}
+
+bool QHelpGenerator::insertFileNotFoundFile()
+{
+ if (!d->query)
+ return false;
+
+ d->query->exec(QLatin1String("SELECT id FROM FileNameTable WHERE Name=\'\'"));
+ if (d->query->next() && d->query->isValid())
+ return true;
+
+ d->query->prepare(QLatin1String("INSERT INTO FileDataTable VALUES (Null, ?)"));
+ d->query->bindValue(0, QByteArray());
+ if (!d->query->exec())
+ return false;
+
+ int fileId = d->query->lastInsertId().toInt();
+ d->query->prepare(QLatin1String("INSERT INTO FileNameTable (FolderId, Name, FileId, Title) "
+ " VALUES (0, '', ?, '')"));
+ d->query->bindValue(0, fileId);
+ if (fileId > -1 && d->query->exec()) {
+ d->fileMap.insert(QString(), fileId);
+ return true;
+ }
+ return false;
+}
+
+bool QHelpGenerator::registerVirtualFolder(const QString &folderName, const QString &ns)
+{
+ if (!d->query || folderName.isEmpty() || ns.isEmpty())
+ return false;
+
+ d->query->prepare(QLatin1String("SELECT Id FROM FolderTable WHERE Name=?"));
+ d->query->bindValue(0, folderName);
+ d->query->exec();
+ d->query->next();
+ if (d->query->isValid() && d->query->value(0).toInt() > 0)
+ return true;
+
+ d->namespaceId = -1;
+ d->query->prepare(QLatin1String("SELECT Id FROM NamespaceTable WHERE Name=?"));
+ d->query->bindValue(0, ns);
+ d->query->exec();
+ while (d->query->next()) {
+ d->namespaceId = d->query->value(0).toInt();
+ break;
+ }
+
+ if (d->namespaceId < 0) {
+ d->query->prepare(QLatin1String("INSERT INTO NamespaceTable VALUES(NULL, ?)"));
+ d->query->bindValue(0, ns);
+ if (d->query->exec())
+ d->namespaceId = d->query->lastInsertId().toInt();
+ }
+
+ if (d->namespaceId > 0) {
+ d->query->prepare(QLatin1String("SELECT Id FROM FolderTable WHERE Name=?"));
+ d->query->bindValue(0, folderName);
+ d->query->exec();
+ while (d->query->next())
+ d->virtualFolderId = d->query->value(0).toInt();
+
+ if (d->virtualFolderId > 0)
+ return true;
+
+ d->query->prepare(QLatin1String("INSERT INTO FolderTable (NamespaceId, Name) "
+ "VALUES (?, ?)"));
+ d->query->bindValue(0, d->namespaceId);
+ d->query->bindValue(1, folderName);
+ if (d->query->exec()) {
+ d->virtualFolderId = d->query->lastInsertId().toInt();
+ return d->virtualFolderId > 0;
+ }
+ }
+ d->error = tr("Cannot register virtual folder!");
+ return false;
+}
+
+bool QHelpGenerator::insertFiles(const QStringList &files, const QString &rootPath,
+ const QStringList &filterAttributes)
+{
+ if (!d->query)
+ return false;
+
+ emit statusChanged(tr("Insert files..."));
+ QList<int> filterAtts;
+ foreach (const QString &filterAtt, filterAttributes) {
+ d->query->prepare(QLatin1String("SELECT Id FROM FilterAttributeTable "
+ "WHERE Name=?"));
+ d->query->bindValue(0, filterAtt);
+ d->query->exec();
+ if (d->query->next())
+ filterAtts.append(d->query->value(0).toInt());
+ }
+
+ int filterSetId = -1;
+ d->query->exec(QLatin1String("SELECT MAX(Id) FROM FileAttributeSetTable"));
+ if (d->query->next())
+ filterSetId = d->query->value(0).toInt();
+ if (filterSetId < 0)
+ return false;
+ ++filterSetId;
+ foreach (const int &attId, filterAtts) {
+ d->query->prepare(QLatin1String("INSERT INTO FileAttributeSetTable "
+ "VALUES(?, ?)"));
+ d->query->bindValue(0, filterSetId);
+ d->query->bindValue(1, attId);
+ d->query->exec();
+ }
+
+ int tableFileId = 1;
+ d->query->exec(QLatin1String("SELECT MAX(Id) FROM FileDataTable"));
+ if (d->query->next())
+ tableFileId = d->query->value(0).toInt() + 1;
+
+ QString title;
+ QString charSet;
+ FileNameTableData fileNameData;
+ QList<QByteArray> fileDataList;
+ QMap<int, QSet<int> > tmpFileFilterMap;
+ QList<FileNameTableData> fileNameDataList;
+
+ int i = 0;
+ foreach (const QString &file, files) {
+ const QString fileName = QDir::cleanPath(file);
+ if (fileName.startsWith(QLatin1String("../"))) {
+ emit warning(tr("The referenced file %1 must be inside or within a "
+ "subdirectory of (%2). Skipping it.").arg(fileName).arg(rootPath));
+ continue;
+ }
+
+ QFile fi(rootPath + QDir::separator() + fileName);
+ if (!fi.exists()) {
+ emit warning(tr("The file %1 does not exist! Skipping it.")
+ .arg(QDir::cleanPath(rootPath + QDir::separator() + fileName)));
+ continue;
+ }
+
+ if (!fi.open(QIODevice::ReadOnly)) {
+ emit warning(tr("Cannot open file %1! Skipping it.")
+ .arg(QDir::cleanPath(rootPath + QDir::separator() + fileName)));
+ continue;
+ }
+
+ QByteArray data = fi.readAll();
+ if (fileName.endsWith(QLatin1String(".html"))
+ || fileName.endsWith(QLatin1String(".htm"))) {
+ charSet = QHelpGlobal::codecFromData(data);
+ QTextStream stream(&data);
+ stream.setCodec(QTextCodec::codecForName(charSet.toLatin1().constData()));
+ title = QHelpGlobal::documentTitle(stream.readAll());
+ } else {
+ title = fileName.mid(fileName.lastIndexOf(QLatin1Char('/')) + 1);
+ }
+
+ int fileId = -1;
+ QMap<QString, int>::Iterator fileMapIt = d->fileMap.find(fileName);
+ if (fileMapIt == d->fileMap.end()) {
+ fileDataList.append(qCompress(data));
+
+ fileNameData.name = fileName;
+ fileNameData.fileId = tableFileId;
+ fileNameData.title = title;
+ fileNameDataList.append(fileNameData);
+
+ d->fileMap.insert(fileName, tableFileId);
+ d->fileFilterMap.insert(tableFileId, filterAtts.toSet());
+ tmpFileFilterMap.insert(tableFileId, filterAtts.toSet());
+
+ ++tableFileId;
+ } else {
+ fileId = fileMapIt.value();
+ QSet<int> &fileFilterSet = d->fileFilterMap[fileId];
+ QSet<int> &tmpFileFilterSet = tmpFileFilterMap[fileId];
+ foreach (const int &filter, filterAtts) {
+ if (!fileFilterSet.contains(filter)
+ && !tmpFileFilterSet.contains(filter)) {
+ fileFilterSet.insert(filter);
+ tmpFileFilterSet.insert(filter);
+ }
+ }
+ }
+ }
+
+ if (!tmpFileFilterMap.isEmpty()) {
+ d->query->exec(QLatin1String("BEGIN"));
+ QMap<int, QSet<int> >::const_iterator it = tmpFileFilterMap.constBegin();
+ while (it != tmpFileFilterMap.constEnd()) {
+ QSet<int>::const_iterator si = it.value().constBegin();
+ while (si != it.value().constEnd()) {
+ d->query->prepare(QLatin1String("INSERT INTO FileFilterTable "
+ "VALUES(?, ?)"));
+ d->query->bindValue(0, *si);
+ d->query->bindValue(1, it.key());
+ d->query->exec();
+ ++si;
+ }
+ ++it;
+ }
+
+ QList<QByteArray>::const_iterator fileIt = fileDataList.constBegin();
+ while (fileIt != fileDataList.constEnd()) {
+ d->query->prepare(QLatin1String("INSERT INTO FileDataTable VALUES "
+ "(Null, ?)"));
+ d->query->bindValue(0, *fileIt);
+ d->query->exec();
+ ++fileIt;
+ if (++i%20 == 0)
+ addProgress(d->fileStep*20.0);
+ }
+
+ QList<FileNameTableData>::const_iterator fileNameIt =
+ fileNameDataList.constBegin();
+ while (fileNameIt != fileNameDataList.constEnd()) {
+ d->query->prepare(QLatin1String("INSERT INTO FileNameTable "
+ "(FolderId, Name, FileId, Title) VALUES (?, ?, ?, ?)"));
+ d->query->bindValue(0, 1);
+ d->query->bindValue(1, (*fileNameIt).name);
+ d->query->bindValue(2, (*fileNameIt).fileId);
+ d->query->bindValue(3, (*fileNameIt).title);
+ d->query->exec();
+ ++fileNameIt;
+ }
+ d->query->exec(QLatin1String("COMMIT"));
+ }
+
+ d->query->exec(QLatin1String("SELECT MAX(Id) FROM FileDataTable"));
+ if (d->query->next()
+ && d->query->value(0).toInt() == tableFileId-1) {
+ addProgress(d->fileStep*(i%20));
+ return true;
+ }
+ return false;
+}
+
+bool QHelpGenerator::registerCustomFilter(const QString &filterName,
+ const QStringList &filterAttribs, bool forceUpdate)
+{
+ if (!d->query)
+ return false;
+
+ d->query->exec(QLatin1String("SELECT Id, Name FROM FilterAttributeTable"));
+ QStringList idsToInsert = filterAttribs;
+ QMap<QString, int> attributeMap;
+ while (d->query->next()) {
+ attributeMap.insert(d->query->value(1).toString(),
+ d->query->value(0).toInt());
+ idsToInsert.removeAll(d->query->value(1).toString());
+ }
+
+ foreach (const QString &id, idsToInsert) {
+ d->query->prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ d->query->bindValue(0, id);
+ d->query->exec();
+ attributeMap.insert(id, d->query->lastInsertId().toInt());
+ }
+
+ int nameId = -1;
+ d->query->prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
+ d->query->bindValue(0, filterName);
+ d->query->exec();
+ while (d->query->next()) {
+ nameId = d->query->value(0).toInt();
+ break;
+ }
+
+ if (nameId < 0) {
+ d->query->prepare(QLatin1String("INSERT INTO FilterNameTable VALUES(NULL, ?)"));
+ d->query->bindValue(0, filterName);
+ if (d->query->exec())
+ nameId = d->query->lastInsertId().toInt();
+ } else if (!forceUpdate) {
+ d->error = tr("The filter %1 is already registered!").arg(filterName);
+ return false;
+ }
+
+ if (nameId < 0) {
+ d->error = tr("Cannot register filter %1!").arg(filterName);
+ return false;
+ }
+
+ d->query->prepare(QLatin1String("DELETE FROM FilterTable WHERE NameId=?"));
+ d->query->bindValue(0, nameId);
+ d->query->exec();
+
+ foreach (const QString &att, filterAttribs) {
+ d->query->prepare(QLatin1String("INSERT INTO FilterTable VALUES(?, ?)"));
+ d->query->bindValue(0, nameId);
+ d->query->bindValue(1, attributeMap[att]);
+ if (!d->query->exec())
+ return false;
+ }
+ return true;
+}
+
+bool QHelpGenerator::insertKeywords(const QList<QHelpDataIndexItem> &keywords,
+ const QStringList &filterAttributes)
+{
+ if (!d->query)
+ return false;
+
+ emit statusChanged(tr("Insert indices..."));
+ int indexId = 1;
+ d->query->exec(QLatin1String("SELECT MAX(Id) FROM IndexTable"));
+ if (d->query->next())
+ indexId = d->query->value(0).toInt() + 1;
+
+ QList<int> filterAtts;
+ foreach (const QString &filterAtt, filterAttributes) {
+ d->query->prepare(QLatin1String("SELECT Id FROM FilterAttributeTable WHERE Name=?"));
+ d->query->bindValue(0, filterAtt);
+ d->query->exec();
+ if (d->query->next())
+ filterAtts.append(d->query->value(0).toInt());
+ }
+
+ int pos = -1;
+ QString fileName;
+ QString anchor;
+ QString fName;
+ int fileId = 1;
+ QList<int> indexFilterTable;
+
+ int i = 0;
+ d->query->exec(QLatin1String("BEGIN"));
+ QSet<QString> indices;
+ foreach (const QHelpDataIndexItem &itm, keywords) {
+ // Identical ids make no sense and just confuse the Assistant user,
+ // so we ignore all repetitions.
+ if (indices.contains(itm.identifier))
+ continue;
+
+ // Still empty ids should be ignored, as otherwise we will include only
+ // the first keyword with an empty id.
+ if (!itm.identifier.isEmpty())
+ indices.insert(itm.identifier);
+
+ pos = itm.reference.indexOf(QLatin1Char('#'));
+ fileName = itm.reference.left(pos);
+ if (pos > -1)
+ anchor = itm.reference.mid(pos+1);
+ else
+ anchor.clear();
+
+ fName = QDir::cleanPath(fileName);
+ if (fName.startsWith(QLatin1String("./")))
+ fName = fName.mid(2);
+
+ QMap<QString, int>::ConstIterator it = d->fileMap.find(fName);
+ if (it != d->fileMap.end())
+ fileId = it.value();
+ else
+ fileId = 1;
+
+ d->query->prepare(QLatin1String("INSERT INTO IndexTable (Name, Identifier, NamespaceId, FileId, Anchor) "
+ "VALUES(?, ?, ?, ?, ?)"));
+ d->query->bindValue(0, itm.name);
+ d->query->bindValue(1, itm.identifier);
+ d->query->bindValue(2, d->namespaceId);
+ d->query->bindValue(3, fileId);
+ d->query->bindValue(4, anchor);
+ d->query->exec();
+
+ indexFilterTable.append(indexId++);
+ if (++i%100 == 0)
+ addProgress(d->indexStep*100.0);
+ }
+ d->query->exec(QLatin1String("COMMIT"));
+
+ d->query->exec(QLatin1String("BEGIN"));
+ foreach (int idx, indexFilterTable) {
+ foreach (int a, filterAtts) {
+ d->query->prepare(QLatin1String("INSERT INTO IndexFilterTable (FilterAttributeId, IndexId) "
+ "VALUES(?, ?)"));
+ d->query->bindValue(0, a);
+ d->query->bindValue(1, idx);
+ d->query->exec();
+ }
+ }
+ d->query->exec(QLatin1String("COMMIT"));
+
+ d->query->exec(QLatin1String("SELECT COUNT(Id) FROM IndexTable"));
+ if (d->query->next() && d->query->value(0).toInt() >= indices.count())
+ return true;
+ return false;
+}
+
+bool QHelpGenerator::insertContents(const QByteArray &ba,
+ const QStringList &filterAttributes)
+{
+ if (!d->query)
+ return false;
+
+ emit statusChanged(tr("Insert contents..."));
+ d->query->prepare(QLatin1String("INSERT INTO ContentsTable (NamespaceId, Data) "
+ "VALUES(?, ?)"));
+ d->query->bindValue(0, d->namespaceId);
+ d->query->bindValue(1, ba);
+ d->query->exec();
+ int contentId = d->query->lastInsertId().toInt();
+ if (contentId < 1) {
+ d->error = tr("Cannot insert contents!");
+ return false;
+ }
+
+ // associate the filter attributes
+ foreach (const QString &filterAtt, filterAttributes) {
+ d->query->prepare(QLatin1String("INSERT INTO ContentsFilterTable (FilterAttributeId, ContentsId) "
+ "SELECT Id, ? FROM FilterAttributeTable WHERE Name=?"));
+ d->query->bindValue(0, contentId);
+ d->query->bindValue(1, filterAtt);
+ d->query->exec();
+ if (!d->query->isActive()) {
+ d->error = tr("Cannot register contents!");
+ return false;
+ }
+ }
+ addProgress(d->contentStep);
+ return true;
+}
+
+bool QHelpGenerator::insertFilterAttributes(const QStringList &attributes)
+{
+ if (!d->query)
+ return false;
+
+ d->query->exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
+ QSet<QString> atts;
+ while (d->query->next())
+ atts.insert(d->query->value(0).toString());
+
+ foreach (const QString &s, attributes) {
+ if (!atts.contains(s)) {
+ d->query->prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
+ d->query->bindValue(0, s);
+ d->query->exec();
+ }
+ }
+ return true;
+}
+
+bool QHelpGenerator::insertMetaData(const QMap<QString, QVariant> &metaData)
+{
+ if (!d->query)
+ return false;
+
+ QMap<QString, QVariant>::const_iterator it = metaData.constBegin();
+ while (it != metaData.constEnd()) {
+ d->query->prepare(QLatin1String("INSERT INTO MetaDataTable VALUES(?, ?)"));
+ d->query->bindValue(0, it.key());
+ d->query->bindValue(1, it.value());
+ d->query->exec();
+ ++it;
+ }
+ return true;
+}
+
+bool QHelpGenerator::checkLinks(const QHelpDataInterface &helpData)
+{
+ /*
+ * Step 1: Gather the canoncal file paths of all files in the project.
+ * We use a set, because there will be a lot of look-ups.
+ */
+ QSet<QString> files;
+ foreach (const QHelpDataFilterSection &filterSection, helpData.filterSections()) {
+ foreach (const QString &file, filterSection.files()) {
+ QFileInfo fileInfo(helpData.rootPath() + QDir::separator() + file);
+ const QString &canonicalFileName = fileInfo.canonicalFilePath();
+ if (!fileInfo.exists())
+ emit warning(tr("File '%1' does not exist.").arg(file));
+ else
+ files.insert(canonicalFileName);
+ }
+ }
+
+ /*
+ * Step 2: Check the hypertext and image references of all HTML files.
+ * Note that we don't parse the files, but simply grep for the
+ * respective HTML elements. Therefore. contents that are e.g.
+ * commented out can cause false warning.
+ */
+ bool allLinksOk = true;
+ foreach (const QString &fileName, files) {
+ if (!fileName.endsWith(QLatin1String("html"))
+ && !fileName.endsWith(QLatin1String("htm")))
+ continue;
+ QFile htmlFile(fileName);
+ if (!htmlFile.open(QIODevice::ReadOnly)) {
+ emit warning(tr("File '%1' cannot be opened.").arg(fileName));
+ continue;
+ }
+ const QRegExp linkPattern(QLatin1String("<(?:a href|img src)=\"?([^#\">]+)[#\">]"));
+ QTextStream stream(&htmlFile);
+ const QString codec = QHelpGlobal::codecFromData(htmlFile.read(1000));
+ stream.setCodec(QTextCodec::codecForName(codec.toLatin1().constData()));
+ const QString &content = stream.readAll();
+ QStringList invalidLinks;
+ for (int pos = linkPattern.indexIn(content); pos != -1;
+ pos = linkPattern.indexIn(content, pos + 1)) {
+ const QString& linkedFileName = linkPattern.cap(1);
+ if (linkedFileName.contains(QLatin1String("://")))
+ continue;
+ const QString curDir = QFileInfo(fileName).dir().path();
+ const QString &canonicalLinkedFileName =
+ QFileInfo(curDir + QDir::separator() + linkedFileName).canonicalFilePath();
+ if (!files.contains(canonicalLinkedFileName)
+ && !invalidLinks.contains(canonicalLinkedFileName)) {
+ emit warning(tr("File '%1' contains an invalid link to file '%2'").
+ arg(fileName).arg(linkedFileName));
+ allLinksOk = false;
+ invalidLinks.append(canonicalLinkedFileName);
+ }
+ }
+ }
+
+ if (!allLinksOk)
+ d->error = tr("Invalid links in HTML files.");
+ return allLinksOk;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/assistant/lib/qhelpgenerator_p.h b/src/assistant/lib/qhelpgenerator_p.h
new file mode 100644
index 000000000..ad32c05de
--- /dev/null
+++ b/src/assistant/lib/qhelpgenerator_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPGENERATOR_H
+#define QHELPGENERATOR_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelp_global.h"
+#include "qhelpdatainterface_p.h"
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QHelpGeneratorPrivate;
+
+class QHELP_EXPORT QHelpGenerator : public QObject
+{
+ Q_OBJECT
+
+public:
+ QHelpGenerator(QObject *parent = 0);
+ ~QHelpGenerator();
+
+ bool generate(QHelpDataInterface *helpData,
+ const QString &outputFileName);
+ bool checkLinks(const QHelpDataInterface &helpData);
+ QString error() const;
+
+Q_SIGNALS:
+ void statusChanged(const QString &msg);
+ void progressChanged(double progress);
+ void warning(const QString &msg);
+
+private:
+ struct FileNameTableData
+ {
+ QString name;
+ int fileId;
+ QString title;
+ };
+
+ void writeTree(QDataStream &s, QHelpDataContentItem *item, int depth);
+ bool createTables();
+ bool insertFileNotFoundFile();
+ bool registerCustomFilter(const QString &filterName,
+ const QStringList &filterAttribs, bool forceUpdate = false);
+ bool registerVirtualFolder(const QString &folderName, const QString &ns);
+ bool insertFilterAttributes(const QStringList &attributes);
+ bool insertKeywords(const QList<QHelpDataIndexItem> &keywords,
+ const QStringList &filterAttributes);
+ bool insertFiles(const QStringList &files, const QString &rootPath,
+ const QStringList &filterAttributes);
+ bool insertContents(const QByteArray &ba,
+ const QStringList &filterAttributes);
+ bool insertMetaData(const QMap<QString, QVariant> &metaData);
+ void cleanupDB();
+ void setupProgress(QHelpDataInterface *helpData);
+ void addProgress(double step);
+
+ QHelpGeneratorPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/assistant/lib/qhelpindexwidget.cpp b/src/assistant/lib/qhelpindexwidget.cpp
new file mode 100644
index 000000000..82d402442
--- /dev/null
+++ b/src/assistant/lib/qhelpindexwidget.cpp
@@ -0,0 +1,444 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpindexwidget.h"
+#include "qhelpenginecore.h"
+#include "qhelpengine_p.h"
+#include "qhelpdbreader_p.h"
+
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtGui/QListView>
+#include <QtGui/QHeaderView>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpIndexProvider : public QThread
+{
+public:
+ QHelpIndexProvider(QHelpEnginePrivate *helpEngine);
+ ~QHelpIndexProvider();
+ void collectIndices(const QString &customFilterName);
+ void stopCollecting();
+ QStringList indices() const;
+ QList<QHelpDBReader*> activeReaders() const;
+ QSet<int> indexIds(QHelpDBReader *reader) const;
+
+private:
+ void run();
+
+ QHelpEnginePrivate *m_helpEngine;
+ QStringList m_indices;
+ QList<QHelpDBReader*> m_activeReaders;
+ QMap<QHelpDBReader*, QSet<int> > m_indexIds;
+ QStringList m_filterAttributes;
+ mutable QMutex m_mutex;
+ bool m_abort;
+};
+
+class QHelpIndexModelPrivate
+{
+public:
+ QHelpIndexModelPrivate(QHelpEnginePrivate *hE)
+ {
+ helpEngine = hE;
+ indexProvider = new QHelpIndexProvider(helpEngine);
+ insertedRows = 0;
+ }
+
+ QHelpEnginePrivate *helpEngine;
+ QHelpIndexProvider *indexProvider;
+ QStringList indices;
+ int insertedRows;
+ QString currentFilter;
+ QList<QHelpDBReader*> activeReaders;
+};
+
+static bool caseInsensitiveLessThan(const QString &as, const QString &bs)
+{
+ return QString::compare(as, bs, Qt::CaseInsensitive) < 0;
+}
+
+QHelpIndexProvider::QHelpIndexProvider(QHelpEnginePrivate *helpEngine)
+ : QThread(helpEngine)
+{
+ m_helpEngine = helpEngine;
+ m_abort = false;
+}
+
+QHelpIndexProvider::~QHelpIndexProvider()
+{
+ stopCollecting();
+}
+
+void QHelpIndexProvider::collectIndices(const QString &customFilterName)
+{
+ m_mutex.lock();
+ m_filterAttributes = m_helpEngine->q->filterAttributes(customFilterName);
+ m_mutex.unlock();
+ if (!isRunning()) {
+ start(LowPriority);
+ } else {
+ stopCollecting();
+ start(LowPriority);
+ }
+}
+
+void QHelpIndexProvider::stopCollecting()
+{
+ if (!isRunning())
+ return;
+ m_mutex.lock();
+ m_abort = true;
+ m_mutex.unlock();
+ wait();
+ m_abort = false;
+}
+
+QStringList QHelpIndexProvider::indices() const
+{
+ QMutexLocker lck(&m_mutex);
+ return m_indices;
+}
+
+QList<QHelpDBReader*> QHelpIndexProvider::activeReaders() const
+{
+ QMutexLocker lck(&m_mutex);
+ return m_activeReaders;
+}
+
+QSet<int> QHelpIndexProvider::indexIds(QHelpDBReader *reader) const
+{
+ QMutexLocker lck(&m_mutex);
+ if (m_indexIds.contains(reader))
+ return m_indexIds.value(reader);
+ return QSet<int>();
+}
+
+void QHelpIndexProvider::run()
+{
+ m_mutex.lock();
+ QStringList atts = m_filterAttributes;
+ m_indices.clear();
+ m_activeReaders.clear();
+ QSet<QString> indicesSet;
+ m_mutex.unlock();
+
+ foreach (const QString &dbFileName, m_helpEngine->fileNameReaderMap.keys()) {
+ m_mutex.lock();
+ if (m_abort) {
+ m_mutex.unlock();
+ return;
+ }
+ m_mutex.unlock();
+ QHelpDBReader reader(dbFileName,
+ QHelpGlobal::uniquifyConnectionName(dbFileName +
+ QLatin1String("FromIndexProvider"),
+ QThread::currentThread()), 0);
+ if (!reader.init())
+ continue;
+ QStringList lst = reader.indicesForFilter(atts);
+ if (!lst.isEmpty()) {
+ m_mutex.lock();
+ foreach (const QString &s, lst)
+ indicesSet.insert(s);
+ if (m_abort) {
+ m_mutex.unlock();
+ return;
+ }
+ QHelpDBReader *orgReader = m_helpEngine->fileNameReaderMap.value(dbFileName);
+ m_indexIds.insert(orgReader, reader.indexIds(atts));
+ m_activeReaders.append(orgReader);
+ m_mutex.unlock();
+ }
+ }
+ m_mutex.lock();
+ m_indices = indicesSet.values();
+ qSort(m_indices.begin(), m_indices.end(), caseInsensitiveLessThan);
+ m_mutex.unlock();
+}
+
+
+
+/*!
+ \class QHelpIndexModel
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpIndexModel class provides a model that
+ supplies index keywords to views.
+
+
+*/
+
+/*!
+ \fn void QHelpIndexModel::indexCreationStarted()
+
+ This signal is emitted when the creation of a new index
+ has started. The current index is invalid from this
+ point on until the signal indexCreated() is emitted.
+
+ \sa isCreatingIndex()
+*/
+
+/*!
+ \fn void QHelpIndexModel::indexCreated()
+
+ This signal is emitted when the index has been created.
+*/
+
+QHelpIndexModel::QHelpIndexModel(QHelpEnginePrivate *helpEngine)
+ : QStringListModel(helpEngine)
+{
+ d = new QHelpIndexModelPrivate(helpEngine);
+
+ connect(d->indexProvider, SIGNAL(finished()), this, SLOT(insertIndices()));
+ connect(helpEngine->q, SIGNAL(setupStarted()), this, SLOT(invalidateIndex()));
+}
+
+QHelpIndexModel::~QHelpIndexModel()
+{
+ delete d;
+}
+
+void QHelpIndexModel::invalidateIndex(bool onShutDown)
+{
+ if (onShutDown)
+ disconnect(this, SLOT(insertIndices()));
+ d->indexProvider->stopCollecting();
+ d->indices.clear();
+ if (!onShutDown)
+ filter(QString());
+}
+
+/*!
+ Creates a new index by querying the help system for
+ keywords for the specified \a customFilterName.
+*/
+void QHelpIndexModel::createIndex(const QString &customFilterName)
+{
+ d->currentFilter = customFilterName;
+ d->indexProvider->collectIndices(customFilterName);
+ emit indexCreationStarted();
+}
+
+void QHelpIndexModel::insertIndices()
+{
+ d->indices = d->indexProvider->indices();
+ d->activeReaders = d->indexProvider->activeReaders();
+ QStringList attributes = d->helpEngine->q->filterAttributes(d->currentFilter);
+ if (attributes.count() > 1) {
+ foreach (QHelpDBReader *r, d->activeReaders)
+ r->createAttributesCache(attributes, d->indexProvider->indexIds(r));
+ }
+ filter(QString());
+ emit indexCreated();
+}
+
+/*!
+ Returns true if the index is currently built up, otherwise
+ false.
+*/
+bool QHelpIndexModel::isCreatingIndex() const
+{
+ return d->indexProvider->isRunning();
+}
+
+/*!
+ Returns all hits found for the \a keyword. A hit consists of
+ the URL and the document title.
+*/
+QMap<QString, QUrl> QHelpIndexModel::linksForKeyword(const QString &keyword) const
+{
+ QMap<QString, QUrl> linkMap;
+ QStringList filterAttributes = d->helpEngine->q->filterAttributes(d->currentFilter);
+ foreach (QHelpDBReader *reader, d->activeReaders)
+ reader->linksForKeyword(keyword, filterAttributes, linkMap);
+ return linkMap;
+}
+
+/*!
+ Filters the indices and returns the model index of the best
+ matching keyword. In a first step, only the keywords containing
+ \a filter are kept in the model's index list. Analogously, if
+ \a wildcard is not empty, only the keywords matched are left
+ in the index list. In a second step, the best match is
+ determined and its index model returned. When specifying a
+ wildcard expression, the \a filter string is used to
+ search for the best match.
+*/
+QModelIndex QHelpIndexModel::filter(const QString &filter, const QString &wildcard)
+{
+ if (filter.isEmpty()) {
+ setStringList(d->indices);
+ return index(-1, 0, QModelIndex());
+ }
+
+ QStringList lst;
+ int goodMatch = -1;
+ int perfectMatch = -1;
+
+ if (!wildcard.isEmpty()) {
+ QRegExp regExp(wildcard, Qt::CaseInsensitive);
+ regExp.setPatternSyntax(QRegExp::Wildcard);
+ foreach (const QString &index, d->indices) {
+ if (index.contains(regExp)) {
+ lst.append(index);
+ if (perfectMatch == -1 && index.startsWith(filter, Qt::CaseInsensitive)) {
+ if (goodMatch == -1)
+ goodMatch = lst.count()-1;
+ if (filter.length() == index.length()){
+ perfectMatch = lst.count()-1;
+ }
+ } else if (perfectMatch > -1 && index == filter) {
+ perfectMatch = lst.count()-1;
+ }
+ }
+ }
+ } else {
+ foreach (const QString &index, d->indices) {
+ if (index.contains(filter, Qt::CaseInsensitive)) {
+ lst.append(index);
+ if (perfectMatch == -1 && index.startsWith(filter, Qt::CaseInsensitive)) {
+ if (goodMatch == -1)
+ goodMatch = lst.count()-1;
+ if (filter.length() == index.length()){
+ perfectMatch = lst.count()-1;
+ }
+ } else if (perfectMatch > -1 && index == filter) {
+ perfectMatch = lst.count()-1;
+ }
+ }
+ }
+
+ }
+
+ if (perfectMatch == -1)
+ perfectMatch = qMax(0, goodMatch);
+
+ setStringList(lst);
+ return index(perfectMatch, 0, QModelIndex());
+}
+
+
+
+/*!
+ \class QHelpIndexWidget
+ \inmodule QtHelp
+ \since 4.4
+ \brief The QHelpIndexWidget class provides a list view
+ displaying the QHelpIndexModel.
+*/
+
+/*!
+ \fn void QHelpIndexWidget::linkActivated(const QUrl &link,
+ const QString &keyword)
+
+ This signal is emitted when an item is activated and its
+ associated \a link should be shown. To know where the link
+ belongs to, the \a keyword is given as a second paremeter.
+*/
+
+/*!
+ \fn void QHelpIndexWidget::linksActivated(const QMap<QString, QUrl> &links,
+ const QString &keyword)
+
+ This signal is emitted when the item representing the \a keyword
+ is activated and the item has more than one link associated.
+ The \a links consist of the document title and their URL.
+*/
+
+QHelpIndexWidget::QHelpIndexWidget()
+ : QListView(0)
+{
+ setEditTriggers(QAbstractItemView::NoEditTriggers);
+ setUniformItemSizes(true);
+ connect(this, SIGNAL(activated(QModelIndex)),
+ this, SLOT(showLink(QModelIndex)));
+}
+
+void QHelpIndexWidget::showLink(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return;
+
+ QHelpIndexModel *indexModel = qobject_cast<QHelpIndexModel*>(model());
+ if (!indexModel)
+ return;
+ QVariant v = indexModel->data(index, Qt::DisplayRole);
+ QString name;
+ if (v.isValid())
+ name = v.toString();
+
+ QMap<QString, QUrl> links = indexModel->linksForKeyword(name);
+ if (links.count() == 1) {
+ emit linkActivated(links.constBegin().value(), name);
+ } else if (links.count() > 1) {
+ emit linksActivated(links, name);
+ }
+}
+
+/*!
+ Activates the current item which will result eventually in
+ the emitting of a linkActivated() or linksActivated()
+ signal.
+*/
+void QHelpIndexWidget::activateCurrentItem()
+{
+ showLink(currentIndex());
+}
+
+/*!
+ Filters the indices according to \a filter or \a wildcard.
+ The item with the best match is set as current item.
+
+ \sa QHelpIndexModel::filter()
+*/
+void QHelpIndexWidget::filterIndices(const QString &filter, const QString &wildcard)
+{
+ QHelpIndexModel *indexModel = qobject_cast<QHelpIndexModel*>(model());
+ if (!indexModel)
+ return;
+ QModelIndex idx = indexModel->filter(filter, wildcard);
+ if (idx.isValid())
+ setCurrentIndex(idx);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpindexwidget.h b/src/assistant/lib/qhelpindexwidget.h
new file mode 100644
index 000000000..0c4d307aa
--- /dev/null
+++ b/src/assistant/lib/qhelpindexwidget.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPINDEXWIDGET_H
+#define QHELPINDEXWIDGET_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QUrl>
+#include <QtGui/QStringListModel>
+#include <QtGui/QListView>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpEnginePrivate;
+class QHelpIndexModelPrivate;
+
+class QHELP_EXPORT QHelpIndexModel : public QStringListModel
+{
+ Q_OBJECT
+
+public:
+ void createIndex(const QString &customFilterName);
+ QModelIndex filter(const QString &filter,
+ const QString &wildcard = QString());
+
+ QMap<QString, QUrl> linksForKeyword(const QString &keyword) const;
+ bool isCreatingIndex() const;
+
+Q_SIGNALS:
+ void indexCreationStarted();
+ void indexCreated();
+
+private Q_SLOTS:
+ void insertIndices();
+ void invalidateIndex(bool onShutDown = false);
+
+private:
+ QHelpIndexModel(QHelpEnginePrivate *helpEngine);
+ ~QHelpIndexModel();
+
+ QHelpIndexModelPrivate *d;
+ friend class QHelpEnginePrivate;
+};
+
+class QHELP_EXPORT QHelpIndexWidget : public QListView
+{
+ Q_OBJECT
+
+Q_SIGNALS:
+ void linkActivated(const QUrl &link, const QString &keyword);
+ void linksActivated(const QMap<QString, QUrl> &links,
+ const QString &keyword);
+
+public Q_SLOTS:
+ void filterIndices(const QString &filter,
+ const QString &wildcard = QString());
+ void activateCurrentItem();
+
+private Q_SLOTS:
+ void showLink(const QModelIndex &index);
+
+private:
+ QHelpIndexWidget();
+ friend class QHelpEngine;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/assistant/lib/qhelpprojectdata.cpp b/src/assistant/lib/qhelpprojectdata.cpp
new file mode 100644
index 000000000..bd59e289c
--- /dev/null
+++ b/src/assistant/lib/qhelpprojectdata.cpp
@@ -0,0 +1,450 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpprojectdata_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QStack>
+#include <QtCore/QMap>
+#include <QtCore/QRegExp>
+#include <QtCore/QUrl>
+#include <QtCore/QVariant>
+#include <QtXml/QXmlStreamReader>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpProjectDataPrivate : public QXmlStreamReader
+{
+public:
+ void readData(const QByteArray &contents);
+
+ QString virtualFolder;
+ QString namespaceName;
+ QString rootPath;
+
+ QStringList fileList;
+ QList<QHelpDataCustomFilter> customFilterList;
+ QList<QHelpDataFilterSection> filterSectionList;
+ QMap<QString, QVariant> metaData;
+
+ QString errorMsg;
+
+private:
+ void readProject();
+ void readCustomFilter();
+ void readFilterSection();
+ void readTOC();
+ void readKeywords();
+ void readFiles();
+ void raiseUnknownTokenError();
+ void addMatchingFiles(const QString &pattern);
+ bool hasValidSyntax(const QString &nameSpace, const QString &vFolder) const;
+
+ QMap<QString, QStringList> dirEntriesCache;
+};
+
+void QHelpProjectDataPrivate::raiseUnknownTokenError()
+{
+ raiseError(QCoreApplication::translate("QHelpProject", "Unknown token."));
+}
+
+void QHelpProjectDataPrivate::readData(const QByteArray &contents)
+{
+ addData(contents);
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("QtHelpProject")
+ && attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
+ readProject();
+ else
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Unknown token. Expected \"QtHelpProject\"!"));
+ }
+ }
+
+ if (hasError()) {
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Error in line %1: %2").arg(lineNumber())
+ .arg(errorString()));
+ }
+}
+
+void QHelpProjectDataPrivate::readProject()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("virtualFolder")) {
+ virtualFolder = readElementText();
+ if (!hasValidSyntax(QLatin1String("test"), virtualFolder))
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Virtual folder has invalid syntax."));
+ } else if (name() == QLatin1String("namespace")) {
+ namespaceName = readElementText();
+ if (!hasValidSyntax(namespaceName, QLatin1String("test")))
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Namespace has invalid syntax."));
+ } else if (name() == QLatin1String("customFilter")) {
+ readCustomFilter();
+ } else if (name() == QLatin1String("filterSection")) {
+ readFilterSection();
+ } else if (name() == QLatin1String("metaData")) {
+ QString n = attributes().value(QLatin1String("name")).toString();
+ if (!metaData.contains(n))
+ metaData[n]
+ = attributes().value(QLatin1String("value")).toString();
+ else
+ metaData.insert(n, attributes().
+ value(QLatin1String("value")).toString());
+ } else {
+ raiseUnknownTokenError();
+ }
+ } else if (isEndElement() && name() == QLatin1String("QtHelpProject")) {
+ if (namespaceName.isEmpty())
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Missing namespace in QtHelpProject."));
+ else if (virtualFolder.isEmpty())
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Missing virtual folder in QtHelpProject"));
+ break;
+ }
+ }
+}
+
+void QHelpProjectDataPrivate::readCustomFilter()
+{
+ QHelpDataCustomFilter filter;
+ filter.name = attributes().value(QLatin1String("name")).toString();
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("filterAttribute"))
+ filter.filterAttributes.append(readElementText());
+ else
+ raiseUnknownTokenError();
+ } else if (isEndElement() && name() == QLatin1String("customFilter")) {
+ break;
+ }
+ }
+ customFilterList.append(filter);
+}
+
+void QHelpProjectDataPrivate::readFilterSection()
+{
+ filterSectionList.append(QHelpDataFilterSection());
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("filterAttribute"))
+ filterSectionList.last().addFilterAttribute(readElementText());
+ else if (name() == QLatin1String("toc"))
+ readTOC();
+ else if (name() == QLatin1String("keywords"))
+ readKeywords();
+ else if (name() == QLatin1String("files"))
+ readFiles();
+ else
+ raiseUnknownTokenError();
+ } else if (isEndElement() && name() == QLatin1String("filterSection")) {
+ break;
+ }
+ }
+}
+
+void QHelpProjectDataPrivate::readTOC()
+{
+ QStack<QHelpDataContentItem*> contentStack;
+ QHelpDataContentItem *itm = 0;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("section")) {
+ QString title = attributes().value(QLatin1String("title")).toString();
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ if (contentStack.isEmpty()) {
+ itm = new QHelpDataContentItem(0, title, ref);
+ filterSectionList.last().addContent(itm);
+ } else {
+ itm = new QHelpDataContentItem(contentStack.top(), title, ref);
+ }
+ contentStack.push(itm);
+ } else {
+ raiseUnknownTokenError();
+ }
+ } else if (isEndElement()) {
+ if (name() == QLatin1String("section")) {
+ contentStack.pop();
+ continue;
+ } else if (name() == QLatin1String("toc") && contentStack.isEmpty()) {
+ break;
+ } else {
+ raiseUnknownTokenError();
+ }
+ }
+ }
+}
+
+void QHelpProjectDataPrivate::readKeywords()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("keyword")) {
+ if (attributes().value(QLatin1String("ref")).toString().isEmpty()
+ || (attributes().value(QLatin1String("name")).toString().isEmpty()
+ && attributes().value(QLatin1String("id")).toString().isEmpty()))
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Missing attribute in keyword at line %1.")
+ .arg(lineNumber()));
+ filterSectionList.last()
+ .addIndex(QHelpDataIndexItem(attributes().
+ value(QLatin1String("name")).toString(),
+ attributes().value(QLatin1String("id")).toString(),
+ attributes().value(QLatin1String("ref")).toString()));
+ } else {
+ raiseUnknownTokenError();
+ }
+ } else if (isEndElement()) {
+ if (name() == QLatin1String("keyword"))
+ continue;
+ else if (name() == QLatin1String("keywords"))
+ break;
+ else
+ raiseUnknownTokenError();
+ }
+ }
+}
+
+void QHelpProjectDataPrivate::readFiles()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file"))
+ addMatchingFiles(readElementText());
+ else
+ raiseUnknownTokenError();
+ } else if (isEndElement()) {
+ if (name() == QLatin1String("file"))
+ continue;
+ else if (name() == QLatin1String("files"))
+ break;
+ else
+ raiseUnknownTokenError();
+ }
+ }
+}
+
+// Expand file pattern and add matches into list. If the pattern does not match
+// any files, insert the pattern itself so the QHelpGenerator will emit a
+// meaningful warning later.
+void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern)
+{
+ // The pattern matching is expensive, so we skip it if no
+ // wildcard symbols occur in the string.
+ if (!pattern.contains('?') && !pattern.contains('*')
+ && !pattern.contains('[') && !pattern.contains(']')) {
+ filterSectionList.last().addFile(pattern);
+ return;
+ }
+
+ QFileInfo fileInfo(rootPath + '/' + pattern);
+ const QDir &dir = fileInfo.dir();
+ const QString &path = dir.canonicalPath();
+
+ // QDir::entryList() is expensive, so we cache the results.
+ QMap<QString, QStringList>::ConstIterator it = dirEntriesCache.find(path);
+ const QStringList &entries = it != dirEntriesCache.constEnd() ?
+ it.value() : dir.entryList(QDir::Files);
+ if (it == dirEntriesCache.constEnd())
+ dirEntriesCache.insert(path, entries);
+
+ bool matchFound = false;
+#ifdef Q_OS_WIN
+ Qt::CaseSensitivity cs = Qt::CaseInsensitive;
+#else
+ Qt::CaseSensitivity cs = Qt::CaseSensitive;
+#endif
+ QRegExp regExp(fileInfo.fileName(), cs, QRegExp::Wildcard);
+ foreach (const QString &file, entries) {
+ if (regExp.exactMatch(file)) {
+ matchFound = true;
+ filterSectionList.last().
+ addFile(QFileInfo(pattern).dir().path() + '/' + file);
+ }
+ }
+ if (!matchFound)
+ filterSectionList.last().addFile(pattern);
+}
+
+bool QHelpProjectDataPrivate::hasValidSyntax(const QString &nameSpace,
+ const QString &vFolder) const
+{
+ const QLatin1Char slash('/');
+ if (nameSpace.contains(slash) || vFolder.contains(slash))
+ return false;
+ QUrl url;
+ const QLatin1String scheme("qthelp");
+ url.setScheme(scheme);
+ const QString canonicalNamespace = nameSpace.toLower();
+ url.setHost(canonicalNamespace);
+ url.setPath(vFolder);
+
+ const QString expectedUrl(scheme + QLatin1String("://")
+ + canonicalNamespace + slash + vFolder);
+ return url.isValid() && url.toString() == expectedUrl;
+}
+
+/*!
+ \internal
+ \class QHelpProjectData
+ \since 4.4
+ \brief The QHelpProjectData class stores all information found
+ in a Qt help project file.
+
+ The structure is filled with data by calling readData(). The
+ specified file has to have the Qt help project file format in
+ order to be read successfully. Possible reading errors can be
+ retrieved by calling errorMessage().
+*/
+
+/*!
+ Constructs a Qt help project data structure.
+*/
+QHelpProjectData::QHelpProjectData()
+{
+ d = new QHelpProjectDataPrivate;
+}
+
+/*!
+ Destroys the help project data.
+*/
+QHelpProjectData::~QHelpProjectData()
+{
+ delete d;
+}
+
+/*!
+ Reads the file \a fileName and stores the help data. The file has to
+ have the Qt help project file format. Returns true if the file
+ was successfully read, otherwise false.
+
+ \sa errorMessage()
+*/
+bool QHelpProjectData::readData(const QString &fileName)
+{
+ d->rootPath = QFileInfo(fileName).absolutePath();
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ d->errorMsg = QCoreApplication::translate("QHelpProject",
+ "The input file %1 could not be opened!").arg(fileName);
+ return false;
+ }
+
+ d->readData(file.readAll());
+ return !d->hasError();
+}
+
+/*!
+ Returns an error message if the reading of the Qt help project
+ file failed. Otherwise, an empty QString is returned.
+
+ \sa readData()
+*/
+QString QHelpProjectData::errorMessage() const
+{
+ if (d->hasError())
+ return d->errorString();
+ return d->errorMsg;
+}
+
+/*!
+ \internal
+*/
+QString QHelpProjectData::namespaceName() const
+{
+ return d->namespaceName;
+}
+
+/*!
+ \internal
+*/
+QString QHelpProjectData::virtualFolder() const
+{
+ return d->virtualFolder;
+}
+
+/*!
+ \internal
+*/
+QList<QHelpDataCustomFilter> QHelpProjectData::customFilters() const
+{
+ return d->customFilterList;
+}
+
+/*!
+ \internal
+*/
+QList<QHelpDataFilterSection> QHelpProjectData::filterSections() const
+{
+ return d->filterSectionList;
+}
+
+/*!
+ \internal
+*/
+QMap<QString, QVariant> QHelpProjectData::metaData() const
+{
+ return d->metaData;
+}
+
+/*!
+ \internal
+*/
+QString QHelpProjectData::rootPath() const
+{
+ return d->rootPath;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpprojectdata_p.h b/src/assistant/lib/qhelpprojectdata_p.h
new file mode 100644
index 000000000..64ae32505
--- /dev/null
+++ b/src/assistant/lib/qhelpprojectdata_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPPROJECTDATA_H
+#define QHELPPROJECTDATA_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelp_global.h"
+#include "qhelpdatainterface_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QHelpProjectDataPrivate;
+
+class QHELP_EXPORT QHelpProjectData : public QHelpDataInterface
+{
+public:
+ QHelpProjectData();
+ ~QHelpProjectData();
+
+ bool readData(const QString &fileName);
+ QString errorMessage() const;
+
+ QString namespaceName() const;
+ QString virtualFolder() const;
+ QList<QHelpDataCustomFilter> customFilters() const;
+ QList<QHelpDataFilterSection> filterSections() const;
+ QMap<QString, QVariant> metaData() const;
+ QString rootPath() const;
+
+private:
+ QHelpProjectDataPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/assistant/lib/qhelpsearchengine.cpp b/src/assistant/lib/qhelpsearchengine.cpp
new file mode 100644
index 000000000..f8f8acf44
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchengine.cpp
@@ -0,0 +1,450 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpenginecore.h"
+#include "qhelpsearchengine.h"
+#include "qhelpsearchquerywidget.h"
+#include "qhelpsearchresultwidget.h"
+
+#include "qhelpsearchindexreader_p.h"
+#if defined(QT_CLUCENE_SUPPORT)
+# include "qhelpsearchindexreader_clucene_p.h"
+# include "qhelpsearchindexwriter_clucene_p.h"
+#else
+# include "qhelpsearchindexreader_default_p.h"
+# include "qhelpsearchindexwriter_default_p.h"
+#endif
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QVariant>
+#include <QtCore/QThread>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_CLUCENE_SUPPORT)
+ using namespace fulltextsearch::clucene;
+#else
+ using namespace fulltextsearch::std;
+#endif
+
+class QHelpSearchEnginePrivate : public QObject
+{
+ Q_OBJECT
+
+signals:
+ void indexingStarted();
+ void indexingFinished();
+
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+private:
+ QHelpSearchEnginePrivate(QHelpEngineCore *helpEngine)
+ : queryWidget(0)
+ , resultWidget(0)
+ , helpEngine(helpEngine)
+ {
+ indexReader = 0;
+ indexWriter = 0;
+ }
+
+ ~QHelpSearchEnginePrivate()
+ {
+ delete indexReader;
+ delete indexWriter;
+ }
+
+ int hitCount() const
+ {
+ int count = 0;
+ if (indexReader)
+ count = indexReader->hitCount();
+
+ return count;
+ }
+
+ QList<QHelpSearchEngine::SearchHit> hits(int start, int end) const
+ {
+ return indexReader ?
+ indexReader->hits(start, end) :
+ QList<QHelpSearchEngine::SearchHit>();
+ }
+
+ void updateIndex(bool reindex = false)
+ {
+ if (helpEngine.isNull())
+ return;
+
+ if (!QFile::exists(QFileInfo(helpEngine->collectionFile()).path()))
+ return;
+
+ if (!indexWriter) {
+ indexWriter = new QHelpSearchIndexWriter();
+
+ connect(indexWriter, SIGNAL(indexingStarted()), this, SIGNAL(indexingStarted()));
+ connect(indexWriter, SIGNAL(indexingFinished()), this, SIGNAL(indexingFinished()));
+ connect(indexWriter, SIGNAL(indexingFinished()), this, SLOT(optimizeIndex()));
+ }
+
+ indexWriter->cancelIndexing();
+ indexWriter->updateIndex(helpEngine->collectionFile(),
+ indexFilesFolder(), reindex);
+ }
+
+ void cancelIndexing()
+ {
+ if (indexWriter)
+ indexWriter->cancelIndexing();
+ }
+
+ void search(const QList<QHelpSearchQuery> &queryList)
+ {
+ if (helpEngine.isNull())
+ return;
+
+ if (!QFile::exists(QFileInfo(helpEngine->collectionFile()).path()))
+ return;
+
+ if (!indexReader) {
+#if defined(QT_CLUCENE_SUPPORT)
+ indexReader = new QHelpSearchIndexReaderClucene();
+#else
+ indexReader = new QHelpSearchIndexReaderDefault();
+#endif // QT_CLUCENE_SUPPORT
+ connect(indexReader, SIGNAL(searchingStarted()), this, SIGNAL(searchingStarted()));
+ connect(indexReader, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
+ }
+
+ m_queryList = queryList;
+ indexReader->cancelSearching();
+ indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), queryList);
+ }
+
+ void cancelSearching()
+ {
+ if (indexReader)
+ indexReader->cancelSearching();
+ }
+
+ QString indexFilesFolder() const
+ {
+ QString indexFilesFolder = QLatin1String(".fulltextsearch");
+ if (helpEngine && !helpEngine->collectionFile().isEmpty()) {
+ QFileInfo fi(helpEngine->collectionFile());
+ indexFilesFolder = fi.absolutePath() + QDir::separator()
+ + QLatin1Char('.')
+ + fi.fileName().left(fi.fileName().lastIndexOf(QLatin1String(".qhc")));
+ }
+ return indexFilesFolder;
+ }
+
+private slots:
+ void optimizeIndex()
+ {
+#if defined(QT_CLUCENE_SUPPORT)
+ if (indexWriter && !helpEngine.isNull()) {
+ indexWriter->optimizeIndex();
+ }
+#endif
+ }
+
+private:
+ friend class QHelpSearchEngine;
+
+ QHelpSearchQueryWidget *queryWidget;
+ QHelpSearchResultWidget *resultWidget;
+
+ fulltextsearch::QHelpSearchIndexReader *indexReader;
+ QHelpSearchIndexWriter *indexWriter;
+
+ QPointer<QHelpEngineCore> helpEngine;
+
+ QList<QHelpSearchQuery> m_queryList;
+};
+
+#include "qhelpsearchengine.moc"
+
+
+/*!
+ \class QHelpSearchQuery
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpSearchQuery class contains the field name and the associated
+ search term
+
+ The QHelpSearchQuery class contains the field name and the associated search
+ term. Depending on the field the search term might get split up into separate
+ terms to be parsed differently by the search engine.
+
+ \sa QHelpSearchQueryWidget
+*/
+
+/*!
+ \fn QHelpSearchQuery::QHelpSearchQuery()
+
+ Constructs a new empty QHelpSearchQuery.
+*/
+
+/*!
+ \fn QHelpSearchQuery::QHelpSearchQuery(FieldName field, const QStringList &wordList)
+
+ Constructs a new QHelpSearchQuery and initializes it with the given \a field and \a wordList.
+*/
+
+/*!
+ \enum QHelpSearchQuery::FieldName
+ This enum type specifies the field names that are handled by the search engine.
+
+ \value DEFAULT the default field provided by the search widget, several terms should be
+ split and stored in the word list except search terms enclosed in quotes.
+ \value FUZZY a field only provided in use with clucene. Terms should be split in separate
+ words and passed to the search engine.
+ \value WITHOUT a field only provided in use with clucene. Terms should be split in separate
+ words and passed to the search engine.
+ \value PHRASE a field only provided in use with clucene. Terms should not be split in separate
+ words.
+ \value ALL a field only provided in use with clucene. Terms should be split in separate
+ words and passed to the search engine
+ \value ATLEAST a field only provided in use with clucene. Terms should be split in separate
+ words and passed to the search engine
+*/
+
+/*!
+ \class QHelpSearchEngine
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpSearchEngine class provides access to widgets reusable
+ to integrate fulltext search as well as to index and search documentation.
+
+ Before the search engine can be used, one has to instantiate at least a
+ QHelpEngineCore object that needs to be passed to the search engines constructor.
+ This is required as the search engine needs to be connected to the help
+ engines setupFinished() signal to know when it can start to index documentation.
+
+ After starting the indexing process the signal indexingStarted() is emitted and
+ on the end of the indexing process the indexingFinished() is emitted. To stop
+ the indexing one can call cancelIndexing().
+
+ While the indexing process has finished, the search engine can now be used to search
+ thru its index for a given term. To do this one may use the possibility of creating the
+ QHelpSearchQuery list by self or reuse the QHelpSearchQueryWidget which has the inbuild
+ functionality to set up a proper search queries list that get's passed to the search engines
+ search() function.
+
+ After the list of querys has been passed to the search engine, the signal searchingStarted()
+ is emitted and after the search has finished the searchingFinished() signal is emitted. The
+ search process can be stopped by calling cancelSearching().
+
+ If the search succeeds, the searchingFinished() will be called with the search hits count,
+ which can be reused to fetch the search hits from the search engine. Calling the hits()
+ function with the range of hits you would like to get will return a list of the requested
+ SearchHits. They basically constist at the moment of a pair of strings where the values
+ of that pair are the documentation file path and the page title.
+
+ To display the given hits use the QHelpSearchResultWidget or build up your own one if you need
+ more advanced functionality. Note that the QHelpSearchResultWidget can not be instantiated
+ directly, you must retrieve the widget from the search engine in use as all connections will be
+ established for you by the widget itself.
+*/
+
+/*!
+ \fn void QHelpSearchEngine::indexingStarted()
+
+ This signal is emitted when indexing process is started.
+*/
+
+/*!
+ \fn void QHelpSearchEngine::indexingFinished()
+
+ This signal is emitted when the indexing process is complete.
+*/
+
+/*!
+ \fn void QHelpSearchEngine::searchingStarted()
+
+ This signal is emitted when the search process is started.
+*/
+
+/*!
+ \fn void QHelpSearchEngine::searchingFinished(int hits)
+
+ This signal is emitted when the search process is complete.
+ The hit count is stored in \a hits.
+*/
+
+/*!
+ Constructs a new search engine with the given \a parent. The search engine
+ uses the given \a helpEngine to access the documentation that needs to be indexed.
+ The QHelpEngine's setupFinished() signal is automatically connected to the
+ QHelpSearchEngine's indexing function, so that new documentation will be indexed
+ after the signal is emitted.
+*/
+QHelpSearchEngine::QHelpSearchEngine(QHelpEngineCore *helpEngine, QObject *parent)
+ : QObject(parent)
+{
+ d = new QHelpSearchEnginePrivate(helpEngine);
+
+ connect(helpEngine, SIGNAL(setupFinished()), this, SLOT(indexDocumentation()));
+
+ connect(d, SIGNAL(indexingStarted()), this, SIGNAL(indexingStarted()));
+ connect(d, SIGNAL(indexingFinished()), this, SIGNAL(indexingFinished()));
+ connect(d, SIGNAL(searchingStarted()), this, SIGNAL(searchingStarted()));
+ connect(d, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
+}
+
+/*!
+ Destructs the search engine.
+*/
+QHelpSearchEngine::~QHelpSearchEngine()
+{
+ delete d;
+}
+
+/*!
+ Returns a widget to use as input widget. Depending on your search engine
+ configuration you will get a different widget with more or less subwidgets.
+*/
+QHelpSearchQueryWidget* QHelpSearchEngine::queryWidget()
+{
+ if (!d->queryWidget)
+ d->queryWidget = new QHelpSearchQueryWidget();
+
+ return d->queryWidget;
+}
+
+/*!
+ Returns a widget that can hold and display the search results.
+*/
+QHelpSearchResultWidget* QHelpSearchEngine::resultWidget()
+{
+ if (!d->resultWidget)
+ d->resultWidget = new QHelpSearchResultWidget(this);
+
+ return d->resultWidget;
+}
+
+/*!
+ \obsolete
+ Returns the amount of hits the search engine found.
+ \sa hitCount()
+*/
+int QHelpSearchEngine::hitsCount() const
+{
+ return d->hitCount();
+}
+
+/*!
+ \since 4.6
+ Returns the amount of hits the search engine found.
+*/
+int QHelpSearchEngine::hitCount() const
+{
+ return d->hitCount();
+}
+
+/*!
+ \typedef QHelpSearchEngine::SearchHit
+
+ Typedef for QPair<QString, QString>.
+ The values of that pair are the documentation file path and the page title.
+
+ \sa hits()
+*/
+
+/*!
+ Returns a list of search hits within the range of \a start \a end.
+*/
+QList<QHelpSearchEngine::SearchHit> QHelpSearchEngine::hits(int start, int end) const
+{
+ return d->hits(start, end);
+}
+
+/*!
+ Returns the list of queries last searched for.
+ \since 4.5
+*/
+QList<QHelpSearchQuery> QHelpSearchEngine::query() const
+{
+ return d->m_queryList;
+}
+
+/*!
+ Forces the search engine to reindex all documentation files.
+*/
+void QHelpSearchEngine::reindexDocumentation()
+{
+ d->updateIndex(true);
+}
+
+/*!
+ Stops the indexing process.
+*/
+void QHelpSearchEngine::cancelIndexing()
+{
+ d->cancelIndexing();
+}
+
+/*!
+ Stops the search process.
+*/
+void QHelpSearchEngine::cancelSearching()
+{
+ d->cancelSearching();
+}
+
+/*!
+ Starts the search process using the given list of queries \a queryList
+ build by the search field name and the values to search for.
+*/
+void QHelpSearchEngine::search(const QList<QHelpSearchQuery> &queryList)
+{
+ d->search(queryList);
+}
+
+void QHelpSearchEngine::indexDocumentation()
+{
+ d->updateIndex();
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchengine.h b/src/assistant/lib/qhelpsearchengine.h
new file mode 100644
index 000000000..baceb7057
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchengine.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHENGINE_H
+#define QHELPSEARCHENGINE_H
+
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QMap>
+#include <QtCore/QUrl>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpEngineCore;
+class QHelpSearchQueryWidget;
+class QHelpSearchResultWidget;
+class QHelpSearchEnginePrivate;
+
+class QHELP_EXPORT QHelpSearchQuery
+{
+public:
+ enum FieldName { DEFAULT = 0, FUZZY, WITHOUT, PHRASE, ALL, ATLEAST };
+
+ QHelpSearchQuery()
+ : fieldName(DEFAULT) { wordList.clear(); }
+ QHelpSearchQuery(FieldName field, const QStringList &wordList)
+ : fieldName(field), wordList(wordList) {}
+
+ FieldName fieldName;
+ QStringList wordList;
+};
+
+class QHELP_EXPORT QHelpSearchEngine : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QHelpSearchEngine(QHelpEngineCore *helpEngine,
+ QObject *parent = 0);
+ ~QHelpSearchEngine();
+
+ QHelpSearchQueryWidget* queryWidget();
+ QHelpSearchResultWidget* resultWidget();
+
+#ifdef QT_DEPRECATED
+ QT_DEPRECATED int hitsCount() const;
+#endif
+ int hitCount() const;
+
+ typedef QPair<QString, QString> SearchHit;
+ QList<SearchHit> hits(int start, int end) const;
+
+ QList<QHelpSearchQuery> query() const;
+
+public Q_SLOTS:
+ void reindexDocumentation();
+ void cancelIndexing();
+
+ void search(const QList<QHelpSearchQuery> &queryList);
+ void cancelSearching();
+
+Q_SIGNALS:
+ void indexingStarted();
+ void indexingFinished();
+
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+private Q_SLOTS:
+ void indexDocumentation();
+
+private:
+ QHelpSearchEnginePrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPSEARCHENGINE_H
diff --git a/src/assistant/lib/qhelpsearchindex_default.cpp b/src/assistant/lib/qhelpsearchindex_default.cpp
new file mode 100644
index 000000000..9974f618d
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindex_default.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpsearchindex_default_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QDataStream &operator>>(QDataStream &s, Document &l)
+{
+ s >> l.docNumber;
+ s >> l.frequency;
+ return s;
+}
+
+QDataStream &operator<<(QDataStream &s, const Document &l)
+{
+ s << qint16(l.docNumber);
+ s << qint16(l.frequency);
+ return s;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchindex_default_p.h b/src/assistant/lib/qhelpsearchindex_default_p.h
new file mode 100644
index 000000000..868609960
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindex_default_p.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHINDEXDEFAULT_H
+#define QHELPSEARCHINDEXDEFAULT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QString>
+#include <QtCore/QVector>
+#include <QtCore/QDataStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtHelpInternal {
+
+struct Document {
+ Document(qint16 d, qint16 f)
+ : docNumber(d), frequency(f) {}
+
+ Document()
+ : docNumber(-1), frequency(0) {}
+
+ bool operator==(const Document &doc) const {
+ return docNumber == doc.docNumber;
+ }
+ bool operator<(const Document &doc) const {
+ return frequency > doc.frequency;
+ }
+ bool operator<=(const Document &doc) const {
+ return frequency >= doc.frequency;
+ }
+ bool operator>(const Document &doc) const {
+ return frequency < doc.frequency;
+ }
+
+ qint16 docNumber;
+ qint16 frequency;
+};
+
+struct DocumentInfo : public Document {
+ DocumentInfo()
+ : Document(-1, 0), documentTitle(QString()), documentUrl(QString()) {}
+
+ DocumentInfo(qint16 d, qint16 f, const QString &title, const QString &url)
+ : Document(d, f), documentTitle(title), documentUrl(url) {}
+
+ DocumentInfo(const Document &document, const QString &title, const QString &url)
+ : Document(document.docNumber, document.frequency), documentTitle(title), documentUrl(url) {}
+
+ QString documentTitle;
+ QString documentUrl;
+};
+
+struct Entry {
+ Entry(qint16 d) { documents.append(Document(d, 1)); }
+ Entry(QVector<Document> l) : documents(l) {}
+
+ QVector<Document> documents;
+};
+
+struct PosEntry {
+ PosEntry(int p) { positions.append(p); }
+ QList<uint> positions;
+};
+
+struct Term {
+ Term() : frequency(-1) {}
+ Term(const QString &t, int f, QVector<Document> l) : term(t), frequency(f), documents(l) {}
+ QString term;
+ int frequency;
+ QVector<Document>documents;
+ bool operator<(const Term &i2) const { return frequency < i2.frequency; }
+};
+
+struct TermInfo {
+ TermInfo() : frequency(-1) {}
+ TermInfo(const QString &t, int f, QVector<DocumentInfo> l)
+ : term(t), frequency(f), documents(l) {}
+
+ bool operator<(const TermInfo &i2) const { return frequency < i2.frequency; }
+
+ QString term;
+ int frequency;
+ QVector<DocumentInfo>documents;
+};
+
+} // namespace QtHelpInternal
+
+using QtHelpInternal::Document;
+using QtHelpInternal::DocumentInfo;
+using QtHelpInternal::Entry;
+using QtHelpInternal::PosEntry;
+using QtHelpInternal::Term;
+using QtHelpInternal::TermInfo;
+
+QDataStream &operator>>(QDataStream &s, Document &l);
+QDataStream &operator<<(QDataStream &s, const Document &l);
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXDEFAULT_H
diff --git a/src/assistant/lib/qhelpsearchindexreader.cpp b/src/assistant/lib/qhelpsearchindexreader.cpp
new file mode 100644
index 000000000..1ee356d2f
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexreader.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpsearchindexreader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+
+QHelpSearchIndexReader::QHelpSearchIndexReader()
+ : QThread()
+ , m_cancel(false)
+{
+ // nothing todo
+}
+
+QHelpSearchIndexReader::~QHelpSearchIndexReader()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ mutex.unlock();
+
+ wait();
+}
+
+void QHelpSearchIndexReader::cancelSearching()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ mutex.unlock();
+}
+
+void QHelpSearchIndexReader::search(const QString &collectionFile, const QString &indexFilesFolder,
+ const QList<QHelpSearchQuery> &queryList)
+{
+ wait();
+
+ this->hitList.clear();
+ this->m_cancel = false;
+ this->m_query = queryList;
+ this->m_collectionFile = collectionFile;
+ this->m_indexFilesFolder = indexFilesFolder;
+
+ start(QThread::NormalPriority);
+}
+
+int QHelpSearchIndexReader::hitCount() const
+{
+ QMutexLocker lock(&mutex);
+ return hitList.count();
+}
+
+QList<QHelpSearchEngine::SearchHit> QHelpSearchIndexReader::hits(int start,
+ int end) const
+{
+ QList<QHelpSearchEngine::SearchHit> hits;
+ QMutexLocker lock(&mutex);
+ for (int i = start; i < end && i < hitList.count(); ++i)
+ hits.append(hitList.at(i));
+ return hits;
+}
+
+
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchindexreader_clucene.cpp b/src/assistant/lib/qhelpsearchindexreader_clucene.cpp
new file mode 100644
index 000000000..537e1d765
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexreader_clucene.cpp
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fulltextsearch/qindexreader_p.h"
+#include "fulltextsearch/qqueryparser_p.h"
+#include "fulltextsearch/qsearchable_p.h"
+#include "qclucenefieldnames_p.h"
+#include "qhelpenginecore.h"
+
+#include "qhelpsearchindexreader_clucene_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QSet>
+#include <QtCore/QString>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QMutexLocker>
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace clucene {
+
+QHelpSearchIndexReaderClucene::QHelpSearchIndexReaderClucene()
+ : QHelpSearchIndexReader()
+{
+ // nothing todo
+}
+
+QHelpSearchIndexReaderClucene::~QHelpSearchIndexReaderClucene()
+{
+}
+
+
+void QHelpSearchIndexReaderClucene::run()
+{
+ mutex.lock();
+
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+
+ const QString collectionFile(this->m_collectionFile);
+ const QList<QHelpSearchQuery> &queryList = this->m_query;
+ const QString indexPath(m_indexFilesFolder);
+
+ mutex.unlock();
+
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ QFileInfo fInfo(indexPath);
+ if (fInfo.exists() && !fInfo.isWritable()) {
+ qWarning("Full Text Search, could not read index (missing permissions).");
+ return;
+ }
+
+ if(QCLuceneIndexReader::indexExists(indexPath)) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+ mutex.unlock();
+
+ emit searchingStarted();
+
+#if !defined(QT_NO_EXCEPTIONS)
+ try {
+#endif
+ QCLuceneBooleanQuery booleanQueryTitle;
+ QCLuceneBooleanQuery booleanQueryContent;
+ QCLuceneStandardAnalyzer analyzer;
+ const QStringList& attribList =
+ engine.filterAttributes(engine.currentFilter());
+ bool titleQueryIsValid = buildQuery(queryList, TitleTokenizedField,
+ attribList, booleanQueryTitle, analyzer);
+ bool contentQueryIsValid = buildQuery(queryList, ContentField,
+ attribList, booleanQueryContent, analyzer);
+ if (!titleQueryIsValid && !contentQueryIsValid) {
+ emit searchingFinished(0);
+ return;
+ }
+
+ QCLuceneIndexSearcher indexSearcher(indexPath);
+
+ // QCLuceneHits object must be allocated on the heap, because
+ // there is no default constructor.
+ QSharedPointer<QCLuceneHits> titleHits;
+ QSharedPointer<QCLuceneHits> contentHits;
+ if (titleQueryIsValid) {
+ titleHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits(
+ indexSearcher.search(booleanQueryTitle)));
+ }
+ if (contentQueryIsValid) {
+ contentHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits(
+ indexSearcher.search(booleanQueryContent)));
+ }
+ bool boost = true;
+ if ((titleHits.isNull() || titleHits->length() == 0)
+ && (contentHits.isNull() || contentHits->length() == 0)) {
+ booleanQueryTitle = QCLuceneBooleanQuery();
+ booleanQueryContent = QCLuceneBooleanQuery();
+ titleQueryIsValid =
+ buildTryHarderQuery(queryList, TitleTokenizedField,
+ attribList, booleanQueryTitle, analyzer);
+ contentQueryIsValid =
+ buildTryHarderQuery(queryList, ContentField, attribList,
+ booleanQueryContent, analyzer);
+ if (!titleQueryIsValid && !contentQueryIsValid) {
+ emit searchingFinished(0);
+ return;
+ }
+ if (titleQueryIsValid) {
+ titleHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits(
+ indexSearcher.search(booleanQueryTitle)));
+ }
+ if (contentQueryIsValid) {
+ contentHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits(
+ indexSearcher.search(booleanQueryContent)));
+ }
+ boost = false;
+ }
+ QList<QSharedPointer<QCLuceneHits> > cluceneHitsList;
+ if (!titleHits.isNull())
+ cluceneHitsList.append(titleHits);
+ if (!contentHits.isNull())
+ cluceneHitsList.append(contentHits);
+
+ QSet<QString> pathSet;
+ QCLuceneDocument document;
+ const QStringList namespaceList = engine.registeredDocumentations();
+
+ foreach (const QSharedPointer<QCLuceneHits> &hits, cluceneHitsList) {
+ for (qint32 i = 0; i < hits->length(); i++) {
+ document = hits->document(i);
+ const QString path = document.get(PathField);
+ if (!pathSet.contains(path) && namespaceList.contains(
+ document.get(NamespaceField), Qt::CaseInsensitive)) {
+ pathSet.insert(path);
+ hitList.append(qMakePair(path, document.get(TitleField)));
+ }
+ document.clear();
+
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ emit searchingFinished(0);
+ return;
+ }
+ mutex.unlock();
+ }
+ }
+
+ indexSearcher.close();
+ const int count = hitList.count();
+ if ((count > 0) && boost)
+ boostSearchHits(engine, hitList, queryList);
+ emit searchingFinished(hitList.count());
+
+#if !defined(QT_NO_EXCEPTIONS)
+ } catch(...) {
+ mutex.lock();
+ hitList.clear();
+ mutex.unlock();
+ emit searchingFinished(0);
+ }
+#endif
+ }
+}
+
+bool QHelpSearchIndexReaderClucene::buildQuery(
+ const QList<QHelpSearchQuery> &queries, const QString &fieldName,
+ const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
+{
+ bool queryIsValid = false;
+ foreach (const QHelpSearchQuery &query, queries) {
+ if (fieldName != ContentField && isNegativeQuery(query)) {
+ queryIsValid = false;
+ break;
+ }
+ switch (query.fieldName) {
+ case QHelpSearchQuery::FUZZY:
+ if (addFuzzyQuery(query, fieldName, booleanQuery, analyzer))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::WITHOUT:
+ if (fieldName != ContentField)
+ return false;
+ if (addWithoutQuery(query, fieldName, booleanQuery))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::PHRASE:
+ if (addPhraseQuery(query, fieldName, booleanQuery))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::ALL:
+ if (addAllQuery(query, fieldName, booleanQuery))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::DEFAULT:
+ if (addDefaultQuery(query, fieldName, true, booleanQuery, analyzer))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::ATLEAST:
+ if (addAtLeastQuery(query, fieldName, booleanQuery, analyzer))
+ queryIsValid = true;
+ break;
+ default:
+ Q_ASSERT(!"Invalid field name");
+ }
+ }
+
+ if (queryIsValid && !filterAttributes.isEmpty()) {
+ queryIsValid =
+ addAttributesQuery(filterAttributes, booleanQuery, analyzer);
+ }
+
+ return queryIsValid;
+}
+
+bool QHelpSearchIndexReaderClucene::buildTryHarderQuery(
+ const QList<QHelpSearchQuery> &queries, const QString &fieldName,
+ const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
+{
+ if (queries.isEmpty())
+ return false;
+ const QHelpSearchQuery &query = queries.front();
+ if (query.fieldName != QHelpSearchQuery::DEFAULT)
+ return false;
+ if (isNegativeQuery(query))
+ return false;
+ if (!addDefaultQuery(query, fieldName, false, booleanQuery, analyzer))
+ return false;
+ if (filterAttributes.isEmpty())
+ return true;
+ return addAttributesQuery(filterAttributes, booleanQuery, analyzer);
+}
+
+bool QHelpSearchIndexReaderClucene::isNegativeQuery(const QHelpSearchQuery &query) const
+{
+ const QString &search = query.wordList.join(" ");
+ return search.contains('!') || search.contains('-')
+ || search.contains(QLatin1String(" NOT "));
+}
+
+bool QHelpSearchIndexReaderClucene::addFuzzyQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
+{
+ bool queryIsValid = false;
+ const QLatin1String fuzzy("~");
+ foreach (const QString &term, query.wordList) {
+ if (!term.isEmpty()) {
+ QCLuceneQuery *lQuery =
+ QCLuceneQueryParser::parse(term + fuzzy, fieldName, analyzer);
+ if (lQuery != 0) {
+ booleanQuery.add(lQuery, true, false, false);
+ queryIsValid = true;
+ }
+ }
+ }
+ return queryIsValid;
+}
+
+bool QHelpSearchIndexReaderClucene::addWithoutQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, QCLuceneBooleanQuery &booleanQuery)
+{
+ bool queryIsValid = false;
+ const QStringList &stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString &term, query.wordList) {
+ if (stopWords.contains(term, Qt::CaseInsensitive))
+ continue;
+ QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm(
+ fieldName, term.toLower()));
+ booleanQuery.add(lQuery, true, false, true);
+ queryIsValid = true;
+ }
+ return queryIsValid;
+}
+
+bool QHelpSearchIndexReaderClucene::addPhraseQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, QCLuceneBooleanQuery &booleanQuery)
+{
+ bool queryIsValid = false;
+ const QString &term = query.wordList.at(0).toLower();
+ if (term.contains(QLatin1Char(' '))) {
+ const QStringList termList = term.split(QLatin1String(" "));
+ QCLucenePhraseQuery *q = new QCLucenePhraseQuery();
+ const QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString &term, termList) {
+ if (!stopWords.contains(term, Qt::CaseInsensitive))
+ q->addTerm(QCLuceneTerm(fieldName, term.toLower()));
+ }
+ if (!q->getTerms().isEmpty()) {
+ booleanQuery.add(q, true, true, false);
+ queryIsValid = true;
+ }
+ } else {
+ QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm(
+ fieldName, term.toLower()));
+ booleanQuery.add(lQuery, true, true, false);
+ queryIsValid = true;
+ }
+ return queryIsValid;
+}
+
+bool QHelpSearchIndexReaderClucene::addAllQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, QCLuceneBooleanQuery &booleanQuery)
+{
+ bool queryIsValid = false;
+ const QStringList &stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString &term, query.wordList) {
+ if (stopWords.contains(term, Qt::CaseInsensitive))
+ continue;
+ QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm(
+ fieldName, term.toLower()));
+ booleanQuery.add(lQuery, true, true, false);
+ queryIsValid = true;
+ }
+ return queryIsValid;
+}
+
+bool QHelpSearchIndexReaderClucene::addDefaultQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, bool allTermsRequired,
+ QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
+{
+ bool queryIsValid = false;
+ foreach (const QString &term, query.wordList) {
+ QCLuceneQuery *lQuery =
+ QCLuceneQueryParser::parse(term.toLower(), fieldName, analyzer);
+ if (lQuery) {
+ booleanQuery.add(lQuery, true, allTermsRequired, false);
+ queryIsValid = true;
+ }
+ }
+ return queryIsValid;
+}
+
+bool QHelpSearchIndexReaderClucene::addAtLeastQuery(
+ const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer)
+{
+ bool queryIsValid = false;
+ foreach (const QString &term, query.wordList) {
+ if (!term.isEmpty()) {
+ QCLuceneQuery *lQuery =
+ QCLuceneQueryParser::parse(term, fieldName, analyzer);
+ if (lQuery) {
+ booleanQuery.add(lQuery, true, false, false);
+ queryIsValid = true;
+ }
+ }
+ }
+ return queryIsValid;
+}
+
+bool QHelpSearchIndexReaderClucene::addAttributesQuery(
+ const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
+{
+ QCLuceneQuery* lQuery = QCLuceneQueryParser::parse(QLatin1String("+")
+ + filterAttributes.join(QLatin1String(" +")), AttributeField, analyzer);
+ if (!lQuery)
+ return false;
+ booleanQuery.add(lQuery, true, true, false);
+ return true;
+}
+
+void QHelpSearchIndexReaderClucene::boostSearchHits(const QHelpEngineCore &engine,
+ QList<QHelpSearchEngine::SearchHit> &hitList, const QList<QHelpSearchQuery> &queryList)
+{
+ foreach (const QHelpSearchQuery &query, queryList) {
+ if (query.fieldName != QHelpSearchQuery::DEFAULT)
+ continue;
+
+ QString joinedQuery = query.wordList.join(QLatin1String(" "));
+
+ QCLuceneStandardAnalyzer analyzer;
+ QCLuceneQuery *parsedQuery = QCLuceneQueryParser::parse(
+ joinedQuery, ContentField, analyzer);
+
+ if (parsedQuery) {
+ joinedQuery = parsedQuery->toString();
+ delete parsedQuery;
+ }
+
+ const QString contentString(ContentField + QLatin1String(":"));
+ int length = contentString.length();
+ int index = joinedQuery.indexOf(contentString);
+
+ QString term;
+ int nextIndex = 0;
+ QStringList searchTerms;
+ while (index != -1) {
+ nextIndex = joinedQuery.indexOf(contentString, index + 1);
+ term = joinedQuery.mid(index + length, nextIndex - (length + index)).simplified();
+ if (term.startsWith(QLatin1String("\""))
+ && term.endsWith(QLatin1String("\""))) {
+ searchTerms.append(term.remove(QLatin1String("\"")));
+ } else {
+ searchTerms += term.split(QLatin1Char(' '));
+ }
+ index = nextIndex;
+ }
+ searchTerms.removeDuplicates();
+
+ int count = qMin(75, hitList.count());
+ QMap<int, QHelpSearchEngine::SearchHit> hitMap;
+ for (int i = 0; i < count; ++i) {
+ const QHelpSearchEngine::SearchHit &hit = hitList.at(i);
+ QString data = QString::fromUtf8(engine.fileData(hit.first));
+
+ int counter = 0;
+ foreach (const QString &term, searchTerms)
+ counter += data.count(term, Qt::CaseInsensitive);
+ hitMap.insertMulti(counter, hit);
+ }
+
+ QList<QHelpSearchEngine::SearchHit> boostedList;
+ QMap<int, QHelpSearchEngine::SearchHit>::const_iterator it = hitMap.constEnd();
+ do {
+ --it;
+ boostedList.append(it.value());
+ } while (it != hitMap.constBegin());
+ boostedList += hitList.mid(count, hitList.count());
+ mutex.lock();
+ hitList = boostedList;
+ mutex.unlock();
+ }
+}
+
+} // namespace clucene
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchindexreader_clucene_p.h b/src/assistant/lib/qhelpsearchindexreader_clucene_p.h
new file mode 100644
index 000000000..dec18a07b
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexreader_clucene_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHINDEXREADERCLUCENE_H
+#define QHELPSEARCHINDEXREADERCLUCENE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include "fulltextsearch/qanalyzer_p.h"
+#include "fulltextsearch/qquery_p.h"
+#include "qhelpsearchindexreader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace clucene {
+
+class QHelpSearchIndexReaderClucene : public QHelpSearchIndexReader
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexReaderClucene();
+ ~QHelpSearchIndexReaderClucene();
+
+private:
+ void run();
+ void boostSearchHits(const QHelpEngineCore &engine, QList<QHelpSearchEngine::SearchHit> &hitList,
+ const QList<QHelpSearchQuery> &queryList);
+ bool buildQuery(const QList<QHelpSearchQuery> &queries,
+ const QString &fieldName,
+ const QStringList &filterAttributes,
+ QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer);
+ bool buildTryHarderQuery(const QList<QHelpSearchQuery> &queries,
+ const QString &fieldName,
+ const QStringList &filterAttributes,
+ QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer);
+ bool addFuzzyQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer);
+ bool addWithoutQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery);
+ bool addPhraseQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery);
+ bool addAllQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery);
+ bool addDefaultQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ bool allTermsRequired, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer);
+ bool addAtLeastQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer);
+ bool addAttributesQuery(const QStringList &filterAttributes,
+ QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer);
+ bool isNegativeQuery(const QHelpSearchQuery &query) const;
+};
+
+} // namespace clucene
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXREADERCLUCENE_H
diff --git a/src/assistant/lib/qhelpsearchindexreader_default.cpp b/src/assistant/lib/qhelpsearchindexreader_default.cpp
new file mode 100644
index 000000000..e49fdfcbd
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexreader_default.cpp
@@ -0,0 +1,612 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpenginecore.h"
+#include "qhelpsearchindexreader_default_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QUrl>
+#include <QtCore/QFile>
+#include <QtCore/QVariant>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDataStream>
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace std {
+
+namespace {
+ QStringList split( const QString &str )
+ {
+ QStringList lst;
+ int j = 0;
+ int i = str.indexOf(QLatin1Char('*'), j );
+
+ if (str.startsWith(QLatin1String("*")))
+ lst << QLatin1String("*");
+
+ while ( i != -1 ) {
+ if ( i > j && i <= (int)str.length() ) {
+ lst << str.mid( j, i - j );
+ lst << QLatin1String("*");
+ }
+ j = i + 1;
+ i = str.indexOf(QLatin1Char('*'), j );
+ }
+
+ int l = str.length() - 1;
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+ lst << str.mid( j, l - j + 1 );
+
+ return lst;
+ }
+}
+
+
+Reader::Reader()
+ : indexPath(QString())
+ , indexFile(QString())
+ , documentFile(QString())
+{
+ termList.clear();
+ indexTable.clear();
+ searchIndexTable.clear();
+}
+
+Reader::~Reader()
+{
+ reset();
+ searchIndexTable.clear();
+}
+
+bool Reader::readIndex()
+{
+ if (indexTable.contains(indexFile))
+ return true;
+
+ QFile idxFile(indexFile);
+ if (!idxFile.open(QFile::ReadOnly))
+ return false;
+
+ QString key;
+ int numOfDocs;
+ EntryTable entryTable;
+ QVector<Document> docs;
+ QDataStream dictStream(&idxFile);
+ while (!dictStream.atEnd()) {
+ dictStream >> key;
+ dictStream >> numOfDocs;
+ docs.resize(numOfDocs);
+ dictStream >> docs;
+ entryTable.insert(key, new Entry(docs));
+ }
+ idxFile.close();
+
+ if (entryTable.isEmpty())
+ return false;
+
+ QFile docFile(documentFile);
+ if (!docFile.open(QFile::ReadOnly))
+ return false;
+
+ QString title, url;
+ DocumentList documentList;
+ QDataStream docStream(&docFile);
+ while (!docStream.atEnd()) {
+ docStream >> title;
+ docStream >> url;
+ documentList.append(QStringList(title) << url);
+ }
+ docFile.close();
+
+ if (documentList.isEmpty()) {
+ cleanupIndex(entryTable);
+ return false;
+ }
+
+ indexTable.insert(indexFile, Index(entryTable, documentList));
+ return true;
+}
+
+bool Reader::initCheck() const
+{
+ return !searchIndexTable.isEmpty();
+}
+
+void Reader::setIndexPath(const QString &path)
+{
+ indexPath = path;
+}
+
+void Reader::filterFilesForAttributes(const QStringList &attributes)
+{
+ searchIndexTable.clear();
+ for(IndexTable::ConstIterator it = indexTable.begin(); it != indexTable.end(); ++it) {
+ const QString fileName = it.key();
+ bool containsAll = true;
+ QStringList split = fileName.split(QLatin1String("@"));
+ foreach (const QString &attribute, attributes) {
+ if (!split.contains(attribute, Qt::CaseInsensitive)) {
+ containsAll = false;
+ break;
+ }
+ }
+
+ if (containsAll)
+ searchIndexTable.insert(fileName, it.value());
+ }
+}
+
+void Reader::setIndexFile(const QString &namespaceName, const QString &attributes)
+{
+ QString extension = namespaceName + QLatin1String("@") + attributes;
+ indexFile = indexPath + QLatin1String("/indexdb40.") + extension;
+ documentFile = indexPath + QLatin1String("/indexdoc40.") + extension;
+}
+
+bool Reader::splitSearchTerm(const QString &searchTerm, QStringList *terms,
+ QStringList *termSeq, QStringList *seqWords)
+{
+ QString term = searchTerm;
+
+ term = term.simplified();
+ term = term.replace(QLatin1String("\'"), QLatin1String("\""));
+ term = term.replace(QLatin1String("`"), QLatin1String("\""));
+ term = term.replace(QLatin1String("-"), QLatin1String(" "));
+ term = term.replace(QRegExp(QLatin1String("\\s[\\S]?\\s")), QLatin1String(" "));
+
+ *terms = term.split(QLatin1Char(' '));
+ QStringList::iterator it = terms->begin();
+ for (; it != terms->end(); ++it) {
+ (*it) = (*it).simplified();
+ (*it) = (*it).toLower();
+ (*it) = (*it).replace(QLatin1String("\""), QLatin1String(""));
+ }
+
+ if (term.contains(QLatin1Char('\"'))) {
+ if ((term.count(QLatin1Char('\"')))%2 == 0) {
+ int beg = 0;
+ int end = 0;
+ QString s;
+ beg = term.indexOf(QLatin1Char('\"'), beg);
+ while (beg != -1) {
+ beg++;
+ end = term.indexOf(QLatin1Char('\"'), beg);
+ s = term.mid(beg, end - beg);
+ s = s.toLower();
+ s = s.simplified();
+ if (s.contains(QLatin1Char('*'))) {
+ qWarning("Full Text Search, using a wildcard within phrases is not allowed.");
+ return false;
+ }
+ *seqWords += s.split(QLatin1Char(' '));
+ *termSeq << s;
+ beg = term.indexOf(QLatin1Char('\"'), end + 1);
+ }
+ } else {
+ qWarning("Full Text Search, the closing quotation mark is missing.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void Reader::searchInIndex(const QStringList &terms)
+{
+ foreach (const QString &term, terms) {
+ QVector<Document> documents;
+
+ for(IndexTable::ConstIterator it = searchIndexTable.begin();
+ it != searchIndexTable.end(); ++it) {
+ EntryTable entryTable = it.value().first;
+ DocumentList documentList = it.value().second;
+
+ if (term.contains(QLatin1Char('*')))
+ documents = setupDummyTerm(getWildcardTerms(term, entryTable), entryTable);
+ else if (entryTable.value(term))
+ documents = entryTable.value(term)->documents;
+ else
+ continue;
+
+ if (!documents.isEmpty()) {
+ DocumentInfo info;
+ QString title, url;
+ QVector<DocumentInfo> documentsInfo;
+ foreach(const Document &doc, documents) {
+ info.docNumber = doc.docNumber;
+ info.frequency = doc.frequency;
+ info.documentUrl = documentList.at(doc.docNumber).at(1);
+ info.documentTitle = documentList.at(doc.docNumber).at(0);
+ documentsInfo.append(info);
+ }
+
+ bool found = false;
+ for(QList<TermInfo>::Iterator tit = termList.begin();
+ tit != termList.end(); ++tit) {
+ TermInfo *t = &(*tit);
+ if(t->term == term) {
+ t->documents += documentsInfo;
+ t->frequency += documentsInfo.count();
+ found = true; break;
+ }
+ }
+ if (!found)
+ termList.append(TermInfo(term, documentsInfo.count(), documentsInfo));
+ }
+ }
+ }
+ qSort(termList);
+}
+
+QVector<DocumentInfo> Reader::hits()
+{
+ QVector<DocumentInfo> documents;
+ if (!termList.count())
+ return documents;
+
+ documents = termList.takeFirst().documents;
+ for(QList<TermInfo>::Iterator it = termList.begin(); it != termList.end(); ++it) {
+ TermInfo *t = &(*it);
+ QVector<DocumentInfo> docs = t->documents;
+ for(QVector<DocumentInfo>::Iterator minDoc_it = documents.begin();
+ minDoc_it != documents.end(); ) {
+ bool found = false;
+ for (QVector<DocumentInfo>::ConstIterator doc_it = docs.constBegin();
+ doc_it != docs.constEnd(); ++doc_it ) {
+ if ( (*minDoc_it).docNumber == (*doc_it).docNumber ) {
+ (*minDoc_it).frequency += (*doc_it).frequency;
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ minDoc_it = documents.erase(minDoc_it);
+ else
+ ++minDoc_it;
+ }
+ }
+
+ qSort(documents);
+ return documents;
+}
+
+bool Reader::searchForPattern(const QStringList &patterns, const QStringList &words,
+ const QByteArray &data)
+{
+ if (data.isEmpty())
+ return false;
+
+ for(QHash<QString, PosEntry*>::ConstIterator mit =
+ miniIndex.begin(); mit != miniIndex.end(); ++mit) {
+ delete mit.value();
+ }
+ miniIndex.clear();
+
+ wordNum = 3;
+ QStringList::ConstIterator cIt = words.begin();
+ for ( ; cIt != words.end(); ++cIt )
+ miniIndex.insert(*cIt, new PosEntry(0));
+
+ QTextStream s(data);
+ QString text = s.readAll();
+ bool valid = true;
+ const QChar *buf = text.unicode();
+ QChar str[64];
+ QChar c = buf[0];
+ int j = 0;
+ int i = 0;
+ while ( j < text.length() ) {
+ if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) {
+ valid = false;
+ if ( i > 1 )
+ buildMiniIndex( QString(str,i) );
+ i = 0;
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) {
+ valid = true;
+ c = buf[++j];
+ continue;
+ }
+ if ( !valid ) {
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) {
+ str[i] = c.toLower();
+ ++i;
+ } else {
+ if ( i > 1 )
+ buildMiniIndex( QString(str,i) );
+ i = 0;
+ }
+ c = buf[++j];
+ }
+ if ( i > 1 )
+ buildMiniIndex( QString(str,i) );
+
+ QStringList::ConstIterator patIt = patterns.begin();
+ QStringList wordLst;
+ QList<uint> a, b;
+ QList<uint>::iterator aIt;
+ for ( ; patIt != patterns.end(); ++patIt ) {
+ wordLst = (*patIt).split(QLatin1Char(' '));
+ a = miniIndex[ wordLst[0] ]->positions;
+ for ( int j = 1; j < (int)wordLst.count(); ++j ) {
+ b = miniIndex[ wordLst[j] ]->positions;
+ aIt = a.begin();
+ while ( aIt != a.end() ) {
+ if ( b.contains( *aIt + 1 )) {
+ (*aIt)++;
+ ++aIt;
+ } else {
+ aIt = a.erase( aIt );
+ }
+ }
+ }
+ }
+ if ( a.count() )
+ return true;
+ return false;
+}
+
+QVector<Document> Reader::setupDummyTerm(const QStringList &terms,
+ const EntryTable &entryTable)
+{
+ QList<Term> termList;
+ for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it) {
+ if (entryTable.value(*it)) {
+ Entry *e = entryTable.value(*it);
+ termList.append(Term(*it, e->documents.count(), e->documents ) );
+ }
+ }
+ QVector<Document> maxList(0);
+ if ( !termList.count() )
+ return maxList;
+ qSort(termList);
+
+ maxList = termList.takeLast().documents;
+ for(QList<Term>::Iterator it = termList.begin(); it != termList.end(); ++it) {
+ Term *t = &(*it);
+ QVector<Document> docs = t->documents;
+ for (QVector<Document>::iterator docIt = docs.begin(); docIt != docs.end(); ++docIt ) {
+ if ( maxList.indexOf( *docIt ) == -1 )
+ maxList.append( *docIt );
+ }
+ }
+ return maxList;
+}
+
+QStringList Reader::getWildcardTerms(const QString &term,
+ const EntryTable &entryTable)
+{
+ QStringList lst;
+ QStringList terms = split(term);
+ QStringList::Iterator iter;
+
+ for(EntryTable::ConstIterator it = entryTable.begin();
+ it != entryTable.end(); ++it) {
+ int index = 0;
+ bool found = false;
+ QString text( it.key() );
+ for ( iter = terms.begin(); iter != terms.end(); ++iter ) {
+ if ( *iter == QLatin1String("*") ) {
+ found = true;
+ continue;
+ }
+ if ( iter == terms.begin() && (*iter)[0] != text[0] ) {
+ found = false;
+ break;
+ }
+ index = text.indexOf( *iter, index );
+ if ( *iter == terms.last() && index != (int)text.length()-1 ) {
+ index = text.lastIndexOf( *iter );
+ if ( index != (int)text.length() - (int)(*iter).length() ) {
+ found = false;
+ break;
+ }
+ }
+ if ( index != -1 ) {
+ found = true;
+ index += (*iter).length();
+ continue;
+ } else {
+ found = false;
+ break;
+ }
+ }
+ if (found)
+ lst << text;
+ }
+
+ return lst;
+}
+
+void Reader::buildMiniIndex(const QString &string)
+{
+ if (miniIndex[string])
+ miniIndex[string]->positions.append(wordNum);
+ ++wordNum;
+}
+
+void Reader::reset()
+{
+ for(IndexTable::Iterator it = indexTable.begin();
+ it != indexTable.end(); ++it) {
+ cleanupIndex(it.value().first);
+ it.value().second.clear();
+ }
+}
+
+void Reader::cleanupIndex(EntryTable &entryTable)
+{
+ for(EntryTable::ConstIterator it =
+ entryTable.begin(); it != entryTable.end(); ++it) {
+ delete it.value();
+ }
+
+ entryTable.clear();
+}
+
+
+QHelpSearchIndexReaderDefault::QHelpSearchIndexReaderDefault()
+ : QHelpSearchIndexReader()
+{
+ // nothing todo
+}
+
+QHelpSearchIndexReaderDefault::~QHelpSearchIndexReaderDefault()
+{
+}
+
+void QHelpSearchIndexReaderDefault::run()
+{
+ mutex.lock();
+
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+
+ const QList<QHelpSearchQuery> &queryList = this->m_query;
+ const QLatin1String key("DefaultSearchNamespaces");
+ const QString collectionFile(this->m_collectionFile);
+ const QString indexPath = m_indexFilesFolder;
+
+ mutex.unlock();
+
+ QString queryTerm;
+ foreach (const QHelpSearchQuery &query, queryList) {
+ if (query.fieldName == QHelpSearchQuery::DEFAULT) {
+ queryTerm = query.wordList.at(0);
+ break;
+ }
+ }
+
+ if (queryTerm.isEmpty())
+ return;
+
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ const QStringList registeredDocs = engine.registeredDocumentations();
+ const QStringList indexedNamespaces = engine.customValue(key).toString().
+ split(QLatin1String("|"), QString::SkipEmptyParts);
+
+ emit searchingStarted();
+
+ // setup the reader
+ m_reader.setIndexPath(indexPath);
+ foreach(const QString &namespaceName, registeredDocs) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ searchingFinished(0); // TODO: check this ???
+ return;
+ }
+ mutex.unlock();
+
+ const QList<QStringList> attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ foreach (const QStringList &attributes, attributeSets) {
+ // read all index files
+ m_reader.setIndexFile(namespaceName, attributes.join(QLatin1String("@")));
+ if (!m_reader.readIndex()) {
+ qWarning("Full Text Search, could not read file for namespace: %s.",
+ namespaceName.toUtf8().constData());
+ }
+ }
+ }
+
+ // get the current filter attributes and minimize the index files table
+ m_reader.filterFilesForAttributes(engine.filterAttributes(engine.currentFilter()));
+
+ hitList.clear();
+ QStringList terms, termSeq, seqWords;
+ if (m_reader.initCheck() && // check if we could read anything
+ m_reader.splitSearchTerm(queryTerm, &terms, &termSeq, &seqWords) ) {
+
+ // search for term(s)
+ m_reader.searchInIndex(terms); // TODO: should this be interruptible as well ???
+
+ QVector<DocumentInfo> hits = m_reader.hits();
+ if (!hits.isEmpty()) {
+ if (termSeq.isEmpty()) {
+ foreach (const DocumentInfo &docInfo, hits) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ searchingFinished(0); // TODO: check this, speed issue while locking???
+ return;
+ }
+ mutex.unlock();
+ hitList.append(qMakePair(docInfo.documentTitle, docInfo.documentUrl));
+ }
+ } else {
+ foreach (const DocumentInfo &docInfo, hits) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ searchingFinished(0); // TODO: check this, speed issue while locking???
+ return;
+ }
+ mutex.unlock();
+
+ if (m_reader.searchForPattern(termSeq, seqWords, engine.fileData(docInfo.documentUrl))) // TODO: should this be interruptible as well ???
+ hitList.append(qMakePair(docInfo.documentTitle, docInfo.documentUrl));
+ }
+ }
+ }
+ }
+
+ emit searchingFinished(hitList.count());
+}
+
+} // namespace std
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchindexreader_default_p.h b/src/assistant/lib/qhelpsearchindexreader_default_p.h
new file mode 100644
index 000000000..30dfe1ed6
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexreader_default_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHINDEXREADERDEFAULT_H
+#define QHELPSEARCHINDEXREADERDEFAULT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelpsearchindex_default_p.h"
+#include "qhelpsearchindexreader_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QPair>
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace std {
+
+class Reader
+{
+ typedef QList<QStringList> DocumentList;
+ typedef QHash<QString, Entry*> EntryTable;
+ typedef QPair<EntryTable, DocumentList> Index;
+ typedef QHash<QString, Index> IndexTable;
+
+public:
+ Reader();
+ ~Reader();
+
+ bool readIndex();
+ bool initCheck() const;
+ void setIndexPath(const QString &path);
+ void filterFilesForAttributes(const QStringList &attributes);
+ void setIndexFile(const QString &namespaceName, const QString &attributes);
+ bool splitSearchTerm(const QString &searchTerm, QStringList *terms,
+ QStringList *termSeq, QStringList *seqWords);
+
+ void searchInIndex(const QStringList &terms);
+ QVector<DocumentInfo> hits();
+ bool searchForPattern(const QStringList &patterns,
+ const QStringList &words, const QByteArray &data);
+
+private:
+ QVector<Document> setupDummyTerm(const QStringList &terms, const EntryTable &entryTable);
+ QStringList getWildcardTerms(const QString &term, const EntryTable &entryTable);
+ void buildMiniIndex(const QString &string);
+ void reset();
+ void cleanupIndex(EntryTable &entryTable);
+
+private:
+ uint wordNum;
+ QString indexPath;
+ QString indexFile;
+ QString documentFile;
+
+ IndexTable indexTable;
+ QList<TermInfo> termList;
+ IndexTable searchIndexTable;
+ QHash<QString, PosEntry*> miniIndex;
+};
+
+
+class QHelpSearchIndexReaderDefault : public QHelpSearchIndexReader
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexReaderDefault();
+ ~QHelpSearchIndexReaderDefault();
+
+private:
+ void run();
+
+private:
+ Reader m_reader;
+};
+
+} // namespace std
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXREADERDEFAULT_H
diff --git a/src/assistant/lib/qhelpsearchindexreader_p.h b/src/assistant/lib/qhelpsearchindexreader_p.h
new file mode 100644
index 000000000..0d7518a6e
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexreader_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHINDEXREADER_H
+#define QHELPSEARCHINDEXREADER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelpsearchengine.h"
+
+#include <QtCore/QList>
+#include <QtCore/QMutex>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QThread>
+#include <QtCore/QWaitCondition>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpEngineCore;
+
+namespace fulltextsearch {
+
+class QHelpSearchIndexReader : public QThread
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexReader();
+ ~QHelpSearchIndexReader();
+
+ void cancelSearching();
+ void search(const QString &collectionFile,
+ const QString &indexFilesFolder,
+ const QList<QHelpSearchQuery> &queryList);
+ int hitCount() const;
+ QList<QHelpSearchEngine::SearchHit> hits(int start, int end) const;
+
+signals:
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+protected:
+ mutable QMutex mutex;
+ QList<QHelpSearchEngine::SearchHit> hitList;
+ bool m_cancel;
+ QString m_collectionFile;
+ QList<QHelpSearchQuery> m_query;
+ QString m_indexFilesFolder;
+
+private:
+ virtual void run()=0;
+};
+
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXREADER_H
diff --git a/src/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/src/assistant/lib/qhelpsearchindexwriter_clucene.cpp
new file mode 100644
index 000000000..f3d5e4fc3
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexwriter_clucene.cpp
@@ -0,0 +1,898 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qclucenefieldnames_p.h"
+#include "qhelpenginecore.h"
+#include "qhelp_global.h"
+#include "fulltextsearch/qhits_p.h"
+#include "fulltextsearch/qquery_p.h"
+#include "fulltextsearch/qanalyzer_p.h"
+#include "fulltextsearch/qdocument_p.h"
+#include "fulltextsearch/qsearchable_p.h"
+#include "fulltextsearch/qindexreader_p.h"
+#include "fulltextsearch/qindexwriter_p.h"
+#include "qhelpsearchindexwriter_clucene_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QString>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+#include <QtNetwork/QLocalSocket>
+#include <QtNetwork/QLocalServer>
+
+#include "private/qfunctions_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace clucene {
+
+// taken from qtexthtmlparser
+static const struct QTextHtmlEntity
+{
+ const char *name;
+ quint16 code;
+} entities[] = {
+ { "AElig", 0x00c6 },
+ { "AMP", 38 },
+ { "Aacute", 0x00c1 },
+ { "Acirc", 0x00c2 },
+ { "Agrave", 0x00c0 },
+ { "Alpha", 0x0391 },
+ { "Aring", 0x00c5 },
+ { "Atilde", 0x00c3 },
+ { "Auml", 0x00c4 },
+ { "Beta", 0x0392 },
+ { "Ccedil", 0x00c7 },
+ { "Chi", 0x03a7 },
+ { "Dagger", 0x2021 },
+ { "Delta", 0x0394 },
+ { "ETH", 0x00d0 },
+ { "Eacute", 0x00c9 },
+ { "Ecirc", 0x00ca },
+ { "Egrave", 0x00c8 },
+ { "Epsilon", 0x0395 },
+ { "Eta", 0x0397 },
+ { "Euml", 0x00cb },
+ { "GT", 62 },
+ { "Gamma", 0x0393 },
+ { "Iacute", 0x00cd },
+ { "Icirc", 0x00ce },
+ { "Igrave", 0x00cc },
+ { "Iota", 0x0399 },
+ { "Iuml", 0x00cf },
+ { "Kappa", 0x039a },
+ { "LT", 60 },
+ { "Lambda", 0x039b },
+ { "Mu", 0x039c },
+ { "Ntilde", 0x00d1 },
+ { "Nu", 0x039d },
+ { "OElig", 0x0152 },
+ { "Oacute", 0x00d3 },
+ { "Ocirc", 0x00d4 },
+ { "Ograve", 0x00d2 },
+ { "Omega", 0x03a9 },
+ { "Omicron", 0x039f },
+ { "Oslash", 0x00d8 },
+ { "Otilde", 0x00d5 },
+ { "Ouml", 0x00d6 },
+ { "Phi", 0x03a6 },
+ { "Pi", 0x03a0 },
+ { "Prime", 0x2033 },
+ { "Psi", 0x03a8 },
+ { "QUOT", 34 },
+ { "Rho", 0x03a1 },
+ { "Scaron", 0x0160 },
+ { "Sigma", 0x03a3 },
+ { "THORN", 0x00de },
+ { "Tau", 0x03a4 },
+ { "Theta", 0x0398 },
+ { "Uacute", 0x00da },
+ { "Ucirc", 0x00db },
+ { "Ugrave", 0x00d9 },
+ { "Upsilon", 0x03a5 },
+ { "Uuml", 0x00dc },
+ { "Xi", 0x039e },
+ { "Yacute", 0x00dd },
+ { "Yuml", 0x0178 },
+ { "Zeta", 0x0396 },
+ { "aacute", 0x00e1 },
+ { "acirc", 0x00e2 },
+ { "acute", 0x00b4 },
+ { "aelig", 0x00e6 },
+ { "agrave", 0x00e0 },
+ { "alefsym", 0x2135 },
+ { "alpha", 0x03b1 },
+ { "amp", 38 },
+ { "and", 0x22a5 },
+ { "ang", 0x2220 },
+ { "apos", 0x0027 },
+ { "aring", 0x00e5 },
+ { "asymp", 0x2248 },
+ { "atilde", 0x00e3 },
+ { "auml", 0x00e4 },
+ { "bdquo", 0x201e },
+ { "beta", 0x03b2 },
+ { "brvbar", 0x00a6 },
+ { "bull", 0x2022 },
+ { "cap", 0x2229 },
+ { "ccedil", 0x00e7 },
+ { "cedil", 0x00b8 },
+ { "cent", 0x00a2 },
+ { "chi", 0x03c7 },
+ { "circ", 0x02c6 },
+ { "clubs", 0x2663 },
+ { "cong", 0x2245 },
+ { "copy", 0x00a9 },
+ { "crarr", 0x21b5 },
+ { "cup", 0x222a },
+ { "curren", 0x00a4 },
+ { "dArr", 0x21d3 },
+ { "dagger", 0x2020 },
+ { "darr", 0x2193 },
+ { "deg", 0x00b0 },
+ { "delta", 0x03b4 },
+ { "diams", 0x2666 },
+ { "divide", 0x00f7 },
+ { "eacute", 0x00e9 },
+ { "ecirc", 0x00ea },
+ { "egrave", 0x00e8 },
+ { "empty", 0x2205 },
+ { "emsp", 0x2003 },
+ { "ensp", 0x2002 },
+ { "epsilon", 0x03b5 },
+ { "equiv", 0x2261 },
+ { "eta", 0x03b7 },
+ { "eth", 0x00f0 },
+ { "euml", 0x00eb },
+ { "euro", 0x20ac },
+ { "exist", 0x2203 },
+ { "fnof", 0x0192 },
+ { "forall", 0x2200 },
+ { "frac12", 0x00bd },
+ { "frac14", 0x00bc },
+ { "frac34", 0x00be },
+ { "frasl", 0x2044 },
+ { "gamma", 0x03b3 },
+ { "ge", 0x2265 },
+ { "gt", 62 },
+ { "hArr", 0x21d4 },
+ { "harr", 0x2194 },
+ { "hearts", 0x2665 },
+ { "hellip", 0x2026 },
+ { "iacute", 0x00ed },
+ { "icirc", 0x00ee },
+ { "iexcl", 0x00a1 },
+ { "igrave", 0x00ec },
+ { "image", 0x2111 },
+ { "infin", 0x221e },
+ { "int", 0x222b },
+ { "iota", 0x03b9 },
+ { "iquest", 0x00bf },
+ { "isin", 0x2208 },
+ { "iuml", 0x00ef },
+ { "kappa", 0x03ba },
+ { "lArr", 0x21d0 },
+ { "lambda", 0x03bb },
+ { "lang", 0x2329 },
+ { "laquo", 0x00ab },
+ { "larr", 0x2190 },
+ { "lceil", 0x2308 },
+ { "ldquo", 0x201c },
+ { "le", 0x2264 },
+ { "lfloor", 0x230a },
+ { "lowast", 0x2217 },
+ { "loz", 0x25ca },
+ { "lrm", 0x200e },
+ { "lsaquo", 0x2039 },
+ { "lsquo", 0x2018 },
+ { "lt", 60 },
+ { "macr", 0x00af },
+ { "mdash", 0x2014 },
+ { "micro", 0x00b5 },
+ { "middot", 0x00b7 },
+ { "minus", 0x2212 },
+ { "mu", 0x03bc },
+ { "nabla", 0x2207 },
+ { "nbsp", 0x00a0 },
+ { "ndash", 0x2013 },
+ { "ne", 0x2260 },
+ { "ni", 0x220b },
+ { "not", 0x00ac },
+ { "notin", 0x2209 },
+ { "nsub", 0x2284 },
+ { "ntilde", 0x00f1 },
+ { "nu", 0x03bd },
+ { "oacute", 0x00f3 },
+ { "ocirc", 0x00f4 },
+ { "oelig", 0x0153 },
+ { "ograve", 0x00f2 },
+ { "oline", 0x203e },
+ { "omega", 0x03c9 },
+ { "omicron", 0x03bf },
+ { "oplus", 0x2295 },
+ { "or", 0x22a6 },
+ { "ordf", 0x00aa },
+ { "ordm", 0x00ba },
+ { "oslash", 0x00f8 },
+ { "otilde", 0x00f5 },
+ { "otimes", 0x2297 },
+ { "ouml", 0x00f6 },
+ { "para", 0x00b6 },
+ { "part", 0x2202 },
+ { "percnt", 0x0025 },
+ { "permil", 0x2030 },
+ { "perp", 0x22a5 },
+ { "phi", 0x03c6 },
+ { "pi", 0x03c0 },
+ { "piv", 0x03d6 },
+ { "plusmn", 0x00b1 },
+ { "pound", 0x00a3 },
+ { "prime", 0x2032 },
+ { "prod", 0x220f },
+ { "prop", 0x221d },
+ { "psi", 0x03c8 },
+ { "quot", 34 },
+ { "rArr", 0x21d2 },
+ { "radic", 0x221a },
+ { "rang", 0x232a },
+ { "raquo", 0x00bb },
+ { "rarr", 0x2192 },
+ { "rceil", 0x2309 },
+ { "rdquo", 0x201d },
+ { "real", 0x211c },
+ { "reg", 0x00ae },
+ { "rfloor", 0x230b },
+ { "rho", 0x03c1 },
+ { "rlm", 0x200f },
+ { "rsaquo", 0x203a },
+ { "rsquo", 0x2019 },
+ { "sbquo", 0x201a },
+ { "scaron", 0x0161 },
+ { "sdot", 0x22c5 },
+ { "sect", 0x00a7 },
+ { "shy", 0x00ad },
+ { "sigma", 0x03c3 },
+ { "sigmaf", 0x03c2 },
+ { "sim", 0x223c },
+ { "spades", 0x2660 },
+ { "sub", 0x2282 },
+ { "sube", 0x2286 },
+ { "sum", 0x2211 },
+ { "sup", 0x2283 },
+ { "sup1", 0x00b9 },
+ { "sup2", 0x00b2 },
+ { "sup3", 0x00b3 },
+ { "supe", 0x2287 },
+ { "szlig", 0x00df },
+ { "tau", 0x03c4 },
+ { "there4", 0x2234 },
+ { "theta", 0x03b8 },
+ { "thetasym", 0x03d1 },
+ { "thinsp", 0x2009 },
+ { "thorn", 0x00fe },
+ { "tilde", 0x02dc },
+ { "times", 0x00d7 },
+ { "trade", 0x2122 },
+ { "uArr", 0x21d1 },
+ { "uacute", 0x00fa },
+ { "uarr", 0x2191 },
+ { "ucirc", 0x00fb },
+ { "ugrave", 0x00f9 },
+ { "uml", 0x00a8 },
+ { "upsih", 0x03d2 },
+ { "upsilon", 0x03c5 },
+ { "uuml", 0x00fc },
+ { "weierp", 0x2118 },
+ { "xi", 0x03be },
+ { "yacute", 0x00fd },
+ { "yen", 0x00a5 },
+ { "yuml", 0x00ff },
+ { "zeta", 0x03b6 },
+ { "zwj", 0x200d },
+ { "zwnj", 0x200c }
+};
+
+Q_STATIC_GLOBAL_OPERATOR bool operator<(const QString &entityStr, const QTextHtmlEntity &entity)
+{
+ return entityStr < QLatin1String(entity.name);
+}
+
+Q_STATIC_GLOBAL_OPERATOR bool operator<(const QTextHtmlEntity &entity, const QString &entityStr)
+{
+ return QLatin1String(entity.name) < entityStr;
+}
+
+static QChar resolveEntity(const QString &entity)
+{
+ const QTextHtmlEntity *start = &entities[0];
+ const QTextHtmlEntity *end = &entities[(sizeof(entities) / sizeof(entities[0]))];
+ const QTextHtmlEntity *e = qBinaryFind(start, end, entity);
+ if (e == end)
+ return QChar();
+ return e->code;
+}
+
+static const uint latin1Extended[0xA0 - 0x80] = {
+ 0x20ac, // 0x80
+ 0x0081, // 0x81 direct mapping
+ 0x201a, // 0x82
+ 0x0192, // 0x83
+ 0x201e, // 0x84
+ 0x2026, // 0x85
+ 0x2020, // 0x86
+ 0x2021, // 0x87
+ 0x02C6, // 0x88
+ 0x2030, // 0x89
+ 0x0160, // 0x8A
+ 0x2039, // 0x8B
+ 0x0152, // 0x8C
+ 0x008D, // 0x8D direct mapping
+ 0x017D, // 0x8E
+ 0x008F, // 0x8F directmapping
+ 0x0090, // 0x90 directmapping
+ 0x2018, // 0x91
+ 0x2019, // 0x92
+ 0x201C, // 0x93
+ 0X201D, // 0x94
+ 0x2022, // 0x95
+ 0x2013, // 0x96
+ 0x2014, // 0x97
+ 0x02DC, // 0x98
+ 0x2122, // 0x99
+ 0x0161, // 0x9A
+ 0x203A, // 0x9B
+ 0x0153, // 0x9C
+ 0x009D, // 0x9D direct mapping
+ 0x017E, // 0x9E
+ 0x0178 // 0x9F
+};
+// end taken from qtexthtmlparser
+
+class DocumentHelper
+{
+public:
+ DocumentHelper(const QString &fileName, const QByteArray &data)
+ : fileName(fileName) , data(readData(data)) {}
+ ~DocumentHelper() {}
+
+ bool addFieldsToDocument(QCLuceneDocument *document,
+ const QString &namespaceName, const QString &attributes = QString())
+ {
+ if (!document)
+ return false;
+
+ if(!data.isEmpty()) {
+ QString parsedData = parseData();
+ QString parsedTitle = QHelpGlobal::documentTitle(data);
+
+ if(!parsedData.isEmpty()) {
+ document->add(new QCLuceneField(ContentField,
+ parsedData,QCLuceneField::INDEX_TOKENIZED));
+ document->add(new QCLuceneField(PathField, fileName,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
+ document->add(new QCLuceneField(TitleField, parsedTitle,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
+ document->add(new QCLuceneField(TitleTokenizedField, parsedTitle,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_TOKENIZED));
+ document->add(new QCLuceneField(NamespaceField, namespaceName,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
+ document->add(new QCLuceneField(AttributeField, attributes,
+ QCLuceneField::STORE_YES | QCLuceneField::INDEX_TOKENIZED));
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+private:
+ QString readData(const QByteArray &data)
+ {
+ QTextStream textStream(data);
+ const QByteArray &codec = QHelpGlobal::codecFromData(data).toLatin1();
+ textStream.setCodec(QTextCodec::codecForName(codec.constData()));
+
+ QString stream = textStream.readAll();
+ if (stream.isNull() || stream.isEmpty())
+ return QString();
+
+ return stream;
+ }
+
+ QString parseData() const
+ {
+ const int length = data.length();
+ const QChar *buf = data.unicode();
+
+ QString parsedContent;
+ parsedContent.reserve(length);
+
+ bool valid = true;
+ int j = 0, count = 0;
+
+ QChar c;
+ while (j < length) {
+ c = buf[j++];
+ if (c == QLatin1Char('<') || c == QLatin1Char('&')) {
+ if (count > 1 && c != QLatin1Char('&'))
+ parsedContent.append(QLatin1Char(' '));
+ else if (c == QLatin1Char('&')) {
+ // Note: this will modify the counter j, in case we sucessful parsed the entity
+ // we will have modified the counter to stay 1 before the closing ';', so
+ // the following if condition will be met with if (c == QLatin1Char(';'))
+ parsedContent.append(parseEntity(length, buf, j));
+ }
+
+ count = 0;
+ valid = false;
+ continue;
+ }
+ if ((c == QLatin1Char('>') || c == QLatin1Char(';')) && !valid) {
+ valid = true;
+ continue;
+ }
+ if (!valid)
+ continue;
+
+ if (c.isLetterOrNumber() || c.isPrint()) {
+ ++count;
+ parsedContent.append(c.toLower());
+ } else {
+ if (count > 1)
+ parsedContent.append(QLatin1Char(' '));
+ count = 0;
+ }
+ }
+
+ return parsedContent;
+ }
+
+ // taken from qtexthtmlparser
+ // parses an entity after "&", and returns it
+ QString parseEntity(int len, const QChar *buf, int &pos) const
+ {
+ int recover = pos;
+ QString entity;
+ while (pos < len) {
+ QChar c = buf[pos++];
+ if (c.isSpace() || pos - recover > 9) {
+ goto error;
+ }
+ if (c == QLatin1Char(';')) {
+ pos--;
+ break;
+ }
+ entity += c;
+ }
+ {
+ QChar resolved = resolveEntity(entity);
+ if (!resolved.isNull())
+ return QString(resolved);
+ }
+ if (entity.length() > 1 && entity.at(0) == QLatin1Char('#')) {
+ entity.remove(0, 1); // removing leading #
+
+ int base = 10;
+ bool ok = false;
+
+ if (entity.at(0).toLower() == QLatin1Char('x')) { // hex entity?
+ entity.remove(0, 1);
+ base = 16;
+ }
+
+ uint uc = entity.toUInt(&ok, base);
+ if (ok) {
+ if (uc >= 0x80 && uc < 0x80 + (sizeof(latin1Extended) / sizeof(latin1Extended[0])))
+ uc = latin1Extended[uc - 0x80]; // windows latin 1 extended
+ QString str;
+ if (uc > 0xffff) {
+ // surrogate pair
+ uc -= 0x10000;
+ ushort high = uc/0x400 + 0xd800;
+ ushort low = uc%0x400 + 0xdc00;
+ str.append(QChar(high));
+ str.append(QChar(low));
+ } else {
+ str.append(QChar(uc));
+ }
+ return str;
+ }
+ }
+ error:
+ pos = recover;
+ return QLatin1String(" ");
+ }
+ // end taken from qtexthtmlparser
+
+private:
+ QString fileName;
+ QString data;
+};
+
+
+QHelpSearchIndexWriter::QHelpSearchIndexWriter()
+ : QThread(0)
+ , m_cancel(false)
+{
+ // nothing todo
+}
+
+QHelpSearchIndexWriter::~QHelpSearchIndexWriter()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ waitCondition.wakeOne();
+ mutex.unlock();
+
+ wait();
+}
+
+void QHelpSearchIndexWriter::cancelIndexing()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ mutex.unlock();
+}
+
+void QHelpSearchIndexWriter::updateIndex(const QString &collectionFile,
+ const QString &indexFilesFolder, bool reindex)
+{
+ wait();
+ mutex.lock();
+ this->m_cancel = false;
+ this->m_reindex = reindex;
+ this->m_collectionFile = collectionFile;
+ this->m_indexFilesFolder = indexFilesFolder;
+ mutex.unlock();
+
+ start(QThread::LowestPriority);
+}
+
+void QHelpSearchIndexWriter::optimizeIndex()
+{
+#if !defined(QT_NO_EXCEPTIONS)
+ try {
+#endif
+ if (QCLuceneIndexReader::indexExists(m_indexFilesFolder)) {
+ if (QCLuceneIndexReader::isLocked(m_indexFilesFolder))
+ return;
+
+ QCLuceneStandardAnalyzer analyzer;
+ QCLuceneIndexWriter writer(m_indexFilesFolder, analyzer, false);
+ writer.optimize();
+ writer.close();
+ }
+#if !defined(QT_NO_EXCEPTIONS)
+ } catch (...) {
+ qWarning("Full Text Search, could not optimize index.");
+ return;
+ }
+#endif
+}
+
+void QHelpSearchIndexWriter::run()
+{
+#if !defined(QT_NO_EXCEPTIONS)
+ try {
+#endif
+ QMutexLocker mutexLocker(&mutex);
+
+ if (m_cancel)
+ return;
+
+ const bool reindex = this->m_reindex;
+ const QString collectionFile(this->m_collectionFile);
+
+ mutexLocker.unlock();
+
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ const QLatin1String key("CluceneIndexedNamespaces");
+ if (reindex)
+ engine.setCustomValue(key, QLatin1String(""));
+
+ QMap<QString, QDateTime> indexMap;
+ const QLatin1String oldKey("CluceneSearchNamespaces");
+ if (!engine.customValue(oldKey, QString()).isNull()) {
+ // old style qhc file < 4.4.2, need to convert...
+ const QStringList indexedNamespaces
+ = engine.customValue(oldKey).toString()
+ .split(QLatin1String("|"), QString::SkipEmptyParts);
+ foreach (const QString &nameSpace, indexedNamespaces)
+ indexMap.insert(nameSpace, QDateTime());
+ engine.removeCustomValue(oldKey);
+ } else {
+ QDataStream dataStream(engine.customValue(key).toByteArray());
+ dataStream >> indexMap;
+ }
+
+ QString indexPath = m_indexFilesFolder;
+
+ QFileInfo fInfo(indexPath);
+ if (fInfo.exists() && !fInfo.isWritable()) {
+ qWarning("Full Text Search, could not create index (missing permissions for '%s').",
+ qPrintable(indexPath));
+ return;
+ }
+
+ emit indexingStarted();
+
+ QCLuceneIndexWriter *writer = 0;
+ QCLuceneStandardAnalyzer analyzer;
+ const QStringList registeredDocs = engine.registeredDocumentations();
+
+ QLocalSocket localSocket;
+ localSocket.connectToServer(QString(QLatin1String("QtAssistant%1"))
+ .arg(QLatin1String(QT_VERSION_STR)));
+
+ QLocalServer localServer;
+ bool otherInstancesRunning = true;
+ if (!localSocket.waitForConnected()) {
+ otherInstancesRunning = false;
+ localServer.listen(QString(QLatin1String("QtAssistant%1"))
+ .arg(QLatin1String(QT_VERSION_STR)));
+ }
+
+ // check if it's locked, and if the other instance is running
+ if (!otherInstancesRunning && QCLuceneIndexReader::isLocked(indexPath))
+ QCLuceneIndexReader::unlock(indexPath);
+
+ if (QCLuceneIndexReader::isLocked(indexPath)) {
+ // poll unless indexing finished to fake progress
+ while (QCLuceneIndexReader::isLocked(indexPath)) {
+ mutexLocker.relock();
+ if (m_cancel)
+ break;
+ mutexLocker.unlock();
+ this->sleep(1);
+ }
+ emit indexingFinished();
+ return;
+ }
+
+ if (QCLuceneIndexReader::indexExists(indexPath) && !reindex) {
+ foreach(const QString &namespaceName, registeredDocs) {
+ mutexLocker.relock();
+ if (m_cancel) {
+ emit indexingFinished();
+ return;
+ }
+ mutexLocker.unlock();
+
+ if (!indexMap.contains(namespaceName)) {
+ // make sure we remove some partly indexed stuff
+ removeDocuments(indexPath, namespaceName);
+ } else {
+ QString path = engine.documentationFileName(namespaceName);
+ if (indexMap.value(namespaceName)
+ < QFileInfo(path).lastModified()) {
+ // make sure we remove some outdated indexed stuff
+ indexMap.remove(namespaceName);
+ removeDocuments(indexPath, namespaceName);
+ }
+
+ if (indexMap.contains(namespaceName)) {
+ // make sure we really have content indexed for namespace
+ QCLuceneTermQuery query(QCLuceneTerm(NamespaceField, namespaceName));
+ QCLuceneIndexSearcher indexSearcher(indexPath);
+ QCLuceneHits hits = indexSearcher.search(query);
+ if (hits.length() <= 0)
+ indexMap.remove(namespaceName);
+ }
+ }
+ }
+ writer = new QCLuceneIndexWriter(indexPath, analyzer, false);
+ } else {
+ indexMap.clear();
+ writer = new QCLuceneIndexWriter(indexPath, analyzer, true);
+ }
+
+ writer->setMergeFactor(100);
+ writer->setMinMergeDocs(1000);
+ writer->setMaxFieldLength(QCLuceneIndexWriter::DEFAULT_MAX_FIELD_LENGTH);
+
+ QStringList namespaces;
+ foreach(const QString &namespaceName, registeredDocs) {
+ mutexLocker.relock();
+ if (m_cancel) {
+ closeIndexWriter(writer);
+ emit indexingFinished();
+ return;
+ }
+ mutexLocker.unlock();
+
+ namespaces.append(namespaceName);
+ if (indexMap.contains(namespaceName))
+ continue;
+
+ const QList<QStringList> attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ if (attributeSets.isEmpty()) {
+ const QList<QUrl> docFiles = indexableFiles(&engine, namespaceName,
+ QStringList());
+ if (!addDocuments(docFiles, engine, QStringList(), namespaceName,
+ writer, analyzer))
+ break;
+ } else {
+ bool bail = false;
+ foreach (const QStringList &attributes, attributeSets) {
+ const QList<QUrl> docFiles = indexableFiles(&engine,
+ namespaceName, attributes);
+ if (!addDocuments(docFiles, engine, attributes, namespaceName,
+ writer, analyzer)) {
+ bail = true;
+ break;
+ }
+ }
+ if (bail)
+ break;
+ }
+
+ mutexLocker.relock();
+ if (!m_cancel) {
+ QString path(engine.documentationFileName(namespaceName));
+ indexMap.insert(namespaceName, QFileInfo(path).lastModified());
+ writeIndexMap(engine, indexMap);
+ }
+ mutexLocker.unlock();
+ }
+
+ closeIndexWriter(writer);
+
+ mutexLocker.relock();
+ if (!m_cancel) {
+ mutexLocker.unlock();
+
+ QStringList indexedNamespaces = indexMap.keys();
+ foreach(const QString &namespaceName, indexedNamespaces) {
+ mutexLocker.relock();
+ if (m_cancel)
+ break;
+ mutexLocker.unlock();
+
+ if (!namespaces.contains(namespaceName)) {
+ indexMap.remove(namespaceName);
+ writeIndexMap(engine, indexMap);
+ removeDocuments(indexPath, namespaceName);
+ }
+ }
+ }
+
+#if !defined(QT_NO_EXCEPTIONS)
+ } catch (...) {
+ qWarning("%s: Failed because of CLucene exception.", Q_FUNC_INFO);
+ }
+#endif
+
+ emit indexingFinished();
+}
+
+bool QHelpSearchIndexWriter::addDocuments(const QList<QUrl> docFiles,
+ const QHelpEngineCore &engine, const QStringList &attributes,
+ const QString &namespaceName, QCLuceneIndexWriter *writer,
+ QCLuceneAnalyzer &analyzer)
+{
+ QMutexLocker locker(&mutex);
+ const QString attrList = attributes.join(QLatin1String(" "));
+
+ locker.unlock();
+ foreach(const QUrl &url, docFiles) {
+ QCLuceneDocument document;
+ DocumentHelper helper(url.toString(), engine.fileData(url));
+ if (helper.addFieldsToDocument(&document, namespaceName, attrList)) {
+#if !defined(QT_NO_EXCEPTIONS)
+ try {
+#endif
+ writer->addDocument(document, analyzer);
+#if !defined(QT_NO_EXCEPTIONS)
+ } catch (...) {
+ qWarning("Full Text Search, could not properly add documents.");
+ return false;
+ }
+#endif
+ }
+ locker.relock();
+ if (m_cancel)
+ return false;
+ locker.unlock();
+ }
+ return true;
+}
+
+void QHelpSearchIndexWriter::removeDocuments(const QString &indexPath,
+ const QString &namespaceName)
+{
+ if (namespaceName.isEmpty() || QCLuceneIndexReader::isLocked(indexPath))
+ return;
+
+ QCLuceneIndexReader reader = QCLuceneIndexReader::open(indexPath);
+ reader.deleteDocuments(QCLuceneTerm(NamespaceField, namespaceName));
+
+ reader.close();
+}
+
+bool QHelpSearchIndexWriter::writeIndexMap(QHelpEngineCore &engine,
+ const QMap<QString, QDateTime> &indexMap)
+{
+ QByteArray bArray;
+
+ QDataStream data(&bArray, QIODevice::ReadWrite);
+ data << indexMap;
+
+ return engine.setCustomValue(QLatin1String("CluceneIndexedNamespaces"),
+ bArray);
+}
+
+QList<QUrl> QHelpSearchIndexWriter::indexableFiles(QHelpEngineCore *helpEngine,
+ const QString &namespaceName, const QStringList &attributes) const
+{
+ QList<QUrl> docFiles = helpEngine->files(namespaceName, attributes,
+ QLatin1String("html"));
+ docFiles += helpEngine->files(namespaceName, attributes, QLatin1String("htm"));
+ docFiles += helpEngine->files(namespaceName, attributes, QLatin1String("txt"));
+
+ return docFiles;
+}
+
+void QHelpSearchIndexWriter::closeIndexWriter(QCLuceneIndexWriter *writer)
+{
+#if !defined(QT_NO_EXCEPTIONS)
+ try {
+#endif
+ writer->close();
+ delete writer;
+#if !defined(QT_NO_EXCEPTIONS)
+ } catch (...) {
+ qWarning("Full Text Search, could not properly close index writer.");
+ }
+#endif
+}
+
+} // namespace clucene
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchindexwriter_clucene_p.h b/src/assistant/lib/qhelpsearchindexwriter_clucene_p.h
new file mode 100644
index 000000000..89146f5a7
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexwriter_clucene_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHINDEXWRITERCLUCENE_H
+#define QHELPSEARCHINDEXWRITERCLUCENE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelpenginecore.h"
+#include "fulltextsearch/qanalyzer_p.h"
+
+#include <QtCore/QUrl>
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QDateTime>
+#include <QtCore/QStringList>
+#include <QtCore/QWaitCondition>
+
+QT_BEGIN_NAMESPACE
+
+class QCLuceneIndexWriter;
+
+namespace fulltextsearch {
+namespace clucene {
+
+class QHelpSearchIndexWriter : public QThread
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexWriter();
+ ~QHelpSearchIndexWriter();
+
+ void cancelIndexing();
+ void updateIndex(const QString &collectionFile,
+ const QString &indexFilesFolder, bool reindex);
+ void optimizeIndex();
+
+signals:
+ void indexingStarted();
+ void indexingFinished();
+
+private:
+ void run();
+
+ bool addDocuments(const QList<QUrl> docFiles, const QHelpEngineCore &engine,
+ const QStringList &attributes, const QString &namespaceName,
+ QCLuceneIndexWriter *writer, QCLuceneAnalyzer &analyzer);
+ void removeDocuments(const QString &indexPath, const QString &namespaceName);
+
+ bool writeIndexMap(QHelpEngineCore& engine,
+ const QMap<QString, QDateTime>& indexMap);
+
+ QList<QUrl> indexableFiles(QHelpEngineCore *helpEngine,
+ const QString &namespaceName, const QStringList &attributes) const;
+
+ void closeIndexWriter(QCLuceneIndexWriter *writer);
+
+private:
+ QMutex mutex;
+ QWaitCondition waitCondition;
+
+ bool m_cancel;
+ bool m_reindex;
+ QString m_collectionFile;
+ QString m_indexFilesFolder;
+};
+
+} // namespace clucene
+} // namespace fulltextsearch
+
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXWRITERCLUCENE_H
diff --git a/src/assistant/lib/qhelpsearchindexwriter_default.cpp b/src/assistant/lib/qhelpsearchindexwriter_default.cpp
new file mode 100644
index 000000000..db7f6ba0d
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexwriter_default.cpp
@@ -0,0 +1,384 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpsearchindexwriter_default_p.h"
+#include "qhelp_global.h"
+#include "qhelpenginecore.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QSet>
+#include <QtCore/QUrl>
+#include <QtCore/QFile>
+#include <QtCore/QRegExp>
+#include <QtCore/QVariant>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace std {
+
+Writer::Writer(const QString &path)
+ : indexPath(path)
+ , indexFile(QString())
+ , documentFile(QString())
+{
+ // nothing todo
+}
+
+Writer::~Writer()
+{
+ reset();
+}
+
+void Writer::reset()
+{
+ for(QHash<QString, Entry*>::ConstIterator it =
+ index.begin(); it != index.end(); ++it) {
+ delete it.value();
+ }
+
+ index.clear();
+ documentList.clear();
+}
+
+bool Writer::writeIndex() const
+{
+ bool status;
+ QFile idxFile(indexFile);
+ if (!(status = idxFile.open(QFile::WriteOnly)))
+ return status;
+
+ QDataStream indexStream(&idxFile);
+ for(QHash<QString, Entry*>::ConstIterator it =
+ index.begin(); it != index.end(); ++it) {
+ indexStream << it.key();
+ indexStream << it.value()->documents.count();
+ indexStream << it.value()->documents;
+ }
+ idxFile.close();
+
+ QFile docFile(documentFile);
+ if (!(status = docFile.open(QFile::WriteOnly)))
+ return status;
+
+ QDataStream docStream(&docFile);
+ foreach(const QStringList &list, documentList) {
+ docStream << list.at(0);
+ docStream << list.at(1);
+ }
+ docFile.close();
+
+ return status;
+}
+
+void Writer::removeIndex() const
+{
+ QFile idxFile(indexFile);
+ if (idxFile.exists())
+ idxFile.remove();
+
+ QFile docFile(documentFile);
+ if (docFile.exists())
+ docFile.remove();
+}
+
+void Writer::setIndexFile(const QString &namespaceName, const QString &attributes)
+{
+ QString extension = namespaceName + QLatin1String("@") + attributes;
+ indexFile = indexPath + QLatin1String("/indexdb40.") + extension;
+ documentFile = indexPath + QLatin1String("/indexdoc40.") + extension;
+}
+
+void Writer::insertInIndex(const QString &string, int docNum)
+{
+ if (string == QLatin1String("amp") || string == QLatin1String("nbsp"))
+ return;
+
+ Entry *entry = 0;
+ if (index.count())
+ entry = index[string];
+
+ if (entry) {
+ if (entry->documents.last().docNumber != docNum)
+ entry->documents.append(Document(docNum, 1));
+ else
+ entry->documents.last().frequency++;
+ } else {
+ index.insert(string, new Entry(docNum));
+ }
+}
+
+void Writer::insertInDocumentList(const QString &title, const QString &url)
+{
+ documentList.append(QStringList(title) << url);
+}
+
+
+QHelpSearchIndexWriter::QHelpSearchIndexWriter()
+ : QThread()
+ , m_cancel(false)
+{
+ // nothing todo
+}
+
+QHelpSearchIndexWriter::~QHelpSearchIndexWriter()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ waitCondition.wakeOne();
+ mutex.unlock();
+
+ wait();
+}
+
+void QHelpSearchIndexWriter::cancelIndexing()
+{
+ mutex.lock();
+ this->m_cancel = true;
+ mutex.unlock();
+}
+
+void QHelpSearchIndexWriter::updateIndex(const QString &collectionFile,
+ const QString &indexFilesFolder,
+ bool reindex)
+{
+ wait();
+ QMutexLocker lock(&mutex);
+
+ this->m_cancel = false;
+ this->m_reindex = reindex;
+ this->m_collectionFile = collectionFile;
+ this->m_indexFilesFolder = indexFilesFolder;
+
+ start(QThread::LowestPriority);
+}
+
+void QHelpSearchIndexWriter::run()
+{
+ mutex.lock();
+
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+
+ const bool reindex(this->m_reindex);
+ const QLatin1String key("DefaultSearchNamespaces");
+ const QString collectionFile(this->m_collectionFile);
+ const QString indexPath = m_indexFilesFolder;
+
+ mutex.unlock();
+
+ QHelpEngineCore engine(collectionFile, 0);
+ if (!engine.setupData())
+ return;
+
+ if (reindex)
+ engine.setCustomValue(key, QLatin1String(""));
+
+ const QStringList registeredDocs = engine.registeredDocumentations();
+ const QStringList indexedNamespaces = engine.customValue(key).toString().
+ split(QLatin1String("|"), QString::SkipEmptyParts);
+
+ emit indexingStarted();
+
+ QStringList namespaces;
+ Writer writer(indexPath);
+ foreach(const QString &namespaceName, registeredDocs) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ return;
+ }
+ mutex.unlock();
+
+ // if indexed, continue
+ namespaces.append(namespaceName);
+ if (indexedNamespaces.contains(namespaceName))
+ continue;
+
+ const QList<QStringList> attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ foreach (const QStringList &attributes, attributeSets) {
+ // cleanup maybe old or unfinished files
+ writer.setIndexFile(namespaceName, attributes.join(QLatin1String("@")));
+ writer.removeIndex();
+
+ QSet<QString> documentsSet;
+ const QList<QUrl> docFiles = engine.files(namespaceName, attributes);
+ foreach(QUrl url, docFiles) {
+ if (m_cancel)
+ return;
+
+ // get rid of duplicated files
+ if (url.hasFragment())
+ url.setFragment(QString());
+
+ QString s = url.toString();
+ if (s.endsWith(QLatin1String(".html"))
+ || s.endsWith(QLatin1String(".htm"))
+ || s.endsWith(QLatin1String(".txt")))
+ documentsSet.insert(s);
+ }
+
+ int docNum = 0;
+ const QStringList documentsList(documentsSet.toList());
+ foreach(const QString &url, documentsList) {
+ if (m_cancel)
+ return;
+
+ QByteArray data(engine.fileData(url));
+ if (data.isEmpty())
+ continue;
+
+ QTextStream s(data);
+ QString en = QHelpGlobal::codecFromData(data);
+ s.setCodec(QTextCodec::codecForName(en.toLatin1().constData()));
+
+ QString text = s.readAll();
+ if (text.isNull())
+ continue;
+
+ QString title = QHelpGlobal::documentTitle(text);
+
+ int j = 0;
+ int i = 0;
+ bool valid = true;
+ const QChar *buf = text.unicode();
+ QChar str[64];
+ QChar c = buf[0];
+
+ while ( j < text.length() ) {
+ if (m_cancel)
+ return;
+
+ if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) {
+ valid = false;
+ if ( i > 1 )
+ writer.insertInIndex(QString(str,i), docNum);
+ i = 0;
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) {
+ valid = true;
+ c = buf[++j];
+ continue;
+ }
+ if ( !valid ) {
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) {
+ str[i] = c.toLower();
+ ++i;
+ } else {
+ if ( i > 1 )
+ writer.insertInIndex(QString(str,i), docNum);
+ i = 0;
+ }
+ c = buf[++j];
+ }
+ if ( i > 1 )
+ writer.insertInIndex(QString(str,i), docNum);
+
+ docNum++;
+ writer.insertInDocumentList(title, url);
+ }
+
+ if (writer.writeIndex()) {
+ engine.setCustomValue(key, addNamespace(
+ engine.customValue(key).toString(), namespaceName));
+ }
+
+ writer.reset();
+ }
+ }
+
+ QStringListIterator qsli(indexedNamespaces);
+ while (qsli.hasNext()) {
+ const QString namespaceName = qsli.next();
+ if (namespaces.contains(namespaceName))
+ continue;
+
+ const QList<QStringList> attributeSets =
+ engine.filterAttributeSets(namespaceName);
+
+ foreach (const QStringList &attributes, attributeSets) {
+ writer.setIndexFile(namespaceName, attributes.join(QLatin1String("@")));
+ writer.removeIndex();
+ }
+
+ engine.setCustomValue(key, removeNamespace(
+ engine.customValue(key).toString(), namespaceName));
+ }
+
+ emit indexingFinished();
+}
+
+QString QHelpSearchIndexWriter::addNamespace(const QString namespaces,
+ const QString &namespaceName)
+{
+ QString value = namespaces;
+ if (!value.contains(namespaceName))
+ value.append(namespaceName).append(QLatin1String("|"));
+
+ return value;
+}
+
+QString QHelpSearchIndexWriter::removeNamespace(const QString namespaces,
+ const QString &namespaceName)
+{
+ QString value = namespaces;
+ if (value.contains(namespaceName))
+ value.remove(namespaceName + QLatin1String("|"));
+
+ return value;
+}
+
+} // namespace std
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchindexwriter_default_p.h b/src/assistant/lib/qhelpsearchindexwriter_default_p.h
new file mode 100644
index 000000000..d510fbc9d
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchindexwriter_default_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHINDEXWRITERDEFAULT_H
+#define QHELPSEARCHINDEXWRITERDEFAULT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the help generator tools. This header file may change from version
+// to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qhelpsearchindex_default_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QMutex>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QThread>
+#include <QtCore/QStringList>
+#include <QtCore/QWaitCondition>
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace std {
+
+class Writer
+{
+public:
+ Writer(const QString &path);
+ ~Writer();
+
+ void reset();
+ bool writeIndex() const;
+ void removeIndex() const;
+ void setIndexFile(const QString &namespaceName, const QString &attributes);
+ void insertInIndex(const QString &string, int docNum);
+ void insertInDocumentList(const QString &title, const QString &url);
+
+private:
+ QString indexPath;
+ QString indexFile;
+ QString documentFile;
+
+ QHash<QString, Entry*> index;
+ QList<QStringList> documentList;
+};
+
+
+class QHelpSearchIndexWriter : public QThread
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchIndexWriter();
+ ~QHelpSearchIndexWriter();
+
+ void cancelIndexing();
+ void updateIndex(const QString &collectionFile,
+ const QString &indexFilesFolder, bool reindex);
+
+signals:
+ void indexingStarted();
+ void indexingFinished();
+
+private:
+ void run();
+ QString addNamespace(const QString namespaces, const QString &namespaceName);
+ QString removeNamespace(const QString namespaces, const QString &namespaceName);
+
+private:
+ QMutex mutex;
+ QWaitCondition waitCondition;
+
+ bool m_cancel;
+ bool m_reindex;
+ QString m_collectionFile;
+ QString m_indexFilesFolder;
+};
+
+} // namespace std
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
+
+#endif // QHELPSEARCHINDEXWRITERDEFAULT_H
diff --git a/src/assistant/lib/qhelpsearchquerywidget.cpp b/src/assistant/lib/qhelpsearchquerywidget.cpp
new file mode 100644
index 000000000..e6a789a40
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchquerywidget.cpp
@@ -0,0 +1,587 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpsearchquerywidget.h"
+
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QtGlobal>
+
+#include <QtGui/QCompleter>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QFocusEvent>
+#include <QtGui/QPushButton>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpSearchQueryWidgetPrivate : public QObject
+{
+ Q_OBJECT
+
+private:
+ struct QueryHistory {
+ explicit QueryHistory() : curQuery(-1) {}
+ QList<QList<QHelpSearchQuery> > queries;
+ int curQuery;
+ };
+
+ class CompleterModel : public QAbstractListModel
+ {
+ public:
+ explicit CompleterModel(QObject *parent)
+ : QAbstractListModel(parent) {}
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const
+ {
+ return parent.isValid() ? 0 : termList.size();
+ }
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
+ {
+ if (!index.isValid() || index.row() >= termList.count()||
+ (role != Qt::EditRole && role != Qt::DisplayRole))
+ return QVariant();
+ return termList.at(index.row());
+ }
+
+ void addTerm(const QString &term)
+ {
+ if (!termList.contains(term)) {
+ termList.append(term);
+ reset();
+ }
+ }
+
+ private:
+ QStringList termList;
+ };
+
+ QHelpSearchQueryWidgetPrivate()
+ : QObject()
+ , simpleSearch(true)
+ , searchCompleter(new CompleterModel(this), this)
+ {
+ searchButton = 0;
+ advancedSearchWidget = 0;
+ showHideAdvancedSearchButton = 0;
+ defaultQuery = 0;
+ exactQuery = 0;
+ similarQuery = 0;
+ withoutQuery = 0;
+ allQuery = 0;
+ atLeastQuery = 0;
+ }
+
+ ~QHelpSearchQueryWidgetPrivate()
+ {
+ // nothing todo
+ }
+
+ void retranslate()
+ {
+ simpleSearchLabel->setText(QHelpSearchQueryWidget::tr("Search for:"));
+ prevQueryButton->setToolTip(QHelpSearchQueryWidget::tr("Previous search"));
+ nextQueryButton->setToolTip(QHelpSearchQueryWidget::tr("Next search"));
+ searchButton->setText(QHelpSearchQueryWidget::tr("Search"));
+#ifdef QT_CLUCENE_SUPPORT
+ advancedSearchLabel->setText(QHelpSearchQueryWidget::tr("Advanced search"));
+ similarLabel->setText(QHelpSearchQueryWidget::tr("words <B>similar</B> to:"));
+ withoutLabel->setText(QHelpSearchQueryWidget::tr("<B>without</B> the words:"));
+ exactLabel->setText(QHelpSearchQueryWidget::tr("with <B>exact phrase</B>:"));
+ allLabel->setText(QHelpSearchQueryWidget::tr("with <B>all</B> of the words:"));
+ atLeastLabel->setText(QHelpSearchQueryWidget::tr("with <B>at least one</B> of the words:"));
+#endif
+ }
+
+ QStringList buildTermList(const QString query)
+ {
+ bool s = false;
+ QString phrase;
+ QStringList wordList;
+ QString searchTerm = query;
+
+ for (int i = 0; i < searchTerm.length(); ++i) {
+ if (searchTerm[i] == QLatin1Char('\"') && !s) {
+ s = true;
+ phrase = searchTerm[i];
+ continue;
+ }
+ if (searchTerm[i] != QLatin1Char('\"') && s)
+ phrase += searchTerm[i];
+ if (searchTerm[i] == QLatin1Char('\"') && s) {
+ s = false;
+ phrase += searchTerm[i];
+ wordList.append(phrase);
+ searchTerm.remove(phrase);
+ }
+ }
+ if (s)
+ searchTerm.replace(phrase, phrase.mid(1));
+
+ const QRegExp exp(QLatin1String("\\s+"));
+ wordList += searchTerm.split(exp, QString::SkipEmptyParts);
+ return wordList;
+ }
+
+ void saveQuery(const QList<QHelpSearchQuery> &query, QueryHistory &queryHist)
+ {
+ // We only add the query to the list if it is different from the last one.
+ bool insert = false;
+ if (queryHist.queries.empty())
+ insert = true;
+ else {
+ const QList<QHelpSearchQuery> &lastQuery = queryHist.queries.last();
+ if (lastQuery.size() != query.size()) {
+ insert = true;
+ } else {
+ for (int i = 0; i < query.size(); ++i) {
+ if (query.at(i).fieldName != lastQuery.at(i).fieldName
+ || query.at(i).wordList != lastQuery.at(i).wordList) {
+ insert = true;
+ break;
+ }
+ }
+ }
+ }
+ if (insert) {
+ queryHist.queries.append(query);
+ foreach (const QHelpSearchQuery &queryPart, query) {
+ static_cast<CompleterModel *>(searchCompleter.model())->
+ addTerm(queryPart.wordList.join(" "));
+ }
+ }
+ }
+
+ void nextOrPrevQuery(int maxOrMinIndex, int addend, QToolButton *thisButton,
+ QToolButton *otherButton)
+ {
+ QueryHistory *queryHist;
+ QList<QLineEdit *> lineEdits;
+ if (simpleSearch) {
+ queryHist = &simpleQueries;
+ lineEdits << defaultQuery;
+ } else {
+ queryHist = &complexQueries;
+ lineEdits << allQuery << atLeastQuery << similarQuery
+ << withoutQuery << exactQuery;
+ }
+ foreach (QLineEdit *lineEdit, lineEdits)
+ lineEdit->clear();
+
+ // Otherwise, the respective button would be disabled.
+ Q_ASSERT(queryHist->curQuery != maxOrMinIndex);
+
+ queryHist->curQuery += addend;
+ const QList<QHelpSearchQuery> &query =
+ queryHist->queries.at(queryHist->curQuery);
+ foreach (const QHelpSearchQuery &queryPart, query) {
+ if (QLineEdit *lineEdit = lineEditFor(queryPart.fieldName))
+ lineEdit->setText(queryPart.wordList.join(" "));
+ }
+
+ if (queryHist->curQuery == maxOrMinIndex)
+ thisButton->setEnabled(false);
+ otherButton->setEnabled(true);
+ }
+
+ QLineEdit* lineEditFor(const QHelpSearchQuery::FieldName &fieldName) const
+ {
+ switch (fieldName) {
+ case QHelpSearchQuery::DEFAULT:
+ return defaultQuery;
+ case QHelpSearchQuery::ALL:
+ return allQuery;
+ case QHelpSearchQuery::ATLEAST:
+ return atLeastQuery;
+ case QHelpSearchQuery::FUZZY:
+ return similarQuery;
+ case QHelpSearchQuery::WITHOUT:
+ return withoutQuery;
+ case QHelpSearchQuery::PHRASE:
+ return exactQuery;
+ default:
+ Q_ASSERT(0);
+ }
+ return 0;
+ }
+
+ void enableOrDisableToolButtons()
+ {
+ const QueryHistory &queryHist = simpleSearch ? simpleQueries
+ : complexQueries;
+ prevQueryButton->setEnabled(queryHist.curQuery > 0);
+ nextQueryButton->setEnabled(queryHist.curQuery
+ < queryHist.queries.size() - 1);
+ }
+
+private slots:
+ void showHideAdvancedSearch()
+ {
+ if (simpleSearch) {
+ advancedSearchWidget->show();
+ showHideAdvancedSearchButton->setText((QLatin1String("-")));
+ } else {
+ advancedSearchWidget->hide();
+ showHideAdvancedSearchButton->setText((QLatin1String("+")));
+ }
+
+ simpleSearch = !simpleSearch;
+ defaultQuery->setEnabled(simpleSearch);
+ enableOrDisableToolButtons();
+ }
+
+ void searchRequested()
+ {
+ QList<QHelpSearchQuery> queryList;
+#if !defined(QT_CLUCENE_SUPPORT)
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
+ QStringList(defaultQuery->text())));
+
+#else
+ if (defaultQuery->isEnabled()) {
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
+ buildTermList(defaultQuery->text())));
+ } else {
+ const QRegExp exp(QLatin1String("\\s+"));
+ QStringList lst = similarQuery->text().split(exp,
+ QString::SkipEmptyParts);
+ if (!lst.isEmpty()) {
+ QStringList fuzzy;
+ foreach (const QString &term, lst)
+ fuzzy += buildTermList(term);
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY,
+ fuzzy));
+ }
+
+ lst = withoutQuery->text().split(exp, QString::SkipEmptyParts);
+ if (!lst.isEmpty()) {
+ QStringList without;
+ foreach (const QString &term, lst)
+ without.append(term);
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT,
+ without));
+ }
+
+ if (!exactQuery->text().isEmpty()) {
+ QString phrase = exactQuery->text().remove(QLatin1Char('\"'));
+ phrase = phrase.simplified();
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE,
+ QStringList(phrase)));
+ }
+
+ lst = allQuery->text().split(exp, QString::SkipEmptyParts);
+ if (!lst.isEmpty()) {
+ QStringList all;
+ foreach (const QString &term, lst)
+ all.append(term);
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all));
+ }
+
+ lst = atLeastQuery->text().split(exp, QString::SkipEmptyParts);
+ if (!lst.isEmpty()) {
+ QStringList atLeast;
+ foreach (const QString &term, lst)
+ atLeast += buildTermList(term);
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST,
+ atLeast));
+ }
+ }
+#endif
+ QueryHistory &queryHist = simpleSearch ? simpleQueries : complexQueries;
+ saveQuery(queryList, queryHist);
+ queryHist.curQuery = queryHist.queries.size() - 1;
+ if (queryHist.curQuery > 0)
+ prevQueryButton->setEnabled(true);
+ nextQueryButton->setEnabled(false);
+ }
+
+ void nextQuery()
+ {
+ nextOrPrevQuery((simpleSearch ? simpleQueries
+ : complexQueries).queries.size() - 1, 1, nextQueryButton,
+ prevQueryButton);
+ }
+
+ void prevQuery()
+ {
+ nextOrPrevQuery(0, -1, prevQueryButton, nextQueryButton);
+ }
+
+private:
+ friend class QHelpSearchQueryWidget;
+
+ bool simpleSearch;
+ QLabel *simpleSearchLabel;
+ QLabel *advancedSearchLabel;
+ QLabel *similarLabel;
+ QLabel *withoutLabel;
+ QLabel *exactLabel;
+ QLabel *allLabel;
+ QLabel *atLeastLabel;
+ QPushButton *searchButton;
+ QWidget* advancedSearchWidget;
+ QToolButton *showHideAdvancedSearchButton;
+ QLineEdit *defaultQuery;
+ QLineEdit *exactQuery;
+ QLineEdit *similarQuery;
+ QLineEdit *withoutQuery;
+ QLineEdit *allQuery;
+ QLineEdit *atLeastQuery;
+ QToolButton *nextQueryButton;
+ QToolButton *prevQueryButton;
+ QueryHistory simpleQueries;
+ QueryHistory complexQueries;
+ QCompleter searchCompleter;
+};
+
+#include "qhelpsearchquerywidget.moc"
+
+
+/*!
+ \class QHelpSearchQueryWidget
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpSearchQueryWidget class provides a simple line edit or
+ an advanced widget to enable the user to input a search term in a
+ standardized input mask.
+*/
+
+/*!
+ \fn void QHelpSearchQueryWidget::search()
+
+ This signal is emitted when a the user has the search button invoked.
+ After reciving the signal you can ask the QHelpSearchQueryWidget for the
+ build list of QHelpSearchQuery's that you may pass to the QHelpSearchEngine's
+ search() function.
+*/
+
+/*!
+ Constructs a new search query widget with the given \a parent.
+*/
+QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ d = new QHelpSearchQueryWidgetPrivate();
+
+ QVBoxLayout *vLayout = new QVBoxLayout(this);
+ vLayout->setMargin(0);
+
+ QHBoxLayout* hBoxLayout = new QHBoxLayout();
+ d->simpleSearchLabel = new QLabel(this);
+ d->defaultQuery = new QLineEdit(this);
+ d->defaultQuery->setCompleter(&d->searchCompleter);
+ d->prevQueryButton = new QToolButton(this);
+ d->prevQueryButton->setArrowType(Qt::LeftArrow);
+ d->prevQueryButton->setEnabled(false);
+ d->nextQueryButton = new QToolButton(this);
+ d->nextQueryButton->setArrowType(Qt::RightArrow);
+ d->nextQueryButton->setEnabled(false);
+ d->searchButton = new QPushButton(this);
+ hBoxLayout->addWidget(d->simpleSearchLabel);
+ hBoxLayout->addWidget(d->defaultQuery);
+ hBoxLayout->addWidget(d->prevQueryButton);
+ hBoxLayout->addWidget(d->nextQueryButton);
+ hBoxLayout->addWidget(d->searchButton);
+
+ vLayout->addLayout(hBoxLayout);
+
+ connect(d->prevQueryButton, SIGNAL(clicked()), d, SLOT(prevQuery()));
+ connect(d->nextQueryButton, SIGNAL(clicked()), d, SLOT(nextQuery()));
+ connect(d->searchButton, SIGNAL(clicked()), this, SIGNAL(search()));
+ connect(d->defaultQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+
+#if defined(QT_CLUCENE_SUPPORT)
+ hBoxLayout = new QHBoxLayout();
+ d->showHideAdvancedSearchButton = new QToolButton(this);
+ d->showHideAdvancedSearchButton->setText(QLatin1String("+"));
+ d->showHideAdvancedSearchButton->setMinimumSize(25, 20);
+
+ d->advancedSearchLabel = new QLabel(this);
+ QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
+ sizePolicy.setHeightForWidth(d->advancedSearchLabel->sizePolicy().hasHeightForWidth());
+ d->advancedSearchLabel->setSizePolicy(sizePolicy);
+
+ QFrame* hLine = new QFrame(this);
+ hLine->setFrameStyle(QFrame::HLine);
+ hBoxLayout->addWidget(d->showHideAdvancedSearchButton);
+ hBoxLayout->addWidget(d->advancedSearchLabel);
+ hBoxLayout->addWidget(hLine);
+
+ vLayout->addLayout(hBoxLayout);
+
+ // setup advanced search layout
+ d->advancedSearchWidget = new QWidget(this);
+ QGridLayout *gLayout = new QGridLayout(d->advancedSearchWidget);
+ gLayout->setMargin(0);
+
+ d->similarLabel = new QLabel(this);
+ gLayout->addWidget(d->similarLabel, 0, 0);
+ d->similarQuery = new QLineEdit(this);
+ d->similarQuery->setCompleter(&d->searchCompleter);
+ gLayout->addWidget(d->similarQuery, 0, 1);
+
+ d->withoutLabel = new QLabel(this);
+ gLayout->addWidget(d->withoutLabel, 1, 0);
+ d->withoutQuery = new QLineEdit(this);
+ d->withoutQuery->setCompleter(&d->searchCompleter);
+ gLayout->addWidget(d->withoutQuery, 1, 1);
+
+ d->exactLabel = new QLabel(this);
+ gLayout->addWidget(d->exactLabel, 2, 0);
+ d->exactQuery = new QLineEdit(this);
+ d->exactQuery->setCompleter(&d->searchCompleter);
+ gLayout->addWidget(d->exactQuery, 2, 1);
+
+ d->allLabel = new QLabel(this);
+ gLayout->addWidget(d->allLabel, 3, 0);
+ d->allQuery = new QLineEdit(this);
+ d->allQuery->setCompleter(&d->searchCompleter);
+ gLayout->addWidget(d->allQuery, 3, 1);
+
+ d->atLeastLabel = new QLabel(this);
+ gLayout->addWidget(d->atLeastLabel, 4, 0);
+ d->atLeastQuery = new QLineEdit(this);
+ d->atLeastQuery->setCompleter(&d->searchCompleter);
+ gLayout->addWidget(d->atLeastQuery, 4, 1);
+
+ vLayout->addWidget(d->advancedSearchWidget);
+ d->advancedSearchWidget->hide();
+
+ d->retranslate();
+
+ connect(d->exactQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->similarQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->withoutQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->allQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->atLeastQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
+ connect(d->showHideAdvancedSearchButton, SIGNAL(clicked()),
+ d, SLOT(showHideAdvancedSearch()));
+#endif
+ connect(this, SIGNAL(search()), d, SLOT(searchRequested()));
+}
+
+/*!
+ Destroys the search query widget.
+*/
+QHelpSearchQueryWidget::~QHelpSearchQueryWidget()
+{
+ delete d;
+}
+
+/*!
+ Expands the search query widget so that the extended search fields are shown.
+*/
+void QHelpSearchQueryWidget::expandExtendedSearch()
+{
+ if (d->simpleSearch)
+ d->showHideAdvancedSearch();
+}
+
+/*!
+ Collapses the search query widget so that only the default search field is
+ shown.
+*/
+void QHelpSearchQueryWidget::collapseExtendedSearch()
+{
+ if (!d->simpleSearch)
+ d->showHideAdvancedSearch();
+}
+
+/*!
+ Returns a list of queries to use in combination with the search engines
+ search(QList<QHelpSearchQuery> &queryList) function.
+*/
+QList<QHelpSearchQuery> QHelpSearchQueryWidget::query() const
+{
+ const QHelpSearchQueryWidgetPrivate::QueryHistory &queryHist =
+ d->simpleSearch ? d->simpleQueries : d->complexQueries;
+ return queryHist.queries.isEmpty() ?
+ QList<QHelpSearchQuery>() : queryHist.queries.last();
+}
+
+/*!
+ Sets the QHelpSearchQueryWidget input fields to the values specified by
+ \a queryList search field name. Please note that one has to call the search
+ engine's search(QList<QHelpSearchQuery> &queryList) function to perform the
+ actual search.
+*/
+void QHelpSearchQueryWidget::setQuery(const QList<QHelpSearchQuery> &queryList)
+{
+ QList<QLineEdit *> lineEdits;
+ lineEdits << d->defaultQuery << d->allQuery << d->atLeastQuery
+ << d->similarQuery << d->withoutQuery << d->exactQuery;
+ foreach (QLineEdit *lineEdit, lineEdits)
+ lineEdit->clear();
+
+ const QLatin1String space(" ");
+ foreach (const QHelpSearchQuery &q, queryList) {
+ if (QLineEdit *lineEdit = d->lineEditFor(q.fieldName))
+ lineEdit->setText(lineEdit->text() + q.wordList.join(space) + space);
+ }
+ d->searchRequested();
+}
+
+/*!
+ \reimp
+*/
+void QHelpSearchQueryWidget::focusInEvent(QFocusEvent *focusEvent)
+{
+ if (focusEvent->reason() != Qt::MouseFocusReason) {
+ d->defaultQuery->selectAll();
+ d->defaultQuery->setFocus();
+ }
+}
+
+/*! \reimp
+*/
+void QHelpSearchQueryWidget::changeEvent(QEvent *event)
+{
+ if (event->type() == QEvent::LanguageChange)
+ d->retranslate();
+ else
+ QWidget::changeEvent(event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchquerywidget.h b/src/assistant/lib/qhelpsearchquerywidget.h
new file mode 100644
index 000000000..e9fb61ceb
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchquerywidget.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHQUERYWIDGET_H
+#define QHELPSEARCHQUERYWIDGET_H
+
+#include <QtHelp/qhelp_global.h>
+#include <QtHelp/qhelpsearchengine.h>
+
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QFocusEvent;
+class QHelpSearchQueryWidgetPrivate;
+
+class QHELP_EXPORT QHelpSearchQueryWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ QHelpSearchQueryWidget(QWidget *parent = 0);
+ ~QHelpSearchQueryWidget();
+
+ void expandExtendedSearch();
+ void collapseExtendedSearch();
+
+ QList<QHelpSearchQuery> query() const;
+ void setQuery(const QList<QHelpSearchQuery> &queryList);
+
+Q_SIGNALS:
+ void search();
+
+private:
+ virtual void focusInEvent(QFocusEvent *focusEvent);
+ virtual void changeEvent(QEvent *event);
+
+private:
+ QHelpSearchQueryWidgetPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPSEARCHQUERYWIDGET_H
diff --git a/src/assistant/lib/qhelpsearchresultwidget.cpp b/src/assistant/lib/qhelpsearchresultwidget.cpp
new file mode 100644
index 000000000..2b5845062
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchresultwidget.cpp
@@ -0,0 +1,447 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhelpsearchresultwidget.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QPointer>
+#include <QtCore/QStringList>
+
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QHeaderView>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QToolButton>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QTextBrowser>
+#include <QtGui/QTreeWidgetItem>
+
+QT_BEGIN_NAMESPACE
+
+class QDefaultResultWidget : public QTreeWidget
+{
+ Q_OBJECT
+
+public:
+ QDefaultResultWidget(QWidget *parent = 0)
+ : QTreeWidget(parent)
+ {
+ header()->hide();
+ connect(this, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
+ this, SLOT(itemActivated(QTreeWidgetItem*,int)));
+ }
+
+ void showResultPage(const QList<QHelpSearchEngine::SearchHit> hits)
+ {
+ foreach (const QHelpSearchEngine::SearchHit &hit, hits)
+ new QTreeWidgetItem(this, QStringList(hit.first) << hit.second);
+ }
+
+signals:
+ void requestShowLink(const QUrl &url);
+
+private slots:
+ void itemActivated(QTreeWidgetItem *item, int /* column */)
+ {
+ if (item) {
+ QString data = item->data(1, Qt::DisplayRole).toString();
+ emit requestShowLink(data);
+ }
+ }
+};
+
+
+class QCLuceneResultWidget : public QTextBrowser
+{
+ Q_OBJECT
+
+public:
+ QCLuceneResultWidget(QWidget *parent = 0)
+ : QTextBrowser(parent)
+ {
+ connect(this, SIGNAL(anchorClicked(QUrl)),
+ this, SIGNAL(requestShowLink(QUrl)));
+ setContextMenuPolicy(Qt::NoContextMenu);
+ }
+
+ void showResultPage(const QList<QHelpSearchEngine::SearchHit> hits, bool isIndexing)
+ {
+ QString htmlFile = QString(QLatin1String("<html><head><title>%1</title></head><body>"))
+ .arg(tr("Search Results"));
+
+ int count = hits.count();
+ if (count != 0) {
+ if (isIndexing)
+ htmlFile += QString(QLatin1String("<div style=\"text-align:left; font-weight:bold; color:red\">"
+ "%1&nbsp;<span style=\"font-weight:normal; color:black\">"
+ "%2</span></div></div><br>")).arg(tr("Note:"))
+ .arg(tr("The search results may not be complete since the "
+ "documentation is still being indexed!"));
+
+ foreach (const QHelpSearchEngine::SearchHit &hit, hits) {
+ htmlFile += QString(QLatin1String("<div style=\"text-align:left; font-weight:bold\""
+ "><a href=\"%1\">%2</a><div style=\"color:green; font-weight:normal;"
+ " margin:5px\">%1</div></div><p></p>"))
+ .arg(hit.first).arg(hit.second);
+ }
+ } else {
+ htmlFile += QLatin1String("<div align=\"center\"><br><br><h2>")
+ + tr("Your search did not match any documents.")
+ + QLatin1String("</h2><div>");
+ if (isIndexing)
+ htmlFile += QLatin1String("<div align=\"center\"><h3>")
+ + tr("(The reason for this might be that the documentation "
+ "is still being indexed.)")
+ + QLatin1String("</h3><div>");
+ }
+
+ htmlFile += QLatin1String("</body></html>");
+
+ setHtml(htmlFile);
+ }
+
+signals:
+ void requestShowLink(const QUrl &url);
+
+private slots:
+ void setSource(const QUrl & /* name */) {}
+};
+
+
+class QHelpSearchResultWidgetPrivate : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void setResults(int hitsCount)
+ {
+ if (!searchEngine.isNull()) {
+#if defined(QT_CLUCENE_SUPPORT)
+ showFirstResultPage();
+ updateNextButtonState(((hitsCount > 20) ? true : false));
+#else
+ resultTreeWidget->clear();
+ resultTreeWidget->showResultPage(searchEngine->hits(0, hitsCount));
+#endif
+ }
+ }
+
+ void showNextResultPage()
+ {
+ if (!searchEngine.isNull()
+ && resultLastToShow < searchEngine->hitCount()) {
+ resultLastToShow += 20;
+ resultFirstToShow += 20;
+
+ resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow,
+ resultLastToShow), isIndexing);
+ if (resultLastToShow >= searchEngine->hitCount())
+ updateNextButtonState(false);
+ }
+ updateHitRange();
+ }
+
+ void showLastResultPage()
+ {
+ if (!searchEngine.isNull()) {
+ resultLastToShow = searchEngine->hitCount();
+ resultFirstToShow = resultLastToShow - (resultLastToShow % 20);
+
+ if (resultFirstToShow == resultLastToShow)
+ resultFirstToShow -= 20;
+
+ resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow,
+ resultLastToShow), isIndexing);
+ updateNextButtonState(false);
+ }
+ updateHitRange();
+ }
+
+ void showFirstResultPage()
+ {
+ if (!searchEngine.isNull()) {
+ resultLastToShow = 20;
+ resultFirstToShow = 0;
+
+ resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow,
+ resultLastToShow), isIndexing);
+ updatePrevButtonState(false);
+ }
+ updateHitRange();
+ }
+
+ void showPreviousResultPage()
+ {
+ if (!searchEngine.isNull()) {
+ int count = resultLastToShow % 20;
+ if (count == 0 || resultLastToShow != searchEngine->hitCount())
+ count = 20;
+
+ resultLastToShow -= count;
+ resultFirstToShow = resultLastToShow -20;
+
+ resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow,
+ resultLastToShow), isIndexing);
+ if (resultFirstToShow == 0)
+ updatePrevButtonState(false);
+ }
+ updateHitRange();
+ }
+
+ void updatePrevButtonState(bool state = true)
+ {
+ firstResultPage->setEnabled(state);
+ previousResultPage->setEnabled(state);
+ }
+
+ void updateNextButtonState(bool state = true)
+ {
+ nextResultPage->setEnabled(state);
+ lastResultPage->setEnabled(state);
+ }
+
+ void indexingStarted()
+ {
+ isIndexing = true;
+ }
+
+ void indexingFinished()
+ {
+ isIndexing = false;
+ }
+
+private:
+ QHelpSearchResultWidgetPrivate(QHelpSearchEngine *engine)
+ : QObject()
+ , searchEngine(engine)
+ , isIndexing(false)
+ {
+ resultTreeWidget = 0;
+ resultTextBrowser = 0;
+
+ resultLastToShow = 20;
+ resultFirstToShow = 0;
+
+ firstResultPage = 0;
+ previousResultPage = 0;
+ hitsLabel = 0;
+ nextResultPage = 0;
+ lastResultPage = 0;
+
+ connect(searchEngine, SIGNAL(indexingStarted()),
+ this, SLOT(indexingStarted()));
+ connect(searchEngine, SIGNAL(indexingFinished()),
+ this, SLOT(indexingFinished()));
+ }
+
+ ~QHelpSearchResultWidgetPrivate()
+ {
+ delete searchEngine;
+ }
+
+ QToolButton* setupToolButton(const QString &iconPath)
+ {
+ QToolButton *button = new QToolButton();
+ button->setEnabled(false);
+ button->setAutoRaise(true);
+ button->setIcon(QIcon(iconPath));
+ button->setIconSize(QSize(12, 12));
+ button->setMaximumSize(QSize(16, 16));
+
+ return button;
+ }
+
+ void updateHitRange()
+ {
+ int last = 0;
+ int first = 0;
+ int count = 0;
+
+ if (!searchEngine.isNull()) {
+ count = searchEngine->hitCount();
+ if (count > 0) {
+ first = resultFirstToShow +1;
+ last = resultLastToShow > count ? count : resultLastToShow;
+ }
+ }
+ hitsLabel->setText(QHelpSearchResultWidget::tr("%1 - %2 of %n Hits", 0, count).arg(first).arg(last));
+ }
+
+private:
+ friend class QHelpSearchResultWidget;
+
+ QPointer<QHelpSearchEngine> searchEngine;
+
+ QDefaultResultWidget *resultTreeWidget;
+ QCLuceneResultWidget *resultTextBrowser;
+
+ int resultLastToShow;
+ int resultFirstToShow;
+ bool isIndexing;
+
+ QToolButton *firstResultPage;
+ QToolButton *previousResultPage;
+ QLabel *hitsLabel;
+ QToolButton *nextResultPage;
+ QToolButton *lastResultPage;
+};
+
+#include "qhelpsearchresultwidget.moc"
+
+
+/*!
+ \class QHelpSearchResultWidget
+ \since 4.4
+ \inmodule QtHelp
+ \brief The QHelpSearchResultWidget class provides either a tree
+ widget or a text browser depending on the used search engine to display
+ the hits found by the search.
+*/
+
+/*!
+ \fn void QHelpSearchResultWidget::requestShowLink(const QUrl &link)
+
+ This signal is emitted when a item is activated and its associated
+ \a link should be shown.
+*/
+
+QHelpSearchResultWidget::QHelpSearchResultWidget(QHelpSearchEngine *engine)
+ : QWidget(0)
+ , d(new QHelpSearchResultWidgetPrivate(engine))
+{
+ QVBoxLayout *vLayout = new QVBoxLayout(this);
+ vLayout->setMargin(0);
+ vLayout->setSpacing(0);
+
+#if defined(QT_CLUCENE_SUPPORT)
+ QHBoxLayout *hBoxLayout = new QHBoxLayout();
+#ifndef Q_OS_MAC
+ hBoxLayout->setMargin(0);
+ hBoxLayout->setSpacing(0);
+#endif
+ hBoxLayout->addWidget(d->firstResultPage = d->setupToolButton(
+ QString::fromUtf8(":/trolltech/assistant/images/3leftarrow.png")));
+
+ hBoxLayout->addWidget(d->previousResultPage = d->setupToolButton(
+ QString::fromUtf8(":/trolltech/assistant/images/1leftarrow.png")));
+
+ d->hitsLabel = new QLabel(tr("0 - 0 of 0 Hits"), this);
+ d->hitsLabel->setEnabled(false);
+ hBoxLayout->addWidget(d->hitsLabel);
+ d->hitsLabel->setAlignment(Qt::AlignCenter);
+ d->hitsLabel->setMinimumSize(QSize(150, d->hitsLabel->height()));
+
+ hBoxLayout->addWidget(d->nextResultPage = d->setupToolButton(
+ QString::fromUtf8(":/trolltech/assistant/images/1rightarrow.png")));
+
+ hBoxLayout->addWidget(d->lastResultPage = d->setupToolButton(
+ QString::fromUtf8(":/trolltech/assistant/images/3rightarrow.png")));
+
+ QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ hBoxLayout->addItem(spacer);
+
+ vLayout->addLayout(hBoxLayout);
+
+ d->resultTextBrowser = new QCLuceneResultWidget(this);
+ vLayout->addWidget(d->resultTextBrowser);
+
+ connect(d->resultTextBrowser, SIGNAL(requestShowLink(QUrl)), this,
+ SIGNAL(requestShowLink(QUrl)));
+
+ connect(d->nextResultPage, SIGNAL(clicked()), d, SLOT(showNextResultPage()));
+ connect(d->lastResultPage, SIGNAL(clicked()), d, SLOT(showLastResultPage()));
+ connect(d->firstResultPage, SIGNAL(clicked()), d, SLOT(showFirstResultPage()));
+ connect(d->previousResultPage, SIGNAL(clicked()), d, SLOT(showPreviousResultPage()));
+
+ connect(d->firstResultPage, SIGNAL(clicked()), d, SLOT(updateNextButtonState()));
+ connect(d->previousResultPage, SIGNAL(clicked()), d, SLOT(updateNextButtonState()));
+ connect(d->nextResultPage, SIGNAL(clicked()), d, SLOT(updatePrevButtonState()));
+ connect(d->lastResultPage, SIGNAL(clicked()), d, SLOT(updatePrevButtonState()));
+
+#else
+ d->resultTreeWidget = new QDefaultResultWidget(this);
+ vLayout->addWidget(d->resultTreeWidget);
+ connect(d->resultTreeWidget, SIGNAL(requestShowLink(QUrl)), this,
+ SIGNAL(requestShowLink(QUrl)));
+#endif
+
+ connect(engine, SIGNAL(searchingFinished(int)), d, SLOT(setResults(int)));
+}
+
+/*! \reimp
+*/
+void QHelpSearchResultWidget::changeEvent(QEvent *event)
+{
+ if (event->type() == QEvent::LanguageChange)
+ d->setResults(d->searchEngine->hitCount());
+}
+
+/*!
+ Destroys the search result widget.
+*/
+QHelpSearchResultWidget::~QHelpSearchResultWidget()
+{
+ delete d;
+}
+
+/*!
+ Returns a reference of the URL that the item at \a point owns, or an
+ empty URL if no item exists at that point.
+*/
+QUrl QHelpSearchResultWidget::linkAt(const QPoint &point)
+{
+ QUrl url;
+#if defined(QT_CLUCENE_SUPPORT)
+ if (d->resultTextBrowser)
+ url = d->resultTextBrowser->anchorAt(point);
+#else
+ if (d->resultTreeWidget) {
+ QTreeWidgetItem *item = d->resultTreeWidget->itemAt(point);
+ if (item)
+ url = item->data(1, Qt::DisplayRole).toString();
+ }
+#endif
+ return url;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/lib/qhelpsearchresultwidget.h b/src/assistant/lib/qhelpsearchresultwidget.h
new file mode 100644
index 000000000..cd6ac1051
--- /dev/null
+++ b/src/assistant/lib/qhelpsearchresultwidget.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHELPSEARCHRESULTWIDGET_H
+#define QHELPSEARCHRESULTWIDGET_H
+
+#include <QtHelp/qhelpsearchengine.h>
+#include <QtHelp/qhelp_global.h>
+
+#include <QtCore/QUrl>
+#include <QtCore/QPoint>
+#include <QtCore/QObject>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Help)
+
+class QHelpSearchResultWidgetPrivate;
+
+class QHELP_EXPORT QHelpSearchResultWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ~QHelpSearchResultWidget();
+ QUrl linkAt(const QPoint &point);
+
+Q_SIGNALS:
+ void requestShowLink(const QUrl &url);
+
+private:
+ friend class QHelpSearchEngine;
+
+ QHelpSearchResultWidgetPrivate *d;
+ QHelpSearchResultWidget(QHelpSearchEngine *engine);
+ virtual void changeEvent(QEvent *event);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHELPSEARCHRESULTWIDGET_H
diff --git a/src/assistant/tools/assistant/Info_mac.plist b/src/assistant/tools/assistant/Info_mac.plist
new file mode 100644
index 000000000..76369a1c5
--- /dev/null
+++ b/src/assistant/tools/assistant/Info_mac.plist
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>@ICON@</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.trolltech.assistant</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+</dict>
+</plist>
diff --git a/src/assistant/tools/assistant/aboutdialog.cpp b/src/assistant/tools/assistant/aboutdialog.cpp
new file mode 100644
index 000000000..b4c390e90
--- /dev/null
+++ b/src/assistant/tools/assistant/aboutdialog.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "aboutdialog.h"
+
+#include "helpviewer.h"
+#include "tracer.h"
+
+#include <QtCore/QBuffer>
+
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+#include <QtGui/QLayout>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QMessageBox>
+#include <QtGui/QDesktopServices>
+
+QT_BEGIN_NAMESPACE
+
+AboutLabel::AboutLabel(QWidget *parent)
+ : QTextBrowser(parent)
+{
+ TRACE_OBJ
+ setFrameStyle(QFrame::NoFrame);
+ QPalette p;
+ p.setColor(QPalette::Base, p.color(QPalette::Background));
+ setPalette(p);
+}
+
+void AboutLabel::setText(const QString &text, const QByteArray &resources)
+{
+ TRACE_OBJ
+ QDataStream in(resources);
+ in >> m_resourceMap;
+
+ QTextBrowser::setText(text);
+}
+
+QSize AboutLabel::minimumSizeHint() const
+{
+ TRACE_OBJ
+ QTextDocument *doc = document();
+ doc->adjustSize();
+ return QSize(int(doc->size().width()), int(doc->size().height()));
+}
+
+QVariant AboutLabel::loadResource(int type, const QUrl &name)
+{
+ TRACE_OBJ
+ if (type == 2 || type == 3) {
+ if (m_resourceMap.contains(name.toString())) {
+ return m_resourceMap.value(name.toString());
+ }
+ }
+ return QVariant();
+}
+
+void AboutLabel::setSource(const QUrl &url)
+{
+ TRACE_OBJ
+ if (url.isValid() && (!HelpViewer::isLocalUrl(url)
+ || !HelpViewer::canOpenPage(url.path()))) {
+ if (!QDesktopServices::openUrl(url)) {
+ QMessageBox::warning(this, tr("Warning"),
+ tr("Unable to launch external application.\n"), tr("OK"));
+ }
+ }
+}
+
+AboutDialog::AboutDialog(QWidget *parent)
+ : QDialog(parent, Qt::MSWindowsFixedSizeDialogHint |
+ Qt::WindowTitleHint|Qt::WindowSystemMenuHint)
+{
+ TRACE_OBJ
+ m_pixmapLabel = 0;
+ m_aboutLabel = new AboutLabel();
+
+ m_closeButton = new QPushButton();
+ m_closeButton->setText(tr("&Close"));
+ connect(m_closeButton, SIGNAL(clicked()), this, SLOT(close()));
+
+ m_layout = new QGridLayout(this);
+ m_layout->addWidget(m_aboutLabel, 1, 0, 1, -1);
+ m_layout->addItem(new QSpacerItem(20, 10, QSizePolicy::Minimum,
+ QSizePolicy::Fixed), 2, 1, 1, 1);
+ m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 0, 1, 1);
+ m_layout->addWidget(m_closeButton, 3, 1, 1, 1);
+ m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 2, 1, 1);
+}
+
+void AboutDialog::setText(const QString &text, const QByteArray &resources)
+{
+ TRACE_OBJ
+ m_aboutLabel->setText(text, resources);
+ updateSize();
+}
+
+void AboutDialog::setPixmap(const QPixmap &pixmap)
+{
+ TRACE_OBJ
+ if (!m_pixmapLabel) {
+ m_pixmapLabel = new QLabel();
+ m_layout->addWidget(m_pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter);
+ }
+ m_pixmapLabel->setPixmap(pixmap);
+ updateSize();
+}
+
+QString AboutDialog::documentTitle() const
+{
+ TRACE_OBJ
+ return m_aboutLabel->documentTitle();
+}
+
+void AboutDialog::updateSize()
+{
+ TRACE_OBJ
+ QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos())
+ .size();
+ int limit = qMin(screenSize.width()/2, 500);
+
+#ifdef Q_WS_MAC
+ limit = qMin(screenSize.width()/2, 420);
+#endif
+
+ layout()->activate();
+ int width = layout()->totalMinimumSize().width();
+
+ if (width > limit)
+ width = limit;
+
+ QFontMetrics fm(qApp->font("QWorkspaceTitleBar"));
+ int windowTitleWidth = qMin(fm.width(windowTitle()) + 50, limit);
+ if (windowTitleWidth > width)
+ width = windowTitleWidth;
+
+ layout()->activate();
+ int height = (layout()->hasHeightForWidth())
+ ? layout()->totalHeightForWidth(width)
+ : layout()->totalMinimumSize().height();
+ setFixedSize(width, height);
+ QCoreApplication::removePostedEvents(this, QEvent::LayoutRequest);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/aboutdialog.h b/src/assistant/tools/assistant/aboutdialog.h
new file mode 100644
index 000000000..292312d05
--- /dev/null
+++ b/src/assistant/tools/assistant/aboutdialog.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABOUTDIALOG_H
+#define ABOUTDIALOG_H
+
+#include <QtGui/QTextBrowser>
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QLabel;
+class QPushButton;
+class QGridLayout;
+
+class AboutLabel : public QTextBrowser
+{
+ Q_OBJECT
+
+public:
+ AboutLabel(QWidget *parent = 0);
+ void setText(const QString &text, const QByteArray &resources);
+ QSize minimumSizeHint() const;
+
+private:
+ QVariant loadResource(int type, const QUrl &name);
+ void setSource(const QUrl &url);
+
+ QMap<QString, QByteArray> m_resourceMap;
+};
+
+class AboutDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ AboutDialog(QWidget *parent = 0);
+ void setText(const QString &text, const QByteArray &resources);
+ void setPixmap(const QPixmap &pixmap);
+ QString documentTitle() const;
+
+private:
+ void updateSize();
+
+ QLabel *m_pixmapLabel;
+ AboutLabel *m_aboutLabel;
+ QPushButton *m_closeButton;
+ QGridLayout *m_layout;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/assistant/assistant.icns b/src/assistant/tools/assistant/assistant.icns
new file mode 100644
index 000000000..6291dd397
--- /dev/null
+++ b/src/assistant/tools/assistant/assistant.icns
Binary files differ
diff --git a/src/assistant/tools/assistant/assistant.ico b/src/assistant/tools/assistant/assistant.ico
new file mode 100644
index 000000000..9e1b83f1b
--- /dev/null
+++ b/src/assistant/tools/assistant/assistant.ico
Binary files differ
diff --git a/src/assistant/tools/assistant/assistant.pro b/src/assistant/tools/assistant/assistant.pro
new file mode 100644
index 000000000..7f0fdd158
--- /dev/null
+++ b/src/assistant/tools/assistant/assistant.pro
@@ -0,0 +1,118 @@
+include(../../../shared/fontpanel/fontpanel.pri)
+TEMPLATE = app
+LANGUAGE = C++
+TARGET = assistant
+contains(QT_CONFIG, webkit):QT += webkit
+CONFIG += qt \
+ warn_on \
+ help
+QT += network
+PROJECTNAME = Assistant
+DESTDIR = ../../../../bin
+target.path = $$[QT_INSTALL_BINS]
+INSTALLS += target
+DEPENDPATH += ../shared
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# ## Work around a qmake issue when statically linking to
+# ## not-yet-installed plugins
+QMAKE_LIBDIR += $$QT_BUILD_TREE/plugins/sqldrivers
+HEADERS += aboutdialog.h \
+ bookmarkdialog.h \
+ bookmarkfiltermodel.h \
+ bookmarkitem.h \
+ bookmarkmanager.h \
+ bookmarkmanagerwidget.h \
+ bookmarkmodel.h \
+ centralwidget.h \
+ cmdlineparser.h \
+ contentwindow.h \
+ findwidget.h \
+ filternamedialog.h \
+ helpenginewrapper.h \
+ helpviewer.h \
+ helpviewer_p.h \
+ indexwindow.h \
+ installdialog.h \
+ mainwindow.h \
+ preferencesdialog.h \
+ qtdocinstaller.h \
+ remotecontrol.h \
+ searchwidget.h \
+ topicchooser.h \
+ tracer.h \
+ xbelsupport.h \
+ ../shared/collectionconfiguration.h \
+ openpagesmodel.h \
+ globalactions.h \
+ openpageswidget.h \
+ openpagesmanager.h \
+ openpagesswitcher.h
+win32:HEADERS += remotecontrol_win.h
+
+SOURCES += aboutdialog.cpp \
+ bookmarkdialog.cpp \
+ bookmarkfiltermodel.cpp \
+ bookmarkitem.cpp \
+ bookmarkmanager.cpp \
+ bookmarkmanagerwidget.cpp \
+ bookmarkmodel.cpp \
+ centralwidget.cpp \
+ cmdlineparser.cpp \
+ contentwindow.cpp \
+ findwidget.cpp \
+ filternamedialog.cpp \
+ helpenginewrapper.cpp \
+ helpviewer.cpp \
+ indexwindow.cpp \
+ installdialog.cpp \
+ main.cpp \
+ mainwindow.cpp \
+ preferencesdialog.cpp \
+ qtdocinstaller.cpp \
+ remotecontrol.cpp \
+ searchwidget.cpp \
+ topicchooser.cpp \
+ xbelsupport.cpp \
+ ../shared/collectionconfiguration.cpp \
+ openpagesmodel.cpp \
+ globalactions.cpp \
+ openpageswidget.cpp \
+ openpagesmanager.cpp \
+ openpagesswitcher.cpp
+contains(QT_CONFIG, webkit) {
+ SOURCES += helpviewer_qwv.cpp
+} else {
+ SOURCES += helpviewer_qtb.cpp
+}
+
+FORMS += bookmarkdialog.ui \
+ bookmarkmanagerwidget.ui \
+ bookmarkwidget.ui \
+ filternamedialog.ui \
+ installdialog.ui \
+ preferencesdialog.ui \
+ topicchooser.ui
+
+RESOURCES += assistant.qrc \
+ assistant_images.qrc
+
+win32 {
+ !wince*:LIBS += -lshell32
+ RC_FILE = assistant.rc
+}
+
+mac {
+ ICON = assistant.icns
+ TARGET = Assistant
+ QMAKE_INFO_PLIST = Info_mac.plist
+}
+
+contains(CONFIG, static): {
+ SQLPLUGINS = $$unique(sql-plugins)
+ contains(SQLPLUGINS, sqlite): {
+ QTPLUGIN += qsqlite
+ DEFINES += USE_STATIC_SQLITE_PLUGIN
+ }
+}
diff --git a/src/assistant/tools/assistant/assistant.qch b/src/assistant/tools/assistant/assistant.qch
new file mode 100644
index 000000000..e6d52997b
--- /dev/null
+++ b/src/assistant/tools/assistant/assistant.qch
Binary files differ
diff --git a/src/assistant/tools/assistant/assistant.qrc b/src/assistant/tools/assistant/assistant.qrc
new file mode 100644
index 000000000..dddf1be75
--- /dev/null
+++ b/src/assistant/tools/assistant/assistant.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/trolltech/assistant" >
+ <file>assistant.qch</file>
+ </qresource>
+</RCC>
diff --git a/src/assistant/tools/assistant/assistant.rc b/src/assistant/tools/assistant/assistant.rc
new file mode 100644
index 000000000..b1bf97b5c
--- /dev/null
+++ b/src/assistant/tools/assistant/assistant.rc
@@ -0,0 +1,32 @@
+#include "winver.h"
+
+IDI_ICON1 ICON DISCARDABLE "assistant.ico"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGS 0x0L
+ FILEFLAGSMASK 0x3fL
+ FILEOS 0x00040004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)"
+ VALUE "FileDescription", "Qt Assistant"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+ VALUE "InternalName", "assistant.exe"
+ VALUE "OriginalFilename", "assistant.exe"
+ VALUE "ProductName", "Qt Assistant"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/src/assistant/tools/assistant/assistant_images.qrc b/src/assistant/tools/assistant/assistant_images.qrc
new file mode 100644
index 000000000..b4f25236d
--- /dev/null
+++ b/src/assistant/tools/assistant/assistant_images.qrc
@@ -0,0 +1,37 @@
+<RCC>
+ <qresource prefix="/trolltech/assistant">
+ <file>images/trolltech-logo.png</file>
+ <file>images/assistant-128.png</file>
+ <file>images/assistant.png</file>
+ <file>images/wrap.png</file>
+ <file>images/bookmark.png</file>
+ <file>images/mac/addtab.png</file>
+ <file>images/mac/book.png</file>
+ <file>images/mac/closetab.png</file>
+ <file>images/mac/editcopy.png</file>
+ <file>images/mac/find.png</file>
+ <file>images/mac/home.png</file>
+ <file>images/mac/next.png</file>
+ <file>images/mac/previous.png</file>
+ <file>images/mac/print.png</file>
+ <file>images/mac/synctoc.png</file>
+ <file>images/mac/zoomin.png</file>
+ <file>images/mac/zoomout.png</file>
+ <file>images/mac/resetzoom.png</file>
+ <file>images/win/addtab.png</file>
+ <file>images/win/book.png</file>
+ <file>images/win/closetab.png</file>
+ <file>images/win/editcopy.png</file>
+ <file>images/win/find.png</file>
+ <file>images/win/home.png</file>
+ <file>images/win/next.png</file>
+ <file>images/win/previous.png</file>
+ <file>images/win/print.png</file>
+ <file>images/win/synctoc.png</file>
+ <file>images/win/zoomin.png</file>
+ <file>images/win/zoomout.png</file>
+ <file>images/win/resetzoom.png</file>
+ <file>images/closebutton.png</file>
+ <file>images/darkclosebutton.png</file>
+ </qresource>
+</RCC>
diff --git a/src/assistant/tools/assistant/bookmarkdialog.cpp b/src/assistant/tools/assistant/bookmarkdialog.cpp
new file mode 100644
index 000000000..d2f88f968
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkdialog.cpp
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bookmarkdialog.h"
+#include "bookmarkfiltermodel.h"
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+#include "helpenginewrapper.h"
+#include "tracer.h"
+
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMenu>
+
+QT_BEGIN_NAMESPACE
+
+BookmarkDialog::BookmarkDialog(BookmarkModel *sourceModel, const QString &title,
+ const QString &url, QWidget *parent)
+ : QDialog(parent)
+ , m_url(url)
+ , m_title(title)
+ , bookmarkModel(sourceModel)
+{
+ TRACE_OBJ
+ ui.setupUi(this);
+
+ ui.bookmarkEdit->setText(m_title);
+ ui.newFolderButton->setVisible(false);
+ ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(accepted()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(rejected()));
+ connect(ui.newFolderButton, SIGNAL(clicked()), this, SLOT(addFolder()));
+ connect(ui.toolButton, SIGNAL(clicked()), this, SLOT(toolButtonClicked()));
+ connect(ui.bookmarkEdit, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+
+ bookmarkProxyModel = new BookmarkFilterModel(this);
+ bookmarkProxyModel->setSourceModel(bookmarkModel);
+ ui.bookmarkFolders->setModel(bookmarkProxyModel);
+ connect(ui.bookmarkFolders, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(currentIndexChanged(int)));
+
+ bookmarkTreeModel = new BookmarkTreeModel(this);
+ bookmarkTreeModel->setSourceModel(bookmarkModel);
+ ui.treeView->setModel(bookmarkTreeModel);
+
+ ui.treeView->expandAll();
+ ui.treeView->setVisible(false);
+ ui.treeView->installEventFilter(this);
+ ui.treeView->viewport()->installEventFilter(this);
+ ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(ui.treeView, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(customContextMenuRequested(QPoint)));
+ connect(ui.treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,
+ QModelIndex)), this, SLOT(currentIndexChanged(QModelIndex)));
+
+ ui.bookmarkFolders->setCurrentIndex(0);
+ ui.treeView->setCurrentIndex(ui.treeView->indexAt(QPoint(2, 2)));
+
+ const HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (helpEngine.usesAppFont())
+ setFont(helpEngine.appFont());
+}
+
+BookmarkDialog::~BookmarkDialog()
+{
+ TRACE_OBJ
+}
+
+bool BookmarkDialog::isRootItem(const QModelIndex &index) const
+{
+ return !bookmarkTreeModel->parent(index).isValid();
+}
+
+bool BookmarkDialog::eventFilter(QObject *object, QEvent *event)
+{
+ TRACE_OBJ
+ if (object != ui.treeView && object != ui.treeView->viewport())
+ return QWidget::eventFilter(object, event);
+
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ switch (ke->key()) {
+ case Qt::Key_F2: {
+ const QModelIndex &index = ui.treeView->currentIndex();
+ if (!isRootItem(index)) {
+ bookmarkModel->setItemsEditable(true);
+ ui.treeView->edit(index);
+ bookmarkModel->setItemsEditable(false);
+ }
+ } break;
+ default: break;
+ }
+ }
+
+ return QObject::eventFilter(object, event);
+}
+
+void BookmarkDialog::currentIndexChanged(int row)
+{
+ TRACE_OBJ
+ QModelIndex next = bookmarkProxyModel->index(row, 0, QModelIndex());
+ if (next.isValid()) {
+ next = bookmarkProxyModel->mapToSource(next);
+ ui.treeView->setCurrentIndex(bookmarkTreeModel->mapFromSource(next));
+ }
+}
+
+void BookmarkDialog::currentIndexChanged(const QModelIndex &index)
+{
+ TRACE_OBJ
+ const QModelIndex current = bookmarkTreeModel->mapToSource(index);
+ if (current.isValid()) {
+ const int row = bookmarkProxyModel->mapFromSource(current).row();
+ ui.bookmarkFolders->setCurrentIndex(row);
+ }
+}
+
+void BookmarkDialog::accepted()
+{
+ TRACE_OBJ
+ QModelIndex index = ui.treeView->currentIndex();
+ if (index.isValid()) {
+ index = bookmarkModel->addItem(bookmarkTreeModel->mapToSource(index));
+ bookmarkModel->setData(index, DataVector() << m_title << m_url << false);
+ } else
+ rejected();
+
+ accept();
+}
+
+void BookmarkDialog::rejected()
+{
+ TRACE_OBJ
+ foreach (const QPersistentModelIndex &index, cache)
+ bookmarkModel->removeItem(index);
+ reject();
+}
+
+void BookmarkDialog::addFolder()
+{
+ TRACE_OBJ
+ QModelIndex index = ui.treeView->currentIndex();
+ if (index.isValid()) {
+ index = bookmarkModel->addItem(bookmarkTreeModel->mapToSource(index),
+ true);
+ cache.append(index);
+
+ index = bookmarkTreeModel->mapFromSource(index);
+ if (index.isValid()) {
+ bookmarkModel->setItemsEditable(true);
+ ui.treeView->edit(index);
+ ui.treeView->expand(index);
+ ui.treeView->setCurrentIndex(index);
+ bookmarkModel->setItemsEditable(false);
+ }
+ }
+}
+
+void BookmarkDialog::toolButtonClicked()
+{
+ TRACE_OBJ
+ const bool visible = !ui.treeView->isVisible();
+ ui.treeView->setVisible(visible);
+ ui.newFolderButton->setVisible(visible);
+
+ if (visible) {
+ resize(QSize(width(), 400));
+ ui.toolButton->setText(QLatin1String("-"));
+ } else {
+ resize(width(), minimumHeight());
+ ui.toolButton->setText(QLatin1String("+"));
+ }
+}
+
+void BookmarkDialog::textChanged(const QString& text)
+{
+ m_title = text;
+}
+
+void BookmarkDialog::customContextMenuRequested(const QPoint &point)
+{
+ TRACE_OBJ
+ const QModelIndex &index = ui.treeView->currentIndex();
+ if (isRootItem(index))
+ return; // check if we go to rename the "Bookmarks Menu", bail
+
+ QMenu menu(QLatin1String(""), this);
+ QAction *renameItem = menu.addAction(tr("Rename Folder"));
+
+ QAction *picked = menu.exec(ui.treeView->mapToGlobal(point));
+ if (picked == renameItem) {
+ bookmarkModel->setItemsEditable(true);
+ ui.treeView->edit(index);
+ bookmarkModel->setItemsEditable(false);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/bookmarkdialog.h b/src/assistant/tools/assistant/bookmarkdialog.h
new file mode 100644
index 000000000..dfa65bbf8
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkdialog.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKDIALOG_H
+#define BOOKMARKDIALOG_H
+
+#include "ui_bookmarkdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkModel;
+class BookmarkFilterModel;
+class BookmarkTreeModel;
+
+class BookmarkDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ BookmarkDialog(BookmarkModel *bookmarkModel, const QString &title,
+ const QString &url, QWidget *parent = 0);
+ ~BookmarkDialog();
+
+private:
+ bool isRootItem(const QModelIndex &index) const;
+ bool eventFilter(QObject *object, QEvent *event);
+
+private slots:
+ void currentIndexChanged(int index);
+ void currentIndexChanged(const QModelIndex &index);
+
+ void accepted();
+ void rejected();
+
+ void addFolder();
+ void toolButtonClicked();
+ void textChanged(const QString& text);
+ void customContextMenuRequested(const QPoint &point);
+
+private:
+ QString m_url;
+ QString m_title;
+ Ui::BookmarkDialog ui;
+ QList<QPersistentModelIndex> cache;
+
+ BookmarkModel *bookmarkModel;
+ BookmarkTreeModel *bookmarkTreeModel;
+ BookmarkFilterModel *bookmarkProxyModel;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKDIALOG_H
diff --git a/src/assistant/tools/assistant/bookmarkdialog.ui b/src/assistant/tools/assistant/bookmarkdialog.ui
new file mode 100644
index 000000000..51315317b
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkdialog.ui
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BookmarkDialog</class>
+ <widget class="QDialog" name="BookmarkDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>450</width>
+ <height>133</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Add Bookmark</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Bookmark:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Add in Folder:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLineEdit" name="bookmarkEdit"/>
+ </item>
+ <item>
+ <widget class="QComboBox" name="bookmarkFolders"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QToolButton" name="toolButton">
+ <property name="minimumSize">
+ <size>
+ <width>25</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>+</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeView" name="treeView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="headerHidden">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QPushButton" name="newFolderButton">
+ <property name="text">
+ <string>New Folder</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>BookmarkDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>BookmarkDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/assistant/tools/assistant/bookmarkfiltermodel.cpp b/src/assistant/tools/assistant/bookmarkfiltermodel.cpp
new file mode 100644
index 000000000..412e08e5d
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkfiltermodel.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bookmarkfiltermodel.h"
+
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+
+BookmarkFilterModel::BookmarkFilterModel(QObject *parent)
+ : QAbstractProxyModel(parent)
+ , hideBookmarks(true)
+ , sourceModel(0)
+{
+}
+
+void BookmarkFilterModel::setSourceModel(QAbstractItemModel *_sourceModel)
+{
+ beginResetModel();
+
+ if (sourceModel) {
+ disconnect(sourceModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
+ this, SLOT(changed(QModelIndex, QModelIndex)));
+ disconnect(sourceModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
+ this, SLOT(rowsInserted(QModelIndex, int, int)));
+ disconnect(sourceModel,
+ SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this,
+ SLOT(rowsAboutToBeRemoved(QModelIndex, int, int)));
+ disconnect(sourceModel, SIGNAL(rowsRemoved(QModelIndex, int, int)),
+ this, SLOT(rowsRemoved(QModelIndex, int, int)));
+ disconnect(sourceModel, SIGNAL(layoutAboutToBeChanged()), this,
+ SLOT(layoutAboutToBeChanged()));
+ disconnect(sourceModel, SIGNAL(layoutChanged()), this,
+ SLOT(layoutChanged()));
+ disconnect(sourceModel, SIGNAL(modelAboutToBeReset()), this,
+ SLOT(modelAboutToBeReset()));
+ disconnect(sourceModel, SIGNAL(modelReset()), this, SLOT(modelReset()));
+ }
+
+ QAbstractProxyModel::setSourceModel(sourceModel);
+ sourceModel = qobject_cast<BookmarkModel*> (_sourceModel);
+
+ connect(sourceModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
+ SLOT(changed(QModelIndex, QModelIndex)));
+
+ connect(sourceModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
+ this, SLOT(rowsInserted(QModelIndex, int, int)));
+
+ connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
+ this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int)));
+ connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
+ SLOT(rowsRemoved(QModelIndex, int, int)));
+
+ connect(sourceModel, SIGNAL(layoutAboutToBeChanged()), this,
+ SLOT(layoutAboutToBeChanged()));
+ connect(sourceModel, SIGNAL(layoutChanged()), this,
+ SLOT(layoutChanged()));
+
+ connect(sourceModel, SIGNAL(modelAboutToBeReset()), this,
+ SLOT(modelAboutToBeReset()));
+ connect(sourceModel, SIGNAL(modelReset()), this, SLOT(modelReset()));
+
+ if (sourceModel)
+ setupCache(sourceModel->index(0, 0, QModelIndex()).parent());
+
+ endResetModel();
+}
+
+int BookmarkFilterModel::rowCount(const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ return cache.count();
+}
+
+int BookmarkFilterModel::columnCount(const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ if (sourceModel)
+ return sourceModel->columnCount();
+ return 0;
+}
+
+QModelIndex BookmarkFilterModel::mapToSource(const QModelIndex &proxyIndex) const
+{
+ const int row = proxyIndex.row();
+ if (proxyIndex.isValid() && row >= 0 && row < cache.count())
+ return cache[row];
+ return QModelIndex();
+}
+
+QModelIndex BookmarkFilterModel::mapFromSource(const QModelIndex &sourceIndex) const
+{
+ return index(cache.indexOf(sourceIndex), 0, QModelIndex());
+}
+
+QModelIndex BookmarkFilterModel::parent(const QModelIndex &child) const
+{
+ Q_UNUSED(child)
+ return QModelIndex();
+}
+
+QModelIndex BookmarkFilterModel::index(int row, int column,
+ const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ if (row < 0 || column < 0 || cache.count() <= row
+ || !sourceModel || sourceModel->columnCount() <= column) {
+ return QModelIndex();
+ }
+ return createIndex(row, 0);
+}
+
+Qt::DropActions BookmarkFilterModel::supportedDropActions () const
+{
+ if (sourceModel)
+ return sourceModel->supportedDropActions();
+ return Qt::IgnoreAction;
+}
+
+Qt::ItemFlags BookmarkFilterModel::flags(const QModelIndex &index) const
+{
+ if (sourceModel)
+ return sourceModel->flags(index);
+ return Qt::NoItemFlags;
+}
+
+QVariant BookmarkFilterModel::data(const QModelIndex &index, int role) const
+{
+ if (sourceModel)
+ return sourceModel->data(mapToSource(index), role);
+ return QVariant();
+}
+
+bool BookmarkFilterModel::setData(const QModelIndex &index, const QVariant &value,
+ int role)
+{
+ if (sourceModel)
+ return sourceModel->setData(mapToSource(index), value, role);
+ return false;
+}
+
+void BookmarkFilterModel::filterBookmarks()
+{
+ if (sourceModel) {
+ beginResetModel();
+ hideBookmarks = true;
+ setupCache(sourceModel->index(0, 0, QModelIndex()).parent());
+ endResetModel();
+ }
+}
+
+void BookmarkFilterModel::filterBookmarkFolders()
+{
+ if (sourceModel) {
+ beginResetModel();
+ hideBookmarks = false;
+ setupCache(sourceModel->index(0, 0, QModelIndex()).parent());
+ endResetModel();
+ }
+}
+
+void BookmarkFilterModel::changed(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight)
+{
+ emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight));
+}
+
+void BookmarkFilterModel::rowsInserted(const QModelIndex &parent, int start,
+ int end)
+{
+ if (!sourceModel)
+ return;
+
+ QModelIndex cachePrevious = parent;
+ if (BookmarkItem *parentItem = sourceModel->itemFromIndex(parent)) {
+ BookmarkItem *newItem = parentItem->child(start);
+
+ // iterate over tree hirarchie to find the previous folder
+ for (int i = 0; i < parentItem->childCount(); ++i) {
+ if (BookmarkItem *child = parentItem->child(i)) {
+ const QModelIndex &tmp = sourceModel->indexFromItem(child);
+ if (tmp.data(UserRoleFolder).toBool() && child != newItem)
+ cachePrevious = tmp;
+ }
+ }
+
+ const QModelIndex &newIndex = sourceModel->indexFromItem(newItem);
+ const bool isFolder = newIndex.data(UserRoleFolder).toBool();
+ if ((isFolder && hideBookmarks) || (!isFolder && !hideBookmarks)) {
+ beginInsertRows(mapFromSource(parent), start, end);
+ const int index = cache.indexOf(cachePrevious) + 1;
+ if (cache.value(index, QPersistentModelIndex()) != newIndex)
+ cache.insert(index, newIndex);
+ endInsertRows();
+ }
+ }
+}
+
+void BookmarkFilterModel::rowsAboutToBeRemoved(const QModelIndex &parent,
+ int start, int end)
+{
+ if (!sourceModel)
+ return;
+
+ if (BookmarkItem *parentItem = sourceModel->itemFromIndex(parent)) {
+ if (BookmarkItem *child = parentItem->child(start)) {
+ indexToRemove = sourceModel->indexFromItem(child);
+ if (cache.contains(indexToRemove))
+ beginRemoveRows(mapFromSource(parent), start, end);
+ }
+ }
+}
+
+void BookmarkFilterModel::rowsRemoved(const QModelIndex &/*parent*/, int, int)
+{
+ if (cache.contains(indexToRemove)) {
+ cache.removeAll(indexToRemove);
+ endRemoveRows();
+ }
+}
+
+void BookmarkFilterModel::layoutAboutToBeChanged()
+{
+ // TODO: ???
+}
+
+void BookmarkFilterModel::layoutChanged()
+{
+ // TODO: ???
+}
+
+void BookmarkFilterModel::modelAboutToBeReset()
+{
+ beginResetModel();
+}
+
+void BookmarkFilterModel::modelReset()
+{
+ if (sourceModel)
+ setupCache(sourceModel->index(0, 0, QModelIndex()).parent());
+ endResetModel();
+}
+
+void BookmarkFilterModel::setupCache(const QModelIndex &parent)
+{
+ cache.clear();
+ for (int i = 0; i < sourceModel->rowCount(parent); ++i)
+ collectItems(sourceModel->index(i, 0, parent));
+}
+
+void BookmarkFilterModel::collectItems(const QModelIndex &parent)
+{
+ if (parent.isValid()) {
+ bool isFolder = sourceModel->data(parent, UserRoleFolder).toBool();
+ if ((isFolder && hideBookmarks) || (!isFolder && !hideBookmarks))
+ cache.append(parent);
+
+ if (sourceModel->hasChildren(parent)) {
+ for (int i = 0; i < sourceModel->rowCount(parent); ++i)
+ collectItems(sourceModel->index(i, 0, parent));
+ }
+ }
+}
+
+// -- BookmarkTreeModel
+
+BookmarkTreeModel::BookmarkTreeModel(QObject *parent)
+ : QSortFilterProxyModel(parent)
+{
+}
+
+int BookmarkTreeModel::columnCount(const QModelIndex &parent) const
+{
+ return qMin(1, QSortFilterProxyModel::columnCount(parent));
+}
+
+bool BookmarkTreeModel::filterAcceptsRow(int row, const QModelIndex &parent) const
+{
+ Q_UNUSED(row)
+ BookmarkModel *model = qobject_cast<BookmarkModel*> (sourceModel());
+ if (model->rowCount(parent) > 0
+ && model->data(model->index(row, 0, parent), UserRoleFolder).toBool())
+ return true;
+ return false;
+}
diff --git a/src/assistant/tools/assistant/bookmarkfiltermodel.h b/src/assistant/tools/assistant/bookmarkfiltermodel.h
new file mode 100644
index 000000000..65ed12f20
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkfiltermodel.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKFILTERMODEL_H
+#define BOOKMARKFILTERMODEL_H
+
+#include <QtCore/QPersistentModelIndex>
+
+#include <QtGui/QAbstractProxyModel>
+#include <QtGui/QSortFilterProxyModel>
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkItem;
+class BookmarkModel;
+
+typedef QList<QPersistentModelIndex> PersistentModelIndexCache;
+
+class BookmarkFilterModel : public QAbstractProxyModel
+{
+ Q_OBJECT
+public:
+ explicit BookmarkFilterModel(QObject *parent = 0);
+
+ void setSourceModel(QAbstractItemModel *sourceModel);
+
+ int rowCount(const QModelIndex &index) const;
+ int columnCount(const QModelIndex &index) const;
+
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
+ QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
+
+ QModelIndex parent(const QModelIndex &child) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
+
+ Qt::DropActions supportedDropActions () const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+
+ void filterBookmarks();
+ void filterBookmarkFolders();
+
+private slots:
+ void changed(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void rowsInserted(const QModelIndex &parent, int start, int end);
+ void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ void rowsRemoved(const QModelIndex &parent, int start, int end);
+ void layoutAboutToBeChanged();
+ void layoutChanged();
+ void modelAboutToBeReset();
+ void modelReset();
+
+private:
+ void setupCache(const QModelIndex &parent);
+ void collectItems(const QModelIndex &parent);
+
+private:
+ bool hideBookmarks;
+ BookmarkModel *sourceModel;
+ PersistentModelIndexCache cache;
+ QPersistentModelIndex indexToRemove;
+};
+
+// -- BookmarkTreeModel
+
+class BookmarkTreeModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ BookmarkTreeModel(QObject *parent = 0);
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+protected:
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKFILTERMODEL_H
diff --git a/src/assistant/tools/assistant/bookmarkitem.cpp b/src/assistant/tools/assistant/bookmarkitem.cpp
new file mode 100644
index 000000000..8bcf451c1
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkitem.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bookmarkitem.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BookmarkItem::BookmarkItem(const DataVector &data, BookmarkItem *parent)
+ : m_data(data)
+ , m_parent(parent)
+{
+}
+
+BookmarkItem::~BookmarkItem()
+{
+ qDeleteAll(m_children);
+}
+
+BookmarkItem*
+BookmarkItem::parent() const
+{
+ return m_parent;
+}
+
+void
+BookmarkItem::setParent(BookmarkItem *parent)
+{
+ m_parent = parent;
+}
+
+void
+BookmarkItem::addChild(BookmarkItem *child)
+{
+ child->setParent(this);
+ m_children.append(child);
+}
+
+BookmarkItem*
+BookmarkItem::child(int number) const
+{
+ if (number >= 0 && number < m_children.count())
+ return m_children[number];
+ return 0;
+}
+
+int BookmarkItem::childCount() const
+{
+ return m_children.count();
+}
+
+int BookmarkItem::childNumber() const
+{
+ if (m_parent)
+ return m_parent->m_children.indexOf(const_cast<BookmarkItem*>(this));
+ return 0;
+}
+
+QVariant
+BookmarkItem::data(int column) const
+{
+ if (column == 0)
+ return m_data[0];
+
+ if (column == 1 || column == UserRoleUrl)
+ return m_data[1];
+
+ if (column == UserRoleFolder)
+ return m_data[1].toString() == QLatin1String("Folder");
+
+ if (column == UserRoleExpanded)
+ return m_data[2];
+
+ return QVariant();
+}
+
+void
+BookmarkItem::setData(const DataVector &data)
+{
+ m_data = data;
+}
+
+bool
+BookmarkItem::setData(int column, const QVariant &newValue)
+{
+ int index = -1;
+ if (column == 0 || column == 1)
+ index = column;
+
+ if (column == UserRoleUrl || column == UserRoleFolder)
+ index = 1;
+
+ if (column == UserRoleExpanded)
+ index = 2;
+
+ if (index < 0)
+ return false;
+
+ m_data[index] = newValue;
+ return true;
+}
+
+bool
+BookmarkItem::insertChildren(bool isFolder, int position, int count)
+{
+ if (position < 0 || position > m_children.size())
+ return false;
+
+ for (int row = 0; row < count; ++row) {
+ m_children.insert(position, new BookmarkItem(DataVector()
+ << (isFolder
+ ? QCoreApplication::translate("BookmarkItem", "New Folder")
+ : QCoreApplication::translate("BookmarkItem", "Untitled"))
+ << (isFolder ? "Folder" : "about:blank") << false, this));
+ }
+
+ return true;
+}
+
+bool
+BookmarkItem::removeChildren(int position, int count)
+{
+ if (position < 0 || position > m_children.size())
+ return false;
+
+ for (int row = 0; row < count; ++row)
+ delete m_children.takeAt(position);
+
+ return true;
+}
+
+void
+BookmarkItem::dumpTree(int indent) const
+{
+ const QString tree(indent, ' ');
+ qDebug() << tree + (data(UserRoleFolder).toBool() ? "Folder" : "Bookmark")
+ << "Label:" << data(0).toString() << "parent:" << m_parent << "this:"
+ << this;
+
+ foreach (BookmarkItem *item, m_children)
+ item->dumpTree(indent + 4);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/bookmarkitem.h b/src/assistant/tools/assistant/bookmarkitem.h
new file mode 100644
index 000000000..96ce786be
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkitem.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BOOKMARKITEM_H
+#define BOOKMARKITEM_H
+
+#include <QtCore/QVariant>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ UserRoleUrl = Qt::UserRole + 50,
+ UserRoleFolder = Qt::UserRole + 100,
+ UserRoleExpanded = Qt::UserRole + 150
+};
+
+typedef QVector<QVariant> DataVector;
+
+class BookmarkItem
+{
+public:
+ explicit BookmarkItem(const DataVector &data, BookmarkItem *parent = 0);
+ ~BookmarkItem();
+
+ BookmarkItem *parent() const;
+ void setParent(BookmarkItem *parent);
+
+ void addChild(BookmarkItem *child);
+ BookmarkItem *child(int number) const;
+
+ int childCount() const;
+ int childNumber() const;
+
+ QVariant data(int column) const;
+ void setData(const DataVector &data);
+ bool setData(int column, const QVariant &value);
+
+ bool insertChildren(bool isFolder, int position, int count);
+ bool removeChildren(int position, int count);
+
+ void dumpTree(int indent) const;
+
+private:
+ DataVector m_data;
+
+ BookmarkItem *m_parent;
+ QList<BookmarkItem*> m_children;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKITEM_H
diff --git a/src/assistant/tools/assistant/bookmarkmanager.cpp b/src/assistant/tools/assistant/bookmarkmanager.cpp
new file mode 100644
index 000000000..87331463b
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkmanager.cpp
@@ -0,0 +1,559 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include "bookmarkmanager.h"
+#include "bookmarkmanagerwidget.h"
+#include "bookmarkdialog.h"
+#include "bookmarkfiltermodel.h"
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+#include "centralwidget.h"
+#include "helpenginewrapper.h"
+
+#include <QtGui/QMenu>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMessageBox>
+#include <QtGui/QSortFilterProxyModel>
+#include <QtGui/QToolBar>
+
+QT_BEGIN_NAMESPACE
+
+// -- BookmarkManager::BookmarkWidget
+
+void BookmarkManager::BookmarkWidget::focusInEvent(QFocusEvent *event)
+{
+ TRACE_OBJ
+ if (event->reason() != Qt::MouseFocusReason) {
+ ui.lineEdit->selectAll();
+ ui.lineEdit->setFocus();
+
+ // force the focus in event on bookmark manager
+ emit focusInEvent();
+ }
+}
+
+// -- BookmarkManager::BookmarkTreeView
+
+BookmarkManager::BookmarkTreeView::BookmarkTreeView(QWidget *parent)
+ : QTreeView(parent)
+{
+ TRACE_OBJ
+ setAcceptDrops(true);
+ setDragEnabled(true);
+ setAutoExpandDelay(1000);
+ setUniformRowHeights(true);
+ setDropIndicatorShown(true);
+ setExpandsOnDoubleClick(true);
+
+ connect(this, SIGNAL(expanded(QModelIndex)), this,
+ SLOT(setExpandedData(QModelIndex)));
+ connect(this, SIGNAL(collapsed(QModelIndex)), this,
+ SLOT(setExpandedData(QModelIndex)));
+
+}
+
+void BookmarkManager::BookmarkTreeView::subclassKeyPressEvent(QKeyEvent *event)
+{
+ TRACE_OBJ
+ QTreeView::keyPressEvent(event);
+}
+
+void BookmarkManager::BookmarkTreeView::setExpandedData(const QModelIndex &index)
+{
+ TRACE_OBJ
+ if (BookmarkModel *treeModel = qobject_cast<BookmarkModel*> (model()))
+ treeModel->setData(index, isExpanded(index), UserRoleExpanded);
+}
+
+// -- BookmarkManager
+
+QMutex BookmarkManager::mutex;
+BookmarkManager* BookmarkManager::bookmarkManager = 0;
+
+// -- public
+
+BookmarkManager* BookmarkManager::instance()
+{
+ TRACE_OBJ
+ if (!bookmarkManager) {
+ QMutexLocker _(&mutex);
+ if (!bookmarkManager)
+ bookmarkManager = new BookmarkManager();
+ }
+ return bookmarkManager;
+}
+
+void BookmarkManager::destroy()
+{
+ TRACE_OBJ
+ delete bookmarkManager;
+ bookmarkManager = 0;
+}
+
+QWidget* BookmarkManager::bookmarkDockWidget() const
+{
+ TRACE_OBJ
+ if (bookmarkWidget)
+ return bookmarkWidget;
+ return 0;
+}
+
+void BookmarkManager::setBookmarksMenu(QMenu* menu)
+{
+ TRACE_OBJ
+ bookmarkMenu = menu;
+ refreshBookmarkMenu();
+}
+
+void BookmarkManager::setBookmarksToolbar(QToolBar *toolBar)
+{
+ TRACE_OBJ
+ m_toolBar = toolBar;
+ refreshBookmarkToolBar();
+}
+
+// -- public slots
+
+void BookmarkManager::addBookmark(const QString &title, const QString &url)
+{
+ TRACE_OBJ
+ showBookmarkDialog(title.isEmpty() ? tr("Untitled") : title,
+ url.isEmpty() ? QLatin1String("about:blank") : url);
+}
+
+// -- private
+
+BookmarkManager::BookmarkManager()
+ : typeAndSearch(false)
+ , bookmarkMenu(0)
+ , m_toolBar(0)
+ , bookmarkModel(new BookmarkModel)
+ , bookmarkFilterModel(0)
+ , typeAndSearchModel(0)
+ , bookmarkWidget(new BookmarkWidget)
+ , bookmarkTreeView(new BookmarkTreeView)
+ , bookmarkManagerWidget(0)
+{
+ TRACE_OBJ
+ bookmarkWidget->installEventFilter(this);
+ connect(bookmarkWidget->ui.add, SIGNAL(clicked()), this,
+ SLOT(addBookmark()));
+ connect(bookmarkWidget->ui.remove, SIGNAL(clicked()), this,
+ SLOT(removeBookmark()));
+ connect(bookmarkWidget->ui.lineEdit, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+ connect(bookmarkWidget, SIGNAL(focusInEvent()), this, SLOT(focusInEvent()));
+
+ bookmarkTreeView->setModel(bookmarkModel);
+ bookmarkTreeView->installEventFilter(this);
+ bookmarkTreeView->viewport()->installEventFilter(this);
+ bookmarkTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
+ bookmarkWidget->ui.stackedWidget->addWidget(bookmarkTreeView);
+
+ connect(bookmarkTreeView, SIGNAL(activated(QModelIndex)), this,
+ SLOT(setSourceFromIndex(QModelIndex)));
+ connect(bookmarkTreeView, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(customContextMenuRequested(QPoint)));
+
+ connect(&HelpEngineWrapper::instance(), SIGNAL(setupFinished()), this,
+ SLOT(setupFinished()));
+ connect(bookmarkModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
+ SLOT(refreshBookmarkMenu()));
+ connect(bookmarkModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this,
+ SLOT(refreshBookmarkMenu()));
+ connect(bookmarkModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
+ SLOT(refreshBookmarkMenu()));
+
+ connect(bookmarkModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
+ SLOT(refreshBookmarkToolBar()));
+ connect(bookmarkModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this,
+ SLOT(refreshBookmarkToolBar()));
+ connect(bookmarkModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
+ SLOT(refreshBookmarkToolBar()));
+}
+
+BookmarkManager::~BookmarkManager()
+{
+ TRACE_OBJ
+ delete bookmarkManagerWidget;
+ HelpEngineWrapper::instance().setBookmarks(bookmarkModel->bookmarks());
+ delete bookmarkModel;
+}
+
+void BookmarkManager::removeItem(const QModelIndex &index)
+{
+ TRACE_OBJ
+ QModelIndex current = index;
+ if (typeAndSearch) { // need to map because of proxy
+ current = typeAndSearchModel->mapToSource(current);
+ current = bookmarkFilterModel->mapToSource(current);
+ } else if (!bookmarkModel->parent(index).isValid()) {
+ return; // check if we should delete the "Bookmarks Menu", bail
+ }
+
+ if (bookmarkModel->hasChildren(current)) {
+ int value = QMessageBox::question(bookmarkTreeView, tr("Remove"),
+ tr("You are going to delete a Folder, this will also<br>"
+ "remove it's content. Are you sure to continue?"),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
+ if (value == QMessageBox::Cancel)
+ return;
+ }
+ bookmarkModel->removeItem(current);
+}
+
+bool BookmarkManager::eventFilter(QObject *object, QEvent *event)
+{
+ if (object != bookmarkTreeView && object != bookmarkTreeView->viewport()
+ && object != bookmarkWidget)
+ return QObject::eventFilter(object, event);
+
+ TRACE_OBJ
+ const bool isWidget = object == bookmarkWidget;
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ switch (ke->key()) {
+ case Qt::Key_F2: {
+ renameBookmark(bookmarkTreeView->currentIndex());
+ } break;
+
+ case Qt::Key_Delete: {
+ removeItem(bookmarkTreeView->currentIndex());
+ return true;
+ } break;
+
+ case Qt::Key_Up: { // needs event filter on widget
+ case Qt::Key_Down:
+ if (isWidget)
+ bookmarkTreeView->subclassKeyPressEvent(ke);
+ } break;
+
+ case Qt::Key_Escape: {
+ emit escapePressed();
+ } break;
+
+ default: break;
+ }
+ }
+
+ if (event->type() == QEvent::MouseButtonRelease && !isWidget) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ switch (me->button()) {
+ case Qt::LeftButton: {
+ if (me->modifiers() & Qt::ControlModifier)
+ setSourceFromIndex(bookmarkTreeView->currentIndex(), true);
+ } break;
+
+ case Qt::MidButton: {
+ setSourceFromIndex(bookmarkTreeView->currentIndex(), true);
+ } break;
+
+ default: break;
+ }
+ }
+
+ return QObject::eventFilter(object, event);
+}
+
+void BookmarkManager::buildBookmarksMenu(const QModelIndex &index, QMenu* menu)
+{
+ TRACE_OBJ
+ if (!index.isValid())
+ return;
+
+ const QString &text = index.data().toString();
+ const QIcon &icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
+ if (index.data(UserRoleFolder).toBool()) {
+ if (QMenu* subMenu = menu->addMenu(icon, text)) {
+ for (int i = 0; i < bookmarkModel->rowCount(index); ++i)
+ buildBookmarksMenu(bookmarkModel->index(i, 0, index), subMenu);
+ }
+ } else {
+ QAction *action = menu->addAction(icon, text);
+ action->setData(index.data(UserRoleUrl).toString());
+ }
+}
+
+void BookmarkManager::showBookmarkDialog(const QString &name, const QString &url)
+{
+ TRACE_OBJ
+ BookmarkDialog dialog(bookmarkModel, name, url, bookmarkTreeView);
+ dialog.exec();
+}
+
+// -- private slots
+
+void BookmarkManager::setupFinished()
+{
+ TRACE_OBJ
+ bookmarkModel->setBookmarks(HelpEngineWrapper::instance().bookmarks());
+ bookmarkModel->expandFoldersIfNeeeded(bookmarkTreeView);
+
+ refreshBookmarkMenu();
+ refreshBookmarkToolBar();
+
+ bookmarkTreeView->hideColumn(1);
+ bookmarkTreeView->header()->setVisible(false);
+ bookmarkTreeView->header()->setStretchLastSection(true);
+
+ if (!bookmarkFilterModel)
+ bookmarkFilterModel = new BookmarkFilterModel(this);
+ bookmarkFilterModel->setSourceModel(bookmarkModel);
+ bookmarkFilterModel->filterBookmarkFolders();
+
+ if (!typeAndSearchModel)
+ typeAndSearchModel = new QSortFilterProxyModel(this);
+ typeAndSearchModel->setDynamicSortFilter(true);
+ typeAndSearchModel->setSourceModel(bookmarkFilterModel);
+}
+
+void BookmarkManager::addBookmark()
+{
+ TRACE_OBJ
+ if (CentralWidget *widget = CentralWidget::instance())
+ addBookmark(widget->currentTitle(), widget->currentSource().toString());
+}
+
+void BookmarkManager::removeBookmark()
+{
+ TRACE_OBJ
+ removeItem(bookmarkTreeView->currentIndex());
+}
+
+void BookmarkManager::manageBookmarks()
+{
+ TRACE_OBJ
+ if (bookmarkManagerWidget == 0) {
+ bookmarkManagerWidget = new BookmarkManagerWidget(bookmarkModel);
+ connect(bookmarkManagerWidget, SIGNAL(setSource(QUrl)), this,
+ SIGNAL(setSource(QUrl)));
+ connect(bookmarkManagerWidget, SIGNAL(setSourceInNewTab(QUrl))
+ , this, SIGNAL(setSourceInNewTab(QUrl)));
+ connect(bookmarkManagerWidget, SIGNAL(managerWidgetAboutToClose())
+ , this, SLOT(managerWidgetAboutToClose()));
+ }
+ bookmarkManagerWidget->show();
+ bookmarkManagerWidget->raise();
+}
+
+void BookmarkManager::refreshBookmarkMenu()
+{
+ TRACE_OBJ
+ if (!bookmarkMenu)
+ return;
+
+ bookmarkMenu->clear();
+
+ bookmarkMenu->addAction(tr("Manage Bookmarks..."), this,
+ SLOT(manageBookmarks()));
+ bookmarkMenu->addAction(QIcon::fromTheme("bookmark-new"),
+ tr("Add Bookmark..."), this, SLOT(addBookmark()), QKeySequence(tr("Ctrl+D")));
+
+ bookmarkMenu->addSeparator();
+
+ QModelIndex root = bookmarkModel->index(0, 0, QModelIndex()).parent();
+ buildBookmarksMenu(bookmarkModel->index(0, 0, root), bookmarkMenu);
+
+ bookmarkMenu->addSeparator();
+
+ root = bookmarkModel->index(1, 0, QModelIndex());
+ for (int i = 0; i < bookmarkModel->rowCount(root); ++i)
+ buildBookmarksMenu(bookmarkModel->index(i, 0, root), bookmarkMenu);
+
+ connect(bookmarkMenu, SIGNAL(triggered(QAction*)), this,
+ SLOT(setSourceFromAction(QAction*)));
+}
+
+void BookmarkManager::refreshBookmarkToolBar()
+{
+ TRACE_OBJ
+ if (!m_toolBar)
+ return;
+
+ m_toolBar->clear();
+ m_toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+
+ const QModelIndex &root = bookmarkModel->index(0, 0, QModelIndex());
+ for (int i = 0; i < bookmarkModel->rowCount(root); ++i) {
+ const QModelIndex &index = bookmarkModel->index(i, 0, root);
+ if (index.data(UserRoleFolder).toBool()) {
+ QToolButton *button = new QToolButton(m_toolBar);
+ button->setPopupMode(QToolButton::InstantPopup);
+ button->setText(index.data().toString());
+ QMenu *menu = new QMenu(button);
+ for (int j = 0; j < bookmarkModel->rowCount(index); ++j)
+ buildBookmarksMenu(bookmarkModel->index(j, 0, index), menu);
+ connect(menu, SIGNAL(triggered(QAction*)), this,
+ SLOT(setSourceFromAction(QAction*)));
+ button->setMenu(menu);
+ button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ button->setIcon(qvariant_cast<QIcon>(index.data(Qt::DecorationRole)));
+ QAction *a = m_toolBar->addWidget(button);
+ a->setText(index.data().toString());
+ } else {
+ QAction *action = m_toolBar->addAction(
+ qvariant_cast<QIcon>(index.data(Qt::DecorationRole)),
+ index.data().toString(), this, SLOT(setSourceFromAction()));
+ action->setData(index.data(UserRoleUrl).toString());
+ }
+ }
+}
+
+void BookmarkManager::renameBookmark(const QModelIndex &index)
+{
+ // check if we should rename the "Bookmarks Menu", bail
+ if (!typeAndSearch && !bookmarkModel->parent(index).isValid())
+ return;
+
+ bookmarkModel->setItemsEditable(true);
+ bookmarkTreeView->edit(index);
+ bookmarkModel->setItemsEditable(false);
+}
+
+
+void BookmarkManager::setSourceFromAction()
+{
+ TRACE_OBJ
+ setSourceFromAction(qobject_cast<QAction*> (sender()));
+}
+
+void BookmarkManager::setSourceFromAction(QAction *action)
+{
+ TRACE_OBJ
+ if (action) {
+ const QVariant &data = action->data();
+ if (data.canConvert<QUrl>())
+ emit setSource(data.toUrl());
+ }
+}
+
+void BookmarkManager::setSourceFromIndex(const QModelIndex &index, bool newTab)
+{
+ TRACE_OBJ
+ QAbstractItemModel *base = bookmarkModel;
+ if (typeAndSearch)
+ base = typeAndSearchModel;
+
+ if (base->data(index, UserRoleFolder).toBool())
+ return;
+
+ const QVariant &data = base->data(index, UserRoleUrl);
+ if (data.canConvert<QUrl>()) {
+ if (newTab)
+ emit setSourceInNewTab(data.toUrl());
+ else
+ emit setSource(data.toUrl());
+ }
+}
+
+void BookmarkManager::customContextMenuRequested(const QPoint &point)
+{
+ TRACE_OBJ
+ QModelIndex index = bookmarkTreeView->indexAt(point);
+ if (!index.isValid())
+ return;
+
+ // check if we should open the menu on "Bookmarks Menu", bail
+ if (!typeAndSearch && !bookmarkModel->parent(index).isValid())
+ return;
+
+ QAction *remove = 0;
+ QAction *rename = 0;
+ QAction *showItem = 0;
+ QAction *showItemInNewTab = 0;
+
+ QMenu menu(QLatin1String(""));
+ if (!typeAndSearch && bookmarkModel->data(index, UserRoleFolder).toBool()) {
+ remove = menu.addAction(tr("Delete Folder"));
+ rename = menu.addAction(tr("Rename Folder"));
+ } else {
+ showItem = menu.addAction(tr("Show Bookmark"));
+ showItemInNewTab = menu.addAction(tr("Show Bookmark in New Tab"));
+ menu.addSeparator();
+ remove = menu.addAction(tr("Delete Bookmark"));
+ rename = menu.addAction(tr("Rename Bookmark"));
+ }
+
+ QAction *pickedAction = menu.exec(bookmarkTreeView->mapToGlobal(point));
+ if (pickedAction == rename)
+ renameBookmark(index);
+ else if (pickedAction == remove)
+ removeItem(index);
+ else if (pickedAction == showItem || pickedAction == showItemInNewTab)
+ setSourceFromIndex(index, pickedAction == showItemInNewTab);
+}
+
+void BookmarkManager::focusInEvent()
+{
+ TRACE_OBJ
+ const QModelIndex &index = bookmarkTreeView->indexAt(QPoint(2, 2));
+ if (index.isValid())
+ bookmarkTreeView->setCurrentIndex(index);
+}
+
+void BookmarkManager::managerWidgetAboutToClose()
+{
+ delete bookmarkManagerWidget;
+ bookmarkManagerWidget = 0;
+}
+
+void BookmarkManager::textChanged(const QString &text)
+{
+ TRACE_OBJ
+ if (!bookmarkWidget->ui.lineEdit->text().isEmpty()) {
+ if (!typeAndSearch) {
+ typeAndSearch = true;
+ bookmarkTreeView->setItemsExpandable(false);
+ bookmarkTreeView->setRootIsDecorated(false);
+ bookmarkTreeView->setModel(typeAndSearchModel);
+ }
+ typeAndSearchModel->setFilterRegExp(QRegExp(text));
+ } else {
+ typeAndSearch = false;
+ bookmarkTreeView->setModel(bookmarkModel);
+ bookmarkTreeView->setItemsExpandable(true);
+ bookmarkTreeView->setRootIsDecorated(true);
+ bookmarkModel->expandFoldersIfNeeeded(bookmarkTreeView);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/bookmarkmanager.h b/src/assistant/tools/assistant/bookmarkmanager.h
new file mode 100644
index 000000000..f5823a7fa
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkmanager.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKMANAGER_H
+#define BOOKMARKMANAGER_H
+
+#include <QtCore/QMutex>
+#include <QtGui/QTreeView>
+
+#include "ui_bookmarkwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkManagerWidget;
+class BookmarkModel;
+class BookmarkFilterModel;
+class QKeyEvent;
+class QSortFilterProxyModel;
+class QToolBar;
+
+class BookmarkManager : public QObject
+{
+ Q_OBJECT
+ class BookmarkWidget;
+ class BookmarkTreeView;
+ class BookmarkListView;
+ Q_DISABLE_COPY(BookmarkManager);
+
+public:
+ static BookmarkManager* instance();
+ static void destroy();
+
+ QWidget* bookmarkDockWidget() const;
+ void setBookmarksMenu(QMenu* menu);
+ void setBookmarksToolbar(QToolBar *toolBar);
+
+public slots:
+ void addBookmark(const QString &title, const QString &url);
+
+signals:
+ void escapePressed();
+ void setSource(const QUrl &url);
+ void setSourceInNewTab(const QUrl &url);
+
+private:
+ BookmarkManager();
+ ~BookmarkManager();
+
+ void removeItem(const QModelIndex &index);
+ bool eventFilter(QObject *object, QEvent *event);
+ void buildBookmarksMenu(const QModelIndex &index, QMenu *menu);
+ void showBookmarkDialog(const QString &name, const QString &url);
+
+private slots:
+ void setupFinished();
+
+ void addBookmark();
+ void removeBookmark();
+ void manageBookmarks();
+ void refreshBookmarkMenu();
+ void refreshBookmarkToolBar();
+ void renameBookmark(const QModelIndex &index);
+
+ void setSourceFromAction();
+ void setSourceFromAction(QAction *action);
+ void setSourceFromIndex(const QModelIndex &index, bool newTab = false);
+
+ void focusInEvent();
+ void managerWidgetAboutToClose();
+ void textChanged(const QString &text);
+ void customContextMenuRequested(const QPoint &point);
+
+private:
+ bool typeAndSearch;
+
+ static QMutex mutex;
+ static BookmarkManager *bookmarkManager;
+
+ QMenu *bookmarkMenu;
+ QToolBar *m_toolBar;
+
+ BookmarkModel *bookmarkModel;
+ BookmarkFilterModel *bookmarkFilterModel;
+ QSortFilterProxyModel *typeAndSearchModel;
+
+ BookmarkWidget *bookmarkWidget;
+ BookmarkTreeView *bookmarkTreeView;
+ BookmarkManagerWidget *bookmarkManagerWidget;
+};
+
+class BookmarkManager::BookmarkWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ BookmarkWidget(QWidget *parent = 0)
+ : QWidget(parent) { ui.setupUi(this); }
+ virtual ~BookmarkWidget() {}
+
+ Ui::BookmarkWidget ui;
+
+signals:
+ void focusInEvent();
+
+private:
+ void focusInEvent(QFocusEvent *event);
+};
+
+class BookmarkManager::BookmarkTreeView : public QTreeView
+{
+ Q_OBJECT
+public:
+ BookmarkTreeView(QWidget *parent = 0);
+ ~BookmarkTreeView() {}
+
+ void subclassKeyPressEvent(QKeyEvent *event);
+
+private slots:
+ void setExpandedData(const QModelIndex &index);
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKMANAGER_H
diff --git a/src/assistant/tools/assistant/bookmarkmanagerwidget.cpp b/src/assistant/tools/assistant/bookmarkmanagerwidget.cpp
new file mode 100644
index 000000000..dd410d3a2
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkmanagerwidget.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bookmarkmanagerwidget.h"
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+#include "tracer.h"
+#include "xbelsupport.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+#include <QtCore/QUrl>
+
+#include <QtGui/QCloseEvent>
+#include <QtGui/QFileDialog>
+#include <QtGui/QKeySequence>
+#include <QtGui/QMessageBox>
+#include <QtGui/QShortcut>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ #define TR(x) QCoreApplication::translate("BookmarkManager", x)
+}
+
+BookmarkManagerWidget::BookmarkManagerWidget(BookmarkModel *sourceModel,
+ QWidget *parent)
+ : QWidget(parent)
+ , bookmarkModel(sourceModel)
+{
+ TRACE_OBJ
+ ui.setupUi(this);
+
+ ui.treeView->setModel(bookmarkModel);
+
+ ui.treeView->expandAll();
+ ui.treeView->installEventFilter(this);
+ ui.treeView->viewport()->installEventFilter(this);
+ ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(ui.treeView, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(customContextMenuRequested(QPoint)));
+
+ connect(ui.remove, SIGNAL(clicked()), this, SLOT(removeItem()));
+ connect(ui.lineEdit, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+ new QShortcut(QKeySequence::Find, ui.lineEdit, SLOT(setFocus()));
+
+ importExportMenu.addAction(tr("Import..."), this, SLOT(importBookmarks()));
+ importExportMenu.addAction(tr("Export..."), this, SLOT(exportBookmarks()));
+ ui.importExport->setMenu(&importExportMenu);
+
+ new QShortcut(QKeySequence::FindNext, this, SLOT(findNext()));
+ new QShortcut(QKeySequence::FindPrevious, this, SLOT(findPrevious()));
+
+ connect(bookmarkModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
+ SLOT(refeshBookmarkCache()));
+ connect(bookmarkModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this,
+ SLOT(refeshBookmarkCache()));
+ connect(bookmarkModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
+ SLOT(refeshBookmarkCache()));
+
+ ui.treeView->setCurrentIndex(ui.treeView->indexAt(QPoint(2, 2)));
+}
+
+BookmarkManagerWidget::~BookmarkManagerWidget()
+{
+ TRACE_OBJ
+}
+
+void BookmarkManagerWidget::closeEvent(QCloseEvent *event)
+{
+ TRACE_OBJ
+ event->accept();
+ emit managerWidgetAboutToClose();
+}
+
+void BookmarkManagerWidget::renameItem(const QModelIndex &index)
+{
+ TRACE_OBJ
+ // check if we should rename the "Bookmarks Menu", bail
+ if (!bookmarkModel->parent(index).isValid())
+ return;
+
+ bookmarkModel->setItemsEditable(true);
+ ui.treeView->edit(index);
+ bookmarkModel->setItemsEditable(false);
+}
+
+static int nextIndex(int current, int count, bool forward)
+{
+ TRACE_OBJ
+ if (current >= 0)
+ return (forward ? (current + 1) : ((current - 1) + count)) % count;
+ return 0;
+}
+
+void BookmarkManagerWidget::selectNextIndex(bool direction) const
+{
+ QModelIndex current = ui.treeView->currentIndex();
+ if (current.isValid() && !cache.isEmpty()) {
+ current = cache.at(nextIndex(cache.indexOf(current), cache.count(),
+ direction));
+ }
+ ui.treeView->setCurrentIndex(current);
+}
+
+bool BookmarkManagerWidget::eventFilter(QObject *object, QEvent *event)
+{
+ TRACE_OBJ
+ if (object != ui.treeView && object != ui.treeView->viewport())
+ return QWidget::eventFilter(object, event);
+
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ switch (ke->key()) {
+ case Qt::Key_F2: {
+ renameItem(ui.treeView->currentIndex());
+ } break;
+
+ case Qt::Key_Delete: {
+ removeItem(ui.treeView->currentIndex());
+ } break;
+
+ default: break;
+ }
+ }
+
+ if (event->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ switch (me->button()) {
+ case Qt::LeftButton: {
+ if (me->modifiers() & Qt::ControlModifier)
+ setSourceFromIndex(ui.treeView->currentIndex(), true);
+ } break;
+
+ case Qt::MidButton: {
+ setSourceFromIndex(ui.treeView->currentIndex(), true);
+ } break;
+
+ default: break;
+ }
+ }
+ return QObject::eventFilter(object, event);
+}
+
+void BookmarkManagerWidget::findNext()
+{
+ TRACE_OBJ
+ selectNextIndex(true);
+}
+
+void BookmarkManagerWidget::findPrevious()
+{
+ TRACE_OBJ
+ selectNextIndex(false);
+}
+
+void BookmarkManagerWidget::importBookmarks()
+{
+ TRACE_OBJ
+ const QString &fileName = QFileDialog::getOpenFileName(0, TR("Open File"),
+ QDir::currentPath(), TR("Files (*.xbel)"));
+
+ if (fileName.isEmpty())
+ return;
+
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly)) {
+ XbelReader reader(bookmarkModel);
+ reader.readFromFile(&file);
+ }
+}
+
+void BookmarkManagerWidget::exportBookmarks()
+{
+ TRACE_OBJ
+ QString fileName = QFileDialog::getSaveFileName(0, TR("Save File"),
+ QLatin1String("untitled.xbel"), TR("Files (*.xbel)"));
+
+ const QLatin1String suffix(".xbel");
+ if (!fileName.endsWith(suffix))
+ fileName.append(suffix);
+
+ QFile file(fileName);
+ if (file.open(QIODevice::WriteOnly)) {
+ XbelWriter writer(bookmarkModel);
+ writer.writeToFile(&file);
+ } else {
+ QMessageBox::information(this, TR("Qt Assistant"),
+ TR("Unable to save bookmarks."), TR("OK"));
+ }
+}
+
+void BookmarkManagerWidget::refeshBookmarkCache()
+{
+ TRACE_OBJ
+ cache.clear();
+
+ const QString &text = ui.lineEdit->text();
+ if (!text.isEmpty())
+ cache = bookmarkModel->indexListFor(text);
+}
+
+void BookmarkManagerWidget::textChanged(const QString &/*text*/)
+{
+ TRACE_OBJ
+ refeshBookmarkCache();
+ if (!cache.isEmpty())
+ ui.treeView->setCurrentIndex(cache.at(0));
+}
+
+void BookmarkManagerWidget::removeItem(const QModelIndex &index)
+{
+ TRACE_OBJ
+ QModelIndex current = index.isValid() ? index : ui.treeView->currentIndex();
+ if (!bookmarkModel->parent(current).isValid())
+ return; // check if we should delete the "Bookmarks Menu", bail
+
+ if (bookmarkModel->hasChildren(current)) {
+ int value = QMessageBox::question(this, TR("Remove"), TR("You are going"
+ "to delete a Folder, this will also<br> remove it's content. Are "
+ "you sure to continue?"),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
+ if (value == QMessageBox::Cancel)
+ return;
+ }
+ bookmarkModel->removeItem(current);
+}
+
+void BookmarkManagerWidget::customContextMenuRequested(const QPoint &point)
+{
+ TRACE_OBJ
+ const QModelIndex &index = ui.treeView->indexAt(point);
+ if (!index.isValid())
+ return;
+
+ // check if we should open the menu on "Bookmarks Menu", bail
+ if (!bookmarkModel->parent(index).isValid())
+ return;
+
+ QAction *remove = 0;
+ QAction *rename = 0;
+ QAction *showItem = 0;
+ QAction *showItemInNewTab = 0;
+
+ QMenu menu(QLatin1String(""));
+ if (bookmarkModel->data(index, UserRoleFolder).toBool()) {
+ remove = menu.addAction(TR("Delete Folder"));
+ rename = menu.addAction(TR("Rename Folder"));
+ } else {
+ showItem = menu.addAction(TR("Show Bookmark"));
+ showItemInNewTab = menu.addAction(TR("Show Bookmark in New Tab"));
+ menu.addSeparator();
+ remove = menu.addAction(TR("Delete Bookmark"));
+ rename = menu.addAction(TR("Rename Bookmark"));
+ }
+
+ QAction *pickedAction = menu.exec(ui.treeView->mapToGlobal(point));
+ if (pickedAction == rename)
+ renameItem(index);
+ else if (pickedAction == remove)
+ removeItem(index);
+ else if (pickedAction == showItem || pickedAction == showItemInNewTab)
+ setSourceFromIndex(index, pickedAction == showItemInNewTab);
+}
+
+void
+BookmarkManagerWidget::setSourceFromIndex(const QModelIndex &index, bool newTab)
+{
+ TRACE_OBJ
+ if (bookmarkModel->data(index, UserRoleFolder).toBool())
+ return;
+
+ const QVariant &data = bookmarkModel->data(index, UserRoleUrl);
+ if (data.canConvert<QUrl>()) {
+ if (newTab)
+ emit setSourceInNewTab(data.toUrl());
+ else
+ emit setSource(data.toUrl());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/bookmarkmanagerwidget.h b/src/assistant/tools/assistant/bookmarkmanagerwidget.h
new file mode 100644
index 000000000..a0dec72a6
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkmanagerwidget.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKMANAGERWIDGET_H
+#define BOOKMARKMANAGERWIDGET_H
+
+#include "ui_bookmarkmanagerwidget.h"
+
+#include <QtCore/QPersistentModelIndex>
+
+#include <QtGui/QMenu>
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkModel;
+class QCloseEvent;
+class QString;
+
+class BookmarkManagerWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit BookmarkManagerWidget(BookmarkModel *bookmarkModel,
+ QWidget *parent = 0);
+ ~BookmarkManagerWidget();
+
+protected:
+ void closeEvent(QCloseEvent *event);
+
+signals:
+ void setSource(const QUrl &url);
+ void setSourceInNewTab(const QUrl &url);
+
+ void managerWidgetAboutToClose();
+
+private:
+ void renameItem(const QModelIndex &index);
+ void selectNextIndex(bool direction) const;
+ bool eventFilter(QObject *object, QEvent *event);
+
+private slots:
+ void findNext();
+ void findPrevious();
+
+ void importBookmarks();
+ void exportBookmarks();
+
+ void refeshBookmarkCache();
+ void textChanged(const QString &text);
+
+ void removeItem(const QModelIndex &index = QModelIndex());
+
+ void customContextMenuRequested(const QPoint &point);
+ void setSourceFromIndex(const QModelIndex &index, bool newTab = false);
+
+private:
+ QMenu importExportMenu;
+ Ui::BookmarkManagerWidget ui;
+ QList<QPersistentModelIndex> cache;
+
+ BookmarkModel *bookmarkModel;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKMANAGERWIDGET_H
diff --git a/src/assistant/tools/assistant/bookmarkmanagerwidget.ui b/src/assistant/tools/assistant/bookmarkmanagerwidget.ui
new file mode 100644
index 000000000..dc965d94e
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkmanagerwidget.ui
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BookmarkManagerWidget</class>
+ <widget class="QWidget" name="BookmarkManagerWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>517</width>
+ <height>348</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Manage Bookmarks</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Search:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeView" name="treeView">
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>true</bool>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="autoExpandDelay">
+ <number>1000</number>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <attribute name="headerDefaultSectionSize">
+ <number>225</number>
+ </attribute>
+ <attribute name="headerMinimumSectionSize">
+ <number>50</number>
+ </attribute>
+ <attribute name="headerDefaultSectionSize">
+ <number>225</number>
+ </attribute>
+ <attribute name="headerMinimumSectionSize">
+ <number>50</number>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="remove">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="importExport">
+ <property name="text">
+ <string>Import and Backup</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton_5">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>pushButton_5</sender>
+ <signal>clicked()</signal>
+ <receiver>BookmarkManagerWidget</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>445</x>
+ <y>328</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>340</x>
+ <y>313</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/assistant/tools/assistant/bookmarkmodel.cpp b/src/assistant/tools/assistant/bookmarkmodel.cpp
new file mode 100644
index 000000000..49b89c38f
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkmodel.cpp
@@ -0,0 +1,461 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bookmarkmodel.h"
+#include "bookmarkitem.h"
+
+#include <QtCore/QMimeData>
+#include <QtCore/QStack>
+
+#include <QtGui/QApplication>
+#include <QtGui/QStyle>
+#include <QtGui/QTreeView>
+
+const quint32 VERSION = 0xe53798;
+const QLatin1String MIMETYPE("application/bookmarks.assistant");
+
+BookmarkModel::BookmarkModel()
+ : QAbstractItemModel()
+ , m_folder(false)
+ , m_editable(false)
+ , rootItem(0)
+{
+}
+
+BookmarkModel::~BookmarkModel()
+{
+ delete rootItem;
+}
+
+QByteArray
+BookmarkModel::bookmarks() const
+{
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ stream << qint32(VERSION);
+
+ const QModelIndex &root = index(0,0, QModelIndex()).parent();
+ for (int i = 0; i < rowCount(root); ++i)
+ collectItems(index(i, 0, root), 0, &stream);
+
+ return ba;
+}
+
+void
+BookmarkModel::setBookmarks(const QByteArray &bookmarks)
+{
+ beginResetModel();
+
+ delete rootItem;
+ folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon);
+ bookmarkIcon = QIcon(QLatin1String(":/trolltech/assistant/images/bookmark.png"));
+
+ rootItem = new BookmarkItem(DataVector() << tr("Name") << tr("Address")
+ << true);
+
+ QStack<BookmarkItem*> parents;
+ QDataStream stream(bookmarks);
+
+ qint32 version;
+ stream >> version;
+ if (version < VERSION) {
+ stream.device()->seek(0);
+ BookmarkItem* toolbar = new BookmarkItem(DataVector() << tr("Toolbar Menu")
+ << QLatin1String("Folder") << true);
+ rootItem->addChild(toolbar);
+
+ BookmarkItem* menu = new BookmarkItem(DataVector() << tr("Bookmarks Menu")
+ << QLatin1String("Folder") << true);
+ rootItem->addChild(menu);
+ parents.push(menu);
+ } else {
+ parents.push(rootItem);
+ }
+
+ qint32 depth;
+ bool expanded;
+ QString name, url;
+ while (!stream.atEnd()) {
+ stream >> depth >> name >> url >> expanded;
+ while ((parents.count() - 1) != depth)
+ parents.pop();
+
+ BookmarkItem *item = new BookmarkItem(DataVector() << name << url << expanded);
+ if (url == QLatin1String("Folder")) {
+ parents.top()->addChild(item);
+ parents.push(item);
+ } else {
+ parents.top()->addChild(item);
+ }
+ }
+
+ cache.clear();
+ setupCache(index(0,0, QModelIndex().parent()));
+ endResetModel();
+}
+
+void
+BookmarkModel::setItemsEditable(bool editable)
+{
+ m_editable = editable;
+}
+
+void
+BookmarkModel::expandFoldersIfNeeeded(QTreeView *treeView)
+{
+ foreach (const QModelIndex &index, cache)
+ treeView->setExpanded(index, index.data(UserRoleExpanded).toBool());
+}
+
+QModelIndex
+BookmarkModel::addItem(const QModelIndex &parent, bool isFolder)
+{
+ m_folder = isFolder;
+ QModelIndex next;
+ if (insertRow(rowCount(parent), parent))
+ next = index(rowCount(parent) - 1, 0, parent);
+ m_folder = false;
+
+ return next;
+}
+
+bool
+BookmarkModel::removeItem(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return false;
+
+ QModelIndexList indexes;
+ if (rowCount(index) > 0)
+ indexes = collectItems(index);
+ indexes.append(index);
+
+ foreach (const QModelIndex &itemToRemove, indexes) {
+ if (!removeRow(itemToRemove.row(), itemToRemove.parent()))
+ return false;
+ cache.remove(itemFromIndex(itemToRemove));
+ }
+ return true;
+}
+
+int
+BookmarkModel::rowCount(const QModelIndex &index) const
+{
+ if (BookmarkItem *item = itemFromIndex(index))
+ return item->childCount();
+ return 0;
+}
+
+int
+BookmarkModel::columnCount(const QModelIndex &/*index*/) const
+{
+ return 2;
+}
+
+QModelIndex
+BookmarkModel::parent(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ if (BookmarkItem *childItem = itemFromIndex(index)) {
+ if (BookmarkItem *parent = childItem->parent()) {
+ if (parent != rootItem)
+ return createIndex(parent->childNumber(), 0, parent);
+ }
+ }
+ return QModelIndex();
+}
+
+QModelIndex
+BookmarkModel::index(int row, int column, const QModelIndex &index) const
+{
+ if (index.isValid() && (index.column() != 0 && index.column() != 1))
+ return QModelIndex();
+
+ if (BookmarkItem *parent = itemFromIndex(index)) {
+ if (BookmarkItem *childItem = parent->child(row))
+ return createIndex(row, column, childItem);
+ }
+ return QModelIndex();
+}
+
+Qt::DropActions
+BookmarkModel::supportedDropActions () const
+{
+ return /* Qt::CopyAction | */Qt::MoveAction;
+}
+
+Qt::ItemFlags
+BookmarkModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return Qt::NoItemFlags;
+
+ Qt::ItemFlags defaultFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+
+ if (m_editable)
+ defaultFlags |= Qt::ItemIsEditable;
+
+ if (itemFromIndex(index) && index.data(UserRoleFolder).toBool()) {
+ if (index.column() > 0)
+ return defaultFlags &~ Qt::ItemIsEditable;
+ return defaultFlags | Qt::ItemIsDropEnabled;
+ }
+
+ return defaultFlags | Qt::ItemIsDragEnabled;
+}
+
+QVariant
+BookmarkModel::data(const QModelIndex &index, int role) const
+{
+ if (index.isValid()) {
+ if (BookmarkItem *item = itemFromIndex(index)) {
+ switch (role) {
+ case Qt::EditRole: {
+ case Qt::DisplayRole:
+ if (index.data(UserRoleFolder).toBool() && index.column() == 1)
+ return QLatin1String("");
+ return item->data(index.column());
+ } break;
+
+ case Qt::DecorationRole: {
+ if (index.column() == 0)
+ return index.data(UserRoleFolder).toBool()
+ ? folderIcon : bookmarkIcon;
+ } break;
+
+ default:;
+ return item->data(role);
+ }
+ }
+ }
+ return QVariant();
+}
+
+void BookmarkModel::setData(const QModelIndex &index, const DataVector &data)
+{
+ if (BookmarkItem *item = itemFromIndex(index)) {
+ item->setData(data);
+ emit dataChanged(index, index);
+ }
+}
+
+bool
+BookmarkModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ bool result = false;
+ if (role != Qt::EditRole && role != UserRoleExpanded)
+ return result;
+
+ if (BookmarkItem *item = itemFromIndex(index)) {
+ if (role == Qt::EditRole) {
+ const bool isFolder = index.data(UserRoleFolder).toBool();
+ if (!isFolder || (isFolder && index.column() == 0))
+ result = item->setData(index.column(), value);
+ } else if (role == UserRoleExpanded) {
+ result = item->setData(UserRoleExpanded, value);
+ }
+ }
+
+ if (result)
+ emit dataChanged(index, index);
+ return result;
+}
+
+QVariant
+BookmarkModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (rootItem && orientation == Qt::Horizontal && role == Qt::DisplayRole)
+ return rootItem->data(section);
+ return QVariant();
+}
+
+QModelIndex
+BookmarkModel::indexFromItem(BookmarkItem *item) const
+{
+ return cache.value(item, QModelIndex());
+}
+
+BookmarkItem*
+BookmarkModel::itemFromIndex(const QModelIndex &index) const
+{
+ if (index.isValid())
+ return static_cast<BookmarkItem*>(index.internalPointer());
+ return rootItem;
+}
+
+QList<QPersistentModelIndex>
+BookmarkModel::indexListFor(const QString &label) const
+{
+ QList<QPersistentModelIndex> hits;
+ const QModelIndexList &list = collectItems(QModelIndex());
+ foreach(const QModelIndex &index, list) {
+ if (index.data().toString().contains(label, Qt::CaseInsensitive))
+ hits.prepend(index); // list is reverse sorted
+ }
+ return hits;
+}
+
+bool
+BookmarkModel::insertRows(int position, int rows, const QModelIndex &parent)
+{
+ if (!parent.data(UserRoleFolder).toBool())
+ return false;
+
+ bool success = false;
+ if (BookmarkItem *parentItem = itemFromIndex(parent)) {
+ beginInsertRows(parent, position, position + rows - 1);
+ success = parentItem->insertChildren(m_folder, position, rows);
+ if (success) {
+ const QModelIndex &current = index(position, 0, parent);
+ cache.insert(itemFromIndex(current), current);
+ }
+ endInsertRows();
+ }
+ return success;
+}
+
+bool
+BookmarkModel::removeRows(int position, int rows, const QModelIndex &index)
+{
+ bool success = false;
+ if (BookmarkItem *parent = itemFromIndex(index)) {
+ beginRemoveRows(index, position, position + rows - 1);
+ success = parent->removeChildren(position, rows);
+ endRemoveRows();
+ }
+ return success;
+}
+
+QStringList
+BookmarkModel::mimeTypes() const
+{
+ return QStringList() << MIMETYPE;
+}
+
+QMimeData*
+BookmarkModel::mimeData(const QModelIndexList &indexes) const
+{
+ if (indexes.isEmpty())
+ return 0;
+
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+
+ foreach (const QModelIndex &index, indexes) {
+ if (index.column() == 0)
+ collectItems(index, 0, &stream);
+ }
+
+ QMimeData *mimeData = new QMimeData();
+ mimeData->setData(MIMETYPE, data);
+ return mimeData;
+}
+
+bool
+BookmarkModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent)
+{
+ if (action == Qt::IgnoreAction)
+ return true;
+
+ if (!data->hasFormat(MIMETYPE) || column > 0)
+ return false;
+
+ QByteArray ba = data->data(MIMETYPE);
+ QDataStream stream(&ba, QIODevice::ReadOnly);
+ while (stream.atEnd())
+ return false;
+
+ qint32 depth;
+ bool expanded;
+ QString name, url;
+ while (!stream.atEnd()) {
+ stream >> depth >> name >> url >> expanded;
+ if (insertRow(qMax(0, row), parent)) {
+ const QModelIndex &current = index(qMax(0, row), 0, parent);
+ if (current.isValid()) {
+ BookmarkItem* item = itemFromIndex(current);
+ item->setData(DataVector() << name << url << expanded);
+ }
+ }
+ }
+ return true;
+}
+
+void
+BookmarkModel::setupCache(const QModelIndex &parent)
+{
+ const QModelIndexList &list = collectItems(parent);
+ foreach (const QModelIndex &index, list)
+ cache.insert(itemFromIndex(index), index);
+}
+
+QModelIndexList
+BookmarkModel::collectItems(const QModelIndex &parent) const
+{
+ QModelIndexList list;
+ for (int i = rowCount(parent) - 1; i >= 0 ; --i) {
+ const QModelIndex &next = index(i, 0, parent);
+ if (data(next, UserRoleFolder).toBool())
+ list += collectItems(next);
+ list.append(next);
+ }
+ return list;
+}
+
+void
+BookmarkModel::collectItems(const QModelIndex &parent, qint32 depth,
+ QDataStream *stream) const
+{
+ if (parent.isValid()) {
+ *stream << depth;
+ *stream << parent.data().toString();
+ *stream << parent.data(UserRoleUrl).toString();
+ *stream << parent.data(UserRoleExpanded).toBool();
+
+ for (int i = 0; i < rowCount(parent); ++i) {
+ if (parent.data(UserRoleFolder).toBool())
+ collectItems(index(i, 0 , parent), depth + 1, stream);
+ }
+ }
+}
diff --git a/src/assistant/tools/assistant/bookmarkmodel.h b/src/assistant/tools/assistant/bookmarkmodel.h
new file mode 100644
index 000000000..33c9e981d
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkmodel.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKMODEL_H
+#define BOOKMARKMODEL_H
+
+#include <QtCore/QAbstractItemModel>
+
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkItem;
+class QMimeData;
+class QTreeView;
+
+typedef QMap<BookmarkItem*, QPersistentModelIndex> ItemModelIndexCache;
+
+class BookmarkModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ BookmarkModel();
+ ~BookmarkModel();
+
+ QByteArray bookmarks() const;
+ void setBookmarks(const QByteArray &bookmarks);
+
+ void setItemsEditable(bool editable);
+ void expandFoldersIfNeeeded(QTreeView *treeView);
+
+ QModelIndex addItem(const QModelIndex &parent, bool isFolder = false);
+ bool removeItem(const QModelIndex &index);
+
+ int rowCount(const QModelIndex &index = QModelIndex()) const;
+ int columnCount(const QModelIndex &index = QModelIndex()) const;
+
+ QModelIndex parent(const QModelIndex &index) const;
+ QModelIndex index(int row, int column, const QModelIndex &index) const;
+
+ Qt::DropActions supportedDropActions () const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ QVariant data(const QModelIndex &index, int role) const;
+ void setData(const QModelIndex &index, const QVector<QVariant> &data);
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+ QModelIndex indexFromItem(BookmarkItem *item) const;
+ BookmarkItem *itemFromIndex(const QModelIndex &index) const;
+ QList<QPersistentModelIndex> indexListFor(const QString &label) const;
+
+ bool insertRows(int position, int rows, const QModelIndex &parent);
+ bool removeRows(int position, int rows, const QModelIndex &parent);
+
+ QStringList mimeTypes() const;
+ QMimeData* mimeData(const QModelIndexList &indexes) const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row,
+ int column, const QModelIndex &parent);
+
+private:
+ void setupCache(const QModelIndex &parent);
+ QModelIndexList collectItems(const QModelIndex &parent) const;
+ void collectItems(const QModelIndex &parent, qint32 depth,
+ QDataStream *stream) const;
+
+private:
+ int columns;
+ bool m_folder;
+ bool m_editable;
+ QIcon folderIcon;
+ QIcon bookmarkIcon;
+ QTreeView *treeView;
+ BookmarkItem *rootItem;
+ ItemModelIndexCache cache;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKMODEL_H
diff --git a/src/assistant/tools/assistant/bookmarkwidget.ui b/src/assistant/tools/assistant/bookmarkwidget.ui
new file mode 100644
index 000000000..a31a2779c
--- /dev/null
+++ b/src/assistant/tools/assistant/bookmarkwidget.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BookmarkWidget</class>
+ <widget class="QWidget" name="BookmarkWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>235</width>
+ <height>606</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Bookmarks</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="margin">
+ <number>4</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Filter:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="add">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="remove">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/tools/assistant/centralwidget.cpp b/src/assistant/tools/assistant/centralwidget.cpp
new file mode 100644
index 000000000..c8c454f60
--- /dev/null
+++ b/src/assistant/tools/assistant/centralwidget.cpp
@@ -0,0 +1,636 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "centralwidget.h"
+
+#include "findwidget.h"
+#include "helpenginewrapper.h"
+#include "helpviewer.h"
+#include "openpagesmanager.h"
+#include "tracer.h"
+#include "../shared/collectionconfiguration.h"
+
+#include <QtCore/QTimer>
+
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QPageSetupDialog>
+#include <QtGui/QPrintDialog>
+#include <QtGui/QPrintPreviewDialog>
+#include <QtGui/QPrinter>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QTextBrowser>
+#include <QtGui/QVBoxLayout>
+
+#include <QtHelp/QHelpSearchEngine>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ CentralWidget *staticCentralWidget = 0;
+}
+
+// -- TabBar
+
+TabBar::TabBar(QWidget *parent)
+ : QTabBar(parent)
+{
+ TRACE_OBJ
+#ifdef Q_OS_MAC
+ setDocumentMode(true);
+#endif
+ setMovable(true);
+ setShape(QTabBar::RoundedNorth);
+ setContextMenuPolicy(Qt::CustomContextMenu);
+ setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred,
+ QSizePolicy::TabWidget));
+ connect(this, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentChanged(int)));
+ connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(slotTabCloseRequested(int)));
+ connect(this, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(slotCustomContextMenuRequested(QPoint)));
+}
+
+TabBar::~TabBar()
+{
+ TRACE_OBJ
+}
+
+int TabBar::addNewTab(const QString &title)
+{
+ TRACE_OBJ
+ const int index = addTab(title);
+ setTabsClosable(count() > 1);
+ return index;
+}
+
+void TabBar::setCurrent(HelpViewer *viewer)
+{
+ TRACE_OBJ
+ for (int i = 0; i < count(); ++i) {
+ HelpViewer *data = tabData(i).value<HelpViewer*>();
+ if (data == viewer) {
+ setCurrentIndex(i);
+ break;
+ }
+ }
+}
+
+void TabBar::removeTabAt(HelpViewer *viewer)
+{
+ TRACE_OBJ
+ for (int i = 0; i < count(); ++i) {
+ HelpViewer *data = tabData(i).value<HelpViewer*>();
+ if (data == viewer) {
+ removeTab(i);
+ break;
+ }
+ }
+ setTabsClosable(count() > 1);
+}
+
+void TabBar::titleChanged()
+{
+ TRACE_OBJ
+ for (int i = 0; i < count(); ++i) {
+ HelpViewer *data = tabData(i).value<HelpViewer*>();
+ QString title = data->title();
+ title.replace(QLatin1Char('&'), QLatin1String("&&"));
+ setTabText(i, title.isEmpty() ? tr("(Untitled)") : title);
+ }
+}
+
+void TabBar::slotCurrentChanged(int index)
+{
+ TRACE_OBJ
+ emit currentTabChanged(tabData(index).value<HelpViewer*>());
+}
+
+void TabBar::slotTabCloseRequested(int index)
+{
+ TRACE_OBJ
+ OpenPagesManager::instance()->closePage(tabData(index).value<HelpViewer*>());
+}
+
+void TabBar::slotCustomContextMenuRequested(const QPoint &pos)
+{
+ TRACE_OBJ
+ const int tab = tabAt(pos);
+ if (tab < 0)
+ return;
+
+ QMenu menu(QLatin1String(""), this);
+ menu.addAction(tr("New &Tab"), OpenPagesManager::instance(), SLOT(createPage()));
+
+ const bool enableAction = count() > 1;
+ QAction *closePage = menu.addAction(tr("&Close Tab"));
+ closePage->setEnabled(enableAction);
+
+ QAction *closePages = menu.addAction(tr("Close Other Tabs"));
+ closePages->setEnabled(enableAction);
+
+ menu.addSeparator();
+
+ HelpViewer *viewer = tabData(tab).value<HelpViewer*>();
+ QAction *newBookmark = menu.addAction(tr("Add Bookmark for this Page..."));
+ const QString &url = viewer->source().toString();
+ if (url.isEmpty() || url == QLatin1String("about:blank"))
+ newBookmark->setEnabled(false);
+
+ QAction *pickedAction = menu.exec(mapToGlobal(pos));
+ if (pickedAction == closePage)
+ slotTabCloseRequested(tab);
+ else if (pickedAction == closePages) {
+ for (int i = count() - 1; i >= 0; --i) {
+ if (i != tab)
+ slotTabCloseRequested(i);
+ }
+ } else if (pickedAction == newBookmark)
+ emit addBookmark(viewer->title(), url);
+}
+
+// -- CentralWidget
+
+CentralWidget::CentralWidget(QWidget *parent)
+ : QWidget(parent)
+#ifndef QT_NO_PRINTER
+ , m_printer(0)
+#endif
+ , m_findWidget(new FindWidget(this))
+ , m_stackedWidget(new QStackedWidget(this))
+ , m_tabBar(new TabBar(this))
+{
+ TRACE_OBJ
+ staticCentralWidget = this;
+ QVBoxLayout *vboxLayout = new QVBoxLayout(this);
+
+ vboxLayout->setMargin(0);
+ vboxLayout->setSpacing(0);
+ vboxLayout->addWidget(m_tabBar);
+ m_tabBar->setVisible(HelpEngineWrapper::instance().showTabs());
+ vboxLayout->addWidget(m_stackedWidget);
+ vboxLayout->addWidget(m_findWidget);
+ m_findWidget->hide();
+
+ connect(m_findWidget, SIGNAL(findNext()), this, SLOT(findNext()));
+ connect(m_findWidget, SIGNAL(findPrevious()), this, SLOT(findPrevious()));
+ connect(m_findWidget, SIGNAL(find(QString, bool, bool)), this,
+ SLOT(find(QString, bool, bool)));
+ connect(m_findWidget, SIGNAL(escapePressed()), this, SLOT(activateTab()));
+ connect(m_tabBar, SIGNAL(addBookmark(QString, QString)), this,
+ SIGNAL(addBookmark(QString, QString)));
+}
+
+CentralWidget::~CentralWidget()
+{
+ TRACE_OBJ
+ QStringList zoomFactors;
+ QStringList currentPages;
+ for (int i = 0; i < m_stackedWidget->count(); ++i) {
+ const HelpViewer * const viewer = viewerAt(i);
+ const QUrl &source = viewer->source();
+ if (source.isValid()) {
+ currentPages << source.toString();
+ zoomFactors << QString::number(viewer->scale());
+ }
+ }
+
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ helpEngine.setLastShownPages(currentPages);
+ helpEngine.setLastZoomFactors(zoomFactors);
+ helpEngine.setLastTabPage(m_stackedWidget->currentIndex());
+
+#ifndef QT_NO_PRINTER
+ delete m_printer;
+#endif
+}
+
+CentralWidget *CentralWidget::instance()
+{
+ TRACE_OBJ
+ return staticCentralWidget;
+}
+
+QUrl CentralWidget::currentSource() const
+{
+ TRACE_OBJ
+ return currentHelpViewer()->source();
+}
+
+QString CentralWidget::currentTitle() const
+{
+ TRACE_OBJ
+ return currentHelpViewer()->title();
+}
+
+bool CentralWidget::hasSelection() const
+{
+ TRACE_OBJ
+ return !currentHelpViewer()->selectedText().isEmpty();
+}
+
+bool CentralWidget::isForwardAvailable() const
+{
+ TRACE_OBJ
+ return currentHelpViewer()->isForwardAvailable();
+}
+
+bool CentralWidget::isBackwardAvailable() const
+{
+ TRACE_OBJ
+ return currentHelpViewer()->isBackwardAvailable();
+}
+
+HelpViewer* CentralWidget::viewerAt(int index) const
+{
+ TRACE_OBJ
+ return static_cast<HelpViewer*>(m_stackedWidget->widget(index));
+}
+
+HelpViewer* CentralWidget::currentHelpViewer() const
+{
+ TRACE_OBJ
+ return static_cast<HelpViewer *>(m_stackedWidget->currentWidget());
+}
+
+void CentralWidget::addPage(HelpViewer *page, bool fromSearch)
+{
+ TRACE_OBJ
+ page->installEventFilter(this);
+ page->setFocus(Qt::OtherFocusReason);
+ connectSignals(page);
+ const int index = m_stackedWidget->addWidget(page);
+ m_tabBar->setTabData(m_tabBar->addNewTab(page->title()),
+ QVariant::fromValue(viewerAt(index)));
+ connect (page, SIGNAL(titleChanged()), m_tabBar, SLOT(titleChanged()));
+
+ if (fromSearch) {
+ connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this,
+ SLOT(highlightSearchTerms()));
+ }
+}
+
+void CentralWidget::removePage(int index)
+{
+ TRACE_OBJ
+ const bool currentChanged = index == currentIndex();
+ m_tabBar->removeTabAt(viewerAt(index));
+ m_stackedWidget->removeWidget(m_stackedWidget->widget(index));
+ if (currentChanged)
+ emit currentViewerChanged();
+}
+
+int CentralWidget::currentIndex() const
+{
+ TRACE_OBJ
+ return m_stackedWidget->currentIndex();
+}
+
+void CentralWidget::setCurrentPage(HelpViewer *page)
+{
+ TRACE_OBJ
+ m_tabBar->setCurrent(page);
+ m_stackedWidget->setCurrentWidget(page);
+ emit currentViewerChanged();
+}
+
+void CentralWidget::connectTabBar()
+{
+ TRACE_OBJ
+ connect(m_tabBar, SIGNAL(currentTabChanged(HelpViewer*)),
+ OpenPagesManager::instance(), SLOT(setCurrentPage(HelpViewer*)));
+}
+
+// -- public slots
+
+void CentralWidget::copy()
+{
+ TRACE_OBJ
+ currentHelpViewer()->copy();
+}
+
+void CentralWidget::home()
+{
+ TRACE_OBJ
+ currentHelpViewer()->home();
+}
+
+void CentralWidget::zoomIn()
+{
+ TRACE_OBJ
+ currentHelpViewer()->scaleUp();
+}
+
+void CentralWidget::zoomOut()
+{
+ TRACE_OBJ
+ currentHelpViewer()->scaleDown();
+}
+
+void CentralWidget::resetZoom()
+{
+ TRACE_OBJ
+ currentHelpViewer()->resetScale();
+}
+
+void CentralWidget::forward()
+{
+ TRACE_OBJ
+ currentHelpViewer()->forward();
+}
+
+void CentralWidget::nextPage()
+{
+ TRACE_OBJ
+ m_stackedWidget->setCurrentIndex((m_stackedWidget->currentIndex() + 1)
+ % m_stackedWidget->count());
+}
+
+void CentralWidget::backward()
+{
+ TRACE_OBJ
+ currentHelpViewer()->backward();
+}
+
+void CentralWidget::previousPage()
+{
+ TRACE_OBJ
+ m_stackedWidget->setCurrentIndex((m_stackedWidget->currentIndex() - 1)
+ % m_stackedWidget->count());
+}
+
+void CentralWidget::print()
+{
+ TRACE_OBJ
+#ifndef QT_NO_PRINTER
+ initPrinter();
+ QPrintDialog dlg(m_printer, this);
+
+ if (!currentHelpViewer()->selectedText().isEmpty())
+ dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
+ dlg.addEnabledOption(QAbstractPrintDialog::PrintPageRange);
+ dlg.addEnabledOption(QAbstractPrintDialog::PrintCollateCopies);
+ dlg.setWindowTitle(tr("Print Document"));
+ if (dlg.exec() == QDialog::Accepted)
+ currentHelpViewer()->print(m_printer);
+#endif
+}
+
+void CentralWidget::pageSetup()
+{
+ TRACE_OBJ
+#ifndef QT_NO_PRINTER
+ initPrinter();
+ QPageSetupDialog dlg(m_printer);
+ dlg.exec();
+#endif
+}
+
+void CentralWidget::printPreview()
+{
+ TRACE_OBJ
+#ifndef QT_NO_PRINTER
+ initPrinter();
+ QPrintPreviewDialog preview(m_printer, this);
+ connect(&preview, SIGNAL(paintRequested(QPrinter*)),
+ SLOT(printPreview(QPrinter*)));
+ preview.exec();
+#endif
+}
+
+void CentralWidget::setSource(const QUrl &url)
+{
+ TRACE_OBJ
+ HelpViewer *viewer = currentHelpViewer();
+ viewer->setSource(url);
+ viewer->setFocus(Qt::OtherFocusReason);
+}
+
+void CentralWidget::setSourceFromSearch(const QUrl &url)
+{
+ TRACE_OBJ
+ connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this,
+ SLOT(highlightSearchTerms()));
+ currentHelpViewer()->setSource(url);
+ currentHelpViewer()->setFocus(Qt::OtherFocusReason);
+}
+
+void CentralWidget::findNext()
+{
+ TRACE_OBJ
+ find(m_findWidget->text(), true, false);
+}
+
+void CentralWidget::findPrevious()
+{
+ TRACE_OBJ
+ find(m_findWidget->text(), false, false);
+}
+
+void CentralWidget::find(const QString &ttf, bool forward, bool incremental)
+{
+ TRACE_OBJ
+ bool found = false;
+ if (HelpViewer *viewer = currentHelpViewer()) {
+ HelpViewer::FindFlags flags = 0;
+ if (!forward)
+ flags |= HelpViewer::FindBackward;
+ if (m_findWidget->caseSensitive())
+ flags |= HelpViewer::FindCaseSensitively;
+ found = viewer->findText(ttf, flags, incremental, false);
+ }
+
+ if (!found && ttf.isEmpty())
+ found = true; // the line edit is empty, no need to mark it red...
+
+ if (!m_findWidget->isVisible())
+ m_findWidget->show();
+ m_findWidget->setPalette(found);
+}
+
+void CentralWidget::activateTab()
+{
+ TRACE_OBJ
+ currentHelpViewer()->setFocus();
+}
+
+void CentralWidget::showTextSearch()
+{
+ TRACE_OBJ
+ m_findWidget->show();
+}
+
+void CentralWidget::updateBrowserFont()
+{
+ TRACE_OBJ
+ const int count = m_stackedWidget->count();
+ const QFont &font = viewerAt(count - 1)->viewerFont();
+ for (int i = 0; i < count; ++i)
+ viewerAt(i)->setViewerFont(font);
+}
+
+void CentralWidget::updateUserInterface()
+{
+ m_tabBar->setVisible(HelpEngineWrapper::instance().showTabs());
+}
+
+// -- protected
+
+void CentralWidget::keyPressEvent(QKeyEvent *e)
+{
+ TRACE_OBJ
+ const QString &text = e->text();
+ if (text.startsWith(QLatin1Char('/'))) {
+ if (!m_findWidget->isVisible()) {
+ m_findWidget->showAndClear();
+ } else {
+ m_findWidget->show();
+ }
+ } else {
+ QWidget::keyPressEvent(e);
+ }
+}
+
+void CentralWidget::focusInEvent(QFocusEvent * /* event */)
+{
+ TRACE_OBJ
+ // If we have a current help viewer then this is the 'focus proxy',
+ // otherwise it's the central widget. This is needed, so an embedding
+ // program can just set the focus to the central widget and it does
+ // The Right Thing(TM)
+ QObject *receiver = m_stackedWidget;
+ if (HelpViewer *viewer = currentHelpViewer())
+ receiver = viewer;
+ QTimer::singleShot(1, receiver, SLOT(setFocus()));
+}
+
+// -- private slots
+
+void CentralWidget::highlightSearchTerms()
+{
+ TRACE_OBJ
+ QHelpSearchEngine *searchEngine =
+ HelpEngineWrapper::instance().searchEngine();
+ QList<QHelpSearchQuery> queryList = searchEngine->query();
+
+ QStringList terms;
+ foreach (const QHelpSearchQuery &query, queryList) {
+ switch (query.fieldName) {
+ default: break;
+ case QHelpSearchQuery::ALL: {
+ case QHelpSearchQuery::PHRASE:
+ case QHelpSearchQuery::DEFAULT:
+ case QHelpSearchQuery::ATLEAST:
+ foreach (QString term, query.wordList)
+ terms.append(term.remove(QLatin1Char('"')));
+ }
+ }
+ }
+
+ HelpViewer *viewer = currentHelpViewer();
+ foreach (const QString& term, terms)
+ viewer->findText(term, 0, false, true);
+ disconnect(viewer, SIGNAL(loadFinished(bool)), this,
+ SLOT(highlightSearchTerms()));
+}
+
+void CentralWidget::printPreview(QPrinter *p)
+{
+ TRACE_OBJ
+#ifndef QT_NO_PRINTER
+ currentHelpViewer()->print(p);
+#endif
+}
+
+void CentralWidget::handleSourceChanged(const QUrl &url)
+{
+ TRACE_OBJ
+ if (sender() == currentHelpViewer())
+ emit sourceChanged(url);
+}
+
+// -- private
+
+void CentralWidget::initPrinter()
+{
+ TRACE_OBJ
+#ifndef QT_NO_PRINTER
+ if (!m_printer)
+ m_printer = new QPrinter(QPrinter::HighResolution);
+#endif
+}
+
+void CentralWidget::connectSignals(HelpViewer *page)
+{
+ TRACE_OBJ
+ connect(page, SIGNAL(copyAvailable(bool)), this,
+ SIGNAL(copyAvailable(bool)));
+ connect(page, SIGNAL(forwardAvailable(bool)), this,
+ SIGNAL(forwardAvailable(bool)));
+ connect(page, SIGNAL(backwardAvailable(bool)), this,
+ SIGNAL(backwardAvailable(bool)));
+ connect(page, SIGNAL(sourceChanged(QUrl)), this,
+ SLOT(handleSourceChanged(QUrl)));
+ connect(page, SIGNAL(highlighted(QString)), this,
+ SIGNAL(highlighted(QString)));
+ connect(page, SIGNAL(printRequested()), this, SLOT(print()));
+}
+
+bool CentralWidget::eventFilter(QObject *object, QEvent *e)
+{
+ TRACE_OBJ
+ if (e->type() != QEvent::KeyPress)
+ return QWidget::eventFilter(object, e);
+
+ HelpViewer *viewer = currentHelpViewer();
+ QKeyEvent *keyEvent = static_cast<QKeyEvent*> (e);
+ if (viewer == object && keyEvent->key() == Qt::Key_Backspace) {
+ if (viewer->isBackwardAvailable()) {
+#if !defined(QT_NO_WEBKIT)
+ // this helps in case there is an html <input> field
+ if (!viewer->hasFocus())
+#endif
+ viewer->backward();
+ }
+ }
+ return QWidget::eventFilter(object, e);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/centralwidget.h b/src/assistant/tools/assistant/centralwidget.h
new file mode 100644
index 000000000..2645fa8df
--- /dev/null
+++ b/src/assistant/tools/assistant/centralwidget.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CENTRALWIDGET_H
+#define CENTRALWIDGET_H
+
+#include <QtCore/QUrl>
+
+#include <QtGui/QTabBar>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class FindWidget;
+class HelpViewer;
+class QStackedWidget;
+
+class TabBar : public QTabBar
+{
+ Q_OBJECT
+public:
+ TabBar(QWidget *parent = 0);
+ ~TabBar();
+
+ int addNewTab(const QString &title);
+ void setCurrent(HelpViewer *viewer);
+ void removeTabAt(HelpViewer *viewer);
+
+public slots:
+ void titleChanged();
+
+signals:
+ void currentTabChanged(HelpViewer *viewer);
+ void addBookmark(const QString &title, const QString &url);
+
+private slots:
+ void slotCurrentChanged(int index);
+ void slotTabCloseRequested(int index);
+ void slotCustomContextMenuRequested(const QPoint &pos);
+};
+
+class CentralWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CentralWidget(QWidget *parent = 0);
+ ~CentralWidget();
+
+ static CentralWidget *instance();
+
+ QUrl currentSource() const;
+ QString currentTitle() const;
+
+ bool hasSelection() const;
+ bool isForwardAvailable() const;
+ bool isBackwardAvailable() const;
+
+ HelpViewer *viewerAt(int index) const;
+ HelpViewer *currentHelpViewer() const;
+
+ void addPage(HelpViewer *page, bool fromSearch = false);
+ void removePage(int index);
+
+ int currentIndex() const;
+ void setCurrentPage(HelpViewer *page);
+
+ void connectTabBar();
+
+public slots:
+ void copy();
+ void home();
+
+ void zoomIn();
+ void zoomOut();
+ void resetZoom();
+
+ void forward();
+ void nextPage();
+
+ void backward();
+ void previousPage();
+
+ void print();
+ void pageSetup();
+ void printPreview();
+
+ void setSource(const QUrl &url);
+ void setSourceFromSearch(const QUrl &url);
+
+ void findNext();
+ void findPrevious();
+ void find(const QString &text, bool forward, bool incremental);
+
+ void activateTab();
+ void showTextSearch();
+ void updateBrowserFont();
+ void updateUserInterface();
+
+signals:
+ void currentViewerChanged();
+ void copyAvailable(bool yes);
+ void sourceChanged(const QUrl &url);
+ void highlighted(const QString &link);
+ void forwardAvailable(bool available);
+ void backwardAvailable(bool available);
+ void addBookmark(const QString &title, const QString &url);
+
+protected:
+ void keyPressEvent(QKeyEvent *);
+ void focusInEvent(QFocusEvent *event);
+
+private slots:
+ void highlightSearchTerms();
+ void printPreview(QPrinter *printer);
+ void handleSourceChanged(const QUrl &url);
+
+private:
+ void initPrinter();
+ void connectSignals(HelpViewer *page);
+ bool eventFilter(QObject *object, QEvent *e);
+
+private:
+#ifndef QT_NO_PRINTER
+ QPrinter *m_printer;
+#endif
+ FindWidget *m_findWidget;
+ QStackedWidget *m_stackedWidget;
+ TabBar *m_tabBar;
+};
+
+QT_END_NAMESPACE
+
+#endif // CENTRALWIDGET_H
diff --git a/src/assistant/tools/assistant/cmdlineparser.cpp b/src/assistant/tools/assistant/cmdlineparser.cpp
new file mode 100644
index 000000000..6a239d305
--- /dev/null
+++ b/src/assistant/tools/assistant/cmdlineparser.cpp
@@ -0,0 +1,376 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QStringBuilder>
+#include <QtGui/QMessageBox>
+
+#include "cmdlineparser.h"
+
+QT_BEGIN_NAMESPACE
+
+static const char helpMessage[] = QT_TRANSLATE_NOOP("CmdLineParser",
+ "Usage: assistant [Options]\n\n"
+ "-collectionFile file Uses the specified collection\n"
+ " file instead of the default one\n"
+ "-showUrl url Shows the document with the\n"
+ " url.\n"
+ "-enableRemoteControl Enables Assistant to be\n"
+ " remotely controlled.\n"
+ "-show widget Shows the specified dockwidget\n"
+ " which can be \"contents\", \"index\",\n"
+ " \"bookmarks\" or \"search\".\n"
+ "-activate widget Activates the specified dockwidget\n"
+ " which can be \"contents\", \"index\",\n"
+ " \"bookmarks\" or \"search\".\n"
+ "-hide widget Hides the specified dockwidget\n"
+ " which can be \"contents\", \"index\"\n"
+ " \"bookmarks\" or \"search\".\n"
+ "-register helpFile Registers the specified help file\n"
+ " (.qch) in the given collection\n"
+ " file.\n"
+ "-unregister helpFile Unregisters the specified help file\n"
+ " (.qch) from the give collection\n"
+ " file.\n"
+ "-setCurrentFilter filter Set the filter as the active filter.\n"
+ "-remove-search-index Removes the full text search index.\n"
+ "-rebuild-search-index Re-builds the full text search index (potentially slow).\n"
+ "-quiet Does not display any error or\n"
+ " status message.\n"
+ "-help Displays this help.\n"
+ );
+
+
+CmdLineParser::CmdLineParser(const QStringList &arguments)
+ : m_pos(0),
+ m_enableRemoteControl(false),
+ m_contents(Untouched),
+ m_index(Untouched),
+ m_bookmarks(Untouched),
+ m_search(Untouched),
+ m_register(None),
+ m_removeSearchIndex(false),
+ m_rebuildSearchIndex(false),
+ m_quiet(false)
+{
+ TRACE_OBJ
+ for (int i = 1; i < arguments.count(); ++i) {
+ const QString &arg = arguments.at(i);
+ if (arg.toLower() == "-quiet")
+ m_quiet = true;
+ else
+ m_arguments.append(arg);
+ }
+}
+
+CmdLineParser::Result CmdLineParser::parse()
+{
+ TRACE_OBJ
+ bool showHelp = false;
+
+ while (m_error.isEmpty() && hasMoreArgs()) {
+ const QString &arg = nextArg().toLower();
+ if (arg == QLatin1String("-collectionfile"))
+ handleCollectionFileOption();
+ else if (arg == QLatin1String("-showurl"))
+ handleShowUrlOption();
+ else if (arg == QLatin1String("-enableremotecontrol"))
+ m_enableRemoteControl = true;
+ else if (arg == QLatin1String("-show"))
+ handleShowOption();
+ else if (arg == QLatin1String("-hide"))
+ handleHideOption();
+ else if (arg == QLatin1String("-activate"))
+ handleActivateOption();
+ else if (arg == QLatin1String("-register"))
+ handleRegisterOption();
+ else if (arg == QLatin1String("-unregister"))
+ handleUnregisterOption();
+ else if (arg == QLatin1String("-setcurrentfilter"))
+ handleSetCurrentFilterOption();
+ else if (arg == QLatin1String("-remove-search-index"))
+ m_removeSearchIndex = true;
+ else if (arg == QLatin1String("-rebuild-search-index"))
+ m_rebuildSearchIndex = true;
+ else if (arg == QLatin1String("-help"))
+ showHelp = true;
+ else
+ m_error = tr("Unknown option: %1").arg(arg);
+ }
+
+ if (!m_error.isEmpty()) {
+ showMessage(m_error + QLatin1String("\n\n\n") + tr(helpMessage), true);
+ return Error;
+ } else if (showHelp) {
+ showMessage(tr(helpMessage), false);
+ return Help;
+ }
+ return Ok;
+}
+
+bool CmdLineParser::hasMoreArgs() const
+{
+ TRACE_OBJ
+ return m_pos < m_arguments.count();
+}
+
+const QString &CmdLineParser::nextArg()
+{
+ TRACE_OBJ
+ Q_ASSERT(hasMoreArgs());
+ return m_arguments.at(m_pos++);
+}
+
+void CmdLineParser::handleCollectionFileOption()
+{
+ TRACE_OBJ
+ if (hasMoreArgs()) {
+ const QString &fileName = nextArg();
+ m_collectionFile = getFileName(fileName);
+ if (m_collectionFile.isEmpty())
+ m_error = tr("The collection file '%1' does not exist.").
+ arg(fileName);
+ } else {
+ m_error = tr("Missing collection file.");
+ }
+}
+
+void CmdLineParser::handleShowUrlOption()
+{
+ TRACE_OBJ
+ if (hasMoreArgs()) {
+ const QString &urlString = nextArg();
+ QUrl url(urlString);
+ if (url.isValid()) {
+ m_url = url;
+ } else
+ m_error = tr("Invalid URL '%1'.").arg(urlString);
+ } else {
+ m_error = tr("Missing URL.");
+ }
+}
+
+void CmdLineParser::handleShowOption()
+{
+ TRACE_OBJ
+ handleShowOrHideOrActivateOption(Show);
+}
+
+void CmdLineParser::handleHideOption()
+{
+ TRACE_OBJ
+ handleShowOrHideOrActivateOption(Hide);
+}
+
+void CmdLineParser::handleActivateOption()
+{
+ TRACE_OBJ
+ handleShowOrHideOrActivateOption(Activate);
+}
+
+void CmdLineParser::handleShowOrHideOrActivateOption(ShowState state)
+{
+ TRACE_OBJ
+ if (hasMoreArgs()) {
+ const QString &widget = nextArg().toLower();
+ if (widget == QLatin1String("contents"))
+ m_contents = state;
+ else if (widget == QLatin1String("index"))
+ m_index = state;
+ else if (widget == QLatin1String("bookmarks"))
+ m_bookmarks = state;
+ else if (widget == QLatin1String("search"))
+ m_search = state;
+ else
+ m_error = tr("Unknown widget: %1").arg(widget);
+ } else {
+ m_error = tr("Missing widget.");
+ }
+}
+
+void CmdLineParser::handleRegisterOption()
+{
+ TRACE_OBJ
+ handleRegisterOrUnregisterOption(Register);
+}
+
+void CmdLineParser::handleUnregisterOption()
+{
+ TRACE_OBJ
+ handleRegisterOrUnregisterOption(Unregister);
+}
+
+void CmdLineParser::handleRegisterOrUnregisterOption(RegisterState state)
+{
+ TRACE_OBJ
+ if (hasMoreArgs()) {
+ const QString &fileName = nextArg();
+ m_helpFile = getFileName(fileName);
+ if (m_helpFile.isEmpty())
+ m_error = tr("The Qt help file '%1' does not exist.").arg(fileName);
+ else
+ m_register = state;
+ } else {
+ m_error = tr("Missing help file.");
+ }
+}
+
+void CmdLineParser::handleSetCurrentFilterOption()
+{
+ TRACE_OBJ
+ if (hasMoreArgs())
+ m_currentFilter = nextArg();
+ else
+ m_error = tr("Missing filter argument.");
+}
+
+QString CmdLineParser::getFileName(const QString &fileName)
+{
+ TRACE_OBJ
+ QFileInfo fi(fileName);
+ if (!fi.exists())
+ return QString();
+ return fi.absoluteFilePath();
+}
+
+void CmdLineParser::showMessage(const QString &msg, bool error)
+{
+ TRACE_OBJ
+ if (m_quiet)
+ return;
+#ifdef Q_OS_WIN
+ QString message = QLatin1String("<pre>") % msg % QLatin1String("</pre>");
+ if (error)
+ QMessageBox::critical(0, tr("Error"), message);
+ else
+ QMessageBox::information(0, tr("Notice"), message);
+#else
+ fprintf(error ? stderr : stdout, "%s\n", qPrintable(msg));
+#endif
+}
+
+void CmdLineParser::setCollectionFile(const QString &file)
+{
+ TRACE_OBJ
+ m_collectionFile = file;
+}
+
+QString CmdLineParser::collectionFile() const
+{
+ TRACE_OBJ
+ return m_collectionFile;
+}
+
+bool CmdLineParser::collectionFileGiven() const
+{
+ TRACE_OBJ
+ return m_arguments.contains(QLatin1String("-collectionfile"),
+ Qt::CaseInsensitive);
+}
+
+QUrl CmdLineParser::url() const
+{
+ TRACE_OBJ
+ return m_url;
+}
+
+bool CmdLineParser::enableRemoteControl() const
+{
+ TRACE_OBJ
+ return m_enableRemoteControl;
+}
+
+CmdLineParser::ShowState CmdLineParser::contents() const
+{
+ TRACE_OBJ
+ return m_contents;
+}
+
+CmdLineParser::ShowState CmdLineParser::index() const
+{
+ TRACE_OBJ
+ return m_index;
+}
+
+CmdLineParser::ShowState CmdLineParser::bookmarks() const
+{
+ TRACE_OBJ
+ return m_bookmarks;
+}
+
+CmdLineParser::ShowState CmdLineParser::search() const
+{
+ TRACE_OBJ
+ return m_search;
+}
+
+QString CmdLineParser::currentFilter() const
+{
+ TRACE_OBJ
+ return m_currentFilter;
+}
+
+bool CmdLineParser::removeSearchIndex() const
+{
+ TRACE_OBJ
+ return m_removeSearchIndex;
+}
+
+bool CmdLineParser::rebuildSearchIndex() const
+{
+ TRACE_OBJ
+ return m_rebuildSearchIndex;
+}
+
+CmdLineParser::RegisterState CmdLineParser::registerRequest() const
+{
+ TRACE_OBJ
+ return m_register;
+}
+
+QString CmdLineParser::helpFile() const
+{
+ TRACE_OBJ
+ return m_helpFile;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/cmdlineparser.h b/src/assistant/tools/assistant/cmdlineparser.h
new file mode 100644
index 000000000..f45679f66
--- /dev/null
+++ b/src/assistant/tools/assistant/cmdlineparser.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CMDLINEPARSER_H
+#define CMDLINEPARSER_H
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QStringList>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+class CmdLineParser
+{
+ Q_DECLARE_TR_FUNCTIONS(CmdLineParser)
+public:
+ enum Result {Ok, Help, Error};
+ enum ShowState {Untouched, Show, Hide, Activate};
+ enum RegisterState {None, Register, Unregister};
+
+ CmdLineParser(const QStringList &arguments);
+ Result parse();
+
+ void setCollectionFile(const QString &file);
+ QString collectionFile() const;
+ bool collectionFileGiven() const;
+ QString cloneFile() const;
+ QUrl url() const;
+ bool enableRemoteControl() const;
+ ShowState contents() const;
+ ShowState index() const;
+ ShowState bookmarks() const;
+ ShowState search() const;
+ QString currentFilter() const;
+ bool removeSearchIndex() const;
+ bool rebuildSearchIndex() const;
+ RegisterState registerRequest() const;
+ QString helpFile() const;
+
+ void showMessage(const QString &msg, bool error);
+
+private:
+ QString getFileName(const QString &fileName);
+ bool hasMoreArgs() const;
+ const QString &nextArg();
+ void handleCollectionFileOption();
+ void handleShowUrlOption();
+ void handleShowOption();
+ void handleHideOption();
+ void handleActivateOption();
+ void handleShowOrHideOrActivateOption(ShowState state);
+ void handleRegisterOption();
+ void handleUnregisterOption();
+ void handleRegisterOrUnregisterOption(RegisterState state);
+ void handleSetCurrentFilterOption();
+
+ QStringList m_arguments;
+ int m_pos;
+ QString m_collectionFile;
+ QString m_cloneFile;
+ QString m_helpFile;
+ QUrl m_url;
+ bool m_enableRemoteControl;
+
+ ShowState m_contents;
+ ShowState m_index;
+ ShowState m_bookmarks;
+ ShowState m_search;
+ RegisterState m_register;
+ QString m_currentFilter;
+ bool m_removeSearchIndex;
+ bool m_rebuildSearchIndex;
+ bool m_quiet;
+ QString m_error;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/assistant/contentwindow.cpp b/src/assistant/tools/assistant/contentwindow.cpp
new file mode 100644
index 000000000..fbf70aa1f
--- /dev/null
+++ b/src/assistant/tools/assistant/contentwindow.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "contentwindow.h"
+
+#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "helpviewer.h"
+#include "openpagesmanager.h"
+#include "tracer.h"
+
+#include <QtGui/QLayout>
+#include <QtGui/QFocusEvent>
+#include <QtGui/QMenu>
+
+#include <QtHelp/QHelpContentWidget>
+
+QT_BEGIN_NAMESPACE
+
+ContentWindow::ContentWindow()
+ : m_contentWidget(HelpEngineWrapper::instance().contentWidget())
+ , m_expandDepth(-2)
+{
+ TRACE_OBJ
+ m_contentWidget->viewport()->installEventFilter(this);
+ m_contentWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(4);
+ layout->addWidget(m_contentWidget);
+
+ connect(m_contentWidget, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(showContextMenu(QPoint)));
+ connect(m_contentWidget, SIGNAL(linkActivated(QUrl)), this,
+ SIGNAL(linkActivated(QUrl)));
+
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(m_contentWidget->model());
+ connect(contentModel, SIGNAL(contentsCreated()), this, SLOT(expandTOC()));
+}
+
+ContentWindow::~ContentWindow()
+{
+ TRACE_OBJ
+}
+
+bool ContentWindow::syncToContent(const QUrl& url)
+{
+ TRACE_OBJ
+ QModelIndex idx = m_contentWidget->indexOf(url);
+ if (!idx.isValid())
+ return false;
+ m_contentWidget->setCurrentIndex(idx);
+ return true;
+}
+
+void ContentWindow::expandTOC()
+{
+ TRACE_OBJ
+ Q_ASSERT(m_expandDepth >= -2);
+ if (m_expandDepth > -2) {
+ expandToDepth(m_expandDepth);
+ m_expandDepth = -2;
+ }
+}
+
+void ContentWindow::expandToDepth(int depth)
+{
+ TRACE_OBJ
+ Q_ASSERT(depth >= -2);
+ m_expandDepth = depth;
+ if (depth == -1)
+ m_contentWidget->expandAll();
+ else if (depth == 0)
+ m_contentWidget->collapseAll();
+ else
+ m_contentWidget->expandToDepth(depth - 1);
+}
+
+void ContentWindow::focusInEvent(QFocusEvent *e)
+{
+ TRACE_OBJ
+ if (e->reason() != Qt::MouseFocusReason)
+ m_contentWidget->setFocus();
+}
+
+void ContentWindow::keyPressEvent(QKeyEvent *e)
+{
+ TRACE_OBJ
+ if (e->key() == Qt::Key_Escape)
+ emit escapePressed();
+}
+
+bool ContentWindow::eventFilter(QObject *o, QEvent *e)
+{
+ TRACE_OBJ
+ if (m_contentWidget && o == m_contentWidget->viewport()
+ && e->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ const QModelIndex &index = m_contentWidget->indexAt(me->pos());
+ if (!index.isValid())
+ return QWidget::eventFilter(o, e);
+
+ const Qt::MouseButtons button = me->button();
+ QItemSelectionModel *sm = m_contentWidget->selectionModel();
+ if (sm->isSelected(index)) {
+ if ((button == Qt::LeftButton && (me->modifiers() & Qt::ControlModifier))
+ || (button == Qt::MidButton)) {
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(m_contentWidget->model());
+ if (contentModel) {
+ QHelpContentItem *itm = contentModel->contentItemAt(index);
+ if (itm && HelpViewer::canOpenPage(itm->url().path()))
+ OpenPagesManager::instance()->createPage(itm->url());
+ }
+ } else if (button == Qt::LeftButton) {
+ itemClicked(index);
+ }
+ }
+ }
+ return QWidget::eventFilter(o, e);
+}
+
+
+void ContentWindow::showContextMenu(const QPoint &pos)
+{
+ TRACE_OBJ
+ if (!m_contentWidget->indexAt(pos).isValid())
+ return;
+
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(m_contentWidget->model());
+ QHelpContentItem *itm =
+ contentModel->contentItemAt(m_contentWidget->currentIndex());
+
+ QMenu menu;
+ QAction *curTab = menu.addAction(tr("Open Link"));
+ QAction *newTab = menu.addAction(tr("Open Link in New Tab"));
+ if (!HelpViewer::canOpenPage(itm->url().path()))
+ newTab->setEnabled(false);
+
+ menu.move(m_contentWidget->mapToGlobal(pos));
+
+ QAction *action = menu.exec();
+ if (curTab == action)
+ emit linkActivated(itm->url());
+ else if (newTab == action)
+ OpenPagesManager::instance()->createPage(itm->url());
+}
+
+void ContentWindow::itemClicked(const QModelIndex &index)
+{
+ TRACE_OBJ
+ QHelpContentModel *contentModel =
+ qobject_cast<QHelpContentModel*>(m_contentWidget->model());
+
+ if (contentModel) {
+ if (QHelpContentItem *itm = contentModel->contentItemAt(index)) {
+ const QUrl &url = itm->url();
+ if (url != CentralWidget::instance()->currentSource())
+ emit linkActivated(url);
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/contentwindow.h b/src/assistant/tools/assistant/contentwindow.h
new file mode 100644
index 000000000..b8bdc8fee
--- /dev/null
+++ b/src/assistant/tools/assistant/contentwindow.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONTENTWINDOW_H
+#define CONTENTWINDOW_H
+
+#include <QtCore/QUrl>
+#include <QtCore/QModelIndex>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpEngine;
+class QHelpContentItem;
+class QHelpContentWidget;
+
+class ContentWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ContentWindow();
+ ~ContentWindow();
+
+ bool syncToContent(const QUrl &url);
+ void expandToDepth(int depth);
+
+signals:
+ void linkActivated(const QUrl &link);
+ void escapePressed();
+
+private slots:
+ void showContextMenu(const QPoint &pos);
+ void expandTOC();
+ void itemClicked(const QModelIndex &index);
+
+private:
+ void focusInEvent(QFocusEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ bool eventFilter(QObject *o, QEvent *e);
+
+ QHelpContentWidget * const m_contentWidget;
+ int m_expandDepth;
+};
+
+QT_END_NAMESPACE
+
+#endif // CONTENTWINDOW_H
diff --git a/src/assistant/tools/assistant/doc/HOWTO b/src/assistant/tools/assistant/doc/HOWTO
new file mode 100644
index 000000000..a0143479e
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/HOWTO
@@ -0,0 +1,16 @@
+How to build/ update a new assistant.qch for Assistant internal help
+
+- update:
+ - open assistant.qdocconf, update year and qt version
+
+ - ..\..\..\..\qdoc3\debug\qdoc3.exe assistant.qdocconf
+ will generate an folder html containing all required stuff
+
+ - cp assistant.qhp to generated html folder
+ - run qhelpgenerator html\assistant.qhp -o ..\assistant.qch
+
+ - rebuild assistant
+
+- to test your changes:
+ - remove assistant.qch in your cache directory
+ - restart assistant
diff --git a/src/assistant/tools/assistant/doc/assistant.qdoc b/src/assistant/tools/assistant/doc/assistant.qdoc
new file mode 100644
index 000000000..8bd7432ec
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/assistant.qdoc
@@ -0,0 +1,461 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page assistant.html
+ \title Qt Assistant
+
+ \chapter Introduction
+
+ This document introduces \e{Qt Assistant}, a tool for presenting on-line
+ documentation. It also introduces the Qt Reference Documentation which
+ is accessible using \e{Qt Assistant}, or with a web browser. The document is
+ divided into the following sections:
+
+ Table of contents:
+
+ \list
+ \o \l{Introduction}
+ \o \l{The One-Minute Guide to Using Qt Assistant}
+ \o \l{Introduction to the Qt Reference Documentation}
+ \o \l{Qt Assistant in More Detail}
+ \o \l{Full Text Searching}
+ \endlist
+
+ \chapter The One-Minute Guide to Using Qt Assistant
+
+ Once you have installed Qt, \QA should be ready to run:
+
+ \list
+ \o On Windows, \QA is available as a menu option on the Qt menu.
+ \o On Mac OS X, \QA is installed in the /Developer/Applications/Qt directory.
+ \o On Unix/Linux, open a terminal, type \c{assistant} and press \key{Enter}.
+ \endlist
+
+ When you start up \QA, you will be presented with a standard main window
+ application, with a menu bar and toolbar. Below these, on the left hand
+ side are navigation windows called \e{Contents}, \e{Index} and \e{Bookmarks}.
+ On the right, taking up most of the space, is the \e{Documentation} window.
+ By default, \QA loads the Qt reference documentation along with the manuals
+ of other Qt tools, like \QD or \QL.
+
+ \QA works in a similar way to a Web browser. If you click hyperlinks
+ (cross-references), the \e{Documentation} window will present the relevant
+ page. You can bookmark pages of particular interest and you can click the
+ \gui{Previous} and \gui{Next} toolbar buttons to navigate within the pages
+ you have visited.
+
+ Although \QA can be used just like a Web browser to navigate through
+ the documentation, \QA offers a powerful means of navigation that Web
+ browsers do not provide. \QA uses an advanced full text search engine
+ to index all the pages in each compressed help file so that you can
+ search for particular words and phrases.
+
+ To perform an index search, click the \gui{Index} tab on the Sidebar
+ (or press \key{Alt+I}). In the \gui{'Look For'} line edit enter a word;
+ e.g., 'homedirpath'. As you type, words are found and highlighted in a list
+ beneath the line edit. If the highlighted text matches what you're
+ looking for, double click it, (or press \key{Enter}) and the
+ \e{Documentation} window will display the relevant page. You rarely have
+ to type in the whole word before \QA finds a match. Note that for some
+ words there may be more than one possible page that is relevant.
+
+ \QA also provides full text searching for finding specific words in
+ the documentation. To activate the full text search, either press \key(Alt+S)
+ or click on the \gui{Search} tab in the \e{Documentation} window. Then
+ enter the term you're looking for and hit the \gui{Search} button. All
+ documents containing the specified term will then be listed in the list box
+ below.
+
+ \chapter Introduction to the Qt Reference Documentation
+
+ The documentation for the Qt library is written in-line in the \c
+ .cpp files by the developers themselves. The documentation team
+ revises the documentation to ensure that it is accurate and usable,
+ and to provide quality control. The documentation team also writes the
+ larger texts, such as the class descriptions that introduce a class
+ along with the concepts the class uses, as well as introducing the
+ functions and properties that the class provides.
+
+ The documentation focuses on the API rather than the internals, since
+ we make great efforts to keep our API consistent and compatible with
+ each new version, but we may change the internals considerably to improve
+ performance and enhance functionality.
+
+ The Qt Reference Documentation consists of almost 1,500 HTML pages
+ (over 2,500 printed pages). The overwhelming majority of pages
+ document Qt classes. Since developers differ in the way they
+ think and work we provide a variety of approaches to navigating the
+ documentation set:
+
+ \list
+ \i The \menu{Qt's Classes} page lists every class
+ in Qt's public API, and consists of several hundred classes.
+ \i The \menu{Qt's Main Classes} page lists the
+ classes you're most likely to use most often, and provides a much
+ shorter and more managable list than the All Classes list.
+ \i The \menu{Grouped Classes} page presents a list
+ of groups, each of which leads to a list of related classes, for
+ example, the \menu{Advanced Widgets} list.
+ \i The \menu{Class Inheritance Hierarchy} page
+ presents a list of classes in terms of the hierarchy of Qt classes.
+ \i The \menu{Member Function Index} page lists all the
+ functions provided by Qt classes, each one with links to the class(es)
+ in which it appears.
+ \endlist
+
+ No matter where you find yourself in the Qt documentation, you will
+ find extensive cross-referencing. Even snippets of example code
+ contain clickable links, so that for example, if you come across a
+ class declaration in a code example, the class name will be a
+ clickable link to the class's documentation.
+
+ In addition to the class documentation some of Qt's modules have
+ extensive descriptions, and there are many overview documents which
+ describe various aspects of the Qt library; all these are linked from
+ the reference documentation home page. There are also two tutorials
+ and numerous example programs in the examples subdirectory of the Qt
+ distribution.
+
+ \chapter Qt Assistant in More Detail
+
+ \img assistant-assistant.png
+
+ \section1 Command Line Options
+
+ \QA handles the following command line options:
+
+ \table
+ \header
+ \o Command Line Option
+ \o Brief Description
+ \row
+ \o -collectionFile <file.qhc>
+ \o Uses the specified collection file instead of the default one.
+ \row
+ \o -showUrl URL
+ \o Shows the document referenced by URL.
+ \row
+ \o -enableRemoteControl
+ \o Enables \QA to be remotly controlled.
+ \row
+ \o -show <widget>
+ \o Shows the specified dockwidget which can be "contents", "index",
+ "bookmarks" or "search".
+ \row
+ \o -hide <widget>
+ \o Hides the specified dockwidget which can be "contents", "index",
+ "bookmarks" or "search.
+ \row
+ \o -activate <widget>
+ \o Activates the specified dockwidget which can be "contents",
+ "index", "bookmarks" or "search.
+ \row
+ \o -register <doc.qch>
+ \o Registers the specified compressed help file in the given help
+ collection.
+ \row
+ \o -unregister <doc.qch>
+ \o Unregisters the specified compressed help file from the given
+ collection file.
+ \row
+ \o -quiet
+ \o Doesn't show any error, warning or success messages.
+ \endtable
+
+ \section1 Tool Windows
+
+ \img assistant-dockwidgets.png
+
+ The tool windows provide four ways to navigate the documentation:
+
+ \list
+ \o The \gui{Contents} window presents a table of contents implemented as a
+ tree view for the documentation that is available. If you click an item,
+ its documentation will appear in the \e{Documentation} window. If you double
+ click an item or click on the control to the left of it, the item's sub-items
+ will appear. Click a sub-item to make its page appear in the \e{Documentation}
+ window. Click on the control next to an open item to hide its sub-items.
+ \o The \gui{Index} window is used to look up key words or phrases.
+ See \l{The One-Minute Guide to Using Qt Assistant} for how to use this
+ window.
+ \o The \gui{Bookmarks} window lists any bookmarks you have made. Double
+ click a bookmark to make its page appear in the \e{Documentation} window.
+ The \gui{Bookmarks} window provides a context menu with \gui{Show Item},
+ \gui{Delete Item} as well as \gui{Rename Item}. Click in the main menu
+ \menu{Bookmark|Add Bookmark...} (or press \key{Ctrl+B}) to bookmark the
+ page that is currently showing in the \e{Documentation} window. Right click
+ a bookmark in the list to rename or delete the highlighted bookmark.
+ \endlist
+
+ If you want the \gui{Documentation} window to use as much space as possible,
+ you can easily group, move or hide the tool windows. To group the windows,
+ drag one on top of the other and release the mouse. If one or all tool
+ windows are not shown, press \key{Alt+C}, \key{Alt+I} or \key{Alt+O} to show
+ the required window.
+
+ The tool windows can be docked into the main window, so you can drag them
+ to the top, left, right or bottom of \e{Qt Assistant's} window, or you can
+ drag them outside \QA to float them as independent windows.
+
+ \section1 Documentation Window
+
+ \img assistant-docwindow.png
+
+ The \gui{Documentation} window lets you create a tab for each
+ documentation page that you view. Click the \gui{Add Tab} button and a new
+ tab will appear with the page name as the tab's caption. This makes it
+ convenient to switch between pages when you are working with different
+ documentation. You can delete a tab by clicking the \gui{Close Tab} button
+ located on the right side of the \gui{Documentation} window.
+
+ \section1 Toolbars
+
+ \img assistant-toolbar.png
+
+ The main toolbar provides fast access to the most common actions.
+
+ \table
+ \header \o Action \o Description \o Menu Item \o Shortcut
+ \row \o \gui{Previous} \o Takes you to the previous page in the history.
+ \o \menu{Go|Previous} \o \key{Alt+Left Arrow}
+ \row \o \gui{Next} \o Takes you to the next page in the history.
+ \o \menu{Go|Next} \o \key{Alt+Right Arrow}
+ \row \o \gui{Home}
+ \o Takes you to the home page as specified in the Preferences Dialog.
+ \o \menu{Go|Home} \o \key{Ctrl+Home}.
+ \row \o \gui{Sync with Table of Contents}
+ \o Synchronizes the \gui{Contents} tool window with the page currently
+ shown in the \gui{Documentation} window.
+ \o \menu{Go|Sync with Table of Contents} \o
+ \row \o \gui{Copy} \o Copies any selected text to the clipboard.
+ \o \menu{Edit|Copy} \o \key{Ctrl+C}
+ \row \o \gui{Print} \o Opens the \gui{Print} dialog.
+ \o \menu{File|Print} \o \key{Ctrl+P}
+ \row \o \gui{Find in Text} \o Opens the \gui{Find Text} dialog.
+ \o \menu{Edit|Find in Text} \o \key{Ctrl+F}
+ \row \o \gui{Zoom in}
+ \o Increases the font size used to display text in the current tab.
+ \o \menu{View|Zoom in} \o \key{Ctrl++}
+ \row \o \gui{Zoom out}
+ \o Decreases the font size used to display text in the current tab.
+ \o \menu{View|Zoom out} \o \key{Ctrl+-}
+ \row \o \gui{Normal Size}
+ \o Resets the font size to its normal size in the current tab.
+ \o \menu{View|Normal Size} \o \key{Ctrl+0}
+ \endtable
+
+ \img assistant-address-toolbar.png
+
+ The address toolbar provides a fast way to enter a specific URL for a
+ documentation file. By default, the address toolbar is not shown, so it
+ has to be activated via \menu{View|Toolbars|Address Toolbar}.
+
+ \img assistant-filter-toolbar.png
+
+ The filter toolbar allows you to apply a filter to the currently installed
+ documentation. As with the address toolbar, the filter toolbar is not visible
+ by default and has to be activated via \menu{View|Toolbars|Filter Toolbar}.
+
+ \section1 Menus
+
+ \section2 File Menu
+
+ \list
+ \o \menu{File|Page Setup...} invokes a dialog allowing you to define
+ page layout properties, such as margin sizes, page orientation and paper size.
+ \o \menu{File|Print Preview...} provides a preview of the printed pages.
+ \o \menu{File|Print...} opens the \l{#Print Dialog}{\gui{Print} dialog}.
+ \o \menu{File|New Tab} opens a new empty tab in the \gui{Documentation}
+ window.
+ \o \menu{File|Close Tab} closes the current tab of the
+ \gui{Documentation} window.
+ \o \menu{File|Exit} closes the \QA application.
+ \endlist
+
+ \section2 Edit Menu
+
+ \list
+ \o \menu{Edit|Copy} copies any selected text to the clipboard.
+ \o \menu{Edit|Find in Text} invokes the \l{#Find Text Control}{\gui{Find Text}
+ control} at the lower end of the \gui{Documentation} window.
+ \o \menu{Edit|Find Next} looks for the next occurance of the specified
+ text in the \gui{Find Text} control.
+ \o \menu{Edit|Find Previous} looks for the previous occurance of
+ the specified text in the \l{#Find Text Control}{\gui{Find Text} control}.
+ \o \menu{Edit|Preferences} invokes the \l{#Preferences Dialog}{\gui{Preferences} dialog}.
+ \endlist
+
+ \section2 View Menu
+
+ \list
+ \o \menu{View|Zoom in} increases the font size in the current tab.
+ \o \menu{View|Zoom out} decreases the font size in the current tab.
+ \o \menu{View|Normal Size} resets the font size in the current tab.
+ \o \menu{View|Contents} toggles the display of the \gui{Contents} tool window.
+ \o \menu{View|Index} toggles the display of the \gui{Index} tool window.
+ \o \menu{View|Bookmarks} toggles the display of the \gui{Bookmarks} tool window.
+ \o \menu{View|Search} toggles the display of the Search in the \gui{Documentation} window.
+ \endlist
+
+ \section2 Go Menu
+
+ \list
+ \o \menu{Go|Home} goes to the home page.
+ \o \menu{Go|Back} displays the previous page in the history.
+ \o \menu{Go|Forward} displays the next page in the history.
+ \o \menu{Go|Sync with Table of Contents} syncs the \gui{Contents} tool window to the currently shown page.
+ \o \menu{Go|Next Page} selects the next tab in the \gui{Documentation} window.
+ \o \menu{Go|Previous Page} selects the previous tab in the \gui{Documentation} window.
+ \endlist
+
+ \section2 Bookmarks Menu
+
+ \list
+ \o \menu{Bookmarks|Add} adds the current page to the list of bookmarks.
+ \endlist
+
+ \section1 Dialogs
+
+ \section2 Print Dialog
+
+ This dialog is platform-specific. It gives access to various printer
+ options and can be used to print the document shown in the current tab.
+
+ \section2 Preferences Dialog
+
+ \img assistant-preferences-fonts.png
+
+ The \menu{Fonts} page allows you to change the font family and font sizes of the
+ browser window displaying the documentation or the application itself.
+
+ \img assistant-preferences-filters.png
+
+ The \menu{Filters} page lets you create and remove documentation
+ filters. To add a new filter, click the \gui{Add} button, specify a
+ filter name in the pop-up dialog and click \gui{OK}, then select
+ the filter attributes in the list box on the right hand side.
+ You can delete a filter by selecting it and clicking the \gui{Remove}
+ button.
+
+ \img assistant-preferences-documentation.png
+
+ The \menu{Documentation} page lets you install and remove compressed help
+ files. Click the \gui{Install} button and choose the path of the compressed
+ help file (*.qch) you would like to install.
+ To delete a help file, select a documentation set in the list and click
+ \gui{Remove}.
+
+ \img assistant-preferences-options.png
+
+ The \menu{Options} page lets you specify the homepage \QA will display when
+ you click the \gui{Home} button in \QA's main user interface. You can specify
+ the hompage by typing it here or clicking on one of the buttons below the
+ textbox. \gui{Current Page} sets the currently displayed page as your home
+ page while \gui{Restore to default} will reset your home page to the default
+ home page.
+
+ \section1 Find Text Control
+
+ This control is used to find text in the current page. Enter the text you want
+ to find in the line edit. The search is incremental, meaning that the most
+ relevant result is shown as you enter characters into the line edit.
+
+ If you check the \gui{Whole words only} checkbox, the search will only consider
+ whole words; for example, if you search for "spin" with this checkbox checked it will
+ not match "spinbox", but will match "spin". If you check the \gui{Case sensitive}
+ checkbox then, for example, "spin" will match "spin" but not "Spin". You can
+ search forwards or backwards from your current position in the page by clicking
+ the \gui{Previous} or \gui{Next} buttons. To hide the find control, either click the
+ \gui{Close} button or hit the \key{Esc} key.
+
+ \section1 Filtering Help Contents
+
+ \QA allows you to install any kind of documentation as long as it is organized
+ in Qt compressed help files (*.qch). For example, it is possible to install the
+ Qt reference documentation for Qt 4.4.0 and Qt 4.4.1 at the same time. In many
+ respects, this is very convenient since only one version of \QA is needed.
+ However, at the same time it becomes more complicated when performing tasks like
+ searching the index because nearly every keyword is defined in Qt 4.4.0 as well
+ as in Qt 4.4.1. This means that \QA will always ask the user to choose which one
+ should be displayed.
+
+ We use documentation filters to solve this issue. A filter is identified by its
+ name, and contains a list of filter attributes. An attribute is just a string and
+ can be freely chosen. Attributes are defined by the documentation itself, this
+ means that every documentation set usually has one or more attributes.
+
+ For example, the Qt 4.4.0 \QA documentation defines the attributes \c {assistant},
+ \c{tools} and \c{4.4.0}, \QD defines \c{designer}, \c{tools} and \c{4.4.0}.
+ The filter to display all tools would then define only the attribute
+ \c{tools} since this attribute is part of both documentation sets.
+ Adding the attribute \c{assistant} to the filter would then only show \QA
+ documentation since the \QD documentation does not contain this
+ attribute. Having an empty list of attributes in a filter will match all
+ documentation; i.e., it is equivalent to requesting unfiltered documentation.
+
+ \section1 Full Text Searching
+
+ \img assistant-search.png
+
+ \QA provides a powerful full text search engine. To search
+ for certain words or text, click the \gui{Search} tab in the \gui{Documentation}
+ window. Then enter the text you want to look for and press \key{Enter}
+ or click the \gui{Search} button. The search is not case sensitive, so,
+ for example, Foo, fOo and FOO are all treated as the same. The following are
+ examples of common search patterns:
+
+ \list
+ \o \c deep -- lists all the documents that contain the word 'deep'
+ \o \c{deep*} -- lists all the documents that contain a word beginning
+ with 'deep'
+ \o \c{deep copy} -- lists all documents that contain both 'deep' \e
+ and 'copy'
+ \o \c{"deep copy"} -- list all documents that contain the phrase 'deep copy'
+ \endlist
+
+ It is also possible to use the \gui{Advanced search} to get more flexibility.
+ You can specify some words so that hits containing these are excluded from the
+ result, or you can search for an exact phrase. Searching for similar words will
+ give results like these:
+
+ \list
+ \o \c{QStin} -- lists all the documents with titles that are similar, such as \c{QString}
+ \o \c{QSting} -- lists all the documents with titles that are similar, such as \c{QString}
+ \o \c{QStrin} -- lists all the documents with titles that are similar, such as \c{QString}
+ \endlist
+
+ Options can be combined to improve the search results.
+
+ The list of documents found is ordered according to the number of
+ occurrences of the search text which they contain, with those containing
+ the highest number of occurrences appearing first. Simply click any
+ document in the list to display it in the \gui{Documentation} window.
+
+ If the documentation has changed \mdash for example, if documents have been added
+ or removed \mdash \QA will index them again.
+*/
diff --git a/src/assistant/tools/assistant/doc/assistant.qdocconf b/src/assistant/tools/assistant/doc/assistant.qdocconf
new file mode 100644
index 000000000..4bd3842d6
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/assistant.qdocconf
@@ -0,0 +1,16 @@
+include(../../../../qdoc3/test/qt.qdocconf)
+
+version =
+
+sourcedirs = $QTDIR/tools/assistant/tools/assistant/doc
+imagedirs = $QTDIR/tools/assistant/tools/assistant/doc/images
+outputdir = $QTDIR/tools/assistant/tools/assistant/doc/html
+project = assistant
+description = "Qt Assistant"
+HTML.{postheader,address} = ""
+HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
+ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
+ "<td width=\"30%\" align=\"left\">Copyright &copy; 2011 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \
+ "<td width=\"40%\" align=\"center\">Trademarks</td>\n" \
+ "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt 4.8.0</div></td>\n" \
+ "</tr></table></div></address>"
diff --git a/src/assistant/tools/assistant/doc/assistant.qhp b/src/assistant/tools/assistant/doc/assistant.qhp
new file mode 100644
index 000000000..7ea4cdd46
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/assistant.qhp
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<QtHelpProject version="1.0">
+ <virtualFolder>assistant</virtualFolder>
+ <namespace>com.trolltech.com.assistantinternal-1.0.0</namespace>
+ <filterSection>
+ <files>
+ <file>assistant.html</file>
+ <file>classic.css</file>
+ <file>images/assistant-address-toolbar.png</file>
+ <file>images/assistant-assistant.png</file>
+ <file>images/assistant-dockwidgets.png</file>
+ <file>images/assistant-docwindow.png</file>
+ <file>images/assistant-filter-toolbar.png</file>
+ <file>images/assistant-preferences-documentation.png</file>
+ <file>images/assistant-preferences-filters.png</file>
+ <file>images/assistant-preferences-fonts.png</file>
+ <file>images/assistant-preferences-options.png</file>
+ <file>images/assistant-search.png</file>
+ <file>images/assistant-toolbar.png</file>
+ </files>
+ </filterSection>
+</QtHelpProject>
diff --git a/src/assistant/tools/assistant/doc/classic.css b/src/assistant/tools/assistant/doc/classic.css
new file mode 100644
index 000000000..911354035
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/classic.css
@@ -0,0 +1,92 @@
+h3.fn,span.fn
+{
+ margin-left: 1cm;
+ text-indent: -1cm;
+}
+
+a:link
+{
+ color: #004faf;
+ text-decoration: none
+}
+
+a:visited
+{
+ color: #672967;
+ text-decoration: none
+}
+
+td.postheader
+{
+ font-family: sans-serif
+}
+
+tr.address
+{
+ font-family: sans-serif
+}
+
+body
+{
+ background: #ffffff;
+ color: black
+}
+
+table tr.odd {
+ background: #f0f0f0;
+ color: black;
+}
+
+table tr.even {
+ background: #e4e4e4;
+ color: black;
+}
+
+table.annotated th {
+ padding: 3px;
+ text-align: left
+}
+
+table.annotated td {
+ padding: 3px;
+}
+
+table tr pre
+{
+ padding-top: none;
+ padding-bottom: none;
+ padding-left: none;
+ padding-right: none;
+ border: none;
+ background: none
+}
+
+tr.qt-style
+{
+ background: #a2c511;
+ color: black
+}
+
+body pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+span.preprocessor, span.preprocessor a
+{
+ color: darkblue;
+}
+
+span.comment
+{
+ color: darkred;
+ font-style: italic
+}
+
+span.string,span.char
+{
+ color: darkgreen;
+}
diff --git a/src/assistant/tools/assistant/doc/images/assistant-address-toolbar.png b/src/assistant/tools/assistant/doc/images/assistant-address-toolbar.png
new file mode 100644
index 000000000..847b7debb
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-address-toolbar.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-assistant.png b/src/assistant/tools/assistant/doc/images/assistant-assistant.png
new file mode 100644
index 000000000..1ff5cc976
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-assistant.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-dockwidgets.png b/src/assistant/tools/assistant/doc/images/assistant-dockwidgets.png
new file mode 100644
index 000000000..17bc064c5
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-dockwidgets.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-docwindow.png b/src/assistant/tools/assistant/doc/images/assistant-docwindow.png
new file mode 100644
index 000000000..c5bac581f
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-docwindow.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-examples.png b/src/assistant/tools/assistant/doc/images/assistant-examples.png
new file mode 100644
index 000000000..47c01bcda
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-examples.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-filter-toolbar.png b/src/assistant/tools/assistant/doc/images/assistant-filter-toolbar.png
new file mode 100644
index 000000000..4e89a79b9
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-filter-toolbar.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-preferences-documentation.png b/src/assistant/tools/assistant/doc/images/assistant-preferences-documentation.png
new file mode 100644
index 000000000..790fd9a1a
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-preferences-documentation.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-preferences-filters.png b/src/assistant/tools/assistant/doc/images/assistant-preferences-filters.png
new file mode 100644
index 000000000..7453dd66d
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-preferences-filters.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-preferences-fonts.png b/src/assistant/tools/assistant/doc/images/assistant-preferences-fonts.png
new file mode 100644
index 000000000..d42d190d0
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-preferences-fonts.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-preferences-options.png b/src/assistant/tools/assistant/doc/images/assistant-preferences-options.png
new file mode 100644
index 000000000..d6624151a
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-preferences-options.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-search.png b/src/assistant/tools/assistant/doc/images/assistant-search.png
new file mode 100644
index 000000000..ef75c3329
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-search.png
Binary files differ
diff --git a/src/assistant/tools/assistant/doc/images/assistant-toolbar.png b/src/assistant/tools/assistant/doc/images/assistant-toolbar.png
new file mode 100644
index 000000000..1b41825c6
--- /dev/null
+++ b/src/assistant/tools/assistant/doc/images/assistant-toolbar.png
Binary files differ
diff --git a/src/assistant/tools/assistant/filternamedialog.cpp b/src/assistant/tools/assistant/filternamedialog.cpp
new file mode 100644
index 000000000..1d9563d2f
--- /dev/null
+++ b/src/assistant/tools/assistant/filternamedialog.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include <QtGui/QPushButton>
+
+#include "filternamedialog.h"
+
+QT_BEGIN_NAMESPACE
+
+FilterNameDialog::FilterNameDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ TRACE_OBJ
+ m_ui.setupUi(this);
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Ok),
+ SIGNAL(clicked()), this, SLOT(accept()));
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel),
+ SIGNAL(clicked()), this, SLOT(reject()));
+ connect(m_ui.lineEdit, SIGNAL(textChanged(QString)),
+ this, SLOT(updateOkButton()));
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true);
+
+}
+
+QString FilterNameDialog::filterName() const
+{
+ TRACE_OBJ
+ return m_ui.lineEdit->text();
+}
+
+void FilterNameDialog::updateOkButton()
+{
+ TRACE_OBJ
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)
+ ->setDisabled(m_ui.lineEdit->text().isEmpty());
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/filternamedialog.h b/src/assistant/tools/assistant/filternamedialog.h
new file mode 100644
index 000000000..35575421e
--- /dev/null
+++ b/src/assistant/tools/assistant/filternamedialog.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FILTERNAMEDIALOG_H
+#define FILTERNAMEDIALOG_H
+
+#include <QtGui/QDialog>
+#include "ui_filternamedialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class FilterNameDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ FilterNameDialog(QWidget *parent = 0);
+ QString filterName() const;
+
+private slots:
+ void updateOkButton();
+
+private:
+ Ui::FilterNameDialogClass m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif // FILTERNAMEDIALOG_H
diff --git a/src/assistant/tools/assistant/filternamedialog.ui b/src/assistant/tools/assistant/filternamedialog.ui
new file mode 100644
index 000000000..755a93479
--- /dev/null
+++ b/src/assistant/tools/assistant/filternamedialog.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>FilterNameDialogClass</class>
+ <widget class="QDialog" name="FilterNameDialogClass" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>312</width>
+ <height>95</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Add Filter Name</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Filter Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <widget class="QLineEdit" name="lineEdit" />
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/tools/assistant/findwidget.cpp b/src/assistant/tools/assistant/findwidget.cpp
new file mode 100644
index 000000000..d45ed30b0
--- /dev/null
+++ b/src/assistant/tools/assistant/findwidget.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+#include "findwidget.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QCheckBox>
+#include <QtGui/QHideEvent>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+FindWidget::FindWidget(QWidget *parent)
+ : QWidget(parent)
+ , appPalette(qApp->palette())
+{
+ TRACE_OBJ
+ installEventFilter(this);
+ QHBoxLayout *hboxLayout = new QHBoxLayout(this);
+ QString resourcePath = QLatin1String(":/trolltech/assistant/images/");
+
+#ifndef Q_OS_MAC
+ hboxLayout->setMargin(0);
+ hboxLayout->setSpacing(6);
+ resourcePath.append(QLatin1String("win"));
+#else
+ resourcePath.append(QLatin1String("mac"));
+#endif
+
+ toolClose = setupToolButton(QLatin1String(""),
+ resourcePath + QLatin1String("/closetab.png"));
+ hboxLayout->addWidget(toolClose);
+ connect(toolClose, SIGNAL(clicked()), SLOT(hide()));
+
+ editFind = new QLineEdit(this);
+ hboxLayout->addWidget(editFind);
+ editFind->setMinimumSize(QSize(150, 0));
+ connect(editFind, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+ connect(editFind, SIGNAL(returnPressed()), this, SIGNAL(findNext()));
+ connect(editFind, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
+
+ toolPrevious = setupToolButton(tr("Previous"),
+ resourcePath + QLatin1String("/previous.png"));
+ connect(toolPrevious, SIGNAL(clicked()), this, SIGNAL(findPrevious()));
+
+ hboxLayout->addWidget(toolPrevious);
+
+ toolNext = setupToolButton(tr("Next"),
+ resourcePath + QLatin1String("/next.png"));
+ hboxLayout->addWidget(toolNext);
+ connect(toolNext, SIGNAL(clicked()), this, SIGNAL(findNext()));
+
+ checkCase = new QCheckBox(tr("Case Sensitive"), this);
+ hboxLayout->addWidget(checkCase);
+
+ labelWrapped = new QLabel(this);
+ labelWrapped->setScaledContents(true);
+ labelWrapped->setTextFormat(Qt::RichText);
+ labelWrapped->setMinimumSize(QSize(0, 20));
+ labelWrapped->setMaximumSize(QSize(105, 20));
+ labelWrapped->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
+ labelWrapped->setText(tr("<img src=\":/trolltech/assistant/images/wrap.png\""
+ ">&nbsp;Search wrapped"));
+ hboxLayout->addWidget(labelWrapped);
+
+ QSpacerItem *spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding,
+ QSizePolicy::Minimum);
+ hboxLayout->addItem(spacerItem);
+ setMinimumWidth(minimumSizeHint().width());
+ labelWrapped->hide();
+
+ updateButtons();
+}
+
+FindWidget::~FindWidget()
+{
+ TRACE_OBJ
+}
+
+void FindWidget::show()
+{
+ TRACE_OBJ
+ QWidget::show();
+ editFind->selectAll();
+ editFind->setFocus(Qt::ShortcutFocusReason);
+}
+
+void FindWidget::showAndClear()
+{
+ TRACE_OBJ
+ show();
+ editFind->clear();
+}
+
+QString FindWidget::text() const
+{
+ TRACE_OBJ
+ return editFind->text();
+}
+
+bool FindWidget::caseSensitive() const
+{
+ TRACE_OBJ
+ return checkCase->isChecked();
+}
+
+void FindWidget::setPalette(bool found)
+{
+ TRACE_OBJ
+ QPalette palette = editFind->palette();
+ palette.setColor(QPalette::Active, QPalette::Base, found ? Qt::white
+ : QColor(255, 102, 102));
+ editFind->setPalette(palette);
+}
+
+void FindWidget::setTextWrappedVisible(bool visible)
+{
+ TRACE_OBJ
+ labelWrapped->setVisible(visible);
+}
+
+void FindWidget::hideEvent(QHideEvent* event)
+{
+ TRACE_OBJ
+#if !defined(QT_NO_WEBKIT)
+ // TODO: remove this once webkit supports setting the palette
+ if (!event->spontaneous())
+ qApp->setPalette(appPalette);
+#else
+ Q_UNUSED(event);
+#endif
+}
+
+void FindWidget::showEvent(QShowEvent* event)
+{
+ TRACE_OBJ
+#if !defined(QT_NO_WEBKIT)
+ // TODO: remove this once webkit supports setting the palette
+ if (!event->spontaneous()) {
+ QPalette p = appPalette;
+ p.setColor(QPalette::Inactive, QPalette::Highlight,
+ p.color(QPalette::Active, QPalette::Highlight));
+ p.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ p.color(QPalette::Active, QPalette::HighlightedText));
+ qApp->setPalette(p);
+ }
+#else
+ Q_UNUSED(event);
+#endif
+}
+
+void FindWidget::updateButtons()
+{
+ TRACE_OBJ
+ const bool enable = !editFind->text().isEmpty();
+ toolNext->setEnabled(enable);
+ toolPrevious->setEnabled(enable);
+}
+
+void FindWidget::textChanged(const QString &text)
+{
+ TRACE_OBJ
+ emit find(text, true, true);
+}
+
+bool FindWidget::eventFilter(QObject *object, QEvent *e)
+{
+ TRACE_OBJ
+ if (e->type() == QEvent::KeyPress) {
+ if ((static_cast<QKeyEvent*>(e))->key() == Qt::Key_Escape) {
+ hide();
+ emit escapePressed();
+ }
+ }
+ return QWidget::eventFilter(object, e);
+}
+
+QToolButton* FindWidget::setupToolButton(const QString &text, const QString &icon)
+{
+ TRACE_OBJ
+ QToolButton *toolButton = new QToolButton(this);
+
+ toolButton->setText(text);
+ toolButton->setAutoRaise(true);
+ toolButton->setIcon(QIcon(icon));
+ toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+
+ return toolButton;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/findwidget.h b/src/assistant/tools/assistant/findwidget.h
new file mode 100644
index 000000000..d3be0f587
--- /dev/null
+++ b/src/assistant/tools/assistant/findwidget.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef FINDWIDGET_H
+#define FINDWIDGET_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QCheckBox;
+class QLabel;
+class QLineEdit;
+class QToolButton;
+
+class FindWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ FindWidget(QWidget *parent = 0);
+ ~FindWidget();
+
+ void show();
+ void showAndClear();
+
+ QString text() const;
+ bool caseSensitive() const;
+
+ void setPalette(bool found);
+ void setTextWrappedVisible(bool visible);
+
+signals:
+ void findNext();
+ void findPrevious();
+ void escapePressed();
+ void find(const QString &text, bool forward, bool incremental);
+
+protected:
+ void hideEvent(QHideEvent* event);
+ void showEvent(QShowEvent * event);
+
+private slots:
+ void updateButtons();
+ void textChanged(const QString &text);
+
+private:
+ bool eventFilter(QObject *object, QEvent *e);
+ QToolButton* setupToolButton(const QString &text, const QString &icon);
+
+private:
+ QPalette appPalette;
+
+ QLineEdit *editFind;
+ QCheckBox *checkCase;
+ QLabel *labelWrapped;
+ QToolButton *toolNext;
+ QToolButton *toolClose;
+ QToolButton *toolPrevious;
+};
+
+QT_END_NAMESPACE
+
+#endif // FINDWIDGET_H
diff --git a/src/assistant/tools/assistant/globalactions.cpp b/src/assistant/tools/assistant/globalactions.cpp
new file mode 100644
index 000000000..7fc59ebcd
--- /dev/null
+++ b/src/assistant/tools/assistant/globalactions.cpp
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "globalactions.h"
+
+#include "centralwidget.h"
+#include "helpviewer.h"
+#include "tracer.h"
+
+#include <QtGui/QAction>
+#include <QtGui/QMenu>
+
+#if !defined(QT_NO_WEBKIT)
+#include <QtWebKit/QWebHistory>
+#endif
+
+GlobalActions *GlobalActions::instance(QObject *parent)
+{
+ Q_ASSERT(!m_instance != !parent);
+ if (!m_instance)
+ m_instance = new GlobalActions(parent);
+ return m_instance;
+}
+
+GlobalActions::GlobalActions(QObject *parent) : QObject(parent)
+{
+ TRACE_OBJ
+
+ // TODO: Put resource path in misc class
+ QString resourcePath = QLatin1String(":/trolltech/assistant/images/");
+#ifdef Q_OS_MAC
+ resourcePath.append(QLatin1String("mac"));
+#else
+ resourcePath.append(QLatin1String("win"));
+#endif
+ CentralWidget *centralWidget = CentralWidget::instance();
+
+ m_backAction = new QAction(tr("&Back"), parent);
+ m_backAction->setEnabled(false);
+ m_backAction->setShortcuts(QKeySequence::Back);
+ m_backAction->setIcon(QIcon(resourcePath + QLatin1String("/previous.png")));
+ connect(m_backAction, SIGNAL(triggered()), centralWidget, SLOT(backward()));
+ m_actionList << m_backAction;
+
+ m_nextAction = new QAction(tr("&Forward"), parent);
+ m_nextAction->setPriority(QAction::LowPriority);
+ m_nextAction->setEnabled(false);
+ m_nextAction->setShortcuts(QKeySequence::Forward);
+ m_nextAction->setIcon(QIcon(resourcePath + QLatin1String("/next.png")));
+ connect(m_nextAction, SIGNAL(triggered()), centralWidget, SLOT(forward()));
+ m_actionList << m_nextAction;
+
+ setupNavigationMenus(m_backAction, m_nextAction, centralWidget);
+
+ m_homeAction = new QAction(tr("&Home"), parent);
+ m_homeAction->setShortcut(tr("ALT+Home"));
+ m_homeAction->setIcon(QIcon(resourcePath + QLatin1String("/home.png")));
+ connect(m_homeAction, SIGNAL(triggered()), centralWidget, SLOT(home()));
+ m_actionList << m_homeAction;
+
+ QAction *separator = new QAction(parent);
+ separator->setSeparator(true);
+ m_actionList << separator;
+
+ m_zoomInAction = new QAction(tr("Zoom &in"), parent);
+ m_zoomInAction->setPriority(QAction::LowPriority);
+ m_zoomInAction->setIcon(QIcon(resourcePath + QLatin1String("/zoomin.png")));
+ m_zoomInAction->setShortcut(QKeySequence::ZoomIn);
+ connect(m_zoomInAction, SIGNAL(triggered()), centralWidget, SLOT(zoomIn()));
+ m_actionList << m_zoomInAction;
+
+ m_zoomOutAction = new QAction(tr("Zoom &out"), parent);
+ m_zoomOutAction->setPriority(QAction::LowPriority);
+ m_zoomOutAction->setIcon(QIcon(resourcePath + QLatin1String("/zoomout.png")));
+ m_zoomOutAction->setShortcut(QKeySequence::ZoomOut);
+ connect(m_zoomOutAction, SIGNAL(triggered()), centralWidget, SLOT(zoomOut()));
+ m_actionList << m_zoomOutAction;
+
+ separator = new QAction(parent);
+ separator->setSeparator(true);
+ m_actionList << separator;
+
+ m_copyAction = new QAction(tr("&Copy selected Text"), parent);
+ m_copyAction->setPriority(QAction::LowPriority);
+ m_copyAction->setIconText("&Copy");
+ m_copyAction->setIcon(QIcon(resourcePath + QLatin1String("/editcopy.png")));
+ m_copyAction->setShortcuts(QKeySequence::Copy);
+ m_copyAction->setEnabled(false);
+ connect(m_copyAction, SIGNAL(triggered()), centralWidget, SLOT(copy()));
+ m_actionList << m_copyAction;
+
+ m_printAction = new QAction(tr("&Print..."), parent);
+ m_printAction->setPriority(QAction::LowPriority);
+ m_printAction->setIcon(QIcon(resourcePath + QLatin1String("/print.png")));
+ m_printAction->setShortcut(QKeySequence::Print);
+ connect(m_printAction, SIGNAL(triggered()), centralWidget, SLOT(print()));
+ m_actionList << m_printAction;
+
+ m_findAction = new QAction(tr("&Find in Text..."), parent);
+ m_findAction->setIconText(tr("&Find"));
+ m_findAction->setIcon(QIcon(resourcePath + QLatin1String("/find.png")));
+ m_findAction->setShortcuts(QKeySequence::Find);
+ connect(m_findAction, SIGNAL(triggered()), centralWidget, SLOT(showTextSearch()));
+ m_actionList << m_findAction;
+
+#ifdef Q_WS_X11
+ m_backAction->setIcon(QIcon::fromTheme("go-previous" , m_backAction->icon()));
+ m_nextAction->setIcon(QIcon::fromTheme("go-next" , m_nextAction->icon()));
+ m_zoomInAction->setIcon(QIcon::fromTheme("zoom-in" , m_zoomInAction->icon()));
+ m_zoomOutAction->setIcon(QIcon::fromTheme("zoom-out" , m_zoomOutAction->icon()));
+ m_copyAction->setIcon(QIcon::fromTheme("edit-copy" , m_copyAction->icon()));
+ m_findAction->setIcon(QIcon::fromTheme("edit-find" , m_findAction->icon()));
+ m_homeAction->setIcon(QIcon::fromTheme("go-home" , m_homeAction->icon()));
+ m_printAction->setIcon(QIcon::fromTheme("document-print" , m_printAction->icon()));
+#endif
+}
+
+void GlobalActions::updateActions()
+{
+ TRACE_OBJ
+ CentralWidget *centralWidget = CentralWidget::instance();
+ m_copyAction->setEnabled(centralWidget->hasSelection());
+ m_nextAction->setEnabled(centralWidget->isForwardAvailable());
+ m_backAction->setEnabled(centralWidget->isBackwardAvailable());
+}
+
+void GlobalActions::setCopyAvailable(bool available)
+{
+ TRACE_OBJ
+ m_copyAction->setEnabled(available);
+}
+
+#if !defined(QT_NO_WEBKIT)
+
+void GlobalActions::slotAboutToShowBackMenu()
+{
+ TRACE_OBJ
+ m_backMenu->clear();
+ if (QWebHistory *history = CentralWidget::instance()->currentHelpViewer()->history()) {
+ const int currentItemIndex = history->currentItemIndex();
+ QList<QWebHistoryItem> items = history->backItems(history->count());
+ for (int i = items.count() - 1; i >= 0; --i) {
+ QAction *action = new QAction(this);
+ action->setText(items.at(i).title());
+ action->setData(-1 * (currentItemIndex - i));
+ m_backMenu->addAction(action);
+ }
+ }
+}
+
+void GlobalActions::slotAboutToShowNextMenu()
+{
+ TRACE_OBJ
+ m_nextMenu->clear();
+ if (QWebHistory *history = CentralWidget::instance()->currentHelpViewer()->history()) {
+ const int count = history->count();
+ QList<QWebHistoryItem> items = history->forwardItems(count);
+ for (int i = 0; i < items.count(); ++i) {
+ QAction *action = new QAction(this);
+ action->setData(count - i);
+ action->setText(items.at(i).title());
+ m_nextMenu->addAction(action);
+ }
+ }
+}
+
+void GlobalActions::slotOpenActionUrl(QAction *action)
+{
+ TRACE_OBJ
+ if (HelpViewer* viewer = CentralWidget::instance()->currentHelpViewer()) {
+ const int offset = action->data().toInt();
+ QWebHistory *history = viewer->history();
+ if (offset > 0) {
+ history->goToItem(history->forwardItems(history->count()
+ - offset + 1).back()); // forward
+ } else if (offset < 0) {
+ history->goToItem(history->backItems(-1 * offset).first()); // back
+ }
+ }
+}
+
+#endif
+
+void GlobalActions::setupNavigationMenus(QAction *back, QAction *next,
+ QWidget *parent)
+{
+#if !defined(QT_NO_WEBKIT)
+ m_backMenu = new QMenu(parent);
+ connect(m_backMenu, SIGNAL(aboutToShow()), this,
+ SLOT(slotAboutToShowBackMenu()));
+ connect(m_backMenu, SIGNAL(triggered(QAction*)), this,
+ SLOT(slotOpenActionUrl(QAction*)));
+ back->setMenu(m_backMenu);
+
+ m_nextMenu = new QMenu(parent);
+ connect(m_nextMenu, SIGNAL(aboutToShow()), this,
+ SLOT(slotAboutToShowNextMenu()));
+ connect(m_nextMenu, SIGNAL(triggered(QAction*)), this,
+ SLOT(slotOpenActionUrl(QAction*)));
+ next->setMenu(m_nextMenu);
+#else
+ Q_UNUSED(back)
+ Q_UNUSED(next)
+ Q_UNUSED(parent)
+#endif
+}
+
+GlobalActions *GlobalActions::m_instance = 0;
diff --git a/src/assistant/tools/assistant/globalactions.h b/src/assistant/tools/assistant/globalactions.h
new file mode 100644
index 000000000..a9059a9a4
--- /dev/null
+++ b/src/assistant/tools/assistant/globalactions.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLOBALACTION_H
+#define GLOBALACTION_H
+
+#include <QtCore/QList>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QMenu;
+
+class GlobalActions : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(GlobalActions)
+public:
+ static GlobalActions *instance(QObject *parent = 0);
+
+ QList<QAction *> actionList() const { return m_actionList; }
+ QAction *backAction() const { return m_backAction; }
+ QAction *nextAction() const { return m_nextAction; }
+ QAction *homeAction() const { return m_homeAction; }
+ QAction *zoomInAction() const { return m_zoomInAction; }
+ QAction *zoomOutAction() const { return m_zoomOutAction; }
+ QAction *copyAction() const { return m_copyAction; }
+ QAction *printAction() const { return m_printAction; }
+ QAction *findAction() const { return m_findAction; }
+
+ Q_SLOT void updateActions();
+ Q_SLOT void setCopyAvailable(bool available);
+
+#if !defined(QT_NO_WEBKIT)
+private slots:
+ void slotAboutToShowBackMenu();
+ void slotAboutToShowNextMenu();
+ void slotOpenActionUrl(QAction *action);
+#endif
+
+private:
+ void setupNavigationMenus(QAction *back, QAction *next, QWidget *parent);
+
+private:
+ GlobalActions(QObject *parent);
+
+ static GlobalActions *m_instance;
+
+ QAction *m_backAction;
+ QAction *m_nextAction;
+ QAction *m_homeAction;
+ QAction *m_zoomInAction;
+ QAction *m_zoomOutAction;
+ QAction *m_copyAction;
+ QAction *m_printAction;
+ QAction *m_findAction;
+
+ QList<QAction *> m_actionList;
+
+ QMenu *m_backMenu;
+ QMenu *m_nextMenu;
+};
+
+QT_END_NAMESPACE
+
+#endif // GLOBALACTION_H
diff --git a/src/assistant/tools/assistant/helpenginewrapper.cpp b/src/assistant/tools/assistant/helpenginewrapper.cpp
new file mode 100644
index 000000000..4c7ff5b30
--- /dev/null
+++ b/src/assistant/tools/assistant/helpenginewrapper.cpp
@@ -0,0 +1,844 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include "helpenginewrapper.h"
+#include "../shared/collectionconfiguration.h"
+
+#include <QtCore/QDateTime>
+#include <QtCore/QFileInfo>
+#include <QtCore/QFileSystemWatcher>
+#include <QtCore/QPair>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QTimer>
+#include <QtHelp/QHelpContentModel>
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpIndexModel>
+#include <QtHelp/QHelpSearchEngine>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ const QString Unfiltered;
+ const QString AppFontKey(QLatin1String("appFont"));
+ const QString AppWritingSystemKey(QLatin1String("appWritingSystem"));
+ const QString BookmarksKey(QLatin1String("Bookmarks"));
+ const QString BrowserFontKey(QLatin1String("browserFont"));
+ const QString BrowserWritingSystemKey(QLatin1String("browserWritingSystem"));
+ const QString HomePageKey(QLatin1String("homepage"));
+ const QString MainWindowKey(QLatin1String("MainWindow"));
+ const QString MainWindowGeometryKey(QLatin1String("MainWindowGeometry"));
+ const QString SearchWasAttachedKey(QLatin1String("SearchWasAttached"));
+ const QString StartOptionKey(QLatin1String("StartOption"));
+ const QString UseAppFontKey(QLatin1String("useAppFont"));
+ const QString UseBrowserFontKey(QLatin1String("useBrowserFont"));
+ const QString VersionKey(QString(QLatin1String("qtVersion%1$$$%2")).
+ arg(QLatin1String(QT_VERSION_STR)));
+ const QString ShowTabsKey(QLatin1String("showTabs"));
+} // anonymous namespace
+
+class TimeoutForwarder : public QObject
+{
+ Q_OBJECT
+public:
+ TimeoutForwarder(const QString &fileName);
+private slots:
+ void forward();
+private:
+ friend class HelpEngineWrapperPrivate;
+
+ const QString m_fileName;
+};
+
+class HelpEngineWrapperPrivate : public QObject
+{
+ Q_OBJECT
+ friend class HelpEngineWrapper;
+ friend class TimeoutForwarder;
+private slots:
+ void qchFileChanged(const QString &fileName);
+
+signals:
+ void documentationRemoved(const QString &namespaceName);
+ void documentationUpdated(const QString &namespaceName);
+
+private:
+ HelpEngineWrapperPrivate(const QString &collectionFile);
+
+ void initFileSystemWatchers();
+ void checkDocFilesWatched();
+ void qchFileChanged(const QString &fileName, bool fromTimeout);
+
+ static const int UpdateGracePeriod = 2000;
+
+ QHelpEngine * const m_helpEngine;
+ QFileSystemWatcher * const m_qchWatcher;
+ typedef QPair<QDateTime, QSharedPointer<TimeoutForwarder> > RecentSignal;
+ QMap<QString, RecentSignal> m_recentQchUpdates;
+};
+
+const QString HelpEngineWrapper::TrUnfiltered = HelpEngineWrapper::tr("Unfiltered");
+
+HelpEngineWrapper *HelpEngineWrapper::helpEngineWrapper = 0;
+
+HelpEngineWrapper &HelpEngineWrapper::instance(const QString &collectionFile)
+{
+ TRACE_OBJ
+ /*
+ * Note that this Singleton cannot be static, because it has to be
+ * deleted before the QApplication.
+ */
+ if (helpEngineWrapper == 0)
+ helpEngineWrapper = new HelpEngineWrapper(collectionFile);
+ return *helpEngineWrapper;
+}
+
+void HelpEngineWrapper::removeInstance()
+{
+ TRACE_OBJ
+ delete helpEngineWrapper;
+ helpEngineWrapper = 0;
+}
+
+HelpEngineWrapper::HelpEngineWrapper(const QString &collectionFile)
+ : d(new HelpEngineWrapperPrivate(collectionFile))
+{
+ TRACE_OBJ
+
+ /*
+ * Otherwise we will waste time if several new docs are found,
+ * because we will start to index them, only to be interrupted
+ * by the next request. Also, there is a nasty SQLITE bug that will
+ * cause the application to hang for minutes in that case.
+ * This call is reverted by initialDocSetupDone(), which must be
+ * called after the new docs have been installed.
+ */
+ disconnect(d->m_helpEngine, SIGNAL(setupFinished()),
+ searchEngine(), SLOT(indexDocumentation()));
+
+ connect(d, SIGNAL(documentationRemoved(QString)),
+ this, SIGNAL(documentationRemoved(QString)));
+ connect(d, SIGNAL(documentationUpdated(QString)),
+ this, SIGNAL(documentationUpdated(QString)));
+ connect(d->m_helpEngine, SIGNAL(currentFilterChanged(QString)),
+ this, SLOT(handleCurrentFilterChanged(QString)));
+ connect(d->m_helpEngine, SIGNAL(setupFinished()),
+ this, SIGNAL(setupFinished()));
+}
+
+HelpEngineWrapper::~HelpEngineWrapper()
+{
+ TRACE_OBJ
+ const QStringList &namespaces = d->m_helpEngine->registeredDocumentations();
+ foreach (const QString &nameSpace, namespaces) {
+ const QString &docFile
+ = d->m_helpEngine->documentationFileName(nameSpace);
+ d->m_qchWatcher->removePath(docFile);
+ }
+
+ delete d;
+}
+
+void HelpEngineWrapper::initialDocSetupDone()
+{
+ TRACE_OBJ
+ connect(d->m_helpEngine, SIGNAL(setupFinished()),
+ searchEngine(), SLOT(indexDocumentation()));
+ setupData();
+}
+
+QHelpSearchEngine *HelpEngineWrapper::searchEngine() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->searchEngine();
+}
+
+QHelpContentModel *HelpEngineWrapper::contentModel() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->contentModel();
+}
+
+QHelpIndexModel *HelpEngineWrapper::indexModel() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->indexModel();
+}
+
+QHelpContentWidget *HelpEngineWrapper::contentWidget()
+{
+ TRACE_OBJ
+ return d->m_helpEngine->contentWidget();
+}
+
+QHelpIndexWidget *HelpEngineWrapper::indexWidget()
+{
+ TRACE_OBJ
+ return d->m_helpEngine->indexWidget();
+}
+
+const QStringList HelpEngineWrapper::registeredDocumentations() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->registeredDocumentations();
+}
+
+const QString HelpEngineWrapper::collectionFile() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->collectionFile();
+}
+
+bool HelpEngineWrapper::registerDocumentation(const QString &docFile)
+{
+ TRACE_OBJ
+ d->checkDocFilesWatched();
+ if (!d->m_helpEngine->registerDocumentation(docFile))
+ return false;
+ d->m_qchWatcher->addPath(docFile);
+ d->checkDocFilesWatched();
+ return true;
+}
+
+bool HelpEngineWrapper::unregisterDocumentation(const QString &namespaceName)
+{
+ TRACE_OBJ
+ d->checkDocFilesWatched();
+ const QString &file = d->m_helpEngine->documentationFileName(namespaceName);
+ if (!d->m_helpEngine->unregisterDocumentation(namespaceName))
+ return false;
+ d->m_qchWatcher->removePath(file);
+ d->checkDocFilesWatched();
+ return true;
+}
+
+bool HelpEngineWrapper::setupData()
+{
+ TRACE_OBJ
+ return d->m_helpEngine->setupData();
+}
+
+bool HelpEngineWrapper::addCustomFilter(const QString &filterName,
+ const QStringList &attributes)
+{
+ TRACE_OBJ
+ return d->m_helpEngine->addCustomFilter(filterName, attributes);
+}
+
+bool HelpEngineWrapper::removeCustomFilter(const QString &filterName)
+{
+ TRACE_OBJ
+ return d->m_helpEngine->removeCustomFilter(filterName);
+}
+
+void HelpEngineWrapper::setCurrentFilter(const QString &currentFilter)
+{
+ TRACE_OBJ
+ const QString &filter
+ = currentFilter == TrUnfiltered ? Unfiltered : currentFilter;
+ d->m_helpEngine->setCurrentFilter(filter);
+}
+
+const QString HelpEngineWrapper::currentFilter() const
+{
+ TRACE_OBJ
+ const QString &filter = d->m_helpEngine->currentFilter();
+ return filter == Unfiltered ? TrUnfiltered : filter;
+}
+
+const QStringList HelpEngineWrapper::customFilters() const
+{
+ TRACE_OBJ
+ QStringList filters = d->m_helpEngine->customFilters();
+ filters.removeOne(Unfiltered);
+ filters.prepend(TrUnfiltered);
+ return filters;
+}
+
+QUrl HelpEngineWrapper::findFile(const QUrl &url) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->findFile(url);
+}
+
+QByteArray HelpEngineWrapper::fileData(const QUrl &url) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->fileData(url);
+}
+
+QMap<QString, QUrl> HelpEngineWrapper::linksForIdentifier(const QString &id) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->linksForIdentifier(id);
+}
+
+const QStringList HelpEngineWrapper::filterAttributes() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->filterAttributes();
+}
+
+const QStringList HelpEngineWrapper::filterAttributes(const QString &filterName) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->filterAttributes(filterName);
+}
+
+QString HelpEngineWrapper::error() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->error();
+}
+
+const QStringList HelpEngineWrapper::qtDocInfo(const QString &component) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(VersionKey.arg(component)).toString().
+ split(CollectionConfiguration::ListSeparator);
+}
+
+void HelpEngineWrapper::setQtDocInfo(const QString &component,
+ const QStringList &doc)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(VersionKey.arg(component),
+ doc.join(CollectionConfiguration::ListSeparator));
+}
+
+const QStringList HelpEngineWrapper::lastShownPages() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::lastShownPages(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setLastShownPages(const QStringList &lastShownPages)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setLastShownPages(*d->m_helpEngine, lastShownPages);
+}
+
+const QStringList HelpEngineWrapper::lastZoomFactors() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::lastZoomFactors(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setLastZoomFactors(const QStringList &lastZoomFactors)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setLastZoomFactors(*d->m_helpEngine, lastZoomFactors);
+}
+
+const QString HelpEngineWrapper::cacheDir() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::cacheDir(*d->m_helpEngine);
+}
+
+bool HelpEngineWrapper::cacheDirIsRelativeToCollection() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::cacheDirIsRelativeToCollection(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setCacheDir(const QString &cacheDir,
+ bool relativeToCollection)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setCacheDir(*d->m_helpEngine, cacheDir,
+ relativeToCollection);
+}
+
+bool HelpEngineWrapper::filterFunctionalityEnabled() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::filterFunctionalityEnabled(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setFilterFunctionalityEnabled(bool enabled)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setFilterFunctionalityEnabled(*d->m_helpEngine,
+ enabled);
+}
+
+bool HelpEngineWrapper::filterToolbarVisible() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::filterToolbarVisible(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setFilterToolbarVisible(bool visible)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setFilterToolbarVisible(*d->m_helpEngine, visible);
+}
+
+bool HelpEngineWrapper::addressBarEnabled() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::addressBarEnabled(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAddressBarEnabled(bool enabled)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAddressBarEnabled(*d->m_helpEngine, enabled);
+}
+
+bool HelpEngineWrapper::addressBarVisible() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::addressBarVisible(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAddressBarVisible(bool visible)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAddressBarVisible(*d->m_helpEngine, visible);
+}
+
+bool HelpEngineWrapper::documentationManagerEnabled() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::documentationManagerEnabled(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setDocumentationManagerEnabled(bool enabled)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setDocumentationManagerEnabled(*d->m_helpEngine,
+ enabled);
+}
+
+const QByteArray HelpEngineWrapper::aboutMenuTexts() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::aboutMenuTexts(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAboutMenuTexts(const QByteArray &texts)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAboutMenuTexts(*d->m_helpEngine, texts);
+}
+
+const QByteArray HelpEngineWrapper::aboutIcon() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::aboutIcon(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAboutIcon(const QByteArray &icon)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAboutIcon(*d->m_helpEngine, icon);
+}
+
+const QByteArray HelpEngineWrapper::aboutImages() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::aboutImages(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAboutImages(const QByteArray &images)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAboutImages(*d->m_helpEngine, images);
+}
+
+const QByteArray HelpEngineWrapper::aboutTexts() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::aboutTexts(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAboutTexts(const QByteArray &texts)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAboutTexts(*d->m_helpEngine, texts);
+}
+
+const QString HelpEngineWrapper::windowTitle() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::windowTitle(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setWindowTitle(const QString &windowTitle)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setWindowTitle(*d->m_helpEngine, windowTitle);
+}
+
+const QByteArray HelpEngineWrapper::applicationIcon() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::applicationIcon(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setApplicationIcon(const QByteArray &icon)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setApplicationIcon(*d->m_helpEngine, icon);
+}
+
+const QByteArray HelpEngineWrapper::mainWindow() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(MainWindowKey).toByteArray();
+}
+
+void HelpEngineWrapper::setMainWindow(const QByteArray &mainWindow)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(MainWindowKey, mainWindow);
+}
+
+const QByteArray HelpEngineWrapper::mainWindowGeometry() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(MainWindowGeometryKey).toByteArray();
+}
+
+void HelpEngineWrapper::setMainWindowGeometry(const QByteArray &geometry)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(MainWindowGeometryKey, geometry);
+}
+
+const QByteArray HelpEngineWrapper::bookmarks() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(BookmarksKey).toByteArray();
+}
+
+void HelpEngineWrapper::setBookmarks(const QByteArray &bookmarks)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(BookmarksKey, bookmarks);
+}
+
+int HelpEngineWrapper::lastTabPage() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::lastTabPage(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setLastTabPage(int lastPage)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setLastTabPage(*d->m_helpEngine, lastPage);
+}
+
+int HelpEngineWrapper::startOption() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(StartOptionKey, ShowLastPages).toInt();
+}
+
+void HelpEngineWrapper::setStartOption(int option)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(StartOptionKey, option);
+}
+
+const QString HelpEngineWrapper::homePage() const
+{
+ TRACE_OBJ
+ const QString &homePage
+ = d->m_helpEngine->customValue(HomePageKey).toString();
+ if (!homePage.isEmpty())
+ return homePage;
+ return defaultHomePage();
+}
+
+void HelpEngineWrapper::setHomePage(const QString &page)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(HomePageKey, page);
+
+}
+
+const QString HelpEngineWrapper::defaultHomePage() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::defaultHomePage(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setDefaultHomePage(const QString &page)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setDefaultHomePage(*d->m_helpEngine, page);
+}
+
+bool HelpEngineWrapper::hasFontSettings() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(UseAppFontKey).isValid();
+}
+
+bool HelpEngineWrapper::usesAppFont() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(UseAppFontKey).toBool();
+}
+
+void HelpEngineWrapper::setUseAppFont(bool useAppFont)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(UseAppFontKey, useAppFont);
+}
+
+bool HelpEngineWrapper::usesBrowserFont() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(UseBrowserFontKey, false).toBool();
+}
+
+void HelpEngineWrapper::setUseBrowserFont(bool useBrowserFont)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(UseBrowserFontKey, useBrowserFont);
+}
+
+const QFont HelpEngineWrapper::appFont() const
+{
+ TRACE_OBJ
+ return qvariant_cast<QFont>(d->m_helpEngine->customValue(AppFontKey));
+}
+
+void HelpEngineWrapper::setAppFont(const QFont &font)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(AppFontKey, font);
+}
+
+QFontDatabase::WritingSystem HelpEngineWrapper::appWritingSystem() const
+{
+ TRACE_OBJ
+ return static_cast<QFontDatabase::WritingSystem>(
+ d->m_helpEngine->customValue(AppWritingSystemKey).toInt());
+}
+
+void HelpEngineWrapper::setAppWritingSystem(QFontDatabase::WritingSystem system)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(AppWritingSystemKey, system);
+}
+
+const QFont HelpEngineWrapper::browserFont() const
+{
+ TRACE_OBJ
+ return qvariant_cast<QFont>(d->m_helpEngine->customValue(BrowserFontKey));
+}
+
+void HelpEngineWrapper::setBrowserFont(const QFont &font)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(BrowserFontKey, font);
+}
+
+QFontDatabase::WritingSystem HelpEngineWrapper::browserWritingSystem() const
+{
+ TRACE_OBJ
+ return static_cast<QFontDatabase::WritingSystem>(
+ d->m_helpEngine->customValue(BrowserWritingSystemKey).toInt());
+}
+
+void HelpEngineWrapper::setBrowserWritingSystem(QFontDatabase::WritingSystem system)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(BrowserWritingSystemKey, system);
+}
+
+void HelpEngineWrapper::handleCurrentFilterChanged(const QString &filter)
+{
+ TRACE_OBJ
+ const QString &filterToReport
+ = filter == Unfiltered ? TrUnfiltered : filter;
+ emit currentFilterChanged(filterToReport);
+}
+
+bool HelpEngineWrapper::showTabs() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(ShowTabsKey, false).toBool();
+}
+
+void HelpEngineWrapper::setShowTabs(bool show)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(ShowTabsKey, show);
+}
+
+bool HelpEngineWrapper::fullTextSearchFallbackEnabled() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::fullTextSearchFallbackEnabled(*d->m_helpEngine);
+}
+
+// -- TimeoutForwarder
+
+TimeoutForwarder::TimeoutForwarder(const QString &fileName)
+ : m_fileName(fileName)
+{
+ TRACE_OBJ
+}
+
+void TimeoutForwarder::forward()
+{
+ TRACE_OBJ
+ HelpEngineWrapper::instance().d->qchFileChanged(m_fileName, true);
+}
+
+// -- HelpEngineWrapperPrivate
+
+HelpEngineWrapperPrivate::HelpEngineWrapperPrivate(const QString &collectionFile)
+ : m_helpEngine(new QHelpEngine(collectionFile, this)),
+ m_qchWatcher(new QFileSystemWatcher(this))
+{
+ TRACE_OBJ
+ if (!m_helpEngine->customFilters().contains(Unfiltered))
+ m_helpEngine->addCustomFilter(Unfiltered, QStringList());
+ initFileSystemWatchers();
+}
+
+void HelpEngineWrapperPrivate::initFileSystemWatchers()
+{
+ TRACE_OBJ
+ foreach(const QString &ns, m_helpEngine->registeredDocumentations()) {
+ const QString &docFile = m_helpEngine->documentationFileName(ns);
+ m_qchWatcher->addPath(docFile);
+ connect(m_qchWatcher, SIGNAL(fileChanged(QString)),
+ this, SLOT(qchFileChanged(QString)));
+ }
+ checkDocFilesWatched();
+}
+
+void HelpEngineWrapperPrivate::qchFileChanged(const QString &fileName)
+{
+ TRACE_OBJ
+ qchFileChanged(fileName, false);
+}
+
+void HelpEngineWrapperPrivate::checkDocFilesWatched()
+{
+ TRACE_OBJ
+ const int watchedFilesCount = m_qchWatcher->files().count();
+ const int docFilesCount = m_helpEngine->registeredDocumentations().count();
+ if (watchedFilesCount != docFilesCount) {
+ qWarning("Strange: Have %d docs, but %d are being watched",
+ watchedFilesCount, docFilesCount);
+ }
+}
+
+void HelpEngineWrapperPrivate::qchFileChanged(const QString &fileName,
+ bool fromTimeout)
+{
+ TRACE_OBJ
+
+ /*
+ * We don't use QHelpEngineCore::namespaceName(fileName), because the file
+ * may not exist anymore or contain a different namespace.
+ */
+ QString ns;
+ foreach (const QString &curNs, m_helpEngine->registeredDocumentations()) {
+ if (m_helpEngine->documentationFileName(curNs) == fileName) {
+ ns = curNs;
+ break;
+ }
+ }
+
+ /*
+ * We can't do an assertion here, because QFileSystemWatcher may send the
+ * signal more than once.
+ */
+ if (ns.isEmpty()) {
+ m_recentQchUpdates.remove(fileName);
+ return;
+ }
+
+ /*
+ * Since the QFileSystemWatcher typically sends the signal more than once,
+ * we repeatedly delay our reaction a bit until we think the last signal
+ * was sent.
+ */
+
+ QMap<QString, RecentSignal>::Iterator it = m_recentQchUpdates.find(fileName);
+ const QDateTime &now = QDateTime::currentDateTime();
+
+ // Case 1: This is the first recent signal for the file.
+ if (it == m_recentQchUpdates.end()) {
+ QSharedPointer<TimeoutForwarder> forwarder(new TimeoutForwarder(fileName));
+ m_recentQchUpdates.insert(fileName, RecentSignal(now, forwarder));
+ QTimer::singleShot(UpdateGracePeriod, forwarder.data(), SLOT(forward()));
+ return;
+ }
+
+ // Case 2: The last signal for this file has not expired yet.
+ if (it.value().first > now.addMSecs(-UpdateGracePeriod)) {
+ if (!fromTimeout)
+ it.value().first = now;
+ else
+ QTimer::singleShot(UpdateGracePeriod, it.value().second.data(),
+ SLOT(forward()));
+ return;
+ }
+
+ // Case 3: The last signal for this file has expired.
+ if (m_helpEngine->unregisterDocumentation(ns)) {
+ if (!QFileInfo(fileName).exists()
+ || !m_helpEngine->registerDocumentation(fileName)) {
+ m_qchWatcher->removePath(fileName);
+ emit documentationRemoved(ns);
+ } else {
+ emit documentationUpdated(ns);
+ }
+ m_helpEngine->setupData();
+ }
+ m_recentQchUpdates.erase(it);
+}
+
+QT_END_NAMESPACE
+
+#include "helpenginewrapper.moc"
diff --git a/src/assistant/tools/assistant/helpenginewrapper.h b/src/assistant/tools/assistant/helpenginewrapper.h
new file mode 100644
index 000000000..ff825b04a
--- /dev/null
+++ b/src/assistant/tools/assistant/helpenginewrapper.h
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPENGINEWRAPPER_H
+#define HELPENGINEWRAPPER_H
+
+#include <QtCore/QMap>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QUrl>
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+
+QT_BEGIN_NAMESPACE
+
+class QFileSystemWatcher;
+class QHelpContentModel;
+class QHelpContentWidget;
+class QHelpIndexModel;
+class QHelpIndexWidget;
+class QHelpSearchEngine;
+
+enum {
+ ShowHomePage = 0,
+ ShowBlankPage = 1,
+ ShowLastPages = 2
+};
+
+class HelpEngineWrapperPrivate;
+class TimeoutForwarder;
+
+class HelpEngineWrapper : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(HelpEngineWrapper)
+ friend class TimeoutForwarder;
+public:
+ static HelpEngineWrapper &instance(const QString &collectionFile = QString());
+ static void removeInstance();
+
+ // Forwarded help engine member functions, possibly enriched.
+ QHelpSearchEngine *searchEngine() const;
+ QHelpContentModel *contentModel() const;
+ QHelpIndexModel *indexModel() const;
+ QHelpContentWidget *contentWidget();
+ QHelpIndexWidget *indexWidget();
+ bool setupData();
+ const QStringList registeredDocumentations() const;
+ const QString collectionFile() const;
+ bool registerDocumentation(const QString &docFile);
+ bool unregisterDocumentation(const QString &namespaceName);
+ bool addCustomFilter(const QString &filterName,
+ const QStringList &attributes);
+ bool removeCustomFilter(const QString &filterName);
+ void setCurrentFilter(const QString &filterName);
+ const QString currentFilter() const;
+ const QStringList customFilters() const;
+ QUrl findFile(const QUrl &url) const;
+ QByteArray fileData(const QUrl &url) const;
+ QMap<QString, QUrl> linksForIdentifier(const QString &id) const;
+ const QStringList filterAttributes() const;
+ const QStringList filterAttributes(const QString &filterName) const;
+ QString error() const;
+
+ /*
+ * To be called after assistant has finished looking for new documentation.
+ * This will mainly cause the search index to be updated, if necessary.
+ */
+ void initialDocSetupDone();
+
+ const QStringList qtDocInfo(const QString &component) const;
+ void setQtDocInfo(const QString &component, const QStringList &doc);
+
+ const QString homePage() const;
+ void setHomePage(const QString &page);
+ const QString defaultHomePage() const;
+ void setDefaultHomePage(const QString &page);
+
+ int lastTabPage() const;
+ void setLastTabPage(int lastPage);
+
+ // TODO: Don't allow last pages and zoom factors to be set in isolation
+ // Perhaps also fill up missing elements automatically or assert.
+ const QStringList lastShownPages() const;
+ void setLastShownPages(const QStringList &lastShownPages);
+ const QStringList lastZoomFactors() const;
+ void setLastZoomFactors(const QStringList &lastZoomFactors);
+
+ const QString cacheDir() const;
+ bool cacheDirIsRelativeToCollection() const;
+ void setCacheDir(const QString &cacheDir, bool relativeToCollection);
+
+ bool filterFunctionalityEnabled() const;
+ void setFilterFunctionalityEnabled(bool enabled);
+
+ bool filterToolbarVisible() const;
+ void setFilterToolbarVisible(bool visible);
+
+ bool addressBarEnabled() const;
+ void setAddressBarEnabled(bool enabled);
+
+ bool addressBarVisible() const;
+ void setAddressBarVisible(bool visible);
+
+ bool documentationManagerEnabled() const;
+ void setDocumentationManagerEnabled(bool enabled);
+
+ const QByteArray aboutMenuTexts() const;
+ void setAboutMenuTexts(const QByteArray &texts);
+ const QByteArray aboutTexts() const;
+ void setAboutTexts(const QByteArray &texts);
+ const QByteArray aboutIcon() const;
+ void setAboutIcon(const QByteArray &icon);
+ const QByteArray aboutImages() const;
+ void setAboutImages(const QByteArray &images);
+
+ const QString windowTitle() const;
+ void setWindowTitle(const QString &windowTitle);
+
+ const QByteArray applicationIcon() const;
+ void setApplicationIcon(const QByteArray &icon);
+
+ const QByteArray mainWindow() const;
+ void setMainWindow(const QByteArray &mainWindow);
+ const QByteArray mainWindowGeometry() const;
+ void setMainWindowGeometry(const QByteArray &geometry);
+
+ const QByteArray bookmarks() const;
+ void setBookmarks(const QByteArray &bookmarks);
+
+ int startOption() const;
+ void setStartOption(int option);
+
+ bool hasFontSettings() const;
+ bool usesAppFont() const;
+ void setUseAppFont(bool useAppFont);
+ bool usesBrowserFont() const;
+ void setUseBrowserFont(bool useBrowserFont);
+ const QFont appFont() const;
+ void setAppFont(const QFont &font);
+ QFontDatabase::WritingSystem appWritingSystem() const;
+ void setAppWritingSystem(QFontDatabase::WritingSystem system);
+ const QFont browserFont() const;
+ void setBrowserFont(const QFont &font);
+ QFontDatabase::WritingSystem browserWritingSystem() const;
+ void setBrowserWritingSystem(QFontDatabase::WritingSystem system);
+
+ bool showTabs() const;
+ void setShowTabs(bool show);
+
+ static const QString TrUnfiltered;
+
+ bool fullTextSearchFallbackEnabled() const;
+
+signals:
+
+ // For asynchronous doc updates triggered by external actions.
+ void documentationRemoved(const QString &namespaceName);
+ void documentationUpdated(const QString &namespaceName);
+
+ // Forwarded from QHelpEngineCore.
+ void currentFilterChanged(const QString &currentFilter);
+ void setupFinished();
+
+private slots:
+ void handleCurrentFilterChanged(const QString &filter);
+
+private:
+ HelpEngineWrapper(const QString &collectionFile);
+ ~HelpEngineWrapper();
+
+ static HelpEngineWrapper *helpEngineWrapper;
+
+ HelpEngineWrapperPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+#endif // HELPENGINEWRAPPER_H
diff --git a/src/assistant/tools/assistant/helpviewer.cpp b/src/assistant/tools/assistant/helpviewer.cpp
new file mode 100644
index 000000000..7bed4965a
--- /dev/null
+++ b/src/assistant/tools/assistant/helpviewer.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpviewer.h"
+#include "helpviewer_p.h"
+
+#include "helpenginewrapper.h"
+#include "tracer.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFileInfo>
+#include <QtCore/QStringBuilder>
+#include <QtCore/QTemporaryFile>
+#include <QtCore/QUrl>
+
+#include <QtGui/QDesktopServices>
+#include <QtGui/QMouseEvent>
+
+#include <QtHelp/QHelpEngineCore>
+
+QT_BEGIN_NAMESPACE
+
+const QString HelpViewer::DocPath = QLatin1String("qthelp://com.trolltech.");
+
+const QString HelpViewer::AboutBlank =
+ QCoreApplication::translate("HelpViewer", "<title>about:blank</title>");
+
+const QString HelpViewer::LocalHelpFile = QLatin1String("qthelp://"
+ "com.trolltech.com.assistantinternal-1.0.0/assistant/assistant.html");
+
+const QString HelpViewer::PageNotFoundMessage =
+ QCoreApplication::translate("HelpViewer", "<title>Error 404...</title><div "
+ "align=\"center\"><br><br><h1>The page could not be found</h1><br><h3>'%1'"
+ "</h3></div>");
+
+struct ExtensionMap {
+ const char *extension;
+ const char *mimeType;
+} extensionMap[] = {
+ { ".bmp", "image/bmp" },
+ { ".css", "text/css" },
+ { ".gif", "image/gif" },
+ { ".html", "text/html" },
+ { ".htm", "text/html" },
+ { ".ico", "image/x-icon" },
+ { ".jpeg", "image/jpeg" },
+ { ".jpg", "image/jpeg" },
+ { ".js", "application/x-javascript" },
+ { ".mng", "video/x-mng" },
+ { ".pbm", "image/x-portable-bitmap" },
+ { ".pgm", "image/x-portable-graymap" },
+ { ".pdf", "application/pdf" },
+ { ".png", "image/png" },
+ { ".ppm", "image/x-portable-pixmap" },
+ { ".rss", "application/rss+xml" },
+ { ".svg", "image/svg+xml" },
+ { ".svgz", "image/svg+xml" },
+ { ".text", "text/plain" },
+ { ".tif", "image/tiff" },
+ { ".tiff", "image/tiff" },
+ { ".txt", "text/plain" },
+ { ".xbm", "image/x-xbitmap" },
+ { ".xml", "text/xml" },
+ { ".xpm", "image/x-xpm" },
+ { ".xsl", "text/xsl" },
+ { ".xhtml", "application/xhtml+xml" },
+ { ".wml", "text/vnd.wap.wml" },
+ { ".wmlc", "application/vnd.wap.wmlc" },
+ { "about:blank", 0 },
+ { 0, 0 }
+};
+
+HelpViewer::~HelpViewer()
+{
+ TRACE_OBJ
+ delete d;
+}
+
+bool HelpViewer::isLocalUrl(const QUrl &url)
+{
+ TRACE_OBJ
+ const QString &scheme = url.scheme();
+ return scheme.isEmpty()
+ || scheme == QLatin1String("file")
+ || scheme == QLatin1String("qrc")
+ || scheme == QLatin1String("data")
+ || scheme == QLatin1String("qthelp")
+ || scheme == QLatin1String("about");
+}
+
+bool HelpViewer::canOpenPage(const QString &url)
+{
+ TRACE_OBJ
+ return !mimeFromUrl(url).isEmpty();
+}
+
+QString HelpViewer::mimeFromUrl(const QUrl &url)
+{
+ TRACE_OBJ
+ const QString &path = url.path();
+ const int index = path.lastIndexOf(QLatin1Char('.'));
+ const QByteArray &ext = path.mid(index).toUtf8().toLower();
+
+ const ExtensionMap *e = extensionMap;
+ while (e->extension) {
+ if (ext == e->extension)
+ return QLatin1String(e->mimeType);
+ ++e;
+ }
+ return QLatin1String("");
+}
+
+bool HelpViewer::launchWithExternalApp(const QUrl &url)
+{
+ TRACE_OBJ
+ if (isLocalUrl(url)) {
+ const HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ const QUrl &resolvedUrl = helpEngine.findFile(url);
+ if (!resolvedUrl.isValid())
+ return false;
+
+ const QString& path = resolvedUrl.path();
+ if (!canOpenPage(path)) {
+ QTemporaryFile tmpTmpFile;
+ if (!tmpTmpFile.open())
+ return false;
+
+ const QString &extension = QFileInfo(path).completeSuffix();
+ QFile actualTmpFile(tmpTmpFile.fileName() % QLatin1String(".")
+ % extension);
+ if (!actualTmpFile.open(QIODevice::ReadWrite | QIODevice::Truncate))
+ return false;
+
+ actualTmpFile.write(helpEngine.fileData(resolvedUrl));
+ actualTmpFile.close();
+ return QDesktopServices::openUrl(QUrl(actualTmpFile.fileName()));
+ }
+ } else if (url.scheme() == QLatin1String("http")) {
+ return QDesktopServices::openUrl(url);
+ }
+ return false;
+}
+
+// -- public slots
+
+void HelpViewer::home()
+{
+ TRACE_OBJ
+ setSource(HelpEngineWrapper::instance().homePage());
+}
+
+// -- private slots
+
+void HelpViewer::setLoadStarted()
+{
+ d->m_loadFinished = false;
+}
+
+void HelpViewer::setLoadFinished(bool ok)
+{
+ d->m_loadFinished = ok;
+ emit sourceChanged(source());
+}
+
+// -- private
+
+bool HelpViewer::handleForwardBackwardMouseButtons(QMouseEvent *event)
+{
+ TRACE_OBJ
+ if (event->button() == Qt::XButton1) {
+ backward();
+ return true;
+ }
+
+ if (event->button() == Qt::XButton2) {
+ forward();
+ return true;
+ }
+
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/helpviewer.h b/src/assistant/tools/assistant/helpviewer.h
new file mode 100644
index 000000000..bba01d0e6
--- /dev/null
+++ b/src/assistant/tools/assistant/helpviewer.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPVIEWER_H
+#define HELPVIEWER_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+#include <QtCore/QVariant>
+
+#include <QtGui/QAction>
+#include <QtGui/QFont>
+
+#if defined(QT_NO_WEBKIT)
+#include <QtGui/QTextBrowser>
+#else
+#include <QtWebKit/QWebView>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_WEBKIT)
+class HelpViewer : public QWebView
+#else
+class HelpViewer : public QTextBrowser
+#endif
+{
+ Q_OBJECT
+ class HelpViewerPrivate;
+ Q_DISABLE_COPY(HelpViewer)
+
+public:
+ enum FindFlag {
+ FindBackward = 0x01,
+ FindCaseSensitively = 0x02
+ };
+ Q_DECLARE_FLAGS(FindFlags, FindFlag)
+
+ HelpViewer(qreal zoom, QWidget *parent = 0);
+ ~HelpViewer();
+
+ QFont viewerFont() const;
+ void setViewerFont(const QFont &font);
+
+ void scaleUp();
+ void scaleDown();
+
+ void resetScale();
+ qreal scale() const;
+
+ QString title() const;
+ void setTitle(const QString &title);
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+
+ QString selectedText() const;
+ bool isForwardAvailable() const;
+ bool isBackwardAvailable() const;
+
+ bool findText(const QString &text, FindFlags flags, bool incremental,
+ bool fromSearch);
+
+ static const QString DocPath;
+ static const QString AboutBlank;
+ static const QString LocalHelpFile;
+ static const QString PageNotFoundMessage;
+
+ static bool isLocalUrl(const QUrl &url);
+ static bool canOpenPage(const QString &url);
+ static QString mimeFromUrl(const QUrl &url);
+ static bool launchWithExternalApp(const QUrl &url);
+
+public slots:
+ void copy();
+ void home();
+
+ void forward();
+ void backward();
+
+signals:
+ void titleChanged();
+#if !defined(QT_NO_WEBKIT)
+ void copyAvailable(bool yes);
+ void sourceChanged(const QUrl &url);
+ void forwardAvailable(bool enabled);
+ void backwardAvailable(bool enabled);
+ void highlighted(const QString &link);
+ void printRequested();
+#else
+ void loadStarted();
+ void loadFinished(bool finished);
+#endif
+
+protected:
+ void keyPressEvent(QKeyEvent *e);
+ void wheelEvent(QWheelEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+
+private slots:
+ void actionChanged();
+ void setLoadStarted();
+ void setLoadFinished(bool ok);
+
+private:
+ bool eventFilter(QObject *obj, QEvent *event);
+ void contextMenuEvent(QContextMenuEvent *event);
+ QVariant loadResource(int type, const QUrl &name);
+ bool handleForwardBackwardMouseButtons(QMouseEvent *e);
+
+private:
+ HelpViewerPrivate *d;
+};
+
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(HelpViewer*)
+
+#endif // HELPVIEWER_H
diff --git a/src/assistant/tools/assistant/helpviewer_p.h b/src/assistant/tools/assistant/helpviewer_p.h
new file mode 100644
index 000000000..378871197
--- /dev/null
+++ b/src/assistant/tools/assistant/helpviewer_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPVIEWERPRIVATE_H
+#define HELPVIEWERPRIVATE_H
+
+#include "centralwidget.h"
+#include "helpviewer.h"
+#include "openpagesmanager.h"
+
+#include <QtCore/QObject>
+#ifdef QT_NO_WEBKIT
+#include <QtGui/QTextBrowser>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class HelpViewer::HelpViewerPrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+#ifdef QT_NO_WEBKIT
+ HelpViewerPrivate(int zoom)
+ : zoomCount(zoom)
+ , forceFont(false)
+ , lastAnchor(QString())
+#else
+ HelpViewerPrivate()
+#endif
+ {
+ m_loadFinished = false;
+ }
+
+#ifdef QT_NO_WEBKIT
+ bool hasAnchorAt(QTextBrowser *browser, const QPoint& pos)
+ {
+ lastAnchor = browser->anchorAt(pos);
+ if (lastAnchor.isEmpty())
+ return false;
+
+ lastAnchor = browser->source().resolved(lastAnchor).toString();
+ if (lastAnchor.at(0) == QLatin1Char('#')) {
+ QString src = browser->source().toString();
+ int hsh = src.indexOf(QLatin1Char('#'));
+ lastAnchor = (hsh >= 0 ? src.left(hsh) : src) + lastAnchor;
+ }
+ return true;
+ }
+
+ void openLink(bool newPage)
+ {
+ if(lastAnchor.isEmpty())
+ return;
+ if (newPage)
+ OpenPagesManager::instance()->createPage(lastAnchor);
+ else
+ CentralWidget::instance()->setSource(lastAnchor);
+ lastAnchor.clear();
+ }
+
+public slots:
+ void openLink()
+ {
+ openLink(false);
+ }
+
+ void openLinkInNewPage()
+ {
+ openLink(true);
+ }
+
+public:
+ int zoomCount;
+ bool forceFont;
+ QString lastAnchor;
+#endif // QT_NO_WEBKIT
+
+public:
+ bool m_loadFinished;
+};
+
+QT_END_NAMESPACE
+
+#endif // HELPVIEWERPRIVATE_H
diff --git a/src/assistant/tools/assistant/helpviewer_qtb.cpp b/src/assistant/tools/assistant/helpviewer_qtb.cpp
new file mode 100644
index 000000000..0a6325cb5
--- /dev/null
+++ b/src/assistant/tools/assistant/helpviewer_qtb.cpp
@@ -0,0 +1,384 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpviewer.h"
+
+#include "globalactions.h"
+#include "helpenginewrapper.h"
+#include "helpviewer_p.h"
+#include "openpagesmanager.h"
+#include "tracer.h"
+
+#include <QtCore/QStringBuilder>
+
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QClipboard>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+HelpViewer::HelpViewer(qreal zoom, QWidget *parent)
+ : QTextBrowser(parent)
+ , d(new HelpViewerPrivate(zoom))
+{
+ TRACE_OBJ
+ QPalette p = palette();
+ p.setColor(QPalette::Inactive, QPalette::Highlight,
+ p.color(QPalette::Active, QPalette::Highlight));
+ p.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ p.color(QPalette::Active, QPalette::HighlightedText));
+ setPalette(p);
+
+ installEventFilter(this);
+ document()->setDocumentMargin(8);
+
+ QFont font = viewerFont();
+ font.setPointSize(int(font.pointSize() + zoom));
+ setViewerFont(font);
+
+ connect(this, SIGNAL(sourceChanged(QUrl)), this, SIGNAL(titleChanged()));
+ connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool)));
+}
+
+QFont HelpViewer::viewerFont() const
+{
+ TRACE_OBJ
+ if (HelpEngineWrapper::instance().usesBrowserFont())
+ return HelpEngineWrapper::instance().browserFont();
+ return qApp->font();
+}
+
+void HelpViewer::setViewerFont(const QFont &newFont)
+{
+ TRACE_OBJ
+ if (font() != newFont) {
+ d->forceFont = true;
+ setFont(newFont);
+ d->forceFont = false;
+ }
+}
+
+void HelpViewer::scaleUp()
+{
+ TRACE_OBJ
+ if (d->zoomCount < 10) {
+ d->zoomCount++;
+ d->forceFont = true;
+ zoomIn();
+ d->forceFont = false;
+ }
+}
+
+void HelpViewer::scaleDown()
+{
+ TRACE_OBJ
+ if (d->zoomCount > -5) {
+ d->zoomCount--;
+ d->forceFont = true;
+ zoomOut();
+ d->forceFont = false;
+ }
+}
+
+void HelpViewer::resetScale()
+{
+ TRACE_OBJ
+ if (d->zoomCount != 0) {
+ d->forceFont = true;
+ zoomOut(d->zoomCount);
+ d->forceFont = false;
+ }
+ d->zoomCount = 0;
+}
+
+qreal HelpViewer::scale() const
+{
+ TRACE_OBJ
+ return d->zoomCount;
+}
+
+QString HelpViewer::title() const
+{
+ TRACE_OBJ
+ return documentTitle();
+}
+
+void HelpViewer::setTitle(const QString &title)
+{
+ TRACE_OBJ
+ setDocumentTitle(title);
+}
+
+QUrl HelpViewer::source() const
+{
+ TRACE_OBJ
+ return QTextBrowser::source();
+}
+
+void HelpViewer::setSource(const QUrl &url)
+{
+ TRACE_OBJ
+ if (launchWithExternalApp(url))
+ return;
+
+ emit loadStarted();
+ QString string = url.toString();
+ const HelpEngineWrapper &engine = HelpEngineWrapper::instance();
+ const QUrl &resolvedUrl = (string == QLatin1String("help") ? LocalHelpFile :
+ engine.findFile(string));
+ QTextBrowser::setSource(resolvedUrl);
+ if (!url.isValid()) {
+ setHtml(string == QLatin1String("about:blank") ? AboutBlank
+ : PageNotFoundMessage.arg(url.toString()));
+ }
+ emit loadFinished(true);
+}
+
+QString HelpViewer::selectedText() const
+{
+ TRACE_OBJ
+ return textCursor().selectedText();
+}
+
+bool HelpViewer::isForwardAvailable() const
+{
+ TRACE_OBJ
+ return QTextBrowser::isForwardAvailable();
+}
+
+bool HelpViewer::isBackwardAvailable() const
+{
+ TRACE_OBJ
+ return QTextBrowser::isBackwardAvailable();
+}
+
+bool HelpViewer::findText(const QString &text, FindFlags flags, bool incremental,
+ bool fromSearch)
+{
+ TRACE_OBJ
+ QTextDocument *doc = document();
+ QTextCursor cursor = textCursor();
+ if (!doc || cursor.isNull())
+ return false;
+
+ const int position = cursor.selectionStart();
+ if (incremental)
+ cursor.setPosition(position);
+
+ QTextDocument::FindFlags textDocFlags;
+ if (flags & HelpViewer::FindBackward)
+ textDocFlags |= QTextDocument::FindBackward;
+ if (flags & HelpViewer::FindCaseSensitively)
+ textDocFlags |= QTextDocument::FindCaseSensitively;
+
+ QTextCursor found = doc->find(text, cursor, textDocFlags);
+ if (found.isNull()) {
+ if ((flags & HelpViewer::FindBackward) == 0)
+ cursor.movePosition(QTextCursor::Start);
+ else
+ cursor.movePosition(QTextCursor::End);
+ found = doc->find(text, cursor, textDocFlags);
+ }
+
+ if (fromSearch) {
+ cursor.beginEditBlock();
+ viewport()->setUpdatesEnabled(false);
+
+ QTextCharFormat marker;
+ marker.setForeground(Qt::red);
+ cursor.movePosition(QTextCursor::Start);
+ setTextCursor(cursor);
+
+ while (find(text)) {
+ QTextCursor hit = textCursor();
+ hit.mergeCharFormat(marker);
+ }
+
+ viewport()->setUpdatesEnabled(true);
+ cursor.endEditBlock();
+ }
+
+ bool cursorIsNull = found.isNull();
+ if (cursorIsNull) {
+ found = textCursor();
+ found.setPosition(position);
+ }
+ setTextCursor(found);
+ return !cursorIsNull;
+}
+
+// -- public slots
+
+void HelpViewer::copy()
+{
+ TRACE_OBJ
+ QTextBrowser::copy();
+}
+
+void HelpViewer::forward()
+{
+ TRACE_OBJ
+ QTextBrowser::forward();
+}
+
+void HelpViewer::backward()
+{
+ TRACE_OBJ
+ QTextBrowser::backward();
+}
+
+// -- protected
+
+void HelpViewer::keyPressEvent(QKeyEvent *e)
+{
+ TRACE_OBJ
+ if ((e->key() == Qt::Key_Home && e->modifiers() != Qt::NoModifier)
+ || (e->key() == Qt::Key_End && e->modifiers() != Qt::NoModifier)) {
+ QKeyEvent* event = new QKeyEvent(e->type(), e->key(), Qt::NoModifier,
+ e->text(), e->isAutoRepeat(), e->count());
+ e = event;
+ }
+ QTextBrowser::keyPressEvent(e);
+}
+
+
+void HelpViewer::wheelEvent(QWheelEvent *e)
+{
+ TRACE_OBJ
+ if (e->modifiers() == Qt::ControlModifier) {
+ e->accept();
+ e->delta() > 0 ? scaleUp() : scaleDown();
+ } else {
+ QTextBrowser::wheelEvent(e);
+ }
+}
+
+void HelpViewer::mousePressEvent(QMouseEvent *e)
+{
+ TRACE_OBJ
+#ifdef Q_OS_LINUX
+ if (handleForwardBackwardMouseButtons(e))
+ return;
+#endif
+
+ QTextBrowser::mousePressEvent(e);
+}
+
+void HelpViewer::mouseReleaseEvent(QMouseEvent *e)
+{
+ TRACE_OBJ
+#ifndef Q_OS_LINUX
+ if (handleForwardBackwardMouseButtons(e))
+ return;
+#endif
+
+ bool controlPressed = e->modifiers() & Qt::ControlModifier;
+ if ((controlPressed && d->hasAnchorAt(this, e->pos())) ||
+ (e->button() == Qt::MidButton && d->hasAnchorAt(this, e->pos()))) {
+ d->openLinkInNewPage();
+ return;
+ }
+
+ QTextBrowser::mouseReleaseEvent(e);
+}
+
+// -- private slots
+
+void HelpViewer::actionChanged()
+{
+ // stub
+ TRACE_OBJ
+}
+
+// -- private
+
+bool HelpViewer::eventFilter(QObject *obj, QEvent *event)
+{
+ TRACE_OBJ
+ if (event->type() == QEvent::FontChange && !d->forceFont)
+ return true;
+ return QTextBrowser::eventFilter(obj, event);
+}
+
+void HelpViewer::contextMenuEvent(QContextMenuEvent *event)
+{
+ TRACE_OBJ
+
+ QMenu menu(QString(), 0);
+ QUrl link;
+ QAction *copyAnchorAction = 0;
+ if (d->hasAnchorAt(this, event->pos())) {
+ link = anchorAt(event->pos());
+ if (link.isRelative())
+ link = source().resolved(link);
+ menu.addAction(tr("Open Link"), d, SLOT(openLink()));
+ menu.addAction(tr("Open Link in New Tab\tCtrl+LMB"), d, SLOT(openLinkInNewPage()));
+
+ if (!link.isEmpty() && link.isValid())
+ copyAnchorAction = menu.addAction(tr("Copy &Link Location"));
+ } else if (!selectedText().isEmpty()) {
+ menu.addAction(tr("Copy"), this, SLOT(copy()));
+ } else {
+ menu.addAction(tr("Reload"), this, SLOT(reload()));
+ }
+
+ if (copyAnchorAction == menu.exec(event->globalPos()))
+ QApplication::clipboard()->setText(link.toString());
+}
+
+QVariant HelpViewer::loadResource(int type, const QUrl &name)
+{
+ TRACE_OBJ
+ QByteArray ba;
+ if (type < 4) {
+ ba = HelpEngineWrapper::instance().fileData(name);
+ if (name.toString().endsWith(QLatin1String(".svg"), Qt::CaseInsensitive)) {
+ QImage image;
+ image.loadFromData(ba, "svg");
+ if (!image.isNull())
+ return image;
+ }
+ }
+ return ba;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/helpviewer_qwv.cpp b/src/assistant/tools/assistant/helpviewer_qwv.cpp
new file mode 100644
index 000000000..efb9b5900
--- /dev/null
+++ b/src/assistant/tools/assistant/helpviewer_qwv.cpp
@@ -0,0 +1,495 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpviewer.h"
+#include "helpviewer_p.h"
+
+#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "openpagesmanager.h"
+#include "tracer.h"
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QString>
+#include <QtCore/QTimer>
+
+#include <QtGui/QApplication>
+#include <QtGui/QWheelEvent>
+
+#include <QtHelp/QHelpEngineCore>
+
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtNetwork/QNetworkReply>
+#include <QtNetwork/QNetworkRequest>
+
+QT_BEGIN_NAMESPACE
+
+// -- HelpNetworkReply
+
+class HelpNetworkReply : public QNetworkReply
+{
+public:
+ HelpNetworkReply(const QNetworkRequest &request, const QByteArray &fileData,
+ const QString &mimeType);
+
+ virtual void abort();
+
+ virtual qint64 bytesAvailable() const
+ { return data.length() + QNetworkReply::bytesAvailable(); }
+
+protected:
+ virtual qint64 readData(char *data, qint64 maxlen);
+
+private:
+ QByteArray data;
+ qint64 origLen;
+};
+
+HelpNetworkReply::HelpNetworkReply(const QNetworkRequest &request,
+ const QByteArray &fileData, const QString& mimeType)
+ : data(fileData), origLen(fileData.length())
+{
+ TRACE_OBJ
+ setRequest(request);
+ setOpenMode(QIODevice::ReadOnly);
+
+ setHeader(QNetworkRequest::ContentTypeHeader, mimeType);
+ setHeader(QNetworkRequest::ContentLengthHeader, QByteArray::number(origLen));
+ QTimer::singleShot(0, this, SIGNAL(metaDataChanged()));
+ QTimer::singleShot(0, this, SIGNAL(readyRead()));
+}
+
+void HelpNetworkReply::abort()
+{
+ TRACE_OBJ
+}
+
+qint64 HelpNetworkReply::readData(char *buffer, qint64 maxlen)
+{
+ TRACE_OBJ
+ qint64 len = qMin(qint64(data.length()), maxlen);
+ if (len) {
+ memcpy(buffer, data.constData(), len);
+ data.remove(0, len);
+ }
+ if (!data.length())
+ QTimer::singleShot(0, this, SIGNAL(finished()));
+ return len;
+}
+
+// -- HelpNetworkAccessManager
+
+class HelpNetworkAccessManager : public QNetworkAccessManager
+{
+public:
+ HelpNetworkAccessManager(QObject *parent);
+
+protected:
+ virtual QNetworkReply *createRequest(Operation op,
+ const QNetworkRequest &request, QIODevice *outgoingData = 0);
+};
+
+HelpNetworkAccessManager::HelpNetworkAccessManager(QObject *parent)
+ : QNetworkAccessManager(parent)
+{
+ TRACE_OBJ
+}
+
+QNetworkReply *HelpNetworkAccessManager::createRequest(Operation /*op*/,
+ const QNetworkRequest &request, QIODevice* /*outgoingData*/)
+{
+ TRACE_OBJ
+ QString url = request.url().toString();
+ const HelpEngineWrapper &engine = HelpEngineWrapper::instance();
+ // TODO: For some reason the url to load is already wrong (passed from webkit)
+ // though the css file and the references inside should work that way. One
+ // possible problem might be that the css is loaded at the same level as the
+ // html, thus a path inside the css like (../images/foo.png) might cd out of
+ // the virtual folder
+ if (!engine.findFile(url).isValid()) {
+ if (url.startsWith(HelpViewer::DocPath)) {
+ QUrl newUrl = request.url();
+ if (!newUrl.path().startsWith(QLatin1String("/qdoc/"))) {
+ newUrl.setPath(QLatin1String("qdoc") + newUrl.path());
+ url = newUrl.toString();
+ }
+ }
+ }
+
+ const QString &mimeType = HelpViewer::mimeFromUrl(url);
+ const QByteArray &data = engine.findFile(url).isValid() ? engine.fileData(url)
+ : HelpViewer::PageNotFoundMessage.arg(url).toUtf8();
+
+ return new HelpNetworkReply(request, data, mimeType.isEmpty()
+ ? QLatin1String("application/octet-stream") : mimeType);
+}
+
+// -- HelpPage
+
+class HelpPage : public QWebPage
+{
+public:
+ HelpPage(QObject *parent);
+
+protected:
+ virtual QWebPage *createWindow(QWebPage::WebWindowType);
+ virtual void triggerAction(WebAction action, bool checked = false);
+
+ virtual bool acceptNavigationRequest(QWebFrame *frame,
+ const QNetworkRequest &request, NavigationType type);
+
+private:
+ bool closeNewTabIfNeeded;
+
+ friend class HelpViewer;
+ QUrl m_loadingUrl;
+ Qt::MouseButtons m_pressedButtons;
+ Qt::KeyboardModifiers m_keyboardModifiers;
+};
+
+HelpPage::HelpPage(QObject *parent)
+ : QWebPage(parent)
+ , closeNewTabIfNeeded(false)
+ , m_pressedButtons(Qt::NoButton)
+ , m_keyboardModifiers(Qt::NoModifier)
+{
+ TRACE_OBJ
+}
+
+QWebPage *HelpPage::createWindow(QWebPage::WebWindowType)
+{
+ TRACE_OBJ
+ HelpPage* newPage = static_cast<HelpPage*>(OpenPagesManager::instance()
+ ->createPage()->page());
+ newPage->closeNewTabIfNeeded = closeNewTabIfNeeded;
+ closeNewTabIfNeeded = false;
+ return newPage;
+}
+
+void HelpPage::triggerAction(WebAction action, bool checked)
+{
+ TRACE_OBJ
+ switch (action) {
+ case OpenLinkInNewWindow:
+ closeNewTabIfNeeded = true;
+ default: // fall through
+ QWebPage::triggerAction(action, checked);
+ break;
+ }
+}
+
+bool HelpPage::acceptNavigationRequest(QWebFrame *,
+ const QNetworkRequest &request, QWebPage::NavigationType type)
+{
+ TRACE_OBJ
+ const bool closeNewTab = closeNewTabIfNeeded;
+ closeNewTabIfNeeded = false;
+
+ const QUrl &url = request.url();
+ if (HelpViewer::launchWithExternalApp(url)) {
+ if (closeNewTab)
+ QMetaObject::invokeMethod(OpenPagesManager::instance(), "closeCurrentPage");
+ return false;
+ }
+
+ if (type == QWebPage::NavigationTypeLinkClicked
+ && (m_keyboardModifiers & Qt::ControlModifier || m_pressedButtons == Qt::MidButton)) {
+ m_pressedButtons = Qt::NoButton;
+ m_keyboardModifiers = Qt::NoModifier;
+ OpenPagesManager::instance()->createPage(url);
+ return false;
+ }
+
+ m_loadingUrl = url; // because of async page loading, we will hit some kind
+ // of race condition while using a remote command, like a combination of
+ // SetSource; SyncContent. SetSource would be called and SyncContents shortly
+ // afterwards, but the page might not have finished loading and the old url
+ // would be returned.
+ return true;
+}
+
+// -- HelpViewer
+
+HelpViewer::HelpViewer(qreal zoom, QWidget *parent)
+ : QWebView(parent)
+ , d(new HelpViewerPrivate)
+{
+ TRACE_OBJ
+ setAcceptDrops(false);
+ settings()->setAttribute(QWebSettings::JavaEnabled, false);
+ settings()->setAttribute(QWebSettings::PluginsEnabled, false);
+
+ setPage(new HelpPage(this));
+ page()->setNetworkAccessManager(new HelpNetworkAccessManager(this));
+
+ QAction* action = pageAction(QWebPage::OpenLinkInNewWindow);
+ action->setText(tr("Open Link in New Page"));
+
+ pageAction(QWebPage::DownloadLinkToDisk)->setVisible(false);
+ pageAction(QWebPage::DownloadImageToDisk)->setVisible(false);
+ pageAction(QWebPage::OpenImageInNewWindow)->setVisible(false);
+
+ connect(pageAction(QWebPage::Copy), SIGNAL(changed()), this,
+ SLOT(actionChanged()));
+ connect(pageAction(QWebPage::Back), SIGNAL(changed()), this,
+ SLOT(actionChanged()));
+ connect(pageAction(QWebPage::Forward), SIGNAL(changed()), this,
+ SLOT(actionChanged()));
+ connect(page(), SIGNAL(linkHovered(QString, QString, QString)), this,
+ SIGNAL(highlighted(QString)));
+ connect(this, SIGNAL(urlChanged(QUrl)), this, SIGNAL(sourceChanged(QUrl)));
+ connect(this, SIGNAL(loadStarted()), this, SLOT(setLoadStarted()));
+ connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool)));
+ connect(this, SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged()));
+ connect(page(), SIGNAL(printRequested(QWebFrame*)), this, SIGNAL(printRequested()));
+
+ setFont(viewerFont());
+ setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom);
+}
+
+QFont HelpViewer::viewerFont() const
+{
+ TRACE_OBJ
+ if (HelpEngineWrapper::instance().usesBrowserFont())
+ return HelpEngineWrapper::instance().browserFont();
+
+ QWebSettings *webSettings = QWebSettings::globalSettings();
+ return QFont(webSettings->fontFamily(QWebSettings::StandardFont),
+ webSettings->fontSize(QWebSettings::DefaultFontSize));
+}
+
+void HelpViewer::setViewerFont(const QFont &font)
+{
+ TRACE_OBJ
+ QWebSettings *webSettings = settings();
+ webSettings->setFontFamily(QWebSettings::StandardFont, font.family());
+ webSettings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize());
+}
+
+void HelpViewer::scaleUp()
+{
+ TRACE_OBJ
+ setTextSizeMultiplier(textSizeMultiplier() + 0.1);
+}
+
+void HelpViewer::scaleDown()
+{
+ TRACE_OBJ
+ setTextSizeMultiplier(qMax(0.0, textSizeMultiplier() - 0.1));
+}
+
+void HelpViewer::resetScale()
+{
+ TRACE_OBJ
+ setTextSizeMultiplier(1.0);
+}
+
+qreal HelpViewer::scale() const
+{
+ TRACE_OBJ
+ return textSizeMultiplier();
+}
+
+QString HelpViewer::title() const
+{
+ TRACE_OBJ
+ return QWebView::title();
+}
+
+void HelpViewer::setTitle(const QString &title)
+{
+ TRACE_OBJ
+ Q_UNUSED(title)
+}
+
+QUrl HelpViewer::source() const
+{
+ TRACE_OBJ
+ HelpPage *currentPage = static_cast<HelpPage*> (page());
+ if (currentPage && !d->m_loadFinished) {
+ // see HelpPage::acceptNavigationRequest(...)
+ return currentPage->m_loadingUrl;
+ }
+ return url();
+}
+
+void HelpViewer::setSource(const QUrl &url)
+{
+ TRACE_OBJ
+ load(url.toString() == QLatin1String("help") ? LocalHelpFile : url);
+}
+
+QString HelpViewer::selectedText() const
+{
+ TRACE_OBJ
+ return QWebView::selectedText();
+}
+
+bool HelpViewer::isForwardAvailable() const
+{
+ TRACE_OBJ
+ return pageAction(QWebPage::Forward)->isEnabled();
+}
+
+bool HelpViewer::isBackwardAvailable() const
+{
+ TRACE_OBJ
+ return pageAction(QWebPage::Back)->isEnabled();
+}
+
+bool HelpViewer::findText(const QString &text, FindFlags flags, bool incremental,
+ bool fromSearch)
+{
+ TRACE_OBJ
+ Q_UNUSED(incremental); Q_UNUSED(fromSearch);
+ QWebPage::FindFlags options = QWebPage::FindWrapsAroundDocument;
+ if (flags & FindBackward)
+ options |= QWebPage::FindBackward;
+ if (flags & FindCaseSensitively)
+ options |= QWebPage::FindCaseSensitively;
+
+ bool found = QWebView::findText(text, options);
+ options = QWebPage::HighlightAllOccurrences;
+ QWebView::findText(QLatin1String(""), options); // clear first
+ QWebView::findText(text, options); // force highlighting of all other matches
+ return found;
+}
+
+// -- public slots
+
+void HelpViewer::copy()
+{
+ TRACE_OBJ
+ triggerPageAction(QWebPage::Copy);
+}
+
+void HelpViewer::forward()
+{
+ TRACE_OBJ
+ QWebView::forward();
+}
+
+void HelpViewer::backward()
+{
+ TRACE_OBJ
+ back();
+}
+
+// -- protected
+
+void HelpViewer::keyPressEvent(QKeyEvent *e)
+{
+ TRACE_OBJ
+ // TODO: remove this once we support multiple keysequences per command
+ if (e->key() == Qt::Key_Insert && e->modifiers() == Qt::CTRL) {
+ if (!selectedText().isEmpty())
+ copy();
+ }
+ QWebView::keyPressEvent(e);
+}
+
+void HelpViewer::wheelEvent(QWheelEvent *event)
+{
+ TRACE_OBJ
+ if (event->modifiers()& Qt::ControlModifier) {
+ event->accept();
+ event->delta() > 0 ? scaleUp() : scaleDown();
+ } else {
+ QWebView::wheelEvent(event);
+ }
+}
+
+void HelpViewer::mousePressEvent(QMouseEvent *event)
+{
+ TRACE_OBJ
+#ifdef Q_OS_LINUX
+ if (handleForwardBackwardMouseButtons(event))
+ return;
+#endif
+
+ if (HelpPage *currentPage = static_cast<HelpPage*> (page())) {
+ currentPage->m_pressedButtons = event->buttons();
+ currentPage->m_keyboardModifiers = event->modifiers();
+ }
+
+ QWebView::mousePressEvent(event);
+}
+
+void HelpViewer::mouseReleaseEvent(QMouseEvent *event)
+{
+ TRACE_OBJ
+#ifndef Q_OS_LINUX
+ if (handleForwardBackwardMouseButtons(event))
+ return;
+#endif
+
+ QWebView::mouseReleaseEvent(event);
+}
+
+// -- private slots
+
+void HelpViewer::actionChanged()
+{
+ TRACE_OBJ
+ QAction *a = qobject_cast<QAction *>(sender());
+ if (a == pageAction(QWebPage::Copy))
+ emit copyAvailable(a->isEnabled());
+ else if (a == pageAction(QWebPage::Back))
+ emit backwardAvailable(a->isEnabled());
+ else if (a == pageAction(QWebPage::Forward))
+ emit forwardAvailable(a->isEnabled());
+}
+
+// -- private
+
+bool HelpViewer::eventFilter(QObject *obj, QEvent *event)
+{
+ TRACE_OBJ
+ return QWebView::eventFilter(obj, event);
+}
+
+void HelpViewer::contextMenuEvent(QContextMenuEvent *event)
+{
+ TRACE_OBJ
+ QWebView::contextMenuEvent(event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/images/assistant-128.png b/src/assistant/tools/assistant/images/assistant-128.png
new file mode 100644
index 000000000..f05949f6d
--- /dev/null
+++ b/src/assistant/tools/assistant/images/assistant-128.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/assistant.png b/src/assistant/tools/assistant/images/assistant.png
new file mode 100644
index 000000000..ea4d1e70c
--- /dev/null
+++ b/src/assistant/tools/assistant/images/assistant.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/bookmark.png b/src/assistant/tools/assistant/images/bookmark.png
new file mode 100644
index 000000000..57e57e343
--- /dev/null
+++ b/src/assistant/tools/assistant/images/bookmark.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/closebutton.png b/src/assistant/tools/assistant/images/closebutton.png
new file mode 100644
index 000000000..c978cf51a
--- /dev/null
+++ b/src/assistant/tools/assistant/images/closebutton.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/darkclosebutton.png b/src/assistant/tools/assistant/images/darkclosebutton.png
new file mode 100644
index 000000000..1077663b2
--- /dev/null
+++ b/src/assistant/tools/assistant/images/darkclosebutton.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/addtab.png b/src/assistant/tools/assistant/images/mac/addtab.png
new file mode 100644
index 000000000..20928fb40
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/addtab.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/book.png b/src/assistant/tools/assistant/images/mac/book.png
new file mode 100644
index 000000000..7a3204c87
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/book.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/closetab.png b/src/assistant/tools/assistant/images/mac/closetab.png
new file mode 100644
index 000000000..ab9d669ee
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/closetab.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/editcopy.png b/src/assistant/tools/assistant/images/mac/editcopy.png
new file mode 100644
index 000000000..f55136446
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/editcopy.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/find.png b/src/assistant/tools/assistant/images/mac/find.png
new file mode 100644
index 000000000..3561745f0
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/find.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/home.png b/src/assistant/tools/assistant/images/mac/home.png
new file mode 100644
index 000000000..78d94da18
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/home.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/next.png b/src/assistant/tools/assistant/images/mac/next.png
new file mode 100644
index 000000000..a585cab80
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/next.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/previous.png b/src/assistant/tools/assistant/images/mac/previous.png
new file mode 100644
index 000000000..612fb34dc
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/previous.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/print.png b/src/assistant/tools/assistant/images/mac/print.png
new file mode 100644
index 000000000..10ca56c82
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/print.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/resetzoom.png b/src/assistant/tools/assistant/images/mac/resetzoom.png
new file mode 100644
index 000000000..759b38296
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/resetzoom.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/synctoc.png b/src/assistant/tools/assistant/images/mac/synctoc.png
new file mode 100644
index 000000000..067fa941b
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/synctoc.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/zoomin.png b/src/assistant/tools/assistant/images/mac/zoomin.png
new file mode 100644
index 000000000..d46f5aff0
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/zoomin.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/mac/zoomout.png b/src/assistant/tools/assistant/images/mac/zoomout.png
new file mode 100644
index 000000000..46326566d
--- /dev/null
+++ b/src/assistant/tools/assistant/images/mac/zoomout.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/trolltech-logo.png b/src/assistant/tools/assistant/images/trolltech-logo.png
new file mode 100644
index 000000000..c53e744ca
--- /dev/null
+++ b/src/assistant/tools/assistant/images/trolltech-logo.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/addtab.png b/src/assistant/tools/assistant/images/win/addtab.png
new file mode 100644
index 000000000..4bb0feb92
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/addtab.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/book.png b/src/assistant/tools/assistant/images/win/book.png
new file mode 100644
index 000000000..09ec4d33f
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/book.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/closetab.png b/src/assistant/tools/assistant/images/win/closetab.png
new file mode 100644
index 000000000..ef9e02086
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/closetab.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/editcopy.png b/src/assistant/tools/assistant/images/win/editcopy.png
new file mode 100644
index 000000000..1121b47d8
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/editcopy.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/find.png b/src/assistant/tools/assistant/images/win/find.png
new file mode 100644
index 000000000..6ea35e930
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/find.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/home.png b/src/assistant/tools/assistant/images/win/home.png
new file mode 100644
index 000000000..b1c6ae191
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/home.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/next.png b/src/assistant/tools/assistant/images/win/next.png
new file mode 100644
index 000000000..8df4127a0
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/next.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/previous.png b/src/assistant/tools/assistant/images/win/previous.png
new file mode 100644
index 000000000..0780bc23d
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/previous.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/print.png b/src/assistant/tools/assistant/images/win/print.png
new file mode 100644
index 000000000..ba7c02dc1
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/print.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/resetzoom.png b/src/assistant/tools/assistant/images/win/resetzoom.png
new file mode 100644
index 000000000..b69ae4e7f
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/resetzoom.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/synctoc.png b/src/assistant/tools/assistant/images/win/synctoc.png
new file mode 100644
index 000000000..da301bc59
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/synctoc.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/zoomin.png b/src/assistant/tools/assistant/images/win/zoomin.png
new file mode 100644
index 000000000..2e586fc7b
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/zoomin.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/win/zoomout.png b/src/assistant/tools/assistant/images/win/zoomout.png
new file mode 100644
index 000000000..a736d3934
--- /dev/null
+++ b/src/assistant/tools/assistant/images/win/zoomout.png
Binary files differ
diff --git a/src/assistant/tools/assistant/images/wrap.png b/src/assistant/tools/assistant/images/wrap.png
new file mode 100644
index 000000000..90f18d9f7
--- /dev/null
+++ b/src/assistant/tools/assistant/images/wrap.png
Binary files differ
diff --git a/src/assistant/tools/assistant/indexwindow.cpp b/src/assistant/tools/assistant/indexwindow.cpp
new file mode 100644
index 000000000..38bc8b96a
--- /dev/null
+++ b/src/assistant/tools/assistant/indexwindow.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "indexwindow.h"
+
+#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "helpviewer.h"
+#include "openpagesmanager.h"
+#include "topicchooser.h"
+#include "tracer.h"
+
+#include <QtGui/QLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QListWidgetItem>
+
+#include <QtHelp/QHelpIndexWidget>
+
+QT_BEGIN_NAMESPACE
+
+IndexWindow::IndexWindow(QWidget *parent)
+ : QWidget(parent)
+ , m_searchLineEdit(new QLineEdit)
+ , m_indexWidget(HelpEngineWrapper::instance().indexWidget())
+{
+ TRACE_OBJ
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QLabel *l = new QLabel(tr("&Look for:"));
+ layout->addWidget(l);
+
+ l->setBuddy(m_searchLineEdit);
+ connect(m_searchLineEdit, SIGNAL(textChanged(QString)), this,
+ SLOT(filterIndices(QString)));
+ m_searchLineEdit->installEventFilter(this);
+ layout->setMargin(4);
+ layout->addWidget(m_searchLineEdit);
+
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ m_indexWidget->installEventFilter(this);
+ connect(helpEngine.indexModel(), SIGNAL(indexCreationStarted()), this,
+ SLOT(disableSearchLineEdit()));
+ connect(helpEngine.indexModel(), SIGNAL(indexCreated()), this,
+ SLOT(enableSearchLineEdit()));
+ connect(m_indexWidget, SIGNAL(linkActivated(QUrl,QString)), this,
+ SIGNAL(linkActivated(QUrl)));
+ connect(m_indexWidget, SIGNAL(linksActivated(QMap<QString,QUrl>,QString)),
+ this, SIGNAL(linksActivated(QMap<QString,QUrl>,QString)));
+ connect(m_searchLineEdit, SIGNAL(returnPressed()), m_indexWidget,
+ SLOT(activateCurrentItem()));
+ layout->addWidget(m_indexWidget);
+
+ m_indexWidget->viewport()->installEventFilter(this);
+}
+
+IndexWindow::~IndexWindow()
+{
+ TRACE_OBJ
+}
+
+void IndexWindow::filterIndices(const QString &filter)
+{
+ TRACE_OBJ
+ if (filter.contains(QLatin1Char('*')))
+ m_indexWidget->filterIndices(filter, filter);
+ else
+ m_indexWidget->filterIndices(filter, QString());
+}
+
+bool IndexWindow::eventFilter(QObject *obj, QEvent *e)
+{
+ TRACE_OBJ
+ if (obj == m_searchLineEdit && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ QModelIndex idx = m_indexWidget->currentIndex();
+ switch (ke->key()) {
+ case Qt::Key_Up:
+ idx = m_indexWidget->model()->index(idx.row()-1,
+ idx.column(), idx.parent());
+ if (idx.isValid()) {
+ m_indexWidget->setCurrentIndex(idx);
+ return true;
+ }
+ break;
+ case Qt::Key_Down:
+ idx = m_indexWidget->model()->index(idx.row()+1,
+ idx.column(), idx.parent());
+ if (idx.isValid()) {
+ m_indexWidget->setCurrentIndex(idx);
+ return true;
+ }
+ break;
+ case Qt::Key_Escape:
+ emit escapePressed();
+ return true;
+ default: ; // stop complaining
+ }
+ } else if (obj == m_indexWidget && e->type() == QEvent::ContextMenu) {
+ QContextMenuEvent *ctxtEvent = static_cast<QContextMenuEvent*>(e);
+ QModelIndex idx = m_indexWidget->indexAt(ctxtEvent->pos());
+ if (idx.isValid()) {
+ QMenu menu;
+ QAction *curTab = menu.addAction(tr("Open Link"));
+ QAction *newTab = menu.addAction(tr("Open Link in New Tab"));
+ menu.move(m_indexWidget->mapToGlobal(ctxtEvent->pos()));
+
+ QAction *action = menu.exec();
+ if (curTab == action)
+ m_indexWidget->activateCurrentItem();
+ else if (newTab == action) {
+ open(m_indexWidget, idx);
+ }
+ }
+ } else if (m_indexWidget && obj == m_indexWidget->viewport()
+ && e->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);
+ QModelIndex idx = m_indexWidget->indexAt(mouseEvent->pos());
+ if (idx.isValid()) {
+ Qt::MouseButtons button = mouseEvent->button();
+ if (((button == Qt::LeftButton) && (mouseEvent->modifiers() & Qt::ControlModifier))
+ || (button == Qt::MidButton)) {
+ open(m_indexWidget, idx);
+ }
+ }
+ }
+#ifdef Q_OS_MAC
+ else if (obj == m_indexWidget && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter)
+ m_indexWidget->activateCurrentItem();
+ }
+#endif
+ return QWidget::eventFilter(obj, e);
+}
+
+void IndexWindow::enableSearchLineEdit()
+{
+ TRACE_OBJ
+ m_searchLineEdit->setDisabled(false);
+ filterIndices(m_searchLineEdit->text());
+}
+
+void IndexWindow::disableSearchLineEdit()
+{
+ TRACE_OBJ
+ m_searchLineEdit->setDisabled(true);
+}
+
+void IndexWindow::setSearchLineEditText(const QString &text)
+{
+ TRACE_OBJ
+ m_searchLineEdit->setText(text);
+}
+
+void IndexWindow::focusInEvent(QFocusEvent *e)
+{
+ TRACE_OBJ
+ if (e->reason() != Qt::MouseFocusReason) {
+ m_searchLineEdit->selectAll();
+ m_searchLineEdit->setFocus();
+ }
+}
+
+void IndexWindow::open(QHelpIndexWidget* indexWidget, const QModelIndex &index)
+{
+ TRACE_OBJ
+ QHelpIndexModel *model = qobject_cast<QHelpIndexModel*>(indexWidget->model());
+ if (model) {
+ QString keyword = model->data(index, Qt::DisplayRole).toString();
+ QMap<QString, QUrl> links = model->linksForKeyword(keyword);
+
+ QUrl url;
+ if (links.count() > 1) {
+ TopicChooser tc(this, keyword, links);
+ if (tc.exec() == QDialog::Accepted)
+ url = tc.link();
+ } else if (links.count() == 1) {
+ url = links.constBegin().value();
+ } else {
+ return;
+ }
+
+ if (!HelpViewer::canOpenPage(url.path()))
+ CentralWidget::instance()->setSource(url);
+ else
+ OpenPagesManager::instance()->createPage(url);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/indexwindow.h b/src/assistant/tools/assistant/indexwindow.h
new file mode 100644
index 000000000..6c1c4e14e
--- /dev/null
+++ b/src/assistant/tools/assistant/indexwindow.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INDEXWINDOW_H
+#define INDEXWINDOW_H
+
+#include <QtCore/QUrl>
+#include <QtGui/QWidget>
+#include <QtGui/QLineEdit>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpIndexWidget;
+class QModelIndex;
+
+class IndexWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ IndexWindow(QWidget *parent = 0);
+ ~IndexWindow();
+
+ void setSearchLineEditText(const QString &text);
+ QString searchLineEditText() const
+ {
+ return m_searchLineEdit->text();
+ }
+
+signals:
+ void linkActivated(const QUrl &link);
+ void linksActivated(const QMap<QString, QUrl> &links,
+ const QString &keyword);
+ void escapePressed();
+
+private slots:
+ void filterIndices(const QString &filter);
+ void enableSearchLineEdit();
+ void disableSearchLineEdit();
+
+private:
+ bool eventFilter(QObject *obj, QEvent *e);
+ void focusInEvent(QFocusEvent *e);
+ void open(QHelpIndexWidget *indexWidget, const QModelIndex &index);
+
+ QLineEdit *m_searchLineEdit;
+ QHelpIndexWidget *m_indexWidget;
+};
+
+QT_END_NAMESPACE
+
+#endif // INDEXWINDOW_H
diff --git a/src/assistant/tools/assistant/installdialog.cpp b/src/assistant/tools/assistant/installdialog.cpp
new file mode 100644
index 000000000..29473a2f9
--- /dev/null
+++ b/src/assistant/tools/assistant/installdialog.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include "installdialog.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QUrl>
+#include <QtCore/QBuffer>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QCryptographicHash>
+
+#include <QtGui/QMessageBox>
+#include <QtGui/QFileDialog>
+
+#include <QtHelp/QHelpEngineCore>
+
+#include <QtNetwork/QHttp>
+
+QT_BEGIN_NAMESPACE
+#ifndef QT_NO_HTTP
+
+#define QCH_FILENAME 92943
+#define QCH_NAMESPACE 92944
+#define QCH_CHECKSUM 92945
+
+InstallDialog::InstallDialog(QHelpEngineCore *helpEngine, QWidget *parent,
+ const QString &host, int port)
+ : QDialog(parent), m_helpEngine(helpEngine), m_host(host), m_port(port)
+{
+ TRACE_OBJ
+ m_ui.setupUi(this);
+
+ m_ui.installButton->setEnabled(false);
+ m_ui.cancelButton->setEnabled(false);
+ m_ui.pathLineEdit->setText(QFileInfo(m_helpEngine->collectionFile()).absolutePath());
+ m_ui.progressBar->hide();
+
+ m_windowTitle = tr("Install Documentation");
+
+ m_http = new QHttp(this);
+ connect(m_http, SIGNAL(requestFinished(int,bool)),
+ this, SLOT(httpRequestFinished(int,bool)));
+ connect(m_http, SIGNAL(dataReadProgress(int,int)),
+ this, SLOT(updateDataReadProgress(int,int)));
+ connect(m_http, SIGNAL(responseHeaderReceived(QHttpResponseHeader)),
+ this, SLOT(readResponseHeader(QHttpResponseHeader)));
+ connect(m_ui.installButton, SIGNAL(clicked()), this, SLOT(install()));
+ connect(m_ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancelDownload()));
+ connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseDirectories()));
+
+ connect(m_ui.listWidget, SIGNAL(itemChanged(QListWidgetItem*)),
+ this, SLOT(updateInstallButton()));
+
+ QTimer::singleShot(0, this, SLOT(init()));
+}
+
+InstallDialog::~InstallDialog()
+{
+ TRACE_OBJ
+}
+
+QStringList InstallDialog::installedDocumentations() const
+{
+ TRACE_OBJ
+ return m_installedDocumentations;
+}
+
+void InstallDialog::init()
+{
+ TRACE_OBJ
+ m_ui.statusLabel->setText(tr("Downloading documentation info..."));
+ m_ui.progressBar->show();
+
+ QUrl url(QLatin1String("http://qt.nokia.com/doc/assistantdocs/docs.txt"));
+ m_buffer = new QBuffer();
+ m_buffer->open(QBuffer::ReadWrite);
+
+ if (m_port > -1)
+ m_http->setProxy(m_host, m_port);
+ m_http->setHost(url.host());
+ m_httpAborted = false;
+ m_docInfoId = m_http->get(url.path(), m_buffer);
+
+ m_ui.cancelButton->setEnabled(true);
+ m_ui.closeButton->setEnabled(false);
+}
+
+void InstallDialog::updateInstallButton()
+{
+ TRACE_OBJ
+ QListWidgetItem *item = 0;
+ for (int i=0; i<m_ui.listWidget->count(); ++i) {
+ item = m_ui.listWidget->item(i);
+ if (item->checkState() == Qt::Checked
+ && item->flags() & Qt::ItemIsEnabled) {
+ m_ui.installButton->setEnabled(true);
+ return;
+ }
+ }
+ m_ui.installButton->setEnabled(false);
+}
+
+void InstallDialog::updateDocItemList()
+{
+ TRACE_OBJ
+ QStringList registeredDocs = m_helpEngine->registeredDocumentations();
+ QListWidgetItem *item = 0;
+ for (int i=0; i<m_ui.listWidget->count(); ++i) {
+ item = m_ui.listWidget->item(i);
+ QString ns = item->data(QCH_NAMESPACE).toString();
+ if (!ns.isEmpty() && registeredDocs.contains(ns)) {
+ item->setFlags(Qt::ItemIsUserCheckable);
+ item->setCheckState(Qt::Checked);
+ }
+ item->setCheckState(Qt::Unchecked);
+ }
+}
+
+void InstallDialog::cancelDownload()
+{
+ TRACE_OBJ
+ m_ui.statusLabel->setText(tr("Download canceled."));
+ m_httpAborted = true;
+ m_itemsToInstall.clear();
+ m_http->abort();
+ m_ui.cancelButton->setEnabled(false);
+ m_ui.closeButton->setEnabled(true);
+ updateInstallButton();
+}
+
+void InstallDialog::install()
+{
+ TRACE_OBJ
+ QListWidgetItem *item = 0;
+ for (int i=0; i<m_ui.listWidget->count(); ++i) {
+ item = m_ui.listWidget->item(i);
+ if (item->checkState() == Qt::Checked)
+ m_itemsToInstall.append(item);
+ }
+ m_ui.installButton->setEnabled(false);
+ downloadNextFile();
+}
+
+void InstallDialog::downloadNextFile()
+{
+ TRACE_OBJ
+ if (!m_itemsToInstall.count()) {
+ m_ui.cancelButton->setEnabled(false);
+ m_ui.closeButton->setEnabled(true);
+ m_ui.statusLabel->setText(tr("Done."));
+ m_ui.progressBar->hide();
+ updateDocItemList();
+ updateInstallButton();
+ return;
+ }
+
+ QListWidgetItem *item = m_itemsToInstall.dequeue();
+ m_currentCheckSum = item->data(QCH_CHECKSUM).toString();
+ QString fileName = item->data(QCH_FILENAME).toString();
+ QString saveFileName = m_ui.pathLineEdit->text() + QDir::separator()
+ + fileName;
+
+ if (QFile::exists(saveFileName)
+ && QMessageBox::information(this, m_windowTitle,
+ tr("The file %1 already exists. Do you want to overwrite it?")
+ .arg(saveFileName), QMessageBox::Yes | QMessageBox::No,
+ QMessageBox::Yes) == QMessageBox::No) {
+ installFile(saveFileName);
+ downloadNextFile();
+ return;
+ }
+
+ m_file = new QFile(saveFileName);
+ if (!m_file->open(QIODevice::WriteOnly|QIODevice::Truncate)) {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Unable to save the file %1: %2.")
+ .arg(saveFileName).arg(m_file->errorString()));
+ delete m_file;
+ m_file = 0;
+ downloadNextFile();
+ return;
+ }
+
+ m_ui.statusLabel->setText(tr("Downloading %1...").arg(fileName));
+ m_ui.progressBar->show();
+
+ QLatin1String urlStr("http://qt.nokia.com/doc/assistantdocs/%1");
+ QUrl url(QString(urlStr).arg(fileName));
+
+ m_httpAborted = false;
+ m_docId = m_http->get(url.path(), m_file);
+
+ m_ui.cancelButton->setEnabled(true);
+ m_ui.closeButton->setEnabled(false);
+}
+
+void InstallDialog::httpRequestFinished(int requestId, bool error)
+{
+ TRACE_OBJ
+ if (requestId == m_docInfoId && m_buffer) {
+ m_ui.progressBar->hide();
+ if (error) {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Download failed: %1.")
+ .arg(m_http->errorString()));
+ } else if (!m_httpAborted) {
+ QStringList registeredDocs = m_helpEngine->registeredDocumentations();
+ m_buffer->seek(0);
+ while (m_buffer->canReadLine()) {
+ QByteArray ba = m_buffer->readLine();
+ QStringList lst = QString::fromAscii(ba.constData()).split(QLatin1Char('|'));
+ if (lst.count() != 4) {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Documentation info file is corrupt!"));
+ } else {
+ QListWidgetItem *item = new QListWidgetItem(m_ui.listWidget);
+ item->setText(lst.at(2).trimmed());
+ item->setData(QCH_FILENAME, lst.first());
+ item->setData(QCH_NAMESPACE, lst.at(1));
+ item->setData(QCH_CHECKSUM, lst.last().trimmed());
+ }
+ }
+ updateDocItemList();
+ }
+ if (m_buffer)
+ m_buffer->close();
+ delete m_buffer;
+ m_buffer = 0;
+ m_ui.statusLabel->setText(tr("Done."));
+ m_ui.cancelButton->setEnabled(false);
+ m_ui.closeButton->setEnabled(true);
+ updateInstallButton();
+ } else if (requestId == m_docId) {
+ m_file->close();
+ if (!m_httpAborted) {
+ QString checkSum;
+ if (m_file->open(QIODevice::ReadOnly)) {
+ QByteArray digest = QCryptographicHash::hash(m_file->readAll(),
+ QCryptographicHash::Md5);
+ m_file->close();
+ checkSum = QString::fromLatin1(digest.toHex());
+ }
+ if (error) {
+ m_file->remove();
+ QMessageBox::warning(this, m_windowTitle,
+ tr("Download failed: %1.")
+ .arg(m_http->errorString()));
+ } else if (checkSum.isEmpty() || m_currentCheckSum != checkSum) {
+ m_file->remove();
+ QMessageBox::warning(this, m_windowTitle,
+ tr("Download failed: Downloaded file is corrupted."));
+ } else {
+ m_ui.statusLabel->setText(tr("Installing documentation %1...")
+ .arg(QFileInfo(m_file->fileName()).fileName()));
+ m_ui.progressBar->setMaximum(0);
+ m_ui.statusLabel->setText(tr("Done."));
+ installFile(m_file->fileName());
+ }
+ } else {
+ m_file->remove();
+ }
+ delete m_file;
+ m_file = 0;
+ downloadNextFile();
+ }
+}
+
+void InstallDialog::installFile(const QString &fileName)
+{
+ TRACE_OBJ
+ if (m_helpEngine->registerDocumentation(fileName)) {
+ m_installedDocumentations
+ .append(QHelpEngineCore::namespaceName(fileName));
+ } else {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Error while installing documentation:\n%1")
+ .arg(m_helpEngine->error()));
+ }
+}
+
+void InstallDialog::readResponseHeader(const QHttpResponseHeader &responseHeader)
+{
+ TRACE_OBJ
+ if (responseHeader.statusCode() != 200) {
+ QMessageBox::information(this, m_windowTitle,
+ tr("Download failed: %1.")
+ .arg(responseHeader.reasonPhrase()));
+ m_httpAborted = true;
+ m_ui.progressBar->hide();
+ m_http->abort();
+ return;
+ }
+}
+
+void InstallDialog::updateDataReadProgress(int bytesRead, int totalBytes)
+{
+ TRACE_OBJ
+ if (m_httpAborted)
+ return;
+
+ m_ui.progressBar->setMaximum(totalBytes);
+ m_ui.progressBar->setValue(bytesRead);
+}
+
+void InstallDialog::browseDirectories()
+{
+ TRACE_OBJ
+ QString dir = QFileDialog::getExistingDirectory(this, m_windowTitle,
+ m_ui.pathLineEdit->text());
+ if (!dir.isEmpty())
+ m_ui.pathLineEdit->setText(dir);
+}
+
+#endif
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/installdialog.h b/src/assistant/tools/assistant/installdialog.h
new file mode 100644
index 000000000..0fb45a130
--- /dev/null
+++ b/src/assistant/tools/assistant/installdialog.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INSTALLDIALOG_H
+#define INSTALLDIALOG_H
+
+#include <QtCore/QQueue>
+#include <QtGui/QDialog>
+#include <QtNetwork/QHttpResponseHeader>
+#include "ui_installdialog.h"
+
+#ifndef QT_NO_HTTP
+
+QT_BEGIN_NAMESPACE
+
+class QHttp;
+class QBuffer;
+class QFile;
+class QHelpEngineCore;
+
+class InstallDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit InstallDialog(QHelpEngineCore *helpEngine, QWidget *parent = 0,
+ const QString &host = QString(), int port = -1);
+ ~InstallDialog();
+
+ QStringList installedDocumentations() const;
+
+private slots:
+ void init();
+ void cancelDownload();
+ void install();
+ void httpRequestFinished(int requestId, bool error);
+ void readResponseHeader(const QHttpResponseHeader &responseHeader);
+ void updateDataReadProgress(int bytesRead, int totalBytes);
+ void updateInstallButton();
+ void browseDirectories();
+
+private:
+ void downloadNextFile();
+ void updateDocItemList();
+ void installFile(const QString &fileName);
+
+ Ui::InstallDialog m_ui;
+ QHelpEngineCore *m_helpEngine;
+ QHttp *m_http;
+ QBuffer *m_buffer;
+ QFile *m_file;
+ bool m_httpAborted;
+ int m_docInfoId;
+ int m_docId;
+ QQueue<QListWidgetItem*> m_itemsToInstall;
+ QString m_currentCheckSum;
+ QString m_windowTitle;
+ QStringList m_installedDocumentations;
+ QString m_host;
+ int m_port;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
+#endif // INSTALLDIALOG_H
diff --git a/src/assistant/tools/assistant/installdialog.ui b/src/assistant/tools/assistant/installdialog.ui
new file mode 100644
index 000000000..21a05da77
--- /dev/null
+++ b/src/assistant/tools/assistant/installdialog.ui
@@ -0,0 +1,118 @@
+<ui version="4.0" >
+ <class>InstallDialog</class>
+ <widget class="QDialog" name="InstallDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>436</width>
+ <height>245</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Install Documentation</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="4" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Available Documentation:</string>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="4" row="1" column="0" colspan="4" >
+ <widget class="QListWidget" name="listWidget" />
+ </item>
+ <item row="1" column="4" >
+ <widget class="QPushButton" name="installButton" >
+ <property name="text" >
+ <string>Install</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4" >
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4" >
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="4" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>56</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Installation Path:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" colspan="2" >
+ <widget class="QLineEdit" name="pathLineEdit" />
+ </item>
+ <item row="5" column="3" >
+ <widget class="QToolButton" name="browseButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="5" >
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="2" >
+ <widget class="QLabel" name="statusLabel" />
+ </item>
+ <item row="7" column="2" colspan="3" >
+ <widget class="QProgressBar" name="progressBar" >
+ <property name="value" >
+ <number>0</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>closeButton</sender>
+ <signal>clicked()</signal>
+ <receiver>InstallDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>330</x>
+ <y>107</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>332</x>
+ <y>158</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/assistant/tools/assistant/main.cpp b/src/assistant/tools/assistant/main.cpp
new file mode 100644
index 000000000..84972c546
--- /dev/null
+++ b/src/assistant/tools/assistant/main.cpp
@@ -0,0 +1,440 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QLocale>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QStringList>
+#include <QtCore/QTranslator>
+#include <QtCore/QUrl>
+
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopServices>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpSearchEngine>
+
+#include <QtNetwork/QLocalSocket>
+
+#include <QtSql/QSqlDatabase>
+
+#include "../shared/collectionconfiguration.h"
+#include "helpenginewrapper.h"
+#include "mainwindow.h"
+#include "cmdlineparser.h"
+
+// #define TRACING_REQUESTED
+
+QT_USE_NAMESPACE
+
+#if defined(USE_STATIC_SQLITE_PLUGIN)
+ #include <QtPlugin>
+ Q_IMPORT_PLUGIN(qsqlite)
+#endif
+
+namespace {
+
+void
+updateLastPagesOnUnregister(QHelpEngineCore& helpEngine, const QString& nsName)
+{
+ TRACE_OBJ
+ int lastPage = CollectionConfiguration::lastTabPage(helpEngine);
+ QStringList currentPages = CollectionConfiguration::lastShownPages(helpEngine);
+ if (!currentPages.isEmpty()) {
+ QStringList zoomList = CollectionConfiguration::lastZoomFactors(helpEngine);
+ while (zoomList.count() < currentPages.count())
+ zoomList.append(CollectionConfiguration::DefaultZoomFactor);
+
+ for (int i = currentPages.count(); --i >= 0;) {
+ if (QUrl(currentPages.at(i)).host() == nsName) {
+ zoomList.removeAt(i);
+ currentPages.removeAt(i);
+ lastPage = (lastPage == (i + 1)) ? 1 : lastPage;
+ }
+ }
+
+ CollectionConfiguration::setLastShownPages(helpEngine, currentPages);
+ CollectionConfiguration::setLastTabPage(helpEngine, lastPage);
+ CollectionConfiguration::setLastZoomFactors(helpEngine, zoomList);
+ }
+}
+
+bool
+updateUserCollection(QHelpEngineCore& user, const QHelpEngineCore& caller)
+{
+ TRACE_OBJ
+ if (!CollectionConfiguration::isNewer(caller, user))
+ return false;
+ CollectionConfiguration::copyConfiguration(caller, user);
+ return true;
+}
+
+void stripNonexistingDocs(QHelpEngineCore& collection)
+{
+ TRACE_OBJ
+ const QStringList &namespaces = collection.registeredDocumentations();
+ foreach (const QString &ns, namespaces) {
+ QFileInfo fi(collection.documentationFileName(ns));
+ if (!fi.exists() || !fi.isFile())
+ collection.unregisterDocumentation(ns);
+ }
+}
+
+QString indexFilesFolder(const QString &collectionFile)
+{
+ TRACE_OBJ
+ QString indexFilesFolder = QLatin1String(".fulltextsearch");
+ if (!collectionFile.isEmpty()) {
+ QFileInfo fi(collectionFile);
+ indexFilesFolder = QLatin1Char('.') +
+ fi.fileName().left(fi.fileName().lastIndexOf(QLatin1String(".qhc")));
+ }
+ return indexFilesFolder;
+}
+
+/*
+ * Returns the expected absolute file path of the cached collection file
+ * correspondinging to the given collection's file.
+ * It may or may not exist yet.
+ */
+QString constructCachedCollectionFilePath(const QHelpEngineCore &collection)
+{
+ TRACE_OBJ
+ const QString &filePath = collection.collectionFile();
+ const QString &fileName = QFileInfo(filePath).fileName();
+ const QString &cacheDir = CollectionConfiguration::cacheDir(collection);
+ const QString &dir = !cacheDir.isEmpty()
+ && CollectionConfiguration::cacheDirIsRelativeToCollection(collection)
+ ? QFileInfo(filePath).dir().absolutePath()
+ + QDir::separator() + cacheDir
+ : MainWindow::collectionFileDirectory(false, cacheDir);
+ return dir + QDir::separator() + fileName;
+}
+
+bool synchronizeDocs(QHelpEngineCore &collection,
+ QHelpEngineCore &cachedCollection,
+ CmdLineParser &cmd)
+{
+ TRACE_OBJ
+ const QDateTime &lastCollectionRegisterTime =
+ CollectionConfiguration::lastRegisterTime(collection);
+ if (!lastCollectionRegisterTime.isValid() || lastCollectionRegisterTime
+ < CollectionConfiguration::lastRegisterTime(cachedCollection))
+ return true;
+
+ const QStringList &docs = collection.registeredDocumentations();
+ const QStringList &cachedDocs = cachedCollection.registeredDocumentations();
+
+ /*
+ * Ensure that the cached collection contains all docs that
+ * the collection contains.
+ */
+ foreach (const QString &doc, docs) {
+ if (!cachedDocs.contains(doc)) {
+ const QString &docFile = collection.documentationFileName(doc);
+ if (!cachedCollection.registerDocumentation(docFile)) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Error registering documentation file '%1': %2").
+ arg(docFile).arg(cachedCollection.error()), true);
+ return false;
+ }
+ }
+ }
+
+ CollectionConfiguration::updateLastRegisterTime(cachedCollection);
+
+ return true;
+}
+
+bool removeSearchIndex(const QString &collectionFile)
+{
+ TRACE_OBJ
+ QString path = QFileInfo(collectionFile).path();
+ path += QLatin1Char('/') + indexFilesFolder(collectionFile);
+
+ QLocalSocket localSocket;
+ localSocket.connectToServer(QString(QLatin1String("QtAssistant%1"))
+ .arg(QLatin1String(QT_VERSION_STR)));
+
+ QDir dir(path); // check if there is no other instance ruinning
+ if (!dir.exists() || localSocket.waitForConnected())
+ return false;
+
+ QStringList lst = dir.entryList(QDir::Files | QDir::Hidden);
+ foreach (const QString &item, lst)
+ dir.remove(item);
+ return true;
+}
+
+bool rebuildSearchIndex(QCoreApplication &app, const QString &collectionFile,
+ CmdLineParser &cmd)
+{
+ TRACE_OBJ
+ QHelpEngine engine(collectionFile);
+ if (!engine.setupData()) {
+ cmd.showMessage(QCoreApplication::translate("Assistant", "Error: %1")
+ .arg(engine.error()), true);
+ return false;
+ }
+
+ QHelpSearchEngine * const searchEngine = engine.searchEngine();
+ QObject::connect(searchEngine, SIGNAL(indexingFinished()), &app,
+ SLOT(quit()));
+ searchEngine->reindexDocumentation();
+ return app.exec() == 0;
+}
+
+bool useGui(int argc, char *argv[])
+{
+ TRACE_OBJ
+ bool gui = true;
+#ifndef Q_OS_WIN
+ // Look for arguments that imply command-line mode.
+ const char * cmdModeArgs[] = {
+ "-help", "-register", "-unregister", "-remove-search-index",
+ "-rebuild-search-index"
+ };
+ for (int i = 1; i < argc; ++i) {
+ for (size_t j = 0; j < sizeof cmdModeArgs/sizeof *cmdModeArgs; ++j) {
+ if(strcmp(argv[i], cmdModeArgs[j]) == 0) {
+ gui = false;
+ break;
+ }
+ }
+ }
+#else
+ Q_UNUSED(argc)
+ Q_UNUSED(argv)
+#endif
+ return gui;
+}
+
+bool registerDocumentation(QHelpEngineCore &collection, CmdLineParser &cmd,
+ bool printSuccess)
+{
+ TRACE_OBJ
+ if (!collection.registerDocumentation(cmd.helpFile())) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Could not register documentation file\n%1\n\nReason:\n%2")
+ .arg(cmd.helpFile()).arg(collection.error()), true);
+ return false;
+ }
+ if (printSuccess)
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Documentation successfully registered."),
+ false);
+ CollectionConfiguration::updateLastRegisterTime(collection);
+ return true;
+}
+
+bool unregisterDocumentation(QHelpEngineCore &collection,
+ const QString &namespaceName, CmdLineParser &cmd, bool printSuccess)
+{
+ TRACE_OBJ
+ if (!collection.unregisterDocumentation(namespaceName)) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Could not unregister documentation"
+ " file\n%1\n\nReason:\n%2").
+ arg(cmd.helpFile()).arg(collection.error()), true);
+ return false;
+ }
+ updateLastPagesOnUnregister(collection, namespaceName);
+ if (printSuccess)
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Documentation successfully unregistered."),
+ false);
+ return true;
+}
+
+void setupTranslation(const QString &fileName, const QString &dir)
+{
+ QTranslator *translator = new QTranslator(QCoreApplication::instance());
+ if (translator->load(fileName, dir)) {
+ QCoreApplication::installTranslator(translator);
+ } else if (!fileName.endsWith(QLatin1String("en_US"))
+ && !fileName.endsWith(QLatin1String("_C"))) {
+ qWarning("Could not load translation file %s in directory %s.",
+ qPrintable(fileName), qPrintable(dir));
+ }
+}
+
+void setupTranslations()
+{
+ TRACE_OBJ
+ const QString& locale = QLocale::system().name();
+ const QString &resourceDir
+ = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ setupTranslation(QLatin1String("assistant_") + locale, resourceDir);
+ setupTranslation(QLatin1String("qt_") + locale, resourceDir);
+ setupTranslation(QLatin1String("qt_help_") + locale, resourceDir);
+}
+
+} // Anonymous namespace.
+
+int main(int argc, char *argv[])
+{
+ TRACE_OBJ
+ QApplication a(argc, argv, useGui(argc, argv));
+ a.addLibraryPath(a.applicationDirPath() + QLatin1String("/plugins"));
+ setupTranslations();
+
+ // Parse arguments.
+ CmdLineParser cmd(a.arguments());
+ CmdLineParser::Result res = cmd.parse();
+ if (res == CmdLineParser::Help)
+ return 0;
+ else if (res == CmdLineParser::Error)
+ return -1;
+
+ /*
+ * Create the collection objects that we need. We always have the
+ * cached collection file. Depending on whether the user specified
+ * one, we also may have an input collection file.
+ */
+ const QString collectionFile = cmd.collectionFile();
+ const bool collectionFileGiven = !collectionFile.isEmpty();
+ QScopedPointer<QHelpEngineCore> collection;
+ if (collectionFileGiven) {
+ collection.reset(new QHelpEngineCore(collectionFile));
+ if (!collection->setupData()) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Error reading collection file '%1': %2.").
+ arg(collectionFile).arg(collection->error()), true);
+ return EXIT_FAILURE;
+ }
+ }
+ const QString &cachedCollectionFile = collectionFileGiven
+ ? constructCachedCollectionFilePath(*collection)
+ : MainWindow::defaultHelpCollectionFileName();
+ if (collectionFileGiven && !QFileInfo(cachedCollectionFile).exists()
+ && !collection->copyCollectionFile(cachedCollectionFile)) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Error creating collection file '%1': %2.").
+ arg(cachedCollectionFile).arg(collection->error()), true);
+ return EXIT_FAILURE;
+ }
+ QHelpEngineCore cachedCollection(cachedCollectionFile);
+ if (!cachedCollection.setupData()) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Error reading collection file '%1': %2.").
+ arg(cachedCollectionFile).
+ arg(cachedCollection.error()), true);
+ return EXIT_FAILURE;
+ }
+
+ stripNonexistingDocs(cachedCollection);
+ if (collectionFileGiven) {
+ if (CollectionConfiguration::isNewer(*collection, cachedCollection))
+ CollectionConfiguration::copyConfiguration(*collection,
+ cachedCollection);
+ if (!synchronizeDocs(*collection, cachedCollection, cmd))
+ return EXIT_FAILURE;
+ }
+
+ if (cmd.registerRequest() != CmdLineParser::None) {
+ const QStringList &cachedDocs =
+ cachedCollection.registeredDocumentations();
+ const QString &namespaceName =
+ QHelpEngineCore::namespaceName(cmd.helpFile());
+ if (cmd.registerRequest() == CmdLineParser::Register) {
+ if (collectionFileGiven
+ && !registerDocumentation(*collection, cmd, true))
+ return EXIT_FAILURE;
+ if (!cachedDocs.contains(namespaceName)
+ && !registerDocumentation(cachedCollection, cmd, !collectionFileGiven))
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
+ }
+ if (cmd.registerRequest() == CmdLineParser::Unregister) {
+ if (collectionFileGiven
+ && !unregisterDocumentation(*collection, namespaceName, cmd, true))
+ return EXIT_FAILURE;
+ if (cachedDocs.contains(namespaceName)
+ && !unregisterDocumentation(cachedCollection, namespaceName,
+ cmd, !collectionFileGiven))
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
+ }
+ }
+
+ if (cmd.removeSearchIndex()) {
+ return removeSearchIndex(cachedCollectionFile)
+ ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+
+ if (cmd.rebuildSearchIndex()) {
+ return rebuildSearchIndex(a, cachedCollectionFile, cmd)
+ ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+
+ if (!QSqlDatabase::isDriverAvailable(QLatin1String("QSQLITE"))) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Cannot load sqlite database driver!"),
+ true);
+ return EXIT_FAILURE;
+ }
+
+ if (!cmd.currentFilter().isEmpty()) {
+ if (collectionFileGiven)
+ collection->setCurrentFilter(cmd.currentFilter());
+ cachedCollection.setCurrentFilter(cmd.currentFilter());
+ }
+
+ if (collectionFileGiven)
+ cmd.setCollectionFile(cachedCollectionFile);
+
+ MainWindow *w = new MainWindow(&cmd);
+ w->show();
+ a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
+
+ /*
+ * We need to be careful here: The main window has to be deleted before
+ * the help engine wrapper, which has to be deleted before the
+ * QApplication.
+ */
+ const int retval = a.exec();
+ delete w;
+ HelpEngineWrapper::removeInstance();
+ return retval;
+}
diff --git a/src/assistant/tools/assistant/mainwindow.cpp b/src/assistant/tools/assistant/mainwindow.cpp
new file mode 100644
index 000000000..342fc76da
--- /dev/null
+++ b/src/assistant/tools/assistant/mainwindow.cpp
@@ -0,0 +1,1099 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+
+#include "aboutdialog.h"
+#include "bookmarkmanager.h"
+#include "centralwidget.h"
+#include "cmdlineparser.h"
+#include "contentwindow.h"
+#include "globalactions.h"
+#include "helpenginewrapper.h"
+#include "indexwindow.h"
+#include "openpagesmanager.h"
+#include "preferencesdialog.h"
+#include "qtdocinstaller.h"
+#include "remotecontrol.h"
+#include "searchwidget.h"
+#include "topicchooser.h"
+#include "tracer.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QDateTime>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QPair>
+#include <QtCore/QResource>
+#include <QtCore/QTextStream>
+#include <QtCore/QTimer>
+
+#include <QtGui/QAction>
+#include <QtGui/QComboBox>
+#include <QtGui/QDesktopServices>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QDockWidget>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QFileDialog>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QMenuBar>
+#include <QtGui/QMessageBox>
+#include <QtGui/QProgressBar>
+#include <QtGui/QShortcut>
+#include <QtGui/QStatusBar>
+#include <QtGui/QToolBar>
+#include <QtGui/QToolButton>
+
+#include <QtHelp/QHelpContentModel>
+#include <QtHelp/QHelpEngineCore>
+#include <QtHelp/QHelpIndexModel>
+#include <QtHelp/QHelpSearchEngine>
+
+#include <cstdlib>
+
+QT_BEGIN_NAMESPACE
+
+MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
+ : QMainWindow(parent)
+ , m_bookmarkWidget(0)
+ , m_filterCombo(0)
+ , m_toolBarMenu(0)
+ , m_cmdLine(cmdLine)
+ , m_progressWidget(0)
+ , m_qtDocInstaller(0)
+ , m_connectedInitSignals(false)
+{
+ TRACE_OBJ
+
+ setToolButtonStyle(Qt::ToolButtonFollowStyle);
+ setDockOptions(dockOptions() | AllowNestedDocks);
+
+ QString collectionFile;
+ if (usesDefaultCollection()) {
+ MainWindow::collectionFileDirectory(true);
+ collectionFile = MainWindow::defaultHelpCollectionFileName();
+ } else {
+ collectionFile = cmdLine->collectionFile();
+ }
+ HelpEngineWrapper &helpEngineWrapper =
+ HelpEngineWrapper::instance(collectionFile);
+ BookmarkManager *bookMarkManager = BookmarkManager::instance();
+
+ if (!initHelpDB(!cmdLine->collectionFileGiven())) {
+ qDebug("Fatal error: Help engine initialization failed. "
+ "Error message was: %s\nAssistant will now exit.",
+ qPrintable(HelpEngineWrapper::instance().error()));
+ std::exit(1);
+ }
+
+ m_centralWidget = new CentralWidget(this);
+ setCentralWidget(m_centralWidget);
+
+ m_indexWindow = new IndexWindow(this);
+ QDockWidget *indexDock = new QDockWidget(tr("Index"), this);
+ indexDock->setObjectName(QLatin1String("IndexWindow"));
+ indexDock->setWidget(m_indexWindow);
+ addDockWidget(Qt::LeftDockWidgetArea, indexDock);
+
+ m_contentWindow = new ContentWindow;
+ QDockWidget *contentDock = new QDockWidget(tr("Contents"), this);
+ contentDock->setObjectName(QLatin1String("ContentWindow"));
+ contentDock->setWidget(m_contentWindow);
+ addDockWidget(Qt::LeftDockWidgetArea, contentDock);
+
+ m_searchWindow = new SearchWidget(helpEngineWrapper.searchEngine());
+ m_searchWindow->setFont(!helpEngineWrapper.usesBrowserFont() ? qApp->font()
+ : helpEngineWrapper.browserFont());
+ QDockWidget *searchDock = new QDockWidget(tr("Search"), this);
+ searchDock->setObjectName(QLatin1String("SearchWindow"));
+ searchDock->setWidget(m_searchWindow);
+ addDockWidget(Qt::LeftDockWidgetArea, searchDock);
+
+ QDockWidget *bookmarkDock = new QDockWidget(tr("Bookmarks"), this);
+ bookmarkDock->setObjectName(QLatin1String("BookmarkWindow"));
+ bookmarkDock->setWidget(m_bookmarkWidget
+ = bookMarkManager->bookmarkDockWidget());
+ addDockWidget(Qt::LeftDockWidgetArea, bookmarkDock);
+
+ QDockWidget *openPagesDock = new QDockWidget(tr("Open Pages"), this);
+ openPagesDock->setObjectName(QLatin1String("Open Pages"));
+ OpenPagesManager *openPagesManager
+ = OpenPagesManager::createInstance(this, usesDefaultCollection(), m_cmdLine->url());
+ openPagesDock->setWidget(openPagesManager->openPagesWidget());
+ addDockWidget(Qt::LeftDockWidgetArea, openPagesDock);
+
+ connect(m_centralWidget, SIGNAL(addBookmark(QString, QString)),
+ bookMarkManager, SLOT(addBookmark(QString, QString)));
+ connect(bookMarkManager, SIGNAL(escapePressed()), this,
+ SLOT(activateCurrentCentralWidgetTab()));
+ connect(bookMarkManager, SIGNAL(setSource(QUrl)), m_centralWidget,
+ SLOT(setSource(QUrl)));
+ connect(bookMarkManager, SIGNAL(setSourceInNewTab(QUrl)),
+ openPagesManager, SLOT(createPage(QUrl)));
+
+ QHelpSearchEngine *searchEngine = helpEngineWrapper.searchEngine();
+ connect(searchEngine, SIGNAL(indexingStarted()), this, SLOT(indexingStarted()));
+ connect(searchEngine, SIGNAL(indexingFinished()), this, SLOT(indexingFinished()));
+
+ QString defWindowTitle = tr("Qt Assistant");
+ setWindowTitle(defWindowTitle);
+
+ setupActions();
+ statusBar()->show();
+ m_centralWidget->connectTabBar();
+
+ setupFilterToolbar();
+ setupAddressToolbar();
+
+ const QString windowTitle = helpEngineWrapper.windowTitle();
+ setWindowTitle(windowTitle.isEmpty() ? defWindowTitle : windowTitle);
+ QByteArray iconArray = helpEngineWrapper.applicationIcon();
+ if (iconArray.size() > 0) {
+ QPixmap pix;
+ pix.loadFromData(iconArray);
+ QIcon appIcon(pix);
+ qApp->setWindowIcon(appIcon);
+ } else {
+ QIcon appIcon(QLatin1String(":/trolltech/assistant/images/assistant-128.png"));
+ qApp->setWindowIcon(appIcon);
+ }
+
+ QToolBar *toolBar = addToolBar(tr("Bookmark Toolbar"));
+ toolBar->setObjectName(QLatin1String("Bookmark Toolbar"));
+ bookMarkManager->setBookmarksToolbar(toolBar);
+
+ // Show the widget here, otherwise the restore geometry and state won't work
+ // on x11.
+ show();
+
+ toolBar->hide();
+ toolBarMenu()->addAction(toolBar->toggleViewAction());
+
+ QByteArray ba(helpEngineWrapper.mainWindow());
+ if (!ba.isEmpty())
+ restoreState(ba);
+
+ ba = helpEngineWrapper.mainWindowGeometry();
+ if (!ba.isEmpty()) {
+ restoreGeometry(ba);
+ } else {
+ tabifyDockWidget(contentDock, indexDock);
+ tabifyDockWidget(indexDock, bookmarkDock);
+ tabifyDockWidget(bookmarkDock, searchDock);
+ contentDock->raise();
+ const QRect screen = QApplication::desktop()->screenGeometry();
+ resize(4*screen.width()/5, 4*screen.height()/5);
+ }
+
+ if (!helpEngineWrapper.hasFontSettings()) {
+ helpEngineWrapper.setUseAppFont(false);
+ helpEngineWrapper.setUseBrowserFont(false);
+ helpEngineWrapper.setAppFont(qApp->font());
+ helpEngineWrapper.setAppWritingSystem(QFontDatabase::Latin);
+ helpEngineWrapper.setBrowserFont(qApp->font());
+ helpEngineWrapper.setBrowserWritingSystem(QFontDatabase::Latin);
+ } else {
+ updateApplicationFont();
+ }
+
+ updateAboutMenuText();
+
+ QTimer::singleShot(0, this, SLOT(insertLastPages()));
+ if (m_cmdLine->enableRemoteControl())
+ (void)new RemoteControl(this);
+
+ if (m_cmdLine->contents() == CmdLineParser::Show)
+ showContents();
+ else if (m_cmdLine->contents() == CmdLineParser::Hide)
+ hideContents();
+
+ if (m_cmdLine->index() == CmdLineParser::Show)
+ showIndex();
+ else if (m_cmdLine->index() == CmdLineParser::Hide)
+ hideIndex();
+
+ if (m_cmdLine->bookmarks() == CmdLineParser::Show)
+ showBookmarksDockWidget();
+ else if (m_cmdLine->bookmarks() == CmdLineParser::Hide)
+ hideBookmarksDockWidget();
+
+ if (m_cmdLine->search() == CmdLineParser::Show)
+ showSearch();
+ else if (m_cmdLine->search() == CmdLineParser::Hide)
+ hideSearch();
+
+ if (m_cmdLine->contents() == CmdLineParser::Activate)
+ showContents();
+ else if (m_cmdLine->index() == CmdLineParser::Activate)
+ showIndex();
+ else if (m_cmdLine->bookmarks() == CmdLineParser::Activate)
+ showBookmarksDockWidget();
+
+ if (!m_cmdLine->currentFilter().isEmpty()) {
+ const QString &curFilter = m_cmdLine->currentFilter();
+ if (helpEngineWrapper.customFilters().contains(curFilter))
+ helpEngineWrapper.setCurrentFilter(curFilter);
+ }
+
+ if (usesDefaultCollection())
+ QTimer::singleShot(0, this, SLOT(lookForNewQtDocumentation()));
+ else
+ checkInitState();
+
+ connect(&helpEngineWrapper, SIGNAL(documentationRemoved(QString)),
+ this, SLOT(documentationRemoved(QString)));
+ connect(&helpEngineWrapper, SIGNAL(documentationUpdated(QString)),
+ this, SLOT(documentationUpdated(QString)));
+
+ setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
+ GlobalActions::instance()->updateActions();
+ if (helpEngineWrapper.addressBarEnabled())
+ showNewAddress();
+}
+
+MainWindow::~MainWindow()
+{
+ TRACE_OBJ
+ if (m_qtDocInstaller)
+ delete m_qtDocInstaller;
+}
+
+bool MainWindow::usesDefaultCollection() const
+{
+ TRACE_OBJ
+ return m_cmdLine->collectionFile().isEmpty();
+}
+
+void MainWindow::closeEvent(QCloseEvent *e)
+{
+ TRACE_OBJ
+ BookmarkManager::destroy();
+ HelpEngineWrapper::instance().setMainWindow(saveState());
+ HelpEngineWrapper::instance().setMainWindowGeometry(saveGeometry());
+ QMainWindow::closeEvent(e);
+}
+
+bool MainWindow::initHelpDB(bool registerInternalDoc)
+{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngineWrapper = HelpEngineWrapper::instance();
+ if (!helpEngineWrapper.setupData())
+ return false;
+
+ if (!registerInternalDoc) {
+ if (helpEngineWrapper.defaultHomePage() == QLatin1String("help"))
+ helpEngineWrapper.setDefaultHomePage(QLatin1String("about:blank"));
+ return true;
+ }
+ bool assistantInternalDocRegistered = false;
+ QString intern(QLatin1String("com.trolltech.com.assistantinternal-"));
+ foreach (const QString &ns, helpEngineWrapper.registeredDocumentations()) {
+ if (ns.startsWith(intern)) {
+ intern = ns;
+ assistantInternalDocRegistered = true;
+ break;
+ }
+ }
+
+ const QString &collectionFile = helpEngineWrapper.collectionFile();
+ QFileInfo fi(collectionFile);
+ QString helpFile;
+ QTextStream(&helpFile) << fi.absolutePath() << QDir::separator()
+ << QLatin1String("assistant.qch.") << (QT_VERSION >> 16)
+ << QLatin1Char('.') << ((QT_VERSION >> 8) & 0xFF);
+
+ bool needsSetup = false;
+ if (!assistantInternalDocRegistered || !QFile::exists(helpFile)) {
+ QFile file(helpFile);
+ if (file.open(QIODevice::WriteOnly)) {
+ QResource res(QLatin1String(":/trolltech/assistant/assistant.qch"));
+ if (file.write((const char*)res.data(), res.size()) != res.size())
+ qDebug() << QLatin1String("could not write assistant.qch...");
+
+ file.close();
+ }
+ helpEngineWrapper.unregisterDocumentation(intern);
+ helpEngineWrapper.registerDocumentation(helpFile);
+ needsSetup = true;
+ }
+
+ if (needsSetup)
+ helpEngineWrapper.setupData();
+ return true;
+}
+
+void MainWindow::lookForNewQtDocumentation()
+{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ QStringList docs;
+ docs << QLatin1String("assistant")
+ << QLatin1String("designer")
+ << QLatin1String("linguist")
+ << QLatin1String("qmake")
+ << QLatin1String("qt");
+ QList<QtDocInstaller::DocInfo> qtDocInfos;
+ foreach (const QString &doc, docs)
+ qtDocInfos.append(QtDocInstaller::DocInfo(doc, helpEngine.qtDocInfo(doc)));
+
+ m_qtDocInstaller = new QtDocInstaller(qtDocInfos);
+ connect(m_qtDocInstaller, SIGNAL(docsInstalled(bool)), this,
+ SLOT(qtDocumentationInstalled()));
+ connect(m_qtDocInstaller, SIGNAL(qchFileNotFound(QString)), this,
+ SLOT(resetQtDocInfo(QString)));
+ connect(m_qtDocInstaller, SIGNAL(registerDocumentation(QString, QString)),
+ this, SLOT(registerDocumentation(QString, QString)));
+ if (helpEngine.qtDocInfo(QLatin1String("qt")).count() != 2)
+ statusBar()->showMessage(tr("Looking for Qt Documentation..."));
+ m_qtDocInstaller->installDocs();
+}
+
+void MainWindow::qtDocumentationInstalled()
+{
+ TRACE_OBJ
+ statusBar()->clearMessage();
+ checkInitState();
+}
+
+void MainWindow::checkInitState()
+{
+ TRACE_OBJ
+ HelpEngineWrapper::instance().initialDocSetupDone();
+ if (!m_cmdLine->enableRemoteControl())
+ return;
+
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (helpEngine.contentModel()->isCreatingContents()
+ || helpEngine.indexModel()->isCreatingIndex()) {
+ if (!m_connectedInitSignals) {
+ connect(helpEngine.contentModel(), SIGNAL(contentsCreated()),
+ this, SLOT(checkInitState()));
+ connect(helpEngine.indexModel(), SIGNAL(indexCreated()), this,
+ SLOT(checkInitState()));
+ m_connectedInitSignals = true;
+ }
+ } else {
+ if (m_connectedInitSignals) {
+ disconnect(helpEngine.contentModel(), 0, this, 0);
+ disconnect(helpEngine.indexModel(), 0, this, 0);
+ }
+ emit initDone();
+ }
+}
+
+void MainWindow::insertLastPages()
+{
+ TRACE_OBJ
+ if (m_cmdLine->search() == CmdLineParser::Activate)
+ showSearch();
+}
+
+void MainWindow::setupActions()
+{
+ TRACE_OBJ
+ QString resourcePath = QLatin1String(":/trolltech/assistant/images/");
+#ifdef Q_OS_MAC
+ setUnifiedTitleAndToolBarOnMac(true);
+ resourcePath.append(QLatin1String("mac"));
+#else
+ resourcePath.append(QLatin1String("win"));
+#endif
+
+ QMenu *menu = menuBar()->addMenu(tr("&File"));
+
+ OpenPagesManager * const openPages = OpenPagesManager::instance();
+ m_newTabAction
+ = menu->addAction(tr("New &Tab"), openPages, SLOT(createPage()));
+ m_newTabAction->setShortcut(QKeySequence::AddTab);
+ m_closeTabAction = menu->addAction(tr("&Close Tab"),
+ openPages, SLOT(closeCurrentPage()));
+ m_closeTabAction->setShortcuts(QKeySequence::Close);
+
+ menu->addSeparator();
+
+ m_pageSetupAction = menu->addAction(tr("Page Set&up..."), m_centralWidget,
+ SLOT(pageSetup()));
+ m_printPreviewAction = menu->addAction(tr("Print Preview..."), m_centralWidget,
+ SLOT(printPreview()));
+
+ GlobalActions *globalActions = GlobalActions::instance(this);
+ menu->addAction(globalActions->printAction());
+ menu->addSeparator();
+
+ QIcon appExitIcon = QIcon::fromTheme("application-exit");
+ QAction *tmp;
+#ifdef Q_OS_WIN
+ tmp = menu->addAction(appExitIcon, tr("E&xit"), this, SLOT(close()));
+ tmp->setShortcut(QKeySequence(tr("CTRL+Q")));
+#else
+ tmp = menu->addAction(appExitIcon, tr("&Quit"), this, SLOT(close()));
+ tmp->setShortcut(QKeySequence::Quit);
+#endif
+ tmp->setMenuRole(QAction::QuitRole);
+
+ menu = menuBar()->addMenu(tr("&Edit"));
+ menu->addAction(globalActions->copyAction());
+ menu->addAction(globalActions->findAction());
+
+ QAction *findNextAction = menu->addAction(tr("Find &Next"), m_centralWidget,
+ SLOT(findNext()));
+ findNextAction->setShortcuts(QKeySequence::FindNext);
+
+ QAction *findPreviousAction = menu->addAction(tr("Find &Previous"),
+ m_centralWidget, SLOT(findPrevious()));
+ findPreviousAction->setShortcuts(QKeySequence::FindPrevious);
+
+ menu->addSeparator();
+ tmp = menu->addAction(tr("Preferences..."), this, SLOT(showPreferences()));
+ tmp->setMenuRole(QAction::PreferencesRole);
+
+ m_viewMenu = menuBar()->addMenu(tr("&View"));
+ m_viewMenu->addAction(globalActions->zoomInAction());
+ m_viewMenu->addAction(globalActions->zoomOutAction());
+
+ m_resetZoomAction = m_viewMenu->addAction(tr("Normal &Size"), m_centralWidget,
+ SLOT(resetZoom()));
+ m_resetZoomAction->setPriority(QAction::LowPriority);
+ m_resetZoomAction->setIcon(QIcon(resourcePath + QLatin1String("/resetzoom.png")));
+ m_resetZoomAction->setShortcut(tr("Ctrl+0"));
+
+ m_viewMenu->addSeparator();
+
+ m_viewMenu->addAction(tr("Contents"), this, SLOT(showContents()),
+ QKeySequence(tr("ALT+C")));
+ m_viewMenu->addAction(tr("Index"), this, SLOT(showIndex()),
+ QKeySequence(tr("ALT+I")));
+ m_viewMenu->addAction(tr("Bookmarks"), this, SLOT(showBookmarksDockWidget()),
+ QKeySequence(tr("ALT+O")));
+ m_viewMenu->addAction(tr("Search"), this, SLOT(showSearch()),
+ QKeySequence(tr("ALT+S")));
+ m_viewMenu->addAction(tr("Open Pages"), this, SLOT(showOpenPages()),
+ QKeySequence(tr("ALT+P")));
+
+ menu = menuBar()->addMenu(tr("&Go"));
+ menu->addAction(globalActions->homeAction());
+ menu->addAction(globalActions->backAction());
+ menu->addAction(globalActions->nextAction());
+
+ m_syncAction = menu->addAction(tr("Sync with Table of Contents"), this,
+ SLOT(syncContents()));
+ m_syncAction->setIconText(tr("Sync"));
+ m_syncAction->setIcon(QIcon(resourcePath + QLatin1String("/synctoc.png")));
+
+ menu->addSeparator();
+
+ tmp = menu->addAction(tr("Next Page"), openPages, SLOT(nextPage()));
+ tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Alt+Right"))
+ << QKeySequence(Qt::CTRL + Qt::Key_PageDown));
+
+ tmp = menu->addAction(tr("Previous Page"), openPages, SLOT(previousPage()));
+ tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Alt+Left"))
+ << QKeySequence(Qt::CTRL + Qt::Key_PageUp));
+
+#ifdef Q_WS_MAC
+ QShortcut *sct = new QShortcut(QKeySequence(Qt::ALT + Qt::Key_Tab), this);
+ connect(sct, SIGNAL(activated()), openPages, SLOT(nextPageWithSwitcher()));
+ sct = new QShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Tab), this);
+ connect(sct, SIGNAL(activated()), openPages, SLOT(previousPageWithSwitcher()));
+#else
+ QShortcut *sct = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Tab), this);
+ connect(sct, SIGNAL(activated()), openPages, SLOT(nextPageWithSwitcher()));
+ sct = new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab), this);
+ connect(sct, SIGNAL(activated()), openPages, SLOT(previousPageWithSwitcher()));
+#endif
+
+ BookmarkManager::instance()->setBookmarksMenu(menuBar()->addMenu(tr("&Bookmarks")));
+
+ menu = menuBar()->addMenu(tr("&Help"));
+ m_aboutAction = menu->addAction(tr("About..."), this, SLOT(showAboutDialog()));
+ m_aboutAction->setMenuRole(QAction::AboutRole);
+
+#ifdef Q_WS_X11
+ m_resetZoomAction->setIcon(QIcon::fromTheme("zoom-original" , m_resetZoomAction->icon()));
+ m_syncAction->setIcon(QIcon::fromTheme("view-refresh" , m_syncAction->icon()));
+#endif
+
+ QToolBar *navigationBar = addToolBar(tr("Navigation Toolbar"));
+ navigationBar->setObjectName(QLatin1String("NavigationToolBar"));
+ navigationBar->addAction(globalActions->backAction());
+ navigationBar->addAction(globalActions->nextAction());
+ navigationBar->addAction(globalActions->homeAction());
+ navigationBar->addAction(m_syncAction);
+ navigationBar->addSeparator();
+ navigationBar->addAction(globalActions->copyAction());
+ navigationBar->addAction(globalActions->printAction());
+ navigationBar->addAction(globalActions->findAction());
+ navigationBar->addSeparator();
+ navigationBar->addAction(globalActions->zoomInAction());
+ navigationBar->addAction(globalActions->zoomOutAction());
+ navigationBar->addAction(m_resetZoomAction);
+
+#if defined(Q_WS_MAC)
+ QMenu *windowMenu = new QMenu(tr("&Window"), this);
+ menuBar()->insertMenu(menu->menuAction(), windowMenu);
+ windowMenu->addAction(tr("Zoom"), this, SLOT(showMaximized()));
+ windowMenu->addAction(tr("Minimize"), this, SLOT(showMinimized()),
+ QKeySequence(tr("Ctrl+M")));
+#endif
+
+ // content viewer connections
+ connect(m_centralWidget, SIGNAL(copyAvailable(bool)), globalActions,
+ SLOT(setCopyAvailable(bool)));
+ connect(m_centralWidget, SIGNAL(currentViewerChanged()), globalActions,
+ SLOT(updateActions()));
+ connect(m_centralWidget, SIGNAL(forwardAvailable(bool)), globalActions,
+ SLOT(updateActions()));
+ connect(m_centralWidget, SIGNAL(backwardAvailable(bool)), globalActions,
+ SLOT(updateActions()));
+ connect(m_centralWidget, SIGNAL(highlighted(QString)), statusBar(),
+ SLOT(showMessage(QString)));
+
+ // index window
+ connect(m_indexWindow, SIGNAL(linkActivated(QUrl)), m_centralWidget,
+ SLOT(setSource(QUrl)));
+ connect(m_indexWindow, SIGNAL(linksActivated(QMap<QString,QUrl>,QString)),
+ this, SLOT(showTopicChooser(QMap<QString,QUrl>,QString)));
+ connect(m_indexWindow, SIGNAL(escapePressed()), this,
+ SLOT(activateCurrentCentralWidgetTab()));
+
+ // content window
+ connect(m_contentWindow, SIGNAL(linkActivated(QUrl)), m_centralWidget,
+ SLOT(setSource(QUrl)));
+ connect(m_contentWindow, SIGNAL(escapePressed()), this,
+ SLOT(activateCurrentCentralWidgetTab()));
+
+ // search window
+ connect(m_searchWindow, SIGNAL(requestShowLink(QUrl)),
+ CentralWidget::instance(), SLOT(setSourceFromSearch(QUrl)));
+ connect(m_searchWindow, SIGNAL(requestShowLinkInNewTab(QUrl)),
+ OpenPagesManager::instance(), SLOT(createNewPageFromSearch(QUrl)));
+
+#if defined(QT_NO_PRINTER)
+ m_pageSetupAction->setVisible(false);
+ m_printPreviewAction->setVisible(false);
+ m_printAction->setVisible(false);
+#endif
+}
+
+QMenu *MainWindow::toolBarMenu()
+{
+ TRACE_OBJ
+ if (!m_toolBarMenu) {
+ m_viewMenu->addSeparator();
+ m_toolBarMenu = m_viewMenu->addMenu(tr("Toolbars"));
+ }
+ return m_toolBarMenu;
+}
+
+void MainWindow::setupFilterToolbar()
+{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (!helpEngine.filterFunctionalityEnabled())
+ return;
+
+ m_filterCombo = new QComboBox(this);
+ m_filterCombo->setMinimumWidth(QFontMetrics(QFont()).
+ width(QLatin1String("MakeTheComboBoxWidthEnough")));
+
+ QToolBar *filterToolBar = addToolBar(tr("Filter Toolbar"));
+ filterToolBar->setObjectName(QLatin1String("FilterToolBar"));
+ filterToolBar->addWidget(new QLabel(tr("Filtered by:").append(QLatin1Char(' ')),
+ this));
+ filterToolBar->addWidget(m_filterCombo);
+
+ if (!helpEngine.filterToolbarVisible())
+ filterToolBar->hide();
+ toolBarMenu()->addAction(filterToolBar->toggleViewAction());
+
+ connect(&helpEngine, SIGNAL(setupFinished()), this,
+ SLOT(setupFilterCombo()), Qt::QueuedConnection);
+ connect(m_filterCombo, SIGNAL(activated(QString)), this,
+ SLOT(filterDocumentation(QString)));
+ connect(&helpEngine, SIGNAL(currentFilterChanged(QString)), this,
+ SLOT(currentFilterChanged(QString)));
+
+ setupFilterCombo();
+}
+
+void MainWindow::setupAddressToolbar()
+{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (!helpEngine.addressBarEnabled())
+ return;
+
+ m_addressLineEdit = new QLineEdit(this);
+ QToolBar *addressToolBar = addToolBar(tr("Address Toolbar"));
+ addressToolBar->setObjectName(QLatin1String("AddressToolBar"));
+ insertToolBarBreak(addressToolBar);
+
+ addressToolBar->addWidget(new QLabel(tr("Address:").append(QLatin1String(" ")),
+ this));
+ addressToolBar->addWidget(m_addressLineEdit);
+
+ if (!helpEngine.addressBarVisible())
+ addressToolBar->hide();
+ toolBarMenu()->addAction(addressToolBar->toggleViewAction());
+
+ // address lineedit
+ connect(m_addressLineEdit, SIGNAL(returnPressed()), this,
+ SLOT(gotoAddress()));
+ connect(m_centralWidget, SIGNAL(currentViewerChanged()), this,
+ SLOT(showNewAddress()));
+ connect(m_centralWidget, SIGNAL(sourceChanged(QUrl)), this,
+ SLOT(showNewAddress(QUrl)));
+}
+
+void MainWindow::updateAboutMenuText()
+{
+ TRACE_OBJ
+ QByteArray ba = HelpEngineWrapper::instance().aboutMenuTexts();
+ if (ba.size() > 0) {
+ QString lang;
+ QString str;
+ QString trStr;
+ QString currentLang = QLocale::system().name();
+ int i = currentLang.indexOf(QLatin1Char('_'));
+ if (i > -1)
+ currentLang = currentLang.left(i);
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ while (!s.atEnd()) {
+ s >> lang;
+ s >> str;
+ if (lang == QLatin1String("default") && trStr.isEmpty()) {
+ trStr = str;
+ } else if (lang == currentLang) {
+ trStr = str;
+ break;
+ }
+ }
+ if (!trStr.isEmpty())
+ m_aboutAction->setText(trStr);
+ }
+}
+
+void MainWindow::showNewAddress()
+{
+ TRACE_OBJ
+ showNewAddress(m_centralWidget->currentSource());
+}
+
+void MainWindow::showNewAddress(const QUrl &url)
+{
+ TRACE_OBJ
+ m_addressLineEdit->setText(url.toString());
+}
+
+void MainWindow::gotoAddress()
+{
+ TRACE_OBJ
+ m_centralWidget->setSource(m_addressLineEdit->text());
+}
+
+void MainWindow::showTopicChooser(const QMap<QString, QUrl> &links,
+ const QString &keyword)
+{
+ TRACE_OBJ
+ TopicChooser tc(this, keyword, links);
+ if (tc.exec() == QDialog::Accepted) {
+ m_centralWidget->setSource(tc.link());
+ }
+}
+
+void MainWindow::showPreferences()
+{
+ TRACE_OBJ
+ PreferencesDialog dia(this);
+ connect(&dia, SIGNAL(updateApplicationFont()), this,
+ SLOT(updateApplicationFont()));
+ connect(&dia, SIGNAL(updateBrowserFont()), m_centralWidget,
+ SLOT(updateBrowserFont()));
+ connect(&dia, SIGNAL(updateUserInterface()), m_centralWidget,
+ SLOT(updateUserInterface()));
+ dia.showDialog();
+}
+
+void MainWindow::syncContents()
+{
+ TRACE_OBJ
+ qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
+ const QUrl url = m_centralWidget->currentSource();
+ showContents();
+ if (!m_contentWindow->syncToContent(url))
+ statusBar()->showMessage(
+ tr("Could not find the associated content item."), 3000);
+ qApp->restoreOverrideCursor();
+}
+
+void MainWindow::showAboutDialog()
+{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ QByteArray contents;
+ QByteArray ba = helpEngine.aboutTexts();
+ if (!ba.isEmpty()) {
+ QString lang;
+ QByteArray cba;
+ QString currentLang = QLocale::system().name();
+ int i = currentLang.indexOf(QLatin1Char('_'));
+ if (i > -1)
+ currentLang = currentLang.left(i);
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ while (!s.atEnd()) {
+ s >> lang;
+ s >> cba;
+ if (lang == QLatin1String("default") && contents.isEmpty()) {
+ contents = cba;
+ } else if (lang == currentLang) {
+ contents = cba;
+ break;
+ }
+ }
+ }
+
+ AboutDialog aboutDia(this);
+
+ QByteArray iconArray;
+ if (!contents.isEmpty()) {
+ iconArray = helpEngine.aboutIcon();
+ QByteArray resources = helpEngine.aboutImages();
+ QPixmap pix;
+ pix.loadFromData(iconArray);
+ aboutDia.setText(QString::fromUtf8(contents), resources);
+ if (!pix.isNull())
+ aboutDia.setPixmap(pix);
+ aboutDia.setWindowTitle(aboutDia.documentTitle());
+ } else {
+ QByteArray resources;
+ aboutDia.setText(tr("<center>"
+ "<h3>%1</h3>"
+ "<p>Version %2</p></center>"
+ "<p>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).</p>")
+ .arg(tr("Qt Assistant")).arg(QLatin1String(QT_VERSION_STR)),
+ resources);
+ QLatin1String path(":/trolltech/assistant/images/assistant-128.png");
+ aboutDia.setPixmap(QString(path));
+ }
+ if (aboutDia.windowTitle().isEmpty())
+ aboutDia.setWindowTitle(tr("About %1").arg(windowTitle()));
+ aboutDia.exec();
+}
+
+void MainWindow::setContentsVisible(bool visible)
+{
+ TRACE_OBJ
+ if (visible)
+ showContents();
+ else
+ hideContents();
+}
+
+void MainWindow::showContents()
+{
+ TRACE_OBJ
+ activateDockWidget(m_contentWindow);
+}
+
+void MainWindow::hideContents()
+{
+ TRACE_OBJ
+ m_contentWindow->parentWidget()->hide();
+}
+
+void MainWindow::setIndexVisible(bool visible)
+{
+ TRACE_OBJ
+ if (visible)
+ showIndex();
+ else
+ hideIndex();
+}
+
+void MainWindow::showIndex()
+{
+ TRACE_OBJ
+ activateDockWidget(m_indexWindow);
+}
+
+void MainWindow::hideIndex()
+{
+ TRACE_OBJ
+ m_indexWindow->parentWidget()->hide();
+}
+
+void MainWindow::setBookmarksVisible(bool visible)
+{
+ TRACE_OBJ
+ if (visible)
+ showBookmarksDockWidget();
+ else
+ hideBookmarksDockWidget();
+}
+
+void MainWindow::showBookmarksDockWidget()
+{
+ TRACE_OBJ
+ activateDockWidget(m_bookmarkWidget);
+}
+
+void MainWindow::hideBookmarksDockWidget()
+{
+ TRACE_OBJ
+ m_bookmarkWidget->parentWidget()->hide();
+}
+
+void MainWindow::setSearchVisible(bool visible)
+{
+ TRACE_OBJ
+ if (visible)
+ showSearch();
+ else
+ hideSearch();
+}
+
+void MainWindow::showSearch()
+{
+ TRACE_OBJ
+ activateDockWidget(m_searchWindow);
+}
+
+void MainWindow::showOpenPages()
+{
+ TRACE_OBJ
+ activateDockWidget(OpenPagesManager::instance()->openPagesWidget());
+}
+
+void MainWindow::hideSearch()
+{
+ TRACE_OBJ
+ m_searchWindow->parentWidget()->hide();
+}
+
+void MainWindow::activateDockWidget(QWidget *w)
+{
+ TRACE_OBJ
+ w->parentWidget()->show();
+ w->parentWidget()->raise();
+ w->setFocus();
+}
+
+void MainWindow::setIndexString(const QString &str)
+{
+ TRACE_OBJ
+ m_indexWindow->setSearchLineEditText(str);
+}
+
+void MainWindow::activateCurrentBrowser()
+{
+ TRACE_OBJ
+ CentralWidget::instance()->activateTab();
+}
+
+void MainWindow::activateCurrentCentralWidgetTab()
+{
+ TRACE_OBJ
+ m_centralWidget->activateTab();
+}
+
+void MainWindow::updateApplicationFont()
+{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ QFont font = qApp->font();
+ if (helpEngine.usesAppFont())
+ font = helpEngine.appFont();
+
+ const QWidgetList &widgets = qApp->allWidgets();
+ foreach (QWidget* widget, widgets)
+ widget->setFont(font);
+}
+
+void MainWindow::setupFilterCombo()
+{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ QString curFilter = m_filterCombo->currentText();
+ if (curFilter.isEmpty())
+ curFilter = helpEngine.currentFilter();
+ m_filterCombo->clear();
+ m_filterCombo->addItems(helpEngine.customFilters());
+ int idx = m_filterCombo->findText(curFilter);
+ if (idx < 0)
+ idx = 0;
+ m_filterCombo->setCurrentIndex(idx);
+}
+
+void MainWindow::filterDocumentation(const QString &customFilter)
+{
+ TRACE_OBJ
+ HelpEngineWrapper::instance().setCurrentFilter(customFilter);
+}
+
+void MainWindow::expandTOC(int depth)
+{
+ TRACE_OBJ
+ Q_ASSERT(depth >= -1);
+ m_contentWindow->expandToDepth(depth);
+}
+
+void MainWindow::indexingStarted()
+{
+ TRACE_OBJ
+ if (!m_progressWidget) {
+ m_progressWidget = new QWidget();
+ QLayout* hlayout = new QHBoxLayout(m_progressWidget);
+
+ QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
+
+ QLabel *label = new QLabel(tr("Updating search index"));
+ label->setSizePolicy(sizePolicy);
+ hlayout->addWidget(label);
+
+ QProgressBar *progressBar = new QProgressBar();
+ progressBar->setRange(0, 0);
+ progressBar->setTextVisible(false);
+ progressBar->setSizePolicy(sizePolicy);
+
+ hlayout->setSpacing(6);
+ hlayout->setMargin(0);
+ hlayout->addWidget(progressBar);
+
+ statusBar()->addPermanentWidget(m_progressWidget);
+ }
+}
+
+void MainWindow::indexingFinished()
+{
+ TRACE_OBJ
+ statusBar()->removeWidget(m_progressWidget);
+ delete m_progressWidget;
+ m_progressWidget = 0;
+}
+
+QString MainWindow::collectionFileDirectory(bool createDir, const QString &cacheDir)
+{
+ TRACE_OBJ
+ QString collectionPath =
+ QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+ if (collectionPath.isEmpty()) {
+ if (cacheDir.isEmpty())
+ collectionPath = QDir::homePath() + QDir::separator()
+ + QLatin1String(".assistant");
+ else
+ collectionPath = QDir::homePath() + QLatin1String("/.") + cacheDir;
+ } else {
+ if (cacheDir.isEmpty())
+ collectionPath = collectionPath + QLatin1String("/Trolltech/Assistant");
+ else
+ collectionPath = collectionPath + QDir::separator() + cacheDir;
+ }
+ collectionPath = QDir::cleanPath(collectionPath);
+ if (createDir) {
+ QDir dir;
+ if (!dir.exists(collectionPath))
+ dir.mkpath(collectionPath);
+ }
+ return collectionPath;
+}
+
+QString MainWindow::defaultHelpCollectionFileName()
+{
+ TRACE_OBJ
+ // forces creation of the default collection file path
+ return collectionFileDirectory(true) + QDir::separator() +
+ QString(QLatin1String("qthelpcollection_%1.qhc")).
+ arg(QLatin1String(QT_VERSION_STR));
+}
+
+void MainWindow::currentFilterChanged(const QString &filter)
+{
+ TRACE_OBJ
+ const int index = m_filterCombo->findText(filter);
+ Q_ASSERT(index != -1);
+ m_filterCombo->setCurrentIndex(index);
+}
+
+void MainWindow::documentationRemoved(const QString &namespaceName)
+{
+ TRACE_OBJ
+ OpenPagesManager::instance()->closePages(namespaceName);
+}
+
+void MainWindow::documentationUpdated(const QString &namespaceName)
+{
+ TRACE_OBJ
+ OpenPagesManager::instance()->reloadPages(namespaceName);
+}
+
+void MainWindow::resetQtDocInfo(const QString &component)
+{
+ TRACE_OBJ
+ HelpEngineWrapper::instance().setQtDocInfo(component,
+ QStringList(QDateTime().toString(Qt::ISODate)));
+}
+
+void MainWindow::registerDocumentation(const QString &component,
+ const QString &absFileName)
+{
+ TRACE_OBJ
+ QString ns = QHelpEngineCore::namespaceName(absFileName);
+ if (ns.isEmpty())
+ return;
+
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (helpEngine.registeredDocumentations().contains(ns))
+ helpEngine.unregisterDocumentation(ns);
+ if (!helpEngine.registerDocumentation(absFileName)) {
+ QMessageBox::warning(this, tr("Qt Assistant"),
+ tr("Could not register file '%1': %2").
+ arg(absFileName).arg(helpEngine.error()));
+ } else {
+ QStringList docInfo;
+ docInfo << QFileInfo(absFileName).lastModified().toString(Qt::ISODate)
+ << absFileName;
+ helpEngine.setQtDocInfo(component, docInfo);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/mainwindow.h b/src/assistant/tools/assistant/mainwindow.h
new file mode 100644
index 000000000..6fe10ec45
--- /dev/null
+++ b/src/assistant/tools/assistant/mainwindow.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtCore/QList>
+#include <QtCore/QUrl>
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QComboBox;
+class QFileSystemWatcher;
+class QLineEdit;
+class QMenu;
+
+class CentralWidget;
+class CmdLineParser;
+class ContentWindow;
+class IndexWindow;
+class OpenPagesWindow;
+class QtDocInstaller;
+class QHelpEngineCore;
+class QHelpEngine;
+class SearchWidget;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(CmdLineParser *cmdLine, QWidget *parent = 0);
+ ~MainWindow();
+
+ static void activateCurrentBrowser();
+ static QString collectionFileDirectory(bool createDir = false,
+ const QString &cacheDir = QString());
+ static QString defaultHelpCollectionFileName();
+
+public:
+ void setIndexString(const QString &str);
+ void expandTOC(int depth);
+ bool usesDefaultCollection() const;
+
+signals:
+ void initDone();
+
+public slots:
+ void setContentsVisible(bool visible);
+ void setIndexVisible(bool visible);
+ void setBookmarksVisible(bool visible);
+ void setSearchVisible(bool visible);
+ void syncContents();
+ void activateCurrentCentralWidgetTab();
+ void currentFilterChanged(const QString &filter);
+
+private slots:
+ void showContents();
+ void showIndex();
+ void showSearch();
+ void showOpenPages();
+ void insertLastPages();
+ void gotoAddress();
+ void showPreferences();
+ void showNewAddress();
+ void showAboutDialog();
+ void showNewAddress(const QUrl &url);
+ void showTopicChooser(const QMap<QString, QUrl> &links, const QString &keyword);
+ void updateApplicationFont();
+ void filterDocumentation(const QString &customFilter);
+ void setupFilterCombo();
+ void lookForNewQtDocumentation();
+ void indexingStarted();
+ void indexingFinished();
+ void qtDocumentationInstalled();
+ void registerDocumentation(const QString &component,
+ const QString &absFileName);
+ void resetQtDocInfo(const QString &component);
+ void checkInitState();
+ void documentationRemoved(const QString &namespaceName);
+ void documentationUpdated(const QString &namespaceName);
+
+private:
+ bool initHelpDB(bool registerInternalDoc);
+ void setupActions();
+ void closeEvent(QCloseEvent *e);
+ void activateDockWidget(QWidget *w);
+ void updateAboutMenuText();
+ void setupFilterToolbar();
+ void setupAddressToolbar();
+ QMenu *toolBarMenu();
+ void hideContents();
+ void hideIndex();
+ void hideSearch();
+
+private slots:
+ void showBookmarksDockWidget();
+ void hideBookmarksDockWidget();
+
+private:
+ QWidget *m_bookmarkWidget;
+
+private:
+ CentralWidget *m_centralWidget;
+ IndexWindow *m_indexWindow;
+ ContentWindow *m_contentWindow;
+ SearchWidget *m_searchWindow;
+ QLineEdit *m_addressLineEdit;
+ QComboBox *m_filterCombo;
+
+ QAction *m_syncAction;
+ QAction *m_printPreviewAction;
+ QAction *m_pageSetupAction;
+ QAction *m_resetZoomAction;
+ QAction *m_aboutAction;
+ QAction *m_closeTabAction;
+ QAction *m_newTabAction;
+
+ QMenu *m_viewMenu;
+ QMenu *m_toolBarMenu;
+
+ CmdLineParser *m_cmdLine;
+
+ QWidget *m_progressWidget;
+ QtDocInstaller *m_qtDocInstaller;
+
+ bool m_connectedInitSignals;
+};
+
+QT_END_NAMESPACE
+
+#endif // MAINWINDOW_H
diff --git a/src/assistant/tools/assistant/openpagesmanager.cpp b/src/assistant/tools/assistant/openpagesmanager.cpp
new file mode 100644
index 000000000..272d9e242
--- /dev/null
+++ b/src/assistant/tools/assistant/openpagesmanager.cpp
@@ -0,0 +1,378 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "openpagesmanager.h"
+
+#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "helpviewer.h"
+#include "openpagesmodel.h"
+#include "openpagesswitcher.h"
+#include "openpageswidget.h"
+#include "tracer.h"
+#include "../shared/collectionconfiguration.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QTreeView>
+
+QT_BEGIN_NAMESPACE
+
+OpenPagesManager *OpenPagesManager::m_instance = 0;
+
+OpenPagesManager *OpenPagesManager::createInstance(QObject *parent,
+ bool defaultCollection, const QUrl &cmdLineUrl)
+{
+ TRACE_OBJ
+ Q_ASSERT(!m_instance);
+ m_instance = new OpenPagesManager(parent, defaultCollection, cmdLineUrl);
+ return m_instance;
+}
+
+OpenPagesManager *OpenPagesManager::instance()
+{
+ TRACE_OBJ
+ Q_ASSERT(m_instance);
+ return m_instance;
+}
+
+OpenPagesManager::OpenPagesManager(QObject *parent, bool defaultCollection,
+ const QUrl &cmdLineUrl)
+ : QObject(parent)
+ , m_model(new OpenPagesModel(this))
+ , m_openPagesWidget(0)
+ , m_openPagesSwitcher(0)
+{
+ TRACE_OBJ
+ m_openPagesWidget = new OpenPagesWidget(m_model);
+ m_openPagesWidget->setFrameStyle(QFrame::NoFrame);
+ connect(m_openPagesWidget, SIGNAL(setCurrentPage(QModelIndex)), this,
+ SLOT(setCurrentPage(QModelIndex)));
+ connect(m_openPagesWidget, SIGNAL(closePage(QModelIndex)), this,
+ SLOT(closePage(QModelIndex)));
+ connect(m_openPagesWidget, SIGNAL(closePagesExcept(QModelIndex)), this,
+ SLOT(closePagesExcept(QModelIndex)));
+
+ m_openPagesSwitcher = new OpenPagesSwitcher(m_model);
+ connect(m_openPagesSwitcher, SIGNAL(closePage(QModelIndex)), this,
+ SLOT(closePage(QModelIndex)));
+ connect(m_openPagesSwitcher, SIGNAL(setCurrentPage(QModelIndex)), this,
+ SLOT(setCurrentPage(QModelIndex)));
+
+ setupInitialPages(defaultCollection, cmdLineUrl);
+}
+
+OpenPagesManager ::~OpenPagesManager()
+{
+ TRACE_OBJ
+ m_instance = 0;
+ delete m_openPagesSwitcher;
+}
+
+int OpenPagesManager::pageCount() const
+{
+ TRACE_OBJ
+ return m_model->rowCount();
+}
+
+void OpenPagesManager::setupInitialPages(bool defaultCollection,
+ const QUrl &cmdLineUrl)
+{
+ TRACE_OBJ
+ if (cmdLineUrl.isValid()) {
+ createPage(cmdLineUrl);
+ return;
+ }
+
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ int initialPage = 0;
+ switch (helpEngine.startOption()) {
+ case ShowHomePage:
+ m_model->addPage(helpEngine.homePage());
+ break;
+ case ShowBlankPage:
+ m_model->addPage(QUrl(QLatin1String("about:blank")));
+ break;
+ case ShowLastPages: {
+ const QStringList &lastShownPageList = helpEngine.lastShownPages();
+ const int pageCount = lastShownPageList.count();
+ if (pageCount == 0) {
+ if (defaultCollection)
+ m_model->addPage(QUrl(QLatin1String("help")));
+ else
+ m_model->addPage(QUrl(QLatin1String("about:blank")));
+ } else {
+ QStringList zoomFactors = helpEngine.lastZoomFactors();
+ while (zoomFactors.count() < pageCount)
+ zoomFactors.append(CollectionConfiguration::DefaultZoomFactor);
+ initialPage = helpEngine.lastTabPage();
+ if (initialPage >= pageCount) {
+ qWarning("Initial page set to %d, maximum possible value is %d",
+ initialPage, pageCount - 1);
+ initialPage = 0;
+ }
+ for (int curPage = 0; curPage < pageCount; ++curPage) {
+ const QString &curFile = lastShownPageList.at(curPage);
+ if (helpEngine.findFile(curFile).isValid()
+ || curFile == QLatin1String("about:blank")) {
+ m_model->addPage(curFile, zoomFactors.at(curPage).toFloat());
+ } else if (curPage <= initialPage && initialPage > 0)
+ --initialPage;
+ }
+ }
+ break;
+ }
+ default:
+ Q_ASSERT(!"Unhandled option");
+ }
+
+ if (m_model->rowCount() == 0)
+ m_model->addPage(helpEngine.homePage());
+ for (int i = 0; i < m_model->rowCount(); ++i)
+ CentralWidget::instance()->addPage(m_model->pageAt(i));
+ setCurrentPage((initialPage >= m_model->rowCount())
+ ? m_model->rowCount() - 1 : initialPage);
+ m_openPagesSwitcher->selectCurrentPage();
+}
+
+HelpViewer *OpenPagesManager::createPage()
+{
+ TRACE_OBJ
+ return createPage(QUrl(QLatin1String("about:blank")));
+}
+
+void OpenPagesManager::closeCurrentPage()
+{
+ TRACE_OBJ
+ Q_ASSERT(m_model->rowCount() > 1);
+ const QModelIndexList selectedIndexes
+ = m_openPagesWidget->selectionModel()->selectedRows();
+ if (selectedIndexes.isEmpty())
+ return;
+ Q_ASSERT(selectedIndexes.count() == 1);
+ removePage(selectedIndexes.first().row());
+}
+
+HelpViewer *OpenPagesManager::createPage(const QUrl &url, bool fromSearch)
+{
+ TRACE_OBJ
+ if (HelpViewer::launchWithExternalApp(url))
+ return 0;
+
+ m_model->addPage(url);
+ const int index = m_model->rowCount() - 1;
+ HelpViewer * const page = m_model->pageAt(index);
+ CentralWidget::instance()->addPage(page, fromSearch);
+ setCurrentPage(index);
+ return page;
+}
+
+HelpViewer *OpenPagesManager::createNewPageFromSearch(const QUrl &url)
+{
+ TRACE_OBJ
+ return createPage(url, true);
+}
+
+void OpenPagesManager::closePage(HelpViewer *viewer)
+{
+ TRACE_OBJ
+ for (int i = 0; i < m_model->rowCount(); ++i) {
+ if (m_model->pageAt(i) == viewer) {
+ removePage(i);
+ break;
+ }
+ }
+}
+
+void OpenPagesManager::closePage(const QModelIndex &index)
+{
+ TRACE_OBJ
+ if (index.isValid())
+ removePage(index.row());
+}
+
+void OpenPagesManager::closePages(const QString &nameSpace)
+{
+ TRACE_OBJ
+ closeOrReloadPages(nameSpace, false);
+}
+
+void OpenPagesManager::reloadPages(const QString &nameSpace)
+{
+ TRACE_OBJ
+ closeOrReloadPages(nameSpace, true);
+ m_openPagesWidget->selectCurrentPage();
+}
+
+void OpenPagesManager::closeOrReloadPages(const QString &nameSpace, bool tryReload)
+{
+ TRACE_OBJ
+ for (int i = m_model->rowCount() - 1; i >= 0; --i) {
+ HelpViewer *page = m_model->pageAt(i);
+ if (page->source().host() != nameSpace)
+ continue;
+ if (tryReload && HelpEngineWrapper::instance().findFile(page->source()).isValid())
+ page->reload();
+ else if (m_model->rowCount() == 1)
+ page->setSource(QUrl(QLatin1String("about:blank")));
+ else
+ removePage(i);
+ }
+}
+
+bool OpenPagesManager::pagesOpenForNamespace(const QString &nameSpace) const
+{
+ TRACE_OBJ
+ for (int i = 0; i < m_model->rowCount(); ++i)
+ if (m_model->pageAt(i)->source().host() == nameSpace)
+ return true;
+ return false;
+}
+
+void OpenPagesManager::setCurrentPage(const QModelIndex &index)
+{
+ TRACE_OBJ
+ if (index.isValid())
+ setCurrentPage(index.row());
+}
+
+void OpenPagesManager::setCurrentPage(int index)
+{
+ TRACE_OBJ
+ setCurrentPage(m_model->pageAt(index));
+}
+
+void OpenPagesManager::setCurrentPage(HelpViewer *page)
+{
+ TRACE_OBJ
+ CentralWidget::instance()->setCurrentPage(page);
+ m_openPagesWidget->selectCurrentPage();
+}
+
+void OpenPagesManager::removePage(int index)
+{
+ TRACE_OBJ
+ CentralWidget::instance()->removePage(index);
+ m_model->removePage(index);
+ m_openPagesWidget->selectCurrentPage();
+}
+
+
+void OpenPagesManager::closePagesExcept(const QModelIndex &index)
+{
+ TRACE_OBJ
+ if (!index.isValid())
+ return;
+
+ int i = 0;
+ HelpViewer *viewer = m_model->pageAt(index.row());
+ while (m_model->rowCount() > 1) {
+ if (m_model->pageAt(i) != viewer)
+ removePage(i);
+ else
+ ++i;
+ }
+}
+
+QAbstractItemView *OpenPagesManager::openPagesWidget() const
+{
+ TRACE_OBJ
+ return m_openPagesWidget;
+}
+
+void OpenPagesManager::nextPage()
+{
+ TRACE_OBJ
+ nextOrPreviousPage(1);
+}
+
+void OpenPagesManager::nextPageWithSwitcher()
+{
+ TRACE_OBJ
+ if (!m_openPagesSwitcher->isVisible()) {
+ m_openPagesSwitcher->selectCurrentPage();
+ m_openPagesSwitcher->gotoNextPage();
+ showSwitcherOrSelectPage();
+ } else {
+ m_openPagesSwitcher->gotoNextPage();
+ }
+}
+
+void OpenPagesManager::previousPage()
+{
+ TRACE_OBJ
+ nextOrPreviousPage(-1);
+}
+
+void OpenPagesManager::previousPageWithSwitcher()
+{
+ TRACE_OBJ
+ if (!m_openPagesSwitcher->isVisible()) {
+ m_openPagesSwitcher->selectCurrentPage();
+ m_openPagesSwitcher->gotoPreviousPage();
+ showSwitcherOrSelectPage();
+ } else {
+ m_openPagesSwitcher->gotoPreviousPage();
+ }
+}
+
+void OpenPagesManager::nextOrPreviousPage(int offset)
+{
+ TRACE_OBJ
+ setCurrentPage((CentralWidget::instance()->currentIndex() + offset
+ + m_model->rowCount()) % m_model->rowCount());
+}
+
+void OpenPagesManager::showSwitcherOrSelectPage() const
+{
+ TRACE_OBJ
+ if (QApplication::keyboardModifiers() != Qt::NoModifier) {
+ const int width = CentralWidget::instance()->width();
+ const int height = CentralWidget::instance()->height();
+ const QPoint p(CentralWidget::instance()->mapToGlobal(QPoint(0, 0)));
+ m_openPagesSwitcher->move((width - m_openPagesSwitcher->width()) / 2 + p.x(),
+ (height - m_openPagesSwitcher->height()) / 2 + p.y());
+ m_openPagesSwitcher->setVisible(true);
+ } else {
+ m_openPagesSwitcher->selectAndHide();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/openpagesmanager.h b/src/assistant/tools/assistant/openpagesmanager.h
new file mode 100644
index 000000000..c34686c8c
--- /dev/null
+++ b/src/assistant/tools/assistant/openpagesmanager.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPENPAGESMANAGER_H
+#define OPENPAGESMANAGER_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractItemView;
+class QModelIndex;
+class QUrl;
+
+class HelpViewer;
+class OpenPagesModel;
+class OpenPagesSwitcher;
+class OpenPagesWidget;
+
+class OpenPagesManager : public QObject
+{
+ Q_OBJECT
+public:
+ static OpenPagesManager *createInstance(QObject *parent,
+ bool defaultCollection, const QUrl &cmdLineUrl);
+ static OpenPagesManager *instance();
+
+ bool pagesOpenForNamespace(const QString &nameSpace) const;
+ void closePages(const QString &nameSpace);
+ void reloadPages(const QString &nameSpace);
+
+ QAbstractItemView* openPagesWidget() const;
+
+ int pageCount() const;
+ void setCurrentPage(int index);
+
+public slots:
+ HelpViewer *createPage(const QUrl &url, bool fromSearch = false);
+ HelpViewer *createNewPageFromSearch(const QUrl &url);
+ HelpViewer *createPage();
+ void closeCurrentPage();
+
+ void nextPage();
+ void nextPageWithSwitcher();
+ void previousPage();
+ void previousPageWithSwitcher();
+
+ void closePage(HelpViewer *page);
+ void setCurrentPage(HelpViewer *page);
+
+private slots:
+ void setCurrentPage(const QModelIndex &index);
+ void closePage(const QModelIndex &index);
+ void closePagesExcept(const QModelIndex &index);
+
+private:
+ OpenPagesManager(QObject *parent, bool defaultCollection,
+ const QUrl &cmdLineUrl);
+ ~OpenPagesManager();
+
+ void setupInitialPages(bool defaultCollection, const QUrl &cmdLineUrl);
+ void closeOrReloadPages(const QString &nameSpace, bool tryReload);
+ void removePage(int index);
+
+ void nextOrPreviousPage(int offset);
+ void showSwitcherOrSelectPage() const;
+
+ OpenPagesModel *m_model;
+ OpenPagesWidget *m_openPagesWidget;
+ OpenPagesSwitcher *m_openPagesSwitcher;
+
+ static OpenPagesManager *m_instance;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPENPAGESMANAGER_H
diff --git a/src/assistant/tools/assistant/openpagesmodel.cpp b/src/assistant/tools/assistant/openpagesmodel.cpp
new file mode 100644
index 000000000..3517693f9
--- /dev/null
+++ b/src/assistant/tools/assistant/openpagesmodel.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "openpagesmodel.h"
+
+#include "helpenginewrapper.h"
+#include "helpviewer.h"
+#include "tracer.h"
+
+#include <QtCore/QStringList>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+OpenPagesModel::OpenPagesModel(QObject *parent) : QAbstractTableModel(parent)
+{
+ TRACE_OBJ
+}
+
+int OpenPagesModel::rowCount(const QModelIndex &parent) const
+{
+ TRACE_OBJ
+ return parent.isValid() ? 0 : m_pages.count();
+}
+
+int OpenPagesModel::columnCount(const QModelIndex &/*parent*/) const
+{
+ TRACE_OBJ
+ return 2;
+}
+
+QVariant OpenPagesModel::data(const QModelIndex &index, int role) const
+{
+ TRACE_OBJ
+ if (!index.isValid() || index.row() >= rowCount() || index.column() > 0
+ || role != Qt::DisplayRole)
+ return QVariant();
+ QString title = m_pages.at(index.row())->title();
+ title.replace(QLatin1Char('&'), QLatin1String("&&"));
+ return title.isEmpty() ? QLatin1String("(Untitled)") : title;
+}
+
+void OpenPagesModel::addPage(const QUrl &url, qreal zoom)
+{
+ TRACE_OBJ
+ beginInsertRows(QModelIndex(), rowCount(), rowCount());
+ HelpViewer *page = new HelpViewer(zoom);
+ connect(page, SIGNAL(titleChanged()), this, SLOT(handleTitleChanged()));
+ m_pages << page;
+ endInsertRows();
+ page->setSource(url);
+}
+
+void OpenPagesModel::removePage(int index)
+{
+ TRACE_OBJ
+ Q_ASSERT(index >= 0 && index < rowCount());
+ beginRemoveRows(QModelIndex(), index, index);
+ HelpViewer *page = m_pages.at(index);
+ m_pages.removeAt(index);
+ endRemoveRows();
+ page->deleteLater();
+}
+
+HelpViewer *OpenPagesModel::pageAt(int index) const
+{
+ TRACE_OBJ
+ Q_ASSERT(index >= 0 && index < rowCount());
+ return m_pages.at(index);
+}
+
+void OpenPagesModel::handleTitleChanged()
+{
+ TRACE_OBJ
+ HelpViewer *page = static_cast<HelpViewer *>(sender());
+ const int row = m_pages.indexOf(page);
+ Q_ASSERT(row != -1 );
+ const QModelIndex &item = index(row, 0);
+ emit dataChanged(item, item);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/openpagesmodel.h b/src/assistant/tools/assistant/openpagesmodel.h
new file mode 100644
index 000000000..dd28a7c5f
--- /dev/null
+++ b/src/assistant/tools/assistant/openpagesmodel.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPENPAGESMODEL_H
+#define OPENPAGESMODEL_H
+
+#include <QtCore/QAbstractTableModel>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class HelpViewer;
+class QUrl;
+
+class OpenPagesModel : public QAbstractTableModel
+{
+ Q_OBJECT
+public:
+ OpenPagesModel(QObject *parent);
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+ void addPage(const QUrl &url, qreal zoom = 0);
+ void removePage(int index);
+ HelpViewer *pageAt(int index) const;
+
+private slots:
+ void handleTitleChanged();
+
+private:
+ QList<HelpViewer *> m_pages;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPENPAGESMODEL_H
diff --git a/src/assistant/tools/assistant/openpagesswitcher.cpp b/src/assistant/tools/assistant/openpagesswitcher.cpp
new file mode 100644
index 000000000..8e7f29bf0
--- /dev/null
+++ b/src/assistant/tools/assistant/openpagesswitcher.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "openpagesswitcher.h"
+
+#include "centralwidget.h"
+#include "openpagesmodel.h"
+#include "openpageswidget.h"
+#include "tracer.h"
+
+#include <QtCore/QEvent>
+
+#include <QtGui/QKeyEvent>
+#include <QtGui/QVBoxLayout>
+
+QT_BEGIN_NAMESPACE
+
+const int gWidth = 300;
+const int gHeight = 200;
+
+OpenPagesSwitcher::OpenPagesSwitcher(OpenPagesModel *model)
+ : QFrame(0, Qt::Popup)
+ , m_openPagesModel(model)
+{
+ TRACE_OBJ
+ resize(gWidth, gHeight);
+
+ m_openPagesWidget = new OpenPagesWidget(m_openPagesModel);
+
+ // We disable the frame on this list view and use a QFrame around it instead.
+ // This improves the look with QGTKStyle.
+#ifndef Q_WS_MAC
+ setFrameStyle(m_openPagesWidget->frameStyle());
+#endif
+ m_openPagesWidget->setFrameStyle(QFrame::NoFrame);
+
+ m_openPagesWidget->allowContextMenu(false);
+ m_openPagesWidget->installEventFilter(this);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(0);
+ layout->addWidget(m_openPagesWidget);
+
+ connect(m_openPagesWidget, SIGNAL(closePage(QModelIndex)), this,
+ SIGNAL(closePage(QModelIndex)));
+ connect(m_openPagesWidget, SIGNAL(setCurrentPage(QModelIndex)), this,
+ SIGNAL(setCurrentPage(QModelIndex)));
+}
+
+OpenPagesSwitcher::~OpenPagesSwitcher()
+{
+ TRACE_OBJ
+}
+
+void OpenPagesSwitcher::gotoNextPage()
+{
+ TRACE_OBJ
+ selectPageUpDown(1);
+}
+
+void OpenPagesSwitcher::gotoPreviousPage()
+{
+ TRACE_OBJ
+ selectPageUpDown(-1);
+}
+
+void OpenPagesSwitcher::selectAndHide()
+{
+ TRACE_OBJ
+ setVisible(false);
+ emit setCurrentPage(m_openPagesWidget->currentIndex());
+}
+
+void OpenPagesSwitcher::selectCurrentPage()
+{
+ TRACE_OBJ
+ m_openPagesWidget->selectCurrentPage();
+}
+
+void OpenPagesSwitcher::setVisible(bool visible)
+{
+ TRACE_OBJ
+ QWidget::setVisible(visible);
+ if (visible)
+ setFocus();
+}
+
+void OpenPagesSwitcher::focusInEvent(QFocusEvent *event)
+{
+ TRACE_OBJ
+ Q_UNUSED(event)
+ m_openPagesWidget->setFocus();
+}
+
+bool OpenPagesSwitcher::eventFilter(QObject *object, QEvent *event)
+{
+ TRACE_OBJ
+ if (object == m_openPagesWidget) {
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ if (ke->key() == Qt::Key_Escape) {
+ setVisible(false);
+ return true;
+ }
+
+ const int key = ke->key();
+ if (key == Qt::Key_Return || key == Qt::Key_Enter || key == Qt::Key_Space) {
+ emit setCurrentPage(m_openPagesWidget->currentIndex());
+ return true;
+ }
+
+ Qt::KeyboardModifier modifier = Qt::ControlModifier;
+#ifdef Q_WS_MAC
+ modifier = Qt::AltModifier;
+#endif
+ if (key == Qt::Key_Backtab
+ && (ke->modifiers() == (modifier | Qt::ShiftModifier)))
+ gotoPreviousPage();
+ else if (key == Qt::Key_Tab && (ke->modifiers() == modifier))
+ gotoNextPage();
+ } else if (event->type() == QEvent::KeyRelease) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ if (ke->modifiers() == 0
+ /*HACK this is to overcome some event inconsistencies between platforms*/
+ || (ke->modifiers() == Qt::AltModifier
+ && (ke->key() == Qt::Key_Alt || ke->key() == -1))) {
+ selectAndHide();
+ }
+ }
+ }
+ return QWidget::eventFilter(object, event);
+}
+
+void OpenPagesSwitcher::selectPageUpDown(int summand)
+{
+ TRACE_OBJ
+ const int pageCount = m_openPagesModel->rowCount();
+ if (pageCount < 2)
+ return;
+
+ const QModelIndexList &list = m_openPagesWidget->selectionModel()->selectedIndexes();
+ if (list.isEmpty())
+ return;
+
+ QModelIndex index = list.first();
+ if (!index.isValid())
+ return;
+
+ index = m_openPagesModel->index((index.row() + summand + pageCount) % pageCount, 0);
+ if (index.isValid()) {
+ m_openPagesWidget->setCurrentIndex(index);
+ m_openPagesWidget->scrollTo(index, QAbstractItemView::PositionAtCenter);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/openpagesswitcher.h b/src/assistant/tools/assistant/openpagesswitcher.h
new file mode 100644
index 000000000..80c7e965d
--- /dev/null
+++ b/src/assistant/tools/assistant/openpagesswitcher.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPENPAGESSWITCHER_H
+#define OPENPAGESSWITCHER_H
+
+#include <QtGui/QFrame>
+
+QT_BEGIN_NAMESPACE
+
+class OpenPagesModel;
+class OpenPagesWidget;
+class QModelIndex;
+
+class OpenPagesSwitcher : public QFrame
+{
+ Q_OBJECT
+
+public:
+ OpenPagesSwitcher(OpenPagesModel *model);
+ ~OpenPagesSwitcher();
+
+ void gotoNextPage();
+ void gotoPreviousPage();
+
+ void selectAndHide();
+ void selectCurrentPage();
+
+ void setVisible(bool visible);
+ void focusInEvent(QFocusEvent *event);
+ bool eventFilter(QObject *object, QEvent *event);
+
+signals:
+ void closePage(const QModelIndex &index);
+ void setCurrentPage(const QModelIndex &index);
+
+private:
+ void selectPageUpDown(int summand);
+
+private:
+ OpenPagesModel *m_openPagesModel;
+ OpenPagesWidget *m_openPagesWidget;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPENPAGESSWITCHER_H
diff --git a/src/assistant/tools/assistant/openpageswidget.cpp b/src/assistant/tools/assistant/openpageswidget.cpp
new file mode 100644
index 000000000..db037125b
--- /dev/null
+++ b/src/assistant/tools/assistant/openpageswidget.cpp
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "openpageswidget.h"
+
+#include "centralwidget.h"
+#include "openpagesmodel.h"
+#include "tracer.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QHeaderView>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QPainter>
+
+#ifdef Q_WS_MAC
+#include <qmacstyle_mac.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+OpenPagesDelegate::OpenPagesDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+ TRACE_OBJ
+}
+
+void OpenPagesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ TRACE_OBJ
+ if (option.state & QStyle::State_MouseOver) {
+ if ((QApplication::mouseButtons() & Qt::LeftButton) == 0)
+ pressedIndex = QModelIndex();
+ QBrush brush = option.palette.alternateBase();
+ if (index == pressedIndex)
+ brush = option.palette.dark();
+ painter->fillRect(option.rect, brush);
+ }
+
+ QStyledItemDelegate::paint(painter, option, index);
+
+ if (index.column() == 1 && index.model()->rowCount() > 1
+ && option.state & QStyle::State_MouseOver) {
+ QIcon icon((option.state & QStyle::State_Selected)
+ ? ":/trolltech/assistant/images/closebutton.png"
+ : ":/trolltech/assistant/images/darkclosebutton.png");
+
+ const QRect iconRect(option.rect.right() - option.rect.height(),
+ option.rect.top(), option.rect.height(), option.rect.height());
+ icon.paint(painter, iconRect, Qt::AlignRight | Qt::AlignVCenter);
+ }
+}
+
+// -- OpenPagesWidget
+
+OpenPagesWidget::OpenPagesWidget(OpenPagesModel *model)
+ : m_allowContextMenu(true)
+{
+ TRACE_OBJ
+ setModel(model);
+ setIndentation(0);
+ setItemDelegate((m_delegate = new OpenPagesDelegate(this)));
+
+ setTextElideMode(Qt::ElideMiddle);
+ setAttribute(Qt::WA_MacShowFocusRect, false);
+
+ viewport()->setAttribute(Qt::WA_Hover);
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setSelectionMode(QAbstractItemView::SingleSelection);
+
+ header()->hide();
+ header()->setStretchLastSection(false);
+ header()->setResizeMode(0, QHeaderView::Stretch);
+ header()->setResizeMode(1, QHeaderView::Fixed);
+ header()->resizeSection(1, 18);
+
+ installEventFilter(this);
+ setUniformRowHeights(true);
+ setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(this, SIGNAL(clicked(QModelIndex)), this,
+ SLOT(handleClicked(QModelIndex)));
+ connect(this, SIGNAL(pressed(QModelIndex)), this,
+ SLOT(handlePressed(QModelIndex)));
+ connect(this, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(contextMenuRequested(QPoint)));
+}
+
+OpenPagesWidget::~OpenPagesWidget()
+{
+ TRACE_OBJ
+}
+
+void OpenPagesWidget::selectCurrentPage()
+{
+ TRACE_OBJ
+ const QModelIndex &current =
+ model()->index(CentralWidget::instance()->currentIndex(), 0);
+
+ QItemSelectionModel * const selModel = selectionModel();
+ selModel->select(current,
+ QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+ selModel->clearSelection();
+
+ setCurrentIndex(current);
+ scrollTo(currentIndex());
+}
+
+void OpenPagesWidget::allowContextMenu(bool ok)
+{
+ TRACE_OBJ
+ m_allowContextMenu = ok;
+}
+
+void OpenPagesWidget::contextMenuRequested(QPoint pos)
+{
+ TRACE_OBJ
+ QModelIndex index = indexAt(pos);
+ if (!index.isValid() || !m_allowContextMenu)
+ return;
+
+ if (index.column() == 1)
+ index = index.sibling(index.row(), 0);
+ QMenu contextMenu;
+ QAction *closeEditor = contextMenu.addAction(tr("Close %1").arg(index.data()
+ .toString()));
+ QAction *closeOtherEditors = contextMenu.addAction(tr("Close All Except %1")
+ .arg(index.data().toString()));
+
+ if (model()->rowCount() == 1) {
+ closeEditor->setEnabled(false);
+ closeOtherEditors->setEnabled(false);
+ }
+
+ QAction *action = contextMenu.exec(mapToGlobal(pos));
+ if (action == closeEditor)
+ emit closePage(index);
+ else if (action == closeOtherEditors)
+ emit closePagesExcept(index);
+}
+
+void OpenPagesWidget::handlePressed(const QModelIndex &index)
+{
+ TRACE_OBJ
+ if (index.column() == 0)
+ emit setCurrentPage(index);
+
+ if (index.column() == 1)
+ m_delegate->pressedIndex = index;
+}
+
+void OpenPagesWidget::handleClicked(const QModelIndex &index)
+{
+ TRACE_OBJ
+ // implemented here to handle the funky close button and to work around a
+ // bug in item views where the delegate wouldn't get the QStyle::State_MouseOver
+ if (index.column() == 1) {
+ if (model()->rowCount() > 1)
+ emit closePage(index);
+
+ QWidget *vp = viewport();
+ const QPoint &cursorPos = QCursor::pos();
+ QMouseEvent e(QEvent::MouseMove, vp->mapFromGlobal(cursorPos), cursorPos,
+ Qt::NoButton, 0, 0);
+ QCoreApplication::sendEvent(vp, &e);
+ }
+}
+
+bool OpenPagesWidget::eventFilter(QObject *obj, QEvent *event)
+{
+ TRACE_OBJ
+ if (obj != this)
+ return QWidget::eventFilter(obj, event);
+
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ if (currentIndex().isValid() && ke->modifiers() == 0) {
+ const int key = ke->key();
+ if (key == Qt::Key_Return || key == Qt::Key_Enter
+ || key == Qt::Key_Space) {
+ emit setCurrentPage(currentIndex());
+ } else if ((key == Qt::Key_Delete || key == Qt::Key_Backspace)
+ && model()->rowCount() > 1) {
+ emit closePage(currentIndex());
+ }
+ }
+ } else if (event->type() == QEvent::KeyRelease) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ if (ke->modifiers() == 0
+ && (ke->key() == Qt::Key_Up || ke->key() == Qt::Key_Down)) {
+ emit setCurrentPage(currentIndex());
+ }
+ }
+ return QWidget::eventFilter(obj, event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/openpageswidget.h b/src/assistant/tools/assistant/openpageswidget.h
new file mode 100644
index 000000000..6041fe22d
--- /dev/null
+++ b/src/assistant/tools/assistant/openpageswidget.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Assistant module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPENPAGESWIDGET_H
+#define OPENPAGESWIDGET_H
+
+#include <QtGui/QStyledItemDelegate>
+#include <QtGui/QTreeView>
+
+QT_BEGIN_NAMESPACE
+
+class OpenPagesModel;
+
+class OpenPagesDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ explicit OpenPagesDelegate(QObject *parent = 0);
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ mutable QModelIndex pressedIndex;
+};
+
+class OpenPagesWidget : public QTreeView
+{
+ Q_OBJECT
+public:
+ OpenPagesWidget(OpenPagesModel *model);
+ ~OpenPagesWidget();
+
+ void selectCurrentPage();
+ void allowContextMenu(bool ok);
+
+signals:
+ void setCurrentPage(const QModelIndex &index);
+ void closePage(const QModelIndex &index);
+ void closePagesExcept(const QModelIndex &index);
+
+private slots:
+ void contextMenuRequested(QPoint pos);
+ void handlePressed(const QModelIndex &index);
+ void handleClicked(const QModelIndex &index);
+
+private:
+ bool eventFilter(QObject *obj, QEvent *event);
+
+ bool m_allowContextMenu;
+ OpenPagesDelegate *m_delegate;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPENPAGESWIDGET_H
diff --git a/src/assistant/tools/assistant/preferencesdialog.cpp b/src/assistant/tools/assistant/preferencesdialog.cpp
new file mode 100644
index 000000000..9bfd35c00
--- /dev/null
+++ b/src/assistant/tools/assistant/preferencesdialog.cpp
@@ -0,0 +1,507 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "preferencesdialog.h"
+
+#include "centralwidget.h"
+#include "filternamedialog.h"
+#include "fontpanel.h"
+#include "helpenginewrapper.h"
+#include "installdialog.h"
+#include "openpagesmanager.h"
+#include "tracer.h"
+
+#include <QtCore/QtAlgorithms>
+#include <QtCore/QFileSystemWatcher>
+
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QFileDialog>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QHeaderView>
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
+
+#include <QtHelp/QHelpEngineCore>
+
+QT_BEGIN_NAMESPACE
+
+PreferencesDialog::PreferencesDialog(QWidget *parent)
+ : QDialog(parent)
+ , m_appFontChanged(false)
+ , m_browserFontChanged(false)
+ , helpEngine(HelpEngineWrapper::instance())
+{
+ TRACE_OBJ
+ m_ui.setupUi(this);
+
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
+ this, SLOT(applyChanges()));
+ connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()),
+ this, SLOT(reject()));
+
+ m_hideFiltersTab = !helpEngine.filterFunctionalityEnabled();
+ m_hideDocsTab = !helpEngine.documentationManagerEnabled();
+
+ if (!m_hideFiltersTab) {
+ m_ui.attributeWidget->header()->hide();
+ m_ui.attributeWidget->setRootIsDecorated(false);
+
+ connect(m_ui.attributeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
+ this, SLOT(updateFilterMap()));
+
+ connect(m_ui.filterWidget,
+ SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this,
+ SLOT(updateAttributes(QListWidgetItem*)));
+
+ connect(m_ui.filterAddButton, SIGNAL(clicked()), this,
+ SLOT(addFilter()));
+ connect(m_ui.filterRemoveButton, SIGNAL(clicked()), this,
+ SLOT(removeFilter()));
+
+ updateFilterPage();
+ } else {
+ m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.filtersTab));
+ }
+
+ if (!m_hideDocsTab) {
+ connect(m_ui.docAddButton, SIGNAL(clicked()), this,
+ SLOT(addDocumentationLocal()));
+ connect(m_ui.docRemoveButton, SIGNAL(clicked()), this,
+ SLOT(removeDocumentation()));
+
+ m_docsBackup = helpEngine.registeredDocumentations();
+ m_ui.registeredDocsListWidget->addItems(m_docsBackup);
+ } else {
+ m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.docsTab));
+ }
+
+ updateFontSettingsPage();
+ updateOptionsPage();
+
+ if (helpEngine.usesAppFont())
+ setFont(helpEngine.appFont());
+}
+
+PreferencesDialog::~PreferencesDialog()
+{
+ TRACE_OBJ
+ if (m_appFontChanged) {
+ helpEngine.setAppFont(m_appFontPanel->selectedFont());
+ helpEngine.setUseAppFont(m_appFontPanel->isChecked());
+ helpEngine.setAppWritingSystem(m_appFontPanel->writingSystem());
+ emit updateApplicationFont();
+ }
+
+ if (m_browserFontChanged) {
+ helpEngine.setBrowserFont(m_browserFontPanel->selectedFont());
+ helpEngine.setUseBrowserFont(m_browserFontPanel->isChecked());
+ helpEngine.setBrowserWritingSystem(m_browserFontPanel->writingSystem());
+ emit updateBrowserFont();
+ }
+
+ QString homePage = m_ui.homePageLineEdit->text();
+ if (homePage.isEmpty())
+ homePage = QLatin1String("help");
+ helpEngine.setHomePage(homePage);
+
+ int option = m_ui.helpStartComboBox->currentIndex();
+ helpEngine.setStartOption(option);
+}
+
+void PreferencesDialog::showDialog()
+{
+ TRACE_OBJ
+ if (exec() != Accepted)
+ m_appFontChanged = m_browserFontChanged = false;
+}
+
+void PreferencesDialog::updateFilterPage()
+{
+ TRACE_OBJ
+ m_ui.filterWidget->clear();
+ m_ui.attributeWidget->clear();
+
+ m_filterMapBackup.clear();
+ const QStringList &filters = helpEngine.customFilters();
+ foreach (const QString &filter, filters) {
+ if (filter == HelpEngineWrapper::TrUnfiltered)
+ continue;
+ QStringList atts = helpEngine.filterAttributes(filter);
+ m_filterMapBackup.insert(filter, atts);
+ if (!m_filterMap.contains(filter))
+ m_filterMap.insert(filter, atts);
+ }
+
+ m_ui.filterWidget->addItems(m_filterMap.keys());
+
+ foreach (const QString &a, helpEngine.filterAttributes())
+ new QTreeWidgetItem(m_ui.attributeWidget, QStringList() << a);
+
+ if (!m_filterMap.keys().isEmpty())
+ m_ui.filterWidget->setCurrentRow(0);
+}
+
+void PreferencesDialog::updateAttributes(QListWidgetItem *item)
+{
+ TRACE_OBJ
+ QStringList checkedList;
+ if (item)
+ checkedList = m_filterMap.value(item->text());
+ QTreeWidgetItem *itm;
+ for (int i = 0; i < m_ui.attributeWidget->topLevelItemCount(); ++i) {
+ itm = m_ui.attributeWidget->topLevelItem(i);
+ if (checkedList.contains(itm->text(0)))
+ itm->setCheckState(0, Qt::Checked);
+ else
+ itm->setCheckState(0, Qt::Unchecked);
+ }
+}
+
+void PreferencesDialog::updateFilterMap()
+{
+ TRACE_OBJ
+ if (!m_ui.filterWidget->currentItem())
+ return;
+ QString filter = m_ui.filterWidget->currentItem()->text();
+ if (!m_filterMap.contains(filter))
+ return;
+
+ QStringList newAtts;
+ QTreeWidgetItem *itm = 0;
+ for (int i = 0; i < m_ui.attributeWidget->topLevelItemCount(); ++i) {
+ itm = m_ui.attributeWidget->topLevelItem(i);
+ if (itm->checkState(0) == Qt::Checked)
+ newAtts.append(itm->text(0));
+ }
+ m_filterMap[filter] = newAtts;
+}
+
+void PreferencesDialog::addFilter()
+{
+ TRACE_OBJ
+ FilterNameDialog dia(this);
+ if (dia.exec() == QDialog::Rejected)
+ return;
+
+ QString filterName = dia.filterName();
+ if (!m_filterMap.contains(filterName)) {
+ m_filterMap.insert(filterName, QStringList());
+ m_ui.filterWidget->addItem(filterName);
+ }
+
+ QList<QListWidgetItem*> lst = m_ui.filterWidget
+ ->findItems(filterName, Qt::MatchCaseSensitive);
+ m_ui.filterWidget->setCurrentItem(lst.first());
+}
+
+void PreferencesDialog::removeFilter()
+{
+ TRACE_OBJ
+ QListWidgetItem *item =
+ m_ui.filterWidget ->takeItem(m_ui.filterWidget->currentRow());
+ if (!item)
+ return;
+
+ m_filterMap.remove(item->text());
+ m_removedFilters.append(item->text());
+ delete item;
+ if (m_ui.filterWidget->count())
+ m_ui.filterWidget->setCurrentRow(0);
+}
+
+void PreferencesDialog::addDocumentationLocal()
+{
+ TRACE_OBJ
+ const QStringList fileNames = QFileDialog::getOpenFileNames(this,
+ tr("Add Documentation"), QString(), tr("Qt Compressed Help Files (*.qch)"));
+ if (fileNames.isEmpty())
+ return;
+
+ QStringList invalidFiles;
+ QStringList alreadyRegistered;
+ foreach (const QString &fileName, fileNames) {
+ const QString nameSpace = QHelpEngineCore::namespaceName(fileName);
+ if (nameSpace.isEmpty()) {
+ invalidFiles.append(fileName);
+ continue;
+ }
+
+ if (m_ui.registeredDocsListWidget->findItems(nameSpace,
+ Qt::MatchFixedString).count()) {
+ alreadyRegistered.append(nameSpace);
+ continue;
+ }
+
+ if (helpEngine.registerDocumentation(fileName)) {
+ m_ui.registeredDocsListWidget->addItem(nameSpace);
+ m_regDocs.append(nameSpace);
+ m_unregDocs.removeAll(nameSpace);
+ }
+ }
+
+ if (!invalidFiles.isEmpty() || !alreadyRegistered.isEmpty()) {
+ QString message;
+ if (!alreadyRegistered.isEmpty()) {
+ foreach (const QString &ns, alreadyRegistered) {
+ message += tr("The namespace %1 is already registered!")
+ .arg(QString("<b>%1</b>").arg(ns)) + QLatin1String("<br>");
+ }
+ if (!invalidFiles.isEmpty())
+ message.append(QLatin1String("<br>"));
+ }
+
+ if (!invalidFiles.isEmpty()) {
+ message += tr("The specified file is not a valid Qt Help File!");
+ message.append(QLatin1String("<ul>"));
+ foreach (const QString &file, invalidFiles)
+ message += QLatin1String("<li>") + file + QLatin1String("</li>");
+ message.append(QLatin1String("</ul>"));
+ }
+ QMessageBox::warning(this, tr("Add Documentation"), message);
+ }
+
+ updateFilterPage();
+}
+
+void PreferencesDialog::removeDocumentation()
+{
+ TRACE_OBJ
+
+ bool foundBefore = false;
+ QList<QListWidgetItem*> l = m_ui.registeredDocsListWidget->selectedItems();
+ foreach (QListWidgetItem* item, l) {
+ const QString& ns = item->text();
+ if (!foundBefore && OpenPagesManager::instance()->pagesOpenForNamespace(ns)) {
+ if (0 == QMessageBox::information(this, tr("Remove Documentation"),
+ tr("Some documents currently opened in Assistant reference the "
+ "documentation you are attempting to remove. Removing the "
+ "documentation will close those documents."), tr("Cancel"),
+ tr("OK"))) return;
+ foundBefore = true;
+ }
+
+ m_unregDocs.append(ns);
+ delete m_ui.registeredDocsListWidget->takeItem(
+ m_ui.registeredDocsListWidget->row(item));
+ }
+
+ if (m_ui.registeredDocsListWidget->count()) {
+ m_ui.registeredDocsListWidget->setCurrentRow(0,
+ QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+void PreferencesDialog::applyChanges()
+{
+ TRACE_OBJ
+ bool filtersWereChanged = false;
+ if (!m_hideFiltersTab) {
+ if (m_filterMap.count() != m_filterMapBackup.count()) {
+ filtersWereChanged = true;
+ } else {
+ QMapIterator<QString, QStringList> it(m_filterMapBackup);
+ while (it.hasNext() && !filtersWereChanged) {
+ it.next();
+ if (!m_filterMap.contains(it.key())) {
+ filtersWereChanged = true;
+ } else {
+ QStringList a = it.value();
+ QStringList b = m_filterMap.value(it.key());
+ if (a.count() != b.count()) {
+ filtersWereChanged = true;
+ } else {
+ QStringList::const_iterator i(a.constBegin());
+ while (i != a.constEnd()) {
+ if (!b.contains(*i)) {
+ filtersWereChanged = true;
+ break;
+ }
+ ++i;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (filtersWereChanged) {
+ foreach (const QString &filter, m_removedFilters)
+ helpEngine.removeCustomFilter(filter);
+ QMapIterator<QString, QStringList> it(m_filterMap);
+ while (it.hasNext()) {
+ it.next();
+ helpEngine.addCustomFilter(it.key(), it.value());
+ }
+ }
+
+ foreach (const QString &doc, m_unregDocs) {
+ OpenPagesManager::instance()->closePages(doc);
+ helpEngine.unregisterDocumentation(doc);
+ }
+
+ if (filtersWereChanged || !m_regDocs.isEmpty() || !m_unregDocs.isEmpty())
+ helpEngine.setupData();
+
+ helpEngine.setShowTabs(m_ui.showTabs->isChecked());
+ if (m_showTabs != m_ui.showTabs->isChecked())
+ emit updateUserInterface();
+
+ accept();
+}
+
+void PreferencesDialog::updateFontSettingsPage()
+{
+ TRACE_OBJ
+ m_browserFontPanel = new FontPanel(this);
+ m_browserFontPanel->setCheckable(true);
+ m_ui.stackedWidget_2->insertWidget(0, m_browserFontPanel);
+
+ m_appFontPanel = new FontPanel(this);
+ m_appFontPanel->setCheckable(true);
+ m_ui.stackedWidget_2->insertWidget(1, m_appFontPanel);
+
+ m_ui.stackedWidget_2->setCurrentIndex(0);
+
+ const QString customSettings(tr("Use custom settings"));
+ m_appFontPanel->setTitle(customSettings);
+
+ QFont font = helpEngine.appFont();
+ m_appFontPanel->setSelectedFont(font);
+
+ QFontDatabase::WritingSystem system = helpEngine.appWritingSystem();
+ m_appFontPanel->setWritingSystem(system);
+
+ m_appFontPanel->setChecked(helpEngine.usesAppFont());
+
+ m_browserFontPanel->setTitle(customSettings);
+
+ font = helpEngine.browserFont();
+ m_browserFontPanel->setSelectedFont(font);
+
+ system = helpEngine.browserWritingSystem();
+ m_browserFontPanel->setWritingSystem(system);
+
+ m_browserFontPanel->setChecked(helpEngine.usesBrowserFont());
+
+ connect(m_appFontPanel, SIGNAL(toggled(bool)), this,
+ SLOT(appFontSettingToggled(bool)));
+ connect(m_browserFontPanel, SIGNAL(toggled(bool)), this,
+ SLOT(browserFontSettingToggled(bool)));
+
+ QList<QComboBox*> allCombos = m_appFontPanel->findChildren<QComboBox*>();
+ foreach (QComboBox* box, allCombos) {
+ connect(box, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(appFontSettingChanged(int)));
+ }
+
+ allCombos = m_browserFontPanel->findChildren<QComboBox*>();
+ foreach (QComboBox* box, allCombos) {
+ connect(box, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(browserFontSettingChanged(int)));
+ }
+}
+
+void PreferencesDialog::appFontSettingToggled(bool on)
+{
+ TRACE_OBJ
+ Q_UNUSED(on)
+ m_appFontChanged = true;
+}
+
+void PreferencesDialog::appFontSettingChanged(int index)
+{
+ TRACE_OBJ
+ Q_UNUSED(index)
+ m_appFontChanged = true;
+}
+
+void PreferencesDialog::browserFontSettingToggled(bool on)
+{
+ TRACE_OBJ
+ Q_UNUSED(on)
+ m_browserFontChanged = true;
+}
+
+void PreferencesDialog::browserFontSettingChanged(int index)
+{
+ TRACE_OBJ
+ Q_UNUSED(index)
+ m_browserFontChanged = true;
+}
+
+void PreferencesDialog::updateOptionsPage()
+{
+ TRACE_OBJ
+ m_ui.homePageLineEdit->setText(helpEngine.homePage());
+
+ int option = helpEngine.startOption();
+ m_ui.helpStartComboBox->setCurrentIndex(option);
+
+ m_showTabs = helpEngine.showTabs();
+ m_ui.showTabs->setChecked(m_showTabs);
+
+ connect(m_ui.blankPageButton, SIGNAL(clicked()), this, SLOT(setBlankPage()));
+ connect(m_ui.currentPageButton, SIGNAL(clicked()), this, SLOT(setCurrentPage()));
+ connect(m_ui.defaultPageButton, SIGNAL(clicked()), this, SLOT(setDefaultPage()));
+}
+
+void PreferencesDialog::setBlankPage()
+{
+ TRACE_OBJ
+ m_ui.homePageLineEdit->setText(QLatin1String("about:blank"));
+}
+
+void PreferencesDialog::setCurrentPage()
+{
+ TRACE_OBJ
+ QString homepage = CentralWidget::instance()->currentSource().toString();
+ if (homepage.isEmpty())
+ homepage = QLatin1String("help");
+
+ m_ui.homePageLineEdit->setText(homepage);
+}
+
+void PreferencesDialog::setDefaultPage()
+{
+ TRACE_OBJ
+ m_ui.homePageLineEdit->setText(helpEngine.defaultHomePage());
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/preferencesdialog.h b/src/assistant/tools/assistant/preferencesdialog.h
new file mode 100644
index 000000000..f9b445e72
--- /dev/null
+++ b/src/assistant/tools/assistant/preferencesdialog.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREFERENCESDIALOG_H
+#define PREFERENCESDIALOG_H
+
+#include <QtGui/QDialog>
+#include "ui_preferencesdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class FontPanel;
+class HelpEngineWrapper;
+class QFileSystemWatcher;
+
+class PreferencesDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ PreferencesDialog(QWidget *parent = 0);
+ ~PreferencesDialog();
+
+ void showDialog();
+
+private slots:
+ void updateAttributes(QListWidgetItem *item);
+ void updateFilterMap();
+ void addFilter();
+ void removeFilter();
+ void addDocumentationLocal();
+ void removeDocumentation();
+ void applyChanges();
+ void appFontSettingToggled(bool on);
+ void appFontSettingChanged(int index);
+ void browserFontSettingToggled(bool on);
+ void browserFontSettingChanged(int index);
+
+ void setBlankPage();
+ void setCurrentPage();
+ void setDefaultPage();
+
+signals:
+ void updateBrowserFont();
+ void updateApplicationFont();
+ void updateUserInterface();
+
+private:
+ void updateFilterPage();
+ void updateFontSettingsPage();
+ void updateOptionsPage();
+
+ Ui::PreferencesDialogClass m_ui;
+ bool m_hideFiltersTab;
+ bool m_hideDocsTab;
+ QMap<QString, QStringList> m_filterMapBackup;
+ QMap<QString, QStringList> m_filterMap;
+ QStringList m_removedFilters;
+ QStringList m_docsBackup;
+ QStringList m_regDocs;
+ QStringList m_unregDocs;
+ FontPanel *m_appFontPanel;
+ FontPanel *m_browserFontPanel;
+ bool m_appFontChanged;
+ bool m_browserFontChanged;
+ HelpEngineWrapper &helpEngine;
+ bool m_showTabs;
+};
+
+QT_END_NAMESPACE
+
+#endif // SETTINGSDIALOG_H
diff --git a/src/assistant/tools/assistant/preferencesdialog.ui b/src/assistant/tools/assistant/preferencesdialog.ui
new file mode 100644
index 000000000..1c6833ad9
--- /dev/null
+++ b/src/assistant/tools/assistant/preferencesdialog.ui
@@ -0,0 +1,400 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PreferencesDialogClass</class>
+ <widget class="QDialog" name="PreferencesDialogClass">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>375</width>
+ <height>275</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Preferences</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="fontsTab">
+ <attribute name="title">
+ <string>Fonts</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="fontLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Font settings:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBox">
+ <item>
+ <property name="text">
+ <string>Browser</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Application</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QStackedWidget" name="stackedWidget_2">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="page_4"/>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="filtersTab">
+ <attribute name="title">
+ <string>Filters</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Filter:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_2">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="text">
+ <string>Attributes:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QListWidget" name="filterWidget"/>
+ </item>
+ <item row="1" column="2" rowspan="2">
+ <widget class="QTreeWidget" name="attributeWidget">
+ <column>
+ <property name="text">
+ <string>1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="filterAddButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="filterRemoveButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="docsTab">
+ <attribute name="title">
+ <string>Documentation</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Registered Documentation:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="registeredDocsListWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="docAddButton">
+ <property name="text">
+ <string>Add...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="docRemoveButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="optionsTab">
+ <attribute name="title">
+ <string>Options</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string/>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>On help start:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="helpStartComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>Show my home page</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Show a blank page</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Show my tabs from last session</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>54</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string/>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Homepage</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="homePageLineEdit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="currentPageButton">
+ <property name="text">
+ <string>Current Page</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="blankPageButton">
+ <property name="text">
+ <string>Blank Page</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="defaultPageButton">
+ <property name="text">
+ <string>Restore to default</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>Appearance</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="showTabs">
+ <property name="text">
+ <string>Show tabs for each individual page</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>72</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>comboBox</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>stackedWidget_2</receiver>
+ <slot>setCurrentIndex(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>375</x>
+ <y>32</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>347</x>
+ <y>125</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/assistant/tools/assistant/qtdocinstaller.cpp b/src/assistant/tools/assistant/qtdocinstaller.cpp
new file mode 100644
index 000000000..ffe352c87
--- /dev/null
+++ b/src/assistant/tools/assistant/qtdocinstaller.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDateTime>
+#include <QtCore/QFileSystemWatcher>
+#include <QtHelp/QHelpEngineCore>
+#include "helpenginewrapper.h"
+#include "qtdocinstaller.h"
+
+QT_BEGIN_NAMESPACE
+
+QtDocInstaller::QtDocInstaller(const QList<DocInfo> &docInfos)
+ : m_abort(false), m_docInfos(docInfos)
+{
+ TRACE_OBJ
+}
+
+QtDocInstaller::~QtDocInstaller()
+{
+ TRACE_OBJ
+ if (!isRunning())
+ return;
+ m_mutex.lock();
+ m_abort = true;
+ m_mutex.unlock();
+ wait();
+}
+
+void QtDocInstaller::installDocs()
+{
+ TRACE_OBJ
+ start(LowPriority);
+}
+
+void QtDocInstaller::run()
+{
+ TRACE_OBJ
+ m_qchDir = QLibraryInfo::location(QLibraryInfo::DocumentationPath)
+ + QDir::separator() + QLatin1String("qch");
+ m_qchFiles = m_qchDir.entryList(QStringList() << QLatin1String("*.qch"));
+
+ bool changes = false;
+ foreach (const DocInfo &docInfo, m_docInfos) {
+ changes |= installDoc(docInfo);
+ m_mutex.lock();
+ if (m_abort) {
+ m_mutex.unlock();
+ return;
+ }
+ m_mutex.unlock();
+ }
+ emit docsInstalled(changes);
+}
+
+bool QtDocInstaller::installDoc(const DocInfo &docInfo)
+{
+ TRACE_OBJ
+ const QString &component = docInfo.first;
+ const QStringList &info = docInfo.second;
+ QDateTime dt;
+ if (!info.isEmpty() && !info.first().isEmpty())
+ dt = QDateTime::fromString(info.first(), Qt::ISODate);
+
+ QString qchFile;
+ if (info.count() == 2)
+ qchFile = info.last();
+
+ if (m_qchFiles.isEmpty()) {
+ emit qchFileNotFound(component);
+ return false;
+ }
+ foreach (const QString &f, m_qchFiles) {
+ if (f.startsWith(component)) {
+ QFileInfo fi(m_qchDir.absolutePath() + QDir::separator() + f);
+ if (dt.isValid() && fi.lastModified().toTime_t() == dt.toTime_t()
+ && qchFile == fi.absoluteFilePath())
+ return false;
+ emit registerDocumentation(component, fi.absoluteFilePath());
+ return true;
+ }
+ }
+
+ emit qchFileNotFound(component);
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/qtdocinstaller.h b/src/assistant/tools/assistant/qtdocinstaller.h
new file mode 100644
index 000000000..909df10ce
--- /dev/null
+++ b/src/assistant/tools/assistant/qtdocinstaller.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTDOCINSTALLER
+#define QTDOCINSTALLER
+
+#include <QtCore/QDir>
+#include <QtCore/QMutex>
+#include <QtCore/QPair>
+#include <QtCore/QStringList>
+#include <QtCore/QThread>
+
+QT_BEGIN_NAMESPACE
+
+class HelpEngineWrapper;
+
+class QtDocInstaller : public QThread
+{
+ Q_OBJECT
+
+public:
+ typedef QPair<QString, QStringList> DocInfo;
+ QtDocInstaller(const QList<DocInfo> &docInfos);
+ ~QtDocInstaller();
+ void installDocs();
+
+signals:
+ void qchFileNotFound(const QString &component);
+ void registerDocumentation(const QString &component,
+ const QString &absFileName);
+ void docsInstalled(bool newDocsInstalled);
+
+private:
+ void run();
+ bool installDoc(const DocInfo &docInfo);
+
+ bool m_abort;
+ QMutex m_mutex;
+ QStringList m_qchFiles;
+ QDir m_qchDir;
+ QList<DocInfo> m_docInfos;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/assistant/remotecontrol.cpp b/src/assistant/tools/assistant/remotecontrol.cpp
new file mode 100644
index 000000000..5d93fbc2e
--- /dev/null
+++ b/src/assistant/tools/assistant/remotecontrol.cpp
@@ -0,0 +1,388 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "remotecontrol.h"
+
+#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "mainwindow.h"
+#include "openpagesmanager.h"
+#include "tracer.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QFileSystemWatcher>
+#include <QtCore/QThread>
+#include <QtCore/QTextStream>
+#include <QtCore/QSocketNotifier>
+
+#include <QtGui/QMessageBox>
+#include <QtGui/QApplication>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpIndexWidget>
+#include <QtHelp/QHelpSearchQueryWidget>
+
+#ifdef Q_OS_WIN
+# include "remotecontrol_win.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN
+
+StdInListenerWin::StdInListenerWin(QObject *parent)
+ : QThread(parent)
+{
+ TRACE_OBJ
+}
+
+StdInListenerWin::~StdInListenerWin()
+{
+ TRACE_OBJ
+ terminate();
+ wait();
+}
+
+void StdInListenerWin::run()
+{
+ TRACE_OBJ
+ bool ok = true;
+ char chBuf[4096];
+ DWORD dwRead;
+
+#ifndef Q_WS_WINCE
+ HANDLE hStdin, hStdinDup;
+
+ hStdin = GetStdHandle(STD_INPUT_HANDLE);
+ if (hStdin == INVALID_HANDLE_VALUE)
+ return;
+
+ DuplicateHandle(GetCurrentProcess(), hStdin,
+ GetCurrentProcess(), &hStdinDup,
+ 0, false, DUPLICATE_SAME_ACCESS);
+
+ CloseHandle(hStdin);
+#else
+ HANDLE hStdinDup;
+ hStdinDup = stdin;
+#endif
+
+ while (ok) {
+ ok = ReadFile(hStdinDup, chBuf, sizeof(chBuf), &dwRead, NULL);
+ if (ok && dwRead != 0)
+ emit receivedCommand(QString::fromLocal8Bit(chBuf, dwRead));
+ }
+}
+#endif
+
+RemoteControl::RemoteControl(MainWindow *mainWindow)
+ : QObject(mainWindow)
+ , m_mainWindow(mainWindow)
+ , m_debug(false)
+ , m_caching(true)
+ , m_syncContents(false)
+ , m_expandTOC(-2)
+ , helpEngine(HelpEngineWrapper::instance())
+
+{
+ TRACE_OBJ
+ connect(m_mainWindow, SIGNAL(initDone()), this, SLOT(applyCache()));
+#ifdef Q_OS_WIN
+ StdInListenerWin *l = new StdInListenerWin(this);
+ connect(l, SIGNAL(receivedCommand(QString)),
+ this, SLOT(handleCommandString(QString)));
+ l->start();
+#else
+ QSocketNotifier *notifier = new QSocketNotifier(fileno(stdin),
+ QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(receivedData()));
+ notifier->setEnabled(true);
+#endif
+}
+
+void RemoteControl::receivedData()
+{
+ TRACE_OBJ
+ QByteArray ba;
+ while (true) {
+ char c = getc(stdin);
+ if (c == EOF || c == '\0')
+ break;
+ if (c)
+ ba.append(c);
+ if (c == '\n')
+ break;
+ }
+ handleCommandString(QString::fromLocal8Bit(ba));
+}
+
+void RemoteControl::handleCommandString(const QString &cmdString)
+{
+ TRACE_OBJ
+ QStringList cmds = cmdString.split(QLatin1Char(';'));
+ QStringList::const_iterator it = cmds.constBegin();
+ while (it != cmds.constEnd()) {
+ QString cmd, arg;
+ splitInputString(*it, cmd, arg);
+
+ if (m_debug)
+ QMessageBox::information(0, tr("Debugging Remote Control"),
+ tr("Received Command: %1 %2").arg(cmd).arg(arg));
+
+ if (cmd == QLatin1String("debug"))
+ handleDebugCommand(arg);
+ else if (cmd == QLatin1String("show"))
+ handleShowOrHideCommand(arg, true);
+ else if (cmd == QLatin1String("hide"))
+ handleShowOrHideCommand(arg, false);
+ else if (cmd == QLatin1String("setsource"))
+ handleSetSourceCommand(arg);
+ else if (cmd == QLatin1String("synccontents"))
+ handleSyncContentsCommand();
+ else if (cmd == QLatin1String("activatekeyword"))
+ handleActivateKeywordCommand(arg);
+ else if (cmd == QLatin1String("activateidentifier"))
+ handleActivateIdentifierCommand(arg);
+ else if (cmd == QLatin1String("expandtoc"))
+ handleExpandTocCommand(arg);
+ else if (cmd == QLatin1String("setcurrentfilter"))
+ handleSetCurrentFilterCommand(arg);
+ else if (cmd == QLatin1String("register"))
+ handleRegisterCommand(arg);
+ else if (cmd == QLatin1String("unregister"))
+ handleUnregisterCommand(arg);
+ else
+ return;
+
+ ++it;
+ }
+ m_mainWindow->raise();
+ m_mainWindow->activateWindow();
+}
+
+void RemoteControl::splitInputString(const QString &input, QString &cmd,
+ QString &arg)
+{
+ TRACE_OBJ
+ QString cmdLine = input.trimmed();
+ int i = cmdLine.indexOf(QLatin1Char(' '));
+ cmd = cmdLine.left(i);
+ arg = cmdLine.mid(i+1);
+ cmd = cmd.toLower();
+}
+
+void RemoteControl::handleDebugCommand(const QString &arg)
+{
+ TRACE_OBJ
+ m_debug = arg == QLatin1String("on");
+}
+
+void RemoteControl::handleShowOrHideCommand(const QString &arg, bool show)
+{
+ TRACE_OBJ
+ if (arg.toLower() == QLatin1String("contents"))
+ m_mainWindow->setContentsVisible(show);
+ else if (arg.toLower() == QLatin1String("index"))
+ m_mainWindow->setIndexVisible(show);
+ else if (arg.toLower() == QLatin1String("bookmarks"))
+ m_mainWindow->setBookmarksVisible(show);
+ else if (arg.toLower() == QLatin1String("search"))
+ m_mainWindow->setSearchVisible(show);
+}
+
+void RemoteControl::handleSetSourceCommand(const QString &arg)
+{
+ TRACE_OBJ
+ QUrl url(arg);
+ if (url.isValid()) {
+ if (url.isRelative())
+ url = CentralWidget::instance()->currentSource().resolved(url);
+ if (m_caching) {
+ clearCache();
+ m_setSource = url;
+ } else {
+ CentralWidget::instance()->setSource(url);
+ }
+ }
+}
+
+void RemoteControl::handleSyncContentsCommand()
+{
+ TRACE_OBJ
+ if (m_caching)
+ m_syncContents = true;
+ else
+ m_mainWindow->syncContents();
+}
+
+void RemoteControl::handleActivateKeywordCommand(const QString &arg)
+{
+ TRACE_OBJ
+ if (m_caching) {
+ clearCache();
+ m_activateKeyword = arg;
+ } else {
+ m_mainWindow->setIndexString(arg);
+ if (!arg.isEmpty()) {
+ if (!helpEngine.indexWidget()->currentIndex().isValid()
+ && helpEngine.fullTextSearchFallbackEnabled()) {
+ if (QHelpSearchEngine *se = helpEngine.searchEngine()) {
+ m_mainWindow->setSearchVisible(true);
+ if (QHelpSearchQueryWidget *w = se->queryWidget()) {
+ w->collapseExtendedSearch();
+ QList<QHelpSearchQuery> queryList;
+ queryList << QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
+ QStringList(arg));
+ w->setQuery(queryList);
+ se->search(queryList);
+ }
+ }
+ } else {
+ m_mainWindow->setIndexVisible(true);
+ helpEngine.indexWidget()->activateCurrentItem();
+ }
+ }
+ }
+}
+
+void RemoteControl::handleActivateIdentifierCommand(const QString &arg)
+{
+ TRACE_OBJ
+ if (m_caching) {
+ clearCache();
+ m_activateIdentifier = arg;
+ } else {
+ const QMap<QString, QUrl> &links = helpEngine.linksForIdentifier(arg);
+ if (!links.isEmpty())
+ CentralWidget::instance()->setSource(links.constBegin().value());
+ }
+}
+
+void RemoteControl::handleExpandTocCommand(const QString &arg)
+{
+ TRACE_OBJ
+ bool ok = false;
+ int depth = -2;
+ if (!arg.isEmpty())
+ depth = arg.toInt(&ok);
+ if (!ok || depth < -2)
+ depth = -2;
+
+ if (m_caching)
+ m_expandTOC = depth;
+ else if (depth != -2)
+ m_mainWindow->expandTOC(depth);
+}
+
+void RemoteControl::handleSetCurrentFilterCommand(const QString &arg)
+{
+ TRACE_OBJ
+ if (helpEngine.customFilters().contains(arg)) {
+ if (m_caching) {
+ clearCache();
+ m_currentFilter = arg;
+ } else {
+ helpEngine.setCurrentFilter(arg);
+ }
+ }
+}
+
+void RemoteControl::handleRegisterCommand(const QString &arg)
+{
+ TRACE_OBJ
+ const QString &absFileName = QFileInfo(arg).absoluteFilePath();
+ if (helpEngine.registeredDocumentations().
+ contains(QHelpEngineCore::namespaceName(absFileName)))
+ return;
+ if (helpEngine.registerDocumentation(absFileName))
+ helpEngine.setupData();
+}
+
+void RemoteControl::handleUnregisterCommand(const QString &arg)
+{
+ TRACE_OBJ
+ const QString &absFileName = QFileInfo(arg).absoluteFilePath();
+ const QString &ns = QHelpEngineCore::namespaceName(absFileName);
+ if (helpEngine.registeredDocumentations().contains(ns)) {
+ OpenPagesManager::instance()->closePages(ns);
+ if (helpEngine.unregisterDocumentation(ns))
+ helpEngine.setupData();
+ }
+}
+
+void RemoteControl::applyCache()
+{
+ TRACE_OBJ
+ if (m_setSource.isValid()) {
+ CentralWidget::instance()->setSource(m_setSource);
+ } else if (!m_activateKeyword.isEmpty()) {
+ m_mainWindow->setIndexString(m_activateKeyword);
+ helpEngine.indexWidget()->activateCurrentItem();
+ } else if (!m_activateIdentifier.isEmpty()) {
+ QMap<QString, QUrl> links =
+ helpEngine.linksForIdentifier(m_activateIdentifier);
+ if (!links.isEmpty())
+ CentralWidget::instance()->setSource(links.constBegin().value());
+ } else if (!m_currentFilter.isEmpty()) {
+ helpEngine.setCurrentFilter(m_currentFilter);
+ }
+
+ if (m_syncContents)
+ m_mainWindow->syncContents();
+
+ Q_ASSERT(m_expandTOC >= -2);
+ if (m_expandTOC != -2)
+ m_mainWindow->expandTOC(m_expandTOC);
+
+ m_caching = false;
+}
+
+void RemoteControl::clearCache()
+{
+ TRACE_OBJ
+ m_currentFilter.clear();
+ m_setSource.clear();
+ m_syncContents = false;
+ m_activateKeyword.clear();
+ m_activateIdentifier.clear();
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/remotecontrol.h b/src/assistant/tools/assistant/remotecontrol.h
new file mode 100644
index 000000000..4a185f050
--- /dev/null
+++ b/src/assistant/tools/assistant/remotecontrol.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef REMOTECONTROL_H
+#define REMOTECONTROL_H
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+class HelpEngineWrapper;
+class MainWindow;
+
+class RemoteControl : public QObject
+{
+ Q_OBJECT
+
+public:
+ RemoteControl(MainWindow *mainWindow);
+
+private slots:
+ void receivedData();
+ void handleCommandString(const QString &cmdString);
+ void applyCache();
+
+private:
+ void clearCache();
+ void splitInputString(const QString &input, QString &cmd, QString &arg);
+ void handleDebugCommand(const QString &arg);
+ void handleShowOrHideCommand(const QString &arg, bool show);
+ void handleSetSourceCommand(const QString &arg);
+ void handleSyncContentsCommand();
+ void handleActivateKeywordCommand(const QString &arg);
+ void handleActivateIdentifierCommand(const QString &arg);
+ void handleExpandTocCommand(const QString &arg);
+ void handleSetCurrentFilterCommand(const QString &arg);
+ void handleRegisterCommand(const QString &arg);
+ void handleUnregisterCommand(const QString &arg);
+
+private:
+ MainWindow *m_mainWindow;
+ bool m_debug;
+
+ bool m_caching;
+ QUrl m_setSource;
+ bool m_syncContents;
+ QString m_activateKeyword;
+ QString m_activateIdentifier;
+ int m_expandTOC;
+ QString m_currentFilter;
+ HelpEngineWrapper &helpEngine;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/assistant/remotecontrol_win.h b/src/assistant/tools/assistant/remotecontrol_win.h
new file mode 100644
index 000000000..807815df1
--- /dev/null
+++ b/src/assistant/tools/assistant/remotecontrol_win.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef REMOTECONTROL_WIN_H
+#define REMOTECONTROL_WIN_H
+
+#include <windows.h>
+#include <QtCore/QThread>
+
+QT_BEGIN_NAMESPACE
+
+class StdInListenerWin : public QThread
+{
+ Q_OBJECT
+
+public:
+ StdInListenerWin(QObject *parent);
+ ~StdInListenerWin();
+
+signals:
+ void receivedCommand(const QString &cmd);
+
+private:
+ void run();
+ bool ok;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/assistant/searchwidget.cpp b/src/assistant/tools/assistant/searchwidget.cpp
new file mode 100644
index 000000000..627d9e745
--- /dev/null
+++ b/src/assistant/tools/assistant/searchwidget.cpp
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include "mainwindow.h"
+#include "searchwidget.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include <QtGui/QMenu>
+#include <QtGui/QLayout>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QClipboard>
+#include <QtGui/QApplication>
+#include <QtGui/QTextBrowser>
+
+#include <QtHelp/QHelpSearchEngine>
+#include <QtHelp/QHelpSearchQueryWidget>
+#include <QtHelp/QHelpSearchResultWidget>
+
+QT_BEGIN_NAMESPACE
+
+SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent)
+ : QWidget(parent)
+ , zoomCount(0)
+ , searchEngine(engine)
+{
+ TRACE_OBJ
+ QVBoxLayout *vLayout = new QVBoxLayout(this);
+
+ resultWidget = searchEngine->resultWidget();
+ QHelpSearchQueryWidget *queryWidget = searchEngine->queryWidget();
+
+ vLayout->addWidget(queryWidget);
+ vLayout->addWidget(resultWidget);
+
+ setFocusProxy(queryWidget);
+
+ connect(queryWidget, SIGNAL(search()), this, SLOT(search()));
+ connect(resultWidget, SIGNAL(requestShowLink(QUrl)), this,
+ SIGNAL(requestShowLink(QUrl)));
+
+ connect(searchEngine, SIGNAL(searchingStarted()), this,
+ SLOT(searchingStarted()));
+ connect(searchEngine, SIGNAL(searchingFinished(int)), this,
+ SLOT(searchingFinished(int)));
+
+ QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
+ if (browser) // Will be null if lib was configured not to use CLucene.
+ browser->viewport()->installEventFilter(this);
+}
+
+SearchWidget::~SearchWidget()
+{
+ TRACE_OBJ
+ // nothing todo
+}
+
+void SearchWidget::zoomIn()
+{
+ TRACE_OBJ
+ QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
+ if (browser && zoomCount != 10) {
+ zoomCount++;
+ browser->zoomIn();
+ }
+}
+
+void SearchWidget::zoomOut()
+{
+ TRACE_OBJ
+ QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
+ if (browser && zoomCount != -5) {
+ zoomCount--;
+ browser->zoomOut();
+ }
+}
+
+void SearchWidget::resetZoom()
+{
+ TRACE_OBJ
+ if (zoomCount == 0)
+ return;
+
+ QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
+ if (browser) {
+ browser->zoomOut(zoomCount);
+ zoomCount = 0;
+ }
+}
+
+void SearchWidget::search() const
+{
+ TRACE_OBJ
+ QList<QHelpSearchQuery> query = searchEngine->queryWidget()->query();
+ searchEngine->search(query);
+}
+
+void SearchWidget::searchingStarted()
+{
+ TRACE_OBJ
+ qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
+}
+
+void SearchWidget::searchingFinished(int hits)
+{
+ TRACE_OBJ
+ Q_UNUSED(hits)
+ qApp->restoreOverrideCursor();
+}
+
+bool SearchWidget::eventFilter(QObject* o, QEvent *e)
+{
+ TRACE_OBJ
+ QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
+ if (browser && o == browser->viewport()
+ && e->type() == QEvent::MouseButtonRelease){
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ QUrl link = resultWidget->linkAt(me->pos());
+ if (!link.isEmpty() || link.isValid()) {
+ bool controlPressed = me->modifiers() & Qt::ControlModifier;
+ if((me->button() == Qt::LeftButton && controlPressed)
+ || (me->button() == Qt::MidButton)) {
+ emit requestShowLinkInNewTab(link);
+ }
+ }
+ }
+ return QWidget::eventFilter(o,e);
+}
+
+void SearchWidget::keyPressEvent(QKeyEvent *keyEvent)
+{
+ TRACE_OBJ
+ if (keyEvent->key() == Qt::Key_Escape)
+ MainWindow::activateCurrentBrowser();
+ else
+ keyEvent->ignore();
+}
+
+void SearchWidget::contextMenuEvent(QContextMenuEvent *contextMenuEvent)
+{
+ TRACE_OBJ
+ QMenu menu;
+ QPoint point = contextMenuEvent->globalPos();
+
+ QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
+ if (!browser)
+ return;
+
+ point = browser->mapFromGlobal(point);
+ if (!browser->rect().contains(point, true))
+ return;
+
+ QUrl link = browser->anchorAt(point);
+
+ QKeySequence keySeq(QKeySequence::Copy);
+ QAction *copyAction = menu.addAction(tr("&Copy") + QLatin1String("\t") +
+ keySeq.toString(QKeySequence::NativeText));
+ copyAction->setEnabled(QTextCursor(browser->textCursor()).hasSelection());
+
+ QAction *copyAnchorAction = menu.addAction(tr("Copy &Link Location"));
+ copyAnchorAction->setEnabled(!link.isEmpty() && link.isValid());
+
+ keySeq = QKeySequence(Qt::CTRL);
+ QAction *newTabAction = menu.addAction(tr("Open Link in New Tab") +
+ QLatin1String("\t") + keySeq.toString(QKeySequence::NativeText) +
+ QLatin1String("LMB"));
+ newTabAction->setEnabled(!link.isEmpty() && link.isValid());
+
+ menu.addSeparator();
+
+ keySeq = QKeySequence::SelectAll;
+ QAction *selectAllAction = menu.addAction(tr("Select All") +
+ QLatin1String("\t") + keySeq.toString(QKeySequence::NativeText));
+
+ QAction *usedAction = menu.exec(mapToGlobal(contextMenuEvent->pos()));
+ if (usedAction == copyAction) {
+ QTextCursor cursor = browser->textCursor();
+ if (!cursor.isNull() && cursor.hasSelection()) {
+ QString selectedText = cursor.selectedText();
+ QMimeData *data = new QMimeData();
+ data->setText(selectedText);
+ QApplication::clipboard()->setMimeData(data);
+ }
+ }
+ else if (usedAction == copyAnchorAction) {
+ QApplication::clipboard()->setText(link.toString());
+ }
+ else if (usedAction == newTabAction) {
+ emit requestShowLinkInNewTab(link);
+ }
+ else if (usedAction == selectAllAction) {
+ browser->selectAll();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/searchwidget.h b/src/assistant/tools/assistant/searchwidget.h
new file mode 100644
index 000000000..077c78771
--- /dev/null
+++ b/src/assistant/tools/assistant/searchwidget.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SEARCHWIDGET_H
+#define SEARCHWIDGET_H
+
+#include <QtCore/QUrl>
+#include <QtCore/QPoint>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QMouseEvent;
+class QHelpSearchEngine;
+class QHelpSearchResultWidget;
+
+class SearchWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SearchWidget(QHelpSearchEngine *engine, QWidget *parent = 0);
+ ~SearchWidget();
+
+ void zoomIn();
+ void zoomOut();
+ void resetZoom();
+
+signals:
+ void requestShowLink(const QUrl &url);
+ void requestShowLinkInNewTab(const QUrl &url);
+
+private slots:
+ void search() const;
+ void searchingStarted();
+ void searchingFinished(int hits);
+
+private:
+ bool eventFilter(QObject* o, QEvent *e);
+ void keyPressEvent(QKeyEvent *keyEvent);
+ void contextMenuEvent(QContextMenuEvent *contextMenuEvent);
+
+private:
+ int zoomCount;
+ QHelpSearchEngine *searchEngine;
+ QHelpSearchResultWidget *resultWidget;
+};
+
+QT_END_NAMESPACE
+
+#endif // SEARCHWIDGET_H
diff --git a/src/assistant/tools/assistant/topicchooser.cpp b/src/assistant/tools/assistant/topicchooser.cpp
new file mode 100644
index 000000000..6f2810bf4
--- /dev/null
+++ b/src/assistant/tools/assistant/topicchooser.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include "topicchooser.h"
+
+QT_BEGIN_NAMESPACE
+
+TopicChooser::TopicChooser(QWidget *parent, const QString &keyword,
+ const QMap<QString, QUrl> &links)
+ : QDialog(parent)
+{
+ TRACE_OBJ
+ ui.setupUi(this);
+ ui.label->setText(tr("Choose a topic for <b>%1</b>:").arg(keyword));
+
+ QMap<QString, QUrl>::const_iterator it = links.constBegin();
+ for (; it != links.constEnd(); ++it) {
+ ui.listWidget->addItem(it.key());
+ m_links.append(it.value());
+ }
+
+ if (ui.listWidget->count() != 0)
+ ui.listWidget->setCurrentRow(0);
+ ui.listWidget->setFocus();
+
+ connect(ui.buttonDisplay, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
+ connect(ui.listWidget, SIGNAL(itemActivated(QListWidgetItem*)), this,
+ SLOT(accept()));
+}
+
+QUrl TopicChooser::link() const
+{
+ TRACE_OBJ
+ QListWidgetItem *item = ui.listWidget->currentItem();
+ if (!item)
+ return QUrl();
+
+ QString title = item->text();
+ if (title.isEmpty())
+ return QUrl();
+
+ const int row = ui.listWidget->row(item);
+ Q_ASSERT(row < m_links.count());
+ return m_links.at(row);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/topicchooser.h b/src/assistant/tools/assistant/topicchooser.h
new file mode 100644
index 000000000..a80f1963d
--- /dev/null
+++ b/src/assistant/tools/assistant/topicchooser.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOPICCHOOSER_H
+#define TOPICCHOOSER_H
+
+#include "ui_topicchooser.h"
+
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class TopicChooser : public QDialog
+{
+ Q_OBJECT
+
+public:
+ TopicChooser(QWidget *parent, const QString &keyword,
+ const QMap<QString, QUrl> &links);
+
+ QUrl link() const;
+
+private:
+ Ui::TopicChooser ui;
+ QList<QUrl> m_links;
+};
+
+QT_END_NAMESPACE
+
+#endif // TOPICCHOOSER_H
diff --git a/src/assistant/tools/assistant/topicchooser.ui b/src/assistant/tools/assistant/topicchooser.ui
new file mode 100644
index 000000000..d4c90bb4b
--- /dev/null
+++ b/src/assistant/tools/assistant/topicchooser.ui
@@ -0,0 +1,116 @@
+<UI version="4.0" stdsetdef="1" >
+ <class>TopicChooser</class>
+ <widget class="QDialog" name="TopicChooser" >
+ <property name="objectName" >
+ <string notr="true">TopicChooser</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>391</width>
+ <height>223</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Choose Topic</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="objectName" >
+ <string notr="true">unnamed</string>
+ </property>
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="objectName" >
+ <string notr="true">label</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Topics</string>
+ </property>
+ <property name="buddy" stdset="0" >
+ <cstring>listWidget</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget" >
+ <property name="objectName" >
+ <string notr="true">listWidget</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="Layout16" >
+ <property name="objectName" >
+ <string notr="true">Layout16</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="objectName" >
+ <string notr="true">unnamed</string>
+ </property>
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer name="Horizontal Spacing2" >
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="sizeType" >
+ <enum>Expanding</enum>
+ </property>
+ <property name="orientation" >
+ <enum>Horizontal</enum>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonDisplay" >
+ <property name="objectName" >
+ <string notr="true">buttonDisplay</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Display</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="objectName" >
+ <string notr="true">buttonCancel</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Close</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+</UI>
diff --git a/src/assistant/tools/assistant/tracer.h b/src/assistant/tools/assistant/tracer.h
new file mode 100644
index 000000000..1ed609acb
--- /dev/null
+++ b/src/assistant/tools/assistant/tracer.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRACER_H
+#define TRACER_H
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+class Tracer
+{
+public:
+ Tracer(const char *func) : m_func(func)
+ {
+ qDebug("Entering function %s.", m_func);
+ }
+
+ ~Tracer()
+ {
+ qDebug("Leaving function %s.", m_func);
+ }
+
+private:
+ const char * const m_func;
+};
+
+QT_END_NAMESPACE
+
+// #define TRACING_REQUESTED
+#ifdef TRACING_REQUESTED
+#define TRACE_OBJ Tracer traceObj__(Q_FUNC_INFO);
+#else
+#define TRACE_OBJ
+#endif
+
+#endif // TRACER_H
diff --git a/src/assistant/tools/assistant/xbelsupport.cpp b/src/assistant/tools/assistant/xbelsupport.cpp
new file mode 100644
index 000000000..2979d10c1
--- /dev/null
+++ b/src/assistant/tools/assistant/xbelsupport.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include "xbelsupport.h"
+
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+
+#include <QtCore/QDate>
+#include <QtCore/QModelIndex>
+
+QT_BEGIN_NAMESPACE
+
+struct Bookmark {
+ QString title;
+ QString url;
+ bool folded;
+};
+
+XbelWriter::XbelWriter(BookmarkModel *model)
+ : QXmlStreamWriter()
+ , bookmarkModel(model)
+{
+ TRACE_OBJ
+ setAutoFormatting(true);
+}
+
+void XbelWriter::writeToFile(QIODevice *device)
+{
+ TRACE_OBJ
+ setDevice(device);
+
+ writeStartDocument();
+ writeDTD(QLatin1String("<!DOCTYPE xbel>"));
+ writeStartElement(QLatin1String("xbel"));
+ writeAttribute(QLatin1String("version"), QLatin1String("1.0"));
+
+ const QModelIndex &root = bookmarkModel->index(0,0, QModelIndex());
+ for (int i = 0; i < bookmarkModel->rowCount(root); ++i)
+ writeData(bookmarkModel->index(i, 0, root));
+ writeEndDocument();
+}
+
+void XbelWriter::writeData(const QModelIndex &index)
+{
+ TRACE_OBJ
+ if (index.isValid()) {
+ Bookmark entry;
+ entry.title = index.data().toString();
+ entry.url = index.data(UserRoleUrl).toString();
+
+ if (index.data(UserRoleFolder).toBool()) {
+ writeStartElement(QLatin1String("folder"));
+ entry.folded = !index.data(UserRoleExpanded).toBool();
+ writeAttribute(QLatin1String("folded"), entry.folded
+ ? QLatin1String("yes") : QLatin1String("no"));
+ writeTextElement(QLatin1String("title"), entry.title);
+
+ for (int i = 0; i < bookmarkModel->rowCount(index); ++i)
+ writeData(bookmarkModel->index(i, 0 , index));
+ writeEndElement();
+ } else {
+ writeStartElement(QLatin1String("bookmark"));
+ writeAttribute(QLatin1String("href"), entry.url);
+ writeTextElement(QLatin1String("title"), entry.title);
+ writeEndElement();
+ }
+ }
+}
+
+// -- XbelReader
+
+XbelReader::XbelReader(BookmarkModel *model)
+ : QXmlStreamReader()
+ , bookmarkModel(model)
+{
+ TRACE_OBJ
+}
+
+bool XbelReader::readFromFile(QIODevice *device)
+{
+ TRACE_OBJ
+ setDevice(device);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isStartElement()) {
+ if (name() == QLatin1String("xbel")
+ && attributes().value(QLatin1String("version"))
+ == QLatin1String("1.0")) {
+ const QModelIndex &root = bookmarkModel->index(0,0, QModelIndex());
+ parents.append(bookmarkModel->addItem(root, true));
+ readXBEL();
+ bookmarkModel->setData(parents.first(),
+ QDate::currentDate().toString(Qt::ISODate), Qt::EditRole);
+ } else {
+ raiseError(QLatin1String("The file is not an XBEL version 1.0 file."));
+ }
+ }
+ }
+
+ return !error();
+}
+
+void XbelReader::readXBEL()
+{
+ TRACE_OBJ
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ if (name() == QLatin1String("folder"))
+ readFolder();
+ else if (name() == QLatin1String("bookmark"))
+ readBookmark();
+ else
+ readUnknownElement();
+ }
+ }
+}
+
+void XbelReader::readFolder()
+{
+ TRACE_OBJ
+ parents.append(bookmarkModel->addItem(parents.last(), true));
+ bookmarkModel->setData(parents.last(),
+ attributes().value(QLatin1String("folded")) == QLatin1String("no"),
+ UserRoleExpanded);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ if (name() == QLatin1String("title")) {
+ bookmarkModel->setData(parents.last(), readElementText(),
+ Qt::EditRole);
+ } else if (name() == QLatin1String("folder"))
+ readFolder();
+ else if (name() == QLatin1String("bookmark"))
+ readBookmark();
+ else
+ readUnknownElement();
+ }
+ }
+
+ parents.removeLast();
+}
+
+void XbelReader::readBookmark()
+{
+ TRACE_OBJ
+ const QModelIndex &index = bookmarkModel->addItem(parents.last(), false);
+ if (BookmarkItem* item = bookmarkModel->itemFromIndex(index)) {
+ item->setData(UserRoleUrl, attributes().value(QLatin1String("href"))
+ .toString());
+ }
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ if (name() == QLatin1String("title"))
+ bookmarkModel->setData(index, readElementText(), Qt::EditRole);
+ else
+ readUnknownElement();
+ }
+ }
+}
+
+void XbelReader::readUnknownElement()
+{
+ TRACE_OBJ
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ readUnknownElement();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/assistant/xbelsupport.h b/src/assistant/tools/assistant/xbelsupport.h
new file mode 100644
index 000000000..4c2a211ad
--- /dev/null
+++ b/src/assistant/tools/assistant/xbelsupport.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XBELSUPPORT_H
+#define XBELSUPPORT_H
+
+#include <QtXml/QXmlStreamReader>
+#include <QtCore/QPersistentModelIndex>
+
+QT_FORWARD_DECLARE_CLASS(QIODevice)
+QT_FORWARD_DECLARE_CLASS(QModelIndex)
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkModel;
+
+class XbelWriter : public QXmlStreamWriter
+{
+public:
+ XbelWriter(BookmarkModel *model);
+ void writeToFile(QIODevice *device);
+
+private:
+ void writeData(const QModelIndex &index);
+
+private:
+ BookmarkModel *bookmarkModel;
+};
+
+class XbelReader : public QXmlStreamReader
+{
+public:
+ XbelReader(BookmarkModel *model);
+ bool readFromFile(QIODevice *device);
+
+private:
+ void readXBEL();
+ void readFolder();
+ void readBookmark();
+ void readUnknownElement();
+
+private:
+ BookmarkModel *bookmarkModel;
+ QList<QPersistentModelIndex> parents;
+};
+
+QT_END_NAMESPACE
+
+#endif // XBELSUPPORT_H
diff --git a/src/assistant/tools/qcollectiongenerator/main.cpp b/src/assistant/tools/qcollectiongenerator/main.cpp
new file mode 100644
index 000000000..058d4281a
--- /dev/null
+++ b/src/assistant/tools/qcollectiongenerator/main.cpp
@@ -0,0 +1,615 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../shared/collectionconfiguration.h"
+#include "../shared/helpgenerator.h"
+
+#include <private/qhelpgenerator_p.h>
+#include <private/qhelpprojectdata_p.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QMap>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDateTime>
+#include <QtCore/QBuffer>
+#include <QtCore/QTranslator>
+#include <QtCore/QLocale>
+#include <QtCore/QLibraryInfo>
+#include <QtHelp/QHelpEngineCore>
+#include <QtXml/QXmlStreamReader>
+
+
+QT_USE_NAMESPACE
+
+class QCG {
+ Q_DECLARE_TR_FUNCTIONS(QCollectionGenerator)
+};
+
+class CollectionConfigReader : public QXmlStreamReader
+{
+public:
+ void readData(const QByteArray &contents);
+
+ QString title() const { return m_title; }
+ QString homePage() const { return m_homePage; }
+ QString startPage() const { return m_startPage; }
+ QString applicationIcon() const { return m_applicationIcon; }
+ QString currentFilter() const { return m_currentFilter; }
+ bool enableFilterFunctionality() const
+ { return m_enableFilterFunctionality; }
+ bool hideFilterFunctionality() const
+ { return m_hideFilterFunctionality; }
+ bool enableAddressBar() const { return m_enableAddressBar; }
+ bool hideAddressBar() const { return m_hideAddressBar; }
+ bool enableDocumentationManager() const
+ { return m_enableDocumentationManager; }
+
+ QMap<QString, QString> aboutMenuTexts() const
+ { return m_aboutMenuTexts; }
+ QString aboutIcon() const { return m_aboutIcon; }
+ QMap<QString, QString> aboutTextFiles() const
+ { return m_aboutTextFiles; }
+
+ QMap<QString, QString> filesToGenerate() const
+ { return m_filesToGenerate; }
+
+ QStringList filesToRegister() const { return m_filesToRegister; }
+
+ QString cacheDirectory() const { return m_cacheDirectory; }
+ bool cacheDirRelativeToCollection() const { return m_cacheDirRelativeToCollection; }
+
+ bool fullTextSearchFallbackEnabled() const {
+ return m_enableFullTextSearchFallback;
+ }
+
+private:
+ void raiseErrorWithLine();
+ void readConfig();
+ void readAssistantSettings();
+ void readMenuTexts();
+ void readAboutDialog();
+ void readDocFiles();
+ void readGenerate();
+ void readFiles();
+ void readRegister();
+
+ QString m_title;
+ QString m_homePage;
+ QString m_startPage;
+ QString m_applicationIcon;
+ QString m_currentFilter;
+ bool m_enableFilterFunctionality;
+ bool m_hideFilterFunctionality;
+ bool m_enableAddressBar;
+ bool m_hideAddressBar;
+ bool m_enableDocumentationManager;
+ QMap<QString, QString> m_aboutMenuTexts;
+ QString m_aboutIcon;
+ QMap<QString, QString> m_aboutTextFiles;
+ QMap<QString, QString> m_filesToGenerate;
+ QStringList m_filesToRegister;
+ QString m_cacheDirectory;
+ bool m_cacheDirRelativeToCollection;
+ bool m_enableFullTextSearchFallback;
+};
+
+void CollectionConfigReader::raiseErrorWithLine()
+{
+ raiseError(QCG::tr("Unknown token at line %1.").arg(lineNumber()));
+}
+
+void CollectionConfigReader::readData(const QByteArray &contents)
+{
+ m_enableFilterFunctionality = true;
+ m_hideFilterFunctionality = true;
+ m_enableAddressBar = true;
+ m_hideAddressBar = true;
+ m_enableDocumentationManager = true;
+ m_enableFullTextSearchFallback = false;
+
+ addData(contents);
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("QHelpCollectionProject")
+ && attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
+ readConfig();
+ else
+ raiseError(QCG::tr("Unknown token at line %1. "
+ "Expected \"QtHelpCollectionProject\".")
+ .arg(lineNumber()));
+ }
+ }
+}
+
+void CollectionConfigReader::readConfig()
+{
+ bool ok = false;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("assistant"))
+ readAssistantSettings();
+ else if (name() == QLatin1String("docFiles"))
+ readDocFiles();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("QHelpCollectionProject")) {
+ ok = true;
+ }
+ }
+ if (!ok && !hasError())
+ raiseError(QCG::tr("Missing end tags."));
+}
+
+void CollectionConfigReader::readAssistantSettings()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("title")) {
+ m_title = readElementText();
+ } else if (name() == QLatin1String("homePage")) {
+ m_homePage = readElementText();
+ } else if (name() == QLatin1String("startPage")) {
+ m_startPage = readElementText();
+ } else if (name() == QLatin1String("currentFilter")) {
+ m_currentFilter = readElementText();
+ } else if (name() == QLatin1String("applicationIcon")) {
+ m_applicationIcon = readElementText();
+ } else if (name() == QLatin1String("enableFilterFunctionality")) {
+ if (attributes().value(QLatin1String("visible")) == QLatin1String("true"))
+ m_hideFilterFunctionality = false;
+ if (readElementText() == QLatin1String("false"))
+ m_enableFilterFunctionality = false;
+ } else if (name() == QLatin1String("enableDocumentationManager")) {
+ if (readElementText() == QLatin1String("false"))
+ m_enableDocumentationManager = false;
+ } else if (name() == QLatin1String("enableAddressBar")) {
+ if (attributes().value(QLatin1String("visible")) == QLatin1String("true"))
+ m_hideAddressBar = false;
+ if (readElementText() == QLatin1String("false"))
+ m_enableAddressBar = false;
+ } else if (name() == QLatin1String("aboutMenuText")) {
+ readMenuTexts();
+ } else if (name() == QLatin1String("aboutDialog")) {
+ readAboutDialog();
+ } else if (name() == "cacheDirectory") {
+ m_cacheDirRelativeToCollection =
+ attributes().value(QLatin1String("base"))
+ == QLatin1String("collection");
+ m_cacheDirectory = readElementText();
+ } else if (name() == QLatin1String("enableFullTextSearchFallback")) {
+ if (readElementText() == QLatin1String("true"))
+ m_enableFullTextSearchFallback = true;
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("assistant")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readMenuTexts()
+{
+ while (!atEnd())
+ {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("text")) {
+ QString lang = attributes().value(QLatin1String("language")).toString();
+ if (lang.isEmpty())
+ lang = QLatin1String("default");
+ m_aboutMenuTexts.insert(lang, readElementText());
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("aboutMenuText")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readAboutDialog()
+{
+ while (!atEnd())
+ {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file")) {
+ QString lang = attributes().value(QLatin1String("language")).toString();
+ if (lang.isEmpty())
+ lang = QLatin1String("default");
+ m_aboutTextFiles.insert(lang, readElementText());
+ } else if (name() == QLatin1String("icon")) {
+ m_aboutIcon = readElementText();
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("aboutDialog")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readDocFiles()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("generate")) {
+ readGenerate();
+ } else if (name() == QLatin1String("register")) {
+ readRegister();
+ } else {
+ raiseErrorWithLine();
+ }
+ } else if (isEndElement() && name() == QLatin1String("docFiles")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readGenerate()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file"))
+ readFiles();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("generate")) {
+ break;
+ }
+ }
+}
+
+void CollectionConfigReader::readFiles()
+{
+ QString input;
+ QString output;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("input"))
+ input = readElementText();
+ else if (name() == QLatin1String("output"))
+ output = readElementText();
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("file")) {
+ break;
+ }
+ }
+ if (input.isEmpty() || output.isEmpty()) {
+ raiseError(QCG::tr("Missing input or output file for help file generation."));
+ return;
+ }
+ m_filesToGenerate.insert(input, output);
+}
+
+void CollectionConfigReader::readRegister()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("file"))
+ m_filesToRegister.append(readElementText());
+ else
+ raiseErrorWithLine();
+ } else if (isEndElement() && name() == QLatin1String("register")) {
+ break;
+ }
+ }
+}
+
+namespace {
+ QString absoluteFileName(const QString &basePath, const QString &fileName)
+ {
+ return QFileInfo(fileName).isAbsolute() ?
+ fileName : basePath + QDir::separator() + fileName;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ QString error;
+ QString arg;
+ QString collectionFile;
+ QString configFile;
+ QString basePath;
+ bool showHelp = false;
+ bool showVersion = false;
+
+ QCoreApplication app(argc, argv);
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QTranslator qt_helpTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("assistant_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)
+ && qt_helpTranslator.load(QLatin1String("qt_help_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ app.installTranslator(&qt_helpTranslator);
+ }
+#endif // Q_OS_WIN32
+
+ for (int i=1; i<argc; ++i) {
+ arg = QString::fromLocal8Bit(argv[i]);
+ if (arg == QLatin1String("-o")) {
+ if (++i < argc) {
+ QFileInfo fi(QString::fromLocal8Bit(argv[i]));
+ collectionFile = fi.absoluteFilePath();
+ } else {
+ error = QCG::tr("Missing output file name.");
+ }
+ } else if (arg == QLatin1String("-h")) {
+ showHelp = true;
+ } else if (arg == QLatin1String("-v")) {
+ showVersion = true;
+ } else {
+ QFileInfo fi(arg);
+ configFile = fi.absoluteFilePath();
+ basePath = fi.absolutePath();
+ }
+ }
+
+ if (showVersion) {
+ fputs(qPrintable(QCG::tr("Qt Collection Generator version 1.0 (Qt %1)\n")
+ .arg(QT_VERSION_STR)), stdout);
+ return 0;
+ }
+
+ if (configFile.isEmpty() && !showHelp)
+ error = QCG::tr("Missing collection config file.");
+
+ QString help = QCG::tr("\nUsage:\n\n"
+ "qcollectiongenerator <collection-config-file> [options]\n\n"
+ " -o <collection-file> Generates a collection file\n"
+ " called <collection-file>. If\n"
+ " this option is not specified\n"
+ " a default name will be used.\n"
+ " -v Displays the version of\n"
+ " qcollectiongenerator.\n\n");
+
+ if (showHelp) {
+ fputs(qPrintable(help), stdout);
+ return 0;
+ }else if (!error.isEmpty()) {
+ fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
+ return -1;
+ }
+
+ QFile file(configFile);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fputs(qPrintable(QCG::tr("Could not open %1.\n").arg(configFile)), stderr);
+ return -1;
+ }
+
+ if (collectionFile.isEmpty()) {
+ QFileInfo fi(configFile);
+ collectionFile = basePath + QDir::separator()
+ + fi.baseName() + QLatin1String(".qhc");
+ }
+
+ fputs(qPrintable(QCG::tr("Reading collection config file...\n")), stdout);
+ CollectionConfigReader config;
+ config.readData(file.readAll());
+ if (config.hasError()) {
+ fputs(qPrintable(QCG::tr("Collection config file error: %1\n")
+ .arg(config.errorString())), stderr);
+ return -1;
+ }
+
+ QMap<QString, QString>::const_iterator it = config.filesToGenerate().constBegin();
+ while (it != config.filesToGenerate().constEnd()) {
+ fputs(qPrintable(QCG::tr("Generating help for %1...\n").arg(it.key())), stdout);
+ QHelpProjectData helpData;
+ if (!helpData.readData(absoluteFileName(basePath, it.key()))) {
+ fprintf(stderr, "%s\n", qPrintable(helpData.errorMessage()));
+ return -1;
+ }
+
+ HelpGenerator helpGenerator;
+ if (!helpGenerator.generate(&helpData, absoluteFileName(basePath, it.value()))) {
+ fprintf(stderr, "%s\n", qPrintable(helpGenerator.error()));
+ return -1;
+ }
+ ++it;
+ }
+
+ fputs(qPrintable(QCG::tr("Creating collection file...\n")), stdout);
+
+ QFileInfo colFi(collectionFile);
+ if (colFi.exists()) {
+ if (!colFi.dir().remove(colFi.fileName())) {
+ fputs(qPrintable(QCG::tr("The file %1 cannot be overwritten.\n")
+ .arg(collectionFile)), stderr);
+ return -1;
+ }
+ }
+
+ QHelpEngineCore helpEngine(collectionFile);
+ if (!helpEngine.setupData()) {
+ fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
+ return -1;
+ }
+
+ foreach (const QString &file, config.filesToRegister()) {
+ if (!helpEngine.registerDocumentation(absoluteFileName(basePath, file))) {
+ fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
+ return -1;
+ }
+ }
+ if (!config.filesToRegister().isEmpty())
+ CollectionConfiguration::updateLastRegisterTime(helpEngine);
+
+ if (!config.title().isEmpty())
+ CollectionConfiguration::setWindowTitle(helpEngine, config.title());
+
+ if (!config.homePage().isEmpty()) {
+ CollectionConfiguration::setDefaultHomePage(helpEngine,
+ config.homePage());
+ }
+
+ if (!config.startPage().isEmpty()) {
+ CollectionConfiguration::setLastShownPages(helpEngine,
+ QStringList(config.startPage()));
+ }
+
+ if (!config.currentFilter().isEmpty()) {
+ helpEngine.setCurrentFilter(config.currentFilter());
+ }
+
+ if (!config.cacheDirectory().isEmpty()) {
+ CollectionConfiguration::setCacheDir(helpEngine, config.cacheDirectory(),
+ config.cacheDirRelativeToCollection());
+ }
+
+ CollectionConfiguration::setFilterFunctionalityEnabled(helpEngine,
+ config.enableFilterFunctionality());
+ CollectionConfiguration::setFilterToolbarVisible(helpEngine,
+ !config.hideFilterFunctionality());
+ CollectionConfiguration::setDocumentationManagerEnabled(helpEngine,
+ config.enableDocumentationManager());
+ CollectionConfiguration::setAddressBarEnabled(helpEngine,
+ config.enableAddressBar());
+ CollectionConfiguration::setAddressBarVisible(helpEngine,
+ !config.hideAddressBar());
+ CollectionConfiguration::setCreationTime(helpEngine,
+ QDateTime::currentDateTime().toTime_t());
+ CollectionConfiguration::setFullTextSearchFallbackEnabled(helpEngine,
+ config.fullTextSearchFallbackEnabled());
+
+ if (!config.applicationIcon().isEmpty()) {
+ QFile icon(absoluteFileName(basePath, config.applicationIcon()));
+ if (!icon.open(QIODevice::ReadOnly)) {
+ fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
+ return -1;
+ }
+ CollectionConfiguration::setApplicationIcon(helpEngine, icon.readAll());
+ }
+
+ if (config.aboutMenuTexts().count()) {
+ QByteArray ba;
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ QMap<QString, QString>::const_iterator it = config.aboutMenuTexts().constBegin();
+ while (it != config.aboutMenuTexts().constEnd()) {
+ s << it.key();
+ s << it.value();
+ ++it;
+ }
+ CollectionConfiguration::setAboutMenuTexts(helpEngine, ba);
+ }
+
+ if (!config.aboutIcon().isEmpty()) {
+ QFile icon(absoluteFileName(basePath, config.aboutIcon()));
+ if (!icon.open(QIODevice::ReadOnly)) {
+ fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
+ return -1;
+ }
+ CollectionConfiguration::setAboutIcon(helpEngine, icon.readAll());
+ }
+
+ if (config.aboutTextFiles().count()) {
+ QByteArray ba;
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ QMap<QString, QString>::const_iterator it = config.aboutTextFiles().constBegin();
+ QMap<QString, QByteArray> imgData;
+
+ QRegExp srcRegExp(QLatin1String("src=(\"(.+)\"|([^\"\\s]+)).*>"));
+ srcRegExp.setMinimal(true);
+ QRegExp imgRegExp(QLatin1String("(<img[^>]+>)"));
+ imgRegExp.setMinimal(true);
+
+ while (it != config.aboutTextFiles().constEnd()) {
+ s << it.key();
+ QFileInfo fi(absoluteFileName(basePath, it.value()));
+ QFile f(fi.absoluteFilePath());
+ if (!f.open(QIODevice::ReadOnly)) {
+ fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(f.fileName())), stderr);
+ return -1;
+ }
+ QByteArray data = f.readAll();
+ s << data;
+
+ QString contents = QString::fromUtf8(data);
+ int pos = 0;
+ while ((pos = imgRegExp.indexIn(contents, pos)) != -1) {
+ QString imgTag = imgRegExp.cap(1);
+ pos += imgRegExp.matchedLength();
+
+ if (srcRegExp.indexIn(imgTag, 0) != -1) {
+ QString src = srcRegExp.cap(2);
+ if (src.isEmpty())
+ src = srcRegExp.cap(3);
+
+ QFile img(fi.absolutePath() + QDir::separator() + src);
+ if (img.open(QIODevice::ReadOnly)) {
+ if (!imgData.contains(src))
+ imgData.insert(src, img.readAll());
+ } else {
+ fputs(qPrintable(QCG::tr("Cannot open referenced image file %1.\n")
+ .arg(img.fileName())), stderr);
+ }
+ }
+ }
+ ++it;
+ }
+ CollectionConfiguration::setAboutTexts(helpEngine, ba);
+ if (imgData.count()) {
+ QByteArray imageData;
+ QBuffer buffer(&imageData);
+ buffer.open(QIODevice::WriteOnly);
+ QDataStream out(&buffer);
+ out << imgData;
+ CollectionConfiguration::setAboutImages(helpEngine, imageData);
+ }
+ }
+
+ return 0;
+}
diff --git a/src/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro b/src/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro
new file mode 100644
index 000000000..98e6a3193
--- /dev/null
+++ b/src/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro
@@ -0,0 +1,17 @@
+QT += xml \
+ network
+TEMPLATE = app
+DESTDIR = ../../../../bin
+TARGET = qcollectiongenerator
+CONFIG += qt \
+ warn_on \
+ help \
+ console
+CONFIG -= app_bundle
+target.path = $$[QT_INSTALL_BINS]
+INSTALLS += target
+SOURCES += ../shared/helpgenerator.cpp \
+ main.cpp \
+ ../shared/collectionconfiguration.cpp
+HEADERS += ../shared/helpgenerator.h \
+ ../shared/collectionconfiguration.h
diff --git a/src/assistant/tools/qhelpconverter/adpreader.cpp b/src/assistant/tools/qhelpconverter/adpreader.cpp
new file mode 100644
index 000000000..a0983755e
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/adpreader.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QRegExp>
+
+#include "adpreader.h"
+
+static bool versionIsAtLeast320(const QString &version)
+{
+ return QRegExp("\\d.\\d\\.\\d").exactMatch(version)
+ && (version[0] > '3' || (version[0] == '3' && version[2] >= '2'));
+}
+
+QT_BEGIN_NAMESPACE
+
+void AdpReader::readData(const QByteArray &contents)
+{
+ clear();
+ m_contents.clear();
+ m_keywords.clear();
+ m_properties.clear();
+ m_files.clear();
+ addData(contents);
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name().toString().toLower() == QLatin1String("assistantconfig")
+ && versionIsAtLeast320(attributes().value(QLatin1String("version")).toString())) {
+ readProject();
+ } else if (name().toString().toLower() == QLatin1String("dcf")) {
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ addFile(ref);
+ m_contents.append(ContentItem(attributes().value(QLatin1String("title")).toString(),
+ ref, 0));
+ readDCF();
+ } else {
+ raiseError();
+ }
+ }
+ }
+}
+
+QList<ContentItem> AdpReader::contents() const
+{
+ return m_contents;
+}
+
+QList<KeywordItem> AdpReader::keywords() const
+{
+ return m_keywords;
+}
+
+QSet<QString> AdpReader::files() const
+{
+ return m_files;
+}
+
+QMap<QString, QString> AdpReader::properties() const
+{
+ return m_properties;
+}
+
+void AdpReader::readProject()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ QString s = name().toString().toLower();
+ if (s == QLatin1String("profile")) {
+ readProfile();
+ } else if (s == QLatin1String("dcf")) {
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ addFile(ref);
+ m_contents.append(ContentItem(attributes().value(QLatin1String("title")).toString(),
+ ref, 0));
+ readDCF();
+ } else {
+ raiseError();
+ }
+ }
+ }
+}
+
+void AdpReader::readProfile()
+{
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name().toString().toLower() == QLatin1String("property")) {
+ QString prop = attributes().value(QLatin1String("name")).toString().toLower();
+ m_properties[prop] = readElementText();
+ } else {
+ raiseError();
+ }
+ } else if (isEndElement()) {
+ break;
+ }
+ }
+}
+
+void AdpReader::readDCF()
+{
+ int depth = 0;
+ while (!atEnd()) {
+ readNext();
+ QString str = name().toString().toLower();
+ if (isStartElement()) {
+ if (str == QLatin1String("section")) {
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ addFile(ref);
+ m_contents.append(ContentItem(attributes().value(QLatin1String("title")).toString(),
+ ref, ++depth));
+ } else if (str == QLatin1String("keyword")) {
+ QString ref = attributes().value(QLatin1String("ref")).toString();
+ addFile(ref);
+ m_keywords.append(KeywordItem(readElementText(), ref));
+ } else {
+ raiseError();
+ }
+ } else if (isEndElement()) {
+ if (str == QLatin1String("section"))
+ --depth;
+ else if (str == QLatin1String("dcf"))
+ break;
+ }
+ }
+}
+
+void AdpReader::addFile(const QString &file)
+{
+ QString s = file;
+ if (s.startsWith(QLatin1String("./")))
+ s = s.mid(2);
+ int i = s.indexOf(QLatin1Char('#'));
+ if (i > -1)
+ s = s.left(i);
+ if (!m_files.contains(s))
+ m_files.insert(s);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/adpreader.h b/src/assistant/tools/qhelpconverter/adpreader.h
new file mode 100644
index 000000000..f0b6ae214
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/adpreader.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ADPREADER_H
+#define ADPREADER_H
+
+#include <QtCore/QMap>
+#include <QtCore/QSet>
+#include <QtXml/QXmlStreamReader>
+
+QT_BEGIN_NAMESPACE
+
+struct ContentItem {
+ ContentItem(const QString &t, const QString &r, int d)
+ : title(t), reference(r), depth(d) {}
+ QString title;
+ QString reference;
+ int depth;
+};
+
+struct KeywordItem {
+ KeywordItem(const QString &k, const QString &r)
+ : keyword(k), reference(r) {}
+ QString keyword;
+ QString reference;
+};
+
+class AdpReader : public QXmlStreamReader
+{
+public:
+ void readData(const QByteArray &contents);
+ QList<ContentItem> contents() const;
+ QList<KeywordItem> keywords() const;
+ QSet<QString> files() const;
+
+ QMap<QString, QString> properties() const;
+
+private:
+ void readProject();
+ void readProfile();
+ void readDCF();
+ void addFile(const QString &file);
+
+ QMap<QString, QString> m_properties;
+ QList<ContentItem> m_contents;
+ QList<KeywordItem> m_keywords;
+ QSet<QString> m_files;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/assistant-128.png b/src/assistant/tools/qhelpconverter/assistant-128.png
new file mode 100644
index 000000000..f05949f6d
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/assistant-128.png
Binary files differ
diff --git a/src/assistant/tools/qhelpconverter/assistant.png b/src/assistant/tools/qhelpconverter/assistant.png
new file mode 100644
index 000000000..ea4d1e70c
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/assistant.png
Binary files differ
diff --git a/src/assistant/tools/qhelpconverter/conversionwizard.cpp b/src/assistant/tools/qhelpconverter/conversionwizard.cpp
new file mode 100644
index 000000000..1df9facc5
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/conversionwizard.cpp
@@ -0,0 +1,265 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QVariant>
+#include <QtCore/QTimer>
+#include <QtGui/QApplication>
+#include <QtGui/QMouseEvent>
+
+#include "conversionwizard.h"
+#include "inputpage.h"
+#include "generalpage.h"
+#include "filterpage.h"
+#include "identifierpage.h"
+#include "pathpage.h"
+#include "filespage.h"
+#include "outputpage.h"
+#include "finishpage.h"
+#include "qhpwriter.h"
+#include "qhcpwriter.h"
+#include "helpwindow.h"
+
+QT_BEGIN_NAMESPACE
+
+ConversionWizard::ConversionWizard()
+{
+ setWindowIcon(QIcon(QLatin1String(":/trolltech/qhelpconverter/assistant.png")));
+ setWindowTitle(tr("Help Conversion Wizard"));
+ setPixmap(QWizard::WatermarkPixmap,
+ QPixmap(QLatin1String(":/trolltech/qhelpconverter/assistant-128.png"))) ;
+ setOptions(QWizard::IndependentPages|QWizard::NoBackButtonOnLastPage
+ |QWizard::HaveHelpButton);
+
+ m_inputPage = new InputPage(&m_adpReader);
+ setPage(Input_Page, m_inputPage);
+
+ m_generalPage = new GeneralPage();
+ setPage(General_Page, m_generalPage);
+
+ m_filterPage = new FilterPage();
+ setPage(Filter_Page, m_filterPage);
+ m_filterPage->setMaximumHeight(240);
+
+ m_identifierPage = new IdentifierPage();
+ setPage(Identifier_Page, m_identifierPage);
+
+ m_pathPage = new PathPage();
+ setPage(Path_Page, m_pathPage);
+ m_pathPage->setMaximumHeight(240);
+
+ m_filesPage = new FilesPage();
+ setPage(Files_Page, m_filesPage);
+ m_filesPage->setMaximumHeight(240);
+
+ m_outputPage = new OutputPage();
+ setPage(Output_Page, m_outputPage);
+ m_outputPage->setMaximumHeight(240);
+
+ m_finishPage = new FinishPage();
+ setPage(Finish_Page, m_finishPage);
+ m_finishPage->setMaximumHeight(240);
+
+ connect(this, SIGNAL(currentIdChanged(int)),
+ this, SLOT(pageChanged(int)));
+
+ m_helpWindow = 0;
+ qApp->installEventFilter(this);
+
+ QAbstractButton *btn = button(QWizard::HelpButton);
+ btn->setCheckable(true);
+ connect(btn, SIGNAL(toggled(bool)), this, SLOT(showHelp(bool)));
+}
+
+void ConversionWizard::setAdpFileName(const QString &fileName)
+{
+ setField(QLatin1String("adpFileName"), fileName);
+}
+
+void ConversionWizard::initializePage(int id)
+{
+ switch (id) {
+ case Path_Page: {
+ QFileInfo fi(field(QLatin1String("adpFileName")).toString());
+ m_pathPage->setPath(fi.absolutePath());
+ break;
+ }
+ case Output_Page: {
+ QFileInfo fi(field(QLatin1String("adpFileName")).toString());
+ m_outputPage->setPath(fi.absolutePath());
+ setField(QLatin1String("ProjectFileName"), fi.baseName()
+ + QLatin1String(".qhp"));
+ setField(QLatin1String("CollectionFileName"), fi.baseName()
+ + QLatin1String(".qhcp"));
+ break;
+ }
+ }
+}
+
+void ConversionWizard::pageChanged(int id)
+{
+ if (id == Files_Page) {
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ m_files.clear();
+ QFileInfo fi(field(QLatin1String("adpFileName")).toString());
+ QDir rootDir = fi.absolutePath();
+ foreach (const QString &p, m_pathPage->paths()) {
+ QDir dir(p);
+ QString rel = rootDir.relativeFilePath(dir.absolutePath());
+ if (!rel.isEmpty())
+ rel.append(QLatin1Char('/'));
+ foreach (const QString &f, dir.entryList(m_pathPage->filters()))
+ m_files.append(rel + f);
+ }
+ m_filesPage->setFilesToRemove(getUnreferencedFiles(m_files));
+ QApplication::restoreOverrideCursor();
+ } else if (id == Output_Page) {
+ m_outputPage->setCollectionComponentEnabled(
+ !m_adpReader.properties().isEmpty());
+ } else if (id == Finish_Page) {
+ QTimer::singleShot(300, this, SLOT(convert()));
+ }
+}
+
+void ConversionWizard::showHelp(bool toggle)
+{
+ int w = 180;
+ int h = 180;
+ if (!m_helpWindow) {
+ m_helpWindow = new HelpWindow(this);
+ m_helpWindow->setMaximumWidth(w);
+ m_helpWindow->setMaximumHeight(h);
+ m_helpWindow->setMinimumHeight(h);
+ }
+
+ if (toggle) {
+ m_helpWindow->setHelp(currentPage()->objectName());
+ QAbstractButton *btn = button(QWizard::HelpButton);
+ QPoint p = btn->pos();
+ int x = p.x();
+ if (btn->pos().x() > w)
+ x = p.x() + btn->width() - w;
+ m_helpWindow->move(x, p.y()-h);
+ m_helpWindow->show();
+ } else {
+ m_helpWindow->hide();
+ }
+}
+
+bool ConversionWizard::eventFilter(QObject *obj, QEvent *e)
+{
+ if (m_helpWindow && m_helpWindow->isVisible()) {
+ if (obj != button(QWizard::HelpButton)
+ && e->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ if (!m_helpWindow->geometry().contains(mapFromParent(me->globalPos()))) {
+ m_helpWindow->hide();
+ button(QWizard::HelpButton)->setChecked(false);
+ }
+ } else if (e->type() == QEvent::KeyPress) {
+ m_helpWindow->hide();
+ button(QWizard::HelpButton)->setChecked(false);
+ }
+ }
+ return QWizard::eventFilter(obj, e);
+}
+
+QStringList ConversionWizard::getUnreferencedFiles(const QStringList &files)
+{
+ QStringList lst;
+ QSet<QString> adpFiles = m_adpReader.files();
+ foreach (const QString &s, files) {
+ if (!adpFiles.contains(s))
+ lst.append(s);
+ }
+ return lst;
+}
+
+void ConversionWizard::convert()
+{
+ QFileInfo fi(field(QLatin1String("adpFileName")).toString());
+ m_finishPage->appendMessage(tr("Converting %1...")
+ .arg(fi.fileName()));
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ QString qhpFileName = field(QLatin1String("ProjectFileName")).toString();
+ QhpWriter qhpWriter(field(QLatin1String("namespaceName")).toString(),
+ field(QLatin1String("virtualFolder")).toString());
+ qhpWriter.setAdpReader(&m_adpReader);
+ qhpWriter.setFilterAttributes(m_filterPage->filterAttributes());
+ qhpWriter.setCustomFilters(m_filterPage->customFilters());
+
+ foreach (const QString &f, m_filesPage->filesToRemove())
+ m_files.removeAll(f);
+ qhpWriter.setFiles(m_files);
+
+ if (field(QLatin1String("createIdentifier")).toBool()) {
+ if (field(QLatin1String("fileNamePrefix")).toBool())
+ qhpWriter.generateIdentifiers(QhpWriter::FilePrefix);
+ else
+ qhpWriter.generateIdentifiers(QhpWriter::GlobalPrefix,
+ field(QLatin1String("globalPrefix")).toString());
+ } else {
+ qhpWriter.generateIdentifiers(QhpWriter::SkipAll);
+ }
+
+ qhpWriter.writeFile(fi.absolutePath() + QDir::separator()
+ + qhpFileName);
+
+ m_finishPage->appendMessage(tr("Writing help collection file..."));
+
+ if (!m_adpReader.properties().isEmpty()) {
+ QhcpWriter qhcpWriter;
+ qhcpWriter.setHelpProjectFile(qhpFileName);
+ qhcpWriter.setProperties(m_adpReader.properties());
+ qhcpWriter.setTitlePath(QLatin1String("qthelp://")
+ + field(QLatin1String("namespaceName")).toString()
+ + QLatin1String("/")
+ +field(QLatin1String("virtualFolder")).toString());
+ qhcpWriter.writeFile(fi.absolutePath() + QDir::separator()
+ + field(QLatin1String("CollectionFileName")).toString());
+ }
+
+ m_finishPage->appendMessage(tr("Done."));
+ QApplication::restoreOverrideCursor();
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/conversionwizard.h b/src/assistant/tools/qhelpconverter/conversionwizard.h
new file mode 100644
index 000000000..eb9b3f556
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/conversionwizard.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONVERSIONWIZARD_H
+#define CONVERSIONWIZARD_H
+
+#include <QtGui/QWizard>
+#include "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+class InputPage;
+class GeneralPage;
+class FilterPage;
+class IdentifierPage;
+class PathPage;
+class FilesPage;
+class OutputPage;
+class FinishPage;
+class HelpWindow;
+
+class ConversionWizard : public QWizard
+{
+ Q_OBJECT
+
+public:
+ ConversionWizard();
+ void setAdpFileName(const QString &fileName);
+
+private slots:
+ void pageChanged(int id);
+ void showHelp(bool toggle);
+ void convert();
+
+private:
+ enum Pages {Input_Page, General_Page, Filter_Page,
+ Identifier_Page, Path_Page, Files_Page, Output_Page,
+ Finish_Page};
+ void initializePage(int id);
+ QStringList getUnreferencedFiles(const QStringList &files);
+ bool eventFilter(QObject *obj, QEvent *e);
+
+ AdpReader m_adpReader;
+ InputPage *m_inputPage;
+ GeneralPage *m_generalPage;
+ FilterPage *m_filterPage;
+ IdentifierPage *m_identifierPage;
+ PathPage *m_pathPage;
+ FilesPage *m_filesPage;
+ OutputPage *m_outputPage;
+ FinishPage *m_finishPage;
+ QStringList m_files;
+ HelpWindow *m_helpWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/doc/filespage.html b/src/assistant/tools/qhelpconverter/doc/filespage.html
new file mode 100644
index 000000000..a7aac18da
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/doc/filespage.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<p>Sometimes it can happen that the previously specified paths contain
+more or other files than actually needed for the documentation.</p>
+<p>This page lists all files which are likely to be unused because they
+are neither referenced by any keyword nor be the TOC.</p>
+</body>
+</html>
diff --git a/src/assistant/tools/qhelpconverter/doc/filterpage.html b/src/assistant/tools/qhelpconverter/doc/filterpage.html
new file mode 100644
index 000000000..7b3781bd5
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/doc/filterpage.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+<p>The help system offers the possibility to filter all installed documentations
+for certain <b>attributes</b>. Commonly specified attributes are e.g. the company
+and product name as well as the product version.</p>
+<p>The help engine and Assistant use <b>custom filters</b> to do the actual
+documentation filtering. A custom filter is basically just a alias name for a
+list of filter attributes. So, if e.g. the custom filter "MyFilter" lists
+the attributes "mycompany, myproduct" then only the documentation with those
+attributes will be shown.</p>
+<p><b>Warning:</b> The filter attributes are case sensitive!</p>
+</body>
+</html>
diff --git a/src/assistant/tools/qhelpconverter/doc/generalpage.html b/src/assistant/tools/qhelpconverter/doc/generalpage.html
new file mode 100644
index 000000000..8d106bec1
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/doc/generalpage.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+<p>The <b>namespace</b> is needed to identify this documentation when having
+several documentation sets installed in a collection.</p>
+<p><b>Virtual</b> folders are used to enable file references between all
+documents. Thereby, the virtual folder acts as the root path of all
+documents, even if those are part of different documentation sets,
+meaning listed under different namespaces.</p>
+</body>
+</html>
diff --git a/src/assistant/tools/qhelpconverter/doc/identifierpage.html b/src/assistant/tools/qhelpconverter/doc/identifierpage.html
new file mode 100644
index 000000000..952b88de8
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/doc/identifierpage.html
@@ -0,0 +1,17 @@
+<html>
+<body>
+<p><b>Identifiers</b> are mostly used to make keywords unique, but they can also
+be used to specify keywords which should not be shown in the index. Identifiers
+are especially help full when using context sensitive help and one keyword has
+more links assigned to it.</p>
+<p>E.g. consider the keyword "replace" in Qt. It is
+included, among others, in QString and QList. To be able to retrieve the proper
+documentation, there is an identifier "QString::replace" and one
+"QList::replace".</p>
+<p>A <b>global prefix</b>, e.g. "MyApp::" is set for all keywords independent
+where they are located. When <b>inheriting</b> the prefix from the file name,
+the keywords get the prefix "[filename]::" where the file name is taken from the
+reference of the keyword. The file name is just the base name, i.e. without any
+directory or extension.</p>
+</body>
+</html>
diff --git a/src/assistant/tools/qhelpconverter/doc/inputpage.html b/src/assistant/tools/qhelpconverter/doc/inputpage.html
new file mode 100644
index 000000000..4054c5472
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/doc/inputpage.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+<p>Both, a .adp or .dcf file can be specified. If an .adp file is detected,
+the wizard generates a Qt help collection file in addition to the help
+project file.</p>
+</body>
+</html>
diff --git a/src/assistant/tools/qhelpconverter/doc/outputpage.html b/src/assistant/tools/qhelpconverter/doc/outputpage.html
new file mode 100644
index 000000000..332ef69fc
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/doc/outputpage.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+<p>The specified output files will be located in the same directory as the
+.adp or .dcf file. The collection file will only be generated if the input
+file was an .adp file.</p>
+</body>
+</html>
diff --git a/src/assistant/tools/qhelpconverter/doc/pathpage.html b/src/assistant/tools/qhelpconverter/doc/pathpage.html
new file mode 100644
index 000000000..95449b3c3
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/doc/pathpage.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<p>The new help system uses, in contrast to the old Qt Assistant, compressed
+help files containing all files (html files, images, stylesheets, ...)
+necessary to display the documentation correctly.</p>
+<p>To be able to find all those files, the source paths have to be given.</p>
+</body>
+</html>
diff --git a/src/assistant/tools/qhelpconverter/filespage.cpp b/src/assistant/tools/qhelpconverter/filespage.cpp
new file mode 100644
index 000000000..e30ec42ef
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/filespage.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QKeyEvent>
+#include "filespage.h"
+
+QT_BEGIN_NAMESPACE
+
+FilesPage::FilesPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Unreferenced Files"));
+ setSubTitle(tr("Remove files which are neither referenced "
+ "by a keyword nor by the TOC."));
+
+ m_ui.setupUi(this);
+ m_ui.fileListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ m_ui.fileListWidget->installEventFilter(this);
+ connect(m_ui.removeButton, SIGNAL(clicked()),
+ this, SLOT(removeFile()));
+ connect(m_ui.removeAllButton, SIGNAL(clicked()),
+ this, SLOT(removeAllFiles()));
+
+ m_ui.fileLabel->setText(tr("<p><b>Warning:</b> "
+ "When removing images or stylesheets, be aware that those files "
+ "are not directly referenced by the .adp or .dcf "
+ "file.</p>"));
+}
+
+void FilesPage::setFilesToRemove(const QStringList &files)
+{
+ m_files = files;
+ m_ui.fileListWidget->clear();
+ m_ui.fileListWidget->addItems(files);
+}
+
+QStringList FilesPage::filesToRemove() const
+{
+ return m_filesToRemove;
+}
+
+void FilesPage::removeFile()
+{
+ int row = m_ui.fileListWidget->currentRow()
+ - m_ui.fileListWidget->selectedItems().count() + 1;
+ foreach (const QListWidgetItem *item, m_ui.fileListWidget->selectedItems()) {
+ m_filesToRemove.append(item->text());
+ delete item;
+ }
+ if (m_ui.fileListWidget->count() > row && row >= 0)
+ m_ui.fileListWidget->setCurrentRow(row);
+ else
+ m_ui.fileListWidget->setCurrentRow(m_ui.fileListWidget->count());
+}
+
+void FilesPage::removeAllFiles()
+{
+ m_ui.fileListWidget->clear();
+ m_filesToRemove = m_files;
+}
+
+bool FilesPage::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj == m_ui.fileListWidget && event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ if (ke->key() == Qt::Key_Delete) {
+ removeFile();
+ return true;
+ }
+ }
+ return QWizardPage::eventFilter(obj, event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/filespage.h b/src/assistant/tools/qhelpconverter/filespage.h
new file mode 100644
index 000000000..393c3d5e1
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/filespage.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FILESPAGE_H
+#define FILESPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_filespage.h"
+
+QT_BEGIN_NAMESPACE
+
+class FilesPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ FilesPage(QWidget *parent = 0);
+ void setFilesToRemove(const QStringList &files);
+ QStringList filesToRemove() const;
+
+private slots:
+ void removeFile();
+ void removeAllFiles();
+
+private:
+ bool eventFilter(QObject *obj, QEvent *event);
+
+ Ui::FilesPage m_ui;
+ QStringList m_files;
+ QStringList m_filesToRemove;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/filespage.ui b/src/assistant/tools/qhelpconverter/filespage.ui
new file mode 100644
index 000000000..d308b9664
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/filespage.ui
@@ -0,0 +1,79 @@
+<ui version="4.0" >
+ <class>FilesPage</class>
+ <widget class="QWidget" name="FilesPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>242</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="2" >
+ <widget class="QLabel" name="fileLabel" >
+ <property name="text" >
+ <string>Files:</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="3" row="1" column="0" >
+ <widget class="QListWidget" name="fileListWidget" />
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="removeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QPushButton" name="removeAllButton" >
+ <property name="text" >
+ <string>Remove All</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>75</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/tools/qhelpconverter/filterpage.cpp b/src/assistant/tools/qhelpconverter/filterpage.cpp
new file mode 100644
index 000000000..3b22ca0d1
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/filterpage.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QMessageBox>
+#include "filterpage.h"
+
+QT_BEGIN_NAMESPACE
+
+FilterPage::FilterPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Filter Settings"));
+ setSubTitle(tr("Specify the filter attributes for the "
+ "documentation. If filter attributes are used, "
+ "also define a custom filter for it. Both the "
+ "filter attributes and the custom filters are "
+ "optional."));
+
+ m_ui.setupUi(this);
+ m_ui.customFilterWidget->headerItem()->setText(0, tr("Filter Name"));
+ m_ui.customFilterWidget->headerItem()->setText(1, tr("Filter Attributes"));
+ m_ui.customFilterWidget->setRootIsDecorated(false);
+ m_ui.removeButton->setDisabled(true);
+ connect(m_ui.addButton, SIGNAL(clicked()),
+ this, SLOT(addFilter()));
+ connect(m_ui.removeButton, SIGNAL(clicked()),
+ this, SLOT(removeFilter()));
+}
+
+bool FilterPage::validatePage()
+{
+ m_filterAttributes.clear();
+ foreach (const QString &f, m_ui.filterLineEdit->text().split(QLatin1Char(','))) {
+ if (!f.trimmed().isEmpty())
+ m_filterAttributes.append(f.trimmed());
+ }
+
+ m_customFilters.clear();
+ QSet<QString> names;
+ QSet<QString> atts;
+ QString str;
+ CustomFilter customFilter;
+ QTreeWidgetItem *item = 0;
+ for (int i=0; i<m_ui.customFilterWidget->topLevelItemCount(); ++i) {
+ item = m_ui.customFilterWidget->topLevelItem(i);
+ str = item->text(0);
+ if (str.isEmpty() || names.contains(str)) {
+ QMessageBox::critical(this, tr("Custom Filters"),
+ tr("The custom filter \'%1\' is defined multiple times.")
+ .arg(str));
+ return false;
+ }
+ names.insert(str);
+ customFilter.name = str;
+
+ str.clear();
+ QStringList lst;
+ foreach (const QString &s, item->text(1).split(QLatin1Char(','))) {
+ const QString st = s.trimmed();
+ if (!st.isEmpty()) {
+ str += QLatin1Char(',') + st;
+ lst.append(st);
+ }
+ }
+ if (atts.contains(str)) {
+ QMessageBox::critical(this, tr("Custom Filters"),
+ tr("The attributes for custom filter \'%1\' are defined multiple times.")
+ .arg(customFilter.name));
+ return false;
+ }
+ atts.insert(str);
+ customFilter.filterAttributes = lst;
+ m_customFilters.append(customFilter);
+ }
+ return true;
+}
+
+QStringList FilterPage::filterAttributes() const
+{
+ return m_filterAttributes;
+}
+
+QList<CustomFilter> FilterPage::customFilters() const
+{
+ return m_customFilters;
+}
+
+void FilterPage::addFilter()
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.customFilterWidget);
+ item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable);
+ item->setText(0, tr("unfiltered", "list of available documentation"));
+ item->setText(1, QLatin1String(""));
+ m_ui.customFilterWidget->editItem(item, 0);
+ m_ui.removeButton->setDisabled(false);
+}
+
+void FilterPage::removeFilter()
+{
+ QModelIndex idx = m_ui.customFilterWidget->currentIndex();
+ if (!idx.isValid())
+ return;
+ QTreeWidgetItem *item = m_ui.customFilterWidget->takeTopLevelItem(idx.row());
+ delete item;
+ if (!m_ui.customFilterWidget->topLevelItemCount())
+ m_ui.removeButton->setDisabled(true);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/filterpage.h b/src/assistant/tools/qhelpconverter/filterpage.h
new file mode 100644
index 000000000..0281a1ed3
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/filterpage.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FILTERPAGE_H
+#define FILTERPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_filterpage.h"
+
+QT_BEGIN_NAMESPACE
+
+struct CustomFilter
+{
+ QString name;
+ QStringList filterAttributes;
+};
+
+class FilterPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ FilterPage(QWidget *parent = 0);
+ QStringList filterAttributes() const;
+ QList<CustomFilter> customFilters() const;
+
+private slots:
+ void addFilter();
+ void removeFilter();
+
+private:
+ bool validatePage();
+
+ Ui::FilterPage m_ui;
+ QStringList m_filterAttributes;
+ QList<CustomFilter> m_customFilters;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/filterpage.ui b/src/assistant/tools/qhelpconverter/filterpage.ui
new file mode 100644
index 000000000..7cda3d9be
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/filterpage.ui
@@ -0,0 +1,125 @@
+<ui version="4.0" >
+ <class>FilterPage</class>
+ <widget class="QWidget" name="FilterPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>419</width>
+ <height>243</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Filter attributes for current documentation (comma separated list):</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLineEdit" name="filterLineEdit" />
+ </item>
+ <item row="4" column="0" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Custom Filters</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item rowspan="3" row="0" column="0" >
+ <widget class="QTreeWidget" name="customFilterWidget" >
+ <property name="columnCount" >
+ <number>2</number>
+ </property>
+ <column>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>2</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QPushButton" name="addButton" >
+ <property name="text" >
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="removeButton" >
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/tools/qhelpconverter/finishpage.cpp b/src/assistant/tools/qhelpconverter/finishpage.cpp
new file mode 100644
index 000000000..a7fa89e2e
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/finishpage.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QTextEdit>
+#include <QtGui/QLayout>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QApplication>
+
+#include "finishpage.h"
+
+QT_BEGIN_NAMESPACE
+
+FinishPage::FinishPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Converting File"));
+ setSubTitle(tr("Creating the new Qt help files from the old ADP file."));
+ setFinalPage(true);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum,
+ QSizePolicy::Fixed));
+
+ m_textEdit = new QTextEdit();
+ layout->addWidget(m_textEdit);
+
+ layout->addItem(new QSpacerItem(20, 40, QSizePolicy::Minimum,
+ QSizePolicy::Expanding));
+}
+
+void FinishPage::appendMessage(const QString &msg)
+{
+ m_textEdit->append(msg);
+ qApp->processEvents();
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/finishpage.h b/src/assistant/tools/qhelpconverter/finishpage.h
new file mode 100644
index 000000000..15b0c4a55
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/finishpage.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FINISHPAGE_H
+#define FINISHPAGE_H
+
+#include <QtGui/QWizardPage>
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+
+class FinishPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ FinishPage(QWidget *parent = 0);
+ void appendMessage(const QString &msg);
+
+private:
+ QTextEdit *m_textEdit;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/generalpage.cpp b/src/assistant/tools/qhelpconverter/generalpage.cpp
new file mode 100644
index 000000000..4b32cbbf9
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/generalpage.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QMessageBox>
+#include "generalpage.h"
+
+QT_BEGIN_NAMESPACE
+
+GeneralPage::GeneralPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("General Settings"));
+ setSubTitle(tr("Specify the namespace and the virtual "
+ "folder for the documentation."));
+
+ m_ui.setupUi(this);
+ connect(m_ui.namespaceLineEdit, SIGNAL(textChanged(QString)),
+ this, SIGNAL(completeChanged()));
+ connect(m_ui.folderLineEdit, SIGNAL(textChanged(QString)),
+ this, SIGNAL(completeChanged()));
+
+ m_ui.namespaceLineEdit->setText(QLatin1String("mycompany.com"));
+ m_ui.folderLineEdit->setText(QLatin1String("product_1.0"));
+
+ registerField(QLatin1String("namespaceName"), m_ui.namespaceLineEdit);
+ registerField(QLatin1String("virtualFolder"), m_ui.folderLineEdit);
+}
+
+bool GeneralPage::isComplete() const
+{
+ if (m_ui.namespaceLineEdit->text().isEmpty()
+ || m_ui.folderLineEdit->text().isEmpty())
+ return false;
+ return true;
+}
+
+bool GeneralPage::validatePage()
+{
+ QString s = m_ui.namespaceLineEdit->text();
+ if (s.contains(QLatin1Char('/')) || s.contains(QLatin1Char('\\'))) {
+ QMessageBox::critical(this, tr("Namespace Error"),
+ tr("The namespace contains some invalid characters."));
+ return false;
+ }
+ s = m_ui.folderLineEdit->text();
+ if (s.contains(QLatin1Char('/')) || s.contains(QLatin1Char('\\'))) {
+ QMessageBox::critical(this, tr("Virtual Folder Error"),
+ tr("The virtual folder contains some invalid characters."));
+ return false;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/generalpage.h b/src/assistant/tools/qhelpconverter/generalpage.h
new file mode 100644
index 000000000..413a798df
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/generalpage.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GENERALPAGE_H
+#define GENERALPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_generalpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class GeneralPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ GeneralPage(QWidget *parent = 0);
+
+private:
+ bool validatePage();
+ bool isComplete() const;
+
+ Ui::GeneralPage m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/generalpage.ui b/src/assistant/tools/qhelpconverter/generalpage.ui
new file mode 100644
index 000000000..9c2babb0a
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/generalpage.ui
@@ -0,0 +1,69 @@
+<ui version="4.0" >
+ <class>GeneralPage</class>
+ <widget class="QWidget" name="GeneralPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>243</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Namespace:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="namespaceLineEdit" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Virtual Folder:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="folderLineEdit" />
+ </item>
+ <item row="0" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/tools/qhelpconverter/helpwindow.cpp b/src/assistant/tools/qhelpconverter/helpwindow.cpp
new file mode 100644
index 000000000..9fa33585e
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/helpwindow.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QTextEdit>
+
+#include "helpwindow.h"
+
+QT_BEGIN_NAMESPACE
+
+HelpWindow::HelpWindow(QWidget *parent)
+ : QWidget(parent, 0)
+{
+ setAutoFillBackground(true);
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(0);
+ QFrame *frame = new QFrame(this);
+ QPalette p = palette();
+ p.setColor(QPalette::Background, Qt::white);
+ setPalette(p);
+ frame->setFrameStyle(QFrame::Box | QFrame::Plain);
+ layout->addWidget(frame);
+
+ layout = new QVBoxLayout(frame);
+ layout->setMargin(2);
+ QLabel *l = new QLabel(tr("<center><b>Wizard Assistant</b></center>"));
+ layout->addWidget(l);
+ m_textEdit = new QTextEdit();
+ m_textEdit->setFrameStyle(QFrame::NoFrame);
+ m_textEdit->setReadOnly(true);
+ layout->addWidget(m_textEdit);
+}
+
+void HelpWindow::setHelp(const QString &topic)
+{
+ QLatin1String fileStr(":/trolltech/qhelpconverter/doc/%1.html");
+ QFile f(QString(fileStr).arg(topic.toLower()));
+ f.open(QIODevice::ReadOnly);
+ QTextStream s(&f);
+ m_textEdit->setText(s.readAll());
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/helpwindow.h b/src/assistant/tools/qhelpconverter/helpwindow.h
new file mode 100644
index 000000000..ba176ed72
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/helpwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPWINDOW_H
+#define HELPWINDOW_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+
+class HelpWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ HelpWindow(QWidget *parent = 0);
+ void setHelp(const QString &topic);
+
+private:
+ QTextEdit *m_textEdit;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/identifierpage.cpp b/src/assistant/tools/qhelpconverter/identifierpage.cpp
new file mode 100644
index 000000000..fb8310a61
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/identifierpage.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "identifierpage.h"
+
+QT_BEGIN_NAMESPACE
+
+IdentifierPage::IdentifierPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Identifiers"));
+ setSubTitle(tr("This page allows you to create identifiers from "
+ "the keywords found in the .adp or .dcf file."));
+
+ m_ui.setupUi(this);
+
+ connect(m_ui.identifierCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(setupButtons(bool)));
+
+ registerField(QLatin1String("createIdentifier"), m_ui.identifierCheckBox);
+ registerField(QLatin1String("globalPrefix"), m_ui.prefixLineEdit);
+ registerField(QLatin1String("fileNamePrefix"), m_ui.fileNameButton);
+}
+
+void IdentifierPage::setupButtons(bool checked)
+{
+ m_ui.globalButton->setEnabled(checked);
+ m_ui.fileNameButton->setEnabled(checked);
+ m_ui.prefixLineEdit->setEnabled(checked
+ && m_ui.globalButton->isChecked());
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/identifierpage.h b/src/assistant/tools/qhelpconverter/identifierpage.h
new file mode 100644
index 000000000..c05eb8f72
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/identifierpage.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IDENTIFIERPAGE_H
+#define IDENTIFIERPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_identifierpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class IdentifierPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ IdentifierPage(QWidget *parent = 0);
+
+private slots:
+ void setupButtons(bool checked);
+
+private:
+ Ui::IdentifierPage m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/identifierpage.ui b/src/assistant/tools/qhelpconverter/identifierpage.ui
new file mode 100644
index 000000000..cd0df7563
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/identifierpage.ui
@@ -0,0 +1,132 @@
+<ui version="4.0" >
+ <class>IdentifierPage</class>
+ <widget class="QWidget" name="IdentifierPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>242</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QCheckBox" name="identifierCheckBox" >
+ <property name="text" >
+ <string>Create identifiers</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>161</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>30</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QRadioButton" name="globalButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Global prefix:</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QLineEdit" name="prefixLineEdit" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="2" >
+ <widget class="QRadioButton" name="fileNameButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Inherit prefix from file names</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>globalButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>prefixLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>122</x>
+ <y>72</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>161</x>
+ <y>71</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/assistant/tools/qhelpconverter/inputpage.cpp b/src/assistant/tools/qhelpconverter/inputpage.cpp
new file mode 100644
index 000000000..aa180b90e
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/inputpage.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFile>
+#include <QtCore/QVariant>
+
+#include <QtGui/QLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QToolButton>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QApplication>
+
+#include "inputpage.h"
+#include "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+InputPage::InputPage(AdpReader *reader, QWidget *parent)
+ : QWizardPage(parent)
+{
+ m_adpReader = reader;
+ setTitle(tr("Input File"));
+ setSubTitle(tr("Specify the .adp or .dcf file you want "
+ "to convert to the new Qt help project format and/or "
+ "collection format."));
+
+ m_ui.setupUi(this);
+ connect(m_ui.browseButton, SIGNAL(clicked()),
+ this, SLOT(getFileName()));
+
+ registerField(QLatin1String("adpFileName"), m_ui.fileLineEdit);
+}
+
+void InputPage::getFileName()
+{
+ QString f = QFileDialog::getOpenFileName(this, tr("Open file"), QString(),
+ tr("Qt Help Files (*.adp *.dcf)"));
+ if (!f.isEmpty())
+ m_ui.fileLineEdit->setText(f);
+}
+
+bool InputPage::validatePage()
+{
+ QFile f(m_ui.fileLineEdit->text().trimmed());
+ if (!f.exists() || !f.open(QIODevice::ReadOnly)) {
+ QMessageBox::critical(this, tr("File Open Error"),
+ tr("The specified file could not be opened!"));
+ return false;
+ }
+
+ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+ m_adpReader->readData(f.readAll());
+ QApplication::restoreOverrideCursor();
+ if (m_adpReader->hasError()) {
+ QMessageBox::critical(this, tr("File Parsing Error"),
+ tr("Parsing error in line %1!").arg(m_adpReader->lineNumber()));
+ return false;
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/inputpage.h b/src/assistant/tools/qhelpconverter/inputpage.h
new file mode 100644
index 000000000..4489dc781
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/inputpage.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INPUTPAGE_H
+#define INPUTPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_inputpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class AdpReader;
+
+class InputPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ explicit InputPage(AdpReader *reader, QWidget *parent = 0);
+
+private slots:
+ void getFileName();
+
+private:
+ bool validatePage();
+
+ Ui::InputPage m_ui;
+ AdpReader *m_adpReader;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/inputpage.ui b/src/assistant/tools/qhelpconverter/inputpage.ui
new file mode 100644
index 000000000..e7cd3a0fa
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/inputpage.ui
@@ -0,0 +1,79 @@
+<ui version="4.0" >
+ <class>InputPage</class>
+ <widget class="QWidget" name="InputPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>242</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>File name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="fileLineEdit" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="browseButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/tools/qhelpconverter/main.cpp b/src/assistant/tools/qhelpconverter/main.cpp
new file mode 100644
index 000000000..38f6ffc4e
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/main.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QTranslator>
+#include <QtCore/QLocale>
+#include <QtCore/QLibraryInfo>
+#include <QtGui/QApplication>
+
+#include "conversionwizard.h"
+
+QT_USE_NAMESPACE
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QTranslator qt_helpTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("assistant_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)
+ && qt_helpTranslator.load(QLatin1String("qt_help_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ app.installTranslator(&qt_helpTranslator);
+ }
+
+ ConversionWizard w;
+ if (argc == 2) {
+ QFileInfo fi(QString::fromLocal8Bit(argv[1]));
+ if (fi.exists())
+ w.setAdpFileName(fi.absoluteFilePath());
+ }
+ w.show();
+ return app.exec();
+}
+
diff --git a/src/assistant/tools/qhelpconverter/outputpage.cpp b/src/assistant/tools/qhelpconverter/outputpage.cpp
new file mode 100644
index 000000000..d8a6bd13f
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/outputpage.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtGui/QMessageBox>
+
+#include "outputpage.h"
+
+QT_BEGIN_NAMESPACE
+
+OutputPage::OutputPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Output File Names"));
+ setSubTitle(tr("Specify the file names for the output files."));
+ setButtonText(QWizard::NextButton, tr("Convert..."));
+
+ m_ui.setupUi(this);
+ connect(m_ui.projectLineEdit, SIGNAL(textChanged(QString)),
+ this, SIGNAL(completeChanged()));
+ connect(m_ui.collectionLineEdit, SIGNAL(textChanged(QString)),
+ this, SIGNAL(completeChanged()));
+
+ registerField(QLatin1String("ProjectFileName"),
+ m_ui.projectLineEdit);
+ registerField(QLatin1String("CollectionFileName"),
+ m_ui.collectionLineEdit);
+}
+
+void OutputPage::setPath(const QString &path)
+{
+ m_path = path;
+}
+
+void OutputPage::setCollectionComponentEnabled(bool enabled)
+{
+ m_ui.collectionLineEdit->setEnabled(enabled);
+ m_ui.label_2->setEnabled(enabled);
+}
+
+bool OutputPage::isComplete() const
+{
+ if (m_ui.projectLineEdit->text().isEmpty()
+ || m_ui.collectionLineEdit->text().isEmpty())
+ return false;
+ return true;
+}
+
+bool OutputPage::validatePage()
+{
+ return checkFile(m_ui.projectLineEdit->text(),
+ tr("Qt Help Project File"))
+ && checkFile(m_ui.collectionLineEdit->text(),
+ tr("Qt Help Collection Project File"));
+}
+
+bool OutputPage::checkFile(const QString &fileName, const QString &title)
+{
+ QFile fi(m_path + QDir::separator() + fileName);
+ if (!fi.exists())
+ return true;
+
+ if (QMessageBox::warning(this, title,
+ tr("The specified file %1 already exist.\n\nDo you want to remove it?")
+ .arg(fileName), tr("Remove"), tr("Cancel")) == 0) {
+ return fi.remove();
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/outputpage.h b/src/assistant/tools/qhelpconverter/outputpage.h
new file mode 100644
index 000000000..535729bf8
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/outputpage.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OUTPUTPAGE_H
+#define OUTPUTPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_outputpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class OutputPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ OutputPage(QWidget *parent = 0);
+ void setPath(const QString &path);
+ void setCollectionComponentEnabled(bool enabled);
+
+private:
+ bool isComplete() const;
+ bool validatePage();
+ bool checkFile(const QString &fileName,
+ const QString &title);
+
+ Ui::OutputPage m_ui;
+ QString m_path;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/outputpage.ui b/src/assistant/tools/qhelpconverter/outputpage.ui
new file mode 100644
index 000000000..755f81808
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/outputpage.ui
@@ -0,0 +1,95 @@
+<ui version="4.0" >
+ <class>OutputPage</class>
+ <widget class="QWidget" name="OutputPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>242</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Project file name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="projectLineEdit" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Collection file name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="collectionLineEdit" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/tools/qhelpconverter/pathpage.cpp b/src/assistant/tools/qhelpconverter/pathpage.cpp
new file mode 100644
index 000000000..e5391eb80
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/pathpage.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QFileDialog>
+
+#include "pathpage.h"
+
+QT_BEGIN_NAMESPACE
+
+PathPage::PathPage(QWidget *parent)
+ : QWizardPage(parent)
+{
+ setTitle(tr("Source File Paths"));
+ setSubTitle(tr("Specify the paths where the sources files "
+ "are located. By default, all files in those directories "
+ "matched by the file filter will be included."));
+
+ m_ui.setupUi(this);
+ connect(m_ui.addButton, SIGNAL(clicked()),
+ this, SLOT(addPath()));
+ connect(m_ui.removeButton, SIGNAL(clicked()),
+ this, SLOT(removePath()));
+
+ m_ui.filterLineEdit->setText(QLatin1String("*.html, *.htm, *.png, *.jpg, *.css"));
+
+ registerField(QLatin1String("sourcePathList"), m_ui.pathListWidget);
+ m_firstTime = true;
+}
+
+void PathPage::setPath(const QString &path)
+{
+ if (!m_firstTime)
+ return;
+
+ m_ui.pathListWidget->addItem(path);
+ m_firstTime = false;
+ m_ui.pathListWidget->setCurrentRow(0);
+}
+
+QStringList PathPage::paths() const
+{
+ QStringList lst;
+ for (int i = 0; i<m_ui.pathListWidget->count(); ++i)
+ lst.append(m_ui.pathListWidget->item(i)->text());
+ return lst;
+}
+
+QStringList PathPage::filters() const
+{
+ QStringList lst;
+ foreach (const QString &s, m_ui.filterLineEdit->text().split(QLatin1Char(','))) {
+ lst.append(s.trimmed());
+ }
+ return lst;
+}
+
+void PathPage::addPath()
+{
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Source File Path"));
+ if (!dir.isEmpty())
+ m_ui.pathListWidget->addItem(dir);
+}
+
+void PathPage::removePath()
+{
+ QListWidgetItem *i = m_ui.pathListWidget
+ ->takeItem(m_ui.pathListWidget->currentRow());
+ delete i;
+ if (!m_ui.pathListWidget->count())
+ m_ui.removeButton->setEnabled(false);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/pathpage.h b/src/assistant/tools/qhelpconverter/pathpage.h
new file mode 100644
index 000000000..aad387976
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/pathpage.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PATHPAGE_H
+#define PATHPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "ui_pathpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class PathPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ PathPage(QWidget *parent = 0);
+ void setPath(const QString &path);
+ QStringList paths() const;
+ QStringList filters() const;
+
+private slots:
+ void addPath();
+ void removePath();
+
+private:
+ Ui::PathPage m_ui;
+ bool m_firstTime;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/pathpage.ui b/src/assistant/tools/qhelpconverter/pathpage.ui
new file mode 100644
index 000000000..89083915d
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/pathpage.ui
@@ -0,0 +1,114 @@
+<ui version="4.0" >
+ <class>PathPage</class>
+ <widget class="QWidget" name="PathPage" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>417</width>
+ <height>243</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>File filters:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <widget class="QLineEdit" name="filterLineEdit" />
+ </item>
+ <item row="1" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" colspan="3" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Documentation source file paths:</string>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="3" row="3" column="0" colspan="3" >
+ <widget class="QListWidget" name="pathListWidget" />
+ </item>
+ <item row="3" column="3" >
+ <widget class="QPushButton" name="addButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3" >
+ <widget class="QPushButton" name="removeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>51</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/assistant/tools/qhelpconverter/qhcpwriter.cpp b/src/assistant/tools/qhelpconverter/qhcpwriter.cpp
new file mode 100644
index 000000000..cdf9f0b3c
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/qhcpwriter.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFile>
+
+#include "qhcpwriter.h"
+
+QT_BEGIN_NAMESPACE
+
+QhcpWriter::QhcpWriter()
+{
+ setAutoFormatting(true);
+}
+
+void QhcpWriter::setHelpProjectFile(const QString &qhpFile)
+{
+ m_qhpFile = qhpFile;
+}
+
+void QhcpWriter::setProperties(const QMap<QString, QString> props)
+{
+ m_properties = props;
+}
+
+void QhcpWriter::setTitlePath(const QString &path)
+{
+ m_titlePath = path;
+}
+
+bool QhcpWriter::writeFile(const QString &fileName)
+{
+ QFile out(fileName);
+ if (!out.open(QIODevice::WriteOnly))
+ return false;
+
+ setDevice(&out);
+ writeStartDocument();
+ writeStartElement(QLatin1String("QHelpCollectionProject"));
+ writeAttribute(QLatin1String("version"), QLatin1String("1.0"));
+ writeAssistantSettings();
+ writeDocuments();
+ writeEndDocument();
+ return true;
+}
+
+void QhcpWriter::writeAssistantSettings()
+{
+ if (m_properties.isEmpty())
+ return;
+
+ writeStartElement(QLatin1String("assistant"));
+
+ if (m_properties.contains(QLatin1String("title")))
+ writeTextElement(QLatin1String("title"), m_properties.value(QLatin1String("title")));
+ if (m_properties.contains(QLatin1String("applicationicon")))
+ writeTextElement(QLatin1String("applicationIcon"),
+ m_properties.value(QLatin1String("applicationicon")));
+ if (m_properties.contains(QLatin1String("startpage")))
+ writeTextElement(QLatin1String("startPage"), m_titlePath + QLatin1String("/")
+ + m_properties.value(QLatin1String("startpage")));
+ if (m_properties.contains(QLatin1String("aboutmenutext"))) {
+ writeStartElement(QLatin1String("aboutMenuText"));
+ writeTextElement(QLatin1String("text"),
+ m_properties.value(QLatin1String("aboutmenutext")));
+ writeEndElement();
+ }
+ if (m_properties.contains(QLatin1String("abouturl"))) {
+ writeStartElement(QLatin1String("aboutDialog"));
+ writeTextElement(QLatin1String("file"), m_properties.value(QLatin1String("abouturl")));
+ writeEndElement();
+ }
+ if (m_properties.contains(QLatin1String("name"))) {
+ writeTextElement(QLatin1String("cacheDirectory"),
+ QLatin1String(".") + m_properties.value(QLatin1String("name")));
+ }
+
+ writeEndElement();
+}
+
+void QhcpWriter::writeDocuments()
+{
+ if (m_qhpFile.isEmpty())
+ return;
+
+ QString out = m_qhpFile;
+ int i = out.indexOf(QLatin1Char('.'));
+ if (i > -1)
+ out = out.left(i);
+ out.append(QLatin1String(".qch"));
+
+ writeStartElement(QLatin1String("docFiles"));
+
+ writeStartElement(QLatin1String("generate"));
+ writeStartElement(QLatin1String("file"));
+ writeTextElement(QLatin1String("input"), m_qhpFile);
+ writeTextElement(QLatin1String("output"), out);
+ writeEndElement();
+ writeEndElement();
+
+ writeStartElement(QLatin1String("register"));
+ writeTextElement(QLatin1String("file"), out);
+ writeEndElement();
+
+ writeEndElement();
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/qhcpwriter.h b/src/assistant/tools/qhelpconverter/qhcpwriter.h
new file mode 100644
index 000000000..de0c6f8e1
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/qhcpwriter.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHCPWRITER_H
+#define QHCPWRITER_H
+
+#include <QtXml/QXmlStreamWriter>
+#include "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+class QhcpWriter : public QXmlStreamWriter
+{
+public:
+ QhcpWriter();
+ bool writeFile(const QString &fileName);
+ void setHelpProjectFile(const QString &qhpFile);
+ void setProperties(const QMap<QString, QString> props);
+ void setTitlePath(const QString &path);
+
+private:
+ void writeAssistantSettings();
+ void writeDocuments();
+
+ QString m_qhpFile;
+ QMap<QString, QString> m_properties;
+ QString m_titlePath;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpconverter/qhelpconverter.pro b/src/assistant/tools/qhelpconverter/qhelpconverter.pro
new file mode 100644
index 000000000..341faf346
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/qhelpconverter.pro
@@ -0,0 +1,47 @@
+QT += xml
+TEMPLATE = app
+TARGET = qhelpconverter
+DESTDIR = ../../../../bin
+CONFIG += qt warn_on help
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+SOURCES += conversionwizard.cpp \
+ inputpage.cpp \
+ generalpage.cpp \
+ filterpage.cpp \
+ identifierpage.cpp \
+ pathpage.cpp \
+ filespage.cpp \
+ outputpage.cpp \
+ finishpage.cpp \
+ adpreader.cpp \
+ qhpwriter.cpp \
+ qhcpwriter.cpp \
+ helpwindow.cpp \
+ main.cpp
+
+HEADERS += conversionwizard.h \
+ inputpage.h \
+ generalpage.h \
+ filterpage.h \
+ identifierpage.h \
+ pathpage.h \
+ filespage.h \
+ outputpage.h \
+ finishpage.h \
+ adpreader.h \
+ qhcpwriter.h \
+ qhpwriter.h \
+ helpwindow.h
+
+FORMS += inputpage.ui \
+ generalpage.ui \
+ filterpage.ui \
+ identifierpage.ui \
+ pathpage.ui \
+ filespage.ui \
+ outputpage.ui
+
+RESOURCES += qhelpconverter.qrc
diff --git a/src/assistant/tools/qhelpconverter/qhelpconverter.qrc b/src/assistant/tools/qhelpconverter/qhelpconverter.qrc
new file mode 100644
index 000000000..e2a68ab43
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/qhelpconverter.qrc
@@ -0,0 +1,13 @@
+<RCC>
+ <qresource prefix="/trolltech/qhelpconverter" >
+ <file>assistant-128.png</file>
+ <file>assistant.png</file>
+ <file>doc/inputpage.html</file>
+ <file>doc/generalpage.html</file>
+ <file>doc/filterpage.html</file>
+ <file>doc/identifierpage.html</file>
+ <file>doc/pathpage.html</file>
+ <file>doc/filespage.html</file>
+ <file>doc/outputpage.html</file>
+ </qresource>
+</RCC>
diff --git a/src/assistant/tools/qhelpconverter/qhpwriter.cpp b/src/assistant/tools/qhelpconverter/qhpwriter.cpp
new file mode 100644
index 000000000..51d392d32
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/qhpwriter.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFile>
+
+#include "qhpwriter.h"
+#include "adpreader.h"
+
+QT_BEGIN_NAMESPACE
+
+QhpWriter::QhpWriter(const QString &namespaceName,
+ const QString &virtualFolder)
+{
+ m_namespaceName = namespaceName;
+ m_virtualFolder = virtualFolder;
+ setAutoFormatting(true);
+}
+
+void QhpWriter::setAdpReader(AdpReader *reader)
+{
+ m_adpReader = reader;
+}
+
+void QhpWriter::setFilterAttributes(const QStringList &attributes)
+{
+ m_filterAttributes = attributes;
+}
+
+void QhpWriter::setCustomFilters(const QList<CustomFilter> filters)
+{
+ m_customFilters = filters;
+}
+
+void QhpWriter::setFiles(const QStringList &files)
+{
+ m_files = files;
+}
+
+void QhpWriter::generateIdentifiers(IdentifierPrefix prefix,
+ const QString prefixString)
+{
+ m_prefix = prefix;
+ m_prefixString = prefixString;
+}
+
+bool QhpWriter::writeFile(const QString &fileName)
+{
+ QFile out(fileName);
+ if (!out.open(QIODevice::WriteOnly))
+ return false;
+
+ setDevice(&out);
+ writeStartDocument();
+ writeStartElement(QLatin1String("QtHelpProject"));
+ writeAttribute(QLatin1String("version"), QLatin1String("1.0"));
+ writeTextElement(QLatin1String("namespace"), m_namespaceName);
+ writeTextElement(QLatin1String("virtualFolder"), m_virtualFolder);
+ writeCustomFilters();
+ writeFilterSection();
+ writeEndDocument();
+
+ out.close();
+ return true;
+}
+
+void QhpWriter::writeCustomFilters()
+{
+ if (!m_customFilters.count())
+ return;
+
+ foreach (const CustomFilter &f, m_customFilters) {
+ writeStartElement(QLatin1String("customFilter"));
+ writeAttribute(QLatin1String("name"), f.name);
+ foreach (const QString &a, f.filterAttributes)
+ writeTextElement(QLatin1String("filterAttribute"), a);
+ writeEndElement();
+ }
+}
+
+void QhpWriter::writeFilterSection()
+{
+ writeStartElement(QLatin1String("filterSection"));
+ foreach (const QString &a, m_filterAttributes)
+ writeTextElement(QLatin1String("filterAttribute"), a);
+
+ writeToc();
+ writeKeywords();
+ writeFiles();
+ writeEndElement();
+}
+
+void QhpWriter::writeToc()
+{
+ QList<ContentItem> lst = m_adpReader->contents();
+ if (lst.isEmpty())
+ return;
+
+ int depth = -1;
+ writeStartElement(QLatin1String("toc"));
+ foreach (const ContentItem &i, lst) {
+ while (depth-- >= i.depth)
+ writeEndElement();
+ writeStartElement(QLatin1String("section"));
+ writeAttribute(QLatin1String("title"), i.title);
+ writeAttribute(QLatin1String("ref"), i.reference);
+ depth = i.depth;
+ }
+ while (depth-- >= -1)
+ writeEndElement();
+}
+
+void QhpWriter::writeKeywords()
+{
+ QList<KeywordItem> lst = m_adpReader->keywords();
+ if (lst.isEmpty())
+ return;
+
+ writeStartElement(QLatin1String("keywords"));
+ foreach (const KeywordItem &i, lst) {
+ writeEmptyElement(QLatin1String("keyword"));
+ writeAttribute(QLatin1String("name"), i.keyword);
+ writeAttribute(QLatin1String("ref"), i.reference);
+ if (m_prefix == FilePrefix) {
+ QString str = i.reference.mid(
+ i.reference.lastIndexOf(QLatin1Char('/'))+1);
+ str = str.left(str.lastIndexOf(QLatin1Char('.')));
+ writeAttribute(QLatin1String("id"), str + QLatin1String("::") + i.keyword);
+ } else if (m_prefix == GlobalPrefix) {
+ writeAttribute(QLatin1String("id"), m_prefixString + i.keyword);
+ }
+ }
+ writeEndElement();
+}
+
+void QhpWriter::writeFiles()
+{
+ if (m_files.isEmpty())
+ return;
+
+ writeStartElement(QLatin1String("files"));
+ foreach (const QString &f, m_files)
+ writeTextElement(QLatin1String("file"), f);
+ writeEndElement();
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/qhelpconverter/qhpwriter.h b/src/assistant/tools/qhelpconverter/qhpwriter.h
new file mode 100644
index 000000000..70fd04aca
--- /dev/null
+++ b/src/assistant/tools/qhelpconverter/qhpwriter.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHPWRITER_H
+#define QHPWRITER_H
+
+#include <QtXml/QXmlStreamWriter>
+#include "filterpage.h"
+
+QT_BEGIN_NAMESPACE
+
+class AdpReader;
+
+class QhpWriter : public QXmlStreamWriter
+{
+public:
+ enum IdentifierPrefix {SkipAll, FilePrefix, GlobalPrefix};
+ QhpWriter(const QString &namespaceName,
+ const QString &virtualFolder);
+ void setAdpReader(AdpReader *reader);
+ void setFilterAttributes(const QStringList &attributes);
+ void setCustomFilters(const QList<CustomFilter> filters);
+ void setFiles(const QStringList &files);
+ void generateIdentifiers(IdentifierPrefix prefix,
+ const QString prefixString = QString());
+ bool writeFile(const QString &fileName);
+
+private:
+ void writeCustomFilters();
+ void writeFilterSection();
+ void writeToc();
+ void writeKeywords();
+ void writeFiles();
+
+ QString m_namespaceName;
+ QString m_virtualFolder;
+ AdpReader *m_adpReader;
+ QStringList m_filterAttributes;
+ QList<CustomFilter> m_customFilters;
+ QStringList m_files;
+ IdentifierPrefix m_prefix;
+ QString m_prefixString;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/qhelpgenerator/main.cpp b/src/assistant/tools/qhelpgenerator/main.cpp
new file mode 100644
index 000000000..386e84c41
--- /dev/null
+++ b/src/assistant/tools/qhelpgenerator/main.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../shared/helpgenerator.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTranslator>
+#include <QtCore/QLocale>
+#include <QtCore/QLibraryInfo>
+
+#include <private/qhelpprojectdata_p.h>
+
+QT_USE_NAMESPACE
+
+class QHG {
+ Q_DECLARE_TR_FUNCTIONS(QHelpGenerator)
+};
+
+int main(int argc, char *argv[])
+{
+ QString error;
+ QString arg;
+ QString compressedFile;
+ QString projectFile;
+ QString basePath;
+ bool showHelp = false;
+ bool showVersion = false;
+ bool checkLinks = false;
+
+ QCoreApplication app(argc, argv);
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QTranslator qt_helpTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("assistant_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)
+ && qt_helpTranslator.load(QLatin1String("qt_help_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ app.installTranslator(&qt_helpTranslator);
+ }
+#endif // Q_OS_WIN32
+
+ for (int i = 1; i < argc; ++i) {
+ arg = QString::fromLocal8Bit(argv[i]);
+ if (arg == QLatin1String("-o")) {
+ if (++i < argc) {
+ QFileInfo fi(QString::fromLocal8Bit(argv[i]));
+ compressedFile = fi.absoluteFilePath();
+ } else {
+ error = QHG::tr("Missing output file name.");
+ }
+ } else if (arg == QLatin1String("-v")) {
+ showVersion = true;
+ } else if (arg == QLatin1String("-h")) {
+ showHelp = true;
+ } else if (arg == QLatin1String("-c")) {
+ checkLinks = true;
+ } else {
+ QFileInfo fi(arg);
+ projectFile = fi.absoluteFilePath();
+ basePath = fi.absolutePath();
+ }
+ }
+
+ if (showVersion) {
+ fputs(qPrintable(QHG::tr("Qt Help Generator version 1.0 (Qt %1)\n")
+ .arg(QT_VERSION_STR)), stdout);
+ return 0;
+ }
+
+ if (projectFile.isEmpty() && !showHelp)
+ error = QHG::tr("Missing Qt help project file.");
+
+ QString help = QHG::tr("\nUsage:\n\n"
+ "qhelpgenerator <help-project-file> [options]\n\n"
+ " -o <compressed-file> Generates a Qt compressed help\n"
+ " file called <compressed-file>.\n"
+ " If this option is not specified\n"
+ " a default name will be used.\n"
+ " -c Checks whether all links in HTML files\n"
+ " point to files in this help project.\n"
+ " -v Displays the version of \n"
+ " qhelpgenerator.\n\n");
+
+ if (showHelp) {
+ fputs(qPrintable(help), stdout);
+ return 0;
+ }else if (!error.isEmpty()) {
+ fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
+ return -1;
+ }
+
+ QFile file(projectFile);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fputs(qPrintable(QHG::tr("Could not open %1.\n").arg(projectFile)), stderr);
+ return -1;
+ }
+
+ if (compressedFile.isEmpty()) {
+ if (!checkLinks) {
+ QFileInfo fi(projectFile);
+ compressedFile = basePath + QDir::separator()
+ + fi.baseName() + QLatin1String(".qch");
+ }
+ } else {
+ // check if the output dir exists -- create if it doesn't
+ QFileInfo fi(compressedFile);
+ QDir parentDir = fi.dir();
+ if (!parentDir.exists()) {
+ if (!parentDir.mkpath(QLatin1String("."))) {
+ fputs(qPrintable(QHG::tr("Could not create output directory: %1\n")
+ .arg(parentDir.path())), stderr);
+ }
+ }
+ }
+
+ QHelpProjectData *helpData = new QHelpProjectData();
+ if (!helpData->readData(projectFile)) {
+ fprintf(stderr, "%s\n", qPrintable(helpData->errorMessage()));
+ return -1;
+ }
+
+ HelpGenerator generator;
+ bool success = true;
+ if (checkLinks)
+ success = generator.checkLinks(*helpData);
+ if (success && !compressedFile.isEmpty())
+ success = generator.generate(helpData, compressedFile);
+ delete helpData;
+ if (!success) {
+ fprintf(stderr, "%s\n", qPrintable(generator.error()));
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/assistant/tools/qhelpgenerator/qhelpgenerator.pro b/src/assistant/tools/qhelpgenerator/qhelpgenerator.pro
new file mode 100644
index 000000000..68efcf593
--- /dev/null
+++ b/src/assistant/tools/qhelpgenerator/qhelpgenerator.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = qhelpgenerator
+DESTDIR = ../../../../bin
+CONFIG += qt warn_on help console
+CONFIG -= app_bundle
+QT += network
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+SOURCES += ../shared/helpgenerator.cpp \
+ main.cpp
+
+HEADERS += ../shared/helpgenerator.h
diff --git a/src/assistant/tools/shared/collectionconfiguration.cpp b/src/assistant/tools/shared/collectionconfiguration.cpp
new file mode 100644
index 000000000..35d5b66df
--- /dev/null
+++ b/src/assistant/tools/shared/collectionconfiguration.cpp
@@ -0,0 +1,327 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "collectionconfiguration.h"
+
+#include <QtHelp/QHelpEngineCore>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ const QString AboutIconKey(QLatin1String("AboutIcon"));
+ const QString AboutImagesKey(QLatin1String("AboutImages"));
+ const QString AboutMenuTextsKey(QLatin1String("AboutMenuTexts"));
+ const QString AboutTextsKey(QLatin1String("AboutTexts"));
+ const QString ApplicationIconKey(QLatin1String("ApplicationIcon"));
+ const QString CacheDirKey(QLatin1String("CacheDirectory"));
+ const QString CacheDirRelativeToCollectionKey(QLatin1String("CacheDirRelativeToCollection"));
+ const QString CreationTimeKey(QLatin1String("CreationTime"));
+ const QString DefaultHomePageKey(QLatin1String("defaultHomepage"));
+ const QString EnableAddressBarKey(QLatin1String("EnableAddressBar"));
+ const QString EnableDocManagerKey(QLatin1String("EnableDocumentationManager"));
+ const QString EnableFilterKey(QLatin1String("EnableFilterFunctionality"));
+ const QString HideAddressBarKey(QLatin1String("HideAddressBar"));
+ const QString FilterToolbarHiddenKey(QLatin1String("HideFilterFunctionality"));
+ const QString LastPageKey(QLatin1String("LastTabPage"));
+ const QString LastRegisterTime(QLatin1String("LastRegisterTime"));
+ const QString LastShownPagesKey(QLatin1String("LastShownPages"));
+ const QString LastZoomFactorsKey(QLatin1String(
+#if !defined(QT_NO_WEBKIT)
+ "LastPagesZoomWebView"
+#else
+ "LastPagesZoomTextBrowser"
+#endif
+ ));
+ const QString WindowTitleKey(QLatin1String("WindowTitle"));
+ const QString FullTextSearchFallbackKey(QLatin1String("FullTextSearchFallback"));
+} // anonymous namespace
+
+const QString CollectionConfiguration::DefaultZoomFactor(QLatin1String("0.0"));
+const QString CollectionConfiguration::ListSeparator(QLatin1String("|"));
+
+uint CollectionConfiguration::creationTime(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(CreationTimeKey, 0).toUInt();
+}
+
+void CollectionConfiguration::setCreationTime(QHelpEngineCore &helpEngine, uint time)
+{
+ helpEngine.setCustomValue(CreationTimeKey, time);
+}
+
+const QString CollectionConfiguration::windowTitle(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(WindowTitleKey).toString();
+}
+
+void CollectionConfiguration::setWindowTitle(QHelpEngineCore &helpEngine,
+ const QString &windowTitle)
+{
+ helpEngine.setCustomValue(WindowTitleKey, windowTitle);
+}
+
+bool CollectionConfiguration::filterFunctionalityEnabled(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(EnableFilterKey, true).toBool();
+}
+
+void CollectionConfiguration::setFilterFunctionalityEnabled(QHelpEngineCore &helpEngine,
+ bool enabled)
+{
+ helpEngine.setCustomValue(EnableFilterKey, enabled);
+}
+
+bool CollectionConfiguration::filterToolbarVisible(const QHelpEngineCore &helpEngine)
+{
+ return !helpEngine.customValue(FilterToolbarHiddenKey, true).toBool();
+}
+
+void CollectionConfiguration::setFilterToolbarVisible(QHelpEngineCore &helpEngine,
+ bool visible)
+{
+ helpEngine.setCustomValue(FilterToolbarHiddenKey, !visible);
+}
+
+bool CollectionConfiguration::addressBarEnabled(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(EnableAddressBarKey, true).toBool();
+}
+
+void CollectionConfiguration::setAddressBarEnabled(QHelpEngineCore &helpEngine,
+ bool enabled)
+{
+ helpEngine.setCustomValue(EnableAddressBarKey, enabled);
+}
+
+bool CollectionConfiguration::addressBarVisible(const QHelpEngineCore &helpEngine)
+{
+ return !helpEngine.customValue(HideAddressBarKey, true).toBool();
+}
+
+void CollectionConfiguration::setAddressBarVisible(QHelpEngineCore &helpEngine,
+ bool visible)
+{
+ helpEngine.setCustomValue(HideAddressBarKey, !visible);
+}
+
+const QString CollectionConfiguration::cacheDir(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(CacheDirKey).toString();
+}
+
+bool CollectionConfiguration::cacheDirIsRelativeToCollection(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(CacheDirRelativeToCollectionKey).toBool();
+}
+
+void CollectionConfiguration::setCacheDir(QHelpEngineCore &helpEngine,
+ const QString &cacheDir, bool relativeToCollection)
+{
+ helpEngine.setCustomValue(CacheDirKey, cacheDir);
+ helpEngine.setCustomValue(CacheDirRelativeToCollectionKey,
+ relativeToCollection);
+}
+
+bool CollectionConfiguration::documentationManagerEnabled(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(EnableDocManagerKey, true).toBool();
+}
+
+void CollectionConfiguration::setDocumentationManagerEnabled(QHelpEngineCore &helpEngine,
+ bool enabled)
+{
+ helpEngine.setCustomValue(EnableDocManagerKey, enabled);
+}
+
+const QByteArray CollectionConfiguration::applicationIcon(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(ApplicationIconKey).toByteArray();
+}
+
+void CollectionConfiguration::setApplicationIcon(QHelpEngineCore &helpEngine,
+ const QByteArray &icon)
+{
+ helpEngine.setCustomValue(ApplicationIconKey, icon);
+}
+
+const QByteArray CollectionConfiguration::aboutMenuTexts(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(AboutMenuTextsKey).toByteArray();
+}
+
+void CollectionConfiguration::setAboutMenuTexts(QHelpEngineCore &helpEngine,
+ const QByteArray &texts)
+{
+ helpEngine.setCustomValue(AboutMenuTextsKey, texts);
+}
+
+const QByteArray CollectionConfiguration::aboutIcon(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(AboutIconKey).toByteArray();
+}
+
+void CollectionConfiguration::setAboutIcon(QHelpEngineCore &helpEngine,
+ const QByteArray &icon)
+{
+ helpEngine.setCustomValue(AboutIconKey, icon);
+}
+
+const QByteArray CollectionConfiguration::aboutTexts(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(AboutTextsKey).toByteArray();
+}
+
+void CollectionConfiguration::setAboutTexts(QHelpEngineCore &helpEngine,
+ const QByteArray &texts)
+{
+ helpEngine.setCustomValue(AboutTextsKey, texts);
+}
+
+const QByteArray CollectionConfiguration::aboutImages(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(AboutImagesKey).toByteArray();
+}
+
+void CollectionConfiguration::setAboutImages(QHelpEngineCore &helpEngine,
+ const QByteArray &images)
+{
+ helpEngine.setCustomValue(AboutImagesKey, images);
+}
+
+const QString CollectionConfiguration::defaultHomePage(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(DefaultHomePageKey, QLatin1String("help")).
+ toString();
+}
+
+void CollectionConfiguration::setDefaultHomePage(QHelpEngineCore &helpEngine,
+ const QString &page)
+{
+ helpEngine.setCustomValue(DefaultHomePageKey, page);
+}
+
+const QStringList CollectionConfiguration::lastShownPages(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(LastShownPagesKey).toString().
+ split(ListSeparator, QString::SkipEmptyParts);
+}
+
+void CollectionConfiguration::setLastShownPages(QHelpEngineCore &helpEngine,
+ const QStringList &lastShownPages)
+{
+ helpEngine.setCustomValue(LastShownPagesKey,
+ lastShownPages.join(ListSeparator));
+}
+
+const QStringList CollectionConfiguration::lastZoomFactors(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(LastZoomFactorsKey).toString().
+ split(ListSeparator, QString::SkipEmptyParts);
+}
+
+void CollectionConfiguration::setLastZoomFactors(QHelpEngineCore &helpEngine,
+ const QStringList &lastZoomFactors)
+{
+ helpEngine.setCustomValue(LastZoomFactorsKey,
+ lastZoomFactors.join(ListSeparator));
+}
+
+int CollectionConfiguration::lastTabPage(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(LastPageKey, 1).toInt();
+}
+
+void CollectionConfiguration::setLastTabPage(QHelpEngineCore &helpEngine,
+ int lastPage)
+{
+ helpEngine.setCustomValue(LastPageKey, lastPage);
+}
+
+const QDateTime CollectionConfiguration::lastRegisterTime(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(LastRegisterTime, QDateTime()).toDateTime();
+}
+
+void CollectionConfiguration::updateLastRegisterTime(QHelpEngineCore &helpEngine)
+{
+ helpEngine.setCustomValue(LastRegisterTime, QDateTime::currentDateTime());
+}
+
+bool CollectionConfiguration::isNewer(const QHelpEngineCore &newer,
+ const QHelpEngineCore &older)
+{
+ return creationTime(newer) > creationTime(older);
+}
+
+void CollectionConfiguration::copyConfiguration(const QHelpEngineCore &source,
+ QHelpEngineCore &target)
+{
+ setCreationTime(target, creationTime(source));
+ setWindowTitle(target, windowTitle(source));
+ target.setCurrentFilter(source.currentFilter());
+ setCacheDir(target, cacheDir(source), cacheDirIsRelativeToCollection(source));
+ setFilterFunctionalityEnabled(target, filterFunctionalityEnabled(source));
+ setFilterToolbarVisible(target, filterToolbarVisible(source));
+ setAddressBarEnabled(target, addressBarEnabled(source));
+ setAddressBarVisible(target, addressBarVisible(source));
+ setDocumentationManagerEnabled(target, documentationManagerEnabled(source));
+ setApplicationIcon(target, applicationIcon(source));
+ setAboutMenuTexts(target, aboutMenuTexts(source));
+ setAboutIcon(target, aboutIcon(source));
+ setAboutTexts(target, aboutTexts(source));
+ setAboutImages(target, aboutImages(source));
+ setDefaultHomePage(target, defaultHomePage(source));
+ setFullTextSearchFallbackEnabled(target, fullTextSearchFallbackEnabled(source));
+}
+
+bool CollectionConfiguration:: fullTextSearchFallbackEnabled(
+ const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(FullTextSearchFallbackKey, false).toBool();
+}
+
+void CollectionConfiguration::setFullTextSearchFallbackEnabled(
+ QHelpEngineCore &helpEngine, bool on)
+{
+ helpEngine.setCustomValue(FullTextSearchFallbackKey, on);
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/shared/collectionconfiguration.h b/src/assistant/tools/shared/collectionconfiguration.h
new file mode 100644
index 000000000..226460ef3
--- /dev/null
+++ b/src/assistant/tools/shared/collectionconfiguration.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COLLECTIONCONFIGURATION_H
+#define COLLECTIONCONFIGURATION_H
+
+#include <QtCore/QByteArray>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDateTime>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpEngineCore;
+
+class CollectionConfiguration
+{
+public:
+ static const QString windowTitle(const QHelpEngineCore &helpEngine);
+ static void setWindowTitle(QHelpEngineCore &helpEngine,
+ const QString &windowTitle);
+
+ static const QString cacheDir(const QHelpEngineCore &helpEngine);
+ static bool cacheDirIsRelativeToCollection(const QHelpEngineCore &helpEngine);
+ static void setCacheDir(QHelpEngineCore &helpEngine,
+ const QString &cacheDir, bool relativeToCollection);
+
+ static uint creationTime(const QHelpEngineCore &helpEngine);
+ static void setCreationTime(QHelpEngineCore &helpEngine, uint time);
+
+ static bool filterFunctionalityEnabled(const QHelpEngineCore &helpEngine);
+ static void setFilterFunctionalityEnabled(QHelpEngineCore &helpEngine,
+ bool enabled);
+
+ static bool filterToolbarVisible(const QHelpEngineCore &helpEngine);
+ static void setFilterToolbarVisible(QHelpEngineCore &helpEngine,
+ bool visible);
+
+ static bool addressBarEnabled(const QHelpEngineCore &helpEngine);
+ static void setAddressBarEnabled(QHelpEngineCore &helpEngine, bool enabled);
+
+ static bool addressBarVisible(const QHelpEngineCore &helpEngine);
+ static void setAddressBarVisible(QHelpEngineCore &helpEngine, bool visible);
+
+
+ static bool documentationManagerEnabled(const QHelpEngineCore &helpEngine);
+ static void setDocumentationManagerEnabled(QHelpEngineCore &helpEngine,
+ bool enabled);
+
+ static const QByteArray applicationIcon(const QHelpEngineCore &helpEngine);
+ static void setApplicationIcon(QHelpEngineCore &helpEngine,
+ const QByteArray &icon);
+
+ // TODO: Encapsulate encoding from/to QByteArray here
+ static const QByteArray aboutMenuTexts(const QHelpEngineCore &helpEngine);
+ static void setAboutMenuTexts(QHelpEngineCore &helpEngine,
+ const QByteArray &texts);
+
+ static const QByteArray aboutIcon(const QHelpEngineCore &helpEngine);
+ static void setAboutIcon(QHelpEngineCore &helpEngine,
+ const QByteArray &icon);
+
+ // TODO: Encapsulate encoding from/to QByteArray here
+ static const QByteArray aboutTexts(const QHelpEngineCore &helpEngine);
+ static void setAboutTexts(QHelpEngineCore &helpEngine,
+ const QByteArray &texts);
+
+ static const QByteArray aboutImages(const QHelpEngineCore &helpEngine);
+ static void setAboutImages(QHelpEngineCore &helpEngine,
+ const QByteArray &images);
+
+ static const QString defaultHomePage(const QHelpEngineCore &helpEngine);
+ static void setDefaultHomePage(QHelpEngineCore &helpEngine,
+ const QString &page);
+
+ // TODO: Don't allow last pages and zoom factors to be set in isolation
+ // Perhaps also fill up missing elements automatically or assert.
+ static const QStringList lastShownPages(const QHelpEngineCore &helpEngine);
+ static void setLastShownPages(QHelpEngineCore &helpEngine,
+ const QStringList &lastShownPages);
+ static const QStringList lastZoomFactors(const QHelpEngineCore &helpEngine);
+ static void setLastZoomFactors(QHelpEngineCore &helPEngine,
+ const QStringList &lastZoomFactors);
+
+ static int lastTabPage(const QHelpEngineCore &helpEngine);
+ static void setLastTabPage(QHelpEngineCore &helpEngine, int lastPage);
+
+ static bool isNewer(const QHelpEngineCore &newer,
+ const QHelpEngineCore &older);
+ static void copyConfiguration(const QHelpEngineCore &source,
+ QHelpEngineCore &target);
+
+ /*
+ * Note that this only reflects register actions caused by the
+ * "-register" command line switch, not GUI or remote control actions.
+ */
+ static const QDateTime lastRegisterTime(const QHelpEngineCore &helpEngine);
+ static void updateLastRegisterTime(QHelpEngineCore &helpEngine);
+
+ static bool fullTextSearchFallbackEnabled(const QHelpEngineCore &helpEngine);
+ static void setFullTextSearchFallbackEnabled(QHelpEngineCore &helpEngine,
+ bool on);
+
+ static const QString DefaultZoomFactor;
+ static const QString ListSeparator;
+};
+
+QT_END_NAMESPACE
+
+#endif // COLLECTIONCONFIGURATION_H
diff --git a/src/assistant/tools/shared/helpgenerator.cpp b/src/assistant/tools/shared/helpgenerator.cpp
new file mode 100644
index 000000000..d551548fb
--- /dev/null
+++ b/src/assistant/tools/shared/helpgenerator.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpgenerator.h"
+
+#include <private/qhelpgenerator_p.h>
+#include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+HelpGenerator::HelpGenerator()
+{
+ generator = new QHelpGenerator(this);
+ connect(generator, SIGNAL(statusChanged(QString)),
+ this, SLOT(printStatus(QString)));
+ connect(generator, SIGNAL(warning(QString)),
+ this, SLOT(printWarning(QString)));
+}
+
+bool HelpGenerator::generate(QHelpDataInterface *helpData,
+ const QString &outputFileName)
+{
+ return generator->generate(helpData, outputFileName);
+}
+
+bool HelpGenerator::checkLinks(const QHelpDataInterface &helpData)
+{
+ return generator->checkLinks(helpData);
+}
+
+QString HelpGenerator::error() const
+{
+ return generator->error();
+}
+
+void HelpGenerator::printStatus(const QString &msg)
+{
+ puts(qPrintable(msg));
+}
+
+void HelpGenerator::printWarning(const QString &msg)
+{
+ puts(qPrintable(tr("Warning: %1").arg(msg)));
+}
+
+QT_END_NAMESPACE
diff --git a/src/assistant/tools/shared/helpgenerator.h b/src/assistant/tools/shared/helpgenerator.h
new file mode 100644
index 000000000..e220a2b68
--- /dev/null
+++ b/src/assistant/tools/shared/helpgenerator.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPGENERATOR_H
+#define HELPGENERATOR_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpDataInterface;
+class QHelpGenerator;
+
+class HelpGenerator : public QObject
+{
+ Q_OBJECT
+
+public:
+ HelpGenerator();
+ bool generate(QHelpDataInterface *helpData,
+ const QString &outputFileName);
+ bool checkLinks(const QHelpDataInterface &helpData);
+ QString error() const;
+
+private slots:
+ void printStatus(const QString &msg);
+ void printWarning(const QString &msg);
+
+private:
+ QHelpGenerator *generator;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/assistant/tools/tools.pro b/src/assistant/tools/tools.pro
new file mode 100644
index 000000000..8bb8cd700
--- /dev/null
+++ b/src/assistant/tools/tools.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS += assistant \
+ qhelpgenerator \
+ qcollectiongenerator \
+ qhelpconverter
+
diff --git a/src/checksdk/README b/src/checksdk/README
new file mode 100644
index 000000000..7eba1db48
--- /dev/null
+++ b/src/checksdk/README
@@ -0,0 +1,3 @@
+checkSDK is used to build Qt/WinCE successfully. It parses the Visual
+Studio configuration and sets up the environment for cross-compilation.
+
diff --git a/src/checksdk/cesdkhandler.cpp b/src/checksdk/cesdkhandler.cpp
new file mode 100644
index 000000000..ad58f42dd
--- /dev/null
+++ b/src/checksdk/cesdkhandler.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "cesdkhandler.h"
+#include <QtCore/QFile>
+#include <QtCore/QDebug>
+#include <QtCore/QXmlStreamReader>
+
+CeSdkInfo::CeSdkInfo() : m_major(0) , m_minor(0)
+{
+}
+
+QStringList CeSdkInfo::environment()
+{
+ QStringList result;
+ QString argument = QLatin1String("PATH=");
+ argument += m_bin;
+ result.append(argument);
+ argument = QLatin1String("INCLUDE=");
+ argument += m_include;
+ result.append(argument);
+ argument = QLatin1String("LIB=");
+ argument += m_lib;
+ result.append(argument);
+ return result;
+}
+
+CeSdkHandler::CeSdkHandler()
+{
+}
+
+bool CeSdkHandler::parse()
+{
+ // look at the file at %VCInstallDir%/vcpackages/WCE.VCPlatform.config
+ // and scan through all installed sdks...
+ m_list.clear();
+ VCInstallDir = QString::fromLatin1(qgetenv("VCInstallDir"));
+ VCInstallDir += QLatin1String("\\");
+ VSInstallDir = QString::fromLatin1(qgetenv("VSInstallDir"));
+ VSInstallDir += QLatin1String("\\");
+ if (VCInstallDir.isEmpty() || VSInstallDir.isEmpty())
+ return false;
+
+ QDir vStudioDir(VCInstallDir);
+ if (!vStudioDir.cd(QLatin1String("vcpackages")))
+ return false;
+
+ QFile configFile(vStudioDir.absoluteFilePath(QLatin1String("WCE.VCPlatform.config")));
+ if (!configFile.exists() || !configFile.open(QIODevice::ReadOnly))
+ return false;
+
+ QString currentElement;
+ CeSdkInfo currentItem;
+ QXmlStreamReader xml(&configFile);
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.isStartElement()) {
+ currentElement = xml.name().toString();
+ if (currentElement == QLatin1String("Platform"))
+ currentItem = CeSdkInfo();
+ else if (currentElement == QLatin1String("Directories")) {
+ QXmlStreamAttributes attr = xml.attributes();
+ currentItem.m_include = fixPaths(attr.value(QLatin1String("Include")).toString());
+ currentItem.m_lib = fixPaths(attr.value(QLatin1String("Library")).toString());
+ currentItem.m_bin = fixPaths(attr.value(QLatin1String("Path")).toString());
+ }
+ } else if (xml.isEndElement()) {
+ if (xml.name().toString() == QLatin1String("Platform"))
+ m_list.append(currentItem);
+ } else if (xml.isCharacters() && !xml.isWhitespace()) {
+ if (currentElement == QLatin1String("PlatformName"))
+ currentItem.m_name = xml.text().toString();
+ else if (currentElement == QLatin1String("OSMajorVersion"))
+ currentItem.m_major = xml.text().toString().toInt();
+ else if (currentElement == QLatin1String("OSMinorVersion"))
+ currentItem.m_minor = xml.text().toString().toInt();
+ }
+ }
+
+ if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
+ qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
+ return false;
+ }
+
+ return m_list.size() > 0 ? true : false;
+}
+
+CeSdkInfo CeSdkHandler::find(const QString &name)
+{
+ for (QList<CeSdkInfo>::iterator it = m_list.begin(); it != m_list.end(); ++it) {
+ if (it->name() == name)
+ return *it;
+ }
+ return CeSdkInfo();
+}
diff --git a/src/checksdk/cesdkhandler.h b/src/checksdk/cesdkhandler.h
new file mode 100644
index 000000000..5ece4fdbb
--- /dev/null
+++ b/src/checksdk/cesdkhandler.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CE_SDK_HANDLER_INCL
+#define CE_SDK_HANDLER_INCL
+
+#include <QStringList>
+#include <QDir>
+
+QT_USE_NAMESPACE
+
+#define VCINSTALL_MACRO "$(VCInstallDir)"
+#define VSINSTALL_MACRO "$(VSInstallDir)"
+
+class CeSdkInfo
+{
+public:
+ CeSdkInfo();
+ inline QString name();
+ inline QString binPath();
+ inline QString includePath();
+ inline QString libPath();
+ QStringList environment();
+ inline bool isValid();
+ inline int majorVersion();
+ inline int minorVersion();
+ inline bool isSupported();
+private:
+ friend class CeSdkHandler;
+ QString m_name;
+ QString m_bin;
+ QString m_include;
+ QString m_lib;
+ int m_major;
+ int m_minor;
+};
+
+inline QString CeSdkInfo::name(){ return m_name; }
+inline QString CeSdkInfo::binPath(){ return m_bin; }
+inline QString CeSdkInfo::includePath(){ return m_include; }
+inline QString CeSdkInfo::libPath(){ return m_lib; }
+inline bool CeSdkInfo::isValid(){ return !m_name.isEmpty() && !m_bin.isEmpty() && !m_include.isEmpty() && !m_lib.isEmpty(); }
+inline int CeSdkInfo::majorVersion(){ return m_major; }
+inline int CeSdkInfo::minorVersion(){ return m_minor; }
+inline bool CeSdkInfo::isSupported() { return m_major >= 5; }
+
+class CeSdkHandler
+{
+public:
+ CeSdkHandler();
+ bool parse();
+ inline QList<CeSdkInfo> listAll() const;
+ CeSdkInfo find(const QString &name);
+private:
+ inline QString fixPaths(QString path) const;
+ QList<CeSdkInfo> m_list;
+ QString VCInstallDir;
+ QString VSInstallDir;
+};
+
+inline QList<CeSdkInfo> CeSdkHandler::listAll() const
+{
+ return m_list;
+}
+
+inline QString CeSdkHandler::fixPaths(QString path) const
+{
+ QString str = QDir::toNativeSeparators(QDir::cleanPath(path.replace(QLatin1String(VCINSTALL_MACRO), VCInstallDir).replace(QLatin1String(VSINSTALL_MACRO), VSInstallDir).replace(QLatin1String("$(PATH)"), QLatin1String("%PATH%"))));
+ if (str.endsWith(QLatin1Char(';')))
+ str.truncate(str.length() - 1);
+ return str;
+}
+
+#endif
diff --git a/src/checksdk/checksdk.pro b/src/checksdk/checksdk.pro
new file mode 100644
index 000000000..a513981af
--- /dev/null
+++ b/src/checksdk/checksdk.pro
@@ -0,0 +1,36 @@
+TEMPLATE = app
+DESTDIR = ../../bin
+TARGET = checksdk
+DEPENDPATH += .
+INCLUDEPATH += .
+QT =
+CONFIG += console
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+DEFINES += QT_BOOTSTRAPPED QT_NO_CODECS QT_LITE_UNICODE QT_NO_LIBRARY \
+ QT_NO_STL QT_NO_COMPRESS QT_NO_DATASTREAM \
+ QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_NO_THREAD \
+ QT_NO_SYSTEMLOCALE QT_NO_GEOM_VARIANT \
+ QT_NODLL QT_NO_QOBJECT
+
+INCLUDEPATH = \
+ $$QT_BUILD_TREE/src/corelib/arch \
+ $$QT_BUILD_TREE/include \
+ $$QT_BUILD_TREE/include/QtCore
+
+DEPENDPATH += $$INCLUDEPATH $$QT_BUILD_TREE/src/corelib/base $$QT_BUILD_TREE/src/corelib/tools $$QT_BUILD_TREE/src/corelib/io
+
+# Input
+SOURCES += \
+ main.cpp \
+ cesdkhandler.cpp
+
+HEADERS += \
+ cesdkhandler.h
+
+include(../../src/tools/bootstrap/bootstrap.pri)
+
diff --git a/src/checksdk/main.cpp b/src/checksdk/main.cpp
new file mode 100644
index 000000000..a5ff61d56
--- /dev/null
+++ b/src/checksdk/main.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "cesdkhandler.h"
+#include <QtCore/QStringList>
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+
+void usage()
+{
+ printf("SDK Scanner - Convenience Tool to setup your environment\n");
+ printf(" for crosscompilation to Windows CE\n");
+ printf("Options:\n");
+ printf("-help This output\n");
+ printf("-list List all available SDKs\n");
+ printf("-sdk <name> Select specified SDK.\n");
+ printf(" Note: SDK names with spaces need to be\n");
+ printf(" specified in parenthesis\n");
+ printf(" default: Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\n");
+ printf("-script <file> Create a script file which can be launched\n");
+ printf(" to setup your environment for specified SDK\n");
+}
+
+int main(int argc, char **argv)
+{
+ if (argc == 1) {
+ usage();
+ return 0;
+ }
+ QString sdkName;
+ bool operationList = false;
+ QString scriptFile;
+
+ QStringList arguments;
+ for (int i=0; i < argc; ++i)
+ arguments.append(QLatin1String(argv[i]));
+ for (int i=1; i < arguments.size(); ++i) {
+ if (arguments[i].toLower() == QLatin1String("-help")) {
+ usage();
+ return 0;
+ } else if (arguments[i].toLower() == QLatin1String("-list")) {
+ operationList = true;
+ } else if (arguments[i].toLower() == QLatin1String("-sdk")) {
+ if (i+1 >= arguments.size()) {
+ qWarning("No SDK specified.");
+ return -1;
+ }
+ sdkName = arguments[++i];
+ } else if (arguments[i].toLower() == QLatin1String("-script")) {
+ if (i+1 >= arguments.size()) {
+ qWarning("No scriptfile specified.");
+ return -1;
+ }
+ scriptFile = arguments[++i];
+ } else {
+ qWarning("Unknown option:%s", qPrintable(arguments[i]));
+ usage();
+ return -1;
+ }
+ }
+
+ CeSdkHandler handler;
+ if (!handler.parse()) {
+ qWarning("Could not find any installed SDK, aborting!");
+ return -1;
+ }
+
+ QList<CeSdkInfo> list = handler.listAll();
+
+ if (operationList) {
+ printf("Available SDKs:\n");
+ for (QList<CeSdkInfo>::iterator it = list.begin(); it != list.end(); ++it) {
+ printf("SDK Name: ");
+ printf(qPrintable(it->name()));
+ printf("\n");
+ }
+ return 0;
+ }
+
+ // Check for SDK Name, otherwise use Windows Mobile as default
+ if (sdkName.isEmpty()) {
+ qWarning("No SDK specified: Defaulting to Windows Mobile 5.0 Pocket PC SDK");
+ sdkName = QString::fromLatin1("Windows Mobile 5.0 Pocket PC SDK (ARMV4I)");
+ }
+
+ // finally find the given SDK and prompt out the environment to be set
+ for (QList<CeSdkInfo>::iterator it = list.begin(); it != list.end(); ++it ) {
+ if (sdkName == it->name()) {
+ if (!it->isValid()) {
+ qWarning("Selected SDK is not valid!");
+ return -1;
+ } else if (!it->isSupported()) {
+ qWarning("Selected SDK is not officially supported and might not work");
+ }
+ QString binPath, includePath, libPath;
+ binPath = QString::fromLatin1("PATH=") + it->binPath();
+ includePath = QString::fromLatin1("INCLUDE=") + it->includePath();
+ libPath = QString::fromLatin1("LIB=") + it->libPath();
+ if (scriptFile.isEmpty()) {
+ printf("Please set up your environment with the following paths:\n");
+ printf(qPrintable(binPath));
+ printf("\n");
+ printf(qPrintable(includePath));
+ printf("\n");
+ printf(qPrintable(libPath));
+ printf("\n");
+ return 0;
+ } else {
+ QFile file(scriptFile);
+ if (!file.open(QIODevice::WriteOnly)) {
+ qWarning("Could not open target script file");
+ return -1;
+ }
+ QString content;
+ content += QLatin1String("@echo off\n");
+ content += QLatin1String("echo Environment Selection:") + sdkName + QLatin1String("\n");
+ content += QLatin1String("set ") + binPath + QLatin1String("\n");
+ content += QLatin1String("set ") + includePath + QLatin1String("\n");
+ content += QLatin1String("set ") + libPath + QLatin1String("\n");
+ file.write(content.toLatin1());
+ return 0;
+ }
+ }
+ }
+ qWarning("Could not find specified SDK: %s" , qPrintable(sdkName));
+ return -1;
+}
diff --git a/src/designer/data/generate_header.xsl b/src/designer/data/generate_header.xsl
new file mode 100644
index 000000000..127f00557
--- /dev/null
+++ b/src/designer/data/generate_header.xsl
@@ -0,0 +1,465 @@
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY endl "&#10;">
+]>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xsl:output method="text"/>
+
+ <xsl:include href="generate_shared.xsl"/>
+
+<!-- Forward declaration -->
+
+ <xsl:template name="class-forward-declaration">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/attribute::name)"/>
+
+ <xsl:text>class </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>;&endl;</xsl:text>
+ </xsl:template>
+
+<!-- Class declaration: child element accessors -->
+
+ <xsl:template name="child-element-accessors">
+ <xsl:param name="node"/>
+
+ <xsl:variable name="isChoice" select="name($node)='xs:choice'"/>
+
+ <xsl:if test="$isChoice">
+ <xsl:text> enum Kind { Unknown = 0</xsl:text>
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ </xsl:for-each>
+ <xsl:text> };&endl;</xsl:text>
+ <xsl:text> inline Kind kind() const { return m_kind; }&endl;&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="array" select="@maxOccurs='unbounded'"/>
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="return-cpp-type">
+ <xsl:call-template name="xs-type-to-cpp-return-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="$array"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="argument-cpp-type">
+ <xsl:call-template name="xs-type-to-cpp-argument-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="$array"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="xs-type-cat">
+ <xsl:call-template name="xs-type-category">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="$array"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> inline </xsl:text>
+ <xsl:value-of select="$return-cpp-type"/>
+ <xsl:text> element</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>() const { return m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>; }&endl;</xsl:text>
+
+ <xsl:if test="$xs-type-cat = 'pointer'">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$return-cpp-type"/>
+ <xsl:text> takeElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>();&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:text> void setElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$argument-cpp-type"/>
+ <xsl:text> a);&endl;</xsl:text>
+
+ <xsl:if test="not($isChoice) and not(@maxOccurs='unbounded')">
+ <xsl:text> inline bool hasElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>() const { return m_children &amp; </xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>; }&endl;</xsl:text>
+ <xsl:text> void clearElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>();&endl;</xsl:text>
+ </xsl:if>
+ <xsl:text>&endl;</xsl:text>
+
+ </xsl:for-each>
+ </xsl:template>
+
+<!-- Class declaration: child element data -->
+
+ <xsl:template name="child-element-data">
+ <xsl:param name="node"/>
+
+ <xsl:variable name="isChoice" select="$node[name()='xs:choice']"/>
+
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cpp-type">
+ <xsl:call-template name="xs-type-to-cpp-return-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="@maxOccurs='unbounded'"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$cpp-type"/>
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ </xsl:for-each>
+
+ <xsl:if test="not($isChoice) and not(@macOccurs='unbounded')">
+ <xsl:text> enum Child {&endl;</xsl:text>
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> </xsl:text>
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ <xsl:text> = </xsl:text>
+ <xsl:call-template name="powers-of-two">
+ <xsl:with-param name="num" select="position() - 1"/>
+ </xsl:call-template>
+ <xsl:if test="position()!=last()">
+ <xsl:text>,</xsl:text>
+ </xsl:if>
+ <xsl:text>&endl;</xsl:text>
+
+ </xsl:for-each>
+ <xsl:text> };&endl;</xsl:text>
+ </xsl:if>
+ </xsl:template>
+
+<!-- Class declaration: attribute accessors -->
+
+ <xsl:template name="attribute-accessors">
+ <xsl:param name="node"/>
+
+ <xsl:for-each select="$node/xs:attribute">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cpp-return-type">
+ <xsl:call-template name="xs-type-to-cpp-return-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cpp-argument-type">
+ <xsl:call-template name="xs-type-to-cpp-argument-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> inline bool hasAttribute</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>() const { return m_has_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>; }&endl;</xsl:text>
+
+ <xsl:text> inline </xsl:text>
+ <xsl:value-of select="$cpp-return-type"/>
+ <xsl:text> attribute</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>() const { return m_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>; }&endl;</xsl:text>
+
+ <xsl:text> inline void setAttribute</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$cpp-argument-type"/>
+ <xsl:text> a) { m_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = a; m_has_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = true; }&endl;</xsl:text>
+
+ <xsl:text> inline void clearAttribute</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>() { m_has_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = false; }&endl;&endl;</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+<!-- Class declaration -->
+
+ <xsl:template name="class-declaration">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+<!-- <xsl:variable name="hasText" select="$node[@mixed='true']"/>-->
+ <xsl:variable name="hasText" select="true()"/>
+
+ <xsl:text>class QDESIGNER_UILIB_EXPORT </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text> {&endl;</xsl:text>
+ <xsl:text>public:&endl;</xsl:text>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>();&endl;</xsl:text>
+ <xsl:text> ~</xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>();&endl;&endl;</xsl:text>
+
+ <xsl:text> void read(QXmlStreamReader &amp;reader);&endl;</xsl:text>
+ <xsl:text>#ifdef QUILOADER_QDOM_READ&endl;</xsl:text>
+ <xsl:text> void read(const QDomElement &amp;node);&endl;</xsl:text>
+ <xsl:text>#endif&endl;</xsl:text>
+ <xsl:text> void write(QXmlStreamWriter &amp;writer, const QString &amp;tagName = QString()) const;&endl;</xsl:text>
+
+ <xsl:if test="$hasText">
+ <xsl:text> inline QString text() const { return m_text; }&endl;</xsl:text>
+ <xsl:text> inline void setText(const QString &amp;s) { m_text = s; }&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:text>&endl;</xsl:text>
+
+ <xsl:text> // attribute accessors&endl;</xsl:text>
+ <xsl:call-template name="attribute-accessors">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:text> // child element accessors&endl;</xsl:text>
+
+ <xsl:for-each select="$node/xs:sequence | $node/xs:choice | $node/xs:all">
+ <xsl:call-template name="child-element-accessors">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text>private:&endl;</xsl:text>
+
+ <xsl:if test="$hasText">
+ <xsl:text> QString m_text;&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:text> void clear(bool clear_all = true);&endl;&endl;</xsl:text>
+
+ <xsl:text> // attribute data&endl;</xsl:text>
+ <xsl:for-each select="$node/xs:attribute">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cpp-type">
+ <xsl:call-template name="xs-type-to-cpp-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$cpp-type"/>
+ <xsl:text> m_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ <xsl:text> bool m_has_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>;&endl;&endl;</xsl:text>
+ </xsl:for-each>
+
+ <xsl:text> // child element data&endl;</xsl:text>
+ <xsl:if test="boolean($node/xs:choice)">
+ <xsl:text> Kind m_kind;&endl;</xsl:text>
+ </xsl:if>
+ <xsl:if test="not($node/xs:choice)">
+ <!-- TODO: if there are no elements with maxOccurs='1', m_children is never used-->
+ <xsl:text> uint m_children;&endl;</xsl:text>
+ </xsl:if>
+ <xsl:for-each select="$node/xs:sequence | $node/xs:choice | $node/xs:all">
+ <xsl:call-template name="child-element-data">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text>&endl;</xsl:text>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>(const </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text> &amp;other);&endl;</xsl:text>
+ <xsl:text> void operator = (const </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>&amp;other);&endl;</xsl:text>
+
+ <xsl:text>};&endl;&endl;</xsl:text>
+ </xsl:template>
+
+<!-- Root -->
+
+ <xsl:template match="xs:schema">
+
+<xsl:text>/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+// THIS FILE IS AUTOMATICALLY GENERATED
+
+#ifndef UI4_H
+#define UI4_H
+
+#include &lt;QtCore/QList&gt;
+#include &lt;QtCore/QString&gt;
+#include &lt;QtCore/QStringList&gt;
+#include &lt;QtCore/QXmlStreamReader&gt;
+#include &lt;QtCore/QXmlStreamWriter&gt;
+#include &lt;QtCore/qglobal.h&gt;
+
+#if defined(QT_UIC3)
+ #define QUILOADER_QDOM_READ
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QUILOADER_QDOM_READ
+ class QDomElement;
+#endif
+
+
+#define QDESIGNER_UILIB_EXTERN Q_DECL_EXPORT
+#define QDESIGNER_UILIB_IMPORT Q_DECL_IMPORT
+
+#if defined(QT_DESIGNER_STATIC) || defined(QT_UIC) || defined(QT_UIC3)
+# define QDESIGNER_UILIB_EXPORT
+#elif defined(QDESIGNER_UILIB_LIBRARY)
+# define QDESIGNER_UILIB_EXPORT QDESIGNER_UILIB_EXTERN
+#else
+# define QDESIGNER_UILIB_EXPORT QDESIGNER_UILIB_IMPORT
+#endif
+
+#ifndef QDESIGNER_UILIB_EXPORT
+# define QDESIGNER_UILIB_EXPORT
+#endif
+
+#ifdef QFORMINTERNAL_NAMESPACE
+namespace QFormInternal
+{
+#endif
+
+</xsl:text>
+
+ <xsl:text>&endl;</xsl:text>
+ <xsl:text>/*******************************************************************************&endl;</xsl:text>
+ <xsl:text>** Forward declarations&endl;</xsl:text>
+ <xsl:text>*/&endl;&endl;</xsl:text>
+
+ <xsl:for-each select="xs:complexType">
+ <xsl:call-template name="class-forward-declaration">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text>&endl;</xsl:text>
+ <xsl:text>/*******************************************************************************&endl;</xsl:text>
+ <xsl:text>** Declarations&endl;</xsl:text>
+ <xsl:text>*/&endl;&endl;</xsl:text>
+
+ <xsl:for-each select="xs:complexType">
+ <xsl:call-template name="class-declaration">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+ <xsl:text>
+#ifdef QFORMINTERNAL_NAMESPACE
+}
+#endif
+
+QT_END_NAMESPACE
+
+#endif // UI4_H
+</xsl:text>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/src/designer/data/generate_impl.xsl b/src/designer/data/generate_impl.xsl
new file mode 100644
index 000000000..a22862e0c
--- /dev/null
+++ b/src/designer/data/generate_impl.xsl
@@ -0,0 +1,1161 @@
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY endl "&#10;">
+]>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xsl:output method="text"/>
+
+ <xsl:include href="generate_shared.xsl"/>
+
+<!-- Implementation: constructor -->
+
+ <xsl:template name="ctor-init-attributes">
+ <xsl:param name="node"/>
+ <xsl:for-each select="$node/xs:attribute">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text> m_has_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = false;&endl;</xsl:text>
+ <xsl:choose>
+ <xsl:when test="@type = 'xs:integer'">
+ <xsl:text> m_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = 0;&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@type = 'xs:double'">
+ <xsl:text> m_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = 0.0;&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@type = 'xs:float'">
+ <xsl:text> m_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = 0.0;&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@type = 'xs:boolean'">
+ <xsl:text> m_attr_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = false;&endl;</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="ctor-init-child-elements">
+ <xsl:param name="node"/>
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="array" select="@maxOccurs='unbounded'"/>
+ <xsl:if test="not($array)">
+ <xsl:variable name="cpp-type">
+ <xsl:call-template name="xs-type-to-cpp-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="$array"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="@type = 'xs:integer'">
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = 0;&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@type = 'xs:float'">
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = 0.0;&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@type = 'xs:boolean'">
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = false;&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@type = 'xs:string'"></xsl:when>
+ <xsl:otherwise>
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = 0;&endl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="ctor-init-members">
+ <xsl:param name="node"/>
+
+ <xsl:if test="boolean($node/xs:choice)">
+ <xsl:text> m_kind = Unknown;&endl;&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:if test="not($node/xs:choice)">
+ <xsl:text> m_children = 0;&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:call-template name="ctor-init-attributes">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+
+ <xsl:if test="$node[@mixed='true']">
+ <xsl:text> m_text = QLatin1String("");&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:for-each select="$node//xs:sequence | $node//xs:choice | $node//xs:all">
+ <xsl:call-template name="ctor-init-child-elements">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="ctor-impl">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+
+ <xsl:value-of select="$name"/>
+ <xsl:text>::</xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>()&endl;</xsl:text>
+ <xsl:text>{&endl;</xsl:text>
+ <xsl:call-template name="ctor-init-members">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+ <xsl:text>}&endl;&endl;</xsl:text>
+ </xsl:template>
+
+<!-- Implementation: destructor -->
+
+ <xsl:template name="dtor-delete-members">
+ <xsl:param name="node"/>
+
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="xs-type-cat">
+ <xsl:call-template name="xs-type-category">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="@maxOccurs='unbounded'">
+ <xsl:if test="$xs-type-cat = 'pointer'">
+ <xsl:text> qDeleteAll(m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:if>
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>.clear();&endl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="$xs-type-cat = 'pointer'">
+ <xsl:text> delete m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="dtor-impl">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+
+ <xsl:value-of select="$name"/>
+ <xsl:text>::~</xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>()&endl;</xsl:text>
+ <xsl:text>{&endl;</xsl:text>
+
+ <xsl:for-each select="$node//xs:sequence | $node//xs:choice | $node//xs:all">
+ <xsl:call-template name="dtor-delete-members">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text>}&endl;&endl;</xsl:text>
+ </xsl:template>
+
+<!-- Implementation: clear() -->
+
+ <xsl:template name="clear-impl">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+
+ <xsl:text>void </xsl:text><xsl:value-of select="$name"/>
+ <xsl:text>::clear(bool clear_all)&endl;</xsl:text>
+ <xsl:text>{&endl;</xsl:text>
+
+ <xsl:for-each select="$node//xs:sequence | $node//xs:choice | $node//xs:all">
+ <xsl:call-template name="dtor-delete-members">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text>&endl; if (clear_all) {&endl;</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="$node[@mixed='true']">
+ <xsl:text> m_text = QLatin1String("");&endl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> m_text.clear();&endl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:call-template name="ctor-init-attributes">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ <xsl:text> }&endl;&endl;</xsl:text>
+
+ <xsl:if test="boolean($node/xs:choice)">
+ <xsl:text> m_kind = Unknown;&endl;&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:if test="not($node/xs:choice)">
+ <xsl:text> m_children = 0;&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:for-each select="$node//xs:sequence | $node//xs:choice | $node//xs:all">
+ <xsl:call-template name="ctor-init-child-elements">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text>}&endl;&endl;</xsl:text>
+
+ </xsl:template>
+
+ <!-- Format a string constant as QString(QLatin1Char('X')) or QLatin1String("foo"), respectively -->
+ <xsl:template name="string-constant">
+ <xsl:param name="literal"/>
+ <xsl:choose>
+ <xsl:when test="string-length($literal) &lt; 2">
+ <xsl:text>QString(QLatin1Char('</xsl:text>
+ <xsl:value-of select="$literal"/>
+ <xsl:text>'))</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>QLatin1String("</xsl:text>
+ <xsl:value-of select="$literal"/>
+ <xsl:text>")</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+<!-- Implementation: read(QXmlStreamReader) -->
+
+ <xsl:template name="read-impl-load-attributes">
+ <xsl:param name="node"/>
+
+ <xsl:if test="$node/xs:attribute">
+ <xsl:text>&endl;</xsl:text>
+ <xsl:text> foreach (const QXmlStreamAttribute &amp;attribute, reader.attributes()) {&endl;</xsl:text>
+ <xsl:text> QStringRef name = attribute.name();&endl;</xsl:text>
+
+ <xsl:for-each select="$node/xs:attribute">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-from-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val">
+ <xsl:text>attribute.value().toString()</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> if (name == </xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="@name"/>
+ </xsl:call-template>
+ <xsl:text>) {&endl;</xsl:text>
+ <xsl:text> setAttribute</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ <xsl:text> continue;&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ </xsl:for-each>
+
+ <xsl:text> reader.raiseError(QLatin1String("Unexpected attribute ") + name.toString());&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="read-impl-load-child-element">
+ <xsl:param name="node"/>
+
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="xs-type-cat">
+ <xsl:call-template name="xs-type-category">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="lower-name">
+ <xsl:call-template name="lower-text">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="array" select="@maxOccurs = 'unbounded'"/>
+
+ <xsl:text> if (tag == </xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$lower-name"/>
+ </xsl:call-template>
+ <xsl:text>) {&endl;</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="not($array) and $xs-type-cat = 'value'">
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-from-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val" select="'reader.readElementText()'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> setElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@maxOccurs='unbounded' and $xs-type-cat = 'value'">
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-from-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val" select="'reader.readElementText()'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>.append(</xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="not(@maxOccurs='unbounded') and $xs-type-cat = 'pointer'">
+ <xsl:text> Dom</xsl:text>
+ <xsl:value-of select="@type"/>
+ <xsl:text> *v = new Dom</xsl:text>
+ <xsl:value-of select="@type"/>
+ <xsl:text>();&endl;</xsl:text>
+ <xsl:text> v->read(reader);&endl;</xsl:text>
+ <xsl:text> setElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(v);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@maxOccurs='unbounded' and $xs-type-cat = 'pointer'">
+ <xsl:text> Dom</xsl:text>
+ <xsl:value-of select="@type"/>
+ <xsl:text> *v = new Dom</xsl:text>
+ <xsl:value-of select="@type"/>
+ <xsl:text>();&endl;</xsl:text>
+ <xsl:text> v->read(reader);&endl;</xsl:text>
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>.append(v);&endl;</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:text> continue;&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="read-impl">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+
+ <xsl:text>void </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>::read(QXmlStreamReader &amp;reader)&endl;</xsl:text>
+
+ <xsl:text>{&endl;</xsl:text>
+
+ <xsl:call-template name="read-impl-load-attributes">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:text>&endl;</xsl:text>
+
+ <xsl:text> for (bool finished = false; !finished &amp;&amp; !reader.hasError();) {&endl;</xsl:text>
+ <xsl:text> switch (reader.readNext()) {&endl;</xsl:text>
+ <xsl:text> case QXmlStreamReader::StartElement : {&endl;</xsl:text>
+ <xsl:text> const QString tag = reader.name().toString().toLower();&endl;</xsl:text>
+
+ <xsl:for-each select="$node//xs:sequence | $node//xs:choice | $node//xs:all">
+ <xsl:call-template name="read-impl-load-child-element">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text> reader.raiseError(QLatin1String("Unexpected element ") + tag);&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ <xsl:text> break;&endl;</xsl:text>
+ <xsl:text> case QXmlStreamReader::EndElement :&endl;</xsl:text>
+ <xsl:text> finished = true;&endl;</xsl:text>
+ <xsl:text> break;&endl;</xsl:text>
+ <xsl:text> case QXmlStreamReader::Characters :&endl;</xsl:text>
+ <xsl:text> if (!reader.isWhitespace())&endl;</xsl:text>
+ <xsl:text> m_text.append(reader.text().toString());&endl;</xsl:text>
+ <xsl:text> break;&endl;</xsl:text>
+ <xsl:text> default :&endl;</xsl:text>
+ <xsl:text> break;&endl;</xsl:text>
+
+ <xsl:text> }&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ <xsl:text>}&endl;&endl;</xsl:text>
+ </xsl:template>
+
+<!-- Implementation: read(QDomElement) -->
+
+ <xsl:template name="read-impl-qdom-load-attributes">
+ <xsl:param name="node"/>
+
+ <xsl:if test="$node/xs:attribute">
+ <xsl:text>&endl;</xsl:text>
+
+ <xsl:for-each select="$node/xs:attribute">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-from-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val">
+ <xsl:text>node.attribute(</xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="@name"/>
+ </xsl:call-template>
+ <xsl:text>)</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> if (node.hasAttribute(</xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="@name"/>
+ </xsl:call-template>
+ <xsl:text>))&endl;</xsl:text>
+ <xsl:text> setAttribute</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="read-impl-qdom-load-child-element">
+ <xsl:param name="node"/>
+
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="xs-type-cat">
+ <xsl:call-template name="xs-type-category">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="lower-name">
+ <xsl:call-template name="lower-text">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="array" select="@maxOccurs = 'unbounded'"/>
+
+ <xsl:text> if (tag == </xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$lower-name"/>
+ </xsl:call-template>
+ <xsl:text>) {&endl;</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="not($array) and $xs-type-cat = 'value'">
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-from-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val" select="'e.text()'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> setElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@maxOccurs='unbounded' and $xs-type-cat = 'value'">
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-from-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val" select="'e.text()'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>.append(</xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="not(@maxOccurs='unbounded') and $xs-type-cat = 'pointer'">
+ <xsl:text> Dom</xsl:text>
+ <xsl:value-of select="@type"/>
+ <xsl:text> *v = new Dom</xsl:text>
+ <xsl:value-of select="@type"/>
+ <xsl:text>();&endl;</xsl:text>
+ <xsl:text> v->read(e);&endl;</xsl:text>
+ <xsl:text> setElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(v);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="@maxOccurs='unbounded' and $xs-type-cat = 'pointer'">
+ <xsl:text> Dom</xsl:text>
+ <xsl:value-of select="@type"/>
+ <xsl:text> *v = new Dom</xsl:text>
+ <xsl:value-of select="@type"/>
+ <xsl:text>();&endl;</xsl:text>
+ <xsl:text> v->read(e);&endl;</xsl:text>
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>.append(v);&endl;</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:text> continue;&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="read-impl-qdom">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+
+ <xsl:text>#ifdef QUILOADER_QDOM_READ&endl;</xsl:text>
+
+ <xsl:text>void </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>::read(const QDomElement &amp;node)&endl;</xsl:text>
+
+ <xsl:text>{</xsl:text>
+
+ <xsl:call-template name="read-impl-qdom-load-attributes">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:text>&endl;</xsl:text>
+
+ <xsl:text> for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {&endl;</xsl:text>
+ <xsl:text> if (!n.isElement())&endl;</xsl:text>
+ <xsl:text> continue;&endl;</xsl:text>
+ <xsl:text> QDomElement e = n.toElement();&endl;</xsl:text>
+ <xsl:text> QString tag = e.tagName().toLower();&endl;</xsl:text>
+
+ <xsl:for-each select="$node//xs:sequence | $node//xs:choice | $node//xs:all">
+ <xsl:call-template name="read-impl-qdom-load-child-element">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text> }&endl;</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="$node[@mixed='true']">
+ <xsl:text> m_text = QLatin1String("");&endl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> m_text.clear();&endl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:text> for (QDomNode child = node.firstChild(); !child.isNull(); child = child.nextSibling()) {&endl;</xsl:text>
+ <xsl:text> if (child.isText())&endl;</xsl:text>
+ <xsl:text> m_text.append(child.nodeValue());&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+
+ <xsl:text>}&endl;</xsl:text>
+ <xsl:text>#endif&endl;</xsl:text>
+ <xsl:text>&endl;</xsl:text>
+ </xsl:template>
+<!-- Implementation: write() -->
+
+ <xsl:template name="write-impl-save-attributes">
+ <xsl:param name="node"/>
+
+ <xsl:for-each select="$node/xs:attribute">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="lower-name">
+ <xsl:call-template name="lower-text">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> if (hasAttribute</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>())&endl;</xsl:text>
+ <xsl:text> writer.writeAttribute(</xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$lower-name"/>
+ </xsl:call-template>
+
+ <xsl:text>, </xsl:text>
+
+ <xsl:call-template name="xs-type-to-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val" select="concat('attribute', $cap-name, '()')"/>
+ </xsl:call-template>
+
+ <xsl:text>);&endl;&endl;</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="write-impl-save-choice-child-element">
+ <xsl:param name="node"/>
+ <xsl:variable name="have-kind" select="name($node) = 'xs:choice'"/>
+
+ <xsl:text> switch (kind()) {&endl;</xsl:text>
+
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="lower-name">
+ <xsl:call-template name="lower-text">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="xs-type-cat">
+ <xsl:call-template name="xs-type-category">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> case </xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>: {&endl;</xsl:text>
+ <xsl:choose>
+ <xsl:when test="$xs-type-cat = 'value'">
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-to-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val" select="concat('element', $cap-name, '()')"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> writer.writeTextElement(</xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$camel-case-name"/>
+ </xsl:call-template>
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type-cat = 'pointer'">
+ <xsl:variable name="cpp-return-type">
+ <xsl:call-template name="xs-type-to-cpp-return-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$cpp-return-type"/>
+ <xsl:text> v = element</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>();&endl;</xsl:text>
+ <xsl:text> if (v != 0) {&endl;</xsl:text>
+ <xsl:text> v->write(writer, </xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$lower-name"/>
+ </xsl:call-template>
+ <xsl:text>);&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:text> break;&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ </xsl:for-each>
+
+ <xsl:text> default:&endl;</xsl:text>
+ <xsl:text> break;&endl;</xsl:text>
+ <xsl:text> }&endl;</xsl:text>
+ </xsl:template>
+
+ <xsl:template name="write-impl-save-sequence-child-element">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="lower-name">
+ <xsl:call-template name="lower-text">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="xs-type-cat">
+ <xsl:call-template name="xs-type-category">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cpp-return-type">
+ <xsl:call-template name="xs-type-to-cpp-return-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="@maxOccurs='unbounded'">
+ <xsl:text> for (int i = 0; i &lt; m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>.size(); ++i) {&endl;</xsl:text>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$cpp-return-type"/>
+ <xsl:text> v = m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>[i];&endl;</xsl:text>
+ <xsl:choose>
+ <xsl:when test="$xs-type-cat = 'pointer'">
+ <xsl:text> v->write(writer, </xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$lower-name"/>
+ </xsl:call-template>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-to-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val" select="'v'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text> writer.writeTextElement(</xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$lower-name"/>
+ </xsl:call-template>
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> }&endl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> if (m_children &amp; </xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>) {&endl;</xsl:text>
+ <xsl:choose>
+ <xsl:when test="$xs-type-cat = 'pointer'">
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>->write(writer, </xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$lower-name"/>
+ </xsl:call-template>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="qstring-func">
+ <xsl:call-template name="xs-type-to-qstring-func">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="val" select="concat('m_', $camel-case-name)"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text> writer.writeTextElement(</xsl:text>
+ <xsl:call-template name="string-constant">
+ <xsl:with-param name="literal" select="$lower-name"/>
+ </xsl:call-template>
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="$qstring-func"/>
+ <xsl:text>);&endl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> }&endl;&endl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="write-impl">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+ <xsl:variable name="lower-name">
+ <xsl:call-template name="lower-text">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text>void </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>::write(QXmlStreamWriter &amp;writer, const QString &amp;tagName) const&endl;</xsl:text>
+ <xsl:text>{&endl;</xsl:text>
+
+ <xsl:text> writer.writeStartElement(tagName.isEmpty() ? QString::fromUtf8("</xsl:text>
+ <xsl:value-of select="$lower-name"/>
+ <xsl:text>") : tagName.toLower());&endl;&endl;</xsl:text>
+
+ <xsl:call-template name="write-impl-save-attributes">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:for-each select="$node//xs:choice">
+ <xsl:call-template name="write-impl-save-choice-child-element">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:for-each select="$node//xs:sequence | $node//xs:all">
+ <xsl:call-template name="write-impl-save-sequence-child-element">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:text> if (!m_text.isEmpty())&endl;</xsl:text>
+ <xsl:text> writer.writeCharacters(m_text);&endl;&endl;</xsl:text>
+
+ <xsl:text> writer.writeEndElement();&endl;</xsl:text>
+ <xsl:text>}&endl;&endl;</xsl:text>
+ </xsl:template>
+
+<!-- Implementation: child element setters -->
+
+ <xsl:template name="child-setter-impl-helper">
+ <xsl:param name="node"/>
+ <xsl:param name="name"/>
+ <xsl:variable name="make-kind-enum" select="name($node)='xs:choice'"/>
+ <xsl:variable name="isChoice" select="name($node)='xs:choice'"/>
+
+ <xsl:for-each select="$node/xs:element">
+ <xsl:variable name="array" select="@maxOccurs = 'unbounded'"/>
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="return-cpp-type">
+ <xsl:call-template name="xs-type-to-cpp-return-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="$array"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="argument-cpp-type">
+ <xsl:call-template name="xs-type-to-cpp-argument-type">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="$array"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="xs-type-cat">
+ <xsl:call-template name="xs-type-category">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="$array"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:if test="$xs-type-cat = 'pointer'">
+ <xsl:value-of select="$return-cpp-type"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>::takeElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>() &endl;{&endl;</xsl:text>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$return-cpp-type"/>
+ <xsl:text> a = m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = 0;&endl;</xsl:text>
+ <xsl:if test="not($isChoice)">
+ <xsl:text> m_children ^= </xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ </xsl:if>
+ <xsl:text> return a;&endl;</xsl:text>
+ <xsl:text>}&endl;&endl;</xsl:text>
+ </xsl:if>
+
+ <xsl:text>void </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>::setElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$argument-cpp-type"/>
+ <xsl:text> a)&endl;</xsl:text>
+ <xsl:text>{&endl;</xsl:text>
+ <xsl:choose>
+ <xsl:when test="$make-kind-enum">
+ <xsl:text> clear(false);&endl;</xsl:text>
+ <xsl:text> m_kind = </xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type-cat = 'pointer'">
+ <xsl:text> delete </xsl:text>
+ <xsl:text>m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:if test="not($isChoice)">
+ <xsl:text> m_children |= </xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ </xsl:if>
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = a;&endl;</xsl:text>
+ <xsl:text>}&endl;&endl;</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="child-setter-impl">
+ <xsl:param name="node"/>
+ <xsl:variable name="name" select="concat('Dom', $node/@name)"/>
+
+ <xsl:for-each select="$node/xs:sequence | $node/xs:choice | $node/xs:all">
+ <xsl:call-template name="child-setter-impl-helper">
+ <xsl:with-param name="node" select="."/>
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="child-clear-impl">
+ <xsl:param name="node"/>
+
+ <xsl:variable name="name" select="concat('Dom', @name)"/>
+ <xsl:for-each select="$node/xs:sequence | $node/xs:choice | $node/xs:all">
+ <xsl:variable name="isChoice" select="name()='xs:choice'"/>
+ <xsl:variable name="make-child-enum" select="boolean(xs:sequence) and not(@maxOccurs='unbounded')"/>
+
+ <xsl:for-each select="xs:element">
+ <xsl:if test="not($isChoice) and not(@maxOccurs='unbounded')">
+ <xsl:variable name="camel-case-name">
+ <xsl:call-template name="camel-case">
+ <xsl:with-param name="text" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="cap-name">
+ <xsl:call-template name="cap-first-char">
+ <xsl:with-param name="text" select="$camel-case-name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="xs-type-cat">
+ <xsl:call-template name="xs-type-category">
+ <xsl:with-param name="xs-type" select="@type"/>
+ <xsl:with-param name="array" select="@maxOccurs='unbounded'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:text>void </xsl:text>
+ <xsl:value-of select="$name"/>
+ <xsl:text>::clearElement</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>()&endl;</xsl:text>
+ <xsl:text>{&endl;</xsl:text>
+ <xsl:if test="$xs-type-cat = 'pointer'">
+ <xsl:text> delete m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ <xsl:text> m_</xsl:text>
+ <xsl:value-of select="$camel-case-name"/>
+ <xsl:text> = 0;&endl;</xsl:text>
+ </xsl:if>
+ <xsl:text> m_children &amp;= ~</xsl:text>
+ <xsl:value-of select="$cap-name"/>
+ <xsl:text>;&endl;</xsl:text>
+ <xsl:text>}&endl;&endl;</xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:for-each>
+ </xsl:template>
+
+
+<!-- Implementation -->
+
+ <xsl:template name="class-implementation">
+ <xsl:param name="node"/>
+
+ <xsl:call-template name="clear-impl">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="ctor-impl">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="dtor-impl">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="read-impl">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="read-impl-qdom">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="write-impl">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="child-setter-impl">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="child-clear-impl">
+ <xsl:with-param name="node" select="$node"/>
+ </xsl:call-template>
+
+ </xsl:template>
+
+<!-- Root -->
+
+ <xsl:template match="xs:schema">
+
+<xsl:text>/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+</xsl:text>
+ <xsl:text>#include "ui4_p.h"&endl;</xsl:text>
+ <xsl:text>&endl;</xsl:text>
+ <xsl:text>#ifdef QUILOADER_QDOM_READ&endl;</xsl:text>
+ <xsl:text>#include &lt;QtXml/QDomElement&gt;&endl;</xsl:text>
+ <xsl:text>#endif&endl;</xsl:text>
+ <xsl:text>&endl;</xsl:text>
+ <xsl:text>QT_BEGIN_NAMESPACE&endl;</xsl:text>
+
+ <xsl:text>#ifdef QFORMINTERNAL_NAMESPACE&endl;</xsl:text>
+ <xsl:text>using namespace QFormInternal;&endl;</xsl:text>
+ <xsl:text>#endif&endl;</xsl:text>
+ <xsl:text>&endl;</xsl:text>
+
+ <xsl:text>/*******************************************************************************&endl;</xsl:text>
+ <xsl:text>** Implementations&endl;</xsl:text>
+ <xsl:text>*/&endl;&endl;</xsl:text>
+
+ <xsl:for-each select="xs:complexType">
+ <xsl:call-template name="class-implementation">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+ <xsl:text>QT_END_NAMESPACE&endl;</xsl:text>
+
+ <xsl:text>&endl;</xsl:text>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/designer/data/generate_shared.xsl b/src/designer/data/generate_shared.xsl
new file mode 100644
index 000000000..ec95fe2b8
--- /dev/null
+++ b/src/designer/data/generate_shared.xsl
@@ -0,0 +1,331 @@
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY endl "&#10;">
+]>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<!-- Hack to make names camel case
+ All names in UI files are lowercase, while the element names are
+ capital case. To make the UI files conforming to the XSD file + keep
+ the DOM interface we rename them here -->
+ <xsl:template name="camel-case">
+ <xsl:param name="text"/>
+ <xsl:choose>
+ <xsl:when test="$text='exportmacro'">exportMacro</xsl:when>
+ <xsl:when test="$text='layoutdefault'">layoutDefault</xsl:when>
+ <xsl:when test="$text='layoutfunction'">layoutFunction</xsl:when>
+ <xsl:when test="$text='pixmapfunction'">pixmapFunction</xsl:when>
+ <xsl:when test="$text='customwidgets'">customWidgets</xsl:when>
+ <xsl:when test="$text='tabstops'">tabStops</xsl:when>
+ <xsl:when test="$text='tabstop'">tabStop</xsl:when>
+ <xsl:when test="$text='buttongroups'">buttonGroups</xsl:when>
+ <xsl:when test="$text='exportmacro'">exportMacro</xsl:when>
+ <xsl:when test="$text='actiongroup'">actionGroup</xsl:when>
+ <xsl:when test="$text='buttongroup'">buttonGroup</xsl:when>
+ <xsl:when test="$text='customwidget'">customWidget</xsl:when>
+ <xsl:when test="$text='sizehint'">sizeHint</xsl:when>
+ <xsl:when test="$text='addpagemethod'">addPageMethod</xsl:when>
+ <xsl:when test="$text='sizepolicy'">sizePolicy</xsl:when>
+ <xsl:when test="$text='hordata'">horData</xsl:when>
+ <xsl:when test="$text='verdata'">verData</xsl:when>
+ <xsl:when test="$text='rowspan'">rowSpan</xsl:when>
+ <xsl:when test="$text='colspan'">colSpan</xsl:when>
+ <xsl:when test="$text='addaction'">addAction</xsl:when>
+ <xsl:when test="$text='zorder'">zOrder</xsl:when>
+ <xsl:when test="$text='startx'">startX</xsl:when>
+ <xsl:when test="$text='starty'">startY</xsl:when>
+ <xsl:when test="$text='endx'">endX</xsl:when>
+ <xsl:when test="$text='endy'">endY</xsl:when>
+ <xsl:when test="$text='centralx'">centralX</xsl:when>
+ <xsl:when test="$text='centraly'">centralY</xsl:when>
+ <xsl:when test="$text='focalx'">focalX</xsl:when>
+ <xsl:when test="$text='focaly'">focalY</xsl:when>
+ <xsl:when test="$text='widgetdata'">widgetData</xsl:when>
+ <xsl:when test="$text='coordinatemode'">coordinateMode</xsl:when>
+ <xsl:when test="$text='brushstyle'">brushStyle</xsl:when>
+ <xsl:when test="$text='colorrole'">colorRole</xsl:when>
+ <xsl:when test="$text='pointsize'">pointSize</xsl:when>
+ <xsl:when test="$text='strikeout'">strikeOut</xsl:when>
+ <xsl:when test="$text='stylestrategy'">styleStrategy</xsl:when>
+ <xsl:when test="$text='hsizetype'">hSizeType</xsl:when>
+ <xsl:when test="$text='vsizetype'">vSizeType</xsl:when>
+ <xsl:when test="$text='horstretch'">horStretch</xsl:when>
+ <xsl:when test="$text='verstretch'">verStretch</xsl:when>
+ <xsl:when test="$text='normaloff'">normalOff</xsl:when>
+ <xsl:when test="$text='normalon'">normalOn</xsl:when>
+ <xsl:when test="$text='disabledoff'">disabledOff</xsl:when>
+ <xsl:when test="$text='disabledon'">disabledOn</xsl:when>
+ <xsl:when test="$text='activeoff'">activeOff</xsl:when>
+ <xsl:when test="$text='activeon'">activeOn</xsl:when>
+ <xsl:when test="$text='selectedoff'">selectedOff</xsl:when>
+ <xsl:when test="$text='selectedon'">selectedOn</xsl:when>
+ <xsl:when test="$text='cursorshape'">cursorShape</xsl:when>
+ <xsl:when test="$text='iconset'">iconSet</xsl:when>
+ <xsl:when test="$text='stringlist'">stringList</xsl:when>
+ <xsl:when test="$text='datetime'">dateTime</xsl:when>
+ <xsl:when test="$text='pointf'">pointF</xsl:when>
+ <xsl:when test="$text='rectf'">rectF</xsl:when>
+ <xsl:when test="$text='sizef'">sizeF</xsl:when>
+ <xsl:when test="$text='longlong'">longLong</xsl:when>
+ <xsl:when test="$text='uint'">UInt</xsl:when>
+ <xsl:when test="$text='ulonglong'">uLongLong</xsl:when>
+ <xsl:when test="$text='rowstretch'">rowStretch</xsl:when>
+ <xsl:when test="$text='columnstretch'">columnStretch</xsl:when>
+ <xsl:when test="$text='rowminimumheight'">rowMinimumHeight</xsl:when>
+ <xsl:when test="$text='columnminimumwidth'">columnMinimumWidth</xsl:when>
+ <xsl:when test="$text='extracomment'">extraComment</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$text"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+
+<!-- Convenience templates -->
+
+ <xsl:template name="cap-first-char">
+ <xsl:param name="text"/>
+ <xsl:value-of select="concat(translate(substring($text, 1, 1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), substring($text, 2))" />
+ </xsl:template>
+
+ <xsl:template name="lower-text">
+ <xsl:param name="text"/>
+
+ <xsl:if test="boolean($text)">
+ <xsl:variable name="head" select="substring($text, 1, 1)"/>
+ <xsl:variable name="tail" select="substring($text, 2)"/>
+ <xsl:variable name="lower-head" select="translate($text, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
+ <xsl:variable name="lower-tail">
+ <xsl:call-template name="lower-text">
+ <xsl:with-param name="text" select="tail"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select='concat($lower-head, $lower-tail)'/>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="powers-of-two">
+ <xsl:param name="num"/>
+
+ <xsl:choose>
+ <xsl:when test="$num=0">1</xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="x">
+ <xsl:call-template name="powers-of-two">
+ <xsl:with-param name="num" select="$num - 1"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="2*$x"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+<!-- Convenience templates: xs-types to c++ types conversions -->
+
+ <xsl:template name="xs-type-from-qstring-func">
+ <xsl:param name="xs-type"/>
+ <xsl:param name="val"/>
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">
+ <xsl:value-of select="$val"/>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">
+ <xsl:value-of select="$val"/>
+ <xsl:text>.toInt()</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:float'">
+ <xsl:value-of select="$val"/>
+ <xsl:text>.toFloat()</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:double'">
+ <xsl:value-of select="$val"/>
+ <xsl:text>.toDouble()</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$val"/>
+ <xsl:text> == QLatin1String("true") ? true : false)</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:long'">
+ <xsl:value-of select="$val"/>
+ <xsl:text>.toLongLong()</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">
+ <xsl:value-of select="$val"/>
+ <xsl:text>.toUInt()</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">
+ <xsl:value-of select="$val"/>
+ <xsl:text>.toULongLong()</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>### BZZZZT! ###</xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="xs-type-to-qstring-func">
+ <xsl:param name="xs-type"/>
+ <xsl:param name="val"/>
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">
+ <xsl:value-of select="$val"/>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">
+ <xsl:text>QString::number(</xsl:text>
+ <xsl:value-of select="$val"/>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:long'">
+ <xsl:text>QString::number(</xsl:text>
+ <xsl:value-of select="$val"/>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">
+ <xsl:text>QString::number(</xsl:text>
+ <xsl:value-of select="$val"/>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">
+ <xsl:text>QString::number(</xsl:text>
+ <xsl:value-of select="$val"/>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:float'">
+ <xsl:text>QString::number(</xsl:text>
+ <xsl:value-of select="$val"/>
+ <xsl:text>, 'f', 8)</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:double'">
+ <xsl:text>QString::number(</xsl:text>
+ <xsl:value-of select="$val"/>
+ <xsl:text>, 'f', 15)</xsl:text>
+ </xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$val"/>
+ <xsl:text> ? QLatin1String("true") : QLatin1String("false"))</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>### BZZZZT! ###</xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="xs-type-category">
+ <xsl:param name="xs-type"/>
+ <xsl:param name="array" select="false"/>
+ <xsl:choose>
+ <xsl:when test="$array">value</xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">value</xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">value</xsl:when>
+ <xsl:when test="$xs-type='xs:float'">value</xsl:when>
+ <xsl:when test="$xs-type='xs:double'">value</xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">value</xsl:when>
+ <xsl:when test="$xs-type='xs:long'">value</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">value</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">value</xsl:when>
+ <xsl:otherwise>pointer</xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="xs-type-to-cpp-type">
+ <xsl:param name="xs-type"/>
+ <xsl:param name="array" select="false"/>
+ <xsl:choose>
+ <xsl:when test="$array">
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">QStringList</xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">QList&lt;int&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:float'">QList&lt;float&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:double'">QList&lt;double&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">QList&lt;bool&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:long'">QList&lt;qlonglong&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">QList&lt;uint&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">QList&lt;qulonglong&gt;</xsl:when>
+ <xsl:otherwise>QList&lt;Dom<xsl:value-of select="$xs-type"/>*&gt;</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">QString</xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">int</xsl:when>
+ <xsl:when test="$xs-type='xs:float'">float</xsl:when>
+ <xsl:when test="$xs-type='xs:double'">double</xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">bool</xsl:when>
+ <xsl:when test="$xs-type='xs:long'">qlonglong</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">uint</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">qulonglong</xsl:when>
+ <xsl:otherwise>Dom<xsl:value-of select="$xs-type"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="xs-type-to-cpp-return-type">
+ <xsl:param name="xs-type"/>
+ <xsl:param name="array" select="false"/>
+ <xsl:choose>
+ <xsl:when test="$array">
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">QStringList</xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">QList&lt;int&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:float'">QList&lt;float&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:double'">QList&lt;double&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">QList&lt;bool&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:long'">QList&lt;qlonglong&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">QList&lt;uint&gt;</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">QList&lt;qulonglong&gt;</xsl:when>
+ <xsl:otherwise>QList&lt;Dom<xsl:value-of select="$xs-type"/>*&gt;</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">QString</xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">int</xsl:when>
+ <xsl:when test="$xs-type='xs:float'">float</xsl:when>
+ <xsl:when test="$xs-type='xs:double'">double</xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">bool</xsl:when>
+ <xsl:when test="$xs-type='xs:long'">qlonglong</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">uint</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">qulonglong</xsl:when>
+ <xsl:otherwise>Dom<xsl:value-of select="$xs-type"/>*</xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="xs-type-to-cpp-argument-type">
+ <xsl:param name="xs-type"/>
+ <xsl:param name="array" select="false"/>
+ <xsl:choose>
+ <xsl:when test="$array">
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">const QStringList&amp;</xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">const QList&lt;int&gt;&amp;</xsl:when>
+ <xsl:when test="$xs-type='xs:float'">const QList&lt;float&gt;&amp;</xsl:when>
+ <xsl:when test="$xs-type='xs:double'">const QList&lt;double&gt;&amp;</xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">const QList&lt;bool&gt;&amp;</xsl:when>
+ <xsl:when test="$xs-type='xs:long'">const QList&lt;qlonglong&gt;&amp;</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">const QList&lt;uint&gt;&amp;</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">const QList&lt;qulonglong&gt;&amp;</xsl:when>
+ <xsl:otherwise>const QList&lt;Dom<xsl:value-of select="$xs-type"/>*&gt;&amp;</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$xs-type='xs:string'">const QString&amp;</xsl:when>
+ <xsl:when test="$xs-type='xs:integer'">int</xsl:when>
+ <xsl:when test="$xs-type='xs:float'">float</xsl:when>
+ <xsl:when test="$xs-type='xs:double'">double</xsl:when>
+ <xsl:when test="$xs-type='xs:boolean'">bool</xsl:when>
+ <xsl:when test="$xs-type='xs:long'">qlonglong</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedInt'">uint</xsl:when>
+ <xsl:when test="$xs-type='xs:unsignedLong'">qulonglong</xsl:when>
+ <xsl:otherwise>Dom<xsl:value-of select="$xs-type"/>*</xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+
+</xsl:stylesheet>
diff --git a/src/designer/data/ui3.xsd b/src/designer/data/ui3.xsd
new file mode 100644
index 000000000..06f325ef3
--- /dev/null
+++ b/src/designer/data/ui3.xsd
@@ -0,0 +1,353 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:element name="UI">
+ <xs:complexType>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="actions">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="action">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="property" type="property" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="author" type="xs:string" />
+ <xs:element name="class" type="xs:string" />
+ <xs:element name="comment" type="xs:string" />
+ <xs:element name="connections">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="connection">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="sender" type="xs:string" />
+ <xs:element name="signal" type="xs:string" />
+ <xs:element name="receiver" type="xs:string" />
+ <xs:element name="slot" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="customWidgets" type="xs:string" />
+ <xs:element name="exportmacro" type="xs:string" />
+ <xs:element name="forwards">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="forward" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="images">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="image">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="data">
+ <xs:complexType>
+ <xs:sequence />
+ <xs:attribute name="format" type="xs:string" />
+ <xs:attribute name="length" type="xs:integer" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="includes">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="include">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="location" type="xs:string" />
+ <xs:attribute name="impldecl" type="xs:string" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="layoutDefaults">
+ <xs:complexType>
+ <xs:sequence />
+ <xs:attribute name="spacing" type="xs:integer" />
+ <xs:attribute name="margin" type="xs:integer" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="layoutFunctions">
+ <xs:complexType>
+ <xs:sequence />
+ <xs:attribute name="spacing" type="xs:string" />
+ <xs:attribute name="margin" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="menubar">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="property" type="property" />
+ <xs:element name="item">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="action">
+ <xs:complexType>
+ <xs:sequence />
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="item">
+ </xs:element>
+ <xs:element name="separator" type="xs:string" />
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="text" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ <xs:element name="class" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="pixmapfunction" type="xs:string" />
+ <xs:element name="signals">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="signal" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="slots">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="slot">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="access" type="xs:string" />
+ <xs:attribute name="specifier" type="xs:string" />
+ <xs:attribute name="language" type="xs:string" />
+ <xs:attribute name="returnType" type="xs:string" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="tabstops">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="tabstop" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="toolbars">
+ <xs:complexType>
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="toolbar">
+ <xs:complexType>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="property" type="property" />
+ <xs:element name="action">
+ <xs:complexType>
+ <xs:sequence />
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="separator" type="xs:string" />
+ </xs:choice>
+ <xs:attribute name="dock" type="xs:integer" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="variables">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="variable">
+ <xs:complexType>
+ <xs:sequence />
+ <xs:attribute name="access" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="widget" type="widget" />
+ <xs:element name="include" type="xs:string" />
+ <xs:element name="variable" type="xs:string" />
+ </xs:choice>
+ <xs:attribute name="version" type="xs:string" />
+ <xs:attribute name="stdsetdef" type="xs:integer" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:complexType name="layout">
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="property" type="property" />
+ <xs:element name="widget" type="widget" />
+ <xs:element name="spacer" type="spacer" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="widget">
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="class" type="xs:string" />
+ <xs:element name="property" type="property" />
+ <xs:element name="hbox" type="layout" />
+ <xs:element name="vbox" type="layout" />
+ <xs:element name="grid" type="layout" />
+ <xs:element name="widget" type="widget" />
+ </xs:choice>
+ <xs:attribute name="class" type="xs:string" />
+ <xs:attribute name="row" type="xs:integer" /> <!-- ### remove me -->
+ <xs:attribute name="column" type="xs:integer" /> <!-- ### remove me -->
+ </xs:complexType>
+
+ <xs:complexType name="spacer">
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="property" type="property" />
+ </xs:sequence>
+ <xs:attribute name="row" type="xs:integer" /> <!-- ### remove me -->
+ <xs:attribute name="column" type="xs:integer" /> <!-- ### remove me -->
+ <xs:attribute name="rowspan" type="xs:integer" /> <!-- ### remove me -->
+ <xs:attribute name="colspan" type="xs:integer" /> <!-- ### remove me -->
+ </xs:complexType>
+
+ <xs:complexType name="color">
+ <xs:sequence>
+ <xs:element name="red" type="xs:integer" />
+ <xs:element name="green" type="xs:integer" />
+ <xs:element name="blue" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="colorGroup">
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="color" type="color" />
+ <xs:element name="pixmap" type="xs:string" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="palette">
+ <xs:sequence>
+ <xs:element name="active" type="colorGroup" />
+ <xs:element name="inactive" type="colorGroup" />
+ <xs:element name="disabled" type="colorGroup" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="font">
+ <xs:sequence>
+ <xs:element name="family" type="xs:string" />
+ <xs:element name="pointSize" type="xs:integer" />
+ <xs:element name="weight" type="xs:integer" />
+ <xs:element name="italic" type="xs:boolean" />
+ <xs:element name="bold" type="xs:boolean" />
+ <xs:element name="underline" type="xs:boolean" />
+ <xs:element name="strikeout" type="xs:boolean" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="point">
+ <xs:sequence>
+ <xs:element name="x" type="xs:integer" />
+ <xs:element name="y" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="rect">
+ <xs:sequence>
+ <xs:element name="x" type="xs:integer" />
+ <xs:element name="y" type="xs:integer" />
+ <xs:element name="width" type="xs:integer" />
+ <xs:element name="height" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="sizePolicy">
+ <xs:sequence>
+ <xs:element name="hsizetype" type="xs:integer" />
+ <xs:element name="vsizetype" type="xs:integer" />
+ <xs:element name="horstretch" type="xs:integer" />
+ <xs:element name="verstretch" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="size">
+ <xs:sequence>
+ <xs:element name="width" type="xs:integer" />
+ <xs:element name="height" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="date">
+ <xs:sequence>
+ <xs:element name="year" type="xs:integer" />
+ <xs:element name="month" type="xs:integer" />
+ <xs:element name="day" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="time">
+ <xs:sequence>
+ <xs:element name="hour" type="xs:integer" />
+ <xs:element name="minute" type="xs:integer" />
+ <xs:element name="second" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="dateTime">
+ <xs:sequence>
+ <xs:element name="hour" type="xs:integer" />
+ <xs:element name="minute" type="xs:integer" />
+ <xs:element name="second" type="xs:integer" />
+ <xs:element name="year" type="xs:integer" />
+ <xs:element name="month" type="xs:integer" />
+ <xs:element name="day" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="property">
+ <xs:choice>
+ <xs:element name="bool" type="xs:boolean" />
+ <xs:element name="color" type="color" />
+ <xs:element name="cstring" type="xs:string" />
+ <xs:element name="cursor" type="xs:integer" />
+ <xs:element name="enum" type="xs:string" />
+ <xs:element name="font" type ="font" />
+ <xs:element name="iconset" type="xs:string" />
+ <xs:element name="palette" type="palette" />
+ <xs:element name="point" type="point" />
+ <xs:element name="rect" type="rect" />
+ <xs:element name="set" type="xs:string" />
+ <xs:element name="sizePolicy" type="sizePolicy" />
+ <xs:element name="size" type="size" />
+ <xs:element name="string" type="xs:string" />
+ <xs:element name="number" type="xs:integer" />
+ <xs:element name="date" type="date" />
+ <xs:element name="time" type="time" />
+ <xs:element name="dateTime" type="dateTime" />
+ </xs:choice>
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="stdset" type="xs:integer" />
+ </xs:complexType>
+
+</xs:schema> \ No newline at end of file
diff --git a/src/designer/data/ui4.xsd b/src/designer/data/ui4.xsd
new file mode 100644
index 000000000..53bae62e2
--- /dev/null
+++ b/src/designer/data/ui4.xsd
@@ -0,0 +1,589 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:element name="ui" type="UI"/>
+
+ <xs:complexType name="UI">
+ <xs:all>
+ <xs:element name="author" type="xs:string" minOccurs="0" />
+ <xs:element name="comment" type="xs:string" minOccurs="0" />
+ <xs:element name="exportmacro" type="xs:string" minOccurs="0" />
+ <xs:element name="class" type="xs:string" />
+ <xs:element name="widget" type="Widget" />
+ <xs:element name="layoutdefault" type="LayoutDefault" minOccurs="0" />
+ <xs:element name="layoutfunction" type="LayoutFunction" minOccurs="0" />
+ <xs:element name="pixmapfunction" type="xs:string" minOccurs="0" />
+ <xs:element name="customwidgets" type="CustomWidgets" minOccurs="0" />
+ <xs:element name="tabstops" type="TabStops" minOccurs="0" />
+ <xs:element name="images" type="Images" minOccurs="0" />
+ <xs:element name="includes" type="Includes" minOccurs="0" />
+ <xs:element name="resources" type="Resources" minOccurs="0" />
+ <xs:element name="connections" type="Connections" minOccurs="0" />
+ <xs:element name="designerdata" type="DesignerData" minOccurs="0" />
+ <xs:element name="slots" type="Slots" minOccurs="0" />
+ <xs:element name="buttongroups" type="ButtonGroups" minOccurs="0" />
+ </xs:all>
+ <xs:attribute name="version" type="xs:string" use="required" />
+ <xs:attribute name="language" type="xs:string" />
+ <xs:attribute name="displayname" type="xs:string" />
+<!-- Legacy attribute generated by uic3 -->
+ <xs:attribute name="stdsetdef" type="xs:integer" />
+<!-- Legacy attribute generated by the VS integration -->
+ <xs:attribute name="stdSetDef" type="xs:integer" />
+ </xs:complexType>
+
+<!-- include begin -->
+ <xs:complexType name="Includes">
+ <xs:sequence>
+ <xs:element name="include" type="Include" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Include" mixed="true" >
+ <xs:attribute name="location" type="xs:string" use="required" />
+ <xs:attribute name="impldecl" type="xs:string" />
+ </xs:complexType>
+<!-- include end -->
+
+<!-- resource begin -->
+ <xs:complexType name="Resources">
+ <xs:sequence>
+ <xs:element name="include" type="Resource" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="Resource">
+ <xs:attribute name="location" type="xs:string" use="required" />
+ </xs:complexType>
+<!-- resource end -->
+
+<!-- actions begin -->
+ <xs:complexType name="ActionGroup">
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="action" type="Action" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="actiongroup" type="ActionGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="attribute" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="Action">
+ <xs:sequence maxOccurs="unbounded" >
+ <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="attribute" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="menu" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="ActionRef">
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:complexType>
+<!-- actions end -->
+
+<!-- button groups begin -->
+ <xs:complexType name="ButtonGroup">
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="attribute" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="ButtonGroups">
+ <xs:sequence>
+ <xs:element name="buttongroup" type="ButtonGroup" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+<!-- button groups end -->
+
+<!-- images begin -->
+ <xs:complexType name="Images">
+ <xs:sequence>
+ <xs:element name="image" type="Image" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Image">
+ <xs:sequence>
+ <xs:element name="data" type="ImageData" />
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="ImageData" mixed="true" >
+ <xs:attribute name="format" type="xs:string" use="required" />
+ <xs:attribute name="length" type="xs:integer" use="required" />
+ </xs:complexType>
+<!-- images end -->
+
+<!-- custom widget support begin -->
+ <xs:complexType name="CustomWidgets">
+ <xs:sequence>
+ <xs:element name="customwidget" type="CustomWidget" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Header" mixed="true" >
+ <xs:attribute name="location" type="xs:string" /> <!-- local or global -->
+ </xs:complexType>
+
+ <xs:complexType name="CustomWidget">
+ <xs:all>
+ <xs:element name="class" type="xs:string" />
+ <xs:element name="extends" type="xs:string" />
+ <xs:element name="header" type="Header" />
+ <xs:element name="sizehint" type="Size" minOccurs="0" />
+ <xs:element name="addpagemethod" type="xs:string" minOccurs="0" />
+ <xs:element name="container" type="xs:integer" minOccurs="0" />
+ <xs:element name="sizepolicy" type="SizePolicyData" minOccurs="0" />
+ <xs:element name="pixmap" type="xs:string" minOccurs="0" />
+ <xs:element name="script" type="Script" minOccurs="0" />
+ <xs:element name="properties" type="Properties" minOccurs="0" />
+ <xs:element name="slots" type="Slots" minOccurs="0" />
+ <xs:element name="propertyspecifications" type="PropertySpecifications" minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="Properties">
+ <xs:sequence>
+ <xs:element name="property" type="PropertyData" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PropertyData">
+ <xs:attribute name="type" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="SizePolicyData">
+ <xs:all>
+ <xs:element name="hordata" type="xs:integer" />
+ <xs:element name="verdata" type="xs:integer" />
+ </xs:all>
+ </xs:complexType>
+
+<!-- custom widget support end -->
+
+ <xs:complexType name="LayoutDefault">
+ <xs:attribute name="spacing" type="xs:integer" use="required" />
+ <xs:attribute name="margin" type="xs:integer" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="LayoutFunction">
+ <xs:attribute name="spacing" type="xs:string" use="required" />
+ <xs:attribute name="margin" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="TabStops">
+ <xs:sequence>
+ <xs:element name="tabstop" type="xs:string" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Layout">
+ <xs:sequence maxOccurs="unbounded" >
+ <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="attribute" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="item" type="LayoutItem" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="class" type="xs:string" use="required" />
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="stretch" type="xs:string" />
+ <xs:attribute name="rowstretch" type="xs:string" />
+ <xs:attribute name="columnstretch" type="xs:string" />
+ <xs:attribute name="rowminimumheight" type="xs:string" />
+ <xs:attribute name="columnminimumwidth" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="LayoutItem">
+ <xs:choice>
+ <xs:element name="widget" type="Widget" />
+ <xs:element name="layout" type="Layout" />
+ <xs:element name="spacer" type="Spacer" />
+ </xs:choice>
+ <xs:attribute name="row" type="xs:integer" />
+ <xs:attribute name="column" type="xs:integer" />
+ <xs:attribute name="rowspan" type="xs:integer" />
+ <xs:attribute name="colspan" type="xs:integer" />
+ <xs:attribute name="alignment" type="xs:string" />
+ </xs:complexType>
+
+<!-- item view begin -->
+ <xs:complexType name="Row">
+ <xs:sequence>
+ <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Column">
+ <xs:sequence>
+ <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Item">
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="item" type="Item" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="row" type="xs:integer" />
+ <xs:attribute name="column" type="xs:integer" />
+ </xs:complexType>
+<!-- item view end -->
+
+ <xs:complexType name="Widget">
+ <!-- Order does not matter (cannot use xs:all here
+ because of unbounded row, column, item -->
+ <xs:sequence>
+ <xs:element name="class" type="xs:string" minOccurs="0" maxOccurs="unbounded" /> <!-- unbounded kept for compatibility reasons -->
+ <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="script" type="Script" minOccurs="0" maxOccurs="unbounded" /> <!-- unbounded kept for compatibility reasons -->
+ <xs:element name="widgetdata" type="WidgetData" minOccurs="0" maxOccurs="unbounded" /> <!-- unbounded kept for compatibility reasons -->
+ <xs:element name="attribute" type="Property" minOccurs="0" maxOccurs="unbounded" />
+<!-- item view begin -->
+ <xs:element name="row" type="Row" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="column" type="Column" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="item" type="Item" minOccurs="0" maxOccurs="unbounded" />
+<!-- item view end -->
+ <xs:element name="layout" type="Layout" minOccurs="0" maxOccurs="unbounded" /> <!-- unbounded kept for compatibility reasons -->
+ <xs:element name="widget" type="Widget" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="action" type="Action" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="actiongroup" type="ActionGroup" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="addaction" type="ActionRef" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="zorder" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="class" type="xs:string" use="required" />
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="native" type="xs:boolean" />
+ </xs:complexType>
+
+ <xs:complexType name="Spacer">
+ <xs:sequence>
+ <xs:element name="property" type="Property" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="Color">
+ <xs:all>
+ <xs:element name="red" type="xs:integer" />
+ <xs:element name="green" type="xs:integer" />
+ <xs:element name="blue" type="xs:integer" />
+ </xs:all>
+ <xs:attribute name="alpha" type="xs:integer" />
+ </xs:complexType>
+
+ <xs:complexType name="GradientStop">
+ <xs:sequence>
+ <xs:element name="color" type="Color" />
+ </xs:sequence>
+ <xs:attribute name="position" type="xs:double" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="Gradient">
+ <xs:sequence>
+ <xs:element name="gradientStop" type="GradientStop" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="startx" type="xs:double" use="required" />
+ <xs:attribute name="starty" type="xs:double" use="required" />
+ <xs:attribute name="endx" type="xs:double" use="required" />
+ <xs:attribute name="endy" type="xs:double" use="required" />
+ <xs:attribute name="centralx" type="xs:double" use="required" />
+ <xs:attribute name="centraly" type="xs:double" use="required" />
+ <xs:attribute name="focalx" type="xs:double" use="required" />
+ <xs:attribute name="focaly" type="xs:double" use="required" />
+ <xs:attribute name="radius" type="xs:double" use="required" />
+ <xs:attribute name="angle" type="xs:double" use="required" />
+ <xs:attribute name="type" type="xs:string" use="required" />
+ <xs:attribute name="spread" type="xs:string" use="required" />
+ <xs:attribute name="coordinatemode" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="Brush">
+ <xs:choice>
+ <xs:element name="color" type="Color" />
+ <xs:element name="texture" type="Property" />
+ <xs:element name="gradient" type="Gradient" />
+ </xs:choice>
+ <xs:attribute name="brushstyle" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="ColorRole">
+ <xs:sequence>
+ <xs:element name="brush" type="Brush" />
+ </xs:sequence>
+ <xs:attribute name="role" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="ColorGroup">
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="colorrole" type="ColorRole" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="color" type="Color" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Palette">
+ <xs:all>
+ <xs:element name="active" type="ColorGroup" />
+ <xs:element name="inactive" type="ColorGroup" />
+ <xs:element name="disabled" type="ColorGroup" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="Font">
+ <xs:all>
+ <xs:element name="family" type="xs:string" minOccurs="0" />
+ <xs:element name="pointsize" type="xs:integer" minOccurs="0" />
+ <xs:element name="weight" type="xs:integer" minOccurs="0" />
+ <xs:element name="italic" type="xs:boolean" minOccurs="0" />
+ <xs:element name="bold" type="xs:boolean" minOccurs="0" />
+ <xs:element name="underline" type="xs:boolean" minOccurs="0" />
+ <xs:element name="strikeout" type="xs:boolean" minOccurs="0" />
+ <xs:element name="antialiasing" type="xs:boolean" minOccurs="0" />
+ <xs:element name="stylestrategy" type="xs:string" minOccurs="0" />
+ <xs:element name="kerning" type="xs:boolean" minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="Point">
+ <xs:all>
+ <xs:element name="x" type="xs:integer" />
+ <xs:element name="y" type="xs:integer" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="Rect">
+ <xs:all>
+ <xs:element name="x" type="xs:integer" />
+ <xs:element name="y" type="xs:integer" />
+ <xs:element name="width" type="xs:integer" />
+ <xs:element name="height" type="xs:integer" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="Locale">
+ <xs:attribute name="language" type="xs:string" use="required" />
+ <xs:attribute name="country" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="SizePolicy">
+ <xs:all>
+ <xs:element name="hsizetype" type="xs:integer" minOccurs="0" />
+ <xs:element name="vsizetype" type="xs:integer" minOccurs="0" />
+ <xs:element name="horstretch" type="xs:integer" />
+ <xs:element name="verstretch" type="xs:integer" />
+ </xs:all>
+ <xs:attribute name="hsizetype" type="xs:string" />
+ <xs:attribute name="vsizetype" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="Size">
+ <xs:all>
+ <xs:element name="width" type="xs:integer" />
+ <xs:element name="height" type="xs:integer" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="Date">
+ <xs:all>
+ <xs:element name="year" type="xs:integer" />
+ <xs:element name="month" type="xs:integer" />
+ <xs:element name="day" type="xs:integer" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="Time">
+ <xs:all>
+ <xs:element name="hour" type="xs:integer" />
+ <xs:element name="minute" type="xs:integer" />
+ <xs:element name="second" type="xs:integer" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="DateTime">
+ <xs:all>
+ <xs:element name="hour" type="xs:integer" />
+ <xs:element name="minute" type="xs:integer" />
+ <xs:element name="second" type="xs:integer" />
+ <xs:element name="year" type="xs:integer" />
+ <xs:element name="month" type="xs:integer" />
+ <xs:element name="day" type="xs:integer" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="StringList">
+ <xs:sequence>
+ <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ResourcePixmap" mixed="true">
+ <xs:attribute name="resource" type="xs:string" />
+ <xs:attribute name="alias" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="ResourceIcon" mixed="true">
+ <xs:all>
+ <xs:element name="normaloff" type="ResourcePixmap" minOccurs="0" />
+ <xs:element name="normalon" type="ResourcePixmap" minOccurs="0" />
+ <xs:element name="disabledoff" type="ResourcePixmap" minOccurs="0" />
+ <xs:element name="disabledon" type="ResourcePixmap" minOccurs="0" />
+ <xs:element name="activeoff" type="ResourcePixmap" minOccurs="0" />
+ <xs:element name="activeon" type="ResourcePixmap" minOccurs="0" />
+ <xs:element name="selectedoff" type="ResourcePixmap" minOccurs="0" />
+ <xs:element name="selectedon" type="ResourcePixmap" minOccurs="0" />
+ </xs:all>
+ <xs:attribute name="theme" type="xs:string" />
+ <xs:attribute name="resource" type="xs:string" /> <!-- pre 4.4 legacy support -->
+ </xs:complexType>
+
+ <xs:complexType name="String" mixed="true">
+ <xs:attribute name="notr" type="xs:string" />
+ <xs:attribute name="comment" type="xs:string" />
+ <xs:attribute name="extracomment" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="PointF">
+ <xs:all>
+ <xs:element name="x" type="xs:double" />
+ <xs:element name="y" type="xs:double" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="RectF">
+ <xs:all>
+ <xs:element name="x" type="xs:double" />
+ <xs:element name="y" type="xs:double" />
+ <xs:element name="width" type="xs:double" />
+ <xs:element name="height" type="xs:double" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="SizeF">
+ <xs:all>
+ <xs:element name="width" type="xs:double" />
+ <xs:element name="height" type="xs:double" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="Char">
+ <xs:sequence>
+ <xs:element name="unicode" type="xs:integer" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Url">
+ <xs:sequence>
+ <xs:element name="string" type="String" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Property">
+ <xs:choice>
+ <xs:element name="bool" type="xs:string" />
+ <xs:element name="color" type="Color" />
+ <xs:element name="cstring" type="xs:string" />
+ <xs:element name="cursor" type="xs:integer" />
+ <xs:element name="cursorshape" type="xs:string" />
+ <xs:element name="enum" type="xs:string" />
+ <xs:element name="font" type ="Font" />
+ <xs:element name="iconset" type="ResourceIcon"/>
+ <xs:element name="pixmap" type="ResourcePixmap" />
+ <xs:element name="palette" type="Palette" />
+ <xs:element name="point" type="Point" />
+ <xs:element name="rect" type="Rect" />
+ <xs:element name="set" type="xs:string" />
+ <xs:element name="locale" type="Locale" />
+ <xs:element name="sizepolicy" type="SizePolicy" />
+ <xs:element name="size" type="Size" />
+ <xs:element name="string" type="String" />
+ <xs:element name="stringlist" type="StringList" />
+ <xs:element name="number" type="xs:integer" />
+ <xs:element name="float" type="xs:float" />
+ <xs:element name="double" type="xs:double" />
+ <xs:element name="date" type="Date" />
+ <xs:element name="time" type="Time" />
+ <xs:element name="datetime" type="DateTime" />
+ <xs:element name="pointf" type="PointF" />
+ <xs:element name="rectf" type="RectF" />
+ <xs:element name="sizef" type="SizeF" />
+ <xs:element name="longlong" type="xs:long" />
+ <xs:element name="char" type="Char" />
+ <xs:element name="url" type="Url" />
+ <xs:element name="uint" type="xs:unsignedInt" />
+ <xs:element name="ulonglong" type="xs:unsignedLong" />
+ <xs:element name="brush" type="Brush" />
+ </xs:choice>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="stdset" type="xs:integer" />
+ </xs:complexType>
+
+ <xs:complexType name="Connections">
+ <xs:sequence>
+ <xs:element name="connection" type="Connection" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Connection">
+ <xs:all>
+ <xs:element name="sender" type="xs:string" />
+ <xs:element name="signal" type="xs:string" />
+ <xs:element name="receiver" type="xs:string" />
+ <xs:element name="slot" type="xs:string" />
+ <xs:element name="hints" type="ConnectionHints" minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="ConnectionHints">
+ <xs:sequence>
+ <xs:element name="hint" type="ConnectionHint" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ConnectionHint">
+ <xs:all>
+ <xs:element name="x" type="xs:integer"/>
+ <xs:element name="y" type="xs:integer"/>
+ </xs:all>
+ <xs:attribute name="type" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="Script">
+ <xs:attribute name="source" type="xs:string" use="required" />
+ <xs:attribute name="language" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="WidgetData">
+ <xs:sequence>
+ <xs:element name="property" type="Property" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DesignerData">
+ <xs:sequence>
+ <xs:element name="property" type="Property" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Slots">
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="signal" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="slot" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PropertySpecifications">
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="stringpropertyspecification" type="StringPropertySpecification" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="StringPropertySpecification">
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="type" type="xs:string" use="required" />
+ <xs:attribute name="notr" type="xs:string"/>
+ </xs:complexType>
+
+</xs:schema>
diff --git a/src/designer/designer.pro b/src/designer/designer.pro
new file mode 100644
index 000000000..721c4fc42
--- /dev/null
+++ b/src/designer/designer.pro
@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+
+CONFIG += qt
+
+SUBDIRS = src
diff --git a/src/designer/src/components/buddyeditor/buddyeditor.cpp b/src/designer/src/components/buddyeditor/buddyeditor.cpp
new file mode 100644
index 000000000..34e1681ef
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor.cpp
@@ -0,0 +1,446 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "buddyeditor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <qdesigner_command_p.h>
+#include <qdesigner_propertycommand_p.h>
+#include <qdesigner_utils_p.h>
+#include <qlayout_widget_p.h>
+#include <connectionedit_p.h>
+#include <metadatabase_p.h>
+
+#include <QtCore/qdebug.h>
+#include <QtGui/QLabel>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+static const char *buddyPropertyC = "buddy";
+
+static bool canBeBuddy(QWidget *w, QDesignerFormWindowInterface *form)
+{
+ if (qobject_cast<const QLayoutWidget*>(w) || qobject_cast<const QLabel*>(w))
+ return false;
+ if (w == form->mainContainer() || w->isHidden() )
+ return false;
+
+ QExtensionManager *ext = form->core()->extensionManager();
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(ext, w)) {
+ const int index = sheet->indexOf(QLatin1String("focusPolicy"));
+ if (index != -1) {
+ bool ok = false;
+ const Qt::FocusPolicy q = static_cast<Qt::FocusPolicy>(qdesigner_internal::Utils::valueOf(sheet->property(index), &ok));
+ // Refuse No-focus unless the widget is promoted.
+ return (ok && q != Qt::NoFocus) || qdesigner_internal::isPromoted(form->core(), w);
+ }
+ }
+ return false;
+}
+
+static QString buddy(QLabel *label, QDesignerFormEditorInterface *core)
+{
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), label);
+ if (sheet == 0)
+ return QString();
+ const int prop_idx = sheet->indexOf(QLatin1String(buddyPropertyC));
+ if (prop_idx == -1)
+ return QString();
+ return sheet->property(prop_idx).toString();
+}
+
+typedef QList<QLabel*> LabelList;
+
+namespace qdesigner_internal {
+
+/*******************************************************************************
+** BuddyEditor
+*/
+
+BuddyEditor::BuddyEditor(QDesignerFormWindowInterface *form, QWidget *parent) :
+ ConnectionEdit(parent, form),
+ m_formWindow(form),
+ m_updating(false)
+{
+}
+
+
+QWidget *BuddyEditor::widgetAt(const QPoint &pos) const
+{
+ QWidget *w = ConnectionEdit::widgetAt(pos);
+
+ while (w != 0 && !m_formWindow->isManaged(w))
+ w = w->parentWidget();
+ if (!w)
+ return w;
+
+ if (state() == Editing) {
+ QLabel *label = qobject_cast<QLabel*>(w);
+ if (label == 0)
+ return 0;
+ const int cnt = connectionCount();
+ for (int i = 0; i < cnt; ++i) {
+ Connection *con = connection(i);
+ if (con->widget(EndPoint::Source) == w)
+ return 0;
+ }
+ } else {
+ if (!canBeBuddy(w, m_formWindow))
+ return 0;
+ }
+
+ return w;
+}
+
+Connection *BuddyEditor::createConnection(QWidget *source, QWidget *destination)
+{
+ return new Connection(this, source, destination);
+}
+
+QDesignerFormWindowInterface *BuddyEditor::formWindow() const
+{
+ return m_formWindow;
+}
+
+void BuddyEditor::updateBackground()
+{
+ if (m_updating || background() == 0)
+ return;
+ ConnectionEdit::updateBackground();
+
+ m_updating = true;
+ QList<Connection *> newList;
+ const LabelList label_list = background()->findChildren<QLabel*>();
+ foreach (QLabel *label, label_list) {
+ const QString buddy_name = buddy(label, m_formWindow->core());
+ if (buddy_name.isEmpty())
+ continue;
+
+ const QList<QWidget *> targets = background()->findChildren<QWidget*>(buddy_name);
+ if (targets.isEmpty())
+ continue;
+
+ QWidget *target = 0;
+
+ QListIterator<QWidget *> it(targets);
+ while (it.hasNext()) {
+ QWidget *widget = it.next();
+ if (widget && !widget->isHidden()) {
+ target = widget;
+ break;
+ }
+ }
+
+ if (target == 0)
+ continue;
+
+ Connection *con = new Connection(this);
+ con->setEndPoint(EndPoint::Source, label, widgetRect(label).center());
+ con->setEndPoint(EndPoint::Target, target, widgetRect(target).center());
+ newList.append(con);
+ }
+
+ QList<Connection *> toRemove;
+
+ const int c = connectionCount();
+ for (int i = 0; i < c; i++) {
+ Connection *con = connection(i);
+ QObject *source = con->object(EndPoint::Source);
+ QObject *target = con->object(EndPoint::Target);
+ bool found = false;
+ QListIterator<Connection *> it(newList);
+ while (it.hasNext()) {
+ Connection *newConn = it.next();
+ if (newConn->object(EndPoint::Source) == source && newConn->object(EndPoint::Target) == target) {
+ found = true;
+ break;
+ }
+ }
+ if (found == false)
+ toRemove.append(con);
+ }
+ if (!toRemove.isEmpty()) {
+ DeleteConnectionsCommand command(this, toRemove);
+ command.redo();
+ foreach (Connection *con, toRemove)
+ delete takeConnection(con);
+ }
+
+ QListIterator<Connection *> it(newList);
+ while (it.hasNext()) {
+ Connection *newConn = it.next();
+
+ bool found = false;
+ const int c = connectionCount();
+ for (int i = 0; i < c; i++) {
+ Connection *con = connection(i);
+ if (con->object(EndPoint::Source) == newConn->object(EndPoint::Source) &&
+ con->object(EndPoint::Target) == newConn->object(EndPoint::Target)) {
+ found = true;
+ break;
+ }
+ }
+ if (found == false) {
+ AddConnectionCommand command(this, newConn);
+ command.redo();
+ } else {
+ delete newConn;
+ }
+ }
+ m_updating = false;
+}
+
+void BuddyEditor::setBackground(QWidget *background)
+{
+ clear();
+ ConnectionEdit::setBackground(background);
+
+ const LabelList label_list = background->findChildren<QLabel*>();
+ foreach (QLabel *label, label_list) {
+ const QString buddy_name = buddy(label, m_formWindow->core());
+ if (buddy_name.isEmpty())
+ continue;
+ QWidget *target = background->findChild<QWidget*>(buddy_name);
+ if (target == 0)
+ continue;
+
+ Connection *con = new Connection(this);
+ con->setEndPoint(EndPoint::Source, label, widgetRect(label).center());
+ con->setEndPoint(EndPoint::Target, target, widgetRect(target).center());
+ addConnection(con);
+ }
+}
+
+static QUndoCommand *createBuddyCommand(QDesignerFormWindowInterface *fw, QLabel *label, QWidget *buddy)
+{
+ SetPropertyCommand *command = new SetPropertyCommand(fw);
+ command->init(label, QLatin1String(buddyPropertyC), buddy->objectName());
+ command->setText(BuddyEditor::tr("Add buddy"));
+ return command;
+}
+
+void BuddyEditor::endConnection(QWidget *target, const QPoint &pos)
+{
+ Connection *tmp_con = newlyAddedConnection();
+ Q_ASSERT(tmp_con != 0);
+
+ tmp_con->setEndPoint(EndPoint::Target, target, pos);
+
+ QWidget *source = tmp_con->widget(EndPoint::Source);
+ Q_ASSERT(source != 0);
+ Q_ASSERT(target != 0);
+ setEnabled(false);
+ Connection *new_con = createConnection(source, target);
+ setEnabled(true);
+ if (new_con != 0) {
+ new_con->setEndPoint(EndPoint::Source, source, tmp_con->endPointPos(EndPoint::Source));
+ new_con->setEndPoint(EndPoint::Target, target, tmp_con->endPointPos(EndPoint::Target));
+
+ selectNone();
+ addConnection(new_con);
+ QLabel *source = qobject_cast<QLabel*>(new_con->widget(EndPoint::Source));
+ QWidget *target = new_con->widget(EndPoint::Target);
+ if (source) {
+ undoStack()->push(createBuddyCommand(m_formWindow, source, target));
+ } else {
+ qDebug("BuddyEditor::endConnection(): not a label");
+ }
+ setSelected(new_con, true);
+ }
+
+ clearNewlyAddedConnection();
+ findObjectsUnderMouse(mapFromGlobal(QCursor::pos()));
+}
+
+void BuddyEditor::widgetRemoved(QWidget *widget)
+{
+ QList<QWidget*> child_list = widget->findChildren<QWidget*>();
+ child_list.prepend(widget);
+
+ ConnectionSet remove_set;
+ foreach (QWidget *w, child_list) {
+ const ConnectionList &cl = connectionList();
+ foreach (Connection *con, cl) {
+ if (con->widget(EndPoint::Source) == w || con->widget(EndPoint::Target) == w)
+ remove_set.insert(con, con);
+ }
+ }
+
+ if (!remove_set.isEmpty()) {
+ undoStack()->beginMacro(tr("Remove buddies"));
+ foreach (Connection *con, remove_set) {
+ setSelected(con, false);
+ con->update();
+ QWidget *source = con->widget(EndPoint::Source);
+ if (qobject_cast<QLabel*>(source) == 0) {
+ qDebug("BuddyConnection::widgetRemoved(): not a label");
+ } else {
+ ResetPropertyCommand *command = new ResetPropertyCommand(formWindow());
+ command->init(source, QLatin1String(buddyPropertyC));
+ undoStack()->push(command);
+ }
+ delete takeConnection(con);
+ }
+ undoStack()->endMacro();
+ }
+}
+
+void BuddyEditor::deleteSelected()
+{
+ const ConnectionSet selectedConnections = selection(); // want copy for unselect
+ if (selectedConnections.isEmpty())
+ return;
+
+ undoStack()->beginMacro(tr("Remove %n buddies", 0, selectedConnections.size()));
+ foreach (Connection *con, selectedConnections) {
+ setSelected(con, false);
+ con->update();
+ QWidget *source = con->widget(EndPoint::Source);
+ if (qobject_cast<QLabel*>(source) == 0) {
+ qDebug("BuddyConnection::deleteSelected(): not a label");
+ } else {
+ ResetPropertyCommand *command = new ResetPropertyCommand(formWindow());
+ command->init(source, QLatin1String(buddyPropertyC));
+ undoStack()->push(command);
+ }
+ delete takeConnection(con);
+ }
+ undoStack()->endMacro();
+}
+
+void BuddyEditor::autoBuddy()
+{
+ // Any labels?
+ LabelList labelList = background()->findChildren<QLabel*>();
+ if (labelList.empty())
+ return;
+ // Find already used buddies
+ QWidgetList usedBuddies;
+ const ConnectionList &beforeConnections = connectionList();
+ foreach (const Connection *c, beforeConnections)
+ usedBuddies.push_back(c->widget(EndPoint::Target));
+ // Find potential new buddies, keep lists in sync
+ QWidgetList buddies;
+ for (LabelList::iterator it = labelList.begin(); it != labelList.end(); ) {
+ QLabel *label = *it;
+ QWidget *newBuddy = 0;
+ if (m_formWindow->isManaged(label)) {
+ const QString buddy_name = buddy(label, m_formWindow->core());
+ if (buddy_name.isEmpty())
+ newBuddy = findBuddy(label, usedBuddies);
+ }
+ if (newBuddy) {
+ buddies.push_back(newBuddy);
+ usedBuddies.push_back(newBuddy);
+ ++it;
+ } else {
+ it = labelList.erase(it);
+ }
+ }
+ // Add the list in one go.
+ if (labelList.empty())
+ return;
+ const int count = labelList.size();
+ Q_ASSERT(count == buddies.size());
+ undoStack()->beginMacro(tr("Add %n buddies", 0, count));
+ for (int i = 0; i < count; i++)
+ undoStack()->push(createBuddyCommand(m_formWindow, labelList.at(i), buddies.at(i)));
+ undoStack()->endMacro();
+ // Now select all new ones
+ const ConnectionList &connections = connectionList();
+ foreach (Connection *con, connections)
+ setSelected(con, buddies.contains(con->widget(EndPoint::Target)));
+}
+
+// Geometrically find a potential buddy for label by checking neighbouring children of parent
+QWidget *BuddyEditor::findBuddy(QLabel *l, const QWidgetList &existingBuddies) const
+{
+ enum { DeltaX = 5 };
+ const QWidget *parent = l->parentWidget();
+ // Try to find next managed neighbour on horizontal line
+ const QRect geom = l->geometry();
+ const int y = geom.center().y();
+ QWidget *neighbour = 0;
+ switch (l->layoutDirection()) {
+ case Qt::LayoutDirectionAuto:
+ case Qt::LeftToRight: { // Walk right to find next managed neighbour
+ const int xEnd = parent->size().width();
+ for (int x = geom.right() + 1; x < xEnd; x += DeltaX)
+ if (QWidget *c = parent->childAt (x, y))
+ if (m_formWindow->isManaged(c)) {
+ neighbour = c;
+ break;
+ }
+ }
+ break;
+ case Qt::RightToLeft: // Walk left to find next managed neighbour
+ for (int x = geom.x() - 1; x >= 0; x -= DeltaX)
+ if (QWidget *c = parent->childAt (x, y))
+ if (m_formWindow->isManaged(c)) {
+ neighbour = c;
+ break;
+ }
+ break;
+ }
+ if (neighbour && !existingBuddies.contains(neighbour) && canBeBuddy(neighbour, m_formWindow))
+ return neighbour;
+
+ return 0;
+}
+
+void BuddyEditor::createContextMenu(QMenu &menu)
+{
+ QAction *autoAction = menu.addAction(tr("Set automatically"));
+ connect(autoAction, SIGNAL(triggered()), this, SLOT(autoBuddy()));
+ menu.addSeparator();
+ ConnectionEdit::createContextMenu(menu);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/buddyeditor/buddyeditor.h b/src/designer/src/components/buddyeditor/buddyeditor.h
new file mode 100644
index 000000000..2cd60071e
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BUDDYEDITOR_H
+#define BUDDYEDITOR_H
+
+#include "buddyeditor_global.h"
+
+#include <connectionedit_p.h>
+#include <QtCore/QPointer>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+class QLabel;
+
+namespace qdesigner_internal {
+
+class QT_BUDDYEDITOR_EXPORT BuddyEditor : public ConnectionEdit
+{
+ Q_OBJECT
+
+public:
+ BuddyEditor(QDesignerFormWindowInterface *form, QWidget *parent);
+
+ QDesignerFormWindowInterface *formWindow() const;
+ virtual void setBackground(QWidget *background);
+ virtual void deleteSelected();
+
+public slots:
+ virtual void updateBackground();
+ virtual void widgetRemoved(QWidget *w);
+ void autoBuddy();
+
+protected:
+ virtual QWidget *widgetAt(const QPoint &pos) const;
+ virtual Connection *createConnection(QWidget *source, QWidget *destination);
+ virtual void endConnection(QWidget *target, const QPoint &pos);
+ virtual void createContextMenu(QMenu &menu);
+
+private:
+ QWidget *findBuddy(QLabel *l, const QWidgetList &existingBuddies) const;
+
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+ bool m_updating;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/components/buddyeditor/buddyeditor.pri b/src/designer/src/components/buddyeditor/buddyeditor.pri
new file mode 100644
index 000000000..c507aa01d
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor.pri
@@ -0,0 +1,16 @@
+
+QT += xml
+
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/buddyeditor.h \
+ $$PWD/buddyeditor_plugin.h \
+ $$PWD/buddyeditor_tool.h \
+ $$PWD/buddyeditor_global.h
+
+SOURCES += \
+ $$PWD/buddyeditor.cpp \
+ $$PWD/buddyeditor_tool.cpp \
+ $$PWD/buddyeditor_plugin.cpp \
+ $$PWD/buddyeditor_instance.cpp
diff --git a/src/designer/src/components/buddyeditor/buddyeditor_global.h b/src/designer/src/components/buddyeditor/buddyeditor_global.h
new file mode 100644
index 000000000..00b216b67
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor_global.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BUDDYEDITOR_GLOBAL_H
+#define BUDDYEDITOR_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN
+#ifdef QT_BUDDYEDITOR_LIBRARY
+# define QT_BUDDYEDITOR_EXPORT
+#else
+# define QT_BUDDYEDITOR_EXPORT
+#endif
+#else
+#define QT_BUDDYEDITOR_EXPORT
+#endif
+
+#endif // BUDDYEDITOR_GLOBAL_H
diff --git a/src/designer/src/components/buddyeditor/buddyeditor_instance.cpp b/src/designer/src/components/buddyeditor/buddyeditor_instance.cpp
new file mode 100644
index 000000000..ef71ec32c
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor_instance.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qplugin.h>
+
+#include "buddyeditor_plugin.h"
+
+QT_USE_NAMESPACE
+
+using namespace qdesigner_internal;
+
+Q_EXPORT_PLUGIN(BuddyEditorPlugin)
diff --git a/src/designer/src/components/buddyeditor/buddyeditor_plugin.cpp b/src/designer/src/components/buddyeditor/buddyeditor_plugin.cpp
new file mode 100644
index 000000000..17b93e1b5
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor_plugin.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QAction>
+
+#include "buddyeditor_plugin.h"
+#include "buddyeditor_tool.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+BuddyEditorPlugin::BuddyEditorPlugin()
+ : m_initialized(false)
+{
+}
+
+BuddyEditorPlugin::~BuddyEditorPlugin()
+{
+}
+
+bool BuddyEditorPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void BuddyEditorPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_ASSERT(!isInitialized());
+
+ m_action = new QAction(tr("Edit Buddies"), this);
+ m_action->setObjectName(QLatin1String("__qt_edit_buddies_action"));
+ QIcon buddyIcon = QIcon::fromTheme("designer-edit-buddy",
+ QIcon(core->resourceLocation() + QLatin1String("/buddytool.png")));
+ m_action->setIcon(buddyIcon);
+ m_action->setEnabled(false);
+
+ setParent(core);
+ m_core = core;
+ m_initialized = true;
+
+ connect(core->formWindowManager(), SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)),
+ this, SLOT(addFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core->formWindowManager(), SIGNAL(formWindowRemoved(QDesignerFormWindowInterface*)),
+ this, SLOT(removeFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface*)));
+}
+
+QDesignerFormEditorInterface *BuddyEditorPlugin::core() const
+{
+ return m_core;
+}
+
+void BuddyEditorPlugin::addFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_ASSERT(formWindow != 0);
+ Q_ASSERT(m_tools.contains(formWindow) == false);
+
+ BuddyEditorTool *tool = new BuddyEditorTool(formWindow, this);
+ m_tools[formWindow] = tool;
+ connect(m_action, SIGNAL(triggered()), tool->action(), SLOT(trigger()));
+ formWindow->registerTool(tool);
+}
+
+void BuddyEditorPlugin::removeFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_ASSERT(formWindow != 0);
+ Q_ASSERT(m_tools.contains(formWindow) == true);
+
+ BuddyEditorTool *tool = m_tools.value(formWindow);
+ m_tools.remove(formWindow);
+ disconnect(m_action, SIGNAL(triggered()), tool->action(), SLOT(trigger()));
+ // ### FIXME disable the tool
+
+ delete tool;
+}
+
+QAction *BuddyEditorPlugin::action() const
+{
+ return m_action;
+}
+
+void BuddyEditorPlugin::activeFormWindowChanged(QDesignerFormWindowInterface *formWindow)
+{
+ m_action->setEnabled(formWindow != 0);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/buddyeditor/buddyeditor_plugin.h b/src/designer/src/components/buddyeditor/buddyeditor_plugin.h
new file mode 100644
index 000000000..7e6e51550
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor_plugin.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BUDDYEDITOR_PLUGIN_H
+#define BUDDYEDITOR_PLUGIN_H
+
+#include "buddyeditor_global.h"
+
+#include <QtDesigner/QDesignerFormEditorPluginInterface>
+
+#include <QtCore/QPointer>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QAction;
+
+namespace qdesigner_internal {
+
+class BuddyEditorTool;
+
+class QT_BUDDYEDITOR_EXPORT BuddyEditorPlugin: public QObject, public QDesignerFormEditorPluginInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerFormEditorPluginInterface)
+public:
+ BuddyEditorPlugin();
+ virtual ~BuddyEditorPlugin();
+
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ QAction *action() const;
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+public slots:
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+
+private slots:
+ void addFormWindow(QDesignerFormWindowInterface *formWindow);
+ void removeFormWindow(QDesignerFormWindowInterface *formWindow);
+
+private:
+ QPointer<QDesignerFormEditorInterface> m_core;
+ QHash<QDesignerFormWindowInterface*, BuddyEditorTool*> m_tools;
+ bool m_initialized;
+ QAction *m_action;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // BUDDYEDITOR_PLUGIN_H
diff --git a/src/designer/src/components/buddyeditor/buddyeditor_tool.cpp b/src/designer/src/components/buddyeditor/buddyeditor_tool.cpp
new file mode 100644
index 000000000..3779789fa
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor_tool.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "buddyeditor_tool.h"
+#include "buddyeditor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+BuddyEditorTool::BuddyEditorTool(QDesignerFormWindowInterface *formWindow, QObject *parent)
+ : QDesignerFormWindowToolInterface(parent),
+ m_formWindow(formWindow),
+ m_action(new QAction(tr("Edit Buddies"), this))
+{
+}
+
+BuddyEditorTool::~BuddyEditorTool()
+{
+}
+
+QDesignerFormEditorInterface *BuddyEditorTool::core() const
+{
+ return m_formWindow->core();
+}
+
+QDesignerFormWindowInterface *BuddyEditorTool::formWindow() const
+{
+ return m_formWindow;
+}
+
+bool BuddyEditorTool::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(managedWidget);
+ Q_UNUSED(event);
+
+ return false;
+}
+
+QWidget *BuddyEditorTool::editor() const
+{
+ if (!m_editor) {
+ Q_ASSERT(formWindow() != 0);
+ m_editor = new BuddyEditor(formWindow(), 0);
+ connect(formWindow(), SIGNAL(mainContainerChanged(QWidget*)), m_editor, SLOT(setBackground(QWidget*)));
+ connect(formWindow(), SIGNAL(changed()),
+ m_editor, SLOT(updateBackground()));
+ }
+
+ return m_editor;
+}
+
+void BuddyEditorTool::activated()
+{
+ m_editor->enableUpdateBackground(true);
+}
+
+void BuddyEditorTool::deactivated()
+{
+ m_editor->enableUpdateBackground(false);
+}
+
+QAction *BuddyEditorTool::action() const
+{
+ return m_action;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/buddyeditor/buddyeditor_tool.h b/src/designer/src/components/buddyeditor/buddyeditor_tool.h
new file mode 100644
index 000000000..dabb4654d
--- /dev/null
+++ b/src/designer/src/components/buddyeditor/buddyeditor_tool.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BUDDYEDITOR_TOOL_H
+#define BUDDYEDITOR_TOOL_H
+
+#include "buddyeditor_global.h"
+
+#include <QtCore/QPointer>
+
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QAction;
+
+namespace qdesigner_internal {
+
+class BuddyEditor;
+
+class QT_BUDDYEDITOR_EXPORT BuddyEditorTool: public QDesignerFormWindowToolInterface
+{
+ Q_OBJECT
+public:
+ explicit BuddyEditorTool(QDesignerFormWindowInterface *formWindow, QObject *parent = 0);
+ virtual ~BuddyEditorTool();
+
+ virtual QDesignerFormEditorInterface *core() const;
+ virtual QDesignerFormWindowInterface *formWindow() const;
+
+ virtual QWidget *editor() const;
+ virtual QAction *action() const;
+
+ virtual void activated();
+ virtual void deactivated();
+
+ virtual bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event);
+
+private:
+ QDesignerFormWindowInterface *m_formWindow;
+ mutable QPointer<BuddyEditor> m_editor;
+ QAction *m_action;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // BUDDYEDITOR_TOOL_H
diff --git a/src/designer/src/components/component.pri b/src/designer/src/components/component.pri
new file mode 100644
index 000000000..c2fc10d9e
--- /dev/null
+++ b/src/designer/src/components/component.pri
@@ -0,0 +1,2 @@
+
+TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end
diff --git a/src/designer/src/components/components.pro b/src/designer/src/components/components.pro
new file mode 100644
index 000000000..97d79b4bb
--- /dev/null
+++ b/src/designer/src/components/components.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+SUBDIRS = lib
diff --git a/src/designer/src/components/formeditor/brushmanagerproxy.cpp b/src/designer/src/components/formeditor/brushmanagerproxy.cpp
new file mode 100644
index 000000000..59803336e
--- /dev/null
+++ b/src/designer/src/components/formeditor/brushmanagerproxy.cpp
@@ -0,0 +1,303 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtbrushmanager.h"
+#include "brushmanagerproxy.h"
+#include "qsimpleresource_p.h"
+#include "qdesigner_utils_p.h"
+#include "ui4_p.h"
+
+#include <QtXml/QXmlStreamWriter>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class BrushManagerProxyPrivate
+{
+ BrushManagerProxy *q_ptr;
+ Q_DECLARE_PUBLIC(BrushManagerProxy)
+
+public:
+ BrushManagerProxyPrivate(BrushManagerProxy *bp, QDesignerFormEditorInterface *core);
+ void brushAdded(const QString &name, const QBrush &brush);
+ void brushRemoved(const QString &name);
+ QString uniqueBrushFileName(const QString &brushName) const;
+
+ QtBrushManager *m_Manager;
+ QString m_designerFolder;
+ const QString m_BrushFolder;
+ QString m_BrushPath;
+ QDesignerFormEditorInterface *m_Core;
+ QMap<QString, QString> m_FileToBrush;
+ QMap<QString, QString> m_BrushToFile;
+};
+
+BrushManagerProxyPrivate::BrushManagerProxyPrivate(BrushManagerProxy *bp, QDesignerFormEditorInterface *core) :
+ q_ptr(bp),
+ m_Manager(0),
+ m_BrushFolder(QLatin1String("brushes")),
+ m_Core(core)
+{
+ m_designerFolder = QDir::homePath();
+ m_designerFolder += QDir::separator();
+ m_designerFolder += QLatin1String(".designer");
+ m_BrushPath = m_designerFolder;
+ m_BrushPath += QDir::separator();
+ m_BrushPath += m_BrushFolder;
+}
+} // namespace qdesigner_internal
+
+using namespace qdesigner_internal;
+
+void BrushManagerProxyPrivate::brushAdded(const QString &name, const QBrush &brush)
+{
+ const QString filename = uniqueBrushFileName(name);
+
+ QDir designerDir(m_designerFolder);
+ if (!designerDir.exists(m_BrushFolder))
+ designerDir.mkdir(m_BrushFolder);
+
+ QFile file(m_BrushPath + QDir::separator() +filename);
+ if (file.open(QIODevice::WriteOnly)) {
+ QSimpleResource resource(m_Core);
+
+ DomBrush *dom = resource.saveBrush(brush);
+
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ writer.writeStartElement(QLatin1String("description"));
+ writer.writeAttribute(QLatin1String("name"), name);
+ dom->write(writer);
+ writer.writeEndElement();
+ writer.writeEndDocument();
+
+ delete dom;
+ file.close();
+
+ m_FileToBrush[filename] = name;
+ m_BrushToFile[name] = filename;
+ }
+}
+
+void BrushManagerProxyPrivate::brushRemoved(const QString &name)
+{
+ QDir brushDir(m_BrushPath);
+
+ QString filename = m_BrushToFile[name];
+ brushDir.remove(filename);
+ m_BrushToFile.remove(name);
+ m_FileToBrush.remove(filename);
+}
+
+QString BrushManagerProxyPrivate::uniqueBrushFileName(const QString &brushName) const
+{
+ const QString extension = QLatin1String(".br");
+ QString filename = brushName.toLower();
+ filename += extension;
+ int i = 0;
+ while (m_FileToBrush.contains(filename)) {
+ filename = brushName.toLower();
+ filename += QString::number(++i);
+ filename += extension;
+ }
+ return filename;
+}
+
+
+BrushManagerProxy::BrushManagerProxy(QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), d_ptr(new BrushManagerProxyPrivate(this, core))
+{
+}
+
+BrushManagerProxy::~BrushManagerProxy()
+{
+}
+
+void BrushManagerProxy::setBrushManager(QtBrushManager *manager)
+{
+ if (d_ptr->m_Manager == manager)
+ return;
+
+ if (d_ptr->m_Manager) {
+ disconnect(d_ptr->m_Manager, SIGNAL(brushAdded(QString,QBrush)),
+ this, SLOT(brushAdded(QString,QBrush)));
+ disconnect(d_ptr->m_Manager, SIGNAL(brushRemoved(QString)),
+ this, SLOT(brushRemoved(QString)));
+ }
+
+ d_ptr->m_Manager = manager;
+
+ if (!d_ptr->m_Manager)
+ return;
+
+ // clear the manager
+ QMap<QString, QBrush> brushes = d_ptr->m_Manager->brushes();
+ QMap<QString, QBrush>::ConstIterator it = brushes.constBegin();
+ while (it != brushes.constEnd()) {
+ QString name = it.key();
+ d_ptr->m_Manager->removeBrush(name);
+
+ it++;
+ }
+
+ // fill up the manager from compiled resources or from brush folder here
+ const QString nameAttribute = QLatin1String("name");
+ const QString brush = QLatin1String("brush");
+ const QString description = QLatin1String("description");
+
+ QDir brushDir(d_ptr->m_BrushPath);
+ bool customBrushesExist = brushDir.exists();
+ if (customBrushesExist) {
+ // load brushes from brush folder
+ QStringList nameFilters;
+ nameFilters.append(QLatin1String("*.br"));
+
+ QFileInfoList infos = brushDir.entryInfoList(nameFilters);
+ QListIterator<QFileInfo> it(infos);
+ while (it.hasNext()) {
+ const QFileInfo fi = it.next();
+
+ QString filename = fi.absoluteFilePath();
+
+ QFile file(filename);
+ if (file.open(QIODevice::ReadOnly)) {
+ QXmlStreamReader reader(&file);
+
+ //<description name="black" >
+ // <brush brushstyle="SolidPattern" >
+ // <color alpha="255" .../>
+ // </brush>
+ //</description>
+
+ QString descname;
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ const QString tag = reader.name().toString().toLower();
+ if (tag == description) {
+ if (!reader.attributes().hasAttribute(nameAttribute))
+ reader.raiseError(tr("The element '%1' is missing the required attribute '%2'.")
+ .arg(tag, nameAttribute));
+ else
+ descname = reader.attributes().value(nameAttribute).toString();
+ continue;
+ }
+ if (tag == brush) {
+ DomBrush brush;
+ brush.read(reader);
+
+ if (descname.isEmpty()) {
+ reader.raiseError(tr("Empty brush name encountered."));
+ } else {
+ QSimpleResource resource(d_ptr->m_Core);
+ QBrush br = resource.setupBrush(&brush);
+ d_ptr->m_Manager->addBrush(descname, br);
+ d_ptr->m_FileToBrush[filename] = descname;
+ d_ptr->m_BrushToFile[descname] = filename;
+ }
+ continue;
+ }
+ reader.raiseError(tr("An unexpected element '%1' was encountered.").arg(tag));
+ }
+ }
+
+ file.close();
+
+ if (reader.hasError()) {
+ qdesigner_internal::designerWarning(tr("An error occurred when reading the brush definition file '%1' at line line %2, column %3: %4")
+ .arg(fi.fileName())
+ .arg(reader.lineNumber())
+ .arg(reader.columnNumber())
+ .arg(reader.errorString()));
+ continue;
+ }
+ }
+ }
+ }
+
+ connect(d_ptr->m_Manager, SIGNAL(brushAdded(QString,QBrush)),
+ this, SLOT(brushAdded(QString,QBrush)));
+ connect(d_ptr->m_Manager, SIGNAL(brushRemoved(QString)),
+ this, SLOT(brushRemoved(QString)));
+
+ if (!customBrushesExist) {
+ // load brushes from resources
+ QFile qrcFile(QLatin1String(":trolltech/brushes/defaultbrushes.xml"));
+ if (!qrcFile.open(QIODevice::ReadOnly))
+ Q_ASSERT(0);
+
+ QXmlStreamReader reader(&qrcFile);
+
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ if (reader.name().toString().toLower() == QLatin1String("description")) {
+ const QString name = reader.attributes().value(nameAttribute).toString();
+ do { // forward to <brush> element, which DomBrush expects
+ reader.readNext();
+ } while (!reader.atEnd() && reader.tokenType() != QXmlStreamReader::StartElement);
+ DomBrush brushDom;
+ brushDom.read(reader);
+ if (!reader.hasError()) {
+ QSimpleResource resource(d_ptr->m_Core);
+ QBrush br = resource.setupBrush(&brushDom);
+ d_ptr->m_Manager->addBrush(name, br);
+ }
+ }
+ }
+ }
+ if (reader.hasError()) {
+ // Should never happen
+ qdesigner_internal::designerWarning(tr("An error occurred when reading the resource file '%1' at line %2, column %3: %4")
+ .arg(qrcFile.fileName())
+ .arg(reader.lineNumber())
+ .arg(reader.columnNumber())
+ .arg(reader.errorString()));
+ }
+
+ qrcFile.close();
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_brushmanagerproxy.cpp"
diff --git a/src/designer/src/components/formeditor/brushmanagerproxy.h b/src/designer/src/components/formeditor/brushmanagerproxy.h
new file mode 100644
index 000000000..934bd8d46
--- /dev/null
+++ b/src/designer/src/components/formeditor/brushmanagerproxy.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BRUSHMANAGERPROXY_H
+#define BRUSHMANAGERPROXY_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class QtBrushManager;
+class BrushManagerProxyPrivate;
+
+class BrushManagerProxy : public QObject
+{
+ Q_OBJECT
+public:
+ explicit BrushManagerProxy(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ ~BrushManagerProxy();
+
+ void setBrushManager(QtBrushManager *manager);
+
+private:
+ QScopedPointer<BrushManagerProxyPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(BrushManagerProxy)
+ Q_DISABLE_COPY(BrushManagerProxy)
+ Q_PRIVATE_SLOT(d_func(), void brushAdded(const QString &, const QBrush &))
+ Q_PRIVATE_SLOT(d_func(), void brushRemoved(const QString &name))
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/components/formeditor/default_actionprovider.cpp b/src/designer/src/components/formeditor/default_actionprovider.cpp
new file mode 100644
index 000000000..c0a51dede
--- /dev/null
+++ b/src/designer/src/components/formeditor/default_actionprovider.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "default_actionprovider.h"
+#include "invisible_widget_p.h"
+#include "qdesigner_toolbar_p.h"
+
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtCore/QRect>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ------------ ActionProviderBase:
+// Draws the drag indicator when dragging an action over a widget
+// that receives action Dnd, such as ToolBar, Menu or MenuBar.
+ActionProviderBase::ActionProviderBase(QWidget *widget) :
+ m_indicator(new InvisibleWidget(widget))
+{
+ Q_ASSERT(widget != 0);
+
+ m_indicator->setAutoFillBackground(true);
+ m_indicator->setBackgroundRole(QPalette::Window);
+
+ QPalette p;
+ p.setColor(m_indicator->backgroundRole(), Qt::red);
+ m_indicator->setPalette(p);
+ m_indicator->hide();
+}
+
+enum { indicatorSize = 2 };
+
+// Position an indicator horizontally over the rectangle, indicating
+// 'Insert before' (left or right according to layout direction)
+static inline QRect horizontalIndicatorRect(const QRect &rect, Qt::LayoutDirection layoutDirection)
+{
+ // Position right?
+ QRect rc = QRect(rect.x(), 0, indicatorSize, rect.height() - 1);
+ if (layoutDirection == Qt::RightToLeft)
+ rc.moveLeft(rc.x() + rect.width() - indicatorSize);
+ return rc;
+}
+
+// Position an indicator vertically over the rectangle, indicating 'Insert before' (top)
+static inline QRect verticalIndicatorRect(const QRect &rect)
+{
+ return QRect(0, rect.top(), rect.width() - 1, indicatorSize);
+}
+
+// Determine the geometry of the indicator by retrieving
+// the action under mouse and positioning the bar within its geometry.
+QRect ActionProviderBase::indicatorGeometry(const QPoint &pos, Qt::LayoutDirection layoutDirection) const
+{
+ QAction *action = actionAt(pos);
+ if (!action)
+ return QRect();
+ QRect rc = actionGeometry(action);
+ return orientation() == Qt::Horizontal ? horizontalIndicatorRect(rc, layoutDirection) : verticalIndicatorRect(rc);
+}
+
+// Adjust the indicator while dragging. (-1,1) is called to finish a DND operation
+void ActionProviderBase::adjustIndicator(const QPoint &pos)
+{
+ if (pos == QPoint(-1, -1)) {
+ m_indicator->hide();
+ return;
+ }
+ const QRect ig = indicatorGeometry(pos, m_indicator->layoutDirection());
+ if (ig.isValid()) {
+ m_indicator->setGeometry(ig);
+ QPalette p = m_indicator->palette();
+ if (p.color(m_indicator->backgroundRole()) != Qt::red) {
+ p.setColor(m_indicator->backgroundRole(), Qt::red);
+ m_indicator->setPalette(p);
+ }
+ m_indicator->show();
+ m_indicator->raise();
+ } else {
+ m_indicator->hide();
+ }
+}
+
+// ------------- QToolBarActionProvider
+QToolBarActionProvider::QToolBarActionProvider(QToolBar *widget, QObject *parent) :
+ QObject(parent),
+ ActionProviderBase(widget),
+ m_widget(widget)
+{
+}
+
+QRect QToolBarActionProvider::actionGeometry(QAction *action) const
+{
+ return m_widget->actionGeometry(action);
+}
+
+QAction *QToolBarActionProvider::actionAt(const QPoint &pos) const
+{
+ return ToolBarEventFilter::actionAt(m_widget, pos);
+}
+
+Qt::Orientation QToolBarActionProvider::orientation() const
+{
+ return m_widget->orientation();
+}
+
+QRect QToolBarActionProvider::indicatorGeometry(const QPoint &pos, Qt::LayoutDirection layoutDirection) const
+{
+ const QRect actionRect = ActionProviderBase::indicatorGeometry(pos, layoutDirection);
+ if (actionRect.isValid())
+ return actionRect;
+ // Toolbar differs in that is has no dummy placeholder to 'insert before'
+ // when intending to append. Check the free area.
+ const QRect freeArea = ToolBarEventFilter::freeArea(m_widget);
+ if (!freeArea.contains(pos))
+ return QRect();
+ return orientation() == Qt::Horizontal ? horizontalIndicatorRect(freeArea, layoutDirection) : verticalIndicatorRect(freeArea);
+}
+
+// ------------- QMenuBarActionProvider
+QMenuBarActionProvider::QMenuBarActionProvider(QMenuBar *widget, QObject *parent) :
+ QObject(parent),
+ ActionProviderBase(widget),
+ m_widget(widget)
+{
+}
+
+QRect QMenuBarActionProvider::actionGeometry(QAction *action) const
+{
+ return m_widget->actionGeometry(action);
+}
+
+QAction *QMenuBarActionProvider::actionAt(const QPoint &pos) const
+{
+ return m_widget->actionAt(pos);
+}
+
+Qt::Orientation QMenuBarActionProvider::orientation() const
+{
+ return Qt::Horizontal;
+}
+
+// ------------- QMenuActionProvider
+QMenuActionProvider::QMenuActionProvider(QMenu *widget, QObject *parent) :
+ QObject(parent),
+ ActionProviderBase(widget),
+ m_widget(widget)
+{
+}
+
+QRect QMenuActionProvider::actionGeometry(QAction *action) const
+{
+ return m_widget->actionGeometry(action);
+}
+
+QAction *QMenuActionProvider::actionAt(const QPoint &pos) const
+{
+ return m_widget->actionAt(pos);
+}
+
+Qt::Orientation QMenuActionProvider::orientation() const
+{
+ return Qt::Vertical;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/default_actionprovider.h b/src/designer/src/components/formeditor/default_actionprovider.h
new file mode 100644
index 000000000..9eba71eef
--- /dev/null
+++ b/src/designer/src/components/formeditor/default_actionprovider.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_ACTIONPROVIDER_H
+#define DEFAULT_ACTIONPROVIDER_H
+
+#include "formeditor_global.h"
+#include "actionprovider_p.h"
+#include <extensionfactory_p.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QToolBar>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class FormWindow;
+
+class QT_FORMEDITOR_EXPORT ActionProviderBase: public QDesignerActionProviderExtension
+{
+protected:
+ explicit ActionProviderBase(QWidget *widget);
+
+public:
+ virtual void adjustIndicator(const QPoint &pos);
+ virtual Qt::Orientation orientation() const = 0;
+
+protected:
+ virtual QRect indicatorGeometry(const QPoint &pos, Qt::LayoutDirection layoutDirection) const;
+
+private:
+ QWidget *m_indicator;
+};
+
+class QT_FORMEDITOR_EXPORT QToolBarActionProvider: public QObject, public ActionProviderBase
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerActionProviderExtension)
+public:
+ explicit QToolBarActionProvider(QToolBar *widget, QObject *parent = 0);
+
+ virtual QRect actionGeometry(QAction *action) const;
+ virtual QAction *actionAt(const QPoint &pos) const;
+ Qt::Orientation orientation() const;
+
+protected:
+ virtual QRect indicatorGeometry(const QPoint &pos, Qt::LayoutDirection layoutDirection) const;
+
+private:
+ QToolBar *m_widget;
+};
+
+class QT_FORMEDITOR_EXPORT QMenuBarActionProvider: public QObject, public ActionProviderBase
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerActionProviderExtension)
+public:
+ explicit QMenuBarActionProvider(QMenuBar *widget, QObject *parent = 0);
+
+ virtual QRect actionGeometry(QAction *action) const;
+ virtual QAction *actionAt(const QPoint &pos) const;
+ Qt::Orientation orientation() const;
+
+private:
+ QMenuBar *m_widget;
+};
+
+class QT_FORMEDITOR_EXPORT QMenuActionProvider: public QObject, public ActionProviderBase
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerActionProviderExtension)
+public:
+ explicit QMenuActionProvider(QMenu *widget, QObject *parent = 0);
+
+ virtual QRect actionGeometry(QAction *action) const;
+ virtual QAction *actionAt(const QPoint &pos) const;
+ Qt::Orientation orientation() const;
+
+private:
+ QMenu *m_widget;
+};
+
+typedef ExtensionFactory<QDesignerActionProviderExtension, QToolBar, QToolBarActionProvider> QToolBarActionProviderFactory;
+typedef ExtensionFactory<QDesignerActionProviderExtension, QMenuBar, QMenuBarActionProvider> QMenuBarActionProviderFactory;
+typedef ExtensionFactory<QDesignerActionProviderExtension, QMenu, QMenuActionProvider> QMenuActionProviderFactory;
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DEFAULT_ACTIONPROVIDER_H
diff --git a/src/designer/src/components/formeditor/default_container.cpp b/src/designer/src/components/formeditor/default_container.cpp
new file mode 100644
index 000000000..e5f2c5b87
--- /dev/null
+++ b/src/designer/src/components/formeditor/default_container.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "default_container.h"
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+template <class Container>
+static inline void setCurrentContainerIndex(int index, Container *container)
+{
+ const bool blocked = container->signalsBlocked();
+ container->blockSignals(true);
+ container->setCurrentIndex(index);
+ container->blockSignals(blocked);
+}
+
+static inline void ensureNoParent(QWidget *widget)
+{
+ if (widget->parentWidget())
+ widget->setParent(0);
+}
+
+static const char *PageLabel = "Page";
+
+namespace qdesigner_internal {
+
+// --------- QStackedWidgetContainer
+QStackedWidgetContainer::QStackedWidgetContainer(QStackedWidget *widget, QObject *parent) :
+ QObject(parent),
+ m_widget(widget)
+{
+}
+
+void QStackedWidgetContainer::setCurrentIndex(int index)
+{
+ setCurrentContainerIndex(index, m_widget);
+}
+
+void QStackedWidgetContainer::addWidget(QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->addWidget(widget);
+}
+
+void QStackedWidgetContainer::insertWidget(int index, QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->insertWidget(index, widget);
+}
+
+void QStackedWidgetContainer::remove(int index)
+{
+ m_widget->removeWidget(widget(index));
+}
+
+// --------- QTabWidgetContainer
+QTabWidgetContainer::QTabWidgetContainer(QTabWidget *widget, QObject *parent) :
+ QObject(parent),
+ m_widget(widget)
+{
+}
+
+void QTabWidgetContainer::setCurrentIndex(int index)
+{
+ setCurrentContainerIndex(index, m_widget);
+}
+
+void QTabWidgetContainer::addWidget(QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->addTab(widget, QString::fromUtf8(PageLabel));
+}
+
+void QTabWidgetContainer::insertWidget(int index, QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->insertTab(index, widget, QString::fromUtf8(PageLabel));
+}
+
+void QTabWidgetContainer::remove(int index)
+{
+ m_widget->removeTab(index);
+}
+
+// ------------------- QToolBoxContainer
+QToolBoxContainer::QToolBoxContainer(QToolBox *widget, QObject *parent) :
+ QObject(parent),
+ m_widget(widget)
+{
+}
+
+void QToolBoxContainer::setCurrentIndex(int index)
+{
+ setCurrentContainerIndex(index, m_widget);
+}
+
+void QToolBoxContainer::addWidget(QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->addItem(widget, QString::fromUtf8(PageLabel));
+}
+
+void QToolBoxContainer::insertWidget(int index, QWidget *widget)
+{
+ ensureNoParent(widget);
+ m_widget->insertItem(index, widget, QString::fromUtf8(PageLabel));
+}
+
+void QToolBoxContainer::remove(int index)
+{
+ m_widget->removeItem(index);
+}
+
+// ------------------- QScrollAreaContainer
+// We pass on active=true only if there are no children yet.
+// If there are children, it is a legacy custom widget QScrollArea that has an internal,
+// unmanaged child, in which case we deactivate the extension (otherwise we crash).
+// The child will then not show up in the task menu
+
+QScrollAreaContainer::QScrollAreaContainer(QScrollArea *widget, QObject *parent) :
+ QObject(parent),
+ SingleChildContainer<QScrollArea>(widget, widget->widget() == 0)
+{
+}
+// ------------------- QDockWidgetContainer
+QDockWidgetContainer::QDockWidgetContainer(QDockWidget *widget, QObject *parent) :
+ QObject(parent),
+ SingleChildContainer<QDockWidget>(widget)
+{
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/default_container.h b/src/designer/src/components/formeditor/default_container.h
new file mode 100644
index 000000000..753f39794
--- /dev/null
+++ b/src/designer/src/components/formeditor/default_container.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_CONTAINER_H
+#define DEFAULT_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/extension.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QStackedWidget>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QScrollArea>
+#include <QtGui/QDockWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ------------ QStackedWidgetContainer
+class QStackedWidgetContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QStackedWidgetContainer(QStackedWidget *widget, QObject *parent = 0);
+
+ virtual int count() const { return m_widget->count(); }
+ virtual QWidget *widget(int index) const { return m_widget->widget(index); }
+
+ virtual int currentIndex() const { return m_widget->currentIndex(); }
+ virtual void setCurrentIndex(int index);
+
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QStackedWidget *m_widget;
+};
+
+// ------------ QTabWidgetContainer
+class QTabWidgetContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QTabWidgetContainer(QTabWidget *widget, QObject *parent = 0);
+
+ virtual int count() const { return m_widget->count(); }
+ virtual QWidget *widget(int index) const { return m_widget->widget(index); }
+
+ virtual int currentIndex() const { return m_widget->currentIndex(); }
+ virtual void setCurrentIndex(int index);
+
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QTabWidget *m_widget;
+};
+
+// ------------ QToolBoxContainer
+class QToolBoxContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QToolBoxContainer(QToolBox *widget, QObject *parent = 0);
+
+ virtual int count() const { return m_widget->count(); }
+ virtual QWidget *widget(int index) const { return m_widget->widget(index); }
+
+ virtual int currentIndex() const { return m_widget->currentIndex(); }
+ virtual void setCurrentIndex(int index);
+
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QToolBox *m_widget;
+};
+
+// ------------ SingleChildContainer:
+// Template for containers that have a single child widget using widget()/setWidget().
+
+template <class Container>
+class SingleChildContainer: public QDesignerContainerExtension
+{
+protected:
+ explicit SingleChildContainer(Container *widget, bool active = true);
+public:
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int /*index*/) {}
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int /*index*/) {}
+
+private:
+ const bool m_active;
+ Container *m_container;
+};
+
+template <class Container>
+SingleChildContainer<Container>::SingleChildContainer(Container *widget, bool active) :
+ m_active(active),
+ m_container(widget)
+{
+}
+
+template <class Container>
+int SingleChildContainer<Container>::count() const
+{
+ return m_active && m_container->widget() ? 1 : 0;
+}
+
+template <class Container>
+QWidget *SingleChildContainer<Container>::widget(int /* index */) const
+{
+ return m_container->widget();
+}
+
+template <class Container>
+int SingleChildContainer<Container>::currentIndex() const
+{
+ return m_active && m_container->widget() ? 0 : -1;
+}
+
+template <class Container>
+void SingleChildContainer<Container>::addWidget(QWidget *widget)
+{
+ Q_ASSERT(m_container->widget() == 0);
+ widget->setParent(m_container);
+ m_container->setWidget(widget);
+}
+
+template <class Container>
+void SingleChildContainer<Container>::insertWidget(int /* index */, QWidget *widget)
+{
+ addWidget(widget);
+}
+
+// ------------ QScrollAreaContainer
+class QScrollAreaContainer: public QObject, public SingleChildContainer<QScrollArea>
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QScrollAreaContainer(QScrollArea *widget, QObject *parent = 0);
+};
+
+// --------------- QDockWidgetContainer
+class QDockWidgetContainer: public QObject, public SingleChildContainer<QDockWidget>
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QDockWidgetContainer(QDockWidget *widget, QObject *parent = 0);
+};
+
+typedef ExtensionFactory<QDesignerContainerExtension, QStackedWidget, QStackedWidgetContainer> QDesignerStackedWidgetContainerFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QTabWidget, QTabWidgetContainer> QDesignerTabWidgetContainerFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QToolBox, QToolBoxContainer> QDesignerToolBoxContainerFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QScrollArea, QScrollAreaContainer> QScrollAreaContainerFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QDockWidget, QDockWidgetContainer> QDockWidgetContainerFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DEFAULT_CONTAINER_H
diff --git a/src/designer/src/components/formeditor/default_layoutdecoration.cpp b/src/designer/src/components/formeditor/default_layoutdecoration.cpp
new file mode 100644
index 000000000..95f190d5d
--- /dev/null
+++ b/src/designer/src/components/formeditor/default_layoutdecoration.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "default_layoutdecoration.h"
+#include "qlayout_widget_p.h"
+
+#include <layoutinfo_p.h>
+
+#include <QtDesigner/QDesignerMetaDataBaseItemInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ---- QDesignerLayoutDecorationFactory ----
+QDesignerLayoutDecorationFactory::QDesignerLayoutDecorationFactory(QExtensionManager *parent)
+ : QExtensionFactory(parent)
+{
+}
+
+QObject *QDesignerLayoutDecorationFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (!object->isWidgetType() || iid != Q_TYPEID(QDesignerLayoutDecorationExtension))
+ return 0;
+
+ QWidget *widget = qobject_cast<QWidget*>(object);
+
+ if (const QLayoutWidget *layoutWidget = qobject_cast<const QLayoutWidget*>(widget))
+ return QLayoutSupport::createLayoutSupport(layoutWidget->formWindow(), widget, parent);
+
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(widget))
+ if (LayoutInfo::managedLayout(fw->core(), widget))
+ return QLayoutSupport::createLayoutSupport(fw, widget, parent);
+
+ return 0;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/default_layoutdecoration.h b/src/designer/src/components/formeditor/default_layoutdecoration.h
new file mode 100644
index 000000000..ee876e88e
--- /dev/null
+++ b/src/designer/src/components/formeditor/default_layoutdecoration.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_LAYOUTDECORATION_H
+#define DEFAULT_LAYOUTDECORATION_H
+
+#include "formeditor_global.h"
+#include <QtDesigner/QDesignerLayoutDecorationExtension>
+#include <QtDesigner/default_extensionfactory.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+class QDesignerLayoutDecorationFactory: public QExtensionFactory
+{
+ Q_OBJECT
+ Q_INTERFACES(QAbstractExtensionFactory)
+public:
+ explicit QDesignerLayoutDecorationFactory(QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DEFAULT_LAYOUTDECORATION_H
diff --git a/src/designer/src/components/formeditor/defaultbrushes.xml b/src/designer/src/components/formeditor/defaultbrushes.xml
new file mode 100644
index 000000000..88035c3a6
--- /dev/null
+++ b/src/designer/src/components/formeditor/defaultbrushes.xml
@@ -0,0 +1,542 @@
+<brushes>
+ <description name="French" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="1" coordinatemode="StretchToDeviceMode" endy="0" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.323" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.343" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.656" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.676" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="German" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="0" coordinatemode="StretchToDeviceMode" endy="1" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.323" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.343" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.656" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.676" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Greek" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="0" coordinatemode="StretchToDeviceMode" endy="1" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.09" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.105" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.205" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.22" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.32" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.335" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.435" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.45" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.55" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.565" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.665" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.68" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.78" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.795" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.895" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.91" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>176</green>
+ <blue>221</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Italian" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="1" coordinatemode="StretchToDeviceMode" endy="0" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>60</red>
+ <green>160</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.323" >
+ <color alpha="255" >
+ <red>60</red>
+ <green>160</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.343" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.656" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.676" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Japanese" >
+ <brush brushstyle="RadialGradientPattern" >
+ <gradient focalx="0.5" focaly="0.5" radius="0.5" spread="PadSpread" type="RadialGradient" coordinatemode="StretchToDeviceMode" centralx="0.5" centraly="0.5" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.49" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.51" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Norwegian" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="1" coordinatemode="StretchToDeviceMode" endy="0" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.225" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.25" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.275" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.3" >
+ <color alpha="255" >
+ <red>5</red>
+ <green>0</green>
+ <blue>70</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.4" >
+ <color alpha="255" >
+ <red>5</red>
+ <green>0</green>
+ <blue>70</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.425" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.45" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.475" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Polish" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="0" coordinatemode="StretchToDeviceMode" endy="1" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.475" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.525" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="Spanish" >
+ <brush brushstyle="LinearGradientPattern" >
+ <gradient spread="PadSpread" startx="0" starty="0" type="LinearGradient" endx="0" coordinatemode="StretchToDeviceMode" endy="1" >
+ <gradientstop position="0" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.24" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.26" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.74" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="0.76" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ <gradientstop position="1" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </gradientstop>
+ </gradient>
+ </brush>
+ </description>
+ <description name="black" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="blue" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="cyan" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="green" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="magenta" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="red" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="white" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </description>
+ <description name="yellow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </description>
+</brushes>
diff --git a/src/designer/src/components/formeditor/deviceprofiledialog.cpp b/src/designer/src/components/formeditor/deviceprofiledialog.cpp
new file mode 100644
index 000000000..b7030689d
--- /dev/null
+++ b/src/designer/src/components/formeditor/deviceprofiledialog.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceprofiledialog.h"
+#include "ui_deviceprofiledialog.h"
+
+#include <abstractdialoggui_p.h>
+#include <deviceprofile_p.h>
+
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QFontDatabase>
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QFile>
+
+QT_BEGIN_NAMESPACE
+
+static const char *profileExtensionC = "qdp";
+
+static inline QString fileFilter()
+{
+ return qdesigner_internal::DeviceProfileDialog::tr("Device Profiles (*.%1)").arg(QLatin1String(profileExtensionC));
+}
+
+// Populate a combo with a sequence of integers, also set them as data.
+template <class IntIterator>
+ static void populateNumericCombo(IntIterator i1, IntIterator i2, QComboBox *cb)
+{
+ QString s;
+ cb->setEditable(false);
+ for ( ; i1 != i2 ; ++i1) {
+ const int n = *i1;
+ s.setNum(n);
+ cb->addItem(s, QVariant(n));
+ }
+}
+
+namespace qdesigner_internal {
+
+DeviceProfileDialog::DeviceProfileDialog(QDesignerDialogGuiInterface *dlgGui, QWidget *parent) :
+ QDialog(parent),
+ m_ui(new Ui::DeviceProfileDialog),
+ m_dlgGui(dlgGui)
+{
+ setModal(true);
+ m_ui->setupUi(this);
+
+ const QList<int> standardFontSizes = QFontDatabase::standardSizes();
+ populateNumericCombo(standardFontSizes.constBegin(), standardFontSizes.constEnd(), m_ui->m_systemFontSizeCombo);
+
+ // Styles
+ const QStringList styles = QStyleFactory::keys();
+ m_ui->m_styleCombo->addItem(tr("Default"), QVariant(QString()));
+ const QStringList::const_iterator cend = styles.constEnd();
+ for (QStringList::const_iterator it = styles.constBegin(); it != cend; ++it)
+ m_ui->m_styleCombo->addItem(*it, *it);
+
+ connect(m_ui->m_nameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(nameChanged(QString)));
+ connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(m_ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
+ // Note that Load/Save emit accepted() of the button box..
+ connect(m_ui->buttonBox->button(QDialogButtonBox::Save), SIGNAL(clicked()), this, SLOT(save()));
+ connect(m_ui->buttonBox->button(QDialogButtonBox::Open), SIGNAL(clicked()), this, SLOT(open()));
+}
+
+DeviceProfileDialog::~DeviceProfileDialog()
+{
+ delete m_ui;
+}
+
+DeviceProfile DeviceProfileDialog::deviceProfile() const
+{
+ DeviceProfile rc;
+ rc.setName(m_ui->m_nameLineEdit->text());
+ rc.setFontFamily(m_ui->m_systemFontComboBox->currentFont().family());
+ rc.setFontPointSize(m_ui->m_systemFontSizeCombo->itemData(m_ui->m_systemFontSizeCombo->currentIndex()).toInt());
+
+ int dpiX, dpiY;
+ m_ui->m_dpiChooser->getDPI(&dpiX, &dpiY);
+ rc.setDpiX(dpiX);
+ rc.setDpiY(dpiY);
+
+ rc.setStyle(m_ui->m_styleCombo->itemData(m_ui->m_styleCombo->currentIndex()).toString());
+
+ return rc;
+}
+
+void DeviceProfileDialog::setDeviceProfile(const DeviceProfile &s)
+{
+ m_ui->m_nameLineEdit->setText(s.name());
+ m_ui->m_systemFontComboBox->setCurrentFont(QFont(s.fontFamily()));
+ const int fontSizeIndex = m_ui->m_systemFontSizeCombo->findData(QVariant(s.fontPointSize()));
+ m_ui->m_systemFontSizeCombo->setCurrentIndex(fontSizeIndex != -1 ? fontSizeIndex : 0);
+ m_ui->m_dpiChooser->setDPI(s.dpiX(), s.dpiY());
+ const int styleIndex = m_ui->m_styleCombo->findData(s.style());
+ m_ui->m_styleCombo->setCurrentIndex(styleIndex != -1 ? styleIndex : 0);
+}
+
+void DeviceProfileDialog::setOkButtonEnabled(bool v)
+{
+ m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(v);
+}
+
+bool DeviceProfileDialog::showDialog(const QStringList &existingNames)
+{
+ m_existingNames = existingNames;
+ m_ui->m_nameLineEdit->setFocus(Qt::OtherFocusReason);
+ nameChanged(m_ui->m_nameLineEdit->text());
+ return exec() == Accepted;
+}
+
+void DeviceProfileDialog::nameChanged(const QString &name)
+{
+ const bool invalid = name.isEmpty() || m_existingNames.indexOf(name) != -1;
+ setOkButtonEnabled(!invalid);
+}
+
+void DeviceProfileDialog::save()
+{
+ QString fn = m_dlgGui->getSaveFileName(this, tr("Save Profile"), QString(), fileFilter());
+ if (fn.isEmpty())
+ return;
+ if (QFileInfo(fn).completeSuffix().isEmpty()) {
+ fn += QLatin1Char('.');
+ fn += QLatin1String(profileExtensionC);
+ }
+
+ QFile file(fn);
+ if (!file.open(QIODevice::WriteOnly|QIODevice::Text)) {
+ critical(tr("Save Profile - Error"), tr("Unable to open the file '%1' for writing: %2").arg(fn, file.errorString()));
+ return;
+ }
+ file.write(deviceProfile().toXml().toUtf8());
+}
+
+void DeviceProfileDialog::open()
+{
+ const QString fn = m_dlgGui->getOpenFileName(this, tr("Open profile"), QString(), fileFilter());
+ if (fn.isEmpty())
+ return;
+
+ QFile file(fn);
+ if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
+ critical(tr("Open Profile - Error"), tr("Unable to open the file '%1' for reading: %2").arg(fn, file.errorString()));
+ return;
+ }
+ QString errorMessage;
+ DeviceProfile newSettings;
+ if (!newSettings.fromXml(QString::fromUtf8(file.readAll()), &errorMessage)) {
+ critical(tr("Open Profile - Error"), tr("'%1' is not a valid profile: %2").arg(fn, errorMessage));
+ return;
+ }
+ setDeviceProfile(newSettings);
+}
+
+void DeviceProfileDialog::critical(const QString &title, const QString &msg)
+{
+ m_dlgGui->message(this, QDesignerDialogGuiInterface::OtherMessage, QMessageBox::Critical, title, msg);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/deviceprofiledialog.h b/src/designer/src/components/formeditor/deviceprofiledialog.h
new file mode 100644
index 000000000..e35f30077
--- /dev/null
+++ b/src/designer/src/components/formeditor/deviceprofiledialog.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SYSTEMSETTINGSDIALOG_H
+#define SYSTEMSETTINGSDIALOG_H
+
+#include <QtGui/QDialog>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class DeviceProfileDialog;
+}
+
+class QDesignerDialogGuiInterface;
+
+class QDialogButtonBox;
+
+namespace qdesigner_internal {
+
+class DeviceProfile;
+
+/* DeviceProfileDialog: Widget to edit system settings for embedded design */
+
+class DeviceProfileDialog : public QDialog
+{
+ Q_DISABLE_COPY(DeviceProfileDialog)
+ Q_OBJECT
+public:
+ explicit DeviceProfileDialog(QDesignerDialogGuiInterface *dlgGui, QWidget *parent = 0);
+ ~DeviceProfileDialog();
+
+ DeviceProfile deviceProfile() const;
+ void setDeviceProfile(const DeviceProfile &s);
+
+ bool showDialog(const QStringList &existingNames);
+
+private slots:
+ void setOkButtonEnabled(bool);
+ void nameChanged(const QString &name);
+ void save();
+ void open();
+
+private:
+ void critical(const QString &title, const QString &msg);
+ Ui::DeviceProfileDialog *m_ui;
+ QDesignerDialogGuiInterface *m_dlgGui;
+ QStringList m_existingNames;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // SYSTEMSETTINGSDIALOG_H
diff --git a/src/designer/src/components/formeditor/deviceprofiledialog.ui b/src/designer/src/components/formeditor/deviceprofiledialog.ui
new file mode 100644
index 000000000..d7a298c67
--- /dev/null
+++ b/src/designer/src/components/formeditor/deviceprofiledialog.ui
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DeviceProfileDialog</class>
+ <widget class="QDialog" name="dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>348</width>
+ <height>209</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QWidget" name="SystemSettingsWidget" native="true">
+ <layout class="QFormLayout" name="formLayout">
+ <item row="1" column="0">
+ <widget class="QLabel" name="m_systemFontFamilyLabel">
+ <property name="text">
+ <string>&amp;Family</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_systemFontComboBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QFontComboBox" name="m_systemFontComboBox"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="m_systemFontSizeLabel">
+ <property name="text">
+ <string>&amp;Point Size</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_systemFontSizeCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="m_systemFontSizeCombo"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="m_styleLabel">
+ <property name="text">
+ <string>Style</string>
+ </property>
+ <property name="buddy">
+ <cstring>m_styleCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="m_styleCombo"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="m_systemDPILabel">
+ <property name="text">
+ <string>Device DPI</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="qdesigner_internal::DPI_Chooser" name="m_dpiChooser" native="true"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_nameLabel">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="m_nameLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Open|QDialogButtonBox::Save</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>qdesigner_internal::DPI_Chooser</class>
+ <extends>QWidget</extends>
+ <header>dpi_chooser.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>m_nameLineEdit</tabstop>
+ <tabstop>m_systemFontComboBox</tabstop>
+ <tabstop>m_systemFontSizeCombo</tabstop>
+ <tabstop>m_styleCombo</tabstop>
+ <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/components/formeditor/dpi_chooser.cpp b/src/designer/src/components/formeditor/dpi_chooser.cpp
new file mode 100644
index 000000000..6d665dd79
--- /dev/null
+++ b/src/designer/src/components/formeditor/dpi_chooser.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "dpi_chooser.h"
+
+#include <deviceprofile_p.h>
+
+#include <QtGui/QComboBox>
+#include <QtGui/QSpinBox>
+#include <QtGui/QLabel>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QCheckBox>
+
+QT_BEGIN_NAMESPACE
+
+enum { minDPI = 50, maxDPI = 400 };
+
+namespace qdesigner_internal {
+
+// Entry struct for predefined values
+struct DPI_Entry {
+ int dpiX;
+ int dpiY;
+ const char *description;
+};
+
+const struct DPI_Entry dpiEntries[] = {
+ //: Embedded device standard screen resolution
+ { 96, 96, QT_TRANSLATE_NOOP("DPI_Chooser", "Standard (96 x 96)") },
+ //: Embedded device screen resolution
+ { 179, 185, QT_TRANSLATE_NOOP("DPI_Chooser", "Greenphone (179 x 185)") },
+ //: Embedded device high definition screen resolution
+ { 192, 192, QT_TRANSLATE_NOOP("DPI_Chooser", "High (192 x 192)") }
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(const struct qdesigner_internal::DPI_Entry*);
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ------------- DPI_Chooser
+
+DPI_Chooser::DPI_Chooser(QWidget *parent) :
+ QWidget(parent),
+ m_systemEntry(new DPI_Entry),
+ m_predefinedCombo(new QComboBox),
+ m_dpiXSpinBox(new QSpinBox),
+ m_dpiYSpinBox(new QSpinBox)
+{
+ // Predefined settings: System
+ DeviceProfile::systemResolution(&(m_systemEntry->dpiX), &(m_systemEntry->dpiY));
+ m_systemEntry->description = 0;
+ const struct DPI_Entry *systemEntry = m_systemEntry;
+ //: System resolution
+ m_predefinedCombo->addItem(tr("System (%1 x %2)").arg(m_systemEntry->dpiX).arg(m_systemEntry->dpiY), QVariant::fromValue(systemEntry));
+ // Devices. Exclude the system values as not to duplicate the entries
+ const int predefinedCount = sizeof(dpiEntries)/sizeof(DPI_Entry);
+ const struct DPI_Entry *ecend = dpiEntries + predefinedCount;
+ for (const struct DPI_Entry *it = dpiEntries; it < ecend; ++it)
+ if (it->dpiX != m_systemEntry->dpiX || it->dpiY != m_systemEntry->dpiY)
+ m_predefinedCombo->addItem(tr(it->description), QVariant::fromValue(it));
+ m_predefinedCombo->addItem(tr("User defined"));
+
+ setFocusProxy(m_predefinedCombo);
+ m_predefinedCombo->setEditable(false);
+ m_predefinedCombo->setCurrentIndex(0);
+ connect(m_predefinedCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(syncSpinBoxes()));
+ // top row with predefined settings
+ QVBoxLayout *vBoxLayout = new QVBoxLayout;
+ vBoxLayout->setMargin(0);
+ vBoxLayout->addWidget(m_predefinedCombo);
+ // Spin box row
+ QHBoxLayout *hBoxLayout = new QHBoxLayout;
+ hBoxLayout->setMargin(0);
+
+ m_dpiXSpinBox->setMinimum(minDPI);
+ m_dpiXSpinBox->setMaximum(maxDPI);
+ hBoxLayout->addWidget(m_dpiXSpinBox);
+ //: DPI X/Y separator
+ hBoxLayout->addWidget(new QLabel(tr(" x ")));
+
+ m_dpiYSpinBox->setMinimum(minDPI);
+ m_dpiYSpinBox->setMaximum(maxDPI);
+ hBoxLayout->addWidget(m_dpiYSpinBox);
+
+ hBoxLayout->addStretch();
+ vBoxLayout->addLayout(hBoxLayout);
+ setLayout(vBoxLayout);
+
+ syncSpinBoxes();
+}
+
+DPI_Chooser::~DPI_Chooser()
+{
+ delete m_systemEntry;
+}
+
+void DPI_Chooser::getDPI(int *dpiX, int *dpiY) const
+{
+ *dpiX = m_dpiXSpinBox->value();
+ *dpiY = m_dpiYSpinBox->value();
+}
+
+void DPI_Chooser::setDPI(int dpiX, int dpiY)
+{
+ // Default to system if it is something weird
+ const bool valid = dpiX >= minDPI && dpiX <= maxDPI && dpiY >= minDPI && dpiY <= maxDPI;
+ if (!valid) {
+ m_predefinedCombo->setCurrentIndex(0);
+ return;
+ }
+ // Try to find the values among the predefined settings
+ const int count = m_predefinedCombo->count();
+ int predefinedIndex = -1;
+ for (int i = 0; i < count; i++) {
+ const QVariant data = m_predefinedCombo->itemData(i);
+ if (data.type() != QVariant::Invalid) {
+ const struct DPI_Entry *entry = qvariant_cast<const struct DPI_Entry *>(data);
+ if (entry->dpiX == dpiX && entry->dpiY == dpiY) {
+ predefinedIndex = i;
+ break;
+ }
+ }
+ }
+ if (predefinedIndex != -1) {
+ m_predefinedCombo->setCurrentIndex(predefinedIndex); // triggers syncSpinBoxes()
+ } else {
+ setUserDefinedValues(dpiX, dpiY);
+ }
+}
+
+void DPI_Chooser::setUserDefinedValues(int dpiX, int dpiY)
+{
+ const bool blocked = m_predefinedCombo->blockSignals(true);
+ m_predefinedCombo->setCurrentIndex(m_predefinedCombo->count() - 1);
+ m_predefinedCombo->blockSignals(blocked);
+
+ m_dpiXSpinBox->setEnabled(true);
+ m_dpiYSpinBox->setEnabled(true);
+ m_dpiXSpinBox->setValue(dpiX);
+ m_dpiYSpinBox->setValue(dpiY);
+}
+
+void DPI_Chooser::syncSpinBoxes()
+{
+ const int predefIdx = m_predefinedCombo->currentIndex();
+ const QVariant data = m_predefinedCombo->itemData(predefIdx);
+
+ // Predefined mode in which spin boxes are disabled or user defined?
+ const bool userSetting = data.type() == QVariant::Invalid;
+ m_dpiXSpinBox->setEnabled(userSetting);
+ m_dpiYSpinBox->setEnabled(userSetting);
+
+ if (!userSetting) {
+ const struct DPI_Entry *entry = qvariant_cast<const struct DPI_Entry *>(data);
+ m_dpiXSpinBox->setValue(entry->dpiX);
+ m_dpiYSpinBox->setValue(entry->dpiY);
+ }
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/dpi_chooser.h b/src/designer/src/components/formeditor/dpi_chooser.h
new file mode 100644
index 000000000..10e3c72d8
--- /dev/null
+++ b/src/designer/src/components/formeditor/dpi_chooser.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef DPICHOOSER_H
+#define DPICHOOSER_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QSpinBox;
+class QComboBox;
+
+namespace qdesigner_internal {
+
+struct DPI_Entry;
+
+/* Let the user choose a DPI settings */
+class DPI_Chooser : public QWidget {
+ Q_DISABLE_COPY(DPI_Chooser)
+ Q_OBJECT
+
+public:
+ explicit DPI_Chooser(QWidget *parent = 0);
+ ~DPI_Chooser();
+
+ void getDPI(int *dpiX, int *dpiY) const;
+ void setDPI(int dpiX, int dpiY);
+
+private slots:
+ void syncSpinBoxes();
+
+private:
+ void setUserDefinedValues(int dpiX, int dpiY);
+
+ struct DPI_Entry *m_systemEntry;
+ QComboBox *m_predefinedCombo;
+ QSpinBox *m_dpiXSpinBox;
+ QSpinBox *m_dpiYSpinBox;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // DPICHOOSER_H
diff --git a/src/designer/src/components/formeditor/embeddedoptionspage.cpp b/src/designer/src/components/formeditor/embeddedoptionspage.cpp
new file mode 100644
index 000000000..10f4509df
--- /dev/null
+++ b/src/designer/src/components/formeditor/embeddedoptionspage.cpp
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "embeddedoptionspage.h"
+#include "deviceprofiledialog.h"
+#include "widgetfactory_p.h"
+#include "formwindowmanager.h"
+
+#include <deviceprofile_p.h>
+#include <iconloader_p.h>
+#include <shared_settings_p.h>
+#include <abstractdialoggui_p.h>
+#include <formwindowbase_p.h>
+
+
+// SDK
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+#include <QtGui/QLabel>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QApplication>
+#include <QtGui/QComboBox>
+#include <QtGui/QToolButton>
+#include <QtGui/QMessageBox>
+#include <QtGui/QLabel>
+#include <QtGui/QGroupBox>
+
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+typedef QList<DeviceProfile> DeviceProfileList;
+
+enum { profileComboIndexOffset = 1 };
+
+// Sort by name. Used by template, do not make it static!
+bool deviceProfileLessThan(const DeviceProfile &d1, const DeviceProfile &d2)
+{
+ return d1.name().toLower() < d2.name().toLower();
+}
+
+static bool ask(QWidget *parent,
+ QDesignerDialogGuiInterface *dlgui,
+ const QString &title,
+ const QString &what)
+{
+ return dlgui->message(parent, QDesignerDialogGuiInterface::OtherMessage,
+ QMessageBox::Question, title, what,
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::Yes;
+}
+
+// ------------ EmbeddedOptionsControlPrivate
+class EmbeddedOptionsControlPrivate {
+ Q_DISABLE_COPY(EmbeddedOptionsControlPrivate)
+public:
+ EmbeddedOptionsControlPrivate(QDesignerFormEditorInterface *core);
+ void init(EmbeddedOptionsControl *q);
+
+ bool isDirty() const { return m_dirty; }
+
+ void loadSettings();
+ void saveSettings();
+ void slotAdd();
+ void slotEdit();
+ void slotDelete();
+ void slotProfileIndexChanged(int);
+
+private:
+ QStringList existingProfileNames() const;
+ void sortAndPopulateProfileCombo();
+ void updateState();
+ void updateDescriptionLabel();
+
+ QDesignerFormEditorInterface *m_core;
+ QComboBox *m_profileCombo;
+ QToolButton *m_addButton;
+ QToolButton *m_editButton;
+ QToolButton *m_deleteButton;
+ QLabel *m_descriptionLabel;
+
+ DeviceProfileList m_sortedProfiles;
+ EmbeddedOptionsControl *m_q;
+ bool m_dirty;
+ QSet<QString> m_usedProfiles;
+};
+
+EmbeddedOptionsControlPrivate::EmbeddedOptionsControlPrivate(QDesignerFormEditorInterface *core) :
+ m_core(core),
+ m_profileCombo(new QComboBox),
+ m_addButton(new QToolButton),
+ m_editButton(new QToolButton),
+ m_deleteButton(new QToolButton),
+ m_descriptionLabel(new QLabel),
+ m_q(0),
+ m_dirty(false)
+{
+ m_descriptionLabel->setMinimumHeight(80);
+ // Determine used profiles to lock them
+ const QDesignerFormWindowManagerInterface *fwm = core->formWindowManager();
+ if (const int fwCount = fwm->formWindowCount()) {
+ for (int i = 0; i < fwCount; i++)
+ if (const FormWindowBase *fwb = qobject_cast<const FormWindowBase *>(fwm->formWindow(i))) {
+ const QString deviceProfileName = fwb->deviceProfileName();
+ if (!deviceProfileName.isEmpty())
+ m_usedProfiles.insert(deviceProfileName);
+ }
+ }
+}
+
+void EmbeddedOptionsControlPrivate::init(EmbeddedOptionsControl *q)
+{
+ m_q = q;
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ m_profileCombo->setMinimumWidth(200);
+ m_profileCombo->setEditable(false);
+ hLayout->addWidget(m_profileCombo);
+ m_profileCombo->addItem(EmbeddedOptionsControl::tr("None"));
+ EmbeddedOptionsControl::connect(m_profileCombo, SIGNAL(currentIndexChanged(int)), m_q, SLOT(slotProfileIndexChanged(int)));
+
+ m_addButton->setIcon(createIconSet(QString::fromUtf8("plus.png")));
+ m_addButton->setToolTip(EmbeddedOptionsControl::tr("Add a profile"));
+ EmbeddedOptionsControl::connect(m_addButton, SIGNAL(clicked()), m_q, SLOT(slotAdd()));
+ hLayout->addWidget(m_addButton);
+
+ EmbeddedOptionsControl::connect(m_editButton, SIGNAL(clicked()), m_q, SLOT(slotEdit()));
+ m_editButton->setIcon(createIconSet(QString::fromUtf8("edit.png")));
+ m_editButton->setToolTip(EmbeddedOptionsControl::tr("Edit the selected profile"));
+ hLayout->addWidget(m_editButton);
+
+ m_deleteButton->setIcon(createIconSet(QString::fromUtf8("minus.png")));
+ m_deleteButton->setToolTip(EmbeddedOptionsControl::tr("Delete the selected profile"));
+ EmbeddedOptionsControl::connect(m_deleteButton, SIGNAL(clicked()), m_q, SLOT(slotDelete()));
+ hLayout->addWidget(m_deleteButton);
+
+ hLayout->addStretch();
+ vLayout->addLayout(hLayout);
+ vLayout->addWidget(m_descriptionLabel);
+ m_q->setLayout(vLayout);
+}
+
+QStringList EmbeddedOptionsControlPrivate::existingProfileNames() const
+{
+ QStringList rc;
+ const DeviceProfileList::const_iterator dcend = m_sortedProfiles.constEnd();
+ for (DeviceProfileList::const_iterator it = m_sortedProfiles.constBegin(); it != dcend; ++it)
+ rc.push_back(it->name());
+ return rc;
+}
+
+void EmbeddedOptionsControlPrivate::slotAdd()
+{
+ DeviceProfileDialog dlg(m_core->dialogGui(), m_q);
+ dlg.setWindowTitle(EmbeddedOptionsControl::tr("Add Profile"));
+ // Create a new profile with a new, unique name
+ DeviceProfile settings;
+ settings.fromSystem();
+ dlg.setDeviceProfile(settings);
+
+ const QStringList names = existingProfileNames();
+ const QString newNamePrefix = EmbeddedOptionsControl::tr("New profile");
+ QString newName = newNamePrefix;
+ for (int i = 2; names.contains(newName); i++) {
+ newName = newNamePrefix;
+ newName += QString::number(i);
+ }
+
+ settings.setName(newName);
+ dlg.setDeviceProfile(settings);
+ if (dlg.showDialog(names)) {
+ const DeviceProfile newProfile = dlg.deviceProfile();
+ m_sortedProfiles.push_back(newProfile);
+ // Maintain sorted order
+ sortAndPopulateProfileCombo();
+ const int index = m_profileCombo->findText(newProfile.name());
+ m_profileCombo->setCurrentIndex(index);
+ m_dirty = true;
+ }
+}
+
+void EmbeddedOptionsControlPrivate::slotEdit()
+{
+ const int index = m_profileCombo->currentIndex() - profileComboIndexOffset;
+ if (index < 0)
+ return;
+
+ // Edit the profile, compile a list of existing names
+ // excluding current one. re-insert if changed,
+ // re-sort if name changed.
+ const DeviceProfile oldProfile = m_sortedProfiles.at(index);
+ const QString oldName = oldProfile.name();
+ QStringList names = existingProfileNames();
+ names.removeAll(oldName);
+
+ DeviceProfileDialog dlg(m_core->dialogGui(), m_q);
+ dlg.setWindowTitle(EmbeddedOptionsControl::tr("Edit Profile"));
+ dlg.setDeviceProfile(oldProfile);
+ if (dlg.showDialog(names)) {
+ const DeviceProfile newProfile = dlg.deviceProfile();
+ if (newProfile != oldProfile) {
+ m_dirty = true;
+ m_sortedProfiles[index] = newProfile;
+ if (newProfile.name() != oldName) {
+ sortAndPopulateProfileCombo();
+ const int index = m_profileCombo->findText(newProfile.name());
+ m_profileCombo->setCurrentIndex(index);
+ } else {
+ updateDescriptionLabel();
+ }
+
+ }
+ }
+}
+
+void EmbeddedOptionsControlPrivate::slotDelete()
+{
+ const int index = m_profileCombo->currentIndex() - profileComboIndexOffset;
+ if (index < 0)
+ return;
+ const QString name = m_sortedProfiles.at(index).name();
+ if (ask(m_q, m_core->dialogGui(),
+ EmbeddedOptionsControl::tr("Delete Profile"),
+ EmbeddedOptionsControl::tr("Would you like to delete the profile '%1'?").arg(name))) {
+ m_profileCombo->setCurrentIndex(0);
+ m_sortedProfiles.removeAt(index);
+ m_profileCombo->removeItem(index + profileComboIndexOffset);
+ m_dirty = true;
+ }
+}
+
+void EmbeddedOptionsControlPrivate::sortAndPopulateProfileCombo()
+{
+ // Clear items until only "None" is left
+ for (int i = m_profileCombo->count() - 1; i > 0; i--)
+ m_profileCombo->removeItem(i);
+ if (!m_sortedProfiles.empty()) {
+ qSort(m_sortedProfiles.begin(), m_sortedProfiles.end(), deviceProfileLessThan);
+ m_profileCombo->addItems(existingProfileNames());
+ }
+}
+
+void EmbeddedOptionsControlPrivate::loadSettings()
+{
+ const QDesignerSharedSettings settings(m_core);
+ m_sortedProfiles = settings.deviceProfiles();
+ sortAndPopulateProfileCombo();
+ // Index: 0 is "None"
+ const int settingsIndex = settings.currentDeviceProfileIndex();
+ const int profileIndex = settingsIndex >= 0 && settingsIndex < m_sortedProfiles.size() ? settingsIndex + profileComboIndexOffset : 0;
+ m_profileCombo->setCurrentIndex(profileIndex);
+ updateState();
+ m_dirty = false;
+}
+
+void EmbeddedOptionsControlPrivate::saveSettings()
+{
+ QDesignerSharedSettings settings(m_core);
+ settings.setDeviceProfiles(m_sortedProfiles);
+ // Index: 0 is "None"
+ settings.setCurrentDeviceProfileIndex(m_profileCombo->currentIndex() - profileComboIndexOffset);
+ m_dirty = false;
+}
+
+//: Format embedded device profile description
+static const char *descriptionFormat = QT_TRANSLATE_NOOP("EmbeddedOptionsControl",
+"<html>"
+"<table>"
+"<tr><td><b>Font</b></td><td>%1, %2</td></tr>"
+"<tr><td><b>Style</b></td><td>%3</td></tr>"
+"<tr><td><b>Resolution</b></td><td>%4 x %5</td></tr>"
+"</table>"
+"</html>");
+
+static inline QString description(const DeviceProfile& p)
+{
+ QString styleName = p.style();
+ if (styleName.isEmpty())
+ styleName = EmbeddedOptionsControl::tr("Default");
+ return EmbeddedOptionsControl::tr(descriptionFormat).
+ arg(p.fontFamily()).arg(p.fontPointSize()).arg(styleName).arg(p.dpiX()).arg(p.dpiY());
+}
+
+void EmbeddedOptionsControlPrivate::updateDescriptionLabel()
+{
+ const int profileIndex = m_profileCombo->currentIndex() - profileComboIndexOffset;
+ if (profileIndex >= 0) {
+ m_descriptionLabel->setText(description(m_sortedProfiles.at(profileIndex)));
+ } else {
+ m_descriptionLabel->clear();
+ }
+}
+
+void EmbeddedOptionsControlPrivate::updateState()
+{
+ const int profileIndex = m_profileCombo->currentIndex() - profileComboIndexOffset;
+ // Allow for changing/deleting only if it is not in use
+ bool modifyEnabled = false;
+ if (profileIndex >= 0)
+ modifyEnabled = !m_usedProfiles.contains(m_sortedProfiles.at(profileIndex).name());
+ m_editButton->setEnabled(modifyEnabled);
+ m_deleteButton->setEnabled(modifyEnabled);
+ updateDescriptionLabel();
+}
+
+void EmbeddedOptionsControlPrivate::slotProfileIndexChanged(int)
+{
+ updateState();
+ m_dirty = true;
+}
+
+// ------------- EmbeddedOptionsControl
+EmbeddedOptionsControl::EmbeddedOptionsControl(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QWidget(parent),
+ m_d(new EmbeddedOptionsControlPrivate(core))
+{
+ m_d->init(this);
+}
+
+EmbeddedOptionsControl::~EmbeddedOptionsControl()
+{
+ delete m_d;
+}
+
+void EmbeddedOptionsControl::slotAdd()
+{
+ m_d->slotAdd();
+}
+
+void EmbeddedOptionsControl::slotEdit()
+{
+ m_d->slotEdit();
+}
+
+void EmbeddedOptionsControl::slotDelete()
+{
+ m_d->slotDelete();
+}
+
+void EmbeddedOptionsControl::loadSettings()
+{
+ m_d->loadSettings();
+}
+
+void EmbeddedOptionsControl::saveSettings()
+{
+ m_d->saveSettings();
+}
+
+void EmbeddedOptionsControl::slotProfileIndexChanged(int i)
+{
+ m_d->slotProfileIndexChanged(i);
+}
+
+bool EmbeddedOptionsControl::isDirty() const
+{
+ return m_d->isDirty();
+}
+
+// EmbeddedOptionsPage:
+EmbeddedOptionsPage::EmbeddedOptionsPage(QDesignerFormEditorInterface *core) :
+ m_core(core)
+{
+}
+
+QString EmbeddedOptionsPage::name() const
+{
+ //: Tab in preferences dialog
+ return QCoreApplication::translate("EmbeddedOptionsPage", "Embedded Design");
+}
+
+QWidget *EmbeddedOptionsPage::createPage(QWidget *parent)
+{
+ QWidget *optionsWidget = new QWidget(parent);
+
+ QVBoxLayout *optionsVLayout = new QVBoxLayout();
+
+ //: EmbeddedOptionsControl group box"
+ QGroupBox *gb = new QGroupBox(QCoreApplication::translate("EmbeddedOptionsPage", "Device Profiles"));
+ QVBoxLayout *gbVLayout = new QVBoxLayout();
+ m_embeddedOptionsControl = new EmbeddedOptionsControl(m_core);
+ m_embeddedOptionsControl->loadSettings();
+ gbVLayout->addWidget(m_embeddedOptionsControl);
+ gb->setLayout(gbVLayout);
+ optionsVLayout->addWidget(gb);
+
+ optionsVLayout->addStretch(1);
+
+ // Outer layout to give it horizontal stretch
+ QHBoxLayout *optionsHLayout = new QHBoxLayout();
+ optionsHLayout->addLayout(optionsVLayout);
+ optionsHLayout->addStretch(1);
+ optionsWidget->setLayout(optionsHLayout);
+ return optionsWidget;
+}
+
+void EmbeddedOptionsPage::apply()
+{
+ if (!m_embeddedOptionsControl || !m_embeddedOptionsControl->isDirty())
+ return;
+
+ m_embeddedOptionsControl->saveSettings();
+ if (FormWindowManager *fw = qobject_cast<qdesigner_internal::FormWindowManager *>(m_core->formWindowManager()))
+ fw->deviceProfilesChanged();
+}
+
+void EmbeddedOptionsPage::finish()
+{
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/embeddedoptionspage.h b/src/designer/src/components/formeditor/embeddedoptionspage.h
new file mode 100644
index 000000000..7947c3790
--- /dev/null
+++ b/src/designer/src/components/formeditor/embeddedoptionspage.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EMBEDDEDOPTIONSPAGE_H
+#define EMBEDDEDOPTIONSPAGE_H
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class EmbeddedOptionsControlPrivate;
+
+/* EmbeddedOptions Control. Presents the user with a list of embedded
+ * device profiles he can modify/add/delete. */
+class EmbeddedOptionsControl : public QWidget {
+ Q_DISABLE_COPY(EmbeddedOptionsControl)
+ Q_OBJECT
+public:
+ explicit EmbeddedOptionsControl(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ ~EmbeddedOptionsControl();
+
+ bool isDirty() const;
+
+public slots:
+ void loadSettings();
+ void saveSettings();
+
+private slots:
+ void slotAdd();
+ void slotEdit();
+ void slotDelete();
+ void slotProfileIndexChanged(int);
+
+private:
+ EmbeddedOptionsControlPrivate *m_d;
+};
+
+// EmbeddedOptionsPage
+class EmbeddedOptionsPage : public QDesignerOptionsPageInterface
+{
+ Q_DISABLE_COPY(EmbeddedOptionsPage)
+public:
+ explicit EmbeddedOptionsPage(QDesignerFormEditorInterface *core);
+
+ QString name() const;
+ QWidget *createPage(QWidget *parent);
+ virtual void finish();
+ virtual void apply();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ QPointer<EmbeddedOptionsControl> m_embeddedOptionsControl;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // EMBEDDEDOPTIONSPAGE_H
diff --git a/src/designer/src/components/formeditor/formeditor.cpp b/src/designer/src/components/formeditor/formeditor.cpp
new file mode 100644
index 000000000..847b99de3
--- /dev/null
+++ b/src/designer/src/components/formeditor/formeditor.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formeditor.h"
+#include "formeditor_optionspage.h"
+#include "embeddedoptionspage.h"
+#include "templateoptionspage.h"
+#include "metadatabase_p.h"
+#include "widgetdatabase_p.h"
+#include "widgetfactory_p.h"
+#include "formwindowmanager.h"
+#include "qmainwindow_container.h"
+#include "qworkspace_container.h"
+#include "qmdiarea_container.h"
+#include "qwizard_container.h"
+#include "default_container.h"
+#include "default_layoutdecoration.h"
+#include "default_actionprovider.h"
+#include "qlayoutwidget_propertysheet.h"
+#include "spacer_propertysheet.h"
+#include "line_propertysheet.h"
+#include "layout_propertysheet.h"
+#include "qdesigner_stackedbox_p.h"
+#include "qdesigner_toolbox_p.h"
+#include "qdesigner_tabwidget_p.h"
+#include "qtbrushmanager.h"
+#include "brushmanagerproxy.h"
+#include "iconcache.h"
+#include "qtresourcemodel_p.h"
+#include "qdesigner_integration_p.h"
+#include "itemview_propertysheet.h"
+
+// sdk
+#include <QtDesigner/QExtensionManager>
+
+// shared
+#include <pluginmanager_p.h>
+#include <qdesigner_taskmenu_p.h>
+#include <qdesigner_membersheet_p.h>
+#include <qdesigner_promotion_p.h>
+#include <dialoggui_p.h>
+#include <qdesigner_introspection_p.h>
+#include <qdesigner_qsettings_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+FormEditor::FormEditor(QObject *parent)
+ : QDesignerFormEditorInterface(parent)
+{
+ setIntrospection(new QDesignerIntrospection);
+ setDialogGui(new DialogGui);
+ QDesignerPluginManager *pluginManager = new QDesignerPluginManager(this);
+ setPluginManager(pluginManager);
+
+ WidgetDataBase *widgetDatabase = new WidgetDataBase(this, this);
+ setWidgetDataBase(widgetDatabase);
+
+ MetaDataBase *metaDataBase = new MetaDataBase(this, this);
+ setMetaDataBase(metaDataBase);
+
+ WidgetFactory *widgetFactory = new WidgetFactory(this, this);
+ setWidgetFactory(widgetFactory);
+
+ FormWindowManager *formWindowManager = new FormWindowManager(this, this);
+ setFormManager(formWindowManager);
+ connect(formWindowManager, SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)), widgetFactory, SLOT(formWindowAdded(QDesignerFormWindowInterface*)));
+ connect(formWindowManager, SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)), widgetFactory, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface*)));
+
+ QExtensionManager *mgr = new QExtensionManager(this);
+ const QString containerExtensionId = Q_TYPEID(QDesignerContainerExtension);
+
+ QDesignerStackedWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
+ QDesignerTabWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
+ QDesignerToolBoxContainerFactory::registerExtension(mgr, containerExtensionId);
+ QMainWindowContainerFactory::registerExtension(mgr, containerExtensionId);
+ QDockWidgetContainerFactory::registerExtension(mgr, containerExtensionId);
+ QScrollAreaContainerFactory::registerExtension(mgr, containerExtensionId);
+ QWorkspaceContainerFactory::registerExtension(mgr, containerExtensionId);
+ QMdiAreaContainerFactory::registerExtension(mgr, containerExtensionId);
+ QWizardContainerFactory::registerExtension(mgr, containerExtensionId);
+
+ mgr->registerExtensions(new QDesignerLayoutDecorationFactory(mgr),
+ Q_TYPEID(QDesignerLayoutDecorationExtension));
+
+ const QString actionProviderExtensionId = Q_TYPEID(QDesignerActionProviderExtension);
+ QToolBarActionProviderFactory::registerExtension(mgr, actionProviderExtensionId);
+ QMenuBarActionProviderFactory::registerExtension(mgr, actionProviderExtensionId);
+ QMenuActionProviderFactory::registerExtension(mgr, actionProviderExtensionId);
+
+ QDesignerDefaultPropertySheetFactory::registerExtension(mgr);
+ QLayoutWidgetPropertySheetFactory::registerExtension(mgr);
+ SpacerPropertySheetFactory::registerExtension(mgr);
+ LinePropertySheetFactory::registerExtension(mgr);
+ LayoutPropertySheetFactory::registerExtension(mgr);
+ QStackedWidgetPropertySheetFactory::registerExtension(mgr);
+ QToolBoxWidgetPropertySheetFactory::registerExtension(mgr);
+ QTabWidgetPropertySheetFactory::registerExtension(mgr);
+ QMdiAreaPropertySheetFactory::registerExtension(mgr);
+ QWorkspacePropertySheetFactory::registerExtension(mgr);
+ QWizardPagePropertySheetFactory::registerExtension(mgr);
+ QWizardPropertySheetFactory::registerExtension(mgr);
+
+ QTreeViewPropertySheetFactory::registerExtension(mgr);
+ QTableViewPropertySheetFactory::registerExtension(mgr);
+
+ const QString internalTaskMenuId = QLatin1String("QDesignerInternalTaskMenuExtension");
+ QDesignerTaskMenuFactory::registerExtension(mgr, internalTaskMenuId);
+
+ mgr->registerExtensions(new QDesignerMemberSheetFactory(mgr),
+ Q_TYPEID(QDesignerMemberSheetExtension));
+
+ setExtensionManager(mgr);
+
+ setIconCache(new IconCache(this));
+
+ QtBrushManager *brushManager = new QtBrushManager(this);
+ setBrushManager(brushManager);
+
+ BrushManagerProxy *brushProxy = new BrushManagerProxy(this, this);
+ brushProxy->setBrushManager(brushManager);
+ setPromotion(new QDesignerPromotion(this));
+
+ QtResourceModel *resourceModel = new QtResourceModel(this);
+ setResourceModel(resourceModel);
+ connect(resourceModel, SIGNAL(qrcFileModifiedExternally(QString)),
+ this, SLOT(slotQrcFileChangedExternally(QString)));
+
+ QList<QDesignerOptionsPageInterface*> optionsPages;
+ optionsPages << new TemplateOptionsPage(this) << new FormEditorOptionsPage(this) << new EmbeddedOptionsPage(this);
+ setOptionsPages(optionsPages);
+
+ setSettingsManager(new QDesignerQSettings());
+}
+
+FormEditor::~FormEditor()
+{
+}
+
+void FormEditor::slotQrcFileChangedExternally(const QString &path)
+{
+ QDesignerIntegration *designerIntegration = qobject_cast<QDesignerIntegration *>(integration());
+ if (!designerIntegration)
+ return;
+
+ QDesignerIntegration::ResourceFileWatcherBehaviour behaviour = designerIntegration->resourceFileWatcherBehaviour();
+ if (behaviour == QDesignerIntegration::NoWatcher) {
+ return;
+ } else if (behaviour == QDesignerIntegration::PromptAndReload) {
+ QMessageBox::StandardButton button = dialogGui()->message(topLevel(), QDesignerDialogGuiInterface::FileChangedMessage, QMessageBox::Warning,
+ tr("Resource File Changed"),
+ tr("The file \"%1\" has changed outside Designer. Do you want to reload it?").arg(path),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+ if (button != QMessageBox::Yes)
+ return;
+ }
+
+ resourceModel()->reload(path);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/formeditor.h b/src/designer/src/components/formeditor/formeditor.h
new file mode 100644
index 000000000..88c24b84e
--- /dev/null
+++ b/src/designer/src/components/formeditor/formeditor.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMEDITOR_H
+#define FORMEDITOR_H
+
+#include "formeditor_global.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+
+namespace qdesigner_internal {
+
+class QT_FORMEDITOR_EXPORT FormEditor: public QDesignerFormEditorInterface
+{
+ Q_OBJECT
+public:
+ FormEditor(QObject *parent = 0);
+ virtual ~FormEditor();
+public slots:
+ void slotQrcFileChangedExternally(const QString &path);
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMEDITOR_H
diff --git a/src/designer/src/components/formeditor/formeditor.pri b/src/designer/src/components/formeditor/formeditor.pri
new file mode 100644
index 000000000..b1a93188a
--- /dev/null
+++ b/src/designer/src/components/formeditor/formeditor.pri
@@ -0,0 +1,77 @@
+
+QT += xml
+
+INCLUDEPATH += $$PWD
+
+FORMS += $$PWD/deviceprofiledialog.ui \
+ $$PWD/formwindowsettings.ui \
+ $$PWD/templateoptionspage.ui
+
+HEADERS += $$PWD/qdesigner_resource.h \
+ $$PWD/qdesignerundostack.h \
+ $$PWD/formwindow.h \
+ $$PWD/formwindow_widgetstack.h \
+ $$PWD/formwindow_dnditem.h \
+ $$PWD/formwindowcursor.h \
+ $$PWD/widgetselection.h \
+ $$PWD/formwindowmanager.h \
+ $$PWD/formeditor.h \
+ $$PWD/formeditor_global.h \
+ $$PWD/qlayoutwidget_propertysheet.h \
+ $$PWD/layout_propertysheet.h \
+ $$PWD/spacer_propertysheet.h \
+ $$PWD/line_propertysheet.h \
+ $$PWD/default_container.h \
+ $$PWD/default_actionprovider.h \
+ $$PWD/qmainwindow_container.h \
+ $$PWD/qworkspace_container.h \
+ $$PWD/qmdiarea_container.h \
+ $$PWD/qwizard_container.h \
+ $$PWD/default_layoutdecoration.h \
+ $$PWD/qtbrushmanager.h \
+ $$PWD/brushmanagerproxy.h \
+ $$PWD/iconcache.h \
+ $$PWD/tool_widgeteditor.h \
+ $$PWD/formeditor_optionspage.h \
+ $$PWD/embeddedoptionspage.h \
+ $$PWD/formwindowsettings.h \
+ $$PWD/deviceprofiledialog.h \
+ $$PWD/dpi_chooser.h \
+ $$PWD/previewactiongroup.h \
+ $$PWD/itemview_propertysheet.h \
+ $$PWD/templateoptionspage.h
+
+SOURCES += $$PWD/qdesigner_resource.cpp \
+ $$PWD/qdesignerundostack.cpp \
+ $$PWD/formwindow.cpp \
+ $$PWD/formwindow_widgetstack.cpp \
+ $$PWD/formwindow_dnditem.cpp \
+ $$PWD/formwindowcursor.cpp \
+ $$PWD/widgetselection.cpp \
+ $$PWD/formwindowmanager.cpp \
+ $$PWD/formeditor.cpp \
+ $$PWD/qlayoutwidget_propertysheet.cpp \
+ $$PWD/layout_propertysheet.cpp \
+ $$PWD/spacer_propertysheet.cpp \
+ $$PWD/line_propertysheet.cpp \
+ $$PWD/qmainwindow_container.cpp \
+ $$PWD/qworkspace_container.cpp \
+ $$PWD/qmdiarea_container.cpp \
+ $$PWD/qwizard_container.cpp \
+ $$PWD/default_container.cpp \
+ $$PWD/default_layoutdecoration.cpp \
+ $$PWD/default_actionprovider.cpp \
+ $$PWD/tool_widgeteditor.cpp \
+ $$PWD/qtbrushmanager.cpp \
+ $$PWD/brushmanagerproxy.cpp \
+ $$PWD/iconcache.cpp \
+ $$PWD/formeditor_optionspage.cpp \
+ $$PWD/embeddedoptionspage.cpp \
+ $$PWD/formwindowsettings.cpp \
+ $$PWD/deviceprofiledialog.cpp \
+ $$PWD/dpi_chooser.cpp \
+ $$PWD/previewactiongroup.cpp \
+ $$PWD/itemview_propertysheet.cpp \
+ $$PWD/templateoptionspage.cpp
+
+RESOURCES += $$PWD/formeditor.qrc
diff --git a/src/designer/src/components/formeditor/formeditor.qrc b/src/designer/src/components/formeditor/formeditor.qrc
new file mode 100644
index 000000000..e42cc66ec
--- /dev/null
+++ b/src/designer/src/components/formeditor/formeditor.qrc
@@ -0,0 +1,175 @@
+<RCC>
+ <qresource prefix="/trolltech/formeditor">
+ <file>images/submenu.png</file>
+ <file>images/cursors/arrow.png</file>
+ <file>images/cursors/busy.png</file>
+ <file>images/cursors/closedhand.png</file>
+ <file>images/cursors/cross.png</file>
+ <file>images/cursors/hand.png</file>
+ <file>images/cursors/hsplit.png</file>
+ <file>images/cursors/ibeam.png</file>
+ <file>images/cursors/no.png</file>
+ <file>images/cursors/openhand.png</file>
+ <file>images/cursors/sizeall.png</file>
+ <file>images/cursors/sizeb.png</file>
+ <file>images/cursors/sizef.png</file>
+ <file>images/cursors/sizeh.png</file>
+ <file>images/cursors/sizev.png</file>
+ <file>images/cursors/uparrow.png</file>
+ <file>images/cursors/vsplit.png</file>
+ <file>images/cursors/wait.png</file>
+ <file>images/cursors/whatsthis.png</file>
+ <file>images/emptyicon.png</file>
+ <file>images/filenew-16.png</file>
+ <file>images/fileopen-16.png</file>
+ <file>images/editdelete-16.png</file>
+ <file>images/plus-16.png</file>
+ <file>images/minus-16.png</file>
+ <file>images/prefix-add.png</file>
+ <file>images/downplus.png</file>
+ <file>images/leveldown.png</file>
+ <file>images/levelup.png</file>
+ <file>images/mac/adjustsize.png</file>
+ <file>images/mac/widgettool.png</file>
+ <file>images/mac/signalslottool.png</file>
+ <file>images/mac/tabordertool.png</file>
+ <file>images/mac/buddytool.png</file>
+ <file>images/mac/editbreaklayout.png</file>
+ <file>images/mac/editcopy.png</file>
+ <file>images/mac/editcut.png</file>
+ <file>images/mac/editdelete.png</file>
+ <file>images/mac/editgrid.png</file>
+ <file>images/mac/editform.png</file>
+ <file>images/mac/edithlayout.png</file>
+ <file>images/mac/edithlayoutsplit.png</file>
+ <file>images/mac/editlower.png</file>
+ <file>images/mac/editpaste.png</file>
+ <file>images/mac/editraise.png</file>
+ <file>images/mac/editvlayout.png</file>
+ <file>images/mac/editvlayoutsplit.png</file>
+ <file>images/mac/filenew.png</file>
+ <file>images/mac/insertimage.png</file>
+ <file>images/mac/undo.png</file>
+ <file>images/mac/redo.png</file>
+ <file>images/mac/fileopen.png</file>
+ <file>images/mac/filesave.png</file>
+ <file>images/mac/resourceeditortool.png</file>
+ <file>images/mac/plus.png</file>
+ <file>images/mac/minus.png</file>
+ <file>images/mac/back.png</file>
+ <file>images/mac/forward.png</file>
+ <file>images/mac/down.png</file>
+ <file>images/mac/up.png</file>
+ <file>images/qtlogo.png</file>
+ <file>images/qt3logo.png</file>
+ <file>images/resetproperty.png</file>
+ <file>images/cleartext.png</file>
+ <file>images/sort.png</file>
+ <file>images/edit.png</file>
+ <file>images/reload.png</file>
+ <file>images/configure.png</file>
+ <file>images/color.png</file>
+ <file>images/dropdownbutton.png</file>
+ <file>images/widgets/calendarwidget.png</file>
+ <file>images/widgets/checkbox.png</file>
+ <file>images/widgets/columnview.png</file>
+ <file>images/widgets/combobox.png</file>
+ <file>images/widgets/commandlinkbutton.png</file>
+ <file>images/widgets/dateedit.png</file>
+ <file>images/widgets/datetimeedit.png</file>
+ <file>images/widgets/dial.png</file>
+ <file>images/widgets/dialogbuttonbox.png</file>
+ <file>images/widgets/dockwidget.png</file>
+ <file>images/widgets/doublespinbox.png</file>
+ <file>images/widgets/fontcombobox.png</file>
+ <file>images/widgets/frame.png</file>
+ <file>images/widgets/graphicsview.png</file>
+ <file>images/widgets/groupbox.png</file>
+ <file>images/widgets/hscrollbar.png</file>
+ <file>images/widgets/hslider.png</file>
+ <file>images/widgets/hsplit.png</file>
+ <file>images/widgets/label.png</file>
+ <file>images/widgets/lcdnumber.png</file>
+ <file>images/widgets/line.png</file>
+ <file>images/widgets/lineedit.png</file>
+ <file>images/widgets/listbox.png</file>
+ <file>images/widgets/listview.png</file>
+ <file>images/widgets/mdiarea.png</file>
+ <file>images/widgets/plaintextedit.png</file>
+ <file>images/widgets/progress.png</file>
+ <file>images/widgets/pushbutton.png</file>
+ <file>images/widgets/radiobutton.png</file>
+ <file>images/widgets/scrollarea.png</file>
+ <file>images/widgets/spacer.png</file>
+ <file>images/widgets/spinbox.png</file>
+ <file>images/widgets/table.png</file>
+ <file>images/widgets/tabwidget.png</file>
+ <file>images/widgets/textedit.png</file>
+ <file>images/widgets/timeedit.png</file>
+ <file>images/widgets/toolbox.png</file>
+ <file>images/widgets/toolbutton.png</file>
+ <file>images/widgets/vline.png</file>
+ <file>images/widgets/vscrollbar.png</file>
+ <file>images/widgets/vslider.png</file>
+ <file>images/widgets/vspacer.png</file>
+ <file>images/widgets/widget.png</file>
+ <file>images/widgets/widgetstack.png</file>
+ <file>images/widgets/wizard.png</file>
+ <file>images/win/adjustsize.png</file>
+ <file>images/win/widgettool.png</file>
+ <file>images/win/signalslottool.png</file>
+ <file>images/win/tabordertool.png</file>
+ <file>images/win/buddytool.png</file>
+ <file>images/win/editbreaklayout.png</file>
+ <file>images/win/editcopy.png</file>
+ <file>images/win/editcut.png</file>
+ <file>images/win/editdelete.png</file>
+ <file>images/win/editgrid.png</file>
+ <file>images/win/editform.png</file>
+ <file>images/win/edithlayout.png</file>
+ <file>images/win/edithlayoutsplit.png</file>
+ <file>images/win/editlower.png</file>
+ <file>images/win/editpaste.png</file>
+ <file>images/win/editraise.png</file>
+ <file>images/win/editvlayout.png</file>
+ <file>images/win/editvlayoutsplit.png</file>
+ <file>images/win/filenew.png</file>
+ <file>images/win/insertimage.png</file>
+ <file>images/win/undo.png</file>
+ <file>images/win/redo.png</file>
+ <file>images/win/fileopen.png</file>
+ <file>images/win/filesave.png</file>
+ <file>images/win/resourceeditortool.png</file>
+ <file>images/win/plus.png</file>
+ <file>images/win/minus.png</file>
+ <file>images/win/textanchor.png</file>
+ <file>images/win/textbold.png</file>
+ <file>images/win/textitalic.png</file>
+ <file>images/win/textunder.png</file>
+ <file>images/win/textleft.png</file>
+ <file>images/win/textcenter.png</file>
+ <file>images/win/textright.png</file>
+ <file>images/win/textjustify.png</file>
+ <file>images/win/textsuperscript.png</file>
+ <file>images/win/textsubscript.png</file>
+ <file>images/win/simplifyrichtext.png</file>
+ <file>images/win/back.png</file>
+ <file>images/win/forward.png</file>
+ <file>images/win/down.png</file>
+ <file>images/win/up.png</file>
+ <file>images/mac/textanchor.png</file>
+ <file>images/mac/textbold.png</file>
+ <file>images/mac/textitalic.png</file>
+ <file>images/mac/textunder.png</file>
+ <file>images/mac/textleft.png</file>
+ <file>images/mac/textcenter.png</file>
+ <file>images/mac/textright.png</file>
+ <file>images/mac/textjustify.png</file>
+ <file>images/mac/textsuperscript.png</file>
+ <file>images/mac/textsubscript.png</file>
+ <file>images/mac/simplifyrichtext.png</file>
+ </qresource>
+ <qresource prefix="/trolltech/brushes">
+ <file>defaultbrushes.xml</file>
+ </qresource>
+</RCC>
diff --git a/src/designer/src/components/formeditor/formeditor_global.h b/src/designer/src/components/formeditor/formeditor_global.h
new file mode 100644
index 000000000..f5df69114
--- /dev/null
+++ b/src/designer/src/components/formeditor/formeditor_global.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMEDITOR_GLOBAL_H
+#define FORMEDITOR_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN
+#ifdef QT_FORMEDITOR_LIBRARY
+# define QT_FORMEDITOR_EXPORT
+#else
+# define QT_FORMEDITOR_EXPORT
+#endif
+#else
+#define QT_FORMEDITOR_EXPORT
+#endif
+
+#endif // FORMEDITOR_GLOBAL_H
diff --git a/src/designer/src/components/formeditor/formeditor_optionspage.cpp b/src/designer/src/components/formeditor/formeditor_optionspage.cpp
new file mode 100644
index 000000000..e50072aac
--- /dev/null
+++ b/src/designer/src/components/formeditor/formeditor_optionspage.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formeditor_optionspage.h"
+
+// shared
+#include "formwindowbase_p.h"
+#include "gridpanel_p.h"
+#include "grid_p.h"
+#include "previewconfigurationwidget_p.h"
+#include "shared_settings_p.h"
+#include "zoomwidget_p.h"
+
+// SDK
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+#include <QtCore/QString>
+#include <QtCore/QCoreApplication>
+#include <QtGui/QGroupBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QComboBox>
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<int> IntList;
+
+namespace qdesigner_internal {
+
+// Zoom, currently for preview only
+class ZoomSettingsWidget : public QGroupBox {
+ Q_DISABLE_COPY(ZoomSettingsWidget)
+public:
+ explicit ZoomSettingsWidget(QWidget *parent = 0);
+
+ void fromSettings(const QDesignerSharedSettings &s);
+ void toSettings(QDesignerSharedSettings &s) const;
+
+private:
+ QComboBox *m_zoomCombo;
+};
+
+ZoomSettingsWidget::ZoomSettingsWidget(QWidget *parent) :
+ QGroupBox(parent),
+ m_zoomCombo(new QComboBox)
+{
+ m_zoomCombo->setEditable(false);
+ const IntList zoomValues = ZoomMenu::zoomValues();
+ const IntList::const_iterator cend = zoomValues.constEnd();
+
+ for (IntList::const_iterator it = zoomValues.constBegin(); it != cend; ++it) {
+ //: Zoom percentage
+ m_zoomCombo->addItem(QCoreApplication::translate("FormEditorOptionsPage", "%1 %").arg(*it), QVariant(*it));
+ }
+
+ // Layout
+ setCheckable(true);
+ setTitle(QCoreApplication::translate("FormEditorOptionsPage", "Preview Zoom"));
+ QFormLayout *lt = new QFormLayout;
+ lt->addRow(QCoreApplication::translate("FormEditorOptionsPage", "Default Zoom"), m_zoomCombo);
+ setLayout(lt);
+}
+
+void ZoomSettingsWidget::fromSettings(const QDesignerSharedSettings &s)
+{
+ setChecked(s.zoomEnabled());
+ const int idx = m_zoomCombo->findData(QVariant(s.zoom()));
+ m_zoomCombo->setCurrentIndex(qMax(0, idx));
+}
+
+void ZoomSettingsWidget::toSettings(QDesignerSharedSettings &s) const
+{
+ s.setZoomEnabled(isChecked());
+ const int zoom = m_zoomCombo->itemData(m_zoomCombo->currentIndex()).toInt();
+ s.setZoom(zoom);
+}
+
+
+
+// FormEditorOptionsPage:
+FormEditorOptionsPage::FormEditorOptionsPage(QDesignerFormEditorInterface *core)
+ : m_core(core)
+{
+}
+
+QString FormEditorOptionsPage::name() const
+{
+ //: Tab in preferences dialog
+ return QCoreApplication::translate("FormEditorOptionsPage", "Forms");
+}
+
+QWidget *FormEditorOptionsPage::createPage(QWidget *parent)
+{
+ QWidget *optionsWidget = new QWidget(parent);
+
+ const QDesignerSharedSettings settings(m_core);
+ m_previewConf = new PreviewConfigurationWidget(m_core);
+ m_zoomSettingsWidget = new ZoomSettingsWidget;
+ m_zoomSettingsWidget->fromSettings(settings);
+
+ m_defaultGridConf = new GridPanel();
+ m_defaultGridConf->setTitle(QCoreApplication::translate("FormEditorOptionsPage", "Default Grid"));
+ m_defaultGridConf->setGrid(settings.defaultGrid());
+
+ QVBoxLayout *optionsVLayout = new QVBoxLayout();
+ optionsVLayout->addWidget(m_defaultGridConf);
+ optionsVLayout->addWidget(m_previewConf);
+ optionsVLayout->addWidget(m_zoomSettingsWidget);
+ optionsVLayout->addStretch(1);
+
+ // Outer layout to give it horizontal stretch
+ QHBoxLayout *optionsHLayout = new QHBoxLayout();
+ optionsHLayout->addLayout(optionsVLayout);
+ optionsHLayout->addStretch(1);
+ optionsWidget->setLayout(optionsHLayout);
+
+ return optionsWidget;
+}
+
+void FormEditorOptionsPage::apply()
+{
+ QDesignerSharedSettings settings(m_core);
+ if (m_defaultGridConf) {
+ const Grid defaultGrid = m_defaultGridConf->grid();
+ settings.setDefaultGrid(defaultGrid);
+
+ FormWindowBase::setDefaultDesignerGrid(defaultGrid);
+ // Update grid settings in all existing form windows
+ QDesignerFormWindowManagerInterface *fwm = m_core->formWindowManager();
+ if (const int numWindows = fwm->formWindowCount()) {
+ for (int i = 0; i < numWindows; i++)
+ if (qdesigner_internal::FormWindowBase *fwb
+ = qobject_cast<qdesigner_internal::FormWindowBase *>( fwm->formWindow(i)))
+ if (!fwb->hasFormGrid())
+ fwb->setDesignerGrid(defaultGrid);
+ }
+ }
+ if (m_previewConf) {
+ m_previewConf->saveState();
+ }
+
+ if (m_zoomSettingsWidget)
+ m_zoomSettingsWidget->toSettings(settings);
+}
+
+void FormEditorOptionsPage::finish()
+{
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/formeditor_optionspage.h b/src/designer/src/components/formeditor/formeditor_optionspage.h
new file mode 100644
index 000000000..d7d169be2
--- /dev/null
+++ b/src/designer/src/components/formeditor/formeditor_optionspage.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMEDITOR_OPTIONSPAGE_H
+#define FORMEDITOR_OPTIONSPAGE_H
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class PreviewConfigurationWidget;
+class GridPanel;
+class ZoomSettingsWidget;
+
+class FormEditorOptionsPage : public QDesignerOptionsPageInterface
+{
+public:
+ explicit FormEditorOptionsPage(QDesignerFormEditorInterface *core);
+
+ QString name() const;
+ QWidget *createPage(QWidget *parent);
+ virtual void apply();
+ virtual void finish();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ QPointer<PreviewConfigurationWidget> m_previewConf;
+ QPointer<GridPanel> m_defaultGridConf;
+ QPointer<ZoomSettingsWidget> m_zoomSettingsWidget;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMEDITOR_OPTIONSPAGE_H
diff --git a/src/designer/src/components/formeditor/formwindow.cpp b/src/designer/src/components/formeditor/formwindow.cpp
new file mode 100644
index 000000000..3fb18aa31
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindow.cpp
@@ -0,0 +1,2981 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindow.h"
+#include "formeditor.h"
+#include "formwindow_dnditem.h"
+#include "formwindow_widgetstack.h"
+#include "formwindowcursor.h"
+#include "formwindowmanager.h"
+#include "tool_widgeteditor.h"
+#include "widgetselection.h"
+#include "qtresourcemodel_p.h"
+#include "widgetfactory_p.h"
+
+// shared
+#include <metadatabase_p.h>
+#include <qdesigner_tabwidget_p.h>
+#include <qdesigner_toolbox_p.h>
+#include <qdesigner_stackedbox_p.h>
+#include <qdesigner_resource.h>
+#include <qdesigner_command_p.h>
+#include <qdesigner_command2_p.h>
+#include <qdesigner_propertycommand_p.h>
+#include <qdesigner_taskmenu_p.h>
+#include <qdesigner_widget_p.h>
+#include <qdesigner_utils_p.h>
+#include <qlayout_widget_p.h>
+#include <spacer_widget_p.h>
+#include <invisible_widget_p.h>
+#include <layoutinfo_p.h>
+#include <qdesigner_objectinspector_p.h>
+#include <connectionedit_p.h>
+#include <actionprovider_p.h>
+#include <ui4_p.h>
+#include <deviceprofile_p.h>
+#include <shared_settings_p.h>
+#include <grid_p.h>
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <abstractdialoggui_p.h>
+
+#include <QtCore/QtDebug>
+#include <QtCore/QBuffer>
+#include <QtCore/QTimer>
+#include <QtCore/QXmlStreamReader>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QClipboard>
+#include <QtGui/QUndoGroup>
+#include <QtGui/QScrollArea>
+#include <QtGui/QRubberBand>
+#include <QtGui/QApplication>
+#include <QtGui/QSplitter>
+#include <QtGui/QPainter>
+#include <QtGui/QGroupBox>
+#include <QtGui/QDockWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QTabWidget>
+#include <QtGui/QButtonGroup>
+
+Q_DECLARE_METATYPE(QWidget*)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+class BlockSelection
+{
+public:
+ BlockSelection(qdesigner_internal::FormWindow *fw)
+ : m_formWindow(fw),
+ m_blocked(m_formWindow->blockSelectionChanged(true))
+ {
+ }
+
+ ~BlockSelection()
+ {
+ if (m_formWindow)
+ m_formWindow->blockSelectionChanged(m_blocked);
+ }
+
+private:
+ QPointer<qdesigner_internal::FormWindow> m_formWindow;
+ const bool m_blocked;
+};
+
+enum { debugFormWindow = 0 };
+}
+
+namespace qdesigner_internal {
+
+// ------------------------ FormWindow::Selection
+// Maintains a pool of WidgetSelections to be used for selected widgets.
+
+class FormWindow::Selection
+{
+public:
+ Selection();
+ ~Selection();
+
+ // Clear
+ void clear();
+
+ // Also clear out the pool. Call if reparenting of the main container occurs.
+ void clearSelectionPool();
+
+ void repaintSelection(QWidget *w);
+ void repaintSelection();
+
+ bool isWidgetSelected(QWidget *w) const;
+ QWidgetList selectedWidgets() const;
+
+ WidgetSelection *addWidget(FormWindow* fw, QWidget *w);
+ // remove widget, return new current widget or 0
+ QWidget* removeWidget(QWidget *w);
+
+ void raiseList(const QWidgetList& l);
+ void raiseWidget(QWidget *w);
+
+ void updateGeometry(QWidget *w);
+
+ void hide(QWidget *w);
+ void show(QWidget *w);
+
+private:
+
+ typedef QList<WidgetSelection *> SelectionPool;
+ SelectionPool m_selectionPool;
+
+ typedef QHash<QWidget *, WidgetSelection *> SelectionHash;
+ SelectionHash m_usedSelections;
+};
+
+FormWindow::Selection::Selection()
+{
+}
+
+FormWindow::Selection::~Selection()
+{
+ clearSelectionPool();
+}
+
+void FormWindow::Selection::clear()
+{
+ if (!m_usedSelections.empty()) {
+ const SelectionHash::iterator mend = m_usedSelections.end();
+ for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
+ it.value()->setWidget(0);
+ }
+ m_usedSelections.clear();
+ }
+}
+
+void FormWindow::Selection::clearSelectionPool()
+{
+ clear();
+ qDeleteAll(m_selectionPool);
+ m_selectionPool.clear();
+}
+
+WidgetSelection *FormWindow::Selection::addWidget(FormWindow* fw, QWidget *w)
+{
+ WidgetSelection *rc = m_usedSelections.value(w);
+ if (rc != 0) {
+ rc->show();
+ rc->updateActive();
+ return rc;
+ }
+ // find a free one in the pool
+ const SelectionPool::iterator pend = m_selectionPool.end();
+ for (SelectionPool::iterator it = m_selectionPool.begin(); it != pend; ++it) {
+ if (! (*it)->isUsed()) {
+ rc = *it;
+ break;
+ }
+ }
+
+ if (rc == 0) {
+ rc = new WidgetSelection(fw);
+ m_selectionPool.push_back(rc);
+ }
+
+ m_usedSelections.insert(w, rc);
+ rc->setWidget(w);
+ return rc;
+}
+
+QWidget* FormWindow::Selection::removeWidget(QWidget *w)
+{
+ WidgetSelection *s = m_usedSelections.value(w);
+ if (!s)
+ return w;
+
+ s->setWidget(0);
+ m_usedSelections.remove(w);
+
+ if (m_usedSelections.isEmpty())
+ return 0;
+
+ return (*m_usedSelections.begin())->widget();
+}
+
+void FormWindow::Selection::repaintSelection(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w))
+ s->update();
+}
+
+void FormWindow::Selection::repaintSelection()
+{
+ const SelectionHash::iterator mend = m_usedSelections.end();
+ for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
+ it.value()->update();
+ }
+}
+
+bool FormWindow::Selection::isWidgetSelected(QWidget *w) const{
+ return m_usedSelections.contains(w);
+}
+
+QWidgetList FormWindow::Selection::selectedWidgets() const
+{
+ return m_usedSelections.keys();
+}
+
+void FormWindow::Selection::raiseList(const QWidgetList& l)
+{
+ const SelectionHash::iterator mend = m_usedSelections.end();
+ for (SelectionHash::iterator it = m_usedSelections.begin(); it != mend; ++it) {
+ WidgetSelection *w = it.value();
+ if (l.contains(w->widget()))
+ w->show();
+ }
+}
+
+void FormWindow::Selection::raiseWidget(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w))
+ s->show();
+}
+
+void FormWindow::Selection::updateGeometry(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w)) {
+ s->updateGeometry();
+ }
+}
+
+void FormWindow::Selection::hide(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w))
+ s->hide();
+}
+
+void FormWindow::Selection::show(QWidget *w)
+{
+ if (WidgetSelection *s = m_usedSelections.value(w))
+ s->show();
+}
+
+// ------------------------ FormWindow
+FormWindow::FormWindow(FormEditor *core, QWidget *parent, Qt::WindowFlags flags) :
+ FormWindowBase(core, parent, flags),
+ m_mouseState(NoMouseState),
+ m_core(core),
+ m_selection(new Selection),
+ m_widgetStack(new FormWindowWidgetStack(this)),
+ m_contextMenuPosition(-1, -1)
+{
+ // Apply settings to formcontainer
+ deviceProfile().apply(core, m_widgetStack->formContainer(), qdesigner_internal::DeviceProfile::ApplyFormParent);
+
+ setLayout(m_widgetStack->layout());
+ init();
+
+ m_cursor = new FormWindowCursor(this, this);
+
+ core->formWindowManager()->addFormWindow(this);
+
+ setDirty(false);
+ setAcceptDrops(true);
+}
+
+FormWindow::~FormWindow()
+{
+ Q_ASSERT(core() != 0);
+ Q_ASSERT(core()->metaDataBase() != 0);
+ Q_ASSERT(core()->formWindowManager() != 0);
+
+ core()->formWindowManager()->removeFormWindow(this);
+ core()->metaDataBase()->remove(this);
+
+ QWidgetList l = widgets();
+ foreach (QWidget *w, l)
+ core()->metaDataBase()->remove(w);
+
+ m_widgetStack = 0;
+ m_rubberBand = 0;
+ if (resourceSet())
+ core()->resourceModel()->removeResourceSet(resourceSet());
+ delete m_selection;
+}
+
+QDesignerFormEditorInterface *FormWindow::core() const
+{
+ return m_core;
+}
+
+QDesignerFormWindowCursorInterface *FormWindow::cursor() const
+{
+ return m_cursor;
+}
+
+void FormWindow::updateWidgets()
+{
+ if (!m_mainContainer)
+ return;
+}
+
+int FormWindow::widgetDepth(const QWidget *w)
+{
+ int d = -1;
+ while (w && !w->isWindow()) {
+ d++;
+ w = w->parentWidget();
+ }
+
+ return d;
+}
+
+bool FormWindow::isChildOf(const QWidget *c, const QWidget *p)
+{
+ while (c) {
+ if (c == p)
+ return true;
+ c = c->parentWidget();
+ }
+ return false;
+}
+
+void FormWindow::setCursorToAll(const QCursor &c, QWidget *start)
+{
+#ifndef QT_NO_CURSOR
+ start->setCursor(c);
+ const QWidgetList widgets = start->findChildren<QWidget*>();
+ foreach (QWidget *widget, widgets) {
+ if (!qobject_cast<WidgetHandle*>(widget)) {
+ widget->setCursor(c);
+ }
+ }
+#endif
+}
+
+void FormWindow::init()
+{
+ if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager())) {
+ manager->undoGroup()->addStack(m_undoStack.qundoStack());
+ }
+
+ m_blockSelectionChanged = false;
+
+ m_defaultMargin = INT_MIN;
+ m_defaultSpacing = INT_MIN;
+
+ connect(m_widgetStack, SIGNAL(currentToolChanged(int)), this, SIGNAL(toolChanged(int)));
+
+ m_selectionChangedTimer = new QTimer(this);
+ m_selectionChangedTimer->setSingleShot(true);
+ connect(m_selectionChangedTimer, SIGNAL(timeout()), this, SLOT(selectionChangedTimerDone()));
+
+ m_checkSelectionTimer = new QTimer(this);
+ m_checkSelectionTimer->setSingleShot(true);
+ connect(m_checkSelectionTimer, SIGNAL(timeout()), this, SLOT(checkSelectionNow()));
+
+ m_geometryChangedTimer = new QTimer(this);
+ m_geometryChangedTimer->setSingleShot(true);
+ connect(m_geometryChangedTimer, SIGNAL(timeout()), this, SIGNAL(geometryChanged()));
+
+ m_rubberBand = 0;
+
+ setFocusPolicy(Qt::StrongFocus);
+
+ m_mainContainer = 0;
+ m_currentWidget = 0;
+
+ connect(&m_undoStack, SIGNAL(changed()), this, SIGNAL(changed()));
+ connect(&m_undoStack, SIGNAL(changed()), this, SLOT(checkSelection()));
+
+ core()->metaDataBase()->add(this);
+
+ initializeCoreTools();
+
+ QAction *a = new QAction(this);
+ a->setText(tr("Edit contents"));
+ a->setShortcut(tr("F2"));
+ connect(a, SIGNAL(triggered()), this, SLOT(editContents()));
+ addAction(a);
+}
+
+QWidget *FormWindow::mainContainer() const
+{
+ return m_mainContainer;
+}
+
+
+void FormWindow::clearMainContainer()
+{
+ if (m_mainContainer) {
+ setCurrentTool(0);
+ m_widgetStack->setMainContainer(0);
+ core()->metaDataBase()->remove(m_mainContainer);
+ unmanageWidget(m_mainContainer);
+ delete m_mainContainer;
+ m_mainContainer = 0;
+ }
+}
+
+void FormWindow::setMainContainer(QWidget *w)
+{
+ if (w == m_mainContainer) {
+ // nothing to do
+ return;
+ }
+
+ clearMainContainer();
+
+ m_mainContainer = w;
+ const QSize sz = m_mainContainer->size();
+
+ m_widgetStack->setMainContainer(m_mainContainer);
+ m_widgetStack->setCurrentTool(m_widgetEditor);
+
+ setCurrentWidget(m_mainContainer);
+ manageWidget(m_mainContainer);
+
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), m_mainContainer)) {
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowTitle")), true);
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowIcon")), true);
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowModality")), true);
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowOpacity")), true);
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowFilePath")), true);
+ // ### generalize
+ }
+
+ m_mainContainer->setFocusPolicy(Qt::StrongFocus);
+ m_mainContainer->resize(sz);
+
+ emit mainContainerChanged(m_mainContainer);
+}
+
+QWidget *FormWindow::findTargetContainer(QWidget *widget) const
+{
+ Q_ASSERT(widget);
+
+ while (QWidget *parentWidget = widget->parentWidget()) {
+ if (LayoutInfo::layoutType(m_core, parentWidget) == LayoutInfo::NoLayout && isManaged(widget))
+ return widget;
+
+ widget = parentWidget;
+ }
+
+ return mainContainer();
+}
+
+static inline void clearObjectInspectorSelection(const QDesignerFormEditorInterface *core)
+{
+ if (QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core->objectInspector()))
+ oi->clearSelection();
+}
+
+// Find a parent of a desired selection state
+static QWidget *findSelectedParent(QDesignerFormWindowInterface *fw, const QWidget *w, bool selected)
+{
+ const QDesignerFormWindowCursorInterface *cursor = fw->cursor();
+ QWidget *mainContainer = fw->mainContainer();
+ for (QWidget *p = w->parentWidget(); p && p != mainContainer; p = p->parentWidget())
+ if (fw->isManaged(p))
+ if (cursor->isWidgetSelected(p) == selected)
+ return p;
+ return 0;
+}
+
+// Mouse modifiers.
+
+enum MouseFlags { ToggleSelectionModifier = 0x1, CycleParentModifier=0x2, CopyDragModifier=0x4 };
+
+static inline unsigned mouseFlags(Qt::KeyboardModifiers mod)
+{
+ switch (mod) {
+ case Qt::ShiftModifier:
+ return CycleParentModifier;
+ break;
+#ifdef Q_WS_MAC
+ case Qt::AltModifier: // "Alt" or "option" key on Mac means copy
+ return CopyDragModifier;
+#endif
+ case Qt::ControlModifier:
+ return CopyDragModifier|ToggleSelectionModifier;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+// Handle the click selection: Do toggling/cycling
+// of parents according to the modifiers.
+void FormWindow::handleClickSelection(QWidget *managedWidget, unsigned mouseMode)
+{
+ const bool sameWidget = managedWidget == m_lastClickedWidget;
+ m_lastClickedWidget = managedWidget;
+
+ const bool selected = isWidgetSelected(managedWidget);
+ if (debugFormWindow)
+ qDebug() << "handleClickSelection" << managedWidget << " same=" << sameWidget << " mouse= " << mouseMode << " selected=" << selected;
+
+ // // toggle selection state of widget
+ if (mouseMode & ToggleSelectionModifier) {
+ selectWidget(managedWidget, !selected);
+ return;
+ }
+
+ QWidget *selectionCandidate = 0;
+ // Hierarchy cycling: If the same widget clicked again: Attempt to cycle
+ // trough the hierarchy. Find the next currently selected parent
+ if (sameWidget && (mouseMode & CycleParentModifier))
+ if (QWidget *currentlySelectedParent = selected ? managedWidget : findSelectedParent(this, managedWidget, true))
+ selectionCandidate = findSelectedParent(this, currentlySelectedParent, false);
+ // Not the same widget, list wrapped over or there was no unselected parent
+ if (!selectionCandidate && !selected)
+ selectionCandidate = managedWidget;
+
+ if (selectionCandidate)
+ selectSingleWidget(selectionCandidate);
+}
+
+void FormWindow::selectSingleWidget(QWidget *w)
+{
+ clearSelection(false);
+ selectWidget(w, true);
+ raiseChildSelections(w);
+}
+
+bool FormWindow::handleMousePressEvent(QWidget * widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ m_mouseState = NoMouseState;
+ m_startPos = QPoint();
+ e->accept();
+
+ BlockSelection blocker(this);
+
+ if (core()->formWindowManager()->activeFormWindow() != this)
+ core()->formWindowManager()->setActiveFormWindow(this);
+
+ const Qt::MouseButtons buttons = e->buttons();
+ if (buttons != Qt::LeftButton && buttons != Qt::MidButton)
+ return true;
+
+ m_startPos = mapFromGlobal(e->globalPos());
+
+ if (debugFormWindow)
+ qDebug() << "handleMousePressEvent:" << widget << ',' << managedWidget;
+
+ if (buttons == Qt::MidButton || isMainContainer(managedWidget) == true) { // press was on the formwindow
+ clearObjectInspectorSelection(m_core); // We might have a toolbar or non-widget selected in the object inspector.
+ clearSelection(false);
+
+ m_mouseState = MouseDrawRubber;
+ m_currRect = QRect();
+ startRectDraw(mapFromGlobal(e->globalPos()), this, Rubber);
+ return true;
+ }
+ if (buttons != Qt::LeftButton)
+ return true;
+
+ const unsigned mouseMode = mouseFlags(e->modifiers());
+
+ /* Normally, we want to be able to click /select-on-press to drag away
+ * the widget in the next step. However, in the case of a widget which
+ * itself or whose parent is selected, we defer the selection to the
+ * release event.
+ * This is to prevent children from being dragged away from layouts
+ * when their layouts are selected and one wants to move the layout.
+ * Note that toggle selection is only deferred if the widget is already
+ * selected, so, it is still possible to just Ctrl+Click and CopyDrag. */
+ const bool deferSelection = isWidgetSelected(managedWidget) || findSelectedParent(this, managedWidget, true);
+ if (deferSelection) {
+ m_mouseState = MouseDeferredSelection;
+ } else {
+ // Cycle the parent unless we explicitly want toggle
+ const unsigned effectiveMouseMode = (mouseMode & ToggleSelectionModifier) ? mouseMode : static_cast<unsigned>(CycleParentModifier);
+ handleClickSelection(managedWidget, effectiveMouseMode);
+ }
+ return true;
+}
+
+// We can drag widget in managed layouts except splitter.
+static bool canDragWidgetInLayout(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ bool managed;
+ const LayoutInfo::Type type = LayoutInfo::laidoutWidgetType(core ,w, &managed);
+ if (!managed)
+ return false;
+ switch (type) {
+ case LayoutInfo::NoLayout:
+ case LayoutInfo::HSplitter:
+ case LayoutInfo::VSplitter:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+bool FormWindow::handleMouseMoveEvent(QWidget *, QWidget *, QMouseEvent *e)
+{
+ e->accept();
+ if (m_startPos.isNull())
+ return true;
+
+ const QPoint pos = mapFromGlobal(e->globalPos());
+
+ switch (m_mouseState) {
+ case MouseDrawRubber: // Rubber band with left/middle mouse
+ continueRectDraw(pos, this, Rubber);
+ return true;
+ case MouseMoveDrag: // Spurious move event after drag started?
+ return true;
+ default:
+ break;
+ }
+
+ if (e->buttons() != Qt::LeftButton)
+ return true;
+
+ const bool canStartDrag = (m_startPos - pos).manhattanLength() > QApplication::startDragDistance();
+
+ if (canStartDrag == false) {
+ // nothing to do
+ return true;
+ }
+
+ m_mouseState = MouseMoveDrag;
+ const bool blocked = blockSelectionChanged(true);
+
+ QWidgetList sel = selectedWidgets();
+ simplifySelection(&sel);
+
+ QSet<QWidget*> widget_set;
+
+ foreach (QWidget *child, sel) { // Move parent layout or container?
+ QWidget *current = child;
+
+ bool done = false;
+ while (!isMainContainer(current) && !done) {
+ if (!isManaged(current)) {
+ current = current->parentWidget();
+ continue;
+ } else if (LayoutInfo::isWidgetLaidout(core(), current)) {
+ // Go up to parent of layout if shift pressed, else do that only for splitters
+ if (!canDragWidgetInLayout(core(), current)) {
+ current = current->parentWidget();
+ continue;
+ }
+ }
+ done = true;
+ }
+
+ if (current == mainContainer())
+ continue;
+
+ widget_set.insert(current);
+ }
+
+ sel = widget_set.toList();
+ QDesignerFormWindowCursorInterface *c = cursor();
+ QWidget *current = c->current();
+ if (sel.contains(current)) {
+ sel.removeAll(current);
+ sel.prepend(current);
+ }
+
+ QList<QDesignerDnDItemInterface*> item_list;
+ const QPoint globalPos = mapToGlobal(m_startPos);
+ const QDesignerDnDItemInterface::DropType dropType = (mouseFlags(e->modifiers()) & CopyDragModifier) ?
+ QDesignerDnDItemInterface::CopyDrop : QDesignerDnDItemInterface::MoveDrop;
+ foreach (QWidget *widget, sel) {
+ item_list.append(new FormWindowDnDItem(dropType, this, widget, globalPos));
+ if (dropType == QDesignerDnDItemInterface::MoveDrop) {
+ m_selection->hide(widget);
+ widget->hide();
+ }
+ }
+
+ blockSelectionChanged(blocked);
+
+ if (!sel.empty()) // reshow selection?
+ if (QDesignerMimeData::execDrag(item_list, core()->topLevel()) == Qt::IgnoreAction && dropType == QDesignerDnDItemInterface::MoveDrop)
+ foreach (QWidget *widget, sel)
+ m_selection->show(widget);
+
+ m_startPos = QPoint();
+
+ return true;
+}
+
+bool FormWindow::handleMouseReleaseEvent(QWidget *w, QWidget *mw, QMouseEvent *e)
+{
+ const MouseState oldState = m_mouseState;
+ m_mouseState = NoMouseState;
+
+ if (debugFormWindow)
+ qDebug() << "handleMouseeleaseEvent:" << w << ',' << mw << "state=" << oldState;
+
+ if (oldState == MouseDoubleClicked)
+ return true;
+
+ e->accept();
+
+ switch (oldState) {
+ case MouseDrawRubber: { // we were drawing a rubber selection
+ endRectDraw(); // get rid of the rectangle
+ const bool blocked = blockSelectionChanged(true);
+ selectWidgets(); // select widgets which intersect the rect
+ blockSelectionChanged(blocked);
+ }
+ break;
+ // Deferred select: Select the child here unless the parent was moved.
+ case MouseDeferredSelection:
+ handleClickSelection(mw, mouseFlags(e->modifiers()));
+ break;
+ default:
+ break;
+ }
+
+ m_startPos = QPoint();
+
+ /* Inform about selection changes (left/mid or context menu). Also triggers
+ * in the case of an empty rubber drag that cleared the selection in
+ * MousePressEvent. */
+ switch (e->button()) {
+ case Qt::LeftButton:
+ case Qt::MidButton:
+ case Qt::RightButton:
+ emitSelectionChanged();
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void FormWindow::checkPreviewGeometry(QRect &r)
+{
+ if (!rect().contains(r)) {
+ if (r.left() < rect().left())
+ r.moveTopLeft(QPoint(0, r.top()));
+ if (r.right() > rect().right())
+ r.moveBottomRight(QPoint(rect().right(), r.bottom()));
+ if (r.top() < rect().top())
+ r.moveTopLeft(QPoint(r.left(), rect().top()));
+ if (r.bottom() > rect().bottom())
+ r.moveBottomRight(QPoint(r.right(), rect().bottom()));
+ }
+}
+
+void FormWindow::startRectDraw(const QPoint &pos, QWidget *, RectType t)
+{
+ m_rectAnchor = (t == Insert) ? designerGrid().snapPoint(pos) : pos;
+
+ m_currRect = QRect(m_rectAnchor, QSize(0, 0));
+ if (!m_rubberBand)
+ m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
+ m_rubberBand->setGeometry(m_currRect);
+ m_rubberBand->show();
+}
+
+void FormWindow::continueRectDraw(const QPoint &pos, QWidget *, RectType t)
+{
+ const QPoint p2 = (t == Insert) ? designerGrid().snapPoint(pos) : pos;
+
+ QRect r(m_rectAnchor, p2);
+ r = r.normalized();
+
+ if (m_currRect == r)
+ return;
+
+ if (r.width() > 1 || r.height() > 1) {
+ m_currRect = r;
+ if (m_rubberBand)
+ m_rubberBand->setGeometry(m_currRect);
+ }
+}
+
+void FormWindow::endRectDraw()
+{
+ if (m_rubberBand) {
+ delete m_rubberBand;
+ m_rubberBand = 0;
+ }
+}
+
+QWidget *FormWindow::currentWidget() const
+{
+ return m_currentWidget;
+}
+
+bool FormWindow::setCurrentWidget(QWidget *currentWidget)
+{
+ if (debugFormWindow)
+ qDebug() << "setCurrentWidget:" << m_currentWidget << " --> " << currentWidget;
+ if (currentWidget == m_currentWidget)
+ return false;
+ // repaint the old widget unless it is the main window
+ if (m_currentWidget && m_currentWidget != mainContainer()) {
+ m_selection->repaintSelection(m_currentWidget);
+ }
+ // set new and repaint
+ m_currentWidget = currentWidget;
+ if (m_currentWidget && m_currentWidget != mainContainer()) {
+ m_selection->repaintSelection(m_currentWidget);
+ }
+ return true;
+}
+
+void FormWindow::selectWidget(QWidget* w, bool select)
+{
+ if (trySelectWidget(w, select))
+ emitSelectionChanged();
+}
+
+// Selects a widget and determines the new current one. Returns true if a change occurs.
+bool FormWindow::trySelectWidget(QWidget *w, bool select)
+{
+ if (debugFormWindow)
+ qDebug() << "trySelectWidget:" << w << select;
+ if (!isManaged(w) && !isCentralWidget(w))
+ return false;
+
+ if (!select && !isWidgetSelected(w))
+ return false;
+
+ if (!mainContainer())
+ return false;
+
+ if (isMainContainer(w) || isCentralWidget(w)) {
+ setCurrentWidget(mainContainer());
+ return true;
+ }
+
+ if (select) {
+ setCurrentWidget(w);
+ m_selection->addWidget(this, w);
+ } else {
+ QWidget *newCurrent = m_selection->removeWidget(w);
+ if (!newCurrent)
+ newCurrent = mainContainer();
+ setCurrentWidget(newCurrent);
+ }
+ return true;
+}
+
+void FormWindow::clearSelection(bool changePropertyDisplay)
+{
+ if (debugFormWindow)
+ qDebug() << "clearSelection(" << changePropertyDisplay << ')';
+ // At all events, we need a current widget.
+ m_selection->clear();
+ setCurrentWidget(mainContainer());
+
+ if (changePropertyDisplay)
+ emitSelectionChanged();
+}
+
+void FormWindow::emitSelectionChanged()
+{
+ if (m_blockSelectionChanged == true) {
+ // nothing to do
+ return;
+ }
+
+ m_selectionChangedTimer->start(0);
+}
+
+void FormWindow::selectionChangedTimerDone()
+{
+ emit selectionChanged();
+}
+
+bool FormWindow::isWidgetSelected(QWidget *w) const
+{
+ return m_selection->isWidgetSelected(w);
+}
+
+bool FormWindow::isMainContainer(const QWidget *w) const
+{
+ return w && (w == this || w == mainContainer());
+}
+
+void FormWindow::updateChildSelections(QWidget *w)
+{
+ const QWidgetList l = w->findChildren<QWidget*>();
+ if (!l.empty()) {
+ const QWidgetList::const_iterator lcend = l.constEnd();
+ for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it) {
+ QWidget *w = *it;
+ if (isManaged(w))
+ updateSelection(w);
+ }
+ }
+}
+
+void FormWindow::repaintSelection()
+{
+ m_selection->repaintSelection();
+}
+
+void FormWindow::raiseSelection(QWidget *w)
+{
+ m_selection->raiseWidget(w);
+}
+
+void FormWindow::updateSelection(QWidget *w)
+{
+ if (!w->isVisibleTo(this)) {
+ selectWidget(w, false);
+ } else {
+ m_selection->updateGeometry(w);
+ }
+}
+
+QWidget *FormWindow::designerWidget(QWidget *w) const
+{
+ while ((w && !isMainContainer(w) && !isManaged(w)) || isCentralWidget(w))
+ w = w->parentWidget();
+
+ return w;
+}
+
+bool FormWindow::isCentralWidget(QWidget *w) const
+{
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(mainContainer()))
+ return w == mainWindow->centralWidget();
+
+ return false;
+}
+
+void FormWindow::ensureUniqueObjectName(QObject *object)
+{
+ QString name = object->objectName();
+ if (name.isEmpty()) {
+ QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
+ if (QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(object)))
+ name = qdesigner_internal::qtify(item->name());
+ }
+ unify(object, name, true);
+ object->setObjectName(name);
+}
+
+template <class Iterator>
+static inline void insertNames(const QDesignerMetaDataBaseInterface *metaDataBase,
+ Iterator it, const Iterator &end,
+ QObject *excludedObject, QSet<QString> &nameSet)
+{
+ for ( ; it != end; ++it)
+ if (excludedObject != *it && metaDataBase->item(*it))
+ nameSet.insert((*it)->objectName());
+}
+
+static QSet<QString> languageKeywords()
+{
+ static QSet<QString> keywords;
+ if (keywords.isEmpty()) {
+ // C++ keywords
+ keywords.insert(QLatin1String("asm"));
+ keywords.insert(QLatin1String("auto"));
+ keywords.insert(QLatin1String("bool"));
+ keywords.insert(QLatin1String("break"));
+ keywords.insert(QLatin1String("case"));
+ keywords.insert(QLatin1String("catch"));
+ keywords.insert(QLatin1String("char"));
+ keywords.insert(QLatin1String("class"));
+ keywords.insert(QLatin1String("const"));
+ keywords.insert(QLatin1String("const_cast"));
+ keywords.insert(QLatin1String("continue"));
+ keywords.insert(QLatin1String("default"));
+ keywords.insert(QLatin1String("delete"));
+ keywords.insert(QLatin1String("do"));
+ keywords.insert(QLatin1String("double"));
+ keywords.insert(QLatin1String("dynamic_cast"));
+ keywords.insert(QLatin1String("else"));
+ keywords.insert(QLatin1String("enum"));
+ keywords.insert(QLatin1String("explicit"));
+ keywords.insert(QLatin1String("export"));
+ keywords.insert(QLatin1String("extern"));
+ keywords.insert(QLatin1String("false"));
+ keywords.insert(QLatin1String("float"));
+ keywords.insert(QLatin1String("for"));
+ keywords.insert(QLatin1String("friend"));
+ keywords.insert(QLatin1String("goto"));
+ keywords.insert(QLatin1String("if"));
+ keywords.insert(QLatin1String("inline"));
+ keywords.insert(QLatin1String("int"));
+ keywords.insert(QLatin1String("long"));
+ keywords.insert(QLatin1String("mutable"));
+ keywords.insert(QLatin1String("namespace"));
+ keywords.insert(QLatin1String("new"));
+ keywords.insert(QLatin1String("NULL"));
+ keywords.insert(QLatin1String("operator"));
+ keywords.insert(QLatin1String("private"));
+ keywords.insert(QLatin1String("protected"));
+ keywords.insert(QLatin1String("public"));
+ keywords.insert(QLatin1String("register"));
+ keywords.insert(QLatin1String("reinterpret_cast"));
+ keywords.insert(QLatin1String("return"));
+ keywords.insert(QLatin1String("short"));
+ keywords.insert(QLatin1String("signed"));
+ keywords.insert(QLatin1String("sizeof"));
+ keywords.insert(QLatin1String("static"));
+ keywords.insert(QLatin1String("static_cast"));
+ keywords.insert(QLatin1String("struct"));
+ keywords.insert(QLatin1String("switch"));
+ keywords.insert(QLatin1String("template"));
+ keywords.insert(QLatin1String("this"));
+ keywords.insert(QLatin1String("throw"));
+ keywords.insert(QLatin1String("true"));
+ keywords.insert(QLatin1String("try"));
+ keywords.insert(QLatin1String("typedef"));
+ keywords.insert(QLatin1String("typeid"));
+ keywords.insert(QLatin1String("typename"));
+ keywords.insert(QLatin1String("union"));
+ keywords.insert(QLatin1String("unsigned"));
+ keywords.insert(QLatin1String("using"));
+ keywords.insert(QLatin1String("virtual"));
+ keywords.insert(QLatin1String("void"));
+ keywords.insert(QLatin1String("volatile"));
+ keywords.insert(QLatin1String("wchar_t"));
+ keywords.insert(QLatin1String("while"));
+
+ // java keywords
+ keywords.insert(QLatin1String("abstract"));
+ keywords.insert(QLatin1String("assert"));
+ keywords.insert(QLatin1String("boolean"));
+ keywords.insert(QLatin1String("break"));
+ keywords.insert(QLatin1String("byte"));
+ keywords.insert(QLatin1String("case"));
+ keywords.insert(QLatin1String("catch"));
+ keywords.insert(QLatin1String("char"));
+ keywords.insert(QLatin1String("class"));
+ keywords.insert(QLatin1String("const"));
+ keywords.insert(QLatin1String("continue"));
+ keywords.insert(QLatin1String("default"));
+ keywords.insert(QLatin1String("do"));
+ keywords.insert(QLatin1String("double"));
+ keywords.insert(QLatin1String("else"));
+ keywords.insert(QLatin1String("enum"));
+ keywords.insert(QLatin1String("extends"));
+ keywords.insert(QLatin1String("false"));
+ keywords.insert(QLatin1String("final"));
+ keywords.insert(QLatin1String("finality"));
+ keywords.insert(QLatin1String("float"));
+ keywords.insert(QLatin1String("for"));
+ keywords.insert(QLatin1String("goto"));
+ keywords.insert(QLatin1String("if"));
+ keywords.insert(QLatin1String("implements"));
+ keywords.insert(QLatin1String("import"));
+ keywords.insert(QLatin1String("instanceof"));
+ keywords.insert(QLatin1String("int"));
+ keywords.insert(QLatin1String("interface"));
+ keywords.insert(QLatin1String("long"));
+ keywords.insert(QLatin1String("native"));
+ keywords.insert(QLatin1String("new"));
+ keywords.insert(QLatin1String("null"));
+ keywords.insert(QLatin1String("package"));
+ keywords.insert(QLatin1String("private"));
+ keywords.insert(QLatin1String("protected"));
+ keywords.insert(QLatin1String("public"));
+ keywords.insert(QLatin1String("return"));
+ keywords.insert(QLatin1String("short"));
+ keywords.insert(QLatin1String("static"));
+ keywords.insert(QLatin1String("strictfp"));
+ keywords.insert(QLatin1String("super"));
+ keywords.insert(QLatin1String("switch"));
+ keywords.insert(QLatin1String("synchronized"));
+ keywords.insert(QLatin1String("this"));
+ keywords.insert(QLatin1String("throw"));
+ keywords.insert(QLatin1String("throws"));
+ keywords.insert(QLatin1String("transient"));
+ keywords.insert(QLatin1String("true"));
+ keywords.insert(QLatin1String("try"));
+ keywords.insert(QLatin1String("void"));
+ keywords.insert(QLatin1String("volatile"));
+ keywords.insert(QLatin1String("while"));
+ }
+ return keywords;
+}
+
+bool FormWindow::unify(QObject *w, QString &s, bool changeIt)
+{
+ typedef QSet<QString> StringSet;
+
+ QWidget *main = mainContainer();
+ if (!main)
+ return true;
+
+ StringSet existingNames = languageKeywords();
+ // build a set of existing names of other widget excluding self
+ if (!(w->isWidgetType() && isMainContainer(qobject_cast<QWidget*>(w))))
+ existingNames.insert(main->objectName());
+
+ const QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();
+ const QWidgetList widgetChildren = main->findChildren<QWidget*>();
+ if (!widgetChildren.empty())
+ insertNames(metaDataBase, widgetChildren.constBegin(), widgetChildren.constEnd(), w, existingNames);
+
+ const QList<QLayout *> layoutChildren = main->findChildren<QLayout*>();
+ if (!layoutChildren.empty())
+ insertNames(metaDataBase, layoutChildren.constBegin(), layoutChildren.constEnd(), w, existingNames);
+
+ const QList<QAction *> actionChildren = main->findChildren<QAction*>();
+ if (!actionChildren.empty())
+ insertNames(metaDataBase, actionChildren.constBegin(), actionChildren.constEnd(), w, existingNames);
+
+ const QList<QButtonGroup *> buttonGroupChildren = main->findChildren<QButtonGroup*>();
+ if (!buttonGroupChildren.empty())
+ insertNames(metaDataBase, buttonGroupChildren.constBegin(), buttonGroupChildren.constEnd(), w, existingNames);
+
+ const StringSet::const_iterator enEnd = existingNames.constEnd();
+ if (existingNames.constFind(s) == enEnd)
+ return true;
+ else
+ if (!changeIt)
+ return false;
+
+ // split 'name_number'
+ qlonglong num = 0;
+ qlonglong factor = 1;
+ int idx = s.length()-1;
+ const ushort zeroUnicode = QLatin1Char('0').unicode();
+ for ( ; idx > 0 && s.at(idx).isDigit(); --idx) {
+ num += (s.at(idx).unicode() - zeroUnicode) * factor;
+ factor *= 10;
+ }
+ // Position index past '_'.
+ const QChar underscore = QLatin1Char('_');
+ if (idx >= 0 && s.at(idx) == underscore) {
+ idx++;
+ } else {
+ num = 1;
+ s += underscore;
+ idx = s.length();
+ }
+ // try 'name_n', 'name_n+1'
+ for (num++ ; ;num++) {
+ s.truncate(idx);
+ s += QString::number(num);
+ if (existingNames.constFind(s) == enEnd)
+ break;
+ }
+ return false;
+}
+/* already_in_form is true when we are moving a widget from one parent to another inside the same
+ * form. All this means is that InsertWidgetCommand::undo() must not unmanage it. */
+
+void FormWindow::insertWidget(QWidget *w, const QRect &rect, QWidget *container, bool already_in_form)
+{
+ clearSelection(false);
+
+ beginCommand(tr("Insert widget '%1'").arg(WidgetFactory::classNameOf(m_core, w))); // ### use the WidgetDatabaseItem
+
+ /* Reparenting into a QSplitter automatically adjusts child's geometry. We create the geometry
+ * command before we push the reparent command, so that the geometry command has the original
+ * geometry of the widget. */
+ QRect r = rect;
+ Q_ASSERT(r.isValid());
+ SetPropertyCommand *geom_cmd = new SetPropertyCommand(this);
+ geom_cmd->init(w, QLatin1String("geometry"), r); // ### use rc.size()
+
+ if (w->parentWidget() != container) {
+ ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
+ cmd->init(w, container);
+ m_undoStack.push(cmd);
+ }
+
+ m_undoStack.push(geom_cmd);
+
+ InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
+ cmd->init(w, already_in_form);
+ m_undoStack.push(cmd);
+
+ endCommand();
+
+ w->show();
+}
+
+QWidget *FormWindow::createWidget(DomUI *ui, const QRect &rc, QWidget *target)
+{
+ QWidget *container = findContainer(target, false);
+ if (!container)
+ return 0;
+ if (isMainContainer(container)) {
+ if (QMainWindow *mw = qobject_cast<QMainWindow*>(container)) {
+ Q_ASSERT(mw->centralWidget() != 0);
+ container = mw->centralWidget();
+ }
+ }
+ QDesignerResource resource(this);
+ const FormBuilderClipboard clipboard = resource.paste(ui, container);
+ if (clipboard.m_widgets.size() != 1) // multiple-paste from DomUI not supported yet
+ return 0;
+ QWidget *widget = clipboard.m_widgets.first();
+ insertWidget(widget, rc, container);
+ return widget;
+}
+
+#ifndef QT_NO_DEBUG
+static bool isDescendant(const QWidget *parent, const QWidget *child)
+{
+ for (; child != 0; child = child->parentWidget()) {
+ if (child == parent)
+ return true;
+ }
+ return false;
+}
+#endif
+
+void FormWindow::resizeWidget(QWidget *widget, const QRect &geometry)
+{
+ Q_ASSERT(isDescendant(this, widget));
+
+ QRect r = geometry;
+ SetPropertyCommand *cmd = new SetPropertyCommand(this);
+ cmd->init(widget, QLatin1String("geometry"), r);
+ cmd->setText(tr("Resize"));
+ m_undoStack.push(cmd);
+}
+
+void FormWindow::raiseChildSelections(QWidget *w)
+{
+ const QWidgetList l = w->findChildren<QWidget*>();
+ if (l.isEmpty())
+ return;
+ m_selection->raiseList(l);
+}
+
+QWidget *FormWindow::containerAt(const QPoint &pos, QWidget *notParentOf)
+{
+ QWidget *container = 0;
+ int depth = -1;
+ const QWidgetList selected = selectedWidgets();
+ if (rect().contains(mapFromGlobal(pos))) {
+ container = mainContainer();
+ depth = widgetDepth(container);
+ }
+
+ QListIterator<QWidget*> it(m_widgets);
+ while (it.hasNext()) {
+ QWidget *wit = it.next();
+ if (qobject_cast<QLayoutWidget*>(wit) || qobject_cast<QSplitter*>(wit))
+ continue;
+ if (!wit->isVisibleTo(this))
+ continue;
+ if (selected.indexOf(wit) != -1)
+ continue;
+ if (!core()->widgetDataBase()->isContainer(wit) &&
+ wit != mainContainer())
+ continue;
+
+ // the rectangles of all ancestors of the container must contain the insert position
+ QWidget *w = wit;
+ while (w && !w->isWindow()) {
+ if (!w->rect().contains((w->mapFromGlobal(pos))))
+ break;
+ w = w->parentWidget();
+ }
+ if (!(w == 0 || w->isWindow()))
+ continue; // we did not get through the full while loop
+
+ int wd = widgetDepth(wit);
+ if (wd == depth && container) {
+ if (wit->parentWidget()->children().indexOf(wit) >
+ container->parentWidget()->children().indexOf(container))
+ wd++;
+ }
+ if (wd > depth && !isChildOf(wit, notParentOf)) {
+ depth = wd;
+ container = wit;
+ }
+ }
+ return container;
+}
+
+QWidgetList FormWindow::selectedWidgets() const
+{
+ return m_selection->selectedWidgets();
+}
+
+void FormWindow::selectWidgets()
+{
+ bool selectionChanged = false;
+ const QWidgetList l = mainContainer()->findChildren<QWidget*>();
+ QListIterator <QWidget*> it(l);
+ const QRect selRect(mapToGlobal(m_currRect.topLeft()), m_currRect.size());
+ while (it.hasNext()) {
+ QWidget *w = it.next();
+ if (w->isVisibleTo(this) && isManaged(w)) {
+ const QPoint p = w->mapToGlobal(QPoint(0,0));
+ const QRect r(p, w->size());
+ if (r.intersects(selRect) && !r.contains(selRect) && trySelectWidget(w, true))
+ selectionChanged = true;
+ }
+ }
+
+ if (selectionChanged)
+ emitSelectionChanged();
+}
+
+bool FormWindow::handleKeyPressEvent(QWidget *widget, QWidget *, QKeyEvent *e)
+{
+ if (qobject_cast<const FormWindow*>(widget) || qobject_cast<const QMenu*>(widget))
+ return false;
+
+ e->accept(); // we always accept!
+
+ switch (e->key()) {
+ default: break; // we don't care about the other keys
+
+ case Qt::Key_Delete:
+ case Qt::Key_Backspace:
+ if (e->modifiers() == Qt::NoModifier)
+ deleteWidgets();
+ break;
+
+ case Qt::Key_Tab:
+ if (e->modifiers() == Qt::NoModifier)
+ cursor()->movePosition(QDesignerFormWindowCursorInterface::Next);
+ break;
+
+ case Qt::Key_Backtab:
+ if (e->modifiers() == Qt::NoModifier)
+ cursor()->movePosition(QDesignerFormWindowCursorInterface::Prev);
+ break;
+
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ handleArrowKeyEvent(e->key(), e->modifiers());
+ break;
+ }
+
+ return true;
+}
+
+int FormWindow::getValue(const QRect &rect, int key, bool size) const
+{
+ if (size) {
+ if (key == Qt::Key_Left || key == Qt::Key_Right)
+ return rect.width();
+ return rect.height();
+ }
+ if (key == Qt::Key_Left || key == Qt::Key_Right)
+ return rect.x();
+ return rect.y();
+}
+
+int FormWindow::calcValue(int val, bool forward, bool snap, int snapOffset) const
+{
+ if (snap) {
+ const int rest = val % snapOffset;
+ if (rest) {
+ const int offset = forward ? snapOffset : 0;
+ const int newOffset = rest < 0 ? offset - snapOffset : offset;
+ return val + newOffset - rest;
+ }
+ return (forward ? val + snapOffset : val - snapOffset);
+ }
+ return (forward ? val + 1 : val - 1);
+}
+
+// ArrowKeyOperation: Stores a keyboard move or resize (Shift pressed)
+// operation.
+struct ArrowKeyOperation {
+ ArrowKeyOperation() : resize(false), distance(0), arrowKey(Qt::Key_Left) {}
+
+ QRect apply(const QRect &in) const;
+
+ bool resize; // Resize: Shift-Key->drag bottom/right corner, else just move
+ int distance;
+ int arrowKey;
+};
+
+} // namespace
+
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(qdesigner_internal::ArrowKeyOperation)
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QRect ArrowKeyOperation::apply(const QRect &rect) const
+{
+ QRect r = rect;
+ if (resize) {
+ if (arrowKey == Qt::Key_Left || arrowKey == Qt::Key_Right)
+ r.setWidth(r.width() + distance);
+ else
+ r.setHeight(r.height() + distance);
+ } else {
+ if (arrowKey == Qt::Key_Left || arrowKey == Qt::Key_Right)
+ r.moveLeft(r.x() + distance);
+ else
+ r.moveTop(r.y() + distance);
+ }
+ return r;
+}
+
+QDebug operator<<(QDebug in, const ArrowKeyOperation &op)
+{
+ in.nospace() << "Resize=" << op.resize << " dist=" << op.distance << " Key=" << op.arrowKey << ' ';
+ return in;
+}
+
+// ArrowKeyPropertyHelper: Applies a struct ArrowKeyOperation
+// (stored as new value) to a list of widgets using to calculate the
+// changed geometry of the widget in setValue(). Thus, the 'newValue'
+// of the property command is the relative move distance, which is the same
+// for all widgets (although resulting in different geometries for the widgets).
+// The command merging can then work as it would when applying the same text
+// to all QLabels.
+
+class ArrowKeyPropertyHelper : public PropertyHelper {
+public:
+ ArrowKeyPropertyHelper(QObject* o, SpecialProperty sp,
+ QDesignerPropertySheetExtension *s, int i) :
+ PropertyHelper(o, sp, s, i) {}
+
+ virtual Value setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask);
+};
+
+PropertyHelper::Value ArrowKeyPropertyHelper::setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask)
+{
+ // Apply operation to obtain the new geometry value.
+ QWidget *w = qobject_cast<QWidget*>(object());
+ const ArrowKeyOperation operation = qvariant_cast<ArrowKeyOperation>(value);
+ const QRect newGeom = operation.apply(w->geometry());
+ return PropertyHelper::setValue(fw, QVariant(newGeom), changed, subPropertyMask);
+}
+
+// ArrowKeyPropertyCommand: Helper factory overwritten to create
+// ArrowKeyPropertyHelper and a merge operation that merges values of
+// the same direction.
+class ArrowKeyPropertyCommand: public SetPropertyCommand {
+public:
+ explicit ArrowKeyPropertyCommand(QDesignerFormWindowInterface *fw,
+ QUndoCommand *p = 0);
+
+ void init(QWidgetList &l, const ArrowKeyOperation &op);
+
+protected:
+ virtual PropertyHelper *createPropertyHelper(QObject *o, SpecialProperty sp,
+ QDesignerPropertySheetExtension *s, int i) const
+ { return new ArrowKeyPropertyHelper(o, sp, s, i); }
+ virtual QVariant mergeValue(const QVariant &newValue);
+};
+
+ArrowKeyPropertyCommand::ArrowKeyPropertyCommand(QDesignerFormWindowInterface *fw,
+ QUndoCommand *p) :
+ SetPropertyCommand(fw, p)
+{
+ static const int mid = qRegisterMetaType<qdesigner_internal::ArrowKeyOperation>();
+ Q_UNUSED(mid)
+}
+
+void ArrowKeyPropertyCommand::init(QWidgetList &l, const ArrowKeyOperation &op)
+{
+ QObjectList ol;
+ foreach(QWidget *w, l)
+ ol.push_back(w);
+ SetPropertyCommand::init(ol, QLatin1String("geometry"), QVariant::fromValue(op));
+
+ setText(op.resize ? FormWindow::tr("Key Resize") : FormWindow::tr("Key Move"));
+}
+
+QVariant ArrowKeyPropertyCommand::mergeValue(const QVariant &newMergeValue)
+{
+ // Merge move operations of the same arrow key
+ if (!newMergeValue.canConvert<ArrowKeyOperation>())
+ return QVariant();
+ ArrowKeyOperation mergedOperation = qvariant_cast<ArrowKeyOperation>(newValue());
+ const ArrowKeyOperation newMergeOperation = qvariant_cast<ArrowKeyOperation>(newMergeValue);
+ if (mergedOperation.resize != newMergeOperation.resize || mergedOperation.arrowKey != newMergeOperation.arrowKey)
+ return QVariant();
+ mergedOperation.distance += newMergeOperation.distance;
+ return QVariant::fromValue(mergedOperation);
+}
+
+void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers)
+{
+ const QDesignerFormWindowCursorInterface *c = cursor();
+ if (!c->hasSelection())
+ return;
+
+ QWidgetList selection;
+
+ // check if a laid out widget is selected
+ const int count = c->selectedWidgetCount();
+ for (int index = 0; index < count; ++index) {
+ QWidget *w = c->selectedWidget(index);
+ if (!LayoutInfo::isWidgetLaidout(m_core, w))
+ selection.append(w);
+ }
+
+ if (selection.isEmpty())
+ return;
+
+ QWidget *current = c->current();
+ if (!current || LayoutInfo::isWidgetLaidout(m_core, current)) {
+ current = selection.first();
+ }
+
+ const bool size = modifiers & Qt::ShiftModifier;
+
+ const bool snap = !(modifiers & Qt::ControlModifier);
+ const bool forward = (key == Qt::Key_Right || key == Qt::Key_Down);
+ const int snapPoint = (key == Qt::Key_Left || key == Qt::Key_Right) ? grid().x() : grid().y();
+
+ const int oldValue = getValue(current->geometry(), key, size);
+
+ const int newValue = calcValue(oldValue, forward, snap, snapPoint);
+
+ ArrowKeyOperation operation;
+ operation.resize = modifiers & Qt::ShiftModifier;
+ operation.distance = newValue - oldValue;
+ operation.arrowKey = key;
+
+ ArrowKeyPropertyCommand *cmd = new ArrowKeyPropertyCommand(this);
+ cmd->init(selection, operation);
+ m_undoStack.push(cmd);
+}
+
+bool FormWindow::handleKeyReleaseEvent(QWidget *, QWidget *, QKeyEvent *e)
+{
+ e->accept();
+ return true;
+}
+
+void FormWindow::selectAll()
+{
+ bool selectionChanged = false;
+ foreach (QWidget *widget, m_widgets) {
+ if (widget->isVisibleTo(this) && trySelectWidget(widget, true))
+ selectionChanged = true;
+ }
+ if (selectionChanged)
+ emitSelectionChanged();
+}
+
+void FormWindow::createLayout(int type, QWidget *container)
+{
+ if (container) {
+ layoutContainer(container, type);
+ } else {
+ LayoutCommand *cmd = new LayoutCommand(this);
+ cmd->init(mainContainer(), selectedWidgets(), static_cast<LayoutInfo::Type>(type));
+ commandHistory()->push(cmd);
+ }
+}
+
+void FormWindow::morphLayout(QWidget *container, int newType)
+{
+ MorphLayoutCommand *cmd = new MorphLayoutCommand(this);
+ if (cmd->init(container, newType)) {
+ commandHistory()->push(cmd);
+ } else {
+ qDebug() << "** WARNING Unable to morph layout.";
+ delete cmd;
+ }
+}
+
+void FormWindow::deleteWidgets()
+{
+ QWidgetList selection = selectedWidgets();
+ simplifySelection(&selection);
+
+ deleteWidgetList(selection);
+}
+
+QString FormWindow::fileName() const
+{
+ return m_fileName;
+}
+
+void FormWindow::setFileName(const QString &fileName)
+{
+ if (m_fileName == fileName)
+ return;
+
+ m_fileName = fileName;
+ emit fileNameChanged(fileName);
+}
+
+QString FormWindow::contents() const
+{
+ QBuffer b;
+ if (!mainContainer() || !b.open(QIODevice::WriteOnly))
+ return QString();
+
+ QDesignerResource resource(const_cast<FormWindow*>(this));
+ resource.save(&b, mainContainer());
+
+ return QString::fromUtf8(b.buffer());
+}
+
+void FormWindow::copy()
+{
+ QBuffer b;
+ if (!b.open(QIODevice::WriteOnly))
+ return;
+
+ FormBuilderClipboard clipboard;
+ QDesignerResource resource(this);
+ resource.setSaveRelative(false);
+ clipboard.m_widgets = selectedWidgets();
+ simplifySelection(&clipboard.m_widgets);
+ resource.copy(&b, clipboard);
+
+ qApp->clipboard()->setText(QString::fromUtf8(b.buffer()), QClipboard::Clipboard);
+}
+
+void FormWindow::cut()
+{
+ copy();
+ deleteWidgets();
+}
+
+// for cases like QMainWindow (central widget is an inner container) or QStackedWidget (page is an inner container)
+QWidget *FormWindow::innerContainer(QWidget *outerContainer) const
+{
+ if (m_core->widgetDataBase()->isContainer(outerContainer))
+ if (const QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), outerContainer)) {
+ const int currentIndex = container->currentIndex();
+ return currentIndex >= 0 ?
+ container->widget(currentIndex) :
+ static_cast<QWidget *>(0);
+ }
+ return outerContainer;
+}
+
+QWidget *FormWindow::containerForPaste() const
+{
+ QWidget *w = mainContainer();
+ if (!w)
+ return 0;
+ do {
+ // Try to find a close parent, for example a non-laid-out
+ // QFrame/QGroupBox when a widget within it is selected.
+ QWidgetList selection = selectedWidgets();
+ if (selection.empty())
+ break;
+ simplifySelection(&selection);
+
+ QWidget *containerOfW = findContainer(selection.first(), /* exclude layouts */ true);
+ if (!containerOfW || containerOfW == mainContainer())
+ break;
+ // No layouts, must be container. No empty page-based containers.
+ containerOfW = innerContainer(containerOfW);
+ if (!containerOfW)
+ break;
+ if (LayoutInfo::layoutType(m_core, containerOfW) != LayoutInfo::NoLayout || !m_core->widgetDataBase()->isContainer(containerOfW))
+ break;
+ w = containerOfW;
+ } while (false);
+ // First check for layout (note that it does not cover QMainWindow
+ // and the like as the central widget has the layout).
+
+ w = innerContainer(w);
+ if (!w)
+ return 0;
+ if (LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout)
+ return 0;
+ // Go up via container extension (also includes step from QMainWindow to its central widget)
+ w = m_core->widgetFactory()->containerOfWidget(w);
+ if (w == 0 || LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout)
+ return 0;
+
+ if (debugFormWindow)
+ qDebug() <<"containerForPaste() " << w;
+ return w;
+}
+
+void FormWindow::paste()
+{
+ paste(PasteAll);
+}
+
+// Construct DomUI from clipboard (paste) and determine number of widgets/actions.
+static inline DomUI *domUIFromClipboard(int *widgetCount, int *actionCount)
+{
+ *widgetCount = *actionCount = 0;
+ const QString clipboardText = qApp->clipboard()->text();
+ if (clipboardText.isEmpty() || clipboardText.indexOf(QLatin1Char('<')) == -1)
+ return 0;
+
+ QXmlStreamReader reader(clipboardText);
+ DomUI *ui = 0;
+ const QString uiElement = QLatin1String("ui");
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0 && !ui) {
+ ui = new DomUI();
+ ui->read(reader);
+ break;
+ } else {
+ reader.raiseError(QCoreApplication::translate("FormWindow", "Unexpected element <%1>").arg(reader.name().toString()));
+ }
+ }
+ }
+ if (reader.hasError()) {
+ delete ui;
+ ui = 0;
+ designerWarning(QCoreApplication::translate("FormWindow", "Error while pasting clipboard contents at line %1, column %2: %3").
+ arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()));
+ return 0;
+ }
+
+ if (const DomWidget *topLevel = ui->elementWidget()) {
+ *widgetCount = topLevel->elementWidget().size();
+ *actionCount = topLevel->elementAction().size();
+ }
+ if (*widgetCount == 0 && *actionCount == 0) {
+ delete ui;
+ return 0;
+ }
+ return ui;
+}
+
+static inline QString pasteCommandDescription(int widgetCount, int actionCount)
+{
+ if (widgetCount == 0)
+ return FormWindow::tr("Paste %n action(s)", 0, actionCount);
+ if (actionCount == 0)
+ return FormWindow::tr("Paste %n widget(s)", 0, widgetCount);
+ return FormWindow::tr("Paste (%1 widgets, %2 actions)").arg(widgetCount).arg(actionCount);
+}
+
+static void positionPastedWidgetsAtMousePosition(FormWindow *fw, const QPoint &contextMenuPosition, QWidget *parent, const QWidgetList &l)
+{
+ // Try to position pasted widgets at mouse position (current mouse position for Ctrl-V or position of context menu)
+ // if it fits. If it is completely outside, force it to 0,0
+ // If it fails, the old coordinates relative to the previous parent will be used.
+ QPoint currentPos = contextMenuPosition.x() >=0 ? parent->mapFrom(fw, contextMenuPosition) : parent->mapFromGlobal(QCursor::pos());
+ const Grid &grid = fw->designerGrid();
+ QPoint cursorPos = grid.snapPoint(currentPos);
+ const QRect parentGeometry = QRect(QPoint(0, 0), parent->size());
+ const bool outside = !parentGeometry.contains(cursorPos);
+ if (outside)
+ cursorPos = grid.snapPoint(QPoint(0, 0));
+ // Determine area of pasted widgets
+ QRect pasteArea;
+ const QWidgetList::const_iterator lcend = l.constEnd();
+ for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it)
+ pasteArea =pasteArea.isNull() ? (*it)->geometry() : pasteArea.united((*it)->geometry());
+
+ // Mouse on some child? (try to position bottomRight on a free spot to
+ // get the stacked-offset effect of Designer 4.3, that is, offset by grid if Ctrl-V is pressed continuously
+ do {
+ const QPoint bottomRight = cursorPos + QPoint(pasteArea.width(), pasteArea.height()) - QPoint(1, 1);
+ if (bottomRight.y() > parentGeometry.bottom() || parent->childAt(bottomRight) == 0)
+ break;
+ cursorPos += QPoint(grid.deltaX(), grid.deltaY());
+ } while (true);
+ // Move.
+ const QPoint offset = cursorPos - pasteArea.topLeft();
+ for (QWidgetList::const_iterator it = l.constBegin(); it != lcend; ++it)
+ (*it)->move((*it)->pos() + offset);
+}
+
+void FormWindow::paste(PasteMode pasteMode)
+{
+ // Avoid QDesignerResource constructing widgets that are not used as
+ // QDesignerResource manages the widgets it creates (creating havoc if one remains unused)
+ DomUI *ui = 0;
+ do {
+ int widgetCount;
+ int actionCount;
+ ui = domUIFromClipboard(&widgetCount, &actionCount);
+ if (!ui)
+ break;
+
+ // Check for actions
+ if (pasteMode == PasteActionsOnly)
+ if (widgetCount != 0 || actionCount == 0)
+ break;
+
+ // Check for widgets: need a container
+ QWidget *pasteContainer = widgetCount ? containerForPaste() : 0;
+ if (widgetCount && pasteContainer == 0) {
+
+ const QString message = tr("Cannot paste widgets. Designer could not find a container "
+ "without a layout to paste into.");
+ const QString infoMessage = tr("Break the layout of the "
+ "container you want to paste into, select this container "
+ "and then paste again.");
+ core()->dialogGui()->message(this, QDesignerDialogGuiInterface::FormEditorMessage, QMessageBox::Information,
+ tr("Paste error"), message, infoMessage, QMessageBox::Ok);
+ break;
+ }
+
+ QDesignerResource resource(this);
+ // Note that the widget factory must be able to locate the
+ // form window (us) via parent, otherwise, it will not able to construct QLayoutWidgets
+ // (It will then default to widgets) among other issues.
+ const FormBuilderClipboard clipboard = resource.paste(ui, pasteContainer, this);
+
+ clearSelection(false);
+ // Create command sequence
+ beginCommand(pasteCommandDescription(widgetCount, actionCount));
+
+ if (widgetCount) {
+ positionPastedWidgetsAtMousePosition(this, m_contextMenuPosition, pasteContainer, clipboard.m_widgets);
+ foreach (QWidget *w, clipboard.m_widgets) {
+ InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
+ cmd->init(w);
+ m_undoStack.push(cmd);
+ selectWidget(w);
+ }
+ }
+
+ if (actionCount)
+ foreach (QAction *a, clipboard.m_actions) {
+ ensureUniqueObjectName(a);
+ AddActionCommand *cmd = new AddActionCommand(this);
+ cmd->init(a);
+ m_undoStack.push(cmd);
+ }
+ endCommand();
+ } while (false);
+ delete ui;
+}
+
+// Draw a dotted frame around containers
+bool FormWindow::frameNeeded(QWidget *w) const
+{
+ if (!core()->widgetDataBase()->isContainer(w))
+ return false;
+ if (qobject_cast<QGroupBox *>(w))
+ return false;
+ if (qobject_cast<QToolBox *>(w))
+ return false;
+ if (qobject_cast<QTabWidget *>(w))
+ return false;
+ if (qobject_cast<QStackedWidget *>(w))
+ return false;
+ if (qobject_cast<QDockWidget *>(w))
+ return false;
+ if (qobject_cast<QDesignerWidget *>(w))
+ return false;
+ if (qobject_cast<QMainWindow *>(w))
+ return false;
+ if (qobject_cast<QDialog *>(w))
+ return false;
+ if (qobject_cast<QLayoutWidget *>(w))
+ return false;
+ return true;
+}
+
+bool FormWindow::eventFilter(QObject *watched, QEvent *event)
+{
+ const bool ret = FormWindowBase::eventFilter(watched, event);
+ if (event->type() != QEvent::Paint)
+ return ret;
+
+ Q_ASSERT(watched->isWidgetType());
+ QWidget *w = static_cast<QWidget *>(watched);
+ QPaintEvent *pe = static_cast<QPaintEvent*>(event);
+ const QRect widgetRect = w->rect();
+ const QRect paintRect = pe->rect();
+ // Does the paint rectangle touch the borders of the widget rectangle
+ if (paintRect.x() > widgetRect.x() && paintRect.y() > widgetRect.y() &&
+ paintRect.right() < widgetRect.right() && paintRect.bottom() < widgetRect.bottom())
+ return ret;
+ QPainter p(w);
+ const QPen pen(QColor(0, 0, 0, 32), 0, Qt::DotLine);
+ p.setPen(pen);
+ p.setBrush(QBrush(Qt::NoBrush));
+ p.drawRect(widgetRect.adjusted(0, 0, -1, -1));
+ return ret;
+}
+
+void FormWindow::manageWidget(QWidget *w)
+{
+ if (isManaged(w))
+ return;
+
+ Q_ASSERT(qobject_cast<QMenu*>(w) == 0);
+
+ if (w->hasFocus())
+ setFocus();
+
+ core()->metaDataBase()->add(w);
+
+ m_insertedWidgets.insert(w);
+ m_widgets.append(w);
+
+#ifndef QT_NO_CURSOR
+ setCursorToAll(Qt::ArrowCursor, w);
+#endif
+
+ emit changed();
+ emit widgetManaged(w);
+
+ if (frameNeeded(w))
+ w->installEventFilter(this);
+}
+
+void FormWindow::unmanageWidget(QWidget *w)
+{
+ if (!isManaged(w))
+ return;
+
+ m_selection->removeWidget(w);
+
+ emit aboutToUnmanageWidget(w);
+
+ if (w == m_currentWidget)
+ setCurrentWidget(mainContainer());
+
+ core()->metaDataBase()->remove(w);
+
+ m_insertedWidgets.remove(w);
+ m_widgets.removeAt(m_widgets.indexOf(w));
+
+ emit changed();
+ emit widgetUnmanaged(w);
+
+ if (frameNeeded(w))
+ w->removeEventFilter(this);
+}
+
+bool FormWindow::isManaged(QWidget *w) const
+{
+ return m_insertedWidgets.contains(w);
+}
+
+void FormWindow::breakLayout(QWidget *w)
+{
+ if (w == this)
+ w = mainContainer();
+ // Find the first-order managed child widgets
+ QWidgetList widgets;
+
+ const QObjectList children = w->children();
+ const QObjectList::const_iterator cend = children.constEnd();
+ const QDesignerMetaDataBaseInterface *mdb = core()->metaDataBase();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it)
+ if ( (*it)->isWidgetType()) {
+ QWidget *w = static_cast<QWidget*>(*it);
+ if (mdb->item(w))
+ widgets.push_back(w);
+ }
+
+ BreakLayoutCommand *cmd = new BreakLayoutCommand(this);
+ cmd->init(widgets, w);
+ commandHistory()->push(cmd);
+ clearSelection(false);
+}
+
+void FormWindow::beginCommand(const QString &description)
+{
+ m_undoStack.beginMacro(description);
+}
+
+void FormWindow::endCommand()
+{
+ m_undoStack.endMacro();
+}
+
+void FormWindow::raiseWidgets()
+{
+ QWidgetList widgets = selectedWidgets();
+ simplifySelection(&widgets);
+
+ if (widgets.isEmpty())
+ return;
+
+ beginCommand(tr("Raise widgets"));
+ foreach (QWidget *widget, widgets) {
+ RaiseWidgetCommand *cmd = new RaiseWidgetCommand(this);
+ cmd->init(widget);
+ m_undoStack.push(cmd);
+ }
+ endCommand();
+}
+
+void FormWindow::lowerWidgets()
+{
+ QWidgetList widgets = selectedWidgets();
+ simplifySelection(&widgets);
+
+ if (widgets.isEmpty())
+ return;
+
+ beginCommand(tr("Lower widgets"));
+ foreach (QWidget *widget, widgets) {
+ LowerWidgetCommand *cmd = new LowerWidgetCommand(this);
+ cmd->init(widget);
+ m_undoStack.push(cmd);
+ }
+ endCommand();
+}
+
+bool FormWindow::handleMouseButtonDblClickEvent(QWidget *w, QWidget *managedWidget, QMouseEvent *e)
+{
+ if (debugFormWindow)
+ qDebug() << "handleMouseButtonDblClickEvent:" << w << ',' << managedWidget << "state=" << m_mouseState;
+
+ e->accept();
+
+ // Might be out of sync due cycling of the parent selection
+ // In that case, do nothing
+ if (isWidgetSelected(managedWidget))
+ emit activated(managedWidget);
+
+ m_mouseState = MouseDoubleClicked;
+ return true;
+}
+
+
+QMenu *FormWindow::initializePopupMenu(QWidget *managedWidget)
+{
+ if (!isManaged(managedWidget) || currentTool())
+ return 0;
+
+ // Make sure the managedWidget is selected and current since
+ // the SetPropertyCommands must use the right reference
+ // object obtained from the property editor for the property group
+ // of a multiselection to be correct.
+ const bool selected = isWidgetSelected(managedWidget);
+ bool update = false;
+ if (selected == false) {
+ clearObjectInspectorSelection(m_core); // We might have a toolbar or non-widget selected in the object inspector.
+ clearSelection(false);
+ update = trySelectWidget(managedWidget, true);
+ raiseChildSelections(managedWidget); // raise selections and select widget
+ } else {
+ update = setCurrentWidget(managedWidget);
+ }
+
+ if (update) {
+ emitSelectionChanged();
+ QMetaObject::invokeMethod(core()->formWindowManager(), "slotUpdateActions");
+ }
+
+ QWidget *contextMenuWidget = 0;
+
+ if (isMainContainer(managedWidget)) { // press on a child widget
+ contextMenuWidget = mainContainer();
+ } else { // press on a child widget
+ // if widget is laid out, find the first non-laid out super-widget
+ QWidget *realWidget = managedWidget; // but store the original one
+ QMainWindow *mw = qobject_cast<QMainWindow*>(mainContainer());
+
+ if (mw && mw->centralWidget() == realWidget) {
+ contextMenuWidget = managedWidget;
+ } else {
+ contextMenuWidget = realWidget;
+ }
+ }
+
+ if (!contextMenuWidget)
+ return 0;
+
+ QMenu *contextMenu = createPopupMenu(contextMenuWidget);
+ if (!contextMenu)
+ return 0;
+
+ emit contextMenuRequested(contextMenu, contextMenuWidget);
+ return contextMenu;
+}
+
+bool FormWindow::handleContextMenu(QWidget *, QWidget *managedWidget, QContextMenuEvent *e)
+{
+ QMenu *contextMenu = initializePopupMenu(managedWidget);
+ if (!contextMenu)
+ return false;
+ const QPoint globalPos = e->globalPos();
+ m_contextMenuPosition = mapFromGlobal (globalPos);
+ contextMenu->exec(globalPos);
+ delete contextMenu;
+ e->accept();
+ m_contextMenuPosition = QPoint(-1, -1);
+ return true;
+}
+
+void FormWindow::setContents(QIODevice *dev)
+{
+ UpdateBlocker ub(this);
+ clearSelection();
+ m_selection->clearSelectionPool();
+ m_insertedWidgets.clear();
+ m_widgets.clear();
+ // The main container is cleared as otherwise
+ // the names of the newly loaded objects will be unified.
+ clearMainContainer();
+ emit changed();
+
+ QDesignerResource r(this);
+ QWidget *w = r.load(dev, formContainer());
+ setMainContainer(w);
+ emit changed();
+}
+
+void FormWindow::setContents(const QString &contents)
+{
+ QByteArray data = contents.toUtf8();
+ QBuffer b(&data);
+ if (b.open(QIODevice::ReadOnly))
+ setContents(&b);
+}
+
+void FormWindow::layoutContainer(QWidget *w, int type)
+{
+ if (w == this)
+ w = mainContainer();
+
+ w = core()->widgetFactory()->containerOfWidget(w);
+
+ const QObjectList l = w->children();
+ if (l.isEmpty())
+ return;
+ // find managed widget children
+ QWidgetList widgets;
+ const QObjectList::const_iterator ocend = l.constEnd();
+ for (QObjectList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it)
+ if ( (*it)->isWidgetType() ) {
+ QWidget *widget = static_cast<QWidget*>(*it);
+ if (widget->isVisibleTo(this) && isManaged(widget))
+ widgets.append(widget);
+ }
+
+ LayoutCommand *cmd = new LayoutCommand(this);
+ cmd->init(mainContainer(), widgets, static_cast<LayoutInfo::Type>(type), w);
+ clearSelection(false);
+ commandHistory()->push(cmd);
+}
+
+bool FormWindow::hasInsertedChildren(QWidget *widget) const // ### move
+{
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ const int index = container->currentIndex();
+ if (index < 0)
+ return false;
+ widget = container->widget(index);
+ }
+
+ const QWidgetList l = widgets(widget);
+
+ foreach (QWidget *child, l) {
+ if (isManaged(child) && !LayoutInfo::isWidgetLaidout(core(), child) && child->isVisibleTo(const_cast<FormWindow*>(this)))
+ return true;
+ }
+
+ return false;
+}
+
+// "Select Ancestor" sub menu code
+void FormWindow::slotSelectWidget(QAction *a)
+{
+ if (QWidget *w = qvariant_cast<QWidget*>(a->data()))
+ selectSingleWidget(w);
+}
+
+static inline QString objectNameOf(const QWidget *w)
+{
+ if (const QLayoutWidget *lw = qobject_cast<const QLayoutWidget *>(w)) {
+ const QLayout *layout = lw->layout();
+ const QString rc = layout->objectName();
+ if (!rc.isEmpty())
+ return rc;
+ // Fall thru for 4.3 forms which have a name on the widget: Display the class name
+ return QString::fromUtf8(layout->metaObject()->className());
+ }
+ return w->objectName();
+}
+
+QAction *FormWindow::createSelectAncestorSubMenu(QWidget *w)
+{
+ // Find the managed, unselected parents
+ QWidgetList parents;
+ QWidget *mc = mainContainer();
+ for (QWidget *p = w->parentWidget(); p && p != mc; p = p->parentWidget())
+ if (isManaged(p) && !isWidgetSelected(p))
+ parents.push_back(p);
+ if (parents.empty())
+ return 0;
+ // Create a submenu listing the managed, unselected parents
+ QMenu *menu = new QMenu;
+ QActionGroup *ag = new QActionGroup(menu);
+ QObject::connect(ag, SIGNAL(triggered(QAction*)), this, SLOT(slotSelectWidget(QAction*)));
+ const int size = parents.size();
+ for (int i = 0; i < size; i++) {
+ QWidget *w = parents.at(i);
+ QAction *a = ag->addAction(objectNameOf(w));
+ a->setData(QVariant::fromValue(w));
+ menu->addAction(a);
+ }
+ QAction *ma = new QAction(tr("Select Ancestor"), 0);
+ ma->setMenu(menu);
+ return ma;
+}
+
+QMenu *FormWindow::createPopupMenu(QWidget *w)
+{
+ QMenu *popup = createExtensionTaskMenu(this, w, true);
+ if (!popup)
+ popup = new QMenu;
+ // if w doesn't have a QDesignerTaskMenu as a child create one and make it a child.
+ // insert actions from QDesignerTaskMenu
+
+ QDesignerFormWindowManagerInterface *manager = core()->formWindowManager();
+ const bool isFormWindow = qobject_cast<const FormWindow*>(w);
+
+ // Check for special containers and obtain the page menu from them to add layout actions.
+ if (!isFormWindow) {
+ if (QStackedWidget *stackedWidget = qobject_cast<QStackedWidget*>(w)) {
+ QStackedWidgetEventFilter::addStackedWidgetContextMenuActions(stackedWidget, popup);
+ } else if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(w)) {
+ QTabWidgetEventFilter::addTabWidgetContextMenuActions(tabWidget, popup);
+ } else if (QToolBox *toolBox = qobject_cast<QToolBox*>(w)) {
+ QToolBoxHelper::addToolBoxContextMenuActions(toolBox, popup);
+ }
+
+ if (manager->actionLower()->isEnabled()) {
+ popup->addAction(manager->actionLower());
+ popup->addAction(manager->actionRaise());
+ popup->addSeparator();
+ }
+ popup->addAction(manager->actionCut());
+ popup->addAction(manager->actionCopy());
+ }
+
+ popup->addAction(manager->actionPaste());
+
+ if (QAction *selectAncestorAction = createSelectAncestorSubMenu(w))
+ popup->addAction(selectAncestorAction);
+ popup->addAction(manager->actionSelectAll());
+
+ if (!isFormWindow) {
+ popup->addAction(manager->actionDelete());
+ }
+
+ popup->addSeparator();
+ QMenu *layoutMenu = popup->addMenu(tr("Lay out"));
+ layoutMenu->addAction(manager->actionAdjustSize());
+ layoutMenu->addAction(manager->actionHorizontalLayout());
+ layoutMenu->addAction(manager->actionVerticalLayout());
+ if (!isFormWindow) {
+ layoutMenu->addAction(manager->actionSplitHorizontal());
+ layoutMenu->addAction(manager->actionSplitVertical());
+ }
+ layoutMenu->addAction(manager->actionGridLayout());
+ layoutMenu->addAction(manager->actionFormLayout());
+ layoutMenu->addAction(manager->actionBreakLayout());
+ layoutMenu->addAction(manager->actionSimplifyLayout());
+
+ return popup;
+}
+
+void FormWindow::resizeEvent(QResizeEvent *e)
+{
+ m_geometryChangedTimer->start(10);
+
+ QWidget::resizeEvent(e);
+}
+
+/*!
+ Maps \a pos in \a w's coordinates to the form's coordinate system.
+
+ This is the equivalent to mapFromGlobal(w->mapToGlobal(pos)) but
+ avoids the two roundtrips to the X-Server on Unix/X11.
+ */
+QPoint FormWindow::mapToForm(const QWidget *w, const QPoint &pos) const
+{
+ QPoint p = pos;
+ const QWidget* i = w;
+ while (i && !i->isWindow() && !isMainContainer(i)) {
+ p = i->mapToParent(p);
+ i = i->parentWidget();
+ }
+
+ return mapFromGlobal(w->mapToGlobal(pos));
+}
+
+bool FormWindow::canBeBuddy(QWidget *w) const // ### rename me.
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), w)) {
+ const int index = sheet->indexOf(QLatin1String("focusPolicy"));
+ if (index != -1) {
+ bool ok = false;
+ const Qt::FocusPolicy q = static_cast<Qt::FocusPolicy>(Utils::valueOf(sheet->property(index), &ok));
+ return ok && q != Qt::NoFocus;
+ }
+ }
+
+ return false;
+}
+
+QWidget *FormWindow::findContainer(QWidget *w, bool excludeLayout) const
+{
+ if (!isChildOf(w, this)
+ || const_cast<const QWidget *>(w) == this)
+ return 0;
+
+ QDesignerWidgetFactoryInterface *widgetFactory = core()->widgetFactory();
+ QDesignerWidgetDataBaseInterface *widgetDataBase = core()->widgetDataBase();
+ QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();
+
+ QWidget *container = widgetFactory->containerOfWidget(mainContainer()); // default parent for new widget is the formwindow
+ if (!isMainContainer(w)) { // press was not on formwindow, check if we can find another parent
+ while (w) {
+ if (qobject_cast<InvisibleWidget*>(w) || !metaDataBase->item(w)) {
+ w = w->parentWidget();
+ continue;
+ }
+
+ const bool isContainer = widgetDataBase->isContainer(w, true) || w == mainContainer();
+
+ if (!isContainer || (excludeLayout && qobject_cast<QLayoutWidget*>(w))) { // ### skip QSplitter
+ w = w->parentWidget();
+ } else {
+ container = w;
+ break;
+ }
+ }
+ }
+
+ return container;
+}
+
+void FormWindow::simplifySelection(QWidgetList *sel) const
+{
+ if (sel->size() < 2)
+ return;
+ // Figure out which widgets should be removed from selection.
+ // We want to remove those whose parent widget is also in the
+ // selection (because the child widgets are contained by
+ // their parent, they shouldn't be in the selection --
+ // they are "implicitly" selected).
+ QWidget *mainC = mainContainer(); // Quick check for main container first
+ if (sel->contains(mainC)) {
+ sel->clear();
+ sel->push_back(mainC);
+ return;
+ }
+ typedef QVector<QWidget *> WidgetVector;
+ WidgetVector toBeRemoved;
+ toBeRemoved.reserve(sel->size());
+ const QWidgetList::const_iterator scend = sel->constEnd();
+ for (QWidgetList::const_iterator it = sel->constBegin(); it != scend; ++it) {
+ QWidget *child = *it;
+ for (QWidget *w = child; true ; ) { // Is any of the parents also selected?
+ QWidget *parent = w->parentWidget();
+ if (!parent || parent == mainC)
+ break;
+ if (sel->contains(parent)) {
+ toBeRemoved.append(child);
+ break;
+ }
+ w = parent;
+ }
+ }
+ // Now we can actually remove the widgets that were marked
+ // for removal in the previous pass.
+ if (!toBeRemoved.isEmpty()) {
+ const WidgetVector::const_iterator rcend = toBeRemoved.constEnd();
+ for (WidgetVector::const_iterator it = toBeRemoved.constBegin(); it != rcend; ++it)
+ sel->removeAll(*it);
+ }
+}
+
+FormWindow *FormWindow::findFormWindow(QWidget *w)
+{
+ return qobject_cast<FormWindow*>(QDesignerFormWindowInterface::findFormWindow(w));
+}
+
+bool FormWindow::isDirty() const
+{
+ return m_undoStack.isDirty();
+}
+
+void FormWindow::setDirty(bool dirty)
+{
+ m_undoStack.setDirty(dirty);
+}
+
+QWidget *FormWindow::containerAt(const QPoint &pos)
+{
+ QWidget *widget = widgetAt(pos);
+ return findContainer(widget, true);
+}
+
+static QWidget *childAt_SkipDropLine(QWidget *w, QPoint pos)
+{
+ const QObjectList child_list = w->children();
+ for (int i = child_list.size() - 1; i >= 0; --i) {
+ QObject *child_obj = child_list[i];
+ if (qobject_cast<WidgetHandle*>(child_obj) != 0)
+ continue;
+ QWidget *child = qobject_cast<QWidget*>(child_obj);
+ if (!child || child->isWindow() || !child->isVisible() ||
+ !child->geometry().contains(pos) || child->testAttribute(Qt::WA_TransparentForMouseEvents))
+ continue;
+ const QPoint childPos = child->mapFromParent(pos);
+ if (QWidget *res = childAt_SkipDropLine(child, childPos))
+ return res;
+ if (child->testAttribute(Qt::WA_MouseNoMask) || child->mask().contains(pos)
+ || child->mask().isEmpty())
+ return child;
+ }
+
+ return 0;
+}
+
+QWidget *FormWindow::widgetAt(const QPoint &pos)
+{
+ QWidget *w = childAt(pos);
+ if (qobject_cast<const WidgetHandle*>(w) != 0)
+ w = childAt_SkipDropLine(this, pos);
+ return (w == 0 || w == formContainer()) ? this : w;
+}
+
+void FormWindow::highlightWidget(QWidget *widget, const QPoint &pos, HighlightMode mode)
+{
+ Q_ASSERT(widget);
+
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*> (widget)) {
+ widget = mainWindow->centralWidget();
+ }
+
+ QWidget *container = findContainer(widget, false);
+
+ if (container == 0 || core()->metaDataBase()->item(container) == 0)
+ return;
+
+ if (QDesignerActionProviderExtension *g = qt_extension<QDesignerActionProviderExtension*>(core()->extensionManager(), container)) {
+ if (mode == Restore) {
+ g->adjustIndicator(QPoint());
+ } else {
+ const QPoint pt = widget->mapTo(container, pos);
+ g->adjustIndicator(pt);
+ }
+ } else if (QDesignerLayoutDecorationExtension *g = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), container)) {
+ if (mode == Restore) {
+ g->adjustIndicator(QPoint(), -1);
+ } else {
+ const QPoint pt = widget->mapTo(container, pos);
+ const int index = g->findItemAt(pt);
+ g->adjustIndicator(pt, index);
+ }
+ }
+
+ QMainWindow *mw = qobject_cast<QMainWindow*> (container);
+ if (container == mainContainer() || (mw && mw->centralWidget() && mw->centralWidget() == container))
+ return;
+
+ if (mode == Restore) {
+ const WidgetPaletteMap::iterator pit = m_palettesBeforeHighlight.find(container);
+ if (pit != m_palettesBeforeHighlight.end()) {
+ container->setPalette(pit.value().first);
+ container->setAutoFillBackground(pit.value().second);
+ m_palettesBeforeHighlight.erase(pit);
+ }
+ } else {
+ QPalette p = container->palette();
+ if (!m_palettesBeforeHighlight.contains(container)) {
+ PaletteAndFill paletteAndFill;
+ if (container->testAttribute(Qt::WA_SetPalette))
+ paletteAndFill.first = p;
+ paletteAndFill.second = container->autoFillBackground();
+ m_palettesBeforeHighlight.insert(container, paletteAndFill);
+ }
+
+ p.setColor(backgroundRole(), p.midlight().color());
+ container->setPalette(p);
+ container->setAutoFillBackground(true);
+ }
+}
+
+QWidgetList FormWindow::widgets(QWidget *widget) const
+{
+ const QObjectList children = widget->children();
+ if (children.empty())
+ return QWidgetList();
+ QWidgetList rc;
+ const QObjectList::const_iterator cend = children.constEnd();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it)
+ if ((*it)->isWidgetType()) {
+ QWidget *w = qobject_cast<QWidget*>(*it);
+ if (isManaged(w))
+ rc.push_back(w);
+ }
+ return rc;
+}
+
+int FormWindow::toolCount() const
+{
+ return m_widgetStack->count();
+}
+
+QDesignerFormWindowToolInterface *FormWindow::tool(int index) const
+{
+ return m_widgetStack->tool(index);
+}
+
+void FormWindow::registerTool(QDesignerFormWindowToolInterface *tool)
+{
+ Q_ASSERT(tool != 0);
+
+ m_widgetStack->addTool(tool);
+
+ if (m_mainContainer)
+ m_mainContainer->update();
+}
+
+void FormWindow::setCurrentTool(int index)
+{
+ m_widgetStack->setCurrentTool(index);
+}
+
+int FormWindow::currentTool() const
+{
+ return m_widgetStack->currentIndex();
+}
+
+bool FormWindow::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
+{
+ if (m_widgetStack == 0)
+ return false;
+
+ QDesignerFormWindowToolInterface *tool = m_widgetStack->currentTool();
+ if (tool == 0)
+ return false;
+
+ return tool->handleEvent(widget, managedWidget, event);
+}
+
+void FormWindow::initializeCoreTools()
+{
+ m_widgetEditor = new WidgetEditorTool(this);
+ registerTool(m_widgetEditor);
+}
+
+void FormWindow::checkSelection()
+{
+ m_checkSelectionTimer->start(0);
+}
+
+void FormWindow::checkSelectionNow()
+{
+ m_checkSelectionTimer->stop();
+
+ foreach (QWidget *widget, selectedWidgets()) {
+ updateSelection(widget);
+
+ if (LayoutInfo::layoutType(core(), widget) != LayoutInfo::NoLayout)
+ updateChildSelections(widget);
+ }
+}
+
+QString FormWindow::author() const
+{
+ return m_author;
+}
+
+QString FormWindow::comment() const
+{
+ return m_comment;
+}
+
+void FormWindow::setAuthor(const QString &author)
+{
+ m_author = author;
+}
+
+void FormWindow::setComment(const QString &comment)
+{
+ m_comment = comment;
+}
+
+void FormWindow::editWidgets()
+{
+ m_widgetEditor->action()->trigger();
+}
+
+QStringList FormWindow::resourceFiles() const
+{
+ return m_resourceFiles;
+}
+
+void FormWindow::addResourceFile(const QString &path)
+{
+ if (!m_resourceFiles.contains(path)) {
+ m_resourceFiles.append(path);
+ setDirty(true);
+ emit resourceFilesChanged();
+ }
+}
+
+void FormWindow::removeResourceFile(const QString &path)
+{
+ if (m_resourceFiles.removeAll(path) > 0) {
+ setDirty(true);
+ emit resourceFilesChanged();
+ }
+}
+
+bool FormWindow::blockSelectionChanged(bool b)
+{
+ const bool blocked = m_blockSelectionChanged;
+ m_blockSelectionChanged = b;
+ return blocked;
+}
+
+void FormWindow::editContents()
+{
+ const QWidgetList sel = selectedWidgets();
+ if (sel.count() == 1) {
+ QWidget *widget = sel.first();
+
+ if (QAction *a = preferredEditAction(core(), widget))
+ a->trigger();
+ }
+}
+
+void FormWindow::dragWidgetWithinForm(QWidget *widget, const QRect &targetGeometry, QWidget *targetContainer)
+{
+ const bool fromLayout = canDragWidgetInLayout(core(), widget);
+ const QDesignerLayoutDecorationExtension *targetDeco = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), targetContainer);
+ const bool toLayout = targetDeco != 0;
+
+ if (fromLayout) {
+ // Drag from Layout: We need to delete the widget properly to store the layout state
+ // Do not simplify the layout when dragging onto a layout
+ // as this might invalidate the insertion position if it is the same layout
+ DeleteWidgetCommand *cmd = new DeleteWidgetCommand(this);
+ unsigned deleteFlags = DeleteWidgetCommand::DoNotUnmanage;
+ if (toLayout)
+ deleteFlags |= DeleteWidgetCommand::DoNotSimplifyLayout;
+ cmd->init(widget, deleteFlags);
+ commandHistory()->push(cmd);
+ }
+
+ if (toLayout) {
+ // Drag from form to layout: just insert. Do not manage
+ insertWidget(widget, targetGeometry, targetContainer, true);
+ } else {
+ // into container without layout
+ if (targetContainer != widget->parent()) { // different parent
+ ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
+ cmd->init(widget, targetContainer );
+ commandHistory()->push(cmd);
+ }
+ resizeWidget(widget, targetGeometry);
+ selectWidget(widget, true);
+ widget->show();
+ }
+}
+
+static Qt::DockWidgetArea detectDropArea(QMainWindow *mainWindow, const QRect &area, const QPoint &drop)
+{
+ QPoint offset = area.topLeft();
+ QRect rect = area;
+ rect.moveTopLeft(QPoint(0, 0));
+ QPoint point = drop - offset;
+ const int x = point.x();
+ const int y = point.y();
+ const int w = rect.width();
+ const int h = rect.height();
+
+ if (rect.contains(point)) {
+ bool topRight = false;
+ bool topLeft = false;
+ if (w * y < h * x) // top and right, oterwise bottom and left
+ topRight = true;
+ if (w * y < h * (w - x)) // top and left, otherwise bottom and right
+ topLeft = true;
+
+ if (topRight && topLeft)
+ return Qt::TopDockWidgetArea;
+ else if (topRight && !topLeft)
+ return Qt::RightDockWidgetArea;
+ else if (!topRight && topLeft)
+ return Qt::LeftDockWidgetArea;
+ return Qt::BottomDockWidgetArea;
+ }
+
+ if (x < 0) {
+ if (y < 0)
+ return mainWindow->corner(Qt::TopLeftCorner);
+ else if (y > h)
+ return mainWindow->corner(Qt::BottomLeftCorner);
+ else
+ return Qt::LeftDockWidgetArea;
+ } else if (x > w) {
+ if (y < 0)
+ return mainWindow->corner(Qt::TopRightCorner);
+ else if (y > h)
+ return mainWindow->corner(Qt::BottomRightCorner);
+ else
+ return Qt::RightDockWidgetArea;
+ } else {
+ if (y < 0)
+ return Qt::TopDockWidgetArea;
+ else
+ return Qt::BottomDockWidgetArea;
+ }
+ return Qt::LeftDockWidgetArea;
+}
+
+bool FormWindow::dropDockWidget(QDesignerDnDItemInterface *item, const QPoint &global_mouse_pos)
+{
+ DomUI *dom_ui = item->domUi();
+
+ QMainWindow *mw = qobject_cast<QMainWindow *>(mainContainer());
+ if (!mw)
+ return false;
+
+ QDesignerResource resource(this);
+ const FormBuilderClipboard clipboard = resource.paste(dom_ui, mw);
+ if (clipboard.m_widgets.size() != 1) // multiple-paste from DomUI not supported yet
+ return false;
+
+ QWidget *centralWidget = mw->centralWidget();
+ QPoint localPos = centralWidget->mapFromGlobal(global_mouse_pos);
+ const QRect centralWidgetAreaRect = centralWidget->rect();
+ Qt::DockWidgetArea area = detectDropArea(mw, centralWidgetAreaRect, localPos);
+
+ beginCommand(tr("Drop widget"));
+
+ clearSelection(false);
+ highlightWidget(mw, QPoint(0, 0), FormWindow::Restore);
+
+ QWidget *widget = clipboard.m_widgets.first();
+
+ insertWidget(widget, QRect(0, 0, 1, 1), mw);
+
+ selectWidget(widget, true);
+ mw->setFocus(Qt::MouseFocusReason); // in case focus was in e.g. object inspector
+
+ core()->formWindowManager()->setActiveFormWindow(this);
+ mainContainer()->activateWindow();
+
+ QDesignerPropertySheetExtension *propertySheet = qobject_cast<QDesignerPropertySheetExtension*>(m_core->extensionManager()->extension(widget, Q_TYPEID(QDesignerPropertySheetExtension)));
+ if (propertySheet) {
+ const QString dockWidgetAreaName = QLatin1String("dockWidgetArea");
+ PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(propertySheet->property(propertySheet->indexOf(dockWidgetAreaName)));
+ e.value = area;
+ QVariant v;
+ v.setValue(e);
+ SetPropertyCommand *cmd = new SetPropertyCommand(this);
+ cmd->init(widget, dockWidgetAreaName, v);
+ m_undoStack.push(cmd);
+ }
+
+ endCommand();
+ return true;
+}
+
+bool FormWindow::dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, QWidget *target,
+ const QPoint &global_mouse_pos)
+{
+
+ QWidget *parent = target;
+ if (parent == 0)
+ parent = mainContainer();
+ // You can only drop stuff onto the central widget of a QMainWindow
+ // ### generalize to use container extension
+ if (QMainWindow *main_win = qobject_cast<QMainWindow*>(target)) {
+ if (!main_win->centralWidget()) {
+ designerWarning(tr("A QMainWindow-based form does not contain a central widget."));
+ return false;
+ }
+ const QPoint main_win_pos = main_win->mapFromGlobal(global_mouse_pos);
+ const QRect central_wgt_geo = main_win->centralWidget()->geometry();
+ if (!central_wgt_geo.contains(main_win_pos))
+ return false;
+ }
+
+ QWidget *container = findContainer(parent, false);
+ if (container == 0)
+ return false;
+
+ beginCommand(tr("Drop widget"));
+
+ clearSelection(false);
+ highlightWidget(target, target->mapFromGlobal(global_mouse_pos), FormWindow::Restore);
+
+ QPoint offset;
+ QDesignerDnDItemInterface *current = 0;
+ QDesignerFormWindowCursorInterface *c = cursor();
+ foreach (QDesignerDnDItemInterface *item, item_list) {
+ QWidget *w = item->widget();
+ if (!current)
+ current = item;
+ if (c->current() == w) {
+ current = item;
+ break;
+ }
+ }
+ if (current) {
+ QRect geom = current->decoration()->geometry();
+ QPoint topLeft = container->mapFromGlobal(geom.topLeft());
+ offset = designerGrid().snapPoint(topLeft) - topLeft;
+ }
+
+ foreach (QDesignerDnDItemInterface *item, item_list) {
+ DomUI *dom_ui = item->domUi();
+ QRect geometry = item->decoration()->geometry();
+ Q_ASSERT(dom_ui != 0);
+
+ geometry.moveTopLeft(container->mapFromGlobal(geometry.topLeft()) + offset);
+ if (item->type() == QDesignerDnDItemInterface::CopyDrop) { // from widget box or CTRL + mouse move
+ QWidget *widget = createWidget(dom_ui, geometry, parent);
+ if (!widget) {
+ endCommand();
+ return false;
+ }
+ selectWidget(widget, true);
+ mainContainer()->setFocus(Qt::MouseFocusReason); // in case focus was in e.g. object inspector
+ } else { // same form move
+ QWidget *widget = item->widget();
+ Q_ASSERT(widget != 0);
+ QDesignerFormWindowInterface *dest = findFormWindow(widget);
+ if (dest == this) {
+ dragWidgetWithinForm(widget, geometry, container);
+ } else { // from other form
+ FormWindow *source = qobject_cast<FormWindow*>(item->source());
+ Q_ASSERT(source != 0);
+
+ source->deleteWidgetList(QWidgetList() << widget);
+ QWidget *new_widget = createWidget(dom_ui, geometry, parent);
+
+ selectWidget(new_widget, true);
+ }
+ }
+ }
+
+ core()->formWindowManager()->setActiveFormWindow(this);
+ mainContainer()->activateWindow();
+ endCommand();
+ return true;
+}
+
+QDir FormWindow::absoluteDir() const
+{
+ if (fileName().isEmpty())
+ return QDir::current();
+
+ return QFileInfo(fileName()).absoluteDir();
+}
+
+void FormWindow::layoutDefault(int *margin, int *spacing)
+{
+ *margin = m_defaultMargin;
+ *spacing = m_defaultSpacing;
+}
+
+void FormWindow::setLayoutDefault(int margin, int spacing)
+{
+ m_defaultMargin = margin;
+ m_defaultSpacing = spacing;
+}
+
+void FormWindow::layoutFunction(QString *margin, QString *spacing)
+{
+ *margin = m_marginFunction;
+ *spacing = m_spacingFunction;
+}
+
+void FormWindow::setLayoutFunction(const QString &margin, const QString &spacing)
+{
+ m_marginFunction = margin;
+ m_spacingFunction = spacing;
+}
+
+QString FormWindow::pixmapFunction() const
+{
+ return m_pixmapFunction;
+}
+
+void FormWindow::setPixmapFunction(const QString &pixmapFunction)
+{
+ m_pixmapFunction = pixmapFunction;
+}
+
+QStringList FormWindow::includeHints() const
+{
+ return m_includeHints;
+}
+
+void FormWindow::setIncludeHints(const QStringList &includeHints)
+{
+ m_includeHints = includeHints;
+}
+
+QString FormWindow::exportMacro() const
+{
+ return m_exportMacro;
+}
+
+void FormWindow::setExportMacro(const QString &exportMacro)
+{
+ m_exportMacro = exportMacro;
+}
+
+QEditorFormBuilder *FormWindow::createFormBuilder()
+{
+ return new QDesignerResource(this);
+}
+
+QWidget *FormWindow::formContainer() const
+{
+ return m_widgetStack->formContainer();
+}
+
+QUndoStack *FormWindow::commandHistory() const
+{
+ return const_cast<QDesignerUndoStack &>(m_undoStack).qundoStack();
+}
+
+} // namespace
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/components/formeditor/formwindow.h b/src/designer/src/components/formeditor/formwindow.h
new file mode 100644
index 000000000..ff862d863
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindow.h
@@ -0,0 +1,374 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOW_H
+#define FORMWINDOW_H
+
+#include "formeditor_global.h"
+#include "qdesignerundostack.h"
+#include <formwindowbase_p.h>
+
+// Qt
+#include <QtCore/QHash>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QSet>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerDnDItemInterface;
+class QDesignerTaskMenuExtension;
+class DomConnections;
+
+class QWidget;
+class QAction;
+class QLabel;
+class QTimer;
+class QAction;
+class QMenu;
+class QRubberBand;
+
+namespace qdesigner_internal {
+
+class FormEditor;
+class FormWindowCursor;
+class WidgetEditorTool;
+class FormWindowWidgetStack;
+class FormWindowManager;
+class FormWindowDnDItem;
+class SetPropertyCommand;
+
+class QT_FORMEDITOR_EXPORT FormWindow: public FormWindowBase
+{
+ Q_OBJECT
+
+public:
+ explicit FormWindow(FormEditor *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ virtual ~FormWindow();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual QDesignerFormWindowCursorInterface *cursor() const;
+
+ // Overwritten: FormWindowBase
+ virtual QWidget *formContainer() const;
+
+ virtual int toolCount() const;
+ virtual int currentTool() const;
+ virtual void setCurrentTool(int index);
+ virtual QDesignerFormWindowToolInterface *tool(int index) const;
+ virtual void registerTool(QDesignerFormWindowToolInterface *tool);
+
+ virtual QString author() const;
+ virtual void setAuthor(const QString &author);
+
+ virtual QString comment() const;
+ virtual void setComment(const QString &comment);
+
+ virtual void layoutDefault(int *margin, int *spacing);
+ virtual void setLayoutDefault(int margin, int spacing);
+
+ virtual void layoutFunction(QString *margin, QString *spacing);
+ virtual void setLayoutFunction(const QString &margin, const QString &spacing);
+
+ virtual QString pixmapFunction() const;
+ virtual void setPixmapFunction(const QString &pixmapFunction);
+
+ virtual QString exportMacro() const;
+ virtual void setExportMacro(const QString &exportMacro);
+
+ virtual QStringList includeHints() const;
+ virtual void setIncludeHints(const QStringList &includeHints);
+
+ virtual QString fileName() const;
+ virtual void setFileName(const QString &fileName);
+
+ virtual QString contents() const;
+ virtual void setContents(const QString &contents);
+ virtual void setContents(QIODevice *dev);
+
+ virtual QDir absoluteDir() const;
+
+ virtual void simplifySelection(QWidgetList *sel) const;
+
+ virtual void ensureUniqueObjectName(QObject *object);
+
+ virtual QWidget *mainContainer() const;
+ void setMainContainer(QWidget *mainContainer);
+ bool isMainContainer(const QWidget *w) const;
+
+ QWidget *currentWidget() const;
+
+ bool hasInsertedChildren(QWidget *w) const;
+
+ QList<QWidget *> selectedWidgets() const;
+ void clearSelection(bool changePropertyDisplay=true);
+ bool isWidgetSelected(QWidget *w) const;
+ void selectWidget(QWidget *w, bool select=true);
+
+ void selectWidgets();
+ void repaintSelection();
+ void updateSelection(QWidget *w);
+ void updateChildSelections(QWidget *w);
+ void raiseChildSelections(QWidget *w);
+ void raiseSelection(QWidget *w);
+
+ inline const QList<QWidget *>& widgets() const { return m_widgets; }
+ inline int widgetCount() const { return m_widgets.count(); }
+ inline QWidget *widgetAt(int index) const { return m_widgets.at(index); }
+
+ QList<QWidget *> widgets(QWidget *widget) const;
+
+ QWidget *createWidget(DomUI *ui, const QRect &rect, QWidget *target);
+
+ bool isManaged(QWidget *w) const;
+
+ void manageWidget(QWidget *w);
+ void unmanageWidget(QWidget *w);
+
+ virtual QUndoStack *commandHistory() const;
+ void beginCommand(const QString &description);
+ void endCommand();
+
+ virtual bool blockSelectionChanged(bool blocked);
+ virtual void emitSelectionChanged();
+
+ bool unify(QObject *w, QString &s, bool changeIt);
+
+ bool isDirty() const;
+ void setDirty(bool dirty);
+
+ static FormWindow *findFormWindow(QWidget *w);
+
+ virtual QWidget *containerAt(const QPoint &pos);
+ virtual QWidget *widgetAt(const QPoint &pos);
+ virtual void highlightWidget(QWidget *w, const QPoint &pos,
+ HighlightMode mode = Highlight);
+
+ void updateOrderIndicators();
+
+ bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event);
+
+ QStringList resourceFiles() const;
+ void addResourceFile(const QString &path);
+ void removeResourceFile(const QString &path);
+
+ void resizeWidget(QWidget *widget, const QRect &geometry);
+
+ bool dropDockWidget(QDesignerDnDItemInterface *item, const QPoint &global_mouse_pos);
+ bool dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, QWidget *target,
+ const QPoint &global_mouse_pos);
+
+ virtual QWidget *findContainer(QWidget *w, bool excludeLayout) const;
+ // for WidgetSelection only.
+ QWidget *designerWidget(QWidget *w) const;
+
+ // Initialize and return a popup menu for a managed widget
+ QMenu *initializePopupMenu(QWidget *managedWidget);
+
+ virtual void paste(PasteMode pasteMode);
+ virtual QEditorFormBuilder *createFormBuilder();
+
+ bool eventFilter(QObject *watched, QEvent *event);
+
+signals:
+ void contextMenuRequested(QMenu *menu, QWidget *widget);
+
+public slots:
+ void deleteWidgets();
+ void raiseWidgets();
+ void lowerWidgets();
+ void copy();
+ void cut();
+ void paste();
+ void selectAll();
+
+ void createLayout(int type, QWidget *container = 0);
+ void morphLayout(QWidget *container, int newType);
+ void breakLayout(QWidget *w);
+
+ void editContents();
+
+protected:
+ virtual QMenu *createPopupMenu(QWidget *w);
+ virtual void resizeEvent(QResizeEvent *e);
+
+ void insertWidget(QWidget *w, const QRect &rect, QWidget *target, bool already_in_form = false);
+
+private slots:
+ void selectionChangedTimerDone();
+ void checkSelection();
+ void checkSelectionNow();
+ void slotSelectWidget(QAction *);
+
+private:
+ enum MouseState {
+ NoMouseState,
+ // Double click received
+ MouseDoubleClicked,
+ // Drawing selection rubber band rectangle
+ MouseDrawRubber,
+ // Started a move operation
+ MouseMoveDrag,
+ // Click on a widget whose parent is selected. Defer selection to release
+ MouseDeferredSelection
+ };
+ MouseState m_mouseState;
+ QPointer<QWidget> m_lastClickedWidget;
+
+ void init();
+ void initializeCoreTools();
+
+ int getValue(const QRect &rect, int key, bool size) const;
+ int calcValue(int val, bool forward, bool snap, int snapOffset) const;
+ void handleClickSelection(QWidget *managedWidget, unsigned mouseFlags);
+
+ bool frameNeeded(QWidget *w) const;
+
+ enum RectType { Insert, Rubber };
+
+ void startRectDraw(const QPoint &global, QWidget *, RectType t);
+ void continueRectDraw(const QPoint &global, QWidget *, RectType t);
+ void endRectDraw();
+
+ QWidget *containerAt(const QPoint &pos, QWidget *notParentOf);
+
+ void checkPreviewGeometry(QRect &r);
+
+ bool handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e);
+ bool handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e);
+ bool handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e);
+
+ bool isCentralWidget(QWidget *w) const;
+
+ bool setCurrentWidget(QWidget *currentWidget);
+ bool trySelectWidget(QWidget *w, bool select);
+
+ void dragWidgetWithinForm(QWidget *widget, const QRect &targetGeometry, QWidget *targetContainer);
+
+ void setCursorToAll(const QCursor &c, QWidget *start);
+
+ QPoint mapToForm(const QWidget *w, const QPoint &pos) const;
+ bool canBeBuddy(QWidget *w) const;
+
+ QWidget *findTargetContainer(QWidget *widget) const;
+
+ void clearMainContainer();
+
+ static int widgetDepth(const QWidget *w);
+ static bool isChildOf(const QWidget *c, const QWidget *p);
+
+ void editWidgets();
+
+ void updateWidgets();
+
+ void handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers);
+
+ void layoutSelection(int type);
+ void layoutContainer(QWidget *w, int type);
+
+private:
+ QWidget *innerContainer(QWidget *outerContainer) const;
+ QWidget *containerForPaste() const;
+ QAction *createSelectAncestorSubMenu(QWidget *w);
+ void selectSingleWidget(QWidget *w);
+
+ FormEditor *m_core;
+ FormWindowCursor *m_cursor;
+ QWidget *m_mainContainer;
+ QWidget *m_currentWidget;
+
+ bool m_blockSelectionChanged;
+
+ QPoint m_rectAnchor;
+ QRect m_currRect;
+
+ QWidgetList m_widgets;
+ QSet<QWidget*> m_insertedWidgets;
+
+ class Selection;
+ Selection *m_selection;
+
+ QPoint m_startPos;
+
+ QDesignerUndoStack m_undoStack;
+
+ QString m_fileName;
+
+ typedef QPair<QPalette ,bool> PaletteAndFill;
+ typedef QMap<QWidget*, PaletteAndFill> WidgetPaletteMap;
+ WidgetPaletteMap m_palettesBeforeHighlight;
+
+ QRubberBand *m_rubberBand;
+
+ QTimer *m_selectionChangedTimer;
+ QTimer *m_checkSelectionTimer;
+ QTimer *m_geometryChangedTimer;
+
+ FormWindowWidgetStack *m_widgetStack;
+ WidgetEditorTool *m_widgetEditor;
+
+ QStringList m_resourceFiles;
+
+ QString m_comment;
+ QString m_author;
+ QString m_pixmapFunction;
+ int m_defaultMargin, m_defaultSpacing;
+ QString m_marginFunction, m_spacingFunction;
+ QString m_exportMacro;
+ QStringList m_includeHints;
+
+ QPoint m_contextMenuPosition;
+
+private:
+ friend class WidgetEditorTool;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOW_H
diff --git a/src/designer/src/components/formeditor/formwindow_dnditem.cpp b/src/designer/src/components/formeditor/formwindow_dnditem.cpp
new file mode 100644
index 000000000..5b8f86b0f
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindow_dnditem.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindow_dnditem.h"
+#include "formwindow.h"
+
+#include <ui4_p.h>
+#include <qdesigner_resource.h>
+#include <qtresourcemodel_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QLabel>
+#include <QtGui/QPixmap>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+static QWidget *decorationFromWidget(QWidget *w)
+{
+ QLabel *label = new QLabel(0, Qt::ToolTip);
+ QPixmap pm = QPixmap::grabWidget(w);
+ label->setPixmap(pm);
+ label->resize(pm.size());
+
+ return label;
+}
+
+static DomUI *widgetToDom(QWidget *widget, FormWindow *form)
+{
+ QDesignerResource builder(form);
+ builder.setSaveRelative(false);
+ return builder.copy(FormBuilderClipboard(widget));
+}
+
+FormWindowDnDItem::FormWindowDnDItem(QDesignerDnDItemInterface::DropType type, FormWindow *form,
+ QWidget *widget, const QPoint &global_mouse_pos)
+ : QDesignerDnDItem(type, form)
+{
+ QWidget *decoration = decorationFromWidget(widget);
+ QPoint pos = widget->mapToGlobal(QPoint(0, 0));
+ decoration->move(pos);
+
+ init(0, widget, decoration, global_mouse_pos);
+}
+
+DomUI *FormWindowDnDItem::domUi() const
+{
+ DomUI *result = QDesignerDnDItem::domUi();
+ if (result != 0)
+ return result;
+ FormWindow *form = qobject_cast<FormWindow*>(source());
+ if (widget() == 0 || form == 0)
+ return 0;
+
+ QtResourceModel *resourceModel = form->core()->resourceModel();
+ QtResourceSet *currentResourceSet = resourceModel->currentResourceSet();
+ /* Short:
+ * We need to activate the original resourceSet associated with a form
+ * to properly generate the dom resource includes.
+ * Long:
+ * widgetToDom() calls copy() on QDesignerResource. It generates the
+ * Dom structure. In order to create DomResources properly we need to
+ * have the associated ResourceSet active (QDesignerResource::saveResources()
+ * queries the resource model for a qrc path for the given resource file:
+ * qrcFile = m_core->resourceModel()->qrcPath(ri->text());
+ * This works only when the resource file comes from the active
+ * resourceSet */
+ resourceModel->setCurrentResourceSet(form->resourceSet());
+
+ result = widgetToDom(widget(), form);
+ const_cast<FormWindowDnDItem*>(this)->setDomUi(result);
+ resourceModel->setCurrentResourceSet(currentResourceSet);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/formwindow_dnditem.h b/src/designer/src/components/formeditor/formwindow_dnditem.h
new file mode 100644
index 000000000..4911c16b5
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindow_dnditem.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOW_DNDITEM_H
+#define FORMWINDOW_DNDITEM_H
+
+#include <qdesigner_dnditem_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class FormWindow;
+
+class FormWindowDnDItem : public QDesignerDnDItem
+{
+public:
+ FormWindowDnDItem(QDesignerDnDItemInterface::DropType type, FormWindow *form,
+ QWidget *widget, const QPoint &global_mouse_pos);
+ virtual DomUI *domUi() const;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOW_DNDITEM_H
diff --git a/src/designer/src/components/formeditor/formwindow_widgetstack.cpp b/src/designer/src/components/formeditor/formwindow_widgetstack.cpp
new file mode 100644
index 000000000..ac20e8ac1
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindow_widgetstack.cpp
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindow_widgetstack.h"
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+
+#include <QtGui/QWidget>
+#include <QtGui/qevent.h>
+#include <QtGui/QAction>
+#include <QtGui/QStackedLayout>
+#include <QtGui/QVBoxLayout>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+FormWindowWidgetStack::FormWindowWidgetStack(QObject *parent) :
+ QObject(parent),
+ m_formContainer(new QWidget),
+ m_formContainerLayout(new QStackedLayout),
+ m_layout(new QStackedLayout)
+{
+ m_layout->setMargin(0);
+ m_layout->setSpacing(0);
+ m_layout->setStackingMode(QStackedLayout::StackAll);
+
+ // We choose a QStackedLayout as immediate layout for
+ // the form windows as it ignores the sizePolicy of
+ // its child (for example, Fixed would cause undesired side effects).
+ m_formContainerLayout->setMargin(0);
+ m_formContainer->setObjectName(QLatin1String("formContainer"));
+ m_formContainer->setLayout(m_formContainerLayout);
+ m_formContainerLayout->setStackingMode(QStackedLayout::StackAll);
+ // System settings might have different background colors, autofill them
+ // (affects for example mainwindow status bars)
+ m_formContainer->setAutoFillBackground(true);
+}
+
+FormWindowWidgetStack::~FormWindowWidgetStack()
+{
+}
+
+int FormWindowWidgetStack::count() const
+{
+ return m_tools.count();
+}
+
+QDesignerFormWindowToolInterface *FormWindowWidgetStack::currentTool() const
+{
+ return tool(currentIndex());
+}
+
+void FormWindowWidgetStack::setCurrentTool(int index)
+{
+ const int cnt = count();
+ if (index < 0 || index >= cnt) {
+ qDebug("FormWindowWidgetStack::setCurrentTool(): invalid index: %d", index);
+ return;
+ }
+
+ const int cur = currentIndex();
+ if (index == cur)
+ return;
+
+ if (cur != -1)
+ m_tools.at(cur)->deactivated();
+
+
+ m_layout->setCurrentIndex(index);
+ // Show the widget editor and the current tool
+ for (int i = 0; i < cnt; i++)
+ m_tools.at(i)->editor()->setVisible(i == 0 || i == index);
+
+ QDesignerFormWindowToolInterface *tool = m_tools.at(index);
+ tool->activated();
+
+ emit currentToolChanged(index);
+}
+
+void FormWindowWidgetStack::setSenderAsCurrentTool()
+{
+ QDesignerFormWindowToolInterface *tool = 0;
+ QAction *action = qobject_cast<QAction*>(sender());
+ if (action == 0) {
+ qDebug("FormWindowWidgetStack::setSenderAsCurrentTool(): sender is not a QAction");
+ return;
+ }
+
+ foreach (QDesignerFormWindowToolInterface *t, m_tools) {
+ if (action == t->action()) {
+ tool = t;
+ break;
+ }
+ }
+
+ if (tool == 0) {
+ qDebug("FormWindowWidgetStack::setSenderAsCurrentTool(): unknown tool");
+ return;
+ }
+
+ setCurrentTool(tool);
+}
+
+int FormWindowWidgetStack::indexOf(QDesignerFormWindowToolInterface *tool) const
+{
+ return m_tools.indexOf(tool);
+}
+
+void FormWindowWidgetStack::setCurrentTool(QDesignerFormWindowToolInterface *tool)
+{
+ int index = indexOf(tool);
+ if (index == -1) {
+ qDebug("FormWindowWidgetStack::setCurrentTool(): unknown tool");
+ return;
+ }
+
+ setCurrentTool(index);
+}
+
+void FormWindowWidgetStack::setMainContainer(QWidget *w)
+{
+ // This code is triggered once by the formwindow and
+ // by integrations doing "revert to saved". Anything changing?
+ const int previousCount = m_formContainerLayout->count();
+ QWidget *previousMainContainer = previousCount ? m_formContainerLayout->itemAt(0)->widget() : static_cast<QWidget*>(0);
+ if (previousMainContainer == w)
+ return;
+ // Swap
+ if (previousCount)
+ delete m_formContainerLayout->takeAt(0);
+ if (w)
+ m_formContainerLayout->addWidget(w);
+}
+
+void FormWindowWidgetStack::addTool(QDesignerFormWindowToolInterface *tool)
+{
+ if (QWidget *w = tool->editor()) {
+ w->setVisible(m_layout->count() == 0); // Initially only form editor is visible
+ m_layout->addWidget(w);
+ } else {
+ // The form editor might not have a tool initially, use dummy. Assert on anything else
+ Q_ASSERT(m_tools.empty());
+ m_layout->addWidget(m_formContainer);
+ }
+
+ m_tools.append(tool);
+
+ connect(tool->action(), SIGNAL(triggered()), this, SLOT(setSenderAsCurrentTool()));
+}
+
+QDesignerFormWindowToolInterface *FormWindowWidgetStack::tool(int index) const
+{
+ if (index < 0 || index >= count())
+ return 0;
+
+ return m_tools.at(index);
+}
+
+int FormWindowWidgetStack::currentIndex() const
+{
+ return m_layout->currentIndex();
+}
+
+QWidget *FormWindowWidgetStack::defaultEditor() const
+{
+ if (m_tools.isEmpty())
+ return 0;
+
+ return m_tools.at(0)->editor();
+}
+
+QLayout *FormWindowWidgetStack::layout() const
+{
+ return m_layout;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/formwindow_widgetstack.h b/src/designer/src/components/formeditor/formwindow_widgetstack.h
new file mode 100644
index 000000000..56f9743bb
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindow_widgetstack.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOW_WIDGETSTACK_H
+#define FORMWINDOW_WIDGETSTACK_H
+
+#include "formeditor_global.h"
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowToolInterface;
+
+class QStackedLayout;
+class QWidget;
+
+namespace qdesigner_internal {
+
+class QT_FORMEDITOR_EXPORT FormWindowWidgetStack: public QObject
+{
+ Q_OBJECT
+public:
+ FormWindowWidgetStack(QObject *parent = 0);
+ virtual ~FormWindowWidgetStack();
+
+ QLayout *layout() const;
+
+ int count() const;
+ QDesignerFormWindowToolInterface *tool(int index) const;
+ QDesignerFormWindowToolInterface *currentTool() const;
+ int currentIndex() const;
+ int indexOf(QDesignerFormWindowToolInterface *tool) const;
+
+ void setMainContainer(QWidget *w = 0);
+
+ // Return the widget containing the form which can be used to apply embedded design settings to.
+ // These settings should not affect the other editing tools.
+ QWidget *formContainer() const { return m_formContainer; }
+
+signals:
+ void currentToolChanged(int index);
+
+public slots:
+ void addTool(QDesignerFormWindowToolInterface *tool);
+ void setCurrentTool(QDesignerFormWindowToolInterface *tool);
+ void setCurrentTool(int index);
+ void setSenderAsCurrentTool();
+
+protected:
+ QWidget *defaultEditor() const;
+
+private:
+ QList<QDesignerFormWindowToolInterface*> m_tools;
+ QWidget *m_formContainer;
+ QStackedLayout *m_formContainerLayout;
+ QStackedLayout *m_layout;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOW_WIDGETSTACK_H
diff --git a/src/designer/src/components/formeditor/formwindowcursor.cpp b/src/designer/src/components/formeditor/formwindowcursor.cpp
new file mode 100644
index 000000000..51d563001
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindowcursor.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindowcursor.h"
+#include "formwindow.h"
+
+// sdk
+#include <QtDesigner/propertysheet.h>
+#include <QtDesigner/QExtensionManager>
+#include <qdesigner_propertycommand_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+FormWindowCursor::FormWindowCursor(FormWindow *fw, QObject *parent)
+ : QObject(parent),
+ m_formWindow(fw)
+{
+ update();
+ connect(fw, SIGNAL(changed()), this, SLOT(update()));
+}
+
+FormWindowCursor::~FormWindowCursor()
+{
+}
+
+QDesignerFormWindowInterface *FormWindowCursor::formWindow() const
+{
+ return m_formWindow;
+}
+
+bool FormWindowCursor::movePosition(MoveOperation op, MoveMode mode)
+{
+ if (widgetCount() == 0)
+ return false;
+
+ int iterator = position();
+
+ if (mode == MoveAnchor)
+ m_formWindow->clearSelection(false);
+
+ switch (op) {
+ case Next:
+ ++iterator;
+ if (iterator >= widgetCount())
+ iterator = 0;
+
+ m_formWindow->selectWidget(m_formWindow->widgetAt(iterator), true);
+ return true;
+
+ case Prev:
+ --iterator;
+ if (iterator < 0)
+ iterator = widgetCount() - 1;
+
+ if (iterator < 0)
+ return false;
+
+ m_formWindow->selectWidget(m_formWindow->widgetAt(iterator), true);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+int FormWindowCursor::position() const
+{
+ const int index = m_formWindow->widgets().indexOf(current());
+ return index == -1 ? 0 : index;
+}
+
+void FormWindowCursor::setPosition(int pos, MoveMode mode)
+{
+ if (!widgetCount())
+ return;
+
+ if (mode == MoveAnchor)
+ m_formWindow->clearSelection(false);
+
+ if (pos >= widgetCount())
+ pos = 0;
+
+ m_formWindow->selectWidget(m_formWindow->widgetAt(pos), true);
+}
+
+QWidget *FormWindowCursor::current() const
+{
+ return m_formWindow->currentWidget();
+}
+
+bool FormWindowCursor::hasSelection() const
+{
+ return !m_formWindow->selectedWidgets().isEmpty();
+}
+
+int FormWindowCursor::selectedWidgetCount() const
+{
+ int N = m_formWindow->selectedWidgets().count();
+ return N ? N : 1;
+}
+
+QWidget *FormWindowCursor::selectedWidget(int index) const
+{
+ return hasSelection()
+ ? m_formWindow->selectedWidgets().at(index)
+ : m_formWindow->mainContainer();
+}
+
+void FormWindowCursor::update()
+{
+ // ### todo
+}
+
+int FormWindowCursor::widgetCount() const
+{
+ return m_formWindow->widgetCount();
+}
+
+QWidget *FormWindowCursor::widget(int index) const
+{
+ return m_formWindow->widgetAt(index);
+}
+
+void FormWindowCursor::setProperty(const QString &name, const QVariant &value)
+{
+
+ // build selection
+ const int N = selectedWidgetCount();
+ Q_ASSERT(N);
+
+ SetPropertyCommand::ObjectList selection;
+ for (int i=0; i<N; ++i)
+ selection.push_back(selectedWidget(i));
+
+
+ SetPropertyCommand* setPropertyCommand = new SetPropertyCommand(m_formWindow);
+ if (setPropertyCommand->init(selection, name, value, current())) {
+ m_formWindow->commandHistory()->push(setPropertyCommand);
+ } else {
+ delete setPropertyCommand;
+ qDebug() << "Unable to set property " << name << '.';
+ }
+}
+
+void FormWindowCursor::setWidgetProperty(QWidget *widget, const QString &name, const QVariant &value)
+{
+ SetPropertyCommand *cmd = new SetPropertyCommand(m_formWindow);
+ if (cmd->init(widget, name, value)) {
+ m_formWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ qDebug() << "Unable to set property " << name << '.';
+ }
+}
+
+void FormWindowCursor::resetWidgetProperty(QWidget *widget, const QString &name)
+{
+ ResetPropertyCommand *cmd = new ResetPropertyCommand(m_formWindow);
+ if (cmd->init(widget, name)) {
+ m_formWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ qDebug() << "Unable to reset property " << name << '.';
+ }
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/formwindowcursor.h b/src/designer/src/components/formeditor/formwindowcursor.h
new file mode 100644
index 000000000..797aab446
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindowcursor.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOWCURSOR_H
+#define FORMWINDOWCURSOR_H
+
+#include "formeditor_global.h"
+#include "formwindow.h"
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QT_FORMEDITOR_EXPORT FormWindowCursor: public QObject, public QDesignerFormWindowCursorInterface
+{
+ Q_OBJECT
+public:
+ explicit FormWindowCursor(FormWindow *fw, QObject *parent = 0);
+ virtual ~FormWindowCursor();
+
+ virtual QDesignerFormWindowInterface *formWindow() const;
+
+ virtual bool movePosition(MoveOperation op, MoveMode mode);
+
+ virtual int position() const;
+ virtual void setPosition(int pos, MoveMode mode);
+
+ virtual QWidget *current() const;
+
+ virtual int widgetCount() const;
+ virtual QWidget *widget(int index) const;
+
+ virtual bool hasSelection() const;
+ virtual int selectedWidgetCount() const;
+ virtual QWidget *selectedWidget(int index) const;
+
+ virtual void setProperty(const QString &name, const QVariant &value);
+ virtual void setWidgetProperty(QWidget *widget, const QString &name, const QVariant &value);
+ virtual void resetWidgetProperty(QWidget *widget, const QString &name);
+
+public slots:
+ void update();
+
+private:
+ FormWindow *m_formWindow;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOWCURSOR_H
diff --git a/src/designer/src/components/formeditor/formwindowmanager.cpp b/src/designer/src/components/formeditor/formwindowmanager.cpp
new file mode 100644
index 000000000..1d662b27c
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindowmanager.cpp
@@ -0,0 +1,1036 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// components/formeditor
+#include "formwindowmanager.h"
+#include "formwindow_dnditem.h"
+#include "formwindow.h"
+#include "formeditor.h"
+#include "widgetselection.h"
+#include "previewactiongroup.h"
+#include "formwindowsettings.h"
+
+// shared
+#include <widgetdatabase_p.h>
+#include <iconloader_p.h>
+#include <connectionedit_p.h>
+#include <qtresourcemodel_p.h>
+#include <qdesigner_dnditem_p.h>
+#include <qdesigner_command_p.h>
+#include <qdesigner_command2_p.h>
+#include <layoutinfo_p.h>
+#include <qlayout_widget_p.h>
+#include <qdesigner_objectinspector_p.h>
+#include <actioneditor_p.h>
+#include <shared_settings_p.h>
+#include <previewmanager_p.h>
+#include <abstractdialoggui_p.h>
+#include <widgetfactory_p.h>
+#include <spacer_widget_p.h>
+
+// SDK
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QDesignerIntegrationInterface>
+
+#include <QtGui/QUndoGroup>
+#include <QtGui/QAction>
+#include <QtGui/QSplitter>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QApplication>
+#include <QtGui/QSizeGrip>
+#include <QtGui/QClipboard>
+#include <QtGui/QMdiArea>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QMessageBox>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { debugFWM = 0 };
+}
+
+static inline QString whatsThisFrom(const QString &str) { /// ### implement me!
+ return str;
+}
+
+// find the first child of w in a sequence
+template <class Iterator>
+static inline Iterator findFirstChildOf(Iterator it,Iterator end, const QWidget *w)
+{
+ for (;it != end; ++it) {
+ if (w->isAncestorOf(*it))
+ return it;
+ }
+ return it;
+}
+
+namespace qdesigner_internal {
+
+FormWindowManager::FormWindowManager(QDesignerFormEditorInterface *core, QObject *parent) :
+ QDesignerFormWindowManager(parent),
+ m_core(core),
+ m_activeFormWindow(0),
+ m_previewManager(new PreviewManager(PreviewManager::SingleFormNonModalPreview, this)),
+ m_createLayoutContext(LayoutContainer),
+ m_morphLayoutContainer(0),
+ m_actionGroupPreviewInStyle(0),
+ m_actionShowFormWindowSettingsDialog(0)
+{
+ setupActions();
+ qApp->installEventFilter(this);
+}
+
+FormWindowManager::~FormWindowManager()
+{
+ qDeleteAll(m_formWindows);
+}
+
+QDesignerFormEditorInterface *FormWindowManager::core() const
+{
+ return m_core;
+}
+
+QDesignerFormWindowInterface *FormWindowManager::activeFormWindow() const
+{
+ return m_activeFormWindow;
+}
+
+int FormWindowManager::formWindowCount() const
+{
+ return m_formWindows.size();
+}
+
+QDesignerFormWindowInterface *FormWindowManager::formWindow(int index) const
+{
+ return m_formWindows.at(index);
+}
+
+bool FormWindowManager::eventFilter(QObject *o, QEvent *e)
+{
+ if (!o->isWidgetType())
+ return false;
+
+ // If we don't have an active form, we only listen for WindowActivate to speed up integrations
+ const QEvent::Type eventType = e->type();
+ if (m_activeFormWindow == 0 && eventType != QEvent::WindowActivate)
+ return false;
+
+ switch (eventType) { // Uninteresting events
+ case QEvent::Create:
+ case QEvent::Destroy:
+ case QEvent::AccessibilityDescription:
+ case QEvent::AccessibilityHelp:
+ case QEvent::AccessibilityPrepare:
+ case QEvent::ActionAdded:
+ case QEvent::ActionChanged:
+ case QEvent::ActionRemoved:
+ case QEvent::ChildAdded:
+ case QEvent::ChildPolished:
+ case QEvent::ChildRemoved:
+ case QEvent::Clipboard:
+ case QEvent::ContentsRectChange:
+ case QEvent::DeferredDelete:
+ case QEvent::FileOpen:
+ case QEvent::LanguageChange:
+ case QEvent::MetaCall:
+ case QEvent::ModifiedChange:
+ case QEvent::Paint:
+ case QEvent::PaletteChange:
+ case QEvent::ParentAboutToChange:
+ case QEvent::ParentChange:
+ case QEvent::Polish:
+ case QEvent::PolishRequest:
+ case QEvent::QueryWhatsThis:
+ case QEvent::StatusTip:
+ case QEvent::StyleChange:
+ case QEvent::Timer:
+ case QEvent::ToolBarChange:
+ case QEvent::ToolTip:
+ case QEvent::WhatsThis:
+ case QEvent::WhatsThisClicked:
+ case QEvent::WinIdChange:
+ case QEvent::DynamicPropertyChange:
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ case QEvent::HoverMove:
+ case QEvent::AcceptDropsChange:
+ return false;
+ default:
+ break;
+ }
+
+ QWidget *widget = static_cast<QWidget*>(o);
+
+ if (qobject_cast<WidgetHandle*>(widget)) { // ### remove me
+ return false;
+ }
+
+ FormWindow *fw = FormWindow::findFormWindow(widget);
+ if (fw == 0) {
+ return false;
+ }
+
+ if (QWidget *managedWidget = findManagedWidget(fw, widget)) {
+ // Prevent MDI and QWorkspace subwindows from being closed by clicking at the title bar
+ if (managedWidget != widget && eventType == QEvent::Close) {
+ e->ignore();
+ return true;
+ }
+ switch (eventType) {
+
+ case QEvent::WindowActivate: {
+ if (fw->parentWidget()->isWindow() && fw->isMainContainer(managedWidget) && activeFormWindow() != fw) {
+ setActiveFormWindow(fw);
+ }
+ } break;
+
+ case QEvent::WindowDeactivate: {
+ if (o == fw && o == activeFormWindow())
+ fw->repaintSelection();
+ } break;
+
+ case QEvent::KeyPress: {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ if (ke->key() == Qt::Key_Escape) {
+ ke->accept();
+ return true;
+ }
+ }
+ // don't break...
+ // Embedded Design: Drop on different form: Make sure the right form
+ // window/device is active before having the widget created by the factory
+ case QEvent::Drop:
+ if (activeFormWindow() != fw)
+ setActiveFormWindow(fw);
+ // don't break...
+ default: {
+ if (fw->handleEvent(widget, managedWidget, e)) {
+ return true;
+ }
+ } break;
+
+ } // end switch
+ }
+
+ return false;
+}
+
+void FormWindowManager::addFormWindow(QDesignerFormWindowInterface *w)
+{
+ FormWindow *formWindow = qobject_cast<FormWindow*>(w);
+ if (!formWindow || m_formWindows.contains(formWindow))
+ return;
+
+ connect(formWindow, SIGNAL(selectionChanged()), this, SLOT(slotUpdateActions()));
+ connect(formWindow->commandHistory(), SIGNAL(indexChanged(int)), this, SLOT(slotUpdateActions()));
+ connect(formWindow, SIGNAL(toolChanged(int)), this, SLOT(slotUpdateActions()));
+
+ if (ActionEditor *ae = qobject_cast<ActionEditor *>(m_core->actionEditor()))
+ connect(w, SIGNAL(mainContainerChanged(QWidget*)), ae, SLOT(mainContainerChanged()));
+ if (QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(m_core->objectInspector()))
+ connect(w, SIGNAL(mainContainerChanged(QWidget*)), oi, SLOT(mainContainerChanged()));
+
+ m_formWindows.append(formWindow);
+ emit formWindowAdded(formWindow);
+}
+
+void FormWindowManager::removeFormWindow(QDesignerFormWindowInterface *w)
+{
+ FormWindow *formWindow = qobject_cast<FormWindow*>(w);
+
+ int idx = m_formWindows.indexOf(formWindow);
+ if (!formWindow || idx == -1)
+ return;
+
+ formWindow->disconnect(this);
+ m_formWindows.removeAt(idx);
+ emit formWindowRemoved(formWindow);
+
+ if (formWindow == m_activeFormWindow)
+ setActiveFormWindow(0);
+
+ if (m_formWindows.size() == 0
+ && m_core->widgetBox()) {
+ // Make sure that widget box is enabled by default
+ m_core->widgetBox()->setEnabled(true);
+ }
+
+}
+
+void FormWindowManager::setActiveFormWindow(QDesignerFormWindowInterface *w)
+{
+ FormWindow *formWindow = qobject_cast<FormWindow*>(w);
+
+ if (formWindow == m_activeFormWindow)
+ return;
+
+ FormWindow *old = m_activeFormWindow;
+
+ m_activeFormWindow = formWindow;
+
+ QtResourceSet *resourceSet = 0;
+ if (formWindow)
+ resourceSet = formWindow->resourceSet();
+ m_core->resourceModel()->setCurrentResourceSet(resourceSet);
+
+ slotUpdateActions();
+
+ if (m_activeFormWindow) {
+ m_activeFormWindow->repaintSelection();
+ if (old)
+ old->repaintSelection();
+ }
+
+ emit activeFormWindowChanged(m_activeFormWindow);
+
+ if (m_activeFormWindow) {
+ m_activeFormWindow->emitSelectionChanged();
+ m_activeFormWindow->commandHistory()->setActive();
+ // Trigger setActiveSubWindow on mdi area unless we are in toplevel mode
+ QMdiSubWindow *mdiSubWindow = 0;
+ if (QWidget *formwindow = m_activeFormWindow->parentWidget()) {
+ mdiSubWindow = qobject_cast<QMdiSubWindow *>(formwindow->parentWidget());
+ }
+ if (mdiSubWindow) {
+ for (QWidget *parent = mdiSubWindow->parentWidget(); parent; parent = parent->parentWidget()) {
+ if (QMdiArea *mdiArea = qobject_cast<QMdiArea*>(parent)) {
+ mdiArea->setActiveSubWindow(mdiSubWindow);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void FormWindowManager::closeAllPreviews()
+{
+ m_previewManager->closeAllPreviews();
+}
+
+QWidget *FormWindowManager::findManagedWidget(FormWindow *fw, QWidget *w)
+{
+ while (w && w != fw) {
+ if (fw->isManaged(w))
+ break;
+ w = w->parentWidget();
+ }
+ return w;
+}
+
+void FormWindowManager::setupActions()
+{
+ m_actionCut = new QAction(createIconSet(QLatin1String("editcut.png")), tr("Cu&t"), this);
+ m_actionCut->setObjectName(QLatin1String("__qt_cut_action"));
+ m_actionCut->setShortcut(QKeySequence::Cut);
+ m_actionCut->setStatusTip(tr("Cuts the selected widgets and puts them on the clipboard"));
+ m_actionCut->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Cut")));
+ connect(m_actionCut, SIGNAL(triggered()), this, SLOT(slotActionCutActivated()));
+ m_actionCut->setEnabled(false);
+
+ m_actionCopy = new QAction(createIconSet(QLatin1String("editcopy.png")), tr("&Copy"), this);
+ m_actionCopy->setObjectName(QLatin1String("__qt_copy_action"));
+ m_actionCopy->setShortcut(QKeySequence::Copy);
+ m_actionCopy->setStatusTip(tr("Copies the selected widgets to the clipboard"));
+ m_actionCopy->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Copy")));
+ connect(m_actionCopy, SIGNAL(triggered()), this, SLOT(slotActionCopyActivated()));
+ m_actionCopy->setEnabled(false);
+
+ m_actionPaste = new QAction(createIconSet(QLatin1String("editpaste.png")), tr("&Paste"), this);
+ m_actionPaste->setObjectName(QLatin1String("__qt_paste_action"));
+ m_actionPaste->setShortcut(QKeySequence::Paste);
+ m_actionPaste->setStatusTip(tr("Pastes the clipboard's contents"));
+ m_actionPaste->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Paste")));
+ connect(m_actionPaste, SIGNAL(triggered()), this, SLOT(slotActionPasteActivated()));
+ m_actionPaste->setEnabled(false);
+
+ m_actionDelete = new QAction(tr("&Delete"), this);
+ m_actionDelete->setObjectName(QLatin1String("__qt_delete_action"));
+ m_actionDelete->setStatusTip(tr("Deletes the selected widgets"));
+ m_actionDelete->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Delete")));
+ connect(m_actionDelete, SIGNAL(triggered()), this, SLOT(slotActionDeleteActivated()));
+ m_actionDelete->setEnabled(false);
+
+ m_actionSelectAll = new QAction(tr("Select &All"), this);
+ m_actionSelectAll->setObjectName(QLatin1String("__qt_select_all_action"));
+ m_actionSelectAll->setShortcut(QKeySequence::SelectAll);
+ m_actionSelectAll->setStatusTip(tr("Selects all widgets"));
+ m_actionSelectAll->setWhatsThis(whatsThisFrom(QLatin1String("Edit|Select All")));
+ connect(m_actionSelectAll, SIGNAL(triggered()), this, SLOT(slotActionSelectAllActivated()));
+ m_actionSelectAll->setEnabled(false);
+
+ m_actionRaise = new QAction(createIconSet(QLatin1String("editraise.png")), tr("Bring to &Front"), this);
+ m_actionRaise->setObjectName(QLatin1String("__qt_raise_action"));
+ m_actionRaise->setShortcut(Qt::CTRL + Qt::Key_L);
+ m_actionRaise->setStatusTip(tr("Raises the selected widgets"));
+ m_actionRaise->setWhatsThis(tr("Raises the selected widgets"));
+ connect(m_actionRaise, SIGNAL(triggered()), this, SLOT(slotActionRaiseActivated()));
+ m_actionRaise->setEnabled(false);
+
+ m_actionLower = new QAction(createIconSet(QLatin1String("editlower.png")), tr("Send to &Back"), this);
+ m_actionLower->setObjectName(QLatin1String("__qt_lower_action"));
+ m_actionLower->setShortcut(Qt::CTRL + Qt::Key_K);
+ m_actionLower->setStatusTip(tr("Lowers the selected widgets"));
+ m_actionLower->setWhatsThis(tr("Lowers the selected widgets"));
+ connect(m_actionLower, SIGNAL(triggered()), this, SLOT(slotActionLowerActivated()));
+ m_actionLower->setEnabled(false);
+
+ m_actionAdjustSize = new QAction(createIconSet(QLatin1String("adjustsize.png")), tr("Adjust &Size"), this);
+ m_actionAdjustSize->setObjectName(QLatin1String("__qt_adjust_size_action"));
+ m_actionAdjustSize->setShortcut(Qt::CTRL + Qt::Key_J);
+ m_actionAdjustSize->setStatusTip(tr("Adjusts the size of the selected widget"));
+ m_actionAdjustSize->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Adjust Size")));
+ connect(m_actionAdjustSize, SIGNAL(triggered()), this, SLOT(slotActionAdjustSizeActivated()));
+ m_actionAdjustSize->setEnabled(false);
+
+
+ m_actionHorizontalLayout = new QAction(createIconSet(QLatin1String("edithlayout.png")), tr("Lay Out &Horizontally"), this);
+ m_actionHorizontalLayout->setObjectName(QLatin1String("__qt_horizontal_layout_action"));
+ m_actionHorizontalLayout->setShortcut(Qt::CTRL + Qt::Key_1);
+ m_actionHorizontalLayout->setStatusTip(tr("Lays out the selected widgets horizontally"));
+ m_actionHorizontalLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out Horizontally")));
+ m_actionHorizontalLayout->setData(LayoutInfo::HBox);
+ m_actionHorizontalLayout->setEnabled(false);
+ connect(m_actionHorizontalLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ m_actionVerticalLayout = new QAction(createIconSet(QLatin1String("editvlayout.png")), tr("Lay Out &Vertically"), this);
+ m_actionVerticalLayout->setObjectName(QLatin1String("__qt_vertical_layout_action"));
+ m_actionVerticalLayout->setShortcut(Qt::CTRL + Qt::Key_2);
+ m_actionVerticalLayout->setStatusTip(tr("Lays out the selected widgets vertically"));
+ m_actionVerticalLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out Vertically")));
+ m_actionVerticalLayout->setData(LayoutInfo::VBox);
+ m_actionVerticalLayout->setEnabled(false);
+ connect(m_actionVerticalLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ QIcon formIcon = QIcon::fromTheme("designer-form-layout", createIconSet(QLatin1String("editform.png")));
+ QAction *actionFormLayout = new QAction(formIcon, tr("Lay Out in a &Form Layout"), this);
+ actionFormLayout->setObjectName(QLatin1String("__qt_form_layout_action"));
+ actionFormLayout->setShortcut(Qt::CTRL + Qt::Key_6);
+ actionFormLayout->setStatusTip(tr("Lays out the selected widgets in a form layout"));
+ actionFormLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out in a Form")));
+ actionFormLayout->setData(LayoutInfo::Form);
+ actionFormLayout->setEnabled(false);
+ setActionFormLayout(actionFormLayout);
+ connect(actionFormLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ m_actionGridLayout = new QAction(createIconSet(QLatin1String("editgrid.png")), tr("Lay Out in a &Grid"), this);
+ m_actionGridLayout->setObjectName(QLatin1String("__qt_grid_layout_action"));
+ m_actionGridLayout->setShortcut(Qt::CTRL + Qt::Key_5);
+ m_actionGridLayout->setStatusTip(tr("Lays out the selected widgets in a grid"));
+ m_actionGridLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out in a Grid")));
+ m_actionGridLayout->setData(LayoutInfo::Grid);
+ m_actionGridLayout->setEnabled(false);
+ connect(m_actionGridLayout, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ m_actionSplitHorizontal = new QAction(createIconSet(QLatin1String("edithlayoutsplit.png")),
+ tr("Lay Out Horizontally in S&plitter"), this);
+ m_actionSplitHorizontal->setObjectName(QLatin1String("__qt_split_horizontal_action"));
+ m_actionSplitHorizontal->setShortcut(Qt::CTRL + Qt::Key_3);
+ m_actionSplitHorizontal->setStatusTip(tr("Lays out the selected widgets horizontally in a splitter"));
+ m_actionSplitHorizontal->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out Horizontally in Splitter")));
+ m_actionSplitHorizontal->setData(LayoutInfo::HSplitter);
+ m_actionSplitHorizontal->setEnabled(false);
+ connect(m_actionSplitHorizontal, SIGNAL(triggered()), this, SLOT(createLayout()));
+
+ m_actionSplitVertical = new QAction(createIconSet(QLatin1String("editvlayoutsplit.png")),
+ tr("Lay Out Vertically in Sp&litter"), this);
+ m_actionSplitVertical->setObjectName(QLatin1String("__qt_split_vertical_action"));
+ m_actionSplitVertical->setShortcut(Qt::CTRL + Qt::Key_4);
+ m_actionSplitVertical->setStatusTip(tr("Lays out the selected widgets vertically in a splitter"));
+ m_actionSplitVertical->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Lay Out Vertically in Splitter")));
+ connect(m_actionSplitVertical, SIGNAL(triggered()), this, SLOT(createLayout()));
+ m_actionSplitVertical->setData(LayoutInfo::VSplitter);
+
+ m_actionSplitVertical->setEnabled(false);
+
+ m_actionBreakLayout = new QAction(createIconSet(QLatin1String("editbreaklayout.png")), tr("&Break Layout"), this);
+ m_actionBreakLayout->setObjectName(QLatin1String("__qt_break_layout_action"));
+ m_actionBreakLayout->setShortcut(Qt::CTRL + Qt::Key_0);
+ m_actionBreakLayout->setStatusTip(tr("Breaks the selected layout"));
+ m_actionBreakLayout->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Break Layout")));
+ connect(m_actionBreakLayout, SIGNAL(triggered()), this, SLOT(slotActionBreakLayoutActivated()));
+ m_actionBreakLayout->setEnabled(false);
+
+ QAction *simplifyLayoutAction = new QAction(tr("Si&mplify Grid Layout"), this);
+ simplifyLayoutAction->setObjectName(QLatin1String("__qt_simplify_layout_action"));
+ simplifyLayoutAction->setStatusTip(tr("Removes empty columns and rows"));
+ simplifyLayoutAction->setWhatsThis(whatsThisFrom(QLatin1String("Layout|Simplify Layout")));
+ connect(simplifyLayoutAction, SIGNAL(triggered()), this, SLOT(slotActionSimplifyLayoutActivated()));
+ simplifyLayoutAction->setEnabled(false);
+ setActionSimplifyLayout(simplifyLayoutAction);
+
+ m_actionDefaultPreview = new QAction(tr("&Preview..."), this);
+ m_actionDefaultPreview->setObjectName(QLatin1String("__qt_default_preview_action"));
+ m_actionDefaultPreview->setStatusTip(tr("Preview current form"));
+ m_actionDefaultPreview->setWhatsThis(whatsThisFrom(QLatin1String("Form|Preview")));
+ connect(m_actionDefaultPreview, SIGNAL(triggered()),
+ this, SLOT(slotActionDefaultPreviewActivated()));
+
+ m_undoGroup = new QUndoGroup(this);
+
+ m_actionUndo = m_undoGroup->createUndoAction(this);
+ m_actionUndo->setEnabled(false);
+
+ m_actionUndo->setIcon(QIcon::fromTheme("edit-undo", createIconSet(QLatin1String("undo.png"))));
+ m_actionRedo = m_undoGroup->createRedoAction(this);
+ m_actionRedo->setEnabled(false);
+ m_actionRedo->setIcon(QIcon::fromTheme("edit-redo", createIconSet(QLatin1String("redo.png"))));
+
+ m_actionShowFormWindowSettingsDialog = new QAction(tr("Form &Settings..."), this);
+ m_actionShowFormWindowSettingsDialog->setObjectName(QLatin1String("__qt_form_settings_action"));
+ connect(m_actionShowFormWindowSettingsDialog, SIGNAL(triggered()), this, SLOT(slotActionShowFormWindowSettingsDialog()));
+ m_actionShowFormWindowSettingsDialog->setEnabled(false);
+
+#ifdef Q_WS_X11
+ m_actionCopy->setIcon(QIcon::fromTheme("edit-copy", m_actionCopy->icon()));
+ m_actionCut->setIcon(QIcon::fromTheme("edit-cut", m_actionCut->icon()));
+ m_actionPaste->setIcon(QIcon::fromTheme("edit-paste", m_actionPaste->icon()));
+ m_actionDelete->setIcon(QIcon::fromTheme("edit-delete", m_actionDelete->icon()));
+
+ // These do not currently exist, but will allow theme authors to fill in the gaps
+ m_actionBreakLayout->setIcon(QIcon::fromTheme("designer-break-layout", m_actionBreakLayout->icon()));
+ m_actionGridLayout->setIcon(QIcon::fromTheme("designer-grid-layout", m_actionGridLayout->icon()));
+ m_actionHorizontalLayout->setIcon(QIcon::fromTheme("designer-horizontal-layout", m_actionHorizontalLayout->icon()));
+ m_actionVerticalLayout->setIcon(QIcon::fromTheme("designer-vertical-layout", m_actionVerticalLayout->icon()));
+ m_actionSplitHorizontal->setIcon(QIcon::fromTheme("designer-split-horizontal", m_actionSplitHorizontal->icon()));
+ m_actionSplitVertical->setIcon(QIcon::fromTheme("designer-split-vertical", m_actionSplitVertical->icon()));
+ m_actionAdjustSize->setIcon(QIcon::fromTheme("designer-adjust-size", m_actionAdjustSize->icon()));
+#endif
+}
+
+void FormWindowManager::slotActionCutActivated()
+{
+ m_activeFormWindow->cut();
+}
+
+void FormWindowManager::slotActionCopyActivated()
+{
+ m_activeFormWindow->copy();
+ slotUpdateActions();
+}
+
+void FormWindowManager::slotActionPasteActivated()
+{
+ m_activeFormWindow->paste();
+}
+
+void FormWindowManager::slotActionDeleteActivated()
+{
+ m_activeFormWindow->deleteWidgets();
+}
+
+void FormWindowManager::slotActionLowerActivated()
+{
+ m_activeFormWindow->lowerWidgets();
+}
+
+void FormWindowManager::slotActionRaiseActivated()
+{
+ m_activeFormWindow->raiseWidgets();
+}
+
+static inline QWidget *findLayoutContainer(const FormWindow *fw)
+{
+ QList<QWidget*> l(fw->selectedWidgets());
+ fw->simplifySelection(&l);
+ return l.empty() ? fw->mainContainer() : l.front();
+}
+
+void FormWindowManager::createLayout()
+{
+ QAction *a = qobject_cast<QAction *>(sender());
+ if (!a)
+ return;
+ const int type = a->data().toInt();
+ switch (m_createLayoutContext) {
+ case LayoutContainer:
+ // Cannot create a splitter on a container
+ if (type != LayoutInfo::HSplitter && type != LayoutInfo::VSplitter)
+ m_activeFormWindow->createLayout(type, findLayoutContainer(m_activeFormWindow));
+ break;
+ case LayoutSelection:
+ m_activeFormWindow->createLayout(type);
+ break;
+ case MorphLayout:
+ m_activeFormWindow->morphLayout(m_morphLayoutContainer, type);
+ break;
+ }
+}
+
+void FormWindowManager::slotActionBreakLayoutActivated()
+{
+ const QList<QWidget *> layouts = layoutsToBeBroken();
+ if (layouts.isEmpty())
+ return;
+
+ if (debugFWM) {
+ qDebug() << "slotActionBreakLayoutActivated: " << layouts.size();
+ foreach (QWidget *w, layouts) {
+ qDebug() << w;
+ }
+ }
+
+ m_activeFormWindow->beginCommand(tr("Break Layout"));
+ foreach (QWidget *layout, layouts) {
+ m_activeFormWindow->breakLayout(layout);
+ }
+ m_activeFormWindow->endCommand();
+}
+
+void FormWindowManager::slotActionSimplifyLayoutActivated()
+{
+ Q_ASSERT(m_activeFormWindow != 0);
+ QWidgetList selectedWidgets = m_activeFormWindow->selectedWidgets();
+ m_activeFormWindow->simplifySelection(&selectedWidgets);
+ if (selectedWidgets.size() != 1)
+ return;
+ SimplifyLayoutCommand *cmd = new SimplifyLayoutCommand(m_activeFormWindow);
+ if (cmd->init(selectedWidgets.front())) {
+ m_activeFormWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ }
+}
+
+void FormWindowManager::slotActionAdjustSizeActivated()
+{
+ Q_ASSERT(m_activeFormWindow != 0);
+
+ m_activeFormWindow->beginCommand(tr("Adjust Size"));
+
+ QList<QWidget*> selectedWidgets = m_activeFormWindow->selectedWidgets();
+ m_activeFormWindow->simplifySelection(&selectedWidgets);
+
+ if (selectedWidgets.isEmpty()) {
+ Q_ASSERT(m_activeFormWindow->mainContainer() != 0);
+ selectedWidgets.append(m_activeFormWindow->mainContainer());
+ }
+
+ // Always count the main container as unlaid-out
+ foreach (QWidget *widget, selectedWidgets) {
+ bool unlaidout = LayoutInfo::layoutType(core(), widget->parentWidget()) == LayoutInfo::NoLayout;
+ bool isMainContainer = m_activeFormWindow->isMainContainer(widget);
+
+ if (unlaidout || isMainContainer) {
+ AdjustWidgetSizeCommand *cmd = new AdjustWidgetSizeCommand(m_activeFormWindow);
+ cmd->init(widget);
+ m_activeFormWindow->commandHistory()->push(cmd);
+ }
+ }
+
+ m_activeFormWindow->endCommand();
+}
+
+void FormWindowManager::slotActionSelectAllActivated()
+{
+ m_activeFormWindow->selectAll();
+}
+
+void FormWindowManager::slotActionDefaultPreviewActivated()
+{
+ slotActionGroupPreviewInStyle(QString(), -1);
+}
+
+void FormWindowManager::slotActionGroupPreviewInStyle(const QString &style, int deviceProfileIndex)
+{
+ QDesignerFormWindowInterface *fw = activeFormWindow();
+ if (!fw)
+ return;
+
+ QString errorMessage;
+ if (!m_previewManager->showPreview(fw, style, deviceProfileIndex, &errorMessage)) {
+ const QString title = tr("Could not create form preview", "Title of warning message box");
+ core()->dialogGui()->message(fw, QDesignerDialogGuiInterface::FormEditorMessage, QMessageBox::Warning,
+ title, errorMessage);
+ }
+}
+
+// The user might click on a layout child or the actual layout container.
+QWidgetList FormWindowManager::layoutsToBeBroken(QWidget *w) const
+{
+ if (!w)
+ return QList<QWidget *>();
+
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: " << w;
+
+ QWidget *parent = w->parentWidget();
+ if (m_activeFormWindow->isMainContainer(w))
+ parent = 0;
+
+ QWidget *widget = core()->widgetFactory()->containerOfWidget(w);
+
+ // maybe we want to remove following block
+ const QDesignerWidgetDataBaseInterface *db = m_core->widgetDataBase();
+ const QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(widget));
+ if (!item) {
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Don't have an item, recursing for parent";
+ return layoutsToBeBroken(parent);
+ }
+
+ const bool layoutContainer = (item->isContainer() || m_activeFormWindow->isMainContainer(widget));
+
+ if (!layoutContainer) {
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Not a container, recursing for parent";
+ return layoutsToBeBroken(parent);
+ }
+
+ QLayout *widgetLayout = widget->layout();
+ QLayout *managedLayout = LayoutInfo::managedLayout(m_core, widgetLayout);
+ if (!managedLayout) {
+ if (qobject_cast<const QSplitter *>(widget)) {
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Splitter special";
+ QList<QWidget *> list = layoutsToBeBroken(parent);
+ list.append(widget);
+ return list;
+ }
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Is a container but doesn't have a managed layout (has an internal layout), returning 0";
+ return QList<QWidget *>();
+ }
+
+ if (managedLayout) {
+ QList<QWidget *> list;
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Is a container and has a layout";
+ if (qobject_cast<const QLayoutWidget *>(widget)) {
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: red layout special case";
+ list = layoutsToBeBroken(parent);
+ }
+ list.append(widget);
+ return list;
+ }
+ if (debugFWM)
+ qDebug() << "layoutsToBeBroken: Is a container but doesn't have a layout at all, returning 0";
+ return QList<QWidget *>();
+
+}
+
+QMap<QWidget *, bool> FormWindowManager::getUnsortedLayoutsToBeBroken(bool firstOnly) const
+{
+ // Return a set of layouts to be broken.
+ QMap<QWidget *, bool> layouts;
+
+ QList<QWidget *> selection = m_activeFormWindow->selectedWidgets();
+ if (selection.isEmpty() && m_activeFormWindow->mainContainer())
+ selection.append(m_activeFormWindow->mainContainer());
+
+ const QList<QWidget *>::const_iterator scend = selection.constEnd();
+ for (QList<QWidget *>::const_iterator sit = selection.constBegin(); sit != scend; ++sit) {
+ // find all layouts
+ const QList<QWidget *> list = layoutsToBeBroken(*sit);
+ if (!list.empty()) {
+ const QList<QWidget *>::const_iterator lbcend = list.constEnd();
+ for (QList<QWidget *>::const_iterator lbit = list.constBegin(); lbit != lbcend; ++lbit) {
+ layouts.insert(*lbit, true);
+ }
+ if (firstOnly)
+ return layouts;
+ }
+ }
+ return layouts;
+}
+
+bool FormWindowManager::hasLayoutsToBeBroken() const
+{
+ // Quick check for layouts to be broken
+ return !getUnsortedLayoutsToBeBroken(true).isEmpty();
+}
+
+QWidgetList FormWindowManager::layoutsToBeBroken() const
+{
+ // Get all layouts. This is a list of all 'red' layouts (QLayoutWidgets)
+ // up to the first 'real' widget with a layout in hierarchy order.
+ QMap<QWidget *, bool> unsortedLayouts = getUnsortedLayoutsToBeBroken(false);
+ // Sort in order of hierarchy
+ QList<QWidget *> orderedLayoutList;
+ const QMap<QWidget *, bool>::const_iterator lscend = unsortedLayouts.constEnd();
+ for (QMap<QWidget *, bool>::const_iterator itLay = unsortedLayouts.constBegin(); itLay != lscend; ++itLay) {
+ QWidget *wToBeInserted = itLay.key();
+ if (!orderedLayoutList.contains(wToBeInserted)) {
+ // try to find first child, use as insertion position, else append
+ const QList<QWidget *>::iterator firstChildPos = findFirstChildOf(orderedLayoutList.begin(), orderedLayoutList.end(), wToBeInserted);
+ if (firstChildPos == orderedLayoutList.end()) {
+ orderedLayoutList.push_back(wToBeInserted);
+ } else {
+ orderedLayoutList.insert(firstChildPos, wToBeInserted);
+ }
+ }
+ }
+ return orderedLayoutList;
+}
+
+static inline bool hasManagedLayoutItems(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ if (const QLayout *ml = LayoutInfo::managedLayout(core, w)) {
+ // Try to find managed items, ignore dummy grid spacers
+ const int count = ml->count();
+ for (int i = 0; i < count; i++)
+ if (!LayoutInfo::isEmptyItem(ml->itemAt(i)))
+ return true;
+ }
+ return false;
+}
+
+void FormWindowManager::slotUpdateActions()
+{
+ m_createLayoutContext = LayoutSelection;
+ m_morphLayoutContainer = 0;
+ bool canMorphIntoVBoxLayout = false;
+ bool canMorphIntoHBoxLayout = false;
+ bool canMorphIntoGridLayout = false;
+ bool canMorphIntoFormLayout = false;
+ int selectedWidgetCount = 0;
+ int laidoutWidgetCount = 0;
+ int unlaidoutWidgetCount = 0;
+ bool pasteAvailable = false;
+ bool layoutAvailable = false;
+ bool breakAvailable = false;
+ bool simplifyAvailable = false;
+ bool layoutContainer = false;
+ bool canChangeZOrder = true;
+
+ do {
+ if (m_activeFormWindow == 0 || m_activeFormWindow->currentTool() != 0)
+ break;
+
+ breakAvailable = hasLayoutsToBeBroken();
+
+ QWidgetList simplifiedSelection = m_activeFormWindow->selectedWidgets();
+
+ selectedWidgetCount = simplifiedSelection.count();
+ pasteAvailable = qApp->clipboard()->mimeData() && qApp->clipboard()->mimeData()->hasText();
+
+ m_activeFormWindow->simplifySelection(&simplifiedSelection);
+ QWidget *mainContainer = m_activeFormWindow->mainContainer();
+ if (simplifiedSelection.isEmpty() && mainContainer)
+ simplifiedSelection.append(mainContainer);
+
+ // Always count the main container as unlaid-out
+ const QWidgetList::const_iterator cend = simplifiedSelection.constEnd();
+ for (QWidgetList::const_iterator it = simplifiedSelection.constBegin(); it != cend; ++it) {
+ if (*it != mainContainer && LayoutInfo::isWidgetLaidout(m_core, *it)) {
+ ++laidoutWidgetCount;
+ } else {
+ ++unlaidoutWidgetCount;
+ }
+ if (qobject_cast<const QLayoutWidget *>(*it) || qobject_cast<const Spacer *>(*it))
+ canChangeZOrder = false;
+ }
+
+ // Figure out layouts: Looking at a group of dangling widgets
+ if (simplifiedSelection.count() != 1) {
+ layoutAvailable = unlaidoutWidgetCount > 1;
+ //breakAvailable = false;
+ break;
+ }
+ // Manipulate layout of a single widget
+ m_createLayoutContext = LayoutSelection;
+ QWidget *widget = core()->widgetFactory()->containerOfWidget(simplifiedSelection.first());
+ if (widget == 0) // We are looking at a page-based container with 0 pages
+ break;
+
+ const QDesignerWidgetDataBaseInterface *db = m_core->widgetDataBase();
+ const QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(widget));
+ if (!item)
+ break;
+
+ QLayout *widgetLayout = LayoutInfo::internalLayout(widget);
+ QLayout *managedLayout = LayoutInfo::managedLayout(m_core, widgetLayout);
+ // We don't touch a layout createds by a custom widget
+ if (widgetLayout && !managedLayout)
+ break;
+
+ layoutContainer = (item->isContainer() || m_activeFormWindow->isMainContainer(widget));
+
+ layoutAvailable = layoutContainer && m_activeFormWindow->hasInsertedChildren(widget) && managedLayout == 0;
+ simplifyAvailable = SimplifyLayoutCommand::canSimplify(m_core, widget);
+ if (layoutAvailable) {
+ m_createLayoutContext = LayoutContainer;
+ } else {
+ /* Cannot create a layout, have some layouts to be broken and
+ * exactly one, non-empty layout with selected: check the morph layout options
+ * (Note that there might be > 1 layouts to broken if the selection
+ * is a red layout, however, we want the inner-most layout here). */
+ if (breakAvailable && simplifiedSelection.size() == 1
+ && hasManagedLayoutItems(m_core, widget)) {
+ int type;
+ m_morphLayoutContainer = widget; // Was: page of first selected
+ m_createLayoutContext = MorphLayout;
+ if (MorphLayoutCommand::canMorph(m_activeFormWindow, m_morphLayoutContainer, &type)) {
+ canMorphIntoVBoxLayout = type != LayoutInfo::VBox;
+ canMorphIntoHBoxLayout = type != LayoutInfo::HBox;
+ canMorphIntoGridLayout = type != LayoutInfo::Grid;
+ canMorphIntoFormLayout = type != LayoutInfo::Form;
+ }
+ }
+ }
+ } while(false);
+
+ m_actionCut->setEnabled(selectedWidgetCount > 0);
+ m_actionCopy->setEnabled(selectedWidgetCount > 0);
+ m_actionDelete->setEnabled(selectedWidgetCount > 0);
+ m_actionLower->setEnabled(canChangeZOrder && selectedWidgetCount > 0);
+ m_actionRaise->setEnabled(canChangeZOrder && selectedWidgetCount > 0);
+
+ m_actionPaste->setEnabled(pasteAvailable);
+
+ m_actionSelectAll->setEnabled(m_activeFormWindow != 0);
+
+ m_actionAdjustSize->setEnabled(unlaidoutWidgetCount > 0);
+
+ m_actionHorizontalLayout->setEnabled(layoutAvailable || canMorphIntoHBoxLayout);
+ m_actionVerticalLayout->setEnabled(layoutAvailable || canMorphIntoVBoxLayout);
+ m_actionSplitHorizontal->setEnabled(layoutAvailable && !layoutContainer);
+ m_actionSplitVertical->setEnabled(layoutAvailable && !layoutContainer);
+ actionFormLayout()->setEnabled(layoutAvailable || canMorphIntoFormLayout);
+ m_actionGridLayout->setEnabled(layoutAvailable || canMorphIntoGridLayout);
+
+ m_actionBreakLayout->setEnabled(breakAvailable);
+ actionSimplifyLayout()->setEnabled(simplifyAvailable);
+ m_actionShowFormWindowSettingsDialog->setEnabled(m_activeFormWindow != 0);
+}
+
+QDesignerFormWindowInterface *FormWindowManager::createFormWindow(QWidget *parentWidget, Qt::WindowFlags flags)
+{
+ FormWindow *formWindow = new FormWindow(qobject_cast<FormEditor*>(core()), parentWidget, flags);
+ formWindow->setProperty(WidgetFactory::disableStyleCustomPaintingPropertyC, QVariant(true));
+ addFormWindow(formWindow);
+ return formWindow;
+}
+
+QPixmap FormWindowManager::createPreviewPixmap(QString *errorMessage)
+{
+ QPixmap pixmap;
+ QDesignerFormWindowInterface *fw = activeFormWindow();
+ if (!fw)
+ return pixmap;
+
+ pixmap = m_previewManager->createPreviewPixmap(fw, QString(), errorMessage);
+ return pixmap;
+}
+
+QAction *FormWindowManager::actionUndo() const
+{
+ return m_actionUndo;
+}
+
+QAction *FormWindowManager::actionRedo() const
+{
+ return m_actionRedo;
+}
+
+QActionGroup *FormWindowManager::actionGroupPreviewInStyle() const
+{
+ if (m_actionGroupPreviewInStyle == 0) {
+ // Wish we could make the 'this' pointer mutable ;-)
+ QObject *parent = const_cast<FormWindowManager*>(this);
+ m_actionGroupPreviewInStyle = new PreviewActionGroup(m_core, parent);
+ connect(m_actionGroupPreviewInStyle, SIGNAL(preview(QString,int)),
+ this, SLOT(slotActionGroupPreviewInStyle(QString,int)));
+ }
+ return m_actionGroupPreviewInStyle;
+}
+
+void FormWindowManager::deviceProfilesChanged()
+{
+ if (m_actionGroupPreviewInStyle)
+ m_actionGroupPreviewInStyle->updateDeviceProfiles();
+}
+
+// DnD stuff
+
+void FormWindowManager::dragItems(const QList<QDesignerDnDItemInterface*> &item_list)
+{
+ QDesignerMimeData::execDrag(item_list, m_core->topLevel());
+}
+
+QUndoGroup *FormWindowManager::undoGroup() const
+{
+ return m_undoGroup;
+}
+
+QAction *FormWindowManager::actionShowFormWindowSettingsDialog() const
+{
+ return m_actionShowFormWindowSettingsDialog;
+}
+
+void FormWindowManager::slotActionShowFormWindowSettingsDialog()
+{
+ QDesignerFormWindowInterface *fw = activeFormWindow();
+ if (!fw)
+ return;
+
+ QDialog *settingsDialog = 0;
+ const bool wasDirty = fw->isDirty();
+
+ // Ask the language extension for a dialog. If not, create our own
+ if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension*>(m_core->extensionManager(), m_core))
+ settingsDialog = lang->createFormWindowSettingsDialog(fw, /*parent=*/ 0);
+
+ if (!settingsDialog)
+ settingsDialog = new FormWindowSettings(fw);
+
+ QString title = QFileInfo(fw->fileName()).fileName();
+ if (title.isEmpty()) // Grab the title from the outer window if no filename
+ if (const QWidget *window = m_core->integration()->containerWindow(fw))
+ title = window->windowTitle();
+
+ settingsDialog->setWindowTitle(tr("Form Settings - %1").arg(title));
+ if (settingsDialog->exec())
+ if (fw->isDirty() != wasDirty)
+ emit formWindowSettingsChanged(fw);
+
+ delete settingsDialog;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/formwindowmanager.h b/src/designer/src/components/formeditor/formwindowmanager.h
new file mode 100644
index 000000000..dfd421522
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindowmanager.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOWMANAGER_H
+#define FORMWINDOWMANAGER_H
+
+#include "formeditor_global.h"
+
+#include <QtDesigner/private/qdesigner_formwindowmanager_p.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QActionGroup;
+class QUndoGroup;
+class QDesignerFormEditorInterface;
+class QDesignerWidgetBoxInterface;
+
+namespace qdesigner_internal {
+
+class FormWindow;
+class PreviewManager;
+class PreviewActionGroup;
+
+class QT_FORMEDITOR_EXPORT FormWindowManager
+ : public QDesignerFormWindowManager
+{
+ Q_OBJECT
+public:
+ explicit FormWindowManager(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ virtual ~FormWindowManager();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ inline QAction *actionCut() const { return m_actionCut; }
+ inline QAction *actionCopy() const { return m_actionCopy; }
+ inline QAction *actionPaste() const { return m_actionPaste; }
+ inline QAction *actionDelete() const { return m_actionDelete; }
+ inline QAction *actionSelectAll() const { return m_actionSelectAll; }
+ inline QAction *actionLower() const { return m_actionLower; }
+ inline QAction *actionRaise() const { return m_actionRaise; }
+ QAction *actionUndo() const;
+ QAction *actionRedo() const;
+
+ inline QAction *actionHorizontalLayout() const { return m_actionHorizontalLayout; }
+ inline QAction *actionVerticalLayout() const { return m_actionVerticalLayout; }
+ inline QAction *actionSplitHorizontal() const { return m_actionSplitHorizontal; }
+ inline QAction *actionSplitVertical() const { return m_actionSplitVertical; }
+ inline QAction *actionGridLayout() const { return m_actionGridLayout; }
+ inline QAction *actionBreakLayout() const { return m_actionBreakLayout; }
+ inline QAction *actionAdjustSize() const { return m_actionAdjustSize; }
+
+ inline QAction *actionDefaultPreview() const { return m_actionDefaultPreview; }
+ QActionGroup *actionGroupPreviewInStyle() const;
+ virtual QAction *actionShowFormWindowSettingsDialog() const;
+
+ QDesignerFormWindowInterface *activeFormWindow() const;
+
+ int formWindowCount() const;
+ QDesignerFormWindowInterface *formWindow(int index) const;
+
+ QDesignerFormWindowInterface *createFormWindow(QWidget *parentWidget = 0, Qt::WindowFlags flags = 0);
+
+ QPixmap createPreviewPixmap(QString *errorMessage);
+
+ bool eventFilter(QObject *o, QEvent *e);
+
+ void dragItems(const QList<QDesignerDnDItemInterface*> &item_list);
+
+ QUndoGroup *undoGroup() const;
+
+ virtual PreviewManager *previewManager() const { return m_previewManager; }
+
+public slots:
+ void addFormWindow(QDesignerFormWindowInterface *formWindow);
+ void removeFormWindow(QDesignerFormWindowInterface *formWindow);
+ void setActiveFormWindow(QDesignerFormWindowInterface *formWindow);
+ void closeAllPreviews();
+ void deviceProfilesChanged();
+
+private slots:
+ void slotActionCutActivated();
+ void slotActionCopyActivated();
+ void slotActionPasteActivated();
+ void slotActionDeleteActivated();
+ void slotActionSelectAllActivated();
+ void slotActionLowerActivated();
+ void slotActionRaiseActivated();
+ void createLayout();
+ void slotActionBreakLayoutActivated();
+ void slotActionAdjustSizeActivated();
+ void slotActionSimplifyLayoutActivated();
+ void slotActionDefaultPreviewActivated();
+ void slotActionGroupPreviewInStyle(const QString &style, int deviceProfileIndex);
+ void slotActionShowFormWindowSettingsDialog();
+
+ void slotUpdateActions();
+
+private:
+ void setupActions();
+ FormWindow *findFormWindow(QWidget *w);
+ QWidget *findManagedWidget(FormWindow *fw, QWidget *w);
+
+ void setCurrentUndoStack(QUndoStack *stack);
+
+private:
+ enum CreateLayoutContext { LayoutContainer, LayoutSelection, MorphLayout };
+
+ QDesignerFormEditorInterface *m_core;
+ FormWindow *m_activeFormWindow;
+ QList<FormWindow*> m_formWindows;
+
+ PreviewManager *m_previewManager;
+
+ /* Context of the layout actions and base for morphing layouts. Determined
+ * in slotUpdateActions() and used later on in the action slots. */
+ CreateLayoutContext m_createLayoutContext;
+ QWidget *m_morphLayoutContainer;
+
+ // edit actions
+ QAction *m_actionCut;
+ QAction *m_actionCopy;
+ QAction *m_actionPaste;
+ QAction *m_actionSelectAll;
+ QAction *m_actionDelete;
+ QAction *m_actionLower;
+ QAction *m_actionRaise;
+ // layout actions
+ QAction *m_actionHorizontalLayout;
+ QAction *m_actionVerticalLayout;
+ QAction *m_actionSplitHorizontal;
+ QAction *m_actionSplitVertical;
+ QAction *m_actionGridLayout;
+ QAction *m_actionBreakLayout;
+ QAction *m_actionAdjustSize;
+ // preview actions
+ QAction *m_actionDefaultPreview;
+ mutable PreviewActionGroup *m_actionGroupPreviewInStyle;
+ QAction *m_actionShowFormWindowSettingsDialog;
+
+ QAction *m_actionUndo;
+ QAction *m_actionRedo;
+
+ QMap<QWidget *,bool> getUnsortedLayoutsToBeBroken(bool firstOnly) const;
+ bool hasLayoutsToBeBroken() const;
+ QWidgetList layoutsToBeBroken(QWidget *w) const;
+ QWidgetList layoutsToBeBroken() const;
+
+ QUndoGroup *m_undoGroup;
+
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOWMANAGER_H
diff --git a/src/designer/src/components/formeditor/formwindowsettings.cpp b/src/designer/src/components/formeditor/formwindowsettings.cpp
new file mode 100644
index 000000000..04d5f8ca5
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindowsettings.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindowsettings.h"
+#include "ui_formwindowsettings.h"
+
+#include <formwindowbase_p.h>
+#include <grid_p.h>
+
+#include <QtGui/QStyle>
+
+#include <QtCore/QRegExp>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// Data structure containing form dialog data providing comparison
+struct FormWindowData {
+ FormWindowData();
+
+ bool equals(const FormWindowData&) const;
+
+ void fromFormWindow(FormWindowBase* fw);
+ void applyToFormWindow(FormWindowBase* fw) const;
+
+ bool layoutDefaultEnabled;
+ int defaultMargin;
+ int defaultSpacing;
+
+ bool layoutFunctionsEnabled;
+ QString marginFunction;
+ QString spacingFunction;
+
+ QString pixFunction;
+
+ QString author;
+
+ QStringList includeHints;
+
+ bool hasFormGrid;
+ Grid grid;
+};
+
+inline bool operator==(const FormWindowData &fd1, const FormWindowData &fd2) { return fd1.equals(fd2); }
+inline bool operator!=(const FormWindowData &fd1, const FormWindowData &fd2) { return !fd1.equals(fd2); }
+
+QDebug operator<<(QDebug str, const FormWindowData &d)
+{
+ str.nospace() << "LayoutDefault=" << d.layoutDefaultEnabled << ',' << d.defaultMargin
+ << ',' << d.defaultSpacing << " LayoutFunctions=" << d.layoutFunctionsEnabled << ','
+ << d.marginFunction << ',' << d.spacingFunction << " PixFunction="
+ << d.pixFunction << " Author=" << d.author << " Hints=" << d.includeHints
+ << " Grid=" << d.hasFormGrid << d.grid.deltaX() << d.grid.deltaY() << '\n';
+ return str;
+}
+
+FormWindowData::FormWindowData() :
+ layoutDefaultEnabled(false),
+ defaultMargin(0),
+ defaultSpacing(0),
+ layoutFunctionsEnabled(false),
+ hasFormGrid(false)
+{
+}
+
+bool FormWindowData::equals(const FormWindowData &rhs) const
+{
+ return layoutDefaultEnabled == rhs.layoutDefaultEnabled &&
+ defaultMargin == rhs.defaultMargin &&
+ defaultSpacing == rhs.defaultSpacing &&
+ layoutFunctionsEnabled == rhs.layoutFunctionsEnabled &&
+ marginFunction == rhs.marginFunction &&
+ spacingFunction == rhs.spacingFunction &&
+ pixFunction == rhs.pixFunction &&
+ author == rhs.author &&
+ includeHints == rhs.includeHints &&
+ hasFormGrid == rhs.hasFormGrid &&
+ grid == rhs.grid;
+}
+
+void FormWindowData::fromFormWindow(FormWindowBase* fw)
+{
+ defaultMargin = defaultSpacing = INT_MIN;
+ fw->layoutDefault(&defaultMargin, &defaultSpacing);
+
+ QStyle *style = fw->formContainer()->style();
+ layoutDefaultEnabled = defaultMargin != INT_MIN || defaultMargin != INT_MIN;
+ if (defaultMargin == INT_MIN)
+ defaultMargin = style->pixelMetric(QStyle::PM_DefaultChildMargin, 0);
+ if (defaultSpacing == INT_MIN)
+ defaultSpacing = style->pixelMetric(QStyle::PM_DefaultLayoutSpacing, 0);
+
+
+ marginFunction.clear();
+ spacingFunction.clear();
+ fw->layoutFunction(&marginFunction, &spacingFunction);
+ layoutFunctionsEnabled = !marginFunction.isEmpty() || !spacingFunction.isEmpty();
+
+ pixFunction = fw->pixmapFunction();
+
+ author = fw->author();
+
+ includeHints = fw->includeHints();
+ includeHints.removeAll(QString());
+
+ hasFormGrid = fw->hasFormGrid();
+ grid = hasFormGrid ? fw->designerGrid() : FormWindowBase::defaultDesignerGrid();
+}
+
+void FormWindowData::applyToFormWindow(FormWindowBase* fw) const
+{
+ fw->setAuthor(author);
+ fw->setPixmapFunction(pixFunction);
+
+ if (layoutDefaultEnabled) {
+ fw->setLayoutDefault(defaultMargin, defaultSpacing);
+ } else {
+ fw->setLayoutDefault(INT_MIN, INT_MIN);
+ }
+
+ if (layoutFunctionsEnabled) {
+ fw->setLayoutFunction(marginFunction, spacingFunction);
+ } else {
+ fw->setLayoutFunction(QString(), QString());
+ }
+
+ fw->setIncludeHints(includeHints);
+
+ const bool hadFormGrid = fw->hasFormGrid();
+ fw->setHasFormGrid(hasFormGrid);
+ if (hasFormGrid || hadFormGrid != hasFormGrid)
+ fw->setDesignerGrid(hasFormGrid ? grid : FormWindowBase::defaultDesignerGrid());
+}
+
+// -------------------------- FormWindowSettings
+
+FormWindowSettings::FormWindowSettings(QDesignerFormWindowInterface *parent) :
+ QDialog(parent),
+ m_ui(new ::Ui::FormWindowSettings),
+ m_formWindow(qobject_cast<FormWindowBase*>(parent)),
+ m_oldData(new FormWindowData)
+{
+ Q_ASSERT(m_formWindow);
+
+ m_ui->setupUi(this);
+ m_ui->gridPanel->setCheckable(true);
+ m_ui->gridPanel->setResetButtonVisible(false);
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ QString deviceProfileName = m_formWindow->deviceProfileName();
+ if (deviceProfileName.isEmpty())
+ deviceProfileName = tr("None");
+ m_ui->deviceProfileLabel->setText(tr("Device Profile: %1").arg(deviceProfileName));
+
+ m_oldData->fromFormWindow(m_formWindow);
+ setData(*m_oldData);
+}
+
+FormWindowSettings::~FormWindowSettings()
+{
+ delete m_oldData;
+ delete m_ui;
+}
+
+FormWindowData FormWindowSettings::data() const
+{
+ FormWindowData rc;
+ rc.author = m_ui->authorLineEdit->text();
+
+ if (m_ui->pixmapFunctionGroupBox->isChecked()) {
+ rc.pixFunction = m_ui->pixmapFunctionLineEdit->text();
+ } else {
+ rc.pixFunction.clear();
+ }
+
+ rc.layoutDefaultEnabled = m_ui->layoutDefaultGroupBox->isChecked();
+ rc.defaultMargin = m_ui->defaultMarginSpinBox->value();
+ rc.defaultSpacing = m_ui->defaultSpacingSpinBox->value();
+
+ rc.layoutFunctionsEnabled = m_ui->layoutFunctionGroupBox->isChecked();
+ rc.marginFunction = m_ui->marginFunctionLineEdit->text();
+ rc.spacingFunction = m_ui->spacingFunctionLineEdit->text();
+
+ const QString hints = m_ui->includeHintsTextEdit->toPlainText();
+ if (!hints.isEmpty()) {
+ rc.includeHints = hints.split(QString(QLatin1Char('\n')));
+ // Purge out any lines consisting of blanks only
+ const QRegExp blankLine = QRegExp(QLatin1String("^\\s*$"));
+ Q_ASSERT(blankLine.isValid());
+ for (QStringList::iterator it = rc.includeHints.begin(); it != rc.includeHints.end(); )
+ if (blankLine.exactMatch(*it)) {
+ it = rc.includeHints.erase(it);
+ } else {
+ ++it;
+ }
+ rc.includeHints.removeAll(QString());
+ }
+
+ rc.hasFormGrid = m_ui->gridPanel->isChecked();
+ rc.grid = m_ui->gridPanel->grid();
+ return rc;
+}
+
+void FormWindowSettings::setData(const FormWindowData &data)
+{
+ m_ui->layoutDefaultGroupBox->setChecked(data.layoutDefaultEnabled);
+ m_ui->defaultMarginSpinBox->setValue(data.defaultMargin);
+ m_ui->defaultSpacingSpinBox->setValue(data.defaultSpacing);
+
+ m_ui->layoutFunctionGroupBox->setChecked(data.layoutFunctionsEnabled);
+ m_ui->marginFunctionLineEdit->setText(data.marginFunction);
+ m_ui->spacingFunctionLineEdit->setText(data.spacingFunction);
+
+ m_ui->pixmapFunctionLineEdit->setText(data.pixFunction);
+ m_ui->pixmapFunctionGroupBox->setChecked(!data.pixFunction.isEmpty());
+
+ m_ui->authorLineEdit->setText(data.author);
+
+ if (data.includeHints.empty()) {
+ m_ui->includeHintsTextEdit->clear();
+ } else {
+ m_ui->includeHintsTextEdit->setText(data.includeHints.join(QLatin1String("\n")));
+ }
+
+ m_ui->gridPanel->setChecked(data.hasFormGrid);
+ m_ui->gridPanel->setGrid(data.grid);
+}
+
+void FormWindowSettings::accept()
+{
+ // Anything changed? -> Apply and set dirty
+ const FormWindowData newData = data();
+ if (newData != *m_oldData) {
+ newData.applyToFormWindow(m_formWindow);
+ m_formWindow->setDirty(true);
+ }
+
+ QDialog::accept();
+}
+}
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/formwindowsettings.h b/src/designer/src/components/formeditor/formwindowsettings.h
new file mode 100644
index 000000000..f5c6f53e3
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindowsettings.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMWINDOWSETTINGS_H
+#define FORMWINDOWSETTINGS_H
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class FormWindowSettings;
+}
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+struct FormWindowData;
+class FormWindowBase;
+
+/* Dialog to edit the settings of a QDesignerFormWindowInterface.
+ * It sets the dirty flag on the form window if something was changed. */
+
+class FormWindowSettings: public QDialog
+{
+ Q_DISABLE_COPY(FormWindowSettings)
+ Q_OBJECT
+public:
+ explicit FormWindowSettings(QDesignerFormWindowInterface *formWindow);
+ virtual ~FormWindowSettings();
+
+ virtual void accept();
+
+private:
+ FormWindowData data() const;
+ void setData(const FormWindowData&);
+
+ Ui::FormWindowSettings *m_ui;
+ FormWindowBase *m_formWindow;
+ FormWindowData *m_oldData;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOWSETTINGS_H
diff --git a/src/designer/src/components/formeditor/formwindowsettings.ui b/src/designer/src/components/formeditor/formwindowsettings.ui
new file mode 100644
index 000000000..1a607b263
--- /dev/null
+++ b/src/designer/src/components/formeditor/formwindowsettings.ui
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>FormWindowSettings</class>
+ <widget class="QDialog" name="FormWindowSettings">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>470</width>
+ <height>466</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form Settings</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="3" column="0" colspan="2">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="layoutDefaultGroupBox">
+ <property name="title">
+ <string>Layout &amp;Default</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>&amp;Spacing:</string>
+ </property>
+ <property name="buddy">
+ <cstring>defaultSpacingSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>&amp;Margin:</string>
+ </property>
+ <property name="buddy">
+ <cstring>defaultMarginSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="defaultSpacingSpinBox"/>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="defaultMarginSpinBox"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="layoutFunctionGroupBox">
+ <property name="title">
+ <string>&amp;Layout Function</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="spacingFunctionLineEdit"/>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="marginFunctionLineEdit"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Ma&amp;rgin:</string>
+ </property>
+ <property name="buddy">
+ <cstring>marginFunctionLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3_2">
+ <property name="text">
+ <string>Spa&amp;cing:</string>
+ </property>
+ <property name="buddy">
+ <cstring>spacingFunctionLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="1">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="pixmapFunctionGroupBox">
+ <property name="title">
+ <string>&amp;Pixmap Function</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="pixmapFunctionLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="1">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>111</width>
+ <height>115</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="7" column="0" colspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="2">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" rowspan="2">
+ <widget class="QGroupBox" name="includeHintsGroupBox">
+ <property name="title">
+ <string>&amp;Include Hints</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="includeHintsTextEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="qdesigner_internal::GridPanel" name="gridPanel">
+ <property name="title">
+ <string>Grid</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QGroupBox" name="embeddedGroupBox">
+ <property name="title">
+ <string>Embedded Design</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="deviceProfileLabel">
+ <property name="text">
+ <string notr="true">TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QGroupBox" name="pixmapFunctionGroupBox_2">
+ <property name="title">
+ <string>&amp;Author</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="authorLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>qdesigner_internal::GridPanel</class>
+ <extends>QGroupBox</extends>
+ <header location="global">gridpanel_p.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>authorLineEdit</tabstop>
+ <tabstop>defaultMarginSpinBox</tabstop>
+ <tabstop>defaultSpacingSpinBox</tabstop>
+ <tabstop>marginFunctionLineEdit</tabstop>
+ <tabstop>spacingFunctionLineEdit</tabstop>
+ <tabstop>pixmapFunctionLineEdit</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>FormWindowSettings</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>294</x>
+ <y>442</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>150</x>
+ <y>459</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>FormWindowSettings</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>373</x>
+ <y>444</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>357</x>
+ <y>461</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/components/formeditor/iconcache.cpp b/src/designer/src/components/formeditor/iconcache.cpp
new file mode 100644
index 000000000..3fceeeade
--- /dev/null
+++ b/src/designer/src/components/formeditor/iconcache.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "iconcache.h"
+#include <QtGui/QPixmap>
+#include <QtGui/QIcon>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+IconCache::IconCache(QObject *parent)
+ : QDesignerIconCacheInterface(parent)
+{
+}
+
+QIcon IconCache::nameToIcon(const QString &path, const QString &resourcePath)
+{
+ Q_UNUSED(path)
+ Q_UNUSED(resourcePath)
+ qWarning() << "IconCache::nameToIcon(): IconCache is obsoleted";
+ return QIcon();
+}
+
+QString IconCache::iconToFilePath(const QIcon &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "IconCache::iconToFilePath(): IconCache is obsoleted";
+ return QString();
+}
+
+QString IconCache::iconToQrcPath(const QIcon &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "IconCache::iconToQrcPath(): IconCache is obsoleted";
+ return QString();
+}
+
+QPixmap IconCache::nameToPixmap(const QString &path, const QString &resourcePath)
+{
+ Q_UNUSED(path)
+ Q_UNUSED(resourcePath)
+ qWarning() << "IconCache::nameToPixmap(): IconCache is obsoleted";
+ return QPixmap();
+}
+
+QString IconCache::pixmapToFilePath(const QPixmap &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "IconCache::pixmapToFilePath(): IconCache is obsoleted";
+ return QString();
+}
+
+QString IconCache::pixmapToQrcPath(const QPixmap &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "IconCache::pixmapToQrcPath(): IconCache is obsoleted";
+ return QString();
+}
+
+QList<QPixmap> IconCache::pixmapList() const
+{
+ qWarning() << "IconCache::pixmapList(): IconCache is obsoleted";
+ return QList<QPixmap>();
+}
+
+QList<QIcon> IconCache::iconList() const
+{
+ qWarning() << "IconCache::iconList(): IconCache is obsoleted";
+ return QList<QIcon>();
+}
+
+QString IconCache::resolveQrcPath(const QString &filePath, const QString &qrcPath, const QString &wd) const
+{
+ Q_UNUSED(filePath)
+ Q_UNUSED(qrcPath)
+ Q_UNUSED(wd)
+ qWarning() << "IconCache::resolveQrcPath(): IconCache is obsoleted";
+ return QString();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/iconcache.h b/src/designer/src/components/formeditor/iconcache.h
new file mode 100644
index 000000000..5d9cc6580
--- /dev/null
+++ b/src/designer/src/components/formeditor/iconcache.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ICONCACHE_H
+#define ICONCACHE_H
+
+#include "formeditor_global.h"
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QT_FORMEDITOR_EXPORT IconCache : public QDesignerIconCacheInterface
+{
+ Q_OBJECT
+public:
+ explicit IconCache(QObject *parent);
+
+ virtual QIcon nameToIcon(const QString &path, const QString &resourcePath = QString());
+ virtual QString iconToFilePath(const QIcon &pm) const;
+ virtual QString iconToQrcPath(const QIcon &pm) const;
+ virtual QPixmap nameToPixmap(const QString &path, const QString &resourcePath = QString());
+ virtual QString pixmapToFilePath(const QPixmap &pm) const;
+ virtual QString pixmapToQrcPath(const QPixmap &pm) const;
+
+ virtual QList<QPixmap> pixmapList() const;
+ virtual QList<QIcon> iconList() const;
+
+ virtual QString resolveQrcPath(const QString &filePath, const QString &qrcPath, const QString &workingDirectory = QString()) const;
+
+private:
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ICONCACHE_H
diff --git a/src/designer/src/components/formeditor/images/cleartext.png b/src/designer/src/components/formeditor/images/cleartext.png
new file mode 100644
index 000000000..74133baff
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cleartext.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/color.png b/src/designer/src/components/formeditor/images/color.png
new file mode 100644
index 000000000..54b7ebcde
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/color.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/configure.png b/src/designer/src/components/formeditor/images/configure.png
new file mode 100644
index 000000000..d9f2fd8c0
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/configure.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/arrow.png b/src/designer/src/components/formeditor/images/cursors/arrow.png
new file mode 100644
index 000000000..a69ef4eb6
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/arrow.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/busy.png b/src/designer/src/components/formeditor/images/cursors/busy.png
new file mode 100644
index 000000000..53717e499
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/busy.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/closedhand.png b/src/designer/src/components/formeditor/images/cursors/closedhand.png
new file mode 100644
index 000000000..b78dd1dac
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/closedhand.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/cross.png b/src/designer/src/components/formeditor/images/cursors/cross.png
new file mode 100644
index 000000000..fe38e7448
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/cross.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/hand.png b/src/designer/src/components/formeditor/images/cursors/hand.png
new file mode 100644
index 000000000..d2004aefa
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/hand.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/hsplit.png b/src/designer/src/components/formeditor/images/cursors/hsplit.png
new file mode 100644
index 000000000..a5667e3ff
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/hsplit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/ibeam.png b/src/designer/src/components/formeditor/images/cursors/ibeam.png
new file mode 100644
index 000000000..097fc5fa7
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/ibeam.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/no.png b/src/designer/src/components/formeditor/images/cursors/no.png
new file mode 100644
index 000000000..2b08c4e2a
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/no.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/openhand.png b/src/designer/src/components/formeditor/images/cursors/openhand.png
new file mode 100644
index 000000000..9181c859e
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/openhand.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/sizeall.png b/src/designer/src/components/formeditor/images/cursors/sizeall.png
new file mode 100644
index 000000000..69f13eb34
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/sizeall.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/sizeb.png b/src/designer/src/components/formeditor/images/cursors/sizeb.png
new file mode 100644
index 000000000..3b127a05d
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/sizeb.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/sizef.png b/src/designer/src/components/formeditor/images/cursors/sizef.png
new file mode 100644
index 000000000..f37d7b91e
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/sizef.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/sizeh.png b/src/designer/src/components/formeditor/images/cursors/sizeh.png
new file mode 100644
index 000000000..a9f40cbc3
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/sizeh.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/sizev.png b/src/designer/src/components/formeditor/images/cursors/sizev.png
new file mode 100644
index 000000000..1edbab27a
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/sizev.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/uparrow.png b/src/designer/src/components/formeditor/images/cursors/uparrow.png
new file mode 100644
index 000000000..d3e70ef4c
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/uparrow.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/vsplit.png b/src/designer/src/components/formeditor/images/cursors/vsplit.png
new file mode 100644
index 000000000..1beda2570
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/vsplit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/wait.png b/src/designer/src/components/formeditor/images/cursors/wait.png
new file mode 100644
index 000000000..69056c479
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/wait.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/cursors/whatsthis.png b/src/designer/src/components/formeditor/images/cursors/whatsthis.png
new file mode 100644
index 000000000..b47601c37
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/cursors/whatsthis.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/downplus.png b/src/designer/src/components/formeditor/images/downplus.png
new file mode 100644
index 000000000..1e384a72d
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/downplus.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/dropdownbutton.png b/src/designer/src/components/formeditor/images/dropdownbutton.png
new file mode 100644
index 000000000..5dd964946
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/dropdownbutton.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/edit.png b/src/designer/src/components/formeditor/images/edit.png
new file mode 100644
index 000000000..a5e49adf9
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/edit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/editdelete-16.png b/src/designer/src/components/formeditor/images/editdelete-16.png
new file mode 100644
index 000000000..ef5c799c1
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/editdelete-16.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/emptyicon.png b/src/designer/src/components/formeditor/images/emptyicon.png
new file mode 100644
index 000000000..897220e21
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/emptyicon.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/filenew-16.png b/src/designer/src/components/formeditor/images/filenew-16.png
new file mode 100644
index 000000000..eefb3c520
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/filenew-16.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/fileopen-16.png b/src/designer/src/components/formeditor/images/fileopen-16.png
new file mode 100644
index 000000000..d832c621c
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/fileopen-16.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/leveldown.png b/src/designer/src/components/formeditor/images/leveldown.png
new file mode 100644
index 000000000..742b7fb84
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/leveldown.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/levelup.png b/src/designer/src/components/formeditor/images/levelup.png
new file mode 100644
index 000000000..48b3e8922
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/levelup.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/adjustsize.png b/src/designer/src/components/formeditor/images/mac/adjustsize.png
new file mode 100644
index 000000000..c4d884c8b
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/adjustsize.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/back.png b/src/designer/src/components/formeditor/images/mac/back.png
new file mode 100644
index 000000000..e58177f43
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/back.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/buddytool.png b/src/designer/src/components/formeditor/images/mac/buddytool.png
new file mode 100644
index 000000000..2a4287089
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/buddytool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/down.png b/src/designer/src/components/formeditor/images/mac/down.png
new file mode 100644
index 000000000..29d1d4439
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/down.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editbreaklayout.png b/src/designer/src/components/formeditor/images/mac/editbreaklayout.png
new file mode 100644
index 000000000..dc005590b
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editbreaklayout.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editcopy.png b/src/designer/src/components/formeditor/images/mac/editcopy.png
new file mode 100644
index 000000000..f55136446
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editcopy.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editcut.png b/src/designer/src/components/formeditor/images/mac/editcut.png
new file mode 100644
index 000000000..a784fd570
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editcut.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editdelete.png b/src/designer/src/components/formeditor/images/mac/editdelete.png
new file mode 100644
index 000000000..201b31cdb
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editdelete.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editform.png b/src/designer/src/components/formeditor/images/mac/editform.png
new file mode 100644
index 000000000..4fc2e40dc
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editform.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editgrid.png b/src/designer/src/components/formeditor/images/mac/editgrid.png
new file mode 100644
index 000000000..bba4a695b
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editgrid.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/edithlayout.png b/src/designer/src/components/formeditor/images/mac/edithlayout.png
new file mode 100644
index 000000000..ec880bb5c
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/edithlayout.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/edithlayoutsplit.png b/src/designer/src/components/formeditor/images/mac/edithlayoutsplit.png
new file mode 100644
index 000000000..227d0115f
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/edithlayoutsplit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editlower.png b/src/designer/src/components/formeditor/images/mac/editlower.png
new file mode 100644
index 000000000..347806fc0
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editlower.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editpaste.png b/src/designer/src/components/formeditor/images/mac/editpaste.png
new file mode 100644
index 000000000..64c0b2d6a
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editpaste.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editraise.png b/src/designer/src/components/formeditor/images/mac/editraise.png
new file mode 100644
index 000000000..09cbbd7d5
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editraise.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editvlayout.png b/src/designer/src/components/formeditor/images/mac/editvlayout.png
new file mode 100644
index 000000000..63b26cdb2
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editvlayout.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/editvlayoutsplit.png b/src/designer/src/components/formeditor/images/mac/editvlayoutsplit.png
new file mode 100644
index 000000000..5a02c944e
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/editvlayoutsplit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/filenew.png b/src/designer/src/components/formeditor/images/mac/filenew.png
new file mode 100644
index 000000000..9dcba4284
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/filenew.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/fileopen.png b/src/designer/src/components/formeditor/images/mac/fileopen.png
new file mode 100644
index 000000000..c12bcd507
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/fileopen.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/filesave.png b/src/designer/src/components/formeditor/images/mac/filesave.png
new file mode 100644
index 000000000..b41ecf531
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/filesave.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/forward.png b/src/designer/src/components/formeditor/images/mac/forward.png
new file mode 100644
index 000000000..34b91f09f
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/forward.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/insertimage.png b/src/designer/src/components/formeditor/images/mac/insertimage.png
new file mode 100644
index 000000000..b8673e13b
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/insertimage.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/minus.png b/src/designer/src/components/formeditor/images/mac/minus.png
new file mode 100644
index 000000000..8d2eaed52
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/minus.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/plus.png b/src/designer/src/components/formeditor/images/mac/plus.png
new file mode 100644
index 000000000..1ee45423e
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/plus.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/redo.png b/src/designer/src/components/formeditor/images/mac/redo.png
new file mode 100644
index 000000000..8875bf246
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/redo.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/resetproperty.png b/src/designer/src/components/formeditor/images/mac/resetproperty.png
new file mode 100644
index 000000000..9048252ec
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/resetproperty.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/resourceeditortool.png b/src/designer/src/components/formeditor/images/mac/resourceeditortool.png
new file mode 100644
index 000000000..7ef511c2b
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/resourceeditortool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/signalslottool.png b/src/designer/src/components/formeditor/images/mac/signalslottool.png
new file mode 100644
index 000000000..71c9b07a8
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/signalslottool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/simplifyrichtext.png b/src/designer/src/components/formeditor/images/mac/simplifyrichtext.png
new file mode 100644
index 000000000..a48e974bf
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/simplifyrichtext.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/tabordertool.png b/src/designer/src/components/formeditor/images/mac/tabordertool.png
new file mode 100644
index 000000000..f54faf9ab
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/tabordertool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textanchor.png b/src/designer/src/components/formeditor/images/mac/textanchor.png
new file mode 100644
index 000000000..baa9dda52
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textanchor.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textbold.png b/src/designer/src/components/formeditor/images/mac/textbold.png
new file mode 100644
index 000000000..38400bd1f
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textbold.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textcenter.png b/src/designer/src/components/formeditor/images/mac/textcenter.png
new file mode 100644
index 000000000..2ef5b2ee6
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textcenter.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textitalic.png b/src/designer/src/components/formeditor/images/mac/textitalic.png
new file mode 100644
index 000000000..0170ee26a
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textitalic.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textjustify.png b/src/designer/src/components/formeditor/images/mac/textjustify.png
new file mode 100644
index 000000000..39cd6c1a9
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textjustify.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textleft.png b/src/designer/src/components/formeditor/images/mac/textleft.png
new file mode 100644
index 000000000..83a66d553
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textleft.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textright.png b/src/designer/src/components/formeditor/images/mac/textright.png
new file mode 100644
index 000000000..e7c04645c
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textright.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textsubscript.png b/src/designer/src/components/formeditor/images/mac/textsubscript.png
new file mode 100644
index 000000000..ff431f396
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textsubscript.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textsuperscript.png b/src/designer/src/components/formeditor/images/mac/textsuperscript.png
new file mode 100644
index 000000000..cb67a33d0
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textsuperscript.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/textunder.png b/src/designer/src/components/formeditor/images/mac/textunder.png
new file mode 100644
index 000000000..968bac5e9
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/textunder.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/undo.png b/src/designer/src/components/formeditor/images/mac/undo.png
new file mode 100644
index 000000000..a3bd5e0bf
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/undo.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/up.png b/src/designer/src/components/formeditor/images/mac/up.png
new file mode 100644
index 000000000..e43731221
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/up.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/mac/widgettool.png b/src/designer/src/components/formeditor/images/mac/widgettool.png
new file mode 100644
index 000000000..e1aa353db
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/mac/widgettool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/minus-16.png b/src/designer/src/components/formeditor/images/minus-16.png
new file mode 100644
index 000000000..745b44572
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/minus-16.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/plus-16.png b/src/designer/src/components/formeditor/images/plus-16.png
new file mode 100644
index 000000000..ef43788e6
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/plus-16.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/prefix-add.png b/src/designer/src/components/formeditor/images/prefix-add.png
new file mode 100644
index 000000000..cfbb053f4
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/prefix-add.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/qt3logo.png b/src/designer/src/components/formeditor/images/qt3logo.png
new file mode 100644
index 000000000..720285001
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/qt3logo.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/qtlogo.png b/src/designer/src/components/formeditor/images/qtlogo.png
new file mode 100644
index 000000000..038fa2cc3
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/qtlogo.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/reload.png b/src/designer/src/components/formeditor/images/reload.png
new file mode 100644
index 000000000..18c752e14
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/reload.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/resetproperty.png b/src/designer/src/components/formeditor/images/resetproperty.png
new file mode 100644
index 000000000..9048252ec
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/resetproperty.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/sort.png b/src/designer/src/components/formeditor/images/sort.png
new file mode 100644
index 000000000..883bfa9de
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/sort.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/submenu.png b/src/designer/src/components/formeditor/images/submenu.png
new file mode 100644
index 000000000..3deb28e3a
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/submenu.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/calendarwidget.png b/src/designer/src/components/formeditor/images/widgets/calendarwidget.png
new file mode 100644
index 000000000..26737b883
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/calendarwidget.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/checkbox.png b/src/designer/src/components/formeditor/images/widgets/checkbox.png
new file mode 100644
index 000000000..ab6f53e02
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/checkbox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/columnview.png b/src/designer/src/components/formeditor/images/widgets/columnview.png
new file mode 100644
index 000000000..4132ee6b1
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/columnview.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/combobox.png b/src/designer/src/components/formeditor/images/widgets/combobox.png
new file mode 100644
index 000000000..bf3ed79f7
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/combobox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/commandlinkbutton.png b/src/designer/src/components/formeditor/images/widgets/commandlinkbutton.png
new file mode 100644
index 000000000..6bbd84a97
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/commandlinkbutton.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/dateedit.png b/src/designer/src/components/formeditor/images/widgets/dateedit.png
new file mode 100644
index 000000000..6827fa742
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/dateedit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/datetimeedit.png b/src/designer/src/components/formeditor/images/widgets/datetimeedit.png
new file mode 100644
index 000000000..7d8e6fe6d
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/datetimeedit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/dial.png b/src/designer/src/components/formeditor/images/widgets/dial.png
new file mode 100644
index 000000000..050d1dbd0
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/dial.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/dialogbuttonbox.png b/src/designer/src/components/formeditor/images/widgets/dialogbuttonbox.png
new file mode 100644
index 000000000..b1f89fbb3
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/dialogbuttonbox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/dockwidget.png b/src/designer/src/components/formeditor/images/widgets/dockwidget.png
new file mode 100644
index 000000000..9eee04f70
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/dockwidget.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/doublespinbox.png b/src/designer/src/components/formeditor/images/widgets/doublespinbox.png
new file mode 100644
index 000000000..5686ac89b
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/doublespinbox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/fontcombobox.png b/src/designer/src/components/formeditor/images/widgets/fontcombobox.png
new file mode 100644
index 000000000..6848f15c2
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/fontcombobox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/frame.png b/src/designer/src/components/formeditor/images/widgets/frame.png
new file mode 100644
index 000000000..68f5da0a3
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/frame.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/graphicsview.png b/src/designer/src/components/formeditor/images/widgets/graphicsview.png
new file mode 100644
index 000000000..93fe7603a
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/graphicsview.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/groupbox.png b/src/designer/src/components/formeditor/images/widgets/groupbox.png
new file mode 100644
index 000000000..4025b4dc5
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/groupbox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/groupboxcollapsible.png b/src/designer/src/components/formeditor/images/widgets/groupboxcollapsible.png
new file mode 100644
index 000000000..62fd1ad56
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/groupboxcollapsible.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/hscrollbar.png b/src/designer/src/components/formeditor/images/widgets/hscrollbar.png
new file mode 100644
index 000000000..466c58de5
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/hscrollbar.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/hslider.png b/src/designer/src/components/formeditor/images/widgets/hslider.png
new file mode 100644
index 000000000..525bd1cab
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/hslider.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/hsplit.png b/src/designer/src/components/formeditor/images/widgets/hsplit.png
new file mode 100644
index 000000000..1ea8f2ac0
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/hsplit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/label.png b/src/designer/src/components/formeditor/images/widgets/label.png
new file mode 100644
index 000000000..5d7d7b4cc
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/label.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/lcdnumber.png b/src/designer/src/components/formeditor/images/widgets/lcdnumber.png
new file mode 100644
index 000000000..c3cac1826
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/lcdnumber.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/line.png b/src/designer/src/components/formeditor/images/widgets/line.png
new file mode 100644
index 000000000..5c64dfb59
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/line.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/lineedit.png b/src/designer/src/components/formeditor/images/widgets/lineedit.png
new file mode 100644
index 000000000..75fc890f4
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/lineedit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/listbox.png b/src/designer/src/components/formeditor/images/widgets/listbox.png
new file mode 100644
index 000000000..367e67ff5
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/listbox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/listview.png b/src/designer/src/components/formeditor/images/widgets/listview.png
new file mode 100644
index 000000000..d1308d575
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/listview.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/mdiarea.png b/src/designer/src/components/formeditor/images/widgets/mdiarea.png
new file mode 100644
index 000000000..7783dd527
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/mdiarea.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/plaintextedit.png b/src/designer/src/components/formeditor/images/widgets/plaintextedit.png
new file mode 100644
index 000000000..077bf16cb
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/plaintextedit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/progress.png b/src/designer/src/components/formeditor/images/widgets/progress.png
new file mode 100644
index 000000000..44ae094e7
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/progress.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/pushbutton.png b/src/designer/src/components/formeditor/images/widgets/pushbutton.png
new file mode 100644
index 000000000..61f779ce2
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/pushbutton.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/radiobutton.png b/src/designer/src/components/formeditor/images/widgets/radiobutton.png
new file mode 100644
index 000000000..10c1d8c3e
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/radiobutton.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/scrollarea.png b/src/designer/src/components/formeditor/images/widgets/scrollarea.png
new file mode 100644
index 000000000..651ea24c0
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/scrollarea.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/spacer.png b/src/designer/src/components/formeditor/images/widgets/spacer.png
new file mode 100644
index 000000000..8a0931bf8
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/spacer.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/spinbox.png b/src/designer/src/components/formeditor/images/widgets/spinbox.png
new file mode 100644
index 000000000..cdd9fe141
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/spinbox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/tabbar.png b/src/designer/src/components/formeditor/images/widgets/tabbar.png
new file mode 100644
index 000000000..d5d37836b
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/tabbar.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/table.png b/src/designer/src/components/formeditor/images/widgets/table.png
new file mode 100644
index 000000000..4bbd9c2d0
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/table.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/tabwidget.png b/src/designer/src/components/formeditor/images/widgets/tabwidget.png
new file mode 100644
index 000000000..1254bb63a
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/tabwidget.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/textedit.png b/src/designer/src/components/formeditor/images/widgets/textedit.png
new file mode 100644
index 000000000..32e897d97
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/textedit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/timeedit.png b/src/designer/src/components/formeditor/images/widgets/timeedit.png
new file mode 100644
index 000000000..c66d91b2f
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/timeedit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/toolbox.png b/src/designer/src/components/formeditor/images/widgets/toolbox.png
new file mode 100644
index 000000000..2ab71dc74
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/toolbox.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/toolbutton.png b/src/designer/src/components/formeditor/images/widgets/toolbutton.png
new file mode 100644
index 000000000..0bff069a5
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/toolbutton.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/vline.png b/src/designer/src/components/formeditor/images/widgets/vline.png
new file mode 100644
index 000000000..35a7300a5
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/vline.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/vscrollbar.png b/src/designer/src/components/formeditor/images/widgets/vscrollbar.png
new file mode 100644
index 000000000..28b7c40c6
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/vscrollbar.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/vslider.png b/src/designer/src/components/formeditor/images/widgets/vslider.png
new file mode 100644
index 000000000..59f06bae4
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/vslider.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/vspacer.png b/src/designer/src/components/formeditor/images/widgets/vspacer.png
new file mode 100644
index 000000000..ce5e8bd7d
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/vspacer.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/widget.png b/src/designer/src/components/formeditor/images/widgets/widget.png
new file mode 100644
index 000000000..1cf960e61
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/widget.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/widgetstack.png b/src/designer/src/components/formeditor/images/widgets/widgetstack.png
new file mode 100644
index 000000000..2c6964e3e
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/widgetstack.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/widgets/wizard.png b/src/designer/src/components/formeditor/images/widgets/wizard.png
new file mode 100644
index 000000000..7c0e107ae
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/widgets/wizard.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/adjustsize.png b/src/designer/src/components/formeditor/images/win/adjustsize.png
new file mode 100644
index 000000000..3cda33371
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/adjustsize.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/back.png b/src/designer/src/components/formeditor/images/win/back.png
new file mode 100644
index 000000000..e58177f43
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/back.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/buddytool.png b/src/designer/src/components/formeditor/images/win/buddytool.png
new file mode 100644
index 000000000..4cd968bbf
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/buddytool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/down.png b/src/designer/src/components/formeditor/images/win/down.png
new file mode 100644
index 000000000..29d1d4439
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/down.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editbreaklayout.png b/src/designer/src/components/formeditor/images/win/editbreaklayout.png
new file mode 100644
index 000000000..07c5fae69
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editbreaklayout.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editcopy.png b/src/designer/src/components/formeditor/images/win/editcopy.png
new file mode 100644
index 000000000..1121b47d8
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editcopy.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editcut.png b/src/designer/src/components/formeditor/images/win/editcut.png
new file mode 100644
index 000000000..4b6c82c7a
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editcut.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editdelete.png b/src/designer/src/components/formeditor/images/win/editdelete.png
new file mode 100644
index 000000000..5a4251402
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editdelete.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editform.png b/src/designer/src/components/formeditor/images/win/editform.png
new file mode 100644
index 000000000..452fcd887
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editform.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editgrid.png b/src/designer/src/components/formeditor/images/win/editgrid.png
new file mode 100644
index 000000000..789bf7d96
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editgrid.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/edithlayout.png b/src/designer/src/components/formeditor/images/win/edithlayout.png
new file mode 100644
index 000000000..4dd3f0ce4
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/edithlayout.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/edithlayoutsplit.png b/src/designer/src/components/formeditor/images/win/edithlayoutsplit.png
new file mode 100644
index 000000000..2dcc69029
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/edithlayoutsplit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editlower.png b/src/designer/src/components/formeditor/images/win/editlower.png
new file mode 100644
index 000000000..ba630944c
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editlower.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editpaste.png b/src/designer/src/components/formeditor/images/win/editpaste.png
new file mode 100644
index 000000000..ffab15aaf
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editpaste.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editraise.png b/src/designer/src/components/formeditor/images/win/editraise.png
new file mode 100644
index 000000000..bb8362c1f
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editraise.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editvlayout.png b/src/designer/src/components/formeditor/images/win/editvlayout.png
new file mode 100644
index 000000000..7ad28fdea
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editvlayout.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/editvlayoutsplit.png b/src/designer/src/components/formeditor/images/win/editvlayoutsplit.png
new file mode 100644
index 000000000..720e18bb3
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/editvlayoutsplit.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/filenew.png b/src/designer/src/components/formeditor/images/win/filenew.png
new file mode 100644
index 000000000..af5d12214
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/filenew.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/fileopen.png b/src/designer/src/components/formeditor/images/win/fileopen.png
new file mode 100644
index 000000000..fc6f17e97
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/fileopen.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/filesave.png b/src/designer/src/components/formeditor/images/win/filesave.png
new file mode 100644
index 000000000..8feec99be
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/filesave.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/forward.png b/src/designer/src/components/formeditor/images/win/forward.png
new file mode 100644
index 000000000..34b91f09f
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/forward.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/insertimage.png b/src/designer/src/components/formeditor/images/win/insertimage.png
new file mode 100644
index 000000000..cfab6375f
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/insertimage.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/minus.png b/src/designer/src/components/formeditor/images/win/minus.png
new file mode 100644
index 000000000..c0dc274bb
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/minus.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/plus.png b/src/designer/src/components/formeditor/images/win/plus.png
new file mode 100644
index 000000000..ecf058941
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/plus.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/redo.png b/src/designer/src/components/formeditor/images/win/redo.png
new file mode 100644
index 000000000..686ad141c
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/redo.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/resourceeditortool.png b/src/designer/src/components/formeditor/images/win/resourceeditortool.png
new file mode 100644
index 000000000..cc9cb5851
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/resourceeditortool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/signalslottool.png b/src/designer/src/components/formeditor/images/win/signalslottool.png
new file mode 100644
index 000000000..e80fd1caa
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/signalslottool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/simplifyrichtext.png b/src/designer/src/components/formeditor/images/win/simplifyrichtext.png
new file mode 100644
index 000000000..e251cf7b9
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/simplifyrichtext.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/tabordertool.png b/src/designer/src/components/formeditor/images/win/tabordertool.png
new file mode 100644
index 000000000..7e6e2de71
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/tabordertool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textanchor.png b/src/designer/src/components/formeditor/images/win/textanchor.png
new file mode 100644
index 000000000..1911ab0d5
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textanchor.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textbold.png b/src/designer/src/components/formeditor/images/win/textbold.png
new file mode 100644
index 000000000..9cbc7138b
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textbold.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textcenter.png b/src/designer/src/components/formeditor/images/win/textcenter.png
new file mode 100644
index 000000000..11efb4b85
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textcenter.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textitalic.png b/src/designer/src/components/formeditor/images/win/textitalic.png
new file mode 100644
index 000000000..b30ce14c1
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textitalic.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textjustify.png b/src/designer/src/components/formeditor/images/win/textjustify.png
new file mode 100644
index 000000000..9de0c8808
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textjustify.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textleft.png b/src/designer/src/components/formeditor/images/win/textleft.png
new file mode 100644
index 000000000..16f80bc32
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textleft.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textright.png b/src/designer/src/components/formeditor/images/win/textright.png
new file mode 100644
index 000000000..16872df62
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textright.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textsubscript.png b/src/designer/src/components/formeditor/images/win/textsubscript.png
new file mode 100644
index 000000000..d86347d83
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textsubscript.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textsuperscript.png b/src/designer/src/components/formeditor/images/win/textsuperscript.png
new file mode 100644
index 000000000..910996560
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textsuperscript.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/textunder.png b/src/designer/src/components/formeditor/images/win/textunder.png
new file mode 100644
index 000000000..c72eff53f
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/textunder.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/undo.png b/src/designer/src/components/formeditor/images/win/undo.png
new file mode 100644
index 000000000..c3b8c5136
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/undo.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/up.png b/src/designer/src/components/formeditor/images/win/up.png
new file mode 100644
index 000000000..e43731221
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/up.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/images/win/widgettool.png b/src/designer/src/components/formeditor/images/win/widgettool.png
new file mode 100644
index 000000000..a52224e06
--- /dev/null
+++ b/src/designer/src/components/formeditor/images/win/widgettool.png
Binary files differ
diff --git a/src/designer/src/components/formeditor/itemview_propertysheet.cpp b/src/designer/src/components/formeditor/itemview_propertysheet.cpp
new file mode 100644
index 000000000..e04c55d5a
--- /dev/null
+++ b/src/designer/src/components/formeditor/itemview_propertysheet.cpp
@@ -0,0 +1,270 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "itemview_propertysheet.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QHeaderView>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+struct Property {
+ Property() : m_sheet(0),m_id(-1) {}
+ Property(QDesignerPropertySheetExtension *sheet, int id)
+ : m_sheet(sheet), m_id(id) {}
+
+ QDesignerPropertySheetExtension *m_sheet;
+ int m_id;
+};
+
+typedef QMap<int, Property> FakePropertyMap;
+
+struct ItemViewPropertySheetPrivate {
+ ItemViewPropertySheetPrivate(QDesignerFormEditorInterface *core,
+ QHeaderView *horizontalHeader,
+ QHeaderView *verticalHeader);
+
+ inline QStringList realPropertyNames();
+ inline QString fakePropertyName(const QString &prefix, const QString &realName);
+
+ // Maps index of fake property to index of real property in respective sheet
+ FakePropertyMap m_propertyIdMap;
+
+ // Maps name of fake property to name of real property
+ QHash<QString, QString> m_propertyNameMap;
+
+ QHash<QHeaderView *, QDesignerPropertySheetExtension *> m_propertySheet;
+ QStringList m_realPropertyNames;
+};
+
+// Name of the fake group
+static const char *headerGroup = "Header";
+
+// Name of the real properties
+static const char *visibleProperty = "visible";
+static const char *cascadingSectionResizesProperty = "cascadingSectionResizes";
+static const char *defaultSectionSizeProperty = "defaultSectionSize";
+static const char *highlightSectionsProperty = "highlightSections";
+static const char *minimumSectionSizeProperty = "minimumSectionSize";
+static const char *showSortIndicatorProperty = "showSortIndicator";
+static const char *stretchLastSectionProperty = "stretchLastSection";
+} // namespace qdesigner_internal
+
+using namespace qdesigner_internal;
+
+
+/***************** ItemViewPropertySheetPrivate *********************/
+
+ItemViewPropertySheetPrivate::ItemViewPropertySheetPrivate(QDesignerFormEditorInterface *core,
+ QHeaderView *horizontalHeader,
+ QHeaderView *verticalHeader)
+{
+ if (horizontalHeader)
+ m_propertySheet.insert(horizontalHeader,
+ qt_extension<QDesignerPropertySheetExtension*>
+ (core->extensionManager(), horizontalHeader));
+ if (verticalHeader)
+ m_propertySheet.insert(verticalHeader,
+ qt_extension<QDesignerPropertySheetExtension*>
+ (core->extensionManager(), verticalHeader));
+}
+
+QStringList ItemViewPropertySheetPrivate::realPropertyNames()
+{
+ if (m_realPropertyNames.isEmpty())
+ m_realPropertyNames
+ << QLatin1String(visibleProperty)
+ << QLatin1String(cascadingSectionResizesProperty)
+ << QLatin1String(defaultSectionSizeProperty)
+ << QLatin1String(highlightSectionsProperty)
+ << QLatin1String(minimumSectionSizeProperty)
+ << QLatin1String(showSortIndicatorProperty)
+ << QLatin1String(stretchLastSectionProperty);
+ return m_realPropertyNames;
+}
+
+QString ItemViewPropertySheetPrivate::fakePropertyName(const QString &prefix,
+ const QString &realName)
+{
+ // prefix = "header", realPropertyName = "isVisible" returns "headerIsVisible"
+ QString fakeName = prefix + realName.at(0).toUpper() + realName.mid(1);
+ m_propertyNameMap.insert(fakeName, realName);
+ return fakeName;
+}
+
+/***************** ItemViewPropertySheet *********************/
+
+/*!
+ \class qdesigner_internal::ItemViewPropertySheet
+
+ \brief
+ Adds header fake properties to QTreeView and QTableView objects
+
+ QHeaderView objects are currently not shown in the object inspector.
+ This class adds some fake properties to the property sheet
+ of QTreeView and QTableView objects that nevertheless allow the manipulation
+ of the headers attached to the item view object.
+
+ Currently the defaultAlignment property is not shown because the property sheet
+ would only show integers, instead of the Qt::Alignment enumeration.
+
+ The fake properties here need special handling in QDesignerResource, uiloader and uic.
+ */
+
+ItemViewPropertySheet::ItemViewPropertySheet(QTreeView *treeViewObject, QObject *parent)
+ : QDesignerPropertySheet(treeViewObject, parent),
+ d(new ItemViewPropertySheetPrivate(core(), treeViewObject->header(), 0))
+{
+ initHeaderProperties(treeViewObject->header(), QLatin1String("header"));
+}
+
+ItemViewPropertySheet::ItemViewPropertySheet(QTableView *tableViewObject, QObject *parent)
+ : QDesignerPropertySheet(tableViewObject, parent),
+ d(new ItemViewPropertySheetPrivate(core(),
+ tableViewObject->horizontalHeader(),
+ tableViewObject->verticalHeader()))
+{
+ initHeaderProperties(tableViewObject->horizontalHeader(), QLatin1String("horizontalHeader"));
+ initHeaderProperties(tableViewObject->verticalHeader(), QLatin1String("verticalHeader"));
+}
+
+ItemViewPropertySheet::~ItemViewPropertySheet()
+{
+ delete d;
+}
+
+void ItemViewPropertySheet::initHeaderProperties(QHeaderView *hv, const QString &prefix)
+{
+ QDesignerPropertySheetExtension *headerSheet = d->m_propertySheet.value(hv);
+ Q_ASSERT(headerSheet);
+ const QString headerGroupS = QLatin1String(headerGroup);
+ foreach (const QString &realPropertyName, d->realPropertyNames()) {
+ const int headerIndex = headerSheet->indexOf(realPropertyName);
+ Q_ASSERT(headerIndex != -1);
+ const QVariant defaultValue = realPropertyName == QLatin1String(visibleProperty) ?
+ QVariant(true) : headerSheet->property(headerIndex);
+ const QString fakePropertyName = d->fakePropertyName(prefix, realPropertyName);
+ const int fakeIndex = createFakeProperty(fakePropertyName, defaultValue);
+ d->m_propertyIdMap.insert(fakeIndex, Property(headerSheet, headerIndex));
+ setAttribute(fakeIndex, true);
+ setPropertyGroup(fakeIndex, headerGroupS);
+ }
+}
+
+/*!
+ Returns the mapping of fake property names to real property names
+ */
+QHash<QString,QString> ItemViewPropertySheet::propertyNameMap() const
+{
+ return d->m_propertyNameMap;
+}
+
+QVariant ItemViewPropertySheet::property(int index) const
+{
+ const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(index);
+ if (it != d->m_propertyIdMap.constEnd())
+ return it.value().m_sheet->property(it.value().m_id);
+ return QDesignerPropertySheet::property(index);
+}
+
+void ItemViewPropertySheet::setProperty(int index, const QVariant &value)
+{
+ const FakePropertyMap::iterator it = d->m_propertyIdMap.find(index);
+ if (it != d->m_propertyIdMap.end()) {
+ it.value().m_sheet->setProperty(it.value().m_id, value);
+ } else {
+ QDesignerPropertySheet::setProperty(index, value);
+ }
+}
+
+void ItemViewPropertySheet::setChanged(int index, bool changed)
+{
+ const FakePropertyMap::iterator it = d->m_propertyIdMap.find(index);
+ if (it != d->m_propertyIdMap.end()) {
+ it.value().m_sheet->setChanged(it.value().m_id, changed);
+ } else {
+ QDesignerPropertySheet::setChanged(index, changed);
+ }
+}
+
+bool ItemViewPropertySheet::isChanged(int index) const
+{
+ const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(index);
+ if (it != d->m_propertyIdMap.constEnd())
+ return it.value().m_sheet->isChanged(it.value().m_id);
+ return QDesignerPropertySheet::isChanged(index);
+}
+
+bool ItemViewPropertySheet::hasReset(int index) const
+{
+ const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(index);
+ if (it != d->m_propertyIdMap.constEnd())
+ return it.value().m_sheet->hasReset(it.value().m_id);
+ return QDesignerPropertySheet::hasReset(index);
+}
+
+bool ItemViewPropertySheet::reset(int index)
+{
+ const FakePropertyMap::iterator it = d->m_propertyIdMap.find(index);
+ if (it != d->m_propertyIdMap.end()) {
+ QDesignerPropertySheetExtension *headerSheet = it.value().m_sheet;
+ const int headerIndex = it.value().m_id;
+ const bool resetRC = headerSheet->reset(headerIndex);
+ // Resetting for "visible" might fail and the stored default
+ // of the Widget database is "false" due to the widget not being
+ // visible at the time it was determined. Reset to "true" manually.
+ if (!resetRC && headerSheet->propertyName(headerIndex) == QLatin1String(visibleProperty)) {
+ headerSheet->setProperty(headerIndex, QVariant(true));
+ headerSheet->setChanged(headerIndex, false);
+ return true;
+ }
+ return resetRC;
+ } else {
+ return QDesignerPropertySheet::reset(index);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/itemview_propertysheet.h b/src/designer/src/components/formeditor/itemview_propertysheet.h
new file mode 100644
index 000000000..59cf809c8
--- /dev/null
+++ b/src/designer/src/components/formeditor/itemview_propertysheet.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ITEMVIEW_PROPERTYSHEET_H
+#define ITEMVIEW_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QTreeView>
+#include <QtGui/QTableView>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+struct ItemViewPropertySheetPrivate;
+
+class ItemViewPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit ItemViewPropertySheet(QTreeView *treeViewObject, QObject *parent = 0);
+ explicit ItemViewPropertySheet(QTableView *tableViewObject, QObject *parent = 0);
+ ~ItemViewPropertySheet();
+
+ QHash<QString,QString> propertyNameMap() const;
+
+ // QDesignerPropertySheet
+ QVariant property(int index) const;
+ void setProperty(int index, const QVariant &value);
+
+ virtual void setChanged(int index, bool changed);
+ virtual bool isChanged(int index) const;
+
+ virtual bool hasReset(int index) const;
+ virtual bool reset(int index);
+
+private:
+ void initHeaderProperties(QHeaderView *hv, const QString &prefix);
+
+ ItemViewPropertySheetPrivate *d;
+};
+
+typedef QDesignerPropertySheetFactory<QTreeView, ItemViewPropertySheet>
+ QTreeViewPropertySheetFactory;
+typedef QDesignerPropertySheetFactory<QTableView, ItemViewPropertySheet>
+ QTableViewPropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ITEMVIEW_PROPERTYSHEET_H
diff --git a/src/designer/src/components/formeditor/layout_propertysheet.cpp b/src/designer/src/components/formeditor/layout_propertysheet.cpp
new file mode 100644
index 000000000..34e51b178
--- /dev/null
+++ b/src/designer/src/components/formeditor/layout_propertysheet.cpp
@@ -0,0 +1,546 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "layout_propertysheet.h"
+
+// sdk
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+// shared
+#include <ui4_p.h>
+#include <qlayout_widget_p.h>
+#include <formbuilderextra_p.h>
+
+#include <QtGui/QFormLayout>
+
+#include <QtCore/QHash>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+#include <QtCore/QByteArray>
+#include <QtCore/QRegExp> // Remove once there is an editor for lists
+
+QT_BEGIN_NAMESPACE
+
+#define USE_LAYOUT_SIZE_CONSTRAINT
+
+static const char *leftMargin = "leftMargin";
+static const char *topMargin = "topMargin";
+static const char *rightMargin = "rightMargin";
+static const char *bottomMargin = "bottomMargin";
+static const char *horizontalSpacing = "horizontalSpacing";
+static const char *verticalSpacing = "verticalSpacing";
+static const char *spacing = "spacing";
+static const char *margin = "margin";
+static const char *sizeConstraint = "sizeConstraint";
+static const char *boxStretchPropertyC = "stretch";
+static const char *gridRowStretchPropertyC = "rowStretch";
+static const char *gridColumnStretchPropertyC = "columnStretch";
+static const char *gridRowMinimumHeightPropertyC = "rowMinimumHeight";
+static const char *gridColumnMinimumWidthPropertyC = "columnMinimumWidth";
+
+namespace {
+ enum LayoutPropertyType {
+ LayoutPropertyNone,
+ LayoutPropertyMargin, // Deprecated
+ LayoutPropertyLeftMargin,
+ LayoutPropertyTopMargin,
+ LayoutPropertyRightMargin,
+ LayoutPropertyBottomMargin,
+ LayoutPropertySpacing,
+ LayoutPropertyHorizontalSpacing,
+ LayoutPropertyVerticalSpacing,
+ LayoutPropertySizeConstraint,
+ LayoutPropertyBoxStretch,
+ LayoutPropertyGridRowStretch,
+ LayoutPropertyGridColumnStretch,
+ LayoutPropertyGridRowMinimumHeight,
+ LayoutPropertyGridColumnMinimumWidth
+ };
+}
+
+// Check for a comma-separated list of integers. Used for
+// per-cell stretch properties and grid per row/column properties.
+// As it works now, they are passed as QByteArray strings. The
+// property sheet refuses all invalid values. This could be
+// replaced by lists once the property editor can handle them.
+
+static bool isIntegerList(const QString &s)
+{
+ // Check for empty string or comma-separated list of integers
+ static const QRegExp re(QLatin1String("[0-9]+(,[0-9]+)+"));
+ Q_ASSERT(re.isValid());
+ return s.isEmpty() || re.exactMatch(s);
+}
+
+// Quick lookup by name
+static LayoutPropertyType layoutPropertyType(const QString &name)
+{
+ static QHash<QString, LayoutPropertyType> namePropertyMap;
+ if (namePropertyMap.empty()) {
+ namePropertyMap.insert(QLatin1String(leftMargin), LayoutPropertyLeftMargin);
+ namePropertyMap.insert(QLatin1String(topMargin), LayoutPropertyTopMargin);
+ namePropertyMap.insert(QLatin1String(rightMargin), LayoutPropertyRightMargin);
+ namePropertyMap.insert(QLatin1String(bottomMargin), LayoutPropertyBottomMargin);
+ namePropertyMap.insert(QLatin1String(horizontalSpacing), LayoutPropertyHorizontalSpacing);
+ namePropertyMap.insert(QLatin1String(verticalSpacing), LayoutPropertyVerticalSpacing);
+ namePropertyMap.insert(QLatin1String(spacing), LayoutPropertySpacing);
+ namePropertyMap.insert(QLatin1String(margin), LayoutPropertyMargin);
+ namePropertyMap.insert(QLatin1String(sizeConstraint), LayoutPropertySizeConstraint);
+ namePropertyMap.insert(QLatin1String(boxStretchPropertyC ), LayoutPropertyBoxStretch);
+ namePropertyMap.insert(QLatin1String(gridRowStretchPropertyC), LayoutPropertyGridRowStretch);
+ namePropertyMap.insert(QLatin1String(gridColumnStretchPropertyC), LayoutPropertyGridColumnStretch);
+ namePropertyMap.insert(QLatin1String(gridRowMinimumHeightPropertyC), LayoutPropertyGridRowMinimumHeight);
+ namePropertyMap.insert(QLatin1String(gridColumnMinimumWidthPropertyC), LayoutPropertyGridColumnMinimumWidth);
+ }
+ return namePropertyMap.value(name, LayoutPropertyNone);
+}
+
+// return the layout margin if it is margin
+static int getLayoutMargin(const QLayout *l, LayoutPropertyType type)
+{
+ int left, top, right, bottom;
+ l->getContentsMargins(&left, &top, &right, &bottom);
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ return left;
+ case LayoutPropertyTopMargin:
+ return top;
+ case LayoutPropertyRightMargin:
+ return right;
+ case LayoutPropertyBottomMargin:
+ return bottom;
+ default:
+ Q_ASSERT(0);
+ break;
+ }
+ return 0;
+}
+
+// return the layout margin if it is margin
+static void setLayoutMargin(QLayout *l, LayoutPropertyType type, int margin)
+{
+ int left, top, right, bottom;
+ l->getContentsMargins(&left, &top, &right, &bottom);
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ left = margin;
+ break;
+ case LayoutPropertyTopMargin:
+ top = margin;
+ break;
+ case LayoutPropertyRightMargin:
+ right = margin;
+ break;
+ case LayoutPropertyBottomMargin:
+ bottom = margin;
+ break;
+ default:
+ Q_ASSERT(0);
+ break;
+ }
+ l->setContentsMargins(left, top, right, bottom);
+}
+
+namespace qdesigner_internal {
+
+// ---------- LayoutPropertySheet: This sheet is never visible in
+// the property editor. Rather, the sheet pulled for QLayoutWidget
+// forwards all properties to it. Some properties (grid spacings) must be handled
+// manually, as they are QDOC_PROPERTY only and not visible to introspection. Ditto
+// for the 4 margins.
+
+LayoutPropertySheet::LayoutPropertySheet(QLayout *l, QObject *parent)
+ : QDesignerPropertySheet(l, parent), m_layout(l)
+{
+ const QString layoutGroup = QLatin1String("Layout");
+ int pindex = createFakeProperty(QLatin1String(leftMargin), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ pindex = createFakeProperty(QLatin1String(topMargin), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ pindex = createFakeProperty(QLatin1String(rightMargin), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ pindex = createFakeProperty(QLatin1String(bottomMargin), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ const int visibleMask = LayoutProperties::visibleProperties(m_layout);
+ if (visibleMask & LayoutProperties::HorizSpacingProperty) {
+ pindex = createFakeProperty(QLatin1String(horizontalSpacing), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ pindex = createFakeProperty(QLatin1String(verticalSpacing), 0);
+ setPropertyGroup(pindex, layoutGroup);
+
+ setAttribute(indexOf(QLatin1String(spacing)), true);
+ }
+
+ setAttribute(indexOf(QLatin1String(margin)), true);
+ // Stretch
+ if (visibleMask & LayoutProperties::BoxStretchProperty) {
+ pindex = createFakeProperty(QLatin1String(boxStretchPropertyC), QByteArray());
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ } else {
+ // Add the grid per-row/column stretch and size limits
+ if (visibleMask & LayoutProperties::GridColumnStretchProperty) {
+ const QByteArray empty;
+ pindex = createFakeProperty(QLatin1String(gridRowStretchPropertyC), empty);
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ pindex = createFakeProperty(QLatin1String(gridColumnStretchPropertyC), empty);
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ pindex = createFakeProperty(QLatin1String(gridRowMinimumHeightPropertyC), empty);
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ pindex = createFakeProperty(QLatin1String(gridColumnMinimumWidthPropertyC), empty);
+ setPropertyGroup(pindex, layoutGroup);
+ setAttribute(pindex, true);
+ }
+ }
+#ifdef USE_LAYOUT_SIZE_CONSTRAINT
+ // SizeConstraint cannot possibly be handled as a real property
+ // as it affects the layout parent widget and thus
+ // conflicts with Designer's special layout widget.
+ // It will take effect on the preview only.
+ pindex = createFakeProperty(QLatin1String(sizeConstraint));
+ setPropertyGroup(pindex, layoutGroup);
+#endif
+}
+
+LayoutPropertySheet::~LayoutPropertySheet()
+{
+}
+
+void LayoutPropertySheet::setProperty(int index, const QVariant &value)
+{
+ const LayoutPropertyType type = layoutPropertyType(propertyName(index));
+ if (QLayoutWidget *lw = qobject_cast<QLayoutWidget *>(m_layout->parent())) {
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ lw->setLayoutLeftMargin(value.toInt());
+ return;
+ case LayoutPropertyTopMargin:
+ lw->setLayoutTopMargin(value.toInt());
+ return;
+ case LayoutPropertyRightMargin:
+ lw->setLayoutRightMargin(value.toInt());
+ return;
+ case LayoutPropertyBottomMargin:
+ lw->setLayoutBottomMargin(value.toInt());
+ return;
+ case LayoutPropertyMargin: {
+ const int v = value.toInt();
+ lw->setLayoutLeftMargin(v);
+ lw->setLayoutTopMargin(v);
+ lw->setLayoutRightMargin(v);
+ lw->setLayoutBottomMargin(v);
+ }
+ return;
+ default:
+ break;
+ }
+ }
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ case LayoutPropertyTopMargin:
+ case LayoutPropertyRightMargin:
+ case LayoutPropertyBottomMargin:
+ setLayoutMargin(m_layout, type, value.toInt());
+ return;
+ case LayoutPropertyHorizontalSpacing:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ grid->setHorizontalSpacing(value.toInt());
+ return;
+ }
+ if (QFormLayout *form = qobject_cast<QFormLayout *>(m_layout)) {
+ form->setHorizontalSpacing(value.toInt());
+ return;
+ }
+ break;
+ case LayoutPropertyVerticalSpacing:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ grid->setVerticalSpacing(value.toInt());
+ return;
+ }
+ if (QFormLayout *form = qobject_cast<QFormLayout *>(m_layout)) {
+ form->setVerticalSpacing(value.toInt());
+ return;
+ }
+ break;
+ case LayoutPropertyBoxStretch:
+ // TODO: Remove the regexp check once a proper editor for integer
+ // lists is in place?
+ if (QBoxLayout *box = qobject_cast<QBoxLayout *>(m_layout)) {
+ const QString stretch = value.toString();
+ if (isIntegerList(stretch))
+ QFormBuilderExtra::setBoxLayoutStretch(value.toString(), box);
+ }
+ break;
+ case LayoutPropertyGridRowStretch:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ const QString stretch = value.toString();
+ if (isIntegerList(stretch))
+ QFormBuilderExtra::setGridLayoutRowStretch(stretch, grid);
+ }
+ break;
+ case LayoutPropertyGridColumnStretch:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ const QString stretch = value.toString();
+ if (isIntegerList(stretch))
+ QFormBuilderExtra::setGridLayoutColumnStretch(value.toString(), grid);
+ }
+ break;
+ case LayoutPropertyGridRowMinimumHeight:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ const QString minSize = value.toString();
+ if (isIntegerList(minSize))
+ QFormBuilderExtra::setGridLayoutRowMinimumHeight(minSize, grid);
+ }
+ break;
+ case LayoutPropertyGridColumnMinimumWidth:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout)) {
+ const QString minSize = value.toString();
+ if (isIntegerList(minSize))
+ QFormBuilderExtra::setGridLayoutColumnMinimumWidth(minSize, grid);
+ }
+ break;
+ default:
+ break;
+ }
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+QVariant LayoutPropertySheet::property(int index) const
+{
+ const LayoutPropertyType type = layoutPropertyType(propertyName(index));
+ if (const QLayoutWidget *lw = qobject_cast<QLayoutWidget *>(m_layout->parent())) {
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ return lw->layoutLeftMargin();
+ case LayoutPropertyTopMargin:
+ return lw->layoutTopMargin();
+ case LayoutPropertyRightMargin:
+ return lw->layoutRightMargin();
+ case LayoutPropertyBottomMargin:
+ return lw->layoutBottomMargin();
+ default:
+ break;
+ }
+ }
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ case LayoutPropertyTopMargin:
+ case LayoutPropertyRightMargin:
+ case LayoutPropertyBottomMargin:
+ return getLayoutMargin(m_layout, type);
+ case LayoutPropertyHorizontalSpacing:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return grid->horizontalSpacing();
+ if (const QFormLayout *form = qobject_cast<QFormLayout *>(m_layout))
+ return form->horizontalSpacing();
+ break;
+ case LayoutPropertyVerticalSpacing:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return grid->verticalSpacing();
+ if (const QFormLayout *form = qobject_cast<QFormLayout *>(m_layout))
+ return form->verticalSpacing();
+ case LayoutPropertyBoxStretch:
+ if (const QBoxLayout *box = qobject_cast<QBoxLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::boxLayoutStretch(box).toUtf8()));
+ break;
+ case LayoutPropertyGridRowStretch:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::gridLayoutRowStretch(grid).toUtf8()));
+ break;
+ case LayoutPropertyGridColumnStretch:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::gridLayoutColumnStretch(grid).toUtf8()));
+ break;
+ case LayoutPropertyGridRowMinimumHeight:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::gridLayoutRowMinimumHeight(grid).toUtf8()));
+ break;
+ case LayoutPropertyGridColumnMinimumWidth:
+ if (const QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ return QVariant(QByteArray(QFormBuilderExtra::gridLayoutColumnMinimumWidth(grid).toUtf8()));
+ break;
+ default:
+ break;
+ }
+ return QDesignerPropertySheet::property(index);
+}
+
+bool LayoutPropertySheet::reset(int index)
+{
+ int left, top, right, bottom;
+ m_layout->getContentsMargins(&left, &top, &right, &bottom);
+ const LayoutPropertyType type = layoutPropertyType(propertyName(index));
+ bool rc = true;
+ switch (type) {
+ case LayoutPropertyLeftMargin:
+ m_layout->setContentsMargins(-1, top, right, bottom);
+ break;
+ case LayoutPropertyTopMargin:
+ m_layout->setContentsMargins(left, -1, right, bottom);
+ break;
+ case LayoutPropertyRightMargin:
+ m_layout->setContentsMargins(left, top, -1, bottom);
+ break;
+ case LayoutPropertyBottomMargin:
+ m_layout->setContentsMargins(left, top, right, -1);
+ break;
+ case LayoutPropertyBoxStretch:
+ if (QBoxLayout *box = qobject_cast<QBoxLayout *>(m_layout))
+ QFormBuilderExtra::clearBoxLayoutStretch(box);
+ break;
+ case LayoutPropertyGridRowStretch:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ QFormBuilderExtra::clearGridLayoutRowStretch(grid);
+ break;
+ case LayoutPropertyGridColumnStretch:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ QFormBuilderExtra::clearGridLayoutColumnStretch(grid);
+ break;
+ case LayoutPropertyGridRowMinimumHeight:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ QFormBuilderExtra::clearGridLayoutRowMinimumHeight(grid);
+ break;
+ case LayoutPropertyGridColumnMinimumWidth:
+ if (QGridLayout *grid = qobject_cast<QGridLayout *>(m_layout))
+ QFormBuilderExtra::clearGridLayoutColumnMinimumWidth(grid);
+ break;
+ default:
+ rc = QDesignerPropertySheet::reset(index);
+ break;
+ }
+ return rc;
+}
+
+void LayoutPropertySheet::setChanged(int index, bool changed)
+{
+ const LayoutPropertyType type = layoutPropertyType(propertyName(index));
+ switch (type) {
+ case LayoutPropertySpacing:
+ if (LayoutProperties::visibleProperties(m_layout) & LayoutProperties::HorizSpacingProperty) {
+ setChanged(indexOf(QLatin1String(horizontalSpacing)), changed);
+ setChanged(indexOf(QLatin1String(verticalSpacing)), changed);
+ }
+ break;
+ case LayoutPropertyMargin:
+ setChanged(indexOf(QLatin1String(leftMargin)), changed);
+ setChanged(indexOf(QLatin1String(topMargin)), changed);
+ setChanged(indexOf(QLatin1String(rightMargin)), changed);
+ setChanged(indexOf(QLatin1String(bottomMargin)), changed);
+ break;
+ default:
+ break;
+ }
+ QDesignerPropertySheet::setChanged(index, changed);
+}
+
+void LayoutPropertySheet::stretchAttributesToDom(QDesignerFormEditorInterface *core, QLayout *lt, DomLayout *domLayout)
+{
+ // Check if the respective stretch properties of the layout are changed.
+ // If so, set them to the DOM
+ const int visibleMask = LayoutProperties::visibleProperties(lt);
+ if (!(visibleMask & (LayoutProperties::BoxStretchProperty|LayoutProperties::GridColumnStretchProperty|LayoutProperties::GridRowStretchProperty)))
+ return;
+ const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), lt);
+ Q_ASSERT(sheet);
+
+ // Stretch
+ if (visibleMask & LayoutProperties::BoxStretchProperty) {
+ const int index = sheet->indexOf(QLatin1String(boxStretchPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeStretch(sheet->property(index).toString());
+ }
+ if (visibleMask & LayoutProperties::GridColumnStretchProperty) {
+ const int index = sheet->indexOf(QLatin1String(gridColumnStretchPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeColumnStretch(sheet->property(index).toString());
+ }
+ if (visibleMask & LayoutProperties::GridRowStretchProperty) {
+ const int index = sheet->indexOf(QLatin1String(gridRowStretchPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeRowStretch(sheet->property(index).toString());
+ }
+ if (visibleMask & LayoutProperties::GridRowMinimumHeightProperty) {
+ const int index = sheet->indexOf(QLatin1String(gridRowMinimumHeightPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeRowMinimumHeight(sheet->property(index).toString());
+ }
+ if (visibleMask & LayoutProperties::GridColumnMinimumWidthProperty) {
+ const int index = sheet->indexOf(QLatin1String(gridColumnMinimumWidthPropertyC));
+ Q_ASSERT(index != -1);
+ if (sheet->isChanged(index))
+ domLayout->setAttributeColumnMinimumWidth(sheet->property(index).toString());
+ }
+}
+
+void LayoutPropertySheet::markChangedStretchProperties(QDesignerFormEditorInterface *core, QLayout *lt, const DomLayout *domLayout)
+{
+ // While the actual values are applied by the form builder, we still need
+ // to mark them as 'changed'.
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), lt);
+ Q_ASSERT(sheet);
+ if (!domLayout->attributeStretch().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(boxStretchPropertyC)), true);
+ if (!domLayout->attributeRowStretch().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(gridRowStretchPropertyC)), true);
+ if (!domLayout->attributeColumnStretch().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(gridColumnStretchPropertyC)), true);
+ if (!domLayout->attributeColumnMinimumWidth().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(gridColumnMinimumWidthPropertyC)), true);
+ if (!domLayout->attributeRowMinimumHeight().isEmpty())
+ sheet->setChanged(sheet->indexOf(QLatin1String(gridRowMinimumHeightPropertyC)), true);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/layout_propertysheet.h b/src/designer/src/components/formeditor/layout_propertysheet.h
new file mode 100644
index 000000000..72a59f876
--- /dev/null
+++ b/src/designer/src/components/formeditor/layout_propertysheet.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LAYOUT_PROPERTYSHEET_H
+#define LAYOUT_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class DomLayout;
+
+namespace qdesigner_internal {
+
+class LayoutPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit LayoutPropertySheet(QLayout *object, QObject *parent = 0);
+ virtual ~LayoutPropertySheet();
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual QVariant property(int index) const;
+ virtual bool reset(int index);
+ void setChanged(int index, bool changed);
+
+ static void stretchAttributesToDom(QDesignerFormEditorInterface *core, QLayout *lt, DomLayout *domLayout);
+ static void markChangedStretchProperties(QDesignerFormEditorInterface *core, QLayout *lt, const DomLayout *domLayout);
+
+private:
+ QLayout *m_layout;
+};
+
+typedef QDesignerPropertySheetFactory<QLayout, LayoutPropertySheet> LayoutPropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LAYOUT_PROPERTYSHEET_H
diff --git a/src/designer/src/components/formeditor/line_propertysheet.cpp b/src/designer/src/components/formeditor/line_propertysheet.cpp
new file mode 100644
index 000000000..64699eaa5
--- /dev/null
+++ b/src/designer/src/components/formeditor/line_propertysheet.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "line_propertysheet.h"
+#include "formwindow.h"
+
+// sdk
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QLayout>
+#include <QtCore/QMetaObject>
+#include <QtCore/QMetaProperty>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+LinePropertySheet::LinePropertySheet(Line *object, QObject *parent)
+ : QDesignerPropertySheet(object, parent)
+{
+ clearFakeProperties();
+}
+
+LinePropertySheet::~LinePropertySheet()
+{
+}
+
+bool LinePropertySheet::isVisible(int index) const
+{
+ const QString name = propertyName(index);
+
+ if (name == QLatin1String("frameShape"))
+ return false;
+ return QDesignerPropertySheet::isVisible(index);
+}
+
+void LinePropertySheet::setProperty(int index, const QVariant &value)
+{
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+QString LinePropertySheet::propertyGroup(int index) const
+{
+ return QDesignerPropertySheet::propertyGroup(index);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/line_propertysheet.h b/src/designer/src/components/formeditor/line_propertysheet.h
new file mode 100644
index 000000000..ec1c098f3
--- /dev/null
+++ b/src/designer/src/components/formeditor/line_propertysheet.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LINE_PROPERTYSHEET_H
+#define LINE_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <qdesigner_widget_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class LinePropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit LinePropertySheet(Line *object, QObject *parent = 0);
+ virtual ~LinePropertySheet();
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool isVisible(int index) const;
+ virtual QString propertyGroup(int index) const;
+};
+
+typedef QDesignerPropertySheetFactory<Line, LinePropertySheet> LinePropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LINE_PROPERTYSHEET_H
diff --git a/src/designer/src/components/formeditor/previewactiongroup.cpp b/src/designer/src/components/formeditor/previewactiongroup.cpp
new file mode 100644
index 000000000..607212c41
--- /dev/null
+++ b/src/designer/src/components/formeditor/previewactiongroup.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "previewactiongroup.h"
+
+#include <deviceprofile_p.h>
+#include <shared_settings_p.h>
+
+#include <QtGui/QStyleFactory>
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+enum { MaxDeviceActions = 20 };
+
+namespace qdesigner_internal {
+
+PreviewActionGroup::PreviewActionGroup(QDesignerFormEditorInterface *core, QObject *parent) :
+ QActionGroup(parent),
+ m_core(core)
+{
+ /* Create a list of up to MaxDeviceActions invisible actions to be
+ * populated with device profiles (actiondata: index) followed by the
+ * standard style actions (actiondata: style name). */
+ connect(this, SIGNAL(triggered(QAction*)), this, SLOT(slotTriggered(QAction*)));
+ setExclusive(true);
+
+ const QString objNamePostfix = QLatin1String("_action");
+ // Create invisible actions for devices. Set index as action data.
+ QString objNamePrefix = QLatin1String("__qt_designer_device_");
+ for (int i = 0; i < MaxDeviceActions; i++) {
+ QAction *a = new QAction(this);
+ QString objName = objNamePrefix;
+ objName += QString::number(i);
+ objName += objNamePostfix;
+ a->setObjectName(objName);
+ a->setVisible(false);
+ a->setData(i);
+ addAction(a);
+ }
+ // Create separator at index MaxDeviceActions
+ QAction *sep = new QAction(this);
+ sep->setObjectName(QLatin1String("__qt_designer_deviceseparator"));
+ sep->setSeparator(true);
+ sep->setVisible(false);
+ addAction(sep);
+ // Populate devices
+ updateDeviceProfiles();
+
+ // Add style actions
+ const QStringList styles = QStyleFactory::keys();
+ const QStringList::const_iterator cend = styles.constEnd();
+ // Make sure ObjectName is unique in case toolbar solution is used.
+ objNamePrefix = QLatin1String("__qt_designer_style_");
+ // Create styles. Set style name string as action data.
+ for (QStringList::const_iterator it = styles.constBegin(); it != cend ;++it) {
+ QAction *a = new QAction(tr("%1 Style").arg(*it), this);
+ QString objName = objNamePrefix;
+ objName += *it;
+ objName += objNamePostfix;
+ a->setObjectName(objName);
+ a->setData(*it);
+ addAction(a);
+ }
+}
+
+void PreviewActionGroup::updateDeviceProfiles()
+{
+ typedef QList<DeviceProfile> DeviceProfileList;
+ typedef QList<QAction *> ActionList;
+
+ const QDesignerSharedSettings settings(m_core);
+ const DeviceProfileList profiles = settings.deviceProfiles();
+ const ActionList al = actions();
+ // Separator?
+ const bool hasProfiles = !profiles.empty();
+ al.at(MaxDeviceActions)->setVisible(hasProfiles);
+ int index = 0;
+ if (hasProfiles) {
+ // Make actions visible
+ const int maxIndex = qMin(static_cast<int>(MaxDeviceActions), profiles.size());
+ for (; index < maxIndex; index++) {
+ const QString name = profiles.at(index).name();
+ al.at(index)->setText(name);
+ al.at(index)->setVisible(true);
+ }
+ }
+ // Hide rest
+ for ( ; index < MaxDeviceActions; index++)
+ al.at(index)->setVisible(false);
+}
+
+void PreviewActionGroup::slotTriggered(QAction *a)
+{
+ // Device or style according to data.
+ const QVariant data = a->data();
+ switch (data.type()) {
+ case QVariant::String:
+ emit preview(data.toString(), -1);
+ break;
+ case QVariant::Int:
+ emit preview(QString(), data.toInt());
+ break;
+ default:
+ break;
+ }
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/previewactiongroup.h b/src/designer/src/components/formeditor/previewactiongroup.h
new file mode 100644
index 000000000..9ba65512b
--- /dev/null
+++ b/src/designer/src/components/formeditor/previewactiongroup.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PREVIEWACTIONGROUP_H
+#define PREVIEWACTIONGROUP_H
+
+#include <QtGui/QActionGroup>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+/* PreviewActionGroup: To be used as a submenu for 'Preview in...'
+ * Offers a menu of styles and device profiles. */
+
+class PreviewActionGroup : public QActionGroup
+{
+ Q_DISABLE_COPY(PreviewActionGroup)
+ Q_OBJECT
+public:
+ explicit PreviewActionGroup(QDesignerFormEditorInterface *core, QObject *parent = 0);
+
+signals:
+ void preview(const QString &style, int deviceProfileIndex);
+
+public slots:
+ void updateDeviceProfiles();
+
+private slots:
+ void slotTriggered(QAction *);
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // PREVIEWACTIONGROUP_H
diff --git a/src/designer/src/components/formeditor/qdesigner_resource.cpp b/src/designer/src/components/formeditor/qdesigner_resource.cpp
new file mode 100644
index 000000000..409a20e8d
--- /dev/null
+++ b/src/designer/src/components/formeditor/qdesigner_resource.cpp
@@ -0,0 +1,2475 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_resource.h"
+#include "formwindow.h"
+#include "dynamicpropertysheet.h"
+#include "qdesigner_tabwidget_p.h"
+#include "qdesigner_toolbox_p.h"
+#include "qdesigner_stackedbox_p.h"
+#include "qdesigner_toolbar_p.h"
+#include "qdesigner_dockwidget_p.h"
+#include "qdesigner_menu_p.h"
+#include "qdesigner_menubar_p.h"
+#include "qdesigner_membersheet_p.h"
+#include "qtresourcemodel_p.h"
+#include "qmdiarea_container.h"
+#include "qwizard_container.h"
+#include "layout_propertysheet.h"
+
+#include <ui4_p.h>
+#include <formbuilderextra_p.h>
+#include <resourcebuilder_p.h>
+#include <textbuilder_p.h>
+#include <qdesigner_widgetitem_p.h>
+
+// shared
+#include <widgetdatabase_p.h>
+#include <metadatabase_p.h>
+#include <layout_p.h>
+#include <layoutinfo_p.h>
+#include <spacer_widget_p.h>
+#include <pluginmanager_p.h>
+#include <widgetfactory_p.h>
+#include <abstractlanguage.h>
+#include <abstractintrospection_p.h>
+
+#include <qlayout_widget_p.h>
+#include <qdesigner_utils_p.h>
+#include <ui4_p.h>
+
+// sdk
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <abstractdialoggui_p.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
+#include <QtGui/QLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QToolBar>
+#include <QtGui/QTabBar>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QApplication>
+#include <QtGui/QMainWindow>
+#include <QtGui/QSplitter>
+#include <QtGui/QMdiArea>
+#include <QtGui/QWorkspace>
+#include <QtGui/QMenuBar>
+#include <QtGui/QFileDialog>
+#include <QtGui/QHeaderView>
+#include <QtGui/QWizardPage>
+#include <private/qlayoutengine_p.h>
+
+#include <QtCore/QBuffer>
+#include <QtCore/QDir>
+#include <QtCore/QMetaProperty>
+#include <QtCore/qdebug.h>
+#include <QtCore/QXmlStreamWriter>
+
+Q_DECLARE_METATYPE(QWidgetList)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ typedef QList<DomProperty*> DomPropertyList;
+}
+
+static const char *currentUiVersion = "4.0";
+static const char *clipboardObjectName = "__qt_fake_top_level";
+
+#define OLD_RESOURCE_FORMAT // Support pre 4.4 format.
+
+namespace qdesigner_internal {
+
+// -------------------- QDesignerResourceBuilder: A resource builder that works on the property sheet icon types.
+class QDesignerResourceBuilder : public QResourceBuilder
+{
+public:
+ QDesignerResourceBuilder(QDesignerFormEditorInterface *core, DesignerPixmapCache *pixmapCache, DesignerIconCache *iconCache);
+
+ void setPixmapCache(DesignerPixmapCache *pixmapCache) { m_pixmapCache = pixmapCache; }
+ void setIconCache(DesignerIconCache *iconCache) { m_iconCache = iconCache; }
+ bool isSaveRelative() const { return m_saveRelative; }
+ void setSaveRelative(bool relative) { m_saveRelative = relative; }
+ QStringList usedQrcFiles() const { return m_usedQrcFiles.keys(); }
+#ifdef OLD_RESOURCE_FORMAT
+ QStringList loadedQrcFiles() const { return m_loadedQrcFiles.keys(); } // needed only for loading old resource attribute of <iconset> tag.
+#endif
+
+ virtual QVariant loadResource(const QDir &workingDirectory, const DomProperty *icon) const;
+
+ virtual QVariant toNativeValue(const QVariant &value) const;
+
+ virtual DomProperty *saveResource(const QDir &workingDirectory, const QVariant &value) const;
+
+ virtual bool isResourceType(const QVariant &value) const;
+private:
+
+ QDesignerFormEditorInterface *m_core;
+ DesignerPixmapCache *m_pixmapCache;
+ DesignerIconCache *m_iconCache;
+ const QDesignerLanguageExtension *m_lang;
+ bool m_saveRelative;
+ mutable QMap<QString, bool> m_usedQrcFiles;
+ mutable QMap<QString, bool> m_loadedQrcFiles;
+};
+
+QDesignerResourceBuilder::QDesignerResourceBuilder(QDesignerFormEditorInterface *core, DesignerPixmapCache *pixmapCache, DesignerIconCache *iconCache) :
+ m_core(core),
+ m_pixmapCache(pixmapCache),
+ m_iconCache(iconCache),
+ m_lang(qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core)),
+ m_saveRelative(true)
+{
+}
+
+static inline void setIconPixmap(QIcon::Mode m, QIcon::State s, const QDir &workingDirectory,
+ QString path, PropertySheetIconValue &icon,
+ const QDesignerLanguageExtension *lang = 0)
+{
+ if (lang == 0 || !lang->isLanguageResource(path))
+ path = QFileInfo(workingDirectory, path).absoluteFilePath();
+ icon.setPixmap(m, s, PropertySheetPixmapValue(path));
+}
+
+QVariant QDesignerResourceBuilder::loadResource(const QDir &workingDirectory, const DomProperty *property) const
+{
+ switch (property->kind()) {
+ case DomProperty::Pixmap: {
+ PropertySheetPixmapValue pixmap;
+ DomResourcePixmap *dp = property->elementPixmap();
+ if (!dp->text().isEmpty()) {
+ if (m_lang != 0 && m_lang->isLanguageResource(dp->text())) {
+ pixmap.setPath(dp->text());
+ } else {
+ pixmap.setPath(QFileInfo(workingDirectory, dp->text()).absoluteFilePath());
+ }
+#ifdef OLD_RESOURCE_FORMAT
+ if (dp->hasAttributeResource())
+ m_loadedQrcFiles.insert(QFileInfo(workingDirectory, dp->attributeResource()).absoluteFilePath(), false);
+#endif
+ }
+ return QVariant::fromValue(pixmap);
+ }
+
+ case DomProperty::IconSet: {
+ PropertySheetIconValue icon;
+ DomResourceIcon *di = property->elementIconSet();
+ icon.setTheme(di->attributeTheme());
+ if (const int flags = iconStateFlags(di)) { // new, post 4.4 format
+ if (flags & NormalOff)
+ setIconPixmap(QIcon::Normal, QIcon::Off, workingDirectory, di->elementNormalOff()->text(), icon, m_lang);
+ if (flags & NormalOn)
+ setIconPixmap(QIcon::Normal, QIcon::On, workingDirectory, di->elementNormalOn()->text(), icon, m_lang);
+ if (flags & DisabledOff)
+ setIconPixmap(QIcon::Disabled, QIcon::Off, workingDirectory, di->elementDisabledOff()->text(), icon, m_lang);
+ if (flags & DisabledOn)
+ setIconPixmap(QIcon::Disabled, QIcon::On, workingDirectory, di->elementDisabledOn()->text(), icon, m_lang);
+ if (flags & ActiveOff)
+ setIconPixmap(QIcon::Active, QIcon::Off, workingDirectory, di->elementActiveOff()->text(), icon, m_lang);
+ if (flags & ActiveOn)
+ setIconPixmap(QIcon::Active, QIcon::On, workingDirectory, di->elementActiveOn()->text(), icon, m_lang);
+ if (flags & SelectedOff)
+ setIconPixmap(QIcon::Selected, QIcon::Off, workingDirectory, di->elementSelectedOff()->text(), icon, m_lang);
+ if (flags & SelectedOn)
+ setIconPixmap(QIcon::Selected, QIcon::On, workingDirectory, di->elementSelectedOn()->text(), icon, m_lang);
+ } else {
+#ifdef OLD_RESOURCE_FORMAT
+ setIconPixmap(QIcon::Normal, QIcon::Off, workingDirectory, di->text(), icon, m_lang);
+ if (di->hasAttributeResource())
+ m_loadedQrcFiles.insert(QFileInfo(workingDirectory, di->attributeResource()).absoluteFilePath(), false);
+#endif
+ }
+ return QVariant::fromValue(icon);
+ }
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QVariant QDesignerResourceBuilder::toNativeValue(const QVariant &value) const
+{
+ if (value.canConvert<PropertySheetPixmapValue>()) {
+ if (m_pixmapCache)
+ return m_pixmapCache->pixmap(qvariant_cast<PropertySheetPixmapValue>(value));
+ } else if (value.canConvert<PropertySheetIconValue>()) {
+ if (m_iconCache)
+ return m_iconCache->icon(qvariant_cast<PropertySheetIconValue>(value));
+ }
+ return value;
+}
+
+DomProperty *QDesignerResourceBuilder::saveResource(const QDir &workingDirectory, const QVariant &value) const
+{
+ DomProperty *p = new DomProperty;
+ if (value.canConvert<PropertySheetPixmapValue>()) {
+ const PropertySheetPixmapValue pix = qvariant_cast<PropertySheetPixmapValue>(value);
+ DomResourcePixmap *rp = new DomResourcePixmap;
+ const QString pixPath = pix.path();
+ switch (pix.pixmapSource(m_core)) {
+ case PropertySheetPixmapValue::LanguageResourcePixmap:
+ rp->setText(pixPath);
+ break;
+ case PropertySheetPixmapValue::ResourcePixmap: {
+ rp->setText(pixPath);
+ const QString qrcFile = m_core->resourceModel()->qrcPath(pixPath);
+ if (!qrcFile.isEmpty()) {
+ m_usedQrcFiles.insert(qrcFile, false);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Add qrc path
+ rp->setAttributeResource(workingDirectory.relativeFilePath(qrcFile));
+#endif
+ }
+ }
+ break;
+ case PropertySheetPixmapValue::FilePixmap:
+ rp->setText(m_saveRelative ? workingDirectory.relativeFilePath(pixPath) : pixPath);
+ break;
+ }
+ p->setElementPixmap(rp);
+ return p;
+ } else if (value.canConvert<PropertySheetIconValue>()) {
+ const PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(value);
+ const QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> pixmaps = icon.paths();
+ const QString theme = icon.theme();
+ if (!pixmaps.isEmpty() || !theme.isEmpty()) {
+ DomResourceIcon *ri = new DomResourceIcon;
+ if (!theme.isEmpty())
+ ri->setAttributeTheme(theme);
+ QMapIterator<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> itPix(pixmaps);
+ while (itPix.hasNext()) {
+ const QIcon::Mode mode = itPix.next().key().first;
+ const QIcon::State state = itPix.key().second;
+ DomResourcePixmap *rp = new DomResourcePixmap;
+ const PropertySheetPixmapValue pix = itPix.value();
+ const PropertySheetPixmapValue::PixmapSource ps = pix.pixmapSource(m_core);
+ const QString pixPath = pix.path();
+ rp->setText(ps == PropertySheetPixmapValue::FilePixmap && m_saveRelative ? workingDirectory.relativeFilePath(pixPath) : pixPath);
+ if (state == QIcon::Off) {
+ switch (mode) {
+ case QIcon::Normal:
+ ri->setElementNormalOff(rp);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Set Normal off as text/path in old format.
+ ri->setText(rp->text());
+#endif
+ if (ps == PropertySheetPixmapValue::ResourcePixmap) {
+ // Be sure that ri->text() file comes from active resourceSet (i.e. make appropriate
+ // resourceSet active before calling this method).
+ const QString qrcFile = m_core->resourceModel()->qrcPath(ri->text());
+ if (!qrcFile.isEmpty()) {
+ m_usedQrcFiles.insert(qrcFile, false);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Set Normal off as text/path in old format.
+ ri->setAttributeResource(workingDirectory.relativeFilePath(qrcFile));
+#endif
+ }
+ }
+ break;
+ case QIcon::Disabled: ri->setElementDisabledOff(rp); break;
+ case QIcon::Active: ri->setElementActiveOff(rp); break;
+ case QIcon::Selected: ri->setElementSelectedOff(rp); break;
+ }
+ } else {
+ switch (mode) {
+ case QIcon::Normal: ri->setElementNormalOn(rp); break;
+ case QIcon::Disabled: ri->setElementDisabledOn(rp); break;
+ case QIcon::Active: ri->setElementActiveOn(rp); break;
+ case QIcon::Selected: ri->setElementSelectedOn(rp); break;
+ }
+ }
+ }
+ p->setElementIconSet(ri);
+ return p;
+ }
+ }
+ delete p;
+ return 0;
+}
+
+bool QDesignerResourceBuilder::isResourceType(const QVariant &value) const
+{
+ if (value.canConvert<PropertySheetPixmapValue>() || value.canConvert<PropertySheetIconValue>())
+ return true;
+ return false;
+}
+// ------------------------- QDesignerTextBuilder
+class QDesignerTextBuilder : public QTextBuilder
+{
+public:
+ QDesignerTextBuilder() {}
+
+ virtual QVariant loadText(const DomProperty *icon) const;
+
+ virtual QVariant toNativeValue(const QVariant &value) const;
+
+ virtual DomProperty *saveText(const QVariant &value) const;
+};
+
+QVariant QDesignerTextBuilder::loadText(const DomProperty *text) const
+{
+ const DomString *str = text->elementString();
+ PropertySheetStringValue strVal(str->text());
+ if (str->hasAttributeComment()) {
+ strVal.setDisambiguation(str->attributeComment());
+ }
+ if (str->hasAttributeExtraComment()) {
+ strVal.setComment(str->attributeExtraComment());
+ }
+ if (str->hasAttributeNotr()) {
+ const QString notr = str->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ strVal.setTranslatable(translatable);
+ }
+ return QVariant::fromValue(strVal);
+}
+
+QVariant QDesignerTextBuilder::toNativeValue(const QVariant &value) const
+{
+ if (value.canConvert<PropertySheetStringValue>())
+ return QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(value).value());
+ return value;
+}
+
+DomProperty *QDesignerTextBuilder::saveText(const QVariant &value) const
+{
+ if (!value.canConvert<PropertySheetStringValue>() && !value.canConvert<QString>())
+ return 0;
+
+ DomProperty *property = new DomProperty();
+ DomString *domStr = new DomString();
+
+ if (value.canConvert<PropertySheetStringValue>()) {
+ PropertySheetStringValue str = qvariant_cast<PropertySheetStringValue>(value);
+
+ domStr->setText(str.value());
+
+ const QString property_comment = str.disambiguation();
+ if (!property_comment.isEmpty())
+ domStr->setAttributeComment(property_comment);
+ const QString property_extraComment = str.comment();
+ if (!property_extraComment.isEmpty())
+ domStr->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = str.translatable();
+ if (!property_translatable)
+ domStr->setAttributeNotr(QLatin1String("true"));
+ } else {
+ domStr->setText(value.toString());
+ }
+
+ property->setElementString(domStr);
+ return property;
+}
+
+QDesignerResource::QDesignerResource(FormWindow *formWindow) :
+ QEditorFormBuilder(formWindow->core()),
+ m_formWindow(formWindow),
+ m_topLevelSpacerCount(0),
+ m_copyWidget(false),
+ m_selected(0),
+ m_resourceBuilder(new QDesignerResourceBuilder(m_formWindow->core(), m_formWindow->pixmapCache(), m_formWindow->iconCache()))
+{
+ setWorkingDirectory(formWindow->absoluteDir());
+ setResourceBuilder(m_resourceBuilder);
+ setTextBuilder(new QDesignerTextBuilder());
+
+ // ### generalise
+ const QString designerWidget = QLatin1String("QDesignerWidget");
+ const QString layoutWidget = QLatin1String("QLayoutWidget");
+ const QString widget = QLatin1String("QWidget");
+ m_internal_to_qt.insert(layoutWidget, widget);
+ m_internal_to_qt.insert(designerWidget, widget);
+ m_internal_to_qt.insert(QLatin1String("QDesignerDialog"), QLatin1String("QDialog"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerMenuBar"), QLatin1String("QMenuBar"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerMenu"), QLatin1String("QMenu"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerDockWidget"), QLatin1String("QDockWidget"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerQ3WidgetStack"), QLatin1String("Q3WidgetStack"));
+
+ // invert
+ QHash<QString, QString>::const_iterator cend = m_internal_to_qt.constEnd();
+ for (QHash<QString, QString>::const_iterator it = m_internal_to_qt.constBegin();it != cend; ++it ) {
+ if (it.value() != designerWidget && it.value() != layoutWidget)
+ m_qt_to_internal.insert(it.value(), it.key());
+
+ }
+}
+
+QDesignerResource::~QDesignerResource()
+{
+}
+
+static inline QString messageBoxTitle()
+{
+ return QApplication::translate("Designer", "Qt Designer");
+}
+
+void QDesignerResource::save(QIODevice *dev, QWidget *widget)
+{
+ m_topLevelSpacerCount = 0;
+
+ QAbstractFormBuilder::save(dev, widget);
+
+ if (QSimpleResource::warningsEnabled() && m_topLevelSpacerCount != 0) {
+ const QString message = QApplication::translate("Designer", "This file contains top level spacers.<br>"
+ "They have <b>NOT</b> been saved into the form.");
+ const QString infoMessage = QApplication::translate("Designer", "Perhaps you forgot to create a layout?");
+
+ core()->dialogGui()->message(widget->window(), QDesignerDialogGuiInterface::TopLevelSpacerMessage,
+ QMessageBox::Warning, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ }
+}
+
+void QDesignerResource::saveDom(DomUI *ui, QWidget *widget)
+{
+ QAbstractFormBuilder::saveDom(ui, widget);
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ Q_ASSERT(sheet != 0);
+
+ const QVariant classVar = sheet->property(sheet->indexOf(QLatin1String("objectName")));
+ QString classStr;
+ if (classVar.canConvert(QVariant::String))
+ classStr = classVar.toString();
+ else
+ classStr = qvariant_cast<PropertySheetStringValue>(classVar).value();
+ ui->setElementClass(classStr);
+
+ for (int index = 0; index < m_formWindow->toolCount(); ++index) {
+ QDesignerFormWindowToolInterface *tool = m_formWindow->tool(index);
+ Q_ASSERT(tool != 0);
+ tool->saveToDom(ui, widget);
+ }
+
+ const QString author = m_formWindow->author();
+ if (!author.isEmpty()) {
+ ui->setElementAuthor(author);
+ }
+
+ const QString comment = m_formWindow->comment();
+ if (!comment.isEmpty()) {
+ ui->setElementComment(comment);
+ }
+
+ const QString exportMacro = m_formWindow->exportMacro();
+ if (!exportMacro.isEmpty()) {
+ ui->setElementExportMacro(exportMacro);
+ }
+
+ const QVariantMap designerFormData = m_formWindow->formData();
+ if (!designerFormData.empty()) {
+ DomPropertyList domPropertyList;
+ const QVariantMap::const_iterator cend = designerFormData.constEnd();
+ for (QVariantMap::const_iterator it = designerFormData.constBegin(); it != cend; ++it) {
+ if (DomProperty *prop = variantToDomProperty(this, widget->metaObject(), it.key(), it.value()))
+ domPropertyList += prop;
+ }
+ if (!domPropertyList.empty()) {
+ DomDesignerData* domDesignerFormData = new DomDesignerData;
+ domDesignerFormData->setElementProperty(domPropertyList);
+ ui->setElementDesignerdata(domDesignerFormData);
+ }
+ }
+
+ if (!m_formWindow->includeHints().isEmpty()) {
+ const QString local = QLatin1String("local");
+ const QString global = QLatin1String("global");
+ QList<DomInclude*> ui_includes;
+ foreach (QString includeHint, m_formWindow->includeHints()) {
+ if (includeHint.isEmpty())
+ continue;
+ DomInclude *incl = new DomInclude;
+ const QString location = includeHint.at(0) == QLatin1Char('<') ? global : local;
+ includeHint.remove(QLatin1Char('"'));
+ includeHint.remove(QLatin1Char('<'));
+ includeHint.remove(QLatin1Char('>'));
+ incl->setAttributeLocation(location);
+ incl->setText(includeHint);
+ ui_includes.append(incl);
+ }
+
+ DomIncludes *includes = new DomIncludes;
+ includes->setElementInclude(ui_includes);
+ ui->setElementIncludes(includes);
+ }
+
+ int defaultMargin = INT_MIN, defaultSpacing = INT_MIN;
+ m_formWindow->layoutDefault(&defaultMargin, &defaultSpacing);
+
+ if (defaultMargin != INT_MIN || defaultSpacing != INT_MIN) {
+ DomLayoutDefault *def = new DomLayoutDefault;
+ if (defaultMargin != INT_MIN)
+ def->setAttributeMargin(defaultMargin);
+ if (defaultSpacing != INT_MIN)
+ def->setAttributeSpacing(defaultSpacing);
+ ui->setElementLayoutDefault(def);
+ }
+
+ QString marginFunction, spacingFunction;
+ m_formWindow->layoutFunction(&marginFunction, &spacingFunction);
+ if (!marginFunction.isEmpty() || !spacingFunction.isEmpty()) {
+ DomLayoutFunction *def = new DomLayoutFunction;
+
+ if (!marginFunction.isEmpty())
+ def->setAttributeMargin(marginFunction);
+ if (!spacingFunction.isEmpty())
+ def->setAttributeSpacing(spacingFunction);
+ ui->setElementLayoutFunction(def);
+ }
+
+ QString pixFunction = m_formWindow->pixmapFunction();
+ if (!pixFunction.isEmpty()) {
+ ui->setElementPixmapFunction(pixFunction);
+ }
+
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core()))
+ extra->saveUiExtraInfo(ui);
+
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ const MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(m_formWindow->mainContainer());
+ const QStringList fakeSlots = item->fakeSlots();
+ const QStringList fakeSignals =item->fakeSignals();
+ if (!fakeSlots.empty() || !fakeSignals.empty()) {
+ DomSlots *domSlots = new DomSlots();
+ domSlots->setElementSlot(fakeSlots);
+ domSlots->setElementSignal(fakeSignals);
+ ui->setElementSlots(domSlots);
+ }
+ }
+}
+
+namespace {
+ enum LoadPreCheck { LoadPreCheckFailed, LoadPreCheckVersion3, LoadPreCheckVersionMismatch, LoadPreCheckOk };
+ // Pair of major, minor
+ typedef QPair<int, int> UiVersion;
+}
+
+static UiVersion uiVersion(const QString &attr)
+{
+ const QStringList versions = attr.split(QLatin1Char('.'));
+ if (versions.empty())
+ return UiVersion(-1, -1);
+
+ bool ok = false;
+ UiVersion rc(versions.at(0).toInt(&ok), 0);
+
+ if (!ok)
+ return UiVersion(-1, -1);
+
+ if (versions.size() > 1) {
+ const int minorVersion = versions.at(1).toInt(&ok);
+ if (ok)
+ rc.second = minorVersion;
+ }
+ return rc;
+}
+
+// Read version and language attributes of an <UI> element.
+static bool readUiAttributes(QIODevice *dev, QString *errorMessage,
+ QString *version,
+ QString *language)
+{
+ const QString uiElement = QLatin1String("ui");
+ const QString versionAttribute = QLatin1String("version");
+ const QString languageAttribute = QLatin1String("language");
+ QXmlStreamReader reader(dev);
+ // Read up to first element
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ const QStringRef tag = reader.name();
+ if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0) {
+ const QXmlStreamAttributes attributes = reader.attributes();
+ if (attributes.hasAttribute(versionAttribute))
+ *version = attributes.value(versionAttribute).toString();
+ if (attributes.hasAttribute(languageAttribute))
+ *language = attributes.value(languageAttribute).toString();
+ return true;
+ } else {
+ *errorMessage = QCoreApplication::translate("Designer", "Invalid UI file: The root element <ui> is missing.");
+ return false;
+
+ }
+ }
+ }
+ *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the UI file at line %1, column %2: %3")
+ .arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString());
+ return false;
+}
+
+// While loading a file, check language, version and extra extension
+static LoadPreCheck loadPrecheck(QDesignerFormEditorInterface *core,
+ QIODevice *dev,
+ QString *errorMessage, QString *versionString)
+{
+ QString language;
+ // Read attributes of <ui> and rewind
+ if (!readUiAttributes(dev, errorMessage, versionString, &language)) {
+ // XML error: Mimick the behaviour occurring if an XML error is
+ // detected later on, report to warning log and have embedding
+ // application display a dialog.
+ designerWarning(*errorMessage);
+ errorMessage->clear();
+ return LoadPreCheckFailed;
+ }
+ dev->seek(0);
+
+ // Check language unless extension present (Jambi)
+ if (!language.isEmpty() && !qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core)) {
+ if (language.toLower() != QLatin1String("c++")) {
+ // Jambi?!
+ *errorMessage = QApplication::translate("Designer", "This file cannot be read because it was created using %1.").arg(language);
+ return LoadPreCheckFailed;
+ }
+ }
+
+ // Version
+ if (!versionString->isEmpty()) {
+ const UiVersion version = uiVersion(*versionString);
+ switch (version.first) {
+ case 3:
+ return LoadPreCheckVersion3;
+ case 4:
+ break;
+ default:
+ *errorMessage = QApplication::translate("Designer", "This file was created using Designer from Qt-%1 and cannot be read.").arg(*versionString);
+ return LoadPreCheckVersionMismatch;
+ }
+ }
+ return LoadPreCheckOk;
+}
+
+QWidget *QDesignerResource::load(QIODevice *dev, QWidget *parentWidget)
+{
+ // Run loadPreCheck for version and language
+ QString errorMessage;
+ QString version;
+ switch (loadPrecheck(core(), dev, &errorMessage, &version)) {
+ case LoadPreCheckFailed:
+ case LoadPreCheckVersionMismatch:
+ if (!errorMessage.isEmpty())
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), errorMessage, QMessageBox::Ok);
+ return 0;
+ case LoadPreCheckVersion3: {
+ QWidget *w = 0;
+ QByteArray ba;
+ if (runUIC( m_formWindow->fileName(), UIC_ConvertV3, ba, errorMessage)) {
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::ReadOnly);
+ w = load(&buffer, parentWidget);
+ if (w) {
+ // Force the form to pop up a save file dialog
+ m_formWindow->setFileName(QString());
+ } else {
+ errorMessage = QApplication::translate("Designer", "The converted file could not be read.");
+ }
+ }
+ if (w) {
+ const QString message = QApplication::translate("Designer",
+ "This file was created using Designer from Qt-%1 and"
+ " will be converted to a new form by Qt Designer.").arg(version);
+ const QString infoMessage = QApplication::translate("Designer",
+ "The old form has not been touched, but you will have to save the form"
+ " under a new name.");
+
+ core()->dialogGui()->message(parentWidget->window(),
+ QDesignerDialogGuiInterface::UiVersionMismatchMessage,
+ QMessageBox::Information, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ return w;
+ }
+
+ const QString message = QApplication::translate("Designer",
+ "This file was created using Designer from Qt-%1 and "
+ "could not be read:\n%2").arg(version).arg(errorMessage);
+ const QString infoMessage = QApplication::translate("Designer",
+ "Please run it through <b>uic3&nbsp;-convert</b> to convert "
+ "it to Qt-4's ui format.");
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ return 0;
+ }
+
+ case LoadPreCheckOk:
+ break;
+ }
+ QWidget *w = QEditorFormBuilder::load(dev, parentWidget);
+ if (w) // Store the class name as 'reset' value for the main container's object name.
+ w->setProperty("_q_classname", w->objectName());
+ return w;
+}
+
+bool QDesignerResource::saveRelative() const
+{
+ return m_resourceBuilder->isSaveRelative();
+}
+
+void QDesignerResource::setSaveRelative(bool relative)
+{
+ m_resourceBuilder->setSaveRelative(relative);
+}
+
+QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget)
+{
+ // Load extra info extension. This is used by Jambi for preventing
+ // C++ UI files from being loaded
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core())) {
+ if (!extra->loadUiExtraInfo(ui)) {
+ const QString errorMessage = QApplication::translate("Designer", "This file cannot be read because the extra info extension failed to load.");
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), errorMessage, QMessageBox::Ok);
+ return 0;
+ }
+ }
+
+ qdesigner_internal::WidgetFactory *factory = qobject_cast<qdesigner_internal::WidgetFactory*>(core()->widgetFactory());
+ Q_ASSERT(factory != 0);
+
+ QDesignerFormWindowInterface *previousFormWindow = factory->currentFormWindow(m_formWindow);
+
+ m_isMainWidget = true;
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ QWidget *mainWidget = QAbstractFormBuilder::create(ui, parentWidget);
+
+ if (mainWidget && m_formWindow) {
+ m_formWindow->setAuthor(ui->elementAuthor());
+ m_formWindow->setComment(ui->elementComment());
+ m_formWindow->setExportMacro(ui->elementExportMacro());
+
+ // Designer data
+ QVariantMap designerFormData;
+ if (ui->hasElementDesignerdata()) {
+ const DomPropertyList domPropertyList = ui->elementDesignerdata()->elementProperty();
+ const DomPropertyList::const_iterator cend = domPropertyList.constEnd();
+ for (DomPropertyList::const_iterator it = domPropertyList.constBegin(); it != cend; ++it) {
+ const QVariant vprop = domPropertyToVariant(this, mainWidget->metaObject(), *it);
+ if (vprop.type() != QVariant::Invalid)
+ designerFormData.insert((*it)->attributeName(), vprop);
+ }
+ }
+ m_formWindow->setFormData(designerFormData);
+
+ m_formWindow->setPixmapFunction(ui->elementPixmapFunction());
+
+ if (DomLayoutDefault *def = ui->elementLayoutDefault()) {
+ m_formWindow->setLayoutDefault(def->attributeMargin(), def->attributeSpacing());
+ }
+
+ if (DomLayoutFunction *fun = ui->elementLayoutFunction()) {
+ m_formWindow->setLayoutFunction(fun->attributeMargin(), fun->attributeSpacing());
+ }
+
+ if (DomIncludes *includes = ui->elementIncludes()) {
+ const QString global = QLatin1String("global");
+ QStringList includeHints;
+ foreach (DomInclude *incl, includes->elementInclude()) {
+ QString text = incl->text();
+
+ if (text.isEmpty())
+ continue;
+
+ if (incl->hasAttributeLocation() && incl->attributeLocation() == global ) {
+ text = text.prepend(QLatin1Char('<')).append(QLatin1Char('>'));
+ } else {
+ text = text.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
+ }
+
+ includeHints.append(text);
+ }
+
+ m_formWindow->setIncludeHints(includeHints);
+ }
+
+ // Register all button groups the form builder adds as children of the main container for them to be found
+ // in the signal slot editor
+ const QObjectList mchildren = mainWidget->children();
+ if (!mchildren.empty()) {
+ QDesignerMetaDataBaseInterface *mdb = core()->metaDataBase();
+ const QObjectList::const_iterator cend = mchildren.constEnd();
+ for (QObjectList::const_iterator it = mchildren.constBegin(); it != cend; ++it)
+ if (QButtonGroup *bg = qobject_cast<QButtonGroup*>(*it))
+ mdb->add(bg);
+ }
+ // Load tools
+ for (int index = 0; index < m_formWindow->toolCount(); ++index) {
+ QDesignerFormWindowToolInterface *tool = m_formWindow->tool(index);
+ Q_ASSERT(tool != 0);
+ tool->loadFromDom(ui, mainWidget);
+ }
+ }
+
+ factory->currentFormWindow(previousFormWindow);
+
+ if (const DomSlots *domSlots = ui->elementSlots()) {
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ QStringList fakeSlots;
+ QStringList fakeSignals;
+ if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) {
+ MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(mainWidget);
+ item->setFakeSlots(fakeSlots);
+ item->setFakeSignals(fakeSignals);
+ }
+ }
+ }
+ if (mainWidget) {
+ // Initialize the mainwindow geometry. Has it been explicitly specified?
+ bool hasExplicitGeometry = false;
+ const QList<DomProperty *> properties = ui->elementWidget()->elementProperty();
+ if (!properties.empty()) {
+ const QString geometry = QLatin1String("geometry");
+ foreach (const DomProperty *p, properties)
+ if (p->attributeName() == geometry) {
+ hasExplicitGeometry = true;
+ break;
+ }
+ }
+ if (hasExplicitGeometry) {
+ // Geometry was specified explicitly: Verify that smartMinSize is respected
+ // (changed fonts, label wrapping policies, etc). This does not happen automatically in docked mode.
+ const QSize size = mainWidget->size();
+ const QSize minSize = size.expandedTo(qSmartMinSize(mainWidget));
+ if (minSize != size)
+ mainWidget->resize(minSize);
+ } else {
+ // No explicit Geometry: perform an adjustSize() to resize the form correctly before embedding it into a container
+ // (which might otherwise squeeze the form)
+ mainWidget->adjustSize();
+ }
+ // Some integration wizards create forms with main containers
+ // based on derived classes of QWidget and load them into Designer
+ // without the plugin existing. This will trigger the auto-promotion
+ // mechanism of Designer, which will set container=false for
+ // QWidgets. For the main container, force container=true and warn.
+ const QDesignerWidgetDataBaseInterface *wdb = core()->widgetDataBase();
+ const int wdbIndex = wdb->indexOfObject(mainWidget);
+ if (wdbIndex != -1) {
+ QDesignerWidgetDataBaseItemInterface *item = wdb->item(wdbIndex);
+ // Promoted main container that is not of container type
+ if (item->isPromoted() && !item->isContainer()) {
+ item->setContainer(true);
+ qWarning("** WARNING The form's main container is an unknown custom widget '%s'."
+ " Defaulting to a promoted instance of '%s', assuming container.",
+ item->name().toUtf8().constData(), item->extends().toUtf8().constData());
+ }
+ }
+ }
+ return mainWidget;
+}
+
+QWidget *QDesignerResource::create(DomWidget *ui_widget, QWidget *parentWidget)
+{
+ const QString className = ui_widget->attributeClass();
+ if (!m_isMainWidget && className == QLatin1String("QWidget") && ui_widget->elementLayout().size() &&
+ !ui_widget->hasAttributeNative()) {
+ // ### check if elementLayout.size() == 1
+
+ QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget);
+
+ if (container == 0) {
+ // generate a QLayoutWidget iff the parent is not an QDesignerContainerExtension.
+ ui_widget->setAttributeClass(QLatin1String("QLayoutWidget"));
+ }
+ }
+
+ // save the actions
+ const QList<DomActionRef*> actionRefs = ui_widget->elementAddAction();
+ ui_widget->setElementAddAction(QList<DomActionRef*>());
+
+ QWidget *w = QAbstractFormBuilder::create(ui_widget, parentWidget);
+
+ // restore the actions
+ ui_widget->setElementAddAction(actionRefs);
+
+ if (w == 0)
+ return 0;
+
+ // ### generalize using the extension manager
+ QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(w);
+ QDesignerMenuBar *menuBar = qobject_cast<QDesignerMenuBar*>(w);
+
+ if (menu) {
+ menu->interactive(false);
+ menu->hide();
+ } else if (menuBar) {
+ menuBar->interactive(false);
+ }
+
+ foreach (DomActionRef *ui_action_ref, actionRefs) {
+ const QString name = ui_action_ref->attributeName();
+ if (name == QLatin1String("separator")) {
+ QAction *sep = new QAction(w);
+ sep->setSeparator(true);
+ w->addAction(sep);
+ addMenuAction(sep);
+ } else if (QAction *a = m_actions.value(name)) {
+ w->addAction(a);
+ } else if (QActionGroup *g = m_actionGroups.value(name)) {
+ w->addActions(g->actions());
+ } else if (QMenu *menu = w->findChild<QMenu*>(name)) {
+ w->addAction(menu->menuAction());
+ addMenuAction(menu->menuAction());
+ }
+ }
+
+ if (menu) {
+ menu->interactive(true);
+ menu->adjustSpecialActions();
+ } else if (menuBar) {
+ menuBar->interactive(true);
+ menuBar->adjustSpecialActions();
+ }
+
+ ui_widget->setAttributeClass(className); // fix the class name
+ applyExtensionDataFromDOM(this, core(), ui_widget, w, true);
+
+ // store user-defined scripts
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ const QString designerSource = QLatin1String("designer");
+ const DomScripts domScripts = ui_widget->elementScript();
+ if (!domScripts.empty()) {
+ foreach (const DomScript *script, domScripts) {
+ if (script->hasAttributeSource() && script->attributeSource() == designerSource) {
+ metaDataBase->metaDataBaseItem(w)->setScript(script->text());
+ }
+ }
+ }
+ }
+
+ return w;
+}
+
+QLayout *QDesignerResource::create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget)
+{
+ QLayout *l = QAbstractFormBuilder::create(ui_layout, layout, parentWidget);
+
+ if (QGridLayout *gridLayout = qobject_cast<QGridLayout*>(l)) {
+ QLayoutSupport::createEmptyCells(gridLayout);
+ } else {
+ if (QFormLayout *formLayout = qobject_cast<QFormLayout*>(l))
+ QLayoutSupport::createEmptyCells(formLayout);
+ }
+ // While the actual values are applied by the form builder, we still need
+ // to mark them as 'changed'.
+ LayoutPropertySheet::markChangedStretchProperties(core(), l, ui_layout);
+ return l;
+}
+
+QLayoutItem *QDesignerResource::create(DomLayoutItem *ui_layoutItem, QLayout *layout, QWidget *parentWidget)
+{
+ if (ui_layoutItem->kind() == DomLayoutItem::Spacer) {
+ const DomSpacer *domSpacer = ui_layoutItem->elementSpacer();
+ const QHash<QString, DomProperty*> properties = propertyMap(domSpacer->elementProperty());
+ Spacer *spacer = static_cast<Spacer*>(core()->widgetFactory()->createWidget(QLatin1String("Spacer"), parentWidget));
+ if (domSpacer->hasAttributeName())
+ changeObjectName(spacer, domSpacer->attributeName());
+ core()->metaDataBase()->add(spacer);
+
+ spacer->setInteractiveMode(false);
+ applyProperties(spacer, ui_layoutItem->elementSpacer()->elementProperty());
+ spacer->setInteractiveMode(true);
+
+ if (m_formWindow) {
+ m_formWindow->manageWidget(spacer);
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), spacer))
+ sheet->setChanged(sheet->indexOf(QLatin1String("orientation")), true);
+ }
+
+ return new QWidgetItem(spacer);
+ } else if (ui_layoutItem->kind() == DomLayoutItem::Layout && parentWidget) {
+ DomLayout *ui_layout = ui_layoutItem->elementLayout();
+ QLayoutWidget *layoutWidget = new QLayoutWidget(m_formWindow, parentWidget);
+ core()->metaDataBase()->add(layoutWidget);
+ if (m_formWindow)
+ m_formWindow->manageWidget(layoutWidget);
+ (void) create(ui_layout, 0, layoutWidget);
+ return new QWidgetItem(layoutWidget);
+ }
+ return QAbstractFormBuilder::create(ui_layoutItem, layout, parentWidget);
+}
+
+void QDesignerResource::changeObjectName(QObject *o, QString objName)
+{
+ m_formWindow->unify(o, objName, true);
+ o->setObjectName(objName);
+
+}
+
+/* If the property is a enum or flag value, retrieve
+ * the existing enum/flag via property sheet and use it to convert */
+
+static bool readDomEnumerationValue(const DomProperty *p,
+ const QDesignerPropertySheetExtension* sheet, int index,
+ QVariant &v)
+{
+ switch (p->kind()) {
+ case DomProperty::Set: {
+ const QVariant sheetValue = sheet->property(index);
+ if (sheetValue.canConvert<PropertySheetFlagValue>()) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(sheetValue);
+ bool ok = false;
+ v = f.metaFlags.parseFlags(p->elementSet(), &ok);
+ if (!ok)
+ designerWarning(f.metaFlags.messageParseFailed(p->elementSet()));
+ return true;
+ }
+ }
+ break;
+ case DomProperty::Enum: {
+ const QVariant sheetValue = sheet->property(index);
+ if (sheetValue.canConvert<PropertySheetEnumValue>()) {
+ const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(sheetValue);
+ bool ok = false;
+ v = e.metaEnum.parseEnum(p->elementEnum(), &ok);
+ if (!ok)
+ designerWarning(e.metaEnum.messageParseFailed(p->elementEnum()));
+ return true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void QDesignerResource::applyProperties(QObject *o, const QList<DomProperty*> &properties)
+{
+ if (properties.empty())
+ return;
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), o);
+ if (!sheet)
+ return;
+
+ QFormBuilderExtra *formBuilderExtra = QFormBuilderExtra::instance(this);
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), o);
+ const bool dynamicPropertiesAllowed = dynamicSheet && dynamicSheet->dynamicPropertiesAllowed();
+
+ const QString objectNameProperty = QLatin1String("objectName");
+ const DomPropertyList::const_iterator cend = properties.constEnd();
+ for (DomPropertyList::const_iterator it = properties.constBegin(); it != cend; ++it) {
+ const DomProperty *p = *it;
+ const QString propertyName = p->attributeName();
+ const int index = sheet->indexOf(propertyName);
+ QVariant v;
+ if (!readDomEnumerationValue(p, sheet, index, v))
+ v = toVariant(o->metaObject(), *it);
+
+ if (p->kind() == DomProperty::String) {
+ if (index != -1 && sheet->property(index).userType() == qMetaTypeId<PropertySheetKeySequenceValue>()) {
+ const DomString *key = p->elementString();
+ PropertySheetKeySequenceValue keyVal(QKeySequence(key->text()));
+ if (key->hasAttributeComment())
+ keyVal.setDisambiguation(key->attributeComment());
+ if (key->hasAttributeExtraComment())
+ keyVal.setComment(key->attributeExtraComment());
+ if (key->hasAttributeNotr()) {
+ const QString notr = key->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ keyVal.setTranslatable(translatable);
+ }
+ v = QVariant::fromValue(keyVal);
+ } else {
+ const DomString *str = p->elementString();
+ PropertySheetStringValue strVal(v.toString());
+ if (str->hasAttributeComment())
+ strVal.setDisambiguation(str->attributeComment());
+ if (str->hasAttributeExtraComment())
+ strVal.setComment(str->attributeExtraComment());
+ if (str->hasAttributeNotr()) {
+ const QString notr = str->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ strVal.setTranslatable(translatable);
+ }
+ v = QVariant::fromValue(strVal);
+ }
+ }
+
+ formBuilderExtra->applyPropertyInternally(o, propertyName, v);
+ if (index != -1) {
+ sheet->setProperty(index, v);
+ sheet->setChanged(index, true);
+ } else if (dynamicPropertiesAllowed) {
+ QVariant defaultValue = QVariant(v.type());
+ bool isDefault = (v == defaultValue);
+ if (v.canConvert<PropertySheetIconValue>()) {
+ defaultValue = QVariant(QVariant::Icon);
+ isDefault = (qvariant_cast<PropertySheetIconValue>(v) == PropertySheetIconValue());
+ } else if (v.canConvert<PropertySheetPixmapValue>()) {
+ defaultValue = QVariant(QVariant::Pixmap);
+ isDefault = (qvariant_cast<PropertySheetPixmapValue>(v) == PropertySheetPixmapValue());
+ } else if (v.canConvert<PropertySheetStringValue>()) {
+ defaultValue = QVariant(QVariant::String);
+ isDefault = (qvariant_cast<PropertySheetStringValue>(v) == PropertySheetStringValue());
+ } else if (v.canConvert<PropertySheetKeySequenceValue>()) {
+ defaultValue = QVariant(QVariant::KeySequence);
+ isDefault = (qvariant_cast<PropertySheetKeySequenceValue>(v) == PropertySheetKeySequenceValue());
+ }
+ if (defaultValue.type() != QVariant::UserType) {
+ const int idx = dynamicSheet->addDynamicProperty(p->attributeName(), defaultValue);
+ if (idx != -1) {
+ sheet->setProperty(idx, v);
+ sheet->setChanged(idx, !isDefault);
+ }
+ }
+ }
+
+ if (propertyName == objectNameProperty)
+ changeObjectName(o, o->objectName());
+ }
+}
+
+QWidget *QDesignerResource::createWidget(const QString &widgetName, QWidget *parentWidget, const QString &_name)
+{
+ QString name = _name;
+ QString className = widgetName;
+ if (m_isMainWidget)
+ m_isMainWidget = false;
+
+ QWidget *w = core()->widgetFactory()->createWidget(className, parentWidget);
+ if (!w)
+ return 0;
+
+ if (name.isEmpty()) {
+ QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
+ if (QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(w)))
+ name = qtify(item->name());
+ }
+
+ changeObjectName(w, name);
+
+ QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget);
+ if (!qobject_cast<QMenu*>(w) && (!parentWidget || !container)) {
+ m_formWindow->manageWidget(w);
+ if (parentWidget) {
+ QList<QWidget *> list = qvariant_cast<QWidgetList>(parentWidget->property("_q_widgetOrder"));
+ list.append(w);
+ parentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(list));
+ QList<QWidget *> zOrder = qvariant_cast<QWidgetList>(parentWidget->property("_q_zOrder"));
+ zOrder.append(w);
+ parentWidget->setProperty("_q_zOrder", QVariant::fromValue(zOrder));
+ }
+ } else {
+ core()->metaDataBase()->add(w);
+ }
+
+ w->setWindowFlags(w->windowFlags() & ~Qt::Window);
+ // Make sure it is non-modal (for example, KDialog calls setModal(true) in the constructor).
+ w->setWindowModality(Qt::NonModal);
+
+ return w;
+}
+
+QLayout *QDesignerResource::createLayout(const QString &layoutName, QObject *parent, const QString &name)
+{
+ QWidget *layoutBase = 0;
+ QLayout *layout = qobject_cast<QLayout*>(parent);
+
+ if (parent->isWidgetType())
+ layoutBase = static_cast<QWidget*>(parent);
+ else {
+ Q_ASSERT( layout != 0 );
+ layoutBase = layout->parentWidget();
+ }
+
+ LayoutInfo::Type layoutType = LayoutInfo::layoutType(layoutName);
+ if (layoutType == LayoutInfo::NoLayout) {
+ designerWarning(QCoreApplication::translate("QDesignerResource", "The layout type '%1' is not supported, defaulting to grid.").arg(layoutName));
+ layoutType = LayoutInfo::Grid;
+ }
+ QLayout *lay = core()->widgetFactory()->createLayout(layoutBase, layout, layoutType);
+ if (lay != 0)
+ changeObjectName(lay, name);
+
+ return lay;
+}
+
+// save
+DomWidget *QDesignerResource::createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive)
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(widget);
+ if (!item)
+ return 0;
+
+ if (qobject_cast<Spacer*>(widget) && m_copyWidget == false) {
+ ++m_topLevelSpacerCount;
+ return 0;
+ }
+
+ const QDesignerWidgetDataBaseInterface *wdb = core()->widgetDataBase();
+ QDesignerWidgetDataBaseItemInterface *widgetInfo = 0;
+ const int widgetInfoIndex = wdb->indexOfObject(widget, false);
+ if (widgetInfoIndex != -1) {
+ widgetInfo = wdb->item(widgetInfoIndex);
+ // Recursively add all dependent custom widgets
+ QDesignerWidgetDataBaseItemInterface *customInfo = widgetInfo;
+ while (customInfo && customInfo->isCustom()) {
+ m_usedCustomWidgets.insert(customInfo, true);
+ const QString extends = customInfo->extends();
+ if (extends == customInfo->name()) {
+ break; // There are faulty files around that have name==extends
+ } else {
+ const int extendsIndex = wdb->indexOfClassName(customInfo->extends());
+ customInfo = extendsIndex != -1 ? wdb->item(extendsIndex) : static_cast<QDesignerWidgetDataBaseItemInterface *>(0);
+ }
+ }
+ }
+
+ DomWidget *w = 0;
+
+ if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(widget))
+ w = saveWidget(tabWidget, ui_parentWidget);
+ else if (QStackedWidget *stackedWidget = qobject_cast<QStackedWidget*>(widget))
+ w = saveWidget(stackedWidget, ui_parentWidget);
+ else if (QToolBox *toolBox = qobject_cast<QToolBox*>(widget))
+ w = saveWidget(toolBox, ui_parentWidget);
+ else if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget))
+ w = saveWidget(toolBar, ui_parentWidget);
+ else if (QDesignerDockWidget *dockWidget = qobject_cast<QDesignerDockWidget*>(widget))
+ w = saveWidget(dockWidget, ui_parentWidget);
+ else if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget))
+ w = saveWidget(widget, container, ui_parentWidget);
+ else if (QWizardPage *wizardPage = qobject_cast<QWizardPage*>(widget))
+ w = saveWidget(wizardPage, ui_parentWidget);
+ else
+ w = QAbstractFormBuilder::createDom(widget, ui_parentWidget, recursive);
+
+ Q_ASSERT( w != 0 );
+
+ if (!qobject_cast<QLayoutWidget*>(widget) && w->attributeClass() == QLatin1String("QWidget")) {
+ w->setAttributeNative(true);
+ }
+
+ const QString className = w->attributeClass();
+ if (m_internal_to_qt.contains(className))
+ w->setAttributeClass(m_internal_to_qt.value(className));
+
+ w->setAttributeName(widget->objectName());
+
+ if (isPromoted( core(), widget)) { // is promoted?
+ Q_ASSERT(widgetInfo != 0);
+
+ w->setAttributeName(widget->objectName());
+ w->setAttributeClass(widgetInfo->name());
+
+ QList<DomProperty*> prop_list = w->elementProperty();
+ foreach (DomProperty *prop, prop_list) {
+ if (prop->attributeName() == QLatin1String("geometry")) {
+ if (DomRect *rect = prop->elementRect()) {
+ rect->setElementX(widget->x());
+ rect->setElementY(widget->y());
+ }
+ break;
+ }
+ }
+ } else if (widgetInfo != 0 && m_usedCustomWidgets.contains(widgetInfo)) {
+ if (widgetInfo->name() != w->attributeClass())
+ w->setAttributeClass(widgetInfo->name());
+ }
+ addExtensionDataToDOM(this, core(), w, widget);
+
+ addUserDefinedScripts(widget, w);
+ return w;
+}
+
+DomLayout *QDesignerResource::createDom(QLayout *layout, DomLayout *ui_parentLayout, DomWidget *ui_parentWidget)
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(layout);
+
+ if (item == 0) {
+ layout = layout->findChild<QLayout*>();
+ // refresh the meta database item
+ item = core()->metaDataBase()->item(layout);
+ }
+
+ if (item == 0) {
+ // nothing to do.
+ return 0;
+ }
+
+ if (qobject_cast<QSplitter*>(layout->parentWidget()) != 0) {
+ // nothing to do.
+ return 0;
+ }
+
+ m_chain.push(layout);
+
+ DomLayout *l = QAbstractFormBuilder::createDom(layout, ui_parentLayout, ui_parentWidget);
+ Q_ASSERT(l != 0);
+ LayoutPropertySheet::stretchAttributesToDom(core(), layout, l);
+
+ m_chain.pop();
+
+ return l;
+}
+
+DomLayoutItem *QDesignerResource::createDom(QLayoutItem *item, DomLayout *ui_layout, DomWidget *ui_parentWidget)
+{
+ DomLayoutItem *ui_item = 0;
+
+ if (Spacer *s = qobject_cast<Spacer*>(item->widget())) {
+ if (!core()->metaDataBase()->item(s))
+ return 0;
+
+ DomSpacer *spacer = new DomSpacer();
+ const QString objectName = s->objectName();
+ if (!objectName.isEmpty())
+ spacer->setAttributeName(objectName);
+ const QList<DomProperty*> properties = computeProperties(item->widget());
+ // ### filter the properties
+ spacer->setElementProperty(properties);
+
+ ui_item = new DomLayoutItem();
+ ui_item->setElementSpacer(spacer);
+ m_laidout.insert(item->widget(), true);
+ } else if (QLayoutWidget *layoutWidget = qobject_cast<QLayoutWidget*>(item->widget())) {
+ // Do not save a QLayoutWidget if it is within a layout (else it is saved as "QWidget"
+ Q_ASSERT(layoutWidget->layout());
+ DomLayout *l = createDom(layoutWidget->layout(), ui_layout, ui_parentWidget);
+ ui_item = new DomLayoutItem();
+ ui_item->setElementLayout(l);
+ m_laidout.insert(item->widget(), true);
+ } else if (!item->spacerItem()) { // we use spacer as fake item in the Designer
+ ui_item = QAbstractFormBuilder::createDom(item, ui_layout, ui_parentWidget);
+ } else {
+ return 0;
+ }
+ return ui_item;
+}
+
+void QDesignerResource::createCustomWidgets(DomCustomWidgets *dom_custom_widgets)
+{
+ QSimpleResource::handleDomCustomWidgets(core(), dom_custom_widgets);
+}
+
+DomTabStops *QDesignerResource::saveTabStops()
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(m_formWindow);
+ Q_ASSERT(item);
+
+ QStringList tabStops;
+ foreach (QWidget *widget, item->tabOrder()) {
+ if (m_formWindow->mainContainer()->isAncestorOf(widget))
+ tabStops.append(widget->objectName());
+ }
+
+ if (tabStops.count()) {
+ DomTabStops *dom = new DomTabStops;
+ dom->setElementTabStop(tabStops);
+ return dom;
+ }
+
+ return 0;
+}
+
+void QDesignerResource::applyTabStops(QWidget *widget, DomTabStops *tabStops)
+{
+ if (!tabStops)
+ return;
+
+ QList<QWidget*> tabOrder;
+ foreach (const QString &widgetName, tabStops->elementTabStop()) {
+ if (QWidget *w = widget->findChild<QWidget*>(widgetName)) {
+ tabOrder.append(w);
+ }
+ }
+
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(m_formWindow);
+ Q_ASSERT(item);
+ item->setTabOrder(tabOrder);
+}
+
+/* Unmanaged container pages occur when someone adds a page in a custom widget
+ * constructor. They don't have a meta DB entry which causes createDom
+ * to return 0. */
+inline QString msgUnmanagedPage(QDesignerFormEditorInterface *core,
+ QWidget *container, int index, QWidget *page)
+{
+ return QCoreApplication::translate("QDesignerResource",
+"The container extension of the widget '%1' (%2) returned a widget not managed by Designer '%3' (%4) when queried for page #%5.\n"
+"Container pages should only be added by specifying them in XML returned by the domXml() method of the custom widget.").
+ arg(container->objectName(), WidgetFactory::classNameOf(core, container),
+ page->objectName(), WidgetFactory::classNameOf(core, page)).
+ arg(index);
+}
+
+DomWidget *QDesignerResource::saveWidget(QWidget *widget, QDesignerContainerExtension *container, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ if (DomWidget *ui_page = createDom(page, ui_widget)) {
+ ui_widget_list.append(ui_page);
+ } else {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ }
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QStackedWidget *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+ if (DomWidget *ui_page = createDom(page, ui_widget)) {
+ ui_widget_list.append(ui_page);
+ } else {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ }
+ }
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QToolBar *toolBar, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(toolBar, ui_parentWidget, false);
+ if (const QMainWindow *mainWindow = qobject_cast<QMainWindow*>(toolBar->parentWidget())) {
+ const bool toolBarBreak = mainWindow->toolBarBreak(toolBar);
+ const Qt::ToolBarArea area = mainWindow->toolBarArea(toolBar);
+
+ QList<DomProperty*> attributes = ui_widget->elementAttribute();
+
+ DomProperty *attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("toolBarArea"));
+ attr->setElementEnum(QLatin1String(toolBarAreaMetaEnum().valueToKey(area)));
+ attributes << attr;
+
+ attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("toolBarBreak"));
+ attr->setElementBool(toolBarBreak ? QLatin1String("true") : QLatin1String("false"));
+ attributes << attr;
+ ui_widget->setElementAttribute(attributes);
+ }
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QDesignerDockWidget *dockWidget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(dockWidget, ui_parentWidget, true);
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(dockWidget->parentWidget())) {
+ const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(dockWidget);
+ DomProperty *attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("dockWidgetArea"));
+ attr->setElementNumber(int(area));
+ ui_widget->setElementAttribute(ui_widget->elementAttribute() << attr);
+ }
+
+ return ui_widget;
+}
+
+static void saveStringProperty(DomProperty *property, const PropertySheetStringValue &value)
+{
+ DomString *str = new DomString();
+ str->setText(value.value());
+
+ const QString property_comment = value.disambiguation();
+ if (!property_comment.isEmpty())
+ str->setAttributeComment(property_comment);
+ const QString property_extraComment = value.comment();
+ if (!property_extraComment.isEmpty())
+ str->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = value.translatable();
+ if (!property_translatable)
+ str->setAttributeNotr(QLatin1String("true"));
+
+ property->setElementString(str);
+}
+
+static void saveKeySequenceProperty(DomProperty *property, const PropertySheetKeySequenceValue &value)
+{
+ DomString *str = new DomString();
+ str->setText(value.value().toString());
+
+ const QString property_comment = value.disambiguation();
+ if (!property_comment.isEmpty())
+ str->setAttributeComment(property_comment);
+ const QString property_extraComment = value.comment();
+ if (!property_extraComment.isEmpty())
+ str->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = value.translatable();
+ if (!property_translatable)
+ str->setAttributeNotr(QLatin1String("true"));
+
+ property->setElementString(str);
+}
+
+DomWidget *QDesignerResource::saveWidget(QTabWidget *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ const int current = widget->currentIndex();
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ DomWidget *ui_page = createDom(page, ui_widget);
+ if (!ui_page) {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ continue;
+ }
+ QList<DomProperty*> ui_attribute_list;
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+ // attribute `icon'
+ widget->setCurrentIndex(i);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String("currentTabIcon"))));
+ DomProperty *p = resourceBuilder()->saveResource(workingDirectory(), QVariant::fromValue(icon));
+ if (p) {
+ p->setAttributeName(strings.iconAttribute);
+ ui_attribute_list.append(p);
+ }
+ // attribute `title'
+ p = textBuilder()->saveText(sheet->property(sheet->indexOf(QLatin1String("currentTabText"))));
+ if (p) {
+ p->setAttributeName(strings.titleAttribute);
+ ui_attribute_list.append(p);
+ }
+
+ // attribute `toolTip'
+ QVariant v = sheet->property(sheet->indexOf(QLatin1String("currentTabToolTip")));
+ if (!qvariant_cast<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.toolTipAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ // attribute `whatsThis'
+ v = sheet->property(sheet->indexOf(QLatin1String("currentTabWhatsThis")));
+ if (!qvariant_cast<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.whatsThisAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ ui_page->setElementAttribute(ui_attribute_list);
+
+ ui_widget_list.append(ui_page);
+ }
+ widget->setCurrentIndex(current);
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QToolBox *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ const int current = widget->currentIndex();
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ DomWidget *ui_page = createDom(page, ui_widget);
+ if (!ui_page) {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ continue;
+ }
+
+ // attribute `label'
+ QList<DomProperty*> ui_attribute_list;
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ // attribute `icon'
+ widget->setCurrentIndex(i);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String("currentItemIcon"))));
+ DomProperty *p = resourceBuilder()->saveResource(workingDirectory(), QVariant::fromValue(icon));
+ if (p) {
+ p->setAttributeName(strings.iconAttribute);
+ ui_attribute_list.append(p);
+ }
+ p = textBuilder()->saveText(sheet->property(sheet->indexOf(QLatin1String("currentItemText"))));
+ if (p) {
+ p->setAttributeName(strings.labelAttribute);
+ ui_attribute_list.append(p);
+ }
+
+ // attribute `toolTip'
+ QVariant v = sheet->property(sheet->indexOf(QLatin1String("currentItemToolTip")));
+ if (!qvariant_cast<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.toolTipAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ ui_page->setElementAttribute(ui_attribute_list);
+
+ ui_widget_list.append(ui_page);
+ }
+ widget->setCurrentIndex(current);
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QWizardPage *wizardPage, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(wizardPage, ui_parentWidget, true);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), wizardPage);
+ // Save the page id (string) attribute, append to existing attributes
+ const QString pageIdPropertyName = QLatin1String(QWizardPagePropertySheet::pageIdProperty);
+ const int pageIdIndex = sheet->indexOf(pageIdPropertyName);
+ if (pageIdIndex != -1 && sheet->isChanged(pageIdIndex)) {
+ DomProperty *property = variantToDomProperty(this, wizardPage->metaObject(), pageIdPropertyName, sheet->property(pageIdIndex));
+ Q_ASSERT(property);
+ property->elementString()->setAttributeNotr(QLatin1String("true"));
+ DomPropertyList attributes = ui_widget->elementAttribute();
+ attributes.push_back(property);
+ ui_widget->setElementAttribute(attributes);
+ }
+ return ui_widget;
+}
+
+// Do not save the 'currentTabName' properties of containers
+static inline bool checkContainerProperty(const QWidget *w, const QString &propertyName)
+{
+ if (qobject_cast<const QToolBox *>(w))
+ return QToolBoxWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QTabWidget *>(w))
+ return QTabWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QStackedWidget *>(w))
+ return QStackedWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QMdiArea *>(w) || qobject_cast<const QWorkspace *>(w))
+ return QMdiAreaPropertySheet::checkProperty(propertyName);
+ return true;
+}
+
+bool QDesignerResource::checkProperty(QObject *obj, const QString &prop) const
+{
+ const QDesignerMetaObjectInterface *meta = core()->introspection()->metaObject(obj);
+
+ const int pindex = meta->indexOfProperty(prop);
+ if (pindex != -1 && !(meta->property(pindex)->attributes(obj) & QDesignerMetaPropertyInterface::StoredAttribute))
+ return false;
+
+ if (prop == QLatin1String("objectName") || prop == QLatin1String("spacerName")) // ### don't store the property objectName
+ return false;
+
+ QWidget *check_widget = 0;
+ if (obj->isWidgetType())
+ check_widget = static_cast<QWidget*>(obj);
+
+ if (check_widget && prop == QLatin1String("geometry")) {
+ if (check_widget == m_formWindow->mainContainer())
+ return true; // Save although maincontainer is technically laid-out by embedding container
+ if (m_selected && m_selected == check_widget)
+ return true;
+
+ return !LayoutInfo::isWidgetLaidout(core(), check_widget);
+ }
+
+ if (check_widget && !checkContainerProperty(check_widget, prop))
+ return false;
+
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), obj)) {
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), obj);
+ const int pindex = sheet->indexOf(prop);
+ if (sheet->isAttribute(pindex))
+ return false;
+
+ if (!dynamicSheet || !dynamicSheet->isDynamicProperty(pindex))
+ return sheet->isChanged(pindex);
+ if (!sheet->isVisible(pindex))
+ return false;
+ return true;
+ }
+
+ return false;
+}
+
+bool QDesignerResource::addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout)
+{
+ if (item->widget() == 0) {
+ return false;
+ }
+
+ QGridLayout *grid = qobject_cast<QGridLayout*>(layout);
+ QBoxLayout *box = qobject_cast<QBoxLayout*>(layout);
+
+ if (grid != 0) {
+ const int rowSpan = ui_item->hasAttributeRowSpan() ? ui_item->attributeRowSpan() : 1;
+ const int colSpan = ui_item->hasAttributeColSpan() ? ui_item->attributeColSpan() : 1;
+ grid->addWidget(item->widget(), ui_item->attributeRow(), ui_item->attributeColumn(), rowSpan, colSpan, item->alignment());
+ return true;
+ } else if (box != 0) {
+ box->addItem(item);
+ return true;
+ }
+
+ return QAbstractFormBuilder::addItem(ui_item, item, layout);
+}
+
+bool QDesignerResource::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
+{
+ core()->metaDataBase()->add(widget); // ensure the widget is in the meta database
+
+ if (! QAbstractFormBuilder::addItem(ui_widget, widget, parentWidget) || qobject_cast<QMainWindow*> (parentWidget)) {
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget))
+ container->addWidget(widget);
+ }
+
+ if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(parentWidget)) {
+ const int tabIndex = tabWidget->count() - 1;
+ const int current = tabWidget->currentIndex();
+
+ tabWidget->setCurrentIndex(tabIndex);
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), parentWidget);
+ if (DomProperty *picon = attributes.value(strings.iconAttribute)) {
+ QVariant v = resourceBuilder()->loadResource(workingDirectory(), picon);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabIcon")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.titleAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabText")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.toolTipAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabToolTip")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.whatsThisAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabWhatsThis")), v);
+ }
+ tabWidget->setCurrentIndex(current);
+ } else if (QToolBox *toolBox = qobject_cast<QToolBox*>(parentWidget)) {
+ const int itemIndex = toolBox->count() - 1;
+ const int current = toolBox->currentIndex();
+
+ toolBox->setCurrentIndex(itemIndex);
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), parentWidget);
+ if (DomProperty *picon = attributes.value(strings.iconAttribute)) {
+ QVariant v = resourceBuilder()->loadResource(workingDirectory(), picon);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemIcon")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.labelAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemText")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.toolTipAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemToolTip")), v);
+ }
+ toolBox->setCurrentIndex(current);
+ }
+
+ return true;
+}
+
+bool QDesignerResource::copy(QIODevice *dev, const FormBuilderClipboard &selection)
+{
+ m_copyWidget = true;
+
+ DomUI *ui = copy(selection);
+
+ m_laidout.clear();
+ m_copyWidget = false;
+
+ if (!ui)
+ return false;
+
+ QXmlStreamWriter writer(dev);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ ui->write(writer);
+ writer.writeEndDocument();
+ delete ui;
+ return true;
+}
+
+DomUI *QDesignerResource::copy(const FormBuilderClipboard &selection)
+{
+ if (selection.empty())
+ return 0;
+
+ m_copyWidget = true;
+
+ DomWidget *ui_widget = new DomWidget();
+ ui_widget->setAttributeName(QLatin1String(clipboardObjectName));
+ bool hasItems = false;
+ // Widgets
+ if (!selection.m_widgets.empty()) {
+ QList<DomWidget*> ui_widget_list;
+ const int size = selection.m_widgets.size();
+ for (int i=0; i< size; ++i) {
+ QWidget *w = selection.m_widgets.at(i);
+ m_selected = w;
+ DomWidget *ui_child = createDom(w, ui_widget);
+ m_selected = 0;
+ if (ui_child)
+ ui_widget_list.append(ui_child);
+ }
+ if (!ui_widget_list.empty()) {
+ ui_widget->setElementWidget(ui_widget_list);
+ hasItems = true;
+ }
+ }
+ // actions
+ if (!selection.m_actions.empty()) {
+ QList<DomAction*> domActions;
+ foreach(QAction* action, selection.m_actions)
+ if (DomAction *domAction = createDom(action))
+ domActions += domAction;
+ if (!domActions.empty()) {
+ ui_widget-> setElementAction(domActions);
+ hasItems = true;
+ }
+ }
+
+ m_laidout.clear();
+ m_copyWidget = false;
+
+ if (!hasItems) {
+ delete ui_widget;
+ return 0;
+ }
+ // UI
+ DomUI *ui = new DomUI();
+ ui->setAttributeVersion(QLatin1String(currentUiVersion));
+ ui->setElementWidget(ui_widget);
+ ui->setElementResources(saveResources(m_resourceBuilder->usedQrcFiles()));
+ if (DomCustomWidgets *cws = saveCustomWidgets())
+ ui->setElementCustomWidgets(cws);
+ return ui;
+}
+
+FormBuilderClipboard QDesignerResource::paste(DomUI *ui, QWidget *widgetParent, QObject *actionParent)
+{
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ const int saved = m_isMainWidget;
+ m_isMainWidget = false;
+
+ FormBuilderClipboard rc;
+
+ // Widgets
+ const DomWidget *topLevel = ui->elementWidget();
+ initialize(ui);
+ const QList<DomWidget*> domWidgets = topLevel->elementWidget();
+ if (!domWidgets.empty()) {
+ const QPoint offset = m_formWindow->grid();
+ foreach (DomWidget* domWidget, domWidgets) {
+ if (QWidget *w = create(domWidget, widgetParent)) {
+ w->move(w->pos() + offset);
+ // ### change the init properties of w
+ rc.m_widgets.append(w);
+ }
+ }
+ }
+ const QList<DomAction*> domActions = topLevel->elementAction();
+ if (!domActions.empty())
+ foreach (DomAction *domAction, domActions)
+ if (QAction *a = create(domAction, actionParent))
+ rc.m_actions .append(a);
+
+ m_isMainWidget = saved;
+
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core()))
+ extra->loadUiExtraInfo(ui);
+
+ createResources(ui->elementResources());
+
+ return rc;
+}
+
+FormBuilderClipboard QDesignerResource::paste(QIODevice *dev, QWidget *widgetParent, QObject *actionParent)
+{
+ DomUI ui;
+ QXmlStreamReader reader(dev);
+ bool uiInitialized = false;
+
+ const QString uiElement = QLatin1String("ui");
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ if (reader.name().compare(uiElement, Qt::CaseInsensitive)) {
+ ui.read(reader);
+ uiInitialized = true;
+ } else {
+ //: Parsing clipboard contents
+ reader.raiseError(QCoreApplication::translate("QDesignerResource", "Unexpected element <%1>").arg(reader.name().toString()));
+ }
+ }
+ }
+ if (reader.hasError()) {
+ //: Parsing clipboard contents
+ designerWarning(QCoreApplication::translate("QDesignerResource", "Error while pasting clipboard contents at line %1, column %2: %3")
+ .arg(reader.lineNumber()).arg(reader.columnNumber())
+ .arg(reader.errorString()));
+ uiInitialized = false;
+ } else if (uiInitialized == false) {
+ //: Parsing clipboard contents
+ designerWarning(QCoreApplication::translate("QDesignerResource", "Error while pasting clipboard contents: The root element <ui> is missing."));
+ }
+
+ if (!uiInitialized)
+ return FormBuilderClipboard();
+
+ FormBuilderClipboard clipBoard = paste(&ui, widgetParent, actionParent);
+
+ return clipBoard;
+}
+
+void QDesignerResource::layoutInfo(DomLayout *layout, QObject *parent, int *margin, int *spacing)
+{
+ QAbstractFormBuilder::layoutInfo(layout, parent, margin, spacing);
+}
+
+DomCustomWidgets *QDesignerResource::saveCustomWidgets()
+{
+ if (m_usedCustomWidgets.isEmpty())
+ return 0;
+
+ // We would like the list to be in order of the widget database indexes
+ // to ensure that base classes come first (nice optics)
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ QDesignerWidgetDataBaseInterface *db = core->widgetDataBase();
+ const bool isInternalWidgetDataBase = qobject_cast<const WidgetDataBase *>(db);
+ typedef QMap<int,DomCustomWidget*> OrderedDBIndexDomCustomWidgetMap;
+ OrderedDBIndexDomCustomWidgetMap orderedMap;
+
+ const QString global = QLatin1String("global");
+ foreach (QDesignerWidgetDataBaseItemInterface *item, m_usedCustomWidgets.keys()) {
+ const QString name = item->name();
+ DomCustomWidget *custom_widget = new DomCustomWidget;
+
+ custom_widget->setElementClass(name);
+ if (item->isContainer())
+ custom_widget->setElementContainer(item->isContainer());
+
+ if (!item->includeFile().isEmpty()) {
+ DomHeader *header = new DomHeader;
+ const IncludeSpecification spec = includeSpecification(item->includeFile());
+ header->setText(spec.first);
+ if (spec.second == IncludeGlobal) {
+ header->setAttributeLocation(global);
+ }
+ custom_widget->setElementHeader(header);
+ custom_widget->setElementExtends(item->extends());
+ }
+
+ if (isInternalWidgetDataBase) {
+ WidgetDataBaseItem *internalItem = static_cast<WidgetDataBaseItem *>(item);
+ const QStringList fakeSlots = internalItem->fakeSlots();
+ const QStringList fakeSignals = internalItem->fakeSignals();
+ if (!fakeSlots.empty() || !fakeSignals.empty()) {
+ DomSlots *domSlots = new DomSlots();
+ domSlots->setElementSlot(fakeSlots);
+ domSlots->setElementSignal(fakeSignals);
+ custom_widget->setElementSlots(domSlots);
+ }
+ const QString addPageMethod = internalItem->addPageMethod();
+ if (!addPageMethod.isEmpty())
+ custom_widget->setElementAddPageMethod(addPageMethod);
+ }
+
+ // Look up static per-class scripts of designer
+ if (DomScript *domScript = createScript(customWidgetScript(core, name), ScriptCustomWidgetPlugin))
+ custom_widget->setElementScript(domScript);
+
+ orderedMap.insert(db->indexOfClassName(name), custom_widget);
+ }
+
+ DomCustomWidgets *customWidgets = new DomCustomWidgets;
+ customWidgets->setElementCustomWidget(orderedMap.values());
+ return customWidgets;
+}
+
+bool QDesignerResource::canCompressMargins(QObject *object) const
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ if (qobject_cast<QLayout *>(object)) {
+ const int l = sheet->property(sheet->indexOf(QLatin1String("leftMargin"))).toInt();
+ const int t = sheet->property(sheet->indexOf(QLatin1String("topMargin"))).toInt();
+ const int r = sheet->property(sheet->indexOf(QLatin1String("rightMargin"))).toInt();
+ const int b = sheet->property(sheet->indexOf(QLatin1String("bottomMargin"))).toInt();
+ if (l == t && l == r && l == b)
+ return true;
+ }
+ }
+ return false;
+}
+
+bool QDesignerResource::canCompressSpacings(QObject *object) const
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ if (qobject_cast<QGridLayout *>(object)) {
+ const int h = sheet->property(sheet->indexOf(QLatin1String("horizontalSpacing"))).toInt();
+ const int v = sheet->property(sheet->indexOf(QLatin1String("verticalSpacing"))).toInt();
+ if (h == v)
+ return true;
+ }
+ }
+ return false;
+}
+
+QList<DomProperty*> QDesignerResource::computeProperties(QObject *object)
+{
+ QList<DomProperty*> properties;
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), object);
+ const int count = sheet->count();
+ QList<DomProperty *> marginProperties;
+ QList<DomProperty *> spacingProperties;
+ const bool compressMargins = canCompressMargins(object);
+ const bool compressSpacings = canCompressSpacings(object);
+ for (int index = 0; index < count; ++index) {
+ if (!sheet->isChanged(index) && (!dynamicSheet || !dynamicSheet->isDynamicProperty(index)))
+ continue;
+
+ const QString propertyName = sheet->propertyName(index);
+ // Suppress windowModality in legacy forms that have it set on child widgets
+ if (propertyName == QLatin1String("windowModality") && !sheet->isVisible(index))
+ continue;
+
+ const QVariant value = sheet->property(index);
+ if (DomProperty *p = createProperty(object, propertyName, value)) {
+ if (compressMargins && (propertyName == QLatin1String("leftMargin")
+ || propertyName == QLatin1String("rightMargin")
+ || propertyName == QLatin1String("topMargin")
+ || propertyName == QLatin1String("bottomMargin"))) {
+ marginProperties.append(p);
+ } else if (compressSpacings && (propertyName == QLatin1String("horizontalSpacing")
+ || propertyName == QLatin1String("verticalSpacing"))) {
+ spacingProperties.append(p);
+ } else {
+ properties.append(p);
+ }
+ }
+ }
+ if (compressMargins) {
+ if (marginProperties.count() == 4) { // if we have 3 it means one is reset so we can't compress
+ DomProperty *marginProperty = marginProperties.at(0);
+ marginProperty->setAttributeName(QLatin1String("margin"));
+ properties.append(marginProperty);
+ delete marginProperties.at(1);
+ delete marginProperties.at(2);
+ delete marginProperties.at(3);
+ } else {
+ properties += marginProperties;
+ }
+ }
+ if (compressSpacings) {
+ if (spacingProperties.count() == 2) {
+ DomProperty *spacingProperty = spacingProperties.at(0);
+ spacingProperty->setAttributeName(QLatin1String("spacing"));
+ properties.append(spacingProperty);
+ delete spacingProperties.at(1);
+ } else {
+ properties += spacingProperties;
+ }
+ }
+ }
+ return properties;
+}
+
+DomProperty *QDesignerResource::applyProperStdSetAttribute(QObject *object, const QString &propertyName, DomProperty *property)
+{
+ if (!property)
+ return 0;
+
+ QExtensionManager *mgr = core()->extensionManager();
+ if (const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(mgr, object)) {
+ const QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(mgr, object);
+ const QDesignerPropertySheet *designerSheet = qobject_cast<QDesignerPropertySheet*>(core()->extensionManager()->extension(object, Q_TYPEID(QDesignerPropertySheetExtension)));
+ const int index = sheet->indexOf(propertyName);
+ if ((dynamicSheet && dynamicSheet->isDynamicProperty(index)) || (designerSheet && designerSheet->isDefaultDynamicProperty(index)))
+ property->setAttributeStdset(0);
+ }
+ return property;
+}
+
+// Optimistic check for a standard setter function
+static inline bool hasSetter(QDesignerFormEditorInterface *core, QObject *object, const QString &propertyName)
+{
+ const QDesignerMetaObjectInterface *meta = core->introspection()->metaObject(object);
+ const int pindex = meta->indexOfProperty(propertyName);
+ if (pindex == -1)
+ return true;
+ return meta->property(pindex)->hasSetter();
+}
+
+DomProperty *QDesignerResource::createProperty(QObject *object, const QString &propertyName, const QVariant &value)
+{
+ if (!checkProperty(object, propertyName)) {
+ return 0;
+ }
+
+ if (value.canConvert<PropertySheetFlagValue>()) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(value);
+ const QString flagString = f.metaFlags.toString(f.value, DesignerMetaFlags::FullyQualified);
+ if (flagString.isEmpty())
+ return 0;
+
+ DomProperty *p = new DomProperty;
+ // check if we have a standard cpp set function
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+ p->setAttributeName(propertyName);
+ p->setElementSet(flagString);
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (value.canConvert<PropertySheetEnumValue>()) {
+ const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(value);
+ bool ok;
+ const QString id = e.metaEnum.toString(e.value, DesignerMetaEnum::FullyQualified, &ok);
+ if (!ok)
+ designerWarning(e.metaEnum.messageToStringFailed(e.value));
+ if (id.isEmpty())
+ return 0;
+
+ DomProperty *p = new DomProperty;
+ // check if we have a standard cpp set function
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+ p->setAttributeName(propertyName);
+ p->setElementEnum(id);
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (value.canConvert<PropertySheetStringValue>()) {
+ const PropertySheetStringValue strVal = qvariant_cast<PropertySheetStringValue>(value);
+ DomProperty *p = new DomProperty;
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+
+ p->setAttributeName(propertyName);
+
+ saveStringProperty(p, strVal);
+
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (value.canConvert<PropertySheetKeySequenceValue>()) {
+ const PropertySheetKeySequenceValue keyVal = qvariant_cast<PropertySheetKeySequenceValue>(value);
+ DomProperty *p = new DomProperty;
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+
+ p->setAttributeName(propertyName);
+
+ saveKeySequenceProperty(p, keyVal);
+
+ return applyProperStdSetAttribute(object, propertyName, p);
+ }
+
+ return applyProperStdSetAttribute(object, propertyName, QAbstractFormBuilder::createProperty(object, propertyName, value));
+}
+
+QStringList QDesignerResource::mergeWithLoadedPaths(const QStringList &paths) const
+{
+ QStringList newPaths = paths;
+#ifdef OLD_RESOURCE_FORMAT
+ QStringList loadedPaths = m_resourceBuilder->loadedQrcFiles();
+ QStringListIterator it(loadedPaths);
+ while (it.hasNext()) {
+ const QString path = it.next();
+ if (!newPaths.contains(path))
+ newPaths << path;
+ }
+#endif
+ return newPaths;
+}
+
+
+void QDesignerResource::createResources(DomResources *resources)
+{
+ QStringList paths;
+ if (resources != 0) {
+ const QList<DomResource*> dom_include = resources->elementInclude();
+ foreach (DomResource *res, dom_include) {
+ QString path = QDir::cleanPath(m_formWindow->absoluteDir().absoluteFilePath(res->attributeLocation()));
+ while (!QFile::exists(path)) {
+ QWidget *dialogParent = m_formWindow->core()->topLevel();
+ const QString promptTitle = QApplication::translate("qdesigner_internal::QDesignerResource", "Loading qrc file", 0, QApplication::UnicodeUTF8);
+ const QString prompt = QApplication::translate("qdesigner_internal::QDesignerResource", "The specified qrc file <p><b>%1</b></p><p>could not be found. Do you want to update the file location?</p>", 0, QApplication::UnicodeUTF8).arg(path);
+
+ const QMessageBox::StandardButton answer = core()->dialogGui()->message(dialogParent, QDesignerDialogGuiInterface::ResourceLoadFailureMessage,
+ QMessageBox::Warning, promptTitle, prompt, QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
+ if (answer == QMessageBox::Yes) {
+ const QFileInfo fi(path);
+ const QString fileDialogTitle = QApplication::translate("qdesigner_internal::QDesignerResource", "New location for %1", 0, QApplication::UnicodeUTF8).arg(fi.fileName());
+ const QString fileDialogPattern = QApplication::translate("qdesigner_internal::QDesignerResource", "Resource files (*.qrc)", 0, QApplication::UnicodeUTF8);
+ path = core()->dialogGui()->getOpenFileName(dialogParent, fileDialogTitle, fi.absolutePath(), fileDialogPattern);
+ if (path.isEmpty())
+ break;
+ m_formWindow->setProperty("_q_resourcepathchanged", QVariant(true));
+ } else {
+ break;
+ }
+ }
+ if (!path.isEmpty()) {
+ paths << path;
+ m_formWindow->addResourceFile(path);
+ }
+ }
+ }
+
+#ifdef OLD_RESOURCE_FORMAT
+ paths = mergeWithLoadedPaths(paths);
+#endif
+
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ if (resourceSet) {
+ QStringList oldPaths = resourceSet->activeQrcPaths();
+ QStringList newPaths = oldPaths;
+ QStringListIterator it(paths);
+ while (it.hasNext()) {
+ const QString path = it.next();
+ if (!newPaths.contains(path))
+ newPaths << path;
+ }
+ resourceSet->activateQrcPaths(newPaths);
+ } else {
+ resourceSet = m_formWindow->core()->resourceModel()->addResourceSet(paths);
+ m_formWindow->setResourceSet(resourceSet);
+ QObject::connect(m_formWindow->core()->resourceModel(), SIGNAL(resourceSetActivated(QtResourceSet*,bool)),
+ m_formWindow, SLOT(resourceSetActivated(QtResourceSet*,bool)));
+ }
+}
+
+DomResources *QDesignerResource::saveResources()
+{
+ QStringList paths;
+ if (m_formWindow->saveResourcesBehaviour() == FormWindowBase::SaveAll) {
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ QList<DomResource*> dom_include;
+ if (resourceSet)
+ paths = resourceSet->activeQrcPaths();
+ } else if (m_formWindow->saveResourcesBehaviour() == FormWindowBase::SaveOnlyUsedQrcFiles) {
+ paths = m_resourceBuilder->usedQrcFiles();
+ }
+
+ return saveResources(paths);
+}
+
+DomResources *QDesignerResource::saveResources(const QStringList &qrcPaths)
+{
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ QList<DomResource*> dom_include;
+ if (resourceSet) {
+ const QStringList activePaths = resourceSet->activeQrcPaths();
+ foreach (const QString &path, activePaths) {
+ if (qrcPaths.contains(path)) {
+ DomResource *dom_res = new DomResource;
+ QString conv_path = path;
+ if (m_resourceBuilder->isSaveRelative())
+ conv_path = m_formWindow->absoluteDir().relativeFilePath(path);
+ dom_res->setAttributeLocation(conv_path.replace(QDir::separator(), QLatin1Char('/')));
+ dom_include.append(dom_res);
+ }
+ }
+ }
+
+ DomResources *dom_resources = new DomResources;
+ dom_resources->setElementInclude(dom_include);
+
+ return dom_resources;
+}
+
+DomAction *QDesignerResource::createDom(QAction *action)
+{
+ if (!core()->metaDataBase()->item(action) || action->menu())
+ return 0;
+
+ return QAbstractFormBuilder::createDom(action);
+}
+
+DomActionGroup *QDesignerResource::createDom(QActionGroup *actionGroup)
+{
+ if (core()->metaDataBase()->item(actionGroup) != 0) {
+ return QAbstractFormBuilder::createDom(actionGroup);
+ }
+
+ return 0;
+}
+
+QAction *QDesignerResource::create(DomAction *ui_action, QObject *parent)
+{
+ if (QAction *action = QAbstractFormBuilder::create(ui_action, parent)) {
+ core()->metaDataBase()->add(action);
+ return action;
+ }
+
+ return 0;
+}
+
+QActionGroup *QDesignerResource::create(DomActionGroup *ui_action_group, QObject *parent)
+{
+ if (QActionGroup *actionGroup = QAbstractFormBuilder::create(ui_action_group, parent)) {
+ core()->metaDataBase()->add(actionGroup);
+ return actionGroup;
+ }
+
+ return 0;
+}
+
+DomActionRef *QDesignerResource::createActionRefDom(QAction *action)
+{
+ if (!core()->metaDataBase()->item(action)
+ || (!action->isSeparator() && !action->menu() && action->objectName().isEmpty()))
+ return 0;
+
+ return QAbstractFormBuilder::createActionRefDom(action);
+}
+
+void QDesignerResource::addMenuAction(QAction *action)
+{
+ core()->metaDataBase()->add(action);
+}
+
+QAction *QDesignerResource::createAction(QObject *parent, const QString &name)
+{
+ if (QAction *action = QAbstractFormBuilder::createAction(parent, name)) {
+ core()->metaDataBase()->add(action);
+ return action;
+ }
+
+ return 0;
+}
+
+QActionGroup *QDesignerResource::createActionGroup(QObject *parent, const QString &name)
+{
+ if (QActionGroup *actionGroup = QAbstractFormBuilder::createActionGroup(parent, name)) {
+ core()->metaDataBase()->add(actionGroup);
+ return actionGroup;
+ }
+
+ return 0;
+}
+
+/* Apply the attributes to a widget via property sheet where appropriate,
+ * that is, the sheet handles attributive fake properties */
+void QDesignerResource::applyAttributesToPropertySheet(const DomWidget *ui_widget, QWidget *widget)
+{
+ const DomPropertyList attributes = ui_widget->elementAttribute();
+ if (attributes.empty())
+ return;
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_formWindow->core()->extensionManager(), widget);
+ const DomPropertyList::const_iterator acend = attributes.constEnd();
+ for (DomPropertyList::const_iterator it = attributes.constBegin(); it != acend; ++it) {
+ const QString name = (*it)->attributeName();
+ const int index = sheet->indexOf(name);
+ if (index == -1) {
+ const QString msg = QString::fromUtf8("Unable to apply attributive property '%1' to '%2'. It does not exist.").arg(name, widget->objectName());
+ designerWarning(msg);
+ } else {
+ sheet->setProperty(index, domPropertyToVariant(this, widget->metaObject(), *it));
+ sheet->setChanged(index, true);
+ }
+ }
+}
+
+void QDesignerResource::loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
+{
+ QAbstractFormBuilder::loadExtraInfo(ui_widget, widget, parentWidget);
+ // Apply the page id attribute of a QWizardPage (which is an attributive fake property)
+ if (qobject_cast<const QWizardPage*>(widget))
+ applyAttributesToPropertySheet(ui_widget, widget);
+}
+
+// Add user defined scripts (dialog box) belonging to QWidget to DomWidget.
+void QDesignerResource::addUserDefinedScripts(QWidget *w, DomWidget *ui_widget)
+{
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ DomScripts domScripts = ui_widget->elementScript();
+ // Look up user-defined scripts of designer
+ if (const qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<const qdesigner_internal::MetaDataBase *>(core->metaDataBase())) {
+ if (const qdesigner_internal::MetaDataBaseItem *metaItem = metaDataBase->metaDataBaseItem(w)) {
+ addScript(metaItem->script(), ScriptDesigner, domScripts);
+ }
+ }
+ if (!domScripts.empty())
+ ui_widget->setElementScript(domScripts);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qdesigner_resource.h b/src/designer/src/components/formeditor/qdesigner_resource.h
new file mode 100644
index 000000000..b7113d162
--- /dev/null
+++ b/src/designer/src/components/formeditor/qdesigner_resource.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_RESOURCE_H
+#define QDESIGNER_RESOURCE_H
+
+#include "formeditor_global.h"
+#include "qsimpleresource_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QStack>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class DomCustomWidget;
+class DomCustomWidgets;
+class DomResource;
+
+class QDesignerContainerExtension;
+class QDesignerFormEditorInterface;
+class QDesignerCustomWidgetInterface;
+class QDesignerWidgetDataBaseItemInterface;
+
+class QTabWidget;
+class QStackedWidget;
+class QToolBox;
+class QToolBar;
+class QDesignerDockWidget;
+class QLayoutWidget;
+class QWizardPage;
+
+namespace qdesigner_internal {
+
+class FormWindow;
+
+class QT_FORMEDITOR_EXPORT QDesignerResource : public QEditorFormBuilder
+{
+public:
+ explicit QDesignerResource(FormWindow *fw);
+ virtual ~QDesignerResource();
+
+ virtual void save(QIODevice *dev, QWidget *widget);
+
+ virtual bool copy(QIODevice *dev, const FormBuilderClipboard &selection);
+ virtual DomUI *copy(const FormBuilderClipboard &selection);
+
+ virtual FormBuilderClipboard paste(DomUI *ui, QWidget *widgetParent, QObject *actionParent = 0);
+ virtual FormBuilderClipboard paste(QIODevice *dev, QWidget *widgetParent, QObject *actionParent = 0);
+
+ bool saveRelative() const;
+ void setSaveRelative(bool relative);
+
+ virtual QWidget *load(QIODevice *dev, QWidget *parentWidget = 0);
+
+protected:
+ using QEditorFormBuilder::create;
+ using QEditorFormBuilder::createDom;
+
+ virtual void saveDom(DomUI *ui, QWidget *widget);
+ virtual QWidget *create(DomUI *ui, QWidget *parentWidget);
+ virtual QWidget *create(DomWidget *ui_widget, QWidget *parentWidget);
+ virtual QLayout *create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget);
+ virtual QLayoutItem *create(DomLayoutItem *ui_layoutItem, QLayout *layout, QWidget *parentWidget);
+ virtual void applyProperties(QObject *o, const QList<DomProperty*> &properties);
+ virtual QList<DomProperty*> computeProperties(QObject *obj);
+ virtual DomProperty *createProperty(QObject *object, const QString &propertyName, const QVariant &value);
+
+ virtual QWidget *createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name);
+ virtual QLayout *createLayout(const QString &layoutName, QObject *parent, const QString &name);
+ virtual void createCustomWidgets(DomCustomWidgets *);
+ virtual void createResources(DomResources*);
+ virtual void applyTabStops(QWidget *widget, DomTabStops *tabStops);
+
+ virtual bool addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout);
+ virtual bool addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
+
+ virtual DomWidget *createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive = true);
+ virtual DomLayout *createDom(QLayout *layout, DomLayout *ui_layout, DomWidget *ui_parentWidget);
+ virtual DomLayoutItem *createDom(QLayoutItem *item, DomLayout *ui_layout, DomWidget *ui_parentWidget);
+
+ virtual QAction *create(DomAction *ui_action, QObject *parent);
+ virtual QActionGroup *create(DomActionGroup *ui_action_group, QObject *parent);
+ virtual void addMenuAction(QAction *action);
+
+ virtual DomAction *createDom(QAction *action);
+ virtual DomActionGroup *createDom(QActionGroup *actionGroup);
+ virtual DomActionRef *createActionRefDom(QAction *action);
+
+ virtual QAction *createAction(QObject *parent, const QString &name);
+ virtual QActionGroup *createActionGroup(QObject *parent, const QString &name);
+
+ virtual bool checkProperty(QObject *obj, const QString &prop) const;
+
+ DomWidget *saveWidget(QTabWidget *widget, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QStackedWidget *widget, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QToolBox *widget, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QWidget *widget, QDesignerContainerExtension *container, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QToolBar *toolBar, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QDesignerDockWidget *dockWidget, DomWidget *ui_parentWidget);
+ DomWidget *saveWidget(QWizardPage *wizardPage, DomWidget *ui_parentWidget);
+
+ virtual DomCustomWidgets *saveCustomWidgets();
+ virtual DomTabStops *saveTabStops();
+ virtual DomResources *saveResources();
+
+ virtual void layoutInfo(DomLayout *layout, QObject *parent, int *margin, int *spacing);
+
+ virtual void loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
+
+ void changeObjectName(QObject *o, QString name);
+ DomProperty *applyProperStdSetAttribute(QObject *object, const QString &propertyName, DomProperty *property);
+
+private:
+ void addUserDefinedScripts(QWidget *w, DomWidget *ui_widget);
+ DomResources *saveResources(const QStringList &qrcPaths);
+ bool canCompressMargins(QObject *object) const;
+ bool canCompressSpacings(QObject *object) const;
+ QStringList mergeWithLoadedPaths(const QStringList &paths) const;
+ void applyAttributesToPropertySheet(const DomWidget *ui_widget, QWidget *widget);
+
+ typedef QList<DomCustomWidget*> DomCustomWidgetList;
+ void addCustomWidgetsToWidgetDatabase(DomCustomWidgetList& list);
+ FormWindow *m_formWindow;
+ bool m_isMainWidget;
+ QHash<QString, QString> m_internal_to_qt;
+ QHash<QString, QString> m_qt_to_internal;
+ QStack<QLayout*> m_chain;
+ QHash<QDesignerWidgetDataBaseItemInterface*, bool> m_usedCustomWidgets;
+ int m_topLevelSpacerCount;
+ bool m_copyWidget;
+ QWidget *m_selected;
+ class QDesignerResourceBuilder *m_resourceBuilder;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_RESOURCE_H
diff --git a/src/designer/src/components/formeditor/qdesignerundostack.cpp b/src/designer/src/components/formeditor/qdesignerundostack.cpp
new file mode 100644
index 000000000..56bb04f9e
--- /dev/null
+++ b/src/designer/src/components/formeditor/qdesignerundostack.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesignerundostack.h"
+
+#include <QtGui/QUndoStack>
+#include <QtGui/QUndoCommand>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QDesignerUndoStack::QDesignerUndoStack(QObject *parent) :
+ QObject(parent),
+ m_undoStack(new QUndoStack),
+ m_fakeDirty(false)
+{
+ connect(m_undoStack, SIGNAL(indexChanged(int)), this, SIGNAL(changed()));
+}
+
+QDesignerUndoStack::~QDesignerUndoStack()
+{ // QUndoStack is managed by the QUndoGroup
+}
+
+void QDesignerUndoStack::push(QUndoCommand * cmd)
+{
+ m_undoStack->push(cmd);
+}
+
+void QDesignerUndoStack::beginMacro(const QString &text)
+{
+ m_undoStack->beginMacro(text);
+}
+
+void QDesignerUndoStack::endMacro()
+{
+ m_undoStack->endMacro();
+}
+
+int QDesignerUndoStack::index() const
+{
+ return m_undoStack->index();
+}
+
+const QUndoStack *QDesignerUndoStack::qundoStack() const
+{
+ return m_undoStack;
+}
+QUndoStack *QDesignerUndoStack::qundoStack()
+{
+ return m_undoStack;
+}
+
+bool QDesignerUndoStack::isDirty() const
+{
+ return m_fakeDirty || !m_undoStack->isClean();
+}
+
+void QDesignerUndoStack::setDirty(bool v)
+{
+ if (isDirty() == v)
+ return;
+ if (v) {
+ m_fakeDirty = true;
+ emit changed();
+ } else {
+ m_fakeDirty = false;
+ m_undoStack->setClean();
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qdesignerundostack.h b/src/designer/src/components/formeditor/qdesignerundostack.h
new file mode 100644
index 000000000..cabb4abdb
--- /dev/null
+++ b/src/designer/src/components/formeditor/qdesignerundostack.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNERUNDOSTACK_H
+#define QDESIGNERUNDOSTACK_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+class QUndoStack;
+class QUndoCommand;
+
+namespace qdesigner_internal {
+
+/* QDesignerUndoStack: A QUndoStack extended by a way of setting it to
+ * "dirty" indepently of commands (by modifications without commands
+ * such as resizing). Accomplished via bool m_fakeDirty flag. The
+ * lifecycle of the QUndoStack is managed by the QUndoGroup. */
+class QDesignerUndoStack : public QObject
+{
+ Q_DISABLE_COPY(QDesignerUndoStack)
+ Q_OBJECT
+public:
+ explicit QDesignerUndoStack(QObject *parent = 0);
+ virtual ~QDesignerUndoStack();
+
+ void push(QUndoCommand * cmd);
+ void beginMacro(const QString &text);
+ void endMacro();
+ int index() const;
+
+ const QUndoStack *qundoStack() const;
+ QUndoStack *qundoStack();
+
+ bool isDirty() const;
+
+signals:
+ void changed();
+
+public slots:
+ void setDirty(bool);
+
+private:
+ QUndoStack *m_undoStack;
+ bool m_fakeDirty;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNERUNDOSTACK_H
diff --git a/src/designer/src/components/formeditor/qlayoutwidget_propertysheet.cpp b/src/designer/src/components/formeditor/qlayoutwidget_propertysheet.cpp
new file mode 100644
index 000000000..49c49fa8e
--- /dev/null
+++ b/src/designer/src/components/formeditor/qlayoutwidget_propertysheet.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlayoutwidget_propertysheet.h"
+#include "qlayout_widget_p.h"
+#include "formwindow.h"
+#include "formeditor.h"
+
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+QLayoutWidgetPropertySheet::QLayoutWidgetPropertySheet(QLayoutWidget *object, QObject *parent)
+ : QDesignerPropertySheet(object, parent)
+{
+ clearFakeProperties();
+}
+
+QLayoutWidgetPropertySheet::~QLayoutWidgetPropertySheet()
+{
+}
+
+bool QLayoutWidgetPropertySheet::isVisible(int index) const
+{
+ static const QString layoutPropertyGroup = QLatin1String("Layout");
+ if (propertyGroup(index) == layoutPropertyGroup)
+ return QDesignerPropertySheet::isVisible(index);
+ return false;
+}
+
+void QLayoutWidgetPropertySheet::setProperty(int index, const QVariant &value)
+{
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+bool QLayoutWidgetPropertySheet::dynamicPropertiesAllowed() const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qlayoutwidget_propertysheet.h b/src/designer/src/components/formeditor/qlayoutwidget_propertysheet.h
new file mode 100644
index 000000000..76e3263f6
--- /dev/null
+++ b/src/designer/src/components/formeditor/qlayoutwidget_propertysheet.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAYOUTWIDGET_PROPERTYSHEET_H
+#define QLAYOUTWIDGET_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+#include <qlayout_widget_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QLayoutWidgetPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit QLayoutWidgetPropertySheet(QLayoutWidget *object, QObject *parent = 0);
+ virtual ~QLayoutWidgetPropertySheet();
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool isVisible(int index) const;
+
+ virtual bool dynamicPropertiesAllowed() const;
+};
+
+typedef QDesignerPropertySheetFactory<QLayoutWidget, QLayoutWidgetPropertySheet> QLayoutWidgetPropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QLAYOUTWIDGET_PROPERTYSHEET_H
diff --git a/src/designer/src/components/formeditor/qmainwindow_container.cpp b/src/designer/src/components/formeditor/qmainwindow_container.cpp
new file mode 100644
index 000000000..d2664b418
--- /dev/null
+++ b/src/designer/src/components/formeditor/qmainwindow_container.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmainwindow_container.h"
+#include "qdesigner_toolbar_p.h"
+#include "formwindow.h"
+
+#include <QtCore/qdebug.h>
+
+#include <QtGui/QLayout>
+#include <QtGui/QMenuBar>
+#include <QtGui/QToolBar>
+#include <QtGui/QStatusBar>
+#include <QtGui/QDockWidget>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+QMainWindowContainer::QMainWindowContainer(QMainWindow *widget, QObject *parent)
+ : QObject(parent),
+ m_mainWindow(widget)
+{
+}
+
+int QMainWindowContainer::count() const
+{
+ return m_widgets.count();
+}
+
+QWidget *QMainWindowContainer::widget(int index) const
+{
+ if (index == -1)
+ return 0;
+
+ return m_widgets.at(index);
+}
+
+int QMainWindowContainer::currentIndex() const
+{
+ return m_mainWindow->centralWidget() ? 0 : -1;
+}
+
+void QMainWindowContainer::setCurrentIndex(int index)
+{
+ Q_UNUSED(index);
+}
+
+
+namespace {
+ // Pair of <area,break_before>
+ typedef QPair<Qt::ToolBarArea,bool> ToolBarData;
+
+ ToolBarData toolBarData(QToolBar *me) {
+ const QMainWindow *mw = qobject_cast<const QMainWindow*>(me->parentWidget());
+ if (!mw || !mw->layout() || mw->layout()->indexOf(me) == -1)
+ return ToolBarData(Qt::TopToolBarArea,false);
+ return ToolBarData(mw->toolBarArea(me), mw->toolBarBreak(me));
+ }
+
+Qt::DockWidgetArea dockWidgetArea(QDockWidget *me)
+{
+ if (const QMainWindow *mw = qobject_cast<const QMainWindow*>(me->parentWidget())) {
+ // Make sure that me is actually managed by mw, otherwise
+ // QMainWindow::dockWidgetArea() will be VERY upset
+ QList<QLayout*> candidates;
+ if (mw->layout()) {
+ candidates.append(mw->layout());
+ candidates += mw->layout()->findChildren<QLayout*>();
+ }
+ foreach (QLayout *l, candidates) {
+ if (l->indexOf(me) != -1) {
+ return mw->dockWidgetArea(me);
+ }
+ }
+ }
+ return Qt::LeftDockWidgetArea;
+}
+}
+
+void QMainWindowContainer::addWidget(QWidget *widget)
+{
+ // remove all the occurrences of widget
+ m_widgets.removeAll(widget);
+
+ // the
+ if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
+ m_widgets.append(widget);
+ const ToolBarData data = toolBarData(toolBar);
+ m_mainWindow->addToolBar(data.first, toolBar);
+ if (data.second) m_mainWindow->insertToolBarBreak(toolBar);
+ toolBar->show();
+ }
+
+ else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {
+ if (menuBar != m_mainWindow->menuBar())
+ m_mainWindow->setMenuBar(menuBar);
+
+ m_widgets.append(widget);
+ menuBar->show();
+ }
+
+ else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {
+ if (statusBar != m_mainWindow->statusBar())
+ m_mainWindow->setStatusBar(statusBar);
+
+ m_widgets.append(widget);
+ statusBar->show();
+ }
+
+ else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {
+ m_widgets.append(widget);
+ m_mainWindow->addDockWidget(dockWidgetArea(dockWidget), dockWidget);
+ dockWidget->show();
+
+ if (FormWindow *fw = FormWindow::findFormWindow(m_mainWindow)) {
+ fw->manageWidget(widget);
+ }
+ }
+
+ else if (widget) {
+ m_widgets.prepend(widget);
+
+ if (widget != m_mainWindow->centralWidget()) {
+ // note that qmainwindow will delete the current central widget if you
+ // call setCentralWidget(), we end up with dangeling pointers in m_widgets list
+ m_widgets.removeAll(m_mainWindow->centralWidget());
+
+ widget->setParent(m_mainWindow);
+ m_mainWindow->setCentralWidget(widget);
+ }
+ }
+}
+
+void QMainWindowContainer::insertWidget(int index, QWidget *widget)
+{
+ Q_UNUSED(index);
+
+ addWidget(widget);
+}
+
+void QMainWindowContainer::remove(int index)
+{
+ QWidget *widget = m_widgets.at(index);
+ if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
+ m_mainWindow->removeToolBar(toolBar);
+ } else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(widget)) {
+ menuBar->hide();
+ menuBar->setParent(0);
+ m_mainWindow->setMenuBar(0);
+ } else if (QStatusBar *statusBar = qobject_cast<QStatusBar*>(widget)) {
+ statusBar->hide();
+ statusBar->setParent(0);
+ m_mainWindow->setStatusBar(0);
+ } else if (QDockWidget *dockWidget = qobject_cast<QDockWidget*>(widget)) {
+ m_mainWindow->removeDockWidget(dockWidget);
+ }
+ m_widgets.removeAt(index);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qmainwindow_container.h b/src/designer/src/components/formeditor/qmainwindow_container.h
new file mode 100644
index 000000000..6151c97ff
--- /dev/null
+++ b/src/designer/src/components/formeditor/qmainwindow_container.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMAINWINDOW_CONTAINER_H
+#define QMAINWINDOW_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionFactory>
+
+#include <extensionfactory_p.h>
+
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QMainWindowContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QMainWindowContainer(QMainWindow *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QMainWindow *m_mainWindow;
+ QList<QWidget*> m_widgets;
+};
+
+typedef ExtensionFactory<QDesignerContainerExtension, QMainWindow, QMainWindowContainer> QMainWindowContainerFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QMAINWINDOW_CONTAINER_H
diff --git a/src/designer/src/components/formeditor/qmdiarea_container.cpp b/src/designer/src/components/formeditor/qmdiarea_container.cpp
new file mode 100644
index 000000000..670d1d062
--- /dev/null
+++ b/src/designer/src/components/formeditor/qmdiarea_container.cpp
@@ -0,0 +1,281 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmdiarea_container.h"
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QMdiArea>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QMdiAreaContainer::QMdiAreaContainer(QMdiArea *widget, QObject *parent)
+ : QObject(parent),
+ m_mdiArea(widget)
+{
+}
+
+int QMdiAreaContainer::count() const
+{
+ return m_mdiArea->subWindowList(QMdiArea::CreationOrder).count();
+}
+
+QWidget *QMdiAreaContainer::widget(int index) const
+{
+ if (index < 0)
+ return 0;
+ return m_mdiArea->subWindowList(QMdiArea::CreationOrder).at(index)->widget();
+}
+
+int QMdiAreaContainer::currentIndex() const
+{
+ if (QMdiSubWindow *sub = m_mdiArea->activeSubWindow())
+ return m_mdiArea->subWindowList(QMdiArea::CreationOrder).indexOf(sub);
+ return -1;
+}
+
+void QMdiAreaContainer::setCurrentIndex(int index)
+{
+ if (index < 0) {
+ qDebug() << "** WARNING Attempt to QMdiAreaContainer::setCurrentIndex(-1)";
+ return;
+ }
+ QMdiSubWindow *frame = m_mdiArea->subWindowList(QMdiArea::CreationOrder).at(index);
+ m_mdiArea->setActiveSubWindow(frame);
+}
+
+void QMdiAreaContainer::addWidget(QWidget *widget)
+{
+ QMdiSubWindow *frame = m_mdiArea->addSubWindow(widget, Qt::Window);
+ frame->show();
+ m_mdiArea->cascadeSubWindows();
+ positionNewMdiChild(m_mdiArea, frame);
+}
+
+// Semi-smart positioning of new windows: Make child fill the whole MDI window below
+// cascaded other windows
+void QMdiAreaContainer::positionNewMdiChild(const QWidget *area, QWidget *mdiChild)
+{
+ enum { MinSize = 20 };
+ const QPoint pos = mdiChild->pos();
+ const QSize areaSize = area->size();
+ switch (QApplication::layoutDirection()) {
+ case Qt::LayoutDirectionAuto:
+ case Qt::LeftToRight: {
+ const QSize fullSize = QSize(areaSize.width() - pos.x(), areaSize.height() - pos.y());
+ if (fullSize.width() > MinSize && fullSize.height() > MinSize)
+ mdiChild->resize(fullSize);
+ }
+ break;
+ case Qt::RightToLeft: {
+ const QSize fullSize = QSize(pos.x() + mdiChild->width(), areaSize.height() - pos.y());
+ if (fullSize.width() > MinSize && fullSize.height() > MinSize) {
+ mdiChild->move(0, pos.y());
+ mdiChild->resize(fullSize);
+ }
+ }
+ break;
+ }
+}
+
+void QMdiAreaContainer::insertWidget(int, QWidget *widget)
+{
+ addWidget(widget);
+}
+
+void QMdiAreaContainer::remove(int index)
+{
+ QList<QMdiSubWindow *> subWins = m_mdiArea->subWindowList(QMdiArea::CreationOrder);
+ if (index >= 0 && index < subWins.size()) {
+ QMdiSubWindow *f = subWins.at(index);
+ m_mdiArea->removeSubWindow(f->widget());
+ delete f;
+ }
+}
+
+// ---------- MdiAreaPropertySheet, creates fake properties:
+// 1) window name (object name of child)
+// 2) title (windowTitle of child).
+
+static const char *subWindowTitleC = "activeSubWindowTitle";
+static const char *subWindowNameC = "activeSubWindowName";
+
+QMdiAreaPropertySheet::QMdiAreaPropertySheet(QWidget *mdiArea, QObject *parent) :
+ QDesignerPropertySheet(mdiArea, parent),
+ m_windowTitleProperty(QLatin1String("windowTitle"))
+{
+ createFakeProperty(QLatin1String(subWindowNameC), QString());
+ createFakeProperty(QLatin1String(subWindowTitleC), QString());
+}
+
+QMdiAreaPropertySheet::MdiAreaProperty QMdiAreaPropertySheet::mdiAreaProperty(const QString &name)
+{
+ typedef QHash<QString, MdiAreaProperty> MdiAreaPropertyHash;
+ static MdiAreaPropertyHash mdiAreaPropertyHash;
+ if (mdiAreaPropertyHash.empty()) {
+ mdiAreaPropertyHash.insert(QLatin1String(subWindowNameC), MdiAreaSubWindowName);
+ mdiAreaPropertyHash.insert(QLatin1String(subWindowTitleC), MdiAreaSubWindowTitle);
+ }
+ return mdiAreaPropertyHash.value(name,MdiAreaNone);
+}
+
+void QMdiAreaPropertySheet::setProperty(int index, const QVariant &value)
+{
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ if (QWidget *w = currentWindow())
+ w->setObjectName(value.toString());
+ break;
+ case MdiAreaSubWindowTitle: // Forward to window title of subwindow
+ if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
+ const int index = cws->indexOf(m_windowTitleProperty);
+ cws->setProperty(index, value);
+ cws->setChanged(index, true);
+ }
+ break;
+ default:
+ QDesignerPropertySheet::setProperty(index, value);
+ break;
+ }
+}
+
+bool QMdiAreaPropertySheet::reset(int index)
+{
+ bool rc = true;
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ setProperty(index, QVariant(QString()));
+ setChanged(index, false);
+ break;
+ case MdiAreaSubWindowTitle: // Forward to window title of subwindow
+ if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
+ const int index = cws->indexOf(m_windowTitleProperty);
+ rc = cws->reset(index);
+ }
+ break;
+ default:
+ rc = QDesignerPropertySheet::reset(index);
+ break;
+ }
+ return rc;
+}
+
+QVariant QMdiAreaPropertySheet::property(int index) const
+{
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ if (QWidget *w = currentWindow())
+ return w->objectName();
+ return QVariant(QString());
+ case MdiAreaSubWindowTitle:
+ if (QWidget *w = currentWindow())
+ return w->windowTitle();
+ return QVariant(QString());
+ case MdiAreaNone:
+ break;
+ }
+ return QDesignerPropertySheet::property(index);
+}
+
+bool QMdiAreaPropertySheet::isEnabled(int index) const
+{
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ case MdiAreaSubWindowTitle:
+ return currentWindow() != 0;
+ case MdiAreaNone:
+ break;
+ }
+ return QDesignerPropertySheet::isEnabled(index);
+}
+
+bool QMdiAreaPropertySheet::isChanged(int index) const
+{
+ bool rc = false;
+ switch (mdiAreaProperty(propertyName(index))) {
+ case MdiAreaSubWindowName:
+ rc = currentWindow() != 0;
+ break;
+ case MdiAreaSubWindowTitle:
+ if (QDesignerPropertySheetExtension *cws = currentWindowSheet()) {
+ const int index = cws->indexOf(m_windowTitleProperty);
+ rc = cws->isChanged(index);
+ }
+ break;
+ default:
+ rc = QDesignerPropertySheet::isChanged(index);
+ break;
+ }
+ return rc;
+}
+
+QWidget *QMdiAreaPropertySheet::currentWindow() const
+{
+ if (const QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), object())) {
+ const int ci = c->currentIndex();
+ if (ci < 0)
+ return 0;
+ return c->widget(ci);
+ }
+ return 0;
+}
+
+QDesignerPropertySheetExtension *QMdiAreaPropertySheet::currentWindowSheet() const
+{
+ QWidget *cw = currentWindow();
+ if (cw == 0)
+ return 0;
+ return qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), cw);
+}
+
+bool QMdiAreaPropertySheet::checkProperty(const QString &propertyName)
+{
+ return mdiAreaProperty(propertyName) == MdiAreaNone;
+}
+}
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qmdiarea_container.h b/src/designer/src/components/formeditor/qmdiarea_container.h
new file mode 100644
index 000000000..453e67109
--- /dev/null
+++ b/src/designer/src/components/formeditor/qmdiarea_container.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMDIAREA_CONTAINER_H
+#define QMDIAREA_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QMdiArea>
+#include <QtGui/QWorkspace>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// Container for QMdiArea
+class QMdiAreaContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QMdiAreaContainer(QMdiArea *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+ // Semismart positioning of a new MDI child after cascading
+ static void positionNewMdiChild(const QWidget *area, QWidget *mdiChild);
+
+private:
+ QMdiArea *m_mdiArea;
+};
+
+// PropertySheet for QMdiArea: Fakes window title and name.
+// Also works for a QWorkspace as it relies on the container extension.
+
+class QMdiAreaPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit QMdiAreaPropertySheet(QWidget *mdiArea, QObject *parent = 0);
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool reset(int index);
+ virtual bool isEnabled(int index) const;
+ virtual bool isChanged(int index) const;
+ virtual QVariant property(int index) const;
+
+ // Check whether the property is to be saved. Returns false for the page
+ // properties (as the property sheet has no concept of 'stored')
+ static bool checkProperty(const QString &propertyName);
+
+private:
+ const QString m_windowTitleProperty;
+ QWidget *currentWindow() const;
+ QDesignerPropertySheetExtension *currentWindowSheet() const;
+
+ enum MdiAreaProperty { MdiAreaSubWindowName, MdiAreaSubWindowTitle, MdiAreaNone };
+ static MdiAreaProperty mdiAreaProperty(const QString &name);
+};
+
+// Factories
+
+typedef ExtensionFactory<QDesignerContainerExtension, QMdiArea, QMdiAreaContainer> QMdiAreaContainerFactory;
+typedef QDesignerPropertySheetFactory<QMdiArea, QMdiAreaPropertySheet> QMdiAreaPropertySheetFactory;
+typedef QDesignerPropertySheetFactory<QWorkspace, QMdiAreaPropertySheet> QWorkspacePropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QMDIAREA_CONTAINER_H
diff --git a/src/designer/src/components/formeditor/qtbrushmanager.cpp b/src/designer/src/components/formeditor/qtbrushmanager.cpp
new file mode 100644
index 000000000..8cba8fa56
--- /dev/null
+++ b/src/designer/src/components/formeditor/qtbrushmanager.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtbrushmanager.h"
+#include <QtGui/QPixmap>
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QtBrushManagerPrivate
+{
+ QtBrushManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtBrushManager)
+public:
+ QMap<QString, QBrush> theBrushMap;
+ QString theCurrentBrush;
+};
+
+QtBrushManager::QtBrushManager(QObject *parent)
+ : QDesignerBrushManagerInterface(parent), d_ptr(new QtBrushManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+QtBrushManager::~QtBrushManager()
+{
+}
+
+QBrush QtBrushManager::brush(const QString &name) const
+{
+ if (d_ptr->theBrushMap.contains(name))
+ return d_ptr->theBrushMap[name];
+ return QBrush();
+}
+
+QMap<QString, QBrush> QtBrushManager::brushes() const
+{
+ return d_ptr->theBrushMap;
+}
+
+QString QtBrushManager::currentBrush() const
+{
+ return d_ptr->theCurrentBrush;
+}
+
+QString QtBrushManager::addBrush(const QString &name, const QBrush &brush)
+{
+ if (name.isNull())
+ return QString();
+
+ QString newName = name;
+ QString nameBase = newName;
+ int i = 0;
+ while (d_ptr->theBrushMap.contains(newName)) {
+ newName = nameBase + QString::number(++i);
+ }
+ d_ptr->theBrushMap[newName] = brush;
+ emit brushAdded(newName, brush);
+
+ return newName;
+}
+
+void QtBrushManager::removeBrush(const QString &name)
+{
+ if (!d_ptr->theBrushMap.contains(name))
+ return;
+ if (currentBrush() == name)
+ setCurrentBrush(QString());
+ emit brushRemoved(name);
+ d_ptr->theBrushMap.remove(name);
+}
+
+void QtBrushManager::setCurrentBrush(const QString &name)
+{
+ QBrush newBrush;
+ if (!name.isNull()) {
+ if (d_ptr->theBrushMap.contains(name))
+ newBrush = d_ptr->theBrushMap[name];
+ else
+ return;
+ }
+ d_ptr->theCurrentBrush = name;
+ emit currentBrushChanged(name, newBrush);
+}
+
+QPixmap QtBrushManager::brushPixmap(const QBrush &brush) const
+{
+ int w = 64;
+ int h = 64;
+
+ QImage img(w, h, QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, w, h), brush);
+ return QPixmap::fromImage(img);
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qtbrushmanager.h b/src/designer/src/components/formeditor/qtbrushmanager.h
new file mode 100644
index 000000000..d490523c8
--- /dev/null
+++ b/src/designer/src/components/formeditor/qtbrushmanager.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTBRUSHMANAGER_H
+#define QTBRUSHMANAGER_H
+
+#include <QtDesigner/QDesignerBrushManagerInterface>
+#include "formeditor_global.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtGui/QBrush>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QtBrushManagerPrivate;
+
+class QT_FORMEDITOR_EXPORT QtBrushManager : public QDesignerBrushManagerInterface
+{
+ Q_OBJECT
+public:
+ QtBrushManager(QObject *parent = 0);
+ ~QtBrushManager();
+
+ QBrush brush(const QString &name) const;
+ QMap<QString, QBrush> brushes() const;
+ QString currentBrush() const;
+
+ QString addBrush(const QString &name, const QBrush &brush);
+ void removeBrush(const QString &name);
+ void setCurrentBrush(const QString &name);
+
+ QPixmap brushPixmap(const QBrush &brush) const;
+
+private:
+ QScopedPointer<QtBrushManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtBrushManager)
+ Q_DISABLE_COPY(QtBrushManager)
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/components/formeditor/qwizard_container.cpp b/src/designer/src/components/formeditor/qwizard_container.cpp
new file mode 100644
index 000000000..d88bcf2f6
--- /dev/null
+++ b/src/designer/src/components/formeditor/qwizard_container.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwizard_container.h"
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QWizard>
+#include <QtGui/QWizardPage>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<int> IdList;
+typedef QList<QWizardPage *> WizardPageList;
+
+namespace qdesigner_internal {
+
+QWizardContainer::QWizardContainer(QWizard *widget, QObject *parent) :
+ QObject(parent),
+ m_wizard(widget)
+{
+}
+
+int QWizardContainer::count() const
+{
+ return m_wizard->pageIds().size();
+}
+
+QWidget *QWizardContainer::widget(int index) const
+{
+ QWidget *rc = 0;
+ if (index >= 0) {
+ const IdList idList = m_wizard->pageIds();
+ if (index < idList.size())
+ rc = m_wizard->page(idList.at(index));
+ }
+ return rc;
+}
+
+int QWizardContainer::currentIndex() const
+{
+ const IdList idList = m_wizard->pageIds();
+ const int currentId = m_wizard->currentId();
+ const int rc = idList.empty() ? -1 : idList.indexOf(currentId);
+ return rc;
+}
+
+void QWizardContainer::setCurrentIndex(int index)
+{
+ if (index < 0 || m_wizard->pageIds().empty())
+ return;
+
+ int currentIdx = currentIndex();
+
+ if (currentIdx == -1) {
+ m_wizard->restart();
+ currentIdx = currentIndex();
+ }
+
+ if (currentIdx == index)
+ return;
+
+ const int d = qAbs(index - currentIdx);
+ if (index > currentIdx) {
+ for (int i = 0; i < d; i++)
+ m_wizard->next();
+ } else {
+ for (int i = 0; i < d; i++)
+ m_wizard->back();
+ }
+}
+
+static const char *msgWrongType = "** WARNING Attempt to add oject that is not of class WizardPage to a QWizard";
+
+void QWizardContainer::addWidget(QWidget *widget)
+{
+ QWizardPage *page = qobject_cast<QWizardPage *>(widget);
+ if (!page) {
+ qWarning("%s", msgWrongType);
+ return;
+ }
+ m_wizard->addPage(page);
+ // Might be -1 after adding the first page
+ setCurrentIndex(m_wizard->pageIds().size() - 1);
+}
+
+void QWizardContainer::insertWidget(int index, QWidget *widget)
+{
+ enum { delta = 5 };
+
+ QWizardPage *newPage = qobject_cast<QWizardPage *>(widget);
+ if (!newPage) {
+ qWarning("%s", msgWrongType);
+ return;
+ }
+
+ const IdList idList = m_wizard->pageIds();
+ const int pageCount = idList.size();
+ if (index >= pageCount) {
+ addWidget(widget);
+ return;
+ }
+
+ // Insert before, reshuffle ids if required
+ const int idBefore = idList.at(index);
+ const int newId = idBefore - 1;
+ const bool needsShuffle =
+ (index == 0 && newId < 0) // At start: QWizard refuses to insert id -1
+ || (index > 0 && idList.at(index - 1) == newId); // In-between
+ if (needsShuffle) {
+ // Create a gap by shuffling pages
+ WizardPageList pageList;
+ pageList.push_back(newPage);
+ for (int i = index; i < pageCount; i++) {
+ pageList.push_back(m_wizard->page(idList.at(i)));
+ m_wizard->removePage(idList.at(i));
+ }
+ int newId = idBefore + delta;
+ const WizardPageList::const_iterator wcend = pageList.constEnd();
+ for (WizardPageList::const_iterator it = pageList.constBegin(); it != wcend; ++it) {
+ m_wizard->setPage(newId, *it);
+ newId += delta;
+ }
+ } else {
+ // Gap found, just insert
+ m_wizard->setPage(newId, newPage);
+ }
+ // Might be at -1 after adding the first page
+ setCurrentIndex(index);
+}
+
+void QWizardContainer::remove(int index)
+{
+ if (index < 0)
+ return;
+
+ const IdList idList = m_wizard->pageIds();
+ if (index >= idList.size())
+ return;
+
+ m_wizard->removePage(idList.at(index));
+ // goto next page, preferably
+ const int newSize = idList.size() - 1;
+ if (index < newSize) {
+ setCurrentIndex(index);
+ } else {
+ if (newSize > 0)
+ setCurrentIndex(newSize - 1);
+ }
+}
+
+// ---------------- QWizardPagePropertySheet
+const char *QWizardPagePropertySheet::pageIdProperty = "pageId";
+
+QWizardPagePropertySheet::QWizardPagePropertySheet(QWizardPage *object, QObject *parent) :
+ QDesignerPropertySheet(object, parent),
+ m_pageIdIndex(createFakeProperty(QLatin1String(pageIdProperty), QString()))
+{
+ setAttribute(m_pageIdIndex, true);
+}
+
+bool QWizardPagePropertySheet::reset(int index)
+{
+ if (index == m_pageIdIndex) {
+ setProperty(index, QString());
+ return true;
+ }
+ return QDesignerPropertySheet::reset(index);
+}
+
+// ---------------- QWizardPropertySheet
+QWizardPropertySheet::QWizardPropertySheet(QWizard *object, QObject *parent) :
+ QDesignerPropertySheet(object, parent),
+ m_startId(QLatin1String("startId"))
+{
+}
+
+bool QWizardPropertySheet::isVisible(int index) const
+{
+ if (propertyName(index) == m_startId)
+ return false;
+ return QDesignerPropertySheet::isVisible(index);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qwizard_container.h b/src/designer/src/components/formeditor/qwizard_container.h
new file mode 100644
index 000000000..43a1e5f62
--- /dev/null
+++ b/src/designer/src/components/formeditor/qwizard_container.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIZARD_CONTAINER_H
+#define QWIZARD_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QWizard>
+#include <QtGui/QWizardPage>
+
+QT_BEGIN_NAMESPACE
+
+class QWizardPage;
+
+namespace qdesigner_internal {
+
+// Container for QWizard. Care must be taken to position
+// the QWizard at some valid page after removal/insertion
+// as it is not used to having its pages ripped out.
+class QWizardContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QWizardContainer(QWizard *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QWizard *m_wizard;
+};
+
+// QWizardPagePropertySheet: Introduces a attribute string fake property
+// "pageId" that allows for specifying enumeration values (uic only).
+// This breaks the pattern of having a "currentSth" property for the
+// container, but was deemed to make sense here since the Page has
+// its own "title" properties.
+class QWizardPagePropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+public:
+ explicit QWizardPagePropertySheet(QWizardPage *object, QObject *parent = 0);
+
+ virtual bool reset(int index);
+
+ static const char *pageIdProperty;
+
+private:
+ const int m_pageIdIndex;
+};
+
+// QWizardPropertySheet: Hides the "startId" property. It cannot be used
+// as QWizard cannot handle setting it as a property before the actual
+// page is added.
+
+class QWizardPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+public:
+ explicit QWizardPropertySheet(QWizard *object, QObject *parent = 0);
+ virtual bool isVisible(int index) const;
+
+private:
+ const QString m_startId;
+};
+
+// Factories
+typedef QDesignerPropertySheetFactory<QWizard, QWizardPropertySheet> QWizardPropertySheetFactory;
+typedef QDesignerPropertySheetFactory<QWizardPage, QWizardPagePropertySheet> QWizardPagePropertySheetFactory;
+typedef ExtensionFactory<QDesignerContainerExtension, QWizard, QWizardContainer> QWizardContainerFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QWIZARD_CONTAINER_H
diff --git a/src/designer/src/components/formeditor/qworkspace_container.cpp b/src/designer/src/components/formeditor/qworkspace_container.cpp
new file mode 100644
index 000000000..ca7de1c56
--- /dev/null
+++ b/src/designer/src/components/formeditor/qworkspace_container.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qworkspace_container.h"
+#include "qmdiarea_container.h"
+
+#include <QtGui/QWorkspace>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QWorkspaceContainer::QWorkspaceContainer(QWorkspace *widget, QObject *parent)
+ : QObject(parent),
+ m_workspace(widget)
+{
+}
+
+int QWorkspaceContainer::count() const
+{
+ return m_workspace->windowList(QWorkspace::CreationOrder).count();
+}
+
+QWidget *QWorkspaceContainer::widget(int index) const
+{
+ if (index < 0)
+ return 0;
+ return m_workspace->windowList(QWorkspace::CreationOrder).at(index);
+}
+
+int QWorkspaceContainer::currentIndex() const
+{
+ if (QWidget *aw = m_workspace->activeWindow())
+ return m_workspace->windowList(QWorkspace::CreationOrder).indexOf(aw);
+ return -1;
+}
+
+void QWorkspaceContainer::setCurrentIndex(int index)
+{
+ m_workspace->setActiveWindow(m_workspace->windowList(QWorkspace::CreationOrder).at(index));
+}
+
+void QWorkspaceContainer::addWidget(QWidget *widget)
+{
+ QWidget *frame = m_workspace->addWindow(widget, Qt::Window);
+ frame->show();
+ m_workspace->cascade();
+ QMdiAreaContainer::positionNewMdiChild(m_workspace, frame);
+}
+
+void QWorkspaceContainer::insertWidget(int, QWidget *widget)
+{
+ addWidget(widget);
+}
+
+void QWorkspaceContainer::remove(int /* index */)
+{
+ // nothing to do here, reparenting to formwindow is apparently sufficient
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/qworkspace_container.h b/src/designer/src/components/formeditor/qworkspace_container.h
new file mode 100644
index 000000000..f595044f4
--- /dev/null
+++ b/src/designer/src/components/formeditor/qworkspace_container.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWORKSPACE_CONTAINER_H
+#define QWORKSPACE_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionFactory>
+
+#include <extensionfactory_p.h>
+#include <QtGui/QWorkspace>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QWorkspaceContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QWorkspaceContainer(QWorkspace *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QWorkspace *m_workspace;
+};
+
+typedef ExtensionFactory<QDesignerContainerExtension, QWorkspace, QWorkspaceContainer> QWorkspaceContainerFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QWORKSPACE_CONTAINER_H
diff --git a/src/designer/src/components/formeditor/spacer_propertysheet.cpp b/src/designer/src/components/formeditor/spacer_propertysheet.cpp
new file mode 100644
index 000000000..6ea37c4d4
--- /dev/null
+++ b/src/designer/src/components/formeditor/spacer_propertysheet.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "spacer_propertysheet.h"
+#include "qdesigner_widget_p.h"
+#include "formwindow.h"
+#include "spacer_widget_p.h"
+
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal
+{
+SpacerPropertySheet::SpacerPropertySheet(Spacer *object, QObject *parent)
+ : QDesignerPropertySheet(object, parent)
+{
+ clearFakeProperties();
+}
+
+SpacerPropertySheet::~SpacerPropertySheet()
+{
+}
+
+bool SpacerPropertySheet::isVisible(int index) const
+{
+ static const QString spacerGroup = QLatin1String("Spacer");
+ return propertyGroup(index) == spacerGroup;
+}
+
+void SpacerPropertySheet::setProperty(int index, const QVariant &value)
+{
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+bool SpacerPropertySheet::dynamicPropertiesAllowed() const
+{
+ return false;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/spacer_propertysheet.h b/src/designer/src/components/formeditor/spacer_propertysheet.h
new file mode 100644
index 000000000..256e3fd71
--- /dev/null
+++ b/src/designer/src/components/formeditor/spacer_propertysheet.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SPACER_PROPERTYSHEET_H
+#define SPACER_PROPERTYSHEET_H
+
+#include <qdesigner_propertysheet_p.h>
+#include <extensionfactory_p.h>
+#include <spacer_widget_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class SpacerPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit SpacerPropertySheet(Spacer *object, QObject *parent = 0);
+ virtual ~SpacerPropertySheet();
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool isVisible(int index) const;
+
+ virtual bool dynamicPropertiesAllowed() const;
+};
+
+typedef QDesignerPropertySheetFactory<Spacer, SpacerPropertySheet> SpacerPropertySheetFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SPACER_PROPERTYSHEET_H
diff --git a/src/designer/src/components/formeditor/templateoptionspage.cpp b/src/designer/src/components/formeditor/templateoptionspage.cpp
new file mode 100644
index 000000000..d81abc12d
--- /dev/null
+++ b/src/designer/src/components/formeditor/templateoptionspage.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "templateoptionspage.h"
+#include "ui_templateoptionspage.h"
+
+#include <shared_settings_p.h>
+#include <iconloader_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <abstractdialoggui_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ----------------- TemplateOptionsWidget
+TemplateOptionsWidget::TemplateOptionsWidget(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QWidget(parent),
+ m_core(core),
+ m_ui(new Ui::TemplateOptionsWidget)
+{
+ m_ui->setupUi(this);
+
+ m_ui->m_addTemplatePathButton->setIcon(
+ qdesigner_internal::createIconSet(QString::fromUtf8("plus.png")));
+ m_ui->m_removeTemplatePathButton->setIcon(
+ qdesigner_internal::createIconSet(QString::fromUtf8("minus.png")));
+
+ connect(m_ui->m_templatePathListWidget, SIGNAL(itemSelectionChanged()),
+ this, SLOT(templatePathSelectionChanged()));
+ connect(m_ui->m_addTemplatePathButton, SIGNAL(clicked()), this, SLOT(addTemplatePath()));
+ connect(m_ui->m_removeTemplatePathButton, SIGNAL(clicked()), this, SLOT(removeTemplatePath()));
+}
+
+TemplateOptionsWidget::~TemplateOptionsWidget()
+{
+ delete m_ui;
+}
+
+QStringList TemplateOptionsWidget::templatePaths() const
+{
+ QStringList rc;
+ const int count = m_ui->m_templatePathListWidget->count();
+ for (int i = 0; i < count; i++) {
+ rc += m_ui->m_templatePathListWidget->item(i)->text();
+ }
+ return rc;
+}
+
+void TemplateOptionsWidget::setTemplatePaths(const QStringList &l)
+{
+ // add paths and select 0
+ m_ui->m_templatePathListWidget->clear();
+ if (l.empty()) {
+ // disable button
+ templatePathSelectionChanged();
+ } else {
+ const QStringList::const_iterator cend = l.constEnd();
+ for (QStringList::const_iterator it = l.constBegin(); it != cend; ++it)
+ m_ui->m_templatePathListWidget->addItem(*it);
+ m_ui->m_templatePathListWidget->setCurrentItem(m_ui->m_templatePathListWidget->item(0));
+ }
+}
+
+void TemplateOptionsWidget::addTemplatePath()
+{
+ const QString templatePath = chooseTemplatePath(m_core, this);
+ if (templatePath.isEmpty())
+ return;
+
+ const QList<QListWidgetItem *> existing
+ = m_ui->m_templatePathListWidget->findItems(templatePath, Qt::MatchExactly);
+ if (!existing.empty())
+ return;
+
+ QListWidgetItem *newItem = new QListWidgetItem(templatePath);
+ m_ui->m_templatePathListWidget->addItem(newItem);
+ m_ui->m_templatePathListWidget->setCurrentItem(newItem);
+}
+
+void TemplateOptionsWidget::removeTemplatePath()
+{
+ const QList<QListWidgetItem *> selectedPaths
+ = m_ui->m_templatePathListWidget->selectedItems();
+ if (selectedPaths.empty())
+ return;
+ delete selectedPaths.front();
+}
+
+void TemplateOptionsWidget::templatePathSelectionChanged()
+{
+ const QList<QListWidgetItem *> selectedPaths = m_ui->m_templatePathListWidget->selectedItems();
+ m_ui->m_removeTemplatePathButton->setEnabled(!selectedPaths.empty());
+}
+
+QString TemplateOptionsWidget::chooseTemplatePath(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ QString rc = core->dialogGui()->getExistingDirectory(parent,
+ tr("Pick a directory to save templates in"));
+ if (rc.isEmpty())
+ return rc;
+
+ if (rc.endsWith(QDir::separator()))
+ rc.remove(rc.size() - 1, 1);
+ return rc;
+}
+
+// ----------------- TemplateOptionsPage
+TemplateOptionsPage::TemplateOptionsPage(QDesignerFormEditorInterface *core) :
+ m_core(core)
+{
+}
+
+QString TemplateOptionsPage::name() const
+{
+ //: Tab in preferences dialog
+ return QCoreApplication::translate("TemplateOptionsPage", "Template Paths");
+}
+
+QWidget *TemplateOptionsPage::createPage(QWidget *parent)
+{
+ m_widget = new TemplateOptionsWidget(m_core, parent);
+ m_initialTemplatePaths = QDesignerSharedSettings(m_core).additionalFormTemplatePaths();
+ m_widget->setTemplatePaths(m_initialTemplatePaths);
+ return m_widget;
+}
+
+void TemplateOptionsPage::apply()
+{
+ if (m_widget) {
+ const QStringList newTemplatePaths = m_widget->templatePaths();
+ if (newTemplatePaths != m_initialTemplatePaths) {
+ QDesignerSharedSettings settings(m_core);
+ settings.setAdditionalFormTemplatePaths(newTemplatePaths);
+ m_initialTemplatePaths = newTemplatePaths;
+ }
+ }
+}
+
+void TemplateOptionsPage::finish()
+{
+}
+}
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/templateoptionspage.h b/src/designer/src/components/formeditor/templateoptionspage.h
new file mode 100644
index 000000000..98d468caa
--- /dev/null
+++ b/src/designer/src/components/formeditor/templateoptionspage.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_TEMPLATEOPTIONS_H
+#define QDESIGNER_TEMPLATEOPTIONS_H
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+
+#include <QtCore/QPointer>
+#include <QtCore/QStringList>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+namespace Ui {
+ class TemplateOptionsWidget;
+}
+
+/* Present the user with a list of form template paths to save
+ * form templates. */
+class TemplateOptionsWidget : public QWidget
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(TemplateOptionsWidget)
+public:
+ explicit TemplateOptionsWidget(QDesignerFormEditorInterface *core,
+ QWidget *parent = 0);
+ ~TemplateOptionsWidget();
+
+
+ QStringList templatePaths() const;
+ void setTemplatePaths(const QStringList &l);
+
+ static QString chooseTemplatePath(QDesignerFormEditorInterface *core, QWidget *parent);
+
+private slots:
+ void addTemplatePath();
+ void removeTemplatePath();
+ void templatePathSelectionChanged();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ Ui::TemplateOptionsWidget *m_ui;
+};
+
+class TemplateOptionsPage : public QDesignerOptionsPageInterface
+{
+ Q_DISABLE_COPY(TemplateOptionsPage)
+public:
+ explicit TemplateOptionsPage(QDesignerFormEditorInterface *core);
+
+ virtual QString name() const;
+ virtual QWidget *createPage(QWidget *parent);
+ virtual void apply();
+ virtual void finish();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ QStringList m_initialTemplatePaths;
+ QPointer<TemplateOptionsWidget> m_widget;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_TEMPLATEOPTIONS_H
diff --git a/src/designer/src/components/formeditor/templateoptionspage.ui b/src/designer/src/components/formeditor/templateoptionspage.ui
new file mode 100644
index 000000000..3427ffeb8
--- /dev/null
+++ b/src/designer/src/components/formeditor/templateoptionspage.ui
@@ -0,0 +1,59 @@
+<ui version="4.0" >
+ <class>qdesigner_internal::TemplateOptionsWidget</class>
+ <widget class="QWidget" name="qdesigner_internal::TemplateOptionsWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>376</width>
+ <height>387</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="m_templatePathGroupBox" >
+ <property name="title" >
+ <string>Additional Template Paths</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="3" >
+ <widget class="QListWidget" name="m_templatePathListWidget" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QToolButton" name="m_addTemplatePathButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QToolButton" name="m_removeTemplatePathButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/components/formeditor/tool_widgeteditor.cpp b/src/designer/src/components/formeditor/tool_widgeteditor.cpp
new file mode 100644
index 000000000..456967f59
--- /dev/null
+++ b/src/designer/src/components/formeditor/tool_widgeteditor.cpp
@@ -0,0 +1,363 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tool_widgeteditor.h"
+#include "formwindow.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+
+#include <layoutinfo_p.h>
+#include <qdesigner_dnditem_p.h>
+#include <qdesigner_resource.h>
+
+#include <QtGui/qevent.h>
+#include <QtGui/QAction>
+#include <QtGui/QMainWindow>
+#include <QtGui/QCursor>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+WidgetEditorTool::WidgetEditorTool(FormWindow *formWindow)
+ : QDesignerFormWindowToolInterface(formWindow),
+ m_formWindow(formWindow),
+ m_action(new QAction(tr("Edit Widgets"), this)),
+ m_specialDockDrag(false)
+{
+}
+
+QAction *WidgetEditorTool::action() const
+{
+ return m_action;
+}
+
+WidgetEditorTool::~WidgetEditorTool()
+{
+}
+
+QDesignerFormEditorInterface *WidgetEditorTool::core() const
+{
+ return m_formWindow->core();
+}
+
+QDesignerFormWindowInterface *WidgetEditorTool::formWindow() const
+{
+ return m_formWindow;
+}
+
+bool WidgetEditorTool::mainWindowSeparatorEvent(QWidget *widget, QEvent *event)
+{
+ QMainWindow *mw = qobject_cast<QMainWindow*>(widget);
+ if (mw == 0)
+ return false;
+
+ if (event->type() != QEvent::MouseButtonPress
+ && event->type() != QEvent::MouseMove
+ && event->type() != QEvent::MouseButtonRelease)
+ return false;
+
+ QMouseEvent *e = static_cast<QMouseEvent*>(event);
+
+ if (event->type() == QEvent::MouseButtonPress) {
+ if (mw->isSeparator(e->pos())) {
+ m_separator_drag_mw = mw;
+ return true;
+ }
+ return false;
+ }
+
+ if (event->type() == QEvent::MouseMove)
+ return m_separator_drag_mw == mw;
+
+ if (event->type() == QEvent::MouseButtonRelease) {
+ if (m_separator_drag_mw != mw)
+ return false;
+ m_separator_drag_mw = 0;
+ return true;
+ }
+
+ return false;
+}
+
+bool WidgetEditorTool::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
+{
+ const bool passive = core()->widgetFactory()->isPassiveInteractor(widget) != 0
+ || mainWindowSeparatorEvent(widget, event); // separators in QMainWindow
+ // are no longer widgets
+ switch (event->type()) {
+ case QEvent::Resize:
+ case QEvent::Move:
+ m_formWindow->updateSelection(widget);
+ break;
+
+ case QEvent::FocusOut:
+ case QEvent::FocusIn: // Popup cancelled over a form widget: Reset its focus frame
+ return !(passive || widget == m_formWindow || widget == m_formWindow->mainContainer());
+
+ case QEvent::Wheel: // Prevent spinboxes and combos from reacting
+ return !passive;
+
+ case QEvent::KeyPress:
+ return !passive && handleKeyPressEvent(widget, managedWidget, static_cast<QKeyEvent*>(event));
+
+ case QEvent::KeyRelease:
+ return !passive && handleKeyReleaseEvent(widget, managedWidget, static_cast<QKeyEvent*>(event));
+
+ case QEvent::MouseMove:
+ return !passive && handleMouseMoveEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
+
+ case QEvent::MouseButtonPress:
+ return !passive && handleMousePressEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
+
+ case QEvent::MouseButtonRelease:
+ return !passive && handleMouseReleaseEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
+
+ case QEvent::MouseButtonDblClick:
+ return !passive && handleMouseButtonDblClickEvent(widget, managedWidget, static_cast<QMouseEvent*>(event));
+
+ case QEvent::ContextMenu:
+ return !passive && handleContextMenu(widget, managedWidget, static_cast<QContextMenuEvent*>(event));
+
+ case QEvent::DragEnter:
+ return handleDragEnterMoveEvent(widget, managedWidget, static_cast<QDragEnterEvent *>(event), true);
+ case QEvent::DragMove:
+ return handleDragEnterMoveEvent(widget, managedWidget, static_cast<QDragEnterEvent *>(event), false);
+ case QEvent::DragLeave:
+ return handleDragLeaveEvent(widget, managedWidget, static_cast<QDragLeaveEvent *>(event));
+ case QEvent::Drop:
+ return handleDropEvent(widget, managedWidget, static_cast<QDropEvent *>(event));
+ default:
+ break;
+
+ } // end switch
+
+ return false;
+}
+
+// ### remove me
+
+bool WidgetEditorTool::handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e)
+{
+ return m_formWindow->handleContextMenu(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ return m_formWindow->handleMouseButtonDblClickEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ return m_formWindow->handleMousePressEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ return m_formWindow->handleMouseMoveEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e)
+{
+ return m_formWindow->handleMouseReleaseEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e)
+{
+ return m_formWindow->handleKeyPressEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e)
+{
+ return m_formWindow->handleKeyReleaseEvent(widget, managedWidget, e);
+}
+
+bool WidgetEditorTool::handlePaintEvent(QWidget *widget, QWidget *managedWidget, QPaintEvent *e)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(managedWidget);
+ Q_UNUSED(e);
+
+ return false;
+}
+
+void WidgetEditorTool::detectDockDrag(const QDesignerMimeData *mimeData)
+{
+ m_specialDockDrag = false;
+ if (!mimeData)
+ return;
+
+ QMainWindow *mw = qobject_cast<QMainWindow*>(m_formWindow->mainContainer());
+ if (!mw)
+ return;
+
+ const QList<QDesignerDnDItemInterface*> item_list = mimeData->items();
+
+ foreach (QDesignerDnDItemInterface *item, item_list) {
+ if (item->decoration() && item->decoration()->property("_q_dockDrag").toBool())
+ m_specialDockDrag = true;
+
+ }
+}
+
+bool WidgetEditorTool::handleDragEnterMoveEvent(QWidget *widget, QWidget * /*managedWidget*/, QDragMoveEvent *e, bool isEnter)
+{
+ const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(e->mimeData());
+ if (!mimeData)
+ return false;
+
+ if (!m_formWindow->hasFeature(QDesignerFormWindowInterface::EditFeature)) {
+ e->ignore();
+ return true;
+ }
+
+ if (isEnter)
+ detectDockDrag(mimeData);
+
+
+ QPoint globalPos = QPoint(0, 0);
+ if (m_specialDockDrag) {
+ m_lastDropTarget = 0;
+ QMainWindow *mw = qobject_cast<QMainWindow*>(m_formWindow->mainContainer());
+ if (mw)
+ m_lastDropTarget = mw->centralWidget();
+ } else {
+ // If custom widgets have acceptDrops=true, the event occurs for them
+ const QPoint formPos = widget != m_formWindow ? widget->mapTo(m_formWindow, e->pos()) : e->pos();
+ globalPos = m_formWindow->mapToGlobal(formPos);
+ const FormWindowBase::WidgetUnderMouseMode wum = mimeData->items().size() == 1 ? FormWindowBase::FindSingleSelectionDropTarget : FormWindowBase::FindMultiSelectionDropTarget;
+ QWidget *dropTarget = m_formWindow->widgetUnderMouse(formPos, wum);
+ if (m_lastDropTarget && dropTarget != m_lastDropTarget)
+ m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(globalPos), FormWindow::Restore);
+ m_lastDropTarget = dropTarget;
+ }
+
+ if (m_lastDropTarget)
+ m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(globalPos), FormWindow::Highlight);
+
+ if (isEnter || m_lastDropTarget)
+ mimeData->acceptEvent(e);
+ else
+ e->ignore();
+ return true;
+}
+
+bool WidgetEditorTool::handleDropEvent(QWidget *widget, QWidget *, QDropEvent *e)
+{
+ const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(e->mimeData());
+ if (!mimeData)
+ return false;
+
+ if (!m_lastDropTarget ||
+ !m_formWindow->hasFeature(QDesignerFormWindowInterface::EditFeature)) {
+ e->ignore();
+ return true;
+ }
+ // FormWindow determines the position from the decoration.
+ const QPoint globalPos = widget->mapToGlobal(e->pos());
+ mimeData->moveDecoration(globalPos);
+ if (m_specialDockDrag) {
+ if (!m_formWindow->dropDockWidget(mimeData->items().at(0), globalPos)) {
+ e->ignore();
+ return true;
+ }
+ } else if (!m_formWindow->dropWidgets(mimeData->items(), m_lastDropTarget, globalPos)) {
+ e->ignore();
+ return true;
+ }
+ mimeData->acceptEvent(e);
+ return true;
+}
+
+bool WidgetEditorTool::restoreDropHighlighting()
+{
+ if (!m_lastDropTarget)
+ return false;
+
+ m_formWindow->highlightWidget(m_lastDropTarget, m_lastDropTarget->mapFromGlobal(QCursor::pos()), FormWindow::Restore);
+ m_lastDropTarget = 0;
+ return true;
+}
+
+bool WidgetEditorTool::handleDragLeaveEvent(QWidget *, QWidget *, QDragLeaveEvent *event)
+{
+ if (restoreDropHighlighting()) {
+ event->accept();
+ return true;
+ }
+ return false;
+}
+
+QWidget *WidgetEditorTool::editor() const
+{
+ Q_ASSERT(formWindow() != 0);
+ return formWindow()->mainContainer();
+}
+
+void WidgetEditorTool::activated()
+{
+ if (core()->widgetBox())
+ core()->widgetBox()->setEnabled(true);
+
+ if (m_formWindow == 0)
+ return;
+
+ QList<QWidget*> sel = m_formWindow->selectedWidgets();
+ foreach (QWidget *w, sel)
+ m_formWindow->raiseSelection(w);
+}
+
+void WidgetEditorTool::deactivated()
+{
+ if (core()->widgetBox())
+ core()->widgetBox()->setEnabled(false);
+
+ if (m_formWindow == 0)
+ return;
+
+ m_formWindow->clearSelection();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/tool_widgeteditor.h b/src/designer/src/components/formeditor/tool_widgeteditor.h
new file mode 100644
index 000000000..369c2fc14
--- /dev/null
+++ b/src/designer/src/components/formeditor/tool_widgeteditor.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOOL_WIDGETEDITOR_H
+#define TOOL_WIDGETEDITOR_H
+
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+
+#include <QtGui/qevent.h>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QMainWindow;
+
+namespace qdesigner_internal {
+
+class FormWindow;
+class QDesignerMimeData;
+
+class WidgetEditorTool: public QDesignerFormWindowToolInterface
+{
+ Q_OBJECT
+public:
+ explicit WidgetEditorTool(FormWindow *formWindow);
+ virtual ~WidgetEditorTool();
+
+ virtual QDesignerFormEditorInterface *core() const;
+ virtual QDesignerFormWindowInterface *formWindow() const;
+ virtual QWidget *editor() const;
+ virtual QAction *action() const;
+
+ virtual void activated();
+ virtual void deactivated();
+
+ virtual bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event);
+
+ bool handleContextMenu(QWidget *widget, QWidget *managedWidget, QContextMenuEvent *e);
+ bool handleMouseButtonDblClickEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMousePressEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMouseMoveEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleMouseReleaseEvent(QWidget *widget, QWidget *managedWidget, QMouseEvent *e);
+ bool handleKeyPressEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e);
+ bool handleKeyReleaseEvent(QWidget *widget, QWidget *managedWidget, QKeyEvent *e);
+ bool handlePaintEvent(QWidget *widget, QWidget *managedWidget, QPaintEvent *e);
+
+ bool handleDragEnterMoveEvent(QWidget *widget, QWidget *managedWidget, QDragMoveEvent *e, bool isEnter);
+ bool handleDragLeaveEvent(QWidget *widget, QWidget *managedWidget, QDragLeaveEvent *e);
+ bool handleDropEvent(QWidget *widget, QWidget *managedWidget, QDropEvent *e);
+
+private:
+ bool restoreDropHighlighting();
+ void detectDockDrag(const QDesignerMimeData *mimeData);
+
+ FormWindow *m_formWindow;
+ QAction *m_action;
+
+ bool mainWindowSeparatorEvent(QWidget *widget, QEvent *event);
+ QPointer<QMainWindow> m_separator_drag_mw;
+ QPointer<QWidget> m_lastDropTarget;
+ bool m_specialDockDrag;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TOOL_WIDGETEDITOR_H
diff --git a/src/designer/src/components/formeditor/widgetselection.cpp b/src/designer/src/components/formeditor/widgetselection.cpp
new file mode 100644
index 000000000..501859130
--- /dev/null
+++ b/src/designer/src/components/formeditor/widgetselection.cpp
@@ -0,0 +1,746 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "widgetselection.h"
+#include "formwindow.h"
+#include "formwindowmanager.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+// shared
+#include <qdesigner_command_p.h>
+#include <qdesigner_propertycommand_p.h>
+#include <layout_p.h>
+#include <layoutinfo_p.h>
+#include <formwindowbase_p.h>
+#include <grid_p.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QWidget>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QStylePainter>
+#include <QtGui/QGridLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QStyleOptionToolButton>
+#include <QtGui/QApplication>
+
+#include <QtCore/QVariant>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+enum { debugWidgetSelection = 0 };
+
+// Return the layout the widget is in
+template <class Layout>
+static inline Layout *managedLayoutOf(const QDesignerFormEditorInterface *core,
+ QWidget *w,
+ const Layout * /* vs6dummy */ = 0)
+{
+ if (QWidget *p = w->parentWidget())
+ if (QLayout *l = LayoutInfo::managedLayout(core, p))
+ return qobject_cast<Layout*>(l);
+ return 0;
+}
+
+// ----------- WidgetHandle
+WidgetHandle::WidgetHandle(FormWindow *parent, WidgetHandle::Type t, WidgetSelection *s) :
+ InvisibleWidget(parent->formContainer()),
+ m_widget(0),
+ m_type(t),
+ m_formWindow( parent),
+ m_sel(s),
+ m_active(true)
+{
+ setMouseTracking(false);
+ setAutoFillBackground(true);
+
+ setBackgroundRole(m_active ? QPalette::Text : QPalette::Dark);
+ setFixedSize(6, 6);
+
+ updateCursor();
+}
+
+void WidgetHandle::updateCursor()
+{
+#ifndef QT_NO_CURSOR
+ if (!m_active) {
+ setCursor(Qt::ArrowCursor);
+ return;
+ }
+
+ switch (m_type) {
+ case LeftTop:
+ setCursor(Qt::SizeFDiagCursor);
+ break;
+ case Top:
+ setCursor(Qt::SizeVerCursor);
+ break;
+ case RightTop:
+ setCursor(Qt::SizeBDiagCursor);
+ break;
+ case Right:
+ setCursor(Qt::SizeHorCursor);
+ break;
+ case RightBottom:
+ setCursor(Qt::SizeFDiagCursor);
+ break;
+ case Bottom:
+ setCursor(Qt::SizeVerCursor);
+ break;
+ case LeftBottom:
+ setCursor(Qt::SizeBDiagCursor);
+ break;
+ case Left:
+ setCursor(Qt::SizeHorCursor);
+ break;
+ default:
+ Q_ASSERT(0);
+ }
+#endif
+}
+
+QDesignerFormEditorInterface *WidgetHandle::core() const
+{
+ if (m_formWindow)
+ return m_formWindow->core();
+
+ return 0;
+}
+
+void WidgetHandle::setActive(bool a)
+{
+ m_active = a;
+ setBackgroundRole(m_active ? QPalette::Text : QPalette::Dark);
+ updateCursor();
+}
+
+void WidgetHandle::setWidget(QWidget *w)
+{
+ m_widget = w;
+}
+
+void WidgetHandle::paintEvent(QPaintEvent *)
+{
+ QDesignerFormWindowManagerInterface *m = m_formWindow->core()->formWindowManager();
+
+ QStylePainter p(this);
+ if (m_formWindow->currentWidget() == m_widget) {
+ p.setPen(m->activeFormWindow() == m_formWindow ? Qt::blue : Qt::red);
+ p.drawRect(0, 0, width() - 1, height() - 1);
+ }
+}
+
+void WidgetHandle::mousePressEvent(QMouseEvent *e)
+{
+ e->accept();
+
+ if (!m_formWindow->hasFeature(FormWindow::EditFeature))
+ return;
+
+ if (!(m_widget && e->button() == Qt::LeftButton))
+ return;
+
+ if (!(m_active))
+ return;
+
+ QWidget *container = m_widget->parentWidget();
+
+ m_origPressPos = container->mapFromGlobal(e->globalPos());
+ m_geom = m_origGeom = m_widget->geometry();
+}
+
+void WidgetHandle::mouseMoveEvent(QMouseEvent *e)
+{
+ if (!(m_widget && m_active && e->buttons() & Qt::LeftButton))
+ return;
+
+ e->accept();
+
+ QWidget *container = m_widget->parentWidget();
+
+ const QPoint rp = container->mapFromGlobal(e->globalPos());
+ const QPoint d = rp - m_origPressPos;
+
+ const QRect pr = container->rect();
+
+ qdesigner_internal::Grid grid;
+ if (const qdesigner_internal::FormWindowBase *fwb = qobject_cast<const qdesigner_internal::FormWindowBase*>(m_formWindow))
+ grid = fwb->designerGrid();
+
+ switch (m_type) {
+
+ case LeftTop: {
+ if (rp.x() > pr.width() - 2 * width() || rp.y() > pr.height() - 2 * height())
+ return;
+
+ int w = m_origGeom.width() - d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ int h = m_origGeom.height() - d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ const int dx = m_widget->width() - w;
+ const int dy = m_widget->height() - h;
+
+ trySetGeometry(m_widget, m_widget->x() + dx, m_widget->y() + dy, w, h);
+ } break;
+
+ case Top: {
+ if (rp.y() > pr.height() - 2 * height())
+ return;
+
+ int h = m_origGeom.height() - d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ const int dy = m_widget->height() - h;
+ trySetGeometry(m_widget, m_widget->x(), m_widget->y() + dy, m_widget->width(), h);
+ } break;
+
+ case RightTop: {
+ if (rp.x() < 2 * width() || rp.y() > pr.height() - 2 * height())
+ return;
+
+ int h = m_origGeom.height() - d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ const int dy = m_widget->height() - h;
+
+ int w = m_origGeom.width() + d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ trySetGeometry(m_widget, m_widget->x(), m_widget->y() + dy, w, h);
+ } break;
+
+ case Right: {
+ if (rp.x() < 2 * width())
+ return;
+
+ int w = m_origGeom.width() + d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ tryResize(m_widget, w, m_widget->height());
+ } break;
+
+ case RightBottom: {
+ if (rp.x() < 2 * width() || rp.y() < 2 * height())
+ return;
+
+ int w = m_origGeom.width() + d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ int h = m_origGeom.height() + d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ tryResize(m_widget, w, h);
+ } break;
+
+ case Bottom: {
+ if (rp.y() < 2 * height())
+ return;
+
+ int h = m_origGeom.height() + d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ tryResize(m_widget, m_widget->width(), h);
+ } break;
+
+ case LeftBottom: {
+ if (rp.x() > pr.width() - 2 * width() || rp.y() < 2 * height())
+ return;
+
+ int w = m_origGeom.width() - d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ int h = m_origGeom.height() + d.y();
+ m_geom.setHeight(h);
+ h = grid.widgetHandleAdjustY(h);
+
+ int dx = m_widget->width() - w;
+
+ trySetGeometry(m_widget, m_widget->x() + dx, m_widget->y(), w, h);
+ } break;
+
+ case Left: {
+ if (rp.x() > pr.width() - 2 * width())
+ return;
+
+ int w = m_origGeom.width() - d.x();
+ m_geom.setWidth(w);
+ w = grid.widgetHandleAdjustX(w);
+
+ const int dx = m_widget->width() - w;
+
+ trySetGeometry(m_widget, m_widget->x() + dx, m_widget->y(), w, m_widget->height());
+ } break;
+
+ default: break;
+
+ } // end switch
+
+ m_sel->updateGeometry();
+
+ if (LayoutInfo::layoutType(m_formWindow->core(), m_widget) != LayoutInfo::NoLayout)
+ m_formWindow->updateChildSelections(m_widget);
+}
+
+void WidgetHandle::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton || !m_active)
+ return;
+
+ e->accept();
+
+ if (!m_formWindow->hasFeature(FormWindow::EditFeature))
+ return;
+
+ switch (WidgetSelection::widgetState(m_formWindow->core(), m_widget)) {
+ case WidgetSelection::UnlaidOut:
+ if (m_geom != m_widget->geometry()) {
+ SetPropertyCommand *cmd = new SetPropertyCommand(m_formWindow);
+ cmd->init(m_widget, QLatin1String("geometry"), m_widget->geometry());
+ cmd->setOldValue(m_origGeom);
+ m_formWindow->commandHistory()->push(cmd);
+ m_formWindow->emitSelectionChanged();
+ }
+ break;
+ case WidgetSelection::LaidOut:
+ break;
+ case WidgetSelection::ManagedGridLayout:
+ changeGridLayoutItemSpan();
+ break;
+ case WidgetSelection::ManagedFormLayout:
+ changeFormLayoutItemSpan();
+ break;
+ }
+}
+
+// Match the left/right widget handle mouse movements to form layout span-changing operations
+static inline int formLayoutLeftHandleOperation(int dx, unsigned possibleOperations)
+{
+ if (dx < 0) {
+ if (possibleOperations & ChangeFormLayoutItemRoleCommand::FieldToSpanning)
+ return ChangeFormLayoutItemRoleCommand::FieldToSpanning;
+ return 0;
+ }
+ if (possibleOperations & ChangeFormLayoutItemRoleCommand::SpanningToField)
+ return ChangeFormLayoutItemRoleCommand::SpanningToField;
+ return 0;
+}
+
+static inline int formLayoutRightHandleOperation(int dx, unsigned possibleOperations)
+{
+ if (dx < 0) {
+ if (possibleOperations & ChangeFormLayoutItemRoleCommand::SpanningToLabel)
+ return ChangeFormLayoutItemRoleCommand::SpanningToLabel;
+ return 0;
+ }
+ if (possibleOperations & ChangeFormLayoutItemRoleCommand::LabelToSpanning)
+ return ChangeFormLayoutItemRoleCommand::LabelToSpanning;
+ return 0;
+}
+
+// Change form layout item horizontal span
+void WidgetHandle::changeFormLayoutItemSpan()
+{
+ QUndoCommand *cmd = 0;
+ // Figure out command according to the movement
+ const int dx = m_widget->geometry().center().x() - m_origGeom.center().x();
+ if (qAbs(dx) >= QApplication::startDragDistance()) {
+ int operation = 0;
+ if (const unsigned possibleOperations = ChangeFormLayoutItemRoleCommand::possibleOperations(m_formWindow->core(), m_widget)) {
+ switch (m_type) {
+ case WidgetHandle::Left:
+ operation = formLayoutLeftHandleOperation(dx, possibleOperations);
+ break;
+ case WidgetHandle::Right:
+ operation = formLayoutRightHandleOperation(dx, possibleOperations);
+ break;
+ default:
+ break;
+ }
+ if (operation) {
+ ChangeFormLayoutItemRoleCommand *fcmd = new ChangeFormLayoutItemRoleCommand(m_formWindow);
+ fcmd->init(m_widget, static_cast<ChangeFormLayoutItemRoleCommand::Operation>(operation));
+ cmd = fcmd;
+ }
+ }
+ }
+ if (cmd) {
+ m_formWindow->commandHistory()->push(cmd);
+ } else {
+ // Cancelled/Invalid. Restore the size of the widget.
+ if (QFormLayout *form = managedLayoutOf<QFormLayout>(m_formWindow->core(), m_widget)) {
+ form->invalidate();
+ form->activate();
+ m_formWindow->clearSelection(false);
+ m_formWindow->selectWidget(m_widget);
+ }
+ }
+}
+
+void WidgetHandle::changeGridLayoutItemSpan()
+{
+ QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core()->extensionManager(), m_widget->parentWidget());
+ if (!deco)
+ return;
+ QGridLayout *grid = managedLayoutOf<QGridLayout>(m_formWindow->core(), m_widget);
+ if (!grid)
+ return;
+
+ const QSize size = m_widget->parentWidget()->size();
+
+ const int index = deco->indexOf(m_widget);
+ const QRect info = deco->itemInfo(index);
+ const int top = deco->findItemAt(info.top() - 1, info.left());
+ const int left = deco->findItemAt(info.top(), info.left() - 1);
+ const int bottom = deco->findItemAt(info.bottom() + 1, info.left());
+ const int right = deco->findItemAt(info.top(), info.right() + 1);
+
+ const QPoint pt = m_origGeom.center() - m_widget->geometry().center();
+
+ ChangeLayoutItemGeometry *cmd = 0;
+
+ switch (m_type) {
+ default:
+ break;
+
+ case WidgetHandle::Top: {
+ if (pt.y() < 0 && info.height() > 1) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y() + 1, info.x(), info.height() - 1, info.width());
+ } else if (pt.y() > 0 && top != -1 && grid->itemAt(top)->spacerItem()) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y() - 1, info.x(), info.height() + 1, info.width());
+ }
+ }
+ break;
+
+ case WidgetHandle::Left: {
+ if (pt.x() < 0 && info.width() > 1) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x() + 1, info.height(), info.width() - 1);
+ } else if (pt.x() > 0 && left != -1 && grid->itemAt(left)->spacerItem()) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x() - 1, info.height(), info.width() + 1);
+ }
+ }
+ break;
+
+ case WidgetHandle::Right: {
+ if (pt.x() > 0 && info.width() > 1) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x(), info.height(), info.width() - 1);
+ } else if (pt.x() < 0 && right != -1 && grid->itemAt(right)->spacerItem()) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x(), info.height(), info.width() + 1);
+ }
+ }
+ break;
+
+ case WidgetHandle::Bottom: {
+ if (pt.y() > 0 && info.width() > 1) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x(), info.height() - 1, info.width());
+ } else if (pt.y() < 0 && bottom != -1 && grid->itemAt(bottom)->spacerItem()) {
+ cmd = new ChangeLayoutItemGeometry(m_formWindow);
+ cmd->init(m_widget, info.y(), info.x(), info.height() + 1, info.width());
+ }
+ }
+ break;
+ }
+
+ if (cmd != 0) {
+ m_formWindow->commandHistory()->push(cmd);
+ } else {
+ grid->invalidate();
+ grid->activate();
+ m_formWindow->clearSelection(false);
+ m_formWindow->selectWidget(m_widget);
+ }
+}
+
+void WidgetHandle::trySetGeometry(QWidget *w, int x, int y, int width, int height)
+{
+ if (!m_formWindow->hasFeature(FormWindow::EditFeature))
+ return;
+
+ int minw = w->minimumSize().width();
+ minw = qMax(minw, 2 * m_formWindow->grid().x());
+
+ int minh = w->minimumSize().height();
+ minh = qMax(minh, 2 * m_formWindow->grid().y());
+
+ if (qMax(minw, width) > w->maximumWidth() ||
+ qMax(minh, height) > w->maximumHeight())
+ return;
+
+ if (width < minw && x != w->x())
+ x -= minw - width;
+
+ if (height < minh && y != w->y())
+ y -= minh - height;
+
+ w->setGeometry(x, y, qMax(minw, width), qMax(minh, height));
+}
+
+void WidgetHandle::tryResize(QWidget *w, int width, int height)
+{
+ int minw = w->minimumSize().width();
+ minw = qMax(minw, 16);
+
+ int minh = w->minimumSize().height();
+ minh = qMax(minh, 16);
+
+ w->resize(qMax(minw, width), qMax(minh, height));
+}
+
+// ------------------ WidgetSelection
+
+WidgetSelection::WidgetState WidgetSelection::widgetState(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ bool isManaged;
+ const LayoutInfo::Type lt = LayoutInfo::laidoutWidgetType(core, w, &isManaged);
+ if (lt == LayoutInfo::NoLayout)
+ return UnlaidOut;
+ if (!isManaged)
+ return LaidOut;
+ switch (lt) {
+ case LayoutInfo::Grid:
+ return ManagedGridLayout;
+ case LayoutInfo::Form:
+ return ManagedFormLayout;
+ default:
+ break;
+ }
+ return LaidOut;
+}
+
+WidgetSelection::WidgetSelection(FormWindow *parent) :
+ m_widget(0),
+ m_formWindow(parent)
+{
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i)
+ m_handles[i] = new WidgetHandle(m_formWindow, static_cast<WidgetHandle::Type>(i), this);
+ hide();
+}
+
+void WidgetSelection::setWidget(QWidget *w)
+{
+ if (m_widget != 0)
+ m_widget->removeEventFilter(this);
+
+ if (w == 0) {
+ hide();
+ m_widget = 0;
+ return;
+ }
+
+ m_widget = w;
+
+ m_widget->installEventFilter(this);
+
+ updateActive();
+
+ updateGeometry();
+ show();
+}
+
+void WidgetSelection::updateActive()
+{
+ const WidgetState ws = widgetState(m_formWindow->core(), m_widget);
+ bool active[WidgetHandle::TypeCount];
+ qFill(active, active + WidgetHandle::TypeCount, false);
+ // Determine active handles
+ switch (ws) {
+ case UnlaidOut:
+ qFill(active, active + WidgetHandle::TypeCount, true);
+ break;
+ case ManagedGridLayout: // Grid: Allow changing span
+ active[WidgetHandle::Left] = active[WidgetHandle::Top] = active[WidgetHandle::Right] = active[WidgetHandle::Bottom] = true;
+ break;
+ case ManagedFormLayout: // Form: Allow changing column span
+ if (const unsigned operation = ChangeFormLayoutItemRoleCommand::possibleOperations(m_formWindow->core(), m_widget)) {
+ active[WidgetHandle::Left] = operation & (ChangeFormLayoutItemRoleCommand::SpanningToField|ChangeFormLayoutItemRoleCommand::FieldToSpanning);
+ active[WidgetHandle::Right] = operation & (ChangeFormLayoutItemRoleCommand::SpanningToLabel|ChangeFormLayoutItemRoleCommand::LabelToSpanning);
+ }
+ break;
+ default:
+ break;
+ }
+
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i)
+ if (WidgetHandle *h = m_handles[i]) {
+ h->setWidget(m_widget);
+ h->setActive(active[i]);
+ }
+}
+
+bool WidgetSelection::isUsed() const
+{
+ return m_widget != 0;
+}
+
+void WidgetSelection::updateGeometry()
+{
+ if (!m_widget || !m_widget->parentWidget())
+ return;
+
+ QPoint p = m_widget->parentWidget()->mapToGlobal(m_widget->pos());
+ p = m_formWindow->formContainer()->mapFromGlobal(p);
+ const QRect r(p, m_widget->size());
+
+ const int w = 6;
+ const int h = 6;
+
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i) {
+ WidgetHandle *hndl = m_handles[ i ];
+ if (!hndl)
+ continue;
+ switch (i) {
+ case WidgetHandle::LeftTop:
+ hndl->move(r.x() - w / 2, r.y() - h / 2);
+ break;
+ case WidgetHandle::Top:
+ hndl->move(r.x() + r.width() / 2 - w / 2, r.y() - h / 2);
+ break;
+ case WidgetHandle::RightTop:
+ hndl->move(r.x() + r.width() - w / 2, r.y() - h / 2);
+ break;
+ case WidgetHandle::Right:
+ hndl->move(r.x() + r.width() - w / 2, r.y() + r.height() / 2 - h / 2);
+ break;
+ case WidgetHandle::RightBottom:
+ hndl->move(r.x() + r.width() - w / 2, r.y() + r.height() - h / 2);
+ break;
+ case WidgetHandle::Bottom:
+ hndl->move(r.x() + r.width() / 2 - w / 2, r.y() + r.height() - h / 2);
+ break;
+ case WidgetHandle::LeftBottom:
+ hndl->move(r.x() - w / 2, r.y() + r.height() - h / 2);
+ break;
+ case WidgetHandle::Left:
+ hndl->move(r.x() - w / 2, r.y() + r.height() / 2 - h / 2);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void WidgetSelection::hide()
+{
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i) {
+ WidgetHandle *h = m_handles[ i ];
+ if (h)
+ h->hide();
+ }
+}
+
+void WidgetSelection::show()
+{
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i) {
+ WidgetHandle *h = m_handles[ i ];
+ if (h) {
+ h->show();
+ h->raise();
+ }
+ }
+}
+
+void WidgetSelection::update()
+{
+ for (int i = WidgetHandle::LeftTop; i < WidgetHandle::TypeCount; ++i) {
+ WidgetHandle *h = m_handles[ i ];
+ if (h)
+ h->update();
+ }
+}
+
+QWidget *WidgetSelection::widget() const
+{
+ return m_widget;
+}
+
+QDesignerFormEditorInterface *WidgetSelection::core() const
+{
+ if (m_formWindow)
+ return m_formWindow->core();
+
+ return 0;
+}
+
+bool WidgetSelection::eventFilter(QObject *object, QEvent *event)
+{
+ if (object != widget())
+ return false;
+
+ switch (event->type()) {
+ default: break;
+
+ case QEvent::Move:
+ case QEvent::Resize:
+ updateGeometry();
+ break;
+ case QEvent::ZOrderChange:
+ show();
+ break;
+ } // end switch
+
+ return false;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/formeditor/widgetselection.h b/src/designer/src/components/formeditor/widgetselection.h
new file mode 100644
index 000000000..987bd4b51
--- /dev/null
+++ b/src/designer/src/components/formeditor/widgetselection.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WIDGETSELECTION_H
+#define WIDGETSELECTION_H
+
+#include "formeditor_global.h"
+#include <invisible_widget_p.h>
+
+#include <QtCore/QHash>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QMouseEvent;
+class QPaintEvent;
+
+namespace qdesigner_internal {
+
+class FormWindow;
+class WidgetSelection;
+
+class QT_FORMEDITOR_EXPORT WidgetHandle: public InvisibleWidget
+{
+ Q_OBJECT
+public:
+ enum Type
+ {
+ LeftTop,
+ Top,
+ RightTop,
+ Right,
+ RightBottom,
+ Bottom,
+ LeftBottom,
+ Left,
+
+ TypeCount
+ };
+
+ WidgetHandle(FormWindow *parent, Type t, WidgetSelection *s);
+ void setWidget(QWidget *w);
+ void setActive(bool a);
+ void updateCursor();
+
+ void setEnabled(bool) {}
+
+ QDesignerFormEditorInterface *core() const;
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+
+private:
+ void changeGridLayoutItemSpan();
+ void changeFormLayoutItemSpan();
+ void trySetGeometry(QWidget *w, int x, int y, int width, int height);
+ void tryResize(QWidget *w, int width, int height);
+
+private:
+ QWidget *m_widget;
+ const Type m_type;
+ QPoint m_origPressPos;
+ FormWindow *m_formWindow;
+ WidgetSelection *m_sel;
+ QRect m_geom, m_origGeom;
+ bool m_active;
+};
+
+class QT_FORMEDITOR_EXPORT WidgetSelection: public QObject
+{
+ Q_OBJECT
+public:
+ WidgetSelection(FormWindow *parent);
+
+ void setWidget(QWidget *w);
+ bool isUsed() const;
+
+ void updateActive();
+ void updateGeometry();
+ void hide();
+ void show();
+ void update();
+
+ QWidget *widget() const;
+
+ QDesignerFormEditorInterface *core() const;
+
+ virtual bool eventFilter(QObject *object, QEvent *event);
+
+ enum WidgetState { UnlaidOut, LaidOut, ManagedGridLayout, ManagedFormLayout };
+ static WidgetState widgetState(const QDesignerFormEditorInterface *core, QWidget *w);
+
+private:
+ WidgetHandle *m_handles[WidgetHandle::TypeCount];
+ QPointer<QWidget> m_widget;
+ FormWindow *m_formWindow;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // WIDGETSELECTION_H
diff --git a/src/designer/src/components/lib/lib.pro b/src/designer/src/components/lib/lib.pro
new file mode 100644
index 000000000..50a8b00fa
--- /dev/null
+++ b/src/designer/src/components/lib/lib.pro
@@ -0,0 +1,77 @@
+TEMPLATE = lib
+TARGET = QtDesignerComponents
+contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
+CONFIG += qt depend_prl no_objective_c designer
+win32|mac: CONFIG += debug_and_release
+QTDIR_build {
+ DESTDIR = $$QT_BUILD_TREE/lib
+ !wince*:DLLDESTDIR = $$QT_BUILD_TREE/bin
+}
+
+# QtDesignerComponents uses
+DEFINES += QT_STATICPLUGIN
+
+isEmpty(QT_MAJOR_VERSION) {
+ VERSION=4.3.0
+} else {
+ VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
+}
+
+include(../../../../../src/qt_targets.pri)
+QMAKE_TARGET_PRODUCT = Designer
+QMAKE_TARGET_DESCRIPTION = Graphical user interface designer.
+
+#load up the headers info
+CONFIG += qt_install_headers
+HEADERS_PRI = $$QT_BUILD_TREE/include/QtDesigner/headers.pri
+include($$HEADERS_PRI, "", true)|clear(HEADERS_PRI)
+
+#mac frameworks
+mac:!static:contains(QT_CONFIG, qt_framework) {
+ QMAKE_FRAMEWORK_BUNDLE_NAME = $$TARGET
+ CONFIG += lib_bundle qt_no_framework_direct_includes qt_framework
+ CONFIG(debug, debug|release):!build_pass:CONFIG += build_all
+}
+
+SOURCES += qdesigner_components.cpp
+
+!contains(CONFIG, static) {
+ DEFINES += QDESIGNER_COMPONENTS_LIBRARY
+ CONFIG += dll
+ LIBS += -lQtDesigner
+} else {
+ DEFINES += QT_DESIGNER_STATIC
+}
+
+INCLUDEPATH += . .. \
+ $$PWD/../../lib/components \
+ $$PWD/../../lib/sdk \
+ $$PWD/../../lib/extension \
+ $$PWD/../../lib/uilib \
+ $$PWD/../../lib/shared
+
+include(../propertyeditor/propertyeditor.pri)
+include(../objectinspector/objectinspector.pri)
+include(../signalsloteditor/signalsloteditor.pri)
+include(../formeditor/formeditor.pri)
+include(../widgetbox/widgetbox.pri)
+include(../buddyeditor/buddyeditor.pri)
+include(../taskmenu/taskmenu.pri)
+include(../tabordereditor/tabordereditor.pri)
+
+PRECOMPILED_HEADER= lib_pch.h
+
+include(../../sharedcomponents.pri)
+include(../component.pri)
+
+unix|win32-g++* {
+ QMAKE_PKGCONFIG_REQUIRES = QtCore QtDesigner QtGui QtXml
+ contains(QT_CONFIG, script): QMAKE_PKGCONFIG_REQUIRES += QtScript
+}
+
+target.path=$$[QT_INSTALL_LIBS]
+INSTALLS += target
+win32 {
+ dlltarget.path=$$[QT_INSTALL_BINS]
+ INSTALLS += dlltarget
+}
diff --git a/src/designer/src/components/lib/lib_pch.h b/src/designer/src/components/lib/lib_pch.h
new file mode 100644
index 000000000..7f2765a79
--- /dev/null
+++ b/src/designer/src/components/lib/lib_pch.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner/QtDesigner>
+#include <QtDesigner/QExtensionManager>
diff --git a/src/designer/src/components/lib/qdesigner_components.cpp b/src/designer/src/components/lib/qdesigner_components.cpp
new file mode 100644
index 000000000..9b7457f46
--- /dev/null
+++ b/src/designer/src/components/lib/qdesigner_components.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner/QDesignerComponents>
+
+#include <actioneditor_p.h>
+#include <widgetdatabase_p.h>
+#include <widgetfactory_p.h>
+
+#include <formeditor/formeditor.h>
+#include <widgetbox/widgetbox.h>
+#include <propertyeditor/propertyeditor.h>
+#include <objectinspector/objectinspector.h>
+#include <taskmenu/taskmenu_component.h>
+#include "qtresourceview_p.h"
+#include <qdesigner_integration_p.h>
+#include <signalsloteditor/signalsloteditorwindow.h>
+
+#include <buddyeditor/buddyeditor_plugin.h>
+#include <signalsloteditor/signalsloteditor_plugin.h>
+#include <tabordereditor/tabordereditor_plugin.h>
+
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerResourceBrowserInterface>
+
+#include <QtCore/qplugin.h>
+#include <QtCore/QDir>
+#include <QtCore/QTextStream>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+
+// ### keep it in sync with Q_IMPORT_PLUGIN in qplugin.h
+#define DECLARE_PLUGIN_INSTANCE(PLUGIN) \
+ extern QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance_##PLUGIN(); \
+ class Static##PLUGIN##PluginInstance { public: \
+ Static##PLUGIN##PluginInstance() { \
+ QT_PREPEND_NAMESPACE(qRegisterStaticPluginInstanceFunction) \
+ (&qt_plugin_instance_##PLUGIN); \
+ } \
+ };
+
+#define INIT_PLUGIN_INSTANCE(PLUGIN) \
+ do { \
+ Static##PLUGIN##PluginInstance instance; \
+ Q_UNUSED(instance); \
+ } while (0)
+
+DECLARE_PLUGIN_INSTANCE(SignalSlotEditorPlugin)
+DECLARE_PLUGIN_INSTANCE(BuddyEditorPlugin)
+DECLARE_PLUGIN_INSTANCE(TabOrderEditorPlugin)
+
+static void initResources()
+{
+ // Q_INIT_RESOURCE only usable in functions in global namespace
+ Q_INIT_RESOURCE(formeditor);
+ Q_INIT_RESOURCE(widgetbox);
+ Q_INIT_RESOURCE(propertyeditor);
+}
+
+
+static void initInstances()
+{
+ static bool plugins_initialized = false;
+
+ if (!plugins_initialized) {
+ INIT_PLUGIN_INSTANCE(SignalSlotEditorPlugin);
+ INIT_PLUGIN_INSTANCE(BuddyEditorPlugin);
+ INIT_PLUGIN_INSTANCE(TabOrderEditorPlugin);
+ plugins_initialized = true;
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerComponents
+ \brief The QDesignerComponents class provides a central resource for the various components
+ used in the \QD user interface.
+ \inmodule QtDesigner
+ \internal
+
+ The QDesignerComponents class is a factory for each of the standard components present
+ in the \QD user interface. It is mostly useful for developers who want to implement
+ a standalone form editing environment using \QD's components, or who need to integrate
+ \QD's components into an existing integrated development environment (IDE).
+
+ \sa QDesignerFormEditorInterface, QDesignerObjectInspectorInterface,
+ QDesignerPropertyEditorInterface, QDesignerWidgetBoxInterface
+*/
+
+/*!
+ Initializes the resources used by the components.*/
+void QDesignerComponents::initializeResources()
+{
+ initResources();
+}
+
+/*!
+ Initializes the plugins used by the components.*/
+void QDesignerComponents::initializePlugins(QDesignerFormEditorInterface *core)
+{
+ qdesigner_internal::QDesignerIntegration::initializePlugins(core);
+}
+
+/*!
+ Constructs a form editor interface with the given \a parent.*/
+QDesignerFormEditorInterface *QDesignerComponents::createFormEditor(QObject *parent)
+{
+ initInstances();
+ return new qdesigner_internal::FormEditor(parent);
+}
+
+/*!
+ Returns a new task menu with the given \a parent for the \a core interface.*/
+QObject *QDesignerComponents::createTaskMenu(QDesignerFormEditorInterface *core, QObject *parent)
+{
+ return new qdesigner_internal::TaskMenuComponent(core, parent);
+}
+
+static inline int qtMajorVersion(int qtVersion) { return qtVersion >> 16; }
+static inline int qtMinorVersion(int qtVersion) { return (qtVersion >> 8) & 0xFF; }
+static inline void setMinorVersion(int minorVersion, int *qtVersion)
+{
+ *qtVersion &= ~0xFF00;
+ *qtVersion |= minorVersion << 8;
+}
+
+// Build the version-dependent name of the user widget box file, '$HOME.designer/widgetbox4.4.xml'
+static inline QString widgetBoxFileName(int qtVersion, const QDesignerLanguageExtension *lang = 0)
+{
+ QString rc; {
+ const QChar dot = QLatin1Char('.');
+ QTextStream str(&rc);
+ str << QDir::homePath() << QDir::separator() << QLatin1String(".designer") << QDir::separator()
+ << QLatin1String("widgetbox");
+ // The naming convention using the version was introduced with 4.4
+ const int major = qtMajorVersion(qtVersion);
+ const int minor = qtMinorVersion(qtVersion);
+ if (major >= 4 && minor >= 4)
+ str << major << dot << minor;
+ if (lang)
+ str << dot << lang->uiExtension();
+ str << QLatin1String(".xml");
+ }
+ return rc;
+}
+
+/*!
+ Returns a new widget box interface with the given \a parent for the \a core interface.*/
+QDesignerWidgetBoxInterface *QDesignerComponents::createWidgetBox(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ qdesigner_internal::WidgetBox *widgetBox = new qdesigner_internal::WidgetBox(core, parent);
+
+ const QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core);
+
+ do {
+ if (lang) {
+ const QString languageWidgetBox = lang->widgetBoxContents();
+ if (!languageWidgetBox.isEmpty()) {
+ widgetBox->loadContents(lang->widgetBoxContents());
+ break;
+ }
+ }
+
+ widgetBox->setFileName(QLatin1String(":/trolltech/widgetbox/widgetbox.xml"));
+ widgetBox->load();
+ } while (false);
+
+ const QString userWidgetBoxFile = widgetBoxFileName(QT_VERSION, lang);
+
+ widgetBox->setFileName(userWidgetBoxFile);
+ if (!QFileInfo(userWidgetBoxFile).exists()) {
+ // check previous version, that is, are we running the new version for the first time
+ // If so, try to copy the old widget box file
+ if (const int minv = qtMinorVersion(QT_VERSION)) {
+ int oldVersion = QT_VERSION;
+ setMinorVersion(minv - 1, &oldVersion);
+ const QString oldWidgetBoxFile = widgetBoxFileName(oldVersion, lang);
+ if (QFileInfo(oldWidgetBoxFile).exists())
+ QFile::copy(oldWidgetBoxFile, userWidgetBoxFile);
+ }
+ }
+ widgetBox->load();
+
+ return widgetBox;
+}
+
+/*!
+ Returns a new property editor interface with the given \a parent for the \a core interface.*/
+QDesignerPropertyEditorInterface *QDesignerComponents::createPropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ return new qdesigner_internal::PropertyEditor(core, parent);
+}
+
+/*!
+ Returns a new object inspector interface with the given \a parent for the \a core interface.*/
+QDesignerObjectInspectorInterface *QDesignerComponents::createObjectInspector(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ return new qdesigner_internal::ObjectInspector(core, parent);
+}
+
+/*!
+ Returns a new action editor interface with the given \a parent for the \a core interface.*/
+QDesignerActionEditorInterface *QDesignerComponents::createActionEditor(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ return new qdesigner_internal::ActionEditor(core, parent);
+}
+
+/*!
+ Returns a new resource editor with the given \a parent for the \a core interface.*/
+QWidget *QDesignerComponents::createResourceEditor(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core)) {
+ QWidget *w = lang->createResourceBrowser(parent);
+ if (w)
+ return w;
+ }
+ QtResourceView *resourceView = new QtResourceView(core, parent);
+ resourceView->setResourceModel(core->resourceModel());
+ resourceView->setSettingsKey(QLatin1String("ResourceBrowser"));
+ qdesigner_internal::QDesignerIntegration *designerIntegration = qobject_cast<qdesigner_internal::QDesignerIntegration *>(core->integration());
+ // Note for integrators: make sure you call createResourceEditor() after you instantiated your subclass of designer integration
+ // (designer doesn't do that since by default editing resources is enabled)
+ if (designerIntegration)
+ resourceView->setResourceEditingEnabled(designerIntegration->isResourceEditingEnabled());
+ return resourceView;
+}
+
+/*!
+ Returns a new signal-slot editor with the given \a parent for the \a core interface.*/
+QWidget *QDesignerComponents::createSignalSlotEditor(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ return new qdesigner_internal::SignalSlotEditorWindow(core, parent);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/components/objectinspector/objectinspector.cpp b/src/designer/src/components/objectinspector/objectinspector.cpp
new file mode 100644
index 000000000..8bcd49e15
--- /dev/null
+++ b/src/designer/src/components/objectinspector/objectinspector.cpp
@@ -0,0 +1,835 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "objectinspector.h"
+#include "objectinspectormodel_p.h"
+#include "formwindow.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+
+// shared
+#include <qdesigner_utils_p.h>
+#include <formwindowbase_p.h>
+#include <itemviewfindwidget.h>
+#include <qdesigner_dnditem_p.h>
+#include <textpropertyeditor_p.h>
+#include <qdesigner_command_p.h>
+#include <grid_p.h>
+
+// Qt
+#include <QtGui/QApplication>
+#include <QtGui/QHeaderView>
+#include <QtGui/QScrollBar>
+#include <QtGui/QPainter>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QItemSelectionModel>
+#include <QtGui/QMenu>
+#include <QtGui/QTreeView>
+#include <QtGui/QItemDelegate>
+#include <QtGui/qevent.h>
+
+#include <QtCore/QVector>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ // Selections: Basically, ObjectInspector has to ensure a consistent
+ // selection, that is, either form-managed widgets (represented
+ // by the cursor interface selection), or unmanaged widgets/objects,
+ // for example actions, container pages, menu bars, tool bars
+ // and the like. The selection state of the latter is managed only in the object inspector.
+ // As soon as a managed widget is selected, unmanaged objects
+ // have to be unselected
+ // Normally, an empty selection is not allowed, the main container
+ // should be selected in this case (applyCursorSelection()).
+ // An exception is when clearSelection is called directly for example
+ // by the action editor that puts an unassociated action into the property
+ // editor. A hack exists to avoid the update in this case.
+
+ enum SelectionType {
+ NoSelection,
+ // A QObject that has a meta database entry
+ QObjectSelection,
+ // Unmanaged widget, menu bar or the like
+ UnmanagedWidgetSelection,
+ // A widget managed by the form window cursor
+ ManagedWidgetSelection };
+
+ typedef QVector<QObject*> QObjectVector;
+}
+
+static inline SelectionType selectionType(const QDesignerFormWindowInterface *fw, QObject *o)
+{
+ if (!o->isWidgetType())
+ return fw->core()->metaDataBase()->item(o) ? QObjectSelection : NoSelection;
+ return fw->isManaged(qobject_cast<QWidget *>(o)) ? ManagedWidgetSelection : UnmanagedWidgetSelection;
+}
+
+// Return an offset for dropping (when dropping widgets on the object
+// inspector, we fake a position on the form based on the widget dropped on).
+// Position the dropped widget with form grid offset to avoid overlapping unless we
+// drop on a layout. Position doesn't matter in the layout case
+// and this enables us to drop on a squeezed layout widget of size zero
+
+static inline QPoint dropPointOffset(const qdesigner_internal::FormWindowBase *fw, const QWidget *dropTarget)
+{
+ if (!dropTarget || dropTarget->layout())
+ return QPoint(0, 0);
+ return QPoint(fw->designerGrid().deltaX(), fw->designerGrid().deltaY());
+}
+
+namespace qdesigner_internal {
+// Delegate with object name validator for the object name column
+class ObjectInspectorDelegate : public QItemDelegate {
+public:
+ explicit ObjectInspectorDelegate(QObject *parent = 0);
+
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+};
+
+ObjectInspectorDelegate::ObjectInspectorDelegate(QObject *parent) :
+ QItemDelegate(parent)
+{
+}
+
+QWidget *ObjectInspectorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex &index) const
+{
+ if (index.column() != ObjectInspectorModel::ObjectNameColumn)
+ return QItemDelegate::createEditor(parent, option, index);
+ // Object name editor
+ const bool isMainContainer = !index.parent().isValid();
+ return new TextPropertyEditor(parent, TextPropertyEditor::EmbeddingTreeView,
+ isMainContainer ? ValidationObjectNameScope : ValidationObjectName);
+}
+
+// ------------ ObjectInspectorTreeView:
+// - Makes the Space key start editing
+// - Suppresses a range selection by dragging or Shift-up/down, which does not really work due
+// to the need to maintain a consistent selection.
+
+class ObjectInspectorTreeView : public QTreeView {
+public:
+ ObjectInspectorTreeView(QWidget *parent = 0) : QTreeView(parent) {}
+
+protected:
+ virtual void mouseMoveEvent (QMouseEvent * event);
+ virtual void keyPressEvent(QKeyEvent *event);
+
+};
+
+void ObjectInspectorTreeView::mouseMoveEvent(QMouseEvent *event)
+{
+ event->ignore(); // suppress a range selection by dragging
+}
+
+void ObjectInspectorTreeView::keyPressEvent(QKeyEvent *event)
+{
+ bool handled = false;
+ switch (event->key()) {
+ case Qt::Key_Up:
+ case Qt::Key_Down: // suppress shift-up/down range selection
+ if (event->modifiers() & Qt::ShiftModifier) {
+ event->ignore();
+ handled = true;
+ }
+ break;
+ case Qt::Key_Space: { // Space pressed: Start editing
+ const QModelIndex index = currentIndex();
+ if (index.isValid() && index.column() == 0 && !model()->hasChildren(index) && model()->flags(index) & Qt::ItemIsEditable) {
+ event->accept();
+ handled = true;
+ edit(index);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (!handled)
+ QTreeView::keyPressEvent(event);
+}
+
+// ------------ ObjectInspectorPrivate
+
+class ObjectInspector::ObjectInspectorPrivate {
+public:
+ ObjectInspectorPrivate(QDesignerFormEditorInterface *core);
+ ~ObjectInspectorPrivate();
+
+ QTreeView *treeView() const { return m_treeView; }
+ ItemViewFindWidget *findWidget() const { return m_findWidget; }
+ QDesignerFormEditorInterface *core() const { return m_core; }
+ const QPointer<FormWindowBase> &formWindow() const { return m_formWindow; }
+
+ void clear();
+ void setFormWindow(QDesignerFormWindowInterface *fwi);
+
+ QWidget *managedWidgetAt(const QPoint &global_mouse_pos);
+
+ void restoreDropHighlighting();
+ void handleDragEnterMoveEvent(const QWidget *objectInspectorWidget, QDragMoveEvent * event, bool isDragEnter);
+ void dropEvent (QDropEvent * event);
+
+ void clearSelection();
+ bool selectObject(QObject *o);
+ void slotSelectionChanged(const QItemSelection & selected, const QItemSelection &deselected);
+ void getSelection(Selection &s) const;
+
+ void slotHeaderDoubleClicked(int column) { m_treeView->resizeColumnToContents(column); }
+ void slotPopupContextMenu(QWidget *parent, const QPoint &pos);
+
+private:
+ void setFormWindowBlocked(QDesignerFormWindowInterface *fwi);
+ void applyCursorSelection();
+ void synchronizeSelection(const QItemSelection & selected, const QItemSelection &deselected);
+ bool checkManagedWidgetSelection(const QModelIndexList &selection);
+ void showContainersCurrentPage(QWidget *widget);
+
+ enum SelectionFlags { AddToSelection = 1, MakeCurrent = 2};
+ void selectIndexRange(const QModelIndexList &indexes, unsigned flags);
+
+ QDesignerFormEditorInterface *m_core;
+ QTreeView *m_treeView;
+ ObjectInspectorModel *m_model;
+ ItemViewFindWidget *m_findWidget;
+ QPointer<FormWindowBase> m_formWindow;
+ QPointer<QWidget> m_formFakeDropTarget;
+ bool m_withinClearSelection;
+};
+
+ObjectInspector::ObjectInspectorPrivate::ObjectInspectorPrivate(QDesignerFormEditorInterface *core) :
+ m_core(core),
+ m_treeView(new ObjectInspectorTreeView),
+ m_model(new ObjectInspectorModel(m_treeView)),
+ m_findWidget(new ItemViewFindWidget(
+ ItemViewFindWidget::NarrowLayout | ItemViewFindWidget::NoWholeWords)),
+ m_withinClearSelection(false)
+{
+ m_treeView->setModel(m_model);
+ m_treeView->setItemDelegate(new ObjectInspectorDelegate);
+ m_treeView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ m_treeView->header()->setResizeMode(1, QHeaderView::Stretch);
+ m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ m_treeView->setAlternatingRowColors(true);
+ m_treeView->setTextElideMode (Qt::ElideMiddle);
+
+ m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+}
+
+ObjectInspector::ObjectInspectorPrivate::~ObjectInspectorPrivate()
+{
+ delete m_treeView->itemDelegate();
+}
+
+void ObjectInspector::ObjectInspectorPrivate::clearSelection()
+{
+ m_withinClearSelection = true;
+ m_treeView->clearSelection();
+ m_withinClearSelection = false;
+}
+
+QWidget *ObjectInspector::ObjectInspectorPrivate::managedWidgetAt(const QPoint &global_mouse_pos)
+{
+ if (!m_formWindow)
+ return 0;
+
+ const QPoint pos = m_treeView->viewport()->mapFromGlobal(global_mouse_pos);
+ QObject *o = m_model->objectAt(m_treeView->indexAt(pos));
+
+ if (!o || !o->isWidgetType())
+ return 0;
+
+ QWidget *rc = qobject_cast<QWidget *>(o);
+ if (!m_formWindow->isManaged(rc))
+ return 0;
+ return rc;
+}
+
+void ObjectInspector::ObjectInspectorPrivate::showContainersCurrentPage(QWidget *widget)
+{
+ if (!widget)
+ return;
+
+ FormWindow *fw = FormWindow::findFormWindow(widget);
+ if (!fw)
+ return;
+
+ QWidget *w = widget->parentWidget();
+ bool macroStarted = false;
+ // Find a multipage container (tab widgets, etc.) in the hierarchy and set the right page.
+ while (w != 0) {
+ if (fw->isManaged(w)) { // Rule out unmanaged internal scroll areas, for example, on QToolBoxes.
+ if (QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), w)) {
+ const int count = c->count();
+ if (count > 1 && !c->widget(c->currentIndex())->isAncestorOf(widget)) {
+ for (int i = 0; i < count; i++)
+ if (c->widget(i)->isAncestorOf(widget)) {
+ if (macroStarted == false) {
+ macroStarted = true;
+ fw->beginCommand(tr("Change Current Page"));
+ }
+ ChangeCurrentPageCommand *cmd = new ChangeCurrentPageCommand(fw);
+ cmd->init(w, i);
+ fw->commandHistory()->push(cmd);
+ break;
+ }
+ }
+ }
+ }
+ w = w->parentWidget();
+ }
+ if (macroStarted == true)
+ fw->endCommand();
+}
+
+void ObjectInspector::ObjectInspectorPrivate::restoreDropHighlighting()
+{
+ if (m_formFakeDropTarget) {
+ if (m_formWindow) {
+ m_formWindow->highlightWidget(m_formFakeDropTarget, QPoint(5, 5), FormWindow::Restore);
+ }
+ m_formFakeDropTarget = 0;
+ }
+}
+
+void ObjectInspector::ObjectInspectorPrivate::handleDragEnterMoveEvent(const QWidget *objectInspectorWidget, QDragMoveEvent * event, bool isDragEnter)
+{
+ if (!m_formWindow) {
+ event->ignore();
+ return;
+ }
+
+ const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(event->mimeData());
+ if (!mimeData) {
+ event->ignore();
+ return;
+ }
+
+ QWidget *dropTarget = 0;
+ QPoint fakeDropTargetOffset = QPoint(0, 0);
+ if (QWidget *managedWidget = managedWidgetAt(objectInspectorWidget->mapToGlobal(event->pos()))) {
+ fakeDropTargetOffset = dropPointOffset(m_formWindow, managedWidget);
+ // pretend we drag over the managed widget on the form
+ const QPoint fakeFormPos = m_formWindow->mapFromGlobal(managedWidget->mapToGlobal(fakeDropTargetOffset));
+ const FormWindowBase::WidgetUnderMouseMode wum = mimeData->items().size() == 1 ? FormWindowBase::FindSingleSelectionDropTarget : FormWindowBase::FindMultiSelectionDropTarget;
+ dropTarget = m_formWindow->widgetUnderMouse(fakeFormPos, wum);
+ }
+
+ if (m_formFakeDropTarget && dropTarget != m_formFakeDropTarget)
+ m_formWindow->highlightWidget(m_formFakeDropTarget, fakeDropTargetOffset, FormWindow::Restore);
+
+ m_formFakeDropTarget = dropTarget;
+ if (m_formFakeDropTarget)
+ m_formWindow->highlightWidget(m_formFakeDropTarget, fakeDropTargetOffset, FormWindow::Highlight);
+
+ // Do not refuse drag enter even if the area is not droppable
+ if (isDragEnter || m_formFakeDropTarget)
+ mimeData->acceptEvent(event);
+ else
+ event->ignore();
+}
+void ObjectInspector::ObjectInspectorPrivate::dropEvent (QDropEvent * event)
+{
+ if (!m_formWindow || !m_formFakeDropTarget) {
+ event->ignore();
+ return;
+ }
+
+ const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(event->mimeData());
+ if (!mimeData) {
+ event->ignore();
+ return;
+ }
+ const QPoint fakeGlobalDropFormPos = m_formFakeDropTarget->mapToGlobal(dropPointOffset(m_formWindow , m_formFakeDropTarget));
+ mimeData->moveDecoration(fakeGlobalDropFormPos + mimeData->hotSpot());
+ if (!m_formWindow->dropWidgets(mimeData->items(), m_formFakeDropTarget, fakeGlobalDropFormPos)) {
+ event->ignore();
+ return;
+ }
+ mimeData->acceptEvent(event);
+}
+
+bool ObjectInspector::ObjectInspectorPrivate::selectObject(QObject *o)
+{
+ if (!m_core->metaDataBase()->item(o))
+ return false;
+
+ typedef QSet<QModelIndex> ModelIndexSet;
+
+ const QModelIndexList objectIndexes = m_model->indexesOf(o);
+ if (objectIndexes.empty())
+ return false;
+
+ QItemSelectionModel *selectionModel = m_treeView->selectionModel();
+ const ModelIndexSet currentSelectedItems = selectionModel->selectedRows(0).toSet();
+
+ // Change in selection?
+ if (!currentSelectedItems.empty() && currentSelectedItems == objectIndexes.toSet())
+ return true;
+
+ // do select and update
+ selectIndexRange(objectIndexes, MakeCurrent);
+ return true;
+}
+
+void ObjectInspector::ObjectInspectorPrivate::selectIndexRange(const QModelIndexList &indexes, unsigned flags)
+{
+ if (indexes.empty())
+ return;
+
+ QItemSelectionModel::SelectionFlags selectFlags = QItemSelectionModel::Select|QItemSelectionModel::Rows;
+ if (!(flags & AddToSelection))
+ selectFlags |= QItemSelectionModel::Clear;
+ if (flags & MakeCurrent)
+ selectFlags |= QItemSelectionModel::Current;
+
+ QItemSelectionModel *selectionModel = m_treeView->selectionModel();
+ const QModelIndexList::const_iterator cend = indexes.constEnd();
+ for (QModelIndexList::const_iterator it = indexes.constBegin(); it != cend; ++it)
+ if (it->column() == 0) {
+ selectionModel->select(*it, selectFlags);
+ selectFlags &= ~(QItemSelectionModel::Clear|QItemSelectionModel::Current);
+ }
+ if (flags & MakeCurrent)
+ m_treeView->scrollTo(indexes.front(), QAbstractItemView::EnsureVisible);
+}
+
+void ObjectInspector::ObjectInspectorPrivate::clear()
+{
+ m_formFakeDropTarget = 0;
+ m_formWindow = 0;
+}
+
+// Form window cursor is in state 'main container only'
+static inline bool mainContainerIsCurrent(const QDesignerFormWindowInterface *fw)
+{
+ const QDesignerFormWindowCursorInterface *cursor = fw->cursor();
+ if (cursor->selectedWidgetCount() > 1)
+ return false;
+ const QWidget *current = cursor->current();
+ return current == fw || current == fw->mainContainer();
+}
+
+void ObjectInspector::ObjectInspectorPrivate::setFormWindow(QDesignerFormWindowInterface *fwi)
+{
+ const bool blocked = m_treeView->selectionModel()->blockSignals(true);
+ {
+ UpdateBlocker ub(m_treeView);
+ setFormWindowBlocked(fwi);
+ }
+
+ m_treeView->update();
+ m_treeView->selectionModel()->blockSignals(blocked);
+}
+
+void ObjectInspector::ObjectInspectorPrivate::setFormWindowBlocked(QDesignerFormWindowInterface *fwi)
+{
+ FormWindowBase *fw = qobject_cast<FormWindowBase *>(fwi);
+ const bool formWindowChanged = m_formWindow != fw;
+
+ m_formWindow = fw;
+
+ const int oldWidth = m_treeView->columnWidth(0);
+ const int xoffset = m_treeView->horizontalScrollBar()->value();
+ const int yoffset = m_treeView->verticalScrollBar()->value();
+
+ if (formWindowChanged)
+ m_formFakeDropTarget = 0;
+
+ switch (m_model->update(m_formWindow)) {
+ case ObjectInspectorModel::NoForm:
+ clear();
+ return;
+ case ObjectInspectorModel::Rebuilt: // Complete rebuild: Just apply cursor selection
+ applyCursorSelection();
+ m_treeView->expandAll();
+ if (formWindowChanged) {
+ m_treeView->resizeColumnToContents(0);
+ } else {
+ m_treeView->setColumnWidth(0, oldWidth);
+ m_treeView->horizontalScrollBar()->setValue(xoffset);
+ m_treeView->verticalScrollBar()->setValue(yoffset);
+ }
+ break;
+ case ObjectInspectorModel::Updated: {
+ // Same structure (property changed or click on the form)
+ // We maintain a selection of unmanaged objects
+ // only if the cursor is in state "mainContainer() == current".
+ // and we have a non-managed selection.
+ // Else we take over the cursor selection.
+ bool applySelection = !mainContainerIsCurrent(m_formWindow);
+ if (!applySelection) {
+ const QModelIndexList currentIndexes = m_treeView->selectionModel()->selectedRows(0);
+ if (currentIndexes.empty()) {
+ applySelection = true;
+ } else {
+ applySelection = selectionType(m_formWindow, m_model->objectAt(currentIndexes.front())) == ManagedWidgetSelection;
+ }
+ }
+ if (applySelection)
+ applyCursorSelection();
+ }
+ break;
+ }
+}
+
+// Apply selection of form window cursor to object inspector, set current
+void ObjectInspector::ObjectInspectorPrivate::applyCursorSelection()
+{
+ const QDesignerFormWindowCursorInterface *cursor = m_formWindow->cursor();
+ const int count = cursor->selectedWidgetCount();
+ if (!count)
+ return;
+
+ // Set the current widget first which also clears the selection
+ QWidget *currentWidget = cursor->current();
+ if (currentWidget)
+ selectIndexRange(m_model->indexesOf(currentWidget), MakeCurrent);
+ else
+ m_treeView->selectionModel()->clearSelection();
+
+ for (int i = 0;i < count; i++) {
+ QWidget *widget = cursor->selectedWidget(i);
+ if (widget != currentWidget)
+ selectIndexRange(m_model->indexesOf(widget), AddToSelection);
+ }
+}
+
+// Synchronize managed widget in the form (select in cursor). Block updates
+static int selectInCursor(FormWindowBase *fw, const QObjectVector &objects, bool value)
+{
+ int rc = 0;
+ const bool blocked = fw->blockSelectionChanged(true);
+ const QObjectVector::const_iterator ocend = objects.constEnd();
+ for (QObjectVector::const_iterator it = objects.constBegin(); it != ocend; ++it)
+ if (selectionType(fw, *it) == ManagedWidgetSelection) {
+ fw->selectWidget(static_cast<QWidget *>(*it), value);
+ rc++;
+ }
+ fw->blockSelectionChanged(blocked);
+ return rc;
+}
+
+void ObjectInspector::ObjectInspectorPrivate::slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
+{
+ if (m_formWindow) {
+ synchronizeSelection(selected, deselected);
+ QMetaObject::invokeMethod(m_core->formWindowManager(), "slotUpdateActions");
+ }
+}
+
+// Convert indexes to object vectors taking into account that
+// some index lists are multicolumn ranges
+static inline QObjectVector indexesToObjects(const ObjectInspectorModel *model, const QModelIndexList &indexes)
+{
+ if (indexes.empty())
+ return QObjectVector();
+ QObjectVector rc;
+ rc.reserve(indexes.size());
+ const QModelIndexList::const_iterator icend = indexes.constEnd();
+ for (QModelIndexList::const_iterator it = indexes.constBegin(); it != icend; ++it)
+ if (it->column() == 0)
+ rc.push_back(model->objectAt(*it));
+ return rc;
+}
+
+// Check if any managed widgets are selected. If so, iterate over
+// selection and deselect all unmanaged objects
+bool ObjectInspector::ObjectInspectorPrivate::checkManagedWidgetSelection(const QModelIndexList &rowSelection)
+{
+ bool isManagedWidgetSelection = false;
+ QItemSelectionModel *selectionModel = m_treeView->selectionModel();
+ const QModelIndexList::const_iterator cscend = rowSelection.constEnd();
+ for (QModelIndexList::const_iterator it = rowSelection.constBegin(); it != cscend; ++it) {
+ QObject *object = m_model->objectAt(*it);
+ if (selectionType(m_formWindow, object) == ManagedWidgetSelection) {
+ isManagedWidgetSelection = true;
+ break;
+ }
+ }
+
+ if (!isManagedWidgetSelection)
+ return false;
+ // Need to unselect unmanaged ones
+ const bool blocked = selectionModel->blockSignals(true);
+ for (QModelIndexList::const_iterator it = rowSelection.constBegin(); it != cscend; ++it) {
+ QObject *object = m_model->objectAt(*it);
+ if (selectionType(m_formWindow, object) != ManagedWidgetSelection)
+ selectionModel->select(*it, QItemSelectionModel::Deselect|QItemSelectionModel::Rows);
+ }
+ selectionModel->blockSignals(blocked);
+ return true;
+}
+
+void ObjectInspector::ObjectInspectorPrivate::synchronizeSelection(const QItemSelection & selectedSelection, const QItemSelection &deselectedSelection)
+{
+ // Synchronize form window cursor.
+ const QObjectVector deselected = indexesToObjects(m_model, deselectedSelection.indexes());
+ const QObjectVector newlySelected = indexesToObjects(m_model, selectedSelection.indexes());
+
+ const QModelIndexList currentSelectedIndexes = m_treeView->selectionModel()->selectedRows(0);
+
+ int deselectedManagedWidgetCount = 0;
+ if (!deselected.empty())
+ deselectedManagedWidgetCount = selectInCursor(m_formWindow, deselected, false);
+
+ if (newlySelected.empty()) { // Nothing selected
+ if (currentSelectedIndexes.empty()) // Do not allow a null-selection, reset to main container
+ m_formWindow->clearSelection(!m_withinClearSelection);
+ return;
+ }
+
+ const int selectManagedWidgetCount = selectInCursor(m_formWindow, newlySelected, true);
+ // Check consistency: Make sure either managed widgets or unmanaged objects are selected.
+ // No newly-selected managed widgets: Unless there are ones in the (old) current selection,
+ // select the unmanaged object
+ if (selectManagedWidgetCount == 0) {
+ if (checkManagedWidgetSelection(currentSelectedIndexes)) {
+ // Managed selection exists, refuse and update if necessary
+ if (deselectedManagedWidgetCount != 0 || selectManagedWidgetCount != 0)
+ m_formWindow->emitSelectionChanged();
+ return;
+ }
+ // And now for the unmanaged selection
+ m_formWindow->clearSelection(false);
+ QObject *unmanagedObject = newlySelected.front();
+ m_core->propertyEditor()->setObject(unmanagedObject);
+ m_core->propertyEditor()->setEnabled(true);
+ // open container page if it is a single widget
+ if (newlySelected.size() == 1 && unmanagedObject->isWidgetType())
+ showContainersCurrentPage(static_cast<QWidget*>(unmanagedObject));
+ return;
+ }
+ // Open container page if it is a single widget
+ if (newlySelected.size() == 1) {
+ QObject *object = newlySelected.back();
+ if (object->isWidgetType())
+ showContainersCurrentPage(static_cast<QWidget*>(object));
+ }
+
+ // A managed widget was newly selected. Make sure there are no unmanaged objects
+ // in the whole unless just single selection
+ if (currentSelectedIndexes.size() > selectManagedWidgetCount)
+ checkManagedWidgetSelection(currentSelectedIndexes);
+ // Update form
+ if (deselectedManagedWidgetCount != 0 || selectManagedWidgetCount != 0)
+ m_formWindow->emitSelectionChanged();
+}
+
+
+void ObjectInspector::ObjectInspectorPrivate::getSelection(Selection &s) const
+{
+ s.clear();
+
+ if (!m_formWindow)
+ return;
+
+ const QModelIndexList currentSelectedIndexes = m_treeView->selectionModel()->selectedRows(0);
+ if (currentSelectedIndexes.empty())
+ return;
+
+ // sort objects
+ foreach (const QModelIndex &index, currentSelectedIndexes)
+ if (QObject *object = m_model->objectAt(index))
+ switch (selectionType(m_formWindow, object)) {
+ case NoSelection:
+ break;
+ case QObjectSelection:
+ // It is actually possible to select an action twice if it is in a menu bar
+ // and in a tool bar.
+ if (!s.objects.contains(object))
+ s.objects.push_back(object);
+ break;
+ case UnmanagedWidgetSelection:
+ s.unmanaged.push_back(qobject_cast<QWidget *>(object));
+ break;
+ case ManagedWidgetSelection:
+ s.managed.push_back(qobject_cast<QWidget *>(object));
+ break;
+ }
+}
+
+// Utility to create a task menu
+static inline QMenu *createTaskMenu(QObject *object, QDesignerFormWindowInterface *fw)
+{
+ // 1) Objects
+ if (!object->isWidgetType())
+ return FormWindowBase::createExtensionTaskMenu(fw, object, false);
+ // 2) Unmanaged widgets
+ QWidget *w = static_cast<QWidget *>(object);
+ if (!fw->isManaged(w))
+ return FormWindowBase::createExtensionTaskMenu(fw, w, false);
+ // 3) Mananaged widgets
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase*>(fw))
+ return fwb->initializePopupMenu(w);
+ return 0;
+}
+
+void ObjectInspector::ObjectInspectorPrivate::slotPopupContextMenu(QWidget * /*parent*/, const QPoint &pos)
+{
+ if (m_formWindow == 0 || m_formWindow->currentTool() != 0)
+ return;
+
+ const QModelIndex index = m_treeView->indexAt (pos);
+ if (QObject *object = m_model->objectAt(m_treeView->indexAt(pos)))
+ if (QMenu *menu = createTaskMenu(object, m_formWindow)) {
+ menu->exec(m_treeView->viewport()->mapToGlobal(pos));
+ delete menu;
+ }
+}
+
+// ------------ ObjectInspector
+ObjectInspector::ObjectInspector(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QDesignerObjectInspector(parent),
+ m_impl(new ObjectInspectorPrivate(core))
+{
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ vbox->setMargin(0);
+
+ QTreeView *treeView = m_impl->treeView();
+ vbox->addWidget(treeView);
+
+ connect(treeView, SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(slotPopupContextMenu(QPoint)));
+
+ connect(treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
+
+ connect(treeView->header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(slotHeaderDoubleClicked(int)));
+ setAcceptDrops(true);
+
+ ItemViewFindWidget *findWidget = m_impl->findWidget();
+ vbox->addWidget(findWidget);
+
+ findWidget->setItemView(treeView);
+ QAction *findAction = new QAction(
+ ItemViewFindWidget::findIconSet(),
+ tr("&Find in Text..."),
+ this);
+ findAction->setShortcut(QKeySequence::Find);
+ findAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
+ addAction(findAction);
+ connect(findAction, SIGNAL(triggered(bool)), findWidget, SLOT(activate()));
+}
+
+ObjectInspector::~ObjectInspector()
+{
+ delete m_impl;
+}
+
+QDesignerFormEditorInterface *ObjectInspector::core() const
+{
+ return m_impl->core();
+}
+
+void ObjectInspector::slotPopupContextMenu(const QPoint &pos)
+{
+ m_impl->slotPopupContextMenu(this, pos);
+}
+
+void ObjectInspector::setFormWindow(QDesignerFormWindowInterface *fwi)
+{
+ m_impl->setFormWindow(fwi);
+}
+
+void ObjectInspector::slotSelectionChanged(const QItemSelection & selected, const QItemSelection &deselected)
+{
+ m_impl->slotSelectionChanged(selected, deselected);
+}
+
+void ObjectInspector::getSelection(Selection &s) const
+{
+ m_impl->getSelection(s);
+}
+
+bool ObjectInspector::selectObject(QObject *o)
+{
+ return m_impl->selectObject(o);
+}
+
+void ObjectInspector::clearSelection()
+{
+ m_impl->clearSelection();
+}
+
+void ObjectInspector::slotHeaderDoubleClicked(int column)
+{
+ m_impl->slotHeaderDoubleClicked(column);
+}
+
+void ObjectInspector::mainContainerChanged()
+{
+ // Invalidate references to objects kept in items
+ if (sender() == m_impl->formWindow())
+ setFormWindow(0);
+}
+
+void ObjectInspector::dragEnterEvent (QDragEnterEvent * event)
+{
+ m_impl->handleDragEnterMoveEvent(this, event, true);
+}
+
+void ObjectInspector::dragMoveEvent(QDragMoveEvent * event)
+{
+ m_impl->handleDragEnterMoveEvent(this, event, false);
+}
+
+void ObjectInspector::dragLeaveEvent(QDragLeaveEvent * /* event*/)
+{
+ m_impl->restoreDropHighlighting();
+}
+
+void ObjectInspector::dropEvent (QDropEvent * event)
+{
+ m_impl->dropEvent(event);
+
+QT_END_NAMESPACE
+}
+}
diff --git a/src/designer/src/components/objectinspector/objectinspector.h b/src/designer/src/components/objectinspector/objectinspector.h
new file mode 100644
index 000000000..ebf4da2ce
--- /dev/null
+++ b/src/designer/src/components/objectinspector/objectinspector.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OBJECTINSPECTOR_H
+#define OBJECTINSPECTOR_H
+
+#include "objectinspector_global.h"
+#include "qdesigner_objectinspector_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+
+class QItemSelection;
+
+namespace qdesigner_internal {
+
+class QT_OBJECTINSPECTOR_EXPORT ObjectInspector: public QDesignerObjectInspector
+{
+ Q_OBJECT
+public:
+ explicit ObjectInspector(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ virtual ~ObjectInspector();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual void getSelection(Selection &s) const;
+ virtual bool selectObject(QObject *o);
+ virtual void clearSelection();
+
+ void setFormWindow(QDesignerFormWindowInterface *formWindow);
+
+public slots:
+ virtual void mainContainerChanged();
+
+private slots:
+ void slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ void slotPopupContextMenu(const QPoint &pos);
+ void slotHeaderDoubleClicked(int column);
+
+protected:
+ virtual void dragEnterEvent (QDragEnterEvent * event);
+ virtual void dragMoveEvent(QDragMoveEvent * event);
+ virtual void dragLeaveEvent(QDragLeaveEvent * event);
+ virtual void dropEvent (QDropEvent * event);
+
+private:
+ class ObjectInspectorPrivate;
+ ObjectInspectorPrivate *m_impl;
+};
+
+} // namespace qdesigner_internal
+
+#endif // OBJECTINSPECTOR_H
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/objectinspector/objectinspector.pri b/src/designer/src/components/objectinspector/objectinspector.pri
new file mode 100644
index 000000000..565f78bdc
--- /dev/null
+++ b/src/designer/src/components/objectinspector/objectinspector.pri
@@ -0,0 +1,16 @@
+# --- The Find widget is also linked into the designer_shared library.
+# Avoid conflict when linking statically
+contains(CONFIG, static) {
+ INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/findwidget
+} else {
+ include(../../../../shared/findwidget/findwidget.pri)
+}
+
+INCLUDEPATH += $$PWD
+
+HEADERS += $$PWD/objectinspector.h \
+ $$PWD/objectinspectormodel_p.h \
+ $$PWD/objectinspector_global.h
+
+SOURCES += $$PWD/objectinspector.cpp \
+ $$PWD/objectinspectormodel.cpp
diff --git a/src/designer/src/components/objectinspector/objectinspector_global.h b/src/designer/src/components/objectinspector/objectinspector_global.h
new file mode 100644
index 000000000..08ddf6e68
--- /dev/null
+++ b/src/designer/src/components/objectinspector/objectinspector_global.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OBJECTINSPECTOR_GLOBAL_H
+#define OBJECTINSPECTOR_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN
+#ifdef QT_OBJECTINSPECTOR_LIBRARY
+# define QT_OBJECTINSPECTOR_EXPORT
+#else
+# define QT_OBJECTINSPECTOR_EXPORT
+#endif
+#else
+#define QT_OBJECTINSPECTOR_EXPORT
+#endif
+
+#endif // OBJECTINSPECTOR_GLOBAL_H
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/objectinspector/objectinspectormodel.cpp b/src/designer/src/components/objectinspector/objectinspectormodel.cpp
new file mode 100644
index 000000000..20f0ff18f
--- /dev/null
+++ b/src/designer/src/components/objectinspector/objectinspectormodel.cpp
@@ -0,0 +1,516 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "objectinspectormodel_p.h"
+
+#include <qlayout_widget_p.h>
+#include <layout_p.h>
+#include <qdesigner_propertycommand_p.h>
+#include <qdesigner_utils_p.h>
+#include <iconloader_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtGui/QLayout>
+#include <QtGui/QAction>
+#include <QtGui/QLayoutItem>
+#include <QtGui/QMenu>
+#include <QtGui/QButtonGroup>
+#include <QtCore/QSet>
+#include <QtCore/QDebug>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { DataRole = 1000 };
+}
+
+static inline QObject *objectOfItem(const QStandardItem *item) {
+ return qvariant_cast<QObject *>(item->data(DataRole));
+}
+
+static bool sortEntry(const QObject *a, const QObject *b)
+{
+ return a->objectName() < b->objectName();
+}
+
+static bool sameIcon(const QIcon &i1, const QIcon &i2)
+{
+ if (i1.isNull() && i2.isNull())
+ return true;
+ if (i1.isNull() != i2.isNull())
+ return false;
+ return i1.serialNumber() == i2.serialNumber();
+}
+
+static inline bool isNameColumnEditable(const QObject *)
+{
+ return true;
+}
+
+static qdesigner_internal::ObjectData::StandardItemList createModelRow(const QObject *o)
+{
+ qdesigner_internal::ObjectData::StandardItemList rc;
+ const Qt::ItemFlags baseFlags = Qt::ItemIsSelectable|Qt::ItemIsDropEnabled|Qt::ItemIsEnabled;
+ for (int i = 0; i < qdesigner_internal::ObjectInspectorModel::NumColumns; i++) {
+ QStandardItem *item = new QStandardItem;
+ Qt::ItemFlags flags = baseFlags;
+ if (i == qdesigner_internal::ObjectInspectorModel::ObjectNameColumn && isNameColumnEditable(o))
+ flags |= Qt::ItemIsEditable;
+ item->setFlags(flags);
+ rc += item;
+ }
+ return rc;
+}
+
+static inline bool isQLayoutWidget(const QObject *o)
+{
+ return o->metaObject() == &QLayoutWidget::staticMetaObject;
+}
+
+namespace qdesigner_internal {
+
+ // context kept while building a model, just there to reduce string allocations
+ struct ModelRecursionContext {
+ explicit ModelRecursionContext(QDesignerFormEditorInterface *core, const QString &sepName);
+
+ const QString designerPrefix;
+ const QString separator;
+
+ QDesignerFormEditorInterface *core;
+ const QDesignerWidgetDataBaseInterface *db;
+ const QDesignerMetaDataBaseInterface *mdb;
+ };
+
+ ModelRecursionContext::ModelRecursionContext(QDesignerFormEditorInterface *c, const QString &sepName) :
+ designerPrefix(QLatin1String("QDesigner")),
+ separator(sepName),
+ core(c),
+ db(c->widgetDataBase()),
+ mdb(c->metaDataBase())
+ {
+ }
+
+ // ------------ ObjectData/ ObjectModel:
+ // Whenever the selection changes, ObjectInspector::setFormWindow is
+ // called. To avoid rebuilding the tree every time (loosing expanded state)
+ // a model is first built from the object tree by recursion.
+ // As a tree is difficult to represent, a flat list of entries (ObjectData)
+ // containing object and parent object is used.
+ // ObjectData has an overloaded operator== that compares the object pointers.
+ // Structural changes which cause a rebuild can be detected by
+ // comparing the lists of ObjectData. If it is the same, only the item data (class name [changed by promotion],
+ // object name and icon) are checked and the existing items are updated.
+
+ ObjectData::ObjectData() :
+ m_parent(0),
+ m_object(0),
+ m_type(Object),
+ m_managedLayoutType(LayoutInfo::NoLayout)
+ {
+ }
+
+ ObjectData::ObjectData(QObject *parent, QObject *object, const ModelRecursionContext &ctx) :
+ m_parent(parent),
+ m_object(object),
+ m_type(Object),
+ m_className(QLatin1String(object->metaObject()->className())),
+ m_objectName(object->objectName()),
+ m_managedLayoutType(LayoutInfo::NoLayout)
+ {
+
+ // 1) set entry
+ if (object->isWidgetType()) {
+ initWidget(static_cast<QWidget*>(object), ctx);
+ } else {
+ initObject(ctx);
+ }
+ if (m_className.startsWith(ctx.designerPrefix))
+ m_className.remove(1, ctx.designerPrefix.size() - 1);
+ }
+
+ void ObjectData::initObject(const ModelRecursionContext &ctx)
+ {
+ // Check objects: Action?
+ if (const QAction *act = qobject_cast<const QAction*>(m_object)) {
+ if (act->isSeparator()) { // separator is reserved
+ m_objectName = ctx.separator;
+ m_type = SeparatorAction;
+ } else {
+ m_type = Action;
+ }
+ m_classIcon = act->icon();
+ } else {
+ m_type = Object;
+ }
+ }
+
+ void ObjectData::initWidget(QWidget *w, const ModelRecursionContext &ctx)
+ {
+ // Check for extension container, QLayoutwidget, or normal container
+ bool isContainer = false;
+ if (const QDesignerWidgetDataBaseItemInterface *widgetItem = ctx.db->item(ctx.db->indexOfObject(w, true))) {
+ m_classIcon = widgetItem->icon();
+ m_className = widgetItem->name();
+ isContainer = widgetItem->isContainer();
+ }
+
+ // We might encounter temporary states with no layouts when re-layouting.
+ // Just default to Widget handling for the moment.
+ if (isQLayoutWidget(w)) {
+ if (const QLayout *layout = w->layout()) {
+ m_type = LayoutWidget;
+ m_managedLayoutType = LayoutInfo::layoutType(ctx.core, layout);
+ m_className = QLatin1String(layout->metaObject()->className());
+ m_objectName = layout->objectName();
+ }
+ return;
+ }
+
+ if (qt_extension<QDesignerContainerExtension*>(ctx.core->extensionManager(), w)) {
+ m_type = ExtensionContainer;
+ return;
+ }
+ if (isContainer) {
+ m_type = LayoutableContainer;
+ m_managedLayoutType = LayoutInfo::managedLayoutType(ctx.core, w);
+ return;
+ }
+ m_type = ChildWidget;
+ }
+
+ bool ObjectData::equals(const ObjectData & me) const
+ {
+ return m_parent == me.m_parent && m_object == me.m_object;
+ }
+
+ unsigned ObjectData::compare(const ObjectData & rhs) const
+ {
+ unsigned rc = 0;
+ if (m_className != rhs.m_className)
+ rc |= ClassNameChanged;
+ if (m_objectName != rhs.m_objectName)
+ rc |= ObjectNameChanged;
+ if (!sameIcon(m_classIcon, rhs.m_classIcon))
+ rc |= ClassIconChanged;
+ if (m_type != rhs.m_type)
+ rc |= TypeChanged;
+ if (m_managedLayoutType != rhs.m_managedLayoutType)
+ rc |= LayoutTypeChanged;
+ return rc;
+ }
+
+ void ObjectData::setItemsDisplayData(const StandardItemList &row, const ObjectInspectorIcons &icons, unsigned mask) const
+ {
+ if (mask & ObjectNameChanged)
+ row[ObjectInspectorModel::ObjectNameColumn]->setText(m_objectName);
+ if (mask & ClassNameChanged) {
+ row[ObjectInspectorModel::ClassNameColumn]->setText(m_className);
+ row[ObjectInspectorModel::ClassNameColumn]->setToolTip(m_className);
+ }
+ // Set a layout icon only for containers. Note that QLayoutWidget don't have
+ // real class icons
+ if (mask & (ClassIconChanged|TypeChanged|LayoutTypeChanged)) {
+ switch (m_type) {
+ case LayoutWidget:
+ row[ObjectInspectorModel::ObjectNameColumn]->setIcon(icons.layoutIcons[m_managedLayoutType]);
+ row[ObjectInspectorModel::ClassNameColumn]->setIcon(icons.layoutIcons[m_managedLayoutType]);
+ break;
+ case LayoutableContainer:
+ row[ObjectInspectorModel::ObjectNameColumn]->setIcon(icons.layoutIcons[m_managedLayoutType]);
+ row[ObjectInspectorModel::ClassNameColumn]->setIcon(m_classIcon);
+ break;
+ default:
+ row[ObjectInspectorModel::ObjectNameColumn]->setIcon(QIcon());
+ row[ObjectInspectorModel::ClassNameColumn]->setIcon(m_classIcon);
+ break;
+ }
+ }
+ }
+
+ void ObjectData::setItems(const StandardItemList &row, const ObjectInspectorIcons &icons) const
+ {
+ const QVariant object = QVariant::fromValue(m_object);
+ row[ObjectInspectorModel::ObjectNameColumn]->setData(object, DataRole);
+ row[ObjectInspectorModel::ClassNameColumn]->setData(object, DataRole);
+ setItemsDisplayData(row, icons, ClassNameChanged|ObjectNameChanged|ClassIconChanged|TypeChanged|LayoutTypeChanged);
+ }
+
+ typedef QList<ObjectData> ObjectModel;
+
+ // Recursive routine that creates the model by traversing the form window object tree.
+ void createModelRecursion(const QDesignerFormWindowInterface *fwi,
+ QObject *parent,
+ QObject *object,
+ ObjectModel &model,
+ const ModelRecursionContext &ctx)
+ {
+ typedef QList<QButtonGroup *> ButtonGroupList;
+ typedef QList<QAction *> ActionList;
+
+ // 1) Create entry
+ const ObjectData entry(parent, object, ctx);
+ model.push_back(entry);
+
+ // 2) recurse over widget children via container extension or children list
+ const QDesignerContainerExtension *containerExtension = 0;
+ if (entry.type() == ObjectData::ExtensionContainer) {
+ containerExtension = qt_extension<QDesignerContainerExtension*>(fwi->core()->extensionManager(), object);
+ Q_ASSERT(containerExtension);
+ const int count = containerExtension->count();
+ for (int i=0; i < count; ++i) {
+ QObject *page = containerExtension->widget(i);
+ Q_ASSERT(page != 0);
+ createModelRecursion(fwi, object, page, model, ctx);
+ }
+ }
+
+ QObjectList children = object->children();
+ if (!children.empty()) {
+ ButtonGroupList buttonGroups;
+ qSort(children.begin(), children.end(), sortEntry);
+ const QObjectList::const_iterator cend = children.constEnd();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it) {
+ // Managed child widgets unless we had a container extension
+ if ((*it)->isWidgetType()) {
+ if (!containerExtension) {
+ QWidget *widget = qobject_cast<QWidget*>(*it);
+ if (fwi->isManaged(widget))
+ createModelRecursion(fwi, object, widget, model, ctx);
+ }
+ } else {
+ if (ctx.mdb->item(*it)) {
+ if (QButtonGroup *bg = qobject_cast<QButtonGroup*>(*it))
+ buttonGroups.push_back(bg);
+ } // Has MetaDataBase entry
+ }
+ }
+ // Add button groups
+ if (!buttonGroups.empty()) {
+ const ButtonGroupList::const_iterator bgcend = buttonGroups.constEnd();
+ for (ButtonGroupList::const_iterator bgit = buttonGroups.constBegin(); bgit != bgcend; ++bgit)
+ createModelRecursion(fwi, object, *bgit, model, ctx);
+ }
+ } // has children
+ if (object->isWidgetType()) {
+ // Add actions
+ const ActionList actions = static_cast<QWidget*>(object)->actions();
+ if (!actions.empty()) {
+ const ActionList::const_iterator cend = actions.constEnd();
+ for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it)
+ if (ctx.mdb->item(*it)) {
+ QAction *action = *it;
+ QObject *obj = action;
+ if (action->menu())
+ obj = action->menu();
+ createModelRecursion(fwi, object, obj, model, ctx);
+ }
+ }
+ }
+ }
+
+ // ------------ ObjectInspectorModel
+ ObjectInspectorModel::ObjectInspectorModel(QObject *parent) :
+ QStandardItemModel(0, NumColumns, parent)
+ {
+ QStringList headers;
+ headers += QCoreApplication::translate("ObjectInspectorModel", "Object");
+ headers += QCoreApplication::translate("ObjectInspectorModel", "Class");
+ Q_ASSERT(headers.size() == NumColumns);
+ setColumnCount(NumColumns);
+ setHorizontalHeaderLabels(headers);
+ // Icons
+ m_icons.layoutIcons[LayoutInfo::NoLayout] = createIconSet(QLatin1String("editbreaklayout.png"));
+ m_icons.layoutIcons[LayoutInfo::HSplitter] = createIconSet(QLatin1String("edithlayoutsplit.png"));
+ m_icons.layoutIcons[LayoutInfo::VSplitter] = createIconSet(QLatin1String("editvlayoutsplit.png"));
+ m_icons.layoutIcons[LayoutInfo::HBox] = createIconSet(QLatin1String("edithlayout.png"));
+ m_icons.layoutIcons[LayoutInfo::VBox] = createIconSet(QLatin1String("editvlayout.png"));
+ m_icons.layoutIcons[LayoutInfo::Grid] = createIconSet(QLatin1String("editgrid.png"));
+ m_icons.layoutIcons[LayoutInfo::Form] = createIconSet(QLatin1String("editform.png"));
+ }
+
+ void ObjectInspectorModel::clearItems()
+ {
+ m_objectIndexMultiMap.clear();
+ m_model.clear();
+ reset(); // force editors to be closed in views
+ removeRow(0);
+ }
+
+ ObjectInspectorModel::UpdateResult ObjectInspectorModel::update(QDesignerFormWindowInterface *fw)
+ {
+ QWidget *mainContainer = fw ? fw->mainContainer() : static_cast<QWidget*>(0);
+ if (!mainContainer) {
+ clearItems();
+ m_formWindow = 0;
+ return NoForm;
+ }
+ m_formWindow = fw;
+ // Build new model and compare to previous one. If the structure is
+ // identical, just update, else rebuild
+ ObjectModel newModel;
+
+ static const QString separator = QCoreApplication::translate("ObjectInspectorModel", "separator");
+ const ModelRecursionContext ctx(fw->core(), separator);
+ createModelRecursion(fw, 0, mainContainer, newModel, ctx);
+
+ if (newModel == m_model) {
+ updateItemContents(m_model, newModel);
+ return Updated;
+ }
+
+ rebuild(newModel);
+ m_model = newModel;
+ return Rebuilt;
+ }
+
+ QObject *ObjectInspectorModel::objectAt(const QModelIndex &index) const
+ {
+ if (index.isValid())
+ if (const QStandardItem *item = itemFromIndex(index))
+ return objectOfItem(item);
+ return 0;
+ }
+
+ // Missing Qt API: get a row
+ ObjectInspectorModel::StandardItemList ObjectInspectorModel::rowAt(QModelIndex index) const
+ {
+ StandardItemList rc;
+ while (true) {
+ rc += itemFromIndex(index);
+ const int nextColumn = index.column() + 1;
+ if (nextColumn >= NumColumns)
+ break;
+ index = index.sibling(index.row(), nextColumn);
+ }
+ return rc;
+ }
+
+ // Rebuild the tree in case the model has completely changed.
+ void ObjectInspectorModel::rebuild(const ObjectModel &newModel)
+ {
+ clearItems();
+ if (newModel.empty())
+ return;
+
+ const ObjectModel::const_iterator mcend = newModel.constEnd();
+ ObjectModel::const_iterator it = newModel.constBegin();
+ // Set up root element
+ StandardItemList rootRow = createModelRow(it->object());
+ it->setItems(rootRow, m_icons);
+ appendRow(rootRow);
+ m_objectIndexMultiMap.insert(it->object(), indexFromItem(rootRow.front()));
+ for (++it; it != mcend; ++it) {
+ // Add to parent item, found via map
+ const QModelIndex parentIndex = m_objectIndexMultiMap.value(it->parent(), QModelIndex());
+ Q_ASSERT(parentIndex.isValid());
+ QStandardItem *parentItem = itemFromIndex(parentIndex);
+ StandardItemList row = createModelRow(it->object());
+ it->setItems(row, m_icons);
+ parentItem->appendRow(row);
+ m_objectIndexMultiMap.insert(it->object(), indexFromItem(row.front()));
+ }
+ }
+
+ // Update item data in case the model has the same structure
+ void ObjectInspectorModel::updateItemContents(ObjectModel &oldModel, const ObjectModel &newModel)
+ {
+ // Change text and icon. Keep a set of changed object
+ // as for example actions might occur several times in the tree.
+ typedef QSet<QObject *> QObjectSet;
+
+ QObjectSet changedObjects;
+
+ const int size = newModel.size();
+ Q_ASSERT(oldModel.size() == size);
+ for (int i = 0; i < size; i++) {
+ const ObjectData &newEntry = newModel[i];
+ ObjectData &entry = oldModel[i];
+ // Has some data changed?
+ if (const unsigned changedMask = entry.compare(newEntry)) {
+ entry = newEntry;
+ QObject * o = entry.object();
+ if (!changedObjects.contains(o)) {
+ changedObjects.insert(o);
+ const QModelIndexList indexes = m_objectIndexMultiMap.values(o);
+ foreach (const QModelIndex &index, indexes)
+ entry.setItemsDisplayData(rowAt(index), m_icons, changedMask);
+ }
+ }
+ }
+ }
+
+ QVariant ObjectInspectorModel::data(const QModelIndex &index, int role) const
+ {
+ const QVariant rc = QStandardItemModel::data(index, role);
+ // Return <noname> if the string is empty for the display role
+ // only (else, editing starts with <noname>).
+ if (role == Qt::DisplayRole && rc.type() == QVariant::String) {
+ const QString s = rc.toString();
+ if (s.isEmpty()) {
+ static const QString noName = QCoreApplication::translate("ObjectInspectorModel", "<noname>");
+ return QVariant(noName);
+ }
+ }
+ return rc;
+ }
+
+ bool ObjectInspectorModel::setData(const QModelIndex &index, const QVariant &value, int role)
+ {
+ if (role != Qt::EditRole || !m_formWindow)
+ return false;
+
+ QObject *object = objectAt(index);
+ if (!object)
+ return false;
+ // Is this a layout widget?
+ const QString nameProperty = isQLayoutWidget(object) ? QLatin1String("layoutName") : QLatin1String("objectName");
+ m_formWindow->commandHistory()->push(createTextPropertyCommand(nameProperty, value.toString(), object, m_formWindow));
+ return true;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/objectinspector/objectinspectormodel_p.h b/src/designer/src/components/objectinspector/objectinspectormodel_p.h
new file mode 100644
index 000000000..499a99afb
--- /dev/null
+++ b/src/designer/src/components/objectinspector/objectinspectormodel_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef OBJECTINSPECTORMODEL_H
+#define OBJECTINSPECTORMODEL_H
+
+#include <layoutinfo_p.h>
+
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QIcon>
+#include <QtCore/QModelIndex>
+#include <QtCore/QString>
+#include <QtCore/QList>
+#include <QtCore/QMultiMap>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+ // Data structure containing the fixed item type icons
+ struct ObjectInspectorIcons {
+ QIcon layoutIcons[LayoutInfo::UnknownLayout + 1];
+ };
+
+ struct ModelRecursionContext;
+
+ // Data structure representing one item of the object inspector.
+ class ObjectData {
+ public:
+ enum Type {
+ Object,
+ Action,
+ SeparatorAction,
+ ChildWidget, // A child widget
+ LayoutableContainer, // A container that can be laid out
+ LayoutWidget, // A QLayoutWidget
+ ExtensionContainer // QTabWidget and the like, container extension
+ };
+
+ typedef QList<QStandardItem *> StandardItemList;
+
+ explicit ObjectData(QObject *parent, QObject *object, const ModelRecursionContext &ctx);
+ ObjectData();
+
+ inline Type type() const { return m_type; }
+ inline QObject *object() const { return m_object; }
+ inline QObject *parent() const { return m_parent; }
+ inline QString objectName() const { return m_objectName; }
+
+ bool equals(const ObjectData & me) const;
+
+ enum ChangedMask { ClassNameChanged = 1, ObjectNameChanged = 2,
+ ClassIconChanged = 4, TypeChanged = 8,
+ LayoutTypeChanged = 16};
+
+ unsigned compare(const ObjectData & me) const;
+
+ // Initially set up a row
+ void setItems(const StandardItemList &row, const ObjectInspectorIcons &icons) const;
+ // Update row data according to change mask
+ void setItemsDisplayData(const StandardItemList &row, const ObjectInspectorIcons &icons, unsigned mask) const;
+
+ private:
+ void initObject(const ModelRecursionContext &ctx);
+ void initWidget(QWidget *w, const ModelRecursionContext &ctx);
+
+ QObject *m_parent;
+ QObject *m_object;
+ Type m_type;
+ QString m_className;
+ QString m_objectName;
+ QIcon m_classIcon;
+ LayoutInfo::Type m_managedLayoutType;
+ };
+
+ inline bool operator==(const ObjectData &e1, const ObjectData &e2) { return e1.equals(e2); }
+ inline bool operator!=(const ObjectData &e1, const ObjectData &e2) { return !e1.equals(e2); }
+
+ typedef QList<ObjectData> ObjectModel;
+
+ // QStandardItemModel for ObjectInspector. Uses ObjectData/ObjectModel
+ // internally for its updates.
+ class ObjectInspectorModel : public QStandardItemModel {
+ public:
+ typedef QList<QStandardItem *> StandardItemList;
+ enum { ObjectNameColumn, ClassNameColumn, NumColumns };
+
+ explicit ObjectInspectorModel(QObject *parent);
+
+ enum UpdateResult { NoForm, Rebuilt, Updated };
+ UpdateResult update(QDesignerFormWindowInterface *fw);
+
+ const QModelIndexList indexesOf(QObject *o) const { return m_objectIndexMultiMap.values(o); }
+ QObject *objectAt(const QModelIndex &index) const;
+
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ private:
+ typedef QMultiMap<QObject *,QModelIndex> ObjectIndexMultiMap;
+
+ void rebuild(const ObjectModel &newModel);
+ void updateItemContents(ObjectModel &oldModel, const ObjectModel &newModel);
+ void clearItems();
+ StandardItemList rowAt(QModelIndex index) const;
+
+ ObjectInspectorIcons m_icons;
+ ObjectIndexMultiMap m_objectIndexMultiMap;
+ ObjectModel m_model;
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+ };
+} // namespace qdesigner_internal
+
+#endif // OBJECTINSPECTORMODEL_H
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/brushpropertymanager.cpp b/src/designer/src/components/propertyeditor/brushpropertymanager.cpp
new file mode 100644
index 000000000..973de63bb
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/brushpropertymanager.cpp
@@ -0,0 +1,298 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "brushpropertymanager.h"
+#include "qtpropertymanager.h"
+#include "qtvariantproperty.h"
+#include "qtpropertybrowserutils_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QVariant>
+#include <QtCore/QString>
+
+static const char *brushStyles[] = {
+QT_TRANSLATE_NOOP("BrushPropertyManager", "No brush"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Solid"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Dense 1"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Dense 2"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Dense 3"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Dense 4"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Dense 5"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Dense 6"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Dense 7"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Horizontal"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Vertical"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Cross"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Backward diagonal"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Forward diagonal"),
+QT_TRANSLATE_NOOP("BrushPropertyManager", "Crossing diagonal"),
+};
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+BrushPropertyManager::BrushPropertyManager()
+{
+}
+
+int BrushPropertyManager::brushStyleToIndex(Qt::BrushStyle st)
+{
+ switch (st) {
+ case Qt::NoBrush: return 0;
+ case Qt::SolidPattern: return 1;
+ case Qt::Dense1Pattern: return 2;
+ case Qt::Dense2Pattern: return 3;
+ case Qt::Dense3Pattern: return 4;
+ case Qt::Dense4Pattern: return 5;
+ case Qt::Dense5Pattern: return 6;
+ case Qt::Dense6Pattern: return 7;
+ case Qt::Dense7Pattern: return 8;
+ case Qt::HorPattern: return 9;
+ case Qt::VerPattern: return 10;
+ case Qt::CrossPattern: return 11;
+ case Qt::BDiagPattern: return 12;
+ case Qt::FDiagPattern: return 13;
+ case Qt::DiagCrossPattern: return 14;
+ default: break;
+ }
+ return 0;
+}
+
+Qt::BrushStyle BrushPropertyManager::brushStyleIndexToStyle(int brushStyleIndex)
+{
+ switch (brushStyleIndex) {
+ case 0: return Qt::NoBrush;
+ case 1: return Qt::SolidPattern;
+ case 2: return Qt::Dense1Pattern;
+ case 3: return Qt::Dense2Pattern;
+ case 4: return Qt::Dense3Pattern;
+ case 5: return Qt::Dense4Pattern;
+ case 6: return Qt::Dense5Pattern;
+ case 7: return Qt::Dense6Pattern;
+ case 8: return Qt::Dense7Pattern;
+ case 9: return Qt::HorPattern;
+ case 10: return Qt::VerPattern;
+ case 11: return Qt::CrossPattern;
+ case 12: return Qt::BDiagPattern;
+ case 13: return Qt::FDiagPattern;
+ case 14: return Qt::DiagCrossPattern;
+ }
+ return Qt::NoBrush;
+}
+
+
+typedef QMap<int, QIcon> EnumIndexIconMap;
+
+static void clearBrushIcons();
+Q_GLOBAL_STATIC_WITH_INITIALIZER(EnumIndexIconMap, brushIcons, qAddPostRoutine(clearBrushIcons))
+
+static void clearBrushIcons()
+{
+ brushIcons()->clear();
+}
+
+const BrushPropertyManager::EnumIndexIconMap &BrushPropertyManager::brushStyleIcons()
+{
+ // Create a map of icons for the brush style editor
+ if (brushIcons()->empty()) {
+ const int brushStyleCount = sizeof(brushStyles)/sizeof(const char *);
+ QBrush brush(Qt::black);
+ const QIcon solidIcon = QtPropertyBrowserUtils::brushValueIcon(brush);
+ for (int i = 0; i < brushStyleCount; i++) {
+ const Qt::BrushStyle style = brushStyleIndexToStyle(i);
+ brush.setStyle(style);
+ brushIcons()->insert(i, QtPropertyBrowserUtils::brushValueIcon(brush));
+ }
+ }
+ return *(brushIcons());
+}
+
+QString BrushPropertyManager::brushStyleIndexToString(int brushStyleIndex)
+{
+ const int brushStyleCount = sizeof(brushStyles)/sizeof(const char *);
+ return brushStyleIndex < brushStyleCount ? QCoreApplication::translate("BrushPropertyManager", brushStyles[brushStyleIndex]) : QString();
+}
+
+void BrushPropertyManager::initializeProperty(QtVariantPropertyManager *vm, QtProperty *property, int enumTypeId)
+{
+ m_brushValues.insert(property, QBrush());
+ // style
+ QtVariantProperty *styleSubProperty = vm->addProperty(enumTypeId, QCoreApplication::translate("BrushPropertyManager", "Style"));
+ property->addSubProperty(styleSubProperty);
+ QStringList styles;
+ const int brushStyleCount = sizeof(brushStyles)/sizeof(const char *);
+ for (int i = 0; i < brushStyleCount; i++)
+ styles.push_back(QCoreApplication::translate("BrushPropertyManager", brushStyles[i]));
+ styleSubProperty->setAttribute(QLatin1String("enumNames"), styles);
+ styleSubProperty->setAttribute(QLatin1String("enumIcons"), QVariant::fromValue(brushStyleIcons()));
+ m_brushPropertyToStyleSubProperty.insert(property, styleSubProperty);
+ m_brushStyleSubPropertyToProperty.insert(styleSubProperty, property);
+ // color
+ QtVariantProperty *colorSubProperty = vm->addProperty(QVariant::Color, QCoreApplication::translate("BrushPropertyManager", "Color"));
+ property->addSubProperty(colorSubProperty);
+ m_brushPropertyToColorSubProperty.insert(property, colorSubProperty);
+ m_brushColorSubPropertyToProperty.insert(colorSubProperty, property);
+}
+
+bool BrushPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ const PropertyBrushMap::iterator brit = m_brushValues.find(property); // Brushes
+ if (brit == m_brushValues.end())
+ return false;
+ m_brushValues.erase(brit);
+ // style
+ PropertyToPropertyMap::iterator subit = m_brushPropertyToStyleSubProperty.find(property);
+ if (subit != m_brushPropertyToStyleSubProperty.end()) {
+ QtProperty *styleProp = subit.value();
+ m_brushStyleSubPropertyToProperty.remove(styleProp);
+ m_brushPropertyToStyleSubProperty.erase(subit);
+ delete styleProp;
+ }
+ // color
+ subit = m_brushPropertyToColorSubProperty.find(property);
+ if (subit != m_brushPropertyToColorSubProperty.end()) {
+ QtProperty *colorProp = subit.value();
+ m_brushColorSubPropertyToProperty.remove(colorProp);
+ m_brushPropertyToColorSubProperty.erase(subit);
+ delete colorProp;
+ }
+ return true;
+}
+
+void BrushPropertyManager::slotPropertyDestroyed(QtProperty *property)
+{
+ PropertyToPropertyMap::iterator subit = m_brushStyleSubPropertyToProperty.find(property);
+ if (subit != m_brushStyleSubPropertyToProperty.end()) {
+ m_brushPropertyToStyleSubProperty[subit.value()] = 0;
+ m_brushStyleSubPropertyToProperty.erase(subit);
+ }
+ subit = m_brushColorSubPropertyToProperty.find(property);
+ if (subit != m_brushColorSubPropertyToProperty.end()) {
+ m_brushPropertyToColorSubProperty[subit.value()] = 0;
+ m_brushColorSubPropertyToProperty.erase(subit);
+ }
+}
+
+
+BrushPropertyManager::ValueChangedResult BrushPropertyManager::valueChanged(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value)
+{
+ switch (value.type()) {
+ case QVariant::Int: // Style subproperty?
+ if (QtProperty *brushProperty = m_brushStyleSubPropertyToProperty.value(property, 0)) {
+ const QBrush oldValue = m_brushValues.value(brushProperty);
+ QBrush newBrush = oldValue;
+ const int index = value.toInt();
+ newBrush.setStyle(brushStyleIndexToStyle(index));
+ if (newBrush == oldValue)
+ return Unchanged;
+ vm->variantProperty(brushProperty)->setValue(newBrush);
+ return Changed;
+ }
+ break;
+ case QVariant::Color: // Color subproperty?
+ if (QtProperty *brushProperty = m_brushColorSubPropertyToProperty.value(property, 0)) {
+ const QBrush oldValue = m_brushValues.value(brushProperty);
+ QBrush newBrush = oldValue;
+ newBrush.setColor(qvariant_cast<QColor>(value));
+ if (newBrush == oldValue)
+ return Unchanged;
+ vm->variantProperty(brushProperty)->setValue(newBrush);
+ return Changed;
+ }
+ break;
+ default:
+ break;
+ }
+ return NoMatch;
+}
+
+BrushPropertyManager::ValueChangedResult BrushPropertyManager::setValue(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value)
+{
+ if (value.type() != QVariant::Brush)
+ return NoMatch;
+ const PropertyBrushMap::iterator brit = m_brushValues.find(property);
+ if (brit == m_brushValues.end())
+ return NoMatch;
+
+ const QBrush newBrush = qvariant_cast<QBrush>(value);
+ if (newBrush == brit.value())
+ return Unchanged;
+ brit.value() = newBrush;
+ if (QtProperty *styleProperty = m_brushPropertyToStyleSubProperty.value(property))
+ vm->variantProperty(styleProperty)->setValue(brushStyleToIndex(newBrush.style()));
+ if (QtProperty *colorProperty = m_brushPropertyToColorSubProperty.value(property))
+ vm->variantProperty(colorProperty)->setValue(newBrush.color());
+
+ return Changed;
+}
+
+bool BrushPropertyManager::valueText(const QtProperty *property, QString *text) const
+{
+ const PropertyBrushMap::const_iterator brit = m_brushValues.constFind(const_cast<QtProperty *>(property));
+ if (brit == m_brushValues.constEnd())
+ return false;
+ const QBrush &brush = brit.value();
+ const QString styleName = brushStyleIndexToString(brushStyleToIndex(brush.style()));
+ *text = QCoreApplication::translate("BrushPropertyManager", "[%1, %2]").arg(styleName).arg(QtPropertyBrowserUtils::colorValueText(brush.color()));
+ return true;
+}
+
+bool BrushPropertyManager::valueIcon(const QtProperty *property, QIcon *icon) const
+{
+ const PropertyBrushMap::const_iterator brit = m_brushValues.constFind(const_cast<QtProperty *>(property));
+ if (brit == m_brushValues.constEnd())
+ return false;
+ *icon = QtPropertyBrowserUtils::brushValueIcon(brit.value());
+ return true;
+}
+
+bool BrushPropertyManager::value(const QtProperty *property, QVariant *v) const
+{
+ const PropertyBrushMap::const_iterator brit = m_brushValues.constFind(const_cast<QtProperty *>(property));
+ if (brit == m_brushValues.constEnd())
+ return false;
+ qVariantSetValue(*v, brit.value());
+ return true;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/brushpropertymanager.h b/src/designer/src/components/propertyeditor/brushpropertymanager.h
new file mode 100644
index 000000000..5c008e2c4
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/brushpropertymanager.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BRUSHPROPERTYMANAGER_H
+#define BRUSHPROPERTYMANAGER_H
+
+#include <QtCore/QMap>
+#include <QtGui/QBrush>
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+class QtProperty;
+class QtVariantPropertyManager;
+
+class QString;
+class QVariant;
+
+namespace qdesigner_internal {
+
+// BrushPropertyManager: A mixin for DesignerPropertyManager that manages brush properties.
+
+class BrushPropertyManager {
+ BrushPropertyManager(const BrushPropertyManager&);
+ BrushPropertyManager &operator=(const BrushPropertyManager&);
+
+public:
+ BrushPropertyManager();
+
+ void initializeProperty(QtVariantPropertyManager *vm, QtProperty *property, int enumTypeId);
+ bool uninitializeProperty(QtProperty *property);
+
+ // Call from slotValueChanged().
+ enum ValueChangedResult { NoMatch, Unchanged, Changed };
+ ValueChangedResult valueChanged(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value);
+ ValueChangedResult setValue(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value);
+
+ bool valueText(const QtProperty *property, QString *text) const;
+ bool valueIcon(const QtProperty *property, QIcon *icon) const;
+ bool value(const QtProperty *property, QVariant *v) const;
+
+ // Call from QtPropertyManager's propertyDestroyed signal
+ void slotPropertyDestroyed(QtProperty *property);
+
+private:
+ static int brushStyleToIndex(Qt::BrushStyle st);
+ static Qt::BrushStyle brushStyleIndexToStyle(int brushStyleIndex);
+ static QString brushStyleIndexToString(int brushStyleIndex);
+
+ typedef QMap<int, QIcon> EnumIndexIconMap;
+ static const EnumIndexIconMap &brushStyleIcons();
+
+ typedef QMap<QtProperty *, QtProperty *> PropertyToPropertyMap;
+ PropertyToPropertyMap m_brushPropertyToStyleSubProperty;
+ PropertyToPropertyMap m_brushPropertyToColorSubProperty;
+ PropertyToPropertyMap m_brushStyleSubPropertyToProperty;
+ PropertyToPropertyMap m_brushColorSubPropertyToProperty;
+
+ typedef QMap<QtProperty *, QBrush> PropertyBrushMap;
+ PropertyBrushMap m_brushValues;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // BRUSHPROPERTYMANAGER_H
diff --git a/src/designer/src/components/propertyeditor/designerpropertymanager.cpp b/src/designer/src/components/propertyeditor/designerpropertymanager.cpp
new file mode 100644
index 000000000..78fb9aaf0
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/designerpropertymanager.cpp
@@ -0,0 +1,2836 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "designerpropertymanager.h"
+#include "qtpropertymanager.h"
+#include "paletteeditorbutton.h"
+#include "qlonglongvalidator.h"
+#include "stringlisteditorbutton.h"
+#include "qtresourceview_p.h"
+#include "qtpropertybrowserutils_p.h"
+
+#include <formwindowbase_p.h>
+#include <textpropertyeditor_p.h>
+#include <stylesheeteditor_p.h>
+#include <richtexteditor_p.h>
+#include <plaintexteditor_p.h>
+#include <iconloader_p.h>
+#include <iconselector_p.h>
+#include <abstractdialoggui_p.h>
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+
+#include <QtGui/QLabel>
+#include <QtGui/QToolButton>
+#include <QtGui/QHBoxLayout>
+#include <QtCore/QFileInfo>
+#include <QtGui/QClipboard>
+#include <QtGui/QLineEdit>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QFileDialog>
+#include <QtGui/QAction>
+#include <QtGui/QMenu>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QApplication>
+#include <QtCore/QUrl>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static const char *resettableAttributeC = "resettable";
+static const char *flagsAttributeC = "flags";
+static const char *validationModesAttributeC = "validationMode";
+static const char *superPaletteAttributeC = "superPalette";
+static const char *defaultResourceAttributeC = "defaultResource";
+static const char *fontAttributeC = "font";
+static const char *themeAttributeC = "theme";
+
+class DesignerFlagPropertyType
+{
+};
+
+
+class DesignerAlignmentPropertyType
+{
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(DesignerFlagPropertyType)
+Q_DECLARE_METATYPE(DesignerAlignmentPropertyType)
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ------------ TextEditor
+class TextEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ TextEditor(QDesignerFormEditorInterface *core, QWidget *parent);
+
+ TextPropertyValidationMode textPropertyValidationMode() const;
+ void setTextPropertyValidationMode(TextPropertyValidationMode vm);
+
+ void setRichTextDefaultFont(const QFont &font) { m_richTextDefaultFont = font; }
+ QFont richTextDefaultFont() const { return m_richTextDefaultFont; }
+
+ void setSpacing(int spacing);
+
+ TextPropertyEditor::UpdateMode updateMode() const { return m_editor->updateMode(); }
+ void setUpdateMode(TextPropertyEditor::UpdateMode um) { m_editor->setUpdateMode(um); }
+
+ void setIconThemeModeEnabled(bool enable);
+
+public slots:
+ void setText(const QString &text);
+
+signals:
+ void textChanged(const QString &text);
+
+private slots:
+ void buttonClicked();
+ void resourceActionActivated();
+ void fileActionActivated();
+private:
+ TextPropertyEditor *m_editor;
+ IconThemeEditor *m_themeEditor;
+ bool m_iconThemeModeEnabled;
+ QFont m_richTextDefaultFont;
+ QToolButton *m_button;
+ QMenu *m_menu;
+ QAction *m_resourceAction;
+ QAction *m_fileAction;
+ QHBoxLayout *m_layout;
+ QDesignerFormEditorInterface *m_core;
+};
+
+TextEditor::TextEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QWidget(parent),
+ m_editor(new TextPropertyEditor(this)),
+ m_themeEditor(new IconThemeEditor(this, false)),
+ m_iconThemeModeEnabled(false),
+ m_richTextDefaultFont(QApplication::font()),
+ m_button(new QToolButton(this)),
+ m_menu(new QMenu(this)),
+ m_resourceAction(new QAction(tr("Choose Resource..."), this)),
+ m_fileAction(new QAction(tr("Choose File..."), this)),
+ m_layout(new QHBoxLayout(this)),
+ m_core(core)
+{
+ m_themeEditor->setVisible(false);
+ m_button->setVisible(false);
+
+ m_layout->addWidget(m_editor);
+ m_layout->addWidget(m_themeEditor);
+ m_button->setText(tr("..."));
+ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+ m_button->setFixedWidth(20);
+ m_layout->addWidget(m_button);
+ m_layout->setMargin(0);
+ m_layout->setSpacing(0);
+
+ connect(m_resourceAction, SIGNAL(triggered()), this, SLOT(resourceActionActivated()));
+ connect(m_fileAction, SIGNAL(triggered()), this, SLOT(fileActionActivated()));
+ connect(m_editor, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString)));
+ connect(m_themeEditor, SIGNAL(edited(QString)), this, SIGNAL(textChanged(QString)));
+ connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+ setFocusProxy(m_editor);
+
+ m_menu->addAction(m_resourceAction);
+ m_menu->addAction(m_fileAction);
+}
+
+void TextEditor::setSpacing(int spacing)
+{
+ m_layout->setSpacing(spacing);
+}
+
+void TextEditor::setIconThemeModeEnabled(bool enable)
+{
+ if (m_iconThemeModeEnabled == enable)
+ return; // nothing changes
+ m_iconThemeModeEnabled = enable;
+ m_editor->setVisible(!enable);
+ m_themeEditor->setVisible(enable);
+ if (enable) {
+ m_themeEditor->setTheme(m_editor->text());
+ setFocusProxy(m_themeEditor);
+ } else {
+ m_editor->setText(m_themeEditor->theme());
+ setFocusProxy(m_editor);
+ }
+}
+
+TextPropertyValidationMode TextEditor::textPropertyValidationMode() const
+{
+ return m_editor->textPropertyValidationMode();
+}
+
+void TextEditor::setTextPropertyValidationMode(TextPropertyValidationMode vm)
+{
+ m_editor->setTextPropertyValidationMode(vm);
+ if (vm == ValidationURL) {
+ m_button->setMenu(m_menu);
+ m_button->setFixedWidth(30);
+ m_button->setPopupMode(QToolButton::MenuButtonPopup);
+ } else {
+ m_button->setMenu(0);
+ m_button->setFixedWidth(20);
+ m_button->setPopupMode(QToolButton::DelayedPopup);
+ }
+ m_button->setVisible(vm == ValidationStyleSheet || vm == ValidationRichText || vm == ValidationMultiLine || vm == ValidationURL);
+}
+
+void TextEditor::setText(const QString &text)
+{
+ if (m_iconThemeModeEnabled)
+ m_themeEditor->setTheme(text);
+ else
+ m_editor->setText(text);
+}
+
+void TextEditor::buttonClicked()
+{
+ const QString oldText = m_editor->text();
+ QString newText;
+ switch (textPropertyValidationMode()) {
+ case ValidationStyleSheet: {
+ StyleSheetEditorDialog dlg(m_core, this);
+ dlg.setText(oldText);
+ if (dlg.exec() != QDialog::Accepted)
+ return;
+ newText = dlg.text();
+ }
+ break;
+ case ValidationRichText: {
+ RichTextEditorDialog dlg(m_core, this);
+ dlg.setDefaultFont(m_richTextDefaultFont);
+ dlg.setText(oldText);
+ if (dlg.showDialog() != QDialog::Accepted)
+ return;
+ newText = dlg.text(Qt::AutoText);
+ }
+ break;
+ case ValidationMultiLine: {
+ PlainTextEditorDialog dlg(m_core, this);
+ dlg.setDefaultFont(m_richTextDefaultFont);
+ dlg.setText(oldText);
+ if (dlg.showDialog() != QDialog::Accepted)
+ return;
+ newText = dlg.text();
+ }
+ break;
+ case ValidationURL: {
+ QString oldPath = oldText;
+ if (oldPath.isEmpty() || oldPath.startsWith(QLatin1String("qrc:")))
+ resourceActionActivated();
+ else
+ fileActionActivated();
+ }
+ return;
+ default:
+ return;
+ }
+ if (newText != oldText) {
+ m_editor->setText(newText);
+ emit textChanged(newText);
+ }
+}
+
+void TextEditor::resourceActionActivated()
+{
+ QString oldPath = m_editor->text();
+ if (oldPath.startsWith(QLatin1String("qrc:")))
+ oldPath.remove(0, 4);
+ // returns ':/file'
+ QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), oldPath, this);
+ if (newPath.startsWith(QLatin1Char(':')))
+ newPath.remove(0, 1);
+ if (newPath.isEmpty() || newPath == oldPath)
+ return;
+ const QString newText = QLatin1String("qrc:") + newPath;
+ m_editor->setText(newText);
+ emit textChanged(newText);
+}
+
+void TextEditor::fileActionActivated()
+{
+ QString oldPath = m_editor->text();
+ if (oldPath.startsWith(QLatin1String("file:")))
+ oldPath = oldPath.mid(5);
+ const QString newPath = m_core->dialogGui()->getOpenFileName(this, tr("Choose a File"), oldPath);
+ if (newPath.isEmpty() || newPath == oldPath)
+ return;
+ const QString newText = QUrl::fromLocalFile(newPath).toString();
+ m_editor->setText(newText);
+ emit textChanged(newText);
+}
+
+// ------------ ThemeInputDialog
+
+class IconThemeDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ static QString getTheme(QWidget *parent, const QString &theme, bool *ok);
+private:
+ IconThemeDialog(QWidget *parent);
+ IconThemeEditor *m_editor;
+};
+
+IconThemeDialog::IconThemeDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ setWindowTitle(tr("Set Icon From Theme"));
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QLabel *label = new QLabel(tr("Input icon name from the current theme:"), this);
+ m_editor = new IconThemeEditor(this);
+ QDialogButtonBox *buttons = new QDialogButtonBox(this);
+ buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+
+ layout->addWidget(label);
+ layout->addWidget(m_editor);
+ layout->addWidget(buttons);
+
+ connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
+}
+
+QString IconThemeDialog::getTheme(QWidget *parent, const QString &theme, bool *ok)
+{
+ IconThemeDialog dlg(parent);
+ dlg.m_editor->setTheme(theme);
+ if (dlg.exec() == QDialog::Accepted) {
+ *ok = true;
+ return dlg.m_editor->theme();
+ }
+ *ok = false;
+ return QString();
+}
+
+// ------------ PixmapEditor
+class PixmapEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ PixmapEditor(QDesignerFormEditorInterface *core, QWidget *parent);
+
+ void setSpacing(int spacing);
+ void setPixmapCache(DesignerPixmapCache *cache);
+ void setIconThemeModeEnabled(bool enabled);
+public slots:
+ void setPath(const QString &path);
+ void setTheme(const QString &theme);
+ void setDefaultPixmap(const QPixmap &pixmap);
+
+signals:
+ void pathChanged(const QString &path);
+ void themeChanged(const QString &theme);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event);
+
+private slots:
+ void defaultActionActivated();
+ void resourceActionActivated();
+ void fileActionActivated();
+ void themeActionActivated();
+ void copyActionActivated();
+ void pasteActionActivated();
+ void clipboardDataChanged();
+private:
+ void updateLabels();
+ bool m_iconThemeModeEnabled;
+ QDesignerFormEditorInterface *m_core;
+ QLabel *m_pixmapLabel;
+ QLabel *m_pathLabel;
+ QToolButton *m_button;
+ QAction *m_resourceAction;
+ QAction *m_fileAction;
+ QAction *m_themeAction;
+ QAction *m_copyAction;
+ QAction *m_pasteAction;
+ QHBoxLayout *m_layout;
+ QPixmap m_defaultPixmap;
+ QString m_path;
+ QString m_theme;
+ DesignerPixmapCache *m_pixmapCache;
+};
+
+PixmapEditor::PixmapEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QWidget(parent),
+ m_iconThemeModeEnabled(false),
+ m_core(core),
+ m_pixmapLabel(new QLabel(this)),
+ m_pathLabel(new QLabel(this)),
+ m_button(new QToolButton(this)),
+ m_resourceAction(new QAction(tr("Choose Resource..."), this)),
+ m_fileAction(new QAction(tr("Choose File..."), this)),
+ m_themeAction(new QAction(tr("Set Icon From Theme..."), this)),
+ m_copyAction(new QAction(createIconSet(QLatin1String("editcopy.png")), tr("Copy Path"), this)),
+ m_pasteAction(new QAction(createIconSet(QLatin1String("editpaste.png")), tr("Paste Path"), this)),
+ m_layout(new QHBoxLayout(this)),
+ m_pixmapCache(0)
+{
+ m_layout->addWidget(m_pixmapLabel);
+ m_layout->addWidget(m_pathLabel);
+ m_button->setText(tr("..."));
+ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+ m_button->setFixedWidth(30);
+ m_button->setPopupMode(QToolButton::MenuButtonPopup);
+ m_layout->addWidget(m_button);
+ m_layout->setMargin(0);
+ m_layout->setSpacing(0);
+ m_pixmapLabel->setFixedWidth(16);
+ m_pixmapLabel->setAlignment(Qt::AlignCenter);
+ m_pathLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
+ m_themeAction->setVisible(false);
+
+ QMenu *menu = new QMenu(this);
+ menu->addAction(m_resourceAction);
+ menu->addAction(m_fileAction);
+ menu->addAction(m_themeAction);
+
+ m_button->setMenu(menu);
+ m_button->setText(tr("..."));
+
+ connect(m_button, SIGNAL(clicked()), this, SLOT(defaultActionActivated()));
+ connect(m_resourceAction, SIGNAL(triggered()), this, SLOT(resourceActionActivated()));
+ connect(m_fileAction, SIGNAL(triggered()), this, SLOT(fileActionActivated()));
+ connect(m_themeAction, SIGNAL(triggered()), this, SLOT(themeActionActivated()));
+ connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copyActionActivated()));
+ connect(m_pasteAction, SIGNAL(triggered()), this, SLOT(pasteActionActivated()));
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored));
+ setFocusProxy(m_button);
+
+ connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
+ clipboardDataChanged();
+}
+
+void PixmapEditor::setPixmapCache(DesignerPixmapCache *cache)
+{
+ m_pixmapCache = cache;
+}
+
+void PixmapEditor::setIconThemeModeEnabled(bool enabled)
+{
+ if (m_iconThemeModeEnabled == enabled)
+ return;
+ m_iconThemeModeEnabled = enabled;
+ m_themeAction->setVisible(enabled);
+}
+
+void PixmapEditor::setSpacing(int spacing)
+{
+ m_layout->setSpacing(spacing);
+}
+
+void PixmapEditor::setPath(const QString &path)
+{
+ m_path = path;
+ updateLabels();
+}
+
+void PixmapEditor::setTheme(const QString &theme)
+{
+ m_theme = theme;
+ updateLabels();
+}
+
+void PixmapEditor::updateLabels()
+{
+ if (m_iconThemeModeEnabled && QIcon::hasThemeIcon(m_theme)) {
+ m_pixmapLabel->setPixmap(QIcon::fromTheme(m_theme).pixmap(16, 16));
+ m_pathLabel->setText(tr("[Theme] %1").arg(m_theme));
+ m_copyAction->setEnabled(true);
+ } else {
+ if (m_path.isEmpty()) {
+ m_pathLabel->setText(m_path);
+ m_pixmapLabel->setPixmap(m_defaultPixmap);
+ m_copyAction->setEnabled(false);
+ } else {
+ m_pathLabel->setText(QFileInfo(m_path).fileName());
+ if (m_pixmapCache)
+ m_pixmapLabel->setPixmap(QIcon(m_pixmapCache->pixmap(PropertySheetPixmapValue(m_path))).pixmap(16, 16));
+ m_copyAction->setEnabled(true);
+ }
+ }
+}
+
+void PixmapEditor::setDefaultPixmap(const QPixmap &pixmap)
+{
+ m_defaultPixmap = QIcon(pixmap).pixmap(16, 16);
+ const bool hasThemeIcon = m_iconThemeModeEnabled && QIcon::hasThemeIcon(m_theme);
+ if (!hasThemeIcon && m_path.isEmpty())
+ m_pixmapLabel->setPixmap(m_defaultPixmap);
+}
+
+void PixmapEditor::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu menu(this);
+ menu.addAction(m_copyAction);
+ menu.addAction(m_pasteAction);
+ menu.exec(event->globalPos());
+ event->accept();
+}
+
+void PixmapEditor::defaultActionActivated()
+{
+ if (m_iconThemeModeEnabled && QIcon::hasThemeIcon(m_theme)) {
+ themeActionActivated();
+ return;
+ }
+ // Default to resource
+ const PropertySheetPixmapValue::PixmapSource ps = m_path.isEmpty() ? PropertySheetPixmapValue::ResourcePixmap : PropertySheetPixmapValue::getPixmapSource(m_core, m_path);
+ switch (ps) {
+ case PropertySheetPixmapValue::LanguageResourcePixmap:
+ case PropertySheetPixmapValue::ResourcePixmap:
+ resourceActionActivated();
+ break;
+ case PropertySheetPixmapValue::FilePixmap:
+ fileActionActivated();
+ break;
+ }
+}
+
+void PixmapEditor::resourceActionActivated()
+{
+ const QString oldPath = m_path;
+ const QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), oldPath, this);
+ if (!newPath.isEmpty() && newPath != oldPath) {
+ setTheme(QString());
+ setPath(newPath);
+ emit pathChanged(newPath);
+ }
+}
+
+void PixmapEditor::fileActionActivated()
+{
+ const QString newPath = IconSelector::choosePixmapFile(m_path, m_core->dialogGui(), this);
+ if (!newPath.isEmpty() && newPath != m_path) {
+ setTheme(QString());
+ setPath(newPath);
+ emit pathChanged(newPath);
+ }
+}
+
+void PixmapEditor::themeActionActivated()
+{
+ bool ok;
+ const QString newTheme = IconThemeDialog::getTheme(this, m_theme, &ok);
+ if (ok && newTheme != m_theme) {
+ setTheme(newTheme);
+ setPath(QString());
+ emit themeChanged(newTheme);
+ }
+}
+
+void PixmapEditor::copyActionActivated()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ if (m_iconThemeModeEnabled && QIcon::hasThemeIcon(m_theme))
+ clipboard->setText(m_theme);
+ else
+ clipboard->setText(m_path);
+}
+
+void PixmapEditor::pasteActionActivated()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ QString subtype = QLatin1String("plain");
+ QString text = clipboard->text(subtype);
+ if (!text.isNull()) {
+ QStringList list = text.split(QLatin1Char('\n'));
+ if (list.size() > 0) {
+ text = list.at(0);
+ if (m_iconThemeModeEnabled && QIcon::hasThemeIcon(text)) {
+ setTheme(text);
+ setPath(QString());
+ emit themeChanged(text);
+ } else {
+ setPath(text);
+ setTheme(QString());
+ emit pathChanged(text);
+ }
+ }
+ }
+}
+
+void PixmapEditor::clipboardDataChanged()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ QString subtype = QLatin1String("plain");
+ const QString text = clipboard->text(subtype);
+ m_pasteAction->setEnabled(!text.isNull());
+}
+
+// --------------- ResetWidget
+class ResetWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ ResetWidget(QtProperty *property, QWidget *parent = 0);
+
+ void setWidget(QWidget *widget);
+ void setResetEnabled(bool enabled);
+ void setValueText(const QString &text);
+ void setValueIcon(const QIcon &icon);
+ void setSpacing(int spacing);
+signals:
+ void resetProperty(QtProperty *property);
+private slots:
+ void slotClicked();
+private:
+ QtProperty *m_property;
+ QLabel *m_textLabel;
+ QLabel *m_iconLabel;
+ QToolButton *m_button;
+ int m_spacing;
+};
+
+ResetWidget::ResetWidget(QtProperty *property, QWidget *parent) :
+ QWidget(parent),
+ m_property(property),
+ m_textLabel(new QLabel(this)),
+ m_iconLabel(new QLabel(this)),
+ m_button(new QToolButton(this)),
+ m_spacing(-1)
+{
+ m_textLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
+ m_iconLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ m_button->setToolButtonStyle(Qt::ToolButtonIconOnly);
+ m_button->setIcon(createIconSet(QLatin1String("resetproperty.png")));
+ m_button->setIconSize(QSize(8,8));
+ m_button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding));
+ connect(m_button, SIGNAL(clicked()), this, SLOT(slotClicked()));
+ QLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ layout->setSpacing(m_spacing);
+ layout->addWidget(m_iconLabel);
+ layout->addWidget(m_textLabel);
+ layout->addWidget(m_button);
+ setFocusProxy(m_textLabel);
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+}
+
+void ResetWidget::setSpacing(int spacing)
+{
+ m_spacing = spacing;
+ layout()->setSpacing(m_spacing);
+}
+
+void ResetWidget::setWidget(QWidget *widget)
+{
+ if (m_textLabel) {
+ delete m_textLabel;
+ m_textLabel = 0;
+ }
+ if (m_iconLabel) {
+ delete m_iconLabel;
+ m_iconLabel = 0;
+ }
+ delete layout();
+ QLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ layout->setSpacing(m_spacing);
+ layout->addWidget(widget);
+ layout->addWidget(m_button);
+ setFocusProxy(widget);
+}
+
+void ResetWidget::setResetEnabled(bool enabled)
+{
+ m_button->setEnabled(enabled);
+}
+
+void ResetWidget::setValueText(const QString &text)
+{
+ if (m_textLabel)
+ m_textLabel->setText(text);
+}
+
+void ResetWidget::setValueIcon(const QIcon &icon)
+{
+ QPixmap pix = icon.pixmap(QSize(16, 16));
+ if (m_iconLabel) {
+ m_iconLabel->setVisible(!pix.isNull());
+ m_iconLabel->setPixmap(pix);
+ }
+}
+
+void ResetWidget::slotClicked()
+{
+ emit resetProperty(m_property);
+}
+
+
+// ------------ DesignerPropertyManager:
+
+DesignerPropertyManager::DesignerPropertyManager(QDesignerFormEditorInterface *core, QObject *parent) :
+ QtVariantPropertyManager(parent),
+ m_changingSubValue(false),
+ m_core(core),
+ m_sourceOfChange(0)
+{
+ connect(this, SIGNAL(valueChanged(QtProperty*,QVariant)), this, SLOT(slotValueChanged(QtProperty*,QVariant)));
+ connect(this, SIGNAL(propertyDestroyed(QtProperty*)), this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+DesignerPropertyManager::~DesignerPropertyManager()
+{
+ clear();
+}
+
+int DesignerPropertyManager::bitCount(int mask) const
+{
+ int count = 0;
+ for (; mask; count++)
+ mask &= mask - 1; // clear the least significant bit set
+ return count;
+}
+
+int DesignerPropertyManager::alignToIndexH(uint align) const
+{
+ if (align & Qt::AlignLeft)
+ return 0;
+ if (align & Qt::AlignHCenter)
+ return 1;
+ if (align & Qt::AlignRight)
+ return 2;
+ if (align & Qt::AlignJustify)
+ return 3;
+ return 0;
+}
+
+int DesignerPropertyManager::alignToIndexV(uint align) const
+{
+ if (align & Qt::AlignTop)
+ return 0;
+ if (align & Qt::AlignVCenter)
+ return 1;
+ if (align & Qt::AlignBottom)
+ return 2;
+ return 1;
+}
+
+uint DesignerPropertyManager::indexHToAlign(int idx) const
+{
+ switch (idx) {
+ case 0: return Qt::AlignLeft;
+ case 1: return Qt::AlignHCenter;
+ case 2: return Qt::AlignRight;
+ case 3: return Qt::AlignJustify;
+ default: break;
+ }
+ return Qt::AlignLeft;
+}
+
+uint DesignerPropertyManager::indexVToAlign(int idx) const
+{
+ switch (idx) {
+ case 0: return Qt::AlignTop;
+ case 1: return Qt::AlignVCenter;
+ case 2: return Qt::AlignBottom;
+ default: break;
+ }
+ return Qt::AlignVCenter;
+}
+
+QString DesignerPropertyManager::indexHToString(int idx) const
+{
+ switch (idx) {
+ case 0: return tr("AlignLeft");
+ case 1: return tr("AlignHCenter");
+ case 2: return tr("AlignRight");
+ case 3: return tr("AlignJustify");
+ default: break;
+ }
+ return tr("AlignLeft");
+}
+
+QString DesignerPropertyManager::indexVToString(int idx) const
+{
+ switch (idx) {
+ case 0: return tr("AlignTop");
+ case 1: return tr("AlignVCenter");
+ case 2: return tr("AlignBottom");
+ default: break;
+ }
+ return tr("AlignVCenter");
+}
+
+void DesignerPropertyManager::slotValueChanged(QtProperty *property, const QVariant &value)
+{
+ if (m_changingSubValue)
+ return;
+ bool enableSubPropertyHandling = true;
+
+ if (QtProperty *flagProperty = m_flagToProperty.value(property, 0)) {
+ const QList<QtProperty *> subFlags = m_propertyToFlags.value(flagProperty);
+ const int subFlagCount = subFlags.count();
+ // flag changed
+ const bool subValue = variantProperty(property)->value().toBool();
+ const int subIndex = subFlags.indexOf(property);
+ if (subIndex < 0)
+ return;
+
+ uint newValue = 0;
+
+ m_changingSubValue = true;
+
+ FlagData data = m_flagValues.value(flagProperty);
+ const QList<uint> values = data.values;
+ // Compute new value, without including (additional) supermasks
+ if (values.at(subIndex) == 0) {
+ for (int i = 0; i < subFlagCount; ++i) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
+ subFlag->setValue(i == subIndex);
+ }
+ } else {
+ if (subValue)
+ newValue = values.at(subIndex); // value mask of subValue
+ for (int i = 0; i < subFlagCount; ++i) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
+ if (subFlag->value().toBool() && bitCount(values.at(i)) == 1)
+ newValue |= values.at(i);
+ }
+ if (newValue == 0) {
+ // Uncheck all items except 0-mask
+ for (int i = 0; i < subFlagCount; ++i) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
+ subFlag->setValue(values.at(i) == 0);
+ }
+ } else if (newValue == data.val) {
+ if (!subValue && bitCount(values.at(subIndex)) > 1) {
+ // We unchecked something, but the original value still holds
+ variantProperty(property)->setValue(true);
+ }
+ } else {
+ // Make sure 0-mask is not selected
+ for (int i = 0; i < subFlagCount; ++i) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
+ if (values.at(i) == 0)
+ subFlag->setValue(false);
+ }
+ // Check/uncheck proper masks
+ if (subValue) {
+ // Make sure submasks and supermasks are selected
+ for (int i = 0; i < subFlagCount; ++i) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
+ const uint vi = values.at(i);
+ if ((vi != 0) && ((vi & newValue) == vi) && !subFlag->value().toBool())
+ subFlag->setValue(true);
+ }
+ } else {
+ // Make sure supermasks are not selected if they're no longer valid
+ for (int i = 0; i < subFlagCount; ++i) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
+ const uint vi = values.at(i);
+ if (subFlag->value().toBool() && ((vi & newValue) != vi))
+ subFlag->setValue(false);
+ }
+ }
+ }
+ }
+ m_changingSubValue = false;
+ data.val = newValue;
+ QVariant v;
+ v.setValue(data.val);
+ variantProperty(flagProperty)->setValue(v);
+ } else if (QtProperty *alignProperty = m_alignHToProperty.value(property, 0)) {
+ const uint v = m_alignValues.value(alignProperty);
+ const uint newValue = indexHToAlign(value.toInt()) | indexVToAlign(alignToIndexV(v));
+ if (v == newValue)
+ return;
+
+ variantProperty(alignProperty)->setValue(newValue);
+ } else if (QtProperty *alignProperty = m_alignVToProperty.value(property, 0)) {
+ const uint v = m_alignValues.value(alignProperty);
+ const uint newValue = indexVToAlign(value.toInt()) | indexHToAlign(alignToIndexH(v));
+ if (v == newValue)
+ return;
+
+ variantProperty(alignProperty)->setValue(newValue);
+ } else if (QtProperty *stringProperty = m_commentToString.value(property, 0)) {
+ const PropertySheetStringValue v = m_stringValues.value(stringProperty);
+ PropertySheetStringValue newValue = v;
+ newValue.setComment(value.toString());
+ if (v == newValue)
+ return;
+
+ variantProperty(stringProperty)->setValue(QVariant::fromValue(newValue));
+ } else if (QtProperty *stringProperty = m_translatableToString.value(property, 0)) {
+ const PropertySheetStringValue v = m_stringValues.value(stringProperty);
+ PropertySheetStringValue newValue = v;
+ newValue.setTranslatable(value.toBool());
+ if (v == newValue)
+ return;
+
+ variantProperty(stringProperty)->setValue(QVariant::fromValue(newValue));
+ } else if (QtProperty *stringProperty = m_disambiguationToString.value(property, 0)) {
+ const PropertySheetStringValue v = m_stringValues.value(stringProperty);
+ PropertySheetStringValue newValue = v;
+ newValue.setDisambiguation(value.toString());
+ if (v == newValue)
+ return;
+
+ variantProperty(stringProperty)->setValue(QVariant::fromValue(newValue));
+ } else if (QtProperty *keySequenceProperty = m_commentToKeySequence.value(property, 0)) {
+ const PropertySheetKeySequenceValue v = m_keySequenceValues.value(keySequenceProperty);
+ PropertySheetKeySequenceValue newValue = v;
+ newValue.setComment(value.toString());
+ if (v == newValue)
+ return;
+
+ variantProperty(keySequenceProperty)->setValue(QVariant::fromValue(newValue));
+ } else if (QtProperty *keySequenceProperty = m_translatableToKeySequence.value(property, 0)) {
+ const PropertySheetKeySequenceValue v = m_keySequenceValues.value(keySequenceProperty);
+ PropertySheetKeySequenceValue newValue = v;
+ newValue.setTranslatable(value.toBool());
+ if (v == newValue)
+ return;
+
+ variantProperty(keySequenceProperty)->setValue(QVariant::fromValue(newValue));
+ } else if (QtProperty *keySequenceProperty = m_disambiguationToKeySequence.value(property, 0)) {
+ const PropertySheetKeySequenceValue v = m_keySequenceValues.value(keySequenceProperty);
+ PropertySheetKeySequenceValue newValue = v;
+ newValue.setDisambiguation(value.toString());
+ if (v == newValue)
+ return;
+
+ variantProperty(keySequenceProperty)->setValue(QVariant::fromValue(newValue));
+ } else if (QtProperty *iProperty = m_iconSubPropertyToProperty.value(property, 0)) {
+ QtVariantProperty *iconProperty = variantProperty(iProperty);
+ PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(iconProperty->value());
+ QMap<QtProperty *, QPair<QIcon::Mode, QIcon::State> >::ConstIterator itState = m_iconSubPropertyToState.constFind(property);
+ if (itState != m_iconSubPropertyToState.constEnd()) {
+ QPair<QIcon::Mode, QIcon::State> pair = m_iconSubPropertyToState.value(property);
+ icon.setPixmap(pair.first, pair.second, qvariant_cast<PropertySheetPixmapValue>(value));
+ } else { // must be theme property
+ icon.setTheme(value.toString());
+ }
+ QtProperty *origSourceOfChange = m_sourceOfChange;
+ if (!origSourceOfChange)
+ m_sourceOfChange = property;
+ iconProperty->setValue(QVariant::fromValue(icon));
+ if (!origSourceOfChange)
+ m_sourceOfChange = origSourceOfChange;
+ } else if (m_iconValues.contains(property)) {
+ enableSubPropertyHandling = m_sourceOfChange;
+ } else {
+ if (m_brushManager.valueChanged(this, property, value) == BrushPropertyManager::Unchanged)
+ return;
+ if (m_fontManager.valueChanged(this, property, value) == FontPropertyManager::Unchanged)
+ return;
+ }
+
+ emit valueChanged(property, value, enableSubPropertyHandling);
+}
+
+void DesignerPropertyManager::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *flagProperty = m_flagToProperty.value(property, 0)) {
+ PropertyToPropertyListMap::iterator it = m_propertyToFlags.find(flagProperty);
+ QList<QtProperty *> &propertyList = it.value();
+ propertyList.replace(propertyList.indexOf(property), 0);
+ m_flagToProperty.remove(property);
+ } else if (QtProperty *alignProperty = m_alignHToProperty.value(property, 0)) {
+ m_propertyToAlignH.remove(alignProperty);
+ m_alignHToProperty.remove(property);
+ } else if (QtProperty *alignProperty = m_alignVToProperty.value(property, 0)) {
+ m_propertyToAlignV.remove(alignProperty);
+ m_alignVToProperty.remove(property);
+ } else if (QtProperty *stringCommentProperty = m_commentToString.value(property, 0)) {
+ m_stringToComment.remove(stringCommentProperty);
+ m_commentToString.remove(property);
+ } else if (QtProperty *stringTranslatableProperty = m_translatableToString.value(property, 0)) {
+ m_stringToTranslatable.remove(stringTranslatableProperty);
+ m_translatableToString.remove(property);
+ } else if (QtProperty *stringDisambiguationProperty = m_disambiguationToString.value(property, 0)) {
+ m_stringToDisambiguation.remove(stringDisambiguationProperty);
+ m_disambiguationToString.remove(property);
+ } else if (QtProperty *keySequenceCommentProperty = m_commentToKeySequence.value(property, 0)) {
+ m_keySequenceToComment.remove(keySequenceCommentProperty);
+ m_commentToKeySequence.remove(property);
+ } else if (QtProperty *keySequenceTranslatableProperty = m_translatableToKeySequence.value(property, 0)) {
+ m_keySequenceToTranslatable.remove(keySequenceTranslatableProperty);
+ m_translatableToKeySequence.remove(property);
+ } else if (QtProperty *keySequenceDisambiguationProperty = m_disambiguationToKeySequence.value(property, 0)) {
+ m_keySequenceToDisambiguation.remove(keySequenceDisambiguationProperty);
+ m_disambiguationToKeySequence.remove(property);
+ } else if (QtProperty *iconProperty = m_iconSubPropertyToProperty.value(property, 0)) {
+ if (m_propertyToTheme.value(iconProperty) == property) {
+ m_propertyToTheme.remove(iconProperty);
+ } else {
+ QMap<QtProperty *, QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> >::iterator it =
+ m_propertyToIconSubProperties.find(iconProperty);
+ QPair<QIcon::Mode, QIcon::State> state = m_iconSubPropertyToState.value(property);
+ QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> &propertyList = it.value();
+ propertyList.remove(state);
+ m_iconSubPropertyToState.remove(property);
+ }
+ m_iconSubPropertyToProperty.remove(property);
+ } else {
+ m_fontManager.slotPropertyDestroyed(property);
+ m_brushManager.slotPropertyDestroyed(property);
+ }
+}
+
+QStringList DesignerPropertyManager::attributes(int propertyType) const
+{
+ if (!isPropertyTypeSupported(propertyType))
+ return QStringList();
+
+ QStringList list = QtVariantPropertyManager::attributes(propertyType);
+ if (propertyType == designerFlagTypeId()) {
+ list.append(QLatin1String(flagsAttributeC));
+ } else if (propertyType == designerPixmapTypeId()) {
+ list.append(QLatin1String(defaultResourceAttributeC));
+ } else if (propertyType == designerIconTypeId()) {
+ list.append(QLatin1String(defaultResourceAttributeC));
+ } else if (propertyType == designerStringTypeId() || propertyType == QVariant::String) {
+ list.append(QLatin1String(validationModesAttributeC));
+ list.append(QLatin1String(fontAttributeC));
+ list.append(QLatin1String(themeAttributeC));
+ } else if (propertyType == QVariant::Palette) {
+ list.append(QLatin1String(superPaletteAttributeC));
+ }
+ list.append(QLatin1String(resettableAttributeC));
+ return list;
+}
+
+int DesignerPropertyManager::attributeType(int propertyType, const QString &attribute) const
+{
+ if (!isPropertyTypeSupported(propertyType))
+ return 0;
+
+ if (propertyType == designerFlagTypeId() && attribute == QLatin1String(flagsAttributeC))
+ return designerFlagListTypeId();
+ if (propertyType == designerPixmapTypeId() && attribute == QLatin1String(defaultResourceAttributeC))
+ return QVariant::Pixmap;
+ if (propertyType == designerIconTypeId() && attribute == QLatin1String(defaultResourceAttributeC))
+ return QVariant::Icon;
+ if (attribute == QLatin1String(resettableAttributeC))
+ return QVariant::Bool;
+ if (propertyType == designerStringTypeId() || propertyType == QVariant::String) {
+ if (attribute == QLatin1String(validationModesAttributeC))
+ return QVariant::Int;
+ if (attribute == QLatin1String(fontAttributeC))
+ return QVariant::Font;
+ if (attribute == QLatin1String(themeAttributeC))
+ return QVariant::Bool;
+ }
+ if (propertyType == QVariant::Palette && attribute == QLatin1String(superPaletteAttributeC))
+ return QVariant::Palette;
+
+ return QtVariantPropertyManager::attributeType(propertyType, attribute);
+}
+
+QVariant DesignerPropertyManager::attributeValue(const QtProperty *property, const QString &attribute) const
+{
+ QtProperty *prop = const_cast<QtProperty *>(property);
+
+ if (attribute == QLatin1String(resettableAttributeC)) {
+ const PropertyBoolMap::const_iterator it = m_resetMap.constFind(prop);
+ if (it != m_resetMap.constEnd())
+ return it.value();
+ }
+
+ if (attribute == QLatin1String(flagsAttributeC)) {
+ PropertyFlagDataMap::const_iterator it = m_flagValues.constFind(prop);
+ if (it != m_flagValues.constEnd()) {
+ QVariant v;
+ v.setValue(it.value().flags);
+ return v;
+ }
+ }
+ if (attribute == QLatin1String(validationModesAttributeC)) {
+ const PropertyIntMap::const_iterator it = m_stringAttributes.constFind(prop);
+ if (it != m_stringAttributes.constEnd())
+ return it.value();
+ }
+
+ if (attribute == QLatin1String(fontAttributeC)) {
+ const PropertyFontMap::const_iterator it = m_stringFontAttributes.constFind(prop);
+ if (it != m_stringFontAttributes.constEnd())
+ return it.value();
+ }
+
+ if (attribute == QLatin1String(themeAttributeC)) {
+ const PropertyBoolMap::const_iterator it = m_stringThemeAttributes.constFind(prop);
+ if (it != m_stringThemeAttributes.constEnd())
+ return it.value();
+ }
+
+ if (attribute == QLatin1String(superPaletteAttributeC)) {
+ PropertyPaletteDataMap::const_iterator it = m_paletteValues.constFind(prop);
+ if (it != m_paletteValues.constEnd())
+ return it.value().superPalette;
+ }
+
+ if (attribute == QLatin1String(defaultResourceAttributeC)) {
+ QMap<QtProperty *, QPixmap>::const_iterator itPix = m_defaultPixmaps.constFind(prop);
+ if (itPix != m_defaultPixmaps.constEnd())
+ return itPix.value();
+
+ QMap<QtProperty *, QIcon>::const_iterator itIcon = m_defaultIcons.constFind(prop);
+ if (itIcon != m_defaultIcons.constEnd())
+ return itIcon.value();
+ }
+
+ return QtVariantPropertyManager::attributeValue(property, attribute);
+}
+
+void DesignerPropertyManager::setAttribute(QtProperty *property,
+ const QString &attribute, const QVariant &value)
+{
+ if (attribute == QLatin1String(resettableAttributeC) && m_resetMap.contains(property)) {
+ if (value.userType() != QVariant::Bool)
+ return;
+ const bool val = value.toBool();
+ const PropertyBoolMap::iterator it = m_resetMap.find(property);
+ if (it.value() == val)
+ return;
+ it.value() = val;
+ emit attributeChanged(variantProperty(property), attribute, value);
+ return;
+ } else if (attribute == QLatin1String(flagsAttributeC) && m_flagValues.contains(property)) {
+ if (value.userType() != designerFlagListTypeId())
+ return;
+
+ const DesignerFlagList flags = qvariant_cast<DesignerFlagList>(value);
+ PropertyFlagDataMap::iterator fit = m_flagValues.find(property);
+ FlagData data = fit.value();
+ if (data.flags == flags)
+ return;
+
+ PropertyToPropertyListMap::iterator pfit = m_propertyToFlags.find(property);
+ QListIterator<QtProperty *> itProp(pfit.value());
+ while (itProp.hasNext()) {
+ if (QtProperty *prop = itProp.next()) {
+ delete prop;
+ m_flagToProperty.remove(prop);
+ }
+ }
+ pfit.value().clear();
+
+ QList<uint> values;
+
+ QListIterator<QPair<QString, uint> > itFlag(flags);
+ while (itFlag.hasNext()) {
+ const QPair<QString, uint> pair = itFlag.next();
+ const QString flagName = pair.first;
+ QtProperty *prop = addProperty(QVariant::Bool);
+ prop->setPropertyName(flagName);
+ property->addSubProperty(prop);
+ m_propertyToFlags[property].append(prop);
+ m_flagToProperty[prop] = property;
+ values.append(pair.second);
+ }
+
+ data.val = 0;
+ data.flags = flags;
+ data.values = values;
+
+ fit.value() = data;
+
+ QVariant v;
+ v.setValue(flags);
+ emit attributeChanged(property, attribute, v);
+
+ emit propertyChanged(property);
+ emit QtVariantPropertyManager::valueChanged(property, data.val);
+ } else if (attribute == QLatin1String(validationModesAttributeC) && m_stringAttributes.contains(property)) {
+ if (value.userType() != QVariant::Int)
+ return;
+
+ const PropertyIntMap::iterator it = m_stringAttributes.find(property);
+ const int oldValue = it.value();
+
+ const int newValue = value.toInt();
+
+ if (oldValue == newValue)
+ return;
+
+ it.value() = newValue;
+
+ emit attributeChanged(property, attribute, newValue);
+ } else if (attribute == QLatin1String(fontAttributeC) && m_stringFontAttributes.contains(property)) {
+ if (value.userType() != QVariant::Font)
+ return;
+
+ const PropertyFontMap::iterator it = m_stringFontAttributes.find(property);
+ const QFont oldValue = it.value();
+
+ const QFont newValue = qvariant_cast<QFont>(value);
+
+ if (oldValue == newValue)
+ return;
+
+ it.value() = newValue;
+
+ emit attributeChanged(property, attribute, newValue);
+ } else if (attribute == QLatin1String(themeAttributeC) && m_stringThemeAttributes.contains(property)) {
+ if (value.userType() != QVariant::Bool)
+ return;
+
+ const PropertyBoolMap::iterator it = m_stringThemeAttributes.find(property);
+ const bool oldValue = it.value();
+
+ const bool newValue = value.toBool();
+
+ if (oldValue == newValue)
+ return;
+
+ it.value() = newValue;
+
+ emit attributeChanged(property, attribute, newValue);
+ } else if (attribute == QLatin1String(superPaletteAttributeC) && m_paletteValues.contains(property)) {
+ if (value.userType() != QVariant::Palette)
+ return;
+
+ QPalette superPalette = qvariant_cast<QPalette>(value);
+
+ const PropertyPaletteDataMap::iterator it = m_paletteValues.find(property);
+ PaletteData data = it.value();
+ if (data.superPalette == superPalette)
+ return;
+
+ data.superPalette = superPalette;
+ // resolve here
+ const uint mask = data.val.resolve();
+ data.val = data.val.resolve(superPalette);
+ data.val.resolve(mask);
+
+ it.value() = data;
+
+ QVariant v;
+ v.setValue(superPalette);
+ emit attributeChanged(property, attribute, v);
+
+ emit propertyChanged(property);
+ emit QtVariantPropertyManager::valueChanged(property, data.val); // if resolve was done, this is also for consistency
+ } else if (attribute == QLatin1String(defaultResourceAttributeC) && m_defaultPixmaps.contains(property)) {
+ if (value.userType() != QVariant::Pixmap)
+ return;
+
+ QPixmap defaultPixmap = qvariant_cast<QPixmap>(value);
+
+ const QMap<QtProperty *, QPixmap>::iterator it = m_defaultPixmaps.find(property);
+ QPixmap oldDefaultPixmap = it.value();
+ if (defaultPixmap.cacheKey() == oldDefaultPixmap.cacheKey())
+ return;
+
+ it.value() = defaultPixmap;
+
+ QVariant v = QVariant::fromValue(defaultPixmap);
+ emit attributeChanged(property, attribute, v);
+
+ emit propertyChanged(property);
+ } else if (attribute == QLatin1String(defaultResourceAttributeC) && m_defaultIcons.contains(property)) {
+ if (value.userType() != QVariant::Icon)
+ return;
+
+ QIcon defaultIcon = qvariant_cast<QIcon>(value);
+
+ const QMap<QtProperty *, QIcon>::iterator it = m_defaultIcons.find(property);
+ QIcon oldDefaultIcon = it.value();
+ if (defaultIcon.cacheKey() == oldDefaultIcon.cacheKey())
+ return;
+
+ it.value() = defaultIcon;
+
+ qdesigner_internal::PropertySheetIconValue icon = m_iconValues.value(property);
+ if (icon.paths().isEmpty()) {
+ QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> subIconProperties = m_propertyToIconSubProperties.value(property);
+ QMapIterator<QPair<QIcon::Mode, QIcon::State>, QtProperty *> itSub(subIconProperties);
+ while (itSub.hasNext()) {
+ QPair<QIcon::Mode, QIcon::State> pair = itSub.next().key();
+ QtProperty *subProp = itSub.value();
+ setAttribute(subProp, QLatin1String(defaultResourceAttributeC),
+ defaultIcon.pixmap(16, 16, pair.first, pair.second));
+ }
+ }
+
+ QVariant v = QVariant::fromValue(defaultIcon);
+ emit attributeChanged(property, attribute, v);
+
+ emit propertyChanged(property);
+ }
+ QtVariantPropertyManager::setAttribute(property, attribute, value);
+}
+
+int DesignerPropertyManager::designerFlagTypeId()
+{
+ static const int rc = qMetaTypeId<DesignerFlagPropertyType>();
+ return rc;
+}
+
+int DesignerPropertyManager::designerFlagListTypeId()
+{
+ static const int rc = qMetaTypeId<DesignerFlagList>();
+ return rc;
+}
+
+int DesignerPropertyManager::designerAlignmentTypeId()
+{
+ static const int rc = qMetaTypeId<DesignerAlignmentPropertyType>();
+ return rc;
+}
+
+int DesignerPropertyManager::designerPixmapTypeId()
+{
+ return qMetaTypeId<PropertySheetPixmapValue>();
+}
+
+int DesignerPropertyManager::designerIconTypeId()
+{
+ return qMetaTypeId<PropertySheetIconValue>();
+}
+
+int DesignerPropertyManager::designerStringTypeId()
+{
+ return qMetaTypeId<PropertySheetStringValue>();
+}
+
+int DesignerPropertyManager::designerKeySequenceTypeId()
+{
+ return qMetaTypeId<PropertySheetKeySequenceValue>();
+}
+
+bool DesignerPropertyManager::isPropertyTypeSupported(int propertyType) const
+{
+ switch (propertyType) {
+ case QVariant::Palette:
+ case QVariant::UInt:
+ case QVariant::LongLong:
+ case QVariant::ULongLong:
+ case QVariant::Url:
+ case QVariant::ByteArray:
+ case QVariant::StringList:
+ case QVariant::Brush:
+ return true;
+ default:
+ break;
+ }
+
+ if (propertyType == designerFlagTypeId())
+ return true;
+ if (propertyType == designerAlignmentTypeId())
+ return true;
+ if (propertyType == designerPixmapTypeId())
+ return true;
+ if (propertyType == designerIconTypeId())
+ return true;
+ if (propertyType == designerStringTypeId())
+ return true;
+ if (propertyType == designerKeySequenceTypeId())
+ return true;
+ return QtVariantPropertyManager::isPropertyTypeSupported(propertyType);
+}
+
+QString DesignerPropertyManager::valueText(const QtProperty *property) const
+{
+ if (m_flagValues.contains(const_cast<QtProperty *>(property))) {
+ const FlagData data = m_flagValues.value(const_cast<QtProperty *>(property));
+ const uint v = data.val;
+ const QChar bar = QLatin1Char('|');
+ QString valueStr;
+ const QList<QPair<QString, uint> > flags = data.flags;
+ const QList<QPair<QString, uint> >::const_iterator fcend = flags.constEnd();
+ for (QList<QPair<QString, uint> >::const_iterator it = flags.constBegin(); it != fcend; ++it) {
+ const uint val = it->second;
+ const bool checked = (val == 0) ? (v == 0) : ((val & v) == val);
+ if (checked) {
+ if (!valueStr.isEmpty())
+ valueStr += bar;
+ valueStr += it->first;
+ }
+ }
+ return valueStr;
+ }
+ if (m_alignValues.contains(const_cast<QtProperty *>(property))) {
+ const uint v = m_alignValues.value(const_cast<QtProperty *>(property));
+ return tr("%1, %2").arg(indexHToString(alignToIndexH(v))).arg(indexVToString(alignToIndexV(v)));
+ }
+ if (m_paletteValues.contains(const_cast<QtProperty *>(property))) {
+ const PaletteData data = m_paletteValues.value(const_cast<QtProperty *>(property));
+ const uint mask = data.val.resolve();
+ if (mask)
+ return tr("Customized (%n roles)", 0, bitCount(mask));
+ static const QString inherited = tr("Inherited");
+ return inherited;
+ }
+ if (m_iconValues.contains(const_cast<QtProperty *>(property))) {
+ const PropertySheetIconValue icon = m_iconValues.value(const_cast<QtProperty *>(property));
+ const QString theme = icon.theme();
+ if (!theme.isEmpty() && QIcon::hasThemeIcon(theme))
+ return tr("[Theme] %1").arg(theme);
+ const PropertySheetIconValue::ModeStateToPixmapMap paths = icon.paths();
+ const PropertySheetIconValue::ModeStateToPixmapMap::const_iterator it = paths.constFind(qMakePair(QIcon::Normal, QIcon::Off));
+ if (it == paths.constEnd())
+ return QString();
+ return QFileInfo(it.value().path()).fileName();
+ }
+ if (m_pixmapValues.contains(const_cast<QtProperty *>(property))) {
+ const QString path = m_pixmapValues.value(const_cast<QtProperty *>(property)).path();
+ if (path.isEmpty())
+ return QString();
+ return QFileInfo(path).fileName();
+ }
+ if (m_uintValues.contains(const_cast<QtProperty *>(property))) {
+ return QString::number(m_uintValues.value(const_cast<QtProperty *>(property)));
+ }
+ if (m_longLongValues.contains(const_cast<QtProperty *>(property))) {
+ return QString::number(m_longLongValues.value(const_cast<QtProperty *>(property)));
+ }
+ if (m_uLongLongValues.contains(const_cast<QtProperty *>(property))) {
+ return QString::number(m_uLongLongValues.value(const_cast<QtProperty *>(property)));
+ }
+ if (m_urlValues.contains(const_cast<QtProperty *>(property))) {
+ return m_urlValues.value(const_cast<QtProperty *>(property)).toString();
+ }
+ if (m_byteArrayValues.contains(const_cast<QtProperty *>(property))) {
+ return QString::fromUtf8(m_byteArrayValues.value(const_cast<QtProperty *>(property)));
+ }
+ if (m_stringListValues.contains(const_cast<QtProperty *>(property))) {
+ return m_stringListValues.value(const_cast<QtProperty *>(property)).join(QLatin1String("; "));
+ }
+ if (QtVariantPropertyManager::valueType(property) == QVariant::String || QtVariantPropertyManager::valueType(property) == designerStringTypeId()) {
+ const QString str = (QtVariantPropertyManager::valueType(property) == QVariant::String) ? value(property).toString() : qvariant_cast<PropertySheetStringValue>(value(property)).value();
+ const int validationMode = attributeValue(property, QLatin1String(validationModesAttributeC)).toInt();
+ return TextPropertyEditor::stringToEditorString(str, static_cast<TextPropertyValidationMode>(validationMode));
+ }
+ if (QtVariantPropertyManager::valueType(property) == designerKeySequenceTypeId()) {
+ return qvariant_cast<PropertySheetKeySequenceValue>(value(property)).value();
+ }
+ if (QtVariantPropertyManager::valueType(property) == QVariant::Bool) {
+ return QString();
+ }
+
+ QString rc;
+ if (m_brushManager.valueText(property, &rc))
+ return rc;
+ return QtVariantPropertyManager::valueText(property);
+}
+
+void DesignerPropertyManager::reloadResourceProperties()
+{
+ DesignerIconCache *iconCache = 0;
+ QMapIterator<QtProperty *, qdesigner_internal::PropertySheetIconValue> itIcon(m_iconValues);
+ while (itIcon.hasNext()) {
+ QtProperty *property = itIcon.next().key();
+ PropertySheetIconValue icon = itIcon.value();
+
+ QIcon defaultIcon = m_defaultIcons.value(property);
+ if (!icon.paths().isEmpty()) {
+ if (!iconCache) {
+ QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
+ qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
+ iconCache = fwb->iconCache();
+ }
+ if (iconCache)
+ defaultIcon = iconCache->icon(icon);
+ }
+
+ QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> iconPaths = icon.paths();
+
+ QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> subProperties = m_propertyToIconSubProperties.value(property);
+ QMapIterator<QPair<QIcon::Mode, QIcon::State>, QtProperty *> itSub(subProperties);
+ while (itSub.hasNext()) {
+ const QPair<QIcon::Mode, QIcon::State> pair = itSub.next().key();
+ QtVariantProperty *subProperty = variantProperty(itSub.value());
+ subProperty->setAttribute(QLatin1String(defaultResourceAttributeC),
+ defaultIcon.pixmap(16, 16, pair.first, pair.second));
+ }
+
+ emit propertyChanged(property);
+ emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(itIcon.value()));
+ }
+ QMapIterator<QtProperty *, qdesigner_internal::PropertySheetPixmapValue> itPix(m_pixmapValues);
+ while (itPix.hasNext()) {
+ QtProperty *property = itPix.next().key();
+ emit propertyChanged(property);
+ emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(itPix.value()));
+ }
+}
+
+QIcon DesignerPropertyManager::valueIcon(const QtProperty *property) const
+{
+ if (m_iconValues.contains(const_cast<QtProperty *>(property))) {
+ if (!property->isModified())
+ return m_defaultIcons.value(const_cast<QtProperty *>(property)).pixmap(16, 16);
+ QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
+ qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
+ if (fwb)
+ return fwb->iconCache()->icon(m_iconValues.value(const_cast<QtProperty *>(property))).pixmap(16, 16);
+ } else if (m_pixmapValues.contains(const_cast<QtProperty *>(property))) {
+ if (!property->isModified())
+ return m_defaultPixmaps.value(const_cast<QtProperty *>(property));
+ QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
+ qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
+ if (fwb)
+ return fwb->pixmapCache()->pixmap(m_pixmapValues.value(const_cast<QtProperty *>(property)));
+ } else if (m_stringThemeAttributes.value(const_cast<QtProperty *>(property), false)) {
+ return QIcon::fromTheme(value(property).toString());
+ } else {
+ QIcon rc;
+ if (m_brushManager.valueIcon(property, &rc))
+ return rc;
+ }
+
+ return QtVariantPropertyManager::valueIcon(property);
+}
+
+QVariant DesignerPropertyManager::value(const QtProperty *property) const
+{
+ if (m_flagValues.contains(const_cast<QtProperty *>(property)))
+ return m_flagValues.value(const_cast<QtProperty *>(property)).val;
+ if (m_alignValues.contains(const_cast<QtProperty *>(property)))
+ return m_alignValues.value(const_cast<QtProperty *>(property));
+ if (m_paletteValues.contains(const_cast<QtProperty *>(property)))
+ return m_paletteValues.value(const_cast<QtProperty *>(property)).val;
+ if (m_iconValues.contains(const_cast<QtProperty *>(property)))
+ return QVariant::fromValue(m_iconValues.value(const_cast<QtProperty *>(property)));
+ if (m_pixmapValues.contains(const_cast<QtProperty *>(property)))
+ return QVariant::fromValue(m_pixmapValues.value(const_cast<QtProperty *>(property)));
+ if (m_stringValues.contains(const_cast<QtProperty *>(property)))
+ return QVariant::fromValue(m_stringValues.value(const_cast<QtProperty *>(property)));
+ if (m_keySequenceValues.contains(const_cast<QtProperty *>(property)))
+ return QVariant::fromValue(m_keySequenceValues.value(const_cast<QtProperty *>(property)));
+ if (m_uintValues.contains(const_cast<QtProperty *>(property)))
+ return m_uintValues.value(const_cast<QtProperty *>(property));
+ if (m_longLongValues.contains(const_cast<QtProperty *>(property)))
+ return m_longLongValues.value(const_cast<QtProperty *>(property));
+ if (m_uLongLongValues.contains(const_cast<QtProperty *>(property)))
+ return m_uLongLongValues.value(const_cast<QtProperty *>(property));
+ if (m_urlValues.contains(const_cast<QtProperty *>(property)))
+ return m_urlValues.value(const_cast<QtProperty *>(property));
+ if (m_byteArrayValues.contains(const_cast<QtProperty *>(property)))
+ return m_byteArrayValues.value(const_cast<QtProperty *>(property));
+ if (m_stringListValues.contains(const_cast<QtProperty *>(property)))
+ return m_stringListValues.value(const_cast<QtProperty *>(property));
+
+ QVariant rc;
+ if (m_brushManager.value(property, &rc))
+ return rc;
+ return QtVariantPropertyManager::value(property);
+}
+
+int DesignerPropertyManager::valueType(int propertyType) const
+{
+ switch (propertyType) {
+ case QVariant::Palette:
+ case QVariant::UInt:
+ case QVariant::LongLong:
+ case QVariant::ULongLong:
+ case QVariant::Url:
+ case QVariant::ByteArray:
+ case QVariant::StringList:
+ case QVariant::Brush:
+ return propertyType;
+ default:
+ break;
+ }
+ if (propertyType == designerFlagTypeId())
+ return QVariant::UInt;
+ if (propertyType == designerAlignmentTypeId())
+ return QVariant::UInt;
+ if (propertyType == designerPixmapTypeId())
+ return propertyType;
+ if (propertyType == designerIconTypeId())
+ return propertyType;
+ if (propertyType == designerStringTypeId())
+ return propertyType;
+ if (propertyType == designerKeySequenceTypeId())
+ return propertyType;
+ return QtVariantPropertyManager::valueType(propertyType);
+}
+
+void DesignerPropertyManager::setValue(QtProperty *property, const QVariant &value)
+{
+ const PropertyFlagDataMap::iterator fit = m_flagValues.find(property);
+
+ if (fit != m_flagValues.end()) {
+ if (value.type() != QVariant::UInt && !value.canConvert(QVariant::UInt))
+ return;
+
+ const uint v = value.toUInt();
+
+ FlagData data = fit.value();
+ if (data.val == v)
+ return;
+
+ // set Value
+
+ const QList<uint> values = data.values;
+ const QList<QtProperty *> subFlags = m_propertyToFlags.value(property);
+ const int subFlagCount = subFlags.count();
+ for (int i = 0; i < subFlagCount; ++i) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
+ const uint val = values.at(i);
+ const bool checked = (val == 0) ? (v == 0) : ((val & v) == val);
+ subFlag->setValue(checked);
+ }
+
+ for (int i = 0; i < subFlagCount; ++i) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
+ const uint val = values.at(i);
+ const bool checked = (val == 0) ? (v == 0) : ((val & v) == val);
+ bool enabled = true;
+ if (val == 0) {
+ if (checked)
+ enabled = false;
+ } else if (bitCount(val) > 1) {
+ // Disabled if all flags contained in the mask are checked
+ uint currentMask = 0;
+ for (int j = 0; j < subFlagCount; ++j) {
+ QtVariantProperty *subFlag = variantProperty(subFlags.at(j));
+ if (bitCount(values.at(j)) == 1)
+ currentMask |= subFlag->value().toBool() ? values.at(j) : 0;
+ }
+ if ((currentMask & values.at(i)) == values.at(i))
+ enabled = false;
+ }
+ subFlag->setEnabled(enabled);
+ }
+
+ data.val = v;
+ fit.value() = data;
+
+ emit QtVariantPropertyManager::valueChanged(property, data.val);
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_alignValues.contains(property)) {
+ if (value.type() != QVariant::UInt && !value.canConvert(QVariant::UInt))
+ return;
+
+ const uint v = value.toUInt();
+
+ uint val = m_alignValues.value(property);
+
+ if (val == v)
+ return;
+
+ QtVariantProperty *alignH = variantProperty(m_propertyToAlignH.value(property));
+ QtVariantProperty *alignV = variantProperty(m_propertyToAlignV.value(property));
+
+ if (alignH)
+ alignH->setValue(alignToIndexH(v));
+ if (alignV)
+ alignV->setValue(alignToIndexV(v));
+
+ m_alignValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, v);
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_stringValues.contains(property)) {
+ if (value.userType() != designerStringTypeId())
+ return;
+
+ const PropertySheetStringValue v = qvariant_cast<PropertySheetStringValue>(value);
+
+ const PropertySheetStringValue val = m_stringValues.value(property);
+
+ if (val == v)
+ return;
+
+ QtVariantProperty *comment = variantProperty(m_stringToComment.value(property));
+ QtVariantProperty *translatable = variantProperty(m_stringToTranslatable.value(property));
+ QtVariantProperty *disambiguation = variantProperty(m_stringToDisambiguation.value(property));
+
+ if (comment)
+ comment->setValue(v.comment());
+ if (translatable)
+ translatable->setValue(v.translatable());
+ if (disambiguation)
+ disambiguation->setValue(v.disambiguation());
+
+ m_stringValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(v));
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_keySequenceValues.contains(property)) {
+ if (value.userType() != designerKeySequenceTypeId())
+ return;
+
+ const PropertySheetKeySequenceValue v = qvariant_cast<PropertySheetKeySequenceValue>(value);
+
+ const PropertySheetKeySequenceValue val = m_keySequenceValues.value(property);
+
+ if (val == v)
+ return;
+
+ QtVariantProperty *comment = variantProperty(m_keySequenceToComment.value(property));
+ QtVariantProperty *translatable = variantProperty(m_keySequenceToTranslatable.value(property));
+ QtVariantProperty *disambiguation = variantProperty(m_keySequenceToDisambiguation.value(property));
+
+ if (comment)
+ comment->setValue(v.comment());
+ if (translatable)
+ translatable->setValue(v.translatable());
+ if (disambiguation)
+ disambiguation->setValue(v.disambiguation());
+
+ m_keySequenceValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(v));
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_paletteValues.contains(property)) {
+ if (value.type() != QVariant::Palette && !value.canConvert(QVariant::Palette))
+ return;
+
+ QPalette p = qvariant_cast<QPalette>(value);
+
+ PaletteData data = m_paletteValues.value(property);
+
+ const uint mask = p.resolve();
+ p = p.resolve(data.superPalette);
+ p.resolve(mask);
+
+ if (data.val == p && data.val.resolve() == p.resolve())
+ return;
+
+ data.val = p;
+ m_paletteValues[property] = data;
+
+ emit QtVariantPropertyManager::valueChanged(property, data.val);
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_iconValues.contains(property)) {
+ if (value.userType() != designerIconTypeId())
+ return;
+
+ const PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(value);
+
+ const PropertySheetIconValue oldIcon = m_iconValues.value(property);
+ if (icon == oldIcon)
+ return;
+
+ m_iconValues[property] = icon;
+
+ QIcon defaultIcon = m_defaultIcons.value(property);
+ if (!icon.paths().isEmpty()) {
+ QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
+ qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
+ if (fwb)
+ defaultIcon = fwb->iconCache()->icon(icon);
+ }
+
+ QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> iconPaths = icon.paths();
+
+ QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> subProperties = m_propertyToIconSubProperties.value(property);
+ QMapIterator<QPair<QIcon::Mode, QIcon::State>, QtProperty *> itSub(subProperties);
+ while (itSub.hasNext()) {
+ const QPair<QIcon::Mode, QIcon::State> pair = itSub.next().key();
+ QtVariantProperty *subProperty = variantProperty(itSub.value());
+ bool hasPath = iconPaths.contains(pair);
+ subProperty->setModified(hasPath);
+ subProperty->setValue(QVariant::fromValue(iconPaths.value(pair)));
+ subProperty->setAttribute(QLatin1String(defaultResourceAttributeC),
+ defaultIcon.pixmap(16, 16, pair.first, pair.second));
+ }
+ QtVariantProperty *themeSubProperty = variantProperty(m_propertyToTheme.value(property));
+ if (themeSubProperty) {
+ const QString theme = icon.theme();
+ themeSubProperty->setModified(!theme.isEmpty());
+ themeSubProperty->setValue(theme);
+ }
+
+ emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(icon));
+ emit propertyChanged(property);
+
+ QString toolTip;
+ const QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue>::ConstIterator itNormalOff =
+ iconPaths.constFind(qMakePair(QIcon::Normal, QIcon::Off));
+ if (itNormalOff != iconPaths.constEnd())
+ toolTip = itNormalOff.value().path();
+ property->setToolTip(toolTip);
+
+ return;
+ } else if (m_pixmapValues.contains(property)) {
+ if (value.userType() != designerPixmapTypeId())
+ return;
+
+ const PropertySheetPixmapValue pixmap = qvariant_cast<PropertySheetPixmapValue>(value);
+
+ const PropertySheetPixmapValue oldPixmap = m_pixmapValues.value(property);
+ if (pixmap == oldPixmap)
+ return;
+
+ m_pixmapValues[property] = pixmap;
+
+ emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(pixmap));
+ emit propertyChanged(property);
+
+ property->setToolTip(pixmap.path());
+
+ return;
+ } else if (m_uintValues.contains(property)) {
+ if (value.type() != QVariant::UInt && !value.canConvert(QVariant::UInt))
+ return;
+
+ const uint v = value.toUInt(0);
+
+ const uint oldValue = m_uintValues.value(property);
+ if (v == oldValue)
+ return;
+
+ m_uintValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, v);
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_longLongValues.contains(property)) {
+ if (value.type() != QVariant::LongLong && !value.canConvert(QVariant::LongLong))
+ return;
+
+ const qlonglong v = value.toLongLong(0);
+
+ const qlonglong oldValue = m_longLongValues.value(property);
+ if (v == oldValue)
+ return;
+
+ m_longLongValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, v);
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_uLongLongValues.contains(property)) {
+ if (value.type() != QVariant::ULongLong && !value.canConvert(QVariant::ULongLong))
+ return;
+
+ qulonglong v = value.toULongLong(0);
+
+ qulonglong oldValue = m_uLongLongValues.value(property);
+ if (v == oldValue)
+ return;
+
+ m_uLongLongValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, v);
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_urlValues.contains(property)) {
+ if (value.type() != QVariant::Url && !value.canConvert(QVariant::Url))
+ return;
+
+ const QUrl v = value.toUrl();
+
+ const QUrl oldValue = m_urlValues.value(property);
+ if (v == oldValue)
+ return;
+
+ m_urlValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, v);
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_byteArrayValues.contains(property)) {
+ if (value.type() != QVariant::ByteArray && !value.canConvert(QVariant::ByteArray))
+ return;
+
+ const QByteArray v = value.toByteArray();
+
+ const QByteArray oldValue = m_byteArrayValues.value(property);
+ if (v == oldValue)
+ return;
+
+ m_byteArrayValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, v);
+ emit propertyChanged(property);
+
+ return;
+ } else if (m_stringListValues.contains(property)) {
+ if (value.type() != QVariant::StringList && !value.canConvert(QVariant::StringList))
+ return;
+
+ const QStringList v = value.toStringList();
+
+ const QStringList oldValue = m_stringListValues.value(property);
+ if (v == oldValue)
+ return;
+
+ m_stringListValues[property] = v;
+
+ emit QtVariantPropertyManager::valueChanged(property, v);
+ emit propertyChanged(property);
+
+ return;
+ }
+ switch (m_brushManager.setValue(this, property, value)) {
+ case BrushPropertyManager::Unchanged:
+ return;
+ case BrushPropertyManager::Changed:
+ emit QtVariantPropertyManager::valueChanged(property, value);
+ emit propertyChanged(property);
+ return;
+ default:
+ break;
+ }
+ m_fontManager.setValue(this, property, value);
+ QtVariantPropertyManager::setValue(property, value);
+ if (QtVariantPropertyManager::valueType(property) == QVariant::String)
+ property->setToolTip(DesignerPropertyManager::value(property).toString());
+ else if (QtVariantPropertyManager::valueType(property) == designerStringTypeId())
+ property->setToolTip(qvariant_cast<PropertySheetStringValue>(DesignerPropertyManager::value(property)).value());
+ else if (QtVariantPropertyManager::valueType(property) == designerKeySequenceTypeId())
+ property->setToolTip(qvariant_cast<PropertySheetKeySequenceValue>(DesignerPropertyManager::value(property)).value());
+ else if (QtVariantPropertyManager::valueType(property) == QVariant::Bool)
+ property->setToolTip(QtVariantPropertyManager::valueText(property));
+}
+
+void DesignerPropertyManager::initializeProperty(QtProperty *property)
+{
+ m_resetMap[property] = false;
+
+ const int type = propertyType(property);
+ m_fontManager.preInitializeProperty(property, type, m_resetMap);
+ switch (type) {
+ case QVariant::Palette:
+ m_paletteValues[property] = PaletteData();
+ break;
+ case QVariant::String:
+ m_stringAttributes[property] = ValidationSingleLine;
+ m_stringFontAttributes[property] = QApplication::font();
+ m_stringThemeAttributes[property] = false;
+ break;
+ case QVariant::UInt:
+ m_uintValues[property] = 0;
+ break;
+ case QVariant::LongLong:
+ m_longLongValues[property] = 0;
+ break;
+ case QVariant::ULongLong:
+ m_uLongLongValues[property] = 0;
+ break;
+ case QVariant::Url:
+ m_urlValues[property] = QUrl();
+ break;
+ case QVariant::ByteArray:
+ m_byteArrayValues[property] = 0;
+ break;
+ case QVariant::StringList:
+ m_stringListValues[property] = QStringList();
+ break;
+ case QVariant::Brush:
+ m_brushManager.initializeProperty(this, property, enumTypeId());
+ break;
+ default:
+ if (type == designerFlagTypeId()) {
+ m_flagValues[property] = FlagData();
+ m_propertyToFlags[property] = QList<QtProperty *>();
+ } else if (type == designerAlignmentTypeId()) {
+ const uint align = Qt::AlignLeft | Qt::AlignVCenter;
+ m_alignValues[property] = align;
+
+ QtVariantProperty *alignH = addProperty(enumTypeId(), tr("Horizontal"));
+ QStringList namesH;
+ namesH << indexHToString(0) << indexHToString(1) << indexHToString(2) << indexHToString(3);
+ alignH->setAttribute(QLatin1String("enumNames"), namesH);
+ alignH->setValue(alignToIndexH(align));
+ m_propertyToAlignH[property] = alignH;
+ m_alignHToProperty[alignH] = property;
+ property->addSubProperty(alignH);
+
+ QtVariantProperty *alignV = addProperty(enumTypeId(), tr("Vertical"));
+ QStringList namesV;
+ namesV << indexVToString(0) << indexVToString(1) << indexVToString(2);
+ alignV->setAttribute(QLatin1String("enumNames"), namesV);
+ alignV->setValue(alignToIndexV(align));
+ m_propertyToAlignV[property] = alignV;
+ m_alignVToProperty[alignV] = property;
+ property->addSubProperty(alignV);
+ } else if (type == designerPixmapTypeId()) {
+ m_pixmapValues[property] = PropertySheetPixmapValue();
+ m_defaultPixmaps[property] = QPixmap();
+ } else if (type == designerIconTypeId()) {
+ m_iconValues[property] = PropertySheetIconValue();
+ m_defaultIcons[property] = QIcon();
+
+ QtVariantProperty *themeProp = addProperty(QVariant::String, tr("Theme"));
+ themeProp->setAttribute(QLatin1String(themeAttributeC), true);
+ m_iconSubPropertyToProperty[themeProp] = property;
+ m_propertyToTheme[property] = themeProp;
+ m_resetMap[themeProp] = true;
+ property->addSubProperty(themeProp);
+
+ createIconSubProperty(property, QIcon::Normal, QIcon::Off, tr("Normal Off"));
+ createIconSubProperty(property, QIcon::Normal, QIcon::On, tr("Normal On"));
+ createIconSubProperty(property, QIcon::Disabled, QIcon::Off, tr("Disabled Off"));
+ createIconSubProperty(property, QIcon::Disabled, QIcon::On, tr("Disabled On"));
+ createIconSubProperty(property, QIcon::Active, QIcon::Off, tr("Active Off"));
+ createIconSubProperty(property, QIcon::Active, QIcon::On, tr("Active On"));
+ createIconSubProperty(property, QIcon::Selected, QIcon::Off, tr("Selected Off"));
+ createIconSubProperty(property, QIcon::Selected, QIcon::On, tr("Selected On"));
+ } else if (type == designerStringTypeId()) {
+ PropertySheetStringValue val;
+ m_stringValues[property] = val;
+ m_stringAttributes[property] = ValidationMultiLine;
+ m_stringFontAttributes[property] = QApplication::font();
+ m_stringThemeAttributes[property] = false;
+
+ QtVariantProperty *translatable = addProperty(QVariant::Bool, tr("translatable"));
+ translatable->setValue(val.translatable());
+ m_stringToTranslatable[property] = translatable;
+ m_translatableToString[translatable] = property;
+ property->addSubProperty(translatable);
+
+ QtVariantProperty *disambiguation = addProperty(QVariant::String, tr("disambiguation"));
+ disambiguation->setValue(val.disambiguation());
+ m_stringToDisambiguation[property] = disambiguation;
+ m_disambiguationToString[disambiguation] = property;
+ property->addSubProperty(disambiguation);
+
+ QtVariantProperty *comment = addProperty(QVariant::String, tr("comment"));
+ comment->setValue(val.comment());
+ m_stringToComment[property] = comment;
+ m_commentToString[comment] = property;
+ property->addSubProperty(comment);
+ } else if (type == designerKeySequenceTypeId()) {
+ PropertySheetKeySequenceValue val;
+ m_keySequenceValues[property] = val;
+
+ QtVariantProperty *translatable = addProperty(QVariant::Bool, tr("translatable"));
+ translatable->setValue(val.translatable());
+ m_keySequenceToTranslatable[property] = translatable;
+ m_translatableToKeySequence[translatable] = property;
+ property->addSubProperty(translatable);
+
+ QtVariantProperty *disambiguation = addProperty(QVariant::String, tr("disambiguation"));
+ disambiguation->setValue(val.disambiguation());
+ m_keySequenceToDisambiguation[property] = disambiguation;
+ m_disambiguationToKeySequence[disambiguation] = property;
+ property->addSubProperty(disambiguation);
+
+ QtVariantProperty *comment = addProperty(QVariant::String, tr("comment"));
+ comment->setValue(val.comment());
+ m_keySequenceToComment[property] = comment;
+ m_commentToKeySequence[comment] = property;
+ property->addSubProperty(comment);
+ }
+ }
+
+ QtVariantPropertyManager::initializeProperty(property);
+ m_fontManager.postInitializeProperty(this, property, type, DesignerPropertyManager::enumTypeId());
+ if (type == QVariant::Double)
+ setAttribute(property, QLatin1String("decimals"), 6);
+}
+
+void DesignerPropertyManager::createIconSubProperty(QtProperty *iconProperty, QIcon::Mode mode, QIcon::State state, const QString &subName)
+{
+ QPair<QIcon::Mode, QIcon::State> pair = qMakePair(mode, state);
+ QtVariantProperty *subProp = addProperty(DesignerPropertyManager::designerPixmapTypeId(), subName);
+ m_propertyToIconSubProperties[iconProperty][pair] = subProp;
+ m_iconSubPropertyToState[subProp] = pair;
+ m_iconSubPropertyToProperty[subProp] = iconProperty;
+ m_resetMap[subProp] = true;
+ iconProperty->addSubProperty(subProp);
+}
+
+void DesignerPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ m_resetMap.remove(property);
+
+ QListIterator<QtProperty *> itProp(m_propertyToFlags[property]);
+ while (itProp.hasNext()) {
+ QtProperty *prop = itProp.next();
+ if (prop) {
+ delete prop;
+ m_flagToProperty.remove(prop);
+ }
+ }
+ m_propertyToFlags.remove(property);
+ m_flagValues.remove(property);
+
+ QtProperty *alignH = m_propertyToAlignH.value(property);
+ if (alignH) {
+ delete alignH;
+ m_alignHToProperty.remove(alignH);
+ }
+ QtProperty *alignV = m_propertyToAlignV.value(property);
+ if (alignV) {
+ delete alignV;
+ m_alignVToProperty.remove(alignV);
+ }
+
+ QtProperty *stringComment = m_stringToComment.value(property);
+ if (stringComment) {
+ delete stringComment;
+ m_commentToString.remove(stringComment);
+ }
+
+ QtProperty *stringTranslatable = m_stringToTranslatable.value(property);
+ if (stringTranslatable) {
+ delete stringTranslatable;
+ m_translatableToString.remove(stringTranslatable);
+ }
+
+ QtProperty *stringDisambiguation = m_stringToDisambiguation.value(property);
+ if (stringDisambiguation) {
+ delete stringDisambiguation;
+ m_disambiguationToString.remove(stringDisambiguation);
+ }
+
+ QtProperty *keySequenceComment = m_keySequenceToComment.value(property);
+ if (keySequenceComment) {
+ delete keySequenceComment;
+ m_commentToKeySequence.remove(keySequenceComment);
+ }
+
+ QtProperty *keySequenceTranslatable = m_keySequenceToTranslatable.value(property);
+ if (keySequenceTranslatable) {
+ delete keySequenceTranslatable;
+ m_translatableToKeySequence.remove(keySequenceTranslatable);
+ }
+
+ QtProperty *keySequenceDisambiguation = m_keySequenceToDisambiguation.value(property);
+ if (keySequenceDisambiguation) {
+ delete keySequenceDisambiguation;
+ m_disambiguationToKeySequence.remove(keySequenceDisambiguation);
+ }
+
+ QtProperty *iconTheme = m_propertyToTheme.value(property);
+ if (iconTheme) {
+ delete iconTheme;
+ m_iconSubPropertyToProperty.remove(iconTheme);
+ }
+
+ m_propertyToAlignH.remove(property);
+ m_propertyToAlignV.remove(property);
+
+ m_stringToComment.remove(property);
+ m_stringToTranslatable.remove(property);
+ m_stringToDisambiguation.remove(property);
+ m_stringValues.remove(property);
+ m_stringAttributes.remove(property);
+ m_stringFontAttributes.remove(property);
+
+ m_keySequenceToComment.remove(property);
+ m_keySequenceToTranslatable.remove(property);
+ m_keySequenceToDisambiguation.remove(property);
+ m_keySequenceValues.remove(property);
+
+ m_paletteValues.remove(property);
+
+ m_iconValues.remove(property);
+ m_defaultIcons.remove(property);
+
+ m_pixmapValues.remove(property);
+ m_defaultPixmaps.remove(property);
+
+ QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> iconSubProperties = m_propertyToIconSubProperties.value(property);
+ QMapIterator<QPair<QIcon::Mode, QIcon::State>, QtProperty *> itIcon(iconSubProperties);
+ while (itIcon.hasNext()) {
+ QtProperty *subIcon = itIcon.next().value();
+ delete subIcon;
+ m_iconSubPropertyToState.remove(subIcon);
+ m_iconSubPropertyToProperty.remove(subIcon);
+ }
+ m_propertyToIconSubProperties.remove(property);
+ m_iconSubPropertyToState.remove(property);
+ m_iconSubPropertyToProperty.remove(property);
+
+ m_uintValues.remove(property);
+ m_longLongValues.remove(property);
+ m_uLongLongValues.remove(property);
+ m_urlValues.remove(property);
+ m_byteArrayValues.remove(property);
+ m_stringListValues.remove(property);
+
+ m_fontManager.uninitializeProperty(property);
+ m_brushManager.uninitializeProperty(property);
+
+ QtVariantPropertyManager::uninitializeProperty(property);
+}
+
+
+bool DesignerPropertyManager::resetFontSubProperty(QtProperty *property)
+{
+ return m_fontManager.resetFontSubProperty(this, property);
+}
+
+bool DesignerPropertyManager::resetIconSubProperty(QtProperty *property)
+{
+ QtProperty *iconProperty = m_iconSubPropertyToProperty.value(property);
+ if (!iconProperty)
+ return false;
+
+ if (m_pixmapValues.contains(property)) {
+ QtVariantProperty *pixmapProperty = variantProperty(property);
+ pixmapProperty->setValue(QVariant::fromValue(PropertySheetPixmapValue()));
+ return true;
+ } else if (m_propertyToTheme.contains(iconProperty)) {
+ QtVariantProperty *themeProperty = variantProperty(property);
+ themeProperty->setValue(QString());
+ return true;
+ }
+ return false;
+}
+
+// -------- DesignerEditorFactory
+DesignerEditorFactory::DesignerEditorFactory(QDesignerFormEditorInterface *core, QObject *parent) :
+ QtVariantEditorFactory(parent),
+ m_resetDecorator(new ResetDecorator(this)),
+ m_changingPropertyValue(false),
+ m_core(core),
+ m_spacing(-1)
+{
+ connect(m_resetDecorator, SIGNAL(resetProperty(QtProperty*)), this, SIGNAL(resetProperty(QtProperty*)));
+}
+
+DesignerEditorFactory::~DesignerEditorFactory()
+{
+}
+
+void DesignerEditorFactory::setSpacing(int spacing)
+{
+ m_spacing = spacing;
+ m_resetDecorator->setSpacing(spacing);
+}
+
+void DesignerEditorFactory::setFormWindowBase(qdesigner_internal::FormWindowBase *fwb)
+{
+ m_fwb = fwb;
+ DesignerPixmapCache *cache = 0;
+ if (fwb)
+ cache = fwb->pixmapCache();
+ QMapIterator<PixmapEditor *, QtProperty *> itPixmapEditor(m_editorToPixmapProperty);
+ while (itPixmapEditor.hasNext()) {
+ PixmapEditor *pe = itPixmapEditor.next().key();
+ pe->setPixmapCache(cache);
+ }
+ QMapIterator<PixmapEditor *, QtProperty *> itIconEditor(m_editorToIconProperty);
+ while (itIconEditor.hasNext()) {
+ PixmapEditor *pe = itIconEditor.next().key();
+ pe->setPixmapCache(cache);
+ }
+}
+
+void DesignerEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager)
+{
+ m_resetDecorator->connectPropertyManager(manager);
+ connect(manager, SIGNAL(attributeChanged(QtProperty*,QString,QVariant)),
+ this, SLOT(slotAttributeChanged(QtProperty*,QString,QVariant)));
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QVariant)),
+ this, SLOT(slotValueChanged(QtProperty*,QVariant)));
+ connect(manager, SIGNAL(propertyChanged(QtProperty*)),
+ this, SLOT(slotPropertyChanged(QtProperty*)));
+ QtVariantEditorFactory::connectPropertyManager(manager);
+}
+
+void DesignerEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager)
+{
+ m_resetDecorator->disconnectPropertyManager(manager);
+ disconnect(manager, SIGNAL(attributeChanged(QtProperty*,QString,QVariant)),
+ this, SLOT(slotAttributeChanged(QtProperty*,QString,QVariant)));
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QVariant)),
+ this, SLOT(slotValueChanged(QtProperty*,QVariant)));
+ disconnect(manager, SIGNAL(propertyChanged(QtProperty*)),
+ this, SLOT(slotPropertyChanged(QtProperty*)));
+ QtVariantEditorFactory::disconnectPropertyManager(manager);
+}
+
+// A helper that calls a setter with a value on a pointer list of editor objects.
+// Could use QList<Editor*> instead of EditorContainer/Editor, but that crashes VS 6.
+template <class EditorContainer, class Editor, class SetterParameter, class Value>
+static inline void applyToEditors(const EditorContainer &list, void (Editor::*setter)(SetterParameter), const Value &value)
+{
+ typedef Q_TYPENAME EditorContainer::const_iterator ListIterator;
+ if (list.empty()) {
+ return;
+ }
+ const ListIterator end = list.constEnd();
+ for (ListIterator it = list.constBegin(); it != end; ++it) {
+ Editor &editor = *(*it);
+ (editor.*setter)(value);
+ }
+}
+
+void DesignerEditorFactory::slotAttributeChanged(QtProperty *property, const QString &attribute, const QVariant &value)
+{
+ QtVariantPropertyManager *manager = propertyManager(property);
+ const int type = manager->propertyType(property);
+ if (type == DesignerPropertyManager::designerPixmapTypeId() && attribute == QLatin1String(defaultResourceAttributeC)) {
+ const QPixmap pixmap = qvariant_cast<QPixmap>(value);
+ applyToEditors(m_pixmapPropertyToEditors.value(property), &PixmapEditor::setDefaultPixmap, pixmap);
+ } else if (type == DesignerPropertyManager::designerStringTypeId() || type == QVariant::String) {
+ if (attribute == QLatin1String(validationModesAttributeC)) {
+ const TextPropertyValidationMode validationMode = static_cast<TextPropertyValidationMode>(value.toInt());
+ applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setTextPropertyValidationMode, validationMode);
+ }
+ if (attribute == QLatin1String(fontAttributeC)) {
+ const QFont font = qvariant_cast<QFont>(value);
+ applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setRichTextDefaultFont, font);
+ }
+ if (attribute == QLatin1String(themeAttributeC)) {
+ const bool themeEnabled = value.toBool();
+ applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setIconThemeModeEnabled, themeEnabled);
+ }
+ } else if (type == QVariant::Palette && attribute == QLatin1String(superPaletteAttributeC)) {
+ const QPalette palette = qvariant_cast<QPalette>(value);
+ applyToEditors(m_palettePropertyToEditors.value(property), &PaletteEditorButton::setSuperPalette, palette);
+ }
+}
+
+void DesignerEditorFactory::slotPropertyChanged(QtProperty *property)
+{
+ QtVariantPropertyManager *manager = propertyManager(property);
+ const int type = manager->propertyType(property);
+ if (type == DesignerPropertyManager::designerIconTypeId()) {
+ QPixmap defaultPixmap;
+ if (!property->isModified())
+ defaultPixmap = qvariant_cast<QIcon>(manager->attributeValue(property, QLatin1String(defaultResourceAttributeC))).pixmap(16, 16);
+ else if (m_fwb)
+ defaultPixmap = m_fwb->iconCache()->icon(qvariant_cast<PropertySheetIconValue>(manager->value(property))).pixmap(16, 16);
+ QList<PixmapEditor *> editors = m_iconPropertyToEditors.value(property);
+ QListIterator<PixmapEditor *> it(editors);
+ while (it.hasNext()) {
+ PixmapEditor *editor = it.next();
+ editor->setDefaultPixmap(defaultPixmap);
+ }
+ }
+}
+
+void DesignerEditorFactory::slotValueChanged(QtProperty *property, const QVariant &value)
+{
+ if (m_changingPropertyValue)
+ return;
+
+ QtVariantPropertyManager *manager = propertyManager(property);
+ const int type = manager->propertyType(property);
+ switch (type) {
+ case QVariant::String:
+ applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setText, value.toString());
+ break;
+ case QVariant::Palette:
+ applyToEditors(m_palettePropertyToEditors.value(property), &PaletteEditorButton::setPalette, qvariant_cast<QPalette>(value));
+ break;
+ case QVariant::UInt:
+ applyToEditors(m_uintPropertyToEditors.value(property), &QLineEdit::setText, QString::number(value.toUInt()));
+ break;
+ case QVariant::LongLong:
+ applyToEditors(m_longLongPropertyToEditors.value(property), &QLineEdit::setText, QString::number(value.toLongLong()));
+ break;
+ case QVariant::ULongLong:
+ applyToEditors(m_uLongLongPropertyToEditors.value(property), &QLineEdit::setText, QString::number(value.toULongLong()));
+ break;
+ case QVariant::Url:
+ applyToEditors(m_urlPropertyToEditors.value(property), &TextEditor::setText, value.toUrl().toString());
+ break;
+ case QVariant::ByteArray:
+ applyToEditors(m_byteArrayPropertyToEditors.value(property), &TextEditor::setText, QString::fromUtf8(value.toByteArray()));
+ break;
+ case QVariant::StringList:
+ applyToEditors(m_stringListPropertyToEditors.value(property), &StringListEditorButton::setStringList, value.toStringList());
+ break;
+ default:
+ if (type == DesignerPropertyManager::designerIconTypeId()) {
+ PropertySheetIconValue iconValue = qvariant_cast<PropertySheetIconValue>(value);
+ const QString theme = iconValue.theme();
+ applyToEditors(m_iconPropertyToEditors.value(property), &PixmapEditor::setTheme, iconValue.theme());
+ applyToEditors(m_iconPropertyToEditors.value(property), &PixmapEditor::setPath, iconValue.pixmap(QIcon::Normal, QIcon::Off).path());
+ } else if (type == DesignerPropertyManager::designerPixmapTypeId()) {
+ applyToEditors(m_pixmapPropertyToEditors.value(property), &PixmapEditor::setPath, qvariant_cast<PropertySheetPixmapValue>(value).path());
+ } else if (type == DesignerPropertyManager::designerStringTypeId()) {
+ applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setText, qvariant_cast<PropertySheetStringValue>(value).value());
+ } else if (type == DesignerPropertyManager::designerKeySequenceTypeId()) {
+ applyToEditors(m_keySequencePropertyToEditors.value(property), &QtKeySequenceEdit::setKeySequence, qvariant_cast<PropertySheetKeySequenceValue>(value).value());
+ }
+ break;
+ }
+}
+
+TextEditor *DesignerEditorFactory::createTextEditor(QWidget *parent, TextPropertyValidationMode vm, const QString &value)
+{
+ TextEditor *rc = new TextEditor(m_core, parent);
+ rc->setText(value);
+ rc->setSpacing(m_spacing);
+ rc->setTextPropertyValidationMode(vm);
+ connect(rc, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ return rc;
+}
+
+QWidget *DesignerEditorFactory::createEditor(QtVariantPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QWidget *editor = 0;
+ const int type = manager->propertyType(property);
+ switch (type) {
+ case QVariant::Bool: {
+ editor = QtVariantEditorFactory::createEditor(manager, property, parent);
+ QtBoolEdit *boolEdit = qobject_cast<QtBoolEdit *>(editor);
+ if (boolEdit)
+ boolEdit->setTextVisible(false);
+ }
+ break;
+ case QVariant::String: {
+ const TextPropertyValidationMode tvm = static_cast<TextPropertyValidationMode>(manager->attributeValue(property, QLatin1String(validationModesAttributeC)).toInt());
+ TextEditor *ed = createTextEditor(parent, tvm, manager->value(property).toString());
+ const QVariant richTextDefaultFont = manager->attributeValue(property, QLatin1String(fontAttributeC));
+ if (richTextDefaultFont.type() == QVariant::Font)
+ ed->setRichTextDefaultFont(qvariant_cast<QFont>(richTextDefaultFont));
+ const bool themeEnabled = manager->attributeValue(property, QLatin1String(themeAttributeC)).toBool();
+ ed->setIconThemeModeEnabled(themeEnabled);
+ m_stringPropertyToEditors[property].append(ed);
+ m_editorToStringProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotStringTextChanged(QString)));
+ editor = ed;
+ }
+ break;
+ case QVariant::Palette: {
+ PaletteEditorButton *ed = new PaletteEditorButton(m_core, qvariant_cast<QPalette>(manager->value(property)), parent);
+ ed->setSuperPalette(qvariant_cast<QPalette>(manager->attributeValue(property, QLatin1String(superPaletteAttributeC))));
+ m_palettePropertyToEditors[property].append(ed);
+ m_editorToPaletteProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(paletteChanged(QPalette)), this, SLOT(slotPaletteChanged(QPalette)));
+ editor = ed;
+ }
+ break;
+ case QVariant::UInt: {
+ QLineEdit *ed = new QLineEdit(parent);
+ ed->setValidator(new QULongLongValidator(0, UINT_MAX, ed));
+ ed->setText(QString::number(manager->value(property).toUInt()));
+ m_uintPropertyToEditors[property].append(ed);
+ m_editorToUintProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotUintChanged(QString)));
+ editor = ed;
+ }
+ break;
+ case QVariant::LongLong: {
+ QLineEdit *ed = new QLineEdit(parent);
+ ed->setValidator(new QLongLongValidator(ed));
+ ed->setText(QString::number(manager->value(property).toLongLong()));
+ m_longLongPropertyToEditors[property].append(ed);
+ m_editorToLongLongProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotLongLongChanged(QString)));
+ editor = ed;
+ }
+ break;
+ case QVariant::ULongLong: {
+ QLineEdit *ed = new QLineEdit(parent);
+ ed->setValidator(new QULongLongValidator(ed));
+ ed->setText(QString::number(manager->value(property).toULongLong()));
+ m_uLongLongPropertyToEditors[property].append(ed);
+ m_editorToULongLongProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotULongLongChanged(QString)));
+ editor = ed;
+ }
+ break;
+ case QVariant::Url: {
+ TextEditor *ed = createTextEditor(parent, ValidationURL, manager->value(property).toUrl().toString());
+ ed->setUpdateMode(TextPropertyEditor::UpdateOnFinished);
+ m_urlPropertyToEditors[property].append(ed);
+ m_editorToUrlProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotUrlChanged(QString)));
+ editor = ed;
+ }
+ break;
+ case QVariant::ByteArray: {
+ TextEditor *ed = createTextEditor(parent, ValidationMultiLine, QString::fromUtf8(manager->value(property).toByteArray()));
+ m_byteArrayPropertyToEditors[property].append(ed);
+ m_editorToByteArrayProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotByteArrayChanged(QString)));
+ editor = ed;
+ }
+ break;
+ case QVariant::StringList: {
+ StringListEditorButton *ed = new StringListEditorButton(manager->value(property).toStringList(), parent);
+ m_stringListPropertyToEditors[property].append(ed);
+ m_editorToStringListProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(stringListChanged(QStringList)), this, SLOT(slotStringListChanged(QStringList)));
+ editor = ed;
+ }
+ break;
+ default:
+ if (type == DesignerPropertyManager::designerPixmapTypeId()) {
+ PixmapEditor *ed = new PixmapEditor(m_core, parent);
+ ed->setPixmapCache(m_fwb->pixmapCache());
+ ed->setPath(qvariant_cast<PropertySheetPixmapValue>(manager->value(property)).path());
+ ed->setDefaultPixmap(qvariant_cast<QPixmap>(manager->attributeValue(property, QLatin1String(defaultResourceAttributeC))));
+ ed->setSpacing(m_spacing);
+ m_pixmapPropertyToEditors[property].append(ed);
+ m_editorToPixmapProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(pathChanged(QString)), this, SLOT(slotPixmapChanged(QString)));
+ editor = ed;
+ } else if (type == DesignerPropertyManager::designerIconTypeId()) {
+ PixmapEditor *ed = new PixmapEditor(m_core, parent);
+ ed->setPixmapCache(m_fwb->pixmapCache());
+ ed->setIconThemeModeEnabled(true);
+ PropertySheetIconValue value = qvariant_cast<PropertySheetIconValue>(manager->value(property));
+ ed->setTheme(value.theme());
+ ed->setPath(value.pixmap(QIcon::Normal, QIcon::Off).path());
+ QPixmap defaultPixmap;
+ if (!property->isModified())
+ defaultPixmap = qvariant_cast<QIcon>(manager->attributeValue(property, QLatin1String(defaultResourceAttributeC))).pixmap(16, 16);
+ else if (m_fwb)
+ defaultPixmap = m_fwb->iconCache()->icon(value).pixmap(16, 16);
+ ed->setDefaultPixmap(defaultPixmap);
+ ed->setSpacing(m_spacing);
+ m_iconPropertyToEditors[property].append(ed);
+ m_editorToIconProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(pathChanged(QString)), this, SLOT(slotIconChanged(QString)));
+ connect(ed, SIGNAL(themeChanged(QString)), this, SLOT(slotIconThemeChanged(QString)));
+ editor = ed;
+ } else if (type == DesignerPropertyManager::designerStringTypeId()) {
+ const TextPropertyValidationMode tvm = static_cast<TextPropertyValidationMode>(manager->attributeValue(property, QLatin1String(validationModesAttributeC)).toInt());
+ TextEditor *ed = createTextEditor(parent, tvm, qvariant_cast<PropertySheetStringValue>(manager->value(property)).value());
+ const QVariant richTextDefaultFont = manager->attributeValue(property, QLatin1String(fontAttributeC));
+ if (richTextDefaultFont.type() == QVariant::Font)
+ ed->setRichTextDefaultFont(qvariant_cast<QFont>(richTextDefaultFont));
+ m_stringPropertyToEditors[property].append(ed);
+ m_editorToStringProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotStringTextChanged(QString)));
+ editor = ed;
+ } else if (type == DesignerPropertyManager::designerKeySequenceTypeId()) {
+ QtKeySequenceEdit *ed = new QtKeySequenceEdit(parent);
+ ed->setKeySequence(qvariant_cast<PropertySheetKeySequenceValue>(manager->value(property)).value());
+ m_keySequencePropertyToEditors[property].append(ed);
+ m_editorToKeySequenceProperty[ed] = property;
+ connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(ed, SIGNAL(keySequenceChanged(QKeySequence)), this, SLOT(slotKeySequenceChanged(QKeySequence)));
+ editor = ed;
+ } else {
+ editor = QtVariantEditorFactory::createEditor(manager, property, parent);
+ }
+ break;
+ }
+ return m_resetDecorator->editor(editor,
+ manager->variantProperty(property)->attributeValue(QLatin1String(resettableAttributeC)).toBool(),
+ manager, property, parent);
+}
+
+template <class Editor>
+bool removeEditor(QObject *object,
+ QMap<QtProperty *, QList<Editor> > *propertyToEditors,
+ QMap<Editor, QtProperty *> *editorToProperty)
+{
+ if (!propertyToEditors)
+ return false;
+ if (!editorToProperty)
+ return false;
+ QMapIterator<Editor, QtProperty *> it(*editorToProperty);
+ while (it.hasNext()) {
+ Editor editor = it.next().key();
+ if (editor == object) {
+ QtProperty *prop = it.value();
+ (*propertyToEditors)[prop].removeAll(editor);
+ if ((*propertyToEditors)[prop].count() == 0)
+ propertyToEditors->remove(prop);
+ editorToProperty->remove(editor);
+ return true;
+ }
+ }
+ return false;
+}
+
+void DesignerEditorFactory::slotEditorDestroyed(QObject *object)
+{
+ if (removeEditor(object, &m_stringPropertyToEditors, &m_editorToStringProperty))
+ return;
+ if (removeEditor(object, &m_keySequencePropertyToEditors, &m_editorToKeySequenceProperty))
+ return;
+ if (removeEditor(object, &m_palettePropertyToEditors, &m_editorToPaletteProperty))
+ return;
+ if (removeEditor(object, &m_pixmapPropertyToEditors, &m_editorToPixmapProperty))
+ return;
+ if (removeEditor(object, &m_iconPropertyToEditors, &m_editorToIconProperty))
+ return;
+ if (removeEditor(object, &m_uintPropertyToEditors, &m_editorToUintProperty))
+ return;
+ if (removeEditor(object, &m_longLongPropertyToEditors, &m_editorToLongLongProperty))
+ return;
+ if (removeEditor(object, &m_uLongLongPropertyToEditors, &m_editorToULongLongProperty))
+ return;
+ if (removeEditor(object, &m_urlPropertyToEditors, &m_editorToUrlProperty))
+ return;
+ if (removeEditor(object, &m_byteArrayPropertyToEditors, &m_editorToByteArrayProperty))
+ return;
+ if (removeEditor(object, &m_stringListPropertyToEditors, &m_editorToStringListProperty))
+ return;
+}
+
+template<class Editor>
+bool updateManager(QtVariantEditorFactory *factory, bool *changingPropertyValue,
+ const QMap<Editor, QtProperty *> &editorToProperty, QWidget *editor, const QVariant &value)
+{
+ if (!editor)
+ return false;
+ QMapIterator<Editor, QtProperty *> it(editorToProperty);
+ while (it.hasNext()) {
+ if (it.next().key() == editor) {
+ QtProperty *prop = it.value();
+ QtVariantPropertyManager *manager = factory->propertyManager(prop);
+ *changingPropertyValue = true;
+ manager->variantProperty(prop)->setValue(value);
+ *changingPropertyValue = false;
+ return true;
+ }
+ }
+ return false;
+}
+
+void DesignerEditorFactory::slotUintChanged(const QString &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToUintProperty, qobject_cast<QWidget *>(sender()), value.toUInt());
+}
+
+void DesignerEditorFactory::slotLongLongChanged(const QString &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToLongLongProperty, qobject_cast<QWidget *>(sender()), value.toLongLong());
+}
+
+void DesignerEditorFactory::slotULongLongChanged(const QString &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToULongLongProperty, qobject_cast<QWidget *>(sender()), value.toULongLong());
+}
+
+void DesignerEditorFactory::slotUrlChanged(const QString &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToUrlProperty, qobject_cast<QWidget *>(sender()), QUrl(value));
+}
+
+void DesignerEditorFactory::slotByteArrayChanged(const QString &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToByteArrayProperty, qobject_cast<QWidget *>(sender()), value.toUtf8());
+}
+
+void DesignerEditorFactory::slotStringTextChanged(const QString &value)
+{
+ QMapIterator<TextEditor *, QtProperty *> it(m_editorToStringProperty);
+ while (it.hasNext()) {
+ if (it.next().key() == sender()) {
+ QtProperty *prop = it.value();
+ QtVariantPropertyManager *manager = propertyManager(prop);
+ QtVariantProperty *varProp = manager->variantProperty(prop);
+ QVariant val = varProp->value();
+ if (val.userType() == DesignerPropertyManager::designerStringTypeId()) {
+ PropertySheetStringValue strVal = qvariant_cast<PropertySheetStringValue>(val);
+ strVal.setValue(value);
+ // Disable translation if no translation subproperties exist.
+ if (varProp->subProperties().empty())
+ strVal.setTranslatable(false);
+ val = QVariant::fromValue(strVal);
+ } else {
+ val = QVariant(value);
+ }
+ m_changingPropertyValue = true;
+ manager->variantProperty(prop)->setValue(val);
+ m_changingPropertyValue = false;
+ }
+ }
+}
+
+void DesignerEditorFactory::slotKeySequenceChanged(const QKeySequence &value)
+{
+ QMapIterator<QtKeySequenceEdit *, QtProperty *> it(m_editorToKeySequenceProperty);
+ while (it.hasNext()) {
+ if (it.next().key() == sender()) {
+ QtProperty *prop = it.value();
+ QtVariantPropertyManager *manager = propertyManager(prop);
+ QtVariantProperty *varProp = manager->variantProperty(prop);
+ QVariant val = varProp->value();
+ if (val.userType() == DesignerPropertyManager::designerKeySequenceTypeId()) {
+ PropertySheetKeySequenceValue keyVal = qvariant_cast<PropertySheetKeySequenceValue>(val);
+ keyVal.setValue(value);
+ val = QVariant::fromValue(keyVal);
+ } else {
+ val = QVariant::fromValue(value);
+ }
+ m_changingPropertyValue = true;
+ manager->variantProperty(prop)->setValue(val);
+ m_changingPropertyValue = false;
+ }
+ }
+}
+
+void DesignerEditorFactory::slotPaletteChanged(const QPalette &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToPaletteProperty, qobject_cast<QWidget *>(sender()), QVariant::fromValue(value));
+}
+
+void DesignerEditorFactory::slotPixmapChanged(const QString &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToPixmapProperty, qobject_cast<QWidget *>(sender()),
+ QVariant::fromValue(PropertySheetPixmapValue(value)));
+}
+
+void DesignerEditorFactory::slotIconChanged(const QString &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToIconProperty, qobject_cast<QWidget *>(sender()),
+ QVariant::fromValue(PropertySheetIconValue(PropertySheetPixmapValue(value))));
+}
+
+void DesignerEditorFactory::slotIconThemeChanged(const QString &value)
+{
+ PropertySheetIconValue icon;
+ icon.setTheme(value);
+ updateManager(this, &m_changingPropertyValue, m_editorToIconProperty, qobject_cast<QWidget *>(sender()),
+ QVariant::fromValue(icon));
+}
+
+void DesignerEditorFactory::slotStringListChanged(const QStringList &value)
+{
+ updateManager(this, &m_changingPropertyValue, m_editorToStringListProperty, qobject_cast<QWidget *>(sender()), QVariant::fromValue(value));
+}
+
+ResetDecorator::~ResetDecorator()
+{
+ QList<ResetWidget *> editors = m_resetWidgetToProperty.keys();
+ QListIterator<ResetWidget *> it(editors);
+ while (it.hasNext())
+ delete it.next();
+}
+
+void ResetDecorator::connectPropertyManager(QtAbstractPropertyManager *manager)
+{
+ connect(manager, SIGNAL(propertyChanged(QtProperty*)),
+ this, SLOT(slotPropertyChanged(QtProperty*)));
+}
+
+void ResetDecorator::disconnectPropertyManager(QtAbstractPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(propertyChanged(QtProperty*)),
+ this, SLOT(slotPropertyChanged(QtProperty*)));
+}
+
+void ResetDecorator::setSpacing(int spacing)
+{
+ m_spacing = spacing;
+}
+
+QWidget *ResetDecorator::editor(QWidget *subEditor, bool resettable, QtAbstractPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ Q_UNUSED(manager)
+
+ ResetWidget *resetWidget = 0;
+ if (resettable) {
+ resetWidget = new ResetWidget(property, parent);
+ resetWidget->setSpacing(m_spacing);
+ resetWidget->setResetEnabled(property->isModified());
+ resetWidget->setValueText(property->valueText());
+ resetWidget->setValueIcon(property->valueIcon());
+ resetWidget->setAutoFillBackground(true);
+ connect(resetWidget, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ connect(resetWidget, SIGNAL(resetProperty(QtProperty*)), this, SIGNAL(resetProperty(QtProperty*)));
+ m_createdResetWidgets[property].append(resetWidget);
+ m_resetWidgetToProperty[resetWidget] = property;
+ }
+ if (subEditor) {
+ if (resetWidget) {
+ subEditor->setParent(resetWidget);
+ resetWidget->setWidget(subEditor);
+ }
+ }
+ if (resetWidget)
+ return resetWidget;
+ return subEditor;
+}
+
+void ResetDecorator::slotPropertyChanged(QtProperty *property)
+{
+ QMap<QtProperty *, QList<ResetWidget *> >::ConstIterator prIt = m_createdResetWidgets.constFind(property);
+ if (prIt == m_createdResetWidgets.constEnd())
+ return;
+
+ const QList<ResetWidget *> editors = prIt.value();
+ const QList<ResetWidget *>::ConstIterator cend = editors.constEnd();
+ for (QList<ResetWidget *>::ConstIterator itEditor = editors.constBegin(); itEditor != cend; ++itEditor) {
+ ResetWidget *widget = *itEditor;
+ widget->setResetEnabled(property->isModified());
+ widget->setValueText(property->valueText());
+ widget->setValueIcon(property->valueIcon());
+ }
+}
+
+void ResetDecorator::slotEditorDestroyed(QObject *object)
+{
+ const QMap<ResetWidget *, QtProperty *>::ConstIterator rcend = m_resetWidgetToProperty.constEnd();
+ for (QMap<ResetWidget *, QtProperty *>::ConstIterator itEditor = m_resetWidgetToProperty.constBegin(); itEditor != rcend; ++itEditor) {
+ if (itEditor.key() == object) {
+ ResetWidget *editor = itEditor.key();
+ QtProperty *property = itEditor.value();
+ m_resetWidgetToProperty.remove(editor);
+ m_createdResetWidgets[property].removeAll(editor);
+ if (m_createdResetWidgets[property].isEmpty())
+ m_createdResetWidgets.remove(property);
+ return;
+ }
+ }
+}
+
+}
+
+QT_END_NAMESPACE
+
+#include "designerpropertymanager.moc"
diff --git a/src/designer/src/components/propertyeditor/designerpropertymanager.h b/src/designer/src/components/propertyeditor/designerpropertymanager.h
new file mode 100644
index 000000000..4f4bb3c17
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/designerpropertymanager.h
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERPROPERTYMANAGER_H
+#define DESIGNERPROPERTYMANAGER_H
+
+#include "qtvariantproperty.h"
+#include "brushpropertymanager.h"
+#include "fontpropertymanager.h"
+
+#include <qdesigner_utils_p.h>
+#include <shared_enums_p.h>
+
+#include <QtCore/QUrl>
+#include <QtCore/QMap>
+#include <QtGui/QFont>
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+typedef QPair<QString, uint> DesignerIntPair;
+typedef QList<DesignerIntPair> DesignerFlagList;
+
+class QDesignerFormEditorInterface;
+class QLineEdit;
+class QUrl;
+class QtKeySequenceEdit;
+
+namespace qdesigner_internal
+{
+
+class ResetWidget;
+
+class TextEditor;
+class PaletteEditorButton;
+class PixmapEditor;
+class StringListEditorButton;
+class FormWindowBase;
+
+class ResetDecorator : public QObject
+{
+ Q_OBJECT
+public:
+ ResetDecorator(QObject *parent = 0) : QObject(parent), m_spacing(-1) {}
+ ~ResetDecorator();
+
+ void connectPropertyManager(QtAbstractPropertyManager *manager);
+ QWidget *editor(QWidget *subEditor, bool resettable, QtAbstractPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtAbstractPropertyManager *manager);
+ void setSpacing(int spacing);
+signals:
+ void resetProperty(QtProperty *property);
+private slots:
+ void slotPropertyChanged(QtProperty *property);
+ void slotEditorDestroyed(QObject *object);
+private:
+ QMap<QtProperty *, QList<ResetWidget *> > m_createdResetWidgets;
+ QMap<ResetWidget *, QtProperty *> m_resetWidgetToProperty;
+ int m_spacing;
+};
+
+class DesignerPropertyManager : public QtVariantPropertyManager
+{
+ Q_OBJECT
+public:
+ explicit DesignerPropertyManager(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ ~DesignerPropertyManager();
+
+ virtual QStringList attributes(int propertyType) const;
+ virtual int attributeType(int propertyType, const QString &attribute) const;
+
+ virtual QVariant attributeValue(const QtProperty *property, const QString &attribute) const;
+ virtual bool isPropertyTypeSupported(int propertyType) const;
+ virtual QVariant value(const QtProperty *property) const;
+ virtual int valueType(int propertyType) const;
+ virtual QString valueText(const QtProperty *property) const;
+ virtual QIcon valueIcon(const QtProperty *property) const;
+
+ bool resetFontSubProperty(QtProperty *property);
+ bool resetIconSubProperty(QtProperty *subProperty);
+
+ void reloadResourceProperties();
+
+ static int designerFlagTypeId();
+ static int designerFlagListTypeId();
+ static int designerAlignmentTypeId();
+ static int designerPixmapTypeId();
+ static int designerIconTypeId();
+ static int designerStringTypeId();
+ static int designerKeySequenceTypeId();
+
+ void setObject(QObject *object) { m_object = object; }
+
+public Q_SLOTS:
+ virtual void setAttribute(QtProperty *property,
+ const QString &attribute, const QVariant &value);
+ virtual void setValue(QtProperty *property, const QVariant &value);
+Q_SIGNALS:
+ // sourceOfChange - a subproperty (or just property) which caused a change
+ //void valueChanged(QtProperty *property, const QVariant &value, QtProperty *sourceOfChange);
+ void valueChanged(QtProperty *property, const QVariant &value, bool enableSubPropertyHandling);
+protected:
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private Q_SLOTS:
+ void slotValueChanged(QtProperty *property, const QVariant &value);
+ void slotPropertyDestroyed(QtProperty *property);
+private:
+ void createIconSubProperty(QtProperty *iconProperty, QIcon::Mode mode, QIcon::State state, const QString &subName);
+
+ typedef QMap<QtProperty *, bool> PropertyBoolMap;
+ PropertyBoolMap m_resetMap;
+
+ int bitCount(int mask) const;
+ struct FlagData
+ {
+ FlagData() : val(0) {}
+ uint val;
+ DesignerFlagList flags;
+ QList<uint> values;
+ };
+ typedef QMap<QtProperty *, FlagData> PropertyFlagDataMap;
+ PropertyFlagDataMap m_flagValues;
+ typedef QMap<QtProperty *, QList<QtProperty *> > PropertyToPropertyListMap;
+ PropertyToPropertyListMap m_propertyToFlags;
+ QMap<QtProperty *, QtProperty *> m_flagToProperty;
+
+ int alignToIndexH(uint align) const;
+ int alignToIndexV(uint align) const;
+ uint indexHToAlign(int idx) const;
+ uint indexVToAlign(int idx) const;
+ QString indexHToString(int idx) const;
+ QString indexVToString(int idx) const;
+ QMap<QtProperty *, uint> m_alignValues;
+ typedef QMap<QtProperty *, QtProperty *> PropertyToPropertyMap;
+ PropertyToPropertyMap m_propertyToAlignH;
+ PropertyToPropertyMap m_propertyToAlignV;
+ PropertyToPropertyMap m_alignHToProperty;
+ PropertyToPropertyMap m_alignVToProperty;
+
+ QMap<QtProperty *, QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> > m_propertyToIconSubProperties;
+ QMap<QtProperty *, QPair<QIcon::Mode, QIcon::State> > m_iconSubPropertyToState;
+ PropertyToPropertyMap m_iconSubPropertyToProperty;
+ PropertyToPropertyMap m_propertyToTheme;
+
+ QMap<QtProperty *, qdesigner_internal::PropertySheetStringValue> m_stringValues;
+ QMap<QtProperty *, QtProperty *> m_stringToComment;
+ QMap<QtProperty *, QtProperty *> m_stringToTranslatable;
+ QMap<QtProperty *, QtProperty *> m_stringToDisambiguation;
+
+ QMap<QtProperty *, QtProperty *> m_commentToString;
+ QMap<QtProperty *, QtProperty *> m_translatableToString;
+ QMap<QtProperty *, QtProperty *> m_disambiguationToString;
+
+ QMap<QtProperty *, qdesigner_internal::PropertySheetKeySequenceValue> m_keySequenceValues;
+ QMap<QtProperty *, QtProperty *> m_keySequenceToComment;
+ QMap<QtProperty *, QtProperty *> m_keySequenceToTranslatable;
+ QMap<QtProperty *, QtProperty *> m_keySequenceToDisambiguation;
+
+ QMap<QtProperty *, QtProperty *> m_commentToKeySequence;
+ QMap<QtProperty *, QtProperty *> m_translatableToKeySequence;
+ QMap<QtProperty *, QtProperty *> m_disambiguationToKeySequence;
+
+ struct PaletteData
+ {
+ QPalette val;
+ QPalette superPalette;
+ };
+ typedef QMap<QtProperty *, PaletteData> PropertyPaletteDataMap;
+ PropertyPaletteDataMap m_paletteValues;
+
+ QMap<QtProperty *, qdesigner_internal::PropertySheetPixmapValue> m_pixmapValues;
+ QMap<QtProperty *, qdesigner_internal::PropertySheetIconValue> m_iconValues;
+
+ QMap<QtProperty *, uint> m_uintValues;
+ QMap<QtProperty *, qlonglong> m_longLongValues;
+ QMap<QtProperty *, qulonglong> m_uLongLongValues;
+ QMap<QtProperty *, QUrl> m_urlValues;
+ QMap<QtProperty *, QByteArray> m_byteArrayValues;
+ QMap<QtProperty *, QStringList> m_stringListValues;
+
+ typedef QMap<QtProperty *, int> PropertyIntMap;
+ PropertyIntMap m_stringAttributes;
+ typedef QMap<QtProperty *, QFont> PropertyFontMap;
+ PropertyFontMap m_stringFontAttributes;
+ PropertyBoolMap m_stringThemeAttributes;
+
+ BrushPropertyManager m_brushManager;
+ FontPropertyManager m_fontManager;
+
+ QMap<QtProperty *, QPixmap> m_defaultPixmaps;
+ QMap<QtProperty *, QIcon> m_defaultIcons;
+
+ bool m_changingSubValue;
+ QDesignerFormEditorInterface *m_core;
+
+ QObject *m_object;
+
+ QtProperty *m_sourceOfChange;
+};
+
+class DesignerEditorFactory : public QtVariantEditorFactory
+{
+ Q_OBJECT
+public:
+ explicit DesignerEditorFactory(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ ~DesignerEditorFactory();
+ void setSpacing(int spacing);
+ void setFormWindowBase(FormWindowBase *fwb);
+signals:
+ void resetProperty(QtProperty *property);
+protected:
+ void connectPropertyManager(QtVariantPropertyManager *manager);
+ QWidget *createEditor(QtVariantPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtVariantPropertyManager *manager);
+private slots:
+ void slotEditorDestroyed(QObject *object);
+ void slotAttributeChanged(QtProperty *property, const QString &attribute, const QVariant &value);
+ void slotPropertyChanged(QtProperty *property);
+ void slotValueChanged(QtProperty *property, const QVariant &value);
+ void slotStringTextChanged(const QString &value);
+ void slotKeySequenceChanged(const QKeySequence &value);
+ void slotPaletteChanged(const QPalette &value);
+ void slotPixmapChanged(const QString &value);
+ void slotIconChanged(const QString &value);
+ void slotIconThemeChanged(const QString &value);
+ void slotUintChanged(const QString &value);
+ void slotLongLongChanged(const QString &value);
+ void slotULongLongChanged(const QString &value);
+ void slotUrlChanged(const QString &value);
+ void slotByteArrayChanged(const QString &value);
+ void slotStringListChanged(const QStringList &value);
+private:
+ TextEditor *createTextEditor(QWidget *parent, TextPropertyValidationMode vm, const QString &value);
+
+ ResetDecorator *m_resetDecorator;
+ bool m_changingPropertyValue;
+ QDesignerFormEditorInterface *m_core;
+ FormWindowBase *m_fwb;
+
+ int m_spacing;
+
+ QMap<QtProperty *, QList<TextEditor *> > m_stringPropertyToEditors;
+ QMap<TextEditor *, QtProperty *> m_editorToStringProperty;
+ QMap<QtProperty *, QList<QtKeySequenceEdit *> > m_keySequencePropertyToEditors;
+ QMap<QtKeySequenceEdit *, QtProperty *> m_editorToKeySequenceProperty;
+ QMap<QtProperty *, QList<PaletteEditorButton *> > m_palettePropertyToEditors;
+ QMap<PaletteEditorButton *, QtProperty *> m_editorToPaletteProperty;
+ QMap<QtProperty *, QList<PixmapEditor *> > m_pixmapPropertyToEditors;
+ QMap<PixmapEditor *, QtProperty *> m_editorToPixmapProperty;
+ QMap<QtProperty *, QList<PixmapEditor *> > m_iconPropertyToEditors;
+ QMap<PixmapEditor *, QtProperty *> m_editorToIconProperty;
+ QMap<QtProperty *, QList<QLineEdit *> > m_uintPropertyToEditors;
+ QMap<QLineEdit *, QtProperty *> m_editorToUintProperty;
+ QMap<QtProperty *, QList<QLineEdit *> > m_longLongPropertyToEditors;
+ QMap<QLineEdit *, QtProperty *> m_editorToLongLongProperty;
+ QMap<QtProperty *, QList<QLineEdit *> > m_uLongLongPropertyToEditors;
+ QMap<QLineEdit *, QtProperty *> m_editorToULongLongProperty;
+ QMap<QtProperty *, QList<TextEditor *> > m_urlPropertyToEditors;
+ QMap<TextEditor *, QtProperty *> m_editorToUrlProperty;
+ QMap<QtProperty *, QList<TextEditor *> > m_byteArrayPropertyToEditors;
+ QMap<TextEditor *, QtProperty *> m_editorToByteArrayProperty;
+ QMap<QtProperty *, QList<StringListEditorButton *> > m_stringListPropertyToEditors;
+ QMap<StringListEditorButton *, QtProperty *> m_editorToStringListProperty;
+};
+
+}
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(DesignerIntPair)
+Q_DECLARE_METATYPE(DesignerFlagList)
+
+#endif
+
diff --git a/src/designer/src/components/propertyeditor/fontmapping.xml b/src/designer/src/components/propertyeditor/fontmapping.xml
new file mode 100644
index 000000000..cbd68b8db
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/fontmapping.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************-->
+
+<!DOCTYPE fontmapping
+[
+<!ENTITY ce "Windows CE" >
+<!ENTITY qe "Qt Embedded" >
+]>
+
+<fontmappings>
+<mapping><family>DejaVu Sans</family><display>DejaVu Sans [&qe;]</display></mapping>
+<mapping><family>DejaVu Sans</family><display>DejaVu Sans [&qe;]</display></mapping>
+<mapping><family>DejaVu Sans</family><display>DejaVu Sans [&qe;]</display></mapping>
+<mapping><family>DejaVu Sans</family><display>DejaVu Sans [&qe;]</display></mapping>
+<mapping><family>DejaVu Sans Mono</family><display>DejaVu Sans Mono [&qe;]</display></mapping>
+<mapping><family>DejaVu Sans Mono</family><display>DejaVu Sans Mono [&qe;]</display></mapping>
+<mapping><family>DejaVu Sans Mono</family><display>DejaVu Sans Mono [&qe;]</display></mapping>
+<mapping><family>DejaVu Sans Mono</family><display>DejaVu Sans Mono [&qe;]</display></mapping>
+<mapping><family>DejaVu Serif</family><display>DejaVu Serif [&qe;]</display></mapping>
+<mapping><family>DejaVu Serif</family><display>DejaVu Serif [&qe;]</display></mapping>
+<mapping><family>DejaVu Serif</family><display>DejaVu Serif [&qe;]</display></mapping>
+<mapping><family>DejaVu Serif</family><display>DejaVu Serif [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Sans</family><display>Bitstream Vera Sans [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Sans</family><display>Bitstream Vera Sans [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Sans</family><display>Bitstream Vera Sans [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Sans</family><display>Bitstream Vera Sans [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Sans Mono</family><display>Bitstream Vera Sans Mono [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Sans Mono</family><display>Bitstream Vera Sans Mono [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Sans Mono</family><display>Bitstream Vera Sans Mono [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Sans Mono</family><display>Bitstream Vera Sans Mono [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Serif</family><display>Bitstream Vera Serif [&qe;]</display></mapping>
+<mapping><family>Bitstream Vera Serif</family><display>Bitstream Vera Serif [&qe;]</display></mapping>
+</fontmappings>
diff --git a/src/designer/src/components/propertyeditor/fontpropertymanager.cpp b/src/designer/src/components/propertyeditor/fontpropertymanager.cpp
new file mode 100644
index 000000000..d04bfe6e2
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/fontpropertymanager.cpp
@@ -0,0 +1,377 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fontpropertymanager.h"
+#include "qtpropertymanager.h"
+#include "qtvariantproperty.h"
+#include "qtpropertybrowserutils_p.h"
+
+#include <qdesigner_utils_p.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QVariant>
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+#include <QtXml/QXmlStreamReader>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+ static const char *aliasingC[] = {
+ QT_TRANSLATE_NOOP("FontPropertyManager", "PreferDefault"),
+ QT_TRANSLATE_NOOP("FontPropertyManager", "NoAntialias"),
+ QT_TRANSLATE_NOOP("FontPropertyManager", "PreferAntialias")
+ };
+
+ FontPropertyManager::FontPropertyManager() :
+ m_createdFontProperty(0)
+ {
+ const int nameCount = sizeof(aliasingC)/sizeof(const char *);
+ for (int i = 0; i < nameCount; i++)
+ m_aliasingEnumNames.push_back(QCoreApplication::translate("FontPropertyManager", aliasingC[i]));
+
+ QString errorMessage;
+ if (!readFamilyMapping(&m_familyMappings, &errorMessage)) {
+ designerWarning(errorMessage);
+ }
+
+ }
+
+ void FontPropertyManager::preInitializeProperty(QtProperty *property,
+ int type,
+ ResetMap &resetMap)
+ {
+ if (m_createdFontProperty) {
+ PropertyToSubPropertiesMap::iterator it = m_propertyToFontSubProperties.find(m_createdFontProperty);
+ if (it == m_propertyToFontSubProperties.end())
+ it = m_propertyToFontSubProperties.insert(m_createdFontProperty, PropertyList());
+ const int index = it.value().size();
+ m_fontSubPropertyToFlag.insert(property, index);
+ it.value().push_back(property);
+ m_fontSubPropertyToProperty[property] = m_createdFontProperty;
+ resetMap[property] = true;
+ }
+
+ if (type == QVariant::Font)
+ m_createdFontProperty = property;
+ }
+
+ // Map the font family names to display names retrieved from the XML configuration
+ static QStringList designerFamilyNames(QStringList families, const FontPropertyManager::NameMap &nm)
+ {
+ if (nm.empty())
+ return families;
+
+ const FontPropertyManager::NameMap::const_iterator ncend = nm.constEnd();
+ const QStringList::iterator end = families.end();
+ for (QStringList::iterator it = families.begin(); it != end; ++it) {
+ const FontPropertyManager::NameMap::const_iterator nit = nm.constFind(*it);
+ if (nit != ncend)
+ *it = nit.value();
+ }
+ return families;
+ }
+
+ void FontPropertyManager::postInitializeProperty(QtVariantPropertyManager *vm,
+ QtProperty *property,
+ int type,
+ int enumTypeId)
+ {
+ if (type != QVariant::Font)
+ return;
+
+ // This will cause a recursion
+ QtVariantProperty *antialiasing = vm->addProperty(enumTypeId, QCoreApplication::translate("FontPropertyManager", "Antialiasing"));
+ const QFont font = qvariant_cast<QFont>(vm->variantProperty(property)->value());
+
+ antialiasing->setAttribute(QLatin1String("enumNames"), m_aliasingEnumNames);
+ antialiasing->setValue(antialiasingToIndex(font.styleStrategy()));
+ property->addSubProperty(antialiasing);
+
+ m_propertyToAntialiasing[property] = antialiasing;
+ m_antialiasingToProperty[antialiasing] = property;
+ // Fiddle family names
+ if (!m_familyMappings.empty()) {
+ const PropertyToSubPropertiesMap::iterator it = m_propertyToFontSubProperties.find(m_createdFontProperty);
+ QtVariantProperty *familyProperty = vm->variantProperty(it.value().front());
+ const QString enumNamesAttribute = QLatin1String("enumNames");
+ QStringList plainFamilyNames = familyProperty->attributeValue(enumNamesAttribute).toStringList();
+ // Did someone load fonts or something?
+ if (m_designerFamilyNames.size() != plainFamilyNames.size())
+ m_designerFamilyNames = designerFamilyNames(plainFamilyNames, m_familyMappings);
+ familyProperty->setAttribute(enumNamesAttribute, m_designerFamilyNames);
+ }
+ // Next
+ m_createdFontProperty = 0;
+ }
+
+ bool FontPropertyManager::uninitializeProperty(QtProperty *property)
+ {
+ const PropertyToPropertyMap::iterator ait = m_propertyToAntialiasing.find(property);
+ if (ait != m_propertyToAntialiasing.end()) {
+ QtProperty *antialiasing = ait.value();
+ m_antialiasingToProperty.remove(antialiasing);
+ m_propertyToAntialiasing.erase(ait);
+ delete antialiasing;
+ }
+
+ PropertyToSubPropertiesMap::iterator sit = m_propertyToFontSubProperties.find(property);
+ if (sit == m_propertyToFontSubProperties.end())
+ return false;
+
+ m_propertyToFontSubProperties.erase(sit);
+ m_fontSubPropertyToFlag.remove(property);
+ m_fontSubPropertyToProperty.remove(property);
+
+ return true;
+ }
+
+ void FontPropertyManager::slotPropertyDestroyed(QtProperty *property)
+ {
+ removeAntialiasingProperty(property);
+ }
+
+ void FontPropertyManager::removeAntialiasingProperty(QtProperty *property)
+ {
+ const PropertyToPropertyMap::iterator ait = m_antialiasingToProperty.find(property);
+ if (ait == m_antialiasingToProperty.end())
+ return;
+ m_propertyToAntialiasing[ait.value()] = 0;
+ m_antialiasingToProperty.erase(ait);
+ }
+
+ bool FontPropertyManager::resetFontSubProperty(QtVariantPropertyManager *vm, QtProperty *property)
+ {
+ const PropertyToPropertyMap::iterator it = m_fontSubPropertyToProperty.find(property);
+ if (it == m_fontSubPropertyToProperty.end())
+ return false;
+
+ QtVariantProperty *fontProperty = vm->variantProperty(it.value());
+
+ QVariant v = fontProperty->value();
+ QFont font = qvariant_cast<QFont>(v);
+ unsigned mask = font.resolve();
+ const unsigned flag = fontFlag(m_fontSubPropertyToFlag.value(property));
+
+ mask &= ~flag;
+ font.resolve(mask);
+ v.setValue(font);
+ fontProperty->setValue(v);
+ return true;
+ }
+
+ int FontPropertyManager::antialiasingToIndex(QFont::StyleStrategy antialias)
+ {
+ switch (antialias) {
+ case QFont::PreferDefault: return 0;
+ case QFont::NoAntialias: return 1;
+ case QFont::PreferAntialias: return 2;
+ default: break;
+ }
+ return 0;
+ }
+
+ QFont::StyleStrategy FontPropertyManager::indexToAntialiasing(int idx)
+ {
+ switch (idx) {
+ case 0: return QFont::PreferDefault;
+ case 1: return QFont::NoAntialias;
+ case 2: return QFont::PreferAntialias;
+ }
+ return QFont::PreferDefault;
+ }
+
+ unsigned FontPropertyManager::fontFlag(int idx)
+ {
+ switch (idx) {
+ case 0: return QFont::FamilyResolved;
+ case 1: return QFont::SizeResolved;
+ case 2: return QFont::WeightResolved;
+ case 3: return QFont::StyleResolved;
+ case 4: return QFont::UnderlineResolved;
+ case 5: return QFont::StrikeOutResolved;
+ case 6: return QFont::KerningResolved;
+ case 7: return QFont::StyleStrategyResolved;
+ }
+ return 0;
+ }
+
+ FontPropertyManager::ValueChangedResult FontPropertyManager::valueChanged(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value)
+ {
+ QtProperty *antialiasingProperty = m_antialiasingToProperty.value(property, 0);
+ if (!antialiasingProperty) {
+ if (m_propertyToFontSubProperties.contains(property)) {
+ updateModifiedState(property, value);
+ }
+ return NoMatch;
+ }
+
+ QtVariantProperty *fontProperty = vm->variantProperty(antialiasingProperty);
+ const QFont::StyleStrategy newValue = indexToAntialiasing(value.toInt());
+
+ QFont font = qvariant_cast<QFont>(fontProperty->value());
+ const QFont::StyleStrategy oldValue = font.styleStrategy();
+ if (newValue == oldValue)
+ return Unchanged;
+
+ font.setStyleStrategy(newValue);
+ fontProperty->setValue(QVariant::fromValue(font));
+ return Changed;
+ }
+
+ void FontPropertyManager::updateModifiedState(QtProperty *property, const QVariant &value)
+ {
+ const PropertyToSubPropertiesMap::iterator it = m_propertyToFontSubProperties.find(property);
+ if (it == m_propertyToFontSubProperties.end())
+ return;
+
+ const PropertyList &subProperties = it.value();
+
+ QFont font = qvariant_cast<QFont>(value);
+ const unsigned mask = font.resolve();
+
+ const int count = subProperties.size();
+ for (int index = 0; index < count; index++) {
+ const unsigned flag = fontFlag(index);
+ subProperties.at(index)->setModified(mask & flag);
+ }
+ }
+
+ void FontPropertyManager::setValue(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value)
+ {
+ updateModifiedState(property, value);
+
+ if (QtProperty *antialiasingProperty = m_propertyToAntialiasing.value(property, 0)) {
+ QtVariantProperty *antialiasing = vm->variantProperty(antialiasingProperty);
+ if (antialiasing) {
+ QFont font = qvariant_cast<QFont>(value);
+ antialiasing->setValue(antialiasingToIndex(font.styleStrategy()));
+ }
+ }
+ }
+
+ /* Parse a mappings file of the form:
+ * <fontmappings>
+ * <mapping><family>DejaVu Sans</family><display>DejaVu Sans [CE]</display></mapping>
+ * ... which is used to display on which platforms fonts are available.*/
+
+ static const char *rootTagC = "fontmappings";
+ static const char *mappingTagC = "mapping";
+ static const char *familyTagC = "family";
+ static const char *displayTagC = "display";
+
+ static QString msgXmlError(const QXmlStreamReader &r, const QString& fileName)
+ {
+ return QString::fromUtf8("An error has been encountered at line %1 of %2: %3:").arg(r.lineNumber()).arg(fileName, r.errorString());
+ }
+
+ /* Switch stages when encountering a start element (state table) */
+ enum ParseStage { ParseBeginning, ParseWithinRoot, ParseWithinMapping, ParseWithinFamily,
+ ParseWithinDisplay, ParseError };
+
+ static ParseStage nextStage(ParseStage currentStage, const QStringRef &startElement)
+ {
+ switch (currentStage) {
+ case ParseBeginning:
+ return startElement == QLatin1String(rootTagC) ? ParseWithinRoot : ParseError;
+ case ParseWithinRoot:
+ case ParseWithinDisplay: // Next mapping, was in <display>
+ return startElement == QLatin1String(mappingTagC) ? ParseWithinMapping : ParseError;
+ case ParseWithinMapping:
+ return startElement == QLatin1String(familyTagC) ? ParseWithinFamily : ParseError;
+ case ParseWithinFamily:
+ return startElement == QLatin1String(displayTagC) ? ParseWithinDisplay : ParseError;
+ case ParseError:
+ break;
+ }
+ return ParseError;
+ }
+
+ bool FontPropertyManager::readFamilyMapping(NameMap *rc, QString *errorMessage)
+ {
+ rc->clear();
+ const QString fileName = QLatin1String(":/trolltech/propertyeditor/fontmapping.xml");
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ *errorMessage = QString::fromUtf8("Unable to open %1: %2").arg(fileName, file.errorString());
+ return false;
+ }
+
+ QXmlStreamReader reader(&file);
+ QXmlStreamReader::TokenType token;
+
+ QString family;
+ ParseStage stage = ParseBeginning;
+ do {
+ token = reader.readNext();
+ switch (token) {
+ case QXmlStreamReader::Invalid:
+ *errorMessage = msgXmlError(reader, fileName);
+ return false;
+ case QXmlStreamReader::StartElement:
+ stage = nextStage(stage, reader.name());
+ switch (stage) {
+ case ParseError:
+ reader.raiseError(QString::fromUtf8("Unexpected element <%1>.").arg(reader.name().toString()));
+ *errorMessage = msgXmlError(reader, fileName);
+ return false;
+ case ParseWithinFamily:
+ family = reader.readElementText();
+ break;
+ case ParseWithinDisplay:
+ rc->insert(family, reader.readElementText());
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ } while (token != QXmlStreamReader::EndDocument);
+ return true;
+ }
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/fontpropertymanager.h b/src/designer/src/components/propertyeditor/fontpropertymanager.h
new file mode 100644
index 000000000..2154186b7
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/fontpropertymanager.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FONTPROPERTYMANAGER_H
+#define FONTPROPERTYMANAGER_H
+
+#include <QtCore/QMap>
+#include <QtCore/QStringList>
+#include <QtGui/QFont>
+
+QT_BEGIN_NAMESPACE
+
+class QtProperty;
+class QtVariantPropertyManager;
+
+class QString;
+class QVariant;
+
+namespace qdesigner_internal {
+
+/* FontPropertyManager: A mixin for DesignerPropertyManager that manages font
+ * properties. Adds an antialiasing subproperty and reset flags/mask handling
+ * for the other subproperties. It also modifies the font family
+ * enumeration names, which it reads from an XML mapping file that
+ * contains annotations indicating the platform the font is available on. */
+
+class FontPropertyManager {
+ Q_DISABLE_COPY(FontPropertyManager)
+
+public:
+ FontPropertyManager();
+
+ typedef QMap<QtProperty *, bool> ResetMap;
+ typedef QMap<QString, QString> NameMap;
+
+ // Call before QtVariantPropertyManager::initializeProperty.
+ void preInitializeProperty(QtProperty *property, int type, ResetMap &resetMap);
+ // Call after QtVariantPropertyManager::initializeProperty. This will trigger
+ // a recursion for the sub properties
+ void postInitializeProperty(QtVariantPropertyManager *vm, QtProperty *property, int type, int enumTypeId);
+
+ bool uninitializeProperty(QtProperty *property);
+
+ // Call from QtPropertyManager's propertyDestroyed signal
+ void slotPropertyDestroyed(QtProperty *property);
+
+ bool resetFontSubProperty(QtVariantPropertyManager *vm, QtProperty *subProperty);
+
+ // Call from slotValueChanged().
+ enum ValueChangedResult { NoMatch, Unchanged, Changed };
+ ValueChangedResult valueChanged(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value);
+
+ // Call from setValue() before calling setValue() on QtVariantPropertyManager.
+ void setValue(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value);
+
+ static bool readFamilyMapping(NameMap *rc, QString *errorMessage);
+
+private:
+ typedef QMap<QtProperty *, QtProperty *> PropertyToPropertyMap;
+ typedef QList<QtProperty *> PropertyList;
+ typedef QMap<QtProperty *, PropertyList> PropertyToSubPropertiesMap;
+
+ void removeAntialiasingProperty(QtProperty *);
+ void updateModifiedState(QtProperty *property, const QVariant &value);
+ static int antialiasingToIndex(QFont::StyleStrategy antialias);
+ static QFont::StyleStrategy indexToAntialiasing(int idx);
+ static unsigned fontFlag(int idx);
+
+ PropertyToPropertyMap m_propertyToAntialiasing;
+ PropertyToPropertyMap m_antialiasingToProperty;
+
+ PropertyToSubPropertiesMap m_propertyToFontSubProperties;
+ QMap<QtProperty *, int> m_fontSubPropertyToFlag;
+ PropertyToPropertyMap m_fontSubPropertyToProperty;
+ QtProperty *m_createdFontProperty;
+ QStringList m_aliasingEnumNames;
+ // Font families with Designer annotations
+ QStringList m_designerFamilyNames;
+ NameMap m_familyMappings;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // FONTPROPERTYMANAGER_H
diff --git a/src/designer/src/components/propertyeditor/newdynamicpropertydialog.cpp b/src/designer/src/components/propertyeditor/newdynamicpropertydialog.cpp
new file mode 100644
index 000000000..32277a0ba
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/newdynamicpropertydialog.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "newdynamicpropertydialog.h"
+#include "ui_newdynamicpropertydialog.h"
+#include <abstractdialoggui_p.h>
+#include <qdesigner_propertysheet_p.h>
+
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+NewDynamicPropertyDialog::NewDynamicPropertyDialog(QDesignerDialogGuiInterface *dialogGui,
+ QWidget *parent) :
+ QDialog(parent),
+ m_dialogGui(dialogGui),
+ m_ui(new Ui::NewDynamicPropertyDialog)
+{
+ m_ui->setupUi(this);
+ connect(m_ui->m_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(nameChanged(QString)));
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ m_ui->m_comboBox->addItem(QLatin1String("String"), QVariant(QVariant::String));
+ m_ui->m_comboBox->addItem(QLatin1String("StringList"), QVariant(QVariant::StringList));
+ m_ui->m_comboBox->addItem(QLatin1String("Char"), QVariant(QVariant::Char));
+ m_ui->m_comboBox->addItem(QLatin1String("ByteArray"), QVariant(QVariant::ByteArray));
+ m_ui->m_comboBox->addItem(QLatin1String("Url"), QVariant(QVariant::Url));
+ m_ui->m_comboBox->addItem(QLatin1String("Bool"), QVariant(QVariant::Bool));
+ m_ui->m_comboBox->addItem(QLatin1String("Int"), QVariant(QVariant::Int));
+ m_ui->m_comboBox->addItem(QLatin1String("UInt"), QVariant(QVariant::UInt));
+ m_ui->m_comboBox->addItem(QLatin1String("LongLong"), QVariant(QVariant::LongLong));
+ m_ui->m_comboBox->addItem(QLatin1String("ULongLong"), QVariant(QVariant::ULongLong));
+ m_ui->m_comboBox->addItem(QLatin1String("Double"), QVariant(QVariant::Double));
+ m_ui->m_comboBox->addItem(QLatin1String("Size"), QVariant(QVariant::Size));
+ m_ui->m_comboBox->addItem(QLatin1String("SizeF"), QVariant(QVariant::SizeF));
+ m_ui->m_comboBox->addItem(QLatin1String("Point"), QVariant(QVariant::Point));
+ m_ui->m_comboBox->addItem(QLatin1String("PointF"), QVariant(QVariant::PointF));
+ m_ui->m_comboBox->addItem(QLatin1String("Rect"), QVariant(QVariant::Rect));
+ m_ui->m_comboBox->addItem(QLatin1String("RectF"), QVariant(QVariant::RectF));
+ m_ui->m_comboBox->addItem(QLatin1String("Date"), QVariant(QVariant::Date));
+ m_ui->m_comboBox->addItem(QLatin1String("Time"), QVariant(QVariant::Time));
+ m_ui->m_comboBox->addItem(QLatin1String("DateTime"), QVariant(QVariant::DateTime));
+ m_ui->m_comboBox->addItem(QLatin1String("Font"), QVariant(QVariant::Font));
+ m_ui->m_comboBox->addItem(QLatin1String("Palette"), QVariant(QVariant::Palette));
+ m_ui->m_comboBox->addItem(QLatin1String("Color"), QVariant(QVariant::Color));
+ m_ui->m_comboBox->addItem(QLatin1String("Pixmap"), QVariant(QVariant::Pixmap));
+ m_ui->m_comboBox->addItem(QLatin1String("Icon"), QVariant(QVariant::Icon));
+ m_ui->m_comboBox->addItem(QLatin1String("Cursor"), QVariant(QVariant::Cursor));
+ m_ui->m_comboBox->addItem(QLatin1String("SizePolicy"), QVariant(QVariant::SizePolicy));
+ m_ui->m_comboBox->addItem(QLatin1String("KeySequence"), QVariant(QVariant::KeySequence));
+
+ m_ui->m_comboBox->setCurrentIndex(0); // String
+ setOkButtonEnabled(false);
+}
+
+void NewDynamicPropertyDialog::setOkButtonEnabled(bool e)
+{
+ m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(e);
+}
+
+NewDynamicPropertyDialog::~NewDynamicPropertyDialog()
+{
+ delete m_ui;
+}
+
+void NewDynamicPropertyDialog::setReservedNames(const QStringList &names)
+{
+ m_reservedNames = names;
+}
+
+void NewDynamicPropertyDialog::setPropertyType(QVariant::Type t)
+{
+ const int index = m_ui->m_comboBox->findData(QVariant(t));
+ if (index != -1)
+ m_ui->m_comboBox->setCurrentIndex(index);
+}
+
+QString NewDynamicPropertyDialog::propertyName() const
+{
+ return m_ui->m_lineEdit->text();
+}
+
+QVariant NewDynamicPropertyDialog::propertyValue() const
+{
+ const int index = m_ui->m_comboBox->currentIndex();
+ if (index == -1)
+ return QVariant();
+ return m_ui->m_comboBox->itemData(index);
+}
+
+void NewDynamicPropertyDialog::information(const QString &message)
+{
+ m_dialogGui->message(this, QDesignerDialogGuiInterface::PropertyEditorMessage, QMessageBox::Information, tr("Set Property Name"), message);
+}
+
+void NewDynamicPropertyDialog::nameChanged(const QString &s)
+{
+ setOkButtonEnabled(!s.isEmpty());
+}
+
+bool NewDynamicPropertyDialog::validatePropertyName(const QString& name)
+{
+ if (m_reservedNames.contains(name)) {
+ information(tr("The current object already has a property named '%1'.\nPlease select another, unique one.").arg(name));
+ return false;
+ }
+ if (!QDesignerPropertySheet::internalDynamicPropertiesEnabled() && name.startsWith(QLatin1String("_q_"))) {
+ information(tr("The '_q_' prefix is reserved for the Qt library.\nPlease select another name."));
+ return false;
+ }
+ return true;
+}
+
+void NewDynamicPropertyDialog::on_m_buttonBox_clicked(QAbstractButton *btn)
+{
+ const int role = m_ui->m_buttonBox->buttonRole(btn);
+ switch (role) {
+ case QDialogButtonBox::RejectRole:
+ reject();
+ break;
+ case QDialogButtonBox::AcceptRole:
+ if (validatePropertyName(propertyName()))
+ accept();
+ break;
+ }
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/newdynamicpropertydialog.h b/src/designer/src/components/propertyeditor/newdynamicpropertydialog.h
new file mode 100644
index 000000000..7c3966a43
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/newdynamicpropertydialog.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEWDYNAMICPROPERTYDIALOG_P_H
+#define NEWDYNAMICPROPERTYDIALOG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "propertyeditor_global.h"
+#include <QtGui/QDialog>
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractButton;
+class QDesignerDialogGuiInterface;
+
+namespace qdesigner_internal {
+
+namespace Ui
+{
+ class NewDynamicPropertyDialog;
+}
+
+class QT_PROPERTYEDITOR_EXPORT NewDynamicPropertyDialog: public QDialog
+{
+ Q_OBJECT
+public:
+ explicit NewDynamicPropertyDialog(QDesignerDialogGuiInterface *dialogGui, QWidget *parent = 0);
+ ~NewDynamicPropertyDialog();
+
+ void setReservedNames(const QStringList &names);
+ void setPropertyType(QVariant::Type t);
+
+ QString propertyName() const;
+ QVariant propertyValue() const;
+
+private slots:
+
+ void on_m_buttonBox_clicked(QAbstractButton *btn);
+ void nameChanged(const QString &);
+
+private:
+ bool validatePropertyName(const QString& name);
+ void setOkButtonEnabled(bool e);
+ void information(const QString &message);
+
+ QDesignerDialogGuiInterface *m_dialogGui;
+ Ui::NewDynamicPropertyDialog *m_ui;
+ QStringList m_reservedNames;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // NEWDYNAMICPROPERTYDIALOG_P_H
diff --git a/src/designer/src/components/propertyeditor/newdynamicpropertydialog.ui b/src/designer/src/components/propertyeditor/newdynamicpropertydialog.ui
new file mode 100644
index 000000000..2aa91f3e9
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/newdynamicpropertydialog.ui
@@ -0,0 +1,106 @@
+<ui version="4.0" >
+ <class>qdesigner_internal::NewDynamicPropertyDialog</class>
+ <widget class="QDialog" name="qdesigner_internal::NewDynamicPropertyDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>118</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Create Dynamic Property</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <layout class="QFormLayout" name="formLayout" >
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="m_lineEdit" >
+ <property name="minimumSize" >
+ <size>
+ <width>220</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Property Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <layout class="QHBoxLayout" name="horizontalLayout" >
+ <item>
+ <widget class="QComboBox" name="m_comboBox" />
+ </item>
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="spacerName" stdset="0" >
+ <string>horizontalSpacer</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Property Type</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="spacerName" stdset="0" >
+ <string/>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="m_buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ <property name="centerButtons" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/components/propertyeditor/paletteeditor.cpp b/src/designer/src/components/propertyeditor/paletteeditor.cpp
new file mode 100644
index 000000000..55a6da5cb
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/paletteeditor.cpp
@@ -0,0 +1,616 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "paletteeditor.h"
+
+#include <iconloader_p.h>
+#include <qtcolorbutton.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerIconCacheInterface>
+
+#include <QtCore/QMetaProperty>
+#include <QtGui/QPainter>
+#include <QtGui/QToolButton>
+#include <QtGui/QLabel>
+#include <QtGui/QHeaderView>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+enum { BrushRole = 33 };
+
+PaletteEditor::PaletteEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QDialog(parent),
+ m_currentColorGroup(QPalette::Active),
+ m_paletteModel(new PaletteModel(this)),
+ m_modelUpdated(false),
+ m_paletteUpdated(false),
+ m_compute(true),
+ m_core(core)
+{
+ ui.setupUi(this);
+ ui.paletteView->setModel(m_paletteModel);
+ updatePreviewPalette();
+ updateStyledButton();
+ ui.paletteView->setModel(m_paletteModel);
+ ColorDelegate *delegate = new ColorDelegate(core, this);
+ ui.paletteView->setItemDelegate(delegate);
+ ui.paletteView->setEditTriggers(QAbstractItemView::AllEditTriggers);
+ connect(m_paletteModel, SIGNAL(paletteChanged(QPalette)),
+ this, SLOT(paletteChanged(QPalette)));
+ ui.paletteView->setSelectionBehavior(QAbstractItemView::SelectRows);
+ ui.paletteView->setDragEnabled(true);
+ ui.paletteView->setDropIndicatorShown(true);
+ ui.paletteView->setRootIsDecorated(false);
+ ui.paletteView->setColumnHidden(2, true);
+ ui.paletteView->setColumnHidden(3, true);
+}
+
+PaletteEditor::~PaletteEditor()
+{
+}
+
+QPalette PaletteEditor::palette() const
+{
+ return m_editPalette;
+}
+
+void PaletteEditor::setPalette(const QPalette &palette)
+{
+ m_editPalette = palette;
+ const uint mask = palette.resolve();
+ for (int i = 0; i < (int)QPalette::NColorRoles; i++) {
+ if (!(mask & (1 << i))) {
+ m_editPalette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(i),
+ m_parentPalette.brush(QPalette::Active, static_cast<QPalette::ColorRole>(i)));
+ m_editPalette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i),
+ m_parentPalette.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i)));
+ m_editPalette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i),
+ m_parentPalette.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i)));
+ }
+ }
+ m_editPalette.resolve(mask);
+ updatePreviewPalette();
+ updateStyledButton();
+ m_paletteUpdated = true;
+ if (!m_modelUpdated)
+ m_paletteModel->setPalette(m_editPalette, m_parentPalette);
+ m_paletteUpdated = false;
+}
+
+void PaletteEditor::setPalette(const QPalette &palette, const QPalette &parentPalette)
+{
+ m_parentPalette = parentPalette;
+ setPalette(palette);
+}
+
+void PaletteEditor::on_buildButton_colorChanged(const QColor &)
+{
+ buildPalette();
+}
+
+void PaletteEditor::on_activeRadio_clicked()
+{
+ m_currentColorGroup = QPalette::Active;
+ updatePreviewPalette();
+}
+
+void PaletteEditor::on_inactiveRadio_clicked()
+{
+ m_currentColorGroup = QPalette::Inactive;
+ updatePreviewPalette();
+}
+
+void PaletteEditor::on_disabledRadio_clicked()
+{
+ m_currentColorGroup = QPalette::Disabled;
+ updatePreviewPalette();
+}
+
+void PaletteEditor::on_computeRadio_clicked()
+{
+ if (m_compute)
+ return;
+ ui.paletteView->setColumnHidden(2, true);
+ ui.paletteView->setColumnHidden(3, true);
+ m_compute = true;
+ m_paletteModel->setCompute(true);
+}
+
+void PaletteEditor::on_detailsRadio_clicked()
+{
+ if (!m_compute)
+ return;
+ const int w = ui.paletteView->columnWidth(1);
+ ui.paletteView->setColumnHidden(2, false);
+ ui.paletteView->setColumnHidden(3, false);
+ QHeaderView *header = ui.paletteView->header();
+ header->resizeSection(1, w / 3);
+ header->resizeSection(2, w / 3);
+ header->resizeSection(3, w / 3);
+ m_compute = false;
+ m_paletteModel->setCompute(false);
+}
+
+void PaletteEditor::paletteChanged(const QPalette &palette)
+{
+ m_modelUpdated = true;
+ if (!m_paletteUpdated)
+ setPalette(palette);
+ m_modelUpdated = false;
+}
+
+void PaletteEditor::buildPalette()
+{
+ const QColor btn = ui.buildButton->color();
+ const QPalette temp = QPalette(btn);
+ setPalette(temp);
+}
+
+void PaletteEditor::updatePreviewPalette()
+{
+ const QPalette::ColorGroup g = currentColorGroup();
+ // build the preview palette
+ const QPalette currentPalette = palette();
+ QPalette previewPalette;
+ for (int i = QPalette::WindowText; i < QPalette::NColorRoles; i++) {
+ const QPalette::ColorRole r = static_cast<QPalette::ColorRole>(i);
+ const QBrush br = currentPalette.brush(g, r);
+ previewPalette.setBrush(QPalette::Active, r, br);
+ previewPalette.setBrush(QPalette::Inactive, r, br);
+ previewPalette.setBrush(QPalette::Disabled, r, br);
+ }
+ ui.previewFrame->setPreviewPalette(previewPalette);
+
+ const bool enabled = g != QPalette::Disabled;
+ ui.previewFrame->setEnabled(enabled);
+ ui.previewFrame->setSubWindowActive(g != QPalette::Inactive);
+}
+
+void PaletteEditor::updateStyledButton()
+{
+ ui.buildButton->setColor(palette().color(QPalette::Active, QPalette::Button));
+}
+
+QPalette PaletteEditor::getPalette(QDesignerFormEditorInterface *core, QWidget* parent, const QPalette &init,
+ const QPalette &parentPal, int *ok)
+{
+ PaletteEditor dlg(core, parent);
+ QPalette parentPalette(parentPal);
+ uint mask = init.resolve();
+ for (int i = 0; i < (int)QPalette::NColorRoles; i++) {
+ if (!(mask & (1 << i))) {
+ parentPalette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(i),
+ init.brush(QPalette::Active, static_cast<QPalette::ColorRole>(i)));
+ parentPalette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i),
+ init.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i)));
+ parentPalette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i),
+ init.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i)));
+ }
+ }
+ dlg.setPalette(init, parentPalette);
+
+ const int result = dlg.exec();
+ if (ok) *ok = result;
+
+ return result == QDialog::Accepted ? dlg.palette() : init;
+}
+
+//////////////////////
+
+PaletteModel::PaletteModel(QObject *parent) :
+ QAbstractTableModel(parent),
+ m_compute(true)
+{
+ const QMetaObject *meta = metaObject();
+ const int index = meta->indexOfProperty("colorRole");
+ const QMetaProperty p = meta->property(index);
+ const QMetaEnum e = p.enumerator();
+ for (int r = QPalette::WindowText; r < QPalette::NColorRoles; r++) {
+ m_roleNames[static_cast<QPalette::ColorRole>(r)] = QLatin1String(e.key(r));
+ }
+}
+
+int PaletteModel::rowCount(const QModelIndex &) const
+{
+ return m_roleNames.count();
+}
+
+int PaletteModel::columnCount(const QModelIndex &) const
+{
+ return 4;
+}
+
+QVariant PaletteModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+ if (index.row() < 0 || index.row() >= QPalette::NColorRoles)
+ return QVariant();
+ if (index.column() < 0 || index.column() >= 4)
+ return QVariant();
+
+ if (index.column() == 0) {
+ if (role == Qt::DisplayRole)
+ return m_roleNames[static_cast<QPalette::ColorRole>(index.row())];
+ if (role == Qt::EditRole) {
+ const uint mask = m_palette.resolve();
+ if (mask & (1 << index.row()))
+ return true;
+ return false;
+ }
+ return QVariant();
+ }
+ if (role == BrushRole)
+ return m_palette.brush(columnToGroup(index.column()),
+ static_cast<QPalette::ColorRole>(index.row()));
+ return QVariant();
+}
+
+bool PaletteModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid())
+ return false;
+
+ if (index.column() != 0 && role == BrushRole) {
+ const QBrush br = qvariant_cast<QBrush>(value);
+ const QPalette::ColorRole r = static_cast<QPalette::ColorRole>(index.row());
+ const QPalette::ColorGroup g = columnToGroup(index.column());
+ m_palette.setBrush(g, r, br);
+
+ QModelIndex idxBegin = PaletteModel::index(r, 0);
+ QModelIndex idxEnd = PaletteModel::index(r, 3);
+ if (m_compute) {
+ m_palette.setBrush(QPalette::Inactive, r, br);
+ switch (r) {
+ case QPalette::WindowText:
+ case QPalette::Text:
+ case QPalette::ButtonText:
+ case QPalette::Base:
+ break;
+ case QPalette::Dark:
+ m_palette.setBrush(QPalette::Disabled, QPalette::WindowText, br);
+ m_palette.setBrush(QPalette::Disabled, QPalette::Dark, br);
+ m_palette.setBrush(QPalette::Disabled, QPalette::Text, br);
+ m_palette.setBrush(QPalette::Disabled, QPalette::ButtonText, br);
+ idxBegin = PaletteModel::index(0, 0);
+ idxEnd = PaletteModel::index(m_roleNames.count() - 1, 3);
+ break;
+ case QPalette::Window:
+ m_palette.setBrush(QPalette::Disabled, QPalette::Base, br);
+ m_palette.setBrush(QPalette::Disabled, QPalette::Window, br);
+ idxBegin = PaletteModel::index(QPalette::Base, 0);
+ break;
+ case QPalette::Highlight:
+ //m_palette.setBrush(QPalette::Disabled, QPalette::Highlight, c.dark(120));
+ break;
+ default:
+ m_palette.setBrush(QPalette::Disabled, r, br);
+ break;
+ }
+ }
+ emit paletteChanged(m_palette);
+ emit dataChanged(idxBegin, idxEnd);
+ return true;
+ }
+ if (index.column() == 0 && role == Qt::EditRole) {
+ uint mask = m_palette.resolve();
+ const bool isMask = qvariant_cast<bool>(value);
+ const int r = index.row();
+ if (isMask)
+ mask |= (1 << r);
+ else {
+ m_palette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(r),
+ m_parentPalette.brush(QPalette::Active, static_cast<QPalette::ColorRole>(r)));
+ m_palette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(r),
+ m_parentPalette.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(r)));
+ m_palette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(r),
+ m_parentPalette.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(r)));
+
+ mask &= ~(1 << index.row());
+ }
+ m_palette.resolve(mask);
+ emit paletteChanged(m_palette);
+ const QModelIndex idxEnd = PaletteModel::index(r, 3);
+ emit dataChanged(index, idxEnd);
+ return true;
+ }
+ return false;
+}
+
+Qt::ItemFlags PaletteModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return Qt::ItemIsEnabled;
+ return Qt::ItemIsEditable | Qt::ItemIsEnabled;
+}
+
+QVariant PaletteModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+ if (section == 0)
+ return tr("Color Role");
+ if (section == groupToColumn(QPalette::Active))
+ return tr("Active");
+ if (section == groupToColumn(QPalette::Inactive))
+ return tr("Inactive");
+ if (section == groupToColumn(QPalette::Disabled))
+ return tr("Disabled");
+ }
+ return QVariant();
+}
+
+QPalette PaletteModel::getPalette() const
+{
+ return m_palette;
+}
+
+void PaletteModel::setPalette(const QPalette &palette, const QPalette &parentPalette)
+{
+ m_parentPalette = parentPalette;
+ m_palette = palette;
+ const QModelIndex idxBegin = index(0, 0);
+ const QModelIndex idxEnd = index(m_roleNames.count() - 1, 3);
+ emit dataChanged(idxBegin, idxEnd);
+}
+
+QPalette::ColorGroup PaletteModel::columnToGroup(int index) const
+{
+ if (index == 1)
+ return QPalette::Active;
+ if (index == 2)
+ return QPalette::Inactive;
+ return QPalette::Disabled;
+}
+
+int PaletteModel::groupToColumn(QPalette::ColorGroup group) const
+{
+ if (group == QPalette::Active)
+ return 1;
+ if (group == QPalette::Inactive)
+ return 2;
+ return 3;
+}
+
+//////////////////////////
+
+BrushEditor::BrushEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QWidget(parent),
+ m_button(new QtColorButton(this)),
+ m_changed(false),
+ m_core(core)
+{
+ QLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ layout->addWidget(m_button);
+ connect(m_button, SIGNAL(colorChanged(QColor)), this, SLOT(brushChanged()));
+ setFocusProxy(m_button);
+}
+
+void BrushEditor::setBrush(const QBrush &brush)
+{
+ m_button->setColor(brush.color());
+ m_changed = false;
+}
+
+QBrush BrushEditor::brush() const
+{
+ return QBrush(m_button->color());
+}
+
+void BrushEditor::brushChanged()
+{
+ m_changed = true;
+ emit changed(this);
+}
+
+bool BrushEditor::changed() const
+{
+ return m_changed;
+}
+
+//////////////////////////
+
+RoleEditor::RoleEditor(QWidget *parent) :
+ QWidget(parent),
+ m_label(new QLabel(this)),
+ m_edited(false)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ layout->setSpacing(0);
+
+ layout->addWidget(m_label);
+ m_label->setAutoFillBackground(true);
+ m_label->setIndent(3); // ### hardcode it should have the same value of textMargin in QItemDelegate
+ setFocusProxy(m_label);
+
+ QToolButton *button = new QToolButton(this);
+ button->setToolButtonStyle(Qt::ToolButtonIconOnly);
+ button->setIcon(createIconSet(QLatin1String("resetproperty.png")));
+ button->setIconSize(QSize(8,8));
+ button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding));
+ layout->addWidget(button);
+ connect(button, SIGNAL(clicked()), this, SLOT(emitResetProperty()));
+}
+
+void RoleEditor::setLabel(const QString &label)
+{
+ m_label->setText(label);
+}
+
+void RoleEditor::setEdited(bool on)
+{
+ QFont font;
+ if (on == true) {
+ font.setBold(on);
+ }
+ m_label->setFont(font);
+ m_edited = on;
+}
+
+bool RoleEditor::edited() const
+{
+ return m_edited;
+}
+
+void RoleEditor::emitResetProperty()
+{
+ setEdited(false);
+ emit changed(this);
+}
+
+//////////////////////////
+ColorDelegate::ColorDelegate(QDesignerFormEditorInterface *core, QObject *parent) :
+ QItemDelegate(parent),
+ m_core(core)
+{
+}
+
+QWidget *ColorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &,
+ const QModelIndex &index) const
+{
+ QWidget *ed = 0;
+ if (index.column() == 0) {
+ RoleEditor *editor = new RoleEditor(parent);
+ connect(editor, SIGNAL(changed(QWidget*)), this, SIGNAL(commitData(QWidget*)));
+ //editor->setFocusPolicy(Qt::NoFocus);
+ //editor->installEventFilter(const_cast<ColorDelegate *>(this));
+ ed = editor;
+ } else {
+ BrushEditor *editor = new BrushEditor(m_core, parent);
+ connect(editor, SIGNAL(changed(QWidget*)), this, SIGNAL(commitData(QWidget*)));
+ editor->setFocusPolicy(Qt::NoFocus);
+ editor->installEventFilter(const_cast<ColorDelegate *>(this));
+ ed = editor;
+ }
+ return ed;
+}
+
+void ColorDelegate::setEditorData(QWidget *ed, const QModelIndex &index) const
+{
+ if (index.column() == 0) {
+ const bool mask = qvariant_cast<bool>(index.model()->data(index, Qt::EditRole));
+ RoleEditor *editor = static_cast<RoleEditor *>(ed);
+ editor->setEdited(mask);
+ const QString colorName = qvariant_cast<QString>(index.model()->data(index, Qt::DisplayRole));
+ editor->setLabel(colorName);
+ } else {
+ const QBrush br = qvariant_cast<QBrush>(index.model()->data(index, BrushRole));
+ BrushEditor *editor = static_cast<BrushEditor *>(ed);
+ editor->setBrush(br);
+ }
+}
+
+void ColorDelegate::setModelData(QWidget *ed, QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+ if (index.column() == 0) {
+ RoleEditor *editor = static_cast<RoleEditor *>(ed);
+ const bool mask = editor->edited();
+ model->setData(index, mask, Qt::EditRole);
+ } else {
+ BrushEditor *editor = static_cast<BrushEditor *>(ed);
+ if (editor->changed()) {
+ QBrush br = editor->brush();
+ model->setData(index, br, BrushRole);
+ }
+ }
+}
+
+void ColorDelegate::updateEditorGeometry(QWidget *ed,
+ const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ QItemDelegate::updateEditorGeometry(ed, option, index);
+ ed->setGeometry(ed->geometry().adjusted(0, 0, -1, -1));
+}
+
+void ColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt,
+ const QModelIndex &index) const
+{
+ QStyleOptionViewItem option = opt;
+ const bool mask = qvariant_cast<bool>(index.model()->data(index, Qt::EditRole));
+ if (index.column() == 0 && mask) {
+ option.font.setBold(true);
+ }
+ QBrush br = qvariant_cast<QBrush>(index.model()->data(index, BrushRole));
+ if (br.style() == Qt::LinearGradientPattern ||
+ br.style() == Qt::RadialGradientPattern ||
+ br.style() == Qt::ConicalGradientPattern) {
+ painter->save();
+ painter->translate(option.rect.x(), option.rect.y());
+ painter->scale(option.rect.width(), option.rect.height());
+ QGradient gr = *(br.gradient());
+ gr.setCoordinateMode(QGradient::LogicalMode);
+ br = QBrush(gr);
+ painter->fillRect(0, 0, 1, 1, br);
+ painter->restore();
+ } else {
+ painter->save();
+ painter->setBrushOrigin(option.rect.x(), option.rect.y());
+ painter->fillRect(option.rect, br);
+ painter->restore();
+ }
+ QItemDelegate::paint(painter, option, index);
+
+
+ const QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &option));
+ const QPen oldPen = painter->pen();
+ painter->setPen(QPen(color));
+
+ painter->drawLine(option.rect.right(), option.rect.y(),
+ option.rect.right(), option.rect.bottom());
+ painter->drawLine(option.rect.x(), option.rect.bottom(),
+ option.rect.right(), option.rect.bottom());
+ painter->setPen(oldPen);
+}
+
+QSize ColorDelegate::sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const
+{
+ return QItemDelegate::sizeHint(opt, index) + QSize(4, 4);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/paletteeditor.h b/src/designer/src/components/propertyeditor/paletteeditor.h
new file mode 100644
index 000000000..9caed1965
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/paletteeditor.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PALETTEEDITOR_H
+#define PALETTEEDITOR_H
+
+#include "ui_paletteeditor.h"
+#include <QtGui/QItemDelegate>
+
+QT_BEGIN_NAMESPACE
+
+class QListView;
+class QLabel;
+class QtColorButton;
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class PaletteEditor: public QDialog
+{
+ Q_OBJECT
+public:
+ virtual ~PaletteEditor();
+
+ static QPalette getPalette(QDesignerFormEditorInterface *core,
+ QWidget* parent, const QPalette &init = QPalette(),
+ const QPalette &parentPal = QPalette(), int *result = 0);
+
+ QPalette palette() const;
+ void setPalette(const QPalette &palette);
+ void setPalette(const QPalette &palette, const QPalette &parentPalette);
+
+private slots:
+
+ void on_buildButton_colorChanged(const QColor &);
+ void on_activeRadio_clicked();
+ void on_inactiveRadio_clicked();
+ void on_disabledRadio_clicked();
+ void on_computeRadio_clicked();
+ void on_detailsRadio_clicked();
+
+ void paletteChanged(const QPalette &palette);
+
+protected:
+
+private:
+ PaletteEditor(QDesignerFormEditorInterface *core, QWidget *parent);
+ void buildPalette();
+
+ void updatePreviewPalette();
+ void updateStyledButton();
+
+ QPalette::ColorGroup currentColorGroup() const
+ { return m_currentColorGroup; }
+
+ Ui::PaletteEditor ui;
+ QPalette m_editPalette;
+ QPalette m_parentPalette;
+ QPalette::ColorGroup m_currentColorGroup;
+ class PaletteModel *m_paletteModel;
+ bool m_modelUpdated;
+ bool m_paletteUpdated;
+ bool m_compute;
+ QDesignerFormEditorInterface *m_core;
+};
+
+
+class PaletteModel : public QAbstractTableModel
+{
+ Q_OBJECT
+ Q_PROPERTY(QPalette::ColorRole colorRole READ colorRole)
+public:
+ explicit PaletteModel(QObject *parent = 0);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+
+ QPalette getPalette() const;
+ void setPalette(const QPalette &palette, const QPalette &parentPalette);
+
+ QPalette::ColorRole colorRole() const { return QPalette::NoRole; }
+ void setCompute(bool on) { m_compute = on; }
+signals:
+ void paletteChanged(const QPalette &palette);
+private:
+
+ QPalette::ColorGroup columnToGroup(int index) const;
+ int groupToColumn(QPalette::ColorGroup group) const;
+
+ QPalette m_palette;
+ QPalette m_parentPalette;
+ QMap<QPalette::ColorRole, QString> m_roleNames;
+ bool m_compute;
+};
+
+class BrushEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit BrushEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+
+ void setBrush(const QBrush &brush);
+ QBrush brush() const;
+ bool changed() const;
+signals:
+ void changed(QWidget *widget);
+private slots:
+ void brushChanged();
+private:
+ QtColorButton *m_button;
+ bool m_changed;
+ QDesignerFormEditorInterface *m_core;
+};
+
+class RoleEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit RoleEditor(QWidget *parent = 0);
+
+ void setLabel(const QString &label);
+ void setEdited(bool on);
+ bool edited() const;
+signals:
+ void changed(QWidget *widget);
+private slots:
+ void emitResetProperty();
+private:
+ QLabel *m_label;
+ bool m_edited;
+};
+
+class ColorDelegate : public QItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit ColorDelegate(QDesignerFormEditorInterface *core, QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ void setEditorData(QWidget *ed, const QModelIndex &index) const;
+ void setModelData(QWidget *ed, QAbstractItemModel *model,
+ const QModelIndex &index) const;
+
+ void updateEditorGeometry(QWidget *ed,
+ const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ virtual void paint(QPainter *painter, const QStyleOptionViewItem &opt,
+ const QModelIndex &index) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const;
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // PALETTEEDITOR_H
diff --git a/src/designer/src/components/propertyeditor/paletteeditor.ui b/src/designer/src/components/propertyeditor/paletteeditor.ui
new file mode 100644
index 000000000..12d27127b
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/paletteeditor.ui
@@ -0,0 +1,264 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::PaletteEditor</class>
+ <widget class="QDialog" name="qdesigner_internal::PaletteEditor" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>365</width>
+ <height>409</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Edit Palette</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="advancedBox" >
+ <property name="minimumSize" >
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="title" >
+ <string>Tune Palette</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="1" >
+ <widget class="QtColorButton" name="buildButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>13</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="4" >
+ <widget class="QTreeView" name="paletteView" >
+ <property name="minimumSize" >
+ <size>
+ <width>0</width>
+ <height>200</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QRadioButton" name="detailsRadio" >
+ <property name="text" >
+ <string>Show Details</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QRadioButton" name="computeRadio" >
+ <property name="text" >
+ <string>Compute Details</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Quick</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="GroupBox126" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Preview</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="2" >
+ <widget class="QRadioButton" name="disabledRadio" >
+ <property name="text" >
+ <string>Disabled</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QRadioButton" name="inactiveRadio" >
+ <property name="text" >
+ <string>Inactive</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QRadioButton" name="activeRadio" >
+ <property name="text" >
+ <string>Active</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="qdesigner_internal::PreviewFrame" native="1" name="previewFrame" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtColorButton</class>
+ <extends>QToolButton</extends>
+ <header>qtcolorbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>qdesigner_internal::PreviewFrame</class>
+ <extends>QWidget</extends>
+ <header>previewframe.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>qdesigner_internal::PaletteEditor</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>180</x>
+ <y>331</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>134</x>
+ <y>341</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>qdesigner_internal::PaletteEditor</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>287</x>
+ <y>329</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>302</x>
+ <y>342</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/components/propertyeditor/paletteeditorbutton.cpp b/src/designer/src/components/propertyeditor/paletteeditorbutton.cpp
new file mode 100644
index 000000000..b716de1e1
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/paletteeditorbutton.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "paletteeditorbutton.h"
+#include "paletteeditor.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+PaletteEditorButton::PaletteEditorButton(QDesignerFormEditorInterface *core, const QPalette &palette, QWidget *parent)
+ : QToolButton(parent),
+ m_palette(palette)
+{
+ m_core = core;
+ setFocusPolicy(Qt::NoFocus);
+ setText(tr("Change Palette"));
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+
+ connect(this, SIGNAL(clicked()), this, SLOT(showPaletteEditor()));
+}
+
+PaletteEditorButton::~PaletteEditorButton()
+{
+}
+
+void PaletteEditorButton::setPalette(const QPalette &palette)
+{
+ m_palette = palette;
+}
+
+void PaletteEditorButton::setSuperPalette(const QPalette &palette)
+{
+ m_superPalette = palette;
+}
+
+void PaletteEditorButton::showPaletteEditor()
+{
+ int result;
+ QPalette p = QPalette();
+ QPalette pal = PaletteEditor::getPalette(m_core, 0, m_palette, m_superPalette, &result);
+ if (result == QDialog::Accepted) {
+ m_palette = pal;
+ emit paletteChanged(m_palette);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/paletteeditorbutton.h b/src/designer/src/components/propertyeditor/paletteeditorbutton.h
new file mode 100644
index 000000000..567605a19
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/paletteeditorbutton.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PALETTEEDITORBUTTON_H
+#define PALETTEEDITORBUTTON_H
+
+#include "propertyeditor_global.h"
+
+#include <QtGui/QPalette>
+#include <QtGui/QToolButton>
+
+#include "abstractformeditor.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QT_PROPERTYEDITOR_EXPORT PaletteEditorButton: public QToolButton
+{
+ Q_OBJECT
+public:
+ PaletteEditorButton(QDesignerFormEditorInterface *core, const QPalette &palette, QWidget *parent = 0);
+ virtual ~PaletteEditorButton();
+
+ void setSuperPalette(const QPalette &palette);
+ inline QPalette palette() const
+ { return m_palette; }
+
+signals:
+ void paletteChanged(const QPalette &palette);
+
+public slots:
+ void setPalette(const QPalette &palette);
+
+private slots:
+ void showPaletteEditor();
+
+private:
+ QPalette m_palette;
+ QPalette m_superPalette;
+ QDesignerFormEditorInterface *m_core;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // PALETTEEDITORBUTTON_H
diff --git a/src/designer/src/components/propertyeditor/previewframe.cpp b/src/designer/src/components/propertyeditor/previewframe.cpp
new file mode 100644
index 000000000..5e426c9c7
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/previewframe.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "previewframe.h"
+#include "previewwidget.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtGui/QPainter>
+#include <QtGui/QMdiArea>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QPaintEvent>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+ class PreviewMdiArea: public QMdiArea {
+ public:
+ PreviewMdiArea(QWidget *parent = 0) : QMdiArea(parent) {}
+ protected:
+ bool viewportEvent ( QEvent * event );
+ };
+
+ bool PreviewMdiArea::viewportEvent (QEvent * event) {
+ if (event->type() != QEvent::Paint)
+ return QMdiArea::viewportEvent (event);
+ QWidget *paintWidget = viewport();
+ QPainter p(paintWidget);
+ p.fillRect(rect(), paintWidget->palette().color(backgroundRole()).dark());
+ p.setPen(QPen(Qt::white));
+ //: Palette editor background
+ p.drawText(0, height() / 2, width(), height(), Qt::AlignHCenter,
+ QCoreApplication::translate("qdesigner_internal::PreviewMdiArea", "The moose in the noose\nate the goose who was loose."));
+ return true;
+ }
+
+PreviewFrame::PreviewFrame(QWidget *parent) :
+ QFrame(parent),
+ m_mdiArea(new PreviewMdiArea(this))
+{
+ m_mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ m_mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ setLineWidth(1);
+
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ vbox->setMargin(0);
+ vbox->addWidget(m_mdiArea);
+
+ setMinimumSize(ensureMdiSubWindow()->minimumSizeHint());
+}
+
+void PreviewFrame::setPreviewPalette(const QPalette &pal)
+{
+ ensureMdiSubWindow()->widget()->setPalette(pal);
+}
+
+void PreviewFrame::setSubWindowActive(bool active)
+{
+ m_mdiArea->setActiveSubWindow (active ? ensureMdiSubWindow() : static_cast<QMdiSubWindow *>(0));
+}
+
+QMdiSubWindow *PreviewFrame::ensureMdiSubWindow()
+{
+ if (!m_mdiSubWindow) {
+ PreviewWidget *previewWidget = new PreviewWidget(m_mdiArea);
+ m_mdiSubWindow = m_mdiArea->addSubWindow(previewWidget, Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
+ m_mdiSubWindow->move(10,10);
+ m_mdiSubWindow->showMaximized();
+ }
+
+ const Qt::WindowStates state = m_mdiSubWindow->windowState();
+ if (state & Qt::WindowMinimized)
+ m_mdiSubWindow->setWindowState(state & ~Qt::WindowMinimized);
+
+ return m_mdiSubWindow;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/previewframe.h b/src/designer/src/components/propertyeditor/previewframe.h
new file mode 100644
index 000000000..567fd7f7a
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/previewframe.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREVIEWFRAME_H
+#define PREVIEWFRAME_H
+
+#include <QtGui/QFrame>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QMdiArea;
+class QMdiSubWindow;
+
+namespace qdesigner_internal {
+
+class PreviewFrame: public QFrame
+{
+ Q_OBJECT
+public:
+ explicit PreviewFrame(QWidget *parent);
+
+ void setPreviewPalette(const QPalette &palette);
+ void setSubWindowActive(bool active);
+
+private:
+ // The user can on some platforms close the mdi child by invoking the system menu.
+ // Ensure a child is present.
+ QMdiSubWindow *ensureMdiSubWindow();
+ QMdiArea *m_mdiArea;
+ QPointer<QMdiSubWindow> m_mdiSubWindow;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/components/propertyeditor/previewwidget.cpp b/src/designer/src/components/propertyeditor/previewwidget.cpp
new file mode 100644
index 000000000..8dec3ffff
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/previewwidget.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "previewwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+PreviewWidget::PreviewWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ ui.setupUi(this);
+}
+
+PreviewWidget::~PreviewWidget()
+{
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/previewwidget.h b/src/designer/src/components/propertyeditor/previewwidget.h
new file mode 100644
index 000000000..4b014db8a
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/previewwidget.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREVIEWWIDGET_H
+#define PREVIEWWIDGET_H
+
+#include "ui_previewwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class PreviewWidget: public QWidget
+{
+ Q_OBJECT
+public:
+ explicit PreviewWidget(QWidget *parent);
+ virtual ~PreviewWidget();
+
+private:
+ Ui::PreviewWidget ui;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // PREVIEWWIDGET_H
diff --git a/src/designer/src/components/propertyeditor/previewwidget.ui b/src/designer/src/components/propertyeditor/previewwidget.ui
new file mode 100644
index 000000000..a5f2a1eee
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/previewwidget.ui
@@ -0,0 +1,238 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::PreviewWidget</class>
+ <widget class="QWidget" name="qdesigner_internal::PreviewWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>471</width>
+ <height>251</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Preview Window</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item rowspan="3" row="0" column="1" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="LineEdit1" >
+ <property name="text" >
+ <string>LineEdit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="ComboBox1" >
+ <item>
+ <property name="text" >
+ <string>ComboBox</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="SpinBox1" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="PushButton1" >
+ <property name="text" >
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QScrollBar" name="ScrollBar1" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="Slider1" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget" >
+ <property name="maximumSize" >
+ <size>
+ <width>32767</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QProgressBar" name="ProgressBar1" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QGroupBox" name="ButtonGroup2" >
+ <property name="title" >
+ <string>ButtonGroup2</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="CheckBox1" >
+ <property name="text" >
+ <string>CheckBox1</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="CheckBox2" >
+ <property name="text" >
+ <string>CheckBox2</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="ButtonGroup1" >
+ <property name="title" >
+ <string>ButtonGroup</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="RadioButton1" >
+ <property name="text" >
+ <string>RadioButton1</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="RadioButton2" >
+ <property name="text" >
+ <string>RadioButton2</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="RadioButton3" >
+ <property name="text" >
+ <string>RadioButton3</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/components/propertyeditor/propertyeditor.cpp b/src/designer/src/components/propertyeditor/propertyeditor.cpp
new file mode 100644
index 000000000..9f298d0a4
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/propertyeditor.cpp
@@ -0,0 +1,1294 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "propertyeditor.h"
+
+#include "qttreepropertybrowser.h"
+#include "qtbuttonpropertybrowser.h"
+#include "qtvariantproperty.h"
+#include "designerpropertymanager.h"
+#include "qdesigner_propertysheet_p.h"
+#include "formwindowbase_p.h"
+#include "filterwidget_p.h" // For FilterWidget
+
+#include "newdynamicpropertydialog.h"
+#include "dynamicpropertysheet.h"
+#include "shared_enums_p.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/private/abstractsettings_p.h>
+// shared
+#include <qdesigner_utils_p.h>
+#include <qdesigner_propertycommand_p.h>
+#include <metadatabase_p.h>
+#include <iconloader_p.h>
+#ifdef Q_OS_WIN
+# include <widgetfactory_p.h>
+#endif
+#include <QtGui/QAction>
+#include <QtGui/QLineEdit>
+#include <QtGui/QMenu>
+#include <QtGui/QApplication>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QScrollArea>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QToolBar>
+#include <QtGui/QToolButton>
+#include <QtGui/QActionGroup>
+#include <QtGui/QLabel>
+#include <QtGui/QPainter>
+
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+
+static const char *SettingsGroupC = "PropertyEditor";
+#if QT_VERSION >= 0x040500
+static const char *ViewKeyC = "View";
+#endif
+static const char *ColorKeyC = "Colored";
+static const char *SortedKeyC = "Sorted";
+static const char *ExpansionKeyC = "ExpandedItems";
+static const char *SplitterPositionKeyC = "SplitterPosition";
+
+enum SettingsView { TreeView, ButtonView };
+
+QT_BEGIN_NAMESPACE
+
+// ---------------------------------------------------------------------------------
+
+namespace qdesigner_internal {
+
+// ----------- ElidingLabel
+// QLabel does not support text eliding so we need a helper class
+
+class ElidingLabel : public QWidget
+{
+public:
+ ElidingLabel(const QString &text = QString(), QWidget *parent = 0)
+ : QWidget(parent),
+ m_text(text),
+ m_mode(Qt::ElideRight) {
+ setContentsMargins(3, 2, 3, 2);
+ }
+ QSize sizeHint() const;
+ void paintEvent(QPaintEvent *e);
+ void setText(const QString &text) {
+ m_text = text;
+ updateGeometry();
+ }
+ void setElidemode(Qt::TextElideMode mode) {
+ m_mode = mode;
+ updateGeometry();
+ }
+private:
+ QString m_text;
+ Qt::TextElideMode m_mode;
+};
+
+QSize ElidingLabel::sizeHint() const
+{
+ QSize size = fontMetrics().boundingRect(m_text).size();
+ size += QSize(contentsMargins().left() + contentsMargins().right(),
+ contentsMargins().top() + contentsMargins().bottom());
+ return size;
+}
+
+void ElidingLabel::paintEvent(QPaintEvent *) {
+ QPainter painter(this);
+ painter.setPen(QColor(0, 0, 0, 60));
+ painter.setBrush(QColor(255, 255, 255, 40));
+ painter.drawRect(rect().adjusted(0, 0, -1, -1));
+ painter.setPen(palette().windowText().color());
+ painter.drawText(contentsRect(), Qt::AlignLeft,
+ fontMetrics().elidedText(m_text, Qt::ElideRight, width(), 0));
+}
+
+
+// ----------- PropertyEditor::Strings
+
+PropertyEditor::Strings::Strings() :
+ m_fontProperty(QLatin1String("font")),
+ m_qLayoutWidget(QLatin1String("QLayoutWidget")),
+ m_designerPrefix(QLatin1String("QDesigner")),
+ m_layout(QLatin1String("Layout")),
+ m_validationModeAttribute(QLatin1String("validationMode")),
+ m_fontAttribute(QLatin1String("font")),
+ m_superPaletteAttribute(QLatin1String("superPalette")),
+ m_enumNamesAttribute(QLatin1String("enumNames")),
+ m_resettableAttribute(QLatin1String("resettable")),
+ m_flagsAttribute(QLatin1String("flags"))
+{
+ m_alignmentProperties.insert(QLatin1String("alignment"));
+ m_alignmentProperties.insert(QLatin1String("layoutLabelAlignment")); // QFormLayout
+ m_alignmentProperties.insert(QLatin1String("layoutFormAlignment"));
+}
+
+// ----------- PropertyEditor
+
+QDesignerMetaDataBaseItemInterface* PropertyEditor::metaDataBaseItem() const
+{
+ QObject *o = object();
+ if (!o)
+ return 0;
+ QDesignerMetaDataBaseInterface *db = core()->metaDataBase();
+ if (!db)
+ return 0;
+ return db->item(o);
+}
+
+void PropertyEditor::setupStringProperty(QtVariantProperty *property, bool isMainContainer)
+{
+ const StringPropertyParameters params = textPropertyValidationMode(core(), m_object, property->propertyName(), isMainContainer);
+ // Does a meta DB entry exist - add comment
+ const bool hasComment = params.second;
+ property->setAttribute(m_strings.m_validationModeAttribute, params.first);
+ // assuming comment cannot appear or disappear for the same property in different object instance
+ if (!hasComment)
+ qDeleteAll(property->subProperties());
+}
+
+void PropertyEditor::setupPaletteProperty(QtVariantProperty *property)
+{
+ QPalette value = qvariant_cast<QPalette>(property->value());
+ QPalette superPalette = QPalette();
+ QWidget *currentWidget = qobject_cast<QWidget *>(m_object);
+ if (currentWidget) {
+ if (currentWidget->isWindow())
+ superPalette = QApplication::palette(currentWidget);
+ else {
+ if (currentWidget->parentWidget())
+ superPalette = currentWidget->parentWidget()->palette();
+ }
+ }
+ m_updatingBrowser = true;
+ property->setAttribute(m_strings.m_superPaletteAttribute, superPalette);
+ m_updatingBrowser = false;
+}
+
+static inline QToolButton *createDropDownButton(QAction *defaultAction, QWidget *parent = 0)
+{
+ QToolButton *rc = new QToolButton(parent);
+ rc->setDefaultAction(defaultAction);
+ rc->setPopupMode(QToolButton::InstantPopup);
+ return rc;
+}
+
+PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags) :
+ QDesignerPropertyEditor(parent, flags),
+ m_core(core),
+ m_propertySheet(0),
+ m_currentBrowser(0),
+ m_treeBrowser(0),
+ m_propertyManager(new DesignerPropertyManager(m_core, this)),
+ m_dynamicGroup(0),
+ m_updatingBrowser(false),
+ m_stackedWidget(new QStackedWidget),
+ m_filterWidget(new FilterWidget(0, FilterWidget::LayoutAlignNone)),
+ m_buttonIndex(-1),
+ m_treeIndex(-1),
+ m_addDynamicAction(new QAction(createIconSet(QLatin1String("plus.png")), tr("Add Dynamic Property..."), this)),
+ m_removeDynamicAction(new QAction(createIconSet(QLatin1String("minus.png")), tr("Remove Dynamic Property"), this)),
+ m_sortingAction(new QAction(createIconSet(QLatin1String("sort.png")), tr("Sorting"), this)),
+ m_coloringAction(new QAction(createIconSet(QLatin1String("color.png")), tr("Color Groups"), this)),
+ m_treeAction(new QAction(tr("Tree View"), this)),
+ m_buttonAction(new QAction(tr("Drop Down Button View"), this)),
+ m_classLabel(new ElidingLabel),
+ m_sorting(false),
+ m_coloring(false),
+ m_brightness(false)
+{
+ QVector<QColor> colors;
+ colors.reserve(6);
+ colors.push_back(QColor(255, 230, 191));
+ colors.push_back(QColor(255, 255, 191));
+ colors.push_back(QColor(191, 255, 191));
+ colors.push_back(QColor(199, 255, 255));
+ colors.push_back(QColor(234, 191, 255));
+ colors.push_back(QColor(255, 191, 239));
+ m_colors.reserve(colors.count());
+ const int darknessFactor = 250;
+ for (int i = 0; i < colors.count(); i++) {
+ QColor c = colors.at(i);
+ m_colors.push_back(qMakePair(c, c.darker(darknessFactor)));
+ }
+ QColor dynamicColor(191, 207, 255);
+ QColor layoutColor(255, 191, 191);
+ m_dynamicColor = qMakePair(dynamicColor, dynamicColor.darker(darknessFactor));
+ m_layoutColor = qMakePair(layoutColor, layoutColor.darker(darknessFactor));
+
+ updateForegroundBrightness();
+
+ QActionGroup *actionGroup = new QActionGroup(this);
+
+ m_treeAction->setCheckable(true);
+ m_treeAction->setIcon(createIconSet(QLatin1String("widgets/listview.png")));
+ m_buttonAction->setCheckable(true);
+ m_buttonAction->setIcon(createIconSet(QLatin1String("dropdownbutton.png")));
+
+ actionGroup->addAction(m_treeAction);
+ actionGroup->addAction(m_buttonAction);
+ connect(actionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotViewTriggered(QAction*)));
+
+ // Add actions
+ QActionGroup *addDynamicActionGroup = new QActionGroup(this);
+ connect(addDynamicActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotAddDynamicProperty(QAction*)));
+
+ QMenu *addDynamicActionMenu = new QMenu(this);
+ m_addDynamicAction->setMenu(addDynamicActionMenu);
+ m_addDynamicAction->setEnabled(false);
+ QAction *addDynamicAction = addDynamicActionGroup->addAction(tr("String..."));
+ addDynamicAction->setData(static_cast<int>(QVariant::String));
+ addDynamicActionMenu->addAction(addDynamicAction);
+ addDynamicAction = addDynamicActionGroup->addAction(tr("Bool..."));
+ addDynamicAction->setData(static_cast<int>(QVariant::Bool));
+ addDynamicActionMenu->addAction(addDynamicAction);
+ addDynamicActionMenu->addSeparator();
+ addDynamicAction = addDynamicActionGroup->addAction(tr("Other..."));
+ addDynamicAction->setData(static_cast<int>(QVariant::Invalid));
+ addDynamicActionMenu->addAction(addDynamicAction);
+ // remove
+ m_removeDynamicAction->setEnabled(false);
+ connect(m_removeDynamicAction, SIGNAL(triggered()), this, SLOT(slotRemoveDynamicProperty()));
+ // Configure
+ QAction *configureAction = new QAction(tr("Configure Property Editor"), this);
+ configureAction->setIcon(createIconSet(QLatin1String("configure.png")));
+ QMenu *configureMenu = new QMenu(this);
+ configureAction->setMenu(configureMenu);
+
+ m_sortingAction->setCheckable(true);
+ connect(m_sortingAction, SIGNAL(toggled(bool)), this, SLOT(slotSorting(bool)));
+
+ m_coloringAction->setCheckable(true);
+ connect(m_coloringAction, SIGNAL(toggled(bool)), this, SLOT(slotColoring(bool)));
+
+ configureMenu->addAction(m_sortingAction);
+ configureMenu->addAction(m_coloringAction);
+#if QT_VERSION >= 0x04FF00
+ configureMenu->addSeparator();
+ configureMenu->addAction(m_treeAction);
+ configureMenu->addAction(m_buttonAction);
+#endif
+ // Assemble toolbar
+ QToolBar *toolBar = new QToolBar;
+ toolBar->addWidget(m_filterWidget);
+ toolBar->addWidget(createDropDownButton(m_addDynamicAction));
+ toolBar->addAction(m_removeDynamicAction);
+ toolBar->addWidget(createDropDownButton(configureAction));
+ // Views
+ QScrollArea *buttonScroll = new QScrollArea(m_stackedWidget);
+ m_buttonBrowser = new QtButtonPropertyBrowser(buttonScroll);
+ buttonScroll->setWidgetResizable(true);
+ buttonScroll->setWidget(m_buttonBrowser);
+ m_buttonIndex = m_stackedWidget->addWidget(buttonScroll);
+ connect(m_buttonBrowser, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentItemChanged(QtBrowserItem*)));
+
+ m_treeBrowser = new QtTreePropertyBrowser(m_stackedWidget);
+ m_treeBrowser->setRootIsDecorated(false);
+ m_treeBrowser->setPropertiesWithoutValueMarked(true);
+ m_treeBrowser->setResizeMode(QtTreePropertyBrowser::Interactive);
+ m_treeIndex = m_stackedWidget->addWidget(m_treeBrowser);
+ connect(m_treeBrowser, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentItemChanged(QtBrowserItem*)));
+ connect(m_filterWidget, SIGNAL(filterChanged(QString)), this, SLOT(setFilter(QString)));
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addWidget(toolBar);
+ layout->addWidget(m_classLabel);
+ layout->addSpacerItem(new QSpacerItem(0,1));
+ layout->addWidget(m_stackedWidget);
+ layout->setMargin(0);
+ layout->setSpacing(0);
+
+ m_treeFactory = new DesignerEditorFactory(m_core, this);
+ m_treeFactory->setSpacing(0);
+ m_groupFactory = new DesignerEditorFactory(m_core, this);
+ QtVariantPropertyManager *variantManager = m_propertyManager;
+ m_buttonBrowser->setFactoryForManager(variantManager, m_groupFactory);
+ m_treeBrowser->setFactoryForManager(variantManager, m_treeFactory);
+
+ m_stackedWidget->setCurrentIndex(m_treeIndex);
+ m_currentBrowser = m_treeBrowser;
+ m_treeAction->setChecked(true);
+
+ connect(m_groupFactory, SIGNAL(resetProperty(QtProperty*)), this, SLOT(slotResetProperty(QtProperty*)));
+ connect(m_treeFactory, SIGNAL(resetProperty(QtProperty*)), this, SLOT(slotResetProperty(QtProperty*)));
+ connect(variantManager, SIGNAL(valueChanged(QtProperty*,QVariant,bool)), this, SLOT(slotValueChanged(QtProperty*,QVariant,bool)));
+
+ // retrieve initial settings
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->beginGroup(QLatin1String(SettingsGroupC));
+#if QT_VERSION >= 0x040500
+ const SettingsView view = settings->value(QLatin1String(ViewKeyC), TreeView).toInt() == TreeView ? TreeView : ButtonView;
+#endif
+ // Coloring not available unless treeview and not sorted
+ m_sorting = settings->value(QLatin1String(SortedKeyC), false).toBool();
+ m_coloring = settings->value(QLatin1String(ColorKeyC), true).toBool();
+ const QVariantMap expansionState = settings->value(QLatin1String(ExpansionKeyC), QVariantMap()).toMap();
+ const int splitterPosition = settings->value(QLatin1String(SplitterPositionKeyC), 150).toInt();
+ settings->endGroup();
+ // Apply settings
+ m_sortingAction->setChecked(m_sorting);
+ m_coloringAction->setChecked(m_coloring);
+ m_treeBrowser->setSplitterPosition(splitterPosition);
+#if QT_VERSION >= 0x040500
+ switch (view) {
+ case TreeView:
+ m_currentBrowser = m_treeBrowser;
+ m_stackedWidget->setCurrentIndex(m_treeIndex);
+ m_treeAction->setChecked(true);
+ break;
+ case ButtonView:
+ m_currentBrowser = m_buttonBrowser;
+ m_stackedWidget->setCurrentIndex(m_buttonIndex);
+ m_buttonAction->setChecked(true);
+ break;
+ }
+#endif
+ // Restore expansionState from QVariant map
+ if (!expansionState.empty()) {
+ const QVariantMap::const_iterator cend = expansionState.constEnd();
+ for (QVariantMap::const_iterator it = expansionState.constBegin(); it != cend; ++it)
+ m_expansionState.insert(it.key(), it.value().toBool());
+ }
+ updateActionsState();
+}
+
+PropertyEditor::~PropertyEditor()
+{
+ storeExpansionState();
+ saveSettings();
+}
+
+void PropertyEditor::saveSettings() const
+{
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->beginGroup(QLatin1String(SettingsGroupC));
+#if QT_VERSION >= 0x040500
+ settings->setValue(QLatin1String(ViewKeyC), QVariant(m_treeAction->isChecked() ? TreeView : ButtonView));
+#endif
+ settings->setValue(QLatin1String(ColorKeyC), QVariant(m_coloring));
+ settings->setValue(QLatin1String(SortedKeyC), QVariant(m_sorting));
+ // Save last expansionState as QVariant map
+ QVariantMap expansionState;
+ if (!m_expansionState.empty()) {
+ const QMap<QString, bool>::const_iterator cend = m_expansionState.constEnd();
+ for (QMap<QString, bool>::const_iterator it = m_expansionState.constBegin(); it != cend; ++it)
+ expansionState.insert(it.key(), QVariant(it.value()));
+ }
+ settings->setValue(QLatin1String(ExpansionKeyC), expansionState);
+ settings->setValue(QLatin1String(SplitterPositionKeyC), m_treeBrowser->splitterPosition());
+ settings->endGroup();
+}
+
+void PropertyEditor::setExpanded(QtBrowserItem *item, bool expanded)
+{
+ if (m_buttonBrowser == m_currentBrowser)
+ m_buttonBrowser->setExpanded(item, expanded);
+ else if (m_treeBrowser == m_currentBrowser)
+ m_treeBrowser->setExpanded(item, expanded);
+}
+
+bool PropertyEditor::isExpanded(QtBrowserItem *item) const
+{
+ if (m_buttonBrowser == m_currentBrowser)
+ return m_buttonBrowser->isExpanded(item);
+ else if (m_treeBrowser == m_currentBrowser)
+ return m_treeBrowser->isExpanded(item);
+ return false;
+}
+
+void PropertyEditor::setItemVisible(QtBrowserItem *item, bool visible)
+{
+ if (m_currentBrowser == m_treeBrowser) {
+ m_treeBrowser->setItemVisible(item, visible);
+ } else {
+ qWarning("** WARNING %s is not implemented for this browser.", Q_FUNC_INFO);
+ }
+}
+
+bool PropertyEditor::isItemVisible(QtBrowserItem *item) const
+{
+ return m_currentBrowser == m_treeBrowser ? m_treeBrowser->isItemVisible(item) : true;
+}
+
+/* Default handling of items not found in the map:
+ * - Top-level items (classes) are assumed to be expanded
+ * - Anything below (properties) is assumed to be collapsed
+ * That is, the map is required, the state cannot be stored in a set */
+
+void PropertyEditor::storePropertiesExpansionState(const QList<QtBrowserItem *> &items)
+{
+ const QChar bar = QLatin1Char('|');
+ QListIterator<QtBrowserItem *> itProperty(items);
+ while (itProperty.hasNext()) {
+ QtBrowserItem *propertyItem = itProperty.next();
+ if (!propertyItem->children().empty()) {
+ QtProperty *property = propertyItem->property();
+ const QString propertyName = property->propertyName();
+ const QMap<QtProperty *, QString>::const_iterator itGroup = m_propertyToGroup.constFind(property);
+ if (itGroup != m_propertyToGroup.constEnd()) {
+ QString key = itGroup.value();
+ key += bar;
+ key += propertyName;
+ m_expansionState[key] = isExpanded(propertyItem);
+ }
+ }
+ }
+}
+
+void PropertyEditor::storeExpansionState()
+{
+ const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
+ if (m_sorting) {
+ storePropertiesExpansionState(items);
+ } else {
+ QListIterator<QtBrowserItem *> itGroup(items);
+ while (itGroup.hasNext()) {
+ QtBrowserItem *item = itGroup.next();
+ const QString groupName = item->property()->propertyName();
+ QList<QtBrowserItem *> propertyItems = item->children();
+ if (!propertyItems.empty())
+ m_expansionState[groupName] = isExpanded(item);
+
+ // properties stuff here
+ storePropertiesExpansionState(propertyItems);
+ }
+ }
+}
+
+void PropertyEditor::collapseAll()
+{
+ QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
+ QListIterator<QtBrowserItem *> itGroup(items);
+ while (itGroup.hasNext())
+ setExpanded(itGroup.next(), false);
+}
+
+void PropertyEditor::applyPropertiesExpansionState(const QList<QtBrowserItem *> &items)
+{
+ const QChar bar = QLatin1Char('|');
+ QListIterator<QtBrowserItem *> itProperty(items);
+ while (itProperty.hasNext()) {
+ const QMap<QString, bool>::const_iterator excend = m_expansionState.constEnd();
+ QtBrowserItem *propertyItem = itProperty.next();
+ QtProperty *property = propertyItem->property();
+ const QString propertyName = property->propertyName();
+ const QMap<QtProperty *, QString>::const_iterator itGroup = m_propertyToGroup.constFind(property);
+ if (itGroup != m_propertyToGroup.constEnd()) {
+ QString key = itGroup.value();
+ key += bar;
+ key += propertyName;
+ const QMap<QString, bool>::const_iterator pit = m_expansionState.constFind(key);
+ if (pit != excend)
+ setExpanded(propertyItem, pit.value());
+ else
+ setExpanded(propertyItem, false);
+ }
+ }
+}
+
+void PropertyEditor::applyExpansionState()
+{
+ const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
+ if (m_sorting) {
+ applyPropertiesExpansionState(items);
+ } else {
+ QListIterator<QtBrowserItem *> itTopLevel(items);
+ const QMap<QString, bool>::const_iterator excend = m_expansionState.constEnd();
+ while (itTopLevel.hasNext()) {
+ QtBrowserItem *item = itTopLevel.next();
+ const QString groupName = item->property()->propertyName();
+ const QMap<QString, bool>::const_iterator git = m_expansionState.constFind(groupName);
+ if (git != excend)
+ setExpanded(item, git.value());
+ else
+ setExpanded(item, true);
+ // properties stuff here
+ applyPropertiesExpansionState(item->children());
+ }
+ }
+}
+
+int PropertyEditor::applyPropertiesFilter(const QList<QtBrowserItem *> &items)
+{
+ int showCount = 0;
+ const bool matchAll = m_filterPattern.isEmpty();
+ QListIterator<QtBrowserItem *> itProperty(items);
+ while (itProperty.hasNext()) {
+ QtBrowserItem *propertyItem = itProperty.next();
+ QtProperty *property = propertyItem->property();
+ const QString propertyName = property->propertyName();
+ const bool showProperty = matchAll || propertyName.contains(m_filterPattern, Qt::CaseInsensitive);
+ setItemVisible(propertyItem, showProperty);
+ if (showProperty)
+ showCount++;
+ }
+ return showCount;
+}
+
+void PropertyEditor::applyFilter()
+{
+ const QList<QtBrowserItem *> items = m_currentBrowser->topLevelItems();
+ if (m_sorting) {
+ applyPropertiesFilter(items);
+ } else {
+ QListIterator<QtBrowserItem *> itTopLevel(items);
+ while (itTopLevel.hasNext()) {
+ QtBrowserItem *item = itTopLevel.next();
+ setItemVisible(item, applyPropertiesFilter(item->children()));
+ }
+ }
+}
+
+void PropertyEditor::clearView()
+{
+ m_currentBrowser->clear();
+}
+
+bool PropertyEditor::event(QEvent *event)
+{
+ if (event->type() == QEvent::PaletteChange)
+ updateForegroundBrightness();
+
+ return QDesignerPropertyEditor::event(event);
+}
+
+void PropertyEditor::updateForegroundBrightness()
+{
+ QColor c = palette().color(QPalette::Text);
+ bool newBrightness = qRound(0.3 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF());
+
+ if (m_brightness == newBrightness)
+ return;
+
+ m_brightness = newBrightness;
+
+ updateColors();
+}
+
+QColor PropertyEditor::propertyColor(QtProperty *property) const
+{
+ if (!m_coloring)
+ return QColor();
+
+ QtProperty *groupProperty = property;
+
+ QMap<QtProperty *, QString>::ConstIterator itProp = m_propertyToGroup.constFind(property);
+ if (itProp != m_propertyToGroup.constEnd())
+ groupProperty = m_nameToGroup.value(itProp.value());
+
+ const int groupIdx = m_groups.indexOf(groupProperty);
+ QPair<QColor, QColor> pair;
+ if (groupIdx != -1) {
+ if (groupProperty == m_dynamicGroup)
+ pair = m_dynamicColor;
+ else if (isLayoutGroup(groupProperty))
+ pair = m_layoutColor;
+ else
+ pair = m_colors[groupIdx % m_colors.count()];
+ }
+ if (!m_brightness)
+ return pair.first;
+ return pair.second;
+}
+
+void PropertyEditor::fillView()
+{
+ if (m_sorting) {
+ QMapIterator<QString, QtVariantProperty *> itProperty(m_nameToProperty);
+ while (itProperty.hasNext()) {
+ QtVariantProperty *property = itProperty.next().value();
+ m_currentBrowser->addProperty(property);
+ }
+ } else {
+ QListIterator<QtProperty *> itGroup(m_groups);
+ while (itGroup.hasNext()) {
+ QtProperty *group = itGroup.next();
+ QtBrowserItem *item = m_currentBrowser->addProperty(group);
+ if (m_currentBrowser == m_treeBrowser)
+ m_treeBrowser->setBackgroundColor(item, propertyColor(group));
+ group->setModified(m_currentBrowser == m_treeBrowser);
+ }
+ }
+}
+
+bool PropertyEditor::isLayoutGroup(QtProperty *group) const
+{
+ return group->propertyName() == m_strings.m_layout;
+}
+
+void PropertyEditor::updateActionsState()
+{
+ m_coloringAction->setEnabled(m_treeAction->isChecked() && !m_sortingAction->isChecked());
+}
+
+void PropertyEditor::slotViewTriggered(QAction *action)
+{
+ storeExpansionState();
+ collapseAll();
+ {
+ UpdateBlocker ub(this);
+ clearView();
+ int idx = 0;
+ if (action == m_treeAction) {
+ m_currentBrowser = m_treeBrowser;
+ idx = m_treeIndex;
+ } else if (action == m_buttonAction) {
+ m_currentBrowser = m_buttonBrowser;
+ idx = m_buttonIndex;
+ }
+ fillView();
+ m_stackedWidget->setCurrentIndex(idx);
+ applyExpansionState();
+ applyFilter();
+ }
+ updateActionsState();
+}
+
+void PropertyEditor::slotSorting(bool sort)
+{
+ if (sort == m_sorting)
+ return;
+
+ storeExpansionState();
+ m_sorting = sort;
+ collapseAll();
+ {
+ UpdateBlocker ub(this);
+ clearView();
+ m_treeBrowser->setRootIsDecorated(sort);
+ fillView();
+ applyExpansionState();
+ applyFilter();
+ }
+ updateActionsState();
+}
+
+void PropertyEditor::updateColors()
+{
+ if (m_treeBrowser && m_currentBrowser == m_treeBrowser) {
+ QList<QtBrowserItem *> items = m_treeBrowser->topLevelItems();
+ QListIterator<QtBrowserItem *> itItem(items);
+ while (itItem.hasNext()) {
+ QtBrowserItem *item = itItem.next();
+ m_treeBrowser->setBackgroundColor(item, propertyColor(item->property()));
+ }
+ }
+}
+
+void PropertyEditor::slotColoring(bool coloring)
+{
+ if (coloring == m_coloring)
+ return;
+
+ m_coloring = coloring;
+
+ updateColors();
+}
+
+void PropertyEditor::slotAddDynamicProperty(QAction *action)
+{
+ if (!m_propertySheet)
+ return;
+
+ const QDesignerDynamicPropertySheetExtension *dynamicSheet =
+ qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);
+
+ if (!dynamicSheet)
+ return;
+
+ QString newName;
+ QVariant newValue;
+ { // Make sure the dialog is closed before the signal is emitted.
+ const QVariant::Type type = static_cast<QVariant::Type>(action->data().toInt());
+ NewDynamicPropertyDialog dlg(core()->dialogGui(), m_currentBrowser);
+ if (type != QVariant::Invalid)
+ dlg.setPropertyType(type);
+
+ QStringList reservedNames;
+ const int propertyCount = m_propertySheet->count();
+ for (int i = 0; i < propertyCount; i++) {
+ if (!dynamicSheet->isDynamicProperty(i) || m_propertySheet->isVisible(i))
+ reservedNames.append(m_propertySheet->propertyName(i));
+ }
+ dlg.setReservedNames(reservedNames);
+ if (dlg.exec() == QDialog::Rejected)
+ return;
+ newName = dlg.propertyName();
+ newValue = dlg.propertyValue();
+ }
+ m_recentlyAddedDynamicProperty = newName;
+ emit addDynamicProperty(newName, newValue);
+}
+
+QDesignerFormEditorInterface *PropertyEditor::core() const
+{
+ return m_core;
+}
+
+bool PropertyEditor::isReadOnly() const
+{
+ return false;
+}
+
+void PropertyEditor::setReadOnly(bool /*readOnly*/)
+{
+ qDebug() << "PropertyEditor::setReadOnly() request";
+}
+
+void PropertyEditor::setPropertyValue(const QString &name, const QVariant &value, bool changed)
+{
+ const QMap<QString, QtVariantProperty*>::const_iterator it = m_nameToProperty.constFind(name);
+ if (it == m_nameToProperty.constEnd())
+ return;
+ QtVariantProperty *property = it.value();
+ updateBrowserValue(property, value);
+ property->setModified(changed);
+}
+
+/* Quick update that assumes the actual count of properties has not changed
+ * N/A when for example executing a layout command and margin properties appear. */
+void PropertyEditor::updatePropertySheet()
+{
+ if (!m_propertySheet)
+ return;
+
+ updateToolBarLabel();
+
+ const int propertyCount = m_propertySheet->count();
+ const QMap<QString, QtVariantProperty*>::const_iterator npcend = m_nameToProperty.constEnd();
+ for (int i = 0; i < propertyCount; ++i) {
+ const QString propertyName = m_propertySheet->propertyName(i);
+ QMap<QString, QtVariantProperty*>::const_iterator it = m_nameToProperty.constFind(propertyName);
+ if (it != npcend)
+ updateBrowserValue(it.value(), m_propertySheet->property(i));
+ }
+}
+
+static inline QLayout *layoutOfQLayoutWidget(QObject *o)
+{
+ if (o->isWidgetType() && !qstrcmp(o->metaObject()->className(), "QLayoutWidget"))
+ return static_cast<QWidget*>(o)->layout();
+ return 0;
+}
+
+void PropertyEditor::updateToolBarLabel()
+{
+ QString objectName;
+ QString className;
+ if (m_object) {
+ if (QLayout *l = layoutOfQLayoutWidget(m_object))
+ objectName = l->objectName();
+ else
+ objectName = m_object->objectName();
+ className = realClassName(m_object);
+ }
+
+ m_classLabel->setVisible(!objectName.isEmpty() || !className.isEmpty());
+ m_classLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ QString classLabelText;
+ if (!objectName.isEmpty())
+ classLabelText += objectName + QLatin1String(" : ");
+ classLabelText += className;
+
+ m_classLabel->setText(classLabelText);
+ m_classLabel->setToolTip(tr("Object: %1\nClass: %2").arg(objectName).arg(className));
+}
+
+void PropertyEditor::updateBrowserValue(QtVariantProperty *property, const QVariant &value)
+{
+ QVariant v = value;
+ const int type = property->propertyType();
+ if (type == QtVariantPropertyManager::enumTypeId()) {
+ const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(v);
+ v = e.metaEnum.keys().indexOf(e.metaEnum.valueToKey(e.value));
+ } else if (type == DesignerPropertyManager::designerFlagTypeId()) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(v);
+ v = QVariant(f.value);
+ } else if (type == DesignerPropertyManager::designerAlignmentTypeId()) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(v);
+ v = QVariant(f.value);
+ }
+ QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));
+ int index = -1;
+ if (sheet)
+ index = sheet->indexOf(property->propertyName());
+ if (sheet && m_propertyToGroup.contains(property)) { // don't do it for comments since property sheet doesn't keep them
+ property->setEnabled(sheet->isEnabled(index));
+ }
+
+ // Rich text string property with comment: Store/Update the font the rich text editor dialog starts out with
+ if (type == QVariant::String && !property->subProperties().empty()) {
+ const int fontIndex = m_propertySheet->indexOf(m_strings.m_fontProperty);
+ if (fontIndex != -1)
+ property->setAttribute(m_strings.m_fontAttribute, m_propertySheet->property(fontIndex));
+ }
+
+ m_updatingBrowser = true;
+ property->setValue(v);
+ if (sheet && sheet->isResourceProperty(index))
+ property->setAttribute(QLatin1String("defaultResource"), sheet->defaultResourceProperty(index));
+ m_updatingBrowser = false;
+}
+
+int PropertyEditor::toBrowserType(const QVariant &value, const QString &propertyName) const
+{
+ if (value.canConvert<PropertySheetFlagValue>()) {
+ if (m_strings.m_alignmentProperties.contains(propertyName))
+ return DesignerPropertyManager::designerAlignmentTypeId();
+ return DesignerPropertyManager::designerFlagTypeId();
+ }
+ if (value.canConvert<PropertySheetEnumValue>())
+ return DesignerPropertyManager::enumTypeId();
+
+ return value.userType();
+}
+
+QString PropertyEditor::realClassName(QObject *object) const
+{
+ if (!object)
+ return QString();
+
+ QString className = QLatin1String(object->metaObject()->className());
+ const QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
+ if (QDesignerWidgetDataBaseItemInterface *widgetItem = db->item(db->indexOfObject(object, true))) {
+ className = widgetItem->name();
+
+ if (object->isWidgetType() && className == m_strings.m_qLayoutWidget
+ && static_cast<QWidget*>(object)->layout()) {
+ className = QLatin1String(static_cast<QWidget*>(object)->layout()->metaObject()->className());
+ }
+ }
+
+ if (className.startsWith(m_strings.m_designerPrefix))
+ className.remove(1, m_strings.m_designerPrefix.size() - 1);
+
+ return className;
+}
+
+static QString msgUnsupportedType(const QString &propertyName, unsigned type)
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << "The property \"" << propertyName << "\" of type " << type;
+ if (type == QVariant::Invalid) {
+ str << " (invalid) ";
+ } else {
+ if (type < QVariant::UserType) {
+ if (const char *typeName = QVariant::typeToName(static_cast<QVariant::Type>(type)))
+ str << " (" << typeName << ") ";
+ } else {
+ str << " (user type) ";
+ }
+ }
+ str << " is not supported yet!";
+ return rc;
+}
+
+void PropertyEditor::setObject(QObject *object)
+{
+ QDesignerFormWindowInterface *oldFormWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
+ // In the first setObject() call following the addition of a dynamic property, focus and edit it.
+ const bool editNewDynamicProperty = object != 0 && m_object == object && !m_recentlyAddedDynamicProperty.isEmpty();
+ m_object = object;
+ m_propertyManager->setObject(object);
+ QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
+ FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
+ m_treeFactory->setFormWindowBase(fwb);
+ m_groupFactory->setFormWindowBase(fwb);
+
+ storeExpansionState();
+
+ UpdateBlocker ub(this);
+
+ updateToolBarLabel();
+
+ QMap<QString, QtVariantProperty *> toRemove = m_nameToProperty;
+
+ const QDesignerDynamicPropertySheetExtension *dynamicSheet =
+ qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);
+ const QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));
+
+ // Optimizization: Instead of rebuilding the complete list every time, compile a list of properties to remove,
+ // remove them, traverse the sheet, in case property exists just set a value, otherwise - create it.
+ QExtensionManager *m = m_core->extensionManager();
+
+ m_propertySheet = qobject_cast<QDesignerPropertySheetExtension*>(m->extension(object, Q_TYPEID(QDesignerPropertySheetExtension)));
+ if (m_propertySheet) {
+ const int propertyCount = m_propertySheet->count();
+ for (int i = 0; i < propertyCount; ++i) {
+ if (!m_propertySheet->isVisible(i))
+ continue;
+
+ const QString propertyName = m_propertySheet->propertyName(i);
+ if (m_propertySheet->indexOf(propertyName) != i)
+ continue;
+ const QString groupName = m_propertySheet->propertyGroup(i);
+ const QMap<QString, QtVariantProperty *>::const_iterator rit = toRemove.constFind(propertyName);
+ if (rit != toRemove.constEnd()) {
+ QtVariantProperty *property = rit.value();
+ if (m_propertyToGroup.value(property) == groupName && toBrowserType(m_propertySheet->property(i), propertyName) == property->propertyType())
+ toRemove.remove(propertyName);
+ }
+ }
+ }
+
+ QMapIterator<QString, QtVariantProperty *> itRemove(toRemove);
+ while (itRemove.hasNext()) {
+ itRemove.next();
+
+ QtVariantProperty *property = itRemove.value();
+ m_nameToProperty.remove(itRemove.key());
+ m_propertyToGroup.remove(property);
+ delete property;
+ }
+
+ if (oldFormWindow != formWindow)
+ reloadResourceProperties();
+
+ bool isMainContainer = false;
+ if (QWidget *widget = qobject_cast<QWidget*>(object)) {
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(widget)) {
+ isMainContainer = (fw->mainContainer() == widget);
+ }
+ }
+ m_groups.clear();
+
+ if (m_propertySheet) {
+ QtProperty *lastProperty = 0;
+ QtProperty *lastGroup = 0;
+ const int propertyCount = m_propertySheet->count();
+ for (int i = 0; i < propertyCount; ++i) {
+ if (!m_propertySheet->isVisible(i))
+ continue;
+
+ const QString propertyName = m_propertySheet->propertyName(i);
+ if (m_propertySheet->indexOf(propertyName) != i)
+ continue;
+ const QVariant value = m_propertySheet->property(i);
+
+ const int type = toBrowserType(value, propertyName);
+
+ QtVariantProperty *property = m_nameToProperty.value(propertyName, 0);
+ bool newProperty = property == 0;
+ if (newProperty) {
+ property = m_propertyManager->addProperty(type, propertyName);
+ if (property) {
+ newProperty = true;
+ if (type == DesignerPropertyManager::enumTypeId()) {
+ const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(value);
+ QStringList names;
+ QStringListIterator it(e.metaEnum.keys());
+ while (it.hasNext())
+ names.append(it.next());
+ m_updatingBrowser = true;
+ property->setAttribute(m_strings.m_enumNamesAttribute, names);
+ m_updatingBrowser = false;
+ } else if (type == DesignerPropertyManager::designerFlagTypeId()) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(value);
+ QList<QPair<QString, uint> > flags;
+ QStringListIterator it(f.metaFlags.keys());
+ while (it.hasNext()) {
+ const QString name = it.next();
+ const uint val = f.metaFlags.keyToValue(name);
+ flags.append(qMakePair(name, val));
+ }
+ m_updatingBrowser = true;
+ QVariant v;
+ v.setValue(flags);
+ property->setAttribute(m_strings.m_flagsAttribute, v);
+ m_updatingBrowser = false;
+ }
+ }
+ }
+
+ if (property != 0) {
+ const bool dynamicProperty = (dynamicSheet && dynamicSheet->isDynamicProperty(i))
+ || (sheet && sheet->isDefaultDynamicProperty(i));
+ switch (type) {
+ case QVariant::Palette:
+ setupPaletteProperty(property);
+ break;
+ case QVariant::KeySequence:
+ //addCommentProperty(property, propertyName);
+ break;
+ default:
+ break;
+ }
+ if (type == QVariant::String || type == qMetaTypeId<PropertySheetStringValue>())
+ setupStringProperty(property, isMainContainer);
+ property->setAttribute(m_strings.m_resettableAttribute, m_propertySheet->hasReset(i));
+
+ const QString groupName = m_propertySheet->propertyGroup(i);
+ QtVariantProperty *groupProperty = 0;
+
+ if (newProperty) {
+ QMap<QString, QtVariantProperty*>::const_iterator itPrev = m_nameToProperty.insert(propertyName, property);
+ m_propertyToGroup[property] = groupName;
+ if (m_sorting) {
+ QtProperty *previous = 0;
+ if (itPrev != m_nameToProperty.constBegin())
+ previous = (--itPrev).value();
+ m_currentBrowser->insertProperty(property, previous);
+ }
+ }
+ const QMap<QString, QtVariantProperty*>::const_iterator gnit = m_nameToGroup.constFind(groupName);
+ if (gnit != m_nameToGroup.constEnd()) {
+ groupProperty = gnit.value();
+ } else {
+ groupProperty = m_propertyManager->addProperty(QtVariantPropertyManager::groupTypeId(), groupName);
+ QtBrowserItem *item = 0;
+ if (!m_sorting)
+ item = m_currentBrowser->insertProperty(groupProperty, lastGroup);
+ m_nameToGroup[groupName] = groupProperty;
+ m_groups.append(groupProperty);
+ if (dynamicProperty)
+ m_dynamicGroup = groupProperty;
+ if (m_currentBrowser == m_treeBrowser && item) {
+ m_treeBrowser->setBackgroundColor(item, propertyColor(groupProperty));
+ groupProperty->setModified(true);
+ }
+ }
+ /* Group changed or new group. Append to last subproperty of
+ * that group. Note that there are cases in which a derived
+ * property sheet appends fake properties for the class
+ * which will appear after the layout group properties
+ * (QWizardPage). To make them appear at the end of the
+ * actual class group, goto last element. */
+ if (lastGroup != groupProperty) {
+ lastGroup = groupProperty;
+ lastProperty = 0; // Append at end
+ const QList<QtProperty*> subProperties = lastGroup->subProperties();
+ if (!subProperties.empty())
+ lastProperty = subProperties.back();
+ lastGroup = groupProperty;
+ }
+ if (!m_groups.contains(groupProperty))
+ m_groups.append(groupProperty);
+ if (newProperty)
+ groupProperty->insertSubProperty(property, lastProperty);
+
+ lastProperty = property;
+
+ updateBrowserValue(property, value);
+
+ property->setModified(m_propertySheet->isChanged(i));
+ if (propertyName == QLatin1String("geometry") && type == QVariant::Rect) {
+ QList<QtProperty *> subProperties = property->subProperties();
+ foreach (QtProperty *subProperty, subProperties) {
+ const QString subPropertyName = subProperty->propertyName();
+ if (subPropertyName == QLatin1String("X") || subPropertyName == QLatin1String("Y"))
+ subProperty->setEnabled(!isMainContainer);
+ }
+ }
+ } else {
+ qWarning("%s", qPrintable(msgUnsupportedType(propertyName, type)));
+ }
+ }
+ }
+ QMap<QString, QtVariantProperty *> groups = m_nameToGroup;
+ QMapIterator<QString, QtVariantProperty *> itGroup(groups);
+ while (itGroup.hasNext()) {
+ QtVariantProperty *groupProperty = itGroup.next().value();
+ if (groupProperty->subProperties().empty()) {
+ if (groupProperty == m_dynamicGroup)
+ m_dynamicGroup = 0;
+ delete groupProperty;
+ m_nameToGroup.remove(itGroup.key());
+ }
+ }
+ const bool addEnabled = dynamicSheet ? dynamicSheet->dynamicPropertiesAllowed() : false;
+ m_addDynamicAction->setEnabled(addEnabled);
+ m_removeDynamicAction->setEnabled(false);
+ applyExpansionState();
+ applyFilter();
+ // In the first setObject() call following the addition of a dynamic property, focus and edit it.
+ if (editNewDynamicProperty) {
+ // Have QApplication process the events related to completely closing the modal 'add' dialog,
+ // otherwise, we cannot focus the property editor in docked mode.
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ editProperty(m_recentlyAddedDynamicProperty);
+ }
+ m_recentlyAddedDynamicProperty.clear();
+ m_filterWidget->setEnabled(object);
+}
+
+void PropertyEditor::reloadResourceProperties()
+{
+ m_updatingBrowser = true;
+ m_propertyManager->reloadResourceProperties();
+ m_updatingBrowser = false;
+}
+
+QtBrowserItem *PropertyEditor::nonFakePropertyBrowserItem(QtBrowserItem *item) const
+{
+ // Top-level properties are QObject/QWidget groups, etc. Find first item property below
+ // which should be nonfake
+ const QList<QtBrowserItem *> topLevelItems = m_currentBrowser->topLevelItems();
+ do {
+ if (topLevelItems.contains(item->parent()))
+ return item;
+ item = item->parent();
+ } while (item);
+ return 0;
+}
+
+QString PropertyEditor::currentPropertyName() const
+{
+ if (QtBrowserItem *browserItem = m_currentBrowser->currentItem())
+ if (QtBrowserItem *topLevelItem = nonFakePropertyBrowserItem(browserItem)) {
+ return topLevelItem->property()->propertyName();
+ }
+ return QString();
+}
+
+void PropertyEditor::slotResetProperty(QtProperty *property)
+{
+ QDesignerFormWindowInterface *form = m_core->formWindowManager()->activeFormWindow();
+ if (!form)
+ return;
+
+ if (m_propertyManager->resetFontSubProperty(property))
+ return;
+
+ if (m_propertyManager->resetIconSubProperty(property))
+ return;
+
+ if (!m_propertyToGroup.contains(property))
+ return;
+
+ emit resetProperty(property->propertyName());
+}
+
+void PropertyEditor::slotValueChanged(QtProperty *property, const QVariant &value, bool enableSubPropertyHandling)
+{
+ if (m_updatingBrowser)
+ return;
+
+ if (!m_propertySheet)
+ return;
+
+ QtVariantProperty *varProp = m_propertyManager->variantProperty(property);
+
+ if (!varProp)
+ return;
+
+ if (!m_propertyToGroup.contains(property))
+ return;
+
+ if (varProp->propertyType() == QtVariantPropertyManager::enumTypeId()) {
+ PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(m_propertySheet->property(m_propertySheet->indexOf(property->propertyName())));
+ const int val = value.toInt();
+ const QString valName = varProp->attributeValue(m_strings.m_enumNamesAttribute).toStringList().at(val);
+ bool ok = false;
+ e.value = e.metaEnum.parseEnum(valName, &ok);
+ Q_ASSERT(ok);
+ QVariant v;
+ v.setValue(e);
+ emitPropertyValueChanged(property->propertyName(), v, true);
+ return;
+ }
+
+ emitPropertyValueChanged(property->propertyName(), value, enableSubPropertyHandling);
+}
+
+bool PropertyEditor::isDynamicProperty(const QtBrowserItem* item) const
+{
+ if (!item)
+ return false;
+
+ const QDesignerDynamicPropertySheetExtension *dynamicSheet =
+ qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);
+
+ if (!dynamicSheet)
+ return false;
+
+ if (m_propertyToGroup.contains(item->property())
+ && dynamicSheet->isDynamicProperty(m_propertySheet->indexOf(item->property()->propertyName())))
+ return true;
+ return false;
+}
+
+void PropertyEditor::editProperty(const QString &name)
+{
+ // find the browser item belonging to the property, make it current and edit it
+ QtBrowserItem *browserItem = 0;
+ if (QtVariantProperty *property = m_nameToProperty.value(name, 0)) {
+ const QList<QtBrowserItem *> items = m_currentBrowser->items(property);
+ if (items.size() == 1)
+ browserItem = items.front();
+ }
+ if (browserItem == 0)
+ return;
+ m_currentBrowser->setFocus(Qt::OtherFocusReason);
+ if (m_currentBrowser == m_treeBrowser) { // edit is currently only supported in tree view
+ m_treeBrowser->editItem(browserItem);
+ } else {
+ m_currentBrowser->setCurrentItem(browserItem);
+ }
+}
+
+void PropertyEditor::slotCurrentItemChanged(QtBrowserItem *item)
+{
+ m_removeDynamicAction->setEnabled(isDynamicProperty(item));
+
+}
+
+void PropertyEditor::slotRemoveDynamicProperty()
+{
+ if (QtBrowserItem* item = m_currentBrowser->currentItem())
+ if (isDynamicProperty(item))
+ emit removeDynamicProperty(item->property()->propertyName());
+}
+
+void PropertyEditor::setFilter(const QString &pattern)
+{
+ m_filterPattern = pattern;
+ applyFilter();
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/propertyeditor.h b/src/designer/src/components/propertyeditor/propertyeditor.h
new file mode 100644
index 000000000..7278a3de9
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/propertyeditor.h
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROPERTYEDITOR_H
+#define PROPERTYEDITOR_H
+
+#include "propertyeditor_global.h"
+#include <qdesigner_propertyeditor_p.h>
+
+#include <QtCore/QPointer>
+#include <QtCore/QMap>
+#include <QtCore/QVector>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+class DomProperty;
+class QDesignerMetaDataBaseItemInterface;
+class QDesignerPropertySheetExtension;
+
+class QtAbstractPropertyBrowser;
+class QtButtonPropertyBrowser;
+class QtTreePropertyBrowser;
+class QtProperty;
+class QtVariantProperty;
+class QtBrowserItem;
+class QStackedWidget;
+
+namespace qdesigner_internal {
+
+class StringProperty;
+class DesignerPropertyManager;
+class DesignerEditorFactory;
+class FilterWidget;
+class ElidingLabel;
+
+class QT_PROPERTYEDITOR_EXPORT PropertyEditor: public QDesignerPropertyEditor
+{
+ Q_OBJECT
+public:
+ explicit PropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ virtual ~PropertyEditor();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool isReadOnly() const;
+ virtual void setReadOnly(bool readOnly);
+ virtual void setPropertyValue(const QString &name, const QVariant &value, bool changed = true);
+ virtual void updatePropertySheet();
+
+ virtual void setObject(QObject *object);
+
+ void reloadResourceProperties();
+
+ virtual QObject *object() const
+ { return m_object; }
+
+ virtual QString currentPropertyName() const;
+
+protected:
+
+ bool event(QEvent *event);
+
+private slots:
+ void slotResetProperty(QtProperty *property);
+ void slotValueChanged(QtProperty *property, const QVariant &value, bool enableSubPropertyHandling);
+ void slotViewTriggered(QAction *action);
+ void slotAddDynamicProperty(QAction *action);
+ void slotRemoveDynamicProperty();
+ void slotSorting(bool sort);
+ void slotColoring(bool color);
+ void slotCurrentItemChanged(QtBrowserItem*);
+ void setFilter(const QString &pattern);
+
+private:
+ void updateBrowserValue(QtVariantProperty *property, const QVariant &value);
+ void updateToolBarLabel();
+ int toBrowserType(const QVariant &value, const QString &propertyName) const;
+ QString removeScope(const QString &value) const;
+ QDesignerMetaDataBaseItemInterface *metaDataBaseItem() const;
+ void setupStringProperty(QtVariantProperty *property, bool isMainContainer);
+ void setupPaletteProperty(QtVariantProperty *property);
+ QString realClassName(QObject *object) const;
+ void storeExpansionState();
+ void applyExpansionState();
+ void storePropertiesExpansionState(const QList<QtBrowserItem *> &items);
+ void applyPropertiesExpansionState(const QList<QtBrowserItem *> &items);
+ void applyFilter();
+ int applyPropertiesFilter(const QList<QtBrowserItem *> &items);
+ void setExpanded(QtBrowserItem *item, bool expanded);
+ bool isExpanded(QtBrowserItem *item) const;
+ void setItemVisible(QtBrowserItem *item, bool visible);
+ bool isItemVisible(QtBrowserItem *item) const;
+ void collapseAll();
+ void clearView();
+ void fillView();
+ bool isLayoutGroup(QtProperty *group) const;
+ void updateColors();
+ void updateForegroundBrightness();
+ QColor propertyColor(QtProperty *property) const;
+ void updateActionsState();
+ QtBrowserItem *nonFakePropertyBrowserItem(QtBrowserItem *item) const;
+ void saveSettings() const;
+ void editProperty(const QString &name);
+ bool isDynamicProperty(const QtBrowserItem* item) const;
+
+ struct Strings {
+ Strings();
+ QSet<QString> m_alignmentProperties;
+ const QString m_fontProperty;
+ const QString m_qLayoutWidget;
+ const QString m_designerPrefix;
+ const QString m_layout;
+ const QString m_validationModeAttribute;
+ const QString m_fontAttribute;
+ const QString m_superPaletteAttribute;
+ const QString m_enumNamesAttribute;
+ const QString m_resettableAttribute;
+ const QString m_flagsAttribute;
+ };
+
+ const Strings m_strings;
+ QDesignerFormEditorInterface *m_core;
+ QDesignerPropertySheetExtension *m_propertySheet;
+ QtAbstractPropertyBrowser *m_currentBrowser;
+ QtButtonPropertyBrowser *m_buttonBrowser;
+ QtTreePropertyBrowser *m_treeBrowser;
+ DesignerPropertyManager *m_propertyManager;
+ DesignerEditorFactory *m_treeFactory;
+ DesignerEditorFactory *m_groupFactory;
+ QPointer<QObject> m_object;
+ QMap<QString, QtVariantProperty*> m_nameToProperty;
+ QMap<QtProperty*, QString> m_propertyToGroup;
+ QMap<QString, QtVariantProperty*> m_nameToGroup;
+ QList<QtProperty *> m_groups;
+ QtProperty *m_dynamicGroup;
+ QString m_recentlyAddedDynamicProperty;
+ bool m_updatingBrowser;
+
+ QStackedWidget *m_stackedWidget;
+ FilterWidget *m_filterWidget;
+ int m_buttonIndex;
+ int m_treeIndex;
+ QAction *m_addDynamicAction;
+ QAction *m_removeDynamicAction;
+ QAction *m_sortingAction;
+ QAction *m_coloringAction;
+ QAction *m_treeAction;
+ QAction *m_buttonAction;
+ ElidingLabel *m_classLabel;
+
+ bool m_sorting;
+ bool m_coloring;
+
+ QMap<QString, bool> m_expansionState;
+
+ QString m_filterPattern;
+ QVector<QPair<QColor, QColor> > m_colors;
+ QPair<QColor, QColor> m_dynamicColor;
+ QPair<QColor, QColor> m_layoutColor;
+
+ bool m_brightness;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // PROPERTYEDITOR_H
diff --git a/src/designer/src/components/propertyeditor/propertyeditor.pri b/src/designer/src/components/propertyeditor/propertyeditor.pri
new file mode 100644
index 000000000..bb1afdb94
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/propertyeditor.pri
@@ -0,0 +1,52 @@
+#the next line prevents non-shadowbuilds from including the same directory twice
+#otherwise, the build command would be too long for some win32 shells.
+!exists($$QT_BUILD_TREE/tools/designer/src/components/propertyeditor/propertyeditor.h):INCLUDEPATH += $$QT_BUILD_TREE/tools/designer/src/components/propertyeditor
+
+INCLUDEPATH += $$PWD
+
+# --- Property browser is also linked into the designer_shared library.
+# Avoid conflict when linking statically
+contains(CONFIG, static) {
+ INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/qtpropertybrowser
+ INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/qtgradienteditor
+} else {
+ include(../../../../shared/qtpropertybrowser/qtpropertybrowser.pri)
+ include(../../../../shared/qtgradienteditor/qtcolorbutton.pri)
+}
+
+FORMS += $$PWD/paletteeditor.ui \
+ $$PWD/stringlisteditor.ui \
+ $$PWD/previewwidget.ui \
+ $$PWD/newdynamicpropertydialog.ui
+
+HEADERS += $$PWD/propertyeditor.h \
+ $$PWD/designerpropertymanager.h \
+ $$PWD/paletteeditor.h \
+ $$PWD/paletteeditorbutton.h \
+ $$PWD/stringlisteditor.h \
+ $$PWD/stringlisteditorbutton.h \
+ $$PWD/previewwidget.h \
+ $$PWD/previewframe.h \
+ $$PWD/newdynamicpropertydialog.h \
+ $$PWD/brushpropertymanager.h \
+ $$PWD/fontpropertymanager.h
+
+SOURCES += $$PWD/propertyeditor.cpp \
+ $$PWD/designerpropertymanager.cpp \
+ $$PWD/paletteeditor.cpp \
+ $$PWD/paletteeditorbutton.cpp \
+ $$PWD/stringlisteditor.cpp \
+ $$PWD/stringlisteditorbutton.cpp \
+ $$PWD/previewwidget.cpp \
+ $$PWD/previewframe.cpp \
+ $$PWD/newdynamicpropertydialog.cpp \
+ $$PWD/brushpropertymanager.cpp \
+ $$PWD/fontpropertymanager.cpp
+
+HEADERS += \
+ $$PWD/propertyeditor_global.h \
+ $$PWD/qlonglongvalidator.h
+
+SOURCES += $$PWD/qlonglongvalidator.cpp
+
+RESOURCES += $$PWD/propertyeditor.qrc
diff --git a/src/designer/src/components/propertyeditor/propertyeditor.qrc b/src/designer/src/components/propertyeditor/propertyeditor.qrc
new file mode 100644
index 000000000..68008eca8
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/propertyeditor.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/trolltech/propertyeditor">
+ <file>fontmapping.xml</file>
+ </qresource>
+</RCC>
diff --git a/src/designer/src/components/propertyeditor/propertyeditor_global.h b/src/designer/src/components/propertyeditor/propertyeditor_global.h
new file mode 100644
index 000000000..f173392f5
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/propertyeditor_global.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROPERTYEDITOR_GLOBAL_H
+#define PROPERTYEDITOR_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN
+#ifdef QT_PROPERTYEDITOR_LIBRARY
+# define QT_PROPERTYEDITOR_EXPORT
+#else
+# define QT_PROPERTYEDITOR_EXPORT
+#endif
+#else
+#define QT_PROPERTYEDITOR_EXPORT
+#endif
+
+QT_END_NAMESPACE
+
+#endif // PROPERTYEDITOR_GLOBAL_H
diff --git a/src/designer/src/components/propertyeditor/qlonglongvalidator.cpp b/src/designer/src/components/propertyeditor/qlonglongvalidator.cpp
new file mode 100644
index 000000000..9396009b3
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/qlonglongvalidator.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlonglongvalidator.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+// ----------------------------------------------------------------------------
+QLongLongValidator::QLongLongValidator(QObject * parent)
+ : QValidator(parent),
+ b(Q_UINT64_C(0x8000000000000000)), t(Q_UINT64_C(0x7FFFFFFFFFFFFFFF))
+{
+}
+
+QLongLongValidator::QLongLongValidator(qlonglong minimum, qlonglong maximum,
+ QObject * parent)
+ : QValidator(parent), b(minimum), t(maximum)
+{
+}
+
+QLongLongValidator::~QLongLongValidator()
+{
+ // nothing
+}
+
+QValidator::State QLongLongValidator::validate(QString & input, int &) const
+{
+ if (input.contains(QLatin1Char(' ')))
+ return Invalid;
+ if (input.isEmpty() || (b < 0 && input == QString(QLatin1Char('-'))))
+ return Intermediate;
+ bool ok;
+ qlonglong entered = input.toLongLong(&ok);
+ if (!ok || (entered < 0 && b >= 0)) {
+ return Invalid;
+ } else if (entered >= b && entered <= t) {
+ return Acceptable;
+ } else {
+ if (entered >= 0)
+ return (entered > t) ? Invalid : Intermediate;
+ else
+ return (entered < b) ? Invalid : Intermediate;
+ }
+}
+
+void QLongLongValidator::setRange(qlonglong bottom, qlonglong top)
+{
+ b = bottom;
+ t = top;
+}
+
+void QLongLongValidator::setBottom(qlonglong bottom)
+{
+ setRange(bottom, top());
+}
+
+void QLongLongValidator::setTop(qlonglong top)
+{
+ setRange(bottom(), top);
+}
+
+
+// ----------------------------------------------------------------------------
+QULongLongValidator::QULongLongValidator(QObject * parent)
+ : QValidator(parent),
+ b(0), t(Q_UINT64_C(0xFFFFFFFFFFFFFFFF))
+{
+}
+
+QULongLongValidator::QULongLongValidator(qulonglong minimum, qulonglong maximum,
+ QObject * parent)
+ : QValidator(parent), b(minimum), t(maximum)
+{
+}
+
+QULongLongValidator::~QULongLongValidator()
+{
+ // nothing
+}
+
+QValidator::State QULongLongValidator::validate(QString & input, int &) const
+{
+ if (input.isEmpty())
+ return Intermediate;
+
+ bool ok;
+ qulonglong entered = input.toULongLong(&ok);
+ if (input.contains(QLatin1Char(' ')) || input.contains(QLatin1Char('-')) || !ok)
+ return Invalid;
+
+ if (entered >= b && entered <= t)
+ return Acceptable;
+
+ return Invalid;
+}
+
+void QULongLongValidator::setRange(qulonglong bottom, qulonglong top)
+{
+ b = bottom;
+ t = top;
+}
+
+void QULongLongValidator::setBottom(qulonglong bottom)
+{
+ setRange(bottom, top());
+}
+
+void QULongLongValidator::setTop(qulonglong top)
+{
+ setRange(bottom(), top);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/qlonglongvalidator.h b/src/designer/src/components/propertyeditor/qlonglongvalidator.h
new file mode 100644
index 000000000..122351e4a
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/qlonglongvalidator.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLONGLONGVALIDATOR_H
+#define QLONGLONGVALIDATOR_H
+
+#include <QtGui/QValidator>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QLongLongValidator : public QValidator
+{
+ Q_OBJECT
+ Q_PROPERTY(qlonglong bottom READ bottom WRITE setBottom)
+ Q_PROPERTY(qlonglong top READ top WRITE setTop)
+
+public:
+ explicit QLongLongValidator(QObject * parent);
+ QLongLongValidator(qlonglong bottom, qlonglong top, QObject * parent);
+ ~QLongLongValidator();
+
+ QValidator::State validate(QString &, int &) const;
+
+ void setBottom(qlonglong);
+ void setTop(qlonglong);
+ virtual void setRange(qlonglong bottom, qlonglong top);
+
+ qlonglong bottom() const { return b; }
+ qlonglong top() const { return t; }
+
+private:
+ Q_DISABLE_COPY(QLongLongValidator)
+
+ qlonglong b;
+ qlonglong t;
+};
+
+// ----------------------------------------------------------------------------
+class QULongLongValidator : public QValidator
+{
+ Q_OBJECT
+ Q_PROPERTY(qulonglong bottom READ bottom WRITE setBottom)
+ Q_PROPERTY(qulonglong top READ top WRITE setTop)
+
+public:
+ explicit QULongLongValidator(QObject * parent);
+ QULongLongValidator(qulonglong bottom, qulonglong top, QObject * parent);
+ ~QULongLongValidator();
+
+ QValidator::State validate(QString &, int &) const;
+
+ void setBottom(qulonglong);
+ void setTop(qulonglong);
+ virtual void setRange(qulonglong bottom, qulonglong top);
+
+ qulonglong bottom() const { return b; }
+ qulonglong top() const { return t; }
+
+private:
+ Q_DISABLE_COPY(QULongLongValidator)
+
+ qulonglong b;
+ qulonglong t;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QLONGLONGVALIDATOR_H
diff --git a/src/designer/src/components/propertyeditor/stringlisteditor.cpp b/src/designer/src/components/propertyeditor/stringlisteditor.cpp
new file mode 100644
index 000000000..cd55eff2e
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/stringlisteditor.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "stringlisteditor.h"
+#include <iconloader_p.h>
+#include <QtGui/QStringListModel>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+StringListEditor::StringListEditor(QWidget *parent)
+ : QDialog(parent), m_model(new QStringListModel(this))
+{
+ setupUi(this);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ listView->setModel(m_model);
+
+ connect(listView->selectionModel(),
+ SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(currentIndexChanged(QModelIndex,QModelIndex)));
+ connect(listView->itemDelegate(),
+ SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
+ this, SLOT(currentValueChanged()));
+
+ QIcon upIcon = createIconSet(QString::fromUtf8("up.png"));
+ QIcon downIcon = createIconSet(QString::fromUtf8("down.png"));
+ QIcon minusIcon = createIconSet(QString::fromUtf8("minus.png"));
+ QIcon plusIcon = createIconSet(QString::fromUtf8("plus.png"));
+ upButton->setIcon(upIcon);
+ downButton->setIcon(downIcon);
+ newButton->setIcon(plusIcon);
+ deleteButton->setIcon(minusIcon);
+
+ updateUi();
+}
+
+StringListEditor::~StringListEditor()
+{
+}
+
+QStringList StringListEditor::getStringList(QWidget *parent, const QStringList &init, int *result)
+{
+ StringListEditor dlg(parent);
+ dlg.setStringList(init);
+ int res = dlg.exec();
+ if (result)
+ *result = res;
+ return (res == QDialog::Accepted) ? dlg.stringList() : init;
+}
+
+void StringListEditor::setStringList(const QStringList &stringList)
+{
+ m_model->setStringList(stringList);
+ updateUi();
+}
+
+QStringList StringListEditor::stringList() const
+{
+ return m_model->stringList();
+}
+
+void StringListEditor::currentIndexChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ Q_UNUSED(previous);
+ setCurrentIndex(current.row());
+ updateUi();
+}
+
+void StringListEditor::currentValueChanged()
+{
+ setCurrentIndex(currentIndex());
+ updateUi();
+}
+
+void StringListEditor::on_upButton_clicked()
+{
+ int from = currentIndex();
+ int to = currentIndex() - 1;
+ QString value = stringAt(from);
+ removeString(from);
+ insertString(to, value);
+ setCurrentIndex(to);
+ updateUi();
+}
+
+void StringListEditor::on_downButton_clicked()
+{
+ int from = currentIndex();
+ int to = currentIndex() + 1;
+ QString value = stringAt(from);
+ removeString(from);
+ insertString(to, value);
+ setCurrentIndex(to);
+ updateUi();
+}
+
+void StringListEditor::on_newButton_clicked()
+{
+ int to = currentIndex();
+ if (to == -1)
+ to = count() - 1;
+ ++to;
+ insertString(to, QString());
+ setCurrentIndex(to);
+ updateUi();
+ editString(to);
+}
+
+void StringListEditor::on_deleteButton_clicked()
+{
+ removeString(currentIndex());
+ setCurrentIndex(currentIndex());
+ updateUi();
+}
+
+void StringListEditor::on_valueEdit_textEdited(const QString &text)
+{
+ setStringAt(currentIndex(), text);
+}
+
+void StringListEditor::updateUi()
+{
+ upButton->setEnabled((count() > 1) && (currentIndex() > 0));
+ downButton->setEnabled((count() > 1) && (currentIndex() >= 0) && (currentIndex() < (count() - 1)));
+ deleteButton->setEnabled(currentIndex() != -1);
+ valueEdit->setEnabled(currentIndex() != -1);
+}
+
+int StringListEditor::currentIndex() const
+{
+ return listView->currentIndex().row();
+}
+
+void StringListEditor::setCurrentIndex(int index)
+{
+ QModelIndex modelIndex = m_model->index(index, 0);
+ if (listView->currentIndex() != modelIndex)
+ listView->setCurrentIndex(modelIndex);
+ valueEdit->setText(stringAt(index));
+}
+
+int StringListEditor::count() const
+{
+ return m_model->rowCount();
+}
+
+QString StringListEditor::stringAt(int index) const
+{
+ return qvariant_cast<QString>(m_model->data(m_model->index(index, 0), Qt::DisplayRole));
+}
+
+void StringListEditor::setStringAt(int index, const QString &value)
+{
+ m_model->setData(m_model->index(index, 0), value);
+}
+
+void StringListEditor::removeString(int index)
+{
+ m_model->removeRows(index, 1);
+}
+
+void StringListEditor::insertString(int index, const QString &value)
+{
+ m_model->insertRows(index, 1);
+ m_model->setData(m_model->index(index, 0), value);
+}
+
+void StringListEditor::editString(int index)
+{
+ listView->edit(m_model->index(index, 0));
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/stringlisteditor.h b/src/designer/src/components/propertyeditor/stringlisteditor.h
new file mode 100644
index 000000000..8848d52d2
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/stringlisteditor.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STRINGLISTEDITOR_H
+#define STRINGLISTEDITOR_H
+
+#include "ui_stringlisteditor.h"
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+class QStringListModel;
+
+namespace qdesigner_internal {
+
+class StringListEditor : public QDialog, private Ui::Dialog
+{
+ Q_OBJECT
+public:
+ ~StringListEditor();
+ void setStringList(const QStringList &stringList);
+ QStringList stringList() const;
+
+ static QStringList getStringList(
+ QWidget *parent, const QStringList &init = QStringList(), int *result = 0);
+
+private slots:
+ void on_upButton_clicked();
+ void on_downButton_clicked();
+ void on_newButton_clicked();
+ void on_deleteButton_clicked();
+ void on_valueEdit_textEdited(const QString &text);
+ void currentIndexChanged(const QModelIndex &current, const QModelIndex &previous);
+ void currentValueChanged();
+
+private:
+ StringListEditor(QWidget *parent = 0);
+ void updateUi();
+ int currentIndex() const;
+ void setCurrentIndex(int index);
+ int count() const;
+ QString stringAt(int index) const;
+ void setStringAt(int index, const QString &value);
+ void removeString(int index);
+ void insertString(int index, const QString &value);
+ void editString(int index);
+
+ QStringListModel *m_model;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // STRINGLISTEDITOR_H
diff --git a/src/designer/src/components/propertyeditor/stringlisteditor.ui b/src/designer/src/components/propertyeditor/stringlisteditor.ui
new file mode 100644
index 000000000..b206789b6
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/stringlisteditor.ui
@@ -0,0 +1,265 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::Dialog</class>
+ <widget class="QDialog" name="qdesigner_internal::Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>StringList</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="0" colspan="2" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="newButton" >
+ <property name="toolTip" >
+ <string>New String</string>
+ </property>
+ <property name="text" >
+ <string>&amp;New</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteButton" >
+ <property name="toolTip" >
+ <string>Delete String</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Delete</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>&amp;Value:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>valueEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="valueEdit" />
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="upButton" >
+ <property name="toolTip" >
+ <string>Move String Up</string>
+ </property>
+ <property name="text" >
+ <string>Up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="downButton" >
+ <property name="toolTip" >
+ <string>Move String Down</string>
+ </property>
+ <property name="text" >
+ <string>Down</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QListView" name="listView" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>qdesigner_internal::Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>258</x>
+ <y>283</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>138</x>
+ <y>294</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>qdesigner_internal::Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>350</x>
+ <y>284</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>369</x>
+ <y>295</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/components/propertyeditor/stringlisteditorbutton.cpp b/src/designer/src/components/propertyeditor/stringlisteditorbutton.cpp
new file mode 100644
index 000000000..9e858cce1
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/stringlisteditorbutton.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "stringlisteditorbutton.h"
+#include "stringlisteditor.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+StringListEditorButton::StringListEditorButton(
+ const QStringList &stringList, QWidget *parent)
+ : QToolButton(parent), m_stringList(stringList)
+{
+ setFocusPolicy(Qt::NoFocus);
+ setText(tr("Change String List"));
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+
+ connect(this, SIGNAL(clicked()), this, SLOT(showStringListEditor()));
+}
+
+StringListEditorButton::~StringListEditorButton()
+{
+}
+
+void StringListEditorButton::setStringList(const QStringList &stringList)
+{
+ m_stringList = stringList;
+}
+
+void StringListEditorButton::showStringListEditor()
+{
+ int result;
+ QStringList lst = StringListEditor::getStringList(0, m_stringList, &result);
+ if (result == QDialog::Accepted) {
+ m_stringList = lst;
+ emit stringListChanged(m_stringList);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/propertyeditor/stringlisteditorbutton.h b/src/designer/src/components/propertyeditor/stringlisteditorbutton.h
new file mode 100644
index 000000000..07bd291f5
--- /dev/null
+++ b/src/designer/src/components/propertyeditor/stringlisteditorbutton.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STRINGLISTEDITORBUTTON_H
+#define STRINGLISTEDITORBUTTON_H
+
+#include "propertyeditor_global.h"
+
+#include <QtCore/QStringList>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QT_PROPERTYEDITOR_EXPORT StringListEditorButton: public QToolButton
+{
+ Q_OBJECT
+public:
+ explicit StringListEditorButton(const QStringList &stringList, QWidget *parent = 0);
+ virtual ~StringListEditorButton();
+
+ inline QStringList stringList() const
+ { return m_stringList; }
+
+signals:
+ void stringListChanged(const QStringList &stringList);
+
+public slots:
+ void setStringList(const QStringList &stringList);
+
+private slots:
+ void showStringListEditor();
+
+private:
+ QStringList m_stringList;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // STRINGLISTEDITORBUTTON_H
diff --git a/src/designer/src/components/signalsloteditor/connectdialog.cpp b/src/designer/src/components/signalsloteditor/connectdialog.cpp
new file mode 100644
index 000000000..64be11345
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/connectdialog.cpp
@@ -0,0 +1,335 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "connectdialog_p.h"
+#include "signalslot_utils_p.h"
+
+#include <signalslotdialog_p.h>
+#include <metadatabase_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerLanguageExtension>
+
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ typedef QList<QListWidgetItem*> ListWidgetItems;
+}
+
+static QString realClassName(QDesignerFormEditorInterface *core, QWidget *widget)
+{
+ QString class_name = QLatin1String(widget->metaObject()->className());
+ const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
+ const int idx = wdb->indexOfObject(widget);
+ if (idx != -1)
+ class_name = wdb->item(idx)->name();
+ return class_name;
+}
+
+static QString widgetLabel(QDesignerFormEditorInterface *core, QWidget *widget)
+{
+ return QString::fromUtf8("%1 (%2)")
+ .arg(qdesigner_internal::realObjectName(core, widget))
+ .arg(realClassName(core, widget));
+}
+
+namespace qdesigner_internal {
+
+ConnectDialog::ConnectDialog(QDesignerFormWindowInterface *formWindow,
+ QWidget *source, QWidget *destination,
+ QWidget *parent) :
+ QDialog(parent),
+ m_source(source),
+ m_destination(destination),
+ m_sourceMode(widgetMode(m_source, formWindow)),
+ m_destinationMode(widgetMode(m_destination, formWindow)),
+ m_formWindow(formWindow)
+{
+ m_ui.setupUi(this);
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ connect(m_ui.signalList, SIGNAL(itemClicked(QListWidgetItem*)),
+ this, SLOT(selectSignal(QListWidgetItem*)));
+ connect(m_ui.slotList, SIGNAL(itemClicked(QListWidgetItem*)),
+ this, SLOT(selectSlot(QListWidgetItem*)));
+ m_ui.slotList->setEnabled(false);
+
+ QPushButton *ok_button = okButton();
+ ok_button->setDefault(true);
+ ok_button->setEnabled(false);
+
+ connect(m_ui.showAllCheckBox, SIGNAL(toggled(bool)), this, SLOT(populateLists()));
+
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ m_ui.signalGroupBox->setTitle(widgetLabel(core, source));
+ m_ui.slotGroupBox->setTitle(widgetLabel(core, destination));
+
+ m_ui.editSignalsButton->setEnabled(m_sourceMode != NormalWidget);
+ connect(m_ui.editSignalsButton, SIGNAL(clicked()), this, SLOT(editSignals()));
+
+ m_ui.editSlotsButton->setEnabled(m_destinationMode != NormalWidget);
+ connect(m_ui.editSlotsButton, SIGNAL(clicked()), this, SLOT(editSlots()));
+
+ populateLists();
+}
+
+ConnectDialog::WidgetMode ConnectDialog::widgetMode(QWidget *w, QDesignerFormWindowInterface *formWindow)
+{
+ QDesignerFormEditorInterface *core = formWindow->core();
+ if (qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core))
+ return NormalWidget;
+
+ if (w == formWindow || formWindow->mainContainer() == w)
+ return MainContainer;
+
+ if (isPromoted(formWindow->core(), w))
+ return PromotedWidget;
+
+ return NormalWidget;
+}
+
+QPushButton *ConnectDialog::okButton()
+{
+ return m_ui.buttonBox->button(QDialogButtonBox::Ok);
+}
+
+void ConnectDialog::setOkButtonEnabled(bool e)
+{
+ okButton()->setEnabled(e);
+}
+
+void ConnectDialog::populateLists()
+{
+ populateSignalList();
+}
+
+void ConnectDialog::setSignalSlot(const QString &signal, const QString &slot)
+{
+ ListWidgetItems sigItems = m_ui.signalList->findItems(signal, Qt::MatchExactly);
+
+ if (sigItems.empty()) {
+ m_ui.showAllCheckBox->setChecked(true);
+ sigItems = m_ui.signalList->findItems(signal, Qt::MatchExactly);
+ }
+
+ if (!sigItems.empty()) {
+ selectSignal(sigItems.front());
+ ListWidgetItems slotItems = m_ui.slotList->findItems(slot, Qt::MatchExactly);
+ if (slotItems.empty()) {
+ m_ui.showAllCheckBox->setChecked(true);
+ slotItems = m_ui.slotList->findItems(slot, Qt::MatchExactly);
+ }
+ if (!slotItems.empty())
+ selectSlot(slotItems.front());
+ }
+}
+
+bool ConnectDialog::showAllSignalsSlots() const
+{
+ return m_ui.showAllCheckBox->isChecked();
+}
+
+void ConnectDialog::setShowAllSignalsSlots(bool showIt)
+{
+ m_ui.showAllCheckBox->setChecked(showIt);
+}
+
+void ConnectDialog::selectSignal(QListWidgetItem *item)
+{
+ if (item) {
+ m_ui.signalList->setCurrentItem(item);
+ populateSlotList(item->text());
+ m_ui.slotList->setEnabled(true);
+ setOkButtonEnabled(!m_ui.slotList->selectedItems().isEmpty());
+ } else {
+ m_ui.signalList->clearSelection();
+ populateSlotList();
+ m_ui.slotList->setEnabled(false);
+ setOkButtonEnabled(false);
+ }
+}
+
+void ConnectDialog::selectSlot(QListWidgetItem *item)
+{
+ if (item) {
+ m_ui.slotList->setCurrentItem(item);
+ } else {
+ m_ui.slotList->clearSelection();
+ }
+ setOkButtonEnabled(true);
+}
+
+QString ConnectDialog::signal() const
+{
+ const ListWidgetItems item_list = m_ui.signalList->selectedItems();
+ if (item_list.size() != 1)
+ return QString();
+ return item_list.at(0)->text();
+}
+
+QString ConnectDialog::slot() const
+{
+ const ListWidgetItems item_list = m_ui.slotList->selectedItems();
+ if (item_list.size() != 1)
+ return QString();
+ return item_list.at(0)->text();
+}
+
+void ConnectDialog::populateSlotList(const QString &signal)
+{
+ QString selectedName;
+ if (const QListWidgetItem * item = m_ui.slotList->currentItem())
+ selectedName = item->text();
+
+ m_ui.slotList->clear();
+
+ QMap<QString, QString> memberToClassName = getMatchingSlots(m_formWindow->core(), m_destination, signal, showAllSignalsSlots());
+
+ QFont font = QApplication::font();
+ font.setItalic(true);
+ QVariant variantFont = QVariant::fromValue(font);
+
+ QListWidgetItem *curr = 0;
+ QMap<QString, QString>::ConstIterator itMember = memberToClassName.constBegin();
+ const QMap<QString, QString>::ConstIterator itMemberEnd = memberToClassName.constEnd();
+ while (itMember != itMemberEnd) {
+ const QString member = itMember.key();
+ const bool qt3Slot = isQt3Slot(m_formWindow->core(), m_destination, member);
+
+ QListWidgetItem *item = new QListWidgetItem(m_ui.slotList);
+ item->setText(member);
+ if (member == selectedName)
+ curr = item;
+
+ if (qt3Slot) {
+ item->setData(Qt::FontRole, variantFont);
+ item->setData(Qt::ForegroundRole, Qt::red);
+ }
+ ++itMember;
+ }
+
+ if (curr)
+ m_ui.slotList->setCurrentItem(curr);
+
+ if (m_ui.slotList->selectedItems().isEmpty())
+ setOkButtonEnabled(false);
+}
+
+void ConnectDialog::populateSignalList()
+{
+ QString selectedName;
+ if (const QListWidgetItem *item = m_ui.signalList->currentItem())
+ selectedName = item->text();
+
+ m_ui.signalList->clear();
+
+ QMap<QString, QString> memberToClassName = getSignals(m_formWindow->core(), m_source, showAllSignalsSlots());
+
+ QFont font = QApplication::font();
+ font.setItalic(true);
+ QVariant variantFont = QVariant::fromValue(font);
+
+ QListWidgetItem *curr = 0;
+ QMap<QString, QString>::ConstIterator itMember = memberToClassName.constBegin();
+ const QMap<QString, QString>::ConstIterator itMemberEnd = memberToClassName.constEnd();
+ while (itMember != itMemberEnd) {
+ const QString member = itMember.key();
+ const bool qt3Signal = isQt3Signal(m_formWindow->core(), m_source, member);
+
+ QListWidgetItem *item = new QListWidgetItem(m_ui.signalList);
+ item->setText(member);
+ if (!selectedName.isEmpty() && member == selectedName)
+ curr = item;
+
+ if (qt3Signal) {
+ item->setData(Qt::FontRole, variantFont);
+ item->setData(Qt::ForegroundRole, Qt::red);
+ }
+ ++itMember;
+ }
+
+ if (curr) {
+ m_ui.signalList->setCurrentItem(curr);
+ } else {
+ selectedName.clear();
+ }
+
+ populateSlotList(selectedName);
+ if (!curr)
+ m_ui.slotList->setEnabled(false);
+}
+
+void ConnectDialog::editSignals()
+{
+ editSignalsSlots(m_source, m_sourceMode, SignalSlotDialog::FocusSignals);
+}
+
+void ConnectDialog::editSlots()
+{
+ editSignalsSlots(m_destination, m_destinationMode, SignalSlotDialog::FocusSlots);
+}
+
+void ConnectDialog::editSignalsSlots(QWidget *w, WidgetMode mode, int signalSlotDialogModeInt)
+{
+ const SignalSlotDialog::FocusMode signalSlotDialogMode = static_cast<SignalSlotDialog::FocusMode>(signalSlotDialogModeInt);
+ switch (mode) {
+ case NormalWidget:
+ break;
+ case MainContainer:
+ if (SignalSlotDialog::editMetaDataBase(m_formWindow, w, this, signalSlotDialogMode))
+ populateLists();
+ break;
+ case PromotedWidget:
+ if (SignalSlotDialog::editPromotedClass(m_formWindow->core(), w, this, signalSlotDialogMode))
+ populateLists();
+ break;
+ }
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/signalsloteditor/connectdialog.ui b/src/designer/src/components/signalsloteditor/connectdialog.ui
new file mode 100644
index 000000000..568516a42
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/connectdialog.ui
@@ -0,0 +1,150 @@
+<ui version="4.0" >
+ <class>ConnectDialog</class>
+ <widget class="QDialog" name="ConnectDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>585</width>
+ <height>361</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Configure Connection</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="signalGroupBox" >
+ <property name="title" >
+ <string>GroupBox</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QListWidget" name="signalList" >
+ <property name="textElideMode" >
+ <enum>Qt::ElideMiddle</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QToolButton" name="editSignalsButton" >
+ <property name="text" >
+ <string>Edit...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QGroupBox" name="slotGroupBox" >
+ <property name="title" >
+ <string>GroupBox</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QListWidget" name="slotList" >
+ <property name="textElideMode" >
+ <enum>Qt::ElideMiddle</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QToolButton" name="editSlotsButton" >
+ <property name="text" >
+ <string>Edit...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="QCheckBox" name="showAllCheckBox" >
+ <property name="text" >
+ <string>Show signals and slots inherited from QWidget</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ConnectDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ConnectDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/components/signalsloteditor/connectdialog_p.h b/src/designer/src/components/signalsloteditor/connectdialog_p.h
new file mode 100644
index 000000000..dd81483d5
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/connectdialog_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONNECTDIALOG_H
+#define CONNECTDIALOG_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "ui_connectdialog.h"
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QPushButton;
+
+namespace qdesigner_internal {
+
+class ConnectDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ ConnectDialog(QDesignerFormWindowInterface *formWindow, QWidget *sender, QWidget *receiver, QWidget *parent = 0);
+
+ QString signal() const;
+ QString slot() const;
+
+ void setSignalSlot(const QString &signal, const QString &slot);
+
+ bool showAllSignalsSlots() const;
+ void setShowAllSignalsSlots(bool showIt);
+
+private slots:
+ void populateLists();
+ void selectSignal(QListWidgetItem *item);
+ void selectSlot(QListWidgetItem *item);
+ void populateSignalList();
+ void populateSlotList(const QString &signal = QString());
+ void editSignals();
+ void editSlots();
+
+private:
+ enum WidgetMode { NormalWidget, MainContainer, PromotedWidget };
+
+ static WidgetMode widgetMode(QWidget *w, QDesignerFormWindowInterface *formWindow);
+ QPushButton *okButton();
+ void setOkButtonEnabled(bool);
+ void editSignalsSlots(QWidget *w, WidgetMode mode, int signalSlotDialogMode);
+
+ QWidget *m_source;
+ QWidget *m_destination;
+ const WidgetMode m_sourceMode;
+ const WidgetMode m_destinationMode;
+ QDesignerFormWindowInterface *m_formWindow;
+ Ui::ConnectDialog m_ui;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // CONNECTDIALOG_H
diff --git a/src/designer/src/components/signalsloteditor/signalslot_utils.cpp b/src/designer/src/components/signalsloteditor/signalslot_utils.cpp
new file mode 100644
index 000000000..ac1fe1cbf
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalslot_utils.cpp
@@ -0,0 +1,334 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "signalslot_utils_p.h"
+
+#include <qdesigner_membersheet_p.h>
+#include <widgetdatabase_p.h>
+#include <metadatabase_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerLanguageExtension>
+
+#include <QtCore/QPair>
+
+QT_BEGIN_NAMESPACE
+
+typedef QPair<QString, QString> ClassNameSignaturePair;
+
+// Find all member functions that match a predicate on the signature string
+// using the member sheet and the fake methods stored in the widget
+// database and the meta data base.
+// Assign a pair of <classname, signature> to OutputIterator.
+
+template <class SignaturePredicate, class OutputIterator>
+static void memberList(QDesignerFormEditorInterface *core,
+ QObject *object,
+ qdesigner_internal::MemberType member_type,
+ bool showAll,
+ SignaturePredicate predicate,
+ OutputIterator it)
+{
+ if (!object)
+ return;
+ // 1) member sheet
+ const QDesignerMemberSheetExtension *members = qt_extension<QDesignerMemberSheetExtension*>(core->extensionManager(), object);
+ Q_ASSERT(members != 0);
+ const int count = members->count();
+ for (int i = 0; i < count; ++i) {
+ if (!members->isVisible(i))
+ continue;
+
+ if (member_type == qdesigner_internal::SignalMember && !members->isSignal(i))
+ continue;
+
+ if (member_type == qdesigner_internal::SlotMember && !members->isSlot(i))
+ continue;
+
+ if (!showAll && members->inheritedFromWidget(i))
+ continue;
+
+ const QString signature = members->signature(i);
+ if (predicate(signature)) {
+ *it = ClassNameSignaturePair(members->declaredInClass(i), signature);
+ ++it;
+ }
+ }
+ // 2) fake slots from widget DB
+ const qdesigner_internal::WidgetDataBase *wdb = qobject_cast<qdesigner_internal::WidgetDataBase *>(core->widgetDataBase());
+ if (!wdb)
+ return;
+ const int idx = wdb->indexOfObject(object);
+ Q_ASSERT(idx != -1);
+ // get the promoted class name
+ const qdesigner_internal::WidgetDataBaseItem *wdbItem = static_cast<qdesigner_internal::WidgetDataBaseItem *>(wdb->item(idx));
+ const QString className = wdbItem->name();
+
+ const QStringList wdbFakeMethods = member_type == qdesigner_internal::SlotMember ? wdbItem->fakeSlots() : wdbItem->fakeSignals();
+ if (!wdbFakeMethods.empty())
+ foreach (const QString &fakeMethod, wdbFakeMethods)
+ if (predicate(fakeMethod)) {
+ *it = ClassNameSignaturePair(className, fakeMethod);
+ ++it;
+ }
+ // 3) fake slots from meta DB
+ qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<qdesigner_internal::MetaDataBase *>(core->metaDataBase());
+ if (!metaDataBase)
+ return;
+
+ if (const qdesigner_internal::MetaDataBaseItem *mdbItem = metaDataBase->metaDataBaseItem(object)) {
+ const QStringList mdbFakeMethods = member_type == qdesigner_internal::SlotMember ? mdbItem->fakeSlots() : mdbItem->fakeSignals();
+ if (!mdbFakeMethods.empty())
+ foreach (const QString &fakeMethod, mdbFakeMethods)
+ if (predicate(fakeMethod)) {
+ *it = ClassNameSignaturePair(className, fakeMethod);
+ ++it;
+ }
+ }
+}
+
+namespace {
+ // Predicate that matches the exact signature string
+ class EqualsPredicate {
+ public:
+ EqualsPredicate(const QString &pattern) : m_pattern(pattern) {}
+ bool operator()(const QString &s) const { return s == m_pattern; }
+ private:
+ const QString m_pattern;
+ };
+ // Predicate for a QString member signature that matches signals up with slots and vice versa
+ class SignalMatchesSlotPredicate {
+ public:
+ SignalMatchesSlotPredicate(QDesignerFormEditorInterface *core, const QString &peer, qdesigner_internal::MemberType memberType);
+ bool operator()(const QString &s) const;
+
+ private:
+ bool signalMatchesSlot(const QString &signal, const QString &slot) const;
+
+ const QString m_peer;
+ qdesigner_internal::MemberType m_memberType;
+ const QDesignerLanguageExtension *m_lang;
+ };
+
+ SignalMatchesSlotPredicate::SignalMatchesSlotPredicate(QDesignerFormEditorInterface *core, const QString &peer, qdesigner_internal::MemberType memberType) :
+ m_peer(peer),
+ m_memberType(memberType),
+ m_lang(qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core))
+ {
+ }
+
+ bool SignalMatchesSlotPredicate::operator()(const QString &s) const
+ {
+ return m_memberType == qdesigner_internal::SlotMember ? signalMatchesSlot(m_peer, s) : signalMatchesSlot(s, m_peer);
+ }
+
+ bool SignalMatchesSlotPredicate::signalMatchesSlot(const QString &signal, const QString &slot) const
+ {
+ if (m_lang)
+ return m_lang->signalMatchesSlot(signal, slot);
+
+ return QDesignerMemberSheet::signalMatchesSlot(signal, slot);
+ }
+
+ // Output iterator for a pair of pair of <classname, signature>
+ // that builds the reverse class list for reverseClassesMemberFunctions()
+ // (for the combos of the ToolWindow)
+ class ReverseClassesMemberIterator {
+ public:
+ ReverseClassesMemberIterator(qdesigner_internal::ClassesMemberFunctions *result);
+
+ ReverseClassesMemberIterator &operator*() { return *this; }
+ ReverseClassesMemberIterator &operator++(int) { return *this; }
+ ReverseClassesMemberIterator &operator++() { return *this; }
+ void operator=(const ClassNameSignaturePair &classNameSignature);
+
+ private:
+ qdesigner_internal::ClassesMemberFunctions *m_result;
+ QString m_lastClassName;
+ QStringList *m_memberList;
+ };
+
+ ReverseClassesMemberIterator::ReverseClassesMemberIterator(qdesigner_internal::ClassesMemberFunctions *result) :
+ m_result(result),
+ m_memberList(0)
+ {
+ }
+
+ void ReverseClassesMemberIterator::operator=(const ClassNameSignaturePair &classNameSignature)
+ {
+ // prepend a new entry if class changes
+ if (!m_memberList || classNameSignature.first != m_lastClassName) {
+ m_lastClassName = classNameSignature.first;
+ m_result->push_front(qdesigner_internal::ClassMemberFunctions(m_lastClassName));
+ m_memberList = &(m_result->front().m_memberList);
+ }
+ m_memberList->push_back(classNameSignature.second);
+ }
+
+ // Output iterator for a pair of pair of <classname, signature>
+ // that adds the signatures to a string list
+ class SignatureIterator {
+ public:
+ SignatureIterator(QMap<QString, QString> *result) : m_result(result) {}
+
+ SignatureIterator &operator*() { return *this; }
+ SignatureIterator &operator++(int) { return *this; }
+ SignatureIterator &operator++() { return *this; }
+ void operator=(const ClassNameSignaturePair &classNameSignature) {
+ m_result->insert(classNameSignature.second, classNameSignature.first);
+ }
+
+ private:
+ QMap<QString, QString> *m_result;
+ };
+}
+
+static inline bool truePredicate(const QString &) { return true; }
+
+namespace qdesigner_internal {
+
+ ClassMemberFunctions::ClassMemberFunctions(const QString &class_name) :
+ m_className(class_name)
+ {
+ }
+
+ bool signalMatchesSlot(QDesignerFormEditorInterface *core, const QString &signal, const QString &slot)
+ {
+ const SignalMatchesSlotPredicate predicate(core, signal, qdesigner_internal::SlotMember);
+ return predicate(slot);
+ }
+
+ // return classes and members in reverse class order to
+ // populate of the combo of the ToolWindow
+ ClassesMemberFunctions reverseClassesMemberFunctions(const QString &obj_name, MemberType member_type,
+ const QString &peer, QDesignerFormWindowInterface *form)
+ {
+ QObject *object = 0;
+ if (obj_name == form->mainContainer()->objectName()) {
+ object = form->mainContainer();
+ } else {
+ object = form->mainContainer()->findChild<QObject*>(obj_name);
+ }
+ if (!object)
+ return ClassesMemberFunctions();
+ QDesignerFormEditorInterface *core = form->core();
+
+ ClassesMemberFunctions rc;
+ memberList(form->core(), object, member_type, true, SignalMatchesSlotPredicate(core, peer, member_type),
+ ReverseClassesMemberIterator(&rc));
+ return rc;
+ }
+
+ QMap<QString, QString> getSignals(QDesignerFormEditorInterface *core, QObject *object, bool showAll)
+ {
+ QMap<QString, QString> rc;
+ memberList(core, object, SignalMember, showAll, truePredicate, SignatureIterator(&rc));
+ return rc;
+ }
+
+ bool isQt3Signal(QDesignerFormEditorInterface *core,
+ QObject *object, const QString &signalSignature)
+ {
+ if (const QDesignerMemberSheetExtension *members
+ = qt_extension<QDesignerMemberSheetExtension*>(core->extensionManager(), object)) {
+ const int count = members->count();
+ for (int i = 0; i < count; ++i)
+ if (members->isSignal(i) && members->signature(i) == signalSignature) {
+ const QDesignerMemberSheet *memberSheet
+ = qobject_cast<QDesignerMemberSheet*>(core->extensionManager()->extension(object,
+ Q_TYPEID(QDesignerMemberSheetExtension)));
+ return (memberSheet && memberSheet->isQt3Signal(i));
+ }
+ }
+
+ return false;
+ }
+
+ bool isQt3Slot(QDesignerFormEditorInterface *core,
+ QObject *object, const QString &slotSignature)
+ {
+ if (const QDesignerMemberSheetExtension *members
+ = qt_extension<QDesignerMemberSheetExtension*>(core->extensionManager(), object)) {
+ Q_ASSERT(members != 0);
+ const int count = members->count();
+ for (int i = 0; i < count; ++i)
+ if (members->isSlot(i) && members->signature(i) == slotSignature) {
+ const QDesignerMemberSheet *memberSheet
+ = qobject_cast<QDesignerMemberSheet*>(core->extensionManager()->extension(object,
+ Q_TYPEID(QDesignerMemberSheetExtension)));
+ return (memberSheet && memberSheet->isQt3Slot(i));
+ }
+ }
+ return false;
+ }
+
+ QMap<QString, QString> getMatchingSlots(QDesignerFormEditorInterface *core, QObject *object, const QString &signalSignature, bool showAll)
+ {
+ QMap<QString, QString> rc;
+ memberList(core, object, SlotMember, showAll, SignalMatchesSlotPredicate(core, signalSignature, qdesigner_internal::SlotMember), SignatureIterator(&rc));
+ return rc;
+ }
+
+ bool memberFunctionListContains(QDesignerFormEditorInterface *core, QObject *object, MemberType type, const QString &signature)
+ {
+ QMap<QString, QString> rc;
+ memberList(core, object, type, true, EqualsPredicate(signature), SignatureIterator(&rc));
+ return !rc.empty();
+ }
+
+ // ### deprecated
+ QString realObjectName(QDesignerFormEditorInterface *core, QObject *object)
+ {
+ if (!object)
+ return QString();
+
+ const QDesignerMetaDataBaseInterface *mdb = core->metaDataBase();
+ if (const QDesignerMetaDataBaseItemInterface *item = mdb->item(object))
+ return item->name();
+
+ return object->objectName();
+ }
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/signalsloteditor/signalslot_utils_p.h b/src/designer/src/components/signalsloteditor/signalslot_utils_p.h
new file mode 100644
index 000000000..0bc434c98
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalslot_utils_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIGNALSLOTUTILS_P_H
+#define SIGNALSLOTUTILS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+enum MemberType { SignalMember, SlotMember };
+
+// member to class name
+QMap<QString, QString> getSignals(QDesignerFormEditorInterface *core, QObject *object, bool showAll);
+QMap<QString, QString> getMatchingSlots(QDesignerFormEditorInterface *core, QObject *object,
+ const QString &signalSignature, bool showAll);
+
+bool memberFunctionListContains(QDesignerFormEditorInterface *core, QObject *object, MemberType type, const QString &signature);
+
+// Members functions listed by class they were inherited from
+struct ClassMemberFunctions
+{
+ ClassMemberFunctions() {}
+ ClassMemberFunctions(const QString &_class_name);
+
+ QString m_className;
+ QStringList m_memberList;
+};
+
+typedef QList<ClassMemberFunctions> ClassesMemberFunctions;
+
+// Return classes and members in reverse class order to
+// populate of the combo of the ToolWindow.
+
+ClassesMemberFunctions reverseClassesMemberFunctions(const QString &obj_name, MemberType member_type,
+ const QString &peer, QDesignerFormWindowInterface *form);
+
+bool signalMatchesSlot(QDesignerFormEditorInterface *core, const QString &signal, const QString &slot);
+
+QString realObjectName(QDesignerFormEditorInterface *core, QObject *object);
+
+bool isQt3Signal(QDesignerFormEditorInterface *core, QObject *object, const QString &signalSignature);
+bool isQt3Slot(QDesignerFormEditorInterface *core, QObject *object, const QString &signalSignature);
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SIGNALSLOTUTILS_P_H
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor.cpp b/src/designer/src/components/signalsloteditor/signalsloteditor.cpp
new file mode 100644
index 000000000..673864032
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor.cpp
@@ -0,0 +1,528 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "signalsloteditor.h"
+#include "signalsloteditor_p.h"
+#include "connectdialog_p.h"
+#include "signalslot_utils_p.h"
+
+#include <metadatabase_p.h>
+#include <ui4_p.h>
+#include <qdesigner_formwindowcommand_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+
+#include <QtGui/QApplication>
+#include <QtGui/QUndoCommand>
+#include <QtGui/QMenu>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+/*******************************************************************************
+** SignalSlotConnection
+*/
+
+SignalSlotConnection::SignalSlotConnection(ConnectionEdit *edit, QWidget *source, QWidget *target)
+ : Connection(edit, source, target)
+{
+}
+
+DomConnection *SignalSlotConnection::toUi() const
+{
+ DomConnection *result = new DomConnection;
+
+ result->setElementSender(sender());
+ result->setElementSignal(signal());
+ result->setElementReceiver(receiver());
+ result->setElementSlot(slot());
+
+ DomConnectionHints *hints = new DomConnectionHints;
+ QList<DomConnectionHint*> list;
+
+ QPoint sp = endPointPos(EndPoint::Source);
+ QPoint tp = endPointPos(EndPoint::Target);
+
+ DomConnectionHint *hint = new DomConnectionHint;
+ hint->setAttributeType(QLatin1String("sourcelabel"));
+ hint->setElementX(sp.x());
+ hint->setElementY(sp.y());
+ list.append(hint);
+
+ hint = new DomConnectionHint;
+ hint->setAttributeType(QLatin1String("destinationlabel"));
+ hint->setElementX(tp.x());
+ hint->setElementY(tp.y());
+ list.append(hint);
+
+ hints->setElementHint(list);
+ result->setElementHints(hints);
+
+ return result;
+}
+
+void SignalSlotConnection::setSignal(const QString &signal)
+{
+ m_signal = signal;
+ setLabel(EndPoint::Source, m_signal);
+}
+
+void SignalSlotConnection::setSlot(const QString &slot)
+{
+ m_slot = slot;
+ setLabel(EndPoint::Target, m_slot);
+}
+
+QString SignalSlotConnection::sender() const
+{
+ QObject *source = object(EndPoint::Source);
+ if (!source)
+ return QString();
+
+ SignalSlotEditor *edit = qobject_cast<SignalSlotEditor*>(this->edit());
+ Q_ASSERT(edit != 0);
+
+ return realObjectName(edit->formWindow()->core(), source);
+}
+
+QString SignalSlotConnection::receiver() const
+{
+ QObject *sink = object(EndPoint::Target);
+ if (!sink)
+ return QString();
+
+ SignalSlotEditor *edit = qobject_cast<SignalSlotEditor*>(this->edit());
+ Q_ASSERT(edit != 0);
+ return realObjectName(edit->formWindow()->core(), sink);
+}
+
+void SignalSlotConnection::updateVisibility()
+{
+ Connection::updateVisibility();
+ if (isVisible() && (signal().isEmpty() || slot().isEmpty()))
+ setVisible(false);
+}
+
+QString SignalSlotConnection::toString() const
+{
+ return QCoreApplication::translate("SignalSlotConnection", "SENDER(%1), SIGNAL(%2), RECEIVER(%3), SLOT(%4)")
+ .arg(sender()).arg(signal()).arg(receiver()).arg(slot());
+}
+
+SignalSlotConnection::State SignalSlotConnection::isValid(const QWidget *background) const
+{
+ const QObject *source = object(EndPoint::Source);
+ if (!source)
+ return ObjectDeleted;
+
+ const QObject *target = object(EndPoint::Target);
+ if (!target)
+ return ObjectDeleted;
+
+ if (m_slot.isEmpty() || m_signal.isEmpty())
+ return InvalidMethod;
+
+ if (const QWidget *sourceWidget = qobject_cast<const QWidget*>(source))
+ if (!background->isAncestorOf(sourceWidget))
+ return NotAncestor;
+
+ if (const QWidget *targetWidget = qobject_cast<const QWidget*>(target))
+ if (!background->isAncestorOf(targetWidget))
+ return NotAncestor;
+
+ return Valid;
+}
+
+/*******************************************************************************
+** Commands
+*/
+
+class SetMemberCommand : public QUndoCommand, public CETypes
+{
+public:
+ SetMemberCommand(SignalSlotConnection *con, EndPoint::Type type,
+ const QString &member, SignalSlotEditor *editor);
+ virtual void redo();
+ virtual void undo();
+private:
+ const QString m_old_member;
+ const QString m_new_member;
+ const EndPoint::Type m_type;
+ SignalSlotConnection *m_con;
+ SignalSlotEditor *m_editor;
+};
+
+SetMemberCommand::SetMemberCommand(SignalSlotConnection *con, EndPoint::Type type,
+ const QString &member, SignalSlotEditor *editor) :
+ m_old_member(type == EndPoint::Source ? con->signal() : con->slot()),
+ m_new_member(member),
+ m_type(type),
+ m_con(con),
+ m_editor(editor)
+{
+ if (type == EndPoint::Source)
+ setText(QApplication::translate("Command", "Change signal"));
+ else
+ setText(QApplication::translate("Command", "Change slot"));
+}
+
+void SetMemberCommand::redo()
+{
+ m_con->update();
+ if (m_type == EndPoint::Source)
+ m_con->setSignal(m_new_member);
+ else
+ m_con->setSlot(m_new_member);
+ m_con->update();
+ emit m_editor->connectionChanged(m_con);
+}
+
+void SetMemberCommand::undo()
+{
+ m_con->update();
+ if (m_type == EndPoint::Source)
+ m_con->setSignal(m_old_member);
+ else
+ m_con->setSlot(m_old_member);
+ m_con->update();
+ emit m_editor->connectionChanged(m_con);
+}
+
+// Command to modify a connection
+class ModifyConnectionCommand : public QDesignerFormWindowCommand
+{
+public:
+ explicit ModifyConnectionCommand(QDesignerFormWindowInterface *form,
+ SignalSlotConnection *conn,
+ const QString &newSignal,
+ const QString &newSlot);
+ virtual void redo();
+ virtual void undo();
+
+private:
+ SignalSlotConnection *m_conn;
+ const QString m_oldSignal;
+ const QString m_oldSlot;
+ const QString m_newSignal;
+ const QString m_newSlot;
+};
+
+ModifyConnectionCommand::ModifyConnectionCommand(QDesignerFormWindowInterface *form,
+ SignalSlotConnection *conn,
+ const QString &newSignal,
+ const QString &newSlot) :
+ QDesignerFormWindowCommand(QCoreApplication::translate("Command", "Change signal-slot connection"), form),
+ m_conn(conn),
+ m_oldSignal(conn->signal()),
+ m_oldSlot(conn->slot()),
+ m_newSignal(newSignal),
+ m_newSlot(newSlot)
+{
+}
+
+void ModifyConnectionCommand::redo()
+{
+ m_conn->setSignal(m_newSignal);
+ m_conn->setSlot(m_newSlot);
+}
+
+void ModifyConnectionCommand::undo()
+{
+ m_conn->setSignal(m_oldSignal);
+ m_conn->setSlot(m_oldSlot);
+}
+
+/*******************************************************************************
+** SignalSlotEditor
+*/
+
+SignalSlotEditor::SignalSlotEditor(QDesignerFormWindowInterface *form_window, QWidget *parent) :
+ ConnectionEdit(parent, form_window),
+ m_form_window(form_window),
+ m_showAllSignalsSlots(false)
+{
+}
+
+void SignalSlotEditor::modifyConnection(Connection *con)
+{
+ SignalSlotConnection *sigslot_con = static_cast<SignalSlotConnection*>(con);
+ ConnectDialog dialog(m_form_window,
+ sigslot_con->widget(EndPoint::Source),
+ sigslot_con->widget(EndPoint::Target),
+ m_form_window->core()->topLevel());
+
+ dialog.setSignalSlot(sigslot_con->signal(), sigslot_con->slot());
+ dialog.setShowAllSignalsSlots(m_showAllSignalsSlots);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ const QString newSignal = dialog.signal();
+ const QString newSlot = dialog.slot();
+ if (sigslot_con->signal() != newSignal || sigslot_con->slot() != newSlot) {
+ ModifyConnectionCommand *cmd = new ModifyConnectionCommand(m_form_window, sigslot_con, newSignal, newSlot);
+ m_form_window->commandHistory()->push(cmd);
+ }
+ }
+
+ m_showAllSignalsSlots = dialog.showAllSignalsSlots();
+}
+
+Connection *SignalSlotEditor::createConnection(QWidget *source, QWidget *destination)
+{
+ SignalSlotConnection *con = 0;
+
+ Q_ASSERT(source != 0);
+ Q_ASSERT(destination != 0);
+
+ ConnectDialog dialog(m_form_window, source, destination, m_form_window->core()->topLevel());
+ dialog.setShowAllSignalsSlots(m_showAllSignalsSlots);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ con = new SignalSlotConnection(this, source, destination);
+ con->setSignal(dialog.signal());
+ con->setSlot(dialog.slot());
+ }
+
+ m_showAllSignalsSlots = dialog.showAllSignalsSlots();
+
+ return con;
+}
+
+DomConnections *SignalSlotEditor::toUi() const
+{
+ DomConnections *result = new DomConnections;
+ QList<DomConnection*> list;
+
+ const int count = connectionCount();
+ for (int i = 0; i < count; ++i) {
+ const SignalSlotConnection *con = static_cast<const SignalSlotConnection*>(connection(i));
+ Q_ASSERT(con != 0);
+
+ // If a widget's parent has been removed or moved to a different form,
+ // and the parent was not a managed widget
+ // (a page in a tab widget), we never get a widgetRemoved(). So we filter out
+ // these child widgets here (check QPointer and verify ancestor).
+ // Also, the user might demote a promoted widget or remove a fake
+ // slot in the editor, which causes the connection to become invalid
+ // once he doubleclicks on the method combo.
+ switch (con->isValid(background())) {
+ case SignalSlotConnection::Valid:
+ list.append(con->toUi());
+ break;
+ case SignalSlotConnection::ObjectDeleted:
+ case SignalSlotConnection::InvalidMethod:
+ case SignalSlotConnection::NotAncestor:
+ break;
+ }
+ }
+ result->setElementConnection(list);
+ return result;
+}
+
+QObject *SignalSlotEditor::objectByName(QWidget *topLevel, const QString &name) const
+{
+ if (name.isEmpty())
+ return 0;
+
+ Q_ASSERT(topLevel);
+ QObject *object = 0;
+ if (topLevel->objectName() == name)
+ object = topLevel;
+ else
+ object = topLevel->findChild<QObject*>(name);
+ const QDesignerMetaDataBaseInterface *mdb = formWindow()->core()->metaDataBase();
+ if (mdb->item(object))
+ return object;
+ return 0;
+}
+
+void SignalSlotEditor::fromUi(const DomConnections *connections, QWidget *parent)
+{
+ if (connections == 0)
+ return;
+
+ setBackground(parent);
+ clear();
+ const QList<DomConnection*> list = connections->elementConnection();
+ foreach (const DomConnection *dom_con, list) {
+ QObject *source = objectByName(parent, dom_con->elementSender());
+ if (source == 0) {
+ qDebug("SignalSlotEditor::fromUi(): no source widget called \"%s\"",
+ dom_con->elementSender().toUtf8().constData());
+ continue;
+ }
+ QObject *destination = objectByName(parent, dom_con->elementReceiver());
+ if (destination == 0) {
+ qDebug("SignalSlotEditor::fromUi(): no destination widget called \"%s\"",
+ dom_con->elementReceiver().toUtf8().constData());
+ continue;
+ }
+
+ QPoint sp = QPoint(20, 20), tp = QPoint(20, 20);
+ const DomConnectionHints *dom_hints = dom_con->elementHints();
+ if (dom_hints != 0) {
+ QList<DomConnectionHint*> list = dom_hints->elementHint();
+ foreach (DomConnectionHint *hint, list) {
+ QString attr_type = hint->attributeType();
+ QPoint p = QPoint(hint->elementX(), hint->elementY());
+ if (attr_type == QLatin1String("sourcelabel"))
+ sp = p;
+ else if (attr_type == QLatin1String("destinationlabel"))
+ tp = p;
+ }
+ }
+
+ SignalSlotConnection *con = new SignalSlotConnection(this);
+
+ con->setEndPoint(EndPoint::Source, source, sp);
+ con->setEndPoint(EndPoint::Target, destination, tp);
+ con->setSignal(dom_con->elementSignal());
+ con->setSlot(dom_con->elementSlot());
+ addConnection(con);
+ }
+}
+
+static bool skipWidget(const QWidget *w)
+{
+ const QString name = QLatin1String(w->metaObject()->className());
+ if (name == QLatin1String("QDesignerWidget"))
+ return true;
+ if (name == QLatin1String("QLayoutWidget"))
+ return true;
+ if (name == QLatin1String("qdesigner_internal::FormWindow"))
+ return true;
+ if (name == QLatin1String("Spacer"))
+ return true;
+ return false;
+}
+
+QWidget *SignalSlotEditor::widgetAt(const QPoint &pos) const
+{
+ QWidget *widget = ConnectionEdit::widgetAt(pos);
+
+ if (widget == m_form_window->mainContainer())
+ return widget;
+
+ for (; widget != 0; widget = widget->parentWidget()) {
+ QDesignerMetaDataBaseItemInterface *item = m_form_window->core()->metaDataBase()->item(widget);
+ if (item == 0)
+ continue;
+ if (skipWidget(widget))
+ continue;
+ break;
+ }
+
+ return widget;
+}
+
+void SignalSlotEditor::setSignal(SignalSlotConnection *con, const QString &member)
+{
+ if (member == con->signal())
+ return;
+
+ m_form_window->beginCommand(QApplication::translate("Command", "Change signal"));
+ undoStack()->push(new SetMemberCommand(con, EndPoint::Source, member, this));
+ if (!signalMatchesSlot(m_form_window->core(), member, con->slot()))
+ undoStack()->push(new SetMemberCommand(con, EndPoint::Target, QString(), this));
+ m_form_window->endCommand();
+}
+
+void SignalSlotEditor::setSlot(SignalSlotConnection *con, const QString &member)
+{
+ if (member == con->slot())
+ return;
+
+ m_form_window->beginCommand(QApplication::translate("Command", "Change slot"));
+ undoStack()->push(new SetMemberCommand(con, EndPoint::Target, member, this));
+ if (!signalMatchesSlot(m_form_window->core(), con->signal(), member))
+ undoStack()->push(new SetMemberCommand(con, EndPoint::Source, QString(), this));
+ m_form_window->endCommand();
+}
+
+void SignalSlotEditor::setSource(Connection *_con, const QString &obj_name)
+{
+ SignalSlotConnection *con = static_cast<SignalSlotConnection*>(_con);
+
+ if (con->sender() == obj_name)
+ return;
+
+ m_form_window->beginCommand(QApplication::translate("Command", "Change sender"));
+ ConnectionEdit::setSource(con, obj_name);
+
+ QObject *sourceObject = con->object(EndPoint::Source);
+
+ if (!memberFunctionListContains(m_form_window->core(), sourceObject, SignalMember, con->signal()))
+ undoStack()->push(new SetMemberCommand(con, EndPoint::Source, QString(), this));
+
+ m_form_window->endCommand();
+}
+
+void SignalSlotEditor::setTarget(Connection *_con, const QString &obj_name)
+{
+ SignalSlotConnection *con = static_cast<SignalSlotConnection*>(_con);
+
+ if (con->receiver() == obj_name)
+ return;
+
+ m_form_window->beginCommand(QApplication::translate("Command", "Change receiver"));
+ ConnectionEdit::setTarget(con, obj_name);
+
+ QObject *targetObject = con->object(EndPoint::Target);
+ if (!memberFunctionListContains(m_form_window->core(), targetObject, SlotMember, con->slot()))
+ undoStack()->push(new SetMemberCommand(con, EndPoint::Target, QString(), this));
+
+ m_form_window->endCommand();
+}
+
+void SignalSlotEditor::addEmptyConnection()
+{
+ SignalSlotConnection *con = new SignalSlotConnection(this);
+ undoStack()->push(new AddConnectionCommand(this, con));
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor.h b/src/designer/src/components/signalsloteditor/signalsloteditor.h
new file mode 100644
index 000000000..fca358760
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIGNALSLOTEDITOR_H
+#define SIGNALSLOTEDITOR_H
+
+#include "signalsloteditor_global.h"
+
+#include <QtDesigner/private/connectionedit_p.h>
+
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomElement>
+
+QT_BEGIN_NAMESPACE
+
+class DomConnections;
+
+namespace qdesigner_internal {
+
+class SignalSlotConnection;
+
+class QT_SIGNALSLOTEDITOR_EXPORT SignalSlotEditor : public ConnectionEdit
+{
+ Q_OBJECT
+
+public:
+ SignalSlotEditor(QDesignerFormWindowInterface *form_window, QWidget *parent);
+
+ virtual void setSignal(SignalSlotConnection *con, const QString &member);
+ virtual void setSlot(SignalSlotConnection *con, const QString &member);
+ virtual void setSource(Connection *con, const QString &obj_name);
+ virtual void setTarget(Connection *con, const QString &obj_name);
+
+ DomConnections *toUi() const;
+ void fromUi(const DomConnections *connections, QWidget *parent);
+
+ QDesignerFormWindowInterface *formWindow() const { return m_form_window; }
+
+ QObject *objectByName(QWidget *topLevel, const QString &name) const;
+
+ void addEmptyConnection();
+
+protected:
+ virtual QWidget *widgetAt(const QPoint &pos) const;
+
+private:
+ virtual Connection *createConnection(QWidget *source, QWidget *destination);
+ virtual void modifyConnection(Connection *con);
+
+ QDesignerFormWindowInterface *m_form_window;
+ bool m_showAllSignalsSlots;
+
+ friend class SetMemberCommand;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SIGNALSLOTEDITOR_H
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor.pri b/src/designer/src/components/signalsloteditor/signalsloteditor.pri
new file mode 100644
index 000000000..e903ce114
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor.pri
@@ -0,0 +1,21 @@
+
+INCLUDEPATH += $$PWD
+
+HEADERS += $$PWD/signalslot_utils_p.h \
+ $$PWD/connectdialog_p.h \
+ $$PWD/signalsloteditor.h \
+ $$PWD/signalsloteditor_tool.h \
+ $$PWD/signalsloteditor_plugin.h \
+ $$PWD/signalsloteditor_global.h \
+ $$PWD/signalsloteditor_p.h \
+ $$PWD/signalsloteditorwindow.h
+
+SOURCES += $$PWD/signalslot_utils.cpp \
+ $$PWD/connectdialog.cpp \
+ $$PWD/signalsloteditor.cpp \
+ $$PWD/signalsloteditor_tool.cpp \
+ $$PWD/signalsloteditor_plugin.cpp \
+ $$PWD/signalsloteditor_instance.cpp \
+ $$PWD/signalsloteditorwindow.cpp
+
+FORMS += $$PWD/connectdialog.ui
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor_global.h b/src/designer/src/components/signalsloteditor/signalsloteditor_global.h
new file mode 100644
index 000000000..122a32a92
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor_global.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIGNALSLOTEDITOR_GLOBAL_H
+#define SIGNALSLOTEDITOR_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN
+#ifdef QT_SIGNALSLOTEDITOR_LIBRARY
+# define QT_SIGNALSLOTEDITOR_EXPORT
+#else
+# define QT_SIGNALSLOTEDITOR_EXPORT
+#endif
+#else
+#define QT_SIGNALSLOTEDITOR_EXPORT
+#endif
+
+#endif // SIGNALSLOTEDITOR_GLOBAL_H
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor_instance.cpp b/src/designer/src/components/signalsloteditor/signalsloteditor_instance.cpp
new file mode 100644
index 000000000..6c2aa3c11
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor_instance.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qplugin.h>
+
+#include "signalsloteditor_plugin.h"
+
+QT_USE_NAMESPACE
+
+using namespace qdesigner_internal;
+
+Q_EXPORT_PLUGIN(SignalSlotEditorPlugin)
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor_p.h b/src/designer/src/components/signalsloteditor/signalsloteditor_p.h
new file mode 100644
index 000000000..bd01c2ef1
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIGNALSLOTEDITOR_P_H
+#define SIGNALSLOTEDITOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+#include <QtCore/QAbstractItemModel>
+
+#include <connectionedit_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+class DomConnection;
+
+namespace qdesigner_internal {
+
+class SignalSlotEditor;
+
+class SignalSlotConnection : public Connection
+{
+public:
+ explicit SignalSlotConnection(ConnectionEdit *edit, QWidget *source = 0, QWidget *target = 0);
+
+ void setSignal(const QString &signal);
+ void setSlot(const QString &slot);
+
+ QString sender() const;
+ QString receiver() const;
+ inline QString signal() const { return m_signal; }
+ inline QString slot() const { return m_slot; }
+
+ DomConnection *toUi() const;
+
+ virtual void updateVisibility();
+
+ enum State { Valid, ObjectDeleted, InvalidMethod, NotAncestor };
+ State isValid(const QWidget *background) const;
+
+ // format for messages, etc.
+ QString toString() const;
+
+private:
+ QString m_signal, m_slot;
+};
+
+class ConnectionModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ explicit ConnectionModel(QObject *parent = 0);
+ void setEditor(SignalSlotEditor *editor = 0);
+
+ virtual QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex parent(const QModelIndex &child) const;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &data, int role = Qt::DisplayRole);
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+
+ QModelIndex connectionToIndex(Connection *con) const;
+ Connection *indexToConnection(const QModelIndex &index) const;
+ void updateAll();
+
+private slots:
+ void connectionAdded(Connection *con);
+ void connectionRemoved(int idx);
+ void aboutToRemoveConnection(Connection *con);
+ void aboutToAddConnection(int idx);
+ void connectionChanged(Connection *con);
+
+private:
+ QPointer<SignalSlotEditor> m_editor;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SIGNALSLOTEDITOR_P_H
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp b/src/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
new file mode 100644
index 000000000..7e1f67f08
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "signalsloteditor_plugin.h"
+#include "signalsloteditor_tool.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+#include <QtGui/QAction>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+SignalSlotEditorPlugin::SignalSlotEditorPlugin()
+ : m_initialized(false), m_action(0)
+{
+}
+
+SignalSlotEditorPlugin::~SignalSlotEditorPlugin()
+{
+}
+
+bool SignalSlotEditorPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void SignalSlotEditorPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_ASSERT(!isInitialized());
+
+ m_action = new QAction(tr("Edit Signals/Slots"), this);
+ m_action->setObjectName(QLatin1String("__qt_edit_signals_slots_action"));
+ m_action->setShortcut(tr("F4"));
+ QIcon icon = QIcon::fromTheme("designer-edit-signals",
+ QIcon(core->resourceLocation() + QLatin1String("/signalslottool.png")));
+ m_action->setIcon(icon);
+ m_action->setEnabled(false);
+
+ setParent(core);
+ m_core = core;
+ m_initialized = true;
+
+ connect(core->formWindowManager(), SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)),
+ this, SLOT(addFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core->formWindowManager(), SIGNAL(formWindowRemoved(QDesignerFormWindowInterface*)),
+ this, SLOT(removeFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface*)));
+}
+
+QDesignerFormEditorInterface *SignalSlotEditorPlugin::core() const
+{
+ return m_core;
+}
+
+void SignalSlotEditorPlugin::addFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_ASSERT(formWindow != 0);
+ Q_ASSERT(m_tools.contains(formWindow) == false);
+
+ SignalSlotEditorTool *tool = new SignalSlotEditorTool(formWindow, this);
+ connect(m_action, SIGNAL(triggered()), tool->action(), SLOT(trigger()));
+ m_tools[formWindow] = tool;
+ formWindow->registerTool(tool);
+}
+
+void SignalSlotEditorPlugin::removeFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_ASSERT(formWindow != 0);
+ Q_ASSERT(m_tools.contains(formWindow) == true);
+
+ SignalSlotEditorTool *tool = m_tools.value(formWindow);
+ m_tools.remove(formWindow);
+ disconnect(m_action, SIGNAL(triggered()), tool->action(), SLOT(trigger()));
+ // ### FIXME disable the tool
+
+ delete tool;
+}
+
+QAction *SignalSlotEditorPlugin::action() const
+{
+ return m_action;
+}
+
+void SignalSlotEditorPlugin::activeFormWindowChanged(QDesignerFormWindowInterface *formWindow)
+{
+ m_action->setEnabled(formWindow != 0);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor_plugin.h b/src/designer/src/components/signalsloteditor/signalsloteditor_plugin.h
new file mode 100644
index 000000000..7ef5e2f5b
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor_plugin.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIGNALSLOTEDITOR_PLUGIN_H
+#define SIGNALSLOTEDITOR_PLUGIN_H
+
+#include "signalsloteditor_global.h"
+
+#include <QtDesigner/QDesignerFormEditorPluginInterface>
+
+#include <QtCore/QPointer>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class SignalSlotEditorTool;
+
+class QT_SIGNALSLOTEDITOR_EXPORT SignalSlotEditorPlugin: public QObject, public QDesignerFormEditorPluginInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerFormEditorPluginInterface)
+public:
+ SignalSlotEditorPlugin();
+ virtual ~SignalSlotEditorPlugin();
+
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QAction *action() const;
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+public slots:
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+
+private slots:
+ void addFormWindow(QDesignerFormWindowInterface *formWindow);
+ void removeFormWindow(QDesignerFormWindowInterface *formWindow);
+
+private:
+ QPointer<QDesignerFormEditorInterface> m_core;
+ QHash<QDesignerFormWindowInterface*, SignalSlotEditorTool*> m_tools;
+ bool m_initialized;
+ QAction *m_action;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SIGNALSLOTEDITOR_PLUGIN_H
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp b/src/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp
new file mode 100644
index 000000000..a56acc37d
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "signalsloteditor_tool.h"
+#include "signalsloteditor.h"
+#include "ui4_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+SignalSlotEditorTool::SignalSlotEditorTool(QDesignerFormWindowInterface *formWindow, QObject *parent)
+ : QDesignerFormWindowToolInterface(parent),
+ m_formWindow(formWindow),
+ m_action(new QAction(tr("Edit Signals/Slots"), this))
+{
+}
+
+SignalSlotEditorTool::~SignalSlotEditorTool()
+{
+}
+
+QDesignerFormEditorInterface *SignalSlotEditorTool::core() const
+{
+ return m_formWindow->core();
+}
+
+QDesignerFormWindowInterface *SignalSlotEditorTool::formWindow() const
+{
+ return m_formWindow;
+}
+
+bool SignalSlotEditorTool::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(managedWidget);
+ Q_UNUSED(event);
+
+ return false;
+}
+
+QWidget *SignalSlotEditorTool::editor() const
+{
+ if (!m_editor) {
+ Q_ASSERT(formWindow() != 0);
+ m_editor = new qdesigner_internal::SignalSlotEditor(formWindow(), 0);
+ connect(formWindow(), SIGNAL(mainContainerChanged(QWidget*)), m_editor, SLOT(setBackground(QWidget*)));
+ connect(formWindow(), SIGNAL(changed()),
+ m_editor, SLOT(updateBackground()));
+ }
+
+ return m_editor;
+}
+
+QAction *SignalSlotEditorTool::action() const
+{
+ return m_action;
+}
+
+void SignalSlotEditorTool::activated()
+{
+ m_editor->enableUpdateBackground(true);
+}
+
+void SignalSlotEditorTool::deactivated()
+{
+ m_editor->enableUpdateBackground(false);
+}
+
+void SignalSlotEditorTool::saveToDom(DomUI *ui, QWidget*)
+{
+ ui->setElementConnections(m_editor->toUi());
+}
+
+void SignalSlotEditorTool::loadFromDom(DomUI *ui, QWidget *mainContainer)
+{
+ m_editor->fromUi(ui->elementConnections(), mainContainer);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditor_tool.h b/src/designer/src/components/signalsloteditor/signalsloteditor_tool.h
new file mode 100644
index 000000000..89b861ed3
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditor_tool.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIGNALSLOTEDITOR_TOOL_H
+#define SIGNALSLOTEDITOR_TOOL_H
+
+#include "signalsloteditor_global.h"
+#include "signalsloteditor.h"
+
+#include <QtCore/QPointer>
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QAction;
+
+namespace qdesigner_internal {
+
+class SignalSlotEditor;
+
+class QT_SIGNALSLOTEDITOR_EXPORT SignalSlotEditorTool: public QDesignerFormWindowToolInterface
+{
+ Q_OBJECT
+public:
+ explicit SignalSlotEditorTool(QDesignerFormWindowInterface *formWindow, QObject *parent = 0);
+ virtual ~SignalSlotEditorTool();
+
+ virtual QDesignerFormEditorInterface *core() const;
+ virtual QDesignerFormWindowInterface *formWindow() const;
+
+ virtual QWidget *editor() const;
+
+ QAction *action() const;
+
+ virtual void activated();
+ virtual void deactivated();
+
+ virtual bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event);
+
+ virtual void saveToDom(DomUI *ui, QWidget *mainContainer);
+ virtual void loadFromDom(DomUI *ui, QWidget *mainContainer);
+
+private:
+ QDesignerFormWindowInterface *m_formWindow;
+ mutable QPointer<qdesigner_internal::SignalSlotEditor> m_editor;
+ QAction *m_action;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SIGNALSLOTEDITOR_TOOL_H
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp b/src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
new file mode 100644
index 000000000..b06a66f2c
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
@@ -0,0 +1,864 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "signalsloteditorwindow.h"
+#include "signalsloteditor_p.h"
+#include "signalsloteditor.h"
+#include "qdesigner_integration_p.h"
+#include "signalslot_utils_p.h"
+
+#include <iconloader_p.h>
+#include <spacer_widget_p.h>
+#include <qlayout_widget_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <abstractdialoggui_p.h>
+
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QDebug>
+#include <QtGui/QAction>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QMenu>
+#include <QtGui/QSortFilterProxyModel>
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QComboBox>
+#include <QtGui/QApplication>
+#include <QtGui/QItemDelegate>
+#include <QtGui/QItemEditorFactory>
+#include <QtGui/QTreeView>
+#include <QtGui/QHeaderView>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QToolButton>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QToolBar>
+
+QT_BEGIN_NAMESPACE
+
+// Add suitable form widgets to a list of objects for the signal slot
+// editor. Prevent special widgets from showing up there.
+static void addWidgetToObjectList(const QWidget *w, QStringList &r)
+{
+ const QMetaObject *mo = w->metaObject();
+ if (mo != &QLayoutWidget::staticMetaObject && mo != &Spacer::staticMetaObject) {
+ const QString name = w->objectName().trimmed();
+ if (!name.isEmpty())
+ r.push_back(name);
+ }
+}
+
+static QStringList objectNameList(QDesignerFormWindowInterface *form)
+{
+ typedef QList<QAction*> ActionList;
+ typedef QList<QButtonGroup *> ButtonGroupList;
+
+ QStringList result;
+
+ QWidget *mainContainer = form->mainContainer();
+ if (!mainContainer)
+ return result;
+
+ // Add main container container pages (QStatusBar, QWizardPages) etc.
+ // to the list. Pages of containers on the form are not added, however.
+ if (const QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension *>(form->core()->extensionManager(), mainContainer)) {
+ const int count = c->count();
+ for (int i = 0 ; i < count; i++)
+ addWidgetToObjectList(c->widget(i), result);
+ }
+
+ const QDesignerFormWindowCursorInterface *cursor = form->cursor();
+ const int widgetCount = cursor->widgetCount();
+ for (int i = 0; i < widgetCount; ++i)
+ addWidgetToObjectList(cursor->widget(i), result);
+
+ const QDesignerMetaDataBaseInterface *mdb = form->core()->metaDataBase();
+
+ // Add managed actions and actions with managed menus
+ const ActionList actions = mainContainer->findChildren<QAction*>();
+ if (!actions.empty()) {
+ const ActionList::const_iterator cend = actions.constEnd();
+ for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it) {
+ QAction *a = *it;
+ if (!a->isSeparator()) {
+ if (QMenu *menu = a->menu()) {
+ if (mdb->item(menu))
+ result.push_back(menu->objectName());
+ } else {
+ if (mdb->item(a))
+ result.push_back(a->objectName());
+ }
+ }
+ }
+ }
+
+ // Add managed buttons groups
+ const ButtonGroupList buttonGroups = mainContainer->findChildren<QButtonGroup *>();
+ if (!buttonGroups.empty()) {
+ const ButtonGroupList::const_iterator cend = buttonGroups.constEnd();
+ for (ButtonGroupList::const_iterator it = buttonGroups.constBegin(); it != cend; ++it)
+ if (mdb->item(*it))
+ result.append((*it)->objectName());
+ }
+
+ result.sort();
+ return result;
+}
+
+namespace qdesigner_internal {
+
+// ------------ ConnectionModel
+
+ConnectionModel::ConnectionModel(QObject *parent) :
+ QAbstractItemModel(parent)
+{
+}
+
+void ConnectionModel::setEditor(SignalSlotEditor *editor)
+{
+ if (m_editor == editor)
+ return;
+
+ if (m_editor) {
+ disconnect(m_editor, SIGNAL(connectionAdded(Connection*)),
+ this, SLOT(connectionAdded(Connection*)));
+ disconnect(m_editor, SIGNAL(connectionRemoved(int)),
+ this, SLOT(connectionRemoved(int)));
+ disconnect(m_editor, SIGNAL(aboutToRemoveConnection(Connection*)),
+ this, SLOT(aboutToRemoveConnection(Connection*)));
+ disconnect(m_editor, SIGNAL(aboutToAddConnection(int)),
+ this, SLOT(aboutToAddConnection(int)));
+ disconnect(m_editor, SIGNAL(connectionChanged(Connection*)),
+ this, SLOT(connectionChanged(Connection*)));
+ }
+ m_editor = editor;
+ if (m_editor) {
+ connect(m_editor, SIGNAL(connectionAdded(Connection*)),
+ this, SLOT(connectionAdded(Connection*)));
+ connect(m_editor, SIGNAL(connectionRemoved(int)),
+ this, SLOT(connectionRemoved(int)));
+ connect(m_editor, SIGNAL(aboutToRemoveConnection(Connection*)),
+ this, SLOT(aboutToRemoveConnection(Connection*)));
+ connect(m_editor, SIGNAL(aboutToAddConnection(int)),
+ this, SLOT(aboutToAddConnection(int)));
+ connect(m_editor, SIGNAL(connectionChanged(Connection*)),
+ this, SLOT(connectionChanged(Connection*)));
+ }
+ reset();
+}
+
+QVariant ConnectionModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (orientation == Qt::Vertical || role != Qt::DisplayRole)
+ return QVariant();
+
+ static const QVariant senderTitle = tr("Sender");
+ static const QVariant signalTitle = tr("Signal");
+ static const QVariant receiverTitle = tr("Receiver");
+ static const QVariant slotTitle = tr("Slot");
+
+ switch (section) {
+ case 0:
+ return senderTitle;
+ case 1:
+ return signalTitle;
+ case 2:
+ return receiverTitle;
+ case 3:
+ return slotTitle;
+ }
+ return QVariant();
+}
+
+QModelIndex ConnectionModel::index(int row, int column,
+ const QModelIndex &parent) const
+{
+ if (parent.isValid() || !m_editor)
+ return QModelIndex();
+ if (row < 0 || row >= m_editor->connectionCount())
+ return QModelIndex();
+ return createIndex(row, column);
+}
+
+Connection *ConnectionModel::indexToConnection(const QModelIndex &index) const
+{
+ if (!index.isValid() || !m_editor)
+ return 0;
+ if (index.row() < 0 || index.row() >= m_editor->connectionCount())
+ return 0;
+ return m_editor->connection(index.row());
+}
+
+QModelIndex ConnectionModel::connectionToIndex(Connection *con) const
+{
+ Q_ASSERT(m_editor);
+ return createIndex(m_editor->indexOfConnection(con), 0);
+}
+
+QModelIndex ConnectionModel::parent(const QModelIndex&) const
+{
+ return QModelIndex();
+}
+
+int ConnectionModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid() || !m_editor)
+ return 0;
+ return m_editor->connectionCount();
+}
+
+int ConnectionModel::columnCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+ return 4;
+}
+
+QVariant ConnectionModel::data(const QModelIndex &index, int role) const
+{
+ if ((role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::FontRole && role != Qt::ForegroundRole) || !m_editor)
+ return QVariant();
+
+ if (index.row() < 0 || index.row() >= m_editor->connectionCount()) {
+ return QVariant();
+ }
+
+ const SignalSlotConnection *con = static_cast<SignalSlotConnection*>(m_editor->connection(index.row()));
+ Q_ASSERT(con != 0);
+
+ if (role == Qt::FontRole || role == Qt::ForegroundRole) {
+ bool isQt3Member = false;
+ if (index.column() == 1) {
+ QDesignerFormEditorInterface *core = m_editor->formWindow()->core();
+ isQt3Member = isQt3Signal(core, con->object(CETypes::EndPoint::Source), con->signal());
+ } else if (index.column() == 3) {
+ QDesignerFormEditorInterface *core = m_editor->formWindow()->core();
+ isQt3Member = isQt3Signal(core, con->object(CETypes::EndPoint::Target), con->slot());
+ }
+ if (isQt3Member) {
+ if (role == Qt::ForegroundRole)
+ return Qt::red;
+ QFont font = QApplication::font();
+ font.setItalic(true);
+ return font;
+ }
+ return QVariant();
+ }
+
+ static const QVariant senderDefault = tr("<sender>");
+ static const QVariant signalDefault = tr("<signal>");
+ static const QVariant receiverDefault = tr("<receiver>");
+ static const QVariant slotDefault = tr("<slot>");
+
+ switch (index.column()) {
+ case 0: {
+ const QString sender = con->sender();
+ if (sender.isEmpty())
+ return senderDefault;
+ return sender;
+ }
+ case 1: {
+ const QString signal = con->signal();
+ if (signal.isEmpty())
+ return signalDefault;
+ return signal;
+ }
+ case 2: {
+ const QString receiver = con->receiver();
+ if (receiver.isEmpty())
+ return receiverDefault;
+ return receiver;
+ }
+ case 3: {
+ const QString slot = con->slot();
+ if (slot.isEmpty())
+ return slotDefault;
+ return slot;
+ }
+ }
+ return QVariant();
+}
+
+bool ConnectionModel::setData(const QModelIndex &index, const QVariant &data, int)
+{
+ if (!index.isValid() || !m_editor)
+ return false;
+ if (data.type() != QVariant::String)
+ return false;
+
+ SignalSlotConnection *con = static_cast<SignalSlotConnection*>(m_editor->connection(index.row()));
+ QDesignerFormWindowInterface *form = m_editor->formWindow();
+
+ QString s = data.toString();
+ switch (index.column()) {
+ case 0:
+ if (!s.isEmpty() && !objectNameList(form).contains(s))
+ s.clear();
+ m_editor->setSource(con, s);
+ break;
+ case 1:
+ if (!memberFunctionListContains(form->core(), con->object(CETypes::EndPoint::Source), SignalMember, s))
+ s.clear();
+ m_editor->setSignal(con, s);
+ break;
+ case 2:
+ if (!s.isEmpty() && !objectNameList(form).contains(s))
+ s.clear();
+ m_editor->setTarget(con, s);
+ break;
+ case 3:
+ if (!memberFunctionListContains(form->core(), con->object(CETypes::EndPoint::Target), SlotMember, s))
+ s.clear();
+ m_editor->setSlot(con, s);
+ break;
+ }
+
+ return true;
+}
+
+void ConnectionModel::connectionAdded(Connection*)
+{
+ endInsertRows();
+}
+
+void ConnectionModel::connectionRemoved(int)
+{
+ endRemoveRows();
+}
+
+void ConnectionModel::aboutToRemoveConnection(Connection *con)
+{
+ Q_ASSERT(m_editor);
+ int idx = m_editor->indexOfConnection(con);
+ beginRemoveRows(QModelIndex(), idx, idx);
+}
+
+void ConnectionModel::aboutToAddConnection(int idx)
+{
+ Q_ASSERT(m_editor);
+ beginInsertRows(QModelIndex(), idx, idx);
+}
+
+Qt::ItemFlags ConnectionModel::flags(const QModelIndex&) const
+{
+ return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
+}
+
+void ConnectionModel::connectionChanged(Connection *con)
+{
+ Q_ASSERT(m_editor);
+ const int idx = m_editor->indexOfConnection(con);
+ SignalSlotConnection *changedCon = static_cast<SignalSlotConnection*>(m_editor->connection(idx));
+ SignalSlotConnection *c = 0;
+ for (int i=0; i<m_editor->connectionCount(); ++i) {
+ if (i == idx)
+ continue;
+ c = static_cast<SignalSlotConnection*>(m_editor->connection(i));
+ if (c->sender() == changedCon->sender() && c->signal() == changedCon->signal()
+ && c->receiver() == changedCon->receiver() && c->slot() == changedCon->slot()) {
+ const QString message = tr("The connection already exists!<br>%1").arg(changedCon->toString());
+ m_editor->formWindow()->core()->dialogGui()->message(m_editor->parentWidget(), QDesignerDialogGuiInterface::SignalSlotEditorMessage,
+ QMessageBox::Warning, tr("Signal and Slot Editor"), message, QMessageBox::Ok);
+ break;
+ }
+ }
+ emit dataChanged(createIndex(idx, 0), createIndex(idx, 3));
+}
+
+void ConnectionModel::updateAll()
+{
+ emit dataChanged(index(0, 0), index(rowCount(), columnCount()));
+}
+}
+
+namespace {
+// ---------------------- InlineEditorModel
+
+class InlineEditorModel : public QStandardItemModel
+{
+ Q_OBJECT
+public:
+ enum { TitleItem = 1 };
+
+ InlineEditorModel(int rows, int cols, QObject *parent = 0);
+
+ void addTitle(const QString &title);
+ void addTextList(const QMap<QString, bool> &text_list);
+ void addText(const QString &text);
+ bool isTitle(int idx) const;
+
+ int findText(const QString &text) const;
+
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+};
+
+InlineEditorModel::InlineEditorModel(int rows, int cols, QObject *parent)
+ : QStandardItemModel(rows, cols, parent)
+{
+}
+
+void InlineEditorModel::addTitle(const QString &title)
+{
+ const int cnt = rowCount();
+ insertRows(cnt, 1);
+ QModelIndex cat_idx = index(cnt, 0);
+ setData(cat_idx, title + QLatin1Char(':'), Qt::DisplayRole);
+ setData(cat_idx, TitleItem, Qt::UserRole);
+ QFont font = QApplication::font();
+ font.setBold(true);
+ setData(cat_idx, font, Qt::FontRole);
+}
+
+bool InlineEditorModel::isTitle(int idx) const
+{
+ if (idx == -1)
+ return false;
+
+ return data(index(idx, 0), Qt::UserRole).toInt() == TitleItem;
+}
+
+void InlineEditorModel::addText(const QString &text)
+{
+ const int cnt = rowCount();
+ insertRows(cnt, 1);
+ setData(index(cnt, 0), text, Qt::DisplayRole);
+}
+
+void InlineEditorModel::addTextList(const QMap<QString, bool> &text_list)
+{
+ int cnt = rowCount();
+ insertRows(cnt, text_list.size());
+ QFont font = QApplication::font();
+ font.setItalic(true);
+ QVariant fontVariant = QVariant::fromValue(font);
+ QMap<QString, bool>::ConstIterator it = text_list.constBegin();
+ const QMap<QString, bool>::ConstIterator itEnd = text_list.constEnd();
+ while (it != itEnd) {
+ const QModelIndex text_idx = index(cnt++, 0);
+ setData(text_idx, it.key(), Qt::DisplayRole);
+ if (it.value()) {
+ setData(text_idx, fontVariant, Qt::FontRole);
+ setData(text_idx, Qt::red, Qt::ForegroundRole);
+ }
+ ++it;
+ }
+}
+
+Qt::ItemFlags InlineEditorModel::flags(const QModelIndex &index) const
+{
+ if (isTitle(index.row()))
+ return Qt::ItemIsEnabled;
+ else
+ return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+}
+
+int InlineEditorModel::findText(const QString &text) const
+{
+ const int cnt = rowCount();
+ for (int i = 0; i < cnt; ++i) {
+ const QModelIndex idx = index(i, 0);
+ if (data(idx, Qt::UserRole).toInt() == TitleItem)
+ continue;
+ if (data(idx, Qt::DisplayRole).toString() == text)
+ return i;
+ }
+ return -1;
+}
+
+// ------------ InlineEditor
+class InlineEditor : public QComboBox
+{
+ Q_OBJECT
+ Q_PROPERTY(QString text READ text WRITE setText USER true)
+public:
+ InlineEditor(QWidget *parent = 0);
+
+ QString text() const;
+ void setText(const QString &text);
+
+ void addTitle(const QString &title);
+ void addText(const QString &text);
+ void addTextList(const QMap<QString, bool> &text_list);
+
+private slots:
+ void checkSelection(int idx);
+
+private:
+ InlineEditorModel *m_model;
+ int m_idx;
+};
+
+InlineEditor::InlineEditor(QWidget *parent) :
+ QComboBox(parent),
+ m_idx(-1)
+{
+ setModel(m_model = new InlineEditorModel(0, 4, this));
+ setFrame(false);
+ m_idx = -1;
+ connect(this, SIGNAL(activated(int)), this, SLOT(checkSelection(int)));
+}
+
+void InlineEditor::checkSelection(int idx)
+{
+ if (idx == m_idx)
+ return;
+
+ if (m_model->isTitle(idx))
+ setCurrentIndex(m_idx);
+ else
+ m_idx = idx;
+}
+
+void InlineEditor::addTitle(const QString &title)
+{
+ m_model->addTitle(title);
+}
+
+void InlineEditor::addTextList(const QMap<QString, bool> &text_list)
+{
+ m_model->addTextList(text_list);
+}
+
+void InlineEditor::addText(const QString &text)
+{
+ m_model->addText(text);
+}
+
+QString InlineEditor::text() const
+{
+ return currentText();
+}
+
+void InlineEditor::setText(const QString &text)
+{
+ m_idx = m_model->findText(text);
+ if (m_idx == -1)
+ m_idx = 0;
+ setCurrentIndex(m_idx);
+}
+
+// ------------------ ConnectionDelegate
+
+class ConnectionDelegate : public QItemDelegate
+{
+ Q_OBJECT
+public:
+ ConnectionDelegate(QWidget *parent = 0);
+
+ void setForm(QDesignerFormWindowInterface *form);
+
+ virtual QWidget *createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+private slots:
+ void emitCommitData();
+
+private:
+ QDesignerFormWindowInterface *m_form;
+};
+
+ConnectionDelegate::ConnectionDelegate(QWidget *parent)
+ : QItemDelegate(parent)
+{
+ m_form = 0;
+
+ static QItemEditorFactory *factory = 0;
+ if (factory == 0) {
+ factory = new QItemEditorFactory;
+ QItemEditorCreatorBase *creator
+ = new QItemEditorCreator<InlineEditor>("text");
+ factory->registerEditor(QVariant::String, creator);
+ }
+
+ setItemEditorFactory(factory);
+}
+
+void ConnectionDelegate::setForm(QDesignerFormWindowInterface *form)
+{
+ m_form = form;
+}
+
+QWidget *ConnectionDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (m_form == 0)
+ return 0;
+
+ QWidget *w = QItemDelegate::createEditor(parent, option, index);
+ InlineEditor *inline_editor = qobject_cast<InlineEditor*>(w);
+ Q_ASSERT(inline_editor != 0);
+ const QAbstractItemModel *model = index.model();
+
+ const QModelIndex obj_name_idx = model->index(index.row(), index.column() <= 1 ? 0 : 2);
+ const QString obj_name = model->data(obj_name_idx, Qt::DisplayRole).toString();
+
+ switch (index.column()) {
+ case 0:
+ case 2: { // object names
+ QStringList obj_name_list = objectNameList(m_form);
+ QMap<QString, bool> markedNameList;
+ markedNameList.insert(tr("<object>"), false);
+ inline_editor->addTextList(markedNameList);
+ markedNameList.clear();
+ foreach (const QString &name, obj_name_list)
+ markedNameList.insert(name, false);
+ inline_editor->addTextList(markedNameList);
+ }
+ break;
+ case 1:
+ case 3: { // signals, slots
+ const qdesigner_internal::MemberType type = index.column() == 1 ? qdesigner_internal::SignalMember : qdesigner_internal::SlotMember;
+ const QModelIndex peer_index = model->index(index.row(), type == qdesigner_internal::SignalMember ? 3 : 1);
+ const QString peer = model->data(peer_index, Qt::DisplayRole).toString();
+
+ const qdesigner_internal::ClassesMemberFunctions class_list = qdesigner_internal::reverseClassesMemberFunctions(obj_name, type, peer, m_form);
+
+ QObject *object = 0;
+ if (obj_name == m_form->mainContainer()->objectName()) {
+ object = m_form->mainContainer();
+ } else {
+ object = m_form->mainContainer()->findChild<QObject*>(obj_name);
+ }
+ inline_editor->addText(type == qdesigner_internal::SignalMember ? tr("<signal>") : tr("<slot>"));
+ foreach (const qdesigner_internal::ClassMemberFunctions &class_info, class_list) {
+ if (class_info.m_className.isEmpty() || class_info.m_memberList.isEmpty())
+ continue;
+ QStringList memberList = class_info.m_memberList;
+ QMap<QString, bool> markedMemberList;
+ foreach (const QString &member, memberList) {
+ bool mark = false;
+ if (type == qdesigner_internal::SignalMember)
+ mark = qdesigner_internal::isQt3Signal(m_form->core(), object, member);
+ else
+ mark = qdesigner_internal::isQt3Slot(m_form->core(), object, member);
+
+ if (!mark)
+ markedMemberList.insert(member, mark);
+ }
+ inline_editor->addTitle(class_info.m_className);
+ inline_editor->addTextList(markedMemberList);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ connect(inline_editor, SIGNAL(activated(int)), this, SLOT(emitCommitData()));
+
+ return inline_editor;
+}
+
+void ConnectionDelegate::emitCommitData()
+{
+ InlineEditor *editor = qobject_cast<InlineEditor*>(sender());
+ emit commitData(editor);
+}
+
+}
+
+namespace qdesigner_internal {
+
+/*******************************************************************************
+** SignalSlotEditorWindow
+*/
+
+SignalSlotEditorWindow::SignalSlotEditorWindow(QDesignerFormEditorInterface *core,
+ QWidget *parent) :
+ QWidget(parent),
+ m_view(new QTreeView),
+ m_editor(0),
+ m_add_button(new QToolButton),
+ m_remove_button(new QToolButton),
+ m_core(core),
+ m_model(new ConnectionModel(this)),
+ m_proxy_model(new QSortFilterProxyModel(this)),
+ m_handling_selection_change(false)
+{
+ m_proxy_model->setSourceModel(m_model);
+ m_view->setModel(m_proxy_model);
+ m_view->setSortingEnabled(true);
+ m_view->setItemDelegate(new ConnectionDelegate(this));
+ m_view->setEditTriggers(QAbstractItemView::DoubleClicked
+ | QAbstractItemView::EditKeyPressed);
+ m_view->setRootIsDecorated(false);
+ m_view->setTextElideMode (Qt::ElideMiddle);
+ connect(m_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(updateUi()));
+ connect(m_view->header(), SIGNAL(sectionDoubleClicked(int)), m_view, SLOT(resizeColumnToContents(int)));
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(0);
+ layout->setSpacing(0);
+
+ QToolBar *toolBar = new QToolBar;
+ toolBar->setIconSize(QSize(22, 22));
+ m_add_button->setIcon(createIconSet(QLatin1String("plus.png")));
+ connect(m_add_button, SIGNAL(clicked()), this, SLOT(addConnection()));
+ toolBar->addWidget(m_add_button);
+
+ m_remove_button->setIcon(createIconSet(QLatin1String("minus.png")));
+ connect(m_remove_button, SIGNAL(clicked()), this, SLOT(removeConnection()));
+ toolBar->addWidget(m_remove_button);
+
+ layout->addWidget(toolBar);
+ layout->addWidget(m_view);
+
+ connect(core->formWindowManager(),
+ SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(setActiveFormWindow(QDesignerFormWindowInterface*)));
+
+ updateUi();
+}
+
+void SignalSlotEditorWindow::setActiveFormWindow(QDesignerFormWindowInterface *form)
+{
+ QDesignerIntegration *integration = qobject_cast<QDesignerIntegration *>(m_core->integration());
+
+ if (!m_editor.isNull()) {
+ disconnect(m_view->selectionModel(),
+ SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(updateEditorSelection(QModelIndex)));
+ disconnect(m_editor, SIGNAL(connectionSelected(Connection*)),
+ this, SLOT(updateDialogSelection(Connection*)));
+ if (integration) {
+ disconnect(integration, SIGNAL(objectNameChanged(QDesignerFormWindowInterface*,QObject*,QString,QString)),
+ this, SLOT(objectNameChanged(QDesignerFormWindowInterface*,QObject*,QString,QString)));
+ }
+ }
+
+ m_editor = form->findChild<SignalSlotEditor*>();
+ m_model->setEditor(m_editor);
+ if (!m_editor.isNull()) {
+ ConnectionDelegate *delegate
+ = qobject_cast<ConnectionDelegate*>(m_view->itemDelegate());
+ if (delegate != 0)
+ delegate->setForm(form);
+
+ connect(m_view->selectionModel(),
+ SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(updateEditorSelection(QModelIndex)));
+ connect(m_editor, SIGNAL(connectionSelected(Connection*)),
+ this, SLOT(updateDialogSelection(Connection*)));
+ if (integration) {
+ connect(integration, SIGNAL(objectNameChanged(QDesignerFormWindowInterface*,QObject*,QString,QString)),
+ this, SLOT(objectNameChanged(QDesignerFormWindowInterface*,QObject*,QString,QString)));
+ }
+ }
+
+ updateUi();
+}
+
+void SignalSlotEditorWindow::updateDialogSelection(Connection *con)
+{
+ if (m_handling_selection_change || m_editor == 0)
+ return;
+
+ QModelIndex index = m_proxy_model->mapFromSource(m_model->connectionToIndex(con));
+ if (index == m_view->currentIndex())
+ return;
+ m_handling_selection_change = true;
+ m_view->setCurrentIndex(index);
+ m_handling_selection_change = false;
+
+ updateUi();
+}
+
+void SignalSlotEditorWindow::updateEditorSelection(const QModelIndex &index)
+{
+ if (m_handling_selection_change || m_editor == 0)
+ return;
+
+ if (m_editor == 0)
+ return;
+
+ Connection *con = m_model->indexToConnection(m_proxy_model->mapToSource(index));
+ if (m_editor->selected(con))
+ return;
+ m_handling_selection_change = true;
+ m_editor->selectNone();
+ m_editor->setSelected(con, true);
+ m_handling_selection_change = false;
+
+ updateUi();
+}
+
+void SignalSlotEditorWindow::objectNameChanged(QDesignerFormWindowInterface *, QObject *, const QString &, const QString &)
+{
+ if (m_editor)
+ m_model->updateAll();
+}
+
+void SignalSlotEditorWindow::addConnection()
+{
+ if (m_editor.isNull())
+ return;
+
+ m_editor->addEmptyConnection();
+ updateUi();
+}
+
+void SignalSlotEditorWindow::removeConnection()
+{
+ if (m_editor.isNull())
+ return;
+
+ m_editor->deleteSelected();
+ updateUi();
+}
+
+void SignalSlotEditorWindow::updateUi()
+{
+ m_add_button->setEnabled(!m_editor.isNull());
+ m_remove_button->setEnabled(!m_editor.isNull() && m_view->currentIndex().isValid());
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#include "signalsloteditorwindow.moc"
diff --git a/src/designer/src/components/signalsloteditor/signalsloteditorwindow.h b/src/designer/src/components/signalsloteditor/signalsloteditorwindow.h
new file mode 100644
index 000000000..179b6c5f4
--- /dev/null
+++ b/src/designer/src/components/signalsloteditor/signalsloteditorwindow.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIGNALSLOTEDITORWINDOW_H
+#define SIGNALSLOTEDITORWINDOW_H
+
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+class QModelIndex;
+class QSortFilterProxyModel;
+class QTreeView;
+class QToolButton;
+
+namespace qdesigner_internal {
+
+class SignalSlotEditor;
+class ConnectionModel;
+class Connection;
+
+class SignalSlotEditorWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit SignalSlotEditorWindow(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+
+public slots:
+ void setActiveFormWindow(QDesignerFormWindowInterface *form);
+
+private slots:
+ void updateDialogSelection(Connection *con);
+ void updateEditorSelection(const QModelIndex &index);
+
+ void objectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object, const QString &newName, const QString &oldName);
+
+ void addConnection();
+ void removeConnection();
+ void updateUi();
+
+private:
+ QTreeView *m_view;
+ QPointer<SignalSlotEditor> m_editor;
+ QToolButton *m_add_button, *m_remove_button;
+ QDesignerFormEditorInterface *m_core;
+ ConnectionModel *m_model;
+ QSortFilterProxyModel *m_proxy_model;
+ bool m_handling_selection_change;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SIGNALSLOTEDITORWINDOW_H
diff --git a/src/designer/src/components/tabordereditor/tabordereditor.cpp b/src/designer/src/components/tabordereditor/tabordereditor.cpp
new file mode 100644
index 000000000..e372bdc14
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor.cpp
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tabordereditor.h"
+
+#include <metadatabase_p.h>
+#include <qdesigner_command_p.h>
+#include <qdesigner_utils_p.h>
+#include <qlayout_widget_p.h>
+#include <orderdialog_p.h>
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+
+#include <QtGui/QPainter>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QResizeEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QApplication>
+
+Q_DECLARE_METATYPE(QWidgetList)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { VBOX_MARGIN = 1, HBOX_MARGIN = 4, BG_ALPHA = 32 };
+}
+
+static QRect fixRect(const QRect &r)
+{
+ return QRect(r.x(), r.y(), r.width() - 1, r.height() - 1);
+}
+
+namespace qdesigner_internal {
+
+TabOrderEditor::TabOrderEditor(QDesignerFormWindowInterface *form, QWidget *parent) :
+ QWidget(parent),
+ m_form_window(form),
+ m_bg_widget(0),
+ m_undo_stack(form->commandHistory()),
+ m_font_metrics(font()),
+ m_current_index(0),
+ m_beginning(true)
+{
+ connect(form, SIGNAL(widgetRemoved(QWidget*)), this, SLOT(widgetRemoved(QWidget*)));
+
+ QFont tabFont = font();
+ tabFont.setPointSize(tabFont.pointSize()*2);
+ tabFont.setBold(true);
+ setFont(tabFont);
+ m_font_metrics = QFontMetrics(tabFont);
+ setAttribute(Qt::WA_MouseTracking, true);
+}
+
+QDesignerFormWindowInterface *TabOrderEditor::formWindow() const
+{
+ return m_form_window;
+}
+
+void TabOrderEditor::setBackground(QWidget *background)
+{
+ if (background == m_bg_widget) {
+ return;
+ }
+
+ m_bg_widget = background;
+ updateBackground();
+}
+
+void TabOrderEditor::updateBackground()
+{
+ if (m_bg_widget == 0) {
+ // nothing to do
+ return;
+ }
+
+ initTabOrder();
+ update();
+}
+
+void TabOrderEditor::widgetRemoved(QWidget*)
+{
+ initTabOrder();
+}
+
+void TabOrderEditor::showEvent(QShowEvent *e)
+{
+ QWidget::showEvent(e);
+ updateBackground();
+}
+
+QRect TabOrderEditor::indicatorRect(int index) const
+{
+ if (index < 0 || index >= m_tab_order_list.size())
+ return QRect();
+
+ const QWidget *w = m_tab_order_list.at(index);
+ const QString text = QString::number(index + 1);
+
+ const QPoint tl = mapFromGlobal(w->mapToGlobal(w->rect().topLeft()));
+ const QSize size = m_font_metrics.size(Qt::TextSingleLine, text);
+ QRect r(tl - QPoint(size.width(), size.height())/2, size);
+ r = QRect(r.left() - HBOX_MARGIN, r.top() - VBOX_MARGIN,
+ r.width() + HBOX_MARGIN*2, r.height() + VBOX_MARGIN*2);
+
+ return r;
+}
+
+static bool isWidgetVisible(QWidget *widget)
+{
+ while (widget && widget->parentWidget()) {
+ if (!widget->isVisibleTo(widget->parentWidget()))
+ return false;
+
+ widget = widget->parentWidget();
+ }
+
+ return true;
+}
+
+void TabOrderEditor::paintEvent(QPaintEvent *e)
+{
+ QPainter p(this);
+ p.setClipRegion(e->region());
+
+ int cur = m_current_index - 1;
+ if (m_beginning == false && cur < 0)
+ cur = m_tab_order_list.size() - 1;
+
+ for (int i = 0; i < m_tab_order_list.size(); ++i) {
+ QWidget *widget = m_tab_order_list.at(i);
+ if (!isWidgetVisible(widget))
+ continue;
+
+ const QRect r = indicatorRect(i);
+
+ QColor c = Qt::darkGreen;
+ if (i == cur)
+ c = Qt::red;
+ else if (i > cur)
+ c = Qt::blue;
+ p.setPen(c);
+ c.setAlpha(BG_ALPHA);
+ p.setBrush(c);
+ p.drawRect(fixRect(r));
+
+ p.setPen(Qt::white);
+ p.drawText(r, QString::number(i + 1), QTextOption(Qt::AlignCenter));
+ }
+}
+
+bool TabOrderEditor::skipWidget(QWidget *w) const
+{
+ if (qobject_cast<QLayoutWidget*>(w)
+ || w == formWindow()->mainContainer()
+ || w->isHidden())
+ return true;
+
+ if (!formWindow()->isManaged(w)) {
+ return true;
+ }
+
+ QExtensionManager *ext = formWindow()->core()->extensionManager();
+ if (const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(ext, w)) {
+ const int index = sheet->indexOf(QLatin1String("focusPolicy"));
+ if (index != -1) {
+ bool ok = false;
+ Qt::FocusPolicy q = (Qt::FocusPolicy) Utils::valueOf(sheet->property(index), &ok);
+ return !ok || q == Qt::NoFocus;
+ }
+ }
+
+ return true;
+}
+
+void TabOrderEditor::initTabOrder()
+{
+ m_tab_order_list.clear();
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+
+ if (const QDesignerMetaDataBaseItemInterface *item = core->metaDataBase()->item(formWindow())) {
+ m_tab_order_list = item->tabOrder();
+ }
+
+ // Remove any widgets that have been removed form the form
+ for (int i = 0; i < m_tab_order_list.size(); ) {
+ QWidget *w = m_tab_order_list.at(i);
+ if (!formWindow()->mainContainer()->isAncestorOf(w) || skipWidget(w))
+ m_tab_order_list.removeAt(i);
+ else
+ ++i;
+ }
+
+ // Append any widgets that are in the form but are not in the tab order
+ QList<QWidget *> childQueue;
+ childQueue.append(formWindow()->mainContainer());
+ while (!childQueue.isEmpty()) {
+ QWidget *child = childQueue.takeFirst();
+ childQueue += qvariant_cast<QWidgetList>(child->property("_q_widgetOrder"));
+
+ if (skipWidget(child))
+ continue;
+
+ if (!m_tab_order_list.contains(child))
+ m_tab_order_list.append(child);
+ }
+
+ // Just in case we missed some widgets
+ QDesignerFormWindowCursorInterface *cursor = formWindow()->cursor();
+ for (int i = 0; i < cursor->widgetCount(); ++i) {
+
+ QWidget *widget = cursor->widget(i);
+ if (skipWidget(widget))
+ continue;
+
+ if (!m_tab_order_list.contains(widget))
+ m_tab_order_list.append(widget);
+ }
+
+ m_indicator_region = QRegion();
+ for (int i = 0; i < m_tab_order_list.size(); ++i) {
+ if (m_tab_order_list.at(i)->isVisible())
+ m_indicator_region |= indicatorRect(i);
+ }
+
+ if (m_current_index >= m_tab_order_list.size())
+ m_current_index = m_tab_order_list.size() - 1;
+ if (m_current_index < 0)
+ m_current_index = 0;
+}
+
+void TabOrderEditor::mouseMoveEvent(QMouseEvent *e)
+{
+ e->accept();
+#ifndef QT_NO_CURSOR
+ if (m_indicator_region.contains(e->pos()))
+ setCursor(Qt::PointingHandCursor);
+ else
+ setCursor(QCursor());
+#endif
+}
+
+int TabOrderEditor::widgetIndexAt(const QPoint &pos) const
+{
+ int target_index = -1;
+ for (int i = 0; i < m_tab_order_list.size(); ++i) {
+ if (!m_tab_order_list.at(i)->isVisible())
+ continue;
+ if (indicatorRect(i).contains(pos)) {
+ target_index = i;
+ break;
+ }
+ }
+
+ return target_index;
+}
+
+void TabOrderEditor::mousePressEvent(QMouseEvent *e)
+{
+ e->accept();
+
+ if (!m_indicator_region.contains(e->pos())) {
+ if (QWidget *child = m_bg_widget->childAt(e->pos())) {
+ QDesignerFormEditorInterface *core = m_form_window->core();
+ if (core->widgetFactory()->isPassiveInteractor(child)) {
+
+ QMouseEvent event(QEvent::MouseButtonPress,
+ child->mapFromGlobal(e->globalPos()),
+ e->button(), e->buttons(), e->modifiers());
+
+ qApp->sendEvent(child, &event);
+
+ QMouseEvent event2(QEvent::MouseButtonRelease,
+ child->mapFromGlobal(e->globalPos()),
+ e->button(), e->buttons(), e->modifiers());
+
+ qApp->sendEvent(child, &event2);
+
+ updateBackground();
+ }
+ }
+ return;
+ }
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ const int target_index = widgetIndexAt(e->pos());
+ if (target_index == -1)
+ return;
+
+ m_beginning = false;
+
+ if (e->modifiers() & Qt::ControlModifier) {
+ m_current_index = target_index + 1;
+ if (m_current_index >= m_tab_order_list.size())
+ m_current_index = 0;
+ update();
+ return;
+ }
+
+ if (m_current_index == -1)
+ return;
+
+ m_tab_order_list.swap(target_index, m_current_index);
+
+ ++m_current_index;
+ if (m_current_index == m_tab_order_list.size())
+ m_current_index = 0;
+
+ TabOrderCommand *cmd = new TabOrderCommand(formWindow());
+ cmd->init(m_tab_order_list);
+ formWindow()->commandHistory()->push(cmd);
+}
+
+void TabOrderEditor::contextMenuEvent(QContextMenuEvent *e)
+{
+ QMenu menu(this);
+ const int target_index = widgetIndexAt(e->pos());
+ QAction *setIndex = menu.addAction(tr("Start from Here"));
+ setIndex->setEnabled(target_index >= 0);
+
+ QAction *resetIndex = menu.addAction(tr("Restart"));
+ menu.addSeparator();
+ QAction *showDialog = menu.addAction(tr("Tab Order List..."));
+ showDialog->setEnabled(m_tab_order_list.size() > 1);
+
+ QAction *result = menu.exec(e->globalPos());
+ if (result == resetIndex) {
+ m_current_index = 0;
+ m_beginning = true;
+ update();
+ } else if (result == setIndex) {
+ m_beginning = false;
+ m_current_index = target_index + 1;
+ if (m_current_index >= m_tab_order_list.size())
+ m_current_index = 0;
+ update();
+ } else if (result == showDialog) {
+ showTabOrderDialog();
+ }
+}
+
+void TabOrderEditor::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ const int target_index = widgetIndexAt(e->pos());
+ if (target_index >= 0)
+ return;
+
+ m_beginning = true;
+ m_current_index = 0;
+ update();
+}
+
+void TabOrderEditor::resizeEvent(QResizeEvent *e)
+{
+ updateBackground();
+ QWidget::resizeEvent(e);
+}
+
+void TabOrderEditor::showTabOrderDialog()
+{
+ if (m_tab_order_list.size() < 2)
+ return;
+ OrderDialog dlg(this);
+ dlg.setWindowTitle(tr("Tab Order List"));
+ dlg.setDescription(tr("Tab Order"));
+ dlg.setFormat(OrderDialog::TabOrderFormat);
+ dlg.setPageList(m_tab_order_list);
+
+ if (dlg.exec() == QDialog::Rejected)
+ return;
+
+ const QWidgetList newOrder = dlg.pageList();
+ if (newOrder == m_tab_order_list)
+ return;
+
+ m_tab_order_list = newOrder;
+ TabOrderCommand *cmd = new TabOrderCommand(formWindow());
+ cmd->init(m_tab_order_list);
+ formWindow()->commandHistory()->push(cmd);
+ update();
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/tabordereditor/tabordereditor.h b/src/designer/src/components/tabordereditor/tabordereditor.h
new file mode 100644
index 000000000..3eacd3739
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TABORDEREDITOR_H
+#define TABORDEREDITOR_H
+
+#include "tabordereditor_global.h"
+
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+#include <QtGui/QRegion>
+#include <QtGui/QFont>
+#include <QtGui/QFontMetrics>
+
+QT_BEGIN_NAMESPACE
+
+class QUndoStack;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class QT_TABORDEREDITOR_EXPORT TabOrderEditor : public QWidget
+{
+ Q_OBJECT
+
+public:
+ TabOrderEditor(QDesignerFormWindowInterface *form, QWidget *parent);
+
+ QDesignerFormWindowInterface *formWindow() const;
+
+public slots:
+ void setBackground(QWidget *background);
+ void updateBackground();
+ void widgetRemoved(QWidget*);
+ void initTabOrder();
+
+private slots:
+ void showTabOrderDialog();
+
+protected:
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void showEvent(QShowEvent *e);
+
+private:
+ QRect indicatorRect(int index) const;
+ int widgetIndexAt(const QPoint &pos) const;
+ bool skipWidget(QWidget *w) const;
+
+ QPointer<QDesignerFormWindowInterface> m_form_window;
+
+ QWidgetList m_tab_order_list;
+
+ QWidget *m_bg_widget;
+ QUndoStack *m_undo_stack;
+ QRegion m_indicator_region;
+
+ QFontMetrics m_font_metrics;
+ int m_current_index;
+ bool m_beginning;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/components/tabordereditor/tabordereditor.pri b/src/designer/src/components/tabordereditor/tabordereditor.pri
new file mode 100644
index 000000000..786c6ae02
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor.pri
@@ -0,0 +1,16 @@
+
+QT += xml
+
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/tabordereditor.h \
+ $$PWD/tabordereditor_plugin.h \
+ $$PWD/tabordereditor_tool.h \
+ $$PWD/tabordereditor_global.h
+
+SOURCES += \
+ $$PWD/tabordereditor.cpp \
+ $$PWD/tabordereditor_tool.cpp \
+ $$PWD/tabordereditor_plugin.cpp \
+ $$PWD/tabordereditor_instance.cpp
diff --git a/src/designer/src/components/tabordereditor/tabordereditor_global.h b/src/designer/src/components/tabordereditor/tabordereditor_global.h
new file mode 100644
index 000000000..13b5e348d
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor_global.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TABORDEREDITOR_GLOBAL_H
+#define TABORDEREDITOR_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN
+#ifdef QT_TABORDEREDITOR_LIBRARY
+# define QT_TABORDEREDITOR_EXPORT
+#else
+# define QT_TABORDEREDITOR_EXPORT
+#endif
+#else
+#define QT_TABORDEREDITOR_EXPORT
+#endif
+
+#endif // TABORDEREDITOR_GLOBAL_H
diff --git a/src/designer/src/components/tabordereditor/tabordereditor_instance.cpp b/src/designer/src/components/tabordereditor/tabordereditor_instance.cpp
new file mode 100644
index 000000000..6ff7903f7
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor_instance.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qplugin.h>
+
+#include "tabordereditor_plugin.h"
+
+QT_USE_NAMESPACE
+using namespace qdesigner_internal;
+
+Q_EXPORT_PLUGIN(TabOrderEditorPlugin)
diff --git a/src/designer/src/components/tabordereditor/tabordereditor_plugin.cpp b/src/designer/src/components/tabordereditor/tabordereditor_plugin.cpp
new file mode 100644
index 000000000..49581e5f6
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor_plugin.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QAction>
+
+#include "tabordereditor_plugin.h"
+#include "tabordereditor_tool.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+TabOrderEditorPlugin::TabOrderEditorPlugin()
+ : m_initialized(false)
+{
+}
+
+TabOrderEditorPlugin::~TabOrderEditorPlugin()
+{
+}
+
+bool TabOrderEditorPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void TabOrderEditorPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_ASSERT(!isInitialized());
+
+ m_action = new QAction(tr("Edit Tab Order"), this);
+ m_action->setObjectName(QLatin1String("_qt_edit_tab_order_action"));
+ QIcon icon = QIcon::fromTheme("designer-edit-tabs",
+ QIcon(core->resourceLocation() + QLatin1String("/tabordertool.png")));
+ m_action->setIcon(icon);
+ m_action->setEnabled(false);
+
+ setParent(core);
+ m_core = core;
+ m_initialized = true;
+
+ connect(core->formWindowManager(), SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)),
+ this, SLOT(addFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core->formWindowManager(), SIGNAL(formWindowRemoved(QDesignerFormWindowInterface*)),
+ this, SLOT(removeFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface*)));
+}
+
+void TabOrderEditorPlugin::activeFormWindowChanged(QDesignerFormWindowInterface *formWindow)
+{
+ m_action->setEnabled(formWindow != 0);
+}
+
+QDesignerFormEditorInterface *TabOrderEditorPlugin::core() const
+{
+ return m_core;
+}
+
+void TabOrderEditorPlugin::addFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_ASSERT(formWindow != 0);
+ Q_ASSERT(m_tools.contains(formWindow) == false);
+
+ TabOrderEditorTool *tool = new TabOrderEditorTool(formWindow, this);
+ m_tools[formWindow] = tool;
+ connect(m_action, SIGNAL(triggered()), tool->action(), SLOT(trigger()));
+ formWindow->registerTool(tool);
+}
+
+void TabOrderEditorPlugin::removeFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_ASSERT(formWindow != 0);
+ Q_ASSERT(m_tools.contains(formWindow) == true);
+
+ TabOrderEditorTool *tool = m_tools.value(formWindow);
+ m_tools.remove(formWindow);
+ disconnect(m_action, SIGNAL(triggered()), tool->action(), SLOT(trigger()));
+ // ### FIXME disable the tool
+
+ delete tool;
+}
+
+QAction *TabOrderEditorPlugin::action() const
+{
+ return m_action;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/tabordereditor/tabordereditor_plugin.h b/src/designer/src/components/tabordereditor/tabordereditor_plugin.h
new file mode 100644
index 000000000..685804624
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor_plugin.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TABORDEREDITOR_PLUGIN_H
+#define TABORDEREDITOR_PLUGIN_H
+
+#include "tabordereditor_global.h"
+
+#include <QtDesigner/QDesignerFormEditorPluginInterface>
+
+#include <QtCore/QPointer>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QAction;
+
+namespace qdesigner_internal {
+
+class TabOrderEditorTool;
+
+class QT_TABORDEREDITOR_EXPORT TabOrderEditorPlugin: public QObject, public QDesignerFormEditorPluginInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerFormEditorPluginInterface)
+public:
+ TabOrderEditorPlugin();
+ virtual ~TabOrderEditorPlugin();
+
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ QAction *action() const;
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+public slots:
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+
+private slots:
+ void addFormWindow(QDesignerFormWindowInterface *formWindow);
+ void removeFormWindow(QDesignerFormWindowInterface *formWindow);
+
+private:
+ QPointer<QDesignerFormEditorInterface> m_core;
+ QHash<QDesignerFormWindowInterface*, TabOrderEditorTool*> m_tools;
+ bool m_initialized;
+ QAction *m_action;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TABORDEREDITOR_PLUGIN_H
diff --git a/src/designer/src/components/tabordereditor/tabordereditor_tool.cpp b/src/designer/src/components/tabordereditor/tabordereditor_tool.cpp
new file mode 100644
index 000000000..2914cb58a
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor_tool.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tabordereditor_tool.h"
+#include "tabordereditor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtCore/QEvent>
+#include <QtGui/QAction>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+TabOrderEditorTool::TabOrderEditorTool(QDesignerFormWindowInterface *formWindow, QObject *parent)
+ : QDesignerFormWindowToolInterface(parent),
+ m_formWindow(formWindow),
+ m_action(new QAction(tr("Edit Tab Order"), this))
+{
+}
+
+TabOrderEditorTool::~TabOrderEditorTool()
+{
+}
+
+QDesignerFormEditorInterface *TabOrderEditorTool::core() const
+{
+ return m_formWindow->core();
+}
+
+QDesignerFormWindowInterface *TabOrderEditorTool::formWindow() const
+{
+ return m_formWindow;
+}
+
+bool TabOrderEditorTool::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(managedWidget);
+
+ if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
+ return true;
+
+ return false;
+}
+
+QWidget *TabOrderEditorTool::editor() const
+{
+ if (!m_editor) {
+ Q_ASSERT(formWindow() != 0);
+ m_editor = new TabOrderEditor(formWindow(), 0);
+ connect(formWindow(), SIGNAL(mainContainerChanged(QWidget*)), m_editor, SLOT(setBackground(QWidget*)));
+ }
+
+ return m_editor;
+}
+
+void TabOrderEditorTool::activated()
+{
+ connect(formWindow(), SIGNAL(changed()),
+ m_editor, SLOT(updateBackground()));
+}
+
+void TabOrderEditorTool::deactivated()
+{
+ disconnect(formWindow(), SIGNAL(changed()),
+ m_editor, SLOT(updateBackground()));
+}
+
+QAction *TabOrderEditorTool::action() const
+{
+ return m_action;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/tabordereditor/tabordereditor_tool.h b/src/designer/src/components/tabordereditor/tabordereditor_tool.h
new file mode 100644
index 000000000..d978e4949
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor_tool.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TABORDEREDITOR_TOOL_H
+#define TABORDEREDITOR_TOOL_H
+
+#include "tabordereditor_global.h"
+
+#include <QtCore/QPointer>
+
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QAction;
+
+namespace qdesigner_internal {
+
+class TabOrderEditor;
+
+class QT_TABORDEREDITOR_EXPORT TabOrderEditorTool: public QDesignerFormWindowToolInterface
+{
+ Q_OBJECT
+public:
+ explicit TabOrderEditorTool(QDesignerFormWindowInterface *formWindow, QObject *parent = 0);
+ virtual ~TabOrderEditorTool();
+
+ virtual QDesignerFormEditorInterface *core() const;
+ virtual QDesignerFormWindowInterface *formWindow() const;
+
+ virtual QWidget *editor() const;
+ virtual QAction *action() const;
+
+ virtual void activated();
+ virtual void deactivated();
+
+ virtual bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event);
+
+private:
+ QDesignerFormWindowInterface *m_formWindow;
+ mutable QPointer<TabOrderEditor> m_editor;
+ QAction *m_action;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TABORDEREDITOR_TOOL_H
diff --git a/src/designer/src/components/taskmenu/button_taskmenu.cpp b/src/designer/src/components/taskmenu/button_taskmenu.cpp
new file mode 100644
index 000000000..953996b8c
--- /dev/null
+++ b/src/designer/src/components/taskmenu/button_taskmenu.cpp
@@ -0,0 +1,709 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "button_taskmenu.h"
+#include "inplace_editor.h"
+#include <qdesigner_formwindowcommand_p.h>
+#include <formwindowbase_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QMenu>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+#include <QtGui/QAbstractButton>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QApplication>
+#include <QtCore/QDebug>
+
+Q_DECLARE_METATYPE(QButtonGroup*)
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+enum { debugButtonMenu = 0 };
+
+typedef QList<QAbstractButton *> ButtonList;
+typedef QList<QButtonGroup *> ButtonGroupList;
+
+// ButtonGroupCommand: Base for commands handling button groups and button lists
+// addButtonsToGroup() and removeButtonsFromGroup() are low-level helpers for
+// adding/removing members to/from existing groups.
+//
+// createButtonGroup()/breakButtonGroup() create and remove the groups from scratch.
+// When using them in a command, the command must be executed within
+// a macro since it makes the form emit objectRemoved() which might cause other components
+// to add commands (for example, removal of signals and slots)
+class ButtonGroupCommand : public QDesignerFormWindowCommand {
+
+protected:
+ ButtonGroupCommand(const QString &description, QDesignerFormWindowInterface *formWindow);
+
+ void initialize(const ButtonList &bl, QButtonGroup *buttonGroup);
+
+ // Helper: Add the buttons to the group
+ void addButtonsToGroup();
+ // Helper; Remove the buttons
+ void removeButtonsFromGroup();
+
+ // Create the button group in Designer
+ void createButtonGroup();
+ // Remove the button group from Designer
+ void breakButtonGroup();
+
+public:
+ static QString nameList(const ButtonList& bl);
+ static ButtonGroupList managedButtonGroups(const QDesignerFormWindowInterface *formWindow);
+
+private:
+ ButtonList m_buttonList;
+ QButtonGroup *m_buttonGroup;
+};
+
+ButtonGroupCommand::ButtonGroupCommand(const QString &description, QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(description, formWindow),
+ m_buttonGroup(0)
+{
+}
+
+void ButtonGroupCommand::initialize(const ButtonList &bl, QButtonGroup *buttonGroup)
+{
+ m_buttonList = bl;
+ m_buttonGroup = buttonGroup;
+}
+
+void ButtonGroupCommand::addButtonsToGroup()
+{
+ if (debugButtonMenu)
+ qDebug() << "Adding " << m_buttonList << " to " << m_buttonGroup;
+ const ButtonList::const_iterator cend = m_buttonList.constEnd();
+ for (ButtonList::const_iterator it = m_buttonList.constBegin(); it != cend; ++it)
+ m_buttonGroup->addButton(*it);
+}
+
+void ButtonGroupCommand::removeButtonsFromGroup()
+{
+ if (debugButtonMenu)
+ qDebug() << "Removing " << m_buttonList << " from " << m_buttonGroup;
+ const ButtonList::const_iterator cend = m_buttonList.constEnd();
+ for (ButtonList::const_iterator it = m_buttonList.constBegin(); it != cend; ++it)
+ m_buttonGroup->removeButton(*it);
+}
+
+void ButtonGroupCommand::createButtonGroup()
+{
+ if (debugButtonMenu)
+ qDebug() << "Creating " << m_buttonGroup << " from " << m_buttonList;
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ QDesignerFormEditorInterface *core = fw->core();
+ core->metaDataBase()->add(m_buttonGroup);
+ addButtonsToGroup();
+ // Make button group visible
+ core->objectInspector()->setFormWindow(fw);
+}
+
+void ButtonGroupCommand::breakButtonGroup()
+{
+ if (debugButtonMenu)
+ qDebug() << "Removing " << m_buttonGroup << " consisting of " << m_buttonList;
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ QDesignerFormEditorInterface *core = fw->core();
+ // Button group was selected, that is, break was invoked via its context menu. Remove it from property editor, select the buttons
+ if (core->propertyEditor()->object() == m_buttonGroup) {
+ fw->clearSelection(false);
+ const ButtonList::const_iterator cend = m_buttonList.constEnd();
+ for (ButtonList::const_iterator it = m_buttonList.constBegin(); it != cend; ++it)
+ fw->selectWidget(*it, true);
+ }
+ // Now remove and refresh object inspector
+ removeButtonsFromGroup();
+ // Notify components (for example, signal slot editor)
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(fw))
+ fwb->emitObjectRemoved(m_buttonGroup);
+ core->metaDataBase()->remove(m_buttonGroup);
+ core->objectInspector()->setFormWindow(fw);
+}
+
+QString ButtonGroupCommand::nameList(const ButtonList& bl)
+{
+ QString rc;
+ const QChar quote = QLatin1Char('\'');
+ const QString separator = QLatin1String(", ");
+ const int size = bl.size();
+ for (int i = 0; i < size; i++) {
+ if (i)
+ rc += separator;
+ rc += quote;
+ rc += bl[i]->objectName();
+ rc += quote;
+ }
+ return rc;
+
+}
+
+ButtonGroupList ButtonGroupCommand::managedButtonGroups(const QDesignerFormWindowInterface *formWindow)
+{
+ const QDesignerMetaDataBaseInterface *mdb = formWindow->core()->metaDataBase();
+ ButtonGroupList bl;
+ // Check 1st order children for managed button groups
+ const QObjectList children = formWindow->mainContainer()->children();
+ const QObjectList::const_iterator cend = children.constEnd();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it) {
+ if (!(*it)->isWidgetType())
+ if (QButtonGroup *bg = qobject_cast<QButtonGroup *>(*it))
+ if (mdb->item(bg))
+ bl.push_back(bg);
+ }
+ return bl;
+}
+
+// --------------- CreateButtonGroupCommand
+// This command might be executed in a macro with a remove
+// command to move buttons from one group to a new one.
+class CreateButtonGroupCommand : public ButtonGroupCommand {
+public:
+ CreateButtonGroupCommand(QDesignerFormWindowInterface *formWindow);
+ bool init(const ButtonList &bl);
+
+ virtual void undo() { breakButtonGroup(); }
+ virtual void redo() { createButtonGroup(); }
+};
+
+CreateButtonGroupCommand::CreateButtonGroupCommand(QDesignerFormWindowInterface *formWindow) :
+ ButtonGroupCommand(QApplication::translate("Command", "Create button group"), formWindow)
+{
+}
+
+bool CreateButtonGroupCommand::init(const ButtonList &bl)
+{
+ if (bl.empty())
+ return false;
+ QDesignerFormWindowInterface *fw = formWindow();
+ QButtonGroup *buttonGroup = new QButtonGroup(fw->mainContainer());
+ buttonGroup->setObjectName(QLatin1String("buttonGroup"));
+ fw->ensureUniqueObjectName(buttonGroup);
+ initialize(bl, buttonGroup);
+ return true;
+}
+
+// --------------- BreakButtonGroupCommand
+class BreakButtonGroupCommand : public ButtonGroupCommand {
+public:
+ BreakButtonGroupCommand(QDesignerFormWindowInterface *formWindow);
+ bool init(QButtonGroup *group);
+
+ virtual void undo() { createButtonGroup(); }
+ virtual void redo() { breakButtonGroup(); }
+};
+
+BreakButtonGroupCommand::BreakButtonGroupCommand(QDesignerFormWindowInterface *formWindow) :
+ ButtonGroupCommand(QApplication::translate("Command", "Break button group"), formWindow)
+{
+}
+
+bool BreakButtonGroupCommand::init(QButtonGroup *group)
+{
+ if (!group)
+ return false;
+ initialize(group->buttons(), group);
+ setText(QApplication::translate("Command", "Break button group '%1'").arg(group->objectName()));
+ return true;
+}
+
+// --------------- AddButtonsToGroupCommand
+// This command might be executed in a macro with a remove
+// command to move buttons from one group to a new one.
+class AddButtonsToGroupCommand : public ButtonGroupCommand {
+public:
+ AddButtonsToGroupCommand(QDesignerFormWindowInterface *formWindow);
+ void init(const ButtonList &bl, QButtonGroup *group);
+
+ virtual void undo() { removeButtonsFromGroup(); }
+ virtual void redo() { addButtonsToGroup(); }
+};
+
+AddButtonsToGroupCommand::AddButtonsToGroupCommand(QDesignerFormWindowInterface *formWindow) :
+ ButtonGroupCommand(QApplication::translate("Command", "Add buttons to group"), formWindow)
+{
+}
+
+void AddButtonsToGroupCommand::init(const ButtonList &bl, QButtonGroup *group)
+{
+ initialize(bl, group);
+ //: Command description for adding buttons to a QButtonGroup
+ setText(QApplication::translate("Command", "Add '%1' to '%2'").arg(nameList(bl), group->objectName()));
+}
+
+//-------------------- RemoveButtonsFromGroupCommand
+class RemoveButtonsFromGroupCommand : public ButtonGroupCommand {
+public:
+ RemoveButtonsFromGroupCommand(QDesignerFormWindowInterface *formWindow);
+ bool init(const ButtonList &bl);
+
+ virtual void undo() { addButtonsToGroup(); }
+ virtual void redo() { removeButtonsFromGroup(); }
+};
+
+RemoveButtonsFromGroupCommand::RemoveButtonsFromGroupCommand(QDesignerFormWindowInterface *formWindow) :
+ ButtonGroupCommand(QApplication::translate("Command", "Remove buttons from group"), formWindow)
+{
+}
+
+bool RemoveButtonsFromGroupCommand::init(const ButtonList &bl)
+{
+ if (bl.empty())
+ return false;
+ QButtonGroup *group = bl.front()->group();
+ if (!group)
+ return false;
+ if (bl.size() >= group->buttons().size())
+ return false;
+ initialize(bl, group);
+ //: Command description for removing buttons from a QButtonGroup
+ setText(QApplication::translate("Command", "Remove '%1' from '%2'").arg(nameList(bl), group->objectName()));
+ return true;
+}
+
+// -------- ButtonGroupMenu
+ButtonGroupMenu::ButtonGroupMenu(QObject *parent) :
+ QObject(parent),
+ m_selectGroupAction(new QAction(tr("Select members"), this)),
+ m_breakGroupAction(new QAction(tr("Break"), this)),
+ m_formWindow(0),
+ m_buttonGroup(0),
+ m_currentButton(0)
+{
+ connect(m_breakGroupAction, SIGNAL(triggered()), this, SLOT(breakGroup()));
+ connect(m_selectGroupAction, SIGNAL(triggered()), this, SLOT(selectGroup()));
+}
+
+void ButtonGroupMenu::initialize(QDesignerFormWindowInterface *formWindow, QButtonGroup *buttonGroup, QAbstractButton *currentButton)
+{
+ m_buttonGroup = buttonGroup;
+ m_currentButton = currentButton;
+ m_formWindow = formWindow;
+ Q_ASSERT(m_formWindow);
+
+ const bool canBreak = buttonGroup != 0;
+ m_breakGroupAction->setEnabled(canBreak);
+ m_selectGroupAction->setEnabled(canBreak);
+}
+
+void ButtonGroupMenu::selectGroup()
+{
+ // Select and make current button "current" again by selecting it last (if there is any)
+ const ButtonList buttons = m_buttonGroup->buttons();
+ m_formWindow->clearSelection(false);
+ const ButtonList::const_iterator cend = buttons.constEnd();
+ for (ButtonList::const_iterator it = buttons.constBegin(); it != cend; ++it)
+ if (*it != m_currentButton)
+ m_formWindow->selectWidget(*it, true);
+ if (m_currentButton)
+ m_formWindow->selectWidget(m_currentButton, true);
+}
+
+void ButtonGroupMenu::breakGroup()
+{
+ BreakButtonGroupCommand *cmd = new BreakButtonGroupCommand(m_formWindow);
+ if (cmd->init(m_buttonGroup)) {
+ // Need a macro since the command might trigger additional commands
+ QUndoStack *history = m_formWindow->commandHistory();
+ history->beginMacro(cmd->text());
+ history->push(cmd);
+ history->endMacro();
+ } else {
+ qWarning("** WARNING Failed to initialize BreakButtonGroupCommand!");
+ delete cmd;
+ }
+}
+
+// ButtonGroupTaskMenu
+ButtonGroupTaskMenu::ButtonGroupTaskMenu(QButtonGroup *buttonGroup, QObject *parent) :
+ QObject(parent),
+ m_buttonGroup(buttonGroup)
+{
+ m_taskActions.push_back(m_menu.breakGroupAction());
+ m_taskActions.push_back(m_menu.selectGroupAction());
+}
+
+QAction *ButtonGroupTaskMenu::preferredEditAction() const
+{
+ return m_menu.selectGroupAction();
+}
+
+QList<QAction*> ButtonGroupTaskMenu::taskActions() const
+{
+ m_menu.initialize(QDesignerFormWindowInterface::findFormWindow(m_buttonGroup), m_buttonGroup);
+ return m_taskActions;
+}
+
+// -------- Text area editor
+class ButtonTextTaskMenuInlineEditor : public TaskMenuInlineEditor
+{
+public:
+ ButtonTextTaskMenuInlineEditor(QAbstractButton *button, QObject *parent);
+
+protected:
+ virtual QRect editRectangle() const;
+};
+
+ButtonTextTaskMenuInlineEditor::ButtonTextTaskMenuInlineEditor(QAbstractButton *button, QObject *parent) :
+ TaskMenuInlineEditor(button, ValidationMultiLine, QLatin1String("text"), parent)
+{
+}
+
+QRect ButtonTextTaskMenuInlineEditor::editRectangle() const
+{
+ QWidget *w = widget();
+ QStyleOptionButton opt;
+ opt.init(w);
+ return w->style()->subElementRect(QStyle::SE_PushButtonContents, &opt, w);
+}
+
+// -------- Command link button description editor
+class LinkDescriptionTaskMenuInlineEditor : public TaskMenuInlineEditor
+{
+public:
+ LinkDescriptionTaskMenuInlineEditor(QAbstractButton *button, QObject *parent);
+
+protected:
+ virtual QRect editRectangle() const;
+};
+
+LinkDescriptionTaskMenuInlineEditor::LinkDescriptionTaskMenuInlineEditor(QAbstractButton *button, QObject *parent) :
+ TaskMenuInlineEditor(button, ValidationMultiLine, QLatin1String("description"), parent)
+{
+}
+
+QRect LinkDescriptionTaskMenuInlineEditor::editRectangle() const
+{
+ QWidget *w = widget(); // TODO: What is the exact description area?
+ QStyleOptionButton opt;
+ opt.init(w);
+ return w->style()->subElementRect(QStyle::SE_PushButtonContents, &opt, w);
+}
+
+// ----------- ButtonTaskMenu:
+
+ButtonTaskMenu::ButtonTaskMenu(QAbstractButton *button, QObject *parent) :
+ QDesignerTaskMenu(button, parent),
+ m_assignGroupSubMenu(new QMenu),
+ m_assignActionGroup(0),
+ m_assignToGroupSubMenuAction(new QAction(tr("Assign to button group"), this)),
+ m_currentGroupSubMenu(new QMenu),
+ m_currentGroupSubMenuAction(new QAction(tr("Button group"), this)),
+ m_createGroupAction(new QAction(tr("New button group"), this)),
+ m_preferredEditAction(new QAction(tr("Change text..."), this)),
+ m_removeFromGroupAction(new QAction(tr("None"), this))
+{
+ connect(m_createGroupAction, SIGNAL(triggered()), this, SLOT(createGroup()));
+ TaskMenuInlineEditor *textEditor = new ButtonTextTaskMenuInlineEditor(button, this);
+ connect(m_preferredEditAction, SIGNAL(triggered()), textEditor, SLOT(editText()));
+ connect(m_removeFromGroupAction, SIGNAL(triggered()), this, SLOT(removeFromGroup()));
+
+ m_assignToGroupSubMenuAction->setMenu(m_assignGroupSubMenu);
+
+ m_currentGroupSubMenu->addAction(m_groupMenu.breakGroupAction());
+ m_currentGroupSubMenu->addAction(m_groupMenu.selectGroupAction());
+ m_currentGroupSubMenuAction->setMenu(m_currentGroupSubMenu);
+
+
+ m_taskActions.append(m_preferredEditAction);
+ m_taskActions.append(m_assignToGroupSubMenuAction);
+ m_taskActions.append(m_currentGroupSubMenuAction);
+ m_taskActions.append(createSeparator());
+}
+
+ButtonTaskMenu::~ButtonTaskMenu()
+{
+ delete m_assignGroupSubMenu;
+ delete m_currentGroupSubMenu;
+}
+
+QAction *ButtonTaskMenu::preferredEditAction() const
+{
+ return m_preferredEditAction;
+}
+
+bool ButtonTaskMenu::refreshAssignMenu(const QDesignerFormWindowInterface *fw, int buttonCount, SelectionType st, QButtonGroup *currentGroup)
+{
+ // clear
+ if (m_assignActionGroup) {
+ delete m_assignActionGroup;
+ m_assignActionGroup = 0;
+ }
+ m_assignGroupSubMenu->clear();
+ if (st == OtherSelection)
+ return false;
+
+
+ // Assign to new: Need several
+ const bool canAssignToNewGroup = buttonCount > 1;
+ m_createGroupAction->setEnabled(canAssignToNewGroup);
+ if (canAssignToNewGroup)
+ m_assignGroupSubMenu->addAction(m_createGroupAction);
+
+ // Assign to other
+ const ButtonGroupList bl = ButtonGroupCommand::managedButtonGroups(fw);
+ // Groups: Any groups to add to except the current?
+ const int groupCount = bl.size();
+ const bool hasAddGroups = groupCount > 1 || (groupCount == 1 && !bl.contains(currentGroup));
+ if (hasAddGroups) {
+ if (!m_assignGroupSubMenu->isEmpty())
+ m_assignGroupSubMenu->addSeparator();
+ // Create a new action group
+ m_assignActionGroup = new QActionGroup(this);
+ connect(m_assignActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(addToGroup(QAction*)));
+
+ const ButtonGroupList::const_iterator cend = bl.constEnd();
+ for (ButtonGroupList::const_iterator it = bl.constBegin(); it != cend; ++it) {
+ QButtonGroup *bg = *it;
+ if (*it != currentGroup) {
+ QAction *a = new QAction(bg->objectName(), m_assignGroupSubMenu);
+ a->setData(QVariant::fromValue(bg));
+ m_assignActionGroup->addAction(a);
+ m_assignGroupSubMenu->addAction(a);
+ }
+ }
+ }
+ // Can remove: A homogenous selection of another group that does not completely break it.
+ const bool canRemoveFromGroup = st == GroupedButtonSelection;
+ m_removeFromGroupAction->setEnabled(canRemoveFromGroup);
+ if (canRemoveFromGroup) {
+ if (!m_assignGroupSubMenu->isEmpty())
+ m_assignGroupSubMenu->addSeparator();
+ m_assignGroupSubMenu->addAction(m_removeFromGroupAction);
+ }
+ return !m_assignGroupSubMenu->isEmpty();
+}
+
+QList<QAction*> ButtonTaskMenu::taskActions() const
+{
+ ButtonTaskMenu *ncThis = const_cast<ButtonTaskMenu*>(this);
+ QButtonGroup *buttonGroup = 0;
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ const SelectionType st = selectionType(fw->cursor(), &buttonGroup);
+
+ m_groupMenu.initialize(fw, buttonGroup, button());
+ const bool hasAssignOptions = ncThis->refreshAssignMenu(fw, fw->cursor()->selectedWidgetCount(), st, buttonGroup);
+ m_assignToGroupSubMenuAction->setVisible(hasAssignOptions);
+ // add/remove
+ switch (st) {
+ case UngroupedButtonSelection:
+ case OtherSelection:
+ m_currentGroupSubMenuAction->setVisible(false);
+ break;
+ case GroupedButtonSelection:
+ m_currentGroupSubMenuAction->setText(tr("Button group '%1'").arg(buttonGroup->objectName()));
+ m_currentGroupSubMenuAction->setVisible(true);
+ break;
+ }
+
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+
+void ButtonTaskMenu::insertAction(int index, QAction *a)
+{
+ m_taskActions.insert(index, a);
+}
+
+/* Create a button list from the cursor selection */
+static ButtonList buttonList(const QDesignerFormWindowCursorInterface *cursor)
+{
+ ButtonList rc;
+ const int selectionCount = cursor->selectedWidgetCount();
+ for (int i = 0; i < selectionCount; i++) {
+ QAbstractButton *ab = qobject_cast<QAbstractButton *>(cursor->selectedWidget(i));
+ Q_ASSERT(ab);
+ rc += ab;
+ }
+ return rc;
+}
+
+// Create a command to remove the buttons from their group
+// If it would leave an empty or 1-member group behind, create a break command instead
+
+static QUndoCommand *createRemoveButtonsCommand(QDesignerFormWindowInterface *fw, const ButtonList &bl)
+{
+
+ QButtonGroup *bg = bl.front()->group();
+ // Complete group or 1-member group?
+ if (bl.size() >= bg->buttons().size() - 1) {
+ BreakButtonGroupCommand *breakCmd = new BreakButtonGroupCommand(fw);
+ if (!breakCmd->init(bg)) {
+ qWarning("** WARNING Failed to initialize BreakButtonGroupCommand!");
+ delete breakCmd;
+ return 0;
+ }
+ return breakCmd;
+ }
+ // Just remove the buttons
+
+ RemoveButtonsFromGroupCommand *removeCmd = new RemoveButtonsFromGroupCommand(fw);
+ if (!removeCmd->init(bl)) {
+ qWarning("** WARNING Failed to initialize RemoveButtonsFromGroupCommand!");
+ delete removeCmd;
+ return 0;
+ }
+ return removeCmd;
+}
+
+void ButtonTaskMenu::createGroup()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ const ButtonList bl = buttonList(fw->cursor());
+ // Do we need to remove the buttons from an existing group?
+ QUndoCommand *removeCmd = 0;
+ if (bl.front()->group()) {
+ removeCmd = createRemoveButtonsCommand(fw, bl);
+ if (!removeCmd)
+ return;
+ }
+ // Add cmd
+ CreateButtonGroupCommand *addCmd = new CreateButtonGroupCommand(fw);
+ if (!addCmd->init(bl)) {
+ qWarning("** WARNING Failed to initialize CreateButtonGroupCommand!");
+ delete addCmd;
+ return;
+ }
+ // Need a macro [even if we only have the add command] since the command might trigger additional commands
+ QUndoStack *history = fw->commandHistory();
+ history->beginMacro(addCmd->text());
+ if (removeCmd)
+ history->push(removeCmd);
+ history->push(addCmd);
+ history->endMacro();
+}
+
+QAbstractButton *ButtonTaskMenu::button() const
+{
+ return qobject_cast<QAbstractButton *>(widget());
+}
+
+// Figure out if we have a homogenous selections (buttons of the same group or no group)
+ButtonTaskMenu::SelectionType ButtonTaskMenu::selectionType(const QDesignerFormWindowCursorInterface *cursor, QButtonGroup **ptrToGroup) const
+{
+ const int selectionCount = cursor->selectedWidgetCount();
+ if (!selectionCount)
+ return OtherSelection;
+
+ QButtonGroup *commonGroup = 0;
+ for (int i = 0; i < selectionCount; i++) {
+ if (const QAbstractButton *ab = qobject_cast<const QAbstractButton *>(cursor->selectedWidget(i))) {
+ QButtonGroup *buttonGroup = ab->group();
+ if (i) {
+ if (buttonGroup != commonGroup)
+ return OtherSelection;
+ } else {
+ commonGroup = buttonGroup;
+ }
+ } else {
+ return OtherSelection;
+ }
+ }
+
+ if (ptrToGroup)
+ *ptrToGroup = commonGroup;
+
+ return commonGroup ? GroupedButtonSelection : UngroupedButtonSelection;
+}
+
+void ButtonTaskMenu::addToGroup(QAction *a)
+{
+ QButtonGroup *bg = qvariant_cast<QButtonGroup *>(a->data());
+ Q_ASSERT(bg);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ const ButtonList bl = buttonList(fw->cursor());
+ // Do we need to remove the buttons from an existing group?
+ QUndoCommand *removeCmd = 0;
+ if (bl.front()->group()) {
+ removeCmd = createRemoveButtonsCommand(fw, bl);
+ if (!removeCmd)
+ return;
+ }
+ AddButtonsToGroupCommand *addCmd = new AddButtonsToGroupCommand(fw);
+ addCmd->init(bl, bg);
+
+ QUndoStack *history = fw->commandHistory();
+ if (removeCmd) {
+ history->beginMacro(addCmd->text());
+ history->push(removeCmd);
+ history->push(addCmd);
+ history->endMacro();
+ } else {
+ history->push(addCmd);
+ }
+}
+
+void ButtonTaskMenu::removeFromGroup()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (QUndoCommand *cmd = createRemoveButtonsCommand(fw, buttonList(fw->cursor())))
+ fw->commandHistory()->push(cmd);
+}
+
+// -------------- CommandLinkButtonTaskMenu
+
+CommandLinkButtonTaskMenu::CommandLinkButtonTaskMenu(QCommandLinkButton *button, QObject *parent) :
+ ButtonTaskMenu(button, parent)
+{
+ TaskMenuInlineEditor *descriptonEditor = new LinkDescriptionTaskMenuInlineEditor(button, this);
+ QAction *descriptionAction = new QAction(tr("Change description..."), this);
+ connect(descriptionAction, SIGNAL(triggered()), descriptonEditor, SLOT(editText()));
+ insertAction(1, descriptionAction);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/button_taskmenu.h b/src/designer/src/components/taskmenu/button_taskmenu.h
new file mode 100644
index 000000000..e7350ca87
--- /dev/null
+++ b/src/designer/src/components/taskmenu/button_taskmenu.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BUTTON_TASKMENU_H
+#define BUTTON_TASKMENU_H
+
+#include <QtGui/QAbstractButton>
+#include <QtGui/QCommandLinkButton>
+#include <QtGui/QButtonGroup>
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMenu;
+class QActionGroup;
+class QDesignerFormWindowCursorInterface;
+
+namespace qdesigner_internal {
+
+// ButtonGroupMenu: Mixin menu for the 'select members'/'break group' options of
+// the task menu of buttons and button group
+class ButtonGroupMenu : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(ButtonGroupMenu)
+public:
+ ButtonGroupMenu(QObject *parent = 0);
+
+ void initialize(QDesignerFormWindowInterface *formWindow,
+ QButtonGroup *buttonGroup = 0,
+ /* Current button for selection in ButtonMode */
+ QAbstractButton *currentButton = 0);
+
+ QAction *selectGroupAction() const { return m_selectGroupAction; }
+ QAction *breakGroupAction() const { return m_breakGroupAction; }
+
+private slots:
+ void selectGroup();
+ void breakGroup();
+
+private:
+ QAction *m_selectGroupAction;
+ QAction *m_breakGroupAction;
+
+ QDesignerFormWindowInterface *m_formWindow;
+ QButtonGroup *m_buttonGroup;
+ QAbstractButton *m_currentButton;
+};
+
+// Task menu extension of a QButtonGroup
+class ButtonGroupTaskMenu : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(ButtonGroupTaskMenu)
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit ButtonGroupTaskMenu(QButtonGroup *buttonGroup, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private:
+ QButtonGroup *m_buttonGroup;
+ QList<QAction*> m_taskActions;
+ mutable ButtonGroupMenu m_menu;
+};
+
+// Task menu extension of a QAbstractButton
+class ButtonTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(ButtonTaskMenu)
+public:
+ explicit ButtonTaskMenu(QAbstractButton *button, QObject *parent = 0);
+ virtual ~ButtonTaskMenu();
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+ QAbstractButton *button() const;
+
+protected:
+ void insertAction(int index, QAction *a);
+
+private slots:
+ void createGroup();
+ void addToGroup(QAction *a);
+ void removeFromGroup();
+
+private:
+ enum SelectionType {
+ OtherSelection,
+ UngroupedButtonSelection,
+ GroupedButtonSelection
+ };
+
+ SelectionType selectionType(const QDesignerFormWindowCursorInterface *cursor, QButtonGroup ** ptrToGroup = 0) const;
+ bool refreshAssignMenu(const QDesignerFormWindowInterface *fw, int buttonCount, SelectionType st, QButtonGroup *currentGroup);
+ QMenu *createGroupSelectionMenu(const QDesignerFormWindowInterface *fw);
+
+ QList<QAction*> m_taskActions;
+ mutable ButtonGroupMenu m_groupMenu;
+ QMenu *m_assignGroupSubMenu;
+ QActionGroup *m_assignActionGroup;
+ QAction *m_assignToGroupSubMenuAction;
+ QMenu *m_currentGroupSubMenu;
+ QAction *m_currentGroupSubMenuAction;
+
+ QAction *m_createGroupAction;
+ QAction *m_preferredEditAction;
+ QAction *m_removeFromGroupAction;
+};
+
+// Task menu extension of a QCommandLinkButton
+class CommandLinkButtonTaskMenu: public ButtonTaskMenu
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(CommandLinkButtonTaskMenu)
+public:
+ explicit CommandLinkButtonTaskMenu(QCommandLinkButton *button, QObject *parent = 0);
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QButtonGroup, ButtonGroupTaskMenu> ButtonGroupTaskMenuFactory;
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QCommandLinkButton, CommandLinkButtonTaskMenu> CommandLinkButtonTaskMenuFactory;
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QAbstractButton, ButtonTaskMenu> ButtonTaskMenuFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // BUTTON_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/combobox_taskmenu.cpp b/src/designer/src/components/taskmenu/combobox_taskmenu.cpp
new file mode 100644
index 000000000..2b9b1fe19
--- /dev/null
+++ b/src/designer/src/components/taskmenu/combobox_taskmenu.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "combobox_taskmenu.h"
+#include "listwidgeteditor.h"
+#include "qdesigner_utils_p.h"
+#include <qdesigner_command_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QStyle>
+#include <QtGui/QLineEdit>
+#include <QtGui/QFontComboBox>
+#include <QtGui/QStyleOption>
+
+#include <QtCore/QEvent>
+#include <QtCore/QVariant>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+ComboBoxTaskMenu::ComboBoxTaskMenu(QComboBox *button, QObject *parent)
+ : QDesignerTaskMenu(button, parent),
+ m_comboBox(button)
+{
+ m_editItemsAction = new QAction(this);
+ m_editItemsAction->setText(tr("Edit Items..."));
+ connect(m_editItemsAction, SIGNAL(triggered()), this, SLOT(editItems()));
+ m_taskActions.append(m_editItemsAction);
+
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ m_taskActions.append(sep);
+}
+
+ComboBoxTaskMenu::~ComboBoxTaskMenu()
+{
+}
+
+QAction *ComboBoxTaskMenu::preferredEditAction() const
+{
+ return m_editItemsAction;
+}
+
+QList<QAction*> ComboBoxTaskMenu::taskActions() const
+{
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+void ComboBoxTaskMenu::editItems()
+{
+ m_formWindow = QDesignerFormWindowInterface::findFormWindow(m_comboBox);
+ if (m_formWindow.isNull())
+ return;
+
+ Q_ASSERT(m_comboBox != 0);
+
+ ListWidgetEditor dlg(m_formWindow, m_comboBox->window());
+ ListContents oldItems = dlg.fillContentsFromComboBox(m_comboBox);
+ if (dlg.exec() == QDialog::Accepted) {
+ ListContents items = dlg.contents();
+ if (items != oldItems) {
+ ChangeListContentsCommand *cmd = new ChangeListContentsCommand(m_formWindow);
+ cmd->init(m_comboBox, oldItems, items);
+ cmd->setText(tr("Change Combobox Contents"));
+ m_formWindow->commandHistory()->push(cmd);
+ }
+ }
+}
+
+ComboBoxTaskMenuFactory::ComboBoxTaskMenuFactory(const QString &iid, QExtensionManager *extensionManager) :
+ ExtensionFactory<QDesignerTaskMenuExtension, QComboBox, ComboBoxTaskMenu>(iid, extensionManager)
+{
+}
+
+QComboBox *ComboBoxTaskMenuFactory::checkObject(QObject *qObject) const
+{
+ QComboBox *combo = qobject_cast<QComboBox*>(qObject);
+ if (!combo)
+ return 0;
+ if (qobject_cast<QFontComboBox*>(combo))
+ return 0;
+ return combo;
+}
+
+void ComboBoxTaskMenu::updateSelection()
+{
+ if (m_editor)
+ m_editor->deleteLater();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/combobox_taskmenu.h b/src/designer/src/components/taskmenu/combobox_taskmenu.h
new file mode 100644
index 000000000..c1eee4837
--- /dev/null
+++ b/src/designer/src/components/taskmenu/combobox_taskmenu.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMBOBOX_TASKMENU_H
+#define COMBOBOX_TASKMENU_H
+
+#include <QtGui/QComboBox>
+#include <QtCore/QPointer>
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QLineEdit;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class ComboBoxTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit ComboBoxTaskMenu(QComboBox *button,
+ QObject *parent = 0);
+ virtual ~ComboBoxTaskMenu();
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void editItems();
+ void updateSelection();
+
+private:
+ QComboBox *m_comboBox;
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+ QPointer<QLineEdit> m_editor;
+ mutable QList<QAction*> m_taskActions;
+ QAction *m_editItemsAction;
+};
+
+class ComboBoxTaskMenuFactory : public ExtensionFactory<QDesignerTaskMenuExtension, QComboBox, ComboBoxTaskMenu>
+{
+public:
+ explicit ComboBoxTaskMenuFactory(const QString &iid, QExtensionManager *extensionManager);
+
+private:
+ virtual QComboBox *checkObject(QObject *qObject) const;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // COMBOBOX_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp b/src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp
new file mode 100644
index 000000000..244ea00ff
--- /dev/null
+++ b/src/designer/src/components/taskmenu/containerwidget_taskmenu.cpp
@@ -0,0 +1,348 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "containerwidget_taskmenu.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerContainerExtension>
+
+#include <qdesigner_command_p.h>
+#include <qdesigner_dockwidget_p.h>
+#include <promotiontaskmenu_p.h>
+#include <widgetdatabase_p.h>
+
+#include <QtGui/QAction>
+#include <QtGui/QMainWindow>
+#include <QtGui/QToolBox>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QTabWidget>
+#include <QtGui/QScrollArea>
+#include <QtGui/QMdiArea>
+#include <QtGui/QWorkspace>
+#include <QtGui/QWizard>
+#include <QtGui/QMenu>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+ContainerWidgetTaskMenu::ContainerWidgetTaskMenu(QWidget *widget, ContainerType type, QObject *parent) :
+ QDesignerTaskMenu(widget, parent),
+ m_type(type),
+ m_containerWidget(widget),
+ m_core(formWindow()->core()),
+ m_pagePromotionTaskMenu(new PromotionTaskMenu(0, PromotionTaskMenu::ModeSingleWidget, this)),
+ m_pageMenuAction(new QAction(this)),
+ m_pageMenu(new QMenu),
+ m_actionDeletePage(new QAction(tr("Delete"), this))
+{
+ Q_ASSERT(m_core);
+ m_taskActions.append(createSeparator());
+
+ connect(m_actionDeletePage, SIGNAL(triggered()), this, SLOT(removeCurrentPage()));
+
+ QAction *actionInsertPageAfter = new QAction(this);
+ connect(actionInsertPageAfter, SIGNAL(triggered()), this, SLOT(addPageAfter()));
+ // Empty Per-Page submenu, deletion and promotion. Updated on demand due to promotion state
+ switch (m_type) {
+ case WizardContainer:
+ case PageContainer:
+ m_taskActions.append(createSeparator()); // for the browse actions
+ break;
+ case MdiContainer:
+ break;
+ }
+ // submenu
+ m_pageMenuAction->setMenu(m_pageMenu);
+ m_taskActions.append(m_pageMenuAction);
+ // Insertion
+ switch (m_type) {
+ case WizardContainer:
+ case PageContainer: { // Before and after in a submenu
+ QAction *insertMenuAction = new QAction(tr("Insert"), this);
+ QMenu *insertMenu = new QMenu;
+ // before
+ QAction *actionInsertPage = new QAction(tr("Insert Page Before Current Page"), this);
+ connect(actionInsertPage, SIGNAL(triggered()), this, SLOT(addPage()));
+ insertMenu->addAction(actionInsertPage);
+ // after
+ actionInsertPageAfter->setText(tr("Insert Page After Current Page"));
+ insertMenu->addAction(actionInsertPageAfter);
+
+ insertMenuAction->setMenu(insertMenu);
+ m_taskActions.append(insertMenuAction);
+ }
+ break;
+ case MdiContainer: // No concept of order
+ actionInsertPageAfter->setText(tr("Add Subwindow"));
+ m_taskActions.append(actionInsertPageAfter);
+ break;
+ }
+}
+
+ContainerWidgetTaskMenu::~ContainerWidgetTaskMenu()
+{
+}
+
+QAction *ContainerWidgetTaskMenu::preferredEditAction() const
+{
+ return 0;
+}
+
+bool ContainerWidgetTaskMenu::canDeletePage() const
+{
+ switch (pageCount()) {
+ case 0:
+ return false;
+ case 1:
+ return m_type != PageContainer; // Do not delete last page of page-type container
+ default:
+ break;
+ }
+ return true;
+}
+
+int ContainerWidgetTaskMenu::pageCount() const
+{
+ if (const QDesignerContainerExtension *ce = containerExtension())
+ return ce->count();
+ return 0;
+}
+
+QString ContainerWidgetTaskMenu::pageMenuText(ContainerType ct, int index, int count)
+{
+ if (ct == MdiContainer)
+ return tr("Subwindow"); // No concept of order, same text everywhere
+ if (index < 0)
+ return tr("Page");
+ return tr("Page %1 of %2").arg(index + 1).arg(count);
+}
+
+QList<QAction*> ContainerWidgetTaskMenu::taskActions() const
+{
+ QList<QAction*> actions = QDesignerTaskMenu::taskActions();
+ actions += m_taskActions;
+ // Update the page submenu, deletion and promotion. Updated on demand due to promotion state.
+ m_pageMenu->clear();
+ m_pageMenu->addAction(m_actionDeletePage);
+ m_actionDeletePage->setEnabled(canDeletePage());
+ const QDesignerContainerExtension *ce = containerExtension();
+ const int index = ce->currentIndex();
+ m_pageMenuAction->setText(pageMenuText(m_type, index, ce->count()));
+ if (index != -1) { // Has a page
+ m_pageMenuAction->setEnabled(true);
+ m_pagePromotionTaskMenu->setWidget(ce->widget(index));
+ m_pagePromotionTaskMenu->addActions(PromotionTaskMenu::LeadingSeparator|PromotionTaskMenu::SuppressGlobalEdit, m_pageMenu);
+ } else { // No page
+ m_pageMenuAction->setEnabled(false);
+ }
+
+ return actions;
+}
+
+QDesignerFormWindowInterface *ContainerWidgetTaskMenu::formWindow() const
+{
+ return QDesignerFormWindowInterface::findFormWindow(m_containerWidget);
+}
+
+QDesignerContainerExtension *ContainerWidgetTaskMenu::containerExtension() const
+{
+ QExtensionManager *mgr = m_core->extensionManager();
+ return qt_extension<QDesignerContainerExtension*>(mgr, m_containerWidget);
+}
+
+void ContainerWidgetTaskMenu::removeCurrentPage()
+{
+ if (QDesignerContainerExtension *c = containerExtension()) {
+ if (c->currentIndex() == -1)
+ return;
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ DeleteContainerWidgetPageCommand *cmd = new DeleteContainerWidgetPageCommand(fw);
+ cmd->init(m_containerWidget, m_type);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void ContainerWidgetTaskMenu::addPage()
+{
+ if (containerExtension()) {
+ QDesignerFormWindowInterface *fw = formWindow();
+ AddContainerWidgetPageCommand *cmd = new AddContainerWidgetPageCommand(fw);
+ cmd->init(m_containerWidget, m_type, AddContainerWidgetPageCommand::InsertBefore);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void ContainerWidgetTaskMenu::addPageAfter()
+{
+ if (containerExtension()) {
+ QDesignerFormWindowInterface *fw = formWindow();
+ AddContainerWidgetPageCommand *cmd = new AddContainerWidgetPageCommand(fw);
+ cmd->init(m_containerWidget, m_type, AddContainerWidgetPageCommand::InsertAfter);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+// -------------- WizardContainerWidgetTaskMenu
+WizardContainerWidgetTaskMenu::WizardContainerWidgetTaskMenu(QWizard *w, QObject *parent) :
+ ContainerWidgetTaskMenu(w, WizardContainer, parent),
+ m_nextAction(new QAction(tr("Next"), this)),
+ m_previousAction(new QAction(tr("Back"), this))
+{
+ connect(m_nextAction, SIGNAL(triggered()), w, SLOT(next()));
+ connect(m_previousAction, SIGNAL(triggered()), w, SLOT(back()));
+ QList<QAction*> &l = containerActions();
+ l.push_front(createSeparator());
+ l.push_front(m_nextAction);
+ l.push_front(m_previousAction);
+ l.push_front(createSeparator());
+}
+
+QList<QAction*> WizardContainerWidgetTaskMenu::taskActions() const
+{
+ // Enable
+ const QDesignerContainerExtension *ce = containerExtension();
+ const int index = ce->currentIndex();
+ m_previousAction->setEnabled(index > 0);
+ m_nextAction->setEnabled(index >= 0 && index < (ce->count() - 1));
+ return ContainerWidgetTaskMenu::taskActions();
+}
+
+// -------------- MdiContainerWidgetTaskMenu
+
+MdiContainerWidgetTaskMenu::MdiContainerWidgetTaskMenu(QMdiArea *m, QObject *parent) :
+ ContainerWidgetTaskMenu(m, MdiContainer, parent)
+{
+ initializeActions();
+ connect(m_nextAction, SIGNAL(triggered()), m, SLOT(activateNextSubWindow()));
+ connect(m_previousAction, SIGNAL(triggered()), m , SLOT(activatePreviousSubWindow()));
+ connect(m_tileAction, SIGNAL(triggered()), m, SLOT(tileSubWindows()));
+ connect(m_cascadeAction, SIGNAL(triggered()), m, SLOT(cascadeSubWindows()));
+}
+
+MdiContainerWidgetTaskMenu::MdiContainerWidgetTaskMenu(QWorkspace *m, QObject *parent) :
+ ContainerWidgetTaskMenu(m, MdiContainer, parent)
+{
+ initializeActions();
+ connect(m_nextAction, SIGNAL(triggered()), m, SLOT(activateNextWindow()));
+ connect(m_previousAction, SIGNAL(triggered()), m, SLOT(activatePreviousWindow()));
+ connect(m_tileAction, SIGNAL(triggered()),m , SLOT(tile()));
+ connect(m_cascadeAction, SIGNAL(triggered()), m, SLOT(cascade()));
+}
+
+void MdiContainerWidgetTaskMenu::initializeActions()
+{
+ m_nextAction =new QAction(tr("Next Subwindow"), this);
+ m_previousAction = new QAction(tr("Previous Subwindow"), this);
+ m_tileAction = new QAction(tr("Tile"), this);
+ m_cascadeAction = new QAction(tr("Cascade"), this);
+
+ QList<QAction*> &l = containerActions();
+ l.push_front(createSeparator());
+ l.push_front(m_tileAction);
+ l.push_front(m_cascadeAction);
+ l.push_front(m_previousAction);
+ l.push_front(m_nextAction);
+ l.push_front(createSeparator());
+}
+
+QList<QAction*> MdiContainerWidgetTaskMenu::taskActions() const
+{
+ const QList<QAction*> rc = ContainerWidgetTaskMenu::taskActions();
+ // Enable
+ const int count = pageCount();
+ m_nextAction->setEnabled(count > 1);
+ m_previousAction->setEnabled(count > 1);
+ m_tileAction->setEnabled(count);
+ m_cascadeAction->setEnabled(count);
+ return rc;
+}
+
+// -------------- ContainerWidgetTaskMenuFactory
+
+ContainerWidgetTaskMenuFactory::ContainerWidgetTaskMenuFactory(QDesignerFormEditorInterface *core, QExtensionManager *extensionManager) :
+ QExtensionFactory(extensionManager),
+ m_core(core)
+{
+}
+
+QObject *ContainerWidgetTaskMenuFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != QLatin1String("QDesignerInternalTaskMenuExtension") || !object->isWidgetType())
+ return 0;
+
+ QWidget *widget = qobject_cast<QWidget*>(object);
+
+ if (qobject_cast<QStackedWidget*>(widget)
+ || qobject_cast<QToolBox*>(widget)
+ || qobject_cast<QTabWidget*>(widget)
+ || qobject_cast<QDesignerDockWidget*>(widget)
+ || qobject_cast<QScrollArea*>(widget)
+ || qobject_cast<QMainWindow*>(widget)) {
+ // Are we using Designer's own container extensions and task menus or did
+ // someone provide an extra one with an addpage method, for example for a QScrollArea?
+ if (const WidgetDataBase *wb = qobject_cast<const WidgetDataBase *>(m_core->widgetDataBase())) {
+ const int idx = wb->indexOfObject(widget);
+ const WidgetDataBaseItem *item = static_cast<const WidgetDataBaseItem *>(wb->item(idx));
+ if (item->addPageMethod().isEmpty())
+ return 0;
+ }
+ }
+
+ if (qt_extension<QDesignerContainerExtension*>(extensionManager(), object) == 0)
+ return 0;
+
+ if (QMdiArea* ma = qobject_cast<QMdiArea*>(widget))
+ return new MdiContainerWidgetTaskMenu(ma, parent);
+ if (QWorkspace *ws = qobject_cast<QWorkspace*>(widget))
+ return new MdiContainerWidgetTaskMenu(ws, parent);
+ if (QWizard *wz = qobject_cast<QWizard *>(widget))
+ return new WizardContainerWidgetTaskMenu(wz, parent);
+ return new ContainerWidgetTaskMenu(widget, PageContainer, parent);
+}
+
+}
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/containerwidget_taskmenu.h b/src/designer/src/components/taskmenu/containerwidget_taskmenu.h
new file mode 100644
index 000000000..6c5f1d481
--- /dev/null
+++ b/src/designer/src/components/taskmenu/containerwidget_taskmenu.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONTAINERWIDGER_TASKMENU_H
+#define CONTAINERWIDGER_TASKMENU_H
+
+#include <qdesigner_taskmenu_p.h>
+#include <shared_enums_p.h>
+
+#include <extensionfactory_p.h>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+class QDesignerContainerExtension;
+class QAction;
+class QMdiArea;
+class QWorkspace;
+class QMenu;
+class QWizard;
+
+namespace qdesigner_internal {
+
+class PromotionTaskMenu;
+
+// ContainerWidgetTaskMenu: Task menu for containers with extension
+
+class ContainerWidgetTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit ContainerWidgetTaskMenu(QWidget *widget, ContainerType type, QObject *parent = 0);
+ virtual ~ContainerWidgetTaskMenu();
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void removeCurrentPage();
+ void addPage();
+ void addPageAfter();
+
+protected:
+ QDesignerContainerExtension *containerExtension() const;
+ QList<QAction*> &containerActions() { return m_taskActions; }
+ int pageCount() const;
+
+private:
+ QDesignerFormWindowInterface *formWindow() const;
+
+private:
+ static QString pageMenuText(ContainerType ct, int index, int count);
+ bool canDeletePage() const;
+
+ const ContainerType m_type;
+ QWidget *m_containerWidget;
+ QDesignerFormEditorInterface *m_core;
+ PromotionTaskMenu *m_pagePromotionTaskMenu;
+ QAction *m_pageMenuAction;
+ QMenu *m_pageMenu;
+ QList<QAction*> m_taskActions;
+ QAction *m_actionDeletePage;
+};
+
+// WizardContainerWidgetTaskMenu: Provide next/back since QWizard
+// has modes in which the "Back" button is not visible.
+
+class WizardContainerWidgetTaskMenu : public ContainerWidgetTaskMenu {
+ Q_OBJECT
+public:
+ explicit WizardContainerWidgetTaskMenu(QWizard *w, QObject *parent = 0);
+
+ virtual QList<QAction*> taskActions() const;
+
+private:
+ QAction *m_nextAction;
+ QAction *m_previousAction;
+};
+
+
+// MdiContainerWidgetTaskMenu: Provide tile/cascade for MDI containers in addition
+
+class MdiContainerWidgetTaskMenu : public ContainerWidgetTaskMenu {
+ Q_OBJECT
+public:
+ explicit MdiContainerWidgetTaskMenu(QMdiArea *m, QObject *parent = 0);
+ explicit MdiContainerWidgetTaskMenu(QWorkspace *m, QObject *parent = 0);
+
+ virtual QList<QAction*> taskActions() const;
+private:
+ void initializeActions();
+
+ QAction *m_nextAction;
+ QAction *m_previousAction;
+ QAction *m_tileAction;
+ QAction *m_cascadeAction;
+};
+
+class ContainerWidgetTaskMenuFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit ContainerWidgetTaskMenuFactory(QDesignerFormEditorInterface *core, QExtensionManager *extensionManager = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // CONTAINERWIDGER_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/groupbox_taskmenu.cpp b/src/designer/src/components/taskmenu/groupbox_taskmenu.cpp
new file mode 100644
index 000000000..1fae0f8ba
--- /dev/null
+++ b/src/designer/src/components/taskmenu/groupbox_taskmenu.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "groupbox_taskmenu.h"
+#include "inplace_editor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// -------- GroupBoxTaskMenuInlineEditor
+class GroupBoxTaskMenuInlineEditor : public TaskMenuInlineEditor
+{
+public:
+ GroupBoxTaskMenuInlineEditor(QGroupBox *button, QObject *parent);
+
+protected:
+ virtual QRect editRectangle() const;
+};
+
+GroupBoxTaskMenuInlineEditor::GroupBoxTaskMenuInlineEditor(QGroupBox *w, QObject *parent) :
+ TaskMenuInlineEditor(w, ValidationSingleLine, QLatin1String("title"), parent)
+{
+}
+
+QRect GroupBoxTaskMenuInlineEditor::editRectangle() const
+{
+ QWidget *w = widget();
+ QStyleOption opt; // ## QStyleOptionGroupBox
+ opt.init(w);
+ return QRect(QPoint(), QSize(w->width(),20));
+}
+
+// --------------- GroupBoxTaskMenu
+
+GroupBoxTaskMenu::GroupBoxTaskMenu(QGroupBox *groupbox, QObject *parent)
+ : QDesignerTaskMenu(groupbox, parent),
+ m_editTitleAction(new QAction(tr("Change title..."), this))
+
+{
+ TaskMenuInlineEditor *editor = new GroupBoxTaskMenuInlineEditor(groupbox, this);
+ connect(m_editTitleAction, SIGNAL(triggered()), editor, SLOT(editText()));
+ m_taskActions.append(m_editTitleAction);
+
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ m_taskActions.append(sep);
+}
+
+QList<QAction*> GroupBoxTaskMenu::taskActions() const
+{
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+QAction *GroupBoxTaskMenu::preferredEditAction() const
+{
+ return m_editTitleAction;
+}
+
+}
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/groupbox_taskmenu.h b/src/designer/src/components/taskmenu/groupbox_taskmenu.h
new file mode 100644
index 000000000..d30d8b1b6
--- /dev/null
+++ b/src/designer/src/components/taskmenu/groupbox_taskmenu.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GROUPBOX_TASKMENU_H
+#define GROUPBOX_TASKMENU_H
+
+#include <QtGui/QGroupBox>
+#include <QtCore/QPointer>
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+class InPlaceEditor;
+
+class GroupBoxTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit GroupBoxTaskMenu(QGroupBox *groupbox, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private:
+ QAction *m_editTitleAction;
+ QList<QAction*> m_taskActions;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QGroupBox, GroupBoxTaskMenu> GroupBoxTaskMenuFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // GROUPBOX_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/inplace_editor.cpp b/src/designer/src/components/taskmenu/inplace_editor.cpp
new file mode 100644
index 000000000..fd74b25f4
--- /dev/null
+++ b/src/designer/src/components/taskmenu/inplace_editor.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractformwindow.h"
+#include "inplace_editor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ----------------- InPlaceEditor
+
+InPlaceEditor::InPlaceEditor(QWidget *widget,
+ TextPropertyValidationMode validationMode,
+ QDesignerFormWindowInterface *fw,
+ const QString& text,
+ const QRect& r) :
+ TextPropertyEditor(widget, EmbeddingInPlace, validationMode),
+ m_InPlaceWidgetHelper(this, widget, fw)
+{
+ setAlignment(m_InPlaceWidgetHelper.alignment());
+ setObjectName(QLatin1String("__qt__passive_m_editor"));
+
+ setText(text);
+ selectAll();
+
+ setGeometry(QRect(widget->mapTo(widget->window(), r.topLeft()), r.size()));
+ setFocus();
+ show();
+
+ connect(this, SIGNAL(editingFinished()),this, SLOT(close()));
+}
+
+
+// -------------- TaskMenuInlineEditor
+
+TaskMenuInlineEditor::TaskMenuInlineEditor(QWidget *w, TextPropertyValidationMode vm,
+ const QString &property, QObject *parent) :
+ QObject(parent),
+ m_vm(vm),
+ m_property(property),
+ m_widget(w),
+ m_managed(true)
+{
+}
+
+void TaskMenuInlineEditor::editText()
+{
+ m_formWindow = QDesignerFormWindowInterface::findFormWindow(m_widget);
+ if (m_formWindow.isNull())
+ return;
+ m_managed = m_formWindow->isManaged(m_widget);
+ // Close as soon as a different widget is selected
+ connect(m_formWindow, SIGNAL(selectionChanged()), this, SLOT(updateSelection()));
+
+ // get old value
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), m_widget);
+ const int index = sheet->indexOf(m_property);
+ if (index == -1)
+ return;
+ m_value = qvariant_cast<PropertySheetStringValue>(sheet->property(index));
+ const QString oldValue = m_value.value();
+
+ m_editor = new InPlaceEditor(m_widget, m_vm, m_formWindow, oldValue, editRectangle());
+ connect(m_editor, SIGNAL(textChanged(QString)), this, SLOT(updateText(QString)));
+}
+
+void TaskMenuInlineEditor::updateText(const QString &text)
+{
+ // In the [rare] event we are invoked on an unmanaged widget,
+ // do not use the cursor selection
+ m_value.setValue(text);
+ if (m_managed) {
+ m_formWindow->cursor()->setProperty(m_property, QVariant::fromValue(m_value));
+ } else {
+ m_formWindow->cursor()->setWidgetProperty(m_widget, m_property, QVariant::fromValue(m_value));
+ }
+}
+
+void TaskMenuInlineEditor::updateSelection()
+{
+ if (m_editor)
+ m_editor->deleteLater();
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/inplace_editor.h b/src/designer/src/components/taskmenu/inplace_editor.h
new file mode 100644
index 000000000..573185cb8
--- /dev/null
+++ b/src/designer/src/components/taskmenu/inplace_editor.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INPLACE_EDITOR_H
+#define INPLACE_EDITOR_H
+
+#include <textpropertyeditor_p.h>
+#include <shared_enums_p.h>
+
+#include "inplace_widget_helper.h"
+#include <qdesigner_utils_p.h>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class InPlaceEditor: public TextPropertyEditor
+{
+ Q_OBJECT
+public:
+ InPlaceEditor(QWidget *widget,
+ TextPropertyValidationMode validationMode,
+ QDesignerFormWindowInterface *fw,
+ const QString& text,
+ const QRect& r);
+private:
+ InPlaceWidgetHelper m_InPlaceWidgetHelper;
+};
+
+// Base class for inline editor helpers to be embedded into a task menu.
+// Inline-edits a property on a multi-selection.
+// To use it for a particular widget/property, overwrite the method
+// returning the edit area.
+
+class TaskMenuInlineEditor : public QObject {
+ TaskMenuInlineEditor(const TaskMenuInlineEditor&);
+ TaskMenuInlineEditor &operator=(const TaskMenuInlineEditor&);
+ Q_OBJECT
+
+public slots:
+ void editText();
+
+private slots:
+ void updateText(const QString &text);
+ void updateSelection();
+
+protected:
+ TaskMenuInlineEditor(QWidget *w, TextPropertyValidationMode vm, const QString &property, QObject *parent);
+ // Overwrite to return the area for the inline editor.
+ virtual QRect editRectangle() const = 0;
+ QWidget *widget() const { return m_widget; }
+
+private:
+ const TextPropertyValidationMode m_vm;
+ const QString m_property;
+ QWidget *m_widget;
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+ QPointer<InPlaceEditor> m_editor;
+ bool m_managed;
+ qdesigner_internal::PropertySheetStringValue m_value;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // INPLACE_EDITOR_H
diff --git a/src/designer/src/components/taskmenu/inplace_widget_helper.cpp b/src/designer/src/components/taskmenu/inplace_widget_helper.cpp
new file mode 100644
index 000000000..47554b3a8
--- /dev/null
+++ b/src/designer/src/components/taskmenu/inplace_widget_helper.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractformwindow.h"
+#include "inplace_widget_helper.h"
+
+#include <QtGui/QResizeEvent>
+#include <QtGui/QPushButton>
+#include <QtGui/QToolButton>
+#include <QtGui/QShortcut>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ InPlaceWidgetHelper::InPlaceWidgetHelper(QWidget *editorWidget, QWidget *parentWidget, QDesignerFormWindowInterface *fw)
+ : QObject(0),
+ m_editorWidget(editorWidget),
+ m_parentWidget(parentWidget),
+ m_noChildEvent(m_parentWidget->testAttribute(Qt::WA_NoChildEventsForParent))
+ {
+ m_editorWidget->setAttribute(Qt::WA_DeleteOnClose);
+ m_editorWidget->setParent(m_parentWidget->window());
+ m_parentWidget->installEventFilter(this);
+ m_editorWidget->installEventFilter(this);
+ connect(m_editorWidget, SIGNAL(destroyed()), fw->mainContainer(), SLOT(setFocus()));
+ }
+
+ InPlaceWidgetHelper::~InPlaceWidgetHelper()
+ {
+ m_parentWidget->setAttribute(Qt::WA_NoChildEventsForParent, m_noChildEvent);
+ }
+
+ Qt::Alignment InPlaceWidgetHelper::alignment() const {
+ if (m_parentWidget->metaObject()->indexOfProperty("alignment") != -1)
+ return Qt::Alignment(m_parentWidget->property("alignment").toInt());
+
+ if (qobject_cast<const QPushButton *>(m_parentWidget)
+ || qobject_cast<const QToolButton *>(m_parentWidget) /* tool needs to be more complex */)
+ return Qt::AlignHCenter;
+
+ return Qt::AlignJustify;
+ }
+
+
+ bool InPlaceWidgetHelper::eventFilter(QObject *object, QEvent *e)
+ {
+ if (object == m_parentWidget) {
+ if (e->type() == QEvent::Resize) {
+ const QResizeEvent *event = static_cast<const QResizeEvent*>(e);
+ const QPoint localPos = m_parentWidget->geometry().topLeft();
+ const QPoint globalPos = m_parentWidget->parentWidget() ? m_parentWidget->parentWidget()->mapToGlobal(localPos) : localPos;
+ const QPoint newPos = (m_editorWidget->parentWidget() ? m_editorWidget->parentWidget()->mapFromGlobal(globalPos) : globalPos)
+ + m_posOffset;
+ const QSize newSize = event->size() + m_sizeOffset;
+ m_editorWidget->setGeometry(QRect(newPos, newSize));
+ }
+ } else if (object == m_editorWidget) {
+ if (e->type() == QEvent::ShortcutOverride) {
+ if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
+ e->accept();
+ return false;
+ }
+ } else if (e->type() == QEvent::KeyPress) {
+ if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
+ e->accept();
+ m_editorWidget->close();
+ return true;
+ }
+ } else if (e->type() == QEvent::Show) {
+ const QPoint localPos = m_parentWidget->geometry().topLeft();
+ const QPoint globalPos = m_parentWidget->parentWidget() ? m_parentWidget->parentWidget()->mapToGlobal(localPos) : localPos;
+ const QPoint newPos = m_editorWidget->parentWidget() ? m_editorWidget->parentWidget()->mapFromGlobal(globalPos) : globalPos;
+ m_posOffset = m_editorWidget->geometry().topLeft() - newPos;
+ m_sizeOffset = m_editorWidget->size() - m_parentWidget->size();
+ }
+ }
+
+ return QObject::eventFilter(object, e);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/inplace_widget_helper.h b/src/designer/src/components/taskmenu/inplace_widget_helper.h
new file mode 100644
index 000000000..663516004
--- /dev/null
+++ b/src/designer/src/components/taskmenu/inplace_widget_helper.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INPLACE_WIDGETHELPER_H
+#define INPLACE_WIDGETHELPER_H
+
+
+#include <QtCore/QObject>
+#include <QtCore/QPoint>
+#include <QtCore/QSize>
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+ // A helper class to make an editor widget suitable for form inline
+ // editing. Derive from the editor widget class and make InPlaceWidgetHelper a member.
+ //
+ // Sets "destructive close" on the editor widget and
+ // wires "ESC" to it.
+ // Installs an event filter on the parent to listen for
+ // resize events and passes them on to the child.
+ // You might want to connect editingFinished() to close() of the editor widget.
+ class InPlaceWidgetHelper: public QObject
+ {
+ Q_OBJECT
+ public:
+ InPlaceWidgetHelper(QWidget *editorWidget, QWidget *parentWidget, QDesignerFormWindowInterface *fw);
+ virtual ~InPlaceWidgetHelper();
+
+ virtual bool eventFilter(QObject *object, QEvent *event);
+
+ // returns a recommended alignment for the editor widget determined from the parent.
+ Qt::Alignment alignment() const;
+ private:
+ QWidget *m_editorWidget;
+ QWidget *m_parentWidget;
+ const bool m_noChildEvent;
+ QPoint m_posOffset;
+ QSize m_sizeOffset;
+ };
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // INPLACE_WIDGETHELPER_H
diff --git a/src/designer/src/components/taskmenu/itemlisteditor.cpp b/src/designer/src/components/taskmenu/itemlisteditor.cpp
new file mode 100644
index 000000000..a04246de5
--- /dev/null
+++ b/src/designer/src/components/taskmenu/itemlisteditor.cpp
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "itemlisteditor.h"
+#include <abstractformbuilder.h>
+#include <iconloader_p.h>
+#include <formwindowbase_p.h>
+#include <designerpropertymanager.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <qttreepropertybrowser.h>
+
+#include <QtGui/QSplitter>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class ItemPropertyBrowser : public QtTreePropertyBrowser
+{
+public:
+ ItemPropertyBrowser()
+ {
+ setResizeMode(Interactive);
+ //: Sample string to determinate the width for the first column of the list item property browser
+ const QString widthSampleString = QCoreApplication::translate("ItemPropertyBrowser", "XX Icon Selected off");
+ m_width = fontMetrics().width(widthSampleString);
+ setSplitterPosition(m_width);
+ m_width += fontMetrics().width(QLatin1String("/this/is/some/random/path"));
+ }
+
+ virtual QSize sizeHint() const
+ {
+ return QSize(m_width, 1);
+ }
+
+private:
+ int m_width;
+};
+
+////////////////// Item editor ///////////////
+AbstractItemEditor::AbstractItemEditor(QDesignerFormWindowInterface *form, QWidget *parent)
+ : QWidget(parent),
+ m_iconCache(qobject_cast<FormWindowBase *>(form)->iconCache()),
+ m_updatingBrowser(false)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ m_propertyManager = new DesignerPropertyManager(form->core(), this);
+ m_editorFactory = new DesignerEditorFactory(form->core(), this);
+ m_editorFactory->setSpacing(0);
+ m_propertyBrowser = new ItemPropertyBrowser;
+ m_propertyBrowser->setFactoryForManager((QtVariantPropertyManager *)m_propertyManager,
+ m_editorFactory);
+
+ connect(m_editorFactory, SIGNAL(resetProperty(QtProperty*)),
+ SLOT(resetProperty(QtProperty*)));
+ connect(m_propertyManager, SIGNAL(valueChanged(QtProperty*,QVariant,bool)),
+ SLOT(propertyChanged(QtProperty*)));
+ connect(iconCache(), SIGNAL(reloaded()), this, SLOT(cacheReloaded()));
+}
+
+AbstractItemEditor::~AbstractItemEditor()
+{
+ m_propertyBrowser->unsetFactoryForManager(m_propertyManager);
+}
+
+static const char * const itemFlagNames[] = {
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Selectable"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Editable"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "DragEnabled"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "DropEnabled"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "UserCheckable"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Enabled"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Tristate"),
+ 0
+};
+
+static const char * const checkStateNames[] = {
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Unchecked"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "PartiallyChecked"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Checked"),
+ 0
+};
+
+static QStringList c2qStringList(const char * const in[])
+{
+ QStringList out;
+ for (int i = 0; in[i]; i++)
+ out << AbstractItemEditor::tr(in[i]);
+ return out;
+}
+
+void AbstractItemEditor::setupProperties(PropertyDefinition *propList)
+{
+ for (int i = 0; propList[i].name; i++) {
+ int type = propList[i].typeFunc ? propList[i].typeFunc() : propList[i].type;
+ int role = propList[i].role;
+ QtVariantProperty *prop = m_propertyManager->addProperty(type, QLatin1String(propList[i].name));
+ Q_ASSERT(prop);
+ if (role == Qt::ToolTipPropertyRole || role == Qt::WhatsThisPropertyRole)
+ prop->setAttribute(QLatin1String("validationMode"), ValidationRichText);
+ else if (role == Qt::DisplayPropertyRole)
+ prop->setAttribute(QLatin1String("validationMode"), ValidationMultiLine);
+ else if (role == Qt::StatusTipPropertyRole)
+ prop->setAttribute(QLatin1String("validationMode"), ValidationSingleLine);
+ else if (role == ItemFlagsShadowRole)
+ prop->setAttribute(QLatin1String("flagNames"), c2qStringList(itemFlagNames));
+ else if (role == Qt::CheckStateRole)
+ prop->setAttribute(QLatin1String("enumNames"), c2qStringList(checkStateNames));
+ prop->setAttribute(QLatin1String("resettable"), true);
+ m_properties.append(prop);
+ m_rootProperties.append(prop);
+ m_propertyToRole.insert(prop, role);
+ }
+}
+
+void AbstractItemEditor::setupObject(QWidget *object)
+{
+ m_propertyManager->setObject(object);
+ QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(object);
+ FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
+ m_editorFactory->setFormWindowBase(fwb);
+}
+
+void AbstractItemEditor::setupEditor(QWidget *object, PropertyDefinition *propList)
+{
+ setupProperties(propList);
+ setupObject(object);
+}
+
+void AbstractItemEditor::propertyChanged(QtProperty *property)
+{
+ if (m_updatingBrowser)
+ return;
+
+
+ BoolBlocker block(m_updatingBrowser);
+ QtVariantProperty *prop = m_propertyManager->variantProperty(property);
+ int role;
+ if ((role = m_propertyToRole.value(prop, -1)) == -1)
+ // Subproperty
+ return;
+
+ if ((role == ItemFlagsShadowRole && prop->value().toInt() == (int)QListWidgetItem().flags())
+ || (role == Qt::DecorationPropertyRole && !qvariant_cast<PropertySheetIconValue>(prop->value()).mask())
+ || (role == Qt::FontRole && !qvariant_cast<QFont>(prop->value()).resolve())) {
+ prop->setModified(false);
+ setItemData(role, QVariant());
+ } else {
+ prop->setModified(true);
+ setItemData(role, prop->value());
+ }
+
+ switch (role) {
+ case Qt::DecorationPropertyRole:
+ setItemData(Qt::DecorationRole, QVariant::fromValue(iconCache()->icon(qvariant_cast<PropertySheetIconValue>(prop->value()))));
+ break;
+ case Qt::DisplayPropertyRole:
+ setItemData(Qt::EditRole, QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(prop->value()).value()));
+ break;
+ case Qt::ToolTipPropertyRole:
+ setItemData(Qt::ToolTipRole, QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(prop->value()).value()));
+ break;
+ case Qt::StatusTipPropertyRole:
+ setItemData(Qt::StatusTipRole, QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(prop->value()).value()));
+ break;
+ case Qt::WhatsThisPropertyRole:
+ setItemData(Qt::WhatsThisRole, QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(prop->value()).value()));
+ break;
+ default:
+ break;
+ }
+
+ prop->setValue(getItemData(role));
+}
+
+void AbstractItemEditor::resetProperty(QtProperty *property)
+{
+ if (m_propertyManager->resetFontSubProperty(property))
+ return;
+
+ if (m_propertyManager->resetIconSubProperty(property))
+ return;
+
+ BoolBlocker block(m_updatingBrowser);
+
+ QtVariantProperty *prop = m_propertyManager->variantProperty(property);
+ int role = m_propertyToRole.value(prop);
+ if (role == ItemFlagsShadowRole)
+ prop->setValue(QVariant::fromValue((int)QListWidgetItem().flags()));
+ else
+ prop->setValue(QVariant(prop->valueType(), (void *)0));
+ prop->setModified(false);
+
+ setItemData(role, QVariant());
+ if (role == Qt::DecorationPropertyRole)
+ setItemData(Qt::DecorationRole, QVariant::fromValue(QIcon()));
+ if (role == Qt::DisplayPropertyRole)
+ setItemData(Qt::EditRole, QVariant::fromValue(QString()));
+ if (role == Qt::ToolTipPropertyRole)
+ setItemData(Qt::ToolTipRole, QVariant::fromValue(QString()));
+ if (role == Qt::StatusTipPropertyRole)
+ setItemData(Qt::StatusTipRole, QVariant::fromValue(QString()));
+ if (role == Qt::WhatsThisPropertyRole)
+ setItemData(Qt::WhatsThisRole, QVariant::fromValue(QString()));
+}
+
+void AbstractItemEditor::cacheReloaded()
+{
+ BoolBlocker block(m_updatingBrowser);
+ m_propertyManager->reloadResourceProperties();
+}
+
+void AbstractItemEditor::updateBrowser()
+{
+ BoolBlocker block(m_updatingBrowser);
+ foreach (QtVariantProperty *prop, m_properties) {
+ int role = m_propertyToRole.value(prop);
+ QVariant val = getItemData(role);
+ if (!val.isValid()) {
+ if (role == ItemFlagsShadowRole)
+ val = QVariant::fromValue((int)QListWidgetItem().flags());
+ else
+ val = QVariant((int)prop->value().userType(), (void *)0);
+ prop->setModified(false);
+ } else {
+ prop->setModified(true);
+ }
+ prop->setValue(val);
+ }
+
+ if (m_propertyBrowser->topLevelItems().isEmpty())
+ foreach (QtVariantProperty *prop, m_rootProperties)
+ m_propertyBrowser->addProperty(prop);
+}
+
+void AbstractItemEditor::injectPropertyBrowser(QWidget *parent, QWidget *widget)
+{
+ // It is impossible to design a splitter with just one widget, so we do it by hand.
+ m_propertySplitter = new QSplitter;
+ m_propertySplitter->addWidget(widget);
+ m_propertySplitter->addWidget(m_propertyBrowser);
+ m_propertySplitter->setStretchFactor(0, 1);
+ m_propertySplitter->setStretchFactor(1, 0);
+ parent->layout()->addWidget(m_propertySplitter);
+}
+
+////////////////// List editor ///////////////
+ItemListEditor::ItemListEditor(QDesignerFormWindowInterface *form, QWidget *parent)
+ : AbstractItemEditor(form, parent),
+ m_updating(false)
+{
+ ui.setupUi(this);
+
+ injectPropertyBrowser(this, ui.widget);
+ connect(ui.showPropertiesButton, SIGNAL(clicked()),
+ this, SLOT(togglePropertyBrowser()));
+ setPropertyBrowserVisible(false);
+
+ QIcon upIcon = createIconSet(QString::fromUtf8("up.png"));
+ QIcon downIcon = createIconSet(QString::fromUtf8("down.png"));
+ QIcon minusIcon = createIconSet(QString::fromUtf8("minus.png"));
+ QIcon plusIcon = createIconSet(QString::fromUtf8("plus.png"));
+ ui.moveListItemUpButton->setIcon(upIcon);
+ ui.moveListItemDownButton->setIcon(downIcon);
+ ui.newListItemButton->setIcon(plusIcon);
+ ui.deleteListItemButton->setIcon(minusIcon);
+
+ connect(iconCache(), SIGNAL(reloaded()), this, SLOT(cacheReloaded()));
+}
+
+void ItemListEditor::setupEditor(QWidget *object, PropertyDefinition *propList)
+{
+ AbstractItemEditor::setupEditor(object, propList);
+
+ if (ui.listWidget->count() > 0)
+ ui.listWidget->setCurrentRow(0);
+ else
+ updateEditor();
+}
+
+void ItemListEditor::setCurrentIndex(int idx)
+{
+ m_updating = true;
+ ui.listWidget->setCurrentRow(idx);
+ m_updating = false;
+}
+
+void ItemListEditor::on_newListItemButton_clicked()
+{
+ int row = ui.listWidget->currentRow() + 1;
+
+ QListWidgetItem *item = new QListWidgetItem(m_newItemText);
+ item->setData(Qt::DisplayPropertyRole, QVariant::fromValue(PropertySheetStringValue(m_newItemText)));
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ if (row < ui.listWidget->count())
+ ui.listWidget->insertItem(row, item);
+ else
+ ui.listWidget->addItem(item);
+ emit itemInserted(row);
+
+ ui.listWidget->setCurrentItem(item);
+ ui.listWidget->editItem(item);
+}
+
+void ItemListEditor::on_deleteListItemButton_clicked()
+{
+ int row = ui.listWidget->currentRow();
+
+ if (row != -1) {
+ delete ui.listWidget->takeItem(row);
+ emit itemDeleted(row);
+ }
+
+ if (row == ui.listWidget->count())
+ row--;
+ if (row < 0)
+ updateEditor();
+ else
+ ui.listWidget->setCurrentRow(row);
+}
+
+void ItemListEditor::on_moveListItemUpButton_clicked()
+{
+ int row = ui.listWidget->currentRow();
+ if (row <= 0)
+ return; // nothing to do
+
+ ui.listWidget->insertItem(row - 1, ui.listWidget->takeItem(row));
+ ui.listWidget->setCurrentRow(row - 1);
+ emit itemMovedUp(row);
+}
+
+void ItemListEditor::on_moveListItemDownButton_clicked()
+{
+ int row = ui.listWidget->currentRow();
+ if (row == -1 || row == ui.listWidget->count() - 1)
+ return; // nothing to do
+
+ ui.listWidget->insertItem(row + 1, ui.listWidget->takeItem(row));
+ ui.listWidget->setCurrentRow(row + 1);
+ emit itemMovedDown(row);
+}
+
+void ItemListEditor::on_listWidget_currentRowChanged()
+{
+ updateEditor();
+ if (!m_updating)
+ emit indexChanged(ui.listWidget->currentRow());
+}
+
+void ItemListEditor::on_listWidget_itemChanged(QListWidgetItem *item)
+{
+ if (m_updatingBrowser)
+ return;
+
+ PropertySheetStringValue val = qvariant_cast<PropertySheetStringValue>(item->data(Qt::DisplayPropertyRole));
+ val.setValue(item->text());
+ BoolBlocker block(m_updatingBrowser);
+ item->setData(Qt::DisplayPropertyRole, QVariant::fromValue(val));
+
+ // The checkState could change, too, but if this signal is connected,
+ // checkState is not in the list anyway, as we are editing a header item.
+ emit itemChanged(ui.listWidget->currentRow(), Qt::DisplayPropertyRole,
+ QVariant::fromValue(val));
+ updateBrowser();
+}
+
+void ItemListEditor::togglePropertyBrowser()
+{
+ setPropertyBrowserVisible(!m_propertyBrowser->isVisible());
+}
+
+void ItemListEditor::setPropertyBrowserVisible(bool v)
+{
+ ui.showPropertiesButton->setText(v ? tr("Properties &>>") : tr("Properties &<<"));
+ m_propertyBrowser->setVisible(v);
+}
+
+void ItemListEditor::setItemData(int role, const QVariant &v)
+{
+ QListWidgetItem *item = ui.listWidget->currentItem();
+ bool reLayout = false;
+ if ((role == Qt::EditRole && (v.toString().count(QLatin1Char('\n')) != item->data(role).toString().count(QLatin1Char('\n'))))
+ || role == Qt::FontRole)
+ reLayout = true;
+ QVariant newValue = v;
+ if (role == Qt::FontRole && newValue.type() == QVariant::Font) {
+ QFont oldFont = ui.listWidget->font();
+ QFont newFont = qvariant_cast<QFont>(newValue).resolve(oldFont);
+ newValue = QVariant::fromValue(newFont);
+ item->setData(role, QVariant()); // force the right font with the current resolve mask is set (item view bug)
+ }
+ item->setData(role, newValue);
+ if (reLayout)
+ ui.listWidget->doItemsLayout();
+ emit itemChanged(ui.listWidget->currentRow(), role, newValue);
+}
+
+QVariant ItemListEditor::getItemData(int role) const
+{
+ return ui.listWidget->currentItem()->data(role);
+}
+
+void ItemListEditor::cacheReloaded()
+{
+ reloadIconResources(iconCache(), ui.listWidget);
+}
+
+void ItemListEditor::updateEditor()
+{
+ bool currentItemEnabled = false;
+
+ bool moveRowUpEnabled = false;
+ bool moveRowDownEnabled = false;
+
+ QListWidgetItem *item = ui.listWidget->currentItem();
+ if (item) {
+ currentItemEnabled = true;
+ int currentRow = ui.listWidget->currentRow();
+ if (currentRow > 0)
+ moveRowUpEnabled = true;
+ if (currentRow < ui.listWidget->count() - 1)
+ moveRowDownEnabled = true;
+ }
+
+ ui.moveListItemUpButton->setEnabled(moveRowUpEnabled);
+ ui.moveListItemDownButton->setEnabled(moveRowDownEnabled);
+ ui.deleteListItemButton->setEnabled(currentItemEnabled);
+
+ if (item)
+ updateBrowser();
+ else
+ m_propertyBrowser->clear();
+}
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/itemlisteditor.h b/src/designer/src/components/taskmenu/itemlisteditor.h
new file mode 100644
index 000000000..ffacad293
--- /dev/null
+++ b/src/designer/src/components/taskmenu/itemlisteditor.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ITEMLISTEDITOR_H
+#define ITEMLISTEDITOR_H
+
+#include "ui_itemlisteditor.h"
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QtProperty;
+class QtVariantProperty;
+class QtTreePropertyBrowser;
+class QSplitter;
+class QVBoxLayout;
+
+namespace qdesigner_internal {
+
+class DesignerIconCache;
+class DesignerPropertyManager;
+class DesignerEditorFactory;
+
+// Utility class that ensures a bool is true while in scope.
+// Courtesy of QBoolBlocker in qobject_p.h
+class BoolBlocker
+{
+public:
+ inline BoolBlocker(bool &b):block(b), reset(b){block = true;}
+ inline ~BoolBlocker(){block = reset; }
+private:
+ bool &block;
+ bool reset;
+};
+
+class AbstractItemEditor: public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit AbstractItemEditor(QDesignerFormWindowInterface *form, QWidget *parent);
+ ~AbstractItemEditor();
+
+ DesignerIconCache *iconCache() const { return m_iconCache; }
+
+ struct PropertyDefinition {
+ int role;
+ int type;
+ int (*typeFunc)();
+ const char *name;
+ };
+
+private slots:
+ void propertyChanged(QtProperty *property);
+ void resetProperty(QtProperty *property);
+ void cacheReloaded();
+
+protected:
+ void setupProperties(PropertyDefinition *propDefs);
+ void setupObject(QWidget *object);
+ void setupEditor(QWidget *object, PropertyDefinition *propDefs);
+ void injectPropertyBrowser(QWidget *parent, QWidget *widget);
+ void updateBrowser();
+ virtual void setItemData(int role, const QVariant &v) = 0;
+ virtual QVariant getItemData(int role) const = 0;
+
+ DesignerIconCache *m_iconCache;
+ DesignerPropertyManager *m_propertyManager;
+ DesignerEditorFactory *m_editorFactory;
+ QSplitter *m_propertySplitter;
+ QtTreePropertyBrowser *m_propertyBrowser;
+ QList<QtVariantProperty*> m_properties;
+ QList<QtVariantProperty*> m_rootProperties;
+ QHash<QtVariantProperty*, int> m_propertyToRole;
+ bool m_updatingBrowser;
+};
+
+class ItemListEditor: public AbstractItemEditor
+{
+ Q_OBJECT
+
+public:
+ explicit ItemListEditor(QDesignerFormWindowInterface *form, QWidget *parent);
+
+ void setupEditor(QWidget *object, PropertyDefinition *propDefs);
+ QListWidget *listWidget() const { return ui.listWidget; }
+ void setNewItemText(const QString &tpl) { m_newItemText = tpl; }
+ QString newItemText() const { return m_newItemText; }
+ void setCurrentIndex(int idx);
+
+signals:
+ void indexChanged(int idx);
+ void itemChanged(int idx, int role, const QVariant &v);
+ void itemInserted(int idx);
+ void itemDeleted(int idx);
+ void itemMovedUp(int idx);
+ void itemMovedDown(int idx);
+
+private slots:
+ void on_newListItemButton_clicked();
+ void on_deleteListItemButton_clicked();
+ void on_moveListItemUpButton_clicked();
+ void on_moveListItemDownButton_clicked();
+ void on_listWidget_currentRowChanged();
+ void on_listWidget_itemChanged(QListWidgetItem * item);
+ void togglePropertyBrowser();
+ void cacheReloaded();
+
+protected:
+ virtual void setItemData(int role, const QVariant &v);
+ virtual QVariant getItemData(int role) const;
+
+private:
+ void setPropertyBrowserVisible(bool v);
+ void updateEditor();
+ Ui::ItemListEditor ui;
+ bool m_updating;
+ QString m_newItemText;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ITEMLISTEDITOR_H
diff --git a/src/designer/src/components/taskmenu/itemlisteditor.ui b/src/designer/src/components/taskmenu/itemlisteditor.ui
new file mode 100644
index 000000000..a13703f90
--- /dev/null
+++ b/src/designer/src/components/taskmenu/itemlisteditor.ui
@@ -0,0 +1,156 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::ItemListEditor</class>
+ <widget class="QWidget" name="qdesigner_internal::ItemListEditor" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>550</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string/>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <widget class="QWidget" native="1" name="widget" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="listWidget" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" >
+ <string>Items List</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="buttonsLayout" >
+ <item>
+ <widget class="QToolButton" name="newListItemButton" >
+ <property name="toolTip" >
+ <string>New Item</string>
+ </property>
+ <property name="text" >
+ <string>&amp;New</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteListItemButton" >
+ <property name="toolTip" >
+ <string>Delete Item</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>16</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="moveListItemUpButton" >
+ <property name="toolTip" >
+ <string>Move Item Up</string>
+ </property>
+ <property name="text" >
+ <string>U</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="moveListItemDownButton" >
+ <property name="toolTip" >
+ <string>Move Item Down</string>
+ </property>
+ <property name="text" >
+ <string>D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="showPropertiesButton" >
+ <property name="text" >
+ <string>Properties &amp;>></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/components/taskmenu/label_taskmenu.cpp b/src/designer/src/components/taskmenu/label_taskmenu.cpp
new file mode 100644
index 000000000..5f0acb209
--- /dev/null
+++ b/src/designer/src/components/taskmenu/label_taskmenu.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "label_taskmenu.h"
+#include "inplace_editor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+#include <QtGui/QTextDocument>
+
+static const char *textPropertyC = "text";
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// -------- LabelTaskMenuInlineEditor
+class LabelTaskMenuInlineEditor : public TaskMenuInlineEditor
+{
+public:
+ LabelTaskMenuInlineEditor(QLabel *button, QObject *parent);
+
+protected:
+ virtual QRect editRectangle() const;
+};
+
+LabelTaskMenuInlineEditor::LabelTaskMenuInlineEditor(QLabel *w, QObject *parent) :
+ TaskMenuInlineEditor(w, ValidationRichText, QLatin1String(textPropertyC), parent)
+{
+}
+
+QRect LabelTaskMenuInlineEditor::editRectangle() const
+{
+ QStyleOptionButton opt;
+ opt.init(widget());
+ return opt.rect;
+}
+
+// --------------- LabelTaskMenu
+
+LabelTaskMenu::LabelTaskMenu(QLabel *label, QObject *parent)
+ : QDesignerTaskMenu(label, parent),
+ m_label(label),
+ m_editRichTextAction(new QAction(tr("Change rich text..."), this)),
+ m_editPlainTextAction(new QAction(tr("Change plain text..."), this))
+{
+ LabelTaskMenuInlineEditor *editor = new LabelTaskMenuInlineEditor(label, this);
+ connect(m_editPlainTextAction, SIGNAL(triggered()), editor, SLOT(editText()));
+ m_taskActions.append(m_editPlainTextAction);
+
+ connect(m_editRichTextAction, SIGNAL(triggered()), this, SLOT(editRichText()));
+ m_taskActions.append(m_editRichTextAction);
+
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ m_taskActions.append(sep);
+}
+
+QAction *LabelTaskMenu::preferredEditAction() const
+{
+ if (m_label->textFormat () == Qt::PlainText) return m_editPlainTextAction;
+ return Qt::mightBeRichText(m_label->text()) ? m_editRichTextAction : m_editPlainTextAction;
+}
+
+QList<QAction*> LabelTaskMenu::taskActions() const
+{
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+void LabelTaskMenu::editRichText()
+{
+ changeTextProperty(QLatin1String(textPropertyC), QString(), MultiSelectionMode, m_label->textFormat());
+}
+
+}
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/label_taskmenu.h b/src/designer/src/components/taskmenu/label_taskmenu.h
new file mode 100644
index 000000000..7f3549128
--- /dev/null
+++ b/src/designer/src/components/taskmenu/label_taskmenu.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LABEL_TASKMENU_H
+#define LABEL_TASKMENU_H
+
+#include <QtGui/QLabel>
+#include <QtCore/QPointer>
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class LabelTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit LabelTaskMenu(QLabel *button, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void editRichText();
+
+private:
+ QLabel *m_label;
+ QList<QAction*> m_taskActions;
+ QAction *m_editRichTextAction;
+ QAction *m_editPlainTextAction;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QLabel, LabelTaskMenu> LabelTaskMenuFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LABEL_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/layouttaskmenu.cpp b/src/designer/src/components/taskmenu/layouttaskmenu.cpp
new file mode 100644
index 000000000..10d5d7c54
--- /dev/null
+++ b/src/designer/src/components/taskmenu/layouttaskmenu.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "layouttaskmenu.h"
+#include <formlayoutmenu_p.h>
+#include <morphmenu_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+// ------------ LayoutWidgetTaskMenu
+LayoutWidgetTaskMenu::LayoutWidgetTaskMenu(QLayoutWidget *lw, QObject *parent) :
+ QObject(parent),
+ m_widget(lw),
+ m_morphMenu(new qdesigner_internal::MorphMenu(this)),
+ m_formLayoutMenu(new qdesigner_internal::FormLayoutMenu(this))
+{
+}
+
+QAction *LayoutWidgetTaskMenu::preferredEditAction() const
+{
+ return m_formLayoutMenu->preferredEditAction(m_widget, m_widget->formWindow());
+}
+
+QList<QAction*> LayoutWidgetTaskMenu::taskActions() const
+{
+ QList<QAction*> rc;
+ QDesignerFormWindowInterface *fw = m_widget->formWindow();
+ m_morphMenu->populate(m_widget, fw, rc);
+ m_formLayoutMenu->populate(m_widget, fw, rc);
+ return rc;
+}
+
+// ------------- SpacerTaskMenu
+SpacerTaskMenu::SpacerTaskMenu(Spacer *, QObject *parent) :
+ QObject(parent)
+{
+}
+
+QAction *SpacerTaskMenu::preferredEditAction() const
+{
+ return 0;
+}
+
+QList<QAction*> SpacerTaskMenu::taskActions() const
+{
+ return QList<QAction*>();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/components/taskmenu/layouttaskmenu.h b/src/designer/src/components/taskmenu/layouttaskmenu.h
new file mode 100644
index 000000000..ca52596ee
--- /dev/null
+++ b/src/designer/src/components/taskmenu/layouttaskmenu.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LAYOUTTASKMENU_H
+#define LAYOUTTASKMENU_H
+
+#include <QtDesigner/QDesignerTaskMenuExtension>
+
+#include <qlayout_widget_p.h>
+#include <spacer_widget_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ class FormLayoutMenu;
+ class MorphMenu;
+}
+
+// Morph menu for QLayoutWidget.
+class LayoutWidgetTaskMenu : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit LayoutWidgetTaskMenu(QLayoutWidget *w, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private:
+ QLayoutWidget *m_widget;
+ qdesigner_internal::MorphMenu *m_morphMenu;
+ qdesigner_internal::FormLayoutMenu *m_formLayoutMenu;
+};
+
+// Empty task menu for spacers.
+class SpacerTaskMenu : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit SpacerTaskMenu(Spacer *bar, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+};
+
+typedef qdesigner_internal::ExtensionFactory<QDesignerTaskMenuExtension, QLayoutWidget, LayoutWidgetTaskMenu> LayoutWidgetTaskMenuFactory;
+typedef qdesigner_internal::ExtensionFactory<QDesignerTaskMenuExtension, Spacer, SpacerTaskMenu> SpacerTaskMenuFactory;
+
+QT_END_NAMESPACE
+
+#endif // LAYOUTTASKMENU_H
diff --git a/src/designer/src/components/taskmenu/lineedit_taskmenu.cpp b/src/designer/src/components/taskmenu/lineedit_taskmenu.cpp
new file mode 100644
index 000000000..c00c493b1
--- /dev/null
+++ b/src/designer/src/components/taskmenu/lineedit_taskmenu.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lineedit_taskmenu.h"
+#include "inplace_editor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// -------- LineEditTaskMenuInlineEditor
+class LineEditTaskMenuInlineEditor : public TaskMenuInlineEditor
+{
+public:
+ LineEditTaskMenuInlineEditor(QLineEdit *button, QObject *parent);
+
+protected:
+ virtual QRect editRectangle() const;
+};
+
+LineEditTaskMenuInlineEditor::LineEditTaskMenuInlineEditor(QLineEdit *w, QObject *parent) :
+ TaskMenuInlineEditor(w, ValidationSingleLine, QLatin1String("text"), parent)
+{
+}
+
+QRect LineEditTaskMenuInlineEditor::editRectangle() const
+{
+ QStyleOption opt;
+ opt.init(widget());
+ return opt.rect;
+}
+
+// --------------- LineEditTaskMenu
+LineEditTaskMenu::LineEditTaskMenu(QLineEdit *lineEdit, QObject *parent) :
+ QDesignerTaskMenu(lineEdit, parent),
+ m_editTextAction(new QAction(tr("Change text..."), this))
+{
+ TaskMenuInlineEditor *editor = new LineEditTaskMenuInlineEditor(lineEdit, this);
+ connect(m_editTextAction, SIGNAL(triggered()), editor, SLOT(editText()));
+ m_taskActions.append(m_editTextAction);
+
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ m_taskActions.append(sep);
+}
+
+QAction *LineEditTaskMenu::preferredEditAction() const
+{
+ return m_editTextAction;
+}
+
+QList<QAction*> LineEditTaskMenu::taskActions() const
+{
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/lineedit_taskmenu.h b/src/designer/src/components/taskmenu/lineedit_taskmenu.h
new file mode 100644
index 000000000..239590bb8
--- /dev/null
+++ b/src/designer/src/components/taskmenu/lineedit_taskmenu.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LINEEDIT_TASKMENU_H
+#define LINEEDIT_TASKMENU_H
+
+#include <QtGui/QLineEdit>
+#include <QtCore/QPointer>
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class LineEditTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit LineEditTaskMenu(QLineEdit *button, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private:
+ QList<QAction*> m_taskActions;
+ QAction *m_editTextAction;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QLineEdit, LineEditTaskMenu> LineEditTaskMenuFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LINEEDIT_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/listwidget_taskmenu.cpp b/src/designer/src/components/taskmenu/listwidget_taskmenu.cpp
new file mode 100644
index 000000000..bd8f6b9f8
--- /dev/null
+++ b/src/designer/src/components/taskmenu/listwidget_taskmenu.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "listwidget_taskmenu.h"
+#include "listwidgeteditor.h"
+#include "qdesigner_utils_p.h"
+#include <qdesigner_command_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QStyle>
+#include <QtGui/QLineEdit>
+#include <QtGui/QStyleOption>
+
+#include <QtCore/QEvent>
+#include <QtCore/QVariant>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+ListWidgetTaskMenu::ListWidgetTaskMenu(QListWidget *button, QObject *parent)
+ : QDesignerTaskMenu(button, parent),
+ m_listWidget(button)
+{
+ m_editItemsAction = new QAction(this);
+ m_editItemsAction->setText(tr("Edit Items..."));
+ connect(m_editItemsAction, SIGNAL(triggered()), this, SLOT(editItems()));
+ m_taskActions.append(m_editItemsAction);
+
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ m_taskActions.append(sep);
+}
+
+ListWidgetTaskMenu::~ListWidgetTaskMenu()
+{
+}
+
+QAction *ListWidgetTaskMenu::preferredEditAction() const
+{
+ return m_editItemsAction;
+}
+
+QList<QAction*> ListWidgetTaskMenu::taskActions() const
+{
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+void ListWidgetTaskMenu::editItems()
+{
+ m_formWindow = QDesignerFormWindowInterface::findFormWindow(m_listWidget);
+ if (m_formWindow.isNull())
+ return;
+
+ Q_ASSERT(m_listWidget != 0);
+
+ ListWidgetEditor dlg(m_formWindow, m_listWidget->window());
+ ListContents oldItems = dlg.fillContentsFromListWidget(m_listWidget);
+ if (dlg.exec() == QDialog::Accepted) {
+ ListContents items = dlg.contents();
+ if (items != oldItems) {
+ ChangeListContentsCommand *cmd = new ChangeListContentsCommand(m_formWindow);
+ cmd->init(m_listWidget, oldItems, items);
+ cmd->setText(tr("Change List Contents"));
+ m_formWindow->commandHistory()->push(cmd);
+ }
+ }
+}
+
+void ListWidgetTaskMenu::updateSelection()
+{
+ if (m_editor)
+ m_editor->deleteLater();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/listwidget_taskmenu.h b/src/designer/src/components/taskmenu/listwidget_taskmenu.h
new file mode 100644
index 000000000..e7e527a38
--- /dev/null
+++ b/src/designer/src/components/taskmenu/listwidget_taskmenu.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LISTWIDGET_TASKMENU_H
+#define LISTWIDGET_TASKMENU_H
+
+#include <QtGui/QListWidget>
+#include <QtCore/QPointer>
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QLineEdit;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class ListWidgetTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit ListWidgetTaskMenu(QListWidget *button, QObject *parent = 0);
+ virtual ~ListWidgetTaskMenu();
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void editItems();
+ void updateSelection();
+
+private:
+ QListWidget *m_listWidget;
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+ QPointer<QLineEdit> m_editor;
+ mutable QList<QAction*> m_taskActions;
+ QAction *m_editItemsAction;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QListWidget, ListWidgetTaskMenu> ListWidgetTaskMenuFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LISTWIDGET_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/listwidgeteditor.cpp b/src/designer/src/components/taskmenu/listwidgeteditor.cpp
new file mode 100644
index 000000000..7c81ea47e
--- /dev/null
+++ b/src/designer/src/components/taskmenu/listwidgeteditor.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "listwidgeteditor.h"
+#include <designerpropertymanager.h>
+#include <abstractformbuilder.h>
+
+#include <QtDesigner/private/abstractsettings_p.h>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QComboBox>
+#include <QtGui/QGroupBox>
+#include <QtGui/QDialogButtonBox>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+ListWidgetEditor::ListWidgetEditor(QDesignerFormWindowInterface *form,
+ QWidget *parent)
+ : QDialog(parent)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ QDialogButtonBox *buttonBox = new QDialogButtonBox;
+ buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
+ connect(buttonBox, SIGNAL(accepted()), SLOT(accept()));
+ connect(buttonBox, SIGNAL(rejected()), SLOT(reject()));
+
+ m_itemsEditor = new ItemListEditor(form, 0);
+ m_itemsEditor->layout()->setMargin(0);
+ m_itemsEditor->setNewItemText(tr("New Item"));
+
+ QFrame *sep = new QFrame;
+ sep->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+
+ QBoxLayout *box = new QVBoxLayout(this);
+ box->addWidget(m_itemsEditor);
+ box->addWidget(sep);
+ box->addWidget(buttonBox);
+
+ // Numbers copied from itemlisteditor.ui
+ // (Automatic resizing doesn't work because ui has parent).
+ resize(550, 360);
+}
+
+static AbstractItemEditor::PropertyDefinition listBoxPropList[] = {
+ { Qt::DisplayPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "text" },
+ { Qt::DecorationPropertyRole, 0, DesignerPropertyManager::designerIconTypeId, "icon" },
+ { Qt::ToolTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "toolTip" },
+ { Qt::StatusTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "statusTip" },
+ { Qt::WhatsThisPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "whatsThis" },
+ { Qt::FontRole, QVariant::Font, 0, "font" },
+ { Qt::TextAlignmentRole, 0, DesignerPropertyManager::designerAlignmentTypeId, "textAlignment" },
+ { Qt::BackgroundRole, QVariant::Brush, 0, "background" },
+ { Qt::ForegroundRole, QVariant::Brush, 0, "foreground" },
+ { ItemFlagsShadowRole, 0, QtVariantPropertyManager::flagTypeId, "flags" },
+ { Qt::CheckStateRole, 0, QtVariantPropertyManager::enumTypeId, "checkState" },
+ { 0, 0, 0, 0 }
+};
+
+ListContents ListWidgetEditor::fillContentsFromListWidget(QListWidget *listWidget)
+{
+ setWindowTitle(tr("Edit List Widget"));
+
+ ListContents retVal;
+ retVal.createFromListWidget(listWidget, false);
+ retVal.applyToListWidget(m_itemsEditor->listWidget(), m_itemsEditor->iconCache(), true);
+
+ m_itemsEditor->setupEditor(listWidget, listBoxPropList);
+
+ return retVal;
+}
+
+static AbstractItemEditor::PropertyDefinition comboBoxPropList[] = {
+ { Qt::DisplayPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "text" },
+ { Qt::DecorationPropertyRole, 0, DesignerPropertyManager::designerIconTypeId, "icon" },
+ { 0, 0, 0, 0 }
+};
+
+ListContents ListWidgetEditor::fillContentsFromComboBox(QComboBox *comboBox)
+{
+ setWindowTitle(tr("Edit Combobox"));
+
+ ListContents retVal;
+ retVal.createFromComboBox(comboBox);
+ retVal.applyToListWidget(m_itemsEditor->listWidget(), m_itemsEditor->iconCache(), true);
+
+ m_itemsEditor->setupEditor(comboBox, comboBoxPropList);
+
+ return retVal;
+}
+
+ListContents ListWidgetEditor::contents() const
+{
+ ListContents retVal;
+ retVal.createFromListWidget(m_itemsEditor->listWidget(), true);
+ return retVal;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/listwidgeteditor.h b/src/designer/src/components/taskmenu/listwidgeteditor.h
new file mode 100644
index 000000000..12d0591f2
--- /dev/null
+++ b/src/designer/src/components/taskmenu/listwidgeteditor.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LISTWIDGETEDITOR_H
+#define LISTWIDGETEDITOR_H
+
+#include "itemlisteditor.h"
+#include <qdesigner_command_p.h>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QListWidget;
+class QComboBox;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class ListWidgetEditor: public QDialog
+{
+ Q_OBJECT
+
+public:
+ ListWidgetEditor(QDesignerFormWindowInterface *form,
+ QWidget *parent);
+
+ ListContents fillContentsFromListWidget(QListWidget *listWidget);
+ ListContents fillContentsFromComboBox(QComboBox *comboBox);
+ ListContents contents() const;
+
+private:
+ ItemListEditor *m_itemsEditor;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LISTWIDGETEDITOR_H
diff --git a/src/designer/src/components/taskmenu/menutaskmenu.cpp b/src/designer/src/components/taskmenu/menutaskmenu.cpp
new file mode 100644
index 000000000..cbcecb122
--- /dev/null
+++ b/src/designer/src/components/taskmenu/menutaskmenu.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "menutaskmenu.h"
+
+#include <promotiontaskmenu_p.h>
+
+#include <QtGui/QAction>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ // ------------ MenuTaskMenu
+ MenuTaskMenu::MenuTaskMenu(QDesignerMenu *menu, QObject *parent) :
+ QObject(parent),
+ m_menu(menu),
+ m_removeAction(new QAction(tr("Remove"), this)),
+ m_promotionTaskMenu(new PromotionTaskMenu(menu, PromotionTaskMenu::ModeSingleWidget, this))
+ {
+ connect(m_removeAction, SIGNAL(triggered()), this, SLOT(removeMenu()));
+ }
+
+ QAction *MenuTaskMenu::preferredEditAction() const
+ {
+ return 0;
+ }
+
+ QList<QAction*> MenuTaskMenu::taskActions() const
+ {
+ QList<QAction*> rc;
+ rc.push_back(m_removeAction);
+ m_promotionTaskMenu->addActions(PromotionTaskMenu::LeadingSeparator, rc);
+ return rc;
+ }
+
+ void MenuTaskMenu::removeMenu()
+ {
+ // Are we on a menu bar or on a menu?
+ QWidget *pw = m_menu->parentWidget();
+ if (QDesignerMenuBar *mb = qobject_cast<QDesignerMenuBar *>(pw)) {
+ mb->deleteMenuAction(m_menu->menuAction());
+ return;
+ }
+ if (QDesignerMenu *m = qobject_cast<QDesignerMenu *>(pw)) {
+ m->deleteAction(m_menu->menuAction());
+ }
+ }
+
+ // ------------- MenuBarTaskMenu
+ MenuBarTaskMenu::MenuBarTaskMenu(QDesignerMenuBar *bar, QObject *parent) :
+ QObject(parent),
+ m_bar(bar)
+ {
+ }
+
+ QAction *MenuBarTaskMenu::preferredEditAction() const
+ {
+ return 0;
+ }
+
+ QList<QAction*> MenuBarTaskMenu::taskActions() const
+ {
+ return m_bar->contextMenuActions();
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/components/taskmenu/menutaskmenu.h b/src/designer/src/components/taskmenu/menutaskmenu.h
new file mode 100644
index 000000000..35cb061b4
--- /dev/null
+++ b/src/designer/src/components/taskmenu/menutaskmenu.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MENUTASKMENU_H
+#define MENUTASKMENU_H
+
+#include <QtDesigner/QDesignerTaskMenuExtension>
+
+#include <qdesigner_menu_p.h>
+#include <qdesigner_menubar_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+ class PromotionTaskMenu;
+
+// The QMenu task menu provides promotion and a remove option. The actual
+// menu context options are not forwarded since they make only sense
+// when a menu is being edited/visible.
+
+class MenuTaskMenu : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit MenuTaskMenu(QDesignerMenu *menu, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void removeMenu();
+
+private:
+ QDesignerMenu *m_menu;
+ QAction *m_removeAction;
+ PromotionTaskMenu *m_promotionTaskMenu;
+};
+
+// The QMenuBar task menu forwards the actions of QDesignerMenuBar,
+// making them available in the object inspector.
+
+class MenuBarTaskMenu : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit MenuBarTaskMenu(QDesignerMenuBar *bar, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private:
+ QDesignerMenuBar *m_bar;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QDesignerMenu, MenuTaskMenu> MenuTaskMenuFactory;
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QDesignerMenuBar, MenuBarTaskMenu> MenuBarTaskMenuFactory;
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // MENUTASKMENU_H
diff --git a/src/designer/src/components/taskmenu/tablewidget_taskmenu.cpp b/src/designer/src/components/taskmenu/tablewidget_taskmenu.cpp
new file mode 100644
index 000000000..e98714f62
--- /dev/null
+++ b/src/designer/src/components/taskmenu/tablewidget_taskmenu.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tablewidget_taskmenu.h"
+#include "tablewidgeteditor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QTableWidget>
+#include <QtGui/QAction>
+#include <QtGui/QLineEdit>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+
+#include <QtCore/QEvent>
+#include <QtCore/QVariant>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+TableWidgetTaskMenu::TableWidgetTaskMenu(QTableWidget *button, QObject *parent)
+ : QDesignerTaskMenu(button, parent),
+ m_tableWidget(button),
+ m_editItemsAction(new QAction(tr("Edit Items..."), this))
+{
+ connect(m_editItemsAction, SIGNAL(triggered()), this, SLOT(editItems()));
+ m_taskActions.append(m_editItemsAction);
+
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ m_taskActions.append(sep);
+}
+
+
+TableWidgetTaskMenu::~TableWidgetTaskMenu()
+{
+}
+
+QAction *TableWidgetTaskMenu::preferredEditAction() const
+{
+ return m_editItemsAction;
+}
+
+QList<QAction*> TableWidgetTaskMenu::taskActions() const
+{
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+void TableWidgetTaskMenu::editItems()
+{
+ m_formWindow = QDesignerFormWindowInterface::findFormWindow(m_tableWidget);
+ if (m_formWindow.isNull())
+ return;
+
+ Q_ASSERT(m_tableWidget != 0);
+
+ TableWidgetEditorDialog dlg(m_formWindow, m_tableWidget->window());
+ TableWidgetContents oldCont = dlg.fillContentsFromTableWidget(m_tableWidget);
+ if (dlg.exec() == QDialog::Accepted) {
+ TableWidgetContents newCont = dlg.contents();
+ if (newCont != oldCont) {
+ ChangeTableContentsCommand *cmd = new ChangeTableContentsCommand(m_formWindow);
+ cmd->init(m_tableWidget, oldCont, newCont);
+ m_formWindow->commandHistory()->push(cmd);
+ }
+ }
+}
+
+void TableWidgetTaskMenu::updateSelection()
+{
+ if (m_editor)
+ m_editor->deleteLater();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/tablewidget_taskmenu.h b/src/designer/src/components/taskmenu/tablewidget_taskmenu.h
new file mode 100644
index 000000000..cbf71fea6
--- /dev/null
+++ b/src/designer/src/components/taskmenu/tablewidget_taskmenu.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TABLEWIDGET_TASKMENU_H
+#define TABLEWIDGET_TASKMENU_H
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+#include <QtGui/QTableWidget>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QLineEdit;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class TableWidgetTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit TableWidgetTaskMenu(QTableWidget *button, QObject *parent = 0);
+ virtual ~TableWidgetTaskMenu();
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void editItems();
+ void updateSelection();
+
+private:
+ QTableWidget *m_tableWidget;
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+ QPointer<QLineEdit> m_editor;
+ mutable QList<QAction*> m_taskActions;
+ QAction *m_editItemsAction;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QTableWidget, TableWidgetTaskMenu> TableWidgetTaskMenuFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TABLEWIDGET_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/tablewidgeteditor.cpp b/src/designer/src/components/taskmenu/tablewidgeteditor.cpp
new file mode 100644
index 000000000..35f1a0e49
--- /dev/null
+++ b/src/designer/src/components/taskmenu/tablewidgeteditor.cpp
@@ -0,0 +1,450 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tablewidgeteditor.h"
+#include <abstractformbuilder.h>
+#include <iconloader_p.h>
+#include <qdesigner_command_p.h>
+#include "formwindowbase_p.h"
+#include "qdesigner_utils_p.h"
+#include <designerpropertymanager.h>
+#include <qttreepropertybrowser.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtCore/QDir>
+#include <QtCore/QQueue>
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+TableWidgetEditor::TableWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog)
+ : AbstractItemEditor(form, 0), m_updatingBrowser(false)
+{
+ m_columnEditor = new ItemListEditor(form, this);
+ m_columnEditor->setObjectName(QLatin1String("columnEditor"));
+ m_columnEditor->setNewItemText(tr("New Column"));
+ m_rowEditor = new ItemListEditor(form, this);
+ m_rowEditor->setObjectName(QLatin1String("rowEditor"));
+ m_rowEditor->setNewItemText(tr("New Row"));
+ ui.setupUi(dialog);
+
+ injectPropertyBrowser(ui.itemsTab, ui.widget);
+ connect(ui.showPropertiesButton, SIGNAL(clicked()),
+ this, SLOT(togglePropertyBrowser()));
+ setPropertyBrowserVisible(false);
+
+ ui.tabWidget->insertTab(0, m_columnEditor, tr("&Columns"));
+ ui.tabWidget->insertTab(1, m_rowEditor, tr("&Rows"));
+ ui.tabWidget->setCurrentIndex(0);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ ui.tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ connect(iconCache(), SIGNAL(reloaded()), this, SLOT(cacheReloaded()));
+
+ connect(ui.tableWidget, SIGNAL(currentCellChanged(int,int,int,int)),
+ this, SLOT(on_tableWidget_currentCellChanged(int,int,int,int)));
+ connect(ui.tableWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
+ this, SLOT(on_tableWidget_itemChanged(QTableWidgetItem*)));
+ connect(m_columnEditor, SIGNAL(indexChanged(int)),
+ this, SLOT(on_columnEditor_indexChanged(int)));
+ connect(m_columnEditor, SIGNAL(itemChanged(int,int,QVariant)),
+ this, SLOT(on_columnEditor_itemChanged(int,int,QVariant)));
+ connect(m_columnEditor, SIGNAL(itemInserted(int)),
+ this, SLOT(on_columnEditor_itemInserted(int)));
+ connect(m_columnEditor, SIGNAL(itemDeleted(int)),
+ this, SLOT(on_columnEditor_itemDeleted(int)));
+ connect(m_columnEditor, SIGNAL(itemMovedUp(int)),
+ this, SLOT(on_columnEditor_itemMovedUp(int)));
+ connect(m_columnEditor, SIGNAL(itemMovedDown(int)),
+ this, SLOT(on_columnEditor_itemMovedDown(int)));
+
+ connect(m_rowEditor, SIGNAL(indexChanged(int)),
+ this, SLOT(on_rowEditor_indexChanged(int)));
+ connect(m_rowEditor, SIGNAL(itemChanged(int,int,QVariant)),
+ this, SLOT(on_rowEditor_itemChanged(int,int,QVariant)));
+ connect(m_rowEditor, SIGNAL(itemInserted(int)),
+ this, SLOT(on_rowEditor_itemInserted(int)));
+ connect(m_rowEditor, SIGNAL(itemDeleted(int)),
+ this, SLOT(on_rowEditor_itemDeleted(int)));
+ connect(m_rowEditor, SIGNAL(itemMovedUp(int)),
+ this, SLOT(on_rowEditor_itemMovedUp(int)));
+ connect(m_rowEditor, SIGNAL(itemMovedDown(int)),
+ this, SLOT(on_rowEditor_itemMovedDown(int)));
+}
+
+static AbstractItemEditor::PropertyDefinition tableHeaderPropList[] = {
+ { Qt::DisplayPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "text" },
+ { Qt::DecorationPropertyRole, 0, DesignerPropertyManager::designerIconTypeId, "icon" },
+ { Qt::ToolTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "toolTip" },
+// { Qt::StatusTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "statusTip" },
+ { Qt::WhatsThisPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "whatsThis" },
+ { Qt::FontRole, QVariant::Font, 0, "font" },
+ { Qt::TextAlignmentRole, 0, DesignerPropertyManager::designerAlignmentTypeId, "textAlignment" },
+ { Qt::BackgroundRole, QVariant::Color, 0, "background" },
+ { Qt::ForegroundRole, QVariant::Brush, 0, "foreground" },
+ { 0, 0, 0, 0 }
+};
+
+static AbstractItemEditor::PropertyDefinition tableItemPropList[] = {
+ { Qt::DisplayPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "text" },
+ { Qt::DecorationPropertyRole, 0, DesignerPropertyManager::designerIconTypeId, "icon" },
+ { Qt::ToolTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "toolTip" },
+// { Qt::StatusTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "statusTip" },
+ { Qt::WhatsThisPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "whatsThis" },
+ { Qt::FontRole, QVariant::Font, 0, "font" },
+ { Qt::TextAlignmentRole, 0, DesignerPropertyManager::designerAlignmentTypeId, "textAlignment" },
+ { Qt::BackgroundRole, QVariant::Brush, 0, "background" },
+ { Qt::ForegroundRole, QVariant::Brush, 0, "foreground" },
+ { ItemFlagsShadowRole, 0, QtVariantPropertyManager::flagTypeId, "flags" },
+ { Qt::CheckStateRole, 0, QtVariantPropertyManager::enumTypeId, "checkState" },
+ { 0, 0, 0, 0 }
+};
+
+TableWidgetContents TableWidgetEditor::fillContentsFromTableWidget(QTableWidget *tableWidget)
+{
+ TableWidgetContents tblCont;
+ tblCont.fromTableWidget(tableWidget, false);
+ tblCont.applyToTableWidget(ui.tableWidget, iconCache(), true);
+
+ tblCont.m_verticalHeader.applyToListWidget(m_rowEditor->listWidget(), iconCache(), true);
+ m_rowEditor->setupEditor(tableWidget, tableHeaderPropList);
+
+ tblCont.m_horizontalHeader.applyToListWidget(m_columnEditor->listWidget(), iconCache(), true);
+ m_columnEditor->setupEditor(tableWidget, tableHeaderPropList);
+
+ setupEditor(tableWidget, tableItemPropList);
+ if (ui.tableWidget->columnCount() > 0 && ui.tableWidget->rowCount() > 0)
+ ui.tableWidget->setCurrentCell(0, 0);
+
+ updateEditor();
+
+ return tblCont;
+}
+
+TableWidgetContents TableWidgetEditor::contents() const
+{
+ TableWidgetContents retVal;
+ retVal.fromTableWidget(ui.tableWidget, true);
+ return retVal;
+}
+
+void TableWidgetEditor::setItemData(int role, const QVariant &v)
+{
+ QTableWidgetItem *item = ui.tableWidget->currentItem();
+ BoolBlocker block(m_updatingBrowser);
+ if (!item) {
+ item = new QTableWidgetItem;
+ ui.tableWidget->setItem(ui.tableWidget->currentRow(), ui.tableWidget->currentColumn(), item);
+ }
+ QVariant newValue = v;
+ if (role == Qt::FontRole && newValue.type() == QVariant::Font) {
+ QFont oldFont = ui.tableWidget->font();
+ QFont newFont = qvariant_cast<QFont>(newValue).resolve(oldFont);
+ newValue = QVariant::fromValue(newFont);
+ item->setData(role, QVariant()); // force the right font with the current resolve mask is set (item view bug)
+ }
+ item->setData(role, newValue);
+}
+
+QVariant TableWidgetEditor::getItemData(int role) const
+{
+ QTableWidgetItem *item = ui.tableWidget->currentItem();
+ if (!item)
+ return QVariant();
+ return item->data(role);
+}
+
+void TableWidgetEditor::on_tableWidget_currentCellChanged(int currentRow, int currentCol, int, int /* XXX remove me */)
+{
+ m_rowEditor->setCurrentIndex(currentRow);
+ m_columnEditor->setCurrentIndex(currentCol);
+ updateBrowser();
+}
+
+void TableWidgetEditor::on_tableWidget_itemChanged(QTableWidgetItem *item)
+{
+ if (m_updatingBrowser)
+ return;
+
+ PropertySheetStringValue val = qvariant_cast<PropertySheetStringValue>(item->data(Qt::DisplayPropertyRole));
+ val.setValue(item->text());
+ BoolBlocker block(m_updatingBrowser);
+ item->setData(Qt::DisplayPropertyRole, QVariant::fromValue(val));
+
+ updateBrowser();
+}
+
+void TableWidgetEditor::on_columnEditor_indexChanged(int col)
+{
+ ui.tableWidget->setCurrentCell(ui.tableWidget->currentRow(), col);
+}
+
+void TableWidgetEditor::on_columnEditor_itemChanged(int idx, int role, const QVariant &v)
+{
+ ui.tableWidget->horizontalHeaderItem(idx)->setData(role, v);
+}
+
+void TableWidgetEditor::on_rowEditor_indexChanged(int col)
+{
+ ui.tableWidget->setCurrentCell(col, ui.tableWidget->currentColumn());
+}
+
+void TableWidgetEditor::on_rowEditor_itemChanged(int idx, int role, const QVariant &v)
+{
+ ui.tableWidget->verticalHeaderItem(idx)->setData(role, v);
+}
+
+void TableWidgetEditor::setPropertyBrowserVisible(bool v)
+{
+ ui.showPropertiesButton->setText(v ? tr("Properties &>>") : tr("Properties &<<"));
+ m_propertyBrowser->setVisible(v);
+}
+
+void TableWidgetEditor::togglePropertyBrowser()
+{
+ setPropertyBrowserVisible(!m_propertyBrowser->isVisible());
+}
+
+void TableWidgetEditor::updateEditor()
+{
+ const bool wasEnabled = ui.tabWidget->isTabEnabled(2);
+ const bool isEnabled = ui.tableWidget->columnCount() && ui.tableWidget->rowCount();
+ ui.tabWidget->setTabEnabled(2, isEnabled);
+ if (!wasEnabled && isEnabled)
+ ui.tableWidget->setCurrentCell(0, 0);
+
+ QMetaObject::invokeMethod(ui.tableWidget, "updateGeometries");
+ ui.tableWidget->viewport()->update();
+}
+
+void TableWidgetEditor::moveColumnsLeft(int fromColumn, int toColumn)
+{
+ if (fromColumn >= toColumn)
+ return;
+
+ QTableWidgetItem *lastItem = ui.tableWidget->takeHorizontalHeaderItem(toColumn);
+ for (int i = toColumn; i > fromColumn; i--) {
+ ui.tableWidget->setHorizontalHeaderItem(i,
+ ui.tableWidget->takeHorizontalHeaderItem(i - 1));
+ }
+ ui.tableWidget->setHorizontalHeaderItem(fromColumn, lastItem);
+
+ for (int i = 0; i < ui.tableWidget->rowCount(); i++) {
+ QTableWidgetItem *lastItem = ui.tableWidget->takeItem(i, toColumn);
+ for (int j = toColumn; j > fromColumn; j--)
+ ui.tableWidget->setItem(i, j, ui.tableWidget->takeItem(i, j - 1));
+ ui.tableWidget->setItem(i, fromColumn, lastItem);
+ }
+}
+
+void TableWidgetEditor::moveColumnsRight(int fromColumn, int toColumn)
+{
+ if (fromColumn >= toColumn)
+ return;
+
+ QTableWidgetItem *lastItem = ui.tableWidget->takeHorizontalHeaderItem(fromColumn);
+ for (int i = fromColumn; i < toColumn; i++) {
+ ui.tableWidget->setHorizontalHeaderItem(i,
+ ui.tableWidget->takeHorizontalHeaderItem(i + 1));
+ }
+ ui.tableWidget->setHorizontalHeaderItem(toColumn, lastItem);
+
+ for (int i = 0; i < ui.tableWidget->rowCount(); i++) {
+ QTableWidgetItem *lastItem = ui.tableWidget->takeItem(i, fromColumn);
+ for (int j = fromColumn; j < toColumn; j++)
+ ui.tableWidget->setItem(i, j, ui.tableWidget->takeItem(i, j + 1));
+ ui.tableWidget->setItem(i, toColumn, lastItem);
+ }
+}
+
+void TableWidgetEditor::moveRowsDown(int fromRow, int toRow)
+{
+ if (fromRow >= toRow)
+ return;
+
+ QTableWidgetItem *lastItem = ui.tableWidget->takeVerticalHeaderItem(toRow);
+ for (int i = toRow; i > fromRow; i--) {
+ ui.tableWidget->setVerticalHeaderItem(i,
+ ui.tableWidget->takeVerticalHeaderItem(i - 1));
+ }
+ ui.tableWidget->setVerticalHeaderItem(fromRow, lastItem);
+
+ for (int i = 0; i < ui.tableWidget->columnCount(); i++) {
+ QTableWidgetItem *lastItem = ui.tableWidget->takeItem(toRow, i);
+ for (int j = toRow; j > fromRow; j--)
+ ui.tableWidget->setItem(j, i, ui.tableWidget->takeItem(j - 1, i));
+ ui.tableWidget->setItem(fromRow, i, lastItem);
+ }
+}
+
+void TableWidgetEditor::moveRowsUp(int fromRow, int toRow)
+{
+ if (fromRow >= toRow)
+ return;
+
+ QTableWidgetItem *lastItem = ui.tableWidget->takeVerticalHeaderItem(fromRow);
+ for (int i = fromRow; i < toRow; i++) {
+ ui.tableWidget->setVerticalHeaderItem(i,
+ ui.tableWidget->takeVerticalHeaderItem(i + 1));
+ }
+ ui.tableWidget->setVerticalHeaderItem(toRow, lastItem);
+
+ for (int i = 0; i < ui.tableWidget->columnCount(); i++) {
+ QTableWidgetItem *lastItem = ui.tableWidget->takeItem(fromRow, i);
+ for (int j = fromRow; j < toRow; j++)
+ ui.tableWidget->setItem(j, i, ui.tableWidget->takeItem(j + 1, i));
+ ui.tableWidget->setItem(toRow, i, lastItem);
+ }
+}
+
+void TableWidgetEditor::on_columnEditor_itemInserted(int idx)
+{
+ const int columnCount = ui.tableWidget->columnCount();
+ ui.tableWidget->setColumnCount(columnCount + 1);
+
+ QTableWidgetItem *newItem = new QTableWidgetItem(m_columnEditor->newItemText());
+ newItem->setData(Qt::DisplayPropertyRole, QVariant::fromValue(PropertySheetStringValue(m_columnEditor->newItemText())));
+ ui.tableWidget->setHorizontalHeaderItem(columnCount, newItem);
+
+ moveColumnsLeft(idx, columnCount);
+
+ int row = ui.tableWidget->currentRow();
+ if (row >= 0)
+ ui.tableWidget->setCurrentCell(row, idx);
+
+ updateEditor();
+}
+
+void TableWidgetEditor::on_columnEditor_itemDeleted(int idx)
+{
+ const int columnCount = ui.tableWidget->columnCount();
+
+ moveColumnsRight(idx, columnCount - 1);
+ ui.tableWidget->setColumnCount(columnCount - 1);
+
+ updateEditor();
+}
+
+void TableWidgetEditor::on_columnEditor_itemMovedUp(int idx)
+{
+ moveColumnsRight(idx - 1, idx);
+
+ ui.tableWidget->setCurrentCell(ui.tableWidget->currentRow(), idx - 1);
+}
+
+void TableWidgetEditor::on_columnEditor_itemMovedDown(int idx)
+{
+ moveColumnsLeft(idx, idx + 1);
+
+ ui.tableWidget->setCurrentCell(ui.tableWidget->currentRow(), idx + 1);
+}
+
+void TableWidgetEditor::on_rowEditor_itemInserted(int idx)
+{
+ const int rowCount = ui.tableWidget->rowCount();
+ ui.tableWidget->setRowCount(rowCount + 1);
+
+ QTableWidgetItem *newItem = new QTableWidgetItem(m_rowEditor->newItemText());
+ newItem->setData(Qt::DisplayPropertyRole, QVariant::fromValue(PropertySheetStringValue(m_rowEditor->newItemText())));
+ ui.tableWidget->setVerticalHeaderItem(rowCount, newItem);
+
+ moveRowsDown(idx, rowCount);
+
+ int col = ui.tableWidget->currentColumn();
+ if (col >= 0)
+ ui.tableWidget->setCurrentCell(idx, col);
+
+ updateEditor();
+}
+
+void TableWidgetEditor::on_rowEditor_itemDeleted(int idx)
+{
+ const int rowCount = ui.tableWidget->rowCount();
+
+ moveRowsUp(idx, rowCount - 1);
+ ui.tableWidget->setRowCount(rowCount - 1);
+
+ updateEditor();
+}
+
+void TableWidgetEditor::on_rowEditor_itemMovedUp(int idx)
+{
+ moveRowsUp(idx - 1, idx);
+
+ ui.tableWidget->setCurrentCell(idx - 1, ui.tableWidget->currentColumn());
+}
+
+void TableWidgetEditor::on_rowEditor_itemMovedDown(int idx)
+{
+ moveRowsDown(idx, idx + 1);
+
+ ui.tableWidget->setCurrentCell(idx + 1, ui.tableWidget->currentColumn());
+}
+
+void TableWidgetEditor::cacheReloaded()
+{
+ reloadIconResources(iconCache(), ui.tableWidget);
+}
+
+TableWidgetEditorDialog::TableWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent) :
+ QDialog(parent), m_editor(form, this)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+}
+
+TableWidgetContents TableWidgetEditorDialog::fillContentsFromTableWidget(QTableWidget *tableWidget)
+{
+ return m_editor.fillContentsFromTableWidget(tableWidget);
+}
+
+TableWidgetContents TableWidgetEditorDialog::contents() const
+{
+ return m_editor.contents();
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/tablewidgeteditor.h b/src/designer/src/components/taskmenu/tablewidgeteditor.h
new file mode 100644
index 000000000..1d5ad1f57
--- /dev/null
+++ b/src/designer/src/components/taskmenu/tablewidgeteditor.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TABLEWIDGETEDITOR_H
+#define TABLEWIDGETEDITOR_H
+
+#include "ui_tablewidgeteditor.h"
+
+#include "listwidgeteditor.h"
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QTableWidget;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class FormWindowBase;
+class PropertySheetIconValue;
+
+class TableWidgetEditor: public AbstractItemEditor
+{
+ Q_OBJECT
+public:
+ explicit TableWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog);
+
+ TableWidgetContents fillContentsFromTableWidget(QTableWidget *tableWidget);
+ TableWidgetContents contents() const;
+
+private slots:
+
+ void on_tableWidget_currentCellChanged(int currentRow, int currnetCol, int, int);
+ void on_tableWidget_itemChanged(QTableWidgetItem *item);
+
+ void on_columnEditor_indexChanged(int idx);
+ void on_columnEditor_itemChanged(int idx, int role, const QVariant &v);
+
+ void on_columnEditor_itemInserted(int idx);
+ void on_columnEditor_itemDeleted(int idx);
+ void on_columnEditor_itemMovedUp(int idx);
+ void on_columnEditor_itemMovedDown(int idx);
+
+ void on_rowEditor_indexChanged(int idx);
+ void on_rowEditor_itemChanged(int idx, int role, const QVariant &v);
+
+ void on_rowEditor_itemInserted(int idx);
+ void on_rowEditor_itemDeleted(int idx);
+ void on_rowEditor_itemMovedUp(int idx);
+ void on_rowEditor_itemMovedDown(int idx);
+
+ void togglePropertyBrowser();
+
+ void cacheReloaded();
+
+protected:
+ virtual void setItemData(int role, const QVariant &v);
+ virtual QVariant getItemData(int role) const;
+
+private:
+ void setPropertyBrowserVisible(bool v);
+ void updateEditor();
+ void moveColumnsLeft(int fromColumn, int toColumn);
+ void moveColumnsRight(int fromColumn, int toColumn);
+ void moveRowsUp(int fromRow, int toRow);
+ void moveRowsDown(int fromRow, int toRow);
+
+ Ui::TableWidgetEditor ui;
+ ItemListEditor *m_rowEditor;
+ ItemListEditor *m_columnEditor;
+ bool m_updatingBrowser;
+};
+
+class TableWidgetEditorDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit TableWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent);
+
+ TableWidgetContents fillContentsFromTableWidget(QTableWidget *tableWidget);
+ TableWidgetContents contents() const;
+
+private:
+ TableWidgetEditor m_editor;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TABLEWIDGETEDITOR_H
diff --git a/src/designer/src/components/taskmenu/tablewidgeteditor.ui b/src/designer/src/components/taskmenu/tablewidgeteditor.ui
new file mode 100644
index 000000000..33691e94d
--- /dev/null
+++ b/src/designer/src/components/taskmenu/tablewidgeteditor.ui
@@ -0,0 +1,157 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::TableWidgetEditor</class>
+ <widget class="QDialog" name="qdesigner_internal::TableWidgetEditor" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>550</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Edit Table Widget</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="itemsTab" >
+ <attribute name="title" >
+ <string>&amp;Items</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <widget class="QWidget" native="1" name="widget" >
+ <layout class="QVBoxLayout" name="verticalLayout_3" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTableWidget" name="tableWidget" >
+ <property name="toolTip" >
+ <string>Table Items</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="buttonsLayout" >
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="showPropertiesButton" >
+ <property name="text" >
+ <string>Properties &amp;>></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>qdesigner_internal::TableWidgetEditor</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>431</x>
+ <y>351</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>373</x>
+ <y>362</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>qdesigner_internal::TableWidgetEditor</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>547</x>
+ <y>354</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>562</x>
+ <y>362</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/components/taskmenu/taskmenu.pri b/src/designer/src/components/taskmenu/taskmenu.pri
new file mode 100644
index 000000000..066b92980
--- /dev/null
+++ b/src/designer/src/components/taskmenu/taskmenu.pri
@@ -0,0 +1,50 @@
+INCLUDEPATH += $$PWD \
+ ../propertyeditor \
+ $$QT_BUILD_TREE/tools/designer/src/components/taskmenu \
+ $$QT_SOURCE_TREE/tools/shared/qtpropertybrowser
+
+FORMS += $$PWD/itemlisteditor.ui \
+ $$PWD/treewidgeteditor.ui \
+ $$PWD/tablewidgeteditor.ui
+
+HEADERS += $$PWD/button_taskmenu.h \
+ $$PWD/groupbox_taskmenu.h \
+ $$PWD/label_taskmenu.h \
+ $$PWD/lineedit_taskmenu.h \
+ $$PWD/listwidget_taskmenu.h \
+ $$PWD/treewidget_taskmenu.h \
+ $$PWD/tablewidget_taskmenu.h \
+ $$PWD/combobox_taskmenu.h \
+ $$PWD/textedit_taskmenu.h \
+ $$PWD/toolbar_taskmenu.h \
+ $$PWD/containerwidget_taskmenu.h \
+ $$PWD/inplace_editor.h \
+ $$PWD/taskmenu_component.h \
+ $$PWD/itemlisteditor.h \
+ $$PWD/listwidgeteditor.h \
+ $$PWD/treewidgeteditor.h \
+ $$PWD/tablewidgeteditor.h \
+ $$PWD/inplace_widget_helper.h \
+ $$PWD/menutaskmenu.h \
+ $$PWD/layouttaskmenu.h
+
+SOURCES += $$PWD/button_taskmenu.cpp \
+ $$PWD/groupbox_taskmenu.cpp \
+ $$PWD/label_taskmenu.cpp \
+ $$PWD/lineedit_taskmenu.cpp \
+ $$PWD/listwidget_taskmenu.cpp \
+ $$PWD/treewidget_taskmenu.cpp \
+ $$PWD/tablewidget_taskmenu.cpp \
+ $$PWD/combobox_taskmenu.cpp \
+ $$PWD/textedit_taskmenu.cpp \
+ $$PWD/toolbar_taskmenu.cpp \
+ $$PWD/containerwidget_taskmenu.cpp \
+ $$PWD/inplace_editor.cpp \
+ $$PWD/taskmenu_component.cpp \
+ $$PWD/itemlisteditor.cpp \
+ $$PWD/listwidgeteditor.cpp \
+ $$PWD/treewidgeteditor.cpp \
+ $$PWD/tablewidgeteditor.cpp \
+ $$PWD/inplace_widget_helper.cpp \
+ $$PWD/menutaskmenu.cpp \
+ $$PWD/layouttaskmenu.cpp
diff --git a/src/designer/src/components/taskmenu/taskmenu_component.cpp b/src/designer/src/components/taskmenu/taskmenu_component.cpp
new file mode 100644
index 000000000..c7f395349
--- /dev/null
+++ b/src/designer/src/components/taskmenu/taskmenu_component.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "taskmenu_component.h"
+#include "button_taskmenu.h"
+#include "groupbox_taskmenu.h"
+#include "label_taskmenu.h"
+#include "lineedit_taskmenu.h"
+#include "listwidget_taskmenu.h"
+#include "treewidget_taskmenu.h"
+#include "tablewidget_taskmenu.h"
+#include "containerwidget_taskmenu.h"
+#include "combobox_taskmenu.h"
+#include "textedit_taskmenu.h"
+#include "menutaskmenu.h"
+#include "toolbar_taskmenu.h"
+#include "layouttaskmenu.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+TaskMenuComponent::TaskMenuComponent(QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent),
+ m_core(core)
+{
+ Q_ASSERT(m_core != 0);
+
+ QExtensionManager *mgr = core->extensionManager();
+ const QString taskMenuId = QLatin1String("QDesignerInternalTaskMenuExtension");
+
+ ButtonTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ CommandLinkButtonTaskMenuFactory::registerExtension(mgr, taskMenuId); // Order!
+ ButtonGroupTaskMenuFactory::registerExtension(mgr, taskMenuId);
+
+ GroupBoxTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ LabelTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ LineEditTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ ListWidgetTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ TreeWidgetTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ TableWidgetTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ TextEditTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ PlainTextEditTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ MenuTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ MenuBarTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ ToolBarTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ StatusBarTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ LayoutWidgetTaskMenuFactory::registerExtension(mgr, taskMenuId);
+ SpacerTaskMenuFactory::registerExtension(mgr, taskMenuId);
+
+ mgr->registerExtensions(new ContainerWidgetTaskMenuFactory(core, mgr), taskMenuId);
+ mgr->registerExtensions(new ComboBoxTaskMenuFactory(taskMenuId, mgr), taskMenuId);
+}
+
+TaskMenuComponent::~TaskMenuComponent()
+{
+}
+
+QDesignerFormEditorInterface *TaskMenuComponent::core() const
+{
+ return m_core;
+
+}
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/components/taskmenu/taskmenu_component.h b/src/designer/src/components/taskmenu/taskmenu_component.h
new file mode 100644
index 000000000..762567c84
--- /dev/null
+++ b/src/designer/src/components/taskmenu/taskmenu_component.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TASKMENU_COMPONENT_H
+#define TASKMENU_COMPONENT_H
+
+#include "taskmenu_global.h"
+#include <QtDesigner/taskmenu.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class QT_TASKMENU_EXPORT TaskMenuComponent: public QObject
+{
+ Q_OBJECT
+public:
+ explicit TaskMenuComponent(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ virtual ~TaskMenuComponent();
+
+ QDesignerFormEditorInterface *core() const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TASKMENU_COMPONENT_H
diff --git a/src/designer/src/components/taskmenu/taskmenu_global.h b/src/designer/src/components/taskmenu/taskmenu_global.h
new file mode 100644
index 000000000..df276016c
--- /dev/null
+++ b/src/designer/src/components/taskmenu/taskmenu_global.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TASKMENU_GLOBAL_H
+#define TASKMENU_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN
+#ifdef QT_TASKMENU_LIBRARY
+# define QT_TASKMENU_EXPORT
+#else
+# define QT_TASKMENU_EXPORT
+#endif
+#else
+#define QT_TASKMENU_EXPORT
+#endif
+
+#endif // TASKMENU_GLOBAL_H
diff --git a/src/designer/src/components/taskmenu/textedit_taskmenu.cpp b/src/designer/src/components/taskmenu/textedit_taskmenu.cpp
new file mode 100644
index 000000000..510a32f5f
--- /dev/null
+++ b/src/designer/src/components/taskmenu/textedit_taskmenu.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "textedit_taskmenu.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtCore/QEvent>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+TextEditTaskMenu::TextEditTaskMenu(QTextEdit *textEdit, QObject *parent) :
+ QDesignerTaskMenu(textEdit, parent),
+ m_format(Qt::RichText),
+ m_property(QLatin1String("html")),
+ m_windowTitle(tr("Edit HTML")),
+ m_editTextAction(new QAction(tr("Change HTML..."), this))
+{
+ initialize();
+}
+
+TextEditTaskMenu::TextEditTaskMenu(QPlainTextEdit *textEdit, QObject *parent) :
+ QDesignerTaskMenu(textEdit, parent),
+ m_format(Qt::PlainText),
+ m_property(QLatin1String("plainText")),
+ m_windowTitle(tr("Edit Text")),
+ m_editTextAction(new QAction(tr("Change Plain Text..."), this))
+{
+ initialize();
+}
+
+
+void TextEditTaskMenu::initialize()
+{
+ connect(m_editTextAction, SIGNAL(triggered()), this, SLOT(editText()));
+ m_taskActions.append(m_editTextAction);
+
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ m_taskActions.append(sep);
+}
+
+TextEditTaskMenu::~TextEditTaskMenu()
+{
+}
+
+QAction *TextEditTaskMenu::preferredEditAction() const
+{
+ return m_editTextAction;
+}
+
+QList<QAction*> TextEditTaskMenu::taskActions() const
+{
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+void TextEditTaskMenu::editText()
+{
+ changeTextProperty(m_property, m_windowTitle, MultiSelectionMode, m_format);
+}
+
+}
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/textedit_taskmenu.h b/src/designer/src/components/taskmenu/textedit_taskmenu.h
new file mode 100644
index 000000000..1429f315e
--- /dev/null
+++ b/src/designer/src/components/taskmenu/textedit_taskmenu.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTEDIT_TASKMENU_H
+#define TEXTEDIT_TASKMENU_H
+
+#include <QtGui/QTextEdit>
+#include <QtGui/QPlainTextEdit>
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class TextEditTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit TextEditTaskMenu(QTextEdit *button, QObject *parent = 0);
+ explicit TextEditTaskMenu(QPlainTextEdit *button, QObject *parent = 0);
+
+ virtual ~TextEditTaskMenu();
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void editText();
+
+private:
+ void initialize();
+
+ const Qt::TextFormat m_format;
+ const QString m_property;
+ const QString m_windowTitle;
+
+ mutable QList<QAction*> m_taskActions;
+ QAction *m_editTextAction;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QTextEdit, TextEditTaskMenu> TextEditTaskMenuFactory;
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QPlainTextEdit, TextEditTaskMenu> PlainTextEditTaskMenuFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TEXTEDIT_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/toolbar_taskmenu.cpp b/src/designer/src/components/taskmenu/toolbar_taskmenu.cpp
new file mode 100644
index 000000000..8db233ca2
--- /dev/null
+++ b/src/designer/src/components/taskmenu/toolbar_taskmenu.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "toolbar_taskmenu.h"
+#include "qdesigner_toolbar_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <promotiontaskmenu_p.h>
+#include <qdesigner_command_p.h>
+
+#include <QtGui/QAction>
+#include <QtGui/QUndoStack>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ // ------------ ToolBarTaskMenu
+ ToolBarTaskMenu::ToolBarTaskMenu(QToolBar *tb, QObject *parent) :
+ QObject(parent),
+ m_toolBar(tb)
+ {
+ }
+
+ QAction *ToolBarTaskMenu::preferredEditAction() const
+ {
+ return 0;
+ }
+
+ QList<QAction*> ToolBarTaskMenu::taskActions() const
+ {
+ if (ToolBarEventFilter *ef = ToolBarEventFilter::eventFilterOf(m_toolBar))
+ return ef->contextMenuActions();
+ return QList<QAction*>();
+ }
+
+ // ------------ StatusBarTaskMenu
+ StatusBarTaskMenu::StatusBarTaskMenu(QStatusBar *sb, QObject *parent) :
+ QObject(parent),
+ m_statusBar(sb),
+ m_removeAction(new QAction(tr("Remove"), this)),
+ m_promotionTaskMenu(new PromotionTaskMenu(sb, PromotionTaskMenu::ModeSingleWidget, this))
+ {
+ connect(m_removeAction, SIGNAL(triggered()), this, SLOT(removeStatusBar()));
+ }
+
+ QAction *StatusBarTaskMenu::preferredEditAction() const
+ {
+ return 0;
+ }
+
+ QList<QAction*> StatusBarTaskMenu::taskActions() const
+ {
+ QList<QAction*> rc;
+ rc.push_back(m_removeAction);
+ m_promotionTaskMenu->addActions(PromotionTaskMenu::LeadingSeparator, rc);
+ return rc;
+ }
+
+ void StatusBarTaskMenu::removeStatusBar()
+ {
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_statusBar)) {
+ DeleteStatusBarCommand *cmd = new DeleteStatusBarCommand(fw);
+ cmd->init(m_statusBar);
+ fw->commandHistory()->push(cmd);
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/components/taskmenu/toolbar_taskmenu.h b/src/designer/src/components/taskmenu/toolbar_taskmenu.h
new file mode 100644
index 000000000..6818e2607
--- /dev/null
+++ b/src/designer/src/components/taskmenu/toolbar_taskmenu.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOOLBAR_TASKMENU_H
+#define TOOLBAR_TASKMENU_H
+
+#include <QtDesigner/QDesignerTaskMenuExtension>
+
+#include <extensionfactory_p.h>
+
+#include <QtGui/QToolBar>
+#include <QtGui/QStatusBar>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ class PromotionTaskMenu;
+
+// ToolBarTaskMenu forwards the actions of ToolBarEventFilter
+class ToolBarTaskMenu : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit ToolBarTaskMenu(QToolBar *tb, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private:
+ QToolBar *m_toolBar;
+};
+
+// StatusBarTaskMenu provides promotion and deletion
+class StatusBarTaskMenu : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit StatusBarTaskMenu(QStatusBar *tb, QObject *parent = 0);
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void removeStatusBar();
+
+private:
+ QStatusBar *m_statusBar;
+ QAction *m_removeAction;
+ PromotionTaskMenu *m_promotionTaskMenu;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QToolBar, ToolBarTaskMenu> ToolBarTaskMenuFactory;
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QStatusBar, StatusBarTaskMenu> StatusBarTaskMenuFactory;
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TOOLBAR_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/treewidget_taskmenu.cpp b/src/designer/src/components/taskmenu/treewidget_taskmenu.cpp
new file mode 100644
index 000000000..96210dcdb
--- /dev/null
+++ b/src/designer/src/components/taskmenu/treewidget_taskmenu.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "treewidget_taskmenu.h"
+#include "treewidgeteditor.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QStyle>
+#include <QtGui/QLineEdit>
+#include <QtGui/QStyleOption>
+
+#include <QtCore/QEvent>
+#include <QtCore/QVariant>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+TreeWidgetTaskMenu::TreeWidgetTaskMenu(QTreeWidget *button, QObject *parent)
+ : QDesignerTaskMenu(button, parent),
+ m_treeWidget(button),
+ m_editItemsAction(new QAction(tr("Edit Items..."), this))
+{
+ connect(m_editItemsAction, SIGNAL(triggered()), this, SLOT(editItems()));
+ m_taskActions.append(m_editItemsAction);
+
+ QAction *sep = new QAction(this);
+ sep->setSeparator(true);
+ m_taskActions.append(sep);
+}
+
+
+TreeWidgetTaskMenu::~TreeWidgetTaskMenu()
+{
+}
+
+QAction *TreeWidgetTaskMenu::preferredEditAction() const
+{
+ return m_editItemsAction;
+}
+
+QList<QAction*> TreeWidgetTaskMenu::taskActions() const
+{
+ return m_taskActions + QDesignerTaskMenu::taskActions();
+}
+
+void TreeWidgetTaskMenu::editItems()
+{
+ m_formWindow = QDesignerFormWindowInterface::findFormWindow(m_treeWidget);
+ if (m_formWindow.isNull())
+ return;
+
+ Q_ASSERT(m_treeWidget != 0);
+
+ TreeWidgetEditorDialog dlg(m_formWindow, m_treeWidget->window());
+ TreeWidgetContents oldCont = dlg.fillContentsFromTreeWidget(m_treeWidget);
+ if (dlg.exec() == QDialog::Accepted) {
+ TreeWidgetContents newCont = dlg.contents();
+ if (newCont != oldCont) {
+ ChangeTreeContentsCommand *cmd = new ChangeTreeContentsCommand(m_formWindow);
+ cmd->init(m_treeWidget, oldCont, newCont);
+ m_formWindow->commandHistory()->push(cmd);
+ }
+ }
+}
+
+void TreeWidgetTaskMenu::updateSelection()
+{
+ if (m_editor)
+ m_editor->deleteLater();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/treewidget_taskmenu.h b/src/designer/src/components/taskmenu/treewidget_taskmenu.h
new file mode 100644
index 000000000..e5a9e9073
--- /dev/null
+++ b/src/designer/src/components/taskmenu/treewidget_taskmenu.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TREEWIDGET_TASKMENU_H
+#define TREEWIDGET_TASKMENU_H
+
+#include <QtGui/QTreeWidget>
+#include <QtCore/QPointer>
+
+#include <qdesigner_taskmenu_p.h>
+#include <extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QLineEdit;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class TreeWidgetTaskMenu: public QDesignerTaskMenu
+{
+ Q_OBJECT
+public:
+ explicit TreeWidgetTaskMenu(QTreeWidget *button, QObject *parent = 0);
+ virtual ~TreeWidgetTaskMenu();
+
+ virtual QAction *preferredEditAction() const;
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void editItems();
+ void updateSelection();
+
+private:
+ QTreeWidget *m_treeWidget;
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+ QPointer<QLineEdit> m_editor;
+ mutable QList<QAction*> m_taskActions;
+ QAction *m_editItemsAction;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QTreeWidget, TreeWidgetTaskMenu> TreeWidgetTaskMenuFactory;
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TREEWIDGET_TASKMENU_H
diff --git a/src/designer/src/components/taskmenu/treewidgeteditor.cpp b/src/designer/src/components/taskmenu/treewidgeteditor.cpp
new file mode 100644
index 000000000..f5f6035f2
--- /dev/null
+++ b/src/designer/src/components/taskmenu/treewidgeteditor.cpp
@@ -0,0 +1,642 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "treewidgeteditor.h"
+#include <formwindowbase_p.h>
+#include <iconloader_p.h>
+#include <qdesigner_command_p.h>
+#include <qdesigner_utils_p.h>
+#include <abstractformbuilder.h>
+#include <designerpropertymanager.h>
+#include <qttreepropertybrowser.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtCore/QDir>
+#include <QtCore/QQueue>
+#include <QtGui/QHeaderView>
+#include <QtGui/QTreeWidgetItemIterator>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+TreeWidgetEditor::TreeWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog)
+ : AbstractItemEditor(form, 0), m_updatingBrowser(false)
+{
+ m_columnEditor = new ItemListEditor(form, this);
+ m_columnEditor->setObjectName(QLatin1String("columnEditor"));
+ m_columnEditor->setNewItemText(tr("New Column"));
+ ui.setupUi(dialog);
+
+ injectPropertyBrowser(ui.itemsTab, ui.widget);
+ connect(ui.showPropertiesButton, SIGNAL(clicked()),
+ this, SLOT(togglePropertyBrowser()));
+ setPropertyBrowserVisible(false);
+
+ ui.tabWidget->insertTab(0, m_columnEditor, tr("&Columns"));
+ ui.tabWidget->setCurrentIndex(0);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ ui.newItemButton->setIcon(createIconSet(QString::fromUtf8("plus.png")));
+ ui.newSubItemButton->setIcon(createIconSet(QString::fromUtf8("downplus.png")));
+ ui.deleteItemButton->setIcon(createIconSet(QString::fromUtf8("minus.png")));
+ ui.moveItemUpButton->setIcon(createIconSet(QString::fromUtf8("up.png")));
+ ui.moveItemDownButton->setIcon(createIconSet(QString::fromUtf8("down.png")));
+ ui.moveItemRightButton->setIcon(createIconSet(QString::fromUtf8("leveldown.png")));
+ ui.moveItemLeftButton->setIcon(createIconSet(QString::fromUtf8("levelup.png")));
+
+ ui.treeWidget->header()->setMovable(false);
+
+ connect(ui.newItemButton, SIGNAL(clicked()), this, SLOT(on_newItemButton_clicked()));
+ connect(ui.newSubItemButton, SIGNAL(clicked()), this, SLOT(on_newSubItemButton_clicked()));
+ connect(ui.moveItemUpButton, SIGNAL(clicked()), this, SLOT(on_moveItemUpButton_clicked()));
+ connect(ui.moveItemDownButton, SIGNAL(clicked()), this, SLOT(on_moveItemDownButton_clicked()));
+ connect(ui.moveItemRightButton, SIGNAL(clicked()), this, SLOT(on_moveItemRightButton_clicked()));
+ connect(ui.moveItemLeftButton, SIGNAL(clicked()), this, SLOT(on_moveItemLeftButton_clicked()));
+ connect(ui.treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ this, SLOT(on_treeWidget_currentItemChanged()));
+ connect(ui.treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
+ this, SLOT(on_treeWidget_itemChanged(QTreeWidgetItem*,int)));
+
+ connect(m_columnEditor, SIGNAL(indexChanged(int)),
+ this, SLOT(on_columnEditor_indexChanged(int)));
+ connect(m_columnEditor, SIGNAL(itemChanged(int,int,QVariant)),
+ this, SLOT(on_columnEditor_itemChanged(int,int,QVariant)));
+ connect(m_columnEditor, SIGNAL(itemInserted(int)),
+ this, SLOT(on_columnEditor_itemInserted(int)));
+ connect(m_columnEditor, SIGNAL(itemDeleted(int)),
+ this, SLOT(on_columnEditor_itemDeleted(int)));
+ connect(m_columnEditor, SIGNAL(itemMovedUp(int)),
+ this, SLOT(on_columnEditor_itemMovedUp(int)));
+ connect(m_columnEditor, SIGNAL(itemMovedDown(int)),
+ this, SLOT(on_columnEditor_itemMovedDown(int)));
+
+ connect(iconCache(), SIGNAL(reloaded()), this, SLOT(cacheReloaded()));
+}
+
+static AbstractItemEditor::PropertyDefinition treeHeaderPropList[] = {
+ { Qt::DisplayPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "text" },
+ { Qt::DecorationPropertyRole, 0, DesignerPropertyManager::designerIconTypeId, "icon" },
+ { Qt::ToolTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "toolTip" },
+ { Qt::StatusTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "statusTip" },
+ { Qt::WhatsThisPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "whatsThis" },
+ { Qt::FontRole, QVariant::Font, 0, "font" },
+ { Qt::TextAlignmentRole, 0, DesignerPropertyManager::designerAlignmentTypeId, "textAlignment" },
+ { Qt::BackgroundRole, QVariant::Color, 0, "background" },
+ { Qt::ForegroundRole, QVariant::Brush, 0, "foreground" },
+ { 0, 0, 0, 0 }
+};
+
+static AbstractItemEditor::PropertyDefinition treeItemColumnPropList[] = {
+ { Qt::DisplayPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "text" },
+ { Qt::DecorationPropertyRole, 0, DesignerPropertyManager::designerIconTypeId, "icon" },
+ { Qt::ToolTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "toolTip" },
+ { Qt::StatusTipPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "statusTip" },
+ { Qt::WhatsThisPropertyRole, 0, DesignerPropertyManager::designerStringTypeId, "whatsThis" },
+ { Qt::FontRole, QVariant::Font, 0, "font" },
+ { Qt::TextAlignmentRole, 0, DesignerPropertyManager::designerAlignmentTypeId, "textAlignment" },
+ { Qt::BackgroundRole, QVariant::Brush, 0, "background" },
+ { Qt::ForegroundRole, QVariant::Brush, 0, "foreground" },
+ { Qt::CheckStateRole, 0, QtVariantPropertyManager::enumTypeId, "checkState" },
+ { 0, 0, 0, 0 }
+};
+
+static AbstractItemEditor::PropertyDefinition treeItemCommonPropList[] = {
+ { ItemFlagsShadowRole, 0, QtVariantPropertyManager::flagTypeId, "flags" },
+ { 0, 0, 0, 0 }
+};
+
+QtVariantProperty *TreeWidgetEditor::setupPropertyGroup(const QString &title, PropertyDefinition *propDefs)
+{
+ setupProperties(propDefs);
+ QtVariantProperty *groupProp = m_propertyManager->addProperty(QtVariantPropertyManager::groupTypeId(), title);
+ foreach (QtVariantProperty *prop, m_rootProperties)
+ groupProp->addSubProperty(prop);
+ m_rootProperties.clear();
+ return groupProp;
+}
+
+TreeWidgetContents TreeWidgetEditor::fillContentsFromTreeWidget(QTreeWidget *treeWidget)
+{
+ TreeWidgetContents treeCont;
+ treeCont.fromTreeWidget(treeWidget, false);
+ treeCont.applyToTreeWidget(ui.treeWidget, iconCache(), true);
+
+ treeCont.m_headerItem.applyToListWidget(m_columnEditor->listWidget(), iconCache(), true);
+ m_columnEditor->setupEditor(treeWidget, treeHeaderPropList);
+
+ QList<QtVariantProperty*> rootProperties;
+ rootProperties.append(setupPropertyGroup(tr("Per column properties"), treeItemColumnPropList));
+ rootProperties.append(setupPropertyGroup(tr("Common properties"), treeItemCommonPropList));
+ m_rootProperties = rootProperties;
+ m_propertyBrowser->setPropertiesWithoutValueMarked(true);
+ m_propertyBrowser->setRootIsDecorated(false);
+ setupObject(treeWidget);
+
+ if (ui.treeWidget->topLevelItemCount() > 0)
+ ui.treeWidget->setCurrentItem(ui.treeWidget->topLevelItem(0));
+
+ updateEditor();
+
+ return treeCont;
+}
+
+TreeWidgetContents TreeWidgetEditor::contents() const
+{
+ TreeWidgetContents retVal;
+ retVal.fromTreeWidget(ui.treeWidget, true);
+ return retVal;
+}
+
+void TreeWidgetEditor::setItemData(int role, const QVariant &v)
+{
+ const int col = (role == ItemFlagsShadowRole) ? 0 : ui.treeWidget->currentColumn();
+ QVariant newValue = v;
+ BoolBlocker block(m_updatingBrowser);
+ if (role == Qt::FontRole && newValue.type() == QVariant::Font) {
+ QFont oldFont = ui.treeWidget->font();
+ QFont newFont = qvariant_cast<QFont>(newValue).resolve(oldFont);
+ newValue = QVariant::fromValue(newFont);
+ ui.treeWidget->currentItem()->setData(col, role, QVariant()); // force the right font with the current resolve mask is set (item view bug)
+ }
+ ui.treeWidget->currentItem()->setData(col, role, newValue);
+}
+
+QVariant TreeWidgetEditor::getItemData(int role) const
+{
+ const int col = (role == ItemFlagsShadowRole) ? 0 : ui.treeWidget->currentColumn();
+ return ui.treeWidget->currentItem()->data(col, role);
+}
+
+void TreeWidgetEditor::on_newItemButton_clicked()
+{
+ QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
+ QTreeWidgetItem *newItem = 0;
+ ui.treeWidget->blockSignals(true);
+ if (curItem) {
+ if (curItem->parent())
+ newItem = new QTreeWidgetItem(curItem->parent(), curItem);
+ else
+ newItem = new QTreeWidgetItem(ui.treeWidget, curItem);
+ } else
+ newItem = new QTreeWidgetItem(ui.treeWidget);
+ const QString newItemText = tr("New Item");
+ newItem->setText(0, newItemText);
+ newItem->setData(0, Qt::DisplayPropertyRole, QVariant::fromValue(PropertySheetStringValue(newItemText)));
+ newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
+ ui.treeWidget->blockSignals(false);
+
+ ui.treeWidget->setCurrentItem(newItem, qMax(ui.treeWidget->currentColumn(), 0));
+ updateEditor();
+ ui.treeWidget->editItem(newItem, ui.treeWidget->currentColumn());
+}
+
+void TreeWidgetEditor::on_newSubItemButton_clicked()
+{
+ QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
+ if (!curItem)
+ return;
+
+ ui.treeWidget->blockSignals(true);
+ QTreeWidgetItem *newItem = new QTreeWidgetItem(curItem);
+ const QString newItemText = tr("New Subitem");
+ newItem->setText(0, newItemText);
+ newItem->setData(0, Qt::DisplayPropertyRole, QVariant::fromValue(PropertySheetStringValue(newItemText)));
+ newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
+ ui.treeWidget->blockSignals(false);
+
+ ui.treeWidget->setCurrentItem(newItem, ui.treeWidget->currentColumn());
+ updateEditor();
+ ui.treeWidget->editItem(newItem, ui.treeWidget->currentColumn());
+}
+
+void TreeWidgetEditor::on_deleteItemButton_clicked()
+{
+ QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
+ if (!curItem)
+ return;
+
+ QTreeWidgetItem *nextCurrent = 0;
+ if (curItem->parent()) {
+ int idx = curItem->parent()->indexOfChild(curItem);
+ if (idx == curItem->parent()->childCount() - 1)
+ idx--;
+ else
+ idx++;
+ if (idx < 0)
+ nextCurrent = curItem->parent();
+ else
+ nextCurrent = curItem->parent()->child(idx);
+ } else {
+ int idx = ui.treeWidget->indexOfTopLevelItem(curItem);
+ if (idx == ui.treeWidget->topLevelItemCount() - 1)
+ idx--;
+ else
+ idx++;
+ if (idx >= 0)
+ nextCurrent = ui.treeWidget->topLevelItem(idx);
+ }
+ closeEditors();
+ ui.treeWidget->blockSignals(true);
+ delete curItem;
+ ui.treeWidget->blockSignals(false);
+
+ if (nextCurrent)
+ ui.treeWidget->setCurrentItem(nextCurrent, ui.treeWidget->currentColumn());
+ updateEditor();
+}
+
+void TreeWidgetEditor::on_moveItemUpButton_clicked()
+{
+ QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
+ if (!curItem)
+ return;
+
+ int idx;
+ if (curItem->parent())
+ idx = curItem->parent()->indexOfChild(curItem);
+ else
+ idx = ui.treeWidget->indexOfTopLevelItem(curItem);
+ if (idx == 0)
+ return;
+
+ QTreeWidgetItem *takenItem;
+ ui.treeWidget->blockSignals(true);
+ if (curItem->parent()) {
+ QTreeWidgetItem *parentItem = curItem->parent();
+ takenItem = parentItem->takeChild(idx);
+ parentItem->insertChild(idx - 1, takenItem);
+ } else {
+ takenItem = ui.treeWidget->takeTopLevelItem(idx);
+ ui.treeWidget->insertTopLevelItem(idx - 1, takenItem);
+ }
+ ui.treeWidget->blockSignals(false);
+
+ ui.treeWidget->setCurrentItem(takenItem, ui.treeWidget->currentColumn());
+ updateEditor();
+}
+
+void TreeWidgetEditor::on_moveItemDownButton_clicked()
+{
+ QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
+ if (!curItem)
+ return;
+
+ int idx, idxCount;
+ if (curItem->parent()) {
+ idx = curItem->parent()->indexOfChild(curItem);
+ idxCount = curItem->parent()->childCount();
+ } else {
+ idx = ui.treeWidget->indexOfTopLevelItem(curItem);
+ idxCount = ui.treeWidget->topLevelItemCount();
+ }
+ if (idx == idxCount - 1)
+ return;
+
+ QTreeWidgetItem *takenItem;
+ ui.treeWidget->blockSignals(true);
+ if (curItem->parent()) {
+ QTreeWidgetItem *parentItem = curItem->parent();
+ takenItem = parentItem->takeChild(idx);
+ parentItem->insertChild(idx + 1, takenItem);
+ } else {
+ takenItem = ui.treeWidget->takeTopLevelItem(idx);
+ ui.treeWidget->insertTopLevelItem(idx + 1, takenItem);
+ }
+ ui.treeWidget->blockSignals(false);
+
+ ui.treeWidget->setCurrentItem(takenItem, ui.treeWidget->currentColumn());
+ updateEditor();
+}
+
+void TreeWidgetEditor::on_moveItemLeftButton_clicked()
+{
+ QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
+ if (!curItem)
+ return;
+
+ QTreeWidgetItem *parentItem = curItem->parent();
+ if (!parentItem)
+ return;
+
+ ui.treeWidget->blockSignals(true);
+ QTreeWidgetItem *takenItem = parentItem->takeChild(parentItem->indexOfChild(curItem));
+ if (parentItem->parent()) {
+ int idx = parentItem->parent()->indexOfChild(parentItem);
+ parentItem->parent()->insertChild(idx, takenItem);
+ } else {
+ int idx = ui.treeWidget->indexOfTopLevelItem(parentItem);
+ ui.treeWidget->insertTopLevelItem(idx, takenItem);
+ }
+ ui.treeWidget->blockSignals(false);
+
+ ui.treeWidget->setCurrentItem(takenItem, ui.treeWidget->currentColumn());
+ updateEditor();
+}
+
+void TreeWidgetEditor::on_moveItemRightButton_clicked()
+{
+ QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
+ if (!curItem)
+ return;
+
+ int idx, idxCount;
+ if (curItem->parent()) {
+ idx = curItem->parent()->indexOfChild(curItem);
+ idxCount = curItem->parent()->childCount();
+ } else {
+ idx = ui.treeWidget->indexOfTopLevelItem(curItem);
+ idxCount = ui.treeWidget->topLevelItemCount();
+ }
+ if (idx == idxCount - 1)
+ return;
+
+ QTreeWidgetItem *takenItem;
+ ui.treeWidget->blockSignals(true);
+ if (curItem->parent()) {
+ QTreeWidgetItem *parentItem = curItem->parent()->child(idx + 1);
+ takenItem = curItem->parent()->takeChild(idx);
+ parentItem->insertChild(0, takenItem);
+ } else {
+ QTreeWidgetItem *parentItem = ui.treeWidget->topLevelItem(idx + 1);
+ takenItem = ui.treeWidget->takeTopLevelItem(idx);
+ parentItem->insertChild(0, takenItem);
+ }
+ ui.treeWidget->blockSignals(false);
+
+ ui.treeWidget->setCurrentItem(takenItem, ui.treeWidget->currentColumn());
+ updateEditor();
+}
+
+void TreeWidgetEditor::togglePropertyBrowser()
+{
+ setPropertyBrowserVisible(!m_propertyBrowser->isVisible());
+}
+
+void TreeWidgetEditor::setPropertyBrowserVisible(bool v)
+{
+ ui.showPropertiesButton->setText(v ? tr("Properties &>>") : tr("Properties &<<"));
+ m_propertyBrowser->setVisible(v);
+}
+
+void TreeWidgetEditor::on_treeWidget_currentItemChanged()
+{
+ m_columnEditor->setCurrentIndex(ui.treeWidget->currentColumn());
+ updateEditor();
+}
+
+void TreeWidgetEditor::on_treeWidget_itemChanged(QTreeWidgetItem *item, int column)
+{
+ if (m_updatingBrowser)
+ return;
+
+ PropertySheetStringValue val = qvariant_cast<PropertySheetStringValue>(item->data(column, Qt::DisplayPropertyRole));
+ val.setValue(item->text(column));
+ BoolBlocker block(m_updatingBrowser);
+ item->setData(column, Qt::DisplayPropertyRole, QVariant::fromValue(val));
+
+ updateBrowser();
+}
+
+void TreeWidgetEditor::on_columnEditor_indexChanged(int idx)
+{
+ if (QTreeWidgetItem *item = ui.treeWidget->currentItem())
+ ui.treeWidget->setCurrentItem(item, idx);
+}
+
+void TreeWidgetEditor::on_columnEditor_itemChanged(int idx, int role, const QVariant &v)
+{
+ if (role == Qt::DisplayPropertyRole)
+ ui.treeWidget->headerItem()->setData(idx, Qt::EditRole, qvariant_cast<PropertySheetStringValue>(v).value());
+ ui.treeWidget->headerItem()->setData(idx, role, v);
+}
+
+void TreeWidgetEditor::updateEditor()
+{
+ QTreeWidgetItem *current = ui.treeWidget->currentItem();
+
+ bool itemsEnabled = false;
+ bool currentItemEnabled = false;
+ bool moveItemUpEnabled = false;
+ bool moveItemDownEnabled = false;
+ bool moveItemRightEnabled = false;
+ bool moveItemLeftEnabled = false;
+
+ if (ui.treeWidget->columnCount() > 0) {
+ itemsEnabled = true;
+ if (current) {
+ int idx;
+ int idxCount;
+ currentItemEnabled = true;
+ if (current->parent()) {
+ moveItemLeftEnabled = true;
+ idx = current->parent()->indexOfChild(current);
+ idxCount = current->parent()->childCount();
+ } else {
+ idx = ui.treeWidget->indexOfTopLevelItem(current);
+ idxCount = ui.treeWidget->topLevelItemCount();
+ }
+ if (idx > 0)
+ moveItemUpEnabled = true;
+ if (idx < idxCount - 1) {
+ moveItemDownEnabled = true;
+ moveItemRightEnabled = true;
+ }
+ }
+ }
+ ui.tabWidget->setTabEnabled(1, itemsEnabled);
+ ui.newSubItemButton->setEnabled(currentItemEnabled);
+ ui.deleteItemButton->setEnabled(currentItemEnabled);
+
+ ui.moveItemUpButton->setEnabled(moveItemUpEnabled);
+ ui.moveItemDownButton->setEnabled(moveItemDownEnabled);
+ ui.moveItemRightButton->setEnabled(moveItemRightEnabled);
+ ui.moveItemLeftButton->setEnabled(moveItemLeftEnabled);
+
+ if (current)
+ updateBrowser();
+ else
+ m_propertyBrowser->clear();
+}
+
+void TreeWidgetEditor::moveColumnItems(const PropertyDefinition *propList,
+ QTreeWidgetItem *item, int fromColumn, int toColumn, int step)
+{
+ BoolBlocker block(m_updatingBrowser);
+
+ QList<QVariant> saveCol;
+ for (int j = 0; propList[j].name; j++)
+ saveCol.append(item->data(toColumn, propList[j].role));
+ QVariant editVariant = item->data(toColumn, Qt::EditRole);
+ QVariant toolTipVariant = item->data(toColumn, Qt::ToolTipRole);
+ QVariant statusTipVariant = item->data(toColumn, Qt::StatusTipRole);
+ QVariant whatsThisVariant = item->data(toColumn, Qt::WhatsThisRole);
+ QVariant decorationVariant = item->data(toColumn, Qt::DecorationRole);
+ for (int i = toColumn; i != fromColumn; i += step) {
+ for (int j = 0; propList[j].name; j++)
+ item->setData(i, propList[j].role, item->data(i + step, propList[j].role));
+ item->setData(i, Qt::EditRole, item->data(i + step, Qt::EditRole));
+ item->setData(i, Qt::ToolTipRole, item->data(i + step, Qt::ToolTipRole));
+ item->setData(i, Qt::StatusTipRole, item->data(i + step, Qt::StatusTipRole));
+ item->setData(i, Qt::WhatsThisRole, item->data(i + step, Qt::WhatsThisRole));
+ item->setData(i, Qt::DecorationRole, item->data(i + step, Qt::DecorationRole));
+ }
+ for (int j = 0; propList[j].name; j++)
+ item->setData(fromColumn, propList[j].role, saveCol[j]);
+ item->setData(fromColumn, Qt::EditRole, editVariant);
+ item->setData(fromColumn, Qt::ToolTipRole, toolTipVariant);
+ item->setData(fromColumn, Qt::StatusTipRole, statusTipVariant);
+ item->setData(fromColumn, Qt::WhatsThisRole, whatsThisVariant);
+ item->setData(fromColumn, Qt::DecorationRole, decorationVariant);
+}
+
+void TreeWidgetEditor::moveColumns(int fromColumn, int toColumn, int step)
+{
+ ui.treeWidget->blockSignals(true);
+
+ moveColumnItems(treeHeaderPropList, ui.treeWidget->headerItem(), fromColumn, toColumn, step);
+
+ QQueue<QTreeWidgetItem *> pendingQueue;
+ for (int i = 0; i < ui.treeWidget->topLevelItemCount(); i++)
+ pendingQueue.enqueue(ui.treeWidget->topLevelItem(i));
+
+ while (!pendingQueue.isEmpty()) {
+ QTreeWidgetItem *item = pendingQueue.dequeue();
+ for (int i = 0; i < item->childCount(); i++)
+ pendingQueue.enqueue(item->child(i));
+
+ moveColumnItems(treeItemColumnPropList, item, fromColumn, toColumn, step);
+ }
+
+ ui.treeWidget->blockSignals(false);
+}
+
+void TreeWidgetEditor::moveColumnsLeft(int fromColumn, int toColumn)
+{
+ if (fromColumn >= toColumn)
+ return;
+
+ moveColumns(fromColumn, toColumn, -1);
+}
+
+void TreeWidgetEditor::moveColumnsRight(int fromColumn, int toColumn)
+{
+ if (fromColumn >= toColumn)
+ return;
+
+ moveColumns(toColumn, fromColumn, 1);
+}
+
+void TreeWidgetEditor::on_columnEditor_itemInserted(int idx)
+{
+ int columnCount = ui.treeWidget->columnCount();
+ ui.treeWidget->setColumnCount(columnCount + 1);
+ ui.treeWidget->headerItem()->setText(columnCount, m_columnEditor->newItemText());
+ moveColumnsLeft(idx, columnCount);
+
+ updateEditor();
+}
+
+void TreeWidgetEditor::on_columnEditor_itemDeleted(int idx)
+{
+ closeEditors();
+
+ int columnCount = ui.treeWidget->columnCount() - 1;
+ if (!columnCount)
+ ui.treeWidget->clear();
+ else
+ moveColumnsRight(idx, columnCount);
+ ui.treeWidget->setColumnCount(columnCount);
+
+ updateEditor();
+}
+
+void TreeWidgetEditor::on_columnEditor_itemMovedUp(int idx)
+{
+ moveColumnsRight(idx - 1, idx);
+
+ ui.treeWidget->setCurrentItem(ui.treeWidget->currentItem(), idx - 1);
+ updateEditor();
+}
+
+void TreeWidgetEditor::on_columnEditor_itemMovedDown(int idx)
+{
+ moveColumnsLeft(idx, idx + 1);
+
+ ui.treeWidget->setCurrentItem(ui.treeWidget->currentItem(), idx + 1);
+ updateEditor();
+}
+
+void TreeWidgetEditor::closeEditors()
+{
+ if (QTreeWidgetItem *cur = ui.treeWidget->currentItem() ) {
+ const int numCols = cur->columnCount ();
+ for (int i = 0; i < numCols; i++)
+ ui.treeWidget->closePersistentEditor (cur, i);
+ }
+}
+
+void TreeWidgetEditor::cacheReloaded()
+{
+ reloadIconResources(iconCache(), ui.treeWidget);
+}
+
+TreeWidgetEditorDialog::TreeWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent) :
+ QDialog(parent), m_editor(form, this)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+}
+
+TreeWidgetContents TreeWidgetEditorDialog::fillContentsFromTreeWidget(QTreeWidget *treeWidget)
+{
+ return m_editor.fillContentsFromTreeWidget(treeWidget);
+}
+
+TreeWidgetContents TreeWidgetEditorDialog::contents() const
+{
+ return m_editor.contents();
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/taskmenu/treewidgeteditor.h b/src/designer/src/components/taskmenu/treewidgeteditor.h
new file mode 100644
index 000000000..f502bf3e4
--- /dev/null
+++ b/src/designer/src/components/taskmenu/treewidgeteditor.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TREEWIDGETEDITOR_H
+#define TREEWIDGETEDITOR_H
+
+#include "ui_treewidgeteditor.h"
+
+#include "listwidgeteditor.h"
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QTreeWidget;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class FormWindowBase;
+class PropertySheetIconValue;
+
+class TreeWidgetEditor: public AbstractItemEditor
+{
+ Q_OBJECT
+public:
+ explicit TreeWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog);
+
+ TreeWidgetContents fillContentsFromTreeWidget(QTreeWidget *treeWidget);
+ TreeWidgetContents contents() const;
+
+private slots:
+ void on_newItemButton_clicked();
+ void on_newSubItemButton_clicked();
+ void on_deleteItemButton_clicked();
+ void on_moveItemUpButton_clicked();
+ void on_moveItemDownButton_clicked();
+ void on_moveItemRightButton_clicked();
+ void on_moveItemLeftButton_clicked();
+
+ void on_treeWidget_currentItemChanged();
+ void on_treeWidget_itemChanged(QTreeWidgetItem *item, int column);
+
+ void on_columnEditor_indexChanged(int idx);
+ void on_columnEditor_itemChanged(int idx, int role, const QVariant &v);
+
+ void on_columnEditor_itemInserted(int idx);
+ void on_columnEditor_itemDeleted(int idx);
+ void on_columnEditor_itemMovedUp(int idx);
+ void on_columnEditor_itemMovedDown(int idx);
+
+ void togglePropertyBrowser();
+ void cacheReloaded();
+
+protected:
+ virtual void setItemData(int role, const QVariant &v);
+ virtual QVariant getItemData(int role) const;
+
+private:
+ void setPropertyBrowserVisible(bool v);
+ QtVariantProperty *setupPropertyGroup(const QString &title, PropertyDefinition *propDefs);
+ void updateEditor();
+ void moveColumnItems(const PropertyDefinition *propList, QTreeWidgetItem *item, int fromColumn, int toColumn, int step);
+ void moveColumns(int fromColumn, int toColumn, int step);
+ void moveColumnsLeft(int fromColumn, int toColumn);
+ void moveColumnsRight(int fromColumn, int toColumn);
+ void closeEditors();
+
+ Ui::TreeWidgetEditor ui;
+ ItemListEditor *m_columnEditor;
+ bool m_updatingBrowser;
+};
+
+class TreeWidgetEditorDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit TreeWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent);
+
+ TreeWidgetContents fillContentsFromTreeWidget(QTreeWidget *treeWidget);
+ TreeWidgetContents contents() const;
+
+private:
+ TreeWidgetEditor m_editor;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // TREEWIDGETEDITOR_H
diff --git a/src/designer/src/components/taskmenu/treewidgeteditor.ui b/src/designer/src/components/taskmenu/treewidgeteditor.ui
new file mode 100644
index 000000000..7a71d4404
--- /dev/null
+++ b/src/designer/src/components/taskmenu/treewidgeteditor.ui
@@ -0,0 +1,257 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::TreeWidgetEditor</class>
+ <widget class="QDialog" name="qdesigner_internal::TreeWidgetEditor" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>700</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Edit Tree Widget</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="itemsTab" >
+ <attribute name="title" >
+ <string>&amp;Items</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QWidget" native="1" name="widget" >
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="treeWidget" >
+ <property name="focusPolicy" >
+ <enum>Qt::WheelFocus</enum>
+ </property>
+ <property name="toolTip" >
+ <string>Tree Items</string>
+ </property>
+ <column>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="buttonsLayout" >
+ <item>
+ <widget class="QToolButton" name="newItemButton" >
+ <property name="toolTip" >
+ <string>New Item</string>
+ </property>
+ <property name="text" >
+ <string>&amp;New</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newSubItemButton" >
+ <property name="toolTip" >
+ <string>New Subitem</string>
+ </property>
+ <property name="text" >
+ <string>New &amp;Subitem</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteItemButton" >
+ <property name="toolTip" >
+ <string>Delete Item</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>28</width>
+ <height>23</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="moveItemLeftButton" >
+ <property name="toolTip" >
+ <string>Move Item Left (before Parent Item)</string>
+ </property>
+ <property name="text" >
+ <string>L</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="moveItemRightButton" >
+ <property name="toolTip" >
+ <string>Move Item Right (as a First Subitem of the Next Sibling Item)</string>
+ </property>
+ <property name="text" >
+ <string>R</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="moveItemUpButton" >
+ <property name="toolTip" >
+ <string>Move Item Up</string>
+ </property>
+ <property name="text" >
+ <string>U</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="moveItemDownButton" >
+ <property name="toolTip" >
+ <string>Move Item Down</string>
+ </property>
+ <property name="text" >
+ <string>D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="showPropertiesButton" >
+ <property name="text" >
+ <string>Properties &amp;>></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>qdesigner_internal::TreeWidgetEditor</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>440</x>
+ <y>335</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>373</x>
+ <y>362</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>qdesigner_internal::TreeWidgetEditor</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>556</x>
+ <y>335</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>562</x>
+ <y>362</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/components/widgetbox/widgetbox.cpp b/src/designer/src/components/widgetbox/widgetbox.cpp
new file mode 100644
index 000000000..c9b0d040a
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetbox.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "widgetbox.h"
+#include "widgetboxtreewidget.h"
+#include "widgetbox_dnditem.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+#include <iconloader_p.h>
+#include <qdesigner_utils_p.h>
+#include <filterwidget_p.h>
+
+#include <QtGui/QDropEvent>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QApplication>
+#include <QtGui/QToolBar>
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+WidgetBox::WidgetBox(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags)
+ : QDesignerWidgetBox(parent, flags),
+ m_core(core),
+ m_view(new WidgetBoxTreeWidget(m_core))
+{
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+
+ // Prevent the filter from grabbing focus since Our view has Qt::NoFocus
+ FilterWidget *filterWidget = new FilterWidget(0, FilterWidget::LayoutAlignNone);
+ filterWidget->setRefuseFocus(true);
+ connect(filterWidget, SIGNAL(filterChanged(QString)), m_view, SLOT(filter(QString)));
+
+ QToolBar *toolBar = new QToolBar(this);
+ toolBar->addWidget(filterWidget);
+ l->addWidget(toolBar);
+
+ // View
+ connect(m_view, SIGNAL(pressed(QString,QString,QPoint)),
+ this, SLOT(handleMousePress(QString,QString,QPoint)));
+ l->addWidget(m_view);
+
+ setAcceptDrops (true);
+}
+
+WidgetBox::~WidgetBox()
+{
+}
+
+QDesignerFormEditorInterface *WidgetBox::core() const
+{
+ return m_core;
+}
+
+void WidgetBox::handleMousePress(const QString &name, const QString &xml, const QPoint &global_mouse_pos)
+{
+ if (QApplication::mouseButtons() != Qt::LeftButton)
+ return;
+
+ DomUI *ui = xmlToUi(name, xml, true);
+ if (ui == 0)
+ return;
+ QList<QDesignerDnDItemInterface*> item_list;
+ item_list.append(new WidgetBoxDnDItem(core(), ui, global_mouse_pos));
+ m_core->formWindowManager()->dragItems(item_list);
+}
+
+int WidgetBox::categoryCount() const
+{
+ return m_view->categoryCount();
+}
+
+QDesignerWidgetBoxInterface::Category WidgetBox::category(int cat_idx) const
+{
+ return m_view->category(cat_idx);
+}
+
+void WidgetBox::addCategory(const Category &cat)
+{
+ m_view->addCategory(cat);
+}
+
+void WidgetBox::removeCategory(int cat_idx)
+{
+ m_view->removeCategory(cat_idx);
+}
+
+int WidgetBox::widgetCount(int cat_idx) const
+{
+ return m_view->widgetCount(cat_idx);
+}
+
+QDesignerWidgetBoxInterface::Widget WidgetBox::widget(int cat_idx, int wgt_idx) const
+{
+ return m_view->widget(cat_idx, wgt_idx);
+}
+
+void WidgetBox::addWidget(int cat_idx, const Widget &wgt)
+{
+ m_view->addWidget(cat_idx, wgt);
+}
+
+void WidgetBox::removeWidget(int cat_idx, int wgt_idx)
+{
+ m_view->removeWidget(cat_idx, wgt_idx);
+}
+
+void WidgetBox::dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, const QPoint&)
+{
+ m_view->dropWidgets(item_list);
+}
+
+void WidgetBox::setFileName(const QString &file_name)
+{
+ m_view->setFileName(file_name);
+}
+
+QString WidgetBox::fileName() const
+{
+ return m_view->fileName();
+}
+
+bool WidgetBox::load()
+{
+ return m_view->load(loadMode());
+}
+
+bool WidgetBox::loadContents(const QString &contents)
+{
+ return m_view->loadContents(contents);
+}
+
+bool WidgetBox::save()
+{
+ return m_view->save();
+}
+
+static const QDesignerMimeData *checkDragEvent(QDropEvent * event,
+ bool acceptEventsFromWidgetBox)
+{
+ const QDesignerMimeData *mimeData = qobject_cast<const QDesignerMimeData *>(event->mimeData());
+ if (!mimeData) {
+ event->ignore();
+ return 0;
+ }
+ // If desired, ignore a widget box drag and drop, where widget==0.
+ if (!acceptEventsFromWidgetBox) {
+ const bool fromWidgetBox = !mimeData->items().first()->widget();
+ if (fromWidgetBox) {
+ event->ignore();
+ return 0;
+ }
+ }
+
+ mimeData->acceptEvent(event);
+ return mimeData;
+}
+
+void WidgetBox::dragEnterEvent (QDragEnterEvent * event)
+{
+ // We accept event originating from the widget box also here,
+ // because otherwise Windows will not show the DnD pixmap.
+ checkDragEvent(event, true);
+}
+
+void WidgetBox::dragMoveEvent(QDragMoveEvent * event)
+{
+ checkDragEvent(event, true);
+}
+
+void WidgetBox::dropEvent(QDropEvent * event)
+{
+ const QDesignerMimeData *mimeData = checkDragEvent(event, false);
+ if (!mimeData)
+ return;
+
+ dropWidgets(mimeData->items(), event->pos());
+ QDesignerMimeData::removeMovedWidgetsFromSourceForm(mimeData->items());
+}
+
+QIcon WidgetBox::iconForWidget(const QString &className, const QString &category) const
+{
+ Widget widgetData;
+ if (!findWidget(this, className, category, &widgetData))
+ return QIcon();
+ return m_view->iconForWidget(widgetData.iconName());
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/widgetbox/widgetbox.h b/src/designer/src/components/widgetbox/widgetbox.h
new file mode 100644
index 000000000..a19c756aa
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetbox.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WIDGETBOX_H
+#define WIDGETBOX_H
+
+#include "widgetbox_global.h"
+#include <qdesigner_widgetbox_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class WidgetBoxTreeWidget;
+
+class QT_WIDGETBOX_EXPORT WidgetBox : public QDesignerWidgetBox
+{
+ Q_OBJECT
+public:
+ explicit WidgetBox(QDesignerFormEditorInterface *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ virtual ~WidgetBox();
+
+ QDesignerFormEditorInterface *core() const;
+
+ virtual int categoryCount() const;
+ virtual Category category(int cat_idx) const;
+ virtual void addCategory(const Category &cat);
+ virtual void removeCategory(int cat_idx);
+
+ virtual int widgetCount(int cat_idx) const;
+ virtual Widget widget(int cat_idx, int wgt_idx) const;
+ virtual void addWidget(int cat_idx, const Widget &wgt);
+ virtual void removeWidget(int cat_idx, int wgt_idx);
+
+ void dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, const QPoint &global_mouse_pos);
+
+ virtual void setFileName(const QString &file_name);
+ virtual QString fileName() const;
+ virtual bool load();
+ virtual bool save();
+
+ virtual bool loadContents(const QString &contents);
+ virtual QIcon iconForWidget(const QString &className, const QString &category = QString()) const;
+
+protected:
+ virtual void dragEnterEvent (QDragEnterEvent * event);
+ virtual void dragMoveEvent(QDragMoveEvent * event);
+ virtual void dropEvent (QDropEvent * event);
+
+private slots:
+ void handleMousePress(const QString &name, const QString &xml, const QPoint &global_mouse_pos);
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ WidgetBoxTreeWidget *m_view;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // WIDGETBOX_H
diff --git a/src/designer/src/components/widgetbox/widgetbox.pri b/src/designer/src/components/widgetbox/widgetbox.pri
new file mode 100644
index 000000000..dd8ad002e
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetbox.pri
@@ -0,0 +1,14 @@
+
+INCLUDEPATH += $$PWD
+
+SOURCES += $$PWD/widgetboxcategorylistview.cpp \
+ $$PWD/widgetboxtreewidget.cpp \
+ $$PWD/widgetbox.cpp \
+ $$PWD/widgetbox_dnditem.cpp
+HEADERS += $$PWD/widgetboxcategorylistview.h \
+ $$PWD/widgetboxtreewidget.h \
+ $$PWD/widgetbox.h \
+ $$PWD/widgetbox_global.h \
+ $$PWD/widgetbox_dnditem.h
+
+RESOURCES += $$PWD/widgetbox.qrc
diff --git a/src/designer/src/components/widgetbox/widgetbox.qrc b/src/designer/src/components/widgetbox/widgetbox.qrc
new file mode 100644
index 000000000..7ecf78c85
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetbox.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/trolltech/widgetbox">
+ <file>widgetbox.xml</file>
+ </qresource>
+</RCC>
diff --git a/src/designer/src/components/widgetbox/widgetbox.xml b/src/designer/src/components/widgetbox/widgetbox.xml
new file mode 100644
index 000000000..4286e0d6c
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetbox.xml
@@ -0,0 +1,932 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************-->
+<widgetbox version="4.2">
+ <category name="Layouts">
+
+ <categoryentry name="Vertical Layout" icon="win/editvlayout.png">
+ <ui>
+ <widget class="QWidget">
+ <property name="objectName">
+ <string notr="true">verticalLayoutWidget</string>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>160</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ </layout>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Horizontal Layout" icon="win/edithlayout.png">
+ <ui>
+ <widget class="QWidget">
+ <property name="objectName">
+ <string notr="true">horizontalLayoutWidget</string>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>160</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ </layout>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Grid Layout" icon="win/editgrid.png">
+ <ui>
+ <widget class="QWidget">
+ <property name="objectName">
+ <string notr="true">gridLayoutWidget</string>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>160</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ </layout>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Form Layout" icon="win/editform.png">
+ <ui>
+ <widget class="QWidget">
+ <property name="objectName">
+ <string notr="true">formLayoutWidget</string>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>160</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ </layout>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ </category>
+
+ <category name="Spacers">
+
+ <categoryentry name="Horizontal Spacer" icon="widgets/spacer.png">
+ <ui>
+ <widget class="Spacer">
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="objectName">
+ <string notr="true">horizontalSpacer</string>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Vertical Spacer" icon="widgets/vspacer.png">
+ <ui>
+ <widget class="Spacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="objectName">
+ <string notr="true">verticalSpacer</string>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ </category>
+
+ <category name="Buttons">
+
+ <categoryentry name="Push Button" icon="widgets/pushbutton.png">
+ <ui>
+ <widget class="QPushButton">
+ <property name="text" >
+ <string>PushButton</string>
+ </property>
+ <property name="objectName">
+ <string notr="true">pushButton</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Tool Button" icon="widgets/toolbutton.png">
+ <ui>
+ <widget class="QToolButton">
+ <property name="objectName">
+ <string notr="true">toolButton</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Radio Button" icon="widgets/radiobutton.png">
+ <ui>
+ <widget class="QRadioButton">
+ <property name="text" >
+ <string>RadioButton</string>
+ </property>
+ <property name="objectName">
+ <string notr="true">radioButton</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Check Box" icon="widgets/checkbox.png">
+ <ui>
+ <widget class="QCheckBox">
+ <property name="text" >
+ <string>CheckBox</string>
+ </property>
+ <property name="objectName">
+ <string notr="true">checkBox</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Command Link Button" icon="widgets/commandlinkbutton.png">
+ <ui>
+ <widget class="QCommandLinkButton">
+ <property name="text" >
+ <string>CommandLinkButton</string>
+ </property>
+ <property name="objectName">
+ <string notr="true">commandLinkButton</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Button Box" icon="widgets/dialogbuttonbox.png">
+ <ui>
+ <widget class="QDialogButtonBox">
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Ok|QDialogButtonBox::Cancel</set>
+ </property>
+ <property name="objectName">
+ <string notr="true">buttonBox</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ </category>
+
+ <category name="Item Views (Model-Based)">
+
+ <categoryentry name="List View" icon="widgets/listbox.png">
+ <ui>
+ <widget class="QListView">
+ <property name="objectName">
+ <string notr="true">listView</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Tree View" icon="widgets/listview.png">
+ <ui>
+ <widget class="QTreeView">
+ <property name="objectName">
+ <string notr="true">treeView</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Table View" icon="widgets/table.png">
+ <ui>
+ <widget class="QTableView">
+ <property name="objectName">
+ <string notr="true">tableView</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Column View" icon="widgets/columnview.png">
+ <ui>
+ <widget class="QColumnView">
+ <property name="objectName">
+ <string notr="true">columnView</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ </category>
+
+ <category name="Item Widgets (Item-Based)">
+ <categoryentry name="List Widget" icon="widgets/listbox.png">
+ <ui>
+ <widget class="QListWidget">
+ <property name="objectName">
+ <string notr="true">listWidget</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Tree Widget" icon="widgets/listview.png">
+ <ui>
+ <widget class="QTreeWidget">
+ <property name="objectName">
+ <string notr="true">treeWidget</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Table Widget" icon="widgets/table.png">
+ <ui>
+ <widget class="QTableWidget">
+ <property name="objectName">
+ <string notr="true">tableWidget</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ </category>
+
+ <category name="Containers">
+
+ <categoryentry name="Group Box" icon="widgets/groupbox.png">
+ <ui>
+ <widget class="QGroupBox">
+ <property name="title" >
+ <string>GroupBox</string>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>120</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">groupBox</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry icon="widgets/scrollarea.png" type="default" name="Scroll Area">
+ <ui>
+ <widget class="QScrollArea">
+ <property name="objectName" >
+ <string notr="true" >scrollArea</string>
+ </property>
+ <property name="widgetResizable" >
+ <bool>true</bool>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>120</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ </widget>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Tool Box" icon="widgets/toolbox.png">
+ <ui>
+ <widget class="QToolBox">
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <property name="objectName">
+ <string notr="true">toolBox</string>
+ </property>
+ <widget class="QWidget" name="page" >
+ <attribute name="label">
+ <string>Page 1</string>
+ </attribute>
+ </widget>
+ <widget class="QWidget" name="page" >
+ <attribute name="label">
+ <string>Page 2</string>
+ </attribute>
+ </widget>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Tab Widget" icon="widgets/tabwidget.png">
+ <ui>
+ <widget class="QTabWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>120</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">tabWidget</string>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ </widget>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 2</string>
+ </attribute>
+ </widget>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Stacked Widget" icon="widgets/widgetstack.png">
+ <ui>
+ <widget class="QStackedWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>120</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">stackedWidget</string>
+ </property>
+ <widget class="QWidget" name="page" />
+ <widget class="QWidget" name="page" />
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Frame" icon="widgets/frame.png">
+ <ui>
+ <widget class="QFrame">
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>120</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="objectName">
+ <string notr="true">frame</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Widget" icon="widgets/widget.png">
+ <ui>
+ <widget class="QWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>120</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">widget</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="MdiArea" icon="widgets/mdiarea.png">
+ <ui>
+ <widget class="QMdiArea">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>200</width>
+ <height>160</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">mdiArea</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Dock Widget" icon="widgets/dockwidget.png">
+ <ui>
+ <widget class="QDockWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>120</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">dockWidget</string>
+ </property>
+ <widget class="QWidget" name="dockWidgetContents" />
+ </widget>
+ </ui>
+ </categoryentry>
+
+ </category>
+
+ <category name="Input Widgets">
+
+ <categoryentry name="Combo Box" icon="widgets/combobox.png">
+ <ui>
+ <widget class="QComboBox">
+ <property name="geometry" >
+ <rect>
+ <x>119</x>
+ <y>28</y>
+ <width>41</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">comboBox</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Font Combo Box" icon="widgets/fontcombobox.png">
+ <ui>
+ <widget class="QFontComboBox">
+ <property name="geometry" >
+ <rect>
+ <x>119</x>
+ <y>28</y>
+ <width>41</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">fontComboBox</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Line Edit" icon="widgets/lineedit.png">
+ <ui>
+ <widget class="QLineEdit">
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>1</y>
+ <width>113</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">lineEdit</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Text Edit" icon="widgets/textedit.png">
+ <ui>
+ <widget class="QTextEdit">
+ <property name="objectName">
+ <string notr="true">textEdit</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>104</width>
+ <height>64</height>
+ </rect>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Plain Text Edit" icon="widgets/plaintextedit.png">
+ <ui>
+ <widget class="QPlainTextEdit">
+ <property name="objectName">
+ <string notr="true">plainTextEdit</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>104</width>
+ <height>64</height>
+ </rect>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Spin Box" icon="widgets/spinbox.png">
+ <ui>
+ <widget class="QSpinBox">
+ <property name="geometry" >
+ <rect>
+ <x>119</x>
+ <y>0</y>
+ <width>42</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">spinBox</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Double Spin Box" icon="widgets/doublespinbox.png">
+ <ui>
+ <widget class="QDoubleSpinBox">
+ <property name="geometry" >
+ <rect>
+ <x>119</x>
+ <y>0</y>
+ <width>62</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">doubleSpinBox</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Time Edit" icon="widgets/timeedit.png">
+ <ui>
+ <widget class="QTimeEdit">
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>28</y>
+ <width>118</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">timeEdit</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Date Edit" icon="widgets/dateedit.png">
+ <ui>
+ <widget class="QDateEdit">
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>28</y>
+ <width>110</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">dateEdit</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Date/Time Edit" icon="widgets/datetimeedit.png">
+ <ui>
+ <widget class="QDateTimeEdit">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>28</y>
+ <width>194</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">dateTimeEdit</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Dial" icon="widgets/dial.png">
+ <ui>
+ <widget class="QDial">
+ <property name="geometry" >
+ <rect>
+ <x>110</x>
+ <y>0</y>
+ <width>50</width>
+ <height>64</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">dial</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Horizontal Scroll Bar" icon="widgets/hscrollbar.png">
+ <ui>
+ <widget class="QScrollBar">
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>126</y>
+ <width>160</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">horizontalScrollBar</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Vertical Scroll Bar" icon="widgets/vscrollbar.png">
+ <ui>
+ <widget class="QScrollBar">
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>126</y>
+ <width>16</width>
+ <height>160</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">verticalScrollBar</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Horizontal Slider" icon="widgets/hslider.png">
+ <ui>
+ <widget class="QSlider">
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>126</y>
+ <width>160</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">horizontalSlider</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Vertical Slider" icon="widgets/vslider.png">
+ <ui>
+ <widget class="QSlider">
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>126</y>
+ <width>16</width>
+ <height>160</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">verticalSlider</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ </category>
+
+
+ <category name="Display Widgets">
+
+ <categoryentry name="Label" icon="widgets/label.png">
+ <ui>
+ <widget class="QLabel">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ <property name="objectName">
+ <string notr="true">label</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Text Browser" icon="widgets/textedit.png">
+ <ui>
+ <widget class="QTextBrowser">
+ <property name="objectName">
+ <string notr="true">textBrowser</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Graphics View" icon="widgets/graphicsview.png">
+ <ui>
+ <widget class="QGraphicsView">
+ <property name="objectName">
+ <string notr="true">graphicsView</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Calendar" icon="widgets/calendarwidget.png">
+ <ui>
+ <widget class="QCalendarWidget">
+ <property name="objectName">
+ <string notr="true">calendarWidget</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="LCD Number" icon="widgets/lcdnumber.png">
+ <ui>
+ <widget class="QLCDNumber">
+ <property name="objectName">
+ <string notr="true">lcdNumber</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Progress Bar" icon="widgets/progress.png">
+ <ui>
+ <widget class="QProgressBar">
+ <property name="value" >
+ <number>24</number>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>9</x>
+ <y>38</y>
+ <width>118</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="objectName">
+ <string notr="true">progressBar</string>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Horizontal Line" icon="widgets/line.png">
+ <ui>
+ <widget class="Line">
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="objectName">
+ <string notr="true">line</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>9</x>
+ <y>67</y>
+ <width>118</width>
+ <height>3</height>
+ </rect>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ <categoryentry name="Vertical Line" icon="widgets/vline.png">
+ <ui>
+ <widget class="Line">
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="objectName">
+ <string notr="true">line</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>133</x>
+ <y>9</y>
+ <width>3</width>
+ <height>61</height>
+ </rect>
+ </property>
+ </widget>
+ </ui>
+ </categoryentry>
+
+ </category>
+</widgetbox>
diff --git a/src/designer/src/components/widgetbox/widgetbox_dnditem.cpp b/src/designer/src/components/widgetbox/widgetbox_dnditem.cpp
new file mode 100644
index 000000000..c122c8411
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetbox_dnditem.cpp
@@ -0,0 +1,225 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "widgetbox_dnditem.h"
+#include "ui4_p.h"
+
+#include <widgetfactory_p.h>
+#include <spacer_widget_p.h>
+#include <qdesigner_formbuilder_p.h>
+#include <qtresourcemodel_p.h>
+#include <formscriptrunner_p.h>
+#include <formwindowbase_p.h>
+#include <qdesigner_utils_p.h>
+#include <qdesigner_dockwidget_p.h>
+#include <qsimpleresource_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+#include <QtGui/QStyle>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+/*******************************************************************************
+** WidgetBoxResource
+*/
+
+static inline DeviceProfile currentDeviceProfile(const QDesignerFormEditorInterface *core)
+{
+ if (QDesignerFormWindowInterface *cfw = core->formWindowManager()->activeFormWindow())
+ if (const FormWindowBase *fwb = qobject_cast<const FormWindowBase *>(cfw))
+ return fwb->deviceProfile();
+ return DeviceProfile();
+}
+
+class WidgetBoxResource : public QDesignerFormBuilder
+{
+public:
+ WidgetBoxResource(QDesignerFormEditorInterface *core);
+
+ // protected->public
+ QWidget *createUI(DomUI *ui, QWidget *parents) { return QDesignerFormBuilder::create(ui, parents); }
+
+protected:
+
+ virtual QWidget *create(DomWidget *ui_widget, QWidget *parents);
+ virtual QWidget *createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name);
+ virtual void createCustomWidgets(DomCustomWidgets *);
+};
+
+WidgetBoxResource::WidgetBoxResource(QDesignerFormEditorInterface *core) :
+ QDesignerFormBuilder(core, DisableScripts, currentDeviceProfile(core))
+{
+}
+
+
+QWidget *WidgetBoxResource::createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name)
+{
+ if (widgetName == QLatin1String("Spacer")) {
+ Spacer *spacer = new Spacer(parentWidget);
+ spacer->setObjectName(name);
+ return spacer;
+ }
+
+ return QDesignerFormBuilder::createWidget(widgetName, parentWidget, name);
+}
+
+QWidget *WidgetBoxResource::create(DomWidget *ui_widget, QWidget *parent)
+{
+ QWidget *result = QDesignerFormBuilder::create(ui_widget, parent);
+ // It is possible to have a syntax error or something in custom
+ // widget XML, so, try to recover here by creating an artificial
+ // top level + widget.
+ if (!result) {
+ const QString msg = QApplication::translate("qdesigner_internal::WidgetBox", "Warning: Widget creation failed in the widget box. This could be caused by invalid custom widget XML.");
+ qdesigner_internal::designerWarning(msg);
+ result = new QWidget(parent);
+ new QWidget(result);
+ }
+ result->setFocusPolicy(Qt::NoFocus);
+ result->setObjectName(ui_widget->attributeName());
+ return result;
+}
+
+void WidgetBoxResource::createCustomWidgets(DomCustomWidgets *dc)
+{
+ // Make a promotion entry in case someone has a promoted widget
+ // in the scratchpad.
+ QSimpleResource::handleDomCustomWidgets(core(), dc);
+
+}
+
+/*******************************************************************************
+** WidgetBoxResource
+*/
+
+static QSize geometryProp(const DomWidget *dw)
+{
+ const QList<DomProperty*> prop_list = dw->elementProperty();
+ const QString geometry = QLatin1String("geometry");
+ foreach (DomProperty *prop, prop_list) {
+ if (prop->attributeName() != geometry)
+ continue;
+ DomRect *dr = prop->elementRect();
+ if (dr == 0)
+ continue;
+ return QSize(dr->elementWidth(), dr->elementHeight());
+ }
+ return QSize();
+}
+
+static QSize domWidgetSize(const DomWidget *dw)
+{
+ QSize size = geometryProp(dw);
+ if (size.isValid())
+ return size;
+
+ foreach (const DomWidget *child, dw->elementWidget()) {
+ size = geometryProp(child);
+ if (size.isValid())
+ return size;
+ }
+
+ foreach (const DomLayout *dl, dw->elementLayout()) {
+ foreach (DomLayoutItem *item, dl->elementItem()) {
+ const DomWidget *child = item->elementWidget();
+ if (child == 0)
+ continue;
+ size = geometryProp(child);
+ if (size.isValid())
+ return size;
+ }
+ }
+
+ return QSize();
+}
+
+static QWidget *decorationFromDomWidget(DomUI *dom_ui, QDesignerFormEditorInterface *core)
+{
+ WidgetBoxResource builder(core);
+ // We have the builder create the articial QWidget fake top level as a tooltip
+ // because the size algorithm works better at weird DPI settings
+ // if the actual widget is created as a child of a container
+ QWidget *fakeTopLevel = builder.createUI(dom_ui, static_cast<QWidget*>(0));
+ fakeTopLevel->setParent(0, Qt::ToolTip); // Container
+ // Actual widget
+ const DomWidget *domW = dom_ui->elementWidget()->elementWidget().front();
+ QWidget *w = fakeTopLevel->findChildren<QWidget*>().front();
+ Q_ASSERT(w);
+ // hack begin;
+ // We set _q_dockDrag dynamic property which will be detected in drag enter event of form window.
+ // Dock drop is handled in special way (highlight goes to central widget of main window)
+ if (qobject_cast<QDesignerDockWidget *>(w))
+ fakeTopLevel->setProperty("_q_dockDrag", QVariant(true));
+ // hack end;
+ w->setAutoFillBackground(true); // Different style for embedded
+ QSize size = domWidgetSize(domW);
+ const QSize minimumSize = w->minimumSizeHint();
+ if (!size.isValid())
+ size = w->sizeHint();
+ if (size.width() < minimumSize.width())
+ size.setWidth(minimumSize.width());
+ if (size.height() < minimumSize.height())
+ size.setHeight(minimumSize.height());
+ // A QWidget might have size -1,-1 if no geometry property is specified in the widget box.
+ if (size.isEmpty())
+ size = size.expandedTo(QSize(16, 16));
+ w->setGeometry(QRect(QPoint(0, 0), size));
+ fakeTopLevel->resize(size);
+ return fakeTopLevel;
+}
+
+WidgetBoxDnDItem::WidgetBoxDnDItem(QDesignerFormEditorInterface *core,
+ DomUI *dom_ui,
+ const QPoint &global_mouse_pos) :
+ QDesignerDnDItem(CopyDrop)
+{
+ QWidget *decoration = decorationFromDomWidget(dom_ui, core);
+ decoration->move(global_mouse_pos - QPoint(5, 5));
+
+ init(dom_ui, 0, decoration, global_mouse_pos);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/widgetbox/widgetbox_dnditem.h b/src/designer/src/components/widgetbox/widgetbox_dnditem.h
new file mode 100644
index 000000000..010cedc03
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetbox_dnditem.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WIDGETBOX_DNDITEM_H
+#define WIDGETBOX_DNDITEM_H
+
+#include <qdesigner_dnditem_p.h>
+#include "widgetbox_global.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class DomUI;
+
+namespace qdesigner_internal {
+
+class QT_WIDGETBOX_EXPORT WidgetBoxDnDItem : public QDesignerDnDItem
+{
+public:
+ WidgetBoxDnDItem(QDesignerFormEditorInterface *core,
+ DomUI *dom_ui,
+ const QPoint &global_mouse_pos);
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // WIDGETBOX_DNDITEM_H
diff --git a/src/designer/src/components/widgetbox/widgetbox_global.h b/src/designer/src/components/widgetbox/widgetbox_global.h
new file mode 100644
index 000000000..0d550c748
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetbox_global.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WIDGETBOX_GLOBAL_H
+#define WIDGETBOX_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN
+#ifdef QT_WIDGETBOX_LIBRARY
+# define QT_WIDGETBOX_EXPORT
+#else
+# define QT_WIDGETBOX_EXPORT
+#endif
+#else
+#define QT_WIDGETBOX_EXPORT
+#endif
+
+#endif // WIDGETBOX_GLOBAL_H
diff --git a/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp b/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp
new file mode 100644
index 000000000..d2a0d43c0
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp
@@ -0,0 +1,510 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "widgetboxcategorylistview.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+
+#include <QtXml/QDomDocument>
+
+#include <QtGui/QIcon>
+#include <QtGui/QListView>
+#include <QtGui/QLineEdit>
+#include <QtGui/QItemDelegate>
+#include <QtGui/QSortFilterProxyModel>
+
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QList>
+#include <QtCore/QTextStream>
+#include <QtCore/QRegExp>
+
+static const char *widgetElementC = "widget";
+static const char *nameAttributeC = "name";
+static const char *uiOpeningTagC = "<ui>";
+static const char *uiClosingTagC = "</ui>";
+
+QT_BEGIN_NAMESPACE
+
+enum { FilterRole = Qt::UserRole + 11 };
+
+static QString domToString(const QDomElement &elt)
+{
+ QString result;
+ QTextStream stream(&result, QIODevice::WriteOnly);
+ elt.save(stream, 2);
+ stream.flush();
+ return result;
+}
+
+static QDomDocument stringToDom(const QString &xml)
+{
+ QDomDocument result;
+ result.setContent(xml);
+ return result;
+}
+
+namespace qdesigner_internal {
+
+// Entry of the model list
+
+struct WidgetBoxCategoryEntry {
+ WidgetBoxCategoryEntry();
+ explicit WidgetBoxCategoryEntry(const QDesignerWidgetBoxInterface::Widget &widget,
+ const QString &filter,
+ const QIcon &icon,
+ bool editable);
+
+ QDesignerWidgetBoxInterface::Widget widget;
+ QString toolTip;
+ QString whatsThis;
+ QString filter;
+ QIcon icon;
+ bool editable;
+};
+
+
+WidgetBoxCategoryEntry::WidgetBoxCategoryEntry() :
+ editable(false)
+{
+}
+
+WidgetBoxCategoryEntry::WidgetBoxCategoryEntry(const QDesignerWidgetBoxInterface::Widget &w,
+ const QString &filterIn,
+ const QIcon &i, bool e) :
+ widget(w),
+ filter(filterIn),
+ icon(i),
+ editable(e)
+{
+}
+
+/* WidgetBoxCategoryModel, representing a list of category entries. Uses a
+ * QAbstractListModel since the behaviour depends on the view mode of the list
+ * view, it does not return text in the case of IconMode. */
+
+class WidgetBoxCategoryModel : public QAbstractListModel {
+public:
+ explicit WidgetBoxCategoryModel(QDesignerFormEditorInterface *core, QObject *parent = 0);
+
+ // QAbstractListModel
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
+ virtual Qt::ItemFlags flags (const QModelIndex & index ) const;
+ virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+
+ // The model returns no text in icon mode, so, it also needs to know it
+ QListView::ViewMode viewMode() const;
+ void setViewMode(QListView::ViewMode vm);
+
+ void addWidget(const QDesignerWidgetBoxInterface::Widget &widget, const QIcon &icon, bool editable);
+
+ QDesignerWidgetBoxInterface::Widget widgetAt(const QModelIndex & index) const;
+ QDesignerWidgetBoxInterface::Widget widgetAt(int row) const;
+
+ int indexOfWidget(const QString &name);
+
+ QDesignerWidgetBoxInterface::Category category() const;
+ bool removeCustomWidgets();
+
+private:
+ typedef QList<WidgetBoxCategoryEntry> WidgetBoxCategoryEntrys;
+
+ QRegExp m_classNameRegExp;
+ QDesignerFormEditorInterface *m_core;
+ WidgetBoxCategoryEntrys m_items;
+ QListView::ViewMode m_viewMode;
+};
+
+WidgetBoxCategoryModel::WidgetBoxCategoryModel(QDesignerFormEditorInterface *core, QObject *parent) :
+ QAbstractListModel(parent),
+ m_classNameRegExp(QLatin1String("<widget +class *= *\"([^\"]+)\"")),
+ m_core(core),
+ m_viewMode(QListView::ListMode)
+{
+ Q_ASSERT(m_classNameRegExp.isValid());
+}
+
+QListView::ViewMode WidgetBoxCategoryModel::viewMode() const
+{
+ return m_viewMode;
+}
+
+void WidgetBoxCategoryModel::setViewMode(QListView::ViewMode vm)
+{
+ if (m_viewMode == vm)
+ return;
+ m_viewMode = vm;
+ if (!m_items.empty())
+ reset();
+}
+
+int WidgetBoxCategoryModel::indexOfWidget(const QString &name)
+{
+ const int count = m_items.size();
+ for (int i = 0; i < count; i++)
+ if (m_items.at(i).widget.name() == name)
+ return i;
+ return -1;
+}
+
+QDesignerWidgetBoxInterface::Category WidgetBoxCategoryModel::category() const
+{
+ QDesignerWidgetBoxInterface::Category rc;
+ const WidgetBoxCategoryEntrys::const_iterator cend = m_items.constEnd();
+ for (WidgetBoxCategoryEntrys::const_iterator it = m_items.constBegin(); it != cend; ++it)
+ rc.addWidget(it->widget);
+ return rc;
+}
+
+bool WidgetBoxCategoryModel::removeCustomWidgets()
+{
+ // Typically, we are a whole category of custom widgets, so, remove all
+ // and do reset.
+ bool changed = false;
+ for (WidgetBoxCategoryEntrys::iterator it = m_items.begin(); it != m_items.end(); )
+ if (it->widget.type() == QDesignerWidgetBoxInterface::Widget::Custom) {
+ it = m_items.erase(it);
+ changed = true;
+ } else {
+ ++it;
+ }
+ if (changed)
+ reset();
+ return changed;
+}
+
+void WidgetBoxCategoryModel::addWidget(const QDesignerWidgetBoxInterface::Widget &widget, const QIcon &icon,bool editable)
+{
+ // build item. Filter on name + class name if it is different and not a layout.
+ QString filter = widget.name();
+ if (!filter.contains(QLatin1String("Layout")) && m_classNameRegExp.indexIn(widget.domXml()) != -1) {
+ const QString className = m_classNameRegExp.cap(1);
+ if (!filter.contains(className))
+ filter += className;
+ }
+ WidgetBoxCategoryEntry item(widget, filter, icon, editable);
+ const QDesignerWidgetDataBaseInterface *db = m_core->widgetDataBase();
+ const int dbIndex = db->indexOfClassName(widget.name());
+ if (dbIndex != -1) {
+ const QDesignerWidgetDataBaseItemInterface *dbItem = db->item(dbIndex);
+ const QString toolTip = dbItem->toolTip();
+ if (!toolTip.isEmpty())
+ item.toolTip = toolTip;
+ const QString whatsThis = dbItem->whatsThis();
+ if (!whatsThis.isEmpty())
+ item.whatsThis = whatsThis;
+ }
+ // insert
+ const int row = m_items.size();
+ beginInsertRows(QModelIndex(), row, row);
+ m_items.push_back(item);
+ endInsertRows();
+}
+
+QVariant WidgetBoxCategoryModel::data(const QModelIndex &index, int role) const
+{
+ const int row = index.row();
+ if (row < 0 || row >= m_items.size())
+ return QVariant();
+
+ const WidgetBoxCategoryEntry &item = m_items.at(row);
+ switch (role) {
+ case Qt::DisplayRole:
+ // No text in icon mode
+ return QVariant(m_viewMode == QListView::ListMode ? item.widget.name() : QString());
+ case Qt::DecorationRole:
+ return QVariant(item.icon);
+ case Qt::EditRole:
+ return QVariant(item.widget.name());
+ case Qt::ToolTipRole: {
+ if (m_viewMode == QListView::ListMode)
+ return QVariant(item.toolTip);
+ // Icon mode tooltip should contain the class name
+ QString tt = item.widget.name();
+ if (!item.toolTip.isEmpty()) {
+ tt += QLatin1Char('\n');
+ tt += item.toolTip;
+ }
+ return QVariant(tt);
+
+ }
+ case Qt::WhatsThisRole:
+ return QVariant(item.whatsThis);
+ case FilterRole:
+ return item.filter;
+ }
+ return QVariant();
+}
+
+bool WidgetBoxCategoryModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ const int row = index.row();
+ if (role != Qt::EditRole || row < 0 || row >= m_items.size() || value.type() != QVariant::String)
+ return false;
+ // Set name and adapt Xml
+ WidgetBoxCategoryEntry &item = m_items[row];
+ const QString newName = value.toString();
+ item.widget.setName(newName);
+
+ const QDomDocument doc = stringToDom(WidgetBoxCategoryListView::widgetDomXml(item.widget));
+ QDomElement widget_elt = doc.firstChildElement(QLatin1String(widgetElementC));
+ if (!widget_elt.isNull()) {
+ widget_elt.setAttribute(QLatin1String(nameAttributeC), newName);
+ item.widget.setDomXml(domToString(widget_elt));
+ }
+ emit dataChanged(index, index);
+ return true;
+}
+
+Qt::ItemFlags WidgetBoxCategoryModel::flags(const QModelIndex &index) const
+{
+ Qt::ItemFlags rc = Qt::ItemIsEnabled;
+ const int row = index.row();
+ if (row >= 0 && row < m_items.size())
+ if (m_items.at(row).editable) {
+ rc |= Qt::ItemIsSelectable;
+ // Can change name in list mode only
+ if (m_viewMode == QListView::ListMode)
+ rc |= Qt::ItemIsEditable;
+ }
+ return rc;
+}
+
+int WidgetBoxCategoryModel::rowCount(const QModelIndex & /*parent*/) const
+{
+ return m_items.size();
+}
+
+bool WidgetBoxCategoryModel::removeRows(int row, int count, const QModelIndex & parent)
+{
+ if (row < 0 || count < 1)
+ return false;
+ const int size = m_items.size();
+ const int last = row + count - 1;
+ if (row >= size || last >= size)
+ return false;
+ beginRemoveRows(parent, row, last);
+ for (int r = last; r >= row; r--)
+ m_items.removeAt(r);
+ endRemoveRows();
+ return true;
+}
+
+QDesignerWidgetBoxInterface::Widget WidgetBoxCategoryModel::widgetAt(const QModelIndex & index) const
+{
+ return widgetAt(index.row());
+}
+
+QDesignerWidgetBoxInterface::Widget WidgetBoxCategoryModel::widgetAt(int row) const
+{
+ if (row < 0 || row >= m_items.size())
+ return QDesignerWidgetBoxInterface::Widget();
+ return m_items.at(row).widget;
+}
+
+/* WidgetSubBoxItemDelegate, ensures a valid name using a regexp validator */
+
+class WidgetBoxCategoryEntryDelegate : public QItemDelegate
+{
+public:
+ explicit WidgetBoxCategoryEntryDelegate(QWidget *parent = 0) : QItemDelegate(parent) {}
+ QWidget *createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+};
+
+QWidget *WidgetBoxCategoryEntryDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ QWidget *result = QItemDelegate::createEditor(parent, option, index);
+ if (QLineEdit *line_edit = qobject_cast<QLineEdit*>(result)) {
+ const QRegExp re = QRegExp(QLatin1String("[_a-zA-Z][_a-zA-Z0-9]*"));
+ Q_ASSERT(re.isValid());
+ line_edit->setValidator(new QRegExpValidator(re, line_edit));
+ }
+ return result;
+}
+
+// ---------------------- WidgetBoxCategoryListView
+
+WidgetBoxCategoryListView::WidgetBoxCategoryListView(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QListView(parent),
+ m_proxyModel(new QSortFilterProxyModel(this)),
+ m_model(new WidgetBoxCategoryModel(core, this))
+{
+ setFocusPolicy(Qt::NoFocus);
+ setFrameShape(QFrame::NoFrame);
+ setIconSize(QSize(22, 22));
+ setSpacing(1);
+ setTextElideMode(Qt::ElideMiddle);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setResizeMode(QListView::Adjust);
+ setUniformItemSizes(true);
+
+ setItemDelegate(new WidgetBoxCategoryEntryDelegate(this));
+
+ connect(this, SIGNAL(pressed(QModelIndex)), this, SLOT(slotPressed(QModelIndex)));
+ setEditTriggers(QAbstractItemView::AnyKeyPressed);
+
+ m_proxyModel->setSourceModel(m_model);
+ m_proxyModel->setFilterRole(FilterRole);
+ setModel(m_proxyModel);
+ connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SIGNAL(scratchPadChanged()));
+}
+
+void WidgetBoxCategoryListView::setViewMode(ViewMode vm)
+{
+ QListView::setViewMode(vm);
+ m_model->setViewMode(vm);
+}
+
+void WidgetBoxCategoryListView::setCurrentItem(AccessMode am, int row)
+{
+ const QModelIndex index = am == FilteredAccess ?
+ m_proxyModel->index(row, 0) :
+ m_proxyModel->mapFromSource(m_model->index(row, 0));
+
+ if (index.isValid())
+ setCurrentIndex(index);
+}
+
+void WidgetBoxCategoryListView::slotPressed(const QModelIndex &index)
+{
+ const QDesignerWidgetBoxInterface::Widget wgt = m_model->widgetAt(m_proxyModel->mapToSource(index));
+ if (wgt.isNull())
+ return;
+ emit pressed(wgt.name(), widgetDomXml(wgt), QCursor::pos());
+}
+
+void WidgetBoxCategoryListView::removeCurrentItem()
+{
+ const QModelIndex index = currentIndex();
+ if (!index.isValid() || !m_proxyModel->removeRow(index.row()))
+ return;
+
+ // We check the unfiltered item count here, we don't want to get removed if the
+ // filtered view is empty
+ if (m_model->rowCount()) {
+ emit itemRemoved();
+ } else {
+ emit lastItemRemoved();
+ }
+}
+
+void WidgetBoxCategoryListView::editCurrentItem()
+{
+ const QModelIndex index = currentIndex();
+ if (index.isValid())
+ edit(index);
+}
+
+int WidgetBoxCategoryListView::count(AccessMode am) const
+{
+ return am == FilteredAccess ? m_proxyModel->rowCount() : m_model->rowCount();
+}
+
+int WidgetBoxCategoryListView::mapRowToSource(int filterRow) const
+{
+ const QModelIndex filterIndex = m_proxyModel->index(filterRow, 0);
+ return m_proxyModel->mapToSource(filterIndex).row();
+}
+
+QDesignerWidgetBoxInterface::Widget WidgetBoxCategoryListView::widgetAt(AccessMode am, const QModelIndex & index) const
+{
+ const QModelIndex unfilteredIndex = am == FilteredAccess ? m_proxyModel->mapToSource(index) : index;
+ return m_model->widgetAt(unfilteredIndex);
+}
+
+QDesignerWidgetBoxInterface::Widget WidgetBoxCategoryListView::widgetAt(AccessMode am, int row) const
+{
+ return m_model->widgetAt(am == UnfilteredAccess ? row : mapRowToSource(row));
+}
+
+void WidgetBoxCategoryListView::removeRow(AccessMode am, int row)
+{
+ m_model->removeRow(am == UnfilteredAccess ? row : mapRowToSource(row));
+}
+
+bool WidgetBoxCategoryListView::containsWidget(const QString &name)
+{
+ return m_model->indexOfWidget(name) != -1;
+}
+
+void WidgetBoxCategoryListView::addWidget(const QDesignerWidgetBoxInterface::Widget &widget, const QIcon &icon, bool editable)
+{
+ m_model->addWidget(widget, icon, editable);
+}
+
+QString WidgetBoxCategoryListView::widgetDomXml(const QDesignerWidgetBoxInterface::Widget &widget)
+{
+ QString domXml = widget.domXml();
+
+ if (domXml.isEmpty()) {
+ domXml = QLatin1String(uiOpeningTagC);
+ domXml += QLatin1String("<widget class=\"");
+ domXml += widget.name();
+ domXml += QLatin1String("\"/>");
+ domXml += QLatin1String(uiClosingTagC);
+ }
+ return domXml;
+}
+
+void WidgetBoxCategoryListView::filter(const QRegExp &re)
+{
+ m_proxyModel->setFilterRegExp(re);
+}
+
+QDesignerWidgetBoxInterface::Category WidgetBoxCategoryListView::category() const
+{
+ return m_model->category();
+}
+
+bool WidgetBoxCategoryListView::removeCustomWidgets()
+{
+ return m_model->removeCustomWidgets();
+}
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/widgetbox/widgetboxcategorylistview.h b/src/designer/src/components/widgetbox/widgetboxcategorylistview.h
new file mode 100644
index 000000000..5e6df1149
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetboxcategorylistview.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WIDGETBOXCATEGORYLISTVIEW_H
+#define WIDGETBOXCATEGORYLISTVIEW_H
+
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+
+#include <QtGui/QListView>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerDnDItemInterface;
+
+class QSortFilterProxyModel;
+class QRegExp;
+
+namespace qdesigner_internal {
+
+class WidgetBoxCategoryModel;
+
+// List view of a category, switchable between icon and list mode.
+// Provides a filtered view.
+class WidgetBoxCategoryListView : public QListView
+{
+ Q_OBJECT
+public:
+ // Whether to access the filtered or unfiltered view
+ enum AccessMode { FilteredAccess, UnfilteredAccess };
+
+ explicit WidgetBoxCategoryListView(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ void setViewMode(ViewMode vm);
+
+ void dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list);
+
+ using QListView::contentsSize;
+
+ // These methods operate on the filtered/unfiltered model according to accessmode
+ int count(AccessMode am) const;
+ QDesignerWidgetBoxInterface::Widget widgetAt(AccessMode am, const QModelIndex &index) const;
+ QDesignerWidgetBoxInterface::Widget widgetAt(AccessMode am, int row) const;
+ void removeRow(AccessMode am, int row);
+ void setCurrentItem(AccessMode am, int row);
+
+ // These methods operate on the unfiltered model and are used for serialization
+ void addWidget(const QDesignerWidgetBoxInterface::Widget &widget, const QIcon &icon, bool editable);
+ bool containsWidget(const QString &name);
+ QDesignerWidgetBoxInterface::Category category() const;
+ bool removeCustomWidgets();
+
+ // Helper: Ensure a <ui> tag in the case of empty XML
+ static QString widgetDomXml(const QDesignerWidgetBoxInterface::Widget &widget);
+
+signals:
+ void scratchPadChanged();
+ void pressed(const QString &name, const QString &xml, const QPoint &globalPos);
+ void itemRemoved();
+ void lastItemRemoved();
+
+public slots:
+ void filter(const QRegExp &re);
+
+private slots:
+ void slotPressed(const QModelIndex &index);
+ void removeCurrentItem();
+ void editCurrentItem();
+
+private:
+ int mapRowToSource(int filterRow) const;
+ QSortFilterProxyModel *m_proxyModel;
+ WidgetBoxCategoryModel *m_model;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // WIDGETBOXCATEGORYLISTVIEW_H
diff --git a/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp b/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp
new file mode 100644
index 000000000..f4b567b69
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetboxtreewidget.cpp
@@ -0,0 +1,1001 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "widgetboxtreewidget.h"
+#include "widgetboxcategorylistview.h"
+
+// shared
+#include <iconloader_p.h>
+#include <sheet_delegate_p.h>
+#include <QtDesigner/private/abstractsettings_p.h>
+#include <ui4_p.h>
+#include <qdesigner_utils_p.h>
+#include <pluginmanager_p.h>
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerDnDItemInterface>
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+#include <QtDesigner/private/abstractsettings_p.h>
+
+#include <QtGui/QHeaderView>
+#include <QtGui/QApplication>
+#include <QtGui/QTreeWidgetItem>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QMenu>
+
+#include <QtCore/QFile>
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+
+static const char *widgetBoxRootElementC = "widgetbox";
+static const char *widgetElementC = "widget";
+static const char *uiElementC = "ui";
+static const char *categoryElementC = "category";
+static const char *categoryEntryElementC = "categoryentry";
+static const char *nameAttributeC = "name";
+static const char *typeAttributeC = "type";
+static const char *iconAttributeC = "icon";
+static const char *defaultTypeValueC = "default";
+static const char *customValueC = "custom";
+static const char *iconPrefixC = "__qt_icon__";
+static const char *scratchPadValueC = "scratchpad";
+static const char *qtLogoC = "qtlogo.png";
+static const char *invisibleNameC = "[invisible]";
+
+enum TopLevelRole { NORMAL_ITEM, SCRATCHPAD_ITEM, CUSTOM_ITEM };
+
+QT_BEGIN_NAMESPACE
+
+static void setTopLevelRole(TopLevelRole tlr, QTreeWidgetItem *item)
+{
+ item->setData(0, Qt::UserRole, QVariant(tlr));
+}
+
+static TopLevelRole topLevelRole(const QTreeWidgetItem *item)
+{
+ return static_cast<TopLevelRole>(item->data(0, Qt::UserRole).toInt());
+}
+
+namespace qdesigner_internal {
+
+WidgetBoxTreeWidget::WidgetBoxTreeWidget(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QTreeWidget(parent),
+ m_core(core),
+ m_iconMode(false),
+ m_scratchPadDeleteTimer(0)
+{
+ setFocusPolicy(Qt::NoFocus);
+ setIndentation(0);
+ setRootIsDecorated(false);
+ setColumnCount(1);
+ header()->hide();
+ header()->setResizeMode(QHeaderView::Stretch);
+ setTextElideMode(Qt::ElideMiddle);
+ setVerticalScrollMode(ScrollPerPixel);
+
+ setItemDelegate(new SheetDelegate(this, this));
+
+ connect(this, SIGNAL(itemPressed(QTreeWidgetItem*,int)),
+ this, SLOT(handleMousePress(QTreeWidgetItem*)));
+}
+
+QIcon WidgetBoxTreeWidget::iconForWidget(QString iconName) const
+{
+ if (iconName.isEmpty())
+ iconName = QLatin1String(qtLogoC);
+
+ if (iconName.startsWith(QLatin1String(iconPrefixC))) {
+ const IconCache::const_iterator it = m_pluginIcons.constFind(iconName);
+ if (it != m_pluginIcons.constEnd())
+ return it.value();
+ }
+ return createIconSet(iconName);
+}
+
+WidgetBoxCategoryListView *WidgetBoxTreeWidget::categoryViewAt(int idx) const
+{
+ WidgetBoxCategoryListView *rc = 0;
+ if (QTreeWidgetItem *cat_item = topLevelItem(idx))
+ if (QTreeWidgetItem *embedItem = cat_item->child(0))
+ rc = qobject_cast<WidgetBoxCategoryListView*>(itemWidget(embedItem, 0));
+ Q_ASSERT(rc);
+ return rc;
+}
+
+void WidgetBoxTreeWidget::saveExpandedState() const
+{
+ QStringList closedCategories;
+ if (const int numCategories = categoryCount()) {
+ for (int i = 0; i < numCategories; ++i) {
+ const QTreeWidgetItem *cat_item = topLevelItem(i);
+ if (!isItemExpanded(cat_item))
+ closedCategories.append(cat_item->text(0));
+ }
+ }
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->beginGroup(QLatin1String(widgetBoxRootElementC));
+ settings->setValue(QLatin1String("Closed categories"), closedCategories);
+ settings->setValue(QLatin1String("View mode"), m_iconMode);
+ settings->endGroup();
+}
+
+void WidgetBoxTreeWidget::restoreExpandedState()
+{
+ typedef QSet<QString> StringSet;
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ m_iconMode = settings->value(QLatin1String("WidgetBox/View mode")).toBool();
+ updateViewMode();
+ const StringSet closedCategories = settings->value(QLatin1String("WidgetBox/Closed categories"), QStringList()).toStringList().toSet();
+ expandAll();
+ if (closedCategories.empty())
+ return;
+
+ if (const int numCategories = categoryCount()) {
+ for (int i = 0; i < numCategories; ++i) {
+ QTreeWidgetItem *item = topLevelItem(i);
+ if (closedCategories.contains(item->text(0)))
+ item->setExpanded(false);
+ }
+ }
+}
+
+WidgetBoxTreeWidget::~WidgetBoxTreeWidget()
+{
+ saveExpandedState();
+}
+
+void WidgetBoxTreeWidget::setFileName(const QString &file_name)
+{
+ m_file_name = file_name;
+}
+
+QString WidgetBoxTreeWidget::fileName() const
+{
+ return m_file_name;
+}
+
+bool WidgetBoxTreeWidget::save()
+{
+ if (fileName().isEmpty())
+ return false;
+
+ QFile file(fileName());
+ if (!file.open(QIODevice::WriteOnly))
+ return false;
+
+ CategoryList cat_list;
+ const int count = categoryCount();
+ for (int i = 0; i < count; ++i)
+ cat_list.append(category(i));
+
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ writeCategories(writer, cat_list);
+ writer.writeEndDocument();
+
+ return true;
+}
+
+void WidgetBoxTreeWidget::slotSave()
+{
+ save();
+}
+
+void WidgetBoxTreeWidget::handleMousePress(QTreeWidgetItem *item)
+{
+ if (item == 0)
+ return;
+
+ if (QApplication::mouseButtons() != Qt::LeftButton)
+ return;
+
+ if (item->parent() == 0) {
+ setItemExpanded(item, !isItemExpanded(item));
+ return;
+ }
+}
+
+int WidgetBoxTreeWidget::ensureScratchpad()
+{
+ const int existingIndex = indexOfScratchpad();
+ if (existingIndex != -1)
+ return existingIndex;
+
+ QTreeWidgetItem *scratch_item = new QTreeWidgetItem(this);
+ scratch_item->setText(0, tr("Scratchpad"));
+ setTopLevelRole(SCRATCHPAD_ITEM, scratch_item);
+ addCategoryView(scratch_item, false); // Scratchpad in list mode.
+ return categoryCount() - 1;
+}
+
+WidgetBoxCategoryListView *WidgetBoxTreeWidget::addCategoryView(QTreeWidgetItem *parent, bool iconMode)
+{
+ QTreeWidgetItem *embed_item = new QTreeWidgetItem(parent);
+ embed_item->setFlags(Qt::ItemIsEnabled);
+ WidgetBoxCategoryListView *categoryView = new WidgetBoxCategoryListView(m_core, this);
+ categoryView->setViewMode(iconMode ? QListView::IconMode : QListView::ListMode);
+ connect(categoryView, SIGNAL(scratchPadChanged()), this, SLOT(slotSave()));
+ connect(categoryView, SIGNAL(pressed(QString,QString,QPoint)), this, SIGNAL(pressed(QString,QString,QPoint)));
+ connect(categoryView, SIGNAL(itemRemoved()), this, SLOT(slotScratchPadItemDeleted()));
+ connect(categoryView, SIGNAL(lastItemRemoved()), this, SLOT(slotLastScratchPadItemDeleted()));
+ setItemWidget(embed_item, 0, categoryView);
+ return categoryView;
+}
+
+int WidgetBoxTreeWidget::indexOfScratchpad() const
+{
+ if (const int numTopLevels = topLevelItemCount()) {
+ for (int i = numTopLevels - 1; i >= 0; --i) {
+ if (topLevelRole(topLevelItem(i)) == SCRATCHPAD_ITEM)
+ return i;
+ }
+ }
+ return -1;
+}
+
+int WidgetBoxTreeWidget::indexOfCategory(const QString &name) const
+{
+ const int topLevelCount = topLevelItemCount();
+ for (int i = 0; i < topLevelCount; ++i) {
+ if (topLevelItem(i)->text(0) == name)
+ return i;
+ }
+ return -1;
+}
+
+bool WidgetBoxTreeWidget::load(QDesignerWidgetBox::LoadMode loadMode)
+{
+ switch (loadMode) {
+ case QDesignerWidgetBox::LoadReplace:
+ clear();
+ break;
+ case QDesignerWidgetBox::LoadCustomWidgetsOnly:
+ addCustomCategories(true);
+ updateGeometries();
+ return true;
+ default:
+ break;
+ }
+
+ const QString name = fileName();
+
+ QFile f(name);
+ if (!f.open(QIODevice::ReadOnly)) // Might not exist at first startup
+ return false;
+
+ const QString contents = QString::fromUtf8(f.readAll());
+ return loadContents(contents);
+}
+
+bool WidgetBoxTreeWidget::loadContents(const QString &contents)
+{
+ QString errorMessage;
+ CategoryList cat_list;
+ if (!readCategories(m_file_name, contents, &cat_list, &errorMessage)) {
+ qdesigner_internal::designerWarning(errorMessage);
+ return false;
+ }
+
+ foreach(const Category &cat, cat_list)
+ addCategory(cat);
+
+ addCustomCategories(false);
+ // Restore which items are expanded
+ restoreExpandedState();
+ return true;
+}
+
+void WidgetBoxTreeWidget::addCustomCategories(bool replace)
+{
+ if (replace) {
+ // clear out all existing custom widgets
+ if (const int numTopLevels = topLevelItemCount()) {
+ for (int t = 0; t < numTopLevels ; ++t)
+ categoryViewAt(t)->removeCustomWidgets();
+ }
+ }
+ // re-add
+ const CategoryList customList = loadCustomCategoryList();
+ const CategoryList::const_iterator cend = customList.constEnd();
+ for (CategoryList::const_iterator it = customList.constBegin(); it != cend; ++it)
+ addCategory(*it);
+}
+
+static inline QString msgXmlError(const QString &fileName, const QXmlStreamReader &r)
+{
+ return QDesignerWidgetBox::tr("An error has been encountered at line %1 of %2: %3")
+ .arg(r.lineNumber()).arg(fileName, r.errorString());
+}
+
+bool WidgetBoxTreeWidget::readCategories(const QString &fileName, const QString &contents,
+ CategoryList *cats, QString *errorMessage)
+{
+ // Read widget box XML:
+ //
+ //<widgetbox version="4.5">
+ // <category name="Layouts">
+ // <categoryentry name="Vertical Layout" icon="win/editvlayout.png" type="default">
+ // <widget class="QListWidget" ...>
+ // ...
+
+ QXmlStreamReader reader(contents);
+
+
+ // Entries of category with name="invisible" should be ignored
+ bool ignoreEntries = false;
+
+ while (!reader.atEnd()) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartElement: {
+ const QStringRef tag = reader.name();
+ if (tag == QLatin1String(widgetBoxRootElementC)) {
+ //<widgetbox version="4.5">
+ continue;
+ }
+ if (tag == QLatin1String(categoryElementC)) {
+ // <category name="Layouts">
+ const QXmlStreamAttributes attributes = reader.attributes();
+ const QString categoryName = attributes.value(QLatin1String(nameAttributeC)).toString();
+ if (categoryName == QLatin1String(invisibleNameC)) {
+ ignoreEntries = true;
+ } else {
+ Category category(categoryName);
+ if (attributes.value(QLatin1String(typeAttributeC)) == QLatin1String(scratchPadValueC))
+ category.setType(Category::Scratchpad);
+ cats->push_back(category);
+ }
+ continue;
+ }
+ if (tag == QLatin1String(categoryEntryElementC)) {
+ // <categoryentry name="Vertical Layout" icon="win/editvlayout.png" type="default">
+ if (!ignoreEntries) {
+ QXmlStreamAttributes attr = reader.attributes();
+ const QString widgetName = attr.value(QLatin1String(nameAttributeC)).toString();
+ const QString widgetIcon = attr.value(QLatin1String(iconAttributeC)).toString();
+ const WidgetBoxTreeWidget::Widget::Type widgetType =
+ attr.value(QLatin1String(typeAttributeC)).toString()
+ == QLatin1String(customValueC) ?
+ WidgetBoxTreeWidget::Widget::Custom :
+ WidgetBoxTreeWidget::Widget::Default;
+
+ Widget w;
+ w.setName(widgetName);
+ w.setIconName(widgetIcon);
+ w.setType(widgetType);
+ if (!readWidget(&w, contents, reader))
+ continue;
+
+ cats->back().addWidget(w);
+ } // ignoreEntries
+ continue;
+ }
+ break;
+ }
+ case QXmlStreamReader::EndElement: {
+ const QStringRef tag = reader.name();
+ if (tag == QLatin1String(widgetBoxRootElementC)) {
+ continue;
+ }
+ if (tag == QLatin1String(categoryElementC)) {
+ ignoreEntries = false;
+ continue;
+ }
+ if (tag == QLatin1String(categoryEntryElementC)) {
+ continue;
+ }
+ break;
+ }
+ default: break;
+ }
+ }
+
+ if (reader.hasError()) {
+ *errorMessage = msgXmlError(fileName, reader);
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ * Read out a widget within a category. This can either be
+ * enclosed in a <ui> element or a (legacy) <widget> element which may
+ * contain nested <widget> elements.
+ *
+ * Examples:
+ *
+ * <ui language="c++">
+ * <widget class="MultiPageWidget" name="multipagewidget"> ... </widget>
+ * <customwidgets>...</customwidgets>
+ * <ui>
+ *
+ * or
+ *
+ * <widget>
+ * <widget> ... </widget>
+ * ...
+ * <widget>
+ *
+ * Returns true on success, false if end was reached or an error has been encountered
+ * in which case the reader has its error flag set. If successful, the current item
+ * of the reader will be the closing element (</ui> or </widget>)
+ */
+bool WidgetBoxTreeWidget::readWidget(Widget *w, const QString &xml, QXmlStreamReader &r)
+{
+ qint64 startTagPosition =0, endTagPosition = 0;
+
+ int nesting = 0;
+ bool endEncountered = false;
+ bool parsedWidgetTag = false;
+ QString outmostElement;
+ while (!endEncountered) {
+ const qint64 currentPosition = r.characterOffset();
+ switch(r.readNext()) {
+ case QXmlStreamReader::StartElement:
+ if (nesting++ == 0) {
+ // First element must be <ui> or (legacy) <widget>
+ const QStringRef name = r.name();
+ if (name == QLatin1String(uiElementC)) {
+ startTagPosition = currentPosition;
+ } else {
+ if (name == QLatin1String(widgetElementC)) {
+ startTagPosition = currentPosition;
+ parsedWidgetTag = true;
+ } else {
+ r.raiseError(QDesignerWidgetBox::tr("Unexpected element <%1> encountered when parsing for <widget> or <ui>").arg(name.toString()));
+ return false;
+ }
+ }
+ } else {
+ // We are within <ui> looking for the first <widget> tag
+ if (!parsedWidgetTag && r.name() == QLatin1String(widgetElementC)) {
+ parsedWidgetTag = true;
+ }
+ }
+ break;
+ case QXmlStreamReader::EndElement:
+ // Reached end of widget?
+ if (--nesting == 0) {
+ endTagPosition = r.characterOffset();
+ endEncountered = true;
+ }
+ break;
+ case QXmlStreamReader::EndDocument:
+ r.raiseError(QDesignerWidgetBox::tr("Unexpected end of file encountered when parsing widgets."));
+ return false;
+ case QXmlStreamReader::Invalid:
+ return false;
+ default:
+ break;
+ }
+ }
+ if (!parsedWidgetTag) {
+ r.raiseError(QDesignerWidgetBox::tr("A widget element could not be found."));
+ return false;
+ }
+ // Oddity: Startposition is 1 off
+ QString widgetXml = xml.mid(startTagPosition, endTagPosition - startTagPosition);
+ const QChar lessThan = QLatin1Char('<');
+ if (!widgetXml.startsWith(lessThan))
+ widgetXml.prepend(lessThan);
+ w->setDomXml(widgetXml);
+ return true;
+}
+
+void WidgetBoxTreeWidget::writeCategories(QXmlStreamWriter &writer, const CategoryList &cat_list) const
+{
+ const QString widgetbox = QLatin1String(widgetBoxRootElementC);
+ const QString name = QLatin1String(nameAttributeC);
+ const QString type = QLatin1String(typeAttributeC);
+ const QString icon = QLatin1String(iconAttributeC);
+ const QString defaultType = QLatin1String(defaultTypeValueC);
+ const QString category = QLatin1String(categoryElementC);
+ const QString categoryEntry = QLatin1String(categoryEntryElementC);
+ const QString iconPrefix = QLatin1String(iconPrefixC);
+ const QString widgetTag = QLatin1String(widgetElementC);
+
+ //
+ // <widgetbox>
+ // <category name="Layouts">
+ // <categoryEntry name="Vertical Layout" type="default" icon="win/editvlayout.png">
+ // <ui>
+ // ...
+ // </ui>
+ // </categoryEntry>
+ // ...
+ // </category>
+ // ...
+ // </widgetbox>
+ //
+
+ writer.writeStartElement(widgetbox);
+
+ foreach (const Category &cat, cat_list) {
+ writer.writeStartElement(category);
+ writer.writeAttribute(name, cat.name());
+ if (cat.type() == Category::Scratchpad)
+ writer.writeAttribute(type, QLatin1String(scratchPadValueC));
+
+ const int widgetCount = cat.widgetCount();
+ for (int i = 0; i < widgetCount; ++i) {
+ const Widget wgt = cat.widget(i);
+ if (wgt.type() == Widget::Custom)
+ continue;
+
+ writer.writeStartElement(categoryEntry);
+ writer.writeAttribute(name, wgt.name());
+ if (!wgt.iconName().startsWith(iconPrefix))
+ writer.writeAttribute(icon, wgt.iconName());
+ writer.writeAttribute(type, defaultType);
+
+ const DomUI *domUI = QDesignerWidgetBox::xmlToUi(wgt.name(), WidgetBoxCategoryListView::widgetDomXml(wgt), false);
+ if (domUI) {
+ domUI->write(writer);
+ delete domUI;
+ }
+
+ writer.writeEndElement(); // categoryEntry
+ }
+ writer.writeEndElement(); // categoryEntry
+ }
+
+ writer.writeEndElement(); // widgetBox
+}
+
+static int findCategory(const QString &name, const WidgetBoxTreeWidget::CategoryList &list)
+{
+ int idx = 0;
+ foreach (const WidgetBoxTreeWidget::Category &cat, list) {
+ if (cat.name() == name)
+ return idx;
+ ++idx;
+ }
+ return -1;
+}
+
+static inline bool isValidIcon(const QIcon &icon)
+{
+ if (!icon.isNull()) {
+ const QList<QSize> availableSizes = icon.availableSizes();
+ if (!availableSizes.empty())
+ return !availableSizes.front().isEmpty();
+ }
+ return false;
+}
+
+WidgetBoxTreeWidget::CategoryList WidgetBoxTreeWidget::loadCustomCategoryList() const
+{
+ CategoryList result;
+
+ const QDesignerPluginManager *pm = m_core->pluginManager();
+ const QDesignerPluginManager::CustomWidgetList customWidgets = pm->registeredCustomWidgets();
+ if (customWidgets.empty())
+ return result;
+
+ static const QString customCatName = tr("Custom Widgets");
+
+ const QString invisible = QLatin1String(invisibleNameC);
+ const QString iconPrefix = QLatin1String(iconPrefixC);
+
+ foreach(QDesignerCustomWidgetInterface *c, customWidgets) {
+ const QString dom_xml = c->domXml();
+ if (dom_xml.isEmpty())
+ continue;
+
+ const QString pluginName = c->name();
+ const QDesignerCustomWidgetData data = pm->customWidgetData(c);
+ QString displayName = data.xmlDisplayName();
+ if (displayName.isEmpty())
+ displayName = pluginName;
+
+ QString cat_name = c->group();
+ if (cat_name.isEmpty())
+ cat_name = customCatName;
+ else if (cat_name == invisible)
+ continue;
+
+ int idx = findCategory(cat_name, result);
+ if (idx == -1) {
+ result.append(Category(cat_name));
+ idx = result.size() - 1;
+ }
+ Category &cat = result[idx];
+
+ const QIcon icon = c->icon();
+
+ QString icon_name;
+ if (isValidIcon(icon)) {
+ icon_name = iconPrefix;
+ icon_name += pluginName;
+ m_pluginIcons.insert(icon_name, icon);
+ } else {
+ icon_name = QLatin1String(qtLogoC);
+ }
+
+ cat.addWidget(Widget(displayName, dom_xml, icon_name, Widget::Custom));
+ }
+
+ return result;
+}
+
+void WidgetBoxTreeWidget::adjustSubListSize(QTreeWidgetItem *cat_item)
+{
+ QTreeWidgetItem *embedItem = cat_item->child(0);
+ if (embedItem == 0)
+ return;
+
+ WidgetBoxCategoryListView *list_widget = static_cast<WidgetBoxCategoryListView*>(itemWidget(embedItem, 0));
+ list_widget->setFixedWidth(header()->width());
+ list_widget->doItemsLayout();
+ const int height = qMax(list_widget->contentsSize().height() ,1);
+ list_widget->setFixedHeight(height);
+ embedItem->setSizeHint(0, QSize(-1, height - 1));
+}
+
+int WidgetBoxTreeWidget::categoryCount() const
+{
+ return topLevelItemCount();
+}
+
+WidgetBoxTreeWidget::Category WidgetBoxTreeWidget::category(int cat_idx) const
+{
+ if (cat_idx >= topLevelItemCount())
+ return Category();
+
+ QTreeWidgetItem *cat_item = topLevelItem(cat_idx);
+
+ QTreeWidgetItem *embedItem = cat_item->child(0);
+ WidgetBoxCategoryListView *categoryView = static_cast<WidgetBoxCategoryListView*>(itemWidget(embedItem, 0));
+
+ Category result = categoryView->category();
+ result.setName(cat_item->text(0));
+
+ switch (topLevelRole(cat_item)) {
+ case SCRATCHPAD_ITEM:
+ result.setType(Category::Scratchpad);
+ break;
+ default:
+ result.setType(Category::Default);
+ break;
+ }
+ return result;
+}
+
+void WidgetBoxTreeWidget::addCategory(const Category &cat)
+{
+ if (cat.widgetCount() == 0)
+ return;
+
+ const bool isScratchPad = cat.type() == Category::Scratchpad;
+ WidgetBoxCategoryListView *categoryView;
+ QTreeWidgetItem *cat_item;
+
+ if (isScratchPad) {
+ const int idx = ensureScratchpad();
+ categoryView = categoryViewAt(idx);
+ cat_item = topLevelItem(idx);
+ } else {
+ const int existingIndex = indexOfCategory(cat.name());
+ if (existingIndex == -1) {
+ cat_item = new QTreeWidgetItem();
+ cat_item->setText(0, cat.name());
+ setTopLevelRole(NORMAL_ITEM, cat_item);
+ // insert before scratchpad
+ const int scratchPadIndex = indexOfScratchpad();
+ if (scratchPadIndex == -1) {
+ addTopLevelItem(cat_item);
+ } else {
+ insertTopLevelItem(scratchPadIndex, cat_item);
+ }
+ setItemExpanded(cat_item, true);
+ categoryView = addCategoryView(cat_item, m_iconMode);
+ } else {
+ categoryView = categoryViewAt(existingIndex);
+ cat_item = topLevelItem(existingIndex);
+ }
+ }
+ // The same categories are read from the file $HOME, avoid duplicates
+ const int widgetCount = cat.widgetCount();
+ for (int i = 0; i < widgetCount; ++i) {
+ const Widget w = cat.widget(i);
+ if (!categoryView->containsWidget(w.name()))
+ categoryView->addWidget(w, iconForWidget(w.iconName()), isScratchPad);
+ }
+ adjustSubListSize(cat_item);
+}
+
+void WidgetBoxTreeWidget::removeCategory(int cat_idx)
+{
+ if (cat_idx >= topLevelItemCount())
+ return;
+ delete takeTopLevelItem(cat_idx);
+}
+
+int WidgetBoxTreeWidget::widgetCount(int cat_idx) const
+{
+ if (cat_idx >= topLevelItemCount())
+ return 0;
+ // SDK functions want unfiltered access
+ return categoryViewAt(cat_idx)->count(WidgetBoxCategoryListView::UnfilteredAccess);
+}
+
+WidgetBoxTreeWidget::Widget WidgetBoxTreeWidget::widget(int cat_idx, int wgt_idx) const
+{
+ if (cat_idx >= topLevelItemCount())
+ return Widget();
+ // SDK functions want unfiltered access
+ WidgetBoxCategoryListView *categoryView = categoryViewAt(cat_idx);
+ return categoryView->widgetAt(WidgetBoxCategoryListView::UnfilteredAccess, wgt_idx);
+}
+
+void WidgetBoxTreeWidget::addWidget(int cat_idx, const Widget &wgt)
+{
+ if (cat_idx >= topLevelItemCount())
+ return;
+
+ QTreeWidgetItem *cat_item = topLevelItem(cat_idx);
+ WidgetBoxCategoryListView *categoryView = categoryViewAt(cat_idx);
+
+ const bool scratch = topLevelRole(cat_item) == SCRATCHPAD_ITEM;
+ categoryView->addWidget(wgt, iconForWidget(wgt.iconName()), scratch);
+ adjustSubListSize(cat_item);
+}
+
+void WidgetBoxTreeWidget::removeWidget(int cat_idx, int wgt_idx)
+{
+ if (cat_idx >= topLevelItemCount())
+ return;
+
+ WidgetBoxCategoryListView *categoryView = categoryViewAt(cat_idx);
+
+ // SDK functions want unfiltered access
+ const WidgetBoxCategoryListView::AccessMode am = WidgetBoxCategoryListView::UnfilteredAccess;
+ if (wgt_idx >= categoryView->count(am))
+ return;
+
+ categoryView->removeRow(am, wgt_idx);
+}
+
+void WidgetBoxTreeWidget::slotScratchPadItemDeleted()
+{
+ const int scratch_idx = indexOfScratchpad();
+ QTreeWidgetItem *scratch_item = topLevelItem(scratch_idx);
+ adjustSubListSize(scratch_item);
+ save();
+}
+
+void WidgetBoxTreeWidget::slotLastScratchPadItemDeleted()
+{
+ // Remove the scratchpad in the next idle loop
+ if (!m_scratchPadDeleteTimer) {
+ m_scratchPadDeleteTimer = new QTimer(this);
+ m_scratchPadDeleteTimer->setSingleShot(true);
+ m_scratchPadDeleteTimer->setInterval(0);
+ connect(m_scratchPadDeleteTimer, SIGNAL(timeout()), this, SLOT(deleteScratchpad()));
+ }
+ if (!m_scratchPadDeleteTimer->isActive())
+ m_scratchPadDeleteTimer->start();
+}
+
+void WidgetBoxTreeWidget::deleteScratchpad()
+{
+ const int idx = indexOfScratchpad();
+ if (idx == -1)
+ return;
+ delete takeTopLevelItem(idx);
+ save();
+}
+
+
+void WidgetBoxTreeWidget::slotListMode()
+{
+ m_iconMode = false;
+ updateViewMode();
+}
+
+void WidgetBoxTreeWidget::slotIconMode()
+{
+ m_iconMode = true;
+ updateViewMode();
+}
+
+void WidgetBoxTreeWidget::updateViewMode()
+{
+ if (const int numTopLevels = topLevelItemCount()) {
+ for (int i = numTopLevels - 1; i >= 0; --i) {
+ QTreeWidgetItem *topLevel = topLevelItem(i);
+ // Scratch pad stays in list mode.
+ const QListView::ViewMode viewMode = m_iconMode && (topLevelRole(topLevel) != SCRATCHPAD_ITEM) ? QListView::IconMode : QListView::ListMode;
+ WidgetBoxCategoryListView *categoryView = categoryViewAt(i);
+ if (viewMode != categoryView->viewMode()) {
+ categoryView->setViewMode(viewMode);
+ adjustSubListSize(topLevelItem(i));
+ }
+ }
+ }
+
+ updateGeometries();
+}
+
+void WidgetBoxTreeWidget::resizeEvent(QResizeEvent *e)
+{
+ QTreeWidget::resizeEvent(e);
+ if (const int numTopLevels = topLevelItemCount()) {
+ for (int i = numTopLevels - 1; i >= 0; --i)
+ adjustSubListSize(topLevelItem(i));
+ }
+}
+
+void WidgetBoxTreeWidget::contextMenuEvent(QContextMenuEvent *e)
+{
+ QTreeWidgetItem *item = itemAt(e->pos());
+
+ const bool scratchpad_menu = item != 0
+ && item->parent() != 0
+ && topLevelRole(item->parent()) == SCRATCHPAD_ITEM;
+
+ QMenu menu;
+ menu.addAction(tr("Expand all"), this, SLOT(expandAll()));
+ menu.addAction(tr("Collapse all"), this, SLOT(collapseAll()));
+ menu.addSeparator();
+
+ QAction *listModeAction = menu.addAction(tr("List View"));
+ QAction *iconModeAction = menu.addAction(tr("Icon View"));
+ listModeAction->setCheckable(true);
+ iconModeAction->setCheckable(true);
+ QActionGroup *viewModeGroup = new QActionGroup(&menu);
+ viewModeGroup->addAction(listModeAction);
+ viewModeGroup->addAction(iconModeAction);
+ if (m_iconMode)
+ iconModeAction->setChecked(true);
+ else
+ listModeAction->setChecked(true);
+ connect(listModeAction, SIGNAL(triggered()), SLOT(slotListMode()));
+ connect(iconModeAction, SIGNAL(triggered()), SLOT(slotIconMode()));
+
+ if (scratchpad_menu) {
+ menu.addSeparator();
+ menu.addAction(tr("Remove"), itemWidget(item, 0), SLOT(removeCurrentItem()));
+ if (!m_iconMode)
+ menu.addAction(tr("Edit name"), itemWidget(item, 0), SLOT(editCurrentItem()));
+ }
+ e->accept();
+ menu.exec(mapToGlobal(e->pos()));
+}
+
+void WidgetBoxTreeWidget::dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list)
+{
+ QTreeWidgetItem *scratch_item = 0;
+ WidgetBoxCategoryListView *categoryView = 0;
+ bool added = false;
+
+ foreach (QDesignerDnDItemInterface *item, item_list) {
+ QWidget *w = item->widget();
+ if (w == 0)
+ continue;
+
+ DomUI *dom_ui = item->domUi();
+ if (dom_ui == 0)
+ continue;
+
+ const int scratch_idx = ensureScratchpad();
+ scratch_item = topLevelItem(scratch_idx);
+ categoryView = categoryViewAt(scratch_idx);
+
+ // Temporarily remove the fake toplevel in-between
+ DomWidget *fakeTopLevel = dom_ui->takeElementWidget();
+ DomWidget *firstWidget = 0;
+ if (fakeTopLevel && !fakeTopLevel->elementWidget().isEmpty()) {
+ firstWidget = fakeTopLevel->elementWidget().first();
+ dom_ui->setElementWidget(firstWidget);
+ } else {
+ dom_ui->setElementWidget(fakeTopLevel);
+ continue;
+ }
+
+ // Serialize to XML
+ QString xml;
+ {
+ QXmlStreamWriter writer(&xml);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ dom_ui->write(writer);
+ writer.writeEndDocument();
+ }
+
+ // Insert fake toplevel again
+ dom_ui->takeElementWidget();
+ dom_ui->setElementWidget(fakeTopLevel);
+
+ const Widget wgt = Widget(w->objectName(), xml);
+ categoryView->addWidget(wgt, iconForWidget(wgt.iconName()), true);
+ setItemExpanded(scratch_item, true);
+ added = true;
+ }
+
+ if (added) {
+ save();
+ QApplication::setActiveWindow(this);
+ // Is the new item visible in filtered mode?
+ const WidgetBoxCategoryListView::AccessMode am = WidgetBoxCategoryListView::FilteredAccess;
+ if (const int count = categoryView->count(am))
+ categoryView->setCurrentItem(am, count - 1);
+ categoryView->adjustSize(); // XXX
+ adjustSubListSize(scratch_item);
+ }
+}
+
+void WidgetBoxTreeWidget::filter(const QString &f)
+{
+ const bool empty = f.isEmpty();
+ const QRegExp re = empty ? QRegExp() : QRegExp(f, Qt::CaseInsensitive, QRegExp::FixedString);
+ const int numTopLevels = topLevelItemCount();
+ bool changed = false;
+ for (int i = 0; i < numTopLevels; i++) {
+ QTreeWidgetItem *tl = topLevelItem(i);
+ WidgetBoxCategoryListView *categoryView = categoryViewAt(i);
+ // Anything changed? -> Enable the category
+ const int oldCount = categoryView->count(WidgetBoxCategoryListView::FilteredAccess);
+ categoryView->filter(re);
+ const int newCount = categoryView->count(WidgetBoxCategoryListView::FilteredAccess);
+ if (oldCount != newCount) {
+ changed = true;
+ const bool categoryEnabled = newCount > 0 || empty;
+ if (categoryEnabled) {
+ categoryView->adjustSize();
+ adjustSubListSize(tl);
+ }
+ setRowHidden (i, QModelIndex(), !categoryEnabled);
+ }
+ }
+ if (changed)
+ updateGeometries();
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/components/widgetbox/widgetboxtreewidget.h b/src/designer/src/components/widgetbox/widgetboxtreewidget.h
new file mode 100644
index 000000000..db4f7cdb1
--- /dev/null
+++ b/src/designer/src/components/widgetbox/widgetboxtreewidget.h
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WIDGETBOXTREEWIDGET_H
+#define WIDGETBOXTREEWIDGET_H
+
+#include <qdesigner_widgetbox_p.h>
+
+#include <QtGui/QTreeWidget>
+#include <QtGui/QIcon>
+#include <QtCore/QList>
+#include <QtCore/QHash>
+#include <QtCore/QXmlStreamReader> // Cannot forward declare them on Mac
+#include <QtCore/QXmlStreamWriter>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerDnDItemInterface;
+
+class QTimer;
+
+namespace qdesigner_internal {
+
+class WidgetBoxCategoryListView;
+
+// WidgetBoxTreeWidget: A tree of categories
+
+class WidgetBoxTreeWidget : public QTreeWidget
+{
+ Q_OBJECT
+
+public:
+ typedef QDesignerWidgetBoxInterface::Widget Widget;
+ typedef QDesignerWidgetBoxInterface::Category Category;
+ typedef QDesignerWidgetBoxInterface::CategoryList CategoryList;
+
+ explicit WidgetBoxTreeWidget(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ ~WidgetBoxTreeWidget();
+
+ int categoryCount() const;
+ Category category(int cat_idx) const;
+ void addCategory(const Category &cat);
+ void removeCategory(int cat_idx);
+
+ int widgetCount(int cat_idx) const;
+ Widget widget(int cat_idx, int wgt_idx) const;
+ void addWidget(int cat_idx, const Widget &wgt);
+ void removeWidget(int cat_idx, int wgt_idx);
+
+ void dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list);
+
+ void setFileName(const QString &file_name);
+ QString fileName() const;
+ bool load(QDesignerWidgetBox::LoadMode loadMode);
+ bool loadContents(const QString &contents);
+ bool save();
+ QIcon iconForWidget(QString iconName) const;
+
+signals:
+ void pressed(const QString name, const QString dom_xml, const QPoint &global_mouse_pos);
+
+public slots:
+ void filter(const QString &);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *e);
+ void resizeEvent(QResizeEvent *e);
+
+private slots:
+ void slotSave();
+ void slotScratchPadItemDeleted();
+ void slotLastScratchPadItemDeleted();
+
+ void handleMousePress(QTreeWidgetItem *item);
+ void deleteScratchpad();
+ void slotListMode();
+ void slotIconMode();
+
+private:
+ WidgetBoxCategoryListView *addCategoryView(QTreeWidgetItem *parent, bool iconMode);
+ WidgetBoxCategoryListView *categoryViewAt(int idx) const;
+ void adjustSubListSize(QTreeWidgetItem *cat_item);
+
+ static bool readCategories(const QString &fileName, const QString &xml, CategoryList *cats, QString *errorMessage);
+ static bool readWidget(Widget *w, const QString &xml, QXmlStreamReader &r);
+
+ CategoryList loadCustomCategoryList() const;
+ void writeCategories(QXmlStreamWriter &writer, const CategoryList &cat_list) const;
+
+ int indexOfCategory(const QString &name) const;
+ int indexOfScratchpad() const;
+ int ensureScratchpad();
+ void addCustomCategories(bool replace);
+
+ void saveExpandedState() const;
+ void restoreExpandedState();
+ void updateViewMode();
+
+ QDesignerFormEditorInterface *m_core;
+ QString m_file_name;
+ typedef QHash<QString, QIcon> IconCache;
+ mutable IconCache m_pluginIcons;
+ bool m_iconMode;
+ QTimer *m_scratchPadDeleteTimer;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // WIDGETBOXTREEWIDGET_H
diff --git a/src/designer/src/designer/Info_mac.plist b/src/designer/src/designer/Info_mac.plist
new file mode 100644
index 000000000..f19176fa7
--- /dev/null
+++ b/src/designer/src/designer/Info_mac.plist
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>@ICON@</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.trolltech.Designer</string>
+ <key>CFBundleSignature</key>
+ <string>ttxt</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>ui</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>uifile.icns</string>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSIsAppleDefaultForType</key>
+ <true/>
+ </dict>
+ </array>
+ <key>NOTE</key>
+ <string>Qt/Designer by Nokia Corporation and/or its subsidiary(-ies)</string>
+</dict>
+</plist>
diff --git a/src/designer/src/designer/appfontdialog.cpp b/src/designer/src/designer/appfontdialog.cpp
new file mode 100644
index 000000000..00b91fa0d
--- /dev/null
+++ b/src/designer/src/designer/appfontdialog.cpp
@@ -0,0 +1,429 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "appfontdialog.h"
+
+#include <iconloader_p.h>
+#include <abstractsettings_p.h>
+
+#include <QtGui/QTreeView>
+#include <QtGui/QToolButton>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QFileDialog>
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QMessageBox>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QDialogButtonBox>
+
+#include <QtCore/QSettings>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QStringList>
+#include <QtCore/QFileInfo>
+#include <QtCore/QtAlgorithms>
+#include <QtCore/QVector>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+enum {FileNameRole = Qt::UserRole + 1, IdRole = Qt::UserRole + 2 };
+enum { debugAppFontWidget = 0 };
+
+static const char fontFileKeyC[] = "fontFiles";
+
+// AppFontManager: Singleton that maintains the mapping of loaded application font
+// ids to the file names (which are not stored in QFontDatabase)
+// and provides API for loading/unloading fonts as well for saving/restoring settings.
+
+class AppFontManager
+{
+ Q_DISABLE_COPY(AppFontManager)
+ AppFontManager();
+public:
+ static AppFontManager &instance();
+
+ void save(QDesignerSettingsInterface *s, const QString &prefix) const;
+ void restore(const QDesignerSettingsInterface *s, const QString &prefix);
+
+ // Return id or -1
+ int add(const QString &fontFile, QString *errorMessage);
+
+ bool remove(int id, QString *errorMessage);
+ bool remove(const QString &fontFile, QString *errorMessage);
+ bool removeAt(int index, QString *errorMessage);
+
+ // Store loaded fonts as pair of file name and Id
+ typedef QPair<QString,int> FileNameFontIdPair;
+ typedef QList<FileNameFontIdPair> FileNameFontIdPairs;
+ const FileNameFontIdPairs &fonts() const;
+
+private:
+ FileNameFontIdPairs m_fonts;
+};
+
+AppFontManager::AppFontManager()
+{
+}
+
+AppFontManager &AppFontManager::instance()
+{
+ static AppFontManager rc;
+ return rc;
+}
+
+void AppFontManager::save(QDesignerSettingsInterface *s, const QString &prefix) const
+{
+ // Store as list of file names
+ QStringList fontFiles;
+ const FileNameFontIdPairs::const_iterator cend = m_fonts.constEnd();
+ for (FileNameFontIdPairs::const_iterator it = m_fonts.constBegin(); it != cend; ++it)
+ fontFiles.push_back(it->first);
+
+ s->beginGroup(prefix);
+ s->setValue(QLatin1String(fontFileKeyC), fontFiles);
+ s->endGroup();
+
+ if (debugAppFontWidget)
+ qDebug() << "AppFontManager::saved" << fontFiles.size() << "fonts under " << prefix;
+}
+
+void AppFontManager::restore(const QDesignerSettingsInterface *s, const QString &prefix)
+{
+ QString key = prefix;
+ key += QLatin1Char('/');
+ key += QLatin1String(fontFileKeyC);
+ const QStringList fontFiles = s->value(key, QStringList()).toStringList();
+
+ if (debugAppFontWidget)
+ qDebug() << "AppFontManager::restoring" << fontFiles.size() << "fonts from " << prefix;
+ if (!fontFiles.empty()) {
+ QString errorMessage;
+ const QStringList::const_iterator cend = fontFiles.constEnd();
+ for (QStringList::const_iterator it = fontFiles.constBegin(); it != cend; ++it)
+ if (add(*it, &errorMessage) == -1)
+ qWarning("%s", qPrintable(errorMessage));
+ }
+}
+
+int AppFontManager::add(const QString &fontFile, QString *errorMessage)
+{
+ const QFileInfo inf(fontFile);
+ if (!inf.isFile()) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "'%1' is not a file.").arg(fontFile);
+ return -1;
+ }
+ if (!inf.isReadable()) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' does not have read permissions.").arg(fontFile);
+ return -1;
+ }
+ const QString fullPath = inf.absoluteFilePath();
+ // Check if already loaded
+ const FileNameFontIdPairs::const_iterator cend = m_fonts.constEnd();
+ for (FileNameFontIdPairs::const_iterator it = m_fonts.constBegin(); it != cend; ++it) {
+ if (it->first == fullPath) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' is already loaded.").arg(fontFile);
+ return -1;
+ }
+ }
+
+ const int id = QFontDatabase::addApplicationFont(fullPath);
+ if (id == -1) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' could not be loaded.").arg(fontFile);
+ return -1;
+ }
+
+ if (debugAppFontWidget)
+ qDebug() << "AppFontManager::add" << fontFile << id;
+ m_fonts.push_back(FileNameFontIdPair(fullPath, id));
+ return id;
+}
+
+bool AppFontManager::remove(int id, QString *errorMessage)
+{
+ const int count = m_fonts.size();
+ for (int i = 0; i < count; i++)
+ if (m_fonts[i].second == id)
+ return removeAt(i, errorMessage);
+
+ *errorMessage = QCoreApplication::translate("AppFontManager", "'%1' is not a valid font id.").arg(id);
+ return false;
+}
+
+bool AppFontManager::remove(const QString &fontFile, QString *errorMessage)
+{
+ const int count = m_fonts.size();
+ for (int i = 0; i < count; i++)
+ if (m_fonts[i].first == fontFile)
+ return removeAt(i, errorMessage);
+
+ *errorMessage = QCoreApplication::translate("AppFontManager", "There is no loaded font matching the id '%1'.").arg(fontFile);
+ return false;
+}
+
+bool AppFontManager::removeAt(int index, QString *errorMessage)
+{
+ Q_ASSERT(index >= 0 && index < m_fonts.size());
+
+ const QString fontFile = m_fonts[index].first;
+ const int id = m_fonts[index].second;
+
+ if (debugAppFontWidget)
+ qDebug() << "AppFontManager::removeAt" << index << '(' << fontFile << id << ')';
+
+ if (!QFontDatabase::removeApplicationFont(id)) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "The font '%1' (%2) could not be unloaded.").arg(fontFile).arg(id);
+ return false;
+ }
+ m_fonts.removeAt(index);
+ return true;
+}
+
+const AppFontManager::FileNameFontIdPairs &AppFontManager::fonts() const
+{
+ return m_fonts;
+}
+
+// ------------- AppFontModel
+class AppFontModel : public QStandardItemModel {
+ Q_DISABLE_COPY(AppFontModel)
+public:
+ AppFontModel(QObject *parent = 0);
+
+ void init(const AppFontManager &mgr);
+ void add(const QString &fontFile, int id);
+ int idAt(const QModelIndex &idx) const;
+};
+
+AppFontModel::AppFontModel(QObject * parent) :
+ QStandardItemModel(parent)
+{
+ setHorizontalHeaderLabels(QStringList(AppFontWidget::tr("Fonts")));
+}
+
+void AppFontModel::init(const AppFontManager &mgr)
+{
+ typedef AppFontManager::FileNameFontIdPairs FileNameFontIdPairs;
+
+ const FileNameFontIdPairs &fonts = mgr.fonts();
+ const FileNameFontIdPairs::const_iterator cend = fonts.constEnd();
+ for (FileNameFontIdPairs::const_iterator it = fonts.constBegin(); it != cend; ++it)
+ add(it->first, it->second);
+}
+
+void AppFontModel::add(const QString &fontFile, int id)
+{
+ const QFileInfo inf(fontFile);
+ // Root item with base name
+ QStandardItem *fileItem = new QStandardItem(inf.completeBaseName());
+ const QString fullPath = inf.absoluteFilePath();
+ fileItem->setData(fullPath, FileNameRole);
+ fileItem->setToolTip(fullPath);
+ fileItem->setData(id, IdRole);
+ fileItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
+
+ appendRow(fileItem);
+ const QStringList families = QFontDatabase::applicationFontFamilies(id);
+ const QStringList::const_iterator cend = families.constEnd();
+ for (QStringList::const_iterator it = families.constBegin(); it != cend; ++it) {
+ QStandardItem *familyItem = new QStandardItem(*it);
+ familyItem->setToolTip(fullPath);
+ familyItem->setFont(QFont(*it));
+ familyItem->setFlags(Qt::ItemIsEnabled);
+ fileItem->appendRow(familyItem);
+ }
+}
+
+int AppFontModel::idAt(const QModelIndex &idx) const
+{
+ if (const QStandardItem *item = itemFromIndex(idx))
+ return item->data(IdRole).toInt();
+ return -1;
+}
+
+// ------------- AppFontWidget
+AppFontWidget::AppFontWidget(QWidget *parent) :
+ QGroupBox(parent),
+ m_view(new QTreeView),
+ m_addButton(new QToolButton),
+ m_removeButton(new QToolButton),
+ m_removeAllButton(new QToolButton),
+ m_model(new AppFontModel(this))
+{
+ m_model->init(AppFontManager::instance());
+ m_view->setModel(m_model);
+ m_view->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ m_view->expandAll();
+ connect(m_view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
+
+ m_addButton->setToolTip(tr("Add font files"));
+ m_addButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("plus.png")));
+ connect(m_addButton, SIGNAL(clicked()), this, SLOT(addFiles()));
+
+ m_removeButton->setEnabled(false);
+ m_removeButton->setToolTip(tr("Remove current font file"));
+ m_removeButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("minus.png")));
+ connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveFiles()));
+
+ m_removeAllButton->setToolTip(tr("Remove all font files"));
+ m_removeAllButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("editdelete.png")));
+ connect(m_removeAllButton, SIGNAL(clicked()), this, SLOT(slotRemoveAll()));
+
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->addWidget(m_addButton);
+ hLayout->addWidget(m_removeButton);
+ hLayout->addWidget(m_removeAllButton);
+ hLayout->addItem(new QSpacerItem(0, 0,QSizePolicy::MinimumExpanding));
+
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ vLayout->addWidget(m_view);
+ vLayout->addLayout(hLayout);
+ setLayout(vLayout);
+}
+
+void AppFontWidget::addFiles()
+{
+ const QStringList files =
+ QFileDialog::getOpenFileNames(this, tr("Add Font Files"), QString(),
+ tr("Font files (*.ttf)"));
+ if (files.empty())
+ return;
+
+ QString errorMessage;
+
+ AppFontManager &fmgr = AppFontManager::instance();
+ const QStringList::const_iterator cend = files.constEnd();
+ for (QStringList::const_iterator it = files.constBegin(); it != cend; ++it) {
+ const int id = fmgr.add(*it, &errorMessage);
+ if (id != -1) {
+ m_model->add(*it, id);
+ } else {
+ QMessageBox::critical(this, tr("Error Adding Fonts"), errorMessage);
+ }
+ }
+ m_view->expandAll();
+}
+
+static void removeFonts(const QModelIndexList &selectedIndexes, AppFontModel *model, QWidget *dialogParent)
+{
+ if (selectedIndexes.empty())
+ return;
+
+ // Reverse sort top level rows and remove
+ AppFontManager &fmgr = AppFontManager::instance();
+ QVector<int> rows;
+ rows.reserve(selectedIndexes.size());
+
+ QString errorMessage;
+ const QModelIndexList::const_iterator cend = selectedIndexes.constEnd();
+ for (QModelIndexList::const_iterator it = selectedIndexes.constBegin(); it != cend; ++it) {
+ const int id = model->idAt(*it);
+ if (id != -1) {
+ if (fmgr.remove(id, &errorMessage)) {
+ rows.push_back(it->row());
+ } else {
+ QMessageBox::critical(dialogParent, AppFontWidget::tr("Error Removing Fonts"), errorMessage);
+ }
+ }
+ }
+
+ qStableSort(rows.begin(), rows.end());
+ for (int i = rows.size() - 1; i >= 0; i--)
+ model->removeRow(rows[i]);
+}
+
+void AppFontWidget::slotRemoveFiles()
+{
+ removeFonts(m_view->selectionModel()->selectedIndexes(), m_model, this);
+}
+
+void AppFontWidget::slotRemoveAll()
+{
+ const int count = m_model->rowCount();
+ if (!count)
+ return;
+
+ const QMessageBox::StandardButton answer =
+ QMessageBox::question(this, tr("Remove Fonts"), tr("Would you like to remove all fonts?"),
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
+ if (answer == QMessageBox::No)
+ return;
+
+ QModelIndexList topLevels;
+ for (int i = 0; i < count; i++)
+ topLevels.push_back(m_model->index(i, 0));
+ removeFonts(topLevels, m_model, this);
+}
+
+void AppFontWidget::selectionChanged(const QItemSelection &selected, const QItemSelection & /*deselected*/)
+{
+ m_removeButton->setEnabled(!selected.indexes().empty());
+}
+
+void AppFontWidget::save(QDesignerSettingsInterface *s, const QString &prefix)
+{
+ AppFontManager::instance().save(s, prefix);
+}
+
+void AppFontWidget::restore(const QDesignerSettingsInterface *s, const QString &prefix)
+{
+ AppFontManager::instance().restore(s, prefix);
+}
+
+// ------------ AppFontDialog
+AppFontDialog::AppFontDialog(QWidget *parent) :
+ QDialog(parent),
+ m_appFontWidget(new AppFontWidget)
+{
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setWindowTitle(tr("Additional Fonts"));
+ setModal(false);
+ QVBoxLayout *vl = new QVBoxLayout;
+ vl->addWidget(m_appFontWidget);
+
+ QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close);
+ QDialog::connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
+ vl->addWidget(bb);
+ setLayout(vl);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/appfontdialog.h b/src/designer/src/designer/appfontdialog.h
new file mode 100644
index 000000000..a373217ac
--- /dev/null
+++ b/src/designer/src/designer/appfontdialog.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_APPFONTWIDGET_H
+#define QDESIGNER_APPFONTWIDGET_H
+
+#include <QtGui/QGroupBox>
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class AppFontModel;
+
+class QTreeView;
+class QToolButton;
+class QItemSelection;
+class QDesignerSettingsInterface;
+
+// AppFontWidget: Manages application fonts which the user can load and
+// provides API for saving/restoring them.
+
+class AppFontWidget : public QGroupBox
+{
+ Q_DISABLE_COPY(AppFontWidget)
+ Q_OBJECT
+public:
+ explicit AppFontWidget(QWidget *parent = 0);
+
+ QStringList fontFiles() const;
+
+ static void save(QDesignerSettingsInterface *s, const QString &prefix);
+ static void restore(const QDesignerSettingsInterface *s, const QString &prefix);
+
+private slots:
+ void addFiles();
+ void slotRemoveFiles();
+ void slotRemoveAll();
+ void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
+
+private:
+ QTreeView *m_view;
+ QToolButton *m_addButton;
+ QToolButton *m_removeButton;
+ QToolButton *m_removeAllButton;
+ AppFontModel *m_model;
+};
+
+// AppFontDialog: Non modal dialog for AppFontWidget which has Qt::WA_DeleteOnClose set.
+
+class AppFontDialog : public QDialog
+{
+ Q_DISABLE_COPY(AppFontDialog)
+ Q_OBJECT
+public:
+ explicit AppFontDialog(QWidget *parent = 0);
+
+private:
+ AppFontWidget *m_appFontWidget;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_APPFONTWIDGET_H
diff --git a/src/designer/src/designer/assistantclient.cpp b/src/designer/src/designer/assistantclient.cpp
new file mode 100644
index 000000000..0433c5c51
--- /dev/null
+++ b/src/designer/src/designer/assistantclient.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "assistantclient.h"
+
+#include <QtCore/QString>
+#include <QtCore/QProcess>
+#include <QtCore/QDir>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QObject>
+#include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+enum { debugAssistantClient = 0 };
+
+AssistantClient::AssistantClient() :
+ m_process(0)
+{
+}
+
+AssistantClient::~AssistantClient()
+{
+ if (isRunning()) {
+ m_process->terminate();
+ m_process->waitForFinished();
+ }
+ delete m_process;
+}
+
+bool AssistantClient::showPage(const QString &path, QString *errorMessage)
+{
+ QString cmd = QLatin1String("SetSource ");
+ cmd += path;
+ return sendCommand(cmd, errorMessage);
+}
+
+bool AssistantClient::activateIdentifier(const QString &identifier, QString *errorMessage)
+{
+ QString cmd = QLatin1String("ActivateIdentifier ");
+ cmd += identifier;
+ return sendCommand(cmd, errorMessage);
+}
+
+bool AssistantClient::activateKeyword(const QString &keyword, QString *errorMessage)
+{
+ QString cmd = QLatin1String("ActivateKeyword ");
+ cmd += keyword;
+ return sendCommand(cmd, errorMessage);
+}
+
+bool AssistantClient::sendCommand(const QString &cmd, QString *errorMessage)
+{
+ if (debugAssistantClient)
+ qDebug() << "sendCommand " << cmd;
+ if (!ensureRunning(errorMessage))
+ return false;
+ if (!m_process->isWritable() || m_process->bytesToWrite() > 0) {
+ *errorMessage = QCoreApplication::translate("AssistantClient", "Unable to send request: Assistant is not responding.");
+ return false;
+ }
+ QTextStream str(m_process);
+ str << cmd << QLatin1Char('\n') << endl;
+ return true;
+}
+
+bool AssistantClient::isRunning() const
+{
+ return m_process && m_process->state() != QProcess::NotRunning;
+}
+
+QString AssistantClient::binary()
+{
+ QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator();
+#if !defined(Q_OS_MAC)
+ app += QLatin1String("assistant");
+#else
+ app += QLatin1String("Assistant.app/Contents/MacOS/Assistant");
+#endif
+
+#if defined(Q_OS_WIN)
+ app += QLatin1String(".exe");
+#endif
+
+ return app;
+}
+
+bool AssistantClient::ensureRunning(QString *errorMessage)
+{
+ if (isRunning())
+ return true;
+
+ if (!m_process)
+ m_process = new QProcess;
+
+ const QString app = binary();
+ if (!QFileInfo(app).isFile()) {
+ *errorMessage = QCoreApplication::translate("AssistantClient", "The binary '%1' does not exist.").arg(app);
+ return false;
+ }
+ if (debugAssistantClient)
+ qDebug() << "Running " << app;
+ // run
+ QStringList args(QLatin1String("-enableRemoteControl"));
+ m_process->start(app, args);
+ if (!m_process->waitForStarted()) {
+ *errorMessage = QCoreApplication::translate("AssistantClient", "Unable to launch assistant (%1).").arg(app);
+ return false;
+ }
+ return true;
+}
+
+QString AssistantClient::documentUrl(const QString &prefix, int qtVersion)
+{
+ if (qtVersion == 0)
+ qtVersion = QT_VERSION;
+ QString rc;
+ QTextStream(&rc) << QLatin1String("qthelp://com.trolltech.") << prefix << QLatin1Char('.')
+ << (qtVersion >> 16) << ((qtVersion >> 8) & 0xFF) << (qtVersion & 0xFF)
+ << QLatin1String("/qdoc/");
+ return rc;
+}
+
+QString AssistantClient::designerManualUrl(int qtVersion)
+{
+ return documentUrl(QLatin1String("designer"), qtVersion);
+}
+
+QString AssistantClient::qtReferenceManualUrl(int qtVersion)
+{
+ return documentUrl(QLatin1String("qt"), qtVersion);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/assistantclient.h b/src/designer/src/designer/assistantclient.h
new file mode 100644
index 000000000..67257d191
--- /dev/null
+++ b/src/designer/src/designer/assistantclient.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ASSISTANTCLIENT_H
+#define ASSISTANTCLIENT_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QProcess;
+class QString;
+
+class AssistantClient
+{
+ AssistantClient(const AssistantClient &);
+ AssistantClient &operator=(const AssistantClient &);
+
+public:
+ AssistantClient();
+ ~AssistantClient();
+
+ bool showPage(const QString &path, QString *errorMessage);
+ bool activateIdentifier(const QString &identifier, QString *errorMessage);
+ bool activateKeyword(const QString &keyword, QString *errorMessage);
+
+ bool isRunning() const;
+
+ static QString documentUrl(const QString &prefix, int qtVersion = 0);
+ // Root of the Qt Designer documentation
+ static QString designerManualUrl(int qtVersion = 0);
+ // Root of the Qt Reference documentation
+ static QString qtReferenceManualUrl(int qtVersion = 0);
+
+private:
+ static QString binary();
+ bool sendCommand(const QString &cmd, QString *errorMessage);
+ bool ensureRunning(QString *errorMessage);
+
+ QProcess *m_process;
+};
+
+QT_END_NAMESPACE
+
+#endif // ASSISTANTCLIENT_H
diff --git a/src/designer/src/designer/designer.icns b/src/designer/src/designer/designer.icns
new file mode 100644
index 000000000..9940214fc
--- /dev/null
+++ b/src/designer/src/designer/designer.icns
Binary files differ
diff --git a/src/designer/src/designer/designer.ico b/src/designer/src/designer/designer.ico
new file mode 100644
index 000000000..ef667333d
--- /dev/null
+++ b/src/designer/src/designer/designer.ico
Binary files differ
diff --git a/src/designer/src/designer/designer.pro b/src/designer/src/designer/designer.pro
new file mode 100644
index 000000000..8564e96cb
--- /dev/null
+++ b/src/designer/src/designer/designer.pro
@@ -0,0 +1,90 @@
+
+DESTDIR = ../../../../bin
+QT += xml network
+contains(QT_CONFIG, script): QT += script
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+INCLUDEPATH += \
+ ../lib/sdk \
+ ../lib/extension \
+ ../lib/shared \
+ ../lib/uilib \
+ extra
+
+QMAKE_LIBDIR += ../../lib ../../../../lib
+LIBS += -lQtDesignerComponents -lQtDesigner
+
+RESOURCES += designer.qrc
+
+contains(CONFIG, static) {
+ DEFINES += QT_DESIGNER_STATIC
+}
+
+TARGET = designer
+
+include(../../../shared/fontpanel/fontpanel.pri)
+include(../../../shared/qttoolbardialog/qttoolbardialog.pri)
+
+HEADERS += \
+ qdesigner.h \
+ qdesigner_toolwindow.h \
+ qdesigner_formwindow.h \
+ qdesigner_workbench.h \
+ qdesigner_settings.h \
+ qdesigner_actions.h \
+ qdesigner_server.h \
+ qdesigner_appearanceoptions.h \
+ saveformastemplate.h \
+ newform.h \
+ versiondialog.h \
+ designer_enums.h \
+ appfontdialog.h \
+ preferencesdialog.h \
+ assistantclient.h \
+ mainwindow.h
+
+SOURCES += main.cpp \
+ qdesigner.cpp \
+ qdesigner_toolwindow.cpp \
+ qdesigner_formwindow.cpp \
+ qdesigner_workbench.cpp \
+ qdesigner_settings.cpp \
+ qdesigner_server.cpp \
+ qdesigner_actions.cpp \
+ qdesigner_appearanceoptions.cpp \
+ saveformastemplate.cpp \
+ newform.cpp \
+ versiondialog.cpp \
+ appfontdialog.cpp \
+ preferencesdialog.cpp \
+ assistantclient.cpp \
+ mainwindow.cpp
+
+PRECOMPILED_HEADER=qdesigner_pch.h
+
+FORMS += saveformastemplate.ui \
+ preferencesdialog.ui \
+ qdesigner_appearanceoptions.ui
+
+win32 {
+ RC_FILE = designer.rc
+}
+
+mac {
+ ICON = designer.icns
+ QMAKE_INFO_PLIST = Info_mac.plist
+ TARGET = Designer
+ FILETYPES.files = uifile.icns
+ FILETYPES.path = Contents/Resources
+ QMAKE_BUNDLE_DATA += FILETYPES
+}
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+include(../sharedcomponents.pri)
+
+unix:!mac:LIBS += -lm
diff --git a/src/designer/src/designer/designer.qrc b/src/designer/src/designer/designer.qrc
new file mode 100644
index 000000000..fac8120d0
--- /dev/null
+++ b/src/designer/src/designer/designer.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/trolltech/designer">
+ <file>images/designer.png</file>
+ </qresource>
+</RCC>
diff --git a/src/designer/src/designer/designer.rc b/src/designer/src/designer/designer.rc
new file mode 100644
index 000000000..9c396b555
--- /dev/null
+++ b/src/designer/src/designer/designer.rc
@@ -0,0 +1,32 @@
+#include "winver.h"
+
+IDI_ICON1 ICON DISCARDABLE "designer.ico"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGS 0x0L
+ FILEFLAGSMASK 0x3fL
+ FILEOS 0x00040004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)"
+ VALUE "FileDescription", "Qt Designer"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+ VALUE "InternalName", "designer"
+ VALUE "OriginalFilename", "designer.exe"
+ VALUE "ProductName", "Qt Designer"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/src/designer/src/designer/designer_enums.h b/src/designer/src/designer/designer_enums.h
new file mode 100644
index 000000000..ca115c37a
--- /dev/null
+++ b/src/designer/src/designer/designer_enums.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERENUMS_H
+#define DESIGNERENUMS_H
+
+enum UIMode
+{
+ NeutralMode,
+ TopLevelMode,
+ DockedMode
+};
+
+#endif // DESIGNERENUMS_H
diff --git a/src/designer/src/designer/images/designer.png b/src/designer/src/designer/images/designer.png
new file mode 100644
index 000000000..0988fcee3
--- /dev/null
+++ b/src/designer/src/designer/images/designer.png
Binary files differ
diff --git a/src/designer/src/designer/images/mdi.png b/src/designer/src/designer/images/mdi.png
new file mode 100644
index 000000000..5012ab304
--- /dev/null
+++ b/src/designer/src/designer/images/mdi.png
Binary files differ
diff --git a/src/designer/src/designer/images/sdi.png b/src/designer/src/designer/images/sdi.png
new file mode 100644
index 000000000..7fff6e8b6
--- /dev/null
+++ b/src/designer/src/designer/images/sdi.png
Binary files differ
diff --git a/src/designer/src/designer/images/workbench.png b/src/designer/src/designer/images/workbench.png
new file mode 100644
index 000000000..06716a44f
--- /dev/null
+++ b/src/designer/src/designer/images/workbench.png
Binary files differ
diff --git a/src/designer/src/designer/main.cpp b/src/designer/src/designer/main.cpp
new file mode 100644
index 000000000..8a5b5c044
--- /dev/null
+++ b/src/designer/src/designer/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner.h"
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDir>
+
+#include <stdlib.h>
+
+QT_USE_NAMESPACE
+
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(designer);
+
+ QDesigner app(argc, argv);
+ app.setQuitOnLastWindowClosed(false);
+
+ return app.exec();
+}
diff --git a/src/designer/src/designer/mainwindow.cpp b/src/designer/src/designer/mainwindow.cpp
new file mode 100644
index 000000000..67e1a4053
--- /dev/null
+++ b/src/designer/src/designer/mainwindow.cpp
@@ -0,0 +1,419 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "qdesigner.h"
+#include "qdesigner_actions.h"
+#include "qdesigner_workbench.h"
+#include "qdesigner_formwindow.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_settings.h"
+#include "qttoolbardialog.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QToolBar>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QStatusBar>
+#include <QtGui/QMenu>
+#include <QtGui/QLayout>
+#include <QtGui/QDockWidget>
+
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+
+static const char *uriListMimeFormatC = "text/uri-list";
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<QAction *> ActionList;
+
+// Helpers for creating toolbars and menu
+
+static void addActionsToToolBar(const ActionList &actions, QToolBar *t)
+{
+ const ActionList::const_iterator cend = actions.constEnd();
+ for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it) {
+ QAction *action = *it;
+ if (action->property(QDesignerActions::defaultToolbarPropertyName).toBool())
+ t->addAction(action);
+ }
+}
+static QToolBar *createToolBar(const QString &title, const QString &objectName, const ActionList &actions)
+{
+ QToolBar *rc = new QToolBar;
+ rc->setObjectName(objectName);
+ rc->setWindowTitle(title);
+ addActionsToToolBar(actions, rc);
+ return rc;
+}
+
+// ---------------- MainWindowBase
+
+MainWindowBase::MainWindowBase(QWidget *parent, Qt::WindowFlags flags) :
+ QMainWindow(parent, flags),
+ m_policy(AcceptCloseEvents)
+{
+#ifndef Q_WS_MAC
+ setWindowIcon(qDesigner->windowIcon());
+#endif
+}
+
+void MainWindowBase::closeEvent(QCloseEvent *e)
+{
+ switch (m_policy) {
+ case AcceptCloseEvents:
+ QMainWindow::closeEvent(e);
+ break;
+ case EmitCloseEventSignal:
+ emit closeEventReceived(e);
+ break;
+ }
+}
+
+QList<QToolBar *> MainWindowBase::createToolBars(const QDesignerActions *actions, bool singleToolBar)
+{
+ // Note that whenever you want to add a new tool bar here, you also have to update the default
+ // action groups added to the toolbar manager in the mainwindow constructor
+ QList<QToolBar *> rc;
+ if (singleToolBar) {
+ //: Not currently used (main tool bar)
+ QToolBar *main = createToolBar(tr("Main"), QLatin1String("mainToolBar"), actions->fileActions()->actions());
+ addActionsToToolBar(actions->editActions()->actions(), main);
+ addActionsToToolBar(actions->toolActions()->actions(), main);
+ addActionsToToolBar(actions->formActions()->actions(), main);
+ rc.push_back(main);
+ } else {
+ rc.push_back(createToolBar(tr("File"), QLatin1String("fileToolBar"), actions->fileActions()->actions()));
+ rc.push_back(createToolBar(tr("Edit"), QLatin1String("editToolBar"), actions->editActions()->actions()));
+ rc.push_back(createToolBar(tr("Tools"), QLatin1String("toolsToolBar"), actions->toolActions()->actions()));
+ rc.push_back(createToolBar(tr("Form"), QLatin1String("formToolBar"), actions->formActions()->actions()));
+ }
+ return rc;
+}
+
+QString MainWindowBase::mainWindowTitle()
+{
+ return tr("Qt Designer");
+}
+
+// Use the minor Qt version as settings versions to avoid conflicts
+int MainWindowBase::settingsVersion()
+{
+ const int version = QT_VERSION;
+ return (version & 0x00FF00) >> 8;
+}
+
+// ----------------- DockedMdiArea
+
+DockedMdiArea::DockedMdiArea(const QString &extension, QWidget *parent) :
+ QMdiArea(parent),
+ m_extension(extension)
+{
+ setAcceptDrops(true);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+}
+
+QStringList DockedMdiArea::uiFiles(const QMimeData *d) const
+{
+ // Extract dropped UI files from Mime data.
+ QStringList rc;
+ if (!d->hasFormat(QLatin1String(uriListMimeFormatC)))
+ return rc;
+ const QList<QUrl> urls = d->urls();
+ if (urls.empty())
+ return rc;
+ const QList<QUrl>::const_iterator cend = urls.constEnd();
+ for (QList<QUrl>::const_iterator it = urls.constBegin(); it != cend; ++it) {
+ const QString fileName = it->toLocalFile();
+ if (!fileName.isEmpty() && fileName.endsWith(m_extension))
+ rc.push_back(fileName);
+ }
+ return rc;
+}
+
+bool DockedMdiArea::event(QEvent *event)
+{
+ // Listen for desktop file manager drop and emit a signal once a file is
+ // dropped.
+ switch (event->type()) {
+ case QEvent::DragEnter: {
+ QDragEnterEvent *e = static_cast<QDragEnterEvent*>(event);
+ if (!uiFiles(e->mimeData()).empty()) {
+ e->acceptProposedAction();
+ return true;
+ }
+ }
+ break;
+ case QEvent::Drop: {
+ QDropEvent *e = static_cast<QDropEvent*>(event);
+ const QStringList files = uiFiles(e->mimeData());
+ const QStringList::const_iterator cend = files.constEnd();
+ for (QStringList::const_iterator it = files.constBegin(); it != cend; ++it) {
+ emit fileDropped(*it);
+ }
+ e->acceptProposedAction();
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ return QMdiArea::event(event);
+}
+
+// ------------- ToolBarManager:
+
+static void addActionsToToolBarManager(const ActionList &al, const QString &title, QtToolBarManager *tbm)
+{
+ const ActionList::const_iterator cend = al.constEnd();
+ for (ActionList::const_iterator it = al.constBegin(); it != cend; ++it)
+ tbm->addAction(*it, title);
+}
+
+ToolBarManager::ToolBarManager(QMainWindow *configureableMainWindow,
+ QWidget *parent,
+ QMenu *toolBarMenu,
+ const QDesignerActions *actions,
+ const QList<QToolBar *> &toolbars,
+ const QList<QDesignerToolWindow*> &toolWindows) :
+ QObject(parent),
+ m_configureableMainWindow(configureableMainWindow),
+ m_parent(parent),
+ m_toolBarMenu(toolBarMenu),
+ m_manager(new QtToolBarManager(this)),
+ m_configureAction(new QAction(tr("Configure Toolbars..."), this)),
+ m_toolbars(toolbars)
+{
+ m_configureAction->setMenuRole(QAction::NoRole);
+ m_configureAction->setObjectName(QLatin1String("__qt_configure_tool_bars_action"));
+ connect(m_configureAction, SIGNAL(triggered()), this, SLOT(configureToolBars()));
+
+ m_manager->setMainWindow(configureableMainWindow);
+
+ foreach(QToolBar *tb, m_toolbars) {
+ const QString title = tb->windowTitle();
+ m_manager->addToolBar(tb, title);
+ addActionsToToolBarManager(tb->actions(), title, m_manager);
+ }
+
+ addActionsToToolBarManager(actions->windowActions()->actions(), tr("Window"), m_manager);
+ addActionsToToolBarManager(actions->helpActions()->actions(), tr("Help"), m_manager);
+
+ // Filter out the device profile preview actions which have int data().
+ ActionList previewActions = actions->styleActions()->actions();
+ ActionList::iterator it = previewActions.begin();
+ for ( ; (*it)->isSeparator() || (*it)->data().type() == QVariant::Int; ++it) ;
+ previewActions.erase(previewActions.begin(), it);
+ addActionsToToolBarManager(previewActions, tr("Style"), m_manager);
+
+ const QString dockTitle = tr("Dock views");
+ foreach (QDesignerToolWindow *tw, toolWindows) {
+ if (QAction *action = tw->action())
+ m_manager->addAction(action, dockTitle);
+ }
+
+ QString category(tr("File"));
+ foreach(QAction *action, actions->fileActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Edit");
+ foreach(QAction *action, actions->editActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Tools");
+ foreach(QAction *action, actions->toolActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Form");
+ foreach(QAction *action, actions->formActions()->actions())
+ m_manager->addAction(action, category);
+
+ m_manager->addAction(m_configureAction, tr("Toolbars"));
+ updateToolBarMenu();
+}
+
+// sort function for sorting tool bars alphabetically by title [non-static since called from template]
+
+bool toolBarTitleLessThan(const QToolBar *t1, const QToolBar *t2)
+{
+ return t1->windowTitle() < t2->windowTitle();
+}
+
+void ToolBarManager::updateToolBarMenu()
+{
+ // Sort tool bars alphabetically by title
+ qStableSort(m_toolbars.begin(), m_toolbars.end(), toolBarTitleLessThan);
+ // add to menu
+ m_toolBarMenu->clear();
+ foreach (QToolBar *tb, m_toolbars)
+ m_toolBarMenu->addAction(tb->toggleViewAction());
+ m_toolBarMenu->addAction(m_configureAction);
+}
+
+void ToolBarManager::configureToolBars()
+{
+ QtToolBarDialog dlg(m_parent);
+ dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ dlg.setToolBarManager(m_manager);
+ dlg.exec();
+ updateToolBarMenu();
+}
+
+QByteArray ToolBarManager::saveState(int version) const
+{
+ return m_manager->saveState(version);
+}
+
+bool ToolBarManager::restoreState(const QByteArray &state, int version)
+{
+ return m_manager->restoreState(state, version);
+}
+
+// ---------- DockedMainWindow
+
+DockedMainWindow::DockedMainWindow(QDesignerWorkbench *wb,
+ QMenu *toolBarMenu,
+ const QList<QDesignerToolWindow*> &toolWindows) :
+ m_toolBarManager(0)
+{
+ setObjectName(QLatin1String("MDIWindow"));
+ setWindowTitle(mainWindowTitle());
+
+ const QList<QToolBar *> toolbars = createToolBars(wb->actionManager(), false);
+ foreach (QToolBar *tb, toolbars)
+ addToolBar(tb);
+ DockedMdiArea *dma = new DockedMdiArea(wb->actionManager()->uiExtension());
+ connect(dma, SIGNAL(fileDropped(QString)),
+ this, SIGNAL(fileDropped(QString)));
+ connect(dma, SIGNAL(subWindowActivated(QMdiSubWindow*)),
+ this, SLOT(slotSubWindowActivated(QMdiSubWindow*)));
+ setCentralWidget(dma);
+
+ QStatusBar *sb = statusBar();
+ Q_UNUSED(sb)
+
+ m_toolBarManager = new ToolBarManager(this, this, toolBarMenu, wb->actionManager(), toolbars, toolWindows);
+}
+
+QMdiArea *DockedMainWindow::mdiArea() const
+{
+ return static_cast<QMdiArea *>(centralWidget());
+}
+
+void DockedMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow)
+{
+ if (subWindow) {
+ QWidget *widget = subWindow->widget();
+ if (QDesignerFormWindow *fw = qobject_cast<QDesignerFormWindow*>(widget)) {
+ emit formWindowActivated(fw);
+ mdiArea()->setActiveSubWindow(subWindow);
+ }
+ }
+}
+
+// Create a MDI subwindow for the form.
+QMdiSubWindow *DockedMainWindow::createMdiSubWindow(QWidget *fw, Qt::WindowFlags f, const QKeySequence &designerCloseActionShortCut)
+{
+ QMdiSubWindow *rc = mdiArea()->addSubWindow(fw, f);
+ // Make action shortcuts respond only if focused to avoid conflicts with
+ // designer menu actions
+ if (designerCloseActionShortCut == QKeySequence(QKeySequence::Close)) {
+ const ActionList systemMenuActions = rc->systemMenu()->actions();
+ if (!systemMenuActions.empty()) {
+ const ActionList::const_iterator cend = systemMenuActions.constEnd();
+ for (ActionList::const_iterator it = systemMenuActions.constBegin(); it != cend; ++it) {
+ if ( (*it)->shortcut() == designerCloseActionShortCut) {
+ (*it)->setShortcutContext(Qt::WidgetShortcut);
+ break;
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+DockedMainWindow::DockWidgetList DockedMainWindow::addToolWindows(const DesignerToolWindowList &tls)
+{
+ DockWidgetList rc;
+ foreach (QDesignerToolWindow *tw, tls) {
+ QDockWidget *dockWidget = new QDockWidget;
+ dockWidget->setObjectName(tw->objectName() + QLatin1String("_dock"));
+ dockWidget->setWindowTitle(tw->windowTitle());
+ addDockWidget(tw->dockWidgetAreaHint(), dockWidget);
+ dockWidget->setWidget(tw);
+ rc.push_back(dockWidget);
+ }
+ return rc;
+}
+
+// Settings consist of MainWindow state and tool bar manager state
+void DockedMainWindow::restoreSettings(const QDesignerSettings &s, const DockWidgetList &dws, const QRect &desktopArea)
+{
+ const int version = settingsVersion();
+ m_toolBarManager->restoreState(s.toolBarsState(DockedMode), version);
+
+ // If there are no old geometry settings, show the window maximized
+ s.restoreGeometry(this, QRect(desktopArea.topLeft(), QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)));
+
+ const QByteArray mainWindowState = s.mainWindowState(DockedMode);
+ const bool restored = !mainWindowState.isEmpty() && restoreState(mainWindowState, version);
+ if (!restored) {
+ // Default: Tabify less relevant windows bottom/right.
+ tabifyDockWidget(dws.at(QDesignerToolWindow::SignalSlotEditor),
+ dws.at(QDesignerToolWindow::ActionEditor));
+ tabifyDockWidget(dws.at(QDesignerToolWindow::ActionEditor),
+ dws.at(QDesignerToolWindow::ResourceEditor));
+ }
+}
+
+void DockedMainWindow::saveSettings(QDesignerSettings &s) const
+{
+ const int version = settingsVersion();
+ s.setToolBarsState(DockedMode, m_toolBarManager->saveState(version));
+ s.saveGeometryFor(this);
+ s.setMainWindowState(DockedMode, saveState(version));
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/mainwindow.h b/src/designer/src/designer/mainwindow.h
new file mode 100644
index 000000000..e39e57203
--- /dev/null
+++ b/src/designer/src/designer/mainwindow.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtGui/QMainWindow>
+#include <QtCore/QList>
+#include <QtGui/QMdiArea>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerActions;
+class QDesignerWorkbench;
+class QDesignerToolWindow;
+class QDesignerFormWindow;
+class QDesignerSettings;
+
+class QtToolBarManager;
+class QToolBar;
+class QMdiArea;
+class QMenu;
+class QByteArray;
+class QMimeData;
+
+/* A main window that has a configureable policy on handling close events. If
+ * enabled, it can forward the close event to external handlers.
+ * Base class for windows that can switch roles between tool windows
+ * and main windows. */
+
+class MainWindowBase: public QMainWindow
+{
+ Q_DISABLE_COPY(MainWindowBase)
+ Q_OBJECT
+protected:
+ explicit MainWindowBase(QWidget *parent = 0, Qt::WindowFlags flags = Qt::Window);
+
+public:
+ enum CloseEventPolicy {
+ /* Always accept close events */
+ AcceptCloseEvents,
+ /* Emit a signal with the event, have it handled elsewhere */
+ EmitCloseEventSignal };
+
+ CloseEventPolicy closeEventPolicy() const { return m_policy; }
+ void setCloseEventPolicy(CloseEventPolicy pol) { m_policy = pol; }
+
+ static QList<QToolBar *> createToolBars(const QDesignerActions *actions, bool singleToolBar);
+ static QString mainWindowTitle();
+
+ // Use the minor Qt version as settings versions to avoid conflicts
+ static int settingsVersion();
+
+signals:
+ void closeEventReceived(QCloseEvent *e);
+
+protected:
+ virtual void closeEvent(QCloseEvent *e);
+private:
+ CloseEventPolicy m_policy;
+};
+
+/* An MdiArea that listens for desktop file manager file drop events and emits
+ * a signal to open a dropped file. */
+class DockedMdiArea : public QMdiArea
+{
+ Q_DISABLE_COPY(DockedMdiArea)
+ Q_OBJECT
+public:
+ explicit DockedMdiArea(const QString &extension, QWidget *parent = 0);
+
+signals:
+ void fileDropped(const QString &);
+
+protected:
+ bool event (QEvent *event);
+
+private:
+ QStringList uiFiles(const QMimeData *d) const;
+
+ const QString m_extension;
+};
+
+// Convenience class that manages a QtToolBarManager and an action to trigger
+// it on a mainwindow.
+class ToolBarManager : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(ToolBarManager)
+public:
+ explicit ToolBarManager(QMainWindow *configureableMainWindow,
+ QWidget *parent,
+ QMenu *toolBarMenu,
+ const QDesignerActions *actions,
+ const QList<QToolBar *> &toolbars,
+ const QList<QDesignerToolWindow*> &toolWindows);
+
+ QByteArray saveState(int version = 0) const;
+ bool restoreState(const QByteArray &state, int version = 0);
+
+private slots:
+ void configureToolBars();
+ void updateToolBarMenu();
+
+private:
+ QMainWindow *m_configureableMainWindow;
+ QWidget *m_parent;
+ QMenu *m_toolBarMenu;
+ QtToolBarManager *m_manager;
+ QAction *m_configureAction;
+ QList<QToolBar *> m_toolbars;
+};
+
+/* Main window to be used for docked mode */
+class DockedMainWindow : public MainWindowBase {
+ Q_OBJECT
+ Q_DISABLE_COPY(DockedMainWindow)
+public:
+ typedef QList<QDesignerToolWindow*> DesignerToolWindowList;
+ typedef QList<QDockWidget *> DockWidgetList;
+
+ explicit DockedMainWindow(QDesignerWorkbench *wb,
+ QMenu *toolBarMenu,
+ const DesignerToolWindowList &toolWindows);
+
+ // Create a MDI subwindow for the form.
+ QMdiSubWindow *createMdiSubWindow(QWidget *fw, Qt::WindowFlags f, const QKeySequence &designerCloseActionShortCut);
+
+ QMdiArea *mdiArea() const;
+
+ DockWidgetList addToolWindows(const DesignerToolWindowList &toolWindows);
+
+ void restoreSettings(const QDesignerSettings &s, const DockWidgetList &dws, const QRect &desktopArea);
+ void saveSettings(QDesignerSettings &) const;
+
+signals:
+ void fileDropped(const QString &);
+ void formWindowActivated(QDesignerFormWindow *);
+
+private slots:
+ void slotSubWindowActivated(QMdiSubWindow*);
+
+private:
+ ToolBarManager *m_toolBarManager;
+};
+
+QT_END_NAMESPACE
+
+#endif // MAINWINDOW_H
diff --git a/src/designer/src/designer/newform.cpp b/src/designer/src/designer/newform.cpp
new file mode 100644
index 000000000..34461f52a
--- /dev/null
+++ b/src/designer/src/designer/newform.cpp
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "newform.h"
+#include "qdesigner_workbench.h"
+#include "qdesigner_actions.h"
+#include "qdesigner_formwindow.h"
+#include "qdesigner_settings.h"
+
+#include <newformwidget_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QTemporaryFile>
+
+#include <QtGui/QApplication>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QMenu>
+#include <QtGui/QCheckBox>
+#include <QtGui/QFrame>
+#include <QtGui/QMessageBox>
+
+QT_BEGIN_NAMESPACE
+
+NewForm::NewForm(QDesignerWorkbench *workbench, QWidget *parentWidget, const QString &fileName)
+ : QDialog(parentWidget,
+#ifdef Q_WS_MAC
+ Qt::Tool |
+#endif
+ Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
+ m_fileName(fileName),
+ m_newFormWidget(QDesignerNewFormWidgetInterface::createNewFormWidget(workbench->core())),
+ m_workbench(workbench),
+ m_chkShowOnStartup(new QCheckBox(tr("Show this Dialog on Startup"))),
+ m_createButton(new QPushButton(QApplication::translate("NewForm", "C&reate", 0, QApplication::UnicodeUTF8))),
+ m_recentButton(new QPushButton(QApplication::translate("NewForm", "Recent", 0, QApplication::UnicodeUTF8))),
+ m_buttonBox(0)
+{
+ setWindowTitle(tr("New Form"));
+ QDesignerSettings settings(m_workbench->core());
+
+ QVBoxLayout *vBoxLayout = new QVBoxLayout;
+
+ connect(m_newFormWidget, SIGNAL(templateActivated()), this, SLOT(slotTemplateActivated()));
+ connect(m_newFormWidget, SIGNAL(currentTemplateChanged(bool)), this, SLOT(slotCurrentTemplateChanged(bool)));
+ vBoxLayout->addWidget(m_newFormWidget);
+
+ QFrame *horizontalLine = new QFrame;
+ horizontalLine->setFrameShape(QFrame::HLine);
+ horizontalLine->setFrameShadow(QFrame::Sunken);
+ vBoxLayout->addWidget(horizontalLine);
+
+ m_chkShowOnStartup->setChecked(settings.showNewFormOnStartup());
+ vBoxLayout->addWidget(m_chkShowOnStartup);
+
+ m_buttonBox = createButtonBox();
+ vBoxLayout->addWidget(m_buttonBox);
+ setLayout(vBoxLayout);
+
+ resize(500, 400);
+ slotCurrentTemplateChanged(m_newFormWidget->hasCurrentTemplate());
+}
+
+QDialogButtonBox *NewForm::createButtonBox()
+{
+ // Dialog buttons with 'recent files'
+ QDialogButtonBox *buttonBox = new QDialogButtonBox;
+ buttonBox->addButton(QApplication::translate("NewForm", "&Close", 0,
+ QApplication::UnicodeUTF8), QDialogButtonBox::RejectRole);
+ buttonBox->addButton(m_createButton, QDialogButtonBox::AcceptRole);
+ buttonBox->addButton(QApplication::translate("NewForm", "&Open...", 0,
+ QApplication::UnicodeUTF8), QDialogButtonBox::ActionRole);
+ buttonBox->addButton(m_recentButton, QDialogButtonBox::ActionRole);
+ QDesignerActions *da = m_workbench->actionManager();
+ QMenu *recentFilesMenu = new QMenu(tr("&Recent Forms"), m_recentButton);
+ // Pop the "Recent Files" stuff in here.
+ const QList<QAction *> recentActions = da->recentFilesActions()->actions();
+ if (!recentActions.empty()) {
+ const QList<QAction *>::const_iterator acend = recentActions.constEnd();
+ for (QList<QAction *>::const_iterator it = recentActions.constBegin(); it != acend; ++it) {
+ recentFilesMenu->addAction(*it);
+ connect(*it, SIGNAL(triggered()), this, SLOT(recentFileChosen()));
+ }
+ }
+ m_recentButton->setMenu(recentFilesMenu);
+ connect(buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(slotButtonBoxClicked(QAbstractButton*)));
+ return buttonBox;
+}
+
+NewForm::~NewForm()
+{
+ QDesignerSettings settings (m_workbench->core());
+ settings.setShowNewFormOnStartup(m_chkShowOnStartup->isChecked());
+}
+
+void NewForm::recentFileChosen()
+{
+ QAction *action = qobject_cast<QAction *>(sender());
+ if (!action)
+ return;
+ if (action->objectName() == QLatin1String("__qt_action_clear_menu_"))
+ return;
+ close();
+}
+
+void NewForm::slotCurrentTemplateChanged(bool templateSelected)
+{
+ if (templateSelected) {
+ m_createButton->setEnabled(true);
+ m_createButton->setDefault(true);
+ } else {
+ m_createButton->setEnabled(false);
+ }
+}
+
+void NewForm::slotTemplateActivated()
+{
+ m_createButton->animateClick(0);
+}
+
+void NewForm::slotButtonBoxClicked(QAbstractButton *btn)
+{
+ switch (m_buttonBox->buttonRole(btn)) {
+ case QDialogButtonBox::RejectRole:
+ reject();
+ break;
+ case QDialogButtonBox::ActionRole:
+ if (btn != m_recentButton) {
+ m_fileName.clear();
+ if (m_workbench->actionManager()->openForm(this))
+ accept();
+ }
+ break;
+ case QDialogButtonBox::AcceptRole: {
+ QString errorMessage;
+ if (openTemplate(&errorMessage)) {
+ accept();
+ } else {
+ QMessageBox::warning(this, tr("Read error"), errorMessage);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+bool NewForm::openTemplate(QString *ptrToErrorMessage)
+{
+ const QString contents = m_newFormWidget->currentTemplate(ptrToErrorMessage);
+ if (contents.isEmpty())
+ return false;
+ // Write to temporary file and open
+ QString tempPattern = QDir::tempPath();
+ if (!tempPattern.endsWith(QDir::separator())) // platform-dependant
+ tempPattern += QDir::separator();
+ tempPattern += QLatin1String("XXXXXX.ui");
+ QTemporaryFile tempFormFile(tempPattern);
+
+ tempFormFile.setAutoRemove(true);
+ if (!tempFormFile.open()) {
+ *ptrToErrorMessage = tr("A temporary form file could not be created in %1.").arg(QDir::tempPath());
+ return false;
+ }
+ const QString tempFormFileName = tempFormFile.fileName();
+ tempFormFile.write(contents.toUtf8());
+ if (!tempFormFile.flush()) {
+ *ptrToErrorMessage = tr("The temporary form file %1 could not be written.").arg(tempFormFileName);
+ return false;
+ }
+ tempFormFile.close();
+ return m_workbench->openTemplate(tempFormFileName, m_fileName, ptrToErrorMessage);
+}
+
+QImage NewForm::grabForm(QDesignerFormEditorInterface *core,
+ QIODevice &file,
+ const QString &workingDir,
+ const qdesigner_internal::DeviceProfile &dp)
+{
+ return qdesigner_internal::NewFormWidget::grabForm(core, file, workingDir, dp);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/newform.h b/src/designer/src/designer/newform.h
new file mode 100644
index 000000000..ad51118b9
--- /dev/null
+++ b/src/designer/src/designer/newform.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEWFORM_H
+#define NEWFORM_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ class DeviceProfile;
+}
+
+class QDesignerFormEditorInterface;
+class QDesignerNewFormWidgetInterface;
+class QDesignerWorkbench;
+
+class QCheckBox;
+class QAbstractButton;
+class QPushButton;
+class QDialogButtonBox;
+class QImage;
+class QIODevice;
+
+class NewForm: public QDialog
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(NewForm)
+
+public:
+ NewForm(QDesignerWorkbench *workbench,
+ QWidget *parentWidget,
+ // Use that file name instead of a temporary one
+ const QString &fileName = QString());
+
+ virtual ~NewForm();
+
+ // Convenience for implementing file dialogs with preview
+ static QImage grabForm(QDesignerFormEditorInterface *core,
+ QIODevice &file,
+ const QString &workingDir,
+ const qdesigner_internal::DeviceProfile &dp);
+
+private slots:
+ void slotButtonBoxClicked(QAbstractButton *btn);
+ void recentFileChosen();
+ void slotCurrentTemplateChanged(bool templateSelected);
+ void slotTemplateActivated();
+
+private:
+ QDialogButtonBox *createButtonBox();
+ bool openTemplate(QString *ptrToErrorMessage);
+
+ QString m_fileName;
+ QDesignerNewFormWidgetInterface *m_newFormWidget;
+ QDesignerWorkbench *m_workbench;
+ QCheckBox *m_chkShowOnStartup;
+ QPushButton *m_createButton;
+ QPushButton *m_recentButton;
+ QDialogButtonBox *m_buttonBox;
+};
+
+QT_END_NAMESPACE
+
+#endif // NEWFORM_H
diff --git a/src/designer/src/designer/preferencesdialog.cpp b/src/designer/src/designer/preferencesdialog.cpp
new file mode 100644
index 000000000..a27e366a5
--- /dev/null
+++ b/src/designer/src/designer/preferencesdialog.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "preferencesdialog.h"
+#include "ui_preferencesdialog.h"
+#include "qdesigner_appearanceoptions.h"
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtGui/QFileDialog>
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+PreferencesDialog::PreferencesDialog(QDesignerFormEditorInterface *core, QWidget *parentWidget) :
+ QDialog(parentWidget),
+ m_ui(new Ui::PreferencesDialog()),
+ m_core(core)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ m_ui->setupUi(this);
+
+ m_optionsPages = core->optionsPages();
+
+ m_ui->m_optionTabWidget->clear();
+ foreach (QDesignerOptionsPageInterface *optionsPage, m_optionsPages) {
+ QWidget *page = optionsPage->createPage(this);
+ m_ui->m_optionTabWidget->addTab(page, optionsPage->name());
+ if (QDesignerAppearanceOptionsWidget *appearanceWidget = qobject_cast<QDesignerAppearanceOptionsWidget *>(page))
+ connect(appearanceWidget, SIGNAL(uiModeChanged(bool)), this, SLOT(slotUiModeChanged(bool)));
+ }
+
+ connect(m_ui->m_dialogButtonBox, SIGNAL(rejected()), this, SLOT(slotRejected()));
+ connect(m_ui->m_dialogButtonBox, SIGNAL(accepted()), this, SLOT(slotAccepted()));
+ connect(applyButton(), SIGNAL(clicked()), this, SLOT(slotApply()));
+}
+
+PreferencesDialog::~PreferencesDialog()
+{
+ delete m_ui;
+}
+
+QPushButton *PreferencesDialog::applyButton() const
+{
+ return m_ui->m_dialogButtonBox->button(QDialogButtonBox::Apply);
+}
+
+void PreferencesDialog::slotApply()
+{
+ foreach (QDesignerOptionsPageInterface *optionsPage, m_optionsPages)
+ optionsPage->apply();
+}
+
+void PreferencesDialog::slotAccepted()
+{
+ slotApply();
+ closeOptionPages();
+ accept();
+}
+
+void PreferencesDialog::slotRejected()
+{
+ closeOptionPages();
+ reject();
+}
+
+void PreferencesDialog::slotUiModeChanged(bool modified)
+{
+ // Cannot "apply" a ui mode change (destroy the dialogs parent)
+ applyButton()->setEnabled(!modified);
+}
+
+void PreferencesDialog::closeOptionPages()
+{
+ foreach (QDesignerOptionsPageInterface *optionsPage, m_optionsPages)
+ optionsPage->finish();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/preferencesdialog.h b/src/designer/src/designer/preferencesdialog.h
new file mode 100644
index 000000000..5ffd7d365
--- /dev/null
+++ b/src/designer/src/designer/preferencesdialog.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREFERENCESDIALOG_H
+#define PREFERENCESDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QPushButton;
+class QDesignerFormEditorInterface;
+class QDesignerOptionsPageInterface;
+
+namespace Ui {
+ class PreferencesDialog;
+}
+
+class PreferencesDialog: public QDialog
+{
+ Q_OBJECT
+public:
+ explicit PreferencesDialog(QDesignerFormEditorInterface *core, QWidget *parentWidget = 0);
+ ~PreferencesDialog();
+
+
+private slots:
+ void slotAccepted();
+ void slotRejected();
+ void slotApply();
+ void slotUiModeChanged(bool modified);
+
+private:
+ QPushButton *applyButton() const;
+ void closeOptionPages();
+
+ Ui::PreferencesDialog *m_ui;
+ QDesignerFormEditorInterface *m_core;
+ QList<QDesignerOptionsPageInterface*> m_optionsPages;
+};
+
+QT_END_NAMESPACE
+
+#endif // PREFERENCESDIALOG_H
diff --git a/src/designer/src/designer/preferencesdialog.ui b/src/designer/src/designer/preferencesdialog.ui
new file mode 100644
index 000000000..28d14bb83
--- /dev/null
+++ b/src/designer/src/designer/preferencesdialog.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PreferencesDialog</class>
+ <widget class="QDialog" name="PreferencesDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>474</width>
+ <height>304</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Preferences</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="m_optionTabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string notr="true">Tab 1</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="m_dialogButtonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Apply|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>m_dialogButtonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>PreferencesDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>m_dialogButtonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>PreferencesDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/designer/qdesigner.cpp b/src/designer/src/designer/qdesigner.cpp
new file mode 100644
index 000000000..1e838c197
--- /dev/null
+++ b/src/designer/src/designer/qdesigner.cpp
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// designer
+#include "qdesigner.h"
+#include "qdesigner_actions.h"
+#include "qdesigner_server.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_workbench.h"
+#include "mainwindow.h"
+
+#include <qdesigner_propertysheet_p.h>
+
+#include <QtGui/QFileOpenEvent>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QMessageBox>
+#include <QtGui/QIcon>
+#include <QtGui/QErrorMessage>
+#include <QtCore/QMetaObject>
+#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QLocale>
+#include <QtCore/QTimer>
+#include <QtCore/QTranslator>
+#include <QtCore/QFileInfo>
+#include <QtCore/qdebug.h>
+
+#include <QtDesigner/QDesignerComponents>
+
+QT_BEGIN_NAMESPACE
+
+static const char *designerApplicationName = "Designer";
+static const char *designerWarningPrefix = "Designer: ";
+
+static void designerMessageHandler(QtMsgType type, const char *msg)
+{
+ // Only Designer warnings are displayed as box
+ QDesigner *designerApp = qDesigner;
+ if (type != QtWarningMsg || !designerApp || qstrncmp(designerWarningPrefix, msg, qstrlen(designerWarningPrefix))) {
+ qInstallMsgHandler(0);
+ qt_message_output(type, msg);
+ qInstallMsgHandler (designerMessageHandler);
+ return;
+ }
+ designerApp->showErrorMessage(msg);
+}
+
+QDesigner::QDesigner(int &argc, char **argv)
+ : QApplication(argc, argv),
+ m_server(0),
+ m_client(0),
+ m_workbench(0), m_suppressNewFormShow(false)
+{
+ setOrganizationName(QLatin1String("Trolltech"));
+ setApplicationName(QLatin1String(designerApplicationName));
+ QDesignerComponents::initializeResources();
+
+#ifndef Q_WS_MAC
+ setWindowIcon(QIcon(QLatin1String(":/trolltech/designer/images/designer.png")));
+#endif
+ initialize();
+}
+
+QDesigner::~QDesigner()
+{
+ if (m_workbench)
+ delete m_workbench;
+ if (m_server)
+ delete m_server;
+ if (m_client)
+ delete m_client;
+}
+
+void QDesigner::showErrorMessage(const char *message)
+{
+ // strip the prefix
+ const QString qMessage = QString::fromUtf8(message + qstrlen(designerWarningPrefix));
+ // If there is no main window yet, just store the message.
+ // The QErrorMessage would otherwise be hidden by the main window.
+ if (m_mainWindow) {
+ showErrorMessageBox(qMessage);
+ } else {
+ qInstallMsgHandler(0);
+ qt_message_output(QtWarningMsg, message); // just in case we crash
+ qInstallMsgHandler (designerMessageHandler);
+ m_initializationErrors += qMessage;
+ m_initializationErrors += QLatin1Char('\n');
+ }
+}
+
+void QDesigner::showErrorMessageBox(const QString &msg)
+{
+ // Manually suppress consecutive messages.
+ // This happens if for example sth is wrong with custom widget creation.
+ // The same warning will be displayed by Widget box D&D and form Drop
+ // while trying to create instance.
+ if (m_errorMessageDialog && m_lastErrorMessage == msg)
+ return;
+
+ if (!m_errorMessageDialog) {
+ m_lastErrorMessage.clear();
+ m_errorMessageDialog = new QErrorMessage(m_mainWindow);
+ const QString title = QCoreApplication::translate("QDesigner", "%1 - warning").arg(QLatin1String(designerApplicationName));
+ m_errorMessageDialog->setWindowTitle(title);
+ m_errorMessageDialog->setMinimumSize(QSize(600, 250));
+ m_errorMessageDialog->setWindowFlags(m_errorMessageDialog->windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ }
+ m_errorMessageDialog->showMessage(msg);
+ m_lastErrorMessage = msg;
+}
+
+QDesignerWorkbench *QDesigner::workbench() const
+{
+ return m_workbench;
+}
+
+QDesignerServer *QDesigner::server() const
+{
+ return m_server;
+}
+
+bool QDesigner::parseCommandLineArgs(QStringList &fileNames, QString &resourceDir)
+{
+ const QStringList args = arguments();
+ const QStringList::const_iterator acend = args.constEnd();
+ QStringList::const_iterator it = args.constBegin();
+ for (++it; it != acend; ++it) {
+ const QString &argument = *it;
+ do {
+ // Arguments
+ if (!argument.startsWith(QLatin1Char('-'))) {
+ if (!fileNames.contains(argument))
+ fileNames.append(argument);
+ break;
+ }
+ // Options
+ if (argument == QLatin1String("-server")) {
+ m_server = new QDesignerServer();
+ printf("%d\n", m_server->serverPort());
+ fflush(stdout);
+ break;
+ }
+ if (argument == QLatin1String("-client")) {
+ bool ok = true;
+ if (++it == acend) {
+ qWarning("** WARNING The option -client requires an argument");
+ return false;
+ }
+ const quint16 port = it->toUShort(&ok);
+ if (ok) {
+ m_client = new QDesignerClient(port, this);
+ } else {
+ qWarning("** WARNING Non-numeric argument specified for -client");
+ return false;
+ }
+ break;
+ }
+ if (argument == QLatin1String("-resourcedir")) {
+ if (++it == acend) {
+ qWarning("** WARNING The option -resourcedir requires an argument");
+ return false;
+ }
+ resourceDir = QFile::decodeName(it->toLocal8Bit());
+ break;
+ }
+ if (argument == QLatin1String("-enableinternaldynamicproperties")) {
+ QDesignerPropertySheet::setInternalDynamicPropertiesEnabled(true);
+ break;
+ }
+ const QString msg = QString::fromUtf8("** WARNING Unknown option %1").arg(argument);
+ qWarning("%s", qPrintable(msg));
+ } while (false);
+ }
+ return true;
+}
+
+void QDesigner::initialize()
+{
+ // initialize the sub components
+ QStringList files;
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ parseCommandLineArgs(files, resourceDir);
+
+ QTranslator *translator = new QTranslator(this);
+ QTranslator *qtTranslator = new QTranslator(this);
+
+ const QString localSysName = QLocale::system().name();
+ QString translatorFileName = QLatin1String("designer_");
+ translatorFileName += localSysName;
+ translator->load(translatorFileName, resourceDir);
+
+ translatorFileName = QLatin1String("qt_");
+ translatorFileName += localSysName;
+ qtTranslator->load(translatorFileName, resourceDir);
+ installTranslator(translator);
+ installTranslator(qtTranslator);
+
+ if (QLibraryInfo::licensedProducts() == QLatin1String("Console")) {
+ QMessageBox::information(0, tr("Qt Designer"),
+ tr("This application cannot be used for the Console edition of Qt"));
+ QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
+ return;
+ }
+
+ m_workbench = new QDesignerWorkbench();
+
+ emit initialized();
+ qInstallMsgHandler(designerMessageHandler); // Warn when loading faulty forms
+
+ m_suppressNewFormShow = m_workbench->readInBackup();
+
+ if (!files.empty()) {
+ const QStringList::const_iterator cend = files.constEnd();
+ for (QStringList::const_iterator it = files.constBegin(); it != cend; ++it) {
+ // Ensure absolute paths for recent file list to be unique
+ QString fileName = *it;
+ const QFileInfo fi(fileName);
+ if (fi.exists() && fi.isRelative())
+ fileName = fi.absoluteFilePath();
+ m_workbench->readInForm(fileName);
+ }
+ }
+ if ( m_workbench->formWindowCount())
+ m_suppressNewFormShow = true;
+
+ // Show up error box with parent now if something went wrong
+ if (m_initializationErrors.isEmpty()) {
+ if (!m_suppressNewFormShow && QDesignerSettings(m_workbench->core()).showNewFormOnStartup())
+ QTimer::singleShot(100, this, SLOT(callCreateForm())); // won't show anything if suppressed
+ } else {
+ showErrorMessageBox(m_initializationErrors);
+ m_initializationErrors.clear();
+ }
+}
+
+bool QDesigner::event(QEvent *ev)
+{
+ bool eaten;
+ switch (ev->type()) {
+ case QEvent::FileOpen:
+ // Set it true first since, if it's a Qt 3 form, the messagebox from convert will fire the timer.
+ m_suppressNewFormShow = true;
+ if (!m_workbench->readInForm(static_cast<QFileOpenEvent *>(ev)->file()))
+ m_suppressNewFormShow = false;
+ eaten = true;
+ break;
+ case QEvent::Close: {
+ QCloseEvent *closeEvent = static_cast<QCloseEvent *>(ev);
+ closeEvent->setAccepted(m_workbench->handleClose());
+ if (closeEvent->isAccepted()) {
+ // We're going down, make sure that we don't get our settings saved twice.
+ if (m_mainWindow)
+ m_mainWindow->setCloseEventPolicy(MainWindowBase::AcceptCloseEvents);
+ eaten = QApplication::event(ev);
+ }
+ eaten = true;
+ break;
+ }
+ default:
+ eaten = QApplication::event(ev);
+ break;
+ }
+ return eaten;
+}
+
+void QDesigner::setMainWindow(MainWindowBase *tw)
+{
+ m_mainWindow = tw;
+}
+
+MainWindowBase *QDesigner::mainWindow() const
+{
+ return m_mainWindow;
+}
+
+void QDesigner::callCreateForm()
+{
+ if (!m_suppressNewFormShow)
+ m_workbench->actionManager()->createForm();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner.h b/src/designer/src/designer/qdesigner.h
new file mode 100644
index 000000000..ff45edffd
--- /dev/null
+++ b/src/designer/src/designer/qdesigner.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_H
+#define QDESIGNER_H
+
+#include <QtCore/QPointer>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+#define qDesigner \
+ (static_cast<QDesigner*>(QCoreApplication::instance()))
+
+class QDesignerWorkbench;
+class QDesignerToolWindow;
+class MainWindowBase;
+class QDesignerServer;
+class QDesignerClient;
+class QErrorMessage;
+
+class QDesigner: public QApplication
+{
+ Q_OBJECT
+public:
+ QDesigner(int &argc, char **argv);
+ virtual ~QDesigner();
+
+ QDesignerWorkbench *workbench() const;
+ QDesignerServer *server() const;
+ MainWindowBase *mainWindow() const;
+ void setMainWindow(MainWindowBase *tw);
+
+protected:
+ bool event(QEvent *ev);
+
+signals:
+ void initialized();
+
+public slots:
+ void showErrorMessage(const char *message);
+
+private slots:
+ void initialize();
+ void callCreateForm();
+
+private:
+ bool parseCommandLineArgs(QStringList &fileNames, QString &resourceDir);
+ void showErrorMessageBox(const QString &);
+
+ QDesignerServer *m_server;
+ QDesignerClient *m_client;
+ QDesignerWorkbench *m_workbench;
+ QPointer<MainWindowBase> m_mainWindow;
+ QPointer<QErrorMessage> m_errorMessageDialog;
+
+ QString m_initializationErrors;
+ QString m_lastErrorMessage;
+ bool m_suppressNewFormShow;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_H
diff --git a/src/designer/src/designer/qdesigner_actions.cpp b/src/designer/src/designer/qdesigner_actions.cpp
new file mode 100644
index 000000000..a84e0732d
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_actions.cpp
@@ -0,0 +1,1437 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_actions.h"
+#include "designer_enums.h"
+#include "qdesigner.h"
+#include "qdesigner_workbench.h"
+#include "qdesigner_formwindow.h"
+#include "newform.h"
+#include "versiondialog.h"
+#include "saveformastemplate.h"
+#include "qdesigner_toolwindow.h"
+#include "preferencesdialog.h"
+#include "appfontdialog.h"
+
+#include <pluginmanager_p.h>
+#include <qdesigner_formbuilder_p.h>
+#include <qdesigner_utils_p.h>
+#include <iconloader_p.h>
+#include <qsimpleresource_p.h>
+#include <previewmanager_p.h>
+#include <codedialog_p.h>
+#include <qdesigner_formwindowmanager_p.h>
+#include "qdesigner_integration_p.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormEditorPluginInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtDesigner/private/shared_settings_p.h>
+#include <QtDesigner/private/formwindowbase_p.h>
+
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QIcon>
+#include <QtGui/QImage>
+#include <QtGui/QPixmap>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QPrintDialog>
+#include <QtGui/QPainter>
+#include <QtGui/QTransform>
+#include <QtGui/QCursor>
+#include <QtCore/QSizeF>
+
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QBuffer>
+#include <QtCore/QPluginLoader>
+#include <QtCore/qdebug.h>
+#include <QtCore/QTimer>
+#include <QtCore/QMetaObject>
+#include <QtCore/QFileInfo>
+#include <QtGui/QStatusBar>
+#include <QtGui/QDesktopWidget>
+#include <QtXml/QDomDocument>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+const char *QDesignerActions::defaultToolbarPropertyName = "__qt_defaultToolBarAction";
+
+//#ifdef Q_WS_MAC
+# define NONMODAL_PREVIEW
+//#endif
+
+static QAction *createSeparator(QObject *parent) {
+ QAction * rc = new QAction(parent);
+ rc->setSeparator(true);
+ return rc;
+}
+
+static QActionGroup *createActionGroup(QObject *parent, bool exclusive = false) {
+ QActionGroup * rc = new QActionGroup(parent);
+ rc->setExclusive(exclusive);
+ return rc;
+}
+
+static inline QString savedMessage(const QString &fileName)
+{
+ return QDesignerActions::tr("Saved %1.").arg(fileName);
+}
+
+// Prompt for a file and make sure an extension is added
+// unless the user explicitly specifies another one.
+
+static QString getSaveFileNameWithExtension(QWidget *parent, const QString &title, QString dir, const QString &filter, const QString &extension)
+{
+ const QChar dot = QLatin1Char('.');
+
+ QString saveFile;
+ while (true) {
+ saveFile = QFileDialog::getSaveFileName(parent, title, dir, filter, 0, QFileDialog::DontConfirmOverwrite);
+ if (saveFile.isEmpty())
+ return saveFile;
+
+ const QFileInfo fInfo(saveFile);
+ if (fInfo.suffix().isEmpty() && !fInfo.fileName().endsWith(dot)) {
+ saveFile += dot;
+ saveFile += extension;
+ }
+
+ const QFileInfo fi(saveFile);
+ if (!fi.exists())
+ break;
+
+ const QString prompt = QDesignerActions::tr("%1 already exists.\nDo you want to replace it?").arg(fi.fileName());
+ if (QMessageBox::warning(parent, title, prompt, QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
+ break;
+
+ dir = saveFile;
+ }
+ return saveFile;
+}
+
+QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
+ : QObject(workbench),
+ m_workbench(workbench),
+ m_core(workbench->core()),
+ m_settings(workbench->core()),
+ m_backupTimer(new QTimer(this)),
+ m_fileActions(createActionGroup(this)),
+ m_recentFilesActions(createActionGroup(this)),
+ m_editActions(createActionGroup(this)),
+ m_formActions(createActionGroup(this)),
+ m_settingsActions(createActionGroup(this)),
+ m_windowActions(createActionGroup(this)),
+ m_toolActions(createActionGroup(this, true)),
+ m_helpActions(0),
+ m_styleActions(0),
+ m_editWidgetsAction(new QAction(tr("Edit Widgets"), this)),
+ m_newFormAction(new QAction(qdesigner_internal::createIconSet(QLatin1String("filenew.png")), tr("&New..."), this)),
+ m_openFormAction(new QAction(qdesigner_internal::createIconSet(QLatin1String("fileopen.png")), tr("&Open..."), this)),
+ m_saveFormAction(new QAction(qdesigner_internal::createIconSet(QLatin1String("filesave.png")), tr("&Save"), this)),
+ m_saveFormAsAction(new QAction(tr("Save &As..."), this)),
+ m_saveAllFormsAction(new QAction(tr("Save A&ll"), this)),
+ m_saveFormAsTemplateAction(new QAction(tr("Save As &Template..."), this)),
+ m_closeFormAction(new QAction(tr("&Close"), this)),
+ m_savePreviewImageAction(new QAction(tr("Save &Image..."), this)),
+ m_printPreviewAction(new QAction(tr("&Print..."), this)),
+ m_quitAction(new QAction(tr("&Quit"), this)),
+ m_previewFormAction(0),
+ m_viewCodeAction(new QAction(tr("View &Code..."), this)),
+ m_minimizeAction(new QAction(tr("&Minimize"), this)),
+ m_bringAllToFrontSeparator(createSeparator(this)),
+ m_bringAllToFrontAction(new QAction(tr("Bring All to Front"), this)),
+ m_windowListSeparatorAction(createSeparator(this)),
+ m_preferencesAction(new QAction(tr("Preferences..."), this)),
+ m_appFontAction(new QAction(tr("Additional Fonts..."), this)),
+ m_appFontDialog(0),
+#ifndef QT_NO_PRINTER
+ m_printer(0),
+#endif
+ m_previewManager(0)
+{
+#ifdef Q_WS_X11
+ m_newFormAction->setIcon(QIcon::fromTheme("document-new", m_newFormAction->icon()));
+ m_openFormAction->setIcon(QIcon::fromTheme("document-open", m_openFormAction->icon()));
+ m_saveFormAction->setIcon(QIcon::fromTheme("document-save", m_saveFormAction->icon()));
+ m_saveFormAsAction->setIcon(QIcon::fromTheme("document-save-as", m_saveFormAsAction->icon()));
+ m_printPreviewAction->setIcon(QIcon::fromTheme("document-print", m_printPreviewAction->icon()));
+ m_closeFormAction->setIcon(QIcon::fromTheme("window-close", m_closeFormAction->icon()));
+ m_quitAction->setIcon(QIcon::fromTheme("application-exit", m_quitAction->icon()));
+#endif
+
+ Q_ASSERT(m_core != 0);
+ qdesigner_internal::QDesignerFormWindowManager *ifwm = qobject_cast<qdesigner_internal::QDesignerFormWindowManager *>(m_core->formWindowManager());
+ Q_ASSERT(ifwm);
+ m_previewManager = ifwm->previewManager();
+ m_previewFormAction = ifwm->actionDefaultPreview();
+ m_styleActions = ifwm->actionGroupPreviewInStyle();
+ connect(ifwm, SIGNAL(formWindowSettingsChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(formWindowSettingsChanged(QDesignerFormWindowInterface*)));
+
+ m_editWidgetsAction->setObjectName(QLatin1String("__qt_edit_widgets_action"));
+ m_newFormAction->setObjectName(QLatin1String("__qt_new_form_action"));
+ m_openFormAction->setObjectName(QLatin1String("__qt_open_form_action"));
+ m_saveFormAction->setObjectName(QLatin1String("__qt_save_form_action"));
+ m_saveFormAsAction->setObjectName(QLatin1String("__qt_save_form_as_action"));
+ m_saveAllFormsAction->setObjectName(QLatin1String("__qt_save_all_forms_action"));
+ m_saveFormAsTemplateAction->setObjectName(QLatin1String("__qt_save_form_as_template_action"));
+ m_closeFormAction->setObjectName(QLatin1String("__qt_close_form_action"));
+ m_quitAction->setObjectName(QLatin1String("__qt_quit_action"));
+ m_previewFormAction->setObjectName(QLatin1String("__qt_preview_form_action"));
+ m_viewCodeAction->setObjectName(QLatin1String("__qt_preview_code_action"));
+ m_minimizeAction->setObjectName(QLatin1String("__qt_minimize_action"));
+ m_bringAllToFrontAction->setObjectName(QLatin1String("__qt_bring_all_to_front_action"));
+ m_preferencesAction->setObjectName(QLatin1String("__qt_preferences_action"));
+
+ m_helpActions = createHelpActions();
+
+ m_newFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ m_openFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ m_saveFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
+ QDesignerFormWindowManagerInterface *formWindowManager = m_core->formWindowManager();
+ Q_ASSERT(formWindowManager != 0);
+
+//
+// file actions
+//
+ m_newFormAction->setShortcut(QKeySequence::New);
+ connect(m_newFormAction, SIGNAL(triggered()), this, SLOT(createForm()));
+ m_fileActions->addAction(m_newFormAction);
+
+ m_openFormAction->setShortcut(QKeySequence::Open);
+ connect(m_openFormAction, SIGNAL(triggered()), this, SLOT(slotOpenForm()));
+ m_fileActions->addAction(m_openFormAction);
+
+ m_fileActions->addAction(createRecentFilesMenu());
+ m_fileActions->addAction(createSeparator(this));
+
+ m_saveFormAction->setShortcut(QKeySequence::Save);
+ connect(m_saveFormAction, SIGNAL(triggered()), this, SLOT(saveForm()));
+ m_fileActions->addAction(m_saveFormAction);
+
+ connect(m_saveFormAsAction, SIGNAL(triggered()), this, SLOT(saveFormAs()));
+ m_fileActions->addAction(m_saveFormAsAction);
+
+#ifdef Q_OS_MAC
+ m_saveAllFormsAction->setShortcut(tr("ALT+CTRL+S"));
+#else
+ m_saveAllFormsAction->setShortcut(tr("CTRL+SHIFT+S")); // Commonly "Save As" on Mac
+#endif
+ connect(m_saveAllFormsAction, SIGNAL(triggered()), this, SLOT(saveAllForms()));
+ m_fileActions->addAction(m_saveAllFormsAction);
+
+ connect(m_saveFormAsTemplateAction, SIGNAL(triggered()), this, SLOT(saveFormAsTemplate()));
+ m_fileActions->addAction(m_saveFormAsTemplateAction);
+
+ m_fileActions->addAction(createSeparator(this));
+
+ m_printPreviewAction->setShortcut(QKeySequence::Print);
+ connect(m_printPreviewAction, SIGNAL(triggered()), this, SLOT(printPreviewImage()));
+ m_fileActions->addAction(m_printPreviewAction);
+ m_printPreviewAction->setObjectName(QLatin1String("__qt_print_action"));
+
+ connect(m_savePreviewImageAction, SIGNAL(triggered()), this, SLOT(savePreviewImage()));
+ m_savePreviewImageAction->setObjectName(QLatin1String("__qt_saveimage_action"));
+ m_fileActions->addAction(m_savePreviewImageAction);
+ m_fileActions->addAction(createSeparator(this));
+
+ m_closeFormAction->setShortcut(QKeySequence::Close);
+ connect(m_closeFormAction, SIGNAL(triggered()), this, SLOT(closeForm()));
+ m_fileActions->addAction(m_closeFormAction);
+ updateCloseAction();
+
+ m_fileActions->addAction(createSeparator(this));
+
+ m_quitAction->setShortcuts(QKeySequence::Quit);
+ m_quitAction->setMenuRole(QAction::QuitRole);
+ connect(m_quitAction, SIGNAL(triggered()), this, SLOT(shutdown()));
+ m_fileActions->addAction(m_quitAction);
+
+//
+// edit actions
+//
+ QAction *undoAction = formWindowManager->actionUndo();
+ undoAction->setObjectName(QLatin1String("__qt_undo_action"));
+ undoAction->setShortcut(QKeySequence::Undo);
+ m_editActions->addAction(undoAction);
+
+ QAction *redoAction = formWindowManager->actionRedo();
+ redoAction->setObjectName(QLatin1String("__qt_redo_action"));
+ redoAction->setShortcut(QKeySequence::Redo);
+ m_editActions->addAction(redoAction);
+
+ m_editActions->addAction(createSeparator(this));
+
+ m_editActions->addAction(formWindowManager->actionCut());
+ m_editActions->addAction(formWindowManager->actionCopy());
+ m_editActions->addAction(formWindowManager->actionPaste());
+ m_editActions->addAction(formWindowManager->actionDelete());
+
+ m_editActions->addAction(formWindowManager->actionSelectAll());
+
+ m_editActions->addAction(createSeparator(this));
+
+ m_editActions->addAction(formWindowManager->actionLower());
+ m_editActions->addAction(formWindowManager->actionRaise());
+
+ formWindowManager->actionLower()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionRaise()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
+//
+// edit mode actions
+//
+
+ m_editWidgetsAction->setCheckable(true);
+ QList<QKeySequence> shortcuts;
+ shortcuts.append(QKeySequence(Qt::Key_F3));
+#if QT_VERSION >= 0x040900 // "ESC" switching to edit mode: Activate once item delegates handle shortcut overrides for ESC.
+ shortcuts.append(QKeySequence(Qt::Key_Escape));
+#endif
+ m_editWidgetsAction->setShortcuts(shortcuts);
+ QIcon fallback(m_core->resourceLocation() + QLatin1String("/widgettool.png"));
+ m_editWidgetsAction->setIcon(QIcon::fromTheme("designer-edit-widget", fallback));
+ connect(m_editWidgetsAction, SIGNAL(triggered()), this, SLOT(editWidgetsSlot()));
+ m_editWidgetsAction->setChecked(true);
+ m_editWidgetsAction->setEnabled(false);
+ m_editWidgetsAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ m_toolActions->addAction(m_editWidgetsAction);
+
+ connect(formWindowManager, SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface*)));
+
+ QList<QObject*> builtinPlugins = QPluginLoader::staticInstances();
+ builtinPlugins += m_core->pluginManager()->instances();
+ foreach (QObject *plugin, builtinPlugins) {
+ if (QDesignerFormEditorPluginInterface *formEditorPlugin = qobject_cast<QDesignerFormEditorPluginInterface*>(plugin)) {
+ if (QAction *action = formEditorPlugin->action()) {
+ m_toolActions->addAction(action);
+ action->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ action->setCheckable(true);
+ }
+ }
+ }
+
+ connect(m_preferencesAction, SIGNAL(triggered()), this, SLOT(showPreferencesDialog()));
+ m_preferencesAction->setMenuRole(QAction::PreferencesRole);
+ m_settingsActions->addAction(m_preferencesAction);
+
+ connect(m_appFontAction, SIGNAL(triggered()), this, SLOT(showAppFontDialog()));
+ m_appFontAction->setMenuRole(QAction::PreferencesRole);
+ m_settingsActions->addAction(m_appFontAction);
+//
+// form actions
+//
+
+ m_formActions->addAction(formWindowManager->actionHorizontalLayout());
+ m_formActions->addAction(formWindowManager->actionVerticalLayout());
+ m_formActions->addAction(formWindowManager->actionSplitHorizontal());
+ m_formActions->addAction(formWindowManager->actionSplitVertical());
+ m_formActions->addAction(formWindowManager->actionGridLayout());
+ m_formActions->addAction(formWindowManager->actionFormLayout());
+ m_formActions->addAction(formWindowManager->actionBreakLayout());
+ m_formActions->addAction(formWindowManager->actionAdjustSize());
+ m_formActions->addAction(formWindowManager->actionSimplifyLayout());
+ m_formActions->addAction(createSeparator(this));
+
+ formWindowManager->actionHorizontalLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionVerticalLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionSplitHorizontal()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionSplitVertical()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionGridLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionFormLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionBreakLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionAdjustSize()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
+ m_previewFormAction->setShortcut(tr("CTRL+R"));
+ m_formActions->addAction(m_previewFormAction);
+ connect(m_previewManager, SIGNAL(firstPreviewOpened()), this, SLOT(updateCloseAction()));
+ connect(m_previewManager, SIGNAL(lastPreviewClosed()), this, SLOT(updateCloseAction()));
+
+ connect(m_viewCodeAction, SIGNAL(triggered()), this, SLOT(viewCode()));
+ // Preview code only in Cpp
+ if (qt_extension<QDesignerLanguageExtension *>(m_core->extensionManager(), m_core) == 0)
+ m_formActions->addAction(m_viewCodeAction);
+
+ m_formActions->addAction(createSeparator(this));
+
+ m_formActions->addAction(ifwm->actionShowFormWindowSettingsDialog());
+//
+// window actions
+//
+ m_minimizeAction->setEnabled(false);
+ m_minimizeAction->setCheckable(true);
+ m_minimizeAction->setShortcut(tr("CTRL+M"));
+ connect(m_minimizeAction, SIGNAL(triggered()), m_workbench, SLOT(toggleFormMinimizationState()));
+ m_windowActions->addAction(m_minimizeAction);
+
+ m_windowActions->addAction(m_bringAllToFrontSeparator);
+ connect(m_bringAllToFrontAction, SIGNAL(triggered()), m_workbench, SLOT(bringAllToFront()));
+ m_windowActions->addAction(m_bringAllToFrontAction);
+ m_windowActions->addAction(m_windowListSeparatorAction);
+
+ setWindowListSeparatorVisible(false);
+
+//
+// connections
+//
+ fixActionContext();
+ activeFormWindowChanged(core()->formWindowManager()->activeFormWindow());
+
+ m_backupTimer->start(180000); // 3min
+ connect(m_backupTimer, SIGNAL(timeout()), this, SLOT(backupForms()));
+
+ // Enable application font action
+ connect(formWindowManager, SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)), this, SLOT(formWindowCountChanged()));
+ connect(formWindowManager, SIGNAL(formWindowRemoved(QDesignerFormWindowInterface*)), this, SLOT(formWindowCountChanged()));
+ formWindowCountChanged();
+}
+
+QActionGroup *QDesignerActions::createHelpActions()
+{
+ QActionGroup *helpActions = createActionGroup(this);
+
+#ifndef QT_JAMBI_BUILD
+ QAction *mainHelpAction = new QAction(tr("Qt Designer &Help"), this);
+ mainHelpAction->setObjectName(QLatin1String("__qt_designer_help_action"));
+ connect(mainHelpAction, SIGNAL(triggered()), this, SLOT(showDesignerHelp()));
+ mainHelpAction->setShortcut(Qt::CTRL + Qt::Key_Question);
+ helpActions->addAction(mainHelpAction);
+
+ helpActions->addAction(createSeparator(this));
+ QAction *widgetHelp = new QAction(tr("Current Widget Help"), this);
+ widgetHelp->setObjectName(QLatin1String("__qt_current_widget_help_action"));
+ widgetHelp->setShortcut(Qt::Key_F1);
+ connect(widgetHelp, SIGNAL(triggered()), this, SLOT(showWidgetSpecificHelp()));
+ helpActions->addAction(widgetHelp);
+
+ helpActions->addAction(createSeparator(this));
+ QAction *whatsNewAction = new QAction(tr("What's New in Qt Designer?"), this);
+ whatsNewAction->setObjectName(QLatin1String("__qt_whats_new_in_qt_designer_action"));
+ connect(whatsNewAction, SIGNAL(triggered()), this, SLOT(showWhatsNew()));
+ helpActions->addAction(whatsNewAction);
+#endif
+
+ helpActions->addAction(createSeparator(this));
+ QAction *aboutPluginsAction = new QAction(tr("About Plugins"), this);
+ aboutPluginsAction->setObjectName(QLatin1String("__qt_about_plugins_action"));
+ aboutPluginsAction->setMenuRole(QAction::ApplicationSpecificRole);
+ connect(aboutPluginsAction, SIGNAL(triggered()), m_core->formWindowManager(), SLOT(aboutPlugins()));
+ helpActions->addAction(aboutPluginsAction);
+
+ QAction *aboutDesignerAction = new QAction(tr("About Qt Designer"), this);
+ aboutDesignerAction->setMenuRole(QAction::AboutRole);
+ aboutDesignerAction->setObjectName(QLatin1String("__qt_about_designer_action"));
+ connect(aboutDesignerAction, SIGNAL(triggered()), this, SLOT(aboutDesigner()));
+ helpActions->addAction(aboutDesignerAction);
+
+ QAction *aboutQtAction = new QAction(tr("About Qt"), this);
+ aboutQtAction->setMenuRole(QAction::AboutQtRole);
+ aboutQtAction->setObjectName(QLatin1String("__qt_about_qt_action"));
+ connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+ helpActions->addAction(aboutQtAction);
+ return helpActions;
+}
+
+QDesignerActions::~QDesignerActions()
+{
+#ifndef QT_NO_PRINTER
+ delete m_printer;
+#endif
+}
+
+QString QDesignerActions::uiExtension() const
+{
+ QDesignerLanguageExtension *lang
+ = qt_extension<QDesignerLanguageExtension *>(m_core->extensionManager(), m_core);
+ if (lang)
+ return lang->uiExtension();
+ return QLatin1String("ui");
+}
+
+QAction *QDesignerActions::createRecentFilesMenu()
+{
+ QMenu *menu = new QMenu;
+ QAction *act;
+ // Need to insert this into the QAction.
+ for (int i = 0; i < MaxRecentFiles; ++i) {
+ act = new QAction(this);
+ act->setVisible(false);
+ connect(act, SIGNAL(triggered()), this, SLOT(openRecentForm()));
+ m_recentFilesActions->addAction(act);
+ menu->addAction(act);
+ }
+ updateRecentFileActions();
+ menu->addSeparator();
+ act = new QAction(QIcon::fromTheme("edit-clear"), tr("Clear &Menu"), this);
+ act->setObjectName(QLatin1String("__qt_action_clear_menu_"));
+ connect(act, SIGNAL(triggered()), this, SLOT(clearRecentFiles()));
+ m_recentFilesActions->addAction(act);
+ menu->addAction(act);
+
+ act = new QAction(QIcon::fromTheme("document-open-recent"), tr("&Recent Forms"), this);
+ act->setMenu(menu);
+ return act;
+}
+
+QActionGroup *QDesignerActions::toolActions() const
+{ return m_toolActions; }
+
+QDesignerWorkbench *QDesignerActions::workbench() const
+{ return m_workbench; }
+
+QDesignerFormEditorInterface *QDesignerActions::core() const
+{ return m_core; }
+
+QActionGroup *QDesignerActions::fileActions() const
+{ return m_fileActions; }
+
+QActionGroup *QDesignerActions::editActions() const
+{ return m_editActions; }
+
+QActionGroup *QDesignerActions::formActions() const
+{ return m_formActions; }
+
+QActionGroup *QDesignerActions::settingsActions() const
+{ return m_settingsActions; }
+
+QActionGroup *QDesignerActions::windowActions() const
+{ return m_windowActions; }
+
+QActionGroup *QDesignerActions::helpActions() const
+{ return m_helpActions; }
+
+QActionGroup *QDesignerActions::styleActions() const
+{ return m_styleActions; }
+
+QAction *QDesignerActions::previewFormAction() const
+{ return m_previewFormAction; }
+
+QAction *QDesignerActions::viewCodeAction() const
+{ return m_viewCodeAction; }
+
+
+void QDesignerActions::editWidgetsSlot()
+{
+ QDesignerFormWindowManagerInterface *formWindowManager = core()->formWindowManager();
+ for (int i=0; i<formWindowManager->formWindowCount(); ++i) {
+ QDesignerFormWindowInterface *formWindow = formWindowManager->formWindow(i);
+ formWindow->editWidgets();
+ }
+}
+
+void QDesignerActions::createForm()
+{
+ showNewFormDialog(QString());
+}
+
+void QDesignerActions::showNewFormDialog(const QString &fileName)
+{
+ closePreview();
+ NewForm *dlg = new NewForm(workbench(), workbench()->core()->topLevel(), fileName);
+
+ dlg->setAttribute(Qt::WA_DeleteOnClose);
+ dlg->setAttribute(Qt::WA_ShowModal);
+
+ dlg->setGeometry(fixDialogRect(dlg->rect()));
+ dlg->exec();
+}
+
+void QDesignerActions::slotOpenForm()
+{
+ openForm(core()->topLevel());
+}
+
+bool QDesignerActions::openForm(QWidget *parent)
+{
+ closePreview();
+ const QString extension = uiExtension();
+ const QStringList fileNames = QFileDialog::getOpenFileNames(parent, tr("Open Form"),
+ m_openDirectory, tr("Designer UI files (*.%1);;All Files (*)").arg(extension), 0, QFileDialog::DontUseSheet);
+
+ if (fileNames.isEmpty())
+ return false;
+
+ bool atLeastOne = false;
+ foreach (const QString &fileName, fileNames) {
+ if (readInForm(fileName) && !atLeastOne)
+ atLeastOne = true;
+ }
+
+ return atLeastOne;
+}
+
+bool QDesignerActions::saveFormAs(QDesignerFormWindowInterface *fw)
+{
+ const QString extension = uiExtension();
+
+ QString dir = fw->fileName();
+ if (dir.isEmpty()) {
+ do {
+ // Build untitled name
+ if (!m_saveDirectory.isEmpty()) {
+ dir = m_saveDirectory;
+ break;
+ }
+ if (!m_openDirectory.isEmpty()) {
+ dir = m_openDirectory;
+ break;
+ }
+ dir = QDir::current().absolutePath();
+ } while (false);
+ dir += QDir::separator();
+ dir += QLatin1String("untitled.");
+ dir += extension;
+ }
+
+ const QString saveFile = getSaveFileNameWithExtension(fw, tr("Save Form As"), dir, tr("Designer UI files (*.%1);;All Files (*)").arg(extension), extension);
+ if (saveFile.isEmpty())
+ return false;
+
+ fw->setFileName(saveFile);
+ return writeOutForm(fw, saveFile);
+}
+
+void QDesignerActions::saveForm()
+{
+ if (QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow()) {
+ if (saveForm(fw))
+ showStatusBarMessage(savedMessage(QFileInfo(fw->fileName()).fileName()));
+ }
+}
+
+void QDesignerActions::saveAllForms()
+{
+ QString fileNames;
+ QDesignerFormWindowManagerInterface *formWindowManager = core()->formWindowManager();
+ if (const int totalWindows = formWindowManager->formWindowCount()) {
+ const QString separator = QLatin1String(", ");
+ for (int i = 0; i < totalWindows; ++i) {
+ QDesignerFormWindowInterface *fw = formWindowManager->formWindow(i);
+ if (fw && fw->isDirty()) {
+ formWindowManager->setActiveFormWindow(fw);
+ if (saveForm(fw)) {
+ if (!fileNames.isEmpty())
+ fileNames += separator;
+ fileNames += QFileInfo(fw->fileName()).fileName();
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ if (!fileNames.isEmpty()) {
+ showStatusBarMessage(savedMessage(fileNames));
+ }
+}
+
+bool QDesignerActions::saveForm(QDesignerFormWindowInterface *fw)
+{
+ bool ret;
+ if (fw->fileName().isEmpty())
+ ret = saveFormAs(fw);
+ else
+ ret = writeOutForm(fw, fw->fileName());
+ return ret;
+}
+
+void QDesignerActions::closeForm()
+{
+ if (m_previewManager->previewCount()) {
+ closePreview();
+ return;
+ }
+
+ if (QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow())
+ if (QWidget *parent = fw->parentWidget()) {
+ if (QMdiSubWindow *mdiSubWindow = qobject_cast<QMdiSubWindow *>(parent->parentWidget())) {
+ mdiSubWindow->close();
+ } else {
+ parent->close();
+ }
+ }
+}
+
+void QDesignerActions::saveFormAs()
+{
+ if (QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow()) {
+ if (saveFormAs(fw))
+ showStatusBarMessage(savedMessage(fw->fileName()));
+ }
+}
+
+void QDesignerActions::saveFormAsTemplate()
+{
+ if (QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow()) {
+ SaveFormAsTemplate dlg(core(), fw, fw->window());
+ dlg.exec();
+ }
+}
+
+void QDesignerActions::notImplementedYet()
+{
+ QMessageBox::information(core()->topLevel(), tr("Designer"), tr("Feature not implemented yet!"));
+}
+
+void QDesignerActions::closePreview()
+{
+ m_previewManager->closeAllPreviews();
+}
+
+void QDesignerActions::viewCode()
+{
+ QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow();
+ if (!fw)
+ return;
+ QString errorMessage;
+ if (!qdesigner_internal::CodeDialog::showCodeDialog(fw, fw, &errorMessage))
+ QMessageBox::warning(fw, tr("Code generation failed"), errorMessage);
+}
+
+void QDesignerActions::fixActionContext()
+{
+ QList<QAction*> actions;
+ actions += m_fileActions->actions();
+ actions += m_editActions->actions();
+ actions += m_toolActions->actions();
+ actions += m_formActions->actions();
+ actions += m_windowActions->actions();
+ actions += m_helpActions->actions();
+
+ foreach (QAction *a, actions) {
+ a->setShortcutContext(Qt::ApplicationShortcut);
+ }
+}
+
+bool QDesignerActions::readInForm(const QString &fileName)
+{
+ QString fn = fileName;
+
+ // First make sure that we don't have this one open already.
+ QDesignerFormWindowManagerInterface *formWindowManager = core()->formWindowManager();
+ const int totalWindows = formWindowManager->formWindowCount();
+ for (int i = 0; i < totalWindows; ++i) {
+ QDesignerFormWindowInterface *w = formWindowManager->formWindow(i);
+ if (w->fileName() == fn) {
+ w->raise();
+ formWindowManager->setActiveFormWindow(w);
+ addRecentFile(fn);
+ return true;
+ }
+ }
+
+ // Otherwise load it.
+ do {
+ QString errorMessage;
+ if (workbench()->openForm(fn, &errorMessage)) {
+ addRecentFile(fn);
+ m_openDirectory = QFileInfo(fn).absolutePath();
+ return true;
+ } else {
+ // prompt to reload
+ QMessageBox box(QMessageBox::Warning, tr("Read error"),
+ tr("%1\nDo you want to update the file location or generate a new form?").arg(errorMessage),
+ QMessageBox::Cancel, core()->topLevel());
+
+ QPushButton *updateButton = box.addButton(tr("&Update"), QMessageBox::ActionRole);
+ QPushButton *newButton = box.addButton(tr("&New Form"), QMessageBox::ActionRole);
+ box.exec();
+ if (box.clickedButton() == box.button(QMessageBox::Cancel))
+ return false;
+
+ if (box.clickedButton() == updateButton) {
+ const QString extension = uiExtension();
+ fn = QFileDialog::getOpenFileName(core()->topLevel(),
+ tr("Open Form"), m_openDirectory,
+ tr("Designer UI files (*.%1);;All Files (*)").arg(extension), 0, QFileDialog::DontUseSheet);
+
+ if (fn.isEmpty())
+ return false;
+ } else if (box.clickedButton() == newButton) {
+ // If the file does not exist, but its directory, is valid, open the template with the editor file name set to it.
+ // (called from command line).
+ QString newFormFileName;
+ const QFileInfo fInfo(fn);
+ if (!fInfo.exists()) {
+ // Normalize file name
+ const QString directory = fInfo.absolutePath();
+ if (QDir(directory).exists()) {
+ newFormFileName = directory;
+ newFormFileName += QLatin1Char('/');
+ newFormFileName += fInfo.fileName();
+ }
+ }
+ showNewFormDialog(newFormFileName);
+ return false;
+ }
+ }
+ } while (true);
+ return true;
+}
+
+static QString createBackup(const QString &fileName)
+{
+ const QString suffix = QLatin1String(".bak");
+ QString backupFile = fileName + suffix;
+ QFileInfo fi(backupFile);
+ int i = 0;
+ while (fi.exists()) {
+ backupFile = fileName + suffix + QString::number(++i);
+ fi.setFile(backupFile);
+ }
+
+ if (QFile::copy(fileName, backupFile))
+ return backupFile;
+ return QString();
+}
+
+static void removeBackup(const QString &backupFile)
+{
+ if (!backupFile.isEmpty())
+ QFile::remove(backupFile);
+}
+
+bool QDesignerActions::writeOutForm(QDesignerFormWindowInterface *fw, const QString &saveFile)
+{
+ Q_ASSERT(fw && !saveFile.isEmpty());
+
+ QString backupFile;
+ QFileInfo fi(saveFile);
+ if (fi.exists())
+ backupFile = createBackup(saveFile);
+
+ QString contents = fw->contents();
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(fw)) {
+ if (fwb->lineTerminatorMode() == qdesigner_internal::FormWindowBase::CRLFLineTerminator)
+ contents.replace(QLatin1Char('\n'), QLatin1String("\r\n"));
+ }
+ const QByteArray utf8Array = contents.toUtf8();
+ m_workbench->updateBackup(fw);
+
+ QFile f(saveFile);
+ while (!f.open(QFile::WriteOnly)) {
+ QMessageBox box(QMessageBox::Warning,
+ tr("Save Form?"),
+ tr("Could not open file"),
+ QMessageBox::NoButton, fw);
+
+ box.setWindowModality(Qt::WindowModal);
+ box.setInformativeText(tr("The file %1 could not be opened."
+ "\nReason: %2"
+ "\nWould you like to retry or select a different file?")
+ .arg(f.fileName()).arg(f.errorString()));
+ QPushButton *retryButton = box.addButton(QMessageBox::Retry);
+ retryButton->setDefault(true);
+ QPushButton *switchButton = box.addButton(tr("Select New File"), QMessageBox::AcceptRole);
+ QPushButton *cancelButton = box.addButton(QMessageBox::Cancel);
+ box.exec();
+
+ if (box.clickedButton() == cancelButton) {
+ removeBackup(backupFile);
+ return false;
+ } else if (box.clickedButton() == switchButton) {
+ QString extension = uiExtension();
+ const QString fileName = QFileDialog::getSaveFileName(fw, tr("Save Form As"),
+ QDir::current().absolutePath(),
+ QLatin1String("*.") + extension);
+ if (fileName.isEmpty()) {
+ removeBackup(backupFile);
+ return false;
+ }
+ if (f.fileName() != fileName) {
+ removeBackup(backupFile);
+ fi.setFile(fileName);
+ backupFile.clear();
+ if (fi.exists())
+ backupFile = createBackup(fileName);
+ }
+ f.setFileName(fileName);
+ fw->setFileName(fileName);
+ }
+ // loop back around...
+ }
+ while (f.write(utf8Array, utf8Array.size()) != utf8Array.size()) {
+ QMessageBox box(QMessageBox::Warning, tr("Save Form?"),
+ tr("Could not write file"),
+ QMessageBox::Retry|QMessageBox::Cancel, fw);
+ box.setWindowModality(Qt::WindowModal);
+ box.setInformativeText(tr("It was not possible to write the entire file %1 to disk."
+ "\nReason:%2\nWould you like to retry?")
+ .arg(f.fileName()).arg(f.errorString()));
+ box.setDefaultButton(QMessageBox::Retry);
+ switch (box.exec()) {
+ case QMessageBox::Retry:
+ f.resize(0);
+ break;
+ default:
+ return false;
+ }
+ }
+ f.close();
+ removeBackup(backupFile);
+ addRecentFile(saveFile);
+ m_saveDirectory = QFileInfo(f).absolutePath();
+
+ fw->setDirty(false);
+ fw->parentWidget()->setWindowModified(false);
+ return true;
+}
+
+void QDesignerActions::shutdown()
+{
+ // Follow the idea from the Mac, i.e. send the Application a close event
+ // and if it's accepted, quit.
+ QCloseEvent ev;
+ QApplication::sendEvent(qDesigner, &ev);
+ if (ev.isAccepted())
+ qDesigner->quit();
+}
+
+void QDesignerActions::activeFormWindowChanged(QDesignerFormWindowInterface *formWindow)
+{
+ const bool enable = formWindow != 0;
+ m_saveFormAction->setEnabled(enable);
+ m_saveFormAsAction->setEnabled(enable);
+ m_saveAllFormsAction->setEnabled(enable);
+ m_saveFormAsTemplateAction->setEnabled(enable);
+ m_closeFormAction->setEnabled(enable);
+ m_savePreviewImageAction->setEnabled(enable);
+ m_printPreviewAction->setEnabled(enable);
+
+ m_editWidgetsAction->setEnabled(enable);
+
+ m_previewFormAction->setEnabled(enable);
+ m_viewCodeAction->setEnabled(enable);
+ m_styleActions->setEnabled(enable);
+}
+
+void QDesignerActions::formWindowSettingsChanged(QDesignerFormWindowInterface *fw)
+{
+ if (QDesignerFormWindow *window = m_workbench->findFormWindow(fw))
+ window->updateChanged();
+}
+
+void QDesignerActions::updateRecentFileActions()
+{
+ QStringList files = m_settings.recentFilesList();
+ const int originalSize = files.size();
+ int numRecentFiles = qMin(files.size(), int(MaxRecentFiles));
+ const QList<QAction *> recentFilesActs = m_recentFilesActions->actions();
+
+ for (int i = 0; i < numRecentFiles; ++i) {
+ const QFileInfo fi(files[i]);
+ // If the file doesn't exist anymore, just remove it from the list so
+ // people don't get confused.
+ if (!fi.exists()) {
+ files.removeAt(i);
+ --i;
+ numRecentFiles = qMin(files.size(), int(MaxRecentFiles));
+ continue;
+ }
+ const QString text = fi.fileName();
+ recentFilesActs[i]->setText(text);
+ recentFilesActs[i]->setIconText(files[i]);
+ recentFilesActs[i]->setVisible(true);
+ }
+
+ for (int j = numRecentFiles; j < MaxRecentFiles; ++j)
+ recentFilesActs[j]->setVisible(false);
+
+ // If there's been a change, right it back
+ if (originalSize != files.size())
+ m_settings.setRecentFilesList(files);
+}
+
+void QDesignerActions::openRecentForm()
+{
+ if (const QAction *action = qobject_cast<const QAction *>(sender())) {
+ if (!readInForm(action->iconText()))
+ updateRecentFileActions(); // File doesn't exist, remove it from settings
+ }
+}
+
+void QDesignerActions::clearRecentFiles()
+{
+ m_settings.setRecentFilesList(QStringList());
+ updateRecentFileActions();
+}
+
+QActionGroup *QDesignerActions::recentFilesActions() const
+{
+ return m_recentFilesActions;
+}
+
+void QDesignerActions::addRecentFile(const QString &fileName)
+{
+ QStringList files = m_settings.recentFilesList();
+ files.removeAll(fileName);
+ files.prepend(fileName);
+ while (files.size() > MaxRecentFiles)
+ files.removeLast();
+
+ m_settings.setRecentFilesList(files);
+ updateRecentFileActions();
+}
+
+QAction *QDesignerActions::openFormAction() const
+{
+ return m_openFormAction;
+}
+
+QAction *QDesignerActions::closeFormAction() const
+{
+ return m_closeFormAction;
+}
+
+QAction *QDesignerActions::minimizeAction() const
+{
+ return m_minimizeAction;
+}
+
+void QDesignerActions::showDesignerHelp()
+{
+ QString url = AssistantClient::designerManualUrl();
+ url += QLatin1String("designer-manual.html");
+ showHelp(url);
+}
+
+void QDesignerActions::showWhatsNew()
+{
+ QString url = AssistantClient::qtReferenceManualUrl();
+ url += QLatin1String("qt4-designer.html");
+ showHelp(url);
+}
+
+void QDesignerActions::helpRequested(const QString &manual, const QString &document)
+{
+ QString url = AssistantClient::documentUrl(manual);
+ url += document;
+ showHelp(url);
+}
+
+void QDesignerActions::showHelp(const QString &url)
+{
+ QString errorMessage;
+ if (!m_assistantClient.showPage(url, &errorMessage))
+ QMessageBox::warning(core()->topLevel(), tr("Assistant"), errorMessage);
+}
+
+void QDesignerActions::aboutDesigner()
+{
+ VersionDialog mb(core()->topLevel());
+ mb.setWindowTitle(tr("About Qt Designer"));
+ if (mb.exec()) {
+ QMessageBox messageBox(QMessageBox::Information, QLatin1String("Easter Egg"),
+ QLatin1String("Easter Egg"), QMessageBox::Ok, core()->topLevel());
+ messageBox.setInformativeText(QLatin1String("The Easter Egg has been removed."));
+ messageBox.exec();
+ }
+}
+
+QAction *QDesignerActions::editWidgets() const
+{
+ return m_editWidgetsAction;
+}
+
+void QDesignerActions::showWidgetSpecificHelp()
+{
+ QString helpId;
+ if (const qdesigner_internal::QDesignerIntegration *integration = qobject_cast<qdesigner_internal::QDesignerIntegration *>(core()->integration()))
+ helpId = integration->contextHelpId();
+
+ if (helpId.isEmpty()) {
+ showDesignerHelp();
+ return;
+ }
+
+ QString errorMessage;
+ const bool rc = m_assistantClient.activateIdentifier(helpId, &errorMessage);
+ if (!rc)
+ QMessageBox::warning(core()->topLevel(), tr("Assistant"), errorMessage);
+}
+
+void QDesignerActions::updateCloseAction()
+{
+ if (m_previewManager->previewCount()) {
+ m_closeFormAction->setText(tr("&Close Preview"));
+ } else {
+ m_closeFormAction->setText(tr("&Close"));
+ }
+}
+
+void QDesignerActions::backupForms()
+{
+ const int count = m_workbench->formWindowCount();
+ if (!count || !ensureBackupDirectories())
+ return;
+
+
+ QStringList tmpFiles;
+ QMap<QString, QString> backupMap;
+ QDir backupDir(m_backupPath);
+ const bool warningsEnabled = qdesigner_internal::QSimpleResource::setWarningsEnabled(false);
+ for (int i = 0; i < count; ++i) {
+ QDesignerFormWindow *fw = m_workbench->formWindow(i);
+ QDesignerFormWindowInterface *fwi = fw->editor();
+
+ QString formBackupName;
+ QTextStream(&formBackupName) << m_backupPath << QDir::separator()
+ << QLatin1String("backup") << i << QLatin1String(".bak");
+
+ QString fwn = QDir::convertSeparators(fwi->fileName());
+ if (fwn.isEmpty())
+ fwn = fw->windowTitle();
+
+ backupMap.insert(fwn, formBackupName);
+
+ QFile file(formBackupName.replace(m_backupPath, m_backupTmpPath));
+ if (file.open(QFile::WriteOnly)){
+ QString contents = fixResourceFileBackupPath(fwi, backupDir);
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(fwi)) {
+ if (fwb->lineTerminatorMode() == qdesigner_internal::FormWindowBase::CRLFLineTerminator)
+ contents.replace(QLatin1Char('\n'), QLatin1String("\r\n"));
+ }
+ const QByteArray utf8Array = contents.toUtf8();
+ if (file.write(utf8Array, utf8Array.size()) != utf8Array.size()) {
+ backupMap.remove(fwn);
+ qdesigner_internal::designerWarning(tr("The backup file %1 could not be written.").arg(file.fileName()));
+ } else
+ tmpFiles.append(formBackupName);
+
+ file.close();
+ }
+ }
+ qdesigner_internal::QSimpleResource::setWarningsEnabled(warningsEnabled);
+ if(!tmpFiles.isEmpty()) {
+ const QStringList backupFiles = backupDir.entryList(QDir::Files);
+ if(!backupFiles.isEmpty()) {
+ QStringListIterator it(backupFiles);
+ while (it.hasNext())
+ backupDir.remove(it.next());
+ }
+
+ QStringListIterator it(tmpFiles);
+ while (it.hasNext()) {
+ const QString tmpName = it.next();
+ QString name(tmpName);
+ name.replace(m_backupTmpPath, m_backupPath);
+ QFile tmpFile(tmpName);
+ if (!tmpFile.copy(name))
+ qdesigner_internal::designerWarning(tr("The backup file %1 could not be written.").arg(name));
+ tmpFile.remove();
+ }
+
+ m_settings.setBackup(backupMap);
+ }
+}
+
+QString QDesignerActions::fixResourceFileBackupPath(QDesignerFormWindowInterface *fwi, const QDir& backupDir)
+{
+ const QString content = fwi->contents();
+ QDomDocument domDoc(QLatin1String("backup"));
+ if(!domDoc.setContent(content))
+ return content;
+
+ const QDomNodeList list = domDoc.elementsByTagName(QLatin1String("resources"));
+ if (list.isEmpty())
+ return content;
+
+ for (int i = 0; i < list.count(); i++) {
+ const QDomNode node = list.at(i);
+ if (!node.isNull()) {
+ const QDomElement element = node.toElement();
+ if(!element.isNull() && element.tagName() == QLatin1String("resources")) {
+ QDomNode childNode = element.firstChild();
+ while (!childNode.isNull()) {
+ QDomElement childElement = childNode.toElement();
+ if(!childElement.isNull() && childElement.tagName() == QLatin1String("include")) {
+ const QString attr = childElement.attribute(QLatin1String("location"));
+ const QString path = fwi->absoluteDir().absoluteFilePath(attr);
+ childElement.setAttribute(QLatin1String("location"), backupDir.relativeFilePath(path));
+ }
+ childNode = childNode.nextSibling();
+ }
+ }
+ }
+ }
+
+
+ return domDoc.toString();
+}
+
+QRect QDesignerActions::fixDialogRect(const QRect &rect) const
+{
+ QRect frameGeometry;
+ const QRect availableGeometry = QApplication::desktop()->availableGeometry(core()->topLevel());
+
+ if (workbench()->mode() == DockedMode) {
+ frameGeometry = core()->topLevel()->frameGeometry();
+ } else
+ frameGeometry = availableGeometry;
+
+ QRect dlgRect = rect;
+ dlgRect.moveCenter(frameGeometry.center());
+
+ // make sure that parts of the dialog are not outside of screen
+ dlgRect.moveBottom(qMin(dlgRect.bottom(), availableGeometry.bottom()));
+ dlgRect.moveRight(qMin(dlgRect.right(), availableGeometry.right()));
+ dlgRect.moveLeft(qMax(dlgRect.left(), availableGeometry.left()));
+ dlgRect.moveTop(qMax(dlgRect.top(), availableGeometry.top()));
+
+ return dlgRect;
+}
+
+void QDesignerActions::showStatusBarMessage(const QString &message) const
+{
+ if (workbench()->mode() == DockedMode) {
+ QStatusBar *bar = qDesigner->mainWindow()->statusBar();
+ if (bar && !bar->isHidden())
+ bar->showMessage(message, 3000);
+ }
+}
+
+void QDesignerActions::setBringAllToFrontVisible(bool visible)
+{
+ m_bringAllToFrontSeparator->setVisible(visible);
+ m_bringAllToFrontAction->setVisible(visible);
+}
+
+void QDesignerActions::setWindowListSeparatorVisible(bool visible)
+{
+ m_windowListSeparatorAction->setVisible(visible);
+}
+
+bool QDesignerActions::ensureBackupDirectories() {
+
+ if (m_backupPath.isEmpty()) {
+ // create names
+ m_backupPath = QDir::homePath();
+ m_backupPath += QDir::separator();
+ m_backupPath += QLatin1String(".designer");
+ m_backupPath += QDir::separator();
+ m_backupPath += QLatin1String("backup");
+ m_backupPath = QDir::convertSeparators(m_backupPath );
+
+ m_backupTmpPath = m_backupPath;
+ m_backupTmpPath += QDir::separator();
+ m_backupTmpPath += QLatin1String("tmp");
+ m_backupTmpPath = QDir::convertSeparators(m_backupTmpPath);
+ }
+
+ // ensure directories
+ const QDir backupDir(m_backupPath);
+ const QDir backupTmpDir(m_backupTmpPath);
+
+ if (!backupDir.exists()) {
+ if (!backupDir.mkpath(m_backupPath)) {
+ qdesigner_internal::designerWarning(tr("The backup directory %1 could not be created.").arg(m_backupPath));
+ return false;
+ }
+ }
+ if (!backupTmpDir.exists()) {
+ if (!backupTmpDir.mkpath(m_backupTmpPath)) {
+ qdesigner_internal::designerWarning(tr("The temporary backup directory %1 could not be created.").arg(m_backupTmpPath));
+ return false;
+ }
+ }
+ return true;
+}
+
+void QDesignerActions::showPreferencesDialog()
+{
+ PreferencesDialog preferencesDialog(workbench()->core(), m_core->topLevel());
+ preferencesDialog.exec();
+}
+
+void QDesignerActions::showAppFontDialog()
+{
+ if (!m_appFontDialog) // Might get deleted when switching ui modes
+ m_appFontDialog = new AppFontDialog(core()->topLevel());
+ m_appFontDialog->show();
+ m_appFontDialog->raise();
+}
+
+QPixmap QDesignerActions::createPreviewPixmap(QDesignerFormWindowInterface *fw)
+{
+ const QCursor oldCursor = core()->topLevel()->cursor();
+ core()->topLevel()->setCursor(Qt::WaitCursor);
+
+ QString errorMessage;
+ const QPixmap pixmap = m_previewManager->createPreviewPixmap(fw, QString(), &errorMessage);
+ core()->topLevel()->setCursor(oldCursor);
+ if (pixmap.isNull()) {
+ QMessageBox::warning(fw, tr("Preview failed"), errorMessage);
+ }
+ return pixmap;
+}
+
+qdesigner_internal::PreviewConfiguration QDesignerActions::previewConfiguration()
+{
+ qdesigner_internal::PreviewConfiguration pc;
+ QDesignerSharedSettings settings(core());
+ if (settings.isCustomPreviewConfigurationEnabled())
+ pc = settings.customPreviewConfiguration();
+ return pc;
+}
+
+void QDesignerActions::savePreviewImage()
+{
+ const char *format = "png";
+
+ QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow();
+ if (!fw)
+ return;
+
+ QImage image;
+ const QString extension = QString::fromAscii(format);
+ const QString filter = tr("Image files (*.%1)").arg(extension);
+
+ QString suggestion = fw->fileName();
+ if (!suggestion.isEmpty()) {
+ suggestion = QFileInfo(suggestion).baseName();
+ suggestion += QLatin1Char('.');
+ suggestion += extension;
+ }
+ do {
+ const QString fileName = getSaveFileNameWithExtension(fw, tr("Save Image"), suggestion, filter, extension);
+ if (fileName.isEmpty())
+ break;
+
+ if (image.isNull()) {
+ const QPixmap pixmap = createPreviewPixmap(fw);
+ if (pixmap.isNull())
+ break;
+
+ image = pixmap.toImage();
+ }
+
+ if (image.save(fileName, format)) {
+ showStatusBarMessage(tr("Saved image %1.").arg(QFileInfo(fileName).fileName()));
+ break;
+ }
+
+ QMessageBox box(QMessageBox::Warning, tr("Save Image"),
+ tr("The file %1 could not be written.").arg( fileName),
+ QMessageBox::Retry|QMessageBox::Cancel, fw);
+ if (box.exec() == QMessageBox::Cancel)
+ break;
+ } while (true);
+}
+
+void QDesignerActions::formWindowCountChanged()
+{
+ const bool enabled = m_core->formWindowManager()->formWindowCount() == 0;
+ /* Disable the application font action if there are form windows open
+ * as the reordering of the fonts sets font properties to 'changed'
+ * and overloaded fonts are not updated. */
+ static const QString disabledTip = tr("Please close all forms to enable the loading of additional fonts.");
+ m_appFontAction->setEnabled(enabled);
+ m_appFontAction->setStatusTip(enabled ? QString() : disabledTip);
+}
+
+void QDesignerActions::printPreviewImage()
+{
+#ifndef QT_NO_PRINTER
+ QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow();
+ if (!fw)
+ return;
+
+ if (!m_printer)
+ m_printer = new QPrinter(QPrinter::HighResolution);
+
+ m_printer->setFullPage(false);
+
+ // Grab the image to be able to a suggest suitable orientation
+ const QPixmap pixmap = createPreviewPixmap(fw);
+ if (pixmap.isNull())
+ return;
+
+ const QSizeF pixmapSize = pixmap.size();
+ m_printer->setOrientation( pixmapSize.width() > pixmapSize.height() ? QPrinter::Landscape : QPrinter::Portrait);
+
+ // Printer parameters
+ QPrintDialog dialog(m_printer, fw);
+ if (!dialog.exec())
+ return;
+
+ const QCursor oldCursor = core()->topLevel()->cursor();
+ core()->topLevel()->setCursor(Qt::WaitCursor);
+ // Estimate of required scaling to make form look the same on screen and printer.
+ const double suggestedScaling = static_cast<double>(m_printer->physicalDpiX()) / static_cast<double>(fw->physicalDpiX());
+
+ QPainter painter(m_printer);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+
+ // Clamp to page
+ const QRectF page = painter.viewport();
+ const double maxScaling = qMin(page.size().width() / pixmapSize.width(), page.size().height() / pixmapSize.height());
+ const double scaling = qMin(suggestedScaling, maxScaling);
+
+ const double xOffset = page.left() + qMax(0.0, (page.size().width() - scaling * pixmapSize.width()) / 2.0);
+ const double yOffset = page.top() + qMax(0.0, (page.size().height() - scaling * pixmapSize.height()) / 2.0);
+
+ // Draw.
+ painter.translate(xOffset, yOffset);
+ painter.scale(scaling, scaling);
+ painter.drawPixmap(0, 0, pixmap);
+ core()->topLevel()->setCursor(oldCursor);
+
+ showStatusBarMessage(tr("Printed %1.").arg(QFileInfo(fw->fileName()).fileName()));
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_actions.h b/src/designer/src/designer/qdesigner_actions.h
new file mode 100644
index 000000000..910901bcb
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_actions.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_ACTIONS_H
+#define QDESIGNER_ACTIONS_H
+
+#include "assistantclient.h"
+#include "qdesigner_settings.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtGui/QPrinter>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerWorkbench;
+
+class QDir;
+class QTimer;
+class QAction;
+class QActionGroup;
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class AppFontDialog;
+
+class QRect;
+class QWidget;
+class QPixmap;
+class QMenu;
+
+namespace qdesigner_internal {
+ class PreviewConfiguration;
+ class PreviewManager;
+}
+
+class QDesignerActions: public QObject
+{
+ Q_OBJECT
+public:
+ explicit QDesignerActions(QDesignerWorkbench *mainWindow);
+ virtual ~QDesignerActions();
+
+ QDesignerWorkbench *workbench() const;
+ QDesignerFormEditorInterface *core() const;
+
+ bool saveForm(QDesignerFormWindowInterface *fw);
+ bool readInForm(const QString &fileName);
+ bool writeOutForm(QDesignerFormWindowInterface *formWindow, const QString &fileName);
+
+ QActionGroup *fileActions() const;
+ QActionGroup *recentFilesActions() const;
+ QActionGroup *editActions() const;
+ QActionGroup *formActions() const;
+ QActionGroup *settingsActions() const;
+ QActionGroup *windowActions() const;
+ QActionGroup *toolActions() const;
+ QActionGroup *helpActions() const;
+ QActionGroup *uiMode() const;
+ QActionGroup *styleActions() const;
+ // file actions
+ QAction *openFormAction() const;
+ QAction *closeFormAction() const;
+ // window actions
+ QAction *minimizeAction() const;
+ // edit mode actions
+ QAction *editWidgets() const;
+ // form actions
+ QAction *previewFormAction() const;
+ QAction *viewCodeAction() const;
+
+ void setBringAllToFrontVisible(bool visible);
+ void setWindowListSeparatorVisible(bool visible);
+
+ bool openForm(QWidget *parent);
+
+ QString uiExtension() const;
+
+ // Boolean dynamic property set on actions to
+ // show them in the default toolbar layout
+ static const char *defaultToolbarPropertyName;
+
+public slots:
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+ void createForm();
+ void slotOpenForm();
+ void helpRequested(const QString &manual, const QString &document);
+
+signals:
+ void useBigIcons(bool);
+
+private slots:
+ void saveForm();
+ void saveFormAs();
+ void saveAllForms();
+ void saveFormAsTemplate();
+ void viewCode();
+ void notImplementedYet();
+ void shutdown();
+ void editWidgetsSlot();
+ void openRecentForm();
+ void clearRecentFiles();
+ void closeForm();
+ void showDesignerHelp();
+ void showWhatsNew();
+ void aboutDesigner();
+ void showWidgetSpecificHelp();
+ void backupForms();
+ void showNewFormDialog(const QString &fileName);
+ void showPreferencesDialog();
+ void showAppFontDialog();
+ void savePreviewImage();
+ void printPreviewImage();
+ void updateCloseAction();
+ void formWindowCountChanged();
+ void formWindowSettingsChanged(QDesignerFormWindowInterface *fw);
+
+private:
+ QAction *createRecentFilesMenu();
+ bool saveFormAs(QDesignerFormWindowInterface *fw);
+ void fixActionContext();
+ void updateRecentFileActions();
+ void addRecentFile(const QString &fileName);
+ void showHelp(const QString &help);
+ void closePreview();
+ QRect fixDialogRect(const QRect &rect) const;
+ QString fixResourceFileBackupPath(QDesignerFormWindowInterface *fwi, const QDir& backupDir);
+ void showStatusBarMessage(const QString &message) const;
+ QActionGroup *createHelpActions();
+ bool ensureBackupDirectories();
+ QPixmap createPreviewPixmap(QDesignerFormWindowInterface *fw);
+ qdesigner_internal::PreviewConfiguration previewConfiguration();
+
+ enum { MaxRecentFiles = 10 };
+ QDesignerWorkbench *m_workbench;
+ QDesignerFormEditorInterface *m_core;
+ QDesignerSettings m_settings;
+ AssistantClient m_assistantClient;
+ QString m_openDirectory;
+ QString m_saveDirectory;
+
+
+ QString m_backupPath;
+ QString m_backupTmpPath;
+
+ QTimer* m_backupTimer;
+
+ QActionGroup *m_fileActions;
+ QActionGroup *m_recentFilesActions;
+ QActionGroup *m_editActions;
+ QActionGroup *m_formActions;
+ QActionGroup *m_settingsActions;
+ QActionGroup *m_windowActions;
+ QActionGroup *m_toolActions;
+ QActionGroup *m_helpActions;
+ QActionGroup *m_styleActions;
+
+ QAction *m_editWidgetsAction;
+
+ QAction *m_newFormAction;
+ QAction *m_openFormAction;
+ QAction *m_saveFormAction;
+ QAction *m_saveFormAsAction;
+ QAction *m_saveAllFormsAction;
+ QAction *m_saveFormAsTemplateAction;
+ QAction *m_closeFormAction;
+ QAction *m_savePreviewImageAction;
+ QAction *m_printPreviewAction;
+
+ QAction *m_quitAction;
+
+ QAction *m_previewFormAction;
+ QAction *m_viewCodeAction;
+
+ QAction *m_minimizeAction;
+ QAction *m_bringAllToFrontSeparator;
+ QAction *m_bringAllToFrontAction;
+ QAction *m_windowListSeparatorAction;
+
+ QAction *m_preferencesAction;
+ QAction *m_appFontAction;
+
+ QPointer<AppFontDialog> m_appFontDialog;
+
+#ifndef QT_NO_PRINTER
+ QPrinter *m_printer;
+#endif
+
+ qdesigner_internal::PreviewManager *m_previewManager;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_ACTIONS_H
diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.cpp b/src/designer/src/designer/qdesigner_appearanceoptions.cpp
new file mode 100644
index 000000000..f5b3f3d6d
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_appearanceoptions.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_appearanceoptions.h"
+#include "ui_qdesigner_appearanceoptions.h"
+
+#include "qdesigner_settings.h"
+#include "qdesigner_toolwindow.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+// ---------------- AppearanceOptions
+AppearanceOptions::AppearanceOptions() :
+ uiMode(DockedMode)
+{
+}
+
+bool AppearanceOptions::equals(const AppearanceOptions &rhs) const
+{
+ return uiMode == rhs.uiMode && toolWindowFontSettings == rhs.toolWindowFontSettings;
+}
+
+void AppearanceOptions::toSettings(QDesignerSettings &settings) const
+{
+ settings.setUiMode(uiMode);
+ settings.setToolWindowFont(toolWindowFontSettings);
+}
+
+void AppearanceOptions::fromSettings(const QDesignerSettings &settings)
+{
+ uiMode = settings.uiMode();
+ toolWindowFontSettings = settings.toolWindowFont();
+}
+
+// ---------------- QDesignerAppearanceOptionsWidget
+QDesignerAppearanceOptionsWidget::QDesignerAppearanceOptionsWidget(QWidget *parent) :
+ QWidget(parent),
+ m_ui(new Ui::AppearanceOptionsWidget),
+ m_initialUIMode(NeutralMode)
+{
+ m_ui->setupUi(this);
+
+ m_ui->m_uiModeCombo->addItem(tr("Docked Window"), QVariant(DockedMode));
+ m_ui->m_uiModeCombo->addItem(tr("Multiple Top-Level Windows"), QVariant(TopLevelMode));
+ connect(m_ui->m_uiModeCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(slotUiModeComboChanged()));
+
+ m_ui->m_fontPanel->setCheckable(true);
+ m_ui->m_fontPanel->setTitle(tr("Toolwindow Font"));
+
+}
+
+QDesignerAppearanceOptionsWidget::~QDesignerAppearanceOptionsWidget()
+{
+ delete m_ui;
+}
+
+UIMode QDesignerAppearanceOptionsWidget::uiMode() const
+{
+ return static_cast<UIMode>(m_ui->m_uiModeCombo->itemData(m_ui->m_uiModeCombo->currentIndex()).toInt());
+}
+
+AppearanceOptions QDesignerAppearanceOptionsWidget::appearanceOptions() const
+{
+ AppearanceOptions rc;
+ rc.uiMode = uiMode();
+ rc.toolWindowFontSettings.m_font = m_ui->m_fontPanel->selectedFont();
+ rc.toolWindowFontSettings.m_useFont = m_ui->m_fontPanel->isChecked();
+ rc.toolWindowFontSettings.m_writingSystem = m_ui->m_fontPanel->writingSystem();
+ return rc;
+}
+
+void QDesignerAppearanceOptionsWidget::setAppearanceOptions(const AppearanceOptions &ao)
+{
+ m_initialUIMode = ao.uiMode;
+ m_ui->m_uiModeCombo->setCurrentIndex(m_ui->m_uiModeCombo->findData(QVariant(ao.uiMode)));
+ m_ui->m_fontPanel->setWritingSystem(ao.toolWindowFontSettings.m_writingSystem);
+ m_ui->m_fontPanel->setSelectedFont(ao.toolWindowFontSettings.m_font);
+ m_ui->m_fontPanel->setChecked(ao.toolWindowFontSettings.m_useFont);
+}
+
+void QDesignerAppearanceOptionsWidget::slotUiModeComboChanged()
+{
+ emit uiModeChanged(m_initialUIMode != uiMode());
+}
+
+// ----------- QDesignerAppearanceOptionsPage
+QDesignerAppearanceOptionsPage::QDesignerAppearanceOptionsPage(QDesignerFormEditorInterface *core) :
+ m_core(core)
+{
+}
+
+QString QDesignerAppearanceOptionsPage::name() const
+{
+ //: Tab in preferences dialog
+ return QCoreApplication::translate("QDesignerAppearanceOptionsPage", "Appearance");
+}
+
+QWidget *QDesignerAppearanceOptionsPage::createPage(QWidget *parent)
+{
+ m_widget = new QDesignerAppearanceOptionsWidget(parent);
+ m_initialOptions.fromSettings(QDesignerSettings(m_core));
+ m_widget->setAppearanceOptions(m_initialOptions);
+ return m_widget;
+}
+
+void QDesignerAppearanceOptionsPage::apply()
+{
+ if (m_widget) {
+ const AppearanceOptions newOptions = m_widget->appearanceOptions();
+ if (newOptions != m_initialOptions) {
+ QDesignerSettings settings(m_core);
+ newOptions.toSettings(settings);
+ QTimer::singleShot(0, this, SIGNAL(settingsChangedDelayed()));
+ m_initialOptions = newOptions;
+ }
+ }
+}
+
+void QDesignerAppearanceOptionsPage::finish()
+{
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.h b/src/designer/src/designer/qdesigner_appearanceoptions.h
new file mode 100644
index 000000000..a6e4f9a49
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_appearanceoptions.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_APPEARANCEOPTIONS_H
+#define QDESIGNER_APPEARANCEOPTIONS_H
+
+#include "designer_enums.h"
+#include "qdesigner_toolwindow.h"
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerSettings;
+
+namespace Ui {
+ class AppearanceOptionsWidget;
+}
+
+/* AppearanceOptions data */
+struct AppearanceOptions {
+ AppearanceOptions();
+ bool equals(const AppearanceOptions&) const;
+ void toSettings(QDesignerSettings &) const;
+ void fromSettings(const QDesignerSettings &);
+
+ UIMode uiMode;
+ ToolWindowFontSettings toolWindowFontSettings;
+};
+
+inline bool operator==(const AppearanceOptions &ao1, const AppearanceOptions &ao2)
+{
+ return ao1.equals(ao2);
+}
+
+inline bool operator!=(const AppearanceOptions &ao1, const AppearanceOptions &ao2)
+{
+ return !ao1.equals(ao2);
+}
+
+/* QDesignerAppearanceOptionsWidget: Let the user edit AppearanceOptions */
+class QDesignerAppearanceOptionsWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QDesignerAppearanceOptionsWidget(QWidget *parent = 0);
+ ~QDesignerAppearanceOptionsWidget();
+
+ AppearanceOptions appearanceOptions() const;
+ void setAppearanceOptions(const AppearanceOptions &ao);
+
+signals:
+ void uiModeChanged(bool modified);
+
+private slots:
+ void slotUiModeComboChanged();
+
+private:
+ UIMode uiMode() const;
+
+ Ui::AppearanceOptionsWidget *m_ui;
+ UIMode m_initialUIMode;
+};
+
+/* The options page for appearance options. Emits a Timer-0 delayed changed
+ * signal to allow the preferences dialog to close (and be deleted) before a
+ * possible switch from docked mode to top-level mode happens. (The switch
+ * would delete the main window, which the preference dialog is a child of
+ * -> BOOM) */
+
+class QDesignerAppearanceOptionsPage : public QObject, public QDesignerOptionsPageInterface
+{
+ Q_OBJECT
+
+public:
+ QDesignerAppearanceOptionsPage(QDesignerFormEditorInterface *core);
+
+ QString name() const;
+ QWidget *createPage(QWidget *parent);
+ virtual void apply();
+ virtual void finish();
+
+signals:
+ void settingsChangedDelayed();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ QPointer<QDesignerAppearanceOptionsWidget> m_widget;
+ AppearanceOptions m_initialOptions;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_APPEARANCEOPTIONS_H
diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.ui b/src/designer/src/designer/qdesigner_appearanceoptions.ui
new file mode 100644
index 000000000..a5582f2ab
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_appearanceoptions.ui
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AppearanceOptionsWidget</class>
+ <widget class="QWidget" name="AppearanceOptionsWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>325</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="m_uiModeGroupBox">
+ <property name="title">
+ <string>User Interface Mode</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QComboBox" name="m_uiModeCombo"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="FontPanel" name="m_fontPanel"/>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>FontPanel</class>
+ <extends>QGroupBox</extends>
+ <header>fontpanel.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/designer/qdesigner_formwindow.cpp b/src/designer/src/designer/qdesigner_formwindow.cpp
new file mode 100644
index 000000000..4770d2a58
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_formwindow.cpp
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_formwindow.h"
+#include "qdesigner_workbench.h"
+#include "formwindowbase_p.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QEvent>
+#include <QtCore/QFile>
+
+#include <QtGui/QAction>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QUndoCommand>
+#include <QtGui/QWindowStateChangeEvent>
+
+QT_BEGIN_NAMESPACE
+
+QDesignerFormWindow::QDesignerFormWindow(QDesignerFormWindowInterface *editor, QDesignerWorkbench *workbench, QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(parent, flags),
+ m_editor(editor),
+ m_workbench(workbench),
+ m_action(new QAction(this)),
+ m_initialized(false),
+ m_windowTitleInitialized(false)
+{
+ Q_ASSERT(workbench);
+
+ setMaximumSize(0xFFF, 0xFFF);
+ QDesignerFormEditorInterface *core = workbench->core();
+
+ if (m_editor) {
+ m_editor->setParent(this);
+ } else {
+ m_editor = core->formWindowManager()->createFormWindow(this);
+ }
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->addWidget(m_editor);
+
+ m_action->setCheckable(true);
+
+ connect(m_editor->commandHistory(), SIGNAL(indexChanged(int)), this, SLOT(updateChanged()));
+ connect(m_editor, SIGNAL(geometryChanged()), this, SLOT(geometryChanged()));
+ qdesigner_internal::FormWindowBase::setupDefaultAction(m_editor);
+}
+
+QDesignerFormWindow::~QDesignerFormWindow()
+{
+ if (workbench())
+ workbench()->removeFormWindow(this);
+}
+
+QAction *QDesignerFormWindow::action() const
+{
+ return m_action;
+}
+
+void QDesignerFormWindow::changeEvent(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::WindowTitleChange:
+ m_action->setText(windowTitle().remove(QLatin1String("[*]")));
+ break;
+ case QEvent::WindowIconChange:
+ m_action->setIcon(windowIcon());
+ break;
+ case QEvent::WindowStateChange: {
+ const QWindowStateChangeEvent *wsce = static_cast<const QWindowStateChangeEvent *>(e);
+ const bool wasMinimized = Qt::WindowMinimized & wsce->oldState();
+ const bool isMinimizedNow = isMinimized();
+ if (wasMinimized != isMinimizedNow )
+ emit minimizationStateChanged(m_editor, isMinimizedNow);
+ }
+ break;
+ default:
+ break;
+ }
+ QWidget::changeEvent(e);
+}
+
+QRect QDesignerFormWindow::geometryHint() const
+{
+ const QPoint point(0, 0);
+ // If we have a container, we want to be just as big.
+ // QMdiSubWindow attempts to resize its children to sizeHint() when switching user interface modes.
+ if (QWidget *mainContainer = m_editor->mainContainer())
+ return QRect(point, mainContainer->size());
+
+ return QRect(point, sizeHint());
+}
+
+QDesignerFormWindowInterface *QDesignerFormWindow::editor() const
+{
+ return m_editor;
+}
+
+QDesignerWorkbench *QDesignerFormWindow::workbench() const
+{
+ return m_workbench;
+}
+
+void QDesignerFormWindow::firstShow()
+{
+ // Set up handling of file name changes and set initial title.
+ if (!m_windowTitleInitialized) {
+ m_windowTitleInitialized = true;
+ if (m_editor) {
+ connect(m_editor, SIGNAL(fileNameChanged(QString)), this, SLOT(updateWindowTitle(QString)));
+ updateWindowTitle(m_editor->fileName());
+ updateChanged();
+ }
+ }
+ show();
+}
+
+int QDesignerFormWindow::getNumberOfUntitledWindows() const
+{
+ const int totalWindows = m_workbench->formWindowCount();
+ if (!totalWindows)
+ return 0;
+
+ int maxUntitled = 0;
+ // Find the number of untitled windows excluding ourselves.
+ // Do not fall for 'untitled.ui', match with modified place holder.
+ // This will cause some problems with i18n, but for now I need the string to be "static"
+ QRegExp rx(QLatin1String("untitled( (\\d+))?\\[\\*\\]"));
+ for (int i = 0; i < totalWindows; ++i) {
+ QDesignerFormWindow *fw = m_workbench->formWindow(i);
+ if (fw != this) {
+ const QString title = m_workbench->formWindow(i)->windowTitle();
+ if (rx.indexIn(title) != -1) {
+ if (maxUntitled == 0)
+ ++maxUntitled;
+ if (rx.captureCount() > 1) {
+ const QString numberCapture = rx.cap(2);
+ if (!numberCapture.isEmpty())
+ maxUntitled = qMax(numberCapture.toInt(), maxUntitled);
+ }
+ }
+ }
+ }
+ return maxUntitled;
+}
+
+void QDesignerFormWindow::updateWindowTitle(const QString &fileName)
+{
+ if (!m_windowTitleInitialized) {
+ m_windowTitleInitialized = true;
+ if (m_editor)
+ connect(m_editor, SIGNAL(fileNameChanged(QString)), this, SLOT(updateWindowTitle(QString)));
+ }
+
+ QString fileNameTitle;
+ if (fileName.isEmpty()) {
+ fileNameTitle = QLatin1String("untitled");
+ if (const int maxUntitled = getNumberOfUntitledWindows()) {
+ fileNameTitle += QLatin1Char(' ');
+ fileNameTitle += QString::number(maxUntitled + 1);
+ }
+ } else {
+ fileNameTitle = QFileInfo(fileName).fileName();
+ }
+
+ if (const QWidget *mc = m_editor->mainContainer()) {
+ setWindowIcon(mc->windowIcon());
+ setWindowTitle(tr("%1 - %2[*]").arg(mc->windowTitle()).arg(fileNameTitle));
+ } else {
+ setWindowTitle(fileNameTitle);
+ }
+}
+
+void QDesignerFormWindow::closeEvent(QCloseEvent *ev)
+{
+ if (m_editor->isDirty()) {
+ raise();
+ QMessageBox box(QMessageBox::Information, tr("Save Form?"),
+ tr("Do you want to save the changes to this document before closing?"),
+ QMessageBox::Discard | QMessageBox::Cancel | QMessageBox::Save, m_editor);
+ box.setInformativeText(tr("If you don't save, your changes will be lost."));
+ box.setWindowModality(Qt::WindowModal);
+ static_cast<QPushButton *>(box.button(QMessageBox::Save))->setDefault(true);
+
+ switch (box.exec()) {
+ case QMessageBox::Save: {
+ bool ok = workbench()->saveForm(m_editor);
+ ev->setAccepted(ok);
+ m_editor->setDirty(!ok);
+ break;
+ }
+ case QMessageBox::Discard:
+ m_editor->setDirty(false); // Not really necessary, but stops problems if we get close again.
+ ev->accept();
+ break;
+ case QMessageBox::Cancel:
+ ev->ignore();
+ break;
+ }
+ }
+}
+
+void QDesignerFormWindow::updateChanged()
+{
+ // Sometimes called after form window destruction.
+ if (m_editor) {
+ setWindowModified(m_editor->isDirty());
+ updateWindowTitle(m_editor->fileName());
+ }
+}
+
+void QDesignerFormWindow::resizeEvent(QResizeEvent *rev)
+{
+ if(m_initialized) {
+ m_editor->setDirty(true);
+ setWindowModified(true);
+ }
+
+ m_initialized = true;
+ QWidget::resizeEvent(rev);
+}
+
+void QDesignerFormWindow::geometryChanged()
+{
+ // If the form window changes, re-update the geometry of the current widget in the property editor.
+ // Note that in the case of layouts, non-maincontainer widgets must also be updated,
+ // so, do not do it for the main container only
+ const QDesignerFormEditorInterface *core = m_editor->core();
+ QObject *object = core->propertyEditor()->object();
+ if (object == 0 || !object->isWidgetType())
+ return;
+ static const QString geometryProperty = QLatin1String("geometry");
+ const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), object);
+ const int geometryIndex = sheet->indexOf(geometryProperty);
+ if (geometryIndex == -1)
+ return;
+ core->propertyEditor()->setPropertyValue(geometryProperty, sheet->property(geometryIndex));
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_formwindow.h b/src/designer/src/designer/qdesigner_formwindow.h
new file mode 100644
index 000000000..5ee4c40b4
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_formwindow.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_FORMWINDOW_H
+#define QDESIGNER_FORMWINDOW_H
+
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerWorkbench;
+class QDesignerFormWindowInterface;
+
+class QDesignerFormWindow: public QWidget
+{
+ Q_OBJECT
+public:
+ QDesignerFormWindow(QDesignerFormWindowInterface *formWindow, QDesignerWorkbench *workbench,
+ QWidget *parent = 0, Qt::WindowFlags flags = 0);
+
+ void firstShow();
+
+ virtual ~QDesignerFormWindow();
+
+ QAction *action() const;
+ QDesignerWorkbench *workbench() const;
+ QDesignerFormWindowInterface *editor() const;
+
+ QRect geometryHint() const;
+
+public slots:
+ void updateChanged();
+
+private slots:
+ void updateWindowTitle(const QString &fileName);
+ void geometryChanged();
+
+signals:
+ void minimizationStateChanged(QDesignerFormWindowInterface *formWindow, bool minimized);
+ void triggerAction();
+
+protected:
+ virtual void changeEvent(QEvent *e);
+ virtual void closeEvent(QCloseEvent *ev);
+ virtual void resizeEvent(QResizeEvent* rev);
+
+private:
+ int getNumberOfUntitledWindows() const;
+ QPointer<QDesignerFormWindowInterface> m_editor;
+ QPointer<QDesignerWorkbench> m_workbench;
+ QAction *m_action;
+ bool m_initialized;
+ bool m_windowTitleInitialized;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_FORMWINDOW_H
diff --git a/src/designer/src/designer/qdesigner_pch.h b/src/designer/src/designer/qdesigner_pch.h
new file mode 100644
index 000000000..12eb3f376
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_pch.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if defined __cplusplus
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtCore/QSettings>
+#include <QtCore/qdebug.h>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QHeaderView>
+#include <QtGui/QMessageBox>
+#include <QtGui/QVBoxLayout>
+#include <QtDesigner/abstractformeditor.h>
+#include <QtDesigner/abstractformwindow.h>
+
+#include "qdesigner.h"
+#include "qdesigner_formwindow.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_workbench.h"
+#endif
diff --git a/src/designer/src/designer/qdesigner_server.cpp b/src/designer/src/designer/qdesigner_server.cpp
new file mode 100644
index 000000000..bffee5b7e
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_server.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QStringList>
+
+#include <QtNetwork/QHostAddress>
+#include <QtNetwork/QTcpServer>
+#include <QtNetwork/QTcpSocket>
+
+#include "qdesigner.h"
+#include "qdesigner_server.h"
+
+#include <qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+// ### review
+
+QDesignerServer::QDesignerServer(QObject *parent)
+ : QObject(parent)
+{
+ m_socket = 0;
+ m_server = new QTcpServer(this);
+ m_server->listen(QHostAddress::LocalHost, 0);
+ if (m_server->isListening())
+ {
+ connect(m_server, SIGNAL(newConnection()),
+ this, SLOT(handleNewConnection()));
+ }
+}
+
+QDesignerServer::~QDesignerServer()
+{
+}
+
+quint16 QDesignerServer::serverPort() const
+{
+ return m_server ? m_server->serverPort() : 0;
+}
+
+void QDesignerServer::sendOpenRequest(int port, const QStringList &files)
+{
+ QTcpSocket *sSocket = new QTcpSocket();
+ sSocket->connectToHost(QHostAddress::LocalHost, port);
+ if(sSocket->waitForConnected(3000))
+ {
+ foreach(const QString &file, files)
+ {
+ QFileInfo fi(file);
+ sSocket->write(fi.absoluteFilePath().toUtf8() + '\n');
+ }
+ sSocket->waitForBytesWritten(3000);
+ sSocket->close();
+ }
+ delete sSocket;
+}
+
+void QDesignerServer::readFromClient()
+{
+ while (m_socket->canReadLine()) {
+ QString file = QString::fromUtf8(m_socket->readLine());
+ if (!file.isNull()) {
+ file.remove(QLatin1Char('\n'));
+ file.remove(QLatin1Char('\r'));
+ qDesigner->postEvent(qDesigner, new QFileOpenEvent(file));
+ }
+ }
+}
+
+void QDesignerServer::socketClosed()
+{
+ m_socket = 0;
+}
+
+void QDesignerServer::handleNewConnection()
+{
+ // no need for more than one connection
+ if (m_socket == 0) {
+ m_socket = m_server->nextPendingConnection();
+ connect(m_socket, SIGNAL(readyRead()),
+ this, SLOT(readFromClient()));
+ connect(m_socket, SIGNAL(disconnected()),
+ this, SLOT(socketClosed()));
+ }
+}
+
+
+QDesignerClient::QDesignerClient(quint16 port, QObject *parent)
+: QObject(parent)
+{
+ m_socket = new QTcpSocket(this);
+ m_socket->connectToHost(QHostAddress::LocalHost, port);
+ connect(m_socket, SIGNAL(readyRead()),
+ this, SLOT(readFromSocket()));
+
+}
+
+QDesignerClient::~QDesignerClient()
+{
+ m_socket->close();
+ m_socket->flush();
+}
+
+void QDesignerClient::readFromSocket()
+{
+ while (m_socket->canReadLine()) {
+ QString file = QString::fromUtf8(m_socket->readLine());
+ if (!file.isNull()) {
+ file.remove(QLatin1Char('\n'));
+ file.remove(QLatin1Char('\r'));
+ if (QFile::exists(file))
+ qDesigner->postEvent(qDesigner, new QFileOpenEvent(file));
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_server.h b/src/designer/src/designer/qdesigner_server.h
new file mode 100644
index 000000000..3aeeebdee
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_server.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_SERVER_H
+#define QDESIGNER_SERVER_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QTcpServer;
+class QTcpSocket;
+
+class QDesignerServer: public QObject
+{
+ Q_OBJECT
+public:
+ explicit QDesignerServer(QObject *parent = 0);
+ virtual ~QDesignerServer();
+
+ quint16 serverPort() const;
+
+ static void sendOpenRequest(int port, const QStringList &files);
+
+private slots:
+ void handleNewConnection();
+ void readFromClient();
+ void socketClosed();
+
+private:
+ QTcpServer *m_server;
+ QTcpSocket *m_socket;
+};
+
+class QDesignerClient: public QObject
+{
+ Q_OBJECT
+public:
+ explicit QDesignerClient(quint16 port, QObject *parent = 0);
+ virtual ~QDesignerClient();
+
+private slots:
+ void readFromSocket();
+
+private:
+ QTcpSocket *m_socket;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_SERVER_H
diff --git a/src/designer/src/designer/qdesigner_settings.cpp b/src/designer/src/designer/qdesigner_settings.cpp
new file mode 100644
index 000000000..89bec14f2
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_settings.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_workbench.h"
+
+#include <abstractformeditor.h>
+#include <abstractsettings_p.h>
+#include <qdesigner_utils_p.h>
+#include <previewmanager_p.h>
+
+#include <QtCore/QVariant>
+#include <QtCore/QDir>
+
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QStyle>
+#include <QtGui/QListView>
+
+#include <QtCore/qdebug.h>
+
+enum { debugSettings = 0 };
+
+QT_BEGIN_NAMESPACE
+
+static const char *newFormShowKey = "newFormDialog/ShowOnStartup";
+
+// Change the version whenever the arrangement changes significantly.
+static const char *mainWindowStateKey = "MainWindowState45";
+static const char *toolBarsStateKey = "ToolBarsState45";
+
+static const char *backupOrgListKey = "backup/fileListOrg";
+static const char *backupBakListKey = "backup/fileListBak";
+static const char *recentFilesListKey = "recentFilesList";
+
+QDesignerSettings::QDesignerSettings(QDesignerFormEditorInterface *core) :
+ qdesigner_internal::QDesignerSharedSettings(core)
+{
+}
+
+void QDesignerSettings::setValue(const QString &key, const QVariant &value)
+{
+ settings()->setValue(key, value);
+}
+
+QVariant QDesignerSettings::value(const QString &key, const QVariant &defaultValue) const
+{
+ return settings()->value(key, defaultValue);
+}
+
+static inline QChar modeChar(UIMode mode)
+{
+ return QLatin1Char(static_cast<char>(mode) + '0');
+}
+
+void QDesignerSettings::saveGeometryFor(const QWidget *w)
+{
+ Q_ASSERT(w && !w->objectName().isEmpty());
+ QDesignerSettingsInterface *s = settings();
+ const bool visible = w->isVisible();
+ if (debugSettings)
+ qDebug() << Q_FUNC_INFO << w << "visible=" << visible;
+ s->beginGroup(w->objectName());
+ s->setValue(QLatin1String("visible"), visible);
+ s->setValue(QLatin1String("geometry"), w->saveGeometry());
+ s->endGroup();
+}
+
+void QDesignerSettings::restoreGeometry(QWidget *w, QRect fallBack) const
+{
+ Q_ASSERT(w && !w->objectName().isEmpty());
+ const QString key = w->objectName();
+ const QByteArray ba(settings()->value(key + QLatin1String("/geometry")).toByteArray());
+ const bool visible = settings()->value(key + QLatin1String("/visible"), true).toBool();
+
+ if (debugSettings)
+ qDebug() << Q_FUNC_INFO << w << fallBack << "visible=" << visible;
+ if (ba.isEmpty()) {
+ /// Apply default geometry, check for null and maximal size
+ if (fallBack.isNull())
+ fallBack = QRect(QPoint(0, 0), w->sizeHint());
+ if (fallBack.size() == QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)) {
+ w->setWindowState(w->windowState() | Qt::WindowMaximized);
+ } else {
+ w->move(fallBack.topLeft());
+ w->resize(fallBack.size());
+ }
+ } else {
+ w->restoreGeometry(ba);
+ }
+
+ if (visible)
+ w->show();
+}
+
+QStringList QDesignerSettings::recentFilesList() const
+{
+ return settings()->value(QLatin1String(recentFilesListKey)).toStringList();
+}
+
+void QDesignerSettings::setRecentFilesList(const QStringList &sl)
+{
+ settings()->setValue(QLatin1String(recentFilesListKey), sl);
+}
+
+void QDesignerSettings::setShowNewFormOnStartup(bool showIt)
+{
+ settings()->setValue(QLatin1String(newFormShowKey), showIt);
+}
+
+bool QDesignerSettings::showNewFormOnStartup() const
+{
+ return settings()->value(QLatin1String(newFormShowKey), true).toBool();
+}
+
+QByteArray QDesignerSettings::mainWindowState(UIMode mode) const
+{
+ return settings()->value(QLatin1String(mainWindowStateKey) + modeChar(mode)).toByteArray();
+}
+
+void QDesignerSettings::setMainWindowState(UIMode mode, const QByteArray &mainWindowState)
+{
+ settings()->setValue(QLatin1String(mainWindowStateKey) + modeChar(mode), mainWindowState);
+}
+
+QByteArray QDesignerSettings::toolBarsState(UIMode mode) const
+{
+ QString key = QLatin1String(toolBarsStateKey);
+ key += modeChar(mode);
+ return settings()->value(key).toByteArray();
+}
+
+void QDesignerSettings::setToolBarsState(UIMode mode, const QByteArray &toolBarsState)
+{
+ QString key = QLatin1String(toolBarsStateKey);
+ key += modeChar(mode);
+ settings()->setValue(key, toolBarsState);
+}
+
+void QDesignerSettings::clearBackup()
+{
+ QDesignerSettingsInterface *s = settings();
+ s->remove(QLatin1String(backupOrgListKey));
+ s->remove(QLatin1String(backupBakListKey));
+}
+
+void QDesignerSettings::setBackup(const QMap<QString, QString> &map)
+{
+ const QStringList org = map.keys();
+ const QStringList bak = map.values();
+
+ QDesignerSettingsInterface *s = settings();
+ s->setValue(QLatin1String(backupOrgListKey), org);
+ s->setValue(QLatin1String(backupBakListKey), bak);
+}
+
+QMap<QString, QString> QDesignerSettings::backup() const
+{
+ const QStringList org = settings()->value(QLatin1String(backupOrgListKey), QStringList()).toStringList();
+ const QStringList bak = settings()->value(QLatin1String(backupBakListKey), QStringList()).toStringList();
+
+ QMap<QString, QString> map;
+ const int orgCount = org.count();
+ for (int i = 0; i < orgCount; ++i)
+ map.insert(org.at(i), bak.at(i));
+
+ return map;
+}
+
+void QDesignerSettings::setUiMode(UIMode mode)
+{
+ QDesignerSettingsInterface *s = settings();
+ s->beginGroup(QLatin1String("UI"));
+ s->setValue(QLatin1String("currentMode"), mode);
+ s->endGroup();
+}
+
+UIMode QDesignerSettings::uiMode() const
+{
+#ifdef Q_WS_MAC
+ const UIMode defaultMode = TopLevelMode;
+#else
+ const UIMode defaultMode = DockedMode;
+#endif
+ UIMode uiMode = static_cast<UIMode>(value(QLatin1String("UI/currentMode"), defaultMode).toInt());
+ return uiMode;
+}
+
+void QDesignerSettings::setToolWindowFont(const ToolWindowFontSettings &fontSettings)
+{
+ QDesignerSettingsInterface *s = settings();
+ s->beginGroup(QLatin1String("UI"));
+ s->setValue(QLatin1String("font"), fontSettings.m_font);
+ s->setValue(QLatin1String("useFont"), fontSettings.m_useFont);
+ s->setValue(QLatin1String("writingSystem"), fontSettings.m_writingSystem);
+ s->endGroup();
+}
+
+ToolWindowFontSettings QDesignerSettings::toolWindowFont() const
+{
+ ToolWindowFontSettings fontSettings;
+ fontSettings.m_writingSystem =
+ static_cast<QFontDatabase::WritingSystem>(value(QLatin1String("UI/writingSystem"),
+ QFontDatabase::Any).toInt());
+ fontSettings.m_font = qvariant_cast<QFont>(value(QLatin1String("UI/font")));
+ fontSettings.m_useFont =
+ settings()->value(QLatin1String("UI/useFont"), QVariant(false)).toBool();
+ return fontSettings;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_settings.h b/src/designer/src/designer/qdesigner_settings.h
new file mode 100644
index 000000000..2391581b8
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_settings.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_SETTINGS_H
+#define QDESIGNER_SETTINGS_H
+
+#include "designer_enums.h"
+#include <shared_settings_p.h>
+#include <QtCore/QMap>
+#include <QtCore/QRect>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerSettingsInterface;
+struct ToolWindowFontSettings;
+
+class QDesignerSettings : public qdesigner_internal::QDesignerSharedSettings
+{
+public:
+ QDesignerSettings(QDesignerFormEditorInterface *core);
+
+ void setValue(const QString &key, const QVariant &value);
+ QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
+
+ void restoreGeometry(QWidget *w, QRect fallBack = QRect()) const;
+ void saveGeometryFor(const QWidget *w);
+
+ QStringList recentFilesList() const;
+ void setRecentFilesList(const QStringList &list);
+
+ void setShowNewFormOnStartup(bool showIt);
+ bool showNewFormOnStartup() const;
+
+ void setUiMode(UIMode mode);
+ UIMode uiMode() const;
+
+ void setToolWindowFont(const ToolWindowFontSettings &fontSettings);
+ ToolWindowFontSettings toolWindowFont() const;
+
+ QByteArray mainWindowState(UIMode mode) const;
+ void setMainWindowState(UIMode mode, const QByteArray &mainWindowState);
+
+ QByteArray toolBarsState(UIMode mode) const;
+ void setToolBarsState(UIMode mode, const QByteArray &mainWindowState);
+
+ void clearBackup();
+ void setBackup(const QMap<QString, QString> &map);
+ QMap<QString, QString> backup() const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_SETTINGS_H
diff --git a/src/designer/src/designer/qdesigner_toolwindow.cpp b/src/designer/src/designer/qdesigner_toolwindow.cpp
new file mode 100644
index 000000000..376b0afae
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_toolwindow.cpp
@@ -0,0 +1,438 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_workbench.h"
+
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerActionEditorInterface>
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QDesignerComponents>
+
+#include <QtCore/QEvent>
+#include <QtCore/QDebug>
+#include <QtGui/QAction>
+#include <QtGui/QCloseEvent>
+
+enum { debugToolWindow = 0 };
+
+QT_BEGIN_NAMESPACE
+
+// ---------------- QDesignerToolWindowFontSettings
+ToolWindowFontSettings::ToolWindowFontSettings() :
+ m_writingSystem(QFontDatabase::Any),
+ m_useFont(false)
+{
+}
+
+bool ToolWindowFontSettings::equals(const ToolWindowFontSettings &rhs) const
+{
+ return m_useFont == rhs.m_useFont &&
+ m_writingSystem == rhs.m_writingSystem &&
+ m_font == rhs.m_font;
+}
+
+// ---------------- QDesignerToolWindow
+QDesignerToolWindow::QDesignerToolWindow(QDesignerWorkbench *workbench,
+ QWidget *w,
+ const QString &objectName,
+ const QString &title,
+ const QString &actionObjectName,
+ Qt::DockWidgetArea dockAreaHint,
+ QWidget *parent,
+ Qt::WindowFlags flags) :
+ MainWindowBase(parent, flags),
+ m_dockAreaHint(dockAreaHint),
+ m_workbench(workbench),
+ m_action(new QAction(this))
+{
+ setObjectName(objectName);
+ setCentralWidget(w);
+
+ setWindowTitle(title);
+
+ m_action->setObjectName(actionObjectName);
+ m_action->setShortcutContext(Qt::ApplicationShortcut);
+ m_action->setText(title);
+ m_action->setCheckable(true);
+ connect(m_action, SIGNAL(triggered(bool)), this, SLOT(showMe(bool)));
+}
+
+void QDesignerToolWindow::showMe(bool v)
+{
+ // Access the QMdiSubWindow in MDI mode.
+ if (QWidget *target = m_workbench->mode() == DockedMode ? parentWidget() : this) {
+ if (v)
+ target->setWindowState(target->windowState() & ~Qt::WindowMinimized);
+ target->setVisible(v);
+ }
+}
+
+void QDesignerToolWindow::showEvent(QShowEvent *e)
+{
+ Q_UNUSED(e);
+
+ bool blocked = m_action->blockSignals(true);
+ m_action->setChecked(true);
+ m_action->blockSignals(blocked);
+}
+
+void QDesignerToolWindow::hideEvent(QHideEvent *e)
+{
+ Q_UNUSED(e);
+
+ bool blocked = m_action->blockSignals(true);
+ m_action->setChecked(false);
+ m_action->blockSignals(blocked);
+}
+
+QAction *QDesignerToolWindow::action() const
+{
+ return m_action;
+}
+
+void QDesignerToolWindow::changeEvent(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::WindowTitleChange:
+ m_action->setText(windowTitle());
+ break;
+ case QEvent::WindowIconChange:
+ m_action->setIcon(windowIcon());
+ break;
+ default:
+ break;
+ }
+ QMainWindow::changeEvent(e);
+}
+
+QDesignerWorkbench *QDesignerToolWindow::workbench() const
+{
+ return m_workbench;
+}
+
+QRect QDesignerToolWindow::geometryHint() const
+{
+ return QRect();
+}
+
+QRect QDesignerToolWindow::availableToolWindowGeometry() const
+{
+ return m_workbench->availableGeometry();
+}
+
+// ---------------------- PropertyEditorToolWindow
+
+static inline QWidget *createPropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0)
+{
+ QDesignerPropertyEditorInterface *widget = QDesignerComponents::createPropertyEditor(core, parent);
+ core->setPropertyEditor(widget);
+ return widget;
+}
+
+class PropertyEditorToolWindow : public QDesignerToolWindow
+{
+public:
+ explicit PropertyEditorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+
+protected:
+ virtual void showEvent(QShowEvent *event);
+};
+
+PropertyEditorToolWindow::PropertyEditorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ createPropertyEditor(workbench->core()),
+ QLatin1String("qt_designer_propertyeditor"),
+ QDesignerToolWindow::tr("Property Editor"),
+ QLatin1String("__qt_property_editor_action"),
+ Qt::RightDockWidgetArea)
+{
+ action()->setShortcut(Qt::CTRL + Qt::Key_I);
+
+}
+
+QRect PropertyEditorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+ const int spacing = 40;
+ const QSize sz(g.width() * 1/4, g.height() * 4/6);
+
+ const QRect rc = QRect((g.right() + 1 - sz.width() - margin),
+ (g.top() + margin + g.height() * 1/6) + spacing,
+ sz.width(), sz.height());
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << rc;
+ return rc;
+}
+
+void PropertyEditorToolWindow::showEvent(QShowEvent *event)
+{
+ if (QDesignerPropertyEditorInterface *e = workbench()->core()->propertyEditor()) {
+ // workaround to update the propertyeditor when it is not visible!
+ e->setObject(e->object()); // ### remove me
+ }
+
+ QDesignerToolWindow::showEvent(event);
+}
+
+// ---------------------- ActionEditorToolWindow
+
+static inline QWidget *createActionEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0)
+{
+ QDesignerActionEditorInterface *widget = QDesignerComponents::createActionEditor(core, parent);
+ core->setActionEditor(widget);
+ return widget;
+}
+
+class ActionEditorToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit ActionEditorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+ActionEditorToolWindow::ActionEditorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ createActionEditor(workbench->core()),
+ QLatin1String("qt_designer_actioneditor"),
+ QDesignerToolWindow::tr("Action Editor"),
+ QLatin1String("__qt_action_editor_tool_action"),
+ Qt::RightDockWidgetArea)
+{
+}
+
+QRect ActionEditorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+
+ const QSize sz(g.width() * 1/4, g.height() * 1/6);
+
+ const QRect rc = QRect((g.right() + 1 - sz.width() - margin),
+ g.top() + margin,
+ sz.width(), sz.height());
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << rc;
+ return rc;
+}
+
+// ---------------------- ObjectInspectorToolWindow
+
+static inline QWidget *createObjectInspector(QDesignerFormEditorInterface *core, QWidget *parent = 0)
+{
+ QDesignerObjectInspectorInterface *widget = QDesignerComponents::createObjectInspector(core, parent);
+ core->setObjectInspector(widget);
+ return widget;
+}
+
+class ObjectInspectorToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit ObjectInspectorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+ObjectInspectorToolWindow::ObjectInspectorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ createObjectInspector(workbench->core()),
+ QLatin1String("qt_designer_objectinspector"),
+ QDesignerToolWindow::tr("Object Inspector"),
+ QLatin1String("__qt_object_inspector_tool_action"),
+ Qt::RightDockWidgetArea)
+{
+}
+
+QRect ObjectInspectorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+
+ const QSize sz(g.width() * 1/4, g.height() * 1/6);
+
+ const QRect rc = QRect((g.right() + 1 - sz.width() - margin),
+ g.top() + margin,
+ sz.width(), sz.height());
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << rc;
+ return rc;
+}
+
+// ---------------------- ResourceEditorToolWindow
+
+class ResourceEditorToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit ResourceEditorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+ResourceEditorToolWindow::ResourceEditorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ QDesignerComponents::createResourceEditor(workbench->core(), 0),
+ QLatin1String("qt_designer_resourceeditor"),
+ QDesignerToolWindow::tr("Resource Browser"),
+ QLatin1String("__qt_resource_editor_tool_action"),
+ Qt::RightDockWidgetArea)
+{
+}
+
+QRect ResourceEditorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+
+ const QSize sz(g.width() * 1/3, g.height() * 1/6);
+ QRect r(QPoint(0, 0), sz);
+ r.moveCenter(g.center());
+ r.moveBottom(g.bottom() - margin);
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << r;
+ return r;
+}
+
+// ---------------------- SignalSlotEditorToolWindow
+
+class SignalSlotEditorToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit SignalSlotEditorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+SignalSlotEditorToolWindow::SignalSlotEditorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ QDesignerComponents::createSignalSlotEditor(workbench->core(), 0),
+ QLatin1String("qt_designer_signalsloteditor"),
+ QDesignerToolWindow::tr("Signal/Slot Editor"),
+ QLatin1String("__qt_signal_slot_editor_tool_action"),
+ Qt::RightDockWidgetArea)
+{
+}
+
+QRect SignalSlotEditorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+
+ const QSize sz(g.width() * 1/3, g.height() * 1/6);
+ QRect r(QPoint(0, 0), sz);
+ r.moveCenter(g.center());
+ r.moveTop(margin + g.top());
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << r;
+ return r;
+}
+
+// ---------------------- WidgetBoxToolWindow
+
+static inline QWidget *createWidgetBox(QDesignerFormEditorInterface *core, QWidget *parent = 0)
+{
+ QDesignerWidgetBoxInterface *widget = QDesignerComponents::createWidgetBox(core, parent);
+ core->setWidgetBox(widget);
+ return widget;
+}
+
+class WidgetBoxToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit WidgetBoxToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+WidgetBoxToolWindow::WidgetBoxToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ createWidgetBox(workbench->core()),
+ QLatin1String("qt_designer_widgetbox"),
+ QDesignerToolWindow::tr("Widget Box"),
+ QLatin1String("__qt_widget_box_tool_action"),
+ Qt::LeftDockWidgetArea)
+{
+}
+
+QRect WidgetBoxToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+ const QRect rc = QRect(g.left() + margin,
+ g.top() + margin,
+ g.width() * 1/4, g.height() * 5/6);
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << rc;
+ return rc;
+}
+
+// -- Factory
+QDesignerToolWindow *QDesignerToolWindow::createStandardToolWindow(StandardToolWindow which,
+ QDesignerWorkbench *workbench)
+{
+ switch (which) {
+ case ActionEditor:
+ return new ActionEditorToolWindow(workbench);
+ case ResourceEditor:
+ return new ResourceEditorToolWindow(workbench);
+ case SignalSlotEditor:
+ return new SignalSlotEditorToolWindow(workbench);
+ case PropertyEditor:
+ return new PropertyEditorToolWindow(workbench);
+ case ObjectInspector:
+ return new ObjectInspectorToolWindow(workbench);
+ case WidgetBox:
+ return new WidgetBoxToolWindow(workbench);
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_toolwindow.h b/src/designer/src/designer/qdesigner_toolwindow.h
new file mode 100644
index 000000000..1c7b876d1
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_toolwindow.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_TOOLWINDOW_H
+#define QDESIGNER_TOOLWINDOW_H
+
+#include "mainwindow.h"
+
+#include <QtCore/QPointer>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+struct ToolWindowFontSettings {
+ ToolWindowFontSettings();
+ bool equals(const ToolWindowFontSettings &) const;
+
+ QFont m_font;
+ QFontDatabase::WritingSystem m_writingSystem;
+ bool m_useFont;
+};
+
+inline bool operator==(const ToolWindowFontSettings &tw1, const ToolWindowFontSettings &tw2)
+{
+ return tw1.equals(tw2);
+}
+
+inline bool operator!=(const ToolWindowFontSettings &tw1, const ToolWindowFontSettings &tw2)
+{
+ return !tw1.equals(tw2);
+}
+
+class QDesignerWorkbench;
+
+/* A tool window with an action that activates it. Note that in toplevel mode,
+ * the Widget box is a tool window as well as the applications' main window,
+ * So, we need to inherit from MainWindowBase. */
+
+class QDesignerToolWindow : public MainWindowBase
+{
+ Q_OBJECT
+protected:
+ explicit QDesignerToolWindow(QDesignerWorkbench *workbench,
+ QWidget *w,
+ const QString &objectName,
+ const QString &title,
+ const QString &actionObjectName,
+ Qt::DockWidgetArea dockAreaHint,
+ QWidget *parent = 0,
+ Qt::WindowFlags flags = Qt::Window);
+
+public:
+ // Note: The order influences the dock widget position.
+ enum StandardToolWindow { WidgetBox, ObjectInspector, PropertyEditor,
+ ResourceEditor, ActionEditor, SignalSlotEditor,
+ StandardToolWindowCount };
+
+ static QDesignerToolWindow *createStandardToolWindow(StandardToolWindow which, QDesignerWorkbench *workbench);
+
+ QDesignerWorkbench *workbench() const;
+ QAction *action() const;
+
+ Qt::DockWidgetArea dockWidgetAreaHint() const { return m_dockAreaHint; }
+ virtual QRect geometryHint() const;
+
+private slots:
+ void showMe(bool);
+
+protected:
+ virtual void showEvent(QShowEvent *e);
+ virtual void hideEvent(QHideEvent *e);
+ virtual void changeEvent(QEvent *e);
+
+ QRect availableToolWindowGeometry() const;
+
+private:
+ const Qt::DockWidgetArea m_dockAreaHint;
+ QDesignerWorkbench *m_workbench;
+ QAction *m_action;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_TOOLWINDOW_H
diff --git a/src/designer/src/designer/qdesigner_workbench.cpp b/src/designer/src/designer/qdesigner_workbench.cpp
new file mode 100644
index 000000000..ffc4b8c7a
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_workbench.cpp
@@ -0,0 +1,1100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_workbench.h"
+#include "qdesigner.h"
+#include "qdesigner_actions.h"
+#include "qdesigner_appearanceoptions.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_formwindow.h"
+#include "appfontdialog.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerFormEditorPluginInterface>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+
+#include <QtDesigner/QDesignerComponents>
+#include <QtDesigner/private/qdesigner_integration_p.h>
+#include <QtDesigner/private/pluginmanager_p.h>
+#include <QtDesigner/private/formwindowbase_p.h>
+#include <QtDesigner/private/actioneditor_p.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QUrl>
+#include <QtCore/QTimer>
+#include <QtCore/QPluginLoader>
+#include <QtCore/qdebug.h>
+
+#include <QtGui/QActionGroup>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QDockWidget>
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QToolBar>
+#include <QtGui/QMdiArea>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+static const char *appFontPrefixC = "AppFonts";
+
+typedef QList<QAction *> ActionList;
+
+static QMdiSubWindow *mdiSubWindowOf(const QWidget *w)
+{
+ QMdiSubWindow *rc = qobject_cast<QMdiSubWindow *>(w->parentWidget());
+ Q_ASSERT(rc);
+ return rc;
+}
+
+static QDockWidget *dockWidgetOf(const QWidget *w)
+{
+ for (QWidget *parentWidget = w->parentWidget(); parentWidget ; parentWidget = parentWidget->parentWidget()) {
+ if (QDockWidget *dw = qobject_cast<QDockWidget *>(parentWidget)) {
+ return dw;
+ }
+ }
+ Q_ASSERT("Dock widget not found");
+ return 0;
+}
+
+// ------------ QDesignerWorkbench::Position
+QDesignerWorkbench::Position::Position(const QMdiSubWindow *mdiSubWindow, const QPoint &mdiAreaOffset) :
+ m_minimized(mdiSubWindow->isShaded()),
+ m_position(mdiSubWindow->pos() + mdiAreaOffset)
+{
+}
+
+QDesignerWorkbench::Position::Position(const QDockWidget *dockWidget) :
+ m_minimized(dockWidget->isMinimized()),
+ m_position(dockWidget->pos())
+{
+}
+
+QDesignerWorkbench::Position::Position(const QWidget *topLevelWindow, const QPoint &desktopTopLeft)
+{
+ const QWidget *window =topLevelWindow->window ();
+ Q_ASSERT(window);
+ m_minimized = window->isMinimized();
+ m_position = window->pos() - desktopTopLeft;
+}
+
+void QDesignerWorkbench::Position::applyTo(QMdiSubWindow *mdiSubWindow,
+ const QPoint &mdiAreaOffset) const
+{
+ // QMdiSubWindow attempts to resize its children to sizeHint() when switching user interface modes.
+ // Restore old size
+ const QPoint mdiAreaPos = QPoint(qMax(0, m_position.x() - mdiAreaOffset.x()),
+ qMax(0, m_position.y() - mdiAreaOffset.y()));
+ mdiSubWindow->move(mdiAreaPos);
+ const QSize decorationSize = mdiSubWindow->size() - mdiSubWindow->contentsRect().size();
+ mdiSubWindow->resize(mdiSubWindow->widget()->size() + decorationSize);
+ mdiSubWindow->show();
+ if (m_minimized) {
+ mdiSubWindow->showShaded();
+ }
+}
+
+void QDesignerWorkbench::Position::applyTo(QWidget *topLevelWindow, const QPoint &desktopTopLeft) const
+{
+ QWidget *window = topLevelWindow->window ();
+ const QPoint newPos = m_position + desktopTopLeft;
+ window->move(newPos);
+ if ( m_minimized) {
+ topLevelWindow->showMinimized();
+ } else {
+ topLevelWindow->show();
+ }
+}
+
+void QDesignerWorkbench::Position::applyTo(QDockWidget *dockWidget) const
+{
+ dockWidget->widget()->setVisible(true);
+ dockWidget->setVisible(!m_minimized);
+}
+
+static inline void addActionsToMenu(QMenu *m, const ActionList &al)
+{
+ const ActionList::const_iterator cend = al.constEnd();
+ for (ActionList::const_iterator it = al.constBegin(); it != cend; ++it)
+ m->addAction(*it);
+}
+
+static inline QMenu *addMenu(QMenuBar *mb, const QString &title, const ActionList &al)
+{
+ QMenu *rc = mb->addMenu(title);
+ addActionsToMenu(rc, al);
+ return rc;
+}
+
+// -------- QDesignerWorkbench
+
+QDesignerWorkbench::QDesignerWorkbench() :
+ m_core(QDesignerComponents::createFormEditor(this)),
+ m_windowActions(new QActionGroup(this)),
+ m_globalMenuBar(new QMenuBar),
+ m_mode(NeutralMode),
+ m_dockedMainWindow(0),
+ m_state(StateInitializing)
+{
+ QDesignerSettings settings(m_core);
+
+ (void) QDesignerComponents::createTaskMenu(core(), this);
+
+ initializeCorePlugins();
+ QDesignerComponents::initializePlugins(core());
+ m_actionManager = new QDesignerActions(this); // accesses plugin components
+
+ m_windowActions->setExclusive(true);
+ connect(m_windowActions, SIGNAL(triggered(QAction*)), this, SLOT(formWindowActionTriggered(QAction*)));
+
+ // Build main menu bar
+ addMenu(m_globalMenuBar, tr("&File"), m_actionManager->fileActions()->actions());
+
+ QMenu *editMenu = addMenu(m_globalMenuBar, tr("&Edit"), m_actionManager->editActions()->actions());
+ editMenu->addSeparator();
+ addActionsToMenu(editMenu, m_actionManager->toolActions()->actions());
+
+ QMenu *formMenu = addMenu(m_globalMenuBar, tr("F&orm"), m_actionManager->formActions()->actions());
+ QMenu *previewSubMenu = new QMenu(tr("Preview in"), formMenu);
+ formMenu->insertMenu(m_actionManager->previewFormAction(), previewSubMenu);
+ addActionsToMenu(previewSubMenu, m_actionManager->styleActions()->actions());
+
+ QMenu *viewMenu = m_globalMenuBar->addMenu(tr("&View"));
+
+ addMenu(m_globalMenuBar, tr("&Settings"), m_actionManager->settingsActions()->actions());
+
+ m_windowMenu = addMenu(m_globalMenuBar, tr("&Window"), m_actionManager->windowActions()->actions());
+
+ addMenu(m_globalMenuBar, tr("&Help"), m_actionManager->helpActions()->actions());
+
+ // Add the tools in view menu order
+ QActionGroup *viewActions = new QActionGroup(this);
+ viewActions->setExclusive(false);
+
+ for (int i = 0; i < QDesignerToolWindow::StandardToolWindowCount; i++) {
+ QDesignerToolWindow *toolWindow = QDesignerToolWindow::createStandardToolWindow(static_cast< QDesignerToolWindow::StandardToolWindow>(i), this);
+ m_toolWindows.push_back(toolWindow);
+ if (QAction *action = toolWindow->action()) {
+ viewMenu->addAction(action);
+ viewActions->addAction(action);
+ }
+ // The widget box becomes the main window in top level mode
+ if (i == QDesignerToolWindow::WidgetBox)
+ connect(toolWindow, SIGNAL(closeEventReceived(QCloseEvent*)), this, SLOT(handleCloseEvent(QCloseEvent*)));
+ }
+ // Integration
+ m_integration = new qdesigner_internal::QDesignerIntegration(m_core, this);
+ connect(m_integration, SIGNAL(helpRequested(QString,QString)), m_actionManager, SLOT(helpRequested(QString,QString)));
+
+ // remaining view options (config toolbars)
+ viewMenu->addSeparator();
+ m_toolbarMenu = viewMenu->addMenu(tr("Toolbars"));
+
+ emit initialized();
+
+ connect(m_core->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(updateWindowMenu(QDesignerFormWindowInterface*)));
+
+
+ { // Add application specific options pages
+ QDesignerAppearanceOptionsPage *appearanceOptions = new QDesignerAppearanceOptionsPage(m_core);
+ connect(appearanceOptions, SIGNAL(settingsChangedDelayed()), this, SLOT(restoreUISettings()));
+ QList<QDesignerOptionsPageInterface*> optionsPages = m_core->optionsPages();
+ optionsPages.push_front(appearanceOptions);
+ m_core->setOptionsPages(optionsPages);
+ }
+
+ restoreUISettings();
+ AppFontWidget::restore(m_core->settingsManager(), QLatin1String(appFontPrefixC));
+ m_state = StateUp;
+}
+
+QDesignerWorkbench::~QDesignerWorkbench()
+{
+ switch (m_mode) {
+ case NeutralMode:
+ case DockedMode:
+ qDeleteAll(m_toolWindows);
+ break;
+ case TopLevelMode: // Everything parented here
+ delete widgetBoxToolWindow();
+ break;
+ }
+}
+
+void QDesignerWorkbench::saveGeometriesForModeChange()
+{
+ m_Positions.clear();
+ switch (m_mode) {
+ case NeutralMode:
+ break;
+ case TopLevelMode: {
+ const QPoint desktopOffset = QApplication::desktop()->availableGeometry().topLeft();
+ foreach (QDesignerToolWindow *tw, m_toolWindows)
+ m_Positions.insert(tw, Position(tw, desktopOffset));
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ m_Positions.insert(fw, Position(fw, desktopOffset));
+ }
+ }
+ break;
+ case DockedMode: {
+ const QPoint mdiAreaOffset = m_dockedMainWindow->mdiArea()->pos();
+ foreach (QDesignerToolWindow *tw, m_toolWindows) {
+ m_Positions.insert(tw, Position(dockWidgetOf(tw)));
+ }
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ m_Positions.insert(fw, Position(mdiSubWindowOf(fw), mdiAreaOffset));
+ }
+ }
+ break;
+ }
+}
+
+UIMode QDesignerWorkbench::mode() const
+{
+ return m_mode;
+}
+
+void QDesignerWorkbench::addFormWindow(QDesignerFormWindow *formWindow)
+{
+ // ### Q_ASSERT(formWindow->windowTitle().isEmpty() == false);
+
+ m_formWindows.append(formWindow);
+
+
+ m_actionManager->setWindowListSeparatorVisible(true);
+
+ if (QAction *action = formWindow->action()) {
+ m_windowActions->addAction(action);
+ m_windowMenu->addAction(action);
+ action->setChecked(true);
+ }
+
+ m_actionManager->minimizeAction()->setEnabled(true);
+ m_actionManager->minimizeAction()->setChecked(false);
+ connect(formWindow, SIGNAL(minimizationStateChanged(QDesignerFormWindowInterface*,bool)),
+ this, SLOT(minimizationStateChanged(QDesignerFormWindowInterface*,bool)));
+
+ m_actionManager->editWidgets()->trigger();
+}
+
+Qt::WindowFlags QDesignerWorkbench::magicalWindowFlags(const QWidget *widgetForFlags) const
+{
+ switch (m_mode) {
+ case TopLevelMode: {
+#ifdef Q_WS_MAC
+ if (qobject_cast<const QDesignerToolWindow *>(widgetForFlags))
+ return Qt::Tool;
+#else
+ Q_UNUSED(widgetForFlags);
+#endif
+ return Qt::Window;
+ }
+ case DockedMode:
+ return Qt::Window | Qt::WindowShadeButtonHint | Qt::WindowSystemMenuHint | Qt::WindowTitleHint;
+ case NeutralMode:
+ return Qt::Window;
+ default:
+ Q_ASSERT(0);
+ return 0;
+ }
+}
+
+QWidget *QDesignerWorkbench::magicalParent(const QWidget *w) const
+{
+ switch (m_mode) {
+ case TopLevelMode: {
+ // Use widget box as parent for all windows except self. This will
+ // result in having just one entry in the MS Windows task bar.
+ QWidget *widgetBoxWrapper = widgetBoxToolWindow();
+ return w == widgetBoxWrapper ? 0 : widgetBoxWrapper;
+ }
+ case DockedMode:
+ return m_dockedMainWindow->mdiArea();
+ case NeutralMode:
+ return 0;
+ default:
+ Q_ASSERT(0);
+ return 0;
+ }
+}
+
+void QDesignerWorkbench::switchToNeutralMode()
+{
+ QDesignerSettings settings(m_core);
+ saveGeometries(settings);
+ saveGeometriesForModeChange();
+
+ if (m_mode == TopLevelMode) {
+ delete m_topLevelData.toolbarManager;
+ m_topLevelData.toolbarManager = 0;
+ qDeleteAll(m_topLevelData.toolbars);
+ m_topLevelData.toolbars.clear();
+ }
+
+ m_mode = NeutralMode;
+
+ foreach (QDesignerToolWindow *tw, m_toolWindows) {
+ tw->setCloseEventPolicy(MainWindowBase::AcceptCloseEvents);
+ tw->setParent(0);
+ }
+
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ fw->setParent(0);
+ fw->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+ }
+
+#ifndef Q_WS_MAC
+ m_globalMenuBar->setParent(0);
+#endif
+
+ m_core->setTopLevel(0);
+ qDesigner->setMainWindow(0);
+
+ delete m_dockedMainWindow;
+ m_dockedMainWindow = 0;
+}
+
+void QDesignerWorkbench::switchToDockedMode()
+{
+ if (m_mode == DockedMode)
+ return;
+
+ switchToNeutralMode();
+
+#ifndef Q_WS_MAC
+ QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow();
+ widgetBoxWrapper->action()->setVisible(true);
+ widgetBoxWrapper->setWindowTitle(tr("Widget Box"));
+#endif
+
+ m_mode = DockedMode;
+ const QDesignerSettings settings(m_core);
+ m_dockedMainWindow = new DockedMainWindow(this, m_toolbarMenu, m_toolWindows);
+ m_dockedMainWindow->setUnifiedTitleAndToolBarOnMac(true);
+ m_dockedMainWindow->setCloseEventPolicy(MainWindowBase::EmitCloseEventSignal);
+ connect(m_dockedMainWindow, SIGNAL(closeEventReceived(QCloseEvent*)), this, SLOT(handleCloseEvent(QCloseEvent*)));
+ connect(m_dockedMainWindow, SIGNAL(fileDropped(QString)), this, SLOT(slotFileDropped(QString)));
+ connect(m_dockedMainWindow, SIGNAL(formWindowActivated(QDesignerFormWindow*)), this, SLOT(slotFormWindowActivated(QDesignerFormWindow*)));
+ m_dockedMainWindow->restoreSettings(settings, m_dockedMainWindow->addToolWindows(m_toolWindows), desktopGeometry());
+
+ m_core->setTopLevel(m_dockedMainWindow);
+
+#ifndef Q_WS_MAC
+ m_dockedMainWindow->setMenuBar(m_globalMenuBar);
+ m_globalMenuBar->show();
+#endif
+ qDesigner->setMainWindow(m_dockedMainWindow);
+
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ QMdiSubWindow *subwin = m_dockedMainWindow->createMdiSubWindow(fw, magicalWindowFlags(fw),
+ m_actionManager->closeFormAction()->shortcut());
+ subwin->hide();
+ if (QWidget *mainContainer = fw->editor()->mainContainer())
+ resizeForm(fw, mainContainer);
+ }
+
+ m_actionManager->setBringAllToFrontVisible(false);
+ m_dockedMainWindow->show();
+ // Trigger adjustMDIFormPositions() delayed as viewport size is not yet known.
+
+ if (m_state != StateInitializing)
+ QMetaObject::invokeMethod(this, "adjustMDIFormPositions", Qt::QueuedConnection);
+}
+
+void QDesignerWorkbench::adjustMDIFormPositions()
+{
+ const QPoint mdiAreaOffset = m_dockedMainWindow->mdiArea()->pos();
+
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ const PositionMap::const_iterator pit = m_Positions.constFind(fw);
+ if (pit != m_Positions.constEnd())
+ pit->applyTo(mdiSubWindowOf(fw), mdiAreaOffset);
+ }
+}
+
+void QDesignerWorkbench::switchToTopLevelMode()
+{
+ if (m_mode == TopLevelMode)
+ return;
+
+ // make sure that the widgetbox is visible if it is different from neutral.
+ QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow();
+ Q_ASSERT(widgetBoxWrapper);
+
+ switchToNeutralMode();
+ const QPoint desktopOffset = desktopGeometry().topLeft();
+ m_mode = TopLevelMode;
+
+ // The widget box is special, it gets the menubar and gets to be the main widget.
+
+ m_core->setTopLevel(widgetBoxWrapper);
+#ifndef Q_WS_MAC
+ widgetBoxWrapper->setMenuBar(m_globalMenuBar);
+ widgetBoxWrapper->action()->setVisible(false);
+ widgetBoxWrapper->setCloseEventPolicy(MainWindowBase::EmitCloseEventSignal);
+ qDesigner->setMainWindow(widgetBoxWrapper);
+ widgetBoxWrapper->setWindowTitle(MainWindowBase::mainWindowTitle());
+#endif
+
+ const QDesignerSettings settings(m_core);
+ m_topLevelData.toolbars = MainWindowBase::createToolBars(m_actionManager, false);
+ m_topLevelData.toolbarManager = new ToolBarManager(widgetBoxWrapper, widgetBoxWrapper,
+ m_toolbarMenu, m_actionManager,
+ m_topLevelData.toolbars, m_toolWindows);
+ const int toolBarCount = m_topLevelData.toolbars.size();
+ for (int i = 0; i < toolBarCount; i++) {
+ widgetBoxWrapper->addToolBar(m_topLevelData.toolbars.at(i));
+ if (i == 3)
+ widgetBoxWrapper->insertToolBarBreak(m_topLevelData.toolbars.at(i));
+ }
+ m_topLevelData.toolbarManager->restoreState(settings.toolBarsState(m_mode), MainWindowBase::settingsVersion());
+ widgetBoxWrapper->restoreState(settings.mainWindowState(m_mode), MainWindowBase::settingsVersion());
+
+ bool found_visible_window = false;
+ foreach (QDesignerToolWindow *tw, m_toolWindows) {
+ tw->setParent(magicalParent(tw), magicalWindowFlags(tw));
+ settings.restoreGeometry(tw, tw->geometryHint());
+ tw->action()->setChecked(tw->isVisible());
+ found_visible_window |= tw->isVisible();
+ }
+
+ if (!m_toolWindows.isEmpty() && !found_visible_window)
+ m_toolWindows.first()->show();
+
+ m_actionManager->setBringAllToFrontVisible(true);
+
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ fw->setParent(magicalParent(fw), magicalWindowFlags(fw));
+ fw->setAttribute(Qt::WA_DeleteOnClose, true);
+ const PositionMap::const_iterator pit = m_Positions.constFind(fw);
+ if (pit != m_Positions.constEnd()) pit->applyTo(fw, desktopOffset);
+ // Force an activate in order to refresh minimumSize, otherwise it will not be respected
+ if (QLayout *layout = fw->layout())
+ layout->invalidate();
+ if (QWidget *mainContainer = fw->editor()->mainContainer())
+ resizeForm(fw, mainContainer);
+ }
+}
+
+QDesignerFormWindowManagerInterface *QDesignerWorkbench::formWindowManager() const
+{
+ return m_core->formWindowManager();
+}
+
+QDesignerFormEditorInterface *QDesignerWorkbench::core() const
+{
+ return m_core;
+}
+
+int QDesignerWorkbench::toolWindowCount() const
+{
+ return m_toolWindows.count();
+}
+
+QDesignerToolWindow *QDesignerWorkbench::toolWindow(int index) const
+{
+ return m_toolWindows.at(index);
+}
+
+int QDesignerWorkbench::formWindowCount() const
+{
+ return m_formWindows.count();
+}
+
+QDesignerFormWindow *QDesignerWorkbench::formWindow(int index) const
+{
+ return m_formWindows.at(index);
+}
+
+QRect QDesignerWorkbench::desktopGeometry() const
+{
+ // Return geometry of the desktop designer is running in.
+ QWidget *widget = 0;
+ switch (m_mode) {
+ case DockedMode:
+ widget = m_dockedMainWindow;
+ break;
+ case TopLevelMode:
+ widget = widgetBoxToolWindow();
+ break;
+ case NeutralMode:
+ break;
+ }
+ const QDesktopWidget *desktop = qApp->desktop();
+ const int screenNumber = widget ? desktop->screenNumber(widget) : 0;
+ return desktop->availableGeometry(screenNumber);
+}
+
+QRect QDesignerWorkbench::availableGeometry() const
+{
+ if (m_mode == DockedMode)
+ return m_dockedMainWindow->mdiArea()->geometry();
+
+ const QDesktopWidget *desktop = qDesigner->desktop();
+ return desktop->availableGeometry(desktop->screenNumber(widgetBoxToolWindow()));
+}
+
+int QDesignerWorkbench::marginHint() const
+{ return 20;
+}
+
+void QDesignerWorkbench::slotFormWindowActivated(QDesignerFormWindow* fw)
+{
+ core()->formWindowManager()->setActiveFormWindow(fw->editor());
+}
+
+void QDesignerWorkbench::removeFormWindow(QDesignerFormWindow *formWindow)
+{
+ QDesignerFormWindowInterface *editor = formWindow->editor();
+ const bool loadOk = editor->mainContainer();
+ updateBackup(editor);
+ const int index = m_formWindows.indexOf(formWindow);
+ if (index != -1) {
+ m_formWindows.removeAt(index);
+ }
+
+ if (QAction *action = formWindow->action()) {
+ m_windowActions->removeAction(action);
+ m_windowMenu->removeAction(action);
+ }
+
+ if (m_formWindows.empty()) {
+ m_actionManager->setWindowListSeparatorVisible(false);
+ // Show up new form dialog unless closing
+ if (loadOk && m_state == StateUp
+ && QDesignerSettings(m_core).showNewFormOnStartup()) {
+ QTimer::singleShot(200, m_actionManager, SLOT(createForm()));
+ }
+ }
+}
+
+void QDesignerWorkbench::initializeCorePlugins()
+{
+ QList<QObject*> plugins = QPluginLoader::staticInstances();
+ plugins += core()->pluginManager()->instances();
+
+ foreach (QObject *plugin, plugins) {
+ if (QDesignerFormEditorPluginInterface *formEditorPlugin = qobject_cast<QDesignerFormEditorPluginInterface*>(plugin)) {
+ if (!formEditorPlugin->isInitialized())
+ formEditorPlugin->initialize(core());
+ }
+ }
+}
+
+void QDesignerWorkbench::saveSettings() const
+{
+ QDesignerSettings settings(m_core);
+ settings.clearBackup();
+ saveGeometries(settings);
+ AppFontWidget::save(m_core->settingsManager(), QLatin1String(appFontPrefixC));
+}
+
+void QDesignerWorkbench::saveGeometries(QDesignerSettings &settings) const
+{
+ switch (m_mode) {
+ case DockedMode:
+ m_dockedMainWindow->saveSettings(settings);
+ break;
+ case TopLevelMode:
+ settings.setToolBarsState(m_mode, m_topLevelData.toolbarManager->saveState(MainWindowBase::settingsVersion()));
+ settings.setMainWindowState(m_mode, widgetBoxToolWindow()->saveState(MainWindowBase::settingsVersion()));
+ foreach (const QDesignerToolWindow *tw, m_toolWindows)
+ settings.saveGeometryFor(tw);
+ break;
+ case NeutralMode:
+ break;
+ }
+}
+
+void QDesignerWorkbench::slotFileDropped(const QString &f)
+{
+ readInForm(f);
+}
+
+bool QDesignerWorkbench::readInForm(const QString &fileName) const
+{
+ return m_actionManager->readInForm(fileName);
+}
+
+bool QDesignerWorkbench::writeOutForm(QDesignerFormWindowInterface *formWindow, const QString &fileName) const
+{
+ return m_actionManager->writeOutForm(formWindow, fileName);
+}
+
+bool QDesignerWorkbench::saveForm(QDesignerFormWindowInterface *frm)
+{
+ return m_actionManager->saveForm(frm);
+}
+
+QDesignerFormWindow *QDesignerWorkbench::findFormWindow(QWidget *widget) const
+{
+ foreach (QDesignerFormWindow *formWindow, m_formWindows) {
+ if (formWindow->editor() == widget)
+ return formWindow;
+ }
+
+ return 0;
+}
+
+bool QDesignerWorkbench::handleClose()
+{
+ m_state = StateClosing;
+ QList<QDesignerFormWindow *> dirtyForms;
+ foreach (QDesignerFormWindow *w, m_formWindows) {
+ if (w->editor()->isDirty())
+ dirtyForms << w;
+ }
+
+ if (dirtyForms.size()) {
+ if (dirtyForms.size() == 1) {
+ if (!dirtyForms.at(0)->close()) {
+ m_state = StateUp;
+ return false;
+ }
+ } else {
+ int count = dirtyForms.size();
+ QMessageBox box(QMessageBox::Warning, tr("Save Forms?"),
+ tr("There are %n forms with unsaved changes."
+ " Do you want to review these changes before quitting?", "", count),
+ QMessageBox::Cancel | QMessageBox::Discard | QMessageBox::Save);
+ box.setInformativeText(tr("If you do not review your documents, all your changes will be lost."));
+ box.button(QMessageBox::Discard)->setText(tr("Discard Changes"));
+ QPushButton *save = static_cast<QPushButton *>(box.button(QMessageBox::Save));
+ save->setText(tr("Review Changes"));
+ box.setDefaultButton(save);
+ switch (box.exec()) {
+ case QMessageBox::Cancel:
+ m_state = StateUp;
+ return false;
+ case QMessageBox::Save:
+ foreach (QDesignerFormWindow *fw, dirtyForms) {
+ fw->show();
+ fw->raise();
+ if (!fw->close()) {
+ m_state = StateUp;
+ return false;
+ }
+ }
+ break;
+ case QMessageBox::Discard:
+ foreach (QDesignerFormWindow *fw, dirtyForms) {
+ fw->editor()->setDirty(false);
+ fw->setWindowModified(false);
+ }
+ break;
+ }
+ }
+ }
+
+ foreach (QDesignerFormWindow *fw, m_formWindows)
+ fw->close();
+
+ saveSettings();
+ return true;
+}
+
+QDesignerActions *QDesignerWorkbench::actionManager() const
+{
+ return m_actionManager;
+}
+
+void QDesignerWorkbench::updateWindowMenu(QDesignerFormWindowInterface *fwi)
+{
+ bool minimizeChecked = false;
+ bool minimizeEnabled = false;
+ QDesignerFormWindow *activeFormWindow = 0;
+ do {
+ if (!fwi)
+ break;
+ activeFormWindow = qobject_cast<QDesignerFormWindow *>(fwi->parentWidget());
+ if (!activeFormWindow)
+ break;
+
+ minimizeEnabled = true;
+ minimizeChecked = isFormWindowMinimized(activeFormWindow);
+ } while (false) ;
+
+ m_actionManager->minimizeAction()->setEnabled(minimizeEnabled);
+ m_actionManager->minimizeAction()->setChecked(minimizeChecked);
+
+ if (!m_formWindows.empty()) {
+ const QList<QDesignerFormWindow*>::const_iterator cend = m_formWindows.constEnd();
+ for (QList<QDesignerFormWindow*>::const_iterator it = m_formWindows.constBegin(); it != cend; ++it)
+ (*it)->action()->setChecked(*it == activeFormWindow);
+ }
+}
+
+void QDesignerWorkbench::formWindowActionTriggered(QAction *a)
+{
+ QDesignerFormWindow *fw = qobject_cast<QDesignerFormWindow *>(a->parentWidget());
+ Q_ASSERT(fw);
+
+ if (isFormWindowMinimized(fw))
+ setFormWindowMinimized(fw, false);
+
+ if (m_mode == DockedMode) {
+ if (QMdiSubWindow *subWindow = qobject_cast<QMdiSubWindow *>(fw->parent())) {
+ m_dockedMainWindow->mdiArea()->setActiveSubWindow(subWindow);
+ }
+ } else {
+ fw->activateWindow();
+ fw->raise();
+ }
+}
+
+void QDesignerWorkbench::closeAllToolWindows()
+{
+ foreach (QDesignerToolWindow *tw, m_toolWindows)
+ tw->hide();
+}
+
+bool QDesignerWorkbench::readInBackup()
+{
+ const QMap<QString, QString> backupFileMap = QDesignerSettings(m_core).backup();
+ if (backupFileMap.isEmpty())
+ return false;
+
+ const QMessageBox::StandardButton answer =
+ QMessageBox::question(0, tr("Backup Information"),
+ tr("The last session of Designer was not terminated correctly. "
+ "Backup files were left behind. Do you want to load them?"),
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
+ if (answer == QMessageBox::No)
+ return false;
+
+ const QString modifiedPlaceHolder = QLatin1String("[*]");
+ QMapIterator<QString, QString> it(backupFileMap);
+ while(it.hasNext()) {
+ it.next();
+
+ QString fileName = it.key();
+ fileName.remove(modifiedPlaceHolder);
+
+ if(m_actionManager->readInForm(it.value()))
+ formWindowManager()->activeFormWindow()->setFileName(fileName);
+
+ }
+ return true;
+}
+
+void QDesignerWorkbench::updateBackup(QDesignerFormWindowInterface* fwi)
+{
+ QString fwn = QDir::convertSeparators(fwi->fileName());
+ if (fwn.isEmpty())
+ fwn = fwi->parentWidget()->windowTitle();
+
+ QDesignerSettings settings(m_core);
+ QMap<QString, QString> map = settings.backup();
+ map.remove(fwn);
+ settings.setBackup(map);
+}
+
+namespace {
+ void raiseWindow(QWidget *w) {
+ if (w->isMinimized())
+ w->setWindowState(w->windowState() & ~Qt::WindowMinimized);
+ w->raise();
+ }
+}
+
+void QDesignerWorkbench::bringAllToFront()
+{
+ if (m_mode != TopLevelMode)
+ return;
+ foreach(QDesignerToolWindow *tw, m_toolWindows)
+ raiseWindow(tw);
+ foreach(QDesignerFormWindow *dfw, m_formWindows)
+ raiseWindow(dfw);
+}
+
+// Resize a form window taking MDI decorations into account
+// Apply maximum size as there is no layout connection between
+// the form's main container and the integration's outer
+// container due to the tool widget stack.
+
+void QDesignerWorkbench::resizeForm(QDesignerFormWindow *fw, const QWidget *mainContainer) const
+{
+ const QSize containerSize = mainContainer->size();
+ const QSize containerMinimumSize = mainContainer->minimumSize();
+ const QSize containerMaximumSize = mainContainer->maximumSize();
+ if (m_mode != DockedMode) {
+ fw->resize(containerSize);
+ fw->setMaximumSize(containerMaximumSize);
+ return;
+ }
+ // get decorations and resize MDI
+ QMdiSubWindow *mdiSubWindow = qobject_cast<QMdiSubWindow *>(fw->parent());
+ Q_ASSERT(mdiSubWindow);
+ const QSize decorationSize = mdiSubWindow->geometry().size() - mdiSubWindow->contentsRect().size();
+ mdiSubWindow->resize(containerSize + decorationSize);
+ // In Qt::RightToLeft mode, the window can grow to be partially hidden by the right border.
+ const int mdiAreaWidth = m_dockedMainWindow->mdiArea()->width();
+ if (qApp->layoutDirection() == Qt::RightToLeft && mdiSubWindow->geometry().right() >= mdiAreaWidth)
+ mdiSubWindow->move(mdiAreaWidth - mdiSubWindow->width(), mdiSubWindow->pos().y());
+
+ if (containerMaximumSize == QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)) {
+ mdiSubWindow->setMaximumSize(containerMaximumSize);
+ } else {
+ mdiSubWindow->setMaximumSize(containerMaximumSize + decorationSize);
+ }
+}
+
+
+// Load a form or return 0 and do cleanup. file name and editor file
+// name in case of loading a template file.
+
+QDesignerFormWindow * QDesignerWorkbench::loadForm(const QString &fileName,
+ bool detectLineTermiantorMode,
+ bool *uic3Converted,
+ QString *errorMessage)
+{
+ QFile file(fileName);
+
+ qdesigner_internal::FormWindowBase::LineTerminatorMode mode = qdesigner_internal::FormWindowBase::NativeLineTerminator;
+
+ if (detectLineTermiantorMode) {
+ if (file.open(QFile::ReadOnly)) {
+ const QString text = QString::fromUtf8(file.readLine());
+ file.close();
+
+ const int lf = text.indexOf(QLatin1Char('\n'));
+ if (lf > 0 && text.at(lf-1) == QLatin1Char('\r')) {
+ mode = qdesigner_internal::FormWindowBase::CRLFLineTerminator;
+ } else if (lf >= 0) {
+ mode = qdesigner_internal::FormWindowBase::LFLineTerminator;
+ }
+ }
+ }
+
+ if (!file.open(QFile::ReadOnly|QFile::Text)) {
+ *errorMessage = tr("The file <b>%1</b> could not be opened.").arg(file.fileName());
+ return 0;
+ }
+
+
+ // Create a form
+ QDesignerFormWindowManagerInterface *formWindowManager = m_core->formWindowManager();
+
+ QDesignerFormWindow *formWindow = new QDesignerFormWindow(/*formWindow=*/ 0, this);
+ addFormWindow(formWindow);
+ QDesignerFormWindowInterface *editor = formWindow->editor();
+ Q_ASSERT(editor);
+
+ // Temporarily set the file name. It is needed when converting a UIC 3 file.
+ // In this case, the file name will we be cleared on return to force a save box.
+ editor->setFileName(fileName);
+ editor->setContents(&file);
+
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(editor))
+ fwb->setLineTerminatorMode(mode);
+
+ switch (m_mode) {
+ case DockedMode: {
+ // below code must be after above call to setContents(), because setContents() may popup warning dialogs which would cause
+ // mdi sub window activation (because of dialogs internal call to processEvent or such)
+ // That activation could have worse consequences, e.g. NULL resource set for active form) before the form is loaded
+ QMdiSubWindow *subWin = m_dockedMainWindow->createMdiSubWindow(formWindow, magicalWindowFlags(formWindow), m_actionManager->closeFormAction()->shortcut());
+ m_dockedMainWindow->mdiArea()->setActiveSubWindow(subWin);
+ }
+ break;
+ case TopLevelMode: {
+ const QRect formWindowGeometryHint = formWindow->geometryHint();
+ formWindow->setAttribute(Qt::WA_DeleteOnClose, true);
+ formWindow->setParent(magicalParent(formWindow), magicalWindowFlags(formWindow));
+ formWindow->resize(formWindowGeometryHint.size());
+ formWindow->move(availableGeometry().center() - formWindowGeometryHint.center());
+ }
+ break;
+ case NeutralMode:
+ break;
+ }
+
+ if (!editor->mainContainer()) {
+ removeFormWindow(formWindow);
+ formWindowManager->removeFormWindow(editor);
+ m_core->metaDataBase()->remove(editor);
+ *errorMessage = tr("The file <b>%1</b> is not a valid Designer UI file.").arg(file.fileName());
+ return 0;
+ }
+ *uic3Converted = editor->fileName().isEmpty();
+ // Did user specify another (missing) resource path -> set dirty.
+ const bool dirty = editor->property("_q_resourcepathchanged").toBool();
+ editor->setDirty(dirty);
+ resizeForm(formWindow, editor->mainContainer());
+ formWindowManager->setActiveFormWindow(editor);
+ return formWindow;
+}
+
+
+QDesignerFormWindow * QDesignerWorkbench::openForm(const QString &fileName, QString *errorMessage)
+{
+ bool uic3Converted;
+ QDesignerFormWindow *rc =loadForm(fileName, true, &uic3Converted, errorMessage);
+ if (!rc)
+ return 0;
+
+ if (!uic3Converted)
+ rc->editor()->setFileName(fileName);
+ rc->firstShow();
+ return rc;
+}
+
+QDesignerFormWindow * QDesignerWorkbench::openTemplate(const QString &templateFileName,
+ const QString &editorFileName,
+ QString *errorMessage)
+{
+ bool uic3Converted;
+ QDesignerFormWindow *rc =loadForm(templateFileName, false, &uic3Converted, errorMessage);
+ if (!rc)
+ return 0;
+
+ if (!uic3Converted)
+ rc->editor()->setFileName(editorFileName);
+
+ rc->firstShow();
+ return rc;
+}
+
+void QDesignerWorkbench::minimizationStateChanged(QDesignerFormWindowInterface *formWindow, bool minimized)
+{
+ // refresh the minimize action state
+ if (core()->formWindowManager()->activeFormWindow() == formWindow) {
+ m_actionManager->minimizeAction()->setChecked(minimized);
+ }
+}
+
+void QDesignerWorkbench::toggleFormMinimizationState()
+{
+ QDesignerFormWindowInterface *fwi = core()->formWindowManager()->activeFormWindow();
+ if (!fwi || m_mode == NeutralMode)
+ return;
+ QDesignerFormWindow *fw = qobject_cast<QDesignerFormWindow *>(fwi->parentWidget());
+ Q_ASSERT(fw);
+ setFormWindowMinimized(fw, !isFormWindowMinimized(fw));
+}
+
+bool QDesignerWorkbench::isFormWindowMinimized(const QDesignerFormWindow *fw)
+{
+ switch (m_mode) {
+ case DockedMode:
+ return mdiSubWindowOf(fw)->isShaded();
+ case TopLevelMode:
+ return fw->window()->isMinimized();
+ default:
+ break;
+ }
+ return fw->isMinimized();
+}
+
+void QDesignerWorkbench::setFormWindowMinimized(QDesignerFormWindow *fw, bool minimized)
+{
+ switch (m_mode) {
+ case DockedMode: {
+ QMdiSubWindow *mdiSubWindow = mdiSubWindowOf(fw);
+ if (minimized) {
+ mdiSubWindow->showShaded();
+ } else {
+ mdiSubWindow->setWindowState(mdiSubWindow->windowState() & ~Qt::WindowMinimized);
+ }
+ }
+ break;
+ case TopLevelMode: {
+ QWidget *window = fw->window();
+ if (window->isMinimized()) {
+ window->setWindowState(window->windowState() & ~Qt::WindowMinimized);
+ } else {
+ window->showMinimized();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void QDesignerWorkbench::restoreUISettings()
+{
+ UIMode mode = QDesignerSettings(m_core).uiMode();
+ switch (mode) {
+ case TopLevelMode:
+ switchToTopLevelMode();
+ break;
+ case DockedMode:
+ switchToDockedMode();
+ break;
+
+ default: Q_ASSERT(0);
+ }
+
+ ToolWindowFontSettings fontSettings = QDesignerSettings(m_core).toolWindowFont();
+ const QFont &font = fontSettings.m_useFont ? fontSettings.m_font : qApp->font();
+
+ if (font == m_toolWindows.front()->font())
+ return;
+
+ foreach(QDesignerToolWindow *tw, m_toolWindows)
+ tw->setFont(font);
+}
+
+void QDesignerWorkbench::handleCloseEvent(QCloseEvent *ev)
+{
+ ev->setAccepted(handleClose());
+ if (ev->isAccepted())
+ QMetaObject::invokeMethod(qDesigner, "quit", Qt::QueuedConnection); // We're going down!
+}
+
+QDesignerToolWindow *QDesignerWorkbench::widgetBoxToolWindow() const
+{
+ return m_toolWindows.at(QDesignerToolWindow::WidgetBox);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_workbench.h b/src/designer/src/designer/qdesigner_workbench.h
new file mode 100644
index 000000000..9266eea60
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_workbench.h
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_WORKBENCH_H
+#define QDESIGNER_WORKBENCH_H
+
+#include "designer_enums.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QList>
+#include <QtCore/QRect>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerActions;
+class QDesignerToolWindow;
+class QDesignerFormWindow;
+class DockedMainWindow;
+class QDesignerSettings;
+
+class QAction;
+class QActionGroup;
+class QDockWidget;
+class QMenu;
+class QMenuBar;
+class QMainWindow;
+class QToolBar;
+class QMdiArea;
+class QMdiSubWindow;
+class QCloseEvent;
+class QFont;
+class QtToolBarManager;
+class ToolBarManager;
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QDesignerFormWindowManagerInterface;
+
+namespace qdesigner_internal {
+class QDesignerIntegration;
+}
+
+class QDesignerWorkbench: public QObject
+{
+ Q_OBJECT
+
+public:
+ QDesignerWorkbench();
+ virtual ~QDesignerWorkbench();
+
+ UIMode mode() const;
+
+ QDesignerFormEditorInterface *core() const;
+ QDesignerFormWindow *findFormWindow(QWidget *widget) const;
+
+ QDesignerFormWindow *openForm(const QString &fileName, QString *errorMessage);
+ QDesignerFormWindow *openTemplate(const QString &templateFileName,
+ const QString &editorFileName,
+ QString *errorMessage);
+
+ int toolWindowCount() const;
+ QDesignerToolWindow *toolWindow(int index) const;
+
+ int formWindowCount() const;
+ QDesignerFormWindow *formWindow(int index) const;
+
+ QDesignerActions *actionManager() const;
+
+ QActionGroup *modeActionGroup() const;
+
+ QRect availableGeometry() const;
+ QRect desktopGeometry() const;
+
+ int marginHint() const;
+
+ bool readInForm(const QString &fileName) const;
+ bool writeOutForm(QDesignerFormWindowInterface *formWindow, const QString &fileName) const;
+ bool saveForm(QDesignerFormWindowInterface *fw);
+ bool handleClose();
+ bool readInBackup();
+ void updateBackup(QDesignerFormWindowInterface* fwi);
+
+signals:
+ void modeChanged(UIMode mode);
+ void initialized();
+
+public slots:
+ void addFormWindow(QDesignerFormWindow *formWindow);
+ void removeFormWindow(QDesignerFormWindow *formWindow);
+ void bringAllToFront();
+ void toggleFormMinimizationState();
+
+private slots:
+ void switchToNeutralMode();
+ void switchToDockedMode();
+ void switchToTopLevelMode();
+ void initializeCorePlugins();
+ void handleCloseEvent(QCloseEvent *);
+ void slotFormWindowActivated(QDesignerFormWindow* fw);
+ void updateWindowMenu(QDesignerFormWindowInterface *fw);
+ void formWindowActionTriggered(QAction *a);
+ void adjustMDIFormPositions();
+ void minimizationStateChanged(QDesignerFormWindowInterface *formWindow, bool minimized);
+
+ void restoreUISettings();
+ void slotFileDropped(const QString &f);
+
+private:
+ QWidget *magicalParent(const QWidget *w) const;
+ Qt::WindowFlags magicalWindowFlags(const QWidget *widgetForFlags) const;
+ QDesignerFormWindowManagerInterface *formWindowManager() const;
+ void closeAllToolWindows();
+ QDesignerToolWindow *widgetBoxToolWindow() const;
+ QDesignerFormWindow *loadForm(const QString &fileName, bool detectLineTermiantorMode, bool *uic3Converted, QString *errorMessage);
+ void resizeForm(QDesignerFormWindow *fw, const QWidget *mainContainer) const;
+ void saveGeometriesForModeChange();
+ void saveGeometries(QDesignerSettings &settings) const;
+
+ bool isFormWindowMinimized(const QDesignerFormWindow *fw);
+ void setFormWindowMinimized(QDesignerFormWindow *fw, bool minimized);
+ void saveSettings() const;
+
+ QDesignerFormEditorInterface *m_core;
+ qdesigner_internal::QDesignerIntegration *m_integration;
+
+ QDesignerActions *m_actionManager;
+ QActionGroup *m_windowActions;
+
+ QMenu *m_windowMenu;
+
+ QMenuBar *m_globalMenuBar;
+
+ struct TopLevelData {
+ ToolBarManager *toolbarManager;
+ QList<QToolBar *> toolbars;
+ };
+ TopLevelData m_topLevelData;
+
+ UIMode m_mode;
+ DockedMainWindow *m_dockedMainWindow;
+
+ QList<QDesignerToolWindow*> m_toolWindows;
+ QList<QDesignerFormWindow*> m_formWindows;
+
+ QMenu *m_toolbarMenu;
+
+ // Helper class to remember the position of a window while switching user
+ // interface modes.
+ class Position {
+ public:
+ Position(const QDockWidget *dockWidget);
+ Position(const QMdiSubWindow *mdiSubWindow, const QPoint &mdiAreaOffset);
+ Position(const QWidget *topLevelWindow, const QPoint &desktopTopLeft);
+
+ void applyTo(QMdiSubWindow *mdiSubWindow, const QPoint &mdiAreaOffset) const;
+ void applyTo(QWidget *topLevelWindow, const QPoint &desktopTopLeft) const;
+ void applyTo(QDockWidget *dockWidget) const;
+
+ QPoint position() const { return m_position; }
+ private:
+ bool m_minimized;
+ // Position referring to top-left corner (desktop in top-level mode or
+ // main window in MDI mode)
+ QPoint m_position;
+ };
+ typedef QHash<QWidget*, Position> PositionMap;
+ PositionMap m_Positions;
+
+ enum State { StateInitializing, StateUp, StateClosing };
+ State m_state;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_WORKBENCH_H
diff --git a/src/designer/src/designer/saveformastemplate.cpp b/src/designer/src/designer/saveformastemplate.cpp
new file mode 100644
index 000000000..49ac64ee5
--- /dev/null
+++ b/src/designer/src/designer/saveformastemplate.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "saveformastemplate.h"
+#include "qdesigner_settings.h"
+
+#include <QtCore/QFile>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+
+#include <QtDesigner/abstractformeditor.h>
+#include <QtDesigner/abstractformwindow.h>
+
+QT_BEGIN_NAMESPACE
+
+SaveFormAsTemplate::SaveFormAsTemplate(QDesignerFormEditorInterface *core,
+ QDesignerFormWindowInterface *formWindow,
+ QWidget *parent)
+ : QDialog(parent, Qt::Sheet),
+ m_core(core),
+ m_formWindow(formWindow)
+{
+ ui.setupUi(this);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ ui.templateNameEdit->setText(formWindow->mainContainer()->objectName());
+ ui.templateNameEdit->selectAll();
+
+ ui.templateNameEdit->setFocus();
+
+ QStringList paths = QDesignerSettings(m_core).formTemplatePaths();
+ ui.categoryCombo->addItems(paths);
+ ui.categoryCombo->addItem(tr("Add path..."));
+ m_addPathIndex = ui.categoryCombo->count() - 1;
+ connect(ui.templateNameEdit, SIGNAL(textChanged(QString)),
+ this, SLOT(updateOKButton(QString)));
+ connect(ui.categoryCombo, SIGNAL(activated(int)), this, SLOT(checkToAddPath(int)));
+}
+
+SaveFormAsTemplate::~SaveFormAsTemplate()
+{
+}
+
+void SaveFormAsTemplate::accept()
+{
+ QString templateFileName = ui.categoryCombo->currentText();
+ templateFileName += QLatin1Char('/');
+ const QString name = ui.templateNameEdit->text();
+ templateFileName += name;
+ const QString extension = QLatin1String(".ui");
+ if (!templateFileName.endsWith(extension))
+ templateFileName.append(extension);
+ QFile file(templateFileName);
+
+ if (file.exists()) {
+ QMessageBox msgBox(QMessageBox::Information, tr("Template Exists"),
+ tr("A template with the name %1 already exists.\n"
+ "Do you want overwrite the template?").arg(name), QMessageBox::Cancel, m_formWindow);
+ msgBox.setDefaultButton(QMessageBox::Cancel);
+ QPushButton *overwriteButton = msgBox.addButton(tr("Overwrite Template"), QMessageBox::AcceptRole);
+ msgBox.exec();
+ if (msgBox.clickedButton() != overwriteButton)
+ return;
+ }
+
+ while (!file.open(QFile::WriteOnly)) {
+ if (QMessageBox::information(m_formWindow, tr("Open Error"),
+ tr("There was an error opening template %1 for writing. Reason: %2").arg(name).arg(file.errorString()),
+ QMessageBox::Retry|QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Cancel) {
+ return;
+ }
+ }
+
+ const QString origName = m_formWindow->fileName();
+ // ensure m_formWindow->contents() will convert properly resource paths to relative paths
+ // (relative to template location, not to the current form location)
+ m_formWindow->setFileName(templateFileName);
+ QByteArray ba = m_formWindow->contents().toUtf8();
+ m_formWindow->setFileName(origName);
+ while (file.write(ba) != ba.size()) {
+ if (QMessageBox::information(m_formWindow, tr("Write Error"),
+ tr("There was an error writing the template %1 to disk. Reason: %2").arg(name).arg(file.errorString()),
+ QMessageBox::Retry|QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Cancel) {
+ file.close();
+ file.remove();
+ return;
+ }
+ file.reset();
+ }
+ // update the list of places too...
+ QStringList sl;
+ for (int i = 0; i < m_addPathIndex; ++i)
+ sl << ui.categoryCombo->itemText(i);
+
+ QDesignerSettings(m_core).setFormTemplatePaths(sl);
+
+ QDialog::accept();
+}
+
+void SaveFormAsTemplate::updateOKButton(const QString &str)
+{
+ QPushButton *okButton = ui.buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setEnabled(!str.isEmpty());
+}
+
+QString SaveFormAsTemplate::chooseTemplatePath(QWidget *parent)
+{
+ QString rc = QFileDialog::getExistingDirectory(parent,
+ tr("Pick a directory to save templates in"));
+ if (rc.isEmpty())
+ return rc;
+
+ if (rc.endsWith(QDir::separator()))
+ rc.remove(rc.size() - 1, 1);
+ return rc;
+}
+
+void SaveFormAsTemplate::checkToAddPath(int itemIndex)
+{
+ if (itemIndex != m_addPathIndex)
+ return;
+
+ const QString dir = chooseTemplatePath(this);
+ if (dir.isEmpty()) {
+ ui.categoryCombo->setCurrentIndex(0);
+ return;
+ }
+
+ ui.categoryCombo->insertItem(m_addPathIndex, dir);
+ ui.categoryCombo->setCurrentIndex(m_addPathIndex);
+ ++m_addPathIndex;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/saveformastemplate.h b/src/designer/src/designer/saveformastemplate.h
new file mode 100644
index 000000000..8b0b3ab8e
--- /dev/null
+++ b/src/designer/src/designer/saveformastemplate.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SAVEFORMASTEMPLATE_H
+#define SAVEFORMASTEMPLATE_H
+
+#include "ui_saveformastemplate.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+
+class SaveFormAsTemplate: public QDialog
+{
+ Q_OBJECT
+public:
+ explicit SaveFormAsTemplate(QDesignerFormEditorInterface *m_core,
+ QDesignerFormWindowInterface *formWindow,
+ QWidget *parent = 0);
+ virtual ~SaveFormAsTemplate();
+
+private slots:
+ void accept();
+ void updateOKButton(const QString &str);
+ void checkToAddPath(int itemIndex);
+
+private:
+ static QString chooseTemplatePath(QWidget *parent);
+
+ Ui::SaveFormAsTemplate ui;
+ QDesignerFormEditorInterface *m_core;
+ QDesignerFormWindowInterface *m_formWindow;
+ int m_addPathIndex;
+};
+
+QT_END_NAMESPACE
+
+#endif // SAVEFORMASTEMPLATE_H
diff --git a/src/designer/src/designer/saveformastemplate.ui b/src/designer/src/designer/saveformastemplate.ui
new file mode 100644
index 000000000..c29ad9ad4
--- /dev/null
+++ b/src/designer/src/designer/saveformastemplate.ui
@@ -0,0 +1,166 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>SaveFormAsTemplate</class>
+ <widget class="QDialog" name="SaveFormAsTemplate" >
+ <property name="windowTitle" >
+ <string>Save Form As Template</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QFormLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text" >
+ <string>&amp;Name:</string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::AutoText</enum>
+ </property>
+ <property name="buddy" >
+ <cstring>templateNameEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="templateNameEdit" >
+ <property name="minimumSize" >
+ <size>
+ <width>222</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="echoMode" >
+ <enum>QLineEdit::Normal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text" >
+ <string>&amp;Category:</string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::AutoText</enum>
+ </property>
+ <property name="buddy" >
+ <cstring>categoryCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="categoryCombo" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QFrame" name="horizontalLine" >
+ <property name="frameShape" >
+ <enum>QFrame::HLine</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>SaveFormAsTemplate</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>256</x>
+ <y>124</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>113</x>
+ <y>143</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>SaveFormAsTemplate</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>332</x>
+ <y>127</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>372</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/designer/uifile.icns b/src/designer/src/designer/uifile.icns
new file mode 100644
index 000000000..2473ea4dc
--- /dev/null
+++ b/src/designer/src/designer/uifile.icns
Binary files differ
diff --git a/src/designer/src/designer/versiondialog.cpp b/src/designer/src/designer/versiondialog.cpp
new file mode 100644
index 000000000..63a95e6d7
--- /dev/null
+++ b/src/designer/src/designer/versiondialog.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QVector>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QPainter>
+#include <QtGui/QPainterPath>
+#include <QtGui/QStyleOption>
+#include "versiondialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class VersionLabel : public QLabel
+{
+ Q_OBJECT
+public:
+ VersionLabel(QWidget *parent = 0);
+
+signals:
+ void triggered();
+
+protected:
+ void mousePressEvent(QMouseEvent *me);
+ void mouseMoveEvent(QMouseEvent *me);
+ void mouseReleaseEvent(QMouseEvent *me);
+ void paintEvent(QPaintEvent *pe);
+private:
+ QVector<QPoint> hitPoints;
+ QVector<QPoint> missPoints;
+ QPainterPath m_path;
+ bool secondStage;
+ bool m_pushed;
+};
+
+VersionLabel::VersionLabel(QWidget *parent)
+ : QLabel(parent), secondStage(false), m_pushed(false)
+{
+ setPixmap(QPixmap(QLatin1String(":/trolltech/designer/images/designer.png")));
+ hitPoints.append(QPoint(56, 25));
+ hitPoints.append(QPoint(29, 55));
+ hitPoints.append(QPoint(56, 87));
+ hitPoints.append(QPoint(82, 55));
+ hitPoints.append(QPoint(58, 56));
+
+ secondStage = false;
+ m_pushed = false;
+}
+
+void VersionLabel::mousePressEvent(QMouseEvent *me)
+{
+ if (me->button() == Qt::LeftButton) {
+ if (!secondStage) {
+ m_path = QPainterPath(me->pos());
+ } else {
+ m_pushed = true;
+ update();
+ }
+ }
+}
+
+void VersionLabel::mouseMoveEvent(QMouseEvent *me)
+{
+ if (me->buttons() & Qt::LeftButton)
+ if (!secondStage)
+ m_path.lineTo(me->pos());
+}
+
+void VersionLabel::mouseReleaseEvent(QMouseEvent *me)
+{
+ if (me->button() == Qt::LeftButton) {
+ if (!secondStage) {
+ m_path.lineTo(me->pos());
+ bool gotIt = true;
+ foreach(const QPoint &pt, hitPoints) {
+ if (!m_path.contains(pt)) {
+ gotIt = false;
+ break;
+ }
+ }
+ if (gotIt) {
+ foreach(const QPoint &pt, missPoints) {
+ if (m_path.contains(pt)) {
+ gotIt = false;
+ break;
+ }
+ }
+ }
+ if (gotIt && !secondStage) {
+ secondStage = true;
+ m_path = QPainterPath();
+ update();
+ }
+ } else {
+ m_pushed = false;
+ update();
+ emit triggered();
+ }
+ }
+}
+
+void VersionLabel::paintEvent(QPaintEvent *pe)
+{
+ if (secondStage) {
+ QPainter p(this);
+ QStyleOptionButton opt;
+ opt.init(this);
+ if (!m_pushed)
+ opt.state |= QStyle::State_Raised;
+ else
+ opt.state |= QStyle::State_Sunken;
+ opt.state &= ~QStyle::State_HasFocus;
+ style()->drawControl(QStyle::CE_PushButtonBevel, &opt, &p, this);
+ }
+ QLabel::paintEvent(pe);
+}
+
+VersionDialog::VersionDialog(QWidget *parent)
+ : QDialog(parent
+#ifdef Q_WS_MAC
+ , Qt::Tool
+#endif
+ )
+{
+ setWindowFlags((windowFlags() & ~Qt::WindowContextHelpButtonHint) | Qt::MSWindowsFixedSizeDialogHint);
+ QGridLayout *layout = new QGridLayout(this);
+ VersionLabel *label = new VersionLabel;
+ QLabel *lbl = new QLabel;
+ QString version = tr("<h3>%1</h3><br/><br/>Version %2");
+ version = version.arg(tr("Qt Designer")).arg(QLatin1String(QT_VERSION_STR));
+ version.append(tr("<br/>Qt Designer is a graphical user interface designer for Qt applications.<br/>"));
+
+ lbl->setText(tr("%1"
+ "<br/>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+ ).arg(version));
+
+ lbl->setWordWrap(true);
+ lbl->setOpenExternalLinks(true);
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
+ connect(buttonBox , SIGNAL(rejected()), this, SLOT(reject()));
+ connect(label, SIGNAL(triggered()), this, SLOT(accept()));
+ layout->addWidget(label, 0, 0, 1, 1);
+ layout->addWidget(lbl, 0, 1, 4, 4);
+ layout->addWidget(buttonBox, 4, 2, 1, 1);
+}
+
+QT_END_NAMESPACE
+
+#include "versiondialog.moc"
diff --git a/src/designer/src/designer/versiondialog.h b/src/designer/src/designer/versiondialog.h
new file mode 100644
index 000000000..0e6760092
--- /dev/null
+++ b/src/designer/src/designer/versiondialog.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VERSIONDIALOG_H
+#define VERSIONDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class VersionDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit VersionDialog(QWidget *parent);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/components/qdesigner_components.h b/src/designer/src/lib/components/qdesigner_components.h
new file mode 100644
index 000000000..e11afc3ee
--- /dev/null
+++ b/src/designer/src/lib/components/qdesigner_components.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_COMPONENTS_H
+#define QDESIGNER_COMPONENTS_H
+
+#include <QtDesigner/qdesigner_components_global.h>
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+class QWidget;
+
+class QDesignerFormEditorInterface;
+class QDesignerWidgetBoxInterface;
+class QDesignerPropertyEditorInterface;
+class QDesignerObjectInspectorInterface;
+class QDesignerActionEditorInterface;
+
+class QDESIGNER_COMPONENTS_EXPORT QDesignerComponents
+{
+public:
+ static void initializeResources();
+ static void initializePlugins(QDesignerFormEditorInterface *core);
+
+ static QDesignerFormEditorInterface *createFormEditor(QObject *parent);
+ static QDesignerWidgetBoxInterface *createWidgetBox(QDesignerFormEditorInterface *core, QWidget *parent);
+ static QDesignerPropertyEditorInterface *createPropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent);
+ static QDesignerObjectInspectorInterface *createObjectInspector(QDesignerFormEditorInterface *core, QWidget *parent);
+ static QDesignerActionEditorInterface *createActionEditor(QDesignerFormEditorInterface *core, QWidget *parent);
+
+ static QObject *createTaskMenu(QDesignerFormEditorInterface *core, QObject *parent);
+ static QWidget *createResourceEditor(QDesignerFormEditorInterface *core, QWidget *parent);
+ static QWidget *createSignalSlotEditor(QDesignerFormEditorInterface *core, QWidget *parent);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDESIGNER_COMPONENTS_H
diff --git a/src/designer/src/lib/components/qdesigner_components_global.h b/src/designer/src/lib/components/qdesigner_components_global.h
new file mode 100644
index 000000000..93f3c73ce
--- /dev/null
+++ b/src/designer/src/lib/components/qdesigner_components_global.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_COMPONENTS_GLOBAL_H
+#define QDESIGNER_COMPONENTS_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define QDESIGNER_COMPONENTS_EXTERN Q_DECL_EXPORT
+#define QDESIGNER_COMPONENTS_IMPORT Q_DECL_IMPORT
+
+#ifdef QT_DESIGNER_STATIC
+# define QDESIGNER_COMPONENTS_EXPORT
+#elif defined(QDESIGNER_COMPONENTS_LIBRARY)
+# define QDESIGNER_COMPONENTS_EXPORT QDESIGNER_COMPONENTS_EXTERN
+#else
+# define QDESIGNER_COMPONENTS_EXPORT QDESIGNER_COMPONENTS_IMPORT
+#endif
+
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // QDESIGNER_COMPONENTS_GLOBAL_H
diff --git a/src/designer/src/lib/extension/default_extensionfactory.cpp b/src/designer/src/lib/extension/default_extensionfactory.cpp
new file mode 100644
index 000000000..a90886695
--- /dev/null
+++ b/src/designer/src/lib/extension/default_extensionfactory.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner/default_extensionfactory.h>
+#include "qextensionmanager.h"
+#include <qpointer.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QExtensionFactory
+
+ \brief The QExtensionFactory class allows you to create a factory
+ that is able to make instances of custom extensions in Qt
+ Designer.
+
+ \inmodule QtDesigner
+
+ In \QD the extensions are not created until they are required. For
+ that reason, when implementing a custom extension, you must also
+ create a QExtensionFactory, i.e. a class that is able to make an
+ instance of your extension, and register it using \QD's \l
+ {QExtensionManager}{extension manager}.
+
+ The QExtensionManager class provides extension management
+ facilities for Qt Designer. When an extension is required, Qt
+ Designer's \l {QExtensionManager}{extension manager} will run
+ through all its registered factories calling
+ QExtensionFactory::createExtension() for each until the first one
+ that is able to create a requested extension for the selected
+ object, is found. This factory will then make an instance of the
+ extension.
+
+ There are four available types of extensions in Qt Designer:
+ QDesignerContainerExtension , QDesignerMemberSheetExtension,
+ QDesignerPropertySheetExtension and QDesignerTaskMenuExtension. Qt
+ Designer's behavior is the same whether the requested extension is
+ associated with a multi page container, a member sheet, a property
+ sheet or a task menu.
+
+ You can either create a new QExtensionFactory and reimplement the
+ QExtensionFactory::createExtension() function. For example:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_extension_default_extensionfactory.cpp 0
+
+ Or you can use an existing factory, expanding the
+ QExtensionFactory::createExtension() function to make the factory
+ able to create your extension as well. For example:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_extension_default_extensionfactory.cpp 1
+
+ For a complete example using the QExtensionFactory class, see the
+ \l {designer/taskmenuextension}{Task Menu Extension example}. The
+ example shows how to create a custom widget plugin for Qt
+ Designer, and how to to use the QDesignerTaskMenuExtension class
+ to add custom items to Qt Designer's task menu.
+
+ \sa QExtensionManager, QAbstractExtensionFactory
+*/
+
+/*!
+ Constructs an extension factory with the given \a parent.
+*/
+QExtensionFactory::QExtensionFactory(QExtensionManager *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ Returns the extension specified by \a iid for the given \a object.
+
+ \sa createExtension()
+*/
+
+QObject *QExtensionFactory::extension(QObject *object, const QString &iid) const
+{
+ if (!object)
+ return 0;
+ const IdObjectKey key = qMakePair(iid, object);
+
+ ExtensionMap::iterator it = m_extensions.find(key);
+ if (it == m_extensions.end()) {
+ if (QObject *ext = createExtension(object, iid, const_cast<QExtensionFactory*>(this))) {
+ connect(ext, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
+ it = m_extensions.insert(key, ext);
+ }
+ }
+
+ if (!m_extended.contains(object)) {
+ connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
+ m_extended.insert(object, true);
+ }
+
+ if (it == m_extensions.end())
+ return 0;
+
+ return it.value();
+}
+
+void QExtensionFactory::objectDestroyed(QObject *object)
+{
+ QMutableMapIterator< IdObjectKey, QObject*> it(m_extensions);
+ while (it.hasNext()) {
+ it.next();
+
+ QObject *o = it.key().second;
+ if (o == object || object == it.value()) {
+ it.remove();
+ }
+ }
+
+ m_extended.remove(object);
+}
+
+/*!
+ Creates an extension specified by \a iid for the given \a object.
+ The extension object is created as a child of the specified \a
+ parent.
+
+ \sa extension()
+*/
+QObject *QExtensionFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ Q_UNUSED(object);
+ Q_UNUSED(iid);
+ Q_UNUSED(parent);
+
+ return 0;
+}
+
+/*!
+ Returns the extension manager for the extension factory.
+*/
+QExtensionManager *QExtensionFactory::extensionManager() const
+{
+ return static_cast<QExtensionManager *>(parent());
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/extension/default_extensionfactory.h b/src/designer/src/lib/extension/default_extensionfactory.h
new file mode 100644
index 000000000..370e69aae
--- /dev/null
+++ b/src/designer/src/lib/extension/default_extensionfactory.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_EXTENSIONFACTORY_H
+#define DEFAULT_EXTENSIONFACTORY_H
+
+#include <QtDesigner/extension_global.h>
+#include <QtDesigner/extension.h>
+
+#include <QtCore/QMap>
+#include <QtCore/QHash>
+#include <QtCore/QPair>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QExtensionManager;
+
+class QDESIGNER_EXTENSION_EXPORT QExtensionFactory : public QObject, public QAbstractExtensionFactory
+{
+ Q_OBJECT
+ Q_INTERFACES(QAbstractExtensionFactory)
+public:
+ QExtensionFactory(QExtensionManager *parent = 0);
+
+ virtual QObject *extension(QObject *object, const QString &iid) const;
+ QExtensionManager *extensionManager() const;
+
+private Q_SLOTS:
+ void objectDestroyed(QObject *object);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ typedef QPair<QString,QObject*> IdObjectKey;
+ typedef QMap< IdObjectKey, QObject*> ExtensionMap;
+ mutable ExtensionMap m_extensions;
+ typedef QHash<QObject*, bool> ExtendedSet;
+ mutable ExtendedSet m_extended;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // DEFAULT_EXTENSIONFACTORY_H
diff --git a/src/designer/src/lib/extension/extension.cpp b/src/designer/src/lib/extension/extension.cpp
new file mode 100644
index 000000000..4d325126b
--- /dev/null
+++ b/src/designer/src/lib/extension/extension.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner/extension.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAbstractExtensionFactory
+
+ \brief The QAbstractExtensionFactory class provides an interface
+ for extension factories in Qt Designer.
+
+ \inmodule QtDesigner
+
+ QAbstractExtensionFactory is not intended to be instantiated
+ directly; use the QExtensionFactory instead.
+
+ In \QD, extension factories are used to look up and create named
+ extensions as they are required. For that reason, when
+ implementing a custom extension, you must also create a
+ QExtensionFactory, i.e a class that is able to make an instance of
+ your extension, and register it using \QD's \l
+ {QExtensionManager}{extension manager}.
+
+ When an extension is required, \QD's \l
+ {QExtensionManager}{extension manager} will run through all its
+ registered factories calling QExtensionFactory::createExtension()
+ for each until the first one that is able to create the requested
+ extension for the selected object, is found. This factory will
+ then make an instance of the extension.
+
+ \sa QExtensionFactory, QExtensionManager
+*/
+
+/*!
+ \fn QAbstractExtensionFactory::~QAbstractExtensionFactory()
+
+ Destroys the extension factory.
+*/
+
+/*!
+ \fn QObject *QAbstractExtensionFactory::extension(QObject *object, const QString &iid) const
+
+ Returns the extension specified by \a iid for the given \a object.
+*/
+
+
+/*!
+ \class QAbstractExtensionManager
+
+ \brief The QAbstractExtensionManager class provides an interface
+ for extension managers in Qt Designer.
+
+ \inmodule QtDesigner
+
+ QAbstractExtensionManager is not intended to be instantiated
+ directly; use the QExtensionManager instead.
+
+ In \QD, extension are not created until they are required. For
+ that reason, when implementing a custom extension, you must also
+ create a QExtensionFactory, i.e a class that is able to make an
+ instance of your extension, and register it using \QD's \l
+ {QExtensionManager}{extension manager}.
+
+ When an extension is required, \QD's \l
+ {QExtensionManager}{extension manager} will run through all its
+ registered factories calling QExtensionFactory::createExtension()
+ for each until the first one that is able to create the requested
+ extension for the selected object, is found. This factory will
+ then make an instance of the extension.
+
+ \sa QExtensionManager, QExtensionFactory
+*/
+
+/*!
+ \fn QAbstractExtensionManager::~QAbstractExtensionManager()
+
+ Destroys the extension manager.
+*/
+
+/*!
+ \fn void QAbstractExtensionManager::registerExtensions(QAbstractExtensionFactory *factory, const QString &iid)
+
+ Register the given extension \a factory with the extension
+ specified by \a iid.
+*/
+
+/*!
+ \fn void QAbstractExtensionManager::unregisterExtensions(QAbstractExtensionFactory *factory, const QString &iid)
+
+ Unregister the given \a factory with the extension specified by \a
+ iid.
+*/
+
+/*!
+ \fn QObject *QAbstractExtensionManager::extension(QObject *object, const QString &iid) const
+
+ Returns the extension, specified by \a iid, for the given \a
+ object.
+*/
+
+/*!
+ \fn T qt_extension(QAbstractExtensionManager* manager, QObject *object)
+
+ \relates QExtensionManager
+
+ Returns the extension of the given \a object cast to type T if the
+ object is of type T (or of a subclass); otherwise returns 0. The
+ extension is retrieved using the given extension \a manager.
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_extension_extension.cpp 0
+
+ When implementing a custom widget plugin, a pointer to \QD's
+ current QDesignerFormEditorInterface object (\c formEditor) is
+ provided by the QDesignerCustomWidgetInterface::initialize()
+ function's parameter.
+
+ If the widget in the example above doesn't have a defined
+ QDesignerPropertySheetExtension, \c propertySheet will be a null
+ pointer.
+
+*/
+
+/*!
+ \macro Q_DECLARE_EXTENSION_INTERFACE(ExtensionName, Identifier)
+
+ \relates QExtensionManager
+
+ Associates the given \a Identifier (a string literal) to the
+ extension class called \a ExtensionName. The \a Identifier must be
+ unique. For example:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_extension_extension.cpp 1
+
+ Using the company and product names is a good way to ensure
+ uniqueness of the identifier.
+
+ When implementing a custom extension class, you must use
+ Q_DECLARE_EXTENSION_INTERFACE() to enable usage of the
+ qt_extension() function. The macro is normally located right after the
+ class definition for \a ExtensionName, in the associated header
+ file.
+
+ \sa Q_DECLARE_INTERFACE()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/extension/extension.h b/src/designer/src/lib/extension/extension.h
new file mode 100644
index 000000000..749550324
--- /dev/null
+++ b/src/designer/src/lib/extension/extension.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EXTENSION_H
+#define EXTENSION_H
+
+#include <QtCore/QString>
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_TYPEID(IFace) QLatin1String(IFace##_iid)
+
+class QAbstractExtensionFactory
+{
+public:
+ virtual ~QAbstractExtensionFactory() {}
+
+ virtual QObject *extension(QObject *object, const QString &iid) const = 0;
+};
+Q_DECLARE_INTERFACE(QAbstractExtensionFactory, "com.trolltech.Qt.QAbstractExtensionFactory")
+
+class QAbstractExtensionManager
+{
+public:
+ virtual ~QAbstractExtensionManager() {}
+
+ virtual void registerExtensions(QAbstractExtensionFactory *factory, const QString &iid) = 0;
+ virtual void unregisterExtensions(QAbstractExtensionFactory *factory, const QString &iid) = 0;
+
+ virtual QObject *extension(QObject *object, const QString &iid) const = 0;
+};
+Q_DECLARE_INTERFACE(QAbstractExtensionManager, "com.trolltech.Qt.QAbstractExtensionManager")
+
+#if defined(Q_CC_MSVC) && (_MSC_VER < 1300)
+
+template <class T>
+inline T qt_extension_helper(QAbstractExtensionManager *, QObject *, T)
+{ return 0; }
+
+template <class T>
+inline T qt_extension(QAbstractExtensionManager* manager, QObject *object)
+{ return qt_extension_helper(manager, object, T(0)); }
+
+#define Q_DECLARE_EXTENSION_INTERFACE(IFace, IId) \
+const char * const IFace##_iid = IId; \
+Q_DECLARE_INTERFACE(IFace, IId) \
+template <> inline IFace *qt_extension_helper<IFace *>(QAbstractExtensionManager *manager, QObject *object, IFace *) \
+{ QObject *extension = manager->extension(object, Q_TYPEID(IFace)); return (IFace *)(extension ? extension->qt_metacast(IFace##_iid) : 0); }
+
+#else
+
+template <class T>
+inline T qt_extension(QAbstractExtensionManager* manager, QObject *object)
+{ return 0; }
+
+#define Q_DECLARE_EXTENSION_INTERFACE(IFace, IId) \
+const char * const IFace##_iid = IId; \
+Q_DECLARE_INTERFACE(IFace, IId) \
+template <> inline IFace *qt_extension<IFace *>(QAbstractExtensionManager *manager, QObject *object) \
+{ QObject *extension = manager->extension(object, Q_TYPEID(IFace)); return extension ? static_cast<IFace *>(extension->qt_metacast(IFace##_iid)) : static_cast<IFace *>(0); }
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // EXTENSION_H
diff --git a/src/designer/src/lib/extension/extension.pri b/src/designer/src/lib/extension/extension.pri
new file mode 100644
index 000000000..d8ef658f2
--- /dev/null
+++ b/src/designer/src/lib/extension/extension.pri
@@ -0,0 +1,12 @@
+# Input
+
+INCLUDEPATH += $$PWD
+
+HEADERS += $$PWD/default_extensionfactory.h \
+ $$PWD/extension.h \
+ $$PWD/qextensionmanager.h
+
+SOURCES += $$PWD/default_extensionfactory.cpp \
+ $$PWD/extension.cpp \
+ $$PWD/qextensionmanager.cpp
+
diff --git a/src/designer/src/lib/extension/extension_global.h b/src/designer/src/lib/extension/extension_global.h
new file mode 100644
index 000000000..25545bb21
--- /dev/null
+++ b/src/designer/src/lib/extension/extension_global.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EXTENSION_GLOBAL_H
+#define EXTENSION_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+#define QDESIGNER_EXTENSION_EXTERN Q_DECL_EXPORT
+#define QDESIGNER_EXTENSION_IMPORT Q_DECL_IMPORT
+
+#ifdef QT_DESIGNER_STATIC
+# define QDESIGNER_EXTENSION_EXPORT
+#elif defined(QDESIGNER_EXTENSION_LIBRARY)
+# define QDESIGNER_EXTENSION_EXPORT QDESIGNER_EXTENSION_EXTERN
+#else
+# define QDESIGNER_EXTENSION_EXPORT QDESIGNER_EXTENSION_IMPORT
+#endif
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // EXTENSION_GLOBAL_H
diff --git a/src/designer/src/lib/extension/qextensionmanager.cpp b/src/designer/src/lib/extension/qextensionmanager.cpp
new file mode 100644
index 000000000..960ae25ed
--- /dev/null
+++ b/src/designer/src/lib/extension/qextensionmanager.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qextensionmanager.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QExtensionManager
+
+ \brief The QExtensionManager class provides extension management
+ facilities for Qt Designer.
+
+ \inmodule QtDesigner
+
+ In \QD the extensions are not created until they are required. For
+ that reason, when implementing an extension, you must also create
+ a QExtensionFactory, i.e a class that is able to make an instance
+ of your extension, and register it using \QD's extension manager.
+
+ The registration of an extension factory is typically made in the
+ QDesignerCustomWidgetInterface::initialize() function:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_extension_qextensionmanager.cpp 0
+
+ The QExtensionManager is not intended to be instantiated
+ directly. You can retrieve an interface to \QD's extension manager
+ using the QDesignerFormEditorInterface::extensionManager()
+ function. A pointer to \QD's current QDesignerFormEditorInterface
+ object (\c formEditor in the example above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's
+ parameter. When implementing a custom widget plugin, you must
+ subclass the QDesignerCustomWidgetInterface to expose your plugin
+ to \QD.
+
+ Then, when an extension is required, \QD's extension manager will
+ run through all its registered factories calling
+ QExtensionFactory::createExtension() for each until the first one
+ that is able to create the requested extension for the selected
+ object, is found. This factory will then make an instance of the
+ extension.
+
+ There are four available types of extensions in \QD:
+ QDesignerContainerExtension , QDesignerMemberSheetExtension,
+ QDesignerPropertySheetExtension and
+ QDesignerTaskMenuExtension. \QD's behavior is the same whether the
+ requested extension is associated with a container, a member
+ sheet, a property sheet or a task menu.
+
+ For a complete example using the QExtensionManager class, see the
+ \l {designer/taskmenuextension}{Task Menu Extension example}. The
+ example shows how to create a custom widget plugin for Qt
+ Designer, and how to to use the QDesignerTaskMenuExtension class
+ to add custom items to \QD's task menu.
+
+ \sa QExtensionFactory, QAbstractExtensionManager
+*/
+
+/*!
+ Constructs an extension manager with the given \a parent.
+*/
+QExtensionManager::QExtensionManager(QObject *parent)
+ : QObject(parent)
+{
+}
+
+
+/*!
+ Destroys the extension manager
+*/
+QExtensionManager::~QExtensionManager()
+{
+}
+
+/*!
+ Register the extension specified by the given \a factory and
+ extension identifier \a iid.
+*/
+void QExtensionManager::registerExtensions(QAbstractExtensionFactory *factory, const QString &iid)
+{
+ if (iid.isEmpty()) {
+ m_globalExtension.prepend(factory);
+ return;
+ }
+
+ FactoryMap::iterator it = m_extensions.find(iid);
+ if (it == m_extensions.end())
+ it = m_extensions.insert(iid, FactoryList());
+
+ it.value().prepend(factory);
+}
+
+/*!
+ Unregister the extension specified by the given \a factory and
+ extension identifier \a iid.
+*/
+void QExtensionManager::unregisterExtensions(QAbstractExtensionFactory *factory, const QString &iid)
+{
+ if (iid.isEmpty()) {
+ m_globalExtension.removeAll(factory);
+ return;
+ }
+
+ const FactoryMap::iterator it = m_extensions.find(iid);
+ if (it == m_extensions.end())
+ return;
+
+ FactoryList &factories = it.value();
+ factories.removeAll(factory);
+
+ if (factories.isEmpty())
+ m_extensions.erase(it);
+}
+
+/*!
+ Returns the extension specified by \a iid, for the given \a
+ object.
+*/
+QObject *QExtensionManager::extension(QObject *object, const QString &iid) const
+{
+ const FactoryMap::const_iterator it = m_extensions.constFind(iid);
+ if (it != m_extensions.constEnd()) {
+ const FactoryList::const_iterator fcend = it.value().constEnd();
+ for (FactoryList::const_iterator fit = it.value().constBegin(); fit != fcend; ++fit)
+ if (QObject *ext = (*fit)->extension(object, iid))
+ return ext;
+ }
+ const FactoryList::const_iterator gfcend = m_globalExtension.constEnd();
+ for (FactoryList::const_iterator git = m_globalExtension.constBegin(); git != gfcend; ++git)
+ if (QObject *ext = (*git)->extension(object, iid))
+ return ext;
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/extension/qextensionmanager.h b/src/designer/src/lib/extension/qextensionmanager.h
new file mode 100644
index 000000000..a387924e6
--- /dev/null
+++ b/src/designer/src/lib/extension/qextensionmanager.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEXTENSIONMANAGER_H
+#define QEXTENSIONMANAGER_H
+
+#include <QtDesigner/extension_global.h>
+#include <QtDesigner/extension.h>
+#include <QtCore/QHash>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QObject; // Fool syncqt
+
+class QDESIGNER_EXTENSION_EXPORT QExtensionManager: public QObject, public QAbstractExtensionManager
+{
+ Q_OBJECT
+ Q_INTERFACES(QAbstractExtensionManager)
+public:
+ QExtensionManager(QObject *parent = 0);
+ ~QExtensionManager();
+
+ virtual void registerExtensions(QAbstractExtensionFactory *factory, const QString &iid = QString());
+ virtual void unregisterExtensions(QAbstractExtensionFactory *factory, const QString &iid = QString());
+
+ virtual QObject *extension(QObject *object, const QString &iid) const;
+
+private:
+ typedef QList<QAbstractExtensionFactory*> FactoryList;
+ typedef QHash<QString, FactoryList> FactoryMap;
+ FactoryMap m_extensions;
+ FactoryList m_globalExtension;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QEXTENSIONMANAGER_H
diff --git a/src/designer/src/lib/lib.pro b/src/designer/src/lib/lib.pro
new file mode 100644
index 000000000..3ba6f5235
--- /dev/null
+++ b/src/designer/src/lib/lib.pro
@@ -0,0 +1,78 @@
+TEMPLATE=lib
+TARGET=QtDesigner
+QT += xml
+contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
+CONFIG += qt
+win32|mac: CONFIG += debug_and_release
+DESTDIR = ../../../../lib
+!wince*:DLLDESTDIR = ../../../../bin
+
+isEmpty(QT_MAJOR_VERSION) {
+ VERSION=4.3.0
+} else {
+ VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
+}
+
+unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES += QtXml
+
+include(../../../../src/qt_targets.pri)
+QMAKE_TARGET_PRODUCT = Designer
+QMAKE_TARGET_DESCRIPTION = Graphical user interface designer.
+
+!contains(CONFIG, static) {
+ CONFIG += dll
+
+ DEFINES += \
+ QDESIGNER_SDK_LIBRARY \
+ QDESIGNER_EXTENSION_LIBRARY \
+ QDESIGNER_UILIB_LIBRARY \
+ QDESIGNER_SHARED_LIBRARY
+} else {
+ DEFINES += QT_DESIGNER_STATIC
+}
+
+#load up the headers info
+CONFIG += qt_install_headers
+HEADERS_PRI = $$QT_BUILD_TREE/include/QtDesigner/headers.pri
+include($$HEADERS_PRI, "", true)|clear(HEADERS_PRI)
+
+#mac frameworks
+mac:CONFIG += explicitlib
+mac:!static:contains(QT_CONFIG, qt_framework) {
+ QMAKE_FRAMEWORK_BUNDLE_NAME = $$TARGET
+ CONFIG += lib_bundle qt_no_framework_direct_includes qt_framework
+ CONFIG(debug, debug|release) {
+ !build_pass:CONFIG += build_all
+ } else { #release
+ !debug_and_release|build_pass {
+ CONFIG -= qt_install_headers #no need to install these as well
+ FRAMEWORK_HEADERS.version = Versions
+ FRAMEWORK_HEADERS.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES
+ FRAMEWORK_HEADERS.path = Headers
+ }
+ QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
+ }
+}
+
+include(extension/extension.pri)
+include(sdk/sdk.pri)
+include(uilib/uilib.pri)
+include(shared/shared.pri)
+PRECOMPILED_HEADER=lib_pch.h
+
+include(../sharedcomponents.pri)
+include(../components/component.pri)
+
+target.path=$$[QT_INSTALL_LIBS]
+INSTALLS += target
+win32 {
+ dlltarget.path=$$[QT_INSTALL_BINS]
+ INSTALLS += dlltarget
+}
+
+
+qt_install_headers {
+ designer_headers.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES
+ designer_headers.path = $$[QT_INSTALL_HEADERS]/QtDesigner
+ INSTALLS += designer_headers
+}
diff --git a/src/designer/src/lib/lib_pch.h b/src/designer/src/lib/lib_pch.h
new file mode 100644
index 000000000..17c3d8cd6
--- /dev/null
+++ b/src/designer/src/lib/lib_pch.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef __cplusplus
+#include "shared_global_p.h"
+#include <QtCore/qdebug.h>
+#include <QtDesigner/abstractformeditor.h>
+#include <QtDesigner/sdk_global.h>
+#include <QtCore/QObject>
+#include <QtDesigner/qextensionmanager.h>
+#include <QtDesigner/abstractformwindow.h>
+#include <QtCore/QMap>
+#include <QtGui/QWidget>
+#include <QtDesigner/propertysheet.h>
+#include <QtDesigner/extension.h>
+#include <QtDesigner/abstractmetadatabase.h>
+#include <QtCore/QList>
+#include <QtDesigner/abstractwidgetfactory.h>
+#include <QtDesigner/abstractwidgetdatabase.h>
+#include <QtGui/QWidget>
+#include "qdesigner_widget_p.h"
+#include <QtGui/QPainter>
+#include <QtGui/QMainWindow>
+#include <QtCore/qglobal.h>
+#include <QtCore/QPointer>
+#include "layout_p.h"
+#endif
diff --git a/src/designer/src/lib/sdk/abstractactioneditor.cpp b/src/designer/src/lib/sdk/abstractactioneditor.cpp
new file mode 100644
index 000000000..f0a7b76a7
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractactioneditor.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractactioneditor.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerActionEditorInterface
+
+ \brief The QDesignerActionEditorInterface class allows you to
+ change the focus of Qt Designer's action editor.
+
+ \inmodule QtDesigner
+
+ The QDesignerActionEditorInterface class is not intended to be
+ instantiated directly. You can retrieve an interface to \QD's
+ action editor using the
+ QDesignerFormEditorInterface::actionEditor() function.
+
+ You can control which actions that are available in the action
+ editor's window using the manageAction() and unmanageAction()
+ functions. An action that is managed by \QD is available in the
+ action editor while an unmanaged action is ignored.
+
+ QDesignerActionEditorInterface also provides the core() function
+ that you can use to retrieve a pointer to \QD's current
+ QDesignerFormEditorInterface object, and the setFormWindow()
+ function that enables you to change the currently selected form
+ window.
+
+ \sa QDesignerFormEditorInterface, QDesignerFormWindowInterface
+*/
+
+/*!
+ Constructs an action editor interface with the given \a parent and
+ the specified window \a flags.
+*/
+QDesignerActionEditorInterface::QDesignerActionEditorInterface(QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(parent, flags)
+{
+}
+
+/*!
+ Destroys the action editor interface.
+*/
+QDesignerActionEditorInterface::~QDesignerActionEditorInterface()
+{
+}
+
+/*!
+ Returns a pointer to \QD's current QDesignerFormEditorInterface
+ object.
+*/
+QDesignerFormEditorInterface *QDesignerActionEditorInterface::core() const
+{
+ return 0;
+}
+
+/*!
+ \fn void QDesignerActionEditorInterface::setFormWindow(QDesignerFormWindowInterface *formWindow)
+
+ Sets the currently selected form window to \a formWindow.
+
+*/
+
+/*!
+ \fn void QDesignerActionEditorInterface::manageAction(QAction *action)
+
+ Instructs \QD to manage the specified \a action. An action that is
+ managed by \QD is available in the action editor.
+
+ \sa unmanageAction()
+*/
+
+/*!
+ \fn void QDesignerActionEditorInterface::unmanageAction(QAction *action)
+
+ Instructs \QD to ignore the specified \a action. An unmanaged
+ action is not available in the action editor.
+
+ \sa manageAction()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractactioneditor.h b/src/designer/src/lib/sdk/abstractactioneditor.h
new file mode 100644
index 000000000..2d4241c23
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractactioneditor.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTACTIONEDITOR_H
+#define ABSTRACTACTIONEDITOR_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+
+class QDESIGNER_SDK_EXPORT QDesignerActionEditorInterface: public QWidget
+{
+ Q_OBJECT
+public:
+ QDesignerActionEditorInterface(QWidget *parent, Qt::WindowFlags flags = 0);
+ virtual ~QDesignerActionEditorInterface();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual void manageAction(QAction *action) = 0;
+ virtual void unmanageAction(QAction *action) = 0;
+
+public Q_SLOTS:
+ virtual void setFormWindow(QDesignerFormWindowInterface *formWindow) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTACTIONEDITOR_H
diff --git a/src/designer/src/lib/sdk/abstractbrushmanager.h b/src/designer/src/lib/sdk/abstractbrushmanager.h
new file mode 100644
index 000000000..87b1bf2c0
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractbrushmanager.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTBRUSHMANAGER_H
+#define ABSTRACTBRUSHMANAGER_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmap.h>
+#include <QtGui/qbrush.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+
+class QDESIGNER_SDK_EXPORT QDesignerBrushManagerInterface : public QObject
+{
+ Q_OBJECT
+public:
+ QDesignerBrushManagerInterface(QObject *parentObject = 0) : QObject(parentObject) {}
+
+ virtual QBrush brush(const QString &name) const = 0;
+ virtual QMap<QString, QBrush> brushes() const = 0;
+ virtual QString currentBrush() const = 0;
+
+ virtual QString addBrush(const QString &name, const QBrush &brush) = 0;
+ virtual void removeBrush(const QString &name) = 0;
+ virtual void setCurrentBrush(const QString &name) = 0;
+
+ virtual QPixmap brushPixmap(const QBrush &brush) const = 0;
+Q_SIGNALS:
+ void brushAdded(const QString &name, const QBrush &brush);
+ void brushRemoved(const QString &name);
+ void currentBrushChanged(const QString &name, const QBrush &brush);
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/designer/src/lib/sdk/abstractdialoggui.cpp b/src/designer/src/lib/sdk/abstractdialoggui.cpp
new file mode 100644
index 000000000..353f1eae6
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractdialoggui.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractdialoggui_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerDialogGuiInterface
+ \since 4.4
+ \internal
+
+ \brief The QDesignerDialogGuiInterface allows integrations of \QD to replace the
+ message boxes displayed by \QD by custom dialogs.
+
+ \inmodule QtDesigner
+
+ QDesignerDialogGuiInterface provides virtual functions that can be overwritten
+ to display message boxes and file dialogs.
+ \sa QMessageBox, QFileDialog
+*/
+
+/*!
+ \enum QDesignerDialogGuiInterface::Message
+
+ This enum specifies the context from within the message box is called.
+
+ \value FormLoadFailureMessage Loading of a form failed
+ \value UiVersionMismatchMessage Attempt to load a file created with an old version of Designer
+ \value ResourceLoadFailureMessage Resources specified in a file could not be found
+ \value TopLevelSpacerMessage Spacer items detected on a container without layout
+ \value PropertyEditorMessage Messages of the propert yeditor
+ \value SignalSlotEditorMessage Messages of the signal / slot editor
+ \value FormEditorMessage Messages of the form editor
+ \value PreviewFailureMessage A preview could not be created
+ \value PromotionErrorMessage Messages related to promotion of a widget
+ \value ResourceEditorMessage Messages of the resource editor
+ \value ScriptDialogMessage Messages of the script dialog
+ \value SignalSlotDialogMessage Messages of the signal slot dialog
+ \value OtherMessage Unspecified context
+*/
+
+/*!
+ Constructs a QDesignerDialogGuiInterface object.
+*/
+
+QDesignerDialogGuiInterface::QDesignerDialogGuiInterface()
+{
+}
+
+/*!
+ Destroys the QDesignerDialogGuiInterface object.
+*/
+QDesignerDialogGuiInterface::~QDesignerDialogGuiInterface()
+{
+}
+
+/*!
+ \fn QMessageBox::StandardButton QDesignerDialogGuiInterface::message(QWidget *parent, Message context, QMessageBox::Icon icon, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
+
+ Opens a message box as child of \a parent within the context \a context, using \a icon, \a title, \a text, \a buttons and \a defaultButton
+ and returns the button chosen by the user.
+*/
+
+/*!
+ \fn QString QDesignerDialogGuiInterface::getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
+
+ Opens a file dialog as child of \a parent using the parameters \a caption, \a dir and \a options that prompts the
+ user for an existing directory. Returns a directory selected by the user.
+*/
+
+/*!
+ \fn QString QDesignerDialogGuiInterface::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options)
+
+ Opens a file dialog as child of \a parent using the parameters \a caption, \a dir, \a filter, \a selectedFilter and \a options
+ that prompts the user for an existing file. Returns a file selected by the user.
+*/
+
+/*!
+ \fn QStringList QDesignerDialogGuiInterface::getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options)
+
+ Opens a file dialog as child of \a parent using the parameters \a caption, \a dir, \a filter, \a selectedFilter and \a options
+ that prompts the user for a set of existing files. Returns one or more existing files selected by the user.
+*/
+
+/*!
+ Opens a file dialog with image browsing capabilities as child of \a parent using the parameters \a caption, \a dir, \a filter, \a selectedFilter and \a options
+ that prompts the user for an existing file. Returns a file selected by the user.
+
+ The default implementation simply calls getOpenFileName(). On platforms that do not support an image preview in the QFileDialog,
+ the function can be reimplemented to provide an image browser.
+
+ \since 4.5
+*/
+
+QString QDesignerDialogGuiInterface::getOpenImageFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
+{
+ return getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
+}
+
+/*!
+ Opens a file dialog with image browsing capabilities as child of \a parent using the parameters \a caption, \a dir, \a filter, \a selectedFilter and \a options
+ that prompts the user for a set of existing files. Returns one or more existing files selected by the user.
+
+ The default implementation simply calls getOpenFileNames(). On platforms that do not support an image preview in the QFileDialog,
+ the function can be reimplemented to provide an image browser.
+
+ \since 4.5
+*/
+
+QStringList QDesignerDialogGuiInterface::getOpenImageFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
+{
+ return getOpenImageFileNames(parent, caption, dir, filter, selectedFilter, options);
+}
+
+/*!
+ \fn QString QDesignerDialogGuiInterface::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options)
+
+ Opens a file dialog as child of \a parent using the parameters \a caption, \a dir, \a filter, \a selectedFilter and \a options
+ that prompts the user for a file. Returns a file selected by the user. The file does not have to exist.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractdialoggui_p.h b/src/designer/src/lib/sdk/abstractdialoggui_p.h
new file mode 100644
index 000000000..af3843850
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractdialoggui_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ABSTRACTDIALOGGUI_H
+#define ABSTRACTDIALOGGUI_H
+
+#include <QtDesigner/sdk_global.h>
+#include <QtGui/QMessageBox>
+#include <QtGui/QFileDialog>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+
+class QDESIGNER_SDK_EXPORT QDesignerDialogGuiInterface
+{
+ Q_DISABLE_COPY(QDesignerDialogGuiInterface)
+public:
+ QDesignerDialogGuiInterface();
+ virtual ~QDesignerDialogGuiInterface();
+
+ enum Message { FormLoadFailureMessage, UiVersionMismatchMessage, ResourceLoadFailureMessage,
+ TopLevelSpacerMessage, PropertyEditorMessage, SignalSlotEditorMessage, FormEditorMessage,
+ PreviewFailureMessage, PromotionErrorMessage, ResourceEditorMessage,
+ ScriptDialogMessage, SignalSlotDialogMessage, OtherMessage, FileChangedMessage };
+
+ virtual QMessageBox::StandardButton
+ message(QWidget *parent, Message context, QMessageBox::Icon icon,
+ const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) = 0;
+
+ virtual QMessageBox::StandardButton
+ message(QWidget *parent, Message context, QMessageBox::Icon icon,
+ const QString &title, const QString &text, const QString &informativeText,
+ QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) = 0;
+
+ virtual QMessageBox::StandardButton
+ message(QWidget *parent, Message context, QMessageBox::Icon icon,
+ const QString &title, const QString &text, const QString &informativeText, const QString &detailedText,
+ QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) = 0;
+
+ virtual QString getExistingDirectory(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly)= 0;
+ virtual QString getOpenFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0)= 0;
+ virtual QString getOpenImageFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
+ virtual QStringList getOpenFileNames(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0)= 0;
+ virtual QStringList getOpenImageFileNames(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
+ virtual QString getSaveFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0)= 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTDIALOGGUI_H
diff --git a/src/designer/src/lib/sdk/abstractdnditem.h b/src/designer/src/lib/sdk/abstractdnditem.h
new file mode 100644
index 000000000..229938d75
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractdnditem.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTDNDITEM_H
+#define ABSTRACTDNDITEM_H
+
+#include <QtDesigner/sdk_global.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class DomUI;
+class QWidget;
+class QPoint;
+
+class QDESIGNER_SDK_EXPORT QDesignerDnDItemInterface
+{
+public:
+ enum DropType { MoveDrop, CopyDrop };
+
+ QDesignerDnDItemInterface() {}
+ virtual ~QDesignerDnDItemInterface() {}
+
+ virtual DomUI *domUi() const = 0;
+ virtual QWidget *widget() const = 0;
+ virtual QWidget *decoration() const = 0;
+ virtual QPoint hotSpot() const = 0;
+ virtual DropType type() const = 0;
+ virtual QWidget *source() const = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTDNDITEM_H
diff --git a/src/designer/src/lib/sdk/abstractdnditem.qdoc b/src/designer/src/lib/sdk/abstractdnditem.qdoc
new file mode 100644
index 000000000..958ee2865
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractdnditem.qdoc
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QDesignerDnDItemInterface
+ \brief The QDesignerDnDItemInterface class provides an interface that is used to manage items
+ during a drag and drop operation.
+ \inmodule QtDesigner
+ \internal
+*/
+
+/*!
+ \enum QDesignerDnDItemInterface::DropType
+
+ This enum describes the result of a drag and drop operation.
+
+ \value MoveDrop The item was moved.
+ \value CopyDrop The item was copied.
+*/
+
+/*!
+ \fn QDesignerDnDItemInterface::QDesignerDnDItemInterface()
+
+ Constructs a new interface to a drag and drop item.
+*/
+
+/*!
+ \fn QDesignerDnDItemInterface::~QDesignerDnDItemInterface()
+
+ Destroys the interface to the item.
+*/
+
+/*!
+ \fn DomUI *QDesignerDnDItemInterface::domUi() const
+
+ Returns a user interface object for the item.
+*/
+
+/*!
+ \fn QWidget *QDesignerDnDItemInterface::widget() const
+
+ Returns the widget being copied or moved in the drag and drop operation.
+
+ \sa source()
+*/
+
+/*!
+ \fn QWidget *QDesignerDnDItemInterface::decoration() const
+
+ Returns the widget used to represent the item.
+*/
+
+/*!
+ \fn QPoint QDesignerDnDItemInterface::hotSpot() const
+
+ Returns the cursor's hotspot.
+
+ \sa QDrag::hotSpot()
+*/
+
+/*!
+ \fn DropType QDesignerDnDItemInterface::type() const
+
+ Returns the type of drag and drop operation in progress.
+*/
+
+/*!
+ \fn QWidget *QDesignerDnDItemInterface::source() const
+
+ Returns the widget that is the source of the drag and drop operation; i.e. the original
+ container of the widget being dragged.
+
+ \sa widget()
+*/
diff --git a/src/designer/src/lib/sdk/abstractformeditor.cpp b/src/designer/src/lib/sdk/abstractformeditor.cpp
new file mode 100644
index 000000000..563781631
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformeditor.cpp
@@ -0,0 +1,630 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractformeditor.h"
+#include "abstractdialoggui_p.h"
+#include "abstractintrospection_p.h"
+#include "abstractsettings_p.h"
+#include "abstractoptionspage_p.h"
+
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtDesigner/QDesignerBrushManagerInterface>
+#include <QtDesigner/QDesignerIntegrationInterface>
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/QDesignerActionEditorInterface>
+#include <pluginmanager_p.h>
+#include <qtresourcemodel_p.h>
+#include <qtgradientmanager.h>
+#include <widgetfactory_p.h>
+#include <shared_settings_p.h>
+#include <formwindowbase_p.h>
+#include <grid_p.h>
+#include <QtDesigner/QDesignerPromotionInterface>
+
+// Must be done outside of the Qt namespace
+static void initResources()
+{
+ Q_INIT_RESOURCE(shared);
+ Q_INIT_RESOURCE(ClamshellPhone);
+ Q_INIT_RESOURCE(PortableMedia);
+ Q_INIT_RESOURCE(S60_nHD_Touchscreen);
+ Q_INIT_RESOURCE(S60_QVGA_Candybar);
+ Q_INIT_RESOURCE(SmartPhone2);
+ Q_INIT_RESOURCE(SmartPhone);
+ Q_INIT_RESOURCE(SmartPhoneWithButtons);
+ Q_INIT_RESOURCE(TouchscreenPhone);
+}
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterfacePrivate {
+public:
+ QDesignerFormEditorInterfacePrivate();
+ ~QDesignerFormEditorInterfacePrivate();
+
+
+ QPointer<QWidget> m_topLevel;
+ QPointer<QDesignerWidgetBoxInterface> m_widgetBox;
+ QPointer<QDesignerPropertyEditorInterface> m_propertyEditor;
+ QPointer<QDesignerFormWindowManagerInterface> m_formWindowManager;
+ QPointer<QExtensionManager> m_extensionManager;
+ QPointer<QDesignerMetaDataBaseInterface> m_metaDataBase;
+ QPointer<QDesignerWidgetDataBaseInterface> m_widgetDataBase;
+ QPointer<QDesignerWidgetFactoryInterface> m_widgetFactory;
+ QPointer<QDesignerObjectInspectorInterface> m_objectInspector;
+ QPointer<QDesignerBrushManagerInterface> m_brushManager;
+ QPointer<QDesignerIntegrationInterface> m_integration;
+ QPointer<QDesignerIconCacheInterface> m_iconCache;
+ QPointer<QDesignerActionEditorInterface> m_actionEditor;
+ QDesignerSettingsInterface *m_settingsManager;
+ QDesignerPluginManager *m_pluginManager;
+ QDesignerPromotionInterface *m_promotion;
+ QDesignerIntrospectionInterface *m_introspection;
+ QDesignerDialogGuiInterface *m_dialogGui;
+ QPointer<QtResourceModel> m_resourceModel;
+ QPointer<QtGradientManager> m_gradientManager; // instantiated and deleted by designer_integration
+ QList<QDesignerOptionsPageInterface*> m_optionsPages;
+};
+
+QDesignerFormEditorInterfacePrivate::QDesignerFormEditorInterfacePrivate() :
+ m_settingsManager(0),
+ m_pluginManager(0),
+ m_promotion(0),
+ m_introspection(0),
+ m_dialogGui(0),
+ m_resourceModel(0),
+ m_gradientManager(0)
+{
+}
+
+QDesignerFormEditorInterfacePrivate::~QDesignerFormEditorInterfacePrivate()
+{
+ delete m_settingsManager;
+ delete m_formWindowManager;
+ delete m_promotion;
+ delete m_introspection;
+ delete m_dialogGui;
+ delete m_resourceModel;
+ qDeleteAll(m_optionsPages);
+}
+
+/*!
+ \class QDesignerFormEditorInterface
+
+ \brief The QDesignerFormEditorInterface class allows you to access
+ Qt Designer's various components.
+
+ \inmodule QtDesigner
+
+ \QD's current QDesignerFormEditorInterface object holds
+ information about all \QD's components: The action editor, the
+ object inspector, the property editor, the widget box, and the
+ extension and form window managers. QDesignerFormEditorInterface
+ contains a collection of functions that provides interfaces to all
+ these components. They are typically used to query (and
+ manipulate) the respective component. For example:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformeditor.cpp 0
+
+ QDesignerFormEditorInterface is not intended to be instantiated
+ directly. A pointer to \QD's current QDesignerFormEditorInterface
+ object (\c formEditor in the example above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's
+ parameter. When implementing a custom widget plugin, you must
+ subclass the QDesignerCustomWidgetInterface to expose your plugin
+ to \QD.
+
+ QDesignerFormEditorInterface also provides functions that can set
+ the action editor, property editor, object inspector and widget
+ box. These are only useful if you want to provide your own custom
+ components.
+
+ If designer is embedded in another program, one could to provide its
+ own settings manager. The manager is used by the components of \QD
+ to store/retrieve persistent configuration settings. The default
+ manager uses QSettings as the backend.
+
+ Finally, QDesignerFormEditorInterface provides the topLevel()
+ function that returns \QD's top-level widget.
+
+ \sa QDesignerCustomWidgetInterface
+*/
+
+/*!
+ Constructs a QDesignerFormEditorInterface object with the given \a
+ parent.
+*/
+
+QDesignerFormEditorInterface::QDesignerFormEditorInterface(QObject *parent)
+ : QObject(parent),
+ d(new QDesignerFormEditorInterfacePrivate())
+{
+ initResources();
+}
+
+/*!
+ Destroys the QDesignerFormEditorInterface object.
+*/
+QDesignerFormEditorInterface::~QDesignerFormEditorInterface()
+{
+ delete d;
+}
+
+/*!
+ Returns an interface to \QD's widget box.
+
+ \sa setWidgetBox()
+*/
+QDesignerWidgetBoxInterface *QDesignerFormEditorInterface::widgetBox() const
+{
+ return d->m_widgetBox;
+}
+
+/*!
+ Sets \QD's widget box to be the specified \a widgetBox.
+
+ \sa widgetBox()
+*/
+void QDesignerFormEditorInterface::setWidgetBox(QDesignerWidgetBoxInterface *widgetBox)
+{
+ d->m_widgetBox = widgetBox;
+}
+
+/*!
+ Returns an interface to \QD's property editor.
+
+ \sa setPropertyEditor()
+*/
+QDesignerPropertyEditorInterface *QDesignerFormEditorInterface::propertyEditor() const
+{
+ return d->m_propertyEditor;
+}
+
+/*!
+ Sets \QD's property editor to be the specified \a propertyEditor.
+
+ \sa propertyEditor()
+*/
+void QDesignerFormEditorInterface::setPropertyEditor(QDesignerPropertyEditorInterface *propertyEditor)
+{
+ d->m_propertyEditor = propertyEditor;
+}
+
+/*!
+ Returns an interface to \QD's action editor.
+
+ \sa setActionEditor()
+*/
+QDesignerActionEditorInterface *QDesignerFormEditorInterface::actionEditor() const
+{
+ return d->m_actionEditor;
+}
+
+/*!
+ Sets \QD's action editor to be the specified \a actionEditor.
+
+ \sa actionEditor()
+*/
+void QDesignerFormEditorInterface::setActionEditor(QDesignerActionEditorInterface *actionEditor)
+{
+ d->m_actionEditor = actionEditor;
+}
+
+/*!
+ Returns \QD's top-level widget.
+*/
+QWidget *QDesignerFormEditorInterface::topLevel() const
+{
+ return d->m_topLevel;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setTopLevel(QWidget *topLevel)
+{
+ d->m_topLevel = topLevel;
+}
+
+/*!
+ Returns an interface to \QD's form window manager.
+*/
+QDesignerFormWindowManagerInterface *QDesignerFormEditorInterface::formWindowManager() const
+{
+ return d->m_formWindowManager;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setFormManager(QDesignerFormWindowManagerInterface *formWindowManager)
+{
+ d->m_formWindowManager = formWindowManager;
+}
+
+/*!
+ Returns an interface to \QD's extension manager.
+*/
+QExtensionManager *QDesignerFormEditorInterface::extensionManager() const
+{
+ return d->m_extensionManager;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setExtensionManager(QExtensionManager *extensionManager)
+{
+ d->m_extensionManager = extensionManager;
+}
+
+/*!
+ \internal
+
+ Returns an interface to the meta database used by the form editor.
+*/
+QDesignerMetaDataBaseInterface *QDesignerFormEditorInterface::metaDataBase() const
+{
+ return d->m_metaDataBase;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setMetaDataBase(QDesignerMetaDataBaseInterface *metaDataBase)
+{
+ d->m_metaDataBase = metaDataBase;
+}
+
+/*!
+ \internal
+
+ Returns an interface to the widget database used by the form editor.
+*/
+QDesignerWidgetDataBaseInterface *QDesignerFormEditorInterface::widgetDataBase() const
+{
+ return d->m_widgetDataBase;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setWidgetDataBase(QDesignerWidgetDataBaseInterface *widgetDataBase)
+{
+ d->m_widgetDataBase = widgetDataBase;
+}
+
+/*!
+ \internal
+
+ Returns an interface to the designer promotion handler.
+*/
+
+QDesignerPromotionInterface *QDesignerFormEditorInterface::promotion() const
+{
+ return d->m_promotion;
+}
+
+/*!
+ \internal
+
+ Sets the designer promotion handler.
+*/
+
+void QDesignerFormEditorInterface::setPromotion(QDesignerPromotionInterface *promotion)
+{
+ if (d->m_promotion)
+ delete d->m_promotion;
+ d->m_promotion = promotion;
+}
+
+/*!
+ \internal
+
+ Returns an interface to the widget factory used by the form editor
+ to create widgets for the form.
+*/
+QDesignerWidgetFactoryInterface *QDesignerFormEditorInterface::widgetFactory() const
+{
+ return d->m_widgetFactory;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setWidgetFactory(QDesignerWidgetFactoryInterface *widgetFactory)
+{
+ d->m_widgetFactory = widgetFactory;
+}
+
+/*!
+ Returns an interface to \QD's object inspector.
+*/
+QDesignerObjectInspectorInterface *QDesignerFormEditorInterface::objectInspector() const
+{
+ return d->m_objectInspector;
+}
+
+/*!
+ Sets \QD's object inspector to be the specified \a
+ objectInspector.
+
+ \sa objectInspector()
+*/
+void QDesignerFormEditorInterface::setObjectInspector(QDesignerObjectInspectorInterface *objectInspector)
+{
+ d->m_objectInspector = objectInspector;
+}
+
+/*!
+ \internal
+
+ Returns an interface to the brush manager used by the palette editor.
+*/
+QDesignerBrushManagerInterface *QDesignerFormEditorInterface::brushManager() const
+{
+ return d->m_brushManager;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setBrushManager(QDesignerBrushManagerInterface *brushManager)
+{
+ d->m_brushManager = brushManager;
+}
+
+/*!
+ \internal
+
+ Returns an interface to the integration.
+*/
+QDesignerIntegrationInterface *QDesignerFormEditorInterface::integration() const
+{
+ return d->m_integration;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setIntegration(QDesignerIntegrationInterface *integration)
+{
+ d->m_integration = integration;
+}
+
+/*!
+ \internal
+
+ Returns an interface to the icon cache used by the form editor to
+ manage icons.
+*/
+QDesignerIconCacheInterface *QDesignerFormEditorInterface::iconCache() const
+{
+ return d->m_iconCache;
+}
+
+/*!
+ \internal
+*/
+void QDesignerFormEditorInterface::setIconCache(QDesignerIconCacheInterface *cache)
+{
+ d->m_iconCache = cache;
+}
+
+/*!
+ \internal
+ \since 4.5
+ Returns the list of options pages that allow the user to configure \QD components.
+*/
+QList<QDesignerOptionsPageInterface*> QDesignerFormEditorInterface::optionsPages() const
+{
+ return d->m_optionsPages;
+}
+
+/*!
+ \internal
+ \since 4.5
+ Sets the list of options pages that allow the user to configure \QD components.
+*/
+void QDesignerFormEditorInterface::setOptionsPages(const QList<QDesignerOptionsPageInterface*> &optionsPages)
+{
+ d->m_optionsPages = optionsPages;
+}
+
+
+/*!
+ \internal
+
+ Returns the plugin manager used by the form editor.
+*/
+QDesignerPluginManager *QDesignerFormEditorInterface::pluginManager() const
+{
+ return d->m_pluginManager;
+}
+
+/*!
+ \internal
+
+ Sets the plugin manager used by the form editor to the specified
+ \a pluginManager.
+*/
+void QDesignerFormEditorInterface::setPluginManager(QDesignerPluginManager *pluginManager)
+{
+ d->m_pluginManager = pluginManager;
+}
+
+/*!
+ \internal
+ \since 4.4
+ Returns the resource model used by the form editor.
+*/
+QtResourceModel *QDesignerFormEditorInterface::resourceModel() const
+{
+ return d->m_resourceModel;
+}
+
+/*!
+ \internal
+
+ Sets the resource model used by the form editor to the specified
+ \a resourceModel.
+*/
+void QDesignerFormEditorInterface::setResourceModel(QtResourceModel *resourceModel)
+{
+ d->m_resourceModel = resourceModel;
+}
+
+/*!
+ \internal
+ \since 4.4
+ Returns the gradient manager used by the style sheet editor.
+*/
+QtGradientManager *QDesignerFormEditorInterface::gradientManager() const
+{
+ return d->m_gradientManager;
+}
+
+/*!
+ \internal
+
+ Sets the gradient manager used by the style sheet editor to the specified
+ \a gradientManager.
+*/
+void QDesignerFormEditorInterface::setGradientManager(QtGradientManager *gradientManager)
+{
+ d->m_gradientManager = gradientManager;
+}
+
+/*!
+ \internal
+ \since 4.5
+ Returns the settings manager used by the components to store persistent settings.
+*/
+QDesignerSettingsInterface *QDesignerFormEditorInterface::settingsManager() const
+{
+ return d->m_settingsManager;
+}
+
+/*!
+ \internal
+ \since 4.5
+ Sets the settings manager used to store/retrieve the persistent settings of the components.
+*/
+void QDesignerFormEditorInterface::setSettingsManager(QDesignerSettingsInterface *settingsManager)
+{
+ if (d->m_settingsManager)
+ delete d->m_settingsManager;
+ d->m_settingsManager = settingsManager;
+
+ // This is a (hopefully) safe place to perform settings-dependent
+ // initializations.
+ const qdesigner_internal::QDesignerSharedSettings settings(this);
+ qdesigner_internal::FormWindowBase::setDefaultDesignerGrid(settings.defaultGrid());
+}
+
+/*!
+ \internal
+ \since 4.4
+ Returns the introspection used by the form editor.
+*/
+QDesignerIntrospectionInterface *QDesignerFormEditorInterface::introspection() const
+{
+ return d->m_introspection;
+}
+
+/*!
+ \internal
+ \since 4.4
+
+ Sets the introspection used by the form editor to the specified \a introspection.
+*/
+void QDesignerFormEditorInterface::setIntrospection(QDesignerIntrospectionInterface *introspection)
+{
+ if (d->m_introspection)
+ delete d->m_introspection;
+ d->m_introspection = introspection;
+}
+
+/*!
+ \internal
+
+ Returns the path to the resources used by the form editor.
+*/
+QString QDesignerFormEditorInterface::resourceLocation() const
+{
+#ifdef Q_WS_MAC
+ return QLatin1String(":/trolltech/formeditor/images/mac");
+#else
+ return QLatin1String(":/trolltech/formeditor/images/win");
+#endif
+}
+
+/*!
+ \internal
+
+ Returns the dialog GUI used by the form editor.
+*/
+
+QDesignerDialogGuiInterface *QDesignerFormEditorInterface::dialogGui() const
+{
+ return d->m_dialogGui;
+}
+
+/*!
+ \internal
+
+ Sets the dialog GUI used by the form editor to the specified \a dialogGui.
+*/
+
+void QDesignerFormEditorInterface::setDialogGui(QDesignerDialogGuiInterface *dialogGui)
+{
+ delete d->m_dialogGui;
+ d->m_dialogGui = dialogGui;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractformeditor.h b/src/designer/src/lib/sdk/abstractformeditor.h
new file mode 100644
index 000000000..fd83ee55d
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformeditor.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTFORMEDITOR_H
+#define ABSTRACTFORMEDITOR_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerWidgetBoxInterface;
+class QDesignerPropertyEditorInterface;
+class QDesignerFormWindowManagerInterface;
+class QDesignerWidgetDataBaseInterface;
+class QDesignerMetaDataBaseInterface;
+class QDesignerWidgetFactoryInterface;
+class QDesignerObjectInspectorInterface;
+class QDesignerPromotionInterface;
+class QDesignerBrushManagerInterface;
+class QDesignerIconCacheInterface;
+class QDesignerActionEditorInterface;
+class QDesignerIntegrationInterface;
+class QDesignerPluginManager;
+class QDesignerIntrospectionInterface;
+class QDesignerDialogGuiInterface;
+class QDesignerSettingsInterface;
+class QDesignerOptionsPageInterface;
+class QtResourceModel;
+class QtGradientManager;
+
+class QWidget;
+
+class QExtensionManager;
+
+class QDesignerFormEditorInterfacePrivate;
+
+class QDESIGNER_SDK_EXPORT QDesignerFormEditorInterface : public QObject
+{
+ Q_OBJECT
+public:
+ QDesignerFormEditorInterface(QObject *parent = 0);
+ virtual ~QDesignerFormEditorInterface();
+
+ QExtensionManager *extensionManager() const;
+
+ QWidget *topLevel() const;
+ QDesignerWidgetBoxInterface *widgetBox() const;
+ QDesignerPropertyEditorInterface *propertyEditor() const;
+ QDesignerObjectInspectorInterface *objectInspector() const;
+ QDesignerFormWindowManagerInterface *formWindowManager() const;
+ QDesignerWidgetDataBaseInterface *widgetDataBase() const;
+ QDesignerMetaDataBaseInterface *metaDataBase() const;
+ QDesignerPromotionInterface *promotion() const;
+ QDesignerWidgetFactoryInterface *widgetFactory() const;
+ QDesignerBrushManagerInterface *brushManager() const;
+ QDesignerIconCacheInterface *iconCache() const;
+ QDesignerActionEditorInterface *actionEditor() const;
+ QDesignerIntegrationInterface *integration() const;
+ QDesignerPluginManager *pluginManager() const;
+ QDesignerIntrospectionInterface *introspection() const;
+ QDesignerDialogGuiInterface *dialogGui() const;
+ QDesignerSettingsInterface *settingsManager() const;
+ QString resourceLocation() const;
+ QtResourceModel *resourceModel() const;
+ QtGradientManager *gradientManager() const;
+ QList<QDesignerOptionsPageInterface*> optionsPages() const;
+
+ void setTopLevel(QWidget *topLevel);
+ void setWidgetBox(QDesignerWidgetBoxInterface *widgetBox);
+ void setPropertyEditor(QDesignerPropertyEditorInterface *propertyEditor);
+ void setObjectInspector(QDesignerObjectInspectorInterface *objectInspector);
+ void setPluginManager(QDesignerPluginManager *pluginManager);
+ void setActionEditor(QDesignerActionEditorInterface *actionEditor);
+ void setIntegration(QDesignerIntegrationInterface *integration);
+ void setIntrospection(QDesignerIntrospectionInterface *introspection);
+ void setDialogGui(QDesignerDialogGuiInterface *dialogGui);
+ void setSettingsManager(QDesignerSettingsInterface *settingsManager);
+ void setResourceModel(QtResourceModel *model);
+ void setGradientManager(QtGradientManager *manager);
+ void setOptionsPages(const QList<QDesignerOptionsPageInterface*> &optionsPages);
+
+protected:
+ void setFormManager(QDesignerFormWindowManagerInterface *formWindowManager);
+ void setMetaDataBase(QDesignerMetaDataBaseInterface *metaDataBase);
+ void setWidgetDataBase(QDesignerWidgetDataBaseInterface *widgetDataBase);
+ void setPromotion(QDesignerPromotionInterface *promotion);
+ void setWidgetFactory(QDesignerWidgetFactoryInterface *widgetFactory);
+ void setExtensionManager(QExtensionManager *extensionManager);
+ void setBrushManager(QDesignerBrushManagerInterface *brushManager);
+ void setIconCache(QDesignerIconCacheInterface *cache);
+
+private:
+ QPointer<QWidget> m_pad1;
+ QPointer<QDesignerWidgetBoxInterface> m_pad2;
+ QPointer<QDesignerPropertyEditorInterface> m_pad3;
+ QPointer<QDesignerFormWindowManagerInterface> m_pad4;
+ QPointer<QExtensionManager> m_pad5;
+ QPointer<QDesignerMetaDataBaseInterface> m_pad6;
+ QPointer<QDesignerWidgetDataBaseInterface> m_pad7;
+ QPointer<QDesignerWidgetFactoryInterface> m_pad8;
+ QPointer<QDesignerObjectInspectorInterface> m_pad9;
+ QPointer<QDesignerBrushManagerInterface> m_pad10;
+ QPointer<QDesignerIconCacheInterface> m_pad11;
+ QPointer<QDesignerActionEditorInterface> m_pad12;
+ QDesignerFormEditorInterfacePrivate *d;
+
+private:
+ QDesignerFormEditorInterface(const QDesignerFormEditorInterface &other);
+ void operator = (const QDesignerFormEditorInterface &other);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTFORMEDITOR_H
diff --git a/src/designer/src/lib/sdk/abstractformeditorplugin.cpp b/src/designer/src/lib/sdk/abstractformeditorplugin.cpp
new file mode 100644
index 000000000..cb7fd8ee9
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformeditorplugin.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner/abstractformeditorplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QDesignerFormEditorPluginInterface
+ \brief The QDesignerFormEditorPluginInterface class provides an interface that is used to
+ manage plugins for Qt Designer's form editor component.
+ \inmodule QtDesigner
+
+ \sa QDesignerFormEditorInterface
+*/
+
+/*!
+ \fn virtual QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface()
+
+ Destroys the plugin interface.
+*/
+
+/*!
+ \fn virtual bool QDesignerFormEditorPluginInterface::isInitialized() const = 0
+
+ Returns true if the plugin interface is initialized; otherwise returns false.
+*/
+
+/*!
+ \fn virtual void QDesignerFormEditorPluginInterface::initialize(QDesignerFormEditorInterface *core) = 0
+
+ Initializes the plugin interface for the specified \a core interface.
+*/
+
+/*!
+ \fn virtual QAction *QDesignerFormEditorPluginInterface::action() const = 0
+
+ Returns the action associated with this interface.
+*/
+
+/*!
+ \fn virtual QDesignerFormEditorInterface *QDesignerFormEditorPluginInterface::core() const = 0
+
+ Returns the core form editor interface associated with this component.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractformeditorplugin.h b/src/designer/src/lib/sdk/abstractformeditorplugin.h
new file mode 100644
index 000000000..a9e01e81a
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformeditorplugin.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTFORMEDITORPLUGIN_H
+#define ABSTRACTFORMEDITORPLUGIN_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QAction;
+
+class QDESIGNER_SDK_EXPORT QDesignerFormEditorPluginInterface
+{
+public:
+ virtual ~QDesignerFormEditorPluginInterface() {}
+
+ virtual bool isInitialized() const = 0;
+ virtual void initialize(QDesignerFormEditorInterface *core) = 0;
+ virtual QAction *action() const = 0;
+
+ virtual QDesignerFormEditorInterface *core() const = 0;
+};
+Q_DECLARE_INTERFACE(QDesignerFormEditorPluginInterface, "com.trolltech.Qt.Designer.QDesignerFormEditorPluginInterface")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTFORMEDITORPLUGIN_H
diff --git a/src/designer/src/lib/sdk/abstractformwindow.cpp b/src/designer/src/lib/sdk/abstractformwindow.cpp
new file mode 100644
index 000000000..7ea450627
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformwindow.cpp
@@ -0,0 +1,814 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractformwindow.h"
+
+#include <widgetfactory_p.h>
+
+#include <QtGui/QTabBar>
+#include <QtGui/QSizeGrip>
+#include <QtGui/QAbstractButton>
+#include <QtGui/QToolBox>
+#include <QtGui/QMenuBar>
+#include <QtGui/QMainWindow>
+#include <QtGui/QDockWidget>
+#include <QtGui/QToolBar>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerFormWindowInterface
+
+ \brief The QDesignerFormWindowInterface class allows you to query
+ and manipulate form windows appearing in Qt Designer's workspace.
+
+ \inmodule QtDesigner
+
+ QDesignerFormWindowInterface provides information about
+ the associated form window as well as allowing its properties to be
+ altered. The interface is not intended to be instantiated
+ directly, but to provide access to \QD's current form windows
+ controlled by \QD's \l {QDesignerFormWindowManagerInterface}{form
+ window manager}.
+
+ If you are looking for the form window containing a specific
+ widget, you can use the static
+ QDesignerFormWindowInterface::findFormWindow() function:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.cpp 0
+
+ But in addition, you can access any of the current form windows
+ through \QD's form window manager: Use the
+ QDesignerFormEditorInterface::formWindowManager() function to
+ retrieve an interface to the manager. Once you have this
+ interface, you have access to all of \QD's current form windows
+ through the QDesignerFormWindowManagerInterface::formWindow()
+ function. For example:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.cpp 1
+
+ The pointer to \QD's current QDesignerFormEditorInterface object
+ (\c formEditor in the example above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's
+ parameter. When implementing a custom widget plugin, you must
+ subclass the QDesignerCustomWidgetInterface class to expose your
+ plugin to \QD.
+
+ Once you have the form window, you can query its properties. For
+ example, a plain custom widget plugin is managed by \QD only at
+ its top level, i.e. none of its child widgets can be resized in
+ \QD's workspace. But QDesignerFormWindowInterface provides you
+ with functions that enables you to control whether a widget should
+ be managed by \QD, or not:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.cpp 2
+
+ The complete list of functions concerning widget management is:
+ isManaged(), manageWidget() and unmanageWidget(). There is also
+ several associated signals: widgetManaged(), widgetRemoved(),
+ aboutToUnmanageWidget() and widgetUnmanaged().
+
+ In addition to controlling the management of widgets, you can
+ control the current selection in the form window using the
+ selectWidget(), clearSelection() and emitSelectionChanged()
+ functions, and the selectionChanged() signal.
+
+ You can also retrieve information about where the form is stored
+ using absoluteDir(), its include files using includeHints(), and
+ its layout and pixmap functions using layoutDefault(),
+ layoutFunction() and pixmapFunction(). You can find out whether
+ the form window has been modified (but not saved) or not, using
+ the isDirty() function. You can retrieve its author(), its
+ contents(), its fileName(), associated comment() and
+ exportMacro(), its mainContainer(), its features(), its grid() and
+ its resourceFiles().
+
+ The interface provides you with functions and slots allowing you
+ to alter most of this information as well. The exception is the
+ directory storing the form window. Finally, there is several
+ signals associated with changes to the information mentioned above
+ and to the form window in general.
+
+ \sa QDesignerFormWindowCursorInterface,
+ QDesignerFormEditorInterface, QDesignerFormWindowManagerInterface
+*/
+
+/*!
+ \enum QDesignerFormWindowInterface::FeatureFlag
+
+ This enum describes the features that are available and can be
+ controlled by the form window interface. These values are used
+ when querying the form window to determine which features it
+ supports:
+
+ \value EditFeature Form editing
+ \value GridFeature Grid display and snap-to-grid facilities for editing
+ \value TabOrderFeature Tab order management
+ \value DefaultFeature Support for default features (form editing and grid)
+
+ \sa hasFeature(), features()
+*/
+
+/*!
+ Constructs a form window interface with the given \a parent and
+ the specified window \a flags.
+*/
+QDesignerFormWindowInterface::QDesignerFormWindowInterface(QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(parent, flags)
+{
+}
+
+/*!
+ Destroys the form window interface.
+*/
+QDesignerFormWindowInterface::~QDesignerFormWindowInterface()
+{
+}
+
+/*!
+ Returns a pointer to \QD's current QDesignerFormEditorInterface
+ object.
+*/
+QDesignerFormEditorInterface *QDesignerFormWindowInterface::core() const
+{
+ return 0;
+}
+
+/*!
+ \fn QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QWidget *widget)
+
+ Returns the form window interface for the given \a widget.
+*/
+
+static inline bool stopFindAtTopLevel(const QObject *w, bool stopAtMenu)
+{
+ // Do we need to go beyond top levels when looking for the form window?
+ // 1) A dialog has a window attribute at the moment it is created
+ // before it is properly embedded into a form window. The property
+ // sheet queries the layout attributes precisely at this moment.
+ // 2) In the case of floating docks and toolbars, we also need to go beyond the top level window.
+ // 3) In the case of menu editing, we don't want to block events from the
+ // Designer menu, so, we say stop.
+ // Note that there must be no false positives for dialogs parented on
+ // the form (for example, the "change object name" dialog), else, its
+ // events will be blocked.
+
+ if (stopAtMenu && w->inherits("QDesignerMenu"))
+ return true;
+ return !qdesigner_internal::WidgetFactory::isFormEditorObject(w);
+}
+
+QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QWidget *w)
+{
+ while (w != 0) {
+ if (QDesignerFormWindowInterface *fw = qobject_cast<QDesignerFormWindowInterface*>(w)) {
+ return fw;
+ } else {
+ if (w->isWindow() && stopFindAtTopLevel(w, true))
+ break;
+ }
+
+ w = w->parentWidget();
+ }
+
+ return 0;
+}
+
+/*!
+ \fn QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObject *object)
+
+ Returns the form window interface for the given \a object.
+
+ \since 4.4
+*/
+
+QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObject *object)
+{
+ while (object != 0) {
+ if (QDesignerFormWindowInterface *fw = qobject_cast<QDesignerFormWindowInterface*>(object)) {
+ return fw;
+ } else {
+ QWidget *w = qobject_cast<QWidget *>(object);
+ // QDesignerMenu is a window, so stopFindAtTopLevel(w) returns 0.
+ // However, we want to find the form window for QActions of a menu.
+ // If this check is inside stopFindAtTopLevel(w), it will break designer
+ // menu editing (e.g. when clicking on items inside an opened menu)
+ if (w && w->isWindow() && stopFindAtTopLevel(w, false))
+ break;
+
+ }
+
+ object = object->parent();
+ }
+
+ return 0;
+}
+
+/*!
+ \fn virtual QString QDesignerFormWindowInterface::fileName() const
+
+ Returns the file name of the UI file that describes the form
+ currently being shown.
+
+ \sa setFileName()
+*/
+
+/*!
+ \fn virtual QDir QDesignerFormWindowInterface::absoluteDir() const
+
+ Returns the absolute location of the directory containing the form
+ shown in the form window.
+*/
+
+/*!
+ \fn virtual QString QDesignerFormWindowInterface::contents() const
+
+ Returns details of the contents of the form currently being
+ displayed in the window.
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setContents(QIODevice *device)
+
+ Sets the form's contents using data obtained from the given \a device.
+
+ Data can be read from QFile objects or any other subclass of QIODevice.
+*/
+
+/*!
+ \fn virtual Feature QDesignerFormWindowInterface::features() const
+
+ Returns a combination of the features provided by the form window
+ associated with the interface. The value returned can be tested
+ against the \l Feature enum values to determine which features are
+ supported by the window.
+
+ \sa setFeatures(), hasFeature()
+*/
+
+/*!
+ \fn virtual bool QDesignerFormWindowInterface::hasFeature(Feature feature) const
+
+ Returns true if the form window offers the specified \a feature;
+ otherwise returns false.
+
+ \sa features()
+*/
+
+/*!
+ \fn virtual QString QDesignerFormWindowInterface::author() const
+
+ Returns details of the author or creator of the form currently
+ being displayed in the window.
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setAuthor(const QString &author)
+
+ Sets the details for the author or creator of the form to the \a
+ author specified.
+*/
+
+/*!
+ \fn virtual QString QDesignerFormWindowInterface::comment() const
+
+ Returns comments about the form currently being displayed in the window.
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setComment(const QString &comment)
+
+ Sets the information about the form to the \a comment
+ specified. This information should be a human-readable comment
+ about the form.
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::layoutDefault(int *margin, int *spacing)
+
+ Fills in the default margin and spacing for the form's default
+ layout in the \a margin and \a spacing variables specified.
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setLayoutDefault(int margin, int spacing)
+
+ Sets the default \a margin and \a spacing for the form's layout.
+
+ \sa layoutDefault()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::layoutFunction(QString *margin, QString *spacing)
+
+ Fills in the current margin and spacing for the form's layout in
+ the \a margin and \a spacing variables specified.
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setLayoutFunction(const QString &margin, const QString &spacing)
+
+ Sets the \a margin and \a spacing for the form's layout.
+
+ The default layout properties will be replaced by the
+ corresponding layout functions when \c uic generates code for the
+ form, that is, if the functions are specified. This is useful when
+ different environments requires different layouts for the same
+ form.
+
+ \sa layoutFunction()
+*/
+
+/*!
+ \fn virtual QString QDesignerFormWindowInterface::pixmapFunction() const
+
+ Returns the name of the function used to load pixmaps into the
+ form window.
+
+ \sa setPixmapFunction()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setPixmapFunction(const QString &pixmapFunction)
+
+ Sets the function used to load pixmaps into the form window
+ to the given \a pixmapFunction.
+
+ \sa pixmapFunction()
+*/
+
+/*!
+ \fn virtual QString QDesignerFormWindowInterface::exportMacro() const
+
+ Returns the export macro associated with the form currently being
+ displayed in the window. The export macro is used when the form
+ is compiled to create a widget plugin.
+
+ \sa {Creating Custom Widgets for Qt Designer}
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setExportMacro(const QString &exportMacro)
+
+ Sets the form window's export macro to \a exportMacro. The export
+ macro is used when building a widget plugin to export the form's
+ interface to other components.
+*/
+
+/*!
+ \fn virtual QStringList QDesignerFormWindowInterface::includeHints() const
+
+ Returns a list of the header files that will be included in the
+ form window's associated UI file.
+
+ Header files may be local, i.e. relative to the project's
+ directory, \c "mywidget.h", or global, i.e. part of Qt or the
+ compilers standard libraries: \c <QtGui/QWidget>.
+
+ \sa setIncludeHints()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setIncludeHints(const QStringList &includeHints)
+
+ Sets the header files that will be included in the form window's
+ associated UI file to the specified \a includeHints.
+
+ Header files may be local, i.e. relative to the project's
+ directory, \c "mywidget.h", or global, i.e. part of Qt or the
+ compilers standard libraries: \c <QtGui/QWidget>.
+
+ \sa includeHints()
+*/
+
+/*!
+ \fn virtual QDesignerFormWindowCursorInterface *QDesignerFormWindowInterface::cursor() const
+
+ Returns the cursor interface used by the form window.
+*/
+
+/*!
+ \fn virtual int QDesignerFormWindowInterface::toolCount() const
+
+ Returns the number of tools available.
+
+ \internal
+*/
+
+/*!
+ \fn virtual int QDesignerFormWindowInterface::currentTool() const
+
+ Returns the index of the current tool in use.
+
+ \sa setCurrentTool()
+
+ \internal
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setCurrentTool(int index)
+
+ Sets the current tool to be the one with the given \a index.
+
+ \sa currentTool()
+
+ \internal
+*/
+
+/*!
+ \fn virtual QDesignerFormWindowToolInterface *QDesignerFormWindowInterface::tool(int index) const
+
+ Returns an interface to the tool with the given \a index.
+
+ \internal
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::registerTool(QDesignerFormWindowToolInterface *tool)
+
+ Registers the given \a tool with the form window.
+
+ \internal
+*/
+
+/*!
+ \fn virtual QPoint QDesignerFormWindowInterface::grid() const = 0
+
+ Returns the grid spacing used by the form window.
+
+ \sa setGrid()
+*/
+
+/*!
+ \fn virtual QWidget *QDesignerFormWindowInterface::mainContainer() const
+
+ Returns the main container widget for the form window.
+
+ \sa setMainContainer()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setMainContainer(QWidget *mainContainer)
+
+ Sets the main container widget on the form to the specified \a
+ mainContainer.
+
+ \sa mainContainer(), mainContainerChanged()
+*/
+
+/*!
+ \fn virtual bool QDesignerFormWindowInterface::isManaged(QWidget *widget) const
+
+ Returns true if the specified \a widget is managed by the form
+ window; otherwise returns false.
+
+ \sa manageWidget()
+*/
+
+/*!
+ \fn virtual bool QDesignerFormWindowInterface::isDirty() const
+
+ Returns true if the form window is "dirty" (modified but not
+ saved); otherwise returns false.
+
+ \sa setDirty()
+*/
+
+/*!
+ \fn virtual QUndoStack *QDesignerFormWindowInterface::commandHistory() const
+
+ Returns an object that can be used to obtain the commands used so
+ far in the construction of the form.
+
+ \internal
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::beginCommand(const QString &description)
+
+ Begins execution of a command with the given \a
+ description. Commands are executed between beginCommand() and
+ endCommand() function calls to ensure that they are recorded on
+ the undo stack.
+
+ \sa endCommand()
+
+ \internal
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::endCommand()
+
+ Ends execution of the current command.
+
+ \sa beginCommand()
+
+ \internal
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::simplifySelection(QList<QWidget*> *widgets) const
+
+ Simplifies the selection of widgets specified by \a widgets.
+
+ \sa selectionChanged()
+ \internal
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::emitSelectionChanged()
+
+ Emits the selectionChanged() signal.
+
+ \sa selectWidget(), clearSelection()
+*/
+
+/*!
+ \fn virtual QStringList QDesignerFormWindowInterface::resourceFiles() const
+
+ Returns a list of paths to resource files that are currently being
+ used by the form window.
+
+ \sa addResourceFile(), removeResourceFile()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::addResourceFile(const QString &path)
+
+ Adds the resource file at the given \a path to those used by the form.
+
+ \sa resourceFiles(), resourceFilesChanged()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::removeResourceFile(const QString &path)
+
+ Removes the resource file at the specified \a path from the list
+ of those used by the form.
+
+ \sa resourceFiles(), resourceFilesChanged()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::ensureUniqueObjectName(QObject *object)
+
+ Ensures that the specified \a object has a unique name amongst the
+ other objects on the form.
+
+ \internal
+*/
+
+// Slots
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::manageWidget(QWidget *widget)
+
+ Instructs the form window to manage the specified \a widget.
+
+ \sa isManaged(), unmanageWidget(), widgetManaged()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::unmanageWidget(QWidget *widget)
+
+ Instructs the form window not to manage the specified \a widget.
+
+ \sa aboutToUnmanageWidget(), widgetUnmanaged()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setFeatures(Feature features)
+
+ Enables the specified \a features for the form window.
+
+ \sa features(), featureChanged()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setDirty(bool dirty)
+
+ If \a dirty is true, the form window is marked as dirty, meaning
+ that it is modified but not saved. If \a dirty is false, the form
+ window is considered to be unmodified.
+
+ \sa isDirty()
+*/
+
+/*!
+\fn virtual void QDesignerFormWindowInterface::clearSelection(bool update)
+
+ Clears the current selection in the form window. If \a update is
+ true, the emitSelectionChanged() function is called, emitting the
+ selectionChanged() signal.
+
+ \sa selectWidget()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::selectWidget(QWidget *widget, bool select)
+
+ If \a select is true, the given \a widget is selected; otherwise
+ the \a widget is deselected.
+
+ \sa clearSelection(), selectionChanged()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setGrid(const QPoint &grid)
+
+ Sets the grid size for the form window to the point specified by
+ \a grid. In this function, the coordinates in the QPoint are used
+ to specify the dimensions of a rectangle in the grid.
+
+ \sa grid()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setFileName(const QString &fileName)
+
+ Sets the file name for the form to the given \a fileName.
+
+ \sa fileName(), fileNameChanged()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::setContents(const QString &contents)
+
+ Sets the contents of the form using data read from the specified
+ \a contents string.
+
+ \sa contents()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowInterface::editWidgets()
+
+ Switches the form window into editing mode.
+
+ \sa \l {Qt Designer's Form Editing Mode}
+
+ \internal
+*/
+
+// Signals
+
+/*!
+ \fn void QDesignerFormWindowInterface::mainContainerChanged(QWidget *mainContainer)
+
+ This signal is emitted whenever the main container changes.
+ The new container is specified by \a mainContainer.
+
+ \sa setMainContainer()
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::toolChanged(int toolIndex)
+
+ This signal is emitted whenever the current tool changes.
+ The specified \a toolIndex is the index of the new tool in the list of
+ tools in the widget box.
+
+ \internal
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::fileNameChanged(const QString &fileName)
+
+ This signal is emitted whenever the file name of the form changes.
+ The new file name is specified by \a fileName.
+
+ \sa setFileName()
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::featureChanged(Feature feature)
+
+ This signal is emitted whenever a feature changes in the form.
+ The new feature is specified by \a feature.
+
+ \sa setFeatures()
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::selectionChanged()
+
+ This signal is emitted whenever the selection in the form changes.
+
+ \sa selectWidget(), clearSelection()
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::geometryChanged()
+
+ This signal is emitted whenever the form's geometry changes.
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::resourceFilesChanged()
+
+ This signal is emitted whenever the list of resource files used by the
+ form changes.
+
+ \sa resourceFiles()
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::widgetManaged(QWidget *widget)
+
+ This signal is emitted whenever a widget on the form becomes managed.
+ The newly managed widget is specified by \a widget.
+
+ \sa manageWidget()
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::widgetUnmanaged(QWidget *widget)
+
+ This signal is emitted whenever a widget on the form becomes unmanaged.
+ The newly released widget is specified by \a widget.
+
+ \sa unmanageWidget(), aboutToUnmanageWidget()
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::aboutToUnmanageWidget(QWidget *widget)
+
+ This signal is emitted whenever a widget on the form is about to
+ become unmanaged. When this signal is emitted, the specified \a
+ widget is still managed, and a widgetUnmanaged() signal will
+ follow, indicating when it is no longer managed.
+
+ \sa unmanageWidget(), isManaged()
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::activated(QWidget *widget)
+
+ This signal is emitted whenever a widget is activated on the form.
+ The activated widget is specified by \a widget.
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::changed()
+
+ This signal is emitted whenever a form is changed.
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::widgetRemoved(QWidget *widget)
+
+ This signal is emitted whenever a widget is removed from the form.
+ The widget that was removed is specified by \a widget.
+*/
+
+/*!
+ \fn void QDesignerFormWindowInterface::objectRemoved(QObject *object)
+
+ This signal is emitted whenever an object (such as
+ an action or a QButtonGroup) is removed from the form.
+ The object that was removed is specified by \a object.
+
+ \since 4.5
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractformwindow.h b/src/designer/src/lib/sdk/abstractformwindow.h
new file mode 100644
index 000000000..36ce4a54c
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformwindow.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTFORMWINDOW_H
+#define ABSTRACTFORMWINDOW_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowCursorInterface;
+class QDesignerFormWindowToolInterface;
+class DomUI;
+class QUndoStack;
+class QDir;
+
+class QDESIGNER_SDK_EXPORT QDesignerFormWindowInterface: public QWidget
+{
+ Q_OBJECT
+public:
+ enum FeatureFlag
+ {
+ EditFeature = 0x01,
+ GridFeature = 0x02,
+ TabOrderFeature = 0x04,
+ DefaultFeature = EditFeature | GridFeature
+ };
+ Q_DECLARE_FLAGS(Feature, FeatureFlag)
+
+public:
+ QDesignerFormWindowInterface(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ virtual ~QDesignerFormWindowInterface();
+
+ virtual QString fileName() const = 0;
+ virtual QDir absoluteDir() const = 0;
+
+ virtual QString contents() const = 0;
+ virtual void setContents(QIODevice *dev) = 0;
+
+ virtual Feature features() const = 0;
+ virtual bool hasFeature(Feature f) const = 0;
+
+ virtual QString author() const = 0;
+ virtual void setAuthor(const QString &author) = 0;
+
+ virtual QString comment() const = 0;
+ virtual void setComment(const QString &comment) = 0;
+
+ virtual void layoutDefault(int *margin, int *spacing) = 0;
+ virtual void setLayoutDefault(int margin, int spacing) = 0;
+
+ virtual void layoutFunction(QString *margin, QString *spacing) = 0;
+ virtual void setLayoutFunction(const QString &margin, const QString &spacing) = 0;
+
+ virtual QString pixmapFunction() const = 0;
+ virtual void setPixmapFunction(const QString &pixmapFunction) = 0;
+
+ virtual QString exportMacro() const = 0;
+ virtual void setExportMacro(const QString &exportMacro) = 0;
+
+ virtual QStringList includeHints() const = 0;
+ virtual void setIncludeHints(const QStringList &includeHints) = 0;
+
+ virtual QDesignerFormEditorInterface *core() const;
+ virtual QDesignerFormWindowCursorInterface *cursor() const = 0;
+
+ virtual int toolCount() const = 0;
+
+ virtual int currentTool() const = 0;
+ virtual void setCurrentTool(int index) = 0;
+
+ virtual QDesignerFormWindowToolInterface *tool(int index) const = 0;
+ virtual void registerTool(QDesignerFormWindowToolInterface *tool) = 0;
+
+ virtual QPoint grid() const = 0;
+
+ virtual QWidget *mainContainer() const = 0;
+ virtual void setMainContainer(QWidget *mainContainer) = 0;
+
+ virtual bool isManaged(QWidget *widget) const = 0;
+
+ virtual bool isDirty() const = 0;
+
+ static QDesignerFormWindowInterface *findFormWindow(QWidget *w);
+ static QDesignerFormWindowInterface *findFormWindow(QObject *obj);
+
+ virtual QUndoStack *commandHistory() const = 0;
+ virtual void beginCommand(const QString &description) = 0;
+ virtual void endCommand() = 0;
+
+ virtual void simplifySelection(QList<QWidget*> *widgets) const = 0;
+
+ // notifications
+ virtual void emitSelectionChanged() = 0;
+
+ virtual QStringList resourceFiles() const = 0;
+ virtual void addResourceFile(const QString &path) = 0;
+ virtual void removeResourceFile(const QString &path) = 0;
+
+ virtual void ensureUniqueObjectName(QObject *object) = 0;
+
+public Q_SLOTS:
+ virtual void manageWidget(QWidget *widget) = 0;
+ virtual void unmanageWidget(QWidget *widget) = 0;
+
+ virtual void setFeatures(Feature f) = 0;
+ virtual void setDirty(bool dirty) = 0;
+ virtual void clearSelection(bool changePropertyDisplay = true) = 0;
+ virtual void selectWidget(QWidget *w, bool select = true) = 0;
+ virtual void setGrid(const QPoint &grid) = 0;
+ virtual void setFileName(const QString &fileName) = 0;
+ virtual void setContents(const QString &contents) = 0;
+
+ virtual void editWidgets() = 0;
+
+Q_SIGNALS:
+ void mainContainerChanged(QWidget *mainContainer);
+ void toolChanged(int toolIndex);
+ void fileNameChanged(const QString &fileName);
+ void featureChanged(Feature f);
+ void selectionChanged();
+ void geometryChanged();
+
+ void resourceFilesChanged();
+
+ void widgetManaged(QWidget *widget);
+ void widgetUnmanaged(QWidget *widget);
+ void aboutToUnmanageWidget(QWidget *widget);
+ void activated(QWidget *widget);
+
+ void changed();
+ void widgetRemoved(QWidget *w);
+ void objectRemoved(QObject *o);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTFORMWINDOW_H
diff --git a/src/designer/src/lib/sdk/abstractformwindowcursor.cpp b/src/designer/src/lib/sdk/abstractformwindowcursor.cpp
new file mode 100644
index 000000000..c2611931e
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformwindowcursor.cpp
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractformwindowcursor.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerFormWindowCursorInterface
+
+ \brief The QDesignerFormWindowCursorInterface class allows you to
+ query and modify a form window's widget selection, and in addition
+ modify the properties of all the form's widgets.
+
+ \inmodule QtDesigner
+
+ QDesignerFormWindowCursorInterface is a convenience class that
+ provides an interface to the associated form window's text cursor;
+ it provides a collection of functions that enables you to query a
+ given form window's selection and change the selection's focus
+ according to defined modes (MoveMode) and movements
+ (MoveOperation). You can also use the interface to query the
+ form's widgets and change their properties.
+
+ The interface is not intended to be instantiated directly, but to
+ provide access to the selections and widgets of \QD's current form
+ windows. QDesignerFormWindowInterface always provides an
+ associated cursor interface. The form window for a given widget
+ can be retrieved using the static
+ QDesignerFormWindowInterface::findFormWindow() functions. For
+ example:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowcursor.cpp 0
+
+ You can retrieve any of \QD's current form windows through
+ \QD's \l {QDesignerFormWindowManagerInterface}{form window
+ manager}.
+
+ Once you have a form window's cursor interface, you can check if
+ the form window has a selection at all using the hasSelection()
+ function. You can query the form window for its total
+ widgetCount() and selectedWidgetCount(). You can retrieve the
+ currently selected widget (or widgets) using the current() or
+ selectedWidget() functions.
+
+ You can retrieve any of the form window's widgets using the
+ widget() function, and check if a widget is selected using the
+ isWidgetSelected() function. You can use the setProperty()
+ function to set the selected widget's properties, and the
+ setWidgetProperty() or resetWidgetProperty() functions to modify
+ the properties of any given widget.
+
+ Finally, you can change the selection by changing the text
+ cursor's position() using the setPosition() and movePosition()
+ functions.
+
+ \sa QDesignerFormWindowInterface, QDesignerFormWindowManagerInterface
+*/
+
+/*!
+ \enum QDesignerFormWindowCursorInterface::MoveOperation
+
+ This enum describes the types of text cursor operation that can occur in a form window.
+
+ \value NoMove The cursor does not move.
+ \value Start Moves the cursor to the start of the focus chain.
+ \value End Moves the cursor to the end of the focus chain.
+ \value Next Moves the cursor to the next widget in the focus chain.
+ \value Prev Moves the cursor to the previous widget in the focus chain.
+ \value Left The cursor moves to the left.
+ \value Right The cursor moves to the right.
+ \value Up The cursor moves upwards.
+ \value Down The cursor moves downwards.
+*/
+
+/*!
+ \enum QDesignerFormWindowCursorInterface::MoveMode
+
+ This enum describes the different modes that are used when the text cursor moves.
+
+ \value MoveAnchor The anchor moves with the cursor to its new location.
+ \value KeepAnchor The anchor remains at the cursor's old location.
+*/
+
+/*!
+ Returns true if the specified \a widget is selected; otherwise
+ returns false.
+*/
+bool QDesignerFormWindowCursorInterface::isWidgetSelected(QWidget *widget) const
+{
+ for (int index=0; index<selectedWidgetCount(); ++index) {
+ if (selectedWidget(index) == widget)
+ return true;
+ }
+
+ return false;
+}
+
+/*!
+ \fn virtual QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface()
+
+ Destroys the cursor interface.
+*/
+
+/*!
+ \fn virtual QDesignerFormWindowInterface *QDesignerFormWindowCursorInterface::formWindow() const
+
+ Returns the form window interface associated with this cursor interface.
+*/
+
+/*!
+ \fn virtual bool QDesignerFormWindowCursorInterface::movePosition(MoveOperation operation, MoveMode mode)
+
+ Performs the given \a operation on the cursor using the specified
+ \a mode, and returns true if it completed successfully; otherwise
+ returns false.
+
+ \sa position(), setPosition()
+*/
+
+/*!
+ \fn virtual int QDesignerFormWindowCursorInterface::position() const
+
+ Returns the cursor position.
+
+ \sa setPosition(), movePosition()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowCursorInterface::setPosition(int position, MoveMode mode = MoveAnchor)
+
+ Sets the position of the cursor to the given \a position using the
+ \a mode to specify how it is moved there.
+
+ \sa position(), movePosition()
+*/
+
+/*!
+ \fn virtual QWidget *QDesignerFormWindowCursorInterface::current() const
+
+ Returns the currently selected widget in the form window.
+
+ \sa selectedWidget()
+*/
+
+/*!
+ \fn virtual int QDesignerFormWindowCursorInterface::widgetCount() const
+
+ Returns the number of widgets in the form window.
+
+ \sa selectedWidgetCount()
+*/
+
+/*!
+ \fn virtual QWidget *QDesignerFormWindowCursorInterface::widget(int index) const
+
+ Returns the widget with the given \a index in the list of widgets
+ in the form window.
+
+ \sa selectedWidget()
+*/
+
+/*!
+ \fn virtual bool QDesignerFormWindowCursorInterface::hasSelection() const
+
+ Returns true if the form window contains a selection; otherwise
+ returns false.
+*/
+
+/*!
+ \fn virtual int QDesignerFormWindowCursorInterface::selectedWidgetCount() const
+
+ Returns the number of selected widgets in the form window.
+
+ \sa widgetCount()
+*/
+
+/*!
+ \fn virtual QWidget *QDesignerFormWindowCursorInterface::selectedWidget(int index) const
+
+ Returns the widget with the given \a index in the list of selected
+ widgets.
+
+ \sa current(), widget()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowCursorInterface::setProperty(const QString &name, const QVariant &value)
+
+ Sets the property with the given \a name for the currently
+ selected widget to the specified \a value.
+
+ \sa setWidgetProperty(), resetWidgetProperty()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowCursorInterface::setWidgetProperty(QWidget *widget, const QString &name, const QVariant &value)
+
+ Sets the property with the given \a name for the given \a widget
+ to the specified \a value.
+
+ \sa resetWidgetProperty(), setProperty()
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowCursorInterface::resetWidgetProperty(QWidget *widget, const QString &name)
+
+ Resets the property with the given \a name for the specified \a
+ widget to its default value.
+
+ \sa setProperty(), setWidgetProperty()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractformwindowcursor.h b/src/designer/src/lib/sdk/abstractformwindowcursor.h
new file mode 100644
index 000000000..7653450cc
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformwindowcursor.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTFORMWINDOWCURSOR_H
+#define ABSTRACTFORMWINDOWCURSOR_H
+
+#include <QtDesigner/sdk_global.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QWidget;
+class QVariant;
+class QString;
+
+class QDESIGNER_SDK_EXPORT QDesignerFormWindowCursorInterface
+{
+public:
+ enum MoveOperation
+ {
+ NoMove,
+
+ Start,
+ End,
+ Next,
+ Prev,
+ Left,
+ Right,
+ Up,
+ Down
+ };
+
+ enum MoveMode
+ {
+ MoveAnchor,
+ KeepAnchor
+ };
+
+public:
+ virtual ~QDesignerFormWindowCursorInterface() {}
+
+ virtual QDesignerFormWindowInterface *formWindow() const = 0;
+
+ virtual bool movePosition(MoveOperation op, MoveMode mode = MoveAnchor) = 0;
+
+ virtual int position() const = 0;
+ virtual void setPosition(int pos, MoveMode mode = MoveAnchor) = 0;
+
+ virtual QWidget *current() const = 0;
+
+ virtual int widgetCount() const = 0;
+ virtual QWidget *widget(int index) const = 0;
+
+ virtual bool hasSelection() const = 0;
+ virtual int selectedWidgetCount() const = 0;
+ virtual QWidget *selectedWidget(int index) const = 0;
+
+ virtual void setProperty(const QString &name, const QVariant &value) = 0;
+ virtual void setWidgetProperty(QWidget *widget, const QString &name, const QVariant &value) = 0;
+ virtual void resetWidgetProperty(QWidget *widget, const QString &name) = 0;
+
+ bool isWidgetSelected(QWidget *widget) const;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTFORMWINDOWCURSOR_H
diff --git a/src/designer/src/lib/sdk/abstractformwindowmanager.cpp b/src/designer/src/lib/sdk/abstractformwindowmanager.cpp
new file mode 100644
index 000000000..75c1d4a11
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformwindowmanager.cpp
@@ -0,0 +1,502 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractformwindowmanager.h"
+
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerFormWindowManagerInterface
+
+ \brief The QDesignerFormWindowManagerInterface class allows you to
+ manipulate the collection of form windows in Qt Designer, and
+ control Qt Designer's form editing actions.
+
+ \inmodule QtDesigner
+
+ QDesignerFormWindowManagerInterface is not intended to be
+ instantiated directly. \QD uses the form window manager to
+ control the various form windows in its workspace. You can
+ retrieve an interface to \QD's form window manager using
+ the QDesignerFormEditorInterface::formWindowManager()
+ function. For example:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowmanager.cpp 0
+
+ When implementing a custom widget plugin, a pointer to \QD's
+ current QDesignerFormEditorInterface object (\c formEditor in the
+ example above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's parameter.
+ You must subclass the QDesignerCustomWidgetInterface to expose
+ your plugin to Qt Designer.
+
+ The form window manager interface provides the createFormWindow()
+ function that enables you to create a new form window which you
+ can add to the collection of form windows that the manager
+ maintains, using the addFormWindow() slot. It also provides the
+ formWindowCount() function returning the number of form windows
+ currently under the manager's control, the formWindow() function
+ returning the form window associated with a given index, and the
+ activeFormWindow() function returning the currently selected form
+ window. The removeFormWindow() slot allows you to reduce the
+ number of form windows the manager must maintain, and the
+ setActiveFormWindow() slot allows you to change the form window
+ focus in \QD's workspace.
+
+ In addition, QDesignerFormWindowManagerInterface contains a
+ collection of functions that enables you to intervene and control
+ \QD's form editing actions. All these functions return the
+ original action, making it possible to propagate the function
+ further after intervention.
+
+ Finally, the interface provides three signals which are emitted
+ when a form window is added, when the currently selected form
+ window changes, or when a form window is removed, respectively. All
+ the signals carry the form window in question as their parameter.
+
+ \sa QDesignerFormEditorInterface, QDesignerFormWindowInterface
+*/
+
+// ------------- QDesignerFormWindowManagerInterfacePrivate
+
+struct QDesignerFormWindowManagerInterfacePrivate {
+ QDesignerFormWindowManagerInterfacePrivate();
+ QAction *m_simplifyLayoutAction;
+ QAction *m_formLayoutAction;
+};
+
+QDesignerFormWindowManagerInterfacePrivate::QDesignerFormWindowManagerInterfacePrivate() :
+ m_simplifyLayoutAction(0),
+ m_formLayoutAction(0)
+{
+}
+
+typedef QMap<const QDesignerFormWindowManagerInterface *, QDesignerFormWindowManagerInterfacePrivate *> FormWindowManagerPrivateMap;
+
+Q_GLOBAL_STATIC(FormWindowManagerPrivateMap, g_FormWindowManagerPrivateMap)
+
+/*!
+ Constructs an interface with the given \a parent for the form window
+ manager.
+*/
+QDesignerFormWindowManagerInterface::QDesignerFormWindowManagerInterface(QObject *parent)
+ : QObject(parent)
+{
+ g_FormWindowManagerPrivateMap()->insert(this, new QDesignerFormWindowManagerInterfacePrivate);
+}
+
+/*!
+ Destroys the interface for the form window manager.
+*/
+QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface()
+{
+ FormWindowManagerPrivateMap *fwmpm = g_FormWindowManagerPrivateMap();
+ const FormWindowManagerPrivateMap::iterator it = fwmpm->find(this);
+ Q_ASSERT(it != fwmpm->end());
+ delete it.value();
+ fwmpm->erase(it);
+}
+
+/*!
+ Allows you to intervene and control \QD's "cut" action. The function
+ returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionCut() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "copy" action. The
+ function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionCopy() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "paste" action. The
+ function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionPaste() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "delete" action. The function
+ returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionDelete() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "select all" action. The
+ function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionSelectAll() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control the action of lowering a form
+ window in \QD's workspace. The function returns the original
+ action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionLower() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control the action of raising of a
+ form window in \QD's workspace. The function returns the original
+ action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionRaise() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control a request for horizontal
+ layout for a form window in \QD's workspace. The function returns
+ the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionHorizontalLayout() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control a request for vertical layout
+ for a form window in \QD's workspace. The function returns the
+ original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionVerticalLayout() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "split horizontal"
+ action. The function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionSplitHorizontal() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "split vertical"
+ action. The function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionSplitVertical() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control a request for grid layout for
+ a form window in \QD's workspace. The function returns the
+ original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionGridLayout() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "form layout" action. The
+ function returns the original action.
+
+FormWindowManagerPrivateMap *fwmpm = g_FormWindowManagerPrivateMap(); \sa QAction
+ \since 4.4
+*/
+
+QAction *QDesignerFormWindowManagerInterface::actionFormLayout() const
+{
+ const QDesignerFormWindowManagerInterfacePrivate *d = g_FormWindowManagerPrivateMap()->value(this);
+ Q_ASSERT(d);
+ return d->m_formLayoutAction;
+}
+
+/*!
+ Sets the "form layout" action to \a action.
+
+ \internal
+ \since 4.4
+*/
+
+void QDesignerFormWindowManagerInterface::setActionFormLayout(QAction *action)
+{
+ QDesignerFormWindowManagerInterfacePrivate *d = g_FormWindowManagerPrivateMap()->value(this);
+ Q_ASSERT(d);
+ d->m_formLayoutAction = action;
+}
+
+/*!
+ Allows you to intervene and control \QD's "break layout" action. The
+ function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionBreakLayout() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "adjust size" action. The
+ function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionAdjustSize() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "simplify layout" action. The
+ function returns the original action.
+
+ \sa QAction
+ \since 4.4
+*/
+
+QAction *QDesignerFormWindowManagerInterface::actionSimplifyLayout() const
+{
+ const QDesignerFormWindowManagerInterfacePrivate *d = g_FormWindowManagerPrivateMap()->value(this);
+ Q_ASSERT(d);
+ return d->m_simplifyLayoutAction;
+}
+
+/*!
+ Sets the "simplify layout" action to \a action.
+
+ \internal
+ \since 4.4
+*/
+
+void QDesignerFormWindowManagerInterface::setActionSimplifyLayout(QAction *action)
+{
+ QDesignerFormWindowManagerInterfacePrivate *d = g_FormWindowManagerPrivateMap()->value(this);
+ Q_ASSERT(d);
+ d->m_simplifyLayoutAction = action;
+}
+
+/*!
+ Returns the currently active form window in \QD's workspace.
+
+ \sa setActiveFormWindow(), removeFormWindow()
+*/
+QDesignerFormWindowInterface *QDesignerFormWindowManagerInterface::activeFormWindow() const
+{
+ return 0;
+}
+
+/*!
+ Returns a pointer to \QD's current QDesignerFormEditorInterface
+ object.
+*/
+QDesignerFormEditorInterface *QDesignerFormWindowManagerInterface::core() const
+{
+ return 0;
+}
+
+/*!
+ Adds the given \a formWindow to the collection of windows that
+ \QD's form window manager maintains.
+
+ \sa formWindowAdded()
+*/
+void QDesignerFormWindowManagerInterface::addFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_UNUSED(formWindow);
+}
+
+/*!
+ Removes the given \a formWindow from the collection of windows that
+ \QD's form window manager maintains.
+
+ \sa formWindow(), formWindowRemoved()
+*/
+void QDesignerFormWindowManagerInterface::removeFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_UNUSED(formWindow);
+}
+
+/*!
+ Sets the given \a formWindow to be the currently active form window in
+ \QD's workspace.
+
+ \sa activeFormWindow(), activeFormWindowChanged()
+*/
+void QDesignerFormWindowManagerInterface::setActiveFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_UNUSED(formWindow);
+}
+
+/*!
+ Returns the number of form windows maintained by \QD's form window
+ manager.
+*/
+int QDesignerFormWindowManagerInterface::formWindowCount() const
+{
+ return 0;
+}
+
+/*!
+ Returns the form window at the given \a index.
+
+ \sa setActiveFormWindow(), removeFormWindow()
+*/
+QDesignerFormWindowInterface *QDesignerFormWindowManagerInterface::formWindow(int index) const
+{
+ Q_UNUSED(index);
+ return 0;
+}
+
+/*!
+ \fn QDesignerFormWindowInterface *QDesignerFormWindowManagerInterface::createFormWindow(QWidget *parent, Qt::WindowFlags flags)
+
+ Creates a form window with the given \a parent and the given window
+ \a flags.
+
+ \sa addFormWindow()
+*/
+QDesignerFormWindowInterface *QDesignerFormWindowManagerInterface::createFormWindow(QWidget *parentWidget, Qt::WindowFlags flags)
+{
+ Q_UNUSED(parentWidget);
+ Q_UNUSED(flags);
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "undo" action. The
+ function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionUndo() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's "redo" action. The
+ function returns the original action.
+
+ \sa QAction
+*/
+QAction *QDesignerFormWindowManagerInterface::actionRedo() const
+{
+ return 0;
+}
+
+/*!
+ \fn void QDesignerFormWindowManagerInterface::formWindowAdded(QDesignerFormWindowInterface *formWindow)
+
+ This signal is emitted when a new form window is added to the
+ collection of windows that \QD's form window manager maintains. A
+ pointer to the new \a formWindow is passed as an argument.
+
+ \sa addFormWindow(), setActiveFormWindow()
+*/
+
+/*!
+ \fn void QDesignerFormWindowManagerInterface::formWindowRemoved(QDesignerFormWindowInterface *formWindow)
+
+ This signal is emitted when a form window is removed from the
+ collection of windows that \QD's form window manager maintains. A
+ pointer to the removed \a formWindow is passed as an argument.
+
+ \sa removeFormWindow()
+*/
+
+/*!
+ \fn void QDesignerFormWindowManagerInterface::activeFormWindowChanged(QDesignerFormWindowInterface *formWindow)
+
+ This signal is emitted when the contents of the currently active
+ form window in \QD's workspace changed. A pointer to the currently
+ active \a formWindow is passed as an argument.
+
+ \sa activeFormWindow()
+*/
+
+/*!
+ \fn void QDesignerFormWindowManagerInterface::dragItems(const QList<QDesignerDnDItemInterface*> &item_list)
+
+ \internal
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractformwindowmanager.h b/src/designer/src/lib/sdk/abstractformwindowmanager.h
new file mode 100644
index 000000000..bdd7c99aa
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformwindowmanager.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTFORMWINDOWMANAGER_H
+#define ABSTRACTFORMWINDOWMANAGER_H
+
+#include <QtDesigner/sdk_global.h>
+#include <QtDesigner/abstractformwindow.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QActionGroup;
+class QDesignerFormEditorInterface;
+class DomUI;
+class QWidget;
+class QDesignerDnDItemInterface;
+
+class QDESIGNER_SDK_EXPORT QDesignerFormWindowManagerInterface: public QObject
+{
+ Q_OBJECT
+public:
+ QDesignerFormWindowManagerInterface(QObject *parent = 0);
+ virtual ~QDesignerFormWindowManagerInterface();
+
+ virtual QAction *actionCut() const;
+ virtual QAction *actionCopy() const;
+ virtual QAction *actionPaste() const;
+ virtual QAction *actionDelete() const;
+ virtual QAction *actionSelectAll() const;
+ virtual QAction *actionLower() const;
+ virtual QAction *actionRaise() const;
+ virtual QAction *actionUndo() const;
+ virtual QAction *actionRedo() const;
+
+ virtual QAction *actionHorizontalLayout() const;
+ virtual QAction *actionVerticalLayout() const;
+ virtual QAction *actionSplitHorizontal() const;
+ virtual QAction *actionSplitVertical() const;
+ virtual QAction *actionGridLayout() const;
+ QAction *actionFormLayout() const;
+ virtual QAction *actionBreakLayout() const;
+ virtual QAction *actionAdjustSize() const;
+ QAction *actionSimplifyLayout() const;
+
+ virtual QDesignerFormWindowInterface *activeFormWindow() const;
+
+ virtual int formWindowCount() const;
+ virtual QDesignerFormWindowInterface *formWindow(int index) const;
+
+ virtual QDesignerFormWindowInterface *createFormWindow(QWidget *parentWidget = 0, Qt::WindowFlags flags = 0);
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual void dragItems(const QList<QDesignerDnDItemInterface*> &item_list) = 0;
+
+Q_SIGNALS:
+ void formWindowAdded(QDesignerFormWindowInterface *formWindow);
+ void formWindowRemoved(QDesignerFormWindowInterface *formWindow);
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+
+public Q_SLOTS:
+ virtual void addFormWindow(QDesignerFormWindowInterface *formWindow);
+ virtual void removeFormWindow(QDesignerFormWindowInterface *formWindow);
+ virtual void setActiveFormWindow(QDesignerFormWindowInterface *formWindow);
+
+protected:
+ void setActionFormLayout(QAction *action);
+ void setActionSimplifyLayout(QAction *action);
+
+private:
+ QDesignerFormWindowManagerInterface(const QDesignerFormWindowManagerInterface &other);
+ QDesignerFormWindowManagerInterface &operator = (const QDesignerFormWindowManagerInterface &other);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTFORMWINDOWMANAGER_H
diff --git a/src/designer/src/lib/sdk/abstractformwindowtool.cpp b/src/designer/src/lib/sdk/abstractformwindowtool.cpp
new file mode 100644
index 000000000..b073b22ea
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformwindowtool.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractformwindowtool.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerFormWindowToolInterface
+
+ \brief The QDesignerFormWindowToolInterface class provides an
+ interface that enables tools to be used on items in a form window.
+
+ \inmodule QtDesigner
+
+ \internal
+*/
+
+/*!
+*/
+QDesignerFormWindowToolInterface::QDesignerFormWindowToolInterface(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+*/
+QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface()
+{
+}
+
+/*!
+ \fn virtual QDesignerFormEditorInterface *QDesignerFormWindowToolInterface::core() const = 0
+*/
+
+/*!
+ \fn virtual QDesignerFormWindowInterface *QDesignerFormWindowToolInterface::formWindow() const = 0
+*/
+
+/*!
+ \fn virtual QWidget *QDesignerFormWindowToolInterface::editor() const = 0
+*/
+
+/*!
+ \fn virtual QAction *QDesignerFormWindowToolInterface::action() const = 0
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowToolInterface::activated() = 0
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowToolInterface::deactivated() = 0
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowToolInterface::saveToDom(DomUI*, QWidget*) {
+*/
+
+/*!
+ \fn virtual void QDesignerFormWindowToolInterface::loadFromDom(DomUI*, QWidget*) {
+*/
+
+/*!
+ \fn virtual bool QDesignerFormWindowToolInterface::handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event) = 0
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractformwindowtool.h b/src/designer/src/lib/sdk/abstractformwindowtool.h
new file mode 100644
index 000000000..77c499420
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractformwindowtool.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTFORMWINDOWTOOL_H
+#define ABSTRACTFORMWINDOWTOOL_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QWidget;
+class QAction;
+class DomUI;
+
+class QDESIGNER_SDK_EXPORT QDesignerFormWindowToolInterface: public QObject
+{
+ Q_OBJECT
+public:
+ QDesignerFormWindowToolInterface(QObject *parent = 0);
+ virtual ~QDesignerFormWindowToolInterface();
+
+ virtual QDesignerFormEditorInterface *core() const = 0;
+ virtual QDesignerFormWindowInterface *formWindow() const = 0;
+ virtual QWidget *editor() const = 0;
+
+ virtual QAction *action() const = 0;
+
+ virtual void activated() = 0;
+ virtual void deactivated() = 0;
+
+ virtual void saveToDom(DomUI*, QWidget*) {}
+ virtual void loadFromDom(DomUI*, QWidget*) {}
+
+ virtual bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTFORMWINDOWTOOL_H
diff --git a/src/designer/src/lib/sdk/abstracticoncache.h b/src/designer/src/lib/sdk/abstracticoncache.h
new file mode 100644
index 000000000..ce2ed9d83
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstracticoncache.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTICONCACHE_H
+#define ABSTRACTICONCACHE_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QIcon;
+class QPixmap;
+class QString;
+
+class QDESIGNER_SDK_EXPORT QDesignerIconCacheInterface : public QObject
+{
+ Q_OBJECT
+public:
+ QDesignerIconCacheInterface(QObject *parent_)
+ : QObject(parent_) {}
+
+ virtual QIcon nameToIcon(const QString &filePath, const QString &qrcPath = QString()) = 0;
+ virtual QPixmap nameToPixmap(const QString &filePath, const QString &qrcPath = QString()) = 0;
+
+ virtual QString iconToFilePath(const QIcon &pm) const = 0;
+ virtual QString iconToQrcPath(const QIcon &pm) const = 0;
+
+ virtual QString pixmapToFilePath(const QPixmap &pm) const = 0;
+ virtual QString pixmapToQrcPath(const QPixmap &pm) const = 0;
+
+ virtual QList<QPixmap> pixmapList() const = 0;
+ virtual QList<QIcon> iconList() const = 0;
+
+ virtual QString resolveQrcPath(const QString &filePath, const QString &qrcPath, const QString &workingDirectory = QString()) const = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTICONCACHE_H
diff --git a/src/designer/src/lib/sdk/abstracticoncache.qdoc b/src/designer/src/lib/sdk/abstracticoncache.qdoc
new file mode 100644
index 000000000..f211c533c
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstracticoncache.qdoc
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QDesignerIconCacheInterface
+ \brief The QDesignerIconCacheInterface class provides an interface to \QD's icon cache.
+ \inmodule QtDesigner
+ \internal
+*/
+
+/*!
+ \fn QDesignerIconCacheInterface::QDesignerIconCacheInterface(QObject *parent)
+
+ Constructs a new interface with the given \a parent.
+*/
+
+/*!
+ \fn QIcon QDesignerIconCacheInterface::nameToIcon(const QString &filePath, const QString &qrcPath)
+
+ Returns the icon associated with the name specified by \a filePath in the resource
+ file specified by \a qrcPath.
+
+ If \a qrcPath refers to a valid resource file, the name used for the file path is a path
+ within those resources; otherwise the file path refers to a local file.
+
+ \sa {The Qt Resource System}, nameToPixmap()
+*/
+
+/*!
+ \fn QPixmap QDesignerIconCacheInterface::nameToPixmap(const QString &filePath, const QString &qrcPath)
+
+ Returns the pixmap associated with the name specified by \a filePath in the resource
+ file specified by \a qrcPath.
+
+ If \a qrcPath refers to a valid resource file, the name used for the file path is a path
+ within those resources; otherwise the file path refers to a local file.
+
+ \sa {The Qt Resource System}, nameToIcon()
+*/
+
+/*!
+ \fn QString QDesignerIconCacheInterface::iconToFilePath(const QIcon &icon) const
+
+ Returns the file path associated with the given \a icon. The file path is a path within
+ an application resources.
+*/
+
+/*!
+ \fn QString QDesignerIconCacheInterface::iconToQrcPath(const QIcon &icon) const
+
+ Returns the path to the resource file that refers to the specified \a icon. The resource
+ path refers to a local file.
+*/
+
+/*!
+ \fn QString QDesignerIconCacheInterface::pixmapToFilePath(const QPixmap &pixmap) const
+
+ Returns the file path associated with the given \a pixmap. The file path is a path within
+ an application resources.
+*/
+
+/*!
+ \fn QString QDesignerIconCacheInterface::pixmapToQrcPath(const QPixmap &pixmap) const
+
+ Returns the path to the resource file that refers to the specified \a pixmap. The resource
+ path refers to a local file.
+*/
+
+/*!
+ \fn QList<QPixmap> QDesignerIconCacheInterface::pixmapList() const
+
+ Returns a list of pixmaps for the icons provided by the icon cache.
+*/
+
+/*!
+ \fn QList<QIcon> QDesignerIconCacheInterface::iconList() const
+
+ Returns a list of icons provided by the icon cache.
+*/
+
+/*!
+ \fn QString QDesignerIconCacheInterface::resolveQrcPath(const QString &filePath, const QString &qrcPath, const QString &workingDirectory) const
+
+ Returns a path to a resource specified by the \a filePath within
+ the resource file located at \a qrcPath. If \a workingDirectory is
+ a valid path to a directory, the path returned will be relative to
+ that directory; otherwise an absolute path is returned.
+
+ \omit
+ ### Needs checking
+ \endomit
+*/
diff --git a/src/designer/src/lib/sdk/abstractintegration.cpp b/src/designer/src/lib/sdk/abstractintegration.cpp
new file mode 100644
index 000000000..0c888f651
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractintegration.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractintegration.h"
+#include "abstractformeditor.h"
+
+#include <QtCore/QVariant>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+
+// Add 'private' struct as a dynamic property.
+
+static const char privatePropertyC[] = "_q_integrationprivate";
+
+struct QDesignerIntegrationInterfacePrivate {
+ QDesignerIntegrationInterfacePrivate() :
+ headerSuffix(QLatin1String(".h")),
+ headerLowercase(true) {}
+
+ QString headerSuffix;
+ bool headerLowercase;
+};
+
+typedef QSharedPointer<QDesignerIntegrationInterfacePrivate> QDesignerIntegrationInterfacePrivatePtr;
+
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QT_PREPEND_NAMESPACE(QDesignerIntegrationInterfacePrivatePtr))
+QT_BEGIN_NAMESPACE
+
+static QDesignerIntegrationInterfacePrivatePtr integrationD(const QObject *o)
+{
+ const QVariant property = o->property(privatePropertyC);
+ Q_ASSERT(qVariantCanConvert<QDesignerIntegrationInterfacePrivatePtr>(property));
+ return qvariant_cast<QDesignerIntegrationInterfacePrivatePtr>(property);
+}
+
+QDesignerIntegrationInterface::QDesignerIntegrationInterface(QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent),
+ m_core(core)
+{
+ core->setIntegration(this);
+ const QDesignerIntegrationInterfacePrivatePtr d(new QDesignerIntegrationInterfacePrivate);
+ setProperty(privatePropertyC, qVariantFromValue<QDesignerIntegrationInterfacePrivatePtr>(d));
+}
+
+QString QDesignerIntegrationInterface::headerSuffix() const
+{
+ return integrationD(this)->headerSuffix;
+}
+
+void QDesignerIntegrationInterface::setHeaderSuffix(const QString &headerSuffix)
+{
+ integrationD(this)->headerSuffix = headerSuffix;
+}
+
+bool QDesignerIntegrationInterface::isHeaderLowercase() const
+{
+ return integrationD(this)->headerLowercase;
+}
+
+void QDesignerIntegrationInterface::setHeaderLowercase(bool headerLowercase)
+{
+ integrationD(this)->headerLowercase = headerLowercase;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractintegration.h b/src/designer/src/lib/sdk/abstractintegration.h
new file mode 100644
index 000000000..9e27f9037
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractintegration.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTINTEGRATION_H
+#define ABSTRACTINTEGRATION_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+class QDESIGNER_SDK_EXPORT QDesignerIntegrationInterface: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString headerSuffix READ headerSuffix WRITE setHeaderSuffix)
+ Q_PROPERTY(bool headerLowercase READ isHeaderLowercase WRITE setHeaderLowercase)
+
+public:
+ QDesignerIntegrationInterface(QDesignerFormEditorInterface *core, QObject *parent = 0);
+
+ inline QDesignerFormEditorInterface *core() const;
+
+ virtual QWidget *containerWindow(QWidget *widget) const = 0;
+
+ QString headerSuffix() const;
+ void setHeaderSuffix(const QString &headerSuffix);
+
+ bool isHeaderLowercase() const;
+ void setHeaderLowercase(bool headerLowerCase);
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+inline QDesignerFormEditorInterface *QDesignerIntegrationInterface::core() const
+{ return m_core; }
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTINTEGRATION_H
diff --git a/src/designer/src/lib/sdk/abstractintrospection.cpp b/src/designer/src/lib/sdk/abstractintrospection.cpp
new file mode 100644
index 000000000..d733588fb
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractintrospection.cpp
@@ -0,0 +1,548 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractintrospection_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerMetaEnumInterface
+ \internal
+ \since 4.4
+
+ \brief QDesignerMetaEnumInterface is part of \QD's introspection interface and represents an enumeration.
+
+ \inmodule QtDesigner
+
+ The QDesignerMetaEnumInterface class provides meta-data about an enumerator.
+
+ \sa QDesignerMetaObjectInterface
+*/
+
+/*!
+ Constructs a QDesignerMetaEnumInterface object.
+*/
+
+QDesignerMetaEnumInterface::QDesignerMetaEnumInterface()
+{
+}
+
+/*!
+ Destroys the QDesignerMetaEnumInterface object.
+*/
+QDesignerMetaEnumInterface::~QDesignerMetaEnumInterface()
+{
+}
+
+/*!
+ \fn bool QDesignerMetaEnumInterface::isFlag() const
+
+ Returns true if this enumerator is used as a flag.
+*/
+
+/*!
+ \fn QString QDesignerMetaEnumInterface::key(int index) const
+
+ Returns the key with the given \a index.
+*/
+
+/*!
+ \fn int QDesignerMetaEnumInterface::keyCount() const
+
+ Returns the number of keys.
+*/
+
+/*!
+ \fn int QDesignerMetaEnumInterface::keyToValue(const QString &key) const
+
+ Returns the integer value of the given enumeration \a key, or -1 if \a key is not defined.
+*/
+
+/*!
+ \fn int QDesignerMetaEnumInterface::keysToValue(const QString &keys) const
+
+ Returns the value derived from combining together the values of the \a keys using the OR operator, or -1 if keys is not defined. Note that the strings in \a keys must be '|'-separated.
+*/
+
+/*!
+ \fn QString QDesignerMetaEnumInterface::name() const
+
+ Returns the name of the enumerator (without the scope).
+*/
+
+/*!
+ \fn QString QDesignerMetaEnumInterface::scope() const
+
+ Returns the scope this enumerator was declared in.
+*/
+
+/*!
+ \fn QString QDesignerMetaEnumInterface::separator() const
+
+ Returns the separator to be used when building enumeration names.
+*/
+
+/*!
+ \fn int QDesignerMetaEnumInterface::value(int index) const
+
+ Returns the value with the given \a index; or returns -1 if there is no such value.
+*/
+
+/*!
+ \fn QString QDesignerMetaEnumInterface::valueToKey(int value) const
+
+ Returns the string that is used as the name of the given enumeration \a value, or QString::null if value is not defined.
+*/
+
+/*!
+ \fn QString QDesignerMetaEnumInterface::valueToKeys(int value) const
+
+ Returns a byte array of '|'-separated keys that represents the given \a value.
+*/
+
+/*!
+ \class QDesignerMetaPropertyInterface
+ \internal
+ \since 4.4
+
+ \brief QDesignerMetaPropertyInterface is part of \QD's introspection interface and represents a property.
+
+ \inmodule QtDesigner
+
+ The QDesignerMetaPropertyInterface class provides meta-data about a property.
+
+ \sa QDesignerMetaObjectInterface
+*/
+
+/*!
+ Constructs a QDesignerMetaPropertyInterface object.
+*/
+
+QDesignerMetaPropertyInterface::QDesignerMetaPropertyInterface()
+{
+}
+
+/*!
+ Destroys the QDesignerMetaPropertyInterface object.
+*/
+
+QDesignerMetaPropertyInterface::~QDesignerMetaPropertyInterface()
+{
+}
+
+/*!
+ \enum QDesignerMetaPropertyInterface::Kind
+
+ This enum indicates whether the property is of a special type.
+
+ \value EnumKind The property is of an enumeration type
+ \value FlagKind The property is of an flag type
+ \value OtherKind The property is of another type
+ */
+
+/*!
+ \enum QDesignerMetaPropertyInterface::AccessFlag
+
+ These flags specify the access the property provides.
+
+ \value ReadAccess Property can be read
+ \value WriteAccess Property can be written
+ \value ResetAccess Property can be reset to a default value
+ */
+
+/*!
+ \enum QDesignerMetaPropertyInterface::Attribute
+
+ Various attributes of the property.
+
+ \value DesignableAttribute Property is designable (visible in \QD)
+ \value ScriptableAttribute Property is scriptable
+ \value StoredAttribute Property is stored, that is, not calculated
+ \value UserAttribute Property is the property that the user can edit for the QObject
+ */
+
+/*!
+ \fn const QDesignerMetaEnumInterface *QDesignerMetaPropertyInterface::enumerator() const
+
+ Returns the enumerator if this property's type is an enumerator type;
+*/
+
+/*!
+ \fn Kind QDesignerMetaPropertyInterface::kind() const
+
+ Returns the type of the property.
+*/
+
+/*!
+ \fn AccessFlags QDesignerMetaPropertyInterface::accessFlags() const
+
+ Returns a combination of access flags.
+*/
+
+/*!
+ \fn Attributes QDesignerMetaPropertyInterface::attributes(const QObject *object) const
+
+ Returns the attributes of the property for the gives \a object.
+*/
+
+/*!
+ \fn QVariant::Type QDesignerMetaPropertyInterface::type() const
+
+ Returns the type of the property.
+*/
+
+/*!
+ \fn QString QDesignerMetaPropertyInterface::name() const
+
+ Returns the name of the property.
+*/
+
+/*!
+ \fn QString QDesignerMetaPropertyInterface::typeName() const
+
+ Returns the name of this property's type.
+*/
+
+
+/*!
+ \fn int QDesignerMetaPropertyInterface::userType() const
+
+ Returns this property's user type.
+*/
+
+/*!
+ \fn bool QDesignerMetaPropertyInterface::hasSetter() const
+
+ Returns whether getter and setter methods exist for this property.
+*/
+
+/*!
+ \fn QVariant QDesignerMetaPropertyInterface::read(const QObject *object) const
+
+ Reads the property's value from the given \a object. Returns the value if it was able to read it; otherwise returns an invalid variant.
+*/
+
+/*!
+ \fn bool QDesignerMetaPropertyInterface::reset(QObject *object) const
+
+ Resets the property for the given \a object with a reset method. Returns true if the reset worked; otherwise returns false.
+*/
+
+/*!
+ \fn bool QDesignerMetaPropertyInterface::write(QObject *object, const QVariant &value) const
+
+ Writes \a value as the property's value to the given \a object. Returns true if the write succeeded; otherwise returns false.
+*/
+
+/*!
+ \class QDesignerMetaMethodInterface
+ \internal
+ \since 4.4
+
+ \brief QDesignerMetaMethodInterface is part of \QD's introspection interface and represents a member function.
+
+ \inmodule QtDesigner
+
+ The QDesignerMetaMethodInterface class provides meta-data about a member function.
+
+ \sa QDesignerMetaObjectInterface
+*/
+
+/*!
+ Constructs a QDesignerMetaMethodInterface object.
+*/
+
+QDesignerMetaMethodInterface::QDesignerMetaMethodInterface()
+{
+}
+
+/*!
+ Destroys the QDesignerMetaMethodInterface object.
+*/
+
+QDesignerMetaMethodInterface::~QDesignerMetaMethodInterface()
+{
+}
+
+/*!
+ \enum QDesignerMetaMethodInterface::MethodType
+
+ This enum specifies the type of the method
+
+ \value Method The function is a plain member function.
+ \value Signal The function is a signal.
+ \value Slot The function is a slot.
+ \value Constructor The function is a constructor.
+
+*/
+
+/*!
+ \enum QDesignerMetaMethodInterface::Access
+
+ This enum represents the access specification of the method
+
+ \value Private A private member function
+ \value Protected A protected member function
+ \value Public A public member function
+*/
+
+/*!
+ \fn QDesignerMetaMethodInterface::Access QDesignerMetaMethodInterface::access() const
+
+ Returns the access specification of this method.
+*/
+
+
+/*!
+ \fn QDesignerMetaMethodInterface::MethodType QDesignerMetaMethodInterface::methodType() const
+
+ Returns the type of this method.
+*/
+
+/*!
+ \fn QStringList QDesignerMetaMethodInterface::parameterNames() const
+
+ Returns a list of parameter names.
+*/
+
+/*!
+ \fn QStringList QDesignerMetaMethodInterface::parameterTypes() const
+
+ Returns a list of parameter types.
+*/
+
+/*!
+ \fn QString QDesignerMetaMethodInterface::signature() const
+
+ Returns the signature of this method.
+*/
+
+/*!
+ \fn QString QDesignerMetaMethodInterface::normalizedSignature() const
+
+ Returns the normalized signature of this method (suitable as signal/slot specification).
+*/
+
+
+/*!
+ \fn QString QDesignerMetaMethodInterface::tag() const
+
+ Returns the tag associated with this method.
+*/
+
+/*!
+ \fn QString QDesignerMetaMethodInterface::typeName() const
+
+ Returns the return type of this method, or an empty string if the return type is void.
+*/
+
+/*!
+ \class QDesignerMetaObjectInterface
+ \internal
+ \since 4.4
+
+ \brief QDesignerMetaObjectInterface is part of \QD's introspection interface and provides meta-information about Qt objects
+
+ \inmodule QtDesigner
+
+ The QDesignerMetaObjectInterface class provides meta-data about Qt objects. For a given object, it can be obtained
+ by querying QDesignerIntrospectionInterface.
+
+ \sa QDesignerIntrospectionInterface
+*/
+
+/*!
+ Constructs a QDesignerMetaObjectInterface object.
+*/
+
+QDesignerMetaObjectInterface::QDesignerMetaObjectInterface()
+{
+}
+
+/*!
+ Destroys the QDesignerMetaObjectInterface object.
+*/
+
+QDesignerMetaObjectInterface::~QDesignerMetaObjectInterface()
+{
+}
+
+/*!
+ \fn QString QDesignerMetaObjectInterface::className() const
+
+ Returns the class name.
+*/
+
+/*!
+ \fn const QDesignerMetaEnumInterface *QDesignerMetaObjectInterface::enumerator(int index) const
+
+ Returns the meta-data for the enumerator with the given \a index.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::enumeratorCount() const
+
+ Returns the number of enumerators in this class.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::enumeratorOffset() const
+
+ Returns the enumerator offset for this class; i.e. the index position of this class's first enumerator.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::indexOfEnumerator(const QString &name) const
+
+ Finds enumerator \a name and returns its index; otherwise returns -1.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::indexOfMethod(const QString &method) const
+
+ Finds \a method and returns its index; otherwise returns -1.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::indexOfProperty(const QString &name) const
+
+ Finds property \a name and returns its index; otherwise returns -1.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::indexOfSignal(const QString &signal) const
+
+ Finds \a signal and returns its index; otherwise returns -1.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::indexOfSlot(const QString &slot) const
+
+ Finds \a slot and returns its index; otherwise returns -1.
+*/
+
+/*!
+ \fn const QDesignerMetaMethodInterface *QDesignerMetaObjectInterface::method(int index) const
+
+ Returns the meta-data for the method with the given \a index.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::methodCount() const
+
+ Returns the number of methods in this class. These include ordinary methods, signals, and slots.
+*/
+
+/*!
+ \fn int QDesignerMetaObjectInterface::methodOffset() const
+
+ Returns the method offset for this class; i.e. the index position of this class's first member function.
+*/
+
+/*!
+ \fn const QDesignerMetaPropertyInterface *QDesignerMetaObjectInterface::property(int index) const
+
+ Returns the meta-data for the property with the given \a index.
+*/
+/*!
+ \fn int QDesignerMetaObjectInterface::propertyCount() const
+
+ Returns the number of properties in this class.
+*/
+/*!
+ \fn int QDesignerMetaObjectInterface::propertyOffset() const
+
+ Returns the property offset for this class; i.e. the index position of this class's first property.
+*/
+
+/*!
+ \fn const QDesignerMetaObjectInterface *QDesignerMetaObjectInterface::superClass() const
+
+ Returns the meta-object of the superclass, or 0 if there is no such object.
+*/
+
+/*!
+ \fn const QDesignerMetaPropertyInterface *QDesignerMetaObjectInterface::userProperty() const
+
+ Returns the property that has the USER flag set to true.
+*/
+
+/*!
+ \class QDesignerIntrospectionInterface
+ \internal
+ \since 4.4
+
+ \brief QDesignerIntrospectionInterface provides access to a QDesignerMetaObjectInterface for a given Qt object.
+
+ \inmodule QtDesigner
+
+ QDesignerIntrospectionInterface is the main class of \QD's introspection interface. These
+ interfaces provide a layer of abstraction around QMetaObject and related classes to allow for the integration
+ of other programming languages.
+
+ An instance of QDesignerIntrospectionInterface can be obtained from the core.
+
+ \sa QDesignerMetaObjectInterface
+*/
+
+/*!
+ Constructs a QDesignerIntrospectionInterface object.
+*/
+
+QDesignerIntrospectionInterface::QDesignerIntrospectionInterface()
+{
+}
+
+/*!
+ Destroys the QDesignerIntrospectionInterface object.
+*/
+
+QDesignerIntrospectionInterface::~QDesignerIntrospectionInterface()
+{
+}
+
+/*!
+ \fn const QDesignerMetaObjectInterface* QDesignerIntrospectionInterface::metaObject(const QObject *object) const
+
+ Returns the meta object of this \a object.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractintrospection_p.h b/src/designer/src/lib/sdk/abstractintrospection_p.h
new file mode 100644
index 000000000..52074b890
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractintrospection_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ABSTRACTMETAOBJECT_H
+#define ABSTRACTMETAOBJECT_H
+
+#include <QtDesigner/sdk_global.h>
+#include <QtCore/QVariant>
+#include <QtCore/QFlags>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDESIGNER_SDK_EXPORT QDesignerMetaEnumInterface
+{
+public:
+ QDesignerMetaEnumInterface();
+ virtual ~QDesignerMetaEnumInterface();
+ virtual bool isFlag() const = 0;
+ virtual QString key(int index) const = 0;
+ virtual int keyCount() const = 0;
+ virtual int keyToValue(const QString &key) const = 0;
+ virtual int keysToValue(const QString &keys) const = 0;
+ virtual QString name() const = 0;
+ virtual QString scope() const = 0;
+ virtual QString separator() const = 0;
+ virtual int value(int index) const = 0;
+ virtual QString valueToKey(int value) const = 0;
+ virtual QString valueToKeys(int value) const = 0;
+};
+
+class QDESIGNER_SDK_EXPORT QDesignerMetaPropertyInterface
+{
+public:
+ enum Kind { EnumKind, FlagKind, OtherKind };
+ enum AccessFlag { ReadAccess = 0x0001, WriteAccess = 0x0002, ResetAccess = 0x0004 };
+ enum Attribute { DesignableAttribute = 0x0001, ScriptableAttribute = 0x0002, StoredAttribute = 0x0004, UserAttribute = 0x0008};
+ Q_DECLARE_FLAGS(Attributes, Attribute)
+ Q_DECLARE_FLAGS(AccessFlags, AccessFlag)
+
+ QDesignerMetaPropertyInterface();
+ virtual ~QDesignerMetaPropertyInterface();
+
+ virtual const QDesignerMetaEnumInterface *enumerator() const = 0;
+
+ virtual Kind kind() const = 0;
+ virtual AccessFlags accessFlags() const = 0;
+ virtual Attributes attributes(const QObject *object = 0) const = 0;
+
+ virtual QVariant::Type type() const = 0;
+ virtual QString name() const = 0;
+ virtual QString typeName() const = 0;
+ virtual int userType() const = 0;
+ virtual bool hasSetter() const = 0;
+
+ virtual QVariant read(const QObject *object) const = 0;
+ virtual bool reset(QObject *object) const = 0;
+ virtual bool write(QObject *object, const QVariant &value) const = 0;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDesignerMetaPropertyInterface::AccessFlags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDesignerMetaPropertyInterface::Attributes)
+
+class QDESIGNER_SDK_EXPORT QDesignerMetaMethodInterface
+{
+public:
+ QDesignerMetaMethodInterface();
+ virtual ~QDesignerMetaMethodInterface();
+
+ enum MethodType { Method, Signal, Slot, Constructor };
+ enum Access { Private, Protected, Public };
+
+ virtual Access access() const = 0;
+ virtual MethodType methodType() const = 0;
+ virtual QStringList parameterNames() const = 0;
+ virtual QStringList parameterTypes() const = 0;
+ virtual QString signature() const = 0;
+ virtual QString normalizedSignature() const = 0;
+ virtual QString tag() const = 0;
+ virtual QString typeName() const = 0;
+};
+
+class QDESIGNER_SDK_EXPORT QDesignerMetaObjectInterface {
+public:
+ QDesignerMetaObjectInterface();
+ virtual ~QDesignerMetaObjectInterface();
+
+ virtual QString className() const = 0;
+ virtual const QDesignerMetaEnumInterface *enumerator(int index) const = 0;
+ virtual int enumeratorCount() const = 0;
+ virtual int enumeratorOffset() const = 0;
+
+ virtual int indexOfEnumerator(const QString &name) const = 0;
+ virtual int indexOfMethod(const QString &method) const = 0;
+ virtual int indexOfProperty(const QString &name) const = 0;
+ virtual int indexOfSignal(const QString &signal) const = 0;
+ virtual int indexOfSlot(const QString &slot) const = 0;
+
+ virtual const QDesignerMetaMethodInterface *method(int index) const = 0;
+ virtual int methodCount() const = 0;
+ virtual int methodOffset() const = 0;
+
+ virtual const QDesignerMetaPropertyInterface *property(int index) const = 0;
+ virtual int propertyCount() const = 0;
+ virtual int propertyOffset() const = 0;
+
+ virtual const QDesignerMetaObjectInterface *superClass() const = 0;
+ virtual const QDesignerMetaPropertyInterface *userProperty() const = 0;
+};
+
+// To be obtained from core
+class QDESIGNER_SDK_EXPORT QDesignerIntrospectionInterface {
+public:
+ QDesignerIntrospectionInterface();
+ virtual ~QDesignerIntrospectionInterface();
+
+ virtual const QDesignerMetaObjectInterface* metaObject(const QObject *object) const = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTMETAOBJECT_H
diff --git a/src/designer/src/lib/sdk/abstractlanguage.h b/src/designer/src/lib/sdk/abstractlanguage.h
new file mode 100644
index 000000000..37c0c5de0
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractlanguage.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_ABTRACT_LANGUAGE_H
+#define QDESIGNER_ABTRACT_LANGUAGE_H
+
+#include <QtDesigner/extension.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDialog;
+class QWidget;
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+class QDesignerResourceBrowserInterface;
+
+class QDesignerLanguageExtension
+{
+public:
+ virtual ~QDesignerLanguageExtension() {}
+
+ virtual QDialog *createFormWindowSettingsDialog(QDesignerFormWindowInterface *formWindow, QWidget *parentWidget) = 0;
+ virtual QDesignerResourceBrowserInterface *createResourceBrowser(QWidget *parentWidget) = 0;
+
+ virtual QDialog *createPromotionDialog(QDesignerFormEditorInterface *formEditor, QWidget *parentWidget = 0) = 0;
+
+ virtual QDialog *createPromotionDialog(QDesignerFormEditorInterface *formEditor,
+ const QString &promotableWidgetClassName,
+ QString *promoteToClassName,
+ QWidget *parentWidget = 0) = 0;
+
+ virtual bool isLanguageResource(const QString &path) const = 0;
+
+ virtual QString classNameOf(QObject *object) const = 0;
+
+ virtual bool signalMatchesSlot(const QString &signal, const QString &slot) const = 0;
+
+ virtual QString widgetBoxContents() const = 0;
+
+ virtual QString uiExtension() const = 0;
+};
+
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerLanguageExtension, "com.trolltech.Qt.Designer.Language.3")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDESIGNER_ABTRACT_LANGUAGE_H
diff --git a/src/designer/src/lib/sdk/abstractmetadatabase.cpp b/src/designer/src/lib/sdk/abstractmetadatabase.cpp
new file mode 100644
index 000000000..061c9aa89
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractmetadatabase.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// sdk
+#include "abstractmetadatabase.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerMetaDataBaseInterface
+ \brief The QDesignerMetaDataBaseInterface class provides an interface to Qt Designer's
+ object meta database.
+ \inmodule QtDesigner
+ \internal
+*/
+
+/*!
+ Constructs an interface to the meta database with the given \a parent.
+*/
+QDesignerMetaDataBaseInterface::QDesignerMetaDataBaseInterface(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ Destroys the interface to the meta database.
+*/
+QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface()
+{
+}
+
+/*!
+ \fn QDesignerMetaDataBaseItemInterface *QDesignerMetaDataBaseInterface::item(QObject *object) const
+
+ Returns the item in the meta database associated with the given \a object.
+*/
+
+/*!
+ \fn void QDesignerMetaDataBaseInterface::add(QObject *object)
+
+ Adds the specified \a object to the meta database.
+*/
+
+/*!
+ \fn void QDesignerMetaDataBaseInterface::remove(QObject *object)
+
+ Removes the specified \a object from the meta database.
+*/
+
+/*!
+ \fn QList<QObject*> QDesignerMetaDataBaseInterface::objects() const
+
+ Returns the list of objects that have corresponding items in the meta database.
+*/
+
+/*!
+ \fn QDesignerFormEditorInterface *QDesignerMetaDataBaseInterface::core() const
+
+ Returns the core interface that is associated with the meta database.
+*/
+
+
+// Doc: Interface only
+
+/*!
+ \class QDesignerMetaDataBaseItemInterface
+ \brief The QDesignerMetaDataBaseItemInterface class provides an interface to individual
+ items in Qt Designer's meta database.
+ \inmodule QtDesigner
+ \internal
+
+ This class allows individual items in \QD's meta-data database to be accessed and modified.
+ Use the QDesignerMetaDataBaseInterface class to change the properties of the database itself.
+*/
+
+/*!
+ \fn QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface()
+
+ Destroys the item interface to the meta-data database.
+*/
+
+/*!
+ \fn QString QDesignerMetaDataBaseItemInterface::name() const
+
+ Returns the name of the item in the database.
+
+ \sa setName()
+*/
+
+/*!
+ \fn void QDesignerMetaDataBaseItemInterface::setName(const QString &name)
+
+ Sets the name of the item to the given \a name.
+
+ \sa name()
+*/
+
+/*!
+ \fn QList<QWidget*> QDesignerMetaDataBaseItemInterface::tabOrder() const
+
+ Returns a list of widgets in the order defined by the form's tab order.
+
+ \sa setTabOrder()
+*/
+
+
+/*!
+ \fn void QDesignerMetaDataBaseItemInterface::setTabOrder(const QList<QWidget*> &tabOrder)
+
+ Sets the tab order in the form using the list of widgets defined by \a tabOrder.
+
+ \sa tabOrder()
+*/
+
+
+/*!
+ \fn bool QDesignerMetaDataBaseItemInterface::enabled() const
+
+ Returns whether the item is enabled.
+
+ \sa setEnabled()
+*/
+
+/*!
+ \fn void QDesignerMetaDataBaseItemInterface::setEnabled(bool enabled)
+
+ If \a enabled is true, the item is enabled; otherwise it is disabled.
+
+ \sa enabled()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractmetadatabase.h b/src/designer/src/lib/sdk/abstractmetadatabase.h
new file mode 100644
index 000000000..1fdc7ef69
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractmetadatabase.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTMETADATABASE_H
+#define ABSTRACTMETADATABASE_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtCore/QHash>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QCursor;
+class QWidget;
+
+class QDesignerFormEditorInterface;
+
+class QDesignerMetaDataBaseItemInterface
+{
+public:
+ virtual ~QDesignerMetaDataBaseItemInterface() {}
+
+ virtual QString name() const = 0;
+ virtual void setName(const QString &name) = 0;
+
+ virtual QList<QWidget*> tabOrder() const = 0;
+ virtual void setTabOrder(const QList<QWidget*> &tabOrder) = 0;
+
+ virtual bool enabled() const = 0;
+ virtual void setEnabled(bool b) = 0;
+};
+
+
+class QDESIGNER_SDK_EXPORT QDesignerMetaDataBaseInterface: public QObject
+{
+ Q_OBJECT
+public:
+ QDesignerMetaDataBaseInterface(QObject *parent = 0);
+ virtual ~QDesignerMetaDataBaseInterface();
+
+ virtual QDesignerMetaDataBaseItemInterface *item(QObject *object) const = 0;
+ virtual void add(QObject *object) = 0;
+ virtual void remove(QObject *object) = 0;
+
+ virtual QList<QObject*> objects() const = 0;
+
+ virtual QDesignerFormEditorInterface *core() const = 0;
+
+Q_SIGNALS:
+ void changed();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTMETADATABASE_H
diff --git a/src/designer/src/lib/sdk/abstractnewformwidget.cpp b/src/designer/src/lib/sdk/abstractnewformwidget.cpp
new file mode 100644
index 000000000..42d43432e
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractnewformwidget.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractnewformwidget_p.h"
+#include <newformwidget_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerNewFormWidgetInterface
+ \since 4.5
+ \internal
+
+ \brief QDesignerNewFormWidgetInterface provides an interface for chooser
+ widgets that can be used within "New Form" dialogs and wizards.
+ It presents the user with a list of choices taken from built-in
+ templates, pre-defined template paths and suitable custom widgets.
+ It provides a static creation function that returns \QD's
+ implementation.
+
+ \inmodule QtDesigner
+*/
+
+/*!
+ Constructs a QDesignerNewFormWidgetInterface object.
+*/
+
+QDesignerNewFormWidgetInterface::QDesignerNewFormWidgetInterface(QWidget *parent) :
+ QWidget(parent)
+{
+}
+
+/*!
+ Destroys the QDesignerNewFormWidgetInterface object.
+*/
+
+QDesignerNewFormWidgetInterface::~QDesignerNewFormWidgetInterface()
+{
+}
+
+/*!
+ Creates an instance of the QDesignerNewFormWidgetInterface as a child
+ of \a parent using \a core.
+*/
+
+QDesignerNewFormWidgetInterface *QDesignerNewFormWidgetInterface::createNewFormWidget(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ return new qdesigner_internal::NewFormWidget(core, parent);
+}
+
+/*!
+ \fn bool QDesignerNewFormWidgetInterface::hasCurrentTemplate() const
+
+ Returns whether a form template is currently selected.
+*/
+
+/*!
+ \fn QString QDesignerNewFormWidgetInterface::currentTemplate(QString *errorMessage = 0)
+
+ Returns the contents of the currently selected template. If the method fails,
+ an empty string is returned and \a errorMessage receives an error message.
+*/
+
+// Signals
+
+/*!
+ \fn void QDesignerNewFormWidgetInterface::templateActivated()
+
+ This signal is emitted whenever the user activates a template by double-clicking.
+*/
+
+/*!
+ \fn void QDesignerNewFormWidgetInterface::currentTemplateChanged(bool templateSelected)
+
+ This signal is emitted whenever the user changes the current template.
+ \a templateSelected indicates whether a template is currently selected.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractnewformwidget_p.h b/src/designer/src/lib/sdk/abstractnewformwidget_p.h
new file mode 100644
index 000000000..db0c74031
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractnewformwidget_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ABSTRACTNEWFORMWIDGET_H
+#define ABSTRACTNEWFORMWIDGET_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+class QDESIGNER_SDK_EXPORT QDesignerNewFormWidgetInterface : public QWidget
+{
+ Q_DISABLE_COPY(QDesignerNewFormWidgetInterface)
+ Q_OBJECT
+public:
+ explicit QDesignerNewFormWidgetInterface(QWidget *parent = 0);
+ virtual ~QDesignerNewFormWidgetInterface();
+
+ virtual bool hasCurrentTemplate() const = 0;
+ virtual QString currentTemplate(QString *errorMessage = 0) = 0;
+
+ static QDesignerNewFormWidgetInterface *createNewFormWidget(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+
+Q_SIGNALS:
+ void templateActivated();
+ void currentTemplateChanged(bool templateSelected);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTNEWFORMWIDGET_H
diff --git a/src/designer/src/lib/sdk/abstractobjectinspector.cpp b/src/designer/src/lib/sdk/abstractobjectinspector.cpp
new file mode 100644
index 000000000..d231fce58
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractobjectinspector.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractobjectinspector.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerObjectInspectorInterface
+
+ \brief The QDesignerObjectInspectorInterface class allows you to
+ change the focus of Qt Designer's object inspector.
+
+ \inmodule QtDesigner
+
+ You can use the QDesignerObjectInspectorInterface to change the
+ current form window selection. For example, when implementing a
+ custom widget plugin:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractobjectinspector.cpp 0
+
+ The QDesignerObjectInspectorInterface class is not intended to be
+ instantiated directly. You can retrieve an interface to \QD's
+ object inspector using the
+ QDesignerFormEditorInterface::objectInspector() function. A
+ pointer to \QD's current QDesignerFormEditorInterface object (\c
+ formEditor in the example above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's
+ parameter. When implementing a custom widget plugin, you must
+ subclass the QDesignerCustomWidgetInterface to expose your plugin
+ to \QD.
+
+ The interface provides the core() function that you can use to
+ retrieve a pointer to \QD's current QDesignerFormEditorInterface
+ object, and the setFormWindow() function that enables you to
+ change the current form window selection.
+
+ \sa QDesignerFormEditorInterface, QDesignerFormWindowInterface
+*/
+
+/*!
+ Constructs an object inspector interface with the given \a parent
+ and the specified window \a flags.
+*/
+QDesignerObjectInspectorInterface::QDesignerObjectInspectorInterface(QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(parent, flags)
+{
+}
+
+/*!
+ Destroys the object inspector interface.
+*/
+QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface()
+{
+}
+
+/*!
+ Returns a pointer to \QD's current QDesignerFormEditorInterface
+ object.
+*/
+QDesignerFormEditorInterface *QDesignerObjectInspectorInterface::core() const
+{
+ return 0;
+}
+
+/*!
+ \fn void QDesignerObjectInspectorInterface::setFormWindow(QDesignerFormWindowInterface *formWindow)
+
+ Sets the currently selected form window to \a formWindow.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractobjectinspector.h b/src/designer/src/lib/sdk/abstractobjectinspector.h
new file mode 100644
index 000000000..74c6e385a
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractobjectinspector.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTOBJECTINSPECTOR_H
+#define ABSTRACTOBJECTINSPECTOR_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+
+class QDESIGNER_SDK_EXPORT QDesignerObjectInspectorInterface: public QWidget
+{
+ Q_OBJECT
+public:
+ QDesignerObjectInspectorInterface(QWidget *parent, Qt::WindowFlags flags = 0);
+ virtual ~QDesignerObjectInspectorInterface();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+public Q_SLOTS:
+ virtual void setFormWindow(QDesignerFormWindowInterface *formWindow) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTOBJECTINSPECTOR_H
diff --git a/src/designer/src/lib/sdk/abstractoptionspage_p.h b/src/designer/src/lib/sdk/abstractoptionspage_p.h
new file mode 100644
index 000000000..f6c54ae44
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractoptionspage_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ABSTRACTOPTIONSPAGE_P_H
+#define ABSTRACTOPTIONSPAGE_P_H
+
+#include <QtDesigner/sdk_global.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+class QWidget;
+
+class QDESIGNER_SDK_EXPORT QDesignerOptionsPageInterface
+{
+public:
+ virtual ~QDesignerOptionsPageInterface() {}
+ virtual QString name() const = 0;
+ virtual QWidget *createPage(QWidget *parent) = 0;
+ virtual void apply() = 0;
+ virtual void finish() = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTOPTIONSPAGE_P_H
diff --git a/src/designer/src/lib/sdk/abstractpromotioninterface.cpp b/src/designer/src/lib/sdk/abstractpromotioninterface.cpp
new file mode 100644
index 000000000..5dd590cb3
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractpromotioninterface.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractpromotioninterface.h"
+
+QT_BEGIN_NAMESPACE
+
+QDesignerPromotionInterface::~QDesignerPromotionInterface()
+{
+}
+
+/*!
+ \class QDesignerPromotionInterface
+
+ \brief The QDesignerPromotionInterface provides functions for modifying
+ the promoted classes in Designer.
+ \inmodule QtDesigner
+ \internal
+ \since 4.3
+*/
+
+/*!
+ \class QDesignerPromotionInterface::PromotedClass
+ A pair of database items containing the base class and the promoted class.
+
+ \typedef QDesignerPromotionInterface::PromotedClasses
+ A list of PromotedClass items.
+
+ virtual QDesignerPromotionInterface::PromotedClasses promotedClasses() const
+
+ Returns a list of promoted classes along with their base classes in alphabetical order.
+ It can be used to populate tree models for editing promoted widgets.
+
+*/
+
+/*!
+ \fn virtual QSet<QString> QDesignerPromotionInterface::referencedPromotedClassNames() const
+
+ Returns a set of promoted classed that are referenced by the currently opened forms.
+*/
+
+/*!
+ \fn virtual bool QDesignerPromotionInterface::addPromotedClass(const QString &baseClass, const QString &className, const QString &includeFile, QString *errorMessage)
+
+ Add a promoted class named \a with the base class \a and include file \a includeFile. Returns \c true on success or \c false along
+ with an error message in \a errorMessage on failure.
+*/
+
+/*!
+ \fn virtual bool QDesignerPromotionInterface::removePromotedClass(const QString &className, QString *errorMessage)
+
+ Remove the promoted class named \a className unless it is referenced by a form. Returns \c true on success or \c false along
+ with an error message in \a errorMessage on failure.
+*/
+
+/*!
+ \fn virtual bool QDesignerPromotionInterface::changePromotedClassName(const QString &oldClassName, const QString &newClassName, QString *errorMessage)
+
+ Change the class name of a promoted class from \a oldClassName to \a newClassName. Returns \c true on success or \c false along
+ with an error message in \a errorMessage on failure.
+*/
+
+/*!
+ \fn virtual bool QDesignerPromotionInterface::setPromotedClassIncludeFile(const QString &className, const QString &includeFile, QString *errorMessage)
+
+ Change the include file of a promoted class named \a className to be \a includeFile. Returns \c true on success or \c false along
+ with an error message in \a errorMessage on failure.
+*/
+
+/*! \fn virtual QList<QDesignerWidgetDataBaseItemInterface *> QDesignerPromotionInterface::promotionBaseClasses() const
+
+ Return a list of base classes that are suitable for promotion.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractpromotioninterface.h b/src/designer/src/lib/sdk/abstractpromotioninterface.h
new file mode 100644
index 000000000..6c60991d8
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractpromotioninterface.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTPROMOTIONINTERFACE_H
+#define ABSTRACTPROMOTIONINTERFACE_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QPair>
+#include <QtCore/QList>
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerWidgetDataBaseItemInterface;
+
+class QDESIGNER_SDK_EXPORT QDesignerPromotionInterface
+{
+public:
+ virtual ~QDesignerPromotionInterface();
+
+ struct PromotedClass {
+ QDesignerWidgetDataBaseItemInterface *baseItem;
+ QDesignerWidgetDataBaseItemInterface *promotedItem;
+ };
+
+ typedef QList<PromotedClass> PromotedClasses;
+
+ virtual PromotedClasses promotedClasses() const = 0;
+
+ virtual QSet<QString> referencedPromotedClassNames() const = 0;
+
+ virtual bool addPromotedClass(const QString &baseClass,
+ const QString &className,
+ const QString &includeFile,
+ QString *errorMessage) = 0;
+
+ virtual bool removePromotedClass(const QString &className, QString *errorMessage) = 0;
+
+ virtual bool changePromotedClassName(const QString &oldClassName, const QString &newClassName, QString *errorMessage) = 0;
+
+ virtual bool setPromotedClassIncludeFile(const QString &className, const QString &includeFile, QString *errorMessage) = 0;
+
+ virtual QList<QDesignerWidgetDataBaseItemInterface *> promotionBaseClasses() const = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTPROMOTIONINTERFACE_H
diff --git a/src/designer/src/lib/sdk/abstractpropertyeditor.cpp b/src/designer/src/lib/sdk/abstractpropertyeditor.cpp
new file mode 100644
index 000000000..040362c9b
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractpropertyeditor.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractpropertyeditor.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerPropertyEditorInterface
+
+ \brief The QDesignerPropertyEditorInterface class allows you to
+ query and manipulate the current state of Qt Designer's property
+ editor.
+
+ \inmodule QtDesigner
+
+ QDesignerPropertyEditorInterface contains a collection of
+ functions that is typically used to query the property editor for
+ its current state, and several slots manipulating it's state. The
+ interface also provide a signal, propertyChanged(), which is
+ emitted whenever a property changes in the property editor. The
+ signal's arguments are the property that changed and its new
+ value.
+
+ For example, when implementing a custom widget plugin, you can
+ connect the signal to a custom slot:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.cpp 0
+
+ Then the custom slot can check if the new value is within the
+ range we want when a specified property, belonging to a particular
+ widget, changes:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.cpp 1
+
+ The QDesignerPropertyEditorInterface class is not intended to be
+ instantiated directly. You can retrieve an interface to \QD's
+ property editor using the
+ QDesignerFormEditorInterface::propertyEditor() function. A pointer
+ to \QD's current QDesignerFormEditorInterface object (\c
+ formEditor in the examples above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's
+ parameter. When implementing a custom widget plugin, you must
+ subclass the QDesignerCustomWidgetInterface to expose your plugin
+ to \QD.
+
+ The functions accessing the property editor are the core()
+ function that you can use to retrieve an interface to the form
+ editor, the currentPropertyName() function that returns the name
+ of the currently selected property in the property editor, the
+ object() function that returns the currently selected object in
+ \QD's workspace, and the isReadOnly() function that returns true
+ if the property editor is write proteced (otherwise false).
+
+ The slots manipulating the property editor's state are the
+ setObject() slot that you can use to change the currently selected
+ object in \QD's workspace, the setPropertyValue() slot that
+ changes the value of a given property and the setReadOnly() slot
+ that control the write protection of the property editor.
+
+ \sa QDesignerFormEditorInterface
+*/
+
+/*!
+ Constructs a property editor interface with the given \a parent and
+ the specified window \a flags.
+*/
+QDesignerPropertyEditorInterface::QDesignerPropertyEditorInterface(QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(parent, flags)
+{
+}
+
+/*!
+ Destroys the property editor interface.
+*/
+QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface()
+{
+}
+
+/*!
+ Returns a pointer to \QD's current QDesignerFormEditorInterface
+ object.
+*/
+QDesignerFormEditorInterface *QDesignerPropertyEditorInterface::core() const
+{
+ return 0;
+}
+
+/*!
+ \fn bool QDesignerPropertyEditorInterface::isReadOnly() const
+
+ Returns true if the property editor is write protected; otherwise
+ false.
+
+ \sa setReadOnly()
+*/
+
+/*!
+ \fn QObject *QDesignerPropertyEditorInterface::object() const
+
+ Returns the currently selected object in \QD's workspace.
+
+ \sa setObject()
+*/
+
+/*!
+ \fn QString QDesignerPropertyEditorInterface::currentPropertyName() const
+
+ Returns the name of the currently selected property in the
+ property editor.
+
+ \sa setPropertyValue()
+*/
+
+/*!
+ \fn void QDesignerPropertyEditorInterface::propertyChanged(const QString &name, const QVariant &value)
+
+ This signal is emitted whenever a property changes in the property
+ editor. The property that changed and its new value are specified
+ by \a name and \a value respectively.
+
+ \sa setPropertyValue()
+*/
+
+/*!
+ \fn void QDesignerPropertyEditorInterface::setObject(QObject *object)
+
+ Changes the currently selected object in \QD's workspace, to \a
+ object.
+
+ \sa object()
+*/
+
+/*!
+ \fn void QDesignerPropertyEditorInterface::setPropertyValue(const QString &name, const QVariant &value, bool changed = true)
+
+ Sets the value of the property specified by \a name to \a
+ value.
+
+ In addition, the property is marked as \a changed in the property
+ editor, i.e. its value is different from the default value.
+
+ \sa currentPropertyName(), propertyChanged()
+*/
+
+/*!
+ \fn void QDesignerPropertyEditorInterface::setReadOnly(bool readOnly)
+
+ If \a readOnly is true, the property editor is made write
+ protected; otherwise the write protection is removed.
+
+ \sa isReadOnly()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractpropertyeditor.h b/src/designer/src/lib/sdk/abstractpropertyeditor.h
new file mode 100644
index 000000000..a8d731631
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractpropertyeditor.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTPROPERTYEDITOR_H
+#define ABSTRACTPROPERTYEDITOR_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QString;
+class QVariant;
+
+class QDESIGNER_SDK_EXPORT QDesignerPropertyEditorInterface: public QWidget
+{
+ Q_OBJECT
+public:
+ QDesignerPropertyEditorInterface(QWidget *parent, Qt::WindowFlags flags = 0);
+ virtual ~QDesignerPropertyEditorInterface();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool isReadOnly() const = 0;
+ virtual QObject *object() const = 0;
+
+ virtual QString currentPropertyName() const = 0;
+
+Q_SIGNALS:
+ void propertyChanged(const QString &name, const QVariant &value);
+
+public Q_SLOTS:
+ virtual void setObject(QObject *object) = 0;
+ virtual void setPropertyValue(const QString &name, const QVariant &value, bool changed = true) = 0;
+ virtual void setReadOnly(bool readOnly) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTPROPERTYEDITOR_H
diff --git a/src/designer/src/lib/sdk/abstractresourcebrowser.cpp b/src/designer/src/lib/sdk/abstractresourcebrowser.cpp
new file mode 100644
index 000000000..0bb7341ef
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractresourcebrowser.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractresourcebrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+QDesignerResourceBrowserInterface::QDesignerResourceBrowserInterface(QWidget *parent)
+ : QWidget(parent)
+{
+
+}
+
+QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface()
+{
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractresourcebrowser.h b/src/designer/src/lib/sdk/abstractresourcebrowser.h
new file mode 100644
index 000000000..836912d9a
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractresourcebrowser.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTRESOURCEBROWSER_H
+#define ABSTRACTRESOURCEBROWSER_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QWidget; // FIXME: fool syncqt
+
+class QDESIGNER_SDK_EXPORT QDesignerResourceBrowserInterface: public QWidget
+{
+ Q_OBJECT
+public:
+ QDesignerResourceBrowserInterface(QWidget *parent = 0);
+ virtual ~QDesignerResourceBrowserInterface();
+
+ virtual void setCurrentPath(const QString &filePath) = 0;
+ virtual QString currentPath() const = 0;
+
+Q_SIGNALS:
+ void currentPathChanged(const QString &filePath);
+ void pathActivated(const QString &filePath);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTFORMEDITOR_H
+
diff --git a/src/designer/src/lib/sdk/abstractsettings_p.h b/src/designer/src/lib/sdk/abstractsettings_p.h
new file mode 100644
index 000000000..6637d1ae5
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractsettings_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ABSTRACTSETTINGS_P_H
+#define ABSTRACTSETTINGS_P_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QVariant>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+/*!
+ To be implemented by IDEs that want to control the way designer retrieves/stores its settings.
+ */
+class QDESIGNER_SDK_EXPORT QDesignerSettingsInterface
+{
+public:
+ virtual ~QDesignerSettingsInterface() {}
+
+ virtual void beginGroup(const QString &prefix) = 0;
+ virtual void endGroup() = 0;
+
+ virtual bool contains(const QString &key) const = 0;
+ virtual void setValue(const QString &key, const QVariant &value) = 0;
+ virtual QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const = 0;
+ virtual void remove(const QString &key) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTSETTINGS_P_H
diff --git a/src/designer/src/lib/sdk/abstractwidgetbox.cpp b/src/designer/src/lib/sdk/abstractwidgetbox.cpp
new file mode 100644
index 000000000..6b23c606a
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractwidgetbox.cpp
@@ -0,0 +1,340 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractwidgetbox.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerWidgetBoxInterface
+
+ \brief The QDesignerWidgetBoxInterface class allows you to control
+ the contents of Qt Designer's widget box.
+
+ \inmodule QtDesigner
+
+ QDesignerWidgetBoxInterface contains a collection of functions
+ that is typically used to manipulate the contents of \QD's widget
+ box.
+
+ \QD uses an XML file to populate its widget box. The name of that
+ file is one of the widget box's properties, and you can retrieve
+ it using the fileName() function.
+
+ QDesignerWidgetBoxInterface also provides the save() function that
+ saves the contents of the widget box in the file specified by the
+ widget box's file name property. If you have made changes to the
+ widget box, for example by dropping a widget into the widget box,
+ without calling the save() function, the original content can be
+ restored by a simple invocation of the load() function:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractwidgetbox.cpp 0
+
+ The QDesignerWidgetBoxInterface class is not intended to be
+ instantiated directly. You can retrieve an interface to Qt
+ Designer's widget box using the
+ QDesignerFormEditorInterface::widgetBox() function. A pointer to
+ \QD's current QDesignerFormEditorInterface object (\c formEditor
+ in the example above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's
+ parameter. When implementing a custom widget plugin, you must
+ subclass the QDesignerCustomWidgetInterface to expose your plugin
+ to \QD.
+
+ If you want to save your changes, and at the same time preserve
+ the original contents, you can use the save() function combined
+ with the setFileName() function to save your changes into another
+ file. Remember to store the name of the original file first:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractwidgetbox.cpp 1
+
+ Then you can restore the original contents of the widget box by
+ resetting the file name to the original file and calling load():
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractwidgetbox.cpp 2
+
+ In a similar way, you can later use your customized XML file:
+
+ \snippet doc/src/snippets/code/tools_designer_src_lib_sdk_abstractwidgetbox.cpp 3
+
+
+ \sa QDesignerFormEditorInterface
+*/
+
+/*!
+ Constructs a widget box interface with the given \a parent and
+ the specified window \a flags.
+*/
+QDesignerWidgetBoxInterface::QDesignerWidgetBoxInterface(QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(parent, flags)
+{
+}
+
+/*!
+ Destroys the widget box interface.
+*/
+QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface()
+{
+}
+
+/*!
+ \internal
+*/
+int QDesignerWidgetBoxInterface::findOrInsertCategory(const QString &categoryName)
+{
+ int count = categoryCount();
+ for (int index=0; index<count; ++index) {
+ Category c = category(index);
+ if (c.name() == categoryName)
+ return index;
+ }
+
+ addCategory(Category(categoryName));
+ return count;
+}
+
+/*!
+ \internal
+ \fn int QDesignerWidgetBoxInterface::categoryCount() const
+*/
+
+/*!
+ \internal
+ \fn Category QDesignerWidgetBoxInterface::category(int cat_idx) const
+*/
+
+/*!
+ \internal
+ \fn void QDesignerWidgetBoxInterface::addCategory(const Category &cat)
+*/
+
+/*!
+ \internal
+ \fn void QDesignerWidgetBoxInterface::removeCategory(int cat_idx)
+*/
+
+/*!
+ \internal
+ \fn int QDesignerWidgetBoxInterface::widgetCount(int cat_idx) const
+*/
+
+/*!
+ \internal
+ \fn Widget QDesignerWidgetBoxInterface::widget(int cat_idx, int wgt_idx) const
+*/
+
+/*!
+ \internal
+ \fn void QDesignerWidgetBoxInterface::addWidget(int cat_idx, const Widget &wgt)
+*/
+
+/*!
+ \internal
+ \fn void QDesignerWidgetBoxInterface::removeWidget(int cat_idx, int wgt_idx)
+*/
+
+/*!
+ \internal
+ \fn void QDesignerWidgetBoxInterface::dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, const QPoint &global_mouse_pos)
+
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::setFileName(const QString &fileName)
+
+ Sets the XML file that \QD will use to populate its widget box, to
+ \a fileName. You must call load() to update the widget box with
+ the new XML file.
+
+ \sa fileName(), load()
+*/
+
+/*!
+ \fn QString QDesignerWidgetBoxInterface::fileName() const
+
+ Returns the name of the XML file \QD is currently using to
+ populate its widget box.
+
+ \sa setFileName()
+*/
+
+/*!
+ \fn bool QDesignerWidgetBoxInterface::load()
+
+ Populates \QD's widget box by loading (or reloading) the currently
+ specified XML file. Returns true if the file is successfully
+ loaded; otherwise false.
+
+ \sa setFileName()
+*/
+
+/*!
+ \fn bool QDesignerWidgetBoxInterface::save()
+
+ Saves the contents of \QD's widget box in the file specified by
+ the fileName() function. Returns true if the content is
+ successfully saved; otherwise false.
+
+ \sa fileName(), setFileName()
+*/
+
+
+/*!
+ \internal
+
+ \class QDesignerWidgetBoxInterface::Widget
+
+ \brief The Widget class specified a widget in Qt Designer's widget
+ box component.
+*/
+
+/*!
+ \enum QDesignerWidgetBoxInterface::Widget::Type
+
+ \value Default
+ \value Custom
+*/
+
+/*!
+ \fn QDesignerWidgetBoxInterface::Widget::Widget(const QString &aname, const QString &xml, const QString &icon_name, Type atype)
+*/
+
+/*!
+ \fn QString QDesignerWidgetBoxInterface::Widget::name() const
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::Widget::setName(const QString &aname)
+*/
+
+/*!
+ \fn QString QDesignerWidgetBoxInterface::Widget::domXml() const
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::Widget::setDomXml(const QString &xml)
+*/
+
+/*!
+ \fn QString QDesignerWidgetBoxInterface::Widget::iconName() const
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::Widget::setIconName(const QString &icon_name)
+*/
+
+/*!
+ \fn Type QDesignerWidgetBoxInterface::Widget::type() const
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::Widget::setType(Type atype)
+*/
+
+/*!
+ \fn bool QDesignerWidgetBoxInterface::Widget::isNull() const
+*/
+
+
+/*!
+ \class QDesignerWidgetBoxInterface::Category
+ \brief The Category class specifies a category in Qt Designer's widget box component.
+ \internal
+*/
+
+/*!
+ \enum QDesignerWidgetBoxInterface::Category::Type
+
+ \value Default
+ \value Scratchpad
+*/
+
+/*!
+ \fn QDesignerWidgetBoxInterface::Category::Category(const QString &aname, Type atype)
+*/
+
+/*!
+ \fn QString QDesignerWidgetBoxInterface::Category::name() const
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::Category::setName(const QString &aname)
+*/
+
+/*!
+ \fn int QDesignerWidgetBoxInterface::Category::widgetCount() const
+*/
+
+/*!
+ \fn Widget QDesignerWidgetBoxInterface::Category::widget(int idx) const
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::Category::removeWidget(int idx)
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::Category::addWidget(const Widget &awidget)
+*/
+
+/*!
+ \fn Type QDesignerWidgetBoxInterface::Category::type() const
+*/
+
+/*!
+ \fn void QDesignerWidgetBoxInterface::Category::setType(Type atype)
+*/
+
+/*!
+ \fn bool QDesignerWidgetBoxInterface::Category::isNull() const
+*/
+
+/*!
+ \typedef QDesignerWidgetBoxInterface::CategoryList
+ \internal
+*/
+
+/*!
+ \typedef QDesignerWidgetBoxInterface::WidgetList
+ \internal
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractwidgetbox.h b/src/designer/src/lib/sdk/abstractwidgetbox.h
new file mode 100644
index 000000000..cf1cb1b2e
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractwidgetbox.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTWIDGETBOX_H
+#define ABSTRACTWIDGETBOX_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QMetaType>
+#include <QtGui/QWidget>
+#include <QtGui/QIcon>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class DomUI;
+class QDesignerDnDItemInterface;
+
+class QDESIGNER_SDK_EXPORT QDesignerWidgetBoxInterface : public QWidget
+{
+ Q_OBJECT
+public:
+ class Widget {
+ public:
+ enum Type { Default, Custom };
+ Widget(const QString &aname = QString(), const QString &xml = QString(),
+ const QString &icon_name = QString(), Type atype = Default)
+ : m_name(aname), m_xml(xml), m_icon_name(icon_name), m_type(atype) {}
+ QString name() const { return m_name; }
+ void setName(const QString &aname) { m_name = aname; }
+ QString domXml() const { return m_xml; }
+ void setDomXml(const QString &xml) { m_xml = xml; }
+ QString iconName() const { return m_icon_name; }
+ void setIconName(const QString &icon_name) { m_icon_name = icon_name; }
+ Type type() const { return m_type; }
+ void setType(Type atype) { m_type = atype; }
+
+ bool isNull() const { return m_name.isEmpty(); }
+
+ private:
+ QString m_name;
+ QString m_xml;
+ QString m_icon_name;
+ Type m_type;
+ };
+ typedef QList<Widget> WidgetList;
+
+ class Category {
+ public:
+ enum Type { Default, Scratchpad };
+
+ Category(const QString &aname = QString(), Type atype = Default)
+ : m_name(aname), m_type(atype) {}
+
+ QString name() const { return m_name; }
+ void setName(const QString &aname) { m_name = aname; }
+ int widgetCount() const { return m_widget_list.size(); }
+ Widget widget(int idx) const { return m_widget_list.at(idx); }
+ void removeWidget(int idx) { m_widget_list.removeAt(idx); }
+ void addWidget(const Widget &awidget) { m_widget_list.append(awidget); }
+ Type type() const { return m_type; }
+ void setType(Type atype) { m_type = atype; }
+
+ bool isNull() const { return m_name.isEmpty(); }
+
+ private:
+ QString m_name;
+ Type m_type;
+ QList<Widget> m_widget_list;
+ };
+ typedef QList<Category> CategoryList;
+
+ QDesignerWidgetBoxInterface(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ virtual ~QDesignerWidgetBoxInterface();
+
+ virtual int categoryCount() const = 0;
+ virtual Category category(int cat_idx) const = 0;
+ virtual void addCategory(const Category &cat) = 0;
+ virtual void removeCategory(int cat_idx) = 0;
+
+ virtual int widgetCount(int cat_idx) const = 0;
+ virtual Widget widget(int cat_idx, int wgt_idx) const = 0;
+ virtual void addWidget(int cat_idx, const Widget &wgt) = 0;
+ virtual void removeWidget(int cat_idx, int wgt_idx) = 0;
+
+ int findOrInsertCategory(const QString &categoryName);
+
+ virtual void dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list,
+ const QPoint &global_mouse_pos) = 0;
+
+ virtual void setFileName(const QString &file_name) = 0;
+ virtual QString fileName() const = 0;
+ virtual bool load() = 0;
+ virtual bool save() = 0;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QT_PREPEND_NAMESPACE(QDesignerWidgetBoxInterface::Widget))
+
+QT_END_HEADER
+
+#endif // ABSTRACTWIDGETBOX_H
diff --git a/src/designer/src/lib/sdk/abstractwidgetdatabase.cpp b/src/designer/src/lib/sdk/abstractwidgetdatabase.cpp
new file mode 100644
index 000000000..f48b10030
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractwidgetdatabase.cpp
@@ -0,0 +1,360 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractwidgetdatabase.h"
+#include <QtCore/qdebug.h>
+#include <qalgorithms.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { debugWidgetDataBase = 0 };
+}
+
+/*!
+ \class QDesignerWidgetDataBaseInterface
+ \brief The QDesignerWidgetDataBaseInterface class provides an interface that is used to
+ access and modify Qt Designer's widget database.
+ \inmodule QtDesigner
+ \internal
+*/
+
+/*!
+ Constructs an interface to the widget database with the given \a parent.
+*/
+QDesignerWidgetDataBaseInterface::QDesignerWidgetDataBaseInterface(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ Destroys the interface to the widget database.
+*/
+QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface()
+{
+ qDeleteAll(m_items);
+}
+
+/*!
+
+*/
+int QDesignerWidgetDataBaseInterface::count() const
+{
+ return m_items.count();
+}
+
+/*!
+*/
+QDesignerWidgetDataBaseItemInterface *QDesignerWidgetDataBaseInterface::item(int index) const
+{
+ return index != -1 ? m_items.at(index) : 0;
+}
+
+/*!
+*/
+int QDesignerWidgetDataBaseInterface::indexOf(QDesignerWidgetDataBaseItemInterface *item) const
+{
+ return m_items.indexOf(item);
+}
+
+/*!
+*/
+void QDesignerWidgetDataBaseInterface::insert(int index, QDesignerWidgetDataBaseItemInterface *item)
+{
+ if (debugWidgetDataBase)
+ qDebug() << "insert at " << index << ' ' << item->name() << " derived from " << item->extends();
+
+ m_items.insert(index, item);
+}
+
+/*!
+*/
+void QDesignerWidgetDataBaseInterface::append(QDesignerWidgetDataBaseItemInterface *item)
+{
+ if (debugWidgetDataBase)
+ qDebug() << "append " << item->name() << " derived from " << item->extends();
+ m_items.append(item);
+}
+
+/*!
+*/
+QDesignerFormEditorInterface *QDesignerWidgetDataBaseInterface::core() const
+{
+ return 0;
+}
+
+/*!
+*/
+int QDesignerWidgetDataBaseInterface::indexOfClassName(const QString &name, bool) const
+{
+ const int itemCount = count();
+ for (int i=0; i<itemCount; ++i) {
+ const QDesignerWidgetDataBaseItemInterface *entry = item(i);
+ if (entry->name() == name)
+ return i;
+ }
+
+ return -1;
+}
+
+/*!
+*/
+int QDesignerWidgetDataBaseInterface::indexOfObject(QObject *object, bool) const
+{
+ if (!object)
+ return -1;
+
+ const QString className = QString::fromUtf8(object->metaObject()->className());
+ return indexOfClassName(className);
+}
+
+/*!
+*/
+bool QDesignerWidgetDataBaseInterface::isContainer(QObject *object, bool resolveName) const
+{
+ if (const QDesignerWidgetDataBaseItemInterface *i = item(indexOfObject(object, resolveName)))
+ return i->isContainer();
+ return false;
+}
+
+/*!
+*/
+bool QDesignerWidgetDataBaseInterface::isCustom(QObject *object, bool resolveName) const
+{
+ if (const QDesignerWidgetDataBaseItemInterface *i = item(indexOfObject(object, resolveName)))
+ return i->isCustom();
+ return false;
+}
+
+/*!
+ \fn void QDesignerWidgetDataBaseInterface::changed()
+
+ This signal is emitted ...
+*/
+
+
+// Doc: No implementation - an abstract class
+
+/*!
+ \class QDesignerWidgetDataBaseItemInterface
+ \brief The QDesignerWidgetDataBaseItemInterface class provides an interface that is used to
+ access individual items in Qt Designer's widget database.
+ \inmodule QtDesigner
+ \internal
+
+ This class enables individual items in the widget database to be accessed and modified.
+ Changes to the widget database itself are made through the QDesignerWidgetDataBaseInterface
+ class.
+*/
+
+/*!
+ \fn virtual QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface()
+
+ Destroys the interface.
+*/
+
+/*!
+ \fn virtual QString QDesignerWidgetDataBaseItemInterface::name() const = 0
+
+ Returns the name of the widget.
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setName(const QString &name) = 0
+*/
+
+/*!
+ \fn virtual QString QDesignerWidgetDataBaseItemInterface::group() const = 0
+
+ Returns the name of the group that the widget belongs to.
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setGroup(const QString &group) = 0
+*/
+
+/*!
+ \fn virtual QString QDesignerWidgetDataBaseItemInterface::toolTip() const = 0
+
+ Returns the tool tip to be used by the widget.
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setToolTip(const QString &toolTip) = 0
+*/
+
+/*!
+ \fn virtual QString QDesignerWidgetDataBaseItemInterface::whatsThis() const = 0
+
+ Returns the "What's This?" help for the widget.
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setWhatsThis(const QString &whatsThis) = 0
+*/
+
+/*!
+ \fn virtual QString QDesignerWidgetDataBaseItemInterface::includeFile() const = 0
+
+ Returns the name of the include file that the widget needs when being built from source.
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setIncludeFile(const QString &includeFile) = 0
+*/
+
+/*!
+ \fn virtual QIcon QDesignerWidgetDataBaseItemInterface::icon() const = 0
+
+ Returns the icon used to represent the item.
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setIcon(const QIcon &icon) = 0
+*/
+
+/*!
+ \fn virtual bool QDesignerWidgetDataBaseItemInterface::isCompat() const = 0
+
+ Returns true if this type of widget is provided for compatibility purposes (e.g. Qt3Support
+ widgets); otherwise returns false.
+
+ \sa setCompat()
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setCompat(bool compat) = 0
+
+ If \a compat is true, the widget is handled as a compatibility widget; otherwise it is
+ handled normally by \QD.
+
+ \sa isCompat()
+*/
+
+/*!
+ \fn virtual bool QDesignerWidgetDataBaseItemInterface::isContainer() const = 0
+
+ Returns true if this widget is intended to be used to hold other widgets; otherwise returns
+ false.
+
+ \sa setContainer()
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setContainer(bool container) = 0
+
+ If \a container is true, the widget can be used to hold other widgets in \QD; otherwise
+ \QD will refuse to let the user place other widgets inside it.
+
+ \sa isContainer()
+*/
+
+/*!
+ \fn virtual bool QDesignerWidgetDataBaseItemInterface::isCustom() const = 0
+
+ Returns true if the widget is a custom widget; otherwise return false if it is a standard
+ Qt widget.
+
+ \sa setCustom()
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setCustom(bool custom) = 0
+
+ If \a custom is true, the widget is handled specially by \QD; otherwise it is handled as
+ a standard Qt widget.
+
+ \sa isCustom()
+*/
+
+/*!
+ \fn virtual QString QDesignerWidgetDataBaseItemInterface::pluginPath() const = 0
+
+ Returns the path to use for the widget plugin.
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setPluginPath(const QString &path) = 0
+*/
+
+/*!
+ \fn virtual bool QDesignerWidgetDataBaseItemInterface::isPromoted() const = 0
+
+ Returns true if the widget is promoted; otherwise returns false.
+
+ Promoted widgets are those that represent custom widgets, but which are represented in
+ \QD by either standard Qt widgets or readily-available custom widgets.
+
+ \sa setPromoted()
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setPromoted(bool promoted) = 0
+
+ If \a promoted is true, the widget is handled as a promoted widget by \QD and will use
+ a placeholder widget to represent it; otherwise it is handled as a standard widget.
+
+ \sa isPromoted()
+*/
+
+/*!
+ \fn virtual QString QDesignerWidgetDataBaseItemInterface::extends() const = 0
+
+ Returns the name of the widget that the item extends.
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setExtends(const QString &s) = 0
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetDataBaseItemInterface::setDefaultPropertyValues(const QList<QVariant> &list) = 0
+
+ Sets the default property values for the widget to the given \a list.
+*/
+
+/*!
+ \fn virtual QList<QVariant> QDesignerWidgetDataBaseItemInterface::defaultPropertyValues() const = 0
+
+ Returns a list of default values to be used as properties for the item.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractwidgetdatabase.h b/src/designer/src/lib/sdk/abstractwidgetdatabase.h
new file mode 100644
index 000000000..7ea5db8a1
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractwidgetdatabase.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTWIDGETDATABASE_H
+#define ABSTRACTWIDGETDATABASE_H
+
+#include <QtDesigner/sdk_global.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QIcon;
+class QString;
+class QDesignerFormEditorInterface;
+class QDebug;
+
+class QDesignerWidgetDataBaseItemInterface
+{
+public:
+ virtual ~QDesignerWidgetDataBaseItemInterface() {}
+
+ virtual QString name() const = 0;
+ virtual void setName(const QString &name) = 0;
+
+ virtual QString group() const = 0;
+ virtual void setGroup(const QString &group) = 0;
+
+ virtual QString toolTip() const = 0;
+ virtual void setToolTip(const QString &toolTip) = 0;
+
+ virtual QString whatsThis() const = 0;
+ virtual void setWhatsThis(const QString &whatsThis) = 0;
+
+ virtual QString includeFile() const = 0;
+ virtual void setIncludeFile(const QString &includeFile) = 0;
+
+ virtual QIcon icon() const = 0;
+ virtual void setIcon(const QIcon &icon) = 0;
+
+ virtual bool isCompat() const = 0;
+ virtual void setCompat(bool compat) = 0;
+
+ virtual bool isContainer() const = 0;
+ virtual void setContainer(bool container) = 0;
+
+ virtual bool isCustom() const = 0;
+ virtual void setCustom(bool custom) = 0;
+
+ virtual QString pluginPath() const = 0;
+ virtual void setPluginPath(const QString &path) = 0;
+
+ virtual bool isPromoted() const = 0;
+ virtual void setPromoted(bool b) = 0;
+
+ virtual QString extends() const = 0;
+ virtual void setExtends(const QString &s) = 0;
+
+ virtual void setDefaultPropertyValues(const QList<QVariant> &list) = 0;
+ virtual QList<QVariant> defaultPropertyValues() const = 0;
+};
+
+class QDESIGNER_SDK_EXPORT QDesignerWidgetDataBaseInterface: public QObject
+{
+ Q_OBJECT
+public:
+ QDesignerWidgetDataBaseInterface(QObject *parent = 0);
+ virtual ~QDesignerWidgetDataBaseInterface();
+
+ virtual int count() const;
+ virtual QDesignerWidgetDataBaseItemInterface *item(int index) const;
+
+ virtual int indexOf(QDesignerWidgetDataBaseItemInterface *item) const;
+ virtual void insert(int index, QDesignerWidgetDataBaseItemInterface *item);
+ virtual void append(QDesignerWidgetDataBaseItemInterface *item);
+
+ virtual int indexOfObject(QObject *object, bool resolveName = true) const;
+ virtual int indexOfClassName(const QString &className, bool resolveName = true) const;
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ bool isContainer(QObject *object, bool resolveName = true) const;
+ bool isCustom(QObject *object, bool resolveName = true) const;
+
+Q_SIGNALS:
+ void changed();
+
+protected:
+ QList<QDesignerWidgetDataBaseItemInterface *> m_items;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTWIDGETDATABASE_H
diff --git a/src/designer/src/lib/sdk/abstractwidgetfactory.cpp b/src/designer/src/lib/sdk/abstractwidgetfactory.cpp
new file mode 100644
index 000000000..769db175c
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractwidgetfactory.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDesigner/abstractwidgetfactory.h>
+#include "abstractformeditor.h"
+#include "abstractwidgetdatabase.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerWidgetFactoryInterface
+ \brief The QDesignerWidgetFactoryInterface class provides an interface that is used to control
+ the widget factory used by Qt Designer.
+ \inmodule QtDesigner
+ \internal
+*/
+
+/*!
+ \fn QDesignerWidgetFactoryInterface::QDesignerWidgetFactoryInterface(QObject *parent)
+
+ Constructs an interface to a widget factory with the given \a parent.
+*/
+QDesignerWidgetFactoryInterface::QDesignerWidgetFactoryInterface(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ \fn virtual QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface()
+*/
+QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface()
+{
+}
+
+/*!
+ \fn virtual QDesignerFormEditorInterface *QDesignerWidgetFactoryInterface::core() const = 0
+
+ Returns the core form editor interface associated with this interface.
+*/
+
+/*!
+ \fn virtual QWidget* QDesignerWidgetFactoryInterface::containerOfWidget(QWidget *child) const = 0
+
+ Returns the widget that contains the specified \a child widget.
+*/
+
+/*!
+ \fn virtual QWidget* QDesignerWidgetFactoryInterface::widgetOfContainer(QWidget *container) const = 0
+
+
+*/
+
+/*!
+ \fn virtual QWidget *QDesignerWidgetFactoryInterface::createWidget(const QString &name, QWidget *parent) const = 0
+
+ Returns a new widget with the given \a name and \a parent widget. If no parent is specified,
+ the widget created will be a top-level widget.
+*/
+
+/*!
+ \fn virtual QLayout *QDesignerWidgetFactoryInterface::createLayout(QWidget *widget, QLayout *layout, int type) const = 0
+
+ Returns a new layout of the specified \a type for the given \a widget or \a layout.
+*/
+
+/*!
+ \fn virtual bool QDesignerWidgetFactoryInterface::isPassiveInteractor(QWidget *widget) = 0
+*/
+
+/*!
+ \fn virtual void QDesignerWidgetFactoryInterface::initialize(QObject *object) const = 0
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/abstractwidgetfactory.h b/src/designer/src/lib/sdk/abstractwidgetfactory.h
new file mode 100644
index 000000000..a5c2ab16d
--- /dev/null
+++ b/src/designer/src/lib/sdk/abstractwidgetfactory.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTWIDGETFACTORY_H
+#define ABSTRACTWIDGETFACTORY_H
+
+#include <QtDesigner/sdk_global.h>
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QWidget;
+class QLayout;
+
+class QDESIGNER_SDK_EXPORT QDesignerWidgetFactoryInterface: public QObject
+{
+ Q_OBJECT
+public:
+ QDesignerWidgetFactoryInterface(QObject *parent = 0);
+ virtual ~QDesignerWidgetFactoryInterface();
+
+ virtual QDesignerFormEditorInterface *core() const = 0;
+
+ virtual QWidget* containerOfWidget(QWidget *w) const = 0;
+ virtual QWidget* widgetOfContainer(QWidget *w) const = 0;
+
+ virtual QWidget *createWidget(const QString &name, QWidget *parentWidget = 0) const = 0;
+ virtual QLayout *createLayout(QWidget *widget, QLayout *layout, int type) const = 0;
+
+ virtual bool isPassiveInteractor(QWidget *widget) = 0;
+ virtual void initialize(QObject *object) const = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // ABSTRACTWIDGETFACTORY_H
diff --git a/src/designer/src/lib/sdk/dynamicpropertysheet.h b/src/designer/src/lib/sdk/dynamicpropertysheet.h
new file mode 100644
index 000000000..478f3a4a6
--- /dev/null
+++ b/src/designer/src/lib/sdk/dynamicpropertysheet.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef DYNAMICPROPERTYSHEET_H
+#define DYNAMICPROPERTYSHEET_H
+
+#include <QtDesigner/extension.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString; // FIXME: fool syncqt
+
+class QDesignerDynamicPropertySheetExtension
+{
+public:
+ virtual ~QDesignerDynamicPropertySheetExtension() {}
+
+ virtual bool dynamicPropertiesAllowed() const = 0;
+ virtual int addDynamicProperty(const QString &propertyName, const QVariant &value) = 0;
+ virtual bool removeDynamicProperty(int index) = 0;
+ virtual bool isDynamicProperty(int index) const = 0;
+ virtual bool canAddDynamicProperty(const QString &propertyName) const = 0;
+};
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerDynamicPropertySheetExtension, "com.trolltech.Qt.Designer.DynamicPropertySheet")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // DYNAMICPROPERTYSHEET_H
diff --git a/src/designer/src/lib/sdk/dynamicpropertysheet.qdoc b/src/designer/src/lib/sdk/dynamicpropertysheet.qdoc
new file mode 100644
index 000000000..e077e714d
--- /dev/null
+++ b/src/designer/src/lib/sdk/dynamicpropertysheet.qdoc
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QDesignerDynamicPropertySheetExtension
+
+ \brief The QDesignerDynamicPropertySheetExtension class allows you to
+ manipulate a widget's dynamic properties in Qt Designer's property editor.
+
+ \sa QDesignerPropertySheetExtension, {QObject#Dynamic Properties}{Dynamic Properties}
+
+ \inmodule QtDesigner
+ \since 4.3
+*/
+
+/*!
+ \fn QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension()
+
+ Destroys the dynamic property sheet extension.
+*/
+
+/*!
+ \fn bool QDesignerDynamicPropertySheetExtension::dynamicPropertiesAllowed() const
+
+ Returns true if the widget supports dynamic properties; otherwise returns false.
+*/
+
+/*!
+ \fn int QDesignerDynamicPropertySheetExtension::addDynamicProperty(const QString &propertyName, const QVariant &value)
+
+ Adds a dynamic property named \a propertyName and sets its value to \a value.
+ Returns the index of the property if it was added successfully; otherwise returns -1 to
+ indicate failure.
+*/
+
+/*!
+ \fn bool QDesignerDynamicPropertySheetExtension::removeDynamicProperty(int index)
+
+ Removes the dynamic property at the given \a index.
+ Returns true if the operation succeeds; otherwise returns false.
+*/
+
+/*!
+ \fn bool QDesignerDynamicPropertySheetExtension::isDynamicProperty(int index) const
+
+ Returns true if the property at the given \a index is a dynamic property; otherwise
+ returns false.
+*/
+
+/*!
+ \fn bool QDesignerDynamicPropertySheetExtension::canAddDynamicProperty(const QString &propertyName) const
+
+ Returns true if \a propertyName is a valid, unique name for a dynamic
+ property; otherwise returns false.
+
+*/
diff --git a/src/designer/src/lib/sdk/extrainfo.cpp b/src/designer/src/lib/sdk/extrainfo.cpp
new file mode 100644
index 000000000..9c272dc16
--- /dev/null
+++ b/src/designer/src/lib/sdk/extrainfo.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "extrainfo.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerExtraInfoExtension
+ \brief The QDesignerExtraInfoExtension class provides extra information about a widget in
+ Qt Designer.
+ \inmodule QtDesigner
+ \internal
+*/
+
+/*!
+ Returns the path to the working directory used by this extension.*/
+QString QDesignerExtraInfoExtension::workingDirectory() const
+{
+ return m_workingDirectory;
+}
+
+/*!
+ Sets the path to the working directory used by the extension to \a workingDirectory.*/
+void QDesignerExtraInfoExtension::setWorkingDirectory(const QString &workingDirectory)
+{
+ m_workingDirectory = workingDirectory;
+}
+
+/*!
+ \fn virtual QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension()
+
+ Destroys the extension.
+*/
+
+/*!
+ \fn virtual QDesignerFormEditorInterface *QDesignerExtraInfoExtension::core() const = 0
+
+ \omit
+ ### Description required
+ \endomit
+*/
+
+/*!
+ \fn virtual QWidget *QDesignerExtraInfoExtension::widget() const = 0
+
+ Returns the widget described by this extension.
+*/
+
+/*!
+ \fn virtual bool QDesignerExtraInfoExtension::saveUiExtraInfo(DomUI *ui) = 0
+
+ Saves the information about the user interface specified by \a ui, and returns true if
+ successful; otherwise returns false.
+*/
+
+/*!
+ \fn virtual bool QDesignerExtraInfoExtension::loadUiExtraInfo(DomUI *ui) = 0
+
+ Loads extra information about the user interface specified by \a ui, and returns true if
+ successful; otherwise returns false.
+*/
+
+/*!
+ \fn virtual bool QDesignerExtraInfoExtension::saveWidgetExtraInfo(DomWidget *widget) = 0
+
+ Saves the information about the specified \a widget, and returns true if successful;
+ otherwise returns false.
+*/
+
+/*!
+ \fn virtual bool QDesignerExtraInfoExtension::loadWidgetExtraInfo(DomWidget *widget) = 0
+
+ Loads extra information about the specified \a widget, and returns true if successful;
+ otherwise returns false.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/extrainfo.h b/src/designer/src/lib/sdk/extrainfo.h
new file mode 100644
index 000000000..10034e9a6
--- /dev/null
+++ b/src/designer/src/lib/sdk/extrainfo.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EXTRAINFO_H
+#define EXTRAINFO_H
+
+#include <QtDesigner/sdk_global.h>
+#include <QtDesigner/extension.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class DomWidget;
+class DomUI;
+class QWidget;
+
+class QDesignerFormEditorInterface;
+
+class QDESIGNER_SDK_EXPORT QDesignerExtraInfoExtension
+{
+public:
+ virtual ~QDesignerExtraInfoExtension() {}
+
+ virtual QDesignerFormEditorInterface *core() const = 0;
+ virtual QWidget *widget() const = 0;
+
+ virtual bool saveUiExtraInfo(DomUI *ui) = 0;
+ virtual bool loadUiExtraInfo(DomUI *ui) = 0;
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget) = 0;
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget) = 0;
+
+ QString workingDirectory() const;
+ void setWorkingDirectory(const QString &workingDirectory);
+
+private:
+ QString m_workingDirectory;
+};
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerExtraInfoExtension, "com.trolltech.Qt.Designer.ExtraInfo.2")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // EXTRAINFO_H
diff --git a/src/designer/src/lib/sdk/layoutdecoration.h b/src/designer/src/lib/sdk/layoutdecoration.h
new file mode 100644
index 000000000..4a6577059
--- /dev/null
+++ b/src/designer/src/lib/sdk/layoutdecoration.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LAYOUTDECORATION_H
+#define LAYOUTDECORATION_H
+
+#include <QtDesigner/extension.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QPair>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QPoint;
+class QLayoutItem;
+class QWidget;
+class QRect;
+class QLayout;
+
+class QDesignerLayoutDecorationExtension
+{
+public:
+ enum InsertMode
+ {
+ InsertWidgetMode,
+ InsertRowMode,
+ InsertColumnMode
+ };
+
+ virtual ~QDesignerLayoutDecorationExtension() {}
+
+ virtual QList<QWidget*> widgets(QLayout *layout) const = 0;
+
+ virtual QRect itemInfo(int index) const = 0;
+ virtual int indexOf(QWidget *widget) const = 0;
+ virtual int indexOf(QLayoutItem *item) const = 0;
+
+ virtual InsertMode currentInsertMode() const = 0;
+ virtual int currentIndex() const = 0;
+ virtual QPair<int, int> currentCell() const = 0;
+ virtual void insertWidget(QWidget *widget, const QPair<int, int> &cell) = 0;
+ virtual void removeWidget(QWidget *widget) = 0;
+
+ virtual void insertRow(int row) = 0;
+ virtual void insertColumn(int column) = 0;
+ virtual void simplify() = 0;
+
+ virtual int findItemAt(const QPoint &pos) const = 0;
+ virtual int findItemAt(int row, int column) const = 0; // atm only for grid.
+
+ virtual void adjustIndicator(const QPoint &pos, int index) = 0;
+};
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerLayoutDecorationExtension, "com.trolltech.Qt.Designer.LayoutDecoration")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // LAYOUTDECORATION_H
diff --git a/src/designer/src/lib/sdk/layoutdecoration.qdoc b/src/designer/src/lib/sdk/layoutdecoration.qdoc
new file mode 100644
index 000000000..9456e380d
--- /dev/null
+++ b/src/designer/src/lib/sdk/layoutdecoration.qdoc
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QDesignerLayoutDecorationExtension
+ \brief The QDesignerLayoutDecorationExtension class provides an extension to a layout in \QD.
+ \inmodule QtDesigner
+ \internal
+*/
+
+/*!
+ \enum QDesignerLayoutDecorationExtension::InsertMode
+
+ This enum describes the modes that are used to insert items into a layout.
+
+ \value InsertWidgetMode Widgets are inserted into empty cells in a layout.
+ \value InsertRowMode Whole rows are inserted into a vertical or grid layout.
+ \value InsertColumnMode Whole columns are inserted into a horizontal or grid layout.
+*/
+
+/*!
+ \fn virtual QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension()
+
+ Destroys the extension.
+*/
+
+/*!
+ \fn virtual QList<QWidget*> QDesignerLayoutDecorationExtension::widgets(QLayout *layout) const
+
+ Returns the widgets that are managed by the given \a layout.
+
+ \sa insertWidget(), removeWidget()
+*/
+
+/*!
+ \fn QRect QDesignerLayoutDecorationExtension::itemInfo(int index) const
+
+ Returns the rectangle covered by the item at the given \a index in the layout.
+*/
+
+/*!
+ \fn int QDesignerLayoutDecorationExtension::indexOf(QWidget *widget) const
+
+ Returns the index of the specified \a widget in the layout.
+*/
+
+/*!
+ \fn int QDesignerLayoutDecorationExtension::indexOf(QLayoutItem *item) const
+
+ Returns the index of the specified layout \a item.
+*/
+
+/*!
+ \fn QDesignerLayoutDecorationExtension::InsertMode QDesignerLayoutDecorationExtension::currentInsertMode() const
+
+ Returns the current insertion mode.
+*/
+
+/*!
+ \fn int QDesignerLayoutDecorationExtension::currentIndex() const
+
+ Returns the current index in the layout.
+*/
+
+/*!
+ \fn QPair<int, int> QDesignerLayoutDecorationExtension::currentCell() const
+
+ Returns a pair containing the row and column of the current cell in the layout.
+*/
+
+/*!
+ \fn void QDesignerLayoutDecorationExtension::insertWidget(QWidget *widget, const QPair<int, int> &cell)
+
+ Inserts the given \a widget into the specified \a cell in the layout.
+
+ \sa removeWidget()
+*/
+
+/*!
+ \fn void QDesignerLayoutDecorationExtension::removeWidget(QWidget *widget)
+
+ Removes the specified \a widget from the layout.
+
+ \sa insertWidget()
+*/
+
+/*!
+ \fn void QDesignerLayoutDecorationExtension::insertRow(int row)
+
+ Inserts a new row into the form at the position specified by \a row.
+*/
+
+/*!
+ \fn void QDesignerLayoutDecorationExtension::insertColumn(int column)
+
+ Inserts a new column into the form at the position specified by \a column.
+*/
+
+/*!
+ \fn void QDesignerLayoutDecorationExtension::simplify()
+
+ Simplifies the layout by removing unnecessary empty rows and columns, and by changing the
+ number of rows or columns spanned by widgets.
+*/
+
+/*!
+ \fn int QDesignerLayoutDecorationExtension::findItemAt(const QPoint &position) const
+
+ Returns the index of the item in the layout that covers the given \a position.
+*/
+
+/*!
+ \fn int QDesignerLayoutDecorationExtension::findItemAt(int row, int column) const
+
+ Returns the item in the layout that occupies the specified \a row and \a column in the layout.
+
+ Currently, this only applies to grid layouts.
+*/
+
+/*!
+ \fn void QDesignerLayoutDecorationExtension::adjustIndicator(const QPoint &position, int index)
+
+ Adjusts the indicator for the item specified by \a index so that
+ it lies at the given \a position on the form.
+*/
diff --git a/src/designer/src/lib/sdk/membersheet.h b/src/designer/src/lib/sdk/membersheet.h
new file mode 100644
index 000000000..b1ff1a4c6
--- /dev/null
+++ b/src/designer/src/lib/sdk/membersheet.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MEMBERSHEET_H
+#define MEMBERSHEET_H
+
+#include <QtDesigner/extension.h>
+
+#include <QtCore/QList>
+#include <QtCore/QByteArray>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString; // FIXME: fool syncqt
+
+class QDesignerMemberSheetExtension
+{
+public:
+ virtual ~QDesignerMemberSheetExtension() {}
+
+ virtual int count() const = 0;
+
+ virtual int indexOf(const QString &name) const = 0;
+
+ virtual QString memberName(int index) const = 0;
+ virtual QString memberGroup(int index) const = 0;
+ virtual void setMemberGroup(int index, const QString &group) = 0;
+
+ virtual bool isVisible(int index) const = 0;
+ virtual void setVisible(int index, bool b) = 0;
+
+ virtual bool isSignal(int index) const = 0;
+ virtual bool isSlot(int index) const = 0;
+
+ virtual bool inheritedFromWidget(int index) const = 0;
+
+ virtual QString declaredInClass(int index) const = 0;
+
+ virtual QString signature(int index) const = 0;
+ virtual QList<QByteArray> parameterTypes(int index) const = 0;
+ virtual QList<QByteArray> parameterNames(int index) const = 0;
+};
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerMemberSheetExtension, "com.trolltech.Qt.Designer.MemberSheet")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // MEMBERSHEET_H
diff --git a/src/designer/src/lib/sdk/membersheet.qdoc b/src/designer/src/lib/sdk/membersheet.qdoc
new file mode 100644
index 000000000..57a366407
--- /dev/null
+++ b/src/designer/src/lib/sdk/membersheet.qdoc
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QDesignerMemberSheetExtension
+
+ \brief The QDesignerMemberSheetExtension class allows you to
+ manipulate a widget's member functions which is displayed when
+ configuring connections using Qt Designer's mode for editing
+ signals and slots.
+
+ \inmodule QtDesigner
+
+ QDesignerMemberSheetExtension is a collection of functions that is
+ typically used to query a widget's member functions, and to
+ manipulate the member functions' appearance in \QD's signals and
+ slots editing mode. For example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 2
+
+ When implementing a custom widget plugin, a pointer to \QD's
+ current QDesignerFormEditorInterface object (\c formEditor in the
+ example above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's parameter.
+
+ The member sheet (and any other extension), can be retrieved by
+ querying \QD's extension manager using the qt_extension()
+ function. When you want to release the extension, you only need to
+ delete the pointer.
+
+ All widgets have a default member sheet used in \QD's signals and
+ slots editing mode with the widget's member functions. But
+ QDesignerMemberSheetExtension also provides an interface for
+ creating custom member sheet extensions.
+
+ \warning \QD uses the QDesignerMemberSheetExtension to facilitate
+ the signal and slot editing mode. Whenever a connection between
+ two widgets is requested, \QD will query for the widgets' member
+ sheet extensions. If a widget has an implemented member sheet
+ extension, this extension will override the default member sheet.
+
+ To create a member sheet extension, your extension class must
+ inherit from both QObject and QDesignerMemberSheetExtension. Then,
+ since we are implementing an interface, we must ensure that it's
+ made known to the meta object system using the Q_INTERFACES()
+ macro:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 3
+
+ This enables \QD to use qobject_cast() to query for
+ supported interfaces using nothing but a QObject pointer.
+
+ In \QD the extensions are not created until they are
+ required. For that reason, when implementing a member sheet
+ extension, you must also create a QExtensionFactory, i.e a class
+ that is able to make an instance of your extension, and register
+ it using \QD's \l {QExtensionManager}{extension manager}.
+
+ When a widget's member sheet extension is required, \QD's \l
+ {QExtensionManager}{extension manager} will run through all its
+ registered factories calling QExtensionFactory::createExtension()
+ for each until the first one that is able to create a member sheet
+ extension for that widget, is found. This factory will then make
+ an instance of the extension. If no such factory is found, \QD
+ will use the default member sheet.
+
+ There are four available types of extensions in \QD:
+ QDesignerContainerExtension, QDesignerMemberSheetExtension,
+ QDesignerPropertySheetExtension and
+ QDesignerTaskMenuExtension. \QD's behavior is the same whether the
+ requested extension is associated with a multi page container, a
+ member sheet, a property sheet or a task menu.
+
+ The QExtensionFactory class provides a standard extension
+ factory, and can also be used as an interface for custom
+ extension factories. You can either create a new
+ QExtensionFactory and reimplement the
+ QExtensionFactory::createExtension() function. For example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 4
+
+ Or you can use an existing factory, expanding the
+ QExtensionFactory::createExtension() function to make the factory
+ able to create a member sheet extension as well. For example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 5
+
+ For a complete example using an extension class, see \l
+ {designer/taskmenuextension}{Task Menu Extension example}. The
+ example shows how to create a custom widget plugin for Qt
+ Designer, and how to to use the QDesignerTaskMenuExtension class
+ to add custom items to \QD's task menu.
+
+ \sa QExtensionFactory, QExtensionManager, {Creating Custom Widget
+ Extensions}
+*/
+
+/*!
+ \fn QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension()
+
+ Destroys the member sheet extension.
+*/
+
+/*!
+ \fn int QDesignerMemberSheetExtension::count() const
+
+ Returns the extension's number of member functions.
+*/
+
+/*!
+ \fn int QDesignerMemberSheetExtension::indexOf(const QString &name) const
+
+ Returns the index of the member function specified by the given \a
+ name.
+
+ \sa memberName()
+*/
+
+/*!
+ \fn QString QDesignerMemberSheetExtension::memberName(int index) const
+
+ Returns the name of the member function with the given \a index.
+
+ \sa indexOf()
+*/
+
+/*!
+ \fn QString QDesignerMemberSheetExtension::memberGroup(int index) const
+
+ Returns the name of the member group specified for the function
+ with the given \a index.
+
+ \sa indexOf(), setMemberGroup()
+*/
+
+/*!
+ \fn void QDesignerMemberSheetExtension::setMemberGroup(int index, const QString &group)
+
+ Sets the member group of the member function with the given \a
+ index, to \a group.
+
+ \sa indexOf(), memberGroup()
+*/
+
+/*!
+ \fn bool QDesignerMemberSheetExtension::isVisible(int index) const
+
+ Returns true if the member function with the given \a index is
+ visible in \QD's signal and slot editor, otherwise false.
+
+ \sa indexOf(), setVisible()
+*/
+
+/*!
+ \fn void QDesignerMemberSheetExtension::setVisible(int index, bool visible)
+
+ If \a visible is true, the member function with the given \a index
+ is visible in \QD's signals and slots editing mode; otherwise the
+ member function is hidden.
+
+ \sa indexOf(), isVisible()
+*/
+
+/*!
+ \fn virtual bool QDesignerMemberSheetExtension::isSignal(int index) const
+
+ Returns true if the member function with the given \a index is a
+ signal, otherwise false.
+
+ \sa indexOf()
+*/
+
+/*!
+ \fn bool QDesignerMemberSheetExtension::isSlot(int index) const
+
+ Returns true if the member function with the given \a index is a
+ slot, otherwise false.
+
+ \sa indexOf()
+*/
+
+/*!
+ \fn bool QDesignerMemberSheetExtension::inheritedFromWidget(int index) const
+
+ Returns true if the member function with the given \a index is
+ inherited from QWidget, otherwise false.
+
+ \sa indexOf()
+*/
+
+/*!
+ \fn QString QDesignerMemberSheetExtension::declaredInClass(int index) const
+
+ Returns the name of the class in which the member function with
+ the given \a index is declared.
+
+ \sa indexOf()
+*/
+
+/*!
+ \fn QString QDesignerMemberSheetExtension::signature(int index) const
+
+ Returns the signature of the member function with the given \a
+ index.
+
+ \sa indexOf()
+*/
+
+/*!
+ \fn QList<QByteArray> QDesignerMemberSheetExtension::parameterTypes(int index) const
+
+ Returns the parameter types of the member function with the given
+ \a index, as a QByteArray list.
+
+ \sa indexOf(), parameterNames()
+*/
+
+/*!
+ \fn QList<QByteArray> QDesignerMemberSheetExtension::parameterNames(int index) const
+
+ Returns the parameter names of the member function with the given
+ \a index, as a QByteArray list.
+
+ \sa indexOf(), parameterTypes()
+*/
diff --git a/src/designer/src/lib/sdk/propertysheet.h b/src/designer/src/lib/sdk/propertysheet.h
new file mode 100644
index 000000000..36a0e4e1b
--- /dev/null
+++ b/src/designer/src/lib/sdk/propertysheet.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROPERTYSHEET_H
+#define PROPERTYSHEET_H
+
+#include <QtDesigner/extension.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QVariant;
+
+class QDesignerPropertySheetExtension
+{
+public:
+ virtual ~QDesignerPropertySheetExtension() {}
+
+ virtual int count() const = 0;
+
+ virtual int indexOf(const QString &name) const = 0;
+
+ virtual QString propertyName(int index) const = 0;
+ virtual QString propertyGroup(int index) const = 0;
+ virtual void setPropertyGroup(int index, const QString &group) = 0;
+
+ virtual bool hasReset(int index) const = 0;
+ virtual bool reset(int index) = 0;
+
+ virtual bool isVisible(int index) const = 0;
+ virtual void setVisible(int index, bool b) = 0;
+
+ virtual bool isAttribute(int index) const = 0;
+ virtual void setAttribute(int index, bool b) = 0;
+
+ virtual QVariant property(int index) const = 0;
+ virtual void setProperty(int index, const QVariant &value) = 0;
+
+ virtual bool isChanged(int index) const = 0;
+ virtual void setChanged(int index, bool changed) = 0;
+
+};
+
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerPropertySheetExtension,
+ "com.trolltech.Qt.Designer.PropertySheet")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // PROPERTYSHEET_H
diff --git a/src/designer/src/lib/sdk/propertysheet.qdoc b/src/designer/src/lib/sdk/propertysheet.qdoc
new file mode 100644
index 000000000..becc74b0e
--- /dev/null
+++ b/src/designer/src/lib/sdk/propertysheet.qdoc
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QDesignerPropertySheetExtension
+
+ \brief The QDesignerPropertySheetExtension class allows you to
+ manipulate a widget's properties which is displayed in Qt
+ Designer's property editor.
+
+ \sa QDesignerDynamicPropertySheetExtension
+
+ \inmodule QtDesigner
+
+ QDesignerPropertySheetExtension provides a collection of functions that
+ are typically used to query a widget's properties, and to
+ manipulate the properties' appearance in the property editor. For
+ example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 15
+
+ Note that if you change the value of a property using the
+ QDesignerPropertySheetExtension::setProperty() function, the undo
+ stack is not updated. To ensure that a property's value can be
+ reverted using the undo stack, you must use the
+ QDesignerFormWindowCursorInterface::setProperty() function, or its
+ buddy \l
+ {QDesignerFormWindowCursorInterface::setWidgetProperty()}{setWidgetProperty()},
+ instead.
+
+ When implementing a custom widget plugin, a pointer to \QD's
+ current QDesignerFormEditorInterface object (\c formEditor in the
+ example above) is provided by the
+ QDesignerCustomWidgetInterface::initialize() function's parameter.
+
+ The property sheet, or any other extension, can be retrieved by
+ querying \QD's extension manager using the qt_extension()
+ function. When you want to release the extension, you only need to
+ delete the pointer.
+
+ All widgets have a default property sheet which populates \QD's
+ property editor with the widget's properties (i.e the ones defined
+ with the Q_PROPERTY() macro). But QDesignerPropertySheetExtension
+ also provides an interface for creating custom property sheet
+ extensions.
+
+ \warning \QD uses the QDesignerPropertySheetExtension to feed its
+ property editor. Whenever a widget is selected in its workspace,
+ \QD will query for the widget's property sheet extension. If the
+ selected widget has an implemented property sheet extension, this
+ extension will override the default property sheet.
+
+ To create a property sheet extension, your extension class must
+ inherit from both QObject and
+ QDesignerPropertySheetExtension. Then, since we are implementing
+ an interface, we must ensure that it's made known to the meta
+ object system using the Q_INTERFACES() macro:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 16
+
+ This enables \QD to use qobject_cast() to query for supported
+ interfaces using nothing but a QObject pointer.
+
+ In \QD the extensions are not created until they are
+ required. For that reason, when implementing a property sheet
+ extension, you must also create a QExtensionFactory, i.e a class
+ that is able to make an instance of your extension, and register
+ it using \QD's \l {QExtensionManager}{extension manager}.
+
+ When a property sheet extension is required, \QD's \l
+ {QExtensionManager}{extension manager} will run through all its
+ registered factories calling QExtensionFactory::createExtension()
+ for each until the first one that is able to create a property
+ sheet extension for the selected widget, is found. This factory
+ will then make an instance of the extension. If no such factory
+ can be found, \QD will use the default property sheet.
+
+ There are four available types of extensions in \QD:
+ QDesignerContainerExtension, QDesignerMemberSheetExtension,
+ QDesignerPropertySheetExtension and QDesignerTaskMenuExtension. Qt
+ Designer's behavior is the same whether the requested extension is
+ associated with a multi page container, a member sheet, a property
+ sheet or a task menu.
+
+ The QExtensionFactory class provides a standard extension factory,
+ and can also be used as an interface for custom extension
+ factories. You can either create a new QExtensionFactory and
+ reimplement the QExtensionFactory::createExtension() function. For
+ example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 17
+
+ Or you can use an existing factory, expanding the
+ QExtensionFactory::createExtension() function to make the factory
+ able to create a property sheet extension extension as well. For
+ example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 18
+
+ For a complete example using an extension class, see the \l
+ {designer/taskmenuextension}{Task Menu Extension example}. The
+ example shows how to create a custom widget plugin for Qt
+ Designer, and how to to use the QDesignerTaskMenuExtension class
+ to add custom items to \QD's task menu.
+
+ \sa QExtensionFactory, QExtensionManager, {Creating Custom Widget
+ Extensions}
+*/
+
+/*!
+ \fn QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension()
+
+ Destroys the property sheet extension.
+*/
+
+/*!
+ \fn int QDesignerPropertySheetExtension::count() const
+
+ Returns the selected widget's number of properties.
+*/
+
+/*!
+ \fn int QDesignerPropertySheetExtension::indexOf(const QString &name) const
+
+ Returns the index for a given property \a name.
+
+ \sa propertyName()
+*/
+
+/*!
+ \fn QString QDesignerPropertySheetExtension::propertyName(int index) const
+
+ Returns the name of the property at the given \a index.
+
+ \sa indexOf()
+*/
+
+/*!
+ \fn QString QDesignerPropertySheetExtension::propertyGroup(int index) const
+
+ Returns the property group for the property at the given \a index.
+
+ \QD's property editor supports property groups, i.e. sections of
+ related properties. A property can be related to a group using the
+ setPropertyGroup() function. The default group of any property is
+ the name of the class that defines it. For example, the
+ QObject::objectName property appears within the QObject property
+ group.
+
+ \sa indexOf(), setPropertyGroup()
+*/
+
+/*!
+ \fn void QDesignerPropertySheetExtension::setPropertyGroup(int index, const QString &group)
+
+ Sets the property group for the property at the given \a index to
+ \a group.
+
+ Relating a property to a group makes it appear within that group's
+ section in the property editor. The default property group of any
+ property is the name of the class that defines it. For example,
+ the QObject::objectName property appears within the QObject
+ property group.
+
+ \sa indexOf(), property(), propertyGroup()
+*/
+
+/*!
+ \fn bool QDesignerPropertySheetExtension::hasReset(int index) const
+
+ Returns true if the property at the given \a index has a reset
+ button in \QD's property editor, otherwise false.
+
+ \sa indexOf(), reset()
+*/
+
+/*!
+ \fn bool QDesignerPropertySheetExtension::reset(int index)
+
+ Resets the value of the property at the given \a index, to the
+ default value. Returns true if a default value could be found, otherwise false.
+
+ \sa indexOf(), hasReset(), isChanged()
+*/
+
+/*!
+ \fn bool QDesignerPropertySheetExtension::isVisible(int index) const
+
+ Returns true if the property at the given \a index is visible in
+ \QD's property editor, otherwise false.
+
+ \sa indexOf(), setVisible()
+*/
+
+/*!
+ \fn void QDesignerPropertySheetExtension::setVisible(int index, bool visible)
+
+ If \a visible is true, the property at the given \a index is
+ visible in \QD's property editor; otherwise the property is
+ hidden.
+
+ \sa indexOf(), isVisible()
+*/
+
+/*!
+ \fn bool QDesignerPropertySheetExtension::isAttribute(int index) const
+
+ Returns true if the property at the given \a index is an attribute,
+ which will be \e excluded from the UI file, otherwise false.
+
+ \sa indexOf(), setAttribute()
+*/
+
+/*!
+ \fn void QDesignerPropertySheetExtension::setAttribute(int index, bool attribute)
+
+ If \a attribute is true, the property at the given \a index is
+ made an attribute which will be \e excluded from the UI file;
+ otherwise it will be included.
+
+ \sa indexOf(), isAttribute()
+*/
+
+/*!
+ \fn QVariant QDesignerPropertySheetExtension::property(int index) const
+
+ Returns the value of the property at the given \a index.
+
+ \sa indexOf(), setProperty(), propertyGroup()
+*/
+
+/*!
+ \fn void QDesignerPropertySheetExtension::setProperty(int index, const QVariant &value)
+
+ Sets the \a value of the property at the given \a index.
+
+ \warning If you change the value of a property using this
+ function, the undo stack is not updated. To ensure that a
+ property's value can be reverted using the undo stack, you must
+ use the QDesignerFormWindowCursorInterface::setProperty()
+ function, or its buddy \l
+ {QDesignerFormWindowCursorInterface::setWidgetProperty()}{setWidgetProperty()},
+ instead.
+
+ \sa indexOf(), property(), propertyGroup()
+*/
+
+/*!
+ \fn bool QDesignerPropertySheetExtension::isChanged(int index) const
+
+ Returns true if the value of the property at the given \a index
+ differs from the property's default value, otherwise false.
+
+ \sa indexOf(), setChanged(), reset()
+*/
+
+/*!
+ \fn void QDesignerPropertySheetExtension::setChanged(int index, bool changed)
+
+ Sets whether the property at the given \a index is different from
+ its default value, or not, depending on the \a changed parameter.
+
+ \sa indexOf(), isChanged()
+*/
diff --git a/src/designer/src/lib/sdk/script.cpp b/src/designer/src/lib/sdk/script.cpp
new file mode 100644
index 000000000..0723b6dcd
--- /dev/null
+++ b/src/designer/src/lib/sdk/script.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "script_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDesignerScriptExtension
+ \brief The QDesignerScriptExtension class allows you to generate a
+ per-widget \l{QtScript} {Qt Script} snippet to be executed while
+ building the form.
+
+ \internal
+ \inmodule QtDesigner
+ \since 4.3
+
+ On saving the form, the extension is queried for a script snippet
+ to be associated with the widget while saving the UI file.
+ This script is then run after creating the widget by \l uic or
+ QUiLoader.
+
+ As opposed to \l QDesignerCustomWidgetInterface::codeTemplate(),
+ it allows for applying an internal state of the widget
+ that can be manipulated using \QD.
+
+ Such a state might for example be the contents of a custom item view widget,
+ for which an editor is provided by the QDesignerTaskMenuExtension.
+
+ While saving the form, the state is serialized as a QVariantMap of
+ \QD-supported properties, which is stored in the UI file. This is
+ handled by data() and setData().
+
+ For item view contents, there might be for example a key that determines
+ the number of items and other keys that contain the actual items following
+ a naming scheme (\c numItems, \c item1, \c item2, ...).
+
+ On saving, script() is invoked, which should return a script snippet that
+ applies the state to the widget while building the form.
+
+ \sa {Creating Custom Widgets for Qt Designer#Using Qt Script to Aid in Building Forms}{Creating Custom Widgets for Qt Designer}, QtScript
+*/
+
+/*!
+ Destroys the extension.
+*/
+
+QDesignerScriptExtension::~QDesignerScriptExtension()
+{
+}
+
+/*!
+ \fn virtual QString QDesignerScriptExtension::script() const
+
+ Returns a script snippet to be associated with the widget.
+*/
+
+/*!
+ \fn virtual QVariantMap QDesignerScriptExtension::data() const
+
+ Returns a map of variants describing the internal state to be
+ stored in the UI file.
+*/
+
+/*!
+ \fn virtual void QDesignerScriptExtension::setData(const QVariantMap &data)
+
+ Applies the internal state stored in \a data to the widget while loading a form.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/sdk/script_p.h b/src/designer/src/lib/sdk/script_p.h
new file mode 100644
index 000000000..81b588ccb
--- /dev/null
+++ b/src/designer/src/lib/sdk/script_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SCRIPT_H
+#define SCRIPT_H
+
+#include <QtDesigner/sdk_global.h>
+#include <QtDesigner/extension.h>
+#include <QtCore/QVariant>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString; // FIXME: fool syncqt
+
+class QDESIGNER_SDK_EXPORT QDesignerScriptExtension
+{
+public:
+ virtual ~QDesignerScriptExtension();
+
+ virtual QVariantMap data() const = 0;
+ virtual void setData(const QVariantMap &data) = 0;
+
+ virtual QString script() const = 0;
+
+};
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerScriptExtension, "com.trolltech.Qt.Designer.Script")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // SCRIPT_H
diff --git a/src/designer/src/lib/sdk/sdk.pri b/src/designer/src/lib/sdk/sdk.pri
new file mode 100644
index 000000000..bc46a1edb
--- /dev/null
+++ b/src/designer/src/lib/sdk/sdk.pri
@@ -0,0 +1,58 @@
+# Input
+
+INCLUDEPATH += $$PWD
+
+HEADERS += $$PWD/abstractformeditor.h \
+ $$PWD/abstractintrospection_p.h \
+ $$PWD/abstractsettings_p.h \
+ $$PWD/abstractformeditorplugin.h \
+ $$PWD/abstractresourcebrowser.h \
+ $$PWD/abstractintegration.h \
+ $$PWD/abstractpropertyeditor.h \
+ $$PWD/abstractformwindow.h \
+ $$PWD/abstractformwindowtool.h \
+ $$PWD/abstractformwindowcursor.h \
+ $$PWD/abstractformwindowmanager.h \
+ $$PWD/abstractwidgetdatabase.h \
+ $$PWD/abstractmetadatabase.h \
+ $$PWD/abstractwidgetfactory.h \
+ $$PWD/abstractobjectinspector.h \
+ $$PWD/abstractactioneditor.h \
+ $$PWD/abstractbrushmanager.h \
+ $$PWD/abstracticoncache.h \
+ $$PWD/abstractlanguage.h \
+ $$PWD/abstractoptionspage_p.h \
+ $$PWD/propertysheet.h \
+ $$PWD/dynamicpropertysheet.h \
+ $$PWD/membersheet.h \
+ $$PWD/taskmenu.h \
+ $$PWD/extrainfo.h \
+ $$PWD/abstractwidgetbox.h \
+ $$PWD/layoutdecoration.h \
+ $$PWD/abstractdnditem.h \
+ $$PWD/abstractpromotioninterface.h \
+ $$PWD/abstractdialoggui_p.h \
+ $$PWD/script_p.h \
+ $$PWD/abstractnewformwidget_p.h
+
+SOURCES += $$PWD/abstractformeditor.cpp \
+ $$PWD/abstractintrospection.cpp \
+ $$PWD/abstractformeditorplugin.cpp \
+ $$PWD/abstractresourcebrowser.cpp \
+ $$PWD/abstractintegration.cpp \
+ $$PWD/abstractpropertyeditor.cpp \
+ $$PWD/abstractformwindow.cpp \
+ $$PWD/abstractformwindowtool.cpp \
+ $$PWD/abstractformwindowcursor.cpp \
+ $$PWD/abstractformwindowmanager.cpp \
+ $$PWD/abstractwidgetdatabase.cpp \
+ $$PWD/abstractmetadatabase.cpp \
+ $$PWD/abstractwidgetfactory.cpp \
+ $$PWD/abstractobjectinspector.cpp \
+ $$PWD/abstractactioneditor.cpp \
+ $$PWD/abstractwidgetbox.cpp \
+ $$PWD/extrainfo.cpp \
+ $$PWD/abstractpromotioninterface.cpp \
+ $$PWD/abstractdialoggui.cpp \
+ $$PWD/script.cpp \
+ $$PWD/abstractnewformwidget.cpp
diff --git a/src/designer/src/lib/sdk/sdk_global.h b/src/designer/src/lib/sdk/sdk_global.h
new file mode 100644
index 000000000..b2a0f5767
--- /dev/null
+++ b/src/designer/src/lib/sdk/sdk_global.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SDK_GLOBAL_H
+#define SDK_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+#define QDESIGNER_SDK_EXTERN Q_DECL_EXPORT
+#define QDESIGNER_SDK_IMPORT Q_DECL_IMPORT
+
+#ifdef QT_DESIGNER_STATIC
+# define QDESIGNER_SDK_EXPORT
+#elif defined(QDESIGNER_SDK_LIBRARY)
+# define QDESIGNER_SDK_EXPORT QDESIGNER_SDK_EXTERN
+#else
+# define QDESIGNER_SDK_EXPORT QDESIGNER_SDK_IMPORT
+#endif
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // SDK_GLOBAL_H
diff --git a/src/designer/src/lib/sdk/taskmenu.h b/src/designer/src/lib/sdk/taskmenu.h
new file mode 100644
index 000000000..94db7bc26
--- /dev/null
+++ b/src/designer/src/lib/sdk/taskmenu.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TASKMENU_H
+#define TASKMENU_H
+
+#include <QtDesigner/extension.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+
+class QDesignerTaskMenuExtension
+{
+public:
+ virtual ~QDesignerTaskMenuExtension() {}
+
+ virtual QAction *preferredEditAction() const;
+
+ virtual QList<QAction*> taskActions() const = 0;
+};
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerTaskMenuExtension, "com.trolltech.Qt.Designer.TaskMenu")
+
+
+inline QAction *QDesignerTaskMenuExtension::preferredEditAction() const
+{ return 0; }
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // TASKMENU_H
diff --git a/src/designer/src/lib/sdk/taskmenu.qdoc b/src/designer/src/lib/sdk/taskmenu.qdoc
new file mode 100644
index 000000000..c5a379539
--- /dev/null
+++ b/src/designer/src/lib/sdk/taskmenu.qdoc
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QDesignerTaskMenuExtension
+ \brief The QDesignerTaskMenuExtension class allows you to add custom
+ menu entries to Qt Designer's task menu.
+ \inmodule QtDesigner
+
+ QDesignerTaskMenuExtension provides an interface for creating
+ custom task menu extensions. It is typically used to create task
+ menu entries that are specific to a plugin in \QD.
+
+ \QD uses the QDesignerTaskMenuExtension to feed its task
+ menu. Whenever a task menu is requested, \QD will query
+ for the selected widget's task menu extension.
+
+ \image taskmenuextension-example-faded.png
+
+ A task menu extension is a collection of QActions. The actions
+ appear as entries in the task menu when the plugin with the
+ specified extension is selected. The image above shows the custom
+ \gui {Edit State...} action which appears in addition to \QD's
+ default task menu entries: \gui Cut, \gui Copy, \gui Paste etc.
+
+ To create a custom task menu extension, your extension class must
+ inherit from both QObject and QDesignerTaskMenuExtension. For
+ example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 9
+
+ Since we are implementing an interface, we must ensure that it
+ is made known to the meta-object system using the Q_INTERFACES()
+ macro. This enables \QD to use the qobject_cast() function to
+ query for supported interfaces using nothing but a QObject
+ pointer.
+
+ You must reimplement the taskActions() function to return a list
+ of actions that will be included in \QD task menu. Optionally, you
+ can reimplement the preferredEditAction() function to set the
+ action that is invoked when selecting your plugin and pressing
+ \key F2. The preferred edit action must be one of the actions
+ returned by taskActions() and, if it's not defined, pressing the
+ \key F2 key will simply be ignored.
+
+ In \QD, extensions are not created until they are required. A
+ task menu extension, for example, is created when you click the
+ right mouse button over a widget in \QD's workspace. For that
+ reason you must also construct an extension factory, using either
+ QExtensionFactory or a subclass, and register it using \QD's
+ \l {QExtensionManager}{extension manager}.
+
+ When a task menu extension is required, \QD's \l
+ {QExtensionManager}{extension manager} will run through all its
+ registered factories calling QExtensionFactory::createExtension()
+ for each until it finds one that is able to create a task menu
+ extension for the selected widget. This factory will then make an
+ instance of the extension.
+
+ There are four available types of extensions in \QD:
+ QDesignerContainerExtension, QDesignerMemberSheetExtension,
+ QDesignerPropertySheetExtension, and QDesignerTaskMenuExtension.
+ \QD's behavior is the same whether the requested extension is
+ associated with a container, a member sheet, a property sheet or a
+ task menu.
+
+ The QExtensionFactory class provides a standard extension factory,
+ and can also be used as an interface for custom extension
+ factories. You can either create a new QExtensionFactory and
+ reimplement the QExtensionFactory::createExtension() function. For
+ example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 10
+
+ Or you can use an existing factory, expanding the
+ QExtensionFactory::createExtension() function to make the factory
+ able to create a task menu extension as well. For example:
+
+ \snippet doc/src/snippets/code/doc_src_qtdesigner.cpp 11
+
+ For a complete example using the QDesignerTaskMenuExtension class,
+ see the \l {designer/taskmenuextension}{Task Menu Extension
+ example}. The example shows how to create a custom widget plugin
+ for \QD, and how to to use the QDesignerTaskMenuExtension
+ class to add custom items to \QD's task menu.
+
+ \sa QExtensionFactory, QExtensionManager, {Creating Custom Widget
+ Extensions}
+*/
+
+/*!
+ \fn QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension()
+
+ Destroys the task menu extension.
+*/
+
+/*!
+ \fn QAction *QDesignerTaskMenuExtension::preferredEditAction() const
+
+ Returns the action that is invoked when selecting a plugin with
+ the specified extension and pressing \key F2.
+
+ The action must be one of the actions returned by taskActions().
+*/
+
+/*!
+ \fn QList<QAction*> QDesignerTaskMenuExtension::taskActions() const
+
+ Returns the task menu extension as a list of actions which will be
+ included in \QD's task menu when a plugin with the specified
+ extension is selected.
+
+ The function must be reimplemented to add actions to the list.
+*/
diff --git a/src/designer/src/lib/shared/actioneditor.cpp b/src/designer/src/lib/shared/actioneditor.cpp
new file mode 100644
index 000000000..fb882c30b
--- /dev/null
+++ b/src/designer/src/lib/shared/actioneditor.cpp
@@ -0,0 +1,823 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "actioneditor_p.h"
+#include "filterwidget_p.h"
+#include "actionrepository_p.h"
+#include "iconloader_p.h"
+#include "newactiondialog_p.h"
+#include "qdesigner_menu_p.h"
+#include "qdesigner_command_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "qdesigner_objectinspector_p.h"
+#include "qdesigner_utils_p.h"
+#include "qsimpleresource_p.h"
+#include "formwindowbase_p.h"
+#include "qdesigner_taskmenu_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/private/abstractsettings_p.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QToolBar>
+#include <QtGui/QSplitter>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
+#include <QtGui/QItemDelegate>
+#include <QtGui/QPainter>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+#include <QtGui/QToolButton>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QItemSelection>
+
+#include <QtCore/QRegExp>
+#include <QtCore/QDebug>
+#include <QtCore/QSignalMapper>
+#include <QtCore/QBuffer>
+
+Q_DECLARE_METATYPE(QAction*)
+
+QT_BEGIN_NAMESPACE
+
+static const char *actionEditorViewModeKey = "ActionEditorViewMode";
+
+static const char *iconPropertyC = "icon";
+static const char *shortcutPropertyC = "shortcut";
+static const char *toolTipPropertyC = "toolTip";
+static const char *checkablePropertyC = "checkable";
+static const char *objectNamePropertyC = "objectName";
+static const char *textPropertyC = "text";
+
+namespace qdesigner_internal {
+//-------- ActionGroupDelegate
+class ActionGroupDelegate: public QItemDelegate
+{
+public:
+ ActionGroupDelegate(QObject *parent)
+ : QItemDelegate(parent) {}
+
+ virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+ {
+ if (option.state & QStyle::State_Selected)
+ painter->fillRect(option.rect, option.palette.highlight());
+
+ QItemDelegate::paint(painter, option, index);
+ }
+
+ virtual void drawFocus(QPainter * /*painter*/, const QStyleOptionViewItem &/*option*/, const QRect &/*rect*/) const {}
+};
+
+//-------- ActionEditor
+ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags) :
+ QDesignerActionEditorInterface(parent, flags),
+ m_core(core),
+ m_actionGroups(0),
+ m_actionView(new ActionView),
+ m_actionNew(new QAction(tr("New..."), this)),
+ m_actionEdit(new QAction(tr("Edit..."), this)),
+ m_actionNavigateToSlot(new QAction(tr("Go to slot..."), this)),
+ m_actionCopy(new QAction(tr("Copy"), this)),
+ m_actionCut(new QAction(tr("Cut"), this)),
+ m_actionPaste(new QAction(tr("Paste"), this)),
+ m_actionSelectAll(new QAction(tr("Select all"), this)),
+ m_actionDelete(new QAction(tr("Delete"), this)),
+ m_viewModeGroup(new QActionGroup(this)),
+ m_iconViewAction(0),
+ m_listViewAction(0),
+ m_filterWidget(0),
+ m_selectAssociatedWidgetsMapper(0)
+{
+ m_actionView->initialize(m_core);
+ m_actionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ setWindowTitle(tr("Actions"));
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+
+ QToolBar *toolbar = new QToolBar;
+ toolbar->setIconSize(QSize(22, 22));
+ toolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+ l->addWidget(toolbar);
+ // edit actions
+ QIcon documentNewIcon = QIcon::fromTheme("document-new", createIconSet(QLatin1String("filenew.png")));
+ m_actionNew->setIcon(documentNewIcon);
+ m_actionNew->setEnabled(false);
+ connect(m_actionNew, SIGNAL(triggered()), this, SLOT(slotNewAction()));
+ toolbar->addAction(m_actionNew);
+
+ connect(m_actionSelectAll, SIGNAL(triggered()), m_actionView, SLOT(selectAll()));
+
+ m_actionCut->setEnabled(false);
+ connect(m_actionCut, SIGNAL(triggered()), this, SLOT(slotCut()));
+ QIcon editCutIcon = QIcon::fromTheme("edit-cut", createIconSet(QLatin1String("editcut.png")));
+ m_actionCut->setIcon(editCutIcon);
+
+ m_actionCopy->setEnabled(false);
+ connect(m_actionCopy, SIGNAL(triggered()), this, SLOT(slotCopy()));
+ QIcon editCopyIcon = QIcon::fromTheme("edit-copy", createIconSet(QLatin1String("editcopy.png")));
+ m_actionCopy->setIcon(editCopyIcon);
+ toolbar->addAction(m_actionCopy);
+
+ connect(m_actionPaste, SIGNAL(triggered()), this, SLOT(slotPaste()));
+ QIcon editPasteIcon = QIcon::fromTheme("edit-paste", createIconSet(QLatin1String("editpaste.png")));
+ m_actionPaste->setIcon(editPasteIcon);
+ toolbar->addAction(m_actionPaste);
+
+ m_actionEdit->setEnabled(false);
+ connect(m_actionEdit, SIGNAL(triggered()), this, SLOT(editCurrentAction()));
+
+ connect(m_actionNavigateToSlot, SIGNAL(triggered()), this, SLOT(navigateToSlotCurrentAction()));
+
+ QIcon editDeleteIcon = QIcon::fromTheme("edit-delete", createIconSet(QLatin1String("editdelete.png")));
+ m_actionDelete->setIcon(editDeleteIcon);
+ m_actionDelete->setEnabled(false);
+ connect(m_actionDelete, SIGNAL(triggered()), this, SLOT(slotDelete()));
+ toolbar->addAction(m_actionDelete);
+
+ // Toolbutton with menu containing action group for detailed/icon view. Steal the icons from the file dialog.
+ //
+ QMenu *configureMenu;
+ toolbar->addWidget(createConfigureMenuButton(tr("Configure Action Editor"), &configureMenu));
+
+ connect(m_viewModeGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotViewMode(QAction*)));
+ m_iconViewAction = m_viewModeGroup->addAction(tr("Icon View"));
+ m_iconViewAction->setData(QVariant(ActionView::IconView));
+ m_iconViewAction->setCheckable(true);
+ m_iconViewAction->setIcon(style()->standardIcon (QStyle::SP_FileDialogListView));
+ configureMenu->addAction(m_iconViewAction);
+
+ m_listViewAction = m_viewModeGroup->addAction(tr("Detailed View"));
+ m_listViewAction->setData(QVariant(ActionView::DetailedView));
+ m_listViewAction->setCheckable(true);
+ m_listViewAction->setIcon(style()->standardIcon (QStyle::SP_FileDialogDetailedView));
+ configureMenu->addAction(m_listViewAction);
+ // filter
+ m_filterWidget = new FilterWidget(toolbar);
+ connect(m_filterWidget, SIGNAL(filterChanged(QString)), this, SLOT(setFilter(QString)));
+ m_filterWidget->setEnabled(false);
+ toolbar->addWidget(m_filterWidget);
+
+ // main layout
+ QSplitter *splitter = new QSplitter(Qt::Horizontal);
+ splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ splitter->addWidget(m_actionView);
+ l->addWidget(splitter);
+
+#if 0 // ### implement me
+ m_actionGroups = new QListWidget(splitter);
+ splitter->addWidget(m_actionGroups);
+ m_actionGroups->setItemDelegate(new ActionGroupDelegate(m_actionGroups));
+ m_actionGroups->setMovement(QListWidget::Static);
+ m_actionGroups->setResizeMode(QListWidget::Fixed);
+ m_actionGroups->setIconSize(QSize(48, 48));
+ m_actionGroups->setFlow(QListWidget::TopToBottom);
+ m_actionGroups->setViewMode(QListWidget::IconMode);
+ m_actionGroups->setWrapping(false);
+#endif
+
+ connect(m_actionView, SIGNAL(resourceImageDropped(QString,QAction*)),
+ this, SLOT(resourceImageDropped(QString,QAction*)));
+
+ connect(m_actionView, SIGNAL(currentChanged(QAction*)),this, SLOT(slotCurrentItemChanged(QAction*)));
+ // make it possible for vs integration to reimplement edit action dialog
+ connect(m_actionView, SIGNAL(activated(QAction*)), this, SIGNAL(itemActivated(QAction*)));
+
+ connect(m_actionView,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
+
+ connect(m_actionView, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)),
+ this, SLOT(slotContextMenuRequested(QContextMenuEvent*,QAction*)));
+
+ connect(this, SIGNAL(itemActivated(QAction*)), this, SLOT(editAction(QAction*)));
+
+ restoreSettings();
+ updateViewModeActions();
+}
+
+// Utility to create a configure button with menu for usage on toolbars
+QToolButton *ActionEditor::createConfigureMenuButton(const QString &t, QMenu **ptrToMenu)
+{
+ QToolButton *configureButton = new QToolButton;
+ QAction *configureAction = new QAction(t, configureButton);
+ QIcon configureIcon = QIcon::fromTheme("document-properties", createIconSet(QLatin1String("configure.png")));
+ configureAction->setIcon(configureIcon);
+ QMenu *configureMenu = new QMenu;
+ configureAction->setMenu(configureMenu);
+ configureButton->setDefaultAction(configureAction);
+ configureButton->setPopupMode(QToolButton::InstantPopup);
+ *ptrToMenu = configureMenu;
+ return configureButton;
+}
+
+ActionEditor::~ActionEditor()
+{
+ saveSettings();
+}
+
+QAction *ActionEditor::actionNew() const
+{
+ return m_actionNew;
+}
+
+QAction *ActionEditor::actionDelete() const
+{
+ return m_actionDelete;
+}
+
+QDesignerFormWindowInterface *ActionEditor::formWindow() const
+{
+ return m_formWindow;
+}
+
+void ActionEditor::setFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ if (formWindow != 0 && formWindow->mainContainer() == 0)
+ formWindow = 0;
+
+ // we do NOT rely on this function to update the action editor
+ if (m_formWindow == formWindow)
+ return;
+
+ if (m_formWindow != 0) {
+ const ActionList actionList = m_formWindow->mainContainer()->findChildren<QAction*>();
+ foreach (QAction *action, actionList)
+ disconnect(action, SIGNAL(changed()), this, SLOT(slotActionChanged()));
+ }
+
+ m_formWindow = formWindow;
+
+ m_actionView->model()->clearActions();
+
+ m_actionEdit->setEnabled(false);
+ m_actionCopy->setEnabled(false);
+ m_actionCut->setEnabled(false);
+ m_actionDelete->setEnabled(false);
+
+ if (!formWindow || !formWindow->mainContainer()) {
+ m_actionNew->setEnabled(false);
+ m_filterWidget->setEnabled(false);
+ return;
+ }
+
+ m_actionNew->setEnabled(true);
+ m_filterWidget->setEnabled(true);
+
+ const ActionList actionList = formWindow->mainContainer()->findChildren<QAction*>();
+ foreach (QAction *action, actionList)
+ if (!action->isSeparator() && core()->metaDataBase()->item(action) != 0) {
+ // Show unless it has a menu. However, listen for change on menu actions also as it might be removed
+ if (!action->menu())
+ m_actionView->model()->addAction(action);
+ connect(action, SIGNAL(changed()), this, SLOT(slotActionChanged()));
+ }
+
+ setFilter(m_filter);
+}
+
+void ActionEditor::slotSelectionChanged(const QItemSelection& selected, const QItemSelection& /*deselected*/)
+{
+ const bool hasSelection = !selected.indexes().empty();
+ m_actionCopy->setEnabled(hasSelection);
+ m_actionCut->setEnabled(hasSelection);
+ m_actionDelete->setEnabled(hasSelection);
+}
+
+void ActionEditor::slotCurrentItemChanged(QAction *action)
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+
+ const bool hasCurrentAction = action != 0;
+ m_actionEdit->setEnabled(hasCurrentAction);
+
+ if (!action) {
+ fw->clearSelection();
+ return;
+ }
+
+ QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector());
+
+ if (action->associatedWidgets().empty()) {
+ // Special case: action not in object tree. Deselect all and set in property editor
+ fw->clearSelection(false);
+ if (oi)
+ oi->clearSelection();
+ core()->propertyEditor()->setObject(action);
+ } else {
+ if (oi)
+ oi->selectObject(action);
+ }
+}
+
+void ActionEditor::slotActionChanged()
+{
+ QAction *action = qobject_cast<QAction*>(sender());
+ Q_ASSERT(action != 0);
+
+ ActionModel *model = m_actionView->model();
+ const int row = model->findAction(action);
+ if (row == -1) {
+ if (action->menu() == 0) // action got its menu deleted, create item
+ model->addAction(action);
+ } else if (action->menu() != 0) { // action got its menu created, remove item
+ model->removeRow(row);
+ } else {
+ // action text or icon changed, update item
+ model->update(row);
+ }
+}
+
+QDesignerFormEditorInterface *ActionEditor::core() const
+{
+ return m_core;
+}
+
+QString ActionEditor::filter() const
+{
+ return m_filter;
+}
+
+void ActionEditor::setFilter(const QString &f)
+{
+ m_filter = f;
+ m_actionView->filter(m_filter);
+}
+
+// Set changed state of icon property, reset when icon is cleared
+static void refreshIconPropertyChanged(const QAction *action, QDesignerPropertySheetExtension *sheet)
+{
+ sheet->setChanged(sheet->indexOf(QLatin1String(iconPropertyC)), !action->icon().isNull());
+}
+
+void ActionEditor::manageAction(QAction *action)
+{
+ action->setParent(formWindow()->mainContainer());
+ core()->metaDataBase()->add(action);
+
+ if (action->isSeparator() || action->menu() != 0)
+ return;
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
+ sheet->setChanged(sheet->indexOf(QLatin1String(objectNamePropertyC)), true);
+ sheet->setChanged(sheet->indexOf(QLatin1String(textPropertyC)), true);
+ refreshIconPropertyChanged(action, sheet);
+
+ m_actionView->setCurrentIndex(m_actionView->model()->addAction(action));
+ connect(action, SIGNAL(changed()), this, SLOT(slotActionChanged()));
+}
+
+void ActionEditor::unmanageAction(QAction *action)
+{
+ core()->metaDataBase()->remove(action);
+ action->setParent(0);
+
+ disconnect(action, SIGNAL(changed()), this, SLOT(slotActionChanged()));
+
+ const int row = m_actionView->model()->findAction(action);
+ if (row != -1)
+ m_actionView->model()->remove(row);
+}
+
+// Set an initial property and mark it as changed in the sheet
+static void setInitialProperty(QDesignerPropertySheetExtension *sheet, const QString &name, const QVariant &value)
+{
+ const int index = sheet->indexOf(name);
+ Q_ASSERT(index != -1);
+ sheet->setProperty(index, value);
+ sheet->setChanged(index, true);
+}
+
+void ActionEditor::slotNewAction()
+{
+ NewActionDialog dlg(this);
+ dlg.setWindowTitle(tr("New action"));
+
+ if (dlg.exec() == QDialog::Accepted) {
+ const ActionData actionData = dlg.actionData();
+ m_actionView->clearSelection();
+ QAction *action = new QAction(formWindow());
+ action->setObjectName(actionData.name);
+ formWindow()->ensureUniqueObjectName(action);
+ action->setText(actionData.text);
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
+ if (!actionData.toolTip.isEmpty())
+ setInitialProperty(sheet, QLatin1String(toolTipPropertyC), actionData.toolTip);
+
+ if (actionData.checkable)
+ setInitialProperty(sheet, QLatin1String(checkablePropertyC), QVariant(true));
+
+ if (!actionData.keysequence.value().isEmpty())
+ setInitialProperty(sheet, QLatin1String(shortcutPropertyC), QVariant::fromValue(actionData.keysequence));
+
+ sheet->setProperty(sheet->indexOf(QLatin1String(iconPropertyC)), QVariant::fromValue(actionData.icon));
+
+ AddActionCommand *cmd = new AddActionCommand(formWindow());
+ cmd->init(action);
+ formWindow()->commandHistory()->push(cmd);
+ }
+}
+
+static inline bool isSameIcon(const QIcon &i1, const QIcon &i2)
+{
+ return i1.serialNumber() == i2.serialNumber();
+}
+
+// return a FormWindow command to apply an icon or a reset command in case it
+// is empty.
+
+static QDesignerFormWindowCommand *setIconPropertyCommand(const PropertySheetIconValue &newIcon, QAction *action, QDesignerFormWindowInterface *fw)
+{
+ const QString iconProperty = QLatin1String(iconPropertyC);
+ if (newIcon.isEmpty()) {
+ ResetPropertyCommand *cmd = new ResetPropertyCommand(fw);
+ cmd->init(action, iconProperty);
+ return cmd;
+ }
+ SetPropertyCommand *cmd = new SetPropertyCommand(fw);
+ cmd->init(action, iconProperty, QVariant::fromValue(newIcon));
+ return cmd;
+}
+
+// return a FormWindow command to apply a QKeySequence or a reset command
+// in case it is empty.
+
+static QDesignerFormWindowCommand *setKeySequencePropertyCommand(const PropertySheetKeySequenceValue &ks, QAction *action, QDesignerFormWindowInterface *fw)
+{
+ const QString shortcutProperty = QLatin1String(shortcutPropertyC);
+ if (ks.value().isEmpty()) {
+ ResetPropertyCommand *cmd = new ResetPropertyCommand(fw);
+ cmd->init(action, shortcutProperty);
+ return cmd;
+ }
+ SetPropertyCommand *cmd = new SetPropertyCommand(fw);
+ cmd->init(action, shortcutProperty, QVariant::fromValue(ks));
+ return cmd;
+}
+
+// return a FormWindow command to apply a POD value or reset command in case
+// it is equal to the default value.
+
+template <class T>
+QDesignerFormWindowCommand *setPropertyCommand(const QString &name, T value, T defaultValue,
+ QObject *o, QDesignerFormWindowInterface *fw)
+{
+ if (value == defaultValue) {
+ ResetPropertyCommand *cmd = new ResetPropertyCommand(fw);
+ cmd->init(o, name);
+ return cmd;
+ }
+ SetPropertyCommand *cmd = new SetPropertyCommand(fw);
+ cmd->init(o, name, QVariant(value));
+ return cmd;
+}
+
+// Return the text value of a string property via PropertySheetStringValue
+static inline QString textPropertyValue(const QDesignerPropertySheetExtension *sheet, const QString &name)
+{
+ const int index = sheet->indexOf(name);
+ Q_ASSERT(index != -1);
+ const PropertySheetStringValue ps = qvariant_cast<PropertySheetStringValue>(sheet->property(index));
+ return ps.value();
+}
+
+void ActionEditor::editAction(QAction *action)
+{
+ if (!action)
+ return;
+
+ NewActionDialog dlg(this);
+ dlg.setWindowTitle(tr("Edit action"));
+
+ ActionData oldActionData;
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
+ oldActionData.name = action->objectName();
+ oldActionData.text = action->text();
+ oldActionData.toolTip = textPropertyValue(sheet, QLatin1String(toolTipPropertyC));
+ oldActionData.icon = qvariant_cast<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String(iconPropertyC))));
+ oldActionData.keysequence = ActionModel::actionShortCut(sheet);
+ oldActionData.checkable = action->isCheckable();
+ dlg.setActionData(oldActionData);
+
+ if (!dlg.exec())
+ return;
+
+ // figure out changes and whether to start a macro
+ const ActionData newActionData = dlg.actionData();
+ const unsigned changeMask = newActionData.compare(oldActionData);
+ if (changeMask == 0u)
+ return;
+
+ const bool severalChanges = (changeMask != ActionData::TextChanged) && (changeMask != ActionData::NameChanged)
+ && (changeMask != ActionData::ToolTipChanged) && (changeMask != ActionData::IconChanged)
+ && (changeMask != ActionData::CheckableChanged) && (changeMask != ActionData::KeysequenceChanged);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ QUndoStack *undoStack = fw->commandHistory();
+ if (severalChanges)
+ fw->beginCommand(QLatin1String("Edit action"));
+
+ if (changeMask & ActionData::NameChanged)
+ undoStack->push(createTextPropertyCommand(QLatin1String(objectNamePropertyC), newActionData.name, action, fw));
+
+ if (changeMask & ActionData::TextChanged)
+ undoStack->push(createTextPropertyCommand(QLatin1String(textPropertyC), newActionData.text, action, fw));
+
+ if (changeMask & ActionData::ToolTipChanged)
+ undoStack->push(createTextPropertyCommand(QLatin1String(toolTipPropertyC), newActionData.toolTip, action, fw));
+
+ if (changeMask & ActionData::IconChanged)
+ undoStack->push(setIconPropertyCommand(newActionData.icon, action, fw));
+
+ if (changeMask & ActionData::CheckableChanged)
+ undoStack->push(setPropertyCommand(QLatin1String(checkablePropertyC), newActionData.checkable, false, action, fw));
+
+ if (changeMask & ActionData::KeysequenceChanged)
+ undoStack->push(setKeySequencePropertyCommand(newActionData.keysequence, action, fw));
+
+ if (severalChanges)
+ fw->endCommand();
+}
+
+void ActionEditor::editCurrentAction()
+{
+ if (QAction *a = m_actionView->currentAction())
+ editAction(a);
+}
+
+void ActionEditor::navigateToSlotCurrentAction()
+{
+ if (QAction *a = m_actionView->currentAction())
+ QDesignerTaskMenu::navigateToSlot(m_core, a, QLatin1String("triggered()"));
+}
+
+void ActionEditor::deleteActions(QDesignerFormWindowInterface *fw, const ActionList &actions)
+{
+ // We need a macro even in the case of single action because the commands might cause the
+ // scheduling of other commands (signal slots connections)
+ const QString description = actions.size() == 1 ?
+ tr("Remove action '%1'").arg(actions.front()->objectName()) : tr("Remove actions");
+ fw->beginCommand(description);
+ foreach(QAction *action, actions) {
+ RemoveActionCommand *cmd = new RemoveActionCommand(fw);
+ cmd->init(action);
+ fw->commandHistory()->push(cmd);
+ }
+ fw->endCommand();
+}
+
+void ActionEditor::copyActions(QDesignerFormWindowInterface *fwi, const ActionList &actions)
+{
+ FormWindowBase *fw = qobject_cast<FormWindowBase *>(fwi);
+ if (!fw )
+ return;
+
+ FormBuilderClipboard clipboard;
+ clipboard.m_actions = actions;
+
+ if (clipboard.empty())
+ return;
+
+ QEditorFormBuilder *formBuilder = fw->createFormBuilder();
+ Q_ASSERT(formBuilder);
+
+ QBuffer buffer;
+ if (buffer.open(QIODevice::WriteOnly))
+ if (formBuilder->copy(&buffer, clipboard))
+ qApp->clipboard()->setText(QString::fromUtf8(buffer.buffer()), QClipboard::Clipboard);
+ delete formBuilder;
+}
+
+void ActionEditor::slotDelete()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+
+ const ActionView::ActionList selection = m_actionView->selectedActions();
+ if (selection.empty())
+ return;
+
+ deleteActions(fw, selection);
+}
+
+QString ActionEditor::actionTextToName(const QString &text, const QString &prefix)
+{
+ QString name = text;
+ if (name.isEmpty())
+ return QString();
+
+ name[0] = name.at(0).toUpper();
+ name.prepend(prefix);
+ const QString underscore = QString(QLatin1Char('_'));
+ name.replace(QRegExp(QString(QLatin1String("[^a-zA-Z_0-9]"))), underscore);
+ name.replace(QRegExp(QLatin1String("__*")), underscore);
+ if (name.endsWith(underscore.at(0)))
+ name.truncate(name.size() - 1);
+
+ return name;
+}
+
+void ActionEditor::resourceImageDropped(const QString &path, QAction *action)
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
+ const PropertySheetIconValue oldIcon =
+ qvariant_cast<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String(iconPropertyC))));
+ PropertySheetIconValue newIcon;
+ newIcon.setPixmap(QIcon::Normal, QIcon::Off, PropertySheetPixmapValue(path));
+ if (newIcon.paths().isEmpty() || newIcon.paths() == oldIcon.paths())
+ return;
+
+ fw->commandHistory()->push(setIconPropertyCommand(newIcon , action, fw));
+}
+
+void ActionEditor::mainContainerChanged()
+{
+ // Invalidate references to objects kept in model
+ if (sender() == formWindow())
+ setFormWindow(0);
+}
+
+void ActionEditor::slotViewMode(QAction *a)
+{
+ m_actionView->setViewMode(a->data().toInt());
+ updateViewModeActions();
+}
+
+void ActionEditor::slotSelectAssociatedWidget(QWidget *w)
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw )
+ return;
+
+ QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector());
+ if (!oi)
+ return;
+
+ fw->clearSelection(); // Actually, there are no widgets selected due to focus in event handling. Just to be sure.
+ oi->selectObject(w);
+}
+
+void ActionEditor::restoreSettings()
+{
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ m_actionView->setViewMode(settings->value(QLatin1String(actionEditorViewModeKey), 0).toInt());
+ updateViewModeActions();
+}
+
+void ActionEditor::saveSettings()
+{
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->setValue(QLatin1String(actionEditorViewModeKey), m_actionView->viewMode());
+}
+
+void ActionEditor::updateViewModeActions()
+{
+ switch (m_actionView->viewMode()) {
+ case ActionView::IconView:
+ m_iconViewAction->setChecked(true);
+ break;
+ case ActionView::DetailedView:
+ m_listViewAction->setChecked(true);
+ break;
+ }
+}
+
+void ActionEditor::slotCopy()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw )
+ return;
+
+ const ActionView::ActionList selection = m_actionView->selectedActions();
+ if (selection.empty())
+ return;
+
+ copyActions(fw, selection);
+}
+
+void ActionEditor::slotCut()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw )
+ return;
+
+ const ActionView::ActionList selection = m_actionView->selectedActions();
+ if (selection.empty())
+ return;
+
+ copyActions(fw, selection);
+ deleteActions(fw, selection);
+}
+
+void ActionEditor::slotPaste()
+{
+ FormWindowBase *fw = qobject_cast<FormWindowBase *>(formWindow());
+ if (!fw)
+ return;
+ m_actionView->clearSelection();
+ fw->paste(FormWindowBase::PasteActionsOnly);
+}
+
+void ActionEditor::slotContextMenuRequested(QContextMenuEvent *e, QAction *item)
+{
+ // set up signal mapper
+ if (!m_selectAssociatedWidgetsMapper) {
+ m_selectAssociatedWidgetsMapper = new QSignalMapper(this);
+ connect(m_selectAssociatedWidgetsMapper, SIGNAL(mapped(QWidget*)), this, SLOT(slotSelectAssociatedWidget(QWidget*)));
+ }
+
+ QMenu menu(this);
+ menu.addAction(m_actionNew);
+ menu.addSeparator();
+ menu.addAction(m_actionEdit);
+ if (QDesignerTaskMenu::isSlotNavigationEnabled(m_core))
+ menu.addAction(m_actionNavigateToSlot);
+
+ // Associated Widgets
+ if (QAction *action = m_actionView->currentAction()) {
+ const QWidgetList associatedWidgets = ActionModel::associatedWidgets(action);
+ if (!associatedWidgets.empty()) {
+ QMenu *associatedWidgetsSubMenu = menu.addMenu(tr("Used In"));
+ foreach (QWidget *w, associatedWidgets) {
+ QAction *action = associatedWidgetsSubMenu->addAction(w->objectName());
+ m_selectAssociatedWidgetsMapper->setMapping(action, w);
+ connect(action, SIGNAL(triggered()), m_selectAssociatedWidgetsMapper, SLOT(map()));
+ }
+ }
+ }
+
+ menu.addSeparator();
+ menu.addAction(m_actionCut);
+ menu.addAction(m_actionCopy);
+ menu.addAction(m_actionPaste);
+ menu.addAction(m_actionSelectAll);
+ menu.addAction(m_actionDelete);
+ menu.addSeparator();
+ menu.addAction(m_iconViewAction);
+ menu.addAction(m_listViewAction);
+
+ emit contextMenuRequested(&menu, item);
+
+ menu.exec(e->globalPos());
+ e->accept();
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/lib/shared/actioneditor_p.h b/src/designer/src/lib/shared/actioneditor_p.h
new file mode 100644
index 000000000..ffeae5846
--- /dev/null
+++ b/src/designer/src/lib/shared/actioneditor_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ACTIONEDITOR_H
+#define ACTIONEDITOR_H
+
+#include "shared_global_p.h"
+#include <QtDesigner/QDesignerActionEditorInterface>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerPropertyEditorInterface;
+class QDesignerSettingsInterface;
+class QMenu;
+class QActionGroup;
+class QSignalMapper;
+class QItemSelection;
+class QListWidget;
+class QPushButton;
+class QLineEdit;
+class QToolButton;
+
+namespace qdesigner_internal {
+
+class ActionView;
+class ResourceMimeData;
+
+class QDESIGNER_SHARED_EXPORT ActionEditor: public QDesignerActionEditorInterface
+{
+ Q_OBJECT
+public:
+ explicit ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ virtual ~ActionEditor();
+
+ QDesignerFormWindowInterface *formWindow() const;
+ virtual void setFormWindow(QDesignerFormWindowInterface *formWindow);
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ QAction *actionNew() const;
+ QAction *actionDelete() const;
+
+ QString filter() const;
+
+ virtual void manageAction(QAction *action);
+ virtual void unmanageAction(QAction *action);
+
+ static QString actionTextToName(const QString &text, const QString &prefix = QLatin1String("action"));
+
+ // Utility to create a configure button with menu for usage on toolbars
+ static QToolButton *createConfigureMenuButton(const QString &t, QMenu **ptrToMenu);
+
+public slots:
+ void setFilter(const QString &filter);
+ void mainContainerChanged();
+
+private slots:
+ void slotCurrentItemChanged(QAction *item);
+ void slotSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
+ void editAction(QAction *item);
+ void editCurrentAction();
+ void navigateToSlotCurrentAction();
+ void slotActionChanged();
+ void slotNewAction();
+ void slotDelete();
+ void resourceImageDropped(const QString &path, QAction *action);
+ void slotContextMenuRequested(QContextMenuEvent *, QAction *);
+ void slotViewMode(QAction *a);
+ void slotSelectAssociatedWidget(QWidget *w);
+ void slotCopy();
+ void slotCut();
+ void slotPaste();
+
+signals:
+ void itemActivated(QAction *item);
+ // Context menu for item or global menu if item == 0.
+ void contextMenuRequested(QMenu *menu, QAction *item);
+
+private:
+ typedef QList<QAction *> ActionList;
+ void deleteActions(QDesignerFormWindowInterface *formWindow, const ActionList &);
+ void copyActions(QDesignerFormWindowInterface *formWindow, const ActionList &);
+
+ void restoreSettings();
+ void saveSettings();
+
+ void updateViewModeActions();
+
+ QDesignerFormEditorInterface *m_core;
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+ QListWidget *m_actionGroups;
+
+ ActionView *m_actionView;
+
+ QAction *m_actionNew;
+ QAction *m_actionEdit;
+ QAction *m_actionNavigateToSlot;
+ QAction *m_actionCopy;
+ QAction *m_actionCut;
+ QAction *m_actionPaste;
+ QAction *m_actionSelectAll;
+ QAction *m_actionDelete;
+
+ QActionGroup *m_viewModeGroup;
+ QAction *m_iconViewAction;
+ QAction *m_listViewAction;
+
+ QString m_filter;
+ QWidget *m_filterWidget;
+ QSignalMapper *m_selectAssociatedWidgetsMapper;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ACTIONEDITOR_H
diff --git a/src/designer/src/lib/shared/actionprovider_p.h b/src/designer/src/lib/shared/actionprovider_p.h
new file mode 100644
index 000000000..ce8a1795e
--- /dev/null
+++ b/src/designer/src/lib/shared/actionprovider_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ACTIONPROVIDER_H
+#define ACTIONPROVIDER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtDesigner/extension.h>
+#include <QtCore/QPoint>
+#include <QtCore/QRect>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+
+class QDesignerActionProviderExtension
+{
+public:
+ virtual ~QDesignerActionProviderExtension() {}
+
+ virtual QRect actionGeometry(QAction *action) const = 0;
+ virtual QAction *actionAt(const QPoint &pos) const = 0;
+
+ virtual void adjustIndicator(const QPoint &pos) = 0;
+};
+
+// Find action at the given position for a widget that has actionGeometry() (QToolBar,
+// QMenuBar, QMenu). They usually have actionAt(), but that fails since Designer usually sets
+// WA_TransparentForMouseEvents on the widgets.
+template <class Widget>
+ int actionIndexAt(const Widget *w, const QPoint &pos, Qt::Orientation orientation)
+{
+ const QList<QAction*> actions = w->actions();
+ const int actionCount = actions.count();
+ if (actionCount == 0)
+ return -1;
+ // actionGeometry() can be wrong sometimes; it returns a geometry that
+ // stretches to the end of the toolbar/menu bar. So, check from the beginning
+ // in the case of a horizontal right-to-left orientation.
+ const bool checkTopRight = orientation == Qt::Horizontal && w->layoutDirection() == Qt::RightToLeft;
+ const QPoint topRight = QPoint(w->rect().width(), 0);
+ for (int index = 0; index < actionCount; ++index) {
+ QRect g = w->actionGeometry(actions.at(index));
+ if (checkTopRight)
+ g.setTopRight(topRight);
+ else
+ g.setTopLeft(QPoint(0, 0));
+
+ if (g.contains(pos))
+ return index;
+ }
+ return -1;
+}
+
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerActionProviderExtension, "com.trolltech.Qt.Designer.ActionProvider")
+
+QT_END_NAMESPACE
+
+#endif // ACTIONPROVIDER_H
diff --git a/src/designer/src/lib/shared/actionrepository.cpp b/src/designer/src/lib/shared/actionrepository.cpp
new file mode 100644
index 000000000..d7701cb9c
--- /dev/null
+++ b/src/designer/src/lib/shared/actionrepository.cpp
@@ -0,0 +1,665 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "actionrepository_p.h"
+#include "qtresourceview_p.h"
+#include "iconloader_p.h"
+#include "qdesigner_utils_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QDrag>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QToolButton>
+#include <QtGui/QPixmap>
+#include <QtGui/QAction>
+#include <QtGui/QHeaderView>
+#include <QtGui/QToolBar>
+#include <QtGui/QMenu>
+#include <QtGui/qevent.h>
+#include <QtCore/QSet>
+#include <QtCore/QDebug>
+
+Q_DECLARE_METATYPE(QAction*)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { listModeIconSize = 16, iconModeIconSize = 24 };
+}
+
+static const char *actionMimeType = "action-repository/actions";
+static const char *plainTextMimeType = "text/plain";
+
+static inline QAction *actionOfItem(const QStandardItem* item)
+{
+ return qvariant_cast<QAction*>(item->data(qdesigner_internal::ActionModel::ActionRole));
+}
+
+namespace qdesigner_internal {
+
+// ----------- ActionModel
+ActionModel::ActionModel(QWidget *parent ) :
+ QStandardItemModel(parent),
+ m_emptyIcon(emptyIcon()),
+ m_core(0)
+{
+ QStringList headers;
+ headers += tr("Name");
+ headers += tr("Used");
+ headers += tr("Text");
+ headers += tr("Shortcut");
+ headers += tr("Checkable");
+ headers += tr("ToolTip");
+ Q_ASSERT(NumColumns == headers.size());
+ setHorizontalHeaderLabels(headers);
+}
+
+void ActionModel::clearActions()
+{
+ removeRows(0, rowCount());
+}
+
+int ActionModel::findAction(QAction *action) const
+{
+ const int rows = rowCount();
+ for (int i = 0; i < rows; i++)
+ if (action == actionOfItem(item(i)))
+ return i;
+ return -1;
+}
+
+void ActionModel::update(int row)
+{
+ Q_ASSERT(m_core);
+ // need to create the row list ... grrr..
+ if (row >= rowCount())
+ return;
+
+ QStandardItemList list;
+ for (int i = 0; i < NumColumns; i++)
+ list += item(row, i);
+
+ setItems(m_core, actionOfItem(list.front()), m_emptyIcon, list);
+}
+
+void ActionModel::remove(int row)
+{
+ qDeleteAll(takeRow(row));
+}
+
+QModelIndex ActionModel::addAction(QAction *action)
+{
+ Q_ASSERT(m_core);
+ QStandardItemList items;
+ const Qt::ItemFlags flags = Qt::ItemIsSelectable|Qt::ItemIsDropEnabled|Qt::ItemIsDragEnabled|Qt::ItemIsEnabled;
+
+ QVariant itemData;
+ itemData.setValue(action);
+
+ for (int i = 0; i < NumColumns; i++) {
+ QStandardItem *item = new QStandardItem;
+ item->setData(itemData, ActionRole);
+ item->setFlags(flags);
+ items.push_back(item);
+ }
+ setItems(m_core, action, m_emptyIcon, items);
+ appendRow(items);
+ return indexFromItem(items.front());
+}
+
+// Find the associated menus and toolbars, ignore toolbuttons
+QWidgetList ActionModel::associatedWidgets(const QAction *action)
+{
+ QWidgetList rc = action->associatedWidgets();
+ for (QWidgetList::iterator it = rc.begin(); it != rc.end(); )
+ if (qobject_cast<const QMenu *>(*it) || qobject_cast<const QToolBar *>(*it)) {
+ ++it;
+ } else {
+ it = rc.erase(it);
+ }
+ return rc;
+}
+
+// shortcut is a fake property, need to retrieve it via property sheet.
+PropertySheetKeySequenceValue ActionModel::actionShortCut(QDesignerFormEditorInterface *core, QAction *action)
+{
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), action);
+ if (!sheet)
+ return PropertySheetKeySequenceValue();
+ return actionShortCut(sheet);
+}
+
+PropertySheetKeySequenceValue ActionModel::actionShortCut(const QDesignerPropertySheetExtension *sheet)
+{
+ const int index = sheet->indexOf(QLatin1String("shortcut"));
+ if (index == -1)
+ return PropertySheetKeySequenceValue();
+ return qvariant_cast<PropertySheetKeySequenceValue>(sheet->property(index));
+}
+
+void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action,
+ const QIcon &defaultIcon,
+ QStandardItemList &sl)
+{
+
+ // Tooltip, mostly for icon view mode
+ QString firstTooltip = action->objectName();
+ const QString text = action->text();
+ if (!text.isEmpty()) {
+ firstTooltip += QLatin1Char('\n');
+ firstTooltip += text;
+ }
+
+ Q_ASSERT(sl.size() == NumColumns);
+
+ QStandardItem *item = sl[NameColumn];
+ item->setText(action->objectName());
+ QIcon icon = action->icon();
+ if (icon.isNull())
+ icon = defaultIcon;
+ item->setIcon(icon);
+ item->setToolTip(firstTooltip);
+ item->setWhatsThis(firstTooltip);
+ // Used
+ const QWidgetList associatedDesignerWidgets = associatedWidgets(action);
+ const bool used = !associatedDesignerWidgets.empty();
+ item = sl[UsedColumn];
+ item->setCheckState(used ? Qt::Checked : Qt::Unchecked);
+ if (used) {
+ QString usedToolTip;
+ const QString separator = QLatin1String(", ");
+ const int count = associatedDesignerWidgets.size();
+ for (int i = 0; i < count; i++) {
+ if (i)
+ usedToolTip += separator;
+ usedToolTip += associatedDesignerWidgets.at(i)->objectName();
+ }
+ item->setToolTip(usedToolTip);
+ } else {
+ item->setToolTip(QString());
+ }
+ // text
+ item = sl[TextColumn];
+ item->setText(action->text());
+ item->setToolTip(action->text());
+ // shortcut
+ const QString shortcut = actionShortCut(core, action).value().toString(QKeySequence::NativeText);
+ item = sl[ShortCutColumn];
+ item->setText(shortcut);
+ item->setToolTip(shortcut);
+ // checkable
+ sl[CheckedColumn]->setCheckState(action->isCheckable() ? Qt::Checked : Qt::Unchecked);
+ // ToolTip. This might be multi-line, rich text
+ QString toolTip = action->toolTip();
+ item = sl[ToolTipColumn];
+ item->setToolTip(toolTip);
+ item->setText(toolTip.replace(QLatin1Char('\n'), QLatin1Char(' ')));
+}
+
+QMimeData *ActionModel::mimeData(const QModelIndexList &indexes ) const
+{
+ ActionRepositoryMimeData::ActionList actionList;
+
+ QSet<QAction*> actions;
+ foreach (const QModelIndex &index, indexes)
+ if (QStandardItem *item = itemFromIndex(index))
+ if (QAction *action = actionOfItem(item))
+ actions.insert(action);
+ return new ActionRepositoryMimeData(actions.toList(), Qt::CopyAction);
+}
+
+// Resource images are plain text. The drag needs to be restricted, however.
+QStringList ActionModel::mimeTypes() const
+{
+ return QStringList(QLatin1String(plainTextMimeType));
+}
+
+QString ActionModel::actionName(int row) const
+{
+ return item(row, NameColumn)->text();
+}
+
+bool ActionModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &)
+{
+ if (action != Qt::CopyAction)
+ return false;
+
+ QStandardItem *droppedItem = item(row, column);
+ if (!droppedItem)
+ return false;
+
+
+ QtResourceView::ResourceType type;
+ QString path;
+ if (!QtResourceView::decodeMimeData(data, &type, &path) || type != QtResourceView::ResourceImage)
+ return false;
+
+ emit resourceImageDropped(path, actionOfItem(droppedItem));
+ return true;
+}
+
+QAction *ActionModel::actionAt(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+ QStandardItem *i = itemFromIndex(index);
+ if (!i)
+ return 0;
+ return actionOfItem(i);
+}
+
+// helpers
+
+static bool handleImageDragEnterMoveEvent(QDropEvent *event)
+{
+ QtResourceView::ResourceType type;
+ const bool rc = QtResourceView::decodeMimeData(event->mimeData(), &type) && type == QtResourceView::ResourceImage;
+ if (rc)
+ event->acceptProposedAction();
+ else
+ event->ignore();
+ return rc;
+}
+
+static void handleImageDropEvent(const QAbstractItemView *iv, QDropEvent *event, ActionModel *am)
+{
+ const QModelIndex index = iv->indexAt(event->pos());
+ if (!index.isValid()) {
+ event->ignore();
+ return;
+ }
+
+ if (!handleImageDragEnterMoveEvent(event))
+ return;
+
+ am->dropMimeData(event->mimeData(), event->proposedAction(), index.row(), 0, iv->rootIndex());
+}
+
+// Basically mimic QAbstractItemView's startDrag routine, except that
+// another pixmap is used, we don't want the whole row.
+
+void startActionDrag(QWidget *dragParent, ActionModel *model, const QModelIndexList &indexes, Qt::DropActions supportedActions)
+{
+ if (indexes.empty())
+ return;
+
+ QDrag *drag = new QDrag(dragParent);
+ QMimeData *data = model->mimeData(indexes);
+ drag->setMimeData(data);
+ if (ActionRepositoryMimeData *actionMimeData = qobject_cast<ActionRepositoryMimeData *>(data))
+ drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(actionMimeData->actionList().front()));
+
+ drag->start(supportedActions);
+}
+
+// ---------------- ActionTreeView:
+ActionTreeView::ActionTreeView(ActionModel *model, QWidget *parent) :
+ QTreeView(parent),
+ m_model(model)
+{
+ setDragEnabled(true);
+ setAcceptDrops(true);
+ setDropIndicatorShown(true);
+ setDragDropMode(DragDrop);
+ setModel(model);
+ setRootIsDecorated(false);
+ setTextElideMode(Qt::ElideMiddle);
+
+ setModel(model);
+ connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(slotActivated(QModelIndex)));
+ connect(header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(resizeColumnToContents(int)));
+
+ setIconSize(QSize(listModeIconSize, listModeIconSize));
+
+}
+
+QAction *ActionTreeView::currentAction() const
+{
+ return m_model->actionAt(currentIndex());
+}
+
+void ActionTreeView::filter(const QString &text)
+{
+ const int rowCount = m_model->rowCount();
+ const bool empty = text.isEmpty();
+ const QModelIndex parent = rootIndex();
+ for (int i = 0; i < rowCount; i++)
+ setRowHidden(i, parent, !empty && !m_model->actionName(i).contains(text, Qt::CaseInsensitive));
+}
+
+void ActionTreeView::dragEnterEvent(QDragEnterEvent *event)
+{
+ handleImageDragEnterMoveEvent(event);
+}
+
+void ActionTreeView::dragMoveEvent(QDragMoveEvent *event)
+{
+ handleImageDragEnterMoveEvent(event);
+}
+
+void ActionTreeView::dropEvent(QDropEvent *event)
+{
+ handleImageDropEvent(this, event, m_model);
+}
+
+void ActionTreeView::focusInEvent(QFocusEvent *event)
+{
+ QTreeView::focusInEvent(event);
+ // Make property editor display current action
+ if (QAction *a = currentAction())
+ emit currentChanged(a);
+}
+
+void ActionTreeView::contextMenuEvent(QContextMenuEvent *event)
+{
+ emit contextMenuRequested(event, m_model->actionAt(indexAt(event->pos())));
+}
+
+void ActionTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ emit currentChanged(m_model->actionAt(current));
+ QTreeView::currentChanged(current, previous);
+}
+
+void ActionTreeView::slotActivated(const QModelIndex &index)
+{
+ emit activated(m_model->actionAt(index));
+}
+
+void ActionTreeView::startDrag(Qt::DropActions supportedActions)
+{
+ startActionDrag(this, m_model, selectedIndexes(), supportedActions);
+}
+
+// ---------------- ActionListView:
+ActionListView::ActionListView(ActionModel *model, QWidget *parent) :
+ QListView(parent),
+ m_model(model)
+{
+ setDragEnabled(true);
+ setAcceptDrops(true);
+ setDropIndicatorShown(true);
+ setDragDropMode(DragDrop);
+ setModel(model);
+ setTextElideMode(Qt::ElideMiddle);
+ connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(slotActivated(QModelIndex)));
+
+ // We actually want 'Static' as the user should be able to
+ // drag away actions only (not to rearrange icons).
+ // We emulate that by not accepting our own
+ // drag data. 'Static' causes the list view to disable drag and drop
+ // on the viewport.
+ setMovement(Snap);
+ setViewMode(IconMode);
+ setIconSize(QSize(iconModeIconSize, iconModeIconSize));
+ setGridSize(QSize(4 * iconModeIconSize, 2 * iconModeIconSize));
+ setSpacing(iconModeIconSize / 3);
+}
+
+QAction *ActionListView::currentAction() const
+{
+ return m_model->actionAt(currentIndex());
+}
+
+void ActionListView::filter(const QString &text)
+{
+ const int rowCount = m_model->rowCount();
+ const bool empty = text.isEmpty();
+ for (int i = 0; i < rowCount; i++)
+ setRowHidden(i, !empty && !m_model->actionName(i).contains(text, Qt::CaseInsensitive));
+}
+
+void ActionListView::dragEnterEvent(QDragEnterEvent *event)
+{
+ handleImageDragEnterMoveEvent(event);
+}
+
+void ActionListView::dragMoveEvent(QDragMoveEvent *event)
+{
+ handleImageDragEnterMoveEvent(event);
+}
+
+void ActionListView::dropEvent(QDropEvent *event)
+{
+ handleImageDropEvent(this, event, m_model);
+}
+
+void ActionListView::focusInEvent(QFocusEvent *event)
+{
+ QListView::focusInEvent(event);
+ // Make property editor display current action
+ if (QAction *a = currentAction())
+ emit currentChanged(a);
+}
+
+void ActionListView::contextMenuEvent(QContextMenuEvent *event)
+{
+ emit contextMenuRequested(event, m_model->actionAt(indexAt(event->pos())));
+}
+
+void ActionListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ emit currentChanged(m_model->actionAt(current));
+ QListView::currentChanged(current, previous);
+}
+
+void ActionListView::slotActivated(const QModelIndex &index)
+{
+ emit activated(m_model->actionAt(index));
+}
+
+void ActionListView::startDrag(Qt::DropActions supportedActions)
+{
+ startActionDrag(this, m_model, selectedIndexes(), supportedActions);
+}
+
+// ActionView
+ActionView::ActionView(QWidget *parent) :
+ QStackedWidget(parent),
+ m_model(new ActionModel(this)),
+ m_actionTreeView(new ActionTreeView(m_model)),
+ m_actionListView(new ActionListView(m_model))
+{
+ addWidget(m_actionListView);
+ addWidget(m_actionTreeView);
+ // Wire signals
+ connect(m_actionTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)),
+ this, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)));
+ connect(m_actionListView, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)),
+ this, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)));
+
+ // make it possible for vs integration to reimplement edit action dialog
+ // [which it shouldn't do actually]
+ connect(m_actionListView, SIGNAL(activated(QAction*)), this, SIGNAL(activated(QAction*)));
+ connect(m_actionTreeView, SIGNAL(activated(QAction*)), this, SIGNAL(activated(QAction*)));
+
+ connect(m_actionListView, SIGNAL(currentChanged(QAction*)),this, SLOT(slotCurrentChanged(QAction*)));
+ connect(m_actionTreeView, SIGNAL(currentChanged(QAction*)),this, SLOT(slotCurrentChanged(QAction*)));
+
+ connect(m_model, SIGNAL(resourceImageDropped(QString,QAction*)),
+ this, SIGNAL(resourceImageDropped(QString,QAction*)));
+
+ // sync selection models
+ QItemSelectionModel *selectionModel = m_actionTreeView->selectionModel();
+ m_actionListView->setSelectionModel(selectionModel);
+ connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SIGNAL(selectionChanged(QItemSelection,QItemSelection)));
+}
+
+int ActionView::viewMode() const
+{
+ return currentWidget() == m_actionListView ? IconView : DetailedView;
+}
+
+void ActionView::setViewMode(int lm)
+{
+ if (viewMode() == lm)
+ return;
+
+ switch (lm) {
+ case IconView:
+ setCurrentWidget(m_actionListView);
+ break;
+ case DetailedView:
+ setCurrentWidget(m_actionTreeView);
+ break;
+ default:
+ break;
+ }
+}
+
+void ActionView::slotCurrentChanged(QAction *action)
+{
+ // emit only for currently visible
+ if (sender() == currentWidget())
+ emit currentChanged(action);
+}
+
+void ActionView::filter(const QString &text)
+{
+ m_actionTreeView->filter(text);
+ m_actionListView->filter(text);
+}
+
+void ActionView::selectAll()
+{
+ m_actionTreeView->selectAll();
+}
+
+void ActionView::clearSelection()
+{
+ m_actionTreeView->selectionModel()->clearSelection();
+}
+
+void ActionView::setCurrentIndex(const QModelIndex &index)
+{
+ m_actionTreeView->setCurrentIndex(index);
+}
+
+QAction *ActionView::currentAction() const
+{
+ return m_actionListView->currentAction();
+}
+
+void ActionView::setSelectionMode(QAbstractItemView::SelectionMode sm)
+{
+ m_actionTreeView->setSelectionMode(sm);
+ m_actionListView->setSelectionMode(sm);
+}
+
+QAbstractItemView::SelectionMode ActionView::selectionMode() const
+{
+ return m_actionListView->selectionMode();
+}
+
+QItemSelection ActionView::selection() const
+{
+ return m_actionListView->selectionModel()->selection();
+}
+
+ActionView::ActionList ActionView::selectedActions() const
+{
+ ActionList rc;
+ foreach (const QModelIndex &index, selection().indexes())
+ if (index.column() == 0)
+ rc += actionOfItem(m_model->itemFromIndex(index));
+ return rc;
+}
+// ---------- ActionRepositoryMimeData
+ActionRepositoryMimeData::ActionRepositoryMimeData(QAction *a, Qt::DropAction dropAction) :
+ m_dropAction(dropAction)
+{
+ m_actionList += a;
+}
+
+ActionRepositoryMimeData::ActionRepositoryMimeData(const ActionList &al, Qt::DropAction dropAction) :
+ m_dropAction(dropAction),
+ m_actionList(al)
+{
+}
+
+QStringList ActionRepositoryMimeData::formats() const
+{
+ return QStringList(QLatin1String(actionMimeType));
+}
+
+QPixmap ActionRepositoryMimeData::actionDragPixmap(const QAction *action)
+{
+
+ // Try to find a suitable pixmap. Grab either widget or icon.
+ const QIcon icon = action->icon();
+ if (!icon.isNull())
+ return icon.pixmap(QSize(22, 22));
+
+ foreach (QWidget *w, action->associatedWidgets())
+ if (QToolButton *tb = qobject_cast<QToolButton *>(w))
+ return QPixmap::grabWidget(tb);
+
+ // Create a QToolButton
+ QToolButton *tb = new QToolButton;
+ tb->setText(action->text());
+ tb->setToolButtonStyle(Qt::ToolButtonTextOnly);
+#ifdef Q_WS_WIN // Force alien off to make adjustSize() take the system minimumsize into account.
+ tb->createWinId();
+#endif
+ tb->adjustSize();
+ const QPixmap rc = QPixmap::grabWidget(tb);
+ tb->deleteLater();
+ return rc;
+}
+
+void ActionRepositoryMimeData::accept(QDragMoveEvent *event) const
+{
+ if (event->proposedAction() == m_dropAction) {
+ event->acceptProposedAction();
+ } else {
+ event->setDropAction(m_dropAction);
+ event->accept();
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/actionrepository_p.h b/src/designer/src/lib/shared/actionrepository_p.h
new file mode 100644
index 000000000..c2393cb0b
--- /dev/null
+++ b/src/designer/src/lib/shared/actionrepository_p.h
@@ -0,0 +1,269 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ACTIONREPOSITORY_H
+#define ACTIONREPOSITORY_H
+
+#include "shared_global_p.h"
+#include <QtCore/QMimeData>
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QTreeView>
+#include <QtGui/QListView>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+class QPixmap;
+
+class QDesignerFormEditorInterface;
+class QDesignerPropertySheetExtension;
+
+namespace qdesigner_internal {
+
+class PropertySheetKeySequenceValue;
+
+// Shared model of actions, to be used for several views (detailed/icon view).
+class QDESIGNER_SHARED_EXPORT ActionModel: public QStandardItemModel
+{
+ Q_OBJECT
+public:
+ enum Columns { NameColumn, UsedColumn, TextColumn, ShortCutColumn, CheckedColumn, ToolTipColumn, NumColumns };
+ enum { ActionRole = Qt::UserRole + 1000 };
+
+ explicit ActionModel(QWidget *parent = 0);
+ void initialize(QDesignerFormEditorInterface *core) { m_core = core; }
+
+ void clearActions();
+ QModelIndex addAction(QAction *a);
+ // remove row
+ void remove(int row);
+ // update the row from the underlying action
+ void update(int row);
+
+ // return row of action or -1.
+ int findAction(QAction *) const;
+
+ QString actionName(int row) const;
+ QAction *actionAt(const QModelIndex &index) const;
+
+ virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
+ virtual QStringList mimeTypes() const;
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+
+ // Find the associated menus and toolbars, ignore toolbuttons
+ static QWidgetList associatedWidgets(const QAction *action);
+
+ // Retrieve shortcut via property sheet as it is a fake property
+ static PropertySheetKeySequenceValue actionShortCut(QDesignerFormEditorInterface *core, QAction *action);
+ static PropertySheetKeySequenceValue actionShortCut(const QDesignerPropertySheetExtension *ps);
+
+signals:
+ void resourceImageDropped(const QString &path, QAction *action);
+
+private:
+ typedef QList<QStandardItem *> QStandardItemList;
+
+ void initializeHeaders();
+ static void setItems(QDesignerFormEditorInterface *core, QAction *a,
+ const QIcon &defaultIcon,
+ QStandardItemList &sl);
+
+ const QIcon m_emptyIcon;
+
+ QDesignerFormEditorInterface *m_core;
+};
+
+// Internal class that provides the detailed view of actions.
+class ActionTreeView: public QTreeView
+{
+ Q_OBJECT
+public:
+ explicit ActionTreeView(ActionModel *model, QWidget *parent = 0);
+ QAction *currentAction() const;
+
+public slots:
+ void filter(const QString &text);
+
+signals:
+ void contextMenuRequested(QContextMenuEvent *event, QAction *);
+ void currentChanged(QAction *action);
+ void activated(QAction *action);
+
+protected slots:
+ virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+protected:
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dragMoveEvent(QDragMoveEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+ virtual void focusInEvent(QFocusEvent *event);
+ virtual void contextMenuEvent(QContextMenuEvent *event);
+ virtual void startDrag(Qt::DropActions supportedActions);
+
+private slots:
+ void slotActivated(const QModelIndex &);
+
+private:
+ ActionModel *m_model;
+};
+
+// Internal class that provides the icon view of actions.
+class ActionListView: public QListView
+{
+ Q_OBJECT
+public:
+ explicit ActionListView(ActionModel *model, QWidget *parent = 0);
+ QAction *currentAction() const;
+
+public slots:
+ void filter(const QString &text);
+
+signals:
+ void contextMenuRequested(QContextMenuEvent *event, QAction *);
+ void currentChanged(QAction *action);
+ void activated(QAction *action);
+
+protected slots:
+ virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+protected:
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dragMoveEvent(QDragMoveEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+ virtual void focusInEvent(QFocusEvent *event);
+ virtual void contextMenuEvent(QContextMenuEvent *event);
+ virtual void startDrag(Qt::DropActions supportedActions);
+
+private slots:
+ void slotActivated(const QModelIndex &);
+
+private:
+ ActionModel *m_model;
+};
+
+// Action View that can be switched between detailed and icon view
+// using a QStackedWidget of ActionListView / ActionTreeView
+// that share the item model and the selection model.
+
+class ActionView : public QStackedWidget {
+ Q_OBJECT
+public:
+ // Separate initialize() function takes core argument to make this
+ // thing usable as promoted widget.
+ explicit ActionView(QWidget *parent = 0);
+ void initialize(QDesignerFormEditorInterface *core) { m_model->initialize(core); }
+
+ // View mode
+ enum { DetailedView, IconView };
+ int viewMode() const;
+ void setViewMode(int lm);
+
+ void setSelectionMode(QAbstractItemView::SelectionMode sm);
+ QAbstractItemView::SelectionMode selectionMode() const;
+
+ ActionModel *model() const { return m_model; }
+
+ QAction *currentAction() const;
+ void setCurrentIndex(const QModelIndex &index);
+
+ typedef QList<QAction*> ActionList;
+ ActionList selectedActions() const;
+ QItemSelection selection() const;
+
+public slots:
+ void filter(const QString &text);
+ void selectAll();
+ void clearSelection();
+
+signals:
+ void contextMenuRequested(QContextMenuEvent *event, QAction *);
+ void currentChanged(QAction *action);
+ void activated(QAction *action);
+ void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
+ void resourceImageDropped(const QString &data, QAction *action);
+
+private slots:
+ void slotCurrentChanged(QAction *action);
+
+private:
+ ActionModel *m_model;
+ ActionTreeView *m_actionTreeView;
+ ActionListView *m_actionListView;
+};
+
+class QDESIGNER_SHARED_EXPORT ActionRepositoryMimeData: public QMimeData
+{
+ Q_OBJECT
+public:
+ typedef QList<QAction*> ActionList;
+
+ ActionRepositoryMimeData(const ActionList &, Qt::DropAction dropAction);
+ ActionRepositoryMimeData(QAction *, Qt::DropAction dropAction);
+
+ const ActionList &actionList() const { return m_actionList; }
+ virtual QStringList formats() const;
+
+ static QPixmap actionDragPixmap(const QAction *action);
+
+ // Utility to accept with right action
+ void accept(QDragMoveEvent *event) const;
+private:
+ const Qt::DropAction m_dropAction;
+ ActionList m_actionList;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ACTIONREPOSITORY_H
diff --git a/src/designer/src/lib/shared/addlinkdialog.ui b/src/designer/src/lib/shared/addlinkdialog.ui
new file mode 100644
index 000000000..3171159f9
--- /dev/null
+++ b/src/designer/src/lib/shared/addlinkdialog.ui
@@ -0,0 +1,112 @@
+<ui version="4.0" >
+ <class>AddLinkDialog</class>
+ <widget class="QDialog" name="AddLinkDialog" >
+ <property name="windowTitle" >
+ <string>Insert Link</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>false</bool>
+ </property>
+ <property name="modal" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <layout class="QFormLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Title:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="titleInput" >
+ <property name="minimumSize" >
+ <size>
+ <width>337</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>URL:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="urlInput" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>AddLinkDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>AddLinkDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/codedialog.cpp b/src/designer/src/lib/shared/codedialog.cpp
new file mode 100644
index 000000000..2420aa54a
--- /dev/null
+++ b/src/designer/src/lib/shared/codedialog.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "codedialog_p.h"
+#include "qdesigner_utils_p.h"
+#include "iconloader_p.h"
+
+#include <texteditfindwidget.h>
+
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QFileDialog>
+#include <QtGui/QIcon>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QTextEdit>
+#include <QtGui/QToolBar>
+#include <QtGui/QVBoxLayout>
+
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QTemporaryFile>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+// ----------------- CodeDialogPrivate
+struct CodeDialog::CodeDialogPrivate {
+ CodeDialogPrivate();
+
+ QTextEdit *m_textEdit;
+ TextEditFindWidget *m_findWidget;
+ QString m_formFileName;
+};
+
+CodeDialog::CodeDialogPrivate::CodeDialogPrivate()
+ : m_textEdit(new QTextEdit)
+ , m_findWidget(new TextEditFindWidget)
+{
+}
+
+// ----------------- CodeDialog
+CodeDialog::CodeDialog(QWidget *parent) :
+ QDialog(parent),
+ m_impl(new CodeDialogPrivate)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ QVBoxLayout *vBoxLayout = new QVBoxLayout;
+
+ // Edit tool bar
+ QToolBar *toolBar = new QToolBar;
+
+ const QIcon saveIcon = createIconSet(QLatin1String("filesave.png"));
+ QAction *saveAction = toolBar->addAction(saveIcon, tr("Save..."));
+ connect(saveAction, SIGNAL(triggered()), this, SLOT(slotSaveAs()));
+
+ const QIcon copyIcon = createIconSet(QLatin1String("editcopy.png"));
+ QAction *copyAction = toolBar->addAction(copyIcon, tr("Copy All"));
+ connect(copyAction, SIGNAL(triggered()), this, SLOT(copyAll()));
+
+ QAction *findAction = toolBar->addAction(
+ TextEditFindWidget::findIconSet(),
+ tr("&Find in Text..."),
+ m_impl->m_findWidget, SLOT(activate()));
+ findAction->setShortcut(QKeySequence::Find);
+
+ vBoxLayout->addWidget(toolBar);
+
+ // Edit
+ m_impl->m_textEdit->setReadOnly(true);
+ m_impl->m_textEdit->setMinimumSize(QSize(
+ m_impl->m_findWidget->minimumSize().width(),
+ 500));
+ vBoxLayout->addWidget(m_impl->m_textEdit);
+
+ // Find
+ m_impl->m_findWidget->setTextEdit(m_impl->m_textEdit);
+ vBoxLayout->addWidget(m_impl->m_findWidget);
+
+ // Button box
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ // Disable auto default
+ QPushButton *closeButton = buttonBox->button(QDialogButtonBox::Close);
+ closeButton->setAutoDefault(false);
+ vBoxLayout->addWidget(buttonBox);
+
+ setLayout(vBoxLayout);
+}
+
+CodeDialog::~CodeDialog()
+{
+ delete m_impl;
+}
+
+void CodeDialog::setCode(const QString &code)
+{
+ m_impl->m_textEdit->setPlainText(code);
+}
+
+QString CodeDialog::code() const
+{
+ return m_impl->m_textEdit->toPlainText();
+}
+
+void CodeDialog::setFormFileName(const QString &f)
+{
+ m_impl->m_formFileName = f;
+}
+
+QString CodeDialog::formFileName() const
+{
+ return m_impl->m_formFileName;
+}
+
+bool CodeDialog::generateCode(const QDesignerFormWindowInterface *fw,
+ QString *code,
+ QString *errorMessage)
+{
+ // Generate temporary file name similar to form file name
+ // (for header guards)
+ QString tempPattern = QDir::tempPath();
+ if (!tempPattern.endsWith(QDir::separator())) // platform-dependant
+ tempPattern += QDir::separator();
+ const QString fileName = fw->fileName();
+ if (fileName.isEmpty()) {
+ tempPattern += QLatin1String("designer");
+ } else {
+ tempPattern += QFileInfo(fileName).baseName();
+ }
+ tempPattern += QLatin1String("XXXXXX.ui");
+ // Write to temp file
+ QTemporaryFile tempFormFile(tempPattern);
+
+ tempFormFile.setAutoRemove(true);
+ if (!tempFormFile.open()) {
+ *errorMessage = tr("A temporary form file could not be created in %1.").arg(QDir::tempPath());
+ return false;
+ }
+ const QString tempFormFileName = tempFormFile.fileName();
+ tempFormFile.write(fw->contents().toUtf8());
+ if (!tempFormFile.flush()) {
+ *errorMessage = tr("The temporary form file %1 could not be written.").arg(tempFormFileName);
+ return false;
+ }
+ tempFormFile.close();
+ // Run uic
+ QByteArray rc;
+ if (!runUIC(tempFormFileName, UIC_GenerateCode, rc, *errorMessage))
+ return false;
+ *code = QString::fromUtf8(rc);
+ return true;
+}
+
+bool CodeDialog::showCodeDialog(const QDesignerFormWindowInterface *fw,
+ QWidget *parent,
+ QString *errorMessage)
+{
+ QString code;
+ if (!generateCode(fw, &code, errorMessage))
+ return false;
+
+ CodeDialog dialog(parent);
+ dialog.setWindowTitle(tr("%1 - [Code]").arg(fw->mainContainer()->windowTitle()));
+ dialog.setCode(code);
+ dialog.setFormFileName(fw->fileName());
+ dialog.exec();
+ return true;
+}
+
+void CodeDialog::slotSaveAs()
+{
+ // build the default relative name 'ui_sth.h'
+ const QString headerSuffix = QString(QLatin1Char('h'));
+ QString filter;
+ const QString uiFile = formFileName();
+
+ if (!uiFile.isEmpty()) {
+ filter = QLatin1String("ui_");
+ filter += QFileInfo(uiFile).baseName();
+ filter += QLatin1Char('.');
+ filter += headerSuffix;
+ }
+ // file dialog
+ while (true) {
+ const QString fileName =
+ QFileDialog::getSaveFileName (this, tr("Save Code"), filter, tr("Header Files (*.%1)").arg(headerSuffix));
+ if (fileName.isEmpty())
+ break;
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly|QIODevice::Text)) {
+ warning(tr("The file %1 could not be opened: %2").arg(fileName).arg(file.errorString()));
+ continue;
+ }
+ file.write(code().toUtf8());
+ if (!file.flush()) {
+ warning(tr("The file %1 could not be written: %2").arg(fileName).arg(file.errorString()));
+ continue;
+ }
+ file.close();
+ break;
+ }
+}
+
+void CodeDialog::warning(const QString &msg)
+{
+ QMessageBox::warning(
+ this, tr("%1 - Error").arg(windowTitle()),
+ msg, QMessageBox::Close);
+}
+
+void CodeDialog::copyAll()
+{
+ QApplication::clipboard()->setText(code());
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/codedialog_p.h b/src/designer/src/lib/shared/codedialog_p.h
new file mode 100644
index 000000000..bed7e224f
--- /dev/null
+++ b/src/designer/src/lib/shared/codedialog_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef CODEPREVIEWDIALOG_H
+#define CODEPREVIEWDIALOG_H
+
+#include "shared_global_p.h"
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+// Dialog for viewing code.
+class QDESIGNER_SHARED_EXPORT CodeDialog : public QDialog
+{
+ Q_OBJECT
+ explicit CodeDialog(QWidget *parent = 0);
+public:
+ virtual ~CodeDialog();
+
+ static bool generateCode(const QDesignerFormWindowInterface *fw,
+ QString *code,
+ QString *errorMessage);
+
+ static bool showCodeDialog(const QDesignerFormWindowInterface *fw,
+ QWidget *parent,
+ QString *errorMessage);
+
+private slots:
+ void slotSaveAs();
+ void copyAll();
+
+private:
+ void setCode(const QString &code);
+ QString code() const;
+ void setFormFileName(const QString &f);
+ QString formFileName() const;
+
+ void warning(const QString &msg);
+
+ struct CodeDialogPrivate;
+ CodeDialogPrivate *m_impl;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // CODEPREVIEWDIALOG_H
diff --git a/src/designer/src/lib/shared/connectionedit.cpp b/src/designer/src/lib/shared/connectionedit.cpp
new file mode 100644
index 000000000..5f5085c17
--- /dev/null
+++ b/src/designer/src/lib/shared/connectionedit.cpp
@@ -0,0 +1,1612 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "connectionedit_p.h"
+
+#include <QtDesigner/abstractformwindow.h>
+
+#include <QtGui/QPainter>
+#include <QtGui/QPaintEvent>
+#include <QtGui/QFontMetrics>
+#include <QtGui/QPixmap>
+#include <QtGui/QMatrix>
+#include <QtGui/QApplication>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+
+#include <QtCore/QMultiMap>
+
+QT_BEGIN_NAMESPACE
+
+static const int BG_ALPHA = 32;
+static const int LINE_PROXIMITY_RADIUS = 3;
+static const int LOOP_MARGIN = 20;
+static const int VLABEL_MARGIN = 1;
+static const int HLABEL_MARGIN = 3;
+static const int GROUND_W = 20;
+static const int GROUND_H = 25;
+
+/*******************************************************************************
+** Tools
+*/
+
+static QRect fixRect(const QRect &r)
+{
+ return QRect(r.x(), r.y(), r.width() - 1, r.height() - 1);
+}
+
+static QRect expand(const QRect &r, int i)
+{
+ return QRect(r.x() - i, r.y() - i, r.width() + 2*i, r.height() + 2*i);
+}
+
+static QRect endPointRectHelper(const QPoint &pos)
+{
+ const QRect r(pos + QPoint(-LINE_PROXIMITY_RADIUS, -LINE_PROXIMITY_RADIUS),
+ QSize(2*LINE_PROXIMITY_RADIUS, 2*LINE_PROXIMITY_RADIUS));
+ return r;
+}
+
+static void paintGround(QPainter *p, QRect r)
+{
+ const QPoint mid = r.center();
+ p->drawLine(mid.x(), r.top(), mid.x(), mid.y());
+ p->drawLine(r.left(), mid.y(), r.right(), mid.y());
+ int y = r.top() + 4*r.height()/6;
+ int x = GROUND_W/6;
+ p->drawLine(r.left() + x, y, r.right() - x, y);
+ y = r.top() + 5*r.height()/6;
+ x = 2*GROUND_W/6;
+ p->drawLine(r.left() + x, y, r.right() - x, y);
+ p->drawLine(mid.x(), r.bottom(), mid.x() + 1, r.bottom());
+}
+
+static void paintEndPoint(QPainter *p, const QPoint &pos)
+{
+ const QRect r(pos + QPoint(-LINE_PROXIMITY_RADIUS, -LINE_PROXIMITY_RADIUS),
+ QSize(2*LINE_PROXIMITY_RADIUS, 2*LINE_PROXIMITY_RADIUS));
+ p->fillRect(fixRect(r), p->pen().color());
+}
+
+static qdesigner_internal::CETypes::LineDir classifyLine(const QPoint &p1, const QPoint &p2)
+{
+ if (p1.x() == p2.x())
+ return p1.y() < p2.y() ? qdesigner_internal::CETypes::DownDir : qdesigner_internal::CETypes::UpDir;
+ Q_ASSERT(p1.y() == p2.y());
+ return p1.x() < p2.x() ? qdesigner_internal::CETypes::RightDir : qdesigner_internal::CETypes::LeftDir;
+}
+
+static QPoint pointInsideRect(const QRect &r, QPoint p)
+{
+ if (p.x() < r.left())
+ p.setX(r.left());
+ else if (p.x() > r.right())
+ p.setX(r.right());
+
+ if (p.y() < r.top())
+ p.setY(r.top());
+ else if (p.y() > r.bottom())
+ p.setY(r.bottom());
+
+ return p;
+}
+
+namespace qdesigner_internal {
+
+/*******************************************************************************
+** Commands
+*/
+
+AddConnectionCommand::AddConnectionCommand(ConnectionEdit *edit, Connection *con)
+ : CECommand(edit), m_con(con)
+{
+ setText(QApplication::translate("Command", "Add connection"));
+}
+
+void AddConnectionCommand::redo()
+{
+ edit()->selectNone();
+ emit edit()->aboutToAddConnection(edit()->m_con_list.size());
+ edit()->m_con_list.append(m_con);
+ m_con->inserted();
+ edit()->setSelected(m_con, true);
+ emit edit()->connectionAdded(m_con);
+}
+
+void AddConnectionCommand::undo()
+{
+ const int idx = edit()->indexOfConnection(m_con);
+ emit edit()->aboutToRemoveConnection(m_con);
+ edit()->setSelected(m_con, false);
+ m_con->update();
+ m_con->removed();
+ edit()->m_con_list.removeAll(m_con);
+ emit edit()->connectionRemoved(idx);
+}
+
+class AdjustConnectionCommand : public CECommand
+{
+public:
+ AdjustConnectionCommand(ConnectionEdit *edit, Connection *con,
+ const QPoint &old_source_pos,
+ const QPoint &old_target_pos,
+ const QPoint &new_source_pos,
+ const QPoint &new_target_pos);
+ virtual void redo();
+ virtual void undo();
+private:
+ Connection *m_con;
+ const QPoint m_old_source_pos;
+ const QPoint m_old_target_pos;
+ const QPoint m_new_source_pos;
+ const QPoint m_new_target_pos;
+};
+
+AdjustConnectionCommand::AdjustConnectionCommand(ConnectionEdit *edit, Connection *con,
+ const QPoint &old_source_pos,
+ const QPoint &old_target_pos,
+ const QPoint &new_source_pos,
+ const QPoint &new_target_pos) :
+ CECommand(edit),
+ m_con(con),
+ m_old_source_pos(old_source_pos),
+ m_old_target_pos(old_target_pos),
+ m_new_source_pos(new_source_pos),
+ m_new_target_pos(new_target_pos)
+{
+ setText(QApplication::translate("Command", "Adjust connection"));
+}
+
+void AdjustConnectionCommand::undo()
+{
+ m_con->setEndPoint(EndPoint::Source, m_con->widget(EndPoint::Source), m_old_source_pos);
+ m_con->setEndPoint(EndPoint::Target, m_con->widget(EndPoint::Target), m_old_target_pos);
+}
+
+void AdjustConnectionCommand::redo()
+{
+ m_con->setEndPoint(EndPoint::Source, m_con->widget(EndPoint::Source), m_new_source_pos);
+ m_con->setEndPoint(EndPoint::Target, m_con->widget(EndPoint::Target), m_new_target_pos);
+}
+
+DeleteConnectionsCommand::DeleteConnectionsCommand(ConnectionEdit *edit,
+ const ConnectionList &con_list)
+ : CECommand(edit), m_con_list(con_list)
+{
+ setText(QApplication::translate("Command", "Delete connections"));
+}
+
+void DeleteConnectionsCommand::redo()
+{
+ foreach (Connection *con, m_con_list) {
+ const int idx = edit()->indexOfConnection(con);
+ emit edit()->aboutToRemoveConnection(con);
+ Q_ASSERT(edit()->m_con_list.contains(con));
+ edit()->setSelected(con, false);
+ con->update();
+ con->removed();
+ edit()->m_con_list.removeAll(con);
+ emit edit()->connectionRemoved(idx);
+ }
+}
+
+void DeleteConnectionsCommand::undo()
+{
+ foreach (Connection *con, m_con_list) {
+ Q_ASSERT(!edit()->m_con_list.contains(con));
+ emit edit()->aboutToAddConnection(edit()->m_con_list.size());
+ edit()->m_con_list.append(con);
+ edit()->setSelected(con, true);
+ con->update();
+ con->inserted();
+ emit edit()->connectionAdded(con);
+ }
+}
+
+class SetEndPointCommand : public CECommand
+{
+public:
+ SetEndPointCommand(ConnectionEdit *edit, Connection *con, EndPoint::Type type, QObject *object);
+ virtual void redo();
+ virtual void undo();
+private:
+ Connection *m_con;
+ const EndPoint::Type m_type;
+ QObject *m_old_widget, *m_new_widget;
+ const QPoint m_old_pos;
+ QPoint m_new_pos;
+};
+
+SetEndPointCommand::SetEndPointCommand(ConnectionEdit *edit, Connection *con,
+ EndPoint::Type type, QObject *object) :
+ CECommand(edit),
+ m_con(con),
+ m_type(type),
+ m_old_widget(con->object(type)),
+ m_new_widget(object),
+ m_old_pos(con->endPointPos(type))
+{
+ if (QWidget *widget = qobject_cast<QWidget*>(object)) {
+ m_new_pos = edit->widgetRect(widget).center();
+ }
+
+ if (m_type == EndPoint::Source)
+ setText(QApplication::translate("Command", "Change source"));
+ else
+ setText(QApplication::translate("Command", "Change target"));
+}
+
+void SetEndPointCommand::redo()
+{
+ m_con->setEndPoint(m_type, m_new_widget, m_new_pos);
+ emit edit()->connectionChanged(m_con);
+}
+
+void SetEndPointCommand::undo()
+{
+ m_con->setEndPoint(m_type, m_old_widget, m_old_pos);
+ emit edit()->connectionChanged(m_con);
+}
+
+/*******************************************************************************
+** Connection
+*/
+
+Connection::Connection(ConnectionEdit *edit) :
+ m_source_pos(QPoint(-1, -1)),
+ m_target_pos(QPoint(-1, -1)),
+ m_source(0),
+ m_target(0),
+ m_edit(edit),
+ m_visible(true)
+{
+
+}
+
+Connection::Connection(ConnectionEdit *edit, QObject *source, QObject *target) :
+ m_source_pos(QPoint(-1, -1)),
+ m_target_pos(QPoint(-1, -1)),
+ m_source(source),
+ m_target(target),
+ m_edit(edit),
+ m_visible(true)
+{
+}
+
+void Connection::setVisible(bool b)
+{
+ m_visible = b;
+}
+
+void Connection::updateVisibility()
+{
+ QWidget *source = widget(EndPoint::Source);
+ QWidget *target = widget(EndPoint::Target);
+
+ if (source == 0 || target == 0) {
+ setVisible(false);
+ return;
+ }
+
+ QWidget *w = source;
+ while (w && w->parentWidget()) {
+ if (!w->isVisibleTo(w->parentWidget())) {
+ setVisible(false);
+ return;
+ }
+ w = w->parentWidget();
+ }
+
+ w = target;
+ while (w && w->parentWidget()) {
+ if (!w->isVisibleTo(w->parentWidget())) {
+ setVisible(false);
+ return;
+ }
+ w = w->parentWidget();
+ }
+
+ setVisible(true);
+}
+
+bool Connection::isVisible() const
+{
+ return m_visible;
+}
+
+bool Connection::ground() const
+{
+ return m_target != 0 && m_target == m_edit->m_bg_widget;
+}
+
+QPoint Connection::endPointPos(EndPoint::Type type) const
+{
+ if (type == EndPoint::Source)
+ return m_source_pos;
+ else
+ return m_target_pos;
+}
+
+static QPoint lineEntryPos(const QPoint &p1, const QPoint &p2, const QRect &rect)
+{
+ QPoint result;
+
+ switch (classifyLine(p1, p2)) {
+ case CETypes::UpDir:
+ result = QPoint(p1.x(), rect.bottom());
+ break;
+ case CETypes::DownDir:
+ result = QPoint(p1.x(), rect.top());
+ break;
+ case CETypes::LeftDir:
+ result = QPoint(rect.right(), p1.y());
+ break;
+ case CETypes::RightDir:
+ result = QPoint(rect.left(), p1.y());
+ break;
+ }
+
+ return result;
+}
+
+static QPolygonF arrowHead(const QPoint &p1, const QPoint &p2)
+{
+ QPolygonF result;
+
+ switch (classifyLine(p1, p2)) {
+ case CETypes::UpDir:
+ result.append(p2 + QPoint(0, 1));
+ result.append(p2 + QPoint(LINE_PROXIMITY_RADIUS, LINE_PROXIMITY_RADIUS*2 + 1));
+ result.append(p2 + QPoint(-LINE_PROXIMITY_RADIUS, LINE_PROXIMITY_RADIUS*2 + 1));
+ break;
+ case CETypes::DownDir:
+ result.append(p2);
+ result.append(p2 + QPoint(LINE_PROXIMITY_RADIUS, -LINE_PROXIMITY_RADIUS*2));
+ result.append(p2 + QPoint(-LINE_PROXIMITY_RADIUS, -LINE_PROXIMITY_RADIUS*2));
+ break;
+ case CETypes::LeftDir:
+ result.append(p2 + QPoint(1, 0));
+ result.append(p2 + QPoint(2*LINE_PROXIMITY_RADIUS + 1, -LINE_PROXIMITY_RADIUS));
+ result.append(p2 + QPoint(2*LINE_PROXIMITY_RADIUS + 1, LINE_PROXIMITY_RADIUS));
+ break;
+ case CETypes::RightDir:
+ result.append(p2);
+ result.append(p2 + QPoint(-2*LINE_PROXIMITY_RADIUS, -LINE_PROXIMITY_RADIUS));
+ result.append(p2 + QPoint(-2*LINE_PROXIMITY_RADIUS, LINE_PROXIMITY_RADIUS));
+ break;
+ }
+
+ return result;
+}
+
+static CETypes::LineDir closestEdge(const QPoint &p, const QRect &r)
+{
+ CETypes::LineDir result = CETypes::UpDir;
+ int min = p.y() - r.top();
+
+ int d = p.x() - r.left();
+ if (d < min) {
+ min = d;
+ result = CETypes::LeftDir;
+ }
+
+ d = r.bottom() - p.y();
+ if (d < min) {
+ min = d;
+ result = CETypes::DownDir;
+ }
+
+ d = r.right() - p.x();
+ if (d < min) {
+ min = d;
+ result = CETypes::RightDir;
+ }
+
+ return result;
+}
+
+static bool pointAboveLine(const QPoint &l1, const QPoint &l2, const QPoint &p)
+{
+ if (l1.x() == l2.x())
+ return p.x() >= l1.x();
+ return p.y() <= l1.y() + (p.x() - l1.x())*(l2.y() - l1.y())/(l2.x() - l1.x());
+}
+
+void Connection::updateKneeList()
+{
+ const LineDir old_source_label_dir = labelDir(EndPoint::Source);
+ const LineDir old_target_label_dir = labelDir(EndPoint::Target);
+
+ QPoint s = endPointPos(EndPoint::Source);
+ QPoint t = endPointPos(EndPoint::Target);
+ const QRect sr = m_source_rect;
+ const QRect tr = m_target_rect;
+
+ m_knee_list.clear();
+ m_arrow_head.clear();
+
+ if (m_source == 0 || s == QPoint(-1, -1) || t == QPoint(-1, -1))
+ return;
+
+ const QRect r = sr | tr;
+
+ m_knee_list.append(s);
+ if (m_target == 0) {
+ m_knee_list.append(QPoint(t.x(), s.y()));
+ } else if (m_target == m_edit->m_bg_widget) {
+ m_knee_list.append(QPoint(s.x(), t.y()));
+ } else if (tr.contains(sr) || sr.contains(tr)) {
+/*
+ +------------------+
+ | +----------+ |
+ | | | |
+ | | o | |
+ | +---|------+ |
+ | | x |
+ +-----|-----|------+
+ +-----+
+
+ We find out which edge of the outer rectangle is closest to the target
+ point, and make a loop which exits and re-enters through that edge.
+*/
+ const LineDir dir = closestEdge(t, tr);
+ switch (dir) {
+ case UpDir:
+ m_knee_list.append(QPoint(s.x(), r.top() - LOOP_MARGIN));
+ m_knee_list.append(QPoint(t.x(), r.top() - LOOP_MARGIN));
+ break;
+ case DownDir:
+ m_knee_list.append(QPoint(s.x(), r.bottom() + LOOP_MARGIN));
+ m_knee_list.append(QPoint(t.x(), r.bottom() + LOOP_MARGIN));
+ break;
+ case LeftDir:
+ m_knee_list.append(QPoint(r.left() - LOOP_MARGIN, s.y()));
+ m_knee_list.append(QPoint(r.left() - LOOP_MARGIN, t.y()));
+ break;
+ case RightDir:
+ m_knee_list.append(QPoint(r.right() + LOOP_MARGIN, s.y()));
+ m_knee_list.append(QPoint(r.right() + LOOP_MARGIN, t.y()));
+ break;
+ }
+ } else {
+ if (r.height() < sr.height() + tr.height()) {
+ if ((s.y() >= tr.top() && s.y() <= tr.bottom()) || (t.y() >= sr.bottom() || t.y() <= sr.top())) {
+/*
+ +--------+
+ | | +--------+
+ | o--+---+--x |
+ | o | | |
+ +-----|--+ | |
+ +------+--x |
+ +--------+
+
+ When dragging one end point, move the other end point to the same y position,
+ if that does not cause it to exit it's rectangle.
+*/
+ if (m_edit->state() == ConnectionEdit::Dragging) {
+ if (m_edit->m_drag_end_point.type == EndPoint::Source) {
+ const QPoint p(t.x(), s.y());
+ m_knee_list.append(p);
+ if (tr.contains(p))
+ t = m_target_pos = p;
+ } else {
+ const QPoint p(s.x(), t.y());
+ m_knee_list.append(p);
+ if (sr.contains(p))
+ s = m_source_pos = p;
+ }
+ } else {
+ m_knee_list.append(QPoint(s.x(), t.y()));
+ }
+ } else {
+/*
+ +--------+
+ | o----+-------+
+ | | +---|----+
+ +--------+ | | |
+ | x |
+ +--------+
+*/
+ m_knee_list.append(QPoint(t.x(), s.y()));
+ }
+ } else if (r.width() < sr.width() + tr.width()) {
+ if ((s.x() >= tr.left() && s.x() <= tr.right()) || t.x() >= sr.right() || t.x() <= sr.left()) {
+/*
+ +--------+
+ | |
+ | o o+--+
+ +----|---+ |
+ +-|------|-+
+ | x x |
+ | |
+ +----------+
+
+ When dragging one end point, move the other end point to the same x position,
+ if that does not cause it to exit it's rectangle.
+*/
+ if (m_edit->state() == ConnectionEdit::Dragging) {
+ if (m_edit->m_drag_end_point.type == EndPoint::Source) {
+ const QPoint p(s.x(), t.y());
+ m_knee_list.append(p);
+ if (tr.contains(p))
+ t = m_target_pos = p;
+ } else {
+ const QPoint p(t.x(), s.y());
+ m_knee_list.append(p);
+ if (sr.contains(p))
+ s = m_source_pos = p;
+ }
+ } else {
+ m_knee_list.append(QPoint(t.x(), s.y()));
+ }
+ } else {
+/*
+ +--------+
+ | |
+ | o |
+ +--|-----+
+ | +--------+
+ +---+-x |
+ | |
+ +--------+
+
+*/
+ m_knee_list.append(QPoint(s.x(), t.y()));
+ }
+ } else {
+/*
+ +--------+
+ | |
+ | o o-+--------+
+ +--|-----+ |
+ | +-----|--+
+ | | x |
+ +--------+-x |
+ +--------+
+
+ The line enters the target rectangle through the closest edge.
+*/
+ if (sr.topLeft() == r.topLeft()) {
+ if (pointAboveLine(tr.topLeft(), tr.bottomRight(), t))
+ m_knee_list.append(QPoint(t.x(), s.y()));
+ else
+ m_knee_list.append(QPoint(s.x(), t.y()));
+ } else if (sr.topRight() == r.topRight()) {
+ if (pointAboveLine(tr.bottomLeft(), tr.topRight(), t))
+ m_knee_list.append(QPoint(t.x(), s.y()));
+ else
+ m_knee_list.append(QPoint(s.x(), t.y()));
+ } else if (sr.bottomRight() == r.bottomRight()) {
+ if (pointAboveLine(tr.topLeft(), tr.bottomRight(), t))
+ m_knee_list.append(QPoint(s.x(), t.y()));
+ else
+ m_knee_list.append(QPoint(t.x(), s.y()));
+ } else {
+ if (pointAboveLine(tr.bottomLeft(), tr.topRight(), t))
+ m_knee_list.append(QPoint(s.x(), t.y()));
+ else
+ m_knee_list.append(QPoint(t.x(), s.y()));
+ }
+ }
+ }
+ m_knee_list.append(t);
+
+ if (m_knee_list.size() == 2)
+ m_knee_list.clear();
+
+ trimLine();
+
+ const LineDir new_source_label_dir = labelDir(EndPoint::Source);
+ const LineDir new_target_label_dir = labelDir(EndPoint::Target);
+ if (new_source_label_dir != old_source_label_dir)
+ updatePixmap(EndPoint::Source);
+ if (new_target_label_dir != old_target_label_dir)
+ updatePixmap(EndPoint::Target);
+}
+
+void Connection::trimLine()
+{
+ if (m_source == 0 || m_source_pos == QPoint(-1, -1) || m_target_pos == QPoint(-1, -1))
+ return;
+ int cnt = m_knee_list.size();
+ if (cnt < 2)
+ return;
+
+ const QRect sr = m_source_rect;
+ const QRect tr = m_target_rect;
+
+ if (sr.contains(m_knee_list.at(1)))
+ m_knee_list.removeFirst();
+
+ cnt = m_knee_list.size();
+ if (cnt < 2)
+ return;
+
+ if (!tr.contains(sr) && tr.contains(m_knee_list.at(cnt - 2)))
+ m_knee_list.removeLast();
+
+ cnt = m_knee_list.size();
+ if (cnt < 2)
+ return;
+
+ if (sr.contains(m_knee_list.at(0)) && !sr.contains(m_knee_list.at(1)))
+ m_knee_list[0] = lineEntryPos(m_knee_list.at(1), m_knee_list.at(0), sr);
+
+ if (tr.contains(m_knee_list.at(cnt - 1)) && !tr.contains(m_knee_list.at(cnt - 2))) {
+ m_knee_list[cnt - 1]
+ = lineEntryPos(m_knee_list.at(cnt - 2), m_knee_list.at(cnt - 1), tr);
+ m_arrow_head = arrowHead(m_knee_list.at(cnt - 2), m_knee_list.at(cnt - 1));
+ }
+}
+
+void Connection::setSource(QObject *source, const QPoint &pos)
+{
+ if (source == m_source && m_source_pos == pos)
+ return;
+
+ update(false);
+
+ m_source = source;
+ if (QWidget *widget = qobject_cast<QWidget*>(source)) {
+ m_source_pos = pos;
+ m_source_rect = m_edit->widgetRect(widget);
+ updateKneeList();
+ }
+
+ update(false);
+}
+
+void Connection::setTarget(QObject *target, const QPoint &pos)
+{
+ if (target == m_target && m_target_pos == pos)
+ return;
+
+ update(false);
+
+ m_target = target;
+ if (QWidget *widget = qobject_cast<QWidget*>(target)) {
+ m_target_pos = pos;
+ m_target_rect = m_edit->widgetRect(widget);
+ updateKneeList();
+ }
+
+ update(false);
+}
+
+static QRect lineRect(const QPoint &a, const QPoint &b)
+{
+ const QPoint c(qMin(a.x(), b.x()), qMin(a.y(), b.y()));
+ const QPoint d(qMax(a.x(), b.x()), qMax(a.y(), b.y()));
+
+ QRect result(c, d);
+ return expand(result, LINE_PROXIMITY_RADIUS);
+}
+
+QRect Connection::groundRect() const
+{
+ if (!ground())
+ return QRect();
+ if (m_knee_list.isEmpty())
+ return QRect();
+
+ const QPoint p = m_knee_list.last();
+ return QRect(p.x() - GROUND_W/2, p.y(), GROUND_W, GROUND_H);
+}
+
+QRegion Connection::region() const
+{
+ QRegion result;
+
+ for (int i = 0; i < m_knee_list.size() - 1; ++i)
+ result = result.unite(lineRect(m_knee_list.at(i), m_knee_list.at(i + 1)));
+
+ if (!m_arrow_head.isEmpty()) {
+ QRect r = m_arrow_head.boundingRect().toRect();
+ r = expand(r, 1);
+ result = result.unite(r);
+ } else if (ground()) {
+ result = result.unite(groundRect());
+ }
+
+ result = result.unite(labelRect(EndPoint::Source));
+ result = result.unite(labelRect(EndPoint::Target));
+
+ return result;
+}
+
+void Connection::update(bool update_widgets) const
+{
+ m_edit->update(region());
+ if (update_widgets) {
+ if (m_source != 0)
+ m_edit->update(m_source_rect);
+ if (m_target != 0)
+ m_edit->update(m_target_rect);
+ }
+
+ m_edit->update(endPointRect(EndPoint::Source));
+ m_edit->update(endPointRect(EndPoint::Target));
+}
+
+void Connection::paint(QPainter *p) const
+{
+ for (int i = 0; i < m_knee_list.size() - 1; ++i)
+ p->drawLine(m_knee_list.at(i), m_knee_list.at(i + 1));
+
+ if (!m_arrow_head.isEmpty()) {
+ p->save();
+ p->setBrush(p->pen().color());
+ p->drawPolygon(m_arrow_head);
+ p->restore();
+ } else if (ground()) {
+ paintGround(p, groundRect());
+ }
+}
+
+bool Connection::contains(const QPoint &pos) const
+{
+ return region().contains(pos);
+}
+
+QRect Connection::endPointRect(EndPoint::Type type) const
+{
+ if (type == EndPoint::Source) {
+ if (m_source_pos != QPoint(-1, -1))
+ return endPointRectHelper(m_source_pos);
+ } else {
+ if (m_target_pos != QPoint(-1, -1))
+ return endPointRectHelper(m_target_pos);
+ }
+ return QRect();
+}
+
+CETypes::LineDir Connection::labelDir(EndPoint::Type type) const
+{
+ const int cnt = m_knee_list.size();
+ if (cnt < 2)
+ return RightDir;
+
+ LineDir dir;
+ if (type == EndPoint::Source)
+ dir = classifyLine(m_knee_list.at(0), m_knee_list.at(1));
+ else
+ dir = classifyLine(m_knee_list.at(cnt - 2), m_knee_list.at(cnt - 1));
+
+ if (dir == LeftDir)
+ dir = RightDir;
+ if (dir == UpDir)
+ dir = DownDir;
+
+ return dir;
+}
+
+QRect Connection::labelRect(EndPoint::Type type) const
+{
+ const int cnt = m_knee_list.size();
+ if (cnt < 2)
+ return QRect();
+ const QString text = label(type);
+ if (text.isEmpty())
+ return QRect();
+
+ const QSize size = labelPixmap(type).size();
+ QPoint p1, p2;
+ if (type == EndPoint::Source) {
+ p1 = m_knee_list.at(0);
+ p2 = m_knee_list.at(1);
+ } else {
+ p1 = m_knee_list.at(cnt - 1);
+ p2 = m_knee_list.at(cnt - 2);
+ }
+ const LineDir dir = classifyLine(p1, p2);
+
+ QRect result;
+ switch (dir) {
+ case UpDir:
+ result = QRect(p1 + QPoint(-size.width()/2, 0), size);
+ break;
+ case DownDir:
+ result = QRect(p1 + QPoint(-size.width()/2, -size.height()), size);
+ break;
+ case LeftDir:
+ result = QRect(p1 + QPoint(0, -size.height()/2), size);
+ break;
+ case RightDir:
+ result = QRect(p1 + QPoint(-size.width(), -size.height()/2), size);
+ break;
+ }
+
+ return result;
+}
+
+void Connection::setLabel(EndPoint::Type type, const QString &text)
+{
+ if (text == label(type))
+ return;
+
+ if (type == EndPoint::Source)
+ m_source_label = text;
+ else
+ m_target_label = text;
+
+ updatePixmap(type);
+}
+
+void Connection::updatePixmap(EndPoint::Type type)
+{
+ QPixmap *pm = type == EndPoint::Source ? &m_source_label_pm : &m_target_label_pm;
+
+ const QString text = label(type);
+ if (text.isEmpty()) {
+ *pm = QPixmap();
+ return;
+ }
+
+ const QFontMetrics fm = m_edit->fontMetrics();
+ const QSize size = fm.size(Qt::TextSingleLine, text) + QSize(HLABEL_MARGIN*2, VLABEL_MARGIN*2);
+ *pm = QPixmap(size);
+ QColor color = m_edit->palette().color(QPalette::Normal, QPalette::Base);
+ color.setAlpha(190);
+ pm->fill(color);
+
+ QPainter p(pm);
+ p.setPen(m_edit->palette().color(QPalette::Normal, QPalette::Text));
+ p.drawText(-fm.leftBearing(text.at(0)) + HLABEL_MARGIN, fm.ascent() + VLABEL_MARGIN, text);
+ p.end();
+
+ const LineDir dir = labelDir(type);
+
+ if (dir == DownDir)
+ *pm = pm->transformed(QMatrix(0.0, -1.0, 1.0, 0.0, 0.0, 0.0));
+}
+
+void Connection::checkWidgets()
+{
+ bool changed = false;
+
+ if (QWidget *sourceWidget = qobject_cast<QWidget*>(m_source)) {
+ const QRect r = m_edit->widgetRect(sourceWidget);
+ if (r != m_source_rect) {
+ if (m_source_pos != QPoint(-1, -1) && !r.contains(m_source_pos)) {
+ QPoint offset = m_source_pos - m_source_rect.topLeft();
+ QPoint old_pos = m_source_pos;
+ m_source_pos = pointInsideRect(r, r.topLeft() + offset);
+ }
+ m_edit->update(m_source_rect);
+ m_source_rect = r;
+ changed = true;
+ }
+ }
+
+ if (QWidget *targetWidget = qobject_cast<QWidget*>(m_target)) {
+ const QRect r = m_edit->widgetRect(targetWidget);
+ if (r != m_target_rect) {
+ if (m_target_pos != QPoint(-1, -1) && !r.contains(m_target_pos)) {
+ const QPoint offset = m_target_pos - m_target_rect.topLeft();
+ const QPoint old_pos = m_target_pos;
+ m_target_pos = pointInsideRect(r, r.topLeft() + offset);
+ }
+ m_edit->update(m_target_rect);
+ m_target_rect = r;
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ update();
+ updateKneeList();
+ update();
+ }
+}
+
+/*******************************************************************************
+** ConnectionEdit
+*/
+
+ConnectionEdit::ConnectionEdit(QWidget *parent, QDesignerFormWindowInterface *form) :
+ QWidget(parent),
+ m_bg_widget(0),
+ m_undo_stack(form->commandHistory()),
+ m_enable_update_background(false),
+ m_tmp_con(0),
+ m_start_connection_on_drag(true),
+ m_widget_under_mouse(0),
+ m_inactive_color(Qt::blue),
+ m_active_color(Qt::red)
+{
+ setAttribute(Qt::WA_MouseTracking, true);
+ setFocusPolicy(Qt::ClickFocus);
+
+ connect(form, SIGNAL(widgetRemoved(QWidget*)), this, SLOT(widgetRemoved(QWidget*)));
+ connect(form, SIGNAL(objectRemoved(QObject*)), this, SLOT(objectRemoved(QObject*)));
+}
+
+ConnectionEdit::~ConnectionEdit()
+{
+ qDeleteAll(m_con_list);
+}
+
+void ConnectionEdit::clear()
+{
+ m_con_list.clear();
+ m_sel_con_set.clear();
+ m_bg_widget = 0;
+ m_widget_under_mouse = 0;
+ m_tmp_con = 0;
+}
+
+void ConnectionEdit::setBackground(QWidget *background)
+{
+ if (background == m_bg_widget) {
+ // nothing to do
+ return;
+ }
+
+ m_bg_widget = background;
+ updateBackground();
+}
+
+void ConnectionEdit::enableUpdateBackground(bool enable)
+{
+ m_enable_update_background = enable;
+ if (enable)
+ updateBackground();
+}
+
+void ConnectionEdit::updateBackground()
+{
+ // Might happen while reloading a form.
+ if (m_bg_widget == 0)
+ return;
+
+ if (!m_enable_update_background)
+ return;
+
+ foreach(Connection *c, m_con_list)
+ c->updateVisibility();
+
+ updateLines();
+ update();
+}
+
+QWidget *ConnectionEdit::widgetAt(const QPoint &pos) const
+{
+ if (m_bg_widget == 0)
+ return 0;
+ QWidget *widget = m_bg_widget->childAt(pos);
+ if (widget == 0)
+ widget = m_bg_widget;
+
+ return widget;
+}
+
+
+QRect ConnectionEdit::widgetRect(QWidget *w) const
+{
+ if (w == 0)
+ return QRect();
+ QRect r = w->geometry();
+ QPoint pos = w->mapToGlobal(QPoint(0, 0));
+ pos = mapFromGlobal(pos);
+ r.moveTopLeft(pos);
+ return r;
+}
+
+ConnectionEdit::State ConnectionEdit::state() const
+{
+ if (m_tmp_con != 0)
+ return Connecting;
+ if (!m_drag_end_point.isNull())
+ return Dragging;
+ return Editing;
+}
+
+void ConnectionEdit::paintLabel(QPainter *p, EndPoint::Type type, Connection *con)
+{
+ if (con->label(type).isEmpty())
+ return;
+
+ const bool heavy = selected(con) || con == m_tmp_con;
+ p->setPen(heavy ? m_active_color : m_inactive_color);
+ p->setBrush(Qt::NoBrush);
+ const QRect r = con->labelRect(type);
+ p->drawPixmap(r.topLeft(), con->labelPixmap(type));
+ p->drawRect(fixRect(r));
+}
+
+void ConnectionEdit::paintConnection(QPainter *p, Connection *con,
+ WidgetSet *heavy_highlight_set,
+ WidgetSet *light_highlight_set) const
+{
+ QWidget *source = con->widget(EndPoint::Source);
+ QWidget *target = con->widget(EndPoint::Target);
+
+ const bool heavy = selected(con) || con == m_tmp_con;
+ WidgetSet *set = heavy ? heavy_highlight_set : light_highlight_set;
+ p->setPen(heavy ? m_active_color : m_inactive_color);
+ con->paint(p);
+
+ if (source != 0 && source != m_bg_widget)
+ set->insert(source, source);
+
+ if (target != 0 && target != m_bg_widget)
+ set->insert(target, target);
+}
+
+void ConnectionEdit::paintEvent(QPaintEvent *e)
+{
+ QPainter p(this);
+ p.setClipRegion(e->region());
+
+ WidgetSet heavy_highlight_set, light_highlight_set;
+
+ foreach (Connection *con, m_con_list) {
+ if (!con->isVisible())
+ continue;
+
+ paintConnection(&p, con, &heavy_highlight_set, &light_highlight_set);
+ }
+
+ if (m_tmp_con != 0)
+ paintConnection(&p, m_tmp_con, &heavy_highlight_set, &light_highlight_set);
+
+ if (!m_widget_under_mouse.isNull() && m_widget_under_mouse != m_bg_widget)
+ heavy_highlight_set.insert(m_widget_under_mouse, m_widget_under_mouse);
+
+ QColor c = m_active_color;
+ p.setPen(c);
+ c.setAlpha(BG_ALPHA);
+ p.setBrush(c);
+
+ foreach (QWidget *w, heavy_highlight_set) {
+ p.drawRect(fixRect(widgetRect(w)));
+ light_highlight_set.remove(w);
+ }
+
+ c = m_inactive_color;
+ p.setPen(c);
+ c.setAlpha(BG_ALPHA);
+ p.setBrush(c);
+
+ foreach (QWidget *w, light_highlight_set)
+ p.drawRect(fixRect(widgetRect(w)));
+
+ p.setBrush(palette().color(QPalette::Base));
+ p.setPen(palette().color(QPalette::Text));
+ foreach (Connection *con, m_con_list) {
+ if (!con->isVisible())
+ continue;
+
+ paintLabel(&p, EndPoint::Source, con);
+ paintLabel(&p, EndPoint::Target, con);
+ }
+
+ p.setPen(m_active_color);
+ p.setBrush(m_active_color);
+
+ foreach (Connection *con, m_con_list) {
+ if (!selected(con) || !con->isVisible())
+ continue;
+
+ paintEndPoint(&p, con->endPointPos(EndPoint::Source));
+
+ if (con->widget(EndPoint::Target) != 0)
+ paintEndPoint(&p, con->endPointPos(EndPoint::Target));
+ }
+}
+
+void ConnectionEdit::abortConnection()
+{
+ m_tmp_con->update();
+ delete m_tmp_con;
+ m_tmp_con = 0;
+#ifndef QT_NO_CURSOR
+ setCursor(QCursor());
+#endif
+ if (m_widget_under_mouse == m_bg_widget)
+ m_widget_under_mouse = 0;
+}
+
+void ConnectionEdit::mousePressEvent(QMouseEvent *e)
+{
+ // Right click only to cancel
+ const Qt::MouseButton button = e->button();
+ const State cstate = state();
+ if (button != Qt::LeftButton && !(button == Qt::RightButton && cstate == Connecting)) {
+ QWidget::mousePressEvent(e);
+ return;
+ }
+
+ e->accept();
+ // Prefer a non-background widget over the connection,
+ // otherwise, widgets covered by the connection labels cannot be accessed
+ Connection *con_under_mouse = 0;
+ if (!m_widget_under_mouse || m_widget_under_mouse == m_bg_widget)
+ con_under_mouse = connectionAt(e->pos());
+
+ m_start_connection_on_drag = false;
+ switch (cstate) {
+ case Connecting:
+ if (button == Qt::RightButton)
+ abortConnection();
+ break;
+ case Dragging:
+ break;
+ case Editing:
+ if (!m_end_point_under_mouse.isNull()) {
+ if (!(e->modifiers() & Qt::ShiftModifier)) {
+ startDrag(m_end_point_under_mouse, e->pos());
+ }
+ } else if (con_under_mouse != 0) {
+ if (!(e->modifiers() & Qt::ShiftModifier)) {
+ selectNone();
+ setSelected(con_under_mouse, true);
+ } else {
+ setSelected(con_under_mouse, !selected(con_under_mouse));
+ }
+ } else {
+ if (!(e->modifiers() & Qt::ShiftModifier)) {
+ selectNone();
+ if (!m_widget_under_mouse.isNull())
+ m_start_connection_on_drag = true;
+ }
+ }
+ break;
+ }
+}
+
+void ConnectionEdit::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton) {
+ QWidget::mouseDoubleClickEvent(e);
+ return;
+ }
+
+ e->accept();
+ switch (state()) {
+ case Connecting:
+ abortConnection();
+ break;
+ case Dragging:
+ break;
+ case Editing:
+ if (!m_widget_under_mouse.isNull()) {
+ emit widgetActivated(m_widget_under_mouse);
+ } else if (m_sel_con_set.size() == 1) {
+ Connection *con = m_sel_con_set.keys().first();
+ modifyConnection(con);
+ }
+ break;
+ }
+
+}
+
+void ConnectionEdit::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton) {
+ QWidget::mouseReleaseEvent(e);
+ return;
+ }
+ e->accept();
+
+ switch (state()) {
+ case Connecting:
+ if (m_widget_under_mouse.isNull())
+ abortConnection();
+ else
+ endConnection(m_widget_under_mouse, e->pos());
+#ifndef QT_NO_CURSOR
+ setCursor(QCursor());
+#endif
+ break;
+ case Editing:
+ break;
+ case Dragging:
+ endDrag(e->pos());
+ break;
+ }
+}
+
+
+void ConnectionEdit::findObjectsUnderMouse(const QPoint &pos)
+{
+ Connection *con_under_mouse = connectionAt(pos);
+
+ QWidget *w = widgetAt(pos);
+ // Prefer a non-background widget over the connection,
+ // otherwise, widgets covered by the connection labels cannot be accessed
+ if (w == m_bg_widget && con_under_mouse)
+ w = 0;
+ else
+ con_under_mouse = 0;
+
+ if (w != m_widget_under_mouse) {
+ if (!m_widget_under_mouse.isNull())
+ update(widgetRect(m_widget_under_mouse));
+ m_widget_under_mouse = w;
+ if (!m_widget_under_mouse.isNull())
+ update(widgetRect(m_widget_under_mouse));
+ }
+
+ const EndPoint hs = endPointAt(pos);
+ if (hs != m_end_point_under_mouse) {
+#ifndef QT_NO_CURSOR
+ if (m_end_point_under_mouse.isNull())
+ setCursor(Qt::PointingHandCursor);
+ else
+ setCursor(QCursor());
+#endif
+ m_end_point_under_mouse = hs;
+ }
+}
+
+void ConnectionEdit::mouseMoveEvent(QMouseEvent *e)
+{
+ findObjectsUnderMouse(e->pos());
+ switch (state()) {
+ case Connecting:
+ continueConnection(m_widget_under_mouse, e->pos());
+ break;
+ case Editing:
+ if ((e->buttons() & Qt::LeftButton)
+ && m_start_connection_on_drag
+ && !m_widget_under_mouse.isNull()) {
+ m_start_connection_on_drag = false;
+ startConnection(m_widget_under_mouse, e->pos());
+#ifndef QT_NO_CURSOR
+ setCursor(Qt::CrossCursor);
+#endif
+ }
+ break;
+ case Dragging:
+ continueDrag(e->pos());
+ break;
+ }
+
+ e->accept();
+}
+
+void ConnectionEdit::keyPressEvent(QKeyEvent *e)
+{
+ switch (e->key()) {
+ case Qt::Key_Delete:
+ if (state() == Editing)
+ deleteSelected();
+ break;
+ case Qt::Key_Escape:
+ if (state() == Connecting)
+ abortConnection();
+ break;
+ }
+
+ e->accept();
+}
+
+void ConnectionEdit::startConnection(QWidget *source, const QPoint &pos)
+{
+ Q_ASSERT(m_tmp_con == 0);
+
+ m_tmp_con = new Connection(this);
+ m_tmp_con->setEndPoint(EndPoint::Source, source, pos);
+}
+
+void ConnectionEdit::endConnection(QWidget *target, const QPoint &pos)
+{
+ Q_ASSERT(m_tmp_con != 0);
+
+ m_tmp_con->setEndPoint(EndPoint::Target, target, pos);
+
+ QWidget *source = m_tmp_con->widget(EndPoint::Source);
+ Q_ASSERT(source != 0);
+ Q_ASSERT(target != 0);
+ setEnabled(false);
+ Connection *new_con = createConnection(source, target);
+ setEnabled(true);
+ if (new_con != 0) {
+ new_con->setEndPoint(EndPoint::Source, source, m_tmp_con->endPointPos(EndPoint::Source));
+ new_con->setEndPoint(EndPoint::Target, target, m_tmp_con->endPointPos(EndPoint::Target));
+ m_undo_stack->push(new AddConnectionCommand(this, new_con));
+ emit connectionChanged(new_con);
+ }
+
+ delete m_tmp_con;
+ m_tmp_con = 0;
+
+ findObjectsUnderMouse(mapFromGlobal(QCursor::pos()));
+}
+
+void ConnectionEdit::continueConnection(QWidget *target, const QPoint &pos)
+{
+ Q_ASSERT(m_tmp_con != 0);
+
+ m_tmp_con->setEndPoint(EndPoint::Target, target, pos);
+}
+
+void ConnectionEdit::modifyConnection(Connection *)
+{
+}
+
+Connection *ConnectionEdit::createConnection(QWidget *source, QWidget *target)
+{
+ Connection *con = new Connection(this, source, target);
+ return con;
+}
+
+// Find all connections which in which a sequence of objects is involved
+template <class ObjectIterator>
+static ConnectionEdit::ConnectionSet findConnectionsOf(const ConnectionEdit::ConnectionList &cl, ObjectIterator oi1, const ObjectIterator &oi2)
+{
+ ConnectionEdit::ConnectionSet rc;
+
+ const ConnectionEdit::ConnectionList::const_iterator ccend = cl.constEnd();
+ for ( ; oi1 != oi2; ++oi1) {
+ for (ConnectionEdit::ConnectionList::const_iterator cit = cl.constBegin(); cit != ccend; ++cit) {
+ Connection *con = *cit;
+ if (con->object(ConnectionEdit::EndPoint::Source) == *oi1 || con->object(ConnectionEdit::EndPoint::Target) == *oi1)
+ rc.insert(con, con);
+ }
+ }
+ return rc;
+}
+
+void ConnectionEdit::widgetRemoved(QWidget *widget)
+{
+ // Remove all connections of that widget and its children.
+ if (m_con_list.empty())
+ return;
+
+ QWidgetList child_list = widget->findChildren<QWidget*>();
+ child_list.prepend(widget);
+
+ const ConnectionSet remove_set = findConnectionsOf(m_con_list, child_list.constBegin(), child_list.constEnd());
+
+ if (!remove_set.isEmpty())
+ m_undo_stack->push(new DeleteConnectionsCommand(this, remove_set.keys()));
+
+ updateBackground();
+}
+
+void ConnectionEdit::objectRemoved(QObject *o)
+{
+ // Remove all connections of that object and its children (in case of action groups).
+ if (m_con_list.empty())
+ return;
+
+ QObjectList child_list = o->children();
+ child_list.prepend(o);
+ const ConnectionSet remove_set = findConnectionsOf(m_con_list, child_list.constBegin(), child_list.constEnd());
+ if (!remove_set.isEmpty())
+ m_undo_stack->push(new DeleteConnectionsCommand(this, remove_set.keys()));
+
+ updateBackground();
+}
+
+void ConnectionEdit::setSelected(Connection *con, bool sel)
+{
+ if (!con || sel == m_sel_con_set.contains(con))
+ return;
+
+ if (sel) {
+ m_sel_con_set.insert(con, con);
+ emit connectionSelected(con);
+ } else {
+ m_sel_con_set.remove(con);
+ }
+
+ con->update();
+}
+
+bool ConnectionEdit::selected(const Connection *con) const
+{
+ return m_sel_con_set.contains(const_cast<Connection*>(con));
+}
+
+void ConnectionEdit::selectNone()
+{
+ foreach (Connection *con, m_sel_con_set)
+ con->update();
+
+ m_sel_con_set.clear();
+}
+
+void ConnectionEdit::selectAll()
+{
+ if (m_sel_con_set.size() == m_con_list.size())
+ return;
+ foreach (Connection *con, m_con_list)
+ setSelected(con, true);
+}
+
+Connection *ConnectionEdit::connectionAt(const QPoint &pos) const
+{
+ foreach (Connection *con, m_con_list) {
+ if (con->contains(pos))
+ return con;
+ }
+ return 0;
+}
+
+CETypes::EndPoint ConnectionEdit::endPointAt(const QPoint &pos) const
+{
+ foreach (Connection *con, m_con_list) {
+ if (!selected(con))
+ continue;
+ const QRect sr = con->endPointRect(EndPoint::Source);
+ const QRect tr = con->endPointRect(EndPoint::Target);
+
+ if (sr.contains(pos))
+ return EndPoint(con, EndPoint::Source);
+ if (tr.contains(pos))
+ return EndPoint(con, EndPoint::Target);
+ }
+ return EndPoint();
+}
+
+void ConnectionEdit::startDrag(const EndPoint &end_point, const QPoint &pos)
+{
+ Q_ASSERT(m_drag_end_point.isNull());
+ m_drag_end_point = end_point;
+ m_old_source_pos = m_drag_end_point.con->endPointPos(EndPoint::Source);
+ m_old_target_pos = m_drag_end_point.con->endPointPos(EndPoint::Target);
+ adjustHotSopt(m_drag_end_point, pos);
+}
+
+void ConnectionEdit::continueDrag(const QPoint &pos)
+{
+ Q_ASSERT(!m_drag_end_point.isNull());
+ adjustHotSopt(m_drag_end_point, pos);
+}
+
+void ConnectionEdit::endDrag(const QPoint &pos)
+{
+ Q_ASSERT(!m_drag_end_point.isNull());
+ adjustHotSopt(m_drag_end_point, pos);
+
+ Connection *con = m_drag_end_point.con;
+ const QPoint new_source_pos = con->endPointPos(EndPoint::Source);
+ const QPoint new_target_pos = con->endPointPos(EndPoint::Target);
+ m_undo_stack->push(new AdjustConnectionCommand(this, con, m_old_source_pos, m_old_target_pos,
+ new_source_pos, new_target_pos));
+
+ m_drag_end_point = EndPoint();
+}
+
+void ConnectionEdit::adjustHotSopt(const EndPoint &end_point, const QPoint &pos)
+{
+ QWidget *w = end_point.con->widget(end_point.type);
+ end_point.con->setEndPoint(end_point.type, w, pointInsideRect(widgetRect(w), pos));
+}
+
+void ConnectionEdit::deleteSelected()
+{
+ if (m_sel_con_set.isEmpty())
+ return;
+ m_undo_stack->push(new DeleteConnectionsCommand(this, m_sel_con_set.keys()));
+}
+
+void ConnectionEdit::addConnection(Connection *con)
+{
+ m_con_list.append(con);
+}
+
+void ConnectionEdit::updateLines()
+{
+ foreach (Connection *con, m_con_list)
+ con->checkWidgets();
+}
+
+void ConnectionEdit::resizeEvent(QResizeEvent *e)
+{
+ updateBackground();
+ QWidget::resizeEvent(e);
+}
+
+void ConnectionEdit::setSource(Connection *con, const QString &obj_name)
+{
+ QObject *object = 0;
+ if (!obj_name.isEmpty()) {
+ object = m_bg_widget->findChild<QObject*>(obj_name);
+ if (object == 0 && m_bg_widget->objectName() == obj_name)
+ object = m_bg_widget;
+
+ if (object == con->object(EndPoint::Source))
+ return;
+ }
+ m_undo_stack->push(new SetEndPointCommand(this, con, EndPoint::Source, object));
+}
+
+void ConnectionEdit::setTarget(Connection *con, const QString &obj_name)
+{
+ QObject *object = 0;
+ if (!obj_name.isEmpty()) {
+ object = m_bg_widget->findChild<QObject*>(obj_name);
+ if (object == 0 && m_bg_widget->objectName() == obj_name)
+ object = m_bg_widget;
+
+ if (object == con->object(EndPoint::Target))
+ return;
+ }
+ m_undo_stack->push(new SetEndPointCommand(this, con, EndPoint::Target, object));
+}
+
+Connection *ConnectionEdit::takeConnection(Connection *con)
+{
+ if (!m_con_list.contains(con))
+ return 0;
+ m_con_list.removeAll(con);
+ return con;
+}
+
+void ConnectionEdit::clearNewlyAddedConnection()
+{
+ delete m_tmp_con;
+ m_tmp_con = 0;
+}
+
+void ConnectionEdit::createContextMenu(QMenu &menu)
+{
+ // Select
+ QAction *selectAllAction = menu.addAction(tr("Select All"));
+ selectAllAction->setEnabled(connectionList().size());
+ connect(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll()));
+ QAction *deselectAllAction = menu.addAction(tr("Deselect All"));
+ deselectAllAction->setEnabled(selection().size());
+ connect(deselectAllAction, SIGNAL(triggered()), this, SLOT(selectNone()));
+ menu.addSeparator();
+ // Delete
+ QAction *deleteAction = menu.addAction(tr("Delete"));
+ deleteAction->setShortcut(QKeySequence::Delete);
+ deleteAction->setEnabled(!selection().isEmpty());
+ connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteSelected()));
+}
+
+void ConnectionEdit::contextMenuEvent(QContextMenuEvent * event)
+{
+ QMenu menu;
+ createContextMenu(menu);
+ menu.exec(event->globalPos());
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/connectionedit_p.h b/src/designer/src/lib/shared/connectionedit_p.h
new file mode 100644
index 000000000..553fbe188
--- /dev/null
+++ b/src/designer/src/lib/shared/connectionedit_p.h
@@ -0,0 +1,324 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef CONNECTIONEDIT_H
+#define CONNECTIONEDIT_H
+
+#include "shared_global_p.h"
+
+#include <QtCore/QMultiMap>
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+
+#include <QtGui/QWidget>
+#include <QtGui/QPixmap>
+#include <QtGui/QPolygonF>
+
+#include <QtGui/QUndoCommand>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QUndoStack;
+class QMenu;
+
+namespace qdesigner_internal {
+
+class Connection;
+class ConnectionEdit;
+
+class QDESIGNER_SHARED_EXPORT CETypes
+{
+public:
+ typedef QList<Connection*> ConnectionList;
+ typedef QMap<Connection*, Connection*> ConnectionSet;
+ typedef QMap<QWidget*, QWidget*> WidgetSet;
+
+ class EndPoint {
+ public:
+ enum Type { Source, Target };
+ explicit EndPoint(Connection *_con = 0, Type _type = Source) : con(_con), type(_type) {}
+ bool isNull() const { return con == 0; }
+ bool operator == (const EndPoint &other) const { return con == other.con && type == other.type; }
+ bool operator != (const EndPoint &other) const { return !operator == (other); }
+ Connection *con;
+ Type type;
+ };
+ enum LineDir { UpDir = 0, DownDir, RightDir, LeftDir };
+};
+
+class QDESIGNER_SHARED_EXPORT Connection : public CETypes
+{
+public:
+ explicit Connection(ConnectionEdit *edit);
+ explicit Connection(ConnectionEdit *edit, QObject *source, QObject *target);
+ virtual ~Connection() {}
+
+ QObject *object(EndPoint::Type type) const
+ {
+ return (type == EndPoint::Source ? m_source : m_target);
+ }
+
+ QWidget *widget(EndPoint::Type type) const
+ {
+ return qobject_cast<QWidget*>(object(type));
+ }
+
+ QPoint endPointPos(EndPoint::Type type) const;
+ QRect endPointRect(EndPoint::Type) const;
+ void setEndPoint(EndPoint::Type type, QObject *w, const QPoint &pos)
+ { type == EndPoint::Source ? setSource(w, pos) : setTarget(w, pos); }
+
+ bool isVisible() const;
+ virtual void updateVisibility();
+ void setVisible(bool b);
+
+ virtual QRegion region() const;
+ bool contains(const QPoint &pos) const;
+ virtual void paint(QPainter *p) const;
+
+ void update(bool update_widgets = true) const;
+ void checkWidgets();
+
+ QString label(EndPoint::Type type) const
+ { return type == EndPoint::Source ? m_source_label : m_target_label; }
+ void setLabel(EndPoint::Type type, const QString &text);
+ QRect labelRect(EndPoint::Type type) const;
+ QPixmap labelPixmap(EndPoint::Type type) const
+ { return type == EndPoint::Source ? m_source_label_pm : m_target_label_pm; }
+
+ ConnectionEdit *edit() const { return m_edit; }
+
+ virtual void inserted() {}
+ virtual void removed() {}
+
+private:
+ QPoint m_source_pos, m_target_pos;
+ QObject *m_source, *m_target;
+ QList<QPoint> m_knee_list;
+ QPolygonF m_arrow_head;
+ ConnectionEdit *m_edit;
+ QString m_source_label, m_target_label;
+ QPixmap m_source_label_pm, m_target_label_pm;
+ QRect m_source_rect, m_target_rect;
+ bool m_visible;
+
+ void setSource(QObject *source, const QPoint &pos);
+ void setTarget(QObject *target, const QPoint &pos);
+ void updateKneeList();
+ void trimLine();
+ void updatePixmap(EndPoint::Type type);
+ LineDir labelDir(EndPoint::Type type) const;
+ bool ground() const;
+ QRect groundRect() const;
+};
+
+class QDESIGNER_SHARED_EXPORT ConnectionEdit : public QWidget, public CETypes
+{
+ Q_OBJECT
+public:
+ ConnectionEdit(QWidget *parent, QDesignerFormWindowInterface *form);
+ virtual ~ConnectionEdit();
+
+ inline const QPointer<QWidget> &background() const { return m_bg_widget; }
+
+ void setSelected(Connection *con, bool sel);
+ bool selected(const Connection *con) const;
+
+ int connectionCount() const { return m_con_list.size(); }
+ Connection *connection(int i) const { return m_con_list.at(i); }
+ int indexOfConnection(Connection *con) const { return m_con_list.indexOf(con); }
+
+ virtual void setSource(Connection *con, const QString &obj_name);
+ virtual void setTarget(Connection *con, const QString &obj_name);
+
+ QUndoStack *undoStack() const { return m_undo_stack; }
+
+ void clear();
+
+ void showEvent(QShowEvent * /*e*/)
+ {
+ updateBackground();
+ }
+
+signals:
+ void aboutToAddConnection(int idx);
+ void connectionAdded(Connection *con);
+ void aboutToRemoveConnection(Connection *con);
+ void connectionRemoved(int idx);
+ void connectionSelected(Connection *con);
+ void widgetActivated(QWidget *wgt);
+ void connectionChanged(Connection *con);
+
+public slots:
+ void selectNone();
+ void selectAll();
+ virtual void deleteSelected();
+ virtual void setBackground(QWidget *background);
+ virtual void updateBackground();
+ virtual void widgetRemoved(QWidget *w);
+ virtual void objectRemoved(QObject *o);
+
+ void updateLines();
+ void enableUpdateBackground(bool enable);
+
+protected:
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void contextMenuEvent(QContextMenuEvent * event);
+
+ virtual Connection *createConnection(QWidget *source, QWidget *target);
+ virtual void modifyConnection(Connection *con);
+
+ virtual QWidget *widgetAt(const QPoint &pos) const;
+ virtual void createContextMenu(QMenu &menu);
+ void addConnection(Connection *con);
+ QRect widgetRect(QWidget *w) const;
+
+ enum State { Editing, Connecting, Dragging };
+ State state() const;
+
+ virtual void endConnection(QWidget *target, const QPoint &pos);
+
+ const ConnectionList &connectionList() const { return m_con_list; }
+ const ConnectionSet &selection() const { return m_sel_con_set; }
+ Connection *takeConnection(Connection *con);
+ Connection *newlyAddedConnection() { return m_tmp_con; }
+ void clearNewlyAddedConnection();
+
+ void findObjectsUnderMouse(const QPoint &pos);
+
+private:
+ void startConnection(QWidget *source, const QPoint &pos);
+ void continueConnection(QWidget *target, const QPoint &pos);
+ void abortConnection();
+
+ void startDrag(const EndPoint &end_point, const QPoint &pos);
+ void continueDrag(const QPoint &pos);
+ void endDrag(const QPoint &pos);
+ void adjustHotSopt(const EndPoint &end_point, const QPoint &pos);
+ Connection *connectionAt(const QPoint &pos) const;
+ EndPoint endPointAt(const QPoint &pos) const;
+ void paintConnection(QPainter *p, Connection *con,
+ WidgetSet *heavy_highlight_set,
+ WidgetSet *light_highlight_set) const;
+ void paintLabel(QPainter *p, EndPoint::Type type, Connection *con);
+
+
+ QPointer<QWidget> m_bg_widget;
+ QUndoStack *m_undo_stack;
+ bool m_enable_update_background;
+
+ Connection *m_tmp_con; // the connection we are currently editing
+ ConnectionList m_con_list;
+ bool m_start_connection_on_drag;
+ EndPoint m_end_point_under_mouse;
+ QPointer<QWidget> m_widget_under_mouse;
+
+ EndPoint m_drag_end_point;
+ QPoint m_old_source_pos, m_old_target_pos;
+ ConnectionSet m_sel_con_set;
+ const QColor m_inactive_color;
+ const QColor m_active_color;
+
+private:
+ friend class Connection;
+ friend class AddConnectionCommand;
+ friend class DeleteConnectionsCommand;
+ friend class SetEndPointCommand;
+};
+
+class QDESIGNER_SHARED_EXPORT CECommand : public QUndoCommand, public CETypes
+{
+public:
+ explicit CECommand(ConnectionEdit *edit)
+ : m_edit(edit) {}
+
+ virtual bool mergeWith(const QUndoCommand *) { return false; }
+
+ ConnectionEdit *edit() const { return m_edit; }
+
+private:
+ ConnectionEdit *m_edit;
+};
+
+class QDESIGNER_SHARED_EXPORT AddConnectionCommand : public CECommand
+{
+public:
+ AddConnectionCommand(ConnectionEdit *edit, Connection *con);
+ virtual void redo();
+ virtual void undo();
+private:
+ Connection *m_con;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteConnectionsCommand : public CECommand
+{
+public:
+ DeleteConnectionsCommand(ConnectionEdit *edit, const ConnectionList &con_list);
+ virtual void redo();
+ virtual void undo();
+private:
+ ConnectionList m_con_list;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // CONNECTIONEDIT_H
diff --git a/src/designer/src/lib/shared/csshighlighter.cpp b/src/designer/src/lib/shared/csshighlighter.cpp
new file mode 100644
index 000000000..4d833b2ab
--- /dev/null
+++ b/src/designer/src/lib/shared/csshighlighter.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "csshighlighter_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+CssHighlighter::CssHighlighter(QTextDocument *document)
+: QSyntaxHighlighter(document)
+{
+}
+
+void CssHighlighter::highlightBlock(const QString& text)
+{
+ enum Token { ALNUM, LBRACE, RBRACE, COLON, SEMICOLON, COMMA, QUOTE, SLASH, STAR };
+ static const int transitions[10][9] = {
+ { Selector, Property, Selector, Pseudo, Property, Selector, Quote, MaybeComment, Selector }, // Selector
+ { Property, Property, Selector, Value, Property, Property, Quote, MaybeComment, Property }, // Property
+ { Value, Property, Selector, Value, Property, Value, Quote, MaybeComment, Value }, // Value
+ { Pseudo1, Property, Selector, Pseudo2, Selector, Selector, Quote, MaybeComment, Pseudo }, // Pseudo
+ { Pseudo1, Property, Selector, Pseudo, Selector, Selector, Quote, MaybeComment, Pseudo1 }, // Pseudo1
+ { Pseudo2, Property, Selector, Pseudo, Selector, Selector, Quote, MaybeComment, Pseudo2 }, // Pseudo2
+ { Quote, Quote, Quote, Quote, Quote, Quote, -1, Quote, Quote }, // Quote
+ { -1, -1, -1, -1, -1, -1, -1, -1, Comment }, // MaybeComment
+ { Comment, Comment, Comment, Comment, Comment, Comment, Comment, Comment, MaybeCommentEnd }, // Comment
+ { Comment, Comment, Comment, Comment, Comment, Comment, Comment, -1, MaybeCommentEnd } // MaybeCommentEnd
+ };
+
+ int lastIndex = 0;
+ bool lastWasSlash = false;
+ int state = previousBlockState(), save_state;
+ if (state == -1) {
+ // As long as the text is empty, leave the state undetermined
+ if (text.isEmpty()) {
+ setCurrentBlockState(-1);
+ return;
+ }
+ // The initial state is based on the precense of a : and the absense of a {.
+ // This is because Qt style sheets support both a full stylesheet as well as
+ // an inline form with just properties.
+ state = save_state = (text.indexOf(QLatin1Char(':')) > -1 &&
+ text.indexOf(QLatin1Char('{')) == -1) ? Property : Selector;
+ } else {
+ save_state = state>>16;
+ state &= 0x00ff;
+ }
+
+ if (state == MaybeCommentEnd) {
+ state = Comment;
+ } else if (state == MaybeComment) {
+ state = save_state;
+ }
+
+ for (int i = 0; i < text.length(); i++) {
+ int token = ALNUM;
+ const QChar c = text.at(i);
+ const char a = c.toAscii();
+
+ if (state == Quote) {
+ if (a == '\\') {
+ lastWasSlash = true;
+ } else {
+ if (a == '\"' && !lastWasSlash) {
+ token = QUOTE;
+ }
+ lastWasSlash = false;
+ }
+ } else {
+ switch (a) {
+ case '{': token = LBRACE; break;
+ case '}': token = RBRACE; break;
+ case ':': token = COLON; break;
+ case ';': token = SEMICOLON; break;
+ case ',': token = COMMA; break;
+ case '\"': token = QUOTE; break;
+ case '/': token = SLASH; break;
+ case '*': token = STAR; break;
+ default: break;
+ }
+ }
+
+ int new_state = transitions[state][token];
+
+ if (new_state != state) {
+ bool include_token = new_state == MaybeCommentEnd || (state == MaybeCommentEnd && new_state!= Comment)
+ || state == Quote;
+ highlight(text, lastIndex, i-lastIndex+include_token, state);
+
+ if (new_state == Comment) {
+ lastIndex = i-1; // include the slash and star
+ } else {
+ lastIndex = i + ((token == ALNUM || new_state == Quote) ? 0 : 1);
+ }
+ }
+
+ if (new_state == -1) {
+ state = save_state;
+ } else if (state <= Pseudo2) {
+ save_state = state;
+ state = new_state;
+ } else {
+ state = new_state;
+ }
+ }
+
+ highlight(text, lastIndex, text.length() - lastIndex, state);
+ setCurrentBlockState(state + (save_state<<16));
+}
+
+void CssHighlighter::highlight(const QString &text, int start, int length, int state)
+{
+ if (start >= text.length() || length <= 0)
+ return;
+
+ QTextCharFormat format;
+
+ switch (state) {
+ case Selector:
+ setFormat(start, length, Qt::darkRed);
+ break;
+ case Property:
+ setFormat(start, length, Qt::blue);
+ break;
+ case Value:
+ setFormat(start, length, Qt::black);
+ break;
+ case Pseudo1:
+ setFormat(start, length, Qt::darkRed);
+ break;
+ case Pseudo2:
+ setFormat(start, length, Qt::darkRed);
+ break;
+ case Quote:
+ setFormat(start, length, Qt::darkMagenta);
+ break;
+ case Comment:
+ case MaybeCommentEnd:
+ format.setForeground(Qt::darkGreen);
+ setFormat(start, length, format);
+ break;
+ default:
+ break;
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/csshighlighter_p.h b/src/designer/src/lib/shared/csshighlighter_p.h
new file mode 100644
index 000000000..f8be2f2c0
--- /dev/null
+++ b/src/designer/src/lib/shared/csshighlighter_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef CSSHIGHLIGHTER_H
+#define CSSHIGHLIGHTER_H
+
+#include <QtGui/QSyntaxHighlighter>
+#include "shared_global_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT CssHighlighter : public QSyntaxHighlighter
+{
+ Q_OBJECT
+public:
+ explicit CssHighlighter(QTextDocument *document);
+
+protected:
+ void highlightBlock(const QString&);
+ void highlight(const QString&, int, int, int/*State*/);
+
+private:
+ enum State { Selector, Property, Value, Pseudo, Pseudo1, Pseudo2, Quote,
+ MaybeComment, Comment, MaybeCommentEnd };
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // CSSHIGHLIGHTER_H
diff --git a/src/designer/src/lib/shared/defaultgradients.xml b/src/designer/src/lib/shared/defaultgradients.xml
new file mode 100644
index 000000000..70559ad12
--- /dev/null
+++ b/src/designer/src/lib/shared/defaultgradients.xml
@@ -0,0 +1,498 @@
+<gradients>
+ <gradient name="BlackWhite" >
+ <gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
+ <stopData position="0" >
+ <colorData g="0" r="0" a="255" b="0" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Czech" >
+ <gradientData centerX="0.5" centerY="0.5" spread="RepeatSpread" coordinateMode="StretchToDeviceMode" type="ConicalGradient" angle="0" >
+ <stopData position="0" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.373978669201521" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.3739913434727503" >
+ <colorData g="30" r="33" a="255" b="255" />
+ </stopData>
+ <stopData position="0.6240176679340937" >
+ <colorData g="30" r="33" a="255" b="255" />
+ </stopData>
+ <stopData position="0.6240430164765525" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Dutch" >
+ <gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="0" endY="1" >
+ <stopData position="0" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.3397947548460661" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.339798898163606" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.6624439732888147" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.6624690150250417" >
+ <colorData g="0" r="0" a="255" b="255" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="0" r="0" a="255" b="255" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Eye" >
+ <gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
+ <stopData position="0" >
+ <colorData g="0" r="0" a="255" b="0" />
+ </stopData>
+ <stopData position="0.1939699465240642" >
+ <colorData g="0" r="0" a="255" b="0" />
+ </stopData>
+ <stopData position="0.202312192513369" >
+ <colorData g="97" r="122" a="255" b="0" />
+ </stopData>
+ <stopData position="0.4955143315508022" >
+ <colorData g="58" r="76" a="255" b="0" />
+ </stopData>
+ <stopData position="0.5048191443850267" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.79" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="158" r="255" a="255" b="158" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Flare1" >
+ <gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
+ <stopData position="0" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.1" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.2" >
+ <colorData g="176" r="255" a="167" b="176" />
+ </stopData>
+ <stopData position="0.3" >
+ <colorData g="151" r="255" a="92" b="151" />
+ </stopData>
+ <stopData position="0.4" >
+ <colorData g="125" r="255" a="51" b="125" />
+ </stopData>
+ <stopData position="0.5" >
+ <colorData g="76" r="255" a="205" b="76" />
+ </stopData>
+ <stopData position="0.52" >
+ <colorData g="76" r="255" a="205" b="76" />
+ </stopData>
+ <stopData position="0.6" >
+ <colorData g="180" r="255" a="84" b="180" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="255" r="255" a="0" b="255" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Flare2" >
+ <gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
+ <stopData position="0" >
+ <colorData g="0" r="0" a="0" b="0" />
+ </stopData>
+ <stopData position="0.52" >
+ <colorData g="0" r="0" a="0" b="0" />
+ </stopData>
+ <stopData position="0.5649999999999999" >
+ <colorData g="121" r="82" a="33" b="76" />
+ </stopData>
+ <stopData position="0.65" >
+ <colorData g="235" r="159" a="64" b="148" />
+ </stopData>
+ <stopData position="0.7219251336898396" >
+ <colorData g="238" r="255" a="129" b="150" />
+ </stopData>
+ <stopData position="0.77" >
+ <colorData g="128" r="255" a="204" b="128" />
+ </stopData>
+ <stopData position="0.89" >
+ <colorData g="128" r="191" a="64" b="255" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="0" r="0" a="0" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Flare3" >
+ <gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
+ <stopData position="0" >
+ <colorData g="235" r="255" a="206" b="235" />
+ </stopData>
+ <stopData position="0.35" >
+ <colorData g="188" r="255" a="80" b="188" />
+ </stopData>
+ <stopData position="0.4" >
+ <colorData g="162" r="255" a="80" b="162" />
+ </stopData>
+ <stopData position="0.425" >
+ <colorData g="132" r="255" a="156" b="132" />
+ </stopData>
+ <stopData position="0.44" >
+ <colorData g="128" r="252" a="80" b="128" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="255" r="255" a="0" b="255" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="German" >
+ <gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="0" endY="1" >
+ <stopData position="0" >
+ <colorData g="0" r="0" a="255" b="0" />
+ </stopData>
+ <stopData position="0.33" >
+ <colorData g="0" r="0" a="255" b="0" />
+ </stopData>
+ <stopData position="0.34" >
+ <colorData g="30" r="255" a="255" b="30" />
+ </stopData>
+ <stopData position="0.66" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.67" >
+ <colorData g="255" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="255" r="255" a="255" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Golden" >
+ <gradientData centerX="0.5" centerY="0.5" spread="PadSpread" coordinateMode="StretchToDeviceMode" type="ConicalGradient" angle="0" >
+ <stopData position="0" >
+ <colorData g="40" r="35" a="255" b="3" />
+ </stopData>
+ <stopData position="0.16" >
+ <colorData g="106" r="136" a="255" b="22" />
+ </stopData>
+ <stopData position="0.225" >
+ <colorData g="140" r="166" a="255" b="41" />
+ </stopData>
+ <stopData position="0.285" >
+ <colorData g="181" r="204" a="255" b="74" />
+ </stopData>
+ <stopData position="0.345" >
+ <colorData g="219" r="235" a="255" b="102" />
+ </stopData>
+ <stopData position="0.415" >
+ <colorData g="236" r="245" a="255" b="112" />
+ </stopData>
+ <stopData position="0.52" >
+ <colorData g="190" r="209" a="255" b="76" />
+ </stopData>
+ <stopData position="0.57" >
+ <colorData g="156" r="187" a="255" b="51" />
+ </stopData>
+ <stopData position="0.635" >
+ <colorData g="142" r="168" a="255" b="42" />
+ </stopData>
+ <stopData position="0.695" >
+ <colorData g="174" r="202" a="255" b="68" />
+ </stopData>
+ <stopData position="0.75" >
+ <colorData g="202" r="218" a="255" b="86" />
+ </stopData>
+ <stopData position="0.8149999999999999" >
+ <colorData g="187" r="208" a="255" b="73" />
+ </stopData>
+ <stopData position="0.88" >
+ <colorData g="156" r="187" a="255" b="51" />
+ </stopData>
+ <stopData position="0.9350000000000001" >
+ <colorData g="108" r="137" a="255" b="26" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="40" r="35" a="255" b="3" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Japanese" >
+ <gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
+ <stopData position="0" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.4799044117647059" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.5226851604278074" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Norwegian" >
+ <gradientData spread="RepeatSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
+ <stopData position="0" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.17" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.18" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.2102117403738299" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.2202117403738299" >
+ <colorData g="16" r="0" a="255" b="255" />
+ </stopData>
+ <stopData position="0.2798973635190806" >
+ <colorData g="16" r="0" a="255" b="255" />
+ </stopData>
+ <stopData position="0.2898973635190806" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.32" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.33" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Pastels" >
+ <gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
+ <stopData position="0" >
+ <colorData g="224" r="245" a="255" b="176" />
+ </stopData>
+ <stopData position="0.09" >
+ <colorData g="189" r="246" a="255" b="237" />
+ </stopData>
+ <stopData position="0.14" >
+ <colorData g="207" r="194" a="255" b="246" />
+ </stopData>
+ <stopData position="0.19" >
+ <colorData g="160" r="184" a="255" b="168" />
+ </stopData>
+ <stopData position="0.25" >
+ <colorData g="186" r="171" a="255" b="248" />
+ </stopData>
+ <stopData position="0.32" >
+ <colorData g="248" r="243" a="255" b="224" />
+ </stopData>
+ <stopData position="0.385" >
+ <colorData g="162" r="249" a="255" b="183" />
+ </stopData>
+ <stopData position="0.47" >
+ <colorData g="115" r="100" a="255" b="124" />
+ </stopData>
+ <stopData position="0.58" >
+ <colorData g="205" r="251" a="255" b="202" />
+ </stopData>
+ <stopData position="0.65" >
+ <colorData g="128" r="170" a="255" b="185" />
+ </stopData>
+ <stopData position="0.75" >
+ <colorData g="222" r="252" a="255" b="204" />
+ </stopData>
+ <stopData position="0.805" >
+ <colorData g="122" r="206" a="255" b="218" />
+ </stopData>
+ <stopData position="0.86" >
+ <colorData g="223" r="254" a="255" b="175" />
+ </stopData>
+ <stopData position="0.91" >
+ <colorData g="236" r="254" a="255" b="244" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="191" r="255" a="255" b="221" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Polish" >
+ <gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="0" endY="1" >
+ <stopData position="0" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.495" >
+ <colorData g="255" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="0.505" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Rainbow" >
+ <gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
+ <stopData position="0" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.166" >
+ <colorData g="255" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.333" >
+ <colorData g="255" r="0" a="255" b="0" />
+ </stopData>
+ <stopData position="0.5" >
+ <colorData g="255" r="0" a="255" b="255" />
+ </stopData>
+ <stopData position="0.666" >
+ <colorData g="0" r="0" a="255" b="255" />
+ </stopData>
+ <stopData position="0.833" >
+ <colorData g="0" r="255" a="255" b="255" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="0" r="255" a="255" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Sky" >
+ <gradientData spread="PadSpread" startX="0" startY="1" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="0" endY="0" >
+ <stopData position="0" >
+ <colorData g="0" r="0" a="255" b="0" />
+ </stopData>
+ <stopData position="0.05" >
+ <colorData g="8" r="14" a="255" b="73" />
+ </stopData>
+ <stopData position="0.36" >
+ <colorData g="17" r="28" a="255" b="145" />
+ </stopData>
+ <stopData position="0.6" >
+ <colorData g="14" r="126" a="255" b="81" />
+ </stopData>
+ <stopData position="0.75" >
+ <colorData g="11" r="234" a="255" b="11" />
+ </stopData>
+ <stopData position="0.79" >
+ <colorData g="70" r="244" a="255" b="5" />
+ </stopData>
+ <stopData position="0.86" >
+ <colorData g="136" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.9350000000000001" >
+ <colorData g="236" r="239" a="255" b="55" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="SunRay" >
+ <gradientData centerX="0" centerY="0" spread="RepeatSpread" coordinateMode="StretchToDeviceMode" type="ConicalGradient" angle="135" >
+ <stopData position="0" >
+ <colorData g="255" r="255" a="69" b="0" />
+ </stopData>
+ <stopData position="0.375" >
+ <colorData g="255" r="255" a="69" b="0" />
+ </stopData>
+ <stopData position="0.4235329090018885" >
+ <colorData g="255" r="251" a="145" b="0" />
+ </stopData>
+ <stopData position="0.45" >
+ <colorData g="255" r="247" a="208" b="0" />
+ </stopData>
+ <stopData position="0.4775811200061043" >
+ <colorData g="244" r="255" a="130" b="71" />
+ </stopData>
+ <stopData position="0.5187165775401069" >
+ <colorData g="218" r="255" a="130" b="71" />
+ </stopData>
+ <stopData position="0.55" >
+ <colorData g="255" r="255" a="255" b="0" />
+ </stopData>
+ <stopData position="0.5775401069518716" >
+ <colorData g="203" r="255" a="130" b="0" />
+ </stopData>
+ <stopData position="0.625" >
+ <colorData g="255" r="255" a="69" b="0" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="255" r="255" a="69" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Tropical" >
+ <gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
+ <stopData position="0" >
+ <colorData g="41" r="9" a="255" b="4" />
+ </stopData>
+ <stopData position="0.08500000000000001" >
+ <colorData g="79" r="2" a="255" b="0" />
+ </stopData>
+ <stopData position="0.19" >
+ <colorData g="147" r="50" a="255" b="22" />
+ </stopData>
+ <stopData position="0.275" >
+ <colorData g="191" r="236" a="255" b="49" />
+ </stopData>
+ <stopData position="0.39" >
+ <colorData g="61" r="243" a="255" b="34" />
+ </stopData>
+ <stopData position="0.555" >
+ <colorData g="81" r="135" a="255" b="60" />
+ </stopData>
+ <stopData position="0.667" >
+ <colorData g="75" r="121" a="255" b="255" />
+ </stopData>
+ <stopData position="0.825" >
+ <colorData g="255" r="164" a="255" b="244" />
+ </stopData>
+ <stopData position="0.885" >
+ <colorData g="222" r="104" a="255" b="71" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="128" r="93" a="255" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Wave" >
+ <gradientData centerX="0.5" centerY="0.5" radius="0.077" spread="RepeatSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
+ <stopData position="0" >
+ <colorData g="169" r="0" a="147" b="255" />
+ </stopData>
+ <stopData position="0.4973262032085561" >
+ <colorData g="0" r="0" a="147" b="0" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="169" r="0" a="147" b="255" />
+ </stopData>
+ </gradientData>
+ </gradient>
+ <gradient name="Wood" >
+ <gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
+ <stopData position="0" >
+ <colorData g="178" r="255" a="255" b="102" />
+ </stopData>
+ <stopData position="0.55" >
+ <colorData g="148" r="235" a="255" b="61" />
+ </stopData>
+ <stopData position="0.98" >
+ <colorData g="0" r="0" a="255" b="0" />
+ </stopData>
+ <stopData position="1" >
+ <colorData g="0" r="0" a="0" b="0" />
+ </stopData>
+ </gradientData>
+ </gradient>
+</gradients>
diff --git a/src/designer/src/lib/shared/deviceprofile.cpp b/src/designer/src/lib/shared/deviceprofile.cpp
new file mode 100644
index 000000000..3228cab5f
--- /dev/null
+++ b/src/designer/src/lib/shared/deviceprofile.cpp
@@ -0,0 +1,467 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceprofile_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <widgetfactory_p.h>
+#include <qdesigner_utils_p.h>
+
+#include <QtGui/QApplication>
+#include <QtGui/QFont>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QApplication>
+
+#include <QtCore/QSharedData>
+#include <QtCore/QTextStream>
+
+#include <QtCore/QXmlStreamWriter>
+#include <QtCore/QXmlStreamReader>
+
+
+static const char *dpiXPropertyC = "_q_customDpiX";
+static const char *dpiYPropertyC = "_q_customDpiY";
+
+// XML serialization
+static const char *xmlVersionC="1.0";
+static const char *rootElementC="deviceprofile";
+static const char *nameElementC = "name";
+static const char *fontFamilyElementC = "fontfamily";
+static const char *fontPointSizeElementC = "fontpointsize";
+static const char *dPIXElementC = "dpix";
+static const char *dPIYElementC = "dpiy";
+static const char *styleElementC = "style";
+
+/* DeviceProfile:
+ * For preview purposes (preview, widget box, new form dialog), the
+ * QDesignerFormBuilder applies the settings to the form main container
+ * (Point being here that the DPI must be set directly for size calculations
+ * to be correct).
+ * For editing purposes, FormWindow applies the settings to the form container
+ * as not to interfere with the font settings of the form main container.
+ * In addition, the widgetfactory maintains the system settings style
+ * and applies it when creating widgets. */
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ---------------- DeviceProfileData
+class DeviceProfileData : public QSharedData {
+public:
+ DeviceProfileData();
+ void fromSystem();
+ void clear();
+
+ QString m_fontFamily;
+ int m_fontPointSize;
+ QString m_style;
+ int m_dpiX;
+ int m_dpiY;
+ QString m_name;
+};
+
+DeviceProfileData::DeviceProfileData() :
+ m_fontPointSize(-1),
+ m_dpiX(-1),
+ m_dpiY(-1)
+{
+}
+
+void DeviceProfileData::clear()
+{
+ m_fontPointSize = -1;
+ m_dpiX = 0;
+ m_dpiY = 0;
+ m_name.clear();
+ m_style.clear();
+}
+
+void DeviceProfileData::fromSystem()
+{
+ const QFont appFont = QApplication::font();
+ m_fontFamily = appFont.family();
+ m_fontPointSize = appFont.pointSize();
+ DeviceProfile::systemResolution(&m_dpiX, &m_dpiY);
+ m_style.clear();
+}
+
+// ---------------- DeviceProfile
+DeviceProfile::DeviceProfile() :
+ m_d(new DeviceProfileData)
+{
+}
+
+DeviceProfile::DeviceProfile(const DeviceProfile &o) :
+ m_d(o.m_d)
+
+{
+}
+
+DeviceProfile& DeviceProfile::operator=(const DeviceProfile &o)
+{
+ m_d.operator=(o.m_d);
+ return *this;
+}
+
+DeviceProfile::~DeviceProfile()
+{
+}
+
+void DeviceProfile::clear()
+{
+ m_d->clear();
+}
+
+bool DeviceProfile::isEmpty() const
+{
+ return m_d->m_name.isEmpty();
+}
+
+QString DeviceProfile::fontFamily() const
+{
+ return m_d->m_fontFamily;
+}
+
+void DeviceProfile::setFontFamily(const QString &f)
+{
+ m_d->m_fontFamily = f;
+}
+
+int DeviceProfile::fontPointSize() const
+{
+ return m_d->m_fontPointSize;
+}
+
+void DeviceProfile::setFontPointSize(int p)
+{
+ m_d->m_fontPointSize = p;
+}
+
+QString DeviceProfile::style() const
+{
+ return m_d->m_style;
+}
+
+void DeviceProfile::setStyle(const QString &s)
+{
+ m_d->m_style = s;
+}
+
+int DeviceProfile::dpiX() const
+{
+ return m_d->m_dpiX;
+}
+
+void DeviceProfile::setDpiX(int d)
+{
+ m_d->m_dpiX = d;
+}
+
+int DeviceProfile::dpiY() const
+{
+ return m_d->m_dpiY;
+}
+
+void DeviceProfile::setDpiY(int d)
+{
+ m_d->m_dpiY = d;
+}
+
+void DeviceProfile::fromSystem()
+{
+ m_d->fromSystem();
+}
+
+QString DeviceProfile::name() const
+{
+ return m_d->m_name;
+}
+
+void DeviceProfile::setName(const QString &n)
+{
+ m_d->m_name = n;
+}
+
+void DeviceProfile::systemResolution(int *dpiX, int *dpiY)
+{
+ const QDesktopWidget *dw = qApp->desktop();
+ *dpiX = dw->logicalDpiX();
+ *dpiY = dw->logicalDpiY();
+}
+
+class FriendlyWidget : public QWidget {
+ friend class DeviceProfile;
+};
+
+void DeviceProfile::widgetResolution(const QWidget *w, int *dpiX, int *dpiY)
+{
+ const FriendlyWidget *fw = static_cast<const FriendlyWidget*>(w);
+ *dpiX = fw->metric(QPaintDevice::PdmDpiX);
+ *dpiY = fw->metric(QPaintDevice::PdmDpiY);
+}
+
+QString DeviceProfile::toString() const
+{
+ const DeviceProfileData &d = *m_d;
+ QString rc;
+ QTextStream(&rc) << "DeviceProfile:name=" << d.m_name << " Font=" << d.m_fontFamily << ' '
+ << d.m_fontPointSize << " Style=" << d.m_style << " DPI=" << d.m_dpiX << ',' << d.m_dpiY;
+ return rc;
+}
+
+// Apply font to widget
+static void applyFont(const QString &family, int size, DeviceProfile::ApplyMode am, QWidget *widget)
+{
+ QFont currentFont = widget->font();
+ if (currentFont.pointSize() == size && currentFont.family() == family)
+ return;
+ switch (am) {
+ case DeviceProfile::ApplyFormParent:
+ // Invisible form parent: Apply all
+ widget->setFont(QFont(family, size));
+ break;
+ case DeviceProfile::ApplyPreview: {
+ // Preview: Apply only subproperties that have not been changed by designer properties
+ bool apply = false;
+ const uint resolve = currentFont.resolve();
+ if (!(resolve & QFont::FamilyResolved)) {
+ currentFont.setFamily(family);
+ apply = true;
+ }
+ if (!(resolve & QFont::SizeResolved)) {
+ currentFont.setPointSize(size);
+ apply = true;
+ }
+ if (apply)
+ widget->setFont(currentFont);
+ }
+ break;
+ }
+}
+
+void DeviceProfile::applyDPI(int dpiX, int dpiY, QWidget *widget)
+{
+ int sysDPIX, sysDPIY; // Set dynamic variables in case values are different from system DPI
+ systemResolution(&sysDPIX, &sysDPIY);
+ if (dpiX != sysDPIX && dpiY != sysDPIY) {
+ widget->setProperty(dpiXPropertyC, QVariant(dpiX));
+ widget->setProperty(dpiYPropertyC, QVariant(dpiY));
+ }
+}
+
+void DeviceProfile::apply(const QDesignerFormEditorInterface *core, QWidget *widget, ApplyMode am) const
+{
+ if (isEmpty())
+ return;
+
+ const DeviceProfileData &d = *m_d;
+
+ if (!d.m_fontFamily.isEmpty())
+ applyFont(d.m_fontFamily, d.m_fontPointSize, am, widget);
+
+ applyDPI(d.m_dpiX, d.m_dpiY, widget);
+
+ if (!d.m_style.isEmpty()) {
+ if (WidgetFactory *wf = qobject_cast<qdesigner_internal::WidgetFactory *>(core->widgetFactory()))
+ wf->applyStyleTopLevel(d.m_style, widget);
+ }
+}
+
+bool DeviceProfile::equals(const DeviceProfile& rhs) const
+{
+ const DeviceProfileData &d = *m_d;
+ const DeviceProfileData &rhs_d = *rhs.m_d;
+ return d.m_fontPointSize == rhs_d.m_fontPointSize &&
+ d.m_dpiX == rhs_d.m_dpiX && d.m_dpiY == rhs_d.m_dpiY && d.m_fontFamily == rhs_d.m_fontFamily &&
+ d.m_style == rhs_d.m_style && d.m_name == rhs_d.m_name;
+}
+
+static inline void writeElement(QXmlStreamWriter &writer, const QString &element, const QString &cdata)
+{
+ writer.writeStartElement(element);
+ writer.writeCharacters(cdata);
+ writer.writeEndElement();
+}
+
+QString DeviceProfile::toXml() const
+{
+ const DeviceProfileData &d = *m_d;
+ QString rc;
+ QXmlStreamWriter writer(&rc);
+ writer.writeStartDocument(QLatin1String(xmlVersionC));
+ writer.writeStartElement(QLatin1String(rootElementC));
+ writeElement(writer, QLatin1String(nameElementC), d.m_name);
+
+ if (!d.m_fontFamily.isEmpty())
+ writeElement(writer, QLatin1String(fontFamilyElementC), d.m_fontFamily);
+ if (d.m_fontPointSize >= 0)
+ writeElement(writer, QLatin1String(fontPointSizeElementC), QString::number(d.m_fontPointSize));
+ if (d.m_dpiX > 0)
+ writeElement(writer, QLatin1String(dPIXElementC), QString::number(d.m_dpiX));
+ if (d.m_dpiY > 0)
+ writeElement(writer, QLatin1String(dPIYElementC), QString::number(d.m_dpiY));
+ if (!d.m_style.isEmpty())
+ writeElement(writer, QLatin1String(styleElementC), d.m_style);
+
+ writer.writeEndElement();
+ writer.writeEndDocument();
+ return rc;
+}
+
+/* Switch stages when encountering a start element (state table) */
+enum ParseStage { ParseBeginning, ParseWithinRoot,
+ ParseName, ParseFontFamily, ParseFontPointSize, ParseDPIX, ParseDPIY, ParseStyle,
+ ParseError };
+
+static ParseStage nextStage(ParseStage currentStage, const QStringRef &startElement)
+{
+ switch (currentStage) {
+ case ParseBeginning:
+ if (startElement == QLatin1String(rootElementC))
+ return ParseWithinRoot;
+ break;
+ case ParseWithinRoot:
+ case ParseName:
+ case ParseFontFamily:
+ case ParseFontPointSize:
+ case ParseDPIX:
+ case ParseDPIY:
+ case ParseStyle:
+ if (startElement == QLatin1String(nameElementC))
+ return ParseName;
+ if (startElement == QLatin1String(fontFamilyElementC))
+ return ParseFontFamily;
+ if (startElement == QLatin1String(fontPointSizeElementC))
+ return ParseFontPointSize;
+ if (startElement == QLatin1String(dPIXElementC))
+ return ParseDPIX;
+ if (startElement == QLatin1String(dPIYElementC))
+ return ParseDPIY;
+ if (startElement == QLatin1String(styleElementC))
+ return ParseStyle;
+ break;
+ case ParseError:
+ break;
+ }
+ return ParseError;
+}
+
+static bool readIntegerElement(QXmlStreamReader &reader, int *v)
+{
+ const QString e = reader.readElementText();
+ bool ok;
+ *v = e.toInt(&ok);
+ //: Reading a number for an embedded device profile
+ if (!ok)
+ reader.raiseError(QApplication::translate("DeviceProfile", "'%1' is not a number.").arg(e));
+ return ok;
+}
+
+bool DeviceProfile::fromXml(const QString &xml, QString *errorMessage)
+{
+ DeviceProfileData &d = *m_d;
+ d.fromSystem();
+
+ QXmlStreamReader reader(xml);
+
+ ParseStage ps = ParseBeginning;
+ QXmlStreamReader::TokenType tt = QXmlStreamReader::NoToken;
+ int iv = 0;
+ do {
+ tt = reader.readNext();
+ if (tt == QXmlStreamReader::StartElement) {
+ ps = nextStage(ps, reader.name());
+ switch (ps) {
+ case ParseBeginning:
+ case ParseWithinRoot:
+ break;
+ case ParseError:
+ reader.raiseError(QApplication::translate("DeviceProfile", "An invalid tag <%1> was encountered.").arg(reader.name().toString()));
+ tt = QXmlStreamReader::Invalid;
+ break;
+ case ParseName:
+ d.m_name = reader.readElementText();
+ break;
+ case ParseFontFamily:
+ d.m_fontFamily = reader.readElementText();
+ break;
+ case ParseFontPointSize:
+ if (readIntegerElement(reader, &iv)) {
+ d.m_fontPointSize = iv;
+ } else {
+ tt = QXmlStreamReader::Invalid;
+ }
+ break;
+ case ParseDPIX:
+ if (readIntegerElement(reader, &iv)) {
+ d.m_dpiX = iv;
+ } else {
+ tt = QXmlStreamReader::Invalid;
+ }
+ break;
+ case ParseDPIY:
+ if (readIntegerElement(reader, &iv)) {
+ d.m_dpiY = iv;
+ } else {
+ tt = QXmlStreamReader::Invalid;
+ }
+ break;
+ case ParseStyle:
+ d.m_style = reader.readElementText();
+ break;
+ }
+ }
+ } while (tt != QXmlStreamReader::Invalid && tt != QXmlStreamReader::EndDocument);
+
+ if (reader.hasError()) {
+ *errorMessage = reader.errorString();
+ return false;
+ }
+
+ return true;
+}
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/lib/shared/deviceprofile_p.h b/src/designer/src/lib/shared/deviceprofile_p.h
new file mode 100644
index 000000000..9d0cdbd51
--- /dev/null
+++ b/src/designer/src/lib/shared/deviceprofile_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef DEVICEPROFILE_H
+#define DEVICEPROFILE_H
+
+#include "shared_global_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QWidget;
+class QStyle;
+
+namespace qdesigner_internal {
+
+class DeviceProfileData;
+
+/* DeviceProfile for embedded design. They influence
+ * default properties (for example, fonts), dpi and
+ * style of the form. This class represents a device
+ * profile. */
+
+class QDESIGNER_SHARED_EXPORT DeviceProfile {
+public:
+ DeviceProfile();
+
+ DeviceProfile(const DeviceProfile&);
+ DeviceProfile& operator=(const DeviceProfile&);
+ ~DeviceProfile();
+
+ void clear();
+
+ // Device name
+ QString name() const;
+ void setName(const QString &);
+
+ // System settings active
+ bool isEmpty() const;
+
+ // Default font family of the embedded system
+ QString fontFamily() const;
+ void setFontFamily(const QString &);
+
+ // Default font size of the embedded system
+ int fontPointSize() const;
+ void setFontPointSize(int p);
+
+ // Display resolution of the embedded system
+ int dpiX() const;
+ void setDpiX(int d);
+ int dpiY() const;
+ void setDpiY(int d);
+
+ // Style
+ QString style() const;
+ void setStyle(const QString &);
+
+ // Initialize from desktop system
+ void fromSystem();
+
+ static void systemResolution(int *dpiX, int *dpiY);
+ static void widgetResolution(const QWidget *w, int *dpiX, int *dpiY);
+
+ bool equals(const DeviceProfile& rhs) const;
+
+ // Apply to form/preview (using font inheritance)
+ enum ApplyMode {
+ /* Pre-Apply to parent widget of form being edited: Apply font
+ * and make use of property inheritance to be able to modify the
+ * font property freely. */
+ ApplyFormParent,
+ /* Post-Apply to preview widget: Change only inherited font
+ * sub properties. */
+ ApplyPreview
+ };
+ void apply(const QDesignerFormEditorInterface *core, QWidget *widget, ApplyMode am) const;
+
+ static void applyDPI(int dpiX, int dpiY, QWidget *widget);
+
+ QString toString() const;
+
+ QString toXml() const;
+ bool fromXml(const QString &xml, QString *errorMessage);
+
+private:
+ QSharedDataPointer<DeviceProfileData> m_d;
+};
+
+inline bool operator==(const DeviceProfile &s1, const DeviceProfile &s2)
+ { return s1.equals(s2); }
+inline bool operator!=(const DeviceProfile &s1, const DeviceProfile &s2)
+ { return !s1.equals(s2); }
+
+}
+
+
+QT_END_NAMESPACE
+
+#endif // DEVICEPROFILE_H
diff --git a/src/designer/src/lib/shared/dialoggui.cpp b/src/designer/src/lib/shared/dialoggui.cpp
new file mode 100644
index 000000000..3aa4c796d
--- /dev/null
+++ b/src/designer/src/lib/shared/dialoggui.cpp
@@ -0,0 +1,265 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "dialoggui_p.h"
+
+#include <QtGui/QFileIconProvider>
+#include <QtGui/QIcon>
+#include <QtGui/QImage>
+#include <QtGui/QImageReader>
+#include <QtGui/QPixmap>
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QFile>
+#include <QtCore/QSet>
+
+// QFileDialog on X11 does not provide an image preview. Display icons.
+#ifdef Q_WS_X11
+# define IMAGE_PREVIEW
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// Icon provider that reads out the known image formats
+class IconProvider : public QFileIconProvider {
+ Q_DISABLE_COPY(IconProvider)
+
+public:
+ IconProvider();
+ virtual QIcon icon (const QFileInfo &info) const;
+
+ inline bool loadCheck(const QFileInfo &info) const;
+ QImage loadImage(const QString &fileName) const;
+
+private:
+ QSet<QString> m_imageFormats;
+};
+
+IconProvider::IconProvider()
+{
+ // Determine a list of readable extensions (upper and lower case)
+ typedef QList<QByteArray> ByteArrayList;
+ const ByteArrayList fmts = QImageReader::supportedImageFormats();
+ const ByteArrayList::const_iterator cend = fmts.constEnd();
+ for (ByteArrayList::const_iterator it = fmts.constBegin(); it != cend; ++it) {
+ const QString suffix = QString::fromUtf8(it->constData());
+ m_imageFormats.insert(suffix.toLower());
+ m_imageFormats.insert(suffix.toUpper());
+
+ }
+}
+
+// Check by extension and type if this appears to be a loadable image
+bool IconProvider::loadCheck(const QFileInfo &info) const
+{
+ if (info.isFile() && info.isReadable()) {
+ const QString suffix = info.suffix();
+ if (!suffix.isEmpty())
+ return m_imageFormats.contains(suffix);
+ }
+ return false;
+}
+
+QImage IconProvider::loadImage(const QString &fileName) const
+{
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly)) {
+ QImageReader imgReader(&file);
+ if (imgReader.canRead()) {
+ QImage image;
+ if (imgReader.read(&image))
+ return image;
+ }
+ }
+ return QImage();
+}
+
+QIcon IconProvider::icon (const QFileInfo &info) const
+{
+ // Don't get stuck on large images.
+ const qint64 maxSize = 131072;
+ if (loadCheck(info) && info.size() < maxSize) {
+ const QImage image = loadImage(info.absoluteFilePath());
+ if (!image.isNull())
+ return QIcon(QPixmap::fromImage(image, Qt::ThresholdDither|Qt::AutoColor));
+ }
+ return QFileIconProvider::icon(info);
+}
+
+// ---------------- DialogGui
+DialogGui::DialogGui() :
+ m_iconProvider(0)
+{
+}
+
+DialogGui::~DialogGui()
+{
+ delete m_iconProvider;
+}
+
+QFileIconProvider *DialogGui::ensureIconProvider()
+{
+ if (!m_iconProvider)
+ m_iconProvider = new IconProvider;
+ return m_iconProvider;
+}
+
+QMessageBox::StandardButton
+ DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
+ const QString &title, const QString &text, QMessageBox::StandardButtons buttons,
+ QMessageBox::StandardButton defaultButton)
+{
+ QMessageBox::StandardButton rc = QMessageBox::NoButton;
+ switch (icon) {
+ case QMessageBox::Information:
+ rc = QMessageBox::information(parent, title, text, buttons, defaultButton);
+ break;
+ case QMessageBox::Warning:
+ rc = QMessageBox::warning(parent, title, text, buttons, defaultButton);
+ break;
+ case QMessageBox::Critical:
+ rc = QMessageBox::critical(parent, title, text, buttons, defaultButton);
+ break;
+ case QMessageBox::Question:
+ rc = QMessageBox::question(parent, title, text, buttons, defaultButton);
+ break;
+ case QMessageBox::NoIcon:
+ break;
+ }
+ return rc;
+}
+
+QMessageBox::StandardButton
+ DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
+ const QString &title, const QString &text, const QString &informativeText,
+ QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
+{
+ QMessageBox msgBox(icon, title, text, buttons, parent);
+ msgBox.setDefaultButton(defaultButton);
+ msgBox.setInformativeText(informativeText);
+ return static_cast<QMessageBox::StandardButton>(msgBox.exec());
+}
+
+QMessageBox::StandardButton
+ DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
+ const QString &title, const QString &text, const QString &informativeText, const QString &detailedText,
+ QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
+{
+ QMessageBox msgBox(icon, title, text, buttons, parent);
+ msgBox.setDefaultButton(defaultButton);
+ msgBox.setInformativeText(informativeText);
+ msgBox.setDetailedText(detailedText);
+ return static_cast<QMessageBox::StandardButton>(msgBox.exec());
+}
+
+QString DialogGui::getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
+{
+ return QFileDialog::getExistingDirectory(parent, caption, dir, options);
+}
+
+QString DialogGui::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
+{
+ return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
+}
+
+QStringList DialogGui::getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
+{
+ return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
+}
+
+QString DialogGui::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
+{
+ return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options);
+}
+
+void DialogGui::initializeImageFileDialog(QFileDialog &fileDialog, QFileDialog::Options options, QFileDialog::FileMode fm)
+{
+ fileDialog.setConfirmOverwrite( !(options & QFileDialog::DontConfirmOverwrite) );
+ fileDialog.setResolveSymlinks( !(options & QFileDialog::DontResolveSymlinks) );
+ fileDialog.setIconProvider(ensureIconProvider());
+ fileDialog.setFileMode(fm);
+}
+
+QString DialogGui::getOpenImageFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options )
+{
+
+#ifdef IMAGE_PREVIEW
+ QFileDialog fileDialog(parent, caption, dir, filter);
+ initializeImageFileDialog(fileDialog, options, QFileDialog::ExistingFile);
+ if (fileDialog.exec() != QDialog::Accepted)
+ return QString();
+
+ const QStringList selectedFiles = fileDialog.selectedFiles();
+ if (selectedFiles.empty())
+ return QString();
+
+ if (selectedFilter)
+ *selectedFilter = fileDialog.selectedFilter();
+
+ return selectedFiles.front();
+#else
+ return getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
+#endif
+}
+
+QStringList DialogGui::getOpenImageFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options )
+{
+#ifdef IMAGE_PREVIEW
+ QFileDialog fileDialog(parent, caption, dir, filter);
+ initializeImageFileDialog(fileDialog, options, QFileDialog::ExistingFiles);
+ if (fileDialog.exec() != QDialog::Accepted)
+ return QStringList();
+
+ const QStringList selectedFiles = fileDialog.selectedFiles();
+ if (!selectedFiles.empty() && selectedFilter)
+ *selectedFilter = fileDialog.selectedFilter();
+
+ return selectedFiles;
+#else
+ return getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
+#endif
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/dialoggui_p.h b/src/designer/src/lib/shared/dialoggui_p.h
new file mode 100644
index 000000000..c78eea2ef
--- /dev/null
+++ b/src/designer/src/lib/shared/dialoggui_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DIALOGGUI
+#define DIALOGGUI
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "shared_global_p.h"
+#include <abstractdialoggui_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFileIconProvider;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT DialogGui : public QDesignerDialogGuiInterface
+{
+public:
+ DialogGui();
+ virtual ~DialogGui();
+
+ virtual QMessageBox::StandardButton
+ message(QWidget *parent, Message context, QMessageBox::Icon icon,
+ const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+
+ virtual QMessageBox::StandardButton
+ message(QWidget *parent, Message context, QMessageBox::Icon icon,
+ const QString &title, const QString &text, const QString &informativeText,
+ QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+
+ virtual QMessageBox::StandardButton
+ message(QWidget *parent, Message context, QMessageBox::Icon icon,
+ const QString &title, const QString &text, const QString &informativeText, const QString &detailedText,
+ QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+
+ virtual QString getExistingDirectory(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly);
+ virtual QString getOpenFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
+ virtual QStringList getOpenFileNames(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
+ virtual QString getSaveFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
+
+ virtual QString getOpenImageFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
+ virtual QStringList getOpenImageFileNames(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
+
+private:
+ QFileIconProvider *ensureIconProvider();
+ void initializeImageFileDialog(QFileDialog &fd, QFileDialog::Options options, QFileDialog::FileMode);
+
+ QFileIconProvider *m_iconProvider;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DIALOGGUI
diff --git a/src/designer/src/lib/shared/extensionfactory_p.h b/src/designer/src/lib/shared/extensionfactory_p.h
new file mode 100644
index 000000000..3b918c292
--- /dev/null
+++ b/src/designer/src/lib/shared/extensionfactory_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SHARED_EXTENSIONFACTORY_H
+#define SHARED_EXTENSIONFACTORY_H
+
+#include <QtDesigner/default_extensionfactory.h>
+#include <QtDesigner/QExtensionManager>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// Extension factory for registering an extension for an object type.
+template <class ExtensionInterface, class Object, class Extension>
+class ExtensionFactory: public QExtensionFactory
+{
+public:
+ explicit ExtensionFactory(const QString &iid, QExtensionManager *parent = 0);
+
+ // Convenience for registering the extension. Do not use for derived classes.
+ static void registerExtension(QExtensionManager *mgr, const QString &iid);
+
+protected:
+ virtual QObject *createExtension(QObject *qObject, const QString &iid, QObject *parent) const;
+
+private:
+ // Can be overwritten to perform checks on the object.
+ // Default does a qobject_cast to the desired class.
+ virtual Object *checkObject(QObject *qObject) const;
+
+ const QString m_iid;
+};
+
+template <class ExtensionInterface, class Object, class Extension>
+ExtensionFactory<ExtensionInterface, Object, Extension>::ExtensionFactory(const QString &iid, QExtensionManager *parent) :
+ QExtensionFactory(parent),
+ m_iid(iid)
+{
+}
+
+template <class ExtensionInterface, class Object, class Extension>
+Object *ExtensionFactory<ExtensionInterface, Object, Extension>::checkObject(QObject *qObject) const
+{
+ return qobject_cast<Object*>(qObject);
+}
+
+template <class ExtensionInterface, class Object, class Extension>
+QObject *ExtensionFactory<ExtensionInterface, Object, Extension>::createExtension(QObject *qObject, const QString &iid, QObject *parent) const
+{
+ if (iid != m_iid)
+ return 0;
+
+ Object *object = checkObject(qObject);
+ if (!object)
+ return 0;
+
+ return new Extension(object, parent);
+}
+
+template <class ExtensionInterface, class Object, class Extension>
+void ExtensionFactory<ExtensionInterface, Object, Extension>::registerExtension(QExtensionManager *mgr, const QString &iid)
+{
+ ExtensionFactory *factory = new ExtensionFactory(iid, mgr);
+ mgr->registerExtensions(factory, iid);
+}
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SHARED_EXTENSIONFACTORY_H
diff --git a/src/designer/src/lib/shared/filterwidget.cpp b/src/designer/src/lib/shared/filterwidget.cpp
new file mode 100644
index 000000000..e6c826cf8
--- /dev/null
+++ b/src/designer/src/lib/shared/filterwidget.cpp
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "filterwidget_p.h"
+#include "iconloader_p.h"
+
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QFocusEvent>
+#include <QtGui/QPalette>
+#include <QtGui/QCursor>
+#include <QtGui/QToolButton>
+#include <QtGui/QPainter>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+
+#include <QtCore/QDebug>
+#include <QtCore/QPropertyAnimation>
+
+enum { debugFilter = 0 };
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+HintLineEdit::HintLineEdit(QWidget *parent) :
+ QLineEdit(parent),
+ m_defaultFocusPolicy(focusPolicy()),
+ m_refuseFocus(false)
+{
+}
+
+IconButton::IconButton(QWidget *parent)
+ : QToolButton(parent)
+{
+ setCursor(Qt::ArrowCursor);
+}
+
+void IconButton::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ // Note isDown should really use the active state but in most styles
+ // this has no proper feedback
+ QIcon::Mode state = QIcon::Disabled;
+ if (isEnabled())
+ state = isDown() ? QIcon::Selected : QIcon::Normal;
+ QPixmap iconpixmap = icon().pixmap(QSize(ICONBUTTON_SIZE, ICONBUTTON_SIZE),
+ state, QIcon::Off);
+ QRect pixmapRect = QRect(0, 0, iconpixmap.width(), iconpixmap.height());
+ pixmapRect.moveCenter(rect().center());
+ painter.setOpacity(m_fader);
+ painter.drawPixmap(pixmapRect, iconpixmap);
+}
+
+void IconButton::animateShow(bool visible)
+{
+ if (visible) {
+ QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
+ animation->setDuration(160);
+ animation->setEndValue(1.0);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+ } else {
+ QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
+ animation->setDuration(160);
+ animation->setEndValue(0.0);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+ }
+}
+
+bool HintLineEdit::refuseFocus() const
+{
+ return m_refuseFocus;
+}
+
+void HintLineEdit::setRefuseFocus(bool v)
+{
+ if (v == m_refuseFocus)
+ return;
+ m_refuseFocus = v;
+ setFocusPolicy(m_refuseFocus ? Qt::NoFocus : m_defaultFocusPolicy);
+}
+
+void HintLineEdit::mousePressEvent(QMouseEvent *e)
+{
+ if (debugFilter)
+ qDebug() << Q_FUNC_INFO;
+ // Explicitly focus on click.
+ if (m_refuseFocus && !hasFocus())
+ setFocus(Qt::OtherFocusReason);
+ QLineEdit::mousePressEvent(e);
+}
+
+void HintLineEdit::focusInEvent(QFocusEvent *e)
+{
+ if (debugFilter)
+ qDebug() << Q_FUNC_INFO;
+ if (m_refuseFocus) {
+ // Refuse the focus if the mouse it outside. In addition to the mouse
+ // press logic, this prevents a re-focussing which occurs once
+ // we actually had focus
+ const Qt::FocusReason reason = e->reason();
+ if (reason == Qt::ActiveWindowFocusReason || reason == Qt::PopupFocusReason) {
+ const QPoint mousePos = mapFromGlobal(QCursor::pos());
+ const bool refuse = !geometry().contains(mousePos);
+ if (debugFilter)
+ qDebug() << Q_FUNC_INFO << refuse ;
+ if (refuse) {
+ e->ignore();
+ return;
+ }
+ }
+ }
+
+ QLineEdit::focusInEvent(e);
+}
+
+// ------------------- FilterWidget
+FilterWidget::FilterWidget(QWidget *parent, LayoutMode lm) :
+ QWidget(parent),
+ m_editor(new HintLineEdit(this)),
+ m_button(new IconButton(m_editor)),
+ m_buttonwidth(0)
+{
+ m_editor->setPlaceholderText(tr("Filter"));
+
+ // Let the style determine minimum height for our widget
+ QSize size(ICONBUTTON_SIZE + 6, ICONBUTTON_SIZE + 2);
+
+ // Note KDE does not reserve space for the highlight color
+ if (style()->inherits("OxygenStyle")) {
+ size = size.expandedTo(QSize(24, 0));
+ }
+
+ // Make room for clear icon
+ QMargins margins = m_editor->textMargins();
+ if (layoutDirection() == Qt::LeftToRight)
+ margins.setRight(size.width());
+ else
+ margins.setLeft(size.width());
+
+ m_editor->setTextMargins(margins);
+
+ QHBoxLayout *l = new QHBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+ if (lm == LayoutAlignRight)
+ l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ l->addWidget(m_editor);
+
+ // KDE has custom icons for this. Notice that icon namings are counter intuitive
+ // If these icons are not avaiable we use the freedesktop standard name before
+ // falling back to a bundled resource
+ QIcon icon = QIcon::fromTheme(layoutDirection() == Qt::LeftToRight ?
+ QLatin1String("edit-clear-locationbar-rtl") :
+ QLatin1String("edit-clear-locationbar-ltr"),
+ QIcon::fromTheme("edit-clear", createIconSet(QLatin1String("cleartext.png"))));
+
+ m_button->setIcon(icon);
+ m_button->setToolTip(tr("Clear text"));
+ connect(m_button, SIGNAL(clicked()), this, SLOT(reset()));
+ connect(m_editor, SIGNAL(textChanged(QString)), this, SLOT(checkButton(QString)));
+ connect(m_editor, SIGNAL(textEdited(QString)), this, SIGNAL(filterChanged(QString)));
+}
+
+QString FilterWidget::text() const
+{
+ return m_editor->text();
+}
+
+void FilterWidget::checkButton(const QString &text)
+{
+ if (m_oldText.isEmpty() || text.isEmpty())
+ m_button->animateShow(!m_editor->text().isEmpty());
+ m_oldText = text;
+}
+
+void FilterWidget::reset()
+{
+ if (debugFilter)
+ qDebug() << Q_FUNC_INFO;
+
+ if (!m_editor->text().isEmpty()) {
+ // Editor has lost focus once this is pressed
+ m_editor->clear();
+ emit filterChanged(QString());
+ }
+}
+
+void FilterWidget::resizeEvent(QResizeEvent *)
+{
+ QRect contentRect = m_editor->rect();
+ if (layoutDirection() == Qt::LeftToRight) {
+ const int iconoffset = m_editor->textMargins().right() + 4;
+ m_button->setGeometry(contentRect.adjusted(m_editor->width() - iconoffset, 0, 0, 0));
+ } else {
+ const int iconoffset = m_editor->textMargins().left() + 4;
+ m_button->setGeometry(contentRect.adjusted(0, 0, -m_editor->width() + iconoffset, 0));
+ }
+}
+
+bool FilterWidget::refuseFocus() const
+{
+ return m_editor->refuseFocus();
+}
+
+void FilterWidget::setRefuseFocus(bool v)
+{
+ m_editor->setRefuseFocus(v);
+}
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/filterwidget_p.h b/src/designer/src/lib/shared/filterwidget_p.h
new file mode 100644
index 000000000..5b5edcd7c
--- /dev/null
+++ b/src/designer/src/lib/shared/filterwidget_p.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef FILTERWIDGET_H
+#define FILTERWIDGET_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QWidget>
+#include <QtGui/QLineEdit>
+#include <QtGui/QColor>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+class QToolButton;
+
+namespace qdesigner_internal {
+
+/* This widget should never have initial focus
+ * (ie, be the first widget of a dialog, else, the hint cannot be displayed.
+ * For situations, where it is the only focusable control (widget box),
+ * there is a special "refuseFocus()" mode, in which it clears the focus
+ * policy and focusses explicitly on click (note that setting Qt::ClickFocus
+ * is not sufficient for that as an ActivationFocus will occur). */
+
+#define ICONBUTTON_SIZE 16
+
+class QDESIGNER_SHARED_EXPORT HintLineEdit : public QLineEdit {
+ Q_OBJECT
+public:
+ explicit HintLineEdit(QWidget *parent = 0);
+
+ bool refuseFocus() const;
+ void setRefuseFocus(bool v);
+
+protected:
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void focusInEvent(QFocusEvent *e);
+
+private:
+ const Qt::FocusPolicy m_defaultFocusPolicy;
+ bool m_refuseFocus;
+};
+
+// IconButton: This is a simple helper class that represents clickable icons
+
+class IconButton: public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(float fader READ fader WRITE setFader)
+public:
+ IconButton(QWidget *parent);
+ void paintEvent(QPaintEvent *event);
+ float fader() { return m_fader; }
+ void setFader(float value) { m_fader = value; update(); }
+ void animateShow(bool visible);
+
+private:
+ float m_fader;
+};
+
+// FilterWidget: For filtering item views, with reset button Uses HintLineEdit.
+
+class QDESIGNER_SHARED_EXPORT FilterWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ enum LayoutMode {
+ // For use in toolbars: Expand to the right
+ LayoutAlignRight,
+ // No special alignment
+ LayoutAlignNone
+ };
+
+ explicit FilterWidget(QWidget *parent = 0, LayoutMode lm = LayoutAlignRight);
+
+ QString text() const;
+ void resizeEvent(QResizeEvent *);
+ bool refuseFocus() const; // see HintLineEdit
+ void setRefuseFocus(bool v);
+
+signals:
+ void filterChanged(const QString &);
+
+public slots:
+ void reset();
+
+private slots:
+ void checkButton(const QString &text);
+
+private:
+ HintLineEdit *m_editor;
+ IconButton *m_button;
+ int m_buttonwidth;
+ QString m_oldText;
+};
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/shared/formlayoutmenu.cpp b/src/designer/src/lib/shared/formlayoutmenu.cpp
new file mode 100644
index 000000000..d52bb53f5
--- /dev/null
+++ b/src/designer/src/lib/shared/formlayoutmenu.cpp
@@ -0,0 +1,534 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formlayoutmenu_p.h"
+#include "layoutinfo_p.h"
+#include "qdesigner_command_p.h"
+#include "qdesigner_utils_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "ui_formlayoutrowdialog.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+
+#include <QtGui/QAction>
+#include <QtGui/QWidget>
+#include <QtGui/QFormLayout>
+#include <QtGui/QUndoStack>
+#include <QtGui/QDialog>
+#include <QtGui/QPushButton>
+#include <QtGui/QRegExpValidator>
+
+#include <QtCore/QPair>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QRegExp>
+#include <QtCore/QMultiHash>
+#include <QtCore/QDebug>
+
+static const char *buddyPropertyC = "buddy";
+static const char *fieldWidgetBaseClasses[] = {
+ "QLineEdit", "QComboBox", "QSpinBox", "QDoubleSpinBox", "QCheckBox",
+ "QDateEdit", "QTimeEdit", "QDateTimeEdit", "QDial", "QWidget"
+};
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// Struct that describes a row of controls (descriptive label and control) to
+// be added to a form layout.
+struct FormLayoutRow {
+ FormLayoutRow() : buddy(false) {}
+
+ QString labelName;
+ QString labelText;
+ QString fieldClassName;
+ QString fieldName;
+ bool buddy;
+};
+
+// A Dialog to edit a FormLayoutRow. Lets the user input a label text, label
+// name, field widget type, field object name and buddy setting. As the
+// user types the label text; the object names to be used for label and field
+// are updated. It also checks the buddy setting depending on whether the
+// label text contains a buddy marker.
+class FormLayoutRowDialog : public QDialog {
+ Q_DISABLE_COPY(FormLayoutRowDialog)
+ Q_OBJECT
+public:
+ explicit FormLayoutRowDialog(QDesignerFormEditorInterface *core,
+ QWidget *parent);
+
+ FormLayoutRow formLayoutRow() const;
+
+ bool buddy() const;
+ void setBuddy(bool);
+
+ // Accessors for form layout row numbers using 0..[n-1] convention
+ int row() const;
+ void setRow(int);
+ void setRowRange(int, int);
+
+ QString fieldClass() const;
+ QString labelText() const;
+
+ static QStringList fieldWidgetClasses(QDesignerFormEditorInterface *core);
+
+private slots:
+ void labelTextEdited(const QString &text);
+ void labelNameEdited(const QString &text);
+ void fieldNameEdited(const QString &text);
+ void buddyClicked();
+ void fieldClassChanged(int);
+
+private:
+ bool isValid() const;
+ void updateObjectNames(bool updateLabel, bool updateField);
+ void updateOkButton();
+
+ // Check for buddy marker in string
+ const QRegExp m_buddyMarkerRegexp;
+
+ Ui::FormLayoutRowDialog m_ui;
+ bool m_labelNameEdited;
+ bool m_fieldNameEdited;
+ bool m_buddyClicked;
+};
+
+FormLayoutRowDialog::FormLayoutRowDialog(QDesignerFormEditorInterface *core,
+ QWidget *parent) :
+ QDialog(parent),
+ m_buddyMarkerRegexp(QLatin1String("\\&[^&]")),
+ m_labelNameEdited(false),
+ m_fieldNameEdited(false),
+ m_buddyClicked(false)
+{
+ Q_ASSERT(m_buddyMarkerRegexp.isValid());
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setModal(true);
+ m_ui.setupUi(this);
+ connect(m_ui.labelTextLineEdit, SIGNAL(textEdited(QString)), this, SLOT(labelTextEdited(QString)));
+
+ QRegExpValidator *nameValidator = new QRegExpValidator(QRegExp(QLatin1String("^[a-zA-Z0-9_]+$")), this);
+ Q_ASSERT(nameValidator->regExp().isValid());
+
+ m_ui.labelNameLineEdit->setValidator(nameValidator);
+ connect(m_ui.labelNameLineEdit, SIGNAL(textEdited(QString)),
+ this, SLOT(labelNameEdited(QString)));
+
+ m_ui.fieldNameLineEdit->setValidator(nameValidator);
+ connect(m_ui.fieldNameLineEdit, SIGNAL(textEdited(QString)),
+ this, SLOT(fieldNameEdited(QString)));
+
+ connect(m_ui.buddyCheckBox, SIGNAL(clicked()), this, SLOT(buddyClicked()));
+
+ m_ui.fieldClassComboBox->addItems(fieldWidgetClasses(core));
+ m_ui.fieldClassComboBox->setCurrentIndex(0);
+ connect(m_ui.fieldClassComboBox, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(fieldClassChanged(int)));
+
+ updateOkButton();
+}
+
+FormLayoutRow FormLayoutRowDialog::formLayoutRow() const
+{
+ FormLayoutRow rc;
+ rc.labelText = labelText();
+ rc.labelName = m_ui.labelNameLineEdit->text();
+ rc.fieldClassName = fieldClass();
+ rc.fieldName = m_ui.fieldNameLineEdit->text();
+ rc.buddy = buddy();
+ return rc;
+}
+
+bool FormLayoutRowDialog::buddy() const
+{
+ return m_ui.buddyCheckBox->checkState() == Qt::Checked;
+}
+
+void FormLayoutRowDialog::setBuddy(bool b)
+{
+ m_ui.buddyCheckBox->setCheckState(b ? Qt::Checked : Qt::Unchecked);
+}
+
+// Convert rows to 1..n convention for users
+int FormLayoutRowDialog::row() const
+{
+ return m_ui.rowSpinBox->value() - 1;
+}
+
+void FormLayoutRowDialog::setRow(int row)
+{
+ m_ui.rowSpinBox->setValue(row + 1);
+}
+
+void FormLayoutRowDialog::setRowRange(int from, int to)
+{
+ m_ui.rowSpinBox->setMinimum(from + 1);
+ m_ui.rowSpinBox->setMaximum(to + 1);
+ m_ui.rowSpinBox->setEnabled(to - from > 0);
+}
+
+QString FormLayoutRowDialog::fieldClass() const
+{
+ return m_ui.fieldClassComboBox->itemText(m_ui.fieldClassComboBox->currentIndex());
+}
+
+QString FormLayoutRowDialog::labelText() const
+{
+ return m_ui.labelTextLineEdit->text();
+}
+
+bool FormLayoutRowDialog::isValid() const
+{
+ // Check for non-empty names and presence of buddy marker if checked
+ const QString name = labelText();
+ if (name.isEmpty() || m_ui.labelNameLineEdit->text().isEmpty() || m_ui.fieldNameLineEdit->text().isEmpty())
+ return false;
+ if (buddy() && !name.contains(m_buddyMarkerRegexp))
+ return false;
+ return true;
+}
+
+void FormLayoutRowDialog::updateOkButton()
+{
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid());
+}
+
+void FormLayoutRowDialog::labelTextEdited(const QString &text)
+{
+ updateObjectNames(true, true);
+ // Set buddy if '&' is present unless the user changed it
+ if (!m_buddyClicked)
+ setBuddy(text.contains(m_buddyMarkerRegexp));
+
+ updateOkButton();
+}
+
+// Get a suitable object name postfix from a class name:
+// "namespace::QLineEdit"->"LineEdit"
+static inline QString postFixFromClassName(QString className)
+{
+ const int index = className.lastIndexOf(QLatin1String("::"));
+ if (index != -1)
+ className.remove(0, index + 2);
+ if (className.size() > 2)
+ if (className.at(0) == QLatin1Char('Q') || className.at(0) == QLatin1Char('K'))
+ if (className.at(1).isUpper())
+ className.remove(0, 1);
+ return className;
+}
+
+// Helper routines to filter out characters for converting texts into
+// class name prefixes. Only accepts ASCII characters/digits and underscores.
+
+enum PrefixCharacterKind { PC_Digit, PC_UpperCaseLetter, PC_LowerCaseLetter,
+ PC_Other, PC_Invalid };
+
+static inline PrefixCharacterKind prefixCharacterKind(const QChar &c)
+{
+ switch (c.category()) {
+ case QChar::Number_DecimalDigit:
+ return PC_Digit;
+ case QChar::Letter_Lowercase: {
+ const char a = c.toAscii();
+ if (a >= 'a' && a <= 'z')
+ return PC_LowerCaseLetter;
+ }
+ break;
+ case QChar::Letter_Uppercase: {
+ const char a = c.toAscii();
+ if (a >= 'A' && a <= 'Z')
+ return PC_UpperCaseLetter;
+ }
+ break;
+ case QChar::Punctuation_Connector:
+ if (c.toAscii() == '_')
+ return PC_Other;
+ break;
+ default:
+ break;
+ }
+ return PC_Invalid;
+}
+
+// Convert the text the user types into a usable class name prefix by filtering
+// characters, lower-casing the first character and camel-casing subsequent
+// words. ("zip code:") --> ("zipCode").
+
+static QString prefixFromLabel(const QString &prefix)
+{
+ QString rc;
+ const int length = prefix.size();
+ bool lastWasAcceptable = false;
+ for (int i = 0 ; i < length; i++) {
+ const QChar c = prefix.at(i);
+ const PrefixCharacterKind kind = prefixCharacterKind(c);
+ const bool acceptable = kind != PC_Invalid;
+ if (acceptable) {
+ if (rc.isEmpty()) {
+ // Lower-case first character
+ rc += kind == PC_UpperCaseLetter ? c.toLower() : c;
+ } else {
+ // Camel-case words
+ rc += !lastWasAcceptable && kind == PC_LowerCaseLetter ? c.toUpper() : c;
+ }
+ }
+ lastWasAcceptable = acceptable;
+ }
+ return rc;
+}
+
+void FormLayoutRowDialog::updateObjectNames(bool updateLabel, bool updateField)
+{
+ // Generate label + field object names from the label text, that is,
+ // "&Zip code:" -> "zipcodeLabel", "zipcodeLineEdit" unless the user
+ // edited it.
+ const bool doUpdateLabel = !m_labelNameEdited && updateLabel;
+ const bool doUpdateField = !m_fieldNameEdited && updateField;
+ if (!doUpdateLabel && !doUpdateField)
+ return;
+
+ const QString prefix = prefixFromLabel(labelText());
+ // Set names
+ if (doUpdateLabel)
+ m_ui.labelNameLineEdit->setText(prefix + QLatin1String("Label"));
+ if (doUpdateField)
+ m_ui.fieldNameLineEdit->setText(prefix + postFixFromClassName(fieldClass()));
+}
+
+void FormLayoutRowDialog::fieldClassChanged(int)
+{
+ updateObjectNames(false, true);
+}
+
+void FormLayoutRowDialog::labelNameEdited(const QString & /*text*/)
+{
+ m_labelNameEdited = true; // stop auto-updating after user change
+ updateOkButton();
+}
+
+void FormLayoutRowDialog::fieldNameEdited(const QString & /*text*/)
+{
+ m_fieldNameEdited = true; // stop auto-updating after user change
+ updateOkButton();
+}
+
+void FormLayoutRowDialog::buddyClicked()
+{
+ m_buddyClicked = true; // stop auto-updating after user change
+ updateOkButton();
+}
+
+/* Create a list of classes suitable for field widgets. Take the fixed base
+ * classes provided and look in the widget database for custom widgets derived
+ * from them ("QLineEdit", "CustomLineEdit", "QComboBox"...). */
+QStringList FormLayoutRowDialog::fieldWidgetClasses(QDesignerFormEditorInterface *core)
+{
+ // Base class -> custom widgets map
+ typedef QMultiHash<QString, QString> ClassMap;
+
+ static QStringList rc;
+ if (rc.empty()) {
+ const int fwCount = sizeof(fieldWidgetBaseClasses)/sizeof(const char*);
+ // Turn known base classes into list
+ QStringList baseClasses;
+ for (int i = 0; i < fwCount; i++)
+ baseClasses.push_back(QLatin1String(fieldWidgetBaseClasses[i]));
+ // Scan for custom widgets that inherit them and store them in a
+ // multimap of base class->custom widgets unless we have a language
+ // extension installed which might do funny things with custom widgets.
+ ClassMap customClassMap;
+ if (qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core) == 0) {
+ const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
+ const int wdbCount = wdb->count();
+ for (int w = 0; w < wdbCount; ++w) {
+ // Check for non-container custom types that extend the
+ // respective base class.
+ const QDesignerWidgetDataBaseItemInterface *dbItem = wdb->item(w);
+ if (!dbItem->isPromoted() && !dbItem->isContainer() && dbItem->isCustom()) {
+ const int index = baseClasses.indexOf(dbItem->extends());
+ if (index != -1)
+ customClassMap.insert(baseClasses.at(index), dbItem->name());
+ }
+ }
+ }
+ // Compile final list, taking each base class and append custom widgets
+ // based on it.
+ for (int i = 0; i < fwCount; i++) {
+ rc.push_back(baseClasses.at(i));
+ rc += customClassMap.values(baseClasses.at(i));
+ }
+ }
+ return rc;
+}
+
+// ------------------ Utilities
+
+static QFormLayout *managedFormLayout(const QDesignerFormEditorInterface *core, const QWidget *w)
+{
+ QLayout *l = 0;
+ if (LayoutInfo::managedLayoutType(core, w, &l) == LayoutInfo::Form)
+ return qobject_cast<QFormLayout *>(l);
+ return 0;
+}
+
+// Create the widgets of a control row and apply text properties contained
+// in the struct, called by addFormLayoutRow()
+static QPair<QWidget *,QWidget *>
+ createWidgets(const FormLayoutRow &row, QWidget *parent,
+ QDesignerFormWindowInterface *formWindow)
+{
+ QDesignerFormEditorInterface *core = formWindow->core();
+ QDesignerWidgetFactoryInterface *wf = core->widgetFactory();
+
+ QPair<QWidget *,QWidget *> rc = QPair<QWidget *,QWidget *>(wf->createWidget(QLatin1String("QLabel"), parent),
+ wf->createWidget(row.fieldClassName, parent));
+ // Set up properties of the label
+ const QString objectNameProperty = QLatin1String("objectName");
+ QDesignerPropertySheetExtension *labelSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), rc.first);
+ int nameIndex = labelSheet->indexOf(objectNameProperty);
+ labelSheet->setProperty(nameIndex, QVariant::fromValue(PropertySheetStringValue(row.labelName)));
+ labelSheet->setChanged(nameIndex, true);
+ formWindow->ensureUniqueObjectName(rc.first);
+ const int textIndex = labelSheet->indexOf(QLatin1String("text"));
+ labelSheet->setProperty(textIndex, QVariant::fromValue(PropertySheetStringValue(row.labelText)));
+ labelSheet->setChanged(textIndex, true);
+ // Set up properties of the control
+ QDesignerPropertySheetExtension *controlSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), rc.second);
+ nameIndex = controlSheet->indexOf(objectNameProperty);
+ controlSheet->setProperty(nameIndex, QVariant::fromValue(PropertySheetStringValue(row.fieldName)));
+ controlSheet->setChanged(nameIndex, true);
+ formWindow->ensureUniqueObjectName(rc.second);
+ return rc;
+}
+
+// Create a command sequence on the undo stack of the form window that creates
+// the widgets of the row and inserts them into the form layout.
+static void addFormLayoutRow(const FormLayoutRow &formLayoutRow, int row, QWidget *w,
+ QDesignerFormWindowInterface *formWindow)
+{
+ QFormLayout *formLayout = managedFormLayout(formWindow->core(), w);
+ Q_ASSERT(formLayout);
+ QUndoStack *undoStack = formWindow->commandHistory();
+ const QString macroName = QCoreApplication::translate("Command", "Add '%1' to '%2'").arg(formLayoutRow.labelText, formLayout->objectName());
+ undoStack->beginMacro(macroName);
+
+ // Create a list of widget insertion commands and pass them a cell position
+ const QPair<QWidget *,QWidget *> widgetPair = createWidgets(formLayoutRow, w, formWindow);
+
+ InsertWidgetCommand *labelCmd = new InsertWidgetCommand(formWindow);
+ labelCmd->init(widgetPair.first, false, row, 0);
+ undoStack->push(labelCmd);
+ InsertWidgetCommand *controlCmd = new InsertWidgetCommand(formWindow);
+ controlCmd->init(widgetPair.second, false, row, 1);
+ undoStack->push(controlCmd);
+ if (formLayoutRow.buddy) {
+ SetPropertyCommand *buddyCommand = new SetPropertyCommand(formWindow);
+ buddyCommand->init(widgetPair.first, QLatin1String(buddyPropertyC), widgetPair.second->objectName());
+ undoStack->push(buddyCommand);
+ }
+ undoStack->endMacro();
+}
+
+// ---------------- FormLayoutMenu
+FormLayoutMenu::FormLayoutMenu(QObject *parent) :
+ QObject(parent),
+ m_separator1(new QAction(this)),
+ m_populateFormAction(new QAction(tr("Add form layout row..."), this)),
+ m_separator2(new QAction(this))
+{
+ m_separator1->setSeparator(true);
+ connect(m_populateFormAction, SIGNAL(triggered()), this, SLOT(slotAddRow()));
+ m_separator2->setSeparator(true);
+}
+
+void FormLayoutMenu::populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList &actions)
+{
+ switch (LayoutInfo::managedLayoutType(fw->core(), w)) {
+ case LayoutInfo::Form:
+ if (!actions.empty() && !actions.back()->isSeparator())
+ actions.push_back(m_separator1);
+ actions.push_back(m_populateFormAction);
+ actions.push_back(m_separator2);
+ m_widget = w;
+ break;
+ default:
+ m_widget = 0;
+ break;
+ }
+}
+
+void FormLayoutMenu::slotAddRow()
+{
+ QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_widget);
+ Q_ASSERT(m_widget && fw);
+ const int rowCount = managedFormLayout(fw->core(), m_widget)->rowCount();
+
+ FormLayoutRowDialog dialog(fw->core(), fw);
+ dialog.setRowRange(0, rowCount);
+ dialog.setRow(rowCount);
+
+ if (dialog.exec() != QDialog::Accepted)
+ return;
+ addFormLayoutRow(dialog.formLayoutRow(), dialog.row(), m_widget, fw);
+}
+
+QAction *FormLayoutMenu::preferredEditAction(QWidget *w, QDesignerFormWindowInterface *fw)
+{
+ if (LayoutInfo::managedLayoutType(fw->core(), w) == LayoutInfo::Form) {
+ m_widget = w;
+ return m_populateFormAction;
+ }
+ return 0;
+}
+}
+
+QT_END_NAMESPACE
+
+#include "formlayoutmenu.moc"
+
diff --git a/src/designer/src/lib/shared/formlayoutmenu_p.h b/src/designer/src/lib/shared/formlayoutmenu_p.h
new file mode 100644
index 000000000..86f8575bd
--- /dev/null
+++ b/src/designer/src/lib/shared/formlayoutmenu_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMLAYOUTMENU
+#define FORMLAYOUTMENU
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "shared_global_p.h"
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+class QAction;
+class QWidget;
+
+namespace qdesigner_internal {
+
+// Task menu to be used for form layouts. Offers an options "Add row" which
+// pops up a dialog in which the user can specify label name, text and buddy.
+class QDESIGNER_SHARED_EXPORT FormLayoutMenu : public QObject
+{
+ Q_DISABLE_COPY(FormLayoutMenu)
+ Q_OBJECT
+public:
+ typedef QList<QAction *> ActionList;
+
+ explicit FormLayoutMenu(QObject *parent);
+
+ // Populate a list of actions with the form layout actions.
+ void populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList &actions);
+ // For implementing QDesignerTaskMenuExtension::preferredEditAction():
+ // Return appropriate action for double clicking.
+ QAction *preferredEditAction(QWidget *w, QDesignerFormWindowInterface *fw);
+
+private slots:
+ void slotAddRow();
+
+private:
+ QAction *m_separator1;
+ QAction *m_populateFormAction;
+ QAction *m_separator2;
+ QPointer<QWidget> m_widget;
+};
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMLAYOUTMENU
diff --git a/src/designer/src/lib/shared/formlayoutrowdialog.ui b/src/designer/src/lib/shared/formlayoutrowdialog.ui
new file mode 100644
index 000000000..c0e0cfe2b
--- /dev/null
+++ b/src/designer/src/lib/shared/formlayoutrowdialog.ui
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FormLayoutRowDialog</class>
+ <widget class="QDialog" name="FormLayoutRowDialog">
+ <property name="windowTitle">
+ <string>Add Form Layout Row</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelTextLabel">
+ <property name="text">
+ <string>&amp;Label text:</string>
+ </property>
+ <property name="buddy">
+ <cstring>labelTextLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="labelTextLineEdit">
+ <property name="minimumSize">
+ <size>
+ <width>180</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="labelNameLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="fieldClassLabel">
+ <property name="text">
+ <string>Field &amp;type:</string>
+ </property>
+ <property name="buddy">
+ <cstring>fieldClassComboBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="fieldClassComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="fieldNameLabel">
+ <property name="text">
+ <string>&amp;Field name:</string>
+ </property>
+ <property name="buddy">
+ <cstring>fieldNameLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="buddyLabel">
+ <property name="text">
+ <string>&amp;Buddy:</string>
+ </property>
+ <property name="buddy">
+ <cstring>buddyCheckBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QCheckBox" name="buddyCheckBox">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="rowLabel">
+ <property name="text">
+ <string>&amp;Row:</string>
+ </property>
+ <property name="buddy">
+ <cstring>rowSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QSpinBox" name="rowSpinBox"/>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="fieldNameLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelNameLabel">
+ <property name="text">
+ <string>Label &amp;name:</string>
+ </property>
+ <property name="buddy">
+ <cstring>labelNameLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>FormLayoutRowDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>FormLayoutRowDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/formwindowbase.cpp b/src/designer/src/lib/shared/formwindowbase.cpp
new file mode 100644
index 000000000..7c87eaf59
--- /dev/null
+++ b/src/designer/src/lib/shared/formwindowbase.cpp
@@ -0,0 +1,502 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formwindowbase_p.h"
+#include "connectionedit_p.h"
+#include "qdesigner_command_p.h"
+#include "qdesigner_propertysheet_p.h"
+#include "qdesigner_propertyeditor_p.h"
+#include "qdesigner_menu_p.h"
+#include "qdesigner_menubar_p.h"
+#include "shared_settings_p.h"
+#include "grid_p.h"
+#include "deviceprofile_p.h"
+#include "qdesigner_utils_p.h"
+
+#include "qsimpleresource_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/QList>
+#include <QtCore/QTimer>
+#include <QtGui/QMenu>
+#include <QtGui/QListWidget>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QTableWidget>
+#include <QtGui/QComboBox>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QToolBar>
+#include <QtGui/QStatusBar>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+#include <QtGui/QLabel>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class FormWindowBasePrivate {
+public:
+ explicit FormWindowBasePrivate(QDesignerFormEditorInterface *core);
+
+ static Grid m_defaultGrid;
+
+ QDesignerFormWindowInterface::Feature m_feature;
+ Grid m_grid;
+ bool m_hasFormGrid;
+ DesignerPixmapCache *m_pixmapCache;
+ DesignerIconCache *m_iconCache;
+ QtResourceSet *m_resourceSet;
+ QMap<QDesignerPropertySheet *, QMap<int, bool> > m_reloadableResources; // bool is dummy, QMap used as QSet
+ QMap<QDesignerPropertySheet *, QObject *> m_reloadablePropertySheets;
+ const DeviceProfile m_deviceProfile;
+ FormWindowBase::LineTerminatorMode m_lineTerminatorMode;
+ FormWindowBase::SaveResourcesBehaviour m_saveResourcesBehaviour;
+};
+
+FormWindowBasePrivate::FormWindowBasePrivate(QDesignerFormEditorInterface *core) :
+ m_feature(QDesignerFormWindowInterface::DefaultFeature),
+ m_grid(m_defaultGrid),
+ m_hasFormGrid(false),
+ m_pixmapCache(0),
+ m_iconCache(0),
+ m_resourceSet(0),
+ m_deviceProfile(QDesignerSharedSettings(core).currentDeviceProfile()),
+ m_lineTerminatorMode(FormWindowBase::NativeLineTerminator),
+ m_saveResourcesBehaviour(FormWindowBase::SaveAll)
+{
+}
+
+Grid FormWindowBasePrivate::m_defaultGrid;
+
+FormWindowBase::FormWindowBase(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags) :
+ QDesignerFormWindowInterface(parent, flags),
+ m_d(new FormWindowBasePrivate(core))
+{
+ syncGridFeature();
+ m_d->m_pixmapCache = new DesignerPixmapCache(this);
+ m_d->m_iconCache = new DesignerIconCache(m_d->m_pixmapCache, this);
+}
+
+FormWindowBase::~FormWindowBase()
+{
+ delete m_d;
+}
+
+DesignerPixmapCache *FormWindowBase::pixmapCache() const
+{
+ return m_d->m_pixmapCache;
+}
+
+DesignerIconCache *FormWindowBase::iconCache() const
+{
+ return m_d->m_iconCache;
+}
+
+QtResourceSet *FormWindowBase::resourceSet() const
+{
+ return m_d->m_resourceSet;
+}
+
+void FormWindowBase::setResourceSet(QtResourceSet *resourceSet)
+{
+ m_d->m_resourceSet = resourceSet;
+}
+
+void FormWindowBase::addReloadableProperty(QDesignerPropertySheet *sheet, int index)
+{
+ m_d->m_reloadableResources[sheet][index] = true;
+}
+
+void FormWindowBase::removeReloadableProperty(QDesignerPropertySheet *sheet, int index)
+{
+ m_d->m_reloadableResources[sheet].remove(index);
+ if (m_d->m_reloadableResources[sheet].count() == 0)
+ m_d->m_reloadableResources.remove(sheet);
+}
+
+void FormWindowBase::addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object)
+{
+ if (qobject_cast<QTreeWidget *>(object) ||
+ qobject_cast<QTableWidget *>(object) ||
+ qobject_cast<QListWidget *>(object) ||
+ qobject_cast<QComboBox *>(object))
+ m_d->m_reloadablePropertySheets[sheet] = object;
+}
+
+void FormWindowBase::removeReloadablePropertySheet(QDesignerPropertySheet *sheet)
+{
+ m_d->m_reloadablePropertySheets.remove(sheet);
+}
+
+void FormWindowBase::reloadProperties()
+{
+ pixmapCache()->clear();
+ iconCache()->clear();
+ QMapIterator<QDesignerPropertySheet *, QMap<int, bool> > itSheet(m_d->m_reloadableResources);
+ while (itSheet.hasNext()) {
+ QDesignerPropertySheet *sheet = itSheet.next().key();
+ QMapIterator<int, bool> itIndex(itSheet.value());
+ while (itIndex.hasNext()) {
+ const int index = itIndex.next().key();
+ const QVariant newValue = sheet->property(index);
+ if (qobject_cast<QLabel *>(sheet->object()) && sheet->propertyName(index) == QLatin1String("text")) {
+ const PropertySheetStringValue newString = qvariant_cast<PropertySheetStringValue>(newValue);
+ // optimize a bit, reset only if the text value might contain a reference to qt resources
+ // (however reloading of icons other than taken from resources might not work here)
+ if (newString.value().contains(QLatin1String(":/"))) {
+ const QVariant resetValue = QVariant::fromValue(PropertySheetStringValue());
+ sheet->setProperty(index, resetValue);
+ }
+ }
+ sheet->setProperty(index, newValue);
+ }
+ if (QTabWidget *tabWidget = qobject_cast<QTabWidget *>(sheet->object())) {
+ const int count = tabWidget->count();
+ const int current = tabWidget->currentIndex();
+ const QString currentTabIcon = QLatin1String("currentTabIcon");
+ for (int i = 0; i < count; i++) {
+ tabWidget->setCurrentIndex(i);
+ const int index = sheet->indexOf(currentTabIcon);
+ sheet->setProperty(index, sheet->property(index));
+ }
+ tabWidget->setCurrentIndex(current);
+ } else if (QToolBox *toolBox = qobject_cast<QToolBox *>(sheet->object())) {
+ const int count = toolBox->count();
+ const int current = toolBox->currentIndex();
+ const QString currentItemIcon = QLatin1String("currentItemIcon");
+ for (int i = 0; i < count; i++) {
+ toolBox->setCurrentIndex(i);
+ const int index = sheet->indexOf(currentItemIcon);
+ sheet->setProperty(index, sheet->property(index));
+ }
+ toolBox->setCurrentIndex(current);
+ }
+ }
+ QMapIterator<QDesignerPropertySheet *, QObject *> itSh(m_d->m_reloadablePropertySheets);
+ while (itSh.hasNext()) {
+ QObject *object = itSh.next().value();
+ reloadIconResources(iconCache(), object);
+ }
+}
+
+void FormWindowBase::resourceSetActivated(QtResourceSet *resource, bool resourceSetChanged)
+{
+ if (resource == resourceSet() && resourceSetChanged) {
+ reloadProperties();
+ emit pixmapCache()->reloaded();
+ emit iconCache()->reloaded();
+ if (QDesignerPropertyEditor *propertyEditor = qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor()))
+ propertyEditor->reloadResourceProperties();
+ }
+}
+
+QVariantMap FormWindowBase::formData()
+{
+ QVariantMap rc;
+ if (m_d->m_hasFormGrid)
+ m_d->m_grid.addToVariantMap(rc, true);
+ return rc;
+}
+
+void FormWindowBase::setFormData(const QVariantMap &vm)
+{
+ Grid formGrid;
+ m_d->m_hasFormGrid = formGrid.fromVariantMap(vm);
+ if (m_d->m_hasFormGrid)
+ m_d->m_grid = formGrid;
+}
+
+QPoint FormWindowBase::grid() const
+{
+ return QPoint(m_d->m_grid.deltaX(), m_d->m_grid.deltaY());
+}
+
+void FormWindowBase::setGrid(const QPoint &grid)
+{
+ m_d->m_grid.setDeltaX(grid.x());
+ m_d->m_grid.setDeltaY(grid.y());
+}
+
+bool FormWindowBase::hasFeature(Feature f) const
+{
+ return f & m_d->m_feature;
+}
+
+static void recursiveUpdate(QWidget *w)
+{
+ w->update();
+
+ const QObjectList &l = w->children();
+ const QObjectList::const_iterator cend = l.constEnd();
+ for (QObjectList::const_iterator it = l.constBegin(); it != cend; ++it) {
+ if (QWidget *w = qobject_cast<QWidget*>(*it))
+ recursiveUpdate(w);
+ }
+}
+
+void FormWindowBase::setFeatures(Feature f)
+{
+ m_d->m_feature = f;
+ const bool enableGrid = f & GridFeature;
+ m_d->m_grid.setVisible(enableGrid);
+ m_d->m_grid.setSnapX(enableGrid);
+ m_d->m_grid.setSnapY(enableGrid);
+ emit featureChanged(f);
+ recursiveUpdate(this);
+}
+
+FormWindowBase::Feature FormWindowBase::features() const
+{
+ return m_d->m_feature;
+}
+
+bool FormWindowBase::gridVisible() const
+{
+ return m_d->m_grid.visible() && currentTool() == 0;
+}
+
+FormWindowBase::SaveResourcesBehaviour FormWindowBase::saveResourcesBehaviour() const
+{
+ return m_d->m_saveResourcesBehaviour;
+}
+
+void FormWindowBase::setSaveResourcesBehaviour(SaveResourcesBehaviour behaviour)
+{
+ m_d->m_saveResourcesBehaviour = behaviour;
+}
+
+void FormWindowBase::syncGridFeature()
+{
+ if (m_d->m_grid.snapX() || m_d->m_grid.snapY())
+ m_d->m_feature |= GridFeature;
+ else
+ m_d->m_feature &= ~GridFeature;
+}
+
+void FormWindowBase::setDesignerGrid(const Grid& grid)
+{
+ m_d->m_grid = grid;
+ syncGridFeature();
+ recursiveUpdate(this);
+}
+
+const Grid &FormWindowBase::designerGrid() const
+{
+ return m_d->m_grid;
+}
+
+bool FormWindowBase::hasFormGrid() const
+{
+ return m_d->m_hasFormGrid;
+}
+
+void FormWindowBase::setHasFormGrid(bool b)
+{
+ m_d->m_hasFormGrid = b;
+}
+
+void FormWindowBase::setDefaultDesignerGrid(const Grid& grid)
+{
+ FormWindowBasePrivate::m_defaultGrid = grid;
+}
+
+const Grid &FormWindowBase::defaultDesignerGrid()
+{
+ return FormWindowBasePrivate::m_defaultGrid;
+}
+
+QMenu *FormWindowBase::initializePopupMenu(QWidget * /*managedWidget*/)
+{
+ return 0;
+}
+
+// Widget under mouse for finding the Widget to highlight
+// when doing DnD. Restricts to pages by geometry if a container with
+// a container extension (or one of its helper widgets) is hit; otherwise
+// returns the widget as such (be it managed/unmanaged)
+
+QWidget *FormWindowBase::widgetUnderMouse(const QPoint &formPos, WidgetUnderMouseMode /* wum */)
+{
+ // widget_under_mouse might be some temporary thing like the dropLine. We need
+ // the actual widget that's part of the edited GUI.
+ QWidget *rc = widgetAt(formPos);
+ if (!rc || qobject_cast<ConnectionEdit*>(rc))
+ return 0;
+
+ if (rc == mainContainer()) {
+ // Refuse main container areas if the main container has a container extension,
+ // for example when hitting QToolBox/QTabWidget empty areas.
+ if (qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), rc))
+ return 0;
+ return rc;
+ }
+
+ // If we hit on container extension type container, make sure
+ // we use the top-most current page
+ if (QWidget *container = findContainer(rc, false))
+ if (QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), container)) {
+ // For container that do not have a "stacked" nature (QToolBox, QMdiArea),
+ // make sure the position is within the current page
+ const int ci = c->currentIndex();
+ if (ci < 0)
+ return 0;
+ QWidget *page = c->widget(ci);
+ QRect pageGeometry = page->geometry();
+ pageGeometry.moveTo(page->mapTo(this, pageGeometry.topLeft()));
+ if (!pageGeometry.contains(formPos))
+ return 0;
+ return page;
+ }
+
+ return rc;
+}
+
+void FormWindowBase::deleteWidgetList(const QWidgetList &widget_list)
+{
+ // We need a macro here even for single widgets because the some components (for example,
+ // the signal slot editor are connected to widgetRemoved() and add their
+ // own commands (for example, to delete w's connections)
+ const QString description = widget_list.size() == 1 ?
+ tr("Delete '%1'").arg(widget_list.front()->objectName()) : tr("Delete");
+
+ commandHistory()->beginMacro(description);
+ foreach (QWidget *w, widget_list) {
+ emit widgetRemoved(w);
+ DeleteWidgetCommand *cmd = new DeleteWidgetCommand(this);
+ cmd->init(w);
+ commandHistory()->push(cmd);
+ }
+ commandHistory()->endMacro();
+}
+
+QMenu *FormWindowBase::createExtensionTaskMenu(QDesignerFormWindowInterface *fw, QObject *o, bool trailingSeparator)
+{
+ typedef QList<QAction *> ActionList;
+ ActionList actions;
+ // 1) Standard public extension
+ QExtensionManager *em = fw->core()->extensionManager();
+ if (const QDesignerTaskMenuExtension *extTaskMenu = qt_extension<QDesignerTaskMenuExtension*>(em, o))
+ actions += extTaskMenu->taskActions();
+ if (const QDesignerTaskMenuExtension *intTaskMenu = qobject_cast<QDesignerTaskMenuExtension *>(em->extension(o, QLatin1String("QDesignerInternalTaskMenuExtension")))) {
+ if (!actions.empty()) {
+ QAction *a = new QAction(fw);
+ a->setSeparator(true);
+ actions.push_back(a);
+ }
+ actions += intTaskMenu->taskActions();
+ }
+ if (actions.empty())
+ return 0;
+ if (trailingSeparator && !actions.back()->isSeparator()) {
+ QAction *a = new QAction(fw);
+ a->setSeparator(true);
+ actions.push_back(a);
+ }
+ QMenu *rc = new QMenu;
+ const ActionList::const_iterator cend = actions.constEnd();
+ for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it)
+ rc->addAction(*it);
+ return rc;
+}
+
+void FormWindowBase::emitObjectRemoved(QObject *o)
+{
+ emit objectRemoved(o);
+}
+
+DeviceProfile FormWindowBase::deviceProfile() const
+{
+ return m_d->m_deviceProfile;
+}
+
+QString FormWindowBase::styleName() const
+{
+ return m_d->m_deviceProfile.isEmpty() ? QString() : m_d->m_deviceProfile.style();
+}
+
+void FormWindowBase::emitWidgetRemoved(QWidget *w)
+{
+ emit widgetRemoved(w);
+}
+
+QString FormWindowBase::deviceProfileName() const
+{
+ return m_d->m_deviceProfile.isEmpty() ? QString() : m_d->m_deviceProfile.name();
+}
+
+void FormWindowBase::setLineTerminatorMode(FormWindowBase::LineTerminatorMode mode)
+{
+ m_d->m_lineTerminatorMode = mode;
+}
+
+FormWindowBase::LineTerminatorMode FormWindowBase::lineTerminatorMode() const
+{
+ return m_d->m_lineTerminatorMode;
+}
+
+void FormWindowBase::triggerDefaultAction(QWidget *widget)
+{
+ if (QAction *action = qdesigner_internal::preferredEditAction(core(), widget))
+ QTimer::singleShot(0, action, SIGNAL(triggered()));
+}
+
+void FormWindowBase::setupDefaultAction(QDesignerFormWindowInterface *fw)
+{
+ QObject::connect(fw, SIGNAL(activated(QWidget*)), fw, SLOT(triggerDefaultAction(QWidget*)));
+}
+
+QString FormWindowBase::fileContents() const
+{
+ const bool oldValue = QSimpleResource::setWarningsEnabled(false);
+ const QString rc = contents();
+ QSimpleResource::setWarningsEnabled(oldValue);
+ return rc;
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/formwindowbase_p.h b/src/designer/src/lib/shared/formwindowbase_p.h
new file mode 100644
index 000000000..f0fb2e204
--- /dev/null
+++ b/src/designer/src/lib/shared/formwindowbase_p.h
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef FORMWINDOWBASE_H
+#define FORMWINDOWBASE_H
+
+#include "shared_global_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtCore/QVariantMap>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerDnDItemInterface;
+class QMenu;
+class QtResourceSet;
+class QDesignerPropertySheet;
+
+namespace qdesigner_internal {
+
+class QEditorFormBuilder;
+class DeviceProfile;
+class Grid;
+
+class DesignerPixmapCache;
+class DesignerIconCache;
+class FormWindowBasePrivate;
+
+class QDESIGNER_SHARED_EXPORT FormWindowBase: public QDesignerFormWindowInterface
+{
+ Q_OBJECT
+public:
+ enum HighlightMode { Restore, Highlight };
+ enum SaveResourcesBehaviour { SaveAll, SaveOnlyUsedQrcFiles, DontSaveQrcFiles };
+
+ explicit FormWindowBase(QDesignerFormEditorInterface *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ virtual ~FormWindowBase();
+
+ QVariantMap formData();
+ void setFormData(const QVariantMap &vm);
+
+ // Return contents without warnings. Should be 'contents(bool quiet)'
+ QString fileContents() const;
+
+ // Return the widget containing the form. This is used to
+ // apply embedded design settings to that are inherited (for example font).
+ // These are meant to be applied to the form only and not to the other editors
+ // in the widget stack.
+ virtual QWidget *formContainer() const = 0;
+
+ // Deprecated
+ virtual QPoint grid() const;
+
+ // Deprecated
+ virtual void setGrid(const QPoint &grid);
+
+ virtual bool hasFeature(Feature f) const;
+ virtual Feature features() const;
+ virtual void setFeatures(Feature f);
+
+ const Grid &designerGrid() const;
+ void setDesignerGrid(const Grid& grid);
+
+ bool hasFormGrid() const;
+ void setHasFormGrid(bool b);
+
+ bool gridVisible() const;
+
+ SaveResourcesBehaviour saveResourcesBehaviour() const;
+ void setSaveResourcesBehaviour(SaveResourcesBehaviour behaviour);
+
+ static const Grid &defaultDesignerGrid();
+ static void setDefaultDesignerGrid(const Grid& grid);
+
+ // Overwrite to initialize and return a full popup menu for a managed widget
+ virtual QMenu *initializePopupMenu(QWidget *managedWidget);
+ // Helper to create a basic popup menu from task menu extensions (internal/public)
+ static QMenu *createExtensionTaskMenu(QDesignerFormWindowInterface *fw, QObject *o, bool trailingSeparator = true);
+
+ virtual bool dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, QWidget *target,
+ const QPoint &global_mouse_pos) = 0;
+
+ // Helper to find the widget at the mouse position with some flags.
+ enum WidgetUnderMouseMode { FindSingleSelectionDropTarget, FindMultiSelectionDropTarget };
+ QWidget *widgetUnderMouse(const QPoint &formPos, WidgetUnderMouseMode m);
+
+ virtual QWidget *widgetAt(const QPoint &pos) = 0;
+ virtual QWidget *findContainer(QWidget *w, bool excludeLayout) const = 0;
+
+ void deleteWidgetList(const QWidgetList &widget_list);
+
+ virtual void highlightWidget(QWidget *w, const QPoint &pos, HighlightMode mode = Highlight) = 0;
+
+ enum PasteMode { PasteAll, PasteActionsOnly };
+ virtual void paste(PasteMode pasteMode) = 0;
+
+ // Factory method to create a form builder
+ virtual QEditorFormBuilder *createFormBuilder() = 0;
+
+ virtual bool blockSelectionChanged(bool blocked) = 0;
+ virtual void emitSelectionChanged() = 0;
+
+ DesignerPixmapCache *pixmapCache() const;
+ DesignerIconCache *iconCache() const;
+ QtResourceSet *resourceSet() const;
+ void setResourceSet(QtResourceSet *resourceSet);
+ void addReloadableProperty(QDesignerPropertySheet *sheet, int index);
+ void removeReloadableProperty(QDesignerPropertySheet *sheet, int index);
+ void addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object);
+ void removeReloadablePropertySheet(QDesignerPropertySheet *sheet);
+ void reloadProperties();
+
+ void emitWidgetRemoved(QWidget *w);
+ void emitObjectRemoved(QObject *o);
+
+ DeviceProfile deviceProfile() const;
+ QString styleName() const;
+ QString deviceProfileName() const;
+
+ enum LineTerminatorMode {
+ LFLineTerminator,
+ CRLFLineTerminator,
+ NativeLineTerminator =
+#if defined (Q_OS_WIN)
+ CRLFLineTerminator
+#else
+ LFLineTerminator
+#endif
+ };
+
+ void setLineTerminatorMode(LineTerminatorMode mode);
+ LineTerminatorMode lineTerminatorMode() const;
+
+ // Connect the 'activated' (doubleclicked) signal of the form window to a
+ // slot triggering the default action (of the task menu)
+ static void setupDefaultAction(QDesignerFormWindowInterface *fw);
+
+public slots:
+ void resourceSetActivated(QtResourceSet *resourceSet, bool resourceSetChanged);
+
+private slots:
+ void triggerDefaultAction(QWidget *w);
+
+private:
+ void syncGridFeature();
+
+ FormWindowBasePrivate *m_d;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // FORMWINDOWBASE_H
diff --git a/src/designer/src/lib/shared/grid.cpp b/src/designer/src/lib/shared/grid.cpp
new file mode 100644
index 000000000..ba991c782
--- /dev/null
+++ b/src/designer/src/lib/shared/grid.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "grid_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QVector>
+#include <QtGui/QPainter>
+#include <QtGui/QWidget>
+#include <QtGui/qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+static const bool defaultSnap = true;
+static const bool defaultVisible = true;
+static const int DEFAULT_GRID = 10;
+static const char* KEY_VISIBLE = "gridVisible";
+static const char* KEY_SNAPX = "gridSnapX";
+static const char* KEY_SNAPY = "gridSnapY";
+static const char* KEY_DELTAX = "gridDeltaX";
+static const char* KEY_DELTAY = "gridDeltaY";
+
+// Insert a value into the serialization map unless default
+template <class T>
+ static inline void valueToVariantMap(T value, T defaultValue, const QString &key, QVariantMap &v, bool forceKey) {
+ if (forceKey || value != defaultValue)
+ v.insert(key, QVariant(value));
+ }
+
+// Obtain a value form QVariantMap
+template <class T>
+ static inline bool valueFromVariantMap(const QVariantMap &v, const QString &key, T &value) {
+ const QVariantMap::const_iterator it = v.constFind(key);
+ const bool found = it != v.constEnd();
+ if (found)
+ value = qvariant_cast<T>(it.value());
+ return found;
+ }
+
+namespace qdesigner_internal
+{
+
+Grid::Grid() :
+ m_visible(defaultVisible),
+ m_snapX(defaultSnap),
+ m_snapY(defaultSnap),
+ m_deltaX(DEFAULT_GRID),
+ m_deltaY(DEFAULT_GRID)
+{
+}
+
+bool Grid::fromVariantMap(const QVariantMap& vm)
+{
+ Grid grid;
+ bool anyData = valueFromVariantMap(vm, QLatin1String(KEY_VISIBLE), grid.m_visible);
+ anyData |= valueFromVariantMap(vm, QLatin1String(KEY_SNAPX), grid.m_snapX);
+ anyData |= valueFromVariantMap(vm, QLatin1String(KEY_SNAPY), grid.m_snapY);
+ anyData |= valueFromVariantMap(vm, QLatin1String(KEY_DELTAX), grid.m_deltaX);
+ anyData |= valueFromVariantMap(vm, QLatin1String(KEY_DELTAY), grid.m_deltaY);
+ if (!anyData)
+ return false;
+ if (grid.m_deltaX == 0 || grid.m_deltaY == 0) {
+ qWarning("Attempt to set invalid grid with a spacing of 0.");
+ return false;
+ }
+ *this = grid;
+ return true;
+}
+
+QVariantMap Grid::toVariantMap(bool forceKeys) const
+{
+ QVariantMap rc;
+ addToVariantMap(rc, forceKeys);
+ return rc;
+}
+
+void Grid::addToVariantMap(QVariantMap& vm, bool forceKeys) const
+{
+ valueToVariantMap(m_visible, defaultVisible, QLatin1String(KEY_VISIBLE), vm, forceKeys);
+ valueToVariantMap(m_snapX, defaultSnap, QLatin1String(KEY_SNAPX), vm, forceKeys);
+ valueToVariantMap(m_snapY, defaultSnap, QLatin1String(KEY_SNAPY), vm, forceKeys);
+ valueToVariantMap(m_deltaX, DEFAULT_GRID, QLatin1String(KEY_DELTAX), vm, forceKeys);
+ valueToVariantMap(m_deltaY, DEFAULT_GRID, QLatin1String(KEY_DELTAY), vm, forceKeys);
+}
+
+void Grid::paint(QWidget *widget, QPaintEvent *e) const
+{
+ QPainter p(widget);
+ paint(p, widget, e);
+}
+
+void Grid::paint(QPainter &p, const QWidget *widget, QPaintEvent *e) const
+{
+ p.setPen(widget->palette().dark().color());
+
+ if (m_visible) {
+ const int xstart = (e->rect().x() / m_deltaX) * m_deltaX;
+ const int ystart = (e->rect().y() / m_deltaY) * m_deltaY;
+
+ const int xend = e->rect().right();
+ const int yend = e->rect().bottom();
+
+ typedef QVector<QPointF> Points;
+ static Points points;
+ points.clear();
+
+ for (int x = xstart; x <= xend; x += m_deltaX) {
+ points.reserve((yend - ystart) / m_deltaY + 1);
+ for (int y = ystart; y <= yend; y += m_deltaY)
+ points.push_back(QPointF(x, y));
+ p.drawPoints( &(*points.begin()), points.count());
+ points.clear();
+ }
+ }
+}
+
+int Grid::snapValue(int value, int grid) const
+{
+ const int rest = value % grid;
+ const int absRest = (rest < 0) ? -rest : rest;
+ int offset = 0;
+ if (2 * absRest > grid)
+ offset = 1;
+ if (rest < 0)
+ offset *= -1;
+ return (value / grid + offset) * grid;
+}
+
+QPoint Grid::snapPoint(const QPoint &p) const
+{
+ const int sx = m_snapX ? snapValue(p.x(), m_deltaX) : p.x();
+ const int sy = m_snapY ? snapValue(p.y(), m_deltaY) : p.y();
+ return QPoint(sx, sy);
+}
+
+int Grid::widgetHandleAdjustX(int x) const
+{
+ return m_snapX ? (x / m_deltaX) * m_deltaX + 1 : x;
+}
+
+int Grid::widgetHandleAdjustY(int y) const
+{
+ return m_snapY ? (y / m_deltaY) * m_deltaY + 1 : y;
+}
+
+bool Grid::equals(const Grid &rhs) const
+{
+ return m_visible == rhs.m_visible &&
+ m_snapX == rhs.m_snapX &&
+ m_snapY == rhs.m_snapY &&
+ m_deltaX == rhs.m_deltaX &&
+ m_deltaY == rhs.m_deltaY;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/grid_p.h b/src/designer/src/lib/shared/grid_p.h
new file mode 100644
index 000000000..b9c7316df
--- /dev/null
+++ b/src/designer/src/lib/shared/grid_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_GRID_H
+#define QDESIGNER_GRID_H
+
+#include "shared_global_p.h"
+
+#include <QtCore/QVariantMap>
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+class QPaintEvent;
+class QPainter;
+
+namespace qdesigner_internal {
+
+// Designer grid which is able to serialize to QVariantMap
+class QDESIGNER_SHARED_EXPORT Grid
+{
+public:
+ Grid();
+
+ bool fromVariantMap(const QVariantMap& vm);
+
+ void addToVariantMap(QVariantMap& vm, bool forceKeys = false) const;
+ QVariantMap toVariantMap(bool forceKeys = false) const;
+
+ inline bool visible() const { return m_visible; }
+ void setVisible(bool visible) { m_visible = visible; }
+
+ inline bool snapX() const { return m_snapX; }
+ void setSnapX(bool snap) { m_snapX = snap; }
+
+ inline bool snapY() const { return m_snapY; }
+ void setSnapY(bool snap) { m_snapY = snap; }
+
+ inline int deltaX() const { return m_deltaX; }
+ void setDeltaX(int dx) { m_deltaX = dx; }
+
+ inline int deltaY() const { return m_deltaY; }
+ void setDeltaY(int dy) { m_deltaY = dy; }
+
+ void paint(QWidget *widget, QPaintEvent *e) const;
+ void paint(QPainter &p, const QWidget *widget, QPaintEvent *e) const;
+
+ QPoint snapPoint(const QPoint &p) const;
+
+ int widgetHandleAdjustX(int x) const;
+ int widgetHandleAdjustY(int y) const;
+
+ inline bool operator==(const Grid &rhs) const { return equals(rhs); }
+ inline bool operator!=(const Grid &rhs) const { return !equals(rhs); }
+
+private:
+ bool equals(const Grid &rhs) const;
+ int snapValue(int value, int grid) const;
+ bool m_visible;
+ bool m_snapX;
+ bool m_snapY;
+ int m_deltaX;
+ int m_deltaY;
+};
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_GRID_H
diff --git a/src/designer/src/lib/shared/gridpanel.cpp b/src/designer/src/lib/shared/gridpanel.cpp
new file mode 100644
index 000000000..0319e5e95
--- /dev/null
+++ b/src/designer/src/lib/shared/gridpanel.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gridpanel_p.h"
+#include "ui_gridpanel.h"
+#include "grid_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+GridPanel::GridPanel(QWidget *parentWidget) :
+ QWidget(parentWidget)
+{
+ m_ui = new Ui::GridPanel;
+ m_ui->setupUi(this);
+
+ connect(m_ui->m_resetButton, SIGNAL(clicked()), this, SLOT(reset()));
+}
+
+GridPanel::~GridPanel()
+{
+ delete m_ui;
+}
+
+void GridPanel::setGrid(const Grid &g)
+{
+ m_ui->m_deltaXSpinBox->setValue(g.deltaX());
+ m_ui->m_deltaYSpinBox->setValue(g.deltaY());
+ m_ui->m_visibleCheckBox->setCheckState(g.visible() ? Qt::Checked : Qt::Unchecked);
+ m_ui->m_snapXCheckBox->setCheckState(g.snapX() ? Qt::Checked : Qt::Unchecked);
+ m_ui->m_snapYCheckBox->setCheckState(g.snapY() ? Qt::Checked : Qt::Unchecked);
+}
+
+void GridPanel::setTitle(const QString &title)
+{
+ m_ui->m_gridGroupBox->setTitle(title);
+}
+
+Grid GridPanel::grid() const
+{
+ Grid rc;
+ rc.setDeltaX(m_ui->m_deltaXSpinBox->value());
+ rc.setDeltaY(m_ui->m_deltaYSpinBox->value());
+ rc.setSnapX(m_ui->m_snapXCheckBox->checkState() == Qt::Checked);
+ rc.setSnapY(m_ui->m_snapYCheckBox->checkState() == Qt::Checked);
+ rc.setVisible(m_ui->m_visibleCheckBox->checkState() == Qt::Checked);
+ return rc;
+}
+
+void GridPanel::reset()
+{
+ setGrid(Grid());
+}
+
+void GridPanel::setCheckable (bool c)
+{
+ m_ui->m_gridGroupBox->setCheckable(c);
+}
+
+bool GridPanel::isCheckable () const
+{
+ return m_ui->m_gridGroupBox->isCheckable ();
+}
+
+bool GridPanel::isChecked () const
+{
+ return m_ui->m_gridGroupBox->isChecked ();
+}
+
+void GridPanel::setChecked(bool c)
+{
+ m_ui->m_gridGroupBox->setChecked(c);
+}
+
+void GridPanel::setResetButtonVisible(bool v)
+{
+ m_ui->m_resetButton->setVisible(v);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/gridpanel.ui b/src/designer/src/lib/shared/gridpanel.ui
new file mode 100644
index 000000000..adfdd3684
--- /dev/null
+++ b/src/designer/src/lib/shared/gridpanel.ui
@@ -0,0 +1,144 @@
+<ui version="4.0" >
+ <class>qdesigner_internal::GridPanel</class>
+ <widget class="QWidget" name="qdesigner_internal::GridPanel" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>393</width>
+ <height>110</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="m_gridGroupBox" >
+ <property name="title" >
+ <string>Grid</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QCheckBox" name="m_visibleCheckBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Visible</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Grid &amp;X</string>
+ </property>
+ <property name="buddy" >
+ <cstring>m_deltaXSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QSpinBox" name="m_deltaXSpinBox" >
+ <property name="minimum" >
+ <number>2</number>
+ </property>
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QCheckBox" name="m_snapXCheckBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Snap</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="m_resetButton" >
+ <property name="text" >
+ <string>Reset</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Grid &amp;Y</string>
+ </property>
+ <property name="buddy" >
+ <cstring>m_deltaYSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QSpinBox" name="m_deltaYSpinBox" >
+ <property name="minimum" >
+ <number>2</number>
+ </property>
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QCheckBox" name="m_snapYCheckBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Snap</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/lib/shared/gridpanel_p.h b/src/designer/src/lib/shared/gridpanel_p.h
new file mode 100644
index 000000000..adcfa3850
--- /dev/null
+++ b/src/designer/src/lib/shared/gridpanel_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Qt tools. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef GRIDPANEL_H
+#define GRIDPANEL_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class Grid;
+
+namespace Ui {
+ class GridPanel;
+}
+
+class QDESIGNER_SHARED_EXPORT GridPanel : public QWidget
+{
+ Q_OBJECT
+public:
+ GridPanel(QWidget *parent = 0);
+ ~GridPanel();
+
+ void setTitle(const QString &title);
+
+ void setGrid(const Grid &g);
+ Grid grid() const;
+
+ void setCheckable (bool c);
+ bool isCheckable () const;
+
+ bool isChecked () const;
+ void setChecked(bool c);
+
+ void setResetButtonVisible(bool v);
+
+private slots:
+ void reset();
+
+private:
+ Ui::GridPanel *m_ui;
+};
+
+} // qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // GRIDPANEL_H
diff --git a/src/designer/src/lib/shared/htmlhighlighter.cpp b/src/designer/src/lib/shared/htmlhighlighter.cpp
new file mode 100644
index 000000000..d16ce62aa
--- /dev/null
+++ b/src/designer/src/lib/shared/htmlhighlighter.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QTextStream>
+
+#include "htmlhighlighter_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+HtmlHighlighter::HtmlHighlighter(QTextEdit *textEdit)
+ : QSyntaxHighlighter(textEdit)
+{
+ QTextCharFormat entityFormat;
+ entityFormat.setForeground(Qt::red);
+ setFormatFor(Entity, entityFormat);
+
+ QTextCharFormat tagFormat;
+ tagFormat.setForeground(Qt::darkMagenta);
+ tagFormat.setFontWeight(QFont::Bold);
+ setFormatFor(Tag, tagFormat);
+
+ QTextCharFormat commentFormat;
+ commentFormat.setForeground(Qt::gray);
+ commentFormat.setFontItalic(true);
+ setFormatFor(Comment, commentFormat);
+
+ QTextCharFormat attributeFormat;
+ attributeFormat.setForeground(Qt::black);
+ attributeFormat.setFontWeight(QFont::Bold);
+ setFormatFor(Attribute, attributeFormat);
+
+ QTextCharFormat valueFormat;
+ valueFormat.setForeground(Qt::blue);
+ setFormatFor(Value, valueFormat);
+}
+
+void HtmlHighlighter::setFormatFor(Construct construct,
+ const QTextCharFormat &format)
+{
+ m_formats[construct] = format;
+ rehighlight();
+}
+
+void HtmlHighlighter::highlightBlock(const QString &text)
+{
+ static const QLatin1Char tab = QLatin1Char('\t');
+ static const QLatin1Char space = QLatin1Char(' ');
+ static const QLatin1Char amp = QLatin1Char('&');
+ static const QLatin1Char startTag = QLatin1Char('<');
+ static const QLatin1Char endTag = QLatin1Char('>');
+ static const QLatin1Char quot = QLatin1Char('"');
+ static const QLatin1Char apos = QLatin1Char('\'');
+ static const QLatin1Char semicolon = QLatin1Char(';');
+ static const QLatin1Char equals = QLatin1Char('=');
+ static const QLatin1String startComment = QLatin1String("<!--");
+ static const QLatin1String endComment = QLatin1String("-->");
+ static const QLatin1String endElement = QLatin1String("/>");
+
+ int state = previousBlockState();
+ int len = text.length();
+ int start = 0;
+ int pos = 0;
+
+ while (pos < len) {
+ switch (state) {
+ case NormalState:
+ default:
+ while (pos < len) {
+ QChar ch = text.at(pos);
+ if (ch == startTag) {
+ if (text.mid(pos, 4) == startComment) {
+ state = InComment;
+ } else {
+ state = InTag;
+ start = pos;
+ while (pos < len && text.at(pos) != space
+ && text.at(pos) != endTag
+ && text.at(pos) != tab
+ && text.mid(pos, 2) != endElement)
+ ++pos;
+ if (text.mid(pos, 2) == endElement)
+ ++pos;
+ setFormat(start, pos - start,
+ m_formats[Tag]);
+ break;
+ }
+ break;
+ } else if (ch == amp) {
+ start = pos;
+ while (pos < len && text.at(pos++) != semicolon)
+ ;
+ setFormat(start, pos - start,
+ m_formats[Entity]);
+ } else {
+ // No tag, comment or entity started, continue...
+ ++pos;
+ }
+ }
+ break;
+ case InComment:
+ start = pos;
+ while (pos < len) {
+ if (text.mid(pos, 3) == endComment) {
+ pos += 3;
+ state = NormalState;
+ break;
+ } else {
+ ++pos;
+ }
+ }
+ setFormat(start, pos - start, m_formats[Comment]);
+ break;
+ case InTag:
+ QChar quote = QChar::Null;
+ while (pos < len) {
+ QChar ch = text.at(pos);
+ if (quote.isNull()) {
+ start = pos;
+ if (ch == apos || ch == quot) {
+ quote = ch;
+ } else if (ch == endTag) {
+ ++pos;
+ setFormat(start, pos - start, m_formats[Tag]);
+ state = NormalState;
+ break;
+ } else if (text.mid(pos, 2) == endElement) {
+ pos += 2;
+ setFormat(start, pos - start, m_formats[Tag]);
+ state = NormalState;
+ break;
+ } else if (ch != space && text.at(pos) != tab) {
+ // Tag not ending, not a quote and no whitespace, so
+ // we must be dealing with an attribute.
+ ++pos;
+ while (pos < len && text.at(pos) != space
+ && text.at(pos) != tab
+ && text.at(pos) != equals)
+ ++pos;
+ setFormat(start, pos - start, m_formats[Attribute]);
+ start = pos;
+ }
+ } else if (ch == quote) {
+ quote = QChar::Null;
+
+ // Anything quoted is a value
+ setFormat(start, pos - start, m_formats[Value]);
+ }
+ ++pos;
+ }
+ break;
+ }
+ }
+ setCurrentBlockState(state);
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/htmlhighlighter_p.h b/src/designer/src/lib/shared/htmlhighlighter_p.h
new file mode 100644
index 000000000..3c9bfc34b
--- /dev/null
+++ b/src/designer/src/lib/shared/htmlhighlighter_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef HTMLHIGHLIGHTER_H
+#define HTMLHIGHLIGHTER_H
+
+#include <QtGui/QSyntaxHighlighter>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+/* HTML syntax highlighter based on Qt Quarterly example */
+class HtmlHighlighter : public QSyntaxHighlighter
+{
+ Q_OBJECT
+
+public:
+ enum Construct {
+ Entity,
+ Tag,
+ Comment,
+ Attribute,
+ Value,
+ LastConstruct = Value
+ };
+
+ HtmlHighlighter(QTextEdit *textEdit);
+
+ void setFormatFor(Construct construct, const QTextCharFormat &format);
+
+ QTextCharFormat formatFor(Construct construct) const
+ { return m_formats[construct]; }
+
+protected:
+ enum State {
+ NormalState = -1,
+ InComment,
+ InTag
+ };
+
+ void highlightBlock(const QString &text);
+
+private:
+ QTextCharFormat m_formats[LastConstruct + 1];
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // HTMLHIGHLIGHTER_H
diff --git a/src/designer/src/lib/shared/iconloader.cpp b/src/designer/src/lib/shared/iconloader.cpp
new file mode 100644
index 000000000..b7f74b224
--- /dev/null
+++ b/src/designer/src/lib/shared/iconloader.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "iconloader_p.h"
+
+#include <QtCore/QFile>
+#include <QtGui/QIcon>
+#include <QtGui/QPixmap>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QDESIGNER_SHARED_EXPORT QIcon createIconSet(const QString &name)
+{
+ QStringList candidates = QStringList()
+ << (QString::fromUtf8(":/trolltech/formeditor/images/") + name)
+#ifdef Q_WS_MAC
+ << (QString::fromUtf8(":/trolltech/formeditor/images/mac/") + name)
+#else
+ << (QString::fromUtf8(":/trolltech/formeditor/images/win/") + name)
+#endif
+ << (QString::fromUtf8(":/trolltech/formeditor/images/designer_") + name);
+
+ foreach (const QString &f, candidates) {
+ if (QFile::exists(f))
+ return QIcon(f);
+ }
+
+ return QIcon();
+}
+
+QDESIGNER_SHARED_EXPORT QIcon emptyIcon()
+{
+ return QIcon(QLatin1String(":/trolltech/formeditor/images/emptyicon.png"));
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/lib/shared/iconloader_p.h b/src/designer/src/lib/shared/iconloader_p.h
new file mode 100644
index 000000000..f0e4d0ace
--- /dev/null
+++ b/src/designer/src/lib/shared/iconloader_p.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ICONLOADER_H
+#define ICONLOADER_H
+
+#include "shared_global_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+class QIcon;
+
+namespace qdesigner_internal {
+
+QDESIGNER_SHARED_EXPORT QIcon createIconSet(const QString &name);
+QDESIGNER_SHARED_EXPORT QIcon emptyIcon();
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ICONLOADER_H
diff --git a/src/designer/src/lib/shared/iconselector.cpp b/src/designer/src/lib/shared/iconselector.cpp
new file mode 100644
index 000000000..0d6e3e0e8
--- /dev/null
+++ b/src/designer/src/lib/shared/iconselector.cpp
@@ -0,0 +1,655 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "iconselector_p.h"
+#include "qdesigner_utils_p.h"
+#include "qtresourcemodel_p.h"
+#include "qtresourceview_p.h"
+#include "iconloader_p.h"
+#include "qdesigner_integration_p.h"
+#include "formwindowbase_p.h"
+
+#include <abstractdialoggui_p.h>
+#include <qdesigner_integration_p.h>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerResourceBrowserInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QToolButton>
+#include <QtCore/QSignalMapper>
+#include <QtGui/QComboBox>
+#include <QtGui/QAction>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QDialog>
+#include <QtGui/QMenu>
+#include <QtGui/QApplication>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QImageReader>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QLabel>
+#include <QtGui/QValidator>
+#include <QtCore/QDebug>
+
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// -------------------- LanguageResourceDialogPrivate
+class LanguageResourceDialogPrivate {
+ LanguageResourceDialog *q_ptr;
+ Q_DECLARE_PUBLIC(LanguageResourceDialog)
+
+public:
+ LanguageResourceDialogPrivate(QDesignerResourceBrowserInterface *rb);
+ void init(LanguageResourceDialog *p);
+
+ void setCurrentPath(const QString &filePath);
+ QString currentPath() const;
+
+ void slotAccepted();
+ void slotPathChanged(const QString &);
+
+private:
+ void setOkButtonEnabled(bool v) { m_dialogButtonBox->button(QDialogButtonBox::Ok)->setEnabled(v); }
+ static bool checkPath(const QString &p);
+
+ QDesignerResourceBrowserInterface *m_browser;
+ QDialogButtonBox *m_dialogButtonBox;
+};
+
+LanguageResourceDialogPrivate::LanguageResourceDialogPrivate(QDesignerResourceBrowserInterface *rb) :
+ q_ptr(0),
+ m_browser(rb),
+ m_dialogButtonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel))
+{
+ setOkButtonEnabled(false);
+}
+
+void LanguageResourceDialogPrivate::init(LanguageResourceDialog *p)
+{
+ q_ptr = p;
+ QLayout *layout = new QVBoxLayout(p);
+ layout->addWidget(m_browser);
+ layout->addWidget(m_dialogButtonBox);
+ QObject::connect(m_dialogButtonBox, SIGNAL(accepted()), p, SLOT(slotAccepted()));
+ QObject::connect(m_dialogButtonBox, SIGNAL(rejected()), p, SLOT(reject()));
+ QObject::connect(m_browser, SIGNAL(currentPathChanged(QString)), p, SLOT(slotPathChanged(QString)));
+ QObject::connect(m_browser, SIGNAL(pathActivated(QString)), p, SLOT(slotAccepted()));
+ p->setModal(true);
+ p->setWindowTitle(LanguageResourceDialog::tr("Choose Resource"));
+ p->setWindowFlags(p->windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setOkButtonEnabled(false);
+}
+
+void LanguageResourceDialogPrivate::setCurrentPath(const QString &filePath)
+{
+ m_browser->setCurrentPath(filePath);
+ setOkButtonEnabled(checkPath(filePath));
+}
+
+QString LanguageResourceDialogPrivate::currentPath() const
+{
+ return m_browser->currentPath();
+}
+
+bool LanguageResourceDialogPrivate::checkPath(const QString &p)
+{
+ return p.isEmpty() ? false : IconSelector::checkPixmap(p, IconSelector::CheckFast);
+}
+
+void LanguageResourceDialogPrivate::slotAccepted()
+{
+ if (checkPath(currentPath()))
+ q_ptr->accept();
+}
+
+void LanguageResourceDialogPrivate::slotPathChanged(const QString &p)
+{
+ setOkButtonEnabled(checkPath(p));
+}
+
+// ------------ LanguageResourceDialog
+LanguageResourceDialog::LanguageResourceDialog(QDesignerResourceBrowserInterface *rb, QWidget *parent) :
+ QDialog(parent),
+ d_ptr(new LanguageResourceDialogPrivate(rb))
+{
+ d_ptr->init( this);
+}
+
+LanguageResourceDialog::~LanguageResourceDialog()
+{
+}
+
+void LanguageResourceDialog::setCurrentPath(const QString &filePath)
+{
+ d_ptr->setCurrentPath(filePath);
+}
+
+QString LanguageResourceDialog::currentPath() const
+{
+ return d_ptr->currentPath();
+}
+
+LanguageResourceDialog* LanguageResourceDialog::create(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core))
+ if (QDesignerResourceBrowserInterface *rb = lang->createResourceBrowser(0))
+ return new LanguageResourceDialog(rb, parent);
+ if (QDesignerIntegration *di = qobject_cast<QDesignerIntegration*>(core->integration()))
+ if (QDesignerResourceBrowserInterface *rb = di->createResourceBrowser(0))
+ return new LanguageResourceDialog(rb, parent);
+ return 0;
+}
+
+// ------------ IconSelectorPrivate
+
+static inline QPixmap emptyPixmap()
+{
+ QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+ return QPixmap::fromImage(img);
+}
+
+class IconSelectorPrivate
+{
+ IconSelector *q_ptr;
+ Q_DECLARE_PUBLIC(IconSelector)
+public:
+ IconSelectorPrivate();
+
+ void slotStateActivated();
+ void slotSetActivated();
+ void slotSetResourceActivated();
+ void slotSetFileActivated();
+ void slotResetActivated();
+ void slotResetAllActivated();
+ void slotUpdate();
+
+ QList<QPair<QPair<QIcon::Mode, QIcon::State>, QString> > m_stateToName; // could be static map
+
+ QMap<QPair<QIcon::Mode, QIcon::State>, int> m_stateToIndex;
+ QMap<int, QPair<QIcon::Mode, QIcon::State> > m_indexToState;
+
+ const QIcon m_emptyIcon;
+ QComboBox *m_stateComboBox;
+ QToolButton *m_iconButton;
+ QAction *m_resetAction;
+ QAction *m_resetAllAction;
+ PropertySheetIconValue m_icon;
+ DesignerIconCache *m_iconCache;
+ DesignerPixmapCache *m_pixmapCache;
+ QtResourceModel *m_resourceModel;
+ QDesignerFormEditorInterface *m_core;
+};
+
+IconSelectorPrivate::IconSelectorPrivate() :
+ q_ptr(0),
+ m_emptyIcon(emptyPixmap()),
+ m_stateComboBox(0),
+ m_iconButton(0),
+ m_resetAction(0),
+ m_resetAllAction(0),
+ m_iconCache(0),
+ m_pixmapCache(0),
+ m_resourceModel(0),
+ m_core(0)
+{
+}
+void IconSelectorPrivate::slotUpdate()
+{
+ QIcon icon;
+ if (m_iconCache)
+ icon = m_iconCache->icon(m_icon);
+
+ QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> paths = m_icon.paths();
+ QMapIterator<QPair<QIcon::Mode, QIcon::State>, int> itIndex(m_stateToIndex);
+ while (itIndex.hasNext()) {
+ const QPair<QIcon::Mode, QIcon::State> state = itIndex.next().key();
+ const PropertySheetPixmapValue pixmap = paths.value(state);
+ const int index = itIndex.value();
+
+ QIcon pixmapIcon = QIcon(icon.pixmap(16, 16, state.first, state.second));
+ if (pixmapIcon.isNull())
+ pixmapIcon = m_emptyIcon;
+ m_stateComboBox->setItemIcon(index, pixmapIcon);
+ QFont font = q_ptr->font();
+ if (!pixmap.path().isEmpty())
+ font.setBold(true);
+ m_stateComboBox->setItemData(index, font, Qt::FontRole);
+ }
+
+ QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
+ PropertySheetPixmapValue currentPixmap = paths.value(state);
+ m_resetAction->setEnabled(!currentPixmap.path().isEmpty());
+ m_resetAllAction->setEnabled(!paths.isEmpty());
+ m_stateComboBox->update();
+}
+
+void IconSelectorPrivate::slotStateActivated()
+{
+ slotUpdate();
+}
+
+void IconSelectorPrivate::slotSetActivated()
+{
+ QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
+ const PropertySheetPixmapValue pixmap = m_icon.pixmap(state.first, state.second);
+ // Default to resource
+ const PropertySheetPixmapValue::PixmapSource ps = pixmap.path().isEmpty() ? PropertySheetPixmapValue::ResourcePixmap : pixmap.pixmapSource(m_core);
+ switch (ps) {
+ case PropertySheetPixmapValue::LanguageResourcePixmap:
+ case PropertySheetPixmapValue::ResourcePixmap:
+ slotSetResourceActivated();
+ break;
+ case PropertySheetPixmapValue::FilePixmap:
+ slotSetFileActivated();
+ break;
+ }
+}
+
+// Choose a pixmap from resource; use language-dependent resource browser if present
+QString IconSelector::choosePixmapResource(QDesignerFormEditorInterface *core, QtResourceModel *resourceModel, const QString &oldPath, QWidget *parent)
+{
+ Q_UNUSED(resourceModel)
+ QString rc;
+
+ if (LanguageResourceDialog* ldlg = LanguageResourceDialog::create(core, parent)) {
+ ldlg->setCurrentPath(oldPath);
+ if (ldlg->exec() == QDialog::Accepted)
+ rc = ldlg->currentPath();
+ delete ldlg;
+ } else {
+ QtResourceViewDialog dlg(core, parent);
+
+ QDesignerIntegration *designerIntegration = qobject_cast<QDesignerIntegration *>(core->integration());
+ if (designerIntegration)
+ dlg.setResourceEditingEnabled(designerIntegration->isResourceEditingEnabled());
+
+ dlg.selectResource(oldPath);
+ if (dlg.exec() == QDialog::Accepted)
+ rc = dlg.selectedResource();
+ }
+ return rc;
+}
+
+void IconSelectorPrivate::slotSetResourceActivated()
+{
+ const QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
+
+ PropertySheetPixmapValue pixmap = m_icon.pixmap(state.first, state.second);
+ const QString oldPath = pixmap.path();
+ const QString newPath = IconSelector::choosePixmapResource(m_core, m_resourceModel, oldPath, q_ptr);
+ if (newPath.isEmpty() || newPath == oldPath)
+ return;
+ const PropertySheetPixmapValue newPixmap = PropertySheetPixmapValue(newPath);
+ if (newPixmap != pixmap) {
+ m_icon.setPixmap(state.first, state.second, newPixmap);
+ slotUpdate();
+ emit q_ptr->iconChanged(m_icon);
+ }
+}
+
+// Helpers for choosing image files: Check for valid image.
+bool IconSelector::checkPixmap(const QString &fileName, CheckMode cm, QString *errorMessage)
+{
+ const QFileInfo fi(fileName);
+ if (!fi.exists() || !fi.isFile() || !fi.isReadable()) {
+ if (errorMessage)
+ *errorMessage = tr("The pixmap file '%1' cannot be read.").arg(fileName);
+ return false;
+ }
+ QImageReader reader(fileName);
+ if (!reader.canRead()) {
+ if (errorMessage)
+ *errorMessage = tr("The file '%1' does not appear to be a valid pixmap file: %2").arg(fileName).arg(reader.errorString());
+ return false;
+ }
+ if (cm == CheckFast)
+ return true;
+
+ const QImage image = reader.read();
+ if (image.isNull()) {
+ if (errorMessage)
+ *errorMessage = tr("The file '%1' could not be read: %2").arg(fileName).arg(reader.errorString());
+ return false;
+ }
+ return true;
+}
+
+// Helpers for choosing image files: Return an image filter for QFileDialog, courtesy of StyledButton
+static QString imageFilter()
+{
+ QString filter = QApplication::translate("IconSelector", "All Pixmaps (");
+ const QList<QByteArray> supportedImageFormats = QImageReader::supportedImageFormats();
+ const QString jpeg = QLatin1String("JPEG");
+ const int count = supportedImageFormats.count();
+ for (int i = 0; i< count; ++i) {
+ if (i)
+ filter += QLatin1Char(' ');
+ filter += QLatin1String("*.");
+ const QString outputFormat = QString::fromUtf8(supportedImageFormats.at(i));
+ if (outputFormat != jpeg)
+ filter += outputFormat.toLower();
+ else
+ filter += QLatin1String("jpg *.jpeg");
+ }
+ filter += QLatin1Char(')');
+ return filter;
+}
+
+// Helpers for choosing image files: Choose a file
+QString IconSelector::choosePixmapFile(const QString &directory, QDesignerDialogGuiInterface *dlgGui,QWidget *parent)
+{
+ QString errorMessage;
+ QString newPath;
+ do {
+ const QString title = tr("Choose a Pixmap");
+ static const QString filter = imageFilter();
+ newPath = dlgGui->getOpenImageFileName(parent, title, directory, filter);
+ if (newPath.isEmpty())
+ break;
+ if (checkPixmap(newPath, CheckFully, &errorMessage))
+ break;
+ dlgGui->message(parent, QDesignerDialogGuiInterface::ResourceEditorMessage, QMessageBox::Warning, tr("Pixmap Read Error"), errorMessage);
+ } while(true);
+ return newPath;
+}
+
+void IconSelectorPrivate::slotSetFileActivated()
+{
+ QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
+
+ PropertySheetPixmapValue pixmap = m_icon.pixmap(state.first, state.second);
+ const QString newPath = IconSelector::choosePixmapFile(pixmap.path(), m_core->dialogGui(), q_ptr);
+ if (!newPath.isEmpty()) {
+ const PropertySheetPixmapValue newPixmap = PropertySheetPixmapValue(newPath);
+ if (!(newPixmap == pixmap)) {
+ m_icon.setPixmap(state.first, state.second, newPixmap);
+ slotUpdate();
+ emit q_ptr->iconChanged(m_icon);
+ }
+ }
+}
+
+void IconSelectorPrivate::slotResetActivated()
+{
+ QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
+
+ PropertySheetPixmapValue pixmap = m_icon.pixmap(state.first, state.second);
+ const PropertySheetPixmapValue newPixmap;
+ if (!(newPixmap == pixmap)) {
+ m_icon.setPixmap(state.first, state.second, newPixmap);
+ slotUpdate();
+ emit q_ptr->iconChanged(m_icon);
+ }
+}
+
+void IconSelectorPrivate::slotResetAllActivated()
+{
+ const PropertySheetIconValue newIcon;
+ if (!(m_icon == newIcon)) {
+ m_icon = newIcon;
+ slotUpdate();
+ emit q_ptr->iconChanged(m_icon);
+ }
+}
+
+// ------------- IconSelector
+IconSelector::IconSelector(QWidget *parent) :
+ QWidget(parent), d_ptr(new IconSelectorPrivate())
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_stateComboBox = new QComboBox(this);
+
+ QHBoxLayout *l = new QHBoxLayout(this);
+ d_ptr->m_iconButton = new QToolButton(this);
+ d_ptr->m_iconButton->setText(tr("..."));
+ d_ptr->m_iconButton->setPopupMode(QToolButton::MenuButtonPopup);
+ l->addWidget(d_ptr->m_stateComboBox);
+ l->addWidget(d_ptr->m_iconButton);
+ l->setMargin(0);
+
+ d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Normal, QIcon::Off), tr("Normal Off") );
+ d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Normal, QIcon::On), tr("Normal On") );
+ d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Disabled, QIcon::Off), tr("Disabled Off") );
+ d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Disabled, QIcon::On), tr("Disabled On") );
+ d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Active, QIcon::Off), tr("Active Off") );
+ d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Active, QIcon::On), tr("Active On") );
+ d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Selected, QIcon::Off), tr("Selected Off") );
+ d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Selected, QIcon::On), tr("Selected On") );
+
+ QMenu *setMenu = new QMenu(this);
+
+ QAction *setResourceAction = new QAction(tr("Choose Resource..."), this);
+ QAction *setFileAction = new QAction(tr("Choose File..."), this);
+ d_ptr->m_resetAction = new QAction(tr("Reset"), this);
+ d_ptr->m_resetAllAction = new QAction(tr("Reset All"), this);
+ d_ptr->m_resetAction->setEnabled(false);
+ d_ptr->m_resetAllAction->setEnabled(false);
+ //d_ptr->m_resetAction->setIcon(createIconSet(QString::fromUtf8("resetproperty.png")));
+
+ setMenu->addAction(setResourceAction);
+ setMenu->addAction(setFileAction);
+ setMenu->addSeparator();
+ setMenu->addAction(d_ptr->m_resetAction);
+ setMenu->addAction(d_ptr->m_resetAllAction);
+
+ int index = 0;
+ QStringList items;
+ QListIterator<QPair<QPair<QIcon::Mode, QIcon::State>, QString> > itName(d_ptr->m_stateToName);
+ while (itName.hasNext()) {
+ QPair<QPair<QIcon::Mode, QIcon::State>, QString> item = itName.next();
+ const QPair<QIcon::Mode, QIcon::State> state = item.first;
+ const QString name = item.second;
+
+ items.append(name);
+ d_ptr->m_stateToIndex[state] = index;
+ d_ptr->m_indexToState[index] = state;
+ index++;
+ }
+ d_ptr->m_stateComboBox->addItems(items);
+
+ d_ptr->m_iconButton->setMenu(setMenu);
+
+ connect(d_ptr->m_stateComboBox, SIGNAL(activated(int)), this, SLOT(slotStateActivated()));
+ connect(d_ptr->m_iconButton, SIGNAL(clicked()), this, SLOT(slotSetActivated()));
+ connect(setResourceAction, SIGNAL(triggered()), this, SLOT(slotSetResourceActivated()));
+ connect(setFileAction, SIGNAL(triggered()), this, SLOT(slotSetFileActivated()));
+ connect(d_ptr->m_resetAction, SIGNAL(triggered()), this, SLOT(slotResetActivated()));
+ connect(d_ptr->m_resetAllAction, SIGNAL(triggered()), this, SLOT(slotResetAllActivated()));
+
+ d_ptr->slotUpdate();
+}
+
+IconSelector::~IconSelector()
+{
+}
+
+void IconSelector::setIcon(const PropertySheetIconValue &icon)
+{
+ if (d_ptr->m_icon == icon)
+ return;
+
+ d_ptr->m_icon = icon;
+ d_ptr->slotUpdate();
+}
+
+PropertySheetIconValue IconSelector::icon() const
+{
+ return d_ptr->m_icon;
+}
+
+void IconSelector::setFormEditor(QDesignerFormEditorInterface *core)
+{
+ d_ptr->m_core = core;
+ d_ptr->m_resourceModel = core->resourceModel();
+ d_ptr->slotUpdate();
+}
+
+void IconSelector::setIconCache(DesignerIconCache *iconCache)
+{
+ d_ptr->m_iconCache = iconCache;
+ connect(iconCache, SIGNAL(reloaded()), this, SLOT(slotUpdate()));
+ d_ptr->slotUpdate();
+}
+
+void IconSelector::setPixmapCache(DesignerPixmapCache *pixmapCache)
+{
+ d_ptr->m_pixmapCache = pixmapCache;
+ connect(pixmapCache, SIGNAL(reloaded()), this, SLOT(slotUpdate()));
+ d_ptr->slotUpdate();
+}
+
+// --- IconThemeEditor
+
+// Validator for theme line edit, accepts empty or non-blank strings.
+class BlankSuppressingValidator : public QValidator {
+public:
+ explicit BlankSuppressingValidator(QObject * parent = 0) : QValidator(parent) {}
+
+ virtual State validate(QString &input, int &pos) const {
+ const int blankPos = input.indexOf(QLatin1Char(' '));
+ if (blankPos != -1) {
+ pos = blankPos;
+ return Invalid;
+ }
+ return Acceptable;
+ }
+};
+
+struct IconThemeEditorPrivate {
+ IconThemeEditorPrivate();
+
+ const QPixmap m_emptyPixmap;
+ QLineEdit *m_themeLineEdit;
+ QLabel *m_themeLabel;
+};
+
+IconThemeEditorPrivate::IconThemeEditorPrivate() :
+ m_emptyPixmap(emptyPixmap()),
+ m_themeLineEdit(new QLineEdit),
+ m_themeLabel(new QLabel)
+{
+}
+
+IconThemeEditor::IconThemeEditor(QWidget *parent, bool wantResetButton) :
+ QWidget (parent), d(new IconThemeEditorPrivate)
+{
+ QHBoxLayout *mainHLayout = new QHBoxLayout;
+ mainHLayout->setMargin(0);
+
+ // Vertically center theme preview label
+ d->m_themeLabel->setPixmap(d->m_emptyPixmap);
+
+ QVBoxLayout *themeLabelVLayout = new QVBoxLayout;
+ d->m_themeLabel->setMargin(1);
+ themeLabelVLayout->setMargin(0);
+ themeLabelVLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
+ themeLabelVLayout->addWidget(d->m_themeLabel);
+ themeLabelVLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
+ mainHLayout->addLayout(themeLabelVLayout);
+
+ d->m_themeLineEdit = new QLineEdit;
+ d->m_themeLineEdit->setValidator(new BlankSuppressingValidator(d->m_themeLineEdit));
+ connect(d->m_themeLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotChanged(QString)));
+ connect(d->m_themeLineEdit, SIGNAL(textEdited(QString)), this, SIGNAL(edited(QString)));
+ mainHLayout->addWidget(d->m_themeLineEdit);
+
+ if (wantResetButton) {
+ QToolButton *themeResetButton = new QToolButton;
+ themeResetButton->setIcon(createIconSet(QLatin1String("resetproperty.png")));
+ connect(themeResetButton, SIGNAL(clicked()), this, SLOT(reset()));
+ mainHLayout->addWidget(themeResetButton);
+ }
+
+ setLayout(mainHLayout);
+ setFocusProxy(d->m_themeLineEdit);
+}
+
+IconThemeEditor::~IconThemeEditor()
+{
+}
+
+void IconThemeEditor::reset()
+{
+ d->m_themeLineEdit->clear();
+ emit edited(QString());
+}
+
+void IconThemeEditor::slotChanged(const QString &theme)
+{
+ updatePreview(theme);
+}
+
+void IconThemeEditor::updatePreview(const QString &t)
+{
+ // Update preview label with icon.
+ if (t.isEmpty() || !QIcon::hasThemeIcon(t)) { // Empty
+ const QPixmap *currentPixmap = d->m_themeLabel->pixmap();
+ if (currentPixmap == 0 || currentPixmap->serialNumber() != d->m_emptyPixmap.serialNumber())
+ d->m_themeLabel->setPixmap(d->m_emptyPixmap);
+ } else {
+ const QIcon icon = QIcon::fromTheme(t);
+ d->m_themeLabel->setPixmap(icon.pixmap(d->m_emptyPixmap.size()));
+ }
+}
+
+QString IconThemeEditor::theme() const
+{
+ return d->m_themeLineEdit->text();
+}
+
+void IconThemeEditor::setTheme(const QString &t)
+{
+ d->m_themeLineEdit->setText(t);
+}
+
+} // qdesigner_internal
+
+QT_END_NAMESPACE
+
+#include "moc_iconselector_p.cpp"
diff --git a/src/designer/src/lib/shared/iconselector_p.h b/src/designer/src/lib/shared/iconselector_p.h
new file mode 100644
index 000000000..4f68b730f
--- /dev/null
+++ b/src/designer/src/lib/shared/iconselector_p.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef ICONSELECTOR_H
+#define ICONSELECTOR_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QWidget>
+#include <QtGui/QDialog>
+
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QtResourceModel;
+class QDesignerFormEditorInterface;
+class QDesignerDialogGuiInterface;
+class QDesignerResourceBrowserInterface;
+
+namespace qdesigner_internal {
+
+class DesignerIconCache;
+class DesignerPixmapCache;
+class PropertySheetIconValue;
+struct IconThemeEditorPrivate;
+
+// Resource Dialog that embeds the language-dependent resource widget as returned by the language extension
+class QDESIGNER_SHARED_EXPORT LanguageResourceDialog : public QDialog
+{
+ Q_OBJECT
+
+ explicit LanguageResourceDialog(QDesignerResourceBrowserInterface *rb, QWidget *parent = 0);
+
+public:
+ virtual ~LanguageResourceDialog();
+ // Factory: Returns 0 if the language extension does not provide a resource browser.
+ static LanguageResourceDialog* create(QDesignerFormEditorInterface *core, QWidget *parent);
+
+ void setCurrentPath(const QString &filePath);
+ QString currentPath() const;
+
+private:
+ QScopedPointer<class LanguageResourceDialogPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(LanguageResourceDialog)
+ Q_DISABLE_COPY(LanguageResourceDialog)
+ Q_PRIVATE_SLOT(d_func(), void slotAccepted())
+ Q_PRIVATE_SLOT(d_func(), void slotPathChanged(QString))
+
+};
+
+class QDESIGNER_SHARED_EXPORT IconSelector: public QWidget
+{
+ Q_OBJECT
+public:
+ IconSelector(QWidget *parent = 0);
+ virtual ~IconSelector();
+
+ void setFormEditor(QDesignerFormEditorInterface *core); // required for dialog gui.
+ void setIconCache(DesignerIconCache *iconCache);
+ void setPixmapCache(DesignerPixmapCache *pixmapCache);
+
+ void setIcon(const PropertySheetIconValue &icon);
+ PropertySheetIconValue icon() const;
+
+ // Check whether a pixmap may be read
+ enum CheckMode { CheckFast, CheckFully };
+ static bool checkPixmap(const QString &fileName, CheckMode cm = CheckFully, QString *errorMessage = 0);
+ // Choose a pixmap from file
+ static QString choosePixmapFile(const QString &directory, QDesignerDialogGuiInterface *dlgGui, QWidget *parent);
+ // Choose a pixmap from resource; use language-dependent resource browser if present
+ static QString choosePixmapResource(QDesignerFormEditorInterface *core, QtResourceModel *resourceModel, const QString &oldPath, QWidget *parent);
+
+signals:
+ void iconChanged(const PropertySheetIconValue &icon);
+private:
+ QScopedPointer<class IconSelectorPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(IconSelector)
+ Q_DISABLE_COPY(IconSelector)
+
+ Q_PRIVATE_SLOT(d_func(), void slotStateActivated())
+ Q_PRIVATE_SLOT(d_func(), void slotSetActivated())
+ Q_PRIVATE_SLOT(d_func(), void slotSetResourceActivated())
+ Q_PRIVATE_SLOT(d_func(), void slotSetFileActivated())
+ Q_PRIVATE_SLOT(d_func(), void slotResetActivated())
+ Q_PRIVATE_SLOT(d_func(), void slotResetAllActivated())
+ Q_PRIVATE_SLOT(d_func(), void slotUpdate())
+};
+
+// IconThemeEditor: Let's the user input theme icon names and shows a preview label.
+class QDESIGNER_SHARED_EXPORT IconThemeEditor : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QString theme READ theme WRITE setTheme DESIGNABLE true)
+public:
+ explicit IconThemeEditor(QWidget *parent = 0, bool wantResetButton = true);
+ virtual ~IconThemeEditor();
+
+ QString theme() const;
+ void setTheme(const QString &theme);
+
+signals:
+ void edited(const QString &);
+
+public slots:
+ void reset();
+
+private slots:
+ void slotChanged(const QString &);
+
+private:
+ void updatePreview(const QString &);
+
+ QScopedPointer<IconThemeEditorPrivate> d;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ICONSELECTOR_H
+
diff --git a/src/designer/src/lib/shared/invisible_widget.cpp b/src/designer/src/lib/shared/invisible_widget.cpp
new file mode 100644
index 000000000..6aceeaa52
--- /dev/null
+++ b/src/designer/src/lib/shared/invisible_widget.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "invisible_widget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+InvisibleWidget::InvisibleWidget(QWidget *parent)
+ : QWidget()
+{
+ setAttribute(Qt::WA_NoChildEventsForParent);
+ setParent(parent);
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/invisible_widget_p.h b/src/designer/src/lib/shared/invisible_widget_p.h
new file mode 100644
index 000000000..04ca72458
--- /dev/null
+++ b/src/designer/src/lib/shared/invisible_widget_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef INVISIBLE_WIDGET_H
+#define INVISIBLE_WIDGET_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT InvisibleWidget: public QWidget
+{
+ Q_OBJECT
+public:
+ InvisibleWidget(QWidget *parent = 0);
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // INVISIBLE_WIDGET_H
diff --git a/src/designer/src/lib/shared/layout.cpp b/src/designer/src/lib/shared/layout.cpp
new file mode 100644
index 000000000..9fe438b08
--- /dev/null
+++ b/src/designer/src/lib/shared/layout.cpp
@@ -0,0 +1,1332 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "layout_p.h"
+#include "qdesigner_utils_p.h"
+#include "qlayout_widget_p.h"
+#include "spacer_widget_p.h"
+#include "layoutdecoration.h"
+#include "widgetfactory_p.h"
+#include "qdesigner_widgetitem_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/QVector>
+
+#include <QtGui/qevent.h>
+#include <QtGui/QGridLayout>
+#include <QtGui/QPainter>
+#include <QtGui/QBitmap>
+#include <QtGui/QSplitter>
+#include <QtGui/QMainWindow>
+#include <QtGui/QApplication>
+#include <QtGui/QScrollArea>
+#include <QtGui/QFormLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QWizardPage>
+#include <QtGui/QWizard>
+#include <QtCore/QDebug>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+enum { FormLayoutColumns = 2 };
+
+namespace qdesigner_internal {
+
+/* The wizard has a policy of setting a size policy of its external children
+ * according to the page being expanding or not (in the latter case, the
+ * page will be pushed to the top). When setting/breaking layouts, this needs
+ * to be updated, which happens via a fake style change event. */
+
+void updateWizardLayout(QWidget *layoutBase);
+
+class FriendlyWizardPage : public QWizardPage {
+ friend void updateWizardLayout(QWidget *);
+};
+
+void updateWizardLayout(QWidget *layoutBase)
+{
+ if (QWizardPage *wizardPage = qobject_cast<QWizardPage*>(layoutBase))
+ if (QWizard *wizard = static_cast<FriendlyWizardPage*>(wizardPage)->wizard()) {
+ QEvent event(QEvent::StyleChange);
+ QApplication::sendEvent(wizard, &event);
+ }
+}
+
+/*!
+ \class Layout layout.h
+ \brief Baseclass for layouting widgets in the Designer (Helper for Layout commands)
+ \internal
+
+ Classes derived from this abstract base class are used for layouting
+ operations in the Designer (creating/breaking layouts).
+
+ Instances live in the Layout/BreakLayout commands.
+*/
+
+/*! \a p specifies the parent of the layoutBase \a lb. The parent
+ might be changed in setup(). If the layoutBase is a
+ container, the parent and the layoutBase are the same. Also they
+ always have to be a widget known to the designer (e.g. in the case
+ of the tabwidget parent and layoutBase are the tabwidget and not the
+ page which actually gets laid out. For actual usage the correct
+ widget is found later by Layout.)
+ */
+
+Layout::Layout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb, LayoutInfo::Type layoutType) :
+ m_widgets(wl),
+ m_parentWidget(p),
+ m_layoutBase(lb),
+ m_formWindow(fw),
+ m_layoutType(layoutType),
+ m_reparentLayoutWidget(true),
+ m_isBreak(false)
+{
+ if (m_layoutBase)
+ m_oldGeometry = m_layoutBase->geometry();
+}
+
+Layout::~Layout()
+{
+}
+
+/*! The widget list we got in the constructor might contain too much
+ widgets (like widgets with different parents, already laid out
+ widgets, etc.). Here we set up the list and so the only the "best"
+ widgets get laid out.
+*/
+
+void Layout::setup()
+{
+ m_startPoint = QPoint(32767, 32767);
+
+ // Go through all widgets of the list we got. As we can only
+ // layout widgets which have the same parent, we first do some
+ // sorting which means create a list for each parent containing
+ // its child here. After that we keep working on the list of
+ // children which has the most entries.
+ // Widgets which are already laid out are thrown away here too
+
+ QMultiMap<QWidget*, QWidget*> lists;
+ foreach (QWidget *w, m_widgets) {
+ QWidget *p = w->parentWidget();
+
+ if (p && LayoutInfo::layoutType(m_formWindow->core(), p) != LayoutInfo::NoLayout
+ && m_formWindow->core()->metaDataBase()->item(p->layout()) != 0)
+ continue;
+
+ lists.insert(p, w);
+ }
+
+ QWidgetList lastList;
+ QWidgetList parents = lists.keys();
+ foreach (QWidget *p, parents) {
+ QWidgetList children = lists.values(p);
+
+ if (children.count() > lastList.count())
+ lastList = children;
+ }
+
+
+ // If we found no list (because no widget did fit at all) or the
+ // best list has only one entry and we do not layout a container,
+ // we leave here.
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_formWindow->core()->widgetDataBase();
+ if (lastList.count() < 2 &&
+ (!m_layoutBase ||
+ (!widgetDataBase->isContainer(m_layoutBase, false) &&
+ m_layoutBase != m_formWindow->mainContainer()))
+ ) {
+ m_widgets.clear();
+ m_startPoint = QPoint(0, 0);
+ return;
+ }
+
+ // Now we have a new and clean widget list, which makes sense
+ // to layout
+ m_widgets = lastList;
+ // Also use the only correct parent later, so store it
+
+ Q_ASSERT(m_widgets.isEmpty() == false);
+
+ m_parentWidget = m_formWindow->core()->widgetFactory()->widgetOfContainer(m_widgets.first()->parentWidget());
+ // Now calculate the position where the layout-meta-widget should
+ // be placed and connect to widgetDestroyed() signals of the
+ // widgets to get informed if one gets deleted to be able to
+ // handle that and do not crash in this case
+ foreach (QWidget *w, m_widgets) {
+ connect(w, SIGNAL(destroyed()), this, SLOT(widgetDestroyed()));
+ m_startPoint = QPoint(qMin(m_startPoint.x(), w->x()), qMin(m_startPoint.y(), w->y()));
+ const QRect rc(w->geometry());
+
+ m_geometries.insert(w, rc);
+ // Change the Z-order, as saving/loading uses the Z-order for
+ // writing/creating widgets and this has to be the same as in
+ // the layout. Else saving + loading will give different results
+ w->raise();
+ }
+
+ sort();
+}
+
+void Layout::widgetDestroyed()
+{
+ if (QWidget *w = qobject_cast<QWidget *>(sender())) {
+ m_widgets.removeAt(m_widgets.indexOf(w));
+ m_geometries.remove(w);
+ }
+}
+
+bool Layout::prepareLayout(bool &needMove, bool &needReparent)
+{
+ foreach (QWidget *widget, m_widgets) {
+ widget->raise();
+ }
+
+ needMove = !m_layoutBase;
+ needReparent = needMove || (m_reparentLayoutWidget && qobject_cast<QLayoutWidget*>(m_layoutBase)) || qobject_cast<QSplitter*>(m_layoutBase);
+
+ QDesignerWidgetFactoryInterface *widgetFactory = m_formWindow->core()->widgetFactory();
+ QDesignerMetaDataBaseInterface *metaDataBase = m_formWindow->core()->metaDataBase();
+
+ if (m_layoutBase == 0) {
+ const bool useSplitter = m_layoutType == LayoutInfo::HSplitter || m_layoutType == LayoutInfo::VSplitter;
+ const QString baseWidgetClassName = useSplitter ? QLatin1String("QSplitter") : QLatin1String("QLayoutWidget");
+ m_layoutBase = widgetFactory->createWidget(baseWidgetClassName, widgetFactory->containerOfWidget(m_parentWidget));
+ if (useSplitter) {
+ m_layoutBase->setObjectName(QLatin1String("splitter"));
+ m_formWindow->ensureUniqueObjectName(m_layoutBase);
+ }
+ } else {
+ LayoutInfo::deleteLayout(m_formWindow->core(), m_layoutBase);
+ }
+
+ metaDataBase->add(m_layoutBase);
+
+ Q_ASSERT(m_layoutBase->layout() == 0 || metaDataBase->item(m_layoutBase->layout()) == 0);
+
+ return true;
+}
+
+static bool isMainContainer(QDesignerFormWindowInterface *fw, const QWidget *w)
+{
+ return w && (w == fw || w == fw->mainContainer());
+}
+
+static bool isPageOfContainerWidget(QDesignerFormWindowInterface *fw, QWidget *widget)
+{
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(
+ fw->core()->extensionManager(), widget->parentWidget());
+
+ if (c != 0) {
+ for (int i = 0; i<c->count(); ++i) {
+ if (widget == c->widget(i))
+ return true;
+ }
+ }
+
+ return false;
+}
+void Layout::finishLayout(bool needMove, QLayout *layout)
+{
+ if (m_parentWidget == m_layoutBase) {
+ QWidget *widget = m_layoutBase;
+ m_oldGeometry = widget->geometry();
+
+ bool done = false;
+ while (!isMainContainer(m_formWindow, widget) && !done) {
+ if (!m_formWindow->isManaged(widget)) {
+ widget = widget->parentWidget();
+ continue;
+ } else if (LayoutInfo::isWidgetLaidout(m_formWindow->core(), widget)) {
+ widget = widget->parentWidget();
+ continue;
+ } else if (isPageOfContainerWidget(m_formWindow, widget)) {
+ widget = widget->parentWidget();
+ continue;
+ } else if (widget->parentWidget()) {
+ QScrollArea *area = qobject_cast<QScrollArea*>(widget->parentWidget()->parentWidget());
+ if (area && area->widget() == widget) {
+ widget = area;
+ continue;
+ }
+ }
+
+ done = true;
+ }
+ updateWizardLayout(m_layoutBase);
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ // We don't want to resize the form window
+ if (!Utils::isCentralWidget(m_formWindow, widget))
+ widget->adjustSize();
+
+ return;
+ }
+
+ if (needMove)
+ m_layoutBase->move(m_startPoint);
+
+ const QRect g(m_layoutBase->pos(), m_layoutBase->size());
+
+ if (LayoutInfo::layoutType(m_formWindow->core(), m_layoutBase->parentWidget()) == LayoutInfo::NoLayout && !m_isBreak)
+ m_layoutBase->adjustSize();
+ else if (m_isBreak)
+ m_layoutBase->setGeometry(m_oldGeometry);
+
+ m_oldGeometry = g;
+ if (layout)
+ layout->invalidate();
+ m_layoutBase->show();
+
+ if (qobject_cast<QLayoutWidget*>(m_layoutBase) || qobject_cast<QSplitter*>(m_layoutBase)) {
+ m_formWindow->clearSelection(false);
+ m_formWindow->manageWidget(m_layoutBase);
+ m_formWindow->selectWidget(m_layoutBase);
+ }
+}
+
+void Layout::undoLayout()
+{
+ if (!m_widgets.count())
+ return;
+
+ m_formWindow->selectWidget(m_layoutBase, false);
+
+ QDesignerWidgetFactoryInterface *widgetFactory = m_formWindow->core()->widgetFactory();
+ QHashIterator<QWidget *, QRect> it(m_geometries);
+ while (it.hasNext()) {
+ it.next();
+
+ if (!it.key())
+ continue;
+
+ QWidget* w = it.key();
+ const QRect rc = it.value();
+
+ const bool showIt = w->isVisibleTo(m_formWindow);
+ QWidget *container = widgetFactory->containerOfWidget(m_parentWidget);
+
+ // ### remove widget here
+ QWidget *parentWidget = w->parentWidget();
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), parentWidget);
+
+ if (deco)
+ deco->removeWidget(w);
+
+ w->setParent(container);
+ w->setGeometry(rc);
+
+ if (showIt)
+ w->show();
+ }
+
+ LayoutInfo::deleteLayout(m_formWindow->core(), m_layoutBase);
+
+ if (m_parentWidget != m_layoutBase && !qobject_cast<QMainWindow*>(m_layoutBase)) {
+ m_formWindow->unmanageWidget(m_layoutBase);
+ m_layoutBase->hide();
+ } else {
+ QMainWindow *mw = qobject_cast<QMainWindow*>(m_formWindow->mainContainer());
+ if (m_layoutBase != m_formWindow->mainContainer() &&
+ (!mw || mw->centralWidget() != m_layoutBase))
+ m_layoutBase->setGeometry(m_oldGeometry);
+ }
+}
+
+void Layout::breakLayout()
+{
+ typedef QMap<QWidget *, QRect> WidgetRectMap;
+ WidgetRectMap rects;
+ /* Store the geometry of the widgets. The idea is to give the user space
+ * to rearrange them, so, we do a adjustSize() on them, unless they want
+ * to grow (expanding widgets like QTextEdit), in which the geometry is
+ * preserved. Note that historically, geometries were re-applied
+ * only after breaking splitters. */
+ foreach (QWidget *w, m_widgets) {
+ const QRect geom = w->geometry();
+ const QSize sizeHint = w->sizeHint();
+ const bool restoreGeometry = sizeHint.isEmpty() || sizeHint.width() > geom.width() || sizeHint.height() > geom.height();
+ rects.insert(w, restoreGeometry ? w->geometry() : QRect(geom.topLeft(), QSize()));
+ }
+ const QPoint m_layoutBasePos = m_layoutBase->pos();
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_formWindow->core()->widgetDataBase();
+
+ LayoutInfo::deleteLayout(m_formWindow->core(), m_layoutBase);
+
+ const bool needReparent = (m_reparentLayoutWidget && qobject_cast<QLayoutWidget*>(m_layoutBase)) ||
+ qobject_cast<QSplitter*>(m_layoutBase) ||
+ (!widgetDataBase->isContainer(m_layoutBase, false) &&
+ m_layoutBase != m_formWindow->mainContainer());
+ const bool add = m_geometries.isEmpty();
+
+ QMapIterator<QWidget*, QRect> it(rects);
+ while (it.hasNext()) {
+ it.next();
+
+ QWidget *w = it.key();
+ if (needReparent) {
+ w->setParent(m_layoutBase->parentWidget(), 0);
+ w->move(m_layoutBasePos + it.value().topLeft());
+ w->show();
+ }
+
+ const QRect oldGeometry = it.value();
+ if (oldGeometry.isEmpty()) {
+ w->adjustSize();
+ } else {
+ w->resize(oldGeometry.size());
+ }
+
+ if (add)
+ m_geometries.insert(w, QRect(w->pos(), w->size()));
+ }
+
+ if (needReparent) {
+ m_layoutBase->hide();
+ m_parentWidget = m_layoutBase->parentWidget();
+ m_formWindow->unmanageWidget(m_layoutBase);
+ } else {
+ m_parentWidget = m_layoutBase;
+ }
+ updateWizardLayout(m_layoutBase);
+
+ if (!m_widgets.isEmpty() && m_widgets.first() && m_widgets.first()->isVisibleTo(m_formWindow))
+ m_formWindow->selectWidget(m_widgets.first());
+ else
+ m_formWindow->selectWidget(m_formWindow);
+}
+
+static QString suggestLayoutName(const char *className)
+{
+ // Legacy
+ if (!qstrcmp(className, "QHBoxLayout"))
+ return QLatin1String("horizontalLayout");
+ if (!qstrcmp(className, "QVBoxLayout"))
+ return QLatin1String("verticalLayout");
+ if (!qstrcmp(className, "QGridLayout"))
+ return QLatin1String("gridLayout");
+
+ return qtify(QString::fromUtf8(className));
+}
+QLayout *Layout::createLayout(int type)
+{
+ Q_ASSERT(m_layoutType != LayoutInfo::HSplitter && m_layoutType != LayoutInfo::VSplitter);
+ QLayout *layout = m_formWindow->core()->widgetFactory()->createLayout(m_layoutBase, 0, type);
+ // set a name
+ layout->setObjectName(suggestLayoutName(layout->metaObject()->className()));
+ m_formWindow->ensureUniqueObjectName(layout);
+ // QLayoutWidget
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_formWindow->core()->extensionManager(), layout);
+ if (sheet && qobject_cast<QLayoutWidget*>(m_layoutBase)) {
+ sheet->setProperty(sheet->indexOf(QLatin1String("leftMargin")), 0);
+ sheet->setProperty(sheet->indexOf(QLatin1String("topMargin")), 0);
+ sheet->setProperty(sheet->indexOf(QLatin1String("rightMargin")), 0);
+ sheet->setProperty(sheet->indexOf(QLatin1String("bottomMargin")), 0);
+ }
+ return layout;
+}
+
+void Layout::reparentToLayoutBase(QWidget *w)
+{
+ if (w->parent() != m_layoutBase) {
+ w->setParent(m_layoutBase, 0);
+ w->move(QPoint(0,0));
+ }
+}
+
+namespace { // within qdesigner_internal
+
+// ----- PositionSortPredicate: Predicate to be usable as LessThan function to sort widgets by position
+class PositionSortPredicate {
+public:
+ PositionSortPredicate(Qt::Orientation orientation) : m_orientation(orientation) {}
+ bool operator()(const QWidget* w1, const QWidget* w2) {
+ return m_orientation == Qt::Horizontal ? w1->x() < w2->x() : w1->y() < w2->y();
+ }
+ private:
+ const Qt::Orientation m_orientation;
+};
+
+// -------- BoxLayout
+class BoxLayout : public Layout
+{
+public:
+ BoxLayout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb,
+ Qt::Orientation orientation);
+
+ virtual void doLayout();
+ virtual void sort();
+
+private:
+ const Qt::Orientation m_orientation;
+};
+
+BoxLayout::BoxLayout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb,
+ Qt::Orientation orientation) :
+ Layout(wl, p, fw, lb, orientation == Qt::Horizontal ? LayoutInfo::HBox : LayoutInfo::VBox),
+ m_orientation(orientation)
+{
+}
+
+void BoxLayout::sort()
+{
+ QWidgetList wl = widgets();
+ qStableSort(wl.begin(), wl.end(), PositionSortPredicate(m_orientation));
+ setWidgets(wl);
+}
+
+void BoxLayout::doLayout()
+{
+ bool needMove, needReparent;
+ if (!prepareLayout(needMove, needReparent))
+ return;
+
+ QBoxLayout *layout = static_cast<QBoxLayout *>(createLayout(m_orientation == Qt::Horizontal ? LayoutInfo::HBox : LayoutInfo::VBox));
+
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+
+ const QWidgetList::const_iterator cend = widgets().constEnd();
+ for (QWidgetList::const_iterator it = widgets().constBegin(); it != cend; ++it) {
+ QWidget *w = *it;
+ if (needReparent)
+ reparentToLayoutBase(w);
+
+ if (const Spacer *spacer = qobject_cast<const Spacer*>(w))
+ layout->addWidget(w, 0, spacer->alignment());
+ else
+ layout->addWidget(w);
+ w->show();
+ }
+ finishLayout(needMove, layout);
+}
+
+// -------- SplitterLayout
+class SplitterLayout : public Layout
+{
+public:
+ SplitterLayout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb,
+ Qt::Orientation orientation);
+
+ virtual void doLayout();
+ virtual void sort();
+
+private:
+ const Qt::Orientation m_orientation;
+};
+
+SplitterLayout::SplitterLayout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb,
+ Qt::Orientation orientation) :
+ Layout(wl, p, fw, lb, orientation == Qt::Horizontal ? LayoutInfo::HSplitter : LayoutInfo::VSplitter),
+ m_orientation(orientation)
+{
+}
+
+void SplitterLayout::sort()
+{
+ QWidgetList wl = widgets();
+ qStableSort(wl.begin(), wl.end(), PositionSortPredicate(m_orientation));
+ setWidgets(wl);
+}
+
+void SplitterLayout::doLayout()
+{
+ bool needMove, needReparent;
+ if (!prepareLayout(needMove, needReparent))
+ return;
+
+ QSplitter *splitter = qobject_cast<QSplitter*>(layoutBaseWidget());
+ Q_ASSERT(splitter != 0);
+
+
+ const QWidgetList::const_iterator cend = widgets().constEnd();
+ for (QWidgetList::const_iterator it = widgets().constBegin(); it != cend; ++it) {
+ QWidget *w = *it;
+ if (needReparent)
+ reparentToLayoutBase(w);
+ splitter->addWidget(w);
+ w->show();
+ }
+
+ splitter->setOrientation(m_orientation);
+ finishLayout(needMove);
+}
+
+// ---------- Grid: Helper for laying out grids
+
+class Grid
+{
+public:
+ enum Mode {
+ GridLayout, // Arbitrary size/supports span
+ FormLayout // 2-column/no span
+ };
+
+ Grid(Mode mode);
+ void resize(int nrows, int ncols);
+
+ ~Grid();
+
+ QWidget* cell(int row, int col) const { return m_cells[ row * m_ncols + col]; }
+
+ void setCells(const QRect &c, QWidget* w);
+
+ bool empty() const { return m_nrows * m_ncols; }
+ int numRows() const { return m_nrows; }
+ int numCols() const { return m_ncols; }
+
+ void simplify();
+ bool locateWidget(QWidget* w, int& row, int& col, int& rowspan, int& colspan) const;
+
+ QDebug debug(QDebug str) const;
+
+private:
+ void setCell(int row, int col, QWidget* w) { m_cells[ row * m_ncols + col] = w; }
+ void swapCells(int r1, int c1, int r2, int c2);
+ void shrink();
+ void reallocFormLayout();
+ int countRow(int r, int c) const;
+ int countCol(int r, int c) const;
+ void setRow(int r, int c, QWidget* w, int count);
+ void setCol(int r, int c, QWidget* w, int count);
+ bool isWidgetStartCol(int c) const;
+ bool isWidgetEndCol(int c) const;
+ bool isWidgetStartRow(int r) const;
+ bool isWidgetEndRow(int r) const;
+ bool isWidgetTopLeft(int r, int c) const;
+ void extendLeft();
+ void extendRight();
+ void extendUp();
+ void extendDown();
+ bool shrinkFormLayoutSpans();
+
+ const Mode m_mode;
+ int m_nrows;
+ int m_ncols;
+
+ QWidget** m_cells; // widget matrix w11, w12, w21...
+};
+
+Grid::Grid(Mode mode) :
+ m_mode(mode),
+ m_nrows(0),
+ m_ncols(0),
+ m_cells(0)
+{
+}
+
+Grid::~Grid()
+{
+ delete [] m_cells;
+}
+
+void Grid::resize(int nrows, int ncols)
+{
+ delete [] m_cells;
+ m_cells = 0;
+ m_nrows = nrows;
+ m_ncols = ncols;
+ if (const int allocSize = m_nrows * m_ncols) {
+ m_cells = new QWidget*[allocSize];
+ qFill(m_cells, m_cells + allocSize, static_cast<QWidget *>(0));
+ }
+}
+
+QDebug Grid::debug(QDebug str) const
+{
+ str << m_nrows << 'x' << m_ncols << '\n';
+ QSet<QWidget *> widgets;
+ const int cellCount = m_nrows * m_ncols;
+ int row, col, rowspan, colspan;
+ for (int c = 0; c < cellCount; c++)
+ if (QWidget *w = m_cells[c])
+ if (!widgets.contains(w)) {
+ widgets.insert(w);
+ locateWidget(w, row, col, rowspan, colspan);
+ str << w << " at " << row << col << rowspan << 'x' << colspan << '\n';
+ }
+ for (int r = 0; r < m_nrows; r++)
+ for (int c = 0; c < m_ncols; c++)
+ str << "At " << r << c << cell(r, c) << '\n';
+
+ return str;
+}
+
+static inline QDebug operator<<(QDebug str, const Grid &g) { return g.debug(str); }
+
+void Grid::setCells(const QRect &c, QWidget* w)
+{
+ const int bottom = c.top() + c.height();
+ const int width = c.width();
+
+ for (int r = c.top(); r < bottom; r++) {
+ QWidget **pos = m_cells + r * m_ncols + c.left();
+ qFill(pos, pos + width, w);
+ }
+}
+
+
+void Grid::swapCells(int r1, int c1, int r2, int c2)
+{
+ QWidget *w1 = cell(r1, c1);
+ setCell(r1, c1, cell(r2, c2));
+ setCell(r2, c2, w1);
+}
+
+int Grid::countRow(int r, int c) const
+{
+ QWidget* w = cell(r, c);
+ int i = c + 1;
+ while (i < m_ncols && cell(r, i) == w)
+ i++;
+ return i - c;
+}
+
+int Grid::countCol(int r, int c) const
+{
+ QWidget* w = cell(r, c);
+ int i = r + 1;
+ while (i < m_nrows && cell(i, c) == w)
+ i++;
+ return i - r;
+}
+
+void Grid::setCol(int r, int c, QWidget* w, int count)
+{
+ for (int i = 0; i < count; i++)
+ setCell(r + i, c, w);
+}
+
+void Grid::setRow(int r, int c, QWidget* w, int count)
+{
+ for (int i = 0; i < count; i++)
+ setCell(r, c + i, w);
+}
+
+bool Grid::isWidgetStartCol(int c) const
+{
+ for (int r = 0; r < m_nrows; r++) {
+ if (cell(r, c) && ((c==0) || (cell(r, c) != cell(r, c-1)))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Grid::isWidgetEndCol(int c) const
+{
+ for (int r = 0; r < m_nrows; r++) {
+ if (cell(r, c) && ((c == m_ncols-1) || (cell(r, c) != cell(r, c+1))))
+ return true;
+ }
+ return false;
+}
+
+bool Grid::isWidgetStartRow(int r) const
+{
+ for ( int c = 0; c < m_ncols; c++) {
+ if (cell(r, c) && ((r==0) || (cell(r, c) != cell(r-1, c))))
+ return true;
+ }
+ return false;
+}
+
+bool Grid::isWidgetEndRow(int r) const
+{
+ for (int c = 0; c < m_ncols; c++) {
+ if (cell(r, c) && ((r == m_nrows-1) || (cell(r, c) != cell(r+1, c))))
+ return true;
+ }
+ return false;
+}
+
+
+bool Grid::isWidgetTopLeft(int r, int c) const
+{
+ QWidget* w = cell(r, c);
+ if (!w)
+ return false;
+ return (!r || cell(r-1, c) != w) && (!c || cell(r, c-1) != w);
+}
+
+void Grid::extendLeft()
+{
+ for (int c = 1; c < m_ncols; c++) {
+ for (int r = 0; r < m_nrows; r++) {
+ QWidget* w = cell(r, c);
+ if (!w)
+ continue;
+
+ const int cc = countCol(r, c);
+ int stretch = 0;
+ for (int i = c-1; i >= 0; i--) {
+ if (cell(r, i))
+ break;
+ if (countCol(r, i) < cc)
+ break;
+ if (isWidgetEndCol(i))
+ break;
+ if (isWidgetStartCol(i)) {
+ stretch = c - i;
+ break;
+ }
+ }
+ if (stretch) {
+ for (int i = 0; i < stretch; i++)
+ setCol(r, c-i-1, w, cc);
+ }
+ }
+ }
+}
+
+
+void Grid::extendRight()
+{
+ for (int c = m_ncols - 2; c >= 0; c--) {
+ for (int r = 0; r < m_nrows; r++) {
+ QWidget* w = cell(r, c);
+ if (!w)
+ continue;
+ const int cc = countCol(r, c);
+ int stretch = 0;
+ for (int i = c+1; i < m_ncols; i++) {
+ if (cell(r, i))
+ break;
+ if (countCol(r, i) < cc)
+ break;
+ if (isWidgetStartCol(i))
+ break;
+ if (isWidgetEndCol(i)) {
+ stretch = i - c;
+ break;
+ }
+ }
+ if (stretch) {
+ for (int i = 0; i < stretch; i++)
+ setCol(r, c+i+1, w, cc);
+ }
+ }
+ }
+
+}
+
+void Grid::extendUp()
+{
+ for (int r = 1; r < m_nrows; r++) {
+ for (int c = 0; c < m_ncols; c++) {
+ QWidget* w = cell(r, c);
+ if (!w)
+ continue;
+ const int cr = countRow(r, c);
+ int stretch = 0;
+ for (int i = r-1; i >= 0; i--) {
+ if (cell(i, c))
+ break;
+ if (countRow(i, c) < cr)
+ break;
+ if (isWidgetEndRow(i))
+ break;
+ if (isWidgetStartRow(i)) {
+ stretch = r - i;
+ break;
+ }
+ }
+ if (stretch) {
+ for (int i = 0; i < stretch; i++)
+ setRow(r-i-1, c, w, cr);
+ }
+ }
+ }
+}
+
+void Grid::extendDown()
+{
+ for (int r = m_nrows - 2; r >= 0; r--) {
+ for (int c = 0; c < m_ncols; c++) {
+ QWidget* w = cell(r, c);
+ if (!w)
+ continue;
+ const int cr = countRow(r, c);
+ int stretch = 0;
+ for (int i = r+1; i < m_nrows; i++) {
+ if (cell(i, c))
+ break;
+ if (countRow(i, c) < cr)
+ break;
+ if (isWidgetStartRow(i))
+ break;
+ if (isWidgetEndRow(i)) {
+ stretch = i - r;
+ break;
+ }
+ }
+ if (stretch) {
+ for (int i = 0; i < stretch; i++)
+ setRow(r+i+1, c, w, cr);
+ }
+ }
+ }
+}
+
+void Grid::simplify()
+{
+ switch (m_mode) {
+ case GridLayout:
+ // Grid: Extend all widgets to occupy most space and delete
+ // rows/columns that are not bordering on a widget
+ extendLeft();
+ extendRight();
+ extendUp();
+ extendDown();
+ shrink();
+ break;
+ case FormLayout:
+ // Form: First treat it as a grid to get the same behaviour
+ // regarding spanning and shrinking. Then restrict the span to
+ // the horizontal span possible in the form, simplify again
+ // and spread the widgets over a 2-column layout
+ extendLeft();
+ extendRight();
+ extendUp();
+ extendDown();
+ shrink();
+ if (shrinkFormLayoutSpans())
+ shrink();
+ reallocFormLayout();
+ break;
+ }
+
+}
+
+void Grid::shrink()
+{
+ // tick off the occupied cols/rows (bordering on widget edges)
+ QVector<bool> columns(m_ncols, false);
+ QVector<bool> rows(m_nrows, false);
+
+ for (int c = 0; c < m_ncols; c++)
+ for (int r = 0; r < m_nrows; r++)
+ if (isWidgetTopLeft(r, c))
+ rows[r] = columns[c] = true;
+
+ // remove empty cols/rows
+ const int simplifiedNCols = columns.count(true);
+ const int simplifiedNRows = rows.count(true);
+ if (simplifiedNCols == m_ncols && simplifiedNRows == m_nrows)
+ return;
+ // reallocate and copy omitting the empty cells
+ QWidget **simplifiedCells = new QWidget*[simplifiedNCols * simplifiedNRows];
+ qFill(simplifiedCells, simplifiedCells + simplifiedNCols * simplifiedNRows, static_cast<QWidget *>(0));
+ QWidget **simplifiedPtr = simplifiedCells;
+
+ for (int r = 0; r < m_nrows; r++)
+ if (rows[r])
+ for (int c = 0; c < m_ncols; c++)
+ if (columns[c]) {
+ if (QWidget *w = cell(r, c))
+ *simplifiedPtr = w;
+ simplifiedPtr++;
+ }
+ Q_ASSERT(simplifiedPtr == simplifiedCells + simplifiedNCols * simplifiedNRows);
+ delete [] m_cells;
+ m_cells = simplifiedCells;
+ m_nrows = simplifiedNRows;
+ m_ncols = simplifiedNCols;
+}
+
+bool Grid::shrinkFormLayoutSpans()
+{
+ bool shrunk = false;
+ typedef QSet<QWidget*> WidgetSet;
+ // Determine unique set of widgets
+ WidgetSet widgets;
+ QWidget **end = m_cells + m_ncols * m_nrows;
+ for (QWidget **wptr = m_cells; wptr < end; wptr++)
+ if (QWidget *w = *wptr)
+ widgets.insert(w);
+ // Restrict the widget span: max horizontal span at column 0: 2, anything else: 1
+ const int maxRowSpan = 1;
+ const WidgetSet::const_iterator cend = widgets.constEnd();
+ for (WidgetSet::const_iterator it = widgets.constBegin(); it != cend ; ++it) {
+ QWidget *w = *it;
+ int row, col, rowspan, colspan;
+ if (!locateWidget(w, row, col, rowspan, colspan))
+ qDebug("ooops, widget '%s' does not fit in layout", w->objectName().toUtf8().constData());
+ const int maxColSpan = col == 0 ? 2 : 1;
+ const int newColSpan = qMin(colspan, maxColSpan);
+ const int newRowSpan = qMin(rowspan, maxRowSpan);
+ if (newColSpan != colspan || newRowSpan != rowspan) {
+ // in case like this:
+ // W1 W1
+ // W1 W2
+ // do:
+ // W1 0
+ // 0 W2
+ for (int i = row; i < row + rowspan - 1; i++)
+ for (int j = col; j < col + colspan - 1; j++)
+ if (i > row + newColSpan - 1 || j > col + newRowSpan - 1)
+ if (cell(i, j) == w)
+ setCell(i, j, 0);
+ shrunk = true;
+ }
+ }
+ return shrunk;
+}
+
+void Grid::reallocFormLayout()
+{
+ // Columns matching? -> happy!
+ if (m_ncols == FormLayoutColumns)
+ return;
+
+ // If there are offset columns (starting past the field column),
+ // move them to the left and squeeze them. This also prevents the
+ // following reallocation from creating empty form rows.
+ int pastRightWidgetCount = 0;
+ if (m_ncols > FormLayoutColumns) {
+ for (int r = 0; r < m_nrows; r++) {
+ // Try to find a column where the form columns are empty and
+ // there are widgets further to the right.
+ if (cell(r, 0) == 0 && cell(r, 1) == 0) {
+ int sourceCol = FormLayoutColumns;
+ QWidget *firstWidget = 0;
+ for ( ; sourceCol < m_ncols; sourceCol++)
+ if (QWidget *w = cell(r, sourceCol)) {
+ firstWidget = w;
+ break;
+ }
+ if (firstWidget) {
+ // Move/squeeze. Copy to beginning of column if it is a label, else field
+ int targetCol = qobject_cast<QLabel*>(firstWidget) ? 0 : 1;
+ for ( ; sourceCol < m_ncols; sourceCol++)
+ if (QWidget *w = cell(r, sourceCol))
+ setCell(r, targetCol++, w);
+ // Pad with zero
+ for ( ; targetCol < m_ncols; targetCol++)
+ setCell(r, targetCol, 0);
+ }
+ }
+ // Any protruding widgets left on that row?
+ for (int c = FormLayoutColumns; c < m_ncols; c++)
+ if (cell(r, c))
+ pastRightWidgetCount++;
+ }
+ }
+ // Reallocate with 2 columns. Just insert the protruding ones as fields.
+ const int formNRows = m_nrows + pastRightWidgetCount;
+ QWidget **formCells = new QWidget*[FormLayoutColumns * formNRows];
+ qFill(formCells, formCells + FormLayoutColumns * formNRows, static_cast<QWidget *>(0));
+ QWidget **formPtr = formCells;
+ const int matchingColumns = qMin(m_ncols, static_cast<int>(FormLayoutColumns));
+ for (int r = 0; r < m_nrows; r++) {
+ int c = 0;
+ for ( ; c < matchingColumns; c++) // Just copy over matching columns
+ *formPtr++ = cell(r, c);
+ formPtr += FormLayoutColumns - matchingColumns; // In case old format was 1 column
+ // protruding widgets: Insert as single-field rows
+ for ( ; c < m_ncols; c++)
+ if (QWidget *w = cell(r, c)) {
+ formPtr++;
+ *formPtr++ = w;
+ }
+ }
+ Q_ASSERT(formPtr == formCells + FormLayoutColumns * formNRows);
+ delete [] m_cells;
+ m_cells = formCells;
+ m_nrows = formNRows;
+ m_ncols = FormLayoutColumns;
+}
+
+bool Grid::locateWidget(QWidget *w, int &row, int &col, int &rowspan, int &colspan) const
+{
+ const int end = m_nrows * m_ncols;
+ const int startIndex = qFind(m_cells, m_cells + end, w) - m_cells;
+ if (startIndex == end)
+ return false;
+
+ row = startIndex / m_ncols;
+ col = startIndex % m_ncols;
+ for (rowspan = 1; row + rowspan < m_nrows && cell(row + rowspan, col) == w; rowspan++) {}
+ for (colspan = 1; col + colspan < m_ncols && cell(row, col + colspan) == w; colspan++) {}
+ return true;
+}
+
+// QGridLayout/QFormLayout Helpers: get item position/add item (overloads to make templates work)
+
+void getGridItemPosition(QGridLayout *gridLayout, int index, int *row, int *column, int *rowspan, int *colspan)
+{
+ gridLayout->getItemPosition(index, row, column, rowspan, colspan);
+}
+
+void addWidgetToGrid(QGridLayout *lt, QWidget * widget, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment)
+{
+ lt->addWidget(widget, row, column, rowSpan, columnSpan, alignment);
+}
+
+inline void getGridItemPosition(QFormLayout *formLayout, int index, int *row, int *column, int *rowspan, int *colspan)
+{
+ getFormLayoutItemPosition(formLayout, index, row, column, rowspan, colspan);
+}
+
+inline void addWidgetToGrid(QFormLayout *lt, QWidget * widget, int row, int column, int, int columnSpan, Qt::Alignment)
+{
+ formLayoutAddWidget(lt, widget, QRect(column, row, columnSpan, 1), false);
+}
+
+// ----------- Base template for grid like layouts
+template <class GridLikeLayout, int LayoutType, int GridMode>
+class GridLayout : public Layout
+{
+public:
+ GridLayout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb);
+
+ virtual void doLayout();
+ virtual void sort() { setWidgets(buildGrid(widgets())); }
+
+protected:
+ QWidget *widgetAt(GridLikeLayout *layout, int row, int column) const;
+
+protected:
+ QWidgetList buildGrid(const QWidgetList &);
+ Grid m_grid;
+};
+
+template <class GridLikeLayout, int LayoutType, int GridMode>
+GridLayout<GridLikeLayout, LayoutType, GridMode>::GridLayout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb) :
+ Layout(wl, p, fw, lb, LayoutInfo::Grid),
+ m_grid(static_cast<Grid::Mode>(GridMode))
+{
+}
+
+template <class GridLikeLayout, int LayoutType, int GridMode>
+QWidget *GridLayout<GridLikeLayout, LayoutType, GridMode>::widgetAt(GridLikeLayout *layout, int row, int column) const
+{
+ int index = 0;
+ while (QLayoutItem *item = layout->itemAt(index)) {
+ if (item->widget()) {
+ int r, c, rowspan, colspan;
+ getGridItemPosition(layout, index, &r, &c, &rowspan, &colspan);
+ if (row == r && column == c)
+ return item->widget();
+ }
+ ++index;
+ }
+ return 0;
+}
+
+template <class GridLikeLayout, int LayoutType, int GridMode>
+void GridLayout<GridLikeLayout, LayoutType, GridMode>::doLayout()
+{
+ bool needMove, needReparent;
+ if (!prepareLayout(needMove, needReparent))
+ return;
+
+ GridLikeLayout *layout = static_cast<GridLikeLayout *>(createLayout(LayoutType));
+
+ if (m_grid.empty())
+ sort();
+
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+
+ const QWidgetList::const_iterator cend = widgets().constEnd();
+ for (QWidgetList::const_iterator it = widgets().constBegin(); it != cend; ++it) {
+ QWidget *w = *it;
+ int r = 0, c = 0, rs = 0, cs = 0;
+
+ if (m_grid.locateWidget(w, r, c, rs, cs)) {
+ if (needReparent)
+ reparentToLayoutBase(w);
+
+ Qt::Alignment alignment = Qt::Alignment(0);
+ if (const Spacer *spacer = qobject_cast<const Spacer*>(w))
+ alignment = spacer->alignment();
+
+ addWidgetToGrid(layout, w, r, c, rs, cs, alignment);
+
+ w->show();
+ } else {
+ qDebug("ooops, widget '%s' does not fit in layout", w->objectName().toUtf8().constData());
+ }
+ }
+
+ QLayoutSupport::createEmptyCells(layout);
+
+ finishLayout(needMove, layout);
+}
+
+// Remove duplicate entries (Remove next, if equal to current)
+void removeIntVecDuplicates(QVector<int> &v)
+{
+ if (v.size() < 2)
+ return;
+
+ for (QVector<int>::iterator current = v.begin() ; (current != v.end()) && ((current+1) != v.end()) ; )
+ if ( (*current == *(current+1)) )
+ v.erase(current+1);
+ else
+ ++current;
+}
+
+// Ensure a non-zero size for a widget geometry (squeezed spacers)
+inline QRect expandGeometry(const QRect &rect)
+{
+ return rect.isEmpty() ? QRect(rect.topLeft(), rect.size().expandedTo(QSize(1, 1))) : rect;
+}
+
+template <class GridLikeLayout, int LayoutType, int GridMode>
+QWidgetList GridLayout<GridLikeLayout, LayoutType, GridMode>::buildGrid(const QWidgetList &widgetList)
+{
+ if (widgetList.empty())
+ return QWidgetList();
+
+ // Pixel to cell conversion:
+ // By keeping a list of start'n'stop values (x & y) for each widget,
+ // it is possible to create a very small grid of cells to represent
+ // the widget layout.
+ // -----------------------------------------------------------------
+
+ // We need a list of both start and stop values for x- & y-axis
+ const int widgetCount = widgetList.size();
+ QVector<int> x( widgetCount * 2 );
+ QVector<int> y( widgetCount * 2 );
+
+ // Using push_back would look nicer, but operator[] is much faster
+ int index = 0;
+ for (int i = 0; i < widgetCount; ++i) {
+ const QRect widgetPos = expandGeometry(widgetList.at(i)->geometry());
+ x[index] = widgetPos.left();
+ x[index+1] = widgetPos.right();
+ y[index] = widgetPos.top();
+ y[index+1] = widgetPos.bottom();
+ index += 2;
+ }
+
+ qSort(x);
+ qSort(y);
+
+ // Remove duplicate x entries (Remove next, if equal to current)
+ removeIntVecDuplicates(x);
+ removeIntVecDuplicates(y);
+
+ // Note that left == right and top == bottom for size 1 items; reserve
+ // enough space
+ m_grid.resize(y.size(), x.size());
+
+ const QWidgetList::const_iterator cend = widgetList.constEnd();
+ for (QWidgetList::const_iterator it = widgetList.constBegin(); it != cend; ++it) {
+ QWidget *w = *it;
+ // Mark the cells in the grid that contains a widget
+ const QRect widgetPos = expandGeometry(w->geometry());
+ QRect c(0, 0, 0, 0); // rect of columns/rows
+
+ // From left til right (not including)
+ const int leftIdx = x.indexOf(widgetPos.left());
+ Q_ASSERT(leftIdx != -1);
+ c.setLeft(leftIdx);
+ c.setRight(leftIdx);
+ for (int cw=leftIdx; cw<x.size(); cw++)
+ if (x[cw] < widgetPos.right())
+ c.setRight(cw);
+ else
+ break;
+ // From top til bottom (not including)
+ const int topIdx = y.indexOf(widgetPos.top());
+ Q_ASSERT(topIdx != -1);
+ c.setTop(topIdx);
+ c.setBottom(topIdx);
+ for (int ch=topIdx; ch<y.size(); ch++)
+ if (y[ch] < widgetPos.bottom())
+ c.setBottom(ch);
+ else
+ break;
+ m_grid.setCells(c, w); // Mark cellblock
+ }
+
+ m_grid.simplify();
+
+ QWidgetList ordered;
+ for (int i = 0; i < m_grid.numRows(); i++)
+ for (int j = 0; j < m_grid.numCols(); j++) {
+ QWidget *w = m_grid.cell(i, j);
+ if (w && !ordered.contains(w))
+ ordered.append(w);
+ }
+ return ordered;
+}
+} // anonymous
+
+Layout* Layout::createLayout(const QWidgetList &widgets, QWidget *parentWidget,
+ QDesignerFormWindowInterface *fw,
+ QWidget *layoutBase, LayoutInfo::Type layoutType)
+{
+ switch (layoutType) {
+ case LayoutInfo::Grid:
+ return new GridLayout<QGridLayout, LayoutInfo::Grid, Grid::GridLayout>(widgets, parentWidget, fw, layoutBase);
+ case LayoutInfo::HBox:
+ case LayoutInfo::VBox: {
+ const Qt::Orientation orientation = layoutType == LayoutInfo::HBox ? Qt::Horizontal : Qt::Vertical;
+ return new BoxLayout(widgets, parentWidget, fw, layoutBase, orientation);
+ }
+ case LayoutInfo::HSplitter:
+ case LayoutInfo::VSplitter: {
+ const Qt::Orientation orientation = layoutType == LayoutInfo::HSplitter ? Qt::Horizontal : Qt::Vertical;
+ return new SplitterLayout(widgets, parentWidget, fw, layoutBase, orientation);
+ }
+ case LayoutInfo::Form:
+ return new GridLayout<QFormLayout, LayoutInfo::Form, Grid::FormLayout>(widgets, parentWidget, fw, layoutBase);
+ default:
+ break;
+ }
+ Q_ASSERT(0);
+ return 0;
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/layout_p.h b/src/designer/src/lib/shared/layout_p.h
new file mode 100644
index 000000000..f901b63b9
--- /dev/null
+++ b/src/designer/src/lib/shared/layout_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef LAYOUT_H
+#define LAYOUT_H
+
+#include "shared_global_p.h"
+#include "layoutinfo_p.h"
+
+#include <QtCore/QPointer>
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtCore/QHash>
+
+#include <QtGui/QLayout>
+#include <QtGui/QGridLayout>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+class QDESIGNER_SHARED_EXPORT Layout : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(Layout)
+protected:
+ Layout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb, LayoutInfo::Type layoutType);
+
+public:
+ static Layout* createLayout(const QWidgetList &widgets, QWidget *parentWidget,
+ QDesignerFormWindowInterface *fw,
+ QWidget *layoutBase, LayoutInfo::Type layoutType);
+
+ virtual ~Layout();
+
+ virtual void sort() = 0;
+ virtual void doLayout() = 0;
+
+ virtual void setup();
+ virtual void undoLayout();
+ virtual void breakLayout();
+
+ const QWidgetList &widgets() const { return m_widgets; }
+ QWidget *parentWidget() const { return m_parentWidget; }
+ QWidget *layoutBaseWidget() const { return m_layoutBase; }
+
+ /* Determines whether instances of QLayoutWidget are unmanaged/hidden
+ * after breaking a layout. Default is true. Can be turned off when
+ * morphing */
+ bool reparentLayoutWidget() const { return m_reparentLayoutWidget; }
+ void setReparentLayoutWidget(bool v) { m_reparentLayoutWidget = v; }
+
+protected:
+ virtual void finishLayout(bool needMove, QLayout *layout = 0);
+ virtual bool prepareLayout(bool &needMove, bool &needReparent);
+
+ void setWidgets(const QWidgetList &widgets) { m_widgets = widgets; }
+ QLayout *createLayout(int type);
+ void reparentToLayoutBase(QWidget *w);
+
+private slots:
+ void widgetDestroyed();
+
+private:
+ QWidgetList m_widgets;
+ QWidget *m_parentWidget;
+ typedef QHash<QWidget *, QRect> WidgetGeometryHash;
+ WidgetGeometryHash m_geometries;
+ QWidget *m_layoutBase;
+ QDesignerFormWindowInterface *m_formWindow;
+ const LayoutInfo::Type m_layoutType;
+ QPoint m_startPoint;
+ QRect m_oldGeometry;
+
+ bool m_reparentLayoutWidget;
+ const bool m_isBreak;
+};
+
+namespace Utils
+{
+
+inline int indexOfWidget(QLayout *layout, QWidget *widget)
+{
+ int index = 0;
+ while (QLayoutItem *item = layout->itemAt(index)) {
+ if (item->widget() == widget)
+ return index;
+
+ ++index;
+ }
+
+ return -1;
+}
+
+} // namespace Utils
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LAYOUT_H
diff --git a/src/designer/src/lib/shared/layoutinfo.cpp b/src/designer/src/lib/shared/layoutinfo.cpp
new file mode 100644
index 000000000..804d069c5
--- /dev/null
+++ b/src/designer/src/lib/shared/layoutinfo.cpp
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "layoutinfo_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QSplitter>
+#include <QtCore/QDebug>
+#include <QtCore/QHash>
+#include <QtCore/QRect>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+/*!
+ \overload
+*/
+LayoutInfo::Type LayoutInfo::layoutType(const QDesignerFormEditorInterface *core, const QLayout *layout)
+{
+ Q_UNUSED(core)
+ if (!layout)
+ return NoLayout;
+ else if (qobject_cast<const QHBoxLayout*>(layout))
+ return HBox;
+ else if (qobject_cast<const QVBoxLayout*>(layout))
+ return VBox;
+ else if (qobject_cast<const QGridLayout*>(layout))
+ return Grid;
+ else if (qobject_cast<const QFormLayout*>(layout))
+ return Form;
+ return UnknownLayout;
+}
+
+static const QHash<QString, LayoutInfo::Type> &layoutNameTypeMap()
+{
+ static QHash<QString, LayoutInfo::Type> nameTypeMap;
+ if (nameTypeMap.empty()) {
+ nameTypeMap.insert(QLatin1String("QVBoxLayout"), LayoutInfo::VBox);
+ nameTypeMap.insert(QLatin1String("QHBoxLayout"), LayoutInfo::HBox);
+ nameTypeMap.insert(QLatin1String("QGridLayout"), LayoutInfo::Grid);
+ nameTypeMap.insert(QLatin1String("QFormLayout"), LayoutInfo::Form);
+ }
+ return nameTypeMap;
+}
+
+LayoutInfo::Type LayoutInfo::layoutType(const QString &typeName)
+{
+ return layoutNameTypeMap().value(typeName, NoLayout);
+}
+
+QString LayoutInfo::layoutName(Type t)
+{
+ return layoutNameTypeMap().key(t);
+}
+
+/*!
+ \overload
+*/
+LayoutInfo::Type LayoutInfo::layoutType(const QDesignerFormEditorInterface *core, const QWidget *w)
+{
+ if (const QSplitter *splitter = qobject_cast<const QSplitter *>(w))
+ return splitter->orientation() == Qt::Horizontal ? HSplitter : VSplitter;
+ return layoutType(core, w->layout());
+}
+
+LayoutInfo::Type LayoutInfo::managedLayoutType(const QDesignerFormEditorInterface *core,
+ const QWidget *w,
+ QLayout **ptrToLayout)
+{
+ if (ptrToLayout)
+ *ptrToLayout = 0;
+ if (const QSplitter *splitter = qobject_cast<const QSplitter *>(w))
+ return splitter->orientation() == Qt::Horizontal ? HSplitter : VSplitter;
+ QLayout *layout = managedLayout(core, w);
+ if (!layout)
+ return NoLayout;
+ if (ptrToLayout)
+ *ptrToLayout = layout;
+ return layoutType(core, layout);
+}
+
+QWidget *LayoutInfo::layoutParent(const QDesignerFormEditorInterface *core, QLayout *layout)
+{
+ Q_UNUSED(core)
+
+ QObject *o = layout;
+ while (o) {
+ if (QWidget *widget = qobject_cast<QWidget*>(o))
+ return widget;
+
+ o = o->parent();
+ }
+ return 0;
+}
+
+void LayoutInfo::deleteLayout(const QDesignerFormEditorInterface *core, QWidget *widget)
+{
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), widget))
+ widget = container->widget(container->currentIndex());
+
+ Q_ASSERT(widget != 0);
+
+ QLayout *layout = managedLayout(core, widget);
+
+ if (layout == 0 || core->metaDataBase()->item(layout) != 0) {
+ delete layout;
+ widget->updateGeometry();
+ return;
+ }
+
+ qDebug() << "trying to delete an unmanaged layout:" << "widget:" << widget << "layout:" << layout;
+}
+
+LayoutInfo::Type LayoutInfo::laidoutWidgetType(const QDesignerFormEditorInterface *core,
+ QWidget *widget,
+ bool *isManaged,
+ QLayout **ptrToLayout)
+{
+ if (isManaged)
+ *isManaged = false;
+ if (ptrToLayout)
+ *ptrToLayout = 0;
+
+ QWidget *parent = widget->parentWidget();
+ if (!parent)
+ return NoLayout;
+
+ // 1) Splitter
+ if (QSplitter *splitter = qobject_cast<QSplitter*>(parent)) {
+ if (isManaged)
+ *isManaged = core->metaDataBase()->item(splitter);
+ return splitter->orientation() == Qt::Horizontal ? HSplitter : VSplitter;
+ }
+
+ // 2) Layout of parent
+ QLayout *parentLayout = parent->layout();
+ if (!parentLayout)
+ return NoLayout;
+
+ if (parentLayout->indexOf(widget) != -1) {
+ if (isManaged)
+ *isManaged = core->metaDataBase()->item(parentLayout);
+ if (ptrToLayout)
+ *ptrToLayout = parentLayout;
+ return layoutType(core, parentLayout);
+ }
+
+ // 3) Some child layout (see below comment about Q3GroupBox)
+ const QList<QLayout*> childLayouts = parentLayout->findChildren<QLayout*>();
+ if (childLayouts.empty())
+ return NoLayout;
+ const QList<QLayout*>::const_iterator lcend = childLayouts.constEnd();
+ for (QList<QLayout*>::const_iterator it = childLayouts.constBegin(); it != lcend; ++it) {
+ QLayout *layout = *it;
+ if (layout->indexOf(widget) != -1) {
+ if (isManaged)
+ *isManaged = core->metaDataBase()->item(layout);
+ if (ptrToLayout)
+ *ptrToLayout = layout;
+ return layoutType(core, layout);
+ }
+ }
+
+ return NoLayout;
+}
+
+QLayout *LayoutInfo::internalLayout(const QWidget *widget)
+{
+ QLayout *widgetLayout = widget->layout();
+ if (widgetLayout && widget->inherits("Q3GroupBox")) {
+ if (widgetLayout->count()) {
+ widgetLayout = widgetLayout->itemAt(0)->layout();
+ } else {
+ widgetLayout = 0;
+ }
+ }
+ return widgetLayout;
+}
+
+
+QLayout *LayoutInfo::managedLayout(const QDesignerFormEditorInterface *core, const QWidget *widget)
+{
+ if (widget == 0)
+ return 0;
+
+ QLayout *layout = widget->layout();
+ if (!layout)
+ return 0;
+
+ return managedLayout(core, layout);
+}
+
+QLayout *LayoutInfo::managedLayout(const QDesignerFormEditorInterface *core, QLayout *layout)
+{
+ QDesignerMetaDataBaseInterface *metaDataBase = core->metaDataBase();
+
+ if (!metaDataBase)
+ return layout;
+ /* This code exists mainly for the Q3GroupBox class, for which
+ * widget->layout() returns an internal VBoxLayout. */
+ const QDesignerMetaDataBaseItemInterface *item = metaDataBase->item(layout);
+ if (item == 0) {
+ layout = layout->findChild<QLayout*>();
+ item = metaDataBase->item(layout);
+ }
+ if (!item)
+ return 0;
+ return layout;
+}
+
+// Is it a a dummy grid placeholder created by Designer?
+bool LayoutInfo::isEmptyItem(QLayoutItem *item)
+{
+ if (item == 0) {
+ qDebug() << "** WARNING Zero-item passed on to isEmptyItem(). This indicates a layout inconsistency.";
+ return true;
+ }
+ return item->spacerItem() != 0;
+}
+
+QDESIGNER_SHARED_EXPORT void getFormLayoutItemPosition(const QFormLayout *formLayout, int index, int *rowPtr, int *columnPtr, int *rowspanPtr, int *colspanPtr)
+{
+ int row;
+ QFormLayout::ItemRole role;
+ formLayout->getItemPosition(index, &row, &role);
+ const int columnspan = role == QFormLayout::SpanningRole ? 2 : 1;
+ const int column = (columnspan > 1 || role == QFormLayout::LabelRole) ? 0 : 1;
+ if (rowPtr)
+ *rowPtr = row;
+ if (columnPtr)
+ *columnPtr = column;
+ if (rowspanPtr)
+ *rowspanPtr = 1;
+ if (colspanPtr)
+ *colspanPtr = columnspan;
+}
+
+static inline QFormLayout::ItemRole formLayoutRole(int column, int colspan)
+{
+ if (colspan > 1)
+ return QFormLayout::SpanningRole;
+ return column == 0 ? QFormLayout::LabelRole : QFormLayout::FieldRole;
+}
+
+QDESIGNER_SHARED_EXPORT void formLayoutAddWidget(QFormLayout *formLayout, QWidget *w, const QRect &r, bool insert)
+{
+ // Consistent API galore...
+ if (insert) {
+ const bool spanning = r.width() > 1;
+ if (spanning) {
+ formLayout->insertRow(r.y(), w);
+ } else {
+ QWidget *label = 0, *field = 0;
+ if (r.x() == 0) {
+ label = w;
+ } else {
+ field = w;
+ }
+ formLayout->insertRow(r.y(), label, field);
+ }
+ } else {
+ formLayout->setWidget(r.y(), formLayoutRole(r.x(), r.width()), w);
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/layoutinfo_p.h b/src/designer/src/lib/shared/layoutinfo_p.h
new file mode 100644
index 000000000..dadfa6ff3
--- /dev/null
+++ b/src/designer/src/lib/shared/layoutinfo_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef LAYOUTINFO_H
+#define LAYOUTINFO_H
+
+#include "shared_global_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+class QLayout;
+class QLayoutItem;
+class QDesignerFormEditorInterface;
+class QFormLayout;
+class QRect;
+class QString;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT LayoutInfo
+{
+public:
+ enum Type
+ {
+ NoLayout,
+ HSplitter,
+ VSplitter,
+ HBox,
+ VBox,
+ Grid,
+ Form,
+ UnknownLayout // QDockWindow inside QMainWindow is inside QMainWindowLayout - it doesn't mean there is no layout
+ };
+
+ static void deleteLayout(const QDesignerFormEditorInterface *core, QWidget *widget);
+
+ // Examines the immediate layout of the widget (will fail for Q3Group Box).
+ static Type layoutType(const QDesignerFormEditorInterface *core, const QWidget *w);
+ // Examines the managed layout of the widget
+ static Type managedLayoutType(const QDesignerFormEditorInterface *core, const QWidget *w, QLayout **layout = 0);
+ static Type layoutType(const QDesignerFormEditorInterface *core, const QLayout *layout);
+ static Type layoutType(const QString &typeName);
+ static QString layoutName(Type t);
+
+ static QWidget *layoutParent(const QDesignerFormEditorInterface *core, QLayout *layout);
+
+ static Type laidoutWidgetType(const QDesignerFormEditorInterface *core, QWidget *widget, bool *isManaged = 0, QLayout **layout = 0);
+ static bool inline isWidgetLaidout(const QDesignerFormEditorInterface *core, QWidget *widget) { return laidoutWidgetType(core, widget) != NoLayout; }
+
+ static QLayout *managedLayout(const QDesignerFormEditorInterface *core, const QWidget *widget);
+ static QLayout *managedLayout(const QDesignerFormEditorInterface *core, QLayout *layout);
+ static QLayout *internalLayout(const QWidget *widget);
+
+ // Is it a a dummy grid placeholder created by Designer?
+ static bool isEmptyItem(QLayoutItem *item);
+};
+
+QDESIGNER_SHARED_EXPORT void getFormLayoutItemPosition(const QFormLayout *formLayout, int index, int *rowPtr, int *columnPtr = 0, int *rowspanPtr = 0, int *colspanPtr = 0);
+QDESIGNER_SHARED_EXPORT void formLayoutAddWidget(QFormLayout *formLayout, QWidget *w, const QRect &r, bool insert);
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // LAYOUTINFO_H
diff --git a/src/designer/src/lib/shared/metadatabase.cpp b/src/designer/src/lib/shared/metadatabase.cpp
new file mode 100644
index 000000000..3cde7da13
--- /dev/null
+++ b/src/designer/src/lib/shared/metadatabase.cpp
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "metadatabase_p.h"
+#include "widgetdatabase_p.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+// Qt
+#include <QtGui/QWidget>
+#include <QtCore/qalgorithms.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ const bool debugMetaDatabase = false;
+}
+
+namespace qdesigner_internal {
+
+MetaDataBaseItem::MetaDataBaseItem(QObject *object)
+ : m_object(object),
+ m_enabled(true)
+{
+}
+
+MetaDataBaseItem::~MetaDataBaseItem()
+{
+}
+
+QString MetaDataBaseItem::name() const
+{
+ Q_ASSERT(m_object);
+ return m_object->objectName();
+}
+
+void MetaDataBaseItem::setName(const QString &name)
+{
+ Q_ASSERT(m_object);
+ m_object->setObjectName(name);
+}
+
+QString MetaDataBaseItem::customClassName() const
+{
+ return m_customClassName;
+}
+void MetaDataBaseItem::setCustomClassName(const QString &customClassName)
+{
+ m_customClassName = customClassName;
+}
+
+
+MetaDataBaseItem::TabOrder MetaDataBaseItem::tabOrder() const
+{
+ return m_tabOrder;
+}
+
+void MetaDataBaseItem::setTabOrder(const TabOrder &tabOrder)
+{
+ m_tabOrder = tabOrder;
+}
+
+bool MetaDataBaseItem::enabled() const
+{
+ return m_enabled;
+}
+
+void MetaDataBaseItem::setEnabled(bool b)
+{
+ m_enabled = b;
+}
+
+QString MetaDataBaseItem::script() const
+{
+ return m_script;
+}
+
+void MetaDataBaseItem::setScript(const QString &script)
+{
+ m_script = script;
+}
+
+QStringList MetaDataBaseItem::fakeSlots() const
+{
+ return m_fakeSlots;
+}
+
+void MetaDataBaseItem::setFakeSlots(const QStringList &fs)
+{
+ m_fakeSlots = fs;
+}
+
+QStringList MetaDataBaseItem::fakeSignals() const
+{
+ return m_fakeSignals;
+}
+
+void MetaDataBaseItem::setFakeSignals(const QStringList &fs)
+{
+ m_fakeSignals = fs;
+}
+
+// -----------------------------------------------------
+MetaDataBase::MetaDataBase(QDesignerFormEditorInterface *core, QObject *parent)
+ : QDesignerMetaDataBaseInterface(parent),
+ m_core(core)
+{
+}
+
+MetaDataBase::~MetaDataBase()
+{
+ qDeleteAll(m_items);
+}
+
+MetaDataBaseItem *MetaDataBase::metaDataBaseItem(QObject *object) const
+{
+ MetaDataBaseItem *i = m_items.value(object);
+ if (i == 0 || !i->enabled())
+ return 0;
+ return i;
+}
+
+void MetaDataBase::add(QObject *object)
+{
+ MetaDataBaseItem *item = m_items.value(object);
+ if (item != 0) {
+ item->setEnabled(true);
+ if (debugMetaDatabase) {
+ qDebug() << "MetaDataBase::add: Existing item for " << object->metaObject()->className() << item->name();
+ }
+ return;
+ }
+
+ item = new MetaDataBaseItem(object);
+ m_items.insert(object, item);
+ if (debugMetaDatabase) {
+ qDebug() << "MetaDataBase::add: New item " << object->metaObject()->className() << item->name();
+ }
+ connect(object, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotDestroyed(QObject*)));
+
+ emit changed();
+}
+
+void MetaDataBase::remove(QObject *object)
+{
+ Q_ASSERT(object);
+
+ if (MetaDataBaseItem *item = m_items.value(object)) {
+ item->setEnabled(false);
+ emit changed();
+ }
+}
+
+QList<QObject*> MetaDataBase::objects() const
+{
+ QList<QObject*> result;
+
+ ItemMap::const_iterator it = m_items.begin();
+ for (; it != m_items.end(); ++it) {
+ if (it.value()->enabled())
+ result.append(it.key());
+ }
+
+ return result;
+}
+
+QDesignerFormEditorInterface *MetaDataBase::core() const
+{
+ return m_core;
+}
+
+void MetaDataBase::slotDestroyed(QObject *object)
+{
+ if (m_items.contains(object)) {
+ MetaDataBaseItem *item = m_items.value(object);
+ delete item;
+ m_items.remove(object);
+ }
+}
+
+// promotion convenience
+QDESIGNER_SHARED_EXPORT bool promoteWidget(QDesignerFormEditorInterface *core,QWidget *widget,const QString &customClassName)
+{
+
+ MetaDataBase *db = qobject_cast<MetaDataBase *>(core->metaDataBase());
+ if (!db)
+ return false;
+ MetaDataBaseItem *item = db->metaDataBaseItem(widget);
+ if (!item) {
+ db ->add(widget);
+ item = db->metaDataBaseItem(widget);
+ }
+ // Recursive promotion occurs if there is a plugin missing.
+ const QString oldCustomClassName = item->customClassName();
+ if (!oldCustomClassName.isEmpty()) {
+ qDebug() << "WARNING: Recursive promotion of " << oldCustomClassName << " to " << customClassName
+ << ". A plugin is missing.";
+ }
+ item->setCustomClassName(customClassName);
+ if (debugMetaDatabase) {
+ qDebug() << "Promoting " << widget->metaObject()->className() << " to " << customClassName;
+ }
+ return true;
+}
+
+QDESIGNER_SHARED_EXPORT void demoteWidget(QDesignerFormEditorInterface *core,QWidget *widget)
+{
+ MetaDataBase *db = qobject_cast<MetaDataBase *>(core->metaDataBase());
+ if (!db)
+ return;
+ MetaDataBaseItem *item = db->metaDataBaseItem(widget);
+ item->setCustomClassName(QString());
+ if (debugMetaDatabase) {
+ qDebug() << "Demoting " << widget;
+ }
+}
+
+QDESIGNER_SHARED_EXPORT bool isPromoted(QDesignerFormEditorInterface *core, QWidget* widget)
+{
+ const MetaDataBase *db = qobject_cast<const MetaDataBase *>(core->metaDataBase());
+ if (!db)
+ return false;
+ const MetaDataBaseItem *item = db->metaDataBaseItem(widget);
+ if (!item)
+ return false;
+ return !item->customClassName().isEmpty();
+}
+
+QDESIGNER_SHARED_EXPORT QString promotedCustomClassName(QDesignerFormEditorInterface *core, QWidget* widget)
+{
+ const MetaDataBase *db = qobject_cast<const MetaDataBase *>(core->metaDataBase());
+ if (!db)
+ return QString();
+ const MetaDataBaseItem *item = db->metaDataBaseItem(widget);
+ if (!item)
+ return QString();
+ return item->customClassName();
+}
+
+QDESIGNER_SHARED_EXPORT QString promotedExtends(QDesignerFormEditorInterface *core, QWidget* widget)
+{
+ const QString customClassName = promotedCustomClassName(core,widget);
+ if (customClassName.isEmpty())
+ return QString();
+ const int i = core->widgetDataBase()->indexOfClassName(customClassName);
+ if (i == -1)
+ return QString();
+ return core->widgetDataBase()->item(i)->extends();
+}
+
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/metadatabase_p.h b/src/designer/src/lib/shared/metadatabase_p.h
new file mode 100644
index 000000000..5675217cc
--- /dev/null
+++ b/src/designer/src/lib/shared/metadatabase_p.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef METADATABASE_H
+#define METADATABASE_H
+
+#include "shared_global_p.h"
+
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+
+#include <QtCore/QHash>
+#include <QtCore/QStringList>
+#include <QtGui/QCursor>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT MetaDataBaseItem: public QDesignerMetaDataBaseItemInterface
+{
+public:
+ explicit MetaDataBaseItem(QObject *object);
+ virtual ~MetaDataBaseItem();
+
+ virtual QString name() const;
+ virtual void setName(const QString &name);
+
+ typedef QList<QWidget*> TabOrder;
+ virtual TabOrder tabOrder() const;
+ virtual void setTabOrder(const TabOrder &tabOrder);
+
+ virtual bool enabled() const;
+ virtual void setEnabled(bool b);
+
+ QString customClassName() const;
+ void setCustomClassName(const QString &customClassName);
+
+ QString script() const;
+ void setScript(const QString &script);
+
+ QStringList fakeSlots() const;
+ void setFakeSlots(const QStringList &);
+
+ QStringList fakeSignals() const;
+ void setFakeSignals(const QStringList &);
+
+private:
+ QObject *m_object;
+ TabOrder m_tabOrder;
+ bool m_enabled;
+ QString m_customClassName;
+ QString m_script;
+ QStringList m_fakeSlots;
+ QStringList m_fakeSignals;
+};
+
+class QDESIGNER_SHARED_EXPORT MetaDataBase: public QDesignerMetaDataBaseInterface
+{
+ Q_OBJECT
+public:
+ explicit MetaDataBase(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ virtual ~MetaDataBase();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual QDesignerMetaDataBaseItemInterface *item(QObject *object) const { return metaDataBaseItem(object); }
+ virtual MetaDataBaseItem *metaDataBaseItem(QObject *object) const;
+ virtual void add(QObject *object);
+ virtual void remove(QObject *object);
+
+ virtual QList<QObject*> objects() const;
+
+private slots:
+ void slotDestroyed(QObject *object);
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ typedef QHash<QObject *, MetaDataBaseItem*> ItemMap;
+ ItemMap m_items;
+};
+
+ // promotion convenience
+ QDESIGNER_SHARED_EXPORT bool promoteWidget(QDesignerFormEditorInterface *core,QWidget *widget,const QString &customClassName);
+ QDESIGNER_SHARED_EXPORT void demoteWidget(QDesignerFormEditorInterface *core,QWidget *widget);
+ QDESIGNER_SHARED_EXPORT bool isPromoted(QDesignerFormEditorInterface *core, QWidget* w);
+ QDESIGNER_SHARED_EXPORT QString promotedCustomClassName(QDesignerFormEditorInterface *core, QWidget* w);
+ QDESIGNER_SHARED_EXPORT QString promotedExtends(QDesignerFormEditorInterface *core, QWidget* w);
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // METADATABASE_H
diff --git a/src/designer/src/lib/shared/morphmenu.cpp b/src/designer/src/lib/shared/morphmenu.cpp
new file mode 100644
index 000000000..67121e597
--- /dev/null
+++ b/src/designer/src/lib/shared/morphmenu.cpp
@@ -0,0 +1,635 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "morphmenu_p.h"
+#include "formwindowbase_p.h"
+#include "widgetfactory_p.h"
+#include "qdesigner_formwindowcommand_p.h"
+#include "qlayout_widget_p.h"
+#include "layoutinfo_p.h"
+#include "qdesigner_propertycommand_p.h"
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+
+#include <QtGui/QWidget>
+#include <QtGui/QAction>
+#include <QtGui/QMenu>
+#include <QtGui/QApplication>
+#include <QtGui/QLayout>
+#include <QtGui/QUndoStack>
+
+#include <QtGui/QFrame>
+#include <QtGui/QGroupBox>
+#include <QtGui/QTabWidget>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QAbstractButton>
+#include <QtGui/QAbstractSpinBox>
+#include <QtGui/QTextEdit>
+#include <QtGui/QPlainTextEdit>
+#include <QtGui/QLabel>
+
+#include <QtCore/QStringList>
+#include <QtCore/QMap>
+#include <QtCore/QVariant>
+#include <QtCore/QSignalMapper>
+#include <QtCore/QDebug>
+
+Q_DECLARE_METATYPE(QWidgetList)
+
+QT_BEGIN_NAMESPACE
+
+// Helpers for the dynamic properties that store Z/Widget order
+static const char *widgetOrderPropertyC = "_q_widgetOrder";
+static const char *zOrderPropertyC = "_q_zOrder";
+
+/* Morphing in Designer:
+ * It is possible to morph:
+ * - Non-Containers into similar widgets by category
+ * - Simple page containers into similar widgets or page-based containers with
+ * a single page (in theory also into a QLayoutWidget, but this might
+ * not always be appropriate).
+ * - Page-based containers into page-based containers or simple containers if
+ * they have just one page
+ * [Page based containers meaning here having a container extension]
+ * Morphing types are restricted to the basic Qt types. Morphing custom
+ * widgets is considered risky since they might have unmanaged layouts
+ * or the like.
+ *
+ * Requirements:
+ * - The widget must be on a non-laid out parent or in a layout managed
+ * by Designer
+ * - Its child widgets must be non-laid out or in a layout managed
+ * by Designer
+ * Note that child widgets can be
+ * - On the widget itself in the case of simple containers
+ * - On several pages in the case of page-based containers
+ * This is what is called 'childContainers' in the code (the widget itself
+ * or the list of container extension pages).
+ *
+ * The Morphing process encompasses:
+ * - Create a target widget and apply properties as far as applicable
+ * If the target widget has a container extension, add a sufficient
+ * number of pages.
+ * - Transferring the child widgets over to the new childContainers.
+ * In the case of a managed layout on a childContainer, this is simply
+ * set on the target childContainer, which is a new Qt 4.5
+ * functionality.
+ * - Replace the widget itself in the parent layout
+ */
+
+namespace qdesigner_internal {
+
+enum MorphCategory {
+ MorphCategoryNone, MorphSimpleContainer, MorphPageContainer, MorphItemView,
+ MorphButton, MorphSpinBox, MorphTextEdit
+};
+
+// Determine category of a widget
+static MorphCategory category(const QWidget *w)
+{
+ // Simple containers: Exact match
+ const QMetaObject *mo = w->metaObject();
+ if (mo == &QWidget::staticMetaObject || mo == &QFrame::staticMetaObject || mo == &QGroupBox::staticMetaObject || mo == &QLayoutWidget::staticMetaObject)
+ return MorphSimpleContainer;
+ if (mo == &QTabWidget::staticMetaObject || mo == &QStackedWidget::staticMetaObject || mo == &QToolBox::staticMetaObject)
+ return MorphPageContainer;
+ if (qobject_cast<const QAbstractItemView*>(w))
+ return MorphItemView;
+ if (qobject_cast<const QAbstractButton *>(w))
+ return MorphButton;
+ if (qobject_cast<const QAbstractSpinBox *>(w))
+ return MorphSpinBox;
+ if (qobject_cast<const QPlainTextEdit *>(w) || qobject_cast<const QTextEdit*>(w))
+ return MorphTextEdit;
+
+ return MorphCategoryNone;
+}
+
+/* Return the similar classes of a category. This is currently restricted
+ * to the known Qt classes with no precautions to parse the Widget Database
+ * (which is too risky, custom classes might have container extensions
+ * or non-managed layouts, etc.). */
+
+static QStringList classesOfCategory(MorphCategory cat)
+{
+ typedef QMap<MorphCategory, QStringList> CandidateCache;
+ static CandidateCache candidateCache;
+ CandidateCache::iterator it = candidateCache.find(cat);
+ if (it == candidateCache.end()) {
+ it = candidateCache.insert(cat, QStringList());
+ QStringList &l = it.value();
+ switch (cat) {
+ case MorphCategoryNone:
+ break;
+ case MorphSimpleContainer:
+ // Do not generally allow to morph into a layout.
+ // This can be risky in case of container pages,etc.
+ l << QLatin1String("QWidget") << QLatin1String("QFrame") << QLatin1String("QGroupBox");
+ break;
+ case MorphPageContainer:
+ l << QLatin1String("QTabWidget") << QLatin1String("QStackedWidget") << QLatin1String("QToolBox");
+ break;
+ case MorphItemView:
+ l << QLatin1String("QListView") << QLatin1String("QListWidget")
+ << QLatin1String("QTreeView") << QLatin1String("QTreeWidget")
+ << QLatin1String("QTableView") << QLatin1String("QTableWidget")
+ << QLatin1String("QColumnView");
+ break;
+ case MorphButton:
+ l << QLatin1String("QCheckBox") << QLatin1String("QRadioButton")
+ << QLatin1String("QPushButton") << QLatin1String("QToolButton")
+ << QLatin1String("QCommandLinkButton");
+ break;
+ case MorphSpinBox:
+ l << QLatin1String("QDateTimeEdit") << QLatin1String("QDateEdit")
+ << QLatin1String("QTimeEdit")
+ << QLatin1String("QSpinBox") << QLatin1String("QDoubleSpinBox");
+ break;
+ case MorphTextEdit:
+ l << QLatin1String("QTextEdit") << QLatin1String("QPlainTextEdit") << QLatin1String("QTextBrowser");
+ break;
+ }
+ }
+ return it.value();
+}
+
+// Return the widgets containing the children to be transferred to. This is the
+// widget itself in most cases, except for QDesignerContainerExtension cases
+static QWidgetList childContainers(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ if (const QDesignerContainerExtension *ce = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), w)) {
+ QWidgetList children;
+ if (const int count = ce->count()) {
+ for (int i = 0; i < count; i++)
+ children.push_back(ce->widget(i));
+ }
+ return children;
+ }
+ QWidgetList self;
+ self.push_back(w);
+ return self;
+}
+
+// Suggest a suitable objectname for the widget to be morphed into
+// Replace the class name parts: 'xxFrame' -> 'xxGroupBox', 'frame' -> 'groupBox'
+static QString suggestObjectName(const QString &oldClassName, const QString &newClassName, const QString &oldName)
+{
+ QString oldClassPart = oldClassName;
+ QString newClassPart = newClassName;
+ if (oldClassPart.startsWith(QLatin1Char('Q')))
+ oldClassPart.remove(0, 1);
+ if (newClassPart.startsWith(QLatin1Char('Q')))
+ newClassPart.remove(0, 1);
+
+ QString newName = oldName;
+ newName.replace(oldClassPart, newClassPart);
+ oldClassPart[0] = oldClassPart.at(0).toLower();
+ newClassPart[0] = newClassPart.at(0).toLower();
+ newName.replace(oldClassPart, newClassPart);
+ return newName;
+}
+
+// Find the label whose buddy the widget is.
+QLabel *buddyLabelOf(QDesignerFormWindowInterface *fw, QWidget *w)
+{
+ typedef QList<QLabel*> LabelList;
+ const LabelList labelList = fw->findChildren<QLabel*>();
+ if (labelList.empty())
+ return 0;
+ const LabelList::const_iterator cend = labelList.constEnd();
+ for (LabelList::const_iterator it = labelList.constBegin(); it != cend; ++it )
+ if ( (*it)->buddy() == w)
+ return *it;
+ return 0;
+}
+
+// Replace widgets in a widget-list type dynamic property of the parent
+// used for Z-order, etc.
+static void replaceWidgetListDynamicProperty(QWidget *parentWidget,
+ QWidget *oldWidget, QWidget *newWidget,
+ const char *name)
+{
+ QWidgetList list = qvariant_cast<QWidgetList>(parentWidget->property(name));
+ const int index = list.indexOf(oldWidget);
+ if (index != -1) {
+ list.replace(index, newWidget);
+ parentWidget->setProperty(name, QVariant::fromValue(list));
+ }
+}
+
+/* Morph a widget into another class. Use the static addMorphMacro() to
+ * add a respective command sequence to the undo stack as it emits signals
+ * which cause other commands to be added. */
+class MorphWidgetCommand : public QDesignerFormWindowCommand
+{
+ Q_DISABLE_COPY(MorphWidgetCommand)
+public:
+
+ explicit MorphWidgetCommand(QDesignerFormWindowInterface *formWindow);
+ ~MorphWidgetCommand();
+
+ // Convenience to add a morph command sequence macro
+ static bool addMorphMacro(QDesignerFormWindowInterface *formWindow, QWidget *w, const QString &newClass);
+
+ bool init(QWidget *widget, const QString &newClass);
+
+ QString newWidgetName() const { return m_afterWidget->objectName(); }
+
+ virtual void redo();
+ virtual void undo();
+
+ static QStringList candidateClasses(QDesignerFormWindowInterface *fw, QWidget *w);
+
+private:
+ static bool canMorph(QDesignerFormWindowInterface *fw, QWidget *w, int *childContainerCount = 0, MorphCategory *cat = 0);
+ void morph(QWidget *before, QWidget *after);
+
+ QWidget *m_beforeWidget;
+ QWidget *m_afterWidget;
+};
+
+bool MorphWidgetCommand::addMorphMacro(QDesignerFormWindowInterface *fw, QWidget *w, const QString &newClass)
+{
+ MorphWidgetCommand *morphCmd = new MorphWidgetCommand(fw);
+ if (!morphCmd->init(w, newClass)) {
+ qWarning("*** Unable to create a MorphWidgetCommand");
+ delete morphCmd;
+ return false;
+ }
+ QLabel *buddyLabel = buddyLabelOf(fw, w);
+ // Need a macro since it adds further commands
+ QUndoStack *us = fw->commandHistory();
+ us->beginMacro(morphCmd->text());
+ // Have the signal slot/buddy editors add their commands to delete widget
+ if (FormWindowBase *fwb = qobject_cast<FormWindowBase*>(fw))
+ fwb->emitWidgetRemoved(w);
+
+ const QString newWidgetName = morphCmd->newWidgetName();
+ us->push(morphCmd);
+
+ // restore buddy using the QByteArray name.
+ if (buddyLabel) {
+ SetPropertyCommand *buddyCmd = new SetPropertyCommand(fw);
+ buddyCmd->init(buddyLabel, QLatin1String("buddy"), QVariant(newWidgetName.toUtf8()));
+ us->push(buddyCmd);
+ }
+ us->endMacro();
+ return true;
+}
+
+MorphWidgetCommand::MorphWidgetCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_beforeWidget(0),
+ m_afterWidget(0)
+{
+}
+
+MorphWidgetCommand::~MorphWidgetCommand()
+{
+}
+
+bool MorphWidgetCommand::init(QWidget *widget, const QString &newClassName)
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ QDesignerFormEditorInterface *core = fw->core();
+
+ if (!canMorph(fw, widget))
+ return false;
+
+ const QString oldClassName = WidgetFactory::classNameOf(core, widget);
+ const QString oldName = widget->objectName();
+ //: MorphWidgetCommand description
+ setText(QApplication::translate("Command", "Morph %1/'%2' into %3").arg(oldClassName, oldName, newClassName));
+
+ m_beforeWidget = widget;
+ m_afterWidget = core->widgetFactory()->createWidget(newClassName, fw);
+ if (!m_afterWidget)
+ return false;
+
+ // Set object name. Do not unique it (as to maintain it).
+ m_afterWidget->setObjectName(suggestObjectName(oldClassName, newClassName, oldName));
+
+ // If the target has a container extension, we add enough new pages to take
+ // up the children of the before widget
+ if (QDesignerContainerExtension* c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_afterWidget)) {
+ if (const int pageCount = childContainers(core, m_beforeWidget).size()) {
+ const QString qWidget = QLatin1String("QWidget");
+ const QString containerName = m_afterWidget->objectName();
+ for (int i = 0; i < pageCount; i++) {
+ QString name = containerName;
+ name += QLatin1String("Page");
+ name += QString::number(i + 1);
+ QWidget *page = core->widgetFactory()->createWidget(qWidget);
+ page->setObjectName(name);
+ fw->ensureUniqueObjectName(page);
+ c->addWidget(page);
+ core->metaDataBase()->add(page);
+ }
+ }
+ }
+
+ // Copy over applicable properties
+ const QDesignerPropertySheetExtension *beforeSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), widget);
+ QDesignerPropertySheetExtension *afterSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), m_afterWidget);
+ const QString objectNameProperty = QLatin1String("objectName");
+ const int count = beforeSheet->count();
+ for (int i = 0; i < count; i++)
+ if (beforeSheet->isVisible(i) && beforeSheet->isChanged(i)) {
+ const QString name = beforeSheet->propertyName(i);
+ if (name != objectNameProperty) {
+ const int afterIndex = afterSheet->indexOf(name);
+ if (afterIndex != -1 && afterSheet->isVisible(afterIndex) && afterSheet->propertyGroup(afterIndex) == beforeSheet->propertyGroup(i)) {
+ afterSheet->setProperty(i, beforeSheet->property(i));
+ afterSheet->setChanged(i, true);
+ } else {
+ // Some mismatch. The rest won't match, either
+ break;
+ }
+ }
+ }
+ return true;
+}
+
+void MorphWidgetCommand::redo()
+{
+ morph(m_beforeWidget, m_afterWidget);
+}
+
+void MorphWidgetCommand::undo()
+{
+ morph(m_afterWidget, m_beforeWidget);
+}
+
+void MorphWidgetCommand::morph(QWidget *before, QWidget *after)
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+
+ fw->unmanageWidget(before);
+
+ const QRect oldGeom = before->geometry();
+ QWidget *parent = before->parentWidget();
+ Q_ASSERT(parent);
+ /* Morphing consists of main 2 steps
+ * 1) Move over children (laid out, non-laid out)
+ * 2) Register self with new parent (laid out, non-laid out) */
+
+ // 1) Move children. Loop over child containers
+ QWidgetList beforeChildContainers = childContainers(fw->core(), before);
+ QWidgetList afterChildContainers = childContainers(fw->core(), after);
+ Q_ASSERT(beforeChildContainers.size() == afterChildContainers.size());
+ const int childContainerCount = beforeChildContainers.size();
+ for (int i = 0; i < childContainerCount; i++) {
+ QWidget *beforeChildContainer = beforeChildContainers.at(i);
+ QWidget *afterChildContainer = afterChildContainers.at(i);
+ if (QLayout *childLayout = beforeChildContainer->layout()) {
+ // Laid-out: Move the layout (since 4.5)
+ afterChildContainer->setLayout(childLayout);
+ } else {
+ // Non-Laid-out: Reparent, move over
+ const QObjectList c = beforeChildContainer->children();
+ const QObjectList::const_iterator cend = c.constEnd();
+ for (QObjectList::const_iterator it = c.constBegin(); it != cend; ++it) {
+ if ( (*it)->isWidgetType()) {
+ QWidget *w = static_cast<QWidget*>(*it);
+ if (fw->isManaged(w)) {
+ const QRect geom = w->geometry();
+ w->setParent(afterChildContainer);
+ w->setGeometry(geom);
+ }
+ }
+ }
+ }
+ afterChildContainer->setProperty(widgetOrderPropertyC, beforeChildContainer->property(widgetOrderPropertyC));
+ afterChildContainer->setProperty(zOrderPropertyC, beforeChildContainer->property(zOrderPropertyC));
+ }
+
+ // 2) Replace the actual widget in the parent layout
+ after->setGeometry(oldGeom);
+ if (QLayout *containingLayout = LayoutInfo::managedLayout(fw->core(), parent)) {
+ LayoutHelper *lh = LayoutHelper::createLayoutHelper(LayoutInfo::layoutType(fw->core(), containingLayout));
+ Q_ASSERT(lh);
+ lh->replaceWidget(containingLayout, before, after);
+ delete lh;
+ } else {
+ before->hide();
+ before->setParent(0);
+ after->setParent(parent);
+ after->setGeometry(oldGeom);
+ }
+
+ // Check various properties: Z order, form tab order
+ replaceWidgetListDynamicProperty(parent, before, after, widgetOrderPropertyC);
+ replaceWidgetListDynamicProperty(parent, before, after, zOrderPropertyC);
+
+ QDesignerMetaDataBaseItemInterface *formItem = fw->core()->metaDataBase()->item(fw);
+ QWidgetList tabOrder = formItem->tabOrder();
+ const int tabIndex = tabOrder.indexOf(before);
+ if (tabIndex != -1) {
+ tabOrder.replace(tabIndex, after);
+ formItem->setTabOrder(tabOrder);
+ }
+
+ after->show();
+ fw->manageWidget(after);
+
+ fw->clearSelection(false);
+ fw->selectWidget(after);
+}
+
+/* Check if morphing is possible. It must be a valid category and the parent/
+ * child relationships must be either non-laidout or directly on
+ * Designer-managed layouts. */
+bool MorphWidgetCommand::canMorph(QDesignerFormWindowInterface *fw, QWidget *w, int *ptrToChildContainerCount, MorphCategory *ptrToCat)
+{
+ if (ptrToChildContainerCount)
+ *ptrToChildContainerCount = 0;
+ const MorphCategory cat = category(w);
+ if (ptrToCat)
+ *ptrToCat = cat;
+ if (cat == MorphCategoryNone)
+ return false;
+
+ QDesignerFormEditorInterface *core = fw->core();
+ // Don't know how to fiddle class names in Jambi..
+ if (qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core))
+ return false;
+ if (!fw->isManaged(w) || w == fw->mainContainer())
+ return false;
+ // Check the parent relationship. We accept only managed parent widgets
+ // with a single, managed layout in which widget is a member.
+ QWidget *parent = w->parentWidget();
+ if (parent == 0)
+ return false;
+ if (QLayout *pl = LayoutInfo::managedLayout(core, parent))
+ if (pl->indexOf(w) < 0 || !core->metaDataBase()->item(pl))
+ return false;
+ // Check Widget database
+ const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
+ const int wdbindex = wdb->indexOfObject(w);
+ if (wdbindex == -1)
+ return false;
+ const bool isContainer = wdb->item(wdbindex)->isContainer();
+ if (!isContainer)
+ return true;
+ // Check children. All child containers must be non-laid-out or have managed layouts
+ const QWidgetList pages = childContainers(core, w);
+ const int pageCount = pages.size();
+ if (ptrToChildContainerCount)
+ *ptrToChildContainerCount = pageCount;
+ if (pageCount) {
+ for (int i = 0; i < pageCount; i++)
+ if (QLayout *cl = pages.at(i)->layout())
+ if (!core->metaDataBase()->item(cl))
+ return false;
+ }
+ return true;
+}
+
+QStringList MorphWidgetCommand::candidateClasses(QDesignerFormWindowInterface *fw, QWidget *w)
+{
+ int childContainerCount;
+ MorphCategory cat;
+ if (!canMorph(fw, w, &childContainerCount, &cat))
+ return QStringList();
+
+ QStringList rc = classesOfCategory(cat);
+ switch (cat) {
+ // Frames, etc can always be morphed into one-page page containers
+ case MorphSimpleContainer:
+ rc += classesOfCategory(MorphPageContainer);
+ break;
+ // Multipage-Containers can be morphed into simple containers if they
+ // have 1 page.
+ case MorphPageContainer:
+ if (childContainerCount == 1)
+ rc += classesOfCategory(MorphSimpleContainer);
+ break;
+ default:
+ break;
+ }
+ return rc;
+}
+
+// MorphMenu
+MorphMenu::MorphMenu(QObject *parent) :
+ QObject(parent),
+ m_subMenuAction(0),
+ m_menu(0),
+ m_mapper(0),
+ m_widget(0),
+ m_formWindow(0)
+{
+}
+
+void MorphMenu::populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList& al)
+{
+ if (populateMenu(w, fw))
+ al.push_back(m_subMenuAction);
+}
+
+void MorphMenu::populate(QWidget *w, QDesignerFormWindowInterface *fw, QMenu& m)
+{
+ if (populateMenu(w, fw))
+ m.addAction(m_subMenuAction);
+}
+
+void MorphMenu::slotMorph(const QString &newClassName)
+{
+ MorphWidgetCommand::addMorphMacro(m_formWindow, m_widget, newClassName);
+}
+
+bool MorphMenu::populateMenu(QWidget *w, QDesignerFormWindowInterface *fw)
+{
+ m_widget = 0;
+ m_formWindow = 0;
+
+ // Clear menu
+ if (m_subMenuAction) {
+ m_subMenuAction->setVisible(false);
+ m_menu->clear();
+ }
+
+ // Checks: Must not be main container
+ if (w == fw->mainContainer())
+ return false;
+
+ const QStringList c = MorphWidgetCommand::candidateClasses(fw, w);
+ if (c.empty())
+ return false;
+
+ // Pull up
+ m_widget = w;
+ m_formWindow = fw;
+ const QString oldClassName = WidgetFactory::classNameOf(fw->core(), w);
+
+ if (!m_subMenuAction) {
+ m_subMenuAction = new QAction(tr("Morph into"), this);
+ m_menu = new QMenu;
+ m_subMenuAction->setMenu(m_menu);
+ m_mapper = new QSignalMapper(this);
+ connect(m_mapper , SIGNAL(mapped(QString)), this, SLOT(slotMorph(QString)));
+ }
+
+ // Add actions
+ const QStringList::const_iterator cend = c.constEnd();
+ for (QStringList::const_iterator it = c.constBegin(); it != cend; ++it) {
+ if (*it != oldClassName) {
+ QAction *a = m_menu->addAction(*it);
+ m_mapper->setMapping (a, *it);
+ connect(a, SIGNAL(triggered()), m_mapper, SLOT(map()));
+ }
+ }
+ m_subMenuAction->setVisible(true);
+ return true;
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/morphmenu_p.h b/src/designer/src/lib/shared/morphmenu_p.h
new file mode 100644
index 000000000..9d20545a6
--- /dev/null
+++ b/src/designer/src/lib/shared/morphmenu_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef MORPH_COMMAND_H
+#define MORPH_COMMAND_H
+
+#include "shared_global_p.h"
+#include "qdesigner_formwindowcommand_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+class QSignalMapper;
+class QMenu;
+
+namespace qdesigner_internal {
+
+/* Conveniene morph menu that acts on a single widget. */
+class QDESIGNER_SHARED_EXPORT MorphMenu : public QObject {
+ Q_DISABLE_COPY(MorphMenu)
+ Q_OBJECT
+public:
+ typedef QList<QAction *> ActionList;
+
+ explicit MorphMenu(QObject *parent = 0);
+
+ void populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList& al);
+ void populate(QWidget *w, QDesignerFormWindowInterface *fw, QMenu& m);
+
+private slots:
+ void slotMorph(const QString &newClassName);
+
+private:
+ bool populateMenu(QWidget *w, QDesignerFormWindowInterface *fw);
+
+ QAction *m_subMenuAction;
+ QMenu *m_menu;
+ QSignalMapper *m_mapper;
+
+ QWidget *m_widget;
+ QDesignerFormWindowInterface *m_formWindow;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // MORPH_COMMAND_H
diff --git a/src/designer/src/lib/shared/newactiondialog.cpp b/src/designer/src/lib/shared/newactiondialog.cpp
new file mode 100644
index 000000000..9aaa347c7
--- /dev/null
+++ b/src/designer/src/lib/shared/newactiondialog.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "newactiondialog_p.h"
+#include "ui_newactiondialog.h"
+#include "richtexteditor_p.h"
+#include "actioneditor_p.h"
+#include "formwindowbase_p.h"
+#include "qdesigner_utils_p.h"
+#include "iconloader_p.h"
+
+#include <QtDesigner/abstractformwindow.h>
+#include <QtDesigner/abstractformeditor.h>
+
+#include <QtGui/QPushButton>
+#include <QtCore/QRegExp>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+// -------------------- ActionData
+
+ActionData::ActionData() :
+ checkable(false)
+{
+}
+
+// Returns a combination of ChangeMask flags
+unsigned ActionData::compare(const ActionData &rhs) const
+{
+ unsigned rc = 0;
+ if (text != rhs.text)
+ rc |= TextChanged;
+ if (name != rhs.name)
+ rc |= NameChanged;
+ if (toolTip != rhs.toolTip)
+ rc |= ToolTipChanged ;
+ if (icon != rhs.icon)
+ rc |= IconChanged ;
+ if (checkable != rhs.checkable)
+ rc |= CheckableChanged;
+ if (keysequence != rhs.keysequence)
+ rc |= KeysequenceChanged ;
+ return rc;
+}
+
+// -------------------- NewActionDialog
+NewActionDialog::NewActionDialog(ActionEditor *parent) :
+ QDialog(parent, Qt::Sheet),
+ m_ui(new Ui::NewActionDialog),
+ m_actionEditor(parent)
+{
+ m_ui->setupUi(this);
+
+ m_ui->tooltipEditor->setTextPropertyValidationMode(ValidationRichText);
+ connect(m_ui->toolTipToolButton, SIGNAL(clicked()), this, SLOT(slotEditToolTip()));
+
+ m_ui->keysequenceResetToolButton->setIcon(createIconSet(QLatin1String("resetproperty.png")));
+ connect(m_ui->keysequenceResetToolButton, SIGNAL(clicked()), this, SLOT(slotResetKeySequence()));
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ m_ui->editActionText->setFocus();
+ m_auto_update_object_name = true;
+ updateButtons();
+
+ QDesignerFormWindowInterface *form = parent->formWindow();
+ m_ui->iconSelector->setFormEditor(form->core());
+ FormWindowBase *formBase = qobject_cast<FormWindowBase *>(form);
+
+ if (formBase) {
+ m_ui->iconSelector->setPixmapCache(formBase->pixmapCache());
+ m_ui->iconSelector->setIconCache(formBase->iconCache());
+ }
+}
+
+NewActionDialog::~NewActionDialog()
+{
+ delete m_ui;
+}
+
+QString NewActionDialog::actionText() const
+{
+ return m_ui->editActionText->text();
+}
+
+QString NewActionDialog::actionName() const
+{
+ return m_ui->editObjectName->text();
+}
+
+ActionData NewActionDialog::actionData() const
+{
+ ActionData rc;
+ rc.text = actionText();
+ rc.name = actionName();
+ rc.toolTip = m_ui->tooltipEditor->text();
+ rc.icon = m_ui->iconSelector->icon();
+ rc.icon.setTheme(m_ui->iconThemeEditor->theme());
+ rc.checkable = m_ui->checkableCheckBox->checkState() == Qt::Checked;
+ rc.keysequence = PropertySheetKeySequenceValue(m_ui->keySequenceEdit->keySequence());
+ return rc;
+}
+
+void NewActionDialog::setActionData(const ActionData &d)
+{
+ m_ui->editActionText->setText(d.text);
+ m_ui->editObjectName->setText(d.name);
+ m_ui->iconSelector->setIcon(d.icon.unthemed());
+ m_ui->iconThemeEditor->setTheme(d.icon.theme());
+ m_ui->tooltipEditor->setText(d.toolTip);
+ m_ui->keySequenceEdit->setKeySequence(d.keysequence.value());
+ m_ui->checkableCheckBox->setCheckState(d.checkable ? Qt::Checked : Qt::Unchecked);
+
+ m_auto_update_object_name = false;
+ updateButtons();
+}
+
+void NewActionDialog::on_editActionText_textEdited(const QString &text)
+{
+ if (text.isEmpty())
+ m_auto_update_object_name = true;
+
+ if (m_auto_update_object_name)
+ m_ui->editObjectName->setText(ActionEditor::actionTextToName(text));
+
+ updateButtons();
+}
+
+void NewActionDialog::on_editObjectName_textEdited(const QString&)
+{
+ updateButtons();
+ m_auto_update_object_name = false;
+}
+
+void NewActionDialog::slotEditToolTip()
+{
+ const QString oldToolTip = m_ui->tooltipEditor->text();
+ RichTextEditorDialog richTextDialog(m_actionEditor->core(), this);
+ richTextDialog.setText(oldToolTip);
+ if (richTextDialog.showDialog() == QDialog::Rejected)
+ return;
+ const QString newToolTip = richTextDialog.text();
+ if (newToolTip != oldToolTip)
+ m_ui->tooltipEditor->setText(newToolTip);
+}
+
+void NewActionDialog::slotResetKeySequence()
+{
+ m_ui->keySequenceEdit->setKeySequence(QKeySequence());
+ m_ui->keySequenceEdit->setFocus(Qt::MouseFocusReason);
+}
+
+void NewActionDialog::updateButtons()
+{
+ QPushButton *okButton = m_ui->buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setEnabled(!actionText().isEmpty() && !actionName().isEmpty());
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/newactiondialog.ui b/src/designer/src/lib/shared/newactiondialog.ui
new file mode 100644
index 000000000..aef971058
--- /dev/null
+++ b/src/designer/src/lib/shared/newactiondialog.ui
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::NewActionDialog</class>
+ <widget class="QDialog" name="qdesigner_internal::NewActionDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>366</width>
+ <height>270</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>New Action...</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="textLabel">
+ <property name="text">
+ <string>&amp;Text:</string>
+ </property>
+ <property name="buddy">
+ <cstring>editActionText</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="editActionText">
+ <property name="minimumSize">
+ <size>
+ <width>255</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="objectNameLabel">
+ <property name="text">
+ <string>Object &amp;name:</string>
+ </property>
+ <property name="buddy">
+ <cstring>editObjectName</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="editObjectName"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="toolTipLabel">
+ <property name="text">
+ <string>T&amp;oolTip:</string>
+ </property>
+ <property name="buddy">
+ <cstring>tooltipEditor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <layout class="QHBoxLayout" name="toolTipLayout">
+ <item>
+ <widget class="TextPropertyEditor" name="tooltipEditor" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="toolTipToolButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="iconThemeLabel">
+ <property name="text">
+ <string>Icon th&amp;eme:</string>
+ </property>
+ <property name="buddy">
+ <cstring>iconThemeEditor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="qdesigner_internal::IconThemeEditor" name="iconThemeEditor" native="true"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="iconLabel">
+ <property name="text">
+ <string>&amp;Icon:</string>
+ </property>
+ <property name="buddy">
+ <cstring>iconSelector</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="qdesigner_internal::IconSelector" name="iconSelector" native="true"/>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="1">
+ <widget class="QCheckBox" name="checkableCheckBox">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="checkableLabel">
+ <property name="text">
+ <string>&amp;Checkable:</string>
+ </property>
+ <property name="buddy">
+ <cstring>checkableCheckBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="shortcutLabel">
+ <property name="text">
+ <string>&amp;Shortcut:</string>
+ </property>
+ <property name="buddy">
+ <cstring>keySequenceEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <layout class="QHBoxLayout" name="keysequenceLayout">
+ <item>
+ <widget class="QtKeySequenceEdit" name="keySequenceEdit" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="keysequenceResetToolButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>qdesigner_internal::IconSelector</class>
+ <extends>QWidget</extends>
+ <header>iconselector_p.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>QtKeySequenceEdit</class>
+ <extends>QWidget</extends>
+ <header>qtpropertybrowserutils_p.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>TextPropertyEditor</class>
+ <extends>QWidget</extends>
+ <header>textpropertyeditor_p.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>qdesigner_internal::IconThemeEditor</class>
+ <extends>QWidget</extends>
+ <header>iconselector_p.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>editActionText</tabstop>
+ <tabstop>editObjectName</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>qdesigner_internal::NewActionDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>165</x>
+ <y>162</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>291</x>
+ <y>94</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>qdesigner_internal::NewActionDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>259</x>
+ <y>162</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>293</x>
+ <y>128</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/newactiondialog_p.h b/src/designer/src/lib/shared/newactiondialog_p.h
new file mode 100644
index 000000000..b06d1f9a5
--- /dev/null
+++ b/src/designer/src/lib/shared/newactiondialog_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEWACTIONDIALOG_P_H
+#define NEWACTIONDIALOG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qdesigner_utils_p.h" // PropertySheetIconValue
+
+#include <QtGui/QDialog>
+#include <QtGui/QKeySequence>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+namespace Ui {
+ class NewActionDialog;
+}
+
+class ActionEditor;
+
+struct ActionData {
+
+ enum ChangeMask {
+ TextChanged = 0x1, NameChanged = 0x2, ToolTipChanged = 0x4,
+ IconChanged = 0x8, CheckableChanged = 0x10, KeysequenceChanged = 0x20
+ };
+
+ ActionData();
+ // Returns a combination of ChangeMask flags
+ unsigned compare(const ActionData &rhs) const;
+
+ QString text;
+ QString name;
+ QString toolTip;
+ PropertySheetIconValue icon;
+ bool checkable;
+ PropertySheetKeySequenceValue keysequence;
+};
+
+inline bool operator==(const ActionData &a1, const ActionData &a2) { return a1.compare(a2) == 0u; }
+inline bool operator!=(const ActionData &a1, const ActionData &a2) { return a1.compare(a2) != 0u; }
+
+class NewActionDialog: public QDialog
+{
+ Q_OBJECT
+public:
+ explicit NewActionDialog(ActionEditor *parent);
+ virtual ~NewActionDialog();
+
+ ActionData actionData() const;
+ void setActionData(const ActionData &d);
+
+ QString actionText() const;
+ QString actionName() const;
+
+private slots:
+ void on_editActionText_textEdited(const QString &text);
+ void on_editObjectName_textEdited(const QString &text);
+ void slotEditToolTip();
+ void slotResetKeySequence();
+
+private:
+ Ui::NewActionDialog *m_ui;
+ ActionEditor *m_actionEditor;
+ bool m_auto_update_object_name;
+
+ void updateButtons();
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // NEWACTIONDIALOG_P_H
diff --git a/src/designer/src/lib/shared/newformwidget.cpp b/src/designer/src/lib/shared/newformwidget.cpp
new file mode 100644
index 000000000..150d97104
--- /dev/null
+++ b/src/designer/src/lib/shared/newformwidget.cpp
@@ -0,0 +1,586 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "newformwidget_p.h"
+#include "ui_newformwidget.h"
+#include "qdesigner_formbuilder_p.h"
+#include "sheet_delegate_p.h"
+#include "widgetdatabase_p.h"
+#include "shared_settings_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDebug>
+#include <QtCore/QByteArray>
+#include <QtCore/QBuffer>
+#include <QtCore/QDir>
+#include <QtCore/QTextStream>
+
+#include <QtGui/QHeaderView>
+#include <QtGui/QTreeWidgetItem>
+#include <QtGui/QPainter>
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+enum { profileComboIndexOffset = 1 };
+enum { debugNewFormWidget = 0 };
+
+enum NewForm_CustomRole {
+ // File name (templates from resources, paths)
+ TemplateNameRole = Qt::UserRole + 100,
+ // Class name (widgets from Widget data base)
+ ClassNameRole = Qt::UserRole + 101
+};
+
+static const char *newFormObjectNameC = "Form";
+
+// Create a form name for an arbitrary class. If it is Qt, qtify it,
+// else return "Form".
+static QString formName(const QString &className)
+{
+ if (!className.startsWith(QLatin1Char('Q')))
+ return QLatin1String(newFormObjectNameC);
+ QString rc = className;
+ rc.remove(0, 1);
+ return rc;
+}
+
+namespace qdesigner_internal {
+
+struct TemplateSize {
+ const char *name;
+ int width;
+ int height;
+};
+
+static const struct TemplateSize templateSizes[] =
+{
+ { QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "Default size"), 0, 0 },
+ { QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "QVGA portrait (240x320)"), 240, 320 },
+ { QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "QVGA landscape (320x240)"), 320, 240 },
+ { QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "VGA portrait (480x640)"), 480, 640 },
+ { QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "VGA landscape (640x480)"), 640, 480 }
+};
+
+/* -------------- NewForm dialog.
+ * Designer takes new form templates from:
+ * 1) Files located in directories specified in resources
+ * 2) Files located in directories specified as user templates
+ * 3) XML from container widgets deemed usable for form templates by the widget
+ * database
+ * 4) XML from custom container widgets deemed usable for form templates by the
+ * widget database
+ *
+ * The widget database provides helper functions to obtain lists of names
+ * and xml for 3,4.
+ *
+ * Fixed-size forms for embedded platforms are obtained as follows:
+ * 1) If the origin is a file:
+ * - Check if the file exists in the subdirectory "/<width>x<height>/" of
+ * the path (currently the case for the dialog box because the button box
+ * needs to be positioned)
+ * - Scale the form using the QWidgetDatabase::scaleFormTemplate routine.
+ * 2) If the origin is XML:
+ * - Scale the form using the QWidgetDatabase::scaleFormTemplate routine.
+ *
+ * The tree widget item roles indicate which type of entry it is
+ * (TemplateNameRole = file name 1,2, ClassNameRole = class name 3,4)
+ */
+
+NewFormWidget::NewFormWidget(QDesignerFormEditorInterface *core, QWidget *parentWidget) :
+ QDesignerNewFormWidgetInterface(parentWidget),
+ m_core(core),
+ m_ui(new Ui::NewFormWidget),
+ m_currentItem(0),
+ m_acceptedItem(0)
+{
+ typedef QList<qdesigner_internal::DeviceProfile> DeviceProfileList;
+
+ m_ui->setupUi(this);
+ m_ui->treeWidget->setItemDelegate(new qdesigner_internal::SheetDelegate(m_ui->treeWidget, this));
+ m_ui->treeWidget->header()->hide();
+ m_ui->treeWidget->header()->setStretchLastSection(true);
+ m_ui->lblPreview->setBackgroundRole(QPalette::Base);
+ QDesignerSharedSettings settings(m_core);
+
+ QString uiExtension = QLatin1String("ui");
+ QString templatePath = QLatin1String(":/trolltech/designer/templates/forms");
+
+ QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core);
+ if (lang) {
+ templatePath = QLatin1String(":/templates/forms");
+ uiExtension = lang->uiExtension();
+ }
+
+ // Resource templates
+ const QString formTemplate = settings.formTemplate();
+ QTreeWidgetItem *selectedItem = 0;
+ loadFrom(templatePath, true, uiExtension, formTemplate, selectedItem);
+ // Additional template paths
+ const QStringList formTemplatePaths = settings.formTemplatePaths();
+ const QStringList::const_iterator ftcend = formTemplatePaths.constEnd();
+ for (QStringList::const_iterator it = formTemplatePaths.constBegin(); it != ftcend; ++it)
+ loadFrom(*it, false, uiExtension, formTemplate, selectedItem);
+
+ // Widgets/custom widgets
+ if (!lang) {
+ //: New Form Dialog Categories
+ loadFrom(tr("Widgets"), qdesigner_internal::WidgetDataBase::formWidgetClasses(core), formTemplate, selectedItem);
+ loadFrom(tr("Custom Widgets"), qdesigner_internal::WidgetDataBase::customFormWidgetClasses(core), formTemplate, selectedItem);
+ }
+
+ // Still no selection - default to first item
+ if (selectedItem == 0 && m_ui->treeWidget->topLevelItemCount() != 0) {
+ QTreeWidgetItem *firstTopLevel = m_ui->treeWidget->topLevelItem(0);
+ if (firstTopLevel->childCount() > 0)
+ selectedItem = firstTopLevel->child(0);
+ }
+
+ // Open parent, select and make visible
+ if (selectedItem) {
+ m_ui->treeWidget->setCurrentItem(selectedItem);
+ m_ui->treeWidget->setItemSelected(selectedItem, true);
+ m_ui->treeWidget->scrollToItem(selectedItem->parent());
+ }
+ // Fill profile combo
+ m_deviceProfiles = settings.deviceProfiles();
+ m_ui->profileComboBox->addItem(tr("None"));
+ connect(m_ui->profileComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDeviceProfileIndexChanged(int)));
+ if (m_deviceProfiles.empty()) {
+ m_ui->profileComboBox->setEnabled(false);
+ } else {
+ const DeviceProfileList::const_iterator dcend = m_deviceProfiles.constEnd();
+ for (DeviceProfileList::const_iterator it = m_deviceProfiles.constBegin(); it != dcend; ++it)
+ m_ui->profileComboBox->addItem(it->name());
+ const int ci = settings.currentDeviceProfileIndex();
+ if (ci >= 0)
+ m_ui->profileComboBox->setCurrentIndex(ci + profileComboIndexOffset);
+ }
+ // Fill size combo
+ const int sizeCount = sizeof(templateSizes)/ sizeof(TemplateSize);
+ for (int i = 0; i < sizeCount; i++) {
+ const QSize size = QSize(templateSizes[i].width, templateSizes[i].height);
+ m_ui->sizeComboBox->addItem(tr(templateSizes[i].name), size);
+ }
+
+ setTemplateSize(settings.newFormSize());
+
+ if (debugNewFormWidget)
+ qDebug() << Q_FUNC_INFO << "Leaving";
+}
+
+NewFormWidget::~NewFormWidget()
+{
+ QDesignerSharedSettings settings (m_core);
+ settings.setNewFormSize(templateSize());
+ // Do not change previously stored item if dialog was rejected
+ if (m_acceptedItem)
+ settings.setFormTemplate(m_acceptedItem->text(0));
+ delete m_ui;
+}
+
+void NewFormWidget::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *)
+{
+ if (debugNewFormWidget)
+ qDebug() << Q_FUNC_INFO << current;
+ if (!current)
+ return;
+
+ if (!current->parent()) { // Top level item: Ensure expanded when browsing down
+ return;
+ }
+
+ m_currentItem = current;
+
+ emit currentTemplateChanged(showCurrentItemPixmap());
+}
+
+bool NewFormWidget::showCurrentItemPixmap()
+{
+ bool rc = false;
+ if (m_currentItem) {
+ const QPixmap pixmap = formPreviewPixmap(m_currentItem);
+ if (pixmap.isNull()) {
+ m_ui->lblPreview->setText(tr("Error loading form"));
+ } else {
+ m_ui->lblPreview->setPixmap(pixmap);
+ rc = true;
+ }
+ }
+ return rc;
+}
+
+void NewFormWidget::on_treeWidget_itemActivated(QTreeWidgetItem *item)
+{
+ if (debugNewFormWidget)
+ qDebug() << Q_FUNC_INFO << item;
+
+ if (item->data(0, TemplateNameRole).isValid() || item->data(0, ClassNameRole).isValid())
+ emit templateActivated();
+}
+
+QPixmap NewFormWidget::formPreviewPixmap(const QTreeWidgetItem *item)
+{
+ // Cache pixmaps per item/device profile
+ const ItemPixmapCacheKey cacheKey(item, profileComboIndex());
+ ItemPixmapCache::iterator it = m_itemPixmapCache.find(cacheKey);
+ if (it == m_itemPixmapCache.end()) {
+ // file or string?
+ const QVariant fileName = item->data(0, TemplateNameRole);
+ QPixmap rc;
+ if (fileName.type() == QVariant::String) {
+ rc = formPreviewPixmap(fileName.toString());
+ } else {
+ const QVariant classNameV = item->data(0, ClassNameRole);
+ Q_ASSERT(classNameV.type() == QVariant::String);
+ const QString className = classNameV.toString();
+ QByteArray data = qdesigner_internal::WidgetDataBase::formTemplate(m_core, className, formName(className)).toUtf8();
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+ rc = formPreviewPixmap(buffer);
+ }
+ if (rc.isNull()) // Retry invalid ones
+ return rc;
+ it = m_itemPixmapCache.insert(cacheKey, rc);
+ }
+ return it.value();
+}
+
+QPixmap NewFormWidget::formPreviewPixmap(const QString &fileName) const
+{
+ QFile f(fileName);
+ if (f.open(QFile::ReadOnly)) {
+ QFileInfo fi(fileName);
+ const QPixmap rc = formPreviewPixmap(f, fi.absolutePath());
+ f.close();
+ return rc;
+ }
+ qWarning() << "The file " << fileName << " could not be opened: " << f.errorString();
+ return QPixmap();
+}
+
+QImage NewFormWidget::grabForm(QDesignerFormEditorInterface *core,
+ QIODevice &file,
+ const QString &workingDir,
+ const qdesigner_internal::DeviceProfile &dp)
+{
+ qdesigner_internal::NewFormWidgetFormBuilder
+ formBuilder(core, qdesigner_internal::QDesignerFormBuilder::DisableScripts, dp);
+ if (!workingDir.isEmpty())
+ formBuilder.setWorkingDirectory(workingDir);
+
+ QWidget *widget = formBuilder.load(&file, 0);
+ if (!widget)
+ return QImage();
+
+ const QPixmap pixmap = QPixmap::grabWidget(widget);
+ widget->deleteLater();
+ return pixmap.toImage();
+}
+
+QPixmap NewFormWidget::formPreviewPixmap(QIODevice &file, const QString &workingDir) const
+{
+ const int margin = 7;
+ const int shadow = 7;
+ const int previewSize = 256;
+
+ const QImage wimage = grabForm(m_core, file, workingDir, currentDeviceProfile());
+ if (wimage.isNull())
+ return QPixmap();
+ const QImage image = wimage.scaled(previewSize - margin * 2, previewSize - margin * 2,
+ Qt::KeepAspectRatio,
+ Qt::SmoothTransformation);
+
+ QImage dest(previewSize, previewSize, QImage::Format_ARGB32_Premultiplied);
+ dest.fill(0);
+
+ QPainter p(&dest);
+ p.drawImage(margin, margin, image);
+
+ p.setPen(QPen(palette().brush(QPalette::WindowText), 0));
+
+ p.drawRect(margin-1, margin-1, image.width() + 1, image.height() + 1);
+
+ const QColor dark(Qt::darkGray);
+ const QColor light(Qt::transparent);
+
+ // right shadow
+ {
+ const QRect rect(margin + image.width() + 1, margin + shadow, shadow, image.height() - shadow + 1);
+ QLinearGradient lg(rect.topLeft(), rect.topRight());
+ lg.setColorAt(0, dark);
+ lg.setColorAt(1, light);
+ p.fillRect(rect, lg);
+ }
+
+ // bottom shadow
+ {
+ const QRect rect(margin + shadow, margin + image.height() + 1, image.width() - shadow + 1, shadow);
+ QLinearGradient lg(rect.topLeft(), rect.bottomLeft());
+ lg.setColorAt(0, dark);
+ lg.setColorAt(1, light);
+ p.fillRect(rect, lg);
+ }
+
+ // bottom/right corner shadow
+ {
+ const QRect rect(margin + image.width() + 1, margin + image.height() + 1, shadow, shadow);
+ QRadialGradient g(rect.topLeft(), shadow);
+ g.setColorAt(0, dark);
+ g.setColorAt(1, light);
+ p.fillRect(rect, g);
+ }
+
+ // top/right corner
+ {
+ const QRect rect(margin + image.width() + 1, margin, shadow, shadow);
+ QRadialGradient g(rect.bottomLeft(), shadow);
+ g.setColorAt(0, dark);
+ g.setColorAt(1, light);
+ p.fillRect(rect, g);
+ }
+
+ // bottom/left corner
+ {
+ const QRect rect(margin, margin + image.height() + 1, shadow, shadow);
+ QRadialGradient g(rect.topRight(), shadow);
+ g.setColorAt(0, dark);
+ g.setColorAt(1, light);
+ p.fillRect(rect, g);
+ }
+
+ p.end();
+
+ return QPixmap::fromImage(dest);
+}
+
+void NewFormWidget::loadFrom(const QString &path, bool resourceFile, const QString &uiExtension,
+ const QString &selectedItem, QTreeWidgetItem *&selectedItemFound)
+{
+ const QDir dir(path);
+
+ if (!dir.exists())
+ return;
+
+ // Iterate through the directory and add the templates
+ const QFileInfoList list = dir.entryInfoList(QStringList(QLatin1String("*.") + uiExtension),
+ QDir::Files);
+
+ if (list.isEmpty())
+ return;
+
+ const QChar separator = resourceFile ? QChar(QLatin1Char('/'))
+ : QDir::separator();
+ QTreeWidgetItem *root = new QTreeWidgetItem(m_ui->treeWidget);
+ root->setFlags(root->flags() & ~Qt::ItemIsSelectable);
+ // Try to get something that is easy to read.
+ QString visiblePath = path;
+ int index = visiblePath.lastIndexOf(separator);
+ if (index != -1) {
+ // try to find a second slash, just to be a bit better.
+ const int index2 = visiblePath.lastIndexOf(separator, index - 1);
+ if (index2 != -1)
+ index = index2;
+ visiblePath = visiblePath.mid(index + 1);
+ visiblePath = QDir::toNativeSeparators(visiblePath);
+ }
+
+ const QChar underscore = QLatin1Char('_');
+ const QChar blank = QLatin1Char(' ');
+ root->setText(0, visiblePath.replace(underscore, blank));
+ root->setToolTip(0, path);
+
+ const QFileInfoList::const_iterator lcend = list.constEnd();
+ for (QFileInfoList::const_iterator it = list.constBegin(); it != lcend; ++it) {
+ if (!it->isFile())
+ continue;
+
+ QTreeWidgetItem *item = new QTreeWidgetItem(root);
+ const QString text = it->baseName().replace(underscore, blank);
+ if (selectedItemFound == 0 && text == selectedItem)
+ selectedItemFound = item;
+ item->setText(0, text);
+ item->setData(0, TemplateNameRole, it->absoluteFilePath());
+ }
+}
+
+void NewFormWidget::loadFrom(const QString &title, const QStringList &nameList,
+ const QString &selectedItem, QTreeWidgetItem *&selectedItemFound)
+{
+ if (nameList.empty())
+ return;
+ QTreeWidgetItem *root = new QTreeWidgetItem(m_ui->treeWidget);
+ root->setFlags(root->flags() & ~Qt::ItemIsSelectable);
+ root->setText(0, title);
+ const QStringList::const_iterator cend = nameList.constEnd();
+ for (QStringList::const_iterator it = nameList.constBegin(); it != cend; ++it) {
+ const QString text = *it;
+ QTreeWidgetItem *item = new QTreeWidgetItem(root);
+ item->setText(0, text);
+ if (selectedItemFound == 0 && text == selectedItem)
+ selectedItemFound = item;
+ item->setData(0, ClassNameRole, *it);
+ }
+}
+
+void NewFormWidget::on_treeWidget_itemPressed(QTreeWidgetItem *item)
+{
+ if (item && !item->parent())
+ m_ui->treeWidget->setItemExpanded(item, !m_ui->treeWidget->isItemExpanded(item));
+}
+
+QSize NewFormWidget::templateSize() const
+{
+ return m_ui->sizeComboBox->itemData(m_ui->sizeComboBox->currentIndex()).toSize();
+}
+
+void NewFormWidget::setTemplateSize(const QSize &s)
+{
+ const int index = s.isNull() ? 0 : m_ui->sizeComboBox->findData(s);
+ if (index != -1)
+ m_ui->sizeComboBox->setCurrentIndex(index);
+}
+
+static QString readAll(const QString &fileName, QString *errorMessage)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
+ *errorMessage = NewFormWidget::tr("Unable to open the form template file '%1': %2").arg(fileName, file.errorString());
+ return QString();
+ }
+ return QString::fromUtf8(file.readAll());
+}
+
+QString NewFormWidget::itemToTemplate(const QTreeWidgetItem *item, QString *errorMessage) const
+{
+ const QSize size = templateSize();
+ // file name or string contents?
+ const QVariant templateFileName = item->data(0, TemplateNameRole);
+ if (templateFileName.type() == QVariant::String) {
+ const QString fileName = templateFileName.toString();
+ // No fixed size: just open.
+ if (size.isNull())
+ return readAll(fileName, errorMessage);
+ // try to find a file matching the size, like "../640x480/xx.ui"
+ const QFileInfo fiBase(fileName);
+ QString sizeFileName;
+ QTextStream(&sizeFileName) << fiBase.path() << QDir::separator()
+ << size.width() << QLatin1Char('x') << size.height() << QDir::separator()
+ << fiBase.fileName();
+ if (QFileInfo(sizeFileName).isFile())
+ return readAll(sizeFileName, errorMessage);
+ // Nothing found, scale via DOM/temporary file
+ QString contents = readAll(fileName, errorMessage);
+ if (!contents.isEmpty())
+ contents = qdesigner_internal::WidgetDataBase::scaleFormTemplate(contents, size, false);
+ return contents;
+ }
+ // Content.
+ const QString className = item->data(0, ClassNameRole).toString();
+ QString contents = qdesigner_internal::WidgetDataBase::formTemplate(m_core, className, formName(className));
+ if (!size.isNull())
+ contents = qdesigner_internal::WidgetDataBase::scaleFormTemplate(contents, size, false);
+ return contents;
+}
+
+void NewFormWidget::slotDeviceProfileIndexChanged(int idx)
+{
+ // Store index for form windows to take effect and refresh pixmap
+ QDesignerSharedSettings settings(m_core);
+ settings.setCurrentDeviceProfileIndex(idx - profileComboIndexOffset);
+ showCurrentItemPixmap();
+}
+
+int NewFormWidget::profileComboIndex() const
+{
+ return m_ui->profileComboBox->currentIndex();
+}
+
+qdesigner_internal::DeviceProfile NewFormWidget::currentDeviceProfile() const
+{
+ const int ci = profileComboIndex();
+ if (ci > 0)
+ return m_deviceProfiles.at(ci - profileComboIndexOffset);
+ return qdesigner_internal::DeviceProfile();
+}
+
+bool NewFormWidget::hasCurrentTemplate() const
+{
+ return m_currentItem != 0;
+}
+
+QString NewFormWidget::currentTemplateI(QString *ptrToErrorMessage)
+{
+ if (m_currentItem == 0) {
+ *ptrToErrorMessage = tr("Internal error: No template selected.");
+ return QString();
+ }
+ const QString contents = itemToTemplate(m_currentItem, ptrToErrorMessage);
+ if (contents.isEmpty())
+ return contents;
+
+ m_acceptedItem = m_currentItem;
+ return contents;
+}
+
+QString NewFormWidget::currentTemplate(QString *ptrToErrorMessage)
+{
+ if (ptrToErrorMessage)
+ return currentTemplateI(ptrToErrorMessage);
+ // Do not loose the error
+ QString errorMessage;
+ const QString contents = currentTemplateI(&errorMessage);
+ if (!errorMessage.isEmpty())
+ qWarning("%s", errorMessage.toUtf8().constData());
+ return contents;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/newformwidget.ui b/src/designer/src/lib/shared/newformwidget.ui
new file mode 100644
index 000000000..830057c0e
--- /dev/null
+++ b/src/designer/src/lib/shared/newformwidget.ui
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::NewFormWidget</class>
+ <widget class="QWidget" name="qdesigner_internal::NewFormWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>480</width>
+ <height>194</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>1</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="treeWidget">
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>128</width>
+ <height>128</height>
+ </size>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="columnCount">
+ <number>1</number>
+ </property>
+ <column>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="lblPreview">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="text">
+ <string>Choose a template for a preview</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>7</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="embeddedGroup">
+ <property name="title">
+ <string>Embedded Design</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="1">
+ <widget class="QComboBox" name="profileComboBox"/>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="sizeComboBox"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Device:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Screen Size:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/lib/shared/newformwidget_p.h b/src/designer/src/lib/shared/newformwidget_p.h
new file mode 100644
index 000000000..940b11ce9
--- /dev/null
+++ b/src/designer/src/lib/shared/newformwidget_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEWFORMWIDGET_H
+#define NEWFORMWIDGET_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "shared_global_p.h"
+#include "deviceprofile_p.h"
+
+#include <abstractnewformwidget_p.h>
+
+#include <QtGui/QWidget>
+#include <QtGui/QPixmap>
+
+#include <QtCore/QStringList>
+#include <QtCore/QPair>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+class QTreeWidgetItem;
+
+namespace qdesigner_internal {
+
+namespace Ui {
+ class NewFormWidget;
+}
+
+class QDesignerWorkbench;
+
+class QDESIGNER_SHARED_EXPORT NewFormWidget : public QDesignerNewFormWidgetInterface
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(NewFormWidget)
+
+public:
+ typedef QList<qdesigner_internal::DeviceProfile> DeviceProfileList;
+
+ explicit NewFormWidget(QDesignerFormEditorInterface *core, QWidget *parentWidget);
+ virtual ~NewFormWidget();
+
+ virtual bool hasCurrentTemplate() const;
+ virtual QString currentTemplate(QString *errorMessage = 0);
+
+ // Convenience for implementing file dialogs with preview
+ static QImage grabForm(QDesignerFormEditorInterface *core,
+ QIODevice &file,
+ const QString &workingDir,
+ const qdesigner_internal::DeviceProfile &dp);
+
+private slots:
+ void on_treeWidget_itemActivated(QTreeWidgetItem *item);
+ void on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *);
+ void on_treeWidget_itemPressed(QTreeWidgetItem *item);
+ void slotDeviceProfileIndexChanged(int idx);
+
+private:
+ QPixmap formPreviewPixmap(const QString &fileName) const;
+ QPixmap formPreviewPixmap(QIODevice &file, const QString &workingDir = QString()) const;
+ QPixmap formPreviewPixmap(const QTreeWidgetItem *item);
+
+ void loadFrom(const QString &path, bool resourceFile, const QString &uiExtension,
+ const QString &selectedItem, QTreeWidgetItem *&selectedItemFound);
+ void loadFrom(const QString &title, const QStringList &nameList,
+ const QString &selectedItem, QTreeWidgetItem *&selectedItemFound);
+
+private:
+ QString itemToTemplate(const QTreeWidgetItem *item, QString *errorMessage) const;
+ QString currentTemplateI(QString *ptrToErrorMessage);
+
+ QSize templateSize() const;
+ void setTemplateSize(const QSize &s);
+ int profileComboIndex() const;
+ qdesigner_internal::DeviceProfile currentDeviceProfile() const;
+ bool showCurrentItemPixmap();
+
+ // Pixmap cache (item, profile combo index)
+ typedef QPair<const QTreeWidgetItem *, int> ItemPixmapCacheKey;
+ typedef QMap<ItemPixmapCacheKey, QPixmap> ItemPixmapCache;
+ ItemPixmapCache m_itemPixmapCache;
+
+ QDesignerFormEditorInterface *m_core;
+ Ui::NewFormWidget *m_ui;
+ QTreeWidgetItem *m_currentItem;
+ QTreeWidgetItem *m_acceptedItem;
+ DeviceProfileList m_deviceProfiles;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // NEWFORMWIDGET_H
diff --git a/src/designer/src/lib/shared/orderdialog.cpp b/src/designer/src/lib/shared/orderdialog.cpp
new file mode 100644
index 000000000..e992fdd34
--- /dev/null
+++ b/src/designer/src/lib/shared/orderdialog.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "orderdialog_p.h"
+#include "iconloader_p.h"
+#include "ui_orderdialog.h"
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QModelIndex>
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+// OrderDialog: Used to reorder the pages of QStackedWidget and QToolBox.
+// Provides up and down buttons as well as DnD via QAbstractItemView::InternalMove mode
+namespace qdesigner_internal {
+
+OrderDialog::OrderDialog(QWidget *parent) :
+ QDialog(parent),
+ m_ui(new Ui::OrderDialog),
+ m_format(PageOrderFormat)
+{
+ m_ui->setupUi(this);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ m_ui->upButton->setIcon(createIconSet(QString::fromUtf8("up.png")));
+ m_ui->downButton->setIcon(createIconSet(QString::fromUtf8("down.png")));
+ m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+ connect(m_ui->buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), this, SLOT(slotReset()));
+ // Catch the remove operation of a DnD operation in QAbstractItemView::InternalMove mode to enable buttons
+ // Selection mode is 'contiguous' to enable DnD of groups
+ connect(m_ui->pageList->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(slotEnableButtonsAfterDnD()));
+
+ m_ui->upButton->setEnabled(false);
+ m_ui->downButton->setEnabled(false);
+}
+
+OrderDialog::~OrderDialog()
+{
+ delete m_ui;
+}
+
+void OrderDialog::setDescription(const QString &d)
+{
+ m_ui->groupBox->setTitle(d);
+}
+
+void OrderDialog::setPageList(const QWidgetList &pages)
+{
+ // The QWidget* are stored in a map indexed by the old index.
+ // The old index is set as user data on the item instead of the QWidget*
+ // because DnD is enabled which requires the user data to serializable
+ m_orderMap.clear();
+ const int count = pages.count();
+ for (int i=0; i < count; ++i)
+ m_orderMap.insert(i, pages.at(i));
+ buildList();
+}
+
+void OrderDialog::buildList()
+{
+ m_ui->pageList->clear();
+ const OrderMap::const_iterator cend = m_orderMap.constEnd();
+ for (OrderMap::const_iterator it = m_orderMap.constBegin(); it != cend; ++it) {
+ QListWidgetItem *item = new QListWidgetItem();
+ const int index = it.key();
+ switch (m_format) {
+ case PageOrderFormat:
+ item->setText(tr("Index %1 (%2)").arg(index).arg(it.value()->objectName()));
+ break;
+ case TabOrderFormat:
+ item->setText(tr("%1 %2").arg(index+1).arg(it.value()->objectName()));
+ break;
+ }
+ item->setData(Qt::UserRole, QVariant(index));
+ m_ui->pageList->addItem(item);
+ }
+
+ if (m_ui->pageList->count() > 0)
+ m_ui->pageList->setCurrentRow(0);
+}
+
+void OrderDialog::slotReset()
+{
+ buildList();
+}
+
+QWidgetList OrderDialog::pageList() const
+{
+ QWidgetList rc;
+ const int count = m_ui->pageList->count();
+ for (int i=0; i < count; ++i) {
+ const int oldIndex = m_ui->pageList->item(i)->data(Qt::UserRole).toInt();
+ rc.append(m_orderMap.value(oldIndex));
+ }
+ return rc;
+}
+
+void OrderDialog::on_upButton_clicked()
+{
+ const int row = m_ui->pageList->currentRow();
+ if (row <= 0)
+ return;
+
+ m_ui->pageList->insertItem(row - 1, m_ui->pageList->takeItem(row));
+ m_ui->pageList->setCurrentRow(row - 1);
+}
+
+void OrderDialog::on_downButton_clicked()
+{
+ const int row = m_ui->pageList->currentRow();
+ if (row == -1 || row == m_ui->pageList->count() - 1)
+ return;
+
+ m_ui->pageList->insertItem(row + 1, m_ui->pageList->takeItem(row));
+ m_ui->pageList->setCurrentRow(row + 1);
+}
+
+void OrderDialog::slotEnableButtonsAfterDnD()
+{
+ enableButtons(m_ui->pageList->currentRow());
+}
+
+void OrderDialog::on_pageList_currentRowChanged(int r)
+{
+ enableButtons(r);
+}
+
+void OrderDialog::enableButtons(int r)
+{
+ m_ui->upButton->setEnabled(r > 0);
+ m_ui->downButton->setEnabled(r >= 0 && r < m_ui->pageList->count() - 1);
+}
+
+QWidgetList OrderDialog::pagesOfContainer(const QDesignerFormEditorInterface *core, QWidget *container)
+{
+ QWidgetList rc;
+ if (QDesignerContainerExtension* ce = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), container)) {
+ const int count = ce->count();
+ for (int i = 0; i < count ;i ++)
+ rc.push_back(ce->widget(i));
+ }
+ return rc;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/orderdialog.ui b/src/designer/src/lib/shared/orderdialog.ui
new file mode 100644
index 000000000..ae9a73488
--- /dev/null
+++ b/src/designer/src/lib/shared/orderdialog.ui
@@ -0,0 +1,198 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>qdesigner_internal::OrderDialog</class>
+ <widget class="QDialog" name="qdesigner_internal::OrderDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>467</width>
+ <height>310</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Change Page Order</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Page Order</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="pageList" >
+ <property name="minimumSize" >
+ <size>
+ <width>344</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="dragDropMode" >
+ <enum>QAbstractItemView::InternalMove</enum>
+ </property>
+ <property name="selectionMode" >
+ <enum>QAbstractItemView::ContiguousSelection</enum>
+ </property>
+ <property name="movement" >
+ <enum>QListView::Snap</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="upButton" >
+ <property name="toolTip" >
+ <string>Move page up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="downButton" >
+ <property name="toolTip" >
+ <string>Move page down</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>99</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>qdesigner_internal::OrderDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>50</x>
+ <y>163</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>6</x>
+ <y>151</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>qdesigner_internal::OrderDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>300</x>
+ <y>160</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>348</x>
+ <y>148</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/orderdialog_p.h b/src/designer/src/lib/shared/orderdialog_p.h
new file mode 100644
index 000000000..00d76fb15
--- /dev/null
+++ b/src/designer/src/lib/shared/orderdialog_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ORDERDIALOG_P_H
+#define ORDERDIALOG_P_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QDialog>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+namespace Ui {
+ class OrderDialog;
+}
+
+class QDESIGNER_SHARED_EXPORT OrderDialog: public QDialog
+{
+ Q_OBJECT
+public:
+ OrderDialog(QWidget *parent);
+ virtual ~OrderDialog();
+
+ static QWidgetList pagesOfContainer(const QDesignerFormEditorInterface *core, QWidget *container);
+
+ void setPageList(const QWidgetList &pages);
+ QWidgetList pageList() const;
+
+ void setDescription(const QString &d);
+
+ enum Format { // Display format
+ PageOrderFormat, // Container pages, ranging 0..[n-1]
+ TabOrderFormat // List of widgets, ranging 1..1
+ };
+
+ void setFormat(Format f) { m_format = f; }
+ Format format() const { return m_format; }
+
+private slots:
+ void on_upButton_clicked();
+ void on_downButton_clicked();
+ void on_pageList_currentRowChanged(int row);
+ void slotEnableButtonsAfterDnD();
+ void slotReset();
+
+private:
+ void buildList();
+ void enableButtons(int r);
+
+ typedef QMap<int, QWidget*> OrderMap;
+ OrderMap m_orderMap;
+ Ui::OrderDialog* m_ui;
+ Format m_format;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // ORDERDIALOG_P_H
diff --git a/src/designer/src/lib/shared/plaintexteditor.cpp b/src/designer/src/lib/shared/plaintexteditor.cpp
new file mode 100644
index 000000000..748cecc41
--- /dev/null
+++ b/src/designer/src/lib/shared/plaintexteditor.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "plaintexteditor_p.h"
+#include "abstractsettings_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QPlainTextEdit>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+static const char *PlainTextDialogC = "PlainTextDialog";
+static const char *Geometry = "Geometry";
+
+
+namespace qdesigner_internal {
+
+PlainTextEditorDialog::PlainTextEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QDialog(parent),
+ m_editor(new QPlainTextEdit),
+ m_core(core)
+{
+ setWindowTitle(tr("Edit text"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ QVBoxLayout *vlayout = new QVBoxLayout(this);
+ vlayout->addWidget(m_editor);
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
+ QPushButton *ok_button = buttonBox->button(QDialogButtonBox::Ok);
+ ok_button->setDefault(true);
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ vlayout->addWidget(buttonBox);
+
+ QDesignerSettingsInterface *settings = core->settingsManager();
+ settings->beginGroup(QLatin1String(PlainTextDialogC));
+
+ if (settings->contains(QLatin1String(Geometry)))
+ restoreGeometry(settings->value(QLatin1String(Geometry)).toByteArray());
+
+ settings->endGroup();
+}
+
+PlainTextEditorDialog::~PlainTextEditorDialog()
+{
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->beginGroup(QLatin1String(PlainTextDialogC));
+
+ settings->setValue(QLatin1String(Geometry), saveGeometry());
+ settings->endGroup();
+}
+
+int PlainTextEditorDialog::showDialog()
+{
+ m_editor->setFocus();
+ return exec();
+}
+
+void PlainTextEditorDialog::setDefaultFont(const QFont &font)
+{
+ m_editor->setFont(font);
+}
+
+void PlainTextEditorDialog::setText(const QString &text)
+{
+ m_editor->setPlainText(text);
+}
+
+QString PlainTextEditorDialog::text() const
+{
+ return m_editor->toPlainText();
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/plaintexteditor_p.h b/src/designer/src/lib/shared/plaintexteditor_p.h
new file mode 100644
index 000000000..830207bbd
--- /dev/null
+++ b/src/designer/src/lib/shared/plaintexteditor_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PLAINTEXTEDITOR_H
+#define PLAINTEXTEDITOR_H
+
+#include <QtGui/QDialog>
+#include "shared_global_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QPlainTextEdit;
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT PlainTextEditorDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit PlainTextEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ ~PlainTextEditorDialog();
+
+ int showDialog();
+
+ void setDefaultFont(const QFont &font);
+
+ void setText(const QString &text);
+ QString text() const;
+
+private:
+ QPlainTextEdit *m_editor;
+ QDesignerFormEditorInterface *m_core;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // RITCHTEXTEDITOR_H
diff --git a/src/designer/src/lib/shared/plugindialog.cpp b/src/designer/src/lib/shared/plugindialog.cpp
new file mode 100644
index 000000000..9b1212b39
--- /dev/null
+++ b/src/designer/src/lib/shared/plugindialog.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "plugindialog_p.h"
+#include "pluginmanager_p.h"
+#include "qdesigner_integration_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerCustomWidgetCollectionInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+
+#include <QtGui/QStyle>
+#include <QtGui/QHeaderView>
+#include <QtGui/QPushButton>
+#include <QtCore/QFileInfo>
+#include <QtCore/QPluginLoader>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+PluginDialog::PluginDialog(QDesignerFormEditorInterface *core, QWidget *parent)
+ : QDialog(parent
+#ifdef Q_WS_MAC
+ , Qt::Tool
+#endif
+ ), m_core(core)
+{
+ ui.setupUi(this);
+
+ ui.message->hide();
+
+ const QStringList headerLabels(tr("Components"));
+
+ ui.treeWidget->setAlternatingRowColors(false);
+ ui.treeWidget->setSelectionMode(QAbstractItemView::NoSelection);
+ ui.treeWidget->setHeaderLabels(headerLabels);
+ ui.treeWidget->header()->hide();
+
+ interfaceIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirOpenIcon),
+ QIcon::Normal, QIcon::On);
+ interfaceIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon),
+ QIcon::Normal, QIcon::Off);
+ featureIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
+
+ setWindowTitle(tr("Plugin Information"));
+ populateTreeWidget();
+
+ if (qobject_cast<qdesigner_internal::QDesignerIntegration *>(m_core->integration())) {
+ QPushButton *updateButton = new QPushButton(tr("Refresh"));
+ const QString tooltip = tr("Scan for newly installed custom widget plugins.");
+ updateButton->setToolTip(tooltip);
+ updateButton->setWhatsThis(tooltip);
+ connect(updateButton, SIGNAL(clicked()), this, SLOT(updateCustomWidgetPlugins()));
+ ui.buttonBox->addButton(updateButton, QDialogButtonBox::ActionRole);
+ }
+}
+
+void PluginDialog::populateTreeWidget()
+{
+ ui.treeWidget->clear();
+ QDesignerPluginManager *pluginManager = m_core->pluginManager();
+ const QStringList fileNames = pluginManager->registeredPlugins();
+
+ if (!fileNames.isEmpty()) {
+ QTreeWidgetItem *topLevelItem = setTopLevelItem(tr("Loaded Plugins"));
+ QFont boldFont = topLevelItem->font(0);
+
+ foreach (const QString &fileName, fileNames) {
+ QPluginLoader loader(fileName);
+ const QFileInfo fileInfo(fileName);
+
+ QTreeWidgetItem *pluginItem = setPluginItem(topLevelItem, fileInfo.fileName(), boldFont);
+
+ if (QObject *plugin = loader.instance()) {
+ if (const QDesignerCustomWidgetCollectionInterface *c = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(plugin)) {
+ foreach (const QDesignerCustomWidgetInterface *p, c->customWidgets())
+ setItem(pluginItem, p->name(), p->toolTip(), p->whatsThis(), p->icon());
+ } else {
+ if (const QDesignerCustomWidgetInterface *p = qobject_cast<QDesignerCustomWidgetInterface*>(plugin))
+ setItem(pluginItem, p->name(), p->toolTip(), p->whatsThis(), p->icon());
+ }
+ }
+ }
+ }
+
+ const QStringList notLoadedPlugins = pluginManager->failedPlugins();
+ if (!notLoadedPlugins.isEmpty()) {
+ QTreeWidgetItem *topLevelItem = setTopLevelItem(tr("Failed Plugins"));
+ const QFont boldFont = topLevelItem->font(0);
+ foreach (const QString &plugin, notLoadedPlugins) {
+ const QString failureReason = pluginManager->failureReason(plugin);
+ QTreeWidgetItem *pluginItem = setPluginItem(topLevelItem, plugin, boldFont);
+ setItem(pluginItem, failureReason, failureReason, QString(), QIcon());
+ }
+ }
+
+ if (ui.treeWidget->topLevelItemCount() == 0) {
+ ui.label->setText(tr("Qt Designer couldn't find any plugins"));
+ ui.treeWidget->hide();
+ } else {
+ ui.label->setText(tr("Qt Designer found the following plugins"));
+ }
+}
+
+QIcon PluginDialog::pluginIcon(const QIcon &icon)
+{
+ if (icon.isNull())
+ return QIcon(QLatin1String(":/trolltech/formeditor/images/qtlogo.png"));
+
+ return icon;
+}
+
+QTreeWidgetItem* PluginDialog::setTopLevelItem(const QString &itemName)
+{
+ QTreeWidgetItem *topLevelItem = new QTreeWidgetItem(ui.treeWidget);
+ topLevelItem->setText(0, itemName);
+ ui.treeWidget->setItemExpanded(topLevelItem, true);
+ topLevelItem->setIcon(0, style()->standardPixmap(QStyle::SP_DirOpenIcon));
+
+ QFont boldFont = topLevelItem->font(0);
+ boldFont.setBold(true);
+ topLevelItem->setFont(0, boldFont);
+
+ return topLevelItem;
+}
+
+QTreeWidgetItem* PluginDialog::setPluginItem(QTreeWidgetItem *topLevelItem,
+ const QString &itemName, const QFont &font)
+{
+ QTreeWidgetItem *pluginItem = new QTreeWidgetItem(topLevelItem);
+ pluginItem->setFont(0, font);
+ pluginItem->setText(0, itemName);
+ ui.treeWidget->setItemExpanded(pluginItem, true);
+ pluginItem->setIcon(0, style()->standardPixmap(QStyle::SP_DirOpenIcon));
+
+ return pluginItem;
+}
+
+void PluginDialog::setItem(QTreeWidgetItem *pluginItem, const QString &name,
+ const QString &toolTip, const QString &whatsThis, const QIcon &icon)
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(pluginItem);
+ item->setText(0, name);
+ item->setToolTip(0, toolTip);
+ item->setWhatsThis(0, whatsThis);
+ item->setIcon(0, pluginIcon(icon));
+}
+
+void PluginDialog::updateCustomWidgetPlugins()
+{
+ if (qdesigner_internal::QDesignerIntegration *integration = qobject_cast<qdesigner_internal::QDesignerIntegration *>(m_core->integration())) {
+ const int before = m_core->widgetDataBase()->count();
+ integration->updateCustomWidgetPlugins();
+ const int after = m_core->widgetDataBase()->count();
+ if (after > before) {
+ ui.message->setText(tr("New custom widget plugins have been found."));
+ ui.message->show();
+ } else {
+ ui.message->setText(QString());
+ }
+ populateTreeWidget();
+ }
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/plugindialog.ui b/src/designer/src/lib/shared/plugindialog.ui
new file mode 100644
index 000000000..50d117082
--- /dev/null
+++ b/src/designer/src/lib/shared/plugindialog.ui
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>PluginDialog</class>
+ <widget class="QDialog" name="PluginDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>401</width>
+ <height>331</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Plugin Information</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string notr="true">TextLabel</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="treeWidget">
+ <property name="textElideMode">
+ <enum>Qt::ElideNone</enum>
+ </property>
+ <column>
+ <property name="text">
+ <string>1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="message">
+ <property name="text">
+ <string notr="true">TextLabel</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>PluginDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>154</x>
+ <y>307</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>401</x>
+ <y>280</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/plugindialog_p.h b/src/designer/src/lib/shared/plugindialog_p.h
new file mode 100644
index 000000000..0027d6e9f
--- /dev/null
+++ b/src/designer/src/lib/shared/plugindialog_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PLUGINDIALOG_H
+#define PLUGINDIALOG_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "ui_plugindialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class PluginDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit PluginDialog(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+
+private slots:
+ void updateCustomWidgetPlugins();
+
+private:
+ void populateTreeWidget();
+ QIcon pluginIcon(const QIcon &icon);
+ QTreeWidgetItem* setTopLevelItem(const QString &itemName);
+ QTreeWidgetItem* setPluginItem(QTreeWidgetItem *topLevelItem,
+ const QString &itemName, const QFont &font);
+ void setItem(QTreeWidgetItem *pluginItem, const QString &name,
+ const QString &toolTip, const QString &whatsThis, const QIcon &icon);
+
+ QDesignerFormEditorInterface *m_core;
+ Ui::PluginDialog ui;
+ QIcon interfaceIcon;
+ QIcon featureIcon;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/shared/pluginmanager.cpp b/src/designer/src/lib/shared/pluginmanager.cpp
new file mode 100644
index 000000000..918fe7d07
--- /dev/null
+++ b/src/designer/src/lib/shared/pluginmanager.cpp
@@ -0,0 +1,786 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pluginmanager_p.h"
+#include "qdesigner_utils_p.h"
+#include "qdesigner_qsettings_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerLanguageExtension>
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSet>
+#include <QtCore/QPluginLoader>
+#include <QtCore/QLibrary>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/qdebug.h>
+#include <QtCore/QMap>
+#include <QtCore/QSettings>
+#include <QtCore/QCoreApplication>
+
+#include <QtCore/QXmlStreamReader>
+#include <QtCore/QXmlStreamAttributes>
+#include <QtCore/QXmlStreamAttribute>
+
+static const char *uiElementC = "ui";
+static const char *languageAttributeC = "language";
+static const char *widgetElementC = "widget";
+static const char *displayNameAttributeC = "displayname";
+static const char *classAttributeC = "class";
+static const char *customwidgetElementC = "customwidget";
+static const char *extendsElementC = "extends";
+static const char *addPageMethodC = "addpagemethod";
+static const char *propertySpecsC = "propertyspecifications";
+static const char *stringPropertySpecC = "stringpropertyspecification";
+static const char *stringPropertyNameAttrC = "name";
+static const char *stringPropertyTypeAttrC = "type";
+static const char *stringPropertyNoTrAttrC = "notr";
+static const char *jambiLanguageC = "jambi";
+
+enum { debugPluginManager = 0 };
+
+/* Custom widgets: Loading custom widgets is a 2-step process: PluginManager
+ * scans for its plugins in the constructor. At this point, it might not be safe
+ * to immediately initialize the custom widgets it finds, because the rest of
+ * Designer is not initialized yet.
+ * Later on, in ensureInitialized(), the plugin instances (including static ones)
+ * are iterated and the custom widget plugins are initialized and added to internal
+ * list of custom widgets and parsed data. Should there be a parse error or a language
+ * mismatch, it kicks out the respective custom widget. The m_initialized flag
+ * is used to indicate the state.
+ * Later, someone might call registerNewPlugins(), which agains clears the flag via
+ * registerPlugin() and triggers the process again.
+ * Also note that Jambi fakes a custom widget collection that changes its contents
+ * every time the project is switched. So, custom widget plugins can actually
+ * disappear, and the custom widget list must be cleared and refilled in
+ * ensureInitialized() after registerNewPlugins. */
+
+QT_BEGIN_NAMESPACE
+
+static QStringList unique(const QStringList &lst)
+{
+ const QSet<QString> s = QSet<QString>::fromList(lst);
+ return s.toList();
+}
+
+QStringList QDesignerPluginManager::defaultPluginPaths()
+{
+ QStringList result;
+
+ const QStringList path_list = QCoreApplication::libraryPaths();
+
+ const QString designer = QLatin1String("designer");
+ foreach (const QString &path, path_list) {
+ QString libPath = path;
+ libPath += QDir::separator();
+ libPath += designer;
+ result.append(libPath);
+ }
+
+ QString homeLibPath = QDir::homePath();
+ homeLibPath += QDir::separator();
+ homeLibPath += QLatin1String(".designer");
+ homeLibPath += QDir::separator();
+ homeLibPath += QLatin1String("plugins");
+
+ result.append(homeLibPath);
+ return result;
+}
+
+// Figure out the language designer is running. ToDo: Introduce some
+// Language name API to QDesignerLanguageExtension?
+
+static inline QString getDesignerLanguage(QDesignerFormEditorInterface *core)
+{
+ if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core)) {
+ if (lang->uiExtension() == QLatin1String("jui"))
+ return QLatin1String(jambiLanguageC);
+ return QLatin1String("unknown");
+ }
+ return QLatin1String("c++");
+}
+
+// ---------------- QDesignerCustomWidgetSharedData
+
+class QDesignerCustomWidgetSharedData : public QSharedData {
+public:
+ // Type of a string property
+ typedef QPair<qdesigner_internal::TextPropertyValidationMode, bool> StringPropertyType;
+ typedef QHash<QString, StringPropertyType> StringPropertyTypeMap;
+
+ explicit QDesignerCustomWidgetSharedData(const QString &thePluginPath) : pluginPath(thePluginPath) {}
+ void clearXML();
+
+ QString pluginPath;
+
+ QString xmlClassName;
+ QString xmlDisplayName;
+ QString xmlLanguage;
+ QString xmlAddPageMethod;
+ QString xmlExtends;
+
+ StringPropertyTypeMap xmlStringPropertyTypeMap;
+};
+
+void QDesignerCustomWidgetSharedData::clearXML()
+{
+ xmlClassName.clear();
+ xmlDisplayName.clear();
+ xmlLanguage.clear();
+ xmlAddPageMethod.clear();
+ xmlExtends.clear();
+ xmlStringPropertyTypeMap.clear();
+}
+
+// ---------------- QDesignerCustomWidgetData
+
+QDesignerCustomWidgetData::QDesignerCustomWidgetData(const QString &pluginPath) :
+ m_d(new QDesignerCustomWidgetSharedData(pluginPath))
+{
+}
+
+QDesignerCustomWidgetData::QDesignerCustomWidgetData(const QDesignerCustomWidgetData &o) :
+ m_d(o.m_d)
+{
+}
+
+QDesignerCustomWidgetData& QDesignerCustomWidgetData::operator=(const QDesignerCustomWidgetData &o)
+{
+ m_d.operator=(o.m_d);
+ return *this;
+}
+
+QDesignerCustomWidgetData::~QDesignerCustomWidgetData()
+{
+}
+
+bool QDesignerCustomWidgetData::isNull() const
+{
+ return m_d->xmlClassName.isEmpty() || m_d->pluginPath.isEmpty();
+}
+
+QString QDesignerCustomWidgetData::xmlClassName() const
+{
+ return m_d->xmlClassName;
+}
+
+QString QDesignerCustomWidgetData::xmlLanguage() const
+{
+ return m_d->xmlLanguage;
+}
+
+QString QDesignerCustomWidgetData::xmlAddPageMethod() const
+{
+ return m_d->xmlAddPageMethod;
+}
+
+QString QDesignerCustomWidgetData::xmlExtends() const
+{
+ return m_d->xmlExtends;
+}
+
+QString QDesignerCustomWidgetData::xmlDisplayName() const
+{
+ return m_d->xmlDisplayName;
+}
+
+QString QDesignerCustomWidgetData::pluginPath() const
+{
+ return m_d->pluginPath;
+}
+
+bool QDesignerCustomWidgetData::xmlStringPropertyType(const QString &name, StringPropertyType *type) const
+{
+ QDesignerCustomWidgetSharedData::StringPropertyTypeMap::const_iterator it = m_d->xmlStringPropertyTypeMap.constFind(name);
+ if (it == m_d->xmlStringPropertyTypeMap.constEnd()) {
+ *type = StringPropertyType(qdesigner_internal::ValidationRichText, true);
+ return false;
+ }
+ *type = it.value();
+ return true;
+}
+
+// Wind a QXmlStreamReader until it finds an element. Returns index or one of FindResult
+enum FindResult { FindError = -2, ElementNotFound = -1 };
+
+static int findElement(const QStringList &desiredElts, QXmlStreamReader &sr)
+{
+ while (true) {
+ switch(sr.readNext()) {
+ case QXmlStreamReader::EndDocument:
+ return ElementNotFound;
+ case QXmlStreamReader::Invalid:
+ return FindError;
+ case QXmlStreamReader::StartElement: {
+ const int index = desiredElts.indexOf(sr.name().toString().toLower());
+ if (index >= 0)
+ return index;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return FindError;
+}
+
+static inline QString msgXmlError(const QString &name, const QString &errorMessage)
+{
+ return QDesignerPluginManager::tr("An XML error was encountered when parsing the XML of the custom widget %1: %2").arg(name, errorMessage);
+}
+
+static inline QString msgAttributeMissing(const QString &name)
+{
+ return QDesignerPluginManager::tr("A required attribute ('%1') is missing.").arg(name);
+}
+
+static qdesigner_internal::TextPropertyValidationMode typeStringToType(const QString &v, bool *ok)
+{
+ *ok = true;
+ if (v == QLatin1String("multiline"))
+ return qdesigner_internal::ValidationMultiLine;
+ if (v == QLatin1String("richtext"))
+ return qdesigner_internal::ValidationRichText;
+ if (v == QLatin1String("stylesheet"))
+ return qdesigner_internal::ValidationStyleSheet;
+ if (v == QLatin1String("singleline"))
+ return qdesigner_internal::ValidationSingleLine;
+ if (v == QLatin1String("objectname"))
+ return qdesigner_internal::ValidationObjectName;
+ if (v == QLatin1String("objectnamescope"))
+ return qdesigner_internal::ValidationObjectNameScope;
+ if (v == QLatin1String("url"))
+ return qdesigner_internal::ValidationURL;
+ *ok = false;
+ return qdesigner_internal::ValidationRichText;
+}
+
+static bool parsePropertySpecs(QXmlStreamReader &sr,
+ QDesignerCustomWidgetSharedData::StringPropertyTypeMap *rc,
+ QString *errorMessage)
+{
+ const QString propertySpecs = QLatin1String(propertySpecsC);
+ const QString stringPropertySpec = QLatin1String(stringPropertySpecC);
+ const QString stringPropertyTypeAttr = QLatin1String(stringPropertyTypeAttrC);
+ const QString stringPropertyNoTrAttr = QLatin1String(stringPropertyNoTrAttrC);
+ const QString stringPropertyNameAttr = QLatin1String(stringPropertyNameAttrC);
+
+ while (!sr.atEnd()) {
+ switch(sr.readNext()) {
+ case QXmlStreamReader::StartElement: {
+ if (sr.name() != stringPropertySpec) {
+ *errorMessage = QDesignerPluginManager::tr("An invalid property specification ('%1') was encountered. Supported types: %2").arg(sr.name().toString(), stringPropertySpec);
+ return false;
+ }
+ const QXmlStreamAttributes atts = sr.attributes();
+ const QString name = atts.value(stringPropertyNameAttr).toString();
+ const QString type = atts.value(stringPropertyTypeAttr).toString();
+ const QString notrS = atts.value(stringPropertyNoTrAttr).toString(); //Optional
+
+ if (type.isEmpty()) {
+ *errorMessage = msgAttributeMissing(stringPropertyTypeAttr);
+ return false;
+ }
+ if (name.isEmpty()) {
+ *errorMessage = msgAttributeMissing(stringPropertyNameAttr);
+ return false;
+ }
+ bool typeOk;
+ const bool noTr = notrS == QLatin1String("true") || notrS == QLatin1String("1");
+ QDesignerCustomWidgetSharedData::StringPropertyType v(typeStringToType(type, &typeOk), !noTr);
+ if (!typeOk) {
+ *errorMessage = QDesignerPluginManager::tr("'%1' is not a valid string property specification.").arg(type);
+ return false;
+ }
+ rc->insert(name, v);
+ }
+ break;
+ case QXmlStreamReader::EndElement: // Outer </stringproperties>
+ if (sr.name() == propertySpecs)
+ return true;
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
+QDesignerCustomWidgetData::ParseResult
+ QDesignerCustomWidgetData::parseXml(const QString &xml, const QString &name, QString *errorMessage)
+{
+ if (debugPluginManager)
+ qDebug() << Q_FUNC_INFO << name;
+
+ QDesignerCustomWidgetSharedData &data = *m_d;
+ data.clearXML();
+
+ QXmlStreamReader sr(xml);
+
+ bool foundUI = false;
+ bool foundWidget = false;
+ ParseResult rc = ParseOk;
+ // Parse for the (optional) <ui> or the first <widget> element
+ QStringList elements;
+ elements.push_back(QLatin1String(uiElementC));
+ elements.push_back(QLatin1String(widgetElementC));
+ for (int i = 0; i < 2 && !foundWidget; i++) {
+ switch (findElement(elements, sr)) {
+ case FindError:
+ *errorMessage = msgXmlError(name, sr.errorString());
+ return ParseError;
+ case ElementNotFound:
+ *errorMessage = QDesignerPluginManager::tr("The XML of the custom widget %1 does not contain any of the elements <widget> or <ui>.").arg(name);
+ return ParseError;
+ case 0: { // <ui>
+ const QXmlStreamAttributes attributes = sr.attributes();
+ data.xmlLanguage = attributes.value(QLatin1String(languageAttributeC)).toString();
+ data.xmlDisplayName = attributes.value(QLatin1String(displayNameAttributeC)).toString();
+ foundUI = true;
+ }
+ break;
+ case 1: // <widget>: Do some sanity checks
+ data.xmlClassName = sr.attributes().value(QLatin1String(classAttributeC)).toString();
+ if (data.xmlClassName.isEmpty()) {
+ *errorMessage = QDesignerPluginManager::tr("The class attribute for the class %1 is missing.").arg(name);
+ rc = ParseWarning;
+ } else {
+ if (data.xmlClassName != name) {
+ *errorMessage = QDesignerPluginManager::tr("The class attribute for the class %1 does not match the class name %2.").arg(data.xmlClassName, name);
+ rc = ParseWarning;
+ }
+ }
+ foundWidget = true;
+ break;
+ }
+ }
+ // Parse out the <customwidget> element which might be present if <ui> was there
+ if (!foundUI)
+ return rc;
+ elements.clear();
+ elements.push_back(QLatin1String(customwidgetElementC));
+ switch (findElement(elements, sr)) {
+ case FindError:
+ *errorMessage = msgXmlError(name, sr.errorString());
+ return ParseError;
+ case ElementNotFound:
+ return rc;
+ default:
+ break;
+ }
+ // Find <extends>, <addPageMethod>, <stringproperties>
+ elements.clear();
+ elements.push_back(QLatin1String(extendsElementC));
+ elements.push_back(QLatin1String(addPageMethodC));
+ elements.push_back(QLatin1String(propertySpecsC));
+ while (true) {
+ switch (findElement(elements, sr)) {
+ case FindError:
+ *errorMessage = msgXmlError(name, sr.errorString());
+ return ParseError;
+ case ElementNotFound:
+ return rc;
+ case 0: // <extends>
+ data.xmlExtends = sr.readElementText();
+ if (sr.tokenType() != QXmlStreamReader::EndElement) {
+ *errorMessage = msgXmlError(name, sr.errorString());
+ return ParseError;
+ }
+ break;
+ case 1: // <addPageMethod>
+ data.xmlAddPageMethod = sr.readElementText();
+ if (sr.tokenType() != QXmlStreamReader::EndElement) {
+ *errorMessage = msgXmlError(name, sr.errorString());
+ return ParseError;
+ }
+ break;
+ case 2: // <stringproperties>
+ if (!parsePropertySpecs(sr, &m_d->xmlStringPropertyTypeMap, errorMessage)) {
+ *errorMessage = msgXmlError(name, *errorMessage);
+ return ParseError;
+ }
+ break;
+ }
+ }
+ return rc;
+}
+
+// ---------------- QDesignerPluginManagerPrivate
+
+class QDesignerPluginManagerPrivate {
+ public:
+ typedef QPair<QString, QString> ClassNamePropertyNameKey;
+
+ QDesignerPluginManagerPrivate(QDesignerFormEditorInterface *core);
+
+ void clearCustomWidgets();
+ bool addCustomWidget(QDesignerCustomWidgetInterface *c,
+ const QString &pluginPath,
+ const QString &designerLanguage);
+ void addCustomWidgets(const QObject *o,
+ const QString &pluginPath,
+ const QString &designerLanguage);
+
+ QDesignerFormEditorInterface *m_core;
+ QStringList m_pluginPaths;
+ QStringList m_registeredPlugins;
+ // TODO: QPluginLoader also caches invalid plugins -> This seems to be dead code
+ QStringList m_disabledPlugins;
+
+ typedef QMap<QString, QString> FailedPluginMap;
+ FailedPluginMap m_failedPlugins;
+
+ // Synced lists of custom widgets and their data. Note that the list
+ // must be ordered for collections to appear in order.
+ QList<QDesignerCustomWidgetInterface *> m_customWidgets;
+ QList<QDesignerCustomWidgetData> m_customWidgetData;
+
+ QStringList defaultPluginPaths() const;
+
+ bool m_initialized;
+};
+
+QDesignerPluginManagerPrivate::QDesignerPluginManagerPrivate(QDesignerFormEditorInterface *core) :
+ m_core(core),
+ m_initialized(false)
+{
+}
+
+void QDesignerPluginManagerPrivate::clearCustomWidgets()
+{
+ m_customWidgets.clear();
+ m_customWidgetData.clear();
+}
+
+// Add a custom widget to the list if it parses correctly
+// and is of the right language
+bool QDesignerPluginManagerPrivate::addCustomWidget(QDesignerCustomWidgetInterface *c,
+ const QString &pluginPath,
+ const QString &designerLanguage)
+{
+ if (debugPluginManager)
+ qDebug() << Q_FUNC_INFO << c->name();
+
+ if (!c->isInitialized())
+ c->initialize(m_core);
+ // Parse the XML even if the plugin is initialized as Jambi might play tricks here
+ QDesignerCustomWidgetData data(pluginPath);
+ const QString domXml = c->domXml();
+ if (!domXml.isEmpty()) { // Legacy: Empty XML means: Do not show up in widget box.
+ QString errorMessage;
+ const QDesignerCustomWidgetData::ParseResult pr = data.parseXml(domXml, c->name(), &errorMessage);
+ switch (pr) {
+ case QDesignerCustomWidgetData::ParseOk:
+ break;
+ case QDesignerCustomWidgetData::ParseWarning:
+ qdesigner_internal::designerWarning(errorMessage);
+ break;
+ case QDesignerCustomWidgetData::ParseError:
+ qdesigner_internal::designerWarning(errorMessage);
+ return false;
+ }
+ // Does the language match?
+ const QString pluginLanguage = data.xmlLanguage();
+ if (!pluginLanguage.isEmpty() && pluginLanguage.compare(designerLanguage, Qt::CaseInsensitive))
+ return false;
+ }
+ m_customWidgets.push_back(c);
+ m_customWidgetData.push_back(data);
+ return true;
+}
+
+// Check the plugin interface for either a custom widget or a collection and
+// add all contained custom widgets.
+void QDesignerPluginManagerPrivate::addCustomWidgets(const QObject *o,
+ const QString &pluginPath,
+ const QString &designerLanguage)
+{
+ if (QDesignerCustomWidgetInterface *c = qobject_cast<QDesignerCustomWidgetInterface*>(o)) {
+ addCustomWidget(c, pluginPath, designerLanguage);
+ return;
+ }
+ if (const QDesignerCustomWidgetCollectionInterface *coll = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(o)) {
+ foreach(QDesignerCustomWidgetInterface *c, coll->customWidgets())
+ addCustomWidget(c, pluginPath, designerLanguage);
+ }
+}
+
+
+// ---------------- QDesignerPluginManager
+// As of 4.4, the header will be distributed with the Eclipse plugin.
+
+QDesignerPluginManager::QDesignerPluginManager(QDesignerFormEditorInterface *core) :
+ QObject(core),
+ m_d(new QDesignerPluginManagerPrivate(core))
+{
+ m_d->m_pluginPaths = defaultPluginPaths();
+ const QSettings settings(qApp->organizationName(), QDesignerQSettings::settingsApplicationName());
+ m_d->m_disabledPlugins = unique(settings.value(QLatin1String("PluginManager/DisabledPlugins")).toStringList());
+
+ // Register plugins
+ updateRegisteredPlugins();
+
+ if (debugPluginManager)
+ qDebug() << "QDesignerPluginManager::disabled: " << m_d->m_disabledPlugins << " static " << m_d->m_customWidgets.size();
+}
+
+QDesignerPluginManager::~QDesignerPluginManager()
+{
+ syncSettings();
+ delete m_d;
+}
+
+QDesignerFormEditorInterface *QDesignerPluginManager::core() const
+{
+ return m_d->m_core;
+}
+
+QStringList QDesignerPluginManager::findPlugins(const QString &path)
+{
+ if (debugPluginManager)
+ qDebug() << Q_FUNC_INFO << path;
+ const QDir dir(path);
+ if (!dir.exists())
+ return QStringList();
+
+ const QFileInfoList infoList = dir.entryInfoList(QDir::Files);
+ if (infoList.empty())
+ return QStringList();
+
+ // Load symbolic links but make sure all file names are unique as not
+ // to fall for something like 'libplugin.so.1 -> libplugin.so'
+ QStringList result;
+ const QFileInfoList::const_iterator icend = infoList.constEnd();
+ for (QFileInfoList::const_iterator it = infoList.constBegin(); it != icend; ++it) {
+ QString fileName;
+ if (it->isSymLink()) {
+ const QFileInfo linkTarget = QFileInfo(it->symLinkTarget());
+ if (linkTarget.exists() && linkTarget.isFile())
+ fileName = linkTarget.absoluteFilePath();
+ } else {
+ fileName = it->absoluteFilePath();
+ }
+ if (!fileName.isEmpty() && QLibrary::isLibrary(fileName) && !result.contains(fileName))
+ result += fileName;
+ }
+ return result;
+}
+
+void QDesignerPluginManager::setDisabledPlugins(const QStringList &disabled_plugins)
+{
+ m_d->m_disabledPlugins = disabled_plugins;
+ updateRegisteredPlugins();
+}
+
+void QDesignerPluginManager::setPluginPaths(const QStringList &plugin_paths)
+{
+ m_d->m_pluginPaths = plugin_paths;
+ updateRegisteredPlugins();
+}
+
+QStringList QDesignerPluginManager::disabledPlugins() const
+{
+ return m_d->m_disabledPlugins;
+}
+
+QStringList QDesignerPluginManager::failedPlugins() const
+{
+ return m_d->m_failedPlugins.keys();
+}
+
+QString QDesignerPluginManager::failureReason(const QString &pluginName) const
+{
+ return m_d->m_failedPlugins.value(pluginName);
+}
+
+QStringList QDesignerPluginManager::registeredPlugins() const
+{
+ return m_d->m_registeredPlugins;
+}
+
+QStringList QDesignerPluginManager::pluginPaths() const
+{
+ return m_d->m_pluginPaths;
+}
+
+QObject *QDesignerPluginManager::instance(const QString &plugin) const
+{
+ if (m_d->m_disabledPlugins.contains(plugin))
+ return 0;
+
+ QPluginLoader loader(plugin);
+ return loader.instance();
+}
+
+void QDesignerPluginManager::updateRegisteredPlugins()
+{
+ if (debugPluginManager)
+ qDebug() << Q_FUNC_INFO;
+ m_d->m_registeredPlugins.clear();
+ foreach (const QString &path, m_d->m_pluginPaths)
+ registerPath(path);
+}
+
+bool QDesignerPluginManager::registerNewPlugins()
+{
+ if (debugPluginManager)
+ qDebug() << Q_FUNC_INFO;
+
+ const int before = m_d->m_registeredPlugins.size();
+ foreach (const QString &path, m_d->m_pluginPaths)
+ registerPath(path);
+ const bool newPluginsFound = m_d->m_registeredPlugins.size() > before;
+ // We force a re-initialize as Jambi collection might return
+ // different widget lists when switching projects.
+ m_d->m_initialized = false;
+ ensureInitialized();
+
+ return newPluginsFound;
+}
+
+void QDesignerPluginManager::registerPath(const QString &path)
+{
+ if (debugPluginManager)
+ qDebug() << Q_FUNC_INFO << path;
+ QStringList candidates = findPlugins(path);
+
+ foreach (const QString &plugin, candidates)
+ registerPlugin(plugin);
+}
+
+void QDesignerPluginManager::registerPlugin(const QString &plugin)
+{
+ if (debugPluginManager)
+ qDebug() << Q_FUNC_INFO << plugin;
+ if (m_d->m_disabledPlugins.contains(plugin))
+ return;
+ if (m_d->m_registeredPlugins.contains(plugin))
+ return;
+
+ QPluginLoader loader(plugin);
+ if (loader.isLoaded() || loader.load()) {
+ m_d->m_registeredPlugins += plugin;
+ QDesignerPluginManagerPrivate::FailedPluginMap::iterator fit = m_d->m_failedPlugins.find(plugin);
+ if (fit != m_d->m_failedPlugins.end())
+ m_d->m_failedPlugins.erase(fit);
+ return;
+ }
+
+ const QString errorMessage = loader.errorString();
+ m_d->m_failedPlugins.insert(plugin, errorMessage);
+}
+
+
+
+bool QDesignerPluginManager::syncSettings()
+{
+ QSettings settings(qApp->organizationName(), QDesignerQSettings::settingsApplicationName());
+ settings.beginGroup(QLatin1String("PluginManager"));
+ settings.setValue(QLatin1String("DisabledPlugins"), m_d->m_disabledPlugins);
+ settings.endGroup();
+ return settings.status() == QSettings::NoError;
+}
+
+void QDesignerPluginManager::ensureInitialized()
+{
+ if (debugPluginManager)
+ qDebug() << Q_FUNC_INFO << m_d->m_initialized << m_d->m_customWidgets.size();
+
+ if (m_d->m_initialized)
+ return;
+
+ const QString designerLanguage = getDesignerLanguage(m_d->m_core);
+
+ m_d->clearCustomWidgets();
+ // Add the static custom widgets
+ const QObjectList staticPluginObjects = QPluginLoader::staticInstances();
+ if (!staticPluginObjects.empty()) {
+ const QString staticPluginPath = QCoreApplication::applicationFilePath();
+ foreach(QObject *o, staticPluginObjects)
+ m_d->addCustomWidgets(o, staticPluginPath, designerLanguage);
+ }
+ foreach (const QString &plugin, m_d->m_registeredPlugins)
+ if (QObject *o = instance(plugin))
+ m_d->addCustomWidgets(o, plugin, designerLanguage);
+
+ m_d->m_initialized = true;
+}
+
+QDesignerPluginManager::CustomWidgetList QDesignerPluginManager::registeredCustomWidgets() const
+{
+ const_cast<QDesignerPluginManager*>(this)->ensureInitialized();
+ return m_d->m_customWidgets;
+}
+
+QDesignerCustomWidgetData QDesignerPluginManager::customWidgetData(QDesignerCustomWidgetInterface *w) const
+{
+ const int index = m_d->m_customWidgets.indexOf(w);
+ if (index == -1)
+ return QDesignerCustomWidgetData();
+ return m_d->m_customWidgetData.at(index);
+}
+
+QDesignerCustomWidgetData QDesignerPluginManager::customWidgetData(const QString &name) const
+{
+ const int count = m_d->m_customWidgets.size();
+ for (int i = 0; i < count; i++)
+ if (m_d->m_customWidgets.at(i)->name() == name)
+ return m_d->m_customWidgetData.at(i);
+ return QDesignerCustomWidgetData();
+}
+
+QObjectList QDesignerPluginManager::instances() const
+{
+ QStringList plugins = registeredPlugins();
+
+ QObjectList lst;
+ foreach (const QString &plugin, plugins) {
+ if (QObject *o = instance(plugin))
+ lst.append(o);
+ }
+
+ return lst;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/pluginmanager_p.h b/src/designer/src/lib/shared/pluginmanager_p.h
new file mode 100644
index 000000000..34aa3041d
--- /dev/null
+++ b/src/designer/src/lib/shared/pluginmanager_p.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PLUGINMANAGER_H
+#define PLUGINMANAGER_H
+
+#include "shared_global_p.h"
+#include "shared_enums_p.h"
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QMap>
+#include <QtCore/QPair>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerCustomWidgetInterface;
+class QDesignerPluginManagerPrivate;
+
+class QDesignerCustomWidgetSharedData;
+
+/* Information contained in the Dom XML of a custom widget. */
+class QDESIGNER_SHARED_EXPORT QDesignerCustomWidgetData {
+public:
+ // StringPropertyType: validation mode and translatable flag.
+ typedef QPair<qdesigner_internal::TextPropertyValidationMode, bool> StringPropertyType;
+
+ explicit QDesignerCustomWidgetData(const QString &pluginPath = QString());
+
+ enum ParseResult { ParseOk, ParseWarning, ParseError };
+ ParseResult parseXml(const QString &xml, const QString &name, QString *errorMessage);
+
+ QDesignerCustomWidgetData(const QDesignerCustomWidgetData&);
+ QDesignerCustomWidgetData& operator=(const QDesignerCustomWidgetData&);
+ ~QDesignerCustomWidgetData();
+
+ bool isNull() const;
+
+ QString pluginPath() const;
+
+ // Data as parsed from the widget's domXML().
+ QString xmlClassName() const;
+ // Optional. The language the plugin is supposed to be used with.
+ QString xmlLanguage() const;
+ // Optional. method used to add pages to a container with a container extension
+ QString xmlAddPageMethod() const;
+ // Optional. Base class
+ QString xmlExtends() const;
+ // Optional. The name to be used in the widget box.
+ QString xmlDisplayName() const;
+ // Type of a string property
+ bool xmlStringPropertyType(const QString &name, StringPropertyType *type) const;
+
+private:
+ QSharedDataPointer<QDesignerCustomWidgetSharedData> m_d;
+};
+
+class QDESIGNER_SHARED_EXPORT QDesignerPluginManager: public QObject
+{
+ Q_OBJECT
+public:
+ typedef QList<QDesignerCustomWidgetInterface*> CustomWidgetList;
+
+ explicit QDesignerPluginManager(QDesignerFormEditorInterface *core);
+ virtual ~QDesignerPluginManager();
+
+ QDesignerFormEditorInterface *core() const;
+
+ QObject *instance(const QString &plugin) const;
+
+ QStringList registeredPlugins() const;
+
+ QStringList findPlugins(const QString &path);
+
+ QStringList pluginPaths() const;
+ void setPluginPaths(const QStringList &plugin_paths);
+
+ QStringList disabledPlugins() const;
+ void setDisabledPlugins(const QStringList &disabled_plugins);
+
+ QStringList failedPlugins() const;
+ QString failureReason(const QString &pluginName) const;
+
+ QObjectList instances() const;
+
+ CustomWidgetList registeredCustomWidgets() const;
+ QDesignerCustomWidgetData customWidgetData(QDesignerCustomWidgetInterface *w) const;
+ QDesignerCustomWidgetData customWidgetData(const QString &className) const;
+
+ bool registerNewPlugins();
+
+public slots:
+ bool syncSettings();
+ void ensureInitialized();
+
+private:
+ void updateRegisteredPlugins();
+ void registerPath(const QString &path);
+ void registerPlugin(const QString &plugin);
+
+private:
+ static QStringList defaultPluginPaths();
+
+ QDesignerPluginManagerPrivate *m_d;
+};
+
+QT_END_NAMESPACE
+
+#endif // PLUGINMANAGER_H
diff --git a/src/designer/src/lib/shared/previewconfigurationwidget.cpp b/src/designer/src/lib/shared/previewconfigurationwidget.cpp
new file mode 100644
index 000000000..2b4506a37
--- /dev/null
+++ b/src/designer/src/lib/shared/previewconfigurationwidget.cpp
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* It is possible to link the skins as resources into Designer by specifying:
+ * QVFB_ROOT=$$QT_SOURCE_TREE/tools/qvfb
+ * RESOURCES += $$QVFB_ROOT/ClamshellPhone.qrc $$QVFB_ROOT/TouchScreenPhone.qrc ...
+ * in lib/shared/shared.pri. However, this exceeds a limit of Visual Studio 6. */
+
+#include "previewconfigurationwidget_p.h"
+#include "ui_previewconfigurationwidget.h"
+#include "previewmanager_p.h"
+#include "abstractsettings_p.h"
+#include "shared_settings_p.h"
+
+#include <iconloader_p.h>
+#include <stylesheeteditor_p.h>
+
+#include <deviceskin.h>
+
+#include <QtGui/QFileDialog>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtCore/QPair>
+#include <QtCore/QList>
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSharedData>
+
+
+static const char *skinResourcePathC = ":/skins/";
+
+QT_BEGIN_NAMESPACE
+
+static const char *skinExtensionC = "skin";
+
+// Pair of skin name, path
+typedef QPair<QString, QString> SkinNamePath;
+typedef QList<SkinNamePath> Skins;
+enum { SkinComboNoneIndex = 0 };
+
+// find default skins (resources)
+static const Skins &defaultSkins() {
+ static Skins rc;
+ if (rc.empty()) {
+ const QString skinPath = QLatin1String(skinResourcePathC);
+ QString pattern = QLatin1String("*.");
+ pattern += QLatin1String(skinExtensionC);
+ const QDir dir(skinPath, pattern);
+ const QFileInfoList list = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot, QDir::Name);
+ if (list.empty())
+ return rc;
+ const QFileInfoList::const_iterator lcend = list.constEnd();
+ for (QFileInfoList::const_iterator it = list.constBegin(); it != lcend; ++it)
+ rc.push_back(SkinNamePath(it->baseName(), it->filePath()));
+ }
+ return rc;
+}
+
+namespace qdesigner_internal {
+
+// ------------- PreviewConfigurationWidgetPrivate
+class PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate {
+public:
+ PreviewConfigurationWidgetPrivate(QDesignerFormEditorInterface *core, QGroupBox *g);
+
+ void slotEditAppStyleSheet();
+ void slotDeleteSkinEntry();
+ void slotSkinChanged(int index);
+
+ void retrieveSettings();
+ void storeSettings() const;
+
+ QAbstractButton *appStyleSheetChangeButton() const { return m_ui.m_appStyleSheetChangeButton; }
+ QAbstractButton *skinRemoveButton() const { return m_ui.m_skinRemoveButton; }
+ QComboBox *skinCombo() const { return m_ui.m_skinCombo; }
+
+ QDesignerFormEditorInterface *m_core;
+
+private:
+ PreviewConfiguration previewConfiguration() const;
+ void setPreviewConfiguration(const PreviewConfiguration &pc);
+
+ QStringList userSkins() const;
+ void addUserSkins(const QStringList &files);
+ bool canRemoveSkin(int index) const;
+ int browseSkin();
+
+ const QString m_defaultStyle;
+ QGroupBox *m_parent;
+ Ui::PreviewConfigurationWidget m_ui;
+
+ int m_firstUserSkinIndex;
+ int m_browseSkinIndex;
+ int m_lastSkinIndex; // required in case browse fails
+};
+
+PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::PreviewConfigurationWidgetPrivate(
+ QDesignerFormEditorInterface *core, QGroupBox *g) :
+ m_core(core),
+ m_defaultStyle(PreviewConfigurationWidget::tr("Default")),
+ m_parent(g),
+ m_firstUserSkinIndex(0),
+ m_browseSkinIndex(0),
+ m_lastSkinIndex(0)
+{
+ m_ui.setupUi(g);
+ // styles
+ m_ui.m_styleCombo->setEditable(false);
+ QStringList styleItems(m_defaultStyle);
+ styleItems += QStyleFactory::keys();
+ m_ui.m_styleCombo->addItems(styleItems);
+
+ // sheet
+ m_ui.m_appStyleSheetLineEdit->setTextPropertyValidationMode(qdesigner_internal::ValidationStyleSheet);
+ m_ui.m_appStyleSheetClearButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("resetproperty.png")));
+ QObject::connect(m_ui.m_appStyleSheetClearButton, SIGNAL(clicked()), m_ui.m_appStyleSheetLineEdit, SLOT(clear()));
+
+ m_ui.m_skinRemoveButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("editdelete.png")));
+ // skins: find default skins (resources)
+ m_ui.m_skinRemoveButton->setEnabled(false);
+ Skins skins = defaultSkins();
+ skins.push_front(SkinNamePath(PreviewConfigurationWidget::tr("None"), QString()));
+
+ const Skins::const_iterator scend = skins.constEnd();
+ for (Skins::const_iterator it = skins.constBegin(); it != scend; ++it)
+ m_ui.m_skinCombo->addItem (it->first, QVariant(it->second));
+ m_browseSkinIndex = m_firstUserSkinIndex = skins.size();
+ m_ui.m_skinCombo->addItem(PreviewConfigurationWidget::tr("Browse..."), QString());
+
+ m_ui.m_skinCombo->setMaxVisibleItems (qMax(15, 2 * m_browseSkinIndex));
+ m_ui.m_skinCombo->setEditable(false);
+
+ retrieveSettings();
+}
+
+bool PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::canRemoveSkin(int index) const
+{
+ return index >= m_firstUserSkinIndex && index != m_browseSkinIndex;
+}
+
+QStringList PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::userSkins() const
+{
+ QStringList rc;
+ for (int i = m_firstUserSkinIndex; i < m_browseSkinIndex; i++)
+ rc.push_back(m_ui.m_skinCombo->itemData(i).toString());
+ return rc;
+}
+
+void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::addUserSkins(const QStringList &files)
+{
+ if (files.empty())
+ return;
+ const QStringList ::const_iterator fcend = files.constEnd();
+ for (QStringList::const_iterator it = files.constBegin(); it != fcend; ++it) {
+ const QFileInfo fi(*it);
+ if (fi.isDir() && fi.isReadable()) {
+ m_ui.m_skinCombo->insertItem(m_browseSkinIndex++, fi.baseName(), QVariant(*it));
+ } else {
+ qWarning() << "Unable to access the skin directory '" << *it << "'.";
+ }
+ }
+}
+
+PreviewConfiguration PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::previewConfiguration() const
+{
+ PreviewConfiguration rc;
+ QString style = m_ui.m_styleCombo->currentText();
+ if (style == m_defaultStyle)
+ style.clear();
+ const QString applicationStyleSheet = m_ui.m_appStyleSheetLineEdit->text();
+ // Figure out skin. 0 is None by definition..
+ const int skinIndex = m_ui.m_skinCombo->currentIndex();
+ QString deviceSkin;
+ if (skinIndex != SkinComboNoneIndex && skinIndex != m_browseSkinIndex)
+ deviceSkin = m_ui.m_skinCombo->itemData(skinIndex).toString();
+
+ return PreviewConfiguration(style, applicationStyleSheet, deviceSkin);
+}
+
+void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::setPreviewConfiguration(const PreviewConfiguration &pc)
+{
+ int styleIndex = m_ui.m_styleCombo->findText(pc.style());
+ if (styleIndex == -1)
+ styleIndex = m_ui.m_styleCombo->findText(m_defaultStyle);
+ m_ui.m_styleCombo->setCurrentIndex(styleIndex);
+ m_ui.m_appStyleSheetLineEdit->setText(pc.applicationStyleSheet());
+ // find skin by file name. 0 is "none"
+ const QString deviceSkin = pc.deviceSkin();
+ int skinIndex = deviceSkin.isEmpty() ? 0 : m_ui.m_skinCombo->findData(QVariant(deviceSkin));
+ if (skinIndex == -1) {
+ qWarning() << "Unable to find skin '" << deviceSkin << "'.";
+ skinIndex = 0;
+ }
+ m_ui.m_skinCombo->setCurrentIndex(skinIndex);
+}
+
+void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::slotEditAppStyleSheet()
+{
+ StyleSheetEditorDialog dlg(m_core, m_parent, StyleSheetEditorDialog::ModeGlobal);
+ dlg.setText(m_ui.m_appStyleSheetLineEdit->text());
+ if (dlg.exec() == QDialog::Accepted)
+ m_ui.m_appStyleSheetLineEdit->setText(dlg.text());
+}
+
+void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::slotDeleteSkinEntry()
+{
+ const int index = m_ui.m_skinCombo->currentIndex();
+ if (canRemoveSkin(index)) {
+ m_ui.m_skinCombo->setCurrentIndex(SkinComboNoneIndex);
+ m_ui.m_skinCombo->removeItem(index);
+ m_browseSkinIndex--;
+ }
+}
+
+void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::slotSkinChanged(int index)
+{
+ if (index == m_browseSkinIndex) {
+ m_ui.m_skinCombo->setCurrentIndex(browseSkin());
+ } else {
+ m_lastSkinIndex = index;
+ m_ui.m_skinRemoveButton->setEnabled(canRemoveSkin(index));
+ m_ui.m_skinCombo->setToolTip(index != SkinComboNoneIndex ? m_ui.m_skinCombo->itemData(index).toString() : QString());
+ }
+}
+
+void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::retrieveSettings()
+{
+ QDesignerSharedSettings settings(m_core);
+ m_parent->setChecked(settings.isCustomPreviewConfigurationEnabled());
+ setPreviewConfiguration(settings.customPreviewConfiguration());
+ addUserSkins(settings.userDeviceSkins());
+}
+
+void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::storeSettings() const
+{
+ QDesignerSharedSettings settings(m_core);
+ settings.setCustomPreviewConfigurationEnabled(m_parent->isChecked());
+ settings.setCustomPreviewConfiguration(previewConfiguration());
+ settings.setUserDeviceSkins(userSkins());
+}
+
+int PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::browseSkin()
+{
+ QFileDialog dlg(m_parent);
+ dlg.setFileMode(QFileDialog::DirectoryOnly);
+ const QString title = tr("Load Custom Device Skin");
+ dlg.setWindowTitle(title);
+ dlg.setFilter(tr("All QVFB Skins (*.%1)").arg(QLatin1String(skinExtensionC)));
+
+ int rc = m_lastSkinIndex;
+ do {
+ if (!dlg.exec())
+ break;
+
+ const QStringList directories = dlg.selectedFiles();
+ if (directories.size() != 1)
+ break;
+
+ // check: 1) name already there
+ const QString directory = directories.front();
+ const QString name = QFileInfo(directory).baseName();
+ const int existingIndex = m_ui.m_skinCombo->findText(name);
+ if (existingIndex != -1 && existingIndex != SkinComboNoneIndex && existingIndex != m_browseSkinIndex) {
+ const QString msgTitle = tr("%1 - Duplicate Skin").arg(title);
+ const QString msg = tr("The skin '%1' already exists.").arg(name);
+ QMessageBox::information(m_parent, msgTitle, msg);
+ break;
+ }
+ // check: 2) can read
+ DeviceSkinParameters parameters;
+ QString readError;
+ if (parameters.read(directory, DeviceSkinParameters::ReadSizeOnly, &readError)) {
+ const QString name = QFileInfo(directory).baseName();
+ m_ui.m_skinCombo->insertItem(m_browseSkinIndex, name, QVariant(directory));
+ rc = m_browseSkinIndex++;
+
+ break;
+ } else {
+ const QString msgTitle = tr("%1 - Error").arg(title);
+ const QString msg = tr("%1 is not a valid skin directory:\n%2").arg(directory).arg(readError);
+ QMessageBox::warning (m_parent, msgTitle, msg);
+ }
+ } while (true);
+ return rc;
+}
+
+// ------------- PreviewConfigurationWidget
+PreviewConfigurationWidget::PreviewConfigurationWidget(QDesignerFormEditorInterface *core,
+ QWidget *parent) :
+ QGroupBox(parent),
+ m_impl(new PreviewConfigurationWidgetPrivate(core, this))
+{
+ connect(m_impl->appStyleSheetChangeButton(), SIGNAL(clicked()), this, SLOT(slotEditAppStyleSheet()));
+ connect(m_impl->skinRemoveButton(), SIGNAL(clicked()), this, SLOT(slotDeleteSkinEntry()));
+ connect(m_impl->skinCombo(), SIGNAL(currentIndexChanged(int)), this, SLOT(slotSkinChanged(int)));
+
+ m_impl->retrieveSettings();
+}
+
+PreviewConfigurationWidget::~PreviewConfigurationWidget()
+{
+ delete m_impl;
+}
+
+void PreviewConfigurationWidget::saveState()
+{
+ m_impl->storeSettings();
+}
+
+void PreviewConfigurationWidget::slotEditAppStyleSheet()
+{
+ m_impl->slotEditAppStyleSheet();
+}
+
+void PreviewConfigurationWidget::slotDeleteSkinEntry()
+{
+ m_impl->slotDeleteSkinEntry();
+}
+
+void PreviewConfigurationWidget::slotSkinChanged(int index)
+{
+ m_impl->slotSkinChanged(index);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/previewconfigurationwidget.ui b/src/designer/src/lib/shared/previewconfigurationwidget.ui
new file mode 100644
index 000000000..2f18766ff
--- /dev/null
+++ b/src/designer/src/lib/shared/previewconfigurationwidget.ui
@@ -0,0 +1,91 @@
+<ui version="4.0" >
+ <class>PreviewConfigurationWidget</class>
+ <widget class="QGroupBox" name="PreviewConfigurationWidget" >
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <property name="title" >
+ <string>Print/Preview Configuration</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <layout class="QFormLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="m_styleLabel" >
+ <property name="text" >
+ <string>Style</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QComboBox" name="m_styleCombo" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="m_appStyleSheetLabel" >
+ <property name="text" >
+ <string>Style sheet</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="qdesigner_internal::TextPropertyEditor" name="m_appStyleSheetLineEdit" >
+ <property name="minimumSize" >
+ <size>
+ <width>149</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="m_appStyleSheetChangeButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="m_appStyleSheetClearButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="m_skinLabel" >
+ <property name="text" >
+ <string>Device skin</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QComboBox" name="m_skinCombo" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="m_skinRemoveButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>qdesigner_internal::TextPropertyEditor</class>
+ <extends>QLineEdit</extends>
+ <header location="global" >textpropertyeditor_p.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/lib/shared/previewconfigurationwidget_p.h b/src/designer/src/lib/shared/previewconfigurationwidget_p.h
new file mode 100644
index 000000000..21ea1f197
--- /dev/null
+++ b/src/designer/src/lib/shared/previewconfigurationwidget_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PREVIEWCONFIGURATIONWIDGET_H
+#define PREVIEWCONFIGURATIONWIDGET_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QGroupBox>
+#include <QtCore/QSharedDataPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerSettingsInterface;
+
+namespace qdesigner_internal {
+
+// ----------- PreviewConfigurationWidget: Widget to edit the preview configuration.
+
+class QDESIGNER_SHARED_EXPORT PreviewConfigurationWidget : public QGroupBox
+{
+ Q_OBJECT
+public:
+ explicit PreviewConfigurationWidget(QDesignerFormEditorInterface *core,
+ QWidget *parent = 0);
+ virtual ~PreviewConfigurationWidget();
+ void saveState();
+
+private slots:
+ void slotEditAppStyleSheet();
+ void slotDeleteSkinEntry();
+ void slotSkinChanged(int);
+
+private:
+ class PreviewConfigurationWidgetPrivate;
+ PreviewConfigurationWidgetPrivate *m_impl;
+
+ PreviewConfigurationWidget(const PreviewConfigurationWidget &other);
+ PreviewConfigurationWidget &operator =(const PreviewConfigurationWidget &other);
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // PREVIEWCONFIGURATIONWIDGET_H
diff --git a/src/designer/src/lib/shared/previewmanager.cpp b/src/designer/src/lib/shared/previewmanager.cpp
new file mode 100644
index 000000000..3857b7864
--- /dev/null
+++ b/src/designer/src/lib/shared/previewmanager.cpp
@@ -0,0 +1,943 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractsettings_p.h"
+#include "previewmanager_p.h"
+#include "qdesigner_formbuilder_p.h"
+#include "shared_settings_p.h"
+#include "shared_settings_p.h"
+#include "zoomwidget_p.h"
+#include "formwindowbase_p.h"
+#include "widgetfactory_p.h"
+
+#include <deviceskin.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+#include <QtGui/QWidget>
+#include <QtGui/qevent.h>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QMainWindow>
+#include <QtGui/QDockWidget>
+#include <QtGui/QApplication>
+#include <QtGui/QPixmap>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QDialog>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QCursor>
+#include <QtGui/QMatrix>
+
+#include <QtCore/QMap>
+#include <QtCore/QDebug>
+#include <QtCore/QSharedData>
+
+QT_BEGIN_NAMESPACE
+
+static inline int compare(const qdesigner_internal::PreviewConfiguration &pc1, const qdesigner_internal::PreviewConfiguration &pc2)
+{
+ int rc = pc1.style().compare(pc2.style());
+ if (rc)
+ return rc;
+ rc = pc1.applicationStyleSheet().compare(pc2.applicationStyleSheet());
+ if (rc)
+ return rc;
+ return pc1.deviceSkin().compare(pc2.deviceSkin());
+}
+
+namespace {
+ // ------ PreviewData (data associated with a preview window)
+ struct PreviewData {
+ PreviewData(const QPointer<QWidget> &widget, const QDesignerFormWindowInterface *formWindow, const qdesigner_internal::PreviewConfiguration &pc);
+ QPointer<QWidget> m_widget;
+ const QDesignerFormWindowInterface *m_formWindow;
+ qdesigner_internal::PreviewConfiguration m_configuration;
+ };
+
+ PreviewData::PreviewData(const QPointer<QWidget>& widget,
+ const QDesignerFormWindowInterface *formWindow,
+ const qdesigner_internal::PreviewConfiguration &pc) :
+ m_widget(widget),
+ m_formWindow(formWindow),
+ m_configuration(pc)
+ {
+ }
+}
+
+namespace qdesigner_internal {
+
+/* In designer, we have the situation that laid-out maincontainers have
+ * a geometry set (which might differ from their sizeHint()). The QGraphicsItem
+ * should return that in its size hint, else such cases won't work */
+
+class DesignerZoomProxyWidget : public ZoomProxyWidget {
+ Q_DISABLE_COPY(DesignerZoomProxyWidget)
+public:
+ DesignerZoomProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
+protected:
+ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
+};
+
+DesignerZoomProxyWidget::DesignerZoomProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) :
+ ZoomProxyWidget(parent, wFlags)
+{
+}
+
+QSizeF DesignerZoomProxyWidget::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
+{
+ if (const QWidget *w = widget())
+ return QSizeF(w->size());
+ return ZoomProxyWidget::sizeHint(which, constraint);
+}
+
+// DesignerZoomWidget which returns DesignerZoomProxyWidget in its factory function
+class DesignerZoomWidget : public ZoomWidget {
+ Q_DISABLE_COPY(DesignerZoomWidget)
+public:
+ DesignerZoomWidget(QWidget *parent = 0);
+private:
+ virtual QGraphicsProxyWidget *createProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0) const;
+};
+
+DesignerZoomWidget::DesignerZoomWidget(QWidget *parent) :
+ ZoomWidget(parent)
+{
+}
+
+QGraphicsProxyWidget *DesignerZoomWidget::createProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) const
+{
+ return new DesignerZoomProxyWidget(parent, wFlags);
+}
+
+// PreviewDeviceSkin: Forwards the key events to the window and
+// provides context menu with rotation options. Derived class
+// can apply additional transformations to the skin.
+
+class PreviewDeviceSkin : public DeviceSkin
+{
+ Q_OBJECT
+public:
+ enum Direction { DirectionUp, DirectionLeft, DirectionRight };
+
+ explicit PreviewDeviceSkin(const DeviceSkinParameters &parameters, QWidget *parent);
+ virtual void setPreview(QWidget *w);
+ QSize screenSize() const { return m_screenSize; }
+
+private slots:
+ void slotSkinKeyPressEvent(int code, const QString& text, bool autorep);
+ void slotSkinKeyReleaseEvent(int code, const QString& text, bool autorep);
+ void slotPopupMenu();
+
+protected:
+ virtual void populateContextMenu(QMenu *) {}
+
+private slots:
+ void slotDirection(QAction *);
+
+protected:
+ // Fit the widget in case the orientation changes (transposing screensize)
+ virtual void fitWidget(const QSize &size);
+ // Calculate the complete transformation for the skin
+ // (base class implementation provides rotation).
+ virtual QMatrix skinTransform() const;
+
+private:
+ const QSize m_screenSize;
+ Direction m_direction;
+
+ QAction *m_directionUpAction;
+ QAction *m_directionLeftAction;
+ QAction *m_directionRightAction;
+ QAction *m_closeAction;
+};
+
+PreviewDeviceSkin::PreviewDeviceSkin(const DeviceSkinParameters &parameters, QWidget *parent) :
+ DeviceSkin(parameters, parent),
+ m_screenSize(parameters.screenSize()),
+ m_direction(DirectionUp),
+ m_directionUpAction(0),
+ m_directionLeftAction(0),
+ m_directionRightAction(0),
+ m_closeAction(0)
+{
+ connect(this, SIGNAL(skinKeyPressEvent(int,QString,bool)),
+ this, SLOT(slotSkinKeyPressEvent(int,QString,bool)));
+ connect(this, SIGNAL(skinKeyReleaseEvent(int,QString,bool)),
+ this, SLOT(slotSkinKeyReleaseEvent(int,QString,bool)));
+ connect(this, SIGNAL(popupMenu()), this, SLOT(slotPopupMenu()));
+}
+
+void PreviewDeviceSkin::setPreview(QWidget *formWidget)
+{
+ formWidget->setFixedSize(m_screenSize);
+ formWidget->setParent(this, Qt::SubWindow);
+ formWidget->setAutoFillBackground(true);
+ setView(formWidget);
+}
+
+void PreviewDeviceSkin::slotSkinKeyPressEvent(int code, const QString& text, bool autorep)
+{
+ if (QWidget *focusWidget = QApplication::focusWidget()) {
+ QKeyEvent e(QEvent::KeyPress,code,0,text,autorep);
+ QApplication::sendEvent(focusWidget, &e);
+ }
+}
+
+void PreviewDeviceSkin::slotSkinKeyReleaseEvent(int code, const QString& text, bool autorep)
+{
+ if (QWidget *focusWidget = QApplication::focusWidget()) {
+ QKeyEvent e(QEvent::KeyRelease,code,0,text,autorep);
+ QApplication::sendEvent(focusWidget, &e);
+ }
+}
+
+// Create a checkable action with integer data and
+// set it checked if it matches the currentState.
+static inline QAction
+ *createCheckableActionIntData(const QString &label,
+ int actionValue, int currentState,
+ QActionGroup *ag, QObject *parent)
+{
+ QAction *a = new QAction(label, parent);
+ a->setData(actionValue);
+ a->setCheckable(true);
+ if (actionValue == currentState)
+ a->setChecked(true);
+ ag->addAction(a);
+ return a;
+}
+
+void PreviewDeviceSkin::slotPopupMenu()
+{
+ QMenu menu(this);
+ // Create actions
+ if (!m_directionUpAction) {
+ QActionGroup *directionGroup = new QActionGroup(this);
+ connect(directionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotDirection(QAction*)));
+ directionGroup->setExclusive(true);
+ m_directionUpAction = createCheckableActionIntData(tr("&Portrait"), DirectionUp, m_direction, directionGroup, this);
+ //: Rotate form preview counter-clockwise
+ m_directionLeftAction = createCheckableActionIntData(tr("Landscape (&CCW)"), DirectionLeft, m_direction, directionGroup, this);
+ //: Rotate form preview clockwise
+ m_directionRightAction = createCheckableActionIntData(tr("&Landscape (CW)"), DirectionRight, m_direction, directionGroup, this);
+ m_closeAction = new QAction(tr("&Close"), this);
+ connect(m_closeAction, SIGNAL(triggered()), parentWidget(), SLOT(close()));
+ }
+ menu.addAction(m_directionUpAction);
+ menu.addAction(m_directionLeftAction);
+ menu.addAction(m_directionRightAction);
+ menu.addSeparator();
+ populateContextMenu(&menu);
+ menu.addAction(m_closeAction);
+ menu.exec(QCursor::pos());
+}
+
+void PreviewDeviceSkin::slotDirection(QAction *a)
+{
+ const Direction newDirection = static_cast<Direction>(a->data().toInt());
+ if (m_direction == newDirection)
+ return;
+ const Qt::Orientation newOrientation = newDirection == DirectionUp ? Qt::Vertical : Qt::Horizontal;
+ const Qt::Orientation oldOrientation = m_direction == DirectionUp ? Qt::Vertical : Qt::Horizontal;
+ m_direction = newDirection;
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ if (oldOrientation != newOrientation) {
+ QSize size = screenSize();
+ if (newOrientation == Qt::Horizontal)
+ size.transpose();
+ fitWidget(size);
+ }
+ setTransform(skinTransform());
+ QApplication::restoreOverrideCursor();
+}
+
+void PreviewDeviceSkin::fitWidget(const QSize &size)
+{
+ view()->setFixedSize(size);
+}
+
+QMatrix PreviewDeviceSkin::skinTransform() const
+{
+ QMatrix newTransform;
+ switch (m_direction) {
+ case DirectionUp:
+ break;
+ case DirectionLeft:
+ newTransform.rotate(270.0);
+ break;
+ case DirectionRight:
+ newTransform.rotate(90.0);
+ break;
+ }
+ return newTransform;
+}
+
+// ------------ PreviewConfigurationPrivate
+class PreviewConfigurationData : public QSharedData {
+public:
+ PreviewConfigurationData() {}
+ explicit PreviewConfigurationData(const QString &style, const QString &applicationStyleSheet, const QString &deviceSkin);
+
+ QString m_style;
+ // Style sheet to prepend (to simulate the effect od QApplication::setSyleSheet()).
+ QString m_applicationStyleSheet;
+ QString m_deviceSkin;
+};
+
+PreviewConfigurationData::PreviewConfigurationData(const QString &style, const QString &applicationStyleSheet, const QString &deviceSkin) :
+ m_style(style),
+ m_applicationStyleSheet(applicationStyleSheet),
+ m_deviceSkin(deviceSkin)
+{
+}
+
+/* ZoomablePreviewDeviceSkin: A Zoomable Widget Preview skin. Embeds preview
+ * into a ZoomWidget and this in turn into the DeviceSkin view and keeps
+ * Device skin zoom + ZoomWidget zoom in sync. */
+
+class ZoomablePreviewDeviceSkin : public PreviewDeviceSkin
+{
+ Q_OBJECT
+public:
+ explicit ZoomablePreviewDeviceSkin(const DeviceSkinParameters &parameters, QWidget *parent);
+ virtual void setPreview(QWidget *w);
+
+ int zoomPercent() const; // Device Skins have a double 'zoom' property
+
+public slots:
+ void setZoomPercent(int);
+
+signals:
+ void zoomPercentChanged(int);
+
+protected:
+ virtual void populateContextMenu(QMenu *m);
+ virtual QMatrix skinTransform() const;
+ virtual void fitWidget(const QSize &size);
+
+private:
+ ZoomMenu *m_zoomMenu;
+ QAction *m_zoomSubMenuAction;
+ ZoomWidget *m_zoomWidget;
+};
+
+ZoomablePreviewDeviceSkin::ZoomablePreviewDeviceSkin(const DeviceSkinParameters &parameters, QWidget *parent) :
+ PreviewDeviceSkin(parameters, parent),
+ m_zoomMenu(new ZoomMenu(this)),
+ m_zoomSubMenuAction(0),
+ m_zoomWidget(new DesignerZoomWidget)
+{
+ connect(m_zoomMenu, SIGNAL(zoomChanged(int)), this, SLOT(setZoomPercent(int)));
+ connect(m_zoomMenu, SIGNAL(zoomChanged(int)), this, SIGNAL(zoomPercentChanged(int)));
+ m_zoomWidget->setZoomContextMenuEnabled(false);
+ m_zoomWidget->setWidgetZoomContextMenuEnabled(false);
+ m_zoomWidget->resize(screenSize());
+ m_zoomWidget->setParent(this, Qt::SubWindow);
+ m_zoomWidget->setAutoFillBackground(true);
+ setView(m_zoomWidget);
+}
+
+static inline qreal zoomFactor(int percent)
+{
+ return qreal(percent) / 100.0;
+}
+
+static inline QSize scaleSize(int zoomPercent, const QSize &size)
+{
+ return zoomPercent == 100 ? size : (QSizeF(size) * zoomFactor(zoomPercent)).toSize();
+}
+
+void ZoomablePreviewDeviceSkin::setPreview(QWidget *formWidget)
+{
+ m_zoomWidget->setWidget(formWidget);
+ m_zoomWidget->resize(scaleSize(zoomPercent(), screenSize()));
+}
+
+int ZoomablePreviewDeviceSkin::zoomPercent() const
+{
+ return m_zoomWidget->zoom();
+}
+
+void ZoomablePreviewDeviceSkin::setZoomPercent(int zp)
+{
+ if (zp == zoomPercent())
+ return;
+
+ // If not triggered by the menu itself: Update it
+ if (m_zoomMenu->zoom() != zp)
+ m_zoomMenu->setZoom(zp);
+
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ m_zoomWidget->setZoom(zp);
+ setTransform(skinTransform());
+ QApplication::restoreOverrideCursor();
+}
+
+void ZoomablePreviewDeviceSkin::populateContextMenu(QMenu *menu)
+{
+ if (!m_zoomSubMenuAction) {
+ m_zoomSubMenuAction = new QAction(tr("&Zoom"), this);
+ QMenu *zoomSubMenu = new QMenu;
+ m_zoomSubMenuAction->setMenu(zoomSubMenu);
+ m_zoomMenu->addActions(zoomSubMenu);
+ }
+ menu->addAction(m_zoomSubMenuAction);
+ menu->addSeparator();
+}
+
+QMatrix ZoomablePreviewDeviceSkin::skinTransform() const
+{
+ // Complete transformation consisting of base class rotation and zoom.
+ QMatrix rc = PreviewDeviceSkin::skinTransform();
+ const int zp = zoomPercent();
+ if (zp != 100) {
+ const qreal factor = zoomFactor(zp);
+ rc.scale(factor, factor);
+ }
+ return rc;
+}
+
+void ZoomablePreviewDeviceSkin::fitWidget(const QSize &size)
+{
+ m_zoomWidget->resize(scaleSize(zoomPercent(), size));
+}
+
+// ------------- PreviewConfiguration
+
+static const char *styleKey = "Style";
+static const char *appStyleSheetKey = "AppStyleSheet";
+static const char *skinKey = "Skin";
+
+PreviewConfiguration::PreviewConfiguration() :
+ m_d(new PreviewConfigurationData)
+{
+}
+
+PreviewConfiguration::PreviewConfiguration(const QString &sty, const QString &applicationSheet, const QString &skin) :
+ m_d(new PreviewConfigurationData(sty, applicationSheet, skin))
+{
+}
+
+PreviewConfiguration::PreviewConfiguration(const PreviewConfiguration &o) :
+ m_d(o.m_d)
+{
+}
+
+PreviewConfiguration &PreviewConfiguration::operator=(const PreviewConfiguration &o)
+{
+ m_d.operator=(o.m_d);
+ return *this;
+}
+
+PreviewConfiguration::~PreviewConfiguration()
+{
+}
+
+void PreviewConfiguration::clear()
+{
+ PreviewConfigurationData &d = *m_d;
+ d.m_style.clear();
+ d.m_applicationStyleSheet.clear();
+ d.m_deviceSkin.clear();
+}
+
+QString PreviewConfiguration::style() const
+{
+ return m_d->m_style;
+}
+
+void PreviewConfiguration::setStyle(const QString &s)
+{
+ m_d->m_style = s;
+}
+
+// Style sheet to prepend (to simulate the effect od QApplication::setSyleSheet()).
+QString PreviewConfiguration::applicationStyleSheet() const
+{
+ return m_d->m_applicationStyleSheet;
+}
+
+void PreviewConfiguration::setApplicationStyleSheet(const QString &as)
+{
+ m_d->m_applicationStyleSheet = as;
+}
+
+QString PreviewConfiguration::deviceSkin() const
+{
+ return m_d->m_deviceSkin;
+}
+
+void PreviewConfiguration::setDeviceSkin(const QString &s)
+{
+ m_d->m_deviceSkin = s;
+}
+
+void PreviewConfiguration::toSettings(const QString &prefix, QDesignerSettingsInterface *settings) const
+{
+ const PreviewConfigurationData &d = *m_d;
+ settings->beginGroup(prefix);
+ settings->setValue(QLatin1String(styleKey), d.m_style);
+ settings->setValue(QLatin1String(appStyleSheetKey), d.m_applicationStyleSheet);
+ settings->setValue(QLatin1String(skinKey), d.m_deviceSkin);
+ settings->endGroup();
+}
+
+void PreviewConfiguration::fromSettings(const QString &prefix, const QDesignerSettingsInterface *settings)
+{
+ clear();
+ QString key = prefix;
+ key += QLatin1Char('/');
+ const int prefixSize = key.size();
+
+ PreviewConfigurationData &d = *m_d;
+
+ const QVariant emptyString = QVariant(QString());
+
+ key += QLatin1String(styleKey);
+ d.m_style = settings->value(key, emptyString).toString();
+
+ key.replace(prefixSize, key.size() - prefixSize, QLatin1String(appStyleSheetKey));
+ d.m_applicationStyleSheet = settings->value(key, emptyString).toString();
+
+ key.replace(prefixSize, key.size() - prefixSize, QLatin1String(skinKey));
+ d.m_deviceSkin = settings->value(key, emptyString).toString();
+}
+
+
+QDESIGNER_SHARED_EXPORT bool operator<(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2)
+{
+ return compare(pc1, pc2) < 0;
+}
+
+QDESIGNER_SHARED_EXPORT bool operator==(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2)
+{
+ return compare(pc1, pc2) == 0;
+}
+
+QDESIGNER_SHARED_EXPORT bool operator!=(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2)
+{
+ return compare(pc1, pc2) != 0;
+}
+
+// ------------- PreviewManagerPrivate
+class PreviewManagerPrivate {
+public:
+ PreviewManagerPrivate(PreviewManager::PreviewMode mode);
+
+ const PreviewManager::PreviewMode m_mode;
+
+ QPointer<QWidget> m_activePreview;
+
+ typedef QList<PreviewData> PreviewDataList;
+
+ PreviewDataList m_previews;
+
+ typedef QMap<QString, DeviceSkinParameters> DeviceSkinConfigCache;
+ DeviceSkinConfigCache m_deviceSkinConfigCache;
+
+ QDesignerFormEditorInterface *m_core;
+ bool m_updateBlocked;
+};
+
+PreviewManagerPrivate::PreviewManagerPrivate(PreviewManager::PreviewMode mode) :
+ m_mode(mode),
+ m_core(0),
+ m_updateBlocked(false)
+{
+}
+
+// ------------- PreviewManager
+
+PreviewManager::PreviewManager(PreviewMode mode, QObject *parent) :
+ QObject(parent),
+ d(new PreviewManagerPrivate(mode))
+{
+}
+
+PreviewManager:: ~PreviewManager()
+{
+ delete d;
+}
+
+
+Qt::WindowFlags PreviewManager::previewWindowFlags(const QWidget *widget) const
+{
+#ifdef Q_WS_WIN
+ Qt::WindowFlags windowFlags = (widget->windowType() == Qt::Window) ? Qt::Window | Qt::WindowMaximizeButtonHint : Qt::WindowFlags(Qt::Dialog);
+#else
+ Q_UNUSED(widget)
+ // Only Dialogs have close buttons on Mac.
+ // On Linux, we don't want an additional task bar item and we don't want a minimize button;
+ // we want the preview to be on top.
+ Qt::WindowFlags windowFlags = Qt::Dialog;
+#endif
+ return windowFlags;
+}
+
+QWidget *PreviewManager::createDeviceSkinContainer(const QDesignerFormWindowInterface *fw) const
+{
+ return new QDialog(fw->window());
+}
+
+// Some widgets might require fake containers
+
+static QWidget *fakeContainer(QWidget *w)
+{
+ // Prevent a dock widget from trying to dock to Designer's main window
+ // (which can be found in the parent hierarchy in MDI mode) by
+ // providing a fake mainwindow
+ if (QDockWidget *dock = qobject_cast<QDockWidget *>(w)) {
+ // Reparent: Clear modality, propagate title and resize outer container
+ const QSize size = w->size();
+ w->setWindowModality(Qt::NonModal);
+ dock->setFeatures(dock->features() & ~(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetClosable));
+ dock->setAllowedAreas(Qt::LeftDockWidgetArea);
+ QMainWindow *mw = new QMainWindow;
+ int leftMargin, topMargin, rightMargin, bottomMargin;
+ mw->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
+ mw->addDockWidget(Qt::LeftDockWidgetArea, dock);
+ mw->resize(size + QSize(leftMargin + rightMargin, topMargin + bottomMargin));
+ return mw;
+ }
+ return w;
+}
+
+static PreviewConfiguration configurationFromSettings(QDesignerFormEditorInterface *core, const QString &style)
+{
+ qdesigner_internal::PreviewConfiguration pc;
+ const QDesignerSharedSettings settings(core);
+ if (settings.isCustomPreviewConfigurationEnabled())
+ pc = settings.customPreviewConfiguration();
+ if (!style.isEmpty())
+ pc.setStyle(style);
+ return pc;
+}
+
+QWidget *PreviewManager::showPreview(const QDesignerFormWindowInterface *fw, const QString &style, int deviceProfileIndex, QString *errorMessage)
+{
+ return showPreview(fw, configurationFromSettings(fw->core(), style), deviceProfileIndex, errorMessage);
+}
+
+QWidget *PreviewManager::showPreview(const QDesignerFormWindowInterface *fw, const QString &style, QString *errorMessage)
+{
+ return showPreview(fw, style, -1, errorMessage);
+}
+
+QWidget *PreviewManager::createPreview(const QDesignerFormWindowInterface *fw,
+ const PreviewConfiguration &pc,
+ int deviceProfileIndex,
+ QString *errorMessage,
+ int initialZoom)
+{
+ if (!d->m_core)
+ d->m_core = fw->core();
+
+ const bool zoomable = initialZoom > 0;
+ // Figure out which profile to apply
+ DeviceProfile deviceProfile;
+ if (deviceProfileIndex >= 0) {
+ deviceProfile = QDesignerSharedSettings(fw->core()).deviceProfileAt(deviceProfileIndex);
+ } else {
+ if (const FormWindowBase *fwb = qobject_cast<const FormWindowBase *>(fw))
+ deviceProfile = fwb->deviceProfile();
+ }
+ // Create
+ QWidget *formWidget = QDesignerFormBuilder::createPreview(fw, pc.style(), pc.applicationStyleSheet(), deviceProfile, errorMessage);
+ if (!formWidget)
+ return 0;
+
+ const QString title = tr("%1 - [Preview]").arg(formWidget->windowTitle());
+ formWidget = fakeContainer(formWidget);
+ formWidget->setWindowTitle(title);
+
+ // Clear any modality settings, child widget modalities must not be higher than parent's
+ formWidget->setWindowModality(Qt::NonModal);
+ // No skin
+ const QString deviceSkin = pc.deviceSkin();
+ if (deviceSkin.isEmpty()) {
+ if (zoomable) { // Embed into ZoomWidget
+ ZoomWidget *zw = new DesignerZoomWidget;
+ connect(zw->zoomMenu(), SIGNAL(zoomChanged(int)), this, SLOT(slotZoomChanged(int)));
+ zw->setWindowTitle(title);
+ zw->setWidget(formWidget);
+ // Keep any widgets' context menus working, do not use global menu
+ zw->setWidgetZoomContextMenuEnabled(true);
+ zw->setParent(fw->window(), previewWindowFlags(formWidget));
+ // Make preview close when Widget closes (Dialog/accept, etc)
+ formWidget->setAttribute(Qt::WA_DeleteOnClose, true);
+ connect(formWidget, SIGNAL(destroyed()), zw, SLOT(close()));
+ zw->setZoom(initialZoom);
+ zw->setProperty(WidgetFactory::disableStyleCustomPaintingPropertyC, QVariant(true));
+ return zw;
+ }
+ formWidget->setParent(fw->window(), previewWindowFlags(formWidget));
+ formWidget->setProperty(WidgetFactory::disableStyleCustomPaintingPropertyC, QVariant(true));
+ return formWidget;
+ }
+ // Embed into skin. find config in cache
+ PreviewManagerPrivate::DeviceSkinConfigCache::iterator it = d->m_deviceSkinConfigCache.find(deviceSkin);
+ if (it == d->m_deviceSkinConfigCache.end()) {
+ DeviceSkinParameters parameters;
+ if (!parameters.read(deviceSkin, DeviceSkinParameters::ReadAll, errorMessage)) {
+ formWidget->deleteLater();
+ return 0;
+ }
+ it = d->m_deviceSkinConfigCache.insert(deviceSkin, parameters);
+ }
+
+ QWidget *skinContainer = createDeviceSkinContainer(fw);
+ PreviewDeviceSkin *skin = 0;
+ if (zoomable) {
+ ZoomablePreviewDeviceSkin *zds = new ZoomablePreviewDeviceSkin(it.value(), skinContainer);
+ zds->setZoomPercent(initialZoom);
+ connect(zds, SIGNAL(zoomPercentChanged(int)), this, SLOT(slotZoomChanged(int)));
+ skin = zds;
+ } else {
+ skin = new PreviewDeviceSkin(it.value(), skinContainer);
+ }
+ skin->setPreview(formWidget);
+ // Make preview close when Widget closes (Dialog/accept, etc)
+ formWidget->setAttribute(Qt::WA_DeleteOnClose, true);
+ connect(formWidget, SIGNAL(destroyed()), skinContainer, SLOT(close()));
+ skinContainer->setWindowTitle(title);
+ skinContainer->setProperty(WidgetFactory::disableStyleCustomPaintingPropertyC, QVariant(true));
+ return skinContainer;
+}
+
+QWidget *PreviewManager::showPreview(const QDesignerFormWindowInterface *fw,
+ const PreviewConfiguration &pc,
+ int deviceProfileIndex,
+ QString *errorMessage)
+{
+ enum { Spacing = 10 };
+ if (QWidget *existingPreviewWidget = raise(fw, pc))
+ return existingPreviewWidget;
+
+ const QDesignerSharedSettings settings(fw->core());
+ const int initialZoom = settings.zoomEnabled() ? settings.zoom() : -1;
+
+ QWidget *widget = createPreview(fw, pc, deviceProfileIndex, errorMessage, initialZoom);
+ if (!widget)
+ return 0;
+ // Install filter for Escape key
+ widget->setAttribute(Qt::WA_DeleteOnClose, true);
+ widget->installEventFilter(this);
+
+ switch (d->m_mode) {
+ case ApplicationModalPreview:
+ // Cannot do this on the Mac as the dialog would have no close button
+ widget->setWindowModality(Qt::ApplicationModal);
+ break;
+ case SingleFormNonModalPreview:
+ case MultipleFormNonModalPreview:
+ widget->setWindowModality(Qt::NonModal);
+ connect(fw, SIGNAL(changed()), widget, SLOT(close()));
+ connect(fw, SIGNAL(destroyed()), widget, SLOT(close()));
+ if (d->m_mode == SingleFormNonModalPreview)
+ connect(fw->core()->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)), widget, SLOT(close()));
+ break;
+ }
+ // Semi-smart algorithm to position previews:
+ // If its the first one, position relative to form.
+ // 2nd, attempt to tile right (for comparing styles) or cascade
+ const QSize size = widget->size();
+ const bool firstPreview = d->m_previews.empty();
+ if (firstPreview) {
+ widget->move(fw->mapToGlobal(QPoint(Spacing, Spacing)));
+ } else {
+ if (QWidget *lastPreview = d->m_previews.back().m_widget) {
+ QDesktopWidget *desktop = qApp->desktop();
+ const QRect lastPreviewGeometry = lastPreview->frameGeometry();
+ const QRect availGeometry = desktop->availableGeometry(desktop->screenNumber(lastPreview));
+ const QPoint newPos = lastPreviewGeometry.topRight() + QPoint(Spacing, 0);
+ if (newPos.x() + size.width() < availGeometry.right())
+ widget->move(newPos);
+ else
+ widget->move(lastPreviewGeometry.topLeft() + QPoint(Spacing, Spacing));
+ }
+
+ }
+ d->m_previews.push_back(PreviewData(widget, fw, pc));
+ widget->show();
+ if (firstPreview)
+ emit firstPreviewOpened();
+ return widget;
+}
+
+QWidget *PreviewManager::raise(const QDesignerFormWindowInterface *fw, const PreviewConfiguration &pc)
+{
+ typedef PreviewManagerPrivate::PreviewDataList PreviewDataList;
+ if (d->m_previews.empty())
+ return false;
+
+ // find matching window
+ const PreviewDataList::const_iterator cend = d->m_previews.constEnd();
+ for (PreviewDataList::const_iterator it = d->m_previews.constBegin(); it != cend ;++it) {
+ QWidget * w = it->m_widget;
+ if (w && it->m_formWindow == fw && it->m_configuration == pc) {
+ w->raise();
+ w->activateWindow();
+ return w;
+ }
+ }
+ return 0;
+}
+
+void PreviewManager::closeAllPreviews()
+{
+ typedef PreviewManagerPrivate::PreviewDataList PreviewDataList;
+ if (!d->m_previews.empty()) {
+ d->m_updateBlocked = true;
+ d->m_activePreview = 0;
+ const PreviewDataList::iterator cend = d->m_previews.end();
+ for (PreviewDataList::iterator it = d->m_previews.begin(); it != cend ;++it) {
+ if (it->m_widget)
+ it->m_widget->close();
+ }
+ d->m_previews.clear();
+ d->m_updateBlocked = false;
+ emit lastPreviewClosed();
+ }
+}
+
+void PreviewManager::updatePreviewClosed(QWidget *w)
+{
+ typedef PreviewManagerPrivate::PreviewDataList PreviewDataList;
+ if (d->m_updateBlocked)
+ return;
+ // Purge out all 0 or widgets to be deleted
+ for (PreviewDataList::iterator it = d->m_previews.begin(); it != d->m_previews.end() ; ) {
+ QWidget *iw = it->m_widget; // Might be 0 when catching QEvent::Destroyed
+ if (iw == 0 || iw == w) {
+ it = d->m_previews.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ if (d->m_previews.empty())
+ emit lastPreviewClosed();
+}
+
+bool PreviewManager::eventFilter(QObject *watched, QEvent *event)
+{
+ // Courtesy of designer
+ do {
+ if (!watched->isWidgetType())
+ break;
+ QWidget *previewWindow = qobject_cast<QWidget *>(watched);
+ if (!previewWindow || !previewWindow->isWindow())
+ break;
+
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ case QEvent::ShortcutOverride: {
+ const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
+ const int key = keyEvent->key();
+ if ((key == Qt::Key_Escape
+#ifdef Q_WS_MAC
+ || (keyEvent->modifiers() == Qt::ControlModifier && key == Qt::Key_Period)
+#endif
+ )) {
+ previewWindow->close();
+ return true;
+ }
+ }
+ break;
+ case QEvent::WindowActivate:
+ d->m_activePreview = previewWindow;
+ break;
+ case QEvent::Destroy: // We don't get QEvent::Close if someone accepts a QDialog.
+ updatePreviewClosed(previewWindow);
+ break;
+ case QEvent::Close:
+ updatePreviewClosed(previewWindow);
+ previewWindow->removeEventFilter (this);
+ break;
+ default:
+ break;
+ }
+ } while(false);
+ return QObject::eventFilter(watched, event);
+}
+
+int PreviewManager::previewCount() const
+{
+ return d->m_previews.size();
+}
+
+QPixmap PreviewManager::createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &style, int deviceProfileIndex, QString *errorMessage)
+{
+ return createPreviewPixmap(fw, configurationFromSettings(fw->core(), style), deviceProfileIndex, errorMessage);
+}
+
+QPixmap PreviewManager::createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &style, QString *errorMessage)
+{
+ return createPreviewPixmap(fw, style, -1, errorMessage);
+}
+
+QPixmap PreviewManager::createPreviewPixmap(const QDesignerFormWindowInterface *fw,
+ const PreviewConfiguration &pc,
+ int deviceProfileIndex,
+ QString *errorMessage)
+{
+ QWidget *widget = createPreview(fw, pc, deviceProfileIndex, errorMessage);
+ if (!widget)
+ return QPixmap();
+ const QPixmap rc = QPixmap::grabWidget(widget);
+ widget->deleteLater();
+ return rc;
+}
+
+void PreviewManager::slotZoomChanged(int z)
+{
+ if (d->m_core) { // Save the last zoom chosen by the user.
+ QDesignerSharedSettings settings(d->m_core);
+ settings.setZoom(z);
+ }
+}
+}
+
+QT_END_NAMESPACE
+
+#include "previewmanager.moc"
diff --git a/src/designer/src/lib/shared/previewmanager_p.h b/src/designer/src/lib/shared/previewmanager_p.h
new file mode 100644
index 000000000..3ca8619ce
--- /dev/null
+++ b/src/designer/src/lib/shared/previewmanager_p.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PREVIEWMANAGER_H
+#define PREVIEWMANAGER_H
+
+#include "shared_global_p.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QWidget;
+class QPixmap;
+class QAction;
+class QActionGroup;
+class QMenu;
+class QWidget;
+class QDesignerSettingsInterface;
+
+namespace qdesigner_internal {
+
+// ----------- PreviewConfiguration
+
+class PreviewConfigurationData;
+
+class QDESIGNER_SHARED_EXPORT PreviewConfiguration {
+public:
+ PreviewConfiguration();
+ explicit PreviewConfiguration(const QString &style,
+ const QString &applicationStyleSheet = QString(),
+ const QString &deviceSkin = QString());
+
+ PreviewConfiguration(const PreviewConfiguration&);
+ PreviewConfiguration& operator=(const PreviewConfiguration&);
+ ~PreviewConfiguration();
+
+ QString style() const;
+ void setStyle(const QString &);
+
+ // Style sheet to prepend (to simulate the effect od QApplication::setSyleSheet()).
+ QString applicationStyleSheet() const;
+ void setApplicationStyleSheet(const QString &);
+
+ QString deviceSkin() const;
+ void setDeviceSkin(const QString &);
+
+ void clear();
+ void toSettings(const QString &prefix, QDesignerSettingsInterface *settings) const;
+ void fromSettings(const QString &prefix, const QDesignerSettingsInterface *settings);
+
+private:
+ QSharedDataPointer<PreviewConfigurationData> m_d;
+};
+
+QDESIGNER_SHARED_EXPORT bool operator<(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2);
+QDESIGNER_SHARED_EXPORT bool operator==(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2);
+QDESIGNER_SHARED_EXPORT bool operator!=(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2);
+
+// ----------- Preview window manager.
+// Maintains a list of preview widgets with their associated form windows and configuration.
+
+class PreviewManagerPrivate;
+
+class QDESIGNER_SHARED_EXPORT PreviewManager : public QObject
+{
+ Q_OBJECT
+public:
+
+ enum PreviewMode {
+ // Modal preview. Do not use on Macs as dialogs would have no close button
+ ApplicationModalPreview,
+ // Non modal previewing of one form in different configurations (closes if form window changes)
+ SingleFormNonModalPreview,
+ // Non modal previewing of several forms in different configurations
+ MultipleFormNonModalPreview };
+
+ explicit PreviewManager(PreviewMode mode, QObject *parent);
+ virtual ~PreviewManager();
+
+ // Show preview. Raise existing preview window if there is one with a matching
+ // configuration, else create a new preview.
+ QWidget *showPreview(const QDesignerFormWindowInterface *, const PreviewConfiguration &pc, int deviceProfileIndex /*=-1*/, QString *errorMessage);
+ // Convenience that creates a preview using a configuration taken from the settings.
+ QWidget *showPreview(const QDesignerFormWindowInterface *, const QString &style, int deviceProfileIndex /*=-1*/, QString *errorMessage);
+ QWidget *showPreview(const QDesignerFormWindowInterface *, const QString &style, QString *errorMessage);
+
+ int previewCount() const;
+
+ // Create a pixmap for printing.
+ QPixmap createPreviewPixmap(const QDesignerFormWindowInterface *fw, const PreviewConfiguration &pc, int deviceProfileIndex /*=-1*/, QString *errorMessage);
+ // Convenience that creates a pixmap using a configuration taken from the settings.
+ QPixmap createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &style, int deviceProfileIndex /*=-1*/, QString *errorMessage);
+ QPixmap createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &style, QString *errorMessage);
+
+ virtual bool eventFilter(QObject *watched, QEvent *event);
+
+public slots:
+ void closeAllPreviews();
+
+signals:
+ void firstPreviewOpened();
+ void lastPreviewClosed();
+
+private slots:
+ void slotZoomChanged(int);
+
+private:
+
+ virtual Qt::WindowFlags previewWindowFlags(const QWidget *widget) const;
+ virtual QWidget *createDeviceSkinContainer(const QDesignerFormWindowInterface *) const;
+
+ QWidget *raise(const QDesignerFormWindowInterface *, const PreviewConfiguration &pc);
+ QWidget *createPreview(const QDesignerFormWindowInterface *,
+ const PreviewConfiguration &pc,
+ int deviceProfileIndex /* = -1 */,
+ QString *errorMessage,
+ /*Disabled by default, <0 */
+ int initialZoom = -1);
+
+ void updatePreviewClosed(QWidget *w);
+
+ PreviewManagerPrivate *d;
+
+ PreviewManager(const PreviewManager &other);
+ PreviewManager &operator =(const PreviewManager &other);
+};
+}
+
+QT_END_NAMESPACE
+
+#endif // PREVIEWMANAGER_H
diff --git a/src/designer/src/lib/shared/promotionmodel.cpp b/src/designer/src/lib/shared/promotionmodel.cpp
new file mode 100644
index 000000000..deab66fa1
--- /dev/null
+++ b/src/designer/src/lib/shared/promotionmodel.cpp
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "promotionmodel_p.h"
+#include "widgetdatabase_p.h"
+
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QDesignerPromotionInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QStandardItem>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ typedef QList<QStandardItem *> StandardItemList;
+
+ // Model columns.
+ enum { ClassNameColumn, IncludeFileColumn, IncludeTypeColumn, ReferencedColumn, NumColumns };
+
+ // Create a model row.
+ StandardItemList modelRow() {
+ StandardItemList rc;
+ for (int i = 0; i < NumColumns; i++) {
+ rc.push_back(new QStandardItem());
+ }
+ return rc;
+ }
+
+ // Create a model row for a base class (read-only, cannot be selected).
+ StandardItemList baseModelRow(const QDesignerWidgetDataBaseItemInterface *dbItem) {
+ StandardItemList rc = modelRow();
+
+ rc[ClassNameColumn]->setText(dbItem->name());
+ for (int i = 0; i < NumColumns; i++) {
+ rc[i]->setFlags(Qt::ItemIsEnabled);
+ }
+ return rc;
+ }
+
+ // Create an editable model row for a promoted class.
+ StandardItemList promotedModelRow(const QDesignerWidgetDataBaseInterface *widgetDataBase,
+ QDesignerWidgetDataBaseItemInterface *dbItem,
+ bool referenced = false) {
+
+ const int index = widgetDataBase->indexOf(dbItem);
+
+ // Associate user data: database index and enabled flag
+ QVariantList userDataList;
+ userDataList.push_back(QVariant(index));
+ userDataList.push_back(QVariant(referenced));
+ const QVariant userData(userDataList);
+
+ StandardItemList rc = modelRow();
+ // name
+ rc[ClassNameColumn]->setText(dbItem->name());
+ rc[ClassNameColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable);
+ rc[ClassNameColumn]->setData(userData);
+ // header
+ const qdesigner_internal::IncludeSpecification spec = qdesigner_internal::includeSpecification(dbItem->includeFile());
+ rc[IncludeFileColumn]->setText(spec.first);
+ rc[IncludeFileColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable);
+ rc[IncludeFileColumn]->setData(userData);
+ // global include
+ rc[IncludeTypeColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsUserCheckable);
+ rc[IncludeTypeColumn]->setData(userData);
+ rc[IncludeTypeColumn]->setCheckState(spec.second == qdesigner_internal::IncludeGlobal ? Qt::Checked : Qt::Unchecked);
+ // referenced
+ rc[ReferencedColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
+ rc[ClassNameColumn]->setData(userData);
+ if (!referenced) {
+ //: Usage of promoted widgets
+ static const QString notUsed = QCoreApplication::translate("PromotionModel", "Not used");
+ rc[ReferencedColumn]->setText(notUsed);
+ }
+ return rc;
+ }
+}
+
+namespace qdesigner_internal {
+
+ PromotionModel::PromotionModel(QDesignerFormEditorInterface *core) :
+ m_core(core)
+ {
+ connect(this, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(slotItemChanged(QStandardItem*)));
+ }
+
+ void PromotionModel::initializeHeaders() {
+ setColumnCount(NumColumns);
+ QStringList horizontalLabels(tr("Name"));
+ horizontalLabels += tr("Header file");
+ horizontalLabels += tr("Global include");
+ horizontalLabels += tr("Usage");
+ setHorizontalHeaderLabels (horizontalLabels);
+ }
+
+ void PromotionModel::updateFromWidgetDatabase() {
+ typedef QDesignerPromotionInterface::PromotedClasses PromotedClasses;
+
+ clear();
+ initializeHeaders();
+
+ // retrieve list of pairs from DB and convert into a tree structure.
+ // Set the item index as user data on the item.
+ const PromotedClasses promotedClasses = m_core->promotion()->promotedClasses();
+
+ if (promotedClasses.empty())
+ return;
+
+ const QSet<QString> usedPromotedClasses = m_core->promotion()->referencedPromotedClassNames();
+
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
+ QDesignerWidgetDataBaseItemInterface *baseClass = 0;
+ QStandardItem *baseItem = 0;
+
+ const PromotedClasses::const_iterator bcend = promotedClasses.constEnd();
+ for (PromotedClasses::const_iterator it = promotedClasses.constBegin(); it != bcend; ++it) {
+ // Start a new base class?
+ if (baseClass != it->baseItem) {
+ baseClass = it->baseItem;
+ const StandardItemList baseRow = baseModelRow(it->baseItem);
+ baseItem = baseRow.front();
+ appendRow(baseRow);
+ }
+ Q_ASSERT(baseItem);
+ // Append derived
+ baseItem->appendRow(promotedModelRow(widgetDataBase, it->promotedItem, usedPromotedClasses.contains(it->promotedItem->name())));
+ }
+ }
+
+ void PromotionModel::slotItemChanged(QStandardItem * changedItem) {
+ // Retrieve DB item
+ bool referenced;
+ QDesignerWidgetDataBaseItemInterface *dbItem = databaseItem(changedItem, &referenced);
+ Q_ASSERT(dbItem);
+ // Change header or type
+ switch (changedItem->column()) {
+ case ClassNameColumn:
+ emit classNameChanged(dbItem, changedItem->text());
+ break;
+ case IncludeTypeColumn:
+ case IncludeFileColumn: {
+ // Get both file and type items via parent.
+ const QStandardItem *baseClassItem = changedItem->parent();
+ const QStandardItem *fileItem = baseClassItem->child(changedItem->row(), IncludeFileColumn);
+ const QStandardItem *typeItem = baseClassItem->child(changedItem->row(), IncludeTypeColumn);
+ emit includeFileChanged(dbItem, buildIncludeFile(fileItem->text(), typeItem->checkState() == Qt::Checked ? IncludeGlobal : IncludeLocal));
+ }
+ break;
+ }
+ }
+
+ QDesignerWidgetDataBaseItemInterface *PromotionModel::databaseItemAt(const QModelIndex &index, bool *referenced) const {
+ if (const QStandardItem *item = itemFromIndex (index))
+ return databaseItem(item, referenced);
+
+ *referenced = false;
+ return 0;
+ }
+
+ QDesignerWidgetDataBaseItemInterface *PromotionModel::databaseItem(const QStandardItem * item, bool *referenced) const {
+ // Decode user data associated with item.
+ const QVariant data = item->data();
+ if (data.type() != QVariant::List) {
+ *referenced = false;
+ return 0;
+ }
+
+ const QVariantList dataList = data.toList();
+ const int index = dataList[0].toInt();
+ *referenced = dataList[1].toBool();
+ return m_core->widgetDataBase()->item(index);
+ }
+
+ QModelIndex PromotionModel::indexOfClass(const QString &className) const {
+ const StandardItemList matches = findItems (className, Qt::MatchFixedString|Qt::MatchCaseSensitive|Qt::MatchRecursive);
+ return matches.empty() ? QModelIndex() : indexFromItem (matches.front());
+ }
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/promotionmodel_p.h b/src/designer/src/lib/shared/promotionmodel_p.h
new file mode 100644
index 000000000..214efb135
--- /dev/null
+++ b/src/designer/src/lib/shared/promotionmodel_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PROMOTIONMODEL_H
+#define PROMOTIONMODEL_H
+
+#include <QtGui/QStandardItemModel>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerWidgetDataBaseItemInterface;
+
+namespace qdesigner_internal {
+
+ // Item model representing the promoted widgets.
+ class PromotionModel : public QStandardItemModel {
+ Q_OBJECT
+
+ public:
+ explicit PromotionModel(QDesignerFormEditorInterface *core);
+
+ void updateFromWidgetDatabase();
+
+ // Return item at model index or 0.
+ QDesignerWidgetDataBaseItemInterface *databaseItemAt(const QModelIndex &, bool *referenced) const;
+
+ QModelIndex indexOfClass(const QString &className) const;
+
+ signals:
+ void includeFileChanged(QDesignerWidgetDataBaseItemInterface *, const QString &includeFile);
+ void classNameChanged(QDesignerWidgetDataBaseItemInterface *, const QString &newName);
+
+ private slots:
+ void slotItemChanged(QStandardItem * item);
+
+ private:
+ void initializeHeaders();
+ // Retrieve data base item of item or return 0.
+ QDesignerWidgetDataBaseItemInterface *databaseItem(const QStandardItem * item, bool *referenced) const;
+
+ QDesignerFormEditorInterface *m_core;
+ };
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // PROMOTIONMODEL_H
diff --git a/src/designer/src/lib/shared/promotiontaskmenu.cpp b/src/designer/src/lib/shared/promotiontaskmenu.cpp
new file mode 100644
index 000000000..dc76ef6cf
--- /dev/null
+++ b/src/designer/src/lib/shared/promotiontaskmenu.cpp
@@ -0,0 +1,361 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "promotiontaskmenu_p.h"
+#include "qdesigner_promotiondialog_p.h"
+#include "widgetfactory_p.h"
+#include "metadatabase_p.h"
+#include "widgetdatabase_p.h"
+#include "qdesigner_command_p.h"
+#include "signalslotdialog_p.h"
+#include "qdesigner_objectinspector_p.h"
+#include "abstractintrospection_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QAction>
+#include <QtGui/QWidget>
+#include <QtGui/QMenu>
+#include <QtCore/QSignalMapper>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+static QAction *separatorAction(QObject *parent)
+{
+ QAction *rc = new QAction(parent);
+ rc->setSeparator(true);
+ return rc;
+}
+
+static inline QDesignerLanguageExtension *languageExtension(QDesignerFormEditorInterface *core)
+{
+ return qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core);
+}
+
+namespace qdesigner_internal {
+
+PromotionTaskMenu::PromotionTaskMenu(QWidget *widget,Mode mode, QObject *parent) :
+ QObject(parent),
+ m_mode(mode),
+ m_widget(widget),
+ m_promotionMapper(0),
+ m_globalEditAction(new QAction(tr("Promoted widgets..."), this)),
+ m_EditPromoteToAction(new QAction(tr("Promote to ..."), this)),
+ m_EditSignalsSlotsAction(new QAction(tr("Change signals/slots..."), this)),
+ m_promoteLabel(tr("Promote to")),
+ m_demoteLabel(tr("Demote to %1"))
+{
+ connect(m_globalEditAction, SIGNAL(triggered()), this, SLOT(slotEditPromotedWidgets()));
+ connect(m_EditPromoteToAction, SIGNAL(triggered()), this, SLOT(slotEditPromoteTo()));
+ connect(m_EditSignalsSlotsAction, SIGNAL(triggered()), this, SLOT(slotEditSignalsSlots()));
+}
+
+PromotionTaskMenu::Mode PromotionTaskMenu::mode() const
+{
+ return m_mode;
+}
+
+void PromotionTaskMenu::setMode(Mode m)
+{
+ m_mode = m;
+}
+
+void PromotionTaskMenu::setWidget(QWidget *widget)
+{
+ m_widget = widget;
+}
+
+void PromotionTaskMenu::setPromoteLabel(const QString &promoteLabel)
+{
+ m_promoteLabel = promoteLabel;
+}
+
+void PromotionTaskMenu::setEditPromoteToLabel(const QString &promoteEditLabel)
+{
+ m_EditPromoteToAction->setText(promoteEditLabel);
+}
+
+void PromotionTaskMenu::setDemoteLabel(const QString &demoteLabel)
+{
+ m_demoteLabel = demoteLabel;
+}
+
+PromotionTaskMenu::PromotionState PromotionTaskMenu::createPromotionActions(QDesignerFormWindowInterface *formWindow)
+{
+ // clear out old
+ if (!m_promotionActions.empty()) {
+ qDeleteAll(m_promotionActions);
+ m_promotionActions.clear();
+ }
+ // No promotion of main container
+ if (formWindow->mainContainer() == m_widget)
+ return NotApplicable;
+
+ // Check for a homogenous selection
+ const PromotionSelectionList promotionSelection = promotionSelectionList(formWindow);
+
+ if (promotionSelection.empty())
+ return NoHomogenousSelection;
+
+ QDesignerFormEditorInterface *core = formWindow->core();
+ // if it is promoted: demote only.
+ if (isPromoted(formWindow->core(), m_widget)) {
+ const QString label = m_demoteLabel.arg( promotedExtends(core , m_widget));
+ QAction *demoteAction = new QAction(label, this);
+ connect(demoteAction, SIGNAL(triggered()), this, SLOT(slotDemoteFromCustomWidget()));
+ m_promotionActions.push_back(demoteAction);
+ return CanDemote;
+ }
+ // figure out candidates
+ const QString baseClassName = WidgetFactory::classNameOf(core, m_widget);
+ const WidgetDataBaseItemList candidates = promotionCandidates(core->widgetDataBase(), baseClassName );
+ if (candidates.empty()) {
+ // Is this thing promotable at all?
+ return QDesignerPromotionDialog::baseClassNames(core->promotion()).contains(baseClassName) ? CanPromote : NotApplicable;
+ }
+ // Set up a signal mapper to associate class names
+ if (!m_promotionMapper) {
+ m_promotionMapper = new QSignalMapper(this);
+ connect(m_promotionMapper, SIGNAL(mapped(QString)), this, SLOT(slotPromoteToCustomWidget(QString)));
+ }
+
+ QMenu *candidatesMenu = new QMenu();
+ // Create a sub menu
+ const WidgetDataBaseItemList::const_iterator cend = candidates.constEnd();
+ // Set up actions and map class names
+ for (WidgetDataBaseItemList::const_iterator it = candidates.constBegin(); it != cend; ++it) {
+ const QString customClassName = (*it)->name();
+ QAction *action = new QAction((*it)->name(), this);
+ connect(action, SIGNAL(triggered()), m_promotionMapper, SLOT(map()));
+ m_promotionMapper->setMapping(action, customClassName);
+ candidatesMenu->addAction(action);
+ }
+ // Sub menu action
+ QAction *subMenuAction = new QAction(m_promoteLabel, this);
+ subMenuAction->setMenu(candidatesMenu);
+ m_promotionActions.push_back(subMenuAction);
+ return CanPromote;
+}
+
+void PromotionTaskMenu::addActions(unsigned separatorFlags, ActionList &actionList)
+{
+ addActions(formWindow(), separatorFlags, actionList);
+}
+
+void PromotionTaskMenu::addActions(QDesignerFormWindowInterface *fw, unsigned flags,
+ ActionList &actionList)
+{
+ Q_ASSERT(m_widget);
+ const int previousSize = actionList.size();
+ const PromotionState promotionState = createPromotionActions(fw);
+
+ // Promotion candidates/demote
+ actionList += m_promotionActions;
+
+ // Edit action depending on context
+ switch (promotionState) {
+ case CanPromote:
+ actionList += m_EditPromoteToAction;
+ break;
+ case CanDemote:
+ if (!(flags & SuppressGlobalEdit))
+ actionList += m_globalEditAction;
+ if (!languageExtension(fw->core())) {
+ actionList += separatorAction(this);
+ actionList += m_EditSignalsSlotsAction;
+ }
+ break;
+ default:
+ if (!(flags & SuppressGlobalEdit))
+ actionList += m_globalEditAction;
+ break;
+ }
+ // Add separators if required
+ if (actionList.size() > previousSize) {
+ if (flags & LeadingSeparator)
+ actionList.insert(previousSize, separatorAction(this));
+ if (flags & TrailingSeparator)
+ actionList += separatorAction(this);
+ }
+}
+
+void PromotionTaskMenu::addActions(QDesignerFormWindowInterface *fw, unsigned flags, QMenu *menu)
+{
+ ActionList actionList;
+ addActions(fw, flags, actionList);
+ menu->addActions(actionList);
+}
+
+void PromotionTaskMenu::addActions(unsigned flags, QMenu *menu)
+{
+ addActions(formWindow(), flags, menu);
+}
+
+void PromotionTaskMenu::promoteTo(QDesignerFormWindowInterface *fw, const QString &customClassName)
+{
+ Q_ASSERT(m_widget);
+ PromoteToCustomWidgetCommand *cmd = new PromoteToCustomWidgetCommand(fw);
+ cmd->init(promotionSelectionList(fw), customClassName);
+ fw->commandHistory()->push(cmd);
+}
+
+
+void PromotionTaskMenu::slotPromoteToCustomWidget(const QString &customClassName)
+{
+ promoteTo(formWindow(), customClassName);
+}
+
+void PromotionTaskMenu::slotDemoteFromCustomWidget()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ const PromotionSelectionList promotedWidgets = promotionSelectionList(fw);
+ Q_ASSERT(!promotedWidgets.empty() && isPromoted(fw->core(), promotedWidgets.front()));
+
+ // ### use the undo stack
+ DemoteFromCustomWidgetCommand *cmd = new DemoteFromCustomWidgetCommand(fw);
+ cmd->init(promotedWidgets);
+ fw->commandHistory()->push(cmd);
+}
+
+void PromotionTaskMenu::slotEditPromoteTo()
+{
+ Q_ASSERT(m_widget);
+ // Check whether invoked over a promotable widget
+ QDesignerFormWindowInterface *fw = formWindow();
+ QDesignerFormEditorInterface *core = fw->core();
+ const QString base_class_name = WidgetFactory::classNameOf(core, m_widget);
+ Q_ASSERT(QDesignerPromotionDialog::baseClassNames(core->promotion()).contains(base_class_name));
+ // Show over promotable widget
+ QString promoteToClassName;
+ QDialog *promotionEditor = 0;
+ if (QDesignerLanguageExtension *lang = languageExtension(core))
+ promotionEditor = lang->createPromotionDialog(core, base_class_name, &promoteToClassName, fw);
+ if (!promotionEditor)
+ promotionEditor = new QDesignerPromotionDialog(core, fw, base_class_name, &promoteToClassName);
+ if (promotionEditor->exec() == QDialog::Accepted && !promoteToClassName.isEmpty()) {
+ promoteTo(fw, promoteToClassName);
+ }
+ delete promotionEditor;
+}
+
+void PromotionTaskMenu::slotEditPromotedWidgets()
+{
+ // Global context, show over non-promotable widget
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+ editPromotedWidgets(fw->core(), fw);
+}
+
+PromotionTaskMenu::PromotionSelectionList PromotionTaskMenu::promotionSelectionList(QDesignerFormWindowInterface *formWindow) const
+{
+ // In multi selection mode, check for a homogenous selection (same class, same promotion state)
+ // and return the list if this is the case. Also make sure m_widget
+ // is the last widget in the list so that it is re-selected as the last
+ // widget by the promotion commands.
+
+ PromotionSelectionList rc;
+
+ if (m_mode != ModeSingleWidget) {
+ QDesignerFormEditorInterface *core = formWindow->core();
+ const QDesignerIntrospectionInterface *intro = core->introspection();
+ const QString className = intro->metaObject(m_widget)->className();
+ const bool promoted = isPromoted(formWindow->core(), m_widget);
+ // Just in case someone plugged an old-style Object Inspector
+ if (QDesignerObjectInspector *designerObjectInspector = qobject_cast<QDesignerObjectInspector *>(core->objectInspector())) {
+ Selection s;
+ designerObjectInspector->getSelection(s);
+ // Find objects of similar state
+ const QWidgetList &source = m_mode == ModeManagedMultiSelection ? s.managed : s.unmanaged;
+ const QWidgetList::const_iterator cend = source.constEnd();
+ for (QWidgetList::const_iterator it = source.constBegin(); it != cend; ++it) {
+ QWidget *w = *it;
+ if (w != m_widget) {
+ // Selection state mismatch
+ if (intro->metaObject(w)->className() != className || isPromoted(core, w) != promoted)
+ return PromotionSelectionList();
+ rc.push_back(w);
+ }
+ }
+ }
+ }
+
+ rc.push_back(m_widget);
+ return rc;
+}
+
+QDesignerFormWindowInterface *PromotionTaskMenu::formWindow() const
+{
+ // Use the QObject overload of QDesignerFormWindowInterface::findFormWindow since that works
+ // for QDesignerMenus also.
+ QObject *o = m_widget;
+ QDesignerFormWindowInterface *result = QDesignerFormWindowInterface::findFormWindow(o);
+ Q_ASSERT(result != 0);
+ return result;
+}
+
+void PromotionTaskMenu::editPromotedWidgets(QDesignerFormEditorInterface *core, QWidget* parent) {
+ QDesignerLanguageExtension *lang = languageExtension(core);
+ // Show over non-promotable widget
+ QDialog *promotionEditor = 0;
+ if (lang)
+ lang->createPromotionDialog(core, parent);
+ if (!promotionEditor)
+ promotionEditor = new QDesignerPromotionDialog(core, parent);
+ promotionEditor->exec();
+ delete promotionEditor;
+}
+
+void PromotionTaskMenu::slotEditSignalsSlots()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+ SignalSlotDialog::editPromotedClass(fw->core(), m_widget, fw);
+}
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/promotiontaskmenu_p.h b/src/designer/src/lib/shared/promotiontaskmenu_p.h
new file mode 100644
index 000000000..94bf78729
--- /dev/null
+++ b/src/designer/src/lib/shared/promotiontaskmenu_p.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PROMOTIONTASKMENU_H
+#define PROMOTIONTASKMENU_H
+
+#include "shared_global_p.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+
+class QAction;
+class QMenu;
+class QWidget;
+class QSignalMapper;
+
+namespace qdesigner_internal {
+
+// A helper class for creating promotion context menus and handling promotion actions.
+
+class QDESIGNER_SHARED_EXPORT PromotionTaskMenu: public QObject
+{
+ Q_OBJECT
+public:
+ enum Mode {
+ ModeSingleWidget,
+ ModeManagedMultiSelection,
+ ModeUnmanagedMultiSelection
+ };
+
+ explicit PromotionTaskMenu(QWidget *widget,Mode mode = ModeManagedMultiSelection, QObject *parent = 0);
+
+ Mode mode() const;
+ void setMode(Mode m);
+
+ void setWidget(QWidget *widget);
+
+ // Set menu labels
+ void setPromoteLabel(const QString &promoteLabel);
+ void setEditPromoteToLabel(const QString &promoteEditLabel);
+ // Defaults to "Demote to %1".arg(class).
+ void setDemoteLabel(const QString &demoteLabel);
+
+ typedef QList<QAction*> ActionList;
+
+ enum AddFlags { LeadingSeparator = 1, TrailingSeparator = 2, SuppressGlobalEdit = 4};
+
+ // Adds a list of promotion actions according to the current promotion state of the widget.
+ void addActions(QDesignerFormWindowInterface *fw, unsigned flags, ActionList &actionList);
+ // Convenience that finds the form window.
+ void addActions(unsigned flags, ActionList &actionList);
+
+ void addActions(QDesignerFormWindowInterface *fw, unsigned flags, QMenu *menu);
+ void addActions(unsigned flags, QMenu *menu);
+
+ // Pop up the editor in a global context.
+ static void editPromotedWidgets(QDesignerFormEditorInterface *core, QWidget* parent);
+
+private slots:
+ void slotPromoteToCustomWidget(const QString &customClassName);
+ void slotDemoteFromCustomWidget();
+ void slotEditPromotedWidgets();
+ void slotEditPromoteTo();
+ void slotEditSignalsSlots();
+
+private:
+ void promoteTo(QDesignerFormWindowInterface *fw, const QString &customClassName);
+
+ enum PromotionState { NotApplicable, NoHomogenousSelection, CanPromote, CanDemote };
+ PromotionState createPromotionActions(QDesignerFormWindowInterface *formWindow);
+ QDesignerFormWindowInterface *formWindow() const;
+
+ typedef QList<QPointer<QWidget> > PromotionSelectionList;
+ PromotionSelectionList promotionSelectionList(QDesignerFormWindowInterface *formWindow) const;
+
+ Mode m_mode;
+
+ QPointer<QWidget> m_widget;
+
+ QSignalMapper *m_promotionMapper;
+ // Per-Widget actions
+ QList<QAction *> m_promotionActions;
+
+ QAction *m_globalEditAction;
+ QAction *m_EditPromoteToAction;
+ QAction *m_EditSignalsSlotsAction;
+
+ QString m_promoteLabel;
+ QString m_demoteLabel;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // PROMOTIONTASKMENU_H
diff --git a/src/designer/src/lib/shared/propertylineedit.cpp b/src/designer/src/lib/shared/propertylineedit.cpp
new file mode 100644
index 000000000..29dff63ab
--- /dev/null
+++ b/src/designer/src/lib/shared/propertylineedit.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "propertylineedit_p.h"
+
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMenu>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ PropertyLineEdit::PropertyLineEdit(QWidget *parent) :
+ QLineEdit(parent), m_wantNewLine(false)
+ {
+ }
+
+ bool PropertyLineEdit::event(QEvent *e)
+ {
+ // handle 'Select all' here as it is not done in the QLineEdit
+ if (e->type() == QEvent::ShortcutOverride && !isReadOnly()) {
+ QKeyEvent* ke = static_cast<QKeyEvent*> (e);
+ if (ke->modifiers() & Qt::ControlModifier) {
+ if(ke->key() == Qt::Key_A) {
+ ke->accept();
+ return true;
+ }
+ }
+ }
+ return QLineEdit::event(e);
+ }
+
+ void PropertyLineEdit::insertNewLine() {
+ insertText(QLatin1String("\\n"));
+ }
+
+ void PropertyLineEdit::insertText(const QString &text) {
+ // position cursor after new text and grab focus
+ const int oldCursorPosition = cursorPosition ();
+ insert(text);
+ setCursorPosition (oldCursorPosition + text.length());
+ setFocus(Qt::OtherFocusReason);
+ }
+
+ void PropertyLineEdit::contextMenuEvent(QContextMenuEvent *event) {
+ QMenu *menu = createStandardContextMenu ();
+
+ if (m_wantNewLine) {
+ menu->addSeparator();
+ QAction* nlAction = menu->addAction(tr("Insert line break"));
+ connect(nlAction, SIGNAL(triggered()), this, SLOT(insertNewLine()));
+ }
+
+ menu->exec(event->globalPos());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/propertylineedit_p.h b/src/designer/src/lib/shared/propertylineedit_p.h
new file mode 100644
index 000000000..b968b18bf
--- /dev/null
+++ b/src/designer/src/lib/shared/propertylineedit_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PROPERTYLINEEDIT_H
+#define PROPERTYLINEEDIT_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QLineEdit>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+ // A line edit with a special context menu allowing for adding (escaped) new lines
+ class PropertyLineEdit : public QLineEdit {
+ Q_OBJECT
+ public:
+ explicit PropertyLineEdit(QWidget *parent);
+ void setWantNewLine(bool nl) { m_wantNewLine = nl; }
+ bool wantNewLine() const { return m_wantNewLine; }
+
+ bool event(QEvent *e);
+ protected:
+ void contextMenuEvent (QContextMenuEvent *event );
+ private slots:
+ void insertNewLine();
+ private:
+ void insertText(const QString &);
+ bool m_wantNewLine;
+ };
+}
+
+QT_END_NAMESPACE
+
+#endif // PROPERTYLINEEDIT_H
diff --git a/src/designer/src/lib/shared/qdesigner_command.cpp b/src/designer/src/lib/shared/qdesigner_command.cpp
new file mode 100644
index 000000000..f4e250d89
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_command.cpp
@@ -0,0 +1,2968 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_command_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "qdesigner_utils_p.h"
+#include "layout_p.h"
+#include "qlayout_widget_p.h"
+#include "qdesigner_widget_p.h"
+#include "qdesigner_menu_p.h"
+#include "shared_enums_p.h"
+#include "metadatabase_p.h"
+#include "formwindowbase_p.h"
+#include <abstractformbuilder.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerActionEditorInterface>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerLayoutDecorationExtension>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtDesigner/QDesignerIntegrationInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtCore/qdebug.h>
+#include <QtCore/QTextStream>
+#include <QtCore/QQueue>
+
+#include <QtGui/QMenuBar>
+#include <QtGui/QStatusBar>
+#include <QtGui/QToolBar>
+#include <QtGui/QToolBox>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QTabWidget>
+#include <QtGui/QTableWidget>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QListWidget>
+#include <QtGui/QComboBox>
+#include <QtGui/QSplitter>
+#include <QtGui/QDockWidget>
+#include <QtGui/QMainWindow>
+#include <QtGui/QWizardPage>
+#include <QtGui/QApplication>
+#include <QtGui/QFormLayout>
+
+Q_DECLARE_METATYPE(QWidgetList)
+
+QT_BEGIN_NAMESPACE
+
+static inline void setPropertySheetWindowTitle(const QDesignerFormEditorInterface *core, QObject *o, const QString &t)
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), o)) {
+ const int idx = sheet->indexOf(QLatin1String("windowTitle"));
+ if (idx != -1) {
+ sheet->setProperty(idx, t);
+ sheet->setChanged(idx, true);
+ }
+ }
+}
+
+namespace qdesigner_internal {
+
+// Helpers for the dynamic properties that store Z/Widget order
+static const char *widgetOrderPropertyC = "_q_widgetOrder";
+static const char *zOrderPropertyC = "_q_zOrder";
+
+static void addToWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name, int index = -1)
+{
+ QWidgetList list = qvariant_cast<QWidgetList>(parentWidget->property(name));
+ list.removeAll(widget);
+ if (index >= 0 && index < list.size()) {
+ list.insert(index, widget);
+ } else {
+ list.append(widget);
+ }
+ parentWidget->setProperty(name, QVariant::fromValue(list));
+}
+
+static int removeFromWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name)
+{
+ QWidgetList list = qvariant_cast<QWidgetList>(parentWidget->property(name));
+ const int firstIndex = list.indexOf(widget);
+ if (firstIndex != -1) {
+ list.removeAll(widget);
+ parentWidget->setProperty(name, QVariant::fromValue(list));
+ }
+ return firstIndex;
+}
+
+// ---- InsertWidgetCommand ----
+InsertWidgetCommand::InsertWidgetCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_insertMode(QDesignerLayoutDecorationExtension::InsertWidgetMode),
+ m_layoutHelper(0),
+ m_widgetWasManaged(false)
+{
+}
+
+InsertWidgetCommand::~InsertWidgetCommand()
+{
+ delete m_layoutHelper;
+}
+
+void InsertWidgetCommand::init(QWidget *widget, bool already_in_form, int layoutRow, int layoutColumn)
+{
+ m_widget = widget;
+
+ setText(QApplication::translate("Command", "Insert '%1'").arg(widget->objectName()));
+
+ QWidget *parentWidget = m_widget->parentWidget();
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), parentWidget);
+
+ m_insertMode = deco ? deco->currentInsertMode() : QDesignerLayoutDecorationExtension::InsertWidgetMode;
+ if (layoutRow >= 0 && layoutColumn >= 0) {
+ m_cell.first = layoutRow;
+ m_cell.second = layoutColumn;
+ } else {
+ m_cell = deco ? deco->currentCell() : qMakePair(0, 0);
+ }
+ m_widgetWasManaged = already_in_form;
+}
+
+static void recursiveUpdate(QWidget *w)
+{
+ w->update();
+
+ const QObjectList &l = w->children();
+ const QObjectList::const_iterator cend = l.end();
+ for ( QObjectList::const_iterator it = l.begin(); it != cend; ++it) {
+ if (QWidget *w = qobject_cast<QWidget*>(*it))
+ recursiveUpdate(w);
+ }
+}
+
+void InsertWidgetCommand::redo()
+{
+ QWidget *parentWidget = m_widget->parentWidget();
+ Q_ASSERT(parentWidget);
+
+ addToWidgetListDynamicProperty(parentWidget, m_widget, widgetOrderPropertyC);
+ addToWidgetListDynamicProperty(parentWidget, m_widget, zOrderPropertyC);
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), parentWidget);
+
+ if (deco != 0) {
+ const LayoutInfo::Type type = LayoutInfo::layoutType(core, LayoutInfo::managedLayout(core, parentWidget));
+ m_layoutHelper = LayoutHelper::createLayoutHelper(type);
+ m_layoutHelper->pushState(core, parentWidget);
+ if (type == LayoutInfo::Grid) {
+ switch (m_insertMode) {
+ case QDesignerLayoutDecorationExtension::InsertRowMode: {
+ deco->insertRow(m_cell.first);
+ } break;
+
+ case QDesignerLayoutDecorationExtension::InsertColumnMode: {
+ deco->insertColumn(m_cell.second);
+ } break;
+
+ default: break;
+ } // end switch
+ }
+ deco->insertWidget(m_widget, m_cell);
+ }
+
+ if (!m_widgetWasManaged)
+ formWindow()->manageWidget(m_widget);
+ m_widget->show();
+ formWindow()->emitSelectionChanged();
+
+ if (parentWidget && parentWidget->layout()) {
+ recursiveUpdate(parentWidget);
+ parentWidget->layout()->invalidate();
+ }
+
+ refreshBuddyLabels();
+}
+
+void InsertWidgetCommand::undo()
+{
+ QWidget *parentWidget = m_widget->parentWidget();
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), parentWidget);
+
+ if (deco) {
+ deco->removeWidget(m_widget);
+ m_layoutHelper->popState(core, parentWidget);
+ }
+
+ if (!m_widgetWasManaged) {
+ formWindow()->unmanageWidget(m_widget);
+ m_widget->hide();
+ }
+
+ removeFromWidgetListDynamicProperty(parentWidget, m_widget, widgetOrderPropertyC);
+ removeFromWidgetListDynamicProperty(parentWidget, m_widget, zOrderPropertyC);
+
+ formWindow()->emitSelectionChanged();
+
+ refreshBuddyLabels();
+}
+
+void InsertWidgetCommand::refreshBuddyLabels()
+{
+ typedef QList<QLabel*> LabelList;
+
+ const LabelList label_list = formWindow()->findChildren<QLabel*>();
+ if (label_list.empty())
+ return;
+
+ const QString buddyProperty = QLatin1String("buddy");
+ const QByteArray objectNameU8 = m_widget->objectName().toUtf8();
+ // Re-set the buddy (The sheet locates the object by name and sets it)
+ const LabelList::const_iterator cend = label_list.constEnd();
+ for (LabelList::const_iterator it = label_list.constBegin(); it != cend; ++it ) {
+ if (QDesignerPropertySheetExtension* sheet = propertySheet(*it)) {
+ const int idx = sheet->indexOf(buddyProperty);
+ if (idx != -1) {
+ const QVariant value = sheet->property(idx);
+ if (value.toByteArray() == objectNameU8)
+ sheet->setProperty(idx, value);
+ }
+ }
+ }
+}
+
+// ---- ChangeZOrderCommand ----
+ChangeZOrderCommand::ChangeZOrderCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QString(), formWindow)
+{
+}
+
+void ChangeZOrderCommand::init(QWidget *widget)
+{
+ Q_ASSERT(widget);
+
+ m_widget = widget;
+
+ setText(QApplication::translate("Command", "Change Z-order of '%1'").arg(widget->objectName()));
+
+ m_oldParentZOrder = qvariant_cast<QWidgetList>(widget->parentWidget()->property("_q_zOrder"));
+ const int index = m_oldParentZOrder.indexOf(m_widget);
+ if (index != -1 && index + 1 < m_oldParentZOrder.count())
+ m_oldPreceding = m_oldParentZOrder.at(index + 1);
+}
+
+void ChangeZOrderCommand::redo()
+{
+ m_widget->parentWidget()->setProperty("_q_zOrder", QVariant::fromValue(reorderWidget(m_oldParentZOrder, m_widget)));
+
+ reorder(m_widget);
+}
+
+void ChangeZOrderCommand::undo()
+{
+ m_widget->parentWidget()->setProperty("_q_zOrder", QVariant::fromValue(m_oldParentZOrder));
+
+ if (m_oldPreceding)
+ m_widget->stackUnder(m_oldPreceding);
+ else
+ m_widget->raise();
+}
+
+// ---- RaiseWidgetCommand ----
+RaiseWidgetCommand::RaiseWidgetCommand(QDesignerFormWindowInterface *formWindow)
+ : ChangeZOrderCommand(formWindow)
+{
+}
+
+void RaiseWidgetCommand::init(QWidget *widget)
+{
+ ChangeZOrderCommand::init(widget);
+ setText(QApplication::translate("Command", "Raise '%1'").arg(widget->objectName()));
+}
+
+QWidgetList RaiseWidgetCommand::reorderWidget(const QWidgetList &list, QWidget *widget) const
+{
+ QWidgetList l = list;
+ l.removeAll(widget);
+ l.append(widget);
+ return l;
+}
+
+void RaiseWidgetCommand::reorder(QWidget *widget) const
+{
+ widget->raise();
+}
+
+// ---- LowerWidgetCommand ----
+LowerWidgetCommand::LowerWidgetCommand(QDesignerFormWindowInterface *formWindow)
+ : ChangeZOrderCommand(formWindow)
+{
+}
+
+QWidgetList LowerWidgetCommand::reorderWidget(const QWidgetList &list, QWidget *widget) const
+{
+ QWidgetList l = list;
+ l.removeAll(widget);
+ l.prepend(widget);
+ return l;
+}
+
+void LowerWidgetCommand::init(QWidget *widget)
+{
+ ChangeZOrderCommand::init(widget);
+ setText(QApplication::translate("Command", "Lower '%1'").arg(widget->objectName()));
+}
+
+void LowerWidgetCommand::reorder(QWidget *widget) const
+{
+ widget->lower();
+}
+
+// ---- ManageWidgetCommandHelper
+ManageWidgetCommandHelper::ManageWidgetCommandHelper() :
+ m_widget(0)
+{
+}
+
+void ManageWidgetCommandHelper::init(const QDesignerFormWindowInterface *fw, QWidget *widget)
+{
+ m_widget = widget;
+ m_managedChildren.clear();
+
+ const QWidgetList children = m_widget->findChildren<QWidget *>();
+ if (children.empty())
+ return;
+
+ m_managedChildren.reserve(children.size());
+ const QWidgetList::const_iterator lcend = children.constEnd();
+ for (QWidgetList::const_iterator it = children.constBegin(); it != lcend; ++it)
+ if (fw->isManaged(*it))
+ m_managedChildren.push_back(*it);
+}
+
+void ManageWidgetCommandHelper::init(QWidget *widget, const WidgetVector &managedChildren)
+{
+ m_widget = widget;
+ m_managedChildren = managedChildren;
+}
+
+void ManageWidgetCommandHelper::manage(QDesignerFormWindowInterface *fw)
+{
+ // Manage the managed children after parent
+ fw->manageWidget(m_widget);
+ if (!m_managedChildren.empty()) {
+ const WidgetVector::const_iterator lcend = m_managedChildren.constEnd();
+ for (WidgetVector::const_iterator it = m_managedChildren.constBegin(); it != lcend; ++it)
+ fw->manageWidget(*it);
+ }
+}
+
+void ManageWidgetCommandHelper::unmanage(QDesignerFormWindowInterface *fw)
+{
+ // Unmanage the managed children first
+ if (!m_managedChildren.empty()) {
+ const WidgetVector::const_iterator lcend = m_managedChildren.constEnd();
+ for (WidgetVector::const_iterator it = m_managedChildren.constBegin(); it != lcend; ++it)
+ fw->unmanageWidget(*it);
+ }
+ fw->unmanageWidget(m_widget);
+}
+
+// ---- DeleteWidgetCommand ----
+DeleteWidgetCommand::DeleteWidgetCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_layoutType(LayoutInfo::NoLayout),
+ m_layoutHelper(0),
+ m_flags(0),
+ m_splitterIndex(-1),
+ m_layoutSimplified(false),
+ m_formItem(0),
+ m_tabOrderIndex(-1),
+ m_widgetOrderIndex(-1),
+ m_zOrderIndex(-1)
+{
+}
+
+DeleteWidgetCommand::~DeleteWidgetCommand()
+{
+ delete m_layoutHelper;
+}
+
+void DeleteWidgetCommand::init(QWidget *widget, unsigned flags)
+{
+ m_widget = widget;
+ m_parentWidget = widget->parentWidget();
+ m_geometry = widget->geometry();
+ m_flags = flags;
+ m_layoutType = LayoutInfo::NoLayout;
+ m_splitterIndex = -1;
+ bool isManaged; // Check for a managed layout
+ QLayout *layout;
+ m_layoutType = LayoutInfo::laidoutWidgetType(formWindow()->core(), m_widget, &isManaged, &layout);
+ if (!isManaged)
+ m_layoutType = LayoutInfo::NoLayout;
+ switch (m_layoutType) {
+ case LayoutInfo::HSplitter:
+ case LayoutInfo::VSplitter: {
+ QSplitter *splitter = qobject_cast<QSplitter *>(m_parentWidget);
+ Q_ASSERT(splitter);
+ m_splitterIndex = splitter->indexOf(widget);
+ }
+ break;
+ case LayoutInfo::NoLayout:
+ break;
+ default:
+ m_layoutHelper = LayoutHelper::createLayoutHelper(m_layoutType);
+ m_layoutPosition = m_layoutHelper->itemInfo(layout, m_widget);
+ break;
+ }
+
+ m_formItem = formWindow()->core()->metaDataBase()->item(formWindow());
+ m_tabOrderIndex = m_formItem->tabOrder().indexOf(widget);
+
+ // Build the list of managed children
+ m_manageHelper.init(formWindow(), m_widget);
+
+ setText(QApplication::translate("Command", "Delete '%1'").arg(widget->objectName()));
+}
+
+void DeleteWidgetCommand::redo()
+{
+ formWindow()->clearSelection();
+ QDesignerFormEditorInterface *core = formWindow()->core();
+
+ if (QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_parentWidget)) {
+ const int count = c->count();
+ for (int i=0; i<count; ++i) {
+ if (c->widget(i) == m_widget) {
+ c->remove(i);
+ return;
+ }
+ }
+ }
+
+ m_widgetOrderIndex = removeFromWidgetListDynamicProperty(m_parentWidget, m_widget, widgetOrderPropertyC);
+ m_zOrderIndex = removeFromWidgetListDynamicProperty(m_parentWidget, m_widget, zOrderPropertyC);
+
+ if (QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), m_parentWidget))
+ deco->removeWidget(m_widget);
+
+ if (m_layoutHelper)
+ switch (m_layoutType) {
+ case LayoutInfo::NoLayout:
+ case LayoutInfo::HSplitter:
+ case LayoutInfo::VSplitter:
+ break;
+ default:
+ // Attempt to simplify grids if a row/column becomes empty
+ m_layoutSimplified = (m_flags & DoNotSimplifyLayout) ? false : m_layoutHelper->canSimplify(core, m_parentWidget, m_layoutPosition);
+ if (m_layoutSimplified) {
+ m_layoutHelper->pushState(core, m_parentWidget);
+ m_layoutHelper->simplify(core, m_parentWidget, m_layoutPosition);
+ }
+ break;
+ }
+
+ if (!(m_flags & DoNotUnmanage))
+ m_manageHelper.unmanage(formWindow());
+
+ m_widget->setParent(formWindow());
+ m_widget->hide();
+
+ if (m_tabOrderIndex != -1) {
+ QList<QWidget*> tab_order = m_formItem->tabOrder();
+ tab_order.removeAt(m_tabOrderIndex);
+ m_formItem->setTabOrder(tab_order);
+ }
+}
+
+void DeleteWidgetCommand::undo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ formWindow()->clearSelection();
+
+ m_widget->setParent(m_parentWidget);
+
+ if (QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_parentWidget)) {
+ c->addWidget(m_widget);
+ return;
+ }
+
+ addToWidgetListDynamicProperty(m_parentWidget, m_widget, widgetOrderPropertyC, m_widgetOrderIndex);
+ addToWidgetListDynamicProperty(m_parentWidget, m_widget, zOrderPropertyC, m_zOrderIndex);
+
+ m_widget->setGeometry(m_geometry);
+
+ if (!(m_flags & DoNotUnmanage))
+ m_manageHelper.manage(formWindow());
+ // ### set up alignment
+ switch (m_layoutType) {
+ case LayoutInfo::NoLayout:
+ break;
+ case LayoutInfo::HSplitter:
+ case LayoutInfo::VSplitter: {
+ QSplitter *splitter = qobject_cast<QSplitter *>(m_widget->parent());
+ Q_ASSERT(splitter);
+ splitter->insertWidget(m_splitterIndex, m_widget);
+ } break;
+ default: {
+ Q_ASSERT(m_layoutHelper);
+ if (m_layoutSimplified)
+ m_layoutHelper->popState(core, m_parentWidget);
+ QLayout *layout = LayoutInfo::managedLayout(core, m_parentWidget);
+ Q_ASSERT(m_layoutType == LayoutInfo::layoutType(core, layout));
+ m_layoutHelper->insertWidget(layout, m_layoutPosition, m_widget);
+ }
+ break;
+ }
+
+ m_widget->show();
+
+ if (m_tabOrderIndex != -1) {
+ QList<QWidget*> tab_order = m_formItem->tabOrder();
+ tab_order.insert(m_tabOrderIndex, m_widget);
+ m_formItem->setTabOrder(tab_order);
+ }
+}
+
+// ---- ReparentWidgetCommand ----
+ReparentWidgetCommand::ReparentWidgetCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QString(), formWindow)
+{
+}
+
+void ReparentWidgetCommand::init(QWidget *widget, QWidget *parentWidget)
+{
+ Q_ASSERT(widget);
+
+ m_widget = widget;
+ m_oldParentWidget = widget->parentWidget();
+ m_newParentWidget = parentWidget;
+
+ m_oldPos = m_widget->pos();
+ m_newPos = m_newParentWidget->mapFromGlobal(m_oldParentWidget->mapToGlobal(m_oldPos));
+
+ setText(QApplication::translate("Command", "Reparent '%1'").arg(widget->objectName()));
+
+ m_oldParentList = qvariant_cast<QWidgetList>(m_oldParentWidget->property("_q_widgetOrder"));
+ m_oldParentZOrder = qvariant_cast<QWidgetList>(m_oldParentWidget->property("_q_zOrder"));
+}
+
+void ReparentWidgetCommand::redo()
+{
+ m_widget->setParent(m_newParentWidget);
+ m_widget->move(m_newPos);
+
+ QWidgetList oldList = m_oldParentList;
+ oldList.removeAll(m_widget);
+ m_oldParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(oldList));
+
+ QWidgetList newList = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_widgetOrder"));
+ newList.append(m_widget);
+ m_newParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(newList));
+
+ QWidgetList oldZOrder = m_oldParentZOrder;
+ oldZOrder.removeAll(m_widget);
+ m_oldParentWidget->setProperty("_q_zOrder", QVariant::fromValue(oldZOrder));
+
+ QWidgetList newZOrder = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_zOrder"));
+ newZOrder.append(m_widget);
+ m_newParentWidget->setProperty("_q_zOrder", QVariant::fromValue(newZOrder));
+
+ m_widget->show();
+ core()->objectInspector()->setFormWindow(formWindow());
+}
+
+void ReparentWidgetCommand::undo()
+{
+ m_widget->setParent(m_oldParentWidget);
+ m_widget->move(m_oldPos);
+
+ m_oldParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(m_oldParentList));
+
+ QWidgetList newList = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_widgetOrder"));
+ newList.removeAll(m_widget);
+ m_newParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(newList));
+
+ m_oldParentWidget->setProperty("_q_zOrder", QVariant::fromValue(m_oldParentZOrder));
+
+ QWidgetList newZOrder = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_zOrder"));
+ m_newParentWidget->setProperty("_q_zOrder", QVariant::fromValue(newZOrder));
+
+ m_widget->show();
+ core()->objectInspector()->setFormWindow(formWindow());
+}
+
+PromoteToCustomWidgetCommand::PromoteToCustomWidgetCommand
+ (QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Promote to custom widget"), formWindow)
+{
+}
+
+void PromoteToCustomWidgetCommand::init(const WidgetList &widgets,const QString &customClassName)
+{
+ m_widgets = widgets;
+ m_customClassName = customClassName;
+}
+
+void PromoteToCustomWidgetCommand::redo()
+{
+ foreach (QWidget *w, m_widgets) {
+ if (w)
+ promoteWidget(core(), w, m_customClassName);
+ }
+ updateSelection();
+}
+
+void PromoteToCustomWidgetCommand::updateSelection()
+{
+ // Update class names in ObjectInspector, PropertyEditor
+ QDesignerFormWindowInterface *fw = formWindow();
+ QDesignerFormEditorInterface *core = fw->core();
+ core->objectInspector()->setFormWindow(fw);
+ if (QObject *o = core->propertyEditor()->object())
+ core->propertyEditor()->setObject(o);
+}
+
+void PromoteToCustomWidgetCommand::undo()
+{
+ foreach (QWidget *w, m_widgets) {
+ if (w)
+ demoteWidget(core(), w);
+ }
+ updateSelection();
+}
+
+// ---- DemoteFromCustomWidgetCommand ----
+
+DemoteFromCustomWidgetCommand::DemoteFromCustomWidgetCommand
+ (QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Demote from custom widget"), formWindow),
+ m_promote_cmd(formWindow)
+{
+}
+
+void DemoteFromCustomWidgetCommand::init(const WidgetList &promoted)
+{
+ m_promote_cmd.init(promoted, promotedCustomClassName(core(), promoted.front()));
+}
+
+void DemoteFromCustomWidgetCommand::redo()
+{
+ m_promote_cmd.undo();
+}
+
+void DemoteFromCustomWidgetCommand::undo()
+{
+ m_promote_cmd.redo();
+}
+
+// ---------- CursorSelectionState
+CursorSelectionState::CursorSelectionState()
+{
+}
+
+void CursorSelectionState::save(const QDesignerFormWindowInterface *formWindow)
+{
+ const QDesignerFormWindowCursorInterface *cursor = formWindow->cursor();
+ m_selection.clear();
+ m_current = cursor->current();
+ if (cursor->hasSelection()) {
+ const int count = cursor->selectedWidgetCount();
+ for(int i = 0; i < count; i++)
+ m_selection.push_back(cursor->selectedWidget(i));
+ }
+}
+
+void CursorSelectionState::restore(QDesignerFormWindowInterface *formWindow) const
+{
+ if (m_selection.empty()) {
+ formWindow->clearSelection(true);
+ } else {
+ // Select current as last
+ formWindow->clearSelection(false);
+ const WidgetPointerList::const_iterator cend = m_selection.constEnd();
+ for (WidgetPointerList::const_iterator it = m_selection.constBegin(); it != cend; ++it)
+ if (QWidget *w = *it)
+ if (w != m_current)
+ formWindow->selectWidget(*it, true);
+ if (m_current)
+ formWindow->selectWidget(m_current, true);
+ }
+}
+
+// ---- LayoutCommand ----
+
+LayoutCommand::LayoutCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_setup(false)
+{
+}
+
+LayoutCommand::~LayoutCommand()
+{
+ delete m_layout;
+}
+
+void LayoutCommand::init(QWidget *parentWidget, const QWidgetList &widgets,
+ LayoutInfo::Type layoutType, QWidget *layoutBase,
+ bool reparentLayoutWidget)
+{
+ m_parentWidget = parentWidget;
+ m_widgets = widgets;
+ formWindow()->simplifySelection(&m_widgets);
+ m_layout = Layout::createLayout(widgets, parentWidget, formWindow(), layoutBase, layoutType);
+ m_layout->setReparentLayoutWidget(reparentLayoutWidget);
+
+ switch (layoutType) {
+ case LayoutInfo::Grid:
+ setText(QApplication::translate("Command", "Lay out using grid"));
+ break;
+ case LayoutInfo::VBox:
+ setText(QApplication::translate("Command", "Lay out vertically"));
+ break;
+ case LayoutInfo::HBox:
+ setText(QApplication::translate("Command", "Lay out horizontally"));
+ break;
+ default:
+ break;
+ }
+ // Delayed setup to avoid confusion in case we are chained
+ // with a BreakLayout in a morph layout macro
+ m_setup = false;
+}
+
+void LayoutCommand::redo()
+{
+ if (!m_setup) {
+ m_layout->setup();
+ m_cursorSelectionState.save(formWindow());
+ m_setup = true;
+ }
+ m_layout->doLayout();
+ core()->objectInspector()->setFormWindow(formWindow());
+}
+
+void LayoutCommand::undo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+
+ QWidget *lb = m_layout->layoutBaseWidget();
+ QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), lb);
+ m_layout->undoLayout();
+ delete deco; // release the extension
+
+ // ### generalize (put in function)
+ if (!m_layoutBase && lb != 0 && !(qobject_cast<QLayoutWidget*>(lb) || qobject_cast<QSplitter*>(lb))) {
+ core->metaDataBase()->add(lb);
+ lb->show();
+ }
+ m_cursorSelectionState.restore(formWindow());
+ core->objectInspector()->setFormWindow(formWindow());
+}
+
+// ---- BreakLayoutCommand ----
+BreakLayoutCommand::BreakLayoutCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Break layout"), formWindow),
+ m_layoutHelper(0),
+ m_properties(0),
+ m_propertyMask(0)
+{
+}
+
+BreakLayoutCommand::~BreakLayoutCommand()
+{
+ delete m_layoutHelper;
+ delete m_layout;
+ delete m_properties;
+}
+
+const LayoutProperties *BreakLayoutCommand::layoutProperties() const
+{
+ return m_properties;
+}
+
+int BreakLayoutCommand::propertyMask() const
+{
+ return m_propertyMask;
+}
+
+void BreakLayoutCommand::init(const QWidgetList &widgets, QWidget *layoutBase, bool reparentLayoutWidget)
+{
+ enum Type { SplitterLayout, LayoutHasMarginSpacing, LayoutHasState };
+
+ const QDesignerFormEditorInterface *core = formWindow()->core();
+ m_widgets = widgets;
+ m_layoutBase = core->widgetFactory()->containerOfWidget(layoutBase);
+ QLayout *layoutToBeBroken;
+ const LayoutInfo::Type layoutType = LayoutInfo::managedLayoutType(core, m_layoutBase, &layoutToBeBroken);
+ m_layout = Layout::createLayout(widgets, m_layoutBase, formWindow(), layoutBase, layoutType);
+ m_layout->setReparentLayoutWidget(reparentLayoutWidget);
+
+ Type type = LayoutHasState;
+ switch (layoutType) {
+ case LayoutInfo::NoLayout:
+ case LayoutInfo::HSplitter:
+ case LayoutInfo::VSplitter:
+ type = SplitterLayout;
+ break;
+ case LayoutInfo::HBox:
+ case LayoutInfo::VBox: // Margin/spacing need to be saved
+ type = LayoutHasMarginSpacing;
+ break;
+ default: // Margin/spacing need to be saved + has a state (empty rows/columns of a grid)
+ type = LayoutHasState;
+ break;
+ }
+ Q_ASSERT(m_layout != 0);
+ m_layout->sort();
+
+
+ if (type >= LayoutHasMarginSpacing) {
+ m_properties = new LayoutProperties;
+ m_propertyMask = m_properties->fromPropertySheet(core, layoutToBeBroken, LayoutProperties::AllProperties);
+ }
+ if (type >= LayoutHasState)
+ m_layoutHelper = LayoutHelper::createLayoutHelper(layoutType);
+ m_cursorSelectionState.save(formWindow());
+}
+
+void BreakLayoutCommand::redo()
+{
+ if (!m_layout)
+ return;
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QWidget *lb = m_layout->layoutBaseWidget();
+ QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), lb);
+ formWindow()->clearSelection(false);
+ if (m_layoutHelper)
+ m_layoutHelper->pushState(core, m_layoutBase);
+ m_layout->breakLayout();
+ delete deco; // release the extension
+
+ foreach (QWidget *widget, m_widgets) {
+ widget->resize(widget->size().expandedTo(QSize(16, 16)));
+ }
+ // Update unless we are in an intermediate state of morphing layout
+ // in which a QLayoutWidget will have no layout at all.
+ if (m_layout->reparentLayoutWidget())
+ core->objectInspector()->setFormWindow(formWindow());
+}
+
+void BreakLayoutCommand::undo()
+{
+ if (!m_layout)
+ return;
+
+ formWindow()->clearSelection(false);
+ m_layout->doLayout();
+ if (m_layoutHelper)
+ m_layoutHelper->popState(formWindow()->core(), m_layoutBase);
+
+ QLayout *layoutToRestored = LayoutInfo::managedLayout(formWindow()->core(), m_layoutBase);
+ if (m_properties && m_layoutBase && layoutToRestored)
+ m_properties->toPropertySheet(formWindow()->core(), layoutToRestored, m_propertyMask);
+ m_cursorSelectionState.restore(formWindow());
+ core()->objectInspector()->setFormWindow(formWindow());
+}
+// ---- SimplifyLayoutCommand
+SimplifyLayoutCommand::SimplifyLayoutCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Simplify Grid Layout"), formWindow),
+ m_area(0, 0, 32767, 32767),
+ m_layoutBase(0),
+ m_layoutHelper(0),
+ m_layoutSimplified(false)
+{
+}
+
+SimplifyLayoutCommand::~SimplifyLayoutCommand()
+{
+ delete m_layoutHelper;
+}
+
+bool SimplifyLayoutCommand::canSimplify(QDesignerFormEditorInterface *core, const QWidget *w, int *layoutType)
+{
+ if (!w)
+ return false;
+ QLayout *layout;
+ const LayoutInfo::Type type = LayoutInfo::managedLayoutType(core, w, &layout);
+ if (layoutType)
+ *layoutType = type;
+ if (!layout)
+ return false;
+ switch (type) { // Known negatives
+ case LayoutInfo::NoLayout:
+ case LayoutInfo::UnknownLayout:
+ case LayoutInfo::HSplitter:
+ case LayoutInfo::VSplitter:
+ case LayoutInfo::HBox:
+ case LayoutInfo::VBox:
+ return false;
+ default:
+ break;
+ }
+ switch (type) {
+ case LayoutInfo::Grid:
+ return QLayoutSupport::canSimplifyQuickCheck(qobject_cast<QGridLayout*>(layout));
+ case LayoutInfo::Form:
+ return QLayoutSupport::canSimplifyQuickCheck(qobject_cast<const QFormLayout*>(layout));
+ default:
+ break;
+ }
+ return false;
+}
+
+bool SimplifyLayoutCommand::init(QWidget *layoutBase)
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ m_layoutSimplified = false;
+ int type;
+ if (canSimplify(core, layoutBase, &type)) {
+ m_layoutBase = layoutBase;
+ m_layoutHelper = LayoutHelper::createLayoutHelper(type);
+ m_layoutSimplified = m_layoutHelper->canSimplify(core, layoutBase, m_area);
+ }
+ return m_layoutSimplified;
+}
+
+void SimplifyLayoutCommand::redo()
+{
+ const QDesignerFormEditorInterface *core = formWindow()->core();
+ if (m_layoutSimplified) {
+ m_layoutHelper->pushState(core, m_layoutBase);
+ m_layoutHelper->simplify(core, m_layoutBase, m_area);
+ }
+}
+void SimplifyLayoutCommand::undo()
+{
+ if (m_layoutSimplified)
+ m_layoutHelper->popState(formWindow()->core(), m_layoutBase);
+}
+
+// ---- ToolBoxCommand ----
+ToolBoxCommand::ToolBoxCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_index(-1)
+{
+}
+
+ToolBoxCommand::~ToolBoxCommand()
+{
+}
+
+void ToolBoxCommand::init(QToolBox *toolBox)
+{
+ m_toolBox = toolBox;
+ m_index = m_toolBox->currentIndex();
+ m_widget = m_toolBox->widget(m_index);
+ m_itemText = m_toolBox->itemText(m_index);
+ m_itemIcon = m_toolBox->itemIcon(m_index);
+}
+
+void ToolBoxCommand::removePage()
+{
+ m_toolBox->removeItem(m_index);
+
+ m_widget->hide();
+ m_widget->setParent(formWindow());
+ formWindow()->clearSelection();
+ formWindow()->selectWidget(m_toolBox, true);
+
+}
+
+void ToolBoxCommand::addPage()
+{
+ m_widget->setParent(m_toolBox);
+ m_toolBox->insertItem(m_index, m_widget, m_itemIcon, m_itemText);
+ m_toolBox->setCurrentIndex(m_index);
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), m_toolBox);
+ if (sheet) {
+ qdesigner_internal::PropertySheetStringValue itemText(m_itemText);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemText")), QVariant::fromValue(itemText));
+ }
+
+ m_widget->show();
+ formWindow()->clearSelection();
+ formWindow()->selectWidget(m_toolBox, true);
+}
+
+// ---- MoveToolBoxPageCommand ----
+MoveToolBoxPageCommand::MoveToolBoxPageCommand(QDesignerFormWindowInterface *formWindow) :
+ ToolBoxCommand(formWindow),
+ m_newIndex(-1),
+ m_oldIndex(-1)
+{
+}
+
+MoveToolBoxPageCommand::~MoveToolBoxPageCommand()
+{
+}
+
+void MoveToolBoxPageCommand::init(QToolBox *toolBox, QWidget *page, int newIndex)
+{
+ ToolBoxCommand::init(toolBox);
+ setText(QApplication::translate("Command", "Move Page"));
+
+ m_widget = page;
+ m_oldIndex = m_toolBox->indexOf(m_widget);
+ m_itemText = m_toolBox->itemText(m_oldIndex);
+ m_itemIcon = m_toolBox->itemIcon(m_oldIndex);
+ m_newIndex = newIndex;
+}
+
+void MoveToolBoxPageCommand::redo()
+{
+ m_toolBox->removeItem(m_oldIndex);
+ m_toolBox->insertItem(m_newIndex, m_widget, m_itemIcon, m_itemText);
+}
+
+void MoveToolBoxPageCommand::undo()
+{
+ m_toolBox->removeItem(m_newIndex);
+ m_toolBox->insertItem(m_oldIndex, m_widget, m_itemIcon, m_itemText);
+}
+
+// ---- DeleteToolBoxPageCommand ----
+DeleteToolBoxPageCommand::DeleteToolBoxPageCommand(QDesignerFormWindowInterface *formWindow)
+ : ToolBoxCommand(formWindow)
+{
+}
+
+DeleteToolBoxPageCommand::~DeleteToolBoxPageCommand()
+{
+}
+
+void DeleteToolBoxPageCommand::init(QToolBox *toolBox)
+{
+ ToolBoxCommand::init(toolBox);
+ setText(QApplication::translate("Command", "Delete Page"));
+}
+
+void DeleteToolBoxPageCommand::redo()
+{
+ removePage();
+ cheapUpdate();
+}
+
+void DeleteToolBoxPageCommand::undo()
+{
+ addPage();
+ cheapUpdate();
+}
+
+// ---- AddToolBoxPageCommand ----
+AddToolBoxPageCommand::AddToolBoxPageCommand(QDesignerFormWindowInterface *formWindow)
+ : ToolBoxCommand(formWindow)
+{
+}
+
+AddToolBoxPageCommand::~AddToolBoxPageCommand()
+{
+}
+
+void AddToolBoxPageCommand::init(QToolBox *toolBox)
+{
+ init(toolBox, InsertBefore);
+}
+
+void AddToolBoxPageCommand::init(QToolBox *toolBox, InsertionMode mode)
+{
+ m_toolBox = toolBox;
+
+ m_index = m_toolBox->currentIndex();
+ if (mode == InsertAfter)
+ m_index++;
+ m_widget = new QDesignerWidget(formWindow(), m_toolBox);
+ m_itemText = QApplication::translate("Command", "Page");
+ m_itemIcon = QIcon();
+ m_widget->setObjectName(QLatin1String("page"));
+ formWindow()->ensureUniqueObjectName(m_widget);
+
+ setText(QApplication::translate("Command", "Insert Page"));
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ core->metaDataBase()->add(m_widget);
+}
+
+void AddToolBoxPageCommand::redo()
+{
+ addPage();
+ cheapUpdate();
+}
+
+void AddToolBoxPageCommand::undo()
+{
+ removePage();
+ cheapUpdate();
+}
+
+// ---- TabWidgetCommand ----
+TabWidgetCommand::TabWidgetCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_index(-1)
+{
+}
+
+TabWidgetCommand::~TabWidgetCommand()
+{
+}
+
+void TabWidgetCommand::init(QTabWidget *tabWidget)
+{
+ m_tabWidget = tabWidget;
+ m_index = m_tabWidget->currentIndex();
+ m_widget = m_tabWidget->widget(m_index);
+ m_itemText = m_tabWidget->tabText(m_index);
+ m_itemIcon = m_tabWidget->tabIcon(m_index);
+}
+
+void TabWidgetCommand::removePage()
+{
+ m_tabWidget->removeTab(m_index);
+
+ m_widget->hide();
+ m_widget->setParent(formWindow());
+ m_tabWidget->setCurrentIndex(qMin(m_index, m_tabWidget->count()));
+
+ formWindow()->clearSelection();
+ formWindow()->selectWidget(m_tabWidget, true);
+}
+
+void TabWidgetCommand::addPage()
+{
+ m_widget->setParent(0);
+ m_tabWidget->insertTab(m_index, m_widget, m_itemIcon, m_itemText);
+ m_widget->show();
+ m_tabWidget->setCurrentIndex(m_index);
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), m_tabWidget);
+ if (sheet) {
+ qdesigner_internal::PropertySheetStringValue itemText(m_itemText);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabText")), QVariant::fromValue(itemText));
+ }
+
+ formWindow()->clearSelection();
+ formWindow()->selectWidget(m_tabWidget, true);
+}
+
+// ---- DeleteTabPageCommand ----
+DeleteTabPageCommand::DeleteTabPageCommand(QDesignerFormWindowInterface *formWindow)
+ : TabWidgetCommand(formWindow)
+{
+}
+
+DeleteTabPageCommand::~DeleteTabPageCommand()
+{
+}
+
+void DeleteTabPageCommand::init(QTabWidget *tabWidget)
+{
+ TabWidgetCommand::init(tabWidget);
+ setText(QApplication::translate("Command", "Delete Page"));
+}
+
+void DeleteTabPageCommand::redo()
+{
+ removePage();
+ cheapUpdate();
+}
+
+void DeleteTabPageCommand::undo()
+{
+ addPage();
+ cheapUpdate();
+}
+
+// ---- AddTabPageCommand ----
+AddTabPageCommand::AddTabPageCommand(QDesignerFormWindowInterface *formWindow)
+ : TabWidgetCommand(formWindow)
+{
+}
+
+AddTabPageCommand::~AddTabPageCommand()
+{
+}
+
+void AddTabPageCommand::init(QTabWidget *tabWidget)
+{
+ init(tabWidget, InsertBefore);
+}
+
+void AddTabPageCommand::init(QTabWidget *tabWidget, InsertionMode mode)
+{
+ m_tabWidget = tabWidget;
+
+ m_index = m_tabWidget->currentIndex();
+ if (mode == InsertAfter)
+ m_index++;
+ m_widget = new QDesignerWidget(formWindow(), m_tabWidget);
+ m_itemText = QApplication::translate("Command", "Page");
+ m_itemIcon = QIcon();
+ m_widget->setObjectName(QLatin1String("tab"));
+ formWindow()->ensureUniqueObjectName(m_widget);
+
+ setText(QApplication::translate("Command", "Insert Page"));
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ core->metaDataBase()->add(m_widget);
+}
+
+void AddTabPageCommand::redo()
+{
+ addPage();
+ cheapUpdate();
+}
+
+void AddTabPageCommand::undo()
+{
+ removePage();
+ cheapUpdate();
+}
+
+// ---- MoveTabPageCommand ----
+MoveTabPageCommand::MoveTabPageCommand(QDesignerFormWindowInterface *formWindow) :
+ TabWidgetCommand(formWindow),
+ m_newIndex(-1),
+ m_oldIndex(-1)
+{
+}
+
+MoveTabPageCommand::~MoveTabPageCommand()
+{
+}
+
+void MoveTabPageCommand::init(QTabWidget *tabWidget, QWidget *page,
+ const QIcon &icon, const QString &label,
+ int index, int newIndex)
+{
+ TabWidgetCommand::init(tabWidget);
+ setText(QApplication::translate("Command", "Move Page"));
+
+ m_page = page;
+ m_newIndex = newIndex;
+ m_oldIndex = index;
+ m_label = label;
+ m_icon = icon;
+}
+
+void MoveTabPageCommand::redo()
+{
+ m_tabWidget->removeTab(m_oldIndex);
+ m_tabWidget->insertTab(m_newIndex, m_page, m_icon, m_label);
+ m_tabWidget->setCurrentIndex(m_newIndex);
+}
+
+void MoveTabPageCommand::undo()
+{
+ m_tabWidget->removeTab(m_newIndex);
+ m_tabWidget->insertTab(m_oldIndex, m_page, m_icon, m_label);
+ m_tabWidget->setCurrentIndex(m_oldIndex);
+}
+
+// ---- StackedWidgetCommand ----
+StackedWidgetCommand::StackedWidgetCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_index(-1)
+{
+}
+
+StackedWidgetCommand::~StackedWidgetCommand()
+{
+}
+
+void StackedWidgetCommand::init(QStackedWidget *stackedWidget)
+{
+ m_stackedWidget = stackedWidget;
+ m_index = m_stackedWidget->currentIndex();
+ m_widget = m_stackedWidget->widget(m_index);
+}
+
+void StackedWidgetCommand::removePage()
+{
+ m_stackedWidget->removeWidget(m_stackedWidget->widget(m_index));
+
+ m_widget->hide();
+ m_widget->setParent(formWindow());
+
+ formWindow()->clearSelection();
+ formWindow()->selectWidget(m_stackedWidget, true);
+}
+
+void StackedWidgetCommand::addPage()
+{
+ m_stackedWidget->insertWidget(m_index, m_widget);
+
+ m_widget->show();
+ m_stackedWidget->setCurrentIndex(m_index);
+
+ formWindow()->clearSelection();
+ formWindow()->selectWidget(m_stackedWidget, true);
+}
+
+// ---- MoveStackedWidgetCommand ----
+MoveStackedWidgetCommand::MoveStackedWidgetCommand(QDesignerFormWindowInterface *formWindow) :
+ StackedWidgetCommand(formWindow),
+ m_newIndex(-1),
+ m_oldIndex(-1)
+{
+}
+
+MoveStackedWidgetCommand::~MoveStackedWidgetCommand()
+{
+}
+
+void MoveStackedWidgetCommand::init(QStackedWidget *stackedWidget, QWidget *page, int newIndex)
+{
+ StackedWidgetCommand::init(stackedWidget);
+ setText(QApplication::translate("Command", "Move Page"));
+
+ m_widget = page;
+ m_newIndex = newIndex;
+ m_oldIndex = m_stackedWidget->indexOf(m_widget);
+}
+
+void MoveStackedWidgetCommand::redo()
+{
+ m_stackedWidget->removeWidget(m_widget);
+ m_stackedWidget->insertWidget(m_newIndex, m_widget);
+}
+
+void MoveStackedWidgetCommand::undo()
+{
+ m_stackedWidget->removeWidget(m_widget);
+ m_stackedWidget->insertWidget(m_oldIndex, m_widget);
+}
+
+// ---- DeleteStackedWidgetPageCommand ----
+DeleteStackedWidgetPageCommand::DeleteStackedWidgetPageCommand(QDesignerFormWindowInterface *formWindow)
+ : StackedWidgetCommand(formWindow)
+{
+}
+
+DeleteStackedWidgetPageCommand::~DeleteStackedWidgetPageCommand()
+{
+}
+
+void DeleteStackedWidgetPageCommand::init(QStackedWidget *stackedWidget)
+{
+ StackedWidgetCommand::init(stackedWidget);
+ setText(QApplication::translate("Command", "Delete Page"));
+}
+
+void DeleteStackedWidgetPageCommand::redo()
+{
+ removePage();
+ cheapUpdate();
+}
+
+void DeleteStackedWidgetPageCommand::undo()
+{
+ addPage();
+ cheapUpdate();
+}
+
+// ---- AddStackedWidgetPageCommand ----
+AddStackedWidgetPageCommand::AddStackedWidgetPageCommand(QDesignerFormWindowInterface *formWindow)
+ : StackedWidgetCommand(formWindow)
+{
+}
+
+AddStackedWidgetPageCommand::~AddStackedWidgetPageCommand()
+{
+}
+
+void AddStackedWidgetPageCommand::init(QStackedWidget *stackedWidget)
+{
+ init(stackedWidget, InsertBefore);
+}
+
+void AddStackedWidgetPageCommand::init(QStackedWidget *stackedWidget, InsertionMode mode)
+{
+ m_stackedWidget = stackedWidget;
+
+ m_index = m_stackedWidget->currentIndex();
+ if (mode == InsertAfter)
+ m_index++;
+ m_widget = new QDesignerWidget(formWindow(), m_stackedWidget);
+ m_widget->setObjectName(QLatin1String("page"));
+ formWindow()->ensureUniqueObjectName(m_widget);
+
+ setText(QApplication::translate("Command", "Insert Page"));
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ core->metaDataBase()->add(m_widget);
+}
+
+void AddStackedWidgetPageCommand::redo()
+{
+ addPage();
+ cheapUpdate();
+}
+
+void AddStackedWidgetPageCommand::undo()
+{
+ removePage();
+ cheapUpdate();
+}
+
+// ---- TabOrderCommand ----
+TabOrderCommand::TabOrderCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Change Tab order"), formWindow),
+ m_widgetItem(0)
+{
+}
+
+void TabOrderCommand::init(const QList<QWidget*> &newTabOrder)
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ Q_ASSERT(core);
+
+ m_widgetItem = core->metaDataBase()->item(formWindow());
+ Q_ASSERT(m_widgetItem);
+ m_oldTabOrder = m_widgetItem->tabOrder();
+ m_newTabOrder = newTabOrder;
+}
+
+void TabOrderCommand::redo()
+{
+ m_widgetItem->setTabOrder(m_newTabOrder);
+}
+
+void TabOrderCommand::undo()
+{
+ m_widgetItem->setTabOrder(m_oldTabOrder);
+}
+
+// ---- CreateMenuBarCommand ----
+CreateMenuBarCommand::CreateMenuBarCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Create Menu Bar"), formWindow)
+{
+}
+
+void CreateMenuBarCommand::init(QMainWindow *mainWindow)
+{
+ m_mainWindow = mainWindow;
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ m_menuBar = qobject_cast<QMenuBar*>(core->widgetFactory()->createWidget(QLatin1String("QMenuBar"), m_mainWindow));
+ core->widgetFactory()->initialize(m_menuBar);
+}
+
+void CreateMenuBarCommand::redo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerContainerExtension *c;
+ c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
+ c->addWidget(m_menuBar);
+
+ m_menuBar->setObjectName(QLatin1String("menuBar"));
+ formWindow()->ensureUniqueObjectName(m_menuBar);
+ core->metaDataBase()->add(m_menuBar);
+ formWindow()->emitSelectionChanged();
+ m_menuBar->setFocus();
+}
+
+void CreateMenuBarCommand::undo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerContainerExtension *c;
+ c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
+ for (int i = 0; i < c->count(); ++i) {
+ if (c->widget(i) == m_menuBar) {
+ c->remove(i);
+ break;
+ }
+ }
+
+ core->metaDataBase()->remove(m_menuBar);
+ formWindow()->emitSelectionChanged();
+}
+
+// ---- DeleteMenuBarCommand ----
+DeleteMenuBarCommand::DeleteMenuBarCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Delete Menu Bar"), formWindow)
+{
+}
+
+void DeleteMenuBarCommand::init(QMenuBar *menuBar)
+{
+ m_menuBar = menuBar;
+ m_mainWindow = qobject_cast<QMainWindow*>(menuBar->parentWidget());
+}
+
+void DeleteMenuBarCommand::redo()
+{
+ if (m_mainWindow) {
+ QDesignerContainerExtension *c;
+ c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
+ Q_ASSERT(c != 0);
+ for (int i=0; i<c->count(); ++i) {
+ if (c->widget(i) == m_menuBar) {
+ c->remove(i);
+ break;
+ }
+ }
+ }
+
+ core()->metaDataBase()->remove(m_menuBar);
+ m_menuBar->hide();
+ m_menuBar->setParent(formWindow());
+ formWindow()->emitSelectionChanged();
+}
+
+void DeleteMenuBarCommand::undo()
+{
+ if (m_mainWindow) {
+ m_menuBar->setParent(m_mainWindow);
+ QDesignerContainerExtension *c;
+ c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
+
+ c->addWidget(m_menuBar);
+
+ core()->metaDataBase()->add(m_menuBar);
+ m_menuBar->show();
+ formWindow()->emitSelectionChanged();
+ }
+}
+
+// ---- CreateStatusBarCommand ----
+CreateStatusBarCommand::CreateStatusBarCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Create Status Bar"), formWindow)
+{
+}
+
+void CreateStatusBarCommand::init(QMainWindow *mainWindow)
+{
+ m_mainWindow = mainWindow;
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ m_statusBar = qobject_cast<QStatusBar*>(core->widgetFactory()->createWidget(QLatin1String("QStatusBar"), m_mainWindow));
+ core->widgetFactory()->initialize(m_statusBar);
+}
+
+void CreateStatusBarCommand::redo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerContainerExtension *c;
+ c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
+ c->addWidget(m_statusBar);
+
+ m_statusBar->setObjectName(QLatin1String("statusBar"));
+ formWindow()->ensureUniqueObjectName(m_statusBar);
+ core->metaDataBase()->add(m_statusBar);
+ formWindow()->emitSelectionChanged();
+}
+
+void CreateStatusBarCommand::undo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
+ for (int i = 0; i < c->count(); ++i) {
+ if (c->widget(i) == m_statusBar) {
+ c->remove(i);
+ break;
+ }
+ }
+
+ core->metaDataBase()->remove(m_statusBar);
+ formWindow()->emitSelectionChanged();
+}
+
+// ---- DeleteStatusBarCommand ----
+DeleteStatusBarCommand::DeleteStatusBarCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Delete Status Bar"), formWindow)
+{
+}
+
+void DeleteStatusBarCommand::init(QStatusBar *statusBar)
+{
+ m_statusBar = statusBar;
+ m_mainWindow = qobject_cast<QMainWindow*>(statusBar->parentWidget());
+}
+
+void DeleteStatusBarCommand::redo()
+{
+ if (m_mainWindow) {
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
+ Q_ASSERT(c != 0);
+ for (int i=0; i<c->count(); ++i) {
+ if (c->widget(i) == m_statusBar) {
+ c->remove(i);
+ break;
+ }
+ }
+ }
+
+ core()->metaDataBase()->remove(m_statusBar);
+ m_statusBar->hide();
+ m_statusBar->setParent(formWindow());
+ formWindow()->emitSelectionChanged();
+}
+
+void DeleteStatusBarCommand::undo()
+{
+ if (m_mainWindow) {
+ m_statusBar->setParent(m_mainWindow);
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
+
+ c->addWidget(m_statusBar);
+
+ core()->metaDataBase()->add(m_statusBar);
+ m_statusBar->show();
+ formWindow()->emitSelectionChanged();
+ }
+}
+
+// ---- AddToolBarCommand ----
+AddToolBarCommand::AddToolBarCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Add Tool Bar"), formWindow)
+{
+}
+
+void AddToolBarCommand::init(QMainWindow *mainWindow)
+{
+ m_mainWindow = mainWindow;
+ QDesignerWidgetFactoryInterface * wf = formWindow()->core()->widgetFactory();
+ // Pass on 0 parent first to avoid reparenting flicker.
+ m_toolBar = qobject_cast<QToolBar*>(wf->createWidget(QLatin1String("QToolBar"), 0));
+ wf->initialize(m_toolBar);
+ m_toolBar->hide();
+}
+
+void AddToolBarCommand::redo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ core->metaDataBase()->add(m_toolBar);
+
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
+ c->addWidget(m_toolBar);
+
+ m_toolBar->setObjectName(QLatin1String("toolBar"));
+ formWindow()->ensureUniqueObjectName(m_toolBar);
+ setPropertySheetWindowTitle(core, m_toolBar, m_toolBar->objectName());
+ formWindow()->emitSelectionChanged();
+}
+
+void AddToolBarCommand::undo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ core->metaDataBase()->remove(m_toolBar);
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
+ for (int i = 0; i < c->count(); ++i) {
+ if (c->widget(i) == m_toolBar) {
+ c->remove(i);
+ break;
+ }
+ }
+ formWindow()->emitSelectionChanged();
+}
+
+// ---- DockWidgetCommand:: ----
+DockWidgetCommand::DockWidgetCommand(const QString &description, QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(description, formWindow)
+{
+}
+
+DockWidgetCommand::~DockWidgetCommand()
+{
+}
+
+void DockWidgetCommand::init(QDockWidget *dockWidget)
+{
+ m_dockWidget = dockWidget;
+}
+
+// ---- AddDockWidgetCommand ----
+AddDockWidgetCommand::AddDockWidgetCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Add Dock Window"), formWindow)
+{
+}
+
+void AddDockWidgetCommand::init(QMainWindow *mainWindow, QDockWidget *dockWidget)
+{
+ m_mainWindow = mainWindow;
+ m_dockWidget = dockWidget;
+}
+
+void AddDockWidgetCommand::init(QMainWindow *mainWindow)
+{
+ m_mainWindow = mainWindow;
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ m_dockWidget = qobject_cast<QDockWidget*>(core->widgetFactory()->createWidget(QLatin1String("QDockWidget"), m_mainWindow));
+}
+
+void AddDockWidgetCommand::redo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
+ c->addWidget(m_dockWidget);
+
+ m_dockWidget->setObjectName(QLatin1String("dockWidget"));
+ formWindow()->ensureUniqueObjectName(m_dockWidget);
+ formWindow()->manageWidget(m_dockWidget);
+ formWindow()->emitSelectionChanged();
+}
+
+void AddDockWidgetCommand::undo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
+ for (int i = 0; i < c->count(); ++i) {
+ if (c->widget(i) == m_dockWidget) {
+ c->remove(i);
+ break;
+ }
+ }
+
+ formWindow()->unmanageWidget(m_dockWidget);
+ formWindow()->emitSelectionChanged();
+}
+
+// ---- AdjustWidgetSizeCommand ----
+AdjustWidgetSizeCommand::AdjustWidgetSizeCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QString(), formWindow)
+{
+}
+
+void AdjustWidgetSizeCommand::init(QWidget *widget)
+{
+ m_widget = widget;
+ setText(QApplication::translate("Command", "Adjust Size of '%1'").arg(widget->objectName()));
+}
+
+QWidget *AdjustWidgetSizeCommand::widgetForAdjust() const
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ // Return the outer, embedding widget if it is the main container
+ if (Utils::isCentralWidget(fw, m_widget))
+ return fw->core()->integration()->containerWindow(m_widget);
+ return m_widget;
+}
+
+void AdjustWidgetSizeCommand::redo()
+{
+ QWidget *aw = widgetForAdjust();
+ m_geometry = aw->geometry();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ aw->adjustSize();
+ const bool isMainContainer = aw != m_widget;
+ if (!isMainContainer) {
+ /* When doing adjustsize on a selected non-laid out child that has been enlarged
+ * and pushed partially over the top/left edge[s], it is possible that it "disappears"
+ * when shrinking. In that case, move it back so that it remains visible. */
+ if (aw->parentWidget()->layout() == 0) {
+ const QRect contentsRect = aw->parentWidget()->contentsRect();
+ const QRect newGeometry = aw->geometry();
+ QPoint newPos = m_geometry.topLeft();
+ if (newGeometry.bottom() <= contentsRect.y())
+ newPos.setY(contentsRect.y());
+ if (newGeometry.right() <= contentsRect.x())
+ newPos.setX(contentsRect.x());
+ if (newPos != m_geometry.topLeft())
+ aw->move(newPos);
+ }
+ }
+ updatePropertyEditor();
+}
+
+void AdjustWidgetSizeCommand::undo()
+{
+ QWidget *aw = widgetForAdjust();
+ aw->resize(m_geometry.size());
+ if (m_geometry.topLeft() != aw->geometry().topLeft())
+ aw->move(m_geometry.topLeft());
+ updatePropertyEditor();
+}
+
+void AdjustWidgetSizeCommand::updatePropertyEditor() const
+{
+ if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
+ if (propertyEditor->object() == m_widget)
+ propertyEditor->setPropertyValue(QLatin1String("geometry"), m_widget->geometry(), true);
+ }
+}
+// ------------ ChangeFormLayoutItemRoleCommand
+
+ChangeFormLayoutItemRoleCommand::ChangeFormLayoutItemRoleCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Change Form Layout Item Geometry"), formWindow),
+ m_operation(SpanningToLabel)
+{
+}
+
+void ChangeFormLayoutItemRoleCommand::init(QWidget *widget, Operation op)
+{
+ m_widget = widget;
+ m_operation = op;
+}
+
+void ChangeFormLayoutItemRoleCommand::redo()
+{
+ doOperation(m_operation);
+}
+
+void ChangeFormLayoutItemRoleCommand::undo()
+{
+ doOperation(reverseOperation(m_operation));
+}
+
+ChangeFormLayoutItemRoleCommand::Operation ChangeFormLayoutItemRoleCommand::reverseOperation(Operation op)
+{
+ switch (op) {
+ case SpanningToLabel:
+ return LabelToSpanning;
+ case SpanningToField:
+ return FieldToSpanning;
+ case LabelToSpanning:
+ return SpanningToLabel;
+ case FieldToSpanning:
+ return SpanningToField;
+ }
+ return SpanningToField;
+}
+
+void ChangeFormLayoutItemRoleCommand::doOperation(Operation op)
+{
+ QFormLayout *fl = ChangeFormLayoutItemRoleCommand::managedFormLayoutOf(formWindow()->core(), m_widget);
+ const int index = fl->indexOf(m_widget);
+ Q_ASSERT(index != -1);
+ int row;
+ QFormLayout::ItemRole role;
+ fl->getItemPosition (index, &row, &role);
+ Q_ASSERT(index != -1);
+ QLayoutItem *item = fl->takeAt(index);
+ const QRect area = QRect(0, row, 2, 1);
+ switch (op) {
+ case SpanningToLabel:
+ fl->setItem(row, QFormLayout::LabelRole, item);
+ QLayoutSupport::createEmptyCells(fl);
+ break;
+ case SpanningToField:
+ fl->setItem(row, QFormLayout::FieldRole, item);
+ QLayoutSupport::createEmptyCells(fl);
+ break;
+ case LabelToSpanning:
+ case FieldToSpanning:
+ QLayoutSupport::removeEmptyCells(fl, area);
+ fl->setItem(row, QFormLayout::SpanningRole, item);
+ break;
+ }
+}
+
+unsigned ChangeFormLayoutItemRoleCommand::possibleOperations(QDesignerFormEditorInterface *core, QWidget *w)
+{
+ QFormLayout *fl = managedFormLayoutOf(core, w);
+ if (!fl)
+ return 0;
+ const int index = fl->indexOf(w);
+ if (index == -1)
+ return 0;
+ int row, col, colspan;
+ getFormLayoutItemPosition(fl, index, &row, &col, 0, &colspan);
+ // Spanning item?
+ if (colspan > 1)
+ return SpanningToLabel|SpanningToField;
+ // Is the neighbouring column free, that is, can the current item be expanded?
+ const QFormLayout::ItemRole neighbouringRole = col == 0 ? QFormLayout::FieldRole : QFormLayout::LabelRole;
+ const bool empty = LayoutInfo::isEmptyItem(fl->itemAt(row, neighbouringRole));
+ if (empty)
+ return col == 0 ? LabelToSpanning : FieldToSpanning;
+ return 0;
+}
+
+QFormLayout *ChangeFormLayoutItemRoleCommand::managedFormLayoutOf(QDesignerFormEditorInterface *core, QWidget *w)
+{
+ if (QLayout *layout = LayoutInfo::managedLayout(core, w->parentWidget()))
+ if (QFormLayout *fl = qobject_cast<QFormLayout *>(layout))
+ return fl;
+ return 0;
+}
+
+// ---- ChangeLayoutItemGeometry ----
+ChangeLayoutItemGeometry::ChangeLayoutItemGeometry(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Change Layout Item Geometry"), formWindow)
+{
+}
+
+void ChangeLayoutItemGeometry::init(QWidget *widget, int row, int column, int rowspan, int colspan)
+{
+ m_widget = widget;
+ Q_ASSERT(m_widget->parentWidget() != 0);
+
+ QLayout *layout = LayoutInfo::managedLayout(formWindow()->core(), m_widget->parentWidget());
+ Q_ASSERT(layout != 0);
+
+ QGridLayout *grid = qobject_cast<QGridLayout*>(layout);
+ Q_ASSERT(grid != 0);
+
+ const int itemIndex = grid->indexOf(m_widget);
+ Q_ASSERT(itemIndex != -1);
+
+ int current_row, current_column, current_rowspan, current_colspan;
+ grid->getItemPosition(itemIndex, &current_row, &current_column, &current_rowspan, &current_colspan);
+
+ m_oldInfo.setRect(current_column, current_row, current_colspan, current_rowspan);
+ m_newInfo.setRect(column, row, colspan, rowspan);
+}
+
+void ChangeLayoutItemGeometry::changeItemPosition(const QRect &g)
+{
+ QLayout *layout = LayoutInfo::managedLayout(formWindow()->core(), m_widget->parentWidget());
+ Q_ASSERT(layout != 0);
+
+ QGridLayout *grid = qobject_cast<QGridLayout*>(layout);
+ Q_ASSERT(grid != 0);
+
+ const int itemIndex = grid->indexOf(m_widget);
+ Q_ASSERT(itemIndex != -1);
+
+ QLayoutItem *item = grid->takeAt(itemIndex);
+ delete item;
+
+ if (!QLayoutSupport::removeEmptyCells(grid, g))
+ qWarning() << "ChangeLayoutItemGeometry::changeItemPosition: Nonempty cell at " << g << '.';
+
+ grid->addWidget(m_widget, g.top(), g.left(), g.height(), g.width());
+
+ grid->invalidate();
+ grid->activate();
+
+ QLayoutSupport::createEmptyCells(grid);
+
+ formWindow()->clearSelection(false);
+ formWindow()->selectWidget(m_widget, true);
+}
+
+void ChangeLayoutItemGeometry::redo()
+{
+ changeItemPosition(m_newInfo);
+}
+
+void ChangeLayoutItemGeometry::undo()
+{
+ changeItemPosition(m_oldInfo);
+}
+
+// ---- ContainerWidgetCommand ----
+ContainerWidgetCommand::ContainerWidgetCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_index(-1)
+{
+}
+
+ContainerWidgetCommand::~ContainerWidgetCommand()
+{
+}
+
+QDesignerContainerExtension *ContainerWidgetCommand::containerExtension() const
+{
+ QExtensionManager *mgr = core()->extensionManager();
+ return qt_extension<QDesignerContainerExtension*>(mgr, m_containerWidget);
+}
+
+void ContainerWidgetCommand::init(QWidget *containerWidget)
+{
+ m_containerWidget = containerWidget;
+
+ if (QDesignerContainerExtension *c = containerExtension()) {
+ m_index = c->currentIndex();
+ m_widget = c->widget(m_index);
+ }
+}
+
+void ContainerWidgetCommand::removePage()
+{
+ if (QDesignerContainerExtension *c = containerExtension()) {
+ if (const int count = c->count()) {
+ // Undo add after last?
+ const int deleteIndex = m_index >= 0 ? m_index : count - 1;
+ c->remove(deleteIndex);
+ m_widget->hide();
+ m_widget->setParent(formWindow());
+ }
+ }
+}
+
+void ContainerWidgetCommand::addPage()
+{
+ if (QDesignerContainerExtension *c = containerExtension()) {
+ int newCurrentIndex;
+ if (m_index >= 0) {
+ c->insertWidget(m_index, m_widget);
+ newCurrentIndex = m_index;
+ } else {
+ c->addWidget(m_widget);
+ newCurrentIndex = c->count() -1 ;
+ }
+ m_widget->show();
+ c->setCurrentIndex(newCurrentIndex);
+ }
+}
+
+// ---- DeleteContainerWidgetPageCommand ----
+DeleteContainerWidgetPageCommand::DeleteContainerWidgetPageCommand(QDesignerFormWindowInterface *formWindow)
+ : ContainerWidgetCommand(formWindow)
+{
+}
+
+DeleteContainerWidgetPageCommand::~DeleteContainerWidgetPageCommand()
+{
+}
+
+void DeleteContainerWidgetPageCommand::init(QWidget *containerWidget, ContainerType ct)
+{
+ ContainerWidgetCommand::init(containerWidget);
+ switch (ct) {
+ case WizardContainer:
+ case PageContainer:
+ setText(QApplication::translate("Command", "Delete Page"));
+ break;
+ case MdiContainer:
+ setText(QApplication::translate("Command", "Delete Subwindow"));
+ break;
+ }
+}
+
+void DeleteContainerWidgetPageCommand::redo()
+{
+ removePage();
+ cheapUpdate();
+}
+
+void DeleteContainerWidgetPageCommand::undo()
+{
+ addPage();
+ cheapUpdate();
+}
+
+// ---- AddContainerWidgetPageCommand ----
+AddContainerWidgetPageCommand::AddContainerWidgetPageCommand(QDesignerFormWindowInterface *formWindow)
+ : ContainerWidgetCommand(formWindow)
+{
+}
+
+AddContainerWidgetPageCommand::~AddContainerWidgetPageCommand()
+{
+}
+
+void AddContainerWidgetPageCommand::init(QWidget *containerWidget, ContainerType ct, InsertionMode mode)
+{
+ m_containerWidget = containerWidget;
+
+ if (QDesignerContainerExtension *c = containerExtension()) {
+ m_index = c->currentIndex();
+ if (m_index >= 0 && mode == InsertAfter)
+ m_index++;
+ m_widget = 0;
+ const QDesignerFormEditorInterface *core = formWindow()->core();
+ switch (ct) {
+ case PageContainer:
+ setText(QApplication::translate("Command", "Insert Page"));
+ m_widget = new QDesignerWidget(formWindow(), m_containerWidget);
+ m_widget->setObjectName(QLatin1String("page"));
+ break;
+ case MdiContainer:
+ setText(QApplication::translate("Command", "Insert Subwindow"));
+ m_widget = new QDesignerWidget(formWindow(), m_containerWidget);
+ m_widget->setObjectName(QLatin1String("subwindow"));
+ setPropertySheetWindowTitle(core, m_widget, QApplication::translate("Command", "Subwindow"));
+ break;
+ case WizardContainer: // Apply style, don't manage
+ m_widget = core->widgetFactory()->createWidget(QLatin1String("QWizardPage"), 0);
+ break;
+ }
+ formWindow()->ensureUniqueObjectName(m_widget);
+ core->metaDataBase()->add(m_widget);
+ }
+}
+
+void AddContainerWidgetPageCommand::redo()
+{
+ addPage();
+ cheapUpdate();
+}
+
+void AddContainerWidgetPageCommand::undo()
+{
+ removePage();
+ cheapUpdate();
+}
+
+ChangeCurrentPageCommand::ChangeCurrentPageCommand(QDesignerFormWindowInterface *formWindow)
+ :
+ QDesignerFormWindowCommand(QString(), formWindow), m_oldIndex(0), m_newIndex(0)
+{
+}
+
+ChangeCurrentPageCommand::~ChangeCurrentPageCommand()
+{
+}
+
+QDesignerContainerExtension *ChangeCurrentPageCommand::containerExtension() const
+{
+ QExtensionManager *mgr = core()->extensionManager();
+ return qt_extension<QDesignerContainerExtension*>(mgr, m_containerWidget);
+}
+
+void ChangeCurrentPageCommand::init(QWidget *containerWidget, int newIndex)
+{
+ m_containerWidget = containerWidget;
+
+ if (QDesignerContainerExtension *c = containerExtension()) {
+ m_newIndex = newIndex;
+ m_oldIndex = c->currentIndex();
+ m_widget = c->widget(m_oldIndex);
+ }
+}
+
+void ChangeCurrentPageCommand::redo()
+{
+ containerExtension()->setCurrentIndex(m_newIndex);
+}
+
+void ChangeCurrentPageCommand::undo()
+{
+ containerExtension()->setCurrentIndex(m_oldIndex);
+}
+
+static int itemRoles[] = {
+ Qt::DecorationPropertyRole,
+ Qt::DisplayPropertyRole,
+ Qt::ToolTipPropertyRole,
+ Qt::StatusTipPropertyRole,
+ Qt::WhatsThisPropertyRole,
+ Qt::FontRole,
+ Qt::TextAlignmentRole,
+ Qt::BackgroundRole,
+ Qt::ForegroundRole,
+ Qt::CheckStateRole,
+ -1
+};
+
+template<class T>
+static void copyRoleFromItem(ItemData *id, int role, const T *item)
+{
+ QVariant v = item->data(role);
+ if (v.isValid())
+ id->m_properties.insert(role, v);
+}
+
+template<class T>
+static void copyRolesFromItem(ItemData *id, const T *item, bool editor)
+{
+ static const int defaultFlags = T().flags();
+
+ for (int i = 0; itemRoles[i] != -1; i++)
+ copyRoleFromItem<T>(id, itemRoles[i], item);
+
+ if (editor)
+ copyRoleFromItem<T>(id, ItemFlagsShadowRole, item);
+ else if (item->flags() != defaultFlags)
+ id->m_properties.insert(ItemFlagsShadowRole, QVariant::fromValue((int)item->flags()));
+}
+
+template<class T>
+static void copyRolesToItem(const ItemData *id, T *item, DesignerIconCache *iconCache, bool editor)
+{
+ QHash<int, QVariant>::const_iterator it = id->m_properties.constBegin(),
+ end = id->m_properties.constEnd();
+ for (; it != end; ++it)
+ if (it.value().isValid()) {
+ if (!editor && it.key() == ItemFlagsShadowRole) {
+ item->setFlags((Qt::ItemFlags)it.value().toInt());
+ } else {
+ item->setData(it.key(), it.value());
+ switch (it.key()) {
+ case Qt::DecorationPropertyRole:
+ if (iconCache)
+ item->setIcon(iconCache->icon(qvariant_cast<PropertySheetIconValue>(it.value())));
+ break;
+ case Qt::DisplayPropertyRole:
+ item->setText(qvariant_cast<PropertySheetStringValue>(it.value()).value());
+ break;
+ case Qt::ToolTipPropertyRole:
+ item->setToolTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
+ break;
+ case Qt::StatusTipPropertyRole:
+ item->setStatusTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
+ break;
+ case Qt::WhatsThisPropertyRole:
+ item->setWhatsThis(qvariant_cast<PropertySheetStringValue>(it.value()).value());
+ break;
+ }
+ }
+ }
+
+ if (editor)
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+}
+
+ItemData::ItemData(const QListWidgetItem *item, bool editor)
+{
+ copyRolesFromItem<QListWidgetItem>(this, item, editor);
+}
+
+QListWidgetItem *ItemData::createListItem(DesignerIconCache *iconCache, bool editor) const
+{
+ QListWidgetItem *item = new QListWidgetItem();
+ copyRolesToItem(this, item, iconCache, editor);
+ return item;
+}
+
+ItemData::ItemData(const QTableWidgetItem *item, bool editor)
+{
+ copyRolesFromItem(this, item, editor);
+}
+
+QTableWidgetItem *ItemData::createTableItem(DesignerIconCache *iconCache, bool editor) const
+{
+ QTableWidgetItem *item = new QTableWidgetItem;
+ copyRolesToItem(this, item, iconCache, editor);
+ return item;
+}
+
+static void copyRoleFromItem(ItemData *id, int role, const QTreeWidgetItem *item, int column)
+{
+ QVariant v = item->data(column, role);
+ if (v.isValid())
+ id->m_properties.insert(role, v);
+}
+
+ItemData::ItemData(const QTreeWidgetItem *item, int column)
+{
+ copyRoleFromItem(this, Qt::EditRole, item, column);
+ PropertySheetStringValue str(item->text(column));
+ m_properties.insert(Qt::DisplayPropertyRole, QVariant::fromValue(str));
+
+ for (int i = 0; itemRoles[i] != -1; i++)
+ copyRoleFromItem(this, itemRoles[i], item, column);
+}
+
+void ItemData::fillTreeItemColumn(QTreeWidgetItem *item, int column, DesignerIconCache *iconCache) const
+{
+ QHash<int, QVariant>::const_iterator it = m_properties.constBegin(), end = m_properties.constEnd();
+ for (; it != end; ++it)
+ if (it.value().isValid()) {
+ item->setData(column, it.key(), it.value());
+ switch (it.key()) {
+ case Qt::DecorationPropertyRole:
+ if (iconCache)
+ item->setIcon(column, iconCache->icon(qvariant_cast<PropertySheetIconValue>(it.value())));
+ break;
+ case Qt::DisplayPropertyRole:
+ item->setText(column, qvariant_cast<PropertySheetStringValue>(it.value()).value());
+ break;
+ case Qt::ToolTipPropertyRole:
+ item->setToolTip(column, qvariant_cast<PropertySheetStringValue>(it.value()).value());
+ break;
+ case Qt::StatusTipPropertyRole:
+ item->setStatusTip(column, qvariant_cast<PropertySheetStringValue>(it.value()).value());
+ break;
+ case Qt::WhatsThisPropertyRole:
+ item->setWhatsThis(column, qvariant_cast<PropertySheetStringValue>(it.value()).value());
+ break;
+ }
+ }
+}
+
+ListContents::ListContents(const QTreeWidgetItem *item)
+{
+ for (int i = 0; i < item->columnCount(); i++)
+ m_items.append(ItemData(item, i));
+}
+
+QTreeWidgetItem *ListContents::createTreeItem(DesignerIconCache *iconCache) const
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem;
+ int i = 0;
+ foreach (const ItemData &id, m_items)
+ id.fillTreeItemColumn(item, i++, iconCache);
+ return item;
+}
+
+void ListContents::createFromListWidget(const QListWidget *listWidget, bool editor)
+{
+ m_items.clear();
+
+ for (int i = 0; i < listWidget->count(); i++)
+ m_items.append(ItemData(listWidget->item(i), editor));
+}
+
+void ListContents::applyToListWidget(QListWidget *listWidget, DesignerIconCache *iconCache, bool editor) const
+{
+ listWidget->clear();
+
+ int i = 0;
+ foreach (const ItemData &entry, m_items) {
+ if (!entry.isValid())
+ new QListWidgetItem(TableWidgetContents::defaultHeaderText(i), listWidget);
+ else
+ listWidget->addItem(entry.createListItem(iconCache, editor));
+ i++;
+ }
+}
+
+void ListContents::createFromComboBox(const QComboBox *comboBox)
+{
+ m_items.clear();
+
+ const int count = comboBox->count();
+ for (int i = 0; i < count; i++) {
+ // We might encounter items added in a custom combo
+ // constructor. Ignore those.
+ const QVariant textValue = comboBox->itemData(i, Qt::DisplayPropertyRole);
+ if (!textValue.isNull()) {
+ ItemData entry;
+ entry.m_properties.insert(Qt::DisplayPropertyRole, textValue);
+ const QVariant iconValue = comboBox->itemData(i, Qt::DecorationPropertyRole);
+ if (!iconValue.isNull())
+ entry.m_properties.insert(Qt::DecorationPropertyRole, iconValue);
+ m_items.append(entry);
+ }
+ }
+}
+
+void ListContents::applyToComboBox(QComboBox *comboBox, DesignerIconCache *iconCache) const
+{
+ comboBox->clear();
+
+ foreach (const ItemData &hash, m_items) {
+ QIcon icon;
+ if (iconCache)
+ icon = iconCache->icon(qvariant_cast<PropertySheetIconValue>(
+ hash.m_properties[Qt::DecorationPropertyRole]));
+ QVariant var = hash.m_properties[Qt::DisplayPropertyRole];
+ PropertySheetStringValue str = qvariant_cast<PropertySheetStringValue>(var);
+ comboBox->addItem(icon, str.value());
+ comboBox->setItemData(comboBox->count() - 1,
+ var,
+ Qt::DisplayPropertyRole);
+ comboBox->setItemData(comboBox->count() - 1,
+ hash.m_properties[Qt::DecorationPropertyRole],
+ Qt::DecorationPropertyRole);
+ }
+}
+
+// --------- TableWidgetContents
+
+TableWidgetContents::TableWidgetContents() :
+ m_columnCount(0),
+ m_rowCount(0)
+{
+}
+
+void TableWidgetContents::clear()
+{
+ m_horizontalHeader.m_items.clear();
+ m_verticalHeader.m_items.clear();
+ m_items.clear();
+ m_columnCount = 0;
+ m_rowCount = 0;
+}
+
+QString TableWidgetContents::defaultHeaderText(int i)
+{
+ return QString::number(i + 1);
+}
+
+bool TableWidgetContents::nonEmpty(const QTableWidgetItem *item, int headerColumn)
+{
+ static int defaultFlags = QTableWidgetItem().flags();
+
+ if (item->flags() != defaultFlags)
+ return true;
+
+ QString text = qvariant_cast<PropertySheetStringValue>(item->data(Qt::DisplayPropertyRole)).value();
+ if (!text.isEmpty()) {
+ if (headerColumn < 0 || text != defaultHeaderText(headerColumn))
+ return true;
+ } else {
+ // FIXME: This doesn't seem to make sense
+ return true;
+ }
+
+ for (int i = 0; itemRoles[i] != -1; i++)
+ if (itemRoles[i] != Qt::DisplayPropertyRole && item->data(itemRoles[i]).isValid())
+ return true;
+
+ return false;
+}
+
+void TableWidgetContents::insertHeaderItem(const QTableWidgetItem *item, int i, ListContents *header, bool editor)
+{
+ if (nonEmpty(item, i))
+ header->m_items.append(ItemData(item, editor));
+ else
+ header->m_items.append(ItemData());
+}
+
+void TableWidgetContents::fromTableWidget(const QTableWidget *tableWidget, bool editor)
+{
+ clear();
+ m_columnCount = tableWidget->columnCount();
+ m_rowCount = tableWidget->rowCount();
+ // horiz header: Legacy behaviour: auto-generate number for empty items
+ for (int col = 0; col < m_columnCount; col++)
+ if (const QTableWidgetItem *item = tableWidget->horizontalHeaderItem(col))
+ insertHeaderItem(item, col, &m_horizontalHeader, editor);
+ // vertical header: Legacy behaviour: auto-generate number for empty items
+ for (int row = 0; row < m_rowCount; row++)
+ if (const QTableWidgetItem *item = tableWidget->verticalHeaderItem(row))
+ insertHeaderItem(item, row, &m_verticalHeader, editor);
+ // cell data
+ for (int col = 0; col < m_columnCount; col++)
+ for (int row = 0; row < m_rowCount; row++)
+ if (const QTableWidgetItem *item = tableWidget->item(row, col))
+ if (nonEmpty(item, -1))
+ m_items.insert(CellRowColumnAddress(row, col), ItemData(item, editor));
+}
+
+void TableWidgetContents::applyToTableWidget(QTableWidget *tableWidget, DesignerIconCache *iconCache, bool editor) const
+{
+ tableWidget->clear();
+
+ tableWidget->setColumnCount(m_columnCount);
+ tableWidget->setRowCount(m_rowCount);
+
+ // horiz header
+ int col = 0;
+ foreach (const ItemData &id, m_horizontalHeader.m_items) {
+ if (id.isValid())
+ tableWidget->setHorizontalHeaderItem(col, id.createTableItem(iconCache, editor));
+ col++;
+ }
+ // vertical header
+ int row = 0;
+ foreach (const ItemData &id, m_verticalHeader.m_items) {
+ if (id.isValid())
+ tableWidget->setVerticalHeaderItem(row, id.createTableItem(iconCache, editor));
+ row++;
+ }
+ // items
+ const TableItemMap::const_iterator icend = m_items.constEnd();
+ for (TableItemMap::const_iterator it = m_items.constBegin(); it != icend; ++ it)
+ tableWidget->setItem(it.key().first, it.key().second, it.value().createTableItem(iconCache, editor));
+}
+
+bool TableWidgetContents::operator==(const TableWidgetContents &rhs) const
+{
+ if (m_columnCount != rhs.m_columnCount || m_rowCount != rhs.m_rowCount)
+ return false;
+
+ return m_horizontalHeader.m_items == rhs.m_horizontalHeader.m_items &&
+ m_verticalHeader.m_items == rhs.m_verticalHeader.m_items &&
+ m_items == rhs.m_items;
+}
+
+// ---- ChangeTableContentsCommand ----
+ChangeTableContentsCommand::ChangeTableContentsCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Change Table Contents"),
+ formWindow), m_iconCache(0)
+{
+ FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
+ if (fwb)
+ m_iconCache = fwb->iconCache();
+}
+
+void ChangeTableContentsCommand::init(QTableWidget *tableWidget,
+ const TableWidgetContents &oldCont, const TableWidgetContents &newCont)
+{
+ m_tableWidget = tableWidget;
+ m_oldContents = oldCont;
+ m_newContents = newCont;
+}
+
+void ChangeTableContentsCommand::redo()
+{
+ m_newContents.applyToTableWidget(m_tableWidget, m_iconCache, false);
+ QMetaObject::invokeMethod(m_tableWidget, "updateGeometries");
+}
+
+void ChangeTableContentsCommand::undo()
+{
+ m_oldContents.applyToTableWidget(m_tableWidget, m_iconCache, false);
+ QMetaObject::invokeMethod(m_tableWidget, "updateGeometries");
+}
+
+// --------- TreeWidgetContents
+TreeWidgetContents::ItemContents::ItemContents(const QTreeWidgetItem *item, bool editor) :
+ ListContents(item)
+{
+ static const int defaultFlags = QTreeWidgetItem().flags();
+
+ if (editor) {
+ QVariant v = item->data(0, ItemFlagsShadowRole);
+ m_itemFlags = v.isValid() ? v.toInt() : -1;
+ } else {
+ m_itemFlags = (item->flags() != defaultFlags) ? (int)item->flags() : -1;
+ }
+
+ for (int i = 0; i < item->childCount(); i++)
+ m_children.append(ItemContents(item->child(i), editor));
+}
+
+QTreeWidgetItem *TreeWidgetContents::ItemContents::createTreeItem(DesignerIconCache *iconCache, bool editor) const
+{
+ QTreeWidgetItem *item = ListContents::createTreeItem(iconCache);
+
+ if (editor)
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+
+ if (m_itemFlags != -1) {
+ if (editor)
+ item->setData(0, ItemFlagsShadowRole, QVariant::fromValue(m_itemFlags));
+ else
+ item->setFlags((Qt::ItemFlags)m_itemFlags);
+ }
+
+ foreach (const ItemContents &ic, m_children)
+ item->addChild(ic.createTreeItem(iconCache, editor));
+
+ return item;
+}
+
+bool TreeWidgetContents::ItemContents::operator==(const TreeWidgetContents::ItemContents &rhs) const
+{
+ return
+ m_itemFlags == rhs.m_itemFlags &&
+ m_items == rhs.m_items &&
+ m_children == rhs.m_children;
+}
+
+void TreeWidgetContents::clear()
+{
+ m_headerItem.m_items.clear();
+ m_rootItems.clear();
+}
+
+void TreeWidgetContents::fromTreeWidget(const QTreeWidget *treeWidget, bool editor)
+{
+ clear();
+ m_headerItem = ListContents(treeWidget->headerItem());
+ for (int col = 0; col < treeWidget->topLevelItemCount(); col++)
+ m_rootItems.append(ItemContents(treeWidget->topLevelItem(col), editor));
+}
+
+void TreeWidgetContents::applyToTreeWidget(QTreeWidget *treeWidget, DesignerIconCache *iconCache, bool editor) const
+{
+ treeWidget->clear();
+
+ treeWidget->setColumnCount(m_headerItem.m_items.count());
+ treeWidget->setHeaderItem(m_headerItem.createTreeItem(iconCache));
+ foreach (const ItemContents &ic, m_rootItems)
+ treeWidget->addTopLevelItem(ic.createTreeItem(iconCache, editor));
+ treeWidget->expandAll();
+}
+
+bool TreeWidgetContents::operator==(const TreeWidgetContents &rhs) const
+{
+ return
+ m_headerItem == rhs.m_headerItem &&
+ m_rootItems == rhs.m_rootItems;
+}
+
+// ---- ChangeTreeContentsCommand ----
+ChangeTreeContentsCommand::ChangeTreeContentsCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Change Tree Contents"), formWindow),
+ m_iconCache(0)
+{
+ FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
+ if (fwb)
+ m_iconCache = fwb->iconCache();
+}
+
+void ChangeTreeContentsCommand::init(QTreeWidget *treeWidget,
+ const TreeWidgetContents &oldState, const TreeWidgetContents &newState)
+{
+ m_treeWidget = treeWidget;
+ m_oldState = oldState;
+ m_newState = newState;
+}
+
+void ChangeTreeContentsCommand::redo()
+{
+ m_newState.applyToTreeWidget(m_treeWidget, m_iconCache, false);
+}
+
+void ChangeTreeContentsCommand::undo()
+{
+ m_oldState.applyToTreeWidget(m_treeWidget, m_iconCache, false);
+}
+
+// ---- ChangeListContentsCommand ----
+ChangeListContentsCommand::ChangeListContentsCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QString(), formWindow), m_iconCache(0)
+{
+ FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
+ if (fwb)
+ m_iconCache = fwb->iconCache();
+}
+
+void ChangeListContentsCommand::init(QListWidget *listWidget,
+ const ListContents &oldItems, const ListContents &items)
+{
+ m_listWidget = listWidget;
+ m_comboBox = 0;
+
+ m_newItemsState = items;
+ m_oldItemsState = oldItems;
+}
+
+void ChangeListContentsCommand::init(QComboBox *comboBox,
+ const ListContents &oldItems, const ListContents &items)
+{
+ m_listWidget = 0;
+ m_comboBox = comboBox;
+
+ m_newItemsState = items;
+ m_oldItemsState = oldItems;
+}
+
+void ChangeListContentsCommand::redo()
+{
+ if (m_listWidget)
+ m_newItemsState.applyToListWidget(m_listWidget, m_iconCache, false);
+ else if (m_comboBox)
+ m_newItemsState.applyToComboBox(m_comboBox, m_iconCache);
+}
+
+void ChangeListContentsCommand::undo()
+{
+ if (m_listWidget)
+ m_oldItemsState.applyToListWidget(m_listWidget, m_iconCache, false);
+ else if (m_comboBox)
+ m_oldItemsState.applyToComboBox(m_comboBox, m_iconCache);
+}
+
+// ---- AddActionCommand ----
+
+AddActionCommand::AddActionCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Add action"), formWindow)
+{
+ m_action = 0;
+}
+
+void AddActionCommand::init(QAction *action)
+{
+ Q_ASSERT(m_action == 0);
+ m_action = action;
+}
+
+void AddActionCommand::redo()
+{
+ core()->actionEditor()->setFormWindow(formWindow());
+ core()->actionEditor()->manageAction(m_action);
+}
+
+void AddActionCommand::undo()
+{
+ core()->actionEditor()->setFormWindow(formWindow());
+ core()->actionEditor()->unmanageAction(m_action);
+}
+
+// ---- RemoveActionCommand ----
+
+RemoveActionCommand::RemoveActionCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Remove action"), formWindow),
+ m_action(0)
+{
+}
+
+static RemoveActionCommand::ActionData findActionIn(QAction *action)
+{
+ RemoveActionCommand::ActionData result;
+ // We only want menus and toolbars, no toolbuttons.
+ foreach (QWidget *widget, action->associatedWidgets())
+ if (qobject_cast<const QMenu *>(widget) || qobject_cast<const QToolBar *>(widget)) {
+ const QList<QAction*> actionList = widget->actions();
+ const int size = actionList.size();
+ for (int i = 0; i < size; ++i) {
+ if (actionList.at(i) == action) {
+ QAction *before = 0;
+ if (i + 1 < size)
+ before = actionList.at(i + 1);
+ result.append(RemoveActionCommand::ActionDataItem(before, widget));
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+void RemoveActionCommand::init(QAction *action)
+{
+ Q_ASSERT(m_action == 0);
+ m_action = action;
+
+ m_actionData = findActionIn(action);
+}
+
+void RemoveActionCommand::redo()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ foreach (const ActionDataItem &item, m_actionData) {
+ item.widget->removeAction(m_action);
+ }
+ // Notify components (for example, signal slot editor)
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(fw))
+ fwb->emitObjectRemoved(m_action);
+
+ core()->actionEditor()->setFormWindow(fw);
+ core()->actionEditor()->unmanageAction(m_action);
+ if (!m_actionData.empty())
+ core()->objectInspector()->setFormWindow(fw);
+}
+
+void RemoveActionCommand::undo()
+{
+ core()->actionEditor()->setFormWindow(formWindow());
+ core()->actionEditor()->manageAction(m_action);
+ foreach (const ActionDataItem &item, m_actionData) {
+ item.widget->insertAction(item.before, m_action);
+ }
+ if (!m_actionData.empty())
+ core()->objectInspector()->setFormWindow(formWindow());
+}
+
+// ---- ActionInsertionCommand ----
+
+ActionInsertionCommand::ActionInsertionCommand(const QString &text, QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(text, formWindow),
+ m_parentWidget(0),
+ m_action(0),
+ m_beforeAction(0),
+ m_update(false)
+{
+}
+
+void ActionInsertionCommand::init(QWidget *parentWidget, QAction *action, QAction *beforeAction, bool update)
+{
+ Q_ASSERT(m_parentWidget == 0);
+ Q_ASSERT(m_action == 0);
+
+ m_parentWidget = parentWidget;
+ m_action = action;
+ m_beforeAction = beforeAction;
+ m_update = update;
+}
+
+void ActionInsertionCommand::insertAction()
+{
+ Q_ASSERT(m_action != 0);
+ Q_ASSERT(m_parentWidget != 0);
+
+ if (m_beforeAction)
+ m_parentWidget->insertAction(m_beforeAction, m_action);
+ else
+ m_parentWidget->addAction(m_action);
+
+ if (m_update) {
+ cheapUpdate();
+ if (QMenu *menu = m_action->menu())
+ selectUnmanagedObject(menu);
+ else
+ selectUnmanagedObject(m_action);
+ PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
+ }
+}
+void ActionInsertionCommand::removeAction()
+{
+ Q_ASSERT(m_action != 0);
+ Q_ASSERT(m_parentWidget != 0);
+
+ if (QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(m_parentWidget))
+ menu->hideSubMenu();
+
+ m_parentWidget->removeAction(m_action);
+
+ if (m_update) {
+ cheapUpdate();
+ selectUnmanagedObject(m_parentWidget);
+ PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
+ }
+}
+
+InsertActionIntoCommand::InsertActionIntoCommand(QDesignerFormWindowInterface *formWindow) :
+ ActionInsertionCommand(QApplication::translate("Command", "Add action"), formWindow)
+{
+}
+// ---- RemoveActionFromCommand ----
+
+RemoveActionFromCommand::RemoveActionFromCommand(QDesignerFormWindowInterface *formWindow) :
+ ActionInsertionCommand(QApplication::translate("Command", "Remove action"), formWindow)
+{
+}
+
+// ---- AddMenuActionCommand ----
+
+MenuActionCommand::MenuActionCommand(const QString &text, QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(text, formWindow),
+ m_action(0),
+ m_actionBefore(0),
+ m_menuParent(0),
+ m_associatedWidget(0),
+ m_objectToSelect(0)
+{
+}
+
+void MenuActionCommand::init(QAction *action, QAction *actionBefore,
+ QWidget *associatedWidget, QWidget *objectToSelect)
+{
+ QMenu *menu = action->menu();
+ Q_ASSERT(menu);
+ m_menuParent = menu->parentWidget();
+ m_action = action;
+ m_actionBefore = actionBefore;
+ m_associatedWidget = associatedWidget;
+ m_objectToSelect = objectToSelect;
+}
+
+void MenuActionCommand::insertMenu()
+{
+ core()->metaDataBase()->add(m_action);
+ QMenu *menu = m_action->menu();
+ if (m_menuParent && menu->parentWidget() != m_menuParent)
+ menu->setParent(m_menuParent);
+ core()->metaDataBase()->add(menu);
+ m_associatedWidget->insertAction(m_actionBefore, m_action);
+ cheapUpdate();
+ selectUnmanagedObject(menu);
+}
+
+void MenuActionCommand::removeMenu()
+{
+ m_action->menu()->setParent(0);
+ QMenu *menu = m_action->menu();
+ core()->metaDataBase()->remove(menu);
+ menu->setParent(0);
+ core()->metaDataBase()->remove(m_action);
+ m_associatedWidget->removeAction(m_action);
+ cheapUpdate();
+ selectUnmanagedObject(m_objectToSelect);
+}
+
+AddMenuActionCommand::AddMenuActionCommand(QDesignerFormWindowInterface *formWindow) :
+ MenuActionCommand(QApplication::translate("Command", "Add menu"), formWindow)
+{
+}
+
+// ---- RemoveMenuActionCommand ----
+RemoveMenuActionCommand::RemoveMenuActionCommand(QDesignerFormWindowInterface *formWindow) :
+ MenuActionCommand(QApplication::translate("Command", "Remove menu"), formWindow)
+{
+}
+
+// ---- CreateSubmenuCommand ----
+CreateSubmenuCommand::CreateSubmenuCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Create submenu"), formWindow),
+ m_action(0),
+ m_menu(0),
+ m_objectToSelect(0)
+{
+}
+
+void CreateSubmenuCommand::init(QDesignerMenu *menu, QAction *action, QObject *objectToSelect)
+{
+ m_menu = menu;
+ m_action = action;
+ m_objectToSelect = objectToSelect;
+}
+
+void CreateSubmenuCommand::redo()
+{
+ m_menu->createRealMenuAction(m_action);
+ cheapUpdate();
+ if (m_objectToSelect)
+ selectUnmanagedObject(m_objectToSelect);
+}
+
+void CreateSubmenuCommand::undo()
+{
+ m_menu->removeRealMenu(m_action);
+ cheapUpdate();
+ selectUnmanagedObject(m_menu);
+}
+
+// ---- DeleteToolBarCommand ----
+DeleteToolBarCommand::DeleteToolBarCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QApplication::translate("Command", "Delete Tool Bar"), formWindow)
+{
+}
+
+void DeleteToolBarCommand::init(QToolBar *toolBar)
+{
+ m_toolBar = toolBar;
+ m_mainWindow = qobject_cast<QMainWindow*>(toolBar->parentWidget());
+}
+
+void DeleteToolBarCommand::redo()
+{
+ if (m_mainWindow) {
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
+ Q_ASSERT(c != 0);
+ for (int i=0; i<c->count(); ++i) {
+ if (c->widget(i) == m_toolBar) {
+ c->remove(i);
+ break;
+ }
+ }
+ }
+
+ core()->metaDataBase()->remove(m_toolBar);
+ m_toolBar->hide();
+ m_toolBar->setParent(formWindow());
+ formWindow()->emitSelectionChanged();
+}
+
+void DeleteToolBarCommand::undo()
+{
+ if (m_mainWindow) {
+ m_toolBar->setParent(m_mainWindow);
+ QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
+
+ c->addWidget(m_toolBar);
+
+ core()->metaDataBase()->add(m_toolBar);
+ m_toolBar->show();
+ formWindow()->emitSelectionChanged();
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_command2.cpp b/src/designer/src/lib/shared/qdesigner_command2.cpp
new file mode 100644
index 000000000..2b0a5a21a
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_command2.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_command2_p.h"
+#include "formwindowbase_p.h"
+#include "layoutinfo_p.h"
+#include "qdesigner_command_p.h"
+#include "widgetfactory_p.h"
+#include "qlayout_widget_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+
+#include <QtGui/QApplication>
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+MorphLayoutCommand::MorphLayoutCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QString(), formWindow),
+ m_breakLayoutCommand(new BreakLayoutCommand(formWindow)),
+ m_layoutCommand(new LayoutCommand(formWindow)),
+ m_newType(LayoutInfo::VBox),
+ m_layoutBase(0)
+{
+}
+
+MorphLayoutCommand::~MorphLayoutCommand()
+{
+ delete m_layoutCommand;
+ delete m_breakLayoutCommand;
+}
+
+bool MorphLayoutCommand::init(QWidget *w, int newType)
+{
+ int oldType;
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!canMorph(fw, w, &oldType) || oldType == newType)
+ return false;
+ m_layoutBase = w;
+ m_newType = newType;
+ // Find all managed widgets
+ m_widgets.clear();
+ const QLayout *layout = LayoutInfo::managedLayout(fw->core(), w);
+ const int count = layout->count();
+ for (int i = 0; i < count ; i++) {
+ if (QWidget *w = layout->itemAt(i)->widget())
+ if (fw->isManaged(w))
+ m_widgets.push_back(w);
+ }
+ const bool reparentLayoutWidget = false; // leave QLayoutWidget intact
+ m_breakLayoutCommand->init(m_widgets, m_layoutBase, reparentLayoutWidget);
+ m_layoutCommand->init(m_layoutBase, m_widgets, static_cast<LayoutInfo::Type>(m_newType), m_layoutBase, reparentLayoutWidget);
+ setText(formatDescription(core(), m_layoutBase, oldType, newType));
+ return true;
+}
+
+bool MorphLayoutCommand::canMorph(const QDesignerFormWindowInterface *formWindow, QWidget *w, int *ptrToCurrentType)
+{
+ if (ptrToCurrentType)
+ *ptrToCurrentType = LayoutInfo::NoLayout;
+ // We want a managed widget or a container page
+ // with a level-0 managed layout
+ QDesignerFormEditorInterface *core = formWindow->core();
+ QLayout *layout = LayoutInfo::managedLayout(core, w);
+ if (!layout)
+ return false;
+ const LayoutInfo::Type type = LayoutInfo::layoutType(core, layout);
+ if (ptrToCurrentType)
+ *ptrToCurrentType = type;
+ switch (type) {
+ case LayoutInfo::HBox:
+ case LayoutInfo::VBox:
+ case LayoutInfo::Grid:
+ case LayoutInfo::Form:
+ return true;
+ break;
+ case LayoutInfo::NoLayout:
+ case LayoutInfo::HSplitter: // Nothing doing
+ case LayoutInfo::VSplitter:
+ case LayoutInfo::UnknownLayout:
+ break;
+ }
+ return false;
+}
+
+void MorphLayoutCommand::redo()
+{
+ m_breakLayoutCommand->redo();
+ m_layoutCommand->redo();
+ /* Transfer applicable properties which is a cross-section of the modified
+ * properties except object name. */
+ if (const LayoutProperties *properties = m_breakLayoutCommand->layoutProperties()) {
+ const int oldMask = m_breakLayoutCommand->propertyMask();
+ QLayout *newLayout = LayoutInfo::managedLayout(core(), m_layoutBase);
+ const int newMask = LayoutProperties::visibleProperties(newLayout);
+ const int applicableMask = (oldMask & newMask) & ~LayoutProperties::ObjectNameProperty;
+ if (applicableMask)
+ properties->toPropertySheet(core(), newLayout, applicableMask);
+ }
+}
+
+void MorphLayoutCommand::undo()
+{
+ m_layoutCommand->undo();
+ m_breakLayoutCommand->undo();
+}
+
+QString MorphLayoutCommand::formatDescription(QDesignerFormEditorInterface * /* core*/, const QWidget *w, int oldType, int newType)
+{
+ const QString oldName = LayoutInfo::layoutName(static_cast<LayoutInfo::Type>(oldType));
+ const QString newName = LayoutInfo::layoutName(static_cast<LayoutInfo::Type>(newType));
+ const QString widgetName = qobject_cast<const QLayoutWidget*>(w) ? w->layout()->objectName() : w->objectName();
+ return QApplication::translate("Command", "Change layout of '%1' from %2 to %3").arg(widgetName, oldName, newName);
+}
+
+LayoutAlignmentCommand::LayoutAlignmentCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Change layout alignment"), formWindow),
+ m_newAlignment(0), m_oldAlignment(0), m_widget(0)
+{
+}
+
+bool LayoutAlignmentCommand::init(QWidget *w, Qt::Alignment alignment)
+{
+ bool enabled;
+ m_newAlignment = alignment;
+ m_oldAlignment = LayoutAlignmentCommand::alignmentOf(core(), w, &enabled);
+ m_widget = w;
+ return enabled;
+}
+
+void LayoutAlignmentCommand::redo()
+{
+ LayoutAlignmentCommand::applyAlignment(core(), m_widget, m_newAlignment);
+}
+
+void LayoutAlignmentCommand::undo()
+{
+ LayoutAlignmentCommand::applyAlignment(core(), m_widget, m_oldAlignment);
+}
+
+// Find out alignment and return whether command is enabled.
+Qt::Alignment LayoutAlignmentCommand::alignmentOf(const QDesignerFormEditorInterface *core, QWidget *w, bool *enabledIn)
+{
+ bool managed;
+ QLayout *layout;
+
+ if (enabledIn)
+ *enabledIn = false;
+ // Can only work on a managed layout
+ const LayoutInfo::Type type = LayoutInfo::laidoutWidgetType(core, w, &managed, &layout);
+ const bool enabled = layout && managed &&
+ (type == LayoutInfo::HBox || type == LayoutInfo::VBox
+ || type == LayoutInfo::Grid);
+ if (!enabled)
+ return Qt::Alignment(0);
+ // Get alignment
+ const int index = layout->indexOf(w);
+ Q_ASSERT(index >= 0);
+ if (enabledIn)
+ *enabledIn = true;
+ return layout->itemAt(index)->alignment();
+}
+
+void LayoutAlignmentCommand::applyAlignment(const QDesignerFormEditorInterface *core, QWidget *w, Qt::Alignment a)
+{
+ // Find layout and apply to item
+ QLayout *layout;
+ LayoutInfo::laidoutWidgetType(core, w, 0, &layout);
+ if (layout) {
+ const int index = layout->indexOf(w);
+ if (index >= 0) {
+ layout->itemAt(index)->setAlignment(a);
+ layout->update();
+ }
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_command2_p.h b/src/designer/src/lib/shared/qdesigner_command2_p.h
new file mode 100644
index 000000000..0a6cce88e
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_command2_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_COMMAND2_H
+#define QDESIGNER_COMMAND2_H
+
+#include "shared_global_p.h"
+#include "qdesigner_formwindowcommand_p.h"
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class LayoutCommand;
+class BreakLayoutCommand;
+
+/* This command changes the type of a managed layout on a widget (including
+ * red layouts of type 'QLayoutWidget') into another type, maintaining the
+ * applicable properties. It does this by chaining BreakLayoutCommand and
+ * LayoutCommand, parametrizing them not to actually delete/reparent
+ * QLayoutWidget's. */
+
+class QDESIGNER_SHARED_EXPORT MorphLayoutCommand : public QDesignerFormWindowCommand {
+ Q_DISABLE_COPY(MorphLayoutCommand)
+public:
+ explicit MorphLayoutCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~MorphLayoutCommand();
+
+ bool init(QWidget *w, int newType);
+
+ static bool canMorph(const QDesignerFormWindowInterface *formWindow, QWidget *w, int *ptrToCurrentType = 0);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ static QString formatDescription(QDesignerFormEditorInterface *core, const QWidget *w, int oldType, int newType);
+
+ BreakLayoutCommand *m_breakLayoutCommand;
+ LayoutCommand *m_layoutCommand;
+ int m_newType;
+ QWidgetList m_widgets;
+ QWidget *m_layoutBase;
+};
+
+// Change the alignment of a widget in a managed grid/box layout cell.
+class LayoutAlignmentCommand : public QDesignerFormWindowCommand {
+ Q_DISABLE_COPY(LayoutAlignmentCommand)
+public:
+ explicit LayoutAlignmentCommand(QDesignerFormWindowInterface *formWindow);
+
+ bool init(QWidget *w, Qt::Alignment alignment);
+
+ virtual void redo();
+ virtual void undo();
+
+ // Find out alignment and return whether command is enabled.
+ static Qt::Alignment alignmentOf(const QDesignerFormEditorInterface *core, QWidget *w, bool *enabled = 0);
+
+private:
+ static void applyAlignment(const QDesignerFormEditorInterface *core, QWidget *w, Qt::Alignment a);
+
+ Qt::Alignment m_newAlignment;
+ Qt::Alignment m_oldAlignment;
+ QWidget *m_widget;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_COMMAND2_H
diff --git a/src/designer/src/lib/shared/qdesigner_command_p.h b/src/designer/src/lib/shared/qdesigner_command_p.h
new file mode 100644
index 000000000..323cec5e5
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_command_p.h
@@ -0,0 +1,1136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_COMMAND_H
+#define QDESIGNER_COMMAND_H
+
+#include "shared_global_p.h"
+#include "shared_enums_p.h"
+#include "layoutinfo_p.h"
+#include "qdesigner_utils_p.h"
+#include "qdesigner_formwindowcommand_p.h"
+#include "qdesigner_formeditorcommand_p.h"
+
+#include <QtDesigner/layoutdecoration.h>
+
+#include <QtGui/QIcon>
+#include <QtCore/QObject>
+#include <QtCore/QPair>
+#include <QtCore/QMap>
+#include <QtCore/QHash>
+#include <QtCore/QPoint>
+#include <QtCore/QRect>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerContainerExtension;
+class QDesignerMetaDataBaseItemInterface;
+class QDesignerMenu;
+
+class QMenuBar;
+class QStatusBar;
+class QToolBar;
+class QToolBox;
+class QTabWidget;
+class QTableWidget;
+class QTableWidgetItem;
+class QTreeWidget;
+class QTreeWidgetItem;
+class QListWidget;
+class QListWidgetItem;
+class QComboBox;
+class QStackedWidget;
+class QDockWidget;
+class QMainWindow;
+class QFormLayout;
+
+namespace qdesigner_internal {
+
+class Layout;
+class LayoutHelper;
+class PropertySheetIconValue;
+class DesignerIconCache;
+struct LayoutProperties;
+
+class QDESIGNER_SHARED_EXPORT InsertWidgetCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit InsertWidgetCommand(QDesignerFormWindowInterface *formWindow);
+ ~InsertWidgetCommand();
+
+ void init(QWidget *widget, bool already_in_form = false, int layoutRow = -1, int layoutColumn = -1);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ void refreshBuddyLabels();
+
+ QPointer<QWidget> m_widget;
+ QDesignerLayoutDecorationExtension::InsertMode m_insertMode;
+ QPair<int, int> m_cell;
+ LayoutHelper* m_layoutHelper;
+ bool m_widgetWasManaged;
+};
+
+class QDESIGNER_SHARED_EXPORT ChangeZOrderCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit ChangeZOrderCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QWidget *widget);
+
+ virtual void redo();
+ virtual void undo();
+protected:
+ virtual QWidgetList reorderWidget(const QWidgetList &list, QWidget *widget) const = 0;
+ virtual void reorder(QWidget *widget) const = 0;
+
+private:
+ QPointer<QWidget> m_widget;
+ QPointer<QWidget> m_oldPreceding;
+ QList<QWidget *> m_oldParentZOrder;
+};
+
+class QDESIGNER_SHARED_EXPORT RaiseWidgetCommand: public ChangeZOrderCommand
+{
+
+public:
+ explicit RaiseWidgetCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QWidget *widget);
+
+protected:
+ virtual QWidgetList reorderWidget(const QWidgetList &list, QWidget *widget) const;
+ virtual void reorder(QWidget *widget) const;
+};
+
+class QDESIGNER_SHARED_EXPORT LowerWidgetCommand: public ChangeZOrderCommand
+{
+
+public:
+ explicit LowerWidgetCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QWidget *widget);
+
+protected:
+ virtual QWidgetList reorderWidget(const QWidgetList &list, QWidget *widget) const;
+ virtual void reorder(QWidget *widget) const;
+};
+
+class QDESIGNER_SHARED_EXPORT AdjustWidgetSizeCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit AdjustWidgetSizeCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QWidget *widget);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ QWidget *widgetForAdjust() const;
+ bool adjustNonLaidOutMainContainer(QWidget *integrationContainer);
+ void updatePropertyEditor() const;
+
+ QPointer<QWidget> m_widget;
+ QRect m_geometry;
+};
+
+// Helper to correctly unmanage a widget and its children for delete operations
+class QDESIGNER_SHARED_EXPORT ManageWidgetCommandHelper {
+public:
+ typedef QVector<QWidget*> WidgetVector;
+
+ ManageWidgetCommandHelper();
+ void init(const QDesignerFormWindowInterface *fw, QWidget *widget);
+ void init(QWidget *widget, const WidgetVector &managedChildren);
+
+ void manage(QDesignerFormWindowInterface *fw);
+ void unmanage(QDesignerFormWindowInterface *fw);
+
+ const WidgetVector &managedChildren() const { return m_managedChildren; }
+private:
+ QWidget *m_widget;
+ WidgetVector m_managedChildren;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteWidgetCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit DeleteWidgetCommand(QDesignerFormWindowInterface *formWindow);
+ ~DeleteWidgetCommand();
+
+ enum DeleteFlags { DoNotUnmanage = 0x1, DoNotSimplifyLayout = 0x2 };
+
+ void init(QWidget *widget, unsigned flags = 0);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ QPointer<QWidget> m_widget;
+ QPointer<QWidget> m_parentWidget;
+ QRect m_geometry;
+ LayoutInfo::Type m_layoutType;
+ LayoutHelper* m_layoutHelper;
+ unsigned m_flags;
+ QRect m_layoutPosition;
+ int m_splitterIndex;
+ bool m_layoutSimplified;
+ QDesignerMetaDataBaseItemInterface *m_formItem;
+ int m_tabOrderIndex;
+ int m_widgetOrderIndex;
+ int m_zOrderIndex;
+ ManageWidgetCommandHelper m_manageHelper;
+};
+
+class QDESIGNER_SHARED_EXPORT ReparentWidgetCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit ReparentWidgetCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QWidget *widget, QWidget *parentWidget);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ QPointer<QWidget> m_widget;
+ QPoint m_oldPos;
+ QPoint m_newPos;
+ QPointer<QWidget> m_oldParentWidget;
+ QPointer<QWidget> m_newParentWidget;
+ QList<QWidget *> m_oldParentList;
+ QList<QWidget *> m_oldParentZOrder;
+};
+
+class QDESIGNER_SHARED_EXPORT ChangeFormLayoutItemRoleCommand : public QDesignerFormWindowCommand
+{
+public:
+ enum Operation { SpanningToLabel = 0x1, SpanningToField = 0x2, LabelToSpanning = 0x4, FieldToSpanning =0x8 };
+
+ explicit ChangeFormLayoutItemRoleCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QWidget *widget, Operation op);
+
+ virtual void redo();
+ virtual void undo();
+
+ // Return a mask of possible operations of that item
+ static unsigned possibleOperations(QDesignerFormEditorInterface *core, QWidget *w);
+
+private:
+ static QFormLayout *managedFormLayoutOf(QDesignerFormEditorInterface *core, QWidget *w);
+ static Operation reverseOperation(Operation op);
+ void doOperation(Operation op);
+
+ QPointer<QWidget> m_widget;
+ Operation m_operation;
+};
+
+class QDESIGNER_SHARED_EXPORT ChangeLayoutItemGeometry: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit ChangeLayoutItemGeometry(QDesignerFormWindowInterface *formWindow);
+
+ void init(QWidget *widget, int row, int column, int rowspan, int colspan);
+
+ virtual void redo();
+ virtual void undo();
+
+protected:
+ void changeItemPosition(const QRect &g);
+
+private:
+ QPointer<QWidget> m_widget;
+ QRect m_oldInfo;
+ QRect m_newInfo;
+};
+
+class QDESIGNER_SHARED_EXPORT TabOrderCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit TabOrderCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(const QList<QWidget*> &newTabOrder);
+
+ inline QList<QWidget*> oldTabOrder() const
+ { return m_oldTabOrder; }
+
+ inline QList<QWidget*> newTabOrder() const
+ { return m_newTabOrder; }
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ QDesignerMetaDataBaseItemInterface *m_widgetItem;
+ QList<QWidget*> m_oldTabOrder;
+ QList<QWidget*> m_newTabOrder;
+};
+
+class QDESIGNER_SHARED_EXPORT PromoteToCustomWidgetCommand : public QDesignerFormWindowCommand
+{
+public:
+ typedef QList<QPointer<QWidget> > WidgetList;
+
+ explicit PromoteToCustomWidgetCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(const WidgetList &widgets, const QString &customClassName);
+ virtual void redo();
+ virtual void undo();
+
+private:
+ void updateSelection();
+ WidgetList m_widgets;
+ QString m_customClassName;
+};
+
+class QDESIGNER_SHARED_EXPORT DemoteFromCustomWidgetCommand : public QDesignerFormWindowCommand
+{
+public:
+ typedef PromoteToCustomWidgetCommand::WidgetList WidgetList;
+
+ explicit DemoteFromCustomWidgetCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(const WidgetList &promoted);
+ virtual void redo();
+ virtual void undo();
+private:
+ PromoteToCustomWidgetCommand m_promote_cmd;
+};
+
+// Mixin class for storing the selection state
+class QDESIGNER_SHARED_EXPORT CursorSelectionState {
+ Q_DISABLE_COPY(CursorSelectionState)
+public:
+ CursorSelectionState();
+
+ void save(const QDesignerFormWindowInterface *formWindow);
+ void restore(QDesignerFormWindowInterface *formWindow) const;
+
+private:
+ typedef QList<QPointer<QWidget> > WidgetPointerList;
+ WidgetPointerList m_selection;
+ QPointer<QWidget> m_current;
+};
+
+class QDESIGNER_SHARED_EXPORT LayoutCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit LayoutCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~LayoutCommand();
+
+ inline QWidgetList widgets() const { return m_widgets; }
+
+ void init(QWidget *parentWidget, const QWidgetList &widgets, LayoutInfo::Type layoutType,
+ QWidget *layoutBase = 0,
+ // Reparent/Hide instances of QLayoutWidget.
+ bool reparentLayoutWidget = true);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ QPointer<QWidget> m_parentWidget;
+ QWidgetList m_widgets;
+ QPointer<QWidget> m_layoutBase;
+ QPointer<Layout> m_layout;
+ CursorSelectionState m_cursorSelectionState;
+ bool m_setup;
+};
+
+class QDESIGNER_SHARED_EXPORT BreakLayoutCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit BreakLayoutCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~BreakLayoutCommand();
+
+ inline QWidgetList widgets() const { return m_widgets; }
+
+ void init(const QWidgetList &widgets, QWidget *layoutBase,
+ // Reparent/Hide instances of QLayoutWidget.
+ bool reparentLayoutWidget = true);
+
+ virtual void redo();
+ virtual void undo();
+
+ // Access the properties of the layout, 0 in case of splitters.
+ const LayoutProperties *layoutProperties() const;
+ int propertyMask() const;
+
+private:
+ QWidgetList m_widgets;
+ QPointer<QWidget> m_layoutBase;
+ QPointer<Layout> m_layout;
+ LayoutHelper* m_layoutHelper;
+ LayoutProperties *m_properties;
+ int m_propertyMask;
+ CursorSelectionState m_cursorSelectionState;
+};
+
+class QDESIGNER_SHARED_EXPORT SimplifyLayoutCommand: public QDesignerFormWindowCommand
+{
+public:
+ explicit SimplifyLayoutCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~SimplifyLayoutCommand();
+
+ bool init(QWidget *layoutBase);
+
+ // Quick check
+ static bool canSimplify(QDesignerFormEditorInterface *core, const QWidget *w, int *layoutType = 0);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ const QRect m_area;
+ QWidget *m_layoutBase;
+ LayoutHelper* m_layoutHelper;
+ bool m_layoutSimplified;
+};
+
+class QDESIGNER_SHARED_EXPORT ToolBoxCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit ToolBoxCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~ToolBoxCommand();
+
+ void init(QToolBox *toolBox);
+
+ virtual void removePage();
+ virtual void addPage();
+
+protected:
+ QPointer<QToolBox> m_toolBox;
+ QPointer<QWidget> m_widget;
+ int m_index;
+ QString m_itemText;
+ QIcon m_itemIcon;
+};
+
+class QDESIGNER_SHARED_EXPORT MoveToolBoxPageCommand: public ToolBoxCommand
+{
+
+public:
+ explicit MoveToolBoxPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~MoveToolBoxPageCommand();
+
+ void init(QToolBox *toolBox, QWidget *page, int newIndex);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ int m_newIndex;
+ int m_oldIndex;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteToolBoxPageCommand: public ToolBoxCommand
+{
+
+public:
+ explicit DeleteToolBoxPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~DeleteToolBoxPageCommand();
+
+ void init(QToolBox *toolBox);
+
+ virtual void redo();
+ virtual void undo();
+};
+
+class QDESIGNER_SHARED_EXPORT AddToolBoxPageCommand: public ToolBoxCommand
+{
+
+public:
+ enum InsertionMode {
+ InsertBefore,
+ InsertAfter
+ };
+ explicit AddToolBoxPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~AddToolBoxPageCommand();
+
+ void init(QToolBox *toolBox);
+ void init(QToolBox *toolBox, InsertionMode mode);
+
+ virtual void redo();
+ virtual void undo();
+};
+
+class QDESIGNER_SHARED_EXPORT TabWidgetCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit TabWidgetCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~TabWidgetCommand();
+
+ void init(QTabWidget *tabWidget);
+
+ virtual void removePage();
+ virtual void addPage();
+
+protected:
+ QPointer<QTabWidget> m_tabWidget;
+ QPointer<QWidget> m_widget;
+ int m_index;
+ QString m_itemText;
+ QIcon m_itemIcon;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteTabPageCommand: public TabWidgetCommand
+{
+
+public:
+ explicit DeleteTabPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~DeleteTabPageCommand();
+
+ void init(QTabWidget *tabWidget);
+
+ virtual void redo();
+ virtual void undo();
+};
+
+class QDESIGNER_SHARED_EXPORT AddTabPageCommand: public TabWidgetCommand
+{
+
+public:
+ enum InsertionMode {
+ InsertBefore,
+ InsertAfter
+ };
+ explicit AddTabPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~AddTabPageCommand();
+
+ void init(QTabWidget *tabWidget);
+ void init(QTabWidget *tabWidget, InsertionMode mode);
+
+ virtual void redo();
+ virtual void undo();
+};
+
+class QDESIGNER_SHARED_EXPORT MoveTabPageCommand: public TabWidgetCommand
+{
+
+public:
+ explicit MoveTabPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~MoveTabPageCommand();
+
+ void init(QTabWidget *tabWidget, QWidget *page,
+ const QIcon &icon, const QString &label,
+ int index, int newIndex);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ int m_newIndex;
+ int m_oldIndex;
+ QPointer<QWidget> m_page;
+ QString m_label;
+ QIcon m_icon;
+};
+
+class QDESIGNER_SHARED_EXPORT StackedWidgetCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit StackedWidgetCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~StackedWidgetCommand();
+
+ void init(QStackedWidget *stackedWidget);
+
+ virtual void removePage();
+ virtual void addPage();
+
+protected:
+ QPointer<QStackedWidget> m_stackedWidget;
+ QPointer<QWidget> m_widget;
+ int m_index;
+};
+
+class QDESIGNER_SHARED_EXPORT MoveStackedWidgetCommand: public StackedWidgetCommand
+{
+
+public:
+ explicit MoveStackedWidgetCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~MoveStackedWidgetCommand();
+
+ void init(QStackedWidget *stackedWidget, QWidget *page, int newIndex);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ int m_newIndex;
+ int m_oldIndex;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteStackedWidgetPageCommand: public StackedWidgetCommand
+{
+
+public:
+ explicit DeleteStackedWidgetPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~DeleteStackedWidgetPageCommand();
+
+ void init(QStackedWidget *stackedWidget);
+
+ virtual void redo();
+ virtual void undo();
+};
+
+class QDESIGNER_SHARED_EXPORT AddStackedWidgetPageCommand: public StackedWidgetCommand
+{
+
+public:
+ enum InsertionMode {
+ InsertBefore,
+ InsertAfter
+ };
+ explicit AddStackedWidgetPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~AddStackedWidgetPageCommand();
+
+ void init(QStackedWidget *stackedWidget);
+ void init(QStackedWidget *stackedWidget, InsertionMode mode);
+
+ virtual void redo();
+ virtual void undo();
+};
+
+class QDESIGNER_SHARED_EXPORT CreateMenuBarCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit CreateMenuBarCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QMainWindow *mainWindow);
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ QPointer<QMainWindow> m_mainWindow;
+ QPointer<QMenuBar> m_menuBar;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteMenuBarCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit DeleteMenuBarCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QMenuBar *menuBar);
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ QPointer<QMainWindow> m_mainWindow;
+ QPointer<QMenuBar> m_menuBar;
+};
+
+class QDESIGNER_SHARED_EXPORT CreateStatusBarCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit CreateStatusBarCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QMainWindow *mainWindow);
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ QPointer<QMainWindow> m_mainWindow;
+ QPointer<QStatusBar> m_statusBar;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteStatusBarCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit DeleteStatusBarCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QStatusBar *statusBar);
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ QPointer<QMainWindow> m_mainWindow;
+ QPointer<QStatusBar> m_statusBar;
+};
+
+class QDESIGNER_SHARED_EXPORT AddToolBarCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit AddToolBarCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QMainWindow *mainWindow);
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ QPointer<QMainWindow> m_mainWindow;
+ QPointer<QToolBar> m_toolBar;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteToolBarCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit DeleteToolBarCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QToolBar *toolBar);
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ QPointer<QMainWindow> m_mainWindow;
+ QPointer<QToolBar> m_toolBar;
+};
+
+class QDESIGNER_SHARED_EXPORT DockWidgetCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit DockWidgetCommand(const QString &description, QDesignerFormWindowInterface *formWindow);
+ virtual ~DockWidgetCommand();
+
+ void init(QDockWidget *dockWidget);
+
+protected:
+ QPointer<QDockWidget> m_dockWidget;
+};
+
+class QDESIGNER_SHARED_EXPORT AddDockWidgetCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit AddDockWidgetCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QMainWindow *mainWindow, QDockWidget *dockWidget);
+ void init(QMainWindow *mainWindow);
+
+ virtual void undo();
+ virtual void redo();
+
+private:
+ QPointer<QMainWindow> m_mainWindow;
+ QPointer<QDockWidget> m_dockWidget;
+};
+
+class QDESIGNER_SHARED_EXPORT ContainerWidgetCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit ContainerWidgetCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~ContainerWidgetCommand();
+
+ QDesignerContainerExtension *containerExtension() const;
+
+ void init(QWidget *containerWidget);
+
+ virtual void removePage();
+ virtual void addPage();
+
+protected:
+ QPointer<QWidget> m_containerWidget;
+ QPointer<QWidget> m_widget;
+ int m_index;
+};
+
+class QDESIGNER_SHARED_EXPORT DeleteContainerWidgetPageCommand: public ContainerWidgetCommand
+{
+
+public:
+ explicit DeleteContainerWidgetPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~DeleteContainerWidgetPageCommand();
+
+ void init(QWidget *containerWidget, ContainerType ct);
+
+ virtual void redo();
+ virtual void undo();
+};
+
+class QDESIGNER_SHARED_EXPORT AddContainerWidgetPageCommand: public ContainerWidgetCommand
+{
+
+public:
+ enum InsertionMode {
+ InsertBefore,
+ InsertAfter
+ };
+ explicit AddContainerWidgetPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~AddContainerWidgetPageCommand();
+
+ void init(QWidget *containerWidget, ContainerType ct, InsertionMode mode);
+
+ virtual void redo();
+ virtual void undo();
+};
+
+class QDESIGNER_SHARED_EXPORT ChangeCurrentPageCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit ChangeCurrentPageCommand(QDesignerFormWindowInterface *formWindow);
+ virtual ~ChangeCurrentPageCommand();
+
+ QDesignerContainerExtension *containerExtension() const;
+
+ void init(QWidget *containerWidget, int newIndex);
+
+ virtual void redo();
+ virtual void undo();
+
+protected:
+ QPointer<QWidget> m_containerWidget;
+ QPointer<QWidget> m_widget;
+ int m_oldIndex;
+ int m_newIndex;
+};
+
+struct QDESIGNER_SHARED_EXPORT ItemData {
+ ItemData() {}
+
+ ItemData(const QListWidgetItem *item, bool editor);
+ ItemData(const QTableWidgetItem *item, bool editor);
+ ItemData(const QTreeWidgetItem *item, int column);
+ QListWidgetItem *createListItem(DesignerIconCache *iconCache, bool editor) const;
+ QTableWidgetItem *createTableItem(DesignerIconCache *iconCache, bool editor) const;
+ void fillTreeItemColumn(QTreeWidgetItem *item, int column, DesignerIconCache *iconCache) const;
+
+ bool isValid() const { return !m_properties.isEmpty(); }
+ bool operator==(const ItemData &rhs) const { return m_properties == rhs.m_properties; }
+ bool operator!=(const ItemData &rhs) const { return m_properties != rhs.m_properties; }
+
+ QHash<int, QVariant> m_properties;
+};
+
+struct QDESIGNER_SHARED_EXPORT ListContents {
+ ListContents() {}
+
+ ListContents(const QTreeWidgetItem *item);
+ QTreeWidgetItem *createTreeItem(DesignerIconCache *iconCache) const;
+
+ void createFromListWidget(const QListWidget *listWidget, bool editor);
+ void applyToListWidget(QListWidget *listWidget, DesignerIconCache *iconCache, bool editor) const;
+ void createFromComboBox(const QComboBox *listWidget);
+ void applyToComboBox(QComboBox *listWidget, DesignerIconCache *iconCache) const;
+
+ bool operator==(const ListContents &rhs) const { return m_items == rhs.m_items; }
+ bool operator!=(const ListContents &rhs) const { return m_items != rhs.m_items; }
+
+ QList<ItemData> m_items;
+};
+
+// Data structure representing the contents of a QTableWidget with
+// methods to retrieve and apply for ChangeTableContentsCommand
+struct QDESIGNER_SHARED_EXPORT TableWidgetContents {
+
+ typedef QPair<int, int> CellRowColumnAddress;
+ typedef QMap<CellRowColumnAddress, ItemData> TableItemMap;
+
+ TableWidgetContents();
+ void clear();
+
+ void fromTableWidget(const QTableWidget *tableWidget, bool editor);
+ void applyToTableWidget(QTableWidget *tableWidget, DesignerIconCache *iconCache, bool editor) const;
+
+ bool operator==(const TableWidgetContents &rhs) const;
+ bool operator!=(const TableWidgetContents &rhs) const { return !(*this == rhs); }
+
+ static bool nonEmpty(const QTableWidgetItem *item, int headerColumn);
+ static QString defaultHeaderText(int i);
+ static void insertHeaderItem(const QTableWidgetItem *item, int i, ListContents *header, bool editor);
+
+ int m_columnCount;
+ int m_rowCount;
+ ListContents m_horizontalHeader;
+ ListContents m_verticalHeader;
+ TableItemMap m_items;
+};
+
+class QDESIGNER_SHARED_EXPORT ChangeTableContentsCommand: public QDesignerFormWindowCommand
+{
+public:
+ explicit ChangeTableContentsCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QTableWidget *tableWidget, const TableWidgetContents &oldCont, const TableWidgetContents &newCont);
+ virtual void redo();
+ virtual void undo();
+
+private:
+ QPointer<QTableWidget> m_tableWidget;
+ TableWidgetContents m_oldContents;
+ TableWidgetContents m_newContents;
+ DesignerIconCache *m_iconCache;
+};
+
+// Data structure representing the contents of a QTreeWidget with
+// methods to retrieve and apply for ChangeTreeContentsCommand
+struct QDESIGNER_SHARED_EXPORT TreeWidgetContents {
+
+ struct ItemContents : public ListContents {
+ ItemContents() : m_itemFlags(-1) {}
+ ItemContents(const QTreeWidgetItem *item, bool editor);
+ QTreeWidgetItem *createTreeItem(DesignerIconCache *iconCache, bool editor) const;
+
+ bool operator==(const ItemContents &rhs) const;
+ bool operator!=(const ItemContents &rhs) const { return !(*this == rhs); }
+
+ int m_itemFlags;
+ //bool m_firstColumnSpanned:1;
+ //bool m_hidden:1;
+ //bool m_expanded:1;
+ QList<ItemContents> m_children;
+ };
+
+ void clear();
+
+ void fromTreeWidget(const QTreeWidget *treeWidget, bool editor);
+ void applyToTreeWidget(QTreeWidget *treeWidget, DesignerIconCache *iconCache, bool editor) const;
+
+ bool operator==(const TreeWidgetContents &rhs) const;
+ bool operator!=(const TreeWidgetContents &rhs) const { return !(*this == rhs); }
+
+ ListContents m_headerItem;
+ QList<ItemContents> m_rootItems;
+};
+
+class QDESIGNER_SHARED_EXPORT ChangeTreeContentsCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit ChangeTreeContentsCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QTreeWidget *treeWidget, const TreeWidgetContents &oldState, const TreeWidgetContents &newState);
+ virtual void redo();
+ virtual void undo();
+ enum ApplyIconStrategy {
+ SetIconStrategy,
+ ResetIconStrategy
+ };
+private:
+ QPointer<QTreeWidget> m_treeWidget;
+ TreeWidgetContents m_oldState;
+ TreeWidgetContents m_newState;
+ DesignerIconCache *m_iconCache;
+};
+
+class QDESIGNER_SHARED_EXPORT ChangeListContentsCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit ChangeListContentsCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QListWidget *listWidget, const ListContents &oldItems, const ListContents &items);
+ void init(QComboBox *comboBox, const ListContents &oldItems, const ListContents &items);
+ virtual void redo();
+ virtual void undo();
+private:
+ QPointer<QListWidget> m_listWidget;
+ QPointer<QComboBox> m_comboBox;
+ ListContents m_oldItemsState;
+ ListContents m_newItemsState;
+ DesignerIconCache *m_iconCache;
+};
+
+class QDESIGNER_SHARED_EXPORT AddActionCommand : public QDesignerFormWindowCommand
+{
+
+public:
+ explicit AddActionCommand(QDesignerFormWindowInterface *formWindow);
+ void init(QAction *action);
+ virtual void redo();
+ virtual void undo();
+private:
+ QAction *m_action;
+};
+
+// Note: This command must be executed within a macro since it
+// makes the form emit objectRemoved() which might cause other components
+// to add commands (for example, removal of signals and slots
+class QDESIGNER_SHARED_EXPORT RemoveActionCommand : public QDesignerFormWindowCommand
+{
+
+public:
+ explicit RemoveActionCommand(QDesignerFormWindowInterface *formWindow);
+ void init(QAction *action);
+ virtual void redo();
+ virtual void undo();
+
+ struct ActionDataItem {
+ ActionDataItem(QAction *_before = 0, QWidget *_widget = 0)
+ : before(_before), widget(_widget) {}
+ QAction *before;
+ QWidget *widget;
+ };
+ typedef QList<ActionDataItem> ActionData;
+
+private:
+ QAction *m_action;
+
+ ActionData m_actionData;
+};
+
+class QDESIGNER_SHARED_EXPORT ActionInsertionCommand : public QDesignerFormWindowCommand
+{
+
+protected:
+ ActionInsertionCommand(const QString &text, QDesignerFormWindowInterface *formWindow);
+
+public:
+ void init(QWidget *parentWidget, QAction *action, QAction *beforeAction = 0, bool update = true);
+
+protected:
+ void insertAction();
+ void removeAction();
+
+private:
+ QWidget *m_parentWidget;
+ QAction *m_action;
+ QAction *m_beforeAction;
+ bool m_update;
+};
+
+class QDESIGNER_SHARED_EXPORT InsertActionIntoCommand : public ActionInsertionCommand
+{
+
+public:
+ explicit InsertActionIntoCommand(QDesignerFormWindowInterface *formWindow);
+
+ virtual void redo() { insertAction(); }
+ virtual void undo() { removeAction(); }
+};
+
+class QDESIGNER_SHARED_EXPORT RemoveActionFromCommand : public ActionInsertionCommand
+{
+
+public:
+ explicit RemoveActionFromCommand(QDesignerFormWindowInterface *formWindow);
+
+ virtual void redo() { removeAction(); }
+ virtual void undo() { insertAction(); }
+};
+
+class QDESIGNER_SHARED_EXPORT MenuActionCommand : public QDesignerFormWindowCommand
+{
+public:
+ void init(QAction *action, QAction *actionBefore, QWidget *associatedWidget, QWidget *objectToSelect);
+
+protected:
+ MenuActionCommand(const QString &text, QDesignerFormWindowInterface *formWindow);
+ void insertMenu();
+ void removeMenu();
+
+private:
+ QAction *m_action;
+ QAction *m_actionBefore;
+ QWidget *m_menuParent;
+ QWidget *m_associatedWidget;
+ QWidget *m_objectToSelect;
+};
+
+class QDESIGNER_SHARED_EXPORT AddMenuActionCommand : public MenuActionCommand
+{
+
+public:
+ explicit AddMenuActionCommand(QDesignerFormWindowInterface *formWindow);
+
+ virtual void redo() { insertMenu(); }
+ virtual void undo() { removeMenu(); }
+};
+
+class QDESIGNER_SHARED_EXPORT RemoveMenuActionCommand : public MenuActionCommand
+{
+
+public:
+ explicit RemoveMenuActionCommand(QDesignerFormWindowInterface *formWindow);
+
+ virtual void redo() { removeMenu(); }
+ virtual void undo() { insertMenu(); }
+};
+
+class QDESIGNER_SHARED_EXPORT CreateSubmenuCommand : public QDesignerFormWindowCommand
+{
+
+public:
+ explicit CreateSubmenuCommand(QDesignerFormWindowInterface *formWindow);
+ void init(QDesignerMenu *menu, QAction *action, QObject *m_objectToSelect = 0);
+ virtual void redo();
+ virtual void undo();
+private:
+ QAction *m_action;
+ QDesignerMenu *m_menu;
+ QObject *m_objectToSelect;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_COMMAND_H
diff --git a/src/designer/src/lib/shared/qdesigner_dnditem.cpp b/src/designer/src/lib/shared/qdesigner_dnditem.cpp
new file mode 100644
index 000000000..83218026a
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_dnditem.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_dnditem_p.h"
+#include "formwindowbase_p.h"
+#include "ui4_p.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QBitmap>
+#include <QtGui/QPixmap>
+#include <QtGui/QImage>
+#include <QtGui/QLabel>
+#include <QtGui/QDrag>
+#include <QtGui/QCursor>
+#include <QtGui/QDropEvent>
+#include <QtGui/QRgb>
+
+#include <QtCore/QMultiMap>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QDesignerDnDItem::QDesignerDnDItem(DropType type, QWidget *source) :
+ m_source(source),
+ m_type(type),
+ m_dom_ui(0),
+ m_widget(0),
+ m_decoration(0)
+{
+}
+
+void QDesignerDnDItem::init(DomUI *ui, QWidget *widget, QWidget *decoration,
+ const QPoint &global_mouse_pos)
+{
+ Q_ASSERT(widget != 0 || ui != 0);
+ Q_ASSERT(decoration != 0);
+
+ m_dom_ui = ui;
+ m_widget = widget;
+ m_decoration = decoration;
+
+ const QRect geometry = m_decoration->geometry();
+ m_hot_spot = global_mouse_pos - m_decoration->geometry().topLeft();
+}
+
+QDesignerDnDItem::~QDesignerDnDItem()
+{
+ if (m_decoration != 0)
+ m_decoration->deleteLater();
+ delete m_dom_ui;
+}
+
+DomUI *QDesignerDnDItem::domUi() const
+{
+ return m_dom_ui;
+}
+
+QWidget *QDesignerDnDItem::decoration() const
+{
+ return m_decoration;
+}
+
+QPoint QDesignerDnDItem::hotSpot() const
+{
+ return m_hot_spot;
+}
+
+QWidget *QDesignerDnDItem::widget() const
+{
+ return m_widget;
+}
+
+QDesignerDnDItem::DropType QDesignerDnDItem::type() const
+{
+ return m_type;
+}
+
+QWidget *QDesignerDnDItem::source() const
+{
+ return m_source;
+}
+
+void QDesignerDnDItem::setDomUi(DomUI *dom_ui)
+{
+ delete m_dom_ui;
+ m_dom_ui = dom_ui;
+}
+
+// ---------- QDesignerMimeData
+
+// Make pixmap transparent on Windows only. Mac is transparent by default, Unix usually does not work.
+#ifdef Q_WS_WIN
+# define TRANSPARENT_DRAG_PIXMAP
+#endif
+
+QDesignerMimeData::QDesignerMimeData(const QDesignerDnDItems &items, QDrag *drag) :
+ m_items(items)
+{
+ enum { Alpha = 200 };
+ QPoint decorationTopLeft;
+ switch (m_items.size()) {
+ case 0:
+ break;
+ case 1: {
+ QWidget *deco = m_items.first()->decoration();
+ decorationTopLeft = deco->pos();
+ const QPixmap widgetPixmap = QPixmap::grabWidget(deco);
+#ifdef TRANSPARENT_DRAG_PIXMAP
+ QImage image(widgetPixmap.size(), QImage::Format_ARGB32);
+ image.fill(QColor(Qt::transparent).rgba());
+ QPainter painter(&image);
+ painter.drawPixmap(QPoint(0, 0), widgetPixmap);
+ painter.end();
+ setImageTransparency(image, Alpha);
+ drag->setPixmap(QPixmap::fromImage(image));
+#else
+ drag->setPixmap(widgetPixmap);
+#endif
+ }
+ break;
+ default: {
+ // determine size of drag decoration by uniting all geometries
+ const QDesignerDnDItems::const_iterator cend = m_items.constEnd();
+ QDesignerDnDItems::const_iterator it =m_items.constBegin();
+ QRect unitedGeometry = (*it)->decoration()->geometry();
+ for (++it; it != cend; ++it )
+ unitedGeometry = unitedGeometry .united((*it)->decoration()->geometry());
+
+ // paint with offset. At the same time, create a mask bitmap, containing widget rectangles.
+ QImage image(unitedGeometry.size(), QImage::Format_ARGB32);
+ image.fill(QColor(Qt::transparent).rgba());
+ QBitmap mask(unitedGeometry.size());
+ mask.clear();
+ // paint with offset, determine action
+ QPainter painter(&image);
+ QPainter maskPainter(&mask);
+ decorationTopLeft = unitedGeometry.topLeft();
+ for (it = m_items.constBegin() ; it != cend; ++it ) {
+ QWidget *w = (*it)->decoration();
+ const QPixmap wp = QPixmap::grabWidget(w);
+ const QPoint pos = w->pos() - decorationTopLeft;
+ painter.drawPixmap(pos, wp);
+ maskPainter.fillRect(QRect(pos, wp.size()), Qt::color1);
+ }
+ painter.end();
+ maskPainter.end();
+#ifdef TRANSPARENT_DRAG_PIXMAP
+ setImageTransparency(image, Alpha);
+#endif
+ QPixmap pixmap = QPixmap::fromImage(image);
+ pixmap.setMask(mask);
+ drag->setPixmap(pixmap);
+ }
+ break;
+ }
+ // determine hot spot and reconstruct the exact starting position as form window
+ // introduces some offset when detecting DnD
+ m_globalStartPos = m_items.first()->decoration()->pos() + m_items.first()->hotSpot();
+ m_hotSpot = m_globalStartPos - decorationTopLeft;
+ drag->setHotSpot(m_hotSpot);
+
+ drag->setMimeData(this);
+}
+
+QDesignerMimeData::~QDesignerMimeData()
+{
+ const QDesignerDnDItems::const_iterator cend = m_items.constEnd();
+ for (QDesignerDnDItems::const_iterator it = m_items.constBegin(); it != cend; ++it )
+ delete *it;
+}
+
+Qt::DropAction QDesignerMimeData::proposedDropAction() const
+{
+ return m_items.first()->type() == QDesignerDnDItemInterface::CopyDrop ? Qt::CopyAction : Qt::MoveAction;
+}
+
+Qt::DropAction QDesignerMimeData::execDrag(const QDesignerDnDItems &items, QWidget * dragSource)
+{
+ if (items.empty())
+ return Qt::IgnoreAction;
+
+ QDrag *drag = new QDrag(dragSource);
+ QDesignerMimeData *mimeData = new QDesignerMimeData(items, drag);
+
+ // Store pointers to widgets that are to be re-shown if a move operation is canceled
+ QWidgetList reshowWidgets;
+ const QDesignerDnDItems::const_iterator cend = items.constEnd();
+ for (QDesignerDnDItems::const_iterator it = items.constBegin(); it != cend; ++it )
+ if (QWidget *w = (*it)->widget())
+ if ((*it)->type() == QDesignerDnDItemInterface::MoveDrop)
+ reshowWidgets.push_back(w);
+
+ const Qt::DropAction executedAction = drag->exec(Qt::CopyAction|Qt::MoveAction, mimeData->proposedDropAction());
+
+ if (executedAction == Qt::IgnoreAction && !reshowWidgets.empty())
+ foreach (QWidget *w, reshowWidgets)
+ w->show();
+
+ return executedAction;
+}
+
+
+void QDesignerMimeData::moveDecoration(const QPoint &globalPos) const
+{
+ const QPoint relativeDistance = globalPos - m_globalStartPos;
+ const QDesignerDnDItems::const_iterator cend = m_items.constEnd();
+ for (QDesignerDnDItems::const_iterator it =m_items.constBegin(); it != cend; ++it ) {
+ QWidget *w = (*it)->decoration();
+ w->move(w->pos() + relativeDistance);
+ }
+}
+
+void QDesignerMimeData::removeMovedWidgetsFromSourceForm(const QDesignerDnDItems &items)
+{
+ typedef QMultiMap<FormWindowBase *, QWidget *> FormWidgetMap;
+ FormWidgetMap formWidgetMap;
+ // Find moved widgets per form
+ const QDesignerDnDItems::const_iterator cend = items.constEnd();
+ for (QDesignerDnDItems::const_iterator it = items.constBegin(); it != cend; ++it )
+ if ((*it)->type() == QDesignerDnDItemInterface::MoveDrop)
+ if (QWidget *w = (*it)->widget())
+ if (FormWindowBase *fb = qobject_cast<FormWindowBase *>((*it)->source()))
+ formWidgetMap.insert(fb, w);
+ if (formWidgetMap.empty())
+ return;
+
+ foreach (FormWindowBase * fb, formWidgetMap.keys())
+ fb->deleteWidgetList(formWidgetMap.values(fb));
+}
+
+void QDesignerMimeData::acceptEventWithAction(Qt::DropAction desiredAction, QDropEvent *e)
+{
+ if (e->proposedAction() == desiredAction) {
+ e->acceptProposedAction();
+ } else {
+ e->setDropAction(desiredAction);
+ e->accept();
+ }
+}
+
+void QDesignerMimeData::acceptEvent(QDropEvent *e) const
+{
+ acceptEventWithAction(proposedDropAction(), e);
+}
+
+void QDesignerMimeData::setImageTransparency(QImage &image, int alpha)
+{
+ const int height = image.height();
+ for (int l = 0; l < height; l++) {
+ QRgb *line = reinterpret_cast<QRgb *>(image.scanLine(l));
+ QRgb *lineEnd = line + image.width();
+ for ( ; line < lineEnd; line++) {
+ const QRgb rgba = *line;
+ *line = qRgba(qRed(rgba), qGreen(rgba), qBlue(rgba), alpha);
+ }
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_dnditem_p.h b/src/designer/src/lib/shared/qdesigner_dnditem_p.h
new file mode 100644
index 000000000..8c9d2e672
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_dnditem_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_DNDITEM_H
+#define QDESIGNER_DNDITEM_H
+
+#include "shared_global_p.h"
+#include <QtDesigner/abstractdnditem.h>
+
+#include <QtCore/QPoint>
+#include <QtCore/QList>
+#include <QtCore/QMimeData>
+
+QT_BEGIN_NAMESPACE
+
+class QDrag;
+class QImage;
+class QDropEvent;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT QDesignerDnDItem: public QDesignerDnDItemInterface
+{
+public:
+ explicit QDesignerDnDItem(DropType type, QWidget *source = 0);
+ virtual ~QDesignerDnDItem();
+
+ virtual DomUI *domUi() const;
+ virtual QWidget *decoration() const;
+ virtual QWidget *widget() const;
+ virtual QPoint hotSpot() const;
+ virtual QWidget *source() const;
+
+ virtual DropType type() const;
+
+protected:
+ void setDomUi(DomUI *dom_ui);
+ void init(DomUI *ui, QWidget *widget, QWidget *decoration, const QPoint &global_mouse_pos);
+
+private:
+ QWidget *m_source;
+ const DropType m_type;
+ const QPoint m_globalStartPos;
+ DomUI *m_dom_ui;
+ QWidget *m_widget;
+ QWidget *m_decoration;
+ QPoint m_hot_spot;
+
+ Q_DISABLE_COPY(QDesignerDnDItem)
+};
+
+// Mime data for use with designer drag and drop operations.
+
+class QDESIGNER_SHARED_EXPORT QDesignerMimeData : public QMimeData {
+ Q_OBJECT
+
+public:
+ typedef QList<QDesignerDnDItemInterface *> QDesignerDnDItems;
+
+ virtual ~QDesignerMimeData();
+
+ const QDesignerDnDItems &items() const { return m_items; }
+
+ // Execute a drag and drop operation.
+ static Qt::DropAction execDrag(const QDesignerDnDItems &items, QWidget * dragSource);
+
+ QPoint hotSpot() const { return m_hotSpot; }
+
+ // Move the decoration. Required for drops over form windows as the position
+ // is derived from the decoration position.
+ void moveDecoration(const QPoint &globalPos) const;
+
+ // For a move operation, create the undo command sequence to remove
+ // the widgets from the source form.
+ static void removeMovedWidgetsFromSourceForm(const QDesignerDnDItems &items);
+
+ // Accept an event with the proper action.
+ void acceptEvent(QDropEvent *e) const;
+
+ // Helper to accept an event with the desired action.
+ static void acceptEventWithAction(Qt::DropAction desiredAction, QDropEvent *e);
+
+private:
+ QDesignerMimeData(const QDesignerDnDItems &items, QDrag *drag);
+ Qt::DropAction proposedDropAction() const;
+
+ static void setImageTransparency(QImage &image, int alpha);
+
+ const QDesignerDnDItems m_items;
+ QPoint m_globalStartPos;
+ QPoint m_hotSpot;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_DNDITEM_H
diff --git a/src/designer/src/lib/shared/qdesigner_dockwidget.cpp b/src/designer/src/lib/shared/qdesigner_dockwidget.cpp
new file mode 100644
index 000000000..8aad4579c
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_dockwidget.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_dockwidget_p.h"
+#include "layoutinfo_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+
+#include <QtGui/QMainWindow>
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+QDesignerDockWidget::QDesignerDockWidget(QWidget *parent)
+ : QDockWidget(parent)
+{
+}
+
+QDesignerDockWidget::~QDesignerDockWidget()
+{
+}
+
+bool QDesignerDockWidget::docked() const
+{
+ return qobject_cast<QMainWindow*>(parentWidget()) != 0;
+}
+
+void QDesignerDockWidget::setDocked(bool b)
+{
+ if (QMainWindow *mainWindow = findMainWindow()) {
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerContainerExtension *c;
+ c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), mainWindow);
+ if (b && !docked()) {
+ // Dock it
+ // ### undo/redo stack
+ setParent(0);
+ c->addWidget(this);
+ formWindow()->selectWidget(this, formWindow()->cursor()->isWidgetSelected(this));
+ } else if (!b && docked()) {
+ // Undock it
+ for (int i = 0; i < c->count(); ++i) {
+ if (c->widget(i) == this) {
+ c->remove(i);
+ break;
+ }
+ }
+ // #### restore the position
+ setParent(mainWindow->centralWidget());
+ show();
+ formWindow()->selectWidget(this, formWindow()->cursor()->isWidgetSelected(this));
+ }
+ }
+}
+
+Qt::DockWidgetArea QDesignerDockWidget::dockWidgetArea() const
+{
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(parentWidget()))
+ return mainWindow->dockWidgetArea(const_cast<QDesignerDockWidget*>(this));
+
+ return Qt::LeftDockWidgetArea;
+}
+
+void QDesignerDockWidget::setDockWidgetArea(Qt::DockWidgetArea dockWidgetArea)
+{
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(parentWidget())) {
+ if ((dockWidgetArea != Qt::NoDockWidgetArea)
+ && isAreaAllowed(dockWidgetArea)) {
+ mainWindow->addDockWidget(dockWidgetArea, this);
+ }
+ }
+}
+
+bool QDesignerDockWidget::inMainWindow() const
+{
+ QMainWindow *mw = findMainWindow();
+ if (mw && !mw->centralWidget()->layout()) {
+ if (mw == parentWidget())
+ return true;
+ if (mw->centralWidget() == parentWidget())
+ return true;
+ }
+ return false;
+}
+
+QDesignerFormWindowInterface *QDesignerDockWidget::formWindow() const
+{
+ return QDesignerFormWindowInterface::findFormWindow(const_cast<QDesignerDockWidget*>(this));
+}
+
+QMainWindow *QDesignerDockWidget::findMainWindow() const
+{
+ if (QDesignerFormWindowInterface *fw = formWindow())
+ return qobject_cast<QMainWindow*>(fw->mainContainer());
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_dockwidget_p.h b/src/designer/src/lib/shared/qdesigner_dockwidget_p.h
new file mode 100644
index 000000000..106ed1fb6
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_dockwidget_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_DOCKWIDGET_H
+#define QDESIGNER_DOCKWIDGET_H
+
+#include "shared_global_p.h"
+#include <QtGui/QDockWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+class QDESIGNER_SHARED_EXPORT QDesignerDockWidget: public QDockWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::DockWidgetArea dockWidgetArea READ dockWidgetArea WRITE setDockWidgetArea DESIGNABLE docked STORED false)
+ Q_PROPERTY(bool docked READ docked WRITE setDocked DESIGNABLE inMainWindow STORED false)
+public:
+ QDesignerDockWidget(QWidget *parent = 0);
+ virtual ~QDesignerDockWidget();
+
+ bool docked() const;
+ void setDocked(bool b);
+
+ Qt::DockWidgetArea dockWidgetArea() const;
+ void setDockWidgetArea(Qt::DockWidgetArea dockWidgetArea);
+
+ bool inMainWindow() const;
+
+private:
+ QDesignerFormWindowInterface *formWindow() const;
+ QMainWindow *findMainWindow() const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_DOCKWIDGET_H
diff --git a/src/designer/src/lib/shared/qdesigner_formbuilder.cpp b/src/designer/src/lib/shared/qdesigner_formbuilder.cpp
new file mode 100644
index 000000000..a8054748b
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_formbuilder.cpp
@@ -0,0 +1,498 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_formbuilder_p.h"
+#include "dynamicpropertysheet.h"
+#include "qsimpleresource_p.h"
+#include "widgetfactory_p.h"
+#include "qdesigner_introspection_p.h"
+
+#include <ui4_p.h>
+#include <formbuilderextra_p.h>
+// sdk
+#include <QtDesigner/container.h>
+#include <QtDesigner/customwidget.h>
+#include <QtDesigner/propertysheet.h>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+#include <abstractdialoggui_p.h>
+
+// shared
+#include <qdesigner_propertysheet_p.h>
+#include <qdesigner_utils_p.h>
+#include <formwindowbase_p.h>
+#include <qtresourcemodel_p.h>
+#include <scripterrordialog_p.h>
+
+#include <QtGui/QWidget>
+#include <QtGui/QMenu>
+#include <QtGui/QToolBar>
+#include <QtGui/QMenuBar>
+#include <QtGui/QMainWindow>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QStyle>
+#include <QtGui/QApplication>
+#include <QtGui/QAbstractScrollArea>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPixmap>
+
+#include <QtCore/QBuffer>
+#include <QtCore/qdebug.h>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_FORMBUILDER_NO_SCRIPT
+static QString summarizeScriptErrors(const QFormScriptRunner::Errors &errors)
+{
+ QString rc = QCoreApplication::translate("QDesignerFormBuilder", "Script errors occurred:");
+ foreach (QFormScriptRunner::Error error, errors) {
+ rc += QLatin1Char('\n');
+ rc += error.errorMessage;
+ }
+ return rc;
+}
+#endif
+
+namespace qdesigner_internal {
+
+QDesignerFormBuilder::QDesignerFormBuilder(QDesignerFormEditorInterface *core,
+ Mode mode,
+ const DeviceProfile &deviceProfile) :
+ m_core(core),
+ m_mode(mode),
+ m_deviceProfile(deviceProfile),
+ m_pixmapCache(0),
+ m_iconCache(0),
+ m_ignoreCreateResources(false),
+ m_tempResourceSet(0),
+ m_mainWidget(true)
+{
+ Q_ASSERT(m_core);
+#ifndef QT_FORMBUILDER_NO_SCRIPT
+ // Disable scripting in the editors.
+ QFormScriptRunner::Options options = formScriptRunner()->options();
+ switch (m_mode) {
+ case DisableScripts:
+ options |= QFormScriptRunner::DisableScripts;
+ break;
+ case EnableScripts:
+ options |= QFormScriptRunner::DisableWarnings;
+ options &= ~QFormScriptRunner::DisableScripts;
+ break;
+ }
+ formScriptRunner()-> setOptions(options);
+#endif
+}
+
+QString QDesignerFormBuilder::systemStyle() const
+{
+ return m_deviceProfile.isEmpty() ?
+ QString::fromUtf8(QApplication::style()->metaObject()->className()) :
+ m_deviceProfile.style();
+}
+
+QWidget *QDesignerFormBuilder::createWidgetFromContents(const QString &contents, QWidget *parentWidget)
+{
+ QByteArray data = contents.toUtf8();
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+ return load(&buffer, parentWidget);
+}
+
+QWidget *QDesignerFormBuilder::create(DomUI *ui, QWidget *parentWidget)
+{
+ m_mainWidget = true;
+ QtResourceSet *resourceSet = core()->resourceModel()->currentResourceSet();
+
+ // reload resource properties;
+ createResources(ui->elementResources());
+ core()->resourceModel()->setCurrentResourceSet(m_tempResourceSet);
+
+ m_ignoreCreateResources = true;
+ DesignerPixmapCache pixmapCache;
+ DesignerIconCache iconCache(&pixmapCache);
+ m_pixmapCache = &pixmapCache;
+ m_iconCache = &iconCache;
+
+ QWidget *widget = QFormBuilder::create(ui, parentWidget);
+
+ core()->resourceModel()->setCurrentResourceSet(resourceSet);
+ core()->resourceModel()->removeResourceSet(m_tempResourceSet);
+ m_tempResourceSet = 0;
+ m_ignoreCreateResources = false;
+ m_pixmapCache = 0;
+ m_iconCache = 0;
+
+ m_customWidgetsWithScript.clear();
+ return widget;
+}
+
+QWidget *QDesignerFormBuilder::createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name)
+{
+ QWidget *widget = 0;
+
+ if (widgetName == QLatin1String("QToolBar")) {
+ widget = new QToolBar(parentWidget);
+ } else if (widgetName == QLatin1String("QMenu")) {
+ widget = new QMenu(parentWidget);
+ } else if (widgetName == QLatin1String("QMenuBar")) {
+ widget = new QMenuBar(parentWidget);
+ } else {
+ widget = core()->widgetFactory()->createWidget(widgetName, parentWidget);
+ }
+
+ if (widget) {
+ widget->setObjectName(name);
+ if (QSimpleResource::hasCustomWidgetScript(m_core, widget))
+ m_customWidgetsWithScript.insert(widget);
+ }
+
+ if (m_mainWidget) { // We need to apply the DPI here to take effect on size hints, etc.
+ m_deviceProfile.apply(m_core, widget, DeviceProfile::ApplyPreview);
+ m_mainWidget = false;
+ }
+ return widget;
+}
+
+bool QDesignerFormBuilder::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
+{
+ // Use container extension or rely on scripts unless main window.
+ if (QFormBuilder::addItem(ui_widget, widget, parentWidget))
+ return true;
+
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), parentWidget)) {
+ container->addWidget(widget);
+ return true;
+ }
+ return false;
+}
+
+bool QDesignerFormBuilder::addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout)
+{
+ return QFormBuilder::addItem(ui_item, item, layout);
+}
+
+QIcon QDesignerFormBuilder::nameToIcon(const QString &filePath, const QString &qrcPath)
+{
+ Q_UNUSED(filePath)
+ Q_UNUSED(qrcPath)
+ qWarning() << "QDesignerFormBuilder::nameToIcon() is obsoleted";
+ return QIcon();
+}
+
+QPixmap QDesignerFormBuilder::nameToPixmap(const QString &filePath, const QString &qrcPath)
+{
+ Q_UNUSED(filePath)
+ Q_UNUSED(qrcPath)
+ qWarning() << "QDesignerFormBuilder::nameToPixmap() is obsoleted";
+ return QPixmap();
+}
+
+/* If the property is a enum or flag value, retrieve
+ * the existing enum/flag type via property sheet and use it to convert */
+
+static bool readDomEnumerationValue(const DomProperty *p,
+ const QDesignerPropertySheetExtension* sheet,
+ QVariant &v)
+{
+ switch (p->kind()) {
+ case DomProperty::Set: {
+ const int index = sheet->indexOf(p->attributeName());
+ if (index == -1)
+ return false;
+ const QVariant sheetValue = sheet->property(index);
+ if (sheetValue.canConvert<PropertySheetFlagValue>()) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(sheetValue);
+ bool ok = false;
+ v = f.metaFlags.parseFlags(p->elementSet(), &ok);
+ if (!ok)
+ designerWarning(f.metaFlags.messageParseFailed(p->elementSet()));
+ return true;
+ }
+ }
+ break;
+ case DomProperty::Enum: {
+ const int index = sheet->indexOf(p->attributeName());
+ if (index == -1)
+ return false;
+ const QVariant sheetValue = sheet->property(index);
+ if (sheetValue.canConvert<PropertySheetEnumValue>()) {
+ const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(sheetValue);
+ bool ok = false;
+ v = e.metaEnum.parseEnum(p->elementEnum(), &ok);
+ if (!ok)
+ designerWarning(e.metaEnum.messageParseFailed(p->elementEnum()));
+ return true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void QDesignerFormBuilder::applyProperties(QObject *o, const QList<DomProperty*> &properties)
+{
+ typedef QList<DomProperty*> DomPropertyList;
+
+ if (properties.empty())
+ return;
+
+ QFormBuilderExtra *formBuilderExtra = QFormBuilderExtra::instance(this);
+ const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), o);
+ const QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), o);
+ const bool changingMetaObject = WidgetFactory::classNameOf(core(), o) == QLatin1String("QAxWidget");
+ const QDesignerMetaObjectInterface *meta = core()->introspection()->metaObject(o);
+ const bool dynamicPropertiesAllowed = dynamicSheet && dynamicSheet->dynamicPropertiesAllowed();
+
+ QDesignerPropertySheet *designerPropertySheet = qobject_cast<QDesignerPropertySheet *>(
+ core()->extensionManager()->extension(o, Q_TYPEID(QDesignerPropertySheetExtension)));
+
+ if (designerPropertySheet) {
+ if (designerPropertySheet->pixmapCache())
+ designerPropertySheet->setPixmapCache(m_pixmapCache);
+ if (designerPropertySheet->iconCache())
+ designerPropertySheet->setIconCache(m_iconCache);
+ }
+
+ const DomPropertyList::const_iterator cend = properties.constEnd();
+ for (DomPropertyList::const_iterator it = properties.constBegin(); it != cend; ++it) {
+ DomProperty *p = *it;
+ QVariant v;
+ if (!readDomEnumerationValue(p, sheet, v))
+ v = toVariant(o->metaObject(), p);
+
+ if (v.isNull())
+ continue;
+
+ const QString attributeName = p->attributeName();
+ if (formBuilderExtra->applyPropertyInternally(o, attributeName, v))
+ continue;
+
+ // refuse fake properties like current tab name (weak test)
+ if (!dynamicPropertiesAllowed) {
+ if (changingMetaObject) // Changes after setting control of QAxWidget
+ meta = core()->introspection()->metaObject(o);
+ if (meta->indexOfProperty(attributeName) == -1)
+ continue;
+ }
+
+ QObject *obj = o;
+ QAbstractScrollArea *scroll = qobject_cast<QAbstractScrollArea *>(o);
+ if (scroll && attributeName == QLatin1String("cursor") && scroll->viewport())
+ obj = scroll->viewport();
+
+ // a real property
+ obj->setProperty(attributeName.toUtf8(), v);
+ }
+}
+
+DomWidget *QDesignerFormBuilder::createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive)
+{
+ DomWidget *ui_widget = QFormBuilder::createDom(widget, ui_parentWidget, recursive);
+ QSimpleResource::addExtensionDataToDOM(this, m_core, ui_widget, widget);
+ return ui_widget;
+}
+
+QWidget *QDesignerFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget)
+{
+ QWidget *widget = QFormBuilder::create(ui_widget, parentWidget);
+ // Do not apply state if scripts are to be run in preview mode
+ QSimpleResource::applyExtensionDataFromDOM(this, m_core, ui_widget, widget, m_mode == DisableScripts);
+ return widget;
+}
+
+void QDesignerFormBuilder::createResources(DomResources *resources)
+{
+ if (m_ignoreCreateResources)
+ return;
+ QStringList paths;
+ if (resources != 0) {
+ const QList<DomResource*> dom_include = resources->elementInclude();
+ foreach (DomResource *res, dom_include) {
+ QString path = QDir::cleanPath(workingDirectory().absoluteFilePath(res->attributeLocation()));
+ paths << path;
+ }
+ }
+
+ m_tempResourceSet = core()->resourceModel()->addResourceSet(paths);
+}
+
+QLayout *QDesignerFormBuilder::create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget)
+{
+ return QFormBuilder::create(ui_layout, layout, parentWidget);
+}
+
+void QDesignerFormBuilder::loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
+{
+ QFormBuilder::loadExtraInfo(ui_widget, widget, parentWidget);
+}
+
+QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw,
+ const QString &styleName,
+ const QString &appStyleSheet,
+ const DeviceProfile &deviceProfile,
+ ScriptErrors *scriptErrors,
+ QString *errorMessage)
+{
+ scriptErrors->clear();
+
+ // load
+ QDesignerFormBuilder builder(fw->core(), EnableScripts, deviceProfile);
+ builder.setWorkingDirectory(fw->absoluteDir());
+
+ const bool warningsEnabled = QSimpleResource::setWarningsEnabled(false);
+ QByteArray bytes = fw->contents().toUtf8();
+ QSimpleResource::setWarningsEnabled(warningsEnabled);
+
+ QBuffer buffer(&bytes);
+ buffer.open(QIODevice::ReadOnly);
+
+ QWidget *widget = builder.load(&buffer, 0);
+ if (!widget) { // Shouldn't happen
+ *errorMessage = QCoreApplication::translate("QDesignerFormBuilder", "The preview failed to build.");
+ return 0;
+ }
+ // Make sure palette is applied
+ const QString styleToUse = styleName.isEmpty() ? builder.deviceProfile().style() : styleName;
+ if (!styleToUse.isEmpty()) {
+ if (WidgetFactory *wf = qobject_cast<qdesigner_internal::WidgetFactory *>(fw->core()->widgetFactory())) {
+ if (styleToUse != wf->styleName())
+ WidgetFactory::applyStyleToTopLevel(wf->getStyle(styleToUse), widget);
+ }
+ }
+#ifndef QT_FORMBUILDER_NO_SCRIPT
+ // Check for script errors
+ *scriptErrors = builder.formScriptRunner()->errors();
+ if (!scriptErrors->empty()) {
+ *errorMessage = summarizeScriptErrors(*scriptErrors);
+ delete widget;
+ return 0;
+ }
+#endif
+ // Fake application style sheet by prepending. (If this doesn't work, fake by nesting
+ // into parent widget).
+ if (!appStyleSheet.isEmpty()) {
+ QString styleSheet = appStyleSheet;
+ styleSheet += QLatin1Char('\n');
+ styleSheet += widget->styleSheet();
+ widget->setStyleSheet(styleSheet);
+ }
+ return widget;
+}
+
+QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName)
+{
+ return createPreview(fw, styleName, QString());
+}
+
+QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw,
+ const QString &styleName,
+ const QString &appStyleSheet,
+ const DeviceProfile &deviceProfile,
+ QString *errorMessage)
+{
+ ScriptErrors scriptErrors;
+ return createPreview(fw, styleName, appStyleSheet, deviceProfile, &scriptErrors, errorMessage);
+}
+
+QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw,
+ const QString &styleName,
+ const QString &appStyleSheet,
+ QString *errorMessage)
+{
+ ScriptErrors scriptErrors;
+ return createPreview(fw, styleName, appStyleSheet, DeviceProfile(), &scriptErrors, errorMessage);
+}
+
+QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet)
+{
+ ScriptErrors scriptErrors;
+ QString errorMessage;
+ QWidget *widget = createPreview(fw, styleName, appStyleSheet, DeviceProfile(), &scriptErrors, &errorMessage);
+ if (!widget) {
+ // Display Script errors or message box
+ QWidget *dialogParent = fw->core()->topLevel();
+ if (scriptErrors.empty()) {
+ fw->core()->dialogGui()->message(dialogParent, QDesignerDialogGuiInterface::PreviewFailureMessage,
+ QMessageBox::Warning, QCoreApplication::translate("QDesignerFormBuilder", "Designer"), errorMessage, QMessageBox::Ok);
+ } else {
+ ScriptErrorDialog scriptErrorDialog(scriptErrors, dialogParent);
+ scriptErrorDialog.exec();
+ }
+ return 0;
+ }
+ return widget;
+}
+
+QPixmap QDesignerFormBuilder::createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet)
+{
+ QWidget *widget = createPreview(fw, styleName, appStyleSheet);
+ if (!widget)
+ return QPixmap();
+
+ const QPixmap rc = QPixmap::grabWidget (widget);
+ widget->deleteLater();
+ return rc;
+}
+
+// ---------- NewFormWidgetFormBuilder
+
+NewFormWidgetFormBuilder::NewFormWidgetFormBuilder(QDesignerFormEditorInterface *core,
+ Mode mode,
+ const DeviceProfile &deviceProfile) :
+ QDesignerFormBuilder(core, mode, deviceProfile)
+{
+}
+
+void NewFormWidgetFormBuilder::createCustomWidgets(DomCustomWidgets *dc)
+{
+ QSimpleResource::handleDomCustomWidgets(core(), dc);
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_formbuilder_p.h b/src/designer/src/lib/shared/qdesigner_formbuilder_p.h
new file mode 100644
index 000000000..2f902e394
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_formbuilder_p.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_FORMBUILDER_H
+#define QDESIGNER_FORMBUILDER_H
+
+#include "shared_global_p.h"
+#include "deviceprofile_p.h"
+
+#include <QtDesigner/private/formscriptrunner_p.h>
+#include <QtDesigner/formbuilder.h>
+
+#include <QtCore/QMap>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+
+class QPixmap;
+class QtResourceSet;
+
+namespace qdesigner_internal {
+
+class DesignerPixmapCache;
+class DesignerIconCache;
+
+/* Form builder used for previewing forms and widget box.
+ * It applies the system settings to its toplevel window. */
+
+class QDESIGNER_SHARED_EXPORT QDesignerFormBuilder: public QFormBuilder
+{
+public:
+ enum Mode {
+ DisableScripts,
+ EnableScripts
+ };
+
+ QDesignerFormBuilder(QDesignerFormEditorInterface *core,
+ Mode mode,
+ const DeviceProfile &deviceProfile = DeviceProfile());
+
+ QWidget *createWidgetFromContents(const QString &contents, QWidget *parentWidget = 0);
+
+ virtual QWidget *createWidget(DomWidget *ui_widget, QWidget *parentWidget = 0)
+ { return QFormBuilder::create(ui_widget, parentWidget); }
+
+ inline QDesignerFormEditorInterface *core() const
+ { return m_core; }
+
+ QString systemStyle() const;
+
+ typedef QFormScriptRunner::Errors ScriptErrors;
+ // Create a preview widget (for integrations) or return 0. The widget has to be embedded into a main window.
+ // Experimental, depending on script support.
+ static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName /* ="" */,
+ const QString &appStyleSheet /* ="" */,
+ const DeviceProfile &deviceProfile,
+ ScriptErrors *scriptErrors, QString *errorMessage);
+ // Convenience that pops up message boxes in case of failures.
+ static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName = QString());
+ // Create a preview widget (for integrations) or return 0. The widget has to be embedded into a main window.
+ static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet, QString *errorMessage);
+ static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet, const DeviceProfile &deviceProfile, QString *errorMessage);
+ // Convenience that pops up message boxes in case of failures.
+ static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet);
+
+ // Create a preview image
+ static QPixmap createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &styleName = QString(), const QString &appStyleSheet = QString());
+
+protected:
+ using QFormBuilder::createDom;
+ using QFormBuilder::create;
+
+ virtual QWidget *create(DomUI *ui, QWidget *parentWidget);
+ virtual DomWidget *createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive = true);
+ virtual QWidget *create(DomWidget *ui_widget, QWidget *parentWidget);
+ virtual QLayout *create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget);
+ virtual void createResources(DomResources *resources);
+
+ virtual QWidget *createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name);
+ virtual bool addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
+ virtual bool addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout);
+
+ virtual QIcon nameToIcon(const QString &filePath, const QString &qrcPath);
+ virtual QPixmap nameToPixmap(const QString &filePath, const QString &qrcPath);
+
+ virtual void applyProperties(QObject *o, const QList<DomProperty*> &properties);
+
+ virtual void loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
+
+ QtResourceSet *internalResourceSet() const { return m_tempResourceSet; }
+
+ DeviceProfile deviceProfile() const { return m_deviceProfile; }
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ const Mode m_mode;
+
+ typedef QSet<QWidget *> WidgetSet;
+ WidgetSet m_customWidgetsWithScript;
+
+ const DeviceProfile m_deviceProfile;
+
+ DesignerPixmapCache *m_pixmapCache;
+ DesignerIconCache *m_iconCache;
+ bool m_ignoreCreateResources;
+ QtResourceSet *m_tempResourceSet;
+ bool m_mainWidget;
+};
+
+// Form builder for a new form widget (preview). To allow for promoted
+// widgets in the template, it implements the handling of custom widgets
+// (adding of them to the widget database).
+
+class QDESIGNER_SHARED_EXPORT NewFormWidgetFormBuilder: public QDesignerFormBuilder {
+public:
+ NewFormWidgetFormBuilder(QDesignerFormEditorInterface *core,
+ Mode mode,
+ const DeviceProfile &deviceProfile = DeviceProfile());
+
+protected:
+ virtual void createCustomWidgets(DomCustomWidgets *);
+};
+
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_FORMBUILDER_H
diff --git a/src/designer/src/lib/shared/qdesigner_formeditorcommand.cpp b/src/designer/src/lib/shared/qdesigner_formeditorcommand.cpp
new file mode 100644
index 000000000..bff14ac5b
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_formeditorcommand.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qdesigner_formeditorcommand_p.h"
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ---- QDesignerFormEditorCommand ----
+QDesignerFormEditorCommand::QDesignerFormEditorCommand(const QString &description, QDesignerFormEditorInterface *core)
+ : QUndoCommand(description),
+ m_core(core)
+{
+}
+
+QDesignerFormEditorInterface *QDesignerFormEditorCommand::core() const
+{
+ return m_core;
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_formeditorcommand_p.h b/src/designer/src/lib/shared/qdesigner_formeditorcommand_p.h
new file mode 100644
index 000000000..7b88be9e6
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_formeditorcommand_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_FORMEDITORCOMMAND_H
+#define QDESIGNER_FORMEDITORCOMMAND_H
+
+#include "shared_global_p.h"
+#include <QtCore/QPointer>
+#include <QtGui/QUndoCommand>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT QDesignerFormEditorCommand: public QUndoCommand
+{
+
+public:
+ QDesignerFormEditorCommand(const QString &description, QDesignerFormEditorInterface *core);
+
+protected:
+ QDesignerFormEditorInterface *core() const;
+
+private:
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_FORMEDITORCOMMAND_H
diff --git a/src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp b/src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp
new file mode 100644
index 000000000..3efc82994
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_formwindowcommand.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qdesigner_formwindowcommand_p.h"
+#include "qdesigner_objectinspector_p.h"
+#include "layout_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtDesigner/QDesignerActionEditorInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+#include <QtGui/QLabel>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ---- QDesignerFormWindowCommand ----
+QDesignerFormWindowCommand::QDesignerFormWindowCommand(const QString &description,
+ QDesignerFormWindowInterface *formWindow,
+ QUndoCommand *parent)
+ : QUndoCommand(description, parent),
+ m_formWindow(formWindow)
+{
+}
+
+QDesignerFormWindowInterface *QDesignerFormWindowCommand::formWindow() const
+{
+ return m_formWindow;
+}
+
+QDesignerFormEditorInterface *QDesignerFormWindowCommand::core() const
+{
+ if (QDesignerFormWindowInterface *fw = formWindow())
+ return fw->core();
+
+ return 0;
+}
+
+void QDesignerFormWindowCommand::undo()
+{
+ cheapUpdate();
+}
+
+void QDesignerFormWindowCommand::redo()
+{
+ cheapUpdate();
+}
+
+void QDesignerFormWindowCommand::cheapUpdate()
+{
+ if (core()->objectInspector())
+ core()->objectInspector()->setFormWindow(formWindow());
+
+ if (core()->actionEditor())
+ core()->actionEditor()->setFormWindow(formWindow());
+}
+
+QDesignerPropertySheetExtension* QDesignerFormWindowCommand::propertySheet(QObject *object) const
+{
+ return qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), object);
+}
+
+void QDesignerFormWindowCommand::updateBuddies(QDesignerFormWindowInterface *form,
+ const QString &old_name,
+ const QString &new_name)
+{
+ QExtensionManager* extensionManager = form->core()->extensionManager();
+
+ typedef QList<QLabel*> LabelList;
+
+ const LabelList label_list = form->findChildren<QLabel*>();
+ if (label_list.empty())
+ return;
+
+ const QString buddyProperty = QLatin1String("buddy");
+ const QByteArray oldNameU8 = old_name.toUtf8();
+ const QByteArray newNameU8 = new_name.toUtf8();
+
+ const LabelList::const_iterator cend = label_list.constEnd();
+ for (LabelList::const_iterator it = label_list.constBegin(); it != cend; ++it ) {
+ if (QDesignerPropertySheetExtension* sheet = qt_extension<QDesignerPropertySheetExtension*>(extensionManager, *it)) {
+ const int idx = sheet->indexOf(buddyProperty);
+ if (idx != -1) {
+ const QByteArray oldBuddy = sheet->property(idx).toByteArray();
+ if (oldBuddy == oldNameU8)
+ sheet->setProperty(idx, newNameU8);
+ }
+ }
+ }
+}
+
+void QDesignerFormWindowCommand::selectUnmanagedObject(QObject *unmanagedObject)
+{
+ // Keep selection in sync
+ if (QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector())) {
+ oi->clearSelection();
+ oi->selectObject(unmanagedObject);
+ }
+ core()->propertyEditor()->setObject(unmanagedObject);
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_formwindowcommand_p.h b/src/designer/src/lib/shared/qdesigner_formwindowcommand_p.h
new file mode 100644
index 000000000..7c98559e3
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_formwindowcommand_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_FORMWINDOWCOMMAND_H
+#define QDESIGNER_FORMWINDOWCOMMAND_H
+
+#include "shared_global_p.h"
+
+#include <QtCore/QPointer>
+#include <QtGui/QUndoCommand>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QDesignerPropertySheetExtension;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT QDesignerFormWindowCommand: public QUndoCommand
+{
+
+public:
+ QDesignerFormWindowCommand(const QString &description,
+ QDesignerFormWindowInterface *formWindow,
+ QUndoCommand *parent = 0);
+
+ virtual void undo();
+ virtual void redo();
+
+ static void updateBuddies(QDesignerFormWindowInterface *form,
+ const QString &old_name, const QString &new_name);
+protected:
+ QDesignerFormWindowInterface *formWindow() const;
+ QDesignerFormEditorInterface *core() const;
+ QDesignerPropertySheetExtension* propertySheet(QObject *object) const;
+
+ void cheapUpdate();
+
+ void selectUnmanagedObject(QObject *unmanagedObject);
+private:
+ QPointer<QDesignerFormWindowInterface> m_formWindow;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_COMMAND_H
diff --git a/src/designer/src/lib/shared/qdesigner_formwindowmanager.cpp b/src/designer/src/lib/shared/qdesigner_formwindowmanager.cpp
new file mode 100644
index 000000000..1521e146e
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_formwindowmanager.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_formwindowmanager_p.h"
+#include "plugindialog_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+/*!
+ \class QDesignerFormWindowManager
+
+ Extends QDesignerFormWindowManagerInterface with methods to control
+ the preview and printing of forms. It provides a facade that simplifies
+ the complexity of the more general PreviewConfiguration & PreviewManager
+ interfaces.
+
+ \since 4.5
+ */
+
+
+QDesignerFormWindowManager::QDesignerFormWindowManager(QObject *parent)
+ : QDesignerFormWindowManagerInterface(parent), m_unused(0)
+{
+}
+
+QDesignerFormWindowManager::~QDesignerFormWindowManager()
+{
+}
+
+/*!
+ Allows you to intervene and control \QD's form "Preview" action. The
+ function returns the original action.
+
+ \since 4.5
+ */
+QAction *QDesignerFormWindowManager::actionDefaultPreview() const
+{
+ return 0;
+}
+
+/*!
+ Allows you to intervene and control \QD's form "Preview in" style action. The
+ function returns the original list of actions.
+
+ The method calls PreviewManager::createStyleActionGroup() internally.
+
+ \since 4.5
+ */
+QActionGroup *QDesignerFormWindowManager::actionGroupPreviewInStyle() const
+{
+ return 0;
+}
+
+/*!
+ \fn QPixmap QDesignerFormWindowManager::createPreviewPixmap(QString *errorMessage)
+
+ Creates a pixmap representing the preview of the currently active form.
+
+ The method calls PreviewManager::createPreviewPixmap() internally.
+
+ \since 4.5
+ */
+
+
+/*!
+ \fn QPixmap QDesignerFormWindowManager::closeAllPreviews()
+
+ Closes all preview windows generated by actionDefaultPreview, actionGroupPreviewInStyle
+ and the corresponding methods in PreviewManager.
+
+ \since 4.5
+ */
+
+/*!
+ \fn PreviewManager *QDesignerFormWindowManager::previewManager()
+
+ Accesses the previewmanager implementation.
+
+ \since 4.5
+ \internal
+ */
+
+/*!
+ \fn QAction *QDesignerFormWindowManager::actionShowFormWindowSettingsDialog() const;
+
+ Allows you to intervene and control \QD's form "Form Settings" action. The
+ function returns the original action.
+
+ \since 4.5
+ \internal
+ */
+
+QAction *QDesignerFormWindowManager::actionShowFormWindowSettingsDialog() const
+{
+ return 0;
+}
+
+/*!
+ \fn void QDesignerFormWindowManager::aboutPlugins()
+
+ Pops up an "About plugins" dialog.
+
+ \since 4.5
+ \internal
+ */
+
+void QDesignerFormWindowManager::aboutPlugins()
+{
+ PluginDialog dlg(core(), core()->topLevel());
+ dlg.exec();
+}
+
+/*!
+ \fn
+ void QDesignerFormWindowManager::formWindowSettingsChanged(QDesignerFormWindowInterface *fw);
+
+ This signal is emitted when the form settings dialog was shown
+ and changes have been made to the form.
+
+ \since 4.5
+ \internal
+ */
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_formwindowmanager_p.h b/src/designer/src/lib/shared/qdesigner_formwindowmanager_p.h
new file mode 100644
index 000000000..43c9149fc
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_formwindowmanager_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_FORMWINDOMANAGER_H
+#define QDESIGNER_FORMWINDOMANAGER_H
+
+#include "shared_global_p.h"
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class PreviewManager;
+
+//
+// Convenience methods to manage form previews (ultimately forwarded to PreviewManager).
+//
+class QDESIGNER_SHARED_EXPORT QDesignerFormWindowManager
+ : public QDesignerFormWindowManagerInterface
+{
+ Q_OBJECT
+public:
+ explicit QDesignerFormWindowManager(QObject *parent = 0);
+ virtual ~QDesignerFormWindowManager();
+
+ virtual QAction *actionDefaultPreview() const;
+ virtual QActionGroup *actionGroupPreviewInStyle() const;
+ virtual QAction *actionShowFormWindowSettingsDialog() const;
+
+ virtual QPixmap createPreviewPixmap(QString *errorMessage) = 0;
+
+ virtual PreviewManager *previewManager() const = 0;
+
+Q_SIGNALS:
+ void formWindowSettingsChanged(QDesignerFormWindowInterface *fw);
+
+public Q_SLOTS:
+ virtual void closeAllPreviews() = 0;
+ void aboutPlugins();
+
+private:
+ void *m_unused;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_FORMWINDOMANAGER_H
diff --git a/src/designer/src/lib/shared/qdesigner_integration.cpp b/src/designer/src/lib/shared/qdesigner_integration.cpp
new file mode 100644
index 000000000..7470bbf80
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_integration.cpp
@@ -0,0 +1,496 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_integration_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "qdesigner_propertyeditor_p.h"
+#include "qdesigner_objectinspector_p.h"
+#include "widgetdatabase_p.h"
+#include "pluginmanager_p.h"
+#include "widgetfactory_p.h"
+#include "qdesigner_widgetbox_p.h"
+#include "qtgradientmanager.h"
+#include "qtgradientutils.h"
+#include "qtresourcemodel_p.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerActionEditorInterface>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerResourceBrowserInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+
+#include <QtCore/QVariant>
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// ---------------- DesignerIntegrationPrivate
+class QDesignerIntegrationPrivate {
+public:
+ QDesignerIntegrationPrivate()
+ : m_gradientManager(0),
+ m_fileWatcherBehaviour(QDesignerIntegration::PromptAndReload),
+ m_resourceEditingEnabled(true),
+ m_slotNavigationEnabled(false)
+ {}
+
+ QString m_gradientsPath;
+ QtGradientManager *m_gradientManager;
+ QDesignerIntegration::ResourceFileWatcherBehaviour m_fileWatcherBehaviour;
+ bool m_resourceEditingEnabled;
+ bool m_slotNavigationEnabled;
+};
+
+// -------------- QDesignerIntegration
+// As of 4.4, the header will be distributed with the Eclipse plugin.
+
+QDesignerIntegration::QDesignerIntegration(QDesignerFormEditorInterface *core, QObject *parent) :
+ QDesignerIntegrationInterface(core, parent),
+ m_d(new QDesignerIntegrationPrivate)
+{
+ initialize();
+}
+
+QDesignerIntegration::~QDesignerIntegration()
+{
+ QFile f(m_d->m_gradientsPath);
+ if (f.open(QIODevice::WriteOnly)) {
+ f.write(QtGradientUtils::saveState(m_d->m_gradientManager).toUtf8());
+ f.close();
+ }
+ delete m_d;
+}
+
+void QDesignerIntegration::initialize()
+{
+ //
+ // integrate the `Form Editor component'
+ //
+
+ // Extensions
+ if (QDesignerPropertyEditor *designerPropertyEditor= qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor())) {
+ connect(designerPropertyEditor, SIGNAL(propertyValueChanged(QString,QVariant,bool)), this, SLOT(updateProperty(QString,QVariant,bool)));
+ connect(designerPropertyEditor, SIGNAL(resetProperty(QString)), this, SLOT(resetProperty(QString)));
+ connect(designerPropertyEditor, SIGNAL(addDynamicProperty(QString,QVariant)),
+ this, SLOT(addDynamicProperty(QString,QVariant)));
+ connect(designerPropertyEditor, SIGNAL(removeDynamicProperty(QString)),
+ this, SLOT(removeDynamicProperty(QString)));
+ } else {
+ connect(core()->propertyEditor(), SIGNAL(propertyChanged(QString,QVariant)),
+ this, SLOT(updatePropertyPrivate(QString,QVariant)));
+ }
+
+ connect(core()->formWindowManager(), SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)),
+ this, SLOT(setupFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core()->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(updateActiveFormWindow(QDesignerFormWindowInterface*)));
+
+ m_d->m_gradientManager = new QtGradientManager(this);
+ core()->setGradientManager(m_d->m_gradientManager);
+
+ QString designerFolder = QDir::homePath();
+ designerFolder += QDir::separator();
+ designerFolder += QLatin1String(".designer");
+ m_d->m_gradientsPath = designerFolder;
+ m_d->m_gradientsPath += QDir::separator();
+ m_d->m_gradientsPath += QLatin1String("gradients.xml");
+
+ QFile f(m_d->m_gradientsPath);
+ if (f.open(QIODevice::ReadOnly)) {
+ QtGradientUtils::restoreState(m_d->m_gradientManager, QString::fromAscii(f.readAll()));
+ f.close();
+ } else {
+ QFile defaultGradients(QLatin1String(":/trolltech/designer/defaultgradients.xml"));
+ if (defaultGradients.open(QIODevice::ReadOnly)) {
+ QtGradientUtils::restoreState(m_d->m_gradientManager, QString::fromAscii(defaultGradients.readAll()));
+ defaultGradients.close();
+ }
+ }
+
+ if (WidgetDataBase *widgetDataBase = qobject_cast<WidgetDataBase*>(core()->widgetDataBase()))
+ widgetDataBase->grabStandardWidgetBoxIcons();
+}
+
+void QDesignerIntegration::updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling)
+{
+ QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
+ if (!formWindow)
+ return;
+
+ Selection selection;
+ getSelection(selection);
+ if (selection.empty())
+ return;
+
+ SetPropertyCommand *cmd = new SetPropertyCommand(formWindow);
+ // find a reference object to compare to and to find the right group
+ if (cmd->init(selection.selection(), name, value, propertyEditorObject(), enableSubPropertyHandling)) {
+ formWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ qDebug() << "Unable to set property " << name << '.';
+ }
+
+ emit propertyChanged(formWindow, name, value);
+}
+
+void QDesignerIntegration::updatePropertyPrivate(const QString &name, const QVariant &value)
+{
+ updateProperty(name, value, true);
+}
+
+void QDesignerIntegration::resetProperty(const QString &name)
+{
+ QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
+ if (!formWindow)
+ return;
+
+ Selection selection;
+ getSelection(selection);
+ if (selection.empty())
+ return;
+
+
+ ResetPropertyCommand *cmd = new ResetPropertyCommand(formWindow);
+ // find a reference object to find the right group
+ if (cmd->init(selection.selection(), name, propertyEditorObject())) {
+ formWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ qDebug() << "** WARNING Unable to reset property " << name << '.';
+ }
+}
+
+void QDesignerIntegration::addDynamicProperty(const QString &name, const QVariant &value)
+{
+ QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
+ if (!formWindow)
+ return;
+
+ Selection selection;
+ getSelection(selection);
+ if (selection.empty())
+ return;
+
+ AddDynamicPropertyCommand *cmd = new AddDynamicPropertyCommand(formWindow);
+ if (cmd->init(selection.selection(), propertyEditorObject(), name, value)) {
+ formWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ qDebug() << "** WARNING Unable to add dynamic property " << name << '.';
+ }
+}
+
+void QDesignerIntegration::removeDynamicProperty(const QString &name)
+{
+ QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
+ if (!formWindow)
+ return;
+
+ Selection selection;
+ getSelection(selection);
+ if (selection.empty())
+ return;
+
+ RemoveDynamicPropertyCommand *cmd = new RemoveDynamicPropertyCommand(formWindow);
+ if (cmd->init(selection.selection(), propertyEditorObject(), name)) {
+ formWindow->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ qDebug() << "** WARNING Unable to remove dynamic property " << name << '.';
+ }
+
+}
+
+
+void QDesignerIntegration::updateActiveFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_UNUSED(formWindow);
+ updateSelection();
+}
+
+void QDesignerIntegration::setupFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ connect(formWindow, SIGNAL(selectionChanged()), this, SLOT(updateSelection()));
+ connect(formWindow, SIGNAL(activated(QWidget*)), this, SLOT(activateWidget(QWidget*)));
+}
+
+void QDesignerIntegration::updateGeometry()
+{
+}
+
+void QDesignerIntegration::updateSelection()
+{
+ QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
+ QWidget *selection = 0;
+
+ if (formWindow) {
+ selection = formWindow->cursor()->current();
+ }
+
+ if (QDesignerActionEditorInterface *actionEditor = core()->actionEditor())
+ actionEditor->setFormWindow(formWindow);
+
+ if (QDesignerPropertyEditorInterface *propertyEditor = core()->propertyEditor())
+ propertyEditor->setObject(selection);
+
+ if (QDesignerObjectInspectorInterface *objectInspector = core()->objectInspector())
+ objectInspector->setFormWindow(formWindow);
+
+}
+
+void QDesignerIntegration::activateWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+}
+
+QWidget *QDesignerIntegration::containerWindow(QWidget *widget) const
+{
+ // Find the parent window to apply a geometry to.
+ while (widget) {
+ if (widget->isWindow())
+ break;
+ if (!qstrcmp(widget->metaObject()->className(), "QMdiSubWindow"))
+ break;
+
+ widget = widget->parentWidget();
+ }
+
+ return widget;
+}
+
+void QDesignerIntegration::getSelection(Selection &s)
+{
+ // Get multiselection from object inspector
+ if (QDesignerObjectInspector *designerObjectInspector = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector())) {
+ designerObjectInspector->getSelection(s);
+ // Action editor puts actions that are not on the form yet
+ // into the property editor only.
+ if (s.empty())
+ if (QObject *object = core()->propertyEditor()->object())
+ s.objects.push_back(object);
+
+ } else {
+ // Just in case someone plugs in an old-style object inspector: Emulate selection
+ s.clear();
+ QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
+ if (!formWindow)
+ return;
+
+ QObject *object = core()->propertyEditor()->object();
+ if (object->isWidgetType()) {
+ QWidget *widget = static_cast<QWidget*>(object);
+ QDesignerFormWindowCursorInterface *cursor = formWindow->cursor();
+ if (cursor->isWidgetSelected(widget)) {
+ s.managed.push_back(widget);
+ } else {
+ s.unmanaged.push_back(widget);
+ }
+ } else {
+ s.objects.push_back(object);
+ }
+ }
+}
+
+QObject *QDesignerIntegration::propertyEditorObject()
+{
+ QDesignerPropertyEditorInterface *propertyEditor = core()->propertyEditor();
+ if (!propertyEditor)
+ return 0;
+ return propertyEditor->object();
+}
+
+// Load plugins into widget database and factory.
+void QDesignerIntegration::initializePlugins(QDesignerFormEditorInterface *formEditor)
+{
+ // load the plugins
+ WidgetDataBase *widgetDataBase = qobject_cast<WidgetDataBase*>(formEditor->widgetDataBase());
+ if (widgetDataBase) {
+ widgetDataBase->loadPlugins();
+ }
+
+ if (WidgetFactory *widgetFactory = qobject_cast<WidgetFactory*>(formEditor->widgetFactory())) {
+ widgetFactory->loadPlugins();
+ }
+
+ if (widgetDataBase) {
+ widgetDataBase->grabDefaultPropertyValues();
+ }
+}
+
+void QDesignerIntegration::updateCustomWidgetPlugins()
+{
+ QDesignerFormEditorInterface *formEditor = core();
+ if (QDesignerPluginManager *pm = formEditor->pluginManager())
+ pm->registerNewPlugins();
+
+ initializePlugins(formEditor);
+
+ // Do not just reload the last file as the WidgetBox merges the compiled-in resources
+ // and $HOME/.designer/widgetbox.xml. This would also double the scratchpad.
+ if (QDesignerWidgetBox *wb = qobject_cast<QDesignerWidgetBox*>(formEditor->widgetBox())) {
+ const QDesignerWidgetBox::LoadMode oldLoadMode = wb->loadMode();
+ wb->setLoadMode(QDesignerWidgetBox::LoadCustomWidgetsOnly);
+ wb->load();
+ wb->setLoadMode(oldLoadMode);
+ }
+}
+
+void QDesignerIntegration::emitObjectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object, const QString &newName, const QString &oldName)
+{
+ emit objectNameChanged(formWindow, object, newName, oldName);
+}
+
+void QDesignerIntegration::emitNavigateToSlot(const QString &objectName,
+ const QString &signalSignature,
+ const QStringList &parameterNames)
+{
+ emit navigateToSlot(objectName, signalSignature, parameterNames);
+}
+
+void QDesignerIntegration::emitNavigateToSlot(const QString &slotSignature)
+{
+ emit navigateToSlot(slotSignature);
+}
+
+void QDesignerIntegration::requestHelp(const QDesignerFormEditorInterface *core, const QString &manual, const QString &document)
+{
+ if (QDesignerIntegration *di = qobject_cast<QDesignerIntegration *>(core->integration()))
+ emit di->helpRequested(manual, document);
+}
+
+QDesignerResourceBrowserInterface *QDesignerIntegration::createResourceBrowser(QWidget *)
+{
+ return 0;
+}
+
+void QDesignerIntegration::setResourceFileWatcherBehaviour(ResourceFileWatcherBehaviour behaviour)
+{
+ m_d->m_fileWatcherBehaviour = behaviour;
+ core()->resourceModel()->setWatcherEnabled(behaviour != QDesignerIntegration::NoWatcher);
+}
+
+QDesignerIntegration::ResourceFileWatcherBehaviour QDesignerIntegration::resourceFileWatcherBehaviour() const
+{
+ return m_d->m_fileWatcherBehaviour;
+}
+
+void QDesignerIntegration::setResourceEditingEnabled(bool enable)
+{
+ m_d->m_resourceEditingEnabled = enable;
+}
+
+bool QDesignerIntegration::isResourceEditingEnabled() const
+{
+ return m_d->m_resourceEditingEnabled;
+}
+
+void QDesignerIntegration::setSlotNavigationEnabled(bool enable)
+{
+ m_d->m_slotNavigationEnabled = enable;
+}
+
+bool QDesignerIntegration::isSlotNavigationEnabled() const
+{
+ return m_d->m_slotNavigationEnabled;
+}
+
+static QString fixHelpClassName(const QString &className)
+{
+ // ### generalize using the Widget Data Base
+ if (className == QLatin1String("Line"))
+ return QLatin1String("QFrame");
+ if (className == QLatin1String("Spacer"))
+ return QLatin1String("QSpacerItem");
+ if (className == QLatin1String("QLayoutWidget"))
+ return QLatin1String("QLayout");
+ return className;
+}
+
+// Return class in which the property is defined
+static QString classForProperty(QDesignerFormEditorInterface *core,
+ QObject *object,
+ const QString &property)
+{
+ if (const QDesignerPropertySheetExtension *ps = qt_extension<QDesignerPropertySheetExtension *>(core->extensionManager(), object)) {
+ const int index = ps->indexOf(property);
+ if (index >= 0)
+ return ps->propertyGroup(index);
+ }
+ return QString();
+}
+
+QString QDesignerIntegration::contextHelpId() const
+{
+ QObject *currentObject = core()->propertyEditor()->object();
+ if (!currentObject)
+ return QString();
+ // Return a help index id consisting of "class::property"
+ QString className;
+ QString currentPropertyName = core()->propertyEditor()->currentPropertyName();
+ if (!currentPropertyName.isEmpty())
+ className = classForProperty(core(), currentObject, currentPropertyName);
+ if (className.isEmpty()) {
+ currentPropertyName.clear(); // We hit on some fake property.
+ className = WidgetFactory::classNameOf(core(), currentObject);
+ }
+ QString helpId = fixHelpClassName(className);
+ if (!currentPropertyName.isEmpty()) {
+ helpId += QLatin1String("::");
+ helpId += currentPropertyName;
+ }
+ return helpId;
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_integration_p.h b/src/designer/src/lib/shared/qdesigner_integration_p.h
new file mode 100644
index 000000000..f4fdff7db
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_integration_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_INTEGRATION_H
+#define QDESIGNER_INTEGRATION_H
+
+#include "shared_global_p.h"
+#include <QtDesigner/QDesignerIntegrationInterface>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QDesignerResourceBrowserInterface;
+
+class QVariant;
+class QWidget;
+
+namespace qdesigner_internal {
+
+struct Selection;
+class QDesignerIntegrationPrivate;
+
+class QDESIGNER_SHARED_EXPORT QDesignerIntegration: public QDesignerIntegrationInterface
+{
+ Q_OBJECT
+public:
+ explicit QDesignerIntegration(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ virtual ~QDesignerIntegration();
+
+ static void requestHelp(const QDesignerFormEditorInterface *core, const QString &manual, const QString &document);
+
+ virtual QWidget *containerWindow(QWidget *widget) const;
+
+ // Load plugins into widget database and factory.
+ static void initializePlugins(QDesignerFormEditorInterface *formEditor);
+ void emitObjectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object,
+ const QString &newName, const QString &oldName);
+ void emitNavigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList &parameterNames);
+ void emitNavigateToSlot(const QString &slotSignature);
+
+ // Create a resource browser specific to integration. Language integration takes precedence
+ virtual QDesignerResourceBrowserInterface *createResourceBrowser(QWidget *parent = 0);
+
+ enum ResourceFileWatcherBehaviour {
+ NoWatcher,
+ ReloadSilently,
+ PromptAndReload
+ };
+
+ ResourceFileWatcherBehaviour resourceFileWatcherBehaviour() const;
+ bool isResourceEditingEnabled() const;
+ bool isSlotNavigationEnabled() const;
+
+ QString contextHelpId() const;
+
+protected:
+
+ void setResourceFileWatcherBehaviour(ResourceFileWatcherBehaviour behaviour); // PromptAndReload by default
+ void setResourceEditingEnabled(bool enable); // true by default
+ void setSlotNavigationEnabled(bool enable); // false by default
+
+signals:
+ void propertyChanged(QDesignerFormWindowInterface *formWindow, const QString &name, const QVariant &value);
+ void objectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object, const QString &newName, const QString &oldName);
+ void helpRequested(const QString &manual, const QString &document);
+
+ void navigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList &parameterNames);
+ void navigateToSlot(const QString &slotSignature);
+
+public slots:
+ virtual void updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling);
+ // Additional signals of designer property editor
+ virtual void resetProperty(const QString &name);
+ virtual void addDynamicProperty(const QString &name, const QVariant &value);
+ virtual void removeDynamicProperty(const QString &name);
+
+ virtual void updateActiveFormWindow(QDesignerFormWindowInterface *formWindow);
+ virtual void setupFormWindow(QDesignerFormWindowInterface *formWindow);
+ virtual void updateSelection();
+ virtual void updateGeometry();
+ virtual void activateWidget(QWidget *widget);
+
+ void updateCustomWidgetPlugins();
+
+private slots:
+ void updatePropertyPrivate(const QString &name, const QVariant &value);
+
+private:
+ void initialize();
+ void getSelection(Selection &s);
+ QObject *propertyEditorObject();
+
+ QDesignerIntegrationPrivate *m_d;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_INTEGRATION_H
diff --git a/src/designer/src/lib/shared/qdesigner_introspection.cpp b/src/designer/src/lib/shared/qdesigner_introspection.cpp
new file mode 100644
index 000000000..9d45acca6
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_introspection.cpp
@@ -0,0 +1,372 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_introspection_p.h"
+
+#include <QtCore/QMetaObject>
+#include <QtCore/QMetaEnum>
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+// Qt Implementation
+static QStringList byteArrayListToStringList(const QList<QByteArray> &l)
+{
+ if (l.empty())
+ return QStringList();
+ QStringList rc;
+ const QList<QByteArray>::const_iterator cend = l.constEnd();
+ for (QList<QByteArray>::const_iterator it = l.constBegin(); it != cend; ++it)
+ rc += QString::fromUtf8(*it);
+ return rc;
+}
+
+static inline QString charToQString(const char *c)
+{
+ if (!c)
+ return QString();
+ return QString::fromUtf8(c);
+}
+
+namespace {
+ // ------- QDesignerMetaEnum
+ class QDesignerMetaEnum : public QDesignerMetaEnumInterface {
+ public:
+ QDesignerMetaEnum(const QMetaEnum &qEnum);
+ virtual bool isFlag() const { return m_enum.isFlag(); }
+ virtual QString key(int index) const { return charToQString(m_enum.key(index)); }
+ virtual int keyCount() const { return m_enum.keyCount(); }
+ virtual int keyToValue(const QString &key) const { return m_enum.keyToValue(key.toUtf8()); }
+ virtual int keysToValue(const QString &keys) const { return m_enum.keysToValue(keys.toUtf8()); }
+ virtual QString name() const { return m_name; }
+ virtual QString scope() const { return m_scope; }
+ virtual QString separator() const;
+ virtual int value(int index) const { return m_enum.value(index); }
+ virtual QString valueToKey(int value) const { return charToQString(m_enum.valueToKey(value)); }
+ virtual QString valueToKeys(int value) const { return charToQString(m_enum.valueToKeys(value)); }
+
+ private:
+ const QMetaEnum m_enum;
+ const QString m_name;
+ const QString m_scope;
+ };
+
+ QDesignerMetaEnum::QDesignerMetaEnum(const QMetaEnum &qEnum) :
+ m_enum(qEnum),
+ m_name(charToQString(m_enum.name())),
+ m_scope(charToQString(m_enum.scope()))
+ {
+ }
+
+ QString QDesignerMetaEnum::separator() const
+ {
+ static const QString rc = QLatin1String("::");
+ return rc;
+ }
+
+ // ------- QDesignerMetaProperty
+ class QDesignerMetaProperty : public QDesignerMetaPropertyInterface {
+ public:
+ QDesignerMetaProperty(const QMetaProperty &property);
+ virtual ~QDesignerMetaProperty();
+
+ virtual const QDesignerMetaEnumInterface *enumerator() const { return m_enumerator; }
+
+ virtual Kind kind() const { return m_kind; }
+
+ virtual AccessFlags accessFlags() const { return m_access; }
+ virtual Attributes attributes(const QObject *object = 0) const;
+
+ virtual QVariant::Type type() const { return m_property.type(); }
+ virtual QString name() const { return m_name; }
+ virtual QString typeName() const { return m_typeName; }
+ virtual int userType() const { return m_property.userType(); }
+ virtual bool hasSetter() const { return m_property.hasStdCppSet(); }
+
+ virtual QVariant read(const QObject *object) const { return m_property.read(object); }
+ virtual bool reset(QObject *object) const { return m_property.reset(object); }
+ virtual bool write(QObject *object, const QVariant &value) const { return m_property.write(object, value); }
+
+ private:
+ const QMetaProperty m_property;
+ const QString m_name;
+ const QString m_typeName;
+ Kind m_kind;
+ AccessFlags m_access;
+ Attributes m_defaultAttributes;
+ QDesignerMetaEnumInterface *m_enumerator;
+ };
+
+ QDesignerMetaProperty::QDesignerMetaProperty(const QMetaProperty &property) :
+ m_property(property),
+ m_name(charToQString(m_property.name())),
+ m_typeName(charToQString(m_property.typeName())),
+ m_kind(OtherKind),
+ m_enumerator(0)
+ {
+ if (m_property.isFlagType() || m_property.isEnumType()) {
+ const QMetaEnum metaEnum = m_property.enumerator();
+ Q_ASSERT(metaEnum.isValid());
+ m_enumerator = new QDesignerMetaEnum(metaEnum);
+ }
+ // kind
+ if (m_property.isFlagType())
+ m_kind = FlagKind;
+ else
+ if (m_property.isEnumType())
+ m_kind = EnumKind;
+ // flags and attributes
+ if (m_property.isReadable())
+ m_access |= ReadAccess;
+ if (m_property.isWritable())
+ m_access |= WriteAccess;
+ if (m_property.isResettable())
+ m_access |= ResetAccess;
+
+ if (m_property.isDesignable())
+ m_defaultAttributes |= DesignableAttribute;
+ if (m_property.isScriptable())
+ m_defaultAttributes |= ScriptableAttribute;
+ if (m_property.isStored())
+ m_defaultAttributes |= StoredAttribute;
+ if (m_property.isUser())
+ m_defaultAttributes |= UserAttribute;
+ }
+
+ QDesignerMetaProperty::~QDesignerMetaProperty()
+ {
+ delete m_enumerator;
+ }
+
+ QDesignerMetaProperty::Attributes QDesignerMetaProperty::attributes(const QObject *object) const
+ {
+ if (!object)
+ return m_defaultAttributes;
+ Attributes rc;
+ if (m_property.isDesignable(object))
+ rc |= DesignableAttribute;
+ if (m_property.isScriptable(object))
+ rc |= ScriptableAttribute;
+ if (m_property.isStored(object))
+ rc |= StoredAttribute;
+ if (m_property.isUser(object))
+ rc |= UserAttribute;
+ return rc;
+ }
+
+ // -------------- QDesignerMetaMethod
+
+ class QDesignerMetaMethod : public QDesignerMetaMethodInterface {
+ public:
+ QDesignerMetaMethod(const QMetaMethod &method);
+
+ virtual Access access() const { return m_access; }
+ virtual MethodType methodType() const { return m_methodType; }
+ virtual QStringList parameterNames() const { return m_parameterNames; }
+ virtual QStringList parameterTypes() const { return m_parameterTypes; }
+ virtual QString signature() const { return m_signature; }
+ virtual QString normalizedSignature() const { return m_normalizedSignature; }
+ virtual QString tag() const { return m_tag; }
+ virtual QString typeName() const { return m_typeName; }
+
+ private:
+ Access m_access;
+ MethodType m_methodType;
+ const QStringList m_parameterNames;
+ const QStringList m_parameterTypes;
+ const QString m_signature;
+ const QString m_normalizedSignature;
+ const QString m_tag;
+ const QString m_typeName;
+ };
+
+ QDesignerMetaMethod::QDesignerMetaMethod(const QMetaMethod &method) :
+ m_parameterNames(byteArrayListToStringList(method.parameterNames())),
+ m_parameterTypes(byteArrayListToStringList(method.parameterTypes())),
+ m_signature(charToQString(method.signature())),
+ m_normalizedSignature(charToQString(QMetaObject::normalizedSignature(method.signature()))),
+ m_tag(charToQString(method.tag())),
+ m_typeName(charToQString(method.typeName()))
+ {
+ switch (method.access()) {
+ case QMetaMethod::Public:
+ m_access = Public;
+ break;
+ case QMetaMethod::Protected:
+ m_access = Protected;
+ break;
+ case QMetaMethod::Private:
+ m_access = Private;
+ break;
+
+ }
+ switch (method.methodType()) {
+ case QMetaMethod::Constructor:
+ m_methodType = Constructor;
+ break;
+ case QMetaMethod::Method:
+ m_methodType = Method;
+ break;
+ case QMetaMethod::Signal:
+ m_methodType = Signal;
+ break;
+
+ case QMetaMethod::Slot:
+ m_methodType = Slot;
+ break;
+ }
+ }
+
+ // ------------- QDesignerMetaObject
+ class QDesignerMetaObject : public QDesignerMetaObjectInterface {
+ public:
+ QDesignerMetaObject(const qdesigner_internal::QDesignerIntrospection *introspection, const QMetaObject *metaObject);
+ virtual ~QDesignerMetaObject();
+
+ virtual QString className() const { return m_className; }
+ virtual const QDesignerMetaEnumInterface *enumerator(int index) const { return m_enumerators[index]; }
+ virtual int enumeratorCount() const { return m_enumerators.size(); }
+ virtual int enumeratorOffset() const { return m_metaObject->enumeratorOffset(); }
+
+ virtual int indexOfEnumerator(const QString &name) const { return m_metaObject->indexOfEnumerator(name.toUtf8()); }
+ virtual int indexOfMethod(const QString &method) const { return m_metaObject->indexOfMethod(method.toUtf8()); }
+ virtual int indexOfProperty(const QString &name) const { return m_metaObject->indexOfProperty(name.toUtf8()); }
+ virtual int indexOfSignal(const QString &signal) const { return m_metaObject->indexOfSignal(signal.toUtf8()); }
+ virtual int indexOfSlot(const QString &slot) const { return m_metaObject->indexOfSlot(slot.toUtf8()); }
+
+ virtual const QDesignerMetaMethodInterface *method(int index) const { return m_methods[index]; }
+ virtual int methodCount() const { return m_methods.size(); }
+ virtual int methodOffset() const { return m_metaObject->methodOffset(); }
+
+ virtual const QDesignerMetaPropertyInterface *property(int index) const { return m_properties[index]; }
+ virtual int propertyCount() const { return m_properties.size(); }
+ virtual int propertyOffset() const { return m_metaObject->propertyOffset(); }
+
+ const QDesignerMetaObjectInterface *superClass() const;
+ virtual const QDesignerMetaPropertyInterface *userProperty() const { return m_userProperty; }
+
+ private:
+ const QString m_className;
+ const qdesigner_internal::QDesignerIntrospection *m_introspection;
+ const QMetaObject *m_metaObject;
+
+ typedef QVector<QDesignerMetaEnumInterface *> Enumerators;
+ Enumerators m_enumerators;
+
+ typedef QVector<QDesignerMetaMethodInterface *> Methods;
+ Methods m_methods;
+
+ typedef QVector<QDesignerMetaPropertyInterface *> Properties;
+ Properties m_properties;
+
+ QDesignerMetaPropertyInterface *m_userProperty;
+ };
+
+ QDesignerMetaObject::QDesignerMetaObject(const qdesigner_internal::QDesignerIntrospection *introspection, const QMetaObject *metaObject) :
+ m_className(charToQString(metaObject->className())),
+ m_introspection(introspection),
+ m_metaObject(metaObject),
+ m_userProperty(0)
+ {
+ const int numEnumerators = metaObject->enumeratorCount();
+ m_enumerators.reserve(numEnumerators);
+ for (int i = 0; i < numEnumerators; i++)
+ m_enumerators.push_back(new QDesignerMetaEnum(metaObject->enumerator(i)));
+ const int numMethods = metaObject->methodCount();
+ m_methods.reserve(numMethods);
+ for (int i = 0; i < numMethods; i++)
+ m_methods.push_back(new QDesignerMetaMethod(metaObject->method(i)));
+
+ const int numProperties = metaObject->propertyCount();
+ m_properties.reserve(numProperties);
+ for (int i = 0; i < numProperties; i++)
+ m_properties.push_back(new QDesignerMetaProperty(metaObject->property(i)));
+
+ const QMetaProperty userProperty = metaObject->userProperty();
+ if (userProperty.isValid())
+ m_userProperty = new QDesignerMetaProperty(userProperty);
+ }
+
+ QDesignerMetaObject::~QDesignerMetaObject()
+ {
+ qDeleteAll(m_enumerators);
+ qDeleteAll(m_methods);
+ qDeleteAll(m_properties);
+ delete m_userProperty;
+ }
+
+ const QDesignerMetaObjectInterface *QDesignerMetaObject::superClass() const
+ {
+ const QMetaObject *qSuperClass = m_metaObject->superClass();
+ if (!qSuperClass)
+ return 0;
+ return m_introspection->metaObjectForQMetaObject(qSuperClass);
+ }
+
+}
+
+namespace qdesigner_internal {
+
+ QDesignerIntrospection::QDesignerIntrospection()
+ {
+ }
+
+ QDesignerIntrospection::~QDesignerIntrospection()
+ {
+ qDeleteAll(m_metaObjectMap.values());
+ }
+
+ const QDesignerMetaObjectInterface* QDesignerIntrospection::metaObject(const QObject *object) const
+ {
+ return metaObjectForQMetaObject(object->metaObject());
+ }
+
+ const QDesignerMetaObjectInterface* QDesignerIntrospection::metaObjectForQMetaObject(const QMetaObject *metaObject) const
+ {
+ MetaObjectMap::iterator it = m_metaObjectMap.find(metaObject);
+ if (it == m_metaObjectMap.end())
+ it = m_metaObjectMap.insert(metaObject, new QDesignerMetaObject(this, metaObject));
+ return it.value();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_introspection_p.h b/src/designer/src/lib/shared/qdesigner_introspection_p.h
new file mode 100644
index 000000000..ed4785f87
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_introspection_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef DESIGNERINTROSPECTION
+#define DESIGNERINTROSPECTION
+
+#include "shared_global_p.h"
+#include <abstractintrospection_p.h>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+struct QMetaObject;
+class QWidget;
+
+namespace qdesigner_internal {
+ // Qt C++ introspection with helpers to find core and meta object for an object
+ class QDESIGNER_SHARED_EXPORT QDesignerIntrospection : public QDesignerIntrospectionInterface {
+ public:
+ QDesignerIntrospection();
+ virtual ~QDesignerIntrospection();
+
+ virtual const QDesignerMetaObjectInterface* metaObject(const QObject *object) const;
+
+ const QDesignerMetaObjectInterface* metaObjectForQMetaObject(const QMetaObject *metaObject) const;
+ private:
+ typedef QMap<const QMetaObject*, QDesignerMetaObjectInterface*> MetaObjectMap;
+ mutable MetaObjectMap m_metaObjectMap;
+
+ };
+}
+
+QT_END_NAMESPACE
+
+#endif // DESIGNERINTROSPECTION
diff --git a/src/designer/src/lib/shared/qdesigner_membersheet.cpp b/src/designer/src/lib/shared/qdesigner_membersheet.cpp
new file mode 100644
index 000000000..f70fc389b
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_membersheet.cpp
@@ -0,0 +1,371 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_membersheet_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <abstractintrospection_p.h>
+
+#include <QtGui/QWidget>
+
+namespace {
+
+class Qt3Members
+ {
+ public:
+ static Qt3Members *instance();
+ QMap<QString, QStringList> getSignals() const { return m_classNameToSignals; }
+ QMap<QString, QStringList> getSlots() const { return m_classNameToSlots; }
+ private:
+ Qt3Members();
+ static Qt3Members *m_instance;
+ QMap<QString, QStringList> m_classNameToSignals;
+ QMap<QString, QStringList> m_classNameToSlots;
+ };
+
+Qt3Members *Qt3Members::m_instance = 0;
+
+Qt3Members::Qt3Members()
+{
+ m_classNameToSignals[QLatin1String("QTextEdit")].append(QLatin1String("currentFontChanged(QFont)"));
+ m_classNameToSignals[QLatin1String("QTextEdit")].append(QLatin1String("currentColorChanged(QColor)"));
+ m_classNameToSignals[QLatin1String("QTabWidget")].append(QLatin1String("currentChanged(QWidget*)"));
+ m_classNameToSignals[QLatin1String("QTabWidget")].append(QLatin1String("selected(QString)"));
+ m_classNameToSignals[QLatin1String("QTabBar")].append(QLatin1String("selected(int)"));
+ m_classNameToSignals[QLatin1String("QMenuBar")].append(QLatin1String("activated(int)"));
+ m_classNameToSignals[QLatin1String("QMenuBar")].append(QLatin1String("highlighted(int)"));
+ m_classNameToSignals[QLatin1String("QMenu")].append(QLatin1String("activated(int)"));
+ m_classNameToSignals[QLatin1String("QMenu")].append(QLatin1String("highlighted(int)"));
+ m_classNameToSignals[QLatin1String("QLineEdit")].append(QLatin1String("lostFocus()"));
+ m_classNameToSignals[QLatin1String("QDial")].append(QLatin1String("dialPressed()"));
+ m_classNameToSignals[QLatin1String("QDial")].append(QLatin1String("dialMoved(int)"));
+ m_classNameToSignals[QLatin1String("QDial")].append(QLatin1String("dialReleased()"));
+ m_classNameToSignals[QLatin1String("QComboBox")].append(QLatin1String("textChanged(QString)"));
+ m_classNameToSignals[QLatin1String("QActionGroup")].append(QLatin1String("selected(QAction*)"));
+ m_classNameToSignals[QLatin1String("QAction")].append(QLatin1String("activated(int)"));
+ m_classNameToSignals[QLatin1String("QAbstractSocket")].append(QLatin1String("connectionClosed()"));
+ m_classNameToSignals[QLatin1String("QAbstractSocket")].append(QLatin1String("delayedCloseFinished()"));
+
+ m_classNameToSlots[QLatin1String("QWidget")].append(QLatin1String("setShown(bool)"));
+ m_classNameToSlots[QLatin1String("QToolButton")].append(QLatin1String("setTextPosition(QToolButton::TextPosition)"));
+ m_classNameToSlots[QLatin1String("QToolButton")].append(QLatin1String("setUsesBigPixmap(bool)"));
+ m_classNameToSlots[QLatin1String("QToolButton")].append(QLatin1String("setUsesTextLabel(bool)"));
+ m_classNameToSlots[QLatin1String("QTextEdit")].append(QLatin1String("setModified(bool)"));
+ m_classNameToSlots[QLatin1String("QTextEdit")].append(QLatin1String("setColor(QColor)"));
+ m_classNameToSlots[QLatin1String("QTabWidget")].append(QLatin1String("setCurrentPage(int)"));
+ m_classNameToSlots[QLatin1String("QTabWidget")].append(QLatin1String("showPage(QWidget*)"));
+ m_classNameToSlots[QLatin1String("QTabWidget")].append(QLatin1String("removePage(QWidget*)"));
+ m_classNameToSlots[QLatin1String("QTabBar")].append(QLatin1String("setCurrentTab(int)"));
+ m_classNameToSlots[QLatin1String("QStatusBar")].append(QLatin1String("message(QString,int)"));
+ m_classNameToSlots[QLatin1String("QStatusBar")].append(QLatin1String("clear()"));
+ m_classNameToSlots[QLatin1String("QSplashScreen")].append(QLatin1String("message(QString,int)"));
+ m_classNameToSlots[QLatin1String("QSplashScreen")].append(QLatin1String("clear()"));
+ m_classNameToSlots[QLatin1String("QSlider")].append(QLatin1String("addStep()"));
+ m_classNameToSlots[QLatin1String("QSlider")].append(QLatin1String("subtractStep()"));
+ m_classNameToSlots[QLatin1String("QAbstractButton")].append(QLatin1String("setOn(bool)"));
+ m_classNameToSlots[QLatin1String("QAction")].append(QLatin1String("setOn(bool)"));
+ m_classNameToSlots[QLatin1String("QErrorMessage")].append(QLatin1String("message(QString)"));
+ m_classNameToSlots[QLatin1String("QTimer")].append(QLatin1String("changeInterval(int)"));
+ m_classNameToSlots[QLatin1String("QTimer")].append(QLatin1String("start(int,bool)"));
+}
+
+Qt3Members *Qt3Members::instance()
+{
+ if (!m_instance)
+ m_instance = new Qt3Members();
+ return m_instance;
+}
+}
+
+QT_BEGIN_NAMESPACE
+
+static QList<QByteArray> stringListToByteArray(const QStringList &l)
+{
+ if (l.empty())
+ return QList<QByteArray>();
+ QList<QByteArray> rc;
+ const QStringList::const_iterator cend = l.constEnd();
+ for (QStringList::const_iterator it = l.constBegin(); it != cend; ++it)
+ rc += it->toUtf8();
+ return rc;
+}
+
+// Find the form editor in the hierarchy.
+// We know that the parent of the sheet is the extension manager
+// whose parent is the core.
+
+static QDesignerFormEditorInterface *formEditorForObject(QObject *o) {
+ do {
+ if (QDesignerFormEditorInterface* core = qobject_cast<QDesignerFormEditorInterface*>(o))
+ return core;
+ o = o->parent();
+ } while(o);
+ Q_ASSERT(o);
+ return 0;
+}
+
+// ------------ QDesignerMemberSheetPrivate
+class QDesignerMemberSheetPrivate {
+public:
+ explicit QDesignerMemberSheetPrivate(QObject *object, QObject *sheetParent);
+
+ QDesignerFormEditorInterface *m_core;
+ const QDesignerMetaObjectInterface *m_meta;
+
+ class Info {
+ public:
+ inline Info() : visible(true) {}
+
+ QString group;
+ bool visible;
+ };
+
+ typedef QHash<int, Info> InfoHash;
+
+ Info &ensureInfo(int index);
+
+ InfoHash m_info;
+};
+
+QDesignerMemberSheetPrivate::QDesignerMemberSheetPrivate(QObject *object, QObject *sheetParent) :
+ m_core(formEditorForObject(sheetParent)),
+ m_meta(m_core->introspection()->metaObject(object))
+{
+}
+
+QDesignerMemberSheetPrivate::Info &QDesignerMemberSheetPrivate::ensureInfo(int index)
+{
+ InfoHash::iterator it = m_info.find(index);
+ if (it == m_info.end()) {
+ it = m_info.insert(index, Info());
+ }
+ return it.value();
+}
+
+// --------- QDesignerMemberSheet
+
+QDesignerMemberSheet::QDesignerMemberSheet(QObject *object, QObject *parent) :
+ QObject(parent),
+ d(new QDesignerMemberSheetPrivate(object, parent))
+{
+}
+
+QDesignerMemberSheet::~QDesignerMemberSheet()
+{
+ delete d;
+}
+
+int QDesignerMemberSheet::count() const
+{
+ return d->m_meta->methodCount();
+}
+
+int QDesignerMemberSheet::indexOf(const QString &name) const
+{
+ return d->m_meta->indexOfMethod(name);
+}
+
+QString QDesignerMemberSheet::memberName(int index) const
+{
+ return d->m_meta->method(index)->tag();
+}
+
+QString QDesignerMemberSheet::declaredInClass(int index) const
+{
+ const QString member = d->m_meta->method(index)->signature();
+
+ // Find class whose superclass does not contain the method.
+ const QDesignerMetaObjectInterface *meta_obj = d->m_meta;
+
+ for (;;) {
+ const QDesignerMetaObjectInterface *tmp = meta_obj->superClass();
+ if (tmp == 0)
+ break;
+ if (tmp->indexOfMethod(member) == -1)
+ break;
+ meta_obj = tmp;
+ }
+ return meta_obj->className();
+}
+
+QString QDesignerMemberSheet::memberGroup(int index) const
+{
+ return d->m_info.value(index).group;
+}
+
+void QDesignerMemberSheet::setMemberGroup(int index, const QString &group)
+{
+ d->ensureInfo(index).group = group;
+}
+
+QString QDesignerMemberSheet::signature(int index) const
+{
+ return d->m_meta->method(index)->normalizedSignature();
+}
+
+bool QDesignerMemberSheet::isVisible(int index) const
+{
+ typedef QDesignerMemberSheetPrivate::InfoHash InfoHash;
+ const InfoHash::const_iterator it = d->m_info.constFind(index);
+ if (it != d->m_info.constEnd())
+ return it.value().visible;
+
+ return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Signal
+ || d->m_meta->method(index)->access() == QDesignerMetaMethodInterface::Public;
+}
+
+void QDesignerMemberSheet::setVisible(int index, bool visible)
+{
+ d->ensureInfo(index).visible = visible;
+}
+
+bool QDesignerMemberSheet::isSignal(int index) const
+{
+ return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Signal;
+}
+
+bool QDesignerMemberSheet::isSlot(int index) const
+{
+ return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Slot;
+}
+
+bool QDesignerMemberSheet::inheritedFromWidget(int index) const
+{
+ const QString name = d->m_meta->method(index)->signature();
+ return declaredInClass(index) == QLatin1String("QWidget") || declaredInClass(index) == QLatin1String("QObject");
+}
+
+
+QList<QByteArray> QDesignerMemberSheet::parameterTypes(int index) const
+{
+ return stringListToByteArray(d->m_meta->method(index)->parameterTypes());
+}
+
+QList<QByteArray> QDesignerMemberSheet::parameterNames(int index) const
+{
+ return stringListToByteArray(d->m_meta->method(index)->parameterNames());
+}
+
+bool QDesignerMemberSheet::signalMatchesSlot(const QString &signal, const QString &slot)
+{
+ bool result = true;
+
+ do {
+ int signal_idx = signal.indexOf(QLatin1Char('('));
+ int slot_idx = slot.indexOf(QLatin1Char('('));
+ if (signal_idx == -1 || slot_idx == -1)
+ break;
+
+ ++signal_idx; ++slot_idx;
+
+ if (slot.at(slot_idx) == QLatin1Char(')'))
+ break;
+
+ while (signal_idx < signal.size() && slot_idx < slot.size()) {
+ const QChar signal_c = signal.at(signal_idx);
+ const QChar slot_c = slot.at(slot_idx);
+
+ if (signal_c == QLatin1Char(',') && slot_c == QLatin1Char(')'))
+ break;
+
+ if (signal_c == QLatin1Char(')') && slot_c == QLatin1Char(')'))
+ break;
+
+ if (signal_c != slot_c) {
+ result = false;
+ break;
+ }
+
+ ++signal_idx; ++slot_idx;
+ }
+ } while (false);
+
+ return result;
+}
+
+bool QDesignerMemberSheet::isQt3Signal(int index) const
+{
+ if (!isSignal(index))
+ return false;
+
+ const QString className = declaredInClass(index);
+ const QString signalSignature = signature(index);
+
+ QMap<QString, QStringList> qt3signals = Qt3Members::instance()->getSignals();
+ QMap<QString, QStringList>::const_iterator it = qt3signals.constFind(className);
+ if (it != qt3signals.constEnd() && (*it).contains(signalSignature))
+ return true;
+
+ return false;
+}
+
+bool QDesignerMemberSheet::isQt3Slot(int index) const
+{
+ if (!isSlot(index))
+ return false;
+
+ const QString className = declaredInClass(index);
+ const QString slotSignature = signature(index);
+
+ QMap<QString, QStringList> qt3slots = Qt3Members::instance()->getSlots();
+ QMap<QString, QStringList>::const_iterator it = qt3slots.constFind(className);
+ if (it != qt3slots.constEnd() && (*it).contains(slotSignature))
+ return true;
+ return false;
+}
+
+// ------------ QDesignerMemberSheetFactory
+
+QDesignerMemberSheetFactory::QDesignerMemberSheetFactory(QExtensionManager *parent)
+ : QExtensionFactory(parent)
+{
+}
+
+QObject *QDesignerMemberSheetFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid == Q_TYPEID(QDesignerMemberSheetExtension)) {
+ return new QDesignerMemberSheet(object, parent);
+ }
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_membersheet_p.h b/src/designer/src/lib/shared/qdesigner_membersheet_p.h
new file mode 100644
index 000000000..0f0f5736c
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_membersheet_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_MEMBERSHEET_H
+#define QDESIGNER_MEMBERSHEET_H
+
+#include "shared_global_p.h"
+
+#include <QtDesigner/membersheet.h>
+#include <QtDesigner/default_extensionfactory.h>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerMemberSheetPrivate;
+
+class QDESIGNER_SHARED_EXPORT QDesignerMemberSheet: public QObject, public QDesignerMemberSheetExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerMemberSheetExtension)
+
+public:
+ explicit QDesignerMemberSheet(QObject *object, QObject *parent = 0);
+ virtual ~QDesignerMemberSheet();
+
+ virtual int indexOf(const QString &name) const;
+
+ virtual int count() const;
+ virtual QString memberName(int index) const;
+
+ virtual QString memberGroup(int index) const;
+ virtual void setMemberGroup(int index, const QString &group);
+
+ virtual bool isVisible(int index) const;
+ virtual void setVisible(int index, bool b);
+
+ virtual bool isSignal(int index) const;
+ virtual bool isSlot(int index) const;
+
+ virtual bool isQt3Signal(int index) const;
+ virtual bool isQt3Slot(int index) const;
+
+ virtual bool inheritedFromWidget(int index) const;
+
+ static bool signalMatchesSlot(const QString &signal, const QString &slot);
+
+ virtual QString declaredInClass(int index) const;
+
+ virtual QString signature(int index) const;
+ virtual QList<QByteArray> parameterTypes(int index) const;
+ virtual QList<QByteArray> parameterNames(int index) const;
+
+private:
+ QDesignerMemberSheetPrivate *d;
+};
+
+class QDESIGNER_SHARED_EXPORT QDesignerMemberSheetFactory: public QExtensionFactory
+{
+ Q_OBJECT
+ Q_INTERFACES(QAbstractExtensionFactory)
+
+public:
+ QDesignerMemberSheetFactory(QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_MEMBERSHEET_H
diff --git a/src/designer/src/lib/shared/qdesigner_menu.cpp b/src/designer/src/lib/shared/qdesigner_menu.cpp
new file mode 100644
index 000000000..e9abf30cd
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_menu.cpp
@@ -0,0 +1,1390 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_menu_p.h"
+#include "qdesigner_menubar_p.h"
+#include "qdesigner_toolbar_p.h"
+#include "qdesigner_command_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "actionrepository_p.h"
+#include "actionprovider_p.h"
+#include "actioneditor_p.h"
+#include "qdesigner_utils_p.h"
+#include "qdesigner_objectinspector_p.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/qdebug.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QLineEdit>
+#include <QtGui/QPainter>
+#include <QtGui/QRubberBand>
+#include <QtGui/QToolTip>
+#include <QtGui/QToolBar>
+#include <QtGui/qevent.h>
+
+Q_DECLARE_METATYPE(QAction*)
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+// give the user a little more space to click on the sub menu rectangle
+static inline void extendClickableArea(QRect *subMenuRect, Qt::LayoutDirection dir)
+{
+ switch (dir) {
+ case Qt::LayoutDirectionAuto: // Should never happen
+ case Qt::LeftToRight:
+ subMenuRect->setLeft(subMenuRect->left() - 20);
+ break;
+ case Qt::RightToLeft:
+ subMenuRect->setRight(subMenuRect->right() + 20);
+ break;
+ }
+}
+
+QDesignerMenu::QDesignerMenu(QWidget *parent) :
+ QMenu(parent),
+ m_subMenuPixmap(QPixmap(QLatin1String(":/trolltech/formeditor/images/submenu.png"))),
+ m_currentIndex(0),
+ m_addItem(new SpecialMenuAction(this)),
+ m_addSeparator(new SpecialMenuAction(this)),
+ m_showSubMenuTimer(new QTimer(this)),
+ m_deactivateWindowTimer(new QTimer(this)),
+ m_adjustSizeTimer(new QTimer(this)),
+ m_editor(new QLineEdit(this)),
+ m_dragging(false),
+ m_lastSubMenuIndex(-1)
+{
+ setContextMenuPolicy(Qt::DefaultContextMenu);
+ setAcceptDrops(true); // ### fake
+ setSeparatorsCollapsible(false);
+
+ connect(m_adjustSizeTimer, SIGNAL(timeout()), this, SLOT(slotAdjustSizeNow()));
+ m_addItem->setText(tr("Type Here"));
+ addAction(m_addItem);
+
+ m_addSeparator->setText(tr("Add Separator"));
+ addAction(m_addSeparator);
+
+ connect(m_showSubMenuTimer, SIGNAL(timeout()), this, SLOT(slotShowSubMenuNow()));
+
+ connect(m_deactivateWindowTimer, SIGNAL(timeout()), this, SLOT(slotDeactivateNow()));
+
+ m_editor->setObjectName(QLatin1String("__qt__passive_editor"));
+ m_editor->hide();
+
+ m_editor->installEventFilter(this);
+ installEventFilter(this);
+}
+
+QDesignerMenu::~QDesignerMenu()
+{
+}
+
+void QDesignerMenu::slotAdjustSizeNow()
+{
+ // Not using a single-shot, since we want to compress the timers if many items are being
+ // adjusted
+ m_adjustSizeTimer->stop();
+ adjustSize();
+}
+
+bool QDesignerMenu::handleEvent(QWidget *widget, QEvent *event)
+{
+ if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
+ update();
+
+ if (widget == m_editor)
+ return false;
+ }
+
+ switch (event->type()) {
+ default: break;
+
+ case QEvent::MouseButtonPress:
+ return handleMousePressEvent(widget, static_cast<QMouseEvent*>(event));
+ case QEvent::MouseButtonRelease:
+ return handleMouseReleaseEvent(widget, static_cast<QMouseEvent*>(event));
+ case QEvent::MouseButtonDblClick:
+ return handleMouseDoubleClickEvent(widget, static_cast<QMouseEvent*>(event));
+ case QEvent::MouseMove:
+ return handleMouseMoveEvent(widget, static_cast<QMouseEvent*>(event));
+ case QEvent::ContextMenu:
+ return handleContextMenuEvent(widget, static_cast<QContextMenuEvent*>(event));
+ case QEvent::KeyPress:
+ return handleKeyPressEvent(widget, static_cast<QKeyEvent*>(event));
+ }
+
+ return true;
+}
+
+void QDesignerMenu::startDrag(const QPoint &pos, Qt::KeyboardModifiers modifiers)
+{
+ const int index = findAction(pos);
+ if (index >= realActionCount())
+ return;
+
+ QAction *action = safeActionAt(index);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ const Qt::DropAction dropAction = (modifiers & Qt::ControlModifier) ? Qt::CopyAction : Qt::MoveAction;
+ if (dropAction == Qt::MoveAction) {
+ RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw);
+ cmd->init(this, action, actions().at(index + 1));
+ fw->commandHistory()->push(cmd);
+ }
+
+ QDrag *drag = new QDrag(this);
+ drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(action));
+ drag->setMimeData(new ActionRepositoryMimeData(action, dropAction));
+
+ const int old_index = m_currentIndex;
+ m_currentIndex = -1;
+
+ if (drag->start(dropAction) == Qt::IgnoreAction) {
+ if (dropAction == Qt::MoveAction) {
+ QAction *previous = safeActionAt(index);
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(this, action, previous);
+ fw->commandHistory()->push(cmd);
+ }
+
+ m_currentIndex = old_index;
+ }
+}
+
+bool QDesignerMenu::handleKeyPressEvent(QWidget * /*widget*/, QKeyEvent *e)
+{
+ m_showSubMenuTimer->stop();
+
+ if (m_editor->isHidden() && hasFocus()) { // In navigation mode
+ switch (e->key()) {
+
+ case Qt::Key_Delete:
+ if (m_currentIndex == -1 || m_currentIndex >= realActionCount())
+ break;
+ hideSubMenu();
+ deleteAction();
+ break;
+
+ case Qt::Key_Left:
+ e->accept();
+ moveLeft();
+ return true;
+
+ case Qt::Key_Right:
+ e->accept();
+ moveRight();
+ return true; // no update
+
+ case Qt::Key_Up:
+ e->accept();
+ moveUp(e->modifiers() & Qt::ControlModifier);
+ return true;
+
+ case Qt::Key_Down:
+ e->accept();
+ moveDown(e->modifiers() & Qt::ControlModifier);
+ return true;
+
+ case Qt::Key_PageUp:
+ m_currentIndex = 0;
+ break;
+
+ case Qt::Key_PageDown:
+ m_currentIndex = actions().count() - 1;
+ break;
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_F2:
+ e->accept();
+ enterEditMode();
+ return true; // no update
+
+ case Qt::Key_Escape:
+ e->ignore();
+ setFocus();
+ hide();
+ closeMenuChain();
+ return true;
+
+ case Qt::Key_Alt:
+ case Qt::Key_Shift:
+ case Qt::Key_Control:
+ e->ignore();
+ setFocus(); // FIXME: this is because some other widget get the focus when CTRL is pressed
+ return true; // no update
+
+ default: {
+ QAction *action = currentAction();
+ if (!action || action->isSeparator() || action == m_addSeparator) {
+ e->ignore();
+ return true;
+ } else if (!e->text().isEmpty() && e->text().at(0).toLatin1() >= 32) {
+ showLineEdit();
+ QApplication::sendEvent(m_editor, e);
+ e->accept();
+ } else {
+ e->ignore();
+ }
+ }
+ return true;
+ }
+ } else if (m_editor->hasFocus()) { // In edit mode
+ switch (e->key()) {
+ default:
+ e->ignore();
+ return false;
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ if (!m_editor->text().isEmpty()) {
+ leaveEditMode(ForceAccept);
+ m_editor->hide();
+ setFocus();
+ moveDown(false);
+ break;
+ }
+ // fall through
+
+ case Qt::Key_Escape:
+ m_editor->hide();
+ setFocus();
+ break;
+ }
+ }
+
+ e->accept();
+ update();
+
+ return true;
+}
+
+static void sendMouseEventTo(QWidget *target, const QPoint &targetPoint, const QMouseEvent *event)
+{
+ QMouseEvent e(event->type(), targetPoint, event->globalPos(), event->button(), event->buttons(), event->modifiers());
+ QApplication::sendEvent(target, &e);
+}
+
+bool QDesignerMenu::handleMouseDoubleClickEvent(QWidget *, QMouseEvent *event)
+{
+ event->accept();
+ m_startPosition = QPoint();
+
+ if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton)
+ return true;
+
+ if (!rect().contains(event->pos())) {
+ // special case for menubar
+ QWidget *target = QApplication::widgetAt(event->globalPos());
+ QMenuBar *mb = qobject_cast<QMenuBar*>(target);
+ QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(target);
+ if (mb != 0 || menu != 0) {
+ const QPoint pt = target->mapFromGlobal(event->globalPos());
+ QAction *action = mb == 0 ? menu->actionAt(pt) : mb->actionAt(pt);
+ if (action)
+ sendMouseEventTo(target, pt, event);
+ }
+ return true;
+ }
+
+ m_currentIndex = findAction(event->pos());
+ QAction *action = safeActionAt(m_currentIndex);
+
+ QRect pm_rect;
+ if (action->menu() || hasSubMenuPixmap(action)) {
+ pm_rect = subMenuPixmapRect(action);
+ extendClickableArea(&pm_rect, layoutDirection());
+ }
+
+ if (!pm_rect.contains(event->pos()) && m_currentIndex != -1)
+ enterEditMode();
+
+ return true;
+}
+
+bool QDesignerMenu::handleMousePressEvent(QWidget * /*widget*/, QMouseEvent *event)
+{
+ if (!rect().contains(event->pos())) {
+ QWidget *clickedWidget = QApplication::widgetAt(event->globalPos());
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(clickedWidget)) {
+ const QPoint pt = mb->mapFromGlobal(event->globalPos());
+ if (QAction *action = mb->actionAt(pt)) {
+ QMenu * menu = action->menu();
+ if (menu == findRootMenu()) {
+ // propagate the mouse press event (but don't close the popup)
+ sendMouseEventTo(mb, pt, event);
+ return true;
+ }
+ }
+ }
+
+ if (QDesignerMenu *m = qobject_cast<QDesignerMenu *>(clickedWidget)) {
+ m->hideSubMenu();
+ sendMouseEventTo(m, m->mapFromGlobal(event->globalPos()), event);
+ } else {
+ QDesignerMenu *root = findRootMenu();
+ root->hide();
+ root->hideSubMenu();
+ }
+ if (clickedWidget) {
+ if (QWidget *focusProxy = clickedWidget->focusProxy())
+ clickedWidget = focusProxy;
+ if (clickedWidget->focusPolicy() != Qt::NoFocus)
+ clickedWidget->setFocus(Qt::OtherFocusReason);
+ }
+ return true;
+ }
+
+ m_showSubMenuTimer->stop();
+ m_startPosition = QPoint();
+ event->accept();
+
+ if (event->button() != Qt::LeftButton)
+ return true;
+
+ m_startPosition = mapFromGlobal(event->globalPos());
+
+ const int index = findAction(m_startPosition);
+
+ QAction *action = safeActionAt(index);
+ QRect pm_rect = subMenuPixmapRect(action);
+ extendClickableArea(&pm_rect, layoutDirection());
+
+ const int old_index = m_currentIndex;
+ m_currentIndex = index;
+ if ((hasSubMenuPixmap(action) || action->menu() != 0)
+ && pm_rect.contains(m_startPosition)) {
+ if (m_currentIndex == m_lastSubMenuIndex) {
+ hideSubMenu();
+ } else
+ slotShowSubMenuNow();
+ } else {
+ if (index == old_index) {
+ if (m_currentIndex == m_lastSubMenuIndex)
+ hideSubMenu();
+ } else {
+ hideSubMenu();
+ }
+ }
+
+ update();
+ if (index != old_index)
+ selectCurrentAction();
+
+ return true;
+}
+
+bool QDesignerMenu::handleMouseReleaseEvent(QWidget *, QMouseEvent *event)
+{
+ event->accept();
+ m_startPosition = QPoint();
+
+ return true;
+}
+
+bool QDesignerMenu::handleMouseMoveEvent(QWidget *, QMouseEvent *event)
+{
+ if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton)
+ return true;
+
+ if (!rect().contains(event->pos())) {
+
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(QApplication::widgetAt(event->globalPos()))) {
+ const QPoint pt = mb->mapFromGlobal(event->globalPos());
+ QAction *action = mb->actionAt(pt);
+ if (action && action->menu() == findRootMenu()) {
+ // propagate the mouse press event (but don't close the popup)
+ sendMouseEventTo(mb, pt, event);
+ return true;
+ }
+ // hide the popup Qt will replay the event
+ slotDeactivateNow();
+ }
+ return true;
+ }
+
+ if (m_startPosition.isNull())
+ return true;
+
+ event->accept();
+
+ const QPoint pos = mapFromGlobal(event->globalPos());
+
+ if ((pos - m_startPosition).manhattanLength() < qApp->startDragDistance())
+ return true;
+
+ startDrag(m_startPosition, event->modifiers());
+ m_startPosition = QPoint();
+
+ return true;
+}
+
+bool QDesignerMenu::handleContextMenuEvent(QWidget *, QContextMenuEvent *event)
+{
+ event->accept();
+
+ const int index = findAction(mapFromGlobal(event->globalPos()));
+ QAction *action = safeActionAt(index);
+ if (qobject_cast<SpecialMenuAction*>(action))
+ return true;
+
+ QMenu menu;
+ QVariant itemData;
+ itemData.setValue(action);
+
+ QAction *addSeparatorAction = menu.addAction(tr("Insert separator"));
+ addSeparatorAction->setData(itemData);
+
+ QAction *removeAction = 0;
+ if (action->isSeparator())
+ removeAction = menu.addAction(tr("Remove separator"));
+ else
+ removeAction = menu.addAction(tr("Remove action '%1'").arg(action->objectName()));
+ removeAction->setData(itemData);
+
+ connect(addSeparatorAction, SIGNAL(triggered(bool)), this, SLOT(slotAddSeparator()));
+ connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(slotRemoveSelectedAction()));
+ menu.exec(event->globalPos());
+
+ return true;
+}
+
+void QDesignerMenu::slotAddSeparator()
+{
+ QAction *action = qobject_cast<QAction *>(sender());
+ if (!action)
+ return;
+
+ QAction *a = qvariant_cast<QAction*>(action->data());
+ Q_ASSERT(a != 0);
+
+ const int pos = actions().indexOf(a);
+ QAction *action_before = 0;
+ if (pos != -1)
+ action_before = safeActionAt(pos);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ fw->beginCommand(tr("Add separator"));
+ QAction *sep = createAction(QString(), true);
+
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(this, sep, action_before);
+ fw->commandHistory()->push(cmd);
+
+ if (parentMenu()) {
+ QAction *parent_action = parentMenu()->currentAction();
+ if (parent_action->menu() == 0) {
+ CreateSubmenuCommand *cmd = new CreateSubmenuCommand(fw);
+ cmd->init(parentMenu(), parentMenu()->currentAction());
+ fw->commandHistory()->push(cmd);
+ }
+ }
+
+ fw->endCommand();
+}
+
+void QDesignerMenu::slotRemoveSelectedAction()
+{
+ if (QAction *action = qobject_cast<QAction *>(sender()))
+ if (QAction *a = qvariant_cast<QAction*>(action->data()))
+ deleteAction(a);
+}
+
+void QDesignerMenu::deleteAction(QAction *a)
+{
+ const int pos = actions().indexOf(a);
+ QAction *action_before = 0;
+ if (pos != -1)
+ action_before = safeActionAt(pos + 1);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw);
+ cmd->init(this, a, action_before);
+ fw->commandHistory()->push(cmd);
+}
+
+QRect QDesignerMenu::subMenuPixmapRect(QAction *action) const
+{
+ const QRect g = actionGeometry(action);
+ const int x = layoutDirection() == Qt::LeftToRight ? (g.right() - m_subMenuPixmap.width() - 2) : 2;
+ const int y = g.top() + (g.height() - m_subMenuPixmap.height())/2 + 1;
+ return QRect(x, y, m_subMenuPixmap.width(), m_subMenuPixmap.height());
+}
+
+bool QDesignerMenu::hasSubMenuPixmap(QAction *action) const
+{
+ return action != 0
+ && qobject_cast<SpecialMenuAction*>(action) == 0
+ && !action->isSeparator()
+ && !action->menu()
+ && canCreateSubMenu(action);
+}
+
+void QDesignerMenu::showEvent ( QShowEvent * event )
+{
+ selectCurrentAction();
+ QMenu::showEvent (event);
+}
+
+void QDesignerMenu::paintEvent(QPaintEvent *event)
+{
+ QMenu::paintEvent(event);
+
+ QPainter p(this);
+
+ QAction *current = currentAction();
+
+ foreach (QAction *a, actions()) {
+ const QRect g = actionGeometry(a);
+
+ if (qobject_cast<SpecialMenuAction*>(a)) {
+ QLinearGradient lg(g.left(), g.top(), g.left(), g.bottom());
+ lg.setColorAt(0.0, Qt::transparent);
+ lg.setColorAt(0.7, QColor(0, 0, 0, 32));
+ lg.setColorAt(1.0, Qt::transparent);
+
+ p.fillRect(g, lg);
+ } else if (hasSubMenuPixmap(a)) {
+ p.drawPixmap(subMenuPixmapRect(a).topLeft(), m_subMenuPixmap);
+ }
+ }
+
+ if (!hasFocus() || !current || m_dragging)
+ return;
+
+ if (QDesignerMenu *menu = parentMenu()) {
+ if (menu->dragging())
+ return;
+ }
+
+ if (QDesignerMenuBar *menubar = qobject_cast<QDesignerMenuBar*>(parentWidget())) {
+ if (menubar->dragging())
+ return;
+ }
+
+ const QRect g = actionGeometry(current);
+ drawSelection(&p, g.adjusted(1, 1, -3, -3));
+}
+
+bool QDesignerMenu::dragging() const
+{
+ return m_dragging;
+}
+
+QDesignerMenu *QDesignerMenu::findRootMenu() const
+{
+ if (parentMenu())
+ return parentMenu()->findRootMenu();
+
+ return const_cast<QDesignerMenu*>(this);
+}
+
+QDesignerMenu *QDesignerMenu::findActivatedMenu() const
+{
+ QList<QDesignerMenu*> candidates;
+ candidates.append(const_cast<QDesignerMenu*>(this));
+ candidates += findChildren<QDesignerMenu*>();
+
+ foreach (QDesignerMenu *m, candidates) {
+ if (m == qApp->activeWindow())
+ return m;
+ }
+
+ return 0;
+}
+
+bool QDesignerMenu::eventFilter(QObject *object, QEvent *event)
+{
+ if (object != this && object != m_editor) {
+ return false;
+ }
+
+ if (!m_editor->isHidden() && object == m_editor && event->type() == QEvent::FocusOut) {
+ leaveEditMode(Default);
+ m_editor->hide();
+ update();
+ return false;
+ }
+
+ bool dispatch = true;
+
+ switch (event->type()) {
+ default: break;
+
+ case QEvent::WindowDeactivate:
+ deactivateMenu();
+ break;
+ case QEvent::ContextMenu:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+
+ while (QApplication::activePopupWidget() && !qobject_cast<QDesignerMenu*>(QApplication::activePopupWidget())) {
+ QApplication::activePopupWidget()->close();
+ }
+
+ // fall through
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ dispatch = (object != m_editor);
+ // no break
+
+ case QEvent::Enter:
+ case QEvent::Leave:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ if (dispatch)
+ if (QWidget *widget = qobject_cast<QWidget*>(object))
+ if (widget == this || isAncestorOf(widget))
+ return handleEvent(widget, event);
+ break;
+ }
+
+ return false;
+};
+
+int QDesignerMenu::findAction(const QPoint &pos) const
+{
+ const int index = actionIndexAt(this, pos, Qt::Vertical);
+ if (index == -1)
+ return realActionCount();
+
+ return index;
+}
+
+void QDesignerMenu::adjustIndicator(const QPoint &pos)
+{
+ if (QDesignerActionProviderExtension *a = actionProvider()) {
+ a->adjustIndicator(pos);
+ }
+}
+
+QDesignerMenu::ActionDragCheck QDesignerMenu::checkAction(QAction *action) const
+{
+ if (!action || (action->menu() && action->menu()->parentWidget() != const_cast<QDesignerMenu*>(this)))
+ return NoActionDrag; // menu action!! nothing to do
+
+ if (!Utils::isObjectAncestorOf(formWindow()->mainContainer(), action))
+ return NoActionDrag; // the action belongs to another form window
+
+ if (actions().contains(action))
+ return ActionDragOnSubMenu; // we already have the action in the menu
+
+ return AcceptActionDrag;
+}
+
+void QDesignerMenu::dragEnterEvent(QDragEnterEvent *event)
+{
+ const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
+ if (!d || d->actionList().empty()) {
+ event->ignore();
+ return;
+ }
+
+ QAction *action = d->actionList().first();
+
+ switch (checkAction(action)) {
+ case NoActionDrag:
+ event->ignore();
+ break;
+ case ActionDragOnSubMenu:
+ d->accept(event);
+ m_dragging = true;
+ break;
+ case AcceptActionDrag:
+ d->accept(event);
+ m_dragging = true;
+ adjustIndicator(event->pos());
+ break;
+ }
+}
+
+void QDesignerMenu::dragMoveEvent(QDragMoveEvent *event)
+{
+ if (actionGeometry(m_addSeparator).contains(event->pos())) {
+ event->ignore();
+ adjustIndicator(QPoint(-1, -1));
+ return;
+ }
+
+ const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
+ if (!d || d->actionList().empty()) {
+ event->ignore();
+ return;
+ }
+
+ QAction *action = d->actionList().first();
+ const ActionDragCheck dc = checkAction(action);
+ switch (dc) {
+ case NoActionDrag:
+ event->ignore();
+ break;
+ case ActionDragOnSubMenu:
+ case AcceptActionDrag: { // Do not pop up submenu of action being dragged
+ const int newIndex = findAction(event->pos());
+ if (safeActionAt(newIndex) != action) {
+ m_currentIndex = newIndex;
+ if (m_lastSubMenuIndex != m_currentIndex)
+ m_showSubMenuTimer->start(300);
+ }
+ if (dc == AcceptActionDrag) {
+ adjustIndicator(event->pos());
+ d->accept(event);
+ } else {
+ event->ignore();
+ }
+ }
+ break;
+ }
+}
+
+void QDesignerMenu::dragLeaveEvent(QDragLeaveEvent *)
+{
+ m_dragging = false;
+ adjustIndicator(QPoint(-1, -1));
+ m_showSubMenuTimer->stop();
+}
+
+void QDesignerMenu::dropEvent(QDropEvent *event)
+{
+ m_showSubMenuTimer->stop();
+ hideSubMenu();
+ m_dragging = false;
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
+ if (!d || d->actionList().empty()) {
+ event->ignore();
+ return;
+ }
+ QAction *action = d->actionList().first();
+ if (action && checkAction(action) == AcceptActionDrag) {
+ event->acceptProposedAction();
+ int index = findAction(event->pos());
+ index = qMin(index, actions().count() - 1);
+
+ fw->beginCommand(tr("Insert action"));
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(this, action, safeActionAt(index));
+ fw->commandHistory()->push(cmd);
+
+ m_currentIndex = index;
+
+ if (parentMenu()) {
+ QAction *parent_action = parentMenu()->currentAction();
+ if (parent_action->menu() == 0) {
+ CreateSubmenuCommand *cmd = new CreateSubmenuCommand(fw);
+ cmd->init(parentMenu(), parentMenu()->currentAction(), action);
+ fw->commandHistory()->push(cmd);
+ }
+ }
+ update();
+ fw->endCommand();
+ } else {
+ event->ignore();
+ }
+ adjustIndicator(QPoint(-1, -1));
+}
+
+void QDesignerMenu::actionEvent(QActionEvent *event)
+{
+ QMenu::actionEvent(event);
+ m_adjustSizeTimer->start(0);
+}
+
+QDesignerFormWindowInterface *QDesignerMenu::formWindow() const
+{
+ if (parentMenu())
+ return parentMenu()->formWindow();
+
+ return QDesignerFormWindowInterface::findFormWindow(parentWidget());
+}
+
+QDesignerActionProviderExtension *QDesignerMenu::actionProvider()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ QDesignerFormEditorInterface *core = fw->core();
+ return qt_extension<QDesignerActionProviderExtension*>(core->extensionManager(), this);
+ }
+
+ return 0;
+}
+
+void QDesignerMenu::closeMenuChain()
+{
+ m_showSubMenuTimer->stop();
+
+ QWidget *w = this;
+ while (w && qobject_cast<QMenu*>(w))
+ w = w->parentWidget();
+
+ if (w) {
+ foreach (QMenu *subMenu, w->findChildren<QMenu*>()) {
+ subMenu->hide();
+ }
+ }
+
+ m_lastSubMenuIndex = -1;
+}
+
+// Close submenu using the left/right keys according to layoutDirection().
+// Return false to indicate the event must be propagated to the menu bar.
+bool QDesignerMenu::hideSubMenuOnCursorKey()
+{
+ if (parentMenu()) {
+ hide();
+ return true;
+ }
+ closeMenuChain();
+ update();
+ if (parentMenuBar())
+ return false;
+ return true;
+}
+
+// Open a submenu using the left/right keys according to layoutDirection().
+// Return false to indicate the event must be propagated to the menu bar.
+bool QDesignerMenu::showSubMenuOnCursorKey()
+{
+ const QAction *action = currentAction();
+
+ if (qobject_cast<const SpecialMenuAction*>(action) || action->isSeparator()) {
+ closeMenuChain();
+ if (parentMenuBar())
+ return false;
+ return true;
+ }
+ m_lastSubMenuIndex = -1; // force a refresh
+ slotShowSubMenuNow();
+ return true;
+}
+
+void QDesignerMenu::moveLeft()
+{
+ const bool handled = layoutDirection() == Qt::LeftToRight ?
+ hideSubMenuOnCursorKey() : showSubMenuOnCursorKey();
+ if (!handled)
+ parentMenuBar()->moveLeft();
+}
+
+void QDesignerMenu::moveRight()
+{
+ const bool handled = layoutDirection() == Qt::LeftToRight ?
+ showSubMenuOnCursorKey() : hideSubMenuOnCursorKey();
+ if (!handled)
+ parentMenuBar()->moveRight();
+}
+
+void QDesignerMenu::moveUp(bool ctrl)
+{
+ if (m_currentIndex == 0) {
+ hide();
+ return;
+ }
+
+ if (ctrl)
+ (void) swap(m_currentIndex, m_currentIndex - 1);
+ --m_currentIndex;
+ m_currentIndex = qMax(0, m_currentIndex);
+ // Always re-select, swapping destroys order
+ update();
+ selectCurrentAction();
+}
+
+void QDesignerMenu::moveDown(bool ctrl)
+{
+ if (m_currentIndex == actions().count() - 1) {
+ return;
+ }
+
+ if (ctrl)
+ (void) swap(m_currentIndex + 1, m_currentIndex);
+
+ ++m_currentIndex;
+ m_currentIndex = qMin(actions().count() - 1, m_currentIndex);
+ update();
+ if (!ctrl)
+ selectCurrentAction();
+}
+
+QAction *QDesignerMenu::currentAction() const
+{
+ if (m_currentIndex < 0 || m_currentIndex >= actions().count())
+ return 0;
+
+ return safeActionAt(m_currentIndex);
+}
+
+int QDesignerMenu::realActionCount() const
+{
+ return actions().count() - 2; // 2 fake actions
+}
+
+void QDesignerMenu::selectCurrentAction()
+{
+ QAction *action = currentAction();
+ if (!action || action == m_addSeparator || action == m_addItem)
+ return;
+
+ QDesignerObjectInspector *oi = 0;
+ if (QDesignerFormWindowInterface *fw = formWindow())
+ oi = qobject_cast<QDesignerObjectInspector *>(fw->core()->objectInspector());
+
+ if (!oi)
+ return;
+
+ oi->clearSelection();
+ if (QMenu *menu = action->menu())
+ oi->selectObject(menu);
+ else
+ oi->selectObject(action);
+}
+
+void QDesignerMenu::createRealMenuAction(QAction *action)
+{
+ if (action->menu())
+ return; // nothing to do
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ QDesignerFormEditorInterface *core = formWindow()->core();
+
+ QDesignerMenu *menu = findOrCreateSubMenu(action);
+ m_subMenus.remove(action);
+
+ action->setMenu(menu);
+ menu->setTitle(action->text());
+
+ Q_ASSERT(fw);
+
+ core->widgetFactory()->initialize(menu);
+
+ const QString niceObjectName = ActionEditor::actionTextToName(menu->title(), QLatin1String("menu"));
+ menu->setObjectName(niceObjectName);
+
+ core->metaDataBase()->add(menu);
+ fw->ensureUniqueObjectName(menu);
+
+ QAction *menuAction = menu->menuAction();
+ core->metaDataBase()->add(menuAction);
+}
+
+void QDesignerMenu::removeRealMenu(QAction *action)
+{
+ QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(action->menu());
+ if (menu == 0)
+ return;
+ action->setMenu(0);
+ m_subMenus.insert(action, menu);
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ core->metaDataBase()->remove(menu);
+}
+
+QDesignerMenu *QDesignerMenu::findOrCreateSubMenu(QAction *action)
+{
+ if (action->menu())
+ return qobject_cast<QDesignerMenu*>(action->menu());
+
+ QDesignerMenu *menu = m_subMenus.value(action);
+ if (!menu) {
+ menu = new QDesignerMenu(this);
+ m_subMenus.insert(action, menu);
+ }
+
+ return menu;
+}
+
+bool QDesignerMenu::canCreateSubMenu(QAction *action) const // ### improve it's a bit too slow
+{
+ foreach (const QWidget *aw, action->associatedWidgets())
+ if (aw != this) {
+ if (const QMenu *m = qobject_cast<const QMenu *>(aw)) {
+ if (m->actions().contains(action))
+ return false; // sorry
+ } else {
+ if (const QToolBar *tb = qobject_cast<const QToolBar *>(aw))
+ if (tb->actions().contains(action))
+ return false; // sorry
+ }
+ }
+ return true;
+}
+
+void QDesignerMenu::slotShowSubMenuNow()
+{
+ m_showSubMenuTimer->stop();
+
+ if (m_lastSubMenuIndex == m_currentIndex)
+ return;
+
+ if (m_lastSubMenuIndex != -1)
+ hideSubMenu();
+
+ if (m_currentIndex >= realActionCount())
+ return;
+
+ QAction *action = currentAction();
+
+ if (action->isSeparator() || !canCreateSubMenu(action))
+ return;
+
+ if (QMenu *menu = findOrCreateSubMenu(action)) {
+ if (!menu->isVisible()) {
+ if ((menu->windowFlags() & Qt::Popup) != Qt::Popup)
+ menu->setWindowFlags(Qt::Popup);
+ const QRect g = actionGeometry(action);
+ if (layoutDirection() == Qt::LeftToRight) {
+ menu->move(mapToGlobal(g.topRight()));
+ } else {
+ // The position is not initially correct due to the unknown width,
+ // causing it to overlap a bit the first time it is invoked.
+ const QSize menuSize = menu->size();
+ QPoint point = g.topLeft() - QPoint(menu->width() + 10, 0);
+ menu->move(mapToGlobal(point));
+ }
+ menu->show();
+ menu->setFocus();
+ } else {
+ menu->raise();
+ }
+ menu->setFocus();
+
+ m_lastSubMenuIndex = m_currentIndex;
+ }
+}
+
+void QDesignerMenu::showSubMenu(QAction *action)
+{
+ m_showSubMenuTimer->stop();
+
+ if (m_editor->isVisible() || !action || qobject_cast<SpecialMenuAction*>(action)
+ || action->isSeparator() || !isVisible())
+ return;
+
+ m_showSubMenuTimer->start(300);
+}
+
+QDesignerMenu *QDesignerMenu::parentMenu() const
+{
+ return qobject_cast<QDesignerMenu*>(parentWidget());
+}
+
+QDesignerMenuBar *QDesignerMenu::parentMenuBar() const
+{
+ if (QDesignerMenuBar *mb = qobject_cast<QDesignerMenuBar*>(parentWidget())) {
+ return mb;
+ } else if (QDesignerMenu *m = parentMenu()) {
+ return m->parentMenuBar();
+ }
+
+ return 0;
+}
+
+void QDesignerMenu::setVisible(bool visible)
+{
+ if (visible)
+ m_currentIndex = 0;
+ else
+ m_lastSubMenuIndex = -1;
+
+ QMenu::setVisible(visible);
+
+}
+
+void QDesignerMenu::adjustSpecialActions()
+{
+ removeAction(m_addItem);
+ removeAction(m_addSeparator);
+ addAction(m_addItem);
+ addAction(m_addSeparator);
+}
+
+bool QDesignerMenu::interactive(bool i)
+{
+ const bool old = m_interactive;
+ m_interactive = i;
+ return old;
+}
+
+void QDesignerMenu::enterEditMode()
+{
+ if (m_currentIndex >= 0 && m_currentIndex <= realActionCount()) {
+ showLineEdit();
+ } else {
+ hideSubMenu();
+ QDesignerFormWindowInterface *fw = formWindow();
+ fw->beginCommand(tr("Add separator"));
+ QAction *sep = createAction(QString(), true);
+
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(this, sep, safeActionAt(realActionCount()));
+ fw->commandHistory()->push(cmd);
+
+ if (parentMenu()) {
+ QAction *parent_action = parentMenu()->currentAction();
+ if (parent_action->menu() == 0) {
+ CreateSubmenuCommand *cmd = new CreateSubmenuCommand(fw);
+ cmd->init(parentMenu(), parentMenu()->currentAction());
+ fw->commandHistory()->push(cmd);
+ }
+ }
+
+ fw->endCommand();
+
+ m_currentIndex = actions().indexOf(m_addItem);
+ update();
+ }
+}
+
+void QDesignerMenu::leaveEditMode(LeaveEditMode mode)
+{
+ if (mode == Default)
+ return;
+
+ QAction *action = 0;
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (m_currentIndex < realActionCount()) {
+ action = safeActionAt(m_currentIndex);
+ fw->beginCommand(QApplication::translate("Command", "Set action text"));
+ } else {
+ Q_ASSERT(fw != 0);
+ fw->beginCommand(QApplication::translate("Command", "Insert action"));
+ action = createAction(ActionEditor::actionTextToName(m_editor->text()));
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(this, action, currentAction());
+ fw->commandHistory()->push(cmd);
+ }
+
+ SetPropertyCommand *cmd = new SetPropertyCommand(fw);
+ cmd->init(action, QLatin1String("text"), m_editor->text());
+ fw->commandHistory()->push(cmd);
+
+ if (parentMenu()) {
+ QAction *parent_action = parentMenu()->currentAction();
+ if (parent_action->menu() == 0) {
+ CreateSubmenuCommand *cmd = new CreateSubmenuCommand(fw);
+ cmd->init(parentMenu(), parentMenu()->currentAction(), action);
+ fw->commandHistory()->push(cmd);
+ }
+ }
+
+ update();
+ fw->endCommand();
+}
+
+QAction *QDesignerMenu::safeMenuAction(QDesignerMenu *menu) const
+{
+ QAction *action = menu->menuAction();
+
+ if (!action)
+ action = m_subMenus.key(menu);
+
+ return action;
+}
+
+void QDesignerMenu::showLineEdit()
+{
+ m_showSubMenuTimer->stop();
+
+ QAction *action = 0;
+
+ if (m_currentIndex < realActionCount())
+ action = safeActionAt(m_currentIndex);
+ else
+ action = m_addItem;
+
+ if (action->isSeparator())
+ return;
+
+ hideSubMenu();
+
+ // open edit field for item name
+ setFocus();
+
+ const QString text = action != m_addItem ? action->text() : QString();
+ m_editor->setText(text);
+ m_editor->selectAll();
+ m_editor->setGeometry(actionGeometry(action).adjusted(1, 1, -2, -2));
+ m_editor->show();
+ m_editor->setFocus();
+}
+
+QAction *QDesignerMenu::createAction(const QString &objectName, bool separator)
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ Q_ASSERT(fw);
+ return ToolBarEventFilter::createAction(fw, objectName, separator);
+}
+
+// ### share with QDesignerMenu::swap
+bool QDesignerMenu::swap(int a, int b)
+{
+ const int left = qMin(a, b);
+ int right = qMax(a, b);
+
+ QAction *action_a = safeActionAt(left);
+ QAction *action_b = safeActionAt(right);
+
+ if (action_a == action_b
+ || !action_a
+ || !action_b
+ || qobject_cast<SpecialMenuAction*>(action_a)
+ || qobject_cast<SpecialMenuAction*>(action_b))
+ return false; // nothing to do
+
+ right = qMin(right, realActionCount());
+ if (right < 0)
+ return false; // nothing to do
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ fw->beginCommand(QApplication::translate("Command", "Move action"));
+
+ QAction *action_b_before = safeActionAt(right + 1);
+
+ RemoveActionFromCommand *cmd1 = new RemoveActionFromCommand(fw);
+ cmd1->init(this, action_b, action_b_before, false);
+ fw->commandHistory()->push(cmd1);
+
+ QAction *action_a_before = safeActionAt(left + 1);
+
+ InsertActionIntoCommand *cmd2 = new InsertActionIntoCommand(fw);
+ cmd2->init(this, action_b, action_a_before, false);
+ fw->commandHistory()->push(cmd2);
+
+ RemoveActionFromCommand *cmd3 = new RemoveActionFromCommand(fw);
+ cmd3->init(this, action_a, action_b, false);
+ fw->commandHistory()->push(cmd3);
+
+ InsertActionIntoCommand *cmd4 = new InsertActionIntoCommand(fw);
+ cmd4->init(this, action_a, action_b_before, true);
+ fw->commandHistory()->push(cmd4);
+
+ fw->endCommand();
+
+ return true;
+}
+
+QAction *QDesignerMenu::safeActionAt(int index) const
+{
+ if (index < 0 || index >= actions().count())
+ return 0;
+
+ return actions().at(index);
+}
+
+void QDesignerMenu::hideSubMenu()
+{
+ m_lastSubMenuIndex = -1;
+ foreach (QMenu *subMenu, findChildren<QMenu*>()) {
+ subMenu->hide();
+ }
+}
+
+void QDesignerMenu::deleteAction()
+{
+ QAction *action = currentAction();
+ const int pos = actions().indexOf(action);
+ QAction *action_before = 0;
+ if (pos != -1)
+ action_before = safeActionAt(pos + 1);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw);
+ cmd->init(this, action, action_before);
+ fw->commandHistory()->push(cmd);
+
+ update();
+}
+
+void QDesignerMenu::deactivateMenu()
+{
+ m_deactivateWindowTimer->start(10);
+}
+
+void QDesignerMenu::slotDeactivateNow()
+{
+ m_deactivateWindowTimer->stop();
+
+ if (m_dragging)
+ return;
+
+ QDesignerMenu *root = findRootMenu();
+
+ if (! root->findActivatedMenu()) {
+ root->hide();
+ root->hideSubMenu();
+ }
+}
+
+void QDesignerMenu::drawSelection(QPainter *p, const QRect &r)
+{
+ p->save();
+
+ QColor c = Qt::blue;
+ p->setPen(QPen(c, 1));
+ c.setAlpha(32);
+ p->setBrush(c);
+ p->drawRect(r);
+
+ p->restore();
+}
+
+void QDesignerMenu::keyPressEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+void QDesignerMenu::keyReleaseEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_menu_p.h b/src/designer/src/lib/shared/qdesigner_menu_p.h
new file mode 100644
index 000000000..b88af7aac
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_menu_p.h
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_MENU_H
+#define QDESIGNER_MENU_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QAction>
+#include <QtGui/QMenu>
+#include <QtGui/QPixmap>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QTimer;
+class QLineEdit;
+
+class QDesignerFormWindowInterface;
+class QDesignerActionProviderExtension;
+class QDesignerMenu;
+class QDesignerMenuBar;
+class QPainter;
+class QMimeData;
+
+namespace qdesigner_internal {
+ class CreateSubmenuCommand;
+ class ActionInsertionCommand;
+}
+
+class QDESIGNER_SHARED_EXPORT QDesignerMenu: public QMenu
+{
+ Q_OBJECT
+public:
+ QDesignerMenu(QWidget *parent = 0);
+ virtual ~QDesignerMenu();
+
+ bool eventFilter(QObject *object, QEvent *event);
+
+ QDesignerFormWindowInterface *formWindow() const;
+ QDesignerActionProviderExtension *actionProvider();
+
+ QDesignerMenu *parentMenu() const;
+ QDesignerMenuBar *parentMenuBar() const;
+
+ virtual void setVisible(bool visible);
+
+ void adjustSpecialActions();
+
+ bool interactive(bool i);
+ void createRealMenuAction(QAction *action);
+ void removeRealMenu(QAction *action);
+
+ static void drawSelection(QPainter *p, const QRect &r);
+
+ bool dragging() const;
+
+ void closeMenuChain();
+
+ void moveLeft();
+ void moveRight();
+ void moveUp(bool ctrl);
+ void moveDown(bool ctrl);
+
+ // Helper for MenuTaskMenu extension
+ void deleteAction(QAction *a);
+
+private slots:
+ void slotAddSeparator();
+ void slotRemoveSelectedAction();
+ void slotShowSubMenuNow();
+ void slotDeactivateNow();
+ void slotAdjustSizeNow();
+
+protected:
+ virtual void actionEvent(QActionEvent *event);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dragMoveEvent(QDragMoveEvent *event);
+ virtual void dragLeaveEvent(QDragLeaveEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+ virtual void paintEvent(QPaintEvent *event);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void keyReleaseEvent(QKeyEvent *event);
+ virtual void showEvent(QShowEvent *event);
+
+ bool handleEvent(QWidget *widget, QEvent *event);
+ bool handleMouseDoubleClickEvent(QWidget *widget, QMouseEvent *event);
+ bool handleMousePressEvent(QWidget *widget, QMouseEvent *event);
+ bool handleMouseReleaseEvent(QWidget *widget, QMouseEvent *event);
+ bool handleMouseMoveEvent(QWidget *widget, QMouseEvent *event);
+ bool handleContextMenuEvent(QWidget *widget, QContextMenuEvent *event);
+ bool handleKeyPressEvent(QWidget *widget, QKeyEvent *event);
+
+ void startDrag(const QPoint &pos, Qt::KeyboardModifiers modifiers);
+
+ void adjustIndicator(const QPoint &pos);
+ int findAction(const QPoint &pos) const;
+
+ QAction *currentAction() const;
+ int realActionCount() const;
+ enum ActionDragCheck { NoActionDrag, ActionDragOnSubMenu, AcceptActionDrag };
+ ActionDragCheck checkAction(QAction *action) const;
+
+ void showSubMenu(QAction *action);
+
+ enum LeaveEditMode {
+ Default = 0,
+ ForceAccept
+ };
+
+ void enterEditMode();
+ void leaveEditMode(LeaveEditMode mode);
+ void showLineEdit();
+
+ QAction *createAction(const QString &text, bool separator = false);
+ QDesignerMenu *findOrCreateSubMenu(QAction *action);
+
+ QAction *safeActionAt(int index) const;
+ QAction *safeMenuAction(QDesignerMenu *menu) const;
+ bool swap(int a, int b);
+
+ void hideSubMenu();
+ void deleteAction();
+ void deactivateMenu();
+
+ bool canCreateSubMenu(QAction *action) const;
+ QDesignerMenu *findRootMenu() const;
+ QDesignerMenu *findActivatedMenu() const;
+
+ QRect subMenuPixmapRect(QAction *action) const;
+ bool hasSubMenuPixmap(QAction *action) const;
+
+ void selectCurrentAction();
+
+private:
+ bool hideSubMenuOnCursorKey();
+ bool showSubMenuOnCursorKey();
+ const QPixmap m_subMenuPixmap;
+
+ QPoint m_startPosition;
+ int m_currentIndex;
+ QAction *m_addItem;
+ QAction *m_addSeparator;
+ QHash<QAction*, QDesignerMenu*> m_subMenus;
+ QTimer *m_showSubMenuTimer;
+ QTimer *m_deactivateWindowTimer;
+ QTimer *m_adjustSizeTimer;
+ bool m_interactive;
+ QLineEdit *m_editor;
+ bool m_dragging;
+ int m_lastSubMenuIndex;
+
+ friend class qdesigner_internal::CreateSubmenuCommand;
+ friend class qdesigner_internal::ActionInsertionCommand;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_MENU_H
diff --git a/src/designer/src/lib/shared/qdesigner_menubar.cpp b/src/designer/src/lib/shared/qdesigner_menubar.cpp
new file mode 100644
index 000000000..534cf0cda
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_menubar.cpp
@@ -0,0 +1,979 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_menubar_p.h"
+#include "qdesigner_menu_p.h"
+#include "qdesigner_command_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "actionrepository_p.h"
+#include "actionprovider_p.h"
+#include "actioneditor_p.h"
+#include "qdesigner_utils_p.h"
+#include "promotiontaskmenu_p.h"
+#include "qdesigner_objectinspector_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QMimeData>
+
+#include <QtCore/qdebug.h>
+
+#include <QtGui/QApplication>
+#include <QtGui/QDrag>
+#include <QtGui/QLineEdit>
+#include <QtGui/QPainter>
+#include <QtGui/qevent.h>
+
+Q_DECLARE_METATYPE(QAction*)
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<QAction *> ActionList;
+
+using namespace qdesigner_internal;
+
+namespace qdesigner_internal
+{
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+SpecialMenuAction::SpecialMenuAction(QObject *parent)
+ : QAction(parent)
+{
+}
+
+SpecialMenuAction::~SpecialMenuAction()
+{
+}
+
+
+} // namespace qdesigner_internal
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+QDesignerMenuBar::QDesignerMenuBar(QWidget *parent) :
+ QMenuBar(parent),
+ m_addMenu(new SpecialMenuAction(this)),
+ m_currentIndex(0),
+ m_interactive(true),
+ m_editor(new QLineEdit(this)),
+ m_dragging(false),
+ m_lastMenuActionIndex( -1),
+ m_promotionTaskMenu(new PromotionTaskMenu(this, PromotionTaskMenu::ModeSingleWidget, this))
+{
+ setContextMenuPolicy(Qt::DefaultContextMenu);
+
+ setAcceptDrops(true); // ### fake
+ // Fake property: Keep the menu bar editable in the form even if a native menu bar is used.
+ setNativeMenuBar(false);
+
+ m_addMenu->setText(tr("Type Here"));
+ addAction(m_addMenu);
+
+ QFont italic;
+ italic.setItalic(true);
+ m_addMenu->setFont(italic);
+
+ m_editor->setObjectName(QLatin1String("__qt__passive_editor"));
+ m_editor->hide();
+ m_editor->installEventFilter(this);
+ installEventFilter(this);
+}
+
+QDesignerMenuBar::~QDesignerMenuBar()
+{
+}
+
+void QDesignerMenuBar::paintEvent(QPaintEvent *event)
+{
+ QMenuBar::paintEvent(event);
+
+ QPainter p(this);
+
+ foreach (QAction *a, actions()) {
+ if (qobject_cast<SpecialMenuAction*>(a)) {
+ const QRect g = actionGeometry(a);
+ QLinearGradient lg(g.left(), g.top(), g.left(), g.bottom());
+ lg.setColorAt(0.0, Qt::transparent);
+ lg.setColorAt(0.7, QColor(0, 0, 0, 32));
+ lg.setColorAt(1.0, Qt::transparent);
+
+ p.fillRect(g, lg);
+ }
+ }
+
+ QAction *action = currentAction();
+
+ if (m_dragging || !action)
+ return;
+
+ if (hasFocus()) {
+ const QRect g = actionGeometry(action);
+ QDesignerMenu::drawSelection(&p, g.adjusted(1, 1, -1, -1));
+ } else if (action->menu() && action->menu()->isVisible()) {
+ const QRect g = actionGeometry(action);
+ p.drawRect(g.adjusted(1, 1, -1, -1));
+ }
+}
+
+bool QDesignerMenuBar::handleEvent(QWidget *widget, QEvent *event)
+{
+ if (!formWindow())
+ return false;
+
+ if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
+ update();
+
+ switch (event->type()) {
+ default: break;
+
+ case QEvent::MouseButtonDblClick:
+ return handleMouseDoubleClickEvent(widget, static_cast<QMouseEvent*>(event));
+ case QEvent::MouseButtonPress:
+ return handleMousePressEvent(widget, static_cast<QMouseEvent*>(event));
+ case QEvent::MouseButtonRelease:
+ return handleMouseReleaseEvent(widget, static_cast<QMouseEvent*>(event));
+ case QEvent::MouseMove:
+ return handleMouseMoveEvent(widget, static_cast<QMouseEvent*>(event));
+ case QEvent::ContextMenu:
+ return handleContextMenuEvent(widget, static_cast<QContextMenuEvent*>(event));
+ case QEvent::KeyPress:
+ return handleKeyPressEvent(widget, static_cast<QKeyEvent*>(event));
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ return widget != m_editor;
+ }
+
+ return true;
+}
+
+bool QDesignerMenuBar::handleMouseDoubleClickEvent(QWidget *, QMouseEvent *event)
+{
+ if (!rect().contains(event->pos()))
+ return true;
+
+ if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton)
+ return true;
+
+ event->accept();
+
+ m_startPosition = QPoint();
+
+ m_currentIndex = actionIndexAt(this, event->pos(), Qt::Horizontal);
+ if (m_currentIndex != -1) {
+ showLineEdit();
+ }
+
+ return true;
+}
+
+bool QDesignerMenuBar::handleKeyPressEvent(QWidget *, QKeyEvent *e)
+{
+ if (m_editor->isHidden()) { // In navigation mode
+ switch (e->key()) {
+
+ case Qt::Key_Delete:
+ if (m_currentIndex == -1 || m_currentIndex >= realActionCount())
+ break;
+ hideMenu();
+ deleteMenu();
+ break;
+
+ case Qt::Key_Left:
+ e->accept();
+ moveLeft(e->modifiers() & Qt::ControlModifier);
+ return true;
+
+ case Qt::Key_Right:
+ e->accept();
+ moveRight(e->modifiers() & Qt::ControlModifier);
+ return true; // no update
+
+ case Qt::Key_Up:
+ e->accept();
+ moveUp();
+ return true;
+
+ case Qt::Key_Down:
+ e->accept();
+ moveDown();
+ return true;
+
+ case Qt::Key_PageUp:
+ m_currentIndex = 0;
+ break;
+
+ case Qt::Key_PageDown:
+ m_currentIndex = actions().count() - 1;
+ break;
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ e->accept();
+ enterEditMode();
+ return true; // no update
+
+ case Qt::Key_Alt:
+ case Qt::Key_Shift:
+ case Qt::Key_Control:
+ case Qt::Key_Escape:
+ e->ignore();
+ setFocus(); // FIXME: this is because some other widget get the focus when CTRL is pressed
+ return true; // no update
+
+ default:
+ if (!e->text().isEmpty() && e->text().at(0).toLatin1() >= 32) {
+ showLineEdit();
+ QApplication::sendEvent(m_editor, e);
+ e->accept();
+ } else {
+ e->ignore();
+ }
+ return true;
+ }
+ } else { // In edit mode
+ switch (e->key()) {
+ default:
+ return false;
+
+ case Qt::Key_Control:
+ e->ignore();
+ return true;
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ if (!m_editor->text().isEmpty()) {
+ leaveEditMode(ForceAccept);
+ if (m_lastFocusWidget)
+ m_lastFocusWidget->setFocus();
+
+ m_editor->hide();
+ showMenu();
+ break;
+ }
+ // fall through
+
+ case Qt::Key_Escape:
+ update();
+ setFocus();
+ break;
+ }
+ }
+
+ e->accept();
+ update();
+
+ return true;
+}
+
+void QDesignerMenuBar::startDrag(const QPoint &pos)
+{
+ const int index = findAction(pos);
+ if (m_currentIndex == -1 || index >= realActionCount())
+ return;
+
+ QAction *action = safeActionAt(index);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw);
+ cmd->init(this, action, actions().at(index + 1));
+ fw->commandHistory()->push(cmd);
+
+ adjustSize();
+
+ hideMenu(index);
+
+ QDrag *drag = new QDrag(this);
+ drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(action));
+ drag->setMimeData(new ActionRepositoryMimeData(action, Qt::MoveAction));
+
+ const int old_index = m_currentIndex;
+ m_currentIndex = -1;
+
+ if (drag->start(Qt::MoveAction) == Qt::IgnoreAction) {
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(this, action, safeActionAt(index));
+ fw->commandHistory()->push(cmd);
+
+ m_currentIndex = old_index;
+ adjustSize();
+ }
+}
+
+bool QDesignerMenuBar::handleMousePressEvent(QWidget *, QMouseEvent *event)
+{
+ m_startPosition = QPoint();
+ event->accept();
+
+ if (event->button() != Qt::LeftButton)
+ return true;
+
+ m_startPosition = event->pos();
+ const int newIndex = actionIndexAt(this, m_startPosition, Qt::Horizontal);
+ const bool changed = newIndex != m_currentIndex;
+ m_currentIndex = newIndex;
+ updateCurrentAction(changed);
+
+ return true;
+}
+
+bool QDesignerMenuBar::handleMouseReleaseEvent(QWidget *, QMouseEvent *event)
+{
+ m_startPosition = QPoint();
+
+ if (event->button() != Qt::LeftButton)
+ return true;
+
+ event->accept();
+ m_currentIndex = actionIndexAt(this, event->pos(), Qt::Horizontal);
+ if (!m_editor->isVisible() && m_currentIndex != -1 && m_currentIndex < realActionCount())
+ showMenu();
+
+ return true;
+}
+
+bool QDesignerMenuBar::handleMouseMoveEvent(QWidget *, QMouseEvent *event)
+{
+ if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton)
+ return true;
+
+ if (m_startPosition.isNull())
+ return true;
+
+ const QPoint pos = mapFromGlobal(event->globalPos());
+
+ if ((pos - m_startPosition).manhattanLength() < qApp->startDragDistance())
+ return true;
+
+ const int index = actionIndexAt(this, m_startPosition, Qt::Horizontal);
+ if (index < actions().count()) {
+ hideMenu(index);
+ update();
+ }
+
+ startDrag(m_startPosition);
+ m_startPosition = QPoint();
+
+ return true;
+}
+
+ActionList QDesignerMenuBar::contextMenuActions()
+{
+ ActionList rc;
+ if (QAction *action = safeActionAt(m_currentIndex)) {
+ if (!qobject_cast<SpecialMenuAction*>(action)) {
+ QVariant itemData;
+ itemData.setValue(action);
+
+ QAction *remove_action = new QAction(tr("Remove Menu '%1'").arg(action->menu()->objectName()), 0);
+ remove_action->setData(itemData);
+ connect(remove_action, SIGNAL(triggered()), this, SLOT(deleteMenu()));
+ rc.push_back(remove_action);
+ QAction *sep = new QAction(0);
+ sep->setSeparator(true);
+ rc.push_back(sep);
+ }
+ }
+
+ m_promotionTaskMenu->addActions(formWindow(), PromotionTaskMenu::TrailingSeparator, rc);
+
+ QAction *remove_menubar = new QAction(tr("Remove Menu Bar"), 0);
+ connect(remove_menubar, SIGNAL(triggered()), this, SLOT(slotRemoveMenuBar()));
+ rc.push_back(remove_menubar);
+ return rc;
+}
+
+bool QDesignerMenuBar::handleContextMenuEvent(QWidget *, QContextMenuEvent *event)
+{
+ event->accept();
+
+ m_currentIndex = actionIndexAt(this, mapFromGlobal(event->globalPos()), Qt::Horizontal);
+
+ update();
+
+ QMenu menu;
+ const ActionList al = contextMenuActions();
+ const ActionList::const_iterator acend = al.constEnd();
+ for (ActionList::const_iterator it = al.constBegin(); it != acend; ++it)
+ menu.addAction(*it);
+ menu.exec(event->globalPos());
+ return true;
+}
+
+void QDesignerMenuBar::slotRemoveMenuBar()
+{
+ Q_ASSERT(formWindow() != 0);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+
+ DeleteMenuBarCommand *cmd = new DeleteMenuBarCommand(fw);
+ cmd->init(this);
+ fw->commandHistory()->push(cmd);
+}
+
+void QDesignerMenuBar::focusOutEvent(QFocusEvent *event)
+{
+ QMenuBar::focusOutEvent(event);
+}
+
+void QDesignerMenuBar::enterEditMode()
+{
+ if (m_currentIndex >= 0 && m_currentIndex <= realActionCount()) {
+ showLineEdit();
+ }
+}
+
+void QDesignerMenuBar::leaveEditMode(LeaveEditMode mode)
+{
+ m_editor->releaseKeyboard();
+
+ if (mode == Default)
+ return;
+
+ if (m_editor->text().isEmpty())
+ return;
+
+ QAction *action = 0;
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ Q_ASSERT(fw);
+
+ if (m_currentIndex >= 0 && m_currentIndex < realActionCount()) {
+ action = safeActionAt(m_currentIndex);
+ fw->beginCommand(QApplication::translate("Command", "Change Title"));
+ } else {
+ fw->beginCommand(QApplication::translate("Command", "Insert Menu"));
+ const QString niceObjectName = ActionEditor::actionTextToName(m_editor->text(), QLatin1String("menu"));
+ QMenu *menu = qobject_cast<QMenu*>(fw->core()->widgetFactory()->createWidget(QLatin1String("QMenu"), this));
+ fw->core()->widgetFactory()->initialize(menu);
+ menu->setObjectName(niceObjectName);
+ menu->setTitle(tr("Menu"));
+ fw->ensureUniqueObjectName(menu);
+ action = menu->menuAction();
+ AddMenuActionCommand *cmd = new AddMenuActionCommand(fw);
+ cmd->init(action, m_addMenu, this, this);
+ fw->commandHistory()->push(cmd);
+ }
+
+ SetPropertyCommand *cmd = new SetPropertyCommand(fw);
+ cmd->init(action, QLatin1String("text"), m_editor->text());
+ fw->commandHistory()->push(cmd);
+ fw->endCommand();
+}
+
+void QDesignerMenuBar::showLineEdit()
+{
+ QAction *action = 0;
+
+ if (m_currentIndex >= 0 && m_currentIndex < realActionCount())
+ action = safeActionAt(m_currentIndex);
+ else
+ action = m_addMenu;
+
+ if (action->isSeparator())
+ return;
+
+ // hideMenu();
+
+ m_lastFocusWidget = qApp->focusWidget();
+
+ // open edit field for item name
+ const QString text = action != m_addMenu ? action->text() : QString();
+
+ m_editor->setText(text);
+ m_editor->selectAll();
+ m_editor->setGeometry(actionGeometry(action));
+ m_editor->show();
+ qApp->setActiveWindow(m_editor);
+ m_editor->setFocus();
+ m_editor->grabKeyboard();
+}
+
+bool QDesignerMenuBar::eventFilter(QObject *object, QEvent *event)
+{
+ if (object != this && object != m_editor)
+ return false;
+
+ if (!m_editor->isHidden() && object == m_editor && event->type() == QEvent::FocusOut) {
+ leaveEditMode(Default);
+ m_editor->hide();
+ update();
+ return true;
+ }
+
+ bool dispatch = true;
+
+ switch (event->type()) {
+ default: break;
+
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::ContextMenu:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ dispatch = (object != m_editor);
+ // no break
+
+ case QEvent::Enter:
+ case QEvent::Leave:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ {
+ QWidget *widget = qobject_cast<QWidget*>(object);
+
+ if (dispatch && widget && (widget == this || isAncestorOf(widget)))
+ return handleEvent(widget, event);
+ } break;
+
+ case QEvent::Shortcut:
+ event->accept();
+ return true;
+ }
+
+ return false;
+};
+
+int QDesignerMenuBar::findAction(const QPoint &pos) const
+{
+ const int index = actionIndexAt(this, pos, Qt::Horizontal);
+ if (index == -1)
+ return realActionCount();
+
+ return index;
+}
+
+void QDesignerMenuBar::adjustIndicator(const QPoint &pos)
+{
+ const int index = findAction(pos);
+ QAction *action = safeActionAt(index);
+ Q_ASSERT(action != 0);
+
+ if (pos != QPoint(-1, -1)) {
+ QDesignerMenu *m = qobject_cast<QDesignerMenu*>(action->menu());
+ if (!m || m->parentMenu()) {
+ m_currentIndex = index;
+ showMenu(index);
+ }
+ }
+
+ if (QDesignerActionProviderExtension *a = actionProvider()) {
+ a->adjustIndicator(pos);
+ }
+}
+
+QDesignerMenuBar::ActionDragCheck QDesignerMenuBar::checkAction(QAction *action) const
+{
+ // action belongs to another form
+ if (!action || !Utils::isObjectAncestorOf(formWindow()->mainContainer(), action))
+ return NoActionDrag;
+
+ if (!action->menu())
+ return ActionDragOnSubMenu; // simple action only on sub menus
+
+ QDesignerMenu *m = qobject_cast<QDesignerMenu*>(action->menu());
+ if (m && m->parentMenu())
+ return ActionDragOnSubMenu; // it looks like a submenu
+
+ if (actions().contains(action))
+ return ActionDragOnSubMenu; // we already have the action in the menubar
+
+ return AcceptActionDrag;
+}
+
+void QDesignerMenuBar::dragEnterEvent(QDragEnterEvent *event)
+{
+ const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
+ if (!d || d->actionList().empty()) {
+ event->ignore();
+ return;
+ }
+
+ QAction *action = d->actionList().first();
+ switch (checkAction(action)) {
+ case NoActionDrag:
+ event->ignore();
+ break;
+ case ActionDragOnSubMenu:
+ m_dragging = true;
+ d->accept(event);
+ break;
+ case AcceptActionDrag:
+ m_dragging = true;
+ d->accept(event);
+ adjustIndicator(event->pos());
+ break;
+ }
+}
+
+void QDesignerMenuBar::dragMoveEvent(QDragMoveEvent *event)
+{
+ const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
+ if (!d || d->actionList().empty()) {
+ event->ignore();
+ return;
+ }
+ QAction *action = d->actionList().first();
+
+ switch (checkAction(action)) {
+ case NoActionDrag:
+ event->ignore();
+ break;
+ case ActionDragOnSubMenu:
+ event->ignore();
+ showMenu(findAction(event->pos()));
+ break;
+ case AcceptActionDrag:
+ d->accept(event);
+ adjustIndicator(event->pos());
+ break;
+ }
+}
+
+void QDesignerMenuBar::dragLeaveEvent(QDragLeaveEvent *)
+{
+ m_dragging = false;
+
+ adjustIndicator(QPoint(-1, -1));
+}
+
+void QDesignerMenuBar::dropEvent(QDropEvent *event)
+{
+ m_dragging = false;
+
+ if (const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData())) {
+
+ QAction *action = d->actionList().first();
+ if (checkAction(action) == AcceptActionDrag) {
+ event->acceptProposedAction();
+ int index = findAction(event->pos());
+ index = qMin(index, actions().count() - 1);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(this, action, safeActionAt(index));
+ fw->commandHistory()->push(cmd);
+
+ m_currentIndex = index;
+ update();
+ adjustIndicator(QPoint(-1, -1));
+ return;
+ }
+ }
+ event->ignore();
+}
+
+void QDesignerMenuBar::actionEvent(QActionEvent *event)
+{
+ QMenuBar::actionEvent(event);
+}
+
+QDesignerFormWindowInterface *QDesignerMenuBar::formWindow() const
+{
+ return QDesignerFormWindowInterface::findFormWindow(const_cast<QDesignerMenuBar*>(this));
+}
+
+QDesignerActionProviderExtension *QDesignerMenuBar::actionProvider()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ QDesignerFormEditorInterface *core = fw->core();
+ return qt_extension<QDesignerActionProviderExtension*>(core->extensionManager(), this);
+ }
+
+ return 0;
+}
+
+QAction *QDesignerMenuBar::currentAction() const
+{
+ if (m_currentIndex < 0 || m_currentIndex >= actions().count())
+ return 0;
+
+ return safeActionAt(m_currentIndex);
+}
+
+int QDesignerMenuBar::realActionCount() const
+{
+ return actions().count() - 1; // 1 fake actions
+}
+
+bool QDesignerMenuBar::dragging() const
+{
+ return m_dragging;
+}
+
+void QDesignerMenuBar::moveLeft(bool ctrl)
+{
+ if (layoutDirection() == Qt::LeftToRight) {
+ movePrevious(ctrl);
+ } else {
+ moveNext(ctrl);
+ }
+}
+
+void QDesignerMenuBar::moveRight(bool ctrl)
+{
+ if (layoutDirection() == Qt::LeftToRight) {
+ moveNext(ctrl);
+ } else {
+ movePrevious(ctrl);
+ }
+}
+
+void QDesignerMenuBar::movePrevious(bool ctrl)
+{
+ const bool swapped = ctrl && swapActions(m_currentIndex, m_currentIndex - 1);
+ const int newIndex = qMax(0, m_currentIndex - 1);
+ // Always re-select, swapping destroys order
+ if (swapped || newIndex != m_currentIndex) {
+ m_currentIndex = newIndex;
+ updateCurrentAction(true);
+ }
+}
+
+void QDesignerMenuBar::moveNext(bool ctrl)
+{
+ const bool swapped = ctrl && swapActions(m_currentIndex + 1, m_currentIndex);
+ const int newIndex = qMin(actions().count() - 1, m_currentIndex + 1);
+ if (swapped || newIndex != m_currentIndex) {
+ m_currentIndex = newIndex;
+ updateCurrentAction(!ctrl);
+ }
+}
+
+void QDesignerMenuBar::moveUp()
+{
+ update();
+}
+
+void QDesignerMenuBar::moveDown()
+{
+ showMenu();
+}
+
+void QDesignerMenuBar::adjustSpecialActions()
+{
+ removeAction(m_addMenu);
+ addAction(m_addMenu);
+}
+
+bool QDesignerMenuBar::interactive(bool i)
+{
+ const bool old = m_interactive;
+ m_interactive = i;
+ return old;
+}
+
+void QDesignerMenuBar::hideMenu(int index)
+{
+ if (index < 0 && m_currentIndex >= 0)
+ index = m_currentIndex;
+
+ if (index < 0 || index >= realActionCount())
+ return;
+
+ QAction *action = safeActionAt(index);
+
+ if (action && action->menu()) {
+ action->menu()->hide();
+
+ if (QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(action->menu())) {
+ menu->closeMenuChain();
+ }
+ }
+}
+
+void QDesignerMenuBar::deleteMenu()
+{
+ deleteMenuAction(currentAction());
+}
+
+void QDesignerMenuBar::deleteMenuAction(QAction *action)
+{
+ if (action && !qobject_cast<SpecialMenuAction*>(action)) {
+ const int pos = actions().indexOf(action);
+ QAction *action_before = 0;
+ if (pos != -1)
+ action_before = safeActionAt(pos + 1);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ RemoveMenuActionCommand *cmd = new RemoveMenuActionCommand(fw);
+ cmd->init(action, action_before, this, this);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QDesignerMenuBar::showMenu(int index)
+{
+ if (index < 0 && m_currentIndex >= 0)
+ index = m_currentIndex;
+
+ if (index < 0 || index >= realActionCount())
+ return;
+
+ m_currentIndex = index;
+ QAction *action = currentAction();
+
+ if (action && action->menu()) {
+ if (m_lastMenuActionIndex != -1 && m_lastMenuActionIndex != index) {
+ hideMenu(m_lastMenuActionIndex);
+ }
+
+ m_lastMenuActionIndex = index;
+ QMenu *menu = action->menu();
+ const QRect g = actionGeometry(action);
+
+ if (!menu->isVisible()) {
+ if ((menu->windowFlags() & Qt::Popup) != Qt::Popup)
+ menu->setWindowFlags(Qt::Popup);
+ menu->adjustSize();
+ if (layoutDirection() == Qt::LeftToRight) {
+ menu->move(mapToGlobal(g.bottomLeft()));
+ } else {
+ // The position is not initially correct due to the unknown width,
+ // causing it to overlap a bit the first time it is invoked.
+ const QSize menuSize = menu->size();
+ QPoint point = g.bottomRight() - QPoint(menu->width(), 0);
+ menu->move(mapToGlobal(point));
+ }
+ menu->setFocus(Qt::MouseFocusReason);
+ menu->raise();
+ menu->show();
+ } else {
+ menu->raise();
+ }
+ }
+}
+
+QAction *QDesignerMenuBar::safeActionAt(int index) const
+{
+ if (index < 0 || index >= actions().count())
+ return 0;
+
+ return actions().at(index);
+}
+
+bool QDesignerMenuBar::swapActions(int a, int b)
+{
+ const int left = qMin(a, b);
+ int right = qMax(a, b);
+
+ QAction *action_a = safeActionAt(left);
+ QAction *action_b = safeActionAt(right);
+
+ if (action_a == action_b
+ || !action_a
+ || !action_b
+ || qobject_cast<SpecialMenuAction*>(action_a)
+ || qobject_cast<SpecialMenuAction*>(action_b))
+ return false; // nothing to do
+
+ right = qMin(right, realActionCount());
+ if (right < 0)
+ return false; // nothing to do
+
+ formWindow()->beginCommand(QApplication::translate("Command", "Move action"));
+
+ QAction *action_b_before = safeActionAt(right + 1);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ RemoveActionFromCommand *cmd1 = new RemoveActionFromCommand(fw);
+ cmd1->init(this, action_b, action_b_before, false);
+ fw->commandHistory()->push(cmd1);
+
+ QAction *action_a_before = safeActionAt(left + 1);
+
+ InsertActionIntoCommand *cmd2 = new InsertActionIntoCommand(fw);
+ cmd2->init(this, action_b, action_a_before, false);
+ fw->commandHistory()->push(cmd2);
+
+ RemoveActionFromCommand *cmd3 = new RemoveActionFromCommand(fw);
+ cmd3->init(this, action_a, action_b, false);
+ fw->commandHistory()->push(cmd3);
+
+ InsertActionIntoCommand *cmd4 = new InsertActionIntoCommand(fw);
+ cmd4->init(this, action_a, action_b_before, true);
+ fw->commandHistory()->push(cmd4);
+
+ fw->endCommand();
+
+ return true;
+}
+
+void QDesignerMenuBar::keyPressEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+void QDesignerMenuBar::keyReleaseEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+void QDesignerMenuBar::updateCurrentAction(bool selectAction)
+{
+ update();
+
+ if (!selectAction)
+ return;
+
+ QAction *action = currentAction();
+ if (!action || action == m_addMenu)
+ return;
+
+ QMenu *menu = action->menu();
+ if (!menu)
+ return;
+
+ QDesignerObjectInspector *oi = 0;
+ if (QDesignerFormWindowInterface *fw = formWindow())
+ oi = qobject_cast<QDesignerObjectInspector *>(fw->core()->objectInspector());
+
+ if (!oi)
+ return;
+
+ oi->clearSelection();
+ oi->selectObject(menu);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_menubar_p.h b/src/designer/src/lib/shared/qdesigner_menubar_p.h
new file mode 100644
index 000000000..8ca538559
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_menubar_p.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_MENUBAR_H
+#define QDESIGNER_MENUBAR_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QAction>
+#include <QtGui/QMenuBar>
+
+#include <QtCore/QPointer>
+#include <QtCore/QMimeData>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerActionProviderExtension;
+
+class QLineEdit;
+class QMimeData;
+
+namespace qdesigner_internal {
+class PromotionTaskMenu;
+
+class SpecialMenuAction: public QAction
+{
+ Q_OBJECT
+public:
+ SpecialMenuAction(QObject *parent = 0);
+ virtual ~SpecialMenuAction();
+};
+
+} // namespace qdesigner_internal
+
+class QDESIGNER_SHARED_EXPORT QDesignerMenuBar: public QMenuBar
+{
+ Q_OBJECT
+public:
+ QDesignerMenuBar(QWidget *parent = 0);
+ virtual ~QDesignerMenuBar();
+
+ bool eventFilter(QObject *object, QEvent *event);
+
+ QDesignerFormWindowInterface *formWindow() const;
+ QDesignerActionProviderExtension *actionProvider();
+
+ void adjustSpecialActions();
+ bool interactive(bool i);
+ bool dragging() const;
+
+ void moveLeft(bool ctrl = false);
+ void moveRight(bool ctrl = false);
+ void moveUp();
+ void moveDown();
+
+ // Helpers for MenuTaskMenu/MenuBarTaskMenu extensions
+ QList<QAction *> contextMenuActions();
+ void deleteMenuAction(QAction *action);
+
+private slots:
+ void deleteMenu();
+ void slotRemoveMenuBar();
+
+protected:
+ virtual void actionEvent(QActionEvent *event);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dragMoveEvent(QDragMoveEvent *event);
+ virtual void dragLeaveEvent(QDragLeaveEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+ virtual void paintEvent(QPaintEvent *event);
+ virtual void focusOutEvent(QFocusEvent *event);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void keyReleaseEvent(QKeyEvent *event);
+
+ bool handleEvent(QWidget *widget, QEvent *event);
+ bool handleMouseDoubleClickEvent(QWidget *widget, QMouseEvent *event);
+ bool handleMousePressEvent(QWidget *widget, QMouseEvent *event);
+ bool handleMouseReleaseEvent(QWidget *widget, QMouseEvent *event);
+ bool handleMouseMoveEvent(QWidget *widget, QMouseEvent *event);
+ bool handleContextMenuEvent(QWidget *widget, QContextMenuEvent *event);
+ bool handleKeyPressEvent(QWidget *widget, QKeyEvent *event);
+
+ void startDrag(const QPoint &pos);
+
+ enum ActionDragCheck { NoActionDrag, ActionDragOnSubMenu, AcceptActionDrag };
+ ActionDragCheck checkAction(QAction *action) const;
+
+ void adjustIndicator(const QPoint &pos);
+ int findAction(const QPoint &pos) const;
+
+ QAction *currentAction() const;
+ int realActionCount() const;
+
+ enum LeaveEditMode {
+ Default = 0,
+ ForceAccept
+ };
+
+ void enterEditMode();
+ void leaveEditMode(LeaveEditMode mode);
+ void showLineEdit();
+
+ void showMenu(int index = -1);
+ void hideMenu(int index = -1);
+
+ QAction *safeActionAt(int index) const;
+
+ bool swapActions(int a, int b);
+
+private:
+ void updateCurrentAction(bool selectAction);
+ void movePrevious(bool ctrl);
+ void moveNext(bool ctrl);
+
+ QAction *m_addMenu;
+ QPointer<QMenu> m_activeMenu;
+ QPoint m_startPosition;
+ int m_currentIndex;
+ bool m_interactive;
+ QLineEdit *m_editor;
+ bool m_dragging;
+ int m_lastMenuActionIndex;
+ QPointer<QWidget> m_lastFocusWidget;
+ qdesigner_internal::PromotionTaskMenu* m_promotionTaskMenu;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_MENUBAR_H
diff --git a/src/designer/src/lib/shared/qdesigner_objectinspector.cpp b/src/designer/src/lib/shared/qdesigner_objectinspector.cpp
new file mode 100644
index 000000000..314638c74
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_objectinspector.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_objectinspector_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QDesignerObjectInspector::QDesignerObjectInspector(QWidget *parent, Qt::WindowFlags flags) :
+ QDesignerObjectInspectorInterface(parent, flags)
+{
+}
+
+void QDesignerObjectInspector::mainContainerChanged()
+{
+}
+
+void Selection::clear()
+{
+ managed.clear();
+ unmanaged.clear();
+ objects.clear();
+}
+
+bool Selection::empty() const
+{
+ return managed.empty() && unmanaged.empty() && objects.empty();
+}
+
+QObjectList Selection::selection() const
+{
+ QObjectList rc(objects);
+ foreach (QObject* o, managed)
+ rc.push_back(o);
+ foreach (QObject* o, unmanaged)
+ rc.push_back(o);
+ return rc;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_objectinspector_p.h b/src/designer/src/lib/shared/qdesigner_objectinspector_p.h
new file mode 100644
index 000000000..9cc630ef6
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_objectinspector_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef DESIGNEROBJECTINSPECTOR_H
+#define DESIGNEROBJECTINSPECTOR_H
+
+#include "shared_global_p.h"
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerDnDItemInterface;
+
+namespace qdesigner_internal {
+
+struct QDESIGNER_SHARED_EXPORT Selection {
+ bool empty() const;
+ void clear();
+
+ // Merge all lists
+ QObjectList selection() const;
+
+ // Selection in cursor (managed widgets)
+ QWidgetList managed;
+ // Unmanaged widgets
+ QWidgetList unmanaged;
+ // Remaining selected objects (non-widgets)
+ QObjectList objects;
+};
+
+// Extends the QDesignerObjectInspectorInterface by functionality
+// to access the selection
+
+class QDESIGNER_SHARED_EXPORT QDesignerObjectInspector: public QDesignerObjectInspectorInterface
+{
+ Q_OBJECT
+public:
+ explicit QDesignerObjectInspector(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+
+ // Select a qobject unmanaged by form window
+ virtual bool selectObject(QObject *o) = 0;
+ virtual void getSelection(Selection &s) const = 0;
+ virtual void clearSelection() = 0;
+
+public slots:
+ virtual void mainContainerChanged();
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DESIGNEROBJECTINSPECTOR_H
diff --git a/src/designer/src/lib/shared/qdesigner_promotion.cpp b/src/designer/src/lib/shared/qdesigner_promotion.cpp
new file mode 100644
index 000000000..bf96b473b
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_promotion.cpp
@@ -0,0 +1,373 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_promotion_p.h"
+#include "widgetdatabase_p.h"
+#include "metadatabase_p.h"
+#include "widgetdatabase_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+
+#include <QtCore/QMap>
+#include <QtCore/QCoreApplication>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ // Return a set of on-promotable classes
+ const QSet<QString> &nonPromotableClasses() {
+ static QSet<QString> rc;
+ if (rc.empty()) {
+ rc.insert(QLatin1String("Line"));
+ rc.insert(QLatin1String("QAction"));
+ rc.insert(QLatin1String("Spacer"));
+ rc.insert(QLatin1String("QMainWindow"));
+ rc.insert(QLatin1String("QDialog"));
+ rc.insert(QLatin1String("QWorkspace"));
+ rc.insert(QLatin1String("QMdiArea"));
+ rc.insert(QLatin1String("QMdiSubWindow"));
+ }
+ return rc;
+ }
+
+ // Return widget database index of a promoted class or -1 with error message
+ int promotedWidgetDataBaseIndex(const QDesignerWidgetDataBaseInterface *widgetDataBase,
+ const QString &className,
+ QString *errorMessage) {
+ const int index = widgetDataBase->indexOfClassName(className);
+ if (index == -1 || !widgetDataBase->item(index)->isPromoted()) {
+ *errorMessage = QCoreApplication::tr("%1 is not a promoted class.").arg(className);
+ return -1;
+ }
+ return index;
+ }
+
+ // Return widget database item of a promoted class or 0 with error message
+ QDesignerWidgetDataBaseItemInterface *promotedWidgetDataBaseItem(const QDesignerWidgetDataBaseInterface *widgetDataBase,
+ const QString &className,
+ QString *errorMessage) {
+
+ const int index = promotedWidgetDataBaseIndex(widgetDataBase, className, errorMessage);
+ if (index == -1)
+ return 0;
+ return widgetDataBase->item(index);
+ }
+
+ // extract class name from xml "<widget class="QWidget" ...>". Quite a hack.
+ QString classNameFromXml(QString xml) {
+ static const QString tag = QLatin1String("class=\"");
+ const int pos = xml.indexOf(tag);
+ if (pos == -1)
+ return QString();
+ xml.remove(0, pos + tag.size());
+ const int closingPos = xml.indexOf(QLatin1Char('"'));
+ if (closingPos == -1)
+ return QString();
+ xml.remove(closingPos, xml.size() - closingPos);
+ return xml;
+ }
+
+ // return a list of class names in the scratch pad
+ QStringList getScratchPadClasses(const QDesignerWidgetBoxInterface *wb) {
+ QStringList rc;
+ const int catCount = wb->categoryCount();
+ for (int c = 0; c < catCount; c++) {
+ const QDesignerWidgetBoxInterface::Category category = wb->category(c);
+ if (category.type() == QDesignerWidgetBoxInterface::Category::Scratchpad) {
+ const int widgetCount = category.widgetCount();
+ for (int w = 0; w < widgetCount; w++) {
+ const QString className = classNameFromXml( category.widget(w).domXml());
+ if (!className.isEmpty())
+ rc += className;
+ }
+ }
+ }
+ return rc;
+ }
+}
+
+namespace qdesigner_internal {
+
+ QDesignerPromotion::QDesignerPromotion(QDesignerFormEditorInterface *core) :
+ m_core(core) {
+ }
+
+ bool QDesignerPromotion::addPromotedClass(const QString &baseClass,
+ const QString &className,
+ const QString &includeFile,
+ QString *errorMessage)
+ {
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
+ const int baseClassIndex = widgetDataBase->indexOfClassName(baseClass);
+
+ if (baseClassIndex == -1) {
+ *errorMessage = QCoreApplication::tr("The base class %1 is invalid.").arg(baseClass);
+ return false;
+ }
+
+ const int existingClassIndex = widgetDataBase->indexOfClassName(className);
+
+ if (existingClassIndex != -1) {
+ *errorMessage = QCoreApplication::tr("The class %1 already exists.").arg(className);
+ return false;
+ }
+ // Clone derived item.
+ QDesignerWidgetDataBaseItemInterface *promotedItem = WidgetDataBaseItem::clone(widgetDataBase->item(baseClassIndex));
+ // Also inherit the container flag in case of QWidget-derived classes
+ // as it is most likely intended for stacked pages.
+ // set new props
+ promotedItem->setName(className);
+ promotedItem->setGroup(QCoreApplication::tr("Promoted Widgets"));
+ promotedItem->setCustom(true);
+ promotedItem->setPromoted(true);
+ promotedItem->setExtends(baseClass);
+ promotedItem->setIncludeFile(includeFile);
+ widgetDataBase->append(promotedItem);
+ return true;
+ }
+
+ QList<QDesignerWidgetDataBaseItemInterface *> QDesignerPromotion::promotionBaseClasses() const
+ {
+ typedef QMap<QString, QDesignerWidgetDataBaseItemInterface *> SortedDatabaseItemMap;
+ SortedDatabaseItemMap sortedDatabaseItemMap;
+
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
+
+ const int cnt = widgetDataBase->count();
+ for (int i = 0; i < cnt; i++) {
+ QDesignerWidgetDataBaseItemInterface *dbItem = widgetDataBase->item(i);
+ if (canBePromoted(dbItem)) {
+ sortedDatabaseItemMap.insert(dbItem->name(), dbItem);
+ }
+ }
+
+ return sortedDatabaseItemMap.values();
+ }
+
+
+ bool QDesignerPromotion::canBePromoted(const QDesignerWidgetDataBaseItemInterface *dbItem) const
+ {
+ if (dbItem->isPromoted() || !dbItem->extends().isEmpty())
+ return false;
+
+ const QString name = dbItem->name();
+
+ if (nonPromotableClasses().contains(name))
+ return false;
+
+ if (name.startsWith(QLatin1String("QDesigner")) ||
+ name.startsWith(QLatin1String("QLayout")))
+ return false;
+
+ return true;
+ }
+
+ QDesignerPromotion::PromotedClasses QDesignerPromotion::promotedClasses() const
+ {
+ typedef QMap<QString, QDesignerWidgetDataBaseItemInterface *> ClassNameItemMap;
+ // A map containing base classes and their promoted classes.
+ typedef QMap<QString, ClassNameItemMap> BaseClassPromotedMap;
+
+ BaseClassPromotedMap baseClassPromotedMap;
+
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
+ // Look for promoted classes and insert into map according to base class.
+ const int cnt = widgetDataBase->count();
+ for (int i = 0; i < cnt; i++) {
+ QDesignerWidgetDataBaseItemInterface *dbItem = widgetDataBase->item(i);
+ if (dbItem->isPromoted()) {
+ const QString baseClassName = dbItem->extends();
+ BaseClassPromotedMap::iterator it = baseClassPromotedMap.find(baseClassName);
+ if (it == baseClassPromotedMap.end()) {
+ it = baseClassPromotedMap.insert(baseClassName, ClassNameItemMap());
+ }
+ it.value().insert(dbItem->name(), dbItem);
+ }
+ }
+ // convert map into list.
+ PromotedClasses rc;
+
+ if (baseClassPromotedMap.empty())
+ return rc;
+
+ const BaseClassPromotedMap::const_iterator bcend = baseClassPromotedMap.constEnd();
+ for (BaseClassPromotedMap::const_iterator bit = baseClassPromotedMap.constBegin(); bit != bcend; ++bit) {
+ const int baseIndex = widgetDataBase->indexOfClassName(bit.key());
+ Q_ASSERT(baseIndex >= 0);
+ QDesignerWidgetDataBaseItemInterface *baseItem = widgetDataBase->item(baseIndex);
+ // promoted
+ const ClassNameItemMap::const_iterator pcend = bit.value().constEnd();
+ for (ClassNameItemMap::const_iterator pit = bit.value().constBegin(); pit != pcend; ++pit) {
+ PromotedClass item;
+ item.baseItem = baseItem;
+ item.promotedItem = pit.value();
+ rc.push_back(item);
+ }
+ }
+
+ return rc;
+ }
+
+ QSet<QString> QDesignerPromotion::referencedPromotedClassNames() const {
+ QSet<QString> rc;
+ const MetaDataBase *metaDataBase = qobject_cast<const MetaDataBase*>(m_core->metaDataBase());
+ if (!metaDataBase)
+ return rc;
+
+ const QList<QObject*> objs = metaDataBase->objects();
+ const QList<QObject*>::const_iterator cend = objs.constEnd();
+ for ( QList<QObject*>::const_iterator it = objs.constBegin(); it != cend; ++it) {
+ const QString customClass = metaDataBase->metaDataBaseItem(*it)->customClassName();
+ if (!customClass.isEmpty())
+ rc.insert(customClass);
+
+ }
+ // check the scratchpad of the widget box
+ if (QDesignerWidgetBoxInterface *widgetBox = m_core->widgetBox()) {
+ const QStringList scratchPadClasses = getScratchPadClasses(widgetBox);
+ if (!scratchPadClasses.empty()) {
+ // Check whether these are actually promoted
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
+ QStringList::const_iterator cend = scratchPadClasses.constEnd();
+ for (QStringList::const_iterator it = scratchPadClasses.constBegin(); it != cend; ++it ) {
+ const int index = widgetDataBase->indexOfClassName(*it);
+ if (index != -1 && widgetDataBase->item(index)->isPromoted())
+ rc += *it;
+ }
+ }
+ }
+ return rc;
+ }
+
+ bool QDesignerPromotion::removePromotedClass(const QString &className, QString *errorMessage) {
+ // check if it exists and is promoted
+ WidgetDataBase *widgetDataBase = qobject_cast<WidgetDataBase *>(m_core->widgetDataBase());
+ if (!widgetDataBase) {
+ *errorMessage = QCoreApplication::tr("The class %1 cannot be removed").arg(className);
+ return false;
+ }
+
+ const int index = promotedWidgetDataBaseIndex(widgetDataBase, className, errorMessage);
+ if (index == -1)
+ return false;
+
+ if (referencedPromotedClassNames().contains(className)) {
+ *errorMessage = QCoreApplication::tr("The class %1 cannot be removed because it is still referenced.").arg(className);
+ return false;
+ }
+ widgetDataBase->remove(index);
+ return true;
+ }
+
+ bool QDesignerPromotion::changePromotedClassName(const QString &oldclassName, const QString &newClassName, QString *errorMessage) {
+ const MetaDataBase *metaDataBase = qobject_cast<const MetaDataBase*>(m_core->metaDataBase());
+ if (!metaDataBase) {
+ *errorMessage = QCoreApplication::tr("The class %1 cannot be renamed").arg(oldclassName);
+ return false;
+ }
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
+
+ // check the new name
+ if (newClassName.isEmpty()) {
+ *errorMessage = QCoreApplication::tr("The class %1 cannot be renamed to an empty name.").arg(oldclassName);
+ return false;
+ }
+ const int existingIndex = widgetDataBase->indexOfClassName(newClassName);
+ if (existingIndex != -1) {
+ *errorMessage = QCoreApplication::tr("There is already a class named %1.").arg(newClassName);
+ return false;
+ }
+ // Check old class
+ QDesignerWidgetDataBaseItemInterface *dbItem = promotedWidgetDataBaseItem(widgetDataBase, oldclassName, errorMessage);
+ if (!dbItem)
+ return false;
+
+ // Change the name in the data base and change all referencing objects in the meta database
+ dbItem->setName(newClassName);
+ bool foundReferences = false;
+ foreach (QObject* object, metaDataBase->objects()) {
+ MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(object);
+ Q_ASSERT(item);
+ if (item->customClassName() == oldclassName) {
+ item->setCustomClassName(newClassName);
+ foundReferences = true;
+ }
+ }
+ // set state
+ if (foundReferences)
+ refreshObjectInspector();
+
+ return true;
+ }
+
+ bool QDesignerPromotion::setPromotedClassIncludeFile(const QString &className, const QString &includeFile, QString *errorMessage) {
+ // check file
+ if (includeFile.isEmpty()) {
+ *errorMessage = QCoreApplication::tr("Cannot set an empty include file.");
+ return false;
+ }
+ // check item
+ QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
+ QDesignerWidgetDataBaseItemInterface *dbItem = promotedWidgetDataBaseItem(widgetDataBase, className, errorMessage);
+ if (!dbItem)
+ return false;
+
+ dbItem->setIncludeFile(includeFile);
+ return true;
+ }
+
+ void QDesignerPromotion::refreshObjectInspector() {
+ if (QDesignerFormWindowManagerInterface *fwm = m_core->formWindowManager()) {
+ if (QDesignerFormWindowInterface *fw = fwm->activeFormWindow())
+ if ( QDesignerObjectInspectorInterface *oi = m_core->objectInspector()) {
+ oi->setFormWindow(fw);
+ }
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_promotion_p.h b/src/designer/src/lib/shared/qdesigner_promotion_p.h
new file mode 100644
index 000000000..b1af1db93
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_promotion_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNERPROMOTION_H
+#define QDESIGNERPROMOTION_H
+
+#include "shared_global_p.h"
+
+#include <QtDesigner/QDesignerPromotionInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+ class QDESIGNER_SHARED_EXPORT QDesignerPromotion : public QDesignerPromotionInterface
+ {
+ public:
+ explicit QDesignerPromotion(QDesignerFormEditorInterface *core);
+
+ virtual PromotedClasses promotedClasses() const;
+
+ virtual QSet<QString> referencedPromotedClassNames() const;
+
+ virtual bool addPromotedClass(const QString &baseClass,
+ const QString &className,
+ const QString &includeFile,
+ QString *errorMessage);
+
+ virtual bool removePromotedClass(const QString &className, QString *errorMessage);
+
+ virtual bool changePromotedClassName(const QString &oldclassName, const QString &newClassName, QString *errorMessage);
+
+ virtual bool setPromotedClassIncludeFile(const QString &className, const QString &includeFile, QString *errorMessage);
+
+ virtual QList<QDesignerWidgetDataBaseItemInterface *> promotionBaseClasses() const;
+
+ private:
+ bool canBePromoted(const QDesignerWidgetDataBaseItemInterface *) const;
+ void refreshObjectInspector();
+
+ QDesignerFormEditorInterface *m_core;
+ };
+}
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNERPROMOTION_H
diff --git a/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp b/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp
new file mode 100644
index 000000000..6463016b1
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp
@@ -0,0 +1,456 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_promotiondialog_p.h"
+#include "promotionmodel_p.h"
+#include "iconloader_p.h"
+#include "widgetdatabase_p.h"
+#include "signalslotdialog_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerPromotionInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseItemInterface>
+#include <QtDesigner/QDesignerIntegrationInterface>
+#include <abstractdialoggui_p.h>
+
+#include <QtCore/QTimer>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QTreeView>
+#include <QtGui/QHeaderView>
+#include <QtGui/QPushButton>
+#include <QtGui/QItemSelectionModel>
+#include <QtGui/QItemSelection>
+#include <QtGui/QComboBox>
+#include <QtGui/QLineEdit>
+#include <QtGui/QCheckBox>
+#include <QtGui/QRegExpValidator>
+#include <QtGui/QLabel>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ // PromotionParameters
+ struct PromotionParameters {
+ QString m_baseClass;
+ QString m_className;
+ QString m_includeFile;
+ };
+
+ // NewPromotedClassPanel
+ NewPromotedClassPanel::NewPromotedClassPanel(const QStringList &baseClasses,
+ int selectedBaseClass,
+ QWidget *parent) :
+ QGroupBox(parent),
+ m_baseClassCombo(new QComboBox),
+ m_classNameEdit(new QLineEdit),
+ m_includeFileEdit(new QLineEdit),
+ m_globalIncludeCheckBox(new QCheckBox),
+ m_addButton(new QPushButton(tr("Add")))
+ {
+ setTitle(tr("New Promoted Class"));
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
+ QHBoxLayout *hboxLayout = new QHBoxLayout(this);
+
+ m_classNameEdit->setValidator(new QRegExpValidator(QRegExp(QLatin1String("[_a-zA-Z:][:_a-zA-Z0-9]*")), m_classNameEdit));
+ connect(m_classNameEdit, SIGNAL(textChanged(QString)), this, SLOT(slotNameChanged(QString)));
+ connect(m_includeFileEdit, SIGNAL(textChanged(QString)), this, SLOT(slotIncludeFileChanged(QString)));
+
+ m_baseClassCombo->setEditable(false);
+ m_baseClassCombo->addItems(baseClasses);
+ if (selectedBaseClass != -1)
+ m_baseClassCombo->setCurrentIndex(selectedBaseClass);
+
+ // Grid
+ QFormLayout *formLayout = new QFormLayout();
+ formLayout->addRow(tr("Base class name:"), m_baseClassCombo);
+ formLayout->addRow(tr("Promoted class name:"), m_classNameEdit);
+ formLayout->addRow(tr("Header file:"), m_includeFileEdit);
+ formLayout->addRow(tr("Global include"), m_globalIncludeCheckBox);
+ hboxLayout->addLayout(formLayout);
+ hboxLayout->addItem(new QSpacerItem(15, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
+ // Button box
+ QVBoxLayout *buttonLayout = new QVBoxLayout();
+
+ m_addButton->setAutoDefault(false);
+ connect(m_addButton, SIGNAL(clicked()), this, SLOT(slotAdd()));
+ m_addButton->setEnabled(false);
+ buttonLayout->addWidget(m_addButton);
+
+ QPushButton *resetButton = new QPushButton(tr("Reset"));
+ resetButton->setAutoDefault(false);
+ connect(resetButton, SIGNAL(clicked()), this, SLOT(slotReset()));
+
+ buttonLayout->addWidget(resetButton);
+ buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::Expanding));
+ hboxLayout->addLayout(buttonLayout);
+
+ enableButtons();
+ }
+
+ void NewPromotedClassPanel::slotAdd() {
+ bool ok = false;
+ emit newPromotedClass(promotionParameters(), &ok);
+ if (ok)
+ slotReset();
+ }
+
+ void NewPromotedClassPanel::slotReset() {
+ const QString empty;
+ m_classNameEdit->setText(empty);
+ m_includeFileEdit->setText(empty);
+ m_globalIncludeCheckBox->setCheckState(Qt::Unchecked);
+ }
+
+ void NewPromotedClassPanel::grabFocus() {
+ m_classNameEdit->setFocus(Qt::OtherFocusReason);
+ }
+
+ void NewPromotedClassPanel::slotNameChanged(const QString &className) {
+ // Suggest a name
+ if (!className.isEmpty()) {
+ const QChar dot(QLatin1Char('.'));
+ QString suggestedHeader = m_promotedHeaderLowerCase ?
+ className.toLower() : className;
+ suggestedHeader.replace(QLatin1String("::"), QString(QLatin1Char('_')));
+ if (!m_promotedHeaderSuffix.startsWith(dot))
+ suggestedHeader += dot;
+ suggestedHeader += m_promotedHeaderSuffix;
+
+ const bool blocked = m_includeFileEdit->blockSignals(true);
+ m_includeFileEdit->setText(suggestedHeader);
+ m_includeFileEdit->blockSignals(blocked);
+ }
+ enableButtons();
+ }
+
+ void NewPromotedClassPanel::slotIncludeFileChanged(const QString &){
+ enableButtons();
+ }
+
+ void NewPromotedClassPanel::enableButtons() {
+ const bool enabled = !m_classNameEdit->text().isEmpty() && !m_includeFileEdit->text().isEmpty();
+ m_addButton->setEnabled(enabled);
+ m_addButton->setDefault(enabled);
+ }
+
+ PromotionParameters NewPromotedClassPanel::promotionParameters() const {
+ PromotionParameters rc;
+ rc.m_baseClass = m_baseClassCombo->currentText();
+ rc.m_className = m_classNameEdit->text();
+ rc.m_includeFile = buildIncludeFile(m_includeFileEdit->text(),
+ m_globalIncludeCheckBox->checkState() == Qt::Checked ? IncludeGlobal : IncludeLocal);
+ return rc;
+ }
+
+ void NewPromotedClassPanel::chooseBaseClass(const QString &baseClass) {
+ const int index = m_baseClassCombo->findText (baseClass);
+ if (index != -1)
+ m_baseClassCombo->setCurrentIndex (index);
+ }
+
+ // --------------- QDesignerPromotionDialog
+ QDesignerPromotionDialog::QDesignerPromotionDialog(QDesignerFormEditorInterface *core,
+ QWidget *parent,
+ const QString &promotableWidgetClassName,
+ QString *promoteTo) :
+ QDialog(parent),
+ m_mode(promotableWidgetClassName.isEmpty() || promoteTo == 0 ? ModeEdit : ModeEditChooseClass),
+ m_promotableWidgetClassName(promotableWidgetClassName),
+ m_core(core),
+ m_promoteTo(promoteTo),
+ m_promotion(core->promotion()),
+ m_model(new PromotionModel(core)),
+ m_treeView(new QTreeView),
+ m_buttonBox(0),
+ m_removeButton(new QPushButton(createIconSet(QString::fromUtf8("minus.png")), QString()))
+ {
+ m_buttonBox = createButtonBox();
+ setModal(true);
+ setWindowTitle(tr("Promoted Widgets"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ QVBoxLayout *vboxLayout = new QVBoxLayout(this);
+
+ // tree view group
+ QGroupBox *treeViewGroup = new QGroupBox();
+ treeViewGroup->setTitle(tr("Promoted Classes"));
+ QVBoxLayout *treeViewVBoxLayout = new QVBoxLayout(treeViewGroup);
+ // tree view
+ m_treeView->setModel (m_model);
+ m_treeView->setMinimumWidth(450);
+ m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
+
+ connect(m_treeView, SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(slotTreeViewContextMenu(QPoint)));
+
+ QHeaderView *headerView = m_treeView->header();
+ headerView->setResizeMode(QHeaderView::ResizeToContents);
+ treeViewVBoxLayout->addWidget(m_treeView);
+ // remove button
+ QHBoxLayout *hboxLayout = new QHBoxLayout();
+ hboxLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
+
+ m_removeButton->setAutoDefault(false);
+ connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemove()));
+ m_removeButton->setEnabled(false);
+ hboxLayout->addWidget(m_removeButton);
+ treeViewVBoxLayout->addLayout(hboxLayout);
+ vboxLayout->addWidget(treeViewGroup);
+ // Create new panel: Try to be smart and preselect a base class. Default to QFrame
+ const QStringList &baseClassNameList = baseClassNames(m_promotion);
+ int preselectedBaseClass = -1;
+ if (m_mode == ModeEditChooseClass) {
+ preselectedBaseClass = baseClassNameList.indexOf(m_promotableWidgetClassName);
+ }
+ if (preselectedBaseClass == -1)
+ preselectedBaseClass = baseClassNameList.indexOf(QLatin1String("QFrame"));
+
+ NewPromotedClassPanel *newPromotedClassPanel = new NewPromotedClassPanel(baseClassNameList, preselectedBaseClass);
+ newPromotedClassPanel->setPromotedHeaderSuffix(core->integration()->headerSuffix());
+ newPromotedClassPanel->setPromotedHeaderLowerCase(core->integration()->isHeaderLowercase());
+ connect(newPromotedClassPanel, SIGNAL(newPromotedClass(PromotionParameters,bool*)), this, SLOT(slotNewPromotedClass(PromotionParameters,bool*)));
+ connect(this, SIGNAL(selectedBaseClassChanged(QString)),
+ newPromotedClassPanel, SLOT(chooseBaseClass(QString)));
+ vboxLayout->addWidget(newPromotedClassPanel);
+ // button box
+ vboxLayout->addWidget(m_buttonBox);
+ // connect model
+ connect(m_model, SIGNAL(includeFileChanged(QDesignerWidgetDataBaseItemInterface*,QString)),
+ this, SLOT(slotIncludeFileChanged(QDesignerWidgetDataBaseItemInterface*,QString)));
+
+ connect(m_model, SIGNAL(classNameChanged(QDesignerWidgetDataBaseItemInterface*,QString)),
+ this, SLOT(slotClassNameChanged(QDesignerWidgetDataBaseItemInterface*,QString)));
+
+ // focus
+ if (m_mode == ModeEditChooseClass)
+ newPromotedClassPanel->grabFocus();
+
+ slotUpdateFromWidgetDatabase();
+ }
+
+ QDialogButtonBox *QDesignerPromotionDialog::createButtonBox() {
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Close);
+
+ connect(buttonBox , SIGNAL(accepted()), this, SLOT(slotAcceptPromoteTo()));
+ buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Promote"));
+ buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+
+ connect(buttonBox , SIGNAL(rejected()), this, SLOT(reject()));
+ return buttonBox;
+ }
+
+ void QDesignerPromotionDialog::slotUpdateFromWidgetDatabase() {
+ m_model->updateFromWidgetDatabase();
+ m_treeView->expandAll();
+ m_removeButton->setEnabled(false);
+ }
+
+ void QDesignerPromotionDialog::delayedUpdateFromWidgetDatabase() {
+ QTimer::singleShot(0, this, SLOT(slotUpdateFromWidgetDatabase()));
+ }
+
+ const QStringList &QDesignerPromotionDialog::baseClassNames(const QDesignerPromotionInterface *promotion) {
+ typedef QList<QDesignerWidgetDataBaseItemInterface *> WidgetDataBaseItemList;
+ static QStringList rc;
+ if (rc.empty()) {
+ // Convert the item list into a string list.
+ const WidgetDataBaseItemList dbItems = promotion->promotionBaseClasses();
+ const WidgetDataBaseItemList::const_iterator cend = dbItems.constEnd();
+ for (WidgetDataBaseItemList::const_iterator it = dbItems.constBegin() ; it != cend; ++it) {
+ rc.push_back( (*it)->name());
+ }
+ }
+ return rc;
+ }
+
+ void QDesignerPromotionDialog::slotAcceptPromoteTo() {
+ Q_ASSERT(m_mode == ModeEditChooseClass);
+ unsigned flags;
+ // Ok pressed: Promote to selected class
+ if (QDesignerWidgetDataBaseItemInterface *dbItem = databaseItemAt(m_treeView->selectionModel()->selection(), flags)) {
+ if (flags & CanPromote) {
+ *m_promoteTo = dbItem ->name();
+ accept();
+ }
+ }
+ }
+
+ void QDesignerPromotionDialog::slotRemove() {
+ unsigned flags;
+ QDesignerWidgetDataBaseItemInterface *dbItem = databaseItemAt(m_treeView->selectionModel()->selection(), flags);
+ if (!dbItem || (flags & Referenced))
+ return;
+
+ QString errorMessage;
+ if (m_promotion->removePromotedClass(dbItem->name(), &errorMessage)) {
+ slotUpdateFromWidgetDatabase();
+ } else {
+ displayError(errorMessage);
+ }
+ }
+
+ void QDesignerPromotionDialog::slotSelectionChanged(const QItemSelection &selected, const QItemSelection &) {
+ // Enable deleting non-referenced items
+ unsigned flags;
+ const QDesignerWidgetDataBaseItemInterface *dbItem = databaseItemAt(selected, flags);
+ m_removeButton->setEnabled(dbItem && !(flags & Referenced));
+ // In choose mode, can we promote to the class?
+ if (m_mode == ModeEditChooseClass) {
+ const bool enablePromoted = flags & CanPromote;
+ m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enablePromoted);
+ m_buttonBox->button(QDialogButtonBox::Ok)->setDefault(enablePromoted);
+ }
+ // different base?
+ if (dbItem) {
+ const QString baseClass = dbItem->extends();
+ if (baseClass != m_lastSelectedBaseClass) {
+ m_lastSelectedBaseClass = baseClass;
+ emit selectedBaseClassChanged(m_lastSelectedBaseClass);
+ }
+ }
+ }
+
+ QDesignerWidgetDataBaseItemInterface *QDesignerPromotionDialog::databaseItemAt(const QItemSelection &selected, unsigned &flags) const {
+ flags = 0;
+ const QModelIndexList indexes = selected.indexes();
+ if (indexes.empty())
+ return 0;
+
+ bool referenced;
+ QDesignerWidgetDataBaseItemInterface *dbItem = m_model->databaseItemAt(indexes.front(), &referenced);
+
+ if (dbItem) {
+ if (referenced)
+ flags |= Referenced;
+ // In choose mode, can we promote to the class?
+ if (m_mode == ModeEditChooseClass && dbItem && dbItem->isPromoted() && dbItem->extends() == m_promotableWidgetClassName)
+ flags |= CanPromote;
+
+ }
+ return dbItem;
+ }
+
+ void QDesignerPromotionDialog::slotNewPromotedClass(const PromotionParameters &p, bool *ok) {
+ QString errorMessage;
+ *ok = m_promotion->addPromotedClass(p.m_baseClass, p.m_className, p.m_includeFile, &errorMessage);
+ if (*ok) {
+ // update and select
+ slotUpdateFromWidgetDatabase();
+ const QModelIndex newClassIndex = m_model->indexOfClass(p.m_className);
+ if (newClassIndex.isValid()) {
+ m_treeView->selectionModel()->select(newClassIndex, QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows);
+ }
+ } else {
+ displayError(errorMessage);
+ }
+ }
+
+ void QDesignerPromotionDialog::slotIncludeFileChanged(QDesignerWidgetDataBaseItemInterface *dbItem, const QString &includeFile) {
+ if (includeFile.isEmpty()) {
+ delayedUpdateFromWidgetDatabase();
+ return;
+ }
+
+ if (dbItem->includeFile() == includeFile)
+ return;
+
+ QString errorMessage;
+ if (!m_promotion->setPromotedClassIncludeFile(dbItem->name(), includeFile, &errorMessage)) {
+ displayError(errorMessage);
+ delayedUpdateFromWidgetDatabase();
+ }
+ }
+
+ void QDesignerPromotionDialog::slotClassNameChanged(QDesignerWidgetDataBaseItemInterface *dbItem, const QString &newName) {
+ if (newName.isEmpty()) {
+ delayedUpdateFromWidgetDatabase();
+ return;
+ }
+ const QString oldName = dbItem->name();
+ if (newName == oldName)
+ return;
+
+ QString errorMessage;
+ if (!m_promotion->changePromotedClassName(oldName , newName, &errorMessage)) {
+ displayError(errorMessage);
+ delayedUpdateFromWidgetDatabase();
+ }
+ }
+
+ void QDesignerPromotionDialog::slotTreeViewContextMenu(const QPoint &pos) {
+ unsigned flags;
+ const QDesignerWidgetDataBaseItemInterface *dbItem = databaseItemAt(m_treeView->selectionModel()->selection(), flags);
+ if (!dbItem)
+ return;
+
+ QMenu menu;
+ QAction *signalSlotAction = menu.addAction(tr("Change signals/slots..."));
+ connect(signalSlotAction, SIGNAL(triggered()), this, SLOT(slotEditSignalsSlots()));
+
+ menu.exec(m_treeView->viewport()->mapToGlobal(pos));
+ }
+
+ void QDesignerPromotionDialog::slotEditSignalsSlots() {
+ unsigned flags;
+ const QDesignerWidgetDataBaseItemInterface *dbItem = databaseItemAt(m_treeView->selectionModel()->selection(), flags);
+ if (!dbItem)
+ return;
+
+ SignalSlotDialog::editPromotedClass(m_core, dbItem->name(), this);
+ }
+
+ void QDesignerPromotionDialog::displayError(const QString &message) {
+ m_core->dialogGui()->message(this, QDesignerDialogGuiInterface::PromotionErrorMessage, QMessageBox::Warning,
+ tr("%1 - Error").arg(windowTitle()), message, QMessageBox::Close);
+ }
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_promotiondialog_p.h b/src/designer/src/lib/shared/qdesigner_promotiondialog_p.h
new file mode 100644
index 000000000..73cf7ad50
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_promotiondialog_p.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef PROMOTIONEDITORDIALOG_H
+#define PROMOTIONEDITORDIALOG_H
+
+#include <QtGui/QDialog>
+#include <QtGui/QGroupBox>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QDesignerPromotionInterface;
+class QDesignerWidgetDataBaseItemInterface;
+
+class QTreeView;
+class QPushButton;
+class QItemSelection;
+class QDialogButtonBox;
+class QComboBox;
+class QLineEdit;
+class QCheckBox;
+
+namespace qdesigner_internal {
+ struct PromotionParameters;
+ class PromotionModel;
+
+
+ // Panel for adding a new promoted class. Separate class for code cleanliness.
+ class NewPromotedClassPanel : public QGroupBox {
+ Q_OBJECT
+ public:
+ explicit NewPromotedClassPanel(const QStringList &baseClasses,
+ int selectedBaseClass = -1,
+ QWidget *parent = 0);
+
+ QString promotedHeaderSuffix() const { return m_promotedHeaderSuffix; }
+ void setPromotedHeaderSuffix(const QString &s) { m_promotedHeaderSuffix = s; }
+
+ bool isPromotedHeaderLowerCase() const { return m_promotedHeaderLowerCase; }
+ void setPromotedHeaderLowerCase(bool l) { m_promotedHeaderLowerCase = l; }
+
+ signals:
+ void newPromotedClass(const PromotionParameters &, bool *ok);
+
+ public slots:
+ void grabFocus();
+ void chooseBaseClass(const QString &);
+ private slots:
+ void slotNameChanged(const QString &);
+ void slotIncludeFileChanged(const QString &);
+ void slotAdd();
+ void slotReset();
+
+ private:
+ PromotionParameters promotionParameters() const;
+ void enableButtons();
+
+ QString m_promotedHeaderSuffix;
+ bool m_promotedHeaderLowerCase;
+
+ QComboBox *m_baseClassCombo;
+ QLineEdit *m_classNameEdit;
+ QLineEdit *m_includeFileEdit;
+ QCheckBox *m_globalIncludeCheckBox;
+ QPushButton *m_addButton;
+ };
+
+ // Dialog for editing promoted classes.
+ class QDesignerPromotionDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ enum Mode { ModeEdit, ModeEditChooseClass };
+
+ explicit QDesignerPromotionDialog(QDesignerFormEditorInterface *core,
+ QWidget *parent = 0,
+ const QString &promotableWidgetClassName = QString(),
+ QString *promoteTo = 0);
+ // Return an alphabetically ordered list of base class names for adding new classes.
+ static const QStringList &baseClassNames(const QDesignerPromotionInterface *promotion);
+
+ signals:
+ void selectedBaseClassChanged(const QString &);
+ private slots:
+ void slotRemove();
+ void slotAcceptPromoteTo();
+ void slotSelectionChanged(const QItemSelection &, const QItemSelection &);
+ void slotNewPromotedClass(const PromotionParameters &, bool *ok);
+
+ void slotIncludeFileChanged(QDesignerWidgetDataBaseItemInterface *, const QString &includeFile);
+ void slotClassNameChanged(QDesignerWidgetDataBaseItemInterface *, const QString &newName);
+ void slotUpdateFromWidgetDatabase();
+ void slotTreeViewContextMenu(const QPoint &);
+ void slotEditSignalsSlots();
+
+ private:
+ QDialogButtonBox *createButtonBox();
+ void delayedUpdateFromWidgetDatabase();
+ // Return item at model index and a combination of flags or 0.
+ enum { Referenced = 1, CanPromote = 2 };
+ QDesignerWidgetDataBaseItemInterface *databaseItemAt(const QItemSelection &, unsigned &flags) const;
+ void displayError(const QString &message);
+
+ const Mode m_mode;
+ const QString m_promotableWidgetClassName;
+ QDesignerFormEditorInterface *m_core;
+ QString *m_promoteTo;
+ QDesignerPromotionInterface *m_promotion;
+ PromotionModel *m_model;
+ QTreeView *m_treeView;
+ QDialogButtonBox *m_buttonBox;
+ QPushButton *m_removeButton;
+ QString m_lastSelectedBaseClass;
+ };
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // PROMOTIONEDITORDIALOG_H
diff --git a/src/designer/src/lib/shared/qdesigner_propertycommand.cpp b/src/designer/src/lib/shared/qdesigner_propertycommand.cpp
new file mode 100644
index 000000000..a9949d85c
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_propertycommand.cpp
@@ -0,0 +1,1503 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_propertycommand_p.h"
+#include "qdesigner_utils_p.h"
+#include "dynamicpropertysheet.h"
+#include "qdesigner_propertyeditor_p.h"
+#include "qdesigner_integration_p.h"
+#include "spacer_widget_p.h"
+#include "qdesigner_propertysheet_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerDynamicPropertySheetExtension>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtDesigner/QDesignerIntegrationInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QSize>
+#include <QtCore/QTextStream>
+#include <QtGui/QWidget>
+#include <QtGui/QApplication>
+#include <QtGui/QAction>
+#include <QtGui/QDialog>
+#include <QtGui/QPushButton>
+#include <QtGui/QLayout>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+enum { debugPropertyCommands = 0 };
+
+// Debug resolve mask of font
+QString fontMask(unsigned m)
+{
+ QString rc;
+ if (m & QFont::FamilyResolved)
+ rc += QLatin1String("Family");
+ if (m & QFont::SizeResolved)
+ rc += QLatin1String("Size ");
+ if (m & QFont::WeightResolved)
+ rc += QLatin1String("Bold ");
+ if (m & QFont::StyleResolved)
+ rc += QLatin1String("Style ");
+ if (m & QFont::UnderlineResolved)
+ rc += QLatin1String("Underline ");
+ if (m & QFont::StrikeOutResolved)
+ rc += QLatin1String("StrikeOut ");
+ if (m & QFont::KerningResolved)
+ rc += QLatin1String("Kerning ");
+ if (m & QFont::StyleStrategyResolved)
+ rc += QLatin1String("StyleStrategy");
+ return rc;
+}
+
+// Debug font
+QString fontString(const QFont &f)
+{
+ QString rc; {
+ const QChar comma = QLatin1Char(',');
+ QTextStream str(&rc);
+ str << QLatin1String("QFont(\"") << f.family() << comma <<
+ f.pointSize();
+ if (f.bold())
+ str << comma << QLatin1String("bold");
+ if (f.italic())
+ str << comma << QLatin1String("italic");
+ if (f.underline())
+ str << comma << QLatin1String("underline");
+ if (f.strikeOut())
+ str << comma << QLatin1String("strikeOut");
+ if (f.kerning())
+ str << comma << QLatin1String("kerning");
+ str << comma << f.styleStrategy() << QLatin1String(" resolve: ")
+ << fontMask(f.resolve()) << QLatin1Char(')');
+ }
+ return rc;
+}
+QSize checkSize(const QSize &size)
+{
+ return size.boundedTo(QSize(0xFFFFFF, 0xFFFFFF));
+}
+
+QSize diffSize(QDesignerFormWindowInterface *fw)
+{
+ const QWidget *container = fw->core()->integration()->containerWindow(fw);
+ if (!container)
+ return QSize();
+
+ const QSize diff = container->size() - fw->size(); // decoration offset of container window
+ return diff;
+}
+
+void checkSizes(QDesignerFormWindowInterface *fw, const QSize &size, QSize *formSize, QSize *containerSize)
+{
+ const QWidget *container = fw->core()->integration()->containerWindow(fw);
+ if (!container)
+ return;
+
+ const QSize diff = diffSize(fw); // decoration offset of container window
+
+ QSize newFormSize = checkSize(size).expandedTo(fw->mainContainer()->minimumSizeHint()); // don't try to resize to smaller size than minimumSizeHint
+ QSize newContainerSize = newFormSize + diff;
+
+ newContainerSize = newContainerSize.expandedTo(container->minimumSizeHint());
+ newContainerSize = newContainerSize.expandedTo(container->minimumSize());
+
+ newFormSize = newContainerSize - diff;
+
+ newContainerSize = checkSize(newContainerSize);
+
+ if (formSize)
+ *formSize = newFormSize;
+ if (containerSize)
+ *containerSize = newContainerSize;
+}
+
+/* SubProperties: When applying a changed property to a multiselection, it sometimes makes
+ * sense to apply only parts (subproperties) of the property.
+ * For example, if someone changes the x-value of a geometry in the property editor
+ * and applies it to a multi-selection, y should not be applied as this would cause all
+ * the widgets to overlap.
+ * The following routines can be used to find out the changed subproperties of a property,
+ * which are represented as a mask, and to apply them while leaving the others intact. */
+
+enum RectSubPropertyMask { SubPropertyX=1, SubPropertyY = 2, SubPropertyWidth = 4, SubPropertyHeight = 8 };
+enum SizePolicySubPropertyMask { SubPropertyHSizePolicy = 1, SubPropertyHStretch = 2, SubPropertyVSizePolicy = 4, SubPropertyVStretch = 8 };
+enum AlignmentSubPropertyMask { SubPropertyHorizontalAlignment = 1, SubPropertyVerticalAlignment = 2 };
+enum StringSubPropertyMask { SubPropertyStringValue = 1, SubPropertyStringComment = 2, SubPropertyStringTranslatable = 4, SubPropertyStringDisambiguation = 8 };
+enum KeySequenceSubPropertyMask { SubPropertyKeySequenceValue = 1, SubPropertyKeySequenceComment = 2, SubPropertyKeySequenceTranslatable = 4, SubPropertyKeySequenceDisambiguation = 8 };
+
+enum CommonSubPropertyMask { SubPropertyAll = 0xFFFFFFFF };
+
+// Set the mask flag in mask if the properties do not match.
+#define COMPARE_SUBPROPERTY(object1, object2, getter, mask, maskFlag) if (object1.getter() != object2.getter()) mask |= maskFlag;
+
+// find changed subproperties of a rectangle
+unsigned compareSubProperties(const QRect & r1, const QRect & r2)
+{
+ unsigned rc = 0;
+ COMPARE_SUBPROPERTY(r1, r2, x, rc, SubPropertyX)
+ COMPARE_SUBPROPERTY(r1, r2, y, rc, SubPropertyY)
+ COMPARE_SUBPROPERTY(r1, r2, width, rc, SubPropertyWidth)
+ COMPARE_SUBPROPERTY(r1, r2, height, rc, SubPropertyHeight)
+ return rc;
+}
+
+// find changed subproperties of a QSize
+unsigned compareSubProperties(const QSize & r1, const QSize & r2)
+{
+ unsigned rc = 0;
+ COMPARE_SUBPROPERTY(r1, r2, width, rc, SubPropertyWidth)
+ COMPARE_SUBPROPERTY(r1, r2, height, rc, SubPropertyHeight)
+ return rc;
+}
+// find changed subproperties of a QSizePolicy
+unsigned compareSubProperties(const QSizePolicy & sp1, const QSizePolicy & sp2)
+{
+ unsigned rc = 0;
+ COMPARE_SUBPROPERTY(sp1, sp2, horizontalPolicy, rc, SubPropertyHSizePolicy)
+ COMPARE_SUBPROPERTY(sp1, sp2, horizontalStretch, rc, SubPropertyHStretch)
+ COMPARE_SUBPROPERTY(sp1, sp2, verticalPolicy, rc, SubPropertyVSizePolicy)
+ COMPARE_SUBPROPERTY(sp1, sp2, verticalStretch, rc, SubPropertyVStretch)
+ return rc;
+}
+// find changed subproperties of qdesigner_internal::PropertySheetStringValue
+unsigned compareSubProperties(const qdesigner_internal::PropertySheetStringValue & str1, const qdesigner_internal::PropertySheetStringValue & str2)
+{
+ unsigned rc = 0;
+ COMPARE_SUBPROPERTY(str1, str2, value, rc, SubPropertyStringValue)
+ COMPARE_SUBPROPERTY(str1, str2, comment, rc, SubPropertyStringComment)
+ COMPARE_SUBPROPERTY(str1, str2, translatable, rc, SubPropertyStringTranslatable)
+ COMPARE_SUBPROPERTY(str1, str2, disambiguation, rc, SubPropertyStringDisambiguation)
+ return rc;
+}
+// find changed subproperties of qdesigner_internal::PropertySheetKeySequenceValue
+unsigned compareSubProperties(const qdesigner_internal::PropertySheetKeySequenceValue & str1, const qdesigner_internal::PropertySheetKeySequenceValue & str2)
+{
+ unsigned rc = 0;
+ COMPARE_SUBPROPERTY(str1, str2, value, rc, SubPropertyKeySequenceValue)
+ COMPARE_SUBPROPERTY(str1, str2, comment, rc, SubPropertyKeySequenceComment)
+ COMPARE_SUBPROPERTY(str1, str2, translatable, rc, SubPropertyKeySequenceTranslatable)
+ COMPARE_SUBPROPERTY(str1, str2, disambiguation, rc, SubPropertyKeySequenceDisambiguation)
+ return rc;
+}
+
+// Compare font-subproperties taking the [undocumented]
+// resolve flag into account
+template <class Property>
+void compareFontSubProperty(const QFont & f1,
+ const QFont & f2,
+ Property (QFont::*getter) () const,
+ unsigned maskBit,
+ unsigned &mask)
+{
+ const bool f1Changed = f1.resolve() & maskBit;
+ const bool f2Changed = f2.resolve() & maskBit;
+ // Role has been set/reset in editor
+ if (f1Changed != f2Changed) {
+ mask |= maskBit;
+ } else {
+ // Was modified in both palettes: Compare values.
+ if (f1Changed && f2Changed && (f1.*getter)() != (f2.*getter)())
+ mask |= maskBit;
+ }
+}
+// find changed subproperties of a QFont
+unsigned compareSubProperties(const QFont & f1, const QFont & f2)
+{
+ unsigned rc = 0;
+ compareFontSubProperty(f1, f2, &QFont::family, QFont::FamilyResolved, rc);
+ compareFontSubProperty(f1, f2, &QFont::pointSize, QFont::SizeResolved, rc);
+ compareFontSubProperty(f1, f2, &QFont::bold, QFont::WeightResolved, rc);
+ compareFontSubProperty(f1, f2, &QFont::italic, QFont::StyleResolved, rc);
+ compareFontSubProperty(f1, f2, &QFont::underline, QFont::UnderlineResolved, rc);
+ compareFontSubProperty(f1, f2, &QFont::strikeOut, QFont::StrikeOutResolved, rc);
+ compareFontSubProperty(f1, f2, &QFont::kerning, QFont::KerningResolved, rc);
+ compareFontSubProperty(f1, f2, &QFont::styleStrategy, QFont::StyleStrategyResolved, rc);
+ if (debugPropertyCommands)
+ qDebug() << "compareSubProperties " << fontString(f1) << fontString(f2) << "\n\treturns " << fontMask(rc);
+ return rc;
+}
+
+// Compare colors of a role
+bool roleColorChanged(const QPalette & p1, const QPalette & p2, QPalette::ColorRole role)
+{
+ for (int group = QPalette::Active; group < QPalette::NColorGroups; group++) {
+ const QPalette::ColorGroup pgroup = static_cast<QPalette::ColorGroup>(group);
+ if (p1.color(pgroup, role) != p2.color(pgroup, role))
+ return true;
+ }
+ return false;
+}
+// find changed subproperties of a QPalette taking the [undocumented] resolve flags into account
+unsigned compareSubProperties(const QPalette & p1, const QPalette & p2)
+{
+ unsigned rc = 0;
+ unsigned maskBit = 1u;
+ // generate a mask for each role
+ const unsigned p1Changed = p1.resolve();
+ const unsigned p2Changed = p2.resolve();
+ for (int role = QPalette::WindowText; role < QPalette::NColorRoles; role++, maskBit <<= 1u) {
+ const bool p1RoleChanged = p1Changed & maskBit;
+ const bool p2RoleChanged = p2Changed & maskBit;
+ // Role has been set/reset in editor
+ if (p1RoleChanged != p2RoleChanged) {
+ rc |= maskBit;
+ } else {
+ // Was modified in both palettes: Compare values.
+ if (p1RoleChanged && p2RoleChanged && roleColorChanged(p1, p2, static_cast<QPalette::ColorRole>(role)))
+ rc |= maskBit;
+ }
+ }
+ return rc;
+}
+
+// find changed subproperties of a QAlignment which is a flag combination of vertical and horizontal
+
+unsigned compareSubProperties(Qt::Alignment a1, Qt::Alignment a2)
+{
+ unsigned rc = 0;
+ if ((a1 & Qt::AlignHorizontal_Mask) != (a2 & Qt::AlignHorizontal_Mask))
+ rc |= SubPropertyHorizontalAlignment;
+ if ((a1 & Qt::AlignVertical_Mask) != (a2 & Qt::AlignVertical_Mask))
+ rc |= SubPropertyVerticalAlignment;
+ return rc;
+}
+
+Qt::Alignment variantToAlignment(const QVariant & q)
+{
+ return Qt::Alignment(qdesigner_internal::Utils::valueOf(q));
+}
+// find changed subproperties of a variant
+unsigned compareSubProperties(const QVariant & q1, const QVariant & q2, qdesigner_internal::SpecialProperty specialProperty)
+{
+ // Do not clobber new value in the comparison function in
+ // case someone sets a QString on a PropertySheetStringValue.
+ if (q1.type() != q2.type())
+ return SubPropertyAll;
+ switch (q1.type()) {
+ case QVariant::Rect:
+ return compareSubProperties(q1.toRect(), q2.toRect());
+ case QVariant::Size:
+ return compareSubProperties(q1.toSize(), q2.toSize());
+ case QVariant::SizePolicy:
+ return compareSubProperties(qvariant_cast<QSizePolicy>(q1), qvariant_cast<QSizePolicy>(q2));
+ case QVariant::Font:
+ return compareSubProperties(qvariant_cast<QFont>(q1), qvariant_cast<QFont>(q2));
+ case QVariant::Palette:
+ return compareSubProperties(qvariant_cast<QPalette>(q1), qvariant_cast<QPalette>(q2));
+ default:
+ if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetIconValue>())
+ return qvariant_cast<qdesigner_internal::PropertySheetIconValue>(q1).compare(qvariant_cast<qdesigner_internal::PropertySheetIconValue>(q2));
+ else if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetStringValue>())
+ return compareSubProperties(qvariant_cast<qdesigner_internal::PropertySheetStringValue>(q1), qvariant_cast<qdesigner_internal::PropertySheetStringValue>(q2));
+ else if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetKeySequenceValue>())
+ return compareSubProperties(qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(q1), qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(q2));
+ // Enumerations, flags
+ switch (specialProperty) {
+ case qdesigner_internal::SP_Alignment:
+ return compareSubProperties(variantToAlignment(q1), variantToAlignment(q2));
+ default:
+ break;
+ }
+ break;
+ }
+ return SubPropertyAll;
+}
+
+// Apply the sub property if mask flag is set in mask
+#define SET_SUBPROPERTY(rc, newValue, getter, setter, mask, maskFlag) if (mask & maskFlag) rc.setter(newValue.getter());
+
+// apply changed subproperties to a rectangle
+QRect applyRectSubProperty(const QRect &oldValue, const QRect &newValue, unsigned mask)
+{
+ QRect rc = oldValue;
+ SET_SUBPROPERTY(rc, newValue, x, moveLeft, mask, SubPropertyX)
+ SET_SUBPROPERTY(rc, newValue, y, moveTop, mask, SubPropertyY)
+ SET_SUBPROPERTY(rc, newValue, width, setWidth, mask, SubPropertyWidth)
+ SET_SUBPROPERTY(rc, newValue, height, setHeight, mask, SubPropertyHeight)
+ return rc;
+}
+
+
+// apply changed subproperties to a rectangle QSize
+QSize applySizeSubProperty(const QSize &oldValue, const QSize &newValue, unsigned mask)
+{
+ QSize rc = oldValue;
+ SET_SUBPROPERTY(rc, newValue, width, setWidth, mask, SubPropertyWidth)
+ SET_SUBPROPERTY(rc, newValue, height, setHeight, mask, SubPropertyHeight)
+ return rc;
+}
+
+
+// apply changed subproperties to a SizePolicy
+QSizePolicy applySizePolicySubProperty(const QSizePolicy &oldValue, const QSizePolicy &newValue, unsigned mask)
+{
+ QSizePolicy rc = oldValue;
+ SET_SUBPROPERTY(rc, newValue, horizontalPolicy, setHorizontalPolicy, mask, SubPropertyHSizePolicy)
+ SET_SUBPROPERTY(rc, newValue, horizontalStretch, setHorizontalStretch, mask, SubPropertyHStretch)
+ SET_SUBPROPERTY(rc, newValue, verticalPolicy, setVerticalPolicy, mask, SubPropertyVSizePolicy)
+ SET_SUBPROPERTY(rc, newValue, verticalStretch, setVerticalStretch, mask, SubPropertyVStretch)
+ return rc;
+}
+
+// apply changed subproperties to a qdesigner_internal::PropertySheetStringValue
+qdesigner_internal::PropertySheetStringValue applyStringSubProperty(const qdesigner_internal::PropertySheetStringValue &oldValue,
+ const qdesigner_internal::PropertySheetStringValue &newValue, unsigned mask)
+{
+ qdesigner_internal::PropertySheetStringValue rc = oldValue;
+ SET_SUBPROPERTY(rc, newValue, value, setValue, mask, SubPropertyStringValue)
+ SET_SUBPROPERTY(rc, newValue, comment, setComment, mask, SubPropertyStringComment)
+ SET_SUBPROPERTY(rc, newValue, translatable, setTranslatable, mask, SubPropertyStringTranslatable)
+ SET_SUBPROPERTY(rc, newValue, disambiguation, setDisambiguation, mask, SubPropertyStringDisambiguation)
+ return rc;
+}
+
+// apply changed subproperties to a qdesigner_internal::PropertySheetKeySequenceValue
+qdesigner_internal::PropertySheetKeySequenceValue applyKeySequenceSubProperty(const qdesigner_internal::PropertySheetKeySequenceValue &oldValue,
+ const qdesigner_internal::PropertySheetKeySequenceValue &newValue, unsigned mask)
+{
+ qdesigner_internal::PropertySheetKeySequenceValue rc = oldValue;
+ SET_SUBPROPERTY(rc, newValue, value, setValue, mask, SubPropertyKeySequenceValue)
+ SET_SUBPROPERTY(rc, newValue, comment, setComment, mask, SubPropertyKeySequenceComment)
+ SET_SUBPROPERTY(rc, newValue, translatable, setTranslatable, mask, SubPropertyKeySequenceTranslatable)
+ SET_SUBPROPERTY(rc, newValue, disambiguation, setDisambiguation, mask, SubPropertyKeySequenceDisambiguation)
+ return rc;
+}
+
+// Apply the font-subproperties keeping the [undocumented]
+// resolve flag in sync (note that PropertySetterType might be something like const T&).
+template <class PropertyReturnType, class PropertySetterType>
+inline void setFontSubProperty(unsigned mask,
+ const QFont &newValue,
+ unsigned maskBit,
+ PropertyReturnType (QFont::*getter) () const,
+ void (QFont::*setter) (PropertySetterType),
+ QFont &value)
+{
+ if (mask & maskBit) {
+ (value.*setter)((newValue.*getter)());
+ // Set the resolve bit from NewValue in return value
+ uint r = value.resolve();
+ const bool origFlag = newValue.resolve() & maskBit;
+ if (origFlag)
+ r |= maskBit;
+ else
+ r &= ~maskBit;
+ value.resolve(r);
+ if (debugPropertyCommands)
+ qDebug() << "setFontSubProperty " << fontMask(maskBit) << " resolve=" << origFlag;
+ }
+}
+// apply changed subproperties to a QFont
+QFont applyFontSubProperty(const QFont &oldValue, const QFont &newValue, unsigned mask)
+{
+ QFont rc = oldValue;
+ setFontSubProperty(mask, newValue, QFont::FamilyResolved, &QFont::family, &QFont::setFamily, rc);
+ setFontSubProperty(mask, newValue, QFont::SizeResolved, &QFont::pointSize, &QFont::setPointSize, rc);
+ setFontSubProperty(mask, newValue, QFont::WeightResolved, &QFont::bold, &QFont::setBold, rc);
+ setFontSubProperty(mask, newValue, QFont::StyleResolved, &QFont::italic, &QFont::setItalic, rc);
+ setFontSubProperty(mask, newValue, QFont::UnderlineResolved, &QFont::underline, &QFont::setUnderline, rc);
+ setFontSubProperty(mask, newValue, QFont::StrikeOutResolved, &QFont::strikeOut, &QFont::setStrikeOut, rc);
+ setFontSubProperty(mask, newValue, QFont::KerningResolved, &QFont::kerning, &QFont::setKerning, rc);
+ setFontSubProperty(mask, newValue, QFont::StyleStrategyResolved, &QFont::styleStrategy, &QFont::setStyleStrategy, rc);
+ if (debugPropertyCommands)
+ qDebug() << "applyFontSubProperty old " << fontMask(oldValue.resolve()) << " new " << fontMask(newValue.resolve()) << " return: " << fontMask(rc.resolve());
+ return rc;
+}
+
+// apply changed subproperties to a QPalette
+QPalette applyPaletteSubProperty(const QPalette &oldValue, const QPalette &newValue, unsigned mask)
+{
+ QPalette rc = oldValue;
+ // apply a mask for each role
+ unsigned maskBit = 1u;
+ for (int role = QPalette::WindowText; role < QPalette::NColorRoles; role++, maskBit <<= 1u) {
+ if (mask & maskBit) {
+ for (int group = QPalette::Active; group < QPalette::NColorGroups; group++) {
+ const QPalette::ColorGroup pgroup = static_cast<QPalette::ColorGroup>(group);
+ const QPalette::ColorRole prole = static_cast<QPalette::ColorRole>(role);
+ rc.setColor(pgroup, prole, newValue.color(pgroup, prole));
+ }
+ // Set the resolve bit from NewValue in return value
+ uint r = rc.resolve();
+ const bool origFlag = newValue.resolve() & maskBit;
+ if (origFlag)
+ r |= maskBit;
+ else
+ r &= ~maskBit;
+ rc.resolve(r);
+ }
+ }
+ return rc;
+}
+
+// apply changed subproperties to a QAlignment which is a flag combination of vertical and horizontal
+Qt::Alignment applyAlignmentSubProperty(Qt::Alignment oldValue, Qt::Alignment newValue, unsigned mask)
+{
+ // easy: both changed.
+ if (mask == (SubPropertyHorizontalAlignment|SubPropertyVerticalAlignment))
+ return newValue;
+ // Change subprop
+ const Qt::Alignment changeMask = (mask & SubPropertyHorizontalAlignment) ? Qt::AlignHorizontal_Mask : Qt::AlignVertical_Mask;
+ const Qt::Alignment takeOverMask = (mask & SubPropertyHorizontalAlignment) ? Qt::AlignVertical_Mask : Qt::AlignHorizontal_Mask;
+ return (oldValue & takeOverMask) | (newValue & changeMask);
+}
+
+}
+
+namespace qdesigner_internal {
+
+// apply changed subproperties to a variant
+PropertyHelper::Value applySubProperty(const QVariant &oldValue, const QVariant &newValue, qdesigner_internal::SpecialProperty specialProperty, unsigned mask, bool changed)
+{
+ if (mask == SubPropertyAll)
+ return PropertyHelper::Value(newValue, changed);
+
+ switch (oldValue.type()) {
+ case QVariant::Rect:
+ return PropertyHelper::Value(applyRectSubProperty(oldValue.toRect(), newValue.toRect(), mask), changed);
+ case QVariant::Size:
+ return PropertyHelper::Value(applySizeSubProperty(oldValue.toSize(), newValue.toSize(), mask), changed);
+ case QVariant::SizePolicy:
+ return PropertyHelper::Value(QVariant::fromValue(applySizePolicySubProperty(qvariant_cast<QSizePolicy>(oldValue), qvariant_cast<QSizePolicy>(newValue), mask)), changed);
+ case QVariant::Font: {
+ // Changed flag in case of font and palette depends on resolve mask only, not on the passed "changed" value.
+
+ // The first case: the user changed bold subproperty and then pressed reset button for this subproperty (not for
+ // the whole font property). We instantiate SetPropertyCommand passing changed=true. But in this case no
+ // subproperty is changed and the whole property should be marked an unchanged.
+
+ // The second case: there are 2 pushbuttons, for 1st the user set bold and italic subproperties,
+ // for the 2nd he set bold only. He does multiselection so that the current widget is the 2nd one.
+ // He press reset next to bold subproperty. In result the 2nd widget should have the whole
+ // font property marked as unchanged and the 1st widget should have the font property
+ // marked as changed and only italic subproperty should be marked as changed (the bold should be reset).
+
+ // The third case: there are 2 pushbuttons, for 1st the user set bold and italic subproperties,
+ // for the 2nd he set bold only. He does multiselection so that the current widget is the 2nd one.
+ // He press reset button for the whole font property. In result whole font properties for both
+ // widgets should be marked as unchanged.
+ QFont font = applyFontSubProperty(qvariant_cast<QFont>(oldValue), qvariant_cast<QFont>(newValue), mask);
+ return PropertyHelper::Value(QVariant::fromValue(font), font.resolve());
+ }
+ case QVariant::Palette: {
+ QPalette palette = applyPaletteSubProperty(qvariant_cast<QPalette>(oldValue), qvariant_cast<QPalette>(newValue), mask);
+ return PropertyHelper::Value(QVariant::fromValue(palette), palette.resolve());
+ }
+ default:
+ if (oldValue.userType() == qMetaTypeId<qdesigner_internal::PropertySheetIconValue>()) {
+ PropertySheetIconValue icon = qvariant_cast<qdesigner_internal::PropertySheetIconValue>(oldValue);
+ icon.assign(qvariant_cast<qdesigner_internal::PropertySheetIconValue>(newValue), mask);
+ return PropertyHelper::Value(QVariant::fromValue(icon), icon.mask());
+ } else if (oldValue.userType() == qMetaTypeId<qdesigner_internal::PropertySheetStringValue>()) {
+ qdesigner_internal::PropertySheetStringValue str = applyStringSubProperty(
+ qvariant_cast<qdesigner_internal::PropertySheetStringValue>(oldValue),
+ qvariant_cast<qdesigner_internal::PropertySheetStringValue>(newValue), mask);
+ return PropertyHelper::Value(QVariant::fromValue(str), changed);
+ } else if (oldValue.userType() == qMetaTypeId<qdesigner_internal::PropertySheetKeySequenceValue>()) {
+ qdesigner_internal::PropertySheetKeySequenceValue key = applyKeySequenceSubProperty(
+ qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(oldValue),
+ qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(newValue), mask);
+ return PropertyHelper::Value(QVariant::fromValue(key), changed);
+ }
+ // Enumerations, flags
+ switch (specialProperty) {
+ case qdesigner_internal::SP_Alignment: {
+ qdesigner_internal::PropertySheetFlagValue f = qvariant_cast<qdesigner_internal::PropertySheetFlagValue>(oldValue);
+ f.value = applyAlignmentSubProperty(variantToAlignment(oldValue), variantToAlignment(newValue), mask);
+ QVariant v;
+ v.setValue(f);
+ return PropertyHelper::Value(v, changed);
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ return PropertyHelper::Value(newValue, changed);
+
+}
+// figure out special property
+enum SpecialProperty getSpecialProperty(const QString& propertyName)
+{
+ if (propertyName == QLatin1String("objectName"))
+ return SP_ObjectName;
+ if (propertyName == QLatin1String("layoutName"))
+ return SP_LayoutName;
+ if (propertyName == QLatin1String("spacerName"))
+ return SP_SpacerName;
+ if (propertyName == QLatin1String("icon"))
+ return SP_Icon;
+ if (propertyName == QLatin1String("currentTabName"))
+ return SP_CurrentTabName;
+ if (propertyName == QLatin1String("currentItemName"))
+ return SP_CurrentItemName;
+ if (propertyName == QLatin1String("currentPageName"))
+ return SP_CurrentPageName;
+ if (propertyName == QLatin1String("geometry"))
+ return SP_Geometry;
+ if (propertyName == QLatin1String("windowTitle"))
+ return SP_WindowTitle;
+ if (propertyName == QLatin1String("minimumSize"))
+ return SP_MinimumSize;
+ if (propertyName == QLatin1String("maximumSize"))
+ return SP_MaximumSize;
+ if (propertyName == QLatin1String("alignment"))
+ return SP_Alignment;
+ if (propertyName == QLatin1String("autoDefault"))
+ return SP_AutoDefault;
+ if (propertyName == QLatin1String("shortcut"))
+ return SP_Shortcut;
+ if (propertyName == QLatin1String("orientation"))
+ return SP_Orientation;
+ return SP_None;
+}
+
+
+PropertyHelper::PropertyHelper(QObject* object,
+ SpecialProperty specialProperty,
+ QDesignerPropertySheetExtension *sheet,
+ int index) :
+ m_specialProperty(specialProperty),
+ m_object(object),
+ m_objectType(OT_Object),
+ m_propertySheet(sheet), m_index(index),
+ m_oldValue(m_propertySheet->property(m_index), m_propertySheet->isChanged(m_index))
+{
+ if (object->isWidgetType()) {
+ m_parentWidget = (qobject_cast<QWidget*>(object))->parentWidget();
+ m_objectType = OT_Widget;
+ } else {
+ if (const QAction *action = qobject_cast<const QAction *>(m_object))
+ m_objectType = action->associatedWidgets().empty() ? OT_FreeAction : OT_AssociatedAction;
+ }
+
+ if(debugPropertyCommands)
+ qDebug() << "PropertyHelper on " << m_object->objectName() << " index= " << m_index << " type = " << m_objectType;
+}
+
+QDesignerIntegration *PropertyHelper::integration(QDesignerFormWindowInterface *fw) const
+{
+ return qobject_cast<QDesignerIntegration *>(fw->core()->integration());
+}
+
+// Set widget value, apply corrections and checks in case of main window.
+void PropertyHelper::checkApplyWidgetValue(QDesignerFormWindowInterface *fw, QWidget* w,
+ SpecialProperty specialProperty, QVariant &value)
+{
+
+ bool isMainContainer = false;
+ if (QDesignerFormWindowCursorInterface *cursor = fw->cursor()) {
+ if (cursor->isWidgetSelected(w)) {
+ if (cursor->isWidgetSelected(fw->mainContainer())) {
+ isMainContainer = true;
+ }
+ }
+ }
+ if (!isMainContainer)
+ return;
+
+ QWidget *container = fw->core()->integration()->containerWindow(fw);
+ if (!container)
+ return;
+
+
+ switch (specialProperty) {
+ case SP_MinimumSize: {
+ const QSize size = checkSize(value.toSize());
+ value.setValue(size);
+ }
+
+ break;
+ case SP_MaximumSize: {
+ QSize fs, cs;
+ checkSizes(fw, value.toSize(), &fs, &cs);
+ container->setMaximumSize(cs);
+ fw->mainContainer()->setMaximumSize(fs);
+ value.setValue(fs);
+
+ }
+ break;
+ case SP_Geometry: {
+ QRect r = value.toRect();
+ QSize fs, cs;
+ checkSizes(fw, r.size(), &fs, &cs);
+ container->resize(cs);
+ r.setSize(fs);
+ value.setValue(r);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+unsigned PropertyHelper::updateMask() const
+{
+ unsigned rc = 0;
+ switch (m_specialProperty) {
+ case SP_ObjectName:
+ case SP_LayoutName:
+ case SP_SpacerName:
+ case SP_CurrentTabName:
+ case SP_CurrentItemName:
+ case SP_CurrentPageName:
+ if (m_objectType != OT_FreeAction)
+ rc |= UpdateObjectInspector;
+ break;
+ case SP_Icon:
+ if (m_objectType == OT_AssociatedAction)
+ rc |= UpdateObjectInspector;
+ break;
+ case SP_Orientation: // for updating splitter icon
+ rc |= UpdateObjectInspector;
+ break;
+ default:
+ break;
+
+ }
+ return rc;
+}
+
+
+bool PropertyHelper::canMerge(const PropertyHelper &other) const
+{
+ return m_object == other.m_object && m_index == other.m_index;
+}
+
+void PropertyHelper::triggerActionChanged(QAction *a)
+{
+ a->setData(QVariant(true)); // this triggers signal "changed" in QAction
+ a->setData(QVariant(false));
+}
+
+// Update the object to reflect the changes
+void PropertyHelper::updateObject(QDesignerFormWindowInterface *fw, const QVariant &oldValue, const QVariant &newValue)
+{
+ if(debugPropertyCommands){
+ qDebug() << "PropertyHelper::updateObject(" << m_object->objectName() << ") " << oldValue << " -> " << newValue;
+ }
+ switch (m_objectType) {
+ case OT_Widget: {
+ switch (m_specialProperty) {
+ case SP_ObjectName: {
+ const QString oldName = qvariant_cast<PropertySheetStringValue>(oldValue).value();
+ const QString newName = qvariant_cast<PropertySheetStringValue>(newValue).value();
+ QDesignerFormWindowCommand::updateBuddies(fw, oldName, newName);
+ }
+ break;
+ default:
+ break;
+ }
+ } break;
+ case OT_AssociatedAction:
+ case OT_FreeAction:
+ // SP_Shortcut is a fake property, so, QAction::changed does not trigger.
+ if (m_specialProperty == SP_ObjectName || m_specialProperty == SP_Shortcut)
+ triggerActionChanged(qobject_cast<QAction *>(m_object));
+ break;
+ default:
+ break;
+ }
+
+ switch (m_specialProperty) {
+ case SP_ObjectName:
+ case SP_LayoutName:
+ case SP_SpacerName:
+ if (QDesignerIntegration *integr = integration(fw)) {
+ const QString oldName = qvariant_cast<PropertySheetStringValue>(oldValue).value();
+ const QString newName = qvariant_cast<PropertySheetStringValue>(newValue).value();
+ integr->emitObjectNameChanged(fw, m_object, newName, oldName);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void PropertyHelper::ensureUniqueObjectName(QDesignerFormWindowInterface *fw, QObject *object) const
+{
+ switch (m_specialProperty) {
+ case SP_SpacerName:
+ if (object->isWidgetType()) {
+ if (Spacer *sp = qobject_cast<Spacer *>(object)) {
+ fw->ensureUniqueObjectName(sp);
+ return;
+ }
+ }
+ fw->ensureUniqueObjectName(object);
+ break;
+ case SP_LayoutName: // Layout name is invoked on the parent widget.
+ if (object->isWidgetType()) {
+ const QWidget * w = qobject_cast<const QWidget *>(object);
+ if (QLayout *wlayout = w->layout()) {
+ fw->ensureUniqueObjectName(wlayout);
+ return;
+ }
+ }
+ fw->ensureUniqueObjectName(object);
+ break;
+ case SP_ObjectName:
+ fw->ensureUniqueObjectName(object);
+ break;
+ default:
+ break;
+ }
+}
+
+PropertyHelper::Value PropertyHelper::setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask)
+{
+ // Set new whole value
+ if (subPropertyMask == SubPropertyAll)
+ return applyValue(fw, m_oldValue.first, Value(value, changed));
+
+ // apply subproperties
+ const PropertyHelper::Value maskedNewValue = applySubProperty(m_oldValue.first, value, m_specialProperty, subPropertyMask, changed);
+ return applyValue(fw, m_oldValue.first, maskedNewValue);
+}
+
+// Apply the value and update. Returns corrected value
+PropertyHelper::Value PropertyHelper::applyValue(QDesignerFormWindowInterface *fw, const QVariant &oldValue, Value newValue)
+{
+ if(debugPropertyCommands){
+ qDebug() << "PropertyHelper::applyValue(" << m_object << ") " << oldValue << " -> " << newValue.first << " changed=" << newValue.second;
+ }
+
+ if (m_objectType == OT_Widget) {
+ checkApplyWidgetValue(fw, qobject_cast<QWidget *>(m_object), m_specialProperty, newValue.first);
+ }
+
+ m_propertySheet->setProperty(m_index, newValue.first);
+ m_propertySheet->setChanged(m_index, newValue.second);
+
+ switch (m_specialProperty) {
+ case SP_LayoutName:
+ case SP_ObjectName:
+ case SP_SpacerName:
+ ensureUniqueObjectName(fw, m_object);
+ newValue.first = m_propertySheet->property(m_index);
+ break;
+ default:
+ break;
+ }
+
+ updateObject(fw, oldValue, newValue.first);
+ return newValue;
+}
+
+PropertyHelper::Value PropertyHelper::restoreOldValue(QDesignerFormWindowInterface *fw)
+{
+ return applyValue(fw, m_propertySheet->property(m_index), m_oldValue);
+}
+
+// find the default value in widget DB in case PropertySheet::reset fails
+QVariant PropertyHelper::findDefaultValue(QDesignerFormWindowInterface *fw) const
+{
+ if (m_specialProperty == SP_AutoDefault && qobject_cast<const QPushButton*>(m_object)) {
+ // AutoDefault defaults to true on dialogs
+ const bool isDialog = qobject_cast<const QDialog *>(fw->mainContainer());
+ return QVariant(isDialog);
+ }
+
+ const int item_idx = fw->core()->widgetDataBase()->indexOfObject(m_object);
+ if (item_idx == -1)
+ return m_oldValue.first; // We simply don't know the value in this case
+
+ const QDesignerWidgetDataBaseItemInterface *item = fw->core()->widgetDataBase()->item(item_idx);
+ const QList<QVariant> default_prop_values = item->defaultPropertyValues();
+ if (m_index < default_prop_values.size())
+ return default_prop_values.at(m_index);
+
+ if (m_oldValue.first.type() == QVariant::Color)
+ return QColor();
+
+ return m_oldValue.first; // Again, we just don't know
+}
+
+PropertyHelper::Value PropertyHelper::restoreDefaultValue(QDesignerFormWindowInterface *fw)
+{
+
+ Value defaultValue = qMakePair(QVariant(), false);
+ const QVariant currentValue = m_propertySheet->property(m_index);
+ // try to reset sheet, else try to find default
+ if (m_propertySheet->reset(m_index)) {
+ defaultValue.first = m_propertySheet->property(m_index);
+ } else {
+ defaultValue.first = findDefaultValue(fw);
+ m_propertySheet->setProperty(m_index, defaultValue.first);
+ }
+
+ m_propertySheet->setChanged(m_index, defaultValue.second);
+
+ if (m_objectType == OT_Widget) {
+ checkApplyWidgetValue(fw, qobject_cast<QWidget *>(m_object), m_specialProperty, defaultValue.first);
+ }
+
+ switch (m_specialProperty) {
+ case SP_LayoutName:
+ case SP_ObjectName:
+ case SP_SpacerName:
+ ensureUniqueObjectName(fw, m_object);
+ defaultValue.first = m_propertySheet->property(m_index);
+ break;
+ default:
+ break;
+ }
+
+ updateObject(fw, currentValue, defaultValue.first);
+ return defaultValue;
+}
+
+// ---- PropertyListCommand::PropertyDescription(
+
+
+PropertyListCommand::PropertyDescription::PropertyDescription(const QString &propertyName,
+ QDesignerPropertySheetExtension *propertySheet,
+ int index) :
+ m_propertyName(propertyName),
+ m_propertyGroup(propertySheet->propertyGroup(index)),
+ m_propertyType(propertySheet->property(index).type()),
+ m_specialProperty(getSpecialProperty(propertyName))
+{
+}
+
+PropertyListCommand::PropertyDescription::PropertyDescription() :
+ m_propertyType(QVariant::Invalid),
+ m_specialProperty(SP_None)
+{
+}
+
+void PropertyListCommand::PropertyDescription::debug() const
+{
+ qDebug() << m_propertyName << m_propertyGroup << m_propertyType << m_specialProperty;
+}
+
+bool PropertyListCommand::PropertyDescription::equals(const PropertyDescription &p) const
+{
+ return m_propertyType == p.m_propertyType && m_specialProperty == p.m_specialProperty &&
+ m_propertyName == p.m_propertyName && m_propertyGroup == p.m_propertyGroup;
+}
+
+
+// ---- PropertyListCommand
+PropertyListCommand::PropertyListCommand(QDesignerFormWindowInterface *formWindow,
+ QUndoCommand *parent) :
+ QDesignerFormWindowCommand(QString(), formWindow, parent)
+{
+}
+
+const QString PropertyListCommand::propertyName() const
+{
+ return m_propertyDescription.m_propertyName;
+}
+
+SpecialProperty PropertyListCommand::specialProperty() const
+{
+ return m_propertyDescription.m_specialProperty;
+}
+
+// add an object
+bool PropertyListCommand::add(QObject *object, const QString &propertyName)
+{
+ QDesignerPropertySheetExtension* sheet = propertySheet(object);
+ Q_ASSERT(sheet);
+
+ const int index = sheet->indexOf(propertyName);
+ if (index == -1)
+ return false;
+
+ if (QDesignerPropertySheet *exSheet = qobject_cast<QDesignerPropertySheet*>(core()->extensionManager()->extension(object, Q_TYPEID(QDesignerPropertySheetExtension))))
+ if (!exSheet->isEnabled(index))
+ return false;
+
+ const PropertyDescription description(propertyName, sheet, index);
+
+ if (m_propertyHelperList.empty()) {
+ // first entry
+ m_propertyDescription = description;
+ } else {
+ // checks: mismatch or only one object in case of name
+ const bool match = m_propertyDescription.equals(description);
+ if (!match || m_propertyDescription.m_specialProperty == SP_ObjectName)
+ return false;
+ }
+
+ const PropertyHelperPtr ph(createPropertyHelper(object, m_propertyDescription.m_specialProperty, sheet, index));
+ m_propertyHelperList.push_back(ph);
+ return true;
+}
+
+PropertyHelper *PropertyListCommand::createPropertyHelper(QObject *object, SpecialProperty sp,
+ QDesignerPropertySheetExtension *sheet, int sheetIndex) const
+{
+ return new PropertyHelper(object, sp, sheet, sheetIndex);
+}
+
+// Init from a list and make sure referenceObject is added first to obtain the right property group
+bool PropertyListCommand::initList(const ObjectList &list, const QString &apropertyName, QObject *referenceObject)
+{
+ propertyHelperList().clear();
+
+ // Ensure the referenceObject (property editor) is first, so the right property group is chosen.
+ if (referenceObject) {
+ if (!add(referenceObject, apropertyName))
+ return false;
+ }
+ foreach (QObject *o, list) {
+ if (o != referenceObject)
+ add(o, apropertyName);
+ }
+
+ return !propertyHelperList().empty();
+}
+
+
+QObject* PropertyListCommand::object(int index) const
+{
+ Q_ASSERT(index < m_propertyHelperList.size());
+ return m_propertyHelperList.at(index)->object();
+}
+
+QVariant PropertyListCommand::oldValue(int index) const
+{
+ Q_ASSERT(index < m_propertyHelperList.size());
+ return m_propertyHelperList.at(index)->oldValue();
+}
+
+void PropertyListCommand::setOldValue(const QVariant &oldValue, int index)
+{
+ Q_ASSERT(index < m_propertyHelperList.size());
+ m_propertyHelperList.at(index)->setOldValue(oldValue);
+}
+// ----- SetValueFunction: Set a new value when applied to a PropertyHelper.
+class SetValueFunction {
+public:
+ SetValueFunction(QDesignerFormWindowInterface *formWindow, const PropertyHelper::Value &newValue, unsigned subPropertyMask);
+
+ PropertyHelper::Value operator()(PropertyHelper&);
+private:
+ QDesignerFormWindowInterface *m_formWindow;
+ const PropertyHelper::Value m_newValue;
+ const unsigned m_subPropertyMask;
+};
+
+
+SetValueFunction::SetValueFunction(QDesignerFormWindowInterface *formWindow, const PropertyHelper::Value &newValue, unsigned subPropertyMask) :
+ m_formWindow(formWindow),
+ m_newValue(newValue),
+ m_subPropertyMask(subPropertyMask)
+{
+}
+
+PropertyHelper::Value SetValueFunction::operator()(PropertyHelper &ph) {
+ return ph.setValue(m_formWindow, m_newValue.first, m_newValue.second, m_subPropertyMask);
+}
+
+// ----- UndoSetValueFunction: Restore old value when applied to a PropertyHelper.
+class UndoSetValueFunction {
+public:
+ UndoSetValueFunction(QDesignerFormWindowInterface *formWindow) : m_formWindow(formWindow) {}
+ PropertyHelper::Value operator()(PropertyHelper& ph) { return ph.restoreOldValue(m_formWindow); }
+private:
+ QDesignerFormWindowInterface *m_formWindow;
+};
+
+// ----- RestoreDefaultFunction: Restore default value when applied to a PropertyHelper.
+class RestoreDefaultFunction {
+public:
+ RestoreDefaultFunction(QDesignerFormWindowInterface *formWindow) : m_formWindow(formWindow) {}
+ PropertyHelper::Value operator()(PropertyHelper& ph) { return ph.restoreDefaultValue(m_formWindow); }
+private:
+ QDesignerFormWindowInterface *m_formWindow;
+};
+
+// ----- changePropertyList: Iterates over a sequence of PropertyHelpers and
+// applies a function to them.
+// The function returns the corrected value which is then set in the property editor.
+// Returns a combination of update flags.
+template <class PropertyListIterator, class Function>
+ unsigned changePropertyList(QDesignerFormEditorInterface *core,
+ const QString &propertyName,
+ PropertyListIterator begin,
+ PropertyListIterator end,
+ Function function)
+{
+ unsigned updateMask = 0;
+ QDesignerPropertyEditorInterface *propertyEditor = core->propertyEditor();
+ bool updatedPropertyEditor = false;
+
+ for (PropertyListIterator it = begin; it != end; ++it) {
+ PropertyHelper *ph = it->data();
+ if (QObject* object = ph->object()) { // Might have been deleted in the meantime
+ const PropertyHelper::Value newValue = function( *ph );
+ updateMask |= ph->updateMask();
+ // Update property editor if it is the current object
+ if (!updatedPropertyEditor && propertyEditor && object == propertyEditor->object()) {
+ propertyEditor->setPropertyValue(propertyName, newValue.first, newValue.second);
+ updatedPropertyEditor = true;
+ }
+ }
+ }
+ if (!updatedPropertyEditor) updateMask |= PropertyHelper::UpdatePropertyEditor;
+ return updateMask;
+}
+
+
+// set a new value, return update mask
+unsigned PropertyListCommand::setValue(QVariant value, bool changed, unsigned subPropertyMask)
+{
+ if(debugPropertyCommands)
+ qDebug() << "PropertyListCommand::setValue(" << value
+ << changed << subPropertyMask << ')';
+ return changePropertyList(formWindow()->core(),
+ m_propertyDescription.m_propertyName,
+ m_propertyHelperList.begin(), m_propertyHelperList.end(),
+ SetValueFunction(formWindow(), PropertyHelper::Value(value, changed), subPropertyMask));
+}
+
+// restore old value, return update mask
+unsigned PropertyListCommand::restoreOldValue()
+{
+ if(debugPropertyCommands)
+ qDebug() << "PropertyListCommand::restoreOldValue()";
+
+ return changePropertyList(formWindow()->core(),
+ m_propertyDescription.m_propertyName, m_propertyHelperList.begin(), m_propertyHelperList.end(),
+ UndoSetValueFunction(formWindow()));
+}
+// set default value, return update mask
+unsigned PropertyListCommand::restoreDefaultValue()
+{
+ if(debugPropertyCommands)
+ qDebug() << "PropertyListCommand::restoreDefaultValue()";
+
+ return changePropertyList(formWindow()->core(),
+ m_propertyDescription.m_propertyName, m_propertyHelperList.begin(), m_propertyHelperList.end(),
+ RestoreDefaultFunction(formWindow()));
+}
+
+// update
+void PropertyListCommand::update(unsigned updateMask)
+{
+ if(debugPropertyCommands)
+ qDebug() << "PropertyListCommand::update(" << updateMask << ')';
+
+ if (updateMask & PropertyHelper::UpdateObjectInspector) {
+ if (QDesignerObjectInspectorInterface *oi = formWindow()->core()->objectInspector())
+ oi->setFormWindow(formWindow());
+ }
+
+ if (updateMask & PropertyHelper::UpdatePropertyEditor) {
+ // this is needed when f.ex. undo, changes parent's palette, but
+ // the child is the active widget,
+ // TODO: current object?
+ if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
+ propertyEditor->setObject(propertyEditor->object());
+ }
+ }
+}
+
+void PropertyListCommand::undo()
+{
+ update(restoreOldValue());
+ QDesignerPropertyEditor *designerPropertyEditor = qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor());
+ if (designerPropertyEditor)
+ designerPropertyEditor->updatePropertySheet();
+}
+
+// check if lists are aequivalent for command merging (same widgets and props)
+bool PropertyListCommand::canMergeLists(const PropertyHelperList& other) const
+{
+ if (m_propertyHelperList.size() != other.size())
+ return false;
+ for (int i = 0; i < m_propertyHelperList.size(); i++) {
+ if (!m_propertyHelperList.at(i)->canMerge(*other.at(i)))
+ return false;
+ }
+ return true;
+}
+
+// ---- SetPropertyCommand ----
+SetPropertyCommand::SetPropertyCommand(QDesignerFormWindowInterface *formWindow,
+ QUndoCommand *parent)
+ : PropertyListCommand(formWindow, parent),
+ m_subPropertyMask(SubPropertyAll)
+{
+}
+
+bool SetPropertyCommand::init(QObject *object, const QString &apropertyName, const QVariant &newValue)
+{
+ Q_ASSERT(object);
+
+ m_newValue = newValue;
+
+ propertyHelperList().clear();
+ if (!add(object, apropertyName))
+ return false;
+
+ setDescription();
+ return true;
+}
+
+bool SetPropertyCommand::init(const ObjectList &list, const QString &apropertyName, const QVariant &newValue,
+ QObject *referenceObject, bool enableSubPropertyHandling)
+{
+ if (!initList(list, apropertyName, referenceObject))
+ return false;
+
+ m_newValue = newValue;
+
+ if(debugPropertyCommands)
+ qDebug() << "SetPropertyCommand::init()" << propertyHelperList().size() << '/' << list.size() << " reference " << referenceObject;
+
+ setDescription();
+
+ if (enableSubPropertyHandling)
+ m_subPropertyMask = subPropertyMask(newValue, referenceObject);
+ return true;
+}
+
+unsigned SetPropertyCommand::subPropertyMask(const QVariant &newValue, QObject *referenceObject)
+{
+ // figure out the mask of changed sub properties when comparing newValue to the current value of the reference object.
+ if (!referenceObject)
+ return SubPropertyAll;
+
+ QDesignerPropertySheetExtension* sheet = propertySheet(referenceObject);
+ Q_ASSERT(sheet);
+
+ const int index = sheet->indexOf(propertyName());
+ if (index == -1 || !sheet->isVisible(index))
+ return SubPropertyAll;
+
+ return compareSubProperties(sheet->property(index), newValue, specialProperty());
+}
+
+void SetPropertyCommand::setDescription()
+{
+ if (propertyHelperList().size() == 1) {
+ setText(QApplication::translate("Command", "Changed '%1' of '%2'").arg(propertyName()).arg(propertyHelperList().at(0)->object()->objectName()));
+ } else {
+ int count = propertyHelperList().size();
+ setText(QApplication::translate("Command", "Changed '%1' of %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(propertyName()));
+ }
+}
+
+void SetPropertyCommand::redo()
+{
+ update(setValue(m_newValue, true, m_subPropertyMask));
+ QDesignerPropertyEditor *designerPropertyEditor = qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor());
+ if (designerPropertyEditor)
+ designerPropertyEditor->updatePropertySheet();
+}
+
+
+int SetPropertyCommand::id() const
+{
+ return 1976;
+}
+
+QVariant SetPropertyCommand::mergeValue(const QVariant &newValue)
+{
+ return newValue;
+}
+
+bool SetPropertyCommand::mergeWith(const QUndoCommand *other)
+{
+ if (id() != other->id() || !formWindow()->isDirty())
+ return false;
+
+ // Merging: When for example when the user types ahead in an inplace-editor,
+ // it makes sense to merge all the generated commands containing the one-character changes.
+ // In the case of subproperties, if the user changes the font size from 10 to 30 via 20
+ // and then changes to bold, it makes sense to merge the font size commands only.
+ // This is why the m_subPropertyMask is checked.
+
+ const SetPropertyCommand *cmd = static_cast<const SetPropertyCommand*>(other);
+ if (!propertyDescription().equals(cmd->propertyDescription()) ||
+ m_subPropertyMask != cmd->m_subPropertyMask ||
+ !canMergeLists(cmd->propertyHelperList()))
+ return false;
+
+ const QVariant newValue = mergeValue(cmd->newValue());
+ if (!newValue.isValid())
+ return false;
+ m_newValue = newValue;
+ m_subPropertyMask |= cmd->m_subPropertyMask;
+ if(debugPropertyCommands)
+ qDebug() << "SetPropertyCommand::mergeWith() succeeded " << propertyName();
+
+ return true;
+}
+
+// ---- ResetPropertyCommand ----
+ResetPropertyCommand::ResetPropertyCommand(QDesignerFormWindowInterface *formWindow)
+ : PropertyListCommand(formWindow)
+{
+}
+
+bool ResetPropertyCommand::init(QObject *object, const QString &apropertyName)
+{
+ Q_ASSERT(object);
+
+ propertyHelperList().clear();
+ if (!add(object, apropertyName))
+ return false;
+
+ setDescription();
+ return true;
+}
+
+bool ResetPropertyCommand::init(const ObjectList &list, const QString &apropertyName, QObject *referenceObject)
+{
+ if (!initList(list, apropertyName, referenceObject))
+ return false;
+
+ if(debugPropertyCommands)
+ qDebug() << "ResetPropertyCommand::init()" << propertyHelperList().size() << '/' << list.size();
+
+ setDescription();
+ return true;
+}
+
+void ResetPropertyCommand::setDescription()
+{
+ if (propertyHelperList().size() == 1) {
+ setText(QApplication::translate("Command", "Reset '%1' of '%2'").arg(propertyName()).arg(propertyHelperList().at(0)->object()->objectName()));
+ } else {
+ int count = propertyHelperList().size();
+ setText(QApplication::translate("Command", "Reset '%1' of %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(propertyName()));
+ }
+}
+
+void ResetPropertyCommand::redo()
+{
+ update(restoreDefaultValue());
+ QDesignerPropertyEditor *designerPropertyEditor = qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor());
+ if (designerPropertyEditor)
+ designerPropertyEditor->updatePropertySheet();
+}
+
+AddDynamicPropertyCommand::AddDynamicPropertyCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QString(), formWindow)
+{
+
+}
+
+bool AddDynamicPropertyCommand::init(const QList<QObject *> &selection, QObject *current,
+ const QString &propertyName, const QVariant &value)
+{
+ Q_ASSERT(current);
+ m_propertyName = propertyName;
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), current);
+ Q_ASSERT(dynamicSheet);
+
+ m_selection.clear();
+
+ if (!value.isValid())
+ return false;
+
+ if (!dynamicSheet->canAddDynamicProperty(m_propertyName))
+ return false;
+
+ m_selection.append(current);
+
+ m_value = value;
+
+ QListIterator<QObject *> it(selection);
+ while (it.hasNext()) {
+ QObject *obj = it.next();
+ if (m_selection.contains(obj))
+ continue;
+ dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
+ Q_ASSERT(dynamicSheet);
+ if (dynamicSheet->canAddDynamicProperty(m_propertyName))
+ m_selection.append(obj);
+ }
+
+ setDescription();
+ return true;
+}
+
+void AddDynamicPropertyCommand::redo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QListIterator<QObject *> it(m_selection);
+ while (it.hasNext()) {
+ QObject *obj = it.next();
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
+ dynamicSheet->addDynamicProperty(m_propertyName, m_value);
+ if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
+ if (propertyEditor->object() == obj)
+ propertyEditor->setObject(obj);
+ }
+ }
+}
+
+void AddDynamicPropertyCommand::undo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QListIterator<QObject *> it(m_selection);
+ while (it.hasNext()) {
+ QObject *obj = it.next();
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), obj);
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
+ dynamicSheet->removeDynamicProperty(sheet->indexOf(m_propertyName));
+ if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
+ if (propertyEditor->object() == obj)
+ propertyEditor->setObject(obj);
+ }
+ }
+}
+
+void AddDynamicPropertyCommand::setDescription()
+{
+ if (m_selection.size() == 1) {
+ setText(QApplication::translate("Command", "Add dynamic property '%1' to '%2'").arg(m_propertyName).arg(m_selection.first()->objectName()));
+ } else {
+ int count = m_selection.size();
+ setText(QApplication::translate("Command", "Add dynamic property '%1' to %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(m_propertyName));
+ }
+}
+
+
+RemoveDynamicPropertyCommand::RemoveDynamicPropertyCommand(QDesignerFormWindowInterface *formWindow)
+ : QDesignerFormWindowCommand(QString(), formWindow)
+{
+
+}
+
+bool RemoveDynamicPropertyCommand::init(const QList<QObject *> &selection, QObject *current,
+ const QString &propertyName)
+{
+ Q_ASSERT(current);
+ m_propertyName = propertyName;
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QDesignerPropertySheetExtension *propertySheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), current);
+ Q_ASSERT(propertySheet);
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), current);
+ Q_ASSERT(dynamicSheet);
+
+ m_objectToValueAndChanged.clear();
+
+ const int index = propertySheet->indexOf(m_propertyName);
+ if (!dynamicSheet->isDynamicProperty(index))
+ return false;
+
+ m_objectToValueAndChanged[current] = qMakePair(propertySheet->property(index), propertySheet->isChanged(index));
+
+ QListIterator<QObject *> it(selection);
+ while (it.hasNext()) {
+ QObject *obj = it.next();
+ if (m_objectToValueAndChanged.contains(obj))
+ continue;
+
+ propertySheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), obj);
+ dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
+ const int idx = propertySheet->indexOf(m_propertyName);
+ if (dynamicSheet->isDynamicProperty(idx))
+ m_objectToValueAndChanged[obj] = qMakePair(propertySheet->property(idx), propertySheet->isChanged(idx));
+ }
+
+ setDescription();
+ return true;
+}
+
+void RemoveDynamicPropertyCommand::redo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QMap<QObject *, QPair<QVariant, bool> >::ConstIterator it = m_objectToValueAndChanged.constBegin();
+ while (it != m_objectToValueAndChanged.constEnd()) {
+ QObject *obj = it.key();
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), obj);
+ dynamicSheet->removeDynamicProperty(sheet->indexOf(m_propertyName));
+ if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
+ if (propertyEditor->object() == obj)
+ propertyEditor->setObject(obj);
+ }
+ ++it;
+ }
+}
+
+void RemoveDynamicPropertyCommand::undo()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ QMap<QObject *, QPair<QVariant, bool> >::ConstIterator it = m_objectToValueAndChanged.constBegin();
+ while (it != m_objectToValueAndChanged.constEnd()) {
+ QObject *obj = it.key();
+ QDesignerPropertySheetExtension *propertySheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), obj);
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core->extensionManager(), obj);
+ const int index = dynamicSheet->addDynamicProperty(m_propertyName, it.value().first);
+ propertySheet->setChanged(index, it.value().second);
+ if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
+ if (propertyEditor->object() == obj)
+ propertyEditor->setObject(obj);
+ }
+ ++it;
+ }
+}
+
+void RemoveDynamicPropertyCommand::setDescription()
+{
+ if (m_objectToValueAndChanged.size() == 1) {
+ setText(QApplication::translate("Command", "Remove dynamic property '%1' from '%2'").arg(m_propertyName).arg(m_objectToValueAndChanged.constBegin().key()->objectName()));
+ } else {
+ int count = m_objectToValueAndChanged.size();
+ setText(QApplication::translate("Command", "Remove dynamic property '%1' from %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(m_propertyName));
+ }
+}
+
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_propertycommand_p.h b/src/designer/src/lib/shared/qdesigner_propertycommand_p.h
new file mode 100644
index 000000000..0dc1825fe
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_propertycommand_p.h
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_PROPERTYCOMMAND_H
+#define QDESIGNER_PROPERTYCOMMAND_H
+
+#include "qdesigner_formwindowcommand_p.h"
+
+#include <QtCore/QVariant>
+#include <QtCore/QList>
+#include <QtCore/QPair>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerPropertySheetExtension;
+
+namespace qdesigner_internal {
+
+class QDesignerIntegration;
+
+enum SpecialProperty {
+ SP_None, SP_ObjectName, SP_LayoutName, SP_SpacerName,SP_WindowTitle,
+ SP_MinimumSize, SP_MaximumSize, SP_Geometry, SP_Icon, SP_CurrentTabName, SP_CurrentItemName, SP_CurrentPageName,
+ SP_AutoDefault, SP_Alignment, SP_Shortcut, SP_Orientation
+};
+
+//Determine special property
+enum SpecialProperty getSpecialProperty(const QString& propertyName);
+
+// A helper class for applying properties to objects.
+// Can be used for Set commands (setValue(), restoreOldValue()) or
+// Reset Commands restoreDefaultValue(), restoreOldValue()).
+//
+class QDESIGNER_SHARED_EXPORT PropertyHelper {
+ Q_DISABLE_COPY(PropertyHelper)
+public:
+ // A pair of Value and changed flag
+ typedef QPair<QVariant, bool> Value;
+
+ enum ObjectType {OT_Object, OT_FreeAction, OT_AssociatedAction, OT_Widget};
+
+ PropertyHelper(QObject* object,
+ SpecialProperty specialProperty,
+ QDesignerPropertySheetExtension *sheet,
+ int index);
+ virtual ~PropertyHelper() {}
+
+ QObject *object() const { return m_object; }
+ SpecialProperty specialProperty() const { return m_specialProperty; }
+ // set a new value. Can be overwritten to perform a transformation (see
+ // handling of Arrow key move in FormWindow class).
+ virtual Value setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask);
+
+ // restore old value
+ Value restoreOldValue(QDesignerFormWindowInterface *fw);
+ // set default value
+ Value restoreDefaultValue(QDesignerFormWindowInterface *fw);
+
+ inline QVariant oldValue() const
+ { return m_oldValue.first; }
+
+ inline void setOldValue(const QVariant &oldValue)
+ { m_oldValue.first = oldValue; }
+
+ // required updates for this property (bit mask)
+ enum UpdateMask { UpdatePropertyEditor=1, UpdateObjectInspector=2 };
+ unsigned updateMask() const;
+
+ // can be merged into one command (that is, object and name match)
+ bool canMerge(const PropertyHelper &other) const;
+ QDesignerIntegration *integration(QDesignerFormWindowInterface *fw) const;
+
+ static void triggerActionChanged(QAction *a);
+
+private:
+ // Apply the value and update. Returns corrected value
+ Value applyValue(QDesignerFormWindowInterface *fw, const QVariant &oldValue, Value newValue);
+
+ static void checkApplyWidgetValue(QDesignerFormWindowInterface *fw, QWidget* w,
+ SpecialProperty specialProperty, QVariant &v);
+
+ void updateObject(QDesignerFormWindowInterface *fw, const QVariant &oldValue, const QVariant &newValue);
+ QVariant findDefaultValue(QDesignerFormWindowInterface *fw) const;
+ void ensureUniqueObjectName(QDesignerFormWindowInterface *fw, QObject *object) const;
+ SpecialProperty m_specialProperty;
+
+ QPointer<QObject> m_object;
+ ObjectType m_objectType;
+ QPointer<QWidget> m_parentWidget;
+
+ QDesignerPropertySheetExtension *m_propertySheet;
+ int m_index;
+
+ Value m_oldValue;
+};
+
+// Base class for commands that can be applied to several widgets
+
+class QDESIGNER_SHARED_EXPORT PropertyListCommand : public QDesignerFormWindowCommand {
+public:
+ typedef QList<QObject *> ObjectList;
+
+ explicit PropertyListCommand(QDesignerFormWindowInterface *formWindow, QUndoCommand *parent = 0);
+
+ QObject* object(int index = 0) const;
+
+ QVariant oldValue(int index = 0) const;
+
+ void setOldValue(const QVariant &oldValue, int index = 0);
+
+ // Calls restoreDefaultValue() and update()
+ virtual void undo();
+
+protected:
+ typedef QSharedPointer<PropertyHelper> PropertyHelperPtr;
+ typedef QList<PropertyHelperPtr> PropertyHelperList;
+
+ // add an object
+ bool add(QObject *object, const QString &propertyName);
+
+ // Init from a list and make sure referenceObject is added first to obtain the right property group
+ bool initList(const ObjectList &list, const QString &apropertyName, QObject *referenceObject = 0);
+
+ // set a new value, return update mask
+ unsigned setValue(QVariant value, bool changed, unsigned subPropertyMask);
+
+ // restore old value, return update mask
+ unsigned restoreOldValue();
+ // set default value, return update mask
+ unsigned restoreDefaultValue();
+
+ // update designer
+ void update(unsigned updateMask);
+
+ // check if lists are aequivalent for command merging (same widgets and props)
+ bool canMergeLists(const PropertyHelperList& other) const;
+
+ PropertyHelperList& propertyHelperList() { return m_propertyHelperList; }
+ const PropertyHelperList& propertyHelperList() const { return m_propertyHelperList; }
+
+ const QString propertyName() const;
+ SpecialProperty specialProperty() const;
+
+ // Helper struct describing a property used for checking whether
+ // properties of different widgets are equivalent
+ struct PropertyDescription {
+ public:
+ PropertyDescription();
+ PropertyDescription(const QString &propertyName, QDesignerPropertySheetExtension *propertySheet, int index);
+ bool equals(const PropertyDescription &p) const;
+ void debug() const;
+
+ QString m_propertyName;
+ QString m_propertyGroup;
+ QVariant::Type m_propertyType;
+ SpecialProperty m_specialProperty;
+ };
+ const PropertyDescription &propertyDescription() const { return m_propertyDescription; }
+
+protected:
+ virtual PropertyHelper *createPropertyHelper(QObject *o, SpecialProperty sp,
+ QDesignerPropertySheetExtension *sheet, int sheetIndex) const;
+
+private:
+ PropertyDescription m_propertyDescription;
+ PropertyHelperList m_propertyHelperList;
+};
+
+class QDESIGNER_SHARED_EXPORT SetPropertyCommand: public PropertyListCommand
+{
+
+public:
+ typedef QList<QObject *> ObjectList;
+
+ explicit SetPropertyCommand(QDesignerFormWindowInterface *formWindow, QUndoCommand *parent = 0);
+
+ bool init(QObject *object, const QString &propertyName, const QVariant &newValue);
+ bool init(const ObjectList &list, const QString &propertyName, const QVariant &newValue,
+ QObject *referenceObject = 0, bool enableSubPropertyHandling = true);
+
+
+ inline QVariant newValue() const
+ { return m_newValue; }
+
+ inline void setNewValue(const QVariant &newValue)
+ { m_newValue = newValue; }
+
+ int id() const;
+ bool mergeWith(const QUndoCommand *other);
+
+ virtual void redo();
+
+protected:
+ virtual QVariant mergeValue(const QVariant &newValue);
+
+private:
+ unsigned subPropertyMask(const QVariant &newValue, QObject *referenceObject);
+ void setDescription();
+ QVariant m_newValue;
+ unsigned m_subPropertyMask;
+};
+
+class QDESIGNER_SHARED_EXPORT ResetPropertyCommand: public PropertyListCommand
+{
+
+public:
+ typedef QList<QObject *> ObjectList;
+
+ explicit ResetPropertyCommand(QDesignerFormWindowInterface *formWindow);
+
+ bool init(QObject *object, const QString &propertyName);
+ bool init(const ObjectList &list, const QString &propertyName, QObject *referenceObject = 0);
+
+ virtual void redo();
+
+protected:
+ virtual bool mergeWith(const QUndoCommand *) { return false; }
+
+private:
+ void setDescription();
+ QString m_propertyName;
+};
+
+
+class QDESIGNER_SHARED_EXPORT AddDynamicPropertyCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit AddDynamicPropertyCommand(QDesignerFormWindowInterface *formWindow);
+
+ bool init(const QList<QObject *> &selection, QObject *current, const QString &propertyName, const QVariant &value);
+
+ virtual void redo();
+ virtual void undo();
+private:
+ void setDescription();
+ QString m_propertyName;
+ QList<QObject *> m_selection;
+ QVariant m_value;
+};
+
+class QDESIGNER_SHARED_EXPORT RemoveDynamicPropertyCommand: public QDesignerFormWindowCommand
+{
+
+public:
+ explicit RemoveDynamicPropertyCommand(QDesignerFormWindowInterface *formWindow);
+
+ bool init(const QList<QObject *> &selection, QObject *current, const QString &propertyName);
+
+ virtual void redo();
+ virtual void undo();
+private:
+ void setDescription();
+ QString m_propertyName;
+ QMap<QObject *, QPair<QVariant, bool> > m_objectToValueAndChanged;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_PROPERTYCOMMAND_H
diff --git a/src/designer/src/lib/shared/qdesigner_propertyeditor.cpp b/src/designer/src/lib/shared/qdesigner_propertyeditor.cpp
new file mode 100644
index 000000000..e3a92e289
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_propertyeditor.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_propertyeditor_p.h"
+#include "pluginmanager_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <widgetfactory_p.h>
+#include <QtGui/QAction>
+#include <QtGui/QLineEdit>
+#include <QtGui/QAbstractButton>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+typedef QDesignerPropertyEditor::StringPropertyParameters StringPropertyParameters;
+// A map of property name to type
+typedef QHash<QString, StringPropertyParameters> PropertyNameTypeMap;
+
+// Compile a map of hard-coded string property types
+static const PropertyNameTypeMap &stringPropertyTypes()
+{
+ static PropertyNameTypeMap propertyNameTypeMap;
+ if (propertyNameTypeMap.empty()) {
+ const StringPropertyParameters richtext(ValidationRichText, true);
+ // Accessibility. Both are texts the narrator reads
+ propertyNameTypeMap.insert(QLatin1String("accessibleDescription"), richtext);
+ propertyNameTypeMap.insert(QLatin1String("accessibleName"), richtext);
+ // object names
+ const StringPropertyParameters objectName(ValidationObjectName, false);
+ propertyNameTypeMap.insert(QLatin1String("buddy"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("currentItemName"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("currentPageName"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("currentTabName"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("layoutName"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("spacerName"), objectName);
+ // Style sheet
+ propertyNameTypeMap.insert(QLatin1String("styleSheet"), StringPropertyParameters(ValidationStyleSheet, false));
+ // Buttons/ QCommandLinkButton
+ const StringPropertyParameters multiline(ValidationMultiLine, true);
+ propertyNameTypeMap.insert(QLatin1String("description"), multiline);
+ propertyNameTypeMap.insert(QLatin1String("iconText"), multiline);
+ // Tooltips, etc.
+ propertyNameTypeMap.insert(QLatin1String("toolTip"), richtext);
+ propertyNameTypeMap.insert(QLatin1String("whatsThis"), richtext);
+ propertyNameTypeMap.insert(QLatin1String("windowIconText"), richtext);
+ propertyNameTypeMap.insert(QLatin1String("html"), richtext);
+ // A QWizard page id
+ propertyNameTypeMap.insert(QLatin1String("pageId"), StringPropertyParameters(ValidationSingleLine, false));
+ // QPlainTextEdit
+ propertyNameTypeMap.insert(QLatin1String("plainText"), StringPropertyParameters(ValidationMultiLine, true));
+ }
+ return propertyNameTypeMap;
+}
+
+QDesignerPropertyEditor::QDesignerPropertyEditor(QWidget *parent, Qt::WindowFlags flags) :
+ QDesignerPropertyEditorInterface(parent, flags),
+ m_propertyChangedForwardingBlocked(false)
+{
+ // Make old signal work for compatibility
+ connect(this, SIGNAL(propertyChanged(QString,QVariant)), this, SLOT(slotPropertyChanged(QString,QVariant)));
+}
+
+QDesignerPropertyEditor::StringPropertyParameters QDesignerPropertyEditor::textPropertyValidationMode(
+ QDesignerFormEditorInterface *core, const QObject *object,
+ const QString &propertyName, bool isMainContainer)
+{
+ // object name - no comment
+ if (propertyName == QLatin1String("objectName")) {
+ const TextPropertyValidationMode vm = isMainContainer ? ValidationObjectNameScope : ValidationObjectName;
+ return StringPropertyParameters(vm, false);
+ }
+
+ // Check custom widgets by class.
+ const QString className = WidgetFactory::classNameOf(core, object);
+ const QDesignerCustomWidgetData customData = core->pluginManager()->customWidgetData(className);
+ if (!customData.isNull()) {
+ StringPropertyParameters customType;
+ if (customData.xmlStringPropertyType(propertyName, &customType))
+ return customType;
+ }
+
+ // Check hardcoded property ames
+ const PropertyNameTypeMap::const_iterator hit = stringPropertyTypes().constFind(propertyName);
+ if (hit != stringPropertyTypes().constEnd())
+ return hit.value();
+
+ // text: Check according to widget type.
+ if (propertyName == QLatin1String("text")) {
+ if (qobject_cast<const QAction *>(object) || qobject_cast<const QLineEdit *>(object))
+ return StringPropertyParameters(ValidationSingleLine, true);
+ if (qobject_cast<const QAbstractButton *>(object))
+ return StringPropertyParameters(ValidationMultiLine, true);
+ return StringPropertyParameters(ValidationRichText, true);
+ }
+
+ // Fuzzy matching
+ if (propertyName.endsWith(QLatin1String("Name")))
+ return StringPropertyParameters(ValidationSingleLine, true);
+
+ if (propertyName.endsWith(QLatin1String("ToolTip")))
+ return StringPropertyParameters(ValidationRichText, true);
+
+#ifdef Q_OS_WIN // No translation for the active X "control" property
+ if (propertyName == QLatin1String("control") && className == QLatin1String("QAxWidget"))
+ return StringPropertyParameters(ValidationSingleLine, false);
+#endif
+
+ // default to single
+ return StringPropertyParameters(ValidationSingleLine, true);
+}
+
+void QDesignerPropertyEditor::emitPropertyValueChanged(const QString &name, const QVariant &value, bool enableSubPropertyHandling)
+{
+ // Avoid duplicate signal emission - see below
+ m_propertyChangedForwardingBlocked = true;
+ emit propertyValueChanged(name, value, enableSubPropertyHandling);
+ emit propertyChanged(name, value);
+ m_propertyChangedForwardingBlocked = false;
+}
+
+void QDesignerPropertyEditor::slotPropertyChanged(const QString &name, const QVariant &value)
+{
+ // Forward signal from Integration using the old interfaces.
+ if (!m_propertyChangedForwardingBlocked)
+ emit propertyValueChanged(name, value, true);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_propertyeditor_p.h b/src/designer/src/lib/shared/qdesigner_propertyeditor_p.h
new file mode 100644
index 000000000..72d6f05b6
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_propertyeditor_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef DESIGNERPROPERTYEDITOR_H
+#define DESIGNERPROPERTYEDITOR_H
+
+#include "shared_global_p.h"
+#include "shared_enums_p.h"
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+// Extends the QDesignerPropertyEditorInterface by property comment handling and
+// a signal for resetproperty.
+
+class QDESIGNER_SHARED_EXPORT QDesignerPropertyEditor: public QDesignerPropertyEditorInterface
+{
+ Q_OBJECT
+public:
+ explicit QDesignerPropertyEditor(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+
+ // A pair <ValidationMode, bool isTranslatable>.
+ typedef QPair<TextPropertyValidationMode, bool> StringPropertyParameters;
+
+ // Return a pair of validation mode and flag indicating whether property is translatable
+ // for textual properties.
+ static StringPropertyParameters textPropertyValidationMode(QDesignerFormEditorInterface *core,
+ const QObject *object, const QString &propertyName, bool isMainContainer);
+
+Q_SIGNALS:
+ void propertyValueChanged(const QString &name, const QVariant &value, bool enableSubPropertyHandling);
+ void resetProperty(const QString &name);
+ void addDynamicProperty(const QString &name, const QVariant &value);
+ void removeDynamicProperty(const QString &name);
+ void editorOpened();
+ void editorClosed();
+
+public Q_SLOTS:
+ /* Quick update that assumes the actual count of properties has not changed
+ * (as opposed to setObject()). N/A when for example executing a
+ * layout command and margin properties appear. */
+ virtual void updatePropertySheet() = 0;
+ virtual void reloadResourceProperties() = 0;
+
+private Q_SLOTS:
+ void slotPropertyChanged(const QString &name, const QVariant &value);
+
+protected:
+ void emitPropertyValueChanged(const QString &name, const QVariant &value, bool enableSubPropertyHandling);
+
+private:
+ bool m_propertyChangedForwardingBlocked;
+
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // DESIGNERPROPERTYEDITOR_H
diff --git a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
new file mode 100644
index 000000000..27527da05
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp
@@ -0,0 +1,1657 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_propertysheet_p.h"
+#include "qdesigner_utils_p.h"
+#include "formwindowbase_p.h"
+#include "layoutinfo_p.h"
+#include "qlayout_widget_p.h"
+#include "qdesigner_introspection_p.h"
+
+#include <formbuilderextra_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+
+#include <QtCore/QDebug>
+
+#include <QtGui/QLayout>
+#include <QtGui/QDockWidget>
+#include <QtGui/QDialog>
+#include <QtGui/QLabel>
+#include <QtGui/QGroupBox>
+#include <QtGui/QStyle>
+#include <QtGui/QApplication>
+#include <QtGui/QToolBar>
+#include <QtGui/QMainWindow>
+#include <QtGui/QMenuBar>
+
+QT_BEGIN_NAMESPACE
+
+#define USE_LAYOUT_SIZE_CONSTRAINT
+
+static const QDesignerMetaObjectInterface *propertyIntroducedBy(const QDesignerMetaObjectInterface *meta, int index)
+{
+ if (index >= meta->propertyOffset())
+ return meta;
+
+ if (meta->superClass())
+ return propertyIntroducedBy(meta->superClass(), index);
+
+ return 0;
+}
+
+// Layout fake properties (prefixed by 'layout' to distinguish them from other 'margins'
+// that might be around. These are forwarded to the layout sheet (after name transformation).
+//
+// 'layoutObjectName' is new for 4.4. It is the name of the actual layout.
+// Up to 4.3, QLayoutWidget's name was displayed in the objectinspector.
+// This changes with 4.4; the layout name is displayed. This means that for
+// old forms, QLayoutWidget will show up as ''; however, the uic code will
+// still use 'verticalLayout' (in case someone accesses it). New Layouts get autogenerated names,
+// legacy forms will keep their empty names (unless someone types in a new name).
+static const char *layoutObjectNameC = "layoutName";
+static const char *layoutLeftMarginC = "layoutLeftMargin";
+static const char *layoutTopMarginC = "layoutTopMargin";
+static const char *layoutRightMarginC = "layoutRightMargin";
+static const char *layoutBottomMarginC = "layoutBottomMargin";
+static const char *layoutSpacingC = "layoutSpacing";
+static const char *layoutHorizontalSpacingC = "layoutHorizontalSpacing";
+static const char *layoutVerticalSpacingC = "layoutVerticalSpacing";
+static const char *layoutSizeConstraintC = "layoutSizeConstraint";
+// form layout
+static const char *layoutFieldGrowthPolicyC = "layoutFieldGrowthPolicy";
+static const char *layoutRowWrapPolicyC = "layoutRowWrapPolicy";
+static const char *layoutLabelAlignmentC = "layoutLabelAlignment";
+static const char *layoutFormAlignmentC = "layoutFormAlignment";
+// stretches
+static const char *layoutboxStretchPropertyC = "layoutStretch";
+static const char *layoutGridRowStretchPropertyC = "layoutRowStretch";
+static const char *layoutGridColumnStretchPropertyC = "layoutColumnStretch";
+static const char *layoutGridRowMinimumHeightC = "layoutRowMinimumHeight";
+static const char *layoutGridColumnMinimumWidthC = "layoutColumnMinimumWidth";
+
+// Find the form editor in the hierarchy.
+// We know that the parent of the sheet is the extension manager
+// whose parent is the core.
+
+static QDesignerFormEditorInterface *formEditorForObject(QObject *o) {
+ do {
+ if (QDesignerFormEditorInterface* core = qobject_cast<QDesignerFormEditorInterface*>(o))
+ return core;
+ o = o->parent();
+ } while(o);
+ Q_ASSERT(o);
+ return 0;
+}
+
+static bool hasLayoutAttributes(QDesignerFormEditorInterface *core, QObject *object)
+{
+ if (!object->isWidgetType())
+ return false;
+
+ QWidget *w = qobject_cast<QWidget *>(object);
+ if (const QDesignerWidgetDataBaseInterface *db = core->widgetDataBase()) {
+ if (db->isContainer(w))
+ return true;
+ }
+ return false;
+}
+
+// Cache DesignerMetaEnum by scope/name of a QMetaEnum
+static const qdesigner_internal::DesignerMetaEnum &designerMetaEnumFor(const QDesignerMetaEnumInterface *me)
+{
+ typedef QPair<QString, QString> ScopeNameKey;
+ typedef QMap<ScopeNameKey, qdesigner_internal::DesignerMetaEnum> DesignerMetaEnumCache;
+ static DesignerMetaEnumCache cache;
+
+ const QString name = me->name();
+ const QString scope = me->scope();
+
+ const ScopeNameKey key = ScopeNameKey(scope, name);
+ DesignerMetaEnumCache::iterator it = cache.find(key);
+ if (it == cache.end()) {
+ qdesigner_internal::DesignerMetaEnum dme = qdesigner_internal::DesignerMetaEnum(name, scope, me->separator());
+ const int keyCount = me->keyCount();
+ for (int i=0; i < keyCount; ++i)
+ dme.addKey(me->value(i), me->key(i));
+ it = cache.insert(key, dme);
+ }
+ return it.value();
+}
+
+// Cache DesignerMetaFlags by scope/name of a QMetaEnum
+static const qdesigner_internal::DesignerMetaFlags &designerMetaFlagsFor(const QDesignerMetaEnumInterface *me)
+{
+ typedef QPair<QString, QString> ScopeNameKey;
+ typedef QMap<ScopeNameKey, qdesigner_internal::DesignerMetaFlags> DesignerMetaFlagsCache;
+ static DesignerMetaFlagsCache cache;
+
+ const QString name = me->name();
+ const QString scope = me->scope();
+
+ const ScopeNameKey key = ScopeNameKey(scope, name);
+ DesignerMetaFlagsCache::iterator it = cache.find(key);
+ if (it == cache.end()) {
+ qdesigner_internal::DesignerMetaFlags dme = qdesigner_internal::DesignerMetaFlags(name, scope, me->separator());
+ const int keyCount = me->keyCount();
+ for (int i=0; i < keyCount; ++i)
+ dme.addKey(me->value(i), me->key(i));
+ it = cache.insert(key, dme);
+ }
+ return it.value();
+}
+
+// ------------ QDesignerMemberSheetPrivate
+class QDesignerPropertySheetPrivate {
+public:
+ typedef QDesignerPropertySheet::PropertyType PropertyType;
+ typedef QDesignerPropertySheet::ObjectType ObjectType;
+
+ explicit QDesignerPropertySheetPrivate(QDesignerPropertySheet *sheetPublic, QObject *object, QObject *sheetParent);
+
+ bool invalidIndex(const char *functionName, int index) const;
+ inline int count() const { return m_meta->propertyCount() + m_addProperties.count(); }
+
+ PropertyType propertyType(int index) const;
+ QString transformLayoutPropertyName(int index) const;
+ QLayout* layout(QDesignerPropertySheetExtension **layoutPropertySheet = 0) const;
+ static ObjectType objectType(const QObject *o);
+
+ bool isReloadableProperty(int index) const;
+ bool isResourceProperty(int index) const;
+ void addResourceProperty(int index, QVariant::Type type);
+ QVariant resourceProperty(int index) const;
+ void setResourceProperty(int index, const QVariant &value);
+ QVariant emptyResourceProperty(int index) const; // of type PropertySheetPixmapValue / PropertySheetIconValue
+ QVariant defaultResourceProperty(int index) const; // of type QPixmap / QIcon (maybe it can be generalized for all types, not resource only)
+
+ bool isStringProperty(int index) const;
+ void addStringProperty(int index);
+ qdesigner_internal::PropertySheetStringValue stringProperty(int index) const;
+ void setStringProperty(int index, const qdesigner_internal::PropertySheetStringValue &value);
+
+ bool isKeySequenceProperty(int index) const;
+ void addKeySequenceProperty(int index);
+ qdesigner_internal::PropertySheetKeySequenceValue keySequenceProperty(int index) const;
+ void setKeySequenceProperty(int index, const qdesigner_internal::PropertySheetKeySequenceValue &value);
+
+ enum PropertyKind { NormalProperty, FakeProperty, DynamicProperty, DefaultDynamicProperty };
+ class Info {
+ public:
+ Info();
+
+ QString group;
+ QVariant defaultValue;
+ bool changed;
+ bool visible;
+ bool attribute;
+ bool reset;
+ PropertyType propertyType;
+ PropertyKind kind;
+ };
+
+ Info &ensureInfo(int index);
+
+ QDesignerPropertySheet *q;
+ QDesignerFormEditorInterface *m_core;
+ const QDesignerMetaObjectInterface *m_meta;
+ const ObjectType m_objectType;
+
+ typedef QHash<int, Info> InfoHash;
+ InfoHash m_info;
+ QHash<int, QVariant> m_fakeProperties;
+ QHash<int, QVariant> m_addProperties;
+ QHash<QString, int> m_addIndex;
+ QHash<int, QVariant> m_resourceProperties; // only PropertySheetPixmapValue snd PropertySheetIconValue here
+ QHash<int, qdesigner_internal::PropertySheetStringValue> m_stringProperties; // only PropertySheetStringValue
+ QHash<int, qdesigner_internal::PropertySheetKeySequenceValue> m_keySequenceProperties; // only PropertySheetKeySequenceValue
+
+ const bool m_canHaveLayoutAttributes;
+
+ // Variables used for caching the layout, access via layout().
+ QPointer<QObject> m_object;
+ mutable QPointer<QLayout> m_lastLayout;
+ mutable QDesignerPropertySheetExtension *m_lastLayoutPropertySheet;
+ mutable bool m_LastLayoutByDesigner;
+
+ qdesigner_internal::DesignerPixmapCache *m_pixmapCache;
+ qdesigner_internal::DesignerIconCache *m_iconCache;
+ QPointer<qdesigner_internal::FormWindowBase> m_fwb;
+
+ // Enable Qt's internal properties starting with prefix "_q_"
+ static bool m_internalDynamicPropertiesEnabled;
+};
+
+bool QDesignerPropertySheetPrivate::m_internalDynamicPropertiesEnabled = false;
+
+/*
+ The property is reloadable if its contents depends on resource.
+*/
+bool QDesignerPropertySheetPrivate::isReloadableProperty(int index) const
+{
+ return isResourceProperty(index)
+ || propertyType(index) == QDesignerPropertySheet::PropertyStyleSheet
+ || propertyType(index) == QDesignerPropertySheet::PropertyText
+ || q->property(index).type() == QVariant::Url;
+}
+
+/*
+ Resource properties are those which:
+ 1) are reloadable
+ 2) their state is associated with a file which can be taken from resources
+ 3) we don't store them in Qt meta object system (because designer keeps different data structure for them)
+*/
+
+bool QDesignerPropertySheetPrivate::isResourceProperty(int index) const
+{
+ return m_resourceProperties.contains(index);
+}
+
+void QDesignerPropertySheetPrivate::addResourceProperty(int index, QVariant::Type type)
+{
+ if (type == QVariant::Pixmap)
+ m_resourceProperties.insert(index, QVariant::fromValue(qdesigner_internal::PropertySheetPixmapValue()));
+ else if (type == QVariant::Icon)
+ m_resourceProperties.insert(index, QVariant::fromValue(qdesigner_internal::PropertySheetIconValue()));
+}
+
+QVariant QDesignerPropertySheetPrivate::emptyResourceProperty(int index) const
+{
+ QVariant v = m_resourceProperties.value(index);
+ if (v.canConvert<qdesigner_internal::PropertySheetPixmapValue>())
+ return QVariant::fromValue(qdesigner_internal::PropertySheetPixmapValue());
+ if (v.canConvert<qdesigner_internal::PropertySheetIconValue>())
+ return QVariant::fromValue(qdesigner_internal::PropertySheetIconValue());
+ return v;
+}
+
+QVariant QDesignerPropertySheetPrivate::defaultResourceProperty(int index) const
+{
+ return m_info.value(index).defaultValue;
+}
+
+QVariant QDesignerPropertySheetPrivate::resourceProperty(int index) const
+{
+ return m_resourceProperties.value(index);
+}
+
+void QDesignerPropertySheetPrivate::setResourceProperty(int index, const QVariant &value)
+{
+ Q_ASSERT(isResourceProperty(index));
+
+ QVariant &v = m_resourceProperties[index];
+ if ((value.canConvert<qdesigner_internal::PropertySheetPixmapValue>() && v.canConvert<qdesigner_internal::PropertySheetPixmapValue>())
+ || (value.canConvert<qdesigner_internal::PropertySheetIconValue>() && v.canConvert<qdesigner_internal::PropertySheetIconValue>()))
+ v = value;
+}
+
+bool QDesignerPropertySheetPrivate::isStringProperty(int index) const
+{
+ return m_stringProperties.contains(index);
+}
+
+void QDesignerPropertySheetPrivate::addStringProperty(int index)
+{
+ m_stringProperties.insert(index, qdesigner_internal::PropertySheetStringValue());
+}
+
+qdesigner_internal::PropertySheetStringValue QDesignerPropertySheetPrivate::stringProperty(int index) const
+{
+ return m_stringProperties.value(index);
+}
+
+void QDesignerPropertySheetPrivate::setStringProperty(int index, const qdesigner_internal::PropertySheetStringValue &value)
+{
+ Q_ASSERT(isStringProperty(index));
+
+ m_stringProperties[index] = value;
+}
+
+bool QDesignerPropertySheetPrivate::isKeySequenceProperty(int index) const
+{
+ return m_keySequenceProperties.contains(index);
+}
+
+void QDesignerPropertySheetPrivate::addKeySequenceProperty(int index)
+{
+ m_keySequenceProperties.insert(index, qdesigner_internal::PropertySheetKeySequenceValue());
+}
+
+qdesigner_internal::PropertySheetKeySequenceValue QDesignerPropertySheetPrivate::keySequenceProperty(int index) const
+{
+ return m_keySequenceProperties.value(index);
+}
+
+void QDesignerPropertySheetPrivate::setKeySequenceProperty(int index, const qdesigner_internal::PropertySheetKeySequenceValue &value)
+{
+ Q_ASSERT(isKeySequenceProperty(index));
+
+ m_keySequenceProperties[index] = value;
+}
+
+QDesignerPropertySheetPrivate::Info::Info() :
+ changed(false),
+ visible(true),
+ attribute(false),
+ reset(true),
+ propertyType(QDesignerPropertySheet::PropertyNone),
+ kind(NormalProperty)
+{
+}
+
+QDesignerPropertySheetPrivate::QDesignerPropertySheetPrivate(QDesignerPropertySheet *sheetPublic, QObject *object, QObject *sheetParent) :
+ q(sheetPublic),
+ m_core(formEditorForObject(sheetParent)),
+ m_meta(m_core->introspection()->metaObject(object)),
+ m_objectType(QDesignerPropertySheet::objectTypeFromObject(object)),
+ m_canHaveLayoutAttributes(hasLayoutAttributes(m_core, object)),
+ m_object(object),
+ m_lastLayout(0),
+ m_lastLayoutPropertySheet(0),
+ m_LastLayoutByDesigner(false),
+ m_pixmapCache(0),
+ m_iconCache(0)
+{
+}
+
+qdesigner_internal::FormWindowBase *QDesignerPropertySheet::formWindowBase() const
+{
+ return d->m_fwb;
+}
+
+bool QDesignerPropertySheetPrivate::invalidIndex(const char *functionName, int index) const
+{
+ if (index < 0 || index >= count()) {
+ qWarning() << "** WARNING " << functionName << " invoked for " << m_object->objectName() << " was passed an invalid index " << index << '.';
+ return true;
+ }
+ return false;
+}
+
+QLayout* QDesignerPropertySheetPrivate::layout(QDesignerPropertySheetExtension **layoutPropertySheet) const
+{
+ // Return the layout and its property sheet
+ // only if it is managed by designer and not one created on a custom widget.
+ // (attempt to cache the value as this requires some hoops).
+ if (layoutPropertySheet)
+ *layoutPropertySheet = 0;
+
+ if (!m_object->isWidgetType() || !m_canHaveLayoutAttributes)
+ return 0;
+
+ QWidget *widget = qobject_cast<QWidget*>(m_object);
+ QLayout *widgetLayout = qdesigner_internal::LayoutInfo::internalLayout(widget);
+ if (!widgetLayout) {
+ m_lastLayout = 0;
+ m_lastLayoutPropertySheet = 0;
+ return 0;
+ }
+ // Smart logic to avoid retrieving the meta DB from the widget every time.
+ if (widgetLayout != m_lastLayout) {
+ m_lastLayout = widgetLayout;
+ m_LastLayoutByDesigner = false;
+ m_lastLayoutPropertySheet = 0;
+ // Is this a layout managed by designer or some layout on a custom widget?
+ if (qdesigner_internal::LayoutInfo::managedLayout(m_core ,widgetLayout)) {
+ m_LastLayoutByDesigner = true;
+ m_lastLayoutPropertySheet = qt_extension<QDesignerPropertySheetExtension*>(m_core->extensionManager(), m_lastLayout);
+ }
+ }
+ if (!m_LastLayoutByDesigner)
+ return 0;
+
+ if (layoutPropertySheet)
+ *layoutPropertySheet = m_lastLayoutPropertySheet;
+
+ return m_lastLayout;
+}
+
+QDesignerPropertySheetPrivate::Info &QDesignerPropertySheetPrivate::ensureInfo(int index)
+{
+ InfoHash::iterator it = m_info.find(index);
+ if (it == m_info.end())
+ it = m_info.insert(index, Info());
+ return it.value();
+}
+
+QDesignerPropertySheet::PropertyType QDesignerPropertySheetPrivate::propertyType(int index) const
+{
+ const InfoHash::const_iterator it = m_info.constFind(index);
+ if (it == m_info.constEnd())
+ return QDesignerPropertySheet::PropertyNone;
+ return it.value().propertyType;
+}
+
+QString QDesignerPropertySheetPrivate::transformLayoutPropertyName(int index) const
+{
+ typedef QMap<QDesignerPropertySheet::PropertyType, QString> TypeNameMap;
+ static TypeNameMap typeNameMap;
+ if (typeNameMap.empty()) {
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutObjectName, QLatin1String("objectName"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutLeftMargin, QLatin1String("leftMargin"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutTopMargin, QLatin1String("topMargin"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutRightMargin, QLatin1String("rightMargin"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutBottomMargin, QLatin1String("bottomMargin"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutSpacing, QLatin1String("spacing"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutHorizontalSpacing, QLatin1String("horizontalSpacing"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutVerticalSpacing, QLatin1String("verticalSpacing"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutSizeConstraint, QLatin1String("sizeConstraint"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutFieldGrowthPolicy, QLatin1String("fieldGrowthPolicy"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutRowWrapPolicy, QLatin1String("rowWrapPolicy"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutLabelAlignment, QLatin1String("labelAlignment"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutFormAlignment, QLatin1String("formAlignment"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutBoxStretch, QLatin1String("stretch"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutGridRowStretch, QLatin1String("rowStretch"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutGridColumnStretch, QLatin1String("columnStretch"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutGridRowMinimumHeight, QLatin1String("rowMinimumHeight"));
+ typeNameMap.insert(QDesignerPropertySheet::PropertyLayoutGridColumnMinimumWidth, QLatin1String("columnMinimumWidth"));
+ }
+ const TypeNameMap::const_iterator it = typeNameMap.constFind(propertyType(index));
+ if (it != typeNameMap.constEnd())
+ return it.value();
+ return QString();
+}
+
+// ----------- QDesignerPropertySheet
+
+QDesignerPropertySheet::ObjectType QDesignerPropertySheet::objectTypeFromObject(const QObject *o)
+{
+ if (qobject_cast<const QLayout *>(o))
+ return ObjectLayout;
+
+ if (!o->isWidgetType())
+ return ObjectNone;
+
+ if (qobject_cast<const QLayoutWidget *>(o))
+ return ObjectLayoutWidget;
+
+ if (qobject_cast<const QLabel*>(o))
+ return ObjectLabel;
+
+ if (o->inherits("Q3GroupBox"))
+ return ObjectQ3GroupBox;
+
+ return ObjectNone;
+}
+
+QDesignerPropertySheet::PropertyType QDesignerPropertySheet::propertyTypeFromName(const QString &name)
+{
+ typedef QHash<QString, PropertyType> PropertyTypeHash;
+ static PropertyTypeHash propertyTypeHash;
+ if (propertyTypeHash.empty()) {
+ propertyTypeHash.insert(QLatin1String(layoutObjectNameC), PropertyLayoutObjectName);
+ propertyTypeHash.insert(QLatin1String(layoutLeftMarginC), PropertyLayoutLeftMargin);
+ propertyTypeHash.insert(QLatin1String(layoutTopMarginC), PropertyLayoutTopMargin);
+ propertyTypeHash.insert(QLatin1String(layoutRightMarginC), PropertyLayoutRightMargin);
+ propertyTypeHash.insert(QLatin1String(layoutBottomMarginC), PropertyLayoutBottomMargin);
+ propertyTypeHash.insert(QLatin1String(layoutSpacingC), PropertyLayoutSpacing);
+ propertyTypeHash.insert(QLatin1String(layoutHorizontalSpacingC), PropertyLayoutHorizontalSpacing);
+ propertyTypeHash.insert(QLatin1String(layoutVerticalSpacingC), PropertyLayoutVerticalSpacing);
+ propertyTypeHash.insert(QLatin1String(layoutSizeConstraintC), PropertyLayoutSizeConstraint);
+ propertyTypeHash.insert(QLatin1String(layoutFieldGrowthPolicyC), PropertyLayoutFieldGrowthPolicy);
+ propertyTypeHash.insert(QLatin1String(layoutRowWrapPolicyC), PropertyLayoutRowWrapPolicy);
+ propertyTypeHash.insert(QLatin1String(layoutLabelAlignmentC), PropertyLayoutLabelAlignment);
+ propertyTypeHash.insert(QLatin1String(layoutFormAlignmentC), PropertyLayoutFormAlignment);
+ propertyTypeHash.insert(QLatin1String(layoutboxStretchPropertyC), PropertyLayoutBoxStretch);
+ propertyTypeHash.insert(QLatin1String(layoutGridRowStretchPropertyC), PropertyLayoutGridRowStretch);
+ propertyTypeHash.insert(QLatin1String(layoutGridColumnStretchPropertyC), PropertyLayoutGridColumnStretch);
+ propertyTypeHash.insert(QLatin1String(layoutGridRowMinimumHeightC), PropertyLayoutGridRowMinimumHeight);
+ propertyTypeHash.insert(QLatin1String(layoutGridColumnMinimumWidthC), PropertyLayoutGridColumnMinimumWidth);
+ propertyTypeHash.insert(QLatin1String("buddy"), PropertyBuddy);
+ propertyTypeHash.insert(QLatin1String("geometry"), PropertyGeometry);
+ propertyTypeHash.insert(QLatin1String("checkable"), PropertyCheckable);
+ propertyTypeHash.insert(QLatin1String("accessibleName"), PropertyAccessibility);
+ propertyTypeHash.insert(QLatin1String("accessibleDescription"), PropertyAccessibility);
+ propertyTypeHash.insert(QLatin1String("windowTitle"), PropertyWindowTitle);
+ propertyTypeHash.insert(QLatin1String("windowIcon"), PropertyWindowIcon);
+ propertyTypeHash.insert(QLatin1String("windowFilePath"), PropertyWindowFilePath);
+ propertyTypeHash.insert(QLatin1String("windowOpacity"), PropertyWindowOpacity);
+ propertyTypeHash.insert(QLatin1String("windowIconText"), PropertyWindowIconText);
+ propertyTypeHash.insert(QLatin1String("windowModality"), PropertyWindowModality);
+ propertyTypeHash.insert(QLatin1String("windowModified"), PropertyWindowModified);
+ propertyTypeHash.insert(QLatin1String("styleSheet"), PropertyStyleSheet);
+ propertyTypeHash.insert(QLatin1String("text"), PropertyText);
+ }
+ return propertyTypeHash.value(name, PropertyNone);
+}
+
+QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent) :
+ QObject(parent),
+ d(new QDesignerPropertySheetPrivate(this, object, parent))
+{
+ typedef QDesignerPropertySheetPrivate::Info Info;
+ const QDesignerMetaObjectInterface *baseMeta = d->m_meta;
+
+ while (baseMeta &&baseMeta->className().startsWith(QLatin1String("QDesigner"))) {
+ baseMeta = baseMeta->superClass();
+ }
+ Q_ASSERT(baseMeta != 0);
+
+ QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(d->m_object);
+ d->m_fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
+ if (d->m_fwb) {
+ d->m_pixmapCache = d->m_fwb->pixmapCache();
+ d->m_iconCache = d->m_fwb->iconCache();
+ d->m_fwb->addReloadablePropertySheet(this, object);
+ }
+
+ for (int index=0; index<count(); ++index) {
+ const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
+ const QString name = p->name();
+ if (p->type() == QVariant::KeySequence) {
+ createFakeProperty(name);
+ } else {
+ setVisible(index, false); // use the default for `real' properties
+ }
+
+ QString pgroup = baseMeta->className();
+
+ if (const QDesignerMetaObjectInterface *pmeta = propertyIntroducedBy(baseMeta, index)) {
+ pgroup = pmeta->className();
+ }
+
+ Info &info = d->ensureInfo(index);
+ info.group = pgroup;
+ info.propertyType = propertyTypeFromName(name);
+
+ if (p->type() == QVariant::Cursor || p->type() == QVariant::Icon || p->type() == QVariant::Pixmap) {
+ info.defaultValue = p->read(d->m_object);
+ if (p->type() == QVariant::Icon || p->type() == QVariant::Pixmap)
+ d->addResourceProperty(index, p->type());
+ } else if (p->type() == QVariant::String) {
+ d->addStringProperty(index);
+ } else if (p->type() == QVariant::KeySequence) {
+ d->addKeySequenceProperty(index);
+ }
+ }
+
+ if (object->isWidgetType()) {
+ createFakeProperty(QLatin1String("focusPolicy"));
+ createFakeProperty(QLatin1String("cursor"));
+ createFakeProperty(QLatin1String("toolTip"));
+ createFakeProperty(QLatin1String("whatsThis"));
+ createFakeProperty(QLatin1String("acceptDrops"));
+ createFakeProperty(QLatin1String("dragEnabled"));
+ // windowModality/Opacity is visible only for the main container, in which case the form windows enables it on loading
+ setVisible(createFakeProperty(QLatin1String("windowModality")), false);
+ setVisible(createFakeProperty(QLatin1String("windowOpacity"), double(1.0)), false);
+ if (qobject_cast<const QToolBar *>(d->m_object)) { // prevent toolbars from being dragged off
+ createFakeProperty(QLatin1String("floatable"), QVariant(true));
+ } else {
+ if (qobject_cast<const QMenuBar *>(d->m_object)) {
+ // Keep the menu bar editable in the form even if a native menu bar is used.
+ const bool nativeMenuBarDefault = !qApp->testAttribute(Qt::AA_DontUseNativeMenuBar);
+ createFakeProperty(QLatin1String("nativeMenuBar"), QVariant(nativeMenuBarDefault));
+ }
+ }
+ if (d->m_canHaveLayoutAttributes) {
+ static const QString layoutGroup = QLatin1String("Layout");
+ const char* fakeLayoutProperties[] = {
+ layoutObjectNameC, layoutLeftMarginC, layoutTopMarginC, layoutRightMarginC, layoutBottomMarginC, layoutSpacingC, layoutHorizontalSpacingC, layoutVerticalSpacingC,
+ layoutFieldGrowthPolicyC, layoutRowWrapPolicyC, layoutLabelAlignmentC, layoutFormAlignmentC,
+ layoutboxStretchPropertyC, layoutGridRowStretchPropertyC, layoutGridColumnStretchPropertyC,
+ layoutGridRowMinimumHeightC, layoutGridColumnMinimumWidthC
+#ifdef USE_LAYOUT_SIZE_CONSTRAINT
+ , layoutSizeConstraintC
+#endif
+ };
+ const int fakeLayoutPropertyCount = sizeof(fakeLayoutProperties)/sizeof(const char*);
+ const int size = count();
+ for (int i = 0; i < fakeLayoutPropertyCount; i++) {
+ createFakeProperty(QLatin1String(fakeLayoutProperties[i]), 0);
+ setAttribute(size + i, true);
+ setPropertyGroup(size + i, layoutGroup);
+ }
+ }
+
+ if (d->m_objectType == ObjectLabel)
+ createFakeProperty(QLatin1String("buddy"), QVariant(QByteArray()));
+ /* We need to create a fake property since the property does not work
+ * for non-toplevel windows or on other systems than Mac and only if
+ * it is above a certain Mac OS version. */
+ if (qobject_cast<const QMainWindow *>(d->m_object))
+ createFakeProperty(QLatin1String("unifiedTitleAndToolBarOnMac"), false);
+ }
+
+ if (qobject_cast<const QDialog*>(object)) {
+ createFakeProperty(QLatin1String("modal"));
+ }
+ if (qobject_cast<const QDockWidget*>(object)) {
+ createFakeProperty(QLatin1String("floating"));
+ }
+
+ typedef QList<QByteArray> ByteArrayList;
+ const ByteArrayList names = object->dynamicPropertyNames();
+ if (!names.empty()) {
+ const ByteArrayList::const_iterator cend = names.constEnd();
+ for (ByteArrayList::const_iterator it = names.constBegin(); it != cend; ++it) {
+ const char* cName = it->constData();
+ const QString name = QString::fromLatin1(cName);
+ const int idx = addDynamicProperty(name, object->property(cName));
+ if (idx != -1)
+ d->ensureInfo(idx).kind = QDesignerPropertySheetPrivate::DefaultDynamicProperty;
+ }
+ }
+}
+
+QDesignerPropertySheet::~QDesignerPropertySheet()
+{
+ if (d->m_fwb)
+ d->m_fwb->removeReloadablePropertySheet(this);
+ delete d;
+}
+
+QObject *QDesignerPropertySheet::object() const
+{
+ return d->m_object;
+}
+
+bool QDesignerPropertySheet::dynamicPropertiesAllowed() const
+{
+ return true;
+}
+
+bool QDesignerPropertySheet::canAddDynamicProperty(const QString &propName) const
+{
+ // used internally
+ if (propName == QLatin1String("database") ||
+ propName == QLatin1String("buttonGroupId"))
+ return false;
+ const int index = d->m_meta->indexOfProperty(propName);
+ if (index != -1)
+ return false; // property already exists and is not a dynamic one
+ if (d->m_addIndex.contains(propName)) {
+ const int idx = d->m_addIndex.value(propName);
+ if (isVisible(idx))
+ return false; // dynamic property already exists
+ else
+ return true;
+ }
+ if (!QDesignerPropertySheet::internalDynamicPropertiesEnabled() && propName.startsWith(QLatin1String("_q_")))
+ return false;
+ return true;
+}
+
+int QDesignerPropertySheet::addDynamicProperty(const QString &propName, const QVariant &value)
+{
+ typedef QDesignerPropertySheetPrivate::Info Info;
+ if (!value.isValid())
+ return -1; // property has invalid type
+ if (!canAddDynamicProperty(propName))
+ return -1;
+
+ QVariant v = value;
+ if (value.type() == QVariant::Icon)
+ v = QVariant::fromValue(qdesigner_internal::PropertySheetIconValue());
+ else if (value.type() == QVariant::Pixmap)
+ v = QVariant::fromValue(qdesigner_internal::PropertySheetPixmapValue());
+ else if (value.type() == QVariant::String)
+ v = QVariant::fromValue(qdesigner_internal::PropertySheetStringValue(value.toString()));
+ else if (value.type() == QVariant::KeySequence) {
+ const QKeySequence keySequence = qvariant_cast<QKeySequence>(value);
+ v = QVariant::fromValue(qdesigner_internal::PropertySheetKeySequenceValue(keySequence));
+ }
+
+ if (d->m_addIndex.contains(propName)) {
+ const int idx = d->m_addIndex.value(propName);
+ // have to be invisible, this was checked in canAddDynamicProperty() method
+ setVisible(idx, true);
+ d->m_addProperties.insert(idx, v);
+ setChanged(idx, false);
+ const int index = d->m_meta->indexOfProperty(propName);
+ Info &info = d->ensureInfo(index);
+ info.defaultValue = value;
+ info.kind = QDesignerPropertySheetPrivate::DynamicProperty;
+ if (value.type() == QVariant::Icon || value.type() == QVariant::Pixmap)
+ d->addResourceProperty(idx, value.type());
+ else if (value.type() == QVariant::String)
+ d->addStringProperty(idx);
+ else if (value.type() == QVariant::KeySequence)
+ d->addKeySequenceProperty(idx);
+ return idx;
+ }
+
+ const int index = count();
+ d->m_addIndex.insert(propName, index);
+ d->m_addProperties.insert(index, v);
+ Info &info = d->ensureInfo(index);
+ info.visible = true;
+ info.changed = false;
+ info.defaultValue = value;
+ info.kind = QDesignerPropertySheetPrivate::DynamicProperty;
+ setPropertyGroup(index, tr("Dynamic Properties"));
+ if (value.type() == QVariant::Icon || value.type() == QVariant::Pixmap)
+ d->addResourceProperty(index, value.type());
+ else if (value.type() == QVariant::String)
+ d->addStringProperty(index);
+ else if (value.type() == QVariant::KeySequence)
+ d->addKeySequenceProperty(index);
+ return index;
+}
+
+bool QDesignerPropertySheet::removeDynamicProperty(int index)
+{
+ if (!d->m_addIndex.contains(propertyName(index)))
+ return false;
+
+ setVisible(index, false);
+ return true;
+}
+
+bool QDesignerPropertySheet::isDynamic(int index) const
+{
+ if (!d->m_addProperties.contains(index))
+ return false;
+
+ switch (propertyType(index)) {
+ case PropertyBuddy:
+ if (d->m_objectType == ObjectLabel)
+ return false;
+ break;
+ case PropertyLayoutLeftMargin:
+ case PropertyLayoutTopMargin:
+ case PropertyLayoutRightMargin:
+ case PropertyLayoutBottomMargin:
+ case PropertyLayoutSpacing:
+ case PropertyLayoutHorizontalSpacing:
+ case PropertyLayoutVerticalSpacing:
+ case PropertyLayoutObjectName:
+ case PropertyLayoutSizeConstraint:
+ case PropertyLayoutFieldGrowthPolicy:
+ case PropertyLayoutRowWrapPolicy:
+ case PropertyLayoutLabelAlignment:
+ case PropertyLayoutFormAlignment:
+ case PropertyLayoutBoxStretch:
+ case PropertyLayoutGridRowStretch:
+ case PropertyLayoutGridColumnStretch:
+ case PropertyLayoutGridRowMinimumHeight:
+ case PropertyLayoutGridColumnMinimumWidth:
+ if (d->m_object->isWidgetType() && d->m_canHaveLayoutAttributes)
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+bool QDesignerPropertySheet::isDynamicProperty(int index) const
+{
+ // Do not complain here, as an invalid index might be encountered
+ // if someone implements a property sheet only, omitting the dynamic sheet.
+ if (index < 0 || index >= count())
+ return false;
+ return d->m_info.value(index).kind == QDesignerPropertySheetPrivate::DynamicProperty;
+}
+
+bool QDesignerPropertySheet::isDefaultDynamicProperty(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+ return d->m_info.value(index).kind == QDesignerPropertySheetPrivate::DefaultDynamicProperty;
+}
+
+bool QDesignerPropertySheet::isResourceProperty(int index) const
+{
+ return d->isResourceProperty(index);
+}
+
+QVariant QDesignerPropertySheet::defaultResourceProperty(int index) const
+{
+ return d->defaultResourceProperty(index);
+}
+
+qdesigner_internal::DesignerPixmapCache *QDesignerPropertySheet::pixmapCache() const
+{
+ return d->m_pixmapCache;
+}
+
+void QDesignerPropertySheet::setPixmapCache(qdesigner_internal::DesignerPixmapCache *cache)
+{
+ d->m_pixmapCache = cache;
+}
+
+qdesigner_internal::DesignerIconCache *QDesignerPropertySheet::iconCache() const
+{
+ return d->m_iconCache;
+}
+
+void QDesignerPropertySheet::setIconCache(qdesigner_internal::DesignerIconCache *cache)
+{
+ d->m_iconCache = cache;
+}
+
+int QDesignerPropertySheet::createFakeProperty(const QString &propertyName, const QVariant &value)
+{
+ typedef QDesignerPropertySheetPrivate::Info Info;
+ // fake properties
+ const int index = d->m_meta->indexOfProperty(propertyName);
+ if (index != -1) {
+ if (!(d->m_meta->property(index)->attributes() & QDesignerMetaPropertyInterface::DesignableAttribute))
+ return -1;
+ Info &info = d->ensureInfo(index);
+ info.visible = false;
+ info.kind = QDesignerPropertySheetPrivate::FakeProperty;
+ QVariant v = value.isValid() ? value : metaProperty(index);
+ if (v.type() == QVariant::String)
+ v = QVariant::fromValue(qdesigner_internal::PropertySheetStringValue());
+ if (v.type() == QVariant::KeySequence)
+ v = QVariant::fromValue(qdesigner_internal::PropertySheetKeySequenceValue());
+ d->m_fakeProperties.insert(index, v);
+ return index;
+ }
+ if (!value.isValid())
+ return -1;
+
+ const int newIndex = count();
+ d->m_addIndex.insert(propertyName, newIndex);
+ d->m_addProperties.insert(newIndex, value);
+ Info &info = d->ensureInfo(newIndex);
+ info.propertyType = propertyTypeFromName(propertyName);
+ info.kind = QDesignerPropertySheetPrivate::FakeProperty;
+ return newIndex;
+}
+
+bool QDesignerPropertySheet::isAdditionalProperty(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+ return d->m_addProperties.contains(index);
+}
+
+bool QDesignerPropertySheet::isFakeProperty(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+ // additional properties must be fake
+ return (d->m_fakeProperties.contains(index) || isAdditionalProperty(index));
+}
+
+int QDesignerPropertySheet::count() const
+{
+ return d->count();
+}
+
+int QDesignerPropertySheet::indexOf(const QString &name) const
+{
+ int index = d->m_meta->indexOfProperty(name);
+
+ if (index == -1)
+ index = d->m_addIndex.value(name, -1);
+
+ return index;
+}
+
+QDesignerPropertySheet::PropertyType QDesignerPropertySheet::propertyType(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return PropertyNone;
+ return d->propertyType(index);
+}
+
+QDesignerPropertySheet::ObjectType QDesignerPropertySheet::objectType() const
+{
+ return d->m_objectType;
+}
+
+QString QDesignerPropertySheet::propertyName(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return QString();
+ if (isAdditionalProperty(index))
+ return d->m_addIndex.key(index);
+
+ return d->m_meta->property(index)->name();
+}
+
+QString QDesignerPropertySheet::propertyGroup(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return QString();
+ const QString g = d->m_info.value(index).group;
+
+ if (!g.isEmpty())
+ return g;
+
+ if (propertyType(index) == PropertyAccessibility)
+ return QString::fromUtf8("Accessibility");
+
+ if (isAdditionalProperty(index))
+ return d->m_meta->className();
+
+ return g;
+}
+
+void QDesignerPropertySheet::setPropertyGroup(int index, const QString &group)
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return;
+ d->ensureInfo(index).group = group;
+}
+
+QVariant QDesignerPropertySheet::property(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return QVariant();
+ if (isAdditionalProperty(index)) {
+ if (isFakeLayoutProperty(index)) {
+ QDesignerPropertySheetExtension *layoutPropertySheet;
+ if (d->layout(&layoutPropertySheet) && layoutPropertySheet) {
+ const QString newPropName = d->transformLayoutPropertyName(index);
+ if (!newPropName.isEmpty()) {
+ const int newIndex = layoutPropertySheet->indexOf(newPropName);
+ if (newIndex != -1)
+ return layoutPropertySheet->property(newIndex);
+ return QVariant();
+ }
+ }
+ }
+ return d->m_addProperties.value(index);
+ }
+
+ if (isFakeProperty(index)) {
+ return d->m_fakeProperties.value(index);
+ }
+
+ if (d->isResourceProperty(index))
+ return d->resourceProperty(index);
+
+ if (d->isStringProperty(index)) {
+ QString strValue = metaProperty(index).toString();
+ qdesigner_internal::PropertySheetStringValue value = d->stringProperty(index);
+ if (strValue != value.value()) {
+ value.setValue(strValue);
+ d->setStringProperty(index, value); // cache it
+ }
+ return QVariant::fromValue(value);
+ }
+
+ if (d->isKeySequenceProperty(index)) {
+ QKeySequence keyValue = qvariant_cast<QKeySequence>(metaProperty(index));
+ qdesigner_internal::PropertySheetKeySequenceValue value = d->keySequenceProperty(index);
+ if (keyValue != value.value()) {
+ value.setValue(keyValue);
+ d->setKeySequenceProperty(index, value); // cache it
+ }
+ return QVariant::fromValue(value);
+ }
+
+ return metaProperty(index);
+}
+
+QVariant QDesignerPropertySheet::metaProperty(int index) const
+{
+ Q_ASSERT(!isFakeProperty(index));
+
+ const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
+ QVariant v = p->read(d->m_object);
+ switch (p->kind()) {
+ case QDesignerMetaPropertyInterface::FlagKind: {
+ qdesigner_internal::PropertySheetFlagValue psflags = qdesigner_internal::PropertySheetFlagValue(v.toInt(), designerMetaFlagsFor(p->enumerator()));
+ v.setValue(psflags);
+ }
+ break;
+ case QDesignerMetaPropertyInterface::EnumKind: {
+ qdesigner_internal::PropertySheetEnumValue pse = qdesigner_internal::PropertySheetEnumValue(v.toInt(), designerMetaEnumFor(p->enumerator()));
+ v.setValue(pse);
+ }
+ break;
+ case QDesignerMetaPropertyInterface::OtherKind:
+ break;
+ }
+ return v;
+}
+
+QVariant QDesignerPropertySheet::resolvePropertyValue(int index, const QVariant &value) const
+{
+ if (value.canConvert<qdesigner_internal::PropertySheetEnumValue>())
+ return qvariant_cast<qdesigner_internal::PropertySheetEnumValue>(value).value;
+
+ if (value.canConvert<qdesigner_internal::PropertySheetFlagValue>())
+ return qvariant_cast<qdesigner_internal::PropertySheetFlagValue>(value).value;
+
+ if (value.canConvert<qdesigner_internal::PropertySheetStringValue>())
+ return qvariant_cast<qdesigner_internal::PropertySheetStringValue>(value).value();
+
+ if (value.canConvert<qdesigner_internal::PropertySheetKeySequenceValue>())
+ return qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(value).value();
+
+ if (value.canConvert<qdesigner_internal::PropertySheetPixmapValue>()) {
+ const QString path = qvariant_cast<qdesigner_internal::PropertySheetPixmapValue>(value).path();
+ if (path.isEmpty())
+ return defaultResourceProperty(index);
+ if (d->m_pixmapCache) {
+ return d->m_pixmapCache->pixmap(qvariant_cast<qdesigner_internal::PropertySheetPixmapValue>(value));
+ }
+ }
+
+ if (value.canConvert<qdesigner_internal::PropertySheetIconValue>()) {
+ const unsigned mask = qvariant_cast<qdesigner_internal::PropertySheetIconValue>(value).mask();
+ if (mask == 0)
+ return defaultResourceProperty(index);
+ if (d->m_iconCache)
+ return d->m_iconCache->icon(qvariant_cast<qdesigner_internal::PropertySheetIconValue>(value));
+ }
+
+ return value;
+}
+
+void QDesignerPropertySheet::setFakeProperty(int index, const QVariant &value)
+{
+ Q_ASSERT(isFakeProperty(index));
+
+ QVariant &v = d->m_fakeProperties[index];
+
+ // set resource properties also (if we are going to have fake resource properties)
+ if (value.canConvert<qdesigner_internal::PropertySheetFlagValue>() || value.canConvert<qdesigner_internal::PropertySheetEnumValue>()) {
+ v = value;
+ } else if (v.canConvert<qdesigner_internal::PropertySheetFlagValue>()) {
+ qdesigner_internal::PropertySheetFlagValue f = qvariant_cast<qdesigner_internal::PropertySheetFlagValue>(v);
+ f.value = value.toInt();
+ v.setValue(f);
+ Q_ASSERT(value.type() == QVariant::Int);
+ } else if (v.canConvert<qdesigner_internal::PropertySheetEnumValue>()) {
+ qdesigner_internal::PropertySheetEnumValue e = qvariant_cast<qdesigner_internal::PropertySheetEnumValue>(v);
+ e.value = value.toInt();
+ v.setValue(e);
+ Q_ASSERT(value.type() == QVariant::Int);
+ } else {
+ v = value;
+ }
+}
+
+void QDesignerPropertySheet::clearFakeProperties()
+{
+ d->m_fakeProperties.clear();
+}
+
+// Buddy needs to be byte array, else uic won't work
+static QVariant toByteArray(const QVariant &value) {
+ if (value.type() == QVariant::ByteArray)
+ return value;
+ const QByteArray ba = value.toString().toUtf8();
+ return QVariant(ba);
+}
+
+void QDesignerPropertySheet::setProperty(int index, const QVariant &value)
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return;
+ if (isAdditionalProperty(index)) {
+ if (d->m_objectType == ObjectLabel && propertyType(index) == PropertyBuddy) {
+ QFormBuilderExtra::applyBuddy(value.toString(), QFormBuilderExtra::BuddyApplyVisibleOnly, qobject_cast<QLabel *>(d->m_object));
+ d->m_addProperties[index] = toByteArray(value);
+ return;
+ }
+
+ if (isFakeLayoutProperty(index)) {
+ QDesignerPropertySheetExtension *layoutPropertySheet;
+ if (d->layout(&layoutPropertySheet) && layoutPropertySheet) {
+ const QString newPropName = d->transformLayoutPropertyName(index);
+ if (!newPropName.isEmpty()) {
+ const int newIndex = layoutPropertySheet->indexOf(newPropName);
+ if (newIndex != -1)
+ layoutPropertySheet->setProperty(newIndex, value);
+ }
+ }
+ }
+
+ if (isDynamicProperty(index) || isDefaultDynamicProperty(index)) {
+ if (d->isResourceProperty(index))
+ d->setResourceProperty(index, value);
+ if (d->isStringProperty(index))
+ d->setStringProperty(index, qvariant_cast<qdesigner_internal::PropertySheetStringValue>(value));
+ if (d->isKeySequenceProperty(index))
+ d->setKeySequenceProperty(index, qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(value));
+ d->m_object->setProperty(propertyName(index).toUtf8(), resolvePropertyValue(index, value));
+ if (d->m_object->isWidgetType()) {
+ QWidget *w = qobject_cast<QWidget *>(d->m_object);
+ w->setStyleSheet(w->styleSheet());
+ }
+ }
+ d->m_addProperties[index] = value;
+ } else if (isFakeProperty(index)) {
+ setFakeProperty(index, value);
+ } else {
+ if (d->isResourceProperty(index))
+ d->setResourceProperty(index, value);
+ if (d->isStringProperty(index))
+ d->setStringProperty(index, qvariant_cast<qdesigner_internal::PropertySheetStringValue>(value));
+ if (d->isKeySequenceProperty(index))
+ d->setKeySequenceProperty(index, qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(value));
+ const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
+ p->write(d->m_object, resolvePropertyValue(index, value));
+ if (qobject_cast<QGroupBox *>(d->m_object) && propertyType(index) == PropertyCheckable) {
+ const int idx = indexOf(QLatin1String("focusPolicy"));
+ if (!isChanged(idx)) {
+ qdesigner_internal::PropertySheetEnumValue e = qvariant_cast<qdesigner_internal::PropertySheetEnumValue>(property(idx));
+ if (value.toBool()) {
+ const QDesignerMetaPropertyInterface *p = d->m_meta->property(idx);
+ p->write(d->m_object, Qt::NoFocus);
+ e.value = Qt::StrongFocus;
+ QVariant v;
+ v.setValue(e);
+ setFakeProperty(idx, v);
+ } else {
+ e.value = Qt::NoFocus;
+ QVariant v;
+ v.setValue(e);
+ setFakeProperty(idx, v);
+ }
+ }
+ }
+ }
+}
+
+bool QDesignerPropertySheet::hasReset(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+ if (isAdditionalProperty(index))
+ return d->m_info.value(index).reset;
+ return true;
+}
+
+bool QDesignerPropertySheet::reset(int index)
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+ if (d->isStringProperty(index)) {
+ qdesigner_internal::PropertySheetStringValue value;
+ // Main container: Reset to stored class name as not to change the file names generated by uic.
+ if (propertyName(index) == QLatin1String("objectName")) {
+ const QVariant classNameDefaultV = d->m_object->property("_q_classname");
+ if (classNameDefaultV.isValid())
+ value.setValue(classNameDefaultV.toString());
+ }
+ setProperty(index, QVariant::fromValue(value));
+ return true;
+ }
+ if (d->isKeySequenceProperty(index))
+ setProperty(index, QVariant::fromValue(qdesigner_internal::PropertySheetKeySequenceValue()));
+ if (d->isResourceProperty(index)) {
+ setProperty(index, d->emptyResourceProperty(index));
+ return true;
+ } else if (isDynamic(index)) {
+ const QString propName = propertyName(index);
+ const QVariant oldValue = d->m_addProperties.value(index);
+ const QVariant defaultValue = d->m_info.value(index).defaultValue;
+ QVariant newValue = defaultValue;
+ if (d->isStringProperty(index)) {
+ newValue = QVariant::fromValue(qdesigner_internal::PropertySheetStringValue(newValue.toString()));
+ } else if (d->isKeySequenceProperty(index)) {
+ const QKeySequence keySequence = qvariant_cast<QKeySequence>(newValue);
+ newValue = QVariant::fromValue(qdesigner_internal::PropertySheetKeySequenceValue(keySequence));
+ }
+ if (oldValue == newValue)
+ return true;
+ d->m_object->setProperty(propName.toUtf8(), defaultValue);
+ d->m_addProperties[index] = newValue;
+ return true;
+ } else if (!d->m_info.value(index).defaultValue.isNull()) {
+ setProperty(index, d->m_info.value(index).defaultValue);
+ return true;
+ }
+ if (isAdditionalProperty(index)) {
+ const PropertyType pType = propertyType(index);
+ if (d->m_objectType == ObjectLabel && pType == PropertyBuddy) {
+ setProperty(index, QVariant(QByteArray()));
+ return true;
+ }
+ if (isFakeLayoutProperty(index)) {
+ // special properties
+ switch (pType) {
+ case PropertyLayoutObjectName:
+ setProperty(index, QString());
+ return true;
+ case PropertyLayoutSizeConstraint:
+ setProperty(index, QVariant(QLayout::SetDefaultConstraint));
+ return true;
+ case PropertyLayoutBoxStretch:
+ case PropertyLayoutGridRowStretch:
+ case PropertyLayoutGridColumnStretch:
+ case PropertyLayoutGridRowMinimumHeight:
+ case PropertyLayoutGridColumnMinimumWidth:
+ case PropertyLayoutFieldGrowthPolicy:
+ case PropertyLayoutRowWrapPolicy:
+ case PropertyLayoutLabelAlignment:
+ case PropertyLayoutFormAlignment: {
+ QDesignerPropertySheetExtension *layoutPropertySheet;
+ if (d->layout(&layoutPropertySheet) && layoutPropertySheet)
+ return layoutPropertySheet->reset(layoutPropertySheet->indexOf(d->transformLayoutPropertyName(index)));
+ }
+ break;
+ default:
+ break;
+ }
+ // special margins
+ int value = -1;
+ switch (d->m_objectType) {
+ case ObjectQ3GroupBox: {
+ const QWidget *w = qobject_cast<const QWidget *>(d->m_object);
+ switch (pType) {
+ case PropertyLayoutLeftMargin:
+ value = w->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
+ break;
+ case PropertyLayoutTopMargin:
+ value = w->style()->pixelMetric(QStyle::PM_LayoutTopMargin);
+ break;
+ case PropertyLayoutRightMargin:
+ value = w->style()->pixelMetric(QStyle::PM_LayoutRightMargin);
+ break;
+ case PropertyLayoutBottomMargin:
+ value = w->style()->pixelMetric(QStyle::PM_LayoutBottomMargin);
+ break;
+ case PropertyLayoutSpacing:
+ case PropertyLayoutHorizontalSpacing:
+ case PropertyLayoutVerticalSpacing:
+ value = -1;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case ObjectLayoutWidget:
+ if (pType == PropertyLayoutLeftMargin ||
+ pType == PropertyLayoutTopMargin ||
+ pType == PropertyLayoutRightMargin ||
+ pType == PropertyLayoutBottomMargin)
+ value = 0;
+ break;
+ default:
+ break;
+ }
+ setProperty(index, value);
+ return true;
+ }
+ return false;
+ } else if (isFakeProperty(index)) {
+ const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
+ const bool result = p->reset(d->m_object);
+ d->m_fakeProperties[index] = p->read(d->m_object);
+ return result;
+ } else if (propertyType(index) == PropertyGeometry && d->m_object->isWidgetType()) {
+ if (QWidget *w = qobject_cast<QWidget*>(d->m_object)) {
+ QWidget *widget = w;
+ if (qdesigner_internal::Utils::isCentralWidget(d->m_fwb, widget) && d->m_fwb->parentWidget())
+ widget = d->m_fwb->parentWidget();
+
+ if (widget != w && widget->parentWidget()) {
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ widget->parentWidget()->adjustSize();
+ }
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ widget->adjustSize();
+ return true;
+ }
+ }
+ // ### TODO: reset for fake properties.
+
+ const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
+ return p->reset(d->m_object);
+}
+
+bool QDesignerPropertySheet::isChanged(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+ if (isAdditionalProperty(index)) {
+ if (isFakeLayoutProperty(index)) {
+ QDesignerPropertySheetExtension *layoutPropertySheet;
+ if (d->layout(&layoutPropertySheet) && layoutPropertySheet) {
+ const QString newPropName = d->transformLayoutPropertyName(index);
+ if (!newPropName.isEmpty()) {
+ const int newIndex = layoutPropertySheet->indexOf(newPropName);
+ if (newIndex != -1)
+ return layoutPropertySheet->isChanged(newIndex);
+ return false;
+ }
+ }
+ }
+ }
+ return d->m_info.value(index).changed;
+}
+
+void QDesignerPropertySheet::setChanged(int index, bool changed)
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return;
+ if (isAdditionalProperty(index)) {
+ if (isFakeLayoutProperty(index)) {
+ QDesignerPropertySheetExtension *layoutPropertySheet;
+ if (d->layout(&layoutPropertySheet) && layoutPropertySheet) {
+ const QString newPropName = d->transformLayoutPropertyName(index);
+ if (!newPropName.isEmpty()) {
+ const int newIndex = layoutPropertySheet->indexOf(newPropName);
+ if (newIndex != -1)
+ layoutPropertySheet->setChanged(newIndex, changed);
+ }
+ }
+ }
+ }
+ if (d->isReloadableProperty(index)) {
+ if (d->m_fwb) {
+ if (changed)
+ d->m_fwb->addReloadableProperty(this, index);
+ else
+ d->m_fwb->removeReloadableProperty(this, index);
+ }
+ }
+ d->ensureInfo(index).changed = changed;
+}
+
+bool QDesignerPropertySheet::isFakeLayoutProperty(int index) const
+{
+ if (!isAdditionalProperty(index))
+ return false;
+
+ switch (propertyType(index)) {
+ case PropertyLayoutObjectName:
+ case PropertyLayoutSizeConstraint:
+ return true;
+ case PropertyLayoutLeftMargin:
+ case PropertyLayoutTopMargin:
+ case PropertyLayoutRightMargin:
+ case PropertyLayoutBottomMargin:
+ case PropertyLayoutSpacing:
+ case PropertyLayoutHorizontalSpacing:
+ case PropertyLayoutVerticalSpacing:
+ case PropertyLayoutFieldGrowthPolicy:
+ case PropertyLayoutRowWrapPolicy:
+ case PropertyLayoutLabelAlignment:
+ case PropertyLayoutFormAlignment:
+ case PropertyLayoutBoxStretch:
+ case PropertyLayoutGridRowStretch:
+ case PropertyLayoutGridColumnStretch:
+ case PropertyLayoutGridRowMinimumHeight:
+ case PropertyLayoutGridColumnMinimumWidth:
+ return d->m_canHaveLayoutAttributes;
+ default:
+ break;
+ }
+ return false;
+}
+
+// Determine the "designable" state of a property. Properties, which have
+// a per-object boolean test function that returns false are shown in
+// disabled state ("checked" depending on "checkable", etc.)
+// Properties, which are generally not designable independent
+// of the object are not shown at all.
+enum DesignableState { PropertyIsDesignable,
+ // Object has a Designable test function that returns false.
+ PropertyOfObjectNotDesignable,
+ PropertyNotDesignable };
+
+static inline DesignableState designableState(const QDesignerMetaPropertyInterface *p, const QObject *object)
+{
+ if (p->attributes(object) & QDesignerMetaPropertyInterface::DesignableAttribute)
+ return PropertyIsDesignable;
+ return (p->attributes() & QDesignerMetaPropertyInterface::DesignableAttribute) ?
+ PropertyOfObjectNotDesignable : PropertyNotDesignable;
+}
+
+bool QDesignerPropertySheet::isVisible(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+
+ const PropertyType type = propertyType(index);
+ if (isAdditionalProperty(index)) {
+ if (isFakeLayoutProperty(index) && d->m_object->isWidgetType()) {
+ const QLayout *currentLayout = d->layout();
+ if (!currentLayout)
+ return false;
+ const int visibleMask = qdesigner_internal::LayoutProperties::visibleProperties(currentLayout);
+ switch (type) {
+ case PropertyLayoutSpacing:
+ return visibleMask & qdesigner_internal::LayoutProperties::SpacingProperty;
+ case PropertyLayoutHorizontalSpacing:
+ case PropertyLayoutVerticalSpacing:
+ return visibleMask & qdesigner_internal::LayoutProperties::HorizSpacingProperty;
+ case PropertyLayoutFieldGrowthPolicy:
+ return visibleMask & qdesigner_internal::LayoutProperties::FieldGrowthPolicyProperty;
+ case PropertyLayoutRowWrapPolicy:
+ return visibleMask & qdesigner_internal::LayoutProperties::RowWrapPolicyProperty;
+ case PropertyLayoutLabelAlignment:
+ return visibleMask & qdesigner_internal::LayoutProperties::LabelAlignmentProperty;
+ case PropertyLayoutFormAlignment:
+ return visibleMask & qdesigner_internal::LayoutProperties::FormAlignmentProperty;
+ case PropertyLayoutBoxStretch:
+ return visibleMask & qdesigner_internal::LayoutProperties::BoxStretchProperty;
+ case PropertyLayoutGridRowStretch:
+ return visibleMask & qdesigner_internal::LayoutProperties::GridRowStretchProperty;
+ case PropertyLayoutGridColumnStretch:
+ return visibleMask & qdesigner_internal::LayoutProperties::GridColumnStretchProperty;
+ case PropertyLayoutGridRowMinimumHeight:
+ return visibleMask & qdesigner_internal::LayoutProperties::GridRowMinimumHeightProperty;
+ case PropertyLayoutGridColumnMinimumWidth:
+ return visibleMask & qdesigner_internal::LayoutProperties::GridColumnMinimumWidthProperty;
+ default:
+ break;
+ }
+ return true;
+ }
+ return d->m_info.value(index).visible;
+ }
+
+ if (isFakeProperty(index)) {
+ switch (type) {
+ case PropertyWindowModality: // Hidden for child widgets
+ case PropertyWindowOpacity:
+ return d->m_info.value(index).visible;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ const bool visible = d->m_info.value(index).visible;
+ switch (type) {
+ case PropertyWindowTitle:
+ case PropertyWindowIcon:
+ case PropertyWindowFilePath:
+ case PropertyWindowOpacity:
+ case PropertyWindowIconText:
+ case PropertyWindowModified:
+ return visible;
+ default:
+ if (visible)
+ return true;
+ break;
+ }
+
+ const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
+ if (!(p->accessFlags() & QDesignerMetaPropertyInterface::WriteAccess))
+ return false;
+
+ // Enabled handling: Hide only statically not designable properties
+ return designableState(p, d->m_object) != PropertyNotDesignable;
+}
+
+void QDesignerPropertySheet::setVisible(int index, bool visible)
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return;
+ d->ensureInfo(index).visible = visible;
+}
+
+bool QDesignerPropertySheet::isEnabled(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+ if (isAdditionalProperty(index))
+ return true;
+
+ if (isFakeProperty(index))
+ return true;
+
+ // Grey out geometry of laid-out widgets (including splitter)
+ if (propertyType(index) == PropertyGeometry && d->m_object->isWidgetType()) {
+ bool isManaged;
+ const qdesigner_internal::LayoutInfo::Type lt = qdesigner_internal::LayoutInfo::laidoutWidgetType(d->m_core, qobject_cast<QWidget *>(d->m_object), &isManaged);
+ return !isManaged || lt == qdesigner_internal::LayoutInfo::NoLayout;
+ }
+
+ if (d->m_info.value(index).visible == true) // Sun CC 5.5 oddity, wants true
+ return true;
+
+ // Enable setting of properties for statically non-designable properties
+ // as this might be done via TaskMenu/Cursor::setProperty. Note that those
+ // properties are not visible.
+ const QDesignerMetaPropertyInterface *p = d->m_meta->property(index);
+ return (p->accessFlags() & QDesignerMetaPropertyInterface::WriteAccess) &&
+ designableState(p, d->m_object) != PropertyOfObjectNotDesignable;
+}
+
+bool QDesignerPropertySheet::isAttribute(int index) const
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return false;
+ if (isAdditionalProperty(index))
+ return d->m_info.value(index).attribute;
+
+ if (isFakeProperty(index))
+ return false;
+
+ return d->m_info.value(index).attribute;
+}
+
+void QDesignerPropertySheet::setAttribute(int index, bool attribute)
+{
+ if (d->invalidIndex(Q_FUNC_INFO, index))
+ return;
+ d->ensureInfo(index).attribute = attribute;
+}
+
+QDesignerFormEditorInterface *QDesignerPropertySheet::core() const
+{
+ return d->m_core;
+}
+
+bool QDesignerPropertySheet::internalDynamicPropertiesEnabled()
+{
+ return QDesignerPropertySheetPrivate::m_internalDynamicPropertiesEnabled;
+}
+
+void QDesignerPropertySheet::setInternalDynamicPropertiesEnabled(bool v)
+{
+ QDesignerPropertySheetPrivate::m_internalDynamicPropertiesEnabled = v;
+}
+
+// ---------- QDesignerAbstractPropertySheetFactory
+
+struct QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate {
+ PropertySheetFactoryPrivate();
+ const QString m_propertySheetId;
+ const QString m_dynamicPropertySheetId;
+
+ typedef QMap<QObject*, QObject*> ExtensionMap;
+ ExtensionMap m_extensions;
+ typedef QHash<QObject*, bool> ExtendedSet;
+ ExtendedSet m_extended;
+};
+
+QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate::PropertySheetFactoryPrivate() :
+ m_propertySheetId(Q_TYPEID(QDesignerPropertySheetExtension)),
+ m_dynamicPropertySheetId(Q_TYPEID(QDesignerDynamicPropertySheetExtension))
+{
+}
+
+// ---------- QDesignerAbstractPropertySheetFactory
+
+
+QDesignerAbstractPropertySheetFactory::QDesignerAbstractPropertySheetFactory(QExtensionManager *parent) :
+ QExtensionFactory(parent),
+ m_impl(new PropertySheetFactoryPrivate)
+{
+}
+
+QDesignerAbstractPropertySheetFactory::~QDesignerAbstractPropertySheetFactory()
+{
+ delete m_impl;
+}
+
+QObject *QDesignerAbstractPropertySheetFactory::extension(QObject *object, const QString &iid) const
+{
+ typedef PropertySheetFactoryPrivate::ExtensionMap ExtensionMap;
+ if (!object)
+ return 0;
+
+ if (iid != m_impl->m_propertySheetId && iid != m_impl->m_dynamicPropertySheetId)
+ return 0;
+
+ ExtensionMap::iterator it = m_impl->m_extensions.find(object);
+ if (it == m_impl->m_extensions.end()) {
+ if (QObject *ext = createPropertySheet(object, const_cast<QDesignerAbstractPropertySheetFactory*>(this))) {
+ connect(ext, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
+ it = m_impl->m_extensions.insert(object, ext);
+ }
+ }
+
+ if (!m_impl->m_extended.contains(object)) {
+ connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
+ m_impl->m_extended.insert(object, true);
+ }
+
+ if (it == m_impl->m_extensions.end())
+ return 0;
+
+ return it.value();
+}
+
+void QDesignerAbstractPropertySheetFactory::objectDestroyed(QObject *object)
+{
+ QMutableMapIterator<QObject*, QObject*> it(m_impl->m_extensions);
+ while (it.hasNext()) {
+ it.next();
+
+ QObject *o = it.key();
+ if (o == object || object == it.value()) {
+ it.remove();
+ }
+ }
+
+ m_impl->m_extended.remove(object);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_propertysheet_p.h b/src/designer/src/lib/shared/qdesigner_propertysheet_p.h
new file mode 100644
index 000000000..67d195b65
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_propertysheet_p.h
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_PROPERTYSHEET_H
+#define QDESIGNER_PROPERTYSHEET_H
+
+#include "shared_global_p.h"
+#include "dynamicpropertysheet.h"
+#include <QtDesigner/propertysheet.h>
+#include <QtDesigner/default_extensionfactory.h>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QVariant>
+#include <QtCore/QPair>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QLayout;
+class QDesignerFormEditorInterface;
+class QDesignerPropertySheetPrivate;
+
+namespace qdesigner_internal
+{
+ class DesignerPixmapCache;
+ class DesignerIconCache;
+ class FormWindowBase;
+}
+
+class QDESIGNER_SHARED_EXPORT QDesignerPropertySheet: public QObject, public QDesignerPropertySheetExtension, public QDesignerDynamicPropertySheetExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension QDesignerDynamicPropertySheetExtension)
+public:
+ explicit QDesignerPropertySheet(QObject *object, QObject *parent = 0);
+ virtual ~QDesignerPropertySheet();
+
+ virtual int indexOf(const QString &name) const;
+
+ virtual int count() const;
+ virtual QString propertyName(int index) const;
+
+ virtual QString propertyGroup(int index) const;
+ virtual void setPropertyGroup(int index, const QString &group);
+
+ virtual bool hasReset(int index) const;
+ virtual bool reset(int index);
+
+ virtual bool isAttribute(int index) const;
+ virtual void setAttribute(int index, bool b);
+
+ virtual bool isVisible(int index) const;
+ virtual void setVisible(int index, bool b);
+
+ virtual QVariant property(int index) const;
+ virtual void setProperty(int index, const QVariant &value);
+
+ virtual bool isChanged(int index) const;
+
+ virtual void setChanged(int index, bool changed);
+
+ virtual bool dynamicPropertiesAllowed() const;
+ virtual int addDynamicProperty(const QString &propertyName, const QVariant &value);
+ virtual bool removeDynamicProperty(int index);
+ virtual bool isDynamicProperty(int index) const;
+ virtual bool canAddDynamicProperty(const QString &propertyName) const;
+
+ bool isDefaultDynamicProperty(int index) const;
+
+ bool isResourceProperty(int index) const;
+ QVariant defaultResourceProperty(int index) const;
+
+ qdesigner_internal::DesignerPixmapCache *pixmapCache() const;
+ void setPixmapCache(qdesigner_internal::DesignerPixmapCache *cache);
+ qdesigner_internal::DesignerIconCache *iconCache() const;
+ void setIconCache(qdesigner_internal::DesignerIconCache *cache);
+ int createFakeProperty(const QString &propertyName, const QVariant &value = QVariant());
+
+ virtual bool isEnabled(int index) const;
+ QObject *object() const;
+
+ static bool internalDynamicPropertiesEnabled();
+ static void setInternalDynamicPropertiesEnabled(bool v);
+
+protected:
+ bool isAdditionalProperty(int index) const;
+ bool isFakeProperty(int index) const;
+ QVariant resolvePropertyValue(int index, const QVariant &value) const;
+ QVariant metaProperty(int index) const;
+ void setFakeProperty(int index, const QVariant &value);
+ void clearFakeProperties();
+
+ bool isFakeLayoutProperty(int index) const;
+ bool isDynamic(int index) const;
+ qdesigner_internal::FormWindowBase *formWindowBase() const;
+ QDesignerFormEditorInterface *core() const;
+
+public:
+ enum PropertyType { PropertyNone,
+ PropertyLayoutObjectName,
+ PropertyLayoutLeftMargin,
+ PropertyLayoutTopMargin,
+ PropertyLayoutRightMargin,
+ PropertyLayoutBottomMargin,
+ PropertyLayoutSpacing,
+ PropertyLayoutHorizontalSpacing,
+ PropertyLayoutVerticalSpacing,
+ PropertyLayoutSizeConstraint,
+ PropertyLayoutFieldGrowthPolicy,
+ PropertyLayoutRowWrapPolicy,
+ PropertyLayoutLabelAlignment,
+ PropertyLayoutFormAlignment,
+ PropertyLayoutBoxStretch,
+ PropertyLayoutGridRowStretch,
+ PropertyLayoutGridColumnStretch,
+ PropertyLayoutGridRowMinimumHeight,
+ PropertyLayoutGridColumnMinimumWidth,
+ PropertyBuddy,
+ PropertyAccessibility,
+ PropertyGeometry,
+ PropertyCheckable,
+ PropertyWindowTitle,
+ PropertyWindowIcon,
+ PropertyWindowFilePath,
+ PropertyWindowOpacity,
+ PropertyWindowIconText,
+ PropertyWindowModality,
+ PropertyWindowModified,
+ PropertyStyleSheet,
+ PropertyText
+ };
+
+ enum ObjectType { ObjectNone, ObjectLabel, ObjectLayout, ObjectLayoutWidget, ObjectQ3GroupBox };
+
+ static ObjectType objectTypeFromObject(const QObject *o);
+ static PropertyType propertyTypeFromName(const QString &name);
+
+protected:
+ PropertyType propertyType(int index) const;
+ ObjectType objectType() const;
+
+private:
+ QDesignerPropertySheetPrivate *d;
+};
+
+/* Abstract base class for factories that register a property sheet that implements
+ * both QDesignerPropertySheetExtension and QDesignerDynamicPropertySheetExtension
+ * by multiple inheritance. The factory maintains ownership of
+ * the extension and returns it for both id's. */
+
+class QDESIGNER_SHARED_EXPORT QDesignerAbstractPropertySheetFactory: public QExtensionFactory
+{
+ Q_OBJECT
+ Q_INTERFACES(QAbstractExtensionFactory)
+public:
+ explicit QDesignerAbstractPropertySheetFactory(QExtensionManager *parent = 0);
+ virtual ~QDesignerAbstractPropertySheetFactory();
+
+ QObject *extension(QObject *object, const QString &iid) const;
+
+private slots:
+ void objectDestroyed(QObject *object);
+
+private:
+ virtual QObject *createPropertySheet(QObject *qObject, QObject *parent) const = 0;
+
+ struct PropertySheetFactoryPrivate;
+ PropertySheetFactoryPrivate *m_impl;
+};
+
+/* Convenience factory template for property sheets that implement
+ * QDesignerPropertySheetExtension and QDesignerDynamicPropertySheetExtension
+ * by multiple inheritance. */
+
+template <class Object, class PropertySheet>
+class QDesignerPropertySheetFactory : public QDesignerAbstractPropertySheetFactory {
+public:
+ explicit QDesignerPropertySheetFactory(QExtensionManager *parent = 0);
+
+ static void registerExtension(QExtensionManager *mgr);
+
+private:
+ // Does a qobject_cast on the object.
+ virtual QObject *createPropertySheet(QObject *qObject, QObject *parent) const;
+};
+
+template <class Object, class PropertySheet>
+QDesignerPropertySheetFactory<Object, PropertySheet>::QDesignerPropertySheetFactory(QExtensionManager *parent) :
+ QDesignerAbstractPropertySheetFactory(parent)
+{
+}
+
+template <class Object, class PropertySheet>
+QObject *QDesignerPropertySheetFactory<Object, PropertySheet>::createPropertySheet(QObject *qObject, QObject *parent) const
+{
+ Object *object = qobject_cast<Object *>(qObject);
+ if (!object)
+ return 0;
+ return new PropertySheet(object, parent);
+}
+
+template <class Object, class PropertySheet>
+void QDesignerPropertySheetFactory<Object, PropertySheet>::registerExtension(QExtensionManager *mgr)
+{
+ QDesignerPropertySheetFactory *factory = new QDesignerPropertySheetFactory(mgr);
+ mgr->registerExtensions(factory, Q_TYPEID(QDesignerPropertySheetExtension));
+ mgr->registerExtensions(factory, Q_TYPEID(QDesignerDynamicPropertySheetExtension));
+}
+
+
+// Standard property sheet
+typedef QDesignerPropertySheetFactory<QObject, QDesignerPropertySheet> QDesignerDefaultPropertySheetFactory;
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_PROPERTYSHEET_H
diff --git a/src/designer/src/lib/shared/qdesigner_qsettings.cpp b/src/designer/src/lib/shared/qdesigner_qsettings.cpp
new file mode 100644
index 000000000..65c78362d
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_qsettings.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_qsettings_p.h"
+
+#include <QtCore/QSettings>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTextStream>
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+
+/*!
+ \class QDesignerSettingsSimple
+
+ \brief Implements QDesignerSettingsInterface by calls to QSettings
+ */
+
+QDesignerQSettings::QDesignerQSettings() :
+ m_settings(qApp->organizationName(), settingsApplicationName())
+{
+}
+
+QString QDesignerQSettings::settingsApplicationName()
+{
+ return qApp->applicationName();
+}
+
+void QDesignerQSettings::beginGroup(const QString &prefix)
+{
+ m_settings.beginGroup(prefix);
+}
+
+void QDesignerQSettings::endGroup()
+{
+ m_settings.endGroup();
+}
+
+bool QDesignerQSettings::contains(const QString &key) const
+{
+ return m_settings.contains(key);
+}
+
+void QDesignerQSettings::setValue(const QString &key, const QVariant &value)
+{
+ m_settings.setValue(key, value);
+}
+
+QVariant QDesignerQSettings::value(const QString &key, const QVariant &defaultValue) const
+{
+ return m_settings.value(key, defaultValue);
+}
+
+void QDesignerQSettings::remove(const QString &key)
+{
+ m_settings.remove(key);
+}
diff --git a/src/designer/src/lib/shared/qdesigner_qsettings_p.h b/src/designer/src/lib/shared/qdesigner_qsettings_p.h
new file mode 100644
index 000000000..e0586cc65
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_qsettings_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_QSETTINGS_H
+#define QDESIGNER_QSETTINGS_H
+
+#include "abstractsettings_p.h"
+#include "shared_global_p.h"
+
+#include <QtCore/QSettings>
+
+QT_BEGIN_NAMESPACE
+
+// Implements QDesignerSettingsInterface by calls to QSettings
+class QDESIGNER_SHARED_EXPORT QDesignerQSettings : public QDesignerSettingsInterface
+{
+public:
+ QDesignerQSettings();
+
+ virtual void beginGroup(const QString &prefix);
+ virtual void endGroup();
+
+ virtual bool contains(const QString &key) const;
+ virtual void setValue(const QString &key, const QVariant &value);
+ virtual QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
+ virtual void remove(const QString &key);
+
+ // The application name to be used for settings. Allows for including
+ // the Qt version to prevent settings of different Qt versions from
+ // interfering.
+ static QString settingsApplicationName();
+
+private:
+ QSettings m_settings;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_QSETTINGS_H
diff --git a/src/designer/src/lib/shared/qdesigner_stackedbox.cpp b/src/designer/src/lib/shared/qdesigner_stackedbox.cpp
new file mode 100644
index 000000000..0206e9709
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_stackedbox.cpp
@@ -0,0 +1,399 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_stackedbox_p.h"
+#include "qdesigner_command_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "orderdialog_p.h"
+#include "promotiontaskmenu_p.h"
+#include "widgetfactory_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QToolButton>
+#include <QtGui/QAction>
+#include <QtGui/qevent.h>
+#include <QtGui/QMenu>
+#include <QtGui/QStackedWidget>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static QToolButton *createToolButton(QWidget *parent, Qt::ArrowType at, const QString &name) {
+ QToolButton *rc = new QToolButton();
+ rc->setAttribute(Qt::WA_NoChildEventsForParent, true);
+ rc->setParent(parent);
+ rc->setObjectName(name);
+ rc->setArrowType(at);
+ rc->setAutoRaise(true);
+ rc->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ rc->setFixedSize(QSize(15, 15));
+ return rc;
+}
+
+// --------------- QStackedWidgetPreviewEventFilter
+QStackedWidgetPreviewEventFilter::QStackedWidgetPreviewEventFilter(QStackedWidget *parent) :
+ QObject(parent),
+ m_buttonToolTipEnabled(false), // Not on preview
+ m_stackedWidget(parent),
+ m_prev(createToolButton(m_stackedWidget, Qt::LeftArrow, QLatin1String("__qt__passive_prev"))),
+ m_next(createToolButton(m_stackedWidget, Qt::RightArrow, QLatin1String("__qt__passive_next")))
+{
+ connect(m_prev, SIGNAL(clicked()), this, SLOT(prevPage()));
+ connect(m_next, SIGNAL(clicked()), this, SLOT(nextPage()));
+
+ updateButtons();
+ m_stackedWidget->installEventFilter(this);
+ m_prev->installEventFilter(this);
+ m_next->installEventFilter(this);
+}
+
+void QStackedWidgetPreviewEventFilter::install(QStackedWidget *stackedWidget)
+{
+ new QStackedWidgetPreviewEventFilter(stackedWidget);
+}
+
+void QStackedWidgetPreviewEventFilter::updateButtons()
+{
+ m_prev->move(m_stackedWidget->width() - 31, 1);
+ m_prev->show();
+ m_prev->raise();
+
+ m_next->move(m_stackedWidget->width() - 16, 1);
+ m_next->show();
+ m_next->raise();
+}
+
+void QStackedWidgetPreviewEventFilter::prevPage()
+{
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(stackedWidget())) {
+ fw->clearSelection();
+ fw->selectWidget(stackedWidget(), true);
+ }
+ const int count = m_stackedWidget->count();
+ if (count > 1) {
+ int newIndex = m_stackedWidget->currentIndex() - 1;
+ if (newIndex < 0)
+ newIndex = count - 1;
+ gotoPage(newIndex);
+ }
+}
+
+void QStackedWidgetPreviewEventFilter::nextPage()
+{
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(stackedWidget())) {
+ fw->clearSelection();
+ fw->selectWidget(stackedWidget(), true);
+ }
+ const int count = m_stackedWidget->count();
+ if (count > 1)
+ gotoPage((m_stackedWidget->currentIndex() + 1) % count);
+}
+
+bool QStackedWidgetPreviewEventFilter::eventFilter(QObject *watched, QEvent *event)
+{
+ if (watched->isWidgetType()) {
+ if (watched == m_stackedWidget) {
+ switch (event->type()) {
+ case QEvent::LayoutRequest:
+ updateButtons();
+ break;
+ case QEvent::ChildAdded:
+ case QEvent::ChildRemoved:
+ case QEvent::Resize:
+ case QEvent::Show:
+ updateButtons();
+ break;
+ default:
+ break;
+ }
+ }
+ if (m_buttonToolTipEnabled && (watched == m_next || watched == m_prev)) {
+ switch (event->type()) {
+ case QEvent::ToolTip:
+ updateButtonToolTip(watched); // Tooltip includes page number, so, refresh on demand
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return QObject::eventFilter(watched, event);
+}
+
+void QStackedWidgetPreviewEventFilter::gotoPage(int page)
+{
+ m_stackedWidget->setCurrentIndex(page);
+ updateButtons();
+}
+
+static inline QString stackedClassName(QStackedWidget *w)
+{
+ if (const QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(w))
+ return qdesigner_internal::WidgetFactory::classNameOf(fw->core(), w);
+ return QLatin1String("Stacked widget");
+}
+
+void QStackedWidgetPreviewEventFilter::updateButtonToolTip(QObject *o)
+{
+ QString className = QLatin1String("Stacked widget");
+ if (const QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_stackedWidget))
+ className = qdesigner_internal::WidgetFactory::classNameOf(fw->core(), m_stackedWidget);
+ if (o == m_prev) {
+ const QString msg = tr("Go to previous page of %1 '%2' (%3/%4).").arg(stackedClassName(m_stackedWidget)).arg(m_stackedWidget->objectName()).arg(m_stackedWidget->currentIndex() + 1).arg(m_stackedWidget->count());
+ m_prev->setToolTip(msg);
+ } else {
+ if (o == m_next) {
+ const QString msg = tr("Go to next page of %1 '%2' (%3/%4).").arg(stackedClassName(m_stackedWidget)).arg(m_stackedWidget->objectName()).arg(m_stackedWidget->currentIndex() + 1).arg(m_stackedWidget->count());
+ m_next->setToolTip(msg);
+ }
+ }
+}
+
+// --------------- QStackedWidgetEventFilter
+QStackedWidgetEventFilter::QStackedWidgetEventFilter(QStackedWidget *parent) :
+ QStackedWidgetPreviewEventFilter(parent),
+ m_actionPreviousPage(new QAction(tr("Previous Page"), this)),
+ m_actionNextPage(new QAction(tr("Next Page"), this)),
+ m_actionDeletePage(new QAction(tr("Delete"), this)),
+ m_actionInsertPage(new QAction(tr("Before Current Page"), this)),
+ m_actionInsertPageAfter(new QAction(tr("After Current Page"), this)),
+ m_actionChangePageOrder(new QAction(tr("Change Page Order..."), this)),
+ m_pagePromotionTaskMenu(new qdesigner_internal::PromotionTaskMenu(0, qdesigner_internal::PromotionTaskMenu::ModeSingleWidget, this))
+{
+ setButtonToolTipEnabled(true);
+ connect(m_actionPreviousPage, SIGNAL(triggered()), this, SLOT(prevPage()));
+ connect(m_actionNextPage, SIGNAL(triggered()), this, SLOT(nextPage()));
+ connect(m_actionDeletePage, SIGNAL(triggered()), this, SLOT(removeCurrentPage()));
+ connect(m_actionInsertPage, SIGNAL(triggered()), this, SLOT(addPage()));
+ connect(m_actionInsertPageAfter, SIGNAL(triggered()), this, SLOT(addPageAfter()));
+ connect(m_actionChangePageOrder, SIGNAL(triggered()), this, SLOT(changeOrder()));
+}
+
+void QStackedWidgetEventFilter::install(QStackedWidget *stackedWidget)
+{
+ new QStackedWidgetEventFilter(stackedWidget);
+}
+
+QStackedWidgetEventFilter *QStackedWidgetEventFilter::eventFilterOf(const QStackedWidget *stackedWidget)
+{
+ // Look for 1st order children only..otherwise, we might get filters of nested widgets
+ const QObjectList children = stackedWidget->children();
+ const QObjectList::const_iterator cend = children.constEnd();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it) {
+ QObject *o = *it;
+ if (!o->isWidgetType())
+ if (QStackedWidgetEventFilter *ef = qobject_cast<QStackedWidgetEventFilter *>(o))
+ return ef;
+ }
+ return 0;
+}
+
+QMenu *QStackedWidgetEventFilter::addStackedWidgetContextMenuActions(const QStackedWidget *stackedWidget, QMenu *popup)
+{
+ QStackedWidgetEventFilter *filter = eventFilterOf(stackedWidget);
+ if (!filter)
+ return 0;
+ return filter->addContextMenuActions(popup);
+}
+
+void QStackedWidgetEventFilter::removeCurrentPage()
+{
+ if (stackedWidget()->currentIndex() == -1)
+ return;
+
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(stackedWidget())) {
+ qdesigner_internal::DeleteStackedWidgetPageCommand *cmd = new qdesigner_internal::DeleteStackedWidgetPageCommand(fw);
+ cmd->init(stackedWidget());
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QStackedWidgetEventFilter::changeOrder()
+{
+ QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(stackedWidget());
+
+ if (!fw)
+ return;
+
+ const QWidgetList oldPages = qdesigner_internal::OrderDialog::pagesOfContainer(fw->core(), stackedWidget());
+ const int pageCount = oldPages.size();
+ if (pageCount < 2)
+ return;
+
+ qdesigner_internal::OrderDialog dlg(fw);
+ dlg.setPageList(oldPages);
+ if (dlg.exec() == QDialog::Rejected)
+ return;
+
+ const QWidgetList newPages = dlg.pageList();
+ if (newPages == oldPages)
+ return;
+
+ fw->beginCommand(tr("Change Page Order"));
+ for(int i=0; i < pageCount; ++i) {
+ if (newPages.at(i) == stackedWidget()->widget(i))
+ continue;
+ qdesigner_internal::MoveStackedWidgetCommand *cmd = new qdesigner_internal::MoveStackedWidgetCommand(fw);
+ cmd->init(stackedWidget(), newPages.at(i), i);
+ fw->commandHistory()->push(cmd);
+ }
+ fw->endCommand();
+}
+
+void QStackedWidgetEventFilter::addPage()
+{
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(stackedWidget())) {
+ qdesigner_internal::AddStackedWidgetPageCommand *cmd = new qdesigner_internal::AddStackedWidgetPageCommand(fw);
+ cmd->init(stackedWidget(), qdesigner_internal::AddStackedWidgetPageCommand::InsertBefore);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QStackedWidgetEventFilter::addPageAfter()
+{
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(stackedWidget())) {
+ qdesigner_internal::AddStackedWidgetPageCommand *cmd = new qdesigner_internal::AddStackedWidgetPageCommand(fw);
+ cmd->init(stackedWidget(), qdesigner_internal::AddStackedWidgetPageCommand::InsertAfter);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QStackedWidgetEventFilter::gotoPage(int page) {
+ // Are we on a form or in a preview?
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(stackedWidget())) {
+ qdesigner_internal::SetPropertyCommand *cmd = new qdesigner_internal::SetPropertyCommand(fw);
+ cmd->init(stackedWidget(), QLatin1String("currentIndex"), page);
+ fw->commandHistory()->push(cmd);
+ fw->emitSelectionChanged(); // Magically prevent an endless loop triggered by auto-repeat.
+ updateButtons();
+ } else {
+ QStackedWidgetPreviewEventFilter::gotoPage(page);
+ }
+}
+
+QMenu *QStackedWidgetEventFilter::addContextMenuActions(QMenu *popup)
+{
+ QMenu *pageMenu = 0;
+ const int count = stackedWidget()->count();
+ const bool hasSeveralPages = count > 1;
+ m_actionDeletePage->setEnabled(count);
+ if (count) {
+ const QString pageSubMenuLabel = tr("Page %1 of %2").arg(stackedWidget()->currentIndex() + 1).arg(count);
+ pageMenu = popup->addMenu(pageSubMenuLabel);
+ pageMenu->addAction(m_actionDeletePage);
+ // Set up promotion menu for current widget.
+ if (QWidget *page = stackedWidget()->currentWidget ()) {
+ m_pagePromotionTaskMenu->setWidget(page);
+ m_pagePromotionTaskMenu->addActions(QDesignerFormWindowInterface::findFormWindow(stackedWidget()),
+ qdesigner_internal::PromotionTaskMenu::SuppressGlobalEdit,
+ pageMenu);
+ }
+ QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
+ insertPageMenu->addAction(m_actionInsertPageAfter);
+ insertPageMenu->addAction(m_actionInsertPage);
+ } else {
+ QAction *insertPageAction = popup->addAction(tr("Insert Page"));
+ connect(insertPageAction, SIGNAL(triggered()), this, SLOT(addPage()));
+ }
+ popup->addAction(m_actionNextPage);
+ m_actionNextPage->setEnabled(hasSeveralPages);
+ popup->addAction(m_actionPreviousPage);
+ m_actionPreviousPage->setEnabled(hasSeveralPages);
+ popup->addAction(m_actionChangePageOrder);
+ m_actionChangePageOrder->setEnabled(hasSeveralPages);
+ popup->addSeparator();
+ return pageMenu;
+}
+
+// -------- QStackedWidgetPropertySheet
+
+static const char *pagePropertyName = "currentPageName";
+
+QStackedWidgetPropertySheet::QStackedWidgetPropertySheet(QStackedWidget *object, QObject *parent) :
+ QDesignerPropertySheet(object, parent),
+ m_stackedWidget(object)
+{
+ createFakeProperty(QLatin1String(pagePropertyName), QString());
+}
+
+bool QStackedWidgetPropertySheet::isEnabled(int index) const
+{
+ if (propertyName(index) != QLatin1String(pagePropertyName))
+ return QDesignerPropertySheet::isEnabled(index);
+ return m_stackedWidget->currentWidget() != 0;
+}
+
+void QStackedWidgetPropertySheet::setProperty(int index, const QVariant &value)
+{
+ if (propertyName(index) == QLatin1String(pagePropertyName)) {
+ if (QWidget *w = m_stackedWidget->currentWidget())
+ w->setObjectName(value.toString());
+ } else {
+ QDesignerPropertySheet::setProperty(index, value);
+ }
+}
+
+QVariant QStackedWidgetPropertySheet::property(int index) const
+{
+ if (propertyName(index) == QLatin1String(pagePropertyName)) {
+ if (const QWidget *w = m_stackedWidget->currentWidget())
+ return w->objectName();
+ return QString();
+ }
+ return QDesignerPropertySheet::property(index);
+}
+
+bool QStackedWidgetPropertySheet::reset(int index)
+{
+ if (propertyName(index) == QLatin1String(pagePropertyName)) {
+ setProperty(index, QString());
+ return true;
+ }
+ return QDesignerPropertySheet::reset(index);
+}
+
+bool QStackedWidgetPropertySheet::checkProperty(const QString &propertyName)
+{
+ return propertyName != QLatin1String(pagePropertyName);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_stackedbox_p.h b/src/designer/src/lib/shared/qdesigner_stackedbox_p.h
new file mode 100644
index 000000000..d4b6db449
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_stackedbox_p.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_STACKEDBOX_H
+#define QDESIGNER_STACKEDBOX_H
+
+#include "shared_global_p.h"
+#include "qdesigner_propertysheet_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QStackedWidget;
+class QWidget;
+class QAction;
+class QMenu;
+class QToolButton;
+
+namespace qdesigner_internal {
+ class PromotionTaskMenu;
+}
+
+// Event filter to be installed on a QStackedWidget in preview mode.
+// Create two buttons to switch pages.
+
+class QDESIGNER_SHARED_EXPORT QStackedWidgetPreviewEventFilter : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QStackedWidgetPreviewEventFilter(QStackedWidget *parent);
+
+ // Install helper on QStackedWidget
+ static void install(QStackedWidget *stackedWidget);
+ bool eventFilter(QObject *watched, QEvent *event);
+
+ void setButtonToolTipEnabled(bool v) { m_buttonToolTipEnabled = v; }
+ bool buttonToolTipEnabled() const { return m_buttonToolTipEnabled; }
+
+public slots:
+ void updateButtons();
+ void prevPage();
+ void nextPage();
+
+protected:
+ QStackedWidget *stackedWidget() const { return m_stackedWidget; }
+ virtual void gotoPage(int page);
+
+private:
+ void updateButtonToolTip(QObject *o);
+
+ bool m_buttonToolTipEnabled;
+ QStackedWidget *m_stackedWidget;
+ QToolButton *m_prev;
+ QToolButton *m_next;
+};
+
+// Event filter to be installed on a QStackedWidget in editing mode.
+// In addition to the browse buttons, handles context menu and everything
+
+class QDESIGNER_SHARED_EXPORT QStackedWidgetEventFilter : public QStackedWidgetPreviewEventFilter
+{
+ Q_OBJECT
+public:
+ explicit QStackedWidgetEventFilter(QStackedWidget *parent);
+
+ // Install helper on QStackedWidget
+ static void install(QStackedWidget *stackedWidget);
+ static QStackedWidgetEventFilter *eventFilterOf(const QStackedWidget *stackedWidget);
+ // Convenience to add a menu on a tackedWidget
+ static QMenu *addStackedWidgetContextMenuActions(const QStackedWidget *stackedWidget, QMenu *popup);
+
+ // Add context menu and return page submenu or 0.
+ QMenu *addContextMenuActions(QMenu *popup);
+
+private slots:
+ void removeCurrentPage();
+ void addPage();
+ void addPageAfter();
+ void changeOrder();
+
+protected:
+ virtual void gotoPage(int page);
+
+private:
+ QAction *m_actionPreviousPage;
+ QAction *m_actionNextPage;
+ QAction *m_actionDeletePage;
+ QAction *m_actionInsertPage;
+ QAction *m_actionInsertPageAfter;
+ QAction *m_actionChangePageOrder;
+ qdesigner_internal::PromotionTaskMenu* m_pagePromotionTaskMenu;
+};
+
+// PropertySheet to handle the "currentPageName" property
+class QDESIGNER_SHARED_EXPORT QStackedWidgetPropertySheet : public QDesignerPropertySheet {
+public:
+ explicit QStackedWidgetPropertySheet(QStackedWidget *object, QObject *parent = 0);
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual QVariant property(int index) const;
+ virtual bool reset(int index);
+ virtual bool isEnabled(int index) const;
+
+ // Check whether the property is to be saved. Returns false for the page
+ // properties (as the property sheet has no concept of 'stored')
+ static bool checkProperty(const QString &propertyName);
+
+private:
+ QStackedWidget *m_stackedWidget;
+};
+
+typedef QDesignerPropertySheetFactory<QStackedWidget, QStackedWidgetPropertySheet> QStackedWidgetPropertySheetFactory;
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_STACKEDBOX_H
diff --git a/src/designer/src/lib/shared/qdesigner_tabwidget.cpp b/src/designer/src/lib/shared/qdesigner_tabwidget.cpp
new file mode 100644
index 000000000..6110deaba
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_tabwidget.cpp
@@ -0,0 +1,572 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_tabwidget_p.h"
+#include "qdesigner_command_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "promotiontaskmenu_p.h"
+#include "formwindowbase_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QApplication>
+#include <QtGui/QTabBar>
+#include <QtGui/QAction>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QLabel>
+#include <QtGui/QTabWidget>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+// Store tab widget as drag source
+class MyMimeData : public QMimeData
+{
+ Q_OBJECT
+public:
+ MyMimeData(const QTabWidget *tab) : m_tab(tab) {}
+ static bool fromMyTab(const QMimeData *mimeData, const QTabWidget *tab) {
+ if (!mimeData)
+ return false;
+ const MyMimeData *m = qobject_cast<const MyMimeData *>(mimeData);
+ return m && m->m_tab == tab;
+ }
+private:
+ const QTabWidget *m_tab;
+};
+
+} // namespace qdesigner_internal
+
+// ------------- QTabWidgetEventFilter
+
+QTabWidgetEventFilter::QTabWidgetEventFilter(QTabWidget *parent) :
+ QObject(parent),
+ m_tabWidget(parent),
+ m_dropIndicator(0),
+ m_dragPage(0),
+ m_mousePressed(false),
+ m_actionDeletePage(new QAction(tr("Delete"), this)),
+ m_actionInsertPage(new QAction(tr("Before Current Page"), this)),
+ m_actionInsertPageAfter(new QAction(tr("After Current Page"), this)),
+ m_pagePromotionTaskMenu(new qdesigner_internal::PromotionTaskMenu(0, qdesigner_internal::PromotionTaskMenu::ModeSingleWidget, this))
+{
+ tabBar()->setAcceptDrops(true);
+ tabBar()->installEventFilter(this);
+
+ connect(m_actionInsertPage, SIGNAL(triggered()), this, SLOT(addPage()));
+ connect(m_actionInsertPageAfter, SIGNAL(triggered()), this, SLOT(addPageAfter()));
+ connect(m_actionDeletePage, SIGNAL(triggered()), this, SLOT(removeCurrentPage()));
+}
+
+QTabWidgetEventFilter::~QTabWidgetEventFilter()
+{
+}
+
+void QTabWidgetEventFilter::install(QTabWidget *tabWidget)
+{
+ new QTabWidgetEventFilter(tabWidget);
+}
+
+QTabWidgetEventFilter *QTabWidgetEventFilter::eventFilterOf(const QTabWidget *tabWidget)
+{
+ // Look for 1st order children only..otherwise, we might get filters of nested tab widgets
+ const QObjectList children = tabWidget->children();
+ const QObjectList::const_iterator cend = children.constEnd();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it) {
+ QObject *o = *it;
+ if (!o->isWidgetType())
+ if (QTabWidgetEventFilter *ef = qobject_cast<QTabWidgetEventFilter*>(o))
+ return ef;
+ }
+ return 0;
+}
+
+QMenu *QTabWidgetEventFilter::addTabWidgetContextMenuActions(const QTabWidget *tabWidget, QMenu *popup)
+{
+ QTabWidgetEventFilter *filter = eventFilterOf(tabWidget);
+ if (!filter)
+ return 0;
+ return filter->addContextMenuActions(popup);
+}
+
+QTabBar *QTabWidgetEventFilter::tabBar() const
+{
+ // QTabWidget::tabBar() accessor is protected, grmbl...
+ if (!m_cachedTabBar) {
+ const QList<QTabBar *> tabBars = m_tabWidget->findChildren<QTabBar *>();
+ Q_ASSERT(tabBars.size() == 1);
+ m_cachedTabBar = tabBars.front();
+ }
+ return m_cachedTabBar;
+
+}
+
+static bool canMove(const QPoint &pressPoint, const QMouseEvent *e)
+{
+ const QPoint pt = pressPoint - e->pos();
+ return pt.manhattanLength() > QApplication::startDragDistance();
+}
+
+bool QTabWidgetEventFilter::eventFilter(QObject *o, QEvent *e)
+{
+ const QEvent::Type type = e->type();
+ // Do not try to locate tab bar and form window, etc. for uninteresting events and
+ // avoid asserts about missing tab bars when being destroyed
+ switch (type) {
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ case QEvent::DragLeave:
+ case QEvent::DragEnter:
+ case QEvent::DragMove:
+ case QEvent::Drop:
+ break;
+ default:
+ return false;
+ }
+
+ if (o != tabBar())
+ return false;
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return false;
+
+ switch (type) {
+ case QEvent::MouseButtonDblClick:
+ break;
+ case QEvent::MouseButtonPress: {
+ QMouseEvent *mev = static_cast<QMouseEvent*>(e);
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ fw->clearSelection();
+ fw->selectWidget(m_tabWidget, true);
+ }
+ if (mev->button() & Qt::LeftButton) {
+ m_mousePressed = true;
+ m_pressPoint = mev->pos();
+
+ QTabBar *tabbar = tabBar();
+ const int count = tabbar->count();
+ for (int i = 0; i < count; ++i) {
+ if (tabbar->tabRect(i).contains(m_pressPoint)) {
+ if (i != tabbar->currentIndex()) {
+ qdesigner_internal::SetPropertyCommand *cmd = new qdesigner_internal::SetPropertyCommand(fw);
+ cmd->init(m_tabWidget, QLatin1String("currentIndex"), i);
+ fw->commandHistory()->push(cmd);
+ }
+ break;
+ }
+ }
+ }
+ } break;
+
+ case QEvent::MouseButtonRelease:
+ m_mousePressed = false;
+ break;
+
+ case QEvent::MouseMove: {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);
+ if (m_mousePressed && canMove(m_pressPoint, mouseEvent)) {
+ const int index = m_tabWidget->currentIndex();
+ if (index == -1)
+ break;
+
+ m_mousePressed = false;
+ QDrag *drg = new QDrag(m_tabWidget);
+ drg->setMimeData(new qdesigner_internal::MyMimeData(m_tabWidget));
+
+ m_dragIndex = index;
+ m_dragPage = m_tabWidget->currentWidget();
+ m_dragLabel = m_tabWidget->tabText(index);
+ m_dragIcon = m_tabWidget->tabIcon(index);
+ if (m_dragIcon.isNull()) {
+ QLabel *label = new QLabel(m_dragLabel);
+ label->adjustSize();
+ drg->setPixmap(QPixmap::grabWidget(label));
+ label->deleteLater();
+ } else {
+ drg->setPixmap(m_dragIcon.pixmap(22, 22));
+ }
+
+ m_tabWidget->removeTab(m_dragIndex);
+
+ const Qt::DropActions dropAction = drg->start(Qt::MoveAction);
+
+ if (dropAction == Qt::IgnoreAction) {
+ // abort
+ m_tabWidget->insertTab(m_dragIndex, m_dragPage, m_dragIcon, m_dragLabel);
+ m_tabWidget->setCurrentIndex(m_dragIndex);
+ }
+
+ if (m_dropIndicator)
+ m_dropIndicator->hide();
+ }
+ } break;
+
+ case QEvent::DragLeave: {
+ if (m_dropIndicator)
+ m_dropIndicator->hide();
+ } break;
+
+ case QEvent::DragEnter:
+ case QEvent::DragMove: {
+ QDragMoveEvent *de = static_cast<QDragMoveEvent*>(e);
+ if (!qdesigner_internal::MyMimeData::fromMyTab(de->mimeData(), m_tabWidget))
+ return false;
+
+ if (de->proposedAction() == Qt::MoveAction)
+ de->acceptProposedAction();
+ else {
+ de->setDropAction(Qt::MoveAction);
+ de->accept();
+ }
+
+ QRect rect;
+ const int index = pageFromPosition(de->pos(), rect);
+
+ if (!m_dropIndicator) {
+ m_dropIndicator = new QWidget(m_tabWidget);
+ QPalette p = m_dropIndicator->palette();
+ p.setColor(m_tabWidget->backgroundRole(), Qt::red);
+ m_dropIndicator->setPalette(p);
+ }
+
+ QPoint pos;
+ if (index == m_tabWidget->count())
+ pos = tabBar()->mapToParent(QPoint(rect.x() + rect.width(), rect.y()));
+ else
+ pos = tabBar()->mapToParent(QPoint(rect.x(), rect.y()));
+
+ m_dropIndicator->setGeometry(pos.x(), pos.y() , 3, rect.height());
+ m_dropIndicator->show();
+ } break;
+
+ case QEvent::Drop: {
+ QDropEvent *de = static_cast<QDropEvent*>(e);
+ if (!qdesigner_internal::MyMimeData::fromMyTab(de->mimeData(), m_tabWidget))
+ return false;
+ de->acceptProposedAction();
+ de->accept();
+
+ QRect rect;
+ const int newIndex = pageFromPosition(de->pos(), rect);
+
+ qdesigner_internal::MoveTabPageCommand *cmd = new qdesigner_internal::MoveTabPageCommand(fw);
+ m_tabWidget->insertTab(m_dragIndex, m_dragPage, m_dragIcon, m_dragLabel);
+ cmd->init(m_tabWidget, m_dragPage, m_dragIcon, m_dragLabel, m_dragIndex, newIndex);
+ fw->commandHistory()->push(cmd);
+ } break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+void QTabWidgetEventFilter::removeCurrentPage()
+{
+ if (!m_tabWidget->currentWidget())
+ return;
+
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ qdesigner_internal::DeleteTabPageCommand *cmd = new qdesigner_internal::DeleteTabPageCommand(fw);
+ cmd->init(m_tabWidget);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QTabWidgetEventFilter::addPage()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ qdesigner_internal::AddTabPageCommand *cmd = new qdesigner_internal::AddTabPageCommand(fw);
+ cmd->init(m_tabWidget, qdesigner_internal::AddTabPageCommand::InsertBefore);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QTabWidgetEventFilter::addPageAfter()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ qdesigner_internal::AddTabPageCommand *cmd = new qdesigner_internal::AddTabPageCommand(fw);
+ cmd->init(m_tabWidget, qdesigner_internal::AddTabPageCommand::InsertAfter);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+QDesignerFormWindowInterface *QTabWidgetEventFilter::formWindow() const
+{
+ return QDesignerFormWindowInterface::findFormWindow(const_cast<QTabWidget*>(m_tabWidget));
+}
+
+// Get page from mouse position. Default to new page if in right half of last page?
+int QTabWidgetEventFilter::pageFromPosition(const QPoint &pos, QRect &rect) const
+{
+ int index = 0;
+ const QTabBar *tabbar = tabBar();
+ const int count = m_tabWidget->count();
+ for (; index < count; index++) {
+ const QRect rc = tabbar->tabRect(index);
+ if (rc.contains(pos)) {
+ rect = rc;
+ break;
+ }
+ }
+
+ if (index == count -1) {
+ QRect rect2 = rect;
+ rect2.setLeft(rect2.left() + rect2.width() / 2);
+ if (rect2.contains(pos))
+ index++;
+ }
+ return index;
+}
+
+QMenu *QTabWidgetEventFilter::addContextMenuActions(QMenu *popup)
+{
+ QMenu *pageMenu = 0;
+ const int count = m_tabWidget->count();
+ m_actionDeletePage->setEnabled(count);
+ if (count) {
+ const int currentIndex = m_tabWidget->currentIndex();
+ const QString pageSubMenuLabel = tr("Page %1 of %2").arg(currentIndex + 1).arg(count);
+ pageMenu = popup->addMenu(pageSubMenuLabel);
+ pageMenu->addAction(m_actionDeletePage);
+ // Set up promotion menu for current widget.
+ if (QWidget *page = m_tabWidget->currentWidget ()) {
+ m_pagePromotionTaskMenu->setWidget(page);
+ m_pagePromotionTaskMenu->addActions(QDesignerFormWindowInterface::findFormWindow(m_tabWidget),
+ qdesigner_internal::PromotionTaskMenu::SuppressGlobalEdit,
+ pageMenu);
+ }
+ QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
+ insertPageMenu->addAction(m_actionInsertPageAfter);
+ insertPageMenu->addAction(m_actionInsertPage);
+ } else {
+ QAction *insertPageAction = popup->addAction(tr("Insert Page"));
+ connect(insertPageAction, SIGNAL(triggered()), this, SLOT(addPage()));
+ }
+ popup->addSeparator();
+ return pageMenu;
+}
+
+// ----------- QTabWidgetPropertySheet
+
+static const char *currentTabTextKey = "currentTabText";
+static const char *currentTabNameKey = "currentTabName";
+static const char *currentTabIconKey = "currentTabIcon";
+static const char *currentTabToolTipKey = "currentTabToolTip";
+static const char *currentTabWhatsThisKey = "currentTabWhatsThis";
+static const char *tabMovableKey = "movable";
+
+QTabWidgetPropertySheet::QTabWidgetPropertySheet(QTabWidget *object, QObject *parent) :
+ QDesignerPropertySheet(object, parent),
+ m_tabWidget(object)
+{
+ createFakeProperty(QLatin1String(currentTabTextKey), QVariant::fromValue(qdesigner_internal::PropertySheetStringValue()));
+ createFakeProperty(QLatin1String(currentTabNameKey), QString());
+ createFakeProperty(QLatin1String(currentTabIconKey), QVariant::fromValue(qdesigner_internal::PropertySheetIconValue()));
+ if (formWindowBase())
+ formWindowBase()->addReloadableProperty(this, indexOf(QLatin1String(currentTabIconKey)));
+ createFakeProperty(QLatin1String(currentTabToolTipKey), QVariant::fromValue(qdesigner_internal::PropertySheetStringValue()));
+ createFakeProperty(QLatin1String(currentTabWhatsThisKey), QVariant::fromValue(qdesigner_internal::PropertySheetStringValue()));
+ // Prevent the tab widget's drag and drop handling from interfering with Designer's
+ createFakeProperty(QLatin1String(tabMovableKey), QVariant(false));
+}
+
+QTabWidgetPropertySheet::TabWidgetProperty QTabWidgetPropertySheet::tabWidgetPropertyFromName(const QString &name)
+{
+ typedef QHash<QString, TabWidgetProperty> TabWidgetPropertyHash;
+ static TabWidgetPropertyHash tabWidgetPropertyHash;
+ if (tabWidgetPropertyHash.empty()) {
+ tabWidgetPropertyHash.insert(QLatin1String(currentTabTextKey), PropertyCurrentTabText);
+ tabWidgetPropertyHash.insert(QLatin1String(currentTabNameKey), PropertyCurrentTabName);
+ tabWidgetPropertyHash.insert(QLatin1String(currentTabIconKey), PropertyCurrentTabIcon);
+ tabWidgetPropertyHash.insert(QLatin1String(currentTabToolTipKey), PropertyCurrentTabToolTip);
+ tabWidgetPropertyHash.insert(QLatin1String(currentTabWhatsThisKey), PropertyCurrentTabWhatsThis);
+ }
+ return tabWidgetPropertyHash.value(name, PropertyTabWidgetNone);
+}
+
+void QTabWidgetPropertySheet::setProperty(int index, const QVariant &value)
+{
+ const TabWidgetProperty tabWidgetProperty = tabWidgetPropertyFromName(propertyName(index));
+ if (tabWidgetProperty == PropertyTabWidgetNone) {
+ QDesignerPropertySheet::setProperty(index, value);
+ return;
+ }
+
+ // index-dependent
+ const int currentIndex = m_tabWidget->currentIndex();
+ QWidget *currentWidget = m_tabWidget->currentWidget();
+ if (!currentWidget)
+ return;
+
+ switch (tabWidgetProperty) {
+ case PropertyCurrentTabText:
+ m_tabWidget->setTabText(currentIndex, qvariant_cast<QString>(resolvePropertyValue(index, value)));
+ m_pageToData[currentWidget].text = qvariant_cast<qdesigner_internal::PropertySheetStringValue>(value);
+ break;
+ case PropertyCurrentTabName:
+ currentWidget->setObjectName(value.toString());
+ break;
+ case PropertyCurrentTabIcon:
+ m_tabWidget->setTabIcon(currentIndex, qvariant_cast<QIcon>(resolvePropertyValue(index, value)));
+ m_pageToData[currentWidget].icon = qvariant_cast<qdesigner_internal::PropertySheetIconValue>(value);
+ break;
+ case PropertyCurrentTabToolTip:
+ m_tabWidget->setTabToolTip(currentIndex, qvariant_cast<QString>(resolvePropertyValue(index, value)));
+ m_pageToData[currentWidget].tooltip = qvariant_cast<qdesigner_internal::PropertySheetStringValue>(value);
+ break;
+ case PropertyCurrentTabWhatsThis:
+ m_tabWidget->setTabWhatsThis(currentIndex, qvariant_cast<QString>(resolvePropertyValue(index, value)));
+ m_pageToData[currentWidget].whatsthis = qvariant_cast<qdesigner_internal::PropertySheetStringValue>(value);
+ break;
+ case PropertyTabWidgetNone:
+ break;
+ }
+}
+
+bool QTabWidgetPropertySheet::isEnabled(int index) const
+{
+ if (tabWidgetPropertyFromName(propertyName(index)) == PropertyTabWidgetNone)
+ return QDesignerPropertySheet::isEnabled(index);
+ return m_tabWidget->currentIndex() != -1;
+}
+
+QVariant QTabWidgetPropertySheet::property(int index) const
+{
+ const TabWidgetProperty tabWidgetProperty = tabWidgetPropertyFromName(propertyName(index));
+ if (tabWidgetProperty == PropertyTabWidgetNone)
+ return QDesignerPropertySheet::property(index);
+
+ // index-dependent
+ QWidget *currentWidget = m_tabWidget->currentWidget();
+ if (!currentWidget) {
+ if (tabWidgetProperty == PropertyCurrentTabIcon)
+ return QVariant::fromValue(qdesigner_internal::PropertySheetIconValue());
+ if (tabWidgetProperty == PropertyCurrentTabText)
+ return QVariant::fromValue(qdesigner_internal::PropertySheetStringValue());
+ if (tabWidgetProperty == PropertyCurrentTabToolTip)
+ return QVariant::fromValue(qdesigner_internal::PropertySheetStringValue());
+ if (tabWidgetProperty == PropertyCurrentTabWhatsThis)
+ return QVariant::fromValue(qdesigner_internal::PropertySheetStringValue());
+ return QVariant(QString());
+ }
+
+ // index-dependent
+ switch (tabWidgetProperty) {
+ case PropertyCurrentTabText:
+ return QVariant::fromValue(m_pageToData.value(currentWidget).text);
+ case PropertyCurrentTabName:
+ return currentWidget->objectName();
+ case PropertyCurrentTabIcon:
+ return QVariant::fromValue(m_pageToData.value(currentWidget).icon);
+ case PropertyCurrentTabToolTip:
+ return QVariant::fromValue(m_pageToData.value(currentWidget).tooltip);
+ case PropertyCurrentTabWhatsThis:
+ return QVariant::fromValue(m_pageToData.value(currentWidget).whatsthis);
+ case PropertyTabWidgetNone:
+ break;
+ }
+ return QVariant();
+}
+
+bool QTabWidgetPropertySheet::reset(int index)
+{
+ const TabWidgetProperty tabWidgetProperty = tabWidgetPropertyFromName(propertyName(index));
+ if (tabWidgetProperty == PropertyTabWidgetNone)
+ return QDesignerPropertySheet::reset(index);
+
+ // index-dependent
+ QWidget *currentWidget = m_tabWidget->currentWidget();
+ if (!currentWidget)
+ return false;
+
+ // index-dependent
+ switch (tabWidgetProperty) {
+ case PropertyCurrentTabName:
+ setProperty(index, QString());
+ break;
+ case PropertyCurrentTabToolTip:
+ m_pageToData[currentWidget].tooltip = qdesigner_internal::PropertySheetStringValue();
+ setProperty(index, QString());
+ break;
+ case PropertyCurrentTabWhatsThis:
+ m_pageToData[currentWidget].whatsthis = qdesigner_internal::PropertySheetStringValue();
+ setProperty(index, QString());
+ break;
+ case PropertyCurrentTabText:
+ m_pageToData[currentWidget].text = qdesigner_internal::PropertySheetStringValue();
+ setProperty(index, QString());
+ break;
+ case PropertyCurrentTabIcon:
+ m_pageToData[currentWidget].icon = qdesigner_internal::PropertySheetIconValue();
+ setProperty(index, QIcon());
+ break;
+ case PropertyTabWidgetNone:
+ break;
+ }
+ return true;
+}
+
+bool QTabWidgetPropertySheet::checkProperty(const QString &propertyName)
+{
+ switch (tabWidgetPropertyFromName(propertyName)) {
+ case PropertyCurrentTabText:
+ case PropertyCurrentTabName:
+ case PropertyCurrentTabToolTip:
+ case PropertyCurrentTabWhatsThis:
+ case PropertyCurrentTabIcon:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#include "qdesigner_tabwidget.moc" // required for MyMimeData
diff --git a/src/designer/src/lib/shared/qdesigner_tabwidget_p.h b/src/designer/src/lib/shared/qdesigner_tabwidget_p.h
new file mode 100644
index 000000000..23140a600
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_tabwidget_p.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_TABWIDGET_H
+#define QDESIGNER_TABWIDGET_H
+
+#include "shared_global_p.h"
+#include "qdesigner_propertysheet_p.h"
+#include "qdesigner_utils_p.h"
+
+#include <QtCore/QPointer>
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QTabWidget;
+class QTabBar;
+class QMenu;
+class QAction;
+
+namespace qdesigner_internal {
+ class PromotionTaskMenu;
+}
+
+class QDESIGNER_SHARED_EXPORT QTabWidgetEventFilter : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QTabWidgetEventFilter(QTabWidget *parent);
+ ~QTabWidgetEventFilter();
+
+ // Install helper on QTabWidget
+ static void install(QTabWidget *tabWidget);
+ static QTabWidgetEventFilter *eventFilterOf(const QTabWidget *tabWidget);
+ // Convenience to add a menu on a tackedWidget
+ static QMenu *addTabWidgetContextMenuActions(const QTabWidget *tabWidget, QMenu *popup);
+
+ // Add context menu and return page submenu or 0.
+ QMenu *addContextMenuActions(QMenu *popup);
+
+ virtual bool eventFilter(QObject *o, QEvent *e);
+
+ QDesignerFormWindowInterface *formWindow() const;
+
+private slots:
+ void removeCurrentPage();
+ void addPage();
+ void addPageAfter();
+
+private:
+ int pageFromPosition(const QPoint &pos, QRect &rect) const;
+ QTabBar *tabBar() const;
+
+ QTabWidget *m_tabWidget;
+ mutable QPointer<QTabBar> m_cachedTabBar;
+ QPoint m_pressPoint;
+ QWidget *m_dropIndicator;
+ int m_dragIndex;
+ QWidget *m_dragPage;
+ QString m_dragLabel;
+ QIcon m_dragIcon;
+ bool m_mousePressed;
+ QAction *m_actionDeletePage;
+ QAction *m_actionInsertPage;
+ QAction *m_actionInsertPageAfter;
+ qdesigner_internal::PromotionTaskMenu* m_pagePromotionTaskMenu;
+};
+
+// PropertySheet to handle the page properties
+class QDESIGNER_SHARED_EXPORT QTabWidgetPropertySheet : public QDesignerPropertySheet {
+public:
+ explicit QTabWidgetPropertySheet(QTabWidget *object, QObject *parent = 0);
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual QVariant property(int index) const;
+ virtual bool reset(int index);
+ virtual bool isEnabled(int index) const;
+
+ // Check whether the property is to be saved. Returns false for the page
+ // properties (as the property sheet has no concept of 'stored')
+ static bool checkProperty(const QString &propertyName);
+
+private:
+ enum TabWidgetProperty { PropertyCurrentTabText, PropertyCurrentTabName, PropertyCurrentTabIcon,
+ PropertyCurrentTabToolTip, PropertyCurrentTabWhatsThis, PropertyTabWidgetNone };
+
+ static TabWidgetProperty tabWidgetPropertyFromName(const QString &name);
+ QTabWidget *m_tabWidget;
+ struct PageData
+ {
+ qdesigner_internal::PropertySheetStringValue text;
+ qdesigner_internal::PropertySheetStringValue tooltip;
+ qdesigner_internal::PropertySheetStringValue whatsthis;
+ qdesigner_internal::PropertySheetIconValue icon;
+ };
+ QMap<QWidget *, PageData> m_pageToData;
+};
+
+typedef QDesignerPropertySheetFactory<QTabWidget, QTabWidgetPropertySheet> QTabWidgetPropertySheetFactory;
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_TABWIDGET_H
diff --git a/src/designer/src/lib/shared/qdesigner_taskmenu.cpp b/src/designer/src/lib/shared/qdesigner_taskmenu.cpp
new file mode 100644
index 000000000..5a9ace4b9
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_taskmenu.cpp
@@ -0,0 +1,912 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_taskmenu_p.h"
+#include "qdesigner_command_p.h"
+#include "qdesigner_command2_p.h"
+#include "richtexteditor_p.h"
+#include "plaintexteditor_p.h"
+#include "stylesheeteditor_p.h"
+#include "qlayout_widget_p.h"
+#include "layout_p.h"
+#include "spacer_widget_p.h"
+#include "textpropertyeditor_p.h"
+#include "promotiontaskmenu_p.h"
+#include "metadatabase_p.h"
+#include "scriptdialog_p.h"
+#include "scriptcommand_p.h"
+#include "signalslotdialog_p.h"
+#include "qdesigner_membersheet_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "qdesigner_utils_p.h"
+#include "qdesigner_objectinspector_p.h"
+#include "morphmenu_p.h"
+#include "qdesigner_integration_p.h"
+#include "formlayoutmenu_p.h"
+#include "ui_selectsignaldialog.h"
+#include "widgetfactory_p.h"
+#include "abstractintrospection_p.h"
+#include "widgetdatabase_p.h"
+
+#include <shared_enums_p.h>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QWidget>
+#include <QtGui/QMenuBar>
+#include <QtGui/QMainWindow>
+#include <QtGui/QStatusBar>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QUndoStack>
+#include <QtCore/QDebug>
+#include <QtCore/QSignalMapper>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+static QMenuBar *findMenuBar(const QWidget *widget)
+{
+ const QList<QObject*> children = widget->children();
+ foreach (QObject *obj, widget->children()) {
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(obj)) {
+ return mb;
+ }
+ }
+
+ return 0;
+}
+
+static QStatusBar *findStatusBar(const QWidget *widget)
+{
+ const QList<QObject*> children = widget->children();
+ foreach (QObject *obj, widget->children()) {
+ if (QStatusBar *sb = qobject_cast<QStatusBar*>(obj)) {
+ return sb;
+ }
+ }
+
+ return 0;
+}
+
+static inline QAction *createSeparatorHelper(QObject *parent) {
+ QAction *rc = new QAction(parent);
+ rc->setSeparator(true);
+ return rc;
+}
+
+static inline qdesigner_internal::QDesignerIntegration *integration(const QDesignerFormEditorInterface *core) {
+ return qobject_cast<qdesigner_internal::QDesignerIntegration *>(core->integration());
+}
+
+static QString objName(const QDesignerFormEditorInterface *core, QObject *object) {
+ QDesignerPropertySheetExtension *sheet
+ = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), object);
+ Q_ASSERT(sheet != 0);
+
+ const QString objectNameProperty = QLatin1String("objectName");
+ const int index = sheet->indexOf(objectNameProperty);
+ const qdesigner_internal::PropertySheetStringValue objectNameValue
+ = qvariant_cast<qdesigner_internal::PropertySheetStringValue>(sheet->property(index));
+ return objectNameValue.value();
+}
+
+enum { ApplyMinimumWidth = 0x1, ApplyMinimumHeight = 0x2, ApplyMaximumWidth = 0x4, ApplyMaximumHeight = 0x8 };
+
+namespace {
+// --------------- ObjectNameDialog
+class ObjectNameDialog : public QDialog
+{
+ public:
+ ObjectNameDialog(QWidget *parent, const QString &oldName);
+ QString newObjectName() const;
+
+ private:
+ qdesigner_internal::TextPropertyEditor *m_editor;
+};
+
+ObjectNameDialog::ObjectNameDialog(QWidget *parent, const QString &oldName)
+ : QDialog(parent),
+ m_editor( new qdesigner_internal::TextPropertyEditor(this, qdesigner_internal::TextPropertyEditor::EmbeddingNone,
+ qdesigner_internal::ValidationObjectName))
+{
+ setWindowTitle(QCoreApplication::translate("ObjectNameDialog", "Change Object Name"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ QVBoxLayout *vboxLayout = new QVBoxLayout(this);
+ vboxLayout->addWidget(new QLabel(QCoreApplication::translate("ObjectNameDialog", "Object Name")));
+
+ m_editor->setText(oldName);
+ m_editor->selectAll();
+ m_editor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ vboxLayout->addWidget(m_editor);
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
+ Qt::Horizontal, this);
+ QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setDefault(true);
+ vboxLayout->addWidget(buttonBox);
+
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+}
+
+QString ObjectNameDialog::newObjectName() const
+{
+ return m_editor->text();
+}
+} // namespace
+
+namespace qdesigner_internal {
+
+// Sub menu displaying the alignment options of a widget in a managed
+// grid/box layout cell.
+class LayoutAlignmentMenu {
+public:
+ explicit LayoutAlignmentMenu(QObject *parent);
+
+ QAction *subMenuAction() const { return m_subMenuAction; }
+
+ void connect(QObject *receiver, const char *aSlot);
+
+ // Set up enabled state and checked actions according to widget (managed box/grid)
+ bool setAlignment(const QDesignerFormEditorInterface *core, QWidget *w);
+
+ // Return the currently checked alignment
+ Qt::Alignment alignment() const;
+
+private:
+ enum Actions { HorizNone, Left, HorizCenter, Right, VerticalNone, Top, VerticalCenter, Bottom };
+ static QAction *createAction(const QString &text, int data, QMenu *menu, QActionGroup *ag);
+
+ QAction *m_subMenuAction;
+ QActionGroup *m_horizGroup;
+ QActionGroup *m_verticalGroup;
+ QAction *m_actions[Bottom + 1];
+};
+
+QAction *LayoutAlignmentMenu::createAction(const QString &text, int data, QMenu *menu, QActionGroup *ag)
+{
+ QAction * a = new QAction(text, 0);
+ a->setCheckable(true);
+ a->setData(QVariant(data));
+ menu->addAction(a);
+ ag->addAction(a);
+ return a;
+}
+
+LayoutAlignmentMenu::LayoutAlignmentMenu(QObject *parent) :
+ m_subMenuAction(new QAction(QDesignerTaskMenu::tr("Layout Alignment"), parent)),
+ m_horizGroup(new QActionGroup(parent)),
+ m_verticalGroup(new QActionGroup(parent))
+{
+ m_horizGroup->setExclusive(true);
+ m_verticalGroup->setExclusive(true);
+
+ QMenu *menu = new QMenu;
+ m_subMenuAction->setMenu(menu);
+
+ m_actions[HorizNone] = createAction(QDesignerTaskMenu::tr("No Horizontal Alignment"), 0, menu, m_horizGroup);
+ m_actions[Left] = createAction(QDesignerTaskMenu::tr("Left"), Qt::AlignLeft, menu, m_horizGroup);
+ m_actions[HorizCenter] = createAction(QDesignerTaskMenu::tr("Center Horizontally"), Qt::AlignHCenter, menu, m_horizGroup);
+ m_actions[Right] = createAction(QDesignerTaskMenu::tr("Right"), Qt::AlignRight, menu, m_horizGroup);
+ menu->addSeparator();
+ m_actions[VerticalNone] = createAction(QDesignerTaskMenu::tr("No Vertical Alignment"), 0, menu, m_verticalGroup);
+ m_actions[Top] = createAction(QDesignerTaskMenu::tr("Top"), Qt::AlignTop, menu, m_verticalGroup);
+ m_actions[VerticalCenter] = createAction(QDesignerTaskMenu::tr("Center Vertically"), Qt::AlignVCenter, menu, m_verticalGroup);
+ m_actions[Bottom] = createAction(QDesignerTaskMenu::tr("Bottom"), Qt::AlignBottom, menu, m_verticalGroup);
+}
+
+void LayoutAlignmentMenu::connect(QObject *receiver, const char *aSlot)
+{
+ QObject::connect(m_horizGroup, SIGNAL(triggered(QAction*)), receiver, aSlot);
+ QObject::connect(m_verticalGroup, SIGNAL(triggered(QAction*)), receiver, aSlot);
+}
+
+bool LayoutAlignmentMenu::setAlignment(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ bool enabled;
+ const Qt::Alignment alignment = LayoutAlignmentCommand::alignmentOf(core, w, &enabled);
+ if (!enabled) {
+ m_subMenuAction->setEnabled(false);
+ m_actions[HorizNone]->setChecked(true);
+ m_actions[VerticalNone]->setChecked(true);
+ return false;
+ }
+ // Get alignment
+ switch (alignment & Qt::AlignHorizontal_Mask) {
+ case Qt::AlignLeft:
+ m_actions[Left]->setChecked(true);
+ break;
+ case Qt::AlignHCenter:
+ m_actions[HorizCenter]->setChecked(true);
+ break;
+ case Qt::AlignRight:
+ m_actions[Right]->setChecked(true);
+ break;
+ default:
+ m_actions[HorizNone]->setChecked(true);
+ break;
+ }
+ switch (alignment & Qt::AlignVertical_Mask) {
+ case Qt::AlignTop:
+ m_actions[Top]->setChecked(true);
+ break;
+ case Qt::AlignVCenter:
+ m_actions[VerticalCenter]->setChecked(true);
+ break;
+ case Qt::AlignBottom:
+ m_actions[Bottom]->setChecked(true);
+ break;
+ default:
+ m_actions[VerticalNone]->setChecked(true);
+ break;
+ }
+ return true;
+}
+
+Qt::Alignment LayoutAlignmentMenu::alignment() const
+{
+ Qt::Alignment alignment = 0;
+ if (const QAction *horizAction = m_horizGroup->checkedAction())
+ if (const int horizAlign = horizAction->data().toInt())
+ alignment |= static_cast<Qt::Alignment>(horizAlign);
+ if (const QAction *vertAction = m_verticalGroup->checkedAction())
+ if (const int vertAlign = vertAction->data().toInt())
+ alignment |= static_cast<Qt::Alignment>(vertAlign);
+ return alignment;
+}
+
+// -------------- QDesignerTaskMenuPrivate
+class QDesignerTaskMenuPrivate {
+public:
+ QDesignerTaskMenuPrivate(QWidget *widget, QObject *parent);
+
+ QDesignerTaskMenu *m_q;
+ QPointer<QWidget> m_widget;
+ QAction *m_separator;
+ QAction *m_separator2;
+ QAction *m_separator3;
+ QAction *m_separator4;
+ QAction *m_separator5;
+ QAction *m_separator6;
+ QAction *m_separator7;
+ QAction *m_changeObjectNameAction;
+ QAction *m_changeToolTip;
+ QAction *m_changeWhatsThis;
+ QAction *m_changeStyleSheet;
+ MorphMenu *m_morphMenu;
+ FormLayoutMenu *m_formLayoutMenu;
+
+ QAction *m_addMenuBar;
+ QAction *m_addToolBar;
+ QAction *m_addStatusBar;
+ QAction *m_removeStatusBar;
+ QAction *m_changeScript;
+ QAction *m_containerFakeMethods;
+ QAction *m_navigateToSlot;
+ PromotionTaskMenu* m_promotionTaskMenu;
+ QActionGroup *m_sizeActionGroup;
+ LayoutAlignmentMenu m_layoutAlignmentMenu;
+ QAction *m_sizeActionsSubMenu;
+};
+
+QDesignerTaskMenuPrivate::QDesignerTaskMenuPrivate(QWidget *widget, QObject *parent) :
+ m_q(0),
+ m_widget(widget),
+ m_separator(createSeparatorHelper(parent)),
+ m_separator2(createSeparatorHelper(parent)),
+ m_separator3(createSeparatorHelper(parent)),
+ m_separator4(createSeparatorHelper(parent)),
+ m_separator5(createSeparatorHelper(parent)),
+ m_separator6(createSeparatorHelper(parent)),
+ m_separator7(createSeparatorHelper(parent)),
+ m_changeObjectNameAction(new QAction(QDesignerTaskMenu::tr("Change objectName..."), parent)),
+ m_changeToolTip(new QAction(QDesignerTaskMenu::tr("Change toolTip..."), parent)),
+ m_changeWhatsThis(new QAction(QDesignerTaskMenu::tr("Change whatsThis..."), parent)),
+ m_changeStyleSheet(new QAction(QDesignerTaskMenu::tr("Change styleSheet..."), parent)),
+ m_morphMenu(new MorphMenu(parent)),
+ m_formLayoutMenu(new FormLayoutMenu(parent)),
+ m_addMenuBar(new QAction(QDesignerTaskMenu::tr("Create Menu Bar"), parent)),
+ m_addToolBar(new QAction(QDesignerTaskMenu::tr("Add Tool Bar"), parent)),
+ m_addStatusBar(new QAction(QDesignerTaskMenu::tr("Create Status Bar"), parent)),
+ m_removeStatusBar(new QAction(QDesignerTaskMenu::tr("Remove Status Bar"), parent)),
+ m_changeScript(new QAction(QDesignerTaskMenu::tr("Change script..."), parent)),
+ m_containerFakeMethods(new QAction(QDesignerTaskMenu::tr("Change signals/slots..."), parent)),
+ m_navigateToSlot(new QAction(QDesignerTaskMenu::tr("Go to slot..."), parent)),
+ m_promotionTaskMenu(new PromotionTaskMenu(widget, PromotionTaskMenu::ModeManagedMultiSelection, parent)),
+ m_sizeActionGroup(new QActionGroup(parent)),
+ m_layoutAlignmentMenu(parent),
+ m_sizeActionsSubMenu(new QAction(QDesignerTaskMenu::tr("Size Constraints"), parent))
+{
+ QMenu *sizeMenu = new QMenu;
+ m_sizeActionsSubMenu->setMenu(sizeMenu);
+ QAction *sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Width"));
+ sizeAction->setData(ApplyMinimumWidth);
+ sizeMenu->addAction(sizeAction);
+
+ sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Height"));
+ sizeAction->setData(ApplyMinimumHeight);
+ sizeMenu->addAction(sizeAction);
+
+ sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Size"));
+ sizeAction->setData(ApplyMinimumWidth|ApplyMinimumHeight);
+ sizeMenu->addAction(sizeAction);
+
+ sizeMenu->addSeparator();
+
+ sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Width"));
+ sizeAction->setData(ApplyMaximumWidth);
+ sizeMenu->addAction(sizeAction);
+
+ sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Height"));
+ sizeAction->setData(ApplyMaximumHeight);
+ sizeMenu->addAction(sizeAction);
+
+ sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Size"));
+ sizeAction->setData(ApplyMaximumWidth|ApplyMaximumHeight);
+ sizeMenu->addAction(sizeAction);
+}
+
+// --------- QDesignerTaskMenu
+QDesignerTaskMenu::QDesignerTaskMenu(QWidget *widget, QObject *parent) :
+ QObject(parent),
+ d(new QDesignerTaskMenuPrivate(widget, parent))
+{
+ d->m_q = this;
+ Q_ASSERT(qobject_cast<QDesignerFormWindowInterface*>(widget) == 0);
+
+ connect(d->m_changeObjectNameAction, SIGNAL(triggered()), this, SLOT(changeObjectName()));
+ connect(d->m_changeToolTip, SIGNAL(triggered()), this, SLOT(changeToolTip()));
+ connect(d->m_changeWhatsThis, SIGNAL(triggered()), this, SLOT(changeWhatsThis()));
+ connect(d->m_changeStyleSheet, SIGNAL(triggered()), this, SLOT(changeStyleSheet()));
+ connect(d->m_addMenuBar, SIGNAL(triggered()), this, SLOT(createMenuBar()));
+ connect(d->m_addToolBar, SIGNAL(triggered()), this, SLOT(addToolBar()));
+ connect(d->m_addStatusBar, SIGNAL(triggered()), this, SLOT(createStatusBar()));
+ connect(d->m_removeStatusBar, SIGNAL(triggered()), this, SLOT(removeStatusBar()));
+ connect(d->m_changeScript, SIGNAL(triggered()), this, SLOT(changeScript()));
+ connect(d->m_containerFakeMethods, SIGNAL(triggered()), this, SLOT(containerFakeMethods()));
+ connect(d->m_navigateToSlot, SIGNAL(triggered()), this, SLOT(slotNavigateToSlot()));
+ connect(d->m_sizeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(applySize(QAction*)));
+ d->m_layoutAlignmentMenu.connect(this, SLOT(slotLayoutAlignment()));
+}
+
+QDesignerTaskMenu::~QDesignerTaskMenu()
+{
+ delete d;
+}
+
+QAction *QDesignerTaskMenu::createSeparator()
+{
+ return createSeparatorHelper(this);
+}
+
+QWidget *QDesignerTaskMenu::widget() const
+{
+ return d->m_widget;
+}
+
+QDesignerFormWindowInterface *QDesignerTaskMenu::formWindow() const
+{
+ QDesignerFormWindowInterface *result = QDesignerFormWindowInterface::findFormWindow(widget());
+ Q_ASSERT(result != 0);
+ return result;
+}
+
+void QDesignerTaskMenu::createMenuBar()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ QMainWindow *mw = qobject_cast<QMainWindow*>(fw->mainContainer());
+ if (!mw) {
+ // ### warning message
+ return;
+ }
+
+ CreateMenuBarCommand *cmd = new CreateMenuBarCommand(fw);
+ cmd->init(mw);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QDesignerTaskMenu::addToolBar()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ QMainWindow *mw = qobject_cast<QMainWindow*>(fw->mainContainer());
+ if (!mw) {
+ // ### warning message
+ return;
+ }
+
+ AddToolBarCommand *cmd = new AddToolBarCommand(fw);
+ cmd->init(mw);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QDesignerTaskMenu::createStatusBar()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ QMainWindow *mw = qobject_cast<QMainWindow*>(fw->mainContainer());
+ if (!mw) {
+ // ### warning message
+ return;
+ }
+
+ CreateStatusBarCommand *cmd = new CreateStatusBarCommand(fw);
+ cmd->init(mw);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QDesignerTaskMenu::removeStatusBar()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ QMainWindow *mw = qobject_cast<QMainWindow*>(fw->mainContainer());
+ if (!mw) {
+ // ### warning message
+ return;
+ }
+
+ DeleteStatusBarCommand *cmd = new DeleteStatusBarCommand(fw);
+ cmd->init(findStatusBar(mw));
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+QList<QAction*> QDesignerTaskMenu::taskActions() const
+{
+ QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(widget());
+ Q_ASSERT(formWindow);
+
+ const bool isMainContainer = formWindow->mainContainer() == widget();
+
+ QList<QAction*> actions;
+
+ if (const QMainWindow *mw = qobject_cast<const QMainWindow*>(formWindow->mainContainer())) {
+ if (isMainContainer || mw->centralWidget() == widget()) {
+ if (!findMenuBar(mw)) {
+ actions.append(d->m_addMenuBar);
+ }
+
+ actions.append(d->m_addToolBar);
+ // ### create the status bar
+ if (!findStatusBar(mw))
+ actions.append(d->m_addStatusBar);
+ else
+ actions.append(d->m_removeStatusBar);
+ actions.append(d->m_separator);
+ }
+ }
+ actions.append(d->m_changeObjectNameAction);
+ d->m_morphMenu->populate(d->m_widget, formWindow, actions);
+ d->m_formLayoutMenu->populate(d->m_widget, formWindow, actions);
+ actions.append(d->m_separator2);
+ actions.append(d->m_changeToolTip);
+ actions.append(d->m_changeWhatsThis);
+ actions.append(d->m_changeStyleSheet);
+ actions.append(d->m_separator6);
+ actions.append(d->m_sizeActionsSubMenu);
+ if (d->m_layoutAlignmentMenu.setAlignment(formWindow->core(), d->m_widget))
+ actions.append(d->m_layoutAlignmentMenu.subMenuAction());
+
+ d->m_promotionTaskMenu->setMode(formWindow->isManaged(d->m_widget) ?
+ PromotionTaskMenu::ModeManagedMultiSelection : PromotionTaskMenu::ModeUnmanagedMultiSelection);
+ d->m_promotionTaskMenu->addActions(formWindow, PromotionTaskMenu::LeadingSeparator, actions);
+
+#ifdef WANT_SCRIPT_OPTION
+ if (!isMainContainer) {
+ actions.append(d->m_separator4);
+ actions.append(d->m_changeScript);
+ }
+#endif
+ if (isMainContainer && !qt_extension<QDesignerLanguageExtension*>(formWindow->core()->extensionManager(), formWindow->core())) {
+ actions.append(d->m_separator5);
+ actions.append(d->m_containerFakeMethods);
+ }
+
+ if (isSlotNavigationEnabled(formWindow->core())) {
+ actions.append(d->m_separator7);
+ actions.append(d->m_navigateToSlot);
+ }
+
+ return actions;
+}
+
+void QDesignerTaskMenu::changeObjectName()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ Q_ASSERT(fw != 0);
+
+ const QString oldObjectName = objName(fw->core(), widget());
+
+ ObjectNameDialog dialog(fw, oldObjectName);
+ if (dialog.exec() == QDialog::Accepted) {
+ const QString newObjectName = dialog.newObjectName();
+ if (!newObjectName.isEmpty() && newObjectName != oldObjectName ) {
+ const QString objectNameProperty = QLatin1String("objectName");
+ PropertySheetStringValue objectNameValue;
+ objectNameValue.setValue(newObjectName);
+ setProperty(fw, CurrentWidgetMode, objectNameProperty, QVariant::fromValue(objectNameValue));
+ }
+ }
+}
+
+void QDesignerTaskMenu::changeTextProperty(const QString &propertyName, const QString &windowTitle, PropertyMode pm, Qt::TextFormat desiredFormat)
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+ Q_ASSERT(d->m_widget->parentWidget() != 0);
+
+ const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(fw->core()->extensionManager(), d->m_widget);
+ const int index = sheet->indexOf(propertyName);
+ if (index == -1) {
+ qDebug() << "** WARNING Invalid property" << propertyName << " passed to changeTextProperty!";
+ return;
+ }
+ PropertySheetStringValue textValue = qvariant_cast<PropertySheetStringValue>(sheet->property(index));
+ const QString oldText = textValue.value();
+ // Pop up respective dialog
+ bool accepted = false;
+ QString newText;
+ switch (desiredFormat) {
+ case Qt::PlainText: {
+ PlainTextEditorDialog dlg(fw->core(), fw);
+ if (!windowTitle.isEmpty())
+ dlg.setWindowTitle(windowTitle);
+ dlg.setDefaultFont(d->m_widget->font());
+ dlg.setText(oldText);
+ accepted = dlg.showDialog() == QDialog::Accepted;
+ newText = dlg.text();
+ }
+ break;
+ default: {
+ RichTextEditorDialog dlg(fw->core(), fw);
+ if (!windowTitle.isEmpty())
+ dlg.setWindowTitle(windowTitle);
+ dlg.setDefaultFont(d->m_widget->font());
+ dlg.setText(oldText);
+ accepted = dlg.showDialog() == QDialog::Accepted;
+ newText = dlg.text(desiredFormat);
+ }
+ break;
+ }
+ // change property
+ if (!accepted || oldText == newText)
+ return;
+
+
+ textValue.setValue(newText);
+ setProperty(fw, pm, propertyName, QVariant::fromValue(textValue));
+}
+
+void QDesignerTaskMenu::changeToolTip()
+{
+ changeTextProperty(QLatin1String("toolTip"), tr("Edit ToolTip"), MultiSelectionMode, Qt::AutoText);
+}
+
+void QDesignerTaskMenu::changeWhatsThis()
+{
+ changeTextProperty(QLatin1String("whatsThis"), tr("Edit WhatsThis"), MultiSelectionMode, Qt::AutoText);
+}
+
+void QDesignerTaskMenu::changeStyleSheet()
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ StyleSheetPropertyEditorDialog dlg(fw, fw, d->m_widget);
+ dlg.exec();
+ }
+}
+
+void QDesignerTaskMenu::changeScript()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+
+ MetaDataBase *metaDataBase = qobject_cast<MetaDataBase*>(fw->core()->metaDataBase());
+ if (!metaDataBase)
+ return;
+
+ const MetaDataBaseItem* item = metaDataBase->metaDataBaseItem(d->m_widget);
+ if (!item)
+ return;
+
+ const QString oldScript = item->script();
+ QString newScript = oldScript;
+
+ ScriptDialog scriptDialog(fw->core()->dialogGui(), fw);
+ if (!scriptDialog.editScript(newScript))
+ return;
+
+ // compile list of selected objects
+ ScriptCommand *scriptCommand = new ScriptCommand(fw);
+ if (!scriptCommand->init(applicableObjects(fw, MultiSelectionMode), newScript)) {
+ delete scriptCommand;
+ return;
+ }
+
+ fw->commandHistory()->push(scriptCommand);
+}
+
+void QDesignerTaskMenu::containerFakeMethods()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+ SignalSlotDialog::editMetaDataBase(fw, d->m_widget, fw);
+}
+
+static QString declaredInClass(const QDesignerMetaObjectInterface *metaObject, const QString &member)
+{
+ // Find class whose superclass does not contain the method.
+ const QDesignerMetaObjectInterface *meta = metaObject;
+
+ for (;;) {
+ const QDesignerMetaObjectInterface *tmpMeta = meta->superClass();
+ if (tmpMeta == 0)
+ break;
+ if (tmpMeta->indexOfMethod(member) == -1)
+ break;
+ meta = tmpMeta;
+ }
+ return meta->className();
+}
+
+bool QDesignerTaskMenu::isSlotNavigationEnabled(const QDesignerFormEditorInterface *core)
+{
+ if (QDesignerIntegration *integr = integration(core))
+ return integr->isSlotNavigationEnabled();
+ return false;
+}
+
+void QDesignerTaskMenu::slotNavigateToSlot()
+{
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ Q_ASSERT(core);
+ navigateToSlot(core, widget());
+}
+
+void QDesignerTaskMenu::navigateToSlot(QDesignerFormEditorInterface *core,
+ QObject *object,
+ const QString &defaultSignal)
+{
+ const QString objectName = objName(core, object);
+ QMap<QString, QMap<QString, QStringList> > classToSignalList;
+
+ QDesignerIntegration *integr = integration(core);
+
+ // "real" signals
+ if (const QDesignerMetaObjectInterface *metaObject = core->introspection()->metaObject(object)) {
+ const int methodCount = metaObject->methodCount();
+ for (int i = 0; i < methodCount; ++i) {
+ const QDesignerMetaMethodInterface *metaMethod = metaObject->method(i);
+ if (metaMethod->methodType() == QDesignerMetaMethodInterface::Signal) {
+ const QString signature = metaMethod->signature();
+ const QStringList parameterNames = metaMethod->parameterNames();
+ classToSignalList[declaredInClass(metaObject, signature)][signature] = parameterNames;
+ }
+ }
+ }
+
+ // fake signals
+ if (qdesigner_internal::MetaDataBase *metaDataBase
+ = qobject_cast<qdesigner_internal::MetaDataBase *>(core->metaDataBase())) {
+ qdesigner_internal::MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(object);
+ Q_ASSERT(item);
+ const QStringList fakeSignals = item->fakeSignals();
+ foreach (const QString &fakeSignal, fakeSignals)
+ classToSignalList[item->customClassName()][fakeSignal] = QStringList();
+ }
+
+ if (object->isWidgetType()) {
+ QWidget *widget = static_cast<QWidget *>(object);
+ if (WidgetDataBase *db = qobject_cast<WidgetDataBase *>(core->widgetDataBase())) {
+ const QString promotedClassName = promotedCustomClassName(core, widget);
+ const int index = core->widgetDataBase()->indexOfClassName(promotedClassName);
+ if (index >= 0) {
+ WidgetDataBaseItem* item = static_cast<WidgetDataBaseItem*>(db->item(index));
+ const QStringList fakeSignals = item->fakeSignals();
+ foreach (const QString &fakeSignal, fakeSignals)
+ classToSignalList[promotedClassName][fakeSignal] = QStringList();
+ }
+ }
+ }
+
+ Ui::SelectSignalDialog dialogUi;
+ QDialog selectSignalDialog(0, Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
+ dialogUi.setupUi(&selectSignalDialog);
+
+ QMap<QString, QMap<QString, QStringList> >::const_iterator iter(classToSignalList.constBegin());
+ for (; iter != classToSignalList.constEnd(); ++iter) {
+ const QString className = iter.key();
+ QMap<QString, QStringList> signalNames = iter.value();
+
+ QMap<QString, QStringList>::const_iterator itSignal(signalNames.constBegin());
+ for (; itSignal != signalNames.constEnd(); ++itSignal) {
+ const QString signalName = itSignal.key();
+ QTreeWidgetItem *row = new QTreeWidgetItem(QStringList() << signalName << className);
+ row->setData(0, Qt::UserRole, itSignal.value());
+ dialogUi.signalList->addTopLevelItem(row);
+ }
+ }
+ if (dialogUi.signalList->topLevelItemCount() == 0) {
+ QTreeWidgetItem *row = new QTreeWidgetItem(QStringList() << tr("no signals available"));
+ dialogUi.signalList->addTopLevelItem(row);
+ dialogUi.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+ } else {
+ connect(dialogUi.signalList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
+ &selectSignalDialog, SLOT(accept()));
+ }
+
+ if (defaultSignal.isEmpty()) {
+ dialogUi.signalList->setCurrentItem(dialogUi.signalList->topLevelItem(0));
+ } else {
+ const QList<QTreeWidgetItem *> items = dialogUi.signalList->findItems (defaultSignal, Qt::MatchExactly, 0);
+ if (!items.empty())
+ dialogUi.signalList->setCurrentItem(items.front());
+ }
+
+ dialogUi.signalList->resizeColumnToContents(0);
+
+ if (selectSignalDialog.exec() == QDialog::Accepted) {
+ QTreeWidgetItem *selectedItem = dialogUi.signalList->selectedItems().first();
+ const QString signalSignature = selectedItem->text(0);
+ const QStringList parameterNames = qvariant_cast<QStringList>(selectedItem->data(0, Qt::UserRole));
+
+ // TODO: Check whether signal is connected to slot
+ integr->emitNavigateToSlot(objectName, signalSignature, parameterNames);
+ }
+}
+
+// Add a command that takes over the value of the current geometry as
+// minimum/maximum size according to the flags.
+static void createSizeCommand(QDesignerFormWindowInterface *fw, QWidget *w, int flags)
+{
+ const QSize size = w->size();
+ if (flags & (ApplyMinimumWidth|ApplyMinimumHeight)) {
+ QSize minimumSize = w-> minimumSize();
+ if (flags & ApplyMinimumWidth)
+ minimumSize.setWidth(size.width());
+ if (flags & ApplyMinimumHeight)
+ minimumSize.setHeight(size.height());
+ SetPropertyCommand* cmd = new SetPropertyCommand(fw);
+ cmd->init(w, QLatin1String("minimumSize"), minimumSize);
+ fw->commandHistory()->push(cmd);
+ }
+ if (flags & (ApplyMaximumWidth|ApplyMaximumHeight)) {
+ QSize maximumSize = w-> maximumSize();
+ if (flags & ApplyMaximumWidth)
+ maximumSize.setWidth(size.width());
+ if (flags & ApplyMaximumHeight)
+ maximumSize.setHeight(size.height());
+ SetPropertyCommand* cmd = new SetPropertyCommand(fw);
+ cmd->init(w, QLatin1String("maximumSize"), maximumSize);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QDesignerTaskMenu::applySize(QAction *a)
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ if (!fw)
+ return;
+
+ const QWidgetList selection = applicableWidgets(fw, MultiSelectionMode);
+ if (selection.isEmpty())
+ return;
+
+ const int mask = a->data().toInt();
+ const int size = selection.size();
+ fw->commandHistory()->beginMacro(tr("Set size constraint on %n widget(s)", 0, size));
+ for (int i = 0; i < size; i++)
+ createSizeCommand(fw, selection.at(i), mask);
+ fw->commandHistory()->endMacro();
+}
+
+template <class Container>
+ static void getApplicableObjects(const QDesignerFormWindowInterface *fw, QWidget *current,
+ QDesignerTaskMenu::PropertyMode pm, Container *c)
+{
+ // Current is always first
+ c->push_back(current);
+ if (pm == QDesignerTaskMenu::CurrentWidgetMode)
+ return;
+ QDesignerObjectInspector *designerObjectInspector = qobject_cast<QDesignerObjectInspector *>(fw->core()->objectInspector());
+ if (!designerObjectInspector)
+ return; // Ooops, someone plugged an old-style Object Inspector
+ // Add managed or unmanaged selection according to current type, make current first
+ Selection s;
+ designerObjectInspector->getSelection(s);
+ const QWidgetList &source = fw->isManaged(current) ? s.managed : s.unmanaged;
+ const QWidgetList::const_iterator cend = source.constEnd();
+ for ( QWidgetList::const_iterator it = source.constBegin(); it != cend; ++it)
+ if (*it != current) // was first
+ c->push_back(*it);
+}
+
+QObjectList QDesignerTaskMenu::applicableObjects(const QDesignerFormWindowInterface *fw, PropertyMode pm) const
+{
+ QObjectList rc;
+ getApplicableObjects(fw, d->m_widget, pm, &rc);
+ return rc;
+}
+
+QWidgetList QDesignerTaskMenu::applicableWidgets(const QDesignerFormWindowInterface *fw, PropertyMode pm) const
+{
+ QWidgetList rc;
+ getApplicableObjects(fw, d->m_widget, pm, &rc);
+ return rc;
+}
+
+void QDesignerTaskMenu::setProperty(QDesignerFormWindowInterface *fw, PropertyMode pm, const QString &name, const QVariant &newValue)
+{
+ SetPropertyCommand* setPropertyCommand = new SetPropertyCommand(fw);
+ if (setPropertyCommand->init(applicableObjects(fw, pm), name, newValue, d->m_widget)) {
+ fw->commandHistory()->push(setPropertyCommand);
+ } else {
+ delete setPropertyCommand;
+ qDebug() << "Unable to set property " << name << '.';
+ }
+}
+
+void QDesignerTaskMenu::slotLayoutAlignment()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ const Qt::Alignment newAlignment = d->m_layoutAlignmentMenu.alignment();
+ LayoutAlignmentCommand *cmd = new LayoutAlignmentCommand(fw);
+ if (cmd->init(d->m_widget, newAlignment)) {
+ fw->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ }
+}
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_taskmenu_p.h b/src/designer/src/lib/shared/qdesigner_taskmenu_p.h
new file mode 100644
index 000000000..b86ce69b1
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_taskmenu_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_TASKMENU_H
+#define QDESIGNER_TASKMENU_H
+
+#include "shared_global_p.h"
+#include "extensionfactory_p.h"
+#include <QtDesigner/QDesignerTaskMenuExtension>
+
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+
+class QWidget;
+class QSignalMapper;
+
+namespace qdesigner_internal {
+class QDesignerTaskMenuPrivate;
+
+class QDESIGNER_SHARED_EXPORT QDesignerTaskMenu: public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ QDesignerTaskMenu(QWidget *widget, QObject *parent);
+ virtual ~QDesignerTaskMenu();
+
+ QWidget *widget() const;
+
+ virtual QList<QAction*> taskActions() const;
+
+ enum PropertyMode { CurrentWidgetMode, MultiSelectionMode };
+
+ static bool isSlotNavigationEnabled(const QDesignerFormEditorInterface *core);
+ static void navigateToSlot(QDesignerFormEditorInterface *core, QObject *o,
+ const QString &defaultSignal = QString());
+
+protected:
+
+ QDesignerFormWindowInterface *formWindow() const;
+ void changeTextProperty(const QString &propertyName, const QString &windowTitle, PropertyMode pm, Qt::TextFormat desiredFormat);
+
+ QAction *createSeparator();
+
+ /* Retrieve the list of objects the task menu is supposed to act on. Note that a task menu can be invoked for
+ * an unmanaged widget [as of 4.5], in which case it must not use the cursor selection,
+ * but the unmanaged selection of the object inspector. */
+ QObjectList applicableObjects(const QDesignerFormWindowInterface *fw, PropertyMode pm) const;
+ QList<QWidget *> applicableWidgets(const QDesignerFormWindowInterface *fw, PropertyMode pm) const;
+
+ void setProperty(QDesignerFormWindowInterface *fw, PropertyMode pm, const QString &name, const QVariant &newValue);
+
+private slots:
+ void changeObjectName();
+ void changeToolTip();
+ void changeWhatsThis();
+ void changeStyleSheet();
+ void createMenuBar();
+ void addToolBar();
+ void createStatusBar();
+ void removeStatusBar();
+ void changeScript();
+ void containerFakeMethods();
+ void slotNavigateToSlot();
+ void applySize(QAction *a);
+ void slotLayoutAlignment();
+
+private:
+ QDesignerTaskMenuPrivate *d;
+};
+
+typedef ExtensionFactory<QDesignerTaskMenuExtension, QWidget, QDesignerTaskMenu> QDesignerTaskMenuFactory;
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_TASKMENU_H
diff --git a/src/designer/src/lib/shared/qdesigner_toolbar.cpp b/src/designer/src/lib/shared/qdesigner_toolbar.cpp
new file mode 100644
index 000000000..0fe730384
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_toolbar.cpp
@@ -0,0 +1,488 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_toolbar_p.h"
+#include "qdesigner_command_p.h"
+#include "actionrepository_p.h"
+#include "actionprovider_p.h"
+#include "qdesigner_utils_p.h"
+#include "qdesigner_objectinspector_p.h"
+#include "promotiontaskmenu_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <actionprovider_p.h>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QToolButton>
+#include <QtGui/QToolBar>
+#include <QtGui/QMenu>
+#include <QtGui/qevent.h>
+#include <QtGui/QApplication>
+#include <QtCore/QDebug>
+
+Q_DECLARE_METATYPE(QAction*)
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<QAction*> ActionList;
+
+namespace qdesigner_internal {
+// ------------------- ToolBarEventFilter
+void ToolBarEventFilter::install(QToolBar *tb)
+{
+ ToolBarEventFilter *tf = new ToolBarEventFilter(tb);
+ tb->installEventFilter(tf);
+ tb->setAcceptDrops(true); // ### fake
+}
+
+ToolBarEventFilter::ToolBarEventFilter(QToolBar *tb) :
+ QObject(tb),
+ m_toolBar(tb),
+ m_promotionTaskMenu(0)
+{
+}
+
+ToolBarEventFilter *ToolBarEventFilter::eventFilterOf(const QToolBar *tb)
+{
+ // Look for 1st order children only..otherwise, we might get filters of nested widgets
+ const QObjectList children = tb->children();
+ const QObjectList::const_iterator cend = children.constEnd();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it) {
+ QObject *o = *it;
+ if (!o->isWidgetType())
+ if (ToolBarEventFilter *ef = qobject_cast<ToolBarEventFilter *>(o))
+ return ef;
+ }
+ return 0;
+}
+
+bool ToolBarEventFilter::eventFilter (QObject *watched, QEvent *event)
+{
+ if (watched != m_toolBar)
+ return QObject::eventFilter (watched, event);
+
+ switch (event->type()) {
+ case QEvent::ChildAdded: {
+ // Children should not interact with the mouse
+ const QChildEvent *ce = static_cast<const QChildEvent *>(event);
+ if (QWidget *w = qobject_cast<QWidget *>(ce->child())) {
+ w->setAttribute(Qt::WA_TransparentForMouseEvents, true);
+ w->setFocusPolicy(Qt::NoFocus);
+ }
+ }
+ break;
+ case QEvent::ContextMenu:
+ return handleContextMenuEvent(static_cast<QContextMenuEvent*>(event));
+ case QEvent::DragEnter:
+ case QEvent::DragMove:
+ return handleDragEnterMoveEvent(static_cast<QDragMoveEvent *>(event));
+ case QEvent::DragLeave:
+ return handleDragLeaveEvent(static_cast<QDragLeaveEvent *>(event));
+ case QEvent::Drop:
+ return handleDropEvent(static_cast<QDropEvent *>(event));
+ case QEvent::MouseButtonPress:
+ return handleMousePressEvent(static_cast<QMouseEvent*>(event));
+ case QEvent::MouseButtonRelease:
+ return handleMouseReleaseEvent(static_cast<QMouseEvent*>(event));
+ case QEvent::MouseMove:
+ return handleMouseMoveEvent(static_cast<QMouseEvent*>(event));
+ default:
+ break;
+ }
+ return QObject::eventFilter (watched, event);
+}
+
+ActionList ToolBarEventFilter::contextMenuActions(const QPoint &globalPos)
+{
+ ActionList rc;
+ const int index = actionIndexAt(m_toolBar, m_toolBar->mapFromGlobal(globalPos), m_toolBar->orientation());
+ const ActionList actions = m_toolBar->actions();
+ QAction *action = index != -1 ?actions.at(index) : 0;
+ QVariant itemData;
+
+ // Insert before
+ if (action && index != 0 && !action->isSeparator()) {
+ QAction *newSeperatorAct = new QAction(tr("Insert Separator before '%1'").arg(action->objectName()), 0);
+ itemData.setValue(action);
+ newSeperatorAct->setData(itemData);
+ connect(newSeperatorAct, SIGNAL(triggered()), this, SLOT(slotInsertSeparator()));
+ rc.push_back(newSeperatorAct);
+ }
+
+ // Append separator
+ if (actions.empty() || !actions.back()->isSeparator()) {
+ QAction *newSeperatorAct = new QAction(tr("Append Separator"), 0);
+ itemData.setValue(static_cast<QAction*>(0));
+ newSeperatorAct->setData(itemData);
+ connect(newSeperatorAct, SIGNAL(triggered()), this, SLOT(slotInsertSeparator()));
+ rc.push_back(newSeperatorAct);
+ }
+ // Promotion
+ if (!m_promotionTaskMenu)
+ m_promotionTaskMenu = new PromotionTaskMenu(m_toolBar, PromotionTaskMenu::ModeSingleWidget, this);
+ m_promotionTaskMenu->addActions(formWindow(), PromotionTaskMenu::LeadingSeparator|PromotionTaskMenu::TrailingSeparator, rc);
+ // Remove
+ if (action) {
+ QAction *a = new QAction(tr("Remove action '%1'").arg(action->objectName()), 0);
+ itemData.setValue(action);
+ a->setData(itemData);
+ connect(a, SIGNAL(triggered()), this, SLOT(slotRemoveSelectedAction()));
+ rc.push_back(a);
+ }
+
+ QAction *remove_toolbar = new QAction(tr("Remove Toolbar '%1'").arg(m_toolBar->objectName()), 0);
+ connect(remove_toolbar, SIGNAL(triggered()), this, SLOT(slotRemoveToolBar()));
+ rc.push_back(remove_toolbar);
+ return rc;
+}
+
+bool ToolBarEventFilter::handleContextMenuEvent(QContextMenuEvent * event )
+{
+ event->accept();
+
+ const QPoint globalPos = event->globalPos();
+ const ActionList al = contextMenuActions(event->globalPos());
+
+ QMenu menu(0);
+ const ActionList::const_iterator acend = al.constEnd();
+ for (ActionList::const_iterator it = al.constBegin(); it != acend; ++it)
+ menu.addAction(*it);
+ menu.exec(globalPos);
+ return true;
+}
+
+void ToolBarEventFilter::slotRemoveSelectedAction()
+{
+ QAction *action = qobject_cast<QAction*>(sender());
+ if (!action)
+ return;
+
+ QAction *a = qvariant_cast<QAction*>(action->data());
+ Q_ASSERT(a != 0);
+
+ QDesignerFormWindowInterface *fw = formWindow();
+ Q_ASSERT(fw);
+
+ const ActionList actions = m_toolBar->actions();
+ const int pos = actions.indexOf(a);
+ QAction *action_before = 0;
+ if (pos != -1 && actions.count() > pos + 1)
+ action_before = actions.at(pos + 1);
+
+ RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw);
+ cmd->init(m_toolBar, a, action_before);
+ fw->commandHistory()->push(cmd);
+}
+
+void ToolBarEventFilter::slotRemoveToolBar()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ Q_ASSERT(fw);
+ DeleteToolBarCommand *cmd = new DeleteToolBarCommand(fw);
+ cmd->init(m_toolBar);
+ fw->commandHistory()->push(cmd);
+}
+
+void ToolBarEventFilter::slotInsertSeparator()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ QAction *theSender = qobject_cast<QAction*>(sender());
+ QAction *previous = qvariant_cast<QAction *>(theSender->data());
+ fw->beginCommand(tr("Insert Separator"));
+ QAction *action = createAction(fw, QLatin1String("separator"), true);
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(m_toolBar, action, previous);
+ fw->commandHistory()->push(cmd);
+ fw->endCommand();
+}
+
+QDesignerFormWindowInterface *ToolBarEventFilter::formWindow() const
+{
+ return QDesignerFormWindowInterface::findFormWindow(m_toolBar);
+}
+
+QAction *ToolBarEventFilter::createAction(QDesignerFormWindowInterface *fw, const QString &objectName, bool separator)
+{
+ QAction *action = new QAction(fw);
+ fw->core()->widgetFactory()->initialize(action);
+ if (separator)
+ action->setSeparator(true);
+
+ action->setObjectName(objectName);
+ fw->ensureUniqueObjectName(action);
+
+ qdesigner_internal::AddActionCommand *cmd = new qdesigner_internal::AddActionCommand(fw);
+ cmd->init(action);
+ fw->commandHistory()->push(cmd);
+
+ return action;
+}
+
+void ToolBarEventFilter::adjustDragIndicator(const QPoint &pos)
+{
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ QDesignerFormEditorInterface *core = fw->core();
+ if (QDesignerActionProviderExtension *a = qt_extension<QDesignerActionProviderExtension*>(core->extensionManager(), m_toolBar))
+ a->adjustIndicator(pos);
+ }
+}
+
+void ToolBarEventFilter::hideDragIndicator()
+{
+ adjustDragIndicator(QPoint(-1, -1));
+}
+
+bool ToolBarEventFilter::handleMousePressEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton || withinHandleArea(m_toolBar, event->pos()))
+ return false;
+
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ QDesignerFormEditorInterface *core = fw->core();
+ // Keep selection in sync
+ fw->clearSelection(false);
+ if (QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core->objectInspector())) {
+ oi->clearSelection();
+ oi->selectObject(m_toolBar);
+ }
+ core->propertyEditor()->setObject(m_toolBar);
+ }
+ m_startPosition = m_toolBar->mapFromGlobal(event->globalPos());
+ event->accept();
+ return true;
+}
+
+bool ToolBarEventFilter::handleMouseReleaseEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton || m_startPosition.isNull() || withinHandleArea(m_toolBar, event->pos()))
+ return false;
+
+ // Accept the event, otherwise, form window selection will trigger
+ m_startPosition = QPoint();
+ event->accept();
+ return true;
+}
+
+bool ToolBarEventFilter::handleMouseMoveEvent(QMouseEvent *event)
+{
+ if (m_startPosition.isNull() || withinHandleArea(m_toolBar, event->pos()))
+ return false;
+
+ const QPoint pos = m_toolBar->mapFromGlobal(event->globalPos());
+ if ((pos - m_startPosition).manhattanLength() > qApp->startDragDistance()) {
+ startDrag(m_startPosition, event->modifiers());
+ m_startPosition = QPoint();
+ event->accept();
+ return true;
+ }
+ return false;
+}
+
+bool ToolBarEventFilter::handleDragEnterMoveEvent(QDragMoveEvent *event)
+{
+ const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
+ if (!d)
+ return false;
+
+ if (d->actionList().isEmpty()) {
+ event->ignore();
+ hideDragIndicator();
+ return true;
+ }
+
+ QAction *action = d->actionList().first();
+ if (!action || action->menu() || m_toolBar->actions().contains(action) || !Utils::isObjectAncestorOf(formWindow()->mainContainer(), action)) {
+ event->ignore();
+ hideDragIndicator();
+ return true;
+ }
+
+ d->accept(event);
+ adjustDragIndicator(event->pos());
+ return true;
+}
+
+bool ToolBarEventFilter::handleDragLeaveEvent(QDragLeaveEvent *)
+{
+ hideDragIndicator();
+ return false;
+}
+
+bool ToolBarEventFilter::handleDropEvent(QDropEvent *event)
+{
+ const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
+ if (!d)
+ return false;
+
+ if (d->actionList().isEmpty()) {
+ event->ignore();
+ hideDragIndicator();
+ return true;
+ }
+
+ QAction *action = d->actionList().first();
+
+ const ActionList actions = m_toolBar->actions();
+ if (!action || actions.contains(action)) {
+ event->ignore();
+ hideDragIndicator();
+ return true;
+ }
+
+ // Try to find action to 'insert before'. Click on action or in free area, else ignore.
+ QAction *beforeAction = 0;
+ const QPoint pos = event->pos();
+ const int index = actionIndexAt(m_toolBar, pos, m_toolBar->orientation());
+ if (index != -1) {
+ beforeAction = actions.at(index);
+ } else {
+ if (!freeArea(m_toolBar).contains(pos)) {
+ event->ignore();
+ hideDragIndicator();
+ return true;
+ }
+ }
+
+ event->acceptProposedAction();
+ QDesignerFormWindowInterface *fw = formWindow();
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(m_toolBar, action, beforeAction);
+ fw->commandHistory()->push(cmd);
+ hideDragIndicator();
+ return true;
+}
+
+void ToolBarEventFilter::startDrag(const QPoint &pos, Qt::KeyboardModifiers modifiers)
+{
+ const int index = actionIndexAt(m_toolBar, pos, m_toolBar->orientation());
+ if (index == - 1)
+ return;
+
+ const ActionList actions = m_toolBar->actions();
+ QAction *action = actions.at(index);
+ QDesignerFormWindowInterface *fw = formWindow();
+
+ const Qt::DropAction dropAction = (modifiers & Qt::ControlModifier) ? Qt::CopyAction : Qt::MoveAction;
+ if (dropAction == Qt::MoveAction) {
+ RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw);
+ const int nextIndex = index + 1;
+ QAction *nextAction = nextIndex < actions.size() ? actions.at(nextIndex) : 0;
+ cmd->init(m_toolBar, action, nextAction);
+ fw->commandHistory()->push(cmd);
+ }
+
+ QDrag *drag = new QDrag(m_toolBar);
+ drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap( action));
+ drag->setMimeData(new ActionRepositoryMimeData(action, dropAction));
+
+ if (drag->start(dropAction) == Qt::IgnoreAction) {
+ hideDragIndicator();
+ if (dropAction == Qt::MoveAction) {
+ const ActionList currentActions = m_toolBar->actions();
+ QAction *previous = 0;
+ if (index >= 0 && index < currentActions.size())
+ previous = currentActions.at(index);
+ InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
+ cmd->init(m_toolBar, action, previous);
+ fw->commandHistory()->push(cmd);
+ }
+ }
+}
+
+QAction *ToolBarEventFilter::actionAt(const QToolBar *tb, const QPoint &pos)
+{
+ const int index = actionIndexAt(tb, pos, tb->orientation());
+ if (index == -1)
+ return 0;
+ return tb->actions().at(index);
+}
+
+//that's a trick to get access to the initStyleOption which is a protected member
+class FriendlyToolBar : public QToolBar {
+public:
+ friend class ToolBarEventFilter;
+};
+
+QRect ToolBarEventFilter::handleArea(const QToolBar *tb)
+{
+ QStyleOptionToolBar opt;
+ static_cast<const FriendlyToolBar*>(tb)->initStyleOption(&opt);
+ return tb->style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, tb);
+}
+
+bool ToolBarEventFilter::withinHandleArea(const QToolBar *tb, const QPoint &pos)
+{
+ return handleArea(tb).contains(pos);
+}
+
+// Determine the free area behind the last action.
+QRect ToolBarEventFilter::freeArea(const QToolBar *tb)
+{
+ QRect rc = QRect(QPoint(0, 0), tb->size());
+ const ActionList actionList = tb->actions();
+ QRect exclusionRectangle = actionList.empty() ? handleArea(tb) : tb->actionGeometry(actionList.back());
+ switch (tb->orientation()) {
+ case Qt::Horizontal:
+ switch (tb->layoutDirection()) {
+ case Qt::LayoutDirectionAuto: // Should never happen
+ case Qt::LeftToRight:
+ rc.setX(exclusionRectangle.right() + 1);
+ break;
+ case Qt::RightToLeft:
+ rc.setRight(exclusionRectangle.x());
+ break;
+ }
+ break;
+ case Qt::Vertical:
+ rc.setY(exclusionRectangle.bottom() + 1);
+ break;
+ }
+ return rc;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_toolbar_p.h b/src/designer/src/lib/shared/qdesigner_toolbar_p.h
new file mode 100644
index 000000000..7a38ec773
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_toolbar_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_TOOLBAR_H
+#define QDESIGNER_TOOLBAR_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QAction>
+#include <QtGui/QToolButton>
+
+#include <QtCore/QList>
+#include <QtCore/QPoint>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QToolBar;
+class QRect;
+class QAction;
+
+namespace qdesigner_internal {
+
+class PromotionTaskMenu;
+
+// Special event filter for tool bars in designer.
+// Handles drag and drop to and from. Ensures that each
+// child widget is WA_TransparentForMouseEvents to enable drag and drop.
+
+class QDESIGNER_SHARED_EXPORT ToolBarEventFilter : public QObject {
+ Q_OBJECT
+
+public:
+ static void install(QToolBar *tb);
+
+ // Find action by position. Note that QToolBar::actionAt() will
+ // not work as designer sets WA_TransparentForMouseEvents on its tool bar buttons
+ // to be able to drag them. This function will return the dummy
+ // sentinel action when applied to tool bars created by designer if the position matches.
+ static QAction *actionAt(const QToolBar *tb, const QPoint &pos);
+
+ static bool withinHandleArea(const QToolBar *tb, const QPoint &pos);
+ static QRect handleArea(const QToolBar *tb);
+ static QRect freeArea(const QToolBar *tb);
+
+ // Utility to create an action
+ static QAction *createAction(QDesignerFormWindowInterface *fw, const QString &objectName, bool separator);
+
+ virtual bool eventFilter (QObject *watched, QEvent *event);
+
+ // Helper for task menu extension
+ QList<QAction *> contextMenuActions(const QPoint &globalPos = QPoint(-1, -1));
+
+ static ToolBarEventFilter *eventFilterOf(const QToolBar *tb);
+
+private slots:
+ void slotRemoveSelectedAction();
+ void slotRemoveToolBar();
+ void slotInsertSeparator();
+
+private:
+ explicit ToolBarEventFilter(QToolBar *tb);
+
+ bool handleContextMenuEvent(QContextMenuEvent * event);
+ bool handleDragEnterMoveEvent(QDragMoveEvent *event);
+ bool handleDragLeaveEvent(QDragLeaveEvent *);
+ bool handleDropEvent(QDropEvent *event);
+ bool handleMousePressEvent(QMouseEvent *event);
+ bool handleMouseReleaseEvent(QMouseEvent *event);
+ bool handleMouseMoveEvent(QMouseEvent *event);
+
+ QDesignerFormWindowInterface *formWindow() const;
+ void adjustDragIndicator(const QPoint &pos);
+ void hideDragIndicator();
+ void startDrag(const QPoint &pos, Qt::KeyboardModifiers modifiers);
+ bool withinHandleArea(const QPoint &pos) const;
+
+ QToolBar *m_toolBar;
+ PromotionTaskMenu *m_promotionTaskMenu;
+ QPoint m_startPosition;
+};
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_TOOLBAR_H
diff --git a/src/designer/src/lib/shared/qdesigner_toolbox.cpp b/src/designer/src/lib/shared/qdesigner_toolbox.cpp
new file mode 100644
index 000000000..675e98c36
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_toolbox.cpp
@@ -0,0 +1,437 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_toolbox_p.h"
+#include "qdesigner_command_p.h"
+#include "orderdialog_p.h"
+#include "promotiontaskmenu_p.h"
+#include "formwindowbase_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtCore/QEvent>
+#include <QtGui/QAction>
+#include <QtGui/QToolBox>
+#include <QtGui/QMenu>
+#include <QtGui/QLayout>
+#include <QtGui/QApplication>
+#include <QtGui/QContextMenuEvent>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+QToolBoxHelper::QToolBoxHelper(QToolBox *toolbox) :
+ QObject(toolbox),
+ m_toolbox(toolbox),
+ m_actionDeletePage(new QAction(tr("Delete Page"), this)),
+ m_actionInsertPage(new QAction(tr("Before Current Page"), this)),
+ m_actionInsertPageAfter(new QAction(tr("After Current Page"), this)),
+ m_actionChangePageOrder(new QAction(tr("Change Page Order..."), this)),
+ m_pagePromotionTaskMenu(new qdesigner_internal::PromotionTaskMenu(0, qdesigner_internal::PromotionTaskMenu::ModeSingleWidget, this))
+{
+ connect(m_actionDeletePage, SIGNAL(triggered()), this, SLOT(removeCurrentPage()));
+ connect(m_actionInsertPage, SIGNAL(triggered()), this, SLOT(addPage()));
+ connect(m_actionInsertPageAfter, SIGNAL(triggered()), this, SLOT(addPageAfter()));
+ connect(m_actionChangePageOrder, SIGNAL(triggered()), this, SLOT(changeOrder()));
+
+ m_toolbox->installEventFilter(this);
+}
+
+void QToolBoxHelper::install(QToolBox *toolbox)
+{
+ new QToolBoxHelper(toolbox);
+}
+
+bool QToolBoxHelper::eventFilter(QObject *watched, QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::ChildPolished:
+ // Install on the buttons
+ if (watched == m_toolbox) {
+ QChildEvent *ce = static_cast<QChildEvent *>(event);
+ if (!qstrcmp(ce->child()->metaObject()->className(), "QToolBoxButton"))
+ ce->child()->installEventFilter(this);
+ }
+ break;
+ case QEvent::ContextMenu:
+ if (watched != m_toolbox) {
+ // An action invoked from the passive interactor (ToolBox button) might
+ // cause its deletion within its event handler, triggering a warning. Re-post
+ // the event to the toolbox.
+ QContextMenuEvent *current = static_cast<QContextMenuEvent *>(event);
+ QContextMenuEvent *copy = new QContextMenuEvent(current->reason(), current->pos(), current-> globalPos(), current->modifiers());
+ QApplication::postEvent(m_toolbox, copy);
+ current->accept();
+ return true;
+ }
+ break;
+ case QEvent::MouseButtonRelease:
+ if (watched != m_toolbox)
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_toolbox)) {
+ fw->clearSelection();
+ fw->selectWidget(m_toolbox, true);
+ }
+ break;
+ default:
+ break;
+ }
+ return QObject::eventFilter(watched, event);
+}
+
+QToolBoxHelper *QToolBoxHelper::helperOf(const QToolBox *toolbox)
+{
+ // Look for 1st order children only..otherwise, we might get filters of nested widgets
+ const QObjectList children = toolbox->children();
+ const QObjectList::const_iterator cend = children.constEnd();
+ for (QObjectList::const_iterator it = children.constBegin(); it != cend; ++it) {
+ QObject *o = *it;
+ if (!o->isWidgetType())
+ if (QToolBoxHelper *h = qobject_cast<QToolBoxHelper *>(o))
+ return h;
+ }
+ return 0;
+}
+
+QMenu *QToolBoxHelper::addToolBoxContextMenuActions(const QToolBox *toolbox, QMenu *popup)
+{
+ QToolBoxHelper *helper = helperOf(toolbox);
+ if (!helper)
+ return 0;
+ return helper->addContextMenuActions(popup);
+}
+
+void QToolBoxHelper::removeCurrentPage()
+{
+ if (m_toolbox->currentIndex() == -1 || !m_toolbox->widget(m_toolbox->currentIndex()))
+ return;
+
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_toolbox)) {
+ qdesigner_internal::DeleteToolBoxPageCommand *cmd = new qdesigner_internal::DeleteToolBoxPageCommand(fw);
+ cmd->init(m_toolbox);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QToolBoxHelper::addPage()
+{
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_toolbox)) {
+ qdesigner_internal::AddToolBoxPageCommand *cmd = new qdesigner_internal::AddToolBoxPageCommand(fw);
+ cmd->init(m_toolbox, qdesigner_internal::AddToolBoxPageCommand::InsertBefore);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+void QToolBoxHelper::changeOrder()
+{
+ QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_toolbox);
+
+ if (!fw)
+ return;
+
+ const QWidgetList oldPages = qdesigner_internal::OrderDialog::pagesOfContainer(fw->core(), m_toolbox);
+ const int pageCount = oldPages.size();
+ if (pageCount < 2)
+ return;
+
+ qdesigner_internal::OrderDialog dlg(fw);
+ dlg.setPageList(oldPages);
+ if (dlg.exec() == QDialog::Rejected)
+ return;
+
+ const QWidgetList newPages = dlg.pageList();
+ if (newPages == oldPages)
+ return;
+
+ fw->beginCommand(tr("Change Page Order"));
+ for(int i=0; i < pageCount; ++i) {
+ if (newPages.at(i) == m_toolbox->widget(i))
+ continue;
+ qdesigner_internal::MoveToolBoxPageCommand *cmd = new qdesigner_internal::MoveToolBoxPageCommand(fw);
+ cmd->init(m_toolbox, newPages.at(i), i);
+ fw->commandHistory()->push(cmd);
+ }
+ fw->endCommand();
+}
+
+void QToolBoxHelper::addPageAfter()
+{
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_toolbox)) {
+ qdesigner_internal::AddToolBoxPageCommand *cmd = new qdesigner_internal::AddToolBoxPageCommand(fw);
+ cmd->init(m_toolbox, qdesigner_internal::AddToolBoxPageCommand::InsertAfter);
+ fw->commandHistory()->push(cmd);
+ }
+}
+
+QPalette::ColorRole QToolBoxHelper::currentItemBackgroundRole() const
+{
+ const QWidget *w = m_toolbox->widget(0);
+ if (!w)
+ return QPalette::Window;
+ return w->backgroundRole();
+}
+
+void QToolBoxHelper::setCurrentItemBackgroundRole(QPalette::ColorRole role)
+{
+ const int count = m_toolbox->count();
+ for (int i = 0; i < count; ++i) {
+ QWidget *w = m_toolbox->widget(i);
+ w->setBackgroundRole(role);
+ w->update();
+ }
+}
+
+QMenu *QToolBoxHelper::addContextMenuActions(QMenu *popup) const
+{
+ QMenu *pageMenu = 0;
+ const int count = m_toolbox->count();
+ m_actionDeletePage->setEnabled(count > 1);
+ if (count) {
+ const QString pageSubMenuLabel = tr("Page %1 of %2").arg(m_toolbox->currentIndex() + 1).arg(count);
+ pageMenu = popup->addMenu(pageSubMenuLabel);
+
+ pageMenu->addAction(m_actionDeletePage);
+ // Set up promotion menu for current widget.
+ if (QWidget *page = m_toolbox->currentWidget ()) {
+ m_pagePromotionTaskMenu->setWidget(page);
+ m_pagePromotionTaskMenu->addActions(QDesignerFormWindowInterface::findFormWindow(m_toolbox),
+ qdesigner_internal::PromotionTaskMenu::SuppressGlobalEdit,
+ pageMenu);
+ }
+ }
+ QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
+ insertPageMenu->addAction(m_actionInsertPageAfter);
+ insertPageMenu->addAction(m_actionInsertPage);
+ if (count > 1) {
+ popup->addAction(m_actionChangePageOrder);
+ }
+ popup->addSeparator();
+ return pageMenu;
+}
+
+// -------- QToolBoxWidgetPropertySheet
+
+static const char *currentItemTextKey = "currentItemText";
+static const char *currentItemNameKey = "currentItemName";
+static const char *currentItemIconKey = "currentItemIcon";
+static const char *currentItemToolTipKey = "currentItemToolTip";
+static const char *tabSpacingKey = "tabSpacing";
+
+enum { tabSpacingDefault = -1 };
+
+QToolBoxWidgetPropertySheet::QToolBoxWidgetPropertySheet(QToolBox *object, QObject *parent) :
+ QDesignerPropertySheet(object, parent),
+ m_toolBox(object)
+{
+ createFakeProperty(QLatin1String(currentItemTextKey), QVariant::fromValue(qdesigner_internal::PropertySheetStringValue()));
+ createFakeProperty(QLatin1String(currentItemNameKey), QString());
+ createFakeProperty(QLatin1String(currentItemIconKey), QVariant::fromValue(qdesigner_internal::PropertySheetIconValue()));
+ if (formWindowBase())
+ formWindowBase()->addReloadableProperty(this, indexOf(QLatin1String(currentItemIconKey)));
+ createFakeProperty(QLatin1String(currentItemToolTipKey), QVariant::fromValue(qdesigner_internal::PropertySheetStringValue()));
+ createFakeProperty(QLatin1String(tabSpacingKey), QVariant(tabSpacingDefault));
+}
+
+QToolBoxWidgetPropertySheet::ToolBoxProperty QToolBoxWidgetPropertySheet::toolBoxPropertyFromName(const QString &name)
+{
+ typedef QHash<QString, ToolBoxProperty> ToolBoxPropertyHash;
+ static ToolBoxPropertyHash toolBoxPropertyHash;
+ if (toolBoxPropertyHash.empty()) {
+ toolBoxPropertyHash.insert(QLatin1String(currentItemTextKey), PropertyCurrentItemText);
+ toolBoxPropertyHash.insert(QLatin1String(currentItemNameKey), PropertyCurrentItemName);
+ toolBoxPropertyHash.insert(QLatin1String(currentItemIconKey), PropertyCurrentItemIcon);
+ toolBoxPropertyHash.insert(QLatin1String(currentItemToolTipKey), PropertyCurrentItemToolTip);
+ toolBoxPropertyHash.insert(QLatin1String(tabSpacingKey), PropertyTabSpacing);
+ }
+ return toolBoxPropertyHash.value(name, PropertyToolBoxNone);
+}
+
+void QToolBoxWidgetPropertySheet::setProperty(int index, const QVariant &value)
+{
+ const ToolBoxProperty toolBoxProperty = toolBoxPropertyFromName(propertyName(index));
+ // independent of index
+ switch (toolBoxProperty) {
+ case PropertyTabSpacing:
+ m_toolBox->layout()->setSpacing(value.toInt());
+ return;
+ case PropertyToolBoxNone:
+ QDesignerPropertySheet::setProperty(index, value);
+ return;
+ default:
+ break;
+ }
+ // index-dependent
+ const int currentIndex = m_toolBox->currentIndex();
+ QWidget *currentWidget = m_toolBox->currentWidget();
+ if (!currentWidget)
+ return;
+
+ switch (toolBoxProperty) {
+ case PropertyCurrentItemText:
+ m_toolBox->setItemText(currentIndex, qvariant_cast<QString>(resolvePropertyValue(index, value)));
+ m_pageToData[currentWidget].text = qvariant_cast<qdesigner_internal::PropertySheetStringValue>(value);
+ break;
+ case PropertyCurrentItemName:
+ currentWidget->setObjectName(value.toString());
+ break;
+ case PropertyCurrentItemIcon:
+ m_toolBox->setItemIcon(currentIndex, qvariant_cast<QIcon>(resolvePropertyValue(index, value)));
+ m_pageToData[currentWidget].icon = qvariant_cast<qdesigner_internal::PropertySheetIconValue>(value);
+ break;
+ case PropertyCurrentItemToolTip:
+ m_toolBox->setItemToolTip(currentIndex, qvariant_cast<QString>(resolvePropertyValue(index, value)));
+ m_pageToData[currentWidget].tooltip = qvariant_cast<qdesigner_internal::PropertySheetStringValue>(value);
+ break;
+ case PropertyTabSpacing:
+ case PropertyToolBoxNone:
+ break;
+ }
+}
+
+bool QToolBoxWidgetPropertySheet::isEnabled(int index) const
+{
+ switch (toolBoxPropertyFromName(propertyName(index))) {
+ case PropertyToolBoxNone: // independent of index
+ case PropertyTabSpacing:
+ return QDesignerPropertySheet::isEnabled(index);
+ default:
+ break;
+ }
+ return m_toolBox->currentIndex() != -1;
+}
+
+QVariant QToolBoxWidgetPropertySheet::property(int index) const
+{
+ const ToolBoxProperty toolBoxProperty = toolBoxPropertyFromName(propertyName(index));
+ // independent of index
+ switch (toolBoxProperty) {
+ case PropertyTabSpacing:
+ return m_toolBox->layout()->spacing();
+ case PropertyToolBoxNone:
+ return QDesignerPropertySheet::property(index);
+ default:
+ break;
+ }
+ // index-dependent
+ QWidget *currentWidget = m_toolBox->currentWidget();
+ if (!currentWidget) {
+ if (toolBoxProperty == PropertyCurrentItemIcon)
+ return QVariant::fromValue(qdesigner_internal::PropertySheetIconValue());
+ if (toolBoxProperty == PropertyCurrentItemText)
+ return QVariant::fromValue(qdesigner_internal::PropertySheetStringValue());
+ if (toolBoxProperty == PropertyCurrentItemToolTip)
+ return QVariant::fromValue(qdesigner_internal::PropertySheetStringValue());
+ return QVariant(QString());
+ }
+
+ // index-dependent
+ switch (toolBoxProperty) {
+ case PropertyCurrentItemText:
+ return QVariant::fromValue(m_pageToData.value(currentWidget).text);
+ case PropertyCurrentItemName:
+ return currentWidget->objectName();
+ case PropertyCurrentItemIcon:
+ return QVariant::fromValue(m_pageToData.value(currentWidget).icon);
+ case PropertyCurrentItemToolTip:
+ return QVariant::fromValue(m_pageToData.value(currentWidget).tooltip);
+ case PropertyTabSpacing:
+ case PropertyToolBoxNone:
+ break;
+ }
+ return QVariant();
+}
+
+bool QToolBoxWidgetPropertySheet::reset(int index)
+{
+ const ToolBoxProperty toolBoxProperty = toolBoxPropertyFromName(propertyName(index));
+ // independent of index
+ switch (toolBoxProperty) {
+ case PropertyTabSpacing:
+ setProperty(index, QVariant(tabSpacingDefault));
+ return true;
+ case PropertyToolBoxNone:
+ return QDesignerPropertySheet::reset(index);
+ default:
+ break;
+ }
+ // index-dependent
+ QWidget *currentWidget = m_toolBox->currentWidget();
+ if (!currentWidget)
+ return false;
+
+ // index-dependent
+ switch (toolBoxProperty) {
+ case PropertyCurrentItemName:
+ setProperty(index, QString());
+ break;
+ case PropertyCurrentItemToolTip:
+ m_pageToData[currentWidget].tooltip = qdesigner_internal::PropertySheetStringValue();
+ setProperty(index, QString());
+ break;
+ case PropertyCurrentItemText:
+ m_pageToData[currentWidget].text = qdesigner_internal::PropertySheetStringValue();
+ setProperty(index, QString());
+ break;
+ case PropertyCurrentItemIcon:
+ m_pageToData[currentWidget].icon = qdesigner_internal::PropertySheetIconValue();
+ setProperty(index, QIcon());
+ break;
+ case PropertyTabSpacing:
+ case PropertyToolBoxNone:
+ break;
+ }
+ return true;
+}
+
+bool QToolBoxWidgetPropertySheet::checkProperty(const QString &propertyName)
+{
+ switch (toolBoxPropertyFromName(propertyName)) {
+ case PropertyCurrentItemText:
+ case PropertyCurrentItemName:
+ case PropertyCurrentItemToolTip:
+ case PropertyCurrentItemIcon:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_toolbox_p.h b/src/designer/src/lib/shared/qdesigner_toolbox_p.h
new file mode 100644
index 000000000..f9d390ed0
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_toolbox_p.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_TOOLBOX_H
+#define QDESIGNER_TOOLBOX_H
+
+#include "shared_global_p.h"
+#include "qdesigner_propertysheet_p.h"
+#include "qdesigner_utils_p.h"
+#include <QtGui/QPalette>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ class PromotionTaskMenu;
+}
+
+class QToolBox;
+
+class QAction;
+class QMenu;
+
+class QDESIGNER_SHARED_EXPORT QToolBoxHelper : public QObject
+{
+ Q_OBJECT
+
+ explicit QToolBoxHelper(QToolBox *toolbox);
+public:
+ // Install helper on QToolBox
+ static void install(QToolBox *toolbox);
+ static QToolBoxHelper *helperOf(const QToolBox *toolbox);
+ // Convenience to add a menu on a toolbox
+ static QMenu *addToolBoxContextMenuActions(const QToolBox *toolbox, QMenu *popup);
+
+ QPalette::ColorRole currentItemBackgroundRole() const;
+ void setCurrentItemBackgroundRole(QPalette::ColorRole role);
+
+ bool eventFilter(QObject *watched, QEvent *event);
+ // Add context menu and return page submenu or 0.
+
+ QMenu *addContextMenuActions(QMenu *popup) const;
+
+private slots:
+ void removeCurrentPage();
+ void addPage();
+ void addPageAfter();
+ void changeOrder();
+
+private:
+ QToolBox *m_toolbox;
+ QAction *m_actionDeletePage;
+ QAction *m_actionInsertPage;
+ QAction *m_actionInsertPageAfter;
+ QAction *m_actionChangePageOrder;
+ qdesigner_internal::PromotionTaskMenu* m_pagePromotionTaskMenu;
+};
+
+// PropertySheet to handle the page properties
+class QDESIGNER_SHARED_EXPORT QToolBoxWidgetPropertySheet : public QDesignerPropertySheet {
+public:
+ explicit QToolBoxWidgetPropertySheet(QToolBox *object, QObject *parent = 0);
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual QVariant property(int index) const;
+ virtual bool reset(int index);
+ virtual bool isEnabled(int index) const;
+
+ // Check whether the property is to be saved. Returns false for the page
+ // properties (as the property sheet has no concept of 'stored')
+ static bool checkProperty(const QString &propertyName);
+
+private:
+ enum ToolBoxProperty { PropertyCurrentItemText, PropertyCurrentItemName, PropertyCurrentItemIcon,
+ PropertyCurrentItemToolTip, PropertyTabSpacing, PropertyToolBoxNone };
+
+ static ToolBoxProperty toolBoxPropertyFromName(const QString &name);
+ QToolBox *m_toolBox;
+ struct PageData
+ {
+ qdesigner_internal::PropertySheetStringValue text;
+ qdesigner_internal::PropertySheetStringValue tooltip;
+ qdesigner_internal::PropertySheetIconValue icon;
+ };
+ QMap<QWidget *, PageData> m_pageToData;
+};
+
+typedef QDesignerPropertySheetFactory<QToolBox, QToolBoxWidgetPropertySheet> QToolBoxWidgetPropertySheetFactory;
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_TOOLBOX_H
diff --git a/src/designer/src/lib/shared/qdesigner_utils.cpp b/src/designer/src/lib/shared/qdesigner_utils.cpp
new file mode 100644
index 000000000..1c6c8547c
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_utils.cpp
@@ -0,0 +1,848 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_utils_p.h"
+#include "qdesigner_propertycommand_p.h"
+#include "abstractformbuilder.h"
+#include "formwindowbase_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/QDesignerResourceBrowserInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QDir>
+#include <QtCore/QProcess>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDebug>
+#include <QtCore/QQueue>
+#include <QtCore/QSharedData>
+
+#include <QtGui/QApplication>
+#include <QtGui/QIcon>
+#include <QtGui/QPixmap>
+#include <QtGui/QListWidget>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QTableWidget>
+#include <QtGui/QComboBox>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal
+{
+ QDESIGNER_SHARED_EXPORT void designerWarning(const QString &message)
+ {
+ qWarning("Designer: %s", qPrintable(message));
+ }
+
+ void reloadTreeItem(DesignerIconCache *iconCache, QTreeWidgetItem *item)
+ {
+ if (!item)
+ return;
+
+ for (int c = 0; c < item->columnCount(); c++) {
+ const QVariant v = item->data(c, Qt::DecorationPropertyRole);
+ if (v.canConvert<PropertySheetIconValue>())
+ item->setIcon(c, iconCache->icon(qvariant_cast<PropertySheetIconValue>(v)));
+ }
+ }
+
+ void reloadListItem(DesignerIconCache *iconCache, QListWidgetItem *item)
+ {
+ if (!item)
+ return;
+
+ const QVariant v = item->data(Qt::DecorationPropertyRole);
+ if (v.canConvert<PropertySheetIconValue>())
+ item->setIcon(iconCache->icon(qvariant_cast<PropertySheetIconValue>(v)));
+ }
+
+ void reloadTableItem(DesignerIconCache *iconCache, QTableWidgetItem *item)
+ {
+ if (!item)
+ return;
+
+ const QVariant v = item->data(Qt::DecorationPropertyRole);
+ if (v.canConvert<PropertySheetIconValue>())
+ item->setIcon(iconCache->icon(qvariant_cast<PropertySheetIconValue>(v)));
+ }
+
+ void reloadIconResources(DesignerIconCache *iconCache, QObject *object)
+ {
+ if (QListWidget *listWidget = qobject_cast<QListWidget *>(object)) {
+ for (int i = 0; i < listWidget->count(); i++)
+ reloadListItem(iconCache, listWidget->item(i));
+ } else if (QComboBox *comboBox = qobject_cast<QComboBox *>(object)) {
+ for (int i = 0; i < comboBox->count(); i++) {
+ const QVariant v = comboBox->itemData(i, Qt::DecorationPropertyRole);
+ if (v.canConvert<PropertySheetIconValue>()) {
+ QIcon icon = iconCache->icon(qvariant_cast<PropertySheetIconValue>(v));
+ comboBox->setItemIcon(i, icon);
+ comboBox->setItemData(i, icon);
+ }
+ }
+ } else if (QTreeWidget *treeWidget = qobject_cast<QTreeWidget *>(object)) {
+ reloadTreeItem(iconCache, treeWidget->headerItem());
+ QQueue<QTreeWidgetItem *> itemsQueue;
+ for (int i = 0; i < treeWidget->topLevelItemCount(); i++)
+ itemsQueue.enqueue(treeWidget->topLevelItem(i));
+ while (!itemsQueue.isEmpty()) {
+ QTreeWidgetItem *item = itemsQueue.dequeue();
+ for (int i = 0; i < item->childCount(); i++)
+ itemsQueue.enqueue(item->child(i));
+ reloadTreeItem(iconCache, item);
+ }
+ } else if (QTableWidget *tableWidget = qobject_cast<QTableWidget *>(object)) {
+ const int columnCount = tableWidget->columnCount();
+ const int rowCount = tableWidget->rowCount();
+ for (int c = 0; c < columnCount; c++)
+ reloadTableItem(iconCache, tableWidget->horizontalHeaderItem(c));
+ for (int r = 0; r < rowCount; r++)
+ reloadTableItem(iconCache, tableWidget->verticalHeaderItem(r));
+ for (int c = 0; c < columnCount; c++)
+ for (int r = 0; r < rowCount; r++)
+ reloadTableItem(iconCache, tableWidget->item(r, c));
+ }
+ }
+
+ // ------------- DesignerMetaEnum
+ DesignerMetaEnum::DesignerMetaEnum(const QString &name, const QString &scope, const QString &separator) :
+ MetaEnum<int>(name, scope, separator)
+ {
+ }
+
+
+ QString DesignerMetaEnum::toString(int value, SerializationMode sm, bool *ok) const
+ {
+ // find value
+ bool valueOk;
+ const QString item = valueToKey(value, &valueOk);
+ if (ok)
+ *ok = valueOk;
+
+ if (!valueOk || sm == NameOnly)
+ return item;
+
+ QString qualifiedItem;
+ appendQualifiedName(item, qualifiedItem);
+ return qualifiedItem;
+ }
+
+ QString DesignerMetaEnum::messageToStringFailed(int value) const
+ {
+ return QCoreApplication::translate("DesignerMetaEnum", "%1 is not a valid enumeration value of '%2'.").arg(value).arg(name());
+ }
+
+ QString DesignerMetaEnum::messageParseFailed(const QString &s) const
+ {
+ return QCoreApplication::translate("DesignerMetaEnum", "'%1' could not be converted to an enumeration value of type '%2'.").arg(s).arg(name());
+ }
+ // -------------- DesignerMetaFlags
+ DesignerMetaFlags::DesignerMetaFlags(const QString &name, const QString &scope, const QString &separator) :
+ MetaEnum<uint>(name, scope, separator)
+ {
+ }
+
+ QStringList DesignerMetaFlags::flags(int ivalue) const
+ {
+ typedef MetaEnum<uint>::KeyToValueMap::const_iterator KeyToValueMapIterator;
+ QStringList rc;
+ const uint v = static_cast<uint>(ivalue);
+ const KeyToValueMapIterator cend = keyToValueMap().constEnd();
+ for (KeyToValueMapIterator it = keyToValueMap().constBegin();it != cend; ++it ) {
+ const uint itemValue = it.value();
+ // Check for equality first as flag values can be 0 or -1, too. Takes preference over a bitwise flag
+ if (v == itemValue) {
+ rc.clear();
+ rc.push_back(it.key());
+ return rc;
+ }
+ // Do not add 0-flags (None-flags)
+ if (itemValue)
+ if ((v & itemValue) == itemValue)
+ rc.push_back(it.key());
+ }
+ return rc;
+ }
+
+
+ QString DesignerMetaFlags::toString(int value, SerializationMode sm) const
+ {
+ const QStringList flagIds = flags(value);
+ if (flagIds.empty())
+ return QString();
+
+ const QChar delimiter = QLatin1Char('|');
+ QString rc;
+ const QStringList::const_iterator cend = flagIds.constEnd();
+ for (QStringList::const_iterator it = flagIds.constBegin(); it != cend; ++it) {
+ if (!rc.isEmpty())
+ rc += delimiter ;
+ if (sm == FullyQualified)
+ appendQualifiedName(*it, rc);
+ else
+ rc += *it;
+ }
+ return rc;
+ }
+
+
+ int DesignerMetaFlags::parseFlags(const QString &s, bool *ok) const
+ {
+ if (s.isEmpty()) {
+ if (ok)
+ *ok = true;
+ return 0;
+ }
+ uint flags = 0;
+ bool valueOk = true;
+ QStringList keys = s.split(QString(QLatin1Char('|')));
+ const QStringList::iterator cend = keys.end();
+ for (QStringList::iterator it = keys.begin(); it != cend; ++it) {
+ const uint flagValue = keyToValue(*it, &valueOk);
+ if (!valueOk) {
+ flags = 0;
+ break;
+ }
+ flags |= flagValue;
+ }
+ if (ok)
+ *ok = valueOk;
+ return static_cast<int>(flags);
+ }
+
+ QString DesignerMetaFlags::messageParseFailed(const QString &s) const
+ {
+ return QCoreApplication::translate("DesignerMetaFlags", "'%1' could not be converted to a flag value of type '%2'.").arg(s).arg(name());
+ }
+
+ // ---------- PropertySheetEnumValue
+
+ PropertySheetEnumValue::PropertySheetEnumValue(int v, const DesignerMetaEnum &me) :
+ value(v),
+ metaEnum(me)
+ {
+ }
+ PropertySheetEnumValue::PropertySheetEnumValue() :
+ value(0)
+ {
+ }
+
+ // ---------------- PropertySheetFlagValue
+ PropertySheetFlagValue::PropertySheetFlagValue(int v, const DesignerMetaFlags &mf) :
+ value(v),
+ metaFlags(mf)
+ {
+ }
+
+ PropertySheetFlagValue::PropertySheetFlagValue() :
+ value(0)
+ {
+ }
+
+ // ---------------- PropertySheetPixmapValue
+ PropertySheetPixmapValue::PropertySheetPixmapValue(const QString &path) : m_path(path)
+ {
+ }
+
+ PropertySheetPixmapValue::PropertySheetPixmapValue()
+ {
+ }
+
+ PropertySheetPixmapValue::PixmapSource PropertySheetPixmapValue::getPixmapSource(QDesignerFormEditorInterface *core, const QString & path)
+ {
+ if (const QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core))
+ return lang->isLanguageResource(path) ? LanguageResourcePixmap : FilePixmap;
+ return path.startsWith(QLatin1Char(':')) ? ResourcePixmap : FilePixmap;
+ }
+
+ int PropertySheetPixmapValue::compare(const PropertySheetPixmapValue &other) const
+ {
+ return m_path.compare(other.m_path);
+ }
+
+ QString PropertySheetPixmapValue::path() const
+ {
+ return m_path;
+ }
+
+ void PropertySheetPixmapValue::setPath(const QString &path)
+ {
+ if (m_path == path)
+ return;
+ m_path = path;
+ }
+
+ // ---------- PropertySheetIconValue
+
+ class PropertySheetIconValueData : public QSharedData {
+ public:
+ PropertySheetIconValue::ModeStateToPixmapMap m_paths;
+ QString m_theme;
+ };
+
+ PropertySheetIconValue::PropertySheetIconValue(const PropertySheetPixmapValue &pixmap) :
+ m_data(new PropertySheetIconValueData)
+ {
+ setPixmap(QIcon::Normal, QIcon::Off, pixmap);
+ }
+
+ PropertySheetIconValue::PropertySheetIconValue() :
+ m_data(new PropertySheetIconValueData)
+ {
+ }
+
+ PropertySheetIconValue::~PropertySheetIconValue()
+ {
+ }
+
+ PropertySheetIconValue::PropertySheetIconValue(const PropertySheetIconValue &rhs) :
+ m_data(rhs.m_data)
+ {
+ }
+
+ PropertySheetIconValue &PropertySheetIconValue::operator=(const PropertySheetIconValue &rhs)
+ {
+ if (this != &rhs)
+ m_data.operator=(rhs.m_data);
+ return *this;
+ }
+
+ bool PropertySheetIconValue::equals(const PropertySheetIconValue &rhs) const
+ {
+ return m_data->m_theme == rhs.m_data->m_theme && m_data->m_paths == rhs.m_data->m_paths;
+ }
+
+ bool PropertySheetIconValue::operator<(const PropertySheetIconValue &other) const
+ {
+ if (const int themeCmp = m_data->m_theme.compare(other.m_data->m_theme))
+ return themeCmp < 0;
+ QMapIterator<ModeStateKey, PropertySheetPixmapValue> itThis(m_data->m_paths);
+ QMapIterator<ModeStateKey, PropertySheetPixmapValue> itOther(other.m_data->m_paths);
+ while (itThis.hasNext() && itOther.hasNext()) {
+ const ModeStateKey thisPair = itThis.next().key();
+ const ModeStateKey otherPair = itOther.next().key();
+ if (thisPair < otherPair)
+ return true;
+ else if (otherPair < thisPair)
+ return false;
+ const int crc = itThis.value().compare(itOther.value());
+ if (crc < 0)
+ return true;
+ if (crc > 0)
+ return false;
+ }
+ if (itOther.hasNext())
+ return true;
+ return false;
+ }
+
+ bool PropertySheetIconValue::isEmpty() const
+ {
+ return m_data->m_theme.isEmpty() && m_data->m_paths.isEmpty();
+ }
+
+ QString PropertySheetIconValue::theme() const
+ {
+ return m_data->m_theme;
+ }
+
+ void PropertySheetIconValue::setTheme(const QString &t)
+ {
+ m_data->m_theme = t;
+ }
+
+ PropertySheetPixmapValue PropertySheetIconValue::pixmap(QIcon::Mode mode, QIcon::State state) const
+ {
+ const ModeStateKey pair = qMakePair(mode, state);
+ return m_data->m_paths.value(pair);
+ }
+
+ void PropertySheetIconValue::setPixmap(QIcon::Mode mode, QIcon::State state, const PropertySheetPixmapValue &pixmap)
+ {
+ const ModeStateKey pair = qMakePair(mode, state);
+ if (pixmap.path().isEmpty())
+ m_data->m_paths.remove(pair);
+ else
+ m_data->m_paths.insert(pair, pixmap);
+ }
+
+ QPixmap DesignerPixmapCache::pixmap(const PropertySheetPixmapValue &value) const
+ {
+ QMap<PropertySheetPixmapValue, QPixmap>::const_iterator it = m_cache.constFind(value);
+ if (it != m_cache.constEnd())
+ return it.value();
+
+ QPixmap pix = QPixmap(value.path());
+ m_cache.insert(value, pix);
+ return pix;
+ }
+
+ void DesignerPixmapCache::clear()
+ {
+ m_cache.clear();
+ }
+
+ DesignerPixmapCache::DesignerPixmapCache(QObject *parent)
+ : QObject(parent)
+ {
+ }
+
+ QIcon DesignerIconCache::icon(const PropertySheetIconValue &value) const
+ {
+ typedef PropertySheetIconValue::ModeStateToPixmapMap::const_iterator ModeStateToPixmapMapConstIt;
+
+ QMap<PropertySheetIconValue, QIcon>::const_iterator it = m_cache.constFind(value);
+ if (it != m_cache.constEnd())
+ return it.value();
+
+ // Match on the theme first if it is available.
+ if (!value.theme().isEmpty()) {
+ const QString theme = value.theme();
+ if (QIcon::hasThemeIcon(theme)) {
+ const QIcon themeIcon = QIcon::fromTheme(theme);
+ m_cache.insert(value, themeIcon);
+ return themeIcon;
+ }
+ }
+
+ QIcon icon;
+ const PropertySheetIconValue::ModeStateToPixmapMap &paths = value.paths();
+ const ModeStateToPixmapMapConstIt cend = paths.constEnd();
+ for (ModeStateToPixmapMapConstIt it = paths.constBegin(); it != cend; ++it) {
+ const QPair<QIcon::Mode, QIcon::State> pair = it.key();
+ icon.addFile(it.value().path(), QSize(), pair.first, pair.second);
+ }
+ m_cache.insert(value, icon);
+ return icon;
+ }
+
+ void DesignerIconCache::clear()
+ {
+ m_cache.clear();
+ }
+
+ DesignerIconCache::DesignerIconCache(DesignerPixmapCache *pixmapCache, QObject *parent)
+ : QObject(parent),
+ m_pixmapCache(pixmapCache)
+ {
+
+ }
+
+ PropertySheetStringValue::PropertySheetStringValue(const QString &value,
+ bool translatable, const QString &disambiguation, const QString &comment)
+ : m_value(value), m_translatable(translatable), m_disambiguation(disambiguation), m_comment(comment)
+ { }
+
+ QString PropertySheetStringValue::value() const
+ {
+ return m_value;
+ }
+
+ void PropertySheetStringValue::setValue(const QString &value)
+ {
+ m_value = value;
+ }
+
+ bool PropertySheetStringValue::translatable() const
+ {
+ return m_translatable;
+ }
+
+ void PropertySheetStringValue::setTranslatable(bool translatable)
+ {
+ m_translatable = translatable;
+ }
+
+ QString PropertySheetStringValue::disambiguation() const
+ {
+ return m_disambiguation;
+ }
+
+ void PropertySheetStringValue::setDisambiguation(const QString &disambiguation)
+ {
+ m_disambiguation = disambiguation;
+ }
+
+ QString PropertySheetStringValue::comment() const
+ {
+ return m_comment;
+ }
+
+ void PropertySheetStringValue::setComment(const QString &comment)
+ {
+ m_comment = comment;
+ }
+
+ bool PropertySheetStringValue::equals(const PropertySheetStringValue &rhs) const
+ {
+ return (m_value == rhs.m_value) && (m_translatable == rhs.m_translatable)
+ && (m_disambiguation == rhs.m_disambiguation) && (m_comment == rhs.m_comment);
+ }
+
+ PropertySheetKeySequenceValue::PropertySheetKeySequenceValue(const QKeySequence &value,
+ bool translatable, const QString &disambiguation, const QString &comment)
+ : m_value(value),
+ m_standardKey(QKeySequence::UnknownKey),
+ m_translatable(translatable),
+ m_disambiguation(disambiguation),
+ m_comment(comment)
+ { }
+
+ PropertySheetKeySequenceValue::PropertySheetKeySequenceValue(const QKeySequence::StandardKey &standardKey,
+ bool translatable, const QString &disambiguation, const QString &comment)
+ : m_value(QKeySequence(standardKey)),
+ m_standardKey(standardKey),
+ m_translatable(translatable),
+ m_disambiguation(disambiguation),
+ m_comment(comment)
+ { }
+
+ QKeySequence PropertySheetKeySequenceValue::value() const
+ {
+ return m_value;
+ }
+
+ void PropertySheetKeySequenceValue::setValue(const QKeySequence &value)
+ {
+ m_value = value;
+ m_standardKey = QKeySequence::UnknownKey;
+ }
+
+ QKeySequence::StandardKey PropertySheetKeySequenceValue::standardKey() const
+ {
+ return m_standardKey;
+ }
+
+ void PropertySheetKeySequenceValue::setStandardKey(const QKeySequence::StandardKey &standardKey)
+ {
+ m_value = QKeySequence(standardKey);
+ m_standardKey = standardKey;
+ }
+
+ bool PropertySheetKeySequenceValue::isStandardKey() const
+ {
+ return m_standardKey != QKeySequence::UnknownKey;
+ }
+
+ QString PropertySheetKeySequenceValue::comment() const
+ {
+ return m_comment;
+ }
+
+ void PropertySheetKeySequenceValue::setComment(const QString &comment)
+ {
+ m_comment = comment;
+ }
+
+ QString PropertySheetKeySequenceValue::disambiguation() const
+ {
+ return m_disambiguation;
+ }
+
+ void PropertySheetKeySequenceValue::setDisambiguation(const QString &disambiguation)
+ {
+ m_disambiguation = disambiguation;
+ }
+
+ bool PropertySheetKeySequenceValue::translatable() const
+ {
+ return m_translatable;
+ }
+
+ void PropertySheetKeySequenceValue::setTranslatable(bool translatable)
+ {
+ m_translatable = translatable;
+ }
+
+ bool PropertySheetKeySequenceValue::equals(const PropertySheetKeySequenceValue &rhs) const
+ {
+ return (m_value == rhs.m_value) && (m_standardKey == rhs.m_standardKey)
+ && (m_translatable == rhs.m_translatable) && (m_disambiguation == rhs.m_disambiguation) && (m_comment == rhs.m_comment);
+ }
+
+
+ /* IconSubPropertyMask: Assign each icon sub-property (pixmaps for the
+ * various states/modes and the theme) a flag bit (see QFont) so that they
+ * can be handled individually when assigning property values to
+ * multiselections in the set-property-commands (that is, do not clobber
+ * other subproperties when assigning just one).
+ * Provide back-and-forth mapping functions for the icon states. */
+
+ enum IconSubPropertyMask {
+ NormalOffIconMask = 0x01,
+ NormalOnIconMask = 0x02,
+ DisabledOffIconMask = 0x04,
+ DisabledOnIconMask = 0x08,
+ ActiveOffIconMask = 0x10,
+ ActiveOnIconMask = 0x20,
+ SelectedOffIconMask = 0x40,
+ SelectedOnIconMask = 0x80,
+ ThemeIconMask = 0x10000
+ };
+
+ static inline uint iconStateToSubPropertyFlag(QIcon::Mode mode, QIcon::State state)
+ {
+ switch (mode) {
+ case QIcon::Disabled:
+ return state == QIcon::On ? DisabledOnIconMask : DisabledOffIconMask;
+ case QIcon::Active:
+ return state == QIcon::On ? ActiveOnIconMask : ActiveOffIconMask;
+ case QIcon::Selected:
+ return state == QIcon::On ? SelectedOnIconMask : SelectedOffIconMask;
+ case QIcon::Normal:
+ break;
+ }
+ return state == QIcon::On ? NormalOnIconMask : NormalOffIconMask;
+ }
+
+ static inline QPair<QIcon::Mode, QIcon::State> subPropertyFlagToIconModeState(unsigned flag)
+ {
+ switch (flag) {
+ case NormalOnIconMask:
+ return qMakePair(QIcon::Normal, QIcon::On);
+ case DisabledOffIconMask:
+ return qMakePair(QIcon::Disabled, QIcon::Off);
+ case DisabledOnIconMask:
+ return qMakePair(QIcon::Disabled, QIcon::On);
+ case ActiveOffIconMask:
+ return qMakePair(QIcon::Active, QIcon::Off);
+ case ActiveOnIconMask:
+ return qMakePair(QIcon::Active, QIcon::On);
+ case SelectedOffIconMask:
+ return qMakePair(QIcon::Selected, QIcon::Off);
+ case SelectedOnIconMask:
+ return qMakePair(QIcon::Selected, QIcon::On);
+ case NormalOffIconMask:
+ default:
+ break;
+ }
+ return qMakePair(QIcon::Normal, QIcon::Off);
+ }
+
+ uint PropertySheetIconValue::mask() const
+ {
+ typedef ModeStateToPixmapMap::const_iterator ModeStateToPixmapMapConstIt;
+
+ uint flags = 0;
+ const ModeStateToPixmapMapConstIt cend = m_data->m_paths.constEnd();
+ for (ModeStateToPixmapMapConstIt it = m_data->m_paths.constBegin(); it != cend; ++it)
+ flags |= iconStateToSubPropertyFlag(it.key().first, it.key().second);
+ if (!m_data->m_theme.isEmpty())
+ flags |= ThemeIconMask;
+ return flags;
+ }
+
+ uint PropertySheetIconValue::compare(const PropertySheetIconValue &other) const
+ {
+ uint diffMask = mask() | other.mask();
+ for (int i = 0; i < 8; i++) {
+ const uint flag = 1 << i;
+ if (diffMask & flag) { // if state is set in both icons, compare the values
+ const QPair<QIcon::Mode, QIcon::State> state = subPropertyFlagToIconModeState(flag);
+ if (pixmap(state.first, state.second) == other.pixmap(state.first, state.second))
+ diffMask &= ~flag;
+ }
+ }
+ if ((diffMask & ThemeIconMask) && theme() == other.theme())
+ diffMask &= ~ThemeIconMask;
+ return diffMask;
+ }
+
+ PropertySheetIconValue PropertySheetIconValue::themed() const
+ {
+ PropertySheetIconValue rc(*this);
+ rc.m_data->m_paths.clear();
+ return rc;
+ }
+
+ PropertySheetIconValue PropertySheetIconValue::unthemed() const
+ {
+ PropertySheetIconValue rc(*this);
+ rc.m_data->m_theme.clear();
+ return rc;
+ }
+
+ void PropertySheetIconValue::assign(const PropertySheetIconValue &other, uint mask)
+ {
+ for (int i = 0; i < 8; i++) {
+ uint flag = 1 << i;
+ if (mask & flag) {
+ const ModeStateKey state = subPropertyFlagToIconModeState(flag);
+ setPixmap(state.first, state.second, other.pixmap(state.first, state.second));
+ }
+ }
+ if (mask & ThemeIconMask)
+ setTheme(other.theme());
+ }
+
+ const PropertySheetIconValue::ModeStateToPixmapMap &PropertySheetIconValue::paths() const
+ {
+ return m_data->m_paths;
+ }
+
+ QDESIGNER_SHARED_EXPORT QDebug operator<<(QDebug d, const PropertySheetIconValue &p)
+ {
+ typedef PropertySheetIconValue::ModeStateToPixmapMap::const_iterator ModeStateToPixmapMapConstIt;
+
+ QDebug nospace = d.nospace();
+ nospace << "PropertySheetIconValue theme='" << p.theme() << "' ";
+
+ const PropertySheetIconValue::ModeStateToPixmapMap &paths = p.paths();
+ const ModeStateToPixmapMapConstIt cend = paths.constEnd();
+ for (ModeStateToPixmapMapConstIt it = paths.constBegin(); it != cend; ++it)
+ nospace << " mode=" << it.key().first << ",state=" << it.key().second
+ << ",'" << it.value().path() << '\'';
+ nospace << " mask=0x" << QString::number(p.mask(), 16);
+ return d;
+ }
+
+ QDESIGNER_SHARED_EXPORT QDesignerFormWindowCommand *createTextPropertyCommand(const QString &propertyName, const QString &text, QObject *object, QDesignerFormWindowInterface *fw)
+ {
+ if (text.isEmpty()) {
+ ResetPropertyCommand *cmd = new ResetPropertyCommand(fw);
+ cmd->init(object, propertyName);
+ return cmd;
+ }
+ SetPropertyCommand *cmd = new SetPropertyCommand(fw);
+ cmd->init(object, propertyName, text);
+ return cmd;
+ }
+
+ QDESIGNER_SHARED_EXPORT QAction *preferredEditAction(QDesignerFormEditorInterface *core, QWidget *managedWidget)
+ {
+ QAction *action = 0;
+ if (const QDesignerTaskMenuExtension *taskMenu = qt_extension<QDesignerTaskMenuExtension*>(core->extensionManager(), managedWidget)) {
+ action = taskMenu->preferredEditAction();
+ if (!action) {
+ const QList<QAction *> actions = taskMenu->taskActions();
+ if (!actions.isEmpty())
+ action = actions.first();
+ }
+ }
+ if (!action) {
+ if (const QDesignerTaskMenuExtension *taskMenu = qobject_cast<QDesignerTaskMenuExtension *>(
+ core->extensionManager()->extension(managedWidget, QLatin1String("QDesignerInternalTaskMenuExtension")))) {
+ action = taskMenu->preferredEditAction();
+ if (!action) {
+ const QList<QAction *> actions = taskMenu->taskActions();
+ if (!actions.isEmpty())
+ action = actions.first();
+ }
+ }
+ }
+ return action;
+ }
+
+ QDESIGNER_SHARED_EXPORT bool runUIC(const QString &fileName, UIC_Mode mode, QByteArray& ba, QString &errorMessage)
+ {
+ QStringList argv;
+ QString binary = QLibraryInfo::location(QLibraryInfo::BinariesPath);
+ binary += QDir::separator();
+ switch (mode) {
+ case UIC_GenerateCode:
+ binary += QLatin1String("uic");
+ break;
+ case UIC_ConvertV3:
+ binary += QLatin1String("uic3");
+ argv += QLatin1String("-convert");
+ break;
+ }
+ argv += fileName;
+ QProcess uic;
+ uic.start(binary, argv);
+ if (!uic.waitForStarted()) {
+ errorMessage = QApplication::translate("Designer", "Unable to launch %1.").arg(binary);
+ return false;
+ }
+ if (!uic.waitForFinished()) {
+ errorMessage = QApplication::translate("Designer", "%1 timed out.").arg(binary);
+ return false;
+ }
+ if (uic.exitCode()) {
+ errorMessage = QString::fromAscii(uic.readAllStandardError());
+ return false;
+ }
+ ba = uic.readAllStandardOutput();
+ return true;
+ }
+
+ QDESIGNER_SHARED_EXPORT QString qtify(const QString &name)
+ {
+ QString qname = name;
+
+ Q_ASSERT(qname.isEmpty() == false);
+
+
+ if (qname.count() > 1 && qname.at(1).isUpper()) {
+ const QChar first = qname.at(0);
+ if (first == QLatin1Char('Q') || first == QLatin1Char('K'))
+ qname.remove(0, 1);
+ }
+
+ const int len = qname.count();
+ for (int i = 0; i < len && qname.at(i).isUpper(); i++)
+ qname[i] = qname.at(i).toLower();
+
+ return qname;
+ }
+
+ // --------------- UpdateBlocker
+ UpdateBlocker::UpdateBlocker(QWidget *w) :
+ m_widget(w),
+ m_enabled(w->updatesEnabled() && w->isVisible())
+ {
+ if (m_enabled)
+ m_widget->setUpdatesEnabled(false);
+ }
+
+ UpdateBlocker::~UpdateBlocker()
+ {
+ if (m_enabled)
+ m_widget->setUpdatesEnabled(true);
+ }
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_utils_p.h b/src/designer/src/lib/shared/qdesigner_utils_p.h
new file mode 100644
index 000000000..1e48cf8db
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_utils_p.h
@@ -0,0 +1,499 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_UTILS_H
+#define QDESIGNER_UTILS_H
+
+#include "shared_global_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtCore/QVariant>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QMap>
+#include <QtGui/QMainWindow>
+#include <QtGui/QIcon>
+#include <QtGui/QPixmap>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+
+namespace qdesigner_internal {
+class QDesignerFormWindowCommand;
+class DesignerIconCache;
+class FormWindowBase;
+
+
+QDESIGNER_SHARED_EXPORT void designerWarning(const QString &message);
+
+QDESIGNER_SHARED_EXPORT void reloadIconResources(DesignerIconCache *iconCache, QObject *object);
+
+/* Flag/Enumeration helpers for the property sheet: Enumeration or flag values are returned by the property sheet
+ * as a pair of meta type and integer value.
+ * The meta type carries all the information required for the property editor and serialization
+ * by the form builders (names, etc).
+ * Note that the property editor uses unqualified names ("Cancel") while the form builder serialization (uic)
+ * requires the whole string
+ * ("QDialogButtonBox::Cancel" or "com.trolltech.qt.gui.QDialogButtonBox.StandardButton.Cancel").*/
+
+/* --------- MetaEnum: Base class representing a QMetaEnum with lookup functions
+ * in both ways. Template of int type since unsigned is more suitable for flags.
+ * The keyToValue() is ignorant of scopes, it can handle fully qualified or unqualified names. */
+
+template <class IntType>
+class MetaEnum
+{
+public:
+ typedef QMap<QString, IntType> KeyToValueMap;
+
+ MetaEnum(const QString &name, const QString &scope, const QString &separator);
+ MetaEnum() {}
+ void addKey(IntType value, const QString &name);
+
+ QString valueToKey(IntType value, bool *ok = 0) const;
+ // Ignorant of scopes.
+ IntType keyToValue(QString key, bool *ok = 0) const;
+
+ const QString &name() const { return m_name; }
+ const QString &scope() const { return m_scope; }
+ const QString &separator() const { return m_separator; }
+
+ const QStringList &keys() const { return m_keys; }
+ const KeyToValueMap &keyToValueMap() const { return m_keyToValueMap; }
+
+protected:
+ void appendQualifiedName(const QString &key, QString &target) const;
+
+private:
+ QString m_name;
+ QString m_scope;
+ QString m_separator;
+ KeyToValueMap m_keyToValueMap;
+ QStringList m_keys;
+};
+
+template <class IntType>
+MetaEnum<IntType>::MetaEnum(const QString &name, const QString &scope, const QString &separator) :
+ m_name(name),
+ m_scope(scope),
+ m_separator(separator)
+{
+}
+
+template <class IntType>
+void MetaEnum<IntType>::addKey(IntType value, const QString &name)
+{
+ m_keyToValueMap.insert(name, value);
+ m_keys.append(name);
+}
+
+template <class IntType>
+QString MetaEnum<IntType>::valueToKey(IntType value, bool *ok) const
+{
+ const QString rc = m_keyToValueMap.key(value);
+ if (ok)
+ *ok = !rc.isEmpty();
+ return rc;
+}
+
+template <class IntType>
+IntType MetaEnum<IntType>::keyToValue(QString key, bool *ok) const
+{
+ if (!m_scope.isEmpty() && key.startsWith(m_scope))
+ key.remove(0, m_scope.size() + m_separator.size());
+ const Q_TYPENAME KeyToValueMap::const_iterator it = m_keyToValueMap.find(key);
+ const bool found = it != m_keyToValueMap.constEnd();
+ if (ok)
+ *ok = found;
+ return found ? it.value() : IntType(0);
+}
+
+template <class IntType>
+void MetaEnum<IntType>::appendQualifiedName(const QString &key, QString &target) const
+{
+ if (!m_scope.isEmpty()) {
+ target += m_scope;
+ target += m_separator;
+ }
+ target += key;
+}
+
+// -------------- DesignerMetaEnum: Meta type for enumerations
+
+class QDESIGNER_SHARED_EXPORT DesignerMetaEnum : public MetaEnum<int>
+{
+public:
+ DesignerMetaEnum(const QString &name, const QString &scope, const QString &separator);
+ DesignerMetaEnum() {}
+
+ enum SerializationMode { FullyQualified, NameOnly };
+ QString toString(int value, SerializationMode sm, bool *ok = 0) const;
+
+ QString messageToStringFailed(int value) const;
+ QString messageParseFailed(const QString &s) const;
+
+ // parse a string (ignorant of scopes)
+ int parseEnum(const QString &s, bool *ok = 0) const { return keyToValue(s, ok); }
+};
+
+// -------------- DesignerMetaFlags: Meta type for flags.
+// Note that while the handling of flags is done using unsigned integers, the actual values returned
+// by the property system are integers.
+
+class QDESIGNER_SHARED_EXPORT DesignerMetaFlags : public MetaEnum<uint>
+{
+public:
+ DesignerMetaFlags(const QString &name, const QString &scope, const QString &separator);
+ DesignerMetaFlags() {}
+
+ enum SerializationMode { FullyQualified, NameOnly };
+ QString toString(int value, SerializationMode sm) const;
+ QStringList flags(int value) const;
+
+ QString messageParseFailed(const QString &s) const;
+ // parse a string (ignorant of scopes)
+ int parseFlags(const QString &s, bool *ok = 0) const;
+};
+
+// -------------- EnumValue: Returned by the property sheet for enumerations
+
+struct QDESIGNER_SHARED_EXPORT PropertySheetEnumValue
+{
+ PropertySheetEnumValue(int v, const DesignerMetaEnum &me);
+ PropertySheetEnumValue();
+
+ int value;
+ DesignerMetaEnum metaEnum;
+};
+
+// -------------- FlagValue: Returned by the property sheet for flags
+
+struct QDESIGNER_SHARED_EXPORT PropertySheetFlagValue
+{
+ PropertySheetFlagValue(int v, const DesignerMetaFlags &mf);
+ PropertySheetFlagValue();
+
+ int value;
+ DesignerMetaFlags metaFlags;
+};
+
+// -------------- PixmapValue: Returned by the property sheet for pixmaps
+class QDESIGNER_SHARED_EXPORT PropertySheetPixmapValue
+{
+public:
+ PropertySheetPixmapValue(const QString &path);
+ PropertySheetPixmapValue();
+
+ bool operator==(const PropertySheetPixmapValue &other) const { return compare(other) == 0; }
+ bool operator!=(const PropertySheetPixmapValue &other) const { return compare(other) != 0; }
+ bool operator<(const PropertySheetPixmapValue &other) const { return compare(other) < 0; }
+
+ // Check where a pixmap comes from
+ enum PixmapSource { LanguageResourcePixmap , ResourcePixmap, FilePixmap };
+ static PixmapSource getPixmapSource(QDesignerFormEditorInterface *core, const QString & path);
+
+ PixmapSource pixmapSource(QDesignerFormEditorInterface *core) const { return getPixmapSource(core, m_path); }
+
+ QString path() const;
+ void setPath(const QString &path); // passing the empty path resets the pixmap
+
+ int compare(const PropertySheetPixmapValue &other) const;
+
+private:
+ QString m_path;
+};
+
+// -------------- IconValue: Returned by the property sheet for icons
+
+class PropertySheetIconValueData;
+
+class QDESIGNER_SHARED_EXPORT PropertySheetIconValue
+{
+ public:
+ PropertySheetIconValue(const PropertySheetPixmapValue &pixmap);
+ PropertySheetIconValue();
+ ~PropertySheetIconValue();
+ PropertySheetIconValue(const PropertySheetIconValue &);
+ PropertySheetIconValue &operator=(const PropertySheetIconValue &);
+
+ bool operator==(const PropertySheetIconValue &other) const { return equals(other); }
+ bool operator!=(const PropertySheetIconValue &other) const { return !equals(other); }
+ bool operator<(const PropertySheetIconValue &other) const;
+
+ bool isEmpty() const;
+
+ QString theme() const;
+ void setTheme(const QString &);
+
+ PropertySheetPixmapValue pixmap(QIcon::Mode mode, QIcon::State state) const;
+ void setPixmap(QIcon::Mode mode, QIcon::State state, const PropertySheetPixmapValue &path); // passing the empty path resets the pixmap
+
+ uint mask() const;
+ uint compare(const PropertySheetIconValue &other) const;
+ void assign(const PropertySheetIconValue &other, uint mask);
+
+ // Convenience accessors to get themed/unthemed icons.
+ PropertySheetIconValue themed() const;
+ PropertySheetIconValue unthemed() const;
+
+ typedef QPair<QIcon::Mode, QIcon::State> ModeStateKey;
+ typedef QMap<ModeStateKey, PropertySheetPixmapValue> ModeStateToPixmapMap;
+
+ const ModeStateToPixmapMap &paths() const;
+
+private:
+ bool equals(const PropertySheetIconValue &rhs) const;
+ QSharedDataPointer<PropertySheetIconValueData> m_data;
+};
+
+QDESIGNER_SHARED_EXPORT QDebug operator<<(QDebug, const PropertySheetIconValue &);
+
+class QDESIGNER_SHARED_EXPORT DesignerPixmapCache : public QObject
+{
+ Q_OBJECT
+public:
+ DesignerPixmapCache(QObject *parent = 0);
+ QPixmap pixmap(const PropertySheetPixmapValue &value) const;
+ void clear();
+signals:
+ void reloaded();
+private:
+ mutable QMap<PropertySheetPixmapValue, QPixmap> m_cache;
+ friend class FormWindowBase;
+};
+
+class QDESIGNER_SHARED_EXPORT DesignerIconCache : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DesignerIconCache(DesignerPixmapCache *pixmapCache, QObject *parent = 0);
+ QIcon icon(const PropertySheetIconValue &value) const;
+ void clear();
+signals:
+ void reloaded();
+private:
+ mutable QMap<PropertySheetIconValue, QIcon> m_cache;
+ DesignerPixmapCache *m_pixmapCache;
+ friend class FormWindowBase;
+};
+
+// -------------- StringValue: Returned by the property sheet for strings
+class QDESIGNER_SHARED_EXPORT PropertySheetStringValue
+{
+public:
+ explicit PropertySheetStringValue(const QString &value = QString(),
+ bool translatable = true,
+ const QString &disambiguation = QString(),
+ const QString &comment = QString());
+
+ bool operator==(const PropertySheetStringValue &other) const { return equals(other); }
+ bool operator!=(const PropertySheetStringValue &other) const { return !equals(other); }
+
+ QString value() const;
+ void setValue(const QString &value);
+ bool translatable() const;
+ void setTranslatable(bool translatable);
+ QString disambiguation() const;
+ void setDisambiguation(const QString &disambiguation);
+ QString comment() const;
+ void setComment(const QString &comment);
+
+private:
+ bool equals(const PropertySheetStringValue &rhs) const;
+
+ QString m_value;
+ bool m_translatable;
+ QString m_disambiguation;
+ QString m_comment;
+};
+
+
+
+// -------------- StringValue: Returned by the property sheet for strings
+class QDESIGNER_SHARED_EXPORT PropertySheetKeySequenceValue
+{
+public:
+ explicit PropertySheetKeySequenceValue(const QKeySequence &value = QKeySequence(),
+ bool translatable = true,
+ const QString &disambiguation = QString(),
+ const QString &comment = QString());
+ explicit PropertySheetKeySequenceValue(const QKeySequence::StandardKey &standardKey,
+ bool translatable = true,
+ const QString &disambiguation = QString(),
+ const QString &comment = QString());
+
+ bool operator==(const PropertySheetKeySequenceValue &other) const { return equals(other); }
+ bool operator!=(const PropertySheetKeySequenceValue &other) const { return !equals(other); }
+
+ QKeySequence value() const;
+ void setValue(const QKeySequence &value);
+ QKeySequence::StandardKey standardKey() const;
+ void setStandardKey(const QKeySequence::StandardKey &standardKey);
+ bool isStandardKey() const;
+
+ bool translatable() const;
+ void setTranslatable(bool translatable);
+ QString disambiguation() const;
+ void setDisambiguation(const QString &disambiguation);
+ QString comment() const;
+ void setComment(const QString &comment);
+
+private:
+ bool equals(const PropertySheetKeySequenceValue &rhs) const;
+
+ QKeySequence m_value;
+ QKeySequence::StandardKey m_standardKey;
+ bool m_translatable;
+ QString m_disambiguation;
+ QString m_comment;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+
+// NOTE: Do not move this code, needed for GCC 3.3
+Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetEnumValue)
+Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetFlagValue)
+Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetPixmapValue)
+Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetIconValue)
+Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetStringValue)
+Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetKeySequenceValue)
+
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+
+// Create a command to change a text property (that is, create a reset property command if the text is empty)
+QDESIGNER_SHARED_EXPORT QDesignerFormWindowCommand *createTextPropertyCommand(const QString &propertyName, const QString &text, QObject *object, QDesignerFormWindowInterface *fw);
+
+// Returns preferred task menu action for managed widget
+QDESIGNER_SHARED_EXPORT QAction *preferredEditAction(QDesignerFormEditorInterface *core, QWidget *managedWidget);
+
+// Convenience to run UIC
+enum UIC_Mode { UIC_GenerateCode, UIC_ConvertV3 };
+QDESIGNER_SHARED_EXPORT bool runUIC(const QString &fileName, UIC_Mode mode, QByteArray& ba, QString &errorMessage);
+
+// Find a suitable variable name for a class.
+QDESIGNER_SHARED_EXPORT QString qtify(const QString &name);
+
+/* UpdateBlocker: Blocks the updates of the widget passed on while in scope.
+ * Does nothing if the incoming widget already has updatesEnabled==false
+ * which is important to avoid side-effects when putting it into QStackedLayout. */
+
+class QDESIGNER_SHARED_EXPORT UpdateBlocker {
+ Q_DISABLE_COPY(UpdateBlocker)
+
+public:
+ UpdateBlocker(QWidget *w);
+ ~UpdateBlocker();
+
+private:
+ QWidget *m_widget;
+ const bool m_enabled;
+};
+
+namespace Utils {
+
+inline int valueOf(const QVariant &value, bool *ok = 0)
+{
+ if (value.canConvert<PropertySheetEnumValue>()) {
+ if (ok)
+ *ok = true;
+ return qvariant_cast<PropertySheetEnumValue>(value).value;
+ }
+ else if (value.canConvert<PropertySheetFlagValue>()) {
+ if (ok)
+ *ok = true;
+ return qvariant_cast<PropertySheetFlagValue>(value).value;
+ }
+ return value.toInt(ok);
+}
+
+inline bool isObjectAncestorOf(QObject *ancestor, QObject *child)
+{
+ QObject *obj = child;
+ while (obj != 0) {
+ if (obj == ancestor)
+ return true;
+ obj = obj->parent();
+ }
+ return false;
+}
+
+inline bool isCentralWidget(QDesignerFormWindowInterface *fw, QWidget *widget)
+{
+ if (! fw || ! widget)
+ return false;
+
+ if (widget == fw->mainContainer())
+ return true;
+
+ // ### generalize for other containers
+ if (QMainWindow *mw = qobject_cast<QMainWindow*>(fw->mainContainer())) {
+ return mw->centralWidget() == widget;
+ }
+
+ return false;
+}
+
+} // namespace Utils
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_UTILS_H
diff --git a/src/designer/src/lib/shared/qdesigner_widget.cpp b/src/designer/src/lib/shared/qdesigner_widget.cpp
new file mode 100644
index 000000000..0368d5337
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_widget.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_widget_p.h"
+#include "formwindowbase_p.h"
+#include "grid_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtGui/QPainter>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+#include <QtGui/qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+/* QDesignerDialog / QDesignerWidget are used to paint a grid on QDialog and QWidget main containers
+ * and container extension pages.
+ * The paint routines work as follows:
+ * We need to clean the background here (to make the parent grid disappear in case we are a container page
+ * and to make palette background settings take effect),
+ * which would normally break style sheets with background settings.
+ * So, we manually make the style paint after cleaning. On top comes the grid
+ * In addition, this code works around
+ * the QStyleSheetStyle setting Qt::WA_StyledBackground to false for subclasses of QWidget.
+ */
+
+QDesignerDialog::QDesignerDialog(QDesignerFormWindowInterface *fw, QWidget *parent) :
+ QDialog(parent),
+ m_formWindow(qobject_cast<qdesigner_internal::FormWindowBase*>(fw))
+{
+}
+
+void QDesignerDialog::paintEvent(QPaintEvent *e)
+{
+ QPainter p(this);
+ QStyleOption opt;
+ opt.initFrom(this);
+ p.fillRect(e->rect(), palette().brush(backgroundRole()));
+ style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
+ if (m_formWindow && m_formWindow->gridVisible())
+ m_formWindow->designerGrid().paint(p, this, e);
+}
+
+QDesignerWidget::QDesignerWidget(QDesignerFormWindowInterface* formWindow, QWidget *parent) :
+ QWidget(parent),
+ m_formWindow(qobject_cast<qdesigner_internal::FormWindowBase*>(formWindow))
+{
+}
+
+QDesignerWidget::~QDesignerWidget()
+{
+}
+
+QDesignerFormWindowInterface* QDesignerWidget::formWindow() const
+{
+ return m_formWindow;
+}
+
+void QDesignerWidget::paintEvent(QPaintEvent *e)
+{
+ QPainter p(this);
+ QStyleOption opt;
+ opt.initFrom(this);
+ p.fillRect(e->rect(), palette().brush(backgroundRole()));
+ style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
+ if (m_formWindow && m_formWindow->gridVisible())
+ m_formWindow->designerGrid().paint(p, this, e);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_widget_p.h b/src/designer/src/lib/shared/qdesigner_widget_p.h
new file mode 100644
index 000000000..bb511ae4b
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_widget_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_WIDGET_H
+#define QDESIGNER_WIDGET_H
+
+#include "shared_global_p.h"
+#include <QtGui/QDialog>
+#include <QtGui/QLabel>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+ class FormWindowBase;
+}
+
+class QDESIGNER_SHARED_EXPORT QDesignerWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QDesignerWidget(QDesignerFormWindowInterface* formWindow, QWidget *parent = 0);
+ virtual ~QDesignerWidget();
+
+ QDesignerFormWindowInterface* formWindow() const;
+
+ void updatePixmap();
+
+ virtual QSize minimumSizeHint() const
+ { return QWidget::minimumSizeHint().expandedTo(QSize(16, 16)); }
+
+protected:
+ virtual void paintEvent(QPaintEvent *e);
+
+private:
+ qdesigner_internal::FormWindowBase* m_formWindow;
+};
+
+class QDESIGNER_SHARED_EXPORT QDesignerDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit QDesignerDialog(QDesignerFormWindowInterface *fw, QWidget *parent);
+
+ virtual QSize minimumSizeHint() const
+ { return QWidget::minimumSizeHint().expandedTo(QSize(16, 16)); }
+
+protected:
+ void paintEvent(QPaintEvent *e);
+
+private:
+ qdesigner_internal::FormWindowBase* m_formWindow;
+};
+
+class QDESIGNER_SHARED_EXPORT Line : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+public:
+ explicit Line(QWidget *parent) : QFrame(parent)
+ { setAttribute(Qt::WA_MouseNoMask); setFrameStyle(HLine | Sunken); }
+
+ inline void setOrientation(Qt::Orientation orient)
+ { setFrameShape(orient == Qt::Horizontal ? HLine : VLine); }
+
+ inline Qt::Orientation orientation() const
+ { return frameShape() == HLine ? Qt::Horizontal : Qt::Vertical; }
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_WIDGET_H
diff --git a/src/designer/src/lib/shared/qdesigner_widgetbox.cpp b/src/designer/src/lib/shared/qdesigner_widgetbox.cpp
new file mode 100644
index 000000000..154b2d61d
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_widgetbox.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_widgetbox_p.h"
+#include "qdesigner_utils_p.h"
+
+#include <ui4_p.h>
+
+#include <QtCore/QRegExp>
+#include <QtCore/QDebug>
+#include <QtCore/QXmlStreamReader>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+QDesignerWidgetBox::QDesignerWidgetBox(QWidget *parent, Qt::WindowFlags flags)
+ : QDesignerWidgetBoxInterface(parent, flags),
+ m_loadMode(LoadMerge)
+{
+
+}
+
+QDesignerWidgetBox::LoadMode QDesignerWidgetBox::loadMode() const
+{
+ return m_loadMode;
+}
+
+void QDesignerWidgetBox::setLoadMode(LoadMode lm)
+{
+ m_loadMode = lm;
+}
+
+// Convenience to find a widget by class name
+bool QDesignerWidgetBox::findWidget(const QDesignerWidgetBoxInterface *wbox,
+ const QString &className,
+ const QString &category,
+ Widget *widgetData)
+{
+ // Note that entry names do not necessarily match the class name
+ // (at least, not for the standard widgets), so,
+ // look in the XML for the class name of the first widget to appear
+ const QString widgetTag = QLatin1String("<widget");
+ QString pattern = QLatin1String("^<widget\\s+class\\s*=\\s*\"");
+ pattern += className;
+ pattern += QLatin1String("\".*$");
+ const QRegExp regexp(pattern);
+ Q_ASSERT(regexp.isValid());
+ const int catCount = wbox->categoryCount();
+ for (int c = 0; c < catCount; c++) {
+ const Category cat = wbox->category(c);
+ if (category.isEmpty() || cat.name() == category) {
+ const int widgetCount = cat.widgetCount();
+ for (int w = 0; w < widgetCount; w++) {
+ const Widget widget = cat.widget(w);
+ QString xml = widget.domXml(); // Erase the <ui> tag that can be present starting from 4.4
+ const int widgetTagIndex = xml.indexOf(widgetTag);
+ if (widgetTagIndex != -1) {
+ xml.remove(0, widgetTagIndex);
+ if (regexp.exactMatch(xml)) {
+ *widgetData = widget;
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+// Convenience to create a Dom Widget from widget box xml code.
+DomUI *QDesignerWidgetBox::xmlToUi(const QString &name, const QString &xml, bool insertFakeTopLevel,
+ QString *errorMessage)
+{
+ QXmlStreamReader reader(xml);
+ DomUI *ui = 0;
+
+ // The xml description must either contain a root element "ui" with a child element "widget"
+ // or "widget" as the root element (4.3 legacy)
+ const QString widgetTag = QLatin1String("widget");
+
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ const QStringRef name = reader.name();
+ if (ui) {
+ reader.raiseError(tr("Unexpected element <%1>").arg(name.toString()));
+ continue;
+ }
+
+ if (name.compare(QLatin1String("widget"), Qt::CaseInsensitive) == 0) { // 4.3 legacy, wrap into DomUI
+ ui = new DomUI;
+ DomWidget *widget = new DomWidget;
+ widget->read(reader);
+ ui->setElementWidget(widget);
+ } else if (name.compare(QLatin1String("ui"), Qt::CaseInsensitive) == 0) { // 4.4
+ ui = new DomUI;
+ ui->read(reader);
+ } else {
+ reader.raiseError(tr("Unexpected element <%1>").arg(name.toString()));
+ }
+ }
+ }
+
+ if (reader.hasError()) {
+ delete ui;
+ *errorMessage = tr("A parse error occurred at line %1, column %2 of the XML code "
+ "specified for the widget %3: %4\n%5")
+ .arg(reader.lineNumber()).arg(reader.columnNumber()).arg(name)
+ .arg(reader.errorString()).arg(xml);
+ return 0;
+ }
+
+ if (!ui || !ui->elementWidget()) {
+ delete ui;
+ *errorMessage = tr("The XML code specified for the widget %1 does not contain "
+ "any widget elements.\n%2").arg(name).arg(xml);
+ return 0;
+ }
+
+ if (insertFakeTopLevel) {
+ DomWidget *fakeTopLevel = new DomWidget;
+ fakeTopLevel->setAttributeClass(QLatin1String("QWidget"));
+ QList<DomWidget *> children;
+ children.push_back(ui->takeElementWidget());
+ fakeTopLevel->setElementWidget(children);
+ ui->setElementWidget(fakeTopLevel);
+ }
+
+ return ui;
+}
+
+// Convenience to create a Dom Widget from widget box xml code.
+DomUI *QDesignerWidgetBox::xmlToUi(const QString &name, const QString &xml, bool insertFakeTopLevel)
+{
+ QString errorMessage;
+ DomUI *rc = xmlToUi(name, xml, insertFakeTopLevel, &errorMessage);
+ if (!rc)
+ qdesigner_internal::designerWarning(errorMessage);
+ return rc;
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_widgetbox_p.h b/src/designer/src/lib/shared/qdesigner_widgetbox_p.h
new file mode 100644
index 000000000..d0a1285db
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_widgetbox_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_WIDGETBOX_H
+#define QDESIGNER_WIDGETBOX_H
+
+#include "shared_global_p.h"
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+
+QT_BEGIN_NAMESPACE
+
+class DomUI;
+
+namespace qdesigner_internal {
+
+// A widget box with a load mode that allows for updating custom widgets.
+
+class QDESIGNER_SHARED_EXPORT QDesignerWidgetBox : public QDesignerWidgetBoxInterface
+{
+ Q_OBJECT
+public:
+ enum LoadMode { LoadMerge, LoadReplace, LoadCustomWidgetsOnly };
+
+ explicit QDesignerWidgetBox(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+
+ LoadMode loadMode() const;
+ void setLoadMode(LoadMode lm);
+
+ virtual bool loadContents(const QString &contents) = 0;
+
+ // Convenience to access the widget box icon of a widget. Empty category
+ // matches all
+ virtual QIcon iconForWidget(const QString &className,
+ const QString &category = QString()) const = 0;
+
+ // Convenience to find a widget by class name. Empty category matches all
+ static bool findWidget(const QDesignerWidgetBoxInterface *wbox,
+ const QString &className,
+ const QString &category /* = QString() */,
+ Widget *widgetData);
+ // Convenience functions to create a DomWidget from widget box xml.
+ static DomUI *xmlToUi(const QString &name, const QString &xml, bool insertFakeTopLevel, QString *errorMessage);
+ static DomUI *xmlToUi(const QString &name, const QString &xml, bool insertFakeTopLevel);
+
+private:
+ LoadMode m_loadMode;
+};
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_WIDGETBOX_H
diff --git a/src/designer/src/lib/shared/qdesigner_widgetitem.cpp b/src/designer/src/lib/shared/qdesigner_widgetitem.cpp
new file mode 100644
index 000000000..a3041ad83
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_widgetitem.cpp
@@ -0,0 +1,345 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_widgetitem_p.h"
+#include "qdesigner_widget_p.h"
+#include "widgetfactory_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QGridLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QApplication>
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDebug>
+#include <private/qlayout_p.h>
+
+QT_BEGIN_NAMESPACE
+
+enum { DebugWidgetItem = 0 };
+enum { MinimumLength = 10 };
+
+// Widget item creation function to be registered as factory method with
+// QLayoutPrivate
+static QWidgetItem *createDesignerWidgetItem(const QLayout *layout, QWidget *widget)
+{
+ Qt::Orientations orientations;
+ if (qdesigner_internal::QDesignerWidgetItem::check(layout, widget, &orientations)) {
+ if (DebugWidgetItem)
+ qDebug() << "QDesignerWidgetItem: Creating on " << layout << widget << orientations;
+ return new qdesigner_internal::QDesignerWidgetItem(layout, widget, orientations);
+ }
+ if (DebugWidgetItem)
+ qDebug() << "QDesignerWidgetItem: Noncontainer: " << layout << widget;
+
+ return 0;
+}
+
+static QString sizePolicyToString(const QSizePolicy &p)
+{
+ QString rc; {
+ QTextStream str(&rc);
+ str << "Control=" << p.controlType() << " expdirs=" << p.expandingDirections()
+ << " hasHeightForWidth=" << p.hasHeightForWidth()
+ << " H: Policy=" << p.horizontalPolicy()
+ << " stretch=" << p.horizontalStretch()
+ << " V: Policy=" << p.verticalPolicy()
+ << " stretch=" << p.verticalStretch();
+ }
+ return rc;
+}
+
+// Find the layout the item is contained in, recursing over
+// child layouts
+static const QLayout *findLayoutOfItem(const QLayout *haystack, const QLayoutItem *needle)
+{
+ const int count = haystack->count();
+ for (int i = 0; i < count; i++) {
+ QLayoutItem *item = haystack->itemAt(i);
+ if (item == needle)
+ return haystack;
+ if (QLayout *childLayout = item->layout())
+ if (const QLayout *containing = findLayoutOfItem(childLayout, needle))
+ return containing;
+ }
+ return 0;
+}
+
+
+namespace qdesigner_internal {
+
+// ------------------ QDesignerWidgetItem
+QDesignerWidgetItem::QDesignerWidgetItem(const QLayout *containingLayout, QWidget *w, Qt::Orientations o) :
+ QWidgetItemV2(w),
+ m_orientations(o),
+ m_nonLaidOutMinSize(w->minimumSizeHint()),
+ m_nonLaidOutSizeHint(w->sizeHint()),
+ m_cachedContainingLayout(containingLayout)
+{
+ // Initialize the minimum size to prevent nonlaid-out frames/widgets
+ // from being slammed to zero
+ const QSize minimumSize = w->minimumSize();
+ if (!minimumSize.isEmpty())
+ m_nonLaidOutMinSize = minimumSize;
+ expand(&m_nonLaidOutMinSize);
+ expand(&m_nonLaidOutSizeHint);
+ w->installEventFilter(this);
+ connect(containingLayout, SIGNAL(destroyed()), this, SLOT(layoutChanged()));
+ if (DebugWidgetItem )
+ qDebug() << "QDesignerWidgetItem" << w << sizePolicyToString(w->sizePolicy()) << m_nonLaidOutMinSize << m_nonLaidOutSizeHint;
+}
+
+void QDesignerWidgetItem::expand(QSize *s) const
+{
+ // Expand the size if its too small
+ if (m_orientations & Qt::Horizontal && s->width() <= 0)
+ s->setWidth(MinimumLength);
+ if (m_orientations & Qt::Vertical && s->height() <= 0)
+ s->setHeight(MinimumLength);
+}
+
+QSize QDesignerWidgetItem::minimumSize() const
+{
+ // Just track the size in case we are laid-out or stretched.
+ const QSize baseMinSize = QWidgetItemV2::minimumSize();
+ QWidget * w = constWidget();
+ if (w->layout() || subjectToStretch(containingLayout(), w)) {
+ m_nonLaidOutMinSize = baseMinSize;
+ return baseMinSize;
+ }
+ // Nonlaid out: Maintain last laid-out size
+ const QSize rc = baseMinSize.expandedTo(m_nonLaidOutMinSize);
+ if (DebugWidgetItem > 1)
+ qDebug() << "minimumSize" << constWidget() << baseMinSize << rc;
+ return rc;
+}
+
+QSize QDesignerWidgetItem::sizeHint() const
+{
+ // Just track the size in case we are laid-out or stretched.
+ const QSize baseSizeHint = QWidgetItemV2::sizeHint();
+ QWidget * w = constWidget();
+ if (w->layout() || subjectToStretch(containingLayout(), w)) {
+ m_nonLaidOutSizeHint = baseSizeHint;
+ return baseSizeHint;
+ }
+ // Nonlaid out: Maintain last laid-out size
+ const QSize rc = baseSizeHint.expandedTo(m_nonLaidOutSizeHint);
+ if (DebugWidgetItem > 1)
+ qDebug() << "sizeHint" << constWidget() << baseSizeHint << rc;
+ return rc;
+}
+
+bool QDesignerWidgetItem::subjectToStretch(const QLayout *layout, QWidget *w)
+{
+ if (!layout)
+ return false;
+ // Are we under some stretch factor?
+ if (const QBoxLayout *bl = qobject_cast<const QBoxLayout *>(layout)) {
+ const int index = bl->indexOf(w);
+ Q_ASSERT(index != -1);
+ return bl->stretch(index) != 0;
+ }
+ if (const QGridLayout *cgl = qobject_cast<const QGridLayout *>(layout)) {
+ QGridLayout *gl = const_cast<QGridLayout *>(cgl);
+ const int index = cgl->indexOf(w);
+ Q_ASSERT(index != -1);
+ int row, column, rowSpan, columnSpan;
+ gl->getItemPosition (index, &row, &column, &rowSpan, &columnSpan);
+ const int rend = row + rowSpan;
+ const int cend = column + columnSpan;
+ for (int r = row; r < rend; r++)
+ if (cgl->rowStretch(r) != 0)
+ return true;
+ for (int c = column; c < cend; c++)
+ if (cgl->columnStretch(c) != 0)
+ return true;
+ }
+ return false;
+}
+
+/* Return the orientations mask for a layout, specifying
+ * in which directions squeezing should be prevented. */
+static Qt::Orientations layoutOrientation(const QLayout *layout)
+{
+ if (const QBoxLayout *bl = qobject_cast<const QBoxLayout *>(layout)) {
+ const QBoxLayout::Direction direction = bl->direction();
+ return direction == QBoxLayout::LeftToRight || direction == QBoxLayout::RightToLeft ? Qt::Horizontal : Qt::Vertical;
+ }
+ if (qobject_cast<const QFormLayout*>(layout))
+ return Qt::Vertical;
+ return Qt::Horizontal|Qt::Vertical;
+}
+
+// Check for a non-container extension container
+bool QDesignerWidgetItem::isContainer(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ if (!WidgetFactory::isFormEditorObject(w))
+ return false;
+ const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
+ const int widx = wdb->indexOfObject(w);
+ if (widx == -1 || !wdb->item(widx)->isContainer())
+ return false;
+ if (qt_extension<QDesignerContainerExtension*>(core->extensionManager(), w))
+ return false;
+ return true;
+}
+
+bool QDesignerWidgetItem::check(const QLayout *layout, QWidget *w, Qt::Orientations *ptrToOrientations)
+{
+ // Check for form-editor non-containerextension-containers (QFrame, etc)
+ // within laid-out form editor widgets. No check for managed() here as we
+ // want container pages and widgets in the process of being morphed as
+ // well. Avoid nested layouts (as the effective stretch cannot be easily
+ // computed and may mess things up). Won't work for Q3 Group boxes.
+ if (ptrToOrientations)
+ *ptrToOrientations = 0;
+
+ const QObject *layoutParent = layout->parent();
+ if (!layoutParent || !layoutParent->isWidgetType() || !WidgetFactory::isFormEditorObject(layoutParent))
+ return false;
+
+ QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(w);
+ if (!fw || !isContainer(fw->core(), w))
+ return false;
+
+ // If it is a box, restrict to its orientation
+ if (ptrToOrientations)
+ *ptrToOrientations = layoutOrientation(layout);
+
+ return true;
+}
+
+QSize QDesignerWidgetItem::nonLaidOutMinSize() const
+{
+ return m_nonLaidOutMinSize;
+}
+
+void QDesignerWidgetItem::setNonLaidOutMinSize(const QSize &s)
+{
+ if (DebugWidgetItem > 1)
+ qDebug() << "setNonLaidOutMinSize" << constWidget() << s;
+ m_nonLaidOutMinSize = s;
+}
+
+QSize QDesignerWidgetItem::nonLaidOutSizeHint() const
+{
+ return m_nonLaidOutSizeHint;
+}
+
+void QDesignerWidgetItem::setNonLaidOutSizeHint(const QSize &s)
+{
+ if (DebugWidgetItem > 1)
+ qDebug() << "setNonLaidOutSizeHint" << constWidget() << s;
+ m_nonLaidOutSizeHint = s;
+}
+
+void QDesignerWidgetItem::install()
+{
+ QLayoutPrivate::widgetItemFactoryMethod = createDesignerWidgetItem;
+}
+
+void QDesignerWidgetItem::deinstall()
+{
+ QLayoutPrivate::widgetItemFactoryMethod = 0;
+}
+
+const QLayout *QDesignerWidgetItem::containingLayout() const
+{
+ if (!m_cachedContainingLayout) {
+ if (QWidget *parentWidget = constWidget()->parentWidget())
+ if (QLayout *parentLayout = parentWidget->layout()) {
+ m_cachedContainingLayout = findLayoutOfItem(parentLayout, this);
+ if (m_cachedContainingLayout)
+ connect(m_cachedContainingLayout, SIGNAL(destroyed()), this, SLOT(layoutChanged()));
+ }
+ if (DebugWidgetItem)
+ qDebug() << Q_FUNC_INFO << " found " << m_cachedContainingLayout << " after reparenting " << constWidget();
+ }
+ return m_cachedContainingLayout;
+}
+
+void QDesignerWidgetItem::layoutChanged()
+{
+ if (DebugWidgetItem)
+ qDebug() << Q_FUNC_INFO;
+ m_cachedContainingLayout = 0;
+}
+
+bool QDesignerWidgetItem::eventFilter(QObject * /* watched */, QEvent *event)
+{
+ if (event->type() == QEvent::ParentChange)
+ layoutChanged();
+ return false;
+}
+
+// ------------------ QDesignerWidgetItemInstaller
+
+int QDesignerWidgetItemInstaller::m_instanceCount = 0;
+
+QDesignerWidgetItemInstaller::QDesignerWidgetItemInstaller()
+{
+ if (m_instanceCount++ == 0) {
+ if (DebugWidgetItem)
+ qDebug() << "QDesignerWidgetItemInstaller: installing";
+ QDesignerWidgetItem::install();
+ }
+}
+
+QDesignerWidgetItemInstaller::~QDesignerWidgetItemInstaller()
+{
+ if (--m_instanceCount == 0) {
+ if (DebugWidgetItem)
+ qDebug() << "QDesignerWidgetItemInstaller: deinstalling";
+ QDesignerWidgetItem::deinstall();
+ }
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qdesigner_widgetitem_p.h b/src/designer/src/lib/shared/qdesigner_widgetitem_p.h
new file mode 100644
index 000000000..f79dbc5a1
--- /dev/null
+++ b/src/designer/src/lib/shared/qdesigner_widgetitem_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef DESIGNERWIDGETITEM_H
+#define DESIGNERWIDGETITEM_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QLayoutItem>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+// QDesignerWidgetItem: A Layout Item that is used for non-containerextension-
+// containers (QFrame, etc) on Designer forms. It prevents its widget
+// from being slammed to size 0 if the widget has no layout:
+// Pre 4.5, this item ensured only that QWidgets and QFrames were not squeezed
+// to size 0 since they have an invalid size hint when non-laid out.
+// Since 4.5, the item is used for every non-containerextension-container.
+// In case the container has itself a layout, it merely tracks the minimum
+// size. If the container has no layout and is not subject to some stretch
+// factor, it will return the last valid size. The effect is that after
+// breaking a layout on a container within a layout, it just maintains its
+// last size and is not slammed to 0,0. In addition, it can be resized.
+// The class keeps track of the containing layout by tracking widget reparent
+// and destroyed slots as Designer will for example re-create grid layouts to
+// shrink them.
+
+class QDESIGNER_SHARED_EXPORT QDesignerWidgetItem : public QObject, public QWidgetItemV2 {
+ Q_DISABLE_COPY(QDesignerWidgetItem)
+ Q_OBJECT
+public:
+ explicit QDesignerWidgetItem(const QLayout *containingLayout, QWidget *w, Qt::Orientations o = Qt::Horizontal|Qt::Vertical);
+
+ const QLayout *containingLayout() const;
+
+ inline QWidget *constWidget() const { return const_cast<QDesignerWidgetItem*>(this)->widget(); }
+
+ virtual QSize minimumSize() const;
+ virtual QSize sizeHint() const;
+
+ // Resize: Takes effect if the contained widget does not have a layout
+ QSize nonLaidOutMinSize() const;
+ void setNonLaidOutMinSize(const QSize &s);
+
+ QSize nonLaidOutSizeHint() const;
+ void setNonLaidOutSizeHint(const QSize &s);
+
+ // Check whether a QDesignerWidgetItem should be installed
+ static bool check(const QLayout *layout, QWidget *w, Qt::Orientations *ptrToOrientations = 0);
+
+ // Register itself using QLayoutPrivate's widget item factory method hook
+ static void install();
+ static void deinstall();
+
+ // Check for a non-container extension container
+ static bool isContainer(const QDesignerFormEditorInterface *core, QWidget *w);
+
+ static bool subjectToStretch(const QLayout *layout, QWidget *w);
+
+ virtual bool eventFilter(QObject * watched, QEvent * event);
+
+private slots:
+ void layoutChanged();
+
+private:
+ void expand(QSize *s) const;
+ bool subjectToStretch() const;
+
+ const Qt::Orientations m_orientations;
+ mutable QSize m_nonLaidOutMinSize;
+ mutable QSize m_nonLaidOutSizeHint;
+ mutable const QLayout *m_cachedContainingLayout;
+};
+
+// Helper class that ensures QDesignerWidgetItem is installed while an
+// instance is in scope.
+
+class QDESIGNER_SHARED_EXPORT QDesignerWidgetItemInstaller {
+ Q_DISABLE_COPY(QDesignerWidgetItemInstaller)
+
+public:
+ QDesignerWidgetItemInstaller();
+ ~QDesignerWidgetItemInstaller();
+
+private:
+ static int m_instanceCount;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/shared/qlayout_widget.cpp b/src/designer/src/lib/shared/qlayout_widget.cpp
new file mode 100644
index 000000000..66e7a795b
--- /dev/null
+++ b/src/designer/src/lib/shared/qlayout_widget.cpp
@@ -0,0 +1,2107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlayout_widget_p.h"
+#include "qdesigner_utils_p.h"
+#include "layout_p.h"
+#include "layoutinfo_p.h"
+#include "invisible_widget_p.h"
+#include "qdesigner_widgetitem_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+
+#include <QtGui/QPainter>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QGridLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/qevent.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/QtAlgorithms>
+#include <QtCore/QMap>
+#include <QtCore/QStack>
+#include <QtCore/QPair>
+#include <QtCore/QSet>
+
+enum { ShiftValue = 1 };
+enum { debugLayout = 0 };
+enum { FormLayoutColumns = 2 };
+enum { indicatorSize = 2 };
+// Grid/form Helpers: get info (overloads to make templates work)
+
+namespace { // Do not use static, will break HP-UX due to templates
+
+QT_USE_NAMESPACE
+
+// overloads to make templates over QGridLayout/QFormLayout work
+inline int gridRowCount(const QGridLayout *gridLayout)
+{
+ return gridLayout->rowCount();
+}
+
+inline int gridColumnCount(const QGridLayout *gridLayout)
+{
+ return gridLayout->columnCount();
+}
+
+// QGridLayout/QFormLayout Helpers: get item position (overloads to make templates work)
+inline void getGridItemPosition(QGridLayout *gridLayout, int index,
+ int *row, int *column, int *rowspan, int *colspan)
+{
+ gridLayout->getItemPosition(index, row, column, rowspan, colspan);
+}
+
+QRect gridItemInfo(QGridLayout *grid, int index)
+{
+ int row, column, rowSpan, columnSpan;
+ // getItemPosition is not const, grmbl..
+ grid->getItemPosition(index, &row, &column, &rowSpan, &columnSpan);
+ return QRect(column, row, columnSpan, rowSpan);
+}
+
+inline int gridRowCount(const QFormLayout *formLayout) { return formLayout->rowCount(); }
+inline int gridColumnCount(const QFormLayout *) { return FormLayoutColumns; }
+
+inline void getGridItemPosition(QFormLayout *formLayout, int index, int *row, int *column, int *rowspan, int *colspan)
+{
+ qdesigner_internal::getFormLayoutItemPosition(formLayout, index, row, column, rowspan, colspan);
+}
+
+QRect gridItemInfo(const QFormLayout *form, int index)
+{
+ int row;
+ int column;
+ int colspan;
+ qdesigner_internal::getFormLayoutItemPosition(form, index, &row, &column, 0, &colspan);
+ return QRect(column, row, colspan, 1);
+}
+} // namespace anonymous
+
+QT_BEGIN_NAMESPACE
+
+static const char *objectNameC = "objectName";
+static const char *sizeConstraintC = "sizeConstraint";
+
+/* A padding spacer element that is used to represent an empty form layout cell. It should grow with its cell.
+ * Should not be used on a grid as it causes resizing inconsistencies */
+namespace qdesigner_internal {
+ class PaddingSpacerItem : public QSpacerItem {
+ public:
+ PaddingSpacerItem() : QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) {}
+ virtual Qt::Orientations expandingDirections () const { return Qt::Vertical | Qt::Horizontal; }
+ };
+}
+
+static inline QSpacerItem *createGridSpacer()
+{
+ return new QSpacerItem(0, 0);
+}
+
+static inline QSpacerItem *createFormSpacer()
+{
+ return new qdesigner_internal::PaddingSpacerItem;
+}
+
+// QGridLayout/QFormLayout Helpers: Debug items of GridLikeLayout
+template <class GridLikeLayout>
+static QDebug debugGridLikeLayout(QDebug str, const GridLikeLayout &gl)
+{
+ const int count = gl.count();
+ str << "Grid: " << gl.objectName() << gridRowCount(&gl) << " rows x " << gridColumnCount(&gl)
+ << " cols " << count << " items\n";
+ for (int i = 0; i < count; i++) {
+ QLayoutItem *item = gl.itemAt(i);
+ str << "Item " << i << item << item->widget() << gridItemInfo(const_cast<GridLikeLayout *>(&gl), i) << " empty=" << qdesigner_internal::LayoutInfo::isEmptyItem(item) << "\n";
+ }
+ return str;
+}
+
+static inline QDebug operator<<(QDebug str, const QGridLayout &gl) { return debugGridLikeLayout(str, gl); }
+static inline QDebug operator<<(QDebug str, const QFormLayout &fl) { return debugGridLikeLayout(str, fl); }
+
+static inline bool isEmptyFormLayoutRow(const QFormLayout *fl, int row)
+{
+ // Spanning can never be empty
+ if (fl->itemAt(row, QFormLayout::SpanningRole))
+ return false;
+ return qdesigner_internal::LayoutInfo::isEmptyItem(fl->itemAt(row, QFormLayout::LabelRole)) && qdesigner_internal::LayoutInfo::isEmptyItem(fl->itemAt(row, QFormLayout::FieldRole));
+}
+
+static inline bool canSimplifyFormLayout(const QFormLayout *formLayout, const QRect &restrictionArea)
+{
+ if (restrictionArea.x() >= FormLayoutColumns)
+ return false;
+ // Try to find empty rows
+ const int bottomCheckRow = qMin(formLayout->rowCount(), restrictionArea.top() + restrictionArea.height());
+ for (int r = restrictionArea.y(); r < bottomCheckRow; r++)
+ if (isEmptyFormLayoutRow(formLayout, r))
+ return true;
+ return false;
+}
+
+// recreate a managed layout (which does not automagically remove
+// empty rows/columns like grid or form layout) in case it needs to shrink
+
+static QLayout *recreateManagedLayout(const QDesignerFormEditorInterface *core, QWidget *w, QLayout *lt)
+{
+ const qdesigner_internal::LayoutInfo::Type t = qdesigner_internal::LayoutInfo::layoutType(core, lt);
+ qdesigner_internal::LayoutProperties properties;
+ const int mask = properties.fromPropertySheet(core, lt, qdesigner_internal::LayoutProperties::AllProperties);
+ qdesigner_internal::LayoutInfo::deleteLayout(core, w);
+ QLayout *rc = core->widgetFactory()->createLayout(w, 0, t);
+ properties.toPropertySheet(core, rc, mask, true);
+ return rc;
+}
+
+// QGridLayout/QFormLayout Helpers: find an item on a form/grid. Return index
+template <class GridLikeLayout>
+int findGridItemAt(GridLikeLayout *gridLayout, int at_row, int at_column)
+{
+ Q_ASSERT(gridLayout);
+ const int count = gridLayout->count();
+ for (int index = 0; index < count; index++) {
+ int row, column, rowspan, colspan;
+ getGridItemPosition(gridLayout, index, &row, &column, &rowspan, &colspan);
+ if (at_row >= row && at_row < (row + rowspan)
+ && at_column >= column && at_column < (column + colspan)) {
+ return index;
+ }
+ }
+ return -1;
+}
+// QGridLayout/QFormLayout Helpers: remove dummy spacers on form/grid
+template <class GridLikeLayout>
+static bool removeEmptyCellsOnGrid(GridLikeLayout *grid, const QRect &area)
+{
+ // check if there are any items in the way. Should be only spacers
+ // Unique out items that span rows/columns.
+ QVector<int> indexesToBeRemoved;
+ indexesToBeRemoved.reserve(grid->count());
+ const int rightColumn = area.x() + area.width();
+ const int bottomRow = area.y() + area.height();
+ for (int c = area.x(); c < rightColumn; c++)
+ for (int r = area.y(); r < bottomRow; r++) {
+ const int index = findGridItemAt(grid, r ,c);
+ if (index != -1)
+ if (QLayoutItem *item = grid->itemAt(index)) {
+ if (qdesigner_internal::LayoutInfo::isEmptyItem(item)) {
+ if (indexesToBeRemoved.indexOf(index) == -1)
+ indexesToBeRemoved.push_back(index);
+ } else {
+ return false;
+ }
+ }
+ }
+ // remove, starting from last
+ if (!indexesToBeRemoved.empty()) {
+ qStableSort(indexesToBeRemoved.begin(), indexesToBeRemoved.end());
+ for (int i = indexesToBeRemoved.size() - 1; i >= 0; i--)
+ delete grid->takeAt(indexesToBeRemoved[i]);
+ }
+ return true;
+}
+
+namespace qdesigner_internal {
+// --------- LayoutProperties
+
+LayoutProperties::LayoutProperties()
+{
+ clear();
+}
+
+void LayoutProperties::clear()
+{
+ qFill(m_margins, m_margins + MarginCount, 0);
+ qFill(m_marginsChanged, m_marginsChanged + MarginCount, false);
+ qFill(m_spacings, m_spacings + SpacingsCount, 0);
+ qFill(m_spacingsChanged, m_spacingsChanged + SpacingsCount, false);
+
+ m_objectName = QVariant();
+ m_objectNameChanged = false;
+ m_sizeConstraint = QVariant(QLayout::SetDefaultConstraint);
+ m_sizeConstraintChanged = false;
+
+ m_fieldGrowthPolicyChanged = m_rowWrapPolicyChanged = m_labelAlignmentChanged = m_formAlignmentChanged = false;
+ m_fieldGrowthPolicy = m_rowWrapPolicy = m_formAlignment = QVariant();
+
+ m_boxStretchChanged = m_gridRowStretchChanged = m_gridColumnStretchChanged = m_gridRowMinimumHeightChanged = false;
+ m_boxStretch = m_gridRowStretch = m_gridColumnStretch = m_gridRowMinimumHeight = QVariant();
+}
+
+int LayoutProperties::visibleProperties(const QLayout *layout)
+{
+ // Grid like layout have 2 spacings.
+ const bool isFormLayout = qobject_cast<const QFormLayout*>(layout);
+ const bool isGridLike = qobject_cast<const QGridLayout*>(layout) || isFormLayout;
+ int rc = ObjectNameProperty|LeftMarginProperty|TopMarginProperty|RightMarginProperty|BottomMarginProperty|
+ SizeConstraintProperty;
+
+ rc |= isGridLike ? (HorizSpacingProperty|VertSpacingProperty) : SpacingProperty;
+ if (isFormLayout) {
+ rc |= FieldGrowthPolicyProperty|RowWrapPolicyProperty|LabelAlignmentProperty|FormAlignmentProperty;
+ } else {
+ if (isGridLike) {
+ rc |= GridRowStretchProperty|GridColumnStretchProperty|GridRowMinimumHeightProperty|GridColumnMinimumWidthProperty;
+ } else {
+ rc |= BoxStretchProperty;
+ }
+ }
+ return rc;
+}
+
+static const char *marginPropertyNamesC[] = {"leftMargin", "topMargin", "rightMargin", "bottomMargin"};
+static const char *spacingPropertyNamesC[] = {"spacing", "horizontalSpacing", "verticalSpacing" };
+static const char *fieldGrowthPolicyPropertyC = "fieldGrowthPolicy";
+static const char *rowWrapPolicyPropertyC = "rowWrapPolicy";
+static const char *labelAlignmentPropertyC = "labelAlignment";
+static const char *formAlignmentPropertyC = "formAlignment";
+static const char *boxStretchPropertyC = "stretch";
+static const char *gridRowStretchPropertyC = "rowStretch";
+static const char *gridColumnStretchPropertyC = "columnStretch";
+static const char *gridRowMinimumHeightPropertyC = "rowMinimumHeight";
+static const char *gridColumnMinimumWidthPropertyC = "columnMinimumWidth";
+
+static bool intValueFromSheet(const QDesignerPropertySheetExtension *sheet, const QString &name, int *value, bool *changed)
+{
+ const int sheetIndex = sheet->indexOf(name);
+ if (sheetIndex == -1)
+ return false;
+ *value = sheet->property(sheetIndex).toInt();
+ *changed = sheet->isChanged(sheetIndex);
+ return true;
+}
+
+static void variantPropertyFromSheet(int mask, int flag, const QDesignerPropertySheetExtension *sheet, const QString &name,
+ QVariant *value, bool *changed, int *returnMask)
+{
+ if (mask & flag) {
+ const int sIndex = sheet->indexOf(name);
+ if (sIndex != -1) {
+ *value = sheet->property(sIndex);
+ *changed = sheet->isChanged(sIndex);
+ *returnMask |= flag;
+ }
+ }
+}
+
+int LayoutProperties::fromPropertySheet(const QDesignerFormEditorInterface *core, QLayout *l, int mask)
+{
+ int rc = 0;
+ const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), l);
+ Q_ASSERT(sheet);
+ // name
+ if (mask & ObjectNameProperty) {
+ const int nameIndex = sheet->indexOf(QLatin1String(objectNameC));
+ Q_ASSERT(nameIndex != -1);
+ m_objectName = sheet->property(nameIndex);
+ m_objectNameChanged = sheet->isChanged(nameIndex);
+ rc |= ObjectNameProperty;
+ }
+ // -- Margins
+ const int marginFlags[MarginCount] = { LeftMarginProperty, TopMarginProperty, RightMarginProperty, BottomMarginProperty};
+ for (int i = 0; i < MarginCount; i++)
+ if (mask & marginFlags[i])
+ if (intValueFromSheet(sheet, QLatin1String(marginPropertyNamesC[i]), m_margins + i, m_marginsChanged + i))
+ rc |= marginFlags[i];
+
+ const int spacingFlags[] = { SpacingProperty, HorizSpacingProperty, VertSpacingProperty};
+ for (int i = 0; i < SpacingsCount; i++)
+ if (mask & spacingFlags[i])
+ if (intValueFromSheet(sheet, QLatin1String(spacingPropertyNamesC[i]), m_spacings + i, m_spacingsChanged + i))
+ rc |= spacingFlags[i];
+ // sizeConstraint, flags
+ variantPropertyFromSheet(mask, SizeConstraintProperty, sheet, QLatin1String(sizeConstraintC), &m_sizeConstraint, &m_sizeConstraintChanged, &rc);
+ variantPropertyFromSheet(mask, FieldGrowthPolicyProperty, sheet, QLatin1String(fieldGrowthPolicyPropertyC), &m_fieldGrowthPolicy, &m_fieldGrowthPolicyChanged, &rc);
+ variantPropertyFromSheet(mask, RowWrapPolicyProperty, sheet, QLatin1String(rowWrapPolicyPropertyC), &m_rowWrapPolicy, &m_rowWrapPolicyChanged, &rc);
+ variantPropertyFromSheet(mask, LabelAlignmentProperty, sheet, QLatin1String(labelAlignmentPropertyC), &m_labelAlignment, &m_labelAlignmentChanged, &rc);
+ variantPropertyFromSheet(mask, FormAlignmentProperty, sheet, QLatin1String(formAlignmentPropertyC), &m_formAlignment, &m_formAlignmentChanged, &rc);
+ variantPropertyFromSheet(mask, BoxStretchProperty, sheet, QLatin1String(boxStretchPropertyC), &m_boxStretch, & m_boxStretchChanged, &rc);
+ variantPropertyFromSheet(mask, GridRowStretchProperty, sheet, QLatin1String(gridRowStretchPropertyC), &m_gridRowStretch, &m_gridRowStretchChanged, &rc);
+ variantPropertyFromSheet(mask, GridColumnStretchProperty, sheet, QLatin1String(gridColumnStretchPropertyC), &m_gridColumnStretch, &m_gridColumnStretchChanged, &rc);
+ variantPropertyFromSheet(mask, GridRowMinimumHeightProperty, sheet, QLatin1String(gridRowMinimumHeightPropertyC), &m_gridRowMinimumHeight, &m_gridRowMinimumHeightChanged, &rc);
+ variantPropertyFromSheet(mask, GridColumnMinimumWidthProperty, sheet, QLatin1String(gridColumnMinimumWidthPropertyC), &m_gridColumnMinimumWidth, &m_gridColumnMinimumWidthChanged, &rc);
+ return rc;
+}
+
+static bool intValueToSheet(QDesignerPropertySheetExtension *sheet, const QString &name, int value, bool changed, bool applyChanged)
+
+{
+
+ const int sheetIndex = sheet->indexOf(name);
+ if (sheetIndex == -1) {
+ qWarning() << " LayoutProperties: Attempt to set property " << name << " that does not exist for the layout.";
+ return false;
+ }
+ sheet->setProperty(sheetIndex, QVariant(value));
+ if (applyChanged)
+ sheet->setChanged(sheetIndex, changed);
+ return true;
+}
+
+static void variantPropertyToSheet(int mask, int flag, bool applyChanged, QDesignerPropertySheetExtension *sheet, const QString &name,
+ const QVariant &value, bool changed, int *returnMask)
+{
+ if (mask & flag) {
+ const int sIndex = sheet->indexOf(name);
+ if (sIndex != -1) {
+ sheet->setProperty(sIndex, value);
+ if (applyChanged)
+ sheet->setChanged(sIndex, changed);
+ *returnMask |= flag;
+ }
+ }
+}
+
+int LayoutProperties::toPropertySheet(const QDesignerFormEditorInterface *core, QLayout *l, int mask, bool applyChanged) const
+{
+ int rc = 0;
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), l);
+ Q_ASSERT(sheet);
+ // name
+ if (mask & ObjectNameProperty) {
+ const int nameIndex = sheet->indexOf(QLatin1String(objectNameC));
+ Q_ASSERT(nameIndex != -1);
+ sheet->setProperty(nameIndex, m_objectName);
+ if (applyChanged)
+ sheet->setChanged(nameIndex, m_objectNameChanged);
+ rc |= ObjectNameProperty;
+ }
+ // margins
+ const int marginFlags[MarginCount] = { LeftMarginProperty, TopMarginProperty, RightMarginProperty, BottomMarginProperty};
+ for (int i = 0; i < MarginCount; i++)
+ if (mask & marginFlags[i])
+ if (intValueToSheet(sheet, QLatin1String(marginPropertyNamesC[i]), m_margins[i], m_marginsChanged[i], applyChanged))
+ rc |= marginFlags[i];
+
+ const int spacingFlags[] = { SpacingProperty, HorizSpacingProperty, VertSpacingProperty};
+ for (int i = 0; i < SpacingsCount; i++)
+ if (mask & spacingFlags[i])
+ if (intValueToSheet(sheet, QLatin1String(spacingPropertyNamesC[i]), m_spacings[i], m_spacingsChanged[i], applyChanged))
+ rc |= spacingFlags[i];
+ // sizeConstraint
+ variantPropertyToSheet(mask, SizeConstraintProperty, applyChanged, sheet, QLatin1String(sizeConstraintC), m_sizeConstraint, m_sizeConstraintChanged, &rc);
+ variantPropertyToSheet(mask, FieldGrowthPolicyProperty, applyChanged, sheet, QLatin1String(fieldGrowthPolicyPropertyC), m_fieldGrowthPolicy, &m_fieldGrowthPolicyChanged, &rc);
+ variantPropertyToSheet(mask, RowWrapPolicyProperty, applyChanged, sheet, QLatin1String(rowWrapPolicyPropertyC), m_rowWrapPolicy, m_rowWrapPolicyChanged, &rc);
+ variantPropertyToSheet(mask, LabelAlignmentProperty, applyChanged, sheet, QLatin1String(labelAlignmentPropertyC), m_labelAlignment, m_labelAlignmentChanged, &rc);
+ variantPropertyToSheet(mask, FormAlignmentProperty, applyChanged, sheet, QLatin1String(formAlignmentPropertyC), m_formAlignment, m_formAlignmentChanged, &rc);
+ variantPropertyToSheet(mask, BoxStretchProperty, applyChanged, sheet, QLatin1String(boxStretchPropertyC), m_boxStretch, m_boxStretchChanged, &rc);
+ variantPropertyToSheet(mask, GridRowStretchProperty, applyChanged, sheet, QLatin1String(gridRowStretchPropertyC), m_gridRowStretch, m_gridRowStretchChanged, &rc);
+ variantPropertyToSheet(mask, GridColumnStretchProperty, applyChanged, sheet, QLatin1String(gridColumnStretchPropertyC), m_gridColumnStretch, m_gridColumnStretchChanged, &rc);
+ variantPropertyToSheet(mask, GridRowMinimumHeightProperty, applyChanged, sheet, QLatin1String(gridRowMinimumHeightPropertyC), m_gridRowMinimumHeight, m_gridRowMinimumHeightChanged, &rc);
+ variantPropertyToSheet(mask, GridColumnMinimumWidthProperty, applyChanged, sheet, QLatin1String(gridColumnMinimumWidthPropertyC), m_gridColumnMinimumWidth, m_gridColumnMinimumWidthChanged, &rc);
+ return rc;
+}
+
+// ---------------- LayoutHelper
+LayoutHelper::LayoutHelper()
+{
+}
+
+LayoutHelper::~LayoutHelper()
+{
+}
+
+int LayoutHelper::indexOf(const QLayout *lt, const QWidget *widget)
+{
+ if (!lt)
+ return -1;
+
+ const int itemCount = lt->count();
+ for (int i = 0; i < itemCount; i++)
+ if (lt->itemAt(i)->widget() == widget)
+ return i;
+ return -1;
+}
+
+QRect LayoutHelper::itemInfo(QLayout *lt, const QWidget *widget) const
+{
+ const int index = indexOf(lt, widget);
+ if (index == -1) {
+ qWarning() << "LayoutHelper::itemInfo: " << widget << " not in layout " << lt;
+ return QRect(0, 0, 1, 1);
+ }
+ return itemInfo(lt, index);
+}
+
+ // ---------------- BoxLayoutHelper
+ class BoxLayoutHelper : public LayoutHelper {
+ public:
+ BoxLayoutHelper(const Qt::Orientation orientation) : m_orientation(orientation) {}
+
+ virtual QRect itemInfo(QLayout *lt, int index) const;
+ virtual void insertWidget(QLayout *lt, const QRect &info, QWidget *w);
+ virtual void removeWidget(QLayout *lt, QWidget *widget);
+ virtual void replaceWidget(QLayout *lt, QWidget *before, QWidget *after);
+
+ virtual void pushState(const QDesignerFormEditorInterface *, const QWidget *);
+ virtual void popState(const QDesignerFormEditorInterface *, QWidget *);
+
+ virtual bool canSimplify(const QDesignerFormEditorInterface *, const QWidget *, const QRect &) const { return false; }
+ virtual void simplify(const QDesignerFormEditorInterface *, QWidget *, const QRect &) {}
+
+ // Helper for restoring layout states
+ typedef QVector <QLayoutItem *> LayoutItemVector;
+ static LayoutItemVector disassembleLayout(QLayout *lt);
+ static QLayoutItem *findItemOfWidget(const LayoutItemVector &lv, QWidget *w);
+
+ private:
+ typedef QVector<QWidget *> BoxLayoutState;
+
+ static BoxLayoutState state(const QBoxLayout*lt);
+
+ QStack<BoxLayoutState> m_states;
+ const Qt::Orientation m_orientation;
+ };
+
+ QRect BoxLayoutHelper::itemInfo(QLayout * /*lt*/, int index) const
+ {
+ return m_orientation == Qt::Horizontal ? QRect(index, 0, 1, 1) : QRect(0, index, 1, 1);
+ }
+
+ void BoxLayoutHelper::insertWidget(QLayout *lt, const QRect &info, QWidget *w)
+ {
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ QBoxLayout *boxLayout = qobject_cast<QBoxLayout *>(lt);
+ Q_ASSERT(boxLayout);
+ boxLayout->insertWidget(m_orientation == Qt::Horizontal ? info.x() : info.y(), w);
+ }
+
+ void BoxLayoutHelper::removeWidget(QLayout *lt, QWidget *widget)
+ {
+ QBoxLayout *boxLayout = qobject_cast<QBoxLayout *>(lt);
+ Q_ASSERT(boxLayout);
+ boxLayout->removeWidget(widget);
+ }
+
+ void BoxLayoutHelper::replaceWidget(QLayout *lt, QWidget *before, QWidget *after)
+ {
+ bool ok = false;
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ if (QBoxLayout *boxLayout = qobject_cast<QBoxLayout *>(lt)) {
+ const int index = boxLayout->indexOf(before);
+ if (index != -1) {
+ const bool visible = before->isVisible();
+ delete boxLayout->takeAt(index);
+ if (visible)
+ before->hide();
+ before->setParent(0);
+ boxLayout->insertWidget(index, after);
+ ok = true;
+ }
+ }
+ if (!ok)
+ qWarning() << "BoxLayoutHelper::replaceWidget : Unable to replace " << before << " by " << after << " in " << lt;
+ }
+
+ BoxLayoutHelper::BoxLayoutState BoxLayoutHelper::state(const QBoxLayout*lt)
+ {
+ BoxLayoutState rc;
+ if (const int count = lt->count()) {
+ rc.reserve(count);
+ for (int i = 0; i < count; i++)
+ if (QWidget *w = lt->itemAt(i)->widget())
+ rc.push_back(w);
+ }
+ return rc;
+ }
+
+ void BoxLayoutHelper::pushState(const QDesignerFormEditorInterface *core, const QWidget *w)
+ {
+ const QBoxLayout *boxLayout = qobject_cast<const QBoxLayout *>(LayoutInfo::managedLayout(core, w));
+ Q_ASSERT(boxLayout);
+ m_states.push(state(boxLayout));
+ }
+
+ QLayoutItem *BoxLayoutHelper::findItemOfWidget(const LayoutItemVector &lv, QWidget *w)
+ {
+ const LayoutItemVector::const_iterator cend = lv.constEnd();
+ for (LayoutItemVector::const_iterator it = lv.constBegin(); it != cend; ++it)
+ if ( (*it)->widget() == w)
+ return *it;
+
+ return 0;
+ }
+
+ BoxLayoutHelper::LayoutItemVector BoxLayoutHelper::disassembleLayout(QLayout *lt)
+ {
+ // Take items
+ const int count = lt->count();
+ if (count == 0)
+ return LayoutItemVector();
+ LayoutItemVector rc;
+ rc.reserve(count);
+ for (int i = count - 1; i >= 0; i--)
+ rc.push_back(lt->takeAt(i));
+ return rc;
+ }
+
+ void BoxLayoutHelper::popState(const QDesignerFormEditorInterface *core, QWidget *w)
+ {
+ QBoxLayout *boxLayout = qobject_cast<QBoxLayout *>(LayoutInfo::managedLayout(core, w));
+ Q_ASSERT(boxLayout);
+ const BoxLayoutState savedState = m_states.pop();
+ const BoxLayoutState currentState = state(boxLayout);
+ // Check for equality/empty. Note that this will currently
+ // always trigger as box layouts do not have a state apart from
+ // the order and there is no layout order editor yet.
+ if (savedState == state(boxLayout))
+ return;
+
+ const int count = savedState.size();
+ Q_ASSERT(count == currentState.size());
+ // Take items and reassemble in saved order
+ const LayoutItemVector items = disassembleLayout(boxLayout);
+ for (int i = 0; i < count; i++) {
+ QLayoutItem *item = findItemOfWidget(items, savedState[i]);
+ Q_ASSERT(item);
+ boxLayout->addItem(item);
+ }
+ }
+
+ // Grid Layout state. Datatype storing the state of a GridLayout as a map of
+ // widgets to QRect(columns, rows) and size. Used to store the state for undo operations
+ // that do not change the widgets within the layout; also provides some manipulation
+ // functions and ability to apply the state to a layout provided its widgets haven't changed.
+ struct GridLayoutState {
+ GridLayoutState();
+
+ void fromLayout(QGridLayout *l);
+ void applyToLayout(const QDesignerFormEditorInterface *core, QWidget *w) const;
+
+ void insertRow(int row);
+ void insertColumn(int column);
+
+ bool simplify(const QRect &r, bool testOnly);
+ void removeFreeRow(int row);
+ void removeFreeColumn(int column);
+
+
+ // State of a cell in one dimension
+ enum DimensionCellState {
+ Free,
+ Spanned, // Item spans it
+ Occupied // Item bordering on it
+ };
+ // Horiontal, Vertical pair of state
+ typedef QPair<DimensionCellState, DimensionCellState> CellState;
+ typedef QVector<CellState> CellStates;
+
+ // Figure out states of a cell and return as a flat vector of
+ // [column1, column2,...] (address as row * columnCount + col)
+ static CellStates cellStates(const QList<QRect> &rects, int numRows, int numColumns);
+
+ typedef QMap<QWidget *, QRect> WidgetItemMap;
+ typedef QMap<QWidget *, Qt::Alignment> WidgetAlignmentMap;
+
+ WidgetItemMap widgetItemMap;
+ WidgetAlignmentMap widgetAlignmentMap;
+
+ int rowCount;
+ int colCount;
+ };
+
+ static inline bool needsSpacerItem(const GridLayoutState::CellState &cs) {
+ return cs.first == GridLayoutState::Free && cs.second == GridLayoutState::Free;
+ }
+
+ static inline QDebug operator<<(QDebug str, const GridLayoutState &gs)
+ {
+ str << "GridLayoutState: " << gs.rowCount << " rows x " << gs.colCount
+ << " cols " << gs.widgetItemMap.size() << " items\n";
+
+ const GridLayoutState::WidgetItemMap::const_iterator wcend = gs.widgetItemMap.constEnd();
+ for (GridLayoutState::WidgetItemMap::const_iterator it = gs.widgetItemMap.constBegin(); it != wcend; ++it)
+ str << "Item " << it.key() << it.value() << '\n';
+ return str;
+ }
+
+ GridLayoutState::GridLayoutState() :
+ rowCount(0),
+ colCount(0)
+ {
+ }
+
+ GridLayoutState::CellStates GridLayoutState::cellStates(const QList<QRect> &rects, int numRows, int numColumns)
+ {
+ CellStates rc = CellStates(numRows * numColumns, CellState(Free, Free));
+ const QList<QRect>::const_iterator rcend = rects.constEnd();
+ for (QList<QRect>::const_iterator it = rects.constBegin(); it != rcend; ++it) {
+ const int leftColumn = it->x();
+ const int topRow = it->y();
+ const int rightColumn = leftColumn + it->width() - 1;
+ const int bottomRow = topRow + it->height() - 1;
+ for (int r = topRow; r <= bottomRow; r++)
+ for (int c = leftColumn; c <= rightColumn; c++) {
+ const int flatIndex = r * numColumns + c;
+ // Bordering horizontally?
+ DimensionCellState &horizState = rc[flatIndex].first;
+ if (c == leftColumn || c == rightColumn) {
+ horizState = Occupied;
+ } else {
+ if (horizState < Spanned)
+ horizState = Spanned;
+ }
+ // Bordering vertically?
+ DimensionCellState &vertState = rc[flatIndex].second;
+ if (r == topRow || r == bottomRow) {
+ vertState = Occupied;
+ } else {
+ if (vertState < Spanned)
+ vertState = Spanned;
+ }
+ }
+ }
+ if (debugLayout) {
+ qDebug() << "GridLayoutState::cellStates: " << numRows << " x " << numColumns;
+ for (int r = 0; r < numRows; r++)
+ for (int c = 0; c < numColumns; c++)
+ qDebug() << " Row: " << r << " column: " << c << rc[r * numColumns + c];
+ }
+ return rc;
+ }
+
+ void GridLayoutState::fromLayout(QGridLayout *l)
+ {
+ rowCount = l->rowCount();
+ colCount = l->columnCount();
+ const int count = l->count();
+ for (int i = 0; i < count; i++) {
+ QLayoutItem *item = l->itemAt(i);
+ if (!LayoutInfo::isEmptyItem(item)) {
+ widgetItemMap.insert(item->widget(), gridItemInfo(l, i));
+ if (item->alignment())
+ widgetAlignmentMap.insert(item->widget(), item->alignment());
+ }
+ }
+ }
+
+ void GridLayoutState::applyToLayout(const QDesignerFormEditorInterface *core, QWidget *w) const
+ {
+ typedef QMap<QLayoutItem *, QRect> LayoutItemRectMap;
+ QGridLayout *grid = qobject_cast<QGridLayout *>(LayoutInfo::managedLayout(core, w));
+ Q_ASSERT(grid);
+ if (debugLayout)
+ qDebug() << ">GridLayoutState::applyToLayout" << *this << *grid;
+ const bool shrink = grid->rowCount() > rowCount || grid->columnCount() > colCount;
+ // Build a map of existing items to rectangles via widget map, delete spacers
+ LayoutItemRectMap itemMap;
+ while (grid->count()) {
+ QLayoutItem *item = grid->takeAt(0);
+ if (!LayoutInfo::isEmptyItem(item)) {
+ QWidget *itemWidget = item->widget();
+ const WidgetItemMap::const_iterator it = widgetItemMap.constFind(itemWidget);
+ if (it == widgetItemMap.constEnd())
+ qFatal("GridLayoutState::applyToLayout: Attempt to apply to a layout that has a widget '%s'/'%s' added after saving the state.",
+ itemWidget->metaObject()->className(), itemWidget->objectName().toUtf8().constData());
+ itemMap.insert(item, it.value());
+ } else {
+ delete item;
+ }
+ }
+ Q_ASSERT(itemMap.size() == widgetItemMap.size());
+ // recreate if shrink
+ if (shrink)
+ grid = static_cast<QGridLayout*>(recreateManagedLayout(core, w, grid));
+
+ // Add widgets items
+ const LayoutItemRectMap::const_iterator icend = itemMap.constEnd();
+ for (LayoutItemRectMap::const_iterator it = itemMap.constBegin(); it != icend; ++it) {
+ const QRect info = it.value();
+ const Qt::Alignment alignment = widgetAlignmentMap.value(it.key()->widget(), Qt::Alignment(0));
+ grid->addItem(it.key(), info.y(), info.x(), info.height(), info.width(), alignment);
+ }
+ // create spacers
+ const CellStates cs = cellStates(itemMap.values(), rowCount, colCount);
+ for (int r = 0; r < rowCount; r++)
+ for (int c = 0; c < colCount; c++)
+ if (needsSpacerItem(cs[r * colCount + c]))
+ grid->addItem(createGridSpacer(), r, c);
+ grid->activate();
+ if (debugLayout)
+ qDebug() << "<GridLayoutState::applyToLayout" << *grid;
+ }
+
+ void GridLayoutState::insertRow(int row)
+ {
+ rowCount++;
+ const WidgetItemMap::iterator iend = widgetItemMap.end();
+ for (WidgetItemMap::iterator it = widgetItemMap.begin(); it != iend; ++it) {
+ const int topRow = it.value().y();
+ if (topRow >= row) {
+ it.value().translate(0, 1);
+ } else { //Over it: Does it span it -> widen?
+ const int rowSpan = it.value().height();
+ if (rowSpan > 1 && topRow + rowSpan > row)
+ it.value().setHeight(rowSpan + 1);
+ }
+ }
+ }
+
+ void GridLayoutState::insertColumn(int column)
+ {
+ colCount++;
+ const WidgetItemMap::iterator iend = widgetItemMap.end();
+ for (WidgetItemMap::iterator it = widgetItemMap.begin(); it != iend; ++it) {
+ const int leftColumn = it.value().x();
+ if (leftColumn >= column) {
+ it.value().translate(1, 0);
+ } else { // Left of it: Does it span it -> widen?
+ const int colSpan = it.value().width();
+ if (colSpan > 1 && leftColumn + colSpan > column)
+ it.value().setWidth(colSpan + 1);
+ }
+ }
+ }
+
+ // Simplify: Remove empty columns/rows and such ones that are only spanned (shrink
+ // spanning items).
+ // 'AB.C.' 'ABC'
+ // 'DDDD.' ==> 'DDD'
+ // 'EF.G.' 'EFG'
+ bool GridLayoutState::simplify(const QRect &r, bool testOnly)
+ {
+ // figure out free rows/columns.
+ QVector<bool> occupiedRows(rowCount, false);
+ QVector<bool> occupiedColumns(colCount, false);
+ // Mark everything outside restriction rectangle as occupied
+ const int restrictionLeftColumn = r.x();
+ const int restrictionRightColumn = restrictionLeftColumn + r.width();
+ const int restrictionTopRow = r.y();
+ const int restrictionBottomRow = restrictionTopRow + r.height();
+ if (restrictionLeftColumn > 0 || restrictionRightColumn < colCount ||
+ restrictionTopRow > 0 || restrictionBottomRow < rowCount) {
+ for (int r = 0; r < rowCount; r++)
+ if (r < restrictionTopRow || r >= restrictionBottomRow)
+ occupiedRows[r] = true;
+ for (int c = 0; c < colCount; c++)
+ if (c < restrictionLeftColumn || c >= restrictionRightColumn)
+ occupiedColumns[c] = true;
+ }
+ // figure out free fields and tick off occupied rows and columns
+ const CellStates cs = cellStates(widgetItemMap.values(), rowCount, colCount);
+ for (int r = 0; r < rowCount; r++)
+ for (int c = 0; c < colCount; c++) {
+ const CellState &state = cs[r * colCount + c];
+ if (state.first == Occupied)
+ occupiedColumns[c] = true;
+ if (state.second == Occupied)
+ occupiedRows[r] = true;
+ }
+ // Any free rows/columns?
+ if (occupiedRows.indexOf(false) == -1 && occupiedColumns.indexOf(false) == -1)
+ return false;
+ if (testOnly)
+ return true;
+ // remove rows
+ for (int r = rowCount - 1; r >= 0; r--)
+ if (!occupiedRows[r])
+ removeFreeRow(r);
+ // remove columns
+ for (int c = colCount - 1; c >= 0; c--)
+ if (!occupiedColumns[c])
+ removeFreeColumn(c);
+ return true;
+ }
+
+ void GridLayoutState::removeFreeRow(int removeRow)
+ {
+ const WidgetItemMap::iterator iend = widgetItemMap.end();
+ for (WidgetItemMap::iterator it = widgetItemMap.begin(); it != iend; ++it) {
+ const int r = it.value().y();
+ Q_ASSERT(r != removeRow); // Free rows only
+ if (r < removeRow) { // Does the item span it? - shrink it
+ const int rowSpan = it.value().height();
+ if (rowSpan > 1) {
+ const int bottomRow = r + rowSpan;
+ if (bottomRow > removeRow)
+ it.value().setHeight(rowSpan - 1);
+ }
+ } else
+ if (r > removeRow) // Item below it? - move.
+ it.value().translate(0, -1);
+ }
+ rowCount--;
+ }
+
+ void GridLayoutState::removeFreeColumn(int removeColumn)
+ {
+ const WidgetItemMap::iterator iend = widgetItemMap.end();
+ for (WidgetItemMap::iterator it = widgetItemMap.begin(); it != iend; ++it) {
+ const int c = it.value().x();
+ Q_ASSERT(c != removeColumn); // Free columns only
+ if (c < removeColumn) { // Does the item span it? - shrink it
+ const int colSpan = it.value().width();
+ if (colSpan > 1) {
+ const int rightColumn = c + colSpan;
+ if (rightColumn > removeColumn)
+ it.value().setWidth(colSpan - 1);
+ }
+ } else
+ if (c > removeColumn) // Item to the right of it? - move.
+ it.value().translate(-1, 0);
+ }
+ colCount--;
+ }
+
+ // ---------------- GridLayoutHelper
+ class GridLayoutHelper : public LayoutHelper {
+ public:
+ GridLayoutHelper() {}
+
+ virtual QRect itemInfo(QLayout *lt, int index) const;
+ virtual void insertWidget(QLayout *lt, const QRect &info, QWidget *w);
+ virtual void removeWidget(QLayout *lt, QWidget *widget);
+ virtual void replaceWidget(QLayout *lt, QWidget *before, QWidget *after);
+
+ virtual void pushState(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout);
+ virtual void popState(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout);
+
+ virtual bool canSimplify(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout, const QRect &restrictionArea) const;
+ virtual void simplify(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout, const QRect &restrictionArea);
+
+ static void insertRow(QGridLayout *grid, int row);
+
+ private:
+ QStack<GridLayoutState> m_states;
+ };
+
+ void GridLayoutHelper::insertRow(QGridLayout *grid, int row)
+ {
+ GridLayoutState state;
+ state.fromLayout(grid);
+ state.insertRow(row);
+ QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(grid);
+ state.applyToLayout(fw->core(), grid->parentWidget());
+ }
+
+ QRect GridLayoutHelper::itemInfo(QLayout * lt, int index) const
+ {
+ QGridLayout *grid = qobject_cast<QGridLayout *>(lt);
+ Q_ASSERT(grid);
+ return gridItemInfo(grid, index);
+ }
+
+ void GridLayoutHelper::insertWidget(QLayout *lt, const QRect &info, QWidget *w)
+ {
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ QGridLayout *gridLayout = qobject_cast<QGridLayout *>(lt);
+ Q_ASSERT(gridLayout);
+ // check if there are any items. Should be only spacers, else something is wrong
+ const int row = info.y();
+ int column = info.x();
+ int colSpan = info.width();
+ int rowSpan = info.height();
+ // If not empty: A multiselection was dropped on an empty item, insert row
+ // and spread items along new row
+ if (!removeEmptyCellsOnGrid(gridLayout, info)) {
+ int freeColumn = -1;
+ colSpan = rowSpan = 1;
+ // First look to the right for a free column
+ const int columnCount = gridLayout->columnCount();
+ for (int c = column; c < columnCount; c++) {
+ const int idx = findGridItemAt(gridLayout, row, c);
+ if (idx != -1 && LayoutInfo::isEmptyItem(gridLayout->itemAt(idx))) {
+ freeColumn = c;
+ break;
+ }
+ }
+ if (freeColumn != -1) {
+ removeEmptyCellsOnGrid(gridLayout, QRect(freeColumn, row, 1, 1));
+ column = freeColumn;
+ } else {
+ GridLayoutHelper::insertRow(gridLayout, row);
+ column = 0;
+ }
+ }
+ gridLayout->addWidget(w, row , column, rowSpan, colSpan);
+ }
+
+ void GridLayoutHelper::removeWidget(QLayout *lt, QWidget *widget)
+ {
+ QGridLayout *gridLayout = qobject_cast<QGridLayout *>(lt);
+ Q_ASSERT(gridLayout);
+ const int index = gridLayout->indexOf(widget);
+ if (index == -1) {
+ qWarning() << "GridLayoutHelper::removeWidget : Attempt to remove " << widget << " which is not in the layout.";
+ return;
+ }
+ // delete old item and pad with by spacer items
+ int row, column, rowspan, colspan;
+ gridLayout->getItemPosition(index, &row, &column, &rowspan, &colspan);
+ delete gridLayout->takeAt(index);
+ const int rightColumn = column + colspan;
+ const int bottomRow = row + rowspan;
+ for (int c = column; c < rightColumn; c++)
+ for (int r = row; r < bottomRow; r++)
+ gridLayout->addItem(createGridSpacer(), r, c);
+ }
+
+ void GridLayoutHelper::replaceWidget(QLayout *lt, QWidget *before, QWidget *after)
+ {
+ bool ok = false;
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ if (QGridLayout *gridLayout = qobject_cast<QGridLayout *>(lt)) {
+ const int index = gridLayout->indexOf(before);
+ if (index != -1) {
+ int row, column, rowSpan, columnSpan;
+ gridLayout->getItemPosition (index, &row, &column, &rowSpan, &columnSpan);
+ const bool visible = before->isVisible();
+ delete gridLayout->takeAt(index);
+ if (visible)
+ before->hide();
+ before->setParent(0);
+ gridLayout->addWidget(after, row, column, rowSpan, columnSpan);
+ ok = true;
+ }
+ }
+ if (!ok)
+ qWarning() << "GridLayoutHelper::replaceWidget : Unable to replace " << before << " by " << after << " in " << lt;
+ }
+
+ void GridLayoutHelper::pushState(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout)
+ {
+ QGridLayout *gridLayout = qobject_cast<QGridLayout *>(LayoutInfo::managedLayout(core, widgetWithManagedLayout));
+ Q_ASSERT(gridLayout);
+ GridLayoutState gs;
+ gs.fromLayout(gridLayout);
+ m_states.push(gs);
+ }
+
+ void GridLayoutHelper::popState(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout)
+ {
+ Q_ASSERT(!m_states.empty());
+ const GridLayoutState state = m_states.pop();
+ state.applyToLayout(core, widgetWithManagedLayout);
+ }
+
+ bool GridLayoutHelper::canSimplify(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout, const QRect &restrictionArea) const
+ {
+ QGridLayout *gridLayout = qobject_cast<QGridLayout *>(LayoutInfo::managedLayout(core, widgetWithManagedLayout));
+ Q_ASSERT(gridLayout);
+ GridLayoutState gs;
+ gs.fromLayout(gridLayout);
+ return gs.simplify(restrictionArea, true);
+ }
+
+ void GridLayoutHelper::simplify(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout, const QRect &restrictionArea)
+ {
+ QGridLayout *gridLayout = qobject_cast<QGridLayout *>(LayoutInfo::managedLayout(core, widgetWithManagedLayout));
+ Q_ASSERT(gridLayout);
+ if (debugLayout)
+ qDebug() << ">GridLayoutHelper::simplify" << *gridLayout;
+ GridLayoutState gs;
+ gs.fromLayout(gridLayout);
+ if (gs.simplify(restrictionArea, false))
+ gs.applyToLayout(core, widgetWithManagedLayout);
+ if (debugLayout)
+ qDebug() << "<GridLayoutHelper::simplify" << *gridLayout;
+ }
+
+ // ---------------- FormLayoutHelper
+ class FormLayoutHelper : public LayoutHelper {
+ public:
+ typedef QPair<QWidget *, QWidget *> WidgetPair;
+ typedef QVector<WidgetPair> FormLayoutState;
+
+ FormLayoutHelper() {}
+
+ virtual QRect itemInfo(QLayout *lt, int index) const;
+ virtual void insertWidget(QLayout *lt, const QRect &info, QWidget *w);
+ virtual void removeWidget(QLayout *lt, QWidget *widget);
+ virtual void replaceWidget(QLayout *lt, QWidget *before, QWidget *after);
+
+ virtual void pushState(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout);
+ virtual void popState(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout);
+
+ virtual bool canSimplify(const QDesignerFormEditorInterface *core, const QWidget *, const QRect &) const;
+ virtual void simplify(const QDesignerFormEditorInterface *, QWidget *, const QRect &);
+
+ private:
+ static FormLayoutState state(const QFormLayout *lt);
+
+ QStack<FormLayoutState> m_states;
+ };
+
+ QRect FormLayoutHelper::itemInfo(QLayout * lt, int index) const
+ {
+ QFormLayout *form = qobject_cast<QFormLayout *>(lt);
+ Q_ASSERT(form);
+ int row, column, colspan;
+ getFormLayoutItemPosition(form, index, &row, &column, 0, &colspan);
+ return QRect(column, row, colspan, 1);
+ }
+
+ void FormLayoutHelper::insertWidget(QLayout *lt, const QRect &info, QWidget *w)
+ {
+ if (debugLayout)
+ qDebug() << "FormLayoutHelper::insertWidget:" << w << info;
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ QFormLayout *formLayout = qobject_cast<QFormLayout *>(lt);
+ Q_ASSERT(formLayout);
+ // check if there are any nonspacer items? (Drop on 3rd column or drop of a multiselection
+ // on an empty item. As the Form layout does not have insert semantics; we need to manually insert a row
+ const bool insert = !removeEmptyCellsOnGrid(formLayout, info);
+ formLayoutAddWidget(formLayout, w, info, insert);
+ QLayoutSupport::createEmptyCells(formLayout);
+ }
+
+ void FormLayoutHelper::removeWidget(QLayout *lt, QWidget *widget)
+ {
+ QFormLayout *formLayout = qobject_cast<QFormLayout *>(lt);
+ Q_ASSERT(formLayout);
+ const int index = formLayout->indexOf(widget);
+ if (index == -1) {
+ qWarning() << "FormLayoutHelper::removeWidget : Attempt to remove " << widget << " which is not in the layout.";
+ return;
+ }
+ // delete old item and pad with by spacer items
+ int row, column, colspan;
+ getFormLayoutItemPosition(formLayout, index, &row, &column, 0, &colspan);
+ if (debugLayout)
+ qDebug() << "FormLayoutHelper::removeWidget: #" << index << widget << " at " << row << column << colspan;
+ delete formLayout->takeAt(index);
+ if (colspan > 1 || column == 0)
+ formLayout->setItem(row, QFormLayout::LabelRole, createFormSpacer());
+ if (colspan > 1 || column == 1)
+ formLayout->setItem(row, QFormLayout::FieldRole, createFormSpacer());
+ }
+
+ void FormLayoutHelper::replaceWidget(QLayout *lt, QWidget *before, QWidget *after)
+ {
+ bool ok = false;
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ if (QFormLayout *formLayout = qobject_cast<QFormLayout *>(lt)) {
+ const int index = formLayout->indexOf(before);
+ if (index != -1) {
+ int row;
+ QFormLayout::ItemRole role;
+ formLayout->getItemPosition (index, &row, &role);
+ const bool visible = before->isVisible();
+ delete formLayout->takeAt(index);
+ if (visible)
+ before->hide();
+ before->setParent(0);
+ formLayout->setWidget(row, role, after);
+ ok = true;
+ }
+ }
+ if (!ok)
+ qWarning() << "FormLayoutHelper::replaceWidget : Unable to replace " << before << " by " << after << " in " << lt;
+ }
+
+ FormLayoutHelper::FormLayoutState FormLayoutHelper::state(const QFormLayout *lt)
+ {
+ const int rowCount = lt->rowCount();
+ if (rowCount == 0)
+ return FormLayoutState();
+ FormLayoutState rc(rowCount, WidgetPair(0, 0));
+ const int count = lt->count();
+ int row, column, colspan;
+ for (int i = 0; i < count; i++) {
+ QLayoutItem *item = lt->itemAt(i);
+ if (!LayoutInfo::isEmptyItem(item)) {
+ QWidget *w = item->widget();
+ Q_ASSERT(w);
+ getFormLayoutItemPosition(lt, i, &row, &column, 0, &colspan);
+ if (colspan > 1 || column == 0)
+ rc[row].first = w;
+ if (colspan > 1 || column == 1)
+ rc[row].second = w;
+ }
+ }
+ if (debugLayout) {
+ qDebug() << "FormLayoutHelper::state: " << rowCount;
+ for (int r = 0; r < rowCount; r++)
+ qDebug() << " Row: " << r << rc[r].first << rc[r].second;
+ }
+ return rc;
+ }
+
+ void FormLayoutHelper::pushState(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout)
+ {
+ QFormLayout *formLayout = qobject_cast<QFormLayout *>(LayoutInfo::managedLayout(core, widgetWithManagedLayout));
+ Q_ASSERT(formLayout);
+ m_states.push(state(formLayout));
+ }
+
+ void FormLayoutHelper::popState(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout)
+ {
+ QFormLayout *formLayout = qobject_cast<QFormLayout *>(LayoutInfo::managedLayout(core, widgetWithManagedLayout));
+ Q_ASSERT(!m_states.empty() && formLayout);
+
+ const FormLayoutState storedState = m_states.pop();
+ const FormLayoutState currentState = state(formLayout);
+ if (currentState == storedState)
+ return;
+ const int rowCount = storedState.size();
+ // clear out, shrink if required, but maintain items via map, pad spacers
+ const BoxLayoutHelper::LayoutItemVector items = BoxLayoutHelper::disassembleLayout(formLayout);
+ if (rowCount < formLayout->rowCount())
+ formLayout = static_cast<QFormLayout*>(recreateManagedLayout(core, widgetWithManagedLayout, formLayout ));
+ for (int r = 0; r < rowCount; r++) {
+ QWidget *widgets[FormLayoutColumns] = { storedState[r].first, storedState[r].second };
+ const bool spanning = widgets[0] != 0 && widgets[0] == widgets[1];
+ if (spanning) {
+ formLayout->setWidget(r, QFormLayout::SpanningRole, widgets[0]);
+ } else {
+ for (int c = 0; c < FormLayoutColumns; c++) {
+ const QFormLayout::ItemRole role = c == 0 ? QFormLayout::LabelRole : QFormLayout::FieldRole;
+ if (widgets[c] && BoxLayoutHelper::findItemOfWidget(items, widgets[c])) {
+ formLayout->setWidget(r, role, widgets[c]);
+ } else {
+ formLayout->setItem(r, role, createFormSpacer());
+ }
+ }
+ }
+ }
+ }
+
+ bool FormLayoutHelper::canSimplify(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout, const QRect &restrictionArea) const
+ {
+ const QFormLayout *formLayout = qobject_cast<QFormLayout *>(LayoutInfo::managedLayout(core, widgetWithManagedLayout));
+ Q_ASSERT(formLayout);
+ return canSimplifyFormLayout(formLayout, restrictionArea);
+ }
+
+ void FormLayoutHelper::simplify(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout, const QRect &restrictionArea)
+ {
+ typedef QPair<QLayoutItem*, QLayoutItem*> LayoutItemPair;
+ typedef QVector<LayoutItemPair> LayoutItemPairs;
+
+ QFormLayout *formLayout = qobject_cast<QFormLayout *>(LayoutInfo::managedLayout(core, widgetWithManagedLayout));
+ Q_ASSERT(formLayout);
+ if (debugLayout)
+ qDebug() << "FormLayoutHelper::simplify";
+ // Transform into vector of item pairs
+ const int rowCount = formLayout->rowCount();
+ LayoutItemPairs pairs(rowCount, LayoutItemPair(0, 0));
+ for (int i = formLayout->count() - 1; i >= 0; i--) {
+ int row, col,colspan;
+ getFormLayoutItemPosition(formLayout, i, &row, &col, 0, &colspan);
+ if (colspan > 1) {
+ pairs[row].first = pairs[row].second = formLayout->takeAt(i);
+ } else {
+ if (col == 0)
+ pairs[row].first = formLayout->takeAt(i);
+ else
+ pairs[row].second = formLayout->takeAt(i);
+ }
+ }
+ // Weed out empty ones
+ const int bottomCheckRow = qMin(rowCount, restrictionArea.y() + restrictionArea.height());
+ for (int r = bottomCheckRow - 1; r >= restrictionArea.y(); r--)
+ if (LayoutInfo::isEmptyItem(pairs[r].first) && LayoutInfo::isEmptyItem(pairs[r].second)) {
+ delete pairs[r].first;
+ delete pairs[r].second;
+ pairs.remove(r);
+ }
+ const int simpleRowCount = pairs.size();
+ if (simpleRowCount < rowCount)
+ formLayout = static_cast<QFormLayout *>(recreateManagedLayout(core, widgetWithManagedLayout, formLayout));
+ // repopulate
+ for (int r = 0; r < simpleRowCount; r++) {
+ const bool spanning = pairs[r].first == pairs[r].second;
+ if (spanning) {
+ formLayout->setItem(r, QFormLayout::SpanningRole, pairs[r].first);
+ } else {
+ formLayout->setItem(r, QFormLayout::LabelRole, pairs[r].first);
+ formLayout->setItem(r, QFormLayout::FieldRole, pairs[r].second);
+ }
+ }
+ }
+
+LayoutHelper *LayoutHelper::createLayoutHelper(int type)
+{
+ LayoutHelper *rc = 0;
+ switch (type) {
+ case LayoutInfo::HBox:
+ rc = new BoxLayoutHelper(Qt::Horizontal);
+ break;
+ case LayoutInfo::VBox:
+ rc = new BoxLayoutHelper(Qt::Vertical);
+ break;
+ case LayoutInfo::Grid:
+ rc = new GridLayoutHelper;
+ break;
+ case LayoutInfo::Form:
+ return new FormLayoutHelper;
+ default:
+ break;
+ }
+ Q_ASSERT(rc);
+ return rc;
+}
+
+// ---- QLayoutSupport (LayoutDecorationExtension)
+QLayoutSupport::QLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, LayoutHelper *helper, QObject *parent) :
+ QObject(parent),
+ m_formWindow(formWindow),
+ m_helper(helper),
+ m_widget(widget),
+ m_currentIndex(-1),
+ m_currentInsertMode(QDesignerLayoutDecorationExtension::InsertWidgetMode)
+{
+}
+
+QLayout * QLayoutSupport::layout() const
+{
+ return LayoutInfo::managedLayout(m_formWindow->core(), m_widget);
+}
+
+void QLayoutSupport::hideIndicator(Indicator i)
+{
+ if (m_indicators[i])
+ m_indicators[i]->hide();
+}
+
+void QLayoutSupport::showIndicator(Indicator i, const QRect &geometry, const QPalette &p)
+{
+ if (!m_indicators[i])
+ m_indicators[i] = new qdesigner_internal::InvisibleWidget(m_widget);
+ QWidget *indicator = m_indicators[i];
+ indicator->setAutoFillBackground(true);
+ indicator->setPalette(p);
+ indicator->setGeometry(geometry);
+ indicator->show();
+ indicator->raise();
+}
+
+QLayoutSupport::~QLayoutSupport()
+{
+ delete m_helper;
+ for (int i = 0; i < NumIndicators; i++)
+ if (m_indicators[i])
+ m_indicators[i]->deleteLater();
+}
+
+QGridLayout * QLayoutSupport::gridLayout() const
+{
+ return qobject_cast<QGridLayout*>(LayoutInfo::managedLayout(m_formWindow->core(), m_widget));
+}
+
+QRect QLayoutSupport::itemInfo(int index) const
+{
+ return m_helper->itemInfo(LayoutInfo::managedLayout(m_formWindow->core(), m_widget), index);
+}
+
+void QLayoutSupport::setInsertMode(InsertMode im)
+{
+ m_currentInsertMode = im;
+}
+
+void QLayoutSupport::setCurrentCell(const QPair<int, int> &cell)
+{
+ m_currentCell = cell;
+}
+
+void QLayoutSupport::adjustIndicator(const QPoint &pos, int index)
+{
+ if (index == -1) { // first item goes anywhere
+ hideIndicator(LeftIndicator);
+ hideIndicator(TopIndicator);
+ hideIndicator(RightIndicator);
+ hideIndicator(BottomIndicator);
+ return;
+ }
+ m_currentIndex = index;
+ m_currentInsertMode = QDesignerLayoutDecorationExtension::InsertWidgetMode;
+
+ QLayoutItem *item = layout()->itemAt(index);
+ const QRect g = extendedGeometry(index);
+ // ### cleanup
+ if (LayoutInfo::isEmptyItem(item)) {
+ // Empty grid/form cell. Draw a rectangle
+ QPalette redPalette;
+ redPalette.setColor(QPalette::Window, Qt::red);
+
+ showIndicator(LeftIndicator, QRect(g.x(), g.y(), indicatorSize, g.height()), redPalette);
+ showIndicator(TopIndicator, QRect(g.x(), g.y(), g.width(), indicatorSize), redPalette);
+ showIndicator(RightIndicator, QRect(g.right(), g.y(), indicatorSize, g.height()), redPalette);
+ showIndicator(BottomIndicator, QRect(g.x(), g.bottom(), g.width(), indicatorSize), redPalette);
+ setCurrentCellFromIndicatorOnEmptyCell(m_currentIndex);
+ } else {
+ // Append/Insert. Draw a bar left/right or above/below
+ QPalette bluePalette;
+ bluePalette.setColor(QPalette::Window, Qt::blue);
+ hideIndicator(LeftIndicator);
+ hideIndicator(TopIndicator);
+
+ const int fromRight = g.right() - pos.x();
+ const int fromBottom = g.bottom() - pos.y();
+
+ const int fromLeft = pos.x() - g.x();
+ const int fromTop = pos.y() - g.y();
+
+ const int fromLeftRight = qMin(fromRight, fromLeft );
+ const int fromBottomTop = qMin(fromBottom, fromTop);
+
+ const Qt::Orientation indicatorOrientation = fromLeftRight < fromBottomTop ? Qt::Vertical : Qt::Horizontal;
+
+ if (supportsIndicatorOrientation(indicatorOrientation)) {
+ const QRect r(layout()->geometry().topLeft(), layout()->parentWidget()->size());
+ switch (indicatorOrientation) {
+ case Qt::Vertical: {
+ hideIndicator(BottomIndicator);
+ const bool closeToLeft = fromLeftRight == fromLeft;
+ showIndicator(RightIndicator, QRect(closeToLeft ? g.x() : g.right() + 1 - indicatorSize, 0, indicatorSize, r.height()), bluePalette);
+
+ const int incr = closeToLeft ? 0 : +1;
+ setCurrentCellFromIndicator(indicatorOrientation, m_currentIndex, incr);
+ }
+ break;
+ case Qt::Horizontal: {
+ hideIndicator(RightIndicator);
+ const bool closeToTop = fromBottomTop == fromTop;
+ showIndicator(BottomIndicator, QRect(r.x(), closeToTop ? g.y() : g.bottom() + 1 - indicatorSize, r.width(), indicatorSize), bluePalette);
+
+ const int incr = closeToTop ? 0 : +1;
+ setCurrentCellFromIndicator(indicatorOrientation, m_currentIndex, incr);
+ }
+ break;
+ }
+ } else {
+ hideIndicator(RightIndicator);
+ hideIndicator(BottomIndicator);
+ } // can handle indicatorOrientation
+ }
+}
+
+int QLayoutSupport::indexOf(QLayoutItem *i) const
+{
+ const QLayout *lt = layout();
+ if (!lt)
+ return -1;
+
+ int index = 0;
+
+ while (QLayoutItem *item = lt->itemAt(index)) {
+ if (item == i)
+ return index;
+
+ ++index;
+ }
+
+ return -1;
+}
+
+int QLayoutSupport::indexOf(QWidget *widget) const
+{
+ const QLayout *lt = layout();
+ if (!lt)
+ return -1;
+
+ int index = 0;
+ while (QLayoutItem *item = lt->itemAt(index)) {
+ if (item->widget() == widget)
+ return index;
+
+ ++index;
+ }
+
+ return -1;
+}
+
+QList<QWidget*> QLayoutSupport::widgets(QLayout *layout) const
+{
+ if (!layout)
+ return QList<QWidget*>();
+
+ QList<QWidget*> lst;
+ int index = 0;
+ while (QLayoutItem *item = layout->itemAt(index)) {
+ ++index;
+
+ QWidget *widget = item->widget();
+ if (widget && formWindow()->isManaged(widget))
+ lst.append(widget);
+ }
+
+ return lst;
+}
+
+int QLayoutSupport::findItemAt(QGridLayout *gridLayout, int at_row, int at_column)
+{
+ return findGridItemAt(gridLayout, at_row, at_column);
+}
+
+// Quick check whether simplify should be enabled for grids. May return false positives.
+// Note: Calculating the occupied area does not work as spanning items may also be simplified.
+
+bool QLayoutSupport::canSimplifyQuickCheck(const QGridLayout *gl)
+{
+ if (!gl)
+ return false;
+ const int colCount = gl->columnCount();
+ const int rowCount = gl->rowCount();
+ if (colCount < 2 || rowCount < 2)
+ return false;
+ // try to find a spacer.
+ const int count = gl->count();
+ for (int index = 0; index < count; index++)
+ if (LayoutInfo::isEmptyItem(gl->itemAt(index)))
+ return true;
+ return false;
+}
+
+bool QLayoutSupport::canSimplifyQuickCheck(const QFormLayout *fl)
+{
+ return canSimplifyFormLayout(fl, QRect(QPoint(0, 0), QSize(32767, 32767)));
+}
+
+// remove dummy spacers
+bool QLayoutSupport::removeEmptyCells(QGridLayout *grid, const QRect &area)
+{
+ return removeEmptyCellsOnGrid(grid, area);
+}
+
+void QLayoutSupport::createEmptyCells(QGridLayout *gridLayout)
+{
+ Q_ASSERT(gridLayout);
+ GridLayoutState gs;
+ gs.fromLayout(gridLayout);
+
+ const GridLayoutState::CellStates cs = GridLayoutState::cellStates(gs.widgetItemMap.values(), gs.rowCount, gs.colCount);
+ for (int c = 0; c < gs.colCount; c++)
+ for (int r = 0; r < gs.rowCount; r++)
+ if (needsSpacerItem(cs[r * gs.colCount + c])) {
+ const int existingItemIndex = findItemAt(gridLayout, r, c);
+ if (existingItemIndex == -1)
+ gridLayout->addItem(createGridSpacer(), r, c);
+ }
+}
+
+bool QLayoutSupport::removeEmptyCells(QFormLayout *formLayout, const QRect &area)
+{
+ return removeEmptyCellsOnGrid(formLayout, area);
+}
+
+void QLayoutSupport::createEmptyCells(QFormLayout *formLayout)
+{
+ // No spanning items here..
+ if (const int rowCount = formLayout->rowCount())
+ for (int c = 0; c < FormLayoutColumns; c++)
+ for (int r = 0; r < rowCount; r++)
+ if (findGridItemAt(formLayout, r, c) == -1)
+ formLayout->setItem(r, c == 0 ? QFormLayout::LabelRole : QFormLayout::FieldRole, createFormSpacer());
+}
+
+int QLayoutSupport::findItemAt(const QPoint &pos) const
+{
+ if (!layout())
+ return -1;
+
+ const QLayout *lt = layout();
+ const int count = lt->count();
+
+ if (count == 0)
+ return -1;
+
+ int best = -1;
+ int bestIndex = -1;
+
+ for (int index = 0; index < count; index++) {
+ QLayoutItem *item = lt->itemAt(index);
+ bool visible = true;
+ // When dragging widgets within layout, the source widget is invisible and must not be hit
+ if (const QWidget *w = item->widget())
+ visible = w->isVisible();
+ if (visible) {
+ const QRect g = item->geometry();
+
+ const int dist = (g.center() - pos).manhattanLength();
+ if (best == -1 || dist < best) {
+ best = dist;
+ bestIndex = index;
+ }
+ }
+ }
+ return bestIndex;
+}
+
+// ------------ QBoxLayoutSupport (LayoutDecorationExtension)
+namespace {
+class QBoxLayoutSupport: public QLayoutSupport
+{
+public:
+ QBoxLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, Qt::Orientation orientation, QObject *parent = 0);
+
+ virtual void insertWidget(QWidget *widget, const QPair<int, int> &cell);
+ virtual void removeWidget(QWidget *widget);
+ virtual void simplify() {}
+ virtual void insertRow(int /*row*/) {}
+ virtual void insertColumn(int /*column*/) {}
+
+ virtual int findItemAt(int /*at_row*/, int /*at_column*/) const { return -1; }
+
+private:
+ virtual void setCurrentCellFromIndicatorOnEmptyCell(int index);
+ virtual void setCurrentCellFromIndicator(Qt::Orientation indicatorOrientation, int index, int increment);
+ virtual bool supportsIndicatorOrientation(Qt::Orientation indicatorOrientation) const;
+ virtual QRect extendedGeometry(int index) const;
+
+ const Qt::Orientation m_orientation;
+};
+
+void QBoxLayoutSupport::removeWidget(QWidget *widget)
+{
+ QLayout *lt = layout();
+ const int index = lt->indexOf(widget);
+ // Adjust the current cell in case a widget was dragged within the same layout to a position
+ // of higher index, which happens as follows:
+ // Drag start: The widget is hidden
+ // Drop: Current cell is stored, widget is removed and re-added, causing an index offset that needs to be compensated
+ QPair<int, int> currCell = currentCell();
+ switch (m_orientation) {
+ case Qt::Horizontal:
+ if (currCell.second > 0 && index < currCell.second ) {
+ currCell.second--;
+ setCurrentCell(currCell);
+ }
+ break;
+ case Qt::Vertical:
+ if (currCell.first > 0 && index < currCell.first) {
+ currCell.first--;
+ setCurrentCell(currCell);
+ }
+ break;
+ }
+ helper()->removeWidget(lt, widget);
+}
+
+QBoxLayoutSupport::QBoxLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, Qt::Orientation orientation, QObject *parent) :
+ QLayoutSupport(formWindow, widget, new BoxLayoutHelper(orientation), parent),
+ m_orientation(orientation)
+{
+}
+
+void QBoxLayoutSupport::setCurrentCellFromIndicatorOnEmptyCell(int index)
+{
+ qDebug() << "QBoxLayoutSupport::setCurrentCellFromIndicatorOnEmptyCell(): Warning: found a fake spacer inside a vbox layout at " << index;
+ setCurrentCell(qMakePair(0, 0));
+}
+
+void QBoxLayoutSupport::insertWidget(QWidget *widget, const QPair<int, int> &cell)
+{
+ switch (m_orientation) {
+ case Qt::Horizontal:
+ helper()->insertWidget(layout(), QRect(cell.second, 0, 1, 1), widget);
+ break;
+ case Qt::Vertical:
+ helper()->insertWidget(layout(), QRect(0, cell.first, 1, 1), widget);
+ break;
+ }
+}
+
+void QBoxLayoutSupport::setCurrentCellFromIndicator(Qt::Orientation indicatorOrientation, int index, int increment)
+{
+ if (m_orientation == Qt::Horizontal && indicatorOrientation == Qt::Vertical) {
+ setCurrentCell(qMakePair(0, index + increment));
+ } else if (m_orientation == Qt::Vertical && indicatorOrientation == Qt::Horizontal) {
+ setCurrentCell(qMakePair(index + increment, 0));
+ }
+}
+
+bool QBoxLayoutSupport::supportsIndicatorOrientation(Qt::Orientation indicatorOrientation) const
+{
+ return m_orientation != indicatorOrientation;
+}
+
+QRect QBoxLayoutSupport::extendedGeometry(int index) const
+{
+ QLayoutItem *item = layout()->itemAt(index);
+ // start off with item geometry
+ QRect g = item->geometry();
+
+ const QRect info = itemInfo(index);
+
+ // On left border: extend to widget border
+ if (info.x() == 0) {
+ QPoint topLeft = g.topLeft();
+ topLeft.rx() = layout()->geometry().left();
+ g.setTopLeft(topLeft);
+ }
+
+ // On top border: extend to widget border
+ if (info.y() == 0) {
+ QPoint topLeft = g.topLeft();
+ topLeft.ry() = layout()->geometry().top();
+ g.setTopLeft(topLeft);
+ }
+
+ // is this the last item?
+ const QBoxLayout *box = static_cast<const QBoxLayout*>(layout());
+ if (index < box->count() -1)
+ return g; // Nope.
+
+ // extend to widget border
+ QPoint bottomRight = g.bottomRight();
+ switch (m_orientation) {
+ case Qt::Vertical:
+ bottomRight.ry() = layout()->geometry().bottom();
+ break;
+ case Qt::Horizontal:
+ bottomRight.rx() = layout()->geometry().right();
+ break;
+ }
+ g.setBottomRight(bottomRight);
+ return g;
+}
+
+// -------------- Base class for QGridLayout-like support classes (LayoutDecorationExtension)
+template <class GridLikeLayout>
+class GridLikeLayoutSupportBase: public QLayoutSupport
+{
+public:
+
+ GridLikeLayoutSupportBase(QDesignerFormWindowInterface *formWindow, QWidget *widget, LayoutHelper *helper, QObject *parent = 0) :
+ QLayoutSupport(formWindow, widget, helper, parent) {}
+
+ void insertWidget(QWidget *widget, const QPair<int, int> &cell);
+ virtual void removeWidget(QWidget *widget) { helper()->removeWidget(layout(), widget); }
+ virtual int findItemAt(int row, int column) const;
+
+protected:
+ GridLikeLayout *gridLikeLayout() const {
+ return qobject_cast<GridLikeLayout*>(LayoutInfo::managedLayout(formWindow()->core(), widget()));
+ }
+
+private:
+
+ virtual void setCurrentCellFromIndicatorOnEmptyCell(int index);
+ virtual void setCurrentCellFromIndicator(Qt::Orientation indicatorOrientation, int index, int increment);
+ virtual bool supportsIndicatorOrientation(Qt::Orientation) const { return true; }
+
+ virtual QRect extendedGeometry(int index) const;
+
+ // Overwrite to check the insertion position (if there are limits)
+ virtual void checkCellForInsertion(int * /*row*/, int * /*col*/) const {}
+};
+
+template <class GridLikeLayout>
+void GridLikeLayoutSupportBase<GridLikeLayout>::setCurrentCellFromIndicatorOnEmptyCell(int index)
+{
+ GridLikeLayout *grid = gridLikeLayout();
+ Q_ASSERT(grid);
+
+ setInsertMode(InsertWidgetMode);
+ int row, column, rowspan, colspan;
+
+ getGridItemPosition(grid, index, &row, &column, &rowspan, &colspan);
+ setCurrentCell(qMakePair(row, column));
+}
+
+template <class GridLikeLayout>
+void GridLikeLayoutSupportBase<GridLikeLayout>::setCurrentCellFromIndicator(Qt::Orientation indicatorOrientation, int index, int increment) {
+ const QRect info = itemInfo(index);
+ switch (indicatorOrientation) {
+ case Qt::Vertical: {
+ setInsertMode(InsertColumnMode);
+ int row = info.top();
+ int column = increment ? info.right() + 1 : info.left();
+ checkCellForInsertion(&row, &column);
+ setCurrentCell(qMakePair(row , column));
+ }
+ break;
+ case Qt::Horizontal: {
+ setInsertMode(InsertRowMode);
+ int row = increment ? info.bottom() + 1 : info.top();
+ int column = info.left();
+ checkCellForInsertion(&row, &column);
+ setCurrentCell(qMakePair(row, column));
+ }
+ break;
+ }
+}
+
+template <class GridLikeLayout>
+void GridLikeLayoutSupportBase<GridLikeLayout>::insertWidget(QWidget *widget, const QPair<int, int> &cell)
+{
+ helper()->insertWidget(layout(), QRect(cell.second, cell.first, 1, 1), widget);
+}
+
+template <class GridLikeLayout>
+int GridLikeLayoutSupportBase<GridLikeLayout>::findItemAt(int at_row, int at_column) const
+{
+ GridLikeLayout *grid = gridLikeLayout();
+ Q_ASSERT(grid);
+ return findGridItemAt(grid, at_row, at_column);
+}
+
+template <class GridLikeLayout>
+QRect GridLikeLayoutSupportBase<GridLikeLayout>::extendedGeometry(int index) const
+{
+ QLayoutItem *item = layout()->itemAt(index);
+ // start off with item geometry
+ QRect g = item->geometry();
+
+ const QRect info = itemInfo(index);
+
+ // On left border: extend to widget border
+ if (info.x() == 0) {
+ QPoint topLeft = g.topLeft();
+ topLeft.rx() = layout()->geometry().left();
+ g.setTopLeft(topLeft);
+ }
+
+ // On top border: extend to widget border
+ if (info.y() == 0) {
+ QPoint topLeft = g.topLeft();
+ topLeft.ry() = layout()->geometry().top();
+ g.setTopLeft(topLeft);
+ }
+ const GridLikeLayout *grid = gridLikeLayout();
+ Q_ASSERT(grid);
+
+ // extend to widget border
+ QPoint bottomRight = g.bottomRight();
+ if (gridRowCount(grid) == info.y())
+ bottomRight.ry() = layout()->geometry().bottom();
+ if (gridColumnCount(grid) == info.x())
+ bottomRight.rx() = layout()->geometry().right();
+ g.setBottomRight(bottomRight);
+ return g;
+}
+
+// -------------- QGridLayoutSupport (LayoutDecorationExtension)
+class QGridLayoutSupport: public GridLikeLayoutSupportBase<QGridLayout>
+{
+public:
+
+ QGridLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, QObject *parent = 0);
+
+ virtual void simplify();
+ virtual void insertRow(int row);
+ virtual void insertColumn(int column);
+
+private:
+};
+
+QGridLayoutSupport::QGridLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, QObject *parent) :
+ GridLikeLayoutSupportBase<QGridLayout>(formWindow, widget, new GridLayoutHelper, parent)
+{
+}
+
+void QGridLayoutSupport::insertRow(int row)
+{
+ QGridLayout *grid = gridLayout();
+ Q_ASSERT(grid);
+ GridLayoutHelper::insertRow(grid, row);
+}
+
+void QGridLayoutSupport::insertColumn(int column)
+{
+ QGridLayout *grid = gridLayout();
+ Q_ASSERT(grid);
+ GridLayoutState state;
+ state.fromLayout(grid);
+ state.insertColumn(column);
+ state.applyToLayout(formWindow()->core(), widget());
+}
+
+void QGridLayoutSupport::simplify()
+{
+ QGridLayout *grid = gridLayout();
+ Q_ASSERT(grid);
+ GridLayoutState state;
+ state.fromLayout(grid);
+
+ const QRect fullArea = QRect(0, 0, state.colCount, state.rowCount);
+ if (state.simplify(fullArea, false))
+ state.applyToLayout(formWindow()->core(), widget());
+}
+
+// -------------- QFormLayoutSupport (LayoutDecorationExtension)
+class QFormLayoutSupport: public GridLikeLayoutSupportBase<QFormLayout>
+{
+public:
+ QFormLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, QObject *parent = 0);
+
+ virtual void simplify() {}
+ virtual void insertRow(int /*row*/) {}
+ virtual void insertColumn(int /*column*/) {}
+
+private:
+ virtual void checkCellForInsertion(int * row, int *col) const;
+};
+
+QFormLayoutSupport::QFormLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, QObject *parent) :
+ GridLikeLayoutSupportBase<QFormLayout>(formWindow, widget, new FormLayoutHelper, parent)
+{
+}
+
+void QFormLayoutSupport::checkCellForInsertion(int *row, int *col) const
+{
+ if (*col >= FormLayoutColumns) { // Clamp to 2 columns
+ *col = 1;
+ (*row)++;
+ }
+}
+} // anonymous namespace
+
+QLayoutSupport *QLayoutSupport::createLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, QObject *parent)
+{
+ const QLayout *layout = LayoutInfo::managedLayout(formWindow->core(), widget);
+ Q_ASSERT(layout);
+ QLayoutSupport *rc = 0;
+ switch (LayoutInfo::layoutType(formWindow->core(), layout)) {
+ case LayoutInfo::HBox:
+ rc = new QBoxLayoutSupport(formWindow, widget, Qt::Horizontal, parent);
+ break;
+ case LayoutInfo::VBox:
+ rc = new QBoxLayoutSupport(formWindow, widget, Qt::Vertical, parent);
+ break;
+ case LayoutInfo::Grid:
+ rc = new QGridLayoutSupport(formWindow, widget, parent);
+ break;
+ case LayoutInfo::Form:
+ rc = new QFormLayoutSupport(formWindow, widget, parent);
+ break;
+ default:
+ break;
+ }
+ Q_ASSERT(rc);
+ return rc;
+}
+} // namespace qdesigner_internal
+
+// -------------- QLayoutWidget
+QLayoutWidget::QLayoutWidget(QDesignerFormWindowInterface *formWindow, QWidget *parent)
+ : QWidget(parent), m_formWindow(formWindow),
+ m_leftMargin(0), m_topMargin(0), m_rightMargin(0), m_bottomMargin(0)
+{
+}
+
+void QLayoutWidget::paintEvent(QPaintEvent*)
+{
+ if (m_formWindow->currentTool() != 0)
+ return;
+
+ // only draw red borders if we're editting widgets
+
+ QPainter p(this);
+
+ QMap<int, QMap<int, bool> > excludedRowsForColumn;
+ QMap<int, QMap<int, bool> > excludedColumnsForRow;
+
+ QLayout *lt = layout();
+ QGridLayout *grid = qobject_cast<QGridLayout *>(lt);
+ if (lt) {
+ if (const int count = lt->count()) {
+ p.setPen(QPen(QColor(255, 0, 0, 35), 1));
+ for (int i = 0; i < count; i++) {
+ QLayoutItem *item = lt->itemAt(i);
+ if (grid) {
+ int row, column, rowSpan, columnSpan;
+ grid->getItemPosition(i, &row, &column, &rowSpan, &columnSpan);
+ QMap<int, bool> rows;
+ QMap<int, bool> columns;
+ for (int i = rowSpan; i > 1; i--)
+ rows[row + i - 2] = true;
+ for (int i = columnSpan; i > 1; i--)
+ columns[column + i - 2] = true;
+
+ while (rowSpan > 0) {
+ excludedColumnsForRow[row + rowSpan - 1].unite(columns);
+ rowSpan--;
+ }
+ while (columnSpan > 0) {
+ excludedRowsForColumn[column + columnSpan - 1].unite(rows);
+ columnSpan--;
+ }
+ }
+ if (item->spacerItem()) {
+ const QRect geometry = item->geometry();
+ if (!geometry.isNull())
+ p.drawRect(geometry.adjusted(1, 1, -2, -2));
+ }
+ }
+ }
+ }
+ if (grid) {
+ p.setPen(QPen(QColor(0, 0x80, 0, 0x80), 1));
+ const int rowCount = grid->rowCount();
+ const int columnCount = grid->columnCount();
+ for (int i = 0; i < rowCount; i++) {
+ for (int j = 0; j < columnCount; j++) {
+ const QRect cellRect = grid->cellRect(i, j);
+ if (j < columnCount - 1 && excludedColumnsForRow.value(i).value(j, false) == false) {
+ const double y0 = (i == 0)
+ ? 0 : (grid->cellRect(i - 1, j).bottom() + cellRect.top()) / 2.0;
+ const double y1 = (i == rowCount - 1)
+ ? height() - 1 : (cellRect.bottom() + grid->cellRect(i + 1, j).top()) / 2.0;
+ const double x = (cellRect.right() + grid->cellRect(i, j + 1).left()) / 2.0;
+ p.drawLine(QPointF(x, y0), QPointF(x, y1));
+ }
+ if (i < rowCount - 1 && excludedRowsForColumn.value(j).value(i, false) == false) {
+ const double x0 = (j == 0)
+ ? 0 : (grid->cellRect(i, j - 1).right() + cellRect.left()) / 2.0;
+ const double x1 = (j == columnCount - 1)
+ ? width() - 1 : (cellRect.right() + grid->cellRect(i, j + 1).left()) / 2.0;
+ const double y = (cellRect.bottom() + grid->cellRect(i + 1, j).top()) / 2.0;
+ p.drawLine(QPointF(x0, y), QPointF(x1, y));
+ }
+ }
+ }
+ }
+ p.setPen(QPen(QColor(255, 0, 0, 128), 1));
+ p.drawRect(0, 0, width() - 1, height() - 1);
+}
+
+bool QLayoutWidget::event(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::LayoutRequest: {
+ (void) QWidget::event(e);
+ // Magic: We are layouted, but the parent is not..
+ if (layout() && qdesigner_internal::LayoutInfo::layoutType(formWindow()->core(), parentWidget()) == qdesigner_internal::LayoutInfo::NoLayout) {
+ resize(layout()->totalMinimumSize().expandedTo(size()));
+ }
+
+ update();
+
+ return true;
+ }
+
+ default:
+ break;
+ }
+
+ return QWidget::event(e);
+}
+
+int QLayoutWidget::layoutLeftMargin() const
+{
+ if (m_leftMargin < 0 && layout()) {
+ int margin;
+ layout()->getContentsMargins(&margin, 0, 0, 0);
+ return margin;
+ }
+ return m_leftMargin;
+}
+
+void QLayoutWidget::setLayoutLeftMargin(int layoutMargin)
+{
+ m_leftMargin = layoutMargin;
+ if (layout()) {
+ int newMargin = m_leftMargin;
+ if (newMargin >= 0 && newMargin < ShiftValue)
+ newMargin = ShiftValue;
+ int left, top, right, bottom;
+ layout()->getContentsMargins(&left, &top, &right, &bottom);
+ layout()->setContentsMargins(newMargin, top, right, bottom);
+ }
+}
+
+int QLayoutWidget::layoutTopMargin() const
+{
+ if (m_topMargin < 0 && layout()) {
+ int margin;
+ layout()->getContentsMargins(0, &margin, 0, 0);
+ return margin;
+ }
+ return m_topMargin;
+}
+
+void QLayoutWidget::setLayoutTopMargin(int layoutMargin)
+{
+ m_topMargin = layoutMargin;
+ if (layout()) {
+ int newMargin = m_topMargin;
+ if (newMargin >= 0 && newMargin < ShiftValue)
+ newMargin = ShiftValue;
+ int left, top, right, bottom;
+ layout()->getContentsMargins(&left, &top, &right, &bottom);
+ layout()->setContentsMargins(left, newMargin, right, bottom);
+ }
+}
+
+int QLayoutWidget::layoutRightMargin() const
+{
+ if (m_rightMargin < 0 && layout()) {
+ int margin;
+ layout()->getContentsMargins(0, 0, &margin, 0);
+ return margin;
+ }
+ return m_rightMargin;
+}
+
+void QLayoutWidget::setLayoutRightMargin(int layoutMargin)
+{
+ m_rightMargin = layoutMargin;
+ if (layout()) {
+ int newMargin = m_rightMargin;
+ if (newMargin >= 0 && newMargin < ShiftValue)
+ newMargin = ShiftValue;
+ int left, top, right, bottom;
+ layout()->getContentsMargins(&left, &top, &right, &bottom);
+ layout()->setContentsMargins(left, top, newMargin, bottom);
+ }
+}
+
+int QLayoutWidget::layoutBottomMargin() const
+{
+ if (m_bottomMargin < 0 && layout()) {
+ int margin;
+ layout()->getContentsMargins(0, 0, 0, &margin);
+ return margin;
+ }
+ return m_bottomMargin;
+}
+
+void QLayoutWidget::setLayoutBottomMargin(int layoutMargin)
+{
+ m_bottomMargin = layoutMargin;
+ if (layout()) {
+ int newMargin = m_bottomMargin;
+ if (newMargin >= 0 && newMargin < ShiftValue)
+ newMargin = ShiftValue;
+ int left, top, right, bottom;
+ layout()->getContentsMargins(&left, &top, &right, &bottom);
+ layout()->setContentsMargins(left, top, right, newMargin);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qlayout_widget_p.h b/src/designer/src/lib/shared/qlayout_widget_p.h
new file mode 100644
index 000000000..a87679e75
--- /dev/null
+++ b/src/designer/src/lib/shared/qlayout_widget_p.h
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QLAYOUT_WIDGET_H
+#define QLAYOUT_WIDGET_H
+
+#include "shared_global_p.h"
+
+#include <QtDesigner/QDesignerLayoutDecorationExtension>
+
+#include <QtCore/QPointer>
+#include <QtCore/QVariant>
+#include <QtGui/QWidget>
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+class QGridLayout;
+class QFormLayout;
+
+namespace qdesigner_internal {
+// ---- LayoutProperties: Helper struct that stores all layout-relevant properties
+// with functions to retrieve and apply to property sheets. Can be used to store the state
+// for undo commands and while rebuilding layouts.
+struct QDESIGNER_SHARED_EXPORT LayoutProperties
+{
+ LayoutProperties();
+ void clear();
+
+ enum Margins { LeftMargin, TopMargin, RightMargin, BottomMargin, MarginCount };
+ enum Spacings { Spacing, HorizSpacing, VertSpacing, SpacingsCount };
+
+ enum PropertyMask {
+ ObjectNameProperty = 0x1,
+ LeftMarginProperty = 0x2, TopMarginProperty = 0x4, RightMarginProperty = 0x8, BottomMarginProperty = 0x10,
+ SpacingProperty = 0x20, HorizSpacingProperty = 0x40, VertSpacingProperty = 0x80,
+ SizeConstraintProperty = 0x100,
+ FieldGrowthPolicyProperty = 0x200, RowWrapPolicyProperty = 0x400, LabelAlignmentProperty = 0x0800, FormAlignmentProperty = 0x1000,
+ BoxStretchProperty = 0x2000, GridRowStretchProperty = 0x4000, GridColumnStretchProperty = 0x8000,
+ GridRowMinimumHeightProperty = 0x10000, GridColumnMinimumWidthProperty = 0x20000,
+ AllProperties = 0xFFFF};
+
+ // return a PropertyMask of visible properties
+ static int visibleProperties(const QLayout *layout);
+
+ // Retrieve from /apply to sheet: A property mask is returned indicating the properties found in the sheet
+ int fromPropertySheet(const QDesignerFormEditorInterface *core, QLayout *l, int mask = AllProperties);
+ int toPropertySheet(const QDesignerFormEditorInterface *core, QLayout *l, int mask = AllProperties, bool applyChanged = true) const;
+
+ int m_margins[MarginCount];
+ bool m_marginsChanged[MarginCount];
+
+ int m_spacings[SpacingsCount];
+ bool m_spacingsChanged[SpacingsCount];
+
+ QVariant m_objectName; // receives a PropertySheetStringValue
+ bool m_objectNameChanged;
+ QVariant m_sizeConstraint;
+ bool m_sizeConstraintChanged;
+
+ bool m_fieldGrowthPolicyChanged;
+ QVariant m_fieldGrowthPolicy;
+ bool m_rowWrapPolicyChanged;
+ QVariant m_rowWrapPolicy;
+ bool m_labelAlignmentChanged;
+ QVariant m_labelAlignment;
+ bool m_formAlignmentChanged;
+ QVariant m_formAlignment;
+
+ bool m_boxStretchChanged;
+ QVariant m_boxStretch;
+
+ bool m_gridRowStretchChanged;
+ QVariant m_gridRowStretch;
+
+ bool m_gridColumnStretchChanged;
+ QVariant m_gridColumnStretch;
+
+ bool m_gridRowMinimumHeightChanged;
+ QVariant m_gridRowMinimumHeight;
+
+ bool m_gridColumnMinimumWidthChanged;
+ QVariant m_gridColumnMinimumWidth;
+};
+
+// -- LayoutHelper: For use with the 'insert widget'/'delete widget' command,
+// able to store and restore states.
+// This could become part of 'QDesignerLayoutDecorationExtensionV2',
+// but to keep any existing old extensions working, it is provided as
+// separate class with a factory function.
+class LayoutHelper {
+protected:
+ LayoutHelper();
+
+public:
+ virtual ~LayoutHelper();
+
+ static LayoutHelper *createLayoutHelper(int type);
+
+ static int indexOf(const QLayout *lt, const QWidget *widget);
+
+ // Return area of an item (x == columns)
+ QRect itemInfo(QLayout *lt, const QWidget *widget) const;
+
+ virtual QRect itemInfo(QLayout *lt, int index) const = 0;
+ virtual void insertWidget(QLayout *lt, const QRect &info, QWidget *w) = 0;
+ virtual void removeWidget(QLayout *lt, QWidget *widget) = 0;
+ // Since 4.5: The 'morphing' feature requires an API for replacing widgets on layouts.
+ virtual void replaceWidget(QLayout *lt, QWidget *before, QWidget *after) = 0;
+
+ // Simplify a grid, remove empty columns, rows within the rectangle
+ // The DeleteWidget command restricts the area to be simplified.
+ virtual bool canSimplify(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout, const QRect &restrictionArea) const = 0;
+ virtual void simplify(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout, const QRect &restrictionArea) = 0;
+
+ // Push and pop a state. Can be used for implementing undo for
+ // simplify/row, column insertion commands, provided that
+ // the widgets remain the same.
+ virtual void pushState(const QDesignerFormEditorInterface *core, const QWidget *widgetWithManagedLayout) = 0;
+ virtual void popState(const QDesignerFormEditorInterface *core, QWidget *widgetWithManagedLayout) = 0;
+};
+
+// Base class for layout decoration extensions.
+class QDESIGNER_SHARED_EXPORT QLayoutSupport: public QObject, public QDesignerLayoutDecorationExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerLayoutDecorationExtension)
+
+protected:
+ QLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, LayoutHelper *helper, QObject *parent = 0);
+
+public:
+ virtual ~QLayoutSupport();
+
+ inline QDesignerFormWindowInterface *formWindow() const { return m_formWindow; }
+
+ // DecorationExtension V2
+ LayoutHelper* helper() const { return m_helper; }
+
+ // DecorationExtension
+ virtual int currentIndex() const { return m_currentIndex; }
+
+ virtual InsertMode currentInsertMode() const { return m_currentInsertMode; }
+
+ virtual QPair<int, int> currentCell() const { return m_currentCell; }
+
+ virtual int findItemAt(const QPoint &pos) const;
+ virtual int indexOf(QWidget *widget) const;
+ virtual int indexOf(QLayoutItem *item) const;
+
+ virtual void adjustIndicator(const QPoint &pos, int index);
+
+ virtual QList<QWidget*> widgets(QLayout *layout) const;
+
+ // Pad empty cells with dummy spacers. Called by layouting commands.
+ static void createEmptyCells(QGridLayout *gridLayout);
+ // remove dummy spacers in the area. Returns false if there are non-empty items in the way
+ static bool removeEmptyCells(QGridLayout *gridLayout, const QRect &area);
+ static void createEmptyCells(QFormLayout *formLayout); // ditto.
+ static bool removeEmptyCells(QFormLayout *formLayout, const QRect &area);
+
+ // grid helpers: find item index
+ static int findItemAt(QGridLayout *, int row, int column);
+ // grid helpers: Quick check whether simplify should be enabled for grids. May return false positives.
+ static bool canSimplifyQuickCheck(const QGridLayout *);
+ static bool canSimplifyQuickCheck(const QFormLayout *fl);
+ // Factory function, create layout support according to layout type of widget
+ static QLayoutSupport *createLayoutSupport(QDesignerFormWindowInterface *formWindow, QWidget *widget, QObject *parent = 0);
+
+protected:
+ // figure out insertion position and mode from indicator on empty cell if supported
+ virtual void setCurrentCellFromIndicatorOnEmptyCell(int index) = 0;
+ // figure out insertion position and mode from indicator
+ virtual void setCurrentCellFromIndicator(Qt::Orientation indicatorOrientation, int index, int increment) = 0;
+
+ // Overwrite to return the extended geometry of an item, that is,
+ // if it is a border item, include the widget border for the indicator to work correctly
+ virtual QRect extendedGeometry(int index) const = 0;
+ virtual bool supportsIndicatorOrientation(Qt::Orientation indicatorOrientation) const = 0;
+
+ QRect itemInfo(int index) const;
+ QLayout *layout() const;
+ QGridLayout *gridLayout() const;
+ QWidget *widget() const { return m_widget; }
+
+ void setInsertMode(InsertMode im);
+ void setCurrentCell(const QPair<int, int> &cell);
+
+private:
+ enum Indicator { LeftIndicator, TopIndicator, RightIndicator, BottomIndicator, NumIndicators };
+
+ void hideIndicator(Indicator i);
+ void showIndicator(Indicator i, const QRect &geometry, const QPalette &);
+
+ QDesignerFormWindowInterface *m_formWindow;
+ LayoutHelper* m_helper;
+
+ QPointer<QWidget> m_widget;
+ QPointer<QWidget> m_indicators[NumIndicators];
+ int m_currentIndex;
+ InsertMode m_currentInsertMode;
+ QPair<int, int> m_currentCell;
+};
+} // namespace qdesigner_internal
+
+// Red layout widget.
+class QDESIGNER_SHARED_EXPORT QLayoutWidget: public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QLayoutWidget(QDesignerFormWindowInterface *formWindow, QWidget *parent = 0);
+
+ int layoutLeftMargin() const;
+ void setLayoutLeftMargin(int layoutMargin);
+
+ int layoutTopMargin() const;
+ void setLayoutTopMargin(int layoutMargin);
+
+ int layoutRightMargin() const;
+ void setLayoutRightMargin(int layoutMargin);
+
+ int layoutBottomMargin() const;
+ void setLayoutBottomMargin(int layoutMargin);
+
+ inline QDesignerFormWindowInterface *formWindow() const { return m_formWindow; }
+
+protected:
+ virtual bool event(QEvent *e);
+ virtual void paintEvent(QPaintEvent *e);
+
+private:
+ QDesignerFormWindowInterface *m_formWindow;
+ int m_leftMargin;
+ int m_topMargin;
+ int m_rightMargin;
+ int m_bottomMargin;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_WIDGET_H
diff --git a/src/designer/src/lib/shared/qscripthighlighter.cpp b/src/designer/src/lib/shared/qscripthighlighter.cpp
new file mode 100644
index 000000000..67555f39e
--- /dev/null
+++ b/src/designer/src/lib/shared/qscripthighlighter.cpp
@@ -0,0 +1,468 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscripthighlighter_p.h"
+
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+static const QSet<QString> &qscriptKeywords() {
+ static QSet<QString> keywords;
+ if (keywords.empty()) {
+ keywords.insert(QLatin1String("Infinity"));
+ keywords.insert(QLatin1String("NaN"));
+ keywords.insert(QLatin1String("abstract"));
+ keywords.insert(QLatin1String("boolean"));
+ keywords.insert(QLatin1String("break"));
+ keywords.insert(QLatin1String("byte"));
+ keywords.insert(QLatin1String("case"));
+ keywords.insert(QLatin1String("catch"));
+ keywords.insert(QLatin1String("char"));
+ keywords.insert(QLatin1String("class"));
+ keywords.insert(QLatin1String("const"));
+ keywords.insert(QLatin1String("constructor"));
+ keywords.insert(QLatin1String("continue"));
+ keywords.insert(QLatin1String("debugger"));
+ keywords.insert(QLatin1String("default"));
+ keywords.insert(QLatin1String("delete"));
+ keywords.insert(QLatin1String("do"));
+ keywords.insert(QLatin1String("double"));
+ keywords.insert(QLatin1String("else"));
+ keywords.insert(QLatin1String("enum"));
+ keywords.insert(QLatin1String("export"));
+ keywords.insert(QLatin1String("extends"));
+ keywords.insert(QLatin1String("false"));
+ keywords.insert(QLatin1String("final"));
+ keywords.insert(QLatin1String("finally"));
+ keywords.insert(QLatin1String("float"));
+ keywords.insert(QLatin1String("for"));
+ keywords.insert(QLatin1String("function"));
+ keywords.insert(QLatin1String("goto"));
+ keywords.insert(QLatin1String("if"));
+ keywords.insert(QLatin1String("implements"));
+ keywords.insert(QLatin1String("import"));
+ keywords.insert(QLatin1String("in"));
+ keywords.insert(QLatin1String("instanceof"));
+ keywords.insert(QLatin1String("int"));
+ keywords.insert(QLatin1String("interface"));
+ keywords.insert(QLatin1String("long"));
+ keywords.insert(QLatin1String("native"));
+ keywords.insert(QLatin1String("new"));
+ keywords.insert(QLatin1String("package"));
+ keywords.insert(QLatin1String("private"));
+ keywords.insert(QLatin1String("protected"));
+ keywords.insert(QLatin1String("public"));
+ keywords.insert(QLatin1String("return"));
+ keywords.insert(QLatin1String("short"));
+ keywords.insert(QLatin1String("static"));
+ keywords.insert(QLatin1String("super"));
+ keywords.insert(QLatin1String("switch"));
+ keywords.insert(QLatin1String("synchronized"));
+ keywords.insert(QLatin1String("this"));
+ keywords.insert(QLatin1String("throw"));
+ keywords.insert(QLatin1String("throws"));
+ keywords.insert(QLatin1String("transient"));
+ keywords.insert(QLatin1String("true"));
+ keywords.insert(QLatin1String("try"));
+ keywords.insert(QLatin1String("typeof"));
+ keywords.insert(QLatin1String("undefined"));
+ keywords.insert(QLatin1String("var"));
+ keywords.insert(QLatin1String("void"));
+ keywords.insert(QLatin1String("volatile"));
+ keywords.insert(QLatin1String("while"));
+ keywords.insert(QLatin1String("with")); // end
+ }
+ return keywords;
+}
+
+static QSet<QChar> alphaChars() {
+ QSet<QChar> rc;
+ const QString alpha = QLatin1String("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ foreach (QChar chr, alpha)
+ rc.insert(chr);
+ return rc;
+}
+
+namespace qdesigner_internal {
+
+QScriptHighlighter::QScriptHighlighter(QTextDocument *parent)
+ : QSyntaxHighlighter(parent)
+{
+ m_numberFormat.setForeground(Qt::blue);
+ m_stringFormat.setForeground(Qt::darkGreen);
+ m_typeFormat.setForeground(Qt::darkMagenta);
+ m_keywordFormat.setForeground(Qt::darkYellow);
+ m_labelFormat.setForeground(Qt::darkRed);
+ m_commentFormat.setForeground(Qt::red);
+ //m_commentFormat.setFontFamily("times");
+ m_commentFormat.setFontItalic(true);
+ m_preProcessorFormat.setForeground(Qt::darkBlue);
+}
+
+void QScriptHighlighter::highlightBlock(const QString &text)
+{
+ // states
+ enum {
+ StateStandard,
+ StateCommentStart1,
+ StateCCommentStart2,
+ StateCppCommentStart2,
+ StateCComment,
+ StateCppComment,
+ StateCCommentEnd1,
+ StateCCommentEnd2,
+ StateStringStart,
+ StateString,
+ StateStringEnd,
+ StateString2Start,
+ StateString2,
+ StateString2End,
+ StateNumber,
+ StatePreProcessor,
+ NumStates
+ };
+ // tokens
+ enum {
+ InputAlpha,
+ InputNumber,
+ InputAsterix,
+ InputSlash,
+ InputParen,
+ InputSpace,
+ InputHash,
+ InputQuotation,
+ InputApostrophe,
+ InputSep,
+ NumInputs
+ };
+
+ static const uchar table[NumStates][NumInputs] = {
+ { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStandard
+ { StateStandard, StateNumber, StateCCommentStart2, StateCppCommentStart2, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCommentStart1
+ { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentStart2
+ { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // CppCommentStart2
+ { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCComment
+ { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // StateCppComment
+ { StateCComment, StateCComment, StateCCommentEnd1, StateCCommentEnd2, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentEnd1
+ { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCCommentEnd2
+ { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateStringStart
+ { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateString
+ { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStringEnd
+ { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2Start
+ { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2
+ { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateString2End
+ { StateNumber, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateNumber
+ { StatePreProcessor, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard } // StatePreProcessor
+ };
+
+ QString buffer;
+ buffer.reserve(text.length());
+ QTextCharFormat emptyFormat;
+
+ int state = StateStandard;
+ const int previousState = previousBlockState();
+ if (previousState != -1)
+ state = previousState;
+
+ if (text.isEmpty()) {
+ setCurrentBlockState(previousState);
+ return;
+ }
+
+ int input = -1;
+ int i = 0;
+ bool lastWasBackSlash = false;
+ bool makeLastStandard = false;
+
+ static const QSet<QChar> alphabeth = alphaChars();
+ static const QString mathChars = QString::fromLatin1("xXeE");
+ static const QString numbers = QString::fromLatin1("0123456789");
+ bool questionMark = false;
+ QChar lastChar;
+ QString firstWord;
+ forever {
+ const QChar c = text.at(i);
+
+ if (lastWasBackSlash) {
+ input = InputSep;
+ } else {
+ switch (c.toLatin1()) {
+ case '*':
+ input = InputAsterix;
+ break;
+ case '/':
+ input = InputSlash;
+ break;
+ case '(': case '[': case '{':
+ input = InputParen;
+ if (state == StateStandard
+ || state == StateNumber
+ || state == StatePreProcessor
+ || state == StateCCommentEnd2
+ || state == StateCCommentEnd1
+ || state == StateString2End
+ || state == StateStringEnd
+ )
+ //blockData->parentheses << Parenthesis(Parenthesis::Open, c, i);
+ break;
+ case ')': case ']': case '}':
+ input = InputParen;
+ if (state == StateStandard
+ || state == StateNumber
+ || state == StatePreProcessor
+ || state == StateCCommentEnd2
+ || state == StateCCommentEnd1
+ || state == StateString2End
+ || state == StateStringEnd
+ ) {
+ //blockData->parentheses << Parenthesis(Parenthesis::Closed, c, i);
+ }
+ break;
+ case '#':
+ input = InputHash;
+ break;
+ case '"':
+ input = InputQuotation;
+ break;
+ case '\'':
+ input = InputApostrophe;
+ break;
+ case ' ':
+ input = InputSpace;
+ break;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': case '0':
+ if (alphabeth.contains(lastChar)
+ && (!mathChars.contains(lastChar) || !numbers.contains(text.at(i - 1)))) {
+ input = InputAlpha;
+ } else {
+ if (input == InputAlpha && numbers.contains(lastChar))
+ input = InputAlpha;
+ else
+ input = InputNumber;
+ }
+ break;
+ case ':': {
+ input = InputAlpha;
+ QChar nextChar = QLatin1Char(' ');
+ if (i < text.length() - 1)
+ nextChar = text.at(i + 1);
+ if (state == StateStandard && !questionMark &&
+ lastChar != QLatin1Char(':') && nextChar != QLatin1Char(':')) {
+ for (int j = 0; j < i; ++j) {
+ if (format(j) == emptyFormat)
+ setFormat(j, 1, m_labelFormat);
+ }
+ }
+ break;
+ }
+ default: {
+ if (!questionMark && c == QLatin1Char('?'))
+ questionMark = true;
+ if (c.isLetter() || c == QLatin1Char('_'))
+ input = InputAlpha;
+ else
+ input = InputSep;
+ } break;
+ }
+ }
+
+ lastWasBackSlash = !lastWasBackSlash && c == QLatin1Char('\\');
+
+ if (input == InputAlpha)
+ buffer += c;
+
+ state = table[state][input];
+
+ switch (state) {
+ case StateStandard: {
+ setFormat(i, 1, emptyFormat);
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ if (!buffer.isEmpty() && input != InputAlpha ) {
+ highlightKeyword(i, buffer);
+ buffer.clear();
+ }
+ } break;
+ case StateCommentStart1:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = true;
+ buffer.resize(0);
+ break;
+ case StateCCommentStart2:
+ setFormat(i - 1, 2, m_commentFormat);
+ makeLastStandard = false;
+ buffer.resize(0);
+ break;
+ case StateCppCommentStart2:
+ setFormat(i - 1, 2, m_commentFormat);
+ makeLastStandard = false;
+ buffer.resize(0);
+ break;
+ case StateCComment:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, m_commentFormat);
+ buffer.resize(0);
+ break;
+ case StateCppComment:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, m_commentFormat);
+ buffer.resize(0);
+ break;
+ case StateCCommentEnd1:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, m_commentFormat);
+ buffer.resize(0);
+ break;
+ case StateCCommentEnd2:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, m_commentFormat);
+ buffer.resize(0);
+ break;
+ case StateStringStart:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, emptyFormat);
+ buffer.resize(0);
+ break;
+ case StateString:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, m_stringFormat);
+ buffer.resize(0);
+ break;
+ case StateStringEnd:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, emptyFormat);
+ buffer.resize(0);
+ break;
+ case StateString2Start:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, emptyFormat);
+ buffer.resize(0);
+ break;
+ case StateString2:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, m_stringFormat);
+ buffer.resize(0);
+ break;
+ case StateString2End:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, emptyFormat);
+ buffer.resize(0);
+ break;
+ case StateNumber:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat( i, 1, m_numberFormat);
+ buffer.resize(0);
+ break;
+ case StatePreProcessor:
+ if (makeLastStandard)
+ setFormat(i - 1, 1, emptyFormat);
+ makeLastStandard = false;
+ setFormat(i, 1, m_preProcessorFormat);
+ buffer.resize(0);
+ break;
+ }
+
+ lastChar = c;
+ i++;
+ if (i >= text.length())
+ break;
+ }
+
+ highlightKeyword(text.length(), buffer);
+
+ if (state == StateCComment
+ || state == StateCCommentEnd1
+ || state == StateCCommentStart2
+ ) {
+ state = StateCComment;
+ } else if (state == StateString) {
+ state = StateString;
+ } else if (state == StateString2) {
+ state = StateString2;
+ } else {
+ state = StateStandard;
+ }
+
+ setCurrentBlockState(state);
+}
+
+void QScriptHighlighter::highlightKeyword(int currentPos, const QString &buffer)
+{
+ if (buffer.isEmpty())
+ return;
+
+ if (buffer.at(0) == QLatin1Char('Q')) {
+ setFormat(currentPos - buffer.length(), buffer.length(), m_typeFormat);
+ } else {
+ if (qscriptKeywords().contains(buffer)) {
+ setFormat(currentPos - buffer.length(), buffer.length(), m_keywordFormat);
+ }
+ }
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qscripthighlighter_p.h b/src/designer/src/lib/shared/qscripthighlighter_p.h
new file mode 100644
index 000000000..7e067c299
--- /dev/null
+++ b/src/designer/src/lib/shared/qscripthighlighter_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QSCRIPTSYNTAXHIGHLIGHTER_H
+#define QSCRIPTSYNTAXHIGHLIGHTER_H
+
+#include <QtGui/QSyntaxHighlighter>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+class QScriptHighlighter : public QSyntaxHighlighter
+{
+public:
+ explicit QScriptHighlighter(QTextDocument *parent);
+ virtual void highlightBlock(const QString &text);
+
+private:
+ void highlightKeyword(int currentPos, const QString &buffer);
+
+ QTextCharFormat m_numberFormat;
+ QTextCharFormat m_stringFormat;
+ QTextCharFormat m_typeFormat;
+ QTextCharFormat m_keywordFormat;
+ QTextCharFormat m_labelFormat;
+ QTextCharFormat m_commentFormat;
+ QTextCharFormat m_preProcessorFormat;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/shared/qsimpleresource.cpp b/src/designer/src/lib/shared/qsimpleresource.cpp
new file mode 100644
index 000000000..178ba3e18
--- /dev/null
+++ b/src/designer/src/lib/shared/qsimpleresource.cpp
@@ -0,0 +1,418 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsimpleresource_p.h"
+#include "widgetfactory_p.h"
+#include "widgetdatabase_p.h"
+
+#include <formscriptrunner_p.h>
+#include <properties_p.h>
+#include <ui4_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <script_p.h>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+#include <QtDesigner/extrainfo.h>
+
+#include <QtGui/QIcon>
+#include <QtGui/QWidget>
+#include <QtGui/QAction>
+#include <QtCore/QDebug>
+#include <QtCore/QCoreApplication>
+
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ typedef QList<DomWidgetData*> DomWidgetDataList;
+ typedef QList<DomProperty*> DomPropertyList;
+ typedef QList<QDesignerCustomWidgetInterface *> CustomWidgetInterfaces;
+}
+
+namespace qdesigner_internal {
+
+bool QSimpleResource::m_warningsEnabled = true;
+
+QSimpleResource::QSimpleResource(QDesignerFormEditorInterface *core) :
+ QAbstractFormBuilder(),
+ m_core(core)
+{
+ QString workingDirectory = QDir::homePath();
+ workingDirectory += QDir::separator();
+ workingDirectory += QLatin1String(".designer");
+ setWorkingDirectory(QDir(workingDirectory));
+#ifndef QT_FORMBUILDER_NO_SCRIPT
+ // Disable scripting in the editors.
+ formScriptRunner()-> setOptions(QFormScriptRunner::DisableScripts);
+#endif
+}
+
+QSimpleResource::~QSimpleResource()
+{
+
+}
+
+QBrush QSimpleResource::setupBrush(DomBrush *brush)
+{
+ return QAbstractFormBuilder::setupBrush(brush);
+}
+
+DomBrush *QSimpleResource::saveBrush(const QBrush &brush)
+{
+ return QAbstractFormBuilder::saveBrush(brush);
+}
+
+QIcon QSimpleResource::nameToIcon(const QString &filePath, const QString &qrcPath)
+{
+ Q_UNUSED(filePath)
+ Q_UNUSED(qrcPath)
+ qWarning() << "QSimpleResource::nameToIcon() is obsoleted";
+ return QIcon();
+}
+
+QString QSimpleResource::iconToFilePath(const QIcon &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "QSimpleResource::iconToFilePath() is obsoleted";
+ return QString();
+}
+
+QString QSimpleResource::iconToQrcPath(const QIcon &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "QSimpleResource::iconToQrcPath() is obsoleted";
+ return QString();
+}
+
+QPixmap QSimpleResource::nameToPixmap(const QString &filePath, const QString &qrcPath)
+{
+ Q_UNUSED(filePath)
+ Q_UNUSED(qrcPath)
+ qWarning() << "QSimpleResource::nameToPixmap() is obsoleted";
+ return QPixmap();
+}
+
+QString QSimpleResource::pixmapToFilePath(const QPixmap &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "QSimpleResource::pixmapToFilePath() is obsoleted";
+ return QString();
+}
+
+QString QSimpleResource::pixmapToQrcPath(const QPixmap &pm) const
+{
+ Q_UNUSED(pm)
+ qWarning() << "QSimpleResource::pixmapToQrcPath() is obsoleted";
+ return QString();
+}
+
+DomScript *QSimpleResource::createScript(const QString &script, ScriptSource source)
+{
+ if (script.isEmpty())
+ return 0;
+ DomScript *domScript = new DomScript();
+ switch (source) {
+ case ScriptExtension:
+ domScript->setAttributeSource(QLatin1String("extension"));
+ break;
+ case ScriptDesigner:
+ domScript->setAttributeSource(QLatin1String("designer"));
+ break;
+ case ScriptCustomWidgetPlugin:
+ domScript->setAttributeSource(QLatin1String("customwidgetplugin"));
+ break;
+ }
+ domScript->setAttributeLanguage(QLatin1String("Qt Script"));
+ domScript->setText(script);
+ return domScript;
+}
+
+// Add a script to a list of DomScripts unless empty
+void QSimpleResource::addScript(const QString &script, ScriptSource source, DomScripts &domScripts)
+{
+ if (DomScript *domScript = createScript(script, source)) {
+ domScripts += domScript;
+ }
+}
+
+void QSimpleResource::addExtensionDataToDOM(QAbstractFormBuilder *afb,
+ QDesignerFormEditorInterface *core,
+ DomWidget *ui_widget, QWidget *widget)
+{
+ QExtensionManager *emgr = core->extensionManager();
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(emgr, widget)) {
+ extra->saveWidgetExtraInfo(ui_widget);
+ }
+ if (QDesignerScriptExtension *scriptExt = qt_extension<QDesignerScriptExtension*>(emgr, widget)) {
+ // Add internal state
+ const QVariantMap data = scriptExt->data();
+ if (!data.empty()) {
+ // Convert the map to a DomState.
+ // We pass on the widget for property introspection. Thus, non-designable properties
+ // that have to be converted using QMetaObject (enums and the like) will work.
+ DomPropertyList properties;
+ const QVariantMap::const_iterator vcend = data.constEnd();
+ for (QVariantMap::const_iterator it = data.constBegin(); it != vcend; ++it) {
+ if (DomProperty *prop = variantToDomProperty(afb, widget->metaObject(), it.key(), it.value()))
+ properties += prop;
+ }
+ if (!properties.empty()) {
+ DomWidgetData *domData = new DomWidgetData;
+ domData->setElementProperty(properties);
+ DomWidgetDataList domDataList;
+ domDataList += domData;
+ ui_widget->setElementWidgetData(domDataList);
+ }
+
+ }
+ // Add script
+ const QString script = scriptExt->script();
+ if (!script.isEmpty()) {
+ DomScripts domScripts = ui_widget->elementScript();
+ addScript(script, ScriptExtension, domScripts);
+ ui_widget->setElementScript(domScripts);
+ }
+ }
+}
+
+void QSimpleResource::applyExtensionDataFromDOM(QAbstractFormBuilder *afb,
+ QDesignerFormEditorInterface *core,
+ DomWidget *ui_widget, QWidget *widget, bool applyState)
+{
+ QExtensionManager *emgr = core->extensionManager();
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(emgr, widget)) {
+ extra->loadWidgetExtraInfo(ui_widget);
+ }
+ if (applyState) {
+ if (QDesignerScriptExtension *scriptExt = qt_extension<QDesignerScriptExtension*>(emgr, widget)) {
+ // Apply the state.
+ // We pass on the widget for property introspection. Thus, non-designable properties
+ // that have to be converted using QMetaObject (enums and the like) will work.
+ QVariantMap data;
+ DomWidgetDataList domDataList = ui_widget->elementWidgetData();
+ if (!domDataList.empty()) {
+ foreach (const DomWidgetData *domData, domDataList) {
+ const DomPropertyList properties = domData->elementProperty();
+ foreach(const DomProperty *prop, properties) {
+ const QVariant vprop = domPropertyToVariant(afb, widget->metaObject(), prop);
+ if (vprop.type() != QVariant::Invalid)
+ data.insert(prop->attributeName(), vprop);
+ }
+ }
+ }
+ scriptExt->setData(data);
+ }
+ }
+}
+
+QString QSimpleResource::customWidgetScript(QDesignerFormEditorInterface *core, QObject *object)
+{
+ return customWidgetScript(core, qdesigner_internal::WidgetFactory::classNameOf(core, object));
+}
+
+bool QSimpleResource::hasCustomWidgetScript(QDesignerFormEditorInterface *, QObject *)
+{
+ return false;
+}
+
+QString QSimpleResource::customWidgetScript(QDesignerFormEditorInterface *, const QString &)
+{
+ return QString();
+}
+
+bool QSimpleResource::setWarningsEnabled(bool warningsEnabled)
+{
+ const bool rc = m_warningsEnabled;
+ m_warningsEnabled = warningsEnabled;
+ return rc;
+}
+
+bool QSimpleResource::warningsEnabled()
+{
+ return m_warningsEnabled;
+}
+
+// Custom widgets handling helpers
+
+// Add unique fake slots and signals to lists
+bool QSimpleResource::addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals)
+{
+ if (!domSlots)
+ return false;
+
+ bool rc = false;
+ foreach (const QString &fakeSlot, domSlots->elementSlot())
+ if (fakeSlots.indexOf(fakeSlot) == -1) {
+ fakeSlots += fakeSlot;
+ rc = true;
+ }
+
+ foreach (const QString &fakeSignal, domSlots->elementSignal())
+ if (fakeSignals.indexOf(fakeSignal) == -1) {
+ fakeSignals += fakeSignal;
+ rc = true;
+ }
+ return rc;
+}
+
+void QSimpleResource::addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item)
+{
+ const DomSlots *domSlots = domCustomWidget->elementSlots();
+ if (!domSlots)
+ return;
+
+ // Merge in new slots, signals
+ QStringList fakeSlots = item->fakeSlots();
+ QStringList fakeSignals = item->fakeSignals();
+ if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) {
+ item->setFakeSlots(fakeSlots);
+ item->setFakeSignals(fakeSignals);
+ }
+}
+
+// Perform one iteration of adding the custom widgets to the database,
+// looking up the base class and inheriting its data.
+// Remove the succeeded custom widgets from the list.
+// Classes whose base class could not be found are left in the list.
+
+void QSimpleResource::addCustomWidgetsToWidgetDatabase(const QDesignerFormEditorInterface *core,
+ QList<DomCustomWidget*>& custom_widget_list)
+{
+ QDesignerWidgetDataBaseInterface *db = core->widgetDataBase();
+ for (int i=0; i < custom_widget_list.size(); ) {
+ bool classInserted = false;
+ DomCustomWidget *custom_widget = custom_widget_list[i];
+ const QString customClassName = custom_widget->elementClass();
+ const QString base_class = custom_widget->elementExtends();
+ QString includeFile;
+ IncludeType includeType = IncludeLocal;
+ if (const DomHeader *header = custom_widget->elementHeader()) {
+ includeFile = header->text();
+ if (header->hasAttributeLocation() && header->attributeLocation() == QLatin1String("global"))
+ includeType = IncludeGlobal;
+ }
+ const bool domIsContainer = custom_widget->elementContainer();
+ // Append a new item
+ if (base_class.isEmpty()) {
+ WidgetDataBaseItem *item = new WidgetDataBaseItem(customClassName);
+ item->setPromoted(false);
+ item->setGroup(QCoreApplication::translate("Designer", "Custom Widgets"));
+ item->setIncludeFile(buildIncludeFile(includeFile, includeType));
+ item->setContainer(domIsContainer);
+ item->setCustom(true);
+ addFakeMethodsToWidgetDataBase(custom_widget, item);
+ db->append(item);
+ custom_widget_list.removeAt(i);
+ classInserted = true;
+ } else {
+ // Create a new entry cloned from base class. Note that this will ignore existing
+ // classes, eg, plugin custom widgets.
+ QDesignerWidgetDataBaseItemInterface *item =
+ appendDerived(db, customClassName, QCoreApplication::translate("Designer", "Promoted Widgets"),
+ base_class,
+ buildIncludeFile(includeFile, includeType),
+ true,true);
+ // Ok, base class found.
+ if (item) {
+ // Hack to accommodate for old UI-files in which "container" is not set properly:
+ // Apply "container" from DOM only if true (else, eg classes from QFrame might not accept
+ // dropping child widgets on them as container=false). This also allows for
+ // QWidget-derived stacked pages.
+ if (domIsContainer)
+ item->setContainer(domIsContainer);
+
+ addFakeMethodsToWidgetDataBase(custom_widget, static_cast<WidgetDataBaseItem*>(item));
+ custom_widget_list.removeAt(i);
+ classInserted = true;
+ }
+ }
+ // Skip failed item.
+ if (!classInserted)
+ i++;
+ }
+
+}
+
+void QSimpleResource::handleDomCustomWidgets(const QDesignerFormEditorInterface *core,
+ const DomCustomWidgets *dom_custom_widgets)
+{
+ if (dom_custom_widgets == 0)
+ return;
+ QList<DomCustomWidget*> custom_widget_list = dom_custom_widgets->elementCustomWidget();
+ // Attempt to insert each item derived from its base class.
+ // This should at most require two iterations in the event that the classes are out of order
+ // (derived first, max depth: promoted custom plugin = 2)
+ for (int iteration = 0; iteration < 2; iteration++) {
+ addCustomWidgetsToWidgetDatabase(core, custom_widget_list);
+ if (custom_widget_list.empty())
+ return;
+ }
+ // Oops, there are classes left whose base class could not be found.
+ // Default them to QWidget with warnings.
+ const QString fallBackBaseClass = QLatin1String("QWidget");
+ for (int i=0; i < custom_widget_list.size(); i++ ) {
+ DomCustomWidget *custom_widget = custom_widget_list[i];
+ const QString customClassName = custom_widget->elementClass();
+ const QString base_class = custom_widget->elementExtends();
+ qDebug() << "** WARNING The base class " << base_class << " of the custom widget class " << customClassName
+ << " could not be found. Defaulting to " << fallBackBaseClass << '.';
+ custom_widget->setElementExtends(fallBackBaseClass);
+ }
+ // One more pass.
+ addCustomWidgetsToWidgetDatabase(core, custom_widget_list);
+}
+
+// ------------ FormBuilderClipboard
+
+FormBuilderClipboard::FormBuilderClipboard(QWidget *w)
+{
+ m_widgets += w;
+}
+
+bool FormBuilderClipboard::empty() const
+{
+ return m_widgets.empty() && m_actions.empty();
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/qsimpleresource_p.h b/src/designer/src/lib/shared/qsimpleresource_p.h
new file mode 100644
index 000000000..597b101cd
--- /dev/null
+++ b/src/designer/src/lib/shared/qsimpleresource_p.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QSIMPLERESOURCE_H
+#define QSIMPLERESOURCE_H
+
+#include "shared_global_p.h"
+#include "abstractformbuilder.h"
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class DomScript;
+class DomCustomWidgets;
+class DomCustomWidget;
+class DomSlots;
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class WidgetDataBaseItem;
+
+class QDESIGNER_SHARED_EXPORT QSimpleResource : public QAbstractFormBuilder
+{
+public:
+ explicit QSimpleResource(QDesignerFormEditorInterface *core);
+ virtual ~QSimpleResource();
+
+ QBrush setupBrush(DomBrush *brush);
+ DomBrush *saveBrush(const QBrush &brush);
+
+ inline QDesignerFormEditorInterface *core() const
+ { return m_core; }
+
+ // Query extensions for additional data
+ static void addExtensionDataToDOM(QAbstractFormBuilder *afb,
+ QDesignerFormEditorInterface *core,
+ DomWidget *ui_widget, QWidget *widget);
+ static void applyExtensionDataFromDOM(QAbstractFormBuilder *afb,
+ QDesignerFormEditorInterface *core,
+ DomWidget *ui_widget, QWidget *widget,
+ bool applyState);
+ // Enable warnings while saving. Turn off for backups.
+ static bool setWarningsEnabled(bool warningsEnabled);
+ static bool warningsEnabled();
+ // Return the script returned by the CustomWidget codeTemplate API
+ static QString customWidgetScript(QDesignerFormEditorInterface *core, QObject *object);
+ static QString customWidgetScript(QDesignerFormEditorInterface *core, const QString &className);
+ static bool hasCustomWidgetScript(QDesignerFormEditorInterface *core, QObject *object);
+
+ // Implementation for FormBuilder::createDomCustomWidgets() that adds
+ // the custom widgets to the widget database
+ static void handleDomCustomWidgets(const QDesignerFormEditorInterface *core,
+ const DomCustomWidgets *dom_custom_widgets);
+
+protected:
+ virtual QIcon nameToIcon(const QString &filePath, const QString &qrcPath);
+ virtual QString iconToFilePath(const QIcon &pm) const;
+ virtual QString iconToQrcPath(const QIcon &pm) const;
+ virtual QPixmap nameToPixmap(const QString &filePath, const QString &qrcPath);
+ virtual QString pixmapToFilePath(const QPixmap &pm) const;
+ virtual QString pixmapToQrcPath(const QPixmap &pm) const;
+
+ enum ScriptSource { ScriptDesigner, ScriptExtension, ScriptCustomWidgetPlugin };
+ static DomScript*createScript(const QString &script, ScriptSource source);
+ typedef QList<DomScript*> DomScripts;
+ static void addScript(const QString &script, ScriptSource source, DomScripts &domScripts);
+
+ static bool addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals);
+
+private:
+ static void addCustomWidgetsToWidgetDatabase(const QDesignerFormEditorInterface *core,
+ QList<DomCustomWidget*>& custom_widget_list);
+ static void addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item);
+
+ static bool m_warningsEnabled;
+ QDesignerFormEditorInterface *m_core;
+};
+
+// Contents of clipboard for formbuilder copy and paste operations
+// (Actions and widgets)
+struct QDESIGNER_SHARED_EXPORT FormBuilderClipboard {
+ typedef QList<QAction*> ActionList;
+
+ FormBuilderClipboard() {}
+ FormBuilderClipboard(QWidget *w);
+
+ bool empty() const;
+
+ QWidgetList m_widgets;
+ ActionList m_actions;
+};
+
+// Base class for a form builder used in the editor that
+// provides copy and paste.(move into base interface)
+class QDESIGNER_SHARED_EXPORT QEditorFormBuilder : public QSimpleResource
+{
+public:
+ explicit QEditorFormBuilder(QDesignerFormEditorInterface *core) : QSimpleResource(core) {}
+
+ virtual bool copy(QIODevice *dev, const FormBuilderClipboard &selection) = 0;
+ virtual DomUI *copy(const FormBuilderClipboard &selection) = 0;
+
+ // A widget parent needs to be specified, otherwise, the widget factory cannot locate the form window via parent
+ // and thus is not able to construct special widgets (QLayoutWidget).
+ virtual FormBuilderClipboard paste(DomUI *ui, QWidget *widgetParent, QObject *actionParent = 0) = 0;
+ virtual FormBuilderClipboard paste(QIODevice *dev, QWidget *widgetParent, QObject *actionParent = 0) = 0;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/shared/qtresourceeditordialog.cpp b/src/designer/src/lib/shared/qtresourceeditordialog.cpp
new file mode 100644
index 000000000..9162b097d
--- /dev/null
+++ b/src/designer/src/lib/shared/qtresourceeditordialog.cpp
@@ -0,0 +1,2223 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractsettings_p.h"
+#include "abstractformeditor.h"
+#include "qtresourceeditordialog_p.h"
+#include "ui_qtresourceeditordialog.h"
+#include "qtresourcemodel_p.h"
+#include "iconloader_p.h"
+
+#include <abstractdialoggui_p.h>
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QCoreApplication>
+#include <QtXml/QDomDocument>
+#include <QtGui/QMenu>
+#include <QtGui/QHeaderView>
+#include <QtGui/QInputDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QStandardItemModel>
+
+QT_BEGIN_NAMESPACE
+
+static const char *rccRootTag = "RCC";
+static const char *rccTag = "qresource";
+static const char *rccFileTag = "file";
+static const char *rccAliasAttribute = "alias";
+static const char *rccPrefixAttribute = "prefix";
+static const char *rccLangAttribute = "lang";
+static const char *SplitterPosition = "SplitterPosition";
+static const char *Geometry = "Geometry";
+static const char *QrcDialogC = "QrcDialog";
+
+static QString msgOverwrite(const QString &fname)
+{
+ return QApplication::translate("QtResourceEditorDialog", "%1 already exists.\nDo you want to replace it?", 0, QApplication::UnicodeUTF8).arg(fname);
+}
+
+static QString msgTagMismatch(const QString &got, const QString &expected)
+{
+ return QApplication::translate("QtResourceEditorDialog", "The file does not appear to be a resource file; element '%1' was found where '%2' was expected.").arg(got).arg(expected);
+}
+
+namespace {
+
+// below 3 data classes should be derived from QSharedData and made implicit shared class
+struct QtResourceFileData {
+ QString path;
+ QString alias;
+ bool operator==(const QtResourceFileData &other) const {
+ if (path == other.path && alias == other.alias)
+ return true;
+ return false;
+ }
+};
+
+struct QtResourcePrefixData {
+ QString prefix;
+ QString language;
+ QList<QtResourceFileData> resourceFileList;
+ bool operator==(const QtResourcePrefixData &other) const {
+ if (prefix == other.prefix && language == other.language && resourceFileList == other.resourceFileList)
+ return true;
+ return false;
+ }
+};
+
+struct QtQrcFileData {
+ QString qrcPath;
+ QList<QtResourcePrefixData> resourceList;
+ bool operator==(const QtQrcFileData &other) const {
+ if (qrcPath == other.qrcPath && resourceList == other.resourceList)
+ return true;
+ return false;
+ }
+};
+
+bool loadResourceFileData(const QDomElement &fileElem, QtResourceFileData *fileData, QString *errorMessage)
+{
+ if (!fileData)
+ return false;
+
+ if (fileElem.tagName() != QLatin1String(rccFileTag)) {
+ *errorMessage = msgTagMismatch(fileElem.tagName(), QLatin1String(rccFileTag));
+ return false;
+ }
+
+ QtResourceFileData &data = *fileData;
+
+ data.path = fileElem.text();
+ data.alias = fileElem.attribute(QLatin1String(rccAliasAttribute));
+
+ return true;
+}
+
+static bool loadResourcePrefixData(const QDomElement &prefixElem, QtResourcePrefixData *prefixData, QString *errorMessage)
+{
+ if (!prefixData)
+ return false;
+
+ if (prefixElem.tagName() != QLatin1String(rccTag)) {
+ *errorMessage = msgTagMismatch(prefixElem.tagName(), QLatin1String(rccTag));
+ return false;
+ }
+
+ QtResourcePrefixData &data = *prefixData;
+
+ data.prefix = prefixElem.attribute(QLatin1String(rccPrefixAttribute));
+ data.language = prefixElem.attribute(QLatin1String(rccLangAttribute));
+ QDomElement fileElem = prefixElem.firstChildElement();
+ while (!fileElem.isNull()) {
+ QtResourceFileData fileData;
+ if (!loadResourceFileData(fileElem, &fileData, errorMessage))
+ return false;
+ data.resourceFileList.append(fileData);
+ fileElem = fileElem.nextSiblingElement();
+ }
+ return true;
+}
+
+static bool loadQrcFileData(const QDomDocument &doc, const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage)
+{
+ if (!qrcFileData)
+ return false;
+
+ QtQrcFileData &data = *qrcFileData;
+
+ QDomElement docElem = doc.documentElement();
+ if (docElem.tagName() != QLatin1String(rccRootTag)) {
+ *errorMessage = msgTagMismatch(docElem.tagName(), QLatin1String(rccRootTag));
+ return false;
+ }
+
+ QDomElement prefixElem = docElem.firstChildElement();
+ while (!prefixElem.isNull()) {
+ QtResourcePrefixData prefixData;
+ if (!loadResourcePrefixData(prefixElem, &prefixData, errorMessage))
+ return false;
+ data.resourceList.append(prefixData);
+ prefixElem = prefixElem.nextSiblingElement();
+ }
+
+ data.qrcPath = path;
+
+ return true;
+}
+
+QDomElement saveResourceFileData(QDomDocument &doc, const QtResourceFileData &fileData)
+{
+ QDomElement fileElem = doc.createElement(QLatin1String(rccFileTag));
+ if (!fileData.alias.isEmpty())
+ fileElem.setAttribute(QLatin1String(rccAliasAttribute), fileData.alias);
+
+ QDomText textElem = doc.createTextNode(fileData.path);
+ fileElem.appendChild(textElem);
+
+ return fileElem;
+}
+
+QDomElement saveResourcePrefixData(QDomDocument &doc, const QtResourcePrefixData &prefixData)
+{
+ QDomElement prefixElem = doc.createElement(QLatin1String(rccTag));
+ if (!prefixData.prefix.isEmpty())
+ prefixElem.setAttribute(QLatin1String(rccPrefixAttribute), prefixData.prefix);
+ if (!prefixData.language.isEmpty())
+ prefixElem.setAttribute(QLatin1String(rccLangAttribute), prefixData.language);
+
+ QListIterator<QtResourceFileData> itFile(prefixData.resourceFileList);
+ while (itFile.hasNext()) {
+ QDomElement fileElem = saveResourceFileData(doc, itFile.next());
+ prefixElem.appendChild(fileElem);
+ }
+
+ return prefixElem;
+}
+
+QDomDocument saveQrcFileData(const QtQrcFileData &qrcFileData)
+{
+ QDomDocument doc;
+ QDomElement docElem = doc.createElement(QLatin1String(rccRootTag));
+ QListIterator<QtResourcePrefixData> itPrefix(qrcFileData.resourceList);
+ while (itPrefix.hasNext()) {
+ QDomElement prefixElem = saveResourcePrefixData(doc, itPrefix.next());
+
+ docElem.appendChild(prefixElem);
+ }
+ doc.appendChild(docElem);
+
+ return doc;
+}
+// --------------- QtResourceFile
+class QtResourceFile {
+public:
+ friend class QtQrcManager;
+
+ QString path() const { return m_path; }
+ QString alias() const { return m_alias; }
+ QString fullPath() const { return m_fullPath; }
+private:
+ QtResourceFile() {}
+
+ QString m_path;
+ QString m_alias;
+ QString m_fullPath;
+};
+
+class QtResourcePrefix {
+public:
+ friend class QtQrcManager;
+
+ QString prefix() const { return m_prefix; }
+ QString language() const { return m_language; }
+ QList<QtResourceFile *> resourceFiles() const { return m_resourceFiles; }
+private:
+ QtResourcePrefix() {}
+
+ QString m_prefix;
+ QString m_language;
+ QList<QtResourceFile *> m_resourceFiles;
+
+};
+// ------------------- QtQrcFile
+class QtQrcFile {
+public:
+ friend class QtQrcManager;
+
+ QString path() const { return m_path; }
+ QString fileName() const { return m_fileName; }
+ QList<QtResourcePrefix *> resourcePrefixList() const { return m_resourcePrefixes; }
+ QtQrcFileData initialState() const { return m_initialState; }
+
+private:
+ QtQrcFile() { }
+
+ void setPath(const QString &path) {
+ m_path = path;
+ QFileInfo fi(path);
+ m_fileName = fi.fileName();
+ }
+
+ QString m_path;
+ QString m_fileName;
+ QList<QtResourcePrefix *> m_resourcePrefixes;
+ QtQrcFileData m_initialState;
+};
+
+// ------------------ QtQrcManager
+class QtQrcManager : public QObject
+{
+ Q_OBJECT
+public:
+ QtQrcManager(QObject *parent = 0);
+ ~QtQrcManager();
+
+ QList<QtQrcFile *> qrcFiles() const;
+
+ // helpers
+ QtQrcFile *qrcFileOf(const QString &path) const;
+ QtQrcFile *qrcFileOf(QtResourcePrefix *resourcePrefix) const;
+ QtQrcFile *qrcFileOf(QtResourceFile *resourceFile) const;
+ QtResourcePrefix *resourcePrefixOf(QtResourceFile *resourceFile) const;
+
+ QtQrcFile *importQrcFile(const QtQrcFileData &qrcFileData, QtQrcFile *beforeQrcFile = 0);
+ void exportQrcFile(QtQrcFile *qrcFile, QtQrcFileData *qrcFileData) const;
+
+ QList<QtResourceFile *> resourceFilesOf(const QString &resourceFullPath) const;
+ QIcon icon(const QString &resourceFullPath) const;
+ bool exists(const QString &resourceFullPath) const;
+ bool exists(QtQrcFile *qrcFile) const;
+
+ QtQrcFile *prevQrcFile(QtQrcFile *qrcFile) const;
+ QtQrcFile *nextQrcFile(QtQrcFile *qrcFile) const;
+ QtResourcePrefix *prevResourcePrefix(QtResourcePrefix *resourcePrefix) const;
+ QtResourcePrefix *nextResourcePrefix(QtResourcePrefix *resourcePrefix) const;
+ QtResourceFile *prevResourceFile(QtResourceFile *resourceFile) const;
+ QtResourceFile *nextResourceFile(QtResourceFile *resourceFile) const;
+
+ void clear();
+
+public slots:
+
+ QtQrcFile *insertQrcFile(const QString &path, QtQrcFile *beforeQrcFile = 0, bool newFile = false);
+ void moveQrcFile(QtQrcFile *qrcFile, QtQrcFile *beforeQrcFile);
+ void setInitialState(QtQrcFile *qrcFile, const QtQrcFileData &initialState);
+ void removeQrcFile(QtQrcFile *qrcFile);
+
+ QtResourcePrefix *insertResourcePrefix(QtQrcFile *qrcFile, const QString &prefix,
+ const QString &language, QtResourcePrefix *beforeResourcePrefix = 0);
+ void moveResourcePrefix(QtResourcePrefix *resourcePrefix, QtResourcePrefix *beforeResourcePrefix); // the same qrc file???
+ void changeResourcePrefix(QtResourcePrefix *resourcePrefix, const QString &newPrefix);
+ void changeResourceLanguage(QtResourcePrefix *resourcePrefix, const QString &newLanguage);
+ void removeResourcePrefix(QtResourcePrefix *resourcePrefix);
+
+ QtResourceFile *insertResourceFile(QtResourcePrefix *resourcePrefix, const QString &path,
+ const QString &alias, QtResourceFile *beforeResourceFile = 0);
+ void moveResourceFile(QtResourceFile *resourceFile, QtResourceFile *beforeResourceFile); // the same prefix???
+ void changeResourceAlias(QtResourceFile *resourceFile, const QString &newAlias);
+ void removeResourceFile(QtResourceFile *resourceFile);
+
+signals:
+ void qrcFileInserted(QtQrcFile *qrcFile);
+ void qrcFileMoved(QtQrcFile *qrcFile, QtQrcFile *oldBeforeQrcFile);
+ void qrcFileRemoved(QtQrcFile *qrcFile);
+
+ void resourcePrefixInserted(QtResourcePrefix *resourcePrefix);
+ void resourcePrefixMoved(QtResourcePrefix *resourcePrefix, QtResourcePrefix *oldBeforeResourcePrefix);
+ void resourcePrefixChanged(QtResourcePrefix *resourcePrefix, const QString &oldPrefix);
+ void resourceLanguageChanged(QtResourcePrefix *resourcePrefix, const QString &oldLanguage);
+ void resourcePrefixRemoved(QtResourcePrefix *resourcePrefix);
+
+ void resourceFileInserted(QtResourceFile *resourceFile);
+ void resourceFileMoved(QtResourceFile *resourceFile, QtResourceFile *oldBeforeResourceFile);
+ void resourceAliasChanged(QtResourceFile *resourceFile, const QString &oldAlias);
+ void resourceFileRemoved(QtResourceFile *resourceFile);
+private:
+
+ QList<QtQrcFile *> m_qrcFiles;
+ QMap<QString, QtQrcFile *> m_pathToQrc;
+ QMap<QtQrcFile *, bool> m_qrcFileToExists;
+ QMap<QtResourcePrefix *, QtQrcFile *> m_prefixToQrc;
+ QMap<QtResourceFile *, QtResourcePrefix *> m_fileToPrefix;
+ QMap<QString, QList<QtResourceFile *> > m_fullPathToResourceFiles;
+ QMap<QString, QIcon> m_fullPathToIcon;
+ QMap<QString, bool> m_fullPathToExists;
+};
+
+QtQrcManager::QtQrcManager(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+QtQrcManager::~QtQrcManager()
+{
+ clear();
+}
+
+QList<QtQrcFile *> QtQrcManager::qrcFiles() const
+{
+ return m_qrcFiles;
+}
+
+QtQrcFile *QtQrcManager::qrcFileOf(const QString &path) const
+{
+ return m_pathToQrc.value(path);
+}
+
+QtQrcFile *QtQrcManager::qrcFileOf(QtResourcePrefix *resourcePrefix) const
+{
+ return m_prefixToQrc.value(resourcePrefix);
+}
+
+QtQrcFile *QtQrcManager::qrcFileOf(QtResourceFile *resourceFile) const
+{
+ return qrcFileOf(resourcePrefixOf(resourceFile));
+}
+
+QtResourcePrefix *QtQrcManager::resourcePrefixOf(QtResourceFile *resourceFile) const
+{
+ return m_fileToPrefix.value(resourceFile);
+}
+
+QtQrcFile *QtQrcManager::importQrcFile(const QtQrcFileData &qrcFileData, QtQrcFile *beforeQrcFile)
+{
+ QtQrcFile *qrcFile = insertQrcFile(qrcFileData.qrcPath, beforeQrcFile);
+ if (!qrcFile)
+ return 0;
+ QListIterator<QtResourcePrefixData> itPrefix(qrcFileData.resourceList);
+ while (itPrefix.hasNext()) {
+ const QtResourcePrefixData &prefixData = itPrefix.next();
+ QtResourcePrefix *resourcePrefix = insertResourcePrefix(qrcFile, prefixData.prefix, prefixData.language, 0);
+ QListIterator<QtResourceFileData> itFile(prefixData.resourceFileList);
+ while (itFile.hasNext()) {
+ const QtResourceFileData &fileData = itFile.next();
+ insertResourceFile(resourcePrefix, fileData.path, fileData.alias, 0);
+ }
+ }
+ setInitialState(qrcFile, qrcFileData);
+ return qrcFile;
+}
+
+void QtQrcManager::exportQrcFile(QtQrcFile *qrcFile, QtQrcFileData *qrcFileData) const
+{
+ if (!qrcFileData)
+ return;
+
+ if (!qrcFile)
+ return;
+
+ QtQrcFileData &data = *qrcFileData;
+
+ QList<QtResourcePrefixData> resourceList;
+
+ QList<QtResourcePrefix *> resourcePrefixes = qrcFile->resourcePrefixList();
+ QListIterator<QtResourcePrefix *> itPrefix(resourcePrefixes);
+ while (itPrefix.hasNext()) {
+ QList<QtResourceFileData> resourceFileList;
+
+ QtResourcePrefix *prefix = itPrefix.next();
+
+ QList<QtResourceFile *> resourceFiles = prefix->resourceFiles();
+ QListIterator<QtResourceFile *> itFile(resourceFiles);
+ while (itFile.hasNext()) {
+ QtResourceFile *file = itFile.next();
+ QtResourceFileData fileData;
+ fileData.path = file->path();
+ fileData.alias = file->alias();
+ resourceFileList << fileData;
+ }
+ QtResourcePrefixData prefixData;
+ prefixData.prefix = prefix->prefix();
+ prefixData.language = prefix->language();
+ prefixData.resourceFileList = resourceFileList;
+
+ resourceList << prefixData;
+ }
+ data = QtQrcFileData();
+ data.qrcPath = qrcFile->path();
+ data.resourceList = resourceList;
+}
+
+QList<QtResourceFile *> QtQrcManager::resourceFilesOf(const QString &resourcePath) const
+{
+ return m_fullPathToResourceFiles.value(resourcePath);
+}
+
+QIcon QtQrcManager::icon(const QString &resourceFullPath) const
+{
+ return m_fullPathToIcon.value(resourceFullPath);
+}
+
+bool QtQrcManager::exists(const QString &resourceFullPath) const
+{
+ return m_fullPathToExists.value(resourceFullPath, false);
+}
+
+bool QtQrcManager::exists(QtQrcFile *qrcFile) const
+{
+ return m_qrcFileToExists.value(qrcFile, false);
+}
+
+QtQrcFile *QtQrcManager::prevQrcFile(QtQrcFile *qrcFile) const
+{
+ if (!qrcFile)
+ return 0;
+ const int idx = m_qrcFiles.indexOf(qrcFile);
+ if (idx <= 0)
+ return 0;
+ return m_qrcFiles.at(idx - 1);
+}
+
+QtQrcFile *QtQrcManager::nextQrcFile(QtQrcFile *qrcFile) const
+{
+ if (!qrcFile)
+ return 0;
+ const int idx = m_qrcFiles.indexOf(qrcFile);
+ if (idx < 0 || idx == m_qrcFiles.size() - 1)
+ return 0;
+ return m_qrcFiles.at(idx + 1);
+}
+
+QtResourcePrefix *QtQrcManager::prevResourcePrefix(QtResourcePrefix *resourcePrefix) const
+{
+ if (!resourcePrefix)
+ return 0;
+ QList<QtResourcePrefix *> prefixes = qrcFileOf(resourcePrefix)->resourcePrefixList();
+ const int idx = prefixes.indexOf(resourcePrefix);
+ if (idx <= 0)
+ return 0;
+ return prefixes.at(idx - 1);
+}
+
+QtResourcePrefix *QtQrcManager::nextResourcePrefix(QtResourcePrefix *resourcePrefix) const
+{
+ if (!resourcePrefix)
+ return 0;
+ QList<QtResourcePrefix *> prefixes = qrcFileOf(resourcePrefix)->resourcePrefixList();
+ const int idx = prefixes.indexOf(resourcePrefix);
+ if (idx < 0 || idx == prefixes.size() - 1)
+ return 0;
+ return prefixes.at(idx + 1);
+}
+
+QtResourceFile *QtQrcManager::prevResourceFile(QtResourceFile *resourceFile) const
+{
+ if (!resourceFile)
+ return 0;
+ QList<QtResourceFile *> files = resourcePrefixOf(resourceFile)->resourceFiles();
+ const int idx = files.indexOf(resourceFile);
+ if (idx <= 0)
+ return 0;
+ return files.at(idx - 1);
+}
+
+QtResourceFile *QtQrcManager::nextResourceFile(QtResourceFile *resourceFile) const
+{
+ if (!resourceFile)
+ return 0;
+ QList<QtResourceFile *> files = resourcePrefixOf(resourceFile)->resourceFiles();
+ const int idx = files.indexOf(resourceFile);
+ if (idx < 0 || idx == files.size() - 1)
+ return 0;
+ return files.at(idx + 1);
+}
+
+void QtQrcManager::clear()
+{
+ QList<QtQrcFile *> oldQrcFiles = qrcFiles();
+ QListIterator<QtQrcFile *> it(oldQrcFiles);
+ while (it.hasNext())
+ removeQrcFile(it.next());
+}
+
+QtQrcFile *QtQrcManager::insertQrcFile(const QString &path, QtQrcFile *beforeQrcFile, bool newFile)
+{
+ if (m_pathToQrc.contains(path))
+ return 0;
+
+ int idx = m_qrcFiles.indexOf(beforeQrcFile);
+ if (idx < 0)
+ idx = m_qrcFiles.size();
+
+ QtQrcFile *qrcFile = new QtQrcFile();
+ qrcFile->setPath(path);
+
+ m_qrcFiles.insert(idx, qrcFile);
+ m_pathToQrc[path] = qrcFile;
+
+ const QFileInfo fi(path);
+ m_qrcFileToExists[qrcFile] = fi.exists() || newFile;
+
+ emit qrcFileInserted(qrcFile);
+ return qrcFile;
+}
+
+void QtQrcManager::moveQrcFile(QtQrcFile *qrcFile, QtQrcFile *beforeQrcFile)
+{
+ if (qrcFile == beforeQrcFile)
+ return;
+
+ const int idx = m_qrcFiles.indexOf(qrcFile);
+ if (idx < 0)
+ return;
+
+ int beforeIdx = m_qrcFiles.indexOf(beforeQrcFile);
+ if (beforeIdx < 0)
+ beforeIdx = m_qrcFiles.size();
+
+ if (idx == beforeIdx - 1) // the same position, nothing changes
+ return;
+
+ QtQrcFile *oldBefore = 0;
+ if (idx < m_qrcFiles.size() - 1)
+ oldBefore = m_qrcFiles.at(idx + 1);
+
+ m_qrcFiles.removeAt(idx);
+ if (idx < beforeIdx)
+ beforeIdx -= 1;
+
+ m_qrcFiles.insert(beforeIdx, qrcFile);
+
+ emit qrcFileMoved(qrcFile, oldBefore);
+}
+
+void QtQrcManager::setInitialState(QtQrcFile *qrcFile, const QtQrcFileData &initialState)
+{
+ qrcFile->m_initialState = initialState;
+}
+
+void QtQrcManager::removeQrcFile(QtQrcFile *qrcFile)
+{
+ const int idx = m_qrcFiles.indexOf(qrcFile);
+ if (idx < 0)
+ return;
+
+ QList<QtResourcePrefix *> resourcePrefixes = qrcFile->resourcePrefixList();
+ QListIterator<QtResourcePrefix *> it(resourcePrefixes);
+ while (it.hasNext())
+ removeResourcePrefix(it.next());
+
+ emit qrcFileRemoved(qrcFile);
+
+ m_qrcFiles.removeAt(idx);
+ m_pathToQrc.remove(qrcFile->path());
+ m_qrcFileToExists.remove(qrcFile);
+ delete qrcFile;
+}
+
+QtResourcePrefix *QtQrcManager::insertResourcePrefix(QtQrcFile *qrcFile, const QString &prefix,
+ const QString &language, QtResourcePrefix *beforeResourcePrefix)
+{
+ if (!qrcFile)
+ return 0;
+
+ int idx = qrcFile->m_resourcePrefixes.indexOf(beforeResourcePrefix);
+ if (idx < 0)
+ idx = qrcFile->m_resourcePrefixes.size();
+
+ QtResourcePrefix *resourcePrefix = new QtResourcePrefix();
+ resourcePrefix->m_prefix = prefix;
+ resourcePrefix->m_language = language;
+
+ qrcFile->m_resourcePrefixes.insert(idx, resourcePrefix);
+ m_prefixToQrc[resourcePrefix] = qrcFile;
+
+ emit resourcePrefixInserted(resourcePrefix);
+ return resourcePrefix;
+}
+
+void QtQrcManager::moveResourcePrefix(QtResourcePrefix *resourcePrefix, QtResourcePrefix *beforeResourcePrefix)
+{
+ if (resourcePrefix == beforeResourcePrefix)
+ return;
+
+ QtQrcFile *qrcFile = qrcFileOf(resourcePrefix);
+ if (!qrcFile)
+ return;
+
+ if (beforeResourcePrefix && qrcFileOf(beforeResourcePrefix) != qrcFile)
+ return;
+
+ const int idx = qrcFile->m_resourcePrefixes.indexOf(resourcePrefix);
+
+ int beforeIdx = qrcFile->m_resourcePrefixes.indexOf(beforeResourcePrefix);
+ if (beforeIdx < 0)
+ beforeIdx = qrcFile->m_resourcePrefixes.size();
+
+ if (idx == beforeIdx - 1) // the same position, nothing changes
+ return;
+
+ QtResourcePrefix *oldBefore = 0;
+ if (idx < qrcFile->m_resourcePrefixes.size() - 1)
+ oldBefore = qrcFile->m_resourcePrefixes.at(idx + 1);
+
+ qrcFile->m_resourcePrefixes.removeAt(idx);
+ if (idx < beforeIdx)
+ beforeIdx -= 1;
+
+ qrcFile->m_resourcePrefixes.insert(beforeIdx, resourcePrefix);
+
+ emit resourcePrefixMoved(resourcePrefix, oldBefore);
+}
+
+void QtQrcManager::changeResourcePrefix(QtResourcePrefix *resourcePrefix, const QString &newPrefix)
+{
+ if (!resourcePrefix)
+ return;
+
+ const QString oldPrefix = resourcePrefix->m_prefix;
+ if (oldPrefix == newPrefix)
+ return;
+
+ resourcePrefix->m_prefix = newPrefix;
+
+ emit resourcePrefixChanged(resourcePrefix, oldPrefix);
+}
+
+void QtQrcManager::changeResourceLanguage(QtResourcePrefix *resourcePrefix, const QString &newLanguage)
+{
+ if (!resourcePrefix)
+ return;
+
+ const QString oldLanguage = resourcePrefix->m_language;
+ if (oldLanguage == newLanguage)
+ return;
+
+ resourcePrefix->m_language = newLanguage;
+
+ emit resourceLanguageChanged(resourcePrefix, oldLanguage);
+}
+
+void QtQrcManager::removeResourcePrefix(QtResourcePrefix *resourcePrefix)
+{
+ QtQrcFile *qrcFile = qrcFileOf(resourcePrefix);
+ if (!qrcFile)
+ return;
+
+ const int idx = qrcFile->m_resourcePrefixes.indexOf(resourcePrefix);
+
+ QList<QtResourceFile *> resourceFiles = resourcePrefix->resourceFiles();
+ QListIterator<QtResourceFile *> it(resourceFiles);
+ while (it.hasNext())
+ removeResourceFile(it.next());
+
+ emit resourcePrefixRemoved(resourcePrefix);
+
+ qrcFile->m_resourcePrefixes.removeAt(idx);
+ m_prefixToQrc.remove(resourcePrefix);
+ delete resourcePrefix;
+}
+
+QtResourceFile *QtQrcManager::insertResourceFile(QtResourcePrefix *resourcePrefix, const QString &path,
+ const QString &alias, QtResourceFile *beforeResourceFile)
+{
+ if (!resourcePrefix)
+ return 0;
+
+ int idx = resourcePrefix->m_resourceFiles.indexOf(beforeResourceFile);
+ if (idx < 0)
+ idx = resourcePrefix->m_resourceFiles.size();
+
+ QtResourceFile *resourceFile = new QtResourceFile();
+ resourceFile->m_path = path;
+ resourceFile->m_alias = alias;
+ const QFileInfo fi(qrcFileOf(resourcePrefix)->path());
+ const QDir dir(fi.absolutePath());
+ const QString fullPath = dir.absoluteFilePath(path);
+ resourceFile->m_fullPath = fullPath;
+
+ resourcePrefix->m_resourceFiles.insert(idx, resourceFile);
+ m_fileToPrefix[resourceFile] = resourcePrefix;
+ m_fullPathToResourceFiles[fullPath].append(resourceFile);
+ if (!m_fullPathToIcon.contains(fullPath)) {
+ m_fullPathToIcon[fullPath] = QIcon(fullPath);
+ const QFileInfo fullInfo(fullPath);
+ m_fullPathToExists[fullPath] = fullInfo.exists();
+ }
+
+ emit resourceFileInserted(resourceFile);
+ return resourceFile;
+}
+
+void QtQrcManager::moveResourceFile(QtResourceFile *resourceFile, QtResourceFile *beforeResourceFile)
+{
+ if (resourceFile == beforeResourceFile)
+ return;
+
+ QtResourcePrefix *resourcePrefix = resourcePrefixOf(resourceFile);
+ if (!resourcePrefix)
+ return;
+
+ if (beforeResourceFile && resourcePrefixOf(beforeResourceFile) != resourcePrefix)
+ return;
+
+ const int idx = resourcePrefix->m_resourceFiles.indexOf(resourceFile);
+
+ int beforeIdx = resourcePrefix->m_resourceFiles.indexOf(beforeResourceFile);
+ if (beforeIdx < 0)
+ beforeIdx = resourcePrefix->m_resourceFiles.size();
+
+ if (idx == beforeIdx - 1) // the same position, nothing changes
+ return;
+
+ QtResourceFile *oldBefore = 0;
+ if (idx < resourcePrefix->m_resourceFiles.size() - 1)
+ oldBefore = resourcePrefix->m_resourceFiles.at(idx + 1);
+
+ resourcePrefix->m_resourceFiles.removeAt(idx);
+ if (idx < beforeIdx)
+ beforeIdx -= 1;
+
+ resourcePrefix->m_resourceFiles.insert(beforeIdx, resourceFile);
+
+ emit resourceFileMoved(resourceFile, oldBefore);
+}
+
+void QtQrcManager::changeResourceAlias(QtResourceFile *resourceFile, const QString &newAlias)
+{
+ if (!resourceFile)
+ return;
+
+ const QString oldAlias = resourceFile->m_alias;
+ if (oldAlias == newAlias)
+ return;
+
+ resourceFile->m_alias = newAlias;
+
+ emit resourceAliasChanged(resourceFile, oldAlias);
+}
+
+void QtQrcManager::removeResourceFile(QtResourceFile *resourceFile)
+{
+ QtResourcePrefix *resourcePrefix = resourcePrefixOf(resourceFile);
+ if (!resourcePrefix)
+ return;
+
+ const int idx = resourcePrefix->m_resourceFiles.indexOf(resourceFile);
+
+ emit resourceFileRemoved(resourceFile);
+
+ resourcePrefix->m_resourceFiles.removeAt(idx);
+ m_fileToPrefix.remove(resourceFile);
+ const QString fullPath = resourceFile->fullPath();
+ m_fullPathToResourceFiles[fullPath].removeAll(resourceFile); // optimize me
+ if (m_fullPathToResourceFiles[fullPath].isEmpty()) {
+ m_fullPathToResourceFiles.remove(fullPath);
+ m_fullPathToIcon.remove(fullPath);
+ m_fullPathToExists.remove(fullPath);
+ }
+ delete resourceFile;
+}
+
+
+
+}
+
+// ----------------- QtResourceEditorDialogPrivate
+class QtResourceEditorDialogPrivate
+{
+ QtResourceEditorDialog *q_ptr;
+ Q_DECLARE_PUBLIC(QtResourceEditorDialog)
+public:
+ QtResourceEditorDialogPrivate();
+
+ void slotQrcFileInserted(QtQrcFile *qrcFile);
+ void slotQrcFileMoved(QtQrcFile *qrcFile);
+ void slotQrcFileRemoved(QtQrcFile *qrcFile);
+
+ QStandardItem *insertResourcePrefix(QtResourcePrefix *resourcePrefix);
+
+ void slotResourcePrefixInserted(QtResourcePrefix *resourcePrefix) { insertResourcePrefix(resourcePrefix); }
+ void slotResourcePrefixMoved(QtResourcePrefix *resourcePrefix);
+ void slotResourcePrefixChanged(QtResourcePrefix *resourcePrefix);
+ void slotResourceLanguageChanged(QtResourcePrefix *resourcePrefix);
+ void slotResourcePrefixRemoved(QtResourcePrefix *resourcePrefix);
+ void slotResourceFileInserted(QtResourceFile *resourceFile);
+ void slotResourceFileMoved(QtResourceFile *resourceFile);
+ void slotResourceAliasChanged(QtResourceFile *resourceFile);
+ void slotResourceFileRemoved(QtResourceFile *resourceFile);
+
+ void slotCurrentQrcFileChanged(QListWidgetItem *item);
+ void slotCurrentTreeViewItemChanged(const QModelIndex &index);
+ void slotListWidgetContextMenuRequested(const QPoint &pos);
+ void slotTreeViewContextMenuRequested(const QPoint &pos);
+ void slotTreeViewItemChanged(QStandardItem *item);
+
+ void slotNewQrcFile();
+ void slotImportQrcFile();
+ void slotRemoveQrcFile();
+ void slotMoveUpQrcFile();
+ void slotMoveDownQrcFile();
+
+ void slotNewPrefix();
+ void slotAddFiles();
+ void slotChangePrefix();
+ void slotChangeLanguage();
+ void slotChangeAlias();
+ void slotClonePrefix();
+ void slotRemove();
+ void slotMoveUp();
+ void slotMoveDown();
+
+ bool loadQrcFile(const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage);
+ bool loadQrcFile(const QString &path, QtQrcFileData *qrcFileData);
+ bool saveQrcFile(const QtQrcFileData &qrcFileData);
+
+ QString qrcFileText(QtQrcFile *qrcFile) const;
+
+ QMessageBox::StandardButton warning(const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) const;
+
+ QString browseForNewLocation(const QString &resourceFile, const QDir &rootDir) const;
+ QString copyResourceFile(const QString &resourceFile, const QString &destPath) const;
+ QtResourceFile *getCurrentResourceFile() const;
+ QtResourcePrefix *getCurrentResourcePrefix() const;
+ void selectTreeRow(QStandardItem *item);
+ QString getSaveFileNameWithExtension(QWidget *parent,
+ const QString &title, QString dir, const QString &filter, const QString &extension) const;
+ QString qrcStartDirectory() const;
+
+ Ui::QtResourceEditorDialog m_ui;
+ QDesignerFormEditorInterface *m_core;
+ QtResourceModel *m_resourceModel;
+ QDesignerDialogGuiInterface *m_dlgGui;
+ QtQrcManager *m_qrcManager;
+ QList<QtQrcFileData> m_initialState;
+
+ QMap<QtQrcFile *, QListWidgetItem *> m_qrcFileToItem;
+ QMap<QListWidgetItem *, QtQrcFile *> m_itemToQrcFile;
+ QMap<QtResourcePrefix *, QStandardItem *> m_resourcePrefixToPrefixItem;
+ QMap<QtResourcePrefix *, QStandardItem *> m_resourcePrefixToLanguageItem;
+ QMap<QStandardItem *, QtResourcePrefix *> m_prefixItemToResourcePrefix;
+ QMap<QStandardItem *, QtResourcePrefix *> m_languageItemToResourcePrefix;
+ QMap<QtResourceFile *, QStandardItem *> m_resourceFileToPathItem;
+ QMap<QtResourceFile *, QStandardItem *> m_resourceFileToAliasItem;
+ QMap<QStandardItem *, QtResourceFile *> m_pathItemToResourceFile;
+ QMap<QStandardItem *, QtResourceFile *> m_aliasItemToResourceFile;
+
+ bool m_ignoreCurrentChanged;
+ bool m_firstQrcFileDialog;
+ QtQrcFile *m_currentQrcFile;
+
+ QAction *m_newQrcFileAction;
+ QAction *m_importQrcFileAction;
+ QAction *m_removeQrcFileAction;
+ QAction *m_moveUpQrcFileAction;
+ QAction *m_moveDownQrcFileAction;
+
+ QAction *m_newPrefixAction;
+ QAction *m_addResourceFileAction;
+ QAction *m_changePrefixAction;
+ QAction *m_changeLanguageAction;
+ QAction *m_changeAliasAction;
+ QAction *m_clonePrefixAction;
+ QAction *m_moveUpAction;
+ QAction *m_moveDownAction;
+ QAction *m_removeAction;
+
+ QStandardItemModel *m_treeModel;
+ QItemSelectionModel *m_treeSelection;
+};
+
+QtResourceEditorDialogPrivate::QtResourceEditorDialogPrivate() :
+ q_ptr(0),
+ m_core(0),
+ m_resourceModel(0),
+ m_dlgGui(0),
+ m_qrcManager(0),
+ m_ignoreCurrentChanged(false),
+ m_firstQrcFileDialog(true),
+ m_currentQrcFile(0),
+ m_newQrcFileAction(0),
+ m_importQrcFileAction(0),
+ m_removeQrcFileAction(0),
+ m_moveUpQrcFileAction(0),
+ m_moveDownQrcFileAction(0),
+ m_newPrefixAction(0),
+ m_addResourceFileAction(0),
+ m_changePrefixAction(0),
+ m_changeLanguageAction(0),
+ m_changeAliasAction(0),
+ m_clonePrefixAction(0),
+ m_moveUpAction(0),
+ m_moveDownAction(0),
+ m_removeAction(0),
+ m_treeModel(0),
+ m_treeSelection(0)
+{
+}
+
+QMessageBox::StandardButton QtResourceEditorDialogPrivate::warning(const QString &title, const QString &text, QMessageBox::StandardButtons buttons,
+ QMessageBox::StandardButton defaultButton) const
+{
+ return m_dlgGui->message(q_ptr, QDesignerDialogGuiInterface::ResourceEditorMessage, QMessageBox::Warning, title, text, buttons, defaultButton);
+}
+
+QString QtResourceEditorDialogPrivate::qrcFileText(QtQrcFile *qrcFile) const
+{
+ const QString path = qrcFile->path();
+ const QString fileName = qrcFile->fileName();
+ const QFileInfo fi(path);
+ if (fi.exists() && !fi.isWritable())
+ return QApplication::translate("QtResourceEditorDialog", "%1 [read-only]").arg(fileName);
+ if (!m_qrcManager->exists(qrcFile))
+ return QApplication::translate("QtResourceEditorDialog", "%1 [missing]").arg(fileName);
+ return fileName;
+}
+
+void QtResourceEditorDialogPrivate::slotQrcFileInserted(QtQrcFile *qrcFile)
+{
+ QListWidgetItem *currentItem = m_ui.qrcFileList->currentItem();
+ int idx = m_ui.qrcFileList->count();
+ QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(qrcFile);
+ QListWidgetItem *nextItem = m_qrcFileToItem.value(nextQrcFile);
+ if (nextItem) {
+ const int row = m_ui.qrcFileList->row(nextItem);
+ if (row >= 0)
+ idx = row;
+ }
+ const QString path = qrcFile->path();
+ QListWidgetItem *item = new QListWidgetItem(qrcFileText(qrcFile));
+ item->setToolTip(path);
+ m_ignoreCurrentChanged = true;
+ m_ui.qrcFileList->insertItem(idx, item);
+ m_ui.qrcFileList->setCurrentItem(currentItem);
+ m_ignoreCurrentChanged = false;
+ m_qrcFileToItem[qrcFile] = item;
+ m_itemToQrcFile[item] = qrcFile;
+ if (!m_qrcManager->exists(qrcFile))
+ item->setForeground(QBrush(Qt::red));
+}
+
+void QtResourceEditorDialogPrivate::slotQrcFileMoved(QtQrcFile *qrcFile)
+{
+ QListWidgetItem *currentItem = m_ui.qrcFileList->currentItem();
+ QListWidgetItem *item = m_qrcFileToItem.value(qrcFile);
+ m_ignoreCurrentChanged = true;
+ m_ui.qrcFileList->takeItem(m_ui.qrcFileList->row(item));
+
+ int idx = m_ui.qrcFileList->count();
+ QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(qrcFile);
+ QListWidgetItem *nextItem = m_qrcFileToItem.value(nextQrcFile);
+ if (nextItem) {
+ int row = m_ui.qrcFileList->row(nextItem);
+ if (row >= 0)
+ idx = row;
+ }
+ m_ui.qrcFileList->insertItem(idx, item);
+ if (currentItem == item)
+ m_ui.qrcFileList->setCurrentItem(item);
+ m_ignoreCurrentChanged = false;
+}
+
+void QtResourceEditorDialogPrivate::slotQrcFileRemoved(QtQrcFile *qrcFile)
+{
+ QListWidgetItem *item = m_qrcFileToItem.value(qrcFile);
+ if (item == m_ui.qrcFileList->currentItem())
+ m_ui.qrcFileList->setCurrentItem(0); // this should trigger list view signal currentItemChanged(0), and slot should set m_currentQrcFile to 0
+ m_ignoreCurrentChanged = true;
+ delete item;
+ m_ignoreCurrentChanged = false;
+ m_itemToQrcFile.remove(item);
+ m_qrcFileToItem.remove(qrcFile);
+}
+
+QStandardItem *QtResourceEditorDialogPrivate::insertResourcePrefix(QtResourcePrefix *resourcePrefix)
+{
+ if (m_qrcManager->qrcFileOf(resourcePrefix) != m_currentQrcFile)
+ return 0;
+
+ QtResourcePrefix *prevResourcePrefix = m_qrcManager->prevResourcePrefix(resourcePrefix);
+ QStandardItem *prevItem = m_resourcePrefixToPrefixItem.value(prevResourcePrefix);
+
+ int row = 0;
+ if (prevItem)
+ row = m_treeModel->indexFromItem(prevItem).row() + 1;
+
+ QStandardItem *prefixItem = new QStandardItem();
+ QStandardItem *languageItem = new QStandardItem();
+ QList<QStandardItem *> items;
+ items << prefixItem;
+ items << languageItem;
+ m_treeModel->insertRow(row, items);
+ const QModelIndex newIndex = m_treeModel->indexFromItem(prefixItem);
+ m_ui.resourceTreeView->setExpanded(newIndex, true);
+ prefixItem->setFlags(prefixItem->flags() | Qt::ItemIsEditable);
+ languageItem->setFlags(languageItem->flags() | Qt::ItemIsEditable);
+ m_resourcePrefixToPrefixItem[resourcePrefix] = prefixItem;
+ m_resourcePrefixToLanguageItem[resourcePrefix] = languageItem;
+ m_prefixItemToResourcePrefix[prefixItem] = resourcePrefix;
+ m_languageItemToResourcePrefix[languageItem] = resourcePrefix;
+ slotResourcePrefixChanged(resourcePrefix);
+ slotResourceLanguageChanged(resourcePrefix);
+ return prefixItem;
+}
+
+void QtResourceEditorDialogPrivate::slotResourcePrefixMoved(QtResourcePrefix *resourcePrefix)
+{
+ QStandardItem *prefixItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
+ if (!prefixItem)
+ return;
+
+ QStandardItem *languageItem = m_resourcePrefixToLanguageItem.value(resourcePrefix);
+ if (!languageItem)
+ return;
+
+ const QModelIndex index = m_treeModel->indexFromItem(prefixItem);
+ const bool expanded = m_ui.resourceTreeView->isExpanded(index);
+ m_ignoreCurrentChanged = true;
+ const QList<QStandardItem *> items = m_treeModel->takeRow(index.row());
+
+ int row = m_treeModel->rowCount();
+ QtResourcePrefix *nextResourcePrefix = m_qrcManager->nextResourcePrefix(resourcePrefix);
+ QStandardItem *nextItem = m_resourcePrefixToPrefixItem.value(nextResourcePrefix);
+ if (nextItem)
+ row = m_treeModel->indexFromItem(nextItem).row();
+ m_treeModel->insertRow(row, items);
+ m_ignoreCurrentChanged = false;
+ m_ui.resourceTreeView->setExpanded(m_treeModel->indexFromItem(items.at(0)), expanded);
+}
+
+void QtResourceEditorDialogPrivate::slotResourcePrefixChanged(QtResourcePrefix *resourcePrefix)
+{
+ QStandardItem *item = m_resourcePrefixToPrefixItem.value(resourcePrefix);
+ if (!item)
+ return;
+
+ m_ignoreCurrentChanged = true;
+ QString prefix = resourcePrefix->prefix();
+ if (prefix.isEmpty())
+ prefix = QApplication::translate("QtResourceEditorDialog", "<no prefix>", 0, QApplication::UnicodeUTF8);
+ item->setText(prefix);
+ item->setToolTip(prefix);
+ m_ignoreCurrentChanged = false;
+}
+
+void QtResourceEditorDialogPrivate::slotResourceLanguageChanged(QtResourcePrefix *resourcePrefix)
+{
+ QStandardItem *item = m_resourcePrefixToLanguageItem.value(resourcePrefix);
+ if (!item)
+ return;
+
+ m_ignoreCurrentChanged = true;
+ const QString language = resourcePrefix->language();
+ item->setText(language);
+ item->setToolTip(language);
+
+ m_ignoreCurrentChanged = false;
+}
+
+void QtResourceEditorDialogPrivate::slotResourcePrefixRemoved(QtResourcePrefix *resourcePrefix)
+{
+ QStandardItem *prefixItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
+ if (!prefixItem)
+ return;
+
+ QStandardItem *languageItem = m_resourcePrefixToLanguageItem.value(resourcePrefix);
+ if (!languageItem)
+ return;
+
+ m_ignoreCurrentChanged = true;
+ m_treeModel->takeRow(m_treeModel->indexFromItem(prefixItem).row());
+ delete prefixItem;
+ delete languageItem;
+ m_ignoreCurrentChanged = false;
+ m_prefixItemToResourcePrefix.remove(prefixItem);
+ m_languageItemToResourcePrefix.remove(languageItem);
+ m_resourcePrefixToPrefixItem.remove(resourcePrefix);
+ m_resourcePrefixToLanguageItem.remove(resourcePrefix);
+}
+
+void QtResourceEditorDialogPrivate::slotResourceFileInserted(QtResourceFile *resourceFile)
+{
+ QtResourcePrefix *resourcePrefix = m_qrcManager->resourcePrefixOf(resourceFile);
+ if (m_qrcManager->qrcFileOf(resourcePrefix) != m_currentQrcFile)
+ return;
+
+ QtResourceFile *prevResourceFile = m_qrcManager->prevResourceFile(resourceFile);
+ QStandardItem *prevItem = m_resourceFileToPathItem.value(prevResourceFile);
+
+ QStandardItem *pathItem = new QStandardItem(resourceFile->path());
+ QStandardItem *aliasItem = new QStandardItem();
+ QStandardItem *parentItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
+ QList<QStandardItem *> items;
+ items << pathItem;
+ items << aliasItem;
+
+ int row = 0;
+ if (prevItem)
+ row = m_treeModel->indexFromItem(prevItem).row() + 1;
+
+ parentItem->insertRow(row, items);
+
+ pathItem->setFlags(pathItem->flags() & ~Qt::ItemIsEditable);
+ aliasItem->setFlags(aliasItem->flags() | Qt::ItemIsEditable);
+ m_resourceFileToPathItem[resourceFile] = pathItem;
+ m_resourceFileToAliasItem[resourceFile] = aliasItem;
+ m_pathItemToResourceFile[pathItem] = resourceFile;
+ m_aliasItemToResourceFile[aliasItem] = resourceFile;
+ pathItem->setToolTip(resourceFile->path());
+ pathItem->setIcon(m_qrcManager->icon(resourceFile->fullPath()));
+ if (!m_qrcManager->exists(resourceFile->fullPath())) {
+ pathItem->setText(QApplication::translate("QtResourceEditorDialog", "%1 [missing]").arg(resourceFile->path()));
+ QBrush redBrush(Qt::red);
+ pathItem->setForeground(redBrush);
+ aliasItem->setForeground(redBrush);
+ }
+ slotResourceAliasChanged(resourceFile);
+}
+
+void QtResourceEditorDialogPrivate::slotResourceFileMoved(QtResourceFile *resourceFile)
+{
+ QStandardItem *pathItem = m_resourceFileToPathItem.value(resourceFile);
+ if (!pathItem)
+ return;
+
+ QStandardItem *aliasItem = m_resourceFileToAliasItem.value(resourceFile);
+ if (!aliasItem)
+ return;
+
+ QStandardItem *parentItem = pathItem->parent();
+ m_ignoreCurrentChanged = true;
+ const QList<QStandardItem *> items = parentItem->takeRow(m_treeModel->indexFromItem(pathItem).row());
+
+ int row = parentItem->rowCount();
+ QtResourceFile *nextResourceFile = m_qrcManager->nextResourceFile(resourceFile);
+ QStandardItem *nextItem = m_resourceFileToPathItem.value(nextResourceFile);
+ if (nextItem)
+ row = m_treeModel->indexFromItem(nextItem).row();
+ parentItem->insertRow(row, items);
+ m_ignoreCurrentChanged = false;
+}
+
+void QtResourceEditorDialogPrivate::slotResourceAliasChanged(QtResourceFile *resourceFile)
+{
+ QStandardItem *item = m_resourceFileToAliasItem.value(resourceFile);
+ if (!item)
+ return;
+
+ m_ignoreCurrentChanged = true;
+ const QString alias = resourceFile->alias();
+ item->setText(alias);
+ item->setToolTip(alias);
+
+ m_ignoreCurrentChanged = false;
+}
+
+void QtResourceEditorDialogPrivate::slotResourceFileRemoved(QtResourceFile *resourceFile)
+{
+ QStandardItem *pathItem = m_resourceFileToPathItem.value(resourceFile);
+ if (!pathItem)
+ return;
+
+ QStandardItem *aliasItem = m_resourceFileToAliasItem.value(resourceFile);
+ if (!aliasItem)
+ return;
+
+ QStandardItem *parentItem = pathItem->parent();
+
+ m_ignoreCurrentChanged = true;
+ parentItem->takeRow(m_treeModel->indexFromItem(pathItem).row());
+ delete pathItem;
+ delete aliasItem;
+ m_ignoreCurrentChanged = false;
+ m_pathItemToResourceFile.remove(pathItem);
+ m_aliasItemToResourceFile.remove(aliasItem);
+ m_resourceFileToPathItem.remove(resourceFile);
+ m_resourceFileToAliasItem.remove(resourceFile);
+}
+
+
+void QtResourceEditorDialogPrivate::slotCurrentQrcFileChanged(QListWidgetItem *item)
+{
+ if (m_ignoreCurrentChanged)
+ return;
+
+ QtQrcFile *newCurrentQrcFile = m_itemToQrcFile.value(item);
+
+ if (newCurrentQrcFile == m_currentQrcFile)
+ return;
+
+ if (m_currentQrcFile) {
+ QMap<QtResourcePrefix *, QStandardItem *> currentPrefixList = m_resourcePrefixToPrefixItem;
+ QMapIterator<QtResourcePrefix *, QStandardItem *> itPrefix(currentPrefixList);
+ while (itPrefix.hasNext()) {
+ QtResourcePrefix *resourcePrefix = itPrefix.next().key();
+ QList<QtResourceFile *> currentResourceFiles = resourcePrefix->resourceFiles();
+ QListIterator<QtResourceFile *> itFile(currentResourceFiles);
+ while (itFile.hasNext())
+ slotResourceFileRemoved(itFile.next());
+ slotResourcePrefixRemoved(resourcePrefix);
+ }
+ }
+
+ m_currentQrcFile = newCurrentQrcFile;
+ slotCurrentTreeViewItemChanged(QModelIndex());
+ QStandardItem *firstPrefix = 0; // select first prefix
+ if (m_currentQrcFile) {
+ QList<QtResourcePrefix *> newPrefixList = m_currentQrcFile->resourcePrefixList();
+ QListIterator<QtResourcePrefix *> itPrefix(newPrefixList);
+ while (itPrefix.hasNext()) {
+ QtResourcePrefix *resourcePrefix = itPrefix.next();
+ if (QStandardItem *newPrefixItem = insertResourcePrefix(resourcePrefix))
+ if (!firstPrefix)
+ firstPrefix = newPrefixItem;
+ QList<QtResourceFile *> newResourceFiles = resourcePrefix->resourceFiles();
+ QListIterator<QtResourceFile *> itFile(newResourceFiles);
+ while (itFile.hasNext())
+ slotResourceFileInserted(itFile.next());
+ }
+ }
+ m_ui.resourceTreeView->setCurrentIndex(firstPrefix ? m_treeModel->indexFromItem(firstPrefix) : QModelIndex());
+
+ m_removeQrcFileAction->setEnabled(m_currentQrcFile);
+ m_moveUpQrcFileAction->setEnabled(m_currentQrcFile && m_qrcManager->prevQrcFile(m_currentQrcFile));
+ m_moveDownQrcFileAction->setEnabled(m_currentQrcFile && m_qrcManager->nextQrcFile(m_currentQrcFile));
+}
+
+void QtResourceEditorDialogPrivate::slotCurrentTreeViewItemChanged(const QModelIndex &index)
+{
+ QStandardItem *item = m_treeModel->itemFromIndex(index);
+ QtResourceFile *resourceFile = m_pathItemToResourceFile.value(item);
+ if (!resourceFile)
+ resourceFile = m_aliasItemToResourceFile.value(item);
+ QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
+ if (!resourcePrefix)
+ resourcePrefix = m_languageItemToResourcePrefix.value(item);
+
+ bool moveUpEnabled = false;
+ bool moveDownEnabled = false;
+ bool currentItem = resourceFile || resourcePrefix;
+
+ if (resourceFile) {
+ if (m_qrcManager->prevResourceFile(resourceFile))
+ moveUpEnabled = true;
+ if (m_qrcManager->nextResourceFile(resourceFile))
+ moveDownEnabled = true;
+ } else if (resourcePrefix) {
+ if (m_qrcManager->prevResourcePrefix(resourcePrefix))
+ moveUpEnabled = true;
+ if (m_qrcManager->nextResourcePrefix(resourcePrefix))
+ moveDownEnabled = true;
+ }
+
+ m_newPrefixAction->setEnabled(m_currentQrcFile);
+ m_addResourceFileAction->setEnabled(currentItem);
+ m_changePrefixAction->setEnabled(currentItem);
+ m_changeLanguageAction->setEnabled(currentItem);
+ m_changeAliasAction->setEnabled(resourceFile);
+ m_removeAction->setEnabled(currentItem);
+ m_moveUpAction->setEnabled(moveUpEnabled);
+ m_moveDownAction->setEnabled(moveDownEnabled);
+ m_clonePrefixAction->setEnabled(currentItem);
+}
+
+void QtResourceEditorDialogPrivate::slotListWidgetContextMenuRequested(const QPoint &pos)
+{
+ QMenu menu(q_ptr);
+ menu.addAction(m_newQrcFileAction);
+ menu.addAction(m_importQrcFileAction);
+ menu.addAction(m_removeQrcFileAction);
+ menu.addSeparator();
+ menu.addAction(m_moveUpQrcFileAction);
+ menu.addAction(m_moveDownQrcFileAction);
+ menu.exec(m_ui.qrcFileList->mapToGlobal(pos));
+}
+
+void QtResourceEditorDialogPrivate::slotTreeViewContextMenuRequested(const QPoint &pos)
+{
+ QMenu menu(q_ptr);
+ menu.addAction(m_newPrefixAction);
+ menu.addAction(m_addResourceFileAction);
+ menu.addAction(m_removeAction);
+ menu.addSeparator();
+ menu.addAction(m_changePrefixAction);
+ menu.addAction(m_changeLanguageAction);
+ menu.addAction(m_changeAliasAction);
+ menu.addSeparator();
+ menu.addAction(m_clonePrefixAction);
+ menu.addSeparator();
+ menu.addAction(m_moveUpAction);
+ menu.addAction(m_moveDownAction);
+ menu.exec(m_ui.resourceTreeView->mapToGlobal(pos));
+}
+
+void QtResourceEditorDialogPrivate::slotTreeViewItemChanged(QStandardItem *item)
+{
+ if (m_ignoreCurrentChanged)
+ return;
+
+ const QString newValue = item->text();
+ QtResourceFile *resourceFile = m_aliasItemToResourceFile.value(item);
+ if (resourceFile) {
+ m_qrcManager->changeResourceAlias(resourceFile, newValue);
+ return;
+ }
+
+ QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
+ if (resourcePrefix) {
+ m_qrcManager->changeResourcePrefix(resourcePrefix, newValue);
+ return;
+ }
+
+ resourcePrefix = m_languageItemToResourcePrefix.value(item);
+ if (resourcePrefix) {
+ m_qrcManager->changeResourceLanguage(resourcePrefix, newValue);
+ return;
+ }
+}
+
+QString QtResourceEditorDialogPrivate::getSaveFileNameWithExtension(QWidget *parent,
+ const QString &title, QString dir, const QString &filter, const QString &extension) const
+{
+ const QChar dot = QLatin1Char('.');
+
+ QString saveFile;
+ while (true) {
+ saveFile = m_dlgGui->getSaveFileName(parent, title, dir, filter, 0, QFileDialog::DontConfirmOverwrite);
+ if (saveFile.isEmpty())
+ return saveFile;
+
+ const QFileInfo fInfo(saveFile);
+ if (fInfo.suffix().isEmpty() && !fInfo.fileName().endsWith(dot)) {
+ saveFile += dot;
+ saveFile += extension;
+ }
+
+ const QFileInfo fi(saveFile);
+ if (!fi.exists())
+ break;
+
+ if (warning(title, msgOverwrite(fi.fileName()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
+ break;
+
+ dir = saveFile;
+ }
+ return saveFile;
+}
+
+QString QtResourceEditorDialogPrivate::qrcStartDirectory() const
+{
+ if (!m_currentQrcFile)
+ return QString();
+ const QDir dir = QFileInfo(m_currentQrcFile->path()).dir();
+ return dir.exists() ? dir.absolutePath() : QString();
+}
+
+void QtResourceEditorDialogPrivate::slotNewQrcFile()
+{
+ const QString qrcPath = getSaveFileNameWithExtension(q_ptr,
+ QApplication::translate("QtResourceEditorDialog", "New Resource File", 0, QApplication::UnicodeUTF8),
+ m_firstQrcFileDialog ? qrcStartDirectory() : QString(),
+ QApplication::translate("QtResourceEditorDialog", "Resource files (*.qrc)", 0, QApplication::UnicodeUTF8),
+ QLatin1String("qrc"));
+ if (qrcPath.isEmpty())
+ return;
+
+ m_firstQrcFileDialog = false;
+ if (QtQrcFile *sameQrcFile = m_qrcManager->qrcFileOf(qrcPath)) {
+ // QMessageBox ???
+ QListWidgetItem *item = m_qrcFileToItem.value(sameQrcFile);
+ m_ui.qrcFileList->setCurrentItem(item);
+ item->setSelected(true);
+ return;
+ }
+
+ QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(m_currentQrcFile);
+
+ QtQrcFile *qrcFile = m_qrcManager->insertQrcFile(qrcPath, nextQrcFile, true);
+ m_ui.qrcFileList->setCurrentItem(m_qrcFileToItem.value(qrcFile));
+}
+
+void QtResourceEditorDialogPrivate::slotImportQrcFile()
+{
+ const QString qrcPath = m_dlgGui->getOpenFileName(q_ptr,
+ QApplication::translate("QtResourceEditorDialog", "Import Resource File", 0, QApplication::UnicodeUTF8),
+ m_firstQrcFileDialog ? qrcStartDirectory() : QString(),
+ QApplication::translate("QtResourceEditorDialog", "Resource files (*.qrc)", 0, QApplication::UnicodeUTF8));
+ if (qrcPath.isEmpty())
+ return;
+ m_firstQrcFileDialog = false;
+ if (QtQrcFile *sameQrcFile = m_qrcManager->qrcFileOf(qrcPath)) {
+ // QMessageBox ???
+ QListWidgetItem *item = m_qrcFileToItem.value(sameQrcFile);
+ m_ui.qrcFileList->setCurrentItem(item);
+ item->setSelected(true);
+ return;
+ }
+
+ QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(m_currentQrcFile);
+
+ QtQrcFileData qrcFileData;
+ loadQrcFile(qrcPath, &qrcFileData);
+ QtQrcFile *qrcFile = m_qrcManager->importQrcFile(qrcFileData, nextQrcFile);
+ m_ui.qrcFileList->setCurrentItem(m_qrcFileToItem.value(qrcFile));
+}
+
+void QtResourceEditorDialogPrivate::slotRemoveQrcFile()
+{
+ if (!m_currentQrcFile)
+ return;
+
+ QtQrcFile *currentQrcFile = m_qrcManager->nextQrcFile(m_currentQrcFile);
+ if (!currentQrcFile)
+ currentQrcFile = m_qrcManager->prevQrcFile(m_currentQrcFile);
+
+ m_qrcManager->removeQrcFile(m_currentQrcFile);
+ QListWidgetItem *item = m_qrcFileToItem.value(currentQrcFile);
+ if (item) {
+ m_ui.qrcFileList->setCurrentItem(item);
+ item->setSelected(true);
+ }
+}
+
+void QtResourceEditorDialogPrivate::slotMoveUpQrcFile()
+{
+ if (!m_currentQrcFile)
+ return;
+
+ QtQrcFile *prevQrcFile = m_qrcManager->prevQrcFile(m_currentQrcFile);
+ if (!prevQrcFile)
+ return;
+
+ m_qrcManager->moveQrcFile(m_currentQrcFile, prevQrcFile);
+}
+
+void QtResourceEditorDialogPrivate::slotMoveDownQrcFile()
+{
+ if (!m_currentQrcFile)
+ return;
+
+ QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(m_currentQrcFile);
+ if (!nextQrcFile)
+ return;
+ nextQrcFile = m_qrcManager->nextQrcFile(nextQrcFile);
+
+ m_qrcManager->moveQrcFile(m_currentQrcFile, nextQrcFile);
+}
+
+QtResourceFile *QtResourceEditorDialogPrivate::getCurrentResourceFile() const
+{
+ QStandardItem *currentItem = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
+
+
+ QtResourceFile *currentResourceFile = 0;
+ if (currentItem) {
+ currentResourceFile = m_pathItemToResourceFile.value(currentItem);
+ if (!currentResourceFile)
+ currentResourceFile = m_aliasItemToResourceFile.value(currentItem);
+ }
+ return currentResourceFile;
+}
+
+QtResourcePrefix *QtResourceEditorDialogPrivate::getCurrentResourcePrefix() const
+{
+ QStandardItem *currentItem = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
+
+ QtResourcePrefix *currentResourcePrefix = 0;
+ if (currentItem) {
+ currentResourcePrefix = m_prefixItemToResourcePrefix.value(currentItem);
+ if (!currentResourcePrefix) {
+ currentResourcePrefix = m_languageItemToResourcePrefix.value(currentItem);
+ if (!currentResourcePrefix) {
+ QtResourceFile *currentResourceFile = getCurrentResourceFile();
+ if (currentResourceFile)
+ currentResourcePrefix = m_qrcManager->resourcePrefixOf(currentResourceFile);
+ }
+ }
+ }
+ return currentResourcePrefix;
+}
+
+void QtResourceEditorDialogPrivate::selectTreeRow(QStandardItem *item)
+{
+ const QModelIndex index = m_treeModel->indexFromItem(item);
+ m_treeSelection->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+ m_treeSelection->setCurrentIndex(index, QItemSelectionModel::Select);
+}
+
+void QtResourceEditorDialogPrivate::slotNewPrefix()
+{
+ if (!m_currentQrcFile)
+ return;
+
+ QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
+ QtResourcePrefix *nextResourcePrefix = m_qrcManager->nextResourcePrefix(currentResourcePrefix);
+ QtResourcePrefix *newResourcePrefix = m_qrcManager->insertResourcePrefix(m_currentQrcFile,
+ QApplication::translate("QtResourceEditorDialog", "newPrefix", 0, QApplication::UnicodeUTF8),
+ QString(), nextResourcePrefix);
+ if (!newResourcePrefix)
+ return;
+
+ QStandardItem *newItem = m_resourcePrefixToPrefixItem.value(newResourcePrefix);
+ if (!newItem)
+ return;
+
+ const QModelIndex index = m_treeModel->indexFromItem(newItem);
+ selectTreeRow(newItem);
+ m_ui.resourceTreeView->edit(index);
+}
+
+static inline QString outOfPathWarning(const QString &fname)
+{
+ return QApplication::translate("QtResourceEditorDialog",
+ "<p><b>Warning:</b> The file</p>"
+ "<p>%1</p>"
+ "<p>is outside of the current resource file's parent directory.</p>").arg(fname);
+}
+
+static inline QString outOfPathWarningInfo()
+{
+ return QApplication::translate("QtResourceEditorDialog",
+ "<p>To resolve the issue, press:</p>"
+ "<table>"
+ "<tr><th align=\"left\">Copy</th><td>to copy the file to the resource file's parent directory.</td></tr>"
+ "<tr><th align=\"left\">Copy As...</th><td>to copy the file into a subdirectory of the resource file's parent directory.</td></tr>"
+ "<tr><th align=\"left\">Keep</th><td>to use its current location.</td></tr></table>");
+}
+
+void QtResourceEditorDialogPrivate::slotAddFiles()
+{
+ if (!m_currentQrcFile)
+ return;
+
+ QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
+ QtResourceFile *currentResourceFile = getCurrentResourceFile();
+ if (!currentResourcePrefix)
+ return;
+
+ QString initialPath = m_currentQrcFile->path();
+ if (currentResourceFile) {
+ QFileInfo fi(currentResourceFile->fullPath());
+ initialPath = fi.absolutePath();
+ }
+
+ const QStringList resourcePaths = m_dlgGui->getOpenImageFileNames(q_ptr,
+ QApplication::translate("QtResourceEditorDialog", "Add Files", 0, QApplication::UnicodeUTF8),
+ initialPath);
+ if (resourcePaths.isEmpty())
+ return;
+
+ QtResourceFile *nextResourceFile = m_qrcManager->nextResourceFile(currentResourceFile);
+ if (!currentResourceFile) {
+ QList<QtResourceFile *> resourceFiles = currentResourcePrefix->resourceFiles();
+ if (resourceFiles.count() > 0)
+ nextResourceFile = resourceFiles.first();
+ }
+
+ const QFileInfo fi(m_currentQrcFile->path());
+ const QString destDir = fi.absolutePath();
+ const QDir dir(fi.absolutePath());
+ QStringListIterator itResourcePath(resourcePaths);
+ while (itResourcePath.hasNext()) {
+ QString resourcePath = itResourcePath.next();
+ QString relativePath = dir.relativeFilePath(resourcePath);
+ if (relativePath.startsWith(QLatin1String(".."))) {
+ QMessageBox msgBox(QMessageBox::Warning,
+ QApplication::translate("QtResourceEditorDialog", "Incorrect Path", 0, QApplication::UnicodeUTF8),
+ outOfPathWarning(relativePath), QMessageBox::Cancel);
+ msgBox.setInformativeText(outOfPathWarningInfo());
+ QPushButton *copyButton = msgBox.addButton(QApplication::translate("QtResourceEditorDialog",
+ "Copy", 0, QApplication::UnicodeUTF8), QMessageBox::ActionRole);
+ QPushButton *copyAsButton = msgBox.addButton(QApplication::translate("QtResourceEditorDialog",
+ "Copy As...", 0, QApplication::UnicodeUTF8), QMessageBox::ActionRole);
+ QPushButton *keepButton = msgBox.addButton(QApplication::translate("QtResourceEditorDialog",
+ "Keep", 0, QApplication::UnicodeUTF8), QMessageBox::ActionRole);
+ QPushButton *skipButton = msgBox.addButton(QApplication::translate("QtResourceEditorDialog",
+ "Skip", 0, QApplication::UnicodeUTF8), QMessageBox::ActionRole);
+ msgBox.setEscapeButton(QMessageBox::Cancel);
+ msgBox.setDefaultButton(copyButton);
+ msgBox.exec();
+ QString destPath;
+ if (msgBox.clickedButton() == keepButton) {
+ // nothing
+ } else if (msgBox.clickedButton() == copyButton) {
+ QFileInfo resInfo(resourcePath);
+ QDir dd(destDir);
+ destPath = dd.absoluteFilePath(resInfo.fileName());
+ if (dd.exists(resInfo.fileName())) {
+ if (warning(QApplication::translate("QtResourceEditorDialog", "Copy", 0, QApplication::UnicodeUTF8),
+ msgOverwrite(resInfo.fileName()),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Yes)
+ continue;
+ }
+ resourcePath = copyResourceFile(resourcePath, destPath); // returns empty string in case copy failed or was canceled
+ } else if (msgBox.clickedButton() == copyAsButton) {
+ destPath = browseForNewLocation(resourcePath, dir); // returns empty string in case browsing was canceled
+ if (destPath.isEmpty())
+ continue;
+ resourcePath = copyResourceFile(resourcePath, destPath); // returns empty string in case copy failed or was canceled
+ } else if (msgBox.clickedButton() == skipButton) { // skipped
+ continue;
+ } else { // canceled
+ return;
+ }
+ if (resourcePath.isEmpty())
+ continue;
+ }
+ relativePath = dir.relativeFilePath(resourcePath);
+ QtResourceFile *newResourceFile = m_qrcManager->insertResourceFile(currentResourcePrefix, relativePath, QString(), nextResourceFile);
+
+ QStandardItem *newItem = m_resourceFileToPathItem.value(newResourceFile);
+ if (newItem)
+ selectTreeRow(newItem);
+ }
+}
+
+void QtResourceEditorDialogPrivate::slotChangePrefix()
+{
+ QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
+ if (!currentResourcePrefix)
+ return;
+
+ QStandardItem *item = m_resourcePrefixToPrefixItem.value(currentResourcePrefix);
+ QModelIndex index = m_treeModel->indexFromItem(item);
+ selectTreeRow(item);
+ m_ui.resourceTreeView->scrollTo(index);
+ m_ui.resourceTreeView->edit(index);
+}
+
+void QtResourceEditorDialogPrivate::slotChangeLanguage()
+{
+ QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
+ if (!currentResourcePrefix)
+ return;
+
+ QStandardItem *item = m_resourcePrefixToLanguageItem.value(currentResourcePrefix);
+ QModelIndex index = m_treeModel->indexFromItem(item);
+ selectTreeRow(item);
+ m_ui.resourceTreeView->scrollTo(index);
+ m_ui.resourceTreeView->edit(index);
+}
+
+void QtResourceEditorDialogPrivate::slotChangeAlias()
+{
+ QtResourceFile *currentResourceFile = getCurrentResourceFile();
+ if (!currentResourceFile)
+ return;
+
+ QStandardItem *item = m_resourceFileToAliasItem.value(currentResourceFile);
+ QModelIndex index = m_treeModel->indexFromItem(item);
+ selectTreeRow(item);
+ m_ui.resourceTreeView->scrollTo(index);
+ m_ui.resourceTreeView->edit(index);
+}
+
+void QtResourceEditorDialogPrivate::slotClonePrefix()
+{
+ QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
+ if (!currentResourcePrefix)
+ return;
+
+ bool ok;
+ QString suffix = QInputDialog::getText(q_ptr, QApplication::translate("QtResourceEditorDialog", "Clone Prefix", 0, QApplication::UnicodeUTF8),
+ QApplication::translate("QtResourceEditorDialog", "Enter the suffix which you want to add to the names of the cloned files.\n"
+ "This could for example be a language extension like \"_de\".", 0, QApplication::UnicodeUTF8),
+ QLineEdit::Normal, QString(), &ok);
+ if (!ok)
+ return;
+
+ QtResourcePrefix *newResourcePrefix = m_qrcManager->insertResourcePrefix(m_currentQrcFile, currentResourcePrefix->prefix(),
+ currentResourcePrefix->language(), m_qrcManager->nextResourcePrefix(currentResourcePrefix));
+ if (newResourcePrefix) {
+ QList<QtResourceFile *> files = currentResourcePrefix->resourceFiles();
+ QListIterator<QtResourceFile *> itFile(files);
+ while (itFile.hasNext()) {
+ QtResourceFile *resourceFile = itFile.next();
+ QString path = resourceFile->path();
+ QFileInfo fi(path);
+ QDir dir(fi.dir());
+ QString oldSuffix = fi.completeSuffix();
+ if (!oldSuffix.isEmpty())
+ oldSuffix = QLatin1Char('.') + oldSuffix;
+ const QString newBaseName = fi.baseName() + suffix + oldSuffix;
+ const QString newPath = QDir::cleanPath(dir.filePath(newBaseName));
+ m_qrcManager->insertResourceFile(newResourcePrefix, newPath,
+ resourceFile->alias());
+ }
+ }
+}
+
+void QtResourceEditorDialogPrivate::slotRemove()
+{
+ QStandardItem *item = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
+ if (!item)
+ return;
+
+ QtResourceFile *resourceFile = m_pathItemToResourceFile.value(item);
+ if (!resourceFile)
+ resourceFile = m_aliasItemToResourceFile.value(item);
+ QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
+ if (!resourcePrefix)
+ resourcePrefix = m_languageItemToResourcePrefix.value(item);
+
+ QStandardItem *newCurrentItem = 0;
+
+ if (resourceFile) {
+ QtResourceFile *nextFile = m_qrcManager->nextResourceFile(resourceFile);
+ if (!nextFile)
+ nextFile = m_qrcManager->prevResourceFile(resourceFile);
+ newCurrentItem = m_resourceFileToPathItem.value(nextFile);
+ if (!newCurrentItem)
+ newCurrentItem = m_resourcePrefixToPrefixItem.value(m_qrcManager->resourcePrefixOf(resourceFile));
+ }
+ if (!newCurrentItem) {
+ QtResourcePrefix *nextPrefix = m_qrcManager->nextResourcePrefix(resourcePrefix);
+ if (!nextPrefix)
+ nextPrefix = m_qrcManager->prevResourcePrefix(resourcePrefix);
+ newCurrentItem = m_resourcePrefixToPrefixItem.value(nextPrefix);
+ }
+
+ selectTreeRow(newCurrentItem);
+
+ if (resourcePrefix)
+ m_qrcManager->removeResourcePrefix(resourcePrefix);
+ else if (resourceFile)
+ m_qrcManager->removeResourceFile(resourceFile);
+}
+
+void QtResourceEditorDialogPrivate::slotMoveUp()
+{
+ if (QtResourceFile *resourceFile = getCurrentResourceFile()) {
+ QtResourceFile *prevFile = m_qrcManager->prevResourceFile(resourceFile);
+
+ if (!prevFile)
+ return;
+
+ m_qrcManager->moveResourceFile(resourceFile, prevFile);
+ selectTreeRow(m_resourceFileToPathItem.value(resourceFile));
+ } else if (QtResourcePrefix *resourcePrefix = getCurrentResourcePrefix()) {
+ QtResourcePrefix *prevPrefix = m_qrcManager->prevResourcePrefix(resourcePrefix);
+
+ if (!prevPrefix)
+ return;
+
+ m_qrcManager->moveResourcePrefix(resourcePrefix, prevPrefix);
+ selectTreeRow(m_resourcePrefixToPrefixItem.value(resourcePrefix));
+ }
+}
+
+void QtResourceEditorDialogPrivate::slotMoveDown()
+{
+ if (QtResourceFile *resourceFile = getCurrentResourceFile()) {
+ QtResourceFile *nextFile = m_qrcManager->nextResourceFile(resourceFile);
+
+ if (!nextFile)
+ return;
+
+ m_qrcManager->moveResourceFile(resourceFile, m_qrcManager->nextResourceFile(nextFile));
+ selectTreeRow(m_resourceFileToPathItem.value(resourceFile));
+ } else if (QtResourcePrefix *resourcePrefix = getCurrentResourcePrefix()) {
+ QtResourcePrefix *nextPrefix = m_qrcManager->nextResourcePrefix(resourcePrefix);
+
+ if (!nextPrefix)
+ return;
+
+ m_qrcManager->moveResourcePrefix(resourcePrefix, m_qrcManager->nextResourcePrefix(nextPrefix));
+ selectTreeRow(m_resourcePrefixToPrefixItem.value(resourcePrefix));
+ }
+}
+
+QString QtResourceEditorDialogPrivate::browseForNewLocation(const QString &resourceFile, const QDir &rootDir) const
+{
+ QFileInfo fi(resourceFile);
+ const QString initialPath = rootDir.absoluteFilePath(fi.fileName());
+ while (1) {
+ QString newPath = m_dlgGui->getSaveFileName(q_ptr,
+ QApplication::translate("QtResourceEditorDialog", "Copy As", 0, QApplication::UnicodeUTF8),
+ initialPath);
+ QString relativePath = rootDir.relativeFilePath(newPath);
+ if (relativePath.startsWith(QLatin1String(".."))) {
+ if (warning(QApplication::translate("QtResourceEditorDialog", "Copy As", 0, QApplication::UnicodeUTF8),
+ QApplication::translate("QtResourceEditorDialog", "<p>The selected file:</p>"
+ "<p>%1</p><p>is outside of the current resource file's directory:</p><p>%2</p>"
+ "<p>Please select another path within this directory.<p>", 0,
+ QApplication::UnicodeUTF8).arg(relativePath).arg(rootDir.absolutePath()),
+ QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok) != QMessageBox::Ok)
+ return QString();
+ } else {
+ return newPath;
+ }
+ }
+
+ return QString();
+}
+
+QString QtResourceEditorDialogPrivate::copyResourceFile(const QString &resourceFile, const QString &destPath) const
+{
+ QFileInfo fi(destPath);
+ if (fi.exists()) {
+ while (fi.exists() && !QFile::remove(destPath)) {
+ if (warning(QApplication::translate("QtResourceEditorDialog", "Copy", 0, QApplication::UnicodeUTF8),
+ QApplication::translate("QtResourceEditorDialog", "Could not overwrite %1.", 0, QApplication::UnicodeUTF8).arg(fi.fileName()),
+ QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Retry)
+ return QString();
+ }
+ }
+ while (!QFile::copy(resourceFile, destPath)) {
+ if (warning(QApplication::translate("QtResourceEditorDialog", "Copy", 0, QApplication::UnicodeUTF8),
+ QApplication::translate("QtResourceEditorDialog", "Could not copy\n%1\nto\n%2",
+ 0, QApplication::UnicodeUTF8).arg(resourceFile).arg(destPath),
+ QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Retry)
+ return QString();
+ }
+ return destPath;
+}
+bool QtResourceEditorDialogPrivate::loadQrcFile(const QString &path, QtQrcFileData *qrcFileData)
+{
+ QString errorMessage;
+ const bool rc = loadQrcFile(path, qrcFileData, &errorMessage);
+// if (!rc)
+// warning(QApplication::translate("QtResourceEditorDialog", "Resource File Load Error"), errorMessage);
+ return rc;
+}
+bool QtResourceEditorDialogPrivate::loadQrcFile(const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage)
+{
+ if (!qrcFileData)
+ return false;
+
+ qrcFileData->qrcPath = path;
+
+ QFile file(path);
+ if (!file.open(QIODevice::ReadOnly)) {
+ // there is sufficient hint while loading a form and after opening the editor (qrc marked marked with red and with [missing] text)
+ //*errorMessage = QApplication::translate("QtResourceEditorDialog", "Unable to open %1 for reading: %2").arg(path).arg(file.errorString());
+ return false;
+ }
+
+ QByteArray dataArray = file.readAll();
+ file.close();
+
+ QDomDocument doc;
+ int errLine, errCol;
+ if (!doc.setContent(dataArray, errorMessage, &errLine, &errCol)) {
+ *errorMessage = QCoreApplication::translate("QtResourceEditorDialog", "A parse error occurred at line %1, column %2 of %3:\n%4").arg(errLine).arg(errCol).arg(path).arg(*errorMessage);
+ return false;
+ }
+
+ return loadQrcFileData(doc, path, qrcFileData, errorMessage);
+}
+
+bool QtResourceEditorDialogPrivate::saveQrcFile(const QtQrcFileData &qrcFileData)
+{
+ QFile file(qrcFileData.qrcPath);
+ while (!file.open(QIODevice::WriteOnly)) {
+ QMessageBox msgBox(QMessageBox::Warning,
+ QApplication::translate("QtResourceEditorDialog", "Save Resource File", 0, QApplication::UnicodeUTF8),
+ QApplication::translate("QtResourceEditorDialog", "Could not write %1: %2", 0, QApplication::UnicodeUTF8).arg(qrcFileData.qrcPath).arg(file.errorString()),
+ QMessageBox::Cancel|QMessageBox::Ignore|QMessageBox::Retry);
+ msgBox.setEscapeButton(QMessageBox::Cancel);
+ msgBox.setDefaultButton(QMessageBox::Ignore);
+ switch (msgBox.exec()) {
+ case QMessageBox::Retry:
+ break; // nothing
+ case QMessageBox::Ignore:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ QDomDocument doc = saveQrcFileData(qrcFileData);
+
+ QByteArray dataArray = doc.toByteArray(2);
+ file.write(dataArray);
+
+ file.close();
+ return true;
+}
+
+QtResourceEditorDialog::QtResourceEditorDialog(QDesignerFormEditorInterface *core, QDesignerDialogGuiInterface *dlgGui, QWidget *parent)
+ : QDialog(parent), d_ptr(new QtResourceEditorDialogPrivate())
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_ui.setupUi(this);
+ d_ptr->m_qrcManager = new QtQrcManager(this);
+ d_ptr->m_dlgGui = dlgGui;
+ d_ptr->m_core = core;
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setWindowTitle(tr("Edit Resources"));
+
+ connect(d_ptr->m_qrcManager, SIGNAL(qrcFileInserted(QtQrcFile*)),
+ this, SLOT(slotQrcFileInserted(QtQrcFile*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(qrcFileMoved(QtQrcFile*,QtQrcFile*)),
+ this, SLOT(slotQrcFileMoved(QtQrcFile*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(qrcFileRemoved(QtQrcFile*)),
+ this, SLOT(slotQrcFileRemoved(QtQrcFile*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourcePrefixInserted(QtResourcePrefix*)),
+ this, SLOT(slotResourcePrefixInserted(QtResourcePrefix*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourcePrefixMoved(QtResourcePrefix*,QtResourcePrefix*)),
+ this, SLOT(slotResourcePrefixMoved(QtResourcePrefix*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourcePrefixChanged(QtResourcePrefix*,QString)),
+ this, SLOT(slotResourcePrefixChanged(QtResourcePrefix*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourceLanguageChanged(QtResourcePrefix*,QString)),
+ this, SLOT(slotResourceLanguageChanged(QtResourcePrefix*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourcePrefixRemoved(QtResourcePrefix*)),
+ this, SLOT(slotResourcePrefixRemoved(QtResourcePrefix*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourceFileInserted(QtResourceFile*)),
+ this, SLOT(slotResourceFileInserted(QtResourceFile*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourceFileMoved(QtResourceFile*,QtResourceFile*)),
+ this, SLOT(slotResourceFileMoved(QtResourceFile*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourceAliasChanged(QtResourceFile*,QString)),
+ this, SLOT(slotResourceAliasChanged(QtResourceFile*)));
+ connect(d_ptr->m_qrcManager, SIGNAL(resourceFileRemoved(QtResourceFile*)),
+ this, SLOT(slotResourceFileRemoved(QtResourceFile*)));
+
+ QIcon upIcon = qdesigner_internal::createIconSet(QString::fromUtf8("up.png"));
+ QIcon downIcon = qdesigner_internal::createIconSet(QString::fromUtf8("down.png"));
+ QIcon minusIcon = qdesigner_internal::createIconSet(QString::fromUtf8("minus-16.png"));
+ QIcon newIcon = qdesigner_internal::createIconSet(QString::fromUtf8("filenew-16.png"));
+ QIcon openIcon = qdesigner_internal::createIconSet(QString::fromUtf8("fileopen-16.png"));
+ QIcon removeIcon = qdesigner_internal::createIconSet(QString::fromUtf8("editdelete-16.png"));
+ QIcon addPrefixIcon = qdesigner_internal::createIconSet(QString::fromUtf8("prefix-add.png"));
+
+ d_ptr->m_newQrcFileAction = new QAction(newIcon, tr("New..."), this);
+ d_ptr->m_newQrcFileAction->setToolTip(tr("New Resource File"));
+ d_ptr->m_importQrcFileAction = new QAction(openIcon, tr("Open..."), this);
+ d_ptr->m_importQrcFileAction->setToolTip(tr("Open Resource File"));
+ d_ptr->m_removeQrcFileAction = new QAction(removeIcon, tr("Remove"), this);
+ d_ptr->m_moveUpQrcFileAction = new QAction(upIcon, tr("Move Up"), this);
+ d_ptr->m_moveDownQrcFileAction = new QAction(downIcon, tr("Move Down"), this);
+
+ d_ptr->m_newPrefixAction = new QAction(addPrefixIcon, tr("Add Prefix"), this);
+ d_ptr->m_newPrefixAction->setToolTip(tr("Add Prefix"));
+ d_ptr->m_addResourceFileAction = new QAction(openIcon, tr("Add Files..."), this);
+ d_ptr->m_changePrefixAction = new QAction(tr("Change Prefix"), this);
+ d_ptr->m_changeLanguageAction = new QAction(tr("Change Language"), this);
+ d_ptr->m_changeAliasAction = new QAction(tr("Change Alias"), this);
+ d_ptr->m_clonePrefixAction = new QAction(tr("Clone Prefix..."), this);
+ d_ptr->m_removeAction = new QAction(minusIcon, tr("Remove"), this);
+ d_ptr->m_moveUpAction = new QAction(upIcon, tr("Move Up"), this);
+ d_ptr->m_moveDownAction = new QAction(downIcon, tr("Move Down"), this);
+
+ d_ptr->m_ui.newQrcButton->setDefaultAction(d_ptr->m_newQrcFileAction);
+ d_ptr->m_ui.importQrcButton->setDefaultAction(d_ptr->m_importQrcFileAction);
+ d_ptr->m_ui.removeQrcButton->setDefaultAction(d_ptr->m_removeQrcFileAction);
+
+ d_ptr->m_ui.newResourceButton->setDefaultAction(d_ptr->m_newPrefixAction);
+ d_ptr->m_ui.addResourceButton->setDefaultAction(d_ptr->m_addResourceFileAction);
+ d_ptr->m_ui.removeResourceButton->setDefaultAction(d_ptr->m_removeAction);
+
+ connect(d_ptr->m_newQrcFileAction, SIGNAL(triggered()), this, SLOT(slotNewQrcFile()));
+ connect(d_ptr->m_importQrcFileAction, SIGNAL(triggered()), this, SLOT(slotImportQrcFile()));
+ connect(d_ptr->m_removeQrcFileAction, SIGNAL(triggered()), this, SLOT(slotRemoveQrcFile()));
+ connect(d_ptr->m_moveUpQrcFileAction, SIGNAL(triggered()), this, SLOT(slotMoveUpQrcFile()));
+ connect(d_ptr->m_moveDownQrcFileAction, SIGNAL(triggered()), this, SLOT(slotMoveDownQrcFile()));
+
+ connect(d_ptr->m_newPrefixAction, SIGNAL(triggered()), this, SLOT(slotNewPrefix()));
+ connect(d_ptr->m_addResourceFileAction, SIGNAL(triggered()), this, SLOT(slotAddFiles()));
+ connect(d_ptr->m_changePrefixAction, SIGNAL(triggered()), this, SLOT(slotChangePrefix()));
+ connect(d_ptr->m_changeLanguageAction, SIGNAL(triggered()), this, SLOT(slotChangeLanguage()));
+ connect(d_ptr->m_changeAliasAction, SIGNAL(triggered()), this, SLOT(slotChangeAlias()));
+ connect(d_ptr->m_clonePrefixAction, SIGNAL(triggered()), this, SLOT(slotClonePrefix()));
+ connect(d_ptr->m_removeAction, SIGNAL(triggered()), this, SLOT(slotRemove()));
+ connect(d_ptr->m_moveUpAction, SIGNAL(triggered()), this, SLOT(slotMoveUp()));
+ connect(d_ptr->m_moveDownAction, SIGNAL(triggered()), this, SLOT(slotMoveDown()));
+
+ d_ptr->m_ui.qrcFileList->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(d_ptr->m_ui.qrcFileList, SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(slotListWidgetContextMenuRequested(QPoint)));
+ connect(d_ptr->m_ui.qrcFileList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ this, SLOT(slotCurrentQrcFileChanged(QListWidgetItem*)));
+
+ d_ptr->m_treeModel = new QStandardItemModel(this);
+ d_ptr->m_treeModel->setColumnCount(2);
+ d_ptr->m_treeModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Prefix / Path")));
+ d_ptr->m_treeModel->setHorizontalHeaderItem(1, new QStandardItem(tr("Language / Alias")));
+ d_ptr->m_ui.resourceTreeView->setModel(d_ptr->m_treeModel);
+ d_ptr->m_ui.resourceTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
+ d_ptr->m_treeSelection = d_ptr->m_ui.resourceTreeView->selectionModel();
+ connect(d_ptr->m_ui.resourceTreeView->header(), SIGNAL(sectionDoubleClicked(int)), d_ptr->m_ui.resourceTreeView, SLOT(resizeColumnToContents(int)));
+ d_ptr->m_ui.resourceTreeView->setTextElideMode(Qt::ElideLeft);
+
+ connect(d_ptr->m_ui.resourceTreeView, SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(slotTreeViewContextMenuRequested(QPoint)));
+ connect(d_ptr->m_treeModel, SIGNAL(itemChanged(QStandardItem*)),
+ this, SLOT(slotTreeViewItemChanged(QStandardItem*)));
+ connect(d_ptr->m_treeSelection, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(slotCurrentTreeViewItemChanged(QModelIndex)));
+
+ d_ptr->m_ui.resourceTreeView->setColumnWidth(0, 200);
+
+ d_ptr->slotCurrentTreeViewItemChanged(QModelIndex());
+ d_ptr->m_removeQrcFileAction->setEnabled(false);
+ d_ptr->m_moveUpQrcFileAction->setEnabled(false);
+ d_ptr->m_moveDownQrcFileAction->setEnabled(false);
+
+ QDesignerSettingsInterface *settings = core->settingsManager();
+ settings->beginGroup(QLatin1String(QrcDialogC));
+
+ d_ptr->m_ui.splitter->restoreState(settings->value(QLatin1String(SplitterPosition)).toByteArray());
+ if (settings->contains(QLatin1String(Geometry)))
+ setGeometry(settings->value(QLatin1String(Geometry)).toRect());
+
+ settings->endGroup();
+}
+
+QtResourceEditorDialog::~QtResourceEditorDialog()
+{
+ QDesignerSettingsInterface *settings = d_ptr->m_core->settingsManager();
+ settings->beginGroup(QLatin1String(QrcDialogC));
+
+ settings->setValue(QLatin1String(SplitterPosition), d_ptr->m_ui.splitter->saveState());
+ settings->setValue(QLatin1String(Geometry), geometry());
+ settings->endGroup();
+}
+
+QtResourceModel *QtResourceEditorDialog::model() const
+{
+ return d_ptr->m_resourceModel;
+}
+
+void QtResourceEditorDialog::setResourceModel(QtResourceModel *model)
+{
+ d_ptr->m_resourceModel = model;
+
+ QtResourceSet *resourceSet = d_ptr->m_resourceModel->currentResourceSet();
+ if (!resourceSet) {
+ // disable everything but cancel button
+ return;
+ }
+
+ d_ptr->m_initialState.clear();
+
+ // enable qrcBox
+
+ QStringList paths = resourceSet->activeQrcPaths();
+ QStringListIterator it(paths);
+ while (it.hasNext()) {
+ const QString path = it.next();
+ QtQrcFileData qrcFileData;
+ d_ptr->loadQrcFile(path, &qrcFileData);
+ d_ptr->m_initialState << qrcFileData;
+ d_ptr->m_qrcManager->importQrcFile(qrcFileData);
+ }
+ if (d_ptr->m_ui.qrcFileList->count() > 0) {
+ d_ptr->m_ui.qrcFileList->item(0)->setSelected(true);
+ }
+}
+
+QString QtResourceEditorDialog::selectedResource() const
+{
+ //QtResourcePrefix *currentResourcePrefix = d_ptr->m_qrcManager->resourcePrefixOf(currentResourceFile);
+ QtResourcePrefix *currentResourcePrefix = d_ptr->getCurrentResourcePrefix();
+ if (!currentResourcePrefix)
+ return QString();
+
+ const QChar slash(QLatin1Char('/'));
+ QString resource = currentResourcePrefix->prefix();
+ if (!resource.startsWith(slash))
+ resource.prepend(slash);
+ if (!resource.endsWith(slash))
+ resource.append(slash);
+ resource.prepend(QLatin1Char(':'));
+
+ QtResourceFile *currentResourceFile = d_ptr->getCurrentResourceFile();
+ if (!currentResourceFile)
+ return resource;
+
+ QString resourceEnding = currentResourceFile->path();
+ if (!currentResourceFile->alias().isEmpty())
+ resourceEnding = currentResourceFile->alias();
+
+ const QString dotSlash(QLatin1String("./"));
+ const QString dotDotSlash(QLatin1String("../"));
+ while (1) {
+ if (resourceEnding.startsWith(slash))
+ resourceEnding = resourceEnding.mid(1);
+ else if (resourceEnding.startsWith(dotSlash))
+ resourceEnding = resourceEnding.mid(dotSlash.count());
+ else if (resourceEnding.startsWith(dotDotSlash))
+ resourceEnding = resourceEnding.mid(dotDotSlash.count());
+ else
+ break;
+ }
+
+ resource.append(resourceEnding);
+
+ return resource;
+}
+
+void QtResourceEditorDialog::displayResourceFailures(const QString &logOutput, QDesignerDialogGuiInterface *dlgGui, QWidget *parent)
+{
+ const QString msg = tr("<html><p><b>Warning:</b> There have been problems while reloading the resources:</p><pre>%1</pre></html>").arg(logOutput);
+ dlgGui->message(parent, QDesignerDialogGuiInterface::ResourceEditorMessage, QMessageBox::Warning,
+ tr("Resource Warning"), msg);
+}
+
+void QtResourceEditorDialog::accept()
+{
+ QStringList newQrcPaths;
+ QList<QtQrcFileData> currentState;
+
+ QList<QtQrcFile *> qrcFiles = d_ptr->m_qrcManager->qrcFiles();
+ QListIterator<QtQrcFile *> itQrc(qrcFiles);
+ while (itQrc.hasNext()) {
+ QtQrcFile *qrcFile = itQrc.next();
+ QtQrcFileData qrcFileData;
+ d_ptr->m_qrcManager->exportQrcFile(qrcFile, &qrcFileData);
+ currentState << qrcFileData;
+ if (qrcFileData == qrcFile->initialState()) {
+ // nothing
+ } else {
+ d_ptr->m_resourceModel->setWatcherEnabled(qrcFileData.qrcPath, false);
+ bool ok = d_ptr->saveQrcFile(qrcFileData);
+ d_ptr->m_resourceModel->setWatcherEnabled(qrcFileData.qrcPath, true);
+ if (!ok)
+ return;
+
+ d_ptr->m_resourceModel->setModified(qrcFileData.qrcPath);
+ }
+ newQrcPaths << qrcFileData.qrcPath;
+ }
+
+ if (currentState == d_ptr->m_initialState) {
+ // nothing
+ } else {
+ int errorCount;
+ QString errorMessages;
+ d_ptr->m_resourceModel->currentResourceSet()->activateQrcPaths(newQrcPaths, &errorCount, &errorMessages);
+ if (errorCount)
+ displayResourceFailures(errorMessages, d_ptr->m_dlgGui, this);
+ }
+ QDialog::accept();
+}
+
+QString QtResourceEditorDialog::editResources(QDesignerFormEditorInterface *core,
+ QtResourceModel *model,
+ QDesignerDialogGuiInterface *dlgGui,
+ QWidget *parent)
+{
+ QtResourceEditorDialog dialog(core, dlgGui, parent);
+ dialog.setResourceModel(model);
+ if (dialog.exec() == QDialog::Accepted)
+ return dialog.selectedResource();
+ return QString();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtresourceeditordialog_p.cpp"
+#include "qtresourceeditordialog.moc"
diff --git a/src/designer/src/lib/shared/qtresourceeditordialog.ui b/src/designer/src/lib/shared/qtresourceeditordialog.ui
new file mode 100644
index 000000000..fa760d9a1
--- /dev/null
+++ b/src/designer/src/lib/shared/qtresourceeditordialog.ui
@@ -0,0 +1,177 @@
+<ui version="4.0" >
+ <class>QtResourceEditorDialog</class>
+ <widget class="QDialog" name="QtResourceEditorDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>469</width>
+ <height>317</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="QSplitter" name="splitter" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="childrenCollapsible" >
+ <bool>false</bool>
+ </property>
+ <widget class="QWidget" name="qrcLayoutWidget" >
+ <layout class="QGridLayout" name="qrcLayout" >
+ <item row="0" column="0" colspan="4" >
+ <widget class="QListWidget" name="qrcFileList" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QToolButton" name="newQrcButton" >
+ <property name="toolTip" >
+ <string>New File</string>
+ </property>
+ <property name="text" >
+ <string>N</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QToolButton" name="removeQrcButton" >
+ <property name="toolTip" >
+ <string>Remove File</string>
+ </property>
+ <property name="text" >
+ <string>R</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Ignored</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QToolButton" name="importQrcButton" >
+ <property name="text" >
+ <string>I</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="resourceLayoutWidget" >
+ <layout class="QGridLayout" name="resourceLayout" >
+ <item row="0" column="0" colspan="4" >
+ <widget class="QTreeView" name="resourceTreeView" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QToolButton" name="newResourceButton" >
+ <property name="toolTip" >
+ <string>New Resource</string>
+ </property>
+ <property name="text" >
+ <string>N</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QToolButton" name="addResourceButton" >
+ <property name="text" >
+ <string>A</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QToolButton" name="removeResourceButton" >
+ <property name="toolTip" >
+ <string>Remove Resource or File</string>
+ </property>
+ <property name="text" >
+ <string>R</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtResourceEditorDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtResourceEditorDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/qtresourceeditordialog_p.h b/src/designer/src/lib/shared/qtresourceeditordialog_p.h
new file mode 100644
index 000000000..eef3bf540
--- /dev/null
+++ b/src/designer/src/lib/shared/qtresourceeditordialog_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QTRESOURCEEDITOR_H
+#define QTRESOURCEEDITOR_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QtResourceModel;
+class QDesignerDialogGuiInterface;
+class QDesignerFormEditorInterface;
+
+class QtResourceEditorDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ QtResourceModel *model() const;
+ void setResourceModel(QtResourceModel *model);
+
+ QString selectedResource() const;
+
+ static QString editResources(QDesignerFormEditorInterface *core, QtResourceModel *model,
+ QDesignerDialogGuiInterface *dlgGui, QWidget *parent = 0);
+
+ // Helper to display a message box with rcc logs in case of errors.
+ static void displayResourceFailures(const QString &logOutput, QDesignerDialogGuiInterface *dlgGui, QWidget *parent = 0);
+
+public slots:
+ virtual void accept();
+
+private:
+ QtResourceEditorDialog(QDesignerFormEditorInterface *core, QDesignerDialogGuiInterface *dlgGui, QWidget *parent = 0);
+ ~QtResourceEditorDialog();
+
+ QScopedPointer<class QtResourceEditorDialogPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtResourceEditorDialog)
+ Q_DISABLE_COPY(QtResourceEditorDialog)
+
+ Q_PRIVATE_SLOT(d_func(), void slotQrcFileInserted(QtQrcFile *))
+ Q_PRIVATE_SLOT(d_func(), void slotQrcFileMoved(QtQrcFile *))
+ Q_PRIVATE_SLOT(d_func(), void slotQrcFileRemoved(QtQrcFile *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourcePrefixInserted(QtResourcePrefix *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourcePrefixMoved(QtResourcePrefix *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourcePrefixChanged(QtResourcePrefix *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourceLanguageChanged(QtResourcePrefix *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourcePrefixRemoved(QtResourcePrefix *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourceFileInserted(QtResourceFile *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourceFileMoved(QtResourceFile *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourceAliasChanged(QtResourceFile *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourceFileRemoved(QtResourceFile *))
+
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentQrcFileChanged(QListWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentTreeViewItemChanged(const QModelIndex &))
+ Q_PRIVATE_SLOT(d_func(), void slotListWidgetContextMenuRequested(const QPoint &))
+ Q_PRIVATE_SLOT(d_func(), void slotTreeViewContextMenuRequested(const QPoint &))
+ Q_PRIVATE_SLOT(d_func(), void slotTreeViewItemChanged(QStandardItem *))
+
+ Q_PRIVATE_SLOT(d_func(), void slotNewQrcFile())
+ Q_PRIVATE_SLOT(d_func(), void slotImportQrcFile())
+ Q_PRIVATE_SLOT(d_func(), void slotRemoveQrcFile())
+ Q_PRIVATE_SLOT(d_func(), void slotMoveUpQrcFile())
+ Q_PRIVATE_SLOT(d_func(), void slotMoveDownQrcFile())
+
+ Q_PRIVATE_SLOT(d_func(), void slotNewPrefix())
+ Q_PRIVATE_SLOT(d_func(), void slotAddFiles())
+ Q_PRIVATE_SLOT(d_func(), void slotChangePrefix())
+ Q_PRIVATE_SLOT(d_func(), void slotChangeLanguage())
+ Q_PRIVATE_SLOT(d_func(), void slotChangeAlias())
+ Q_PRIVATE_SLOT(d_func(), void slotClonePrefix())
+ Q_PRIVATE_SLOT(d_func(), void slotRemove())
+ Q_PRIVATE_SLOT(d_func(), void slotMoveUp())
+ Q_PRIVATE_SLOT(d_func(), void slotMoveDown())
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/designer/src/lib/shared/qtresourcemodel.cpp b/src/designer/src/lib/shared/qtresourcemodel.cpp
new file mode 100644
index 000000000..ca2fb7882
--- /dev/null
+++ b/src/designer/src/lib/shared/qtresourcemodel.cpp
@@ -0,0 +1,650 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtresourcemodel_p.h"
+#include <rcc.h>
+
+#include <QtCore/QStringList>
+#include <QtCore/QMap>
+#include <QtCore/QResource>
+#include <QtCore/QFileInfo>
+#include <QtCore/QIODevice>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QBuffer>
+#include <QtCore/QFileSystemWatcher>
+
+QT_BEGIN_NAMESPACE
+
+enum { debugResourceModel = 0 };
+
+// ------------------- QtResourceSetPrivate
+class QtResourceSetPrivate
+{
+ QtResourceSet *q_ptr;
+ Q_DECLARE_PUBLIC(QtResourceSet)
+public:
+ QtResourceSetPrivate(QtResourceModel *model = 0);
+
+ QtResourceModel *m_resourceModel;
+};
+
+QtResourceSetPrivate::QtResourceSetPrivate(QtResourceModel *model) :
+ q_ptr(0),
+ m_resourceModel(model)
+{
+}
+
+// -------------------- QtResourceModelPrivate
+class QtResourceModelPrivate
+{
+ QtResourceModel *q_ptr;
+ Q_DECLARE_PUBLIC(QtResourceModel)
+ Q_DISABLE_COPY(QtResourceModelPrivate)
+public:
+ QtResourceModelPrivate();
+ void activate(QtResourceSet *resourceSet, const QStringList &newPaths, int *errorCount = 0, QString *errorMessages = 0);
+ void removeOldPaths(QtResourceSet *resourceSet, const QStringList &newPaths);
+
+ QMap<QString, bool> m_pathToModified;
+ QMap<QtResourceSet *, QStringList> m_resourceSetToPaths;
+ QMap<QtResourceSet *, bool> m_resourceSetToReload; // while path is recreated it needs to be reregistered
+ // (it is - in the new current resource set, but when the path was used in
+ // other resource set
+ // then later when that resource set is activated it needs to be reregistered)
+ QMap<QtResourceSet *, bool> m_newlyCreated; // all created but not activated yet
+ // (if was active at some point and it's not now it will not be on that map)
+ QMap<QString, QList<QtResourceSet *> > m_pathToResourceSet;
+ QtResourceSet *m_currentResourceSet;
+
+ typedef QMap<QString, const QByteArray *> PathDataMap;
+ PathDataMap m_pathToData;
+
+ QMap<QString, QStringList> m_pathToContents; // qrc path to its contents.
+ QMap<QString, QString> m_fileToQrc; // this map contains the content of active resource set only.
+ // Activating different resource set changes the contents.
+
+ QFileSystemWatcher *m_fileWatcher;
+ bool m_fileWatcherEnabled;
+ QMap<QString, bool> m_fileWatchedMap;
+private:
+ void registerResourceSet(QtResourceSet *resourceSet);
+ void unregisterResourceSet(QtResourceSet *resourceSet);
+ void setWatcherEnabled(const QString &path, bool enable);
+ void addWatcher(const QString &path);
+ void removeWatcher(const QString &path);
+
+ void slotFileChanged(const QString &);
+
+ const QByteArray *createResource(const QString &path, QStringList *contents, int *errorCount, QIODevice &errorDevice) const;
+ void deleteResource(const QByteArray *data) const;
+};
+
+QtResourceModelPrivate::QtResourceModelPrivate() :
+ q_ptr(0),
+ m_currentResourceSet(0),
+ m_fileWatcher(0),
+ m_fileWatcherEnabled(true)
+{
+}
+
+// --------------------- QtResourceSet
+QtResourceSet::QtResourceSet() :
+ d_ptr(new QtResourceSetPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+QtResourceSet::QtResourceSet(QtResourceModel *model) :
+ d_ptr(new QtResourceSetPrivate(model))
+{
+ d_ptr->q_ptr = this;
+}
+
+QtResourceSet::~QtResourceSet()
+{
+}
+
+QStringList QtResourceSet::activeQrcPaths() const
+{
+ QtResourceSet *that = const_cast<QtResourceSet *>(this);
+ return d_ptr->m_resourceModel->d_ptr->m_resourceSetToPaths.value(that);
+}
+
+void QtResourceSet::activateQrcPaths(const QStringList &paths, int *errorCount, QString *errorMessages)
+{
+ d_ptr->m_resourceModel->d_ptr->activate(this, paths, errorCount, errorMessages);
+}
+
+bool QtResourceSet::isModified(const QString &path) const
+{
+ return d_ptr->m_resourceModel->isModified(path);
+}
+
+void QtResourceSet::setModified(const QString &path)
+{
+ d_ptr->m_resourceModel->setModified(path);
+}
+
+// ------------------- QtResourceModelPrivate
+const QByteArray *QtResourceModelPrivate::createResource(const QString &path, QStringList *contents, int *errorCount, QIODevice &errorDevice) const
+{
+ typedef RCCResourceLibrary::ResourceDataFileMap ResourceDataFileMap;
+ const QByteArray *rc = 0;
+ *errorCount = -1;
+ contents->clear();
+ do {
+ // run RCC
+ RCCResourceLibrary library;
+ library.setVerbose(true);
+ library.setInputFiles(QStringList(path));
+ library.setFormat(RCCResourceLibrary::Binary);
+
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ if (!library.readFiles(/* ignore errors*/ true, errorDevice))
+ break;
+ // return code cannot be fully trusted, might still be empty
+ const ResourceDataFileMap resMap = library.resourceDataFileMap();
+ if (!library.output(buffer, errorDevice))
+ break;
+
+ *errorCount = library.failedResources().size();
+ *contents = resMap.keys();
+
+ if (resMap.empty())
+ break;
+
+ buffer.close();
+ rc = new QByteArray(buffer.data());
+ } while (false);
+
+ if (debugResourceModel)
+ qDebug() << "createResource" << path << "returns data=" << rc << " hasWarnings=" << *errorCount;
+ return rc;
+}
+
+void QtResourceModelPrivate::deleteResource(const QByteArray *data) const
+{
+ if (data) {
+ if (debugResourceModel)
+ qDebug() << "deleteResource";
+ delete data;
+ }
+}
+
+void QtResourceModelPrivate::registerResourceSet(QtResourceSet *resourceSet)
+{
+ if (!resourceSet)
+ return;
+
+ // unregister old paths (all because the order of registration is important), later it can be optimized a bit
+ QStringList toRegister = resourceSet->activeQrcPaths();
+ QStringListIterator itRegister(toRegister);
+ while (itRegister.hasNext()) {
+ const QString path = itRegister.next();
+ if (debugResourceModel)
+ qDebug() << "registerResourceSet " << path;
+ const PathDataMap::const_iterator itRcc = m_pathToData.constFind(path);
+ if (itRcc != m_pathToData.constEnd()) { // otherwise data was not created yet
+ const QByteArray *data = itRcc.value();
+ if (data) {
+ if (!QResource::registerResource(reinterpret_cast<const uchar *>(data->constData()))) {
+ qWarning() << "** WARNING: Failed to register " << path << " (QResource failure).";
+ } else {
+ QStringList contents = m_pathToContents.value(path);
+ QStringListIterator itContents(contents);
+ while (itContents.hasNext()) {
+ const QString filePath = itContents.next();
+ if (!m_fileToQrc.contains(filePath)) // the first loaded resource has higher priority in qt resource system
+ m_fileToQrc.insert(filePath, path);
+ }
+ }
+ }
+ }
+ }
+}
+
+void QtResourceModelPrivate::unregisterResourceSet(QtResourceSet *resourceSet)
+{
+ if (!resourceSet)
+ return;
+
+ // unregister old paths (all because the order of registration is importans), later it can be optimized a bit
+ QStringList toUnregister = resourceSet->activeQrcPaths();
+ QStringListIterator itUnregister(toUnregister);
+ while (itUnregister.hasNext()) {
+ const QString path = itUnregister.next();
+ if (debugResourceModel)
+ qDebug() << "unregisterResourceSet " << path;
+ const PathDataMap::const_iterator itRcc = m_pathToData.constFind(path);
+ if (itRcc != m_pathToData.constEnd()) { // otherwise data was not created yet
+ const QByteArray *data = itRcc.value();
+ if (data) {
+ if (!QResource::unregisterResource(reinterpret_cast<const uchar *>(itRcc.value()->constData())))
+ qWarning() << "** WARNING: Failed to unregister " << path << " (QResource failure).";
+ }
+ }
+ }
+ m_fileToQrc.clear();
+}
+
+void QtResourceModelPrivate::activate(QtResourceSet *resourceSet, const QStringList &newPaths, int *errorCountPtr, QString *errorMessages)
+{
+ if (debugResourceModel)
+ qDebug() << "activate " << resourceSet;
+ if (errorCountPtr)
+ *errorCountPtr = 0;
+ if (errorMessages)
+ errorMessages->clear();
+
+ QBuffer errorStream;
+ errorStream.open(QIODevice::WriteOnly);
+
+ int errorCount = 0;
+ int generatedCount = 0;
+ bool newResourceSetChanged = false;
+
+ if (resourceSet && resourceSet->activeQrcPaths() != newPaths && !m_newlyCreated.contains(resourceSet))
+ newResourceSetChanged = true;
+
+ PathDataMap newPathToData = m_pathToData;
+
+ QStringListIterator itPath(newPaths);
+ while (itPath.hasNext()) {
+ const QString path = itPath.next();
+ if (resourceSet && !m_pathToResourceSet[path].contains(resourceSet))
+ m_pathToResourceSet[path].append(resourceSet);
+ const QMap<QString, bool>::iterator itMod = m_pathToModified.find(path);
+ if (itMod == m_pathToModified.end() || itMod.value()) { // new path or path is already created, but needs to be recreated
+ QStringList contents;
+ int qrcErrorCount;
+ generatedCount++;
+ const QByteArray *data = createResource(path, &contents, &qrcErrorCount, errorStream);
+
+ newPathToData.insert(path, data);
+ if (qrcErrorCount) // Count single failed files as sort of 1/2 error
+ errorCount++;
+ addWatcher(path);
+
+ m_pathToModified.insert(path, false);
+ m_pathToContents.insert(path, contents);
+ newResourceSetChanged = true;
+ const QMap<QString, QList<QtResourceSet *> >::iterator itReload = m_pathToResourceSet.find(path);
+ if (itReload != m_pathToResourceSet.end()) {
+ QList<QtResourceSet *> resources = itReload.value();
+ QListIterator<QtResourceSet *> itRes(resources);
+ while (itRes.hasNext()) {
+ QtResourceSet *res = itRes.next();
+ if (res != resourceSet) {
+ m_resourceSetToReload[res] = true;
+ }
+ }
+ }
+ } else { // path is already created, don't need to recreate
+ }
+ }
+
+ QList<const QByteArray *> oldData = m_pathToData.values();
+ QList<const QByteArray *> newData = newPathToData.values();
+
+ QList<const QByteArray *> toDelete;
+ QListIterator<const QByteArray *> itOld(oldData);
+ if (itOld.hasNext()) {
+ const QByteArray *array = itOld.next();
+ if (array && !newData.contains(array))
+ toDelete.append(array);
+ }
+
+ // Nothing can fail below here?
+ if (generatedCount) {
+ if (errorCountPtr)
+ *errorCountPtr = errorCount;
+ errorStream.close();
+ const QString stderrOutput = QString::fromUtf8(errorStream.data());
+ if (debugResourceModel)
+ qDebug() << "Output: (" << errorCount << ")\n" << stderrOutput;
+ if (errorMessages)
+ *errorMessages = stderrOutput;
+ }
+ // register
+ const QMap<QtResourceSet *, bool>::iterator itReload = m_resourceSetToReload.find(resourceSet);
+ if (itReload != m_resourceSetToReload.end()) {
+ if (itReload.value()) {
+ newResourceSetChanged = true;
+ m_resourceSetToReload.insert(resourceSet, false);
+ }
+ }
+
+ QStringList oldActivePaths;
+ if (m_currentResourceSet)
+ oldActivePaths = m_currentResourceSet->activeQrcPaths();
+
+ const bool needReregister = (oldActivePaths != newPaths) || newResourceSetChanged;
+
+ QMap<QtResourceSet *, bool>::iterator itNew = m_newlyCreated.find(resourceSet);
+ if (itNew != m_newlyCreated.end()) {
+ m_newlyCreated.remove(resourceSet);
+ if (needReregister)
+ newResourceSetChanged = true;
+ }
+
+ if (!newResourceSetChanged && !needReregister && (m_currentResourceSet == resourceSet)) {
+ foreach (const QByteArray *data, toDelete)
+ deleteResource(data);
+
+ return; // nothing changed
+ }
+
+ if (needReregister)
+ unregisterResourceSet(m_currentResourceSet);
+
+ foreach (const QByteArray *data, toDelete)
+ deleteResource(data);
+
+ m_pathToData = newPathToData;
+ m_currentResourceSet = resourceSet;
+
+ if (resourceSet)
+ removeOldPaths(resourceSet, newPaths);
+
+ if (needReregister)
+ registerResourceSet(m_currentResourceSet);
+
+ emit q_ptr->resourceSetActivated(m_currentResourceSet, newResourceSetChanged);
+
+ // deactivates the paths from old current resource set
+ // add new paths to the new current resource set
+ // reloads all paths which are marked as modified from the current resource set;
+ // activates the paths from current resource set
+ // emits resourceSetActivated() (don't emit only in case when old resource set is the same as new one
+ // AND no path was reloaded AND the list of paths is exactly the same)
+}
+
+void QtResourceModelPrivate::removeOldPaths(QtResourceSet *resourceSet, const QStringList &newPaths)
+{
+ QStringList oldPaths = m_resourceSetToPaths.value(resourceSet);
+ if (oldPaths != newPaths) {
+ // remove old
+ QStringListIterator itOldPaths(oldPaths);
+ while (itOldPaths.hasNext()) {
+ QString oldPath = itOldPaths.next();
+ if (!newPaths.contains(oldPath)) {
+ const QMap<QString, QList<QtResourceSet *> >::iterator itRemove = m_pathToResourceSet.find(oldPath);
+ if (itRemove != m_pathToResourceSet.end()) {
+ const int idx = itRemove.value().indexOf(resourceSet);
+ if (idx >= 0)
+ itRemove.value().removeAt(idx);
+ if (itRemove.value().count() == 0) {
+ PathDataMap::iterator it = m_pathToData.find(oldPath);
+ if (it != m_pathToData.end())
+ deleteResource(it.value());
+ m_pathToResourceSet.erase(itRemove);
+ m_pathToModified.remove(oldPath);
+ m_pathToContents.remove(oldPath);
+ m_pathToData.remove(oldPath);
+ removeWatcher(oldPath);
+ }
+ }
+ }
+ }
+ m_resourceSetToPaths[resourceSet] = newPaths;
+ }
+}
+
+void QtResourceModelPrivate::setWatcherEnabled(const QString &path, bool enable)
+{
+ if (!enable) {
+ m_fileWatcher->removePath(path);
+ return;
+ }
+
+ QFileInfo fi(path);
+ if (fi.exists())
+ m_fileWatcher->addPath(path);
+}
+
+void QtResourceModelPrivate::addWatcher(const QString &path)
+{
+ QMap<QString, bool>::ConstIterator it = m_fileWatchedMap.constFind(path);
+ if (it != m_fileWatchedMap.constEnd() && it.value() == false)
+ return;
+
+ m_fileWatchedMap.insert(path, true);
+ if (!m_fileWatcherEnabled)
+ return;
+ setWatcherEnabled(path, true);
+}
+
+void QtResourceModelPrivate::removeWatcher(const QString &path)
+{
+ if (!m_fileWatchedMap.contains(path))
+ return;
+
+ m_fileWatchedMap.remove(path);
+ if (!m_fileWatcherEnabled)
+ return;
+ setWatcherEnabled(path, false);
+}
+
+void QtResourceModelPrivate::slotFileChanged(const QString &path)
+{
+ setWatcherEnabled(path, false);
+ emit q_ptr->qrcFileModifiedExternally(path);
+ setWatcherEnabled(path, true); //readd
+}
+
+// ----------------------- QtResourceModel
+QtResourceModel::QtResourceModel(QObject *parent) :
+ QObject(parent),
+ d_ptr(new QtResourceModelPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_fileWatcher = new QFileSystemWatcher(this);
+ connect(d_ptr->m_fileWatcher, SIGNAL(fileChanged(QString)),
+ this, SLOT(slotFileChanged(QString)));
+}
+
+QtResourceModel::~QtResourceModel()
+{
+ blockSignals(true);
+ QList<QtResourceSet *> resourceList = resourceSets();
+ QListIterator<QtResourceSet *> it(resourceList);
+ while (it.hasNext())
+ removeResourceSet(it.next());
+ blockSignals(false);
+}
+
+QStringList QtResourceModel::loadedQrcFiles() const
+{
+ return d_ptr->m_pathToModified.keys();
+}
+
+bool QtResourceModel::isModified(const QString &path) const
+{
+ QMap<QString, bool>::const_iterator it = d_ptr->m_pathToModified.find(path);
+ if (it != d_ptr->m_pathToModified.constEnd())
+ return it.value();
+ return true;
+}
+
+void QtResourceModel::setModified(const QString &path)
+{
+ QMap<QString, bool>::const_iterator itMod = d_ptr->m_pathToModified.find(path);
+ if (itMod == d_ptr->m_pathToModified.constEnd())
+ return;
+
+ d_ptr->m_pathToModified[path] = true;
+ QMap<QString, QList<QtResourceSet *> >::const_iterator it = d_ptr->m_pathToResourceSet.constFind(path);
+ if (it == d_ptr->m_pathToResourceSet.constEnd())
+ return;
+
+ QList<QtResourceSet *> resourceList = it.value();
+ QListIterator<QtResourceSet *> itReload(resourceList);
+ while (itReload.hasNext())
+ d_ptr->m_resourceSetToReload.insert(itReload.next(), true);
+}
+
+QList<QtResourceSet *> QtResourceModel::resourceSets() const
+{
+ return d_ptr->m_resourceSetToPaths.keys();
+}
+
+QtResourceSet *QtResourceModel::currentResourceSet() const
+{
+ return d_ptr->m_currentResourceSet;
+}
+
+void QtResourceModel::setCurrentResourceSet(QtResourceSet *resourceSet, int *errorCount, QString *errorMessages)
+{
+ d_ptr->activate(resourceSet, d_ptr->m_resourceSetToPaths.value(resourceSet), errorCount, errorMessages);
+}
+
+QtResourceSet *QtResourceModel::addResourceSet(const QStringList &paths)
+{
+ QtResourceSet *newResource = new QtResourceSet(this);
+ d_ptr->m_resourceSetToPaths.insert(newResource, paths);
+ d_ptr->m_resourceSetToReload.insert(newResource, false);
+ d_ptr->m_newlyCreated.insert(newResource, true);
+ QStringListIterator it(paths);
+ while (it.hasNext()) {
+ const QString path = it.next();
+ d_ptr->m_pathToResourceSet[path].append(newResource);
+ }
+ return newResource;
+}
+
+// TODO
+void QtResourceModel::removeResourceSet(QtResourceSet *resourceSet)
+{
+ if (!resourceSet)
+ return;
+ if (currentResourceSet() == resourceSet)
+ setCurrentResourceSet(0);
+
+ // remove rcc files for those paths which are not used in any other resource set
+ d_ptr->removeOldPaths(resourceSet, QStringList());
+
+ d_ptr->m_resourceSetToPaths.remove(resourceSet);
+ d_ptr->m_resourceSetToReload.remove(resourceSet);
+ d_ptr->m_newlyCreated.remove(resourceSet);
+ delete resourceSet;
+}
+
+void QtResourceModel::reload(const QString &path, int *errorCount, QString *errorMessages)
+{
+ setModified(path);
+
+ d_ptr->activate(d_ptr->m_currentResourceSet, d_ptr->m_resourceSetToPaths.value(d_ptr->m_currentResourceSet), errorCount, errorMessages);
+}
+
+void QtResourceModel::reload(int *errorCount, QString *errorMessages)
+{
+ QMap<QString, bool>::iterator it = d_ptr->m_pathToModified.begin();
+ QMap<QString, bool>::iterator itEnd = d_ptr->m_pathToModified.end(); // will it be valid when I iterate the map and change it???
+ while (it != itEnd) {
+ it = d_ptr->m_pathToModified.insert(it.key(), true);
+ ++it;
+ }
+
+ QMap<QtResourceSet *, bool>::iterator itReload = d_ptr->m_resourceSetToReload.begin();
+ QMap<QtResourceSet *, bool>::iterator itReloadEnd = d_ptr->m_resourceSetToReload.end();
+ while (itReload != itReloadEnd) {
+ itReload = d_ptr->m_resourceSetToReload.insert(itReload.key(), true); // empty resourceSets could be omitted here
+ ++itReload;
+ }
+
+ d_ptr->activate(d_ptr->m_currentResourceSet, d_ptr->m_resourceSetToPaths.value(d_ptr->m_currentResourceSet), errorCount, errorMessages);
+}
+
+QMap<QString, QString> QtResourceModel::contents() const
+{
+ return d_ptr->m_fileToQrc;
+}
+
+QString QtResourceModel::qrcPath(const QString &file) const
+{
+ return d_ptr->m_fileToQrc.value(file);
+}
+
+void QtResourceModel::setWatcherEnabled(bool enable)
+{
+ if (d_ptr->m_fileWatcherEnabled == enable)
+ return;
+
+ d_ptr->m_fileWatcherEnabled = enable;
+
+ QMapIterator<QString, bool> it(d_ptr->m_fileWatchedMap);
+ if (it.hasNext())
+ d_ptr->setWatcherEnabled(it.next().key(), d_ptr->m_fileWatcherEnabled);
+}
+
+bool QtResourceModel::isWatcherEnabled() const
+{
+ return d_ptr->m_fileWatcherEnabled;
+}
+
+void QtResourceModel::setWatcherEnabled(const QString &path, bool enable)
+{
+ QMap<QString, bool>::Iterator it = d_ptr->m_fileWatchedMap.find(path);
+ if (it == d_ptr->m_fileWatchedMap.end())
+ return;
+
+ if (it.value() == enable)
+ return;
+
+ it.value() = enable;
+
+ if (!d_ptr->m_fileWatcherEnabled)
+ return;
+
+ d_ptr->setWatcherEnabled(it.key(), enable);
+}
+
+bool QtResourceModel::isWatcherEnabled(const QString &path)
+{
+ return d_ptr->m_fileWatchedMap.value(path, false);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtresourcemodel_p.cpp"
diff --git a/src/designer/src/lib/shared/qtresourcemodel_p.h b/src/designer/src/lib/shared/qtresourcemodel_p.h
new file mode 100644
index 000000000..b1ddcca4a
--- /dev/null
+++ b/src/designer/src/lib/shared/qtresourcemodel_p.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QTRESOURCEMODEL_H
+#define QTRESOURCEMODEL_H
+
+#include "shared_global_p.h"
+#include <QtCore/QMap>
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QtResourceModel;
+
+class QDESIGNER_SHARED_EXPORT QtResourceSet // one instance per one form
+{
+public:
+ QStringList activeQrcPaths() const;
+
+ // activateQrcPaths(): if this QtResourceSet is active it emits resourceSetActivated();
+ // otherwise only in case if active QtResource set contains one of
+ // paths which was marked as modified by this resource set, the signal
+ // is emitted (with reload = true);
+ // If new path appears on the list it is automatically added to
+ // loaded list of QtResourceModel. In addition it is marked as modified in case
+ // QtResourceModel didn't contain the path.
+ // If some path is removed from that list (and is not used in any other
+ // resource set) it is automatically unloaded. The removed file can also be
+ // marked as modified (later when another resource set which contains
+ // removed path is activated will be reloaded)
+ void activateQrcPaths(const QStringList &paths, int *errorCount = 0, QString *errorMessages = 0);
+
+ bool isModified(const QString &path) const; // for all paths in resource model (redundant here, maybe it should be removed from here)
+ void setModified(const QString &path); // for all paths in resource model (redundant here, maybe it should be removed from here)
+private:
+ QtResourceSet();
+ QtResourceSet(QtResourceModel *model);
+ ~QtResourceSet();
+ friend class QtResourceModel;
+
+ QScopedPointer<class QtResourceSetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtResourceSet)
+ Q_DISABLE_COPY(QtResourceSet)
+};
+
+class QDESIGNER_SHARED_EXPORT QtResourceModel : public QObject // one instance per whole designer
+{
+ Q_OBJECT
+public:
+ QtResourceModel(QObject *parent = 0);
+ ~QtResourceModel();
+
+ QStringList loadedQrcFiles() const;
+ bool isModified(const QString &path) const; // only for paths which are on loadedQrcFiles() list
+ void setModified(const QString &path); // only for paths which are on loadedQrcPaths() list
+
+ QList<QtResourceSet *> resourceSets() const;
+
+ QtResourceSet *currentResourceSet() const;
+ void setCurrentResourceSet(QtResourceSet *resourceSet, int *errorCount = 0, QString *errorMessages = 0);
+
+ QtResourceSet *addResourceSet(const QStringList &paths);
+ void removeResourceSet(QtResourceSet *resourceSet);
+
+ void reload(const QString &path, int *errorCount = 0, QString *errorMessages = 0);
+ void reload(int *errorCount = 0, QString *errorMessages = 0);
+
+ // Contents of the current resource set (content file to qrc path)
+ QMap<QString, QString> contents() const;
+ // Find the qrc file belonging to the contained file (from current resource set)
+ QString qrcPath(const QString &file) const;
+
+ void setWatcherEnabled(bool enable);
+ bool isWatcherEnabled() const;
+
+ void setWatcherEnabled(const QString &path, bool enable);
+ bool isWatcherEnabled(const QString &path);
+
+signals:
+ void resourceSetActivated(QtResourceSet *resourceSet, bool resourceSetChanged); // resourceSetChanged since last time it was activated!
+ void qrcFileModifiedExternally(const QString &path);
+
+private:
+ friend class QtResourceSet;
+
+ QScopedPointer<class QtResourceModelPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtResourceModel)
+ Q_DISABLE_COPY(QtResourceModel)
+
+ Q_PRIVATE_SLOT(d_func(), void slotFileChanged(const QString &))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/shared/qtresourceview.cpp b/src/designer/src/lib/shared/qtresourceview.cpp
new file mode 100644
index 000000000..040027355
--- /dev/null
+++ b/src/designer/src/lib/shared/qtresourceview.cpp
@@ -0,0 +1,906 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractsettings_p.h"
+#include "qtresourceview_p.h"
+#include "qtresourcemodel_p.h"
+#include "qtresourceeditordialog_p.h"
+#include "iconloader_p.h"
+#include "filterwidget_p.h" // For FilterWidget
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtGui/QToolBar>
+#include <QtGui/QAction>
+#include <QtGui/QSplitter>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QListWidget>
+#include <QtGui/QHeaderView>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QPainter>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QQueue>
+#include <QtGui/QPainter>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QMessageBox>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
+#include <QtGui/QMenu>
+#include <QtGui/QDrag>
+#include <QtCore/QMimeData>
+#include <QtXml/QDomDocument>
+
+QT_BEGIN_NAMESPACE
+
+static const char *elementResourceData = "resource";
+static const char *typeAttribute = "type";
+static const char *typeImage = "image";
+static const char *typeStyleSheet = "stylesheet";
+static const char *typeOther = "other";
+static const char *fileAttribute = "file";
+static const char *SplitterPosition = "SplitterPosition";
+static const char *Geometry = "Geometry";
+static const char *ResourceViewDialogC = "ResourceDialog";
+
+// ---------------- ResourceListWidget: A list widget that has drag enabled
+class ResourceListWidget : public QListWidget {
+public:
+ ResourceListWidget(QWidget *parent = 0);
+
+protected:
+ virtual void startDrag(Qt::DropActions supportedActions);
+};
+
+ResourceListWidget::ResourceListWidget(QWidget *parent) :
+ QListWidget(parent)
+{
+ setDragEnabled(true);
+}
+
+void ResourceListWidget::startDrag(Qt::DropActions supportedActions)
+{
+ if (supportedActions == Qt::MoveAction)
+ return;
+
+ QListWidgetItem *item = currentItem();
+ if (!item)
+ return;
+
+ const QString filePath = item->data(Qt::UserRole).toString();
+ const QIcon icon = item->icon();
+
+ QMimeData *mimeData = new QMimeData;
+ const QtResourceView::ResourceType type = icon.isNull() ? QtResourceView::ResourceOther : QtResourceView::ResourceImage;
+ mimeData->setText(QtResourceView::encodeMimeData(type , filePath));
+
+ QDrag *drag = new QDrag(this);
+ if (!icon.isNull()) {
+ const QSize size = icon.actualSize(iconSize());
+ drag->setPixmap(icon.pixmap(size));
+ drag->setHotSpot(QPoint(size.width() / 2, size.height() / 2));
+ }
+
+ drag->setMimeData(mimeData);
+ drag->exec(Qt::CopyAction);
+}
+
+/* TODO
+
+ 1) load the icons in separate thread...Hmm..if Qt is configured with threads....
+*/
+
+// ---------------------------- QtResourceViewPrivate
+class QtResourceViewPrivate
+{
+ QtResourceView *q_ptr;
+ Q_DECLARE_PUBLIC(QtResourceView)
+public:
+ QtResourceViewPrivate(QDesignerFormEditorInterface *core);
+
+ void slotResourceSetActivated(QtResourceSet *resourceSet);
+ void slotCurrentPathChanged(QTreeWidgetItem *);
+ void slotCurrentResourceChanged(QListWidgetItem *);
+ void slotResourceActivated(QListWidgetItem *);
+ void slotEditResources();
+ void slotReloadResources();
+ void slotCopyResourcePath();
+ void slotListWidgetContextMenuRequested(const QPoint &pos);
+ void slotFilterChanged(const QString &pattern);
+ void createPaths();
+ QTreeWidgetItem *createPath(const QString &path, QTreeWidgetItem *parent);
+ void createResources(const QString &path);
+ void storeExpansionState();
+ void applyExpansionState();
+ void restoreSettings();
+ void saveSettings();
+ void updateActions();
+ void filterOutResources();
+
+ QPixmap makeThumbnail(const QPixmap &pix) const;
+
+ QDesignerFormEditorInterface *m_core;
+ QtResourceModel *m_resourceModel;
+ QToolBar *m_toolBar;
+ qdesigner_internal::FilterWidget *m_filterWidget;
+ QTreeWidget *m_treeWidget;
+ QListWidget *m_listWidget;
+ QSplitter *m_splitter;
+ QMap<QString, QStringList> m_pathToContents; // full path to contents file names (full path to its resource filenames)
+ QMap<QString, QString> m_pathToParentPath; // full path to full parent path
+ QMap<QString, QStringList> m_pathToSubPaths; // full path to full sub paths
+ QMap<QString, QTreeWidgetItem *> m_pathToItem;
+ QMap<QTreeWidgetItem *, QString> m_itemToPath;
+ QMap<QString, QListWidgetItem *> m_resourceToItem;
+ QMap<QListWidgetItem *, QString> m_itemToResource;
+ QAction *m_editResourcesAction;
+ QAction *m_reloadResourcesAction;
+ QAction *m_copyResourcePathAction;
+
+ QMap<QString, bool> m_expansionState;
+
+ bool m_ignoreGuiSignals;
+ QString m_settingsKey;
+ bool m_resourceEditingEnabled;
+ QString m_filterPattern;
+};
+
+QtResourceViewPrivate::QtResourceViewPrivate(QDesignerFormEditorInterface *core) :
+ q_ptr(0),
+ m_core(core),
+ m_resourceModel(0),
+ m_toolBar(new QToolBar),
+ m_treeWidget(new QTreeWidget),
+ m_listWidget(new ResourceListWidget),
+ m_splitter(0),
+ m_editResourcesAction(0),
+ m_reloadResourcesAction(0),
+ m_copyResourcePathAction(0),
+ m_ignoreGuiSignals(false),
+ m_resourceEditingEnabled(true)
+{
+}
+
+void QtResourceViewPrivate::restoreSettings()
+{
+ if (m_settingsKey.isEmpty())
+ return;
+
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->beginGroup(m_settingsKey);
+
+ m_splitter->restoreState(settings->value(QLatin1String(SplitterPosition)).toByteArray());
+ settings->endGroup();
+}
+
+void QtResourceViewPrivate::saveSettings()
+{
+ if (m_settingsKey.isEmpty())
+ return;
+
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->beginGroup(m_settingsKey);
+
+ settings->setValue(QLatin1String(SplitterPosition), m_splitter->saveState());
+ settings->endGroup();
+}
+
+void QtResourceViewPrivate::slotEditResources()
+{
+ const QString selectedResource
+ = QtResourceEditorDialog::editResources(m_core, m_resourceModel,
+ m_core->dialogGui(), q_ptr);
+ if (!selectedResource.isEmpty())
+ q_ptr->selectResource(selectedResource);
+}
+
+void QtResourceViewPrivate::slotReloadResources()
+{
+ if (m_resourceModel) {
+ int errorCount;
+ QString errorMessages;
+ m_resourceModel->reload(&errorCount, &errorMessages);
+ if (errorCount)
+ QtResourceEditorDialog::displayResourceFailures(errorMessages, m_core->dialogGui(), q_ptr);
+ }
+}
+
+void QtResourceViewPrivate::slotCopyResourcePath()
+{
+ const QString path = q_ptr->selectedResource();
+ QClipboard *clipboard = QApplication::clipboard();
+ clipboard->setText(path);
+}
+
+void QtResourceViewPrivate::slotListWidgetContextMenuRequested(const QPoint &pos)
+{
+ QMenu menu(q_ptr);
+ menu.addAction(m_copyResourcePathAction);
+ menu.exec(m_listWidget->mapToGlobal(pos));
+}
+
+void QtResourceViewPrivate::slotFilterChanged(const QString &pattern)
+{
+ m_filterPattern = pattern;
+ filterOutResources();
+}
+
+void QtResourceViewPrivate::storeExpansionState()
+{
+ QMapIterator<QString, QTreeWidgetItem *> it(m_pathToItem);
+ while (it.hasNext()) {
+ it.next();
+ m_expansionState[it.key()] = it.value()->isExpanded();
+ }
+}
+
+void QtResourceViewPrivate::applyExpansionState()
+{
+ QMapIterator<QString, QTreeWidgetItem *> it(m_pathToItem);
+ while (it.hasNext()) {
+ it.next();
+ it.value()->setExpanded(m_expansionState.value(it.key(), true));
+ }
+}
+
+QPixmap QtResourceViewPrivate::makeThumbnail(const QPixmap &pix) const
+{
+ int w = qMax(48, pix.width());
+ int h = qMax(48, pix.height());
+ QRect imgRect(0, 0, w, h);
+ QImage img(w, h, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+ if (!pix.isNull()) {
+ QRect r(0, 0, pix.width(), pix.height());
+ r.moveCenter(imgRect.center());
+ QPainter p(&img);
+ p.drawPixmap(r.topLeft(), pix);
+ }
+ return QPixmap::fromImage(img);
+}
+
+void QtResourceViewPrivate::updateActions()
+{
+ bool resourceActive = false;
+ if (m_resourceModel)
+ resourceActive = m_resourceModel->currentResourceSet();
+
+ m_editResourcesAction->setVisible(m_resourceEditingEnabled);
+ m_editResourcesAction->setEnabled(resourceActive);
+ m_reloadResourcesAction->setEnabled(resourceActive);
+ m_filterWidget->setEnabled(resourceActive);
+}
+
+void QtResourceViewPrivate::slotResourceSetActivated(QtResourceSet *resourceSet)
+{
+ Q_UNUSED(resourceSet)
+
+ updateActions();
+
+ storeExpansionState();
+ const QString currentPath = m_itemToPath.value(m_treeWidget->currentItem());
+ const QString currentResource = m_itemToResource.value(m_listWidget->currentItem());
+ m_treeWidget->clear();
+ m_pathToContents.clear();
+ m_pathToParentPath.clear();
+ m_pathToSubPaths.clear();
+ m_pathToItem.clear();
+ m_itemToPath.clear();
+ m_listWidget->clear();
+ m_resourceToItem.clear();
+ m_itemToResource.clear();
+
+ createPaths();
+ applyExpansionState();
+
+ if (!currentResource.isEmpty())
+ q_ptr->selectResource(currentResource);
+ else if (!currentPath.isEmpty())
+ q_ptr->selectResource(currentPath);
+ filterOutResources();
+}
+
+void QtResourceViewPrivate::slotCurrentPathChanged(QTreeWidgetItem *item)
+{
+ if (m_ignoreGuiSignals)
+ return;
+
+ m_listWidget->clear();
+ m_resourceToItem.clear();
+ m_itemToResource.clear();
+
+ if (!item)
+ return;
+
+ const QString currentPath = m_itemToPath.value(item);
+ createResources(currentPath);
+}
+
+void QtResourceViewPrivate::slotCurrentResourceChanged(QListWidgetItem *item)
+{
+ m_copyResourcePathAction->setEnabled(item);
+ if (m_ignoreGuiSignals)
+ return;
+
+ emit q_ptr->resourceSelected(m_itemToResource.value(item));
+}
+
+void QtResourceViewPrivate::slotResourceActivated(QListWidgetItem *item)
+{
+ if (m_ignoreGuiSignals)
+ return;
+
+ emit q_ptr->resourceActivated(m_itemToResource.value(item));
+}
+
+void QtResourceViewPrivate::createPaths()
+{
+ if (!m_resourceModel)
+ return;
+
+ // Resource root up until 4.6 was ':', changed to ":/" as of 4.7
+ const QString root(QLatin1String(":/"));
+
+ QMap<QString, QString> contents = m_resourceModel->contents();
+ QMapIterator<QString, QString> itContents(contents);
+ while (itContents.hasNext()) {
+ const QString filePath = itContents.next().key();
+ const QFileInfo fi(filePath);
+ QString dirPath = fi.absolutePath();
+ m_pathToContents[dirPath].append(fi.fileName());
+ while (!m_pathToParentPath.contains(dirPath) && dirPath != root) { // create all parent paths
+ const QFileInfo fd(dirPath);
+ const QString parentDirPath = fd.absolutePath();
+ m_pathToParentPath[dirPath] = parentDirPath;
+ m_pathToSubPaths[parentDirPath].append(dirPath);
+ dirPath = parentDirPath;
+ }
+ }
+
+ QQueue<QPair<QString, QTreeWidgetItem *> > pathToParentItemQueue;
+ pathToParentItemQueue.enqueue(qMakePair(root, static_cast<QTreeWidgetItem *>(0)));
+ while (!pathToParentItemQueue.isEmpty()) {
+ QPair<QString, QTreeWidgetItem *> pathToParentItem = pathToParentItemQueue.dequeue();
+ const QString path = pathToParentItem.first;
+ QTreeWidgetItem *item = createPath(path, pathToParentItem.second);
+ QStringList subPaths = m_pathToSubPaths.value(path);
+ QStringListIterator itSubPaths(subPaths);
+ while (itSubPaths.hasNext())
+ pathToParentItemQueue.enqueue(qMakePair(itSubPaths.next(), item));
+ }
+}
+
+void QtResourceViewPrivate::filterOutResources()
+{
+ QMap<QString, bool> pathToMatchingContents; // true means the path has any matching contents
+ QMap<QString, bool> pathToVisible; // true means the path has to be shown
+
+ // 1) we go from root path recursively.
+ // 2) we check every path if it contains at least one matching resource - if empty we add it
+ // to pathToMatchingContents and pathToVisible with false, if non empty
+ // we add it with true and change every parent path in pathToVisible to true.
+ // 3) we hide these items which has pathToVisible value false.
+
+ const bool matchAll = m_filterPattern.isEmpty();
+ const QString root(QLatin1String(":/"));
+
+ QQueue<QString> pathQueue;
+ pathQueue.enqueue(root);
+ while (!pathQueue.isEmpty()) {
+ const QString path = pathQueue.dequeue();
+
+ QStringList fileNames = m_pathToContents.value(path);
+ QStringListIterator it(fileNames);
+ bool hasContents = matchAll;
+ if (!matchAll) { // the case filter is not empty - we check if the path contains anything
+ while (it.hasNext()) {
+ QString fileName = it.next();
+ hasContents = fileName.contains(m_filterPattern, Qt::CaseInsensitive);
+ if (hasContents) // the path contains at least one resource which matches the filter
+ break;
+ }
+ }
+
+ pathToMatchingContents[path] = hasContents;
+ pathToVisible[path] = hasContents;
+
+ if (hasContents) { // if the path is going to be shown we need to show all its parent paths
+ QString parentPath = m_pathToParentPath.value(path);
+ while (!parentPath.isEmpty()) {
+ QString p = parentPath;
+ if (pathToVisible.value(p)) // parent path is already shown, we break the loop
+ break;
+ pathToVisible[p] = true;
+ parentPath = m_pathToParentPath.value(p);
+ }
+ }
+
+ QStringList subPaths = m_pathToSubPaths.value(path); // we do the same for children paths
+ QStringListIterator itSubPaths(subPaths);
+ while (itSubPaths.hasNext())
+ pathQueue.enqueue(itSubPaths.next());
+ }
+
+ // we setup here new path and resource to be activated
+ const QString currentPath = m_itemToPath.value(m_treeWidget->currentItem());
+ QString newCurrentPath = currentPath;
+ QString currentResource = m_itemToResource.value(m_listWidget->currentItem());
+ if (!matchAll) {
+ bool searchForNewPathWithContents = true;
+
+ if (!currentPath.isEmpty()) { // if the currentPath is empty we will search for a new path too
+ QMap<QString, bool>::ConstIterator it = pathToMatchingContents.constFind(currentPath);
+ if (it != pathToMatchingContents.constEnd() && it.value()) // the current item has contents, we don't need to search for another path
+ searchForNewPathWithContents = false;
+ }
+
+ if (searchForNewPathWithContents) {
+ // we find the first path with the matching contents
+ QMap<QString, bool>::ConstIterator itContents = pathToMatchingContents.constBegin();
+ while (itContents != pathToMatchingContents.constEnd()) {
+ if (itContents.value()) {
+ newCurrentPath = itContents.key(); // the new path will be activated
+ break;
+ }
+
+ itContents++;
+ }
+ }
+
+ QFileInfo fi(currentResource);
+ if (!fi.fileName().contains(m_filterPattern, Qt::CaseInsensitive)) { // the case when the current resource is filtered out
+ const QStringList fileNames = m_pathToContents.value(newCurrentPath);
+ QStringListIterator it(fileNames);
+ while (it.hasNext()) { // we try to select the first matching resource from the newCurrentPath
+ QString fileName = it.next();
+ if (fileName.contains(m_filterPattern, Qt::CaseInsensitive)) {
+ QDir dirPath(newCurrentPath);
+ currentResource = dirPath.absoluteFilePath(fileName); // the new resource inside newCurrentPath will be activated
+ break;
+ }
+ }
+ }
+ }
+
+ QTreeWidgetItem *newCurrentItem = m_pathToItem.value(newCurrentPath);
+ if (currentPath != newCurrentPath)
+ m_treeWidget->setCurrentItem(newCurrentItem);
+ else
+ slotCurrentPathChanged(newCurrentItem); // trigger filtering on the current path
+
+ QListWidgetItem *currentResourceItem = m_resourceToItem.value(currentResource);
+ if (currentResourceItem) {
+ m_listWidget->setCurrentItem(currentResourceItem);
+ m_listWidget->scrollToItem(currentResourceItem);
+ }
+
+ QMapIterator<QString, bool> it(pathToVisible); // hide all paths filtered out
+ while (it.hasNext()) {
+ const QString path = it.next().key();
+ QTreeWidgetItem *item = m_pathToItem.value(path);
+ if (item)
+ item->setHidden(!it.value());
+ }
+}
+
+QTreeWidgetItem *QtResourceViewPrivate::createPath(const QString &path, QTreeWidgetItem *parent)
+{
+ QTreeWidgetItem *item = 0;
+ if (parent)
+ item = new QTreeWidgetItem(parent);
+ else
+ item = new QTreeWidgetItem(m_treeWidget);
+ m_pathToItem[path] = item;
+ m_itemToPath[item] = path;
+ QString substPath;
+ if (parent) {
+ QFileInfo di(path);
+ substPath = di.fileName();
+ } else {
+ substPath = QLatin1String("<resource root>");
+ }
+ item->setText(0, substPath);
+ item->setToolTip(0, path);
+ return item;
+}
+
+void QtResourceViewPrivate::createResources(const QString &path)
+{
+ const bool matchAll = m_filterPattern.isEmpty();
+
+ QDir dir(path);
+ QStringList fileNames = m_pathToContents.value(path);
+ QStringListIterator it(fileNames);
+ while (it.hasNext()) {
+ QString fileName = it.next();
+ const bool showProperty = matchAll || fileName.contains(m_filterPattern, Qt::CaseInsensitive);
+ if (showProperty) {
+ QString filePath = dir.absoluteFilePath(fileName);
+ QFileInfo fi(filePath);
+ if (fi.isFile()) {
+ QListWidgetItem *item = new QListWidgetItem(fi.fileName(), m_listWidget);
+ const QPixmap pix = QPixmap(filePath);
+ if (pix.isNull()) {
+ item->setToolTip(filePath);
+ } else {
+ item->setIcon(QIcon(makeThumbnail(pix)));
+ const QSize size = pix.size();
+ item->setToolTip(QtResourceView::tr("Size: %1 x %2\n%3").arg(size.width()).arg(size.height()).arg(filePath));
+ }
+ item->setFlags(item->flags() | Qt::ItemIsDragEnabled);
+ item->setData(Qt::UserRole, filePath);
+ m_itemToResource[item] = filePath;
+ m_resourceToItem[filePath] = item;
+ }
+ }
+ }
+}
+
+// -------------- QtResourceView
+
+QtResourceView::QtResourceView(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QWidget(parent),
+ d_ptr(new QtResourceViewPrivate(core))
+{
+ d_ptr->q_ptr = this;
+
+ QIcon editIcon = QIcon::fromTheme("document-properties", qdesigner_internal::createIconSet(QLatin1String("edit.png")));
+ d_ptr->m_editResourcesAction = new QAction(editIcon, tr("Edit Resources..."), this);
+ d_ptr->m_toolBar->addAction(d_ptr->m_editResourcesAction);
+ connect(d_ptr->m_editResourcesAction, SIGNAL(triggered()), this, SLOT(slotEditResources()));
+ d_ptr->m_editResourcesAction->setEnabled(false);
+
+ QIcon refreshIcon = QIcon::fromTheme("view-refresh", qdesigner_internal::createIconSet(QLatin1String("reload.png")));
+ d_ptr->m_reloadResourcesAction = new QAction(refreshIcon, tr("Reload"), this);
+
+ d_ptr->m_toolBar->addAction(d_ptr->m_reloadResourcesAction);
+ connect(d_ptr->m_reloadResourcesAction, SIGNAL(triggered()), this, SLOT(slotReloadResources()));
+ d_ptr->m_reloadResourcesAction->setEnabled(false);
+
+ QIcon copyIcon = QIcon::fromTheme("edit-copy", qdesigner_internal::createIconSet(QLatin1String("editcopy.png")));
+ d_ptr->m_copyResourcePathAction = new QAction(copyIcon, tr("Copy Path"), this);
+ connect(d_ptr->m_copyResourcePathAction, SIGNAL(triggered()), this, SLOT(slotCopyResourcePath()));
+ d_ptr->m_copyResourcePathAction->setEnabled(false);
+
+ //d_ptr->m_filterWidget = new qdesigner_internal::FilterWidget(0, qdesigner_internal::FilterWidget::LayoutAlignNone);
+ d_ptr->m_filterWidget = new qdesigner_internal::FilterWidget(d_ptr->m_toolBar);
+ d_ptr->m_toolBar->addWidget(d_ptr->m_filterWidget);
+ connect(d_ptr->m_filterWidget, SIGNAL(filterChanged(QString)), this, SLOT(slotFilterChanged(QString)));
+
+ d_ptr->m_splitter = new QSplitter;
+ d_ptr->m_splitter->setChildrenCollapsible(false);
+ d_ptr->m_splitter->addWidget(d_ptr->m_treeWidget);
+ d_ptr->m_splitter->addWidget(d_ptr->m_listWidget);
+
+ QLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(0);
+ layout->setSpacing(0);
+ layout->addWidget(d_ptr->m_toolBar);
+ layout->addWidget(d_ptr->m_splitter);
+
+ d_ptr->m_treeWidget->setColumnCount(1);
+ d_ptr->m_treeWidget->header()->hide();
+ d_ptr->m_treeWidget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
+
+ d_ptr->m_listWidget->setViewMode(QListView::IconMode);
+ d_ptr->m_listWidget->setResizeMode(QListView::Adjust);
+ d_ptr->m_listWidget->setIconSize(QSize(48, 48));
+ d_ptr->m_listWidget->setGridSize(QSize(64, 64));
+
+ connect(d_ptr->m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ this, SLOT(slotCurrentPathChanged(QTreeWidgetItem*)));
+ connect(d_ptr->m_listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ this, SLOT(slotCurrentResourceChanged(QListWidgetItem*)));
+ connect(d_ptr->m_listWidget, SIGNAL(itemActivated(QListWidgetItem*)),
+ this, SLOT(slotResourceActivated(QListWidgetItem*)));
+ d_ptr->m_listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(d_ptr->m_listWidget, SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(slotListWidgetContextMenuRequested(QPoint)));
+}
+
+QtResourceView::~QtResourceView()
+{
+ if (!d_ptr->m_settingsKey.isEmpty())
+ d_ptr->saveSettings();
+}
+
+bool QtResourceView::event(QEvent *event)
+{
+ if (event->type() == QEvent::Show) {
+ d_ptr->m_listWidget->scrollToItem(d_ptr->m_listWidget->currentItem());
+ d_ptr->m_treeWidget->scrollToItem(d_ptr->m_treeWidget->currentItem());
+ }
+ return QWidget::event(event);
+}
+
+QtResourceModel *QtResourceView::model() const
+{
+ return d_ptr->m_resourceModel;
+}
+
+QString QtResourceView::selectedResource() const
+{
+ QListWidgetItem *item = d_ptr->m_listWidget->currentItem();
+ return d_ptr->m_itemToResource.value(item);
+}
+
+void QtResourceView::selectResource(const QString &resource)
+{
+ if (resource.isEmpty())
+ return;
+ QFileInfo fi(resource);
+ QDir dir = fi.absoluteDir();
+ if (fi.isDir())
+ dir = QDir(resource);
+ QString dirPath = dir.absolutePath();
+ QMap<QString, QTreeWidgetItem *>::const_iterator it;
+ while ((it = d_ptr->m_pathToItem.find(dirPath)) == d_ptr->m_pathToItem.constEnd()) {
+ if (!dir.cdUp())
+ break;
+ dirPath = dir.absolutePath();
+ }
+ if (it != d_ptr->m_pathToItem.constEnd()) {
+ QTreeWidgetItem *treeItem = it.value();
+ d_ptr->m_treeWidget->setCurrentItem(treeItem);
+ d_ptr->m_treeWidget->scrollToItem(treeItem);
+ // expand all up to current one is done by qt
+ // list widget is already propagated (currrent changed was sent by qt)
+ QListWidgetItem *item = d_ptr->m_resourceToItem.value(resource);
+ if (item) {
+ d_ptr->m_listWidget->setCurrentItem(item);
+ d_ptr->m_listWidget->scrollToItem(item);
+ }
+ }
+}
+
+QString QtResourceView::settingsKey() const
+{
+ return d_ptr->m_settingsKey;
+}
+
+void QtResourceView::setSettingsKey(const QString &key)
+{
+ if (d_ptr->m_settingsKey == key)
+ return;
+
+ d_ptr->m_settingsKey = key;
+
+ if (key.isEmpty())
+ return;
+
+ d_ptr->restoreSettings();
+}
+
+void QtResourceView::setResourceModel(QtResourceModel *model)
+{
+ if (d_ptr->m_resourceModel) {
+ disconnect(d_ptr->m_resourceModel, SIGNAL(resourceSetActivated(QtResourceSet*,bool)),
+ this, SLOT(slotResourceSetActivated(QtResourceSet*)));
+ }
+
+ // clear here
+ d_ptr->m_treeWidget->clear();
+ d_ptr->m_listWidget->clear();
+
+ d_ptr->m_resourceModel = model;
+
+ if (!d_ptr->m_resourceModel)
+ return;
+
+ connect(d_ptr->m_resourceModel, SIGNAL(resourceSetActivated(QtResourceSet*,bool)),
+ this, SLOT(slotResourceSetActivated(QtResourceSet*)));
+
+ // fill new here
+ d_ptr->slotResourceSetActivated(d_ptr->m_resourceModel->currentResourceSet());
+}
+
+bool QtResourceView::isResourceEditingEnabled() const
+{
+ return d_ptr->m_resourceEditingEnabled;
+}
+
+void QtResourceView::setResourceEditingEnabled(bool enable)
+{
+ d_ptr->m_resourceEditingEnabled = enable;
+ d_ptr->updateActions();
+}
+
+void QtResourceView::setDragEnabled(bool dragEnabled)
+{
+ d_ptr->m_listWidget->setDragEnabled(dragEnabled);
+}
+
+bool QtResourceView::dragEnabled() const
+{
+ return d_ptr->m_listWidget->dragEnabled();
+}
+
+QString QtResourceView::encodeMimeData(ResourceType resourceType, const QString &path)
+{
+ QDomDocument doc;
+ QDomElement elem = doc.createElement(QLatin1String(elementResourceData));
+ switch (resourceType) {
+ case ResourceImage:
+ elem.setAttribute(QLatin1String(typeAttribute), QLatin1String(typeImage));
+ break;
+ case ResourceStyleSheet:
+ elem.setAttribute(QLatin1String(typeAttribute), QLatin1String(typeStyleSheet));
+ break;
+ case ResourceOther:
+ elem.setAttribute(QLatin1String(typeAttribute), QLatin1String(typeOther));
+ break;
+ }
+ elem.setAttribute(QLatin1String(fileAttribute), path);
+ doc.appendChild(elem);
+ return doc.toString();
+}
+
+bool QtResourceView::decodeMimeData(const QMimeData *md, ResourceType *t, QString *file)
+{
+ return md->hasText() ? decodeMimeData(md->text(), t, file) : false;
+}
+
+bool QtResourceView::decodeMimeData(const QString &text, ResourceType *t, QString *file)
+{
+
+ const QString docElementName = QLatin1String(elementResourceData);
+ static const QString docElementString = QLatin1Char('<') + docElementName;
+
+ if (text.isEmpty() || text.indexOf(docElementString) == -1)
+ return false;
+
+ QDomDocument doc;
+ if (!doc.setContent(text))
+ return false;
+
+ const QDomElement domElement = doc.documentElement();
+ if (domElement.tagName() != docElementName)
+ return false;
+
+ if (t) {
+ const QString typeAttr = QLatin1String(typeAttribute);
+ if (domElement.hasAttribute (typeAttr)) {
+ const QString typeValue = domElement.attribute(typeAttr, QLatin1String(typeOther));
+ if (typeValue == QLatin1String(typeImage)) {
+ *t = ResourceImage;
+ } else {
+ *t = typeValue == QLatin1String(typeStyleSheet) ? ResourceStyleSheet : ResourceOther;
+ }
+ }
+ }
+ if (file) {
+ const QString fileAttr = QLatin1String(fileAttribute);
+ if (domElement.hasAttribute(fileAttr)) {
+ *file = domElement.attribute(fileAttr, QString());
+ } else {
+ file->clear();
+ }
+ }
+ return true;
+}
+
+// ---------------------------- QtResourceViewDialogPrivate
+
+class QtResourceViewDialogPrivate
+{
+ QtResourceViewDialog *q_ptr;
+ Q_DECLARE_PUBLIC(QtResourceViewDialog)
+public:
+ QtResourceViewDialogPrivate(QDesignerFormEditorInterface *core);
+
+ void slotResourceSelected(const QString &resource) { setOkButtonEnabled(!resource.isEmpty()); }
+ void setOkButtonEnabled(bool v) { m_box->button(QDialogButtonBox::Ok)->setEnabled(v); }
+
+ QDesignerFormEditorInterface *m_core;
+ QtResourceView *m_view;
+ QDialogButtonBox *m_box;
+};
+
+QtResourceViewDialogPrivate::QtResourceViewDialogPrivate(QDesignerFormEditorInterface *core) :
+ q_ptr(0),
+ m_core(core),
+ m_view(new QtResourceView(core)),
+ m_box(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel))
+{
+ m_view->setSettingsKey(QLatin1String(ResourceViewDialogC));
+}
+
+// ------------ QtResourceViewDialog
+QtResourceViewDialog::QtResourceViewDialog(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QDialog(parent),
+ d_ptr(new QtResourceViewDialogPrivate(core))
+{
+ setWindowTitle(tr("Select Resource"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ d_ptr->q_ptr = this;
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addWidget(d_ptr->m_view);
+ layout->addWidget(d_ptr->m_box);
+ connect(d_ptr->m_box, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(d_ptr->m_box, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(d_ptr->m_view, SIGNAL(resourceActivated(QString)), this, SLOT(accept()));
+ connect(d_ptr->m_view, SIGNAL(resourceSelected(QString)), this, SLOT(slotResourceSelected(QString)));
+ d_ptr->setOkButtonEnabled(false);
+ d_ptr->m_view->setResourceModel(core->resourceModel());
+
+ QDesignerSettingsInterface *settings = core->settingsManager();
+ settings->beginGroup(QLatin1String(ResourceViewDialogC));
+
+ if (settings->contains(QLatin1String(Geometry)))
+ setGeometry(settings->value(QLatin1String(Geometry)).toRect());
+
+ settings->endGroup();
+}
+
+QtResourceViewDialog::~QtResourceViewDialog()
+{
+ QDesignerSettingsInterface *settings = d_ptr->m_core->settingsManager();
+ settings->beginGroup(QLatin1String(ResourceViewDialogC));
+
+ settings->setValue(QLatin1String(Geometry), geometry());
+
+ settings->endGroup();
+}
+
+QString QtResourceViewDialog::selectedResource() const
+{
+ return d_ptr->m_view->selectedResource();
+}
+
+void QtResourceViewDialog::selectResource(const QString &path)
+{
+ d_ptr->m_view->selectResource(path);
+}
+
+bool QtResourceViewDialog::isResourceEditingEnabled() const
+{
+ return d_ptr->m_view->isResourceEditingEnabled();
+}
+
+void QtResourceViewDialog::setResourceEditingEnabled(bool enable)
+{
+ d_ptr->m_view->setResourceEditingEnabled(enable);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtresourceview_p.cpp"
diff --git a/src/designer/src/lib/shared/qtresourceview_p.h b/src/designer/src/lib/shared/qtresourceview_p.h
new file mode 100644
index 000000000..947df64e4
--- /dev/null
+++ b/src/designer/src/lib/shared/qtresourceview_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QTRESOURCEVIEW_H
+#define QTRESOURCEVIEW_H
+
+#include "shared_global_p.h"
+#include <QtGui/QWidget>
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QtResourceModel;
+class QtResourceSet;
+class QDesignerFormEditorInterface;
+class QMimeData;
+
+class QDESIGNER_SHARED_EXPORT QtResourceView : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QtResourceView(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ ~QtResourceView();
+
+ void setDragEnabled(bool dragEnabled);
+ bool dragEnabled() const;
+
+ QtResourceModel *model() const;
+ void setResourceModel(QtResourceModel *model);
+
+ QString selectedResource() const;
+ void selectResource(const QString &resource);
+
+ QString settingsKey() const;
+ void setSettingsKey(const QString &key);
+
+ bool isResourceEditingEnabled() const;
+ void setResourceEditingEnabled(bool enable);
+
+ // Helpers for handling the drag originating in QtResourceView (Xml/text)
+ enum ResourceType { ResourceImage, ResourceStyleSheet, ResourceOther };
+ static QString encodeMimeData(ResourceType resourceType, const QString &path);
+
+ static bool decodeMimeData(const QMimeData *md, ResourceType *t = 0, QString *file = 0);
+ static bool decodeMimeData(const QString &text, ResourceType *t = 0, QString *file = 0);
+
+signals:
+ void resourceSelected(const QString &resource);
+ void resourceActivated(const QString &resource);
+
+protected:
+ bool event(QEvent *event);
+
+private:
+
+ QScopedPointer<class QtResourceViewPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtResourceView)
+ Q_DISABLE_COPY(QtResourceView)
+ Q_PRIVATE_SLOT(d_func(), void slotResourceSetActivated(QtResourceSet *))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentPathChanged(QTreeWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentResourceChanged(QListWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void slotResourceActivated(QListWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void slotEditResources())
+ Q_PRIVATE_SLOT(d_func(), void slotReloadResources())
+ Q_PRIVATE_SLOT(d_func(), void slotCopyResourcePath())
+ Q_PRIVATE_SLOT(d_func(), void slotListWidgetContextMenuRequested(const QPoint &pos))
+ Q_PRIVATE_SLOT(d_func(), void slotFilterChanged(const QString &pattern))
+};
+
+class QDESIGNER_SHARED_EXPORT QtResourceViewDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit QtResourceViewDialog(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ virtual ~QtResourceViewDialog();
+
+ QString selectedResource() const;
+ void selectResource(const QString &path);
+
+ bool isResourceEditingEnabled() const;
+ void setResourceEditingEnabled(bool enable);
+
+private:
+ QScopedPointer<class QtResourceViewDialogPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtResourceViewDialog)
+ Q_DISABLE_COPY(QtResourceViewDialog)
+ Q_PRIVATE_SLOT(d_func(), void slotResourceSelected(const QString &))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/shared/richtexteditor.cpp b/src/designer/src/lib/shared/richtexteditor.cpp
new file mode 100644
index 000000000..c2cdb2098
--- /dev/null
+++ b/src/designer/src/lib/shared/richtexteditor.cpp
@@ -0,0 +1,906 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "richtexteditor_p.h"
+#include "htmlhighlighter_p.h"
+#include "iconselector_p.h"
+#include "ui_addlinkdialog.h"
+#include "abstractsettings_p.h"
+
+#include "iconloader_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QPointer>
+#include <QtCore/QXmlStreamReader>
+#include <QtCore/QXmlStreamWriter>
+#include <QtCore/QXmlStreamAttributes>
+
+#include <QtGui/QAction>
+#include <QtGui/QColorDialog>
+#include <QtGui/QComboBox>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QTextCursor>
+#include <QtGui/QPainter>
+#include <QtGui/QIcon>
+#include <QtGui/QMenu>
+#include <QtGui/QMoveEvent>
+#include <QtGui/QTabWidget>
+#include <QtGui/QTextDocument>
+#include <QtGui/QTextBlock>
+#include <QtGui/QToolBar>
+#include <QtGui/QToolButton>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QDialogButtonBox>
+
+QT_BEGIN_NAMESPACE
+
+static const char RichTextDialogGroupC[] = "RichTextDialog";
+static const char GeometryKeyC[] = "Geometry";
+static const char TabKeyC[] = "Tab";
+
+const bool simplifyRichTextDefault = true;
+
+namespace qdesigner_internal {
+
+// Richtext simplification filter helpers: Elements to be discarded
+static inline bool filterElement(const QStringRef &name)
+{
+ return name != QLatin1String("meta") && name != QLatin1String("style");
+}
+
+// Richtext simplification filter helpers: Filter attributes of elements
+static inline void filterAttributes(const QStringRef &name,
+ QXmlStreamAttributes *atts,
+ bool *paragraphAlignmentFound)
+{
+ typedef QXmlStreamAttributes::iterator AttributeIt;
+
+ if (atts->isEmpty())
+ return;
+
+ // No style attributes for <body>
+ if (name == QLatin1String("body")) {
+ atts->clear();
+ return;
+ }
+
+ // Clean out everything except 'align' for 'p'
+ if (name == QLatin1String("p")) {
+ for (AttributeIt it = atts->begin(); it != atts->end(); ) {
+ if (it->name() == QLatin1String("align")) {
+ ++it;
+ *paragraphAlignmentFound = true;
+ } else {
+ it = atts->erase(it);
+ }
+ }
+ return;
+ }
+}
+
+// Richtext simplification filter helpers: Check for blank QStringRef.
+static inline bool isWhiteSpace(const QStringRef &in)
+{
+ const int count = in.size();
+ for (int i = 0; i < count; i++)
+ if (!in.at(i).isSpace())
+ return false;
+ return true;
+}
+
+// Richtext simplification filter: Remove hard-coded font settings,
+// <style> elements, <p> attributes other than 'align' and
+// and unnecessary meta-information.
+QString simplifyRichTextFilter(const QString &in, bool *isPlainTextPtr = 0)
+{
+ unsigned elementCount = 0;
+ bool paragraphAlignmentFound = false;
+ QString out;
+ QXmlStreamReader reader(in);
+ QXmlStreamWriter writer(&out);
+ writer.setAutoFormatting(false);
+ writer.setAutoFormattingIndent(0);
+
+ while (!reader.atEnd()) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartElement:
+ elementCount++;
+ if (filterElement(reader.name())) {
+ const QStringRef name = reader.name();
+ QXmlStreamAttributes attributes = reader.attributes();
+ filterAttributes(name, &attributes, &paragraphAlignmentFound);
+ writer.writeStartElement(name.toString());
+ if (!attributes.isEmpty())
+ writer.writeAttributes(attributes);
+ } else {
+ reader.readElementText(); // Skip away all nested elements and characters.
+ }
+ break;
+ case QXmlStreamReader::Characters:
+ if (!isWhiteSpace(reader.text()))
+ writer.writeCharacters(reader.text().toString());
+ break;
+ case QXmlStreamReader::EndElement:
+ writer.writeEndElement();
+ break;
+ default:
+ break;
+ }
+ }
+ // Check for plain text (no spans, just <html><head><body><p>)
+ if (isPlainTextPtr)
+ *isPlainTextPtr = !paragraphAlignmentFound && elementCount == 4u; //
+ return out;
+}
+
+class RichTextEditor : public QTextEdit
+{
+ Q_OBJECT
+public:
+ explicit RichTextEditor(QWidget *parent = 0);
+ void setDefaultFont(QFont font);
+
+ QToolBar *createToolBar(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+
+ bool simplifyRichText() const { return m_simplifyRichText; }
+
+public slots:
+ void setFontBold(bool b);
+ void setFontPointSize(double);
+ void setText(const QString &text);
+ void setSimplifyRichText(bool v);
+ QString text(Qt::TextFormat format) const;
+
+signals:
+ void stateChanged();
+ void simplifyRichTextChanged(bool);
+
+private:
+ bool m_simplifyRichText;
+};
+
+class AddLinkDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ AddLinkDialog(RichTextEditor *editor, QWidget *parent = 0);
+ ~AddLinkDialog();
+
+ int showDialog();
+
+public slots:
+ void accept();
+
+private:
+ RichTextEditor *m_editor;
+ Ui::AddLinkDialog *m_ui;
+};
+
+AddLinkDialog::AddLinkDialog(RichTextEditor *editor, QWidget *parent) :
+ QDialog(parent),
+ m_ui(new Ui::AddLinkDialog)
+{
+ m_ui->setupUi(this);
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ m_editor = editor;
+}
+
+AddLinkDialog::~AddLinkDialog()
+{
+ delete m_ui;
+}
+
+int AddLinkDialog::showDialog()
+{
+ // Set initial focus
+ const QTextCursor cursor = m_editor->textCursor();
+ if (cursor.hasSelection()) {
+ m_ui->titleInput->setText(cursor.selectedText());
+ m_ui->urlInput->setFocus();
+ } else {
+ m_ui->titleInput->setFocus();
+ }
+
+ return exec();
+}
+
+void AddLinkDialog::accept()
+{
+ const QString title = m_ui->titleInput->text();
+ const QString url = m_ui->urlInput->text();
+
+ if (!title.isEmpty()) {
+ QString html = QLatin1String("<a href=\"");
+ html += url;
+ html += QLatin1String("\">");
+ html += title;
+ html += QLatin1String("</a>");
+
+ m_editor->insertHtml(html);
+ }
+
+ m_ui->titleInput->clear();
+ m_ui->urlInput->clear();
+
+ QDialog::accept();
+}
+
+class HtmlTextEdit : public QTextEdit
+{
+ Q_OBJECT
+
+public:
+ HtmlTextEdit(QWidget *parent = 0)
+ : QTextEdit(parent)
+ {}
+
+ void contextMenuEvent(QContextMenuEvent *event);
+
+private slots:
+ void actionTriggered(QAction *action);
+};
+
+void HtmlTextEdit::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu *menu = createStandardContextMenu();
+ QMenu *htmlMenu = new QMenu(tr("Insert HTML entity"), menu);
+
+ typedef struct {
+ const char *text;
+ const char *entity;
+ } Entry;
+
+ const Entry entries[] = {
+ { "&&amp; (&&)", "&amp;" },
+ { "&&nbsp;", "&nbsp;" },
+ { "&&lt; (<)", "&lt;" },
+ { "&&gt; (>)", "&gt;" },
+ { "&&copy; (Copyright)", "&copy;" },
+ { "&&reg; (Trade Mark)", "&reg;" },
+ };
+
+ for (int i = 0; i < 6; ++i) {
+ QAction *entityAction = new QAction(QLatin1String(entries[i].text),
+ htmlMenu);
+ entityAction->setData(QLatin1String(entries[i].entity));
+ htmlMenu->addAction(entityAction);
+ }
+
+ menu->addMenu(htmlMenu);
+ connect(htmlMenu, SIGNAL(triggered(QAction*)),
+ SLOT(actionTriggered(QAction*)));
+ menu->exec(event->globalPos());
+ delete menu;
+}
+
+void HtmlTextEdit::actionTriggered(QAction *action)
+{
+ insertPlainText(action->data().toString());
+}
+
+class ColorAction : public QAction
+{
+ Q_OBJECT
+
+public:
+ ColorAction(QObject *parent);
+
+ const QColor& color() const { return m_color; }
+ void setColor(const QColor &color);
+
+signals:
+ void colorChanged(const QColor &color);
+
+private slots:
+ void chooseColor();
+
+private:
+ QColor m_color;
+};
+
+ColorAction::ColorAction(QObject *parent):
+ QAction(parent)
+{
+ setText(tr("Text Color"));
+ setColor(Qt::black);
+ connect(this, SIGNAL(triggered()), this, SLOT(chooseColor()));
+}
+
+void ColorAction::setColor(const QColor &color)
+{
+ if (color == m_color)
+ return;
+ m_color = color;
+ QPixmap pix(24, 24);
+ QPainter painter(&pix);
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ painter.fillRect(pix.rect(), m_color);
+ painter.setPen(m_color.darker());
+ painter.drawRect(pix.rect().adjusted(0, 0, -1, -1));
+ setIcon(pix);
+}
+
+void ColorAction::chooseColor()
+{
+ const QColor col = QColorDialog::getColor(m_color, 0);
+ if (col.isValid() && col != m_color) {
+ setColor(col);
+ emit colorChanged(m_color);
+ }
+}
+
+class RichTextEditorToolBar : public QToolBar
+{
+ Q_OBJECT
+public:
+ RichTextEditorToolBar(QDesignerFormEditorInterface *core,
+ RichTextEditor *editor,
+ QWidget *parent = 0);
+
+public slots:
+ void updateActions();
+
+private slots:
+ void alignmentActionTriggered(QAction *action);
+ void sizeInputActivated(const QString &size);
+ void colorChanged(const QColor &color);
+ void setVAlignSuper(bool super);
+ void setVAlignSub(bool sub);
+ void insertLink();
+ void insertImage();
+
+private:
+ QAction *m_bold_action;
+ QAction *m_italic_action;
+ QAction *m_underline_action;
+ QAction *m_valign_sup_action;
+ QAction *m_valign_sub_action;
+ QAction *m_align_left_action;
+ QAction *m_align_center_action;
+ QAction *m_align_right_action;
+ QAction *m_align_justify_action;
+ QAction *m_link_action;
+ QAction *m_image_action;
+ QAction *m_simplify_richtext_action;
+ ColorAction *m_color_action;
+ QComboBox *m_font_size_input;
+
+ QDesignerFormEditorInterface *m_core;
+ QPointer<RichTextEditor> m_editor;
+};
+
+static QAction *createCheckableAction(const QIcon &icon, const QString &text,
+ QObject *receiver, const char *slot,
+ QObject *parent = 0)
+{
+ QAction *result = new QAction(parent);
+ result->setIcon(icon);
+ result->setText(text);
+ result->setCheckable(true);
+ result->setChecked(false);
+ if (slot)
+ QObject::connect(result, SIGNAL(triggered(bool)), receiver, slot);
+ return result;
+}
+
+RichTextEditorToolBar::RichTextEditorToolBar(QDesignerFormEditorInterface *core,
+ RichTextEditor *editor,
+ QWidget *parent) :
+ QToolBar(parent),
+ m_link_action(new QAction(this)),
+ m_image_action(new QAction(this)),
+ m_color_action(new ColorAction(this)),
+ m_font_size_input(new QComboBox),
+ m_core(core),
+ m_editor(editor)
+{
+ // Font size combo box
+ m_font_size_input->setEditable(false);
+ const QList<int> font_sizes = QFontDatabase::standardSizes();
+ foreach (int font_size, font_sizes)
+ m_font_size_input->addItem(QString::number(font_size));
+
+ connect(m_font_size_input, SIGNAL(activated(QString)),
+ this, SLOT(sizeInputActivated(QString)));
+ addWidget(m_font_size_input);
+
+ addSeparator();
+
+ // Bold, italic and underline buttons
+
+ m_bold_action = createCheckableAction(
+ createIconSet(QLatin1String("textbold.png")),
+ tr("Bold"), editor, SLOT(setFontBold(bool)), this);
+ m_bold_action->setShortcut(tr("CTRL+B"));
+ addAction(m_bold_action);
+
+ m_italic_action = createCheckableAction(
+ createIconSet(QLatin1String("textitalic.png")),
+ tr("Italic"), editor, SLOT(setFontItalic(bool)), this);
+ m_italic_action->setShortcut(tr("CTRL+I"));
+ addAction(m_italic_action);
+
+ m_underline_action = createCheckableAction(
+ createIconSet(QLatin1String("textunder.png")),
+ tr("Underline"), editor, SLOT(setFontUnderline(bool)), this);
+ m_underline_action->setShortcut(tr("CTRL+U"));
+ addAction(m_underline_action);
+
+ addSeparator();
+
+ // Left, center, right and justified alignment buttons
+
+ QActionGroup *alignment_group = new QActionGroup(this);
+ connect(alignment_group, SIGNAL(triggered(QAction*)),
+ SLOT(alignmentActionTriggered(QAction*)));
+
+ m_align_left_action = createCheckableAction(
+ createIconSet(QLatin1String("textleft.png")),
+ tr("Left Align"), editor, 0, alignment_group);
+ addAction(m_align_left_action);
+
+ m_align_center_action = createCheckableAction(
+ createIconSet(QLatin1String("textcenter.png")),
+ tr("Center"), editor, 0, alignment_group);
+ addAction(m_align_center_action);
+
+ m_align_right_action = createCheckableAction(
+ createIconSet(QLatin1String("textright.png")),
+ tr("Right Align"), editor, 0, alignment_group);
+ addAction(m_align_right_action);
+
+ m_align_justify_action = createCheckableAction(
+ createIconSet(QLatin1String("textjustify.png")),
+ tr("Justify"), editor, 0, alignment_group);
+ addAction(m_align_justify_action);
+
+ addSeparator();
+
+ // Superscript and subscript buttons
+
+ m_valign_sup_action = createCheckableAction(
+ createIconSet(QLatin1String("textsuperscript.png")),
+ tr("Superscript"),
+ this, SLOT(setVAlignSuper(bool)), this);
+ addAction(m_valign_sup_action);
+
+ m_valign_sub_action = createCheckableAction(
+ createIconSet(QLatin1String("textsubscript.png")),
+ tr("Subscript"),
+ this, SLOT(setVAlignSub(bool)), this);
+ addAction(m_valign_sub_action);
+
+ addSeparator();
+
+ // Insert hyperlink and image buttons
+
+ m_link_action->setIcon(createIconSet(QLatin1String("textanchor.png")));
+ m_link_action->setText(tr("Insert &Link"));
+ connect(m_link_action, SIGNAL(triggered()), SLOT(insertLink()));
+ addAction(m_link_action);
+
+ m_image_action->setIcon(createIconSet(QLatin1String("insertimage.png")));
+ m_image_action->setText(tr("Insert &Image"));
+ connect(m_image_action, SIGNAL(triggered()), SLOT(insertImage()));
+ addAction(m_image_action);
+
+ addSeparator();
+
+ // Text color button
+ connect(m_color_action, SIGNAL(colorChanged(QColor)),
+ this, SLOT(colorChanged(QColor)));
+ addAction(m_color_action);
+
+ addSeparator();
+
+ // Simplify rich text
+ m_simplify_richtext_action
+ = createCheckableAction(createIconSet(QLatin1String("simplifyrichtext.png")),
+ tr("Simplify Rich Text"), m_editor, SLOT(setSimplifyRichText(bool)));
+ m_simplify_richtext_action->setChecked(m_editor->simplifyRichText());
+ connect(m_editor, SIGNAL(simplifyRichTextChanged(bool)),
+ m_simplify_richtext_action, SLOT(setChecked(bool)));
+ addAction(m_simplify_richtext_action);
+
+ connect(editor, SIGNAL(textChanged()), this, SLOT(updateActions()));
+ connect(editor, SIGNAL(stateChanged()), this, SLOT(updateActions()));
+
+ updateActions();
+}
+
+void RichTextEditorToolBar::alignmentActionTriggered(QAction *action)
+{
+ Qt::Alignment new_alignment;
+
+ if (action == m_align_left_action) {
+ new_alignment = Qt::AlignLeft;
+ } else if (action == m_align_center_action) {
+ new_alignment = Qt::AlignCenter;
+ } else if (action == m_align_right_action) {
+ new_alignment = Qt::AlignRight;
+ } else {
+ new_alignment = Qt::AlignJustify;
+ }
+
+ m_editor->setAlignment(new_alignment);
+}
+
+void RichTextEditorToolBar::colorChanged(const QColor &color)
+{
+ m_editor->setTextColor(color);
+ m_editor->setFocus();
+}
+
+void RichTextEditorToolBar::sizeInputActivated(const QString &size)
+{
+ bool ok;
+ int i = size.toInt(&ok);
+ if (!ok)
+ return;
+
+ m_editor->setFontPointSize(i);
+ m_editor->setFocus();
+}
+
+void RichTextEditorToolBar::setVAlignSuper(bool super)
+{
+ const QTextCharFormat::VerticalAlignment align = super ?
+ QTextCharFormat::AlignSuperScript : QTextCharFormat::AlignNormal;
+
+ QTextCharFormat charFormat = m_editor->currentCharFormat();
+ charFormat.setVerticalAlignment(align);
+ m_editor->setCurrentCharFormat(charFormat);
+
+ m_valign_sub_action->setChecked(false);
+}
+
+void RichTextEditorToolBar::setVAlignSub(bool sub)
+{
+ const QTextCharFormat::VerticalAlignment align = sub ?
+ QTextCharFormat::AlignSubScript : QTextCharFormat::AlignNormal;
+
+ QTextCharFormat charFormat = m_editor->currentCharFormat();
+ charFormat.setVerticalAlignment(align);
+ m_editor->setCurrentCharFormat(charFormat);
+
+ m_valign_sup_action->setChecked(false);
+}
+
+void RichTextEditorToolBar::insertLink()
+{
+ AddLinkDialog linkDialog(m_editor, this);
+ linkDialog.showDialog();
+ m_editor->setFocus();
+}
+
+void RichTextEditorToolBar::insertImage()
+{
+ const QString path = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), QString(), this);
+ if (!path.isEmpty())
+ m_editor->insertHtml(QLatin1String("<img src=\"") + path + QLatin1String("\"/>"));
+}
+
+void RichTextEditorToolBar::updateActions()
+{
+ if (m_editor == 0) {
+ setEnabled(false);
+ return;
+ }
+
+ const Qt::Alignment alignment = m_editor->alignment();
+ const QTextCursor cursor = m_editor->textCursor();
+ const QTextCharFormat charFormat = cursor.charFormat();
+ const QFont font = charFormat.font();
+ const QTextCharFormat::VerticalAlignment valign =
+ charFormat.verticalAlignment();
+ const bool superScript = valign == QTextCharFormat::AlignSuperScript;
+ const bool subScript = valign == QTextCharFormat::AlignSubScript;
+
+ if (alignment & Qt::AlignLeft) {
+ m_align_left_action->setChecked(true);
+ } else if (alignment & Qt::AlignRight) {
+ m_align_right_action->setChecked(true);
+ } else if (alignment & Qt::AlignHCenter) {
+ m_align_center_action->setChecked(true);
+ } else {
+ m_align_justify_action->setChecked(true);
+ }
+
+ m_bold_action->setChecked(font.bold());
+ m_italic_action->setChecked(font.italic());
+ m_underline_action->setChecked(font.underline());
+ m_valign_sup_action->setChecked(superScript);
+ m_valign_sub_action->setChecked(subScript);
+
+ const int size = font.pointSize();
+ const int idx = m_font_size_input->findText(QString::number(size));
+ if (idx != -1)
+ m_font_size_input->setCurrentIndex(idx);
+
+ m_color_action->setColor(m_editor->textColor());
+}
+
+RichTextEditor::RichTextEditor(QWidget *parent)
+ : QTextEdit(parent), m_simplifyRichText(simplifyRichTextDefault)
+{
+ connect(this, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
+ this, SIGNAL(stateChanged()));
+ connect(this, SIGNAL(cursorPositionChanged()),
+ this, SIGNAL(stateChanged()));
+}
+
+QToolBar *RichTextEditor::createToolBar(QDesignerFormEditorInterface *core, QWidget *parent)
+{
+ return new RichTextEditorToolBar(core, this, parent);
+}
+
+void RichTextEditor::setFontBold(bool b)
+{
+ if (b)
+ setFontWeight(QFont::Bold);
+ else
+ setFontWeight(QFont::Normal);
+}
+
+void RichTextEditor::setFontPointSize(double d)
+{
+ QTextEdit::setFontPointSize(qreal(d));
+}
+
+void RichTextEditor::setText(const QString &text)
+{
+
+ if (Qt::mightBeRichText(text))
+ setHtml(text);
+ else
+ setPlainText(text);
+}
+
+void RichTextEditor::setSimplifyRichText(bool v)
+{
+ if (v != m_simplifyRichText) {
+ m_simplifyRichText = v;
+ emit simplifyRichTextChanged(v);
+ }
+}
+
+void RichTextEditor::setDefaultFont(QFont font)
+{
+ // Some default fonts on Windows have a default size of 7.8,
+ // which results in complicated rich text generated by toHtml().
+ // Use an integer value.
+ const int pointSize = qRound(font.pointSizeF());
+ if (pointSize > 0 && !qFuzzyCompare(qreal(pointSize), font.pointSizeF())) {
+ font.setPointSize(pointSize);
+ }
+
+ document()->setDefaultFont(font);
+ if (font.pointSize() > 0)
+ setFontPointSize(font.pointSize());
+ else
+ setFontPointSize(QFontInfo(font).pointSize());
+ emit textChanged();
+}
+
+QString RichTextEditor::text(Qt::TextFormat format) const
+{
+ switch (format) {
+ case Qt::LogText:
+ case Qt::PlainText:
+ return toPlainText();
+ case Qt::RichText:
+ return m_simplifyRichText ? simplifyRichTextFilter(toHtml()) : toHtml();
+ case Qt::AutoText:
+ break;
+ }
+ const QString html = toHtml();
+ bool isPlainText;
+ const QString simplifiedHtml = simplifyRichTextFilter(html, &isPlainText);
+ if (isPlainText)
+ return toPlainText();
+ return m_simplifyRichText ? simplifiedHtml : html;
+}
+
+RichTextEditorDialog::RichTextEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent) :
+ QDialog(parent),
+ m_editor(new RichTextEditor()),
+ m_text_edit(new HtmlTextEdit),
+ m_tab_widget(new QTabWidget),
+ m_state(Clean),
+ m_core(core),
+ m_initialTab(RichTextIndex)
+{
+ setWindowTitle(tr("Edit text"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ // Read settings
+ const QDesignerSettingsInterface *settings = core->settingsManager();
+ const QString rootKey = QLatin1String(RichTextDialogGroupC) + QLatin1Char('/');
+ const QByteArray lastGeometry = settings->value(rootKey + QLatin1String(GeometryKeyC)).toByteArray();
+ const int initialTab = settings->value(rootKey + QLatin1String(TabKeyC), QVariant(m_initialTab)).toInt();
+ if (initialTab == RichTextIndex || initialTab == SourceIndex)
+ m_initialTab = initialTab;
+
+ m_text_edit->setAcceptRichText(false);
+ new HtmlHighlighter(m_text_edit);
+
+ connect(m_editor, SIGNAL(textChanged()), this, SLOT(richTextChanged()));
+ connect(m_editor, SIGNAL(simplifyRichTextChanged(bool)), this, SLOT(richTextChanged()));
+ connect(m_text_edit, SIGNAL(textChanged()), this, SLOT(sourceChanged()));
+
+ // The toolbar needs to be created after the RichTextEditor
+ QToolBar *tool_bar = m_editor->createToolBar(core);
+ tool_bar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ QWidget *rich_edit = new QWidget;
+ QVBoxLayout *rich_edit_layout = new QVBoxLayout(rich_edit);
+ rich_edit_layout->addWidget(tool_bar);
+ rich_edit_layout->addWidget(m_editor);
+
+ QWidget *plain_edit = new QWidget;
+ QVBoxLayout *plain_edit_layout = new QVBoxLayout(plain_edit);
+ plain_edit_layout->addWidget(m_text_edit);
+
+ m_tab_widget->setTabPosition(QTabWidget::South);
+ m_tab_widget->addTab(rich_edit, tr("Rich Text"));
+ m_tab_widget->addTab(plain_edit, tr("Source"));
+ connect(m_tab_widget, SIGNAL(currentChanged(int)),
+ SLOT(tabIndexChanged(int)));
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
+ QPushButton *ok_button = buttonBox->button(QDialogButtonBox::Ok);
+ ok_button->setText(tr("&OK"));
+ ok_button->setDefault(true);
+ buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("&Cancel"));
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addWidget(m_tab_widget);
+ layout->addWidget(buttonBox);
+
+ if (!lastGeometry.isEmpty())
+ restoreGeometry(lastGeometry);
+}
+
+RichTextEditorDialog::~RichTextEditorDialog()
+{
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->beginGroup(QLatin1String(RichTextDialogGroupC));
+
+ settings->setValue(QLatin1String(GeometryKeyC), saveGeometry());
+ settings->setValue(QLatin1String(TabKeyC), m_tab_widget->currentIndex());
+ settings->endGroup();
+}
+
+int RichTextEditorDialog::showDialog()
+{
+ m_tab_widget->setCurrentIndex(m_initialTab);
+ switch (m_initialTab) {
+ case RichTextIndex:
+ m_editor->selectAll();
+ m_editor->setFocus();
+ break;
+ case SourceIndex:
+ m_text_edit->selectAll();
+ m_text_edit->setFocus();
+ break;
+ }
+ return exec();
+}
+
+void RichTextEditorDialog::setDefaultFont(const QFont &font)
+{
+ m_editor->setDefaultFont(font);
+}
+
+void RichTextEditorDialog::setText(const QString &text)
+{
+ // Generally simplify rich text unless verbose text is found.
+ const bool isSimplifiedRichText = !text.startsWith("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">");
+ m_editor->setSimplifyRichText(isSimplifiedRichText);
+ m_editor->setText(text);
+ m_text_edit->setPlainText(text);
+ m_state = Clean;
+}
+
+QString RichTextEditorDialog::text(Qt::TextFormat format) const
+{
+ // In autotext mode, if the user has changed the source, use that
+ if (format == Qt::AutoText && (m_state == Clean || m_state == SourceChanged))
+ return m_text_edit->toPlainText();
+ // If the plain text HTML editor is selected, first copy its contents over
+ // to the rich text editor so that it is converted to Qt-HTML or actual
+ // plain text.
+ if (m_tab_widget->currentIndex() == SourceIndex && m_state == SourceChanged)
+ m_editor->setHtml(m_text_edit->toPlainText());
+ return m_editor->text(format);
+}
+
+void RichTextEditorDialog::tabIndexChanged(int newIndex)
+{
+ // Anything changed, is there a need for a conversion?
+ if (newIndex == SourceIndex && m_state != RichTextChanged)
+ return;
+ if (newIndex == RichTextIndex && m_state != SourceChanged)
+ return;
+ const State oldState = m_state;
+ // Remember the cursor position, since it is invalidated by setPlainText
+ QTextEdit *new_edit = (newIndex == SourceIndex) ? m_text_edit : m_editor;
+ const int position = new_edit->textCursor().position();
+
+ if (newIndex == SourceIndex)
+ m_text_edit->setPlainText(m_editor->text(Qt::RichText));
+ else
+ m_editor->setHtml(m_text_edit->toPlainText());
+
+ QTextCursor cursor = new_edit->textCursor();
+ cursor.movePosition(QTextCursor::End);
+ if (cursor.position() > position) {
+ cursor.setPosition(position);
+ }
+ new_edit->setTextCursor(cursor);
+ m_state = oldState; // Changed is triggered by setting the text
+}
+
+void RichTextEditorDialog::richTextChanged()
+{
+ m_state = RichTextChanged;
+}
+
+void RichTextEditorDialog::sourceChanged()
+{
+ m_state = SourceChanged;
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#include "richtexteditor.moc"
diff --git a/src/designer/src/lib/shared/richtexteditor_p.h b/src/designer/src/lib/shared/richtexteditor_p.h
new file mode 100644
index 000000000..086c5d518
--- /dev/null
+++ b/src/designer/src/lib/shared/richtexteditor_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef RICHTEXTEDITOR_H
+#define RICHTEXTEDITOR_H
+
+#include <QtGui/QTextEdit>
+#include <QtGui/QDialog>
+#include "shared_global_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTabWidget;
+class QToolBar;
+
+class QDesignerFormEditorInterface;
+
+namespace qdesigner_internal {
+
+class RichTextEditor;
+
+class QDESIGNER_SHARED_EXPORT RichTextEditorDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit RichTextEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent = 0);
+ ~RichTextEditorDialog();
+
+ int showDialog();
+ void setDefaultFont(const QFont &font);
+ void setText(const QString &text);
+ QString text(Qt::TextFormat format = Qt::AutoText) const;
+
+private slots:
+ void tabIndexChanged(int newIndex);
+ void richTextChanged();
+ void sourceChanged();
+
+private:
+ enum TabIndex { RichTextIndex, SourceIndex };
+ enum State { Clean, RichTextChanged, SourceChanged };
+ RichTextEditor *m_editor;
+ QTextEdit *m_text_edit;
+ QTabWidget *m_tab_widget;
+ State m_state;
+ QDesignerFormEditorInterface *m_core;
+ int m_initialTab;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // RITCHTEXTEDITOR_H
diff --git a/src/designer/src/lib/shared/scriptcommand.cpp b/src/designer/src/lib/shared/scriptcommand.cpp
new file mode 100644
index 000000000..a8f47a574
--- /dev/null
+++ b/src/designer/src/lib/shared/scriptcommand.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scriptcommand_p.h"
+#include "metadatabase_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+ScriptCommand::ScriptCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QCoreApplication::translate("Command", "Change script"), formWindow)
+{
+}
+
+bool ScriptCommand::init(const ObjectList &list, const QString &script)
+{
+ MetaDataBase *metaDataBase = qobject_cast<MetaDataBase*>(formWindow()->core()->metaDataBase());
+ if (!metaDataBase)
+ return false;
+
+ // Save old values
+ m_oldValues.clear();
+ foreach (QObject *obj, list) {
+ const MetaDataBaseItem* item = metaDataBase->metaDataBaseItem(obj);
+ if (!item)
+ return false;
+ m_oldValues.push_back(ObjectScriptPair(obj, item->script()));
+ }
+ m_script = script;
+ return true;
+}
+
+void ScriptCommand::redo()
+{
+ MetaDataBase *metaDataBase = qobject_cast<MetaDataBase*>(formWindow()->core()->metaDataBase());
+ Q_ASSERT(metaDataBase);
+
+ ObjectScriptList::const_iterator cend = m_oldValues.constEnd();
+ for (ObjectScriptList::const_iterator it = m_oldValues.constBegin();it != cend; ++it ) {
+ if (it->first)
+ metaDataBase->metaDataBaseItem(it->first)->setScript(m_script);
+ }
+}
+
+void ScriptCommand::undo()
+{
+ MetaDataBase *metaDataBase = qobject_cast<MetaDataBase*>(formWindow()->core()->metaDataBase());
+ Q_ASSERT(metaDataBase);
+
+ ObjectScriptList::const_iterator cend = m_oldValues.constEnd();
+ for (ObjectScriptList::const_iterator it = m_oldValues.constBegin();it != cend; ++it ) {
+ if (it->first)
+ metaDataBase->metaDataBaseItem(it->first)->setScript(it->second);
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/scriptcommand_p.h b/src/designer/src/lib/shared/scriptcommand_p.h
new file mode 100644
index 000000000..eed8e06eb
--- /dev/null
+++ b/src/designer/src/lib/shared/scriptcommand_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_SCRIPTCOMMAND_H
+#define QDESIGNER_SCRIPTCOMMAND_H
+
+#include "qdesigner_formwindowcommand_p.h"
+
+#include <QtCore/QPair>
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT ScriptCommand: public QDesignerFormWindowCommand
+{
+ ScriptCommand(const ScriptCommand &);
+ ScriptCommand& operator=(const ScriptCommand &);
+
+public:
+ explicit ScriptCommand(QDesignerFormWindowInterface *formWindow);
+
+ typedef QList<QObject *> ObjectList;
+ bool init(const ObjectList &list, const QString &script);
+
+ virtual void redo();
+ virtual void undo();
+
+private:
+ typedef QPair<QPointer<QObject>, QString> ObjectScriptPair;
+ typedef QList<ObjectScriptPair> ObjectScriptList;
+ ObjectScriptList m_oldValues;
+ QString m_script;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_SCRIPTCOMMAND_H
diff --git a/src/designer/src/lib/shared/scriptdialog.cpp b/src/designer/src/lib/shared/scriptdialog.cpp
new file mode 100644
index 000000000..e2c1c7460
--- /dev/null
+++ b/src/designer/src/lib/shared/scriptdialog.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scriptdialog_p.h"
+#include "qscripthighlighter_p.h"
+
+#include <abstractdialoggui_p.h>
+
+#include <QtGui/QTextEdit>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QMessageBox>
+#ifdef QT_SCRIPT_LIB
+#include <QtScript/QScriptEngine>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+ // ScriptDialog
+ ScriptDialog::ScriptDialog(QDesignerDialogGuiInterface *m_dialogGui, QWidget *parent) :
+ QDialog(parent),
+ m_dialogGui(m_dialogGui),
+ m_textEdit(new QTextEdit)
+ {
+ setWindowTitle(tr("Edit script"));
+ setModal(true);
+
+ QVBoxLayout *vboxLayout = new QVBoxLayout(this);
+
+ const QString textHelp = tr("\
+<html>Enter a Qt Script snippet to be executed while loading the form.<br>\
+The widget and its children are accessible via the \
+variables <i>widget</i> and <i>childWidgets</i>, respectively.");
+ m_textEdit->setToolTip(textHelp);
+ m_textEdit->setWhatsThis(textHelp);
+ m_textEdit->setMinimumSize(QSize(600, 400));
+ vboxLayout->addWidget(m_textEdit);
+ new QScriptHighlighter(m_textEdit->document());
+ // button box
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
+ connect(buttonBox , SIGNAL(rejected()), this, SLOT(reject()));
+ connect(buttonBox , SIGNAL(accepted()), this, SLOT(slotAccept()));
+ vboxLayout->addWidget(buttonBox);
+ }
+
+ bool ScriptDialog::editScript(QString &script)
+ {
+ m_textEdit->setText(script);
+ if (exec() != Accepted)
+ return false;
+
+ script = trimmedScript();
+ return true;
+ }
+
+ void ScriptDialog::slotAccept()
+ {
+ if (checkScript())
+ accept();
+ }
+
+ QString ScriptDialog::trimmedScript() const
+ {
+ // Ensure a single newline
+ QString rc = m_textEdit->toPlainText().trimmed();
+ if (!rc.isEmpty())
+ rc += QLatin1Char('\n');
+ return rc;
+ }
+
+ bool ScriptDialog::checkScript()
+ {
+ const QString script = trimmedScript();
+ if (script.isEmpty())
+ return true;
+#ifdef QT_SCRIPT_LIB
+ QScriptEngine scriptEngine;
+ if (scriptEngine.canEvaluate(script))
+ return true;
+ m_dialogGui->message(this, QDesignerDialogGuiInterface::ScriptDialogMessage, QMessageBox::Warning,
+ windowTitle(), tr("Syntax error"), QMessageBox::Ok);
+ return false;
+#else
+ return true;
+#endif
+ }
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/scriptdialog_p.h b/src/designer/src/lib/shared/scriptdialog_p.h
new file mode 100644
index 000000000..bb1881d00
--- /dev/null
+++ b/src/designer/src/lib/shared/scriptdialog_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SCRIPTDIALOG_H
+#define SCRIPTDIALOG_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerDialogGuiInterface;
+
+class QTextEdit;
+
+namespace qdesigner_internal {
+
+ // Dialog for showing script errors
+ class QDESIGNER_SHARED_EXPORT ScriptDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit ScriptDialog(QDesignerDialogGuiInterface *dialogGui, QWidget *parent);
+ bool editScript(QString &script);
+
+ private slots:
+ void slotAccept();
+
+ private:
+ QString trimmedScript() const;
+ bool checkScript();
+
+ QDesignerDialogGuiInterface *m_dialogGui;
+ QTextEdit *m_textEdit;
+ };
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SCRIPTDIALOG_H
diff --git a/src/designer/src/lib/shared/scripterrordialog.cpp b/src/designer/src/lib/shared/scripterrordialog.cpp
new file mode 100644
index 000000000..30d57342b
--- /dev/null
+++ b/src/designer/src/lib/shared/scripterrordialog.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scripterrordialog_p.h"
+
+#include <QtGui/QTextEdit>
+#include <QtGui/QTextCursor>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QPen>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+static void formatError(const QFormScriptRunner::Error &error,
+ QTextCursor &cursor)
+{
+ const QTextCharFormat oldFormat = cursor.charFormat();
+ // Message
+ cursor.insertText(QCoreApplication::translate("ScriptErrorDialog", "An error occurred while running the scripts for \"%1\":\n").arg(error.objectName));
+
+ QTextCharFormat format(oldFormat);
+
+ // verbatim listing
+ format.setFontFamily(QLatin1String("Courier"));
+ cursor.insertText(error.script, format);
+
+ const QString newLine(QLatin1Char('\n'));
+
+ cursor.insertText(newLine);
+
+ // red error
+ format = oldFormat;
+ format.setTextOutline(QPen(Qt::red));
+ cursor.insertText(error.errorMessage, format);
+ cursor.insertText(newLine);
+ cursor.setCharFormat (oldFormat);
+}
+
+namespace qdesigner_internal {
+
+ // ScriptErrorDialog
+ ScriptErrorDialog::ScriptErrorDialog(const Errors& errors, QWidget *parent) :
+ QDialog(parent),
+ m_textEdit(new QTextEdit)
+ {
+ setWindowTitle(tr("Script errors"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setModal(true);
+
+ QVBoxLayout *vboxLayout = new QVBoxLayout(this);
+
+ m_textEdit->setReadOnly(true);
+ m_textEdit->setMinimumSize(QSize(600, 400));
+ vboxLayout->addWidget(m_textEdit);
+ // button box
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
+ connect(buttonBox , SIGNAL(rejected()), this, SLOT(reject()));
+ vboxLayout->addWidget(buttonBox);
+
+ // Generate text
+ QTextCursor cursor = m_textEdit->textCursor();
+ cursor.movePosition (QTextCursor::End);
+ foreach (const QFormScriptRunner::Error error, errors)
+ formatError(error, cursor);
+ }
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/scripterrordialog_p.h b/src/designer/src/lib/shared/scripterrordialog_p.h
new file mode 100644
index 000000000..24ead6f4b
--- /dev/null
+++ b/src/designer/src/lib/shared/scripterrordialog_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SCRIPTERRORDIALOG_H
+#define SCRIPTERRORDIALOG_H
+
+#include "shared_global_p.h"
+#include "formscriptrunner_p.h"
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+
+namespace qdesigner_internal {
+
+ // Dialog for showing script errors
+ class QDESIGNER_SHARED_EXPORT ScriptErrorDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ typedef QFormScriptRunner::Errors Errors;
+ ScriptErrorDialog(const Errors& errors, QWidget *parent);
+
+ private:
+ QTextEdit *m_textEdit;
+
+ };
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SCRIPTERRORDIALOG_H
diff --git a/src/designer/src/lib/shared/selectsignaldialog.ui b/src/designer/src/lib/shared/selectsignaldialog.ui
new file mode 100644
index 000000000..99387dd2a
--- /dev/null
+++ b/src/designer/src/lib/shared/selectsignaldialog.ui
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SelectSignalDialog</class>
+ <widget class="QDialog" name="SelectSignalDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>514</width>
+ <height>183</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Go to slot</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Select signal</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QTreeWidget" name="signalList">
+ <property name="sortingEnabled">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>signal</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>class</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>SelectSignalDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>257</x>
+ <y>335</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>SelectSignalDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>325</x>
+ <y>335</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/shared.pri b/src/designer/src/lib/shared/shared.pri
new file mode 100644
index 000000000..9d5091164
--- /dev/null
+++ b/src/designer/src/lib/shared/shared.pri
@@ -0,0 +1,189 @@
+
+INCLUDEPATH += $$PWD
+contains(QT_CONFIG, script): QT += script
+
+include(../../../../shared/qtpropertybrowser/qtpropertybrowserutils.pri)
+include(../../../../shared/deviceskin/deviceskin.pri)
+include(../../../../../src/tools/rcc/rcc.pri)
+include(../../../../shared/findwidget/findwidget.pri)
+include(../../../../shared/qtgradienteditor/qtgradienteditor.pri)
+
+# Input
+FORMS += $$PWD/addlinkdialog.ui \
+ $$PWD/orderdialog.ui \
+ $$PWD/newactiondialog.ui \
+ $$PWD/gridpanel.ui \
+ $$PWD/signalslotdialog.ui \
+ $$PWD/previewconfigurationwidget.ui \
+ $$PWD/qtresourceeditordialog.ui \
+ $$PWD/newformwidget.ui \
+ $$PWD/selectsignaldialog.ui \
+ $$PWD/formlayoutrowdialog.ui \
+ $$PWD/plugindialog.ui
+
+HEADERS += \
+ $$PWD/shared_global_p.h \
+ $$PWD/spacer_widget_p.h \
+ $$PWD/layoutinfo_p.h \
+ $$PWD/layout_p.h \
+ $$PWD/connectionedit_p.h \
+ $$PWD/pluginmanager_p.h \
+ $$PWD/metadatabase_p.h \
+ $$PWD/qdesigner_formeditorcommand_p.h \
+ $$PWD/qdesigner_formwindowcommand_p.h \
+ $$PWD/qdesigner_command_p.h \
+ $$PWD/morphmenu_p.h \
+ $$PWD/qdesigner_command2_p.h \
+ $$PWD/qdesigner_formbuilder_p.h \
+ $$PWD/qdesigner_taskmenu_p.h \
+ $$PWD/formlayoutmenu_p.h \
+ $$PWD/qdesigner_widget_p.h \
+ $$PWD/qdesigner_propertysheet_p.h \
+ $$PWD/qdesigner_membersheet_p.h \
+ $$PWD/qdesigner_propertyeditor_p.h \
+ $$PWD/qdesigner_objectinspector_p.h \
+ $$PWD/qdesigner_integration_p.h \
+ $$PWD/invisible_widget_p.h \
+ $$PWD/qlayout_widget_p.h \
+ $$PWD/sheet_delegate_p.h \
+ $$PWD/qdesigner_stackedbox_p.h \
+ $$PWD/qdesigner_tabwidget_p.h \
+ $$PWD/qdesigner_dockwidget_p.h \
+ $$PWD/qdesigner_toolbox_p.h \
+ $$PWD/qdesigner_dnditem_p.h \
+ $$PWD/qsimpleresource_p.h \
+ $$PWD/widgetfactory_p.h \
+ $$PWD/widgetdatabase_p.h \
+ $$PWD/qdesigner_promotion_p.h \
+ $$PWD/qdesigner_introspection_p.h \
+ $$PWD/promotionmodel_p.h \
+ $$PWD/qdesigner_promotiondialog_p.h \
+ $$PWD/iconloader_p.h \
+ $$PWD/richtexteditor_p.h \
+ $$PWD/plaintexteditor_p.h \
+ $$PWD/actioneditor_p.h \
+ $$PWD/actionrepository_p.h \
+ $$PWD/qdesigner_toolbar_p.h \
+ $$PWD/qdesigner_menubar_p.h \
+ $$PWD/qdesigner_menu_p.h \
+ $$PWD/actionprovider_p.h \
+ $$PWD/orderdialog_p.h \
+ $$PWD/newactiondialog_p.h \
+ $$PWD/stylesheeteditor_p.h \
+ $$PWD/csshighlighter_p.h \
+ $$PWD/shared_enums_p.h \
+ $$PWD/textpropertyeditor_p.h \
+ $$PWD/propertylineedit_p.h \
+ $$PWD/promotiontaskmenu_p.h \
+ $$PWD/scripterrordialog_p.h \
+ $$PWD/scriptcommand_p.h \
+ $$PWD/scriptdialog_p.h \
+ $$PWD/qscripthighlighter_p.h \
+ $$PWD/gridpanel_p.h \
+ $$PWD/grid_p.h \
+ $$PWD/formwindowbase_p.h \
+ $$PWD/qdesigner_utils_p.h \
+ $$PWD/qdesigner_widgetbox_p.h \
+ $$PWD/signalslotdialog_p.h \
+ $$PWD/extensionfactory_p.h \
+ $$PWD/dialoggui_p.h \
+ $$PWD/deviceprofile_p.h \
+ $$PWD/zoomwidget_p.h \
+ $$PWD/previewmanager_p.h \
+ $$PWD/previewconfigurationwidget_p.h \
+ $$PWD/codedialog_p.h \
+ $$PWD/qtresourceeditordialog_p.h \
+ $$PWD/qtresourcemodel_p.h \
+ $$PWD/qtresourceview_p.h \
+ $$PWD/iconselector_p.h \
+ $$PWD/htmlhighlighter_p.h \
+ $$PWD/qdesigner_widgetitem_p.h \
+ $$PWD/qdesigner_qsettings_p.h \
+ $$PWD/qdesigner_formwindowmanager_p.h \
+ $$PWD/shared_settings_p.h \
+ $$PWD/newformwidget_p.h \
+ $$PWD/filterwidget_p.h \
+ $$PWD/plugindialog_p.h
+
+SOURCES += \
+ $$PWD/spacer_widget.cpp \
+ $$PWD/layoutinfo.cpp \
+ $$PWD/layout.cpp \
+ $$PWD/connectionedit.cpp \
+ $$PWD/pluginmanager.cpp \
+ $$PWD/qdesigner_formwindowcommand.cpp \
+ $$PWD/qdesigner_formeditorcommand.cpp \
+ $$PWD/qdesigner_command.cpp \
+ $$PWD/morphmenu.cpp \
+ $$PWD/qdesigner_command2.cpp \
+ $$PWD/qdesigner_propertycommand.cpp \
+ $$PWD/qdesigner_formbuilder.cpp \
+ $$PWD/qdesigner_taskmenu.cpp \
+ $$PWD/formlayoutmenu.cpp \
+ $$PWD/qdesigner_widget.cpp \
+ $$PWD/qdesigner_dockwidget.cpp \
+ $$PWD/qdesigner_propertysheet.cpp \
+ $$PWD/qdesigner_membersheet.cpp \
+ $$PWD/qdesigner_propertyeditor.cpp \
+ $$PWD/qdesigner_objectinspector.cpp \
+ $$PWD/qdesigner_integration.cpp \
+ $$PWD/qdesigner_dnditem.cpp \
+ $$PWD/qsimpleresource.cpp \
+ $$PWD/invisible_widget.cpp \
+ $$PWD/qlayout_widget.cpp \
+ $$PWD/sheet_delegate.cpp \
+ $$PWD/metadatabase.cpp \
+ $$PWD/qdesigner_stackedbox.cpp \
+ $$PWD/qdesigner_tabwidget.cpp \
+ $$PWD/qdesigner_toolbox.cpp \
+ $$PWD/widgetfactory.cpp \
+ $$PWD/widgetdatabase.cpp \
+ $$PWD/qdesigner_promotion.cpp \
+ $$PWD/qdesigner_introspection.cpp \
+ $$PWD/promotionmodel.cpp \
+ $$PWD/qdesigner_promotiondialog.cpp \
+ $$PWD/richtexteditor.cpp \
+ $$PWD/plaintexteditor.cpp \
+ $$PWD/actioneditor.cpp \
+ $$PWD/actionrepository.cpp \
+ $$PWD/qdesigner_toolbar.cpp \
+ $$PWD/qdesigner_menubar.cpp \
+ $$PWD/qdesigner_menu.cpp \
+ $$PWD/orderdialog.cpp \
+ $$PWD/newactiondialog.cpp \
+ $$PWD/stylesheeteditor.cpp \
+ $$PWD/csshighlighter.cpp \
+ $$PWD/textpropertyeditor.cpp \
+ $$PWD/propertylineedit.cpp \
+ $$PWD/promotiontaskmenu.cpp \
+ $$PWD/scripterrordialog.cpp \
+ $$PWD/scriptcommand.cpp \
+ $$PWD/scriptdialog.cpp \
+ $$PWD/qscripthighlighter.cpp\
+ $$PWD/gridpanel.cpp \
+ $$PWD/grid.cpp \
+ $$PWD/formwindowbase.cpp \
+ $$PWD/qdesigner_utils.cpp \
+ $$PWD/qdesigner_widgetbox.cpp \
+ $$PWD/iconloader.cpp \
+ $$PWD/signalslotdialog.cpp \
+ $$PWD/dialoggui.cpp \
+ $$PWD/deviceprofile.cpp \
+ $$PWD/zoomwidget.cpp \
+ $$PWD/previewmanager.cpp \
+ $$PWD/previewconfigurationwidget.cpp \
+ $$PWD/codedialog.cpp \
+ $$PWD/qtresourceeditordialog.cpp \
+ $$PWD/qtresourcemodel.cpp \
+ $$PWD/qtresourceview.cpp \
+ $$PWD/iconselector.cpp \
+ $$PWD/htmlhighlighter.cpp \
+ $$PWD/qdesigner_widgetitem.cpp \
+ $$PWD/qdesigner_qsettings.cpp \
+ $$PWD/qdesigner_formwindowmanager.cpp \
+ $$PWD/shared_settings.cpp \
+ $$PWD/newformwidget.cpp \
+ $$PWD/filterwidget.cpp \
+ $$PWD/plugindialog.cpp
+
+RESOURCES += $$PWD/shared.qrc
diff --git a/src/designer/src/lib/shared/shared.qrc b/src/designer/src/lib/shared/shared.qrc
new file mode 100644
index 000000000..81be8076d
--- /dev/null
+++ b/src/designer/src/lib/shared/shared.qrc
@@ -0,0 +1,20 @@
+<RCC>
+ <qresource prefix="/trolltech/designer">
+ <file>defaultgradients.xml</file>
+ <!-- Templates -->
+ <file>templates/forms/Dialog_with_Buttons_Bottom.ui</file>
+ <file>templates/forms/240x320/Dialog_with_Buttons_Bottom.ui</file>
+ <file>templates/forms/320x240/Dialog_with_Buttons_Bottom.ui</file>
+ <file>templates/forms/480x640/Dialog_with_Buttons_Bottom.ui</file>
+ <file>templates/forms/640x480/Dialog_with_Buttons_Bottom.ui</file>
+ <file>templates/forms/Dialog_with_Buttons_Right.ui</file>
+ <file>templates/forms/240x320/Dialog_with_Buttons_Right.ui</file>
+ <file>templates/forms/320x240/Dialog_with_Buttons_Right.ui</file>
+ <file>templates/forms/480x640/Dialog_with_Buttons_Right.ui</file>
+ <file>templates/forms/640x480/Dialog_with_Buttons_Right.ui</file>
+ <file>templates/forms/Dialog_without_Buttons.ui</file>
+ <file>templates/forms/Widget.ui</file>
+ <file>templates/forms/Main_Window.ui</file>
+ </qresource>
+</RCC>
+
diff --git a/src/designer/src/lib/shared/shared_enums_p.h b/src/designer/src/lib/shared/shared_enums_p.h
new file mode 100644
index 000000000..cbf90589d
--- /dev/null
+++ b/src/designer/src/lib/shared/shared_enums_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SHAREDENUMS_H
+#define SHAREDENUMS_H
+
+#include "shared_global_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+ // Validation mode of text property line edits
+ enum TextPropertyValidationMode {
+ // Allow for multiline editing using literal "\n".
+ ValidationMultiLine,
+ // Allow for HTML rich text including multiline editing using literal "\n".
+ ValidationRichText,
+ // Validate a stylesheet
+ ValidationStyleSheet,
+ // Single line mode, suppresses newlines
+ ValidationSingleLine,
+ // Allow only for identifier characters
+ ValidationObjectName,
+ // Allow only for identifier characters and colons
+ ValidationObjectNameScope,
+ // URL
+ ValidationURL
+ };
+
+ // Container types
+ enum ContainerType {
+ // A container with pages, at least one of which one must always be present (for example, QTabWidget)
+ PageContainer,
+ // Mdi type container. All pages may be deleted, no concept of page order
+ MdiContainer,
+ // Wizard container
+ WizardContainer
+ };
+
+ enum AuxiliaryItemDataRoles {
+ // item->flags while being edited
+ ItemFlagsShadowRole = 0x13370551
+ };
+
+}
+
+QT_END_NAMESPACE
+
+#endif // SHAREDENUMS_H
diff --git a/src/designer/src/lib/shared/shared_global_p.h b/src/designer/src/lib/shared/shared_global_p.h
new file mode 100644
index 000000000..ce0a7aaf4
--- /dev/null
+++ b/src/designer/src/lib/shared/shared_global_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SHARED_GLOBAL_H
+#define SHARED_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef QT_DESIGNER_STATIC
+#define QDESIGNER_SHARED_EXTERN
+#define QDESIGNER_SHARED_IMPORT
+#else
+#define QDESIGNER_SHARED_EXTERN Q_DECL_EXPORT
+#define QDESIGNER_SHARED_IMPORT Q_DECL_IMPORT
+#endif
+
+#ifndef QT_NO_SHARED_EXPORT
+# ifdef QDESIGNER_SHARED_LIBRARY
+# define QDESIGNER_SHARED_EXPORT QDESIGNER_SHARED_EXTERN
+# else
+# define QDESIGNER_SHARED_EXPORT QDESIGNER_SHARED_IMPORT
+# endif
+#else
+# define QDESIGNER_SHARED_EXPORT
+#endif
+
+#endif // SHARED_GLOBAL_H
diff --git a/src/designer/src/lib/shared/shared_settings.cpp b/src/designer/src/lib/shared/shared_settings.cpp
new file mode 100644
index 000000000..20b49fd35
--- /dev/null
+++ b/src/designer/src/lib/shared/shared_settings.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "shared_settings_p.h"
+#include "grid_p.h"
+#include "previewmanager_p.h"
+#include "qdesigner_utils_p.h"
+#include <QtDesigner/abstractformeditor.h>
+#include <QtDesigner/private/abstractsettings_p.h>
+#include <QtCore/QStringList>
+#include <QtCore/QDir>
+#include <QtCore/QVariantMap>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QSize>
+
+QT_BEGIN_NAMESPACE
+
+static const char *designerPath = "/.designer";
+static const char *defaultGridKey = "defaultGrid";
+static const char *previewKey = "Preview";
+static const char *enabledKey = "Enabled";
+static const char *userDeviceSkinsKey= "UserDeviceSkins";
+static const char *zoomKey = "zoom";
+static const char *zoomEnabledKey = "zoomEnabled";
+static const char *deviceProfileIndexKey = "DeviceProfileIndex";
+static const char *deviceProfilesKey = "DeviceProfiles";
+static const char *formTemplatePathsKey = "FormTemplatePaths";
+static const char *formTemplateKey = "FormTemplate";
+static const char *newFormSizeKey = "NewFormSize";
+
+using namespace qdesigner_internal;
+
+static bool checkTemplatePath(const QString &path, bool create)
+{
+ QDir current(QDir::current());
+ if (current.exists(path))
+ return true;
+
+ if (!create)
+ return false;
+
+ if (current.mkpath(path))
+ return true;
+
+ qdesigner_internal::designerWarning(QCoreApplication::translate("QDesignerSharedSettings", "The template path %1 could not be created.").arg(path));
+ return false;
+}
+
+namespace qdesigner_internal {
+
+QDesignerSharedSettings::QDesignerSharedSettings(QDesignerFormEditorInterface *core)
+ : m_settings(core->settingsManager())
+{
+}
+
+Grid QDesignerSharedSettings::defaultGrid() const
+{
+ Grid grid;
+ const QVariantMap defaultGridMap
+ = m_settings->value(QLatin1String(defaultGridKey), QVariantMap()).toMap();
+ if (!defaultGridMap.empty())
+ grid.fromVariantMap(defaultGridMap);
+ return grid;
+}
+
+void QDesignerSharedSettings::setDefaultGrid(const Grid &grid)
+{
+ m_settings->setValue(QLatin1String(defaultGridKey), grid.toVariantMap());
+}
+
+const QStringList &QDesignerSharedSettings::defaultFormTemplatePaths()
+{
+ static QStringList rc;
+ if (rc.empty()) {
+ // Ensure default form template paths
+ const QString templatePath = QLatin1String("/templates");
+ // home
+ QString path = QDir::homePath();
+ path += QLatin1String(designerPath);
+ path += templatePath;
+ if (checkTemplatePath(path, true))
+ rc += path;
+
+ // designer/bin: Might be owned by root in some installations, do not force it.
+ path = qApp->applicationDirPath();
+ path += templatePath;
+ if (checkTemplatePath(path, false))
+ rc += path;
+ }
+ return rc;
+}
+
+QStringList QDesignerSharedSettings::formTemplatePaths() const
+{
+ return m_settings->value(QLatin1String(formTemplatePathsKey),
+ defaultFormTemplatePaths()).toStringList();
+}
+
+void QDesignerSharedSettings::setFormTemplatePaths(const QStringList &paths)
+{
+ m_settings->setValue(QLatin1String(formTemplatePathsKey), paths);
+}
+
+QString QDesignerSharedSettings::formTemplate() const
+{
+ return m_settings->value(QLatin1String(formTemplateKey)).toString();
+}
+
+void QDesignerSharedSettings::setFormTemplate(const QString &t)
+{
+ m_settings->setValue(QLatin1String(formTemplateKey), t);
+}
+
+void QDesignerSharedSettings::setAdditionalFormTemplatePaths(const QStringList &additionalPaths)
+{
+ // merge template paths
+ QStringList templatePaths = defaultFormTemplatePaths();
+ templatePaths += additionalPaths;
+ setFormTemplatePaths(templatePaths);
+}
+
+QStringList QDesignerSharedSettings::additionalFormTemplatePaths() const
+{
+ // get template paths excluding internal ones
+ QStringList rc = formTemplatePaths();
+ foreach (const QString &internalTemplatePath, defaultFormTemplatePaths()) {
+ const int index = rc.indexOf(internalTemplatePath);
+ if (index != -1)
+ rc.removeAt(index);
+ }
+ return rc;
+}
+
+QSize QDesignerSharedSettings::newFormSize() const
+{
+ return m_settings->value(QLatin1String(newFormSizeKey), QSize(0, 0)).toSize();
+}
+
+void QDesignerSharedSettings::setNewFormSize(const QSize &s)
+{
+ if (s.isNull()) {
+ m_settings->remove(QLatin1String(newFormSizeKey));
+ } else {
+ m_settings->setValue(QLatin1String(newFormSizeKey), s);
+ }
+}
+
+
+PreviewConfiguration QDesignerSharedSettings::customPreviewConfiguration() const
+{
+ PreviewConfiguration configuration;
+ configuration.fromSettings(QLatin1String(previewKey), m_settings);
+ return configuration;
+}
+
+void QDesignerSharedSettings::setCustomPreviewConfiguration(const PreviewConfiguration &configuration)
+{
+ configuration.toSettings(QLatin1String(previewKey), m_settings);
+}
+
+bool QDesignerSharedSettings::isCustomPreviewConfigurationEnabled() const
+{
+ m_settings->beginGroup(QLatin1String(previewKey));
+ bool isEnabled = m_settings->value(QLatin1String(enabledKey), false).toBool();
+ m_settings->endGroup();
+ return isEnabled;
+}
+
+void QDesignerSharedSettings::setCustomPreviewConfigurationEnabled(bool enabled)
+{
+ m_settings->beginGroup(QLatin1String(previewKey));
+ m_settings->setValue(QLatin1String(enabledKey), enabled);
+ m_settings->endGroup();
+}
+
+QStringList QDesignerSharedSettings::userDeviceSkins() const
+{
+ m_settings->beginGroup(QLatin1String(previewKey));
+ QStringList userDeviceSkins
+ = m_settings->value(QLatin1String(userDeviceSkinsKey), QStringList()).toStringList();
+ m_settings->endGroup();
+ return userDeviceSkins;
+}
+
+void QDesignerSharedSettings::setUserDeviceSkins(const QStringList &userDeviceSkins)
+{
+ m_settings->beginGroup(QLatin1String(previewKey));
+ m_settings->setValue(QLatin1String(userDeviceSkinsKey), userDeviceSkins);
+ m_settings->endGroup();
+}
+
+int QDesignerSharedSettings::zoom() const
+{
+ return m_settings->value(QLatin1String(zoomKey), 100).toInt();
+}
+
+void QDesignerSharedSettings::setZoom(int z)
+{
+ m_settings->setValue(QLatin1String(zoomKey), QVariant(z));
+}
+
+bool QDesignerSharedSettings::zoomEnabled() const
+{
+ return m_settings->value(QLatin1String(zoomEnabledKey), false).toBool();
+}
+
+void QDesignerSharedSettings::setZoomEnabled(bool v)
+{
+ m_settings->setValue(QLatin1String(zoomEnabledKey), v);
+}
+
+DeviceProfile QDesignerSharedSettings::currentDeviceProfile() const
+{
+ return deviceProfileAt(currentDeviceProfileIndex());
+}
+
+void QDesignerSharedSettings::setCurrentDeviceProfileIndex(int i)
+{
+ m_settings->setValue(QLatin1String(deviceProfileIndexKey), i);
+}
+
+int QDesignerSharedSettings::currentDeviceProfileIndex() const
+{
+ return m_settings->value(QLatin1String(deviceProfileIndexKey), -1).toInt();
+}
+
+static inline QString msgWarnDeviceProfileXml(const QString &msg)
+{
+ return QCoreApplication::translate("QDesignerSharedSettings", "An error has been encountered while parsing device profile XML: %1").arg(msg);
+}
+
+DeviceProfile QDesignerSharedSettings::deviceProfileAt(int idx) const
+{
+ DeviceProfile rc;
+ if (idx < 0)
+ return rc;
+ const QStringList xmls = deviceProfileXml();
+ if (idx >= xmls.size())
+ return rc;
+ QString errorMessage;
+ if (!rc.fromXml(xmls.at(idx), &errorMessage)) {
+ rc.clear();
+ designerWarning(msgWarnDeviceProfileXml(errorMessage));
+ }
+ return rc;
+}
+
+QStringList QDesignerSharedSettings::deviceProfileXml() const
+{
+ return m_settings->value(QLatin1String(deviceProfilesKey), QStringList()).toStringList();
+}
+
+QDesignerSharedSettings::DeviceProfileList QDesignerSharedSettings::deviceProfiles() const
+{
+ DeviceProfileList rc;
+ const QStringList xmls = deviceProfileXml();
+ if (xmls.empty())
+ return rc;
+ // De-serialize
+ QString errorMessage;
+ DeviceProfile dp;
+ const QStringList::const_iterator scend = xmls.constEnd();
+ for (QStringList::const_iterator it = xmls.constBegin(); it != scend; ++it) {
+ if (dp.fromXml(*it, &errorMessage)) {
+ rc.push_back(dp);
+ } else {
+ designerWarning(msgWarnDeviceProfileXml(errorMessage));
+ }
+ }
+ return rc;
+}
+
+void QDesignerSharedSettings::setDeviceProfiles(const DeviceProfileList &dp)
+{
+ QStringList l;
+ const DeviceProfileList::const_iterator dcend = dp.constEnd();
+ for (DeviceProfileList::const_iterator it = dp.constBegin(); it != dcend; ++it)
+ l.push_back(it->toXml());
+ m_settings->setValue(QLatin1String(deviceProfilesKey), l);
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/shared_settings_p.h b/src/designer/src/lib/shared/shared_settings_p.h
new file mode 100644
index 000000000..6e151ee53
--- /dev/null
+++ b/src/designer/src/lib/shared/shared_settings_p.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef SHARED_SETTINGS_H
+#define SHARED_SETTINGS_H
+
+#include "shared_global_p.h"
+#include "deviceprofile_p.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerSettingsInterface;
+
+class QStringList;
+class QSize;
+
+namespace qdesigner_internal {
+class Grid;
+class PreviewConfiguration;
+}
+
+/*!
+ Auxiliary methods to store/retrieve settings
+ */
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT QDesignerSharedSettings {
+public:
+ typedef QList<DeviceProfile> DeviceProfileList;
+
+ explicit QDesignerSharedSettings(QDesignerFormEditorInterface *core);
+
+ Grid defaultGrid() const;
+ void setDefaultGrid(const Grid &grid);
+
+ QStringList formTemplatePaths() const;
+ void setFormTemplatePaths(const QStringList &paths);
+
+ void setAdditionalFormTemplatePaths(const QStringList &additionalPaths);
+ QStringList additionalFormTemplatePaths() const;
+
+ QString formTemplate() const;
+ void setFormTemplate(const QString &t);
+
+ QSize newFormSize() const;
+ void setNewFormSize(const QSize &s);
+
+ // Check with isCustomPreviewConfigurationEnabled if custom or default
+ // configuration should be used.
+ PreviewConfiguration customPreviewConfiguration() const;
+ void setCustomPreviewConfiguration(const PreviewConfiguration &configuration);
+
+ bool isCustomPreviewConfigurationEnabled() const;
+ void setCustomPreviewConfigurationEnabled(bool enabled);
+
+ QStringList userDeviceSkins() const;
+ void setUserDeviceSkins(const QStringList &userDeviceSkins);
+
+ bool zoomEnabled() const;
+ void setZoomEnabled(bool v);
+
+ // Zoom in percent
+ int zoom() const;
+ void setZoom(int z);
+
+ // Embedded Design
+ DeviceProfile currentDeviceProfile() const;
+ void setCurrentDeviceProfileIndex(int i);
+ int currentDeviceProfileIndex() const;
+
+ DeviceProfile deviceProfileAt(int idx) const;
+ DeviceProfileList deviceProfiles() const;
+ void setDeviceProfiles(const DeviceProfileList &dp);
+
+ static const QStringList &defaultFormTemplatePaths();
+
+protected:
+ QDesignerSettingsInterface *settings() const { return m_settings; }
+
+private:
+ QStringList deviceProfileXml() const;
+ QDesignerSettingsInterface *m_settings;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SHARED_SETTINGS_H
diff --git a/src/designer/src/lib/shared/sheet_delegate.cpp b/src/designer/src/lib/shared/sheet_delegate.cpp
new file mode 100644
index 000000000..896ed5b83
--- /dev/null
+++ b/src/designer/src/lib/shared/sheet_delegate.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "sheet_delegate_p.h"
+
+#include <QtCore/QAbstractItemModel>
+#include <QtGui/QTreeView>
+#include <QtGui/QStyle>
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+SheetDelegate::SheetDelegate(QTreeView *view, QWidget *parent)
+ : QItemDelegate(parent),
+ m_view(view)
+{
+}
+
+void SheetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ const QAbstractItemModel *model = index.model();
+ Q_ASSERT(model);
+
+ if (!model->parent(index).isValid()) {
+ // this is a top-level item.
+ QStyleOptionButton buttonOption;
+
+ buttonOption.state = option.state;
+#ifdef Q_WS_MAC
+ buttonOption.state |= QStyle::State_Raised;
+#endif
+ buttonOption.state &= ~QStyle::State_HasFocus;
+
+ buttonOption.rect = option.rect;
+ buttonOption.palette = option.palette;
+ buttonOption.features = QStyleOptionButton::None;
+ m_view->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, m_view);
+
+ QStyleOption branchOption;
+ static const int i = 9; // ### hardcoded in qcommonstyle.cpp
+ QRect r = option.rect;
+ branchOption.rect = QRect(r.left() + i/2, r.top() + (r.height() - i)/2, i, i);
+ branchOption.palette = option.palette;
+ branchOption.state = QStyle::State_Children;
+
+ if (m_view->isExpanded(index))
+ branchOption.state |= QStyle::State_Open;
+
+ m_view->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, painter, m_view);
+
+ // draw text
+ QRect textrect = QRect(r.left() + i*2, r.top(), r.width() - ((5*i)/2), r.height());
+ QString text = elidedText(option.fontMetrics, textrect.width(), Qt::ElideMiddle,
+ model->data(index, Qt::DisplayRole).toString());
+ m_view->style()->drawItemText(painter, textrect, Qt::AlignCenter,
+ option.palette, m_view->isEnabled(), text);
+
+ } else {
+ QItemDelegate::paint(painter, option, index);
+ }
+}
+
+QSize SheetDelegate::sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const
+{
+ QStyleOptionViewItem option = opt;
+ QSize sz = QItemDelegate::sizeHint(opt, index) + QSize(2, 2);
+ return sz;
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/sheet_delegate_p.h b/src/designer/src/lib/shared/sheet_delegate_p.h
new file mode 100644
index 000000000..887cc6619
--- /dev/null
+++ b/src/designer/src/lib/shared/sheet_delegate_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef SHEET_DELEGATE_H
+#define SHEET_DELEGATE_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QItemDelegate>
+#include <QtGui/QTreeView>
+
+QT_BEGIN_NAMESPACE
+
+class QTreeView;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT SheetDelegate: public QItemDelegate
+{
+ Q_OBJECT
+public:
+ SheetDelegate(QTreeView *view, QWidget *parent);
+
+ virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const;
+
+private:
+ QTreeView *m_view;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // SHEET_DELEGATE_H
diff --git a/src/designer/src/lib/shared/signalslotdialog.cpp b/src/designer/src/lib/shared/signalslotdialog.cpp
new file mode 100644
index 000000000..a65aafade
--- /dev/null
+++ b/src/designer/src/lib/shared/signalslotdialog.cpp
@@ -0,0 +1,526 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "signalslotdialog_p.h"
+#include "ui_signalslotdialog.h"
+#include "metadatabase_p.h"
+#include "widgetdatabase_p.h"
+
+#include "qdesigner_formwindowcommand_p.h"
+#include "iconloader_p.h"
+
+#include <QtDesigner/QDesignerMemberSheetExtension>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <abstractdialoggui_p.h>
+
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QRegExpValidator>
+#include <QtGui/QItemDelegate>
+#include <QtGui/QLineEdit>
+#include <QtGui/QApplication>
+#include <QtGui/QMessageBox>
+
+#include <QtCore/QRegExp>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+// Regexp to match a function signature, arguments potentially
+// with namespace colons.
+static const char *signatureRegExp = "^[\\w+_]+\\(([\\w+:]\\*?,?)*\\)$";
+static const char *methodNameRegExp = "^[\\w+_]+$";
+
+static QStandardItem *createEditableItem(const QString &text)
+{
+ QStandardItem *rc = new QStandardItem(text);
+ rc->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable);
+ return rc;
+}
+
+static QStandardItem *createDisabledItem(const QString &text)
+{
+ QStandardItem *rc = new QStandardItem(text);
+ Qt::ItemFlags flags = rc->flags();
+ rc->setFlags(flags & ~(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable));
+ return rc;
+}
+
+static void fakeMethodsFromMetaDataBase(QDesignerFormEditorInterface *core, QObject *o, QStringList &slotList, QStringList &signalList)
+{
+ slotList.clear();
+ signalList.clear();
+ if (qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<qdesigner_internal::MetaDataBase *>(core->metaDataBase()))
+ if (const qdesigner_internal::MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(o)) {
+ slotList = item->fakeSlots();
+ signalList = item->fakeSignals();
+ }
+}
+
+static void fakeMethodsToMetaDataBase(QDesignerFormEditorInterface *core, QObject *o, const QStringList &slotList, const QStringList &signalList)
+{
+ if (qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<qdesigner_internal::MetaDataBase *>(core->metaDataBase())) {
+ qdesigner_internal::MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(o);
+ Q_ASSERT(item);
+ item->setFakeSlots(slotList);
+ item->setFakeSignals(signalList);
+ }
+}
+
+static void existingMethodsFromMemberSheet(QDesignerFormEditorInterface *core,
+ QObject *o,
+ QStringList &slotList, QStringList &signalList)
+{
+ slotList.clear();
+ signalList.clear();
+
+ QDesignerMemberSheetExtension *msheet = qt_extension<QDesignerMemberSheetExtension*>(core->extensionManager(), o);
+ if (!msheet)
+ return;
+
+ for (int i = 0, count = msheet->count(); i < count; ++i)
+ if (msheet->isVisible(i)) {
+ if (msheet->isSlot(i))
+ slotList += msheet->signature(i);
+ else
+ if (msheet->isSignal(i))
+ signalList += msheet->signature(i);
+ }
+}
+
+namespace {
+ // Internal helper class: A Delegate that validates using RegExps and additionally checks
+ // on closing (adds missing parentheses).
+ class SignatureDelegate : public QItemDelegate {
+ public:
+ SignatureDelegate(QObject * parent = 0);
+ virtual QWidget * createEditor (QWidget * parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
+ virtual void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+
+ private:
+ const QRegExp m_signatureRegexp;
+ const QRegExp m_methodNameRegexp;
+ };
+
+ SignatureDelegate::SignatureDelegate(QObject * parent) :
+ QItemDelegate(parent),
+ m_signatureRegexp(QLatin1String(signatureRegExp)),
+ m_methodNameRegexp(QLatin1String(methodNameRegExp))
+ {
+ Q_ASSERT(m_signatureRegexp.isValid());
+ Q_ASSERT(m_methodNameRegexp.isValid());
+ }
+
+ QWidget * SignatureDelegate::createEditor ( QWidget * parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
+ {
+ QWidget *rc = QItemDelegate::createEditor(parent, option, index);
+ QLineEdit *le = qobject_cast<QLineEdit *>(rc);
+ Q_ASSERT(le);
+ le->setValidator(new QRegExpValidator(m_signatureRegexp, le));
+ return rc;
+ }
+
+ void SignatureDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
+ {
+ QLineEdit *le = qobject_cast<QLineEdit *>(editor);
+ Q_ASSERT(le);
+ // Did the user just type a name? .. Add parentheses
+ QString signature = le->text();
+ if (!m_signatureRegexp.exactMatch(signature )) {
+ if (m_methodNameRegexp.exactMatch(signature )) {
+ signature += QLatin1String("()");
+ le->setText(signature);
+ } else {
+ return;
+ }
+ }
+ QItemDelegate::setModelData(editor, model, index);
+ }
+
+ // ------ FakeMethodMetaDBCommand: Undo Command to change fake methods in the meta DB.
+ class FakeMethodMetaDBCommand : public qdesigner_internal::QDesignerFormWindowCommand {
+
+ public:
+ explicit FakeMethodMetaDBCommand(QDesignerFormWindowInterface *formWindow);
+
+ void init(QObject *o,
+ const QStringList &oldFakeSlots, const QStringList &oldFakeSignals,
+ const QStringList &newFakeSlots, const QStringList &newFakeSignals);
+
+ virtual void undo() { fakeMethodsToMetaDataBase(core(), m_object, m_oldFakeSlots, m_oldFakeSignals); }
+ virtual void redo() { fakeMethodsToMetaDataBase(core(), m_object, m_newFakeSlots, m_newFakeSignals); }
+
+ private:
+ QObject *m_object;
+ QStringList m_oldFakeSlots;
+ QStringList m_oldFakeSignals;
+ QStringList m_newFakeSlots;
+ QStringList m_newFakeSignals;
+ };
+
+ FakeMethodMetaDBCommand::FakeMethodMetaDBCommand(QDesignerFormWindowInterface *formWindow) :
+ qdesigner_internal::QDesignerFormWindowCommand(QApplication::translate("Command", "Change signals/slots"), formWindow),
+ m_object(0)
+ {
+ }
+
+ void FakeMethodMetaDBCommand::init(QObject *o,
+ const QStringList &oldFakeSlots, const QStringList &oldFakeSignals,
+ const QStringList &newFakeSlots, const QStringList &newFakeSignals)
+ {
+ m_object = o;
+ m_oldFakeSlots = oldFakeSlots;
+ m_oldFakeSignals = oldFakeSignals;
+ m_newFakeSlots = newFakeSlots;
+ m_newFakeSignals = newFakeSignals;
+ }
+}
+
+namespace qdesigner_internal {
+
+// ------ SignalSlotDialogData
+void SignalSlotDialogData::clear()
+{
+ m_existingMethods.clear();
+ m_fakeMethods.clear();
+}
+
+// ------ SignatureModel
+SignatureModel::SignatureModel(QObject *parent) :
+ QStandardItemModel(parent)
+{
+}
+
+bool SignatureModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (role != Qt::EditRole)
+ return QStandardItemModel::setData(index, value, role);
+ // check via signal (unless it is the same), in which case we can't be bothered.
+ const QStandardItem *item = itemFromIndex(index);
+ Q_ASSERT(item);
+ const QString signature = value.toString();
+ if (item->text() == signature)
+ return true;
+
+ bool ok = true;
+ emit checkSignature(signature, &ok);
+ if (!ok)
+ return false;
+
+ return QStandardItemModel::setData(index, value, role);
+}
+
+// ------ SignaturePanel
+SignaturePanel::SignaturePanel(QObject *parent, QListView *listView, QToolButton *addButton, QToolButton *removeButton, const QString &newPrefix) :
+ QObject(parent),
+ m_newPrefix(newPrefix),
+ m_model(new SignatureModel(this)),
+ m_listView(listView),
+ m_removeButton(removeButton)
+{
+ m_removeButton->setEnabled(false);
+
+ connect(addButton, SIGNAL(clicked()), this, SLOT(slotAdd()));
+ connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemove()));
+
+ m_listView->setModel(m_model);
+ SignatureDelegate *delegate = new SignatureDelegate(this);
+ m_listView->setItemDelegate(delegate);
+ connect(m_model, SIGNAL(checkSignature(QString,bool*)), this, SIGNAL(checkSignature(QString,bool*)));
+
+ connect(m_listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
+}
+
+void SignaturePanel::slotAdd()
+{
+ m_listView->selectionModel()->clearSelection();
+ // find unique name
+ for (int i = 1; ; i++) {
+ QString newSlot = m_newPrefix;
+ newSlot += QString::number(i); // Always add number, Avoid setting 'slot' for first entry
+ newSlot += QLatin1Char('(');
+ // check for function name independent of parameters
+ if (m_model->findItems(newSlot, Qt::MatchStartsWith, 0).empty()) {
+ newSlot += QLatin1Char(')');
+ QStandardItem * item = createEditableItem(newSlot);
+ m_model->appendRow(item);
+ const QModelIndex index = m_model->indexFromItem (item);
+ m_listView->setCurrentIndex (index);
+ m_listView->edit(index);
+ return;
+ }
+ }
+}
+
+int SignaturePanel::count(const QString &signature) const
+{
+ return m_model->findItems(signature).size();
+}
+
+void SignaturePanel::slotRemove()
+{
+ const QModelIndexList selectedIndexes = m_listView->selectionModel()->selectedIndexes ();
+ if (selectedIndexes.empty())
+ return;
+
+ closeEditor();
+ // scroll to previous
+ if (const int row = selectedIndexes.front().row())
+ m_listView->setCurrentIndex (selectedIndexes.front().sibling(row - 1, 0));
+
+ for (int i = selectedIndexes.size() - 1; i >= 0; i--)
+ qDeleteAll(m_model->takeRow(selectedIndexes[i].row()));
+}
+
+void SignaturePanel::slotSelectionChanged(const QItemSelection &selected, const QItemSelection &)
+{
+ m_removeButton->setEnabled(!selected.indexes().empty());
+}
+
+void SignaturePanel::setData(const SignalSlotDialogData &d)
+{
+ m_model->clear();
+
+ QStandardItem *lastExisting = 0;
+ foreach(const QString &s, d.m_existingMethods) {
+ lastExisting = createDisabledItem(s);
+ m_model->appendRow(lastExisting);
+ }
+ foreach(const QString &s, d.m_fakeMethods)
+ m_model->appendRow(createEditableItem(s));
+ if (lastExisting)
+ m_listView->scrollTo(m_model->indexFromItem(lastExisting));
+}
+
+QStringList SignaturePanel::fakeMethods() const
+{
+ QStringList rc;
+ if (const int rowCount = m_model->rowCount())
+ for (int i = 0; i < rowCount; i++) {
+ const QStandardItem *item = m_model->item(i);
+ if (item->flags() & Qt::ItemIsEditable)
+ rc += item->text();
+ }
+ return rc;
+}
+
+void SignaturePanel::closeEditor()
+{
+ const QModelIndex idx = m_listView->currentIndex();
+ if (idx.isValid())
+ m_listView->closePersistentEditor(idx);
+}
+
+// ------ SignalSlotDialog
+
+SignalSlotDialog::SignalSlotDialog(QDesignerDialogGuiInterface *dialogGui, QWidget *parent, FocusMode mode) :
+ QDialog(parent),
+ m_focusMode(mode),
+ m_ui(new Ui::SignalSlotDialogClass),
+ m_dialogGui(dialogGui)
+{
+ setModal(true);
+ m_ui->setupUi(this);
+
+ const QIcon plusIcon = qdesigner_internal::createIconSet(QString::fromUtf8("plus.png"));
+ const QIcon minusIcon = qdesigner_internal::createIconSet(QString::fromUtf8("minus.png"));
+ m_ui->addSlotButton->setIcon(plusIcon);
+ m_ui->removeSlotButton->setIcon(minusIcon);
+ m_ui->addSignalButton->setIcon(plusIcon);
+ m_ui->removeSignalButton->setIcon(minusIcon);
+
+ m_slotPanel = new SignaturePanel(this, m_ui->slotListView, m_ui->addSlotButton, m_ui->removeSlotButton, QLatin1String("slot"));
+ m_signalPanel = new SignaturePanel(this, m_ui->signalListView, m_ui->addSignalButton, m_ui->removeSignalButton, QLatin1String("signal"));
+ connect(m_slotPanel, SIGNAL(checkSignature(QString,bool*)), this, SLOT(slotCheckSignature(QString,bool*)));
+ connect(m_signalPanel, SIGNAL(checkSignature(QString,bool*)), this, SLOT(slotCheckSignature(QString,bool*)));
+
+ connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ switch(m_focusMode) {
+ case FocusSlots:
+ m_ui->slotListView->setFocus(Qt::OtherFocusReason);
+ break;
+ case FocusSignals:
+ m_ui->signalListView->setFocus(Qt::OtherFocusReason);
+ break;
+ }
+}
+
+SignalSlotDialog::~SignalSlotDialog()
+{
+ delete m_ui;
+}
+
+void SignalSlotDialog::slotCheckSignature(const QString &signature, bool *ok)
+{
+ QString errorMessage;
+ do {
+ if (m_slotPanel->count(signature)) {
+ errorMessage = tr("There is already a slot with the signature '%1'.").arg(signature);
+ *ok = false;
+ break;
+ }
+ if (m_signalPanel->count(signature)) {
+ errorMessage = tr("There is already a signal with the signature '%1'.").arg(signature);
+ *ok = false;
+ break;
+ }
+ } while (false);
+ if (!*ok)
+ m_dialogGui->message(this, QDesignerDialogGuiInterface::SignalSlotDialogMessage,
+ QMessageBox::Warning, tr("%1 - Duplicate Signature").arg(windowTitle()), errorMessage, QMessageBox::Close);
+}
+
+QDialog::DialogCode SignalSlotDialog::showDialog(SignalSlotDialogData &slotData, SignalSlotDialogData &signalData)
+{
+ m_slotPanel->setData(slotData);
+ m_signalPanel->setData(signalData);
+
+ const DialogCode rc = static_cast<DialogCode>(exec());
+ if (rc == Rejected)
+ return rc;
+
+ slotData.m_fakeMethods = m_slotPanel->fakeMethods();
+ signalData.m_fakeMethods = m_signalPanel->fakeMethods();
+ return rc;
+}
+
+bool SignalSlotDialog::editMetaDataBase(QDesignerFormWindowInterface *fw, QObject *object, QWidget *parent, FocusMode mode)
+{
+ QDesignerFormEditorInterface *core = fw->core();
+ SignalSlotDialog dlg(core->dialogGui(), parent, mode);
+ dlg.setWindowTitle(tr("Signals/Slots of %1").arg(object->objectName()));
+
+ SignalSlotDialogData slotData;
+ SignalSlotDialogData signalData;
+
+ existingMethodsFromMemberSheet(core, object, slotData.m_existingMethods, signalData.m_existingMethods);
+ fakeMethodsFromMetaDataBase(core, object, slotData.m_fakeMethods, signalData.m_fakeMethods);
+
+ const QStringList oldSlots = slotData.m_fakeMethods;
+ const QStringList oldSignals = signalData.m_fakeMethods;
+
+ if (dlg.showDialog(slotData, signalData) == QDialog::Rejected)
+ return false;
+
+ if (oldSlots == slotData.m_fakeMethods && oldSignals == signalData.m_fakeMethods)
+ return false;
+
+ FakeMethodMetaDBCommand *cmd = new FakeMethodMetaDBCommand(fw);
+ cmd->init(object, oldSlots, oldSignals, slotData.m_fakeMethods, signalData.m_fakeMethods);
+ fw->commandHistory()->push(cmd);
+ return true;
+}
+
+bool SignalSlotDialog::editPromotedClass(QDesignerFormEditorInterface *core, const QString &promotedClassName, QWidget *parent, FocusMode mode)
+{
+ const int index = core->widgetDataBase()->indexOfClassName(promotedClassName);
+ if (index == -1)
+ return false;
+
+ const QString baseClassName = core->widgetDataBase()->item(index)->extends();
+ if (baseClassName.isEmpty())
+ return false;
+
+ QWidget *widget = core->widgetFactory()->createWidget(baseClassName, 0);
+ if (!widget)
+ return false;
+ const bool rc = editPromotedClass(core, promotedClassName, widget, parent, mode);
+ widget->deleteLater();
+ return rc;
+}
+
+bool SignalSlotDialog::editPromotedClass(QDesignerFormEditorInterface *core, QObject *baseObject, QWidget *parent, FocusMode mode)
+{
+ if (!baseObject->isWidgetType())
+ return false;
+
+ const QString promotedClassName = promotedCustomClassName(core, qobject_cast<QWidget*>(baseObject));
+ if (promotedClassName.isEmpty())
+ return false;
+ return editPromotedClass(core, promotedClassName, baseObject, parent, mode);
+}
+
+
+bool SignalSlotDialog::editPromotedClass(QDesignerFormEditorInterface *core, const QString &promotedClassName, QObject *object, QWidget *parent, FocusMode mode)
+{
+ WidgetDataBase *db = qobject_cast<WidgetDataBase *>(core->widgetDataBase());
+ if (!db)
+ return false;
+
+ const int index = core->widgetDataBase()->indexOfClassName(promotedClassName);
+ if (index == -1)
+ return false;
+
+ WidgetDataBaseItem* item = static_cast<WidgetDataBaseItem*>(db->item(index));
+
+ SignalSlotDialogData slotData;
+ SignalSlotDialogData signalData;
+
+ existingMethodsFromMemberSheet(core, object, slotData.m_existingMethods, signalData.m_existingMethods);
+ slotData.m_fakeMethods = item->fakeSlots();
+ signalData.m_fakeMethods = item->fakeSignals();
+
+ const QStringList oldSlots = slotData.m_fakeMethods;
+ const QStringList oldSignals = signalData.m_fakeMethods;
+
+ SignalSlotDialog dlg(core->dialogGui(), parent, mode);
+ dlg.setWindowTitle(tr("Signals/Slots of %1").arg(promotedClassName));
+
+ if (dlg.showDialog(slotData, signalData) == QDialog::Rejected)
+ return false;
+
+ if (oldSlots == slotData.m_fakeMethods && oldSignals == signalData.m_fakeMethods)
+ return false;
+
+ item->setFakeSlots(slotData.m_fakeMethods);
+ item->setFakeSignals(signalData.m_fakeMethods);
+
+ return true;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/signalslotdialog.ui b/src/designer/src/lib/shared/signalslotdialog.ui
new file mode 100644
index 000000000..1a8a8d921
--- /dev/null
+++ b/src/designer/src/lib/shared/signalslotdialog.ui
@@ -0,0 +1,129 @@
+<ui version="4.0" >
+ <class>SignalSlotDialogClass</class>
+ <widget class="QDialog" name="SignalSlotDialogClass" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>617</width>
+ <height>535</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Signals and slots</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QGroupBox" name="slotGroupBox" >
+ <property name="title" >
+ <string>Slots</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QListView" name="slotListView" />
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QToolButton" name="addSlotButton" >
+ <property name="toolTip" >
+ <string>Add</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeSlotButton" >
+ <property name="toolTip" >
+ <string>Delete</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="signalGroupBox" >
+ <property name="title" >
+ <string>Signals</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QListView" name="signalListView" />
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QToolButton" name="addSignalButton" >
+ <property name="toolTip" >
+ <string>Add</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeSignalButton" >
+ <property name="toolTip" >
+ <string>Delete</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="spacerName" stdset="0" >
+ <string/>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/lib/shared/signalslotdialog_p.h b/src/designer/src/lib/shared/signalslotdialog_p.h
new file mode 100644
index 000000000..1bfeecece
--- /dev/null
+++ b/src/designer/src/lib/shared/signalslotdialog_p.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef _SIGNALSLOTDIALOG_H
+#define _SIGNALSLOTDIALOG_H
+
+#include "shared_global_p.h"
+#include <QtCore/QStringList>
+#include <QtGui/QDialog>
+#include <QtGui/QStandardItemModel>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QDesignerDialogGuiInterface;
+class QDesignerMemberSheet;
+class QListView;
+class QToolButton;
+class QItemSelection;
+
+namespace Ui {
+ class SignalSlotDialogClass;
+}
+
+namespace qdesigner_internal {
+
+// Dialog data
+struct SignalSlotDialogData {
+ void clear();
+ QStringList m_existingMethods;
+ QStringList m_fakeMethods;
+};
+
+// Internal helper class: A model for signatures that allows for verifying duplicates
+// (checking signals versus slots and vice versa).
+class SignatureModel : public QStandardItemModel {
+ Q_OBJECT
+
+public:
+ SignatureModel(QObject *parent = 0);
+ virtual bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+signals:
+ void checkSignature(const QString &signature, bool *ok);
+};
+
+// Internal helper class: Panel for editing method signatures. List view with validator,
+// add and remove button
+class SignaturePanel : public QObject {
+ Q_OBJECT
+
+public:
+ SignaturePanel(QObject *parent, QListView *listView, QToolButton *addButton, QToolButton *removeButton, const QString &newPrefix);
+
+ QStringList fakeMethods() const;
+ void setData(const SignalSlotDialogData &d);
+ int count(const QString &signature) const;
+
+signals:
+ void checkSignature(const QString &signature, bool *ok);
+
+private slots:
+ void slotAdd();
+ void slotRemove();
+ void slotSelectionChanged(const QItemSelection &, const QItemSelection &);
+
+private:
+ void closeEditor();
+
+ const QString m_newPrefix;
+ SignatureModel *m_model;
+ QListView *m_listView;
+ QToolButton *m_removeButton;
+};
+
+// Dialog for editing signals and slots.
+// Provides static convenience function
+// to modify fake signals and slots. They are
+// handled in 2 ways:
+// 1) For the MainContainer: Fake signals and slots are stored
+// in the meta database (per-instance)
+// 2) For promoted widgets: Fake signals and slots are stored
+// in the widget database (per-class)
+// Arguably, we could require the MainContainer to be promoted for that, too,
+// but that would require entering a header.
+
+class QDESIGNER_SHARED_EXPORT SignalSlotDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ enum FocusMode { FocusSlots, FocusSignals };
+
+ explicit SignalSlotDialog(QDesignerDialogGuiInterface *dialogGui, QWidget *parent = 0, FocusMode m = FocusSlots);
+ virtual ~SignalSlotDialog();
+
+ DialogCode showDialog(SignalSlotDialogData &slotData, SignalSlotDialogData &signalData);
+
+ // Edit fake methods stored in MetaDataBase (per instance, used for main containers)
+ static bool editMetaDataBase(QDesignerFormWindowInterface *fw, QObject *object, QWidget *parent = 0, FocusMode m = FocusSlots);
+
+ // Edit fake methods of a promoted class stored in WidgetDataBase (synthesizes a widget to obtain existing members).
+ static bool editPromotedClass(QDesignerFormEditorInterface *core, const QString &promotedClassName, QWidget *parent = 0, FocusMode m = FocusSlots);
+ // Edit fake methods of a promoted class stored in WidgetDataBase on a base class instance.
+ static bool editPromotedClass(QDesignerFormEditorInterface *core, QObject *baseObject, QWidget *parent = 0, FocusMode m = FocusSlots);
+
+private slots:
+ void slotCheckSignature(const QString &signature, bool *ok);
+
+private:
+ // Edit fake methods of a promoted class stored in WidgetDataBase using an instance of the base class.
+ static bool editPromotedClass(QDesignerFormEditorInterface *core, const QString &promotedClassName, QObject *baseObject, QWidget *parent, FocusMode m);
+
+ const FocusMode m_focusMode;
+ Ui::SignalSlotDialogClass *m_ui;
+ QDesignerDialogGuiInterface *m_dialogGui;
+ SignaturePanel *m_slotPanel;
+ SignaturePanel *m_signalPanel;
+};
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/lib/shared/spacer_widget.cpp b/src/designer/src/lib/shared/spacer_widget.cpp
new file mode 100644
index 000000000..528a4f427
--- /dev/null
+++ b/src/designer/src/lib/shared/spacer_widget.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "spacer_widget_p.h"
+#include "layoutinfo_p.h"
+
+#include <QtDesigner/abstractformwindow.h>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QLayout>
+#include <QtGui/QPainter>
+#include <QtGui/qevent.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+// The Spacer widget is Designer representation of QLayoutItem.
+// It uses QLayoutItem's sizeHint property as QWidget
+// sizeHint and the QLayoutItem's sizeType property as QWidget size policy.
+// If it is not within a layout, it adds a margin (m_SizeOffset) around it
+// to avoid being shrunk to an invisible state when the sizeHint is reset to 0,0
+// and enables sizeHandle-resizing. In a layout, however, this m_SizeOffset
+// should not be applied for pixel-exact design.
+
+Spacer::Spacer(QWidget *parent) :
+ QWidget(parent),
+ m_SizeOffset(3, 3), // A small offset to ensure the spacer is still visible when reset to size 0,0
+ m_orientation(Qt::Vertical),
+ m_interactive(true),
+ m_layoutState(UnknownLayoutState),
+ m_sizeHint(0, 0)
+{
+ setAttribute(Qt::WA_MouseNoMask);
+ m_formWindow = QDesignerFormWindowInterface::findFormWindow(this);
+ setSizeType(QSizePolicy::Expanding);
+}
+
+bool Spacer::event(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::ToolTip:
+ updateToolTip(); // Tooltip includes size, so, refresh on demand
+ break;
+ case QEvent::ParentChange: // Cache information about 'being in layout' which is expensive to calculate.
+ m_layoutState = UnknownLayoutState;
+ break;
+ default:
+ break;
+ }
+ return QWidget::event(e);
+}
+
+bool Spacer::isInLayout() const
+{
+ if (m_layoutState == UnknownLayoutState) {
+ m_layoutState = OutsideLayout;
+ if (m_formWindow)
+ if (const QWidget *parent = parentWidget())
+ if (qdesigner_internal::LayoutInfo::managedLayoutType(m_formWindow->core(), parent) != qdesigner_internal::LayoutInfo::NoLayout)
+ m_layoutState = InLayout;
+ }
+ return m_layoutState == InLayout;
+}
+
+void Spacer::paintEvent(QPaintEvent *)
+{
+ // Only draw spacers when we're editting widgets
+ if (m_formWindow != 0 && m_formWindow->currentTool() != 0)
+ return;
+
+ QPainter p(this);
+ p.setPen(Qt::blue);
+ const int w = width();
+ const int h = height();
+ if (w * h == 0)
+ return;
+
+ if (w <= m_SizeOffset.width() || h <= m_SizeOffset.height()) {
+ const int lw = w - 1;
+ const int lh = h - 1;
+ switch (m_orientation) {
+ case Qt::Horizontal:
+ p.drawLine(0, 0, 0, lh);
+ p.drawLine(lw, 0, lw, lh);
+ break;
+ case Qt::Vertical:
+ p.drawLine(0, 0, lw, 0);
+ p.drawLine(0, lh, lw, lh);
+ break;
+ }
+ return;
+ }
+ if (m_orientation == Qt::Horizontal) {
+ const int dist = 3;
+ const int amplitude = qMin(3, h / 3);
+ const int base = h / 2;
+ int i = 0;
+ p.setPen(Qt::white);
+ for (i = 0; i < w / 3 +2; ++i)
+ p.drawLine(i * dist, base - amplitude, i * dist + dist / 2, base + amplitude);
+ p.setPen(Qt::blue);
+ for (i = 0; i < w / 3 +2; ++i)
+ p.drawLine(i * dist + dist / 2, base + amplitude, i * dist + dist, base - amplitude);
+ const int y = h/2;
+ p.drawLine(0, y-10, 0, y+10);
+ p.drawLine(w - 1, y-10, w - 1, y+10);
+ } else {
+ const int dist = 3;
+ const int amplitude = qMin(3, w / 3);
+ const int base = w / 2;
+ int i = 0;
+ p.setPen(Qt::white);
+ for (i = 0; i < h / 3 +2; ++i)
+ p.drawLine(base - amplitude, i * dist, base + amplitude,i * dist + dist / 2);
+ p.setPen(Qt::blue);
+ for (i = 0; i < h / 3 +2; ++i)
+ p.drawLine(base + amplitude, i * dist + dist / 2, base - amplitude, i * dist + dist);
+ const int x = w/2;
+ p.drawLine(x-10, 0, x+10, 0);
+ p.drawLine(x-10, h - 1, x+10, h - 1);
+ }
+}
+
+void Spacer::resizeEvent(QResizeEvent* e)
+{
+ QWidget::resizeEvent(e);
+ // When resized by widget handle dragging after a reset (QSize(0, 0)):
+ // Mark the property as changed (geometry and sizeHint are in sync except for 'changed').
+ if (m_formWindow) {
+ const QSize oldSize = e->oldSize();
+ if (oldSize.isNull() || oldSize.width() <= m_SizeOffset.width() || oldSize.height() <= m_SizeOffset.height())
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_formWindow->core()->extensionManager(), this))
+ sheet->setChanged(sheet->indexOf(QLatin1String("sizeHint")), true);
+ }
+
+ updateMask();
+
+ if (!m_interactive)
+ return;
+
+ if (!isInLayout()) { // Allow size-handle resize only if not in layout
+ const QSize currentSize = size();
+ if (currentSize.width() >= m_SizeOffset.width() && currentSize.height() >= m_SizeOffset.height())
+ m_sizeHint = currentSize - m_SizeOffset;
+ }
+}
+
+void Spacer::updateMask()
+{
+ QRegion r(rect());
+ const int w = width();
+ const int h = height();
+ if (w > 1 && h > 1) {
+ if (m_orientation == Qt::Horizontal) {
+ const int amplitude = qMin(3, h / 3);
+ const int base = h / 2;
+ r = r.subtract(QRect(1, 0, w - 2, base - amplitude));
+ r = r.subtract(QRect(1, base + amplitude, w - 2, h - base - amplitude));
+ } else {
+ const int amplitude = qMin(3, w / 3);
+ const int base = w / 2;
+ r = r.subtract(QRect(0, 1, base - amplitude, h - 2));
+ r = r.subtract(QRect(base + amplitude, 1, w - base - amplitude, h - 2));
+ }
+ }
+ setMask(r);
+}
+
+void Spacer::setSizeType(QSizePolicy::Policy t)
+{
+ const QSizePolicy sizeP = m_orientation == Qt::Vertical ? QSizePolicy(QSizePolicy::Minimum, t) : QSizePolicy(t, QSizePolicy::Minimum);
+ setSizePolicy(sizeP);
+}
+
+
+QSizePolicy::Policy Spacer::sizeType() const
+{
+ return m_orientation == Qt::Vertical ? sizePolicy().verticalPolicy() : sizePolicy().horizontalPolicy();
+}
+
+Qt::Alignment Spacer::alignment() const
+{
+ // For grid layouts
+ return m_orientation == Qt::Vertical ? Qt::AlignHCenter : Qt::AlignVCenter;
+}
+
+QSize Spacer::sizeHint() const
+{
+ return isInLayout() ? m_sizeHint : m_sizeHint + m_SizeOffset;
+}
+
+QSize Spacer::sizeHintProperty() const
+{
+ return m_sizeHint;
+}
+
+void Spacer::setSizeHintProperty(const QSize &s)
+{
+ m_sizeHint = s;
+
+ if (!isInLayout()) // Visible resize only if not in layout
+ resize(s + m_SizeOffset);
+
+ updateGeometry();
+}
+
+Qt::Orientation Spacer::orientation() const
+{
+ return m_orientation;
+}
+
+void Spacer::setOrientation(Qt::Orientation o)
+{
+ if (m_orientation == o)
+ return;
+
+ const QSizePolicy::Policy st = sizeType(); // flip size type
+ m_orientation = o;
+ setSizeType(st);
+
+ if (m_interactive) {
+ m_sizeHint = QSize(m_sizeHint.height(), m_sizeHint.width());
+ if (!isInLayout())
+ resize(m_sizeHint + m_SizeOffset);
+ }
+
+ updateMask();
+ update();
+ updateGeometry();
+}
+
+void Spacer::updateToolTip()
+{
+ const QString format = m_orientation == Qt::Horizontal ? tr("Horizontal Spacer '%1', %2 x %3") : tr("Vertical Spacer '%1', %2 x %3");
+ QString msg = format.arg(objectName()).arg(m_sizeHint.width()).arg(m_sizeHint.height());
+ setToolTip(msg);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/spacer_widget_p.h b/src/designer/src/lib/shared/spacer_widget_p.h
new file mode 100644
index 000000000..dd9288d24
--- /dev/null
+++ b/src/designer/src/lib/shared/spacer_widget_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef SPACER_WIDGET_H
+#define SPACER_WIDGET_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QWidget>
+#include <QtGui/QSizePolicy>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+
+class QDESIGNER_SHARED_EXPORT Spacer: public QWidget
+{
+ Q_OBJECT
+
+ Q_ENUMS(SizeType)
+ // Special hack: Make name appear as "spacer name"
+ Q_PROPERTY(QString spacerName READ objectName WRITE setObjectName)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_PROPERTY(QSizePolicy::Policy sizeType READ sizeType WRITE setSizeType)
+ Q_PROPERTY(QSize sizeHint READ sizeHintProperty WRITE setSizeHintProperty DESIGNABLE true STORED true)
+
+public:
+ Spacer(QWidget *parent = 0);
+
+ QSize sizeHint() const;
+
+ QSize sizeHintProperty() const;
+ void setSizeHintProperty(const QSize &s);
+
+ QSizePolicy::Policy sizeType() const;
+ void setSizeType(QSizePolicy::Policy t);
+
+ Qt::Alignment alignment() const;
+ Qt::Orientation orientation() const;
+
+ void setOrientation(Qt::Orientation o);
+ void setInteractiveMode(bool b) { m_interactive = b; };
+
+ virtual bool event(QEvent *e);
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void resizeEvent(QResizeEvent* e);
+ void updateMask();
+
+private:
+ bool isInLayout() const;
+ void updateToolTip();
+
+ const QSize m_SizeOffset;
+ QDesignerFormWindowInterface *m_formWindow;
+ Qt::Orientation m_orientation;
+ bool m_interactive;
+ // Cache information about 'being in layout' which is expensive to calculate.
+ enum LayoutState { InLayout, OutsideLayout, UnknownLayoutState };
+ mutable LayoutState m_layoutState;
+ QSize m_sizeHint;
+};
+
+QT_END_NAMESPACE
+
+#endif // SPACER_WIDGET_H
diff --git a/src/designer/src/lib/shared/stylesheeteditor.cpp b/src/designer/src/lib/shared/stylesheeteditor.cpp
new file mode 100644
index 000000000..ee5fea41e
--- /dev/null
+++ b/src/designer/src/lib/shared/stylesheeteditor.cpp
@@ -0,0 +1,409 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "stylesheeteditor_p.h"
+#include "csshighlighter_p.h"
+#include "iconselector_p.h"
+#include "qtgradientmanager.h"
+#include "qtgradientviewdialog.h"
+#include "qtgradientutils.h"
+#include "qdesigner_integration_p.h"
+#include "qdesigner_utils_p.h"
+#include "abstractsettings_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QSignalMapper>
+#include <QtGui/QAction>
+#include <QtGui/QColorDialog>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QFontDialog>
+#include <QtGui/QMenu>
+#include <QtGui/QPushButton>
+#include <QtGui/QTextDocument>
+#include <QtGui/QToolBar>
+#include <QtGui/QVBoxLayout>
+#include "private/qcssparser_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static const char *styleSheetProperty = "styleSheet";
+static const char *StyleSheetDialogC = "StyleSheetDialog";
+static const char *Geometry = "Geometry";
+
+namespace qdesigner_internal {
+
+StyleSheetEditor::StyleSheetEditor(QWidget *parent)
+ : QTextEdit(parent)
+{
+ setTabStopWidth(fontMetrics().width(QLatin1Char(' '))*4);
+ setAcceptRichText(false);
+ new CssHighlighter(document());
+}
+
+// --- StyleSheetEditorDialog
+StyleSheetEditorDialog::StyleSheetEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent, Mode mode):
+ QDialog(parent),
+ m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::Help)),
+ m_editor(new StyleSheetEditor),
+ m_validityLabel(new QLabel(tr("Valid Style Sheet"))),
+ m_core(core),
+ m_addResourceAction(new QAction(tr("Add Resource..."), this)),
+ m_addGradientAction(new QAction(tr("Add Gradient..."), this)),
+ m_addColorAction(new QAction(tr("Add Color..."), this)),
+ m_addFontAction(new QAction(tr("Add Font..."), this))
+{
+ setWindowTitle(tr("Edit Style Sheet"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(m_buttonBox, SIGNAL(helpRequested()), this, SLOT(slotRequestHelp()));
+ m_buttonBox->button(QDialogButtonBox::Help)->setShortcut(QKeySequence::HelpContents);
+
+ connect(m_editor, SIGNAL(textChanged()), this, SLOT(validateStyleSheet()));
+
+ QToolBar *toolBar = new QToolBar;
+
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(toolBar, 0, 0, 1, 2);
+ layout->addWidget(m_editor, 1, 0, 1, 2);
+ layout->addWidget(m_validityLabel, 2, 0, 1, 1);
+ layout->addWidget(m_buttonBox, 2, 1, 1, 1);
+ setLayout(layout);
+
+ m_editor->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(m_editor, SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(slotContextMenuRequested(QPoint)));
+
+ QSignalMapper *resourceActionMapper = new QSignalMapper(this);
+ QSignalMapper *gradientActionMapper = new QSignalMapper(this);
+ QSignalMapper *colorActionMapper = new QSignalMapper(this);
+
+ resourceActionMapper->setMapping(m_addResourceAction, QString());
+ gradientActionMapper->setMapping(m_addGradientAction, QString());
+ colorActionMapper->setMapping(m_addColorAction, QString());
+
+ connect(m_addResourceAction, SIGNAL(triggered()), resourceActionMapper, SLOT(map()));
+ connect(m_addGradientAction, SIGNAL(triggered()), gradientActionMapper, SLOT(map()));
+ connect(m_addColorAction, SIGNAL(triggered()), colorActionMapper, SLOT(map()));
+ connect(m_addFontAction, SIGNAL(triggered()), this, SLOT(slotAddFont()));
+
+ m_addResourceAction->setEnabled(mode == ModePerForm);
+
+ const char * const resourceProperties[] = {
+ "background-image",
+ "border-image",
+ "image",
+ 0
+ };
+
+ const char * const colorProperties[] = {
+ "color",
+ "background-color",
+ "alternate-background-color",
+ "border-color",
+ "border-top-color",
+ "border-right-color",
+ "border-bottom-color",
+ "border-left-color",
+ "gridline-color",
+ "selection-color",
+ "selection-background-color",
+ 0
+ };
+
+ QMenu *resourceActionMenu = new QMenu(this);
+ QMenu *gradientActionMenu = new QMenu(this);
+ QMenu *colorActionMenu = new QMenu(this);
+
+ for (int resourceProperty = 0; resourceProperties[resourceProperty]; ++resourceProperty) {
+ QAction *action = resourceActionMenu->addAction(QLatin1String(resourceProperties[resourceProperty]));
+ connect(action, SIGNAL(triggered()), resourceActionMapper, SLOT(map()));
+ resourceActionMapper->setMapping(action, QLatin1String(resourceProperties[resourceProperty]));
+ }
+
+ for (int colorProperty = 0; colorProperties[colorProperty]; ++colorProperty) {
+ QAction *gradientAction = gradientActionMenu->addAction(QLatin1String(colorProperties[colorProperty]));
+ QAction *colorAction = colorActionMenu->addAction(QLatin1String(colorProperties[colorProperty]));
+ connect(gradientAction, SIGNAL(triggered()), gradientActionMapper, SLOT(map()));
+ connect(colorAction, SIGNAL(triggered()), colorActionMapper, SLOT(map()));
+ gradientActionMapper->setMapping(gradientAction, QLatin1String(colorProperties[colorProperty]));
+ colorActionMapper->setMapping(colorAction, QLatin1String(colorProperties[colorProperty]));
+ }
+
+ connect(resourceActionMapper, SIGNAL(mapped(QString)), this, SLOT(slotAddResource(QString)));
+ connect(gradientActionMapper, SIGNAL(mapped(QString)), this, SLOT(slotAddGradient(QString)));
+ connect(colorActionMapper, SIGNAL(mapped(QString)), this, SLOT(slotAddColor(QString)));
+
+ m_addResourceAction->setMenu(resourceActionMenu);
+ m_addGradientAction->setMenu(gradientActionMenu);
+ m_addColorAction->setMenu(colorActionMenu);
+
+ toolBar->addAction(m_addResourceAction);
+ toolBar->addAction(m_addGradientAction);
+ toolBar->addAction(m_addColorAction);
+ toolBar->addAction(m_addFontAction);
+
+ m_editor->setFocus();
+
+ QDesignerSettingsInterface *settings = core->settingsManager();
+ settings->beginGroup(QLatin1String(StyleSheetDialogC));
+
+ if (settings->contains(QLatin1String(Geometry)))
+ restoreGeometry(settings->value(QLatin1String(Geometry)).toByteArray());
+
+ settings->endGroup();
+}
+
+StyleSheetEditorDialog::~StyleSheetEditorDialog()
+{
+ QDesignerSettingsInterface *settings = m_core->settingsManager();
+ settings->beginGroup(QLatin1String(StyleSheetDialogC));
+
+ settings->setValue(QLatin1String(Geometry), saveGeometry());
+ settings->endGroup();
+}
+
+void StyleSheetEditorDialog::setOkButtonEnabled(bool v)
+{
+ m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(v);
+ if (QPushButton *applyButton = m_buttonBox->button(QDialogButtonBox::Apply))
+ applyButton->setEnabled(v);
+}
+
+void StyleSheetEditorDialog::slotContextMenuRequested(const QPoint &pos)
+{
+ QMenu *menu = m_editor->createStandardContextMenu();
+ menu->addSeparator();
+ menu->addAction(m_addResourceAction);
+ menu->addAction(m_addGradientAction);
+ menu->exec(mapToGlobal(pos));
+ delete menu;
+}
+
+void StyleSheetEditorDialog::slotAddResource(const QString &property)
+{
+ const QString path = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), QString(), this);
+ if (!path.isEmpty())
+ insertCssProperty(property, QString(QLatin1String("url(%1)")).arg(path));
+}
+
+void StyleSheetEditorDialog::slotAddGradient(const QString &property)
+{
+ bool ok;
+ const QGradient grad = QtGradientViewDialog::getGradient(&ok, m_core->gradientManager(), this);
+ if (ok)
+ insertCssProperty(property, QtGradientUtils::styleSheetCode(grad));
+}
+
+void StyleSheetEditorDialog::slotAddColor(const QString &property)
+{
+ const QColor color = QColorDialog::getColor(0xffffffff, this, QString(), QColorDialog::ShowAlphaChannel);
+ if (!color.isValid())
+ return;
+
+ QString colorStr;
+
+ if (color.alpha() == 255) {
+ colorStr = QString(QLatin1String("rgb(%1, %2, %3)")).arg(
+ color.red()).arg(color.green()).arg(color.blue());
+ } else {
+ colorStr = QString(QLatin1String("rgba(%1, %2, %3, %4)")).arg(
+ color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha());
+ }
+
+ insertCssProperty(property, colorStr);
+}
+
+void StyleSheetEditorDialog::slotAddFont()
+{
+ bool ok;
+ QFont font = QFontDialog::getFont(&ok, this);
+ if (ok) {
+ QString fontStr;
+ if (font.weight() != QFont::Normal) {
+ fontStr += QString::number(font.weight());
+ fontStr += QLatin1Char(' ');
+ }
+
+ switch (font.style()) {
+ case QFont::StyleItalic:
+ fontStr += QLatin1String("italic ");
+ break;
+ case QFont::StyleOblique:
+ fontStr += QLatin1String("oblique ");
+ break;
+ default:
+ break;
+ }
+ fontStr += QString::number(font.pointSize());
+ fontStr += QLatin1String("pt \"");
+ fontStr += font.family();
+ fontStr += QLatin1Char('"');
+
+ insertCssProperty(QLatin1String("font"), fontStr);
+ QString decoration;
+ if (font.underline())
+ decoration += QLatin1String("underline");
+ if (font.strikeOut()) {
+ if (!decoration.isEmpty())
+ decoration += QLatin1Char(' ');
+ decoration += QLatin1String("line-through");
+ }
+ insertCssProperty(QLatin1String("text-decoration"), decoration);
+ }
+}
+
+void StyleSheetEditorDialog::insertCssProperty(const QString &name, const QString &value)
+{
+ if (!value.isEmpty()) {
+ QTextCursor cursor = m_editor->textCursor();
+ if (!name.isEmpty()) {
+ cursor.beginEditBlock();
+ cursor.removeSelectedText();
+ cursor.movePosition(QTextCursor::EndOfLine);
+
+ // Simple check to see if we're in a selector scope
+ const QTextDocument *doc = m_editor->document();
+ const QTextCursor closing = doc->find(QLatin1String("}"), cursor, QTextDocument::FindBackward);
+ const QTextCursor opening = doc->find(QLatin1String("{"), cursor, QTextDocument::FindBackward);
+ const bool inSelector = !opening.isNull() && (closing.isNull() ||
+ closing.position() < opening.position());
+ QString insertion;
+ if (m_editor->textCursor().block().length() != 1)
+ insertion += QLatin1Char('\n');
+ if (inSelector)
+ insertion += QLatin1Char('\t');
+ insertion += name;
+ insertion += QLatin1String(": ");
+ insertion += value;
+ insertion += QLatin1Char(';');
+ cursor.insertText(insertion);
+ cursor.endEditBlock();
+ } else {
+ cursor.insertText(value);
+ }
+ }
+}
+
+void StyleSheetEditorDialog::slotRequestHelp()
+{
+ QDesignerIntegration::requestHelp(m_core, QLatin1String("qt"),
+ QLatin1String("stylesheet-reference.html"));
+}
+
+QDialogButtonBox * StyleSheetEditorDialog::buttonBox() const
+{
+ return m_buttonBox;
+}
+
+QString StyleSheetEditorDialog::text() const
+{
+ return m_editor->toPlainText();
+}
+
+void StyleSheetEditorDialog::setText(const QString &t)
+{
+ m_editor->setText(t);
+}
+
+bool StyleSheetEditorDialog::isStyleSheetValid(const QString &styleSheet)
+{
+ QCss::Parser parser(styleSheet);
+ QCss::StyleSheet sheet;
+ if (parser.parse(&sheet))
+ return true;
+ QString fullSheet = QLatin1String("* { ");
+ fullSheet += styleSheet;
+ fullSheet += QLatin1Char('}');
+ QCss::Parser parser2(fullSheet);
+ return parser2.parse(&sheet);
+}
+
+void StyleSheetEditorDialog::validateStyleSheet()
+{
+ const bool valid = isStyleSheetValid(m_editor->toPlainText());
+ setOkButtonEnabled(valid);
+ if (valid) {
+ m_validityLabel->setText(tr("Valid Style Sheet"));
+ m_validityLabel->setStyleSheet(QLatin1String("color: green"));
+ } else {
+ m_validityLabel->setText(tr("Invalid Style Sheet"));
+ m_validityLabel->setStyleSheet(QLatin1String("color: red"));
+ }
+}
+
+// --- StyleSheetPropertyEditorDialog
+StyleSheetPropertyEditorDialog::StyleSheetPropertyEditorDialog(QWidget *parent,
+ QDesignerFormWindowInterface *fw,
+ QWidget *widget):
+ StyleSheetEditorDialog(fw->core(), parent),
+ m_fw(fw),
+ m_widget(widget)
+{
+ Q_ASSERT(m_fw != 0);
+
+ QPushButton *apply = buttonBox()->addButton(QDialogButtonBox::Apply);
+ QObject::connect(apply, SIGNAL(clicked()), this, SLOT(applyStyleSheet()));
+ QObject::connect(buttonBox(), SIGNAL(accepted()), this, SLOT(applyStyleSheet()));
+
+ QDesignerPropertySheetExtension *sheet =
+ qt_extension<QDesignerPropertySheetExtension*>(m_fw->core()->extensionManager(), m_widget);
+ Q_ASSERT(sheet != 0);
+ const int index = sheet->indexOf(QLatin1String(styleSheetProperty));
+ const PropertySheetStringValue value = qvariant_cast<PropertySheetStringValue>(sheet->property(index));
+ setText(value.value());
+}
+
+void StyleSheetPropertyEditorDialog::applyStyleSheet()
+{
+ const PropertySheetStringValue value(text(), false);
+ m_fw->cursor()->setWidgetProperty(m_widget, QLatin1String(styleSheetProperty), QVariant::fromValue(value));
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/stylesheeteditor_p.h b/src/designer/src/lib/shared/stylesheeteditor_p.h
new file mode 100644
index 000000000..ce735c71b
--- /dev/null
+++ b/src/designer/src/lib/shared/stylesheeteditor_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef STYLESHEETEDITOR_H
+#define STYLESHEETEDITOR_H
+
+#include <QtGui/QTextEdit>
+#include <QtGui/QDialog>
+#include <QtGui/QLabel>
+#include "shared_global_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerFormEditorInterface;
+
+class QDialogButtonBox;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT StyleSheetEditor : public QTextEdit
+{
+ Q_OBJECT
+public:
+ StyleSheetEditor(QWidget *parent = 0);
+};
+
+// Edit a style sheet.
+class QDESIGNER_SHARED_EXPORT StyleSheetEditorDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ enum Mode {
+ ModeGlobal, // resources are disabled (we don't have current resource set loaded), used e.g. in configuration dialog context
+ ModePerForm // resources are available
+ };
+
+ StyleSheetEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent, Mode mode = ModePerForm);
+ ~StyleSheetEditorDialog();
+ QString text() const;
+ void setText(const QString &t);
+
+ static bool isStyleSheetValid(const QString &styleSheet);
+
+
+private slots:
+ void validateStyleSheet();
+ void slotContextMenuRequested(const QPoint &pos);
+ void slotAddResource(const QString &property);
+ void slotAddGradient(const QString &property);
+ void slotAddColor(const QString &property);
+ void slotAddFont();
+ void slotRequestHelp();
+
+protected:
+ QDialogButtonBox *buttonBox() const;
+ void setOkButtonEnabled(bool v);
+
+private:
+ void insertCssProperty(const QString &name, const QString &value);
+
+ QDialogButtonBox *m_buttonBox;
+ StyleSheetEditor *m_editor;
+ QLabel *m_validityLabel;
+ QDesignerFormEditorInterface *m_core;
+ QAction *m_addResourceAction;
+ QAction *m_addGradientAction;
+ QAction *m_addColorAction;
+ QAction *m_addFontAction;
+};
+
+// Edit the style sheet property of the designer selection.
+// Provides an "Apply" button.
+
+class QDESIGNER_SHARED_EXPORT StyleSheetPropertyEditorDialog : public StyleSheetEditorDialog
+{
+ Q_OBJECT
+public:
+ StyleSheetPropertyEditorDialog(QWidget *parent, QDesignerFormWindowInterface *fw, QWidget *widget);
+
+ static bool isStyleSheetValid(const QString &styleSheet);
+
+private slots:
+ void applyStyleSheet();
+
+private:
+ QDesignerFormWindowInterface *m_fw;
+ QWidget *m_widget;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // STYLESHEETEDITOR_H
diff --git a/src/designer/src/lib/shared/templates/forms/240x320/Dialog_with_Buttons_Bottom.ui b/src/designer/src/lib/shared/templates/forms/240x320/Dialog_with_Buttons_Bottom.ui
new file mode 100644
index 000000000..7ff64b0cb
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/240x320/Dialog_with_Buttons_Bottom.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>240</width>
+ <height>320</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>270</y>
+ <width>221</width>
+ <height>41</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/240x320/Dialog_with_Buttons_Right.ui b/src/designer/src/lib/shared/templates/forms/240x320/Dialog_with_Buttons_Right.ui
new file mode 100644
index 000000000..203af78ff
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/240x320/Dialog_with_Buttons_Right.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>240</width>
+ <height>320</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>150</x>
+ <y>10</y>
+ <width>81</width>
+ <height>301</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/320x240/Dialog_with_Buttons_Bottom.ui b/src/designer/src/lib/shared/templates/forms/320x240/Dialog_with_Buttons_Bottom.ui
new file mode 100644
index 000000000..0ac856e4e
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/320x240/Dialog_with_Buttons_Bottom.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>320</width>
+ <height>240</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>200</y>
+ <width>301</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/320x240/Dialog_with_Buttons_Right.ui b/src/designer/src/lib/shared/templates/forms/320x240/Dialog_with_Buttons_Right.ui
new file mode 100644
index 000000000..52f0f66a4
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/320x240/Dialog_with_Buttons_Right.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>320</width>
+ <height>240</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>230</x>
+ <y>10</y>
+ <width>81</width>
+ <height>221</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/480x640/Dialog_with_Buttons_Bottom.ui b/src/designer/src/lib/shared/templates/forms/480x640/Dialog_with_Buttons_Bottom.ui
new file mode 100644
index 000000000..0d219c937
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/480x640/Dialog_with_Buttons_Bottom.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>480</width>
+ <height>640</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>600</y>
+ <width>461</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/480x640/Dialog_with_Buttons_Right.ui b/src/designer/src/lib/shared/templates/forms/480x640/Dialog_with_Buttons_Right.ui
new file mode 100644
index 000000000..c82a78e87
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/480x640/Dialog_with_Buttons_Right.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>480</width>
+ <height>640</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>390</x>
+ <y>10</y>
+ <width>81</width>
+ <height>621</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/640x480/Dialog_with_Buttons_Bottom.ui b/src/designer/src/lib/shared/templates/forms/640x480/Dialog_with_Buttons_Bottom.ui
new file mode 100644
index 000000000..adc5d4847
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/640x480/Dialog_with_Buttons_Bottom.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>640</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>440</y>
+ <width>621</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/640x480/Dialog_with_Buttons_Right.ui b/src/designer/src/lib/shared/templates/forms/640x480/Dialog_with_Buttons_Right.ui
new file mode 100644
index 000000000..defb42a40
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/640x480/Dialog_with_Buttons_Right.ui
@@ -0,0 +1,67 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>640</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>550</x>
+ <y>10</y>
+ <width>81</width>
+ <height>461</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/Dialog_with_Buttons_Bottom.ui b/src/designer/src/lib/shared/templates/forms/Dialog_with_Buttons_Bottom.ui
new file mode 100644
index 000000000..18d31ab91
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/Dialog_with_Buttons_Bottom.ui
@@ -0,0 +1,71 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>30</x>
+ <y>240</y>
+ <width>341</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/Dialog_with_Buttons_Right.ui b/src/designer/src/lib/shared/templates/forms/Dialog_with_Buttons_Right.ui
new file mode 100644
index 000000000..703d594f4
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/Dialog_with_Buttons_Right.ui
@@ -0,0 +1,71 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="geometry" >
+ <rect>
+ <x>290</x>
+ <y>20</y>
+ <width>81</width>
+ <height>241</height>
+ </rect>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/Dialog_without_Buttons.ui b/src/designer/src/lib/shared/templates/forms/Dialog_without_Buttons.ui
new file mode 100644
index 000000000..1be629818
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/Dialog_without_Buttons.ui
@@ -0,0 +1,18 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/Main_Window.ui b/src/designer/src/lib/shared/templates/forms/Main_Window.ui
new file mode 100644
index 000000000..9ae3b5024
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/Main_Window.ui
@@ -0,0 +1,24 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QMenuBar" name="menubar" />
+ <widget class="QWidget" name="centralwidget" />
+ <widget class="QStatusBar" name="statusbar" />
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <connections/>
+</ui>
diff --git a/src/designer/src/lib/shared/templates/forms/Widget.ui b/src/designer/src/lib/shared/templates/forms/Widget.ui
new file mode 100644
index 000000000..4b7d6a45f
--- /dev/null
+++ b/src/designer/src/lib/shared/templates/forms/Widget.ui
@@ -0,0 +1,21 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>Form</class>
+ <widget class="QWidget" name="Form" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <connections/>
+</ui>
diff --git a/src/designer/src/lib/shared/textpropertyeditor.cpp b/src/designer/src/lib/shared/textpropertyeditor.cpp
new file mode 100644
index 000000000..bc6cbeac7
--- /dev/null
+++ b/src/designer/src/lib/shared/textpropertyeditor.cpp
@@ -0,0 +1,430 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "textpropertyeditor_p.h"
+#include "propertylineedit_p.h"
+#include "stylesheeteditor_p.h"
+
+#include <QtGui/QLineEdit>
+#include <QtGui/QRegExpValidator>
+#include <QtGui/QResizeEvent>
+#include <QtGui/QCompleter>
+#include <QtGui/QAbstractItemView>
+#include <QtCore/QRegExp>
+#include <QtCore/QUrl>
+#include <QtCore/QFile>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ const QChar NewLineChar(QLatin1Char('\n'));
+ const QLatin1String EscapedNewLine("\\n");
+
+ // A validator that replaces offending strings
+ class ReplacementValidator : public QValidator {
+ public:
+ ReplacementValidator (QObject * parent,
+ const QString &offending,
+ const QString &replacement);
+ virtual void fixup ( QString & input ) const;
+ virtual State validate ( QString & input, int &pos) const;
+ private:
+ const QString m_offending;
+ const QString m_replacement;
+ };
+
+ ReplacementValidator::ReplacementValidator (QObject * parent,
+ const QString &offending,
+ const QString &replacement) :
+ QValidator(parent ),
+ m_offending(offending),
+ m_replacement(replacement)
+ {
+ }
+
+ void ReplacementValidator::fixup ( QString & input ) const {
+ input.replace(m_offending, m_replacement);
+ }
+
+ QValidator::State ReplacementValidator::validate ( QString & input, int &/* pos */) const {
+ fixup (input);
+ return Acceptable;
+ }
+
+ // A validator for style sheets. Does newline handling and validates sheets.
+ class StyleSheetValidator : public ReplacementValidator {
+ public:
+ StyleSheetValidator (QObject * parent);
+ virtual State validate(QString & input, int &pos) const;
+ };
+
+ StyleSheetValidator::StyleSheetValidator (QObject * parent) :
+ ReplacementValidator(parent, NewLineChar, EscapedNewLine)
+ {
+ }
+
+ QValidator::State StyleSheetValidator::validate ( QString & input, int &pos) const
+ {
+ // base class
+ const State state = ReplacementValidator:: validate(input, pos);
+ if (state != Acceptable)
+ return state;
+ // now check style sheet, create string with newlines
+ const QString styleSheet = qdesigner_internal::TextPropertyEditor::editorStringToString(input, qdesigner_internal::ValidationStyleSheet);
+ const bool valid = qdesigner_internal::StyleSheetEditorDialog::isStyleSheetValid(styleSheet);
+ return valid ? Acceptable : Intermediate;
+ }
+
+ // A validator for URLs based on QUrl. Enforces complete protocol
+ // specification with a completer (adds a trailing slash)
+ class UrlValidator : public QValidator {
+ public:
+ UrlValidator(QCompleter *completer, QObject *parent);
+
+ virtual State validate(QString &input, int &pos) const;
+ virtual void fixup(QString &input) const;
+ private:
+ QUrl guessUrlFromString(const QString &string) const;
+ QCompleter *m_completer;
+ };
+
+ UrlValidator::UrlValidator(QCompleter *completer, QObject *parent) :
+ QValidator(parent),
+ m_completer(completer)
+ {
+ }
+
+ QValidator::State UrlValidator::validate(QString &input, int &pos) const
+ {
+ Q_UNUSED(pos);
+
+ if (input.isEmpty())
+ return Acceptable;
+
+ const QUrl url(input, QUrl::StrictMode);
+
+ if (!url.isValid() || url.isEmpty())
+ return Intermediate;
+
+ if (url.scheme().isEmpty())
+ return Intermediate;
+
+ if (url.host().isEmpty() && url.path().isEmpty())
+ return Intermediate;
+
+ return Acceptable;
+ }
+
+ void UrlValidator::fixup(QString &input) const
+ {
+ // Don't try to fixup if the user is busy selecting a completion proposal
+ if (const QAbstractItemView *iv = m_completer->popup()) {
+ if (iv->isVisible())
+ return;
+ }
+
+ input = guessUrlFromString(input).toString();
+ }
+
+ QUrl UrlValidator::guessUrlFromString(const QString &string) const
+ {
+ const QString urlStr = string.trimmed();
+ const QRegExp qualifiedUrl(QLatin1String("^[a-zA-Z]+\\:.*"));
+
+ // Check if it looks like a qualified URL. Try parsing it and see.
+ const bool hasSchema = qualifiedUrl.exactMatch(urlStr);
+ if (hasSchema) {
+ const QUrl url(urlStr, QUrl::TolerantMode);
+ if (url.isValid())
+ return url;
+ }
+
+ // Might be a Qt resource
+ if (string.startsWith(QLatin1String(":/")))
+ return QUrl(QLatin1String("qrc") + string);
+
+ // Might be a file.
+ if (QFile::exists(urlStr))
+ return QUrl::fromLocalFile(urlStr);
+
+ // Might be a short url - try to detect the schema.
+ if (!hasSchema) {
+ const int dotIndex = urlStr.indexOf(QLatin1Char('.'));
+ if (dotIndex != -1) {
+ const QString prefix = urlStr.left(dotIndex).toLower();
+ QString urlString;
+ if (prefix == QLatin1String("ftp"))
+ urlString += prefix;
+ else
+ urlString += QLatin1String("http");
+ urlString += QLatin1String("://");
+ urlString += urlStr;
+ const QUrl url(urlString, QUrl::TolerantMode);
+ if (url.isValid())
+ return url;
+ }
+ }
+
+ // Fall back to QUrl's own tolerant parser.
+ return QUrl(string, QUrl::TolerantMode);
+ }
+}
+
+namespace qdesigner_internal {
+ // TextPropertyEditor
+ TextPropertyEditor::TextPropertyEditor(QWidget *parent,
+ EmbeddingMode embeddingMode,
+ TextPropertyValidationMode validationMode) :
+ QWidget(parent),
+ m_validationMode(ValidationSingleLine),
+ m_updateMode(UpdateAsYouType),
+ m_lineEdit(new PropertyLineEdit(this)),
+ m_textEdited(false)
+ {
+ switch (embeddingMode) {
+ case EmbeddingNone:
+ break;
+ case EmbeddingTreeView:
+ m_lineEdit->setFrame(false);
+ break;
+ case EmbeddingInPlace:
+ m_lineEdit->setFrame(false);
+ Q_ASSERT(parent);
+ m_lineEdit->setBackgroundRole(parent->backgroundRole());
+ break;
+ }
+
+ setFocusProxy(m_lineEdit);
+
+ connect(m_lineEdit,SIGNAL(editingFinished()), this, SIGNAL(editingFinished()));
+ connect(m_lineEdit,SIGNAL(returnPressed()), this, SLOT(slotEditingFinished()));
+ connect(m_lineEdit,SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString)));
+ connect(m_lineEdit,SIGNAL(textEdited(QString)), this, SLOT(slotTextEdited()));
+
+ setTextPropertyValidationMode(validationMode);
+ }
+
+ void TextPropertyEditor::setTextPropertyValidationMode(TextPropertyValidationMode vm) {
+ m_validationMode = vm;
+ m_lineEdit->setWantNewLine(multiLine(m_validationMode));
+ switch (m_validationMode) {
+ case ValidationStyleSheet:
+ m_lineEdit->setValidator(new StyleSheetValidator(m_lineEdit));
+ m_lineEdit->setCompleter(0);
+ break;
+ case ValidationMultiLine:
+ case ValidationRichText:
+ // Set a validator that replaces newline characters by literal "\\n".
+ // While it is not possible to actually type a newline characters,
+ // it can be pasted into the line edit.
+ m_lineEdit->setValidator(new ReplacementValidator(m_lineEdit, NewLineChar, EscapedNewLine));
+ m_lineEdit->setCompleter(0);
+ break;
+ case ValidationSingleLine:
+ // Set a validator that replaces newline characters by a blank.
+ m_lineEdit->setValidator(new ReplacementValidator(m_lineEdit, NewLineChar, QString(QLatin1Char(' '))));
+ m_lineEdit->setCompleter(0);
+ break;
+ case ValidationObjectName:
+ setRegExpValidator(QLatin1String("[_a-zA-Z][_a-zA-Z0-9]{,1023}"));
+ m_lineEdit->setCompleter(0);
+ break;
+ case ValidationObjectNameScope:
+ setRegExpValidator(QLatin1String("[_a-zA-Z:][_a-zA-Z0-9:]{,1023}"));
+ m_lineEdit->setCompleter(0);
+ break;
+ case ValidationURL: {
+ static QStringList urlCompletions;
+ if (urlCompletions.empty()) {
+ urlCompletions.push_back(QLatin1String("about:blank"));
+ urlCompletions.push_back(QLatin1String("http://"));
+ urlCompletions.push_back(QLatin1String("http://www."));
+ urlCompletions.push_back(QLatin1String("http://qt.nokia.com/"));
+ urlCompletions.push_back(QLatin1String("file://"));
+ urlCompletions.push_back(QLatin1String("ftp://"));
+ urlCompletions.push_back(QLatin1String("data:"));
+ urlCompletions.push_back(QLatin1String("data:text/html,"));
+ urlCompletions.push_back(QLatin1String("qrc:/"));
+ }
+ QCompleter *completer = new QCompleter(urlCompletions, m_lineEdit);
+ m_lineEdit->setCompleter(completer);
+ m_lineEdit->setValidator(new UrlValidator(completer, m_lineEdit));
+ }
+ break;
+ }
+
+ setFocusProxy(m_lineEdit);
+ setText(m_cachedText);
+ markIntermediateState();
+ }
+
+ void TextPropertyEditor::setRegExpValidator(const QString &pattern)
+ {
+ const QRegExp regExp(pattern);
+ Q_ASSERT(regExp.isValid());
+ m_lineEdit->setValidator(new QRegExpValidator(regExp,m_lineEdit));
+ }
+
+ QString TextPropertyEditor::text() const
+ {
+ return m_cachedText;
+ }
+
+ void TextPropertyEditor::markIntermediateState()
+ {
+ if (m_lineEdit->hasAcceptableInput()) {
+ m_lineEdit->setPalette(QPalette());
+ } else {
+ QPalette palette = m_lineEdit->palette();
+ palette.setColor(QPalette::Active, QPalette::Text, Qt::red);
+ m_lineEdit->setPalette(palette);
+ }
+
+ }
+
+ void TextPropertyEditor::setText(const QString &text)
+ {
+ m_cachedText = text;
+ m_lineEdit->setText(stringToEditorString(text, m_validationMode));
+ markIntermediateState();
+ m_textEdited = false;
+ }
+
+ void TextPropertyEditor::slotTextEdited()
+ {
+ m_textEdited = true;
+ }
+
+ void TextPropertyEditor::slotTextChanged(const QString &text) {
+ m_cachedText = editorStringToString(text, m_validationMode);
+ markIntermediateState();
+ if (m_updateMode == UpdateAsYouType)
+ emit textChanged(m_cachedText);
+ }
+
+ void TextPropertyEditor::slotEditingFinished()
+ {
+ if (m_updateMode == UpdateOnFinished && m_textEdited) {
+ emit textChanged(m_cachedText);
+ m_textEdited = false;
+ }
+ }
+
+ void TextPropertyEditor::selectAll() {
+ m_lineEdit->selectAll();
+ }
+
+ void TextPropertyEditor::clear() {
+ m_lineEdit->clear();
+ }
+
+ void TextPropertyEditor::setAlignment(Qt::Alignment alignment) {
+ m_lineEdit->setAlignment(alignment);
+ }
+
+ void TextPropertyEditor::installEventFilter(QObject *filterObject)
+ {
+ if (m_lineEdit)
+ m_lineEdit->installEventFilter(filterObject);
+ }
+
+ void TextPropertyEditor::resizeEvent ( QResizeEvent * event ) {
+ m_lineEdit->resize( event->size());
+ }
+
+ QSize TextPropertyEditor::sizeHint () const {
+ return m_lineEdit->sizeHint ();
+ }
+
+ QSize TextPropertyEditor::minimumSizeHint () const {
+ return m_lineEdit->minimumSizeHint ();
+ }
+
+ // Returns whether newline characters are valid in validationMode.
+ bool TextPropertyEditor::multiLine(TextPropertyValidationMode validationMode) {
+ return validationMode == ValidationMultiLine || validationMode == ValidationStyleSheet || validationMode == ValidationRichText;
+ }
+
+ // Replace newline characters literal "\n" for inline editing in mode ValidationMultiLine
+ QString TextPropertyEditor::stringToEditorString(const QString &s, TextPropertyValidationMode validationMode) {
+ if (s.isEmpty() || !multiLine(validationMode))
+ return s;
+
+ QString rc(s);
+ // protect backslashes
+ rc.replace(QLatin1Char('\\'), QLatin1String("\\\\"));
+ // escape newlines
+ rc.replace(NewLineChar, QString(EscapedNewLine));
+ return rc;
+
+ }
+
+ // Replace literal "\n" by actual new lines for inline editing in mode ValidationMultiLine
+ // Note: As the properties are updated while the user types, it is important
+ // that trailing slashes ('bla\') are not deleted nor ignored, else this will
+ // cause jumping of the cursor
+ QString TextPropertyEditor::editorStringToString(const QString &s, TextPropertyValidationMode validationMode) {
+ if (s.isEmpty() || !multiLine(validationMode))
+ return s;
+
+ QString rc(s);
+ for (int pos = 0; (pos = rc.indexOf(QLatin1Char('\\'),pos)) >= 0 ; ) {
+ // found an escaped character. If not a newline or at end of string, leave as is, else insert '\n'
+ const int nextpos = pos + 1;
+ if (nextpos >= rc.length()) // trailing '\\'
+ break;
+ // Escaped NewLine
+ if (rc.at(nextpos) == QChar(QLatin1Char('n')))
+ rc[nextpos] = NewLineChar;
+ // Remove escape, go past escaped
+ rc.remove(pos,1);
+ pos++;
+ }
+ return rc;
+ }
+
+ bool TextPropertyEditor::hasAcceptableInput() const {
+ return m_lineEdit->hasAcceptableInput();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/textpropertyeditor_p.h b/src/designer/src/lib/shared/textpropertyeditor_p.h
new file mode 100644
index 000000000..da92e8e82
--- /dev/null
+++ b/src/designer/src/lib/shared/textpropertyeditor_p.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef TEXTPROPERTYEDITOR_H
+#define TEXTPROPERTYEDITOR_H
+
+#include "shared_global_p.h"
+#include "shared_enums_p.h"
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+ class PropertyLineEdit;
+
+ // Inline-Editor for text properties. Does escaping of newline characters
+ // to '\n' and back and provides validation modes. The interface
+ // corresponds to that of QLineEdit.
+ class QDESIGNER_SHARED_EXPORT TextPropertyEditor : public QWidget
+ {
+ TextPropertyEditor(const TextPropertyEditor &);
+ TextPropertyEditor& operator=(const TextPropertyEditor &);
+ Q_OBJECT
+ Q_PROPERTY(QString text READ text WRITE setText USER true)
+ public:
+ enum EmbeddingMode {
+ // Stand-alone widget
+ EmbeddingNone,
+ // Disable frame
+ EmbeddingTreeView,
+ // For editing in forms
+ EmbeddingInPlace
+ };
+
+ enum UpdateMode {
+ // Emit textChanged() as the user types
+ UpdateAsYouType,
+ // Emit textChanged() only when the user finishes (for QUrl, etc.)
+ UpdateOnFinished
+ };
+
+ explicit TextPropertyEditor(QWidget *parent = 0, EmbeddingMode embeddingMode = EmbeddingNone, TextPropertyValidationMode validationMode = ValidationMultiLine);
+
+ TextPropertyValidationMode textPropertyValidationMode() const { return m_validationMode; }
+ void setTextPropertyValidationMode(TextPropertyValidationMode vm);
+
+ UpdateMode updateMode() const { return m_updateMode; }
+ void setUpdateMode(UpdateMode um) { m_updateMode = um; }
+
+ QString text() const;
+
+ virtual QSize sizeHint () const;
+ virtual QSize minimumSizeHint () const;
+
+ void setAlignment(Qt::Alignment alignment);
+
+ bool hasAcceptableInput() const;
+
+ // installs an event filter object on the private QLineEdit
+ void installEventFilter(QObject *filterObject);
+
+ // Replace newline characters by literal "\n" for inline editing
+ // in mode ValidationMultiLine
+ static QString stringToEditorString(const QString &s, TextPropertyValidationMode validationMode = ValidationMultiLine);
+
+ // Replace literal "\n" by actual new lines in mode ValidationMultiLine
+ static QString editorStringToString(const QString &s, TextPropertyValidationMode validationMode = ValidationMultiLine);
+
+ // Returns whether newline characters are valid in validationMode.
+ static bool multiLine(TextPropertyValidationMode validationMode);
+
+ signals:
+ void textChanged(const QString &text);
+ void editingFinished();
+
+ public slots:
+ void setText(const QString &text);
+ void selectAll();
+ void clear();
+
+ protected:
+ void resizeEvent(QResizeEvent * event );
+
+ private slots:
+ void slotTextChanged(const QString &text);
+ void slotTextEdited();
+ void slotEditingFinished();
+
+ private:
+ void setRegExpValidator(const QString &pattern);
+ void markIntermediateState();
+
+ TextPropertyValidationMode m_validationMode;
+ UpdateMode m_updateMode;
+ PropertyLineEdit* m_lineEdit;
+
+ // Cached text containing real newline characters.
+ QString m_cachedText;
+ bool m_textEdited;
+ };
+}
+
+QT_END_NAMESPACE
+
+#endif // TEXTPROPERTYEDITOR_H
diff --git a/src/designer/src/lib/shared/widgetdatabase.cpp b/src/designer/src/lib/shared/widgetdatabase.cpp
new file mode 100644
index 000000000..aa1a77592
--- /dev/null
+++ b/src/designer/src/lib/shared/widgetdatabase.cpp
@@ -0,0 +1,865 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "widgetdatabase_p.h"
+#include "widgetfactory_p.h"
+#include "spacer_widget_p.h"
+#include "abstractlanguage.h"
+#include "pluginmanager_p.h"
+#include "qdesigner_widgetbox_p.h"
+#include "qdesigner_utils_p.h"
+#include <ui4_p.h>
+
+#include <QtDesigner/customwidget.h>
+#include <QtDesigner/propertysheet.h>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtXml/QXmlStreamWriter>
+
+#include <QtCore/QScopedPointer>
+#include <QtCore/qdebug.h>
+#include <QtCore/QMetaProperty>
+#include <QtCore/QTextStream>
+#include <QtCore/QRegExp>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { debugWidgetDataBase = 0 };
+}
+
+namespace qdesigner_internal {
+
+// ----------------------------------------------------------
+WidgetDataBaseItem::WidgetDataBaseItem(const QString &name, const QString &group)
+ : m_name(name),
+ m_group(group),
+ m_compat(0),
+ m_container(0),
+ m_form(0),
+ m_custom(0),
+ m_promoted(0)
+{
+}
+
+QString WidgetDataBaseItem::name() const
+{
+ return m_name;
+}
+
+void WidgetDataBaseItem::setName(const QString &name)
+{
+ m_name = name;
+}
+
+QString WidgetDataBaseItem::group() const
+{
+ return m_group;
+}
+
+void WidgetDataBaseItem::setGroup(const QString &group)
+{
+ m_group = group;
+}
+
+QString WidgetDataBaseItem::toolTip() const
+{
+ return m_toolTip;
+}
+
+void WidgetDataBaseItem::setToolTip(const QString &toolTip)
+{
+ m_toolTip = toolTip;
+}
+
+QString WidgetDataBaseItem::whatsThis() const
+{
+ return m_whatsThis;
+}
+
+void WidgetDataBaseItem::setWhatsThis(const QString &whatsThis)
+{
+ m_whatsThis = whatsThis;
+}
+
+QString WidgetDataBaseItem::includeFile() const
+{
+ return m_includeFile;
+}
+
+void WidgetDataBaseItem::setIncludeFile(const QString &includeFile)
+{
+ m_includeFile = includeFile;
+}
+
+QIcon WidgetDataBaseItem::icon() const
+{
+ return m_icon;
+}
+
+void WidgetDataBaseItem::setIcon(const QIcon &icon)
+{
+ m_icon = icon;
+}
+
+bool WidgetDataBaseItem::isCompat() const
+{
+ return m_compat;
+}
+
+void WidgetDataBaseItem::setCompat(bool b)
+{
+ m_compat = b;
+}
+
+bool WidgetDataBaseItem::isContainer() const
+{
+ return m_container;
+}
+
+void WidgetDataBaseItem::setContainer(bool b)
+{
+ m_container = b;
+}
+
+bool WidgetDataBaseItem::isCustom() const
+{
+ return m_custom;
+}
+
+void WidgetDataBaseItem::setCustom(bool b)
+{
+ m_custom = b;
+}
+
+QString WidgetDataBaseItem::pluginPath() const
+{
+ return m_pluginPath;
+}
+
+void WidgetDataBaseItem::setPluginPath(const QString &path)
+{
+ m_pluginPath = path;
+}
+
+bool WidgetDataBaseItem::isPromoted() const
+{
+ return m_promoted;
+}
+
+void WidgetDataBaseItem::setPromoted(bool b)
+{
+ m_promoted = b;
+}
+
+QString WidgetDataBaseItem::extends() const
+{
+ return m_extends;
+}
+
+void WidgetDataBaseItem::setExtends(const QString &s)
+{
+ m_extends = s;
+}
+
+void WidgetDataBaseItem::setDefaultPropertyValues(const QList<QVariant> &list)
+{
+ m_defaultPropertyValues = list;
+}
+
+QList<QVariant> WidgetDataBaseItem::defaultPropertyValues() const
+{
+ return m_defaultPropertyValues;
+}
+
+QStringList WidgetDataBaseItem::fakeSlots() const
+{
+ return m_fakeSlots;
+}
+
+void WidgetDataBaseItem::setFakeSlots(const QStringList &fs)
+{
+ m_fakeSlots = fs;
+}
+
+QStringList WidgetDataBaseItem::fakeSignals() const
+{
+ return m_fakeSignals;
+}
+
+void WidgetDataBaseItem::setFakeSignals(const QStringList &fs)
+{
+ m_fakeSignals = fs;
+}
+
+QString WidgetDataBaseItem::addPageMethod() const
+{
+ return m_addPageMethod;
+}
+
+void WidgetDataBaseItem::setAddPageMethod(const QString &m)
+{
+ m_addPageMethod = m;
+}
+
+WidgetDataBaseItem *WidgetDataBaseItem::clone(const QDesignerWidgetDataBaseItemInterface *item)
+{
+ WidgetDataBaseItem *rc = new WidgetDataBaseItem(item->name(), item->group());
+
+ rc->setToolTip(item->toolTip());
+ rc->setWhatsThis(item->whatsThis());
+ rc->setIncludeFile(item->includeFile());
+ rc->setIcon(item->icon());
+ rc->setCompat(item->isCompat());
+ rc->setContainer(item->isContainer());
+ rc->setCustom(item->isCustom() );
+ rc->setPluginPath(item->pluginPath());
+ rc->setPromoted(item->isPromoted());
+ rc->setExtends(item->extends());
+ rc->setDefaultPropertyValues(item->defaultPropertyValues());
+ // container page method, fake slots and signals ignored here.y
+ return rc;
+}
+
+// ----------------------------------------------------------
+WidgetDataBase::WidgetDataBase(QDesignerFormEditorInterface *core, QObject *parent)
+ : QDesignerWidgetDataBaseInterface(parent),
+ m_core(core)
+{
+#define DECLARE_LAYOUT(L, C)
+#define DECLARE_COMPAT_WIDGET(W, C) DECLARE_WIDGET(W, C)
+#define DECLARE_WIDGET(W, C) append(new WidgetDataBaseItem(QString::fromUtf8(#W)));
+
+#include "widgets.table"
+
+#undef DECLARE_COMPAT_WIDGET
+#undef DECLARE_LAYOUT
+#undef DECLARE_WIDGET
+#undef DECLARE_WIDGET_1
+
+ append(new WidgetDataBaseItem(QString::fromUtf8("Line")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("Spacer")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("QSplitter")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("QLayoutWidget")));
+ // QDesignerWidget is used as central widget and as container for tab widgets, etc.
+ WidgetDataBaseItem *designerWidgetItem = new WidgetDataBaseItem(QString::fromUtf8("QDesignerWidget"));
+ designerWidgetItem->setContainer(true);
+ append(designerWidgetItem);
+ append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerDialog")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerMenu")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerMenuBar")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerDockWidget")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("QDesignerQ3WidgetStack")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("QAction")));
+ append(new WidgetDataBaseItem(QString::fromUtf8("QButtonGroup")));
+
+ // ### remove me
+ // ### check the casts
+
+#if 0 // ### enable me after 4.1
+ item(indexOfClassName(QLatin1String("QToolBar")))->setContainer(true);
+#endif
+
+ item(indexOfClassName(QLatin1String("QTabWidget")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QGroupBox")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QScrollArea")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QStackedWidget")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QToolBox")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QFrame")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QLayoutWidget")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QDesignerWidget")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QDesignerDialog")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QSplitter")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QMainWindow")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QDockWidget")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QDesignerDockWidget")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QDesignerQ3WidgetStack")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QMdiArea")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QWorkspace")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QWizard")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QWizardPage")))->setContainer(true);
+
+ item(indexOfClassName(QLatin1String("QWidget")))->setContainer(true);
+ item(indexOfClassName(QLatin1String("QDialog")))->setContainer(true);
+}
+
+WidgetDataBase::~WidgetDataBase()
+{
+}
+
+QDesignerFormEditorInterface *WidgetDataBase::core() const
+{
+ return m_core;
+}
+
+int WidgetDataBase::indexOfObject(QObject *object, bool /*resolveName*/) const
+{
+ QExtensionManager *mgr = m_core->extensionManager();
+ QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension*> (mgr, m_core);
+
+ QString id;
+
+ if (lang)
+ id = lang->classNameOf(object);
+
+ if (id.isEmpty())
+ id = WidgetFactory::classNameOf(m_core,object);
+
+ return QDesignerWidgetDataBaseInterface::indexOfClassName(id);
+}
+
+static WidgetDataBaseItem *createCustomWidgetItem(const QDesignerCustomWidgetInterface *c,
+ const QDesignerCustomWidgetData &data)
+{
+ WidgetDataBaseItem *item = new WidgetDataBaseItem(c->name(), c->group());
+ item->setContainer(c->isContainer());
+ item->setCustom(true);
+ item->setIcon(c->icon());
+ item->setIncludeFile(c->includeFile());
+ item->setToolTip(c->toolTip());
+ item->setWhatsThis(c->whatsThis());
+ item->setPluginPath(data.pluginPath());
+ item->setAddPageMethod(data.xmlAddPageMethod());
+ item->setExtends(data.xmlExtends());
+ return item;
+}
+
+void WidgetDataBase::loadPlugins()
+{
+ typedef QMap<QString, int> NameIndexMap;
+ typedef QList<QDesignerWidgetDataBaseItemInterface*> ItemList;
+ typedef QMap<QString, QDesignerWidgetDataBaseItemInterface*> NameItemMap;
+ typedef QSet<QString> NameSet;
+ // 1) create a map of existing custom classes
+ NameIndexMap existingCustomClasses;
+ NameSet nonCustomClasses;
+ const int count = m_items.size();
+ for (int i = 0; i < count; i++) {
+ const QDesignerWidgetDataBaseItemInterface* item = m_items[i];
+ if (item->isCustom() && !item->isPromoted())
+ existingCustomClasses.insert(item->name(), i);
+ else
+ nonCustomClasses.insert(item->name());
+ }
+ // 2) create a list plugins
+ ItemList pluginList;
+ const QDesignerPluginManager *pm = m_core->pluginManager();
+ foreach(QDesignerCustomWidgetInterface* c, pm->registeredCustomWidgets())
+ pluginList += createCustomWidgetItem(c, pm->customWidgetData(c));
+
+ // 3) replace custom classes or add new ones, remove them from existingCustomClasses,
+ // leaving behind deleted items
+ unsigned replacedPlugins = 0;
+ unsigned addedPlugins = 0;
+ unsigned removedPlugins = 0;
+ if (!pluginList.empty()) {
+ ItemList::const_iterator cend = pluginList.constEnd();
+ for (ItemList::const_iterator it = pluginList.constBegin();it != cend; ++it ) {
+ QDesignerWidgetDataBaseItemInterface* pluginItem = *it;
+ const QString pluginName = pluginItem->name();
+ NameIndexMap::iterator existingIt = existingCustomClasses.find(pluginName);
+ if (existingIt == existingCustomClasses.end()) {
+ // Add new class.
+ if (nonCustomClasses.contains(pluginName)) {
+ designerWarning(tr("A custom widget plugin whose class name (%1) matches that of an existing class has been found.").arg(pluginName));
+ } else {
+ append(pluginItem);
+ addedPlugins++;
+ }
+ } else {
+ // replace existing info
+ const int existingIndex = existingIt.value();
+ delete m_items[existingIndex];
+ m_items[existingIndex] = pluginItem;
+ existingCustomClasses.erase(existingIt);
+ replacedPlugins++;
+
+ }
+ }
+ }
+ // 4) remove classes that have not been matched. The stored indexes become invalid while deleting.
+ if (!existingCustomClasses.empty()) {
+ NameIndexMap::const_iterator cend = existingCustomClasses.constEnd();
+ for (NameIndexMap::const_iterator it = existingCustomClasses.constBegin();it != cend; ++it ) {
+ const int index = indexOfClassName(it.key());
+ if (index != -1) {
+ remove(index);
+ removedPlugins++;
+ }
+ }
+ }
+ if (debugWidgetDataBase)
+ qDebug() << "WidgetDataBase::loadPlugins(): " << addedPlugins << " added, " << replacedPlugins << " replaced, " << removedPlugins << "deleted.";
+}
+
+void WidgetDataBase::remove(int index)
+{
+ Q_ASSERT(index < m_items.size());
+ delete m_items.takeAt(index);
+}
+
+QList<QVariant> WidgetDataBase::defaultPropertyValues(const QString &name)
+{
+ WidgetFactory *factory = qobject_cast<WidgetFactory *>(m_core->widgetFactory());
+ Q_ASSERT(factory);
+ // Create non-widgets, widgets in order
+ QObject* object = factory->createObject(name, 0);
+ if (!object)
+ object = factory->createWidget(name, 0);
+ if (!object) {
+ qDebug() << "** WARNING Factory failed to create " << name;
+ return QList<QVariant>();
+ }
+ // Get properties from sheet.
+ QList<QVariant> result;
+ if (const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_core->extensionManager(), object)) {
+ const int propertyCount = sheet->count();
+ for (int i = 0; i < propertyCount; ++i) {
+ result.append(sheet->property(i));
+ }
+ }
+ delete object;
+ return result;
+}
+
+void WidgetDataBase::grabDefaultPropertyValues()
+{
+ const int itemCount = count();
+ for (int i = 0; i < itemCount; ++i) {
+ QDesignerWidgetDataBaseItemInterface *dbItem = item(i);
+ const QList<QVariant> default_prop_values = defaultPropertyValues(dbItem->name());
+ dbItem->setDefaultPropertyValues(default_prop_values);
+ }
+}
+
+void WidgetDataBase::grabStandardWidgetBoxIcons()
+{
+ // At this point, grab the default icons for the non-custom widgets from
+ // the widget box. They will show up in the object inspector.
+ if (const QDesignerWidgetBox *wb = qobject_cast<const QDesignerWidgetBox *>(m_core->widgetBox())) {
+ const QString qWidgetClass = QLatin1String("QWidget");
+ const int itemCount = count();
+ for (int i = 0; i < itemCount; ++i) {
+ QDesignerWidgetDataBaseItemInterface *dbItem = item(i);
+ if (!dbItem->isCustom() && dbItem->icon().isNull()) {
+ // Careful not to catch the layout icons when looking for
+ // QWidget
+ const QString name = dbItem->name();
+ if (name == qWidgetClass) {
+ dbItem->setIcon(wb->iconForWidget(name, QLatin1String("Containers")));
+ } else {
+ dbItem->setIcon(wb->iconForWidget(name));
+ }
+ }
+ }
+ }
+}
+
+// --------------------- Functions relevant generation of new forms based on widgets (apart from the standard templates)
+
+enum { NewFormWidth = 400, NewFormHeight = 300 };
+
+// Check if class is suitable to generate a form from
+static inline bool isExistingTemplate(const QString &className)
+{
+ return className == QLatin1String("QWidget") || className == QLatin1String("QDialog") || className == QLatin1String("QMainWindow");
+}
+
+// Check if class is suitable to generate a form from
+static inline bool suitableForNewForm(const QString &className)
+{
+ if (className.isEmpty()) // Missing custom widget information
+ return false;
+ if (className == QLatin1String("QWorkspace"))
+ return false;
+ if (className == QLatin1String("QSplitter"))
+ return false;
+ if (className.startsWith(QLatin1String("QDesigner")) || className.startsWith(QLatin1String("Q3")) || className.startsWith(QLatin1String("QLayout")))
+ return false;
+ return true;
+}
+
+// Return a list of widget classes from which new forms can be generated.
+// Suitable for 'New form' wizards in integrations.
+QStringList WidgetDataBase::formWidgetClasses(const QDesignerFormEditorInterface *core)
+{
+ static QStringList rc;
+ if (rc.empty()) {
+ const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
+ const int widgetCount = wdb->count();
+ for (int i = 0; i < widgetCount; i++) {
+ const QDesignerWidgetDataBaseItemInterface *item = wdb->item(i);
+ if (item->isContainer() && !item->isCustom() && !item->isPromoted()) {
+ const QString name = item->name(); // Standard Widgets: no existing templates
+ if (!isExistingTemplate(name) && suitableForNewForm(name))
+ rc += name;
+ }
+ }
+ }
+ return rc;
+}
+
+// Return a list of custom widget classes from which new forms can be generated.
+// Suitable for 'New form' wizards in integrations.
+QStringList WidgetDataBase::customFormWidgetClasses(const QDesignerFormEditorInterface *core)
+{
+ QStringList rc;
+ const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
+ const int widgetCount = wdb->count();
+ for (int i = 0; i < widgetCount; i++) { // Custom widgets: check name and base class.
+ const QDesignerWidgetDataBaseItemInterface *item = wdb->item(i);
+ if (item->isContainer() && item->isCustom() && !item->isPromoted()) {
+ if (suitableForNewForm(item->name()) && suitableForNewForm(item->extends()))
+ rc += item->name();
+ }
+ }
+ return rc;
+}
+
+// Get XML for a new form from the widget box. Change objectName/geometry
+// properties to be suitable for new forms
+static QString xmlFromWidgetBox(const QDesignerFormEditorInterface *core, const QString &className, const QString &objectName)
+{
+ typedef QList<DomProperty*> PropertyList;
+
+ QDesignerWidgetBoxInterface::Widget widget;
+ const bool found = QDesignerWidgetBox::findWidget(core->widgetBox(), className, QString(), &widget);
+ if (!found)
+ return QString();
+ QScopedPointer<DomUI> domUI(QDesignerWidgetBox::xmlToUi(className, widget.domXml(), false));
+ if (domUI.isNull())
+ return QString();
+ domUI->setAttributeVersion(QLatin1String("4.0"));
+ DomWidget *domWidget = domUI->elementWidget();
+ if (!domWidget)
+ return QString();
+ // Properties: Remove the "objectName" property in favour of the name attribute and check geometry.
+ domWidget->setAttributeName(objectName);
+ const QString geometryProperty = QLatin1String("geometry");
+ const QString objectNameProperty = QLatin1String("objectName");
+ PropertyList properties = domWidget->elementProperty();
+ for (PropertyList::iterator it = properties.begin(); it != properties.end(); ) {
+ DomProperty *property = *it;
+ if (property->attributeName() == objectNameProperty) { // remove "objectName"
+ it = properties.erase(it);
+ delete property;
+ } else {
+ if (property->attributeName() == geometryProperty) { // Make sure form is at least 400, 300
+ if (DomRect *geom = property->elementRect()) {
+ if (geom->elementWidth() < NewFormWidth)
+ geom->setElementWidth(NewFormWidth);
+ if (geom->elementHeight() < NewFormHeight)
+ geom->setElementHeight(NewFormHeight);
+ }
+ }
+ ++it;
+ }
+ }
+ // Add a window title property
+ DomString *windowTitleString = new DomString;
+ windowTitleString->setText(objectName);
+ DomProperty *windowTitleProperty = new DomProperty;
+ windowTitleProperty->setAttributeName(QLatin1String("windowTitle"));
+ windowTitleProperty->setElementString(windowTitleString);
+ properties.push_back(windowTitleProperty);
+ // ------
+ domWidget->setElementProperty(properties);
+ // Embed in in DomUI and get string. Omit the version number.
+ domUI->setElementClass(objectName);
+
+ QString rc;
+ { // Serialize domUI
+ QXmlStreamWriter writer(&rc);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ domUI->write(writer);
+ writer.writeEndDocument();
+ }
+ return rc;
+}
+
+// Generate default standard ui new form xml based on the class passed on as similarClassName.
+static QString generateNewFormXML(const QString &className, const QString &similarClassName, const QString &name)
+{
+ QString rc; {
+ QTextStream str(&rc);
+ str << QLatin1String("<ui version=\"4.0\" >\n<class>") << name << QLatin1String("</class>\n")
+ << QLatin1String("<widget class=\"") << className << QLatin1String("\" name=\"") << name << QLatin1String("\" >\n")
+ << QLatin1String("<property name=\"geometry\" >\n<rect><x>0</x><y>0</y><width>")
+ << NewFormWidth << QLatin1String("</width><height>") << NewFormHeight << QLatin1String("</height></rect>\n</property>\n");
+ str << QLatin1String("<property name=\"windowTitle\" >\n<string>") << name << QLatin1String("</string>\n</property>\n");
+
+ if (similarClassName == QLatin1String("QMainWindow")) {
+ str << QLatin1String("<widget class=\"QWidget\" name=\"centralwidget\" />\n");
+ } else {
+ if (similarClassName == QLatin1String("QWizard"))
+ str << QLatin1String("<widget class=\"QWizardPage\" name=\"wizardPage1\" /><widget class=\"QWizardPage\" name=\"wizardPage2\" />\n");
+ }
+ str << QLatin1String("</widget>\n</ui>\n");
+ }
+ return rc;
+}
+
+// Generate a form template using a class name obtained from formWidgetClasses(), customFormWidgetClasses().
+QString WidgetDataBase::formTemplate(const QDesignerFormEditorInterface *core, const QString &className, const QString &objectName)
+{
+ // How to find suitable XML for a class:
+ // 1) Look in widget box (as all the required centralwidgets, tab widget pages, etc. should be there).
+ const QString widgetBoxXml = xmlFromWidgetBox(core, className, objectName);
+ if (!widgetBoxXml.isEmpty())
+ return widgetBoxXml;
+ // 2) If that fails, only custom main windows, custom dialogs and unsupported Qt Widgets should
+ // be left over. Generate something that is similar to the default templates. Find a similar class.
+ const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
+ QString similarClass = QLatin1String("QWidget");
+ const int index = wdb->indexOfClassName(className);
+ if (index != -1) {
+ const QDesignerWidgetDataBaseItemInterface *item = wdb->item(index);
+ similarClass = item->isCustom() ? item->extends() : item->name();
+ }
+ // Generate standard ui based on the class passed on as baseClassName.
+ const QString rc = generateNewFormXML(className, similarClass, objectName);
+ return rc;
+}
+
+// Set a fixed size on a XML template
+QString WidgetDataBase::scaleFormTemplate(const QString &xml, const QSize &size, bool fixed)
+{
+ typedef QList<DomProperty*> PropertyList;
+ DomUI *domUI = QDesignerWidgetBox::xmlToUi(QLatin1String("Form"), xml, false);
+ if (!domUI)
+ return QString();
+ DomWidget *domWidget = domUI->elementWidget();
+ if (!domWidget)
+ return QString();
+ // Properties: Find/Ensure the geometry, minimum and maximum sizes properties
+ const QString geometryPropertyName = QLatin1String("geometry");
+ const QString minimumSizePropertyName = QLatin1String("minimumSize");
+ const QString maximumSizePropertyName = QLatin1String("maximumSize");
+ DomProperty *geomProperty = 0;
+ DomProperty *minimumSizeProperty = 0;
+ DomProperty *maximumSizeProperty = 0;
+
+ PropertyList properties = domWidget->elementProperty();
+ const PropertyList::const_iterator cend = properties.constEnd();
+ for (PropertyList::const_iterator it = properties.constBegin(); it != cend; ++it) {
+ const QString name = (*it)->attributeName();
+ if (name == geometryPropertyName) {
+ geomProperty = *it;
+ } else {
+ if (name == minimumSizePropertyName) {
+ minimumSizeProperty = *it;
+ } else {
+ if (name == maximumSizePropertyName)
+ maximumSizeProperty = *it;
+ }
+ }
+ }
+ if (!geomProperty) {
+ geomProperty = new DomProperty;
+ geomProperty->setAttributeName(geometryPropertyName);
+ geomProperty->setElementRect(new DomRect);
+ properties.push_front(geomProperty);
+ }
+ if (fixed) {
+ if (!minimumSizeProperty) {
+ minimumSizeProperty = new DomProperty;
+ minimumSizeProperty->setAttributeName(minimumSizePropertyName);
+ minimumSizeProperty->setElementSize(new DomSize);
+ properties.push_back(minimumSizeProperty);
+ }
+ if (!maximumSizeProperty) {
+ maximumSizeProperty = new DomProperty;
+ maximumSizeProperty->setAttributeName(maximumSizePropertyName);
+ maximumSizeProperty->setElementSize(new DomSize);
+ properties.push_back(maximumSizeProperty);
+ }
+ }
+ // Set values of geometry, minimum and maximum sizes properties
+ const int width = size.width();
+ const int height = size.height();
+ if (DomRect *geom = geomProperty->elementRect()) {
+ geom->setElementWidth(width);
+ geom->setElementHeight(height);
+ }
+ if (fixed) {
+ if (DomSize *s = minimumSizeProperty->elementSize()) {
+ s->setElementWidth(width);
+ s->setElementHeight(height);
+ }
+ if (DomSize *s = maximumSizeProperty->elementSize()) {
+ s->setElementWidth(width);
+ s->setElementHeight(height);
+ }
+ }
+ // write back
+ domWidget->setElementProperty(properties);
+
+ QString rc;
+ { // serialize domUI
+ QXmlStreamWriter writer(&rc);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ domUI->write(writer);
+ writer.writeEndDocument();
+ }
+
+ delete domUI;
+ return rc;
+}
+
+// ---- free functions
+QDESIGNER_SHARED_EXPORT IncludeSpecification includeSpecification(QString includeFile)
+{
+ const bool global = !includeFile.isEmpty() &&
+ includeFile[0] == QLatin1Char('<') &&
+ includeFile[includeFile.size() - 1] == QLatin1Char('>');
+ if (global) {
+ includeFile.remove(includeFile.size() - 1, 1);
+ includeFile.remove(0, 1);
+ }
+ return IncludeSpecification(includeFile, global ? IncludeGlobal : IncludeLocal);
+}
+
+QDESIGNER_SHARED_EXPORT QString buildIncludeFile(QString includeFile, IncludeType includeType) {
+ if (includeType == IncludeGlobal && !includeFile.isEmpty()) {
+ includeFile.append(QLatin1Char('>'));
+ includeFile.insert(0, QLatin1Char('<'));
+ }
+ return includeFile;
+}
+
+
+/* Appends a derived class to the database inheriting the data of the base class. Used
+ for custom and promoted widgets.
+
+ Depending on whether an entry exists, the existing or a newly created entry is
+ returned. A return value of 0 indicates that the base class could not be found. */
+
+QDESIGNER_SHARED_EXPORT QDesignerWidgetDataBaseItemInterface *
+ appendDerived(QDesignerWidgetDataBaseInterface *db,
+ const QString &className, const QString &group,
+ const QString &baseClassName,
+ const QString &includeFile,
+ bool promoted, bool custom)
+{
+ if (debugWidgetDataBase)
+ qDebug() << "appendDerived " << className << " derived from " << baseClassName;
+ // Check.
+ if (className.isEmpty() || baseClassName.isEmpty()) {
+ qWarning("** WARNING %s called with an empty class names: '%s' extends '%s'.",
+ Q_FUNC_INFO, className.toUtf8().constData(), baseClassName.toUtf8().constData());
+ return 0;
+ }
+ // Check whether item already exists.
+ QDesignerWidgetDataBaseItemInterface *derivedItem = 0;
+ const int existingIndex = db->indexOfClassName(className);
+ if ( existingIndex != -1)
+ derivedItem = db->item(existingIndex);
+ if (derivedItem) {
+ // Check the existing item for base class mismatch. This will likely
+ // happen when loading a file written by an instance with missing plugins.
+ // In that case, just warn and ignore the file properties.
+ //
+ // An empty base class indicates that it is not known (for example, for custom plugins).
+ // In this case, the widget DB is later updated once the widget is created
+ // by DOM (by querying the metaobject). Suppress the warning.
+ const QString existingBaseClass = derivedItem->extends();
+ if (existingBaseClass.isEmpty() || baseClassName == existingBaseClass)
+ return derivedItem;
+
+ // Warn about mismatches
+ designerWarning(QCoreApplication::translate("WidgetDataBase",
+ "The file contains a custom widget '%1' whose base class (%2)"
+ " differs from the current entry in the widget database (%3)."
+ " The widget database is left unchanged.").
+ arg(className, baseClassName, existingBaseClass));
+ return derivedItem;
+ }
+ // Create this item, inheriting its base properties
+ const int baseIndex = db->indexOfClassName(baseClassName);
+ if (baseIndex == -1) {
+ if (debugWidgetDataBase)
+ qDebug() << "appendDerived failed due to missing base class";
+ return 0;
+ }
+ const QDesignerWidgetDataBaseItemInterface *baseItem = db->item(baseIndex);
+ derivedItem = WidgetDataBaseItem::clone(baseItem);
+ // Sort of hack: If base class is QWidget, we most likely
+ // do not want to inherit the container attribute.
+ static const QString qWidgetName = QLatin1String("QWidget");
+ if (baseItem->name() == qWidgetName)
+ derivedItem->setContainer(false);
+ // set new props
+ derivedItem->setName(className);
+ derivedItem->setGroup(group);
+ derivedItem->setCustom(custom);
+ derivedItem->setPromoted(promoted);
+ derivedItem->setExtends(baseClassName);
+ derivedItem->setIncludeFile(includeFile);
+ db->append(derivedItem);
+ return derivedItem;
+}
+
+/* Return a list of database items to which a class can be promoted to. */
+
+QDESIGNER_SHARED_EXPORT WidgetDataBaseItemList
+ promotionCandidates(const QDesignerWidgetDataBaseInterface *db,
+ const QString &baseClassName)
+{
+ WidgetDataBaseItemList rc;
+ // find existing promoted widgets deriving from base.
+ const int count = db->count();
+ for (int i = 0; i < count; ++i) {
+ QDesignerWidgetDataBaseItemInterface *item = db->item(i);
+ if (item->isPromoted() && item->extends() == baseClassName) {
+ rc.push_back(item);
+ }
+ }
+ return rc;
+}
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/widgetdatabase_p.h b/src/designer/src/lib/shared/widgetdatabase_p.h
new file mode 100644
index 000000000..eb89cb139
--- /dev/null
+++ b/src/designer/src/lib/shared/widgetdatabase_p.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef WIDGETDATABASE_H
+#define WIDGETDATABASE_H
+
+#include "shared_global_p.h"
+
+#include <QtDesigner/QDesignerWidgetDataBaseInterface>
+
+#include <QtGui/QIcon>
+#include <QtCore/QString>
+#include <QtCore/QVariant>
+#include <QtCore/QPair>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+class QDesignerCustomWidgetInterface;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT WidgetDataBaseItem: public QDesignerWidgetDataBaseItemInterface
+{
+public:
+ explicit WidgetDataBaseItem(const QString &name = QString(),
+ const QString &group = QString());
+
+ QString name() const;
+ void setName(const QString &name);
+
+ QString group() const;
+ void setGroup(const QString &group);
+
+ QString toolTip() const;
+ void setToolTip(const QString &toolTip);
+
+ QString whatsThis() const;
+ void setWhatsThis(const QString &whatsThis);
+
+ QString includeFile() const;
+ void setIncludeFile(const QString &includeFile);
+
+
+ QIcon icon() const;
+ void setIcon(const QIcon &icon);
+
+ bool isCompat() const;
+ void setCompat(bool compat);
+
+ bool isContainer() const;
+ void setContainer(bool b);
+
+ bool isCustom() const;
+ void setCustom(bool b);
+
+ QString pluginPath() const;
+ void setPluginPath(const QString &path);
+
+ bool isPromoted() const;
+ void setPromoted(bool b);
+
+ QString extends() const;
+ void setExtends(const QString &s);
+
+ void setDefaultPropertyValues(const QList<QVariant> &list);
+ QList<QVariant> defaultPropertyValues() const;
+
+ static WidgetDataBaseItem *clone(const QDesignerWidgetDataBaseItemInterface *item);
+
+ QStringList fakeSlots() const;
+ void setFakeSlots(const QStringList &);
+
+ QStringList fakeSignals() const;
+ void setFakeSignals(const QStringList &);
+
+ QString addPageMethod() const;
+ void setAddPageMethod(const QString &m);
+
+private:
+ QString m_name;
+ QString m_group;
+ QString m_toolTip;
+ QString m_whatsThis;
+ QString m_includeFile;
+ QString m_pluginPath;
+ QString m_extends;
+ QString m_addPageMethod;
+ QIcon m_icon;
+ uint m_compat: 1;
+ uint m_container: 1;
+ uint m_form: 1;
+ uint m_custom: 1;
+ uint m_promoted: 1;
+ QList<QVariant> m_defaultPropertyValues;
+ QStringList m_fakeSlots;
+ QStringList m_fakeSignals;
+};
+
+enum IncludeType { IncludeLocal, IncludeGlobal };
+
+typedef QPair<QString, IncludeType> IncludeSpecification;
+
+QDESIGNER_SHARED_EXPORT IncludeSpecification includeSpecification(QString includeFile);
+QDESIGNER_SHARED_EXPORT QString buildIncludeFile(QString includeFile, IncludeType includeType);
+
+class QDESIGNER_SHARED_EXPORT WidgetDataBase: public QDesignerWidgetDataBaseInterface
+{
+ Q_OBJECT
+public:
+ explicit WidgetDataBase(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ virtual ~WidgetDataBase();
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual int indexOfObject(QObject *o, bool resolveName = true) const;
+
+ void remove(int index);
+
+
+ void grabDefaultPropertyValues();
+ void grabStandardWidgetBoxIcons();
+
+ // Helpers for 'New Form' wizards in integrations. Obtain a list of suitable classes and generate XML for them.
+ static QStringList formWidgetClasses(const QDesignerFormEditorInterface *core);
+ static QStringList customFormWidgetClasses(const QDesignerFormEditorInterface *core);
+ static QString formTemplate(const QDesignerFormEditorInterface *core, const QString &className, const QString &objectName);
+
+ // Helpers for 'New Form' wizards: Set a fixed size on a XML form template
+ static QString scaleFormTemplate(const QString &xml, const QSize &size, bool fixed);
+
+public slots:
+ void loadPlugins();
+
+private:
+ QList<QVariant> defaultPropertyValues(const QString &name);
+
+ QDesignerFormEditorInterface *m_core;
+};
+
+QDESIGNER_SHARED_EXPORT QDesignerWidgetDataBaseItemInterface
+ *appendDerived(QDesignerWidgetDataBaseInterface *db,
+ const QString &className,
+ const QString &group,
+ const QString &baseClassName,
+ const QString &includeFile,
+ bool promoted,
+ bool custom);
+
+typedef QList<QDesignerWidgetDataBaseItemInterface*> WidgetDataBaseItemList;
+
+QDESIGNER_SHARED_EXPORT WidgetDataBaseItemList
+ promotionCandidates(const QDesignerWidgetDataBaseInterface *db,
+ const QString &baseClassName);
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // WIDGETDATABASE_H
diff --git a/src/designer/src/lib/shared/widgetfactory.cpp b/src/designer/src/lib/shared/widgetfactory.cpp
new file mode 100644
index 000000000..bcd23eed3
--- /dev/null
+++ b/src/designer/src/lib/shared/widgetfactory.cpp
@@ -0,0 +1,899 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "widgetfactory_p.h"
+#include "widgetdatabase_p.h"
+#include "metadatabase_p.h"
+#include "qlayout_widget_p.h"
+#include "qdesigner_widget_p.h"
+#include "qdesigner_tabwidget_p.h"
+#include "qdesigner_toolbox_p.h"
+#include "qdesigner_stackedbox_p.h"
+#include "qdesigner_toolbar_p.h"
+#include "qdesigner_menubar_p.h"
+#include "qdesigner_menu_p.h"
+#include "qdesigner_dockwidget_p.h"
+#include "qdesigner_utils_p.h"
+#include "formwindowbase_p.h"
+
+// shared
+#include "layoutinfo_p.h"
+#include "spacer_widget_p.h"
+#include "layout_p.h"
+#include "abstractintrospection_p.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+
+#include <QtGui/QtGui>
+#include <QtGui/QScrollBar>
+#include <QtGui/QFontComboBox>
+#include <QtGui/QAbstractSpinBox>
+#include <QtGui/QLineEdit>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QWizard>
+#include <QtCore/qdebug.h>
+#include <QtCore/QMetaObject>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN
+static inline bool isAxWidget(const QObject *o)
+{
+ // Is it one of QDesignerAxWidget/QDesignerAxPluginWidget?
+ static const char *axWidgetName = "QDesignerAx";
+ static const unsigned axWidgetNameLen = qstrlen(axWidgetName);
+ return qstrncmp(o->metaObject()->className(), axWidgetName, axWidgetNameLen) == 0;
+}
+#endif
+
+/* Dynamic boolean property indicating object was created by the factory
+ * for the form editor. */
+
+static const char *formEditorDynamicProperty = "_q_formEditorObject";
+
+namespace qdesigner_internal {
+
+// A friendly SpinBox that grants access to its QLineEdit
+class FriendlySpinBox : public QAbstractSpinBox {
+public:
+ friend class WidgetFactory;
+};
+
+// An event filter for form-combo boxes that prevents the embedded line edit
+// from getting edit focus (and drawing blue artifacts/lines). It catches the
+// ChildPolished event when the "editable" property flips to true and the
+// QLineEdit is created and turns off the LineEdit's focus policy.
+
+class ComboEventFilter : public QObject {
+public:
+ explicit ComboEventFilter(QComboBox *parent) : QObject(parent) {}
+ virtual bool eventFilter(QObject *watched, QEvent *event);
+};
+
+bool ComboEventFilter::eventFilter(QObject *watched, QEvent *event)
+{
+ if (event->type() == QEvent::ChildPolished) {
+ QComboBox *cb = static_cast<QComboBox*>(watched);
+ if (QLineEdit *le = cb->lineEdit())
+ le->setFocusPolicy(Qt::NoFocus);
+ }
+ return QObject::eventFilter(watched, event);
+}
+
+/* Watch out for QWizards changing their pages and make sure that not some
+ * selected widget becomes invisible on a hidden page (causing the selection
+ * handles to shine through). Select the wizard in that case in analogy to
+ * the QTabWidget event filters, etc. */
+
+class WizardPageChangeWatcher : public QObject {
+ Q_OBJECT
+public:
+ explicit WizardPageChangeWatcher(QWizard *parent);
+
+public slots:
+ void pageChanged();
+};
+
+WizardPageChangeWatcher::WizardPageChangeWatcher(QWizard *parent) :
+ QObject(parent)
+{
+ connect(parent, SIGNAL(currentIdChanged(int)), this, SLOT(pageChanged()));
+}
+
+void WizardPageChangeWatcher::pageChanged()
+{
+ /* Use a bit more conservative approach than that for the QTabWidget,
+ * change the selection only if a selected child becomes invisible by
+ * changing the page. */
+ QWizard *wizard = static_cast<QWizard *>(parent());
+ QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(wizard);
+ if (!fw)
+ return;
+ QDesignerFormWindowCursorInterface *cursor = fw->cursor();
+ const int selCount = cursor->selectedWidgetCount();
+ for (int i = 0; i < selCount; i++) {
+ if (!cursor->selectedWidget(i)->isVisible()) {
+ fw->clearSelection(false);
+ fw->selectWidget(wizard, true);
+ break;
+ }
+ }
+}
+
+// ---------------- WidgetFactory::Strings
+WidgetFactory::Strings::Strings() :
+ m_alignment(QLatin1String("alignment")),
+ m_bottomMargin(QLatin1String("bottomMargin")),
+ m_geometry(QLatin1String("geometry")),
+ m_leftMargin(QLatin1String("leftMargin")),
+ m_line(QLatin1String("Line")),
+ m_objectName(QLatin1String("objectName")),
+ m_spacerName(QLatin1String("spacerName")),
+ m_orientation(QLatin1String("orientation")),
+ m_q3WidgetStack(QLatin1String("Q3WidgetStack")),
+ m_qAction(QLatin1String("QAction")),
+ m_qButtonGroup(QLatin1String("QButtonGroup")),
+ m_qAxWidget(QLatin1String("QAxWidget")),
+ m_qDialog(QLatin1String("QDialog")),
+ m_qDockWidget(QLatin1String("QDockWidget")),
+ m_qLayoutWidget(QLatin1String("QLayoutWidget")),
+ m_qMenu(QLatin1String("QMenu")),
+ m_qMenuBar(QLatin1String("QMenuBar")),
+ m_qWidget(QLatin1String("QWidget")),
+ m_rightMargin(QLatin1String("rightMargin")),
+ m_sizeHint(QLatin1String("sizeHint")),
+ m_spacer(QLatin1String("Spacer")),
+ m_text(QLatin1String("text")),
+ m_title(QLatin1String("title")),
+ m_topMargin(QLatin1String("topMargin")),
+ m_windowIcon(QLatin1String("windowIcon")),
+ m_windowTitle(QLatin1String("windowTitle"))
+{
+}
+// ---------------- WidgetFactory
+QPointer<QWidget> *WidgetFactory::m_lastPassiveInteractor = new QPointer<QWidget>();
+bool WidgetFactory::m_lastWasAPassiveInteractor = false;
+const char *WidgetFactory::disableStyleCustomPaintingPropertyC = "_q_custom_style_disabled";
+
+WidgetFactory::WidgetFactory(QDesignerFormEditorInterface *core, QObject *parent)
+ : QDesignerWidgetFactoryInterface(parent),
+ m_core(core),
+ m_formWindow(0),
+ m_currentStyle(0)
+{
+}
+
+WidgetFactory::~WidgetFactory()
+{
+}
+
+QDesignerFormWindowInterface *WidgetFactory::currentFormWindow(QDesignerFormWindowInterface *fw)
+{
+ QDesignerFormWindowInterface *was = m_formWindow;
+ m_formWindow = fw;
+ return was;
+}
+
+void WidgetFactory::loadPlugins()
+{
+ m_customFactory.clear();
+
+ QDesignerPluginManager *pluginManager = m_core->pluginManager();
+
+ QList<QDesignerCustomWidgetInterface*> lst = pluginManager->registeredCustomWidgets();
+ foreach (QDesignerCustomWidgetInterface *c, lst) {
+ m_customFactory.insert(c->name(), c);
+ }
+}
+
+// Convencience to create non-widget objects. Returns 0 if unknown
+QObject* WidgetFactory::createObject(const QString &className, QObject* parent) const
+{
+ if (className.isEmpty()) {
+ qWarning("** WARNING %s called with an empty class name", Q_FUNC_INFO);
+ return 0;
+ }
+ if (className == m_strings.m_qAction)
+ return new QAction(parent);
+ if (className == m_strings.m_qButtonGroup)
+ return new QButtonGroup(parent);
+ return 0;
+}
+
+QWidget* WidgetFactory::createCustomWidget(const QString &className, QWidget *parentWidget, bool *creationError) const
+{
+ *creationError = false;
+ CustomWidgetFactoryMap::const_iterator it = m_customFactory.constFind(className);
+ if (it == m_customFactory.constEnd())
+ return 0;
+
+ QDesignerCustomWidgetInterface *factory = it.value();
+ QWidget *rc = factory->createWidget(parentWidget);
+ // shouldn't happen
+ if (!rc) {
+ *creationError = true;
+ designerWarning(tr("The custom widget factory registered for widgets of class %1 returned 0.").arg(className));
+ return 0;
+ }
+ // Figure out the base class unless it is known
+ static QSet<QString> knownCustomClasses;
+ if (!knownCustomClasses.contains(className)) {
+ QDesignerWidgetDataBaseInterface *wdb = m_core->widgetDataBase();
+ const int widgetInfoIndex = wdb->indexOfObject(rc, false);
+ if (widgetInfoIndex != -1) {
+ if (wdb->item(widgetInfoIndex)->extends().isEmpty()) {
+ const QDesignerMetaObjectInterface *mo = core()->introspection()->metaObject(rc)->superClass();
+ // If we hit on a 'Q3DesignerXXWidget' that claims to be a 'Q3XXWidget', step
+ // over.
+ if (mo && mo->className() == className)
+ mo = mo->superClass();
+ while (mo != 0) {
+ if (core()->widgetDataBase()->indexOfClassName(mo->className()) != -1) {
+ wdb->item(widgetInfoIndex)->setExtends(mo->className());
+ break;
+ }
+ mo = mo->superClass();
+ }
+ }
+ knownCustomClasses.insert(className);
+ }
+ }
+ // Since a language plugin may lie about its names, like Qt Jambi
+ // does, return immediately here...
+ QDesignerLanguageExtension *lang =
+ qt_extension<QDesignerLanguageExtension *>(m_core->extensionManager(), m_core);
+ if (lang)
+ return rc;
+
+#ifdef Q_OS_WIN
+ if (isAxWidget(rc))
+ return rc;
+#endif
+ // Check for mismatched class names which is hard to track.
+ // Perform literal comparison first for QAxWidget, for which a meta object hack is in effect.
+ const char *createdClassNameC = rc->metaObject()->className();
+ const QByteArray classNameB = className.toUtf8();
+ const char *classNameC = classNameB.constData();
+
+ if (qstrcmp(createdClassNameC, classNameC) && !rc->inherits(classNameC))
+ designerWarning(tr("A class name mismatch occurred when creating a widget using the custom widget factory registered for widgets of class %1."
+ " It returned a widget of class %2.").arg(className).arg(QString::fromUtf8(createdClassNameC)));
+ return rc;
+}
+
+
+QWidget *WidgetFactory::createWidget(const QString &widgetName, QWidget *parentWidget) const
+{
+ if (widgetName.isEmpty()) {
+ qWarning("** WARNING %s called with an empty class name", Q_FUNC_INFO);
+ return 0;
+ }
+ // Preview or for form window?
+ QDesignerFormWindowInterface *fw = m_formWindow;
+ if (! fw)
+ fw = QDesignerFormWindowInterface::findFormWindow(parentWidget);
+
+ QWidget *w = 0;
+ do {
+ // 1) custom. If there is an explicit failure(factory wants to indicate something is wrong),
+ // return 0, do not try to find fallback, which might be worse in the case of Q3 widget.
+ bool customWidgetCreationError;
+ w = createCustomWidget(widgetName, parentWidget, &customWidgetCreationError);
+ if (w) {
+ break;
+ } else {
+ if (customWidgetCreationError)
+ return 0;
+ }
+
+ // 2) Special widgets
+ if (widgetName == m_strings.m_line) {
+ w = new Line(parentWidget);
+ } else if (widgetName == m_strings.m_qDockWidget) {
+ w = new QDesignerDockWidget(parentWidget);
+ } else if (widgetName == m_strings.m_qMenuBar) {
+ w = new QDesignerMenuBar(parentWidget);
+ } else if (widgetName == m_strings.m_qMenu) {
+ w = new QDesignerMenu(parentWidget);
+ } else if (widgetName == m_strings.m_spacer) {
+ w = new Spacer(parentWidget);
+ } else if (widgetName == m_strings.m_qDockWidget) {
+ w = new QDesignerDockWidget(parentWidget);
+ } else if (widgetName == m_strings.m_qLayoutWidget) {
+ w = fw ? new QLayoutWidget(fw, parentWidget) : new QWidget(parentWidget);
+ } else if (widgetName == m_strings.m_qDialog) {
+ if (fw) {
+ w = new QDesignerDialog(fw, parentWidget);
+ } else {
+ w = new QDialog(parentWidget);
+ }
+ } else if (widgetName == m_strings.m_qWidget) {
+ /* We want a 'QDesignerWidget' that draws a grid only for widget
+ * forms and container extension pages (not for preview and not
+ * for normal QWidget children on forms (legacy) */
+ if (fw && parentWidget) {
+ if (qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), parentWidget)) {
+ w = new QDesignerWidget(fw, parentWidget);
+ } else {
+ if (const FormWindowBase *fwb = qobject_cast<FormWindowBase *>(fw))
+ if (parentWidget == fwb->formContainer())
+ w = new QDesignerWidget(fw, parentWidget);
+ }
+ }
+ if (!w)
+ w = new QWidget(parentWidget);
+ }
+ if (w)
+ break;
+
+ // 3) table
+ const QByteArray widgetNameBA = widgetName.toUtf8();
+ const char *widgetNameC = widgetNameBA.constData();
+
+ if (w) { // symmetry for macro
+ }
+
+#define DECLARE_LAYOUT(L, C)
+#define DECLARE_COMPAT_WIDGET(W, C) /*DECLARE_WIDGET(W, C)*/
+#define DECLARE_WIDGET(W, C) else if (!qstrcmp(widgetNameC, #W)) { Q_ASSERT(w == 0); w = new W(parentWidget); }
+#define DECLARE_WIDGET_1(W, C) else if (!qstrcmp(widgetNameC, #W)) { Q_ASSERT(w == 0); w = new W(0, parentWidget); }
+
+#include "widgets.table"
+
+#undef DECLARE_COMPAT_WIDGET
+#undef DECLARE_LAYOUT
+#undef DECLARE_WIDGET
+#undef DECLARE_WIDGET_1
+
+ if (w)
+ break;
+ // 4) fallBack
+ const QString fallBackBaseClass = m_strings.m_qWidget;
+ QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
+ QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfClassName(widgetName));
+ if (item == 0) {
+ // Emergency: Create, derived from QWidget
+ QString includeFile = widgetName.toLower();
+ includeFile += QLatin1String(".h");
+ item = appendDerived(db,widgetName, tr("%1 Widget").arg(widgetName),fallBackBaseClass,
+ includeFile, true, true);
+ Q_ASSERT(item);
+ }
+ QString baseClass = item->extends();
+ if (baseClass.isEmpty()) {
+ // Currently happens in the case of Q3-Support widgets
+ baseClass =fallBackBaseClass;
+ }
+ if (QWidget *promotedWidget = createWidget(baseClass, parentWidget)) {
+ promoteWidget(core(), promotedWidget, widgetName);
+ return promotedWidget; // Do not initialize twice.
+ }
+ } while (false);
+
+ Q_ASSERT(w != 0);
+ if (m_currentStyle)
+ w->setStyle(m_currentStyle);
+ initializeCommon(w);
+ if (fw) { // form editor initialization
+ initialize(w);
+ } else { // preview-only initialization
+ initializePreview(w);
+ }
+ return w;
+}
+
+QString WidgetFactory::classNameOf(QDesignerFormEditorInterface *c, const QObject* o)
+{
+ if (o == 0)
+ return QString();
+
+ const char *className = o->metaObject()->className();
+ if (!o->isWidgetType())
+ return QLatin1String(className);
+ const QWidget *w = static_cast<const QWidget*>(o);
+ // check promoted before designer special
+ const QString customClassName = promotedCustomClassName(c, const_cast<QWidget*>(w));
+ if (!customClassName.isEmpty())
+ return customClassName;
+ if (qobject_cast<const QDesignerMenuBar*>(w))
+ return QLatin1String("QMenuBar");
+ else if (qobject_cast<const QDesignerMenu*>(w))
+ return QLatin1String("QMenu");
+ else if (qobject_cast<const QDesignerDockWidget*>(w))
+ return QLatin1String("QDockWidget");
+ else if (qobject_cast<const QDesignerDialog*>(w))
+ return QLatin1String("QDialog");
+ else if (qobject_cast<const QDesignerWidget*>(w))
+ return QLatin1String("QWidget");
+#ifdef Q_OS_WIN
+ else if (isAxWidget(w))
+ return QLatin1String("QAxWidget");
+#endif
+ else if (qstrcmp(className, "QDesignerQ3WidgetStack") == 0)
+ return QLatin1String("Q3WidgetStack");
+
+ return QLatin1String(className);
+}
+
+QLayout *WidgetFactory::createUnmanagedLayout(QWidget *parentWidget, int type)
+{
+ switch (type) {
+ case LayoutInfo::HBox:
+ return new QHBoxLayout(parentWidget);
+ case LayoutInfo::VBox:
+ return new QVBoxLayout(parentWidget);
+ case LayoutInfo::Grid:
+ return new QGridLayout(parentWidget);
+ case LayoutInfo::Form:
+ return new QFormLayout(parentWidget);
+ default:
+ Q_ASSERT(0);
+ break;
+ }
+ return 0;
+}
+
+
+/*! Creates a layout on the widget \a widget of the type \a type
+ which can be \c HBox, \c VBox or \c Grid.
+*/
+
+QLayout *WidgetFactory::createLayout(QWidget *widget, QLayout *parentLayout, int type) const // ### (sizepolicy)
+{
+ QDesignerMetaDataBaseInterface *metaDataBase = core()->metaDataBase();
+
+ if (parentLayout == 0) {
+ QWidget *page = containerOfWidget(widget);
+ if (page) {
+ widget = page;
+ } else {
+ const QString msg = tr("The current page of the container '%1' (%2) could not be determined while creating a layout."
+"This indicates an inconsistency in the ui-file, probably a layout being constructed on a container widget.").arg(widget->objectName()).arg(classNameOf(core(), widget));
+ designerWarning(msg);
+ }
+ }
+
+ Q_ASSERT(metaDataBase->item(widget) != 0); // ensure the widget is managed
+
+ if (parentLayout == 0 && metaDataBase->item(widget->layout()) == 0) {
+ parentLayout = widget->layout();
+ }
+
+ QWidget *parentWidget = parentLayout != 0 ? 0 : widget;
+
+ QLayout *layout = createUnmanagedLayout(parentWidget, type);
+ metaDataBase->add(layout); // add the layout in the MetaDataBase
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), layout);
+
+ sheet->setChanged(sheet->indexOf(m_strings.m_objectName), true);
+ if (widget->inherits("Q3GroupBox")) {
+ layout->setContentsMargins(widget->style()->pixelMetric(QStyle::PM_LayoutLeftMargin),
+ widget->style()->pixelMetric(QStyle::PM_LayoutTopMargin),
+ widget->style()->pixelMetric(QStyle::PM_LayoutRightMargin),
+ widget->style()->pixelMetric(QStyle::PM_LayoutBottomMargin));
+ QGridLayout *grid = qobject_cast<QGridLayout *>(layout);
+ if (grid) {
+ grid->setHorizontalSpacing(-1);
+ grid->setVerticalSpacing(-1);
+ } else {
+ layout->setSpacing(-1);
+ }
+ layout->setAlignment(Qt::AlignTop);
+ // Just to ensure; before 4.3 orientation property was always set (now only for QSplitter class).
+ // Calling Q3GroupBox::setOrientation() invoked in turn setSpacing(0). Below fixes that
+ widget->layout()->setSpacing(-1);
+ } else if (widget->inherits("QLayoutWidget")) {
+ sheet->setProperty(sheet->indexOf(m_strings.m_leftMargin), 0);
+ sheet->setProperty(sheet->indexOf(m_strings.m_topMargin), 0);
+ sheet->setProperty(sheet->indexOf(m_strings.m_rightMargin), 0);
+ sheet->setProperty(sheet->indexOf(m_strings.m_bottomMargin), 0);
+ }
+
+ if (sheet) {
+ const int index = sheet->indexOf(m_strings.m_alignment);
+ if (index != -1)
+ sheet->setChanged(index, true);
+ }
+
+ if (metaDataBase->item(widget->layout()) == 0) {
+ Q_ASSERT(layout->parent() == 0);
+ QBoxLayout *box = qobject_cast<QBoxLayout*>(widget->layout());
+ if (!box) { // we support only unmanaged box layouts
+ const QString msg = tr("Attempt to add a layout to a widget '%1' (%2) which already has an unmanaged layout of type %3.\n"
+ "This indicates an inconsistency in the ui-file.").
+ arg(widget->objectName()).arg(classNameOf(core(), widget)).arg(classNameOf(core(), widget->layout()));
+ designerWarning(msg);
+ return 0;
+ }
+ box->addLayout(layout);
+ }
+
+ return layout;
+}
+
+/*! Returns the widget into which children should be inserted when \a
+ w is a container known to designer.
+
+ Usually, it is \a w itself, but there are exceptions (for example, a
+ tabwidget is known to designer as a container, but the child
+ widgets should be inserted into the current page of the
+ tabwidget. In this case, the current page of
+ the tabwidget would be returned.)
+ */
+QWidget* WidgetFactory::containerOfWidget(QWidget *w) const
+{
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), w))
+ return container->widget(container->currentIndex());
+
+ return w;
+}
+
+/*! Returns the actual designer widget of the container \a w. This is
+ normally \a w itself, but it might be a parent or grand parent of \a w
+ (for example, when working with a tabwidget and \a w is the container which
+ contains and layouts children, but the actual widget known to
+ designer is the tabwidget which is the parent of \a w. In this case,
+ the tabwidget would be returned.)
+*/
+
+QWidget* WidgetFactory::widgetOfContainer(QWidget *w) const
+{
+ // ### cleanup
+ if (!w)
+ return 0;
+ if (w->parentWidget() && w->parentWidget()->parentWidget() &&
+ w->parentWidget()->parentWidget()->parentWidget() &&
+ qobject_cast<QToolBox*>(w->parentWidget()->parentWidget()->parentWidget()))
+ return w->parentWidget()->parentWidget()->parentWidget();
+
+ while (w != 0) {
+ if (core()->widgetDataBase()->isContainer(w) ||
+ (w && qobject_cast<QDesignerFormWindowInterface*>(w->parentWidget())))
+ return w;
+
+ w = w->parentWidget();
+ }
+
+ return w;
+}
+
+QDesignerFormEditorInterface *WidgetFactory::core() const
+{
+ return m_core;
+}
+
+// Necessary initializations for form editor/preview objects
+void WidgetFactory::initializeCommon(QWidget *widget) const
+{
+ // Apply style
+ if (m_currentStyle)
+ widget->setStyle(m_currentStyle);
+ // Prevent the wizard from emulating the Windows Vista Theme.
+ // This theme (in both Aero and Basic mode) is tricky to
+ // emulate properly in designer due to 1) the manipulation of the non-client area of
+ // the top-level window, and 2) the upper-right location of the Back button.
+ // The wizard falls back to QWizard::ModernStyle whenever the Vista theme
+ // would normally apply.
+ if (QWizard *wizard = qobject_cast<QWizard *>(widget)) {
+ wizard->setProperty("_q_wizard_vista_off", QVariant(true));
+ return;
+ }
+}
+
+// Necessary initializations for preview objects
+void WidgetFactory::initializePreview(QWidget *widget) const
+{
+
+ if (QStackedWidget *stackedWidget = qobject_cast<QStackedWidget*>(widget)) {
+ QStackedWidgetPreviewEventFilter::install(stackedWidget); // Add browse button only.
+ return;
+ }
+}
+
+// Necessary initializations for form editor objects
+void WidgetFactory::initialize(QObject *object) const
+{
+ // Indicate that this is a form object (for QDesignerFormWindowInterface::findFormWindow)
+ object->setProperty(formEditorDynamicProperty, QVariant(true));
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_core->extensionManager(), object);
+ if (!sheet)
+ return;
+
+ sheet->setChanged(sheet->indexOf(m_strings.m_objectName), true);
+
+ if (!object->isWidgetType()) {
+ if (qobject_cast<QAction*>(object))
+ sheet->setChanged(sheet->indexOf(m_strings.m_text), true);
+ return;
+ }
+
+ QWidget *widget = static_cast<QWidget*>(object);
+ const bool isMenu = qobject_cast<QMenu*>(widget);
+ const bool isMenuBar = !isMenu && qobject_cast<QMenuBar*>(widget);
+
+ widget->setAttribute(Qt::WA_TransparentForMouseEvents, false);
+ widget->setFocusPolicy((isMenu || isMenuBar) ? Qt::StrongFocus : Qt::NoFocus);
+
+ if (!isMenu)
+ sheet->setChanged(sheet->indexOf(m_strings.m_geometry), true);
+
+ if (qobject_cast<Spacer*>(widget)) {
+ sheet->setChanged(sheet->indexOf(m_strings.m_spacerName), true);
+ return;
+ }
+
+ const int o = sheet->indexOf(m_strings.m_orientation);
+ if (o != -1 && widget->inherits("QSplitter"))
+ sheet->setChanged(o, true);
+
+ if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget)) {
+ ToolBarEventFilter::install(toolBar);
+ sheet->setVisible(sheet->indexOf(m_strings.m_windowTitle), true);
+ toolBar->setFloatable(false); // prevent toolbars from being dragged off
+ return;
+ }
+
+ if (qobject_cast<QDockWidget*>(widget)) {
+ sheet->setVisible(sheet->indexOf(m_strings.m_windowTitle), true);
+ sheet->setVisible(sheet->indexOf(m_strings.m_windowIcon), true);
+ return;
+ }
+
+ if (isMenu) {
+ sheet->setChanged(sheet->indexOf(m_strings.m_title), true);
+ return;
+ }
+ // helpers
+ if (QToolBox *toolBox = qobject_cast<QToolBox*>(widget)) {
+ QToolBoxHelper::install(toolBox);
+ return;
+ }
+ if (QStackedWidget *stackedWidget = qobject_cast<QStackedWidget*>(widget)) {
+ QStackedWidgetEventFilter::install(stackedWidget);
+ return;
+ }
+ if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(widget)) {
+ QTabWidgetEventFilter::install(tabWidget);
+ return;
+ }
+ // Prevent embedded line edits from getting focus
+ if (QAbstractSpinBox *asb = qobject_cast<QAbstractSpinBox *>(widget)) {
+ if (QLineEdit *lineEdit = static_cast<FriendlySpinBox*>(asb)->lineEdit())
+ lineEdit->setFocusPolicy(Qt::NoFocus);
+ return;
+ }
+ if (QComboBox *cb = qobject_cast<QComboBox *>(widget)) {
+ if (QFontComboBox *fcb = qobject_cast<QFontComboBox *>(widget)) {
+ fcb->lineEdit()->setFocusPolicy(Qt::NoFocus); // Always present
+ return;
+ }
+ cb->installEventFilter(new ComboEventFilter(cb));
+ return;
+ }
+ if (QWizard *wz = qobject_cast<QWizard *>(widget)) {
+ WizardPageChangeWatcher *pw = new WizardPageChangeWatcher(wz);
+ Q_UNUSED(pw);
+ }
+}
+
+static inline QString classNameOfStyle(const QStyle *s)
+{
+ return QLatin1String(s->metaObject()->className());
+}
+
+QString WidgetFactory::styleName() const
+{
+ return classNameOfStyle(style());
+}
+
+static inline bool isApplicationStyle(const QString &styleName)
+{
+ return styleName.isEmpty() || styleName == classNameOfStyle(qApp->style());
+}
+
+void WidgetFactory::setStyleName(const QString &styleName)
+{
+ m_currentStyle = isApplicationStyle(styleName) ? static_cast<QStyle*>(0) : getStyle(styleName);
+}
+
+QStyle *WidgetFactory::style() const
+{
+ return m_currentStyle ? m_currentStyle : qApp->style();
+}
+
+QStyle *WidgetFactory::getStyle(const QString &styleName)
+{
+ if (isApplicationStyle(styleName))
+ return qApp->style();
+
+ StyleCache::iterator it = m_styleCache.find(styleName);
+ if (it == m_styleCache.end()) {
+ QStyle *style = QStyleFactory::create(styleName);
+ if (!style) {
+ const QString msg = tr("Cannot create style '%1'.").arg(styleName);
+ designerWarning(msg);
+ return 0;
+ }
+ it = m_styleCache.insert(styleName, style);
+ }
+ return it.value();
+}
+
+void WidgetFactory::applyStyleTopLevel(const QString &styleName, QWidget *w)
+{
+ if (QStyle *style = getStyle(styleName))
+ applyStyleToTopLevel(style, w);
+}
+
+void WidgetFactory::applyStyleToTopLevel(QStyle *style, QWidget *widget)
+{
+ if (!style)
+ return;
+ const QPalette standardPalette = style->standardPalette();
+ if (widget->style() == style && widget->palette() == standardPalette)
+ return;
+
+ widget->setStyle(style);
+ widget->setPalette(standardPalette);
+ const QWidgetList lst = widget->findChildren<QWidget*>();
+ const QWidgetList::const_iterator cend = lst.constEnd();
+ for (QWidgetList::const_iterator it = lst.constBegin(); it != cend; ++it)
+ (*it)->setStyle(style);
+}
+
+// Check for 'interactor' click on a tab bar,
+// which can appear within a QTabWidget or as a standalone widget.
+
+static bool isTabBarInteractor(const QTabBar *tabBar)
+{
+ // Tabbar embedded in Q(Designer)TabWidget, ie, normal tab widget case
+ if (qobject_cast<const QTabWidget*>(tabBar->parentWidget()))
+ return true;
+
+ // Standalone tab bar on the form. Return true for tab rect areas
+ // only to allow the user to select the tab bar by clicking outside the actual tabs.
+ const int count = tabBar->count();
+ if (count == 0)
+ return false;
+
+ // click into current tab: No Interaction
+ const int currentIndex = tabBar->currentIndex();
+ const QPoint pos = tabBar->mapFromGlobal(QCursor::pos());
+ if (tabBar->tabRect(currentIndex).contains(pos))
+ return false;
+
+ // click outside: No Interaction
+ const QRect geometry = QRect(QPoint(0, 0), tabBar->size());
+ if (!geometry.contains(pos))
+ return false;
+ // click into another tab: Let's interact, switch tabs.
+ for (int i = 0; i < count; i++)
+ if (tabBar->tabRect(i).contains(pos))
+ return true;
+ return false;
+}
+
+bool WidgetFactory::isPassiveInteractor(QWidget *widget)
+{
+ static const QString qtPassive = QLatin1String("__qt__passive_");
+ if (m_lastPassiveInteractor != 0 && (QWidget*)(*m_lastPassiveInteractor) == widget)
+ return m_lastWasAPassiveInteractor;
+
+ if (QApplication::activePopupWidget() || widget == 0) // if a popup is open, we have to make sure that this one is closed, else X might do funny things
+ return true;
+
+ m_lastWasAPassiveInteractor = false;
+ (*m_lastPassiveInteractor) = widget;
+
+ if (const QTabBar *tabBar = qobject_cast<const QTabBar*>(widget)) {
+ if (isTabBarInteractor(tabBar))
+ m_lastWasAPassiveInteractor = true;
+ return m_lastWasAPassiveInteractor;
+#ifndef QT_NO_SIZEGRIP
+ } else if (qobject_cast<QSizeGrip*>(widget)) {
+ return (m_lastWasAPassiveInteractor = true);
+#endif
+ } else if (qobject_cast<QMdiSubWindow*>(widget))
+ return (m_lastWasAPassiveInteractor = true);
+ else if (qobject_cast<QAbstractButton*>(widget) && (qobject_cast<QTabBar*>(widget->parent()) || qobject_cast<QToolBox*>(widget->parent())))
+ return (m_lastWasAPassiveInteractor = true);
+ else if (qobject_cast<QMenuBar*>(widget))
+ return (m_lastWasAPassiveInteractor = true);
+ else if (qobject_cast<QToolBar*>(widget))
+ return (m_lastWasAPassiveInteractor = true);
+ else if (qobject_cast<QScrollBar*>(widget)) {
+ // A scroll bar is an interactor on a QAbstractScrollArea only.
+ if (const QWidget *parent = widget->parentWidget()) {
+ const QString objectName = parent->objectName();
+ static const QString scrollAreaVContainer = QLatin1String("qt_scrollarea_vcontainer");
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+ void formWindowAdded(QDesignerFormWindowInterface *formWindow);
+ static const QString scrollAreaHContainer = QLatin1String("qt_scrollarea_hcontainer");
+ if (objectName == scrollAreaVContainer || objectName == scrollAreaHContainer) {
+ m_lastWasAPassiveInteractor = true;
+ return m_lastWasAPassiveInteractor;
+ }
+ }
+ } else if (qstrcmp(widget->metaObject()->className(), "QDockWidgetTitle") == 0)
+ return (m_lastWasAPassiveInteractor = true);
+ else if (qstrcmp(widget->metaObject()->className(), "QWorkspaceTitleBar") == 0)
+ return (m_lastWasAPassiveInteractor = true);
+ else if (widget->objectName().startsWith(qtPassive))
+ return (m_lastWasAPassiveInteractor = true);
+ return m_lastWasAPassiveInteractor;
+}
+
+void WidgetFactory::formWindowAdded(QDesignerFormWindowInterface *formWindow)
+{
+ setFormWindowStyle(formWindow);
+}
+
+void WidgetFactory::activeFormWindowChanged(QDesignerFormWindowInterface *formWindow)
+{
+ setFormWindowStyle(formWindow);
+}
+
+void WidgetFactory::setFormWindowStyle(QDesignerFormWindowInterface *formWindow)
+{
+ if (FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow))
+ setStyleName(fwb->styleName());
+}
+
+bool WidgetFactory::isFormEditorObject(const QObject *object)
+{
+ return object->property(formEditorDynamicProperty).isValid();
+}
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#include "widgetfactory.moc"
diff --git a/src/designer/src/lib/shared/widgetfactory_p.h b/src/designer/src/lib/shared/widgetfactory_p.h
new file mode 100644
index 000000000..994731c41
--- /dev/null
+++ b/src/designer/src/lib/shared/widgetfactory_p.h
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef WIDGETFACTORY_H
+#define WIDGETFACTORY_H
+
+#include "shared_global_p.h"
+#include "pluginmanager_p.h"
+
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+
+#include <QtCore/QMap>
+#include <QtCore/QHash>
+#include <QtCore/QVariant>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+class QWidget;
+class QLayout;
+class QDesignerFormEditorInterface;
+class QDesignerCustomWidgetInterface;
+class QDesignerFormWindowInterface;
+class QStyle;
+
+namespace qdesigner_internal {
+
+class QDESIGNER_SHARED_EXPORT WidgetFactory: public QDesignerWidgetFactoryInterface
+{
+ Q_OBJECT
+public:
+ explicit WidgetFactory(QDesignerFormEditorInterface *core, QObject *parent = 0);
+ ~WidgetFactory();
+
+ virtual QWidget* containerOfWidget(QWidget *widget) const;
+ virtual QWidget* widgetOfContainer(QWidget *widget) const;
+
+ QObject* createObject(const QString &className, QObject* parent) const;
+
+ virtual QWidget *createWidget(const QString &className, QWidget *parentWidget) const;
+ virtual QLayout *createLayout(QWidget *widget, QLayout *layout, int type) const;
+
+ virtual bool isPassiveInteractor(QWidget *widget);
+ virtual void initialize(QObject *object) const;
+ void initializeCommon(QWidget *object) const;
+ void initializePreview(QWidget *object) const;
+
+
+ virtual QDesignerFormEditorInterface *core() const;
+
+ static QString classNameOf(QDesignerFormEditorInterface *core, const QObject* o);
+
+ QDesignerFormWindowInterface *currentFormWindow(QDesignerFormWindowInterface *fw);
+
+ static QLayout *createUnmanagedLayout(QWidget *parentWidget, int type);
+
+ // The widget factory maintains a cache of styles which it owns.
+ QString styleName() const;
+ void setStyleName(const QString &styleName);
+
+ /* Return a cached style matching the name or QApplication's style if
+ * it is the default. */
+ QStyle *getStyle(const QString &styleName);
+ // Return the current style used by the factory. This either a cached one
+ // or QApplication's style */
+ QStyle *style() const;
+
+ // Apply one of the cached styles or QApplication's style to a toplevel widget.
+ void applyStyleTopLevel(const QString &styleName, QWidget *w);
+ static void applyStyleToTopLevel(QStyle *style, QWidget *widget);
+
+ // Return whether object was created by the factory for the form editor.
+ static bool isFormEditorObject(const QObject *o);
+
+ // Boolean dynamic property to set on widgets to prevent custom
+ // styles from interfering
+ static const char *disableStyleCustomPaintingPropertyC;
+
+public slots:
+ void loadPlugins();
+
+private slots:
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+ void formWindowAdded(QDesignerFormWindowInterface *formWindow);
+
+private:
+ struct Strings { // Reduce string allocations by storing predefined strings
+ Strings();
+ const QString m_alignment;
+ const QString m_bottomMargin;
+ const QString m_geometry;
+ const QString m_leftMargin;
+ const QString m_line;
+ const QString m_objectName;
+ const QString m_spacerName;
+ const QString m_orientation;
+ const QString m_q3WidgetStack;
+ const QString m_qAction;
+ const QString m_qButtonGroup;
+ const QString m_qAxWidget;
+ const QString m_qDialog;
+ const QString m_qDockWidget;
+ const QString m_qLayoutWidget;
+ const QString m_qMenu;
+ const QString m_qMenuBar;
+ const QString m_qWidget;
+ const QString m_rightMargin;
+ const QString m_sizeHint;
+ const QString m_spacer;
+ const QString m_text;
+ const QString m_title;
+ const QString m_topMargin;
+ const QString m_windowIcon;
+ const QString m_windowTitle;
+ };
+
+ QWidget* createCustomWidget(const QString &className, QWidget *parentWidget, bool *creationError) const;
+ QDesignerFormWindowInterface *findFormWindow(QWidget *parentWidget) const;
+ void setFormWindowStyle(QDesignerFormWindowInterface *formWindow);
+
+ const Strings m_strings;
+ QDesignerFormEditorInterface *m_core;
+ typedef QMap<QString, QDesignerCustomWidgetInterface*> CustomWidgetFactoryMap;
+ CustomWidgetFactoryMap m_customFactory;
+ QDesignerFormWindowInterface *m_formWindow;
+
+ // Points to the cached style or 0 if the default (qApp) is active
+ QStyle *m_currentStyle;
+ typedef QHash<QString, QStyle *> StyleCache;
+ StyleCache m_styleCache;
+
+ static QPointer<QWidget> *m_lastPassiveInteractor;
+ static bool m_lastWasAPassiveInteractor;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif // WIDGETFACTORY_H
diff --git a/src/designer/src/lib/shared/zoomwidget.cpp b/src/designer/src/lib/shared/zoomwidget.cpp
new file mode 100644
index 000000000..c77a518fe
--- /dev/null
+++ b/src/designer/src/lib/shared/zoomwidget.cpp
@@ -0,0 +1,570 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "zoomwidget_p.h"
+
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QGraphicsProxyWidget>
+#include <QtGui/QMenu>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QScrollBar>
+
+#include <QtCore/QTextStream>
+#include <QtCore/qmath.h>
+#include <QtCore/QDebug>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<QAction*> ActionList;
+typedef QList<QGraphicsItem *> GraphicsItemList;
+
+enum { debugZoomWidget = 0 };
+
+static const int menuZoomList[] = { 100, 25, 50, 75, 125, 150 , 175, 200 };
+
+static inline QSize qCeiling(const QSizeF &s)
+{
+ return QSize(qCeil(s.width()), qCeil(s.height()));
+}
+
+namespace qdesigner_internal {
+
+// ---------- ZoomMenu
+
+ZoomMenu::ZoomMenu(QObject *parent) :
+ QObject(parent),
+ m_menuActions(new QActionGroup(this))
+{
+ connect(m_menuActions, SIGNAL(triggered(QAction*)), this, SLOT(slotZoomMenu(QAction*)));
+ const int nz = sizeof(menuZoomList)/sizeof(int);
+ for (int i = 0; i < nz; i++) {
+ const int zoom = menuZoomList[i];
+ //: Zoom factor
+ QAction *a = m_menuActions->addAction(tr("%1 %").arg(zoom));
+ a->setCheckable(true);
+ a->setData(QVariant(zoom));
+ if (zoom == 100)
+ a->setChecked(true);
+ m_menuActions->addAction(a);
+ }
+}
+
+int ZoomMenu::zoomOf(const QAction *a)
+{
+ return a->data().toInt();
+}
+
+void ZoomMenu::addActions(QMenu *m)
+{
+ const ActionList za = m_menuActions->actions();
+ const ActionList::const_iterator cend = za.constEnd();
+ for (ActionList::const_iterator it = za.constBegin(); it != cend; ++it) {
+ m->addAction(*it);
+ if (zoomOf(*it) == 100)
+ m->addSeparator();
+ }
+}
+
+int ZoomMenu::zoom() const
+{
+ return m_menuActions->checkedAction()->data().toInt();
+}
+
+void ZoomMenu::setZoom(int percent)
+{
+ const ActionList za = m_menuActions->actions();
+ const ActionList::const_iterator cend = za.constEnd();
+ for (ActionList::const_iterator it = za.constBegin(); it != cend; ++it)
+ if (zoomOf(*it) == percent) {
+ (*it)->setChecked(true);
+ return;
+ }
+}
+
+void ZoomMenu::slotZoomMenu(QAction *a)
+{
+ emit zoomChanged(zoomOf(a));
+}
+
+QList<int> ZoomMenu::zoomValues()
+{
+ QList<int> rc;
+ const int nz = sizeof(menuZoomList)/sizeof(int);
+ for (int i = 0; i < nz; i++)
+ rc.push_back(menuZoomList[i]);
+ return rc;
+}
+
+// --------- ZoomView
+ZoomView::ZoomView(QWidget *parent) :
+ QGraphicsView(parent),
+ m_scene(new QGraphicsScene(this)),
+ m_zoom(100),
+ m_zoomFactor(1.0),
+ m_zoomContextMenuEnabled(false),
+ m_zoomMenu(0)
+{
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setFrameShape(QFrame::NoFrame);
+ setScene(m_scene);
+ if (debugZoomWidget)
+ qDebug() << "scene" << m_scene->sceneRect();
+
+}
+
+int ZoomView::zoom() const
+{
+ return m_zoom;
+}
+
+void ZoomView::scrollToOrigin()
+{
+ const QPoint origin(0 ,0);
+ const QPoint current = scrollPosition();
+ if (current != origin) {
+ if (debugZoomWidget)
+ qDebug() << "ZoomView::scrollToOrigin from " << current;
+ setScrollPosition(origin);
+ }
+}
+
+void ZoomView::setZoom(int percent)
+{
+ if (debugZoomWidget)
+ qDebug() << "ZoomView::setZoom" << percent;
+
+ if (m_zoom == percent)
+ return;
+
+ m_zoom = percent;
+ const qreal hundred = 100.0;
+ m_zoomFactor = static_cast<qreal>(m_zoom) / hundred;
+
+ applyZoom();
+ if (m_zoomMenu) // Do not force them into existence
+ m_zoomMenu->setZoom(m_zoom);
+
+ resetTransform();
+ scale(m_zoomFactor, m_zoomFactor);
+}
+
+void ZoomView::applyZoom()
+{
+}
+
+qreal ZoomView::zoomFactor() const
+{
+ return m_zoomFactor;
+}
+
+bool ZoomView::isZoomContextMenuEnabled() const
+{
+ return m_zoomContextMenuEnabled;
+}
+
+void ZoomView::setZoomContextMenuEnabled(bool e)
+{
+ m_zoomContextMenuEnabled = e;
+}
+
+ZoomMenu *ZoomView::zoomMenu()
+{
+ if (!m_zoomMenu) {
+ m_zoomMenu = new ZoomMenu(this);
+ m_zoomMenu->setZoom(m_zoom);
+ connect(m_zoomMenu, SIGNAL(zoomChanged(int)), this, SLOT(setZoom(int)));
+ }
+ return m_zoomMenu;
+}
+
+void ZoomView::contextMenuEvent(QContextMenuEvent *event)
+{
+ if (debugZoomWidget > 1)
+ qDebug() << "ZoomView::contextMenuEvent" << event->pos() << event->globalPos() << zoom() << '%';
+
+ if (m_zoomContextMenuEnabled) {
+ showContextMenu(event->globalPos());
+ } else {
+ QGraphicsView::contextMenuEvent(event);
+ }
+}
+
+void ZoomView::showContextMenu(const QPoint &globalPos)
+{
+ QMenu menu;
+ zoomMenu()->addActions(&menu);
+ if (debugZoomWidget) {
+ menu.addSeparator();
+ QAction *da = menu.addAction(QLatin1String("Dump"));
+ connect(da, SIGNAL(triggered()), this, SLOT(dump()));
+ }
+ menu.exec(globalPos);
+}
+
+QPoint ZoomView::scrollPosition() const
+{
+ return QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value());
+}
+
+void ZoomView::setScrollPosition(const QPoint& pos)
+{
+ horizontalScrollBar()->setValue(pos.x());
+ verticalScrollBar()->setValue(pos.y());
+}
+
+// -------------- ZoomProxyWidget
+ZoomProxyWidget::ZoomProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) :
+ QGraphicsProxyWidget(parent, wFlags)
+{
+}
+
+QVariant ZoomProxyWidget::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ switch (change) {
+ case ItemPositionChange: {
+ const QPointF newPos = value.toPointF();
+ const QPointF desiredPos = QPointF(0, 0);
+ if (newPos != desiredPos && debugZoomWidget)
+ qDebug() << "ZoomProxyWidget::itemChange: refusing " << newPos;
+ return desiredPos;
+ }
+ default:
+ break;
+ }
+ return QGraphicsProxyWidget::itemChange(change, value);
+}
+
+/* ZoomedEventFilterRedirector: Event filter for the zoomed widget.
+ * It redirects the events to another handler of ZoomWidget as its
+ * base class QScrollArea also implements eventFilter() for its viewport. */
+
+static const char *zoomedEventFilterRedirectorNameC = "__qt_ZoomedEventFilterRedirector";
+
+class ZoomedEventFilterRedirector : public QObject {
+ Q_DISABLE_COPY(ZoomedEventFilterRedirector)
+
+public:
+ explicit ZoomedEventFilterRedirector(ZoomWidget *zw, QObject *parent);
+ virtual bool eventFilter(QObject *watched, QEvent *event);
+
+private:
+ ZoomWidget *m_zw;
+};
+
+ZoomedEventFilterRedirector::ZoomedEventFilterRedirector(ZoomWidget *zw, QObject *parent) :
+ QObject(parent),
+ m_zw(zw)
+{
+ setObjectName(QLatin1String(zoomedEventFilterRedirectorNameC));
+}
+
+bool ZoomedEventFilterRedirector::eventFilter(QObject *watched, QEvent *event)
+{
+ return m_zw->zoomedEventFilter(watched, event);
+}
+
+
+// --------- ZoomWidget
+
+ZoomWidget::ZoomWidget(QWidget *parent) :
+ ZoomView(parent),
+ m_proxy(0),
+ m_viewResizeBlocked(false),
+ m_widgetResizeBlocked(false),
+ m_widgetZoomContextMenuEnabled(false)
+{
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+}
+
+void ZoomWidget::setWidget(QWidget *w, Qt::WindowFlags wFlags)
+{
+ if (debugZoomWidget)
+ qDebug() << "ZoomWidget::setWidget" << w << bin << wFlags;
+
+ if (m_proxy) {
+ scene().removeItem(m_proxy);
+ if (QWidget *w = m_proxy->widget()) {
+ // remove the event filter
+ if (QObject *evf = w->findChild<QObject*>(QLatin1String(zoomedEventFilterRedirectorNameC)))
+ w->removeEventFilter(evf);
+ }
+ m_proxy->deleteLater();
+ }
+ // Set window flags on the outer proxy for them to take effect
+ m_proxy = createProxyWidget(0, Qt::Window);
+ m_proxy->setWidget(w);
+
+ m_proxy->setWindowFlags(wFlags);
+ scene().addItem(m_proxy);
+ w->installEventFilter(new ZoomedEventFilterRedirector(this, w));
+ resizeToWidgetSize(); // Do manually for new widget
+ m_proxy->show();
+}
+
+bool ZoomWidget::isWidgetZoomContextMenuEnabled() const
+{
+ return m_widgetZoomContextMenuEnabled;
+}
+void ZoomWidget::setWidgetZoomContextMenuEnabled(bool e)
+{
+ m_widgetZoomContextMenuEnabled = e;
+}
+
+QSize ZoomWidget::viewPortMargin() const
+{
+ return QSize(0, 0);
+}
+
+QSizeF ZoomWidget::widgetDecorationSizeF() const
+{
+ qreal left, top, right, bottom;
+ m_proxy->getWindowFrameMargins (&left, &top, &right, &bottom);
+ const QSizeF rc = QSizeF(left + right, top + bottom);
+ return rc;
+}
+
+QSize ZoomWidget::widgetSize() const
+{
+ if (m_proxy)
+ return m_proxy->widget()->size();
+ return QSize(0, 0);
+}
+
+/* Convert widget size to QGraphicsView size.
+ * Watch out for limits (0, QWIDGETSIZE_MAX); just pass them on */
+
+QSize ZoomWidget::widgetSizeToViewSize(const QSize &s, bool *ptrToValid) const
+{
+ const QSize vpMargin = viewPortMargin();
+ const QSizeF deco = widgetDecorationSizeF();
+ const int width = s.width();
+
+ QSize rc = s;
+ bool valid = false;
+ if (width != 0 && width != QWIDGETSIZE_MAX) {
+ valid = true;
+ rc.setWidth(vpMargin.width() + qCeil(deco.width() + zoomFactor() * static_cast<qreal>(width)));
+ }
+
+ const int height = s.height();
+ if (height != 0 && height != QWIDGETSIZE_MAX) {
+ valid = true;
+ rc.setHeight(vpMargin.height() + qCeil(deco.height() + zoomFactor() * static_cast<qreal>(height)));
+ }
+
+ if (ptrToValid)
+ *ptrToValid = valid;
+
+ return rc;
+}
+
+// On changing zoom: Make QGraphicsView big enough to hold the widget
+void ZoomWidget::resizeToWidgetSize()
+{
+ if (!m_proxy)
+ return;
+
+ m_viewResizeBlocked = true;
+ // Convert size, apply transformed min/max size if applicable
+ const QSize wsize = widgetSize();
+ const QSize viewSize = widgetSizeToViewSize(wsize);
+
+ bool hasMinimumSize = false;
+ const QSize minimumSize = m_proxy->widget()->minimumSize();
+ const QSize viewMinimumSize = widgetSizeToViewSize(minimumSize, &hasMinimumSize);
+
+ bool hasMaximumSize = false;
+ const QSize maximumSize = m_proxy->widget()->maximumSize();
+ const QSize viewMaximumSize = widgetSizeToViewSize(maximumSize, &hasMaximumSize);
+
+ if (debugZoomWidget) {
+ qDebug()
+ << "ZoomWidget::resizeToWidgetSize()\n"
+ << "Widget: " << wsize << "(scaled)" << (wsize * zoomFactor()) << " Min/Max" << minimumSize << maximumSize << '\n'
+ << " View: " << viewSize << hasMinimumSize << viewMinimumSize << hasMaximumSize << viewMaximumSize;
+ }
+ // Apply
+ if (hasMinimumSize)
+ setMinimumSize(viewMinimumSize);
+ if (hasMaximumSize)
+ setMaximumSize(viewMaximumSize);
+ // now resize
+ doResize(viewSize);
+ if (debugZoomWidget)
+ qDebug() << "ZoomWidget::resizeToWidgetSize(): resulting view size" << size();
+ m_viewResizeBlocked = false;
+}
+
+void ZoomWidget::applyZoom()
+{
+ resizeToWidgetSize();
+}
+
+/* virtual */ void ZoomWidget::doResize(const QSize &s)
+{
+ if (debugZoomWidget > 1)
+ qDebug() << ">ZoomWidget::doResize() " << s;
+ resize(s);
+}
+
+void ZoomWidget::resizeEvent(QResizeEvent *event)
+{
+ /* QGraphicsView Resized from outside: Adapt widget. For some reason,
+ * the size passed in the event is not to be trusted. This might be due
+ * to some QScrollArea event fiddling. Have QScrollArea resize first
+ * and the use the size ZoomView::resizeEvent(event); */
+ if (m_proxy && !m_viewResizeBlocked) {
+ if (debugZoomWidget > 1)
+ qDebug() << '>' << Q_FUNC_INFO << size() << ")::resizeEvent from " << event->oldSize() << " to " << event->size();
+ const QSizeF newViewPortSize = size() - viewPortMargin();
+ const QSizeF widgetSizeF = newViewPortSize / zoomFactor() - widgetDecorationSizeF();
+ m_widgetResizeBlocked = true;
+ m_proxy->widget()->resize(widgetSizeF.toSize());
+ setSceneRect(QRectF(QPointF(0, 0), widgetSizeF));
+ scrollToOrigin();
+ m_widgetResizeBlocked = false;
+ if (debugZoomWidget > 1)
+ qDebug() << '<' << Q_FUNC_INFO << widgetSizeF << m_proxy->widget()->size() << m_proxy->size();
+ }
+}
+
+QSize ZoomWidget::minimumSizeHint() const
+{
+ if (!m_proxy)
+ return QGraphicsView::minimumSizeHint();
+
+ const QSizeF wmsh = m_proxy->widget()->minimumSizeHint();
+ const QSize rc = viewPortMargin() + (wmsh * zoomFactor()).toSize();
+ if (debugZoomWidget > 1)
+ qDebug() << "minimumSizeHint()" << rc;
+ return rc;
+}
+
+QSize ZoomWidget::sizeHint() const
+{
+ if (!m_proxy)
+ return QGraphicsView::sizeHint();
+
+ const QSizeF wsh = m_proxy->widget()->sizeHint();
+ const QSize rc = viewPortMargin() + (wsh * zoomFactor()).toSize();
+ if (debugZoomWidget > 1)
+ qDebug() << "sizeHint()" << rc;
+ return rc;
+}
+
+bool ZoomWidget::zoomedEventFilter(QObject * /*watched*/, QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ if (debugZoomWidget) { // Debug helper: Press 'D' on the zoomed widget
+ const QKeyEvent *kevent = static_cast<QKeyEvent*>(event);
+ if (kevent->key() == Qt::Key_D)
+ dump();
+ }
+ break;
+ case QEvent::Resize:
+ if (debugZoomWidget > 1) {
+ const QResizeEvent *re = static_cast<const QResizeEvent *>(event);
+ qDebug() << "ZoomWidget::zoomedEventFilter" << re->oldSize() << re->size() << " at " << m_proxy->widget()->geometry();
+ }
+ if (!m_widgetResizeBlocked)
+ resizeToWidgetSize();
+
+ break;
+ case QEvent::ContextMenu:
+ if (m_widgetZoomContextMenuEnabled) {
+ // Calculate global position from scaled
+ QContextMenuEvent *ce = static_cast<QContextMenuEvent*>(event);
+ const QPointF origin = mapToGlobal(QPoint(0, 0)) - scrollPosition();
+ const QPointF pos = QPointF(origin + (QPointF(ce->pos()) * zoomFactor()));
+ showContextMenu(pos.toPoint());
+ ce->accept();
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void ZoomWidget::setItemAcceptDrops(bool)
+{
+ if (m_proxy)
+ m_proxy->setAcceptDrops(true);
+}
+
+bool ZoomWidget::itemAcceptDrops() const
+{
+ return m_proxy ? m_proxy->acceptDrops() : false;
+}
+
+ // Factory function for QGraphicsProxyWidgets which can be overwritten. Default creates a ZoomProxyWidget
+QGraphicsProxyWidget *ZoomWidget::createProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) const
+{
+ return new ZoomProxyWidget(parent, wFlags);
+}
+
+void ZoomWidget::dump() const
+{
+
+ qDebug() << "ZoomWidget::dump " << geometry() << " Viewport " << viewport()->geometry()
+ << "Scroll: " << scrollPosition() << "Matrix: " << matrix() << " SceneRect: " << sceneRect();
+ if (m_proxy) {
+ qDebug() << "Proxy Pos: " << m_proxy->pos() << "Proxy " << m_proxy->size()
+ << "\nProxy size hint"
+ << m_proxy->effectiveSizeHint(Qt::MinimumSize)
+ << m_proxy->effectiveSizeHint(Qt::PreferredSize)
+ << m_proxy->effectiveSizeHint(Qt::MaximumSize)
+ << "\nMatrix: " << m_proxy->matrix()
+ << "\nWidget: " << m_proxy->widget()->geometry()
+ << "scaled" << (zoomFactor() * m_proxy->widget()->size());
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/lib/shared/zoomwidget_p.h b/src/designer/src/lib/shared/zoomwidget_p.h
new file mode 100644
index 000000000..4b2a05077
--- /dev/null
+++ b/src/designer/src/lib/shared/zoomwidget_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef ZOOMWIDGET_H
+#define ZOOMWIDGET_H
+
+#include "shared_global_p.h"
+
+#include <QtGui/QGraphicsView>
+#include <QtGui/QGraphicsProxyWidget>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsScene;
+class QMenu;
+class QAction;
+class QActionGroup;
+
+namespace qdesigner_internal {
+
+// A checkable zoom menu action group. Operates in percent.
+
+class QDESIGNER_SHARED_EXPORT ZoomMenu : public QObject {
+ Q_OBJECT
+ Q_DISABLE_COPY(ZoomMenu)
+
+public:
+ ZoomMenu(QObject *parent = 0);
+ void addActions(QMenu *m);
+
+ int zoom() const;
+
+ // Return a list of available zoom values.
+ static QList<int> zoomValues();
+
+public slots:
+ void setZoom(int percent);
+
+signals:
+ void zoomChanged(int);
+
+private slots:
+ void slotZoomMenu(QAction *);
+
+private:
+ static int zoomOf(const QAction *a);
+
+ QActionGroup *m_menuActions;
+};
+
+/* Zoom view: A QGraphicsView with a zoom menu */
+
+class QDESIGNER_SHARED_EXPORT ZoomView : public QGraphicsView
+{
+ Q_PROPERTY(int zoom READ zoom WRITE setZoom DESIGNABLE true SCRIPTABLE true)
+ Q_PROPERTY(bool zoomContextMenuEnabled READ isZoomContextMenuEnabled WRITE setZoomContextMenuEnabled DESIGNABLE true SCRIPTABLE true)
+ Q_OBJECT
+ Q_DISABLE_COPY(ZoomView)
+public:
+ ZoomView(QWidget *parent = 0);
+
+ /* Zoom in percent (for easily implementing menus) and qreal zoomFactor
+ * in sync */
+ int zoom() const; // in percent
+ qreal zoomFactor() const;
+
+ // Zoom Menu on QGraphicsView.
+ bool isZoomContextMenuEnabled() const;
+ void setZoomContextMenuEnabled(bool e);
+
+ QGraphicsScene &scene() { return *m_scene; }
+ const QGraphicsScene &scene() const { return *m_scene; }
+
+ // Helpers for menu
+ ZoomMenu *zoomMenu();
+
+ QPoint scrollPosition() const;
+ void setScrollPosition(const QPoint& pos);
+ void scrollToOrigin();
+
+public slots:
+ void setZoom(int percent);
+ void showContextMenu(const QPoint &globalPos);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event);
+
+ // Overwrite for implementing additional behaviour when doing setZoom();
+ virtual void applyZoom();
+
+private:
+ QGraphicsScene *m_scene;
+ int m_zoom;
+ qreal m_zoomFactor;
+
+ bool m_zoomContextMenuEnabled;
+ bool m_resizeBlocked;
+ ZoomMenu *m_zoomMenu;
+};
+
+/* The proxy widget used in ZoomWidget. It refuses to move away from 0,0,
+ * This behaviour is required for Windows only. */
+
+class QDESIGNER_SHARED_EXPORT ZoomProxyWidget : public QGraphicsProxyWidget {
+ Q_DISABLE_COPY(ZoomProxyWidget)
+public:
+ explicit ZoomProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
+
+protected:
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+};
+
+/* Zoom widget: A QGraphicsView-based container for a widget that allows for
+ * zooming it. Communicates changes in size in the following ways:
+ * 1) Embedded widget wants to resize: Listen for its resize in event filter
+ * and resize
+ * 2) Zoom is changed: resize to fully display the embedded widget
+ * 3) Outer widget changes (by manually resizing the window:
+ * Pass the scaled change on to the embedded widget.
+ * Provides helper functions for a zoom context menu on the widget. */
+
+class QDESIGNER_SHARED_EXPORT ZoomWidget : public ZoomView
+{
+ Q_PROPERTY(bool widgetZoomContextMenuEnabled READ isWidgetZoomContextMenuEnabled WRITE setWidgetZoomContextMenuEnabled DESIGNABLE true SCRIPTABLE true)
+ Q_PROPERTY(bool itemAcceptDrops READ itemAcceptDrops WRITE setItemAcceptDrops DESIGNABLE true SCRIPTABLE true)
+ Q_OBJECT
+ Q_DISABLE_COPY(ZoomWidget)
+
+public:
+ ZoomWidget(QWidget *parent = 0);
+ void setWidget(QWidget *w, Qt::WindowFlags wFlags = 0);
+
+ const QGraphicsProxyWidget *proxy() const { return m_proxy; }
+ QGraphicsProxyWidget *proxy() { return m_proxy; }
+
+ /* Enable the zoom Menu on the Widget (as opposed ZoomView's menu which
+ * is on the canvas). */
+ bool isWidgetZoomContextMenuEnabled() const;
+ void setWidgetZoomContextMenuEnabled(bool e);
+
+ void setItemAcceptDrops(bool);
+ bool itemAcceptDrops() const;
+
+ virtual QSize minimumSizeHint() const;
+ virtual QSize sizeHint() const;
+
+ bool zoomedEventFilter(QObject *watched, QEvent *event);
+
+public slots:
+ // debug state
+ void dump() const;
+
+protected:
+ void resizeEvent(QResizeEvent * event);
+
+ // Overwritten from ZoomView
+ virtual void applyZoom();
+ // Overwrite to actually perform a resize. This is required if we are in a layout. Default does resize().
+ virtual void doResize(const QSize &s);
+
+private:
+ // Factory function for QGraphicsProxyWidgets which can be overwritten. Default creates a ZoomProxyWidget
+ virtual QGraphicsProxyWidget *createProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0) const;
+ QSize widgetSizeToViewSize(const QSize &s, bool *ptrToValid = 0) const;
+
+ void resizeToWidgetSize();
+ QSize viewPortMargin() const;
+ QSize widgetSize() const;
+ QSizeF widgetDecorationSizeF() const;
+
+ QGraphicsProxyWidget *m_proxy;
+ bool m_viewResizeBlocked;
+ bool m_widgetResizeBlocked;
+ bool m_widgetZoomContextMenuEnabled;
+};
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/plugins/activeqt/activeqt.pro b/src/designer/src/plugins/activeqt/activeqt.pro
new file mode 100644
index 000000000..f58df8a38
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/activeqt.pro
@@ -0,0 +1,32 @@
+TARGET = $$qtLibraryTarget(qaxwidget)
+TEMPLATE = lib
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/designer
+
+CONFIG += qt warn_on qaxcontainer plugin designer debug_and_release
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+INCLUDEPATH += $$QT_SOURCE_TREE/src/activeqt/shared/ \
+ $$QT_BUILD_TREE/src/activeqt/container \
+ ../../lib/uilib
+
+# Input
+SOURCES += qaxwidgetextrainfo.cpp \
+qaxwidgetplugin.cpp \
+qdesigneraxwidget.cpp \
+qaxwidgetpropertysheet.cpp \
+qaxwidgettaskmenu.cpp \
+ $$QT_SOURCE_TREE/src/activeqt/shared/qaxtypes.cpp
+
+HEADERS += qaxwidgetextrainfo.h \
+qaxwidgetplugin.h \
+qdesigneraxwidget.h \
+qaxwidgetpropertysheet.h \
+qaxwidgettaskmenu.h \
+ $$QT_SOURCE_TREE/src/activeqt/shared/qaxtypes.h
+
+# install
+target.path = $$[QT_INSTALL_PLUGINS]/designer
+INSTALLS += target
diff --git a/src/designer/src/plugins/activeqt/qaxwidgetextrainfo.cpp b/src/designer/src/plugins/activeqt/qaxwidgetextrainfo.cpp
new file mode 100644
index 000000000..f58e1856d
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qaxwidgetextrainfo.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaxwidgetextrainfo.h"
+#include "qdesigneraxwidget.h"
+#include "qaxwidgetpropertysheet.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/private/ui4_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QAxWidgetExtraInfo::QAxWidgetExtraInfo(QDesignerAxWidget *widget, QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), m_widget(widget), m_core(core)
+{
+}
+
+QWidget *QAxWidgetExtraInfo::widget() const
+{
+ return m_widget;
+}
+
+QDesignerFormEditorInterface *QAxWidgetExtraInfo::core() const
+{
+ return m_core;
+}
+
+bool QAxWidgetExtraInfo::saveUiExtraInfo(DomUI *)
+{
+ return false;
+}
+
+bool QAxWidgetExtraInfo::loadUiExtraInfo(DomUI *)
+{
+ return false;
+}
+
+bool QAxWidgetExtraInfo::saveWidgetExtraInfo(DomWidget *ui_widget)
+{
+ /* Turn off standard setters and make sure "control" is in front,
+ * otherwise, previews will not work as the properties are not applied via
+ * the caching property sheet, them. */
+ typedef QList<DomProperty *> DomPropertyList;
+ DomPropertyList props = ui_widget->elementProperty();
+ const int size = props.size();
+ const QString controlProperty = QLatin1String(QAxWidgetPropertySheet::controlPropertyName);
+ for (int i = 0; i < size; i++) {
+ props.at(i)->setAttributeStdset(false);
+ if (i > 0 && props.at(i)->attributeName() == controlProperty) {
+ qSwap(props[0], props[i]);
+ ui_widget->setElementProperty(props);
+ }
+
+ }
+ return true;
+}
+
+bool QAxWidgetExtraInfo::loadWidgetExtraInfo(DomWidget *)
+{
+ return false;
+}
+
+QAxWidgetExtraInfoFactory::QAxWidgetExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent)
+ : QExtensionFactory(parent), m_core(core)
+{
+}
+
+QObject *QAxWidgetExtraInfoFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerExtraInfoExtension))
+ return 0;
+
+ if (QDesignerAxWidget *w = qobject_cast<QDesignerAxWidget*>(object))
+ return new QAxWidgetExtraInfo(w, m_core, parent);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/activeqt/qaxwidgetextrainfo.h b/src/designer/src/plugins/activeqt/qaxwidgetextrainfo.h
new file mode 100644
index 000000000..cb94eea6c
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qaxwidgetextrainfo.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ACTIVEQT_EXTRAINFO_H
+#define ACTIVEQT_EXTRAINFO_H
+
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionFactory>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerAxWidget;
+
+class QAxWidgetExtraInfo: public QObject, public QDesignerExtraInfoExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerExtraInfoExtension)
+public:
+ QAxWidgetExtraInfo(QDesignerAxWidget *widget, QDesignerFormEditorInterface *core, QObject *parent);
+
+ virtual QWidget *widget() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool saveUiExtraInfo(DomUI *ui);
+ virtual bool loadUiExtraInfo(DomUI *ui);
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget);
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget);
+
+private:
+ QPointer<QDesignerAxWidget> m_widget;
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+class QAxWidgetExtraInfoFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit QAxWidgetExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // ACTIVEQT_EXTRAINFO_H
diff --git a/src/designer/src/plugins/activeqt/qaxwidgetplugin.cpp b/src/designer/src/plugins/activeqt/qaxwidgetplugin.cpp
new file mode 100644
index 000000000..019ada2f5
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qaxwidgetplugin.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaxwidgetplugin.h"
+#include "qaxwidgetextrainfo.h"
+#include "qdesigneraxwidget.h"
+#include "qaxwidgetpropertysheet.h"
+#include "qaxwidgettaskmenu.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <ActiveQt/QAxWidget>
+
+QT_BEGIN_NAMESPACE
+
+QAxWidgetPlugin::QAxWidgetPlugin(QObject *parent) :
+ QObject(parent),
+ m_core(0)
+{
+}
+
+QString QAxWidgetPlugin::name() const
+{
+ return QLatin1String("QAxWidget");
+}
+
+QString QAxWidgetPlugin::group() const
+{
+ return QLatin1String("Containers");
+}
+
+QString QAxWidgetPlugin::toolTip() const
+{
+ return tr("ActiveX control");
+}
+
+QString QAxWidgetPlugin::whatsThis() const
+{
+ return tr("ActiveX control widget");
+}
+
+QString QAxWidgetPlugin::includeFile() const
+{
+ return QLatin1String("qaxwidget.h");
+}
+
+QIcon QAxWidgetPlugin::icon() const
+{
+ return QIcon(QDesignerAxWidget::widgetIcon());
+}
+
+bool QAxWidgetPlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *QAxWidgetPlugin::createWidget(QWidget *parent)
+{
+ // Construction from Widget box or on a form?
+ const bool isFormEditor = parent != 0 && QDesignerFormWindowInterface::findFormWindow(parent) != 0;
+ QDesignerAxWidget *rc = new QDesignerAxPluginWidget(parent);
+ if (!isFormEditor)
+ rc->setDrawFlags(QDesignerAxWidget::DrawFrame|QDesignerAxWidget::DrawControl);
+ return rc;
+}
+
+bool QAxWidgetPlugin::isInitialized() const
+{
+ return m_core != 0;
+}
+
+void QAxWidgetPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ if (m_core != 0)
+ return;
+
+ m_core = core;
+
+ QExtensionManager *mgr = core->extensionManager();
+ ActiveXPropertySheetFactory::registerExtension(mgr);
+ ActiveXTaskMenuFactory::registerExtension(mgr, Q_TYPEID(QDesignerTaskMenuExtension));
+ QAxWidgetExtraInfoFactory *extraInfoFactory = new QAxWidgetExtraInfoFactory(core, mgr);
+ mgr->registerExtensions(extraInfoFactory, Q_TYPEID(QDesignerExtraInfoExtension));
+}
+
+QString QAxWidgetPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"QAxWidget\" name=\"axWidget\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>80</width>\
+ <height>70</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+Q_EXPORT_PLUGIN(QAxWidgetPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/activeqt/qaxwidgetplugin.h b/src/designer/src/plugins/activeqt/qaxwidgetplugin.h
new file mode 100644
index 000000000..a018811e6
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qaxwidgetplugin.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ACTIVEXPLUGIN_H
+#define ACTIVEXPLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+
+class QAxWidgetPlugin : public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit inline QAxWidgetPlugin(QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/plugins/activeqt/qaxwidgetpropertysheet.cpp b/src/designer/src/plugins/activeqt/qaxwidgetpropertysheet.cpp
new file mode 100644
index 000000000..7d8408e12
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qaxwidgetpropertysheet.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaxwidgetpropertysheet.h"
+#include "qdesigneraxwidget.h"
+
+#include <QtDesigner/QDesignerMemberSheetExtension>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+
+#include <QtDesigner/QExtensionManager>
+#include <QtCore/QDebug>
+#include <QtCore/QTimer>
+
+static const char *geometryPropertyC = "geometry";
+
+QT_BEGIN_NAMESPACE
+
+const char *QAxWidgetPropertySheet::controlPropertyName = "control";
+
+QAxWidgetPropertySheet::QAxWidgetPropertySheet(QDesignerAxWidget *object, QObject *parent) :
+ QDesignerPropertySheet(object, parent),
+ m_controlProperty(controlPropertyName),
+ m_propertyGroup(QLatin1String("QAxWidget"))
+{
+ if (!axWidget()->loaded()) { // For some obscure reason....
+ const int controlIndex = QDesignerPropertySheet::indexOf(m_controlProperty);
+ setPropertyGroup(controlIndex, m_propertyGroup);
+ }
+}
+
+bool QAxWidgetPropertySheet::isEnabled(int index) const
+{
+ if (propertyName(index) == m_controlProperty)
+ return false;
+ return QDesignerPropertySheet::isEnabled(index);
+}
+
+bool QAxWidgetPropertySheet::dynamicPropertiesAllowed() const
+{
+ return false;
+}
+
+QDesignerAxWidget *QAxWidgetPropertySheet::axWidget() const
+{
+ return static_cast<QDesignerAxWidget*>(object());
+}
+
+// Reload as the meta object changes.
+bool QAxWidgetPropertySheet::reset(int index)
+{
+ const QString name = propertyName(index);
+ QMap<QString, QVariant>::iterator it = m_currentProperties.changedProperties.find(name);
+ if (it != m_currentProperties.changedProperties.end())
+ m_currentProperties.changedProperties.erase(it);
+ if (name != m_controlProperty)
+ return QDesignerPropertySheet::reset(index);
+ axWidget()->resetControl();
+ QTimer::singleShot(0, this, SLOT(updatePropertySheet()));
+ return true;
+}
+
+void QAxWidgetPropertySheet::setProperty(int index, const QVariant &value)
+{
+
+ // take care of all changed properties
+ const QString name = propertyName(index);
+ m_currentProperties.changedProperties[name] = value;
+ if (name != m_controlProperty) {
+ QDesignerPropertySheet::setProperty(index, value);
+ return;
+ }
+ // Loading forms: Reload
+ if (name == m_controlProperty) {
+ const QString clsid = value.toString();
+ if (clsid.isEmpty() || !axWidget()->loadControl(clsid))
+ reset(index);
+ else
+ QTimer::singleShot(100, this, SLOT(updatePropertySheet()));
+ }
+}
+
+int QAxWidgetPropertySheet::indexOf(const QString &name) const
+{
+ const int index = QDesignerPropertySheet::indexOf(name);
+ if (index != -1)
+ return index;
+ // Loading before recreation of sheet in timer slot: Add a fake property to store the value
+ const QVariant dummValue(0);
+ QAxWidgetPropertySheet *that = const_cast<QAxWidgetPropertySheet *>(this);
+ const int newIndex = that->createFakeProperty(name, dummValue);
+ that->setPropertyGroup(newIndex, m_propertyGroup);
+ return newIndex;
+}
+
+void QAxWidgetPropertySheet::updatePropertySheet()
+{
+ // refresh the property sheet (we are deleting m_currentProperties)
+ struct SavedProperties tmp = m_currentProperties;
+ QDesignerAxWidget *axw = axWidget();
+ QDesignerFormWindowInterface *formWin = QDesignerFormWindowInterface::findFormWindow(axw);
+ Q_ASSERT(formWin != 0);
+ tmp.widget = axw;
+ tmp.clsid = axw->control();
+ // Delete the sheets as they cache the meta object and other information
+ delete this;
+ delete qt_extension<QDesignerMemberSheetExtension *>(formWin->core()->extensionManager(), axw);
+ reloadPropertySheet(tmp, formWin);
+}
+
+void QAxWidgetPropertySheet::reloadPropertySheet(const struct SavedProperties &properties, QDesignerFormWindowInterface *formWin)
+{
+ QDesignerFormEditorInterface *core = formWin->core();
+ //Recreation of the property sheet
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension *>(core->extensionManager(), properties.widget);
+
+ bool foundGeometry = false;
+ const QString geometryProperty = QLatin1String(geometryPropertyC);
+ const SavedProperties::NamePropertyMap::const_iterator cend = properties.changedProperties.constEnd();
+ for (SavedProperties::NamePropertyMap::const_iterator i = properties.changedProperties.constBegin(); i != cend; ++i) {
+ const QString name = i.key();
+ const int index = sheet->indexOf(name);
+ if (index == -1)
+ continue;
+ // filter out geometry as this will resize the control
+ // to is default size even if it is attached to an layout
+ // but set the changed flag to work around preview bug...
+ if (name == geometryProperty) {
+ sheet->setChanged(index, true);
+ foundGeometry = true;
+ continue;
+ }
+ if (name == QLatin1String(controlPropertyName)) {
+ sheet->setChanged(index, !i.value().toString().isEmpty());
+ continue;
+ }
+ sheet->setChanged(index, true);
+ sheet->setProperty(index, i.value());
+ }
+
+ if (!foundGeometry) // Make sure geometry is always changed in Designer
+ sheet->setChanged(sheet->indexOf(geometryProperty), true);
+
+ if (core->propertyEditor()->object() == properties.widget) {
+ formWin->clearSelection(true);
+ formWin->selectWidget(properties.widget);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/activeqt/qaxwidgetpropertysheet.h b/src/designer/src/plugins/activeqt/qaxwidgetpropertysheet.h
new file mode 100644
index 000000000..b1fd35b54
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qaxwidgetpropertysheet.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACTIVEXPROPERTYSHEET_H
+#define QACTIVEXPROPERTYSHEET_H
+
+#include <QtDesigner/private/qdesigner_propertysheet_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerAxWidget;
+class QDesignerFormWindowInterface;
+
+/* The propertysheet has a method to delete itself and repopulate
+ * if the "control" property changes. Pre 4.5, the control property
+ * might not be the first one, so, the properties are stored and
+ * re-applied. If the "control" is the first one, it should be
+ * sufficient to reapply the changed flags, however, care must be taken when
+ * resetting the control.
+ * Resetting a control: The current behaviour is that the modified Active X properties are added again
+ * as Fake-Properties, which is a nice side-effect as not cause a loss. */
+
+class QAxWidgetPropertySheet: public QDesignerPropertySheet
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit QAxWidgetPropertySheet(QDesignerAxWidget *object, QObject *parent = 0);
+
+ virtual bool isEnabled(int index) const;
+ virtual void setProperty(int index, const QVariant &value);
+ virtual bool reset(int index);
+ int indexOf(const QString &name) const;
+ bool dynamicPropertiesAllowed() const;
+
+ static const char *controlPropertyName;
+
+public slots:
+ void updatePropertySheet();
+
+private:
+ QDesignerAxWidget *axWidget() const;
+
+ const QString m_controlProperty;
+ const QString m_propertyGroup;
+ int m_controlIndex;
+ struct SavedProperties {
+ typedef QMap<QString, QVariant> NamePropertyMap;
+ NamePropertyMap changedProperties;
+ QWidget *widget;
+ QString clsid;
+ } m_currentProperties;
+
+ static void reloadPropertySheet(const struct SavedProperties &properties, QDesignerFormWindowInterface *formWin);
+};
+
+typedef QDesignerPropertySheetFactory<QDesignerAxWidget, QAxWidgetPropertySheet> ActiveXPropertySheetFactory;
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp b/src/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp
new file mode 100644
index 000000000..d49f369d3
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaxwidgettaskmenu.h"
+#include "qdesigneraxwidget.h"
+#include "qaxwidgetpropertysheet.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtGui/QUndoCommand>
+#include <QtGui/QMessageBox>
+#include <QtGui/QUndoStack>
+#include <QtCore/QUuid>
+#include <ActiveQt/qaxselect.h>
+
+#include <olectl.h>
+#include <qaxtypes.h>
+
+QT_BEGIN_NAMESPACE
+
+/* SetControlCommand: An undo commands that sets a control bypassing
+ Designer's property system which cannot handle the changing
+ of the 'control' property's index and other cached information
+ when modifying it. */
+
+class SetControlCommand : public QUndoCommand
+{
+public:
+ SetControlCommand(QDesignerAxWidget *ax, QDesignerFormWindowInterface *core, const QString &newClsid = QString());
+
+ virtual void redo() { apply(m_newClsid); }
+ virtual void undo() { apply(m_oldClsid); }
+
+private:
+ bool apply(const QString &clsid);
+
+ QDesignerAxWidget *m_axWidget;
+ QDesignerFormWindowInterface *m_formWindow;
+ QString m_oldClsid;
+ QString m_newClsid;
+};
+
+SetControlCommand::SetControlCommand(QDesignerAxWidget *ax, QDesignerFormWindowInterface *fw, const QString &newClsid) :
+ m_axWidget(ax),
+ m_formWindow(fw),
+ m_oldClsid(ax->control()),
+ m_newClsid(newClsid)
+{
+ if (m_newClsid.isEmpty())
+ setText(QDesignerAxWidget::tr("Reset control"));
+ else
+ setText(QDesignerAxWidget::tr("Set control"));
+}
+
+bool SetControlCommand::apply(const QString &clsid)
+{
+ if (m_oldClsid == m_newClsid)
+ return true;
+
+ QObject *ext = m_formWindow->core()->extensionManager()->extension(m_axWidget, Q_TYPEID(QDesignerPropertySheetExtension));
+ QAxWidgetPropertySheet *sheet = qobject_cast<QAxWidgetPropertySheet*>(ext);
+ if (!sheet)
+ return false;
+
+ const bool hasClsid = !clsid.isEmpty();
+ const int index = sheet->indexOf(QLatin1String(QAxWidgetPropertySheet::controlPropertyName));
+ if (hasClsid)
+ sheet->setProperty(index, clsid);
+ else
+ sheet->reset(index);
+ return true;
+}
+
+// -------------------- QAxWidgetTaskMenu
+QAxWidgetTaskMenu::QAxWidgetTaskMenu(QDesignerAxWidget *object, QObject *parent) :
+ QObject(parent),
+ m_axwidget(object),
+ m_setAction(new QAction(tr("Set Control"), this)),
+ m_resetAction(new QAction(tr("Reset Control"), this))
+{
+ connect(m_setAction, SIGNAL(triggered()), this, SLOT(setActiveXControl()));
+ connect(m_resetAction, SIGNAL(triggered()), this, SLOT(resetActiveXControl()));
+ m_taskActions.push_back(m_setAction);
+ m_taskActions.push_back(m_resetAction);
+}
+
+QAxWidgetTaskMenu::~QAxWidgetTaskMenu()
+{
+}
+
+QList<QAction*> QAxWidgetTaskMenu::taskActions() const
+{
+ const bool loaded = m_axwidget->loaded();
+ m_setAction->setEnabled(!loaded);
+ m_resetAction->setEnabled(loaded);
+ return m_taskActions;
+}
+
+void QAxWidgetTaskMenu::resetActiveXControl()
+{
+ QDesignerFormWindowInterface *formWin = QDesignerFormWindowInterface::findFormWindow(m_axwidget);
+ Q_ASSERT(formWin != 0);
+ formWin->commandHistory()->push(new SetControlCommand(m_axwidget, formWin));
+}
+
+void QAxWidgetTaskMenu::setActiveXControl()
+{
+ QAxSelect *dialog = new QAxSelect(m_axwidget->topLevelWidget());
+ if (dialog->exec()) {
+ QUuid clsid = dialog->clsid();
+ QString key;
+
+ IClassFactory2 *cf2 = 0;
+ CoGetClassObject(clsid, CLSCTX_SERVER, 0, IID_IClassFactory2, (void**)&cf2);
+
+ if (cf2) {
+ BSTR bKey;
+ HRESULT hres = cf2->RequestLicKey(0, &bKey);
+ if (hres == CLASS_E_NOTLICENSED) {
+ QMessageBox::warning(m_axwidget->topLevelWidget(), tr("Licensed Control"),
+ tr("The control requires a design-time license"));
+ clsid = QUuid();
+ } else {
+ key = QString::fromWCharArray(bKey);
+ }
+
+ cf2->Release();
+ }
+
+ if (!clsid.isNull()) {
+ QDesignerFormWindowInterface *formWin = QDesignerFormWindowInterface::findFormWindow(m_axwidget);
+
+ Q_ASSERT(formWin != 0);
+ QString value = clsid.toString();
+ if (!key.isEmpty()) {
+ value += QLatin1Char(':');
+ value += key;
+ }
+ formWin->commandHistory()->push(new SetControlCommand(m_axwidget, formWin, value));
+ }
+ }
+ delete dialog;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/activeqt/qaxwidgettaskmenu.h b/src/designer/src/plugins/activeqt/qaxwidgettaskmenu.h
new file mode 100644
index 000000000..aec27765e
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qaxwidgettaskmenu.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACTIVEXTASKMENU_H
+#define QACTIVEXTASKMENU_H
+
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtDesigner/private/extensionfactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerAxWidget;
+
+class QAxWidgetTaskMenu: public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit QAxWidgetTaskMenu(QDesignerAxWidget *object, QObject *parent = 0);
+ virtual ~QAxWidgetTaskMenu();
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void setActiveXControl();
+ void resetActiveXControl();
+
+private:
+ QDesignerAxWidget *m_axwidget;
+ QAction *m_setAction;
+ QAction *m_resetAction;
+ QList<QAction*> m_taskActions;
+};
+
+typedef qdesigner_internal::ExtensionFactory<QDesignerTaskMenuExtension, QDesignerAxWidget, QAxWidgetTaskMenu> ActiveXTaskMenuFactory;
+
+QT_END_NAMESPACE
+
+#endif // QACTIVEXTASKMENU
diff --git a/src/designer/src/plugins/activeqt/qdesigneraxwidget.cpp b/src/designer/src/plugins/activeqt/qdesigneraxwidget.cpp
new file mode 100644
index 000000000..cadbc1dd6
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qdesigneraxwidget.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigneraxwidget.h"
+
+#include <QtCore/QMetaProperty>
+#include <QtCore/QDebug>
+#include <QtGui/QIcon>
+#include <QtGui/QPainter>
+#include <QtGui/QResizeEvent>
+
+#include <ActiveQt/QAxWidget>
+
+#include <olectl.h>
+#include <qaxtypes.h>
+
+enum { debugAxWidget = 0 };
+
+QT_BEGIN_NAMESPACE
+
+/* XPM */
+const char *widgetIconXPM[]={
+"22 22 6 1",
+"a c #000000",
+"# c #808080",
+"+ c #aaa5a0",
+"b c #dddddd",
+"* c #d4d0c8",
+". c none",
+".........#aa#...#aa#..",
+".........abba...abba..",
+".........abba...abba..",
+".........#aa#...#aa#..",
+"..........aa.....aa...",
+"..........aa.....aa...",
+"..........aa.....aa...",
+".......aaaaaaaaaaaaaaa",
+".......a*************a",
+".......a************#a",
+".......a***********+#a",
+".......a***********+#a",
+".......a***********+#a",
+"#aa#...a***********+#a",
+"abbaaaaa***********+#a",
+"abbaaaaa***********+#a",
+"#aa#...a***********+#a",
+".......a***********+#a",
+".......a***********+#a",
+".......a**++++++++++#a",
+".......a*############a",
+".......aaaaaaaaaaaaaaa"};
+
+QDesignerAxWidget::QDesignerAxWidget(QWidget *parent) :
+ QWidget(parent),
+ m_defaultSize(80, 70),
+ m_drawFlags(DrawIndicator|DrawFrame|DrawControl),
+ m_axobject(0),
+ m_axImage(widgetIcon())
+{
+}
+
+QDesignerAxWidget::~QDesignerAxWidget()
+{
+ delete m_axobject;
+}
+
+QPixmap QDesignerAxWidget::widgetIcon()
+{
+ return QPixmap(widgetIconXPM);
+}
+
+QString QDesignerAxWidget::control() const
+{
+ if (m_axobject)
+ return m_axobject->control();
+ return QString();
+}
+
+void QDesignerAxWidget::setControl(const QString &clsid)
+{
+ if (clsid == control())
+ return;
+ if (clsid.isEmpty()) {
+ resetControl();
+ } else {
+ loadControl(clsid);
+ }
+}
+void QDesignerAxWidget::resetControl()
+{
+ if (!m_axobject)
+ return;
+ delete m_axobject;
+ m_axobject = 0;
+ update();
+}
+
+bool QDesignerAxWidget::loadControl(const QString &clsid)
+{
+ if (clsid.isEmpty())
+ return false;
+ if (m_axobject)
+ resetControl();
+ m_axobject = new QAxWidget();
+
+ if (!m_axobject->setControl(clsid)) {
+ delete m_axobject;
+ m_axobject = 0;
+ return false;
+ }
+ update();
+ return true;
+}
+
+QSize QDesignerAxWidget::sizeHint() const
+{
+ if (m_axobject)
+ return m_axobject->sizeHint();
+ return m_defaultSize;
+}
+
+QSize QDesignerAxWidget::minimumSizeHint() const
+{
+ if (m_axobject)
+ return m_axobject->minimumSizeHint();
+ return QWidget::minimumSizeHint();
+}
+
+void QDesignerAxWidget::paintEvent(QPaintEvent * /*event */)
+{
+ QPainter p(this);
+ const QRect r = contentsRect();
+ const int contentsWidth = r.width();
+ const int contentsHeight= r.height();
+ if (m_axobject) { // QAxWidget has no concept of sizeHint()
+ if (m_drawFlags & DrawControl) {
+ m_axobject->resize(size());
+ m_axobject->render(&p);
+ }
+ if (m_drawFlags & DrawIndicator) {
+ static const QString loaded = tr("Control loaded");
+ QColor patternColor(Qt::green);
+ if (m_drawFlags & DrawControl)
+ patternColor.setAlpha(80);
+ p.setBrush(QBrush(patternColor, Qt::BDiagPattern));
+ p.setPen(Qt::black);
+ if (r.height() > 5)
+ p.drawText(5,contentsHeight - 5, loaded);
+ }
+ }
+ if (m_drawFlags & DrawFrame) {
+ p.drawRect(r.adjusted(0, 0, -1, -1));
+ }
+ if (m_drawFlags & DrawIndicator) {
+ if (contentsWidth > m_axImage.width() && contentsHeight > m_axImage.height())
+ p.drawPixmap((contentsWidth - m_axImage.width()) / 2,
+ (contentsHeight-m_axImage.height()) / 2, m_axImage);
+ }
+}
+
+// --------- QDesignerAxPluginWidget
+QDesignerAxPluginWidget::QDesignerAxPluginWidget(QWidget *parent) :
+ QDesignerAxWidget(parent)
+{
+}
+
+QDesignerAxPluginWidget::~QDesignerAxPluginWidget()
+{
+}
+
+const QMetaObject *QDesignerAxPluginWidget::metaObject() const
+{
+ if (const QAxWidget *aw = axobject())
+ return aw->metaObject();
+
+ return QDesignerAxWidget::metaObject();
+}
+
+static QString msgComException(const QObject *o, const QMetaObject::Call call, int index)
+{
+ return QDesignerAxWidget::tr("A COM exception occurred when executing a meta call of type %1, index %2 of \"%3\".").
+ arg(call).arg(index).arg(o->objectName());
+}
+
+int QDesignerAxPluginWidget::qt_metacall(QMetaObject::Call call, int signal, void **argv)
+{
+ QAxWidget *aw = axobject();
+ if (!aw)
+ return QDesignerAxWidget::qt_metacall(call,signal,argv);
+
+
+ const QMetaObject *mo = metaObject();
+ // Have base class handle inherited stuff (geometry, enabled...)
+ const bool inherited = call == QMetaObject::InvokeMetaMethod ?
+ (signal < mo->methodOffset()) : (signal < mo->propertyOffset());
+ if (inherited)
+ return QDesignerAxWidget::qt_metacall(call, signal, argv);
+
+ int rc = -1;
+#ifndef QT_NO_EXCEPTIONS
+ try {
+#endif
+ if (debugAxWidget)
+ if (call != QMetaObject::InvokeMetaMethod)
+ qDebug() << objectName() << call << signal << mo->property(signal).name();
+ switch (call) {
+ case QMetaObject::QueryPropertyStored: // Pretend all changed properties are stored for them to be saved
+ if (m_propValues.contains(signal))
+ if (argv[0])
+ *reinterpret_cast< bool*>(argv[0]) = true;
+ break;
+ case QMetaObject::ResetProperty:
+ rc = aw->qt_metacall(call, signal, argv);
+ update();
+ m_propValues.remove(signal);
+ break;
+ case QMetaObject::WriteProperty:
+ rc = aw->qt_metacall(call, signal, argv);
+ update();
+ m_propValues.insert(signal, true);
+ break;
+ default:
+ rc = aw->qt_metacall(call, signal, argv);
+ break;
+ }
+#ifndef QT_NO_EXCEPTIONS
+ } catch(...) {
+ qWarning(msgComException(this, call, signal).toUtf8());
+ }
+#endif
+ return rc;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/activeqt/qdesigneraxwidget.h b/src/designer/src/plugins/activeqt/qdesigneraxwidget.h
new file mode 100644
index 000000000..88d49e1b0
--- /dev/null
+++ b/src/designer/src/plugins/activeqt/qdesigneraxwidget.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACTIVEXPLUGINOBJECT_H
+#define QACTIVEXPLUGINOBJECT_H
+
+#include <QtCore/QPointer>
+#include <QtCore/QMap>
+#include <QtGui/QWidget>
+#include <QtGui/QPixmap>
+
+QT_BEGIN_NAMESPACE
+
+class QAxWidget;
+
+/* QDesignerAxWidget aggregates QAxWidget to keep it out of the event loop while applying
+ * properties directly.
+ * Thus, it is possible to set property values in designer that are out of range
+ * for the control, which might cause it to throw exceptions.
+ *
+ * QDesignerAxWidget is the base class following the internal naming
+ * conventions that makes the control property visible to the introspection interface.
+ *
+ * The trick to aggregate a QAxWidget is to overwrite the metaObject() function
+ * generated by moc to return the QMetaObject of QAxWidget. This is what QDesignerAxPluginWidget does. */
+
+class QDesignerAxWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QString control READ control WRITE setControl RESET resetControl DESIGNABLE true)
+ Q_DISABLE_COPY(QDesignerAxWidget)
+
+protected:
+ explicit QDesignerAxWidget(QWidget *parent);
+
+public:
+ virtual ~QDesignerAxWidget();
+
+ bool loadControl(const QString &clsid);
+
+ void resetControl();
+ void setControl(const QString &clsid);
+ QString control() const;
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ bool loaded() { return (m_axobject != 0); }
+
+ static QPixmap widgetIcon();
+
+ enum { DrawIndicator = 0x1, DrawFrame = 0x2, DrawControl = 0x4 };
+
+ unsigned drawFlags() const { return m_drawFlags; }
+ void setDrawFlags(unsigned f) { m_drawFlags = f; }
+
+protected:
+ void paintEvent(QPaintEvent *event);
+ QAxWidget *axobject() const { return m_axobject; }
+
+private:
+ const QSize m_defaultSize;
+ unsigned m_drawFlags;
+ QAxWidget *m_axobject;
+ QPixmap m_axImage;
+};
+
+class QDesignerAxPluginWidget : public QDesignerAxWidget
+{
+ // No Q_OBJECT here! - meta functionality is overridden
+public:
+ explicit QDesignerAxPluginWidget(QWidget *parent);
+ virtual ~QDesignerAxPluginWidget();
+
+ virtual const QMetaObject *metaObject() const;
+ virtual int qt_metacall(QMetaObject::Call, int, void **);
+
+private:
+ QMap<int, bool> m_propValues;
+};
+
+#if defined Q_CC_MSVC && _MSC_VER < 1300
+template <> inline QDesignerAxWidget *qobject_cast_helper<QDesignerAxWidget*>(QObject *o, QDesignerAxWidget*)
+#else
+template <> inline QDesignerAxWidget *qobject_cast<QDesignerAxWidget*>(QObject *o)
+#endif
+{
+ if (!o)
+ return 0;
+
+ // Unloaded state
+ if (strcmp(o->metaObject()->className(), "QDesignerAxWidget") == 0)
+ return static_cast<QDesignerAxPluginWidget*>(o);
+
+ // Loaded state with fake meta object
+ if (strcmp(o->metaObject()->className(), "QAxWidget") == 0)
+ return static_cast<QDesignerAxPluginWidget*>(o);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // ACTIVEQT_EXTRAINFO_H
diff --git a/src/designer/src/plugins/phononwidgets/images/seekslider.png b/src/designer/src/plugins/phononwidgets/images/seekslider.png
new file mode 100644
index 000000000..a1f4cb0d5
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/images/seekslider.png
Binary files differ
diff --git a/src/designer/src/plugins/phononwidgets/images/videoplayer.png b/src/designer/src/plugins/phononwidgets/images/videoplayer.png
new file mode 100644
index 000000000..55d86a6d3
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/images/videoplayer.png
Binary files differ
diff --git a/src/designer/src/plugins/phononwidgets/images/videowidget.png b/src/designer/src/plugins/phononwidgets/images/videowidget.png
new file mode 100644
index 000000000..3e8706e45
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/images/videowidget.png
Binary files differ
diff --git a/src/designer/src/plugins/phononwidgets/images/volumeslider.png b/src/designer/src/plugins/phononwidgets/images/volumeslider.png
new file mode 100644
index 000000000..ea81dd2a1
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/images/volumeslider.png
Binary files differ
diff --git a/src/designer/src/plugins/phononwidgets/phononcollection.cpp b/src/designer/src/plugins/phononwidgets/phononcollection.cpp
new file mode 100644
index 000000000..c26571434
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/phononcollection.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "videoplayerplugin.h"
+#include "seeksliderplugin.h"
+#include "volumesliderplugin.h"
+
+#include <QtDesigner/QDesignerCustomWidgetCollectionInterface>
+#include <QtCore/qplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+class PhononCollection: public QObject, public QDesignerCustomWidgetCollectionInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
+public:
+ explicit PhononCollection(QObject *parent = 0);
+
+ virtual QList<QDesignerCustomWidgetInterface*> customWidgets() const;
+
+private:
+ QList<QDesignerCustomWidgetInterface*> m_plugins;
+};
+
+PhononCollection::PhononCollection(QObject *parent) :
+ QObject(parent)
+{
+ const QString group = QLatin1String("Phonon");
+ m_plugins.push_back(new VideoPlayerPlugin(group, this));
+ m_plugins.push_back(new SeekSliderPlugin(group, this));
+ m_plugins.push_back(new VolumeSliderPlugin(group, this));
+}
+
+QList<QDesignerCustomWidgetInterface*> PhononCollection::customWidgets() const
+{
+ return m_plugins;
+}
+
+Q_EXPORT_PLUGIN(PhononCollection)
+
+QT_END_NAMESPACE
+
+#include "phononcollection.moc"
diff --git a/src/designer/src/plugins/phononwidgets/phononwidgets.pro b/src/designer/src/plugins/phononwidgets/phononwidgets.pro
new file mode 100644
index 000000000..4e0f0cc1a
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/phononwidgets.pro
@@ -0,0 +1,24 @@
+TEMPLATE = lib
+TARGET = phononwidgets
+CONFIG += qt warn_on plugin
+QT += phonon
+
+include(../plugins.pri)
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+# Input
+SOURCES += videoplayerplugin.cpp \
+ videoplayertaskmenu.cpp \
+ seeksliderplugin.cpp \
+ volumesliderplugin.cpp \
+ phononcollection.cpp
+
+HEADERS += videoplayerplugin.h \
+ videoplayertaskmenu.h \
+ seeksliderplugin.h \
+ volumesliderplugin.h
+
+RESOURCES += phononwidgets.qrc
diff --git a/src/designer/src/plugins/phononwidgets/phononwidgets.qrc b/src/designer/src/plugins/phononwidgets/phononwidgets.qrc
new file mode 100644
index 000000000..aa51330fd
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/phononwidgets.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/trolltech/phononwidgets">
+ <file>images/videoplayer.png</file>
+ <file>images/videowidget.png</file>
+ <file>images/seekslider.png</file>
+ <file>images/volumeslider.png</file>
+ </qresource>
+</RCC>
diff --git a/src/designer/src/plugins/phononwidgets/seeksliderplugin.cpp b/src/designer/src/plugins/phononwidgets/seeksliderplugin.cpp
new file mode 100644
index 000000000..23f479096
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/seeksliderplugin.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "seeksliderplugin.h"
+
+#include <phonon/seekslider.h>
+
+static const char *toolTipC = "Phonon Seek Slider";
+
+QT_BEGIN_NAMESPACE
+
+SeekSliderPlugin::SeekSliderPlugin(const QString &group, QObject *parent) :
+ QObject(parent),
+ m_group(group),
+ m_initialized(false)
+{
+}
+
+QString SeekSliderPlugin::name() const
+{
+ return QLatin1String("Phonon::SeekSlider");
+}
+
+QString SeekSliderPlugin::group() const
+{
+ return m_group;
+}
+
+QString SeekSliderPlugin::toolTip() const
+{
+ return tr(toolTipC);
+}
+
+QString SeekSliderPlugin::whatsThis() const
+{
+ return tr(toolTipC);
+}
+
+QString SeekSliderPlugin::includeFile() const
+{
+ return QLatin1String("<phonon/seekslider.h>");
+}
+
+QIcon SeekSliderPlugin::icon() const
+{
+ return QIcon(QLatin1String(":/trolltech/phononwidgets/images/seekslider.png"));
+}
+
+bool SeekSliderPlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *SeekSliderPlugin::createWidget(QWidget *parent)
+{
+ return new Phonon::SeekSlider(parent);
+}
+
+bool SeekSliderPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void SeekSliderPlugin::initialize(QDesignerFormEditorInterface *)
+{
+ if (m_initialized)
+ return;
+ m_initialized = true;
+}
+
+QString SeekSliderPlugin::domXml() const
+{
+ return QLatin1String("\
+ <ui language=\"c++\">\
+ <widget class=\"Phonon::SeekSlider\" name=\"seekSlider\"/>\
+ </ui>");
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/phononwidgets/seeksliderplugin.h b/src/designer/src/plugins/phononwidgets/seeksliderplugin.h
new file mode 100644
index 000000000..516ba73d1
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/seeksliderplugin.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SEEKSLIDER_PLUGIN_H
+#define SEEKSLIDER_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class SeekSliderPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit SeekSliderPlugin(const QString &group, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ const QString m_group;
+ bool m_initialized;
+};
+
+QT_END_NAMESPACE
+
+#endif // SEEKSLIDER_PLUGIN_H
diff --git a/src/designer/src/plugins/phononwidgets/videoplayerplugin.cpp b/src/designer/src/plugins/phononwidgets/videoplayerplugin.cpp
new file mode 100644
index 000000000..129ad1694
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/videoplayerplugin.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "videoplayerplugin.h"
+#include "videoplayertaskmenu.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtCore/qplugin.h>
+#include <phonon/videoplayer.h>
+
+static const char *toolTipC = "Phonon Video Player";
+
+QT_BEGIN_NAMESPACE
+
+VideoPlayerPlugin::VideoPlayerPlugin(const QString &group, QObject *parent) :
+ QObject(parent),
+ m_group(group),
+ m_initialized(false)
+{
+}
+
+QString VideoPlayerPlugin::name() const
+{
+ return QLatin1String("Phonon::VideoPlayer");
+}
+
+QString VideoPlayerPlugin::group() const
+{
+ return m_group;
+}
+
+QString VideoPlayerPlugin::toolTip() const
+{
+ return tr(toolTipC);
+}
+
+QString VideoPlayerPlugin::whatsThis() const
+{
+ return tr(toolTipC);
+}
+
+QString VideoPlayerPlugin::includeFile() const
+{
+ return QLatin1String("<phonon/videoplayer.h>");
+}
+
+QIcon VideoPlayerPlugin::icon() const
+{
+ return QIcon(QLatin1String(":/trolltech/phononwidgets/images/videoplayer.png"));
+}
+
+bool VideoPlayerPlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *VideoPlayerPlugin::createWidget(QWidget *parent)
+{
+ return new Phonon::VideoPlayer(Phonon::NoCategory, parent);
+}
+
+bool VideoPlayerPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void VideoPlayerPlugin::initialize(QDesignerFormEditorInterface * core)
+{
+ if (m_initialized)
+ return;
+
+ QExtensionManager *mgr = core->extensionManager();
+ VideoPlayerTaskMenuFactory::registerExtension(mgr, Q_TYPEID(QDesignerTaskMenuExtension));
+ m_initialized = true;
+}
+
+QString VideoPlayerPlugin::domXml() const
+{
+ return QLatin1String("\
+ <ui language=\"c++\">\
+ <widget class=\"Phonon::VideoPlayer\" name=\"videoPlayer\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>300</width>\
+ <height>200</height>\
+ </rect>\
+ </property>\
+ </widget>\
+ </ui>");
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/phononwidgets/videoplayerplugin.h b/src/designer/src/plugins/phononwidgets/videoplayerplugin.h
new file mode 100644
index 000000000..3d7c1b31c
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/videoplayerplugin.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIDEOPLAYER_PLUGIN_H
+#define VIDEOPLAYER_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class VideoPlayerPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit VideoPlayerPlugin(const QString &group, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ const QString m_group;
+ bool m_initialized;
+};
+
+QT_END_NAMESPACE
+
+#endif // VIDEOPLAYER_PLUGIN_H
diff --git a/src/designer/src/plugins/phononwidgets/videoplayertaskmenu.cpp b/src/designer/src/plugins/phononwidgets/videoplayertaskmenu.cpp
new file mode 100644
index 000000000..90cc96ffa
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/videoplayertaskmenu.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "videoplayertaskmenu.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <phonon/videoplayer.h>
+#include <phonon/mediaobject.h>
+
+#include <QtGui/QPlainTextEdit>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QAction>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+
+QT_BEGIN_NAMESPACE
+
+// ----------------- MimeTypeDialog: Display mime types in scrollable text
+
+class MimeTypeDialog : public QDialog {
+ Q_DISABLE_COPY(MimeTypeDialog)
+public:
+ explicit MimeTypeDialog(QWidget *parent = 0);
+
+ void setMimeTypes(const QStringList &);
+
+private:
+ QPlainTextEdit *m_plainTextEdit;
+};
+
+MimeTypeDialog::MimeTypeDialog(QWidget *parent) :
+ QDialog(parent),
+ m_plainTextEdit(new QPlainTextEdit)
+{
+ setModal(true);
+ setWindowTitle(VideoPlayerTaskMenu::tr("Available Mime Types"));
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ m_plainTextEdit->setReadOnly(true);
+ layout->addWidget(m_plainTextEdit);
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ layout->addWidget(buttonBox);
+
+ setLayout(layout);
+}
+
+void MimeTypeDialog::setMimeTypes(const QStringList &l)
+{
+ m_plainTextEdit->setPlainText(l.join(QString(1, QLatin1Char('\n'))));
+}
+
+// ----------------- VideoPlayerTaskMenu
+VideoPlayerTaskMenu::VideoPlayerTaskMenu(Phonon::VideoPlayer *object, QObject *parent) :
+ QObject(parent),
+ m_widget(object),
+ m_displayMimeTypesAction(new QAction(tr("Display supported mime types..."), this)),
+ m_loadAction(new QAction(tr("Load..."), this)),
+ m_playAction(new QAction(tr("Play"), this)),
+ m_pauseAction(new QAction(tr("Pause"), this)),
+ m_stopAction(new QAction(tr("Stop"), this))
+{
+ m_taskActions << m_displayMimeTypesAction << m_loadAction << m_playAction << m_pauseAction << m_stopAction;
+
+ connect(m_widget->mediaObject(), SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(mediaObjectStateChanged(Phonon::State,Phonon::State)));
+ connect(m_displayMimeTypesAction, SIGNAL(triggered()), this, SLOT(slotMimeTypes()));
+ connect(m_loadAction, SIGNAL(triggered()), this, SLOT(slotLoad()));
+ connect(m_playAction, SIGNAL(triggered()), object, SLOT(play()));
+ connect(m_pauseAction, SIGNAL(triggered()), object, SLOT(pause()));
+ connect(m_stopAction, SIGNAL(triggered()), object, SLOT(stop()));
+}
+
+QList<QAction*> VideoPlayerTaskMenu::taskActions() const
+{
+ const bool isPlaying = m_widget->isPlaying();
+ const bool isPaused = m_widget->isPlaying();
+ m_loadAction->setEnabled(!isPlaying && !isPaused);
+ m_playAction->setEnabled(!isPlaying);
+ m_pauseAction->setEnabled(isPlaying);
+ m_stopAction->setEnabled(isPlaying || isPaused);
+ return m_taskActions;
+}
+
+void VideoPlayerTaskMenu::slotMimeTypes()
+{
+ MimeTypeDialog mimeTypeDialog(m_widget->window());
+ mimeTypeDialog.setMimeTypes(Phonon::BackendCapabilities::availableMimeTypes());
+ mimeTypeDialog.exec();
+}
+
+void VideoPlayerTaskMenu::slotLoad()
+{
+ const QString fileName = QFileDialog::getOpenFileName(m_widget->window(), tr("Choose Video Player Media Source"));
+ if (fileName.isEmpty())
+ return;
+ m_widget->load(Phonon::MediaSource(fileName));
+
+}
+
+void VideoPlayerTaskMenu::mediaObjectStateChanged(Phonon::State newstate, Phonon::State /* oldstate */)
+{
+ if (newstate == Phonon::ErrorState) {
+ const QString msg = tr("An error has occurred in '%1': %2").arg(m_widget->objectName(), m_widget->mediaObject()->errorString());
+ QMessageBox::warning(m_widget->window(), tr("Video Player Error"), msg);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/phononwidgets/videoplayertaskmenu.h b/src/designer/src/plugins/phononwidgets/videoplayertaskmenu.h
new file mode 100644
index 000000000..a94061186
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/videoplayertaskmenu.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIDEOPLAYERTASKMENU_H
+#define VIDEOPLAYERTASKMENU_H
+
+
+#include <QtCore/QObject>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtDesigner/private/extensionfactory_p.h>
+
+#include <phonon/backendcapabilities.h>
+#include <phonon/videoplayer.h>
+
+QT_BEGIN_NAMESPACE
+
+class VideoPlayerTaskMenu: public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit VideoPlayerTaskMenu(Phonon::VideoPlayer *object, QObject *parent = 0);
+ virtual QList<QAction*> taskActions() const;
+
+private slots:
+ void slotLoad();
+ void slotMimeTypes();
+ void mediaObjectStateChanged(Phonon::State newstate, Phonon::State oldstate);
+
+private:
+ Phonon::VideoPlayer *m_widget;
+ QAction *m_displayMimeTypesAction;
+ QAction *m_loadAction;
+ QAction *m_playAction;
+ QAction *m_pauseAction;
+ QAction *m_stopAction;
+
+ QList<QAction*> m_taskActions;
+};
+
+typedef qdesigner_internal::ExtensionFactory<QDesignerTaskMenuExtension, Phonon::VideoPlayer, VideoPlayerTaskMenu> VideoPlayerTaskMenuFactory;
+
+QT_END_NAMESPACE
+
+#endif // VIDEOPLAYERTASKMENU_H
diff --git a/src/designer/src/plugins/phononwidgets/volumesliderplugin.cpp b/src/designer/src/plugins/phononwidgets/volumesliderplugin.cpp
new file mode 100644
index 000000000..bff21b61f
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/volumesliderplugin.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "volumesliderplugin.h"
+
+#include <phonon/volumeslider.h>
+
+static const char *toolTipC = "Phonon Volume Slider";
+
+QT_BEGIN_NAMESPACE
+
+VolumeSliderPlugin::VolumeSliderPlugin(const QString &group, QObject *parent) :
+ QObject(parent),
+ m_group(group),
+ m_initialized(false)
+{
+}
+
+QString VolumeSliderPlugin::name() const
+{
+ return QLatin1String("Phonon::VolumeSlider");
+}
+
+QString VolumeSliderPlugin::group() const
+{
+ return m_group;
+}
+
+QString VolumeSliderPlugin::toolTip() const
+{
+ return tr(toolTipC);
+}
+
+QString VolumeSliderPlugin::whatsThis() const
+{
+ return tr(toolTipC);
+}
+
+QString VolumeSliderPlugin::includeFile() const
+{
+ return QLatin1String("<phonon/volumeslider.h>");
+}
+
+QIcon VolumeSliderPlugin::icon() const
+{
+ return QIcon(QLatin1String(":/trolltech/phononwidgets/images/volumeslider.png"));
+}
+
+bool VolumeSliderPlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *VolumeSliderPlugin::createWidget(QWidget *parent)
+{
+ return new Phonon::VolumeSlider(parent);
+}
+
+bool VolumeSliderPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void VolumeSliderPlugin::initialize(QDesignerFormEditorInterface *)
+{
+ if (m_initialized)
+ return;
+ m_initialized = true;
+}
+
+QString VolumeSliderPlugin::domXml() const
+{
+ return QLatin1String("\
+ <ui language=\"c++\">\
+ <widget class=\"Phonon::VolumeSlider\" name=\"volumeSlider\"/>\
+ </ui>");
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/phononwidgets/volumesliderplugin.h b/src/designer/src/plugins/phononwidgets/volumesliderplugin.h
new file mode 100644
index 000000000..005215e62
--- /dev/null
+++ b/src/designer/src/plugins/phononwidgets/volumesliderplugin.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VOLUMESLIDER_PLUGIN_H
+#define VOLUMESLIDER_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class VolumeSliderPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit VolumeSliderPlugin(const QString &group, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ const QString m_group;
+ bool m_initialized;
+};
+
+QT_END_NAMESPACE
+
+#endif // VOLUMESLIDER_PLUGIN_H
diff --git a/src/designer/src/plugins/plugins.pri b/src/designer/src/plugins/plugins.pri
new file mode 100644
index 000000000..e5edfe2f2
--- /dev/null
+++ b/src/designer/src/plugins/plugins.pri
@@ -0,0 +1,8 @@
+CONFIG += designer
+win32|mac: CONFIG+= debug_and_release
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/designer
+contains(TEMPLATE, ".*lib"):TARGET = $$qtLibraryTarget($$TARGET)
+
+# install
+target.path = $$[QT_INSTALL_PLUGINS]/designer
+INSTALLS += target
diff --git a/src/designer/src/plugins/plugins.pro b/src/designer/src/plugins/plugins.pro
new file mode 100644
index 000000000..bcebb82ec
--- /dev/null
+++ b/src/designer/src/plugins/plugins.pro
@@ -0,0 +1,10 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+REQUIRES = !CONFIG(static,shared|static)
+contains(QT_CONFIG, qt3support): SUBDIRS += widgets
+win32: SUBDIRS += activeqt
+# contains(QT_CONFIG, opengl): SUBDIRS += tools/view3d
+contains(QT_CONFIG, webkit): SUBDIRS += qwebview
+contains(QT_CONFIG, phonon): SUBDIRS += phononwidgets
+contains(QT_CONFIG, declarative): SUBDIRS += qdeclarativeview
diff --git a/src/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro b/src/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro
new file mode 100644
index 000000000..b8abe8741
--- /dev/null
+++ b/src/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+TARGET = qdeclarativeview
+CONFIG += qt warn_on plugin designer
+QT += declarative
+
+include(../plugins.pri)
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+SOURCES += qdeclarativeview_plugin.cpp
+HEADERS += qdeclarativeview_plugin.h
diff --git a/src/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp b/src/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp
new file mode 100644
index 000000000..99dac8aa9
--- /dev/null
+++ b/src/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativeview_plugin.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtDeclarative/QDeclarativeView>
+
+static const char toolTipC[] = "QtDeclarative view widget";
+
+QT_BEGIN_NAMESPACE
+
+QDeclarativeViewPlugin::QDeclarativeViewPlugin(QObject *parent) :
+ QObject(parent),
+ m_initialized(false)
+{
+}
+
+QString QDeclarativeViewPlugin::name() const
+{
+ return QLatin1String("QDeclarativeView");
+}
+
+QString QDeclarativeViewPlugin::group() const
+{
+ return QLatin1String("Display Widgets");
+}
+
+QString QDeclarativeViewPlugin::toolTip() const
+{
+ return tr(toolTipC);
+}
+
+QString QDeclarativeViewPlugin::whatsThis() const
+{
+ return tr(toolTipC);
+}
+
+QString QDeclarativeViewPlugin::includeFile() const
+{
+ return QLatin1String("QtDeclarative/QDeclarativeView");
+}
+
+QIcon QDeclarativeViewPlugin::icon() const
+{
+ return QIcon();
+}
+
+bool QDeclarativeViewPlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *QDeclarativeViewPlugin::createWidget(QWidget *parent)
+{
+ return new QDeclarativeView(parent);
+}
+
+bool QDeclarativeViewPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void QDeclarativeViewPlugin::initialize(QDesignerFormEditorInterface * /*core*/)
+{
+ if (m_initialized)
+ return;
+
+ m_initialized = true;
+}
+
+QString QDeclarativeViewPlugin::domXml() const
+{
+ return QLatin1String("\
+ <ui language=\"c++\">\
+ <widget class=\"QDeclarativeView\" name=\"declarativeView\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>300</width>\
+ <height>200</height>\
+ </rect>\
+ </property>\
+ </widget>\
+ </ui>");
+}
+
+Q_EXPORT_PLUGIN2(customwidgetplugin, QDeclarativeViewPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h b/src/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h
new file mode 100644
index 000000000..0f14df74f
--- /dev/null
+++ b/src/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEVIEW_PLUGIN_H
+#define QDECLARATIVEVIEW_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeViewPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ QDeclarativeViewPlugin(QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEVIEW_PLUGIN_H
diff --git a/src/designer/src/plugins/qwebview/images/qwebview.png b/src/designer/src/plugins/qwebview/images/qwebview.png
new file mode 100644
index 000000000..01a0920c9
--- /dev/null
+++ b/src/designer/src/plugins/qwebview/images/qwebview.png
Binary files differ
diff --git a/src/designer/src/plugins/qwebview/qwebview.pro b/src/designer/src/plugins/qwebview/qwebview.pro
new file mode 100644
index 000000000..b1f6371d1
--- /dev/null
+++ b/src/designer/src/plugins/qwebview/qwebview.pro
@@ -0,0 +1,15 @@
+TEMPLATE = lib
+TARGET = qwebview
+CONFIG += qt warn_on plugin
+QT += webkit
+
+include(../plugins.pri)
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+# Input
+SOURCES += qwebview_plugin.cpp
+HEADERS += qwebview_plugin.h
+RESOURCES += qwebview_plugin.qrc
diff --git a/src/designer/src/plugins/qwebview/qwebview_plugin.cpp b/src/designer/src/plugins/qwebview/qwebview_plugin.cpp
new file mode 100644
index 000000000..9c965f0ca
--- /dev/null
+++ b/src/designer/src/plugins/qwebview/qwebview_plugin.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebview_plugin.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtWebKit/QWebView>
+
+static const char *toolTipC = "QtWebKit Web widget";
+
+QT_BEGIN_NAMESPACE
+
+QWebViewPlugin::QWebViewPlugin(QObject *parent) :
+ QObject(parent),
+ m_initialized(false)
+{
+}
+
+QString QWebViewPlugin::name() const
+{
+ return QLatin1String("QWebView");
+}
+
+QString QWebViewPlugin::group() const
+{
+ return QLatin1String("Display Widgets");
+}
+
+QString QWebViewPlugin::toolTip() const
+{
+ return tr(toolTipC);
+}
+
+QString QWebViewPlugin::whatsThis() const
+{
+ return tr(toolTipC);
+}
+
+QString QWebViewPlugin::includeFile() const
+{
+ return QLatin1String("QtWebKit/QWebView");
+}
+
+QIcon QWebViewPlugin::icon() const
+{
+ return QIcon(QLatin1String(":/trolltech/qwebview/images/qwebview.png"));
+}
+
+bool QWebViewPlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *QWebViewPlugin::createWidget(QWidget *parent)
+{
+ return new QWebView(parent);
+}
+
+bool QWebViewPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void QWebViewPlugin::initialize(QDesignerFormEditorInterface * /*core*/)
+{
+ if (m_initialized)
+ return;
+
+ m_initialized = true;
+}
+
+QString QWebViewPlugin::domXml() const
+{
+ return QLatin1String("\
+ <ui language=\"c++\">\
+ <widget class=\"QWebView\" name=\"webView\">\
+ <property name=\"url\">\
+ <url>\
+ <string>about:blank</string>\
+ </url>\
+ </property>\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>300</width>\
+ <height>200</height>\
+ </rect>\
+ </property>\
+ </widget>\
+ </ui>");
+}
+
+Q_EXPORT_PLUGIN2(customwidgetplugin, QWebViewPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/qwebview/qwebview_plugin.h b/src/designer/src/plugins/qwebview/qwebview_plugin.h
new file mode 100644
index 000000000..d364bc1a4
--- /dev/null
+++ b/src/designer/src/plugins/qwebview/qwebview_plugin.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBPAGE_PLUGIN_H
+#define QWEBPAGE_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QWebViewPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ QWebViewPlugin(QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBPAGE_PLUGIN_H
diff --git a/src/designer/src/plugins/qwebview/qwebview_plugin.qrc b/src/designer/src/plugins/qwebview/qwebview_plugin.qrc
new file mode 100644
index 000000000..a3e2b9016
--- /dev/null
+++ b/src/designer/src/plugins/qwebview/qwebview_plugin.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/trolltech/qwebview">
+ <file>images/qwebview.png</file>
+ </qresource>
+</RCC>
diff --git a/src/designer/src/plugins/tools/view3d/view3d.cpp b/src/designer/src/plugins/tools/view3d/view3d.cpp
new file mode 100644
index 000000000..06718f433
--- /dev/null
+++ b/src/designer/src/plugins/tools/view3d/view3d.cpp
@@ -0,0 +1,492 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtGui>
+#include <QtOpenGL>
+
+#include "abstractformeditor.h"
+#include "abstractmetadatabase.h"
+#include "abstractformwindow.h"
+#include "view3d.h"
+
+#define SELECTION_BUFSIZE 512
+
+/*******************************************************************************
+** QView3DWidget
+*/
+
+class QView3DWidget : public QGLWidget
+{
+ Q_OBJECT
+public:
+ QView3DWidget(QWidget *parent);
+ virtual void initializeGL();
+ virtual void resizeGL(int w, int h);
+ virtual void paintGL();
+ void clear();
+
+ void addTexture(QWidget *w, const QPixmap &pm);
+
+ void beginAddingWidgets(QWidget *form);
+ void addWidget(int depth, QWidget *w);
+ void endAddingWidgets();
+
+ QWidget *widgetAt(const QPoint &pos);
+
+signals:
+ void updateForm();
+
+protected:
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void wheelEvent(QWheelEvent *);
+ void keyReleaseEvent(QKeyEvent *);
+
+ void contextMenuEvent(QContextMenuEvent *);
+
+private:
+ QWidget *m_form;
+ QPoint m_old_pos;
+ bool m_layer_coloring;
+ bool m_use_mipmaps;
+ GLuint m_form_list_id;
+
+ typedef QMap<QWidget*, GLuint> TextureMap;
+ TextureMap m_texture_map;
+
+ typedef QMap<GLuint, QWidget*> WidgetNameMap;
+ GLuint m_next_widget_name;
+ WidgetNameMap m_widget_name_map;
+};
+
+QView3DWidget::QView3DWidget(QWidget *parent)
+ : QGLWidget(parent)
+ , m_layer_coloring(true)
+ , m_form_list_id(0)
+ , m_next_widget_name(0)
+{
+ setFocusPolicy(Qt::StrongFocus);
+}
+
+static int nearestSize(int v)
+{
+ int n = 0, last = 0;
+ for (int s = 0; s < 32; ++s) {
+ if (((v>>s) & 1) == 1) {
+ ++n;
+ last = s;
+ }
+ }
+ if (n > 1)
+ return 1 << (last+1);
+ return 1 << last;
+}
+
+// static int pm_cnt = 0;
+
+void QView3DWidget::addTexture(QWidget *w, const QPixmap &pm)
+{
+ int tx_w = nearestSize(pm.width());
+ int tx_h = nearestSize(pm.height());
+
+ QPixmap tmp(tx_w, tx_h);
+ tmp.fill(QColor(0,0,0));
+ QPainter p(&tmp);
+ p.drawPixmap(0, tx_h - pm.height(), pm);
+ p.end();
+ QImage tex = tmp.toImage();
+
+// QString file_name = QString("pixmapDump%1.png").arg(pm_cnt++);
+// qDebug() << "grabWidget():" << file_name << tex.save(file_name, "PNG");
+
+ tex = QGLWidget::convertToGLFormat(tex);
+
+ GLuint tx_id;
+ glGenTextures(1, &tx_id);
+ glBindTexture(GL_TEXTURE_2D, tx_id);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if (m_use_mipmaps) {
+ //glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
+ //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.f);
+ } else {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex.width(), tex.height(), 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, tex.bits());
+ m_texture_map[w] = tx_id;
+}
+
+void QView3DWidget::addWidget(int depth, QWidget *widget)
+{
+ TextureMap::const_iterator it = m_texture_map.find(widget);
+ Q_ASSERT(it != m_texture_map.end());
+
+ makeCurrent();
+
+ int w = m_form->size().width();
+ int h = m_form->size().height();
+ int max = qMax(w, h);
+ QRect r = widget->rect();
+ QPoint pos = widget->mapToGlobal(QPoint(0, 0));
+ r.moveTopLeft(m_form->mapFromGlobal(pos));
+
+ float s = r.width()/float(nearestSize(r.width()));
+ float t = r.height()/float(nearestSize(r.height()));
+
+ if (m_layer_coloring)
+ glColor4f(1.0 - depth/10.0, 1.0 - depth/10.0, 1.0, 1.0 - depth/20.0);
+ else
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
+ glBindTexture(GL_TEXTURE_2D, *it);
+ glBegin(GL_QUADS);
+ glLoadName(m_next_widget_name);
+ glTexCoord2f(0.0, 0.0); glVertex3f(r.left() - w/2, r.bottom() - h/2, depth*max/8);
+ glTexCoord2f(s, 0.0); glVertex3f(r.right() - w/2, r.bottom()- h/2, depth*max/8);
+ glTexCoord2f(s, t); glVertex3f(r.right() - w/2, r.top() - h/2, depth*max/8);
+ glTexCoord2f(0.0, t); glVertex3f(r.left() - w/2, r.top() - h/2, depth*max/8);
+ glEnd();
+
+ m_widget_name_map[m_next_widget_name++] = widget;
+}
+
+void QView3DWidget::clear()
+{
+ makeCurrent();
+ glDeleteLists(m_form_list_id, 1);
+ foreach (GLuint id, m_texture_map)
+ glDeleteTextures(1, &id);
+ m_texture_map.clear();
+ m_widget_name_map.clear();
+ m_next_widget_name = 0;
+}
+
+void QView3DWidget::beginAddingWidgets(QWidget *form)
+{
+ makeCurrent();
+ m_form = form;
+ m_form_list_id = glGenLists(1);
+ glNewList(m_form_list_id, GL_COMPILE);
+ glInitNames();
+ glPushName(-1);
+ m_next_widget_name = 0;
+}
+
+void QView3DWidget::endAddingWidgets()
+{
+ makeCurrent();
+ glEndList();
+}
+
+void QView3DWidget::initializeGL()
+{
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ qglClearColor(palette().color(QPalette::Window).dark());
+ glColor3f (1.0, 1.0, 1.0);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+
+ glShadeModel(GL_FLAT);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ QString extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
+ m_use_mipmaps = false;// extensions.contains("GL_SGIS_generate_mipmap");
+}
+
+void QView3DWidget::resizeGL(int width, int height)
+{
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-width/2, width/2, height/2, -height/2, -999999, 999999);
+}
+
+void QView3DWidget::paintGL()
+{
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glCallList(m_form_list_id);
+
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glTranslatef(-width()/2, -height()/2, 0.0);
+
+ QFontMetrics fm(font());
+ glColor4f(0.4, 0.4, 0.4, 0.7);
+ glRecti(0, height() - fm.lineSpacing()*2.5, width(), height());
+
+ glColor3f(1.0, 1.0, 1.0);
+ renderText(10, height() - fm.lineSpacing()*1.5,
+ "Press and hold left/right mouse button = tilt the view.");
+ renderText(10, height() - fm.lineSpacing()*0.5,
+ "Mouse wheel = zoom. 't' = toggle layer coloring. 'r' = reset transform.");
+ glPopMatrix();
+ glPopAttrib();
+}
+
+QWidget *QView3DWidget::widgetAt(const QPoint &pos)
+{
+ makeCurrent();
+ GLuint selectBuf[SELECTION_BUFSIZE];
+ glSelectBuffer(SELECTION_BUFSIZE, selectBuf);
+ glRenderMode (GL_SELECT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glCallList(m_form_list_id);
+ return 0;
+}
+
+void QView3DWidget::keyReleaseEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_T) {
+ m_layer_coloring = !m_layer_coloring;
+ emit updateForm();
+ } else if (e->key() == Qt::Key_R) {
+ makeCurrent();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ }
+
+ updateGL();
+}
+
+void QView3DWidget::mousePressEvent(QMouseEvent *e)
+{
+ m_old_pos = e->pos();
+}
+
+void QView3DWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ m_old_pos = e->pos();
+}
+
+void QView3DWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ if (e->buttons() & (Qt::LeftButton | Qt::RightButton)) {
+ GLfloat rx = (GLfloat) (e->x() - m_old_pos.x()) / width();
+ GLfloat ry = (GLfloat) (e->y() - m_old_pos.y()) / height();
+
+ makeCurrent();
+ glMatrixMode(GL_MODELVIEW);
+ if (e->buttons() & Qt::LeftButton) {
+ // Left button down - rotate around X and Y axes
+ glRotatef(-180*ry, 1, 0, 0);
+ glRotatef(180*rx, 0, 1, 0);
+ } else if (e->buttons() & Qt::RightButton) {
+ // Right button down - rotate around X and Z axes
+ glRotatef(-180*ry, 1, 0, 0);
+ glRotatef(-180*rx, 0, 0, 1);
+ }
+ updateGL();
+ m_old_pos = e->pos();
+ } else {
+
+ }
+}
+
+void QView3DWidget::wheelEvent(QWheelEvent *e)
+{
+ makeCurrent();
+ glMatrixMode(GL_MODELVIEW);
+ if (e->delta() < 0)
+ glScalef(0.9, 0.9, 0.9);
+ else
+ glScalef(1.1, 1.1, 1.1);
+ updateGL();
+}
+
+void QView3DWidget::contextMenuEvent(QContextMenuEvent *e)
+{
+ e->accept();
+}
+
+/*******************************************************************************
+** Misc tools
+*/
+
+class WalkWidgetTreeFunction
+{
+public:
+ virtual void operator () (int depth, QWidget *widget) const = 0;
+};
+
+static bool skipWidget(QDesignerFormEditorInterface *core, QWidget *widget)
+{
+ QDesignerMetaDataBaseItemInterface *item = core->metaDataBase()->item(widget);
+ if (item == 0)
+ return true;
+ QString name = widget->metaObject()->className();
+ if (name == "QLayoutWidget")
+ return true;
+
+ return false;
+}
+
+static void walkWidgetTree(QDesignerFormEditorInterface *core, int depth, QWidget *widget, const WalkWidgetTreeFunction &func)
+{
+ if (widget == 0)
+ return;
+ if (!widget->isVisible())
+ return;
+
+ if (!skipWidget(core, widget))
+ func(depth++, widget);
+
+ QObjectList child_obj_list = widget->children();
+ foreach (QObject *child_obj, child_obj_list) {
+ QWidget *child = qobject_cast<QWidget*>(child_obj);
+ if (child != 0)
+ walkWidgetTree(core, depth, child, func);
+ }
+}
+
+static void grabWidget_helper(QWidget *widget, QPixmap &res, QPixmap &buf,
+ const QRect &r, const QPoint &offset, QDesignerFormEditorInterface *core)
+{
+ buf.fill(widget, r.topLeft());
+ QPainter::setRedirected(widget, &buf, r.topLeft());
+ QPaintEvent e(r & widget->rect());
+ QApplication::sendEvent(widget, &e);
+ QPainter::restoreRedirected(widget);
+ {
+ QPainter pt(&res);
+ pt.drawPixmap(offset.x(), offset.y(), buf, 0, 0, r.width(), r.height());
+ }
+
+ const QObjectList children = widget->children();
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *child = qobject_cast<QWidget*>(children.at(i));
+ if (child == 0 || child->isWindow())
+ continue;
+ if (child->isHidden() || !child->geometry().intersects(r))
+ continue;
+ if (core->metaDataBase()->item(child) != 0)
+ continue;
+ QRect cr = r & child->geometry();
+ cr.translate(-child->pos());
+ grabWidget_helper(child, res, buf, cr, offset + child->pos(), core);
+ }
+}
+
+static QPixmap grabWidget(QWidget * widget, QDesignerFormEditorInterface *core)
+{
+ if (!widget)
+ return QPixmap();
+
+ QRect r = widget->rect();
+ QSize s = widget->size();
+
+ QPixmap res(s), buf(s);
+
+ grabWidget_helper(widget, res, buf, r, QPoint(), core);
+
+ return res;
+}
+
+/*******************************************************************************
+** QView3D
+*/
+
+class AddTexture : public WalkWidgetTreeFunction
+{
+public:
+ inline AddTexture(QDesignerFormEditorInterface *core, QView3DWidget *w)
+ : m_core(core), m_3d_widget(w) {}
+ inline virtual void operator ()(int, QWidget *w) const
+ { m_3d_widget->addTexture(w, ::grabWidget(w, m_core)); }
+ QDesignerFormEditorInterface *m_core;
+ QView3DWidget *m_3d_widget;
+};
+
+class AddWidget : public WalkWidgetTreeFunction
+{
+public:
+ inline AddWidget(QView3DWidget *w) : m_3d_widget(w) {}
+ inline virtual void operator ()(int depth, QWidget *w) const
+ { m_3d_widget->addWidget(depth, w); }
+ QView3DWidget *m_3d_widget;
+};
+
+QView3D::QView3D(QDesignerFormWindowInterface *form_window, QWidget *parent)
+ : QWidget(parent)
+{
+ m_form_window = form_window;
+ m_3d_widget = new QView3DWidget(this);
+ connect(m_3d_widget, SIGNAL(updateForm()), this, SLOT(updateForm()));
+
+ QGridLayout *layout = new QGridLayout(this);
+ layout->setMargin(0);
+ layout->addWidget(m_3d_widget, 0, 0, 1, 1);
+
+ updateForm();
+}
+
+void QView3D::updateForm()
+{
+ QWidget *w = m_form_window->mainContainer();
+ if (w == 0)
+ return;
+
+ m_3d_widget->clear();
+
+ walkWidgetTree(m_form_window->core(), 0, w, AddTexture(m_form_window->core(), m_3d_widget));
+ m_3d_widget->beginAddingWidgets(w);
+ walkWidgetTree(m_form_window->core(), 0, w, AddWidget(m_3d_widget));
+ m_3d_widget->endAddingWidgets();
+}
+
+#include "view3d.moc"
diff --git a/src/designer/src/plugins/tools/view3d/view3d.h b/src/designer/src/plugins/tools/view3d/view3d.h
new file mode 100644
index 000000000..43e2ae9eb
--- /dev/null
+++ b/src/designer/src/plugins/tools/view3d/view3d.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIEW3D_H
+#define VIEW3D_H
+
+#include "view3d_global.h"
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QScrollBar;
+class QGLWidget;
+class QDesignerFormWindowInterface;
+
+class QView3DWidget;
+
+class QView3D : public QWidget
+{
+ Q_OBJECT
+
+public:
+ QView3D(QDesignerFormWindowInterface *form_window, QWidget *parent);
+
+public slots:
+ void updateForm();
+
+private:
+ QView3DWidget *m_3d_widget;
+ QDesignerFormWindowInterface *m_form_window;
+
+ void addWidget(int depth, QWidget *w);
+ void addTexture(QWidget *w);
+};
+
+#endif // VIEW3D_H
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/tools/view3d/view3d.pro b/src/designer/src/plugins/tools/view3d/view3d.pro
new file mode 100644
index 000000000..c28c70693
--- /dev/null
+++ b/src/designer/src/plugins/tools/view3d/view3d.pro
@@ -0,0 +1,17 @@
+
+TEMPLATE = lib
+QT += opengl
+CONFIG += qt warn_on plugin
+DESTDIR =
+TARGET = view3d
+
+include(../../plugins.pri)
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+# Input
+SOURCES += view3d.cpp view3d_tool.cpp view3d_plugin.cpp
+HEADERS += view3d.h view3d_tool.h view3d_plugin.h view3d_global.h
+
diff --git a/src/designer/src/plugins/tools/view3d/view3d_global.h b/src/designer/src/plugins/tools/view3d/view3d_global.h
new file mode 100644
index 000000000..5eb936ab4
--- /dev/null
+++ b/src/designer/src/plugins/tools/view3d/view3d_global.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIEW3D_GLOBAL_H
+#define VIEW3D_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN
+#ifdef VIEW3D_LIBRARY
+# define VIEW3D_EXPORT
+#else
+# define VIEW3D_EXPORT
+#endif
+#else
+#define VIEW3D_EXPORT
+#endif
+
+#endif // VIEW3D_GLOBAL_H
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/tools/view3d/view3d_plugin.cpp b/src/designer/src/plugins/tools/view3d/view3d_plugin.cpp
new file mode 100644
index 000000000..62b7868e7
--- /dev/null
+++ b/src/designer/src/plugins/tools/view3d/view3d_plugin.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qplugin.h>
+#include <QtGui/QAction>
+#include "view3d_plugin.h"
+#include "view3d_tool.h"
+
+QView3DPlugin::QView3DPlugin()
+{
+ m_core = 0;
+ m_action = 0;
+}
+
+bool QView3DPlugin::isInitialized() const
+{
+ return m_core != 0;
+}
+
+void QView3DPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_ASSERT(!isInitialized());
+
+ m_action = new QAction(tr("3D View"), this);
+ m_core = core;
+ setParent(core);
+
+ connect(core->formWindowManager(), SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)),
+ this, SLOT(addFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core->formWindowManager(), SIGNAL(formWindowRemoved(QDesignerFormWindowInterface*)),
+ this, SLOT(removeFormWindow(QDesignerFormWindowInterface*)));
+
+ connect(core->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface*)));
+}
+
+QAction *QView3DPlugin::action() const
+{
+ return m_action;
+}
+
+QDesignerFormEditorInterface *QView3DPlugin::core() const
+{
+ return m_core;
+}
+
+void QView3DPlugin::activeFormWindowChanged(QDesignerFormWindowInterface *formWindow)
+{
+ m_action->setEnabled(formWindow != 0);
+}
+
+void QView3DPlugin::addFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_ASSERT(formWindow != 0);
+ Q_ASSERT(m_tool_list.contains(formWindow) == false);
+
+ QView3DTool *tool = new QView3DTool(formWindow, this);
+ m_tool_list[formWindow] = tool;
+ connect(m_action, SIGNAL(triggered()), tool->action(), SLOT(trigger()));
+ formWindow->registerTool(tool);
+}
+
+void QView3DPlugin::removeFormWindow(QDesignerFormWindowInterface *formWindow)
+{
+ Q_ASSERT(formWindow != 0);
+ Q_ASSERT(m_tool_list.contains(formWindow));
+
+ QView3DTool *tool = m_tool_list.value(formWindow);
+ m_tool_list.remove(formWindow);
+ disconnect(m_action, SIGNAL(triggered()), tool->action(), SLOT(trigger()));
+
+ delete tool;
+}
+
+Q_EXPORT_PLUGIN2(view3d, QView3DPlugin)
diff --git a/src/designer/src/plugins/tools/view3d/view3d_plugin.h b/src/designer/src/plugins/tools/view3d/view3d_plugin.h
new file mode 100644
index 000000000..6845bb30a
--- /dev/null
+++ b/src/designer/src/plugins/tools/view3d/view3d_plugin.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3VIEW3D_PLUGIN_H
+#define Q3VIEW3D_PLUGIN_H
+
+#include <QtCore/QList>
+#include <QtCore/QHash>
+#include <QtDesigner/QDesignerFormEditorPluginInterface>
+#include "view3d_global.h"
+
+QT_BEGIN_NAMESPACE
+
+class QView3DTool;
+class QAction;
+
+class VIEW3D_EXPORT QView3DPlugin : public QObject, public QDesignerFormEditorPluginInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerFormEditorPluginInterface)
+
+public:
+ QView3DPlugin();
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QAction *action() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+public slots:
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+
+private slots:
+ void addFormWindow(QDesignerFormWindowInterface *formWindow);
+ void removeFormWindow(QDesignerFormWindowInterface *formWindow);
+
+private:
+ QPointer<QDesignerFormEditorInterface> m_core;
+ QHash<QDesignerFormWindowInterface*, QView3DTool*> m_tool_list;
+ QAction *m_action;
+};
+
+#endif // QVIEW3D_PLUGIN_H
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/tools/view3d/view3d_tool.cpp b/src/designer/src/plugins/tools/view3d/view3d_tool.cpp
new file mode 100644
index 000000000..e92a58bc9
--- /dev/null
+++ b/src/designer/src/plugins/tools/view3d/view3d_tool.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QAction>
+#include "view3d_tool.h"
+
+QView3DTool::QView3DTool(QDesignerFormWindowInterface *formWindow, QObject *parent)
+ : QDesignerFormWindowToolInterface(parent)
+{
+ m_action = new QAction(tr("3DView"), this);
+ m_formWindow = formWindow;
+}
+
+QDesignerFormEditorInterface *QView3DTool::core() const
+{
+ return m_formWindow->core();
+}
+
+QDesignerFormWindowInterface *QView3DTool::formWindow() const
+{
+ return m_formWindow;
+}
+
+QWidget *QView3DTool::editor() const
+{
+ if (m_editor == 0)
+ m_editor = new QView3D(formWindow(), 0);
+
+ return m_editor;
+}
+
+QAction *QView3DTool::action() const
+{
+ return m_action;
+}
+
+void QView3DTool::activated()
+{
+ if (m_editor != 0)
+ m_editor->updateForm();
+}
+
+void QView3DTool::deactivated()
+{
+}
+
+bool QView3DTool::handleEvent(QWidget*, QWidget*, QEvent*)
+{
+ return false;
+}
diff --git a/src/designer/src/plugins/tools/view3d/view3d_tool.h b/src/designer/src/plugins/tools/view3d/view3d_tool.h
new file mode 100644
index 000000000..acb4dc1b6
--- /dev/null
+++ b/src/designer/src/plugins/tools/view3d/view3d_tool.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIEW3D_TOOL_H
+#define VIEW3D_TOOL_H
+
+#include "view3d_global.h"
+#include "view3d.h"
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+
+QT_BEGIN_NAMESPACE
+
+class VIEW3D_EXPORT QView3DTool : public QDesignerFormWindowToolInterface
+{
+ Q_OBJECT
+
+public:
+ explicit QView3DTool(QDesignerFormWindowInterface *formWindow, QObject *parent = 0);
+ virtual QDesignerFormEditorInterface *core() const;
+ virtual QDesignerFormWindowInterface *formWindow() const;
+ virtual QWidget *editor() const;
+
+ virtual QAction *action() const;
+
+ virtual void activated();
+ virtual void deactivated();
+
+ virtual bool handleEvent(QWidget *widget, QWidget *managedWidget, QEvent *event);
+
+private:
+ QDesignerFormWindowInterface *m_formWindow;
+ mutable QPointer<QView3D> m_editor;
+ QAction *m_action;
+};
+
+#endif // VIEW3D_TOOL_H
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3iconview/q3iconview_extrainfo.cpp b/src/designer/src/plugins/widgets/q3iconview/q3iconview_extrainfo.cpp
new file mode 100644
index 000000000..35c8e32c3
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3iconview/q3iconview_extrainfo.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3iconview_extrainfo.h"
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/private/ui4_p.h>
+
+#include <Qt3Support/Q3IconView>
+
+QT_BEGIN_NAMESPACE
+
+inline QHash<QString, DomProperty *> propertyMap(const QList<DomProperty *> &properties) // ### remove me
+{
+ QHash<QString, DomProperty *> map;
+
+ for (int i=0; i<properties.size(); ++i) {
+ DomProperty *p = properties.at(i);
+ map.insert(p->attributeName(), p);
+ }
+
+ return map;
+}
+
+Q3IconViewExtraInfo::Q3IconViewExtraInfo(Q3IconView *widget, QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), m_widget(widget), m_core(core)
+{}
+
+QWidget *Q3IconViewExtraInfo::widget() const
+{ return m_widget; }
+
+QDesignerFormEditorInterface *Q3IconViewExtraInfo::core() const
+{ return m_core; }
+
+bool Q3IconViewExtraInfo::saveUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+bool Q3IconViewExtraInfo::loadUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+
+bool Q3IconViewExtraInfo::saveWidgetExtraInfo(DomWidget *ui_widget)
+{
+ // ### finish me
+ Q3IconView *iconView = qobject_cast<Q3IconView*>(widget());
+ Q_ASSERT(iconView != 0);
+
+ QList<DomItem*> ui_items;
+
+ Q3IconViewItem *__item = iconView->firstItem();
+ while (__item != 0) {
+ DomItem *ui_item = new DomItem();
+
+ QList<DomProperty*> properties;
+
+ // text property
+ DomProperty *ptext = new DomProperty();
+ DomString *str = new DomString();
+ str->setText(__item->text());
+ ptext->setAttributeName(QLatin1String("text"));
+ ptext->setElementString(str);
+ properties.append(ptext);
+
+ ui_item->setElementProperty(properties);
+ ui_items.append(ui_item);
+
+ if (__item->pixmap() != 0 && core()->iconCache()) {
+ QPixmap pix = *__item->pixmap();
+ QString filePath = core()->iconCache()->pixmapToFilePath(pix);
+ QString qrcPath = core()->iconCache()->pixmapToQrcPath(pix);
+ DomResourcePixmap *ui_pix = new DomResourcePixmap();
+ if (!qrcPath.isEmpty())
+ ui_pix->setAttributeResource(qrcPath);
+ ui_pix->setText(filePath);
+
+ DomProperty *ppix = new DomProperty();
+ ppix->setAttributeName(QLatin1String("pixmap"));
+ ppix->setElementPixmap(ui_pix);
+ properties.append(ppix);
+ }
+
+ __item = __item->nextItem();
+ }
+
+ ui_widget->setElementItem(ui_items);
+
+ return true;
+}
+
+bool Q3IconViewExtraInfo::loadWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q3IconView *iconView = qobject_cast<Q3IconView*>(widget());
+ Q_ASSERT(iconView != 0);
+ Q_UNUSED(iconView);
+
+ if (ui_widget->elementItem().size()) {
+ initializeQ3IconViewItems(ui_widget->elementItem());
+ }
+
+ return true;
+}
+
+void Q3IconViewExtraInfo::initializeQ3IconViewItems(const QList<DomItem *> &items)
+{
+ Q3IconView *iconView = qobject_cast<Q3IconView*>(widget());
+ Q_ASSERT(iconView != 0);
+
+ for (int i=0; i<items.size(); ++i) {
+ DomItem *item = items.at(i);
+
+ Q3IconViewItem *__item = new Q3IconViewItem(iconView);
+
+ QList<DomProperty*> properties = item->elementProperty();
+ for (int i=0; i<properties.size(); ++i) {
+ DomProperty *p = properties.at(i);
+ if (p->attributeName() == QLatin1String("text"))
+ __item->setText(p->elementString()->text());
+
+ if (p->attributeName() == QLatin1String("pixmap")) {
+ DomResourcePixmap *pix = p->elementPixmap();
+ QPixmap pixmap(core()->iconCache()->resolveQrcPath(pix->text(), pix->attributeResource(), workingDirectory()));
+ __item->setPixmap(pixmap);
+ }
+ }
+ }
+}
+
+
+Q3IconViewExtraInfoFactory::Q3IconViewExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent)
+ : QExtensionFactory(parent), m_core(core)
+{}
+
+QObject *Q3IconViewExtraInfoFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerExtraInfoExtension))
+ return 0;
+
+ if (Q3IconView *w = qobject_cast<Q3IconView*>(object))
+ return new Q3IconViewExtraInfo(w, m_core, parent);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3iconview/q3iconview_extrainfo.h b/src/designer/src/plugins/widgets/q3iconview/q3iconview_extrainfo.h
new file mode 100644
index 000000000..bcd823b86
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3iconview/q3iconview_extrainfo.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3ICONVIEW_EXTRAINFO_H
+#define Q3ICONVIEW_EXTRAINFO_H
+
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionFactory>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class Q3IconView;
+class Q3IconViewItem;
+class DomItem;
+
+class Q3IconViewExtraInfo: public QObject, public QDesignerExtraInfoExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerExtraInfoExtension)
+public:
+ Q3IconViewExtraInfo(Q3IconView *widget, QDesignerFormEditorInterface *core, QObject *parent);
+
+ virtual QWidget *widget() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool saveUiExtraInfo(DomUI *ui);
+ virtual bool loadUiExtraInfo(DomUI *ui);
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget);
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget);
+
+ void initializeQ3IconViewItems(const QList<DomItem *> &items);
+
+private:
+ QPointer<Q3IconView> m_widget;
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+class Q3IconViewExtraInfoFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3IconViewExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3ICONVIEW_EXTRAINFO_H
diff --git a/src/designer/src/plugins/widgets/q3iconview/q3iconview_plugin.cpp b/src/designer/src/plugins/widgets/q3iconview/q3iconview_plugin.cpp
new file mode 100644
index 000000000..0ed5b88db
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3iconview/q3iconview_plugin.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3iconview_plugin.h"
+#include "q3iconview_extrainfo.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <Qt3Support/Q3IconView>
+
+QT_BEGIN_NAMESPACE
+
+Q3IconViewPlugin::Q3IconViewPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3IconViewPlugin::name() const
+{ return QLatin1String("Q3IconView"); }
+
+QString Q3IconViewPlugin::group() const
+{ return QLatin1String("Qt 3 Support"); }
+
+QString Q3IconViewPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3IconViewPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3IconViewPlugin::includeFile() const
+{ return QLatin1String("q3iconview.h"); }
+
+QIcon Q3IconViewPlugin::icon() const
+{ return m_icon; }
+
+bool Q3IconViewPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3IconViewPlugin::createWidget(QWidget *parent)
+{ return new Q3IconView(parent); }
+
+bool Q3IconViewPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3IconViewPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ QExtensionManager *mgr = core->extensionManager();
+ Q_ASSERT(mgr != 0);
+
+ mgr->registerExtensions(new Q3IconViewExtraInfoFactory(core, mgr), Q_TYPEID(QDesignerExtraInfoExtension));
+
+ m_initialized = true;
+}
+
+QString Q3IconViewPlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3IconViewPlugin::domXml() const
+{ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3IconView\" name=\"iconView\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3iconview/q3iconview_plugin.h b/src/designer/src/plugins/widgets/q3iconview/q3iconview_plugin.h
new file mode 100644
index 000000000..9074b38f6
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3iconview/q3iconview_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3ICONVIEW_PLUGIN_H
+#define Q3ICONVIEW_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3IconViewPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3IconViewPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3ICONVIEW_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/q3listbox/q3listbox_extrainfo.cpp b/src/designer/src/plugins/widgets/q3listbox/q3listbox_extrainfo.cpp
new file mode 100644
index 000000000..6cd037247
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3listbox/q3listbox_extrainfo.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3listbox_extrainfo.h"
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/private/ui4_p.h>
+
+#include <Qt3Support/Q3ListBox>
+
+QT_BEGIN_NAMESPACE
+
+inline QHash<QString, DomProperty *> propertyMap(const QList<DomProperty *> &properties) // ### remove me
+{
+ QHash<QString, DomProperty *> map;
+
+ for (int i=0; i<properties.size(); ++i) {
+ DomProperty *p = properties.at(i);
+ map.insert(p->attributeName(), p);
+ }
+
+ return map;
+}
+
+Q3ListBoxExtraInfo::Q3ListBoxExtraInfo(Q3ListBox *widget, QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), m_widget(widget), m_core(core)
+{}
+
+QWidget *Q3ListBoxExtraInfo::widget() const
+{ return m_widget; }
+
+QDesignerFormEditorInterface *Q3ListBoxExtraInfo::core() const
+{ return m_core; }
+
+bool Q3ListBoxExtraInfo::saveUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+bool Q3ListBoxExtraInfo::loadUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+
+bool Q3ListBoxExtraInfo::saveWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q3ListBox *listBox = qobject_cast<Q3ListBox*>(widget());
+ Q_ASSERT(listBox != 0);
+
+ QList<DomItem *> items;
+ const int childCount = listBox->count();
+ for (int i = 0; i < childCount; ++i) {
+ DomItem *item = new DomItem();
+
+ QList<DomProperty*> properties;
+
+ DomString *str = new DomString();
+ str->setText(listBox->text(i));
+
+ DomProperty *ptext = new DomProperty();
+ ptext->setAttributeName(QLatin1String("text"));
+ ptext->setElementString(str);
+
+ properties.append(ptext);
+ item->setElementProperty(properties);
+ items.append(item);
+ }
+ ui_widget->setElementItem(items);
+
+ return true;
+}
+
+bool Q3ListBoxExtraInfo::loadWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q3ListBox *listBox = qobject_cast<Q3ListBox*>(widget());
+ Q_ASSERT(listBox != 0);
+
+ QList<DomItem *> items = ui_widget->elementItem();
+ for (int i = 0; i < items.size(); ++i) {
+ DomItem *item = items.at(i);
+
+ QHash<QString, DomProperty*> properties = propertyMap(item->elementProperty());
+ DomProperty *text = properties.value(QLatin1String("text"));
+ DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+
+ QString txt = text->elementString()->text();
+
+ if (pixmap != 0) {
+ DomResourcePixmap *pix = pixmap->elementPixmap();
+ QPixmap pixmap(core()->iconCache()->resolveQrcPath(pix->text(), pix->attributeResource(), workingDirectory()));
+ listBox->insertItem(pixmap, txt);
+ } else {
+ listBox->insertItem(txt);
+ }
+ }
+
+ return true;
+}
+
+Q3ListBoxExtraInfoFactory::Q3ListBoxExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent)
+ : QExtensionFactory(parent), m_core(core)
+{}
+
+QObject *Q3ListBoxExtraInfoFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerExtraInfoExtension))
+ return 0;
+
+ if (Q3ListBox *w = qobject_cast<Q3ListBox*>(object))
+ return new Q3ListBoxExtraInfo(w, m_core, parent);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3listbox/q3listbox_extrainfo.h b/src/designer/src/plugins/widgets/q3listbox/q3listbox_extrainfo.h
new file mode 100644
index 000000000..48b844141
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3listbox/q3listbox_extrainfo.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3LISTBOX_EXTRAINFO_H
+#define Q3LISTBOX_EXTRAINFO_H
+
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionFactory>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class Q3ListBox;
+class Q3ListBoxItem;
+class DomItem;
+
+class Q3ListBoxExtraInfo: public QObject, public QDesignerExtraInfoExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerExtraInfoExtension)
+public:
+ Q3ListBoxExtraInfo(Q3ListBox *widget, QDesignerFormEditorInterface *core, QObject *parent);
+
+ virtual QWidget *widget() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool saveUiExtraInfo(DomUI *ui);
+ virtual bool loadUiExtraInfo(DomUI *ui);
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget);
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget);
+
+private:
+ QPointer<Q3ListBox> m_widget;
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+class Q3ListBoxExtraInfoFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3ListBoxExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3LISTBOX_EXTRAINFO_H
diff --git a/src/designer/src/plugins/widgets/q3listbox/q3listbox_plugin.cpp b/src/designer/src/plugins/widgets/q3listbox/q3listbox_plugin.cpp
new file mode 100644
index 000000000..331b48964
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3listbox/q3listbox_plugin.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3listbox_plugin.h"
+#include "q3listbox_extrainfo.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <Qt3Support/Q3ListBox>
+
+QT_BEGIN_NAMESPACE
+
+Q3ListBoxPlugin::Q3ListBoxPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3ListBoxPlugin::name() const
+{ return QLatin1String("Q3ListBox"); }
+
+QString Q3ListBoxPlugin::group() const
+{ return QLatin1String("Qt 3 Support"); }
+
+QString Q3ListBoxPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3ListBoxPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3ListBoxPlugin::includeFile() const
+{ return QLatin1String("q3listbox.h"); }
+
+QIcon Q3ListBoxPlugin::icon() const
+{ return m_icon; }
+
+bool Q3ListBoxPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3ListBoxPlugin::createWidget(QWidget *parent)
+{ return new Q3ListBox(parent); }
+
+bool Q3ListBoxPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3ListBoxPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ QExtensionManager *mgr = core->extensionManager();
+ Q_ASSERT(mgr != 0);
+
+ mgr->registerExtensions(new Q3ListBoxExtraInfoFactory(core, mgr), Q_TYPEID(QDesignerExtraInfoExtension));
+
+ m_initialized = true;
+}
+
+QString Q3ListBoxPlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3ListBoxPlugin::domXml() const
+{ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3ListBox\" name=\"listBox\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3listbox/q3listbox_plugin.h b/src/designer/src/plugins/widgets/q3listbox/q3listbox_plugin.h
new file mode 100644
index 000000000..d1c99d07f
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3listbox/q3listbox_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3LISTBOX_PLUGIN_H
+#define Q3LISTBOX_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3ListBoxPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3ListBoxPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3LISTBOX_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/q3listview/q3listview_extrainfo.cpp b/src/designer/src/plugins/widgets/q3listview/q3listview_extrainfo.cpp
new file mode 100644
index 000000000..2dda71749
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3listview/q3listview_extrainfo.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3listview_extrainfo.h"
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/private/ui4_p.h>
+
+#include <Qt3Support/Q3ListView>
+#include <Qt3Support/Q3Header>
+
+QT_BEGIN_NAMESPACE
+
+inline QHash<QString, DomProperty *> propertyMap(const QList<DomProperty *> &properties) // ### remove me
+{
+ QHash<QString, DomProperty *> map;
+
+ for (int i=0; i<properties.size(); ++i) {
+ DomProperty *p = properties.at(i);
+ map.insert(p->attributeName(), p);
+ }
+
+ return map;
+}
+
+Q3ListViewExtraInfo::Q3ListViewExtraInfo(Q3ListView *widget, QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), m_widget(widget), m_core(core)
+{}
+
+QWidget *Q3ListViewExtraInfo::widget() const
+{ return m_widget; }
+
+QDesignerFormEditorInterface *Q3ListViewExtraInfo::core() const
+{ return m_core; }
+
+bool Q3ListViewExtraInfo::saveUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+bool Q3ListViewExtraInfo::loadUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+
+bool Q3ListViewExtraInfo::saveWidgetExtraInfo(DomWidget *ui_widget)
+{
+ // ### finish me
+ Q3ListView *listView = qobject_cast<Q3ListView*>(widget());
+ Q_ASSERT(listView != 0);
+
+ QList<DomColumn*> columns;
+ Q3Header *header = listView->header();
+ for (int i=0; i<header->count(); ++i) {
+ DomColumn *c = new DomColumn();
+
+ QList<DomProperty*> properties;
+
+ DomString *str = new DomString();
+ str->setText(header->label(i));
+
+ DomProperty *ptext = new DomProperty();
+ ptext->setAttributeName(QLatin1String("text"));
+ ptext->setElementString(str);
+
+ DomProperty *pclickable = new DomProperty();
+ pclickable->setAttributeName(QLatin1String("clickable"));
+ pclickable->setElementBool(header->isClickEnabled(i) ? QLatin1String("true") : QLatin1String("false"));
+
+ DomProperty *presizable = new DomProperty();
+ presizable->setAttributeName(QLatin1String("resizable"));
+ presizable->setElementBool(header->isResizeEnabled(i) ? QLatin1String("true") : QLatin1String("false"));
+
+ properties.append(ptext);
+ properties.append(pclickable);
+ properties.append(presizable);
+
+ c->setElementProperty(properties);
+ columns.append(c);
+ }
+
+ ui_widget->setElementColumn(columns);
+
+ QList<DomItem *> items;
+ Q3ListViewItem *child = listView->firstChild();
+ while (child) {
+ items.append(saveQ3ListViewItem(child));
+ child = child->nextSibling();
+ }
+ ui_widget->setElementItem(items);
+
+
+ return true;
+}
+
+bool Q3ListViewExtraInfo::loadWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q3ListView *listView = qobject_cast<Q3ListView*>(widget());
+ Q_ASSERT(listView != 0);
+
+ Q3Header *header = listView->header();
+
+ QList<DomColumn*> columns = ui_widget->elementColumn();
+ for (int i=0; i<columns.size(); ++i) {
+ DomColumn *column = columns.at(i);
+
+ QHash<QString, DomProperty*> properties = propertyMap(column->elementProperty());
+ DomProperty *text = properties.value(QLatin1String("text"));
+ DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+ DomProperty *clickable = properties.value(QLatin1String("clickable"));
+ DomProperty *resizable = properties.value(QLatin1String("resizable"));
+
+ QString txt = text->elementString()->text();
+
+ if (pixmap != 0) {
+ DomResourcePixmap *pix = pixmap->elementPixmap();
+ QIcon icon(core()->iconCache()->resolveQrcPath(pix->text(), pix->attributeResource(), workingDirectory()));
+ listView->addColumn(icon, txt);
+ } else {
+ listView->addColumn(txt);
+ }
+
+ if (clickable != 0) {
+ header->setClickEnabled(clickable->elementBool() == QLatin1String("true"), header->count() - 1);
+ }
+
+ if (resizable != 0) {
+ header->setResizeEnabled(resizable->elementBool() == QLatin1String("true"), header->count() - 1);
+ }
+ }
+
+ if (ui_widget->elementItem().size()) {
+ initializeQ3ListViewItems(ui_widget->elementItem());
+ }
+
+ return true;
+}
+
+DomItem *Q3ListViewExtraInfo::saveQ3ListViewItem(Q3ListViewItem *item) const
+{
+ DomItem *pitem = new DomItem();
+ QList<DomProperty *> properties;
+ const int columnCount = static_cast<Q3ListView*>(widget())->columns();
+ for (int i = 0; i < columnCount; ++i) {
+ DomString *str = new DomString();
+ str->setText(item->text(i));
+
+ DomProperty *ptext = new DomProperty();
+ ptext->setAttributeName(QLatin1String("text"));
+ ptext->setElementString(str);
+
+ properties.append(ptext);
+ }
+ pitem->setElementProperty(properties);
+ QList<DomItem *> items;
+ Q3ListViewItem *child = item->firstChild();
+ while (child) {
+ items.append(saveQ3ListViewItem(child));
+ child = child->nextSibling();
+ }
+ pitem->setElementItem(items);
+ return pitem;
+}
+
+void Q3ListViewExtraInfo::initializeQ3ListViewItems(const QList<DomItem *> &items, Q3ListViewItem *parentItem)
+{
+ for (int i=0; i<items.size(); ++i) {
+ DomItem *item = items.at(i);
+
+ Q3ListViewItem *__item = 0;
+ if (parentItem != 0)
+ __item = new Q3ListViewItem(parentItem);
+ else
+ __item = new Q3ListViewItem(static_cast<Q3ListView*>(widget()));
+
+ int textCount = 0, pixCount = 0;
+ QList<DomProperty*> properties = item->elementProperty();
+ for (int i=0; i<properties.size(); ++i) {
+ DomProperty *p = properties.at(i);
+ if (p->attributeName() == QLatin1String("text"))
+ __item->setText(textCount++, p->elementString()->text());
+
+ if (p->attributeName() == QLatin1String("pixmap")) {
+ DomResourcePixmap *pix = p->elementPixmap();
+ QPixmap pixmap(core()->iconCache()->resolveQrcPath(pix->text(), pix->attributeResource(), workingDirectory()));
+ __item->setPixmap(pixCount++, pixmap);
+ }
+ }
+
+ if (item->elementItem().size()) {
+ __item->setOpen(true);
+ initializeQ3ListViewItems(item->elementItem(), __item);
+ }
+ }
+}
+
+
+Q3ListViewExtraInfoFactory::Q3ListViewExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent)
+ : QExtensionFactory(parent), m_core(core)
+{}
+
+QObject *Q3ListViewExtraInfoFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerExtraInfoExtension))
+ return 0;
+
+ if (Q3ListView *w = qobject_cast<Q3ListView*>(object))
+ return new Q3ListViewExtraInfo(w, m_core, parent);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3listview/q3listview_extrainfo.h b/src/designer/src/plugins/widgets/q3listview/q3listview_extrainfo.h
new file mode 100644
index 000000000..caedc133f
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3listview/q3listview_extrainfo.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3LISTVIEW_EXTRAINFO_H
+#define Q3LISTVIEW_EXTRAINFO_H
+
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionFactory>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class Q3ListView;
+class Q3ListViewItem;
+class DomItem;
+
+class Q3ListViewExtraInfo: public QObject, public QDesignerExtraInfoExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerExtraInfoExtension)
+public:
+ Q3ListViewExtraInfo(Q3ListView *widget, QDesignerFormEditorInterface *core, QObject *parent);
+
+ virtual QWidget *widget() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool saveUiExtraInfo(DomUI *ui);
+ virtual bool loadUiExtraInfo(DomUI *ui);
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget);
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget);
+
+ DomItem *saveQ3ListViewItem(Q3ListViewItem *item) const;
+ void initializeQ3ListViewItems(const QList<DomItem *> &items, Q3ListViewItem *parentItem = 0);
+
+private:
+ QPointer<Q3ListView> m_widget;
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+class Q3ListViewExtraInfoFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3ListViewExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3LISTVIEW_EXTRAINFO_H
diff --git a/src/designer/src/plugins/widgets/q3listview/q3listview_plugin.cpp b/src/designer/src/plugins/widgets/q3listview/q3listview_plugin.cpp
new file mode 100644
index 000000000..4c5b193bd
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3listview/q3listview_plugin.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3listview_plugin.h"
+#include "q3listview_extrainfo.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <Qt3Support/Q3ListView>
+
+QT_BEGIN_NAMESPACE
+
+Q3ListViewPlugin::Q3ListViewPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3ListViewPlugin::name() const
+{ return QLatin1String("Q3ListView"); }
+
+QString Q3ListViewPlugin::group() const
+{ return QLatin1String("Qt 3 Support"); }
+
+QString Q3ListViewPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3ListViewPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3ListViewPlugin::includeFile() const
+{ return QLatin1String("q3listview.h"); }
+
+QIcon Q3ListViewPlugin::icon() const
+{ return m_icon; }
+
+bool Q3ListViewPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3ListViewPlugin::createWidget(QWidget *parent)
+{ return new Q3ListView(parent); }
+
+bool Q3ListViewPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3ListViewPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ QExtensionManager *mgr = core->extensionManager();
+ Q_ASSERT(mgr != 0);
+
+ mgr->registerExtensions(new Q3ListViewExtraInfoFactory(core, mgr), Q_TYPEID(QDesignerExtraInfoExtension));
+
+ m_initialized = true;
+}
+
+QString Q3ListViewPlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3ListViewPlugin::domXml() const
+{ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3ListView\" name=\"listView\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3listview/q3listview_plugin.h b/src/designer/src/plugins/widgets/q3listview/q3listview_plugin.h
new file mode 100644
index 000000000..e006d7344
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3listview/q3listview_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3LISTVIEW_PLUGIN_H
+#define Q3LISTVIEW_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3ListViewPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3ListViewPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3LISTVIEW_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_container.cpp b/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_container.cpp
new file mode 100644
index 000000000..b156623b3
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_container.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3mainwindow_container.h"
+
+#include <Qt3Support/Q3MainWindow>
+
+#include <QtCore/qdebug.h>
+#include <QtGui/QToolBar>
+#include <QtGui/QMenuBar>
+#include <QtGui/QStatusBar>
+
+#include <Qt3Support/Q3ToolBar>
+
+QT_BEGIN_NAMESPACE
+
+Q3MainWindowContainer::Q3MainWindowContainer(Q3MainWindow *widget, QObject *parent)
+ : QObject(parent),
+ m_mainWindow(widget)
+{}
+
+int Q3MainWindowContainer::count() const
+{
+ return m_widgets.count();
+}
+
+QWidget *Q3MainWindowContainer::widget(int index) const
+{
+ if (index == -1)
+ return 0;
+
+ return m_widgets.at(index);
+}
+
+int Q3MainWindowContainer::currentIndex() const
+{
+ return m_mainWindow->centralWidget() ? 0 : -1;
+}
+
+void Q3MainWindowContainer::setCurrentIndex(int index)
+{
+ Q_UNUSED(index);
+}
+
+void Q3MainWindowContainer::addWidget(QWidget *widget)
+{
+ if (qobject_cast<QToolBar*>(widget)) {
+ m_widgets.append(widget);
+ } else if (qobject_cast<Q3ToolBar*>(widget)) {
+ m_widgets.append(widget);
+ } else if (qobject_cast<QMenuBar*>(widget)) {
+ (void) m_mainWindow->menuBar();
+ m_widgets.append(widget);
+ } else if (qobject_cast<QStatusBar*>(widget)) {
+ (void) m_mainWindow->statusBar();
+ m_widgets.append(widget);
+ } else {
+ Q_ASSERT(m_mainWindow->centralWidget() == 0);
+ widget->setParent(m_mainWindow);
+ m_mainWindow->setCentralWidget(widget);
+ m_widgets.prepend(widget);
+ }
+}
+
+void Q3MainWindowContainer::insertWidget(int index, QWidget *widget)
+{
+ m_widgets.insert(index, widget);
+}
+
+void Q3MainWindowContainer::remove(int index)
+{
+ m_widgets.removeAt(index);
+}
+
+Q3MainWindowContainerFactory::Q3MainWindowContainerFactory(QExtensionManager *parent)
+ : QExtensionFactory(parent)
+{
+}
+
+QObject *Q3MainWindowContainerFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerContainerExtension))
+ return 0;
+
+ if (Q3MainWindow *w = qobject_cast<Q3MainWindow*>(object))
+ return new Q3MainWindowContainer(w, parent);
+
+ return 0;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_container.h b/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_container.h
new file mode 100644
index 000000000..fdadee61a
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_container.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3MAINWINDOW_CONTAINER_H
+#define Q3MAINWINDOW_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionFactory>
+
+QT_BEGIN_NAMESPACE
+
+class Q3MainWindow;
+
+class Q3MainWindowContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit Q3MainWindowContainer(Q3MainWindow *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ Q3MainWindow *m_mainWindow;
+ QList<QWidget*> m_widgets;
+};
+
+class Q3MainWindowContainerFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3MainWindowContainerFactory(QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3MAINWINDOW_CONTAINER_H
diff --git a/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.cpp b/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.cpp
new file mode 100644
index 000000000..9c91586a7
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3mainwindow_plugin.h"
+#include "q3mainwindow_container.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <Qt3Support/Q3MainWindow>
+
+QT_BEGIN_NAMESPACE
+
+Q3MainWindowPlugin::Q3MainWindowPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3MainWindowPlugin::name() const
+{ return QLatin1String("Q3MainWindow"); }
+
+QString Q3MainWindowPlugin::group() const
+{ return QLatin1String("[invisible]"); }
+
+QString Q3MainWindowPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3MainWindowPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3MainWindowPlugin::includeFile() const
+{ return QLatin1String("q3mainwindow.h"); }
+
+QIcon Q3MainWindowPlugin::icon() const
+{ return m_icon; }
+
+bool Q3MainWindowPlugin::isContainer() const
+{ return true; }
+
+QWidget *Q3MainWindowPlugin::createWidget(QWidget *parent)
+{ return new Q3MainWindow(parent); }
+
+bool Q3MainWindowPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3MainWindowPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ m_initialized = true;
+ QExtensionManager *mgr = core->extensionManager();
+ mgr->registerExtensions(new Q3MainWindowContainerFactory(mgr), Q_TYPEID(QDesignerContainerExtension));
+}
+
+QString Q3MainWindowPlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3MainWindowPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3MainWindow\" name=\"mainWindow\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ <widget class=\"QWidget\" name=\"centralWidget\" />\
+ </widget>\
+</ui>");
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.h b/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.h
new file mode 100644
index 000000000..00a1c205f
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3MAINWINDOW_PLUGIN_H
+#define Q3MAINWINDOW_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3MainWindowPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3MainWindowPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3MAINWINDOW_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/q3table/q3table_extrainfo.cpp b/src/designer/src/plugins/widgets/q3table/q3table_extrainfo.cpp
new file mode 100644
index 000000000..3305e2b74
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3table/q3table_extrainfo.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3table_extrainfo.h"
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/private/ui4_p.h>
+
+#include <Qt3Support/Q3Table>
+
+QT_BEGIN_NAMESPACE
+
+inline QHash<QString, DomProperty *> propertyMap(const QList<DomProperty *> &properties) // ### remove me
+{
+ QHash<QString, DomProperty *> map;
+
+ for (int i=0; i<properties.size(); ++i) {
+ DomProperty *p = properties.at(i);
+ map.insert(p->attributeName(), p);
+ }
+
+ return map;
+}
+
+Q3TableExtraInfo::Q3TableExtraInfo(Q3Table *widget, QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), m_widget(widget), m_core(core)
+{}
+
+QWidget *Q3TableExtraInfo::widget() const
+{ return m_widget; }
+
+QDesignerFormEditorInterface *Q3TableExtraInfo::core() const
+{ return m_core; }
+
+bool Q3TableExtraInfo::saveUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+bool Q3TableExtraInfo::loadUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+
+bool Q3TableExtraInfo::saveWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q_UNUSED(ui_widget);
+
+ Q3Table *table = qobject_cast<Q3Table*>(widget());
+ Q_ASSERT(table != 0);
+
+ Q3Header *hHeader = table->horizontalHeader();
+
+ QList<DomColumn*> columns;
+ for (int i=0; i<hHeader->count(); ++i) {
+ DomColumn *column = new DomColumn();
+ QList<DomProperty *> properties;
+
+ DomProperty *property = new DomProperty();
+ DomString *string = new DomString();
+ string->setText(hHeader->label(i));
+ property->setElementString(string);
+ property->setAttributeName("text");
+ properties.append(property);
+
+ column->setElementProperty(properties);
+ columns.append(column);
+ }
+ ui_widget->setElementColumn(columns);
+
+ Q3Header *vHeader = table->verticalHeader();
+
+ QList<DomRow*> rows;
+ for (int i=0; i<vHeader->count(); ++i) {
+ DomRow *row = new DomRow();
+ QList<DomProperty *> properties;
+
+ DomProperty *property = new DomProperty();
+ DomString *string = new DomString();
+ string->setText(vHeader->label(i));
+ property->setElementString(string);
+ property->setAttributeName("text");
+ properties.append(property);
+
+ row->setElementProperty(properties);
+ rows.append(row);
+ }
+ ui_widget->setElementRow(rows);
+
+ return true;
+}
+
+bool Q3TableExtraInfo::loadWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q_UNUSED(ui_widget);
+
+ Q3Table *table = qobject_cast<Q3Table*>(widget());
+ Q_ASSERT(table != 0);
+
+ Q3Header *hHeader = table->horizontalHeader();
+
+ QList<DomColumn*> columns = ui_widget->elementColumn();
+ for (int i=0; i<columns.size(); ++i) {
+ DomColumn *column = columns.at(i);
+
+ QHash<QString, DomProperty*> properties = propertyMap(column->elementProperty());
+ DomProperty *text = properties.value(QLatin1String("text"));
+ DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+
+ QString txt = text->elementString()->text();
+
+ if (pixmap != 0) {
+ DomResourcePixmap *pix = pixmap->elementPixmap();
+ QIcon icon(core()->iconCache()->resolveQrcPath(pix->text(), pix->attributeResource(), workingDirectory()));
+ hHeader->setLabel(i, icon, txt);
+ } else {
+ hHeader->setLabel(i, txt);
+ }
+ }
+
+ Q3Header *vHeader = table->verticalHeader();
+
+ QList<DomRow*> rows = ui_widget->elementRow();
+ for (int i=0; i<rows.size(); ++i) {
+ DomRow *row = rows.at(i);
+
+ QHash<QString, DomProperty*> properties = propertyMap(row->elementProperty());
+ DomProperty *text = properties.value(QLatin1String("text"));
+ DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+
+ QString txt = text->elementString()->text();
+
+ if (pixmap != 0) {
+ DomResourcePixmap *pix = pixmap->elementPixmap();
+ QIcon icon(core()->iconCache()->resolveQrcPath(pix->text(), pix->attributeResource(), workingDirectory()));
+ vHeader->setLabel(i, icon, txt);
+ } else {
+ vHeader->setLabel(i, txt);
+ }
+ }
+
+ return true;
+}
+
+Q3TableExtraInfoFactory::Q3TableExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent)
+ : QExtensionFactory(parent), m_core(core)
+{}
+
+QObject *Q3TableExtraInfoFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerExtraInfoExtension))
+ return 0;
+
+ if (Q3Table *w = qobject_cast<Q3Table*>(object))
+ return new Q3TableExtraInfo(w, m_core, parent);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3table/q3table_extrainfo.h b/src/designer/src/plugins/widgets/q3table/q3table_extrainfo.h
new file mode 100644
index 000000000..3b5ab9f4b
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3table/q3table_extrainfo.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3TABLE_EXTRAINFO_H
+#define Q3TABLE_EXTRAINFO_H
+
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionFactory>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class Q3Table;
+class Q3TableItem;
+class DomItem;
+
+class Q3TableExtraInfo: public QObject, public QDesignerExtraInfoExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerExtraInfoExtension)
+public:
+ Q3TableExtraInfo(Q3Table *widget, QDesignerFormEditorInterface *core, QObject *parent);
+
+ virtual QWidget *widget() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool saveUiExtraInfo(DomUI *ui);
+ virtual bool loadUiExtraInfo(DomUI *ui);
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget);
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget);
+
+private:
+ QPointer<Q3Table> m_widget;
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+class Q3TableExtraInfoFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3TableExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3TABLE_EXTRAINFO_H
diff --git a/src/designer/src/plugins/widgets/q3table/q3table_plugin.cpp b/src/designer/src/plugins/widgets/q3table/q3table_plugin.cpp
new file mode 100644
index 000000000..38562a210
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3table/q3table_plugin.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3table_plugin.h"
+#include "q3table_extrainfo.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <Qt3Support/Q3Table>
+
+QT_BEGIN_NAMESPACE
+
+Q3TablePlugin::Q3TablePlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3TablePlugin::name() const
+{ return QLatin1String("Q3Table"); }
+
+QString Q3TablePlugin::group() const
+{ return QLatin1String("Qt 3 Support"); }
+
+QString Q3TablePlugin::toolTip() const
+{ return QString(); }
+
+QString Q3TablePlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3TablePlugin::includeFile() const
+{ return QLatin1String("q3table.h"); }
+
+QIcon Q3TablePlugin::icon() const
+{ return m_icon; }
+
+bool Q3TablePlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3TablePlugin::createWidget(QWidget *parent)
+{ return new Q3Table(parent); }
+
+bool Q3TablePlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3TablePlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ QExtensionManager *mgr = core->extensionManager();
+ Q_ASSERT(mgr != 0);
+
+ mgr->registerExtensions(new Q3TableExtraInfoFactory(core, mgr), Q_TYPEID(QDesignerExtraInfoExtension));
+
+ m_initialized = true;
+}
+
+QString Q3TablePlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3TablePlugin::domXml() const
+{ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3Table\" name=\"table\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3table/q3table_plugin.h b/src/designer/src/plugins/widgets/q3table/q3table_plugin.h
new file mode 100644
index 000000000..92034ea59
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3table/q3table_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3TABLE_PLUGIN_H
+#define Q3TABLE_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3TablePlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3TablePlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3TABLE_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/q3textedit/q3textedit_extrainfo.cpp b/src/designer/src/plugins/widgets/q3textedit/q3textedit_extrainfo.cpp
new file mode 100644
index 000000000..3c1530a56
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3textedit/q3textedit_extrainfo.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3textedit_extrainfo.h"
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/private/ui4_p.h>
+
+#include <Qt3Support/Q3TextEdit>
+
+QT_BEGIN_NAMESPACE
+
+inline QHash<QString, DomProperty *> propertyMap(const QList<DomProperty *> &properties) // ### remove me
+{
+ QHash<QString, DomProperty *> map;
+
+ for (int i=0; i<properties.size(); ++i) {
+ DomProperty *p = properties.at(i);
+ map.insert(p->attributeName(), p);
+ }
+
+ return map;
+}
+
+Q3TextEditExtraInfo::Q3TextEditExtraInfo(Q3TextEdit *widget, QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), m_widget(widget), m_core(core)
+{}
+
+QWidget *Q3TextEditExtraInfo::widget() const
+{ return m_widget; }
+
+QDesignerFormEditorInterface *Q3TextEditExtraInfo::core() const
+{ return m_core; }
+
+bool Q3TextEditExtraInfo::saveUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+bool Q3TextEditExtraInfo::loadUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+
+bool Q3TextEditExtraInfo::saveWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q_UNUSED(ui_widget);
+
+ Q3TextEdit *textEdit = qobject_cast<Q3TextEdit*>(widget());
+ Q_ASSERT(textEdit != 0);
+ Q_UNUSED(textEdit);
+ return true;
+}
+
+bool Q3TextEditExtraInfo::loadWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q_UNUSED(ui_widget);
+
+ Q3TextEdit *textEdit = qobject_cast<Q3TextEdit*>(widget());
+ Q_ASSERT(textEdit != 0);
+ Q_UNUSED(textEdit);
+ return true;
+}
+
+Q3TextEditExtraInfoFactory::Q3TextEditExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent)
+ : QExtensionFactory(parent), m_core(core)
+{}
+
+QObject *Q3TextEditExtraInfoFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerExtraInfoExtension))
+ return 0;
+
+ if (Q3TextEdit *w = qobject_cast<Q3TextEdit*>(object))
+ return new Q3TextEditExtraInfo(w, m_core, parent);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3textedit/q3textedit_extrainfo.h b/src/designer/src/plugins/widgets/q3textedit/q3textedit_extrainfo.h
new file mode 100644
index 000000000..5fe89097e
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3textedit/q3textedit_extrainfo.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3TEXTEDIT_EXTRAINFO_H
+#define Q3TEXTEDIT_EXTRAINFO_H
+
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionFactory>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class Q3TextEdit;
+class Q3TextEditItem;
+class DomItem;
+
+class Q3TextEditExtraInfo: public QObject, public QDesignerExtraInfoExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerExtraInfoExtension)
+public:
+ Q3TextEditExtraInfo(Q3TextEdit *widget, QDesignerFormEditorInterface *core, QObject *parent);
+
+ virtual QWidget *widget() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool saveUiExtraInfo(DomUI *ui);
+ virtual bool loadUiExtraInfo(DomUI *ui);
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget);
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget);
+
+private:
+ QPointer<Q3TextEdit> m_widget;
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+class Q3TextEditExtraInfoFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3TextEditExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3TEXTEDIT_EXTRAINFO_H
diff --git a/src/designer/src/plugins/widgets/q3textedit/q3textedit_plugin.cpp b/src/designer/src/plugins/widgets/q3textedit/q3textedit_plugin.cpp
new file mode 100644
index 000000000..8da4315cb
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3textedit/q3textedit_plugin.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3textedit_plugin.h"
+#include "q3textedit_extrainfo.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <Qt3Support/Q3TextEdit>
+
+QT_BEGIN_NAMESPACE
+
+Q3TextEditPlugin::Q3TextEditPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3TextEditPlugin::name() const
+{ return QLatin1String("Q3TextEdit"); }
+
+QString Q3TextEditPlugin::group() const
+{ return QLatin1String("Qt 3 Support"); }
+
+QString Q3TextEditPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3TextEditPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3TextEditPlugin::includeFile() const
+{ return QLatin1String("q3textedit.h"); }
+
+QIcon Q3TextEditPlugin::icon() const
+{ return m_icon; }
+
+
+bool Q3TextEditPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3TextEditPlugin::createWidget(QWidget *parent)
+{ return new Q3TextEdit(parent); }
+
+bool Q3TextEditPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3TextEditPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ QExtensionManager *mgr = core->extensionManager();
+ Q_ASSERT(mgr != 0);
+
+ mgr->registerExtensions(new Q3TextEditExtraInfoFactory(core, mgr), Q_TYPEID(QDesignerExtraInfoExtension));
+
+ m_initialized = true;
+}
+
+QString Q3TextEditPlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3TextEditPlugin::domXml() const
+{ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3TextEdit\" name=\"textEdit\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3textedit/q3textedit_plugin.h b/src/designer/src/plugins/widgets/q3textedit/q3textedit_plugin.h
new file mode 100644
index 000000000..cfae30832
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3textedit/q3textedit_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3TEXTEDIT_PLUGIN_H
+#define Q3TEXTEDIT_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3TextEditPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3TextEditPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3TEXTEDIT_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.cpp b/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.cpp
new file mode 100644
index 000000000..44d5286b6
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3toolbar_extrainfo.h"
+
+#include <QtDesigner/QDesignerIconCacheInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/private/ui4_p.h>
+
+#include <Qt3Support/Q3ToolBar>
+
+QT_BEGIN_NAMESPACE
+
+inline QHash<QString, DomProperty *> propertyMap(const QList<DomProperty *> &properties) // ### remove me
+{
+ QHash<QString, DomProperty *> map;
+
+ for (int i=0; i<properties.size(); ++i) {
+ DomProperty *p = properties.at(i);
+ map.insert(p->attributeName(), p);
+ }
+
+ return map;
+}
+
+Q3ToolBarExtraInfo::Q3ToolBarExtraInfo(Q3ToolBar *widget, QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), m_widget(widget), m_core(core)
+{}
+
+QWidget *Q3ToolBarExtraInfo::widget() const
+{ return m_widget; }
+
+QDesignerFormEditorInterface *Q3ToolBarExtraInfo::core() const
+{ return m_core; }
+
+bool Q3ToolBarExtraInfo::saveUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+bool Q3ToolBarExtraInfo::loadUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+
+bool Q3ToolBarExtraInfo::saveWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q_UNUSED(ui_widget);
+ return true;
+}
+
+bool Q3ToolBarExtraInfo::loadWidgetExtraInfo(DomWidget *ui_widget)
+{
+ Q_UNUSED(ui_widget);
+ return true;
+}
+
+Q3ToolBarExtraInfoFactory::Q3ToolBarExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent)
+ : QExtensionFactory(parent), m_core(core)
+{}
+
+QObject *Q3ToolBarExtraInfoFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerExtraInfoExtension))
+ return 0;
+
+ if (Q3ToolBar *w = qobject_cast<Q3ToolBar*>(object))
+ return new Q3ToolBarExtraInfo(w, m_core, parent);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.h b/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.h
new file mode 100644
index 000000000..d5865c84f
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3TOOLBAR_EXTRAINFO_H
+#define Q3TOOLBAR_EXTRAINFO_H
+
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionFactory>
+
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class Q3ToolBar;
+class DomItem;
+
+class Q3ToolBarExtraInfo: public QObject, public QDesignerExtraInfoExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerExtraInfoExtension)
+public:
+ Q3ToolBarExtraInfo(Q3ToolBar *widget, QDesignerFormEditorInterface *core, QObject *parent);
+
+ virtual QWidget *widget() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool saveUiExtraInfo(DomUI *ui);
+ virtual bool loadUiExtraInfo(DomUI *ui);
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget);
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget);
+
+private:
+ QPointer<Q3ToolBar> m_widget;
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+class Q3ToolBarExtraInfoFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3ToolBarExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3TOOLBAR_EXTRAINFO_H
diff --git a/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_plugin.cpp b/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_plugin.cpp
new file mode 100644
index 000000000..83ef66bd8
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_plugin.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3toolbar_plugin.h"
+#include "q3toolbar_extrainfo.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <QtCore/QDebug>
+
+#include <Qt3Support/Q3MainWindow>
+#include <Qt3Support/Q3ToolBar>
+#include <QtGui/QMainWindow>
+#include <QtGui/QToolBar>
+
+QT_BEGIN_NAMESPACE
+
+Q3ToolBarPlugin::Q3ToolBarPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3ToolBarPlugin::name() const
+{ return QLatin1String("Q3ToolBar"); }
+
+QString Q3ToolBarPlugin::group() const
+{ return QLatin1String("Qt 3 Support"); }
+
+QString Q3ToolBarPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3ToolBarPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3ToolBarPlugin::includeFile() const
+{ return QLatin1String("q3listview.h"); }
+
+QIcon Q3ToolBarPlugin::icon() const
+{ return m_icon; }
+
+bool Q3ToolBarPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3ToolBarPlugin::createWidget(QWidget *parent)
+{
+ if (!parent)
+ return new Q3ToolBar;
+ // If there is a parent, it must be a Q3MainWindow
+ if (Q3MainWindow *mw3 = qobject_cast<Q3MainWindow*>(parent))
+ return new Q3ToolBar(mw3);
+ // Somebody hacked up a form?
+ if (QMainWindow *mw4 = qobject_cast<QMainWindow*>(parent)) {
+ qDebug() << "*** WARNING QMainWindow was passed as a parent widget of Q3ToolBar. Creating a QToolBar...";
+ return new QToolBar(mw4);
+ }
+ // Can't be helped
+ const QString msg = QString::fromUtf8("*** WARNING Parent widget of Q3ToolBar must be a Q3MainWindow (%1)!").arg(QLatin1String(parent->metaObject()->className()));
+ qDebug() << msg;
+ return 0;
+}
+
+bool Q3ToolBarPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3ToolBarPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ QExtensionManager *mgr = core->extensionManager();
+ Q_ASSERT(mgr != 0);
+
+ mgr->registerExtensions(new Q3ToolBarExtraInfoFactory(core, mgr), Q_TYPEID(QDesignerExtraInfoExtension));
+
+ m_initialized = true;
+}
+
+QString Q3ToolBarPlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3ToolBarPlugin::domXml() const
+{ return QString(); }
+
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_plugin.h b/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_plugin.h
new file mode 100644
index 000000000..344f3e27c
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3toolbar/q3toolbar_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3TOOLBAR_PLUGIN_H
+#define Q3TOOLBAR_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3ToolBarPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3ToolBarPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3TOOLBAR_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/q3widgets/q3widget_plugins.cpp b/src/designer/src/plugins/widgets/q3widgets/q3widget_plugins.cpp
new file mode 100644
index 000000000..2f8cca257
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3widgets/q3widget_plugins.cpp
@@ -0,0 +1,601 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3widget_plugins.h"
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QIcon>
+#include <QtGui/QLayout>
+#include <Qt3Support/Q3ButtonGroup>
+#include <Qt3Support/Q3ComboBox>
+#include <Qt3Support/Q3DateEdit>
+#include <Qt3Support/Q3DateTimeEdit>
+#include <Qt3Support/Q3Frame>
+#include <Qt3Support/Q3GroupBox>
+#include <Qt3Support/Q3ProgressBar>
+#include <Qt3Support/Q3TextBrowser>
+#include <Qt3Support/Q3TimeEdit>
+
+static const char *groupNameC = "Qt 3 Support";
+
+QT_BEGIN_NAMESPACE
+
+Q3ButtonGroupPlugin::Q3ButtonGroupPlugin(const QIcon &icon, QObject *parent) :
+ QObject(parent),
+ m_initialized(false),
+ m_icon(icon)
+{
+}
+
+Q3ButtonGroupPlugin::~Q3ButtonGroupPlugin()
+{
+}
+
+QString Q3ButtonGroupPlugin::name() const
+{
+ return QLatin1String("Q3ButtonGroup");
+}
+
+QString Q3ButtonGroupPlugin::group() const
+{
+ return QLatin1String(groupNameC);
+}
+
+QString Q3ButtonGroupPlugin::toolTip() const
+{
+ return QString();
+}
+
+QString Q3ButtonGroupPlugin::whatsThis() const
+{
+ return QString();
+}
+
+QString Q3ButtonGroupPlugin::includeFile() const
+{
+ return QLatin1String("Qt3Support/Q3ButtonGroup");
+}
+
+QIcon Q3ButtonGroupPlugin::icon() const
+{
+ return m_icon;
+}
+
+bool Q3ButtonGroupPlugin::isContainer() const
+{
+ return true;
+}
+
+QWidget *Q3ButtonGroupPlugin::createWidget(QWidget *parent)
+{
+ Q3ButtonGroup *g = new Q3ButtonGroup(parent);
+ g->setColumnLayout(0, Qt::Vertical);
+ g->setInsideMargin(0);
+ g->layout()->setSpacing(-1);
+ return g;
+}
+
+bool Q3ButtonGroupPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void Q3ButtonGroupPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+QString Q3ButtonGroupPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3ButtonGroup\" name=\"buttonGroup\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+Q3ComboBoxPlugin::Q3ComboBoxPlugin(const QIcon &icon, QObject *parent) :
+ QObject(parent),
+ m_initialized(false),
+ m_icon(icon)
+{
+}
+
+Q3ComboBoxPlugin::~Q3ComboBoxPlugin()
+{
+}
+
+QString Q3ComboBoxPlugin::name() const
+{
+ return QLatin1String("Q3ComboBox");
+}
+
+QString Q3ComboBoxPlugin::group() const
+{
+ return QLatin1String(groupNameC);
+}
+
+QString Q3ComboBoxPlugin::toolTip() const
+{
+ return QString();
+}
+
+QString Q3ComboBoxPlugin::whatsThis() const
+{
+ return QString();
+}
+
+QString Q3ComboBoxPlugin::includeFile() const
+{
+ return QLatin1String("Qt3Support/Q3ComboBox");
+}
+
+QIcon Q3ComboBoxPlugin::icon() const
+{
+ return m_icon;
+}
+
+bool Q3ComboBoxPlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *Q3ComboBoxPlugin::createWidget(QWidget *parent)
+{
+ return new Q3ComboBox(parent);
+}
+
+bool Q3ComboBoxPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+QString Q3ComboBoxPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+<widget class=\"Q3ComboBox\" name=\"comboBox\"/>\
+</ui>");
+}
+
+void Q3ComboBoxPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+Q3DateEditPlugin::Q3DateEditPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3DateEditPlugin::name() const
+{ return QLatin1String("Q3DateEdit"); }
+
+QString Q3DateEditPlugin::group() const
+{ return QLatin1String(groupNameC); }
+
+QString Q3DateEditPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3DateEditPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3DateEditPlugin::includeFile() const
+{ return QLatin1String("Qt3Support/Q3DateEdit"); }
+
+QIcon Q3DateEditPlugin::icon() const
+{ return m_icon; }
+
+bool Q3DateEditPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3DateEditPlugin::createWidget(QWidget *parent)
+{ return new Q3DateEdit(parent); }
+
+bool Q3DateEditPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3DateEditPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+QString Q3DateEditPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3DateEdit\" name=\"dateEdit\"/>\
+</ui>");
+}
+
+Q3DateTimeEditPlugin::Q3DateTimeEditPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3DateTimeEditPlugin::name() const
+{ return QLatin1String("Q3DateTimeEdit"); }
+
+QString Q3DateTimeEditPlugin::group() const
+{ return QLatin1String(groupNameC); }
+
+QString Q3DateTimeEditPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3DateTimeEditPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3DateTimeEditPlugin::includeFile() const
+{ return QLatin1String("Qt3Support/Q3DateTimeEdit"); }
+
+QIcon Q3DateTimeEditPlugin::icon() const
+{ return m_icon; }
+
+bool Q3DateTimeEditPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3DateTimeEditPlugin::createWidget(QWidget *parent)
+{ return new Q3DateTimeEdit(parent); }
+
+bool Q3DateTimeEditPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3DateTimeEditPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+QString Q3DateTimeEditPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3DateTimeEdit\" name=\"dateTimeEdit\"/>\
+</ui>");
+}
+
+Q3FramePlugin::Q3FramePlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent),
+ m_initialized(false),
+ m_icon(icon)
+{
+}
+
+Q3FramePlugin::~Q3FramePlugin()
+{
+}
+
+QString Q3FramePlugin::name() const
+{
+ return QLatin1String("Q3Frame");
+}
+
+QString Q3FramePlugin::group() const
+{
+ return QLatin1String(groupNameC);
+}
+
+QString Q3FramePlugin::toolTip() const
+{
+ return QString();
+}
+
+QString Q3FramePlugin::whatsThis() const
+{
+ return QString();
+}
+
+QString Q3FramePlugin::includeFile() const
+{
+ return QLatin1String("Qt3Support/Q3Frame");
+}
+
+QIcon Q3FramePlugin::icon() const
+{
+ return m_icon;
+}
+
+bool Q3FramePlugin::isContainer() const
+{
+ return true;
+}
+
+QWidget *Q3FramePlugin::createWidget(QWidget *parent)
+{
+ return new Q3Frame(parent);
+}
+
+bool Q3FramePlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void Q3FramePlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+QString Q3FramePlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3Frame\" name=\"frame\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+Q3GroupBoxPlugin::Q3GroupBoxPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent),
+ m_initialized(false),
+ m_icon(icon)
+{
+}
+
+Q3GroupBoxPlugin::~Q3GroupBoxPlugin()
+{
+}
+
+QString Q3GroupBoxPlugin::name() const
+{
+ return QLatin1String("Q3GroupBox");
+}
+
+QString Q3GroupBoxPlugin::group() const
+{
+ return QLatin1String(groupNameC);
+}
+
+QString Q3GroupBoxPlugin::toolTip() const
+{
+ return QString();
+}
+
+QString Q3GroupBoxPlugin::whatsThis() const
+{
+ return QString();
+}
+
+QString Q3GroupBoxPlugin::includeFile() const
+{
+ return QLatin1String("Qt3Support/Q3GroupBox");
+}
+
+QIcon Q3GroupBoxPlugin::icon() const
+{
+ return m_icon;
+}
+
+bool Q3GroupBoxPlugin::isContainer() const
+{
+ return true;
+}
+
+QWidget *Q3GroupBoxPlugin::createWidget(QWidget *parent)
+{
+ Q3GroupBox *g = new Q3GroupBox(parent);
+ g->setColumnLayout(0, Qt::Vertical);
+ g->setInsideMargin(0);
+ g->layout()->setSpacing(-1);
+ return g;
+}
+
+bool Q3GroupBoxPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void Q3GroupBoxPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+QString Q3GroupBoxPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3GroupBox\" name=\"groupBox\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ </widget>\
+</ui>");
+}
+
+Q3ProgressBarPlugin::Q3ProgressBarPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3ProgressBarPlugin::name() const
+{ return QLatin1String("Q3ProgressBar"); }
+
+QString Q3ProgressBarPlugin::group() const
+{ return QLatin1String(groupNameC); }
+
+QString Q3ProgressBarPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3ProgressBarPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3ProgressBarPlugin::includeFile() const
+{ return QLatin1String("Qt3Support/Q3ProgressBar"); }
+
+QIcon Q3ProgressBarPlugin::icon() const
+{ return m_icon; }
+
+bool Q3ProgressBarPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3ProgressBarPlugin::createWidget(QWidget *parent)
+{ return new Q3ProgressBar(parent); }
+
+bool Q3ProgressBarPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3ProgressBarPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+QString Q3ProgressBarPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3ProgressBar\" name=\"progressBar\"/>\
+</ui>");
+}
+
+Q3TextBrowserPlugin::Q3TextBrowserPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3TextBrowserPlugin::name() const
+{ return QLatin1String("Q3TextBrowser"); }
+
+QString Q3TextBrowserPlugin::group() const
+{ return QLatin1String(groupNameC); }
+
+QString Q3TextBrowserPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3TextBrowserPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3TextBrowserPlugin::includeFile() const
+{ return QLatin1String("Qt3Support/Q3TextBrowser"); }
+
+QIcon Q3TextBrowserPlugin::icon() const
+{ return m_icon; }
+
+bool Q3TextBrowserPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3TextBrowserPlugin::createWidget(QWidget *parent)
+{ return new Q3TextBrowser(parent); }
+
+bool Q3TextBrowserPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3TextBrowserPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+QString Q3TextBrowserPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3TextBrowser\" name=\"textBrowser\"/>\
+</ui>");
+}
+
+Q3TimeEditPlugin::Q3TimeEditPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3TimeEditPlugin::name() const
+{ return QLatin1String("Q3TimeEdit"); }
+
+QString Q3TimeEditPlugin::group() const
+{ return QLatin1String(groupNameC); }
+
+QString Q3TimeEditPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3TimeEditPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3TimeEditPlugin::includeFile() const
+{ return QLatin1String("Qt3Support/Q3TimeEdit"); }
+
+QIcon Q3TimeEditPlugin::icon() const
+{ return m_icon; }
+
+bool Q3TimeEditPlugin::isContainer() const
+{ return false; }
+
+QWidget *Q3TimeEditPlugin::createWidget(QWidget *parent)
+{ return new Q3TimeEdit(parent); }
+
+bool Q3TimeEditPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3TimeEditPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+ m_initialized = true;
+}
+
+QString Q3TimeEditPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3TimeEdit\" name=\"timeEdit\"/>\
+</ui>");
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3widgets/q3widget_plugins.h b/src/designer/src/plugins/widgets/q3widgets/q3widget_plugins.h
new file mode 100644
index 000000000..2ba00f027
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3widgets/q3widget_plugins.h
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3WIDGET_PLUGINS_H
+#define Q3WIDGET_PLUGINS_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3ButtonGroupPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3ButtonGroupPlugin(const QIcon &icon, QObject *parent = 0);
+ virtual ~Q3ButtonGroupPlugin();
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+
+ virtual bool isContainer() const;
+
+ virtual QWidget *createWidget(QWidget *parent);
+
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+class Q3ComboBoxPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3ComboBoxPlugin(const QIcon &icon, QObject *parent = 0);
+ virtual ~Q3ComboBoxPlugin();
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+
+ virtual bool isContainer() const;
+
+ virtual QWidget *createWidget(QWidget *parent);
+
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+class Q3DateEditPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3DateEditPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+class Q3DateTimeEditPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3DateTimeEditPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+class Q3FramePlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3FramePlugin(const QIcon &icon, QObject *parent = 0);
+ virtual ~Q3FramePlugin();
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+
+ virtual bool isContainer() const;
+
+ virtual QWidget *createWidget(QWidget *parent);
+
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+class Q3GroupBoxPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3GroupBoxPlugin(const QIcon &icon, QObject *parent = 0);
+ virtual ~Q3GroupBoxPlugin();
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+
+ virtual bool isContainer() const;
+
+ virtual QWidget *createWidget(QWidget *parent);
+
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+class Q3ProgressBarPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3ProgressBarPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+class Q3TextBrowserPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3TextBrowserPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+class Q3TimeEditPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3TimeEditPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3WIDGET_PLUGINS_H
diff --git a/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_container.cpp b/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_container.cpp
new file mode 100644
index 000000000..500185da5
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_container.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3widgetstack_container.h"
+#include "qdesigner_q3widgetstack_p.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+Q3WidgetStackContainer::Q3WidgetStackContainer(QDesignerQ3WidgetStack *widget, QObject *parent)
+ : QObject(parent),
+ m_widget(widget)
+{}
+
+int Q3WidgetStackContainer::count() const
+{ return m_pages.count(); }
+
+QWidget *Q3WidgetStackContainer::widget(int index) const
+{
+ if (index == -1)
+ return 0;
+
+ return m_pages.at(index);
+}
+
+int Q3WidgetStackContainer::currentIndex() const
+{ return m_pages.indexOf(m_widget->visibleWidget()); }
+
+void Q3WidgetStackContainer::setCurrentIndex(int index)
+{ m_widget->raiseWidget(m_pages.at(index)); }
+
+void Q3WidgetStackContainer::addWidget(QWidget *widget)
+{
+ m_pages.append(widget);
+ m_widget->addWidget(widget);
+}
+
+void Q3WidgetStackContainer::insertWidget(int index, QWidget *widget)
+{
+ m_pages.insert(index, widget);
+ m_widget->addWidget(widget);
+ m_widget->setCurrentIndex(index);
+}
+
+void Q3WidgetStackContainer::remove(int index)
+{
+ int current = currentIndex();
+ m_widget->removeWidget(m_pages.at(index));
+ m_pages.removeAt(index);
+ if (index == current) {
+ if (count() > 0)
+ m_widget->setCurrentIndex((index == count()) ? index-1 : index);
+ } else if (index < current) {
+ if (current > 0)
+ m_widget->setCurrentIndex(current-1);
+ }
+}
+
+Q3WidgetStackContainerFactory::Q3WidgetStackContainerFactory(QExtensionManager *parent)
+ : QExtensionFactory(parent)
+{
+}
+
+QObject *Q3WidgetStackContainerFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerContainerExtension))
+ return 0;
+
+ if (QDesignerQ3WidgetStack *w = qobject_cast<QDesignerQ3WidgetStack*>(object))
+ return new Q3WidgetStackContainer(w, parent);
+
+ return 0;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_container.h b/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_container.h
new file mode 100644
index 000000000..9c6324de0
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_container.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3WIDGETSTACK_CONTAINER_H
+#define Q3WIDGETSTACK_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionFactory>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerQ3WidgetStack;
+
+class Q3WidgetStackContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit Q3WidgetStackContainer(QDesignerQ3WidgetStack *widget, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ QDesignerQ3WidgetStack *m_widget;
+ QList<QWidget*> m_pages;
+};
+
+class Q3WidgetStackContainerFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3WidgetStackContainerFactory(QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3WIDGETSTACK_CONTAINER_H
diff --git a/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.cpp b/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.cpp
new file mode 100644
index 000000000..2fa87cc09
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3widgetstack_plugin.h"
+#include "q3widgetstack_container.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include "qdesigner_q3widgetstack_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Q3WidgetStackPlugin::Q3WidgetStackPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3WidgetStackPlugin::name() const
+{ return QLatin1String("Q3WidgetStack"); }
+
+QString Q3WidgetStackPlugin::group() const
+{ return QLatin1String("Qt 3 Support"); }
+
+QString Q3WidgetStackPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3WidgetStackPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3WidgetStackPlugin::includeFile() const
+{ return QLatin1String("q3widgetstack.h"); }
+
+QIcon Q3WidgetStackPlugin::icon() const
+{ return m_icon; }
+
+bool Q3WidgetStackPlugin::isContainer() const
+{ return true; }
+
+QWidget *Q3WidgetStackPlugin::createWidget(QWidget *parent)
+{ return new QDesignerQ3WidgetStack(parent); }
+
+bool Q3WidgetStackPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3WidgetStackPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ m_initialized = true;
+ QExtensionManager *mgr = core->extensionManager();
+ mgr->registerExtensions(new Q3WidgetStackContainerFactory(mgr), Q_TYPEID(QDesignerContainerExtension));
+}
+
+QString Q3WidgetStackPlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3WidgetStackPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3WidgetStack\" name=\"widgetStack\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ <widget class=\"QWidget\" name=\"page\"/>\
+ <widget class=\"QWidget\" name=\"page_2\"/>\
+ </widget>\
+</ui>");
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.h b/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.h
new file mode 100644
index 000000000..0e319c259
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3WIDGETSTACK_PLUGIN_H
+#define Q3WIDGETSTACK_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3WidgetStackPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3WidgetStackPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3WIDGETSTACK_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack.cpp b/src/designer/src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack.cpp
new file mode 100644
index 000000000..a6bc34844
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack.cpp
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_q3widgetstack_p.h"
+#include "../../../lib/shared/qdesigner_propertycommand_p.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QEvent>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ QToolButton *createToolButton(QWidget *parent, Qt::ArrowType at, const QString &name) {
+ QToolButton *rc = new QToolButton();
+ rc->setAttribute(Qt::WA_NoChildEventsForParent, true);
+ rc->setParent(parent);
+ rc->setObjectName(name);
+ rc->setArrowType(at);
+ rc->setAutoRaise(true);
+ rc->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ rc->setFixedSize(QSize(15, 15));
+ return rc;
+ }
+}
+
+QDesignerQ3WidgetStack::QDesignerQ3WidgetStack(QWidget *parent) :
+ Q3WidgetStack(parent),
+ m_prev(createToolButton(this, Qt::LeftArrow, QLatin1String("__qt__passive_prev"))),
+ m_next(createToolButton(this, Qt::RightArrow, QLatin1String("__qt__passive_next")))
+{
+ connect(m_prev, SIGNAL(clicked()), this, SLOT(prevPage()));
+ connect(m_next, SIGNAL(clicked()), this, SLOT(nextPage()));
+ updateButtons();
+
+ connect(this, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentChanged(int)));
+}
+
+QDesignerFormWindowInterface *QDesignerQ3WidgetStack::formWindow()
+{
+ return QDesignerFormWindowInterface::findFormWindow(this);
+}
+
+QDesignerContainerExtension *QDesignerQ3WidgetStack::container()
+{
+ if (formWindow()) {
+ QDesignerFormEditorInterface *core = formWindow()->core();
+ return qt_extension<QDesignerContainerExtension*>(core->extensionManager(), this);
+ }
+ return 0;
+}
+
+int QDesignerQ3WidgetStack::count()
+{
+ return container() ? container()->count() : 0;
+}
+
+int QDesignerQ3WidgetStack::currentIndex()
+{
+ return container() ? container()->currentIndex() : -1;
+}
+
+void QDesignerQ3WidgetStack::setCurrentIndex(int index)
+{
+ if (container() && (index >= 0) && (index < count())) {
+ container()->setCurrentIndex(index);
+ emit currentChanged(index);
+ }
+}
+
+QWidget *QDesignerQ3WidgetStack::widget(int index)
+{
+ return container() ? container()->widget(index) : 0;
+}
+
+void QDesignerQ3WidgetStack::updateButtons()
+{
+ if (m_prev) {
+ m_prev->move(width() - 31, 1);
+ m_prev->show();
+ m_prev->raise();
+ }
+
+ if (m_next) {
+ m_next->move(width() - 16, 1);
+ m_next->show();
+ m_next->raise();
+ }
+}
+
+void QDesignerQ3WidgetStack::gotoPage(int page) {
+ // Are we on a form or in a preview?
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ qdesigner_internal::SetPropertyCommand *cmd = new qdesigner_internal::SetPropertyCommand(fw);
+ cmd->init(this, QLatin1String("currentIndex"), page);
+ fw->commandHistory()->push(cmd);
+ fw->emitSelectionChanged(); // Magically prevent an endless loop triggered by auto-repeat.
+ } else {
+ setCurrentIndex(page);
+ }
+ updateButtons();
+}
+
+
+void QDesignerQ3WidgetStack::prevPage()
+{
+ if (count() > 1) {
+ int newIndex = currentIndex() - 1;
+ if (newIndex < 0)
+ newIndex = count() - 1;
+ gotoPage(newIndex);
+ }
+}
+
+void QDesignerQ3WidgetStack::nextPage()
+{
+ if (count() > 1)
+ gotoPage((currentIndex() + 1) % count());
+}
+
+QString QDesignerQ3WidgetStack::currentPageName()
+{
+ if (currentIndex() == -1)
+ return QString();
+
+ return widget(currentIndex())->objectName();
+}
+
+void QDesignerQ3WidgetStack::setCurrentPageName(const QString &pageName)
+{
+ if (currentIndex() == -1)
+ return;
+
+ if (QWidget *w = widget(currentIndex()))
+ w->setObjectName(pageName);
+}
+
+bool QDesignerQ3WidgetStack::event(QEvent *e)
+{
+ if (e->type() == QEvent::LayoutRequest) {
+ updateButtons();
+ }
+
+ return Q3WidgetStack::event(e);
+}
+
+void QDesignerQ3WidgetStack::childEvent(QChildEvent *e)
+{
+ Q3WidgetStack::childEvent(e);
+ updateButtons();
+}
+
+void QDesignerQ3WidgetStack::resizeEvent(QResizeEvent *e)
+{
+ Q3WidgetStack::resizeEvent(e);
+ updateButtons();
+}
+
+void QDesignerQ3WidgetStack::showEvent(QShowEvent *e)
+{
+ Q3WidgetStack::showEvent(e);
+ updateButtons();
+}
+
+void QDesignerQ3WidgetStack::slotCurrentChanged(int index)
+{
+ if (widget(index)) {
+ if (QDesignerFormWindowInterface *fw = formWindow()) {
+ fw->clearSelection();
+ fw->selectWidget(this, true);
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack_p.h b/src/designer/src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack_p.h
new file mode 100644
index 000000000..53f90299f
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QDESIGNER_Q3WIDGETSTACK_P_H
+#define QDESIGNER_Q3WIDGETSTACK_P_H
+
+#include <Qt3Support/Q3WidgetStack>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormWindowInterface;
+class QDesignerContainerExtension;
+class QToolButton;
+class QChildEvent;
+class QResizeEvent;
+class QShowEvent;
+class QEvent;
+
+class QDesignerQ3WidgetStack : public Q3WidgetStack
+{
+ Q_OBJECT
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex STORED false DESIGNABLE true)
+ Q_PROPERTY(QString currentPageName READ currentPageName WRITE setCurrentPageName STORED false DESIGNABLE true)
+public:
+ QDesignerQ3WidgetStack(QWidget *parent = 0);
+ int currentIndex();
+ QString currentPageName();
+
+public slots:
+ void updateButtons();
+ void setCurrentIndex(int index);
+ void setCurrentPageName(const QString &pageName);
+
+private slots:
+ void prevPage();
+ void nextPage();
+ void slotCurrentChanged(int index);
+
+signals:
+ void currentChanged(int index);
+
+protected:
+ virtual void childEvent(QChildEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void showEvent(QShowEvent *e);
+ virtual bool event(QEvent *e);
+
+private:
+ void gotoPage(int page);
+ QDesignerFormWindowInterface *formWindow();
+ QDesignerContainerExtension *container();
+ int count();
+ QWidget *widget(int index);
+ QToolButton *m_prev, *m_next;
+};
+
+QT_END_NAMESPACE
+
+#endif // !QDESIGNER_Q3WIDGETSTACK_P_H
diff --git a/src/designer/src/plugins/widgets/q3wizard/q3wizard_container.cpp b/src/designer/src/plugins/widgets/q3wizard/q3wizard_container.cpp
new file mode 100644
index 000000000..98cbdc7c7
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3wizard/q3wizard_container.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3wizard_container.h"
+#include <Qt3Support/Q3Wizard>
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/private/ui4_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+static const char *currentPageText = "currentPageText";
+
+Q3WizardHelper::Q3WizardHelper(Q3Wizard *wizard)
+ : QObject(wizard),
+ m_wizard(wizard)
+{
+ connect(m_wizard, SIGNAL(selected(QString)), this, SLOT(slotCurrentChanged()));
+}
+
+void Q3WizardHelper::slotCurrentChanged()
+{
+ if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_wizard)) {
+ fw->clearSelection();
+ fw->selectWidget(m_wizard, true);
+ }
+}
+
+Q3WizardExtraInfo::Q3WizardExtraInfo(Q3Wizard *wizard, QDesignerFormEditorInterface *core, QObject *parent)
+ : QObject(parent), m_wizard(wizard), m_core(core)
+{}
+
+QWidget *Q3WizardExtraInfo::widget() const
+{ return m_wizard; }
+
+Q3Wizard *Q3WizardExtraInfo::wizard() const
+{ return m_wizard; }
+
+QDesignerFormEditorInterface *Q3WizardExtraInfo::core() const
+{ return m_core; }
+
+bool Q3WizardExtraInfo::saveUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+bool Q3WizardExtraInfo::loadUiExtraInfo(DomUI *ui)
+{ Q_UNUSED(ui); return false; }
+
+bool Q3WizardExtraInfo::saveWidgetExtraInfo(DomWidget *ui_widget)
+{
+ int i = 0;
+ foreach (DomWidget *ui_child, ui_widget->elementWidget()) {
+ DomProperty *p = new DomProperty();
+ p->setAttributeName(QLatin1String("title"));
+ DomString *str = new DomString();
+ str->setText(wizard()->title(wizard()->page(i)));
+ p->setElementString(str);
+
+ QList<DomProperty *> attributes = ui_child->elementAttribute();
+ attributes.append(p);
+ ui_child->setElementAttribute(attributes);
+
+ i++;
+ }
+ return true;
+}
+
+bool Q3WizardExtraInfo::loadWidgetExtraInfo(DomWidget *ui_widget)
+{
+ int i = 0;
+ foreach (const DomWidget *ui_child, ui_widget->elementWidget()) {
+ foreach (const DomProperty *ui_prop, ui_child->elementAttribute()) {
+ if (ui_prop->attributeName() == QLatin1String("title")) {
+ const DomString *ui_string = ui_prop->elementString();
+ if (ui_string)
+ wizard()->setTitle(wizard()->page(i), ui_string->text());
+ }
+ }
+ i++;
+ }
+ return true;
+}
+
+Q3WizardExtraInfoFactory::Q3WizardExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent)
+ : QExtensionFactory(parent), m_core(core)
+{}
+
+QObject *Q3WizardExtraInfoFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerExtraInfoExtension))
+ return 0;
+
+ if (Q3Wizard *w = qobject_cast<Q3Wizard *>(object))
+ return new Q3WizardExtraInfo(w, m_core, parent);
+
+ return 0;
+}
+
+Q3WizardContainer::Q3WizardContainer(Q3Wizard *wizard, QObject *parent)
+ : QObject(parent),
+ m_wizard(wizard)
+{}
+
+int Q3WizardContainer::count() const
+{
+ return m_wizard->pageCount();
+}
+
+QWidget *Q3WizardContainer::widget(int index) const
+{
+ Q_ASSERT(index != -1);
+ return m_wizard->page(index);
+}
+
+int Q3WizardContainer::currentIndex() const
+{
+ if (m_wizard->currentPage() == 0 && m_wizard->pageCount())
+ m_wizard->showPage(widget(0));
+
+ return m_wizard->indexOf(m_wizard->currentPage());
+}
+
+void Q3WizardContainer::setCurrentIndex(int index)
+{
+ const bool blocked = m_wizard->signalsBlocked();
+ m_wizard->blockSignals(true);
+ m_wizard->showPage(widget(index));
+ m_wizard->blockSignals(blocked);
+}
+
+void Q3WizardContainer::addWidget(QWidget *widget)
+{
+ m_wizard->addPage(widget, tr("Page"));
+}
+
+void Q3WizardContainer::insertWidget(int index, QWidget *widget)
+{
+ m_wizard->insertPage(widget, tr("Page"), index);
+}
+
+void Q3WizardContainer::remove(int index)
+{
+ m_wizard->removePage(widget(index));
+}
+
+Q3WizardContainerFactory::Q3WizardContainerFactory(QExtensionManager *parent)
+ : QExtensionFactory(parent)
+{
+}
+
+QObject *Q3WizardContainerFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
+{
+ if (iid != Q_TYPEID(QDesignerContainerExtension))
+ return 0;
+
+ if (Q3Wizard *w = qobject_cast<Q3Wizard*>(object))
+ return new Q3WizardContainer(w, parent);
+
+ return 0;
+}
+
+Q3WizardPropertySheet::Q3WizardPropertySheet(Q3Wizard *object, QObject *parent)
+ : QDesignerPropertySheet(object, parent), m_wizard(object)
+{
+ createFakeProperty(QLatin1String(currentPageText), QString());
+}
+
+void Q3WizardPropertySheet::setProperty(int index, const QVariant &value)
+{
+ const QString prop = propertyName(index);
+ if (prop == QLatin1String(currentPageText)) {
+ m_wizard->setTitle(m_wizard->currentPage(), value.toString());
+ return;
+ }
+ QDesignerPropertySheet::setProperty(index, value);
+}
+
+QVariant Q3WizardPropertySheet::property(int index) const
+{
+ const QString prop = propertyName(index);
+ if (prop == QLatin1String(currentPageText))
+ return m_wizard->title(m_wizard->currentPage());
+ return QDesignerPropertySheet::property(index);
+}
+
+bool Q3WizardPropertySheet::reset(int index)
+{
+ const QString prop = propertyName(index);
+ if (prop == QLatin1String(currentPageText)) {
+ m_wizard->setTitle(m_wizard->currentPage(), QString());
+ return true;
+ }
+ return QDesignerPropertySheet::reset(index);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3wizard/q3wizard_container.h b/src/designer/src/plugins/widgets/q3wizard/q3wizard_container.h
new file mode 100644
index 000000000..fa9138326
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3wizard/q3wizard_container.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3WIZARD_CONTAINER_H
+#define Q3WIZARD_CONTAINER_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/private/qdesigner_propertysheet_p.h>
+
+#include <QtCore/QPointer>
+#include <Qt3Support/Q3Wizard>
+
+QT_BEGIN_NAMESPACE
+
+class Q3Wizard;
+
+class Q3WizardHelper : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Q3WizardHelper(Q3Wizard *wizard);
+private slots:
+ void slotCurrentChanged();
+private:
+ Q3Wizard *m_wizard;
+};
+
+class Q3WizardExtraInfo: public QObject, public QDesignerExtraInfoExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerExtraInfoExtension)
+public:
+ explicit Q3WizardExtraInfo(Q3Wizard *wizard, QDesignerFormEditorInterface *core, QObject *parent);
+
+ virtual QWidget *widget() const;
+ virtual Q3Wizard *wizard() const;
+ virtual QDesignerFormEditorInterface *core() const;
+
+ virtual bool saveUiExtraInfo(DomUI *ui);
+ virtual bool loadUiExtraInfo(DomUI *ui);
+
+ virtual bool saveWidgetExtraInfo(DomWidget *ui_widget);
+ virtual bool loadWidgetExtraInfo(DomWidget *ui_widget);
+
+private:
+ QPointer<Q3Wizard> m_wizard;
+ QPointer<QDesignerFormEditorInterface> m_core;
+};
+
+class Q3WizardExtraInfoFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ Q3WizardExtraInfoFactory(QDesignerFormEditorInterface *core, QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+
+private:
+ QDesignerFormEditorInterface *m_core;
+};
+
+class Q3WizardContainer: public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit Q3WizardContainer(Q3Wizard *wizard, QObject *parent = 0);
+
+ virtual int count() const;
+ virtual QWidget *widget(int index) const;
+ virtual int currentIndex() const;
+ virtual void setCurrentIndex(int index);
+ virtual void addWidget(QWidget *widget);
+ virtual void insertWidget(int index, QWidget *widget);
+ virtual void remove(int index);
+
+private:
+ Q3Wizard *m_wizard;
+};
+
+class Q3WizardContainerFactory: public QExtensionFactory
+{
+ Q_OBJECT
+public:
+ explicit Q3WizardContainerFactory(QExtensionManager *parent = 0);
+
+protected:
+ virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
+};
+
+class Q3WizardPropertySheet : public QDesignerPropertySheet {
+public:
+ explicit Q3WizardPropertySheet(Q3Wizard *object, QObject *parent = 0);
+
+ virtual void setProperty(int index, const QVariant &value);
+ virtual QVariant property(int index) const;
+ virtual bool reset(int index);
+
+private:
+ Q3Wizard *m_wizard;
+};
+
+typedef QDesignerPropertySheetFactory<Q3Wizard, Q3WizardPropertySheet> Q3WizardPropertySheetFactory;
+
+QT_END_NAMESPACE
+
+#endif // Q3WIZARD_CONTAINER_H
diff --git a/src/designer/src/plugins/widgets/q3wizard/q3wizard_plugin.cpp b/src/designer/src/plugins/widgets/q3wizard/q3wizard_plugin.cpp
new file mode 100644
index 000000000..bb2c17203
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3wizard/q3wizard_plugin.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3wizard_plugin.h"
+#include "q3wizard_container.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtGui/QPushButton>
+#include <Qt3Support/Q3Wizard>
+
+QT_BEGIN_NAMESPACE
+
+Q3WizardPlugin::Q3WizardPlugin(const QIcon &icon, QObject *parent)
+ : QObject(parent), m_initialized(false), m_icon(icon)
+{}
+
+QString Q3WizardPlugin::name() const
+{ return QLatin1String("Q3Wizard"); }
+
+QString Q3WizardPlugin::group() const
+{ return QLatin1String("[invisible]"); }
+
+QString Q3WizardPlugin::toolTip() const
+{ return QString(); }
+
+QString Q3WizardPlugin::whatsThis() const
+{ return QString(); }
+
+QString Q3WizardPlugin::includeFile() const
+{ return QLatin1String("q3wizard.h"); }
+
+QIcon Q3WizardPlugin::icon() const
+{ return m_icon; }
+
+bool Q3WizardPlugin::isContainer() const
+{ return true; }
+
+QWidget *Q3WizardPlugin::createWidget(QWidget *parent)
+{
+ Q3Wizard *wizard = new Q3Wizard(parent);
+ new Q3WizardHelper(wizard);
+ wizard->backButton()->setObjectName(QLatin1String("__qt__passive_") + wizard->backButton()->objectName());
+ wizard->nextButton()->setObjectName(QLatin1String("__qt__passive_") + wizard->nextButton()->objectName());
+ return wizard;
+}
+
+bool Q3WizardPlugin::isInitialized() const
+{ return m_initialized; }
+
+void Q3WizardPlugin::initialize(QDesignerFormEditorInterface *core)
+{
+ Q_UNUSED(core);
+
+ if (m_initialized)
+ return;
+
+ m_initialized = true;
+ QExtensionManager *mgr = core->extensionManager();
+ Q3WizardPropertySheetFactory::registerExtension(mgr);
+ mgr->registerExtensions(new Q3WizardContainerFactory(mgr), Q_TYPEID(QDesignerContainerExtension));
+ mgr->registerExtensions(new Q3WizardExtraInfoFactory(core, mgr), Q_TYPEID(QDesignerExtraInfoExtension));
+}
+
+QString Q3WizardPlugin::codeTemplate() const
+{ return QString(); }
+
+QString Q3WizardPlugin::domXml() const
+{
+ return QLatin1String("\
+<ui language=\"c++\">\
+ <widget class=\"Q3Wizard\" name=\"wizard\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>100</width>\
+ <height>80</height>\
+ </rect>\
+ </property>\
+ <widget class=\"QWidget\" />\
+ <widget class=\"QWidget\" />\
+ </widget>\
+</ui>");
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/plugins/widgets/q3wizard/q3wizard_plugin.h b/src/designer/src/plugins/widgets/q3wizard/q3wizard_plugin.h
new file mode 100644
index 000000000..67b958dbb
--- /dev/null
+++ b/src/designer/src/plugins/widgets/q3wizard/q3wizard_plugin.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3WIZARD_PLUGIN_H
+#define Q3WIZARD_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class Q3WizardPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ explicit Q3WizardPlugin(const QIcon &icon, QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString codeTemplate() const;
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+ QIcon m_icon;
+};
+
+QT_END_NAMESPACE
+
+#endif // Q3WIZARD_PLUGIN_H
diff --git a/src/designer/src/plugins/widgets/qt3supportwidgets.cpp b/src/designer/src/plugins/widgets/qt3supportwidgets.cpp
new file mode 100644
index 000000000..153392787
--- /dev/null
+++ b/src/designer/src/plugins/widgets/qt3supportwidgets.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3toolbar/q3toolbar_plugin.h"
+#include "q3iconview/q3iconview_plugin.h"
+#include "q3wizard/q3wizard_plugin.h"
+#include "q3mainwindow/q3mainwindow_plugin.h"
+#include "q3widgetstack/q3widgetstack_plugin.h"
+#include "q3listview/q3listview_plugin.h"
+#include "q3table/q3table_plugin.h"
+#include "q3listbox/q3listbox_plugin.h"
+#include "q3listview/q3listview_plugin.h"
+#include "q3textedit/q3textedit_plugin.h"
+#include "q3widgets/q3widget_plugins.h"
+
+#include <QtDesigner/QDesignerCustomWidgetCollectionInterface>
+#include <QtCore/qplugin.h>
+#include <QtCore/qdebug.h>
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+class Qt3SupportWidgets: public QObject, public QDesignerCustomWidgetCollectionInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
+public:
+ Qt3SupportWidgets(QObject *parent = 0);
+
+ virtual QList<QDesignerCustomWidgetInterface*> customWidgets() const;
+
+private:
+ QList<QDesignerCustomWidgetInterface*> m_plugins;
+};
+
+Qt3SupportWidgets::Qt3SupportWidgets(QObject *parent)
+ : QObject(parent)
+{
+ const QIcon qt3Icon(QLatin1String(":/trolltech/formeditor/images/qt3logo.png"));
+ m_plugins.append(new Q3ToolBarPlugin(qt3Icon, this));
+ m_plugins.append(new Q3IconViewPlugin(qt3Icon, this));
+ m_plugins.append(new Q3GroupBoxPlugin(qt3Icon, this));
+ m_plugins.append(new Q3FramePlugin(qt3Icon, this));
+ m_plugins.append(new Q3WizardPlugin(qt3Icon, this));
+ m_plugins.append(new Q3MainWindowPlugin(qt3Icon, this));
+ m_plugins.append(new Q3WidgetStackPlugin(qt3Icon, this));
+ m_plugins.append(new Q3ButtonGroupPlugin(qt3Icon, this));
+ m_plugins.append(new Q3TablePlugin(qt3Icon, this));
+ m_plugins.append(new Q3ListBoxPlugin(qt3Icon, this));
+ m_plugins.append(new Q3ListViewPlugin(qt3Icon, this));
+ m_plugins.append(new Q3ComboBoxPlugin(qt3Icon, this));
+ m_plugins.append(new Q3TextEditPlugin(qt3Icon, this));
+ m_plugins.append(new Q3DateEditPlugin(qt3Icon, this));
+ m_plugins.append(new Q3TimeEditPlugin(qt3Icon, this));
+ m_plugins.append(new Q3DateTimeEditPlugin(qt3Icon, this));
+ m_plugins.append(new Q3ProgressBarPlugin(qt3Icon, this));
+ m_plugins.append(new Q3TextBrowserPlugin(qt3Icon, this));
+}
+
+QList<QDesignerCustomWidgetInterface*> Qt3SupportWidgets::customWidgets() const
+{
+ return m_plugins;
+}
+
+Q_EXPORT_PLUGIN(Qt3SupportWidgets)
+
+QT_END_NAMESPACE
+
+#include "qt3supportwidgets.moc"
diff --git a/src/designer/src/plugins/widgets/widgets.pro b/src/designer/src/plugins/widgets/widgets.pro
new file mode 100644
index 000000000..4d8f9bae8
--- /dev/null
+++ b/src/designer/src/plugins/widgets/widgets.pro
@@ -0,0 +1,82 @@
+QT += qt3support
+TEMPLATE = lib
+CONFIG += plugin
+DESTDIR =
+TARGET = qt3supportwidgets
+
+CONFIG += qt warn_on qt_no_compat_warning
+
+include(../plugins.pri)
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+DEPENDPATH += q3iconview \
+ q3listview \
+ q3mainwindow \
+ q3toolbar \
+ q3widgetstack \
+ q3wizard \
+ q3listbox \
+ q3table \
+ q3textedit \
+ q3widgets
+
+INCLUDEPATH += . \
+ q3iconview \
+ q3listview \
+ q3mainwindow \
+ q3toolbar \
+ q3widgetstack \
+ q3wizard \
+ q3listbox \
+ q3table \
+ q3textedit \
+ q3widgets
+
+
+SOURCES += qt3supportwidgets.cpp
+
+# Input
+HEADERS += q3iconview/q3iconview_extrainfo.h \
+ q3iconview/q3iconview_plugin.h \
+ q3listview/q3listview_extrainfo.h \
+ q3listview/q3listview_plugin.h \
+ q3mainwindow/q3mainwindow_container.h \
+ q3mainwindow/q3mainwindow_plugin.h \
+ q3toolbar/q3toolbar_extrainfo.h \
+ q3toolbar/q3toolbar_plugin.h \
+ q3widgetstack/q3widgetstack_container.h \
+ q3widgetstack/q3widgetstack_plugin.h \
+ q3widgetstack/qdesigner_q3widgetstack_p.h \
+ q3wizard/q3wizard_container.h \
+ q3wizard/q3wizard_plugin.h \
+ q3listbox/q3listbox_extrainfo.h \
+ q3listbox/q3listbox_plugin.h \
+ q3table/q3table_extrainfo.h \
+ q3table/q3table_plugin.h \
+ q3textedit/q3textedit_extrainfo.h \
+ q3textedit/q3textedit_plugin.h \
+ q3widgets/q3widget_plugins.h \
+
+SOURCES += q3iconview/q3iconview_extrainfo.cpp \
+ q3iconview/q3iconview_plugin.cpp \
+ q3listview/q3listview_extrainfo.cpp \
+ q3listview/q3listview_plugin.cpp \
+ q3mainwindow/q3mainwindow_container.cpp \
+ q3mainwindow/q3mainwindow_plugin.cpp \
+ q3toolbar/q3toolbar_extrainfo.cpp \
+ q3toolbar/q3toolbar_plugin.cpp \
+ q3widgetstack/q3widgetstack_container.cpp \
+ q3widgetstack/q3widgetstack_plugin.cpp \
+ q3widgetstack/qdesigner_q3widgetstack.cpp \
+ q3wizard/q3wizard_container.cpp \
+ q3wizard/q3wizard_plugin.cpp \
+ q3listbox/q3listbox_extrainfo.cpp \
+ q3listbox/q3listbox_plugin.cpp \
+ q3table/q3table_extrainfo.cpp \
+ q3table/q3table_plugin.cpp \
+ q3textedit/q3textedit_extrainfo.cpp \
+ q3textedit/q3textedit_plugin.cpp \
+ q3widgets/q3widget_plugins.cpp
diff --git a/src/designer/src/sharedcomponents.pri b/src/designer/src/sharedcomponents.pri
new file mode 100644
index 000000000..98c59667d
--- /dev/null
+++ b/src/designer/src/sharedcomponents.pri
@@ -0,0 +1,30 @@
+contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
+
+for(QTSHAREDLIB, $$list($$unique(LIBS))) {
+ QT_SHARED_LIB_NAME =
+ isEqual(QTSHAREDLIB, -lformeditor):QT_SHARED_LIB_NAME = formeditor
+ else:isEqual(QTSHAREDLIB, -lobjectinspector):QT_SHARED_LIB_NAME = objectinspector
+ else:isEqual(QTSHAREDLIB, -lpropertyeditor):QT_SHARED_LIB_NAME = propertyeditor
+ else:isEqual(QTSHAREDLIB, -lwidgetbox):QT_SHARED_LIB_NAME = widgetbox
+ else:isEqual(QTSHAREDLIB, -lsignalsloteditor):QT_SHARED_LIB_NAME = signalsloteditor
+ else:isEqual(QTSHAREDLIB, -ltabordereditor):QT_SHARED_LIB_NAME = tabordereditor
+ else:isEqual(QTSHAREDLIB, -lresourceeditor):QT_SHARED_LIB_NAME = resourceeditor
+ else:isEqual(QTSHAREDLIB, -lbuddyeditor):QT_SHARED_LIB_NAME = buddyeditor
+ else:isEqual(QTSHAREDLIB, -ltaskmenu):QT_SHARED_LIB_NAME = taskmenu
+ else:isEqual(QTSHAREDLIB, -lQtDesigner):QT_SHARED_LIB_NAME = QtDesigner
+ else:isEqual(QTSHAREDLIB, -lQtDesignerComponents):QT_SHARED_LIB_NAME = QtDesignerComponents
+ else:isEqual(QTSHAREDLIB, -lQtOpenGL):QT_SHARED_LIB_NAME = QtOpenGL
+
+ !isEmpty(QT_SHARED_LIB_NAME) {
+ LIBS -= -l$${QT_SHARED_LIB_NAME}
+ qtAddLibrary($$QT_SHARED_LIB_NAME)
+ }
+}
+
+unix {
+ CONFIG += create_pc
+ QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS]
+ QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS]/$$TARGET
+ QMAKE_PKGCONFIG_CFLAGS = -I$$[QT_INSTALL_HEADERS]
+ QMAKE_PKGCONFIG_DESTDIR = pkgconfig
+}
diff --git a/src/designer/src/src.pro b/src/designer/src/src.pro
new file mode 100644
index 000000000..78665b751
--- /dev/null
+++ b/src/designer/src/src.pro
@@ -0,0 +1,12 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS = \
+ uitools \
+ lib \
+ components \
+ designer
+
+CONFIG(shared,shared|static):SUBDIRS += plugins
+
+symbian|wince*: SUBDIRS = uitools
diff --git a/src/doxygen/config/footer.html b/src/doxygen/config/footer.html
new file mode 100644
index 000000000..d7e968d14
--- /dev/null
+++ b/src/doxygen/config/footer.html
@@ -0,0 +1,8 @@
+<p /><address><hr /><div align="center">
+<table width="100%" cellspacing="0" border="0"><tr class="address">
+<td width="30%">Copyright &copy; 2011 Nokia Corporation and/or its subsidiary(-ies).</td>
+<td width="40%" align="center"><a href="trademarks.html">Trademarks</a></td>
+<td width="30%" align="right"><div align="right">Qt $projectnumber</div></td>
+</tr></table></div></address>
+</body>
+</html>
diff --git a/src/doxygen/config/header.html b/src/doxygen/config/header.html
new file mode 100644
index 000000000..504d4f7df
--- /dev/null
+++ b/src/doxygen/config/header.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>$title</title>
+ <link href="phonon.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<table border="0" cellpadding="0" cellspacing="0" width="100%">
+<tr>
+<td align="left" valign="top" width="32">
+<a href="http://qt.nokia.com/"><img src="images/qt-logo.png" align="left" width="32" height="32" border="0" /></a>
+</td>
+<td width="1">&nbsp;&nbsp;</td>
+<td class="postheader" valign="center">
+<a href="index.html">
+<font color="#004faf">Home</font></a>&nbsp;&middot;
+ <a href="classes.html">
+<font color="#004faf">All&nbsp;Classes</font></a>&nbsp;&middot;
+ <a href="mainclasses.html">
+<font color="#004faf">Main&nbsp;Classes</font></a>&nbsp;&middot;
+ <a href="groups.html">
+<font color="#004faf">Grouped&nbsp;Classes</font></a>&nbsp;&middot;
+ <a href="modules.html">
+<font color="#004faf">Modules</font></a>&nbsp;&middot;
+ <a href="functions.html">
+<font color="#004faf">Functions</font></a>
+</td>
+<td align="right" valign="top" width="230"><a href="http://qt.nokia.com"><img src="images/trolltech-logo.png" align="right" width="203" height="32" border="0" /></a></td></tr></table>
diff --git a/src/doxygen/config/phonon.css b/src/doxygen/config/phonon.css
new file mode 100644
index 000000000..fe05e2f60
--- /dev/null
+++ b/src/doxygen/config/phonon.css
@@ -0,0 +1,114 @@
+h3.fn,span.fn
+{
+ margin-left: 1cm;
+ text-indent: -1cm;
+}
+
+a:link
+{
+ color: #004faf;
+ text-decoration: none
+}
+
+a:visited
+{
+ color: #672967;
+ text-decoration: none
+}
+
+td.postheader
+{
+ font-family: sans-serif
+}
+
+tr.address
+{
+ font-family: sans-serif
+}
+
+body
+{
+ background: #ffffff;
+ color: black
+}
+
+table tr.odd {
+ background: #f0f0f0;
+ color: black;
+}
+
+table tr.even {
+ background: #e4e4e4;
+ color: black;
+}
+
+table.annotated th {
+ padding: 3px;
+ text-align: left
+}
+
+table.annotated td {
+ padding: 3px;
+}
+
+table tr pre
+{
+ padding-top: none;
+ padding-bottom: none;
+ padding-left: none;
+ padding-right: none;
+ border: none;
+ background: none
+}
+
+tr.qt-style
+{
+ background: #a2c511;
+ color: black
+}
+
+body pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+p code
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+h1 {
+ text-align: center
+}
+
+span.preprocessor, span.preprocessor a
+{
+ color: darkblue;
+}
+
+span.comment
+{
+ color: darkred;
+ font-style: italic
+}
+
+span.string,span.char
+{
+ color: darkgreen;
+}
+
+.subtitle
+{
+ font-size: 0.8em
+}
+
+.small-subtitle
+{
+ font-size: 0.65em
+}
diff --git a/src/doxygen/config/phonon.doxyfile b/src/doxygen/config/phonon.doxyfile
new file mode 100644
index 000000000..a43007dde
--- /dev/null
+++ b/src/doxygen/config/phonon.doxyfile
@@ -0,0 +1,220 @@
+# Doxygen config file for Phonon documentation, adapted from the KDE apidocs
+# config file.
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = Qt
+PROJECT_NUMBER = %VERSION%
+OUTPUT_DIRECTORY = doc
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 4
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = YES
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = YES
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE = doxygen.log
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = src/3rdparty/kdelibs/phonon
+FILE_PATTERNS = *.cpp \
+ *.h \
+ *.dox
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html-phonon
+HTML_FILE_EXTENSION = .html
+HTML_HEADER = tools/doxygen/config/header.html
+HTML_FOOTER = tools/doxygen/config/footer.html
+HTML_STYLESHEET = tools/doxygen/config/phonon.css
+HTML_ALIGN_MEMBERS = NO
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = NO
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES = doc/indexes/qt.tags
+GENERATE_TAGFILE = doc/indexes/phonon.tags
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
+
+
+### KDE Settings
+ALIASES = \
+ "intern=\par<b>Internal use only.</b>" \
+ "reimp=\par<b>Reimplemented from superclass.</b>" \
+ "obsolete=@deprecated" \
+ "feature=\xrefitem features \"Feature(s)\" \"Features\"" \
+ "maintainer=\xrefitem maintainers \"Maintainer(s)\" \"Maintainers\"" \
+ "unmaintained=\xrefitem unmaintained \"Unmaintained\" \"Unmaintained\"" \
+ "requirement=\xrefitem requirements \"Requirement(s)\" \"Requirements\"" \
+ "faq=\xrefitem FAQ \"F.A.Q.\" \"F.A.Q.\"" \
+ "authors=\xrefitem authors \"Author(s)\" \"Authors\"" \
+ "maintainers=\xrefitem maintainers \"Maintainer(s)\" \"Maintainers\"" \
+ "port4=\xrefitem port4 \"KDE 4 Porting Guide\" \"KDE 4 Porting Guide\"" \
+ "glossary=\xrefitem glossary \"KDE 4 Glossary\" \"KDE 4 Glossary\"" \
+ "acronym=\b "\
+ "licenses=\xrefitem licenses \"License(s)\" \"Licenses\"" \
+ "short=@brief "\
+ "FIXME=\xrefitem fixme \"Fixme\" \"Fixme\"" \
+ "bc=\xrefitem bc \"Binary Compatible\" \"Binary Compatible\"" \
+ "artistic=<a href=\"http://www.opensource.org/licenses/artistic-license.php\">Artistic</a>" \
+ "bsd=<a href=\"http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5\">BSD</a>" \
+ "x11=<a href=\"http://www.xfree86.org/3.3.6/COPYRIGHT2.html#3\">X11</a>" \
+ "gpl=<a href=\"http://www.fsf.org/licensing/licenses/gpl.html#SEC1\">GPL</a>" \
+ "lgpl=<a href=\"http://www.fsf.org/licensing/licenses/lgpl.html#SEC1\">LGPL</a>" \
+ "qpl=<a href=\"http://qt.nokia.com/products/licensing\">QPL</a>"
+
diff --git a/src/kmap2qmap/kmap2qmap.pro b/src/kmap2qmap/kmap2qmap.pro
new file mode 100644
index 000000000..cc8200b7e
--- /dev/null
+++ b/src/kmap2qmap/kmap2qmap.pro
@@ -0,0 +1,12 @@
+
+TEMPLATE = app
+DESTDIR = ../../bin
+QT = core
+CONFIG += console
+CONFIG -= app_bundle
+
+DEPENDPATH += $$QT_SOURCE_TREE/src/gui/embedded
+INCLUDEPATH += $$QT_SOURCE_TREE/src/gui/embedded
+
+# Input
+SOURCES += main.cpp
diff --git a/src/kmap2qmap/main.cpp b/src/kmap2qmap/main.cpp
new file mode 100644
index 000000000..b8b65578f
--- /dev/null
+++ b/src/kmap2qmap/main.cpp
@@ -0,0 +1,991 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <cstdio>
+
+#include <QFile>
+#include <QFileInfo>
+#include <QDir>
+#include <QTextCodec>
+#include <QList>
+#include <QVector>
+#include <QByteArray>
+#include <QStringList>
+#include <QTextStream>
+
+#include "qkbd_qws_p.h"
+
+using namespace std;
+
+
+struct modifier_map_t {
+ const char *symbol;
+ quint8 modifier;
+ quint32 qtmodifier;
+};
+
+static const struct modifier_map_t modifier_map[] = {
+ { "plain", QWSKeyboard::ModPlain, Qt::NoModifier },
+ { "shift", QWSKeyboard::ModShift, Qt::ShiftModifier },
+ { "altgr", QWSKeyboard::ModAltGr, Qt::AltModifier },
+ { "control", QWSKeyboard::ModControl, Qt::ControlModifier },
+ { "alt", QWSKeyboard::ModAlt, Qt::AltModifier },
+ { "meta", QWSKeyboard::ModAlt, Qt::AltModifier },
+ { "shiftl", QWSKeyboard::ModShiftL, Qt::ShiftModifier },
+ { "shiftr", QWSKeyboard::ModShiftR, Qt::ShiftModifier },
+ { "ctrll", QWSKeyboard::ModCtrlL, Qt::ControlModifier },
+ { "ctrlr", QWSKeyboard::ModCtrlR, Qt::ControlModifier },
+};
+
+static const int modifier_map_size = sizeof(modifier_map)/sizeof(modifier_map_t);
+
+
+struct symbol_map_t {
+ const char *symbol;
+ quint32 qtcode;
+};
+
+static const struct symbol_map_t symbol_map[] = {
+ { "space", Qt::Key_Space },
+ { "exclam", Qt::Key_Exclam },
+ { "quotedbl", Qt::Key_QuoteDbl },
+ { "numbersign", Qt::Key_NumberSign },
+ { "dollar", Qt::Key_Dollar },
+ { "percent", Qt::Key_Percent },
+ { "ampersand", Qt::Key_Ampersand },
+ { "apostrophe", Qt::Key_Apostrophe },
+ { "parenleft", Qt::Key_ParenLeft },
+ { "parenright", Qt::Key_ParenRight },
+ { "asterisk", Qt::Key_Asterisk },
+ { "plus", Qt::Key_Plus },
+ { "comma", Qt::Key_Comma },
+ { "minus", Qt::Key_Minus },
+ { "period", Qt::Key_Period },
+ { "slash", Qt::Key_Slash },
+ { "zero", Qt::Key_0 },
+ { "one", Qt::Key_1 },
+ { "two", Qt::Key_2 },
+ { "three", Qt::Key_3 },
+ { "four", Qt::Key_4 },
+ { "five", Qt::Key_5 },
+ { "six", Qt::Key_6 },
+ { "seven", Qt::Key_7 },
+ { "eight", Qt::Key_8 },
+ { "nine", Qt::Key_9 },
+ { "colon", Qt::Key_Colon },
+ { "semicolon", Qt::Key_Semicolon },
+ { "less", Qt::Key_Less },
+ { "equal", Qt::Key_Equal },
+ { "greater", Qt::Key_Greater },
+ { "question", Qt::Key_Question },
+ { "at", Qt::Key_At },
+ { "bracketleft", Qt::Key_BracketLeft },
+ { "backslash", Qt::Key_Backslash },
+ { "bracketright", Qt::Key_BracketRight },
+ { "asciicircum", Qt::Key_AsciiCircum },
+ { "underscore", Qt::Key_Underscore },
+ { "grave", Qt::Key_QuoteLeft },
+ { "braceleft", Qt::Key_BraceLeft },
+ { "bar", Qt::Key_Bar },
+ { "braceright", Qt::Key_BraceRight },
+ { "asciitilde", Qt::Key_AsciiTilde },
+ { "nobreakspace", Qt::Key_nobreakspace },
+ { "exclamdown", Qt::Key_exclamdown },
+ { "cent", Qt::Key_cent },
+ { "sterling", Qt::Key_sterling },
+ { "currency", Qt::Key_currency },
+ { "yen", Qt::Key_yen },
+ { "brokenbar", Qt::Key_brokenbar },
+ { "section", Qt::Key_section },
+ { "diaeresis", Qt::Key_diaeresis },
+ { "copyright", Qt::Key_copyright },
+ { "ordfeminine", Qt::Key_ordfeminine },
+ { "guillemotleft", Qt::Key_guillemotleft },
+ { "notsign", Qt::Key_notsign },
+ { "hyphen", Qt::Key_hyphen },
+ { "registered", Qt::Key_registered },
+ { "macron", Qt::Key_macron },
+ { "degree", Qt::Key_degree },
+ { "plusminus", Qt::Key_plusminus },
+ { "twosuperior", Qt::Key_twosuperior },
+ { "threesuperior", Qt::Key_threesuperior },
+ { "acute", Qt::Key_acute },
+ { "mu", Qt::Key_mu },
+ { "paragraph", Qt::Key_paragraph },
+ { "periodcentered", Qt::Key_periodcentered },
+ { "cedilla", Qt::Key_cedilla },
+ { "onesuperior", Qt::Key_onesuperior },
+ { "masculine", Qt::Key_masculine },
+ { "guillemotright", Qt::Key_guillemotright },
+ { "onequarter", Qt::Key_onequarter },
+ { "onehalf", Qt::Key_onehalf },
+ { "threequarters", Qt::Key_threequarters },
+ { "questiondown", Qt::Key_questiondown },
+ { "Agrave", Qt::Key_Agrave },
+ { "Aacute", Qt::Key_Aacute },
+ { "Acircumflex", Qt::Key_Acircumflex },
+ { "Atilde", Qt::Key_Atilde },
+ { "Adiaeresis", Qt::Key_Adiaeresis },
+ { "Aring", Qt::Key_Aring },
+ { "AE", Qt::Key_AE },
+ { "Ccedilla", Qt::Key_Ccedilla },
+ { "Egrave", Qt::Key_Egrave },
+ { "Eacute", Qt::Key_Eacute },
+ { "Ecircumflex", Qt::Key_Ecircumflex },
+ { "Ediaeresis", Qt::Key_Ediaeresis },
+ { "Igrave", Qt::Key_Igrave },
+ { "Iacute", Qt::Key_Iacute },
+ { "Icircumflex", Qt::Key_Icircumflex },
+ { "Idiaeresis", Qt::Key_Idiaeresis },
+ { "ETH", Qt::Key_ETH },
+ { "Ntilde", Qt::Key_Ntilde },
+ { "Ograve", Qt::Key_Ograve },
+ { "Oacute", Qt::Key_Oacute },
+ { "Ocircumflex", Qt::Key_Ocircumflex },
+ { "Otilde", Qt::Key_Otilde },
+ { "Odiaeresis", Qt::Key_Odiaeresis },
+ { "multiply", Qt::Key_multiply },
+ { "Ooblique", Qt::Key_Ooblique },
+ { "Ugrave", Qt::Key_Ugrave },
+ { "Uacute", Qt::Key_Uacute },
+ { "Ucircumflex", Qt::Key_Ucircumflex },
+ { "Udiaeresis", Qt::Key_Udiaeresis },
+ { "Yacute", Qt::Key_Yacute },
+ { "THORN", Qt::Key_THORN },
+ { "ssharp", Qt::Key_ssharp },
+
+ { "agrave", 0xe0 /*Qt::Key_agrave*/ },
+ { "aacute", 0xe1 /*Qt::Key_aacute*/ },
+ { "acircumflex", 0xe2 /*Qt::Key_acircumflex*/ },
+ { "atilde", 0xe3 /*Qt::Key_atilde*/ },
+ { "adiaeresis", 0xe4 /*Qt::Key_adiaeresis*/ },
+ { "aring", 0xe5 /*Qt::Key_aring*/ },
+ { "ae", 0xe6 /*Qt::Key_ae*/ },
+ { "ccedilla", 0xe7 /*Qt::Key_ccedilla*/ },
+ { "egrave", 0xe8 /*Qt::Key_egrave*/ },
+ { "eacute", 0xe9 /*Qt::Key_eacute*/ },
+ { "ecircumflex", 0xea /*Qt::Key_ecircumflex*/ },
+ { "ediaeresis", 0xeb /*Qt::Key_ediaeresis*/ },
+ { "igrave", 0xec /*Qt::Key_igrave*/ },
+ { "iacute", 0xed /*Qt::Key_iacute*/ },
+ { "icircumflex", 0xee /*Qt::Key_icircumflex*/ },
+ { "idiaeresis", 0xef /*Qt::Key_idiaeresis*/ },
+ { "eth", 0xf0 /*Qt::Key_eth*/ },
+ { "ntilde", 0xf1 /*Qt::Key_ntilde*/ },
+ { "ograve", 0xf2 /*Qt::Key_ograve*/ },
+ { "oacute", 0xf3 /*Qt::Key_oacute*/ },
+ { "ocircumflex", 0xf4 /*Qt::Key_ocircumflex*/ },
+ { "otilde", 0xf5 /*Qt::Key_otilde*/ },
+ { "odiaeresis", 0xf6 /*Qt::Key_odiaeresis*/ },
+ { "division", Qt::Key_division },
+ { "oslash", 0xf8 /*Qt::Key_oslash*/ },
+ { "ugrave", 0xf9 /*Qt::Key_ugrave*/ },
+ { "uacute", 0xfa /*Qt::Key_uacute*/ },
+ { "ucircumflex", 0xfb /*Qt::Key_ucircumflex*/ },
+ { "udiaeresis", 0xfc /*Qt::Key_udiaeresis*/ },
+ { "yacute", 0xfd /*Qt::Key_yacute*/ },
+ { "thorn", 0xfe /*Qt::Key_thorn*/ },
+ { "ydiaeresis", Qt::Key_ydiaeresis },
+
+ { "F1", Qt::Key_F1 },
+ { "F2", Qt::Key_F2 },
+ { "F3", Qt::Key_F3 },
+ { "F4", Qt::Key_F4 },
+ { "F5", Qt::Key_F5 },
+ { "F6", Qt::Key_F6 },
+ { "F7", Qt::Key_F7 },
+ { "F8", Qt::Key_F8 },
+ { "F9", Qt::Key_F9 },
+ { "F10", Qt::Key_F10 },
+ { "F11", Qt::Key_F11 },
+ { "F12", Qt::Key_F12 },
+ { "F13", Qt::Key_F13 },
+ { "F14", Qt::Key_F14 },
+ { "F15", Qt::Key_F15 },
+ { "F16", Qt::Key_F16 },
+ { "F17", Qt::Key_F17 },
+ { "F18", Qt::Key_F18 },
+ { "F19", Qt::Key_F19 },
+ { "F20", Qt::Key_F20 },
+ { "F21", Qt::Key_F21 },
+ { "F22", Qt::Key_F22 },
+ { "F23", Qt::Key_F23 },
+ { "F24", Qt::Key_F24 },
+ { "F25", Qt::Key_F25 },
+ { "F26", Qt::Key_F26 },
+ { "F27", Qt::Key_F27 },
+ { "F28", Qt::Key_F28 },
+ { "F29", Qt::Key_F29 },
+ { "F30", Qt::Key_F30 },
+ { "F31", Qt::Key_F31 },
+ { "F32", Qt::Key_F32 },
+ { "F33", Qt::Key_F33 },
+ { "F34", Qt::Key_F34 },
+ { "F35", Qt::Key_F35 },
+
+ { "BackSpace", Qt::Key_Backspace },
+ { "Tab", Qt::Key_Tab },
+ { "Escape", Qt::Key_Escape },
+ { "Delete", Qt::Key_Backspace }, // what's the difference between "Delete" and "BackSpace"??
+ { "Return", Qt::Key_Return },
+ { "Break", Qt::Key_unknown }, //TODO: why doesn't Qt support the 'Break' key?
+ { "Caps_Lock", Qt::Key_CapsLock },
+ { "Num_Lock", Qt::Key_NumLock },
+ { "Scroll_Lock", Qt::Key_ScrollLock },
+ { "Caps_On", Qt::Key_CapsLock },
+ { "Compose", Qt::Key_Multi_key },
+ { "Bare_Num_Lock", Qt::Key_NumLock },
+ { "Find", Qt::Key_Home },
+ { "Insert", Qt::Key_Insert },
+ { "Remove", Qt::Key_Delete },
+ { "Select", Qt::Key_End },
+ { "Prior", Qt::Key_PageUp },
+ { "Next", Qt::Key_PageDown },
+ { "Help", Qt::Key_Help },
+ { "Pause", Qt::Key_Pause },
+
+ { "KP_0", Qt::Key_0 | Qt::KeypadModifier },
+ { "KP_1", Qt::Key_1 | Qt::KeypadModifier },
+ { "KP_2", Qt::Key_2 | Qt::KeypadModifier },
+ { "KP_3", Qt::Key_3 | Qt::KeypadModifier },
+ { "KP_4", Qt::Key_4 | Qt::KeypadModifier },
+ { "KP_5", Qt::Key_5 | Qt::KeypadModifier },
+ { "KP_6", Qt::Key_6 | Qt::KeypadModifier },
+ { "KP_7", Qt::Key_7 | Qt::KeypadModifier },
+ { "KP_8", Qt::Key_8 | Qt::KeypadModifier },
+ { "KP_9", Qt::Key_9 | Qt::KeypadModifier },
+ { "KP_Add", Qt::Key_Plus | Qt::KeypadModifier },
+ { "KP_Subtract", Qt::Key_Minus | Qt::KeypadModifier },
+ { "KP_Multiply", Qt::Key_Asterisk | Qt::KeypadModifier },
+ { "KP_Divide", Qt::Key_Slash | Qt::KeypadModifier },
+ { "KP_Enter", Qt::Key_Enter | Qt::KeypadModifier },
+ { "KP_Comma", Qt::Key_Comma | Qt::KeypadModifier },
+ { "KP_Period", Qt::Key_Period | Qt::KeypadModifier },
+ { "KP_MinPlus", Qt::Key_plusminus | Qt::KeypadModifier },
+
+ { "dead_grave", Qt::Key_Dead_Grave },
+ { "dead_acute", Qt::Key_Dead_Acute },
+ { "dead_circumflex", Qt::Key_Dead_Circumflex },
+ { "dead_tilde", Qt::Key_Dead_Tilde },
+ { "dead_diaeresis", Qt::Key_Dead_Diaeresis },
+ { "dead_cedilla", Qt::Key_Dead_Cedilla },
+
+ { "Down", Qt::Key_Down },
+ { "Left", Qt::Key_Left },
+ { "Right", Qt::Key_Right },
+ { "Up", Qt::Key_Up },
+ { "Shift", Qt::Key_Shift },
+ { "AltGr", Qt::Key_AltGr },
+ { "Control", Qt::Key_Control },
+ { "Alt", Qt::Key_Alt },
+ { "ShiftL", Qt::Key_Shift },
+ { "ShiftR", Qt::Key_Shift },
+ { "CtrlL", Qt::Key_Control },
+ { "CtrlR", Qt::Key_Control },
+};
+
+static const int symbol_map_size = sizeof(symbol_map)/sizeof(symbol_map_t);
+
+
+struct symbol_dead_unicode_t {
+ quint32 dead;
+ quint16 unicode;
+};
+
+static const symbol_dead_unicode_t symbol_dead_unicode[] = {
+ { Qt::Key_Dead_Grave, '`' },
+ { Qt::Key_Dead_Acute, '\'' },
+ { Qt::Key_Dead_Circumflex, '^' },
+ { Qt::Key_Dead_Tilde, '~' },
+ { Qt::Key_Dead_Diaeresis, '"' },
+ { Qt::Key_Dead_Cedilla, ',' },
+};
+
+static const int symbol_dead_unicode_size = sizeof(symbol_dead_unicode)/sizeof(symbol_dead_unicode_t);
+
+
+struct symbol_synonyms_t {
+ const char *from;
+ const char *to;
+};
+
+static const symbol_synonyms_t symbol_synonyms[] = {
+ { "Control_h", "BackSpace" },
+ { "Control_i", "Tab" },
+ { "Control_j", "Linefeed" },
+ { "Home", "Find" },
+ { "End", "Select" },
+ { "PageUp", "Prior" },
+ { "PageDown", "Next" },
+ { "multiplication", "multiply" },
+ { "pound", "sterling" },
+ { "pilcrow", "paragraph" },
+ { "Oslash", "Ooblique" },
+ { "Shift_L", "ShiftL" },
+ { "Shift_R", "ShiftR" },
+ { "Control_L", "CtrlL" },
+ { "Control_R", "CtrlR" },
+ { "AltL", "Alt" },
+ { "AltR", "AltGr" },
+ { "Alt_L", "Alt" },
+ { "Alt_R", "AltGr" },
+ { "AltGr_L", "Alt" },
+ { "AltGr_R", "AltGr" },
+ { "tilde", "asciitilde" },
+ { "circumflex", "asciicircum" },
+ { "dead_ogonek", "dead_cedilla" },
+ { "dead_caron", "dead_circumflex" },
+ { "dead_breve", "dead_tilde" },
+ { "dead_doubleacute", "dead_tilde" },
+ { "no-break_space", "nobreakspace" },
+ { "paragraph_sign", "section" },
+ { "soft_hyphen", "hyphen" },
+ { "rightanglequote", "guillemotright" },
+};
+
+static const int symbol_synonyms_size = sizeof(symbol_synonyms)/sizeof(symbol_synonyms_t);
+
+// makes the generated array in --header mode a bit more human readable
+QT_BEGIN_NAMESPACE
+static bool operator<(const QWSKeyboard::Mapping &m1, const QWSKeyboard::Mapping &m2)
+{
+ return m1.keycode != m2.keycode ? m1.keycode < m2.keycode : m1.modifiers < m2.modifiers;
+}
+QT_END_NAMESPACE
+
+class KeymapParser {
+public:
+ KeymapParser();
+ ~KeymapParser();
+
+ bool parseKmap(QFile *kmap);
+ bool generateQmap(QFile *qmap);
+ bool generateHeader(QFile *qmap);
+
+ int parseWarningCount() const { return m_warning_count; }
+
+private:
+ bool parseSymbol(const QByteArray &str, const QTextCodec *codec, quint16 &unicode, quint32 &qtcode, quint8 &flags, quint16 &special);
+ bool parseCompose(const QByteArray &str, const QTextCodec *codec, quint16 &unicode);
+ bool parseModifier(const QByteArray &str, quint8 &modifier);
+
+ void updateMapping(quint16 keycode = 0, quint8 modifiers = 0, quint16 unicode = 0xffff, quint32 qtcode = Qt::Key_unknown, quint8 flags = 0, quint16 = 0);
+
+ static quint32 toQtModifiers(quint8 modifiers);
+ static QList<QByteArray> tokenize(const QByteArray &line);
+
+
+private:
+ QList<QWSKeyboard::Mapping> m_keymap;
+ QList<QWSKeyboard::Composing> m_keycompose;
+
+ int m_warning_count;
+};
+
+
+
+int main(int argc, char **argv)
+{
+ int header = 0;
+ if (argc >= 2 && !qstrcmp(argv[1], "--header"))
+ header = 1;
+
+ if (argc < (3 + header)) {
+ fprintf(stderr, "Usage: kmap2qmap [--header] <kmap> [<additional kmaps> ...] <qmap>\n");
+ fprintf(stderr, " --header can be used to generate Qt's default compiled in qmap.\n");
+ return 1;
+ }
+
+ QVector<QFile *> kmaps(argc - header - 2);
+ for (int i = 0; i < kmaps.size(); ++i) {
+ kmaps [i] = new QFile(QString::fromLocal8Bit(argv[i + 1 + header]));
+
+ if (!kmaps[i]->open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Could not read from '%s'.\n", argv[i + 1 + header]);
+ return 2;
+ }
+ }
+ QFile *qmap = new QFile(QString::fromLocal8Bit(argv[argc - 1]));
+
+ if (!qmap->open(QIODevice::WriteOnly)) {
+ fprintf(stderr, "Could not write to '%s'.\n", argv[argc - 1]);
+ return 3;
+ }
+
+ KeymapParser p;
+
+ for (int i = 0; i < kmaps.size(); ++i) {
+ if (!p.parseKmap(kmaps[i])) {
+ fprintf(stderr, "Parsing kmap '%s' failed.\n", qPrintable(kmaps[i]->fileName()));
+ return 4;
+ }
+ }
+
+ if (p.parseWarningCount()) {
+ fprintf(stderr, "\nParsing the specified keymap(s) produced %d warning(s).\n" \
+ "Your generated qmap might not be complete.\n", \
+ p.parseWarningCount());
+ }
+ if (!(header ? p.generateHeader(qmap) : p.generateQmap(qmap))) {
+ fprintf(stderr, "Generating the qmap failed.\n");
+ return 5;
+ }
+
+ qDeleteAll(kmaps);
+ delete qmap;
+
+ return 0;
+}
+
+
+KeymapParser::KeymapParser()
+ : m_warning_count(0)
+{ }
+
+
+KeymapParser::~KeymapParser()
+{ }
+
+
+bool KeymapParser::generateHeader(QFile *f)
+{
+ QTextStream ts(f);
+
+ ts << "#ifndef QWSKEYBOARDHANDLER_DEFAULTMAP_H" << endl;
+ ts << "#define QWSKEYBOARDHANDLER_DEFAULTMAP_H" << endl << endl;
+
+ ts << "const QWSKeyboard::Mapping QWSKbPrivate::s_keymap_default[] = {" << endl;
+
+ for (int i = 0; i < m_keymap.size(); ++i) {
+ const QWSKeyboard::Mapping &m = m_keymap.at(i);
+ QString s;
+ s.sprintf(" { %3d, 0x%04x, 0x%08x, 0x%02x, 0x%02x, 0x%04x },\n", m.keycode, m.unicode, m.qtcode, m.modifiers, m.flags, m.special);
+ ts << s;
+ }
+
+ ts << "};" << endl << endl;
+
+ ts << "const QWSKeyboard::Composing QWSKbPrivate::s_keycompose_default[] = {" << endl;
+
+ for (int i = 0; i < m_keycompose.size(); ++i) {
+ const QWSKeyboard::Composing &c = m_keycompose.at(i);
+ QString s;
+ s.sprintf(" { 0x%04x, 0x%04x, 0x%04x },\n", c.first, c.second, c.result);
+ ts << s;
+ }
+ ts << "};" << endl << endl;
+
+ ts << "#endif" << endl;
+
+ return (ts.status() == QTextStream::Ok);
+}
+
+
+bool KeymapParser::generateQmap(QFile *f)
+{
+ QDataStream ds(f);
+
+ ds << quint32(QWSKeyboard::FileMagic) << quint32(1 /* version */) << quint32(m_keymap.size()) << quint32(m_keycompose.size());
+
+ if (ds.status() != QDataStream::Ok)
+ return false;
+
+ for (int i = 0; i < m_keymap.size(); ++i)
+ ds << m_keymap[i];
+
+ for (int i = 0; i < m_keycompose.size(); ++i)
+ ds << m_keycompose[i];
+
+ return (ds.status() == QDataStream::Ok);
+}
+
+
+QList<QByteArray> KeymapParser::tokenize(const QByteArray &line)
+{
+ bool quoted = false, separator = true;
+ QList<QByteArray> result;
+ QByteArray token;
+
+ for (int i = 0; i < line.length(); ++i) {
+ QChar c = line.at(i);
+
+ if (!quoted && c == '#' && separator)
+ break;
+ else if (!quoted && c == '"' && separator)
+ quoted = true;
+ else if (quoted && c == '"')
+ quoted = false;
+ else if (!quoted && c.isSpace()) {
+ separator = true;
+ if (!token.isEmpty()) {
+ result.append(token);
+ token.truncate(0);
+ }
+ }
+ else {
+ separator = false;
+ token.append(c);
+ }
+ }
+ if (!token.isEmpty())
+ result.append(token);
+ return result;
+}
+
+
+#define parseWarning(s) do { qWarning("Warning: keymap file '%s', line %d: %s", qPrintable(f->fileName()), lineno, s); ++m_warning_count; } while (false)
+
+bool KeymapParser::parseKmap(QFile *f)
+{
+ QByteArray line;
+ int lineno = 0;
+ QList<int> keymaps;
+ QTextCodec *codec = QTextCodec::codecForName("iso8859-1");
+
+ for (int i = 0; i <= 256; ++i)
+ keymaps << i;
+
+ while (!f->atEnd() && !f->error()) {
+ line = f->readLine();
+ lineno++;
+
+ QList<QByteArray> tokens = tokenize(line);
+
+ if (tokens.isEmpty())
+ continue;
+
+ if (tokens[0] == "keymaps") {
+ keymaps.clear();
+
+ if (tokens.count() > 1) {
+ foreach (const QByteArray &section, tokens[1].split(',')) {
+ int dashpos = section.indexOf('-');
+
+ //qWarning("Section %s", section.constData());
+ int end = section.mid(dashpos + 1).toInt();
+ int start = end;
+ if (dashpos > 0)
+ start = section.left(dashpos).toInt();
+
+ if (start <= end && start >=0 && end <= 256) {
+ for (int i = start; i <= end; ++i) {
+ //qWarning("appending keymap %d", i);
+ keymaps.append(i);
+ }
+ }
+ else
+ parseWarning("keymaps has an invalid range");
+ }
+ qSort(keymaps);
+ }
+ else
+ parseWarning("keymaps with more than one argument");
+ }
+ else if (tokens[0] == "alt_is_meta") {
+ // simply ignore it for now
+ }
+ else if (tokens[0] == "include") {
+ if (tokens.count() == 2) {
+ QString incname = QString::fromLocal8Bit(tokens[1]);
+ bool found = false;
+ QList<QDir> searchpath;
+ QFileInfo fi(*f);
+
+ if (!incname.endsWith(QLatin1String(".kmap")) && !incname.endsWith(QLatin1String(".inc")))
+ incname.append(QLatin1String(".inc"));
+
+ QDir d = fi.dir();
+ searchpath << d;
+ if (d.cdUp() && d.cd(QLatin1String("include")))
+ searchpath << d;
+ searchpath << QDir::current();
+
+ foreach (const QDir &path, searchpath) {
+ QFile f2(path.filePath(incname));
+ //qWarning(" -- trying to include %s", qPrintable(f2.fileName()));
+ if (f2.open(QIODevice::ReadOnly)) {
+ if (!parseKmap(&f2))
+ parseWarning("could not parse keymap include");
+ found = true;
+ }
+ }
+
+ if (!found)
+ parseWarning("could not locate keymap include");
+ } else
+ parseWarning("include doesn't have exactly one argument");
+ }
+ else if (tokens[0] == "charset") {
+ if (tokens.count() == 2) {
+ codec = QTextCodec::codecForName(tokens[1]);
+ if (!codec) {
+ parseWarning("could not parse codec definition");
+ codec = QTextCodec::codecForName("iso8859-1");
+ }
+ } else
+ parseWarning("codec doesn't habe exactly one argument");
+ }
+ else if (tokens[0] == "strings") {
+ // simply ignore those - they have no meaning for QWS
+ }
+ else if (tokens[0] == "compose") {
+ if (tokens.count() == 5 && tokens[3] == "to") {
+ QWSKeyboard::Composing c = { 0xffff, 0xffff, 0xffff };
+
+ if (!parseCompose(tokens[1], codec, c.first))
+ parseWarning("could not parse first compose symbol");
+ if (!parseCompose(tokens[2], codec, c.second))
+ parseWarning("could not parse second compose symbol");
+ if (!parseCompose(tokens[4], codec, c.result))
+ parseWarning("could not parse resulting compose symbol");
+
+ if (c.first != 0xffff && c.second != 0xffff && c.result != 0xffff) {
+ m_keycompose << c;
+ }
+ } else
+ parseWarning("non-standard compose line");
+ }
+ else {
+ int kcpos = tokens.indexOf("keycode");
+
+ if (kcpos >= 0 && kcpos < (tokens.count()-3) && tokens[kcpos+2] == "=") {
+ quint16 keycode = tokens[kcpos+1].toInt();
+
+ if (keycode <= 0 || keycode > 0x1ff /* KEY_MAX */) {
+ parseWarning("keycode out of range [0..0x1ff]");
+ break;
+ }
+
+ bool line_modifiers = (kcpos > 0);
+
+ quint8 modifiers = 0; //, modifiers_mask = 0xff;
+ for (int i = 0; i < kcpos; ++i) {
+ quint8 mod;
+ if (!parseModifier(tokens[i], mod)) {
+ parseWarning("unknown modifier prefix for keycode");
+ continue;
+ }
+ modifiers |= mod;
+ }
+
+ int kccount = tokens.count() - kcpos - 3; // 3 : 'keycode' 'X' '='
+
+ if (line_modifiers && kccount > 1) {
+ parseWarning("line has modifiers, but more than one keycode");
+ break;
+ }
+
+ // only process one symbol when a prefix modifer was specified
+ for (int i = 0; i < (line_modifiers ? 1 : kccount); ++i) {
+ if (!line_modifiers)
+ modifiers = keymaps[i];
+
+ quint32 qtcode;
+ quint16 unicode;
+ quint16 special;
+ quint8 flags;
+ if (!parseSymbol(tokens[i + kcpos + 3], codec, unicode, qtcode, flags, special)) {
+ parseWarning((QByteArray("symbol could not be parsed: ") + tokens[i + kcpos + 3]).constData());
+ break;
+ }
+
+ if (qtcode == Qt::Key_unknown && unicode == 0xffff) // VoidSymbol
+ continue;
+
+ if (!line_modifiers && kccount == 1) {
+ if ((unicode >= 'A' && unicode <= 'Z') || (unicode >= 'a' && unicode <= 'z')) {
+ quint16 other_unicode = (unicode >= 'A' && unicode <= 'Z') ? unicode - 'A' + 'a' : unicode - 'a' + 'A';
+ quint16 lower_unicode = (unicode >= 'A' && unicode <= 'Z') ? unicode - 'A' + 'a' : unicode;
+
+ // a single a-z|A-Z value results in a very flags mapping: see below
+
+ updateMapping(keycode, QWSKeyboard::ModPlain, unicode, qtcode, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModShift, other_unicode, qtcode, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModAltGr, unicode, qtcode, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, other_unicode, qtcode, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModControl, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModAltGr, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModAlt, unicode, qtcode | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModShift, unicode, qtcode | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModAltGr, unicode, qtcode | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, unicode, qtcode | Qt::AltModifier, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModAltGr, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
+ }
+ else {
+ // a single value results in that mapping regardless of the modifier
+ //for (int mod = 0; mod <= 255; ++mod)
+ // updateMapping(keycode, quint8(mod), unicode, qtcode | toQtModifiers(mod), flags, special);
+
+ // we can save a lot of space in the qmap, since we do that anyway in the kbd handler:
+ updateMapping(keycode, QWSKeyboard::ModPlain, unicode, qtcode, flags, special);
+ }
+ }
+ else {
+ // "normal" mapping
+ updateMapping(keycode, modifiers, unicode, qtcode, flags, special);
+ }
+ }
+ }
+ }
+ }
+ qSort(m_keymap);
+ return !m_keymap.isEmpty();
+}
+
+
+
+void KeymapParser::updateMapping(quint16 keycode, quint8 modifiers, quint16 unicode, quint32 qtcode, quint8 flags, quint16 special)
+{
+ for (int i = 0; i < m_keymap.size(); ++i) {
+ QWSKeyboard::Mapping &m = m_keymap[i];
+
+ if (m.keycode == keycode && m.modifiers == modifiers) {
+ m.unicode = unicode;
+ m.qtcode = qtcode;
+ m.flags = flags;
+ m.special = special;
+ return;
+ }
+ }
+ QWSKeyboard::Mapping m = { keycode, unicode, qtcode, modifiers, flags, special };
+ m_keymap << m;
+}
+
+
+quint32 KeymapParser::toQtModifiers(quint8 modifiers)
+{
+ quint32 qtmodifiers = Qt::NoModifier;
+
+ for (int i = 0; i < modifier_map_size; ++i) {
+ if (modifiers & modifier_map[i].modifier)
+ qtmodifiers |= modifier_map[i].qtmodifier;
+ }
+ return qtmodifiers;
+}
+
+
+bool KeymapParser::parseModifier(const QByteArray &str, quint8 &modifier)
+{
+ QByteArray lstr = str.toLower();
+
+ for (int i = 0; i < modifier_map_size; ++i) {
+ if (lstr == modifier_map[i].symbol) {
+ modifier = modifier_map[i].modifier;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool KeymapParser::parseCompose(const QByteArray &str, const QTextCodec *codec, quint16 &unicode)
+{
+ if (str == "'\\''") {
+ unicode = '\'';
+ return true;
+ } else if (str.length() == 3 && str.startsWith('\'') && str.endsWith('\'')) {
+ QString temp = codec->toUnicode(str.constData() + 1, str.length() - 2);
+ if (temp.length() != 1)
+ return false;
+ unicode = temp[0].unicode();
+ return true;
+ } else {
+ quint32 code = str.toUInt();
+ if (code > 255)
+ return false;
+ char c[2];
+ c[0] = char(code);
+ c[1] = 0;
+ QString temp = codec->toUnicode(c);
+ if (temp.length() != 1)
+ return false;
+ unicode = temp[0].unicode();
+ return true;
+ }
+}
+
+
+bool KeymapParser::parseSymbol(const QByteArray &str, const QTextCodec * /*codec*/, quint16 &unicode, quint32 &qtcode, quint8 &flags, quint16 &special)
+{
+ flags = (str[0] == '+') ? QWSKeyboard::IsLetter : 0;
+ QByteArray sym = (flags & QWSKeyboard::IsLetter) ? str.right(str.length() - 1) : str;
+
+ special = 0;
+ qtcode = Qt::Key_unknown;
+ unicode = 0xffff;
+
+ if (sym == "VoidSymbol" || sym == "nul")
+ return true;
+
+ bool try_to_find_qtcode = false;
+
+ if (sym[0] >= '0' && sym[0] <= '9') { // kernel internal action number
+ return false;
+ } else if (sym.length() == 6 && sym[1] == '+' && (sym[0] == 'U' || sym[0] == 'u')) { // unicode
+ bool ok;
+ unicode = sym.mid(2).toUInt(&ok, 16);
+ if (!ok)
+ return false;
+ try_to_find_qtcode = true;
+ } else { // symbolic
+ for (int i = 0; i < symbol_synonyms_size; ++i) {
+ if (sym == symbol_synonyms[i].from) {
+ sym = symbol_synonyms[i].to;
+ break;
+ }
+ }
+
+ quint32 qtmod = 0;
+
+ // parse prepended modifiers
+ forever {
+ int underpos = sym.indexOf('_');
+
+ if (underpos <= 0)
+ break;
+ QByteArray modsym = sym.left(underpos);
+ QByteArray nomodsym = sym.mid(underpos + 1);
+ quint8 modifier = 0;
+
+ if (!parseModifier(modsym, modifier))
+ break;
+
+ qtmod |= toQtModifiers(modifier);
+ sym = nomodsym;
+ }
+
+ if (qtcode == Qt::Key_unknown) {
+ quint8 modcode;
+ // check if symbol is a modifier
+ if (parseModifier(sym, modcode)) {
+ special = modcode;
+ flags |= QWSKeyboard::IsModifier;
+ }
+
+ // map symbol to Qt key code
+ for (int i = 0; i < symbol_map_size; ++i) {
+ if (sym == symbol_map[i].symbol) {
+ qtcode = symbol_map[i].qtcode;
+ break;
+ }
+ }
+
+ // a-zA-Z is not in the table to save space
+ if (qtcode == Qt::Key_unknown && sym.length() == 1) {
+ char letter = sym.at(0);
+
+ if (letter >= 'a' && letter <= 'z') {
+ qtcode = Qt::Key_A + letter - 'a';
+ unicode = letter;
+ }
+ else if (letter >= 'A' && letter <= 'Z') {
+ qtcode = Qt::Key_A + letter - 'A';
+ unicode = letter;
+ }
+ }
+ // System keys
+ if (qtcode == Qt::Key_unknown) {
+ quint16 sys = 0;
+
+ if (sym == "Decr_Console") {
+ sys = QWSKeyboard::SystemConsolePrevious;
+ } else if (sym == "Incr_Console") {
+ sys = QWSKeyboard::SystemConsoleNext;
+ } else if (sym.startsWith("Console_")) {
+ int console = sym.mid(8).toInt() - 1;
+ if (console >= 0 && console <= (QWSKeyboard::SystemConsoleLast - QWSKeyboard::SystemConsoleFirst)) {
+ sys = QWSKeyboard::SystemConsoleFirst + console;
+ }
+ } else if (sym == "Boot") {
+ sys = QWSKeyboard::SystemReboot;
+ } else if (sym == "QtZap") {
+ sys = QWSKeyboard::SystemZap;
+ }
+
+ if (sys) {
+ flags |= QWSKeyboard::IsSystem;
+ special = sys;
+ qtcode = Qt::Key_Escape; // just a dummy
+ }
+ }
+
+ // map Qt key codes in the iso-8859-1 range to unicode
+ if (qtcode != Qt::Key_unknown && unicode == 0xffff) {
+ quint32 qtcode_no_mod = qtcode & ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier);
+ if (qtcode_no_mod <= 0x000000ff) // iso-8859-1
+ unicode = quint16(qtcode_no_mod);
+ }
+
+ // flag dead keys
+ if (qtcode >= Qt::Key_Dead_Grave && qtcode <= Qt::Key_Dead_Horn) {
+ flags = QWSKeyboard::IsDead;
+
+ for (int i = 0; i < symbol_dead_unicode_size; ++i) {
+ if (symbol_dead_unicode[i].dead == qtcode) {
+ unicode = symbol_dead_unicode[i].unicode;
+ break;
+ }
+ }
+ }
+ }
+ if ((qtcode == Qt::Key_unknown) && (unicode == 0xffff))
+ return false;
+
+ qtcode |= qtmod;
+ }
+
+ // map unicode in the iso-8859-1 range to Qt key codes
+ if (unicode >= 0x0020 && unicode <= 0x00ff && qtcode == Qt::Key_unknown)
+ qtcode = unicode; // iso-8859-1
+
+ return true;
+}
+
diff --git a/src/linguist/lconvert/lconvert.pro b/src/linguist/lconvert/lconvert.pro
new file mode 100644
index 000000000..66a194ec1
--- /dev/null
+++ b/src/linguist/lconvert/lconvert.pro
@@ -0,0 +1,22 @@
+
+TEMPLATE = app
+TARGET = lconvert
+DESTDIR = ../../../bin
+
+QT -= gui
+
+CONFIG += qt warn_on console
+CONFIG -= app_bundle
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+include(../shared/formats.pri)
+
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
+SOURCES += main.cpp
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/linguist/lconvert/main.cpp b/src/linguist/lconvert/main.cpp
new file mode 100644
index 000000000..a9960fc65
--- /dev/null
+++ b/src/linguist/lconvert/main.cpp
@@ -0,0 +1,301 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QTranslator>
+#include <QtCore/QLibraryInfo>
+
+#include <iostream>
+
+QT_USE_NAMESPACE
+
+class LC {
+ Q_DECLARE_TR_FUNCTIONS(LConvert)
+};
+
+static int usage(const QStringList &args)
+{
+ Q_UNUSED(args);
+
+ QString loaders;
+ QString line(QLatin1String(" %1 - %2\n"));
+ foreach (Translator::FileFormat format, Translator::registeredFileFormats())
+ loaders += line.arg(format.extension, -5).arg(format.description);
+
+ std::cout << qPrintable(LC::tr("\nUsage:\n"
+ " lconvert [options] <infile> [<infile>...]\n\n"
+ "lconvert is part of Qt's Linguist tool chain. It can be used as a\n"
+ "stand-alone tool to convert and filter translation data files.\n"
+ "The following file formats are supported:\n\n%1\n"
+ "If multiple input files are specified, they are merged with\n"
+ "translations from later files taking precedence.\n\n"
+ "Options:\n"
+ " -h\n"
+ " --help Display this information and exit.\n\n"
+ " -i <infile>\n"
+ " --input-file <infile>\n"
+ " Specify input file. Use if <infile> might start with a dash.\n"
+ " This option can be used several times to merge inputs.\n"
+ " May be '-' (standard input) for use in a pipe.\n\n"
+ " -o <outfile>\n"
+ " --output-file <outfile>\n"
+ " Specify output file. Default is '-' (standard output).\n\n"
+ " -if <informat>\n"
+ " --input-format <format>\n"
+ " Specify input format for subsequent <infile>s.\n"
+ " The format is auto-detected from the file name and defaults to 'ts'.\n\n"
+ " -of <outformat>\n"
+ " --output-format <outformat>\n"
+ " Specify output format. See -if.\n\n"
+ " --input-codec <codec>\n"
+ " Specify encoding for QM and PO input files. Default is 'Latin1'\n"
+ " for QM and 'UTF-8' for PO files. UTF-8 is always tried as well for\n"
+ " QM, corresponding to the possible use of the trUtf8() function.\n\n"
+ " --output-codec <codec>\n"
+ " Specify encoding for PO output files. Default is 'UTF-8'.\n\n"
+ " --drop-tags <regexp>\n"
+ " Drop named extra tags when writing TS or XLIFF files.\n"
+ " May be specified repeatedly.\n\n"
+ " --drop-translations\n"
+ " Drop existing translations and reset the status to 'unfinished'.\n"
+ " Note: this implies --no-obsolete.\n\n"
+ " --source-language <language>[_<region>]\n"
+ " Specify/override the language of the source strings. Defaults to\n"
+ " POSIX if not specified and the file does not name it yet.\n\n"
+ " --target-language <language>[_<region>]\n"
+ " Specify/override the language of the translation.\n"
+ " The target language is guessed from the file name if this option\n"
+ " is not specified and the file contents name no language yet.\n\n"
+ " --no-obsolete\n"
+ " Drop obsolete messages.\n\n"
+ " --no-finished\n"
+ " Drop finished messages.\n\n"
+ " --sort-contexts\n"
+ " Sort contexts in output TS file alphabetically.\n\n"
+ " --locations {absolute|relative|none}\n"
+ " Override how source code references are saved in TS files.\n"
+ " Default is absolute.\n\n"
+ " --no-ui-lines\n"
+ " Drop line numbers from references to UI files.\n\n"
+ " --verbose\n"
+ " be a bit more verbose\n\n"
+ "Long options can be specified with only one leading dash, too.\n\n"
+ "Return value:\n"
+ " 0 on success\n"
+ " 1 on command line parse failures\n"
+ " 2 on read failures\n"
+ " 3 on write failures\n").arg(loaders));
+ return 1;
+}
+
+struct File
+{
+ QString name;
+ QString format;
+};
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+#endif // Q_OS_WIN32
+
+ QStringList args = app.arguments();
+ QList<File> inFiles;
+ QString inFormat(QLatin1String("auto"));
+ QString outFileName;
+ QString outFormat(QLatin1String("auto"));
+ QString targetLanguage;
+ QString sourceLanguage;
+ bool dropTranslations = false;
+ bool noObsolete = false;
+ bool noFinished = false;
+ bool verbose = false;
+ bool noUiLines = false;
+ Translator::LocationsType locations = Translator::DefaultLocations;
+
+ ConversionData cd;
+ Translator tr;
+
+ for (int i = 1; i < args.size(); ++i) {
+ if (args[i].startsWith(QLatin1String("--")))
+ args[i].remove(0, 1);
+ if (args[i] == QLatin1String("-o")
+ || args[i] == QLatin1String("-output-file")) {
+ if (++i >= args.size())
+ return usage(args);
+ outFileName = args[i];
+ } else if (args[i] == QLatin1String("-of")
+ || args[i] == QLatin1String("-output-format")) {
+ if (++i >= args.size())
+ return usage(args);
+ outFormat = args[i];
+ } else if (args[i] == QLatin1String("-i")
+ || args[i] == QLatin1String("-input-file")) {
+ if (++i >= args.size())
+ return usage(args);
+ File file;
+ file.name = args[i];
+ file.format = inFormat;
+ inFiles.append(file);
+ } else if (args[i] == QLatin1String("-if")
+ || args[i] == QLatin1String("-input-format")) {
+ if (++i >= args.size())
+ return usage(args);
+ inFormat = args[i];
+ } else if (args[i] == QLatin1String("-input-codec")) {
+ if (++i >= args.size())
+ return usage(args);
+ cd.m_codecForSource = args[i].toLatin1();
+ } else if (args[i] == QLatin1String("-output-codec")) {
+ if (++i >= args.size())
+ return usage(args);
+ cd.m_outputCodec = args[i].toLatin1();
+ } else if (args[i] == QLatin1String("-drop-tag")) {
+ if (++i >= args.size())
+ return usage(args);
+ cd.m_dropTags.append(args[i]);
+ } else if (args[i] == QLatin1String("-drop-translations")) {
+ dropTranslations = true;
+ } else if (args[i] == QLatin1String("-target-language")) {
+ if (++i >= args.size())
+ return usage(args);
+ targetLanguage = args[i];
+ } else if (args[i] == QLatin1String("-source-language")) {
+ if (++i >= args.size())
+ return usage(args);
+ sourceLanguage = args[i];
+ } else if (args[i].startsWith(QLatin1String("-h"))) {
+ usage(args);
+ return 0;
+ } else if (args[i] == QLatin1String("-no-obsolete")) {
+ noObsolete = true;
+ } else if (args[i] == QLatin1String("-no-finished")) {
+ noFinished = true;
+ } else if (args[i] == QLatin1String("-sort-contexts")) {
+ cd.m_sortContexts = true;
+ } else if (args[i] == QLatin1String("-locations")) {
+ if (++i >= args.size())
+ return usage(args);
+ if (args[i] == QLatin1String("none"))
+ locations = Translator::NoLocations;
+ else if (args[i] == QLatin1String("relative"))
+ locations = Translator::RelativeLocations;
+ else if (args[i] == QLatin1String("absolute"))
+ locations = Translator::AbsoluteLocations;
+ else
+ return usage(args);
+ } else if (args[i] == QLatin1String("-no-ui-lines")) {
+ noUiLines = true;
+ } else if (args[i] == QLatin1String("-verbose")) {
+ verbose = true;
+ } else if (args[i].startsWith(QLatin1Char('-'))) {
+ return usage(args);
+ } else {
+ File file;
+ file.name = args[i];
+ file.format = inFormat;
+ inFiles.append(file);
+ }
+ }
+
+ if (inFiles.isEmpty())
+ return usage(args);
+
+ tr.setLanguageCode(Translator::guessLanguageCodeFromFileName(inFiles[0].name));
+
+ if (!tr.load(inFiles[0].name, cd, inFiles[0].format)) {
+ std::cerr << qPrintable(cd.error());
+ return 2;
+ }
+ tr.reportDuplicates(tr.resolveDuplicates(), inFiles[0].name, verbose);
+
+ for (int i = 1; i < inFiles.size(); ++i) {
+ Translator tr2;
+ if (!tr2.load(inFiles[i].name, cd, inFiles[i].format)) {
+ std::cerr << qPrintable(cd.error());
+ return 2;
+ }
+ tr2.reportDuplicates(tr2.resolveDuplicates(), inFiles[i].name, verbose);
+ for (int j = 0; j < tr2.messageCount(); ++j)
+ tr.replaceSorted(tr2.message(j));
+ }
+
+ if (!targetLanguage.isEmpty())
+ tr.setLanguageCode(targetLanguage);
+ if (!sourceLanguage.isEmpty())
+ tr.setSourceLanguageCode(sourceLanguage);
+ if (noObsolete)
+ tr.stripObsoleteMessages();
+ if (noFinished)
+ tr.stripFinishedMessages();
+ if (dropTranslations)
+ tr.dropTranslations();
+ if (noUiLines)
+ tr.dropUiLines();
+ if (locations != Translator::DefaultLocations)
+ tr.setLocationsType(locations);
+
+ tr.normalizeTranslations(cd);
+ if (!cd.errors().isEmpty()) {
+ std::cerr << qPrintable(cd.error());
+ cd.clearErrors();
+ }
+ if (!tr.save(outFileName, cd, outFormat)) {
+ std::cerr << qPrintable(cd.error());
+ return 3;
+ }
+ return 0;
+}
diff --git a/src/linguist/linguist.pro b/src/linguist/linguist.pro
new file mode 100644
index 000000000..248c89e2b
--- /dev/null
+++ b/src/linguist/linguist.pro
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+SUBDIRS = \
+ lrelease \
+ lupdate \
+ lconvert
+!no-png:!contains(QT_CONFIG, no-gui):SUBDIRS += linguist
diff --git a/src/linguist/linguist/Info_mac.plist b/src/linguist/linguist/Info_mac.plist
new file mode 100644
index 000000000..b11f493bd
--- /dev/null
+++ b/src/linguist/linguist/Info_mac.plist
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.1">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>linguist.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.trolltech.Linguist</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleExecutable</key>
+ <string>Linguist</string>
+</dict>
+</plist>
diff --git a/src/linguist/linguist/batchtranslation.ui b/src/linguist/linguist/batchtranslation.ui
new file mode 100644
index 000000000..659595622
--- /dev/null
+++ b/src/linguist/linguist/batchtranslation.ui
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>BatchTranslationDialog</class>
+ <widget class="QDialog" name="batchTranslationDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>437</width>
+ <height>492</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Qt Linguist - Batch Translation</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Options</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="ckMarkFinished">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Set translated entries to finished</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="ckTranslateTranslated">
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Retranslate entries with existing translation</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="ckTranslateFinished">
+ <property name="toolTip">
+ <string>Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked</string>
+ </property>
+ <property name="text">
+ <string>Translate also finished entries</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Phrase book preference</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QListView" name="phrasebookList">
+ <property name="uniformItemSizes">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="moveUpButton">
+ <property name="text">
+ <string>Move up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveDownButton">
+ <property name="text">
+ <string>Move down</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>The batch translator will search through the selected phrase books in the order given above</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="runButton">
+ <property name="text">
+ <string>&amp;Run</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>batchTranslationDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>388</x>
+ <y>461</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>188</x>
+ <y>465</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/linguist/linguist/batchtranslationdialog.cpp b/src/linguist/linguist/batchtranslationdialog.cpp
new file mode 100644
index 000000000..e58316ff0
--- /dev/null
+++ b/src/linguist/linguist/batchtranslationdialog.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "batchtranslationdialog.h"
+#include "phrase.h"
+#include "messagemodel.h"
+
+#include <QtGui/QMessageBox>
+#include <QtGui/QProgressDialog>
+
+QT_BEGIN_NAMESPACE
+
+CheckableListModel::CheckableListModel(QObject *parent)
+ : QStandardItemModel(parent)
+{
+}
+
+Qt::ItemFlags CheckableListModel::flags(const QModelIndex &index) const
+{
+ Q_UNUSED(index);
+ return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+BatchTranslationDialog::BatchTranslationDialog(MultiDataModel *dataModel, QWidget *w)
+ : QDialog(w), m_model(this), m_dataModel(dataModel)
+{
+ m_ui.setupUi(this);
+ connect(m_ui.runButton, SIGNAL(clicked()), this, SLOT(startTranslation()));
+ connect(m_ui.moveUpButton, SIGNAL(clicked()), this, SLOT(movePhraseBookUp()));
+ connect(m_ui.moveDownButton, SIGNAL(clicked()), this, SLOT(movePhraseBookDown()));
+
+ m_ui.phrasebookList->setModel(&m_model);
+ m_ui.phrasebookList->setSelectionBehavior(QAbstractItemView::SelectItems);
+ m_ui.phrasebookList->setSelectionMode(QAbstractItemView::SingleSelection);
+}
+
+
+void BatchTranslationDialog::setPhraseBooks(const QList<PhraseBook *> &phrasebooks, int modelIndex)
+{
+ QString fn = QFileInfo(m_dataModel->srcFileName(modelIndex)).baseName();
+ setWindowTitle(tr("Batch Translation of '%1' - Qt Linguist").arg(fn));
+ m_model.clear();
+ m_model.insertColumn(0);
+ m_phrasebooks = phrasebooks;
+ m_modelIndex = modelIndex;
+ int count = phrasebooks.count();
+ m_model.insertRows(0, count);
+ for (int i = 0; i < count; ++i) {
+ QModelIndex idx(m_model.index(i, 0));
+ m_model.setData(idx, phrasebooks[i]->friendlyPhraseBookName());
+ int sortOrder;
+ if (phrasebooks[i]->language() != QLocale::C
+ && m_dataModel->language(m_modelIndex) != QLocale::C) {
+ if (phrasebooks[i]->language() != m_dataModel->language(m_modelIndex))
+ sortOrder = 3;
+ else
+ sortOrder = (phrasebooks[i]->country()
+ == m_dataModel->model(m_modelIndex)->country()) ? 0 : 1;
+ } else {
+ sortOrder = 2;
+ }
+ m_model.setData(idx, sortOrder == 3 ? Qt::Unchecked : Qt::Checked, Qt::CheckStateRole);
+ m_model.setData(idx, sortOrder, Qt::UserRole + 1);
+ m_model.setData(idx, i, Qt::UserRole);
+ }
+ m_model.setSortRole(Qt::UserRole + 1);
+ m_model.sort(0);
+}
+
+void BatchTranslationDialog::startTranslation()
+{
+ int translatedcount = 0;
+ QCursor oldCursor = cursor();
+ setCursor(Qt::BusyCursor);
+ int messageCount = m_dataModel->messageCount();
+
+ QProgressDialog *dlgProgress;
+ dlgProgress = new QProgressDialog(tr("Searching, please wait..."), tr("&Cancel"), 0, messageCount, this);
+ dlgProgress->show();
+
+ int msgidx = 0;
+ const bool translateTranslated = m_ui.ckTranslateTranslated->isChecked();
+ const bool translateFinished = m_ui.ckTranslateFinished->isChecked();
+ for (MultiDataModelIterator it(m_dataModel, m_modelIndex); it.isValid(); ++it) {
+ if (MessageItem *m = it.current()) {
+ if (!m->isObsolete()
+ && (translateTranslated || m->translation().isEmpty())
+ && (translateFinished || !m->isFinished())) {
+
+ // Go through them in the order the user specified in the phrasebookList
+ for (int b = 0; b < m_model.rowCount(); ++b) {
+ QModelIndex idx(m_model.index(b, 0));
+ QVariant checkState = m_model.data(idx, Qt::CheckStateRole);
+ if (checkState == Qt::Checked) {
+ PhraseBook *pb = m_phrasebooks[m_model.data(idx, Qt::UserRole).toInt()];
+ foreach (const Phrase *ph, pb->phrases()) {
+ if (ph->source() == m->text()) {
+ m_dataModel->setTranslation(it, ph->target());
+ m_dataModel->setFinished(it, m_ui.ckMarkFinished->isChecked());
+ ++translatedcount;
+ goto done; // break 2;
+ }
+ }
+ }
+ }
+ }
+ }
+ done:
+ ++msgidx;
+ if (!(msgidx & 15))
+ dlgProgress->setValue(msgidx);
+ qApp->processEvents();
+ if (dlgProgress->wasCanceled())
+ break;
+ }
+ dlgProgress->hide();
+
+ setCursor(oldCursor);
+ emit finished();
+ QMessageBox::information(this, tr("Linguist batch translator"),
+ tr("Batch translated %n entries", "", translatedcount), QMessageBox::Ok);
+}
+
+void BatchTranslationDialog::movePhraseBookUp()
+{
+ QModelIndexList indexes = m_ui.phrasebookList->selectionModel()->selectedIndexes();
+ if (indexes.count() <= 0) return;
+
+ QModelIndex sel = indexes[0];
+ int row = sel.row();
+ if (row > 0) {
+ QModelIndex other = m_model.index(row - 1, 0);
+ QMap<int, QVariant> seldata = m_model.itemData(sel);
+ m_model.setItemData(sel, m_model.itemData(other));
+ m_model.setItemData(other, seldata);
+ m_ui.phrasebookList->selectionModel()->setCurrentIndex(other, QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+void BatchTranslationDialog::movePhraseBookDown()
+{
+ QModelIndexList indexes = m_ui.phrasebookList->selectionModel()->selectedIndexes();
+ if (indexes.count() <= 0) return;
+
+ QModelIndex sel = indexes[0];
+ int row = sel.row();
+ if (row < m_model.rowCount() - 1) {
+ QModelIndex other = m_model.index(row + 1, 0);
+ QMap<int, QVariant> seldata = m_model.itemData(sel);
+ m_model.setItemData(sel, m_model.itemData(other));
+ m_model.setItemData(other, seldata);
+ m_ui.phrasebookList->selectionModel()->setCurrentIndex(other, QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/batchtranslationdialog.h b/src/linguist/linguist/batchtranslationdialog.h
new file mode 100644
index 000000000..16d70cafe
--- /dev/null
+++ b/src/linguist/linguist/batchtranslationdialog.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BATCHTRANSLATIONDIALOG_H
+#define BATCHTRANSLATIONDIALOG_H
+
+#include "ui_batchtranslation.h"
+#include "phrase.h"
+
+#include <QtGui/QDialog>
+#include <QtGui/QStandardItemModel>
+
+QT_BEGIN_NAMESPACE
+
+class MultiDataModel;
+
+class CheckableListModel : public QStandardItemModel
+{
+public:
+ CheckableListModel(QObject *parent = 0);
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+};
+
+class BatchTranslationDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ BatchTranslationDialog(MultiDataModel *model, QWidget *w = 0);
+ void setPhraseBooks(const QList<PhraseBook *> &phrasebooks, int modelIndex);
+
+signals:
+ void finished();
+
+private slots:
+ void startTranslation();
+ void movePhraseBookUp();
+ void movePhraseBookDown();
+
+private:
+ Ui::BatchTranslationDialog m_ui;
+ CheckableListModel m_model;
+ MultiDataModel *m_dataModel;
+ QList<PhraseBook *> m_phrasebooks;
+ int m_modelIndex;
+};
+
+QT_END_NAMESPACE
+
+#endif // BATCHTRANSLATIONDIALOG_H
diff --git a/src/linguist/linguist/errorsview.cpp b/src/linguist/linguist/errorsview.cpp
new file mode 100644
index 000000000..f24b3bede
--- /dev/null
+++ b/src/linguist/linguist/errorsview.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "errorsview.h"
+
+#include "messagemodel.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+
+#include <QtGui/QListView>
+#include <QtGui/QStandardItem>
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QTextEdit>
+#include <QtGui/QVBoxLayout>
+
+QT_BEGIN_NAMESPACE
+
+ErrorsView::ErrorsView(MultiDataModel *dataModel, QWidget *parent) :
+ QListView(parent),
+ m_dataModel(dataModel)
+{
+ m_list = new QStandardItemModel(this);
+ setModel(m_list);
+}
+
+void ErrorsView::clear()
+{
+ m_list->clear();
+}
+
+void ErrorsView::addError(int model, const ErrorType type, const QString &arg)
+{
+ QString error;
+ switch (type) {
+ case SuperfluousAccelerator:
+ addError(model, tr("Accelerator possibly superfluous in translation."));
+ break;
+ case MissingAccelerator:
+ addError(model, tr("Accelerator possibly missing in translation."));
+ break;
+ case PunctuationDiffer:
+ addError(model, tr("Translation does not end with the same punctuation as the source text."));
+ break;
+ case IgnoredPhrasebook:
+ addError(model, tr("A phrase book suggestion for '%1' was ignored.").arg(arg));
+ break;
+ case PlaceMarkersDiffer:
+ addError(model, tr("Translation does not refer to the same place markers as in the source text."));
+ break;
+ case NumerusMarkerMissing:
+ addError(model, tr("Translation does not contain the necessary %n place marker."));
+ break;
+ default:
+ addError(model, tr("Unknown error"));
+ break;
+ }
+}
+
+QString ErrorsView::firstError()
+{
+ return (m_list->rowCount() == 0) ? QString() : m_list->item(0)->text();
+}
+
+void ErrorsView::addError(int model, const QString &error)
+{
+ // NOTE: Three statics instead of one just for GCC 3.3.5
+ static QLatin1String imageLocation(":/images/s_check_danger.png");
+ static QPixmap image(imageLocation);
+ static QIcon pxDanger(image);
+ QString lang;
+ if (m_dataModel->modelCount() > 1)
+ lang = m_dataModel->model(model)->localizedLanguage() + QLatin1String(": ");
+ QStandardItem *item = new QStandardItem(pxDanger, lang + error);
+ item->setEditable(false);
+ m_list->appendRow(QList<QStandardItem*>() << item);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/errorsview.h b/src/linguist/linguist/errorsview.h
new file mode 100644
index 000000000..a7a7dc1b7
--- /dev/null
+++ b/src/linguist/linguist/errorsview.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ERRORSVIEW_H
+#define ERRORSVIEW_H
+
+#include <QListView>
+
+QT_BEGIN_NAMESPACE
+
+class QStandardItemModel;
+
+class MultiDataModel;
+
+class ErrorsView : public QListView
+{
+ Q_OBJECT
+public:
+ enum ErrorType {
+ SuperfluousAccelerator,
+ MissingAccelerator,
+ PunctuationDiffer,
+ IgnoredPhrasebook,
+ PlaceMarkersDiffer,
+ NumerusMarkerMissing
+ };
+
+ ErrorsView(MultiDataModel *dataModel, QWidget *parent = 0);
+ void clear();
+ void addError(int model, const ErrorType type, const QString &arg = QString());
+ QString firstError();
+private:
+ void addError(int model, const QString &error);
+ QStandardItemModel *m_list;
+ MultiDataModel *m_dataModel;
+};
+
+QT_END_NAMESPACE
+
+#endif // ERRORSVIEW_H
diff --git a/src/linguist/linguist/finddialog.cpp b/src/linguist/linguist/finddialog.cpp
new file mode 100644
index 000000000..f05b710aa
--- /dev/null
+++ b/src/linguist/linguist/finddialog.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* TRANSLATOR FindDialog
+
+ Choose Edit|Find from the menu bar or press Ctrl+F to pop up the
+ Find dialog
+*/
+
+#include "finddialog.h"
+
+QT_BEGIN_NAMESPACE
+
+FindDialog::FindDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ setupUi(this);
+
+ findNxt->setEnabled(false);
+
+ connect(findNxt, SIGNAL(clicked()), this, SLOT(emitFindNext()));
+ connect(led, SIGNAL(textChanged(QString)), this, SLOT(verifyText(QString)));
+
+ led->setFocus();
+}
+
+void FindDialog::verifyText(const QString &text)
+{
+ findNxt->setEnabled(!text.isEmpty());
+}
+
+void FindDialog::emitFindNext()
+{
+ DataModel::FindLocation where;
+ if (sourceText != 0)
+ where =
+ DataModel::FindLocation(
+ (sourceText->isChecked() ? DataModel::SourceText : 0) |
+ (translations->isChecked() ? DataModel::Translations : 0) |
+ (comments->isChecked() ? DataModel::Comments : 0));
+ else
+ where = DataModel::Translations;
+ emit findNext(led->text(), where, matchCase->isChecked(), ignoreAccelerators->isChecked());
+ led->selectAll();
+}
+
+void FindDialog::find()
+{
+ led->setFocus();
+
+ show();
+ activateWindow();
+ raise();
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/finddialog.h b/src/linguist/linguist/finddialog.h
new file mode 100644
index 000000000..afacd5b7d
--- /dev/null
+++ b/src/linguist/linguist/finddialog.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FINDDIALOG_H
+#define FINDDIALOG_H
+
+#include "ui_finddialog.h"
+#include "messagemodel.h"
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class FindDialog : public QDialog, public Ui::FindDialog
+{
+ Q_OBJECT
+public:
+ FindDialog(QWidget *parent = 0);
+
+signals:
+ void findNext(const QString& text, DataModel::FindLocation where, bool matchCase, bool ignoreAccelerators);
+
+private slots:
+ void emitFindNext();
+ void verifyText(const QString &);
+ void find();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/linguist/linguist/finddialog.ui b/src/linguist/linguist/finddialog.ui
new file mode 100644
index 000000000..2ecb110d7
--- /dev/null
+++ b/src/linguist/linguist/finddialog.ui
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>FindDialog</class>
+ <widget class="QDialog" name="FindDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>414</width>
+ <height>175</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Find</string>
+ </property>
+ <property name="whatsThis">
+ <string>This window allows you to search for some text in the translation source file.</string>
+ </property>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="findWhat">
+ <property name="text">
+ <string>&amp;Find what:</string>
+ </property>
+ <property name="buddy">
+ <cstring>led</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="led">
+ <property name="whatsThis">
+ <string>Type in the text to search for.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Options</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="sourceText">
+ <property name="whatsThis">
+ <string>Source texts are searched when checked.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Source texts</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="translations">
+ <property name="whatsThis">
+ <string>Translations are searched when checked.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Translations</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="matchCase">
+ <property name="whatsThis">
+ <string>Texts such as 'TeX' and 'tex' are considered as different when checked.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Match case</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="comments">
+ <property name="whatsThis">
+ <string>Comments and contexts are searched when checked.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Comments</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="ignoreAccelerators">
+ <property name="text">
+ <string>Ignore &amp;accelerators</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="findNxt">
+ <property name="whatsThis">
+ <string>Click here to find the next occurrence of the text you typed in.</string>
+ </property>
+ <property name="text">
+ <string>Find Next</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancel">
+ <property name="whatsThis">
+ <string>Click here to close this window.</string>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>51</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>led</tabstop>
+ <tabstop>findNxt</tabstop>
+ <tabstop>cancel</tabstop>
+ <tabstop>comments</tabstop>
+ <tabstop>sourceText</tabstop>
+ <tabstop>translations</tabstop>
+ <tabstop>matchCase</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>cancel</sender>
+ <signal>clicked()</signal>
+ <receiver>FindDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>372</x>
+ <y>58</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>373</x>
+ <y>109</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/linguist/linguist/formpreviewview.cpp b/src/linguist/linguist/formpreviewview.cpp
new file mode 100644
index 000000000..a2a600257
--- /dev/null
+++ b/src/linguist/linguist/formpreviewview.cpp
@@ -0,0 +1,537 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "formpreviewview.h"
+#include "messagemodel.h"
+
+#include <quiloader.h>
+#include <abstractformbuilder.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QTime>
+
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QFontComboBox>
+#include <QtGui/QFrame>
+#include <QtGui/QGridLayout>
+#include <QtGui/QListWidget>
+#include <QtGui/QMdiArea>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QMenu>
+#include <QtGui/QTableWidget>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QTreeWidget>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_CC_SUN) || defined(Q_CC_HPACC) || defined(Q_CC_XLC)
+int qHash(const QUiTranslatableStringValue &tsv)
+#else
+static int qHash(const QUiTranslatableStringValue &tsv)
+#endif
+{
+ return qHash(tsv.value()) ^ qHash(tsv.comment());
+}
+
+static bool operator==(const QUiTranslatableStringValue &tsv1, const QUiTranslatableStringValue &tsv2)
+{
+ return tsv1.value() == tsv2.value() && tsv1.comment() == tsv2.comment();
+}
+
+#define INSERT_TARGET(_tsv, _type, _target, _prop) \
+ do { \
+ target.type = _type; \
+ target.target._target; \
+ target.prop._prop; \
+ (*targets)[qvariant_cast<QUiTranslatableStringValue>(_tsv)].append(target); \
+ } while (0)
+
+static void registerTreeItem(QTreeWidgetItem *item, TargetsHash *targets)
+{
+ const QUiItemRolePair *irs = QFormInternal::qUiItemRoles;
+
+ int cnt = item->columnCount();
+ for (int i = 0; i < cnt; ++i) {
+ for (unsigned j = 0; irs[j].shadowRole >= 0; j++) {
+ QVariant v = item->data(i, irs[j].shadowRole);
+ if (v.isValid()) {
+ TranslatableEntry target;
+ target.prop.treeIndex.column = i;
+ INSERT_TARGET(v, TranslatableTreeWidgetItem, treeWidgetItem = item, treeIndex.index = j);
+ }
+ }
+ }
+
+ cnt = item->childCount();
+ for (int j = 0; j < cnt; ++j)
+ registerTreeItem(item->child(j), targets);
+}
+
+#define REGISTER_ITEM_CORE(item, propType, targetName) \
+ const QUiItemRolePair *irs = QFormInternal::qUiItemRoles; \
+ for (unsigned j = 0; irs[j].shadowRole >= 0; j++) { \
+ QVariant v = item->data(irs[j].shadowRole); \
+ if (v.isValid()) \
+ INSERT_TARGET(v, propType, targetName = item, index = j); \
+ }
+
+static void registerListItem(QListWidgetItem *item, TargetsHash *targets)
+{
+ TranslatableEntry target;
+ REGISTER_ITEM_CORE(item, TranslatableListWidgetItem, listWidgetItem);
+}
+
+static void registerTableItem(QTableWidgetItem *item, TargetsHash *targets)
+{
+ if (!item)
+ return;
+
+ TranslatableEntry target;
+ REGISTER_ITEM_CORE(item, TranslatableTableWidgetItem, tableWidgetItem);
+}
+
+#define REGISTER_SUBWIDGET_PROP(mainWidget, propType, propName) \
+ do { \
+ QVariant v = mainWidget->widget(i)->property(propName); \
+ if (v.isValid()) \
+ INSERT_TARGET(v, propType, object = mainWidget, index = i); \
+ } while (0)
+
+static void buildTargets(QObject *o, TargetsHash *targets)
+{
+ TranslatableEntry target;
+
+ foreach (const QByteArray &prop, o->dynamicPropertyNames()) {
+ if (prop.startsWith(PROP_GENERIC_PREFIX)) {
+ const QByteArray propName = prop.mid(sizeof(PROP_GENERIC_PREFIX) - 1);
+ INSERT_TARGET(o->property(prop),
+ TranslatableProperty, object = o, name = qstrdup(propName.data()));
+ }
+ }
+ if (0) {
+#ifndef QT_NO_TABWIDGET
+ } else if (QTabWidget *tabw = qobject_cast<QTabWidget*>(o)) {
+ const int cnt = tabw->count();
+ for (int i = 0; i < cnt; ++i) {
+ REGISTER_SUBWIDGET_PROP(tabw, TranslatableTabPageText, PROP_TABPAGETEXT);
+# ifndef QT_NO_TOOLTIP
+ REGISTER_SUBWIDGET_PROP(tabw, TranslatableTabPageToolTip, PROP_TABPAGETOOLTIP);
+# endif
+# ifndef QT_NO_WHATSTHIS
+ REGISTER_SUBWIDGET_PROP(tabw, TranslatableTabPageWhatsThis, PROP_TABPAGEWHATSTHIS);
+# endif
+ }
+#endif
+#ifndef QT_NO_TOOLBOX
+ } else if (QToolBox *toolw = qobject_cast<QToolBox*>(o)) {
+ const int cnt = toolw->count();
+ for (int i = 0; i < cnt; ++i) {
+ REGISTER_SUBWIDGET_PROP(toolw, TranslatableToolItemText, PROP_TOOLITEMTEXT);
+# ifndef QT_NO_TOOLTIP
+ REGISTER_SUBWIDGET_PROP(toolw, TranslatableToolItemToolTip, PROP_TOOLITEMTOOLTIP);
+# endif
+ }
+#endif
+#ifndef QT_NO_COMBOBOX
+ } else if (QComboBox *combow = qobject_cast<QComboBox*>(o)) {
+ if (!qobject_cast<QFontComboBox*>(o)) {
+ const int cnt = combow->count();
+ for (int i = 0; i < cnt; ++i) {
+ const QVariant v = combow->itemData(i, Qt::DisplayPropertyRole);
+ if (v.isValid())
+ INSERT_TARGET(v, TranslatableComboBoxItem, comboBox = combow, index = i);
+ }
+ }
+#endif
+#ifndef QT_NO_LISTWIDGET
+ } else if (QListWidget *listw = qobject_cast<QListWidget*>(o)) {
+ const int cnt = listw->count();
+ for (int i = 0; i < cnt; ++i)
+ registerListItem(listw->item(i), targets);
+#endif
+#ifndef QT_NO_TABLEWIDGET
+ } else if (QTableWidget *tablew = qobject_cast<QTableWidget*>(o)) {
+ const int row_cnt = tablew->rowCount();
+ const int col_cnt = tablew->columnCount();
+ for (int j = 0; j < col_cnt; ++j)
+ registerTableItem(tablew->verticalHeaderItem(j), targets);
+ for (int i = 0; i < row_cnt; ++i) {
+ registerTableItem(tablew->horizontalHeaderItem(i), targets);
+ for (int j = 0; j < col_cnt; ++j)
+ registerTableItem(tablew->item(i, j), targets);
+ }
+#endif
+#ifndef QT_NO_TREEWIDGET
+ } else if (QTreeWidget *treew = qobject_cast<QTreeWidget*>(o)) {
+ if (QTreeWidgetItem *item = treew->headerItem())
+ registerTreeItem(item, targets);
+ const int cnt = treew->topLevelItemCount();
+ for (int i = 0; i < cnt; ++i)
+ registerTreeItem(treew->topLevelItem(i), targets);
+#endif
+ }
+ foreach (QObject *co, o->children())
+ buildTargets(co, targets);
+}
+
+static void destroyTargets(TargetsHash *targets)
+{
+ for (TargetsHash::Iterator it = targets->begin(), end = targets->end(); it != end; ++it)
+ foreach (const TranslatableEntry &target, *it)
+ if (target.type == TranslatableProperty)
+ delete target.prop.name;
+ targets->clear();
+}
+
+static void retranslateTarget(const TranslatableEntry &target, const QString &text)
+{
+ switch (target.type) {
+ case TranslatableProperty:
+ target.target.object->setProperty(target.prop.name, text);
+ break;
+#ifndef QT_NO_TABWIDGET
+ case TranslatableTabPageText:
+ target.target.tabWidget->setTabText(target.prop.index, text);
+ break;
+# ifndef QT_NO_TOOLTIP
+ case TranslatableTabPageToolTip:
+ target.target.tabWidget->setTabToolTip(target.prop.index, text);
+ break;
+# endif
+# ifndef QT_NO_WHATSTHIS
+ case TranslatableTabPageWhatsThis:
+ target.target.tabWidget->setTabWhatsThis(target.prop.index, text);
+ break;
+# endif
+#endif // QT_NO_TABWIDGET
+#ifndef QT_NO_TOOLBOX
+ case TranslatableToolItemText:
+ target.target.toolBox->setItemText(target.prop.index, text);
+ break;
+# ifndef QT_NO_TOOLTIP
+ case TranslatableToolItemToolTip:
+ target.target.toolBox->setItemToolTip(target.prop.index, text);
+ break;
+# endif
+#endif // QT_NO_TOOLBOX
+#ifndef QT_NO_COMBOBOX
+ case TranslatableComboBoxItem:
+ target.target.comboBox->setItemText(target.prop.index, text);
+ break;
+#endif
+#ifndef QT_NO_LISTWIDGET
+ case TranslatableListWidgetItem:
+ target.target.listWidgetItem->setData(target.prop.index, text);
+ break;
+#endif
+#ifndef QT_NO_TABLEWIDGET
+ case TranslatableTableWidgetItem:
+ target.target.tableWidgetItem->setData(target.prop.index, text);
+ break;
+#endif
+#ifndef QT_NO_TREEWIDGET
+ case TranslatableTreeWidgetItem:
+ target.target.treeWidgetItem->setData(target.prop.treeIndex.column, target.prop.treeIndex.index, text);
+ break;
+#endif
+ }
+}
+
+static void retranslateTargets(
+ const QList<TranslatableEntry> &targets, const QUiTranslatableStringValue &tsv,
+ const DataModel *dataModel, const QString &className)
+{
+ QString sourceText = QString::fromUtf8(tsv.value());
+ QString text;
+ if (MessageItem *msg = dataModel->findMessage(
+ className, sourceText, QString::fromUtf8(tsv.comment())))
+ text = msg->translation();
+ if (text.isEmpty() && !tsv.value().isEmpty())
+ text = QLatin1Char('#') + sourceText;
+
+ foreach (const TranslatableEntry &target, targets)
+ retranslateTarget(target, text);
+}
+
+static void highlightTreeWidgetItem(QTreeWidgetItem *item, int col, bool on)
+{
+ QVariant br = item->data(col, Qt::BackgroundRole + 500);
+ QVariant fr = item->data(col, Qt::ForegroundRole + 500);
+ if (on) {
+ if (!br.isValid() && !fr.isValid()) {
+ item->setData(col, Qt::BackgroundRole + 500, item->data(col, Qt::BackgroundRole));
+ item->setData(col, Qt::ForegroundRole + 500, item->data(col, Qt::ForegroundRole));
+ QPalette pal = qApp->palette();
+ item->setData(col, Qt::BackgroundRole, pal.color(QPalette::Dark));
+ item->setData(col, Qt::ForegroundRole, pal.color(QPalette::Light));
+ }
+ } else {
+ if (br.isValid() || fr.isValid()) {
+ item->setData(col, Qt::BackgroundRole, br);
+ item->setData(col, Qt::ForegroundRole, fr);
+ item->setData(col, Qt::BackgroundRole + 500, QVariant());
+ item->setData(col, Qt::ForegroundRole + 500, QVariant());
+ }
+ }
+}
+
+template <class T>
+static void highlightWidgetItem(T *item, bool on)
+{
+ QVariant br = item->data(Qt::BackgroundRole + 500);
+ QVariant fr = item->data(Qt::ForegroundRole + 500);
+ if (on) {
+ if (!br.isValid() && !fr.isValid()) {
+ item->setData(Qt::BackgroundRole + 500, item->data(Qt::BackgroundRole));
+ item->setData(Qt::ForegroundRole + 500, item->data(Qt::ForegroundRole));
+ QPalette pal = qApp->palette();
+ item->setData(Qt::BackgroundRole, pal.color(QPalette::Dark));
+ item->setData(Qt::ForegroundRole, pal.color(QPalette::Light));
+ }
+ } else {
+ if (br.isValid() || fr.isValid()) {
+ item->setData(Qt::BackgroundRole, br);
+ item->setData(Qt::ForegroundRole, fr);
+ item->setData(Qt::BackgroundRole + 500, QVariant());
+ item->setData(Qt::ForegroundRole + 500, QVariant());
+ }
+ }
+}
+
+#define AUTOFILL_BACKUP_PROP "_q_linguist_autoFillBackup"
+#define PALETTE_BACKUP_PROP "_q_linguist_paletteBackup"
+#define FONT_BACKUP_PROP "_q_linguist_fontBackup"
+
+static void highlightWidget(QWidget *w, bool on);
+
+static void highlightAction(QAction *a, bool on)
+{
+ QVariant bak = a->property(FONT_BACKUP_PROP);
+ if (on) {
+ if (!bak.isValid()) {
+ QFont fnt = qApp->font();
+ a->setProperty(FONT_BACKUP_PROP, QVariant::fromValue(a->font().resolve(fnt)));
+ fnt.setBold(true);
+ fnt.setItalic(true);
+ a->setFont(fnt);
+ }
+ } else {
+ if (bak.isValid()) {
+ a->setFont(qvariant_cast<QFont>(bak));
+ a->setProperty(FONT_BACKUP_PROP, QVariant());
+ }
+ }
+ foreach (QWidget *w, a->associatedWidgets())
+ highlightWidget(w, on);
+}
+
+static void highlightWidget(QWidget *w, bool on)
+{
+ QVariant bak = w->property(PALETTE_BACKUP_PROP);
+ if (on) {
+ if (!bak.isValid()) {
+ QPalette pal = qApp->palette();
+ foreach (QObject *co, w->children())
+ if (QWidget *cw = qobject_cast<QWidget *>(co))
+ cw->setPalette(cw->palette().resolve(pal));
+ w->setProperty(PALETTE_BACKUP_PROP, QVariant::fromValue(w->palette().resolve(pal)));
+ w->setProperty(AUTOFILL_BACKUP_PROP, QVariant::fromValue(w->autoFillBackground()));
+ QColor col1 = pal.color(QPalette::Dark);
+ QColor col2 = pal.color(QPalette::Light);
+ pal.setColor(QPalette::Base, col1);
+ pal.setColor(QPalette::Window, col1);
+ pal.setColor(QPalette::Button, col1);
+ pal.setColor(QPalette::Text, col2);
+ pal.setColor(QPalette::WindowText, col2);
+ pal.setColor(QPalette::ButtonText, col2);
+ pal.setColor(QPalette::BrightText, col2);
+ w->setPalette(pal);
+ w->setAutoFillBackground(true);
+ }
+ } else {
+ if (bak.isValid()) {
+ w->setPalette(qvariant_cast<QPalette>(bak));
+ w->setAutoFillBackground(qvariant_cast<bool>(w->property(AUTOFILL_BACKUP_PROP)));
+ w->setProperty(PALETTE_BACKUP_PROP, QVariant());
+ w->setProperty(AUTOFILL_BACKUP_PROP, QVariant());
+ }
+ }
+ if (QMenu *m = qobject_cast<QMenu *>(w))
+ if (m->menuAction())
+ highlightAction(m->menuAction(), on);
+}
+
+static void highlightTarget(const TranslatableEntry &target, bool on)
+{
+ switch (target.type) {
+ case TranslatableProperty:
+ if (QAction *a = qobject_cast<QAction *>(target.target.object)) {
+ highlightAction(a, on);
+ break;
+ }
+ // fallthrough
+#ifndef QT_NO_TABWIDGET
+ case TranslatableTabPageText:
+# ifndef QT_NO_TOOLTIP
+ case TranslatableTabPageToolTip:
+# endif
+# ifndef QT_NO_WHATSTHIS
+ case TranslatableTabPageWhatsThis:
+# endif
+#endif // QT_NO_TABWIDGET
+#ifndef QT_NO_TOOLBOX
+ case TranslatableToolItemText:
+# ifndef QT_NO_TOOLTIP
+ case TranslatableToolItemToolTip:
+# endif
+#endif // QT_NO_TOOLBOX
+#ifndef QT_NO_COMBOBOX
+ case TranslatableComboBoxItem:
+#endif
+ if (QWidget *w = qobject_cast<QWidget *>(target.target.object))
+ highlightWidget(w, on);
+ break;
+#ifndef QT_NO_LISTWIDGET
+ case TranslatableListWidgetItem:
+ highlightWidgetItem(target.target.listWidgetItem, on);
+ break;
+#endif
+#ifndef QT_NO_TABLEWIDGET
+ case TranslatableTableWidgetItem:
+ highlightWidgetItem(target.target.tableWidgetItem, on);
+ break;
+#endif
+#ifndef QT_NO_TREEWIDGET
+ case TranslatableTreeWidgetItem:
+ highlightTreeWidgetItem(target.target.treeWidgetItem, target.prop.treeIndex.column, on);
+ break;
+#endif
+ }
+}
+
+static void highlightTargets(const QList<TranslatableEntry> &targets, bool on)
+{
+ foreach (const TranslatableEntry &target, targets)
+ highlightTarget(target, on);
+}
+
+FormPreviewView::FormPreviewView(QWidget *parent, MultiDataModel *dataModel)
+ : QMainWindow(parent), m_form(0), m_dataModel(dataModel)
+{
+ m_mdiSubWindow = new QMdiSubWindow;
+ m_mdiSubWindow->setWindowFlags(m_mdiSubWindow->windowFlags() & ~Qt::WindowSystemMenuHint);
+ m_mdiArea = new QMdiArea(this);
+ m_mdiArea->addSubWindow(m_mdiSubWindow);
+ setCentralWidget(m_mdiArea);
+ m_mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ m_mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+}
+
+void FormPreviewView::setSourceContext(int model, MessageItem *messageItem)
+{
+ if (model < 0 || !messageItem) {
+ m_lastModel = -1;
+ return;
+ }
+
+ QDir dir = QFileInfo(m_dataModel->srcFileName(model)).dir();
+ QString fileName = QDir::cleanPath(dir.absoluteFilePath(messageItem->fileName()));
+ if (m_lastFormName != fileName) {
+ delete m_form;
+ m_form = 0;
+ m_lastFormName.clear();
+ m_highlights.clear();
+ destroyTargets(&m_targets);
+
+ static QUiLoader *uiLoader;
+ if (!uiLoader) {
+ uiLoader = new QUiLoader(this);
+ uiLoader->setLanguageChangeEnabled(true);
+ uiLoader->setTranslationEnabled(false);
+ }
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ qDebug() << "CANNOT OPEN FORM" << fileName;
+ m_mdiSubWindow->hide();
+ return;
+ }
+ m_form = uiLoader->load(&file, m_mdiSubWindow);
+ if (!m_form) {
+ qDebug() << "CANNOT LOAD FORM" << fileName;
+ m_mdiSubWindow->hide();
+ return;
+ }
+ file.close();
+ buildTargets(m_form, &m_targets);
+
+ setToolTip(fileName);
+
+ m_form->setWindowFlags(Qt::Widget);
+ m_form->setWindowModality(Qt::NonModal);
+ m_form->setFocusPolicy(Qt::NoFocus);
+ m_form->show(); // needed, otherwide the Qt::NoFocus is not propagated.
+ m_mdiSubWindow->setWidget(m_form);
+ m_mdiSubWindow->show();
+ m_mdiArea->cascadeSubWindows();
+ m_lastFormName = fileName;
+ m_lastClassName = messageItem->context();
+ m_lastModel = -1;
+ } else {
+ highlightTargets(m_highlights, false);
+ }
+ QUiTranslatableStringValue tsv;
+ tsv.setValue(messageItem->text().toUtf8());
+ tsv.setComment(messageItem->comment().toUtf8());
+ m_highlights = m_targets.value(tsv);
+ if (m_lastModel != model) {
+ for (TargetsHash::Iterator it = m_targets.begin(), end = m_targets.end(); it != end; ++it)
+ retranslateTargets(*it, it.key(), m_dataModel->model(model), m_lastClassName);
+ m_lastModel = model;
+ } else {
+ retranslateTargets(m_highlights, tsv, m_dataModel->model(model), m_lastClassName);
+ }
+ highlightTargets(m_highlights, true);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/formpreviewview.h b/src/linguist/linguist/formpreviewview.h
new file mode 100644
index 000000000..e30160670
--- /dev/null
+++ b/src/linguist/linguist/formpreviewview.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FORMPREVIEWVIEW_H
+#define FORMPREVIEWVIEW_H
+
+#include <quiloader_p.h>
+
+#include <QtCore/QHash>
+#include <QtCore/QList>
+
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+class MultiDataModel;
+class FormFrame;
+class MessageItem;
+
+class QComboBox;
+class QListWidgetItem;
+class QGridLayout;
+class QMdiArea;
+class QMdiSubWindow;
+class QToolBox;
+class QTableWidgetItem;
+class QTreeWidgetItem;
+
+enum TranslatableEntryType {
+ TranslatableProperty,
+ TranslatableToolItemText,
+ TranslatableToolItemToolTip,
+ TranslatableTabPageText,
+ TranslatableTabPageToolTip,
+ TranslatableTabPageWhatsThis,
+ TranslatableListWidgetItem,
+ TranslatableTableWidgetItem,
+ TranslatableTreeWidgetItem,
+ TranslatableComboBoxItem
+};
+
+struct TranslatableEntry {
+ TranslatableEntryType type;
+ union {
+ QObject *object;
+ QComboBox *comboBox;
+ QTabWidget *tabWidget;
+ QToolBox *toolBox;
+ QListWidgetItem *listWidgetItem;
+ QTableWidgetItem *tableWidgetItem;
+ QTreeWidgetItem *treeWidgetItem;
+ } target;
+ union {
+ char *name;
+ int index;
+ struct {
+ short index; // Known to be below 1000
+ short column;
+ } treeIndex;
+ } prop;
+};
+
+typedef QHash<QUiTranslatableStringValue, QList<TranslatableEntry> > TargetsHash;
+
+class FormPreviewView : public QMainWindow
+{
+ Q_OBJECT
+public:
+ FormPreviewView(QWidget *parent, MultiDataModel *dataModel);
+
+ void setSourceContext(int model, MessageItem *messageItem);
+
+private:
+ bool m_isActive;
+ QString m_currentFileName;
+ QMdiArea *m_mdiArea;
+ QMdiSubWindow *m_mdiSubWindow;
+ QWidget *m_form;
+ TargetsHash m_targets;
+ QList<TranslatableEntry> m_highlights;
+ MultiDataModel *m_dataModel;
+
+ QString m_lastFormName;
+ QString m_lastClassName;
+ int m_lastModel;
+};
+
+QT_END_NAMESPACE
+
+#endif // FORMPREVIEWVIEW_H
diff --git a/src/linguist/linguist/globals.cpp b/src/linguist/linguist/globals.cpp
new file mode 100644
index 000000000..f2a8cd248
--- /dev/null
+++ b/src/linguist/linguist/globals.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "globals.h"
+
+const QString &settingsPrefix()
+{
+ static QString prefix = QString(QLatin1String("%1.%2/"))
+ .arg((QT_VERSION >> 16) & 0xff)
+ .arg((QT_VERSION >> 8) & 0xff);
+ return prefix;
+}
+
+QString settingPath(const char *path)
+{
+ return settingsPrefix() + QLatin1String(path);
+}
diff --git a/src/linguist/linguist/globals.h b/src/linguist/linguist/globals.h
new file mode 100644
index 000000000..7d82f5b59
--- /dev/null
+++ b/src/linguist/linguist/globals.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include <QString>
+
+const QString &settingsPrefix();
+QString settingPath(const char *path);
+
+#endif // GLOBALS_H
diff --git a/src/linguist/linguist/images/appicon.png b/src/linguist/linguist/images/appicon.png
new file mode 100644
index 000000000..d388cbd0b
--- /dev/null
+++ b/src/linguist/linguist/images/appicon.png
Binary files differ
diff --git a/src/linguist/linguist/images/down.png b/src/linguist/linguist/images/down.png
new file mode 100644
index 000000000..29d1d4439
--- /dev/null
+++ b/src/linguist/linguist/images/down.png
Binary files differ
diff --git a/src/linguist/linguist/images/editdelete.png b/src/linguist/linguist/images/editdelete.png
new file mode 100644
index 000000000..df2a147d2
--- /dev/null
+++ b/src/linguist/linguist/images/editdelete.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-128-32.png b/src/linguist/linguist/images/icons/linguist-128-32.png
new file mode 100644
index 000000000..d108208fa
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-128-32.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-128-8.png b/src/linguist/linguist/images/icons/linguist-128-8.png
new file mode 100644
index 000000000..6678dd2ae
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-128-8.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-16-32.png b/src/linguist/linguist/images/icons/linguist-16-32.png
new file mode 100644
index 000000000..8dfc97406
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-16-32.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-16-8.png b/src/linguist/linguist/images/icons/linguist-16-8.png
new file mode 100644
index 000000000..4f4e83955
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-16-8.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-32-32.png b/src/linguist/linguist/images/icons/linguist-32-32.png
new file mode 100644
index 000000000..d388cbd0b
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-32-32.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-32-8.png b/src/linguist/linguist/images/icons/linguist-32-8.png
new file mode 100644
index 000000000..3db4bc5c0
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-32-8.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-48-32.png b/src/linguist/linguist/images/icons/linguist-48-32.png
new file mode 100644
index 000000000..ceb738759
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-48-32.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-48-8.png b/src/linguist/linguist/images/icons/linguist-48-8.png
new file mode 100644
index 000000000..9a13c201d
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-48-8.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-64-32.png b/src/linguist/linguist/images/icons/linguist-64-32.png
new file mode 100644
index 000000000..0cce805e3
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-64-32.png
Binary files differ
diff --git a/src/linguist/linguist/images/icons/linguist-64-8.png b/src/linguist/linguist/images/icons/linguist-64-8.png
new file mode 100644
index 000000000..05c833dc9
--- /dev/null
+++ b/src/linguist/linguist/images/icons/linguist-64-8.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/accelerator.png b/src/linguist/linguist/images/mac/accelerator.png
new file mode 100644
index 000000000..9a684c104
--- /dev/null
+++ b/src/linguist/linguist/images/mac/accelerator.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/book.png b/src/linguist/linguist/images/mac/book.png
new file mode 100644
index 000000000..7a3204c87
--- /dev/null
+++ b/src/linguist/linguist/images/mac/book.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/doneandnext.png b/src/linguist/linguist/images/mac/doneandnext.png
new file mode 100644
index 000000000..512fea884
--- /dev/null
+++ b/src/linguist/linguist/images/mac/doneandnext.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/editcopy.png b/src/linguist/linguist/images/mac/editcopy.png
new file mode 100644
index 000000000..f55136446
--- /dev/null
+++ b/src/linguist/linguist/images/mac/editcopy.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/editcut.png b/src/linguist/linguist/images/mac/editcut.png
new file mode 100644
index 000000000..a784fd570
--- /dev/null
+++ b/src/linguist/linguist/images/mac/editcut.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/editpaste.png b/src/linguist/linguist/images/mac/editpaste.png
new file mode 100644
index 000000000..64c0b2d6a
--- /dev/null
+++ b/src/linguist/linguist/images/mac/editpaste.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/filenew.png b/src/linguist/linguist/images/mac/filenew.png
new file mode 100644
index 000000000..d3882c7b3
--- /dev/null
+++ b/src/linguist/linguist/images/mac/filenew.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/fileopen.png b/src/linguist/linguist/images/mac/fileopen.png
new file mode 100644
index 000000000..fc06c5ec6
--- /dev/null
+++ b/src/linguist/linguist/images/mac/fileopen.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/fileprint.png b/src/linguist/linguist/images/mac/fileprint.png
new file mode 100644
index 000000000..808c97ea3
--- /dev/null
+++ b/src/linguist/linguist/images/mac/fileprint.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/filesave.png b/src/linguist/linguist/images/mac/filesave.png
new file mode 100644
index 000000000..b41ecf531
--- /dev/null
+++ b/src/linguist/linguist/images/mac/filesave.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/next.png b/src/linguist/linguist/images/mac/next.png
new file mode 100644
index 000000000..ba0792c36
--- /dev/null
+++ b/src/linguist/linguist/images/mac/next.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/nextunfinished.png b/src/linguist/linguist/images/mac/nextunfinished.png
new file mode 100644
index 000000000..bffbf0bb1
--- /dev/null
+++ b/src/linguist/linguist/images/mac/nextunfinished.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/phrase.png b/src/linguist/linguist/images/mac/phrase.png
new file mode 100644
index 000000000..651234109
--- /dev/null
+++ b/src/linguist/linguist/images/mac/phrase.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/prev.png b/src/linguist/linguist/images/mac/prev.png
new file mode 100644
index 000000000..612fb34dc
--- /dev/null
+++ b/src/linguist/linguist/images/mac/prev.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/prevunfinished.png b/src/linguist/linguist/images/mac/prevunfinished.png
new file mode 100644
index 000000000..4d937b2a2
--- /dev/null
+++ b/src/linguist/linguist/images/mac/prevunfinished.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/print.png b/src/linguist/linguist/images/mac/print.png
new file mode 100644
index 000000000..10ca56c82
--- /dev/null
+++ b/src/linguist/linguist/images/mac/print.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/punctuation.png b/src/linguist/linguist/images/mac/punctuation.png
new file mode 100644
index 000000000..4719fc68f
--- /dev/null
+++ b/src/linguist/linguist/images/mac/punctuation.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/redo.png b/src/linguist/linguist/images/mac/redo.png
new file mode 100644
index 000000000..8875bf246
--- /dev/null
+++ b/src/linguist/linguist/images/mac/redo.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/searchfind.png b/src/linguist/linguist/images/mac/searchfind.png
new file mode 100644
index 000000000..3561745f0
--- /dev/null
+++ b/src/linguist/linguist/images/mac/searchfind.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/undo.png b/src/linguist/linguist/images/mac/undo.png
new file mode 100644
index 000000000..a3bd5e0bf
--- /dev/null
+++ b/src/linguist/linguist/images/mac/undo.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/validateplacemarkers.png b/src/linguist/linguist/images/mac/validateplacemarkers.png
new file mode 100644
index 000000000..18ccc4cbc
--- /dev/null
+++ b/src/linguist/linguist/images/mac/validateplacemarkers.png
Binary files differ
diff --git a/src/linguist/linguist/images/mac/whatsthis.png b/src/linguist/linguist/images/mac/whatsthis.png
new file mode 100644
index 000000000..5b7078fff
--- /dev/null
+++ b/src/linguist/linguist/images/mac/whatsthis.png
Binary files differ
diff --git a/src/linguist/linguist/images/minus.png b/src/linguist/linguist/images/minus.png
new file mode 100644
index 000000000..745b44572
--- /dev/null
+++ b/src/linguist/linguist/images/minus.png
Binary files differ
diff --git a/src/linguist/linguist/images/plus.png b/src/linguist/linguist/images/plus.png
new file mode 100644
index 000000000..ef43788e6
--- /dev/null
+++ b/src/linguist/linguist/images/plus.png
Binary files differ
diff --git a/src/linguist/linguist/images/s_check_danger.png b/src/linguist/linguist/images/s_check_danger.png
new file mode 100644
index 000000000..e10157768
--- /dev/null
+++ b/src/linguist/linguist/images/s_check_danger.png
Binary files differ
diff --git a/src/linguist/linguist/images/s_check_empty.png b/src/linguist/linguist/images/s_check_empty.png
new file mode 100644
index 000000000..759a41b6c
--- /dev/null
+++ b/src/linguist/linguist/images/s_check_empty.png
Binary files differ
diff --git a/src/linguist/linguist/images/s_check_obsolete.png b/src/linguist/linguist/images/s_check_obsolete.png
new file mode 100644
index 000000000..b852b639f
--- /dev/null
+++ b/src/linguist/linguist/images/s_check_obsolete.png
Binary files differ
diff --git a/src/linguist/linguist/images/s_check_off.png b/src/linguist/linguist/images/s_check_off.png
new file mode 100644
index 000000000..640b68972
--- /dev/null
+++ b/src/linguist/linguist/images/s_check_off.png
Binary files differ
diff --git a/src/linguist/linguist/images/s_check_on.png b/src/linguist/linguist/images/s_check_on.png
new file mode 100644
index 000000000..afcaf634d
--- /dev/null
+++ b/src/linguist/linguist/images/s_check_on.png
Binary files differ
diff --git a/src/linguist/linguist/images/s_check_warning.png b/src/linguist/linguist/images/s_check_warning.png
new file mode 100644
index 000000000..f689c3303
--- /dev/null
+++ b/src/linguist/linguist/images/s_check_warning.png
Binary files differ
diff --git a/src/linguist/linguist/images/splash.png b/src/linguist/linguist/images/splash.png
new file mode 100644
index 000000000..0e99a1cf0
--- /dev/null
+++ b/src/linguist/linguist/images/splash.png
Binary files differ
diff --git a/src/linguist/linguist/images/up.png b/src/linguist/linguist/images/up.png
new file mode 100644
index 000000000..e43731221
--- /dev/null
+++ b/src/linguist/linguist/images/up.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/accelerator.png b/src/linguist/linguist/images/win/accelerator.png
new file mode 100644
index 000000000..c423c12cf
--- /dev/null
+++ b/src/linguist/linguist/images/win/accelerator.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/book.png b/src/linguist/linguist/images/win/book.png
new file mode 100644
index 000000000..09ec4d33f
--- /dev/null
+++ b/src/linguist/linguist/images/win/book.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/doneandnext.png b/src/linguist/linguist/images/win/doneandnext.png
new file mode 100644
index 000000000..9d1d58d6a
--- /dev/null
+++ b/src/linguist/linguist/images/win/doneandnext.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/editcopy.png b/src/linguist/linguist/images/win/editcopy.png
new file mode 100644
index 000000000..1121b47d8
--- /dev/null
+++ b/src/linguist/linguist/images/win/editcopy.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/editcut.png b/src/linguist/linguist/images/win/editcut.png
new file mode 100644
index 000000000..4b6c82c7a
--- /dev/null
+++ b/src/linguist/linguist/images/win/editcut.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/editpaste.png b/src/linguist/linguist/images/win/editpaste.png
new file mode 100644
index 000000000..ffab15aaf
--- /dev/null
+++ b/src/linguist/linguist/images/win/editpaste.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/filenew.png b/src/linguist/linguist/images/win/filenew.png
new file mode 100644
index 000000000..af5d12214
--- /dev/null
+++ b/src/linguist/linguist/images/win/filenew.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/fileopen.png b/src/linguist/linguist/images/win/fileopen.png
new file mode 100644
index 000000000..fc6f17e97
--- /dev/null
+++ b/src/linguist/linguist/images/win/fileopen.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/filesave.png b/src/linguist/linguist/images/win/filesave.png
new file mode 100644
index 000000000..8feec99be
--- /dev/null
+++ b/src/linguist/linguist/images/win/filesave.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/next.png b/src/linguist/linguist/images/win/next.png
new file mode 100644
index 000000000..8df4127a0
--- /dev/null
+++ b/src/linguist/linguist/images/win/next.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/nextunfinished.png b/src/linguist/linguist/images/win/nextunfinished.png
new file mode 100644
index 000000000..636b9213b
--- /dev/null
+++ b/src/linguist/linguist/images/win/nextunfinished.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/phrase.png b/src/linguist/linguist/images/win/phrase.png
new file mode 100644
index 000000000..8ff952c51
--- /dev/null
+++ b/src/linguist/linguist/images/win/phrase.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/prev.png b/src/linguist/linguist/images/win/prev.png
new file mode 100644
index 000000000..0780bc23d
--- /dev/null
+++ b/src/linguist/linguist/images/win/prev.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/prevunfinished.png b/src/linguist/linguist/images/win/prevunfinished.png
new file mode 100644
index 000000000..139d11b03
--- /dev/null
+++ b/src/linguist/linguist/images/win/prevunfinished.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/print.png b/src/linguist/linguist/images/win/print.png
new file mode 100644
index 000000000..ba7c02dc1
--- /dev/null
+++ b/src/linguist/linguist/images/win/print.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/punctuation.png b/src/linguist/linguist/images/win/punctuation.png
new file mode 100644
index 000000000..e2372a2ef
--- /dev/null
+++ b/src/linguist/linguist/images/win/punctuation.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/redo.png b/src/linguist/linguist/images/win/redo.png
new file mode 100644
index 000000000..686ad141c
--- /dev/null
+++ b/src/linguist/linguist/images/win/redo.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/searchfind.png b/src/linguist/linguist/images/win/searchfind.png
new file mode 100644
index 000000000..6ea35e930
--- /dev/null
+++ b/src/linguist/linguist/images/win/searchfind.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/undo.png b/src/linguist/linguist/images/win/undo.png
new file mode 100644
index 000000000..c3b8c5136
--- /dev/null
+++ b/src/linguist/linguist/images/win/undo.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/validateplacemarkers.png b/src/linguist/linguist/images/win/validateplacemarkers.png
new file mode 100644
index 000000000..cc127fde9
--- /dev/null
+++ b/src/linguist/linguist/images/win/validateplacemarkers.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/whatsthis.png b/src/linguist/linguist/images/win/whatsthis.png
new file mode 100644
index 000000000..623cad687
--- /dev/null
+++ b/src/linguist/linguist/images/win/whatsthis.png
Binary files differ
diff --git a/src/linguist/linguist/linguist.icns b/src/linguist/linguist/linguist.icns
new file mode 100644
index 000000000..5918e001c
--- /dev/null
+++ b/src/linguist/linguist/linguist.icns
Binary files differ
diff --git a/src/linguist/linguist/linguist.ico b/src/linguist/linguist/linguist.ico
new file mode 100644
index 000000000..5bbdc485b
--- /dev/null
+++ b/src/linguist/linguist/linguist.ico
Binary files differ
diff --git a/src/linguist/linguist/linguist.pro b/src/linguist/linguist/linguist.pro
new file mode 100644
index 000000000..ce8d5854f
--- /dev/null
+++ b/src/linguist/linguist/linguist.pro
@@ -0,0 +1,96 @@
+TEMPLATE = app
+LANGUAGE = C++
+DESTDIR = ../../../bin
+
+QT += xml
+
+CONFIG += qt \
+ warn_on \
+ uitools
+
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+include(../shared/formats.pri)
+
+DEFINES += QFORMINTERNAL_NAMESPACE
+INCLUDEPATH += ../../designer/src/uitools
+INCLUDEPATH += ../../designer/src/lib/uilib
+
+SOURCES += \
+ batchtranslationdialog.cpp \
+ errorsview.cpp \
+ finddialog.cpp \
+ formpreviewview.cpp \
+ globals.cpp \
+ main.cpp \
+ mainwindow.cpp \
+ messageeditor.cpp \
+ messageeditorwidgets.cpp \
+ messagehighlighter.cpp \
+ messagemodel.cpp \
+ phrasebookbox.cpp \
+ phrase.cpp \
+ phrasemodel.cpp \
+ phraseview.cpp \
+ printout.cpp \
+ recentfiles.cpp \
+ sourcecodeview.cpp \
+ statistics.cpp \
+ translatedialog.cpp \
+ translationsettingsdialog.cpp \
+ ../shared/simtexth.cpp
+
+HEADERS += \
+ batchtranslationdialog.h \
+ errorsview.h \
+ finddialog.h \
+ formpreviewview.h \
+ globals.h \
+ mainwindow.h \
+ messageeditor.h \
+ messageeditorwidgets.h \
+ messagehighlighter.h \
+ messagemodel.h \
+ phrasebookbox.h \
+ phrase.h \
+ phrasemodel.h \
+ phraseview.h \
+ printout.h \
+ recentfiles.h \
+ sourcecodeview.h \
+ statistics.h \
+ translatedialog.h \
+ translationsettingsdialog.h \
+ ../shared/simtexth.h
+
+contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
+DEFINES += QT_KEYWORDS
+TARGET = linguist
+win32:RC_FILE = linguist.rc
+mac {
+ static:CONFIG -= global_init_link_order
+ ICON = linguist.icns
+ TARGET = Linguist
+ QMAKE_INFO_PLIST=Info_mac.plist
+}
+PROJECTNAME = Qt \
+ Linguist
+target.path = $$[QT_INSTALL_BINS]
+INSTALLS += target
+phrasebooks.path = $$[QT_INSTALL_DATA]/phrasebooks
+
+# ## will this work on windows?
+phrasebooks.files = $$QT_SOURCE_TREE/tools/linguist/phrasebooks/*
+INSTALLS += phrasebooks
+FORMS += statistics.ui \
+ phrasebookbox.ui \
+ batchtranslation.ui \
+ translatedialog.ui \
+ mainwindow.ui \
+ translationsettings.ui \
+ finddialog.ui
+RESOURCES += linguist.qrc
diff --git a/src/linguist/linguist/linguist.qrc b/src/linguist/linguist/linguist.qrc
new file mode 100644
index 000000000..b70b9cd52
--- /dev/null
+++ b/src/linguist/linguist/linguist.qrc
@@ -0,0 +1,57 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/appicon.png</file>
+ <file>images/mac/accelerator.png</file>
+ <file>images/mac/book.png</file>
+ <file>images/mac/doneandnext.png</file>
+ <file>images/mac/editcopy.png</file>
+ <file>images/mac/editcut.png</file>
+ <file>images/mac/editpaste.png</file>
+ <file>images/mac/fileopen.png</file>
+ <file>images/mac/filesave.png</file>
+ <file>images/mac/next.png</file>
+ <file>images/mac/nextunfinished.png</file>
+ <file>images/mac/phrase.png</file>
+ <file>images/mac/prev.png</file>
+ <file>images/mac/prevunfinished.png</file>
+ <file>images/mac/print.png</file>
+ <file>images/mac/punctuation.png</file>
+ <file>images/mac/redo.png</file>
+ <file>images/mac/searchfind.png</file>
+ <file>images/mac/undo.png</file>
+ <file>images/mac/validateplacemarkers.png</file>
+ <file>images/mac/whatsthis.png</file>
+ <file>images/s_check_danger.png</file>
+ <file>images/s_check_empty.png</file>
+ <file>images/s_check_obsolete.png</file>
+ <file>images/s_check_off.png</file>
+ <file>images/s_check_on.png</file>
+ <file>images/s_check_warning.png</file>
+ <file>images/splash.png</file>
+ <file>images/up.png</file>
+ <file>images/down.png</file>
+ <file>images/editdelete.png</file>
+ <file>images/minus.png</file>
+ <file>images/plus.png</file>
+ <file>images/win/accelerator.png</file>
+ <file>images/win/book.png</file>
+ <file>images/win/doneandnext.png</file>
+ <file>images/win/editcopy.png</file>
+ <file>images/win/editcut.png</file>
+ <file>images/win/editpaste.png</file>
+ <file>images/win/fileopen.png</file>
+ <file>images/win/filesave.png</file>
+ <file>images/win/next.png</file>
+ <file>images/win/nextunfinished.png</file>
+ <file>images/win/phrase.png</file>
+ <file>images/win/prev.png</file>
+ <file>images/win/prevunfinished.png</file>
+ <file>images/win/print.png</file>
+ <file>images/win/punctuation.png</file>
+ <file>images/win/redo.png</file>
+ <file>images/win/searchfind.png</file>
+ <file>images/win/undo.png</file>
+ <file>images/win/validateplacemarkers.png</file>
+ <file>images/win/whatsthis.png</file>
+ </qresource>
+</RCC>
diff --git a/src/linguist/linguist/linguist.rc b/src/linguist/linguist/linguist.rc
new file mode 100644
index 000000000..375f02a27
--- /dev/null
+++ b/src/linguist/linguist/linguist.rc
@@ -0,0 +1,32 @@
+#include "winver.h"
+
+IDI_ICON1 ICON DISCARDABLE "linguist.ico"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGS 0x0L
+ FILEFLAGSMASK 0x3fL
+ FILEOS 0x00040004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)"
+ VALUE "FileDescription", "Qt Linguist"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+ VALUE "InternalName", "linguist"
+ VALUE "OriginalFilename", "linguist.exe"
+ VALUE "ProductName", "Qt Linguist"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/src/linguist/linguist/main.cpp b/src/linguist/linguist/main.cpp
new file mode 100644
index 000000000..c1388e198
--- /dev/null
+++ b/src/linguist/linguist/main.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "globals.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QLocale>
+#include <QtCore/QSettings>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTranslator>
+
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QPixmap>
+#include <QtGui/QSplashScreen>
+
+QT_USE_NAMESPACE
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(linguist);
+
+ QApplication app(argc, argv);
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+
+ QStringList files;
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ QStringList args = app.arguments();
+
+ for (int i = 1; i < args.count(); ++i) {
+ QString argument = args.at(i);
+ if (argument == QLatin1String("-resourcedir")) {
+ if (i + 1 < args.count()) {
+ resourceDir = QFile::decodeName(args.at(++i).toLocal8Bit());
+ } else {
+ // issue a warning
+ }
+ } else if (!files.contains(argument)) {
+ files.append(argument);
+ }
+ }
+
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ if (qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir))
+ app.installTranslator(&qtTranslator);
+ else
+ app.removeTranslator(&translator);
+ }
+
+ app.setOrganizationName(QLatin1String("Trolltech"));
+ app.setApplicationName(QLatin1String("Linguist"));
+
+ QSettings config;
+
+ QWidget tmp;
+ tmp.restoreGeometry(config.value(settingPath("Geometry/WindowGeometry")).toByteArray());
+
+ QSplashScreen *splash = 0;
+ int screenId = QApplication::desktop()->screenNumber(tmp.geometry().center());
+ splash = new QSplashScreen(QApplication::desktop()->screen(screenId),
+ QPixmap(QLatin1String(":/images/splash.png")));
+ if (QApplication::desktop()->isVirtualDesktop()) {
+ QRect srect(0, 0, splash->width(), splash->height());
+ splash->move(QApplication::desktop()->availableGeometry(screenId).center() - srect.center());
+ }
+ splash->setAttribute(Qt::WA_DeleteOnClose);
+ splash->show();
+
+ MainWindow mw;
+ mw.show();
+ splash->finish(&mw);
+ QApplication::restoreOverrideCursor();
+
+ mw.openFiles(files, true);
+
+ return app.exec();
+}
diff --git a/src/linguist/linguist/mainwindow.cpp b/src/linguist/linguist/mainwindow.cpp
new file mode 100644
index 000000000..e6fad1b38
--- /dev/null
+++ b/src/linguist/linguist/mainwindow.cpp
@@ -0,0 +1,2724 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* TRANSLATOR MainWindow
+
+ This is the application's main window.
+*/
+
+#include "mainwindow.h"
+
+#include "batchtranslationdialog.h"
+#include "errorsview.h"
+#include "finddialog.h"
+#include "formpreviewview.h"
+#include "globals.h"
+#include "messageeditor.h"
+#include "messagemodel.h"
+#include "phrasebookbox.h"
+#include "phrasemodel.h"
+#include "phraseview.h"
+#include "printout.h"
+#include "sourcecodeview.h"
+#include "statistics.h"
+#include "translatedialog.h"
+#include "translationsettingsdialog.h"
+
+#include <QAction>
+#include <QApplication>
+#include <QBitmap>
+#include <QCloseEvent>
+#include <QDebug>
+#include <QDesktopWidget>
+#include <QDockWidget>
+#include <QFile>
+#include <QFileDialog>
+#include <QFileInfo>
+#include <QHeaderView>
+#include <QInputDialog>
+#include <QItemDelegate>
+#include <QLabel>
+#include <QLayout>
+#include <QLibraryInfo>
+#include <QMenu>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QPrintDialog>
+#include <QPrinter>
+#include <QProcess>
+#include <QRegExp>
+#include <QSettings>
+#include <QSortFilterProxyModel>
+#include <QStackedWidget>
+#include <QStatusBar>
+#include <QTextStream>
+#include <QToolBar>
+#include <QUrl>
+#include <QWhatsThis>
+
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int MessageMS = 2500;
+
+enum Ending {
+ End_None,
+ End_FullStop,
+ End_Interrobang,
+ End_Colon,
+ End_Ellipsis
+};
+
+static bool hasFormPreview(const QString &fileName)
+{
+ return fileName.endsWith(QLatin1String(".ui"))
+ || fileName.endsWith(QLatin1String(".jui"));
+}
+
+static Ending ending(QString str, QLocale::Language lang)
+{
+ str = str.simplified();
+ if (str.isEmpty())
+ return End_None;
+
+ switch (str.at(str.length() - 1).unicode()) {
+ case 0x002e: // full stop
+ if (str.endsWith(QLatin1String("...")))
+ return End_Ellipsis;
+ else
+ return End_FullStop;
+ case 0x0589: // armenian full stop
+ case 0x06d4: // arabic full stop
+ case 0x3002: // ideographic full stop
+ return End_FullStop;
+ case 0x0021: // exclamation mark
+ case 0x003f: // question mark
+ case 0x00a1: // inverted exclamation mark
+ case 0x00bf: // inverted question mark
+ case 0x01c3: // latin letter retroflex click
+ case 0x037e: // greek question mark
+ case 0x061f: // arabic question mark
+ case 0x203c: // double exclamation mark
+ case 0x203d: // interrobang
+ case 0x2048: // question exclamation mark
+ case 0x2049: // exclamation question mark
+ case 0x2762: // heavy exclamation mark ornament
+ case 0xff01: // full width exclamation mark
+ case 0xff1f: // full width question mark
+ return End_Interrobang;
+ case 0x003b: // greek 'compatibility' questionmark
+ return lang == QLocale::Greek ? End_Interrobang : End_None;
+ case 0x003a: // colon
+ case 0xff1a: // full width colon
+ return End_Colon;
+ case 0x2026: // horizontal ellipsis
+ return End_Ellipsis;
+ default:
+ return End_None;
+ }
+}
+
+
+class ContextItemDelegate : public QItemDelegate
+{
+public:
+ ContextItemDelegate(QObject *parent, MultiDataModel *model) : QItemDelegate(parent), m_dataModel(model) {}
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+ {
+ const QAbstractItemModel *model = index.model();
+ Q_ASSERT(model);
+
+ if (!model->parent(index).isValid()) {
+ if (index.column() - 1 == m_dataModel->modelCount()) {
+ QStyleOptionViewItem opt = option;
+ opt.font.setBold(true);
+ QItemDelegate::paint(painter, opt, index);
+ return;
+ }
+ }
+ QItemDelegate::paint(painter, option, index);
+ }
+
+private:
+ MultiDataModel *m_dataModel;
+};
+
+static const QVariant &pxObsolete()
+{
+ static const QVariant v =
+ QVariant::fromValue(QPixmap(QLatin1String(":/images/s_check_obsolete.png")));
+ return v;
+}
+
+
+class SortedMessagesModel : public QSortFilterProxyModel
+{
+public:
+ SortedMessagesModel(QObject *parent, MultiDataModel *model) : QSortFilterProxyModel(parent), m_dataModel(model) {}
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const
+ {
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
+ switch (section - m_dataModel->modelCount()) {
+ case 0: return QString();
+ case 1: return MainWindow::tr("Source text");
+ case 2: return MainWindow::tr("Index");
+ }
+
+ if (role == Qt::DecorationRole && orientation == Qt::Horizontal && section - 1 < m_dataModel->modelCount())
+ return pxObsolete();
+
+ return QVariant();
+ }
+
+private:
+ MultiDataModel *m_dataModel;
+};
+
+class SortedContextsModel : public QSortFilterProxyModel
+{
+public:
+ SortedContextsModel(QObject *parent, MultiDataModel *model) : QSortFilterProxyModel(parent), m_dataModel(model) {}
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const
+ {
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
+ switch (section - m_dataModel->modelCount()) {
+ case 0: return QString();
+ case 1: return MainWindow::tr("Context");
+ case 2: return MainWindow::tr("Items");
+ case 3: return MainWindow::tr("Index");
+ }
+
+ if (role == Qt::DecorationRole && orientation == Qt::Horizontal && section - 1 < m_dataModel->modelCount())
+ return pxObsolete();
+
+ return QVariant();
+ }
+
+private:
+ MultiDataModel *m_dataModel;
+};
+
+class FocusWatcher : public QObject
+{
+public:
+ FocusWatcher(MessageEditor *msgedit, QObject *parent) : QObject(parent), m_messageEditor(msgedit) {}
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event);
+
+private:
+ MessageEditor *m_messageEditor;
+};
+
+bool FocusWatcher::eventFilter(QObject *, QEvent *event)
+{
+ if (event->type() == QEvent::FocusIn)
+ m_messageEditor->setEditorFocus(-1);
+ return false;
+}
+
+MainWindow::MainWindow()
+ : QMainWindow(0, Qt::Window),
+ m_assistantProcess(0),
+ m_printer(0),
+ m_findMatchCase(Qt::CaseInsensitive),
+ m_findIgnoreAccelerators(true),
+ m_findWhere(DataModel::NoLocation),
+ m_foundWhere(DataModel::NoLocation),
+ m_translationSettingsDialog(0),
+ m_settingCurrentMessage(false),
+ m_fileActiveModel(-1),
+ m_editActiveModel(-1),
+ m_statistics(0)
+{
+ setUnifiedTitleAndToolBarOnMac(true);
+ m_ui.setupUi(this);
+
+#ifndef Q_WS_MAC
+ setWindowIcon(QPixmap(QLatin1String(":/images/appicon.png") ));
+#endif
+
+ m_dataModel = new MultiDataModel(this);
+ m_messageModel = new MessageModel(this, m_dataModel);
+
+ // Set up the context dock widget
+ m_contextDock = new QDockWidget(this);
+ m_contextDock->setObjectName(QLatin1String("ContextDockWidget"));
+ m_contextDock->setAllowedAreas(Qt::AllDockWidgetAreas);
+ m_contextDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
+ m_contextDock->setWindowTitle(tr("Context"));
+ m_contextDock->setAcceptDrops(true);
+ m_contextDock->installEventFilter(this);
+
+ m_sortedContextsModel = new SortedContextsModel(this, m_dataModel);
+ m_sortedContextsModel->setSortRole(MessageModel::SortRole);
+ m_sortedContextsModel->setSortCaseSensitivity(Qt::CaseInsensitive);
+ m_sortedContextsModel->setSourceModel(m_messageModel);
+
+ m_contextView = new QTreeView(this);
+ m_contextView->setRootIsDecorated(false);
+ m_contextView->setItemsExpandable(false);
+ m_contextView->setUniformRowHeights(true);
+ m_contextView->setAlternatingRowColors(true);
+ m_contextView->setAllColumnsShowFocus(true);
+ m_contextView->setItemDelegate(new ContextItemDelegate(this, m_dataModel));
+ m_contextView->setSortingEnabled(true);
+ m_contextView->setWhatsThis(tr("This panel lists the source contexts."));
+ m_contextView->setModel(m_sortedContextsModel);
+ m_contextView->header()->setMovable(false);
+ m_contextView->setColumnHidden(0, true);
+ m_contextView->header()->setStretchLastSection(false);
+
+ m_contextDock->setWidget(m_contextView);
+
+ // Set up the messages dock widget
+ m_messagesDock = new QDockWidget(this);
+ m_messagesDock->setObjectName(QLatin1String("StringsDockWidget"));
+ m_messagesDock->setAllowedAreas(Qt::AllDockWidgetAreas);
+ m_messagesDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
+ m_messagesDock->setWindowTitle(tr("Strings"));
+ m_messagesDock->setAcceptDrops(true);
+ m_messagesDock->installEventFilter(this);
+
+ m_sortedMessagesModel = new SortedMessagesModel(this, m_dataModel);
+ m_sortedMessagesModel->setSortRole(MessageModel::SortRole);
+ m_sortedMessagesModel->setSortCaseSensitivity(Qt::CaseInsensitive);
+ m_sortedMessagesModel->setSortLocaleAware(true);
+ m_sortedMessagesModel->setSourceModel(m_messageModel);
+
+ m_messageView = new QTreeView(m_messagesDock);
+ m_messageView->setSortingEnabled(true);
+ m_messageView->setRootIsDecorated(false);
+ m_messageView->setUniformRowHeights(true);
+ m_messageView->setAllColumnsShowFocus(true);
+ m_messageView->setItemsExpandable(false);
+ m_messageView->setModel(m_sortedMessagesModel);
+ m_messageView->header()->setMovable(false);
+ m_messageView->setColumnHidden(0, true);
+
+ m_messagesDock->setWidget(m_messageView);
+
+ // Set up main message view
+ m_messageEditor = new MessageEditor(m_dataModel, this);
+ m_messageEditor->setAcceptDrops(true);
+ m_messageEditor->installEventFilter(this);
+ // We can't call setCentralWidget(m_messageEditor), since it is already called in m_ui.setupUi()
+ QBoxLayout *lout = new QBoxLayout(QBoxLayout::TopToBottom, m_ui.centralwidget);
+ lout->addWidget(m_messageEditor);
+ lout->setMargin(0);
+ m_ui.centralwidget->setLayout(lout);
+
+ // Set up the phrases & guesses dock widget
+ m_phrasesDock = new QDockWidget(this);
+ m_phrasesDock->setObjectName(QLatin1String("PhrasesDockwidget"));
+ m_phrasesDock->setAllowedAreas(Qt::AllDockWidgetAreas);
+ m_phrasesDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
+ m_phrasesDock->setWindowTitle(tr("Phrases and guesses"));
+
+ m_phraseView = new PhraseView(m_dataModel, &m_phraseDict, this);
+ m_phrasesDock->setWidget(m_phraseView);
+
+ // Set up source code and form preview dock widget
+ m_sourceAndFormDock = new QDockWidget(this);
+ m_sourceAndFormDock->setObjectName(QLatin1String("SourceAndFormDock"));
+ m_sourceAndFormDock->setAllowedAreas(Qt::AllDockWidgetAreas);
+ m_sourceAndFormDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
+ m_sourceAndFormDock->setWindowTitle(tr("Sources and Forms"));
+ m_sourceAndFormView = new QStackedWidget(this);
+ m_sourceAndFormDock->setWidget(m_sourceAndFormView);
+ //connect(m_sourceAndDock, SIGNAL(visibilityChanged(bool)),
+ // m_sourceCodeView, SLOT(setActivated(bool)));
+ m_formPreviewView = new FormPreviewView(0, m_dataModel);
+ m_sourceCodeView = new SourceCodeView(0);
+ m_sourceAndFormView->addWidget(m_sourceCodeView);
+ m_sourceAndFormView->addWidget(m_formPreviewView);
+
+ // Set up errors dock widget
+ m_errorsDock = new QDockWidget(this);
+ m_errorsDock->setObjectName(QLatin1String("ErrorsDockWidget"));
+ m_errorsDock->setAllowedAreas(Qt::AllDockWidgetAreas);
+ m_errorsDock->setFeatures(QDockWidget::AllDockWidgetFeatures);
+ m_errorsDock->setWindowTitle(tr("Warnings"));
+ m_errorsView = new ErrorsView(m_dataModel, this);
+ m_errorsDock->setWidget(m_errorsView);
+
+ // Arrange dock widgets
+ setDockNestingEnabled(true);
+ setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
+ setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
+ setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+ setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
+ addDockWidget(Qt::LeftDockWidgetArea, m_contextDock);
+ addDockWidget(Qt::TopDockWidgetArea, m_messagesDock);
+ addDockWidget(Qt::BottomDockWidgetArea, m_phrasesDock);
+ addDockWidget(Qt::TopDockWidgetArea, m_sourceAndFormDock);
+ addDockWidget(Qt::BottomDockWidgetArea, m_errorsDock);
+ //tabifyDockWidget(m_errorsDock, m_sourceAndFormDock);
+ //tabifyDockWidget(m_sourceCodeDock, m_phrasesDock);
+
+ // Allow phrases doc to intercept guesses shortcuts
+ m_messageEditor->installEventFilter(m_phraseView);
+
+ // Set up shortcuts for the dock widgets
+ QShortcut *contextShortcut = new QShortcut(QKeySequence(Qt::Key_F6), this);
+ connect(contextShortcut, SIGNAL(activated()), this, SLOT(showContextDock()));
+ QShortcut *messagesShortcut = new QShortcut(QKeySequence(Qt::Key_F7), this);
+ connect(messagesShortcut, SIGNAL(activated()), this, SLOT(showMessagesDock()));
+ QShortcut *errorsShortcut = new QShortcut(QKeySequence(Qt::Key_F8), this);
+ connect(errorsShortcut, SIGNAL(activated()), this, SLOT(showErrorDock()));
+ QShortcut *sourceCodeShortcut = new QShortcut(QKeySequence(Qt::Key_F9), this);
+ connect(sourceCodeShortcut, SIGNAL(activated()), this, SLOT(showSourceCodeDock()));
+ QShortcut *phrasesShortcut = new QShortcut(QKeySequence(Qt::Key_F10), this);
+ connect(phrasesShortcut, SIGNAL(activated()), this, SLOT(showPhrasesDock()));
+
+ connect(m_phraseView, SIGNAL(phraseSelected(int,QString)),
+ m_messageEditor, SLOT(setTranslation(int,QString)));
+ connect(m_contextView->selectionModel(),
+ SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
+ this, SLOT(selectedContextChanged(QModelIndex,QModelIndex)));
+ connect(m_messageView->selectionModel(),
+ SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
+ this, SLOT(selectedMessageChanged(QModelIndex,QModelIndex)));
+ connect(m_contextView->selectionModel(),
+ SIGNAL(currentColumnChanged(QModelIndex,QModelIndex)),
+ SLOT(updateLatestModel(QModelIndex)));
+ connect(m_messageView->selectionModel(),
+ SIGNAL(currentColumnChanged(QModelIndex,QModelIndex)),
+ SLOT(updateLatestModel(QModelIndex)));
+
+ connect(m_messageEditor, SIGNAL(activeModelChanged(int)), SLOT(updateActiveModel(int)));
+
+ m_translateDialog = new TranslateDialog(this);
+ m_batchTranslateDialog = new BatchTranslationDialog(m_dataModel, this);
+ m_findDialog = new FindDialog(this);
+
+ setupMenuBar();
+ setupToolBars();
+
+ m_progressLabel = new QLabel();
+ statusBar()->addPermanentWidget(m_progressLabel);
+ m_modifiedLabel = new QLabel(tr(" MOD ", "status bar: file(s) modified"));
+ statusBar()->addPermanentWidget(m_modifiedLabel);
+
+ modelCountChanged();
+ initViewHeaders();
+ resetSorting();
+
+ connect(m_dataModel, SIGNAL(modifiedChanged(bool)),
+ this, SLOT(setWindowModified(bool)));
+ connect(m_dataModel, SIGNAL(modifiedChanged(bool)),
+ m_modifiedLabel, SLOT(setVisible(bool)));
+ connect(m_dataModel, SIGNAL(multiContextDataChanged(MultiDataIndex)),
+ SLOT(updateProgress()));
+ connect(m_dataModel, SIGNAL(messageDataChanged(MultiDataIndex)),
+ SLOT(maybeUpdateStatistics(MultiDataIndex)));
+ connect(m_dataModel, SIGNAL(translationChanged(MultiDataIndex)),
+ SLOT(translationChanged(MultiDataIndex)));
+ connect(m_dataModel, SIGNAL(languageChanged(int)),
+ SLOT(updatePhraseDict(int)));
+
+ setWindowModified(m_dataModel->isModified());
+ m_modifiedLabel->setVisible(m_dataModel->isModified());
+
+ connect(m_messageView, SIGNAL(clicked(QModelIndex)),
+ this, SLOT(toggleFinished(QModelIndex)));
+ connect(m_messageView, SIGNAL(activated(QModelIndex)),
+ m_messageEditor, SLOT(setEditorFocus()));
+ connect(m_contextView, SIGNAL(activated(QModelIndex)),
+ m_messageView, SLOT(setFocus()));
+ connect(m_messageEditor, SIGNAL(translationChanged(QStringList)),
+ this, SLOT(updateTranslation(QStringList)));
+ connect(m_messageEditor, SIGNAL(translatorCommentChanged(QString)),
+ this, SLOT(updateTranslatorComment(QString)));
+ connect(m_findDialog, SIGNAL(findNext(QString,DataModel::FindLocation,bool,bool)),
+ this, SLOT(findNext(QString,DataModel::FindLocation,bool,bool)));
+ connect(m_translateDialog, SIGNAL(requestMatchUpdate(bool&)), SLOT(updateTranslateHit(bool&)));
+ connect(m_translateDialog, SIGNAL(activated(int)), SLOT(translate(int)));
+
+ QSize as(qApp->desktop()->size());
+ as -= QSize(30, 30);
+ resize(QSize(1000, 800).boundedTo(as));
+ show();
+ readConfig();
+ m_statistics = 0;
+
+ connect(m_ui.actionLengthVariants, SIGNAL(toggled(bool)),
+ m_messageEditor, SLOT(setLengthVariants(bool)));
+ m_messageEditor->setLengthVariants(m_ui.actionLengthVariants->isChecked());
+
+ m_focusWatcher = new FocusWatcher(m_messageEditor, this);
+ m_contextView->installEventFilter(m_focusWatcher);
+ m_messageView->installEventFilter(m_focusWatcher);
+ m_messageEditor->installEventFilter(m_focusWatcher);
+ m_sourceAndFormView->installEventFilter(m_focusWatcher);
+ m_phraseView->installEventFilter(m_focusWatcher);
+ m_errorsView->installEventFilter(m_focusWatcher);
+}
+
+MainWindow::~MainWindow()
+{
+ writeConfig();
+ if (m_assistantProcess && m_assistantProcess->state() == QProcess::Running) {
+ m_assistantProcess->terminate();
+ m_assistantProcess->waitForFinished(3000);
+ }
+ qDeleteAll(m_phraseBooks);
+ delete m_dataModel;
+ delete m_statistics;
+ delete m_printer;
+}
+
+void MainWindow::initViewHeaders()
+{
+ m_contextView->header()->setResizeMode(1, QHeaderView::Stretch);
+ m_contextView->header()->setResizeMode(2, QHeaderView::ResizeToContents);
+ m_messageView->setColumnHidden(2, true);
+ // last visible column auto-stretches
+}
+
+void MainWindow::modelCountChanged()
+{
+ int mc = m_dataModel->modelCount();
+
+ for (int i = 0; i < mc; ++i) {
+ m_contextView->header()->setResizeMode(i + 1, QHeaderView::Fixed);
+ m_contextView->header()->resizeSection(i + 1, 24);
+
+ m_messageView->header()->setResizeMode(i + 1, QHeaderView::Fixed);
+ m_messageView->header()->resizeSection(i + 1, 24);
+ }
+
+ if (!mc) {
+ selectedMessageChanged(QModelIndex(), QModelIndex());
+ updateLatestModel(-1);
+ } else {
+ if (!m_contextView->currentIndex().isValid()) {
+ // Ensure that something is selected
+ m_contextView->setCurrentIndex(m_sortedContextsModel->index(0, 0));
+ } else {
+ // Plug holes that turn up in the selection due to inserting columns
+ m_contextView->selectionModel()->select(m_contextView->currentIndex(),
+ QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows);
+ m_messageView->selectionModel()->select(m_messageView->currentIndex(),
+ QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows);
+ }
+ // Field insertions/removals are automatic, but not the re-fill
+ m_messageEditor->showMessage(m_currentIndex);
+ if (mc == 1)
+ updateLatestModel(0);
+ else if (m_currentIndex.model() >= mc)
+ updateLatestModel(mc - 1);
+ }
+
+ m_contextView->setUpdatesEnabled(true);
+ m_messageView->setUpdatesEnabled(true);
+
+ updateProgress();
+ updateCaption();
+
+ m_ui.actionFind->setEnabled(m_dataModel->contextCount() > 0);
+ m_ui.actionFindNext->setEnabled(false);
+
+ m_formPreviewView->setSourceContext(-1, 0);
+}
+
+struct OpenedFile {
+ OpenedFile(DataModel *_dataModel, bool _readWrite, bool _langGuessed)
+ { dataModel = _dataModel; readWrite = _readWrite; langGuessed = _langGuessed; }
+ DataModel *dataModel;
+ bool readWrite;
+ bool langGuessed;
+};
+
+bool MainWindow::openFiles(const QStringList &names, bool globalReadWrite)
+{
+ if (names.isEmpty())
+ return false;
+
+ bool waitCursor = false;
+ statusBar()->showMessage(tr("Loading..."));
+ qApp->processEvents();
+
+ QList<OpenedFile> opened;
+ bool closeOld = false;
+ foreach (QString name, names) {
+ if (!waitCursor) {
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ waitCursor = true;
+ }
+
+ bool readWrite = globalReadWrite;
+ if (name.startsWith(QLatin1Char('='))) {
+ name.remove(0, 1);
+ readWrite = false;
+ }
+ QFileInfo fi(name);
+ if (fi.exists()) // Make the loader error out instead of reading stdin
+ name = fi.canonicalFilePath();
+ if (m_dataModel->isFileLoaded(name) >= 0)
+ continue;
+
+ bool langGuessed;
+ DataModel *dm = new DataModel(m_dataModel);
+ if (!dm->load(name, &langGuessed, this)) {
+ delete dm;
+ continue;
+ }
+ if (opened.isEmpty()) {
+ if (!m_dataModel->isWellMergeable(dm)) {
+ QApplication::restoreOverrideCursor();
+ waitCursor = false;
+ switch (QMessageBox::information(this, tr("Loading File - Qt Linguist"),
+ tr("The file '%1' does not seem to be related to the currently open file(s) '%2'.\n\n"
+ "Close the open file(s) first?")
+ .arg(DataModel::prettifyPlainFileName(name), m_dataModel->condensedSrcFileNames(true)),
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No,
+ QMessageBox::Cancel | QMessageBox::Escape))
+ {
+ case QMessageBox::Cancel:
+ delete dm;
+ return false;
+ case QMessageBox::Yes:
+ closeOld = true;
+ break;
+ case QMessageBox::No:
+ break;
+ }
+ }
+ } else {
+ if (!opened.first().dataModel->isWellMergeable(dm)) {
+ QApplication::restoreOverrideCursor();
+ waitCursor = false;
+ switch (QMessageBox::information(this, tr("Loading File - Qt Linguist"),
+ tr("The file '%1' does not seem to be related to the file '%2'"
+ " which is being loaded as well.\n\n"
+ "Skip loading the first named file?")
+ .arg(DataModel::prettifyPlainFileName(name), opened.first().dataModel->srcFileName(true)),
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No,
+ QMessageBox::Cancel | QMessageBox::Escape))
+ {
+ case QMessageBox::Cancel:
+ delete dm;
+ foreach (const OpenedFile &op, opened)
+ delete op.dataModel;
+ return false;
+ case QMessageBox::Yes:
+ delete dm;
+ continue;
+ case QMessageBox::No:
+ break;
+ }
+ }
+ }
+ opened.append(OpenedFile(dm, readWrite, langGuessed));
+ }
+
+ if (closeOld) {
+ if (waitCursor) {
+ QApplication::restoreOverrideCursor();
+ waitCursor = false;
+ }
+ if (!closeAll()) {
+ foreach (const OpenedFile &op, opened)
+ delete op.dataModel;
+ return false;
+ }
+ }
+
+ foreach (const OpenedFile &op, opened) {
+ if (op.langGuessed) {
+ if (waitCursor) {
+ QApplication::restoreOverrideCursor();
+ waitCursor = false;
+ }
+ if (!m_translationSettingsDialog)
+ m_translationSettingsDialog = new TranslationSettingsDialog(this);
+ m_translationSettingsDialog->setDataModel(op.dataModel);
+ m_translationSettingsDialog->exec();
+ }
+ }
+
+ if (!waitCursor)
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ m_contextView->setUpdatesEnabled(false);
+ m_messageView->setUpdatesEnabled(false);
+ int totalCount = 0;
+ foreach (const OpenedFile &op, opened) {
+ m_phraseDict.append(QHash<QString, QList<Phrase *> >());
+ m_dataModel->append(op.dataModel, op.readWrite);
+ if (op.readWrite)
+ updatePhraseDictInternal(m_phraseDict.size() - 1);
+ totalCount += op.dataModel->messageCount();
+ }
+ statusBar()->showMessage(tr("%n translation unit(s) loaded.", 0, totalCount), MessageMS);
+ modelCountChanged();
+ recentFiles().addFiles(m_dataModel->srcFileNames());
+
+ revalidate();
+ QApplication::restoreOverrideCursor();
+ return true;
+}
+
+RecentFiles &MainWindow::recentFiles()
+{
+ static RecentFiles recentFiles(10);
+ return recentFiles;
+}
+
+const QString &MainWindow::resourcePrefix()
+{
+#ifdef Q_WS_MAC
+ static const QString prefix(QLatin1String(":/images/mac"));
+#else
+ static const QString prefix(QLatin1String(":/images/win"));
+#endif
+ return prefix;
+}
+
+void MainWindow::open()
+{
+ openFiles(pickTranslationFiles());
+}
+
+void MainWindow::openAux()
+{
+ openFiles(pickTranslationFiles(), false);
+}
+
+void MainWindow::closeFile()
+{
+ int model = m_currentIndex.model();
+ if (model >= 0 && maybeSave(model)) {
+ m_phraseDict.removeAt(model);
+ m_contextView->setUpdatesEnabled(false);
+ m_messageView->setUpdatesEnabled(false);
+ m_dataModel->close(model);
+ modelCountChanged();
+ }
+}
+
+bool MainWindow::closeAll()
+{
+ if (maybeSaveAll()) {
+ m_phraseDict.clear();
+ m_contextView->setUpdatesEnabled(false);
+ m_messageView->setUpdatesEnabled(false);
+ m_dataModel->closeAll();
+ modelCountChanged();
+ initViewHeaders();
+ recentFiles().closeGroup();
+ return true;
+ }
+ return false;
+}
+
+static QString fileFilters(bool allFirst)
+{
+ static const QString pattern(QLatin1String("%1 (*.%2);;"));
+ QStringList allExtensions;
+ QString filter;
+ foreach (const Translator::FileFormat &format, Translator::registeredFileFormats()) {
+ if (format.fileType == Translator::FileFormat::TranslationSource && format.priority >= 0) {
+ filter.append(pattern.arg(format.description).arg(format.extension));
+ allExtensions.append(QLatin1String("*.") + format.extension);
+ }
+ }
+ QString allFilter = QObject::tr("Translation files (%1);;").arg(allExtensions.join(QLatin1String(" ")));
+ if (allFirst)
+ filter.prepend(allFilter);
+ else
+ filter.append(allFilter);
+ filter.append(QObject::tr("All files (*)"));
+ return filter;
+}
+
+QStringList MainWindow::pickTranslationFiles()
+{
+ QString dir;
+ if (!recentFiles().isEmpty())
+ dir = QFileInfo(recentFiles().lastOpenedFile()).path();
+
+ QString varFilt;
+ if (m_dataModel->modelCount()) {
+ QFileInfo mainFile(m_dataModel->srcFileName(0));
+ QString mainFileBase = mainFile.baseName();
+ int pos = mainFileBase.indexOf(QLatin1Char('_'));
+ if (pos > 0)
+ varFilt = tr("Related files (%1);;")
+ .arg(mainFileBase.left(pos) + QLatin1String("_*.") + mainFile.completeSuffix());
+ }
+
+ return QFileDialog::getOpenFileNames(this, tr("Open Translation Files"), dir,
+ varFilt +
+ fileFilters(true));
+}
+
+void MainWindow::saveInternal(int model)
+{
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ if (m_dataModel->save(model, this)) {
+ updateCaption();
+ statusBar()->showMessage(tr("File saved."), MessageMS);
+ }
+ QApplication::restoreOverrideCursor();
+}
+
+void MainWindow::saveAll()
+{
+ for (int i = 0; i < m_dataModel->modelCount(); ++i)
+ if (m_dataModel->isModelWritable(i))
+ saveInternal(i);
+ recentFiles().closeGroup();
+}
+
+void MainWindow::save()
+{
+ if (m_currentIndex.model() < 0)
+ return;
+
+ saveInternal(m_currentIndex.model());
+}
+
+void MainWindow::saveAs()
+{
+ if (m_currentIndex.model() < 0)
+ return;
+
+ QString newFilename = QFileDialog::getSaveFileName(this, QString(), m_dataModel->srcFileName(m_currentIndex.model()),
+ fileFilters(false));
+ if (!newFilename.isEmpty()) {
+ if (m_dataModel->saveAs(m_currentIndex.model(), newFilename, this)) {
+ updateCaption();
+ statusBar()->showMessage(tr("File saved."), MessageMS);
+ recentFiles().addFiles(m_dataModel->srcFileNames());
+ }
+ }
+}
+
+void MainWindow::releaseAs()
+{
+ if (m_currentIndex.model() < 0)
+ return;
+
+ QFileInfo oldFile(m_dataModel->srcFileName(m_currentIndex.model()));
+ QString newFilename = oldFile.path() + QLatin1String("/")
+ + oldFile.completeBaseName() + QLatin1String(".qm");
+
+ newFilename = QFileDialog::getSaveFileName(this, tr("Release"), newFilename,
+ tr("Qt message files for released applications (*.qm)\nAll files (*)"));
+ if (!newFilename.isEmpty()) {
+ if (m_dataModel->release(m_currentIndex.model(), newFilename, false, false, SaveEverything, this))
+ statusBar()->showMessage(tr("File created."), MessageMS);
+ }
+}
+
+void MainWindow::releaseInternal(int model)
+{
+ QFileInfo oldFile(m_dataModel->srcFileName(model));
+ QString newFilename = oldFile.path() + QLatin1Char('/')
+ + oldFile.completeBaseName() + QLatin1String(".qm");
+
+ if (!newFilename.isEmpty()) {
+ if (m_dataModel->release(model, newFilename, false, false, SaveEverything, this))
+ statusBar()->showMessage(tr("File created."), MessageMS);
+ }
+}
+
+// No-question
+void MainWindow::release()
+{
+ if (m_currentIndex.model() < 0)
+ return;
+
+ releaseInternal(m_currentIndex.model());
+}
+
+void MainWindow::releaseAll()
+{
+ for (int i = 0; i < m_dataModel->modelCount(); ++i)
+ if (m_dataModel->isModelWritable(i))
+ releaseInternal(i);
+}
+
+QPrinter *MainWindow::printer()
+{
+ if (!m_printer)
+ m_printer = new QPrinter;
+ return m_printer;
+}
+
+void MainWindow::print()
+{
+ int pageNum = 0;
+ QPrintDialog dlg(printer(), this);
+ if (dlg.exec()) {
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ printer()->setDocName(m_dataModel->condensedSrcFileNames(true));
+ statusBar()->showMessage(tr("Printing..."));
+ PrintOut pout(printer());
+
+ for (int i = 0; i < m_dataModel->contextCount(); ++i) {
+ MultiContextItem *mc = m_dataModel->multiContextItem(i);
+ pout.vskip();
+ pout.setRule(PrintOut::ThickRule);
+ pout.setGuide(mc->context());
+ pout.addBox(100, tr("Context: %1").arg(mc->context()),
+ PrintOut::Strong);
+ pout.flushLine();
+ pout.addBox(4);
+ pout.addBox(92, mc->comment(), PrintOut::Emphasis);
+ pout.flushLine();
+ pout.setRule(PrintOut::ThickRule);
+
+ for (int j = 0; j < mc->messageCount(); ++j) {
+ pout.setRule(PrintOut::ThinRule);
+ bool printedSrc = false;
+ QString comment;
+ for (int k = 0; k < m_dataModel->modelCount(); ++k) {
+ if (const MessageItem *m = mc->messageItem(k, j)) {
+ if (!printedSrc) {
+ pout.addBox(40, m->text());
+ pout.addBox(4);
+ comment = m->comment();
+ printedSrc = true;
+ } else {
+ pout.addBox(44); // Maybe put the name of the translation here
+ }
+ if (m->message().isPlural() && m_dataModel->language(k) != QLocale::C) {
+ QStringList transls = m->translations();
+ pout.addBox(40, transls.join(QLatin1String("\n")));
+ } else {
+ pout.addBox(40, m->translation());
+ }
+ pout.addBox(4);
+ QString type;
+ switch (m->message().type()) {
+ case TranslatorMessage::Finished:
+ type = tr("finished");
+ break;
+ case TranslatorMessage::Unfinished:
+ type = m->danger() ? tr("unresolved") : QLatin1String("unfinished");
+ break;
+ case TranslatorMessage::Obsolete:
+ type = tr("obsolete");
+ break;
+ }
+ pout.addBox(12, type, PrintOut::Normal, Qt::AlignRight);
+ pout.flushLine();
+ }
+ }
+ if (!comment.isEmpty()) {
+ pout.addBox(4);
+ pout.addBox(92, comment, PrintOut::Emphasis);
+ pout.flushLine(true);
+ }
+
+ if (pout.pageNum() != pageNum) {
+ pageNum = pout.pageNum();
+ statusBar()->showMessage(tr("Printing... (page %1)")
+ .arg(pageNum));
+ }
+ }
+ }
+ pout.flushLine(true);
+ QApplication::restoreOverrideCursor();
+ statusBar()->showMessage(tr("Printing completed"), MessageMS);
+ } else {
+ statusBar()->showMessage(tr("Printing aborted"), MessageMS);
+ }
+}
+
+bool MainWindow::searchItem(const QString &searchWhat)
+{
+ if ((m_findWhere & m_foundWhere) == 0)
+ return false;
+
+ QString text = searchWhat;
+
+ if (m_findIgnoreAccelerators)
+ // FIXME: This removes too much. The proper solution might be too slow, though.
+ text.remove(QLatin1Char('&'));
+
+ int foundOffset = text.indexOf(m_findText, 0, m_findMatchCase);
+ return foundOffset >= 0;
+}
+
+void MainWindow::findAgain()
+{
+ if (m_dataModel->contextCount() == 0)
+ return;
+
+ const QModelIndex &startIndex = m_messageView->currentIndex();
+ QModelIndex index = nextMessage(startIndex);
+
+ while (index.isValid()) {
+ QModelIndex realIndex = m_sortedMessagesModel->mapToSource(index);
+ MultiDataIndex dataIndex = m_messageModel->dataIndex(realIndex, -1);
+ bool hadMessage = false;
+ for (int i = 0; i < m_dataModel->modelCount(); ++i) {
+ if (MessageItem *m = m_dataModel->messageItem(dataIndex, i)) {
+ // Note: we do not look into plurals on grounds of them not
+ // containing anything much different from the singular.
+ if (hadMessage) {
+ m_foundWhere = DataModel::Translations;
+ if (!searchItem(m->translation()))
+ m_foundWhere = DataModel::NoLocation;
+ } else {
+ switch (m_foundWhere) {
+ case 0:
+ m_foundWhere = DataModel::SourceText;
+ // fall-through to search source text
+ case DataModel::SourceText:
+ if (searchItem(m->text()))
+ break;
+ if (searchItem(m->pluralText()))
+ break;
+ m_foundWhere = DataModel::Translations;
+ // fall-through to search translation
+ case DataModel::Translations:
+ if (searchItem(m->translation()))
+ break;
+ m_foundWhere = DataModel::Comments;
+ // fall-through to search comment
+ case DataModel::Comments:
+ if (searchItem(m->comment()))
+ break;
+ if (searchItem(m->extraComment()))
+ break;
+ if (searchItem(m->translatorComment()))
+ break;
+ m_foundWhere = DataModel::NoLocation;
+ // did not find the search string in this message
+ }
+ }
+ if (m_foundWhere != DataModel::NoLocation) {
+ setCurrentMessage(realIndex, i);
+
+ // determine whether the search wrapped
+ const QModelIndex &c1 = m_sortedContextsModel->mapFromSource(
+ m_sortedMessagesModel->mapToSource(startIndex)).parent();
+ const QModelIndex &c2 = m_sortedContextsModel->mapFromSource(realIndex).parent();
+ const QModelIndex &m = m_sortedMessagesModel->mapFromSource(realIndex);
+
+ if (c2.row() < c1.row() || (c1.row() == c2.row() && m.row() <= startIndex.row()))
+ statusBar()->showMessage(tr("Search wrapped."), MessageMS);
+
+ m_findDialog->hide();
+ return;
+ }
+ hadMessage = true;
+ }
+ }
+
+ // since we don't search startIndex at the beginning, only now we have searched everything
+ if (index == startIndex)
+ break;
+
+ index = nextMessage(index);
+ }
+
+ qApp->beep();
+ QMessageBox::warning(m_findDialog, tr("Qt Linguist"),
+ tr("Cannot find the string '%1'.").arg(m_findText));
+ m_foundWhere = DataModel::NoLocation;
+}
+
+void MainWindow::showBatchTranslateDialog()
+{
+ m_messageModel->blockSignals(true);
+ m_batchTranslateDialog->setPhraseBooks(m_phraseBooks, m_currentIndex.model());
+ if (m_batchTranslateDialog->exec() != QDialog::Accepted)
+ m_messageModel->blockSignals(false);
+ // else signal finished() calls refreshItemViews()
+}
+
+void MainWindow::showTranslateDialog()
+{
+ m_latestCaseSensitivity = -1;
+ QModelIndex idx = m_messageView->currentIndex();
+ QModelIndex idx2 = m_sortedMessagesModel->index(idx.row(), m_currentIndex.model() + 1, idx.parent());
+ m_messageView->setCurrentIndex(idx2);
+ QString fn = QFileInfo(m_dataModel->srcFileName(m_currentIndex.model())).baseName();
+ m_translateDialog->setWindowTitle(tr("Search And Translate in '%1' - Qt Linguist").arg(fn));
+ m_translateDialog->exec();
+}
+
+void MainWindow::updateTranslateHit(bool &hit)
+{
+ MessageItem *m;
+ hit = (m = m_dataModel->messageItem(m_currentIndex))
+ && !m->isObsolete()
+ && m->compare(m_translateDialog->findText(), false, m_translateDialog->caseSensitivity());
+}
+
+void MainWindow::translate(int mode)
+{
+ QString findText = m_translateDialog->findText();
+ QString replaceText = m_translateDialog->replaceText();
+ bool markFinished = m_translateDialog->markFinished();
+ Qt::CaseSensitivity caseSensitivity = m_translateDialog->caseSensitivity();
+
+ int translatedCount = 0;
+
+ if (mode == TranslateDialog::TranslateAll) {
+ for (MultiDataModelIterator it(m_dataModel, m_currentIndex.model()); it.isValid(); ++it) {
+ MessageItem *m = it.current();
+ if (m && !m->isObsolete() && m->compare(findText, false, caseSensitivity)) {
+ if (!translatedCount)
+ m_messageModel->blockSignals(true);
+ m_dataModel->setTranslation(it, replaceText);
+ m_dataModel->setFinished(it, markFinished);
+ ++translatedCount;
+ }
+ }
+ if (translatedCount) {
+ refreshItemViews();
+ QMessageBox::warning(m_translateDialog, tr("Translate - Qt Linguist"),
+ tr("Translated %n entry(s)", 0, translatedCount));
+ }
+ } else {
+ if (mode == TranslateDialog::Translate) {
+ m_dataModel->setTranslation(m_currentIndex, replaceText);
+ m_dataModel->setFinished(m_currentIndex, markFinished);
+ }
+
+ if (findText != m_latestFindText || caseSensitivity != m_latestCaseSensitivity) {
+ m_latestFindText = findText;
+ m_latestCaseSensitivity = caseSensitivity;
+ m_remainingCount = m_dataModel->messageCount();
+ m_hitCount = 0;
+ }
+
+ QModelIndex index = m_messageView->currentIndex();
+ int prevRemained = m_remainingCount;
+ forever {
+ if (--m_remainingCount <= 0) {
+ if (!m_hitCount)
+ break;
+ m_remainingCount = m_dataModel->messageCount() - 1;
+ if (QMessageBox::question(m_translateDialog, tr("Translate - Qt Linguist"),
+ tr("No more occurrences of '%1'. Start over?").arg(findText),
+ QMessageBox::Yes|QMessageBox::No) != QMessageBox::Yes)
+ return;
+ m_remainingCount -= prevRemained;
+ }
+
+ index = nextMessage(index);
+
+ QModelIndex realIndex = m_sortedMessagesModel->mapToSource(index);
+ MultiDataIndex dataIndex = m_messageModel->dataIndex(realIndex, m_currentIndex.model());
+ if (MessageItem *m = m_dataModel->messageItem(dataIndex)) {
+ if (!m->isObsolete() && m->compare(findText, false, caseSensitivity)) {
+ setCurrentMessage(realIndex, m_currentIndex.model());
+ ++translatedCount;
+ ++m_hitCount;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!translatedCount) {
+ qApp->beep();
+ QMessageBox::warning(m_translateDialog, tr("Translate - Qt Linguist"),
+ tr("Cannot find the string '%1'.").arg(findText));
+ }
+}
+
+void MainWindow::newPhraseBook()
+{
+ QString name = QFileDialog::getSaveFileName(this, tr("Create New Phrase Book"),
+ m_phraseBookDir, tr("Qt phrase books (*.qph)\nAll files (*)"));
+ if (!name.isEmpty()) {
+ PhraseBook pb;
+ if (!m_translationSettingsDialog)
+ m_translationSettingsDialog = new TranslationSettingsDialog(this);
+ m_translationSettingsDialog->setPhraseBook(&pb);
+ if (!m_translationSettingsDialog->exec())
+ return;
+ m_phraseBookDir = QFileInfo(name).absolutePath();
+ if (savePhraseBook(&name, pb)) {
+ if (openPhraseBook(name))
+ statusBar()->showMessage(tr("Phrase book created."), MessageMS);
+ }
+ }
+}
+
+bool MainWindow::isPhraseBookOpen(const QString &name)
+{
+ foreach(const PhraseBook *pb, m_phraseBooks) {
+ if (pb->fileName() == name)
+ return true;
+ }
+
+ return false;
+}
+
+void MainWindow::openPhraseBook()
+{
+ QString name = QFileDialog::getOpenFileName(this, tr("Open Phrase Book"),
+ m_phraseBookDir, tr("Qt phrase books (*.qph);;All files (*)"));
+
+ if (!name.isEmpty()) {
+ m_phraseBookDir = QFileInfo(name).absolutePath();
+ if (!isPhraseBookOpen(name)) {
+ if (PhraseBook *phraseBook = openPhraseBook(name)) {
+ int n = phraseBook->phrases().count();
+ statusBar()->showMessage(tr("%n phrase(s) loaded.", 0, n), MessageMS);
+ }
+ }
+ }
+}
+
+void MainWindow::closePhraseBook(QAction *action)
+{
+ PhraseBook *pb = m_phraseBookMenu[PhraseCloseMenu].value(action);
+ if (!maybeSavePhraseBook(pb))
+ return;
+
+ m_phraseBookMenu[PhraseCloseMenu].remove(action);
+ m_ui.menuClosePhraseBook->removeAction(action);
+
+ QAction *act = m_phraseBookMenu[PhraseEditMenu].key(pb);
+ m_phraseBookMenu[PhraseEditMenu].remove(act);
+ m_ui.menuEditPhraseBook->removeAction(act);
+
+ act = m_phraseBookMenu[PhrasePrintMenu].key(pb);
+ m_ui.menuPrintPhraseBook->removeAction(act);
+
+ m_phraseBooks.removeOne(pb);
+ disconnect(pb, SIGNAL(listChanged()), this, SLOT(updatePhraseDicts()));
+ updatePhraseDicts();
+ delete pb;
+ updatePhraseBookActions();
+}
+
+void MainWindow::editPhraseBook(QAction *action)
+{
+ PhraseBook *pb = m_phraseBookMenu[PhraseEditMenu].value(action);
+ PhraseBookBox box(pb, this);
+ box.exec();
+
+ updatePhraseDicts();
+}
+
+void MainWindow::printPhraseBook(QAction *action)
+{
+ PhraseBook *phraseBook = m_phraseBookMenu[PhrasePrintMenu].value(action);
+
+ int pageNum = 0;
+
+ QPrintDialog dlg(printer(), this);
+ if (dlg.exec()) {
+ printer()->setDocName(phraseBook->fileName());
+ statusBar()->showMessage(tr("Printing..."));
+ PrintOut pout(printer());
+ pout.setRule(PrintOut::ThinRule);
+ foreach (const Phrase *p, phraseBook->phrases()) {
+ pout.setGuide(p->source());
+ pout.addBox(29, p->source());
+ pout.addBox(4);
+ pout.addBox(29, p->target());
+ pout.addBox(4);
+ pout.addBox(34, p->definition(), PrintOut::Emphasis);
+
+ if (pout.pageNum() != pageNum) {
+ pageNum = pout.pageNum();
+ statusBar()->showMessage(tr("Printing... (page %1)")
+ .arg(pageNum));
+ }
+ pout.setRule(PrintOut::NoRule);
+ pout.flushLine(true);
+ }
+ pout.flushLine(true);
+ statusBar()->showMessage(tr("Printing completed"), MessageMS);
+ } else {
+ statusBar()->showMessage(tr("Printing aborted"), MessageMS);
+ }
+}
+
+void MainWindow::addToPhraseBook()
+{
+ MessageItem *currentMessage = m_dataModel->messageItem(m_currentIndex);
+ Phrase *phrase = new Phrase(currentMessage->text(), currentMessage->translation(), QString());
+ QStringList phraseBookList;
+ QHash<QString, PhraseBook *> phraseBookHash;
+ foreach (PhraseBook *pb, m_phraseBooks) {
+ if (pb->language() != QLocale::C && m_dataModel->language(m_currentIndex.model()) != QLocale::C) {
+ if (pb->language() != m_dataModel->language(m_currentIndex.model()))
+ continue;
+ if (pb->country() == m_dataModel->model(m_currentIndex.model())->country())
+ phraseBookList.prepend(pb->friendlyPhraseBookName());
+ else
+ phraseBookList.append(pb->friendlyPhraseBookName());
+ } else {
+ phraseBookList.append(pb->friendlyPhraseBookName());
+ }
+ phraseBookHash.insert(pb->friendlyPhraseBookName(), pb);
+ }
+ if (phraseBookList.isEmpty()) {
+ QMessageBox::warning(this, tr("Add to phrase book"),
+ tr("No appropriate phrasebook found."));
+ } else if (phraseBookList.size() == 1) {
+ if (QMessageBox::information(this, tr("Add to phrase book"),
+ tr("Adding entry to phrasebook %1").arg(phraseBookList.at(0)),
+ QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok)
+ == QMessageBox::Ok)
+ phraseBookHash.value(phraseBookList.at(0))->append(phrase);
+ } else {
+ bool okPressed = false;
+ QString selection = QInputDialog::getItem(this, tr("Add to phrase book"),
+ tr("Select phrase book to add to"),
+ phraseBookList, 0, false, &okPressed);
+ if (okPressed)
+ phraseBookHash.value(selection)->append(phrase);
+ }
+}
+
+void MainWindow::resetSorting()
+{
+ m_contextView->sortByColumn(-1, Qt::AscendingOrder);
+ m_messageView->sortByColumn(-1, Qt::AscendingOrder);
+}
+
+void MainWindow::manual()
+{
+ if (!m_assistantProcess)
+ m_assistantProcess = new QProcess();
+
+ if (m_assistantProcess->state() != QProcess::Running) {
+ QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator();
+#if !defined(Q_OS_MAC)
+ app += QLatin1String("assistant");
+#else
+ app += QLatin1String("Assistant.app/Contents/MacOS/Assistant");
+#endif
+
+ m_assistantProcess->start(app, QStringList() << QLatin1String("-enableRemoteControl"));
+ if (!m_assistantProcess->waitForStarted()) {
+ QMessageBox::critical(this, tr("Qt Linguist"),
+ tr("Unable to launch Qt Assistant (%1)").arg(app));
+ return;
+ }
+ }
+
+ QTextStream str(m_assistantProcess);
+ str << QLatin1String("SetSource qthelp://com.trolltech.linguist.")
+ << (QT_VERSION >> 16) << ((QT_VERSION >> 8) & 0xFF)
+ << (QT_VERSION & 0xFF)
+ << QLatin1String("/qdoc/linguist-manual.html")
+ << QLatin1Char('\n') << endl;
+}
+
+void MainWindow::about()
+{
+ QMessageBox box(this);
+ box.setTextFormat(Qt::RichText);
+ QString version = tr("Version %1");
+ version = version.arg(QLatin1String(QT_VERSION_STR));
+
+ box.setText(tr("<center><img src=\":/images/splash.png\"/></img><p>%1</p></center>"
+ "<p>Qt Linguist is a tool for adding translations to Qt "
+ "applications.</p>"
+ "<p>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+ ).arg(version));
+
+ box.setWindowTitle(QApplication::translate("AboutDialog", "Qt Linguist"));
+ box.setIcon(QMessageBox::NoIcon);
+ box.exec();
+}
+
+void MainWindow::aboutQt()
+{
+ QMessageBox::aboutQt(this, tr("Qt Linguist"));
+}
+
+void MainWindow::setupPhrase()
+{
+ bool enabled = !m_phraseBooks.isEmpty();
+ m_ui.menuClosePhraseBook->setEnabled(enabled);
+ m_ui.menuEditPhraseBook->setEnabled(enabled);
+ m_ui.menuPrintPhraseBook->setEnabled(enabled);
+}
+
+void MainWindow::closeEvent(QCloseEvent *e)
+{
+ if (maybeSaveAll() && closePhraseBooks())
+ e->accept();
+ else
+ e->ignore();
+}
+
+bool MainWindow::maybeSaveAll()
+{
+ if (!m_dataModel->isModified())
+ return true;
+
+ switch (QMessageBox::information(this, tr("Qt Linguist"),
+ tr("Do you want to save the modified files?"),
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No,
+ QMessageBox::Cancel | QMessageBox::Escape))
+ {
+ case QMessageBox::Cancel:
+ return false;
+ case QMessageBox::Yes:
+ saveAll();
+ return !m_dataModel->isModified();
+ case QMessageBox::No:
+ break;
+ }
+ return true;
+}
+
+bool MainWindow::maybeSave(int model)
+{
+ if (!m_dataModel->isModified(model))
+ return true;
+
+ switch (QMessageBox::information(this, tr("Qt Linguist"),
+ tr("Do you want to save '%1'?").arg(m_dataModel->srcFileName(model, true)),
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No,
+ QMessageBox::Cancel | QMessageBox::Escape))
+ {
+ case QMessageBox::Cancel:
+ return false;
+ case QMessageBox::Yes:
+ saveInternal(model);
+ return !m_dataModel->isModified(model);
+ case QMessageBox::No:
+ break;
+ }
+ return true;
+}
+
+void MainWindow::updateCaption()
+{
+ QString cap;
+ bool enable = false;
+ bool enableRw = false;
+ for (int i = 0; i < m_dataModel->modelCount(); ++i) {
+ enable = true;
+ if (m_dataModel->isModelWritable(i)) {
+ enableRw = true;
+ break;
+ }
+ }
+ m_ui.actionSaveAll->setEnabled(enableRw);
+ m_ui.actionReleaseAll->setEnabled(enableRw);
+ m_ui.actionCloseAll->setEnabled(enable);
+ m_ui.actionPrint->setEnabled(enable);
+ m_ui.actionAccelerators->setEnabled(enable);
+ m_ui.actionEndingPunctuation->setEnabled(enable);
+ m_ui.actionPhraseMatches->setEnabled(enable);
+ m_ui.actionPlaceMarkerMatches->setEnabled(enable);
+ m_ui.actionResetSorting->setEnabled(enable);
+
+ updateActiveModel(m_messageEditor->activeModel());
+ // Ensure that the action labels get updated
+ m_fileActiveModel = m_editActiveModel = -2;
+
+ if (!enable)
+ cap = tr("Qt Linguist[*]");
+ else
+ cap = tr("%1[*] - Qt Linguist").arg(m_dataModel->condensedSrcFileNames(true));
+ setWindowTitle(cap);
+}
+
+void MainWindow::selectedContextChanged(const QModelIndex &sortedIndex, const QModelIndex &oldIndex)
+{
+ if (sortedIndex.isValid()) {
+ if (m_settingCurrentMessage)
+ return; // Avoid playing ping-pong with the current message
+
+ QModelIndex sourceIndex = m_sortedContextsModel->mapToSource(sortedIndex);
+ if (m_messageModel->parent(currentMessageIndex()).row() == sourceIndex.row())
+ return;
+
+ QModelIndex contextIndex = setMessageViewRoot(sourceIndex);
+ const QModelIndex &firstChild =
+ m_sortedMessagesModel->index(0, sourceIndex.column(), contextIndex);
+ m_messageView->setCurrentIndex(firstChild);
+ } else if (oldIndex.isValid()) {
+ m_contextView->setCurrentIndex(oldIndex);
+ }
+}
+
+/*
+ * Updates the message displayed in the message editor and related actions.
+ */
+void MainWindow::selectedMessageChanged(const QModelIndex &sortedIndex, const QModelIndex &oldIndex)
+{
+ // Keep a valid selection whenever possible
+ if (!sortedIndex.isValid() && oldIndex.isValid()) {
+ m_messageView->setCurrentIndex(oldIndex);
+ return;
+ }
+
+ QModelIndex index = m_sortedMessagesModel->mapToSource(sortedIndex);
+ if (index.isValid()) {
+ int model = (index.column() && (index.column() - 1 < m_dataModel->modelCount())) ?
+ index.column() - 1 : m_currentIndex.model();
+ m_currentIndex = m_messageModel->dataIndex(index, model);
+ m_messageEditor->showMessage(m_currentIndex);
+ MessageItem *m = 0;
+ if (model >= 0 && (m = m_dataModel->messageItem(m_currentIndex))) {
+ if (m_dataModel->isModelWritable(model) && !m->isObsolete())
+ m_phraseView->setSourceText(m_currentIndex.model(), m->text());
+ else
+ m_phraseView->setSourceText(-1, QString());
+ } else {
+ if (model < 0) {
+ model = m_dataModel->multiContextItem(m_currentIndex.context())
+ ->firstNonobsoleteMessageIndex(m_currentIndex.message());
+ if (model >= 0)
+ m = m_dataModel->messageItem(m_currentIndex, model);
+ }
+ m_phraseView->setSourceText(-1, QString());
+ }
+ if (m && !m->fileName().isEmpty()) {
+ if (hasFormPreview(m->fileName())) {
+ m_sourceAndFormView->setCurrentWidget(m_formPreviewView);
+ m_formPreviewView->setSourceContext(model, m);
+ } else {
+ m_sourceAndFormView->setCurrentWidget(m_sourceCodeView);
+ QDir dir = QFileInfo(m_dataModel->srcFileName(model)).dir();
+ QString fileName = QDir::cleanPath(dir.absoluteFilePath(m->fileName()));
+ m_sourceCodeView->setSourceContext(fileName, m->lineNumber());
+ }
+ m_errorsView->setEnabled(true);
+ } else {
+ m_sourceAndFormView->setCurrentWidget(m_sourceCodeView);
+ m_sourceCodeView->setSourceContext(QString(), 0);
+ m_errorsView->setEnabled(false);
+ }
+ updateDanger(m_currentIndex, true);
+ } else {
+ m_currentIndex = MultiDataIndex();
+ m_messageEditor->showNothing();
+ m_phraseView->setSourceText(-1, QString());
+ m_sourceAndFormView->setCurrentWidget(m_sourceCodeView);
+ m_sourceCodeView->setSourceContext(QString(), 0);
+ }
+
+ updatePhraseBookActions();
+ m_ui.actionSelectAll->setEnabled(index.isValid());
+}
+
+void MainWindow::translationChanged(const MultiDataIndex &index)
+{
+ // We get that as a result of batch translation or search & translate,
+ // so the current model is known to match.
+ if (index != m_currentIndex)
+ return;
+
+ m_messageEditor->showMessage(index);
+ updateDanger(index, true);
+
+ MessageItem *m = m_dataModel->messageItem(index);
+ if (hasFormPreview(m->fileName()))
+ m_formPreviewView->setSourceContext(index.model(), m);
+}
+
+// This and the following function operate directly on the messageitem,
+// so the model does not emit modification notifications.
+void MainWindow::updateTranslation(const QStringList &translations)
+{
+ MessageItem *m = m_dataModel->messageItem(m_currentIndex);
+ if (!m)
+ return;
+ if (translations == m->translations())
+ return;
+
+ m->setTranslations(translations);
+ if (!m->fileName().isEmpty() && hasFormPreview(m->fileName()))
+ m_formPreviewView->setSourceContext(m_currentIndex.model(), m);
+ updateDanger(m_currentIndex, true);
+
+ if (m->isFinished())
+ m_dataModel->setFinished(m_currentIndex, false);
+ else
+ m_dataModel->setModified(m_currentIndex.model(), true);
+}
+
+void MainWindow::updateTranslatorComment(const QString &comment)
+{
+ MessageItem *m = m_dataModel->messageItem(m_currentIndex);
+ if (!m)
+ return;
+ if (comment == m->translatorComment())
+ return;
+
+ m->setTranslatorComment(comment);
+
+ m_dataModel->setModified(m_currentIndex.model(), true);
+}
+
+void MainWindow::refreshItemViews()
+{
+ m_messageModel->blockSignals(false);
+ m_contextView->update();
+ m_messageView->update();
+ setWindowModified(m_dataModel->isModified());
+ m_modifiedLabel->setVisible(m_dataModel->isModified());
+ updateStatistics();
+}
+
+void MainWindow::doneAndNext()
+{
+ int model = m_messageEditor->activeModel();
+ if (model >= 0 && m_dataModel->isModelWritable(model))
+ m_dataModel->setFinished(m_currentIndex, true);
+
+ if (!m_messageEditor->focusNextUnfinished())
+ nextUnfinished();
+}
+
+void MainWindow::toggleFinished(const QModelIndex &index)
+{
+ if (!index.isValid() || index.column() - 1 >= m_dataModel->modelCount()
+ || !m_dataModel->isModelWritable(index.column() - 1) || index.parent() == QModelIndex())
+ return;
+
+ QModelIndex item = m_sortedMessagesModel->mapToSource(index);
+ MultiDataIndex dataIndex = m_messageModel->dataIndex(item);
+ MessageItem *m = m_dataModel->messageItem(dataIndex);
+
+ if (!m || m->message().type() == TranslatorMessage::Obsolete)
+ return;
+
+ m_dataModel->setFinished(dataIndex, !m->isFinished());
+}
+
+/*
+ * Receives a context index in the sorted messages model and returns the next
+ * logical context index in the same model, based on the sort order of the
+ * contexts in the sorted contexts model.
+ */
+QModelIndex MainWindow::nextContext(const QModelIndex &index) const
+{
+ QModelIndex sortedContextIndex = m_sortedContextsModel->mapFromSource(
+ m_sortedMessagesModel->mapToSource(index));
+
+ int nextRow = sortedContextIndex.row() + 1;
+ if (nextRow >= m_sortedContextsModel->rowCount())
+ nextRow = 0;
+ sortedContextIndex = m_sortedContextsModel->index(nextRow, index.column());
+
+ return m_sortedMessagesModel->mapFromSource(
+ m_sortedContextsModel->mapToSource(sortedContextIndex));
+}
+
+/*
+ * See nextContext.
+ */
+QModelIndex MainWindow::prevContext(const QModelIndex &index) const
+{
+ QModelIndex sortedContextIndex = m_sortedContextsModel->mapFromSource(
+ m_sortedMessagesModel->mapToSource(index));
+
+ int prevRow = sortedContextIndex.row() - 1;
+ if (prevRow < 0) prevRow = m_sortedContextsModel->rowCount() - 1;
+ sortedContextIndex = m_sortedContextsModel->index(prevRow, index.column());
+
+ return m_sortedMessagesModel->mapFromSource(
+ m_sortedContextsModel->mapToSource(sortedContextIndex));
+}
+
+QModelIndex MainWindow::nextMessage(const QModelIndex &currentIndex, bool checkUnfinished) const
+{
+ QModelIndex idx = currentIndex.isValid() ? currentIndex : m_sortedMessagesModel->index(0, 0);
+ do {
+ int row = 0;
+ QModelIndex par = idx.parent();
+ if (par.isValid()) {
+ row = idx.row() + 1;
+ } else { // In case we are located on a top-level node
+ par = idx;
+ }
+
+ if (row >= m_sortedMessagesModel->rowCount(par)) {
+ par = nextContext(par);
+ row = 0;
+ }
+ idx = m_sortedMessagesModel->index(row, idx.column(), par);
+
+ if (!checkUnfinished)
+ return idx;
+
+ QModelIndex item = m_sortedMessagesModel->mapToSource(idx);
+ MultiDataIndex index = m_messageModel->dataIndex(item, -1);
+ if (m_dataModel->multiMessageItem(index)->isUnfinished())
+ return idx;
+ } while (idx != currentIndex);
+ return QModelIndex();
+}
+
+QModelIndex MainWindow::prevMessage(const QModelIndex &currentIndex, bool checkUnfinished) const
+{
+ QModelIndex idx = currentIndex.isValid() ? currentIndex : m_sortedMessagesModel->index(0, 0);
+ do {
+ int row = idx.row() - 1;
+ QModelIndex par = idx.parent();
+ if (!par.isValid()) { // In case we are located on a top-level node
+ par = idx;
+ row = -1;
+ }
+
+ if (row < 0) {
+ par = prevContext(par);
+ row = m_sortedMessagesModel->rowCount(par) - 1;
+ }
+ idx = m_sortedMessagesModel->index(row, idx.column(), par);
+
+ if (!checkUnfinished)
+ return idx;
+
+ QModelIndex item = m_sortedMessagesModel->mapToSource(idx);
+ MultiDataIndex index = m_messageModel->dataIndex(item, -1);
+ if (m_dataModel->multiMessageItem(index)->isUnfinished())
+ return idx;
+ } while (idx != currentIndex);
+ return QModelIndex();
+}
+
+void MainWindow::nextUnfinished()
+{
+ if (m_ui.actionNextUnfinished->isEnabled()) {
+ if (!next(true)) {
+ // If no Unfinished message is left, the user has finished the job. We
+ // congratulate on a job well done with this ringing bell.
+ statusBar()->showMessage(tr("No untranslated translation units left."), MessageMS);
+ qApp->beep();
+ }
+ }
+}
+
+void MainWindow::prevUnfinished()
+{
+ if (m_ui.actionNextUnfinished->isEnabled()) {
+ if (!prev(true)) {
+ // If no Unfinished message is left, the user has finished the job. We
+ // congratulate on a job well done with this ringing bell.
+ statusBar()->showMessage(tr("No untranslated translation units left."), MessageMS);
+ qApp->beep();
+ }
+ }
+}
+
+void MainWindow::prev()
+{
+ prev(false);
+}
+
+void MainWindow::next()
+{
+ next(false);
+}
+
+bool MainWindow::prev(bool checkUnfinished)
+{
+ QModelIndex index = prevMessage(m_messageView->currentIndex(), checkUnfinished);
+ if (index.isValid())
+ setCurrentMessage(m_sortedMessagesModel->mapToSource(index));
+ if (checkUnfinished)
+ m_messageEditor->setUnfinishedEditorFocus();
+ else
+ m_messageEditor->setEditorFocus();
+ return index.isValid();
+}
+
+bool MainWindow::next(bool checkUnfinished)
+{
+ QModelIndex index = nextMessage(m_messageView->currentIndex(), checkUnfinished);
+ if (index.isValid())
+ setCurrentMessage(m_sortedMessagesModel->mapToSource(index));
+ if (checkUnfinished)
+ m_messageEditor->setUnfinishedEditorFocus();
+ else
+ m_messageEditor->setEditorFocus();
+ return index.isValid();
+}
+
+void MainWindow::findNext(const QString &text, DataModel::FindLocation where, bool matchCase, bool ignoreAccelerators)
+{
+ if (text.isEmpty())
+ return;
+ m_findText = text;
+ m_findWhere = where;
+ m_findMatchCase = matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ m_findIgnoreAccelerators = ignoreAccelerators;
+ m_ui.actionFindNext->setEnabled(true);
+ findAgain();
+}
+
+void MainWindow::revalidate()
+{
+ for (MultiDataModelIterator it(m_dataModel, -1); it.isValid(); ++it)
+ updateDanger(it, false);
+
+ if (m_currentIndex.isValid())
+ updateDanger(m_currentIndex, true);
+}
+
+QString MainWindow::friendlyString(const QString& str)
+{
+ QString f = str.toLower();
+ f.replace(QRegExp(QString(QLatin1String("[.,:;!?()-]"))), QString(QLatin1String(" ")));
+ f.remove(QLatin1Char('&'));
+ return f.simplified();
+}
+
+static inline void setThemeIcon(QAction *action, const char *name, const char *fallback)
+{
+ const QIcon fallbackIcon(MainWindow::resourcePrefix() + QLatin1String(fallback));
+#ifdef Q_WS_X11
+ action->setIcon(QIcon::fromTheme(QLatin1String(name), fallbackIcon));
+#else
+ Q_UNUSED(name)
+ action->setIcon(fallbackIcon);
+#endif
+}
+
+void MainWindow::setupMenuBar()
+{
+ // There are no fallback icons for these
+#ifdef Q_WS_X11
+ m_ui.menuRecentlyOpenedFiles->setIcon(QIcon::fromTheme(QLatin1String("document-open-recent")));
+ m_ui.actionCloseAll->setIcon(QIcon::fromTheme(QLatin1String("window-close")));
+ m_ui.actionExit->setIcon(QIcon::fromTheme(QLatin1String("application-exit")));
+ m_ui.actionSelectAll->setIcon(QIcon::fromTheme(QLatin1String("edit-select-all")));
+#endif
+
+ // Prefer theme icons when available for these actions
+ setThemeIcon(m_ui.actionOpen, "document-open", "/fileopen.png");
+ setThemeIcon(m_ui.actionOpenAux, "document-open", "/fileopen.png");
+ setThemeIcon(m_ui.actionSave, "document-save", "/filesave.png");
+ setThemeIcon(m_ui.actionSaveAll, "document-save", "/filesave.png");
+ setThemeIcon(m_ui.actionPrint, "document-print", "/print.png");
+ setThemeIcon(m_ui.actionRedo, "edit-redo", "/redo.png");
+ setThemeIcon(m_ui.actionUndo, "edit-undo", "/undo.png");
+ setThemeIcon(m_ui.actionCut, "edit-cut", "/editcut.png");
+ setThemeIcon(m_ui.actionCopy, "edit-copy", "/editcopy.png");
+ setThemeIcon(m_ui.actionPaste, "edit-paste", "/editpaste.png");
+ setThemeIcon(m_ui.actionFind, "edit-find", "/searchfind.png");
+
+ // No well defined theme icons for these actions
+ m_ui.actionAccelerators->setIcon(QIcon(resourcePrefix() + QLatin1String("/accelerator.png")));
+ m_ui.actionOpenPhraseBook->setIcon(QIcon(resourcePrefix() + QLatin1String("/book.png")));
+ m_ui.actionDoneAndNext->setIcon(QIcon(resourcePrefix() + QLatin1String("/doneandnext.png")));
+ m_ui.actionNext->setIcon(QIcon(resourcePrefix() + QLatin1String("/next.png")));
+ m_ui.actionNextUnfinished->setIcon(QIcon(resourcePrefix() + QLatin1String("/nextunfinished.png")));
+ m_ui.actionPhraseMatches->setIcon(QIcon(resourcePrefix() + QLatin1String("/phrase.png")));
+ m_ui.actionEndingPunctuation->setIcon(QIcon(resourcePrefix() + QLatin1String("/punctuation.png")));
+ m_ui.actionPrev->setIcon(QIcon(resourcePrefix() + QLatin1String("/prev.png")));
+ m_ui.actionPrevUnfinished->setIcon(QIcon(resourcePrefix() + QLatin1String("/prevunfinished.png")));
+ m_ui.actionPlaceMarkerMatches->setIcon(QIcon(resourcePrefix() + QLatin1String("/validateplacemarkers.png")));
+ m_ui.actionWhatsThis->setIcon(QIcon(resourcePrefix() + QLatin1String("/whatsthis.png")));
+
+ // File menu
+ connect(m_ui.menuFile, SIGNAL(aboutToShow()), SLOT(fileAboutToShow()));
+ connect(m_ui.actionOpen, SIGNAL(triggered()), this, SLOT(open()));
+ connect(m_ui.actionOpenAux, SIGNAL(triggered()), this, SLOT(openAux()));
+ connect(m_ui.actionSaveAll, SIGNAL(triggered()), this, SLOT(saveAll()));
+ connect(m_ui.actionSave, SIGNAL(triggered()), this, SLOT(save()));
+ connect(m_ui.actionSaveAs, SIGNAL(triggered()), this, SLOT(saveAs()));
+ connect(m_ui.actionReleaseAll, SIGNAL(triggered()), this, SLOT(releaseAll()));
+ connect(m_ui.actionRelease, SIGNAL(triggered()), this, SLOT(release()));
+ connect(m_ui.actionReleaseAs, SIGNAL(triggered()), this, SLOT(releaseAs()));
+ connect(m_ui.actionPrint, SIGNAL(triggered()), this, SLOT(print()));
+ connect(m_ui.actionClose, SIGNAL(triggered()), this, SLOT(closeFile()));
+ connect(m_ui.actionCloseAll, SIGNAL(triggered()), this, SLOT(closeAll()));
+ connect(m_ui.actionExit, SIGNAL(triggered()), this, SLOT(close()));
+
+ // Edit menu
+ connect(m_ui.menuEdit, SIGNAL(aboutToShow()), SLOT(editAboutToShow()));
+
+ connect(m_ui.actionUndo, SIGNAL(triggered()), m_messageEditor, SLOT(undo()));
+ connect(m_messageEditor, SIGNAL(undoAvailable(bool)), m_ui.actionUndo, SLOT(setEnabled(bool)));
+
+ connect(m_ui.actionRedo, SIGNAL(triggered()), m_messageEditor, SLOT(redo()));
+ connect(m_messageEditor, SIGNAL(redoAvailable(bool)), m_ui.actionRedo, SLOT(setEnabled(bool)));
+
+ connect(m_ui.actionCopy, SIGNAL(triggered()), m_messageEditor, SLOT(copy()));
+ connect(m_messageEditor, SIGNAL(copyAvailable(bool)), m_ui.actionCopy, SLOT(setEnabled(bool)));
+
+ connect(m_messageEditor, SIGNAL(cutAvailable(bool)), m_ui.actionCut, SLOT(setEnabled(bool)));
+ connect(m_ui.actionCut, SIGNAL(triggered()), m_messageEditor, SLOT(cut()));
+
+ connect(m_messageEditor, SIGNAL(pasteAvailable(bool)), m_ui.actionPaste, SLOT(setEnabled(bool)));
+ connect(m_ui.actionPaste, SIGNAL(triggered()), m_messageEditor, SLOT(paste()));
+
+ connect(m_ui.actionSelectAll, SIGNAL(triggered()), m_messageEditor, SLOT(selectAll()));
+ connect(m_ui.actionFind, SIGNAL(triggered()), m_findDialog, SLOT(find()));
+ connect(m_ui.actionFindNext, SIGNAL(triggered()), this, SLOT(findAgain()));
+ connect(m_ui.actionSearchAndTranslate, SIGNAL(triggered()), this, SLOT(showTranslateDialog()));
+ connect(m_ui.actionBatchTranslation, SIGNAL(triggered()), this, SLOT(showBatchTranslateDialog()));
+ connect(m_ui.actionTranslationFileSettings, SIGNAL(triggered()), this, SLOT(showTranslationSettings()));
+
+ connect(m_batchTranslateDialog, SIGNAL(finished()), SLOT(refreshItemViews()));
+
+ // Translation menu
+ // when updating the accelerators, remember the status bar
+ connect(m_ui.actionPrevUnfinished, SIGNAL(triggered()), this, SLOT(prevUnfinished()));
+ connect(m_ui.actionNextUnfinished, SIGNAL(triggered()), this, SLOT(nextUnfinished()));
+ connect(m_ui.actionNext, SIGNAL(triggered()), this, SLOT(next()));
+ connect(m_ui.actionPrev, SIGNAL(triggered()), this, SLOT(prev()));
+ connect(m_ui.actionDoneAndNext, SIGNAL(triggered()), this, SLOT(doneAndNext()));
+ connect(m_ui.actionBeginFromSource, SIGNAL(triggered()), m_messageEditor, SLOT(beginFromSource()));
+ connect(m_messageEditor, SIGNAL(beginFromSourceAvailable(bool)), m_ui.actionBeginFromSource, SLOT(setEnabled(bool)));
+
+ // Phrasebook menu
+ connect(m_ui.actionNewPhraseBook, SIGNAL(triggered()), this, SLOT(newPhraseBook()));
+ connect(m_ui.actionOpenPhraseBook, SIGNAL(triggered()), this, SLOT(openPhraseBook()));
+ connect(m_ui.menuClosePhraseBook, SIGNAL(triggered(QAction*)),
+ this, SLOT(closePhraseBook(QAction*)));
+ connect(m_ui.menuEditPhraseBook, SIGNAL(triggered(QAction*)),
+ this, SLOT(editPhraseBook(QAction*)));
+ connect(m_ui.menuPrintPhraseBook, SIGNAL(triggered(QAction*)),
+ this, SLOT(printPhraseBook(QAction*)));
+ connect(m_ui.actionAddToPhraseBook, SIGNAL(triggered()), this, SLOT(addToPhraseBook()));
+
+ // Validation menu
+ connect(m_ui.actionAccelerators, SIGNAL(triggered()), this, SLOT(revalidate()));
+ connect(m_ui.actionEndingPunctuation, SIGNAL(triggered()), this, SLOT(revalidate()));
+ connect(m_ui.actionPhraseMatches, SIGNAL(triggered()), this, SLOT(revalidate()));
+ connect(m_ui.actionPlaceMarkerMatches, SIGNAL(triggered()), this, SLOT(revalidate()));
+
+ // View menu
+ connect(m_ui.actionResetSorting, SIGNAL(triggered()), this, SLOT(resetSorting()));
+ connect(m_ui.actionDisplayGuesses, SIGNAL(triggered()), m_phraseView, SLOT(toggleGuessing()));
+ connect(m_ui.actionStatistics, SIGNAL(triggered()), this, SLOT(toggleStatistics()));
+ connect(m_ui.menuView, SIGNAL(aboutToShow()), this, SLOT(updateViewMenu()));
+ m_ui.menuViewViews->addAction(m_contextDock->toggleViewAction());
+ m_ui.menuViewViews->addAction(m_messagesDock->toggleViewAction());
+ m_ui.menuViewViews->addAction(m_phrasesDock->toggleViewAction());
+ m_ui.menuViewViews->addAction(m_sourceAndFormDock->toggleViewAction());
+ m_ui.menuViewViews->addAction(m_errorsDock->toggleViewAction());
+
+#if defined(Q_WS_MAC)
+ // Window menu
+ QMenu *windowMenu = new QMenu(tr("&Window"), this);
+ menuBar()->insertMenu(m_ui.menuHelp->menuAction(), windowMenu);
+ windowMenu->addAction(tr("Minimize"), this,
+ SLOT(showMinimized()), QKeySequence(tr("Ctrl+M")));
+#endif
+
+ // Help
+ connect(m_ui.actionManual, SIGNAL(triggered()), this, SLOT(manual()));
+ connect(m_ui.actionAbout, SIGNAL(triggered()), this, SLOT(about()));
+ connect(m_ui.actionAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt()));
+ connect(m_ui.actionWhatsThis, SIGNAL(triggered()), this, SLOT(onWhatsThis()));
+
+ connect(m_ui.menuRecentlyOpenedFiles, SIGNAL(triggered(QAction*)), this,
+ SLOT(recentFileActivated(QAction*)));
+
+ m_ui.actionManual->setWhatsThis(tr("Display the manual for %1.").arg(tr("Qt Linguist")));
+ m_ui.actionAbout->setWhatsThis(tr("Display information about %1.").arg(tr("Qt Linguist")));
+ m_ui.actionDoneAndNext->setShortcuts(QList<QKeySequence>()
+ << QKeySequence(QLatin1String("Ctrl+Return"))
+ << QKeySequence(QLatin1String("Ctrl+Enter")));
+
+ // Disable the Close/Edit/Print phrasebook menuitems if they are not loaded
+ connect(m_ui.menuPhrases, SIGNAL(aboutToShow()), this, SLOT(setupPhrase()));
+
+ connect(m_ui.menuRecentlyOpenedFiles, SIGNAL(aboutToShow()), SLOT(setupRecentFilesMenu()));
+}
+
+void MainWindow::updateActiveModel(int model)
+{
+ if (model >= 0)
+ updateLatestModel(model);
+}
+
+// Arriving here implies that the messageEditor does not have focus
+void MainWindow::updateLatestModel(const QModelIndex &index)
+{
+ if (index.column() && (index.column() - 1 < m_dataModel->modelCount()))
+ updateLatestModel(index.column() - 1);
+}
+
+void MainWindow::updateLatestModel(int model)
+{
+ m_currentIndex = MultiDataIndex(model, m_currentIndex.context(), m_currentIndex.message());
+ bool enable = false;
+ bool enableRw = false;
+ if (model >= 0) {
+ enable = true;
+ if (m_dataModel->isModelWritable(model))
+ enableRw = true;
+
+ if (m_currentIndex.isValid()) {
+ if (MessageItem *item = m_dataModel->messageItem(m_currentIndex)) {
+ if (!item->fileName().isEmpty() && hasFormPreview(item->fileName()))
+ m_formPreviewView->setSourceContext(model, item);
+ if (enableRw && !item->isObsolete())
+ m_phraseView->setSourceText(model, item->text());
+ else
+ m_phraseView->setSourceText(-1, QString());
+ } else {
+ m_phraseView->setSourceText(-1, QString());
+ }
+ }
+ }
+ m_ui.actionSave->setEnabled(enableRw);
+ m_ui.actionSaveAs->setEnabled(enableRw);
+ m_ui.actionRelease->setEnabled(enableRw);
+ m_ui.actionReleaseAs->setEnabled(enableRw);
+ m_ui.actionClose->setEnabled(enable);
+ m_ui.actionTranslationFileSettings->setEnabled(enableRw);
+ m_ui.actionSearchAndTranslate->setEnabled(enableRw);
+ // cut & paste - edit only
+ updatePhraseBookActions();
+ updateStatistics();
+}
+
+// Note for *AboutToShow: Due to the delayed nature, only actions without shortcuts
+// and representations outside the menu may be setEnabled()/setVisible() here.
+
+void MainWindow::fileAboutToShow()
+{
+ if (m_fileActiveModel != m_currentIndex.model()) {
+ // We rename the actions so the shortcuts need not be reassigned.
+ bool en;
+ if (m_dataModel->modelCount() > 1) {
+ if (m_currentIndex.model() >= 0) {
+ QString fn = QFileInfo(m_dataModel->srcFileName(m_currentIndex.model())).baseName();
+ m_ui.actionSave->setText(tr("&Save '%1'").arg(fn));
+ m_ui.actionSaveAs->setText(tr("Save '%1' &As...").arg(fn));
+ m_ui.actionRelease->setText(tr("Release '%1'").arg(fn));
+ m_ui.actionReleaseAs->setText(tr("Release '%1' As...").arg(fn));
+ m_ui.actionClose->setText(tr("&Close '%1'").arg(fn));
+ } else {
+ m_ui.actionSave->setText(tr("&Save"));
+ m_ui.actionSaveAs->setText(tr("Save &As..."));
+ m_ui.actionRelease->setText(tr("Release"));
+ m_ui.actionReleaseAs->setText(tr("Release As..."));
+ m_ui.actionClose->setText(tr("&Close"));
+ }
+
+ m_ui.actionSaveAll->setText(tr("Save All"));
+ m_ui.actionReleaseAll->setText(tr("&Release All"));
+ m_ui.actionCloseAll->setText(tr("Close All"));
+ en = true;
+ } else {
+ m_ui.actionSaveAs->setText(tr("Save &As..."));
+ m_ui.actionReleaseAs->setText(tr("Release As..."));
+
+ m_ui.actionSaveAll->setText(tr("&Save"));
+ m_ui.actionReleaseAll->setText(tr("&Release"));
+ m_ui.actionCloseAll->setText(tr("&Close"));
+ en = false;
+ }
+ m_ui.actionSave->setVisible(en);
+ m_ui.actionRelease->setVisible(en);
+ m_ui.actionClose->setVisible(en);
+ m_fileActiveModel = m_currentIndex.model();
+ }
+}
+
+void MainWindow::editAboutToShow()
+{
+ if (m_editActiveModel != m_currentIndex.model()) {
+ if (m_currentIndex.model() >= 0 && m_dataModel->modelCount() > 1) {
+ QString fn = QFileInfo(m_dataModel->srcFileName(m_currentIndex.model())).baseName();
+ m_ui.actionTranslationFileSettings->setText(tr("Translation File &Settings for '%1'...").arg(fn));
+ m_ui.actionBatchTranslation->setText(tr("&Batch Translation of '%1'...").arg(fn));
+ m_ui.actionSearchAndTranslate->setText(tr("Search And &Translate in '%1'...").arg(fn));
+ } else {
+ m_ui.actionTranslationFileSettings->setText(tr("Translation File &Settings..."));
+ m_ui.actionBatchTranslation->setText(tr("&Batch Translation..."));
+ m_ui.actionSearchAndTranslate->setText(tr("Search And &Translate..."));
+ }
+ m_editActiveModel = m_currentIndex.model();
+ }
+}
+
+void MainWindow::updateViewMenu()
+{
+ bool check = m_statistics ? m_statistics->isVisible() : false;
+ m_ui.actionStatistics->setChecked(check);
+}
+
+void MainWindow::showContextDock()
+{
+ m_contextDock->show();
+ m_contextDock->raise();
+}
+
+void MainWindow::showMessagesDock()
+{
+ m_messagesDock->show();
+ m_messagesDock->raise();
+}
+
+void MainWindow::showPhrasesDock()
+{
+ m_phrasesDock->show();
+ m_phrasesDock->raise();
+}
+
+void MainWindow::showSourceCodeDock()
+{
+ m_sourceAndFormDock->show();
+ m_sourceAndFormDock->raise();
+}
+
+void MainWindow::showErrorDock()
+{
+ m_errorsDock->show();
+ m_errorsDock->raise();
+}
+
+void MainWindow::onWhatsThis()
+{
+ QWhatsThis::enterWhatsThisMode();
+}
+
+void MainWindow::setupToolBars()
+{
+ QToolBar *filet = new QToolBar(this);
+ filet->setObjectName(QLatin1String("FileToolbar"));
+ filet->setWindowTitle(tr("File"));
+ this->addToolBar(filet);
+ m_ui.menuToolbars->addAction(filet->toggleViewAction());
+
+ QToolBar *editt = new QToolBar(this);
+ editt->setVisible(false);
+ editt->setObjectName(QLatin1String("EditToolbar"));
+ editt->setWindowTitle(tr("Edit"));
+ this->addToolBar(editt);
+ m_ui.menuToolbars->addAction(editt->toggleViewAction());
+
+ QToolBar *translationst = new QToolBar(this);
+ translationst->setObjectName(QLatin1String("TranslationToolbar"));
+ translationst->setWindowTitle(tr("Translation"));
+ this->addToolBar(translationst);
+ m_ui.menuToolbars->addAction(translationst->toggleViewAction());
+
+ QToolBar *validationt = new QToolBar(this);
+ validationt->setObjectName(QLatin1String("ValidationToolbar"));
+ validationt->setWindowTitle(tr("Validation"));
+ this->addToolBar(validationt);
+ m_ui.menuToolbars->addAction(validationt->toggleViewAction());
+
+ QToolBar *helpt = new QToolBar(this);
+ helpt->setVisible(false);
+ helpt->setObjectName(QLatin1String("HelpToolbar"));
+ helpt->setWindowTitle(tr("Help"));
+ this->addToolBar(helpt);
+ m_ui.menuToolbars->addAction(helpt->toggleViewAction());
+
+
+ filet->addAction(m_ui.actionOpen);
+ filet->addAction(m_ui.actionSaveAll);
+ filet->addAction(m_ui.actionPrint);
+ filet->addSeparator();
+ filet->addAction(m_ui.actionOpenPhraseBook);
+
+ editt->addAction(m_ui.actionUndo);
+ editt->addAction(m_ui.actionRedo);
+ editt->addSeparator();
+ editt->addAction(m_ui.actionCut);
+ editt->addAction(m_ui.actionCopy);
+ editt->addAction(m_ui.actionPaste);
+ editt->addSeparator();
+ editt->addAction(m_ui.actionFind);
+
+ translationst->addAction(m_ui.actionPrev);
+ translationst->addAction(m_ui.actionNext);
+ translationst->addAction(m_ui.actionPrevUnfinished);
+ translationst->addAction(m_ui.actionNextUnfinished);
+ translationst->addAction(m_ui.actionDoneAndNext);
+
+ validationt->addAction(m_ui.actionAccelerators);
+ validationt->addAction(m_ui.actionEndingPunctuation);
+ validationt->addAction(m_ui.actionPhraseMatches);
+ validationt->addAction(m_ui.actionPlaceMarkerMatches);
+
+ helpt->addAction(m_ui.actionWhatsThis);
+}
+
+QModelIndex MainWindow::setMessageViewRoot(const QModelIndex &index)
+{
+ const QModelIndex &sortedContextIndex = m_sortedMessagesModel->mapFromSource(index);
+ const QModelIndex &trueContextIndex = m_sortedMessagesModel->index(sortedContextIndex.row(), 0);
+ if (m_messageView->rootIndex() != trueContextIndex)
+ m_messageView->setRootIndex(trueContextIndex);
+ return trueContextIndex;
+}
+
+/*
+ * Updates the selected entries in the context and message views.
+ */
+void MainWindow::setCurrentMessage(const QModelIndex &index)
+{
+ const QModelIndex &contextIndex = m_messageModel->parent(index);
+ if (!contextIndex.isValid())
+ return;
+
+ const QModelIndex &trueIndex = m_messageModel->index(contextIndex.row(), index.column(), QModelIndex());
+ m_settingCurrentMessage = true;
+ m_contextView->setCurrentIndex(m_sortedContextsModel->mapFromSource(trueIndex));
+ m_settingCurrentMessage = false;
+
+ setMessageViewRoot(contextIndex);
+ m_messageView->setCurrentIndex(m_sortedMessagesModel->mapFromSource(index));
+}
+
+void MainWindow::setCurrentMessage(const QModelIndex &index, int model)
+{
+ const QModelIndex &theIndex = m_messageModel->index(index.row(), model + 1, index.parent());
+ setCurrentMessage(theIndex);
+ m_messageEditor->setEditorFocus(model);
+}
+
+QModelIndex MainWindow::currentContextIndex() const
+{
+ return m_sortedContextsModel->mapToSource(m_contextView->currentIndex());
+}
+
+QModelIndex MainWindow::currentMessageIndex() const
+{
+ return m_sortedMessagesModel->mapToSource(m_messageView->currentIndex());
+}
+
+PhraseBook *MainWindow::openPhraseBook(const QString& name)
+{
+ PhraseBook *pb = new PhraseBook();
+ bool langGuessed;
+ if (!pb->load(name, &langGuessed)) {
+ QMessageBox::warning(this, tr("Qt Linguist"),
+ tr("Cannot read from phrase book '%1'.").arg(name));
+ delete pb;
+ return 0;
+ }
+ if (langGuessed) {
+ if (!m_translationSettingsDialog)
+ m_translationSettingsDialog = new TranslationSettingsDialog(this);
+ m_translationSettingsDialog->setPhraseBook(pb);
+ m_translationSettingsDialog->exec();
+ }
+
+ m_phraseBooks.append(pb);
+
+ QAction *a = m_ui.menuClosePhraseBook->addAction(pb->friendlyPhraseBookName());
+ m_phraseBookMenu[PhraseCloseMenu].insert(a, pb);
+ a->setWhatsThis(tr("Close this phrase book."));
+
+ a = m_ui.menuEditPhraseBook->addAction(pb->friendlyPhraseBookName());
+ m_phraseBookMenu[PhraseEditMenu].insert(a, pb);
+ a->setWhatsThis(tr("Enables you to add, modify, or delete"
+ " entries in this phrase book."));
+
+ a = m_ui.menuPrintPhraseBook->addAction(pb->friendlyPhraseBookName());
+ m_phraseBookMenu[PhrasePrintMenu].insert(a, pb);
+ a->setWhatsThis(tr("Print the entries in this phrase book."));
+
+ connect(pb, SIGNAL(listChanged()), this, SLOT(updatePhraseDicts()));
+ updatePhraseDicts();
+ updatePhraseBookActions();
+
+ return pb;
+}
+
+bool MainWindow::savePhraseBook(QString *name, PhraseBook &pb)
+{
+ if (!name->contains(QLatin1Char('.')))
+ *name += QLatin1String(".qph");
+
+ if (!pb.save(*name)) {
+ QMessageBox::warning(this, tr("Qt Linguist"),
+ tr("Cannot create phrase book '%1'.").arg(*name));
+ return false;
+ }
+ return true;
+}
+
+bool MainWindow::maybeSavePhraseBook(PhraseBook *pb)
+{
+ if (pb->isModified())
+ switch (QMessageBox::information(this, tr("Qt Linguist"),
+ tr("Do you want to save phrase book '%1'?").arg(pb->friendlyPhraseBookName()),
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No,
+ QMessageBox::Cancel | QMessageBox::Escape))
+ {
+ case QMessageBox::Cancel:
+ return false;
+ case QMessageBox::Yes:
+ if (!pb->save(pb->fileName()))
+ return false;
+ break;
+ case QMessageBox::No:
+ break;
+ }
+ return true;
+}
+
+bool MainWindow::closePhraseBooks()
+{
+ foreach(PhraseBook *phraseBook, m_phraseBooks)
+ if (!maybeSavePhraseBook(phraseBook))
+ return false;
+ return true;
+}
+
+void MainWindow::updateProgress()
+{
+ int numEditable = m_dataModel->getNumEditable();
+ int numFinished = m_dataModel->getNumFinished();
+ if (!m_dataModel->modelCount())
+ m_progressLabel->setText(QString(QLatin1String(" ")));
+ else
+ m_progressLabel->setText(QString(QLatin1String(" %1/%2 "))
+ .arg(numFinished).arg(numEditable));
+ bool enable = numFinished != numEditable;
+ m_ui.actionPrevUnfinished->setEnabled(enable);
+ m_ui.actionNextUnfinished->setEnabled(enable);
+ m_ui.actionDoneAndNext->setEnabled(enable);
+
+ m_ui.actionPrev->setEnabled(m_dataModel->contextCount() > 0);
+ m_ui.actionNext->setEnabled(m_dataModel->contextCount() > 0);
+}
+
+void MainWindow::updatePhraseBookActions()
+{
+ bool phraseBookLoaded = (m_currentIndex.model() >= 0) && !m_phraseBooks.isEmpty();
+ m_ui.actionBatchTranslation->setEnabled(m_dataModel->contextCount() > 0 && phraseBookLoaded
+ && m_dataModel->isModelWritable(m_currentIndex.model()));
+ m_ui.actionAddToPhraseBook->setEnabled(currentMessageIndex().isValid() && phraseBookLoaded);
+}
+
+void MainWindow::updatePhraseDictInternal(int model)
+{
+ QHash<QString, QList<Phrase *> > &pd = m_phraseDict[model];
+
+ pd.clear();
+ foreach (PhraseBook *pb, m_phraseBooks) {
+ bool before;
+ if (pb->language() != QLocale::C && m_dataModel->language(model) != QLocale::C) {
+ if (pb->language() != m_dataModel->language(model))
+ continue;
+ before = (pb->country() == m_dataModel->model(model)->country());
+ } else {
+ before = false;
+ }
+ foreach (Phrase *p, pb->phrases()) {
+ QString f = friendlyString(p->source());
+ if (f.length() > 0) {
+ f = f.split(QLatin1Char(' ')).first();
+ if (!pd.contains(f)) {
+ pd.insert(f, QList<Phrase *>());
+ }
+ if (before)
+ pd[f].prepend(p);
+ else
+ pd[f].append(p);
+ }
+ }
+ }
+}
+
+void MainWindow::updatePhraseDict(int model)
+{
+ updatePhraseDictInternal(model);
+ m_phraseView->update();
+}
+
+void MainWindow::updatePhraseDicts()
+{
+ for (int i = 0; i < m_phraseDict.size(); ++i)
+ if (!m_dataModel->isModelWritable(i))
+ m_phraseDict[i].clear();
+ else
+ updatePhraseDictInternal(i);
+ revalidate();
+ m_phraseView->update();
+}
+
+static bool haveMnemonic(const QString &str)
+{
+ for (const ushort *p = (ushort *)str.constData();; ) { // Assume null-termination
+ ushort c = *p++;
+ if (!c)
+ break;
+ if (c == '&') {
+ c = *p++;
+ if (!c)
+ return false;
+ // "Nobody" ever really uses these alt-space, and they are highly annoying
+ // because we get a lot of false positives.
+ if (c != '&' && c != ' ' && QChar(c).isPrint()) {
+ const ushort *pp = p;
+ for (; *p < 256 && isalpha(*p); p++) ;
+ if (pp == p || *p != ';')
+ return true;
+ // This looks like a HTML &entity;, so ignore it. As a HTML string
+ // won't contain accels anyway, we can stop scanning here.
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+void MainWindow::updateDanger(const MultiDataIndex &index, bool verbose)
+{
+ MultiDataIndex curIdx = index;
+ m_errorsView->clear();
+
+ QString source;
+ for (int mi = 0; mi < m_dataModel->modelCount(); ++mi) {
+ if (!m_dataModel->isModelWritable(mi))
+ continue;
+ curIdx.setModel(mi);
+ MessageItem *m = m_dataModel->messageItem(curIdx);
+ if (!m || m->isObsolete())
+ continue;
+
+ bool danger = false;
+ if (m->message().isTranslated()) {
+ if (source.isEmpty()) {
+ source = m->pluralText();
+ if (source.isEmpty())
+ source = m->text();
+ }
+ QStringList translations = m->translations();
+
+ // Truncated variants are permitted to be "denormalized"
+ for (int i = 0; i < translations.count(); ++i) {
+ int sep = translations.at(i).indexOf(QChar(Translator::BinaryVariantSeparator));
+ if (sep >= 0)
+ translations[i].truncate(sep);
+ }
+
+ if (m_ui.actionAccelerators->isChecked()) {
+ bool sk = haveMnemonic(source);
+ bool tk = true;
+ for (int i = 0; i < translations.count() && tk; ++i) {
+ tk &= haveMnemonic(translations[i]);
+ }
+
+ if (!sk && tk) {
+ if (verbose)
+ m_errorsView->addError(mi, ErrorsView::SuperfluousAccelerator);
+ danger = true;
+ } else if (sk && !tk) {
+ if (verbose)
+ m_errorsView->addError(mi, ErrorsView::MissingAccelerator);
+ danger = true;
+ }
+ }
+ if (m_ui.actionEndingPunctuation->isChecked()) {
+ bool endingok = true;
+ for (int i = 0; i < translations.count() && endingok; ++i) {
+ endingok &= (ending(source, m_dataModel->sourceLanguage(mi)) ==
+ ending(translations[i], m_dataModel->language(mi)));
+ }
+
+ if (!endingok) {
+ if (verbose)
+ m_errorsView->addError(mi, ErrorsView::PunctuationDiffer);
+ danger = true;
+ }
+ }
+ if (m_ui.actionPhraseMatches->isChecked()) {
+ QString fsource = friendlyString(source);
+ QString ftranslation = friendlyString(translations.first());
+ QStringList lookupWords = fsource.split(QLatin1Char(' '));
+
+ bool phraseFound;
+ foreach (const QString &s, lookupWords) {
+ if (m_phraseDict[mi].contains(s)) {
+ phraseFound = true;
+ foreach (const Phrase *p, m_phraseDict[mi].value(s)) {
+ if (fsource == friendlyString(p->source())) {
+ if (ftranslation.indexOf(friendlyString(p->target())) >= 0) {
+ phraseFound = true;
+ break;
+ } else {
+ phraseFound = false;
+ }
+ }
+ }
+ if (!phraseFound) {
+ if (verbose)
+ m_errorsView->addError(mi, ErrorsView::IgnoredPhrasebook, s);
+ danger = true;
+ }
+ }
+ }
+ }
+
+ if (m_ui.actionPlaceMarkerMatches->isChecked()) {
+ // Stores the occurrence count of the place markers in the map placeMarkerIndexes.
+ // i.e. the occurrence count of %1 is stored at placeMarkerIndexes[1],
+ // count of %2 is stored at placeMarkerIndexes[2] etc.
+ // In the first pass, it counts all place markers in the sourcetext.
+ // In the second pass it (de)counts all place markers in the translation.
+ // When finished, all elements should have returned to a count of 0,
+ // if not there is a mismatch
+ // between place markers in the source text and the translation text.
+ QHash<int, int> placeMarkerIndexes;
+ QString translation;
+ int numTranslations = translations.count();
+ for (int pass = 0; pass < numTranslations + 1; ++pass) {
+ const QChar *uc_begin = source.unicode();
+ const QChar *uc_end = uc_begin + source.length();
+ if (pass >= 1) {
+ translation = translations[pass - 1];
+ uc_begin = translation.unicode();
+ uc_end = uc_begin + translation.length();
+ }
+ const QChar *c = uc_begin;
+ while (c < uc_end) {
+ if (c->unicode() == '%') {
+ const QChar *escape_start = ++c;
+ while (c->isDigit())
+ ++c;
+ const QChar *escape_end = c;
+ bool ok = true;
+ int markerIndex = QString::fromRawData(
+ escape_start, escape_end - escape_start).toInt(&ok);
+ if (ok)
+ placeMarkerIndexes[markerIndex] += (pass == 0 ? numTranslations : -1);
+ }
+ ++c;
+ }
+ }
+
+ foreach (int i, placeMarkerIndexes) {
+ if (i != 0) {
+ if (verbose)
+ m_errorsView->addError(mi, ErrorsView::PlaceMarkersDiffer);
+ danger = true;
+ break;
+ }
+ }
+
+ // Piggy-backed on the general place markers, we check the plural count marker.
+ if (m->message().isPlural()) {
+ for (int i = 0; i < numTranslations; ++i)
+ if (m_dataModel->model(mi)->countRefNeeds().at(i)
+ && !translations[i].contains(QLatin1String("%n"))) {
+ if (verbose)
+ m_errorsView->addError(mi, ErrorsView::NumerusMarkerMissing);
+ danger = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (danger != m->danger())
+ m_dataModel->setDanger(curIdx, danger);
+ }
+
+ if (verbose)
+ statusBar()->showMessage(m_errorsView->firstError());
+}
+
+void MainWindow::readConfig()
+{
+ QSettings config;
+
+ QRect r(pos(), size());
+ restoreGeometry(config.value(settingPath("Geometry/WindowGeometry")).toByteArray());
+ restoreState(config.value(settingPath("MainWindowState")).toByteArray());
+
+ m_ui.actionAccelerators->setChecked(
+ config.value(settingPath("Validators/Accelerator"), true).toBool());
+ m_ui.actionEndingPunctuation->setChecked(
+ config.value(settingPath("Validators/EndingPunctuation"), true).toBool());
+ m_ui.actionPhraseMatches->setChecked(
+ config.value(settingPath("Validators/PhraseMatch"), true).toBool());
+ m_ui.actionPlaceMarkerMatches->setChecked(
+ config.value(settingPath("Validators/PlaceMarkers"), true).toBool());
+ m_ui.actionLengthVariants->setChecked(
+ config.value(settingPath("Options/LengthVariants"), false).toBool());
+
+ recentFiles().readConfig();
+
+ int size = config.beginReadArray(settingPath("OpenedPhraseBooks"));
+ for (int i = 0; i < size; ++i) {
+ config.setArrayIndex(i);
+ openPhraseBook(config.value(QLatin1String("FileName")).toString());
+ }
+ config.endArray();
+}
+
+void MainWindow::writeConfig()
+{
+ QSettings config;
+ config.setValue(settingPath("Geometry/WindowGeometry"),
+ saveGeometry());
+ config.setValue(settingPath("Validators/Accelerator"),
+ m_ui.actionAccelerators->isChecked());
+ config.setValue(settingPath("Validators/EndingPunctuation"),
+ m_ui.actionEndingPunctuation->isChecked());
+ config.setValue(settingPath("Validators/PhraseMatch"),
+ m_ui.actionPhraseMatches->isChecked());
+ config.setValue(settingPath("Validators/PlaceMarkers"),
+ m_ui.actionPlaceMarkerMatches->isChecked());
+ config.setValue(settingPath("Options/LengthVariants"),
+ m_ui.actionLengthVariants->isChecked());
+ config.setValue(settingPath("MainWindowState"),
+ saveState());
+ recentFiles().writeConfig();
+
+ config.beginWriteArray(settingPath("OpenedPhraseBooks"),
+ m_phraseBooks.size());
+ for (int i = 0; i < m_phraseBooks.size(); ++i) {
+ config.setArrayIndex(i);
+ config.setValue(QLatin1String("FileName"), m_phraseBooks.at(i)->fileName());
+ }
+ config.endArray();
+}
+
+void MainWindow::setupRecentFilesMenu()
+{
+ m_ui.menuRecentlyOpenedFiles->clear();
+ foreach (const QStringList &strList, recentFiles().filesLists())
+ if (strList.size() == 1) {
+ const QString &str = strList.first();
+ m_ui.menuRecentlyOpenedFiles->addAction(
+ DataModel::prettifyFileName(str))->setData(str);
+ } else {
+ QMenu *menu = m_ui.menuRecentlyOpenedFiles->addMenu(
+ MultiDataModel::condenseFileNames(
+ MultiDataModel::prettifyFileNames(strList)));
+ menu->addAction(tr("All"))->setData(strList);
+ foreach (const QString &str, strList)
+ menu->addAction(DataModel::prettifyFileName(str))->setData(str);
+ }
+}
+
+void MainWindow::recentFileActivated(QAction *action)
+{
+ openFiles(action->data().toStringList());
+}
+
+void MainWindow::toggleStatistics()
+{
+ if (m_ui.actionStatistics->isChecked()) {
+ if (!m_statistics) {
+ m_statistics = new Statistics(this);
+ connect(m_dataModel, SIGNAL(statsChanged(int,int,int,int,int,int)),
+ m_statistics, SLOT(updateStats(int,int,int,int,int,int)));
+ }
+ m_statistics->show();
+ updateStatistics();
+ }
+ else if (m_statistics) {
+ m_statistics->close();
+ }
+}
+
+void MainWindow::maybeUpdateStatistics(const MultiDataIndex &index)
+{
+ if (index.model() == m_currentIndex.model())
+ updateStatistics();
+}
+
+void MainWindow::updateStatistics()
+{
+ // don't call this if stats dialog is not open
+ // because this can be slow...
+ if (!m_statistics || !m_statistics->isVisible() || m_currentIndex.model() < 0)
+ return;
+
+ m_dataModel->model(m_currentIndex.model())->updateStatistics();
+}
+
+void MainWindow::showTranslationSettings(int model)
+{
+ if (!m_translationSettingsDialog)
+ m_translationSettingsDialog = new TranslationSettingsDialog(this);
+ m_translationSettingsDialog->setDataModel(m_dataModel->model(model));
+ m_translationSettingsDialog->exec();
+}
+
+void MainWindow::showTranslationSettings()
+{
+ showTranslationSettings(m_currentIndex.model());
+}
+
+bool MainWindow::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::DragEnter) {
+ QDragEnterEvent *e = static_cast<QDragEnterEvent*>(event);
+ if (e->mimeData()->hasFormat(QLatin1String("text/uri-list"))) {
+ e->acceptProposedAction();
+ return true;
+ }
+ } else if (event->type() == QEvent::Drop) {
+ QDropEvent *e = static_cast<QDropEvent*>(event);
+ if (!e->mimeData()->hasFormat(QLatin1String("text/uri-list")))
+ return false;
+ QStringList urls;
+ foreach (QUrl url, e->mimeData()->urls())
+ if (!url.toLocalFile().isEmpty())
+ urls << url.toLocalFile();
+ if (!urls.isEmpty())
+ openFiles(urls);
+ e->acceptProposedAction();
+ return true;
+ } else if (event->type() == QEvent::KeyPress) {
+ if (static_cast<QKeyEvent *>(event)->key() == Qt::Key_Escape) {
+ if (object == m_messageEditor)
+ m_messageView->setFocus();
+ else if (object == m_messagesDock)
+ m_contextView->setFocus();
+ }
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/mainwindow.h b/src/linguist/linguist/mainwindow.h
new file mode 100644
index 000000000..fe9daf264
--- /dev/null
+++ b/src/linguist/linguist/mainwindow.h
@@ -0,0 +1,267 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "phrase.h"
+#include "ui_mainwindow.h"
+#include "recentfiles.h"
+#include "messagemodel.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QLocale>
+
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QPixmap;
+class QAction;
+class QDialog;
+class QLabel;
+class QMenu;
+class QPrinter;
+class QProcess;
+class QIcon;
+class QSortFilterProxyModel;
+class QStackedWidget;
+class QTableView;
+class QTreeView;
+
+class BatchTranslationDialog;
+class ErrorsView;
+class FindDialog;
+class FocusWatcher;
+class FormPreviewView;
+class MessageEditor;
+class PhraseView;
+class SourceCodeView;
+class Statistics;
+class TranslateDialog;
+class TranslationSettingsDialog;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ enum {PhraseCloseMenu, PhraseEditMenu, PhrasePrintMenu};
+
+ MainWindow();
+ ~MainWindow();
+
+ bool openFiles(const QStringList &names, bool readWrite = true);
+ static RecentFiles &recentFiles();
+ static const QString &resourcePrefix();
+ static QString friendlyString(const QString &str);
+
+protected:
+ void readConfig();
+ void writeConfig();
+ void closeEvent(QCloseEvent *);
+ bool eventFilter(QObject *object, QEvent *event);
+
+private slots:
+ void doneAndNext();
+ void prev();
+ void next();
+ void recentFileActivated(QAction *action);
+ void setupRecentFilesMenu();
+ void open();
+ void openAux();
+ void saveAll();
+ void save();
+ void saveAs();
+ void releaseAll();
+ void release();
+ void releaseAs();
+ void print();
+ void closeFile();
+ bool closeAll();
+ void findAgain();
+ void showTranslateDialog();
+ void showBatchTranslateDialog();
+ void showTranslationSettings();
+ void updateTranslateHit(bool &hit);
+ void translate(int mode);
+ void newPhraseBook();
+ void openPhraseBook();
+ void closePhraseBook(QAction *action);
+ void editPhraseBook(QAction *action);
+ void printPhraseBook(QAction *action);
+ void addToPhraseBook();
+ void manual();
+ void resetSorting();
+ void about();
+ void aboutQt();
+
+ void updateViewMenu();
+ void fileAboutToShow();
+ void editAboutToShow();
+
+ void showContextDock();
+ void showMessagesDock();
+ void showPhrasesDock();
+ void showSourceCodeDock();
+ void showErrorDock();
+
+ void setupPhrase();
+ bool maybeSaveAll();
+ bool maybeSave(int model);
+ void updateProgress();
+ void maybeUpdateStatistics(const MultiDataIndex &);
+ void translationChanged(const MultiDataIndex &);
+ void updateCaption();
+ void updateLatestModel(const QModelIndex &index);
+ void selectedContextChanged(const QModelIndex &sortedIndex, const QModelIndex &oldIndex);
+ void selectedMessageChanged(const QModelIndex &sortedIndex, const QModelIndex &oldIndex);
+
+ // To synchronize from the message editor to the model ...
+ void updateTranslation(const QStringList &translations);
+ void updateTranslatorComment(const QString &comment);
+
+ void updateActiveModel(int);
+ void refreshItemViews();
+ void toggleFinished(const QModelIndex &index);
+ void prevUnfinished();
+ void nextUnfinished();
+ void findNext(const QString &text, DataModel::FindLocation where, bool matchCase, bool ignoreAccelerators);
+ void revalidate();
+ void toggleStatistics();
+ void onWhatsThis();
+ void updatePhraseDicts();
+ void updatePhraseDict(int model);
+
+private:
+ QModelIndex nextContext(const QModelIndex &index) const;
+ QModelIndex prevContext(const QModelIndex &index) const;
+ QModelIndex nextMessage(const QModelIndex &currentIndex, bool checkUnfinished = false) const;
+ QModelIndex prevMessage(const QModelIndex &currentIndex, bool checkUnfinished = false) const;
+ bool next(bool checkUnfinished);
+ bool prev(bool checkUnfinished);
+
+ void updateStatistics();
+ void initViewHeaders();
+ void modelCountChanged();
+ void setupMenuBar();
+ void setupToolBars();
+ void setCurrentMessage(const QModelIndex &index);
+ void setCurrentMessage(const QModelIndex &index, int model);
+ QModelIndex setMessageViewRoot(const QModelIndex &index);
+ QModelIndex currentContextIndex() const;
+ QModelIndex currentMessageIndex() const;
+ PhraseBook *openPhraseBook(const QString &name);
+ bool isPhraseBookOpen(const QString &name);
+ bool savePhraseBook(QString *name, PhraseBook &pb);
+ bool maybeSavePhraseBook(PhraseBook *phraseBook);
+ bool closePhraseBooks();
+ QStringList pickTranslationFiles();
+ void showTranslationSettings(int model);
+ void updateLatestModel(int model);
+ void updatePhraseBookActions();
+ void updatePhraseDictInternal(int model);
+ void releaseInternal(int model);
+ void saveInternal(int model);
+
+ QPrinter *printer();
+
+ // FIXME: move to DataModel
+ void updateDanger(const MultiDataIndex &index, bool verbose);
+
+ bool searchItem(const QString &searchWhat);
+
+ QProcess *m_assistantProcess;
+ QTreeView *m_contextView;
+ QTreeView *m_messageView;
+ MultiDataModel *m_dataModel;
+ MessageModel *m_messageModel;
+ QSortFilterProxyModel *m_sortedContextsModel;
+ QSortFilterProxyModel *m_sortedMessagesModel;
+ MessageEditor *m_messageEditor;
+ PhraseView *m_phraseView;
+ QStackedWidget *m_sourceAndFormView;
+ SourceCodeView *m_sourceCodeView;
+ FormPreviewView *m_formPreviewView;
+ ErrorsView *m_errorsView;
+ QLabel *m_progressLabel;
+ QLabel *m_modifiedLabel;
+ FocusWatcher *m_focusWatcher;
+ QString m_phraseBookDir;
+ // model : keyword -> list of appropriate phrases in the phrasebooks
+ QList<QHash<QString, QList<Phrase *> > > m_phraseDict;
+ QList<PhraseBook *> m_phraseBooks;
+ QMap<QAction *, PhraseBook *> m_phraseBookMenu[3];
+ QPrinter *m_printer;
+
+ FindDialog *m_findDialog;
+ QString m_findText;
+ Qt::CaseSensitivity m_findMatchCase;
+ bool m_findIgnoreAccelerators;
+ DataModel::FindLocation m_findWhere;
+ DataModel::FindLocation m_foundWhere;
+
+ TranslateDialog *m_translateDialog;
+ QString m_latestFindText;
+ int m_latestCaseSensitivity;
+ int m_remainingCount;
+ int m_hitCount;
+
+ BatchTranslationDialog *m_batchTranslateDialog;
+ TranslationSettingsDialog *m_translationSettingsDialog;
+
+ bool m_settingCurrentMessage;
+ int m_fileActiveModel;
+ int m_editActiveModel;
+ MultiDataIndex m_currentIndex;
+
+ QDockWidget *m_contextDock;
+ QDockWidget *m_messagesDock;
+ QDockWidget *m_phrasesDock;
+ QDockWidget *m_sourceAndFormDock;
+ QDockWidget *m_errorsDock;
+
+ Ui::MainWindow m_ui; // menus and actions
+ Statistics *m_statistics;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/linguist/linguist/mainwindow.ui b/src/linguist/linguist/mainwindow.ui
new file mode 100644
index 000000000..3453740ec
--- /dev/null
+++ b/src/linguist/linguist/mainwindow.ui
@@ -0,0 +1,892 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>673</width>
+ <height>461</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget"/>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>673</width>
+ <height>28</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuPhrases">
+ <property name="title">
+ <string>&amp;Phrases</string>
+ </property>
+ <widget class="QMenu" name="menuClosePhraseBook">
+ <property name="title">
+ <string>&amp;Close Phrase Book</string>
+ </property>
+ </widget>
+ <widget class="QMenu" name="menuEditPhraseBook">
+ <property name="title">
+ <string>&amp;Edit Phrase Book</string>
+ </property>
+ </widget>
+ <widget class="QMenu" name="menuPrintPhraseBook">
+ <property name="title">
+ <string>&amp;Print Phrase Book</string>
+ </property>
+ </widget>
+ <addaction name="actionNewPhraseBook"/>
+ <addaction name="actionOpenPhraseBook"/>
+ <addaction name="menuClosePhraseBook"/>
+ <addaction name="separator"/>
+ <addaction name="menuEditPhraseBook"/>
+ <addaction name="menuPrintPhraseBook"/>
+ <addaction name="actionAddToPhraseBook"/>
+ </widget>
+ <widget class="QMenu" name="menuValidation">
+ <property name="title">
+ <string>V&amp;alidation</string>
+ </property>
+ <addaction name="actionAccelerators"/>
+ <addaction name="actionEndingPunctuation"/>
+ <addaction name="actionPhraseMatches"/>
+ <addaction name="actionPlaceMarkerMatches"/>
+ </widget>
+ <widget class="QMenu" name="menuView">
+ <property name="title">
+ <string>&amp;View</string>
+ </property>
+ <widget class="QMenu" name="menuViewViews">
+ <property name="title">
+ <string>Vie&amp;ws</string>
+ </property>
+ </widget>
+ <widget class="QMenu" name="menuToolbars">
+ <property name="title">
+ <string>&amp;Toolbars</string>
+ </property>
+ </widget>
+ <addaction name="actionResetSorting"/>
+ <addaction name="actionDisplayGuesses"/>
+ <addaction name="actionStatistics"/>
+ <addaction name="actionLengthVariants"/>
+ <addaction name="separator"/>
+ <addaction name="menuToolbars"/>
+ <addaction name="menuViewViews"/>
+ </widget>
+ <widget class="QMenu" name="menuHelp">
+ <property name="title">
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="actionManual"/>
+ <addaction name="actionAbout"/>
+ <addaction name="actionAboutQt"/>
+ <addaction name="actionWhatsThis"/>
+ </widget>
+ <widget class="QMenu" name="menuTranslation">
+ <property name="title">
+ <string>&amp;Translation</string>
+ </property>
+ <addaction name="actionPrevUnfinished"/>
+ <addaction name="actionNextUnfinished"/>
+ <addaction name="actionPrev"/>
+ <addaction name="actionNext"/>
+ <addaction name="actionDoneAndNext"/>
+ <addaction name="actionBeginFromSource"/>
+ </widget>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <widget class="QMenu" name="menuRecentlyOpenedFiles">
+ <property name="title">
+ <string>Recently Opened &amp;Files</string>
+ </property>
+ </widget>
+ <addaction name="actionOpen"/>
+ <addaction name="actionOpenAux"/>
+ <addaction name="menuRecentlyOpenedFiles"/>
+ <addaction name="separator"/>
+ <addaction name="actionSaveAll"/>
+ <addaction name="actionSave"/>
+ <addaction name="actionSaveAs"/>
+ <addaction name="actionReleaseAll"/>
+ <addaction name="actionRelease"/>
+ <addaction name="actionReleaseAs"/>
+ <addaction name="separator"/>
+ <addaction name="actionPrint"/>
+ <addaction name="separator"/>
+ <addaction name="actionCloseAll"/>
+ <addaction name="actionClose"/>
+ <addaction name="separator"/>
+ <addaction name="actionExit"/>
+ </widget>
+ <widget class="QMenu" name="menuEdit">
+ <property name="title">
+ <string>&amp;Edit</string>
+ </property>
+ <addaction name="actionUndo"/>
+ <addaction name="actionRedo"/>
+ <addaction name="separator"/>
+ <addaction name="actionCut"/>
+ <addaction name="actionCopy"/>
+ <addaction name="actionPaste"/>
+ <addaction name="actionSelectAll"/>
+ <addaction name="separator"/>
+ <addaction name="actionFind"/>
+ <addaction name="actionFindNext"/>
+ <addaction name="actionSearchAndTranslate"/>
+ <addaction name="actionBatchTranslation"/>
+ <addaction name="actionTranslationFileSettings"/>
+ </widget>
+ <addaction name="menuFile"/>
+ <addaction name="menuEdit"/>
+ <addaction name="menuTranslation"/>
+ <addaction name="menuValidation"/>
+ <addaction name="menuPhrases"/>
+ <addaction name="menuView"/>
+ <addaction name="menuHelp"/>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ <action name="actionOpen">
+ <property name="text">
+ <string>&amp;Open...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Open a Qt translation source file (TS file) for editing</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionExit">
+ <property name="text">
+ <string>E&amp;xit</string>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string>Close this window and exit.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::QuitRole</enum>
+ </property>
+ </action>
+ <action name="actionSave">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="whatsThis">
+ <string>Save changes made to this Qt translation source file</string>
+ </property>
+ </action>
+ <action name="actionSaveAs">
+ <property name="text">
+ <string>Save &amp;As...</string>
+ </property>
+ <property name="iconText">
+ <string>Save As...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Save changes made to this Qt translation source file into a new file.</string>
+ </property>
+ </action>
+ <action name="actionRelease">
+ <property name="text">
+ <string>Release</string>
+ </property>
+ <property name="whatsThis">
+ <string>Create a Qt message file suitable for released applications from the current message file.</string>
+ </property>
+ </action>
+ <action name="actionPrint">
+ <property name="text">
+ <string>&amp;Print...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Print a list of all the translation units in the current translation source file.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+P</string>
+ </property>
+ </action>
+ <action name="actionUndo">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Undo</string>
+ </property>
+ <property name="whatsThis">
+ <string>Undo the last editing operation performed on the current translation.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Z</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionRedo">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Redo</string>
+ </property>
+ <property name="whatsThis">
+ <string>Redo an undone editing operation performed on the translation.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Y</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionCut">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Cu&amp;t</string>
+ </property>
+ <property name="whatsThis">
+ <string>Copy the selected translation text to the clipboard and deletes it.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+X</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionCopy">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Copy</string>
+ </property>
+ <property name="whatsThis">
+ <string>Copy the selected translation text to the clipboard.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+C</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionPaste">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Paste</string>
+ </property>
+ <property name="whatsThis">
+ <string>Paste the clipboard text into the translation.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+V</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionSelectAll">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Select &amp;All</string>
+ </property>
+ <property name="whatsThis">
+ <string>Select the whole translation text.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+A</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionFind">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Find...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Search for some text in the translation source file.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+F</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionFindNext">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Find &amp;Next</string>
+ </property>
+ <property name="whatsThis">
+ <string>Continue the search where it was left.</string>
+ </property>
+ <property name="shortcut">
+ <string>F3</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionPrevUnfinished">
+ <property name="text">
+ <string>&amp;Prev Unfinished</string>
+ </property>
+ <property name="toolTip">
+ <string>Previous unfinished item</string>
+ </property>
+ <property name="whatsThis">
+ <string>Move to the previous unfinished item.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+K</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionNextUnfinished">
+ <property name="text">
+ <string>&amp;Next Unfinished</string>
+ </property>
+ <property name="toolTip">
+ <string>Next unfinished item</string>
+ </property>
+ <property name="whatsThis">
+ <string>Move to the next unfinished item.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+J</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionPrev">
+ <property name="text">
+ <string>P&amp;rev</string>
+ </property>
+ <property name="toolTip">
+ <string>Move to previous item</string>
+ </property>
+ <property name="whatsThis">
+ <string>Move to the previous item.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+K</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionNext">
+ <property name="text">
+ <string>Ne&amp;xt</string>
+ </property>
+ <property name="toolTip">
+ <string>Next item</string>
+ </property>
+ <property name="whatsThis">
+ <string>Move to the next item.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+J</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionDoneAndNext">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Done and Next</string>
+ </property>
+ <property name="toolTip">
+ <string>Mark item as done and move to the next unfinished item</string>
+ </property>
+ <property name="whatsThis">
+ <string>Mark this item as done and move to the next unfinished item.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionBeginFromSource">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Copy from source text</string>
+ </property>
+ <property name="iconText">
+ <string>Copy from source text</string>
+ </property>
+ <property name="toolTip">
+ <string>Copies the source text into the translation field</string>
+ </property>
+ <property name="whatsThis">
+ <string>Copies the source text into the translation field.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+B</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionAccelerators">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Accelerators</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle the validity check of accelerators</string>
+ </property>
+ <property name="whatsThis">
+ <string>Toggle the validity check of accelerators, i.e. whether the number of ampersands in the source and translation text is the same. If the check fails, a message is shown in the warnings window.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionEndingPunctuation">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Ending Punctuation</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle the validity check of ending punctuation</string>
+ </property>
+ <property name="whatsThis">
+ <string>Toggle the validity check of ending punctuation. If the check fails, a message is shown in the warnings window.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionPhraseMatches">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Phrase matches</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle checking that phrase suggestions are used</string>
+ </property>
+ <property name="whatsThis">
+ <string>Toggle checking that phrase suggestions are used. If the check fails, a message is shown in the warnings window.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionPlaceMarkerMatches">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Place &amp;Marker Matches</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle the validity check of place markers</string>
+ </property>
+ <property name="whatsThis">
+ <string>Toggle the validity check of place markers, i.e. whether %1, %2, ... are used consistently in the source text and translation text. If the check fails, a message is shown in the warnings window.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionNewPhraseBook">
+ <property name="text">
+ <string>&amp;New Phrase Book...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Create a new phrase book.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+N</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionOpenPhraseBook">
+ <property name="text">
+ <string>&amp;Open Phrase Book...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Open a phrase book to assist translation.</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+H</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionResetSorting">
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Reset Sorting</string>
+ </property>
+ <property name="whatsThis">
+ <string>Sort the items back in the same order as in the message file.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionDisplayGuesses">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Display guesses</string>
+ </property>
+ <property name="whatsThis">
+ <string>Set whether or not to display translation guesses.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionStatistics">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Statistics</string>
+ </property>
+ <property name="whatsThis">
+ <string>Display translation statistics.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionManual">
+ <property name="text">
+ <string>&amp;Manual</string>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="shortcut">
+ <string>F1</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionAbout">
+ <property name="text">
+ <string>About Qt Linguist</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::AboutRole</enum>
+ </property>
+ </action>
+ <action name="actionAboutQt">
+ <property name="text">
+ <string>About Qt</string>
+ </property>
+ <property name="whatsThis">
+ <string>Display information about the Qt toolkit by Nokia.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::AboutQtRole</enum>
+ </property>
+ </action>
+ <action name="actionWhatsThis">
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;What's This?</string>
+ </property>
+ <property name="iconText">
+ <string>What's This?</string>
+ </property>
+ <property name="toolTip">
+ <string>What's This?</string>
+ </property>
+ <property name="whatsThis">
+ <string>Enter What's This? mode.</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+F1</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionSearchAndTranslate">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Search And Translate...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Replace the translation on all entries that matches the search source text.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionBatchTranslation">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Batch Translation...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Batch translate all entries using the information in the phrase books.</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionReleaseAs">
+ <property name="text">
+ <string>Release As...</string>
+ </property>
+ <property name="iconText">
+ <string>Release As...</string>
+ </property>
+ <property name="whatsThis">
+ <string>Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the TS file.</string>
+ </property>
+ </action>
+ <action name="actionFile">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>File</string>
+ </property>
+ </action>
+ <action name="actionEdit">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Edit</string>
+ </property>
+ </action>
+ <action name="actionTranslation">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Translation</string>
+ </property>
+ </action>
+ <action name="actionValidation">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Validation</string>
+ </property>
+ </action>
+ <action name="actionHelp">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Help</string>
+ </property>
+ </action>
+ <action name="actionPreviewForm">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Open/Refresh Form &amp;Preview</string>
+ </property>
+ <property name="iconText">
+ <string>Form Preview Tool</string>
+ </property>
+ <property name="toolTip">
+ <string>Form Preview Tool</string>
+ </property>
+ <property name="shortcut">
+ <string>F5</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionTranslationFileSettings">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Translation File &amp;Settings...</string>
+ </property>
+ <property name="menuRole">
+ <enum>QAction::NoRole</enum>
+ </property>
+ </action>
+ <action name="actionAddToPhraseBook">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Add to Phrase Book</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+T</string>
+ </property>
+ </action>
+ <action name="actionOpenAux">
+ <property name="text">
+ <string>Open Read-O&amp;nly...</string>
+ </property>
+ </action>
+ <action name="actionSaveAll">
+ <property name="text">
+ <string>&amp;Save All</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="actionReleaseAll">
+ <property name="text">
+ <string>&amp;Release All</string>
+ </property>
+ </action>
+ <action name="actionClose">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </action>
+ <action name="actionCloseAll">
+ <property name="text">
+ <string>&amp;Close All</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+W</string>
+ </property>
+ </action>
+ <action name="actionLengthVariants">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Length Variants</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/linguist/linguist/messageeditor.cpp b/src/linguist/linguist/messageeditor.cpp
new file mode 100644
index 000000000..3a705c1a7
--- /dev/null
+++ b/src/linguist/linguist/messageeditor.cpp
@@ -0,0 +1,880 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* TRANSLATOR MessageEditor
+
+ This is the right panel of the main window.
+*/
+
+#include "messageeditor.h"
+#include "messageeditorwidgets.h"
+#include "simtexth.h"
+#include "phrasemodel.h"
+
+#include <QApplication>
+#include <QBoxLayout>
+#include <QClipboard>
+#include <QDebug>
+#include <QDockWidget>
+#include <QHeaderView>
+#include <QKeyEvent>
+#include <QMainWindow>
+#include <QPainter>
+#include <QTreeView>
+#include <QVBoxLayout>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef NEVER_TRUE
+// Allow translators to provide localized names for QLocale::languageToString
+// At least the own language should be translated ... This is a "hack" until
+// functionality is provided within Qt (see task 196275).
+static const char * language_strings[] =
+{
+ QT_TRANSLATE_NOOP("MessageEditor", "Russian"),
+ QT_TRANSLATE_NOOP("MessageEditor", "German"),
+ QT_TRANSLATE_NOOP("MessageEditor", "Japanese"),
+ QT_TRANSLATE_NOOP("MessageEditor", "French"),
+ QT_TRANSLATE_NOOP("MessageEditor", "Polish"),
+ QT_TRANSLATE_NOOP("MessageEditor", "Chinese")
+};
+#endif
+
+/*
+ MessageEditor class impl.
+
+ Handles layout of dock windows and the editor page.
+*/
+MessageEditor::MessageEditor(MultiDataModel *dataModel, QMainWindow *parent)
+ : QScrollArea(parent->centralWidget()),
+ m_dataModel(dataModel),
+ m_currentModel(-1),
+ m_currentNumerus(-1),
+ m_lengthVariants(false),
+ m_undoAvail(false),
+ m_redoAvail(false),
+ m_cutAvail(false),
+ m_copyAvail(false),
+ m_selectionHolder(0),
+ m_focusWidget(0)
+{
+ setObjectName(QLatin1String("scroll area"));
+
+ QPalette p;
+ p.setBrush(QPalette::Window, p.brush(QPalette::Active, QPalette::Base));
+ setPalette(p);
+
+ setupEditorPage();
+
+ // Signals
+ connect(qApp->clipboard(), SIGNAL(dataChanged()),
+ SLOT(clipboardChanged()));
+ connect(m_dataModel, SIGNAL(modelAppended()),
+ SLOT(messageModelAppended()));
+ connect(m_dataModel, SIGNAL(modelDeleted(int)),
+ SLOT(messageModelDeleted(int)));
+ connect(m_dataModel, SIGNAL(allModelsDeleted()),
+ SLOT(allModelsDeleted()));
+ connect(m_dataModel, SIGNAL(languageChanged(int)),
+ SLOT(setTargetLanguage(int)));
+
+ m_tabOrderTimer.setSingleShot(true);
+ connect(&m_tabOrderTimer, SIGNAL(timeout()), SLOT(reallyFixTabOrder()));
+
+ clipboardChanged();
+
+ setWhatsThis(tr("This whole panel allows you to view and edit "
+ "the translation of some source text."));
+ showNothing();
+}
+
+void MessageEditor::setupEditorPage()
+{
+ QFrame *editorPage = new QFrame;
+ editorPage->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+
+ m_source = new FormWidget(tr("Source text"), false);
+ m_source->setHideWhenEmpty(true);
+ m_source->setWhatsThis(tr("This area shows the source text."));
+ connect(m_source, SIGNAL(selectionChanged(QTextEdit*)),
+ SLOT(selectionChanged(QTextEdit*)));
+
+ m_pluralSource = new FormWidget(tr("Source text (Plural)"), false);
+ m_pluralSource->setHideWhenEmpty(true);
+ m_pluralSource->setWhatsThis(tr("This area shows the plural form of the source text."));
+ connect(m_pluralSource, SIGNAL(selectionChanged(QTextEdit*)),
+ SLOT(selectionChanged(QTextEdit*)));
+
+ m_commentText = new FormWidget(tr("Developer comments"), false);
+ m_commentText->setHideWhenEmpty(true);
+ m_commentText->setObjectName(QLatin1String("comment/context view"));
+ m_commentText->setWhatsThis(tr("This area shows a comment that"
+ " may guide you, and the context in which the text"
+ " occurs.") );
+
+ QBoxLayout *subLayout = new QVBoxLayout;
+
+ subLayout->setMargin(5);
+ subLayout->addWidget(m_source);
+ subLayout->addWidget(m_pluralSource);
+ subLayout->addWidget(m_commentText);
+
+ m_layout = new QVBoxLayout;
+ m_layout->setSpacing(2);
+ m_layout->setMargin(2);
+ m_layout->addLayout(subLayout);
+ m_layout->addStretch(1);
+ editorPage->setLayout(m_layout);
+
+ setWidget(editorPage);
+ setWidgetResizable(true);
+}
+
+QPalette MessageEditor::paletteForModel(int model) const
+{
+ QBrush brush = m_dataModel->brushForModel(model);
+ QPalette pal;
+
+ if (m_dataModel->isModelWritable(model)) {
+ pal.setBrush(QPalette::Window, brush);
+ } else {
+ QPixmap pm(brush.texture().size());
+ pm.fill();
+ QPainter p(&pm);
+ p.fillRect(brush.texture().rect(), brush);
+ pal.setBrush(QPalette::Window, pm);
+ }
+ return pal;
+}
+
+void MessageEditor::messageModelAppended()
+{
+ int model = m_editors.size();
+ m_editors.append(MessageEditorData());
+ MessageEditorData &ed = m_editors.last();
+ ed.pluralEditMode = false;
+ ed.fontSize = font().pointSize();
+ ed.container = new QWidget;
+ if (model > 0) {
+ ed.container->setPalette(paletteForModel(model));
+ ed.container->setAutoFillBackground(true);
+ if (model == 1) {
+ m_editors[0].container->setPalette(paletteForModel(0));
+ m_editors[0].container->setAutoFillBackground(true);
+ }
+ }
+ bool writable = m_dataModel->isModelWritable(model);
+ ed.transCommentText = new FormWidget(QString(), true);
+ ed.transCommentText->setEditingEnabled(writable);
+ ed.transCommentText->setHideWhenEmpty(!writable);
+ ed.transCommentText->setWhatsThis(tr("Here you can enter comments for your own use."
+ " They have no effect on the translated applications.") );
+ ed.transCommentText->getEditor()->installEventFilter(this);
+ connect(ed.transCommentText, SIGNAL(selectionChanged(QTextEdit*)),
+ SLOT(selectionChanged(QTextEdit*)));
+ connect(ed.transCommentText, SIGNAL(textChanged(QTextEdit*)),
+ SLOT(emitTranslatorCommentChanged(QTextEdit*)));
+ connect(ed.transCommentText, SIGNAL(textChanged(QTextEdit*)), SLOT(resetHoverSelection()));
+ connect(ed.transCommentText, SIGNAL(cursorPositionChanged()), SLOT(resetHoverSelection()));
+ fixTabOrder();
+ QBoxLayout *box = new QVBoxLayout(ed.container);
+ box->setMargin(5);
+ box->addWidget(ed.transCommentText);
+ box->addSpacing(ed.transCommentText->getEditor()->fontMetrics().height() / 2);
+ m_layout->addWidget(ed.container);
+ setTargetLanguage(model);
+}
+
+void MessageEditor::allModelsDeleted()
+{
+ foreach (const MessageEditorData &med, m_editors)
+ med.container->deleteLater();
+ m_editors.clear();
+ m_currentModel = -1;
+ // Do not emit activeModelChanged() - the main window will refresh anyway
+ m_currentNumerus = -1;
+ showNothing();
+}
+
+void MessageEditor::messageModelDeleted(int model)
+{
+ m_editors[model].container->deleteLater();
+ m_editors.removeAt(model);
+ if (model <= m_currentModel) {
+ if (model < m_currentModel || m_currentModel == m_editors.size())
+ --m_currentModel;
+ // Do not emit activeModelChanged() - the main window will refresh anyway
+ if (m_currentModel >= 0) {
+ if (m_currentNumerus >= m_editors[m_currentModel].transTexts.size())
+ m_currentNumerus = m_editors[m_currentModel].transTexts.size() - 1;
+ activeEditor()->setFocus();
+ } else {
+ m_currentNumerus = -1;
+ }
+ }
+ if (m_editors.size() == 1) {
+ m_editors[0].container->setAutoFillBackground(false);
+ } else {
+ for (int i = model; i < m_editors.size(); ++i)
+ m_editors[i].container->setPalette(paletteForModel(i));
+ }
+}
+
+void MessageEditor::addPluralForm(int model, const QString &label, bool writable)
+{
+ FormMultiWidget *transEditor = new FormMultiWidget(label);
+ connect(transEditor, SIGNAL(editorCreated(QTextEdit*)), SLOT(editorCreated(QTextEdit*)));
+ transEditor->setEditingEnabled(writable);
+ transEditor->setHideWhenEmpty(!writable);
+ if (!m_editors[model].transTexts.isEmpty())
+ transEditor->setVisible(false);
+ transEditor->setMultiEnabled(m_lengthVariants);
+ static_cast<QBoxLayout *>(m_editors[model].container->layout())->insertWidget(
+ m_editors[model].transTexts.count(), transEditor);
+
+ connect(transEditor, SIGNAL(selectionChanged(QTextEdit*)),
+ SLOT(selectionChanged(QTextEdit*)));
+ connect(transEditor, SIGNAL(textChanged(QTextEdit*)),
+ SLOT(emitTranslationChanged(QTextEdit*)));
+ connect(transEditor, SIGNAL(textChanged(QTextEdit*)), SLOT(resetHoverSelection()));
+ connect(transEditor, SIGNAL(cursorPositionChanged()), SLOT(resetHoverSelection()));
+
+ m_editors[model].transTexts << transEditor;
+}
+
+void MessageEditor::editorCreated(QTextEdit *te)
+{
+ FormMultiWidget *snd = static_cast<FormMultiWidget *>(sender());
+ for (int model = 0; ; ++model) {
+ MessageEditorData med = m_editors.at(model);
+ if (med.transTexts.contains(snd)) {
+ QFont font;
+ font.setPointSize(static_cast<int>(med.fontSize));
+ te->setFont(font);
+
+ te->installEventFilter(this);
+
+ fixTabOrder();
+ return;
+ }
+ }
+}
+
+void MessageEditor::fixTabOrder()
+{
+ m_tabOrderTimer.start(0);
+}
+
+void MessageEditor::reallyFixTabOrder()
+{
+ QWidget *prev = this;
+ foreach (const MessageEditorData &med, m_editors) {
+ foreach (FormMultiWidget *fmw, med.transTexts)
+ foreach (QTextEdit *te, fmw->getEditors()) {
+ setTabOrder(prev, te);
+ prev = te;
+ }
+ QTextEdit *te = med.transCommentText->getEditor();
+ setTabOrder(prev, te);
+ prev = te;
+ }
+}
+
+/*! internal
+ Returns all translations for an item.
+ The number of translations is dependent on if we have a plural form or not.
+ If we don't have a plural form, then this should only contain one item.
+ Otherwise it will contain the number of numerus forms for the particular language.
+*/
+QStringList MessageEditor::translations(int model) const
+{
+ QStringList translations;
+ for (int i = 0; i < m_editors[model].transTexts.count() &&
+ m_editors[model].transTexts.at(i)->isVisible(); ++i)
+ translations << m_editors[model].transTexts[i]->getTranslation();
+ return translations;
+}
+
+static void clearSelection(QTextEdit *t)
+{
+ bool oldBlockState = t->blockSignals(true);
+ QTextCursor c = t->textCursor();
+ c.clearSelection();
+ t->setTextCursor(c);
+ t->blockSignals(oldBlockState);
+}
+
+void MessageEditor::selectionChanged(QTextEdit *te)
+{
+ if (te != m_selectionHolder) {
+ if (m_selectionHolder)
+ clearSelection(m_selectionHolder);
+ m_selectionHolder = (te->textCursor().hasSelection() ? te : 0);
+ updateCanCutCopy();
+ }
+}
+
+void MessageEditor::resetHoverSelection()
+{
+ if (m_selectionHolder &&
+ (m_selectionHolder == m_source->getEditor()
+ || m_selectionHolder == m_pluralSource->getEditor()))
+ resetSelection();
+}
+
+void MessageEditor::resetSelection()
+{
+ if (m_selectionHolder) {
+ clearSelection(m_selectionHolder);
+ m_selectionHolder = 0;
+ updateCanCutCopy();
+ }
+}
+
+void MessageEditor::activeModelAndNumerus(int *model, int *numerus) const
+{
+ for (int j = 0; j < m_editors.count(); ++j) {
+ for (int i = 0; i < m_editors[j].transTexts.count(); ++i)
+ foreach (QTextEdit *te, m_editors[j].transTexts[i]->getEditors())
+ if (m_focusWidget == te) {
+ *model = j;
+ *numerus = i;
+ return;
+ }
+ if (m_focusWidget == m_editors[j].transCommentText->getEditor()) {
+ *model = j;
+ *numerus = -1;
+ return;
+ }
+ }
+ *model = -1;
+ *numerus = -1;
+}
+
+QTextEdit *MessageEditor::activeTranslation() const
+{
+ if (m_currentNumerus < 0)
+ return 0;
+ const QList<FormatTextEdit *> &editors =
+ m_editors[m_currentModel].transTexts[m_currentNumerus]->getEditors();
+ foreach (QTextEdit *te, editors)
+ if (te->hasFocus())
+ return te;
+ return editors.first();
+}
+
+QTextEdit *MessageEditor::activeOr1stTranslation() const
+{
+ if (m_currentNumerus < 0) {
+ for (int i = 0; i < m_editors.size(); ++i)
+ if (m_editors[i].container->isVisible()
+ && !m_editors[i].transTexts.first()->getEditors().first()->isReadOnly())
+ return m_editors[i].transTexts.first()->getEditors().first();
+ return 0;
+ }
+ return activeTranslation();
+}
+
+QTextEdit *MessageEditor::activeTransComment() const
+{
+ if (m_currentModel < 0 || m_currentNumerus >= 0)
+ return 0;
+ return m_editors[m_currentModel].transCommentText->getEditor();
+}
+
+QTextEdit *MessageEditor::activeEditor() const
+{
+ if (QTextEdit *te = activeTransComment())
+ return te;
+ return activeTranslation();
+}
+
+QTextEdit *MessageEditor::activeOr1stEditor() const
+{
+ if (QTextEdit *te = activeTransComment())
+ return te;
+ return activeOr1stTranslation();
+}
+
+void MessageEditor::setTargetLanguage(int model)
+{
+ const QStringList &numerusForms = m_dataModel->model(model)->numerusForms();
+ const QString &langLocalized = m_dataModel->model(model)->localizedLanguage();
+ for (int i = 0; i < numerusForms.count(); ++i) {
+ const QString &label = tr("%1 translation (%2)").arg(langLocalized, numerusForms[i]);
+ if (!i)
+ m_editors[model].firstForm = label;
+ if (i >= m_editors[model].transTexts.count())
+ addPluralForm(model, label, m_dataModel->isModelWritable(model));
+ else
+ m_editors[model].transTexts[i]->setLabel(label);
+ m_editors[model].transTexts[i]->setVisible(!i || m_editors[model].pluralEditMode);
+ m_editors[model].transTexts[i]->setWhatsThis(
+ tr("This is where you can enter or modify"
+ " the translation of the above source text.") );
+ }
+ for (int j = m_editors[model].transTexts.count() - numerusForms.count(); j > 0; --j)
+ delete m_editors[model].transTexts.takeLast();
+ m_editors[model].invariantForm = tr("%1 translation").arg(langLocalized);
+ m_editors[model].transCommentText->setLabel(tr("%1 translator comments").arg(langLocalized));
+}
+
+MessageEditorData *MessageEditor::modelForWidget(const QObject *o)
+{
+ for (int j = 0; j < m_editors.count(); ++j) {
+ for (int i = 0; i < m_editors[j].transTexts.count(); ++i)
+ foreach (QTextEdit *te, m_editors[j].transTexts[i]->getEditors())
+ if (te == o)
+ return &m_editors[j];
+ if (m_editors[j].transCommentText->getEditor() == o)
+ return &m_editors[j];
+ }
+ return 0;
+}
+
+static bool applyFont(MessageEditorData *med)
+{
+ QFont font;
+ font.setPointSize(static_cast<int>(med->fontSize));
+ for (int i = 0; i < med->transTexts.count(); ++i)
+ foreach (QTextEdit *te, med->transTexts[i]->getEditors())
+ te->setFont(font);
+ med->transCommentText->getEditor()->setFont(font);
+ return true;
+}
+
+static bool incFont(MessageEditorData *med)
+{
+ if (!med || med->fontSize >= 32)
+ return true;
+ med->fontSize *= 1.2;
+ return applyFont(med);
+}
+
+static bool decFont(MessageEditorData *med)
+{
+ if (!med || med->fontSize <= 8)
+ return true;
+ med->fontSize /= 1.2;
+ return applyFont(med);
+}
+
+bool MessageEditor::eventFilter(QObject *o, QEvent *e)
+{
+ // handle copying from the source
+ if (e->type() == QEvent::ShortcutOverride) {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+
+ if (ke->modifiers() & Qt::ControlModifier) {
+ if (ke->key() == Qt::Key_C) {
+ if (m_source->getEditor()->textCursor().hasSelection()) {
+ m_source->getEditor()->copy();
+ return true;
+ }
+ if (m_pluralSource->getEditor()->textCursor().hasSelection()) {
+ m_pluralSource->getEditor()->copy();
+ return true;
+ }
+ } else if (ke->key() == Qt::Key_A) {
+ return true;
+ }
+ }
+ } else if (e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ if (ke->modifiers() & Qt::ControlModifier) {
+ if (ke->key() == Qt::Key_Plus || ke->key() == Qt::Key_Equal)
+ return incFont(modelForWidget(o));
+ if (ke->key() == Qt::Key_Minus)
+ return decFont(modelForWidget(o));
+ } else {
+ // Ctrl-Tab is still passed through to the textedit and causes a tab to be inserted.
+ if (ke->key() == Qt::Key_Tab) {
+ focusNextChild();
+ return true;
+ }
+ }
+ } else if (e->type() == QEvent::Wheel) {
+ QWheelEvent *we = static_cast<QWheelEvent *>(e);
+ if (we->modifiers() & Qt::ControlModifier) {
+ if (we->delta() > 0)
+ return incFont(modelForWidget(o));
+ return decFont(modelForWidget(o));
+ }
+ } else if (e->type() == QEvent::FocusIn) {
+ QWidget *widget = static_cast<QWidget *>(o);
+ if (widget != m_focusWidget)
+ trackFocus(widget);
+ }
+
+ return QScrollArea::eventFilter(o, e);
+}
+
+void MessageEditor::grabFocus(QWidget *widget)
+{
+ if (widget != m_focusWidget) {
+ widget->setFocus();
+ trackFocus(widget);
+ }
+}
+
+void MessageEditor::trackFocus(QWidget *widget)
+{
+ m_focusWidget = widget;
+
+ int model, numerus;
+ activeModelAndNumerus(&model, &numerus);
+ if (model != m_currentModel || numerus != m_currentNumerus) {
+ resetSelection();
+ m_currentModel = model;
+ m_currentNumerus = numerus;
+ emit activeModelChanged(activeModel());
+ updateBeginFromSource();
+ updateUndoRedo();
+ updateCanPaste();
+ }
+}
+
+void MessageEditor::showNothing()
+{
+ m_source->clearTranslation();
+ m_pluralSource->clearTranslation();
+ m_commentText->clearTranslation();
+ for (int j = 0; j < m_editors.count(); ++j) {
+ setEditingEnabled(j, false);
+ foreach (FormMultiWidget *widget, m_editors[j].transTexts)
+ widget->clearTranslation();
+ m_editors[j].transCommentText->clearTranslation();
+ }
+ emit pasteAvailable(false);
+ updateBeginFromSource();
+ updateUndoRedo();
+}
+
+void MessageEditor::showMessage(const MultiDataIndex &index)
+{
+ m_currentIndex = index;
+
+ bool hadMsg = false;
+ for (int j = 0; j < m_editors.size(); ++j) {
+
+ MessageEditorData &ed = m_editors[j];
+
+ MessageItem *item = m_dataModel->messageItem(index, j);
+ if (!item) {
+ ed.container->hide();
+ continue;
+ }
+ ed.container->show();
+
+ if (!hadMsg) {
+
+ // Source text form
+ m_source->setTranslation(item->text());
+ m_pluralSource->setTranslation(item->pluralText());
+ // Use location from first non-obsolete message
+ if (!item->fileName().isEmpty()) {
+ QString toolTip = tr("'%1'\nLine: %2").arg(item->fileName(), QString::number(item->lineNumber()));
+ m_source->setToolTip(toolTip);
+ } else {
+ m_source->setToolTip(QLatin1String(""));
+ }
+
+ // Comment field
+ QString commentText = item->comment().simplified();
+
+ if (!item->extraComment().isEmpty()) {
+ if (!commentText.isEmpty())
+ commentText += QLatin1String("\n");
+ commentText += item->extraComment().simplified();
+ }
+
+ m_commentText->setTranslation(commentText);
+
+ hadMsg = true;
+ }
+
+ setEditingEnabled(j, m_dataModel->isModelWritable(j)
+ && item->message().type() != TranslatorMessage::Obsolete);
+
+ // Translation label
+ ed.pluralEditMode = item->translations().count() > 1;
+ ed.transTexts.first()->setLabel(ed.pluralEditMode ? ed.firstForm : ed.invariantForm);
+
+ // Translation forms
+ if (item->text().isEmpty() && !item->context().isEmpty()) {
+ for (int i = 0; i < ed.transTexts.size(); ++i)
+ ed.transTexts.at(i)->setVisible(false);
+ } else {
+ QStringList normalizedTranslations =
+ m_dataModel->model(j)->normalizedTranslations(*item);
+ for (int i = 0; i < ed.transTexts.size(); ++i) {
+ bool shouldShow = (i < normalizedTranslations.count());
+ if (shouldShow)
+ setTranslation(j, normalizedTranslations.at(i), i);
+ else
+ setTranslation(j, QString(), i);
+ ed.transTexts.at(i)->setVisible(i == 0 || shouldShow);
+ }
+ }
+
+ ed.transCommentText->setTranslation(item->translatorComment().trimmed(), false);
+ }
+
+ updateUndoRedo();
+}
+
+void MessageEditor::setTranslation(int model, const QString &translation, int numerus)
+{
+ MessageEditorData &ed = m_editors[model];
+ if (numerus >= ed.transTexts.count())
+ numerus = 0;
+ FormMultiWidget *transForm = ed.transTexts[numerus];
+ transForm->setTranslation(translation, false);
+
+ updateBeginFromSource();
+}
+
+void MessageEditor::setTranslation(int latestModel, const QString &translation)
+{
+ int numerus;
+ if (m_currentNumerus < 0) {
+ numerus = 0;
+ } else {
+ latestModel = m_currentModel;
+ numerus = m_currentNumerus;
+ }
+ FormMultiWidget *transForm = m_editors[latestModel].transTexts[numerus];
+ transForm->getEditors().first()->setFocus();
+ transForm->setTranslation(translation, true);
+
+ updateBeginFromSource();
+}
+
+void MessageEditor::setEditingEnabled(int model, bool enabled)
+{
+ MessageEditorData &ed = m_editors[model];
+ foreach (FormMultiWidget *widget, ed.transTexts)
+ widget->setEditingEnabled(enabled);
+ ed.transCommentText->setEditingEnabled(enabled);
+
+ updateCanPaste();
+}
+
+void MessageEditor::setLengthVariants(bool on)
+{
+ m_lengthVariants = on;
+ foreach (const MessageEditorData &ed, m_editors)
+ foreach (FormMultiWidget *widget, ed.transTexts)
+ widget->setMultiEnabled(on);
+}
+
+void MessageEditor::undo()
+{
+ activeEditor()->document()->undo();
+}
+
+void MessageEditor::redo()
+{
+ activeEditor()->document()->redo();
+}
+
+void MessageEditor::updateUndoRedo()
+{
+ bool newUndoAvail = false;
+ bool newRedoAvail = false;
+ if (QTextEdit *te = activeEditor()) {
+ QTextDocument *doc = te->document();
+ newUndoAvail = doc->isUndoAvailable();
+ newRedoAvail = doc->isRedoAvailable();
+ }
+
+ if (newUndoAvail != m_undoAvail) {
+ m_undoAvail = newUndoAvail;
+ emit undoAvailable(newUndoAvail);
+ }
+
+ if (newRedoAvail != m_redoAvail) {
+ m_redoAvail = newRedoAvail;
+ emit redoAvailable(newRedoAvail);
+ }
+}
+
+void MessageEditor::cut()
+{
+ m_selectionHolder->cut();
+}
+
+void MessageEditor::copy()
+{
+ m_selectionHolder->copy();
+}
+
+void MessageEditor::updateCanCutCopy()
+{
+ bool newCopyState = false;
+ bool newCutState = false;
+
+ if (m_selectionHolder) {
+ newCopyState = true;
+ newCutState = !m_selectionHolder->isReadOnly();
+ }
+
+ if (newCopyState != m_copyAvail) {
+ m_copyAvail = newCopyState;
+ emit copyAvailable(m_copyAvail);
+ }
+
+ if (newCutState != m_cutAvail) {
+ m_cutAvail = newCutState;
+ emit cutAvailable(m_cutAvail);
+ }
+}
+
+void MessageEditor::paste()
+{
+ activeEditor()->paste();
+}
+
+void MessageEditor::updateCanPaste()
+{
+ QTextEdit *te;
+ emit pasteAvailable(!m_clipboardEmpty
+ && (te = activeEditor()) && !te->isReadOnly());
+}
+
+void MessageEditor::clipboardChanged()
+{
+ // this is expensive, so move it out of the common path in updateCanPaste
+ m_clipboardEmpty = qApp->clipboard()->text().isNull();
+ updateCanPaste();
+}
+
+void MessageEditor::selectAll()
+{
+ // make sure we don't select the selection of a translator textedit,
+ // if we really want the source text editor to be selected.
+ QTextEdit *te;
+ if ((te = m_source->getEditor())->underMouse()
+ || (te = m_pluralSource->getEditor())->underMouse()
+ || ((te = activeEditor()) && te->hasFocus()))
+ te->selectAll();
+}
+
+void MessageEditor::emitTranslationChanged(QTextEdit *widget)
+{
+ grabFocus(widget); // DND proofness
+ updateBeginFromSource();
+ updateUndoRedo();
+ emit translationChanged(translations(m_currentModel));
+}
+
+void MessageEditor::emitTranslatorCommentChanged(QTextEdit *widget)
+{
+ grabFocus(widget); // DND proofness
+ updateUndoRedo();
+ emit translatorCommentChanged(m_editors[m_currentModel].transCommentText->getTranslation());
+}
+
+void MessageEditor::updateBeginFromSource()
+{
+ bool overwrite = false;
+ if (QTextEdit *activeEditor = activeTranslation())
+ overwrite = !activeEditor->isReadOnly()
+ && activeEditor->toPlainText().trimmed().isEmpty();
+ emit beginFromSourceAvailable(overwrite);
+}
+
+void MessageEditor::beginFromSource()
+{
+ MessageItem *item = m_dataModel->messageItem(m_currentIndex, m_currentModel);
+ setTranslation(m_currentModel,
+ m_currentNumerus > 0 && !item->pluralText().isEmpty() ?
+ item->pluralText() : item->text());
+}
+
+void MessageEditor::setEditorFocus()
+{
+ if (!widget()->hasFocus())
+ if (QTextEdit *activeEditor = activeOr1stEditor())
+ activeEditor->setFocus();
+}
+
+void MessageEditor::setEditorFocus(int model)
+{
+ if (m_currentModel != model) {
+ if (model < 0) {
+ resetSelection();
+ m_currentNumerus = -1;
+ m_currentModel = -1;
+ m_focusWidget = 0;
+ emit activeModelChanged(activeModel());
+ updateBeginFromSource();
+ updateUndoRedo();
+ updateCanPaste();
+ } else {
+ m_editors[model].transTexts.first()->getEditors().first()->setFocus();
+ }
+ }
+}
+
+bool MessageEditor::focusNextUnfinished(int start)
+{
+ for (int j = start; j < m_editors.count(); ++j)
+ if (m_dataModel->isModelWritable(j))
+ if (MessageItem *item = m_dataModel->messageItem(m_currentIndex, j))
+ if (item->type() == TranslatorMessage::Unfinished) {
+ m_editors[j].transTexts.first()->getEditors().first()->setFocus();
+ return true;
+ }
+ return false;
+}
+
+void MessageEditor::setUnfinishedEditorFocus()
+{
+ focusNextUnfinished(0);
+}
+
+bool MessageEditor::focusNextUnfinished()
+{
+ return focusNextUnfinished(m_currentModel + 1);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/messageeditor.h b/src/linguist/linguist/messageeditor.h
new file mode 100644
index 000000000..875ef3303
--- /dev/null
+++ b/src/linguist/linguist/messageeditor.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGEEDITOR_H
+#define MESSAGEEDITOR_H
+
+#include "messagemodel.h"
+
+#include <QtCore/QLocale>
+#include <QtCore/QTimer>
+
+#include <QtGui/QFrame>
+#include <QtGui/QScrollArea>
+
+QT_BEGIN_NAMESPACE
+
+class QBoxLayout;
+class QMainWindow;
+class QTextEdit;
+
+class MessageEditor;
+class FormatTextEdit;
+class FormWidget;
+class FormMultiWidget;
+
+struct MessageEditorData {
+ QWidget *container;
+ FormWidget *transCommentText;
+ QList<FormMultiWidget *> transTexts;
+ QString invariantForm;
+ QString firstForm;
+ qreal fontSize;
+ bool pluralEditMode;
+};
+
+class MessageEditor : public QScrollArea
+{
+ Q_OBJECT
+
+public:
+ MessageEditor(MultiDataModel *dataModel, QMainWindow *parent = 0);
+
+ void showNothing();
+ void showMessage(const MultiDataIndex &index);
+ void setNumerusForms(int model, const QStringList &numerusForms);
+ bool eventFilter(QObject *, QEvent *);
+ void setTranslation(int model, const QString &translation, int numerus);
+ int activeModel() const { return (m_editors.count() != 1) ? m_currentModel : 0; }
+ void setEditorFocus(int model);
+ void setUnfinishedEditorFocus();
+ bool focusNextUnfinished();
+
+signals:
+ void translationChanged(const QStringList &translations);
+ void translatorCommentChanged(const QString &comment);
+ void activeModelChanged(int model);
+
+ void undoAvailable(bool avail);
+ void redoAvailable(bool avail);
+ void cutAvailable(bool avail);
+ void copyAvailable(bool avail);
+ void pasteAvailable(bool avail);
+ void beginFromSourceAvailable(bool enable);
+
+public slots:
+ void undo();
+ void redo();
+ void cut();
+ void copy();
+ void paste();
+ void selectAll();
+ void beginFromSource();
+ void setEditorFocus();
+ void setTranslation(int latestModel, const QString &translation);
+ void setLengthVariants(bool on);
+
+private slots:
+ void editorCreated(QTextEdit *);
+ void selectionChanged(QTextEdit *);
+ void resetHoverSelection();
+ void emitTranslationChanged(QTextEdit *);
+ void emitTranslatorCommentChanged(QTextEdit *);
+ void updateCanPaste();
+ void clipboardChanged();
+ void messageModelAppended();
+ void messageModelDeleted(int model);
+ void allModelsDeleted();
+ void setTargetLanguage(int model);
+ void reallyFixTabOrder();
+
+private:
+ void setupEditorPage();
+ void setEditingEnabled(int model, bool enabled);
+ bool focusNextUnfinished(int start);
+ void resetSelection();
+ void grabFocus(QWidget *widget);
+ void trackFocus(QWidget *widget);
+ void activeModelAndNumerus(int *model, int *numerus) const;
+ QTextEdit *activeTranslation() const;
+ QTextEdit *activeOr1stTranslation() const;
+ QTextEdit *activeTransComment() const;
+ QTextEdit *activeEditor() const;
+ QTextEdit *activeOr1stEditor() const;
+ MessageEditorData *modelForWidget(const QObject *o);
+ int activeTranslationNumerus() const;
+ QStringList translations(int model) const;
+ void updateBeginFromSource();
+ void updateUndoRedo();
+ void updateCanCutCopy();
+ void addPluralForm(int model, const QString &label, bool writable);
+ void fixTabOrder();
+ QPalette paletteForModel(int model) const;
+
+ MultiDataModel *m_dataModel;
+
+ MultiDataIndex m_currentIndex;
+ int m_currentModel;
+ int m_currentNumerus;
+
+ bool m_lengthVariants;
+
+ bool m_undoAvail;
+ bool m_redoAvail;
+ bool m_cutAvail;
+ bool m_copyAvail;
+
+ bool m_clipboardEmpty;
+
+ QTextEdit *m_selectionHolder;
+ QWidget *m_focusWidget;
+ QBoxLayout *m_layout;
+ FormWidget *m_source;
+ FormWidget *m_pluralSource;
+ FormWidget *m_commentText;
+ QList<MessageEditorData> m_editors;
+
+ QTimer m_tabOrderTimer;
+};
+
+QT_END_NAMESPACE
+
+#endif // MESSAGEEDITOR_H
diff --git a/src/linguist/linguist/messageeditorwidgets.cpp b/src/linguist/linguist/messageeditorwidgets.cpp
new file mode 100644
index 000000000..f55c336a9
--- /dev/null
+++ b/src/linguist/linguist/messageeditorwidgets.cpp
@@ -0,0 +1,456 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "messageeditorwidgets.h"
+#include "messagehighlighter.h"
+
+#include <translator.h>
+
+#include <QAbstractTextDocumentLayout>
+#include <QAction>
+#include <QApplication>
+#include <QClipboard>
+#include <QDebug>
+#include <QLayout>
+#include <QMenu>
+#include <QMessageBox>
+#include <QPainter>
+#include <QScrollArea>
+#include <QTextBlock>
+#include <QTextDocumentFragment>
+#include <QToolButton>
+#include <QVBoxLayout>
+
+QT_BEGIN_NAMESPACE
+
+ExpandingTextEdit::ExpandingTextEdit(QWidget *parent)
+ : QTextEdit(parent)
+{
+ setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding));
+
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ QAbstractTextDocumentLayout *docLayout = document()->documentLayout();
+ connect(docLayout, SIGNAL(documentSizeChanged(QSizeF)), SLOT(updateHeight(QSizeF)));
+ connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(reallyEnsureCursorVisible()));
+
+ m_minimumHeight = qRound(docLayout->documentSize().height()) + frameWidth() * 2;
+}
+
+void ExpandingTextEdit::updateHeight(const QSizeF &documentSize)
+{
+ m_minimumHeight = qRound(documentSize.height()) + frameWidth() * 2;
+ updateGeometry();
+}
+
+QSize ExpandingTextEdit::sizeHint() const
+{
+ return QSize(100, m_minimumHeight);
+}
+
+QSize ExpandingTextEdit::minimumSizeHint() const
+{
+ return QSize(100, m_minimumHeight);
+}
+
+void ExpandingTextEdit::reallyEnsureCursorVisible()
+{
+ QObject *ancestor = parent();
+ while (ancestor) {
+ QScrollArea *scrollArea = qobject_cast<QScrollArea*>(ancestor);
+ if (scrollArea &&
+ (scrollArea->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff &&
+ scrollArea->horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) {
+ const QRect &r = cursorRect();
+ const QPoint &c = mapTo(scrollArea->widget(), r.center());
+ scrollArea->ensureVisible(c.x(), c.y());
+ break;
+ }
+ ancestor = ancestor->parent();
+ }
+}
+
+FormatTextEdit::FormatTextEdit(QWidget *parent)
+ : ExpandingTextEdit(parent)
+{
+ setLineWrapMode(QTextEdit::WidgetWidth);
+ setAcceptRichText(false);
+ QTextOption option = document()->defaultTextOption();
+ option.setFlags(option.flags()
+ | QTextOption::ShowLineAndParagraphSeparators
+ | QTextOption::ShowTabsAndSpaces);
+ document()->setDefaultTextOption(option);
+
+ // Do not set different background if disabled
+ QPalette p = palette();
+ p.setColor(QPalette::Disabled, QPalette::Base, p.color(QPalette::Active, QPalette::Base));
+ setPalette(p);
+
+ setEditable(true);
+
+ m_highlighter = new MessageHighlighter(this);
+}
+
+void FormatTextEdit::setEditable(bool editable)
+{
+ // save default frame style
+ static int framed = frameStyle();
+ static Qt::FocusPolicy defaultFocus = focusPolicy();
+
+ if (editable) {
+ setFrameStyle(framed);
+ setFocusPolicy(defaultFocus);
+ } else {
+ setFrameStyle(QFrame::NoFrame | QFrame::Plain);
+ setFocusPolicy(Qt::NoFocus);
+ }
+
+ setReadOnly(!editable);
+}
+
+void FormatTextEdit::setPlainText(const QString &text, bool userAction)
+{
+ if (!userAction) {
+ // Prevent contentsChanged signal
+ bool oldBlockState = blockSignals(true);
+ document()->setUndoRedoEnabled(false);
+ ExpandingTextEdit::setPlainText(text);
+ // highlighter is out of sync because of blocked signals
+ m_highlighter->rehighlight();
+ document()->setUndoRedoEnabled(true);
+ blockSignals(oldBlockState);
+ } else {
+ ExpandingTextEdit::setPlainText(text);
+ }
+}
+
+FormWidget::FormWidget(const QString &label, bool isEditable, QWidget *parent)
+ : QWidget(parent),
+ m_hideWhenEmpty(false)
+{
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setMargin(0);
+
+ m_label = new QLabel(this);
+ QFont fnt;
+ fnt.setBold(true);
+ m_label->setFont(fnt);
+ m_label->setText(label);
+ layout->addWidget(m_label);
+
+ m_editor = new FormatTextEdit(this);
+ m_editor->setEditable(isEditable);
+ //m_textEdit->setWhatsThis(tr("This area shows text from an auxillary translation."));
+ layout->addWidget(m_editor);
+
+ setLayout(layout);
+
+ connect(m_editor, SIGNAL(textChanged()), SLOT(slotTextChanged()));
+ connect(m_editor, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
+ connect(m_editor, SIGNAL(cursorPositionChanged()), SIGNAL(cursorPositionChanged()));
+}
+
+void FormWidget::slotTextChanged()
+{
+ emit textChanged(m_editor);
+}
+
+void FormWidget::slotSelectionChanged()
+{
+ emit selectionChanged(m_editor);
+}
+
+void FormWidget::setTranslation(const QString &text, bool userAction)
+{
+ m_editor->setPlainText(text, userAction);
+ if (m_hideWhenEmpty)
+ setHidden(text.isEmpty());
+}
+
+void FormWidget::setEditingEnabled(bool enable)
+{
+ // Use read-only state so that the text can still be copied
+ m_editor->setReadOnly(!enable);
+ m_label->setEnabled(enable);
+}
+
+
+class ButtonWrapper : public QWidget
+{
+ // no Q_OBJECT: no need to, and don't want the useless moc file
+
+public:
+ ButtonWrapper(QWidget *wrapee, QWidget *relator) : m_wrapee(wrapee)
+ {
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+ QBoxLayout *box = new QVBoxLayout;
+ box->setMargin(0);
+ setLayout(box);
+ box->addWidget(wrapee, 0, Qt::AlignBottom);
+ if (relator)
+ relator->installEventFilter(this);
+ }
+
+protected:
+ virtual bool eventFilter(QObject *object, QEvent *event)
+ {
+ if (event->type() == QEvent::Resize) {
+ QWidget *relator = static_cast<QWidget *>(object);
+ setFixedHeight((relator->height() + layout()->spacing() + m_wrapee->height()) / 2);
+ }
+ return false;
+ }
+
+private:
+ QWidget *m_wrapee;
+};
+
+FormMultiWidget::FormMultiWidget(const QString &label, QWidget *parent)
+ : QWidget(parent),
+ m_hideWhenEmpty(false),
+ m_multiEnabled(false),
+ m_plusIcon(QIcon(QLatin1String(":/images/plus.png"))), // make static
+ m_minusIcon(QIcon(QLatin1String(":/images/minus.png")))
+{
+ m_label = new QLabel(this);
+ QFont fnt;
+ fnt.setBold(true);
+ m_label->setFont(fnt);
+ m_label->setText(label);
+
+ m_plusButtons.append(
+ new ButtonWrapper(makeButton(m_plusIcon, SLOT(plusButtonClicked())), 0));
+}
+
+QAbstractButton *FormMultiWidget::makeButton(const QIcon &icon, const char *slot)
+{
+ QAbstractButton *btn = new QToolButton(this);
+ btn->setIcon(icon);
+ btn->setFixedSize(icon.availableSizes().first() /* + something */);
+ btn->setFocusPolicy(Qt::NoFocus);
+ connect(btn, SIGNAL(clicked()), slot);
+ return btn;
+}
+
+void FormMultiWidget::addEditor(int idx)
+{
+ FormatTextEdit *editor = new FormatTextEdit(this);
+ m_editors.insert(idx, editor);
+
+ m_minusButtons.insert(idx, makeButton(m_minusIcon, SLOT(minusButtonClicked())));
+ m_plusButtons.insert(idx + 1,
+ new ButtonWrapper(makeButton(m_plusIcon, SLOT(plusButtonClicked())), editor));
+
+ connect(editor, SIGNAL(textChanged()), SLOT(slotTextChanged()));
+ connect(editor, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
+ connect(editor, SIGNAL(cursorPositionChanged()), SIGNAL(cursorPositionChanged()));
+ editor->installEventFilter(this);
+
+ emit editorCreated(editor);
+}
+
+bool FormMultiWidget::eventFilter(QObject *watched, QEvent *event)
+{
+ int i = 0;
+ while (m_editors.at(i) != watched)
+ if (++i >= m_editors.count()) // Happens when deleting an editor
+ return false;
+ if (event->type() == QEvent::FocusOut) {
+ m_minusButtons.at(i)->setToolTip(QString());
+ m_plusButtons.at(i)->setToolTip(QString());
+ m_plusButtons.at(i + 1)->setToolTip(QString());
+ } else if (event->type() == QEvent::FocusIn) {
+ m_minusButtons.at(i)->setToolTip(/*: translate, but don't change */ tr("Alt+Delete"));
+ m_plusButtons.at(i)->setToolTip(/*: translate, but don't change */ tr("Shift+Alt+Insert"));
+ m_plusButtons.at(i + 1)->setToolTip(/*: translate, but don't change */ tr("Alt+Insert"));
+ } else if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+ if (ke->modifiers() & Qt::AltModifier) {
+ if (ke->key() == Qt::Key_Delete) {
+ deleteEditor(i);
+ return true;
+ } else if (ke->key() == Qt::Key_Insert) {
+ if (!(ke->modifiers() & Qt::ShiftModifier))
+ ++i;
+ insertEditor(i);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void FormMultiWidget::updateLayout()
+{
+ delete layout();
+
+ QGridLayout *layout = new QGridLayout;
+ layout->setMargin(0);
+ setLayout(layout);
+
+ bool variants = m_multiEnabled && m_label->isEnabled();
+
+ layout->addWidget(m_label, 0, 0, 1, variants ? 3 : 1);
+
+ for (int i = 0; i < m_plusButtons.count(); ++i) {
+ if (variants)
+ layout->addWidget(m_plusButtons.at(i), 1 + i * 2, 0, 2, 1, Qt::AlignTop);
+ m_plusButtons.at(i)->setVisible(variants);
+ }
+ for (int j = 0; j < m_minusButtons.count(); ++j) {
+ if (variants)
+ layout->addWidget(m_minusButtons.at(j), 2 + j * 2, 2, 2, 1, Qt::AlignVCenter);
+ m_minusButtons.at(j)->setVisible(variants);
+ }
+ for (int k = 0; k < m_editors.count(); ++k)
+ layout->addWidget(m_editors.at(k), 2 + k * 2, variants ? 1 : 0, 2, 1, Qt::AlignVCenter);
+
+ updateGeometry();
+}
+
+void FormMultiWidget::slotTextChanged()
+{
+ emit textChanged(static_cast<QTextEdit *>(sender()));
+}
+
+void FormMultiWidget::slotSelectionChanged()
+{
+ emit selectionChanged(static_cast<QTextEdit *>(sender()));
+}
+
+void FormMultiWidget::setTranslation(const QString &text, bool userAction)
+{
+ QStringList texts = text.split(QChar(Translator::BinaryVariantSeparator), QString::KeepEmptyParts);
+
+ while (m_editors.count() > texts.count()) {
+ delete m_minusButtons.takeLast();
+ delete m_plusButtons.takeLast();
+ delete m_editors.takeLast();
+ }
+ while (m_editors.count() < texts.count())
+ addEditor(m_editors.count());
+ updateLayout();
+
+ for (int i = 0; i < texts.count(); ++i)
+ // XXX this will emit n textChanged signals
+ m_editors.at(i)->setPlainText(texts.at(i), userAction);
+
+ if (m_hideWhenEmpty)
+ setHidden(text.isEmpty());
+}
+
+QString FormMultiWidget::getTranslation() const
+{
+ QString ret;
+ for (int i = 0; i < m_editors.count(); ++i) {
+ if (i)
+ ret += QChar(Translator::BinaryVariantSeparator);
+ ret += m_editors.at(i)->toPlainText();
+ }
+ return ret;
+}
+
+void FormMultiWidget::setEditingEnabled(bool enable)
+{
+ // Use read-only state so that the text can still be copied
+ for (int i = 0; i < m_editors.count(); ++i)
+ m_editors.at(i)->setReadOnly(!enable);
+ m_label->setEnabled(enable);
+ if (m_multiEnabled)
+ updateLayout();
+}
+
+void FormMultiWidget::setMultiEnabled(bool enable)
+{
+ m_multiEnabled = enable;
+ if (m_label->isEnabled())
+ updateLayout();
+}
+
+void FormMultiWidget::minusButtonClicked()
+{
+ int i = 0;
+ while (m_minusButtons.at(i) != sender())
+ ++i;
+ deleteEditor(i);
+}
+
+void FormMultiWidget::plusButtonClicked()
+{
+ QWidget *btn = static_cast<QAbstractButton *>(sender())->parentWidget();
+ int i = 0;
+ while (m_plusButtons.at(i) != btn)
+ ++i;
+ insertEditor(i);
+}
+
+void FormMultiWidget::deleteEditor(int idx)
+{
+ if (m_editors.count() == 1) {
+ // Don't just clear(), so the undo history is not lost
+ QTextCursor c = m_editors.first()->textCursor();
+ c.select(QTextCursor::Document);
+ c.removeSelectedText();
+ } else {
+ if (!m_editors.at(idx)->toPlainText().isEmpty()) {
+ if (QMessageBox::question(topLevelWidget(), tr("Confirmation - Qt Linguist"),
+ tr("Delete non-empty length variant?"),
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes)
+ != QMessageBox::Yes)
+ return;
+ }
+ delete m_editors.takeAt(idx);
+ delete m_minusButtons.takeAt(idx);
+ delete m_plusButtons.takeAt(idx + 1);
+ updateLayout();
+ emit textChanged(m_editors.at((m_editors.count() == idx) ? idx - 1 : idx));
+ }
+}
+
+void FormMultiWidget::insertEditor(int idx)
+{
+ addEditor(idx);
+ updateLayout();
+ emit textChanged(m_editors.at(idx));
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/messageeditorwidgets.h b/src/linguist/linguist/messageeditorwidgets.h
new file mode 100644
index 000000000..482d9b9db
--- /dev/null
+++ b/src/linguist/linguist/messageeditorwidgets.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGEEDITORWIDGETS_H
+#define MESSAGEEDITORWIDGETS_H
+
+#include <QIcon>
+#include <QImage>
+#include <QLabel>
+#include <QMap>
+#include <QTextEdit>
+#include <QUrl>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractButton;
+class QAction;
+class QContextMenuEvent;
+class QKeyEvent;
+class QMenu;
+class QSizeF;
+class QString;
+class QVariant;
+
+class MessageHighlighter;
+
+/*
+ Automatically adapt height to document contents
+ */
+class ExpandingTextEdit : public QTextEdit
+{
+ Q_OBJECT
+
+public:
+ ExpandingTextEdit(QWidget *parent = 0);
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+private slots:
+ void updateHeight(const QSizeF &documentSize);
+ void reallyEnsureCursorVisible();
+
+private:
+ int m_minimumHeight;
+};
+
+/*
+ Format markup & control characters
+*/
+class FormatTextEdit : public ExpandingTextEdit
+{
+ Q_OBJECT
+public:
+ FormatTextEdit(QWidget *parent = 0);
+ void setEditable(bool editable);
+
+public slots:
+ void setPlainText(const QString & text, bool userAction);
+
+private:
+ MessageHighlighter *m_highlighter;
+};
+
+/*
+ Displays text field & associated label
+*/
+class FormWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ FormWidget(const QString &label, bool isEditable, QWidget *parent = 0);
+ void setLabel(const QString &label) { m_label->setText(label); }
+ void setTranslation(const QString &text, bool userAction = false);
+ void clearTranslation() { setTranslation(QString(), false); }
+ QString getTranslation() { return m_editor->toPlainText(); }
+ void setEditingEnabled(bool enable);
+ void setHideWhenEmpty(bool optional) { m_hideWhenEmpty = optional; }
+ FormatTextEdit *getEditor() { return m_editor; }
+
+signals:
+ void textChanged(QTextEdit *);
+ void selectionChanged(QTextEdit *);
+ void cursorPositionChanged();
+
+private slots:
+ void slotSelectionChanged();
+ void slotTextChanged();
+
+private:
+ QLabel *m_label;
+ FormatTextEdit *m_editor;
+ bool m_hideWhenEmpty;
+};
+
+/*
+ Displays text fields & associated label
+*/
+class FormMultiWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ FormMultiWidget(const QString &label, QWidget *parent = 0);
+ void setLabel(const QString &label) { m_label->setText(label); }
+ void setTranslation(const QString &text, bool userAction = false);
+ void clearTranslation() { setTranslation(QString(), false); }
+ QString getTranslation() const;
+ void setEditingEnabled(bool enable);
+ void setMultiEnabled(bool enable);
+ void setHideWhenEmpty(bool optional) { m_hideWhenEmpty = optional; }
+ const QList<FormatTextEdit *> &getEditors() const { return m_editors; }
+
+signals:
+ void editorCreated(QTextEdit *);
+ void textChanged(QTextEdit *);
+ void selectionChanged(QTextEdit *);
+ void cursorPositionChanged();
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event);
+
+private slots:
+ void slotTextChanged();
+ void slotSelectionChanged();
+ void minusButtonClicked();
+ void plusButtonClicked();
+
+private:
+ void addEditor(int idx);
+ void updateLayout();
+ QAbstractButton *makeButton(const QIcon &icon, const char *slot);
+ void insertEditor(int idx);
+ void deleteEditor(int idx);
+
+ QLabel *m_label;
+ QList<FormatTextEdit *> m_editors;
+ QList<QWidget *> m_plusButtons;
+ QList<QAbstractButton *> m_minusButtons;
+ bool m_hideWhenEmpty;
+ bool m_multiEnabled;
+ QIcon m_plusIcon, m_minusIcon;
+};
+
+QT_END_NAMESPACE
+
+#endif // MESSAGEEDITORWIDGETS_H
diff --git a/src/linguist/linguist/messagehighlighter.cpp b/src/linguist/linguist/messagehighlighter.cpp
new file mode 100644
index 000000000..bef2d6221
--- /dev/null
+++ b/src/linguist/linguist/messagehighlighter.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "messagehighlighter.h"
+
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+MessageHighlighter::MessageHighlighter(QTextEdit *textEdit)
+ : QSyntaxHighlighter(textEdit)
+{
+ QTextCharFormat entityFormat;
+ entityFormat.setForeground(Qt::red);
+ m_formats[Entity] = entityFormat;
+
+ QTextCharFormat tagFormat;
+ tagFormat.setForeground(Qt::darkMagenta);
+ m_formats[Tag] = tagFormat;
+
+ QTextCharFormat commentFormat;
+ commentFormat.setForeground(Qt::gray);
+ commentFormat.setFontItalic(true);
+ m_formats[Comment] = commentFormat;
+
+ QTextCharFormat attributeFormat;
+ attributeFormat.setForeground(Qt::black);
+ attributeFormat.setFontItalic(true);
+ m_formats[Attribute] = attributeFormat;
+
+ QTextCharFormat valueFormat;
+ valueFormat.setForeground(Qt::blue);
+ m_formats[Value] = valueFormat;
+
+ QTextCharFormat acceleratorFormat;
+ acceleratorFormat.setFontUnderline(true);
+ m_formats[Accelerator] = acceleratorFormat;
+
+ QTextCharFormat variableFormat;
+ variableFormat.setForeground(Qt::blue);
+ m_formats[Variable] = variableFormat;
+
+ rehighlight();
+}
+
+void MessageHighlighter::highlightBlock(const QString &text)
+{
+ static const QLatin1Char tab = QLatin1Char('\t');
+ static const QLatin1Char space = QLatin1Char(' ');
+ static const QLatin1Char amp = QLatin1Char('&');
+ static const QLatin1Char endTag = QLatin1Char('>');
+ static const QLatin1Char quot = QLatin1Char('"');
+ static const QLatin1Char apos = QLatin1Char('\'');
+ static const QLatin1Char semicolon = QLatin1Char(';');
+ static const QLatin1Char equals = QLatin1Char('=');
+ static const QLatin1Char percent = QLatin1Char('%');
+ static const QLatin1String startComment = QLatin1String("<!--");
+ static const QLatin1String endComment = QLatin1String("-->");
+ static const QLatin1String endElement = QLatin1String("/>");
+
+ int state = previousBlockState();
+ int len = text.length();
+ int start = 0;
+ int pos = 0;
+
+ while (pos < len) {
+ switch (state) {
+ case NormalState:
+ default:
+ while (pos < len) {
+ QChar ch = text.at(pos);
+ if (ch == QLatin1Char('<')) {
+ if (text.mid(pos, 4) == startComment) {
+ state = InComment;
+ } else {
+ state = InTag;
+ start = pos;
+ while (pos < len && text.at(pos) != space
+ && text.at(pos) != endTag
+ && text.at(pos) != tab
+ && text.mid(pos, 2) != endElement)
+ ++pos;
+ if (text.mid(pos, 2) == endElement)
+ ++pos;
+ setFormat(start, pos - start,
+ m_formats[Tag]);
+ break;
+ }
+ break;
+ } else if (ch == amp && pos + 1 < len) {
+ // Default is Accelerator
+ if (text.at(pos + 1).isLetterOrNumber())
+ setFormat(pos + 1, 1, m_formats[Accelerator]);
+
+ // When a semicolon follows assume an Entity
+ start = pos;
+ ch = text.at(++pos);
+ while (pos + 1 < len && ch != semicolon && ch.isLetterOrNumber())
+ ch = text.at(++pos);
+ if (ch == semicolon)
+ setFormat(start, pos - start + 1, m_formats[Entity]);
+ } else if (ch == percent) {
+ start = pos;
+ // %[1-9]*
+ for (++pos; pos < len && text.at(pos).isDigit(); ++pos) {}
+ // %n
+ if (pos < len && pos == start + 1 && text.at(pos) == QLatin1Char('n'))
+ ++pos;
+ setFormat(start, pos - start, m_formats[Variable]);
+ } else {
+ // No tag, comment or entity started, continue...
+ ++pos;
+ }
+ }
+ break;
+ case InComment:
+ start = pos;
+ while (pos < len) {
+ if (text.mid(pos, 3) == endComment) {
+ pos += 3;
+ state = NormalState;
+ break;
+ } else {
+ ++pos;
+ }
+ }
+ setFormat(start, pos - start, m_formats[Comment]);
+ break;
+ case InTag:
+ QChar quote = QChar::Null;
+ while (pos < len) {
+ QChar ch = text.at(pos);
+ if (quote.isNull()) {
+ start = pos;
+ if (ch == apos || ch == quot) {
+ quote = ch;
+ } else if (ch == endTag) {
+ ++pos;
+ setFormat(start, pos - start, m_formats[Tag]);
+ state = NormalState;
+ break;
+ } else if (text.mid(pos, 2) == endElement) {
+ pos += 2;
+ setFormat(start, pos - start, m_formats[Tag]);
+ state = NormalState;
+ break;
+ } else if (ch != space && text.at(pos) != tab) {
+ // Tag not ending, not a quote and no whitespace, so
+ // we must be dealing with an attribute.
+ ++pos;
+ while (pos < len && text.at(pos) != space
+ && text.at(pos) != tab
+ && text.at(pos) != equals)
+ ++pos;
+ setFormat(start, pos - start, m_formats[Attribute]);
+ start = pos;
+ }
+ } else if (ch == quote) {
+ quote = QChar::Null;
+
+ // Anything quoted is a value
+ setFormat(start, pos - start, m_formats[Value]);
+ }
+ ++pos;
+ }
+ break;
+ }
+ }
+ setCurrentBlockState(state);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/messagehighlighter.h b/src/linguist/linguist/messagehighlighter.h
new file mode 100644
index 000000000..455140f61
--- /dev/null
+++ b/src/linguist/linguist/messagehighlighter.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGEHIGHLIGHTER_H
+#define MESSAGEHIGHLIGHTER_H
+
+#include <QtGui/QSyntaxHighlighter>
+
+QT_BEGIN_NAMESPACE
+
+/* Message highlighter based on HtmlSyntaxHighlighter from designer */
+class MessageHighlighter : public QSyntaxHighlighter
+{
+ Q_OBJECT
+
+public:
+ MessageHighlighter(QTextEdit *textEdit);
+
+protected:
+ void highlightBlock(const QString &text);
+
+private:
+ enum Construct {
+ Entity,
+ Tag,
+ Comment,
+ Attribute,
+ Value,
+ Accelerator, // "Open &File"
+ Variable, // "Opening %1"
+ LastConstruct = Variable
+ };
+
+ enum State {
+ NormalState = -1,
+ InComment,
+ InTag
+ };
+
+ QTextCharFormat m_formats[LastConstruct + 1];
+};
+
+QT_END_NAMESPACE
+
+#endif // MESSAGEHIGHLIGHTER_H
diff --git a/src/linguist/linguist/messagemodel.cpp b/src/linguist/linguist/messagemodel.cpp
new file mode 100644
index 000000000..2d126577c
--- /dev/null
+++ b/src/linguist/linguist/messagemodel.cpp
@@ -0,0 +1,1426 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "messagemodel.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QTextCodec>
+
+#include <QtGui/QMessageBox>
+#include <QtGui/QPainter>
+#include <QtGui/QPixmap>
+#include <QtGui/QTextDocument>
+
+#include <private/qtranslator_p.h>
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+/******************************************************************************
+ *
+ * MessageItem
+ *
+ *****************************************************************************/
+
+MessageItem::MessageItem(const TranslatorMessage &message)
+ : m_message(message),
+ m_danger(false)
+{
+ if (m_message.translation().isEmpty())
+ m_message.setTranslation(QString());
+}
+
+
+bool MessageItem::compare(const QString &findText, bool matchSubstring,
+ Qt::CaseSensitivity cs) const
+{
+ return matchSubstring
+ ? text().indexOf(findText, 0, cs) >= 0
+ : text().compare(findText, cs) == 0;
+}
+
+/******************************************************************************
+ *
+ * ContextItem
+ *
+ *****************************************************************************/
+
+ContextItem::ContextItem(const QString &context)
+ : m_context(context),
+ m_finishedCount(0),
+ m_finishedDangerCount(0),
+ m_unfinishedDangerCount(0),
+ m_nonobsoleteCount(0)
+{}
+
+void ContextItem::appendToComment(const QString &str)
+{
+ if (!m_comment.isEmpty())
+ m_comment += QLatin1String("\n\n");
+ m_comment += str;
+}
+
+MessageItem *ContextItem::messageItem(int i) const
+{
+ if (i >= 0 && i < msgItemList.count())
+ return const_cast<MessageItem *>(&msgItemList[i]);
+ Q_ASSERT(i >= 0 && i < msgItemList.count());
+ return 0;
+}
+
+MessageItem *ContextItem::findMessage(const QString &sourcetext, const QString &comment) const
+{
+ for (int i = 0; i < messageCount(); ++i) {
+ MessageItem *mi = messageItem(i);
+ if (mi->text() == sourcetext && mi->comment() == comment)
+ return mi;
+ }
+ return 0;
+}
+
+/******************************************************************************
+ *
+ * DataModel
+ *
+ *****************************************************************************/
+
+DataModel::DataModel(QObject *parent)
+ : QObject(parent),
+ m_modified(false),
+ m_numMessages(0),
+ m_srcWords(0),
+ m_srcChars(0),
+ m_srcCharsSpc(0),
+ m_language(QLocale::Language(-1)),
+ m_sourceLanguage(QLocale::Language(-1)),
+ m_country(QLocale::Country(-1)),
+ m_sourceCountry(QLocale::Country(-1))
+{}
+
+QStringList DataModel::normalizedTranslations(const MessageItem &m) const
+{
+ return Translator::normalizedTranslations(m.message(), m_numerusForms.count());
+}
+
+ContextItem *DataModel::contextItem(int context) const
+{
+ if (context >= 0 && context < m_contextList.count())
+ return const_cast<ContextItem *>(&m_contextList[context]);
+ Q_ASSERT(context >= 0 && context < m_contextList.count());
+ return 0;
+}
+
+MessageItem *DataModel::messageItem(const DataIndex &index) const
+{
+ if (ContextItem *c = contextItem(index.context()))
+ return c->messageItem(index.message());
+ return 0;
+}
+
+ContextItem *DataModel::findContext(const QString &context) const
+{
+ for (int c = 0; c < m_contextList.count(); ++c) {
+ ContextItem *ctx = contextItem(c);
+ if (ctx->context() == context)
+ return ctx;
+ }
+ return 0;
+}
+
+MessageItem *DataModel::findMessage(const QString &context,
+ const QString &sourcetext, const QString &comment) const
+{
+ if (ContextItem *ctx = findContext(context))
+ return ctx->findMessage(sourcetext, comment);
+ return 0;
+}
+
+static int calcMergeScore(const DataModel *one, const DataModel *two)
+{
+ int inBoth = 0;
+ for (int i = 0; i < two->contextCount(); ++i) {
+ ContextItem *oc = two->contextItem(i);
+ if (ContextItem *c = one->findContext(oc->context())) {
+ for (int j = 0; j < oc->messageCount(); ++j) {
+ MessageItem *m = oc->messageItem(j);
+ if (c->findMessage(m->text(), m->comment()) >= 0)
+ ++inBoth;
+ }
+ }
+ }
+ return inBoth * 100 / two->messageCount();
+}
+
+bool DataModel::isWellMergeable(const DataModel *other) const
+{
+ if (!other->messageCount() || !messageCount())
+ return true;
+
+ return calcMergeScore(this, other) + calcMergeScore(other, this) > 90;
+}
+
+bool DataModel::load(const QString &fileName, bool *langGuessed, QWidget *parent)
+{
+ Translator tor;
+ ConversionData cd;
+ bool ok = tor.load(fileName, cd, QLatin1String("auto"));
+ if (!ok) {
+ QMessageBox::warning(parent, QObject::tr("Qt Linguist"), cd.error());
+ return false;
+ }
+
+ if (!tor.messageCount()) {
+ QMessageBox::warning(parent, QObject::tr("Qt Linguist"),
+ tr("The translation file '%1' will not be loaded because it is empty.")
+ .arg(Qt::escape(fileName)));
+ return false;
+ }
+
+ Translator::Duplicates dupes = tor.resolveDuplicates();
+ if (!dupes.byId.isEmpty() || !dupes.byContents.isEmpty()) {
+ QString err = tr("<qt>Duplicate messages found in '%1':").arg(Qt::escape(fileName));
+ int numdups = 0;
+ foreach (int i, dupes.byId) {
+ if (++numdups >= 5) {
+ err += tr("<p>[more duplicates omitted]");
+ goto doWarn;
+ }
+ err += tr("<p>* ID: %1").arg(Qt::escape(tor.message(i).id()));
+ }
+ foreach (int j, dupes.byContents) {
+ const TranslatorMessage &msg = tor.message(j);
+ if (++numdups >= 5) {
+ err += tr("<p>[more duplicates omitted]");
+ break;
+ }
+ err += tr("<p>* Context: %1<br>* Source: %2")
+ .arg(Qt::escape(msg.context()), Qt::escape(msg.sourceText()));
+ if (!msg.comment().isEmpty())
+ err += tr("<br>* Comment: %3").arg(Qt::escape(msg.comment()));
+ }
+ doWarn:
+ QMessageBox::warning(parent, QObject::tr("Qt Linguist"), err);
+ }
+
+ m_srcFileName = fileName;
+ m_codecName = tor.codecName();
+ m_relativeLocations = (tor.locationsType() == Translator::RelativeLocations);
+ m_extra = tor.extras();
+ m_contextList.clear();
+ m_numMessages = 0;
+
+ QHash<QString, int> contexts;
+
+ m_srcWords = 0;
+ m_srcChars = 0;
+ m_srcCharsSpc = 0;
+
+ foreach (const TranslatorMessage &msg, tor.messages()) {
+ if (!contexts.contains(msg.context())) {
+ contexts.insert(msg.context(), m_contextList.size());
+ m_contextList.append(ContextItem(msg.context()));
+ }
+
+ ContextItem *c = contextItem(contexts.value(msg.context()));
+ if (msg.sourceText() == QLatin1String(ContextComment)) {
+ c->appendToComment(msg.comment());
+ } else {
+ MessageItem tmp(msg);
+ if (msg.type() == TranslatorMessage::Finished)
+ c->incrementFinishedCount();
+ if (msg.type() != TranslatorMessage::Obsolete) {
+ doCharCounting(tmp.text(), m_srcWords, m_srcChars, m_srcCharsSpc);
+ doCharCounting(tmp.pluralText(), m_srcWords, m_srcChars, m_srcCharsSpc);
+ c->incrementNonobsoleteCount();
+ }
+ c->appendMessage(tmp);
+ ++m_numMessages;
+ }
+ }
+
+ // Try to detect the correct language in the following order
+ // 1. Look for the language attribute in the ts
+ // if that fails
+ // 2. Guestimate the language from the filename
+ // (expecting the qt_{en,de}.ts convention)
+ // if that fails
+ // 3. Retrieve the locale from the system.
+ *langGuessed = false;
+ QString lang = tor.languageCode();
+ if (lang.isEmpty()) {
+ lang = QFileInfo(fileName).baseName();
+ int pos = lang.indexOf(QLatin1Char('_'));
+ if (pos != -1 && pos + 3 == lang.length())
+ lang = fileName.mid(pos + 1);
+ else
+ lang.clear();
+ *langGuessed = true;
+ }
+ QLocale::Language l;
+ QLocale::Country c;
+ Translator::languageAndCountry(lang, &l, &c);
+ if (l == QLocale::C) {
+ QLocale sys;
+ l = sys.language();
+ c = sys.country();
+ *langGuessed = true;
+ }
+ if (!setLanguageAndCountry(l, c))
+ QMessageBox::warning(parent, QObject::tr("Qt Linguist"),
+ tr("Linguist does not know the plural rules for '%1'.\n"
+ "Will assume a single universal form.")
+ .arg(m_localizedLanguage));
+ // Try to detect the correct source language in the following order
+ // 1. Look for the language attribute in the ts
+ // if that fails
+ // 2. Assume English
+ lang = tor.sourceLanguageCode();
+ if (lang.isEmpty()) {
+ l = QLocale::C;
+ c = QLocale::AnyCountry;
+ } else {
+ Translator::languageAndCountry(lang, &l, &c);
+ }
+ setSourceLanguageAndCountry(l, c);
+
+ setModified(false);
+
+ return true;
+}
+
+bool DataModel::save(const QString &fileName, QWidget *parent)
+{
+ Translator tor;
+ for (DataModelIterator it(this); it.isValid(); ++it)
+ tor.append(it.current()->message());
+
+ tor.setLanguageCode(Translator::makeLanguageCode(m_language, m_country));
+ tor.setSourceLanguageCode(Translator::makeLanguageCode(m_sourceLanguage, m_sourceCountry));
+ tor.setCodecName(m_codecName);
+ tor.setLocationsType(m_relativeLocations ? Translator::RelativeLocations
+ : Translator::AbsoluteLocations);
+ tor.setExtras(m_extra);
+ ConversionData cd;
+ bool ok = tor.save(fileName, cd, QLatin1String("auto"));
+ if (ok)
+ setModified(false);
+ else
+ QMessageBox::warning(parent, QObject::tr("Qt Linguist"), cd.error());
+ return ok;
+}
+
+bool DataModel::saveAs(const QString &newFileName, QWidget *parent)
+{
+ if (!save(newFileName, parent))
+ return false;
+ m_srcFileName = newFileName;
+ return true;
+}
+
+bool DataModel::release(const QString &fileName, bool verbose, bool ignoreUnfinished,
+ TranslatorSaveMode mode, QWidget *parent)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ QMessageBox::warning(parent, QObject::tr("Qt Linguist"),
+ tr("Cannot create '%2': %1").arg(file.errorString()).arg(fileName));
+ return false;
+ }
+ Translator tor;
+ QLocale locale(m_language, m_country);
+ tor.setLanguageCode(locale.name());
+ for (DataModelIterator it(this); it.isValid(); ++it)
+ tor.append(it.current()->message());
+ ConversionData cd;
+ cd.m_verbose = verbose;
+ cd.m_ignoreUnfinished = ignoreUnfinished;
+ cd.m_saveMode = mode;
+ bool ok = tor.release(&file, cd);
+ if (!ok)
+ QMessageBox::warning(parent, QObject::tr("Qt Linguist"), cd.error());
+ return ok;
+}
+
+void DataModel::doCharCounting(const QString &text, int &trW, int &trC, int &trCS)
+{
+ trCS += text.length();
+ bool inWord = false;
+ for (int i = 0; i < text.length(); ++i) {
+ if (text[i].isLetterOrNumber() || text[i] == QLatin1Char('_')) {
+ if (!inWord) {
+ ++trW;
+ inWord = true;
+ }
+ } else {
+ inWord = false;
+ }
+ if (!text[i].isSpace())
+ trC++;
+ }
+}
+
+bool DataModel::setLanguageAndCountry(QLocale::Language lang, QLocale::Country country)
+{
+ if (m_language == lang && m_country == country)
+ return true;
+ m_language = lang;
+ m_country = country;
+
+ if (lang == QLocale::C || uint(lang) > uint(QLocale::LastLanguage)) // XXX does this make any sense?
+ lang = QLocale::English;
+ QByteArray rules;
+ bool ok = getNumerusInfo(lang, country, &rules, &m_numerusForms, 0);
+ m_localizedLanguage = QCoreApplication::translate("MessageEditor", QLocale::languageToString(lang).toAscii());
+ m_countRefNeeds.clear();
+ for (int i = 0; i < rules.size(); ++i) {
+ m_countRefNeeds.append(!(rules.at(i) == Q_EQ && (i == (rules.size() - 2) || rules.at(i + 2) == (char)Q_NEWRULE)));
+ while (++i < rules.size() && rules.at(i) != (char)Q_NEWRULE) {}
+ }
+ m_countRefNeeds.append(true);
+ if (!ok) {
+ m_numerusForms.clear();
+ m_numerusForms << tr("Universal Form");
+ }
+ emit languageChanged();
+ setModified(true);
+ return ok;
+}
+
+void DataModel::setSourceLanguageAndCountry(QLocale::Language lang, QLocale::Country country)
+{
+ if (m_sourceLanguage == lang && m_sourceCountry == country)
+ return;
+ m_sourceLanguage = lang;
+ m_sourceCountry = country;
+ setModified(true);
+}
+
+void DataModel::updateStatistics()
+{
+ int trW = 0;
+ int trC = 0;
+ int trCS = 0;
+
+ for (DataModelIterator it(this); it.isValid(); ++it) {
+ const MessageItem *mi = it.current();
+ if (mi->isFinished())
+ foreach (const QString &trnsl, mi->translations())
+ doCharCounting(trnsl, trW, trC, trCS);
+ }
+
+ emit statsChanged(m_srcWords, m_srcChars, m_srcCharsSpc, trW, trC, trCS);
+}
+
+void DataModel::setModified(bool isModified)
+{
+ if (m_modified == isModified)
+ return;
+ m_modified = isModified;
+ emit modifiedChanged();
+}
+
+QString DataModel::prettifyPlainFileName(const QString &fn)
+{
+ static QString workdir = QDir::currentPath() + QLatin1Char('/');
+
+ return QDir::toNativeSeparators(fn.startsWith(workdir) ? fn.mid(workdir.length()) : fn);
+}
+
+QString DataModel::prettifyFileName(const QString &fn)
+{
+ if (fn.startsWith(QLatin1Char('=')))
+ return QLatin1Char('=') + prettifyPlainFileName(fn.mid(1));
+ else
+ return prettifyPlainFileName(fn);
+}
+
+/******************************************************************************
+ *
+ * DataModelIterator
+ *
+ *****************************************************************************/
+
+DataModelIterator::DataModelIterator(DataModel *model, int context, int message)
+ : DataIndex(context, message), m_model(model)
+{
+}
+
+bool DataModelIterator::isValid() const
+{
+ return m_context < m_model->m_contextList.count();
+}
+
+void DataModelIterator::operator++()
+{
+ ++m_message;
+ if (m_message >= m_model->m_contextList.at(m_context).messageCount()) {
+ ++m_context;
+ m_message = 0;
+ }
+}
+
+MessageItem *DataModelIterator::current() const
+{
+ return m_model->messageItem(*this);
+}
+
+
+/******************************************************************************
+ *
+ * MultiMessageItem
+ *
+ *****************************************************************************/
+
+MultiMessageItem::MultiMessageItem(const MessageItem *m)
+ : m_text(m->text()),
+ m_pluralText(m->pluralText()),
+ m_comment(m->comment()),
+ m_nonnullCount(0),
+ m_nonobsoleteCount(0),
+ m_editableCount(0),
+ m_unfinishedCount(0)
+{
+}
+
+/******************************************************************************
+ *
+ * MultiContextItem
+ *
+ *****************************************************************************/
+
+MultiContextItem::MultiContextItem(int oldCount, ContextItem *ctx, bool writable)
+ : m_context(ctx->context()),
+ m_comment(ctx->comment()),
+ m_finishedCount(0),
+ m_editableCount(0),
+ m_nonobsoleteCount(0)
+{
+ QList<MessageItem *> mList;
+ QList<MessageItem *> eList;
+ for (int j = 0; j < ctx->messageCount(); ++j) {
+ MessageItem *m = ctx->messageItem(j);
+ mList.append(m);
+ eList.append(0);
+ m_multiMessageList.append(MultiMessageItem(m));
+ }
+ for (int i = 0; i < oldCount; ++i) {
+ m_messageLists.append(eList);
+ m_writableMessageLists.append(0);
+ m_contextList.append(0);
+ }
+ m_messageLists.append(mList);
+ m_writableMessageLists.append(writable ? &m_messageLists.last() : 0);
+ m_contextList.append(ctx);
+}
+
+void MultiContextItem::appendEmptyModel()
+{
+ QList<MessageItem *> eList;
+ for (int j = 0; j < messageCount(); ++j)
+ eList.append(0);
+ m_messageLists.append(eList);
+ m_writableMessageLists.append(0);
+ m_contextList.append(0);
+}
+
+void MultiContextItem::assignLastModel(ContextItem *ctx, bool writable)
+{
+ if (writable)
+ m_writableMessageLists.last() = &m_messageLists.last();
+ m_contextList.last() = ctx;
+}
+
+// XXX this is not needed, yet
+void MultiContextItem::moveModel(int oldPos, int newPos)
+{
+ m_contextList.insert(newPos, m_contextList[oldPos]);
+ m_messageLists.insert(newPos, m_messageLists[oldPos]);
+ m_writableMessageLists.insert(newPos, m_writableMessageLists[oldPos]);
+ removeModel(oldPos < newPos ? oldPos : oldPos + 1);
+}
+
+void MultiContextItem::removeModel(int pos)
+{
+ m_contextList.removeAt(pos);
+ m_messageLists.removeAt(pos);
+ m_writableMessageLists.removeAt(pos);
+}
+
+void MultiContextItem::putMessageItem(int pos, MessageItem *m)
+{
+ m_messageLists.last()[pos] = m;
+}
+
+void MultiContextItem::appendMessageItems(const QList<MessageItem *> &m)
+{
+ QList<MessageItem *> nullItems = m; // Basically, just a reservation
+ for (int i = 0; i < nullItems.count(); ++i)
+ nullItems[i] = 0;
+ for (int i = 0; i < m_messageLists.count() - 1; ++i)
+ m_messageLists[i] += nullItems;
+ m_messageLists.last() += m;
+ foreach (MessageItem *mi, m)
+ m_multiMessageList.append(MultiMessageItem(mi));
+}
+
+void MultiContextItem::removeMultiMessageItem(int pos)
+{
+ for (int i = 0; i < m_messageLists.count(); ++i)
+ m_messageLists[i].removeAt(pos);
+ m_multiMessageList.removeAt(pos);
+}
+
+int MultiContextItem::firstNonobsoleteMessageIndex(int msgIdx) const
+{
+ for (int i = 0; i < m_messageLists.size(); ++i)
+ if (m_messageLists[i][msgIdx] && !m_messageLists[i][msgIdx]->isObsolete())
+ return i;
+ return -1;
+}
+
+int MultiContextItem::findMessage(const QString &sourcetext, const QString &comment) const
+{
+ for (int i = 0, cnt = messageCount(); i < cnt; ++i) {
+ MultiMessageItem *m = multiMessageItem(i);
+ if (m->text() == sourcetext && m->comment() == comment)
+ return i;
+ }
+ return -1;
+}
+
+/******************************************************************************
+ *
+ * MultiDataModel
+ *
+ *****************************************************************************/
+
+static const uchar paletteRGBs[7][3] = {
+ { 236, 244, 255 }, // blue
+ { 236, 255, 255 }, // cyan
+ { 236, 255, 232 }, // green
+ { 255, 255, 230 }, // yellow
+ { 255, 242, 222 }, // orange
+ { 255, 236, 236 }, // red
+ { 252, 236, 255 } // purple
+};
+
+MultiDataModel::MultiDataModel(QObject *parent) :
+ QObject(parent),
+ m_numFinished(0),
+ m_numEditable(0),
+ m_numMessages(0),
+ m_modified(false)
+{
+ for (int i = 0; i < 7; ++i)
+ m_colors[i] = QColor(paletteRGBs[i][0], paletteRGBs[i][1], paletteRGBs[i][2]);
+
+ m_bitmap = QBitmap(8, 8);
+ m_bitmap.clear();
+ QPainter p(&m_bitmap);
+ for (int j = 0; j < 8; ++j)
+ for (int k = 0; k < 8; ++k)
+ if ((j + k) & 4)
+ p.drawPoint(j, k);
+}
+
+MultiDataModel::~MultiDataModel()
+{
+ qDeleteAll(m_dataModels);
+}
+
+QBrush MultiDataModel::brushForModel(int model) const
+{
+ QBrush brush(m_colors[model % 7]);
+ if (!isModelWritable(model))
+ brush.setTexture(m_bitmap);
+ return brush;
+}
+
+bool MultiDataModel::isWellMergeable(const DataModel *dm) const
+{
+ if (!dm->messageCount() || !messageCount())
+ return true;
+
+ int inBothNew = 0;
+ for (int i = 0; i < dm->contextCount(); ++i) {
+ ContextItem *c = dm->contextItem(i);
+ if (MultiContextItem *mc = findContext(c->context())) {
+ for (int j = 0; j < c->messageCount(); ++j) {
+ MessageItem *m = c->messageItem(j);
+ if (mc->findMessage(m->text(), m->comment()) >= 0)
+ ++inBothNew;
+ }
+ }
+ }
+ int newRatio = inBothNew * 100 / dm->messageCount();
+
+ int inBothOld = 0;
+ for (int k = 0; k < contextCount(); ++k) {
+ MultiContextItem *mc = multiContextItem(k);
+ if (ContextItem *c = dm->findContext(mc->context())) {
+ for (int j = 0; j < mc->messageCount(); ++j) {
+ MultiMessageItem *m = mc->multiMessageItem(j);
+ if (c->findMessage(m->text(), m->comment()))
+ ++inBothOld;
+ }
+ }
+ }
+ int oldRatio = inBothOld * 100 / messageCount();
+
+ return newRatio + oldRatio > 90;
+}
+
+void MultiDataModel::append(DataModel *dm, bool readWrite)
+{
+ int insCol = modelCount() + 1;
+ m_msgModel->beginInsertColumns(QModelIndex(), insCol, insCol);
+ m_dataModels.append(dm);
+ for (int j = 0; j < contextCount(); ++j) {
+ m_msgModel->beginInsertColumns(m_msgModel->createIndex(j, 0, 0), insCol, insCol);
+ m_multiContextList[j].appendEmptyModel();
+ m_msgModel->endInsertColumns();
+ }
+ m_msgModel->endInsertColumns();
+ int appendedContexts = 0;
+ for (int i = 0; i < dm->contextCount(); ++i) {
+ ContextItem *c = dm->contextItem(i);
+ int mcx = findContextIndex(c->context());
+ if (mcx >= 0) {
+ MultiContextItem *mc = multiContextItem(mcx);
+ mc->assignLastModel(c, readWrite);
+ QList<MessageItem *> appendItems;
+ for (int j = 0; j < c->messageCount(); ++j) {
+ MessageItem *m = c->messageItem(j);
+ int msgIdx = mc->findMessage(m->text(), m->comment());
+ if (msgIdx >= 0)
+ mc->putMessageItem(msgIdx, m);
+ else
+ appendItems << m;
+ }
+ if (!appendItems.isEmpty()) {
+ int msgCnt = mc->messageCount();
+ m_msgModel->beginInsertRows(m_msgModel->createIndex(mcx, 0, 0),
+ msgCnt, msgCnt + appendItems.size() - 1);
+ mc->appendMessageItems(appendItems);
+ m_msgModel->endInsertRows();
+ m_numMessages += appendItems.size();
+ }
+ } else {
+ m_multiContextList << MultiContextItem(modelCount() - 1, c, readWrite);
+ m_numMessages += c->messageCount();
+ ++appendedContexts;
+ }
+ }
+ if (appendedContexts) {
+ // Do that en block to avoid itemview inefficiency. It doesn't hurt that we
+ // announce the availability of the data "long" after it was actually added.
+ m_msgModel->beginInsertRows(QModelIndex(),
+ contextCount() - appendedContexts, contextCount() - 1);
+ m_msgModel->endInsertRows();
+ }
+ dm->setWritable(readWrite);
+ updateCountsOnAdd(modelCount() - 1, readWrite);
+ connect(dm, SIGNAL(modifiedChanged()), SLOT(onModifiedChanged()));
+ connect(dm, SIGNAL(languageChanged()), SLOT(onLanguageChanged()));
+ connect(dm, SIGNAL(statsChanged(int,int,int,int,int,int)), SIGNAL(statsChanged(int,int,int,int,int,int)));
+ emit modelAppended();
+}
+
+void MultiDataModel::close(int model)
+{
+ if (m_dataModels.count() == 1) {
+ closeAll();
+ } else {
+ updateCountsOnRemove(model, isModelWritable(model));
+ int delCol = model + 1;
+ m_msgModel->beginRemoveColumns(QModelIndex(), delCol, delCol);
+ for (int i = m_multiContextList.size(); --i >= 0;) {
+ m_msgModel->beginRemoveColumns(m_msgModel->createIndex(i, 0, 0), delCol, delCol);
+ m_multiContextList[i].removeModel(model);
+ m_msgModel->endRemoveColumns();
+ }
+ delete m_dataModels.takeAt(model);
+ m_msgModel->endRemoveColumns();
+ emit modelDeleted(model);
+ for (int i = m_multiContextList.size(); --i >= 0;) {
+ MultiContextItem &mc = m_multiContextList[i];
+ QModelIndex contextIdx = m_msgModel->createIndex(i, 0, 0);
+ for (int j = mc.messageCount(); --j >= 0;)
+ if (mc.multiMessageItem(j)->isEmpty()) {
+ m_msgModel->beginRemoveRows(contextIdx, j, j);
+ mc.removeMultiMessageItem(j);
+ m_msgModel->endRemoveRows();
+ --m_numMessages;
+ }
+ if (!mc.messageCount()) {
+ m_msgModel->beginRemoveRows(QModelIndex(), i, i);
+ m_multiContextList.removeAt(i);
+ m_msgModel->endRemoveRows();
+ }
+ }
+ onModifiedChanged();
+ }
+}
+
+void MultiDataModel::closeAll()
+{
+ m_numFinished = 0;
+ m_numEditable = 0;
+ m_numMessages = 0;
+ qDeleteAll(m_dataModels);
+ m_dataModels.clear();
+ m_multiContextList.clear();
+ m_msgModel->reset();
+ emit allModelsDeleted();
+ onModifiedChanged();
+}
+
+// XXX this is not needed, yet
+void MultiDataModel::moveModel(int oldPos, int newPos)
+{
+ int delPos = oldPos < newPos ? oldPos : oldPos + 1;
+ m_dataModels.insert(newPos, m_dataModels[oldPos]);
+ m_dataModels.removeAt(delPos);
+ for (int i = 0; i < m_multiContextList.size(); ++i)
+ m_multiContextList[i].moveModel(oldPos, newPos);
+}
+
+QStringList MultiDataModel::prettifyFileNames(const QStringList &names)
+{
+ QStringList out;
+
+ foreach (const QString &name, names)
+ out << DataModel::prettifyFileName(name);
+ return out;
+}
+
+QString MultiDataModel::condenseFileNames(const QStringList &names)
+{
+ if (names.isEmpty())
+ return QString();
+
+ if (names.count() < 2)
+ return names.first();
+
+ QString prefix = names.first();
+ if (prefix.startsWith(QLatin1Char('=')))
+ prefix.remove(0, 1);
+ QString suffix = prefix;
+ for (int i = 1; i < names.count(); ++i) {
+ QString fn = names[i];
+ if (fn.startsWith(QLatin1Char('=')))
+ fn.remove(0, 1);
+ for (int j = 0; j < prefix.length(); ++j)
+ if (fn[j] != prefix[j]) {
+ if (j < prefix.length()) {
+ while (j > 0 && prefix[j - 1].isLetterOrNumber())
+ --j;
+ prefix.truncate(j);
+ }
+ break;
+ }
+ int fnl = fn.length() - 1;
+ int sxl = suffix.length() - 1;
+ for (int k = 0; k <= sxl; ++k)
+ if (fn[fnl - k] != suffix[sxl - k]) {
+ if (k < sxl) {
+ while (k > 0 && suffix[sxl - k + 1].isLetterOrNumber())
+ --k;
+ if (prefix.length() + k > fnl)
+ --k;
+ suffix.remove(0, sxl - k + 1);
+ }
+ break;
+ }
+ }
+ QString ret = prefix + QLatin1Char('{');
+ int pxl = prefix.length();
+ int sxl = suffix.length();
+ for (int j = 0; j < names.count(); ++j) {
+ if (j)
+ ret += QLatin1Char(',');
+ int off = pxl;
+ QString fn = names[j];
+ if (fn.startsWith(QLatin1Char('='))) {
+ ret += QLatin1Char('=');
+ ++off;
+ }
+ ret += fn.mid(off, fn.length() - sxl - off);
+ }
+ ret += QLatin1Char('}') + suffix;
+ return ret;
+}
+
+QStringList MultiDataModel::srcFileNames(bool pretty) const
+{
+ QStringList names;
+ foreach (DataModel *dm, m_dataModels)
+ names << (dm->isWritable() ? QString() : QString::fromLatin1("=")) + dm->srcFileName(pretty);
+ return names;
+}
+
+QString MultiDataModel::condensedSrcFileNames(bool pretty) const
+{
+ return condenseFileNames(srcFileNames(pretty));
+}
+
+bool MultiDataModel::isModified() const
+{
+ foreach (const DataModel *mdl, m_dataModels)
+ if (mdl->isModified())
+ return true;
+ return false;
+}
+
+void MultiDataModel::onModifiedChanged()
+{
+ bool modified = isModified();
+ if (modified != m_modified) {
+ emit modifiedChanged(modified);
+ m_modified = modified;
+ }
+}
+
+void MultiDataModel::onLanguageChanged()
+{
+ int i = 0;
+ while (sender() != m_dataModels[i])
+ ++i;
+ emit languageChanged(i);
+}
+
+int MultiDataModel::isFileLoaded(const QString &name) const
+{
+ for (int i = 0; i < m_dataModels.size(); ++i)
+ if (m_dataModels[i]->srcFileName() == name)
+ return i;
+ return -1;
+}
+
+int MultiDataModel::findContextIndex(const QString &context) const
+{
+ for (int i = 0; i < m_multiContextList.size(); ++i) {
+ const MultiContextItem &mc = m_multiContextList[i];
+ if (mc.context() == context)
+ return i;
+ }
+ return -1;
+}
+
+MultiContextItem *MultiDataModel::findContext(const QString &context) const
+{
+ for (int i = 0; i < m_multiContextList.size(); ++i) {
+ const MultiContextItem &mc = m_multiContextList[i];
+ if (mc.context() == context)
+ return const_cast<MultiContextItem *>(&mc);
+ }
+ return 0;
+}
+
+MessageItem *MultiDataModel::messageItem(const MultiDataIndex &index, int model) const
+{
+ if (index.context() < contextCount() && model >= 0 && model < modelCount()) {
+ MultiContextItem *mc = multiContextItem(index.context());
+ if (index.message() < mc->messageCount())
+ return mc->messageItem(model, index.message());
+ }
+ Q_ASSERT(model >= 0 && model < modelCount());
+ Q_ASSERT(index.context() < contextCount());
+ return 0;
+}
+
+void MultiDataModel::setTranslation(const MultiDataIndex &index, const QString &translation)
+{
+ MessageItem *m = messageItem(index);
+ if (translation == m->translation())
+ return;
+ m->setTranslation(translation);
+ setModified(index.model(), true);
+ emit translationChanged(index);
+}
+
+void MultiDataModel::setFinished(const MultiDataIndex &index, bool finished)
+{
+ MultiContextItem *mc = multiContextItem(index.context());
+ MultiMessageItem *mm = mc->multiMessageItem(index.message());
+ ContextItem *c = contextItem(index);
+ MessageItem *m = messageItem(index);
+ TranslatorMessage::Type type = m->type();
+ if (type == TranslatorMessage::Unfinished && finished) {
+ m->setType(TranslatorMessage::Finished);
+ mm->decrementUnfinishedCount();
+ if (!mm->countUnfinished()) {
+ incrementFinishedCount();
+ mc->incrementFinishedCount();
+ emit multiContextDataChanged(index);
+ }
+ c->incrementFinishedCount();
+ if (m->danger()) {
+ c->incrementFinishedDangerCount();
+ c->decrementUnfinishedDangerCount();
+ if (!c->unfinishedDangerCount()
+ || c->finishedCount() == c->nonobsoleteCount())
+ emit contextDataChanged(index);
+ } else if (c->finishedCount() == c->nonobsoleteCount()) {
+ emit contextDataChanged(index);
+ }
+ emit messageDataChanged(index);
+ setModified(index.model(), true);
+ } else if (type == TranslatorMessage::Finished && !finished) {
+ m->setType(TranslatorMessage::Unfinished);
+ mm->incrementUnfinishedCount();
+ if (mm->countUnfinished() == 1) {
+ decrementFinishedCount();
+ mc->decrementFinishedCount();
+ emit multiContextDataChanged(index);
+ }
+ c->decrementFinishedCount();
+ if (m->danger()) {
+ c->decrementFinishedDangerCount();
+ c->incrementUnfinishedDangerCount();
+ if (c->unfinishedDangerCount() == 1
+ || c->finishedCount() + 1 == c->nonobsoleteCount())
+ emit contextDataChanged(index);
+ } else if (c->finishedCount() + 1 == c->nonobsoleteCount()) {
+ emit contextDataChanged(index);
+ }
+ emit messageDataChanged(index);
+ setModified(index.model(), true);
+ }
+}
+
+void MultiDataModel::setDanger(const MultiDataIndex &index, bool danger)
+{
+ ContextItem *c = contextItem(index);
+ MessageItem *m = messageItem(index);
+ if (!m->danger() && danger) {
+ if (m->isFinished()) {
+ c->incrementFinishedDangerCount();
+ if (c->finishedDangerCount() == 1)
+ emit contextDataChanged(index);
+ } else {
+ c->incrementUnfinishedDangerCount();
+ if (c->unfinishedDangerCount() == 1)
+ emit contextDataChanged(index);
+ }
+ emit messageDataChanged(index);
+ m->setDanger(danger);
+ } else if (m->danger() && !danger) {
+ if (m->isFinished()) {
+ c->decrementFinishedDangerCount();
+ if (!c->finishedDangerCount())
+ emit contextDataChanged(index);
+ } else {
+ c->decrementUnfinishedDangerCount();
+ if (!c->unfinishedDangerCount())
+ emit contextDataChanged(index);
+ }
+ emit messageDataChanged(index);
+ m->setDanger(danger);
+ }
+}
+
+void MultiDataModel::updateCountsOnAdd(int model, bool writable)
+{
+ for (int i = 0; i < m_multiContextList.size(); ++i) {
+ MultiContextItem &mc = m_multiContextList[i];
+ for (int j = 0; j < mc.messageCount(); ++j)
+ if (MessageItem *m = mc.messageItem(model, j)) {
+ MultiMessageItem *mm = mc.multiMessageItem(j);
+ mm->incrementNonnullCount();
+ if (!m->isObsolete()) {
+ if (writable) {
+ if (!mm->countEditable()) {
+ mc.incrementEditableCount();
+ incrementEditableCount();
+ if (m->isFinished()) {
+ mc.incrementFinishedCount();
+ incrementFinishedCount();
+ } else {
+ mm->incrementUnfinishedCount();
+ }
+ } else if (!m->isFinished()) {
+ if (!mm->isUnfinished()) {
+ mc.decrementFinishedCount();
+ decrementFinishedCount();
+ }
+ mm->incrementUnfinishedCount();
+ }
+ mm->incrementEditableCount();
+ }
+ mc.incrementNonobsoleteCount();
+ mm->incrementNonobsoleteCount();
+ }
+ }
+ }
+}
+
+void MultiDataModel::updateCountsOnRemove(int model, bool writable)
+{
+ for (int i = 0; i < m_multiContextList.size(); ++i) {
+ MultiContextItem &mc = m_multiContextList[i];
+ for (int j = 0; j < mc.messageCount(); ++j)
+ if (MessageItem *m = mc.messageItem(model, j)) {
+ MultiMessageItem *mm = mc.multiMessageItem(j);
+ mm->decrementNonnullCount();
+ if (!m->isObsolete()) {
+ mm->decrementNonobsoleteCount();
+ mc.decrementNonobsoleteCount();
+ if (writable) {
+ mm->decrementEditableCount();
+ if (!mm->countEditable()) {
+ mc.decrementEditableCount();
+ decrementEditableCount();
+ if (m->isFinished()) {
+ mc.decrementFinishedCount();
+ decrementFinishedCount();
+ } else {
+ mm->decrementUnfinishedCount();
+ }
+ } else if (!m->isFinished()) {
+ mm->decrementUnfinishedCount();
+ if (!mm->isUnfinished()) {
+ mc.incrementFinishedCount();
+ incrementFinishedCount();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/******************************************************************************
+ *
+ * MultiDataModelIterator
+ *
+ *****************************************************************************/
+
+MultiDataModelIterator::MultiDataModelIterator(MultiDataModel *dataModel, int model, int context, int message)
+ : MultiDataIndex(model, context, message), m_dataModel(dataModel)
+{
+}
+
+void MultiDataModelIterator::operator++()
+{
+ Q_ASSERT(isValid());
+ ++m_message;
+ if (m_message >= m_dataModel->m_multiContextList.at(m_context).messageCount()) {
+ ++m_context;
+ m_message = 0;
+ }
+}
+
+bool MultiDataModelIterator::isValid() const
+{
+ return m_context < m_dataModel->m_multiContextList.count();
+}
+
+MessageItem *MultiDataModelIterator::current() const
+{
+ return m_dataModel->messageItem(*this);
+}
+
+
+/******************************************************************************
+ *
+ * MessageModel
+ *
+ *****************************************************************************/
+
+MessageModel::MessageModel(QObject *parent, MultiDataModel *data)
+ : QAbstractItemModel(parent), m_data(data)
+{
+ data->m_msgModel = this;
+ connect(m_data, SIGNAL(multiContextDataChanged(MultiDataIndex)),
+ SLOT(multiContextItemChanged(MultiDataIndex)));
+ connect(m_data, SIGNAL(contextDataChanged(MultiDataIndex)),
+ SLOT(contextItemChanged(MultiDataIndex)));
+ connect(m_data, SIGNAL(messageDataChanged(MultiDataIndex)),
+ SLOT(messageItemChanged(MultiDataIndex)));
+}
+
+QModelIndex MessageModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (!parent.isValid())
+ return createIndex(row, column, 0);
+ if (!parent.internalId())
+ return createIndex(row, column, parent.row() + 1);
+ return QModelIndex();
+}
+
+QModelIndex MessageModel::parent(const QModelIndex& index) const
+{
+ if (index.internalId())
+ return createIndex(index.internalId() - 1, 0, 0);
+ return QModelIndex();
+}
+
+void MessageModel::multiContextItemChanged(const MultiDataIndex &index)
+{
+ QModelIndex idx = createIndex(index.context(), m_data->modelCount() + 2, 0);
+ emit dataChanged(idx, idx);
+}
+
+void MessageModel::contextItemChanged(const MultiDataIndex &index)
+{
+ QModelIndex idx = createIndex(index.context(), index.model() + 1, 0);
+ emit dataChanged(idx, idx);
+}
+
+void MessageModel::messageItemChanged(const MultiDataIndex &index)
+{
+ QModelIndex idx = createIndex(index.message(), index.model() + 1, index.context() + 1);
+ emit dataChanged(idx, idx);
+}
+
+QModelIndex MessageModel::modelIndex(const MultiDataIndex &index)
+{
+ if (index.message() < 0) // Should be unused case
+ return createIndex(index.context(), index.model() + 1, 0);
+ return createIndex(index.message(), index.model() + 1, index.context() + 1);
+}
+
+int MessageModel::rowCount(const QModelIndex &parent) const
+{
+ if (!parent.isValid())
+ return m_data->contextCount(); // contexts
+ if (!parent.internalId()) // messages
+ return m_data->multiContextItem(parent.row())->messageCount();
+ return 0;
+}
+
+int MessageModel::columnCount(const QModelIndex &) const
+{
+ return m_data->modelCount() + 3;
+}
+
+QVariant MessageModel::data(const QModelIndex &index, int role) const
+{
+ static QVariant pxOn =
+ QVariant::fromValue(QPixmap(QLatin1String(":/images/s_check_on.png")));
+ static QVariant pxOff =
+ QVariant::fromValue(QPixmap(QLatin1String(":/images/s_check_off.png")));
+ static QVariant pxObsolete =
+ QVariant::fromValue(QPixmap(QLatin1String(":/images/s_check_obsolete.png")));
+ static QVariant pxDanger =
+ QVariant::fromValue(QPixmap(QLatin1String(":/images/s_check_danger.png")));
+ static QVariant pxWarning =
+ QVariant::fromValue(QPixmap(QLatin1String(":/images/s_check_warning.png")));
+ static QVariant pxEmpty =
+ QVariant::fromValue(QPixmap(QLatin1String(":/images/s_check_empty.png")));
+
+ int row = index.row();
+ int column = index.column() - 1;
+ if (column < 0)
+ return QVariant();
+
+ int numLangs = m_data->modelCount();
+
+ if (role == Qt::ToolTipRole && column < numLangs) {
+ return tr("Completion status for %1").arg(m_data->model(column)->localizedLanguage());
+ } else if (index.internalId()) {
+ // this is a message
+ int crow = index.internalId() - 1;
+ MultiContextItem *mci = m_data->multiContextItem(crow);
+ if (row >= mci->messageCount() || !index.isValid())
+ return QVariant();
+
+ if (role == Qt::DisplayRole || (role == Qt::ToolTipRole && column == numLangs)) {
+ switch (column - numLangs) {
+ case 0: // Source text
+ {
+ MultiMessageItem *msgItem = mci->multiMessageItem(row);
+ if (msgItem->text().isEmpty()) {
+ if (mci->context().isEmpty())
+ return tr("<file header>");
+ else
+ return tr("<context comment>");
+ }
+ return msgItem->text().simplified();
+ }
+ default: // Status or dummy column => no text
+ return QVariant();
+ }
+ }
+ else if (role == Qt::DecorationRole && column < numLangs) {
+ if (MessageItem *msgItem = mci->messageItem(column, row)) {
+ switch (msgItem->message().type()) {
+ case TranslatorMessage::Unfinished:
+ if (msgItem->translation().isEmpty())
+ return pxEmpty;
+ if (msgItem->danger())
+ return pxDanger;
+ return pxOff;
+ case TranslatorMessage::Finished:
+ if (msgItem->danger())
+ return pxWarning;
+ return pxOn;
+ default:
+ return pxObsolete;
+ }
+ }
+ return QVariant();
+ }
+ else if (role == SortRole) {
+ switch (column - numLangs) {
+ case 0: // Source text
+ return mci->multiMessageItem(row)->text().simplified().remove(QLatin1Char('&'));
+ case 1: // Dummy column
+ return QVariant();
+ default:
+ if (MessageItem *msgItem = mci->messageItem(column, row)) {
+ int rslt = !msgItem->translation().isEmpty();
+ if (!msgItem->danger())
+ rslt |= 2;
+ if (msgItem->isObsolete())
+ rslt |= 8;
+ else if (msgItem->isFinished())
+ rslt |= 4;
+ return rslt;
+ }
+ return INT_MAX;
+ }
+ }
+ else if (role == Qt::ForegroundRole && column > 0
+ && mci->multiMessageItem(row)->isObsolete()) {
+ return QBrush(Qt::darkGray);
+ }
+ else if (role == Qt::ForegroundRole && column == numLangs
+ && mci->multiMessageItem(row)->text().isEmpty()) {
+ return QBrush(QColor(0, 0xa0, 0xa0));
+ }
+ else if (role == Qt::BackgroundRole) {
+ if (column < numLangs && numLangs != 1)
+ return m_data->brushForModel(column);
+ }
+ } else {
+ // this is a context
+ if (row >= m_data->contextCount() || !index.isValid())
+ return QVariant();
+
+ MultiContextItem *mci = m_data->multiContextItem(row);
+
+ if (role == Qt::DisplayRole || (role == Qt::ToolTipRole && column == numLangs)) {
+ switch (column - numLangs) {
+ case 0: // Context
+ {
+ if (mci->context().isEmpty())
+ return tr("<unnamed context>");
+ return mci->context().simplified();
+ }
+ case 1:
+ {
+ QString s;
+ s.sprintf("%d/%d", mci->getNumFinished(), mci->getNumEditable());
+ return s;
+ }
+ default:
+ return QVariant(); // Status => no text
+ }
+ }
+ else if (role == Qt::DecorationRole && column < numLangs) {
+ if (ContextItem *contextItem = mci->contextItem(column)) {
+ if (contextItem->isObsolete())
+ return pxObsolete;
+ if (contextItem->isFinished())
+ return contextItem->finishedDangerCount() > 0 ? pxWarning : pxOn;
+ return contextItem->unfinishedDangerCount() > 0 ? pxDanger : pxOff;
+ }
+ return QVariant();
+ }
+ else if (role == SortRole) {
+ switch (column - numLangs) {
+ case 0: // Context (same as display role)
+ return mci->context().simplified();
+ case 1: // Items
+ return mci->getNumEditable();
+ default: // Percent
+ if (ContextItem *contextItem = mci->contextItem(column)) {
+ int totalItems = contextItem->nonobsoleteCount();
+ int percent = totalItems ? (100 * contextItem->finishedCount()) / totalItems : 100;
+ int rslt = percent * (((1 << 28) - 1) / 100) + totalItems;
+ if (contextItem->isObsolete()) {
+ rslt |= (1 << 30);
+ } else if (contextItem->isFinished()) {
+ rslt |= (1 << 29);
+ if (!contextItem->finishedDangerCount())
+ rslt |= (1 << 28);
+ } else {
+ if (!contextItem->unfinishedDangerCount())
+ rslt |= (1 << 28);
+ }
+ return rslt;
+ }
+ return INT_MAX;
+ }
+ }
+ else if (role == Qt::ForegroundRole && column >= numLangs
+ && m_data->multiContextItem(row)->isObsolete()) {
+ return QBrush(Qt::darkGray);
+ }
+ else if (role == Qt::ForegroundRole && column == numLangs
+ && m_data->multiContextItem(row)->context().isEmpty()) {
+ return QBrush(QColor(0, 0xa0, 0xa0));
+ }
+ else if (role == Qt::BackgroundRole) {
+ if (column < numLangs && numLangs != 1) {
+ QBrush brush = m_data->brushForModel(column);
+ if (row & 1) {
+ brush.setColor(brush.color().darker(108));
+ }
+ return brush;
+ }
+ }
+ }
+ return QVariant();
+}
+
+MultiDataIndex MessageModel::dataIndex(const QModelIndex &index, int model) const
+{
+ Q_ASSERT(index.isValid());
+ Q_ASSERT(index.internalId());
+ return MultiDataIndex(model, index.internalId() - 1, index.row());
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/messagemodel.h b/src/linguist/linguist/messagemodel.h
new file mode 100644
index 000000000..d8ca9d8e8
--- /dev/null
+++ b/src/linguist/linguist/messagemodel.h
@@ -0,0 +1,535 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGEMODEL_H
+#define MESSAGEMODEL_H
+
+#include "translator.h"
+
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QList>
+#include <QtCore/QHash>
+#include <QtCore/QLocale>
+#include <QtGui/QColor>
+#include <QtGui/QBitmap>
+#include <QtXml/QXmlDefaultHandler>
+
+
+QT_BEGIN_NAMESPACE
+
+class DataModel;
+class MultiDataModel;
+
+class MessageItem
+{
+public:
+ MessageItem(const TranslatorMessage &message);
+
+ bool danger() const { return m_danger; }
+ void setDanger(bool danger) { m_danger = danger; }
+
+ void setTranslation(const QString &translation)
+ { m_message.setTranslation(translation); }
+
+ QString context() const { return m_message.context(); }
+ QString text() const { return m_message.sourceText(); }
+ QString pluralText() const { return m_message.extra(QLatin1String("po-msgid_plural")); }
+ QString comment() const { return m_message.comment(); }
+ QString fileName() const { return m_message.fileName(); }
+ QString extraComment() const { return m_message.extraComment(); }
+ QString translatorComment() const { return m_message.translatorComment(); }
+ void setTranslatorComment(const QString &cmt) { m_message.setTranslatorComment(cmt); }
+ int lineNumber() const { return m_message.lineNumber(); }
+ QString translation() const { return m_message.translation(); }
+ QStringList translations() const { return m_message.translations(); }
+ void setTranslations(const QStringList &translations)
+ { m_message.setTranslations(translations); }
+
+ TranslatorMessage::Type type() const { return m_message.type(); }
+ void setType(TranslatorMessage::Type type) { m_message.setType(type); }
+
+ bool isFinished() const { return type() == TranslatorMessage::Finished; }
+ bool isObsolete() const { return type() == TranslatorMessage::Obsolete; }
+ const TranslatorMessage &message() const { return m_message; }
+
+ bool compare(const QString &findText, bool matchSubstring,
+ Qt::CaseSensitivity cs) const;
+
+private:
+ TranslatorMessage m_message;
+ bool m_danger;
+};
+
+
+class ContextItem
+{
+public:
+ ContextItem(const QString &context);
+
+ int finishedDangerCount() const { return m_finishedDangerCount; }
+ int unfinishedDangerCount() const { return m_unfinishedDangerCount; }
+
+ int finishedCount() const { return m_finishedCount; }
+ int unfinishedCount() const { return m_nonobsoleteCount - m_finishedCount; }
+ int nonobsoleteCount() const { return m_nonobsoleteCount; }
+
+ QString context() const { return m_context; }
+ QString comment() const { return m_comment; }
+ QString fullContext() const { return m_comment.trimmed(); }
+
+ // For item status in context list
+ bool isObsolete() const { return !nonobsoleteCount(); }
+ bool isFinished() const { return unfinishedCount() == 0; }
+
+ MessageItem *messageItem(int i) const;
+ int messageCount() const { return msgItemList.count(); }
+
+ MessageItem *findMessage(const QString &sourcetext, const QString &comment) const;
+
+private:
+ friend class DataModel;
+ friend class MultiDataModel;
+ void appendMessage(const MessageItem &msg) { msgItemList.append(msg); }
+ void appendToComment(const QString &x);
+ void incrementFinishedCount() { ++m_finishedCount; }
+ void decrementFinishedCount() { --m_finishedCount; }
+ void incrementFinishedDangerCount() { ++m_finishedDangerCount; }
+ void decrementFinishedDangerCount() { --m_finishedDangerCount; }
+ void incrementUnfinishedDangerCount() { ++m_unfinishedDangerCount; }
+ void decrementUnfinishedDangerCount() { --m_unfinishedDangerCount; }
+ void incrementNonobsoleteCount() { ++m_nonobsoleteCount; }
+
+ QString m_comment;
+ QString m_context;
+ int m_finishedCount;
+ int m_finishedDangerCount;
+ int m_unfinishedDangerCount;
+ int m_nonobsoleteCount;
+ QList<MessageItem> msgItemList;
+};
+
+
+class DataIndex
+{
+public:
+ DataIndex() : m_context(-1), m_message(-1) {}
+ DataIndex(int context, int message) : m_context(context), m_message(message) {}
+ int context() const { return m_context; }
+ int message() const { return m_message; }
+ bool isValid() const { return m_context >= 0; }
+protected:
+ int m_context;
+ int m_message;
+};
+
+
+class DataModelIterator : public DataIndex
+{
+public:
+ DataModelIterator(DataModel *model, int contextNo = 0, int messageNo = 0);
+ MessageItem *current() const;
+ bool isValid() const;
+ void operator++();
+private:
+ DataModelIterator() {}
+ DataModel *m_model; // not owned
+};
+
+
+class DataModel : public QObject
+{
+ Q_OBJECT
+public:
+ DataModel(QObject *parent = 0);
+
+ enum FindLocation { NoLocation = 0, SourceText = 0x1, Translations = 0x2, Comments = 0x4 };
+
+ // Specializations
+ int contextCount() const { return m_contextList.count(); }
+ ContextItem *findContext(const QString &context) const;
+ MessageItem *findMessage(const QString &context, const QString &sourcetext,
+ const QString &comment) const;
+
+ ContextItem *contextItem(int index) const;
+ MessageItem *messageItem(const DataIndex &index) const;
+
+ int messageCount() const { return m_numMessages; }
+ bool isEmpty() const { return m_numMessages == 0; }
+ bool isModified() const { return m_modified; }
+ void setModified(bool dirty);
+ bool isWritable() const { return m_writable; }
+ void setWritable(bool writable) { m_writable = writable; }
+
+ bool isWellMergeable(const DataModel *other) const;
+ bool load(const QString &fileName, bool *langGuessed, QWidget *parent);
+ bool save(QWidget *parent) { return save(m_srcFileName, parent); }
+ bool saveAs(const QString &newFileName, QWidget *parent);
+ bool release(const QString &fileName, bool verbose,
+ bool ignoreUnfinished, TranslatorSaveMode mode, QWidget *parent);
+ QString srcFileName(bool pretty = false) const
+ { return pretty ? prettifyPlainFileName(m_srcFileName) : m_srcFileName; }
+
+ static QString prettifyPlainFileName(const QString &fn);
+ static QString prettifyFileName(const QString &fn);
+
+ bool setLanguageAndCountry(QLocale::Language lang, QLocale::Country country);
+ QLocale::Language language() const { return m_language; }
+ QLocale::Country country() const { return m_country; }
+ void setSourceLanguageAndCountry(QLocale::Language lang, QLocale::Country country);
+ QLocale::Language sourceLanguage() const { return m_sourceLanguage; }
+ QLocale::Country sourceCountry() const { return m_sourceCountry; }
+
+ const QString &localizedLanguage() const { return m_localizedLanguage; }
+ const QStringList &numerusForms() const { return m_numerusForms; }
+ const QList<bool> &countRefNeeds() const { return m_countRefNeeds; }
+
+ QStringList normalizedTranslations(const MessageItem &m) const;
+ void doCharCounting(const QString& text, int& trW, int& trC, int& trCS);
+ void updateStatistics();
+
+ int getSrcWords() const { return m_srcWords; }
+ int getSrcChars() const { return m_srcChars; }
+ int getSrcCharsSpc() const { return m_srcCharsSpc; }
+
+signals:
+ void statsChanged(int words, int characters, int cs, int words2, int characters2, int cs2);
+ void progressChanged(int finishedCount, int oldFinishedCount);
+ void languageChanged();
+ void modifiedChanged();
+
+private:
+ friend class DataModelIterator;
+ QList<ContextItem> m_contextList;
+
+ bool save(const QString &fileName, QWidget *parent);
+ void updateLocale();
+
+ bool m_writable;
+ bool m_modified;
+
+ int m_numMessages;
+
+ // For statistics
+ int m_srcWords;
+ int m_srcChars;
+ int m_srcCharsSpc;
+
+ QString m_srcFileName;
+ QLocale::Language m_language;
+ QLocale::Language m_sourceLanguage;
+ QLocale::Country m_country;
+ QLocale::Country m_sourceCountry;
+ QByteArray m_codecName;
+ bool m_relativeLocations;
+ Translator::ExtraData m_extra;
+
+ QString m_localizedLanguage;
+ QStringList m_numerusForms;
+ QList<bool> m_countRefNeeds;
+};
+
+
+struct MultiMessageItem
+{
+public:
+ MultiMessageItem(const MessageItem *m);
+ QString text() const { return m_text; }
+ QString pluralText() const { return m_pluralText; }
+ QString comment() const { return m_comment; }
+ bool isEmpty() const { return !m_nonnullCount; }
+ // The next two include also read-only
+ bool isObsolete() const { return m_nonnullCount && !m_nonobsoleteCount; }
+ int countNonobsolete() const { return m_nonobsoleteCount; }
+ // The next three include only read-write
+ int countEditable() const { return m_editableCount; }
+ bool isUnfinished() const { return m_unfinishedCount != 0; }
+ int countUnfinished() const { return m_unfinishedCount; }
+
+private:
+ friend class MultiDataModel;
+ void incrementNonnullCount() { ++m_nonnullCount; }
+ void decrementNonnullCount() { --m_nonnullCount; }
+ void incrementNonobsoleteCount() { ++m_nonobsoleteCount; }
+ void decrementNonobsoleteCount() { --m_nonobsoleteCount; }
+ void incrementEditableCount() { ++m_editableCount; }
+ void decrementEditableCount() { --m_editableCount; }
+ void incrementUnfinishedCount() { ++m_unfinishedCount; }
+ void decrementUnfinishedCount() { --m_unfinishedCount; }
+
+ QString m_text;
+ QString m_pluralText;
+ QString m_comment;
+ int m_nonnullCount; // all
+ int m_nonobsoleteCount; // all
+ int m_editableCount; // read-write
+ int m_unfinishedCount; // read-write
+};
+
+struct MultiContextItem
+{
+public:
+ MultiContextItem(int oldCount, ContextItem *ctx, bool writable);
+
+ ContextItem *contextItem(int model) const { return m_contextList[model]; }
+
+ MultiMessageItem *multiMessageItem(int msgIdx) const
+ { return const_cast<MultiMessageItem *>(&m_multiMessageList[msgIdx]); }
+ MessageItem *messageItem(int model, int msgIdx) const { return m_messageLists[model][msgIdx]; }
+ int firstNonobsoleteMessageIndex(int msgIdx) const;
+ int findMessage(const QString &sourcetext, const QString &comment) const;
+
+ QString context() const { return m_context; }
+ QString comment() const { return m_comment; }
+ int messageCount() const { return m_messageLists.isEmpty() ? 0 : m_messageLists[0].count(); }
+ // For item count in context list
+ int getNumFinished() const { return m_finishedCount; }
+ int getNumEditable() const { return m_editableCount; }
+ // For background in context list
+ bool isObsolete() const { return messageCount() && !m_nonobsoleteCount; }
+
+private:
+ friend class MultiDataModel;
+ void appendEmptyModel();
+ void assignLastModel(ContextItem *ctx, bool writable);
+ void removeModel(int pos);
+ void moveModel(int oldPos, int newPos); // newPos is *before* removing at oldPos
+ void putMessageItem(int pos, MessageItem *m);
+ void appendMessageItems(const QList<MessageItem *> &m);
+ void removeMultiMessageItem(int pos);
+ void incrementFinishedCount() { ++m_finishedCount; }
+ void decrementFinishedCount() { --m_finishedCount; }
+ void incrementEditableCount() { ++m_editableCount; }
+ void decrementEditableCount() { --m_editableCount; }
+ void incrementNonobsoleteCount() { ++m_nonobsoleteCount; }
+ void decrementNonobsoleteCount() { --m_nonobsoleteCount; }
+
+ QString m_context;
+ QString m_comment;
+ QList<MultiMessageItem> m_multiMessageList;
+ QList<ContextItem *> m_contextList;
+ // The next two could be in the MultiMessageItems, but are here for efficiency
+ QList<QList<MessageItem *> > m_messageLists;
+ QList<QList<MessageItem *> *> m_writableMessageLists;
+ int m_finishedCount; // read-write
+ int m_editableCount; // read-write
+ int m_nonobsoleteCount; // all (note: this counts messages, not multi-messages)
+};
+
+
+class MultiDataIndex
+{
+public:
+ MultiDataIndex() : m_model(-1), m_context(-1), m_message(-1) {}
+ MultiDataIndex(int model, int context, int message)
+ : m_model(model), m_context(context), m_message(message) {}
+ void setModel(int model) { m_model = model; }
+ int model() const { return m_model; }
+ int context() const { return m_context; }
+ int message() const { return m_message; }
+ bool isValid() const { return m_context >= 0; }
+ bool operator==(const MultiDataIndex &other) const
+ { return m_model == other.m_model && m_context == other.m_context && m_message == other.m_message; }
+ bool operator!=(const MultiDataIndex &other) const { return !(*this == other); }
+protected:
+ int m_model;
+ int m_context;
+ int m_message;
+};
+
+
+class MultiDataModelIterator : public MultiDataIndex
+{
+public:
+ MultiDataModelIterator(MultiDataModel *model, int modelNo, int contextNo = 0, int messageNo = 0);
+ MessageItem *current() const;
+ bool isValid() const;
+ void operator++();
+private:
+ MultiDataModelIterator() {}
+ MultiDataModel *m_dataModel; // not owned
+};
+
+
+class MessageModel;
+
+class MultiDataModel : public QObject
+{
+ Q_OBJECT
+
+public:
+ MultiDataModel(QObject *parent = 0);
+ ~MultiDataModel();
+
+ bool isWellMergeable(const DataModel *dm) const;
+ void append(DataModel *dm, bool readWrite);
+ bool save(int model, QWidget *parent) { return m_dataModels[model]->save(parent); }
+ bool saveAs(int model, const QString &newFileName, QWidget *parent)
+ { return m_dataModels[model]->saveAs(newFileName, parent); }
+ bool release(int model, const QString &fileName, bool verbose, bool ignoreUnfinished, TranslatorSaveMode mode, QWidget *parent)
+ { return m_dataModels[model]->release(fileName, verbose, ignoreUnfinished, mode, parent); }
+ void close(int model);
+ void closeAll();
+ int isFileLoaded(const QString &name) const;
+ void moveModel(int oldPos, int newPos); // newPos is *before* removing at oldPos; note that this does not emit update signals
+
+ // Entire multi-model
+ int modelCount() const { return m_dataModels.count(); }
+ int contextCount() const { return m_multiContextList.count(); }
+ int messageCount() const { return m_numMessages; }
+ // Next two needed for progress indicator in main window
+ int getNumFinished() const { return m_numFinished; }
+ int getNumEditable() const { return m_numEditable; }
+ bool isModified() const;
+ QStringList srcFileNames(bool pretty = false) const;
+ QString condensedSrcFileNames(bool pretty = false) const;
+
+ // Per submodel
+ QString srcFileName(int model, bool pretty = false) const { return m_dataModels[model]->srcFileName(pretty); }
+ bool isModelWritable(int model) const { return m_dataModels[model]->isWritable(); }
+ bool isModified(int model) const { return m_dataModels[model]->isModified(); }
+ void setModified(int model, bool dirty) { m_dataModels[model]->setModified(dirty); }
+ QLocale::Language language(int model) const { return m_dataModels[model]->language(); }
+ QLocale::Language sourceLanguage(int model) const { return m_dataModels[model]->sourceLanguage(); }
+
+ // Per message
+ void setTranslation(const MultiDataIndex &index, const QString &translation);
+ void setFinished(const MultiDataIndex &index, bool finished);
+ void setDanger(const MultiDataIndex &index, bool danger);
+
+ // Retrieve items
+ DataModel *model(int i) { return m_dataModels[i]; }
+ MultiContextItem *multiContextItem(int ctxIdx) const
+ { return const_cast<MultiContextItem *>(&m_multiContextList[ctxIdx]); }
+ MultiMessageItem *multiMessageItem(const MultiDataIndex &index) const
+ { return multiContextItem(index.context())->multiMessageItem(index.message()); }
+ MessageItem *messageItem(const MultiDataIndex &index, int model) const;
+ MessageItem *messageItem(const MultiDataIndex &index) const { return messageItem(index, index.model()); }
+
+ static QString condenseFileNames(const QStringList &names);
+ static QStringList prettifyFileNames(const QStringList &names);
+
+ QBrush brushForModel(int model) const;
+
+signals:
+ void modelAppended();
+ void modelDeleted(int model);
+ void allModelsDeleted();
+ void languageChanged(int model);
+ void statsChanged(int words, int characters, int cs, int words2, int characters2, int cs2);
+ void modifiedChanged(bool);
+ void multiContextDataChanged(const MultiDataIndex &index);
+ void contextDataChanged(const MultiDataIndex &index);
+ void messageDataChanged(const MultiDataIndex &index);
+ void translationChanged(const MultiDataIndex &index); // Only the primary one
+
+private slots:
+ void onModifiedChanged();
+ void onLanguageChanged();
+
+private:
+ friend class MultiDataModelIterator;
+ friend class MessageModel;
+
+ int findContextIndex(const QString &context) const;
+ MultiContextItem *findContext(const QString &context) const;
+
+ ContextItem *contextItem(const MultiDataIndex &index) const
+ { return multiContextItem(index.context())->contextItem(index.model()); }
+
+ void updateCountsOnAdd(int model, bool writable);
+ void updateCountsOnRemove(int model, bool writable);
+ void incrementFinishedCount() { ++m_numFinished; }
+ void decrementFinishedCount() { --m_numFinished; }
+ void incrementEditableCount() { ++m_numEditable; }
+ void decrementEditableCount() { --m_numEditable; }
+
+ int m_numFinished;
+ int m_numEditable;
+ int m_numMessages;
+
+ bool m_modified;
+
+ QList<MultiContextItem> m_multiContextList;
+ QList<DataModel *> m_dataModels;
+
+ MessageModel *m_msgModel;
+
+ QColor m_colors[7];
+ QBitmap m_bitmap;
+};
+
+class MessageModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ enum { SortRole = Qt::UserRole };
+
+ MessageModel(QObject *parent, MultiDataModel *data);
+
+ // QAbstractItemModel
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+ // Convenience
+ MultiDataIndex dataIndex(const QModelIndex &index, int model) const;
+ MultiDataIndex dataIndex(const QModelIndex &index) const
+ { return dataIndex(index, index.column() - 1 < m_data->modelCount() ? index.column() - 1 : -1); }
+ QModelIndex modelIndex(const MultiDataIndex &index);
+
+private slots:
+ void reset() { QAbstractItemModel::reset(); }
+ void multiContextItemChanged(const MultiDataIndex &index);
+ void contextItemChanged(const MultiDataIndex &index);
+ void messageItemChanged(const MultiDataIndex &index);
+
+private:
+ friend class MultiDataModel;
+
+ MultiDataModel *m_data; // not owned
+};
+
+QT_END_NAMESPACE
+
+#endif // MESSAGEMODEL_H
diff --git a/src/linguist/linguist/phrase.cpp b/src/linguist/linguist/phrase.cpp
new file mode 100644
index 000000000..2f51c42bd
--- /dev/null
+++ b/src/linguist/linguist/phrase.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "phrase.h"
+#include "translator.h"
+
+#include <QApplication>
+#include <QFile>
+#include <QFileInfo>
+#include <QMessageBox>
+#include <QRegExp>
+#include <QTextCodec>
+#include <QTextStream>
+#include <QXmlAttributes>
+#include <QXmlDefaultHandler>
+#include <QXmlParseException>
+
+QT_BEGIN_NAMESPACE
+
+static QString protect(const QString & str)
+{
+ QString p = str;
+ p.replace(QLatin1Char('&'), QLatin1String("&amp;"));
+ p.replace(QLatin1Char('\"'), QLatin1String("&quot;"));
+ p.replace(QLatin1Char('>'), QLatin1String("&gt;"));
+ p.replace(QLatin1Char('<'), QLatin1String("&lt;"));
+ p.replace(QLatin1Char('\''), QLatin1String("&apos;"));
+ return p;
+}
+
+Phrase::Phrase()
+ : shrtc(-1), m_phraseBook(0)
+{
+}
+
+Phrase::Phrase(const QString &source, const QString &target,
+ const QString &definition, int sc)
+ : shrtc(sc), s(source), t(target), d(definition),
+ m_phraseBook(0)
+{
+}
+
+Phrase::Phrase(const QString &source, const QString &target,
+ const QString &definition, PhraseBook *phraseBook)
+ : shrtc(-1), s(source), t(target), d(definition),
+ m_phraseBook(phraseBook)
+{
+}
+
+void Phrase::setSource(const QString &ns)
+{
+ if (s == ns)
+ return;
+ s = ns;
+ if (m_phraseBook)
+ m_phraseBook->phraseChanged(this);
+}
+
+void Phrase::setTarget(const QString &nt)
+{
+ if (t == nt)
+ return;
+ t = nt;
+ if (m_phraseBook)
+ m_phraseBook->phraseChanged(this);
+}
+
+void Phrase::setDefinition(const QString &nd)
+{
+ if (d == nd)
+ return;
+ d = nd;
+ if (m_phraseBook)
+ m_phraseBook->phraseChanged(this);
+}
+
+bool operator==(const Phrase &p, const Phrase &q)
+{
+ return p.source() == q.source() && p.target() == q.target() &&
+ p.definition() == q.definition() && p.phraseBook() == q.phraseBook();
+}
+
+class QphHandler : public QXmlDefaultHandler
+{
+public:
+ QphHandler(PhraseBook *phraseBook)
+ : pb(phraseBook), ferrorCount(0) { }
+
+ virtual bool startElement(const QString &namespaceURI,
+ const QString &localName, const QString &qName,
+ const QXmlAttributes &atts);
+ virtual bool endElement(const QString &namespaceURI,
+ const QString &localName, const QString &qName);
+ virtual bool characters(const QString &ch);
+ virtual bool fatalError(const QXmlParseException &exception);
+
+ QString language() const { return m_language; }
+ QString sourceLanguage() const { return m_sourceLanguage; }
+
+private:
+ PhraseBook *pb;
+ QString source;
+ QString target;
+ QString definition;
+ QString m_language;
+ QString m_sourceLanguage;
+
+ QString accum;
+ int ferrorCount;
+};
+
+bool QphHandler::startElement(const QString & /* namespaceURI */,
+ const QString & /* localName */,
+ const QString &qName,
+ const QXmlAttributes &atts)
+{
+ if (qName == QLatin1String("QPH")) {
+ m_language = atts.value(QLatin1String("language"));
+ m_sourceLanguage = atts.value(QLatin1String("sourcelanguage"));
+ } else if (qName == QLatin1String("phrase")) {
+ source.truncate(0);
+ target.truncate(0);
+ definition.truncate(0);
+ }
+ accum.truncate(0);
+ return true;
+}
+
+bool QphHandler::endElement(const QString & /* namespaceURI */,
+ const QString & /* localName */,
+ const QString &qName)
+{
+ if (qName == QLatin1String("source"))
+ source = accum;
+ else if (qName == QLatin1String("target"))
+ target = accum;
+ else if (qName == QLatin1String("definition"))
+ definition = accum;
+ else if (qName == QLatin1String("phrase"))
+ pb->m_phrases.append(new Phrase(source, target, definition, pb));
+ return true;
+}
+
+bool QphHandler::characters(const QString &ch)
+{
+ accum += ch;
+ return true;
+}
+
+bool QphHandler::fatalError(const QXmlParseException &exception)
+{
+ if (ferrorCount++ == 0) {
+ QString msg = PhraseBook::tr("Parse error at line %1, column %2 (%3).")
+ .arg(exception.lineNumber()).arg(exception.columnNumber())
+ .arg(exception.message());
+ QMessageBox::information(0,
+ QObject::tr("Qt Linguist"), msg);
+ }
+ return false;
+}
+
+PhraseBook::PhraseBook() :
+ m_changed(false),
+ m_language(QLocale::C),
+ m_sourceLanguage(QLocale::C),
+ m_country(QLocale::AnyCountry),
+ m_sourceCountry(QLocale::AnyCountry)
+{
+}
+
+PhraseBook::~PhraseBook()
+{
+ qDeleteAll(m_phrases);
+}
+
+void PhraseBook::setLanguageAndCountry(QLocale::Language lang, QLocale::Country country)
+{
+ if (m_language == lang && m_country == country)
+ return;
+ m_language = lang;
+ m_country = country;
+ setModified(true);
+}
+
+void PhraseBook::setSourceLanguageAndCountry(QLocale::Language lang, QLocale::Country country)
+{
+ if (m_sourceLanguage == lang && m_sourceCountry == country)
+ return;
+ m_sourceLanguage = lang;
+ m_sourceCountry = country;
+ setModified(true);
+}
+
+bool PhraseBook::load(const QString &fileName, bool *langGuessed)
+{
+ QFile f(fileName);
+ if (!f.open(QIODevice::ReadOnly))
+ return false;
+
+ m_fileName = fileName;
+
+ QXmlInputSource in(&f);
+ QXmlSimpleReader reader;
+ // don't click on these!
+ reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), false);
+ reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true);
+ reader.setFeature(QLatin1String("http://trolltech.com/xml/features/report-whitespace"
+ "-only-CharData"), false);
+ QphHandler *hand = new QphHandler(this);
+ reader.setContentHandler(hand);
+ reader.setErrorHandler(hand);
+
+ bool ok = reader.parse(in);
+ reader.setContentHandler(0);
+ reader.setErrorHandler(0);
+
+ Translator::languageAndCountry(hand->language(), &m_language, &m_country);
+ *langGuessed = false;
+ if (m_language == QLocale::C) {
+ QLocale sys;
+ m_language = sys.language();
+ m_country = sys.country();
+ *langGuessed = true;
+ }
+
+ QString lang = hand->sourceLanguage();
+ if (lang.isEmpty()) {
+ m_sourceLanguage = QLocale::C;
+ m_sourceCountry = QLocale::AnyCountry;
+ } else {
+ Translator::languageAndCountry(lang, &m_sourceLanguage, &m_sourceCountry);
+ }
+
+ delete hand;
+ f.close();
+ if (!ok) {
+ qDeleteAll(m_phrases);
+ m_phrases.clear();
+ } else {
+ emit listChanged();
+ }
+
+ return ok;
+}
+
+bool PhraseBook::save(const QString &fileName)
+{
+ QFile f(fileName);
+ if (!f.open(QIODevice::WriteOnly))
+ return false;
+
+ m_fileName = fileName;
+
+ QTextStream t(&f);
+ t.setCodec( QTextCodec::codecForName("UTF-8") );
+
+ t << "<!DOCTYPE QPH>\n<QPH";
+ if (sourceLanguage() != QLocale::C)
+ t << " sourcelanguage=\""
+ << Translator::makeLanguageCode(sourceLanguage(), sourceCountry()) << '"';
+ if (language() != QLocale::C)
+ t << " language=\"" << Translator::makeLanguageCode(language(), country()) << '"';
+ t << ">\n";
+ foreach (Phrase *p, m_phrases) {
+ t << "<phrase>\n";
+ t << " <source>" << protect( p->source() ) << "</source>\n";
+ t << " <target>" << protect( p->target() ) << "</target>\n";
+ if (!p->definition().isEmpty())
+ t << " <definition>" << protect( p->definition() )
+ << "</definition>\n";
+ t << "</phrase>\n";
+ }
+ t << "</QPH>\n";
+ f.close();
+ setModified(false);
+ return true;
+}
+
+void PhraseBook::append(Phrase *phrase)
+{
+ m_phrases.append(phrase);
+ phrase->setPhraseBook(this);
+ setModified(true);
+ emit listChanged();
+}
+
+void PhraseBook::remove(Phrase *phrase)
+{
+ m_phrases.removeOne(phrase);
+ phrase->setPhraseBook(0);
+ setModified(true);
+ emit listChanged();
+}
+
+void PhraseBook::setModified(bool modified)
+ {
+ if (m_changed != modified) {
+ emit modifiedChanged(modified);
+ m_changed = modified;
+ }
+}
+
+void PhraseBook::phraseChanged(Phrase *p)
+{
+ Q_UNUSED(p);
+
+ setModified(true);
+}
+
+QString PhraseBook::friendlyPhraseBookName() const
+{
+ if (!m_fileName.isEmpty())
+ return QFileInfo(m_fileName).fileName();
+ return QString();
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/phrase.h b/src/linguist/linguist/phrase.h
new file mode 100644
index 000000000..a46165c46
--- /dev/null
+++ b/src/linguist/linguist/phrase.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PHRASE_H
+#define PHRASE_H
+
+#include <QObject>
+#include <QString>
+#include <QList>
+#include <QtCore/QLocale>
+
+QT_BEGIN_NAMESPACE
+
+class PhraseBook;
+
+class Phrase
+{
+public:
+ Phrase();
+ Phrase(const QString &source, const QString &target,
+ const QString &definition, int sc = -1);
+ Phrase(const QString &source, const QString &target,
+ const QString &definition, PhraseBook *phraseBook);
+
+ QString source() const { return s; }
+ void setSource(const QString &ns);
+ QString target() const {return t;}
+ void setTarget(const QString &nt);
+ QString definition() const {return d;}
+ void setDefinition (const QString &nd);
+ int shortcut() const { return shrtc; }
+ PhraseBook *phraseBook() const { return m_phraseBook; }
+ void setPhraseBook(PhraseBook *book) { m_phraseBook = book; }
+
+private:
+ int shrtc;
+ QString s;
+ QString t;
+ QString d;
+ PhraseBook *m_phraseBook;
+};
+
+bool operator==(const Phrase &p, const Phrase &q);
+inline bool operator!=(const Phrase &p, const Phrase &q) {
+ return !(p == q);
+}
+
+class QphHandler;
+
+class PhraseBook : public QObject
+{
+ Q_OBJECT
+
+public:
+ PhraseBook();
+ ~PhraseBook();
+ bool load(const QString &fileName, bool *langGuessed);
+ bool save(const QString &fileName);
+ QList<Phrase *> phrases() const { return m_phrases; }
+ void append(Phrase *phrase);
+ void remove(Phrase *phrase);
+ QString fileName() const { return m_fileName; }
+ QString friendlyPhraseBookName() const;
+ bool isModified() const { return m_changed; }
+
+ void setLanguageAndCountry(QLocale::Language lang, QLocale::Country country);
+ QLocale::Language language() const { return m_language; }
+ QLocale::Country country() const { return m_country; }
+ void setSourceLanguageAndCountry(QLocale::Language lang, QLocale::Country country);
+ QLocale::Language sourceLanguage() const { return m_sourceLanguage; }
+ QLocale::Country sourceCountry() const { return m_sourceCountry; }
+
+signals:
+ void modifiedChanged(bool changed);
+ void listChanged();
+
+private:
+ // Prevent copying
+ PhraseBook(const PhraseBook &);
+ PhraseBook& operator=(const PhraseBook &);
+
+ void setModified(bool modified);
+ void phraseChanged(Phrase *phrase);
+
+ QList<Phrase *> m_phrases;
+ QString m_fileName;
+ bool m_changed;
+
+ QLocale::Language m_language;
+ QLocale::Language m_sourceLanguage;
+ QLocale::Country m_country;
+ QLocale::Country m_sourceCountry;
+
+ friend class QphHandler;
+ friend class Phrase;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/linguist/linguist/phrasebookbox.cpp b/src/linguist/linguist/phrasebookbox.cpp
new file mode 100644
index 000000000..32d707040
--- /dev/null
+++ b/src/linguist/linguist/phrasebookbox.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* TRANSLATOR PhraseBookBox
+
+ Go to Phrase > Edit Phrase Book... The dialog that pops up is a
+ PhraseBookBox.
+*/
+
+#include "phrasebookbox.h"
+#include "translationsettingsdialog.h"
+
+#include <QtEvents>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QHeaderView>
+#include <QSortFilterProxyModel>
+
+QT_BEGIN_NAMESPACE
+
+PhraseBookBox::PhraseBookBox(PhraseBook *phraseBook, QWidget *parent)
+ : QDialog(parent),
+ m_phraseBook(phraseBook),
+ m_translationSettingsDialog(0)
+{
+
+// This definition needs to be within class context for lupdate to find it
+#define NewPhrase tr("(New Entry)")
+
+ setupUi(this);
+ setWindowTitle(tr("%1[*] - Qt Linguist").arg(m_phraseBook->friendlyPhraseBookName()));
+ setWindowModified(m_phraseBook->isModified());
+
+ phrMdl = new PhraseModel(this);
+
+ m_sortedPhraseModel = new QSortFilterProxyModel(this);
+ m_sortedPhraseModel->setSortCaseSensitivity(Qt::CaseInsensitive);
+ m_sortedPhraseModel->setSortLocaleAware(true);
+ m_sortedPhraseModel->setDynamicSortFilter(true);
+ m_sortedPhraseModel->setSourceModel(phrMdl);
+
+ phraseList->setModel(m_sortedPhraseModel);
+ phraseList->header()->setDefaultSectionSize(150);
+ phraseList->header()->setResizeMode(QHeaderView::Interactive);
+
+ connect(sourceLed, SIGNAL(textChanged(QString)),
+ this, SLOT(sourceChanged(QString)));
+ connect(targetLed, SIGNAL(textChanged(QString)),
+ this, SLOT(targetChanged(QString)));
+ connect(definitionLed, SIGNAL(textChanged(QString)),
+ this, SLOT(definitionChanged(QString)));
+ connect(phraseList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(selectionChanged()));
+ connect(newBut, SIGNAL(clicked()), this, SLOT(newPhrase()));
+ connect(removeBut, SIGNAL(clicked()), this, SLOT(removePhrase()));
+ connect(settingsBut, SIGNAL(clicked()), this, SLOT(settings()));
+ connect(saveBut, SIGNAL(clicked()), this, SLOT(save()));
+ connect(m_phraseBook, SIGNAL(modifiedChanged(bool)), this, SLOT(setWindowModified(bool)));
+
+ sourceLed->installEventFilter(this);
+ targetLed->installEventFilter(this);
+ definitionLed->installEventFilter(this);
+
+ foreach (Phrase *p, phraseBook->phrases())
+ phrMdl->addPhrase(p);
+
+ phraseList->sortByColumn(0, Qt::AscendingOrder);
+
+ enableDisable();
+}
+
+bool PhraseBookBox::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::KeyPress &&
+ (obj == sourceLed || obj == targetLed || obj == definitionLed))
+ {
+ const QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ const int key = keyEvent->key();
+
+ switch (key) {
+ case Qt::Key_Down:
+ case Qt::Key_Up:
+ case Qt::Key_PageDown:
+ case Qt::Key_PageUp:
+ return QApplication::sendEvent(phraseList, event);
+ }
+ }
+ return QDialog::eventFilter(obj, event);
+}
+
+void PhraseBookBox::newPhrase()
+{
+ Phrase *p = new Phrase();
+ p->setSource(NewPhrase);
+ m_phraseBook->append(p);
+ selectItem(phrMdl->addPhrase(p));
+}
+
+void PhraseBookBox::removePhrase()
+{
+ QModelIndex index = currentPhraseIndex();
+ Phrase *phrase = phrMdl->phrase(index);
+ m_phraseBook->remove(phrase);
+ phrMdl->removePhrase(index);
+ delete phrase;
+}
+
+void PhraseBookBox::settings()
+{
+ if (!m_translationSettingsDialog)
+ m_translationSettingsDialog = new TranslationSettingsDialog(this);
+ m_translationSettingsDialog->setPhraseBook(m_phraseBook);
+ m_translationSettingsDialog->exec();
+}
+
+void PhraseBookBox::save()
+{
+ const QString &fileName = m_phraseBook->fileName();
+ if (!m_phraseBook->save(fileName))
+ QMessageBox::warning(this,
+ tr("Qt Linguist"),
+ tr("Cannot save phrase book '%1'.").arg(fileName));
+}
+
+void PhraseBookBox::sourceChanged(const QString& source)
+{
+ QModelIndex index = currentPhraseIndex();
+ if (index.isValid())
+ phrMdl->setData(phrMdl->index(index.row(), 0), source);
+}
+
+void PhraseBookBox::targetChanged(const QString& target)
+{
+ QModelIndex index = currentPhraseIndex();
+ if (index.isValid())
+ phrMdl->setData(phrMdl->index(index.row(), 1), target);
+}
+
+void PhraseBookBox::definitionChanged(const QString& definition)
+{
+ QModelIndex index = currentPhraseIndex();
+ if (index.isValid())
+ phrMdl->setData(phrMdl->index(index.row(), 2), definition);
+}
+
+void PhraseBookBox::selectionChanged()
+{
+ enableDisable();
+}
+
+void PhraseBookBox::selectItem(const QModelIndex &index)
+{
+ const QModelIndex &sortedIndex = m_sortedPhraseModel->mapFromSource(index);
+ phraseList->scrollTo(sortedIndex);
+ phraseList->setCurrentIndex(sortedIndex);
+}
+
+void PhraseBookBox::enableDisable()
+{
+ QModelIndex index = currentPhraseIndex();
+
+ sourceLed->blockSignals(true);
+ targetLed->blockSignals(true);
+ definitionLed->blockSignals(true);
+
+ bool indexValid = index.isValid();
+
+ if (indexValid) {
+ Phrase *p = phrMdl->phrase(index);
+ sourceLed->setText(p->source().simplified());
+ targetLed->setText(p->target().simplified());
+ definitionLed->setText(p->definition());
+ }
+ else {
+ sourceLed->setText(QString());
+ targetLed->setText(QString());
+ definitionLed->setText(QString());
+ }
+
+ sourceLed->setEnabled(indexValid);
+ targetLed->setEnabled(indexValid);
+ definitionLed->setEnabled(indexValid);
+ removeBut->setEnabled(indexValid);
+
+ sourceLed->blockSignals(false);
+ targetLed->blockSignals(false);
+ definitionLed->blockSignals(false);
+
+ QWidget *f = QApplication::focusWidget();
+ if (f != sourceLed && f != targetLed && f != definitionLed) {
+ QLineEdit *led = (sourceLed->text() == NewPhrase ? sourceLed : targetLed);
+ led->setFocus();
+ led->selectAll();
+ } else {
+ static_cast<QLineEdit*>(f)->selectAll();
+ }
+}
+
+QModelIndex PhraseBookBox::currentPhraseIndex() const
+{
+ return m_sortedPhraseModel->mapToSource(phraseList->currentIndex());
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/phrasebookbox.h b/src/linguist/linguist/phrasebookbox.h
new file mode 100644
index 000000000..3cf2ce8a3
--- /dev/null
+++ b/src/linguist/linguist/phrasebookbox.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PHRASEBOOKBOX_H
+#define PHRASEBOOKBOX_H
+
+#include "ui_phrasebookbox.h"
+#include "phrase.h"
+#include "phrasemodel.h"
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class TranslationSettingsDialog;
+
+class QSortFilterProxyModel;
+
+class PhraseBookBox : public QDialog, public Ui::PhraseBookBox
+{
+ Q_OBJECT
+public:
+ PhraseBookBox(PhraseBook *phraseBook, QWidget *parent = 0);
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *event);
+
+private slots:
+ void newPhrase();
+ void removePhrase();
+ void settings();
+ void save();
+ void sourceChanged(const QString &source);
+ void targetChanged(const QString &target);
+ void definitionChanged(const QString &definition);
+ void selectionChanged();
+
+private:
+ void selectItem(const QModelIndex &index);
+ void enableDisable();
+ QModelIndex currentPhraseIndex() const;
+
+ QString fn;
+ PhraseBook *m_phraseBook;
+ PhraseModel *phrMdl;
+ QSortFilterProxyModel *m_sortedPhraseModel;
+ TranslationSettingsDialog *m_translationSettingsDialog;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/linguist/linguist/phrasebookbox.ui b/src/linguist/linguist/phrasebookbox.ui
new file mode 100644
index 000000000..5c29d5ea1
--- /dev/null
+++ b/src/linguist/linguist/phrasebookbox.ui
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>PhraseBookBox</class>
+ <widget class="QDialog" name="PhraseBookBox">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>596</width>
+ <height>454</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Edit Phrase Book</string>
+ </property>
+ <property name="whatsThis">
+ <string>This window allows you to add, modify, or delete entries in a phrase book.</string>
+ </property>
+ <layout class="QHBoxLayout" name="hboxLayout">
+ <item>
+ <layout class="QVBoxLayout" name="inputsLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLabel" name="target">
+ <property name="text">
+ <string>&amp;Translation:</string>
+ </property>
+ <property name="buddy">
+ <cstring>targetLed</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="targetLed">
+ <property name="whatsThis">
+ <string>This is the phrase in the target language corresponding to the source phrase.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="source">
+ <property name="text">
+ <string>S&amp;ource phrase:</string>
+ </property>
+ <property name="buddy">
+ <cstring>sourceLed</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="definitionLed">
+ <property name="whatsThis">
+ <string>This is a definition for the source phrase.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="sourceLed">
+ <property name="whatsThis">
+ <string>This is the phrase in the source language.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="definition">
+ <property name="text">
+ <string>&amp;Definition:</string>
+ </property>
+ <property name="buddy">
+ <cstring>definitionLed</cstring>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeView" name="phraseList">
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>false</bool>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="expandsOnDoubleClick">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="buttonLayout">
+ <item>
+ <widget class="QPushButton" name="newBut">
+ <property name="whatsThis">
+ <string>Click here to add the phrase to the phrase book.</string>
+ </property>
+ <property name="text">
+ <string>&amp;New Entry</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeBut">
+ <property name="whatsThis">
+ <string>Click here to remove the entry from the phrase book.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Remove Entry</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="settingsBut">
+ <property name="text">
+ <string>Settin&amp;gs...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="saveBut">
+ <property name="whatsThis">
+ <string>Click here to save the changes made.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeBut">
+ <property name="whatsThis">
+ <string>Click here to close this window.</string>
+ </property>
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer1">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>51</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>sourceLed</tabstop>
+ <tabstop>targetLed</tabstop>
+ <tabstop>definitionLed</tabstop>
+ <tabstop>newBut</tabstop>
+ <tabstop>removeBut</tabstop>
+ <tabstop>saveBut</tabstop>
+ <tabstop>closeBut</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>closeBut</sender>
+ <signal>clicked()</signal>
+ <receiver>PhraseBookBox</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>545</x>
+ <y>166</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>545</x>
+ <y>199</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/linguist/linguist/phrasemodel.cpp b/src/linguist/linguist/phrasemodel.cpp
new file mode 100644
index 000000000..e28b64927
--- /dev/null
+++ b/src/linguist/linguist/phrasemodel.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "phrasemodel.h"
+
+QT_BEGIN_NAMESPACE
+
+void PhraseModel::removePhrases()
+{
+ int r = plist.count();
+ if (r > 0) {
+ plist.clear();
+ reset();
+ }
+}
+
+Phrase *PhraseModel::phrase(const QModelIndex &index) const
+{
+ return plist.at(index.row());
+}
+
+void PhraseModel::setPhrase(const QModelIndex &indx, Phrase *ph)
+{
+ int r = indx.row();
+
+ plist[r] = ph;
+
+ // update item in view
+ const QModelIndex &si = index(r, 0);
+ const QModelIndex &ei = index(r, 2);
+ emit dataChanged(si, ei);
+}
+
+QModelIndex PhraseModel::addPhrase(Phrase *p)
+{
+ int r = plist.count();
+
+ plist.append(p);
+
+ // update phrases as we add them
+ beginInsertRows(QModelIndex(), r, r);
+ QModelIndex i = index(r, 0);
+ endInsertRows();
+ return i;
+}
+
+void PhraseModel::removePhrase(const QModelIndex &index)
+{
+ int r = index.row();
+ beginRemoveRows(QModelIndex(), r, r);
+ plist.removeAt(r);
+ endRemoveRows();
+}
+
+QModelIndex PhraseModel::index(Phrase * const phr) const
+{
+ int row;
+ if ((row = plist.indexOf(phr)) == -1)
+ return QModelIndex();
+
+ return index(row, 0);
+}
+
+int PhraseModel::rowCount(const QModelIndex &) const
+{
+ return plist.count();
+}
+
+int PhraseModel::columnCount(const QModelIndex &) const
+{
+ return 3;
+}
+
+QVariant PhraseModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if ((role == Qt::DisplayRole) && (orientation == Qt::Horizontal)) {
+ switch(section) {
+ case 0:
+ return tr("Source phrase");
+ case 1:
+ return tr("Translation");
+ case 2:
+ return tr("Definition");
+ }
+ }
+
+ return QVariant();
+}
+
+Qt::ItemFlags PhraseModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+ Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ // Edit is allowed for source & translation if item is from phrasebook
+ if (plist.at(index.row())->phraseBook()
+ && (index.column() != 2))
+ flags |= Qt::ItemIsEditable;
+ return flags;
+}
+
+bool PhraseModel::setData(const QModelIndex & index, const QVariant & value, int role)
+{
+ int row = index.row();
+ int column = index.column();
+
+ if (!index.isValid() || row >= plist.count() || role != Qt::EditRole)
+ return false;
+
+ Phrase *phrase = plist.at(row);
+
+ switch (column) {
+ case 0:
+ phrase->setSource(value.toString());
+ break;
+ case 1:
+ phrase->setTarget(value.toString());
+ break;
+ case 2:
+ phrase->setDefinition(value.toString());
+ break;
+ default:
+ return false;
+ }
+
+ emit dataChanged(index, index);
+ return true;
+}
+
+QVariant PhraseModel::data(const QModelIndex &index, int role) const
+{
+ int row = index.row();
+ int column = index.column();
+
+ if (row >= plist.count() || !index.isValid())
+ return QVariant();
+
+ Phrase *phrase = plist.at(row);
+
+ if (role == Qt::DisplayRole || (role == Qt::ToolTipRole && column != 2)) {
+ switch (column) {
+ case 0: // source phrase
+ return phrase->source().simplified();
+ case 1: // translation
+ return phrase->target().simplified();
+ case 2: // definition
+ return phrase->definition();
+ }
+ }
+ else if (role == Qt::EditRole && column != 2) {
+ switch (column) {
+ case 0: // source phrase
+ return phrase->source();
+ case 1: // translation
+ return phrase->target();
+ }
+ }
+
+ return QVariant();
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/phrasemodel.h b/src/linguist/linguist/phrasemodel.h
new file mode 100644
index 000000000..95efa00dd
--- /dev/null
+++ b/src/linguist/linguist/phrasemodel.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PHRASEMODEL_H
+#define PHRASEMODEL_H
+
+#include "phrase.h"
+
+#include <QList>
+#include <QAbstractItemModel>
+
+QT_BEGIN_NAMESPACE
+
+class PhraseModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ PhraseModel(QObject *parent = 0)
+ : QAbstractTableModel(parent)
+ {}
+
+ void removePhrases();
+ QList<Phrase *> phraseList() const {return plist;}
+
+ QModelIndex addPhrase(Phrase *p);
+ void removePhrase(const QModelIndex &index);
+
+ Phrase *phrase(const QModelIndex &index) const;
+ void setPhrase(const QModelIndex &indx, Phrase *ph);
+ QModelIndex index(Phrase * const phr) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
+ { return QAbstractTableModel::index(row, column, parent); }
+
+ // from qabstracttablemodel
+ int rowCount(const QModelIndex &) const;
+ int columnCount(const QModelIndex &) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole);
+
+ // HACK: This model will be displayed in a _TreeView_
+ // which has a tendency to expand 'children' on double click
+ bool hasChildren(const QModelIndex &parent) const
+ { return !parent.isValid(); }
+
+private:
+ QList<Phrase *> plist;
+};
+
+QT_END_NAMESPACE
+
+#endif // PHRASEMODEL_H
diff --git a/src/linguist/linguist/phraseview.cpp b/src/linguist/linguist/phraseview.cpp
new file mode 100644
index 000000000..f39a5fb36
--- /dev/null
+++ b/src/linguist/linguist/phraseview.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "globals.h"
+#include "mainwindow.h"
+#include "messagemodel.h"
+#include "phrase.h"
+#include "phraseview.h"
+#include "phrasemodel.h"
+#include "simtexth.h"
+
+#include <QHeaderView>
+#include <QKeyEvent>
+#include <QSettings>
+#include <QTreeView>
+#include <QWidget>
+#include <QDebug>
+
+
+QT_BEGIN_NAMESPACE
+
+// Maximum number of guesses to display
+static const int MaxCandidates = 5;
+
+static QString phraseViewHeaderKey()
+{
+ return settingPath("PhraseViewHeader");
+}
+
+PhraseView::PhraseView(MultiDataModel *model, QList<QHash<QString, QList<Phrase *> > > *phraseDict, QWidget *parent)
+ : QTreeView(parent),
+ m_dataModel(model),
+ m_phraseDict(phraseDict),
+ m_modelIndex(-1),
+ m_doGuesses(true)
+{
+ setObjectName(QLatin1String("phrase list view"));
+
+ m_phraseModel = new PhraseModel(this);
+
+ setModel(m_phraseModel);
+ setAlternatingRowColors(true);
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setSelectionMode(QAbstractItemView::SingleSelection);
+ setRootIsDecorated(false);
+ setItemsExpandable(false);
+
+ for (int i = 0; i < 10; i++)
+ (void) new GuessShortcut(i, this, SLOT(guessShortcut(int)));
+
+ header()->setResizeMode(QHeaderView::Interactive);
+ header()->setClickable(true);
+ header()->restoreState(QSettings().value(phraseViewHeaderKey()).toByteArray());
+
+ connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(selectPhrase(QModelIndex)));
+}
+
+PhraseView::~PhraseView()
+{
+ QSettings().setValue(phraseViewHeaderKey(), header()->saveState());
+ deleteGuesses();
+}
+
+void PhraseView::toggleGuessing()
+{
+ m_doGuesses = !m_doGuesses;
+ update();
+}
+
+void PhraseView::update()
+{
+ setSourceText(m_modelIndex, m_sourceText);
+}
+
+
+void PhraseView::contextMenuEvent(QContextMenuEvent *event)
+{
+ QModelIndex index = indexAt(event->pos());
+ if (!index.isValid())
+ return;
+
+ QMenu *contextMenu = new QMenu(this);
+
+ QAction *insertAction = new QAction(tr("Insert"), contextMenu);
+ connect(insertAction, SIGNAL(triggered()), this, SLOT(selectPhrase()));
+
+ QAction *editAction = new QAction(tr("Edit"), contextMenu);
+ connect(editAction, SIGNAL(triggered()), this, SLOT(editPhrase()));
+ editAction->setEnabled(model()->flags(index) & Qt::ItemIsEditable);
+
+ contextMenu->addAction(insertAction);
+ contextMenu->addAction(editAction);
+
+ contextMenu->exec(event->globalPos());
+ event->accept();
+}
+
+void PhraseView::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ QModelIndex index = indexAt(event->pos());
+ if (!index.isValid())
+ return;
+
+ emit phraseSelected(m_modelIndex, m_phraseModel->phrase(index)->target());
+ event->accept();
+}
+
+void PhraseView::guessShortcut(int key)
+{
+ foreach (const Phrase *phrase, m_phraseModel->phraseList())
+ if (phrase->shortcut() == key) {
+ emit phraseSelected(m_modelIndex, phrase->target());
+ return;
+ }
+}
+
+void PhraseView::selectPhrase(const QModelIndex &index)
+{
+ emit phraseSelected(m_modelIndex, m_phraseModel->phrase(index)->target());
+}
+
+void PhraseView::selectPhrase()
+{
+ emit phraseSelected(m_modelIndex, m_phraseModel->phrase(currentIndex())->target());
+}
+
+void PhraseView::editPhrase()
+{
+ edit(currentIndex());
+}
+
+static CandidateList similarTextHeuristicCandidates(MultiDataModel *model, int mi,
+ const char *text, int maxCandidates)
+{
+ QList<int> scores;
+ CandidateList candidates;
+
+ StringSimilarityMatcher stringmatcher(QString::fromLatin1(text));
+
+ for (MultiDataModelIterator it(model, mi); it.isValid(); ++it) {
+ MessageItem *m = it.current();
+ if (!m)
+ continue;
+
+ TranslatorMessage mtm = m->message();
+ if (mtm.type() == TranslatorMessage::Unfinished
+ || mtm.translation().isEmpty())
+ continue;
+
+ QString s = m->text();
+
+ int score = stringmatcher.getSimilarityScore(s);
+
+ if (candidates.count() == maxCandidates && score > scores[maxCandidates - 1])
+ candidates.removeLast();
+ if (candidates.count() < maxCandidates && score >= textSimilarityThreshold ) {
+ Candidate cand(s, mtm.translation());
+
+ int i;
+ for (i = 0; i < candidates.size(); ++i) {
+ if (score >= scores.at(i)) {
+ if (score == scores.at(i)) {
+ if (candidates.at(i) == cand)
+ goto continue_outer_loop;
+ } else {
+ break;
+ }
+ }
+ }
+ scores.insert(i, score);
+ candidates.insert(i, cand);
+ }
+ continue_outer_loop:
+ ;
+ }
+ return candidates;
+}
+
+
+void PhraseView::setSourceText(int model, const QString &sourceText)
+{
+ m_modelIndex = model;
+ m_sourceText = sourceText;
+ m_phraseModel->removePhrases();
+ deleteGuesses();
+
+ if (model < 0)
+ return;
+
+ foreach (Phrase *p, getPhrases(model, sourceText))
+ m_phraseModel->addPhrase(p);
+
+ if (!sourceText.isEmpty() && m_doGuesses) {
+ CandidateList cl = similarTextHeuristicCandidates(m_dataModel, model,
+ sourceText.toLatin1(), MaxCandidates);
+ int n = 0;
+ foreach (const Candidate &candidate, cl) {
+ QString def;
+ if (n < 9)
+ def = tr("Guess (%1)").arg(QString(QKeySequence(Qt::CTRL | (Qt::Key_0 + (n + 1)))));
+ else
+ def = tr("Guess");
+ Phrase *guess = new Phrase(candidate.source, candidate.target, def, n);
+ m_guesses.append(guess);
+ m_phraseModel->addPhrase(guess);
+ ++n;
+ }
+ }
+}
+
+QList<Phrase *> PhraseView::getPhrases(int model, const QString &source)
+{
+ QList<Phrase *> phrases;
+ QString f = MainWindow::friendlyString(source);
+ QStringList lookupWords = f.split(QLatin1Char(' '));
+
+ foreach (const QString &s, lookupWords) {
+ if (m_phraseDict->at(model).contains(s)) {
+ foreach (Phrase *p, m_phraseDict->at(model).value(s)) {
+ if (f.contains(MainWindow::friendlyString(p->source())))
+ phrases.append(p);
+ }
+ }
+ }
+ return phrases;
+}
+
+void PhraseView::deleteGuesses()
+{
+ qDeleteAll(m_guesses);
+ m_guesses.clear();
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/phraseview.h b/src/linguist/linguist/phraseview.h
new file mode 100644
index 000000000..6feedffa3
--- /dev/null
+++ b/src/linguist/linguist/phraseview.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PHRASEVIEW_H
+#define PHRASEVIEW_H
+
+#include <QList>
+#include <QShortcut>
+#include <QTreeView>
+#include "phrase.h"
+
+QT_BEGIN_NAMESPACE
+
+class MultiDataModel;
+class PhraseModel;
+
+class GuessShortcut : public QShortcut
+{
+ Q_OBJECT
+public:
+ GuessShortcut(int nkey, QWidget *parent, const char *member)
+ : QShortcut(parent), nrkey(nkey)
+ {
+ setKey(Qt::CTRL + (Qt::Key_1 + nrkey));
+ connect(this, SIGNAL(activated()), this, SLOT(keyActivated()));
+ connect(this, SIGNAL(activated(int)), parent, member);
+ }
+
+private slots:
+ void keyActivated() { emit activated(nrkey); }
+
+signals:
+ void activated(int nkey);
+
+private:
+ int nrkey;
+};
+
+class PhraseView : public QTreeView
+{
+ Q_OBJECT
+
+public:
+ PhraseView(MultiDataModel *model, QList<QHash<QString, QList<Phrase *> > > *phraseDict, QWidget *parent = 0);
+ ~PhraseView();
+ void setSourceText(int model, const QString &sourceText);
+
+public slots:
+ void toggleGuessing();
+ void update();
+
+signals:
+ void phraseSelected(int latestModel, const QString &phrase);
+
+protected:
+ // QObject
+ virtual void contextMenuEvent(QContextMenuEvent *event);
+ // QAbstractItemView
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
+
+private slots:
+ void guessShortcut(int nkey);
+ void selectPhrase(const QModelIndex &index);
+ void selectPhrase();
+ void editPhrase();
+
+private:
+ QList<Phrase *> getPhrases(int model, const QString &sourceText);
+ void deleteGuesses();
+
+ MultiDataModel *m_dataModel;
+ QList<QHash<QString, QList<Phrase *> > > *m_phraseDict;
+ QList<Phrase *> m_guesses;
+ PhraseModel *m_phraseModel;
+ QString m_sourceText;
+ int m_modelIndex;
+ bool m_doGuesses;
+};
+
+QT_END_NAMESPACE
+
+#endif // PHRASEVIEW_H
diff --git a/src/linguist/linguist/printout.cpp b/src/linguist/linguist/printout.cpp
new file mode 100644
index 000000000..342f24081
--- /dev/null
+++ b/src/linguist/linguist/printout.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "printout.h"
+
+#include <QPrinter>
+#include <QFontMetrics>
+
+QT_BEGIN_NAMESPACE
+
+PrintOut::PrintOut(QPrinter *printer)
+ : pr(printer), nextRule(NoRule), page(0)
+{
+ p.begin(pr);
+ QFont f(QLatin1String("Arial"));
+ f8 = f;
+ f8.setPointSize(8);
+ f10 = f;
+ f10.setPointSize(10);
+ p.setFont(f10);
+ fmetrics = new QFontMetrics(p.fontMetrics());
+ hmargin = 5 * printer->width() / printer->widthMM(); // 5 mm
+ vmargin = 5 * printer->height() / printer->heightMM(); // 5 mm
+ hsize = printer->width() - 2 * hmargin;
+ vsize = printer->height() - vmargin;
+ dateTime = QDateTime::currentDateTime();
+ breakPage(true); // init vsize and draw first header
+ cp = Paragraph(QPoint(hmargin, voffset));
+}
+
+PrintOut::~PrintOut()
+{
+ flushLine();
+ delete fmetrics;
+ p.end();
+}
+
+void PrintOut::setRule(Rule rule)
+{
+ if (nextRule < rule)
+ nextRule = rule;
+}
+
+void PrintOut::setGuide(const QString &guide)
+{
+ g = guide;
+}
+
+void PrintOut::vskip()
+{
+ if (!firstParagraph)
+ voffset += 14;
+}
+
+void PrintOut::flushLine(bool /* mayBreak */)
+{
+ if (voffset + cp.rect.height() > vsize)
+ breakPage();
+ else if (!firstParagraph)
+ drawRule(nextRule);
+
+ for (int i = 0; i < cp.boxes.count(); ++i) {
+ Box b = cp.boxes[i];
+ b.rect.translate(0, voffset);
+ QRect r = b.rect;
+ p.setFont(b.font);
+ p.drawText(r, b.text, b.options);
+ }
+ voffset += cp.rect.height();
+
+ nextRule = NoRule;
+ cp = Paragraph(QPoint(hmargin, voffset));
+ firstParagraph = false;
+}
+
+void PrintOut::addBox(int percent, const QString &text, Style style, Qt::Alignment halign)
+{
+ QTextOption options;
+ options.setAlignment(halign | Qt::AlignTop);
+ options.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+ QFont f = f10;
+ if (style == Strong)
+ f.setBold(true);
+ else if (style == Emphasis)
+ f.setItalic(true);
+ int wd = hsize * percent / 100;
+ QRect r(cp.rect.x() + cp.rect.width(), 0, wd, vsize);
+ const int ht = static_cast<int>(p.boundingRect(r, text, options).height());
+
+ Box b(r, text, f, options);
+ cp.boxes.append(b);
+ cp.rect.setSize(QSize(cp.rect.width() + wd, qMax(cp.rect.height(), ht)));
+}
+
+// use init if initial vsize should be calculated (first breakPage call)
+void PrintOut::breakPage(bool init)
+{
+ static const int LeftAlign = Qt::AlignLeft | Qt::AlignTop;
+ static const int RightAlign = Qt::AlignRight | Qt::AlignTop;
+ QRect r1, r2;
+ int h1 = 0;
+ int h2 = 0;
+
+ if (page > 0)
+ pr->newPage();
+
+ if (!init)
+ page++;
+
+ voffset = 0;
+
+ p.setFont(f10);
+ r1 = QRect(hmargin, voffset, 3 * hsize / 4, vsize);
+ r2 = QRect(r1.x() + r1.width(), voffset, hsize - r1.width(), vsize);
+ h1 = p.boundingRect(r1, LeftAlign, pr->docName()).height();
+ if (!init)
+ p.drawText(r1, LeftAlign, pr->docName());
+ h2 = p.boundingRect(r2, RightAlign, QString::number(page)).height();
+ if (!init)
+ p.drawText(r2, RightAlign, QString::number(page));
+ voffset += qMax(h1, h2 );
+
+ r1 = QRect(hmargin, voffset, hsize / 2, LeftAlign);
+ p.setFont(f8);
+ h1 = p.boundingRect(r1, LeftAlign, dateTime.toString()).height();
+ if (!init)
+ p.drawText(r1, LeftAlign, dateTime.toString());
+ p.setFont(f10);
+ voffset += qMax(h1, h2);
+
+ voffset += 4;
+ if (!init)
+ p.drawLine(QPoint(hmargin, voffset), QPoint(hmargin + hsize, voffset));
+ voffset += 14;
+
+ firstParagraph = true;
+
+ if (init) {
+ vsize -= voffset;
+ breakPage(); // now draw it when the vsize is ok
+ }
+
+}
+
+void PrintOut::drawRule(Rule rule)
+{
+ QPen pen;
+
+ switch (rule) {
+ case NoRule:
+ voffset += 5;
+ break;
+ case ThinRule:
+ pen.setColor(QColor(192, 192, 192));
+ pen.setStyle(Qt::DotLine);
+ pen.setWidth(0);
+ p.setPen(pen);
+ voffset += 5;
+ p.drawLine(QPoint(hmargin, voffset),
+ QPoint(hmargin + hsize, voffset));
+ p.setPen(QPen());
+ voffset += 2;
+ break;
+ case ThickRule:
+ voffset += 7;
+ p.drawLine(QPoint(hmargin, voffset),
+ QPoint(hmargin + hsize, voffset));
+ voffset += 4;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/printout.h b/src/linguist/linguist/printout.h
new file mode 100644
index 000000000..c46c0fabf
--- /dev/null
+++ b/src/linguist/linguist/printout.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PRINTOUT_H
+#define PRINTOUT_H
+
+#include <QFont>
+#include <QPainter>
+#include <QRect>
+#include <QTextOption>
+#include <QList>
+#include <QDateTime>
+
+QT_BEGIN_NAMESPACE
+
+class QPrinter;
+class QFontMetrics;
+
+class PrintOut
+{
+public:
+ enum Rule { NoRule, ThinRule, ThickRule };
+ enum Style { Normal, Strong, Emphasis };
+
+ PrintOut(QPrinter *printer);
+ ~PrintOut();
+
+ void setRule(Rule rule);
+ void setGuide(const QString &guide);
+ void vskip();
+ void flushLine(bool mayBreak = false);
+ void addBox(int percent, const QString &text = QString(),
+ Style style = Normal,
+ Qt::Alignment halign = Qt::AlignLeft);
+
+ int pageNum() const { return page; }
+
+ struct Box
+ {
+ QRect rect;
+ QString text;
+ QFont font;
+ QTextOption options;
+
+ Box( const QRect& r, const QString& t, const QFont& f, const QTextOption &o )
+ : rect( r ), text( t ), font( f ), options( o ) { }
+ };
+
+private:
+ void breakPage(bool init = false);
+ void drawRule( Rule rule );
+
+ struct Paragraph {
+ QRect rect;
+ QList<Box> boxes;
+
+ Paragraph() { }
+ Paragraph( QPoint p ) : rect( p, QSize(0, 0) ) { }
+ };
+
+ QPrinter *pr;
+ QPainter p;
+ QFont f8;
+ QFont f10;
+ QFontMetrics *fmetrics;
+ Rule nextRule;
+ Paragraph cp;
+ int page;
+ bool firstParagraph;
+ QString g;
+ QDateTime dateTime;
+
+ int hmargin;
+ int vmargin;
+ int voffset;
+ int hsize;
+ int vsize;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/linguist/linguist/recentfiles.cpp b/src/linguist/linguist/recentfiles.cpp
new file mode 100644
index 000000000..e1d79ce24
--- /dev/null
+++ b/src/linguist/linguist/recentfiles.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "recentfiles.h"
+#include "globals.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSettings>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+static QString configKey()
+{
+ return settingPath("RecentlyOpenedFiles");
+}
+
+
+RecentFiles::RecentFiles(const int maxEntries)
+ : m_groupOpen(false),
+ m_clone1st(false),
+ m_maxEntries(maxEntries)
+{
+ m_timer.setSingleShot(true);
+ m_timer.setInterval(3 * 60 * 1000);
+ connect(&m_timer, SIGNAL(timeout()), SLOT(closeGroup()));
+}
+
+/*
+ * The logic is as follows:
+ * - The most recent (i.e., topmost) item can be open ("in flux")
+ * - The item is closed by either a timeout (3 min or so) or a
+ * "terminal action" (e.g., closing all files)
+ * - While the item is open, modifications to the set of open files
+ * will modify that item instead of creating new items
+ * - If the open item is modified to be equal to an existing item,
+ * the existing item is deleted, but will be re-created when the
+ * open item is modified even further
+ * Cases (actions in parentheses are no-ops):
+ * - identical to top item => (do nothing)
+ * - closed, new item => insert at top, (clear marker)
+ * - closed, existing item => move to top, mark for cloning
+ * - open, new item, not marked => replace top, (clear marker)
+ * - open, new item, marked => insert at top, clear marker
+ * - open, existing item, not marked => replace top, delete copy, mark for cloning
+ * - open, existing item, marked => insert at top, delete copy, (mark for cloning)
+ * - closing clears marker
+ */
+void RecentFiles::addFiles(const QStringList &names)
+{
+ if (m_strLists.isEmpty() || names != m_strLists.first()) {
+ if (m_groupOpen && !m_clone1st)
+ // Group being open implies at least one item in the list
+ m_strLists.removeFirst();
+ m_groupOpen = true;
+
+ // We do *not* sort the actual entries, as that would destroy the user's
+ // chosen arrangement. However, we do the searching on sorted lists, so
+ // we throw out (probably) obsolete arrangements.
+ QList<QStringList> sortedLists = m_strLists;
+ for (int i = 0; i < sortedLists.size(); ++i)
+ sortedLists[i].sort();
+ QStringList sortedNames = names;
+ sortedNames.sort();
+
+ int index = sortedLists.indexOf(sortedNames);
+ if (index >= 0) {
+ m_strLists.removeAt(index);
+ m_clone1st = true;
+ } else {
+ if (m_strLists.count() >= m_maxEntries)
+ m_strLists.removeLast();
+ m_clone1st = false;
+ }
+ m_strLists.prepend(names);
+ }
+ m_timer.start();
+}
+
+void RecentFiles::closeGroup()
+{
+ m_timer.stop();
+ m_groupOpen = false;
+}
+
+void RecentFiles::readConfig()
+{
+ m_strLists.clear();
+ QVariant val = QSettings().value(configKey());
+ if (val.type() == QVariant::StringList) // Backwards compat to Qt < 4.5
+ foreach (const QString &s, val.toStringList())
+ m_strLists << QStringList(QFileInfo(s).canonicalFilePath());
+ else
+ foreach (const QVariant &v, val.toList())
+ m_strLists << v.toStringList();
+}
+
+void RecentFiles::writeConfig() const
+{
+ QList<QVariant> vals;
+ foreach (const QStringList &sl, m_strLists)
+ vals << sl;
+ QSettings().setValue(configKey(), vals);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/recentfiles.h b/src/linguist/linguist/recentfiles.h
new file mode 100644
index 000000000..09c2b407c
--- /dev/null
+++ b/src/linguist/linguist/recentfiles.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RECENTFILES_H
+#define RECENTFILES_H
+
+#include <QString>
+#include <QStringList>
+#include <QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class RecentFiles : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit RecentFiles(const int maxEntries);
+
+ bool isEmpty() { return m_strLists.isEmpty(); }
+ void addFiles(const QStringList &names);
+ QString lastOpenedFile() const {
+ if (m_strLists.isEmpty() || m_strLists.first().isEmpty())
+ return QString::null;
+ return m_strLists.at(0).at(0);
+ }
+ const QList<QStringList>& filesLists() const { return m_strLists; }
+
+ void readConfig();
+ void writeConfig() const;
+
+public slots:
+ void closeGroup();
+
+private:
+ bool m_groupOpen;
+ bool m_clone1st;
+ int m_maxEntries;
+ QList<QStringList> m_strLists;
+ QTimer m_timer;
+};
+
+QT_END_NAMESPACE
+
+#endif // RECENTFILES_H
diff --git a/src/linguist/linguist/sourcecodeview.cpp b/src/linguist/linguist/sourcecodeview.cpp
new file mode 100644
index 000000000..b6c011714
--- /dev/null
+++ b/src/linguist/linguist/sourcecodeview.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "sourcecodeview.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextStream>
+
+#include <QtGui/QTextCharFormat>
+#include <QtGui/QTextBlock>
+#include <QtGui/QTextCursor>
+
+QT_BEGIN_NAMESPACE
+
+SourceCodeView::SourceCodeView(QWidget *parent)
+ : QPlainTextEdit(parent),
+ m_isActive(true),
+ m_lineNumToLoad(0)
+{
+ setReadOnly(true);
+}
+
+void SourceCodeView::setSourceContext(const QString &fileName, const int lineNum)
+{
+ m_fileToLoad.clear();
+ setToolTip(fileName);
+
+ if (fileName.isEmpty()) {
+ clear();
+ m_currentFileName.clear();
+ appendHtml(tr("<i>Source code not available</i>"));
+ return;
+ }
+
+ if (m_isActive) {
+ showSourceCode(fileName, lineNum);
+ } else {
+ m_fileToLoad = fileName;
+ m_lineNumToLoad = lineNum;
+ }
+}
+
+void SourceCodeView::setActivated(bool activated)
+{
+ m_isActive = activated;
+ if (activated && !m_fileToLoad.isEmpty()) {
+ showSourceCode(m_fileToLoad, m_lineNumToLoad);
+ m_fileToLoad.clear();
+ }
+}
+
+void SourceCodeView::showSourceCode(const QString &absFileName, const int lineNum)
+{
+ QString fileText = fileHash.value(absFileName);
+
+ if (fileText.isNull()) { // File not in hash
+ m_currentFileName.clear();
+
+ // Assume fileName is relative to directory
+ QFile file(absFileName);
+
+ if (!file.exists()) {
+ clear();
+ appendHtml(tr("<i>File %1 not available</i>").arg(absFileName));
+ return;
+ }
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ clear();
+ appendHtml(tr("<i>File %1 not readable</i>").arg(absFileName));
+ return;
+ }
+ fileText = QString::fromLatin1(file.readAll());
+ fileHash.insert(absFileName, fileText);
+ }
+
+
+ if (m_currentFileName != absFileName) {
+ setPlainText(fileText);
+ m_currentFileName = absFileName;
+ }
+
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(document()->findBlockByNumber(lineNum - 1).position());
+ setTextCursor(cursor);
+ centerCursor();
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
+
+ QTextEdit::ExtraSelection selectedLine;
+ selectedLine.cursor = cursor;
+
+ // Define custom color for line selection
+ const QColor fg = palette().color(QPalette::Highlight);
+ const QColor bg = palette().color(QPalette::Base);
+ QColor col;
+ const qreal ratio = 0.25;
+ col.setRedF(fg.redF() * ratio + bg.redF() * (1 - ratio));
+ col.setGreenF(fg.greenF() * ratio + bg.greenF() * (1 - ratio));
+ col.setBlueF(fg.blueF() * ratio + bg.blueF() * (1 - ratio));
+
+ selectedLine.format.setBackground(col);
+ selectedLine.format.setProperty(QTextFormat::FullWidthSelection, true);
+ setExtraSelections(QList<QTextEdit::ExtraSelection>() << selectedLine);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/sourcecodeview.h b/src/linguist/linguist/sourcecodeview.h
new file mode 100644
index 000000000..6f42a31cb
--- /dev/null
+++ b/src/linguist/linguist/sourcecodeview.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SOURCECODEVIEW_H
+#define SOURCECODEVIEW_H
+
+#include <QDir>
+#include <QHash>
+#include <QPlainTextEdit>
+
+QT_BEGIN_NAMESPACE
+
+class SourceCodeView : public QPlainTextEdit
+{
+ Q_OBJECT
+public:
+ SourceCodeView(QWidget *parent = 0);
+ void setSourceContext(const QString &fileName, const int lineNum);
+
+public slots:
+ void setActivated(bool activated);
+
+private:
+ void showSourceCode(const QString &fileName, const int lineNum);
+
+ bool m_isActive;
+ QString m_fileToLoad;
+ int m_lineNumToLoad;
+ QString m_currentFileName;
+
+ QHash<QString, QString> fileHash;
+};
+
+QT_END_NAMESPACE
+
+#endif // SOURCECODEVIEW_H
diff --git a/src/linguist/linguist/statistics.cpp b/src/linguist/linguist/statistics.cpp
new file mode 100644
index 000000000..821ce7ab4
--- /dev/null
+++ b/src/linguist/linguist/statistics.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "statistics.h"
+
+QT_BEGIN_NAMESPACE
+
+Statistics::Statistics(QWidget* parent, Qt::WindowFlags fl)
+ : QDialog(parent, fl)
+{
+ setupUi(this);
+}
+
+void Statistics::languageChange()
+{
+ retranslateUi(this);
+}
+
+void Statistics::updateStats(int sW,int sC,int sCS,int trW,int trC,int trCS)
+{
+ untrWords->setText(QString::number(sW));
+ untrChars->setText(QString::number(sC));
+ untrCharsSpc->setText(QString::number(sCS));
+ trWords->setText(QString::number(trW));
+ trChars->setText(QString::number(trC));
+ trCharsSpc->setText(QString::number(trCS));
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/statistics.h b/src/linguist/linguist/statistics.h
new file mode 100644
index 000000000..fe1f6cfa2
--- /dev/null
+++ b/src/linguist/linguist/statistics.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STATISTICS_H
+#define STATISTICS_H
+
+#include "ui_statistics.h"
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class Statistics : public QDialog, public Ui::Statistics
+{
+ Q_OBJECT
+
+public:
+ Statistics(QWidget *parent = 0, Qt::WindowFlags fl = 0);
+ ~Statistics() {}
+
+public slots:
+ virtual void updateStats(int w1, int c1, int cs1, int w2, int c2, int cs2);
+
+protected slots:
+ virtual void languageChange();
+};
+
+QT_END_NAMESPACE
+
+#endif // STATISTICS_H
diff --git a/src/linguist/linguist/statistics.ui b/src/linguist/linguist/statistics.ui
new file mode 100644
index 000000000..28402b0e4
--- /dev/null
+++ b/src/linguist/linguist/statistics.ui
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>Statistics</class>
+ <widget class="QDialog" name="linguist_stats">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>336</width>
+ <height>169</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Statistics</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="1" column="0">
+ <layout class="QHBoxLayout">
+ <item>
+ <spacer name="spacer4_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeBtn">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0">
+ <widget class="QFrame" name="frame4">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="2">
+ <widget class="QLabel" name="textLabel4">
+ <property name="text">
+ <string>Translation</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="textLabel5">
+ <property name="text">
+ <string>Source</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="untrWords">
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="trWords">
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="textLabel1">
+ <property name="text">
+ <string>Words:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="trChars">
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="untrChars">
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="textLabel3">
+ <property name="text">
+ <string>Characters:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="textLabel6">
+ <property name="text">
+ <string>Characters (with spaces):</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLabel" name="trCharsSpc">
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="untrCharsSpc">
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>closeBtn</sender>
+ <signal>clicked()</signal>
+ <receiver>linguist_stats</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>179</x>
+ <y>144</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>239</x>
+ <y>142</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/linguist/linguist/translatedialog.cpp b/src/linguist/linguist/translatedialog.cpp
new file mode 100644
index 000000000..94acfd5fd
--- /dev/null
+++ b/src/linguist/linguist/translatedialog.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translatedialog.h"
+
+QT_BEGIN_NAMESPACE
+
+TranslateDialog::TranslateDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ m_ui.setupUi(this);
+ connect(m_ui.findNxt, SIGNAL(clicked()), this, SLOT(emitFindNext()));
+ connect(m_ui.translate, SIGNAL(clicked()), this, SLOT(emitTranslateAndFindNext()));
+ connect(m_ui.translateAll, SIGNAL(clicked()), this, SLOT(emitTranslateAll()));
+ connect(m_ui.ledFindWhat, SIGNAL(textChanged(QString)), SLOT(verifyText()));
+ connect(m_ui.ckMatchCase, SIGNAL(toggled(bool)), SLOT(verifyText()));
+}
+
+void TranslateDialog::showEvent(QShowEvent *)
+{
+ verifyText();
+ m_ui.ledFindWhat->setFocus();
+}
+
+void TranslateDialog::verifyText()
+{
+ QString text = m_ui.ledFindWhat->text();
+ bool canFind = !text.isEmpty();
+ bool hit = false;
+ if (canFind)
+ emit requestMatchUpdate(hit);
+ m_ui.findNxt->setEnabled(canFind);
+ m_ui.translate->setEnabled(canFind && hit);
+ m_ui.translateAll->setEnabled(canFind);
+}
+
+void TranslateDialog::emitFindNext()
+{
+ emit activated(Skip);
+}
+
+void TranslateDialog::emitTranslateAndFindNext()
+{
+ emit activated(Translate);
+}
+
+void TranslateDialog::emitTranslateAll()
+{
+ emit activated(TranslateAll);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/translatedialog.h b/src/linguist/linguist/translatedialog.h
new file mode 100644
index 000000000..80c09a74a
--- /dev/null
+++ b/src/linguist/linguist/translatedialog.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRANSLATEDIALOG_H
+#define TRANSLATEDIALOG_H
+
+#include "ui_translatedialog.h"
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class TranslateDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ enum {
+ Skip,
+ Translate,
+ TranslateAll
+ };
+
+ TranslateDialog(QWidget *parent = 0);
+
+ bool markFinished() const { return m_ui.ckMarkFinished->isChecked(); }
+ Qt::CaseSensitivity caseSensitivity() const
+ { return m_ui.ckMatchCase->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive; }
+ QString findText() const { return m_ui.ledFindWhat->text(); }
+ QString replaceText() const { return m_ui.ledTranslateTo->text(); }
+
+signals:
+ void requestMatchUpdate(bool &hit);
+ void activated(int mode);
+
+protected:
+ virtual void showEvent(QShowEvent *event);
+
+private slots:
+ void emitFindNext();
+ void emitTranslateAndFindNext();
+ void emitTranslateAll();
+ void verifyText();
+
+private:
+ Ui::TranslateDialog m_ui;
+};
+
+
+QT_END_NAMESPACE
+#endif //TRANSLATEDIALOG_H
+
diff --git a/src/linguist/linguist/translatedialog.ui b/src/linguist/linguist/translatedialog.ui
new file mode 100644
index 000000000..7c0baa722
--- /dev/null
+++ b/src/linguist/linguist/translatedialog.ui
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>TranslateDialog</class>
+ <widget class="QDialog" name="translateDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>407</width>
+ <height>174</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis">
+ <string>This window allows you to search for some text in the translation source file.</string>
+ </property>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="ledTranslateTo">
+ <property name="whatsThis">
+ <string>Type in the text to search for.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="findWhat">
+ <property name="text">
+ <string>Find &amp;source text:</string>
+ </property>
+ <property name="buddy">
+ <cstring>ledFindWhat</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="translateTo">
+ <property name="text">
+ <string>&amp;Translate to:</string>
+ </property>
+ <property name="buddy">
+ <cstring>ledTranslateTo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="ledFindWhat">
+ <property name="whatsThis">
+ <string>Type in the text to search for.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Search options</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QCheckBox" name="ckMatchCase">
+ <property name="whatsThis">
+ <string>Texts such as 'TeX' and 'tex' are considered as different when checked.</string>
+ </property>
+ <property name="text">
+ <string>Match &amp;case</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="ckMarkFinished">
+ <property name="text">
+ <string>Mark new translation as &amp;finished</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="findNxt">
+ <property name="whatsThis">
+ <string>Click here to find the next occurrence of the text you typed in.</string>
+ </property>
+ <property name="text">
+ <string>Find Next</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="translate">
+ <property name="text">
+ <string>Translate</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="translateAll">
+ <property name="text">
+ <string>Translate All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancel">
+ <property name="whatsThis">
+ <string>Click here to close this window.</string>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>51</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>ledFindWhat</tabstop>
+ <tabstop>ledTranslateTo</tabstop>
+ <tabstop>findNxt</tabstop>
+ <tabstop>translate</tabstop>
+ <tabstop>translateAll</tabstop>
+ <tabstop>cancel</tabstop>
+ <tabstop>ckMatchCase</tabstop>
+ <tabstop>ckMarkFinished</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>cancel</sender>
+ <signal>clicked()</signal>
+ <receiver>translateDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>360</x>
+ <y>132</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>357</x>
+ <y>151</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/linguist/linguist/translationsettings.ui b/src/linguist/linguist/translationsettings.ui
new file mode 100644
index 000000000..c868360e6
--- /dev/null
+++ b/src/linguist/linguist/translationsettings.ui
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TranslationSettingsDialog</class>
+ <widget class="QDialog" name="translationSettingsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>416</width>
+ <height>263</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string/>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="srcGroupBox">
+ <property name="title">
+ <string>Source language</string>
+ </property>
+ <layout class="QGridLayout" name="_2">
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="srcCbLanguageList"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="srcLblLanguage">
+ <property name="text">
+ <string>Language</string>
+ </property>
+ <property name="buddy">
+ <cstring>tgtCbLanguageList</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="srcCbCountryList"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="srcLblCountry">
+ <property name="text">
+ <string>Country/Region</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="tgtGroupBox">
+ <property name="title">
+ <string>Target language</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="tgtCbLanguageList"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="tgtLblLanguage">
+ <property name="text">
+ <string>Language</string>
+ </property>
+ <property name="buddy">
+ <cstring>tgtCbLanguageList</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="tgtCbCountryList"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="tgtLblCountry">
+ <property name="text">
+ <string>Country/Region</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>100</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>translationSettingsDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>216</x>
+ <y>241</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>222</x>
+ <y>213</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/linguist/linguist/translationsettingsdialog.cpp b/src/linguist/linguist/translationsettingsdialog.cpp
new file mode 100644
index 000000000..2049af12b
--- /dev/null
+++ b/src/linguist/linguist/translationsettingsdialog.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "translationsettingsdialog.h"
+#include "messagemodel.h"
+#include "phrase.h"
+
+#include <QtCore/QLocale>
+
+QT_BEGIN_NAMESPACE
+
+TranslationSettingsDialog::TranslationSettingsDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ m_ui.setupUi(this);
+
+ for (int i = QLocale::C + 1; i < QLocale::LastLanguage; ++i) {
+ QString lang = QLocale::languageToString(QLocale::Language(i));
+ m_ui.srcCbLanguageList->addItem(lang, QVariant(i));
+ }
+ m_ui.srcCbLanguageList->model()->sort(0, Qt::AscendingOrder);
+ m_ui.srcCbLanguageList->insertItem(0, QLatin1String("POSIX"), QVariant(QLocale::C));
+
+ m_ui.tgtCbLanguageList->setModel(m_ui.srcCbLanguageList->model());
+}
+
+void TranslationSettingsDialog::setDataModel(DataModel *dataModel)
+{
+ m_dataModel = dataModel;
+ m_phraseBook = 0;
+ QString fn = QFileInfo(dataModel->srcFileName()).baseName();
+ setWindowTitle(tr("Settings for '%1' - Qt Linguist").arg(fn));
+}
+
+void TranslationSettingsDialog::setPhraseBook(PhraseBook *phraseBook)
+{
+ m_phraseBook = phraseBook;
+ m_dataModel = 0;
+ QString fn = QFileInfo(phraseBook->fileName()).baseName();
+ setWindowTitle(tr("Settings for '%1' - Qt Linguist").arg(fn));
+}
+
+static void fillCountryCombo(const QVariant &lng, QComboBox *combo)
+{
+ combo->clear();
+ QLocale::Language lang = QLocale::Language(lng.toInt());
+ if (lang != QLocale::C) {
+ foreach (QLocale::Country cntr, QLocale::countriesForLanguage(lang)) {
+ QString country = QLocale::countryToString(cntr);
+ combo->addItem(country, QVariant(cntr));
+ }
+ combo->model()->sort(0, Qt::AscendingOrder);
+ }
+ combo->insertItem(0, TranslationSettingsDialog::tr("Any Country"), QVariant(QLocale::AnyCountry));
+ combo->setCurrentIndex(0);
+}
+
+void TranslationSettingsDialog::on_srcCbLanguageList_currentIndexChanged(int idx)
+{
+ fillCountryCombo(m_ui.srcCbLanguageList->itemData(idx), m_ui.srcCbCountryList);
+}
+
+void TranslationSettingsDialog::on_tgtCbLanguageList_currentIndexChanged(int idx)
+{
+ fillCountryCombo(m_ui.tgtCbLanguageList->itemData(idx), m_ui.tgtCbCountryList);
+}
+
+void TranslationSettingsDialog::on_buttonBox_accepted()
+{
+ int itemindex = m_ui.tgtCbLanguageList->currentIndex();
+ QVariant var = m_ui.tgtCbLanguageList->itemData(itemindex);
+ QLocale::Language lang = QLocale::Language(var.toInt());
+
+ itemindex = m_ui.tgtCbCountryList->currentIndex();
+ var = m_ui.tgtCbCountryList->itemData(itemindex);
+ QLocale::Country country = QLocale::Country(var.toInt());
+
+ itemindex = m_ui.srcCbLanguageList->currentIndex();
+ var = m_ui.srcCbLanguageList->itemData(itemindex);
+ QLocale::Language lang2 = QLocale::Language(var.toInt());
+
+ itemindex = m_ui.srcCbCountryList->currentIndex();
+ var = m_ui.srcCbCountryList->itemData(itemindex);
+ QLocale::Country country2 = QLocale::Country(var.toInt());
+
+ if (m_phraseBook) {
+ m_phraseBook->setLanguageAndCountry(lang, country);
+ m_phraseBook->setSourceLanguageAndCountry(lang2, country2);
+ } else {
+ m_dataModel->setLanguageAndCountry(lang, country);
+ m_dataModel->setSourceLanguageAndCountry(lang2, country2);
+ }
+
+ accept();
+}
+
+void TranslationSettingsDialog::showEvent(QShowEvent *)
+{
+ QLocale::Language lang, lang2;
+ QLocale::Country country, country2;
+
+ if (m_phraseBook) {
+ lang = m_phraseBook->language();
+ country = m_phraseBook->country();
+ lang2 = m_phraseBook->sourceLanguage();
+ country2 = m_phraseBook->sourceCountry();
+ } else {
+ lang = m_dataModel->language();
+ country = m_dataModel->country();
+ lang2 = m_dataModel->sourceLanguage();
+ country2 = m_dataModel->sourceCountry();
+ }
+
+ int itemindex = m_ui.tgtCbLanguageList->findData(QVariant(int(lang)));
+ m_ui.tgtCbLanguageList->setCurrentIndex(itemindex == -1 ? 0 : itemindex);
+
+ itemindex = m_ui.tgtCbCountryList->findData(QVariant(int(country)));
+ m_ui.tgtCbCountryList->setCurrentIndex(itemindex == -1 ? 0 : itemindex);
+
+ itemindex = m_ui.srcCbLanguageList->findData(QVariant(int(lang2)));
+ m_ui.srcCbLanguageList->setCurrentIndex(itemindex == -1 ? 0 : itemindex);
+
+ itemindex = m_ui.srcCbCountryList->findData(QVariant(int(country2)));
+ m_ui.srcCbCountryList->setCurrentIndex(itemindex == -1 ? 0 : itemindex);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/linguist/translationsettingsdialog.h b/src/linguist/linguist/translationsettingsdialog.h
new file mode 100644
index 000000000..9eee406fa
--- /dev/null
+++ b/src/linguist/linguist/translationsettingsdialog.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRANSLATIONSETTINGSDIALOG_H
+#define TRANSLATIONSETTINGSDIALOG_H
+
+#include "ui_translationsettings.h"
+
+#include <QtCore/QLocale>
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class DataModel;
+class PhraseBook;
+
+class TranslationSettingsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ TranslationSettingsDialog(QWidget *parent = 0);
+ void setDataModel(DataModel *model);
+ void setPhraseBook(PhraseBook *phraseBook);
+
+private:
+ virtual void showEvent(QShowEvent *e);
+
+private slots:
+ void on_buttonBox_accepted();
+ void on_srcCbLanguageList_currentIndexChanged(int idx);
+ void on_tgtCbLanguageList_currentIndexChanged(int idx);
+
+private:
+ Ui::TranslationSettingsDialog m_ui;
+ DataModel *m_dataModel;
+ PhraseBook *m_phraseBook;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // TRANSLATIONSETTINGSDIALOG_H
diff --git a/src/linguist/lrelease/lrelease.1 b/src/linguist/lrelease/lrelease.1
new file mode 100644
index 000000000..61977926b
--- /dev/null
+++ b/src/linguist/lrelease/lrelease.1
@@ -0,0 +1,118 @@
+.TH lrelease 1 "18 October 2001" "Nokia Corporation and/or its subsidiary(-ies)" \" -*- nroff -*-
+.\"
+.\" Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+.\" All rights reserved.
+.\" Contact: Nokia Corporation (qt-info@nokia.com)
+.\"
+.\" This file is part of the QtGui module of the Qt Toolkit.
+.\"
+.\" $QT_BEGIN_LICENSE:LGPL$
+.\" No Commercial Usage
+.\" This file contains pre-release code and may not be distributed.
+.\" You may use this file in accordance with the terms and conditions
+.\" contained in the Technology Preview License Agreement accompanying
+.\" this package.
+.\"
+.\" GNU Lesser General Public License Usage
+.\" Alternatively, this file may be used under the terms of the GNU Lesser
+.\" General Public License version 2.1 as published by the Free Software
+.\" Foundation and appearing in the file LICENSE.LGPL included in the
+.\" packaging of this file. Please review the following information to
+.\" ensure the GNU Lesser General Public License version 2.1 requirements
+.\" will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+.\"
+.\" In addition, as a special exception, Nokia gives you certain additional
+.\" rights. These rights are described in the Nokia Qt LGPL Exception
+.\" version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+.\"
+.\" If you have questions regarding the use of this file, please contact
+.\" Nokia at qt-info@nokia.com.
+.\"
+.\"
+.\"
+.\"
+.\"
+.\"
+.\"
+.\"
+.\" $QT_END_LICENSE$
+.\"
+.SH NAME
+lrelease \- generate Qt message files from Qt Linguist translation files
+.SH SYNOPSIS
+.B lrelease
+.RI "[ " options " ] " project-file
+.br
+.B lrelease
+.RI "[ " options " ] " ts-files " [ -qm " qm-file " ]"
+.SH DESCRIPTION
+This page documents the
+.B Qt Linguist Release
+tool for the Qt GUI toolkit.
+.B Lrelease
+reads a qmake/tmake project file (.pro file) and converts the
+translation files (TS files) specified in it into Qt message files
+(QM files) used by the application to translate.
+.PP
+The QM file format is a compact binary format that provides
+extremely fast lookups for translations and that is used by Qt.
+.SH OPTIONS
+.TP
+.I "-help"
+Display the usage and exit.
+.TP
+.I "-compress"
+Compress the QM files.
+.TP
+.I "-nounfinished"
+Do not include unfinished translations.
+.TP
+.I "-removeidentical"
+If the translated text is the same as
+the source text, do not include the message.
+.TP
+.I "-silent"
+Do not explain what is being done.
+.TP
+.I "-version"
+Display the version of
+.B lrelease
+and exit.
+.SH USAGE
+Here is an example .pro file that can be given to
+.B lrelease:
+.PP
+.in +4
+.nf
+HEADERS = funnydialog.h \\
+ wackywidget.h
+SOURCES = funnydialog.cpp \\
+ main.cpp \\
+ wackywidget.cpp
+FORMS = fancybox.ui
+TRANSLATIONS = gnomovision_dk.ts \\
+ gnomovision_fi.ts \\
+ gnomovision_no.ts \\
+ gnomovision_se.ts
+.fi
+.in -4
+.PP
+When running
+.B lrelease
+on this project file, the Qt message files gnomovision_dk.qm,
+gnomovision_fi.qm, gnomovision_no.qm and gnomovision_se.qm will be
+generated from gnomovision_dk.ts, gnomovision_fi.ts,
+gnomovision_no.ts and gnomovision_se.ts, respectively.
+.PP
+.B Lrelease
+can also be invoked with a list of TS files to convert:
+.PP
+.in +4
+.nf
+lrelease gnomovision_*.ts
+.fi
+.in -4
+.SH "SEE ALSO"
+.BR lupdate (1)
+and
+.BR http://qt.nokia.com/doc/i18n.html
diff --git a/src/linguist/lrelease/lrelease.pro b/src/linguist/lrelease/lrelease.pro
new file mode 100644
index 000000000..89694be6e
--- /dev/null
+++ b/src/linguist/lrelease/lrelease.pro
@@ -0,0 +1,23 @@
+TEMPLATE = app
+TARGET = lrelease
+DESTDIR = ../../../bin
+
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
+SOURCES += main.cpp
+
+INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global # qlibraryinfo.cpp includes qconfig.cpp
+SOURCES += \
+ $$QT_SOURCE_TREE/src/corelib/global/qlibraryinfo.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qsettings.cpp
+win32:SOURCES += $$QT_SOURCE_TREE/src/corelib/io/qsettings_win.cpp
+macx:SOURCES += $$QT_SOURCE_TREE/src/corelib/io/qsettings_mac.cpp
+
+include(../../../src/tools/bootstrap/bootstrap.pri)
+include(../shared/formats.pri)
+include(../shared/proparser.pri)
+include(../../shared/symbian/epocroot.pri)
+
+win32:LIBS += -ladvapi32 # for qsettings_win.cpp
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/linguist/lrelease/main.cpp b/src/linguist/lrelease/main.cpp
new file mode 100644
index 000000000..b1beec873
--- /dev/null
+++ b/src/linguist/lrelease/main.cpp
@@ -0,0 +1,391 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+#include "profileevaluator.h"
+
+#ifndef QT_BOOTSTRAPPED
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTranslator>
+#endif
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QRegExp>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+
+#include <iostream>
+
+QT_USE_NAMESPACE
+
+#ifdef QT_BOOTSTRAPPED
+static void initBinaryDir(
+#ifndef Q_OS_WIN
+ const char *argv0
+#endif
+ );
+
+struct LR {
+ static inline QString tr(const char *sourceText, const char *comment = 0)
+ {
+ return QCoreApplication::translate("LRelease", sourceText, comment);
+ }
+};
+#else
+class LR {
+ Q_DECLARE_TR_FUNCTIONS(LRelease)
+};
+#endif
+
+static void printOut(const QString & out)
+{
+ QTextStream stream(stdout);
+ stream << out;
+}
+
+static void printUsage()
+{
+ printOut(LR::tr(
+ "Usage:\n"
+ " lrelease [options] project-file\n"
+ " lrelease [options] ts-files [-qm qm-file]\n\n"
+ "lrelease is part of Qt's Linguist tool chain. It can be used as a\n"
+ "stand-alone tool to convert XML-based translations files in the TS\n"
+ "format into the 'compiled' QM format used by QTranslator objects.\n\n"
+ "Options:\n"
+ " -help Display this information and exit\n"
+ " -idbased\n"
+ " Use IDs instead of source strings for message keying\n"
+ " -compress\n"
+ " Compress the QM files\n"
+ " -nounfinished\n"
+ " Do not include unfinished translations\n"
+ " -removeidentical\n"
+ " If the translated text is the same as\n"
+ " the source text, do not include the message\n"
+ " -markuntranslated <prefix>\n"
+ " If a message has no real translation, use the source text\n"
+ " prefixed with the given string instead\n"
+ " -silent\n"
+ " Do not explain what is being done\n"
+ " -version\n"
+ " Display the version of lrelease and exit\n"
+ ));
+}
+
+static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbose */)
+{
+ ConversionData cd;
+ bool ok = tor.load(tsFileName, cd, QLatin1String("auto"));
+ if (!ok) {
+ std::cerr << qPrintable(LR::tr("lrelease error: %1").arg(cd.error()));
+ } else {
+ if (!cd.errors().isEmpty())
+ printOut(cd.error());
+ }
+ cd.clearErrors();
+ return ok;
+}
+
+static bool releaseTranslator(Translator &tor, const QString &qmFileName,
+ ConversionData &cd, bool removeIdentical)
+{
+ tor.reportDuplicates(tor.resolveDuplicates(), qmFileName, cd.isVerbose());
+
+ if (cd.isVerbose())
+ printOut(LR::tr("Updating '%1'...\n").arg(qmFileName));
+ if (removeIdentical) {
+ if (cd.isVerbose())
+ printOut(LR::tr("Removing translations equal to source text in '%1'...\n").arg(qmFileName));
+ tor.stripIdenticalSourceTranslations();
+ }
+
+ QFile file(qmFileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ std::cerr << qPrintable(LR::tr("lrelease error: cannot create '%1': %2\n")
+ .arg(qmFileName, file.errorString()));
+ return false;
+ }
+
+ tor.normalizeTranslations(cd);
+ bool ok = tor.release(&file, cd);
+ file.close();
+
+ if (!ok) {
+ std::cerr << qPrintable(LR::tr("lrelease error: cannot save '%1': %2")
+ .arg(qmFileName, cd.error()));
+ } else if (!cd.errors().isEmpty()) {
+ printOut(cd.error());
+ }
+ cd.clearErrors();
+ return ok;
+}
+
+static bool releaseTsFile(const QString& tsFileName,
+ ConversionData &cd, bool removeIdentical)
+{
+ Translator tor;
+ if (!loadTsFile(tor, tsFileName, cd.isVerbose()))
+ return false;
+
+ QString qmFileName = tsFileName;
+ foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
+ if (qmFileName.endsWith(QLatin1Char('.') + fmt.extension)) {
+ qmFileName.chop(fmt.extension.length() + 1);
+ break;
+ }
+ }
+ qmFileName += QLatin1String(".qm");
+
+ return releaseTranslator(tor, qmFileName, cd, removeIdentical);
+}
+
+int main(int argc, char **argv)
+{
+#ifdef QT_BOOTSTRAPPED
+ initBinaryDir(
+#ifndef Q_OS_WIN
+ argv[0]
+#endif
+ );
+#else
+ QCoreApplication app(argc, argv);
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+#endif // Q_OS_WIN32
+#endif // QT_BOOTSTRAPPED
+
+ ConversionData cd;
+ cd.m_verbose = true; // the default is true starting with Qt 4.2
+ bool removeIdentical = false;
+ Translator tor;
+ QStringList inputFiles;
+ QString outputFile;
+
+ for (int i = 1; i < argc; ++i) {
+ if (!strcmp(argv[i], "-compress")) {
+ cd.m_saveMode = SaveStripped;
+ continue;
+ } else if (!strcmp(argv[i], "-idbased")) {
+ cd.m_idBased = true;
+ continue;
+ } else if (!strcmp(argv[i], "-nocompress")) {
+ cd.m_saveMode = SaveEverything;
+ continue;
+ } else if (!strcmp(argv[i], "-removeidentical")) {
+ removeIdentical = true;
+ continue;
+ } else if (!strcmp(argv[i], "-nounfinished")) {
+ cd.m_ignoreUnfinished = true;
+ continue;
+ } else if (!strcmp(argv[i], "-markuntranslated")) {
+ if (i == argc - 1) {
+ printUsage();
+ return 1;
+ }
+ cd.m_unTrPrefix = QString::fromLocal8Bit(argv[++i]);
+ } else if (!strcmp(argv[i], "-silent")) {
+ cd.m_verbose = false;
+ continue;
+ } else if (!strcmp(argv[i], "-verbose")) {
+ cd.m_verbose = true;
+ continue;
+ } else if (!strcmp(argv[i], "-version")) {
+ printOut(LR::tr("lrelease version %1\n").arg(QLatin1String(QT_VERSION_STR)));
+ return 0;
+ } else if (!strcmp(argv[i], "-qm")) {
+ if (i == argc - 1) {
+ printUsage();
+ return 1;
+ }
+ outputFile = QString::fromLocal8Bit(argv[++i]);
+ } else if (!strcmp(argv[i], "-help")) {
+ printUsage();
+ return 0;
+ } else if (argv[i][0] == '-') {
+ printUsage();
+ return 1;
+ } else {
+ inputFiles << QString::fromLocal8Bit(argv[i]);
+ }
+ }
+
+ if (inputFiles.isEmpty()) {
+ printUsage();
+ return 1;
+ }
+
+ foreach (const QString &inputFile, inputFiles) {
+ if (inputFile.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
+ || inputFile.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
+ QFileInfo fi(inputFile);
+ ProFile pro(fi.absoluteFilePath());
+
+ ProFileEvaluator visitor;
+ visitor.setVerbose(cd.isVerbose());
+
+ if (!visitor.queryProFile(&pro)) {
+ std::cerr << qPrintable(LR::tr(
+ "lrelease error: cannot read project file '%1'.\n")
+ .arg(inputFile));
+ continue;
+ }
+ if (!visitor.accept(&pro)) {
+ std::cerr << qPrintable(LR::tr(
+ "lrelease error: cannot process project file '%1'.\n")
+ .arg(inputFile));
+ continue;
+ }
+
+ QStringList translations = visitor.values(QLatin1String("TRANSLATIONS"));
+ if (translations.isEmpty()) {
+ std::cerr << qPrintable(LR::tr(
+ "lrelease warning: Met no 'TRANSLATIONS' entry in project file '%1'\n")
+ .arg(inputFile));
+ } else {
+ QDir proDir(fi.absolutePath());
+ foreach (const QString &trans, translations)
+ if (!releaseTsFile(QFileInfo(proDir, trans).filePath(), cd, removeIdentical))
+ return 1;
+ }
+ } else {
+ if (outputFile.isEmpty()) {
+ if (!releaseTsFile(inputFile, cd, removeIdentical))
+ return 1;
+ } else {
+ if (!loadTsFile(tor, inputFile, cd.isVerbose()))
+ return 1;
+ }
+ }
+ }
+
+ if (!outputFile.isEmpty())
+ return releaseTranslator(tor, outputFile, cd, removeIdentical) ? 0 : 1;
+
+ return 0;
+}
+
+#ifdef QT_BOOTSTRAPPED
+
+#ifdef Q_OS_WIN
+# include <windows.h>
+#endif
+
+static QString binDir;
+
+static void initBinaryDir(
+#ifndef Q_OS_WIN
+ const char *_argv0
+#endif
+ )
+{
+#ifdef Q_OS_WIN
+ wchar_t module_name[MAX_PATH];
+ GetModuleFileName(0, module_name, MAX_PATH);
+ QFileInfo filePath = QString::fromWCharArray(module_name);
+ binDir = filePath.filePath();
+#else
+ QString argv0 = QFile::decodeName(QByteArray(_argv0));
+ QString absPath;
+
+ if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
+ /*
+ If argv0 starts with a slash, it is already an absolute
+ file path.
+ */
+ absPath = argv0;
+ } else if (argv0.contains(QLatin1Char('/'))) {
+ /*
+ If argv0 contains one or more slashes, it is a file path
+ relative to the current directory.
+ */
+ absPath = QDir::current().absoluteFilePath(argv0);
+ } else {
+ /*
+ Otherwise, the file path has to be determined using the
+ PATH environment variable.
+ */
+ QByteArray pEnv = qgetenv("PATH");
+ QDir currentDir = QDir::current();
+ QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1String(":"));
+ for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
+ if ((*p).isEmpty())
+ continue;
+ QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
+ QFileInfo candidate_fi(candidate);
+ if (candidate_fi.exists() && !candidate_fi.isDir()) {
+ binDir = candidate_fi.canonicalPath();
+ return;
+ }
+ }
+ return;
+ }
+
+ QFileInfo fi(absPath);
+ if (fi.exists())
+ binDir = fi.canonicalPath();
+#endif
+}
+
+QT_BEGIN_NAMESPACE
+
+// The name is hard-coded in QLibraryInfo
+QString qmake_libraryInfoFile()
+{
+ if (binDir.isEmpty())
+ return QString();
+ return QDir(binDir).filePath(QString::fromLatin1("qt.conf"));
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_BOOTSTRAPPED
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
new file mode 100644
index 000000000..2ae478e70
--- /dev/null
+++ b/src/linguist/lupdate/cpp.cpp
@@ -0,0 +1,2245 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lupdate.h"
+
+#include <translator.h>
+
+#include <QtCore/QBitArray>
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QStack>
+#include <QtCore/QString>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
+
+#include <iostream>
+
+#include <ctype.h> // for isXXX()
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+/* qmake ignore Q_OBJECT */
+
+static QString MagicComment(QLatin1String("TRANSLATOR"));
+
+#define STRING(s) static QString str##s(QLatin1String(#s))
+
+//#define DIAGNOSE_RETRANSLATABILITY // FIXME: should make a runtime option of this
+
+class HashString {
+public:
+ HashString() : m_hash(0x80000000) {}
+ explicit HashString(const QString &str) : m_str(str), m_hash(0x80000000) {}
+ void setValue(const QString &str) { m_str = str; m_hash = 0x80000000; }
+ const QString &value() const { return m_str; }
+ bool operator==(const HashString &other) const { return m_str == other.m_str; }
+private:
+ QString m_str;
+ // qHash() of a QString is only 28 bits wide, so we can use
+ // the highest bit(s) as the "hash valid" flag.
+ mutable uint m_hash;
+ friend uint qHash(const HashString &str);
+};
+
+uint qHash(const HashString &str)
+{
+ if (str.m_hash & 0x80000000)
+ str.m_hash = qHash(str.m_str);
+ return str.m_hash;
+}
+
+class HashStringList {
+public:
+ explicit HashStringList(const QList<HashString> &list) : m_list(list), m_hash(0x80000000) {}
+ const QList<HashString> &value() const { return m_list; }
+ bool operator==(const HashStringList &other) const { return m_list == other.m_list; }
+private:
+ QList<HashString> m_list;
+ mutable uint m_hash;
+ friend uint qHash(const HashStringList &list);
+};
+
+uint qHash(const HashStringList &list)
+{
+ if (list.m_hash & 0x80000000) {
+ uint hash = 0;
+ foreach (const HashString &qs, list.m_list) {
+ hash ^= qHash(qs) ^ 0x0ad9f526;
+ hash = ((hash << 13) & 0x0fffffff) | (hash >> 15);
+ }
+ list.m_hash = hash;
+ }
+ return list.m_hash;
+}
+
+typedef QList<HashString> NamespaceList;
+
+struct Namespace {
+
+ Namespace() :
+ classDef(this),
+ hasTrFunctions(false), complained(false)
+ {}
+ ~Namespace()
+ {
+ qDeleteAll(children);
+ }
+
+ QHash<HashString, Namespace *> children;
+ QHash<HashString, NamespaceList> aliases;
+ QList<HashStringList> usings;
+
+ // Class declarations set no flags and create no namespaces, so they are ignored.
+ // Class definitions may appear multiple times - but only because we are trying to
+ // "compile" all sources irrespective of build configuration.
+ // Nested classes may be forward-declared inside a definition, and defined in another file.
+ // The latter will detach the class' child list, so clones need a backlink to the original
+ // definition (either one in case of multiple definitions).
+ // Namespaces can have tr() functions as well, so we need to track parent definitions for
+ // them as well. The complication is that we may have to deal with a forrest instead of
+ // a tree - in that case the parent will be arbitrary. However, it seem likely that
+ // Q_DECLARE_TR_FUNCTIONS would be used either in "class-like" namespaces with a central
+ // header or only locally in a file.
+ Namespace *classDef;
+
+ QString trQualification;
+
+ bool hasTrFunctions;
+ bool complained; // ... that tr functions are missing.
+};
+
+static int nextFileId;
+
+class VisitRecorder {
+public:
+ VisitRecorder()
+ {
+ m_ba.resize(nextFileId);
+ }
+ bool tryVisit(int fileId)
+ {
+ if (m_ba.at(fileId))
+ return false;
+ m_ba[fileId] = true;
+ return true;
+ }
+private:
+ QBitArray m_ba;
+};
+
+struct ParseResults {
+ int fileId;
+ Namespace rootNamespace;
+ QSet<const ParseResults *> includes;
+};
+
+typedef QHash<QString, const ParseResults *> ParseResultHash;
+typedef QHash<QString, const Translator *> TranslatorHash;
+
+class CppFiles {
+
+public:
+ static const ParseResults *getResults(const QString &cleanFile);
+ static void setResults(const QString &cleanFile, const ParseResults *results);
+ static const Translator *getTranslator(const QString &cleanFile);
+ static void setTranslator(const QString &cleanFile, const Translator *results);
+ static bool isBlacklisted(const QString &cleanFile);
+ static void setBlacklisted(const QString &cleanFile);
+
+private:
+ static ParseResultHash &parsedFiles();
+ static TranslatorHash &translatedFiles();
+ static QSet<QString> &blacklistedFiles();
+};
+
+class CppParser {
+
+public:
+ CppParser(ParseResults *results = 0);
+ void setInput(const QString &in);
+ void setInput(QTextStream &ts, const QString &fileName);
+ void setTranslator(Translator *_tor) { tor = _tor; }
+ void parse(const QString &initialContext, ConversionData &cd, QSet<QString> &inclusions);
+ void parseInternal(ConversionData &cd, QSet<QString> &inclusions);
+ const ParseResults *recordResults(bool isHeader);
+ void deleteResults() { delete results; }
+
+ struct SavedState {
+ NamespaceList namespaces;
+ QStack<int> namespaceDepths;
+ NamespaceList functionContext;
+ QString functionContextUnresolved;
+ QString pendingContext;
+ };
+
+private:
+ struct IfdefState {
+ IfdefState() {}
+ IfdefState(int _bracketDepth, int _braceDepth, int _parenDepth) :
+ bracketDepth(_bracketDepth),
+ braceDepth(_braceDepth),
+ parenDepth(_parenDepth),
+ elseLine(-1)
+ {}
+
+ SavedState state;
+ int bracketDepth, bracketDepth1st;
+ int braceDepth, braceDepth1st;
+ int parenDepth, parenDepth1st;
+ int elseLine;
+ };
+
+ std::ostream &yyMsg(int line = 0);
+
+ uint getChar();
+ uint getToken();
+ bool getMacroArgs();
+ bool match(uint t);
+ bool matchString(QString *s);
+ bool matchEncoding(bool *utf8);
+ bool matchStringOrNull(QString *s);
+ bool matchExpression();
+
+ QString transcode(const QString &str, bool utf8);
+ void recordMessage(
+ int line, const QString &context, const QString &text, const QString &comment,
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool utf8, bool plural);
+
+ void processInclude(const QString &file, ConversionData &cd,
+ QSet<QString> &inclusions);
+
+ void saveState(SavedState *state);
+ void loadState(const SavedState *state);
+
+ static QString stringifyNamespace(const NamespaceList &namespaces);
+ static QStringList stringListifyNamespace(const NamespaceList &namespaces);
+ typedef bool (CppParser::*VisitNamespaceCallback)(const Namespace *ns, void *context) const;
+ bool visitNamespace(const NamespaceList &namespaces, int nsCount,
+ VisitNamespaceCallback callback, void *context,
+ VisitRecorder &vr, const ParseResults *rslt) const;
+ bool visitNamespace(const NamespaceList &namespaces, int nsCount,
+ VisitNamespaceCallback callback, void *context) const;
+ static QStringList stringListifySegments(const QList<HashString> &namespaces);
+ bool qualifyOneCallbackOwn(const Namespace *ns, void *context) const;
+ bool qualifyOneCallbackUsing(const Namespace *ns, void *context) const;
+ bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
+ NamespaceList *resolved, QSet<HashStringList> *visitedUsings) const;
+ bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
+ NamespaceList *resolved) const;
+ bool fullyQualify(const NamespaceList &namespaces, int nsCnt,
+ const QList<HashString> &segments, bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const;
+ bool fullyQualify(const NamespaceList &namespaces,
+ const QList<HashString> &segments, bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const;
+ bool fullyQualify(const NamespaceList &namespaces,
+ const QString &segments, bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const;
+ bool findNamespaceCallback(const Namespace *ns, void *context) const;
+ const Namespace *findNamespace(const NamespaceList &namespaces, int nsCount = -1) const;
+ void enterNamespace(NamespaceList *namespaces, const HashString &name);
+ void truncateNamespaces(NamespaceList *namespaces, int lenght);
+ Namespace *modifyNamespace(NamespaceList *namespaces, bool haveLast = true);
+
+ enum {
+ Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return,
+ Tok_tr, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid,
+ Tok_Q_OBJECT, Tok_Q_DECLARE_TR_FUNCTIONS,
+ Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon,
+ Tok_Equals, Tok_LeftBracket, Tok_RightBracket,
+ Tok_LeftBrace, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon,
+ Tok_Null, Tok_Integer,
+ Tok_QuotedInclude, Tok_AngledInclude,
+ Tok_Other
+ };
+
+ // Tokenizer state
+ QString yyFileName;
+ int yyCh;
+ bool yyAtNewline;
+ bool yyCodecIsUtf8;
+ bool yyForceUtf8;
+ QString yyWord;
+ qlonglong yyInteger;
+ QStack<IfdefState> yyIfdefStack;
+ int yyBracketDepth;
+ int yyBraceDepth;
+ int yyParenDepth;
+ int yyLineNo;
+ int yyCurLineNo;
+ int yyBracketLineNo;
+ int yyBraceLineNo;
+ int yyParenLineNo;
+
+ // the string to read from and current position in the string
+ QTextCodec *yySourceCodec;
+ QString yyInStr;
+ const ushort *yyInPtr;
+
+ // Parser state
+ uint yyTok;
+
+ NamespaceList namespaces;
+ QStack<int> namespaceDepths;
+ NamespaceList functionContext;
+ QString functionContextUnresolved;
+ QString prospectiveContext;
+ QString pendingContext;
+ ParseResults *results;
+ Translator *tor;
+ bool directInclude;
+
+ SavedState savedState;
+ int yyMinBraceDepth;
+ bool inDefine;
+};
+
+CppParser::CppParser(ParseResults *_results)
+{
+ tor = 0;
+ if (_results) {
+ results = _results;
+ directInclude = true;
+ } else {
+ results = new ParseResults;
+ directInclude = false;
+ }
+ yyBracketDepth = 0;
+ yyBraceDepth = 0;
+ yyParenDepth = 0;
+ yyCurLineNo = 1;
+ yyBracketLineNo = 1;
+ yyBraceLineNo = 1;
+ yyParenLineNo = 1;
+ yyAtNewline = true;
+ yyMinBraceDepth = 0;
+ inDefine = false;
+}
+
+
+std::ostream &CppParser::yyMsg(int line)
+{
+ return std::cerr << qPrintable(yyFileName) << ':' << (line ? line : yyLineNo) << ": ";
+}
+
+void CppParser::setInput(const QString &in)
+{
+ yyInStr = in;
+ yyFileName = QString();
+ yySourceCodec = 0;
+ yyForceUtf8 = true;
+}
+
+void CppParser::setInput(QTextStream &ts, const QString &fileName)
+{
+ yyInStr = ts.readAll();
+ yyFileName = fileName;
+ yySourceCodec = ts.codec();
+ yyForceUtf8 = false;
+}
+
+/*
+ The first part of this source file is the C++ tokenizer. We skip
+ most of C++; the only tokens that interest us are defined here.
+ Thus, the code fragment
+
+ int main()
+ {
+ printf("Hello, world!\n");
+ return 0;
+ }
+
+ is broken down into the following tokens (Tok_ omitted):
+
+ Ident Ident LeftParen RightParen
+ LeftBrace
+ Ident LeftParen String RightParen Semicolon
+ return Semicolon
+ RightBrace.
+
+ The 0 doesn't produce any token.
+*/
+
+uint CppParser::getChar()
+{
+ const ushort *uc = yyInPtr;
+ forever {
+ ushort c = *uc;
+ if (!c) {
+ yyInPtr = uc;
+ return EOF;
+ }
+ ++uc;
+ if (c == '\\') {
+ ushort cc = *uc;
+ if (cc == '\n') {
+ ++yyCurLineNo;
+ ++uc;
+ continue;
+ }
+ if (cc == '\r') {
+ ++yyCurLineNo;
+ ++uc;
+ if (*uc == '\n')
+ ++uc;
+ continue;
+ }
+ }
+ if (c == '\r') {
+ if (*uc == '\n')
+ ++uc;
+ c = '\n';
+ ++yyCurLineNo;
+ yyAtNewline = true;
+ } else if (c == '\n') {
+ ++yyCurLineNo;
+ yyAtNewline = true;
+ } else if (c != ' ' && c != '\t' && c != '#') {
+ yyAtNewline = false;
+ }
+ yyInPtr = uc;
+ return c;
+ }
+}
+
+// This ignores commas, parens and comments.
+// IOW, it understands only a single, simple argument.
+bool CppParser::getMacroArgs()
+{
+ // Failing this assertion would mean losing the preallocated buffer.
+ Q_ASSERT(yyWord.isDetached());
+ yyWord.resize(0);
+
+ while (isspace(yyCh))
+ yyCh = getChar();
+ if (yyCh != '(')
+ return false;
+ do {
+ yyCh = getChar();
+ } while (isspace(yyCh));
+ ushort *ptr = (ushort *)yyWord.unicode();
+ while (yyCh != ')') {
+ if (yyCh == EOF)
+ return false;
+ *ptr++ = yyCh;
+ yyCh = getChar();
+ }
+ yyCh = getChar();
+ for (; ptr != (ushort *)yyWord.unicode() && isspace(*(ptr - 1)); --ptr) ;
+ yyWord.resize(ptr - (ushort *)yyWord.unicode());
+ return true;
+}
+
+STRING(Q_OBJECT);
+STRING(Q_DECLARE_TR_FUNCTIONS);
+STRING(QT_TR_NOOP);
+STRING(QT_TRID_NOOP);
+STRING(QT_TRANSLATE_NOOP);
+STRING(QT_TRANSLATE_NOOP3);
+STRING(QT_TR_NOOP_UTF8);
+STRING(QT_TRANSLATE_NOOP_UTF8);
+STRING(QT_TRANSLATE_NOOP3_UTF8);
+STRING(class);
+// QTranslator::findMessage() has the same parameters as QApplication::translate()
+STRING(findMessage);
+STRING(friend);
+STRING(namespace);
+STRING(operator);
+STRING(qtTrId);
+STRING(return);
+STRING(struct);
+STRING(TR);
+STRING(Tr);
+STRING(tr);
+STRING(trUtf8);
+STRING(translate);
+STRING(using);
+
+uint CppParser::getToken()
+{
+ restart:
+ // Failing this assertion would mean losing the preallocated buffer.
+ Q_ASSERT(yyWord.isDetached());
+ yyWord.resize(0);
+
+ while (yyCh != EOF) {
+ yyLineNo = yyCurLineNo;
+
+ if (yyCh == '#' && yyAtNewline) {
+ /*
+ Early versions of lupdate complained about
+ unbalanced braces in the following code:
+
+ #ifdef ALPHA
+ while (beta) {
+ #else
+ while (gamma) {
+ #endif
+ delta;
+ }
+
+ The code contains, indeed, two opening braces for
+ one closing brace; yet there's no reason to panic.
+
+ The solution is to remember yyBraceDepth as it was
+ when #if, #ifdef or #ifndef was met, and to set
+ yyBraceDepth to that value when meeting #elif or
+ #else.
+ */
+ do {
+ yyCh = getChar();
+ } while (isspace(yyCh) && yyCh != '\n');
+
+ switch (yyCh) {
+ case 'd': // define
+ // Skip over the name of the define to avoid it being interpreted as c++ code
+ do { // Rest of "define"
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (!isspace(yyCh));
+ do { // Space beween "define" and macro name
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (isspace(yyCh));
+ do { // Macro name
+ if (yyCh == '(') {
+ // Argument list. Follows the name without a space, and no
+ // paren nesting is possible.
+ do {
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (yyCh != ')');
+ break;
+ }
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (!isspace(yyCh));
+ do { // Shortcut the immediate newline case if no comments follow.
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (isspace(yyCh));
+
+ saveState(&savedState);
+ yyMinBraceDepth = yyBraceDepth;
+ inDefine = true;
+ goto restart;
+ case 'i':
+ yyCh = getChar();
+ if (yyCh == 'f') {
+ // if, ifdef, ifndef
+ yyIfdefStack.push(IfdefState(yyBracketDepth, yyBraceDepth, yyParenDepth));
+ yyCh = getChar();
+ } else if (yyCh == 'n') {
+ // include
+ do {
+ yyCh = getChar();
+ } while (yyCh != EOF && !isspace(yyCh));
+ do {
+ yyCh = getChar();
+ } while (isspace(yyCh));
+ int tChar;
+ if (yyCh == '"')
+ tChar = '"';
+ else if (yyCh == '<')
+ tChar = '>';
+ else
+ break;
+ ushort *ptr = (ushort *)yyWord.unicode();
+ forever {
+ yyCh = getChar();
+ if (yyCh == EOF || yyCh == '\n')
+ break;
+ if (yyCh == tChar) {
+ yyCh = getChar();
+ break;
+ }
+ *ptr++ = yyCh;
+ }
+ yyWord.resize(ptr - (ushort *)yyWord.unicode());
+ return (tChar == '"') ? Tok_QuotedInclude : Tok_AngledInclude;
+ }
+ break;
+ case 'e':
+ yyCh = getChar();
+ if (yyCh == 'l') {
+ // elif, else
+ if (!yyIfdefStack.isEmpty()) {
+ IfdefState &is = yyIfdefStack.top();
+ if (is.elseLine != -1) {
+ if (yyBracketDepth != is.bracketDepth1st
+ || yyBraceDepth != is.braceDepth1st
+ || yyParenDepth != is.parenDepth1st)
+ yyMsg(is.elseLine)
+ << qPrintable(LU::tr("Parenthesis/bracket/brace mismatch between "
+ "#if and #else branches; using #if branch\n"));
+ } else {
+ is.bracketDepth1st = yyBracketDepth;
+ is.braceDepth1st = yyBraceDepth;
+ is.parenDepth1st = yyParenDepth;
+ saveState(&is.state);
+ }
+ is.elseLine = yyLineNo;
+ yyBracketDepth = is.bracketDepth;
+ yyBraceDepth = is.braceDepth;
+ yyParenDepth = is.parenDepth;
+ }
+ yyCh = getChar();
+ } else if (yyCh == 'n') {
+ // endif
+ if (!yyIfdefStack.isEmpty()) {
+ IfdefState is = yyIfdefStack.pop();
+ if (is.elseLine != -1) {
+ if (yyBracketDepth != is.bracketDepth1st
+ || yyBraceDepth != is.braceDepth1st
+ || yyParenDepth != is.parenDepth1st)
+ yyMsg(is.elseLine)
+ << qPrintable(LU::tr("Parenthesis/brace mismatch between "
+ "#if and #else branches; using #if branch\n"));
+ yyBracketDepth = is.bracketDepth1st;
+ yyBraceDepth = is.braceDepth1st;
+ yyParenDepth = is.parenDepth1st;
+ loadState(&is.state);
+ }
+ }
+ yyCh = getChar();
+ }
+ break;
+ }
+ // Optimization: skip over rest of preprocessor directive
+ do {
+ if (yyCh == '/') {
+ yyCh = getChar();
+ if (yyCh == '/') {
+ do {
+ yyCh = getChar();
+ } while (yyCh != EOF && yyCh != '\n');
+ break;
+ } else if (yyCh == '*') {
+ bool metAster = false;
+
+ forever {
+ yyCh = getChar();
+ if (yyCh == EOF) {
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ comment\n"));
+ break;
+ }
+
+ if (yyCh == '*') {
+ metAster = true;
+ } else if (metAster && yyCh == '/') {
+ yyCh = getChar();
+ break;
+ } else {
+ metAster = false;
+ }
+ }
+ }
+ } else {
+ yyCh = getChar();
+ }
+ } while (yyCh != '\n' && yyCh != EOF);
+ yyCh = getChar();
+ } else if ((yyCh >= 'A' && yyCh <= 'Z') || (yyCh >= 'a' && yyCh <= 'z') || yyCh == '_') {
+ ushort *ptr = (ushort *)yyWord.unicode();
+ do {
+ *ptr++ = yyCh;
+ yyCh = getChar();
+ } while ((yyCh >= 'A' && yyCh <= 'Z') || (yyCh >= 'a' && yyCh <= 'z')
+ || (yyCh >= '0' && yyCh <= '9') || yyCh == '_');
+ yyWord.resize(ptr - (ushort *)yyWord.unicode());
+
+ //qDebug() << "IDENT: " << yyWord;
+
+ switch (yyWord.unicode()[0].unicode()) {
+ case 'Q':
+ if (yyWord == strQ_OBJECT)
+ return Tok_Q_OBJECT;
+ if (yyWord == strQ_DECLARE_TR_FUNCTIONS)
+ return Tok_Q_DECLARE_TR_FUNCTIONS;
+ if (yyWord == strQT_TR_NOOP)
+ return Tok_tr;
+ if (yyWord == strQT_TRID_NOOP)
+ return Tok_trid;
+ if (yyWord == strQT_TRANSLATE_NOOP)
+ return Tok_translate;
+ if (yyWord == strQT_TRANSLATE_NOOP3)
+ return Tok_translate;
+ if (yyWord == strQT_TR_NOOP_UTF8)
+ return Tok_trUtf8;
+ if (yyWord == strQT_TRANSLATE_NOOP_UTF8)
+ return Tok_translateUtf8;
+ if (yyWord == strQT_TRANSLATE_NOOP3_UTF8)
+ return Tok_translateUtf8;
+ break;
+ case 'T':
+ // TR() for when all else fails
+ if (yyWord == strTR || yyWord == strTr)
+ return Tok_tr;
+ break;
+ case 'c':
+ if (yyWord == strclass)
+ return Tok_class;
+ break;
+ case 'f':
+ /*
+ QTranslator::findMessage() has the same parameters as
+ QApplication::translate().
+ */
+ if (yyWord == strfindMessage)
+ return Tok_translate;
+ if (yyWord == strfriend)
+ return Tok_friend;
+ break;
+ case 'n':
+ if (yyWord == strnamespace)
+ return Tok_namespace;
+ break;
+ case 'o':
+ if (yyWord == stroperator) {
+ // Operator overload declaration/definition.
+ // We need to prevent those characters from confusing the followup
+ // parsing. Actually using them does not add value, so just eat them.
+ while (isspace(yyCh))
+ yyCh = getChar();
+ while (yyCh == '+' || yyCh == '-' || yyCh == '*' || yyCh == '/' || yyCh == '%'
+ || yyCh == '=' || yyCh == '<' || yyCh == '>' || yyCh == '!'
+ || yyCh == '&' || yyCh == '|' || yyCh == '~' || yyCh == '^'
+ || yyCh == '[' || yyCh == ']')
+ yyCh = getChar();
+ }
+ break;
+ case 'q':
+ if (yyWord == strqtTrId)
+ return Tok_trid;
+ break;
+ case 'r':
+ if (yyWord == strreturn)
+ return Tok_return;
+ break;
+ case 's':
+ if (yyWord == strstruct)
+ return Tok_class;
+ break;
+ case 't':
+ if (yyWord == strtr)
+ return Tok_tr;
+ if (yyWord == strtrUtf8)
+ return Tok_trUtf8;
+ if (yyWord == strtranslate)
+ return Tok_translate;
+ break;
+ case 'u':
+ if (yyWord == strusing)
+ return Tok_using;
+ break;
+ }
+ return Tok_Ident;
+ } else {
+ switch (yyCh) {
+ case '\n':
+ if (inDefine) {
+ loadState(&savedState);
+ prospectiveContext.clear();
+ yyBraceDepth = yyMinBraceDepth;
+ yyMinBraceDepth = 0;
+ inDefine = false;
+ }
+ yyCh = getChar();
+ break;
+ case '/':
+ yyCh = getChar();
+ if (yyCh == '/') {
+ ushort *ptr = (ushort *)yyWord.unicode() + yyWord.length();
+ do {
+ yyCh = getChar();
+ if (yyCh == EOF)
+ break;
+ *ptr++ = yyCh;
+ } while (yyCh != '\n');
+ yyWord.resize(ptr - (ushort *)yyWord.unicode());
+ } else if (yyCh == '*') {
+ bool metAster = false;
+ ushort *ptr = (ushort *)yyWord.unicode() + yyWord.length();
+
+ forever {
+ yyCh = getChar();
+ if (yyCh == EOF) {
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ comment\n"));
+ break;
+ }
+ *ptr++ = yyCh;
+
+ if (yyCh == '*')
+ metAster = true;
+ else if (metAster && yyCh == '/')
+ break;
+ else
+ metAster = false;
+ }
+ yyWord.resize(ptr - (ushort *)yyWord.unicode() - 2);
+
+ yyCh = getChar();
+ }
+ return Tok_Comment;
+ case '"': {
+ ushort *ptr = (ushort *)yyWord.unicode() + yyWord.length();
+ yyCh = getChar();
+ while (yyCh != EOF && yyCh != '\n' && yyCh != '"') {
+ if (yyCh == '\\') {
+ yyCh = getChar();
+ if (yyCh == EOF || yyCh == '\n')
+ break;
+ *ptr++ = '\\';
+ }
+ *ptr++ = yyCh;
+ yyCh = getChar();
+ }
+ yyWord.resize(ptr - (ushort *)yyWord.unicode());
+
+ if (yyCh != '"')
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ string\n"));
+ else
+ yyCh = getChar();
+ return Tok_String;
+ }
+ case '-':
+ yyCh = getChar();
+ if (yyCh == '>') {
+ yyCh = getChar();
+ return Tok_Arrow;
+ }
+ break;
+ case ':':
+ yyCh = getChar();
+ if (yyCh == ':') {
+ yyCh = getChar();
+ return Tok_ColonColon;
+ }
+ return Tok_Colon;
+ // Incomplete: '<' might be part of '<=' or of template syntax.
+ // The main intent of not completely ignoring it is to break
+ // parsing of things like std::cout << QObject::tr() as
+ // context std::cout::QObject (see Task 161106)
+ case '=':
+ yyCh = getChar();
+ return Tok_Equals;
+ case '>':
+ case '<':
+ yyCh = getChar();
+ return Tok_Other;
+ case '\'':
+ yyCh = getChar();
+ if (yyCh == '\\')
+ yyCh = getChar();
+
+ forever {
+ if (yyCh == EOF || yyCh == '\n') {
+ yyMsg() << "Unterminated C++ character\n";
+ break;
+ }
+ yyCh = getChar();
+ if (yyCh == '\'') {
+ yyCh = getChar();
+ break;
+ }
+ }
+ break;
+ case '{':
+ if (yyBraceDepth == 0)
+ yyBraceLineNo = yyCurLineNo;
+ yyBraceDepth++;
+ yyCh = getChar();
+ return Tok_LeftBrace;
+ case '}':
+ if (yyBraceDepth == yyMinBraceDepth) {
+ if (!inDefine)
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing brace in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
+ // Avoid things getting messed up even more
+ yyCh = getChar();
+ return Tok_Semicolon;
+ }
+ yyBraceDepth--;
+ yyCh = getChar();
+ return Tok_RightBrace;
+ case '(':
+ if (yyParenDepth == 0)
+ yyParenLineNo = yyCurLineNo;
+ yyParenDepth++;
+ yyCh = getChar();
+ return Tok_LeftParen;
+ case ')':
+ if (yyParenDepth == 0)
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing parenthesis in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
+ else
+ yyParenDepth--;
+ yyCh = getChar();
+ return Tok_RightParen;
+ case '[':
+ if (yyBracketDepth == 0)
+ yyBracketLineNo = yyCurLineNo;
+ yyBracketDepth++;
+ yyCh = getChar();
+ return Tok_LeftBracket;
+ case ']':
+ if (yyBracketDepth == 0)
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing bracket in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
+ else
+ yyBracketDepth--;
+ yyCh = getChar();
+ return Tok_RightBracket;
+ case ',':
+ yyCh = getChar();
+ return Tok_Comma;
+ case ';':
+ yyCh = getChar();
+ return Tok_Semicolon;
+ case '0':
+ yyCh = getChar();
+ if (yyCh == 'x') {
+ do {
+ yyCh = getChar();
+ } while ((yyCh >= '0' && yyCh <= '9')
+ || (yyCh >= 'a' && yyCh <= 'f') || (yyCh >= 'A' && yyCh <= 'F'));
+ return Tok_Integer;
+ }
+ if (yyCh < '0' || yyCh > '9')
+ return Tok_Null;
+ // Fallthrough
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ do {
+ yyCh = getChar();
+ } while (yyCh >= '0' && yyCh <= '9');
+ return Tok_Integer;
+ default:
+ yyCh = getChar();
+ break;
+ }
+ }
+ }
+ return Tok_Eof;
+}
+
+/*
+ The second part of this source file are namespace/class related
+ utilities for the third part.
+*/
+
+void CppParser::saveState(SavedState *state)
+{
+ state->namespaces = namespaces;
+ state->namespaceDepths = namespaceDepths;
+ state->functionContext = functionContext;
+ state->functionContextUnresolved = functionContextUnresolved;
+ state->pendingContext = pendingContext;
+}
+
+void CppParser::loadState(const SavedState *state)
+{
+ namespaces = state->namespaces;
+ namespaceDepths = state->namespaceDepths;
+ functionContext = state->functionContext;
+ functionContextUnresolved = state->functionContextUnresolved;
+ pendingContext = state->pendingContext;
+}
+
+Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool haveLast)
+{
+ Namespace *pns, *ns = &results->rootNamespace;
+ for (int i = 1; i < namespaces->count(); ++i) {
+ pns = ns;
+ if (!(ns = pns->children.value(namespaces->at(i)))) {
+ do {
+ ns = new Namespace;
+ if (haveLast || i < namespaces->count() - 1)
+ if (const Namespace *ons = findNamespace(*namespaces, i + 1))
+ ns->classDef = ons->classDef;
+ pns->children.insert(namespaces->at(i), ns);
+ pns = ns;
+ } while (++i < namespaces->count());
+ break;
+ }
+ }
+ return ns;
+}
+
+QString CppParser::stringifyNamespace(const NamespaceList &namespaces)
+{
+ QString ret;
+ for (int i = 1; i < namespaces.count(); ++i) {
+ if (i > 1)
+ ret += QLatin1String("::");
+ ret += namespaces.at(i).value();
+ }
+ return ret;
+}
+
+QStringList CppParser::stringListifyNamespace(const NamespaceList &namespaces)
+{
+ QStringList ret;
+ for (int i = 1; i < namespaces.count(); ++i)
+ ret << namespaces.at(i).value();
+ return ret;
+}
+
+bool CppParser::visitNamespace(const NamespaceList &namespaces, int nsCount,
+ VisitNamespaceCallback callback, void *context,
+ VisitRecorder &vr, const ParseResults *rslt) const
+{
+ const Namespace *ns = &rslt->rootNamespace;
+ for (int i = 1; i < nsCount; ++i)
+ if (!(ns = ns->children.value(namespaces.at(i))))
+ goto supers;
+ if ((this->*callback)(ns, context))
+ return true;
+supers:
+ foreach (const ParseResults *sup, rslt->includes)
+ if (vr.tryVisit(sup->fileId)
+ && visitNamespace(namespaces, nsCount, callback, context, vr, sup))
+ return true;
+ return false;
+}
+
+bool CppParser::visitNamespace(const NamespaceList &namespaces, int nsCount,
+ VisitNamespaceCallback callback, void *context) const
+{
+ VisitRecorder vr;
+ return visitNamespace(namespaces, nsCount, callback, context, vr, results);
+}
+
+QStringList CppParser::stringListifySegments(const QList<HashString> &segments)
+{
+ QStringList ret;
+ for (int i = 0; i < segments.count(); ++i)
+ ret << segments.at(i).value();
+ return ret;
+}
+
+struct QualifyOneData {
+ QualifyOneData(const NamespaceList &ns, int nsc, const HashString &seg, NamespaceList *rslvd,
+ QSet<HashStringList> *visited)
+ : namespaces(ns), nsCount(nsc), segment(seg), resolved(rslvd), visitedUsings(visited)
+ {}
+
+ const NamespaceList &namespaces;
+ int nsCount;
+ const HashString &segment;
+ NamespaceList *resolved;
+ QSet<HashStringList> *visitedUsings;
+};
+
+bool CppParser::qualifyOneCallbackOwn(const Namespace *ns, void *context) const
+{
+ QualifyOneData *data = (QualifyOneData *)context;
+ if (ns->children.contains(data->segment)) {
+ *data->resolved = data->namespaces.mid(0, data->nsCount);
+ *data->resolved << data->segment;
+ return true;
+ }
+ QHash<HashString, NamespaceList>::ConstIterator nsai = ns->aliases.constFind(data->segment);
+ if (nsai != ns->aliases.constEnd()) {
+ const NamespaceList &nsl = *nsai;
+ if (nsl.last().value().isEmpty()) { // Delayed alias resolution
+ NamespaceList &nslIn = *const_cast<NamespaceList *>(&nsl);
+ nslIn.removeLast();
+ NamespaceList nslOut;
+ if (!fullyQualify(data->namespaces, data->nsCount, nslIn, false, &nslOut, 0)) {
+ const_cast<Namespace *>(ns)->aliases.remove(data->segment);
+ return false;
+ }
+ nslIn = nslOut;
+ }
+ *data->resolved = nsl;
+ return true;
+ }
+ return false;
+}
+
+bool CppParser::qualifyOneCallbackUsing(const Namespace *ns, void *context) const
+{
+ QualifyOneData *data = (QualifyOneData *)context;
+ foreach (const HashStringList &use, ns->usings)
+ if (!data->visitedUsings->contains(use)) {
+ data->visitedUsings->insert(use);
+ if (qualifyOne(use.value(), use.value().count(), data->segment, data->resolved,
+ data->visitedUsings))
+ return true;
+ }
+ return false;
+}
+
+bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
+ NamespaceList *resolved, QSet<HashStringList> *visitedUsings) const
+{
+ QualifyOneData data(namespaces, nsCnt, segment, resolved, visitedUsings);
+
+ if (visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackOwn, &data))
+ return true;
+
+ return visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackUsing, &data);
+}
+
+bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
+ NamespaceList *resolved) const
+{
+ QSet<HashStringList> visitedUsings;
+
+ return qualifyOne(namespaces, nsCnt, segment, resolved, &visitedUsings);
+}
+
+bool CppParser::fullyQualify(const NamespaceList &namespaces, int nsCnt,
+ const QList<HashString> &segments, bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const
+{
+ int nsIdx;
+ int initSegIdx;
+
+ if (segments.first().value().isEmpty()) {
+ // fully qualified
+ if (segments.count() == 1) {
+ resolved->clear();
+ *resolved << HashString(QString());
+ return true;
+ }
+ initSegIdx = 1;
+ nsIdx = 0;
+ } else {
+ initSegIdx = 0;
+ nsIdx = nsCnt - 1;
+ }
+
+ do {
+ if (qualifyOne(namespaces, nsIdx + 1, segments[initSegIdx], resolved)) {
+ int segIdx = initSegIdx;
+ while (++segIdx < segments.count()) {
+ if (!qualifyOne(*resolved, resolved->count(), segments[segIdx], resolved)) {
+ if (unresolved)
+ *unresolved = stringListifySegments(segments.mid(segIdx));
+ return false;
+ }
+ }
+ return true;
+ }
+ } while (!isDeclaration && --nsIdx >= 0);
+ resolved->clear();
+ *resolved << HashString(QString());
+ if (unresolved)
+ *unresolved = stringListifySegments(segments.mid(initSegIdx));
+ return false;
+}
+
+bool CppParser::fullyQualify(const NamespaceList &namespaces,
+ const QList<HashString> &segments, bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const
+{
+ return fullyQualify(namespaces, namespaces.count(),
+ segments, isDeclaration, resolved, unresolved);
+}
+
+bool CppParser::fullyQualify(const NamespaceList &namespaces,
+ const QString &quali, bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const
+{
+ static QString strColons(QLatin1String("::"));
+
+ QList<HashString> segments;
+ foreach (const QString &str, quali.split(strColons)) // XXX slow, but needs to be fast(?)
+ segments << HashString(str);
+ return fullyQualify(namespaces, segments, isDeclaration, resolved, unresolved);
+}
+
+bool CppParser::findNamespaceCallback(const Namespace *ns, void *context) const
+{
+ *((const Namespace **)context) = ns;
+ return true;
+}
+
+const Namespace *CppParser::findNamespace(const NamespaceList &namespaces, int nsCount) const
+{
+ const Namespace *ns = 0;
+ if (nsCount == -1)
+ nsCount = namespaces.count();
+ visitNamespace(namespaces, nsCount, &CppParser::findNamespaceCallback, &ns);
+ return ns;
+}
+
+void CppParser::enterNamespace(NamespaceList *namespaces, const HashString &name)
+{
+ *namespaces << name;
+ if (!findNamespace(*namespaces))
+ modifyNamespace(namespaces, false);
+}
+
+void CppParser::truncateNamespaces(NamespaceList *namespaces, int length)
+{
+ if (namespaces->count() > length)
+ namespaces->erase(namespaces->begin() + length, namespaces->end());
+}
+
+/*
+ Functions for processing include files.
+*/
+
+ParseResultHash &CppFiles::parsedFiles()
+{
+ static ParseResultHash parsed;
+
+ return parsed;
+}
+
+TranslatorHash &CppFiles::translatedFiles()
+{
+ static TranslatorHash tors;
+
+ return tors;
+}
+
+QSet<QString> &CppFiles::blacklistedFiles()
+{
+ static QSet<QString> blacklisted;
+
+ return blacklisted;
+}
+
+const ParseResults *CppFiles::getResults(const QString &cleanFile)
+{
+ return parsedFiles().value(cleanFile);
+}
+
+void CppFiles::setResults(const QString &cleanFile, const ParseResults *results)
+{
+ parsedFiles().insert(cleanFile, results);
+}
+
+const Translator *CppFiles::getTranslator(const QString &cleanFile)
+{
+ return translatedFiles().value(cleanFile);
+}
+
+void CppFiles::setTranslator(const QString &cleanFile, const Translator *tor)
+{
+ translatedFiles().insert(cleanFile, tor);
+}
+
+bool CppFiles::isBlacklisted(const QString &cleanFile)
+{
+ return blacklistedFiles().contains(cleanFile);
+}
+
+void CppFiles::setBlacklisted(const QString &cleanFile)
+{
+ blacklistedFiles().insert(cleanFile);
+}
+
+static bool isHeader(const QString &name)
+{
+ QString fileExt = QFileInfo(name).suffix();
+ return fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive);
+}
+
+void CppParser::processInclude(const QString &file, ConversionData &cd,
+ QSet<QString> &inclusions)
+{
+ QString cleanFile = QDir::cleanPath(file);
+
+ if (inclusions.contains(cleanFile)) {
+ yyMsg() << qPrintable(LU::tr("circular inclusion of %1\n").arg(cleanFile));
+ return;
+ }
+
+ // If the #include is in any kind of namespace, has been blacklisted previously,
+ // or is not a header file (stdc++ extensionless or *.h*), then really include
+ // it. Otherwise it is safe to process it stand-alone and re-use the parsed
+ // namespace data for inclusion into other files.
+ bool isIndirect = false;
+ if (namespaces.count() == 1 && functionContext.count() == 1
+ && functionContextUnresolved.isEmpty() && pendingContext.isEmpty()
+ && !CppFiles::isBlacklisted(cleanFile)
+ && isHeader(cleanFile)) {
+
+ if (const ParseResults *res = CppFiles::getResults(cleanFile)) {
+ results->includes.insert(res);
+ return;
+ }
+
+ isIndirect = true;
+ }
+
+ QFile f(cleanFile);
+ if (!f.open(QIODevice::ReadOnly)) {
+ yyMsg() << qPrintable(LU::tr("Cannot open %1: %2\n").arg(cleanFile, f.errorString()));
+ return;
+ }
+
+ QTextStream ts(&f);
+ ts.setCodec(yySourceCodec);
+ ts.setAutoDetectUnicode(true);
+
+ inclusions.insert(cleanFile);
+ if (isIndirect) {
+ CppParser parser;
+ foreach (const QString &projectRoot, cd.m_projectRoots)
+ if (cleanFile.startsWith(projectRoot)) {
+ parser.setTranslator(new Translator);
+ break;
+ }
+ parser.setInput(ts, cleanFile);
+ parser.parse(cd.m_defaultContext, cd, inclusions);
+ results->includes.insert(parser.recordResults(true));
+ } else {
+ CppParser parser(results);
+ parser.namespaces = namespaces;
+ parser.functionContext = functionContext;
+ parser.functionContextUnresolved = functionContextUnresolved;
+ parser.pendingContext = pendingContext;
+ parser.setInput(ts, cleanFile);
+ parser.parseInternal(cd, inclusions);
+ // Avoid that messages obtained by direct scanning are used
+ CppFiles::setBlacklisted(cleanFile);
+ }
+ inclusions.remove(cleanFile);
+}
+
+/*
+ The third part of this source file is the parser. It accomplishes
+ a very easy task: It finds all strings inside a tr() or translate()
+ call, and possibly finds out the context of the call. It supports
+ three cases: (1) the context is specified, as in
+ FunnyDialog::tr("Hello") or translate("FunnyDialog", "Hello");
+ (2) the call appears within an inlined function; (3) the call
+ appears within a function defined outside the class definition.
+*/
+
+bool CppParser::match(uint t)
+{
+ bool matches = (yyTok == t);
+ if (matches)
+ yyTok = getToken();
+ return matches;
+}
+
+bool CppParser::matchString(QString *s)
+{
+ bool matches = false;
+ s->clear();
+ forever {
+ while (yyTok == Tok_Comment)
+ yyTok = getToken();
+ if (yyTok != Tok_String)
+ return matches;
+ matches = true;
+ *s += yyWord;
+ s->detach();
+ yyTok = getToken();
+ }
+}
+
+STRING(QApplication);
+STRING(QCoreApplication);
+STRING(UnicodeUTF8);
+STRING(DefaultCodec);
+STRING(CodecForTr);
+
+bool CppParser::matchEncoding(bool *utf8)
+{
+ if (yyTok != Tok_Ident)
+ return false;
+ if (yyWord == strQApplication || yyWord == strQCoreApplication) {
+ yyTok = getToken();
+ if (yyTok == Tok_ColonColon)
+ yyTok = getToken();
+ }
+ if (yyWord == strUnicodeUTF8) {
+ *utf8 = true;
+ yyTok = getToken();
+ return true;
+ }
+ if (yyWord == strDefaultCodec || yyWord == strCodecForTr) {
+ *utf8 = false;
+ yyTok = getToken();
+ return true;
+ }
+ return false;
+}
+
+bool CppParser::matchStringOrNull(QString *s)
+{
+ return matchString(s) || match(Tok_Null);
+}
+
+/*
+ * match any expression that can return a number, which can be
+ * 1. Literal number (e.g. '11')
+ * 2. simple identifier (e.g. 'm_count')
+ * 3. simple function call (e.g. 'size()' )
+ * 4. function call on an object (e.g. 'list.size()')
+ * 5. function call on an object (e.g. 'list->size()')
+ *
+ * Other cases:
+ * size(2,4)
+ * list().size()
+ * list(a,b).size(2,4)
+ * etc...
+ */
+bool CppParser::matchExpression()
+{
+ if (match(Tok_Null) || match(Tok_Integer))
+ return true;
+
+ int parenlevel = 0;
+ while (match(Tok_Ident) || parenlevel > 0) {
+ if (yyTok == Tok_RightParen) {
+ if (parenlevel == 0) break;
+ --parenlevel;
+ yyTok = getToken();
+ } else if (yyTok == Tok_LeftParen) {
+ yyTok = getToken();
+ if (yyTok == Tok_RightParen) {
+ yyTok = getToken();
+ } else {
+ ++parenlevel;
+ }
+ } else if (yyTok == Tok_Ident) {
+ continue;
+ } else if (yyTok == Tok_Arrow) {
+ yyTok = getToken();
+ } else if (parenlevel == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+QString CppParser::transcode(const QString &str, bool utf8)
+{
+ static const char tab[] = "abfnrtv";
+ static const char backTab[] = "\a\b\f\n\r\t\v";
+ // This function has to convert back to bytes, as C's \0* sequences work at that level.
+ const QByteArray in = yyForceUtf8 ? str.toUtf8() : tor->codec()->fromUnicode(str);
+ QByteArray out;
+
+ out.reserve(in.length());
+ for (int i = 0; i < in.length();) {
+ uchar c = in[i++];
+ if (c == '\\') {
+ if (i >= in.length())
+ break;
+ c = in[i++];
+
+ if (c == '\n')
+ continue;
+
+ if (c == 'x') {
+ QByteArray hex;
+ while (i < in.length() && isxdigit((c = in[i]))) {
+ hex += c;
+ i++;
+ }
+ out += hex.toUInt(0, 16);
+ } else if (c >= '0' && c < '8') {
+ QByteArray oct;
+ int n = 0;
+ oct += c;
+ while (n < 2 && i < in.length() && (c = in[i]) >= '0' && c < '8') {
+ i++;
+ n++;
+ oct += c;
+ }
+ out += oct.toUInt(0, 8);
+ } else {
+ const char *p = strchr(tab, c);
+ out += !p ? c : backTab[p - tab];
+ }
+ } else {
+ out += c;
+ }
+ }
+ return (utf8 || yyForceUtf8) ? QString::fromUtf8(out.constData(), out.length())
+ : tor->codec()->toUnicode(out);
+}
+
+void CppParser::recordMessage(
+ int line, const QString &context, const QString &text, const QString &comment,
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool utf8, bool plural)
+{
+ TranslatorMessage msg(
+ transcode(context, utf8), transcode(text, utf8), transcode(comment, utf8), QString(),
+ yyFileName, line, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(transcode(extracomment.simplified(), utf8));
+ msg.setId(msgid);
+ msg.setExtras(extra);
+ if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit())
+ msg.setUtf8(true);
+ tor->append(msg);
+}
+
+void CppParser::parse(const QString &initialContext, ConversionData &cd,
+ QSet<QString> &inclusions)
+{
+ if (tor)
+ yyCodecIsUtf8 = (tor->codecName() == "UTF-8");
+
+ namespaces << HashString();
+ functionContext = namespaces;
+ functionContextUnresolved = initialContext;
+
+ parseInternal(cd, inclusions);
+}
+
+void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
+{
+ static QString strColons(QLatin1String("::"));
+
+ QString context;
+ QString text;
+ QString comment;
+ QString extracomment;
+ QString msgid;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
+ QString prefix;
+#ifdef DIAGNOSE_RETRANSLATABILITY
+ QString functionName;
+#endif
+ int line;
+ bool utf8;
+ bool yyTokColonSeen = false; // Start of c'tor's initializer list
+
+ yyWord.reserve(yyInStr.size()); // Rather insane. That's because we do no length checking.
+ yyInPtr = (const ushort *)yyInStr.unicode();
+ yyCh = getChar();
+ yyTok = getToken();
+ while (yyTok != Tok_Eof) {
+ // these are array indexing operations. we ignore them entirely
+ // so they don't confuse our scoping of static initializers.
+ // we enter the loop by either reading a left bracket or by an
+ // #else popping the state.
+ while (yyBracketDepth)
+ yyTok = getToken();
+ //qDebug() << "TOKEN: " << yyTok;
+ switch (yyTok) {
+ case Tok_QuotedInclude: {
+ text = QDir(QFileInfo(yyFileName).absolutePath()).absoluteFilePath(yyWord);
+ text.detach();
+ if (QFileInfo(text).isFile()) {
+ processInclude(text, cd, inclusions);
+ yyTok = getToken();
+ break;
+ }
+ }
+ /* fall through */
+ case Tok_AngledInclude: {
+ QStringList cSources = cd.m_allCSources.values(yyWord);
+ if (!cSources.isEmpty()) {
+ foreach (const QString &cSource, cSources)
+ processInclude(cSource, cd, inclusions);
+ goto incOk;
+ }
+ foreach (const QString &incPath, cd.m_includePath) {
+ text = QDir(incPath).absoluteFilePath(yyWord);
+ text.detach();
+ if (QFileInfo(text).isFile()) {
+ processInclude(text, cd, inclusions);
+ goto incOk;
+ }
+ }
+ incOk:
+ yyTok = getToken();
+ break;
+ }
+ case Tok_friend:
+ yyTok = getToken();
+ // These are forward declarations, so ignore them.
+ if (yyTok == Tok_class)
+ yyTok = getToken();
+ break;
+ case Tok_class:
+ yyTokColonSeen = false;
+ /*
+ Partial support for inlined functions.
+ */
+ yyTok = getToken();
+ if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0) {
+ QList<HashString> quali;
+ HashString fct;
+ do {
+ /*
+ This code should execute only once, but we play
+ safe with impure definitions such as
+ 'class Q_EXPORT QMessageBox', in which case
+ 'QMessageBox' is the class name, not 'Q_EXPORT'.
+ */
+ text = yyWord;
+ text.detach();
+ fct.setValue(text);
+ yyTok = getToken();
+ } while (yyTok == Tok_Ident);
+ while (yyTok == Tok_ColonColon) {
+ yyTok = getToken();
+ if (yyTok != Tok_Ident)
+ break; // Oops ...
+ quali << fct;
+ text = yyWord;
+ text.detach();
+ fct.setValue(text);
+ yyTok = getToken();
+ }
+ while (yyTok == Tok_Comment)
+ yyTok = getToken();
+ if (yyTok == Tok_Colon) {
+ // Skip any token until '{' since we might do things wrong if we find
+ // a '::' token here.
+ do {
+ yyTok = getToken();
+ } while (yyTok != Tok_LeftBrace && yyTok != Tok_Eof);
+ } else {
+ if (yyTok != Tok_LeftBrace) {
+ // Obviously a forward declaration. We skip those, as they
+ // don't create actually usable namespaces.
+ break;
+ }
+ }
+
+ if (!quali.isEmpty()) {
+ // Forward-declared class definitions can be namespaced.
+ NamespaceList nsl;
+ if (!fullyQualify(namespaces, quali, true, &nsl, 0)) {
+ yyMsg() << "Ignoring definition of undeclared qualified class\n";
+ break;
+ }
+ namespaceDepths.push(namespaces.count());
+ namespaces = nsl;
+ } else {
+ namespaceDepths.push(namespaces.count());
+ }
+ enterNamespace(&namespaces, fct);
+
+ functionContext = namespaces;
+ functionContextUnresolved.clear(); // Pointless
+ prospectiveContext.clear();
+ pendingContext.clear();
+
+ yyTok = getToken();
+ }
+ break;
+ case Tok_namespace:
+ yyTokColonSeen = false;
+ yyTok = getToken();
+ if (yyTok == Tok_Ident) {
+ text = yyWord;
+ text.detach();
+ HashString ns = HashString(text);
+ yyTok = getToken();
+ if (yyTok == Tok_LeftBrace) {
+ namespaceDepths.push(namespaces.count());
+ enterNamespace(&namespaces, ns);
+
+ functionContext = namespaces;
+ functionContextUnresolved.clear();
+ prospectiveContext.clear();
+ pendingContext.clear();
+ yyTok = getToken();
+ } else if (yyTok == Tok_Equals) {
+ // e.g. namespace Is = OuterSpace::InnerSpace;
+ QList<HashString> fullName;
+ yyTok = getToken();
+ if (yyTok == Tok_ColonColon)
+ fullName.append(HashString(QString()));
+ while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
+ if (yyTok == Tok_Ident) {
+ text = yyWord;
+ text.detach();
+ fullName.append(HashString(text));
+ }
+ yyTok = getToken();
+ }
+ if (fullName.isEmpty())
+ break;
+ fullName.append(HashString(QString())); // Mark as unresolved
+ modifyNamespace(&namespaces)->aliases[ns] = fullName;
+ }
+ } else if (yyTok == Tok_LeftBrace) {
+ // Anonymous namespace
+ namespaceDepths.push(namespaces.count());
+ yyTok = getToken();
+ }
+ break;
+ case Tok_using:
+ yyTok = getToken();
+ // XXX this should affect only the current scope, not the entire current namespace
+ if (yyTok == Tok_namespace) {
+ QList<HashString> fullName;
+ yyTok = getToken();
+ if (yyTok == Tok_ColonColon)
+ fullName.append(HashString(QString()));
+ while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
+ if (yyTok == Tok_Ident) {
+ text = yyWord;
+ text.detach();
+ fullName.append(HashString(text));
+ }
+ yyTok = getToken();
+ }
+ NamespaceList nsl;
+ if (fullyQualify(namespaces, fullName, false, &nsl, 0))
+ modifyNamespace(&namespaces)->usings << HashStringList(nsl);
+ } else {
+ QList<HashString> fullName;
+ if (yyTok == Tok_ColonColon)
+ fullName.append(HashString(QString()));
+ while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
+ if (yyTok == Tok_Ident) {
+ text = yyWord;
+ text.detach();
+ fullName.append(HashString(text));
+ }
+ yyTok = getToken();
+ }
+ if (fullName.isEmpty())
+ break;
+ // using-declarations cannot rename classes, so the last element of
+ // fullName is already the resolved name we actually want.
+ // As we do no resolution here, we'll collect useless usings of data
+ // members and methods as well. This is no big deal.
+ HashString &ns = fullName.last();
+ fullName.append(HashString(QString())); // Mark as unresolved
+ modifyNamespace(&namespaces)->aliases[ns] = fullName;
+ }
+ break;
+ case Tok_tr:
+ case Tok_trUtf8:
+ if (!tor)
+ goto case_default;
+ if (!sourcetext.isEmpty())
+ yyMsg() << qPrintable(LU::tr("//% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n"));
+ utf8 = (yyTok == Tok_trUtf8);
+ line = yyLineNo;
+ yyTok = getToken();
+ if (match(Tok_LeftParen) && matchString(&text) && !text.isEmpty()) {
+ comment.clear();
+ bool plural = false;
+
+ if (match(Tok_RightParen)) {
+ // no comment
+ } else if (match(Tok_Comma) && matchStringOrNull(&comment)) { //comment
+ if (match(Tok_RightParen)) {
+ // ok,
+ } else if (match(Tok_Comma)) {
+ plural = true;
+ }
+ }
+ if (!pendingContext.isEmpty() && !prefix.startsWith(strColons)) {
+ QStringList unresolved;
+ if (!fullyQualify(namespaces, pendingContext, true, &functionContext, &unresolved)) {
+ functionContextUnresolved = unresolved.join(strColons);
+ yyMsg() << qPrintable(LU::tr("Qualifying with unknown namespace/class %1::%2\n")
+ .arg(stringifyNamespace(functionContext)).arg(unresolved.first()));
+ }
+ pendingContext.clear();
+ }
+ if (prefix.isEmpty()) {
+ if (functionContextUnresolved.isEmpty()) {
+ int idx = functionContext.length();
+ if (idx < 2) {
+ yyMsg() << qPrintable(LU::tr("tr() cannot be called without context\n"));
+ break;
+ }
+ Namespace *fctx;
+ while (!(fctx = findNamespace(functionContext, idx)->classDef)->hasTrFunctions) {
+ if (idx == 1) {
+ context = stringifyNamespace(functionContext);
+ fctx = findNamespace(functionContext)->classDef;
+ if (!fctx->complained) {
+ yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n")
+ .arg(context));
+ fctx->complained = true;
+ }
+ goto gotctx;
+ }
+ --idx;
+ }
+ if (fctx->trQualification.isEmpty()) {
+ context.clear();
+ for (int i = 1;;) {
+ context += functionContext.at(i).value();
+ if (++i == idx)
+ break;
+ context += strColons;
+ }
+ fctx->trQualification = context;
+ } else {
+ context = fctx->trQualification;
+ }
+ } else {
+ context = (stringListifyNamespace(functionContext)
+ << functionContextUnresolved).join(strColons);
+ }
+ } else {
+#ifdef DIAGNOSE_RETRANSLATABILITY
+ int last = prefix.lastIndexOf(strColons);
+ QString className = prefix.mid(last == -1 ? 0 : last + 2);
+ if (!className.isEmpty() && className == functionName) {
+ yyMsg() << qPrintable(LU::tr("It is not recommended to call tr() from within a constructor '%1::%2'\n")
+ .arg(className).arg(functionName));
+ }
+#endif
+ prefix.chop(2);
+ NamespaceList nsl;
+ QStringList unresolved;
+ if (fullyQualify(functionContext, prefix, false, &nsl, &unresolved)) {
+ Namespace *fctx = findNamespace(nsl)->classDef;
+ if (fctx->trQualification.isEmpty()) {
+ context = stringifyNamespace(nsl);
+ fctx->trQualification = context;
+ } else {
+ context = fctx->trQualification;
+ }
+ if (!fctx->hasTrFunctions && !fctx->complained) {
+ yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n").arg(context));
+ fctx->complained = true;
+ }
+ } else {
+ context = (stringListifyNamespace(nsl) + unresolved).join(strColons);
+ }
+ prefix.clear();
+ }
+
+ gotctx:
+ recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
+ }
+ sourcetext.clear(); // Will have warned about that already
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ break;
+ case Tok_translateUtf8:
+ case Tok_translate:
+ if (!tor)
+ goto case_default;
+ if (!sourcetext.isEmpty())
+ yyMsg() << qPrintable(LU::tr("//% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n"));
+ utf8 = (yyTok == Tok_translateUtf8);
+ line = yyLineNo;
+ yyTok = getToken();
+ if (match(Tok_LeftParen)
+ && matchString(&context)
+ && match(Tok_Comma)
+ && matchString(&text) && !text.isEmpty())
+ {
+ comment.clear();
+ bool plural = false;
+ if (!match(Tok_RightParen)) {
+ // look for comment
+ if (match(Tok_Comma) && matchStringOrNull(&comment)) {
+ if (!match(Tok_RightParen)) {
+ // look for encoding
+ if (match(Tok_Comma)) {
+ if (matchEncoding(&utf8)) {
+ if (!match(Tok_RightParen)) {
+ // look for the plural quantifier,
+ // this can be a number, an identifier or
+ // a function call,
+ // so for simplicity we mark it as plural if
+ // we know we have a comma instead of an
+ // right parentheses.
+ plural = match(Tok_Comma);
+ }
+ } else {
+ // This can be a QTranslator::translate("context",
+ // "source", "comment", n) plural translation
+ if (matchExpression() && match(Tok_RightParen)) {
+ plural = true;
+ } else {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
+ }
+ sourcetext.clear(); // Will have warned about that already
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ break;
+ case Tok_trid:
+ if (!tor)
+ goto case_default;
+ if (!msgid.isEmpty())
+ yyMsg() << qPrintable(LU::tr("//= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n"));
+ //utf8 = false; // Maybe use //%% or something like that
+ line = yyLineNo;
+ yyTok = getToken();
+ if (match(Tok_LeftParen) && matchString(&msgid) && !msgid.isEmpty()) {
+ bool plural = match(Tok_Comma);
+ recordMessage(line, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, false, plural);
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ break;
+ case Tok_Q_DECLARE_TR_FUNCTIONS:
+ if (getMacroArgs()) {
+ Namespace *ns = modifyNamespace(&namespaces);
+ ns->hasTrFunctions = true;
+ ns->trQualification = yyWord;
+ ns->trQualification.detach();
+ }
+ yyTok = getToken();
+ break;
+ case Tok_Q_OBJECT:
+ modifyNamespace(&namespaces)->hasTrFunctions = true;
+ yyTok = getToken();
+ break;
+ case Tok_Ident:
+ prefix += yyWord;
+ prefix.detach();
+ yyTok = getToken();
+ if (yyTok != Tok_ColonColon) {
+ prefix.clear();
+ if (yyTok == Tok_Ident && !yyParenDepth)
+ prospectiveContext.clear();
+ }
+ break;
+ case Tok_Comment: {
+ if (!tor)
+ goto case_default;
+ const QChar *ptr = yyWord.unicode();
+ if (*ptr == QLatin1Char(':') && ptr[1].isSpace()) {
+ yyWord.remove(0, 2);
+ extracomment += yyWord;
+ extracomment.detach();
+ } else if (*ptr == QLatin1Char('=') && ptr[1].isSpace()) {
+ yyWord.remove(0, 2);
+ msgid = yyWord.simplified();
+ msgid.detach();
+ } else if (*ptr == QLatin1Char('~') && ptr[1].isSpace()) {
+ yyWord.remove(0, 2);
+ text = yyWord.trimmed();
+ int k = text.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ extra.insert(text.left(k), text.mid(k + 1).trimmed());
+ text.clear();
+ } else if (*ptr == QLatin1Char('%') && ptr[1].isSpace()) {
+ sourcetext.reserve(sourcetext.length() + yyWord.length() - 2);
+ ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length();
+ int p = 2, c;
+ forever {
+ if (p >= yyWord.length())
+ break;
+ c = yyWord.unicode()[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"') {
+ yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n"));
+ break;
+ }
+ forever {
+ if (p >= yyWord.length()) {
+ whoops:
+ yyMsg() << qPrintable(LU::tr("Unterminated meta string\n"));
+ break;
+ }
+ c = yyWord.unicode()[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= yyWord.length())
+ goto whoops;
+ c = yyWord.unicode()[p++].unicode();
+ if (c == '\n')
+ goto whoops;
+ *ptr++ = '\\';
+ }
+ *ptr++ = c;
+ }
+ }
+ sourcetext.resize(ptr - (ushort *)sourcetext.data());
+ } else {
+ const ushort *uc = (const ushort *)yyWord.unicode(); // Is zero-terminated
+ int idx = 0;
+ ushort c;
+ while ((c = uc[idx]) == ' ' || c == '\t' || c == '\n')
+ ++idx;
+ if (!memcmp(uc + idx, MagicComment.unicode(), MagicComment.length() * 2)) {
+ idx += MagicComment.length();
+ comment = QString::fromRawData(yyWord.unicode() + idx,
+ yyWord.length() - idx).simplified();
+ int k = comment.indexOf(QLatin1Char(' '));
+ if (k == -1) {
+ context = comment;
+ } else {
+ context = comment.left(k);
+ comment.remove(0, k + 1);
+ TranslatorMessage msg(
+ transcode(context, false), QString(),
+ transcode(comment, false), QString(),
+ yyFileName, yyLineNo, QStringList(),
+ TranslatorMessage::Finished, false);
+ msg.setExtraComment(transcode(extracomment.simplified(), false));
+ extracomment.clear();
+ tor->append(msg);
+ tor->setExtras(extra);
+ extra.clear();
+ }
+ }
+ }
+ yyTok = getToken();
+ break;
+ }
+ case Tok_Arrow:
+ yyTok = getToken();
+ if (yyTok == Tok_tr || yyTok == Tok_trUtf8)
+ yyMsg() << qPrintable(LU::tr("Cannot invoke tr() like this\n"));
+ break;
+ case Tok_ColonColon:
+ if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0 && !yyTokColonSeen)
+ prospectiveContext = prefix;
+ prefix += strColons;
+ yyTok = getToken();
+#ifdef DIAGNOSE_RETRANSLATABILITY
+ if (yyTok == Tok_Ident && yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0) {
+ functionName = yyWord;
+ functionName.detach();
+ }
+#endif
+ break;
+ case Tok_RightBrace:
+ if (yyBraceDepth + 1 == namespaceDepths.count()) // class or namespace
+ truncateNamespaces(&namespaces, namespaceDepths.pop());
+ if (yyBraceDepth == namespaceDepths.count()) {
+ // function, class or namespace
+ if (!yyBraceDepth && !directInclude) {
+ truncateNamespaces(&functionContext, 1);
+ functionContextUnresolved = cd.m_defaultContext;
+ } else {
+ functionContext = namespaces;
+ functionContextUnresolved.clear();
+ }
+ pendingContext.clear();
+ }
+ // fallthrough
+ case Tok_Semicolon:
+ prospectiveContext.clear();
+ prefix.clear();
+ if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) {
+ yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n"));
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
+ yyTokColonSeen = false;
+ yyTok = getToken();
+ break;
+ case Tok_Colon:
+ if (!prospectiveContext.isEmpty()
+ && yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0)
+ pendingContext = prospectiveContext;
+ yyTokColonSeen = true;
+ yyTok = getToken();
+ break;
+ case Tok_LeftBrace:
+ if (!prospectiveContext.isEmpty()
+ && yyBraceDepth == namespaceDepths.count() + 1 && yyParenDepth == 0)
+ pendingContext = prospectiveContext;
+ // fallthrough
+ case Tok_LeftParen:
+ case Tok_RightParen:
+ yyTokColonSeen = false;
+ yyTok = getToken();
+ break;
+ default:
+ if (!yyParenDepth)
+ prospectiveContext.clear();
+ // fallthrough
+ case Tok_Equals: // for static initializers; other cases make no difference
+ case Tok_RightBracket: // ignoring indexing; same reason
+ case_default:
+ yyTok = getToken();
+ break;
+ }
+ }
+
+ if (yyBraceDepth != 0)
+ yyMsg(yyBraceLineNo)
+ << qPrintable(LU::tr("Unbalanced opening brace in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
+ else if (yyParenDepth != 0)
+ yyMsg(yyParenLineNo)
+ << qPrintable(LU::tr("Unbalanced opening parenthesis in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
+ else if (yyBracketDepth != 0)
+ yyMsg(yyBracketLineNo)
+ << qPrintable(LU::tr("Unbalanced opening bracket in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
+}
+
+const ParseResults *CppParser::recordResults(bool isHeader)
+{
+ if (tor) {
+ if (tor->messageCount()) {
+ CppFiles::setTranslator(yyFileName, tor);
+ } else {
+ delete tor;
+ tor = 0;
+ }
+ }
+ if (isHeader) {
+ const ParseResults *pr;
+ if (!tor && results->includes.count() == 1
+ && results->rootNamespace.children.isEmpty()
+ && results->rootNamespace.aliases.isEmpty()
+ && results->rootNamespace.usings.isEmpty()) {
+ // This is a forwarding header. Slash it.
+ pr = *results->includes.begin();
+ delete results;
+ } else {
+ results->fileId = nextFileId++;
+ pr = results;
+ }
+ CppFiles::setResults(yyFileName, pr);
+ return pr;
+ } else {
+ delete results;
+ return 0;
+ }
+}
+
+/*
+ Fetches tr() calls in C++ code in UI files (inside "<function>"
+ tag). This mechanism is obsolete.
+*/
+void fetchtrInlinedCpp(const QString &in, Translator &translator, const QString &context)
+{
+ CppParser parser;
+ parser.setInput(in);
+ ConversionData cd;
+ QSet<QString> inclusions;
+ parser.setTranslator(&translator);
+ parser.parse(context, cd, inclusions);
+ parser.deleteResults();
+}
+
+void loadCPP(Translator &translator, const QStringList &filenames, ConversionData &cd)
+{
+ QByteArray codecName = cd.m_codecForSource.isEmpty()
+ ? translator.codecName() : cd.m_codecForSource;
+ QTextCodec *codec = QTextCodec::codecForName(codecName);
+
+ foreach (const QString &filename, filenames) {
+ if (CppFiles::getResults(filename) || CppFiles::isBlacklisted(filename))
+ continue;
+
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
+ continue;
+ }
+
+ CppParser parser;
+ QTextStream ts(&file);
+ ts.setCodec(codec);
+ ts.setAutoDetectUnicode(true);
+ parser.setInput(ts, filename);
+ if (cd.m_outputCodec.isEmpty() && ts.codec()->name() == "UTF-16")
+ translator.setCodecName("System");
+ Translator *tor = new Translator;
+ tor->setCodecName(translator.codecName());
+ parser.setTranslator(tor);
+ QSet<QString> inclusions;
+ parser.parse(cd.m_defaultContext, cd, inclusions);
+ parser.recordResults(isHeader(filename));
+ }
+
+ foreach (const QString &filename, filenames)
+ if (!CppFiles::isBlacklisted(filename))
+ if (const Translator *tor = CppFiles::getTranslator(filename))
+ foreach (const TranslatorMessage &msg, tor->messages())
+ translator.extend(msg);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/java.cpp b/src/linguist/lupdate/java.cpp
new file mode 100644
index 000000000..bc3649912
--- /dev/null
+++ b/src/linguist/lupdate/java.cpp
@@ -0,0 +1,645 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lupdate.h"
+
+#include <translator.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QRegExp>
+#include <QtCore/QStack>
+#include <QtCore/QStack>
+#include <QtCore/QString>
+#include <QtCore/QTextCodec>
+#include <QtCore/QCoreApplication>
+
+#include <iostream>
+
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+enum { Tok_Eof, Tok_class, Tok_return, Tok_tr,
+ Tok_translate, Tok_Ident, Tok_Package,
+ Tok_Comment, Tok_String, Tok_Colon, Tok_Dot,
+ Tok_LeftBrace, Tok_RightBrace, Tok_LeftParen,
+ Tok_RightParen, Tok_Comma, Tok_Semicolon,
+ Tok_Integer, Tok_Plus, Tok_PlusPlus, Tok_PlusEq, Tok_null };
+
+class Scope
+{
+ public:
+ QString name;
+ enum Type {Clazz, Function, Other} type;
+ int line;
+
+ Scope(const QString & name, Type type, int line) :
+ name(name),
+ type(type),
+ line(line)
+ {}
+
+ ~Scope()
+ {}
+};
+
+/*
+ The tokenizer maintains the following global variables. The names
+ should be self-explanatory.
+*/
+
+static QString yyFileName;
+static QChar yyCh;
+static QString yyIdent;
+static QString yyComment;
+static QString yyString;
+
+
+static qlonglong yyInteger;
+static int yyParenDepth;
+static int yyLineNo;
+static int yyCurLineNo;
+static int yyParenLineNo;
+static int yyTok;
+
+// the string to read from and current position in the string
+static QString yyInStr;
+static int yyInPos;
+
+// The parser maintains the following global variables.
+static QString yyPackage;
+static QStack<Scope*> yyScope;
+static QString yyDefaultContext;
+
+std::ostream &yyMsg(int line = 0)
+{
+ return std::cerr << qPrintable(yyFileName) << ':' << (line ? line : yyLineNo) << ": ";
+}
+
+static QChar getChar()
+{
+ if (yyInPos >= yyInStr.size())
+ return EOF;
+ QChar c = yyInStr[yyInPos++];
+ if (c.unicode() == '\n')
+ ++yyCurLineNo;
+ return c.unicode();
+}
+
+static int getToken()
+{
+ const char tab[] = "bfnrt\"\'\\";
+ const char backTab[] = "\b\f\n\r\t\"\'\\";
+
+ yyIdent.clear();
+ yyComment.clear();
+ yyString.clear();
+
+ while ( yyCh != EOF ) {
+ yyLineNo = yyCurLineNo;
+
+ if ( yyCh.isLetter() || yyCh.toLatin1() == '_' ) {
+ do {
+ yyIdent.append(yyCh);
+ yyCh = getChar();
+ } while ( yyCh.isLetterOrNumber() || yyCh.toLatin1() == '_' );
+
+ if (yyTok != Tok_Dot) {
+ switch ( yyIdent.at(0).toLatin1() ) {
+ case 'r':
+ if ( yyIdent == QLatin1String("return") )
+ return Tok_return;
+ break;
+ case 'c':
+ if ( yyIdent == QLatin1String("class") )
+ return Tok_class;
+ break;
+ case 'n':
+ if ( yyIdent == QLatin1String("null") )
+ return Tok_null;
+ break;
+ }
+ }
+ switch ( yyIdent.at(0).toLatin1() ) {
+ case 'T':
+ // TR() for when all else fails
+ if ( yyIdent == QLatin1String("TR") )
+ return Tok_tr;
+ break;
+ case 'p':
+ if( yyIdent == QLatin1String("package") )
+ return Tok_Package;
+ break;
+ case 't':
+ if ( yyIdent == QLatin1String("tr") )
+ return Tok_tr;
+ if ( yyIdent == QLatin1String("translate") )
+ return Tok_translate;
+ }
+ return Tok_Ident;
+ } else {
+ switch ( yyCh.toLatin1() ) {
+
+ case '/':
+ yyCh = getChar();
+ if ( yyCh == QLatin1Char('/') ) {
+ do {
+ yyCh = getChar();
+ if (yyCh == EOF)
+ break;
+ yyComment.append(yyCh);
+ } while (yyCh != QLatin1Char('\n'));
+ return Tok_Comment;
+
+ } else if ( yyCh == QLatin1Char('*') ) {
+ bool metAster = false;
+ bool metAsterSlash = false;
+
+ while ( !metAsterSlash ) {
+ yyCh = getChar();
+ if ( yyCh == EOF ) {
+ yyMsg() << qPrintable(LU::tr("Unterminated Java comment.\n"));
+ return Tok_Comment;
+ }
+
+ yyComment.append( yyCh );
+
+ if ( yyCh == QLatin1Char('*') )
+ metAster = true;
+ else if ( metAster && yyCh == QLatin1Char('/') )
+ metAsterSlash = true;
+ else
+ metAster = false;
+ }
+ yyComment.chop(2);
+ yyCh = getChar();
+
+ return Tok_Comment;
+ }
+ break;
+ case '"':
+ yyCh = getChar();
+
+ while ( yyCh != EOF && yyCh != QLatin1Char('\n') && yyCh != QLatin1Char('"') ) {
+ if ( yyCh == QLatin1Char('\\') ) {
+ yyCh = getChar();
+ if ( yyCh == QLatin1Char('u') ) {
+ yyCh = getChar();
+ uint unicode(0);
+ for (int i = 4; i > 0; --i) {
+ unicode = unicode << 4;
+ if( yyCh.isDigit() ) {
+ unicode += yyCh.digitValue();
+ }
+ else {
+ int sub(yyCh.toLower().toAscii() - 87);
+ if( sub > 15 || sub < 10) {
+ yyMsg() << qPrintable(LU::tr("Invalid Unicode value.\n"));
+ break;
+ }
+ unicode += sub;
+ }
+ yyCh = getChar();
+ }
+ yyString.append(QChar(unicode));
+ }
+ else if ( yyCh == QLatin1Char('\n') ) {
+ yyCh = getChar();
+ }
+ else {
+ yyString.append( QLatin1Char(backTab[strchr( tab, yyCh.toAscii() ) - tab]) );
+ yyCh = getChar();
+ }
+ } else {
+ yyString.append(yyCh);
+ yyCh = getChar();
+ }
+ }
+
+ if ( yyCh != QLatin1Char('"') )
+ yyMsg() << qPrintable(LU::tr("Unterminated string.\n"));
+
+ yyCh = getChar();
+
+ return Tok_String;
+
+ case ':':
+ yyCh = getChar();
+ return Tok_Colon;
+ case '\'':
+ yyCh = getChar();
+
+ if ( yyCh == QLatin1Char('\\') )
+ yyCh = getChar();
+ do {
+ yyCh = getChar();
+ } while ( yyCh != EOF && yyCh != QLatin1Char('\'') );
+ yyCh = getChar();
+ break;
+ case '{':
+ yyCh = getChar();
+ return Tok_LeftBrace;
+ case '}':
+ yyCh = getChar();
+ return Tok_RightBrace;
+ case '(':
+ if (yyParenDepth == 0)
+ yyParenLineNo = yyCurLineNo;
+ yyParenDepth++;
+ yyCh = getChar();
+ return Tok_LeftParen;
+ case ')':
+ if (yyParenDepth == 0)
+ yyParenLineNo = yyCurLineNo;
+ yyParenDepth--;
+ yyCh = getChar();
+ return Tok_RightParen;
+ case ',':
+ yyCh = getChar();
+ return Tok_Comma;
+ case '.':
+ yyCh = getChar();
+ return Tok_Dot;
+ case ';':
+ yyCh = getChar();
+ return Tok_Semicolon;
+ case '+':
+ yyCh = getChar();
+ if (yyCh == QLatin1Char('+')) {
+ yyCh = getChar();
+ return Tok_PlusPlus;
+ }
+ if( yyCh == QLatin1Char('=') ){
+ yyCh = getChar();
+ return Tok_PlusEq;
+ }
+ return Tok_Plus;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ QByteArray ba;
+ ba += yyCh.toLatin1();
+ yyCh = getChar();
+ bool hex = yyCh == QLatin1Char('x');
+ if ( hex ) {
+ ba += yyCh.toLatin1();
+ yyCh = getChar();
+ }
+ while ( hex ? isxdigit(yyCh.toLatin1()) : yyCh.isDigit() ) {
+ ba += yyCh.toLatin1();
+ yyCh = getChar();
+ }
+ bool ok;
+ yyInteger = ba.toLongLong(&ok);
+ if (ok) return Tok_Integer;
+ break;
+ }
+ default:
+ yyCh = getChar();
+ }
+ }
+ }
+ return Tok_Eof;
+}
+
+static bool match( int t )
+{
+ bool matches = ( yyTok == t );
+ if ( matches )
+ yyTok = getToken();
+ return matches;
+}
+
+static bool matchString( QString &s )
+{
+ if ( yyTok != Tok_String )
+ return false;
+
+ s = yyString;
+ yyTok = getToken();
+ while ( yyTok == Tok_Plus ) {
+ yyTok = getToken();
+ if (yyTok == Tok_String)
+ s += yyString;
+ else {
+ yyMsg() << qPrintable(LU::tr(
+ "String used in translation can contain only literals"
+ " concatenated with other literals, not expressions or numbers.\n"));
+ return false;
+ }
+ yyTok = getToken();
+ }
+ return true;
+}
+
+static bool matchStringOrNull(QString &s)
+{
+ bool matches = matchString(s);
+ if (!matches) {
+ matches = (yyTok == Tok_null);
+ if (matches)
+ yyTok = getToken();
+ }
+ return matches;
+}
+
+/*
+ * match any expression that can return a number, which can be
+ * 1. Literal number (e.g. '11')
+ * 2. simple identifier (e.g. 'm_count')
+ * 3. simple function call (e.g. 'size()' )
+ * 4. function call on an object (e.g. 'list.size()')
+ * 5. function call on an object (e.g. 'list->size()')
+ *
+ * Other cases:
+ * size(2,4)
+ * list().size()
+ * list(a,b).size(2,4)
+ * etc...
+ */
+static bool matchExpression()
+{
+ if (match(Tok_Integer)) {
+ return true;
+ }
+
+ int parenlevel = 0;
+ while (match(Tok_Ident) || parenlevel > 0) {
+ if (yyTok == Tok_RightParen) {
+ if (parenlevel == 0) break;
+ --parenlevel;
+ yyTok = getToken();
+ } else if (yyTok == Tok_LeftParen) {
+ yyTok = getToken();
+ if (yyTok == Tok_RightParen) {
+ yyTok = getToken();
+ } else {
+ ++parenlevel;
+ }
+ } else if (yyTok == Tok_Ident) {
+ continue;
+ } else if (parenlevel == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static const QString context()
+{
+ QString context(yyPackage);
+ bool innerClass = false;
+ for (int i = 0; i < yyScope.size(); ++i) {
+ if (yyScope.at(i)->type == Scope::Clazz) {
+ if (innerClass)
+ context.append(QLatin1String("$"));
+ else
+ context.append(QLatin1String("."));
+
+ context.append(yyScope.at(i)->name);
+ innerClass = true;
+ }
+ }
+ return context.isEmpty() ? yyDefaultContext : context;
+}
+
+static void recordMessage(
+ Translator *tor, const QString &context, const QString &text, const QString &comment,
+ const QString &extracomment, bool plural)
+{
+ TranslatorMessage msg(
+ context, text, comment, QString(),
+ yyFileName, yyLineNo, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ tor->extend(msg);
+}
+
+static void parse( Translator *tor )
+{
+ QString text;
+ QString com;
+ QString extracomment;
+
+ yyCh = getChar();
+
+ yyTok = getToken();
+ while ( yyTok != Tok_Eof ) {
+ switch ( yyTok ) {
+ case Tok_class:
+ yyTok = getToken();
+ if(yyTok == Tok_Ident) {
+ yyScope.push(new Scope(yyIdent, Scope::Clazz, yyLineNo));
+ }
+ else {
+ yyMsg() << qPrintable(LU::tr("'class' must be followed by a class name.\n"));
+ break;
+ }
+ while (!match(Tok_LeftBrace)) {
+ yyTok = getToken();
+ }
+ break;
+
+ case Tok_tr:
+ yyTok = getToken();
+ if ( match(Tok_LeftParen) && matchString(text) ) {
+ com.clear();
+ bool plural = false;
+
+ if ( match(Tok_RightParen) ) {
+ // no comment
+ } else if (match(Tok_Comma) && matchStringOrNull(com)) { //comment
+ if ( match(Tok_RightParen)) {
+ // ok,
+ } else if (match(Tok_Comma)) {
+ plural = true;
+ }
+ }
+ if (!text.isEmpty())
+ recordMessage(tor, context(), text, com, extracomment, plural);
+ }
+ break;
+ case Tok_translate:
+ {
+ QString contextOverride;
+ yyTok = getToken();
+ if ( match(Tok_LeftParen) &&
+ matchString(contextOverride) &&
+ match(Tok_Comma) &&
+ matchString(text) ) {
+
+ com.clear();
+ bool plural = false;
+ if (!match(Tok_RightParen)) {
+ // look for comment
+ if ( match(Tok_Comma) && matchStringOrNull(com)) {
+ if (!match(Tok_RightParen)) {
+ if (match(Tok_Comma) && matchExpression() && match(Tok_RightParen)) {
+ plural = true;
+ } else {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ if (!text.isEmpty())
+ recordMessage(tor, contextOverride, text, com, extracomment, plural);
+ }
+ }
+ break;
+
+ case Tok_Ident:
+ yyTok = getToken();
+ break;
+
+ case Tok_Comment:
+ if (yyComment.startsWith(QLatin1Char(':'))) {
+ yyComment.remove(0, 1);
+ extracomment.append(yyComment);
+ }
+ yyTok = getToken();
+ break;
+
+ case Tok_RightBrace:
+ if ( yyScope.isEmpty() ) {
+ yyMsg() << qPrintable(LU::tr("Excess closing brace.\n"));
+ }
+ else
+ delete (yyScope.pop());
+ extracomment.clear();
+ yyTok = getToken();
+ break;
+
+ case Tok_LeftBrace:
+ yyScope.push(new Scope(QString(), Scope::Other, yyLineNo));
+ yyTok = getToken();
+ break;
+
+ case Tok_Semicolon:
+ extracomment.clear();
+ yyTok = getToken();
+ break;
+
+ case Tok_Package:
+ yyTok = getToken();
+ while(!match(Tok_Semicolon)) {
+ switch(yyTok) {
+ case Tok_Ident:
+ yyPackage.append(yyIdent);
+ break;
+ case Tok_Dot:
+ yyPackage.append(QLatin1String("."));
+ break;
+ default:
+ yyMsg() << qPrintable(LU::tr("'package' must be followed by package name.\n"));
+ break;
+ }
+ yyTok = getToken();
+ }
+ break;
+
+ default:
+ yyTok = getToken();
+ }
+ }
+
+ if ( !yyScope.isEmpty() )
+ yyMsg(yyScope.top()->line) << qPrintable(LU::tr("Unbalanced opening brace.\n"));
+ else if ( yyParenDepth != 0 )
+ yyMsg(yyParenLineNo) << qPrintable(LU::tr("Unbalanced opening parenthesis.\n"));
+}
+
+
+bool loadJava(Translator &translator, const QString &filename, ConversionData &cd)
+{
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
+ return false;
+ }
+
+ yyDefaultContext = cd.m_defaultContext;
+ yyInPos = -1;
+ yyFileName = filename;
+ yyPackage.clear();
+ yyScope.clear();
+ yyTok = -1;
+ yyParenDepth = 0;
+ yyCurLineNo = 0;
+ yyParenLineNo = 1;
+
+ QTextStream ts(&file);
+ QByteArray codecName;
+ if (!cd.m_codecForSource.isEmpty())
+ codecName = cd.m_codecForSource;
+ else
+ codecName = translator.codecName(); // Just because it should be latin1 already
+ ts.setCodec(QTextCodec::codecForName(codecName));
+ ts.setAutoDetectUnicode(true);
+ yyInStr = ts.readAll();
+ yyInPos = 0;
+ yyFileName = filename;
+ yyCurLineNo = 1;
+ yyParenLineNo = 1;
+
+ parse(&translator);
+
+ // Java uses UTF-16 internally and Jambi makes UTF-8 for tr() purposes of it.
+ translator.setCodecName("UTF-8");
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/lupdate.1 b/src/linguist/lupdate/lupdate.1
new file mode 100644
index 000000000..80b7429b3
--- /dev/null
+++ b/src/linguist/lupdate/lupdate.1
@@ -0,0 +1,153 @@
+.TH lupdate 1 "18 October 2001" "Nokia Corporation and/or its subsidiary(-ies)" \" -*- nroff -*-
+.\"
+.\" Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+.\" All rights reserved.
+.\" Contact: Nokia Corporation (qt-info@nokia.com)
+.\"
+.\" This file is part of the QtGui module of the Qt Toolkit.
+.\"
+.\" $QT_BEGIN_LICENSE:LGPL$
+.\" No Commercial Usage
+.\" This file contains pre-release code and may not be distributed.
+.\" You may use this file in accordance with the terms and conditions
+.\" contained in the Technology Preview License Agreement accompanying
+.\" this package.
+.\"
+.\" GNU Lesser General Public License Usage
+.\" Alternatively, this file may be used under the terms of the GNU Lesser
+.\" General Public License version 2.1 as published by the Free Software
+.\" Foundation and appearing in the file LICENSE.LGPL included in the
+.\" packaging of this file. Please review the following information to
+.\" ensure the GNU Lesser General Public License version 2.1 requirements
+.\" will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+.\"
+.\" In addition, as a special exception, Nokia gives you certain additional
+.\" rights. These rights are described in the Nokia Qt LGPL Exception
+.\" version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+.\"
+.\" If you have questions regarding the use of this file, please contact
+.\" Nokia at qt-info@nokia.com.
+.\"
+.\"
+.\"
+.\"
+.\"
+.\"
+.\"
+.\"
+.\" $QT_END_LICENSE$
+.\"
+.SH NAME
+lupdate \- update Qt Linguist translation files
+.SH SYNOPSIS
+.B lupdate
+.RI "[ " options " ] " project-file
+.br
+.B lupdate
+.RI "[ " options " ] " source-files " -ts " ts-files
+.SH DESCRIPTION
+This page documents the
+.B Qt Linguist Update
+tool for the Qt GUI toolkit.
+.B Lupdate
+reads a qmake/tmake project file (.pro file), finds the translatable
+strings in the specified source, header and interface files, and
+updates the translation files (TS files) specified in it. The
+translation files are given to the translator who uses
+.B Qt Linguist
+to read the files and insert the translations.
+.PP
+The TS file format is a simple human-readable XML format that can be
+used with version control systems if required.
+.PP
+.SH OPTIONS
+.TP
+.I "-disable-heuristic {sametext|similartext|number}"
+Disable the named merge heuristic. Can be specified multiple times.
+.TP
+.I "-extensions <ext>[,<ext>...]"
+Process files with the given extensions only.
+The extension list must be separated with commas, not with whitespace.
+Default: 'ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx'.
+.TP
+.I "-help"
+Display the usage and exit.
+.TP
+.I "-locations {absolute|relative|none}"
+Specify/override how source code references are saved in TS files.
+Default is absolute.
+.TP
+.I "-no-obsolete"
+Drop all obsolete strings.
+.TP
+.I "-no-recursive"
+Do not recursively scan the following directories.
+.TP
+.I "-no-sort"
+Do not sort contexts in TS files.
+.TP
+.I "-pluralonly"
+Only include plural form messages.
+.TP
+.I "-pro <filename>"
+Name of a .pro file. Useful for files with .pro
+file syntax but different file suffix
+.TP
+.I "-recursive"
+Recursively scan the following directories.
+.TP
+.I "-silent"
+Do not explain what is being done.
+.TP
+.I "-source-language <language>[_<region>]"
+Specify/override the language of the source strings. Defaults to
+POSIX if not specified and the file does not name it yet.
+.TP
+.I "-target-language <language>[_<region>]"
+Specify/override the language of the translation.
+The target language is guessed from the file name if this option
+is not specified and the file contents name no language yet.
+.I "-version"
+Display the version of
+.B lupdate
+and exit.
+.SH USAGE
+Here is an example .pro file that can be given to
+.B lupdate:
+.PP
+.in +4
+.nf
+HEADERS = funnydialog.h \\
+ wackywidget.h
+SOURCES = funnydialog.cpp \\
+ main.cpp \\
+ wackywidget.cpp
+FORMS = fancybox.ui
+TRANSLATIONS = gnomovision_dk.ts \\
+ gnomovision_fi.ts \\
+ gnomovision_no.ts \\
+ gnomovision_se.ts
+.fi
+.in -4
+.PP
+When running
+.B lupdate
+on this project file, the translatable strings in all the files
+listed in the HEADERS, SOURCES and FORMS entries will be put in
+the translation files listed in the TRANSLATIONS entry. Previous
+translations will be reused as far as possible, and translated
+strings that have vanished from the source files are marked obsolete.
+.PP
+.B lupdate
+can also be invoked with a list of C++ source files, UI files
+and TS files:
+.PP
+.in +4
+.nf
+lupdate *.cpp *.h *.ui -ts gnomovision_dk.ts
+.fi
+.in -4
+.SH "SEE ALSO"
+.BR lrelease (1)
+and
+.BR http://qt.nokia.com/doc/i18n.html
diff --git a/src/linguist/lupdate/lupdate.exe.manifest b/src/linguist/lupdate/lupdate.exe.manifest
new file mode 100644
index 000000000..e0b2f734a
--- /dev/null
+++ b/src/linguist/lupdate/lupdate.exe.manifest
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
+ manifestVersion="1.0">
+ <!-- Make sure Vista UAC does not believe lupdate is an installer -->
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel
+ level="asInvoker"
+ uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly> \ No newline at end of file
diff --git a/src/linguist/lupdate/lupdate.h b/src/linguist/lupdate/lupdate.h
new file mode 100644
index 000000000..e8d84d85e
--- /dev/null
+++ b/src/linguist/lupdate/lupdate.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LUPDATE_H
+#define LUPDATE_H
+
+#include "qglobal.h"
+
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+
+class ConversionData;
+class QString;
+class QStringList;
+class Translator;
+class TranslatorMessage;
+
+enum UpdateOption {
+ Verbose = 1,
+ NoObsolete = 2,
+ PluralOnly = 4,
+ NoSort = 8,
+ HeuristicSameText = 16,
+ HeuristicSimilarText = 32,
+ HeuristicNumber = 64,
+ AbsoluteLocations = 256,
+ RelativeLocations = 512,
+ NoLocations = 1024,
+ NoUiLines = 2048
+};
+
+Q_DECLARE_FLAGS(UpdateOptions, UpdateOption)
+Q_DECLARE_OPERATORS_FOR_FLAGS(UpdateOptions)
+
+Translator merge(const Translator &tor, const Translator &virginTor,
+ UpdateOptions options, QString &err);
+
+void fetchtrInlinedCpp(const QString &in, Translator &translator, const QString &context);
+void loadCPP(Translator &translator, const QStringList &filenames, ConversionData &cd);
+bool loadJava(Translator &translator, const QString &filename, ConversionData &cd);
+bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd);
+bool loadUI(Translator &translator, const QString &filename, ConversionData &cd);
+bool loadQml(Translator &translator, const QString &filename, ConversionData &cd);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/linguist/lupdate/lupdate.pro b/src/linguist/lupdate/lupdate.pro
new file mode 100644
index 000000000..3ed909ae5
--- /dev/null
+++ b/src/linguist/lupdate/lupdate.pro
@@ -0,0 +1,49 @@
+TEMPLATE = app
+TARGET = lupdate
+DESTDIR = ../../../bin
+
+QT -= gui
+
+CONFIG += qt warn_on console
+CONFIG -= app_bundle
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+include(../shared/formats.pri)
+include(../shared/proparser.pri)
+
+include($$QT_SOURCE_TREE/src/declarative/qml/parser/parser.pri)
+INCLUDEPATH += $$QT_SOURCE_TREE/src/declarative/qml $$QT_BUILD_TREE/include/QtDeclarative
+
+SOURCES += \
+ main.cpp \
+ merge.cpp \
+ ../shared/simtexth.cpp \
+ \
+ cpp.cpp \
+ java.cpp \
+ qscript.cpp \
+ qdeclarative.cpp \
+ ui.cpp
+
+HEADERS += \
+ lupdate.h \
+ ../shared/simtexth.h
+
+DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
+
+
+win32:RC_FILE = winmanifest.rc
+
+embed_manifest_exe:win32-msvc2005 {
+ # The default configuration embed_manifest_exe overrides the manifest file
+ # already embedded via RC_FILE. Vs2008 already have the necessary manifest entry
+ QMAKE_POST_LINK += $$quote(mt.exe -updateresource:$$DESTDIR/lupdate.exe -manifest \"$${PWD}\\lupdate.exe.manifest\")
+}
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp
new file mode 100644
index 000000000..f8e6a90e3
--- /dev/null
+++ b/src/linguist/lupdate/main.cpp
@@ -0,0 +1,730 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lupdate.h"
+
+#include <translator.h>
+#include <profileevaluator.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTranslator>
+#include <QtCore/QLibraryInfo>
+
+#include <iostream>
+
+static QString m_defaultExtensions;
+
+static void printOut(const QString & out)
+{
+ std::cout << qPrintable(out);
+}
+
+static void printErr(const QString & out)
+{
+ std::cerr << qPrintable(out);
+}
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+static void recursiveFileInfoList(const QDir &dir,
+ const QSet<QString> &nameFilters, QDir::Filters filter,
+ QFileInfoList *fileinfolist)
+{
+ foreach (const QFileInfo &fi, dir.entryInfoList(filter))
+ if (fi.isDir())
+ recursiveFileInfoList(QDir(fi.absoluteFilePath()), nameFilters, filter, fileinfolist);
+ else if (nameFilters.contains(fi.suffix()))
+ fileinfolist->append(fi);
+}
+
+static void printUsage()
+{
+ printOut(LU::tr(
+ "Usage:\n"
+ " lupdate [options] [project-file]...\n"
+ " lupdate [options] [source-file|path|@lst-file]... -ts ts-files|@lst-file\n\n"
+ "lupdate is part of Qt's Linguist tool chain. It extracts translatable\n"
+ "messages from Qt UI files, C++, Java and JavaScript/QtScript source code.\n"
+ "Extracted messages are stored in textual translation source files (typically\n"
+ "Qt TS XML). New and modified messages can be merged into existing TS files.\n\n"
+ "Options:\n"
+ " -help Display this information and exit.\n"
+ " -no-obsolete\n"
+ " Drop all obsolete strings.\n"
+ " -extensions <ext>[,<ext>]...\n"
+ " Process files with the given extensions only.\n"
+ " The extension list must be separated with commas, not with whitespace.\n"
+ " Default: '%1'.\n"
+ " -pluralonly\n"
+ " Only include plural form messages.\n"
+ " -silent\n"
+ " Do not explain what is being done.\n"
+ " -no-sort\n"
+ " Do not sort contexts in TS files.\n"
+ " -no-recursive\n"
+ " Do not recursively scan the following directories.\n"
+ " -recursive\n"
+ " Recursively scan the following directories (default).\n"
+ " -I <includepath> or -I<includepath>\n"
+ " Additional location to look for include files.\n"
+ " May be specified multiple times.\n"
+ " -locations {absolute|relative|none}\n"
+ " Specify/override how source code references are saved in TS files.\n"
+ " Default is absolute.\n"
+ " -no-ui-lines\n"
+ " Do not record line numbers in references to UI files.\n"
+ " -disable-heuristic {sametext|similartext|number}\n"
+ " Disable the named merge heuristic. Can be specified multiple times.\n"
+ " -pro <filename>\n"
+ " Name of a .pro file. Useful for files with .pro file syntax but\n"
+ " different file suffix. Projects are recursed into and merged.\n"
+ " -source-language <language>[_<region>]\n"
+ " Specify the language of the source strings for new files.\n"
+ " Defaults to POSIX if not specified.\n"
+ " -target-language <language>[_<region>]\n"
+ " Specify the language of the translations for new files.\n"
+ " Guessed from the file name if not specified.\n"
+ " -ts <ts-file>...\n"
+ " Specify the output file(s). This will override the TRANSLATIONS\n"
+ " and nullify the CODECFORTR from possibly specified project files.\n"
+ " -codecfortr <codec>\n"
+ " Specify the codec assumed for tr() calls. Effective only with -ts.\n"
+ " -version\n"
+ " Display the version of lupdate and exit.\n"
+ " @lst-file\n"
+ " Read additional file names (one per line) from lst-file.\n"
+ ).arg(m_defaultExtensions));
+}
+
+static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFileNames,
+ bool setCodec, const QString &sourceLanguage, const QString &targetLanguage,
+ UpdateOptions options, bool *fail)
+{
+ QDir dir;
+ QString err;
+ foreach (const QString &fileName, tsFileNames) {
+ QString fn = dir.relativeFilePath(fileName);
+ ConversionData cd;
+ Translator tor;
+ cd.m_sortContexts = !(options & NoSort);
+ if (QFile(fileName).exists()) {
+ if (!tor.load(fileName, cd, QLatin1String("auto"))) {
+ printErr(cd.error());
+ *fail = true;
+ continue;
+ }
+ tor.resolveDuplicates();
+ cd.clearErrors();
+ if (setCodec && fetchedTor.codec() != tor.codec())
+ printErr(LU::tr("lupdate warning: Codec for tr() '%1' disagrees with"
+ " existing file's codec '%2'. Expect trouble.\n")
+ .arg(QString::fromLatin1(fetchedTor.codecName()),
+ QString::fromLatin1(tor.codecName())));
+ if (!targetLanguage.isEmpty() && targetLanguage != tor.languageCode())
+ printErr(LU::tr("lupdate warning: Specified target language '%1' disagrees with"
+ " existing file's language '%2'. Ignoring.\n")
+ .arg(targetLanguage, tor.languageCode()));
+ if (!sourceLanguage.isEmpty() && sourceLanguage != tor.sourceLanguageCode())
+ printErr(LU::tr("lupdate warning: Specified source language '%1' disagrees with"
+ " existing file's language '%2'. Ignoring.\n")
+ .arg(sourceLanguage, tor.sourceLanguageCode()));
+ } else {
+ if (setCodec)
+ tor.setCodec(fetchedTor.codec());
+ if (!targetLanguage.isEmpty())
+ tor.setLanguageCode(targetLanguage);
+ else
+ tor.setLanguageCode(Translator::guessLanguageCodeFromFileName(fileName));
+ if (!sourceLanguage.isEmpty())
+ tor.setSourceLanguageCode(sourceLanguage);
+ }
+ tor.makeFileNamesAbsolute(QFileInfo(fileName).absoluteDir());
+ if (options & NoLocations)
+ tor.setLocationsType(Translator::NoLocations);
+ else if (options & RelativeLocations)
+ tor.setLocationsType(Translator::RelativeLocations);
+ else if (options & AbsoluteLocations)
+ tor.setLocationsType(Translator::AbsoluteLocations);
+ if (options & Verbose)
+ printOut(LU::tr("Updating '%1'...\n").arg(fn));
+
+ UpdateOptions theseOptions = options;
+ if (tor.locationsType() == Translator::NoLocations) // Could be set from file
+ theseOptions |= NoLocations;
+ Translator out = merge(tor, fetchedTor, theseOptions, err);
+ if (setCodec)
+ out.setCodec(fetchedTor.codec());
+
+ if ((options & Verbose) && !err.isEmpty()) {
+ printOut(err);
+ err.clear();
+ }
+ if (options & PluralOnly) {
+ if (options & Verbose)
+ printOut(LU::tr("Stripping non plural forms in '%1'...\n").arg(fn));
+ out.stripNonPluralForms();
+ }
+ if (options & NoObsolete)
+ out.stripObsoleteMessages();
+ out.stripEmptyContexts();
+
+ out.normalizeTranslations(cd);
+ if (!cd.errors().isEmpty()) {
+ printErr(cd.error());
+ cd.clearErrors();
+ }
+ if (!out.save(fileName, cd, QLatin1String("auto"))) {
+ printErr(cd.error());
+ *fail = true;
+ }
+ }
+}
+
+static QStringList getSources(const char *var, const char *vvar, const QStringList &baseVPaths,
+ const QString &projectDir, const ProFileEvaluator &visitor)
+{
+ QStringList vPaths = visitor.absolutePathValues(QLatin1String(vvar), projectDir);
+ vPaths += baseVPaths;
+ vPaths.removeDuplicates();
+ return visitor.absoluteFileValues(QLatin1String(var), projectDir, vPaths, 0);
+}
+
+static QStringList getSources(const ProFileEvaluator &visitor, const QString &projectDir)
+{
+ QStringList baseVPaths;
+ baseVPaths += visitor.absolutePathValues(QLatin1String("VPATH"), projectDir);
+ baseVPaths << projectDir; // QMAKE_ABSOLUTE_SOURCE_PATH
+ baseVPaths += visitor.absolutePathValues(QLatin1String("DEPENDPATH"), projectDir);
+ baseVPaths.removeDuplicates();
+
+ QStringList sourceFiles;
+
+ // app/lib template
+ sourceFiles += getSources("SOURCES", "VPATH_SOURCES", baseVPaths, projectDir, visitor);
+
+ sourceFiles += getSources("FORMS", "VPATH_FORMS", baseVPaths, projectDir, visitor);
+ sourceFiles += getSources("FORMS3", "VPATH_FORMS3", baseVPaths, projectDir, visitor);
+
+ QStringList vPathsInc = baseVPaths;
+ vPathsInc += visitor.absolutePathValues(QLatin1String("INCLUDEPATH"), projectDir);
+ vPathsInc.removeDuplicates();
+ sourceFiles += visitor.absoluteFileValues(QLatin1String("HEADERS"), projectDir, vPathsInc, 0);
+
+ sourceFiles.removeDuplicates();
+ sourceFiles.sort();
+
+ return sourceFiles;
+}
+
+static void processSources(Translator &fetchedTor,
+ const QStringList &sourceFiles, ConversionData &cd)
+{
+ QStringList sourceFilesCpp;
+ for (QStringList::const_iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) {
+ if (it->endsWith(QLatin1String(".java"), Qt::CaseInsensitive))
+ loadJava(fetchedTor, *it, cd);
+ else if (it->endsWith(QLatin1String(".ui"), Qt::CaseInsensitive)
+ || it->endsWith(QLatin1String(".jui"), Qt::CaseInsensitive))
+ loadUI(fetchedTor, *it, cd);
+ else if (it->endsWith(QLatin1String(".js"), Qt::CaseInsensitive)
+ || it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive))
+ loadQScript(fetchedTor, *it, cd);
+ else if (it->endsWith(QLatin1String(".qml"), Qt::CaseInsensitive))
+ loadQml(fetchedTor, *it, cd);
+ else
+ sourceFilesCpp << *it;
+ }
+ loadCPP(fetchedTor, sourceFilesCpp, cd);
+ if (!cd.error().isEmpty())
+ printErr(cd.error());
+}
+
+static void processProjects(
+ bool topLevel, bool nestComplain, const QStringList &proFiles,
+ UpdateOptions options, const QByteArray &codecForSource,
+ const QString &targetLanguage, const QString &sourceLanguage,
+ Translator *parentTor, bool *fail);
+
+static void processProject(
+ bool nestComplain, const QFileInfo &pfi, ProFileEvaluator &visitor,
+ UpdateOptions options, const QByteArray &_codecForSource,
+ const QString &targetLanguage, const QString &sourceLanguage,
+ Translator *fetchedTor, bool *fail)
+{
+ QByteArray codecForSource = _codecForSource;
+ QStringList tmp = visitor.values(QLatin1String("CODECFORSRC"));
+ if (!tmp.isEmpty()) {
+ codecForSource = tmp.last().toLatin1();
+ if (!QTextCodec::codecForName(codecForSource)) {
+ printErr(LU::tr("lupdate warning: Codec for source '%1' is invalid."
+ " Falling back to codec for tr().\n")
+ .arg(QString::fromLatin1(codecForSource)));
+ codecForSource.clear();
+ }
+ }
+ if (visitor.templateType() == ProFileEvaluator::TT_Subdirs) {
+ QStringList subProFiles;
+ QDir proDir(pfi.absoluteDir());
+ foreach (const QString &subdir, visitor.values(QLatin1String("SUBDIRS"))) {
+ QString subPro = QDir::cleanPath(proDir.absoluteFilePath(subdir));
+ QFileInfo subInfo(subPro);
+ if (subInfo.isDir())
+ subProFiles << (subPro + QLatin1Char('/')
+ + subInfo.fileName() + QLatin1String(".pro"));
+ else
+ subProFiles << subPro;
+ }
+ processProjects(false, nestComplain, subProFiles, options, codecForSource,
+ targetLanguage, sourceLanguage, fetchedTor, fail);
+ } else {
+ ConversionData cd;
+ cd.m_noUiLines = options & NoUiLines;
+ cd.m_codecForSource = codecForSource;
+ cd.m_includePath = visitor.values(QLatin1String("INCLUDEPATH"));
+ QStringList sourceFiles = getSources(visitor, pfi.absolutePath());
+ QSet<QString> sourceDirs;
+ sourceDirs.insert(QDir::cleanPath(pfi.absolutePath()) + QLatin1Char('/'));
+ foreach (const QString &sf, sourceFiles)
+ sourceDirs.insert(sf.left(sf.lastIndexOf(QLatin1Char('/')) + 1));
+ QStringList rootList = sourceDirs.toList();
+ rootList.sort();
+ for (int prev = 0, curr = 1; curr < rootList.length(); )
+ if (rootList.at(curr).startsWith(rootList.at(prev)))
+ rootList.removeAt(curr);
+ else
+ prev = curr++;
+ cd.m_projectRoots = QSet<QString>::fromList(rootList);
+ processSources(*fetchedTor, sourceFiles, cd);
+ }
+}
+
+static void processProjects(
+ bool topLevel, bool nestComplain, const QStringList &proFiles,
+ UpdateOptions options, const QByteArray &codecForSource,
+ const QString &targetLanguage, const QString &sourceLanguage,
+ Translator *parentTor, bool *fail)
+{
+ foreach (const QString &proFile, proFiles) {
+ ProFileEvaluator visitor;
+ visitor.setVerbose(options & Verbose);
+
+ QHash<QString, QStringList> lupdateConfig;
+ lupdateConfig.insert(QLatin1String("CONFIG"), QStringList(QLatin1String("lupdate_run")));
+ visitor.addVariables(lupdateConfig);
+
+ QFileInfo pfi(proFile);
+ ProFile pro(pfi.absoluteFilePath());
+ if (!visitor.queryProFile(&pro) || !visitor.accept(&pro)) {
+ if (topLevel)
+ *fail = true;
+ continue;
+ }
+
+ if (visitor.contains(QLatin1String("TRANSLATIONS"))) {
+ if (parentTor) {
+ if (topLevel) {
+ printErr(LU::tr("lupdate warning: TS files from command line "
+ "will override TRANSLATIONS in %1.\n").arg(proFile));
+ goto noTrans;
+ } else if (nestComplain) {
+ printErr(LU::tr("lupdate warning: TS files from command line "
+ "prevent recursing into %1.\n").arg(proFile));
+ continue;
+ }
+ }
+ QStringList tsFiles;
+ QDir proDir(pfi.absolutePath());
+ foreach (const QString &tsFile, visitor.values(QLatin1String("TRANSLATIONS")))
+ tsFiles << QFileInfo(proDir, tsFile).filePath();
+ if (tsFiles.isEmpty()) {
+ // This might mean either a buggy PRO file or an intentional detach -
+ // we can't know without seeing the actual RHS of the assignment ...
+ // Just assume correctness and be silent.
+ continue;
+ }
+ Translator tor;
+ bool setCodec = false;
+ QStringList tmp = visitor.values(QLatin1String("CODEC"))
+ + visitor.values(QLatin1String("DEFAULTCODEC"))
+ + visitor.values(QLatin1String("CODECFORTR"));
+ if (!tmp.isEmpty()) {
+ tor.setCodecName(tmp.last().toLatin1());
+ setCodec = true;
+ }
+ processProject(false, pfi, visitor, options, codecForSource,
+ targetLanguage, sourceLanguage, &tor, fail);
+ updateTsFiles(tor, tsFiles, setCodec, sourceLanguage, targetLanguage, options, fail);
+ continue;
+ }
+ noTrans:
+ if (!parentTor) {
+ if (topLevel)
+ printErr(LU::tr("lupdate warning: no TS files specified. Only diagnostics "
+ "will be produced for '%1'.\n").arg(proFile));
+ Translator tor;
+ processProject(nestComplain, pfi, visitor, options, codecForSource,
+ targetLanguage, sourceLanguage, &tor, fail);
+ } else {
+ processProject(nestComplain, pfi, visitor, options, codecForSource,
+ targetLanguage, sourceLanguage, parentTor, fail);
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+#endif // Q_OS_WIN32
+
+ m_defaultExtensions = QLatin1String("java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml");
+
+ QStringList args = app.arguments();
+ QStringList tsFileNames;
+ QStringList proFiles;
+ QMultiHash<QString, QString> allCSources;
+ QSet<QString> projectRoots;
+ QStringList sourceFiles;
+ QStringList includePath;
+ QString targetLanguage;
+ QString sourceLanguage;
+ QByteArray codecForTr;
+
+ UpdateOptions options =
+ Verbose | // verbose is on by default starting with Qt 4.2
+ HeuristicSameText | HeuristicSimilarText | HeuristicNumber;
+ int numFiles = 0;
+ bool metTsFlag = false;
+ bool recursiveScan = true;
+
+ QString extensions = m_defaultExtensions;
+ QSet<QString> extensionsNameFilters;
+
+ for (int i = 1; i < argc; ++i) {
+ QString arg = args.at(i);
+ if (arg == QLatin1String("-help")
+ || arg == QLatin1String("--help")
+ || arg == QLatin1String("-h")) {
+ printUsage();
+ return 0;
+ } else if (arg == QLatin1String("-pluralonly")) {
+ options |= PluralOnly;
+ continue;
+ } else if (arg == QLatin1String("-noobsolete")
+ || arg == QLatin1String("-no-obsolete")) {
+ options |= NoObsolete;
+ continue;
+ } else if (arg == QLatin1String("-silent")) {
+ options &= ~Verbose;
+ continue;
+ } else if (arg == QLatin1String("-target-language")) {
+ ++i;
+ if (i == argc) {
+ printErr(LU::tr("The option -target-language requires a parameter.\n"));
+ return 1;
+ }
+ targetLanguage = args[i];
+ continue;
+ } else if (arg == QLatin1String("-source-language")) {
+ ++i;
+ if (i == argc) {
+ printErr(LU::tr("The option -source-language requires a parameter.\n"));
+ return 1;
+ }
+ sourceLanguage = args[i];
+ continue;
+ } else if (arg == QLatin1String("-disable-heuristic")) {
+ ++i;
+ if (i == argc) {
+ printErr(LU::tr("The option -disable-heuristic requires a parameter.\n"));
+ return 1;
+ }
+ arg = args[i];
+ if (arg == QLatin1String("sametext")) {
+ options &= ~HeuristicSameText;
+ } else if (arg == QLatin1String("similartext")) {
+ options &= ~HeuristicSimilarText;
+ } else if (arg == QLatin1String("number")) {
+ options &= ~HeuristicNumber;
+ } else {
+ printErr(LU::tr("Invalid heuristic name passed to -disable-heuristic.\n"));
+ return 1;
+ }
+ continue;
+ } else if (arg == QLatin1String("-locations")) {
+ ++i;
+ if (i == argc) {
+ printErr(LU::tr("The option -locations requires a parameter.\n"));
+ return 1;
+ }
+ if (args[i] == QLatin1String("none")) {
+ options |= NoLocations;
+ } else if (args[i] == QLatin1String("relative")) {
+ options |= RelativeLocations;
+ } else if (args[i] == QLatin1String("absolute")) {
+ options |= AbsoluteLocations;
+ } else {
+ printErr(LU::tr("Invalid parameter passed to -locations.\n"));
+ return 1;
+ }
+ continue;
+ } else if (arg == QLatin1String("-no-ui-lines")) {
+ options |= NoUiLines;
+ continue;
+ } else if (arg == QLatin1String("-verbose")) {
+ options |= Verbose;
+ continue;
+ } else if (arg == QLatin1String("-no-recursive")) {
+ recursiveScan = false;
+ continue;
+ } else if (arg == QLatin1String("-recursive")) {
+ recursiveScan = true;
+ continue;
+ } else if (arg == QLatin1String("-no-sort")
+ || arg == QLatin1String("-nosort")) {
+ options |= NoSort;
+ continue;
+ } else if (arg == QLatin1String("-version")) {
+ printOut(QObject::tr("lupdate version %1\n").arg(QLatin1String(QT_VERSION_STR)));
+ return 0;
+ } else if (arg == QLatin1String("-codecfortr")) {
+ ++i;
+ if (i == argc) {
+ printErr(LU::tr("The -codecfortr option should be followed by a codec name.\n"));
+ return 1;
+ }
+ codecForTr = args[i].toLatin1();
+ continue;
+ } else if (arg == QLatin1String("-ts")) {
+ metTsFlag = true;
+ continue;
+ } else if (arg == QLatin1String("-extensions")) {
+ ++i;
+ if (i == argc) {
+ printErr(LU::tr("The -extensions option should be followed by an extension list.\n"));
+ return 1;
+ }
+ extensions = args[i];
+ continue;
+ } else if (arg == QLatin1String("-pro")) {
+ ++i;
+ if (i == argc) {
+ printErr(LU::tr("The -pro option should be followed by a filename of .pro file.\n"));
+ return 1;
+ }
+ proFiles += args[i];
+ numFiles++;
+ continue;
+ } else if (arg.startsWith(QLatin1String("-I"))) {
+ if (arg.length() == 2) {
+ ++i;
+ if (i == argc) {
+ printErr(LU::tr("The -I option should be followed by a path.\n"));
+ return 1;
+ }
+ includePath += args[i];
+ } else {
+ includePath += args[i].mid(2);
+ }
+ continue;
+ } else if (arg.startsWith(QLatin1String("-")) && arg != QLatin1String("-")) {
+ printErr(LU::tr("Unrecognized option '%1'.\n").arg(arg));
+ return 1;
+ }
+
+ QStringList files;
+ if (arg.startsWith(QLatin1String("@"))) {
+ QFile lstFile(arg.mid(1));
+ if (!lstFile.open(QIODevice::ReadOnly)) {
+ printErr(LU::tr("lupdate error: List file '%1' is not readable.\n")
+ .arg(lstFile.fileName()));
+ return 1;
+ }
+ while (!lstFile.atEnd())
+ files << QString::fromLocal8Bit(lstFile.readLine().trimmed());
+ } else {
+ files << arg;
+ }
+ if (metTsFlag) {
+ foreach (const QString &file, files) {
+ bool found = false;
+ foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
+ if (file.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) {
+ QFileInfo fi(file);
+ if (!fi.exists() || fi.isWritable()) {
+ tsFileNames.append(QFileInfo(file).absoluteFilePath());
+ } else {
+ printErr(LU::tr("lupdate warning: For some reason, '%1' is not writable.\n")
+ .arg(file));
+ }
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ printErr(LU::tr("lupdate error: File '%1' has no recognized extension.\n")
+ .arg(file));
+ return 1;
+ }
+ }
+ numFiles++;
+ } else {
+ foreach (const QString &file, files) {
+ QFileInfo fi(file);
+ if (!fi.exists()) {
+ printErr(LU::tr("lupdate error: File '%1' does not exist.\n").arg(file));
+ return 1;
+ }
+ if (file.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
+ || file.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
+ proFiles << file;
+ } else if (fi.isDir()) {
+ if (options & Verbose)
+ printOut(LU::tr("Scanning directory '%1'...\n").arg(file));
+ QDir dir = QDir(fi.filePath());
+ projectRoots.insert(dir.absolutePath() + QLatin1Char('/'));
+ if (extensionsNameFilters.isEmpty()) {
+ foreach (QString ext, extensions.split(QLatin1Char(','))) {
+ ext = ext.trimmed();
+ if (ext.startsWith(QLatin1Char('.')))
+ ext.remove(0, 1);
+ extensionsNameFilters.insert(ext);
+ }
+ }
+ QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
+ if (recursiveScan)
+ filters |= QDir::AllDirs | QDir::NoDotAndDotDot;
+ QFileInfoList fileinfolist;
+ recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist);
+ int scanRootLen = dir.absolutePath().length();
+ foreach (const QFileInfo &fi, fileinfolist) {
+ QString fn = QDir::cleanPath(fi.absoluteFilePath());
+ sourceFiles << fn;
+
+ if (!fn.endsWith(QLatin1String(".java"))
+ && !fn.endsWith(QLatin1String(".jui"))
+ && !fn.endsWith(QLatin1String(".ui"))
+ && !fn.endsWith(QLatin1String(".js"))
+ && !fn.endsWith(QLatin1String(".qs"))
+ && !fn.endsWith(QLatin1String(".qml"))) {
+ int offset = 0;
+ int depth = 0;
+ do {
+ offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
+ QString ffn = fn.mid(offset + 1);
+ allCSources.insert(ffn, fn);
+ } while (++depth < 3 && offset > scanRootLen);
+ }
+ }
+ } else {
+ sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
+ projectRoots.insert(fi.absolutePath() + QLatin1Char('/'));
+ }
+ }
+ numFiles++;
+ }
+ } // for args
+
+ if (numFiles == 0) {
+ printUsage();
+ return 1;
+ }
+
+ if (!targetLanguage.isEmpty() && tsFileNames.count() != 1)
+ printErr(LU::tr("lupdate warning: -target-language usually only"
+ " makes sense with exactly one TS file.\n"));
+ if (!codecForTr.isEmpty() && tsFileNames.isEmpty())
+ printErr(LU::tr("lupdate warning: -codecfortr has no effect without -ts.\n"));
+
+ bool fail = false;
+ if (proFiles.isEmpty()) {
+ if (tsFileNames.isEmpty())
+ printErr(LU::tr("lupdate warning:"
+ " no TS files specified. Only diagnostics will be produced.\n"));
+
+ Translator fetchedTor;
+ ConversionData cd;
+ cd.m_noUiLines = options & NoUiLines;
+ cd.m_projectRoots = projectRoots;
+ cd.m_includePath = includePath;
+ cd.m_allCSources = allCSources;
+ fetchedTor.setCodecName(codecForTr);
+ processSources(fetchedTor, sourceFiles, cd);
+ updateTsFiles(fetchedTor, tsFileNames, !codecForTr.isEmpty(),
+ sourceLanguage, targetLanguage, options, &fail);
+ } else {
+ if (!sourceFiles.isEmpty() || !includePath.isEmpty()) {
+ printErr(LU::tr("lupdate error:"
+ " Both project and source files / include paths specified.\n"));
+ return 1;
+ }
+ if (!tsFileNames.isEmpty()) {
+ Translator fetchedTor;
+ fetchedTor.setCodecName(codecForTr);
+ processProjects(true, true, proFiles, options, QByteArray(),
+ targetLanguage, sourceLanguage, &fetchedTor, &fail);
+ updateTsFiles(fetchedTor, tsFileNames, !codecForTr.isEmpty(),
+ sourceLanguage, targetLanguage, options, &fail);
+ } else {
+ processProjects(true, false, proFiles, options, QByteArray(),
+ targetLanguage, sourceLanguage, 0, &fail);
+ }
+ }
+ return fail ? 1 : 0;
+}
diff --git a/src/linguist/lupdate/merge.cpp b/src/linguist/lupdate/merge.cpp
new file mode 100644
index 000000000..39de603eb
--- /dev/null
+++ b/src/linguist/lupdate/merge.cpp
@@ -0,0 +1,515 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lupdate.h"
+
+#include "simtexth.h"
+#include "translator.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QMap>
+#include <QtCore/QStringList>
+#include <QtCore/QTextCodec>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+static bool isDigitFriendly(QChar c)
+{
+ return c.isPunct() || c.isSpace();
+}
+
+static int numberLength(const QString &s, int i)
+{
+ if (i >= s.size() || !s.at(i).isDigit())
+ return 0;
+
+ int pos = i;
+ do {
+ ++i;
+ } while (i < s.size()
+ && (s.at(i).isDigit()
+ || (isDigitFriendly(s[i])
+ && i + 1 < s.size()
+ && (s[i + 1].isDigit()
+ || (isDigitFriendly(s[i + 1])
+ && i + 2 < s.size()
+ && s[i + 2].isDigit())))));
+ return i - pos;
+}
+
+
+/*
+ Returns a version of 'key' where all numbers have been replaced by zeroes. If
+ there were none, returns "".
+*/
+static QString zeroKey(const QString &key)
+{
+ QString zeroed;
+ bool metSomething = false;
+
+ for (int i = 0; i < key.size(); ++i) {
+ int len = numberLength(key, i);
+ if (len > 0) {
+ i += len;
+ zeroed.append(QLatin1Char('0'));
+ metSomething = true;
+ } else {
+ zeroed.append(key.at(i));
+ }
+ }
+ return metSomething ? zeroed : QString();
+}
+
+static QString translationAttempt(const QString &oldTranslation,
+ const QString &oldSource, const QString &newSource)
+{
+ int p = zeroKey(oldSource).count(QLatin1Char('0'));
+ QString attempt;
+ QStringList oldNumbers;
+ QStringList newNumbers;
+ QVector<bool> met(p);
+ QVector<int> matchedYet(p);
+ int i, j;
+ int k = 0, ell, best;
+ int m, n;
+ int pass;
+
+ /*
+ This algorithm is hard to follow, so we'll consider an example
+ all along: oldTranslation is "XeT 3.0", oldSource is "TeX 3.0"
+ and newSource is "XeT 3.1".
+
+ First, we set up two tables: oldNumbers and newNumbers. In our
+ example, oldNumber[0] is "3.0" and newNumber[0] is "3.1".
+ */
+ for (i = 0, j = 0; i < oldSource.size(); i++, j++) {
+ m = numberLength(oldSource, i);
+ n = numberLength(newSource, j);
+ if (m > 0) {
+ oldNumbers.append(oldSource.mid(i, m + 1));
+ newNumbers.append(newSource.mid(j, n + 1));
+ i += m;
+ j += n;
+ met[k] = false;
+ matchedYet[k] = 0;
+ k++;
+ }
+ }
+
+ /*
+ We now go over the old translation, "XeT 3.0", one letter at a
+ time, looking for numbers found in oldNumbers. Whenever such a
+ number is met, it is replaced with its newNumber equivalent. In
+ our example, the "3.0" of "XeT 3.0" becomes "3.1".
+ */
+ for (i = 0; i < oldTranslation.length(); i++) {
+ attempt += oldTranslation[i];
+ for (k = 0; k < p; k++) {
+ if (oldTranslation[i] == oldNumbers[k][matchedYet[k]])
+ matchedYet[k]++;
+ else
+ matchedYet[k] = 0;
+ }
+
+ /*
+ Let's find out if the last character ended a match. We make
+ two passes over the data. In the first pass, we try to
+ match only numbers that weren't matched yet; if that fails,
+ the second pass does the trick. This is useful in some
+ suspicious cases, flagged below.
+ */
+ for (pass = 0; pass < 2; pass++) {
+ best = p; // an impossible value
+ for (k = 0; k < p; k++) {
+ if ((!met[k] || pass > 0) &&
+ matchedYet[k] == oldNumbers[k].length() &&
+ numberLength(oldTranslation, i + 1 - matchedYet[k]) == matchedYet[k]) {
+ // the longer the better
+ if (best == p || matchedYet[k] > matchedYet[best])
+ best = k;
+ }
+ }
+ if (best != p) {
+ attempt.truncate(attempt.length() - matchedYet[best]);
+ attempt += newNumbers[best];
+ met[best] = true;
+ for (k = 0; k < p; k++)
+ matchedYet[k] = 0;
+ break;
+ }
+ }
+ }
+
+ /*
+ We flag two kinds of suspicious cases. They are identified as
+ such with comments such as "{2000?}" at the end.
+
+ Example of the first kind: old source text "TeX 3.0" translated
+ as "XeT 2.0" is flagged "TeX 2.0 {3.0?}", no matter what the
+ new text is.
+ */
+ for (k = 0; k < p; k++) {
+ if (!met[k])
+ attempt += QLatin1String(" {") + newNumbers[k] + QLatin1String("?}");
+ }
+
+ /*
+ Example of the second kind: "1 of 1" translated as "1 af 1",
+ with new source text "1 of 2", generates "1 af 2 {1 or 2?}"
+ because it's not clear which of "1 af 2" and "2 af 1" is right.
+ */
+ for (k = 0; k < p; k++) {
+ for (ell = 0; ell < p; ell++) {
+ if (k != ell && oldNumbers[k] == oldNumbers[ell] &&
+ newNumbers[k] < newNumbers[ell])
+ attempt += QLatin1String(" {") + newNumbers[k] + QLatin1String(" or ") +
+ newNumbers[ell] + QLatin1String("?}");
+ }
+ }
+ return attempt;
+}
+
+
+/*
+ Augments a Translator with translations easily derived from
+ similar existing (probably obsolete) translations.
+
+ For example, if "TeX 3.0" is translated as "XeT 3.0" and "TeX 3.1"
+ has no translation, "XeT 3.1" is added to the translator and is
+ marked Unfinished.
+
+ Returns the number of additional messages that this heuristic translated.
+*/
+int applyNumberHeuristic(Translator &tor)
+{
+ QMap<QString, QPair<QString, QString> > translated;
+ QVector<bool> untranslated(tor.messageCount());
+ int inserted = 0;
+
+ for (int i = 0; i < tor.messageCount(); ++i) {
+ const TranslatorMessage &msg = tor.message(i);
+ bool hasTranslation = msg.isTranslated();
+ if (msg.type() == TranslatorMessage::Unfinished) {
+ if (!hasTranslation)
+ untranslated[i] = true;
+ } else if (hasTranslation && msg.translations().count() == 1) {
+ const QString &key = zeroKey(msg.sourceText());
+ if (!key.isEmpty())
+ translated.insert(key, qMakePair(msg.sourceText(), msg.translation()));
+ }
+ }
+
+ for (int i = 0; i < tor.messageCount(); ++i) {
+ if (untranslated[i]) {
+ TranslatorMessage &msg = tor.message(i);
+ const QString &key = zeroKey(msg.sourceText());
+ if (!key.isEmpty()) {
+ QMap<QString, QPair<QString, QString> >::ConstIterator t =
+ translated.constFind(key);
+ if (t != translated.constEnd() && t->first != msg.sourceText()) {
+ msg.setTranslation(translationAttempt(t->second, t->first,
+ msg.sourceText()));
+ inserted++;
+ }
+ }
+ }
+ }
+ return inserted;
+}
+
+
+/*
+ Augments a Translator with trivially derived translations.
+
+ For example, if "Enabled:" is consistendly translated as "Eingeschaltet:" no
+ matter the context or the comment, "Eingeschaltet:" is added as the
+ translation of any untranslated "Enabled:" text and is marked Unfinished.
+
+ Returns the number of additional messages that this heuristic translated.
+*/
+
+int applySameTextHeuristic(Translator &tor)
+{
+ QMap<QString, QStringList> translated;
+ QMap<QString, bool> avoid; // Want a QTreeSet, in fact
+ QVector<bool> untranslated(tor.messageCount());
+ int inserted = 0;
+
+ for (int i = 0; i < tor.messageCount(); ++i) {
+ const TranslatorMessage &msg = tor.message(i);
+ if (!msg.isTranslated()) {
+ if (msg.type() == TranslatorMessage::Unfinished)
+ untranslated[i] = true;
+ } else {
+ const QString &key = msg.sourceText();
+ QMap<QString, QStringList>::ConstIterator t = translated.constFind(key);
+ if (t != translated.constEnd()) {
+ /*
+ The same source text is translated at least two
+ different ways. Do nothing then.
+ */
+ if (*t != msg.translations()) {
+ translated.remove(key);
+ avoid.insert(key, true);
+ }
+ } else if (!avoid.contains(key)) {
+ translated.insert(key, msg.translations());
+ }
+ }
+ }
+
+ for (int i = 0; i < tor.messageCount(); ++i) {
+ if (untranslated[i]) {
+ TranslatorMessage &msg = tor.message(i);
+ QMap<QString, QStringList>::ConstIterator t = translated.constFind(msg.sourceText());
+ if (t != translated.constEnd()) {
+ msg.setTranslations(*t);
+ ++inserted;
+ }
+ }
+ }
+ return inserted;
+}
+
+
+
+/*
+ Merges two Translator objects. The first one
+ is a set of source texts and translations for a previous version of
+ the internationalized program; the second one is a set of fresh
+ source texts newly extracted from the source code, without any
+ translation yet.
+*/
+
+Translator merge(const Translator &tor, const Translator &virginTor,
+ UpdateOptions options, QString &err)
+{
+ int known = 0;
+ int neww = 0;
+ int obsoleted = 0;
+ int similarTextHeuristicCount = 0;
+
+ Translator outTor;
+ outTor.setLanguageCode(tor.languageCode());
+ outTor.setSourceLanguageCode(tor.sourceLanguageCode());
+ outTor.setLocationsType(tor.locationsType());
+ outTor.setCodecName(tor.codecName());
+
+ /*
+ The types of all the messages from the vernacular translator
+ are updated according to the virgin translator.
+ */
+ foreach (TranslatorMessage m, tor.messages()) {
+ TranslatorMessage::Type newType = TranslatorMessage::Finished;
+
+ if (m.sourceText().isEmpty() && m.id().isEmpty()) {
+ // context/file comment
+ TranslatorMessage mv = virginTor.find(m.context());
+ if (!mv.isNull())
+ m.setComment(mv.comment());
+ } else {
+ TranslatorMessage mv;
+ int mvi = virginTor.find(m);
+ if (mvi < 0) {
+ if (!(options & HeuristicSimilarText)) {
+ makeObsolete:
+ newType = TranslatorMessage::Obsolete;
+ if (m.type() != TranslatorMessage::Obsolete)
+ obsoleted++;
+ m.clearReferences();
+ } else {
+ mv = virginTor.find(m.context(), m.comment(), m.allReferences());
+ if (mv.isNull()) {
+ // did not find it in the virgin, mark it as obsolete
+ goto makeObsolete;
+ } else {
+ // Do not just accept it if its on the same line number,
+ // but different source text.
+ // Also check if the texts are more or less similar before
+ // we consider them to represent the same message...
+ if (getSimilarityScore(m.sourceText(), mv.sourceText()) >= textSimilarityThreshold) {
+ // It is just slightly modified, assume that it is the same string
+
+ // Mark it as unfinished. (Since the source text
+ // was changed it might require re-translating...)
+ newType = TranslatorMessage::Unfinished;
+ ++similarTextHeuristicCount;
+ neww++;
+
+ outdateSource:
+ m.setOldSourceText(m.sourceText());
+ m.setSourceText(mv.sourceText());
+ const QString &oldpluralsource = m.extra(QLatin1String("po-msgid_plural"));
+ if (!oldpluralsource.isEmpty()) {
+ m.setExtra(QLatin1String("po-old_msgid_plural"), oldpluralsource);
+ m.unsetExtra(QLatin1String("po-msgid_plural"));
+ }
+ goto copyAttribs; // Update secondary references
+ } else {
+ // The virgin and vernacular sourceTexts are so
+ // different that we could not find it.
+ goto makeObsolete;
+ }
+ }
+ }
+ } else {
+ mv = virginTor.message(mvi);
+ if (!mv.id().isEmpty()
+ && (mv.context() != m.context()
+ || mv.sourceText() != m.sourceText()
+ || mv.comment() != m.comment())) {
+ known++;
+ newType = TranslatorMessage::Unfinished;
+ m.setContext(mv.context());
+ m.setComment(mv.comment());
+ if (mv.sourceText() != m.sourceText())
+ goto outdateSource;
+ } else {
+ switch (m.type()) {
+ case TranslatorMessage::Finished:
+ default:
+ if (m.isPlural() == mv.isPlural()) {
+ newType = TranslatorMessage::Finished;
+ } else {
+ newType = TranslatorMessage::Unfinished;
+ }
+ known++;
+ break;
+ case TranslatorMessage::Unfinished:
+ newType = TranslatorMessage::Unfinished;
+ known++;
+ break;
+ case TranslatorMessage::Obsolete:
+ newType = TranslatorMessage::Unfinished;
+ neww++;
+ }
+ }
+
+ // Always get the filename and linenumber info from the
+ // virgin Translator, in case it has changed location.
+ // This should also enable us to read a file that does not
+ // have the <location> element.
+ // why not use operator=()? Because it overwrites e.g. userData.
+ copyAttribs:
+ m.setReferences(mv.allReferences());
+ m.setPlural(mv.isPlural());
+ m.setUtf8(mv.isUtf8());
+ m.setExtraComment(mv.extraComment());
+ m.setId(mv.id());
+ }
+ }
+
+ m.setType(newType);
+ outTor.append(m);
+ }
+
+ /*
+ Messages found only in the virgin translator are added to the
+ vernacular translator.
+ */
+ foreach (const TranslatorMessage &mv, virginTor.messages()) {
+ if (mv.sourceText().isEmpty() && mv.id().isEmpty()) {
+ if (tor.contains(mv.context()))
+ continue;
+ } else {
+ if (tor.find(mv) >= 0)
+ continue;
+ if (options & HeuristicSimilarText) {
+ TranslatorMessage m = tor.find(mv.context(), mv.comment(), mv.allReferences());
+ if (!m.isNull()) {
+ if (getSimilarityScore(m.sourceText(), mv.sourceText()) >= textSimilarityThreshold)
+ continue;
+ }
+ }
+ }
+ if (options & NoLocations)
+ outTor.append(mv);
+ else
+ outTor.appendSorted(mv);
+ if (!mv.sourceText().isEmpty() || !mv.id().isEmpty())
+ ++neww;
+ }
+
+ /*
+ The same-text heuristic handles cases where a message has an
+ obsolete counterpart with a different context or comment.
+ */
+ int sameTextHeuristicCount = (options & HeuristicSameText) ? applySameTextHeuristic(outTor) : 0;
+
+ /*
+ The number heuristic handles cases where a message has an
+ obsolete counterpart with mostly numbers differing in the
+ source text.
+ */
+ int sameNumberHeuristicCount = (options & HeuristicNumber) ? applyNumberHeuristic(outTor) : 0;
+
+ if (options & Verbose) {
+ int totalFound = neww + known;
+ err += LU::tr(" Found %n source text(s) (%1 new and %2 already existing)\n", 0, totalFound).arg(neww).arg(known);
+
+ if (obsoleted) {
+ if (options & NoObsolete) {
+ err += LU::tr(" Removed %n obsolete entries\n", 0, obsoleted);
+ } else {
+ err += LU::tr(" Kept %n obsolete entries\n", 0, obsoleted);
+ }
+ }
+
+ if (sameNumberHeuristicCount)
+ err += LU::tr(" Number heuristic provided %n translation(s)\n",
+ 0, sameNumberHeuristicCount);
+ if (sameTextHeuristicCount)
+ err += LU::tr(" Same-text heuristic provided %n translation(s)\n",
+ 0, sameTextHeuristicCount);
+ if (similarTextHeuristicCount)
+ err += LU::tr(" Similar-text heuristic provided %n translation(s)\n",
+ 0, similarTextHeuristicCount);
+ }
+ return outTor;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/qdeclarative.cpp b/src/linguist/lupdate/qdeclarative.cpp
new file mode 100644
index 000000000..6bf9cf469
--- /dev/null
+++ b/src/linguist/lupdate/qdeclarative.cpp
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lupdate.h"
+
+#include <translator.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QString>
+
+#include "parser/qdeclarativejsengine_p.h"
+#include "parser/qdeclarativejsparser_p.h"
+#include "parser/qdeclarativejslexer_p.h"
+#include "parser/qdeclarativejsnodepool_p.h"
+#include "parser/qdeclarativejsastvisitor_p.h"
+#include "parser/qdeclarativejsast_p.h"
+
+#include <QCoreApplication>
+#include <QFile>
+#include <QFileInfo>
+#include <QtDebug>
+#include <QStringList>
+
+#include <iostream>
+#include <cstdlib>
+#include <cctype>
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+using namespace QDeclarativeJS;
+
+class Comment
+{
+public:
+ Comment() : lastLine(-1) {}
+ QString extracomment;
+ QString msgid;
+ TranslatorMessage::ExtraData extra;
+ QString sourcetext;
+ int lastLine;
+
+ bool isValid() const
+ { return !extracomment.isEmpty() || !msgid.isEmpty() || !sourcetext.isEmpty() || !extra.isEmpty(); }
+};
+
+class FindTrCalls: protected AST::Visitor
+{
+public:
+ void operator()(Translator *translator, const QString &fileName, AST::Node *node)
+ {
+ m_translator = translator;
+ m_fileName = fileName;
+ m_component = QFileInfo(fileName).baseName(); //matches qsTr usage in QScriptEngine
+ accept(node);
+ }
+
+ QList<Comment> comments;
+
+protected:
+ using AST::Visitor::visit;
+ using AST::Visitor::endVisit;
+
+ void accept(AST::Node *node)
+ { AST::Node::acceptChild(node, this); }
+
+ virtual void endVisit(AST::CallExpression *node)
+ {
+ m_bSource.clear();
+ if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(node->base)) {
+ if (idExpr->name->asString() == QLatin1String("qsTr") ||
+ idExpr->name->asString() == QLatin1String("QT_TR_NOOP")) {
+ if (!node->arguments)
+ return;
+ AST::BinaryExpression *binary = AST::cast<AST::BinaryExpression *>(node->arguments->expression);
+ if (binary) {
+ if (!createString(binary))
+ m_bSource.clear();
+ }
+ AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
+ if (literal || !m_bSource.isEmpty()) {
+ const QString source = literal ? literal->value->asString() : m_bSource;
+
+ QString comment;
+ bool plural = false;
+ AST::ArgumentList *commentNode = node->arguments->next;
+ if (commentNode && AST::cast<AST::StringLiteral *>(commentNode->expression)) {
+ literal = AST::cast<AST::StringLiteral *>(commentNode->expression);
+ comment = literal->value->asString();
+
+ AST::ArgumentList *nNode = commentNode->next;
+ if (nNode)
+ plural = true;
+ }
+
+ QString id;
+ QString extracomment;
+ TranslatorMessage::ExtraData extra;
+ Comment scomment = findComment(node->firstSourceLocation().startLine);
+ if (scomment.isValid()) {
+ extracomment = scomment.extracomment;
+ extra = scomment.extra;
+ id = scomment.msgid;
+ }
+
+ TranslatorMessage msg(m_component, source,
+ comment, QString(), m_fileName,
+ node->firstSourceLocation().startLine, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ msg.setId(id);
+ msg.setExtras(extra);
+ m_translator->extend(msg);
+ }
+ } else if (idExpr->name->asString() == QLatin1String("qsTranslate") ||
+ idExpr->name->asString() == QLatin1String("QT_TRANSLATE_NOOP")) {
+ if (node->arguments && AST::cast<AST::StringLiteral *>(node->arguments->expression)) {
+ AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
+ const QString context = literal->value->asString();
+
+ QString source;
+ QString comment;
+ bool plural = false;
+ AST::ArgumentList *sourceNode = node->arguments->next;
+ if (!sourceNode)
+ return;
+ literal = AST::cast<AST::StringLiteral *>(sourceNode->expression);
+ AST::BinaryExpression *binary = AST::cast<AST::BinaryExpression *>(sourceNode->expression);
+ if (binary) {
+ if (!createString(binary))
+ m_bSource.clear();
+ }
+ if (!literal && m_bSource.isEmpty())
+ return;
+
+ QString id;
+ QString extracomment;
+ TranslatorMessage::ExtraData extra;
+ Comment scomment = findComment(node->firstSourceLocation().startLine);
+ if (scomment.isValid()) {
+ extracomment = scomment.extracomment;
+ extra = scomment.extra;
+ id = scomment.msgid;
+ }
+
+ source = literal ? literal->value->asString() : m_bSource;
+ AST::ArgumentList *commentNode = sourceNode->next;
+ if (commentNode && AST::cast<AST::StringLiteral *>(commentNode->expression)) {
+ literal = AST::cast<AST::StringLiteral *>(commentNode->expression);
+ comment = literal->value->asString();
+
+ AST::ArgumentList *nNode = commentNode->next;
+ if (nNode)
+ plural = true;
+ }
+
+ TranslatorMessage msg(context, source,
+ comment, QString(), m_fileName,
+ node->firstSourceLocation().startLine, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ msg.setId(id);
+ msg.setExtras(extra);
+ m_translator->extend(msg);
+ }
+ } else if (idExpr->name->asString() == QLatin1String("qsTrId") ||
+ idExpr->name->asString() == QLatin1String("QT_TRID_NOOP")) {
+ if (!node->arguments)
+ return;
+
+ AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
+ if (literal) {
+
+ QString extracomment;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
+ Comment comment = findComment(node->firstSourceLocation().startLine);
+ if (comment.isValid()) {
+ extracomment = comment.extracomment;
+ sourcetext = comment.sourcetext;
+ extra = comment.extra;
+ }
+
+ const QString id = literal->value->asString();
+ bool plural = node->arguments->next;
+
+ TranslatorMessage msg(QString(), sourcetext,
+ QString(), QString(), m_fileName,
+ node->firstSourceLocation().startLine, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ msg.setId(id);
+ msg.setExtras(extra);
+ m_translator->extend(msg);
+ }
+ }
+ }
+ }
+
+private:
+ bool createString(AST::BinaryExpression *b)
+ {
+ if (!b || b->op != 0)
+ return false;
+ AST::BinaryExpression *l = AST::cast<AST::BinaryExpression *>(b->left);
+ AST::BinaryExpression *r = AST::cast<AST::BinaryExpression *>(b->right);
+ AST::StringLiteral *ls = AST::cast<AST::StringLiteral *>(b->left);
+ AST::StringLiteral *rs = AST::cast<AST::StringLiteral *>(b->right);
+ if ((!l && !ls) || (!r && !rs))
+ return false;
+ if (l) {
+ if (!createString(l))
+ return false;
+ } else
+ m_bSource.prepend(ls->value->asString());
+
+ if (r) {
+ if (!createString(r))
+ return false;
+ } else
+ m_bSource.append(rs->value->asString());
+
+ return true;
+ }
+
+ Comment findComment(int loc)
+ {
+ if (comments.isEmpty())
+ return Comment();
+
+ int i = 0;
+ int commentLoc = comments.at(i).lastLine;
+ while (commentLoc <= loc) {
+ if (commentLoc == loc)
+ return comments.at(i);
+ if (i == comments.count()-1)
+ break;
+ commentLoc = comments.at(++i).lastLine;
+ }
+ return Comment();
+ }
+
+ Translator *m_translator;
+ QString m_fileName;
+ QString m_component;
+ QString m_bSource;
+};
+
+QString createErrorString(const QString &filename, const QString &code, Parser &parser)
+{
+ // print out error
+ QStringList lines = code.split(QLatin1Char('\n'));
+ lines.append(QLatin1String("\n")); // sentinel.
+ QString errorString;
+
+ foreach (const DiagnosticMessage &m, parser.diagnosticMessages()) {
+
+ if (m.isWarning())
+ continue;
+
+ QString error = filename + QLatin1Char(':') + QString::number(m.loc.startLine)
+ + QLatin1Char(':') + QString::number(m.loc.startColumn) + QLatin1String(": error: ")
+ + m.message + QLatin1Char('\n');
+
+ int line = 0;
+ if (m.loc.startLine > 0)
+ line = m.loc.startLine - 1;
+
+ const QString textLine = lines.at(line);
+
+ error += textLine + QLatin1Char('\n');
+
+ int column = m.loc.startColumn - 1;
+ if (column < 0)
+ column = 0;
+
+ column = qMin(column, textLine.length());
+
+ for (int i = 0; i < column; ++i) {
+ const QChar ch = textLine.at(i);
+ if (ch.isSpace())
+ error += ch.unicode();
+ else
+ error += QLatin1Char(' ');
+ }
+ error += QLatin1String("^\n");
+ errorString += error;
+ }
+ return errorString;
+}
+
+bool processComment(const QChar *chars, int length, Comment &comment)
+{
+ // Try to match the logic of the QtScript parser.
+ if (!length)
+ return comment.isValid();
+ if (*chars == QLatin1Char(':') && chars[1].isSpace()) {
+ comment.extracomment += QString(chars+1, length-1);
+ } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) {
+ comment.msgid = QString(chars+2, length-2).simplified();
+ } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) {
+ QString text = QString(chars+2, length-2).trimmed();
+ int k = text.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ comment.extra.insert(text.left(k), text.mid(k + 1).trimmed());
+ } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) {
+ comment.sourcetext.reserve(comment.sourcetext.length() + length-2);
+ ushort *ptr = (ushort *)comment.sourcetext.data() + comment.sourcetext.length();
+ int p = 2, c;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"')
+ break;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (c == '\n')
+ break;
+ *ptr++ = '\\';
+ }
+ *ptr++ = c;
+ }
+ }
+ comment.sourcetext.resize(ptr - (ushort *)comment.sourcetext.data());
+ }
+ return comment.isValid();
+}
+
+bool loadQml(Translator &translator, const QString &filename, ConversionData &cd)
+{
+ cd.m_sourceFileName = filename;
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
+ return false;
+ }
+
+ const QString code = QTextStream(&file).readAll();
+
+ Engine driver;
+ Parser parser(&driver);
+
+ NodePool nodePool(filename, &driver);
+ driver.setNodePool(&nodePool);
+
+ Lexer lexer(&driver);
+ lexer.setCode(code, /*line = */ 1);
+ driver.setLexer(&lexer);
+
+ if (parser.parse()) {
+ FindTrCalls trCalls;
+
+ // build up a list of comments that contain translation information.
+ for (int i = 0; i < driver.comments().size(); ++i) {
+ AST::SourceLocation loc = driver.comments().at(i);
+ QString commentStr = code.mid(loc.offset, loc.length);
+
+ if (trCalls.comments.isEmpty() || trCalls.comments.last().lastLine != int(loc.startLine)) {
+ Comment comment;
+ comment.lastLine = loc.startLine+1;
+ if (processComment(commentStr.constData(), commentStr.length(), comment))
+ trCalls.comments.append(comment);
+ } else {
+ Comment &lastComment = trCalls.comments.last();
+ lastComment.lastLine += 1;
+ processComment(commentStr.constData(), commentStr.length(), lastComment);
+ }
+ }
+
+ //find all tr calls in the code
+ trCalls(&translator, filename, parser.ast());
+ } else {
+ QString error = createErrorString(filename, code, parser);
+ cd.appendError(error);
+ return false;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/qscript.cpp b/src/linguist/lupdate/qscript.cpp
new file mode 100644
index 000000000..e53c9dc95
--- /dev/null
+++ b/src/linguist/lupdate/qscript.cpp
@@ -0,0 +1,2612 @@
+// This file was generated by qlalr - DO NOT EDIT!
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#define Q_SCRIPT_REGEXPLITERAL_RULE1 7
+
+#define Q_SCRIPT_REGEXPLITERAL_RULE2 8
+
+#include <translator.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/qdebug.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qtextcodec.h>
+#include <QtCore/qvariant.h>
+
+#include <iostream>
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+static QString MagicComment(QLatin1String("TRANSLATOR"));
+
+class QScriptGrammar
+{
+public:
+ enum {
+ EOF_SYMBOL = 0,
+ T_AND = 1,
+ T_AND_AND = 2,
+ T_AND_EQ = 3,
+ T_AUTOMATIC_SEMICOLON = 62,
+ T_BREAK = 4,
+ T_CASE = 5,
+ T_CATCH = 6,
+ T_COLON = 7,
+ T_COMMA = 8,
+ T_CONST = 81,
+ T_CONTINUE = 9,
+ T_DEBUGGER = 82,
+ T_DEFAULT = 10,
+ T_DELETE = 11,
+ T_DIVIDE_ = 12,
+ T_DIVIDE_EQ = 13,
+ T_DO = 14,
+ T_DOT = 15,
+ T_ELSE = 16,
+ T_EQ = 17,
+ T_EQ_EQ = 18,
+ T_EQ_EQ_EQ = 19,
+ T_FALSE = 80,
+ T_FINALLY = 20,
+ T_FOR = 21,
+ T_FUNCTION = 22,
+ T_GE = 23,
+ T_GT = 24,
+ T_GT_GT = 25,
+ T_GT_GT_EQ = 26,
+ T_GT_GT_GT = 27,
+ T_GT_GT_GT_EQ = 28,
+ T_IDENTIFIER = 29,
+ T_IF = 30,
+ T_IN = 31,
+ T_INSTANCEOF = 32,
+ T_LBRACE = 33,
+ T_LBRACKET = 34,
+ T_LE = 35,
+ T_LPAREN = 36,
+ T_LT = 37,
+ T_LT_LT = 38,
+ T_LT_LT_EQ = 39,
+ T_MINUS = 40,
+ T_MINUS_EQ = 41,
+ T_MINUS_MINUS = 42,
+ T_NEW = 43,
+ T_NOT = 44,
+ T_NOT_EQ = 45,
+ T_NOT_EQ_EQ = 46,
+ T_NULL = 78,
+ T_NUMERIC_LITERAL = 47,
+ T_OR = 48,
+ T_OR_EQ = 49,
+ T_OR_OR = 50,
+ T_PLUS = 51,
+ T_PLUS_EQ = 52,
+ T_PLUS_PLUS = 53,
+ T_QUESTION = 54,
+ T_RBRACE = 55,
+ T_RBRACKET = 56,
+ T_REMAINDER = 57,
+ T_REMAINDER_EQ = 58,
+ T_RESERVED_WORD = 83,
+ T_RETURN = 59,
+ T_RPAREN = 60,
+ T_SEMICOLON = 61,
+ T_STAR = 63,
+ T_STAR_EQ = 64,
+ T_STRING_LITERAL = 65,
+ T_SWITCH = 66,
+ T_THIS = 67,
+ T_THROW = 68,
+ T_TILDE = 69,
+ T_TRUE = 79,
+ T_TRY = 70,
+ T_TYPEOF = 71,
+ T_VAR = 72,
+ T_VOID = 73,
+ T_WHILE = 74,
+ T_WITH = 75,
+ T_XOR = 76,
+ T_XOR_EQ = 77,
+
+ ACCEPT_STATE = 236,
+ RULE_COUNT = 267,
+ STATE_COUNT = 465,
+ TERMINAL_COUNT = 84,
+ NON_TERMINAL_COUNT = 88,
+
+ GOTO_INDEX_OFFSET = 465,
+ GOTO_INFO_OFFSET = 1374,
+ GOTO_CHECK_OFFSET = 1374
+ };
+
+ static const char *const spell [];
+ static const int lhs [];
+ static const int rhs [];
+ static const int goto_default [];
+ static const int action_default [];
+ static const int action_index [];
+ static const int action_info [];
+ static const int action_check [];
+
+ static inline int nt_action (int state, int nt)
+ {
+ const int *const goto_index = &action_index [GOTO_INDEX_OFFSET];
+ const int *const goto_check = &action_check [GOTO_CHECK_OFFSET];
+
+ const int yyn = goto_index [state] + nt;
+
+ if (yyn < 0 || goto_check [yyn] != nt)
+ return goto_default [nt];
+
+ const int *const goto_info = &action_info [GOTO_INFO_OFFSET];
+ return goto_info [yyn];
+ }
+
+ static inline int t_action (int state, int token)
+ {
+ const int yyn = action_index [state] + token;
+
+ if (yyn < 0 || action_check [yyn] != token)
+ return - action_default [state];
+
+ return action_info [yyn];
+ }
+};
+
+const char *const QScriptGrammar::spell [] = {
+ "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ";", "continue",
+ "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===",
+ "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier",
+ "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=",
+ "-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=",
+ "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return",
+ ")", ";", 0, "*", "*=", "string literal", "switch", "this", "throw", "~",
+ "try", "typeof", "var", "void", "while", "with", "^", "^=", "null", "true",
+ "false", "const", "debugger", "reserved word"};
+
+const int QScriptGrammar::lhs [] = {
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 87, 87, 91, 91, 86, 86,
+ 92, 92, 93, 93, 93, 93, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 95, 95, 96,
+ 96, 96, 96, 96, 99, 99, 100, 100, 100, 100,
+ 98, 98, 101, 101, 102, 102, 103, 103, 103, 104,
+ 104, 104, 104, 104, 104, 104, 104, 104, 104, 105,
+ 105, 105, 105, 106, 106, 106, 107, 107, 107, 107,
+ 108, 108, 108, 108, 108, 108, 108, 109, 109, 109,
+ 109, 109, 109, 110, 110, 110, 110, 110, 111, 111,
+ 111, 111, 111, 112, 112, 113, 113, 114, 114, 115,
+ 115, 116, 116, 117, 117, 118, 118, 119, 119, 120,
+ 120, 121, 121, 122, 122, 123, 123, 90, 90, 124,
+ 124, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 89, 89, 126, 126, 127, 127, 128,
+ 128, 129, 129, 129, 129, 129, 129, 129, 129, 129,
+ 129, 129, 129, 129, 129, 129, 130, 146, 146, 145,
+ 145, 131, 131, 147, 147, 148, 148, 150, 150, 149,
+ 151, 154, 152, 152, 155, 153, 153, 132, 133, 133,
+ 134, 134, 135, 135, 135, 135, 135, 135, 135, 136,
+ 136, 136, 136, 137, 137, 137, 137, 138, 138, 139,
+ 141, 156, 156, 159, 159, 157, 157, 160, 158, 140,
+ 142, 142, 143, 143, 143, 161, 162, 144, 163, 97,
+ 167, 167, 164, 164, 165, 165, 168, 84, 169, 169,
+ 170, 170, 166, 166, 88, 88, 171};
+
+const int QScriptGrammar:: rhs[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 3, 5, 3, 3, 2, 4, 1, 2, 0, 1,
+ 3, 5, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 4, 3, 3, 1, 2, 2, 2, 4, 3,
+ 2, 3, 1, 3, 1, 1, 1, 2, 2, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 3, 3, 3, 1, 3, 3, 1, 3, 3, 3,
+ 1, 3, 3, 3, 3, 3, 3, 1, 3, 3,
+ 3, 3, 3, 1, 3, 3, 3, 3, 1, 3,
+ 3, 3, 3, 1, 3, 1, 3, 1, 3, 1,
+ 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
+ 3, 1, 3, 1, 5, 1, 5, 1, 3, 1,
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 0, 1, 1, 3, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 3, 1, 2, 0,
+ 1, 3, 3, 1, 1, 1, 3, 1, 3, 2,
+ 2, 2, 0, 1, 2, 0, 1, 1, 2, 2,
+ 7, 5, 7, 7, 5, 9, 10, 7, 8, 2,
+ 2, 3, 3, 2, 2, 3, 3, 3, 3, 5,
+ 5, 3, 5, 1, 2, 0, 1, 4, 3, 3,
+ 3, 3, 3, 3, 4, 5, 2, 1, 8, 8,
+ 1, 3, 0, 1, 0, 1, 1, 1, 1, 2,
+ 1, 1, 0, 1, 0, 1, 2};
+
+const int QScriptGrammar::action_default [] = {
+ 0, 97, 164, 128, 136, 132, 172, 179, 76, 148,
+ 178, 186, 174, 124, 0, 175, 262, 61, 176, 177,
+ 182, 77, 140, 144, 65, 94, 75, 80, 60, 0,
+ 114, 180, 101, 259, 258, 261, 183, 0, 194, 0,
+ 248, 0, 8, 9, 0, 5, 0, 263, 2, 0,
+ 265, 19, 0, 0, 0, 0, 0, 3, 6, 0,
+ 0, 166, 208, 7, 0, 1, 0, 0, 4, 0,
+ 0, 195, 0, 0, 0, 184, 185, 90, 0, 173,
+ 181, 0, 0, 77, 96, 263, 2, 265, 79, 78,
+ 0, 0, 0, 92, 93, 91, 0, 264, 253, 254,
+ 0, 251, 0, 252, 0, 255, 256, 0, 257, 250,
+ 260, 0, 266, 0, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 23,
+ 41, 42, 43, 44, 45, 25, 46, 47, 24, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 0,
+ 21, 0, 0, 0, 22, 13, 95, 0, 125, 0,
+ 0, 0, 0, 115, 0, 0, 0, 0, 0, 0,
+ 105, 0, 0, 0, 99, 100, 98, 103, 107, 106,
+ 104, 102, 117, 116, 118, 0, 133, 0, 129, 68,
+ 0, 0, 0, 70, 59, 58, 0, 0, 69, 165,
+ 0, 73, 71, 0, 72, 74, 209, 210, 0, 161,
+ 154, 152, 159, 160, 158, 157, 163, 156, 155, 153,
+ 162, 149, 0, 137, 0, 0, 141, 0, 0, 145,
+ 67, 0, 0, 63, 0, 62, 267, 224, 0, 225,
+ 226, 227, 220, 0, 221, 222, 223, 81, 0, 0,
+ 0, 0, 0, 213, 214, 170, 168, 130, 138, 134,
+ 150, 126, 171, 0, 77, 142, 146, 119, 108, 0,
+ 0, 127, 0, 0, 0, 0, 120, 0, 0, 0,
+ 0, 0, 112, 110, 113, 111, 109, 122, 121, 123,
+ 0, 135, 0, 131, 0, 169, 77, 0, 151, 166,
+ 167, 0, 166, 0, 0, 216, 0, 0, 0, 218,
+ 0, 139, 0, 0, 143, 0, 0, 147, 206, 0,
+ 198, 207, 201, 0, 205, 0, 166, 199, 0, 166,
+ 0, 0, 217, 0, 0, 0, 219, 264, 253, 0,
+ 0, 255, 0, 249, 0, 240, 0, 0, 0, 212,
+ 0, 211, 188, 191, 0, 27, 30, 31, 248, 34,
+ 35, 5, 39, 40, 2, 41, 44, 3, 6, 166,
+ 7, 48, 1, 50, 4, 52, 53, 54, 55, 56,
+ 57, 189, 187, 65, 66, 64, 0, 228, 229, 0,
+ 0, 0, 231, 236, 234, 237, 0, 0, 235, 236,
+ 0, 232, 0, 233, 190, 239, 0, 190, 238, 0,
+ 241, 242, 0, 190, 243, 244, 0, 0, 245, 0,
+ 0, 0, 246, 247, 83, 82, 0, 0, 0, 215,
+ 0, 0, 0, 230, 0, 20, 0, 17, 19, 11,
+ 0, 16, 12, 18, 15, 10, 0, 14, 87, 85,
+ 89, 86, 84, 88, 203, 196, 0, 204, 200, 0,
+ 202, 192, 0, 193, 197};
+
+const int QScriptGrammar::goto_default [] = {
+ 29, 28, 436, 434, 113, 14, 2, 435, 112, 111,
+ 114, 193, 24, 17, 189, 26, 8, 200, 21, 27,
+ 77, 25, 1, 32, 30, 267, 13, 261, 3, 257,
+ 5, 259, 4, 258, 22, 265, 23, 266, 9, 260,
+ 256, 297, 386, 262, 263, 35, 6, 79, 12, 15,
+ 18, 19, 10, 7, 31, 80, 20, 36, 75, 76,
+ 11, 354, 353, 78, 456, 455, 319, 320, 458, 322,
+ 457, 321, 392, 396, 399, 395, 394, 414, 415, 16,
+ 100, 107, 96, 99, 106, 108, 33, 0};
+
+const int QScriptGrammar::action_index [] = {
+ 1210, 59, -84, 71, 41, -1, -84, -84, 148, -84,
+ -84, -84, -84, 201, 130, -84, -84, -84, -84, -84,
+ -84, 343, 67, 62, 122, 109, -84, -84, -84, 85,
+ 273, -84, 184, -84, 1210, -84, -84, 119, -84, 112,
+ -84, 521, -84, -84, 1130, -84, 45, 54, 58, 38,
+ 1290, 50, 521, 521, 521, 376, 521, -84, -84, 521,
+ 521, 521, -84, -84, 25, -84, 521, 521, -84, 43,
+ 521, -84, 521, 18, 15, -84, -84, -84, 24, -84,
+ -84, 521, 521, 64, 153, 27, -84, 1050, -84, -84,
+ 521, 521, 521, -84, -84, -84, 28, -84, 37, 55,
+ 19, -84, 33, -84, 34, 1210, -84, 16, 1210, -84,
+ -84, 39, 52, -3, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, 521,
+ -84, 1050, 125, 521, -84, -84, 155, 521, 189, 521,
+ 521, 521, 521, 248, 521, 521, 521, 521, 521, 521,
+ 243, 521, 521, 521, 75, 82, 94, 177, 184, 184,
+ 184, 184, 263, 283, 298, 521, 44, 521, 77, -84,
+ 970, 521, 817, -84, -84, -84, 95, 521, -84, -84,
+ 93, -84, -84, 521, -84, -84, -84, -84, 521, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, 521, 41, 521, 521, 68, 66, 521, -84,
+ -84, 970, 521, -84, 103, -84, -84, -84, 63, -84,
+ -84, -84, -84, 69, -84, -84, -84, -84, -27, 12,
+ 521, 92, 100, -84, -84, 890, -84, 31, -13, -45,
+ -84, 210, 32, -28, 387, 20, 73, 304, 117, -5,
+ 521, 212, 521, 521, 521, 521, 213, 521, 521, 521,
+ 521, 521, 151, 150, 176, 158, 168, 304, 304, 228,
+ 521, -72, 521, 4, 521, -84, 306, 521, -84, 521,
+ 8, -50, 521, -48, 1130, -84, 521, 80, 1130, -84,
+ 521, -33, 521, 521, 5, 48, 521, -84, 17, 88,
+ 11, -84, -84, 521, -84, -29, 521, -84, -41, 521,
+ -39, 1130, -84, 521, 87, 1130, -84, -8, -2, -35,
+ 10, 1210, -16, -84, 1130, -84, 521, 86, 1130, -14,
+ 1130, -84, -84, 1130, -36, 107, -21, 165, 3, 521,
+ 1130, 6, 14, 61, 7, -19, 448, -4, -6, 671,
+ 29, 13, 23, 521, 30, -10, 521, 9, 521, -30,
+ -18, -84, -84, 164, -84, -84, 46, -84, -84, 521,
+ 111, -24, -84, 36, -84, 40, 99, 521, -84, 21,
+ 22, -84, -11, -84, 1130, -84, 106, 1130, -84, 178,
+ -84, -84, 98, 1130, 57, -84, 56, 60, -84, 51,
+ 26, 35, -84, -84, -84, -84, 521, 97, 1130, -84,
+ 521, 90, 1130, -84, 79, 76, 744, -84, 49, -84,
+ 594, -84, -84, -84, -84, -84, 83, -84, -84, -84,
+ -84, -84, -84, -84, 42, -84, 162, -84, -84, 521,
+ -84, -84, 53, -84, -84,
+
+ -61, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -4, -88, -88, 22, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -51, -88, -88, -88, -88, -88,
+ -88, 105, -88, -88, -12, -88, -88, -88, -88, -88,
+ -7, -88, 35, 132, 62, 154, 79, -88, -88, 100,
+ 75, 36, -88, -88, -88, -88, 37, 70, -88, -1,
+ 86, -88, 92, -88, -88, -88, -88, -88, -88, -88,
+ -88, 90, 95, -88, -88, -88, -88, -88, -88, -88,
+ 87, 82, 74, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -47, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, 28,
+ -88, 20, -88, 19, -88, -88, -88, 39, -88, 42,
+ 43, 106, 61, -88, 63, 55, 52, 53, 91, 125,
+ -88, 120, 123, 118, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, 116, -88, 59, -88, -88,
+ 16, 18, 15, -88, -88, -88, -88, 21, -88, -88,
+ -88, -88, -88, 24, -88, -88, -88, -88, 38, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, 97, -88, 115, 25, -88, -88, 26, -88,
+ -88, 111, 14, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ 23, -88, -88, -88, -88, 108, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ 160, -88, 171, 163, 145, 179, -88, 135, 45, 41,
+ 66, 80, -88, -88, -88, -88, -88, -88, -88, -88,
+ 172, -88, 156, -88, 142, -88, -88, 144, -88, 122,
+ -88, -88, 114, -88, -23, -88, 48, -88, 29, -88,
+ 224, -88, 157, 175, -88, -88, 182, -88, -88, -88,
+ -88, -88, -88, 183, -88, -21, 134, -88, -88, 49,
+ -88, 3, -88, 44, -88, 2, -88, -88, -37, -88,
+ -88, -31, -88, -88, 10, -88, 47, -88, 17, -88,
+ 27, -88, -88, 13, -88, -88, -88, -88, -88, 117,
+ 6, -88, -88, -88, -88, -88, 154, -88, -88, 1,
+ -88, -88, -88, 7, -88, -35, 137, -88, 141, -88,
+ -88, -88, -88, -6, -88, -88, -88, -88, -88, 78,
+ -88, -88, -88, -88, -88, -69, -88, 11, -88, -59,
+ -88, -88, -88, -88, 83, -88, -88, 56, -88, -88,
+ -88, -88, -88, -40, -58, -88, -88, -29, -88, -88,
+ -88, -45, -88, -88, -88, -88, -3, -88, -42, -88,
+ -5, -88, -32, -88, -88, -88, 9, -88, 8, -88,
+ -2, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, -88, -88, -88, -88, -88, -88, -88, -88, 12,
+ -88, -88, -56, -88, -88};
+
+const int QScriptGrammar::action_info [] = {
+ 318, -25, 350, -45, 292, 270, 426, 310, -194, 393,
+ -32, 302, 304, -37, 344, 290, 197, 346, 430, 382,
+ 329, 331, 310, 413, 318, 340, 397, 101, 338, 404,
+ -49, 292, 270, 299, 323, 290, -24, -51, -195, 343,
+ 294, 397, 333, 341, 403, 397, 149, 249, 250, 389,
+ 255, 430, 155, 454, 426, 316, 97, 437, 437, 459,
+ 151, 389, 103, 102, 98, 344, 101, 105, 413, 222,
+ 222, 109, 157, 228, 346, 187, 413, 417, 157, 104,
+ 420, 255, 454, 337, 443, 236, 421, 438, 197, 185,
+ 97, 197, 419, 413, 197, 197, 325, -263, 197, 81,
+ 197, 203, 0, 197, 416, 197, 88, 388, 387, 400,
+ 82, 197, 224, 407, 197, 81, 225, 89, 417, 197,
+ 187, 90, 81, 312, 241, 240, 82, 313, 0, 0,
+ 246, 245, 153, 82, 81, 439, 238, 231, 197, 0,
+ 308, 243, 171, 447, 172, 82, 348, 335, 238, 326,
+ 432, 198, 252, 204, 401, 173, 232, 428, 192, 235,
+ 0, 254, 253, 190, 0, 90, 91, 90, 239, 237,
+ 462, 391, 92, 244, 242, 171, 171, 172, 172, 231,
+ 239, 237, 191, 171, 192, 172, 197, 0, 173, 173,
+ 0, 207, 206, 171, 243, 172, 173, 0, 232, 0,
+ 192, 171, 171, 172, 172, 0, 173, 159, 160, 171,
+ 91, 172, 91, 0, 173, 173, 92, 0, 92, 159,
+ 160, 0, 173, 463, 461, 0, 244, 242, 272, 273,
+ 272, 273, 0, 0, 161, 162, 277, 278, 0, 411,
+ 410, 0, 0, 0, 0, 279, 161, 162, 280, 0,
+ 281, 277, 278, 0, 0, 274, 275, 274, 275, 0,
+ 279, 0, 0, 280, 0, 281, 0, 0, 171, 0,
+ 172, 164, 165, 0, 0, 0, 0, 0, 0, 166,
+ 167, 173, 0, 168, 0, 169, 164, 165, 0, 0,
+ 0, 0, 0, 0, 166, 167, 164, 165, 168, 0,
+ 169, 0, 0, 0, 166, 167, 164, 165, 168, 209,
+ 169, 0, 0, 0, 166, 167, 0, 0, 168, 210,
+ 169, 164, 165, 211, 0, 0, 0, 277, 278, 166,
+ 167, 0, 212, 168, 213, 169, 279, 0, 0, 280,
+ 0, 281, 0, 0, 0, 214, 209, 215, 88, 0,
+ 0, 0, 0, 0, 0, 216, 210, 0, 217, 89,
+ 211, 0, 0, 0, 218, 0, 0, 0, 0, 212,
+ 219, 213, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 214, 220, 215, 88, 0, 0, 42, 43,
+ 209, 0, 216, 0, 0, 217, 89, 0, 85, 0,
+ 210, 218, 0, 0, 211, 86, 0, 219, 0, 87,
+ 51, 0, 52, 212, 0, 213, 0, 0, 306, 55,
+ 220, 0, 0, 58, 0, 0, 214, 0, 215, 88,
+ 0, 0, 0, 0, 0, 0, 216, 0, 0, 217,
+ 89, 63, 0, 65, 0, 218, 0, 0, 0, 0,
+ 0, 219, 0, 0, 57, 68, 45, 0, 0, 0,
+ 42, 43, 0, 0, 220, 0, 0, 0, 0, 0,
+ 85, 0, 0, 0, 0, 0, 0, 86, 0, 0,
+ 0, 87, 51, 0, 52, 0, 0, 0, 0, 0,
+ 0, 55, 0, 0, 0, 58, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 63, 0, 65, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 57, 68, 45, 0,
+ 0, 0, 41, 42, 43, 0, 0, 0, 0, 0,
+ 0, 0, 0, 85, 0, 0, 0, 0, 0, 0,
+ 86, 0, 0, 0, 87, 51, 0, 52, 0, 0,
+ 0, 53, 0, 54, 55, 56, 0, 0, 58, 0,
+ 0, 0, 59, 0, 60, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 63, 0, 65, 0,
+ 67, 0, 70, 0, 72, 0, 0, 0, 0, 57,
+ 68, 45, 0, 0, 0, 41, 42, 43, 0, 0,
+ 0, 0, 0, 0, 0, 0, 85, 0, 0, 0,
+ 0, 0, 0, 86, 0, 0, 0, 87, 51, 0,
+ 52, 0, 0, 0, 53, 0, 54, 55, 56, 0,
+ 0, 58, 0, 0, 0, 59, 0, 60, 0, 0,
+ 442, 0, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 65, 0, 67, 0, 70, 0, 72, 0, 0,
+ 0, 0, 57, 68, 45, 0, 0, 0, -47, 0,
+ 0, 0, 41, 42, 43, 0, 0, 0, 0, 0,
+ 0, 0, 0, 85, 0, 0, 0, 0, 0, 0,
+ 86, 0, 0, 0, 87, 51, 0, 52, 0, 0,
+ 0, 53, 0, 54, 55, 56, 0, 0, 58, 0,
+ 0, 0, 59, 0, 60, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 63, 0, 65, 0,
+ 67, 0, 70, 0, 72, 0, 0, 0, 0, 57,
+ 68, 45, 0, 0, 0, 41, 42, 43, 0, 0,
+ 0, 0, 0, 0, 0, 0, 85, 0, 0, 0,
+ 0, 0, 0, 86, 0, 0, 0, 87, 51, 0,
+ 52, 0, 0, 0, 53, 0, 54, 55, 56, 0,
+ 0, 58, 0, 0, 0, 59, 0, 60, 0, 0,
+ 445, 0, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 65, 0, 67, 0, 70, 0, 72, 0, 0,
+ 0, 0, 57, 68, 45, 0, 0, 0, 41, 42,
+ 43, 0, 0, 0, 0, 0, 0, 0, 0, 85,
+ 0, 0, 0, 0, 0, 0, 86, 0, 0, 0,
+ 87, 51, 0, 52, 0, 0, 0, 53, 0, 54,
+ 55, 56, 0, 0, 58, 0, 0, 0, 59, 0,
+ 60, 0, 0, 0, 0, 0, 0, 202, 0, 0,
+ 0, 0, 63, 0, 65, 0, 67, 0, 70, 0,
+ 72, 0, 0, 0, 0, 57, 68, 45, 0, 0,
+ 0, 41, 42, 43, 0, 0, 0, 0, 0, 0,
+ 0, 0, 85, 0, 0, 0, 0, 0, 0, 86,
+ 0, 0, 0, 87, 51, 0, 52, 0, 0, 0,
+ 53, 0, 54, 55, 56, 0, 0, 58, 0, 0,
+ 0, 59, 0, 60, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 63, 0, 65, 0, 67,
+ 0, 70, 269, 72, 0, 0, 0, 0, 57, 68,
+ 45, 0, 0, 0, 115, 116, 117, 0, 0, 119,
+ 121, 122, 0, 0, 123, 0, 124, 0, 0, 0,
+ 126, 127, 128, 0, 0, 0, 0, 0, 0, 195,
+ 130, 131, 132, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 133, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 137,
+ 0, 0, 0, 0, 0, 0, 139, 140, 141, 0,
+ 143, 144, 145, 146, 147, 148, 0, 0, 134, 142,
+ 125, 118, 120, 136, 115, 116, 117, 0, 0, 119,
+ 121, 122, 0, 0, 123, 0, 124, 0, 0, 0,
+ 126, 127, 128, 0, 0, 0, 0, 0, 0, 129,
+ 130, 131, 132, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 133, 0, 0, 0, 135, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 137,
+ 0, 0, 0, 0, 0, 138, 139, 140, 141, 0,
+ 143, 144, 145, 146, 147, 148, 0, 0, 134, 142,
+ 125, 118, 120, 136, 37, 0, 0, 0, 0, 39,
+ 0, 41, 42, 43, 44, 0, 0, 0, 0, 0,
+ 0, 46, 85, 0, 0, 0, 0, 0, 0, 48,
+ 49, 0, 0, 50, 51, 0, 52, 0, 0, 0,
+ 53, 0, 54, 55, 56, 0, 0, 58, 0, 0,
+ 0, 59, 0, 60, 0, 0, 0, 0, 0, 61,
+ 0, 62, 0, 0, 0, 63, 64, 65, 66, 67,
+ 69, 70, 71, 72, 73, 74, 0, 0, 57, 68,
+ 45, 38, 40, 0, 37, 0, 0, 0, 0, 39,
+ 0, 41, 42, 43, 44, 0, 0, 0, 0, 0,
+ 0, 46, 47, 0, 0, 0, 0, 0, 0, 48,
+ 49, 0, 0, 50, 51, 0, 52, 0, 0, 0,
+ 53, 0, 54, 55, 56, 0, 0, 58, 0, 0,
+ 0, 59, 0, 60, 0, 0, 0, 0, 0, 61,
+ 0, 62, 0, 0, 0, 63, 64, 65, 66, 67,
+ 69, 70, 71, 72, 73, 74, 0, 0, 57, 68,
+ 45, 38, 40, 0, 355, 116, 117, 0, 0, 357,
+ 121, 359, 42, 43, 360, 0, 124, 0, 0, 0,
+ 126, 362, 363, 0, 0, 0, 0, 0, 0, 364,
+ 365, 131, 132, 50, 51, 0, 52, 0, 0, 0,
+ 53, 0, 54, 366, 56, 0, 0, 368, 0, 0,
+ 0, 59, 0, 60, 0, -190, 0, 0, 0, 369,
+ 0, 62, 0, 0, 0, 370, 371, 372, 373, 67,
+ 375, 376, 377, 378, 379, 380, 0, 0, 367, 374,
+ 361, 356, 358, 136,
+
+ 431, 422, 427, 429, 441, 352, 300, 398, 385, 464,
+ 440, 412, 409, 433, 402, 444, 406, 423, 460, 234,
+ 418, 201, 305, 196, 34, 154, 194, 199, 251, 152,
+ 205, 227, 229, 248, 150, 110, 230, 208, 352, 110,
+ 446, 300, 409, 339, 221, 412, 327, 336, 332, 334,
+ 342, 248, 347, 307, 300, 345, 0, 83, 381, 83,
+ 83, 83, 349, 83, 284, 158, 163, 182, 283, 0,
+ 83, 83, 351, 83, 309, 178, 179, 83, 177, 83,
+ 83, 83, 449, 390, 83, 184, 170, 188, 83, 285,
+ 453, 330, 83, 83, 95, 452, 0, 83, 83, 450,
+ 83, 352, 94, 286, 83, 83, 424, 93, 83, 83,
+ 83, 84, 425, 83, 180, 83, 156, 408, 83, 300,
+ 451, 194, 233, 83, 83, 247, 264, 300, 352, 223,
+ 183, 268, 0, 83, 83, 83, 83, 247, 83, 300,
+ 176, 83, 174, 83, 405, 175, 186, 0, 181, 226,
+ 83, 0, 448, 83, 0, 83, 303, 424, 282, 83,
+ 296, 425, 296, 83, 301, 268, 383, 268, 268, 384,
+ 288, 0, 0, 0, 83, 83, 328, 0, 83, 268,
+ 268, 83, 295, 268, 298, 293, 268, 271, 287, 83,
+ 83, 0, 314, 296, 268, 268, 276, 83, 268, 0,
+ 296, 296, 268, 291, 289, 268, 268, 0, 0, 0,
+ 0, 0, 0, 0, 0, 315, 0, 0, 0, 0,
+ 0, 0, 317, 324, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 83, 0, 0, 0, 0, 268, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 311, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0};
+
+const int QScriptGrammar::action_check [] = {
+ 29, 7, 16, 7, 76, 1, 36, 2, 29, 33,
+ 7, 61, 60, 7, 7, 48, 8, 36, 36, 55,
+ 61, 60, 2, 33, 29, 60, 5, 29, 36, 7,
+ 7, 76, 1, 61, 17, 48, 7, 7, 29, 55,
+ 8, 5, 31, 33, 55, 5, 7, 74, 36, 36,
+ 36, 36, 55, 29, 36, 7, 29, 8, 8, 17,
+ 8, 36, 29, 8, 36, 7, 29, 33, 33, 2,
+ 2, 55, 1, 7, 36, 76, 33, 20, 1, 60,
+ 29, 36, 29, 29, 8, 0, 60, 8, 8, 48,
+ 29, 8, 36, 33, 8, 8, 8, 36, 8, 40,
+ 8, 8, -1, 8, 6, 8, 42, 61, 62, 10,
+ 51, 8, 50, 7, 8, 40, 54, 53, 20, 8,
+ 76, 12, 40, 50, 61, 62, 51, 54, -1, -1,
+ 61, 62, 7, 51, 40, 56, 29, 15, 8, -1,
+ 60, 29, 25, 60, 27, 51, 60, 60, 29, 61,
+ 60, 56, 60, 60, 55, 38, 34, 60, 36, 56,
+ -1, 61, 62, 15, -1, 12, 57, 12, 61, 62,
+ 8, 60, 63, 61, 62, 25, 25, 27, 27, 15,
+ 61, 62, 34, 25, 36, 27, 8, -1, 38, 38,
+ -1, 61, 62, 25, 29, 27, 38, -1, 34, -1,
+ 36, 25, 25, 27, 27, -1, 38, 18, 19, 25,
+ 57, 27, 57, -1, 38, 38, 63, -1, 63, 18,
+ 19, -1, 38, 61, 62, -1, 61, 62, 18, 19,
+ 18, 19, -1, -1, 45, 46, 23, 24, -1, 61,
+ 62, -1, -1, -1, -1, 32, 45, 46, 35, -1,
+ 37, 23, 24, -1, -1, 45, 46, 45, 46, -1,
+ 32, -1, -1, 35, -1, 37, -1, -1, 25, -1,
+ 27, 23, 24, -1, -1, -1, -1, -1, -1, 31,
+ 32, 38, -1, 35, -1, 37, 23, 24, -1, -1,
+ -1, -1, -1, -1, 31, 32, 23, 24, 35, -1,
+ 37, -1, -1, -1, 31, 32, 23, 24, 35, 3,
+ 37, -1, -1, -1, 31, 32, -1, -1, 35, 13,
+ 37, 23, 24, 17, -1, -1, -1, 23, 24, 31,
+ 32, -1, 26, 35, 28, 37, 32, -1, -1, 35,
+ -1, 37, -1, -1, -1, 39, 3, 41, 42, -1,
+ -1, -1, -1, -1, -1, 49, 13, -1, 52, 53,
+ 17, -1, -1, -1, 58, -1, -1, -1, -1, 26,
+ 64, 28, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 39, 77, 41, 42, -1, -1, 12, 13,
+ 3, -1, 49, -1, -1, 52, 53, -1, 22, -1,
+ 13, 58, -1, -1, 17, 29, -1, 64, -1, 33,
+ 34, -1, 36, 26, -1, 28, -1, -1, 31, 43,
+ 77, -1, -1, 47, -1, -1, 39, -1, 41, 42,
+ -1, -1, -1, -1, -1, -1, 49, -1, -1, 52,
+ 53, 65, -1, 67, -1, 58, -1, -1, -1, -1,
+ -1, 64, -1, -1, 78, 79, 80, -1, -1, -1,
+ 12, 13, -1, -1, 77, -1, -1, -1, -1, -1,
+ 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
+ -1, 33, 34, -1, 36, -1, -1, -1, -1, -1,
+ -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 65, -1, 67, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 78, 79, 80, -1,
+ -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
+ -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, -1, 67, -1,
+ 69, -1, 71, -1, 73, -1, -1, -1, -1, 78,
+ 79, 80, -1, -1, -1, 11, 12, 13, -1, -1,
+ -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
+ -1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
+ 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
+ -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
+ 56, -1, -1, -1, -1, -1, -1, -1, -1, 65,
+ -1, 67, -1, 69, -1, 71, -1, 73, -1, -1,
+ -1, -1, 78, 79, 80, -1, -1, -1, 7, -1,
+ -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
+ -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, -1, 67, -1,
+ 69, -1, 71, -1, 73, -1, -1, -1, -1, 78,
+ 79, 80, -1, -1, -1, 11, 12, 13, -1, -1,
+ -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
+ -1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
+ 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
+ -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
+ 56, -1, -1, -1, -1, -1, -1, -1, -1, 65,
+ -1, 67, -1, 69, -1, 71, -1, 73, -1, -1,
+ -1, -1, 78, 79, 80, -1, -1, -1, 11, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
+ -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
+ 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
+ 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
+ 53, -1, -1, -1, -1, -1, -1, 60, -1, -1,
+ -1, -1, 65, -1, 67, -1, 69, -1, 71, -1,
+ 73, -1, -1, -1, -1, 78, 79, 80, -1, -1,
+ -1, 11, 12, 13, -1, -1, -1, -1, -1, -1,
+ -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
+ -1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
+ -1, 51, -1, 53, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 65, -1, 67, -1, 69,
+ -1, 71, 72, 73, -1, -1, -1, -1, 78, 79,
+ 80, -1, -1, -1, 4, 5, 6, -1, -1, 9,
+ 10, 11, -1, -1, 14, -1, 16, -1, -1, -1,
+ 20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, 31, 32, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 43, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 59,
+ -1, -1, -1, -1, -1, -1, 66, 67, 68, -1,
+ 70, 71, 72, 73, 74, 75, -1, -1, 78, 79,
+ 80, 81, 82, 83, 4, 5, 6, -1, -1, 9,
+ 10, 11, -1, -1, 14, -1, 16, -1, -1, -1,
+ 20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, 31, 32, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 59,
+ -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
+ 70, 71, 72, 73, 74, 75, -1, -1, 78, 79,
+ 80, 81, 82, 83, 4, -1, -1, -1, -1, 9,
+ -1, 11, 12, 13, 14, -1, -1, -1, -1, -1,
+ -1, 21, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
+ -1, 51, -1, 53, -1, -1, -1, -1, -1, 59,
+ -1, 61, -1, -1, -1, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, -1, -1, 78, 79,
+ 80, 81, 82, -1, 4, -1, -1, -1, -1, 9,
+ -1, 11, 12, 13, 14, -1, -1, -1, -1, -1,
+ -1, 21, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
+ -1, 51, -1, 53, -1, -1, -1, -1, -1, 59,
+ -1, 61, -1, -1, -1, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, -1, -1, 78, 79,
+ 80, 81, 82, -1, 4, 5, 6, -1, -1, 9,
+ 10, 11, 12, 13, 14, -1, 16, -1, -1, -1,
+ 20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, 31, 32, 33, 34, -1, 36, -1, -1, -1,
+ 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
+ -1, 51, -1, 53, -1, 55, -1, -1, -1, 59,
+ -1, 61, -1, -1, -1, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, -1, -1, 78, 79,
+ 80, 81, 82, 83,
+
+ 5, 46, 5, 45, 6, 45, 5, 76, 14, 65,
+ 2, 46, 5, 45, 73, 6, 5, 46, 6, 5,
+ 78, 6, 45, 5, 85, 6, 10, 6, 5, 9,
+ 6, 6, 6, 45, 6, 86, 14, 41, 45, 86,
+ 5, 5, 5, 80, 6, 46, 67, 45, 45, 5,
+ 81, 45, 5, 5, 5, 45, -1, 18, 45, 18,
+ 18, 18, 45, 18, 23, 26, 24, 24, 23, -1,
+ 18, 18, 45, 18, 45, 23, 23, 18, 23, 18,
+ 18, 18, 20, 5, 18, 24, 23, 28, 18, 23,
+ 20, 42, 18, 18, 20, 20, -1, 18, 18, 20,
+ 18, 45, 20, 23, 18, 18, 20, 20, 18, 18,
+ 18, 21, 20, 18, 23, 18, 21, 61, 18, 5,
+ 20, 10, 11, 18, 18, 20, 18, 5, 45, 32,
+ 24, 23, -1, 18, 18, 18, 18, 20, 18, 5,
+ 22, 18, 22, 18, 61, 22, 30, -1, 23, 34,
+ 18, -1, 20, 18, -1, 18, 42, 20, 23, 18,
+ 18, 20, 18, 18, 42, 23, 12, 23, 23, 15,
+ 25, -1, -1, -1, 18, 18, 42, -1, 18, 23,
+ 23, 18, 40, 23, 40, 29, 23, 27, 25, 18,
+ 18, -1, 35, 18, 23, 23, 25, 18, 23, -1,
+ 18, 18, 23, 31, 25, 23, 23, -1, -1, -1,
+ -1, -1, -1, -1, -1, 40, -1, -1, -1, -1,
+ -1, -1, 40, 40, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 18, -1, -1, -1, -1, 23, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 33, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1};
+
+static void recordMessage(
+ Translator *tor, const QString &context, const QString &text, const QString &comment,
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool plural, const QString &fileName, int lineNo)
+{
+ TranslatorMessage msg(
+ context, text, comment, QString(),
+ fileName, lineNo, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ msg.setId(msgid);
+ msg.setExtras(extra);
+ tor->extend(msg);
+}
+
+
+namespace QScript
+{
+
+class CommentProcessor
+{
+public:
+ virtual ~CommentProcessor() {}
+ virtual void processComment(const QChar *chars, int length) = 0;
+};
+
+class Lexer
+{
+public:
+ Lexer(CommentProcessor *);
+ ~Lexer();
+
+ void setCode(const QString &c, const QString &fileName, int lineno);
+ int lex();
+
+ QString fileName() const { return yyfilename; }
+ int currentLineNo() const { return yylineno; }
+ int currentColumnNo() const { return yycolumn; }
+
+ int startLineNo() const { return startlineno; }
+ int startColumnNo() const { return startcolumn; }
+
+ int endLineNo() const { return currentLineNo(); }
+ int endColumnNo() const
+ { int col = currentColumnNo(); return (col > 0) ? col - 1 : col; }
+
+ bool prevTerminator() const { return terminator; }
+
+ enum State { Start,
+ Identifier,
+ InIdentifier,
+ InSingleLineComment,
+ InMultiLineComment,
+ InNum,
+ InNum0,
+ InHex,
+ InOctal,
+ InDecimal,
+ InExponentIndicator,
+ InExponent,
+ Hex,
+ Octal,
+ Number,
+ String,
+ Eof,
+ InString,
+ InEscapeSequence,
+ InHexEscape,
+ InUnicodeEscape,
+ Other,
+ Bad };
+
+ enum Error {
+ NoError,
+ IllegalCharacter,
+ UnclosedStringLiteral,
+ IllegalEscapeSequence,
+ IllegalUnicodeEscapeSequence,
+ UnclosedComment,
+ IllegalExponentIndicator,
+ IllegalIdentifier
+ };
+
+ enum ParenthesesState {
+ IgnoreParentheses,
+ CountParentheses,
+ BalancedParentheses
+ };
+
+ enum RegExpBodyPrefix {
+ NoPrefix,
+ EqualPrefix
+ };
+
+ bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix);
+
+ QString pattern;
+ int flags;
+
+ State lexerState() const
+ { return state; }
+
+ QString errorMessage() const
+ { return errmsg; }
+ void setErrorMessage(const QString &err)
+ { errmsg = err; }
+ void setErrorMessage(const char *err)
+ { setErrorMessage(QString::fromLatin1(err)); }
+
+ Error error() const
+ { return err; }
+ void clearError()
+ { err = NoError; }
+
+private:
+ QString yyfilename;
+ int yylineno;
+ bool done;
+ char *buffer8;
+ QChar *buffer16;
+ uint size8, size16;
+ uint pos8, pos16;
+ bool terminator;
+ bool restrKeyword;
+ // encountered delimiter like "'" and "}" on last run
+ bool delimited;
+ int stackToken;
+
+ State state;
+ void setDone(State s);
+ uint pos;
+ void shift(uint p);
+ int lookupKeyword(const char *);
+
+ bool isWhiteSpace() const;
+ bool isLineTerminator() const;
+ bool isHexDigit(ushort c) const;
+ bool isOctalDigit(ushort c) const;
+
+ int matchPunctuator(ushort c1, ushort c2,
+ ushort c3, ushort c4);
+ ushort singleEscape(ushort c) const;
+ ushort convertOctal(ushort c1, ushort c2,
+ ushort c3) const;
+public:
+ static unsigned char convertHex(ushort c1);
+ static unsigned char convertHex(ushort c1, ushort c2);
+ static QChar convertUnicode(ushort c1, ushort c2,
+ ushort c3, ushort c4);
+ static bool isIdentLetter(ushort c);
+ static bool isDecimalDigit(ushort c);
+
+ inline int ival() const { return qsyylval.toInt(); }
+ inline double dval() const { return qsyylval.toDouble(); }
+ inline QString ustr() const { return qsyylval.toString(); }
+ inline QVariant val() const { return qsyylval; }
+
+ const QChar *characterBuffer() const { return buffer16; }
+ int characterCount() const { return pos16; }
+
+private:
+ void record8(ushort c);
+ void record16(QChar c);
+ void recordStartPos();
+
+ int findReservedWord(const QChar *buffer, int size) const;
+
+ void syncProhibitAutomaticSemicolon();
+
+ void processComment(const QChar *, int);
+
+ const QChar *code;
+ uint length;
+ int yycolumn;
+ int startlineno;
+ int startcolumn;
+ int bol; // begin of line
+
+ QVariant qsyylval;
+
+ // current and following unicode characters
+ ushort current, next1, next2, next3;
+
+ struct keyword {
+ const char *name;
+ int token;
+ };
+
+ QString errmsg;
+ Error err;
+
+ bool wantRx;
+ bool check_reserved;
+
+ ParenthesesState parenthesesState;
+ int parenthesesCount;
+ bool prohibitAutomaticSemicolon;
+
+ CommentProcessor *commentProcessor;
+};
+
+} // namespace QScript
+
+extern double qstrtod(const char *s00, char const **se, bool *ok);
+
+#define shiftWindowsLineBreak() if(current == '\r' && next1 == '\n') shift(1);
+
+namespace QScript {
+
+static int toDigit(char c)
+{
+ if ((c >= '0') && (c <= '9'))
+ return c - '0';
+ else if ((c >= 'a') && (c <= 'z'))
+ return 10 + c - 'a';
+ else if ((c >= 'A') && (c <= 'Z'))
+ return 10 + c - 'A';
+ return -1;
+}
+
+double integerFromString(const char *buf, int size, int radix)
+{
+ if (size == 0)
+ return qSNaN();
+
+ double sign = 1.0;
+ int i = 0;
+ if (buf[0] == '+') {
+ ++i;
+ } else if (buf[0] == '-') {
+ sign = -1.0;
+ ++i;
+ }
+
+ if (((size-i) >= 2) && (buf[i] == '0')) {
+ if (((buf[i+1] == 'x') || (buf[i+1] == 'X'))
+ && (radix < 34)) {
+ if ((radix != 0) && (radix != 16))
+ return 0;
+ radix = 16;
+ i += 2;
+ } else {
+ if (radix == 0) {
+ radix = 8;
+ ++i;
+ }
+ }
+ } else if (radix == 0) {
+ radix = 10;
+ }
+
+ int j = i;
+ for ( ; i < size; ++i) {
+ int d = toDigit(buf[i]);
+ if ((d == -1) || (d >= radix))
+ break;
+ }
+ double result;
+ if (j == i) {
+ if (!qstrcmp(buf, "Infinity"))
+ result = qInf();
+ else
+ result = qSNaN();
+ } else {
+ result = 0;
+ double multiplier = 1;
+ for (--i ; i >= j; --i, multiplier *= radix)
+ result += toDigit(buf[i]) * multiplier;
+ }
+ result *= sign;
+ return result;
+}
+
+} // namespace QScript
+
+QScript::Lexer::Lexer(QScript::CommentProcessor *proc)
+ :
+ yylineno(0),
+ size8(128), size16(128), restrKeyword(false),
+ stackToken(-1), pos(0),
+ code(0), length(0),
+ bol(true),
+ current(0), next1(0), next2(0), next3(0),
+ err(NoError),
+ check_reserved(true),
+ parenthesesState(IgnoreParentheses),
+ prohibitAutomaticSemicolon(false),
+ commentProcessor(proc)
+{
+ // allocate space for read buffers
+ buffer8 = new char[size8];
+ buffer16 = new QChar[size16];
+ flags = 0;
+
+}
+
+QScript::Lexer::~Lexer()
+{
+ delete [] buffer8;
+ delete [] buffer16;
+}
+
+void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno)
+{
+ errmsg = QString();
+ yyfilename = fileName;
+ yylineno = lineno;
+ yycolumn = 1;
+ restrKeyword = false;
+ delimited = false;
+ stackToken = -1;
+ pos = 0;
+ code = c.unicode();
+ length = c.length();
+ bol = true;
+
+ // read first characters
+ current = (length > 0) ? code[0].unicode() : 0;
+ next1 = (length > 1) ? code[1].unicode() : 0;
+ next2 = (length > 2) ? code[2].unicode() : 0;
+ next3 = (length > 3) ? code[3].unicode() : 0;
+}
+
+void QScript::Lexer::shift(uint p)
+{
+ while (p--) {
+ ++pos;
+ ++yycolumn;
+ current = next1;
+ next1 = next2;
+ next2 = next3;
+ next3 = (pos + 3 < length) ? code[pos+3].unicode() : 0;
+ }
+}
+
+void QScript::Lexer::setDone(State s)
+{
+ state = s;
+ done = true;
+}
+
+int QScript::Lexer::findReservedWord(const QChar *c, int size) const
+{
+ switch (size) {
+ case 2: {
+ if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o'))
+ return QScriptGrammar::T_DO;
+ else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('f'))
+ return QScriptGrammar::T_IF;
+ else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n'))
+ return QScriptGrammar::T_IN;
+ } break;
+
+ case 3: {
+ if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('o') && c[2] == QLatin1Char('r'))
+ return QScriptGrammar::T_FOR;
+ else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('e') && c[2] == QLatin1Char('w'))
+ return QScriptGrammar::T_NEW;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') && c[2] == QLatin1Char('y'))
+ return QScriptGrammar::T_TRY;
+ else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('a') && c[2] == QLatin1Char('r'))
+ return QScriptGrammar::T_VAR;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') && c[2] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 4: {
+ if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
+ return QScriptGrammar::T_CASE;
+ else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('l')
+ && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
+ return QScriptGrammar::T_ELSE;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('s'))
+ return QScriptGrammar::T_THIS;
+ else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('d'))
+ return QScriptGrammar::T_VOID;
+ else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('i')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('h'))
+ return QScriptGrammar::T_WITH;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('e'))
+ return QScriptGrammar::T_TRUE;
+ else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('u')
+ && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('l'))
+ return QScriptGrammar::T_NULL;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('n')
+ && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('m'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('y')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('l') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('g'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('r'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('g') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('o'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 5: {
+ if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('e') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('k'))
+ return QScriptGrammar::T_BREAK;
+ else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('c')
+ && c[4] == QLatin1Char('h'))
+ return QScriptGrammar::T_CATCH;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
+ && c[4] == QLatin1Char('w'))
+ return QScriptGrammar::T_THROW;
+ else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('l')
+ && c[4] == QLatin1Char('e'))
+ return QScriptGrammar::T_WHILE;
+ else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('s')
+ && c[4] == QLatin1Char('t'))
+ return QScriptGrammar::T_CONST;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('s')
+ && c[4] == QLatin1Char('e'))
+ return QScriptGrammar::T_FALSE;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('r')
+ && c[4] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('u')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('r'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('l'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('l')
+ && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('s')
+ && c[4] == QLatin1Char('s'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('l')
+ && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 6: {
+ if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
+ && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('e'))
+ return QScriptGrammar::T_DELETE;
+ else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('u')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('n'))
+ return QScriptGrammar::T_RETURN;
+ else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('w')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('c') && c[5] == QLatin1Char('h'))
+ return QScriptGrammar::T_SWITCH;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('y')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('o') && c[5] == QLatin1Char('f'))
+ return QScriptGrammar::T_TYPEOF;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('t')
+ && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('b')
+ && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('u')
+ && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('l')
+ && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('i')
+ && c[4] == QLatin1Char('v') && c[5] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
+ && c[4] == QLatin1Char('w') && c[5] == QLatin1Char('s'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 7: {
+ if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
+ && c[2] == QLatin1Char('f') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('u') && c[5] == QLatin1Char('l')
+ && c[6] == QLatin1Char('t'))
+ return QScriptGrammar::T_DEFAULT;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('l')
+ && c[6] == QLatin1Char('y'))
+ return QScriptGrammar::T_FINALLY;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('l')
+ && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('a')
+ && c[6] == QLatin1Char('n'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('n') && c[5] == QLatin1Char('d')
+ && c[6] == QLatin1Char('s'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('c') && c[3] == QLatin1Char('k')
+ && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('g')
+ && c[6] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('v')
+ && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('t')
+ && c[6] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 8: {
+ if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('n')
+ && c[6] == QLatin1Char('u') && c[7] == QLatin1Char('e'))
+ return QScriptGrammar::T_CONTINUE;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('u')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
+ && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
+ && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n'))
+ return QScriptGrammar::T_FUNCTION;
+ else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
+ && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('u')
+ && c[4] == QLatin1Char('g') && c[5] == QLatin1Char('g')
+ && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('r'))
+ return QScriptGrammar::T_DEBUGGER;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('b')
+ && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('a')
+ && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
+ && c[6] == QLatin1Char('l') && c[7] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 9: {
+ if (check_reserved) {
+ if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('f')
+ && c[6] == QLatin1Char('a') && c[7] == QLatin1Char('c')
+ && c[8] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('n')
+ && c[4] == QLatin1Char('s') && c[5] == QLatin1Char('i')
+ && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
+ && c[8] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('c')
+ && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('e')
+ && c[8] == QLatin1Char('d'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 10: {
+ if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
+ && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('n')
+ && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('e')
+ && c[8] == QLatin1Char('o') && c[9] == QLatin1Char('f'))
+ return QScriptGrammar::T_INSTANCEOF;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('l')
+ && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('m')
+ && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
+ && c[8] == QLatin1Char('t') && c[9] == QLatin1Char('s'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 12: {
+ if (check_reserved) {
+ if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('y')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
+ && c[4] == QLatin1Char('h') && c[5] == QLatin1Char('r')
+ && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n')
+ && c[8] == QLatin1Char('i') && c[9] == QLatin1Char('z')
+ && c[10] == QLatin1Char('e') && c[11] == QLatin1Char('d'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ } // switch
+
+ return -1;
+}
+
+int QScript::Lexer::lex()
+{
+ int token = 0;
+ state = Start;
+ ushort stringType = 0; // either single or double quotes
+ pos8 = pos16 = 0;
+ done = false;
+ terminator = false;
+
+ // did we push a token on the stack previously ?
+ // (after an automatic semicolon insertion)
+ if (stackToken >= 0) {
+ setDone(Other);
+ token = stackToken;
+ stackToken = -1;
+ }
+
+ while (!done) {
+ switch (state) {
+ case Start:
+ if (isWhiteSpace()) {
+ // do nothing
+ } else if (current == '/' && next1 == '/') {
+ recordStartPos();
+ shift(1);
+ Q_ASSERT(pos16 == 0);
+ state = InSingleLineComment;
+ } else if (current == '/' && next1 == '*') {
+ recordStartPos();
+ shift(1);
+ Q_ASSERT(pos16 == 0);
+ state = InMultiLineComment;
+ } else if (current == 0) {
+ syncProhibitAutomaticSemicolon();
+ if (!terminator && !delimited && !prohibitAutomaticSemicolon) {
+ // automatic semicolon insertion if program incomplete
+ token = QScriptGrammar::T_SEMICOLON;
+ stackToken = 0;
+ setDone(Other);
+ } else {
+ setDone(Eof);
+ }
+ } else if (isLineTerminator()) {
+ shiftWindowsLineBreak();
+ yylineno++;
+ yycolumn = 0;
+ bol = true;
+ terminator = true;
+ syncProhibitAutomaticSemicolon();
+ if (restrKeyword) {
+ token = QScriptGrammar::T_SEMICOLON;
+ setDone(Other);
+ }
+ } else if (current == '"' || current == '\'') {
+ recordStartPos();
+ state = InString;
+ stringType = current;
+ } else if (isIdentLetter(current)) {
+ recordStartPos();
+ record16(current);
+ state = InIdentifier;
+ } else if (current == '0') {
+ recordStartPos();
+ record8(current);
+ state = InNum0;
+ } else if (isDecimalDigit(current)) {
+ recordStartPos();
+ record8(current);
+ state = InNum;
+ } else if (current == '.' && isDecimalDigit(next1)) {
+ recordStartPos();
+ record8(current);
+ state = InDecimal;
+ } else {
+ recordStartPos();
+ token = matchPunctuator(current, next1, next2, next3);
+ if (token != -1) {
+ if (terminator && !delimited && !prohibitAutomaticSemicolon
+ && (token == QScriptGrammar::T_PLUS_PLUS
+ || token == QScriptGrammar::T_MINUS_MINUS)) {
+ // automatic semicolon insertion
+ stackToken = token;
+ token = QScriptGrammar::T_SEMICOLON;
+ }
+ setDone(Other);
+ }
+ else {
+ setDone(Bad);
+ err = IllegalCharacter;
+ errmsg = LU::tr("Illegal character");
+ }
+ }
+ break;
+ case InString:
+ if (current == stringType) {
+ shift(1);
+ setDone(String);
+ } else if (current == 0 || isLineTerminator()) {
+ setDone(Bad);
+ err = UnclosedStringLiteral;
+ errmsg = LU::tr("Unclosed string at end of line");
+ } else if (current == '\\') {
+ state = InEscapeSequence;
+ } else {
+ record16(current);
+ }
+ break;
+ // Escape Sequences inside of strings
+ case InEscapeSequence:
+ if (isOctalDigit(current)) {
+ if (current >= '0' && current <= '3' &&
+ isOctalDigit(next1) && isOctalDigit(next2)) {
+ record16(convertOctal(current, next1, next2));
+ shift(2);
+ state = InString;
+ } else if (isOctalDigit(current) &&
+ isOctalDigit(next1)) {
+ record16(convertOctal('0', current, next1));
+ shift(1);
+ state = InString;
+ } else if (isOctalDigit(current)) {
+ record16(convertOctal('0', '0', current));
+ state = InString;
+ } else {
+ setDone(Bad);
+ err = IllegalEscapeSequence;
+ errmsg = LU::tr("Illegal escape sequence");
+ }
+ } else if (current == 'x')
+ state = InHexEscape;
+ else if (current == 'u')
+ state = InUnicodeEscape;
+ else {
+ record16(singleEscape(current));
+ state = InString;
+ }
+ break;
+ case InHexEscape:
+ if (isHexDigit(current) && isHexDigit(next1)) {
+ state = InString;
+ record16(QLatin1Char(convertHex(current, next1)));
+ shift(1);
+ } else if (current == stringType) {
+ record16(QLatin1Char('x'));
+ shift(1);
+ setDone(String);
+ } else {
+ record16(QLatin1Char('x'));
+ record16(current);
+ state = InString;
+ }
+ break;
+ case InUnicodeEscape:
+ if (isHexDigit(current) && isHexDigit(next1) &&
+ isHexDigit(next2) && isHexDigit(next3)) {
+ record16(convertUnicode(current, next1, next2, next3));
+ shift(3);
+ state = InString;
+ } else if (current == stringType) {
+ record16(QLatin1Char('u'));
+ shift(1);
+ setDone(String);
+ } else {
+ setDone(Bad);
+ err = IllegalUnicodeEscapeSequence;
+ errmsg = LU::tr("Illegal unicode escape sequence");
+ }
+ break;
+ case InSingleLineComment:
+ if (isLineTerminator()) {
+ record16(current); // include newline
+ processComment(buffer16, pos16);
+ shiftWindowsLineBreak();
+ yylineno++;
+ yycolumn = 0;
+ pos16 = 0;
+ terminator = true;
+ bol = true;
+ if (restrKeyword) {
+ token = QScriptGrammar::T_SEMICOLON;
+ setDone(Other);
+ } else
+ state = Start;
+ } else if (current == 0) {
+ setDone(Eof);
+ } else {
+ record16(current);
+ }
+ break;
+ case InMultiLineComment:
+ if (current == 0) {
+ setDone(Bad);
+ err = UnclosedComment;
+ errmsg = LU::tr("Unclosed comment at end of file");
+ } else if (isLineTerminator()) {
+ shiftWindowsLineBreak();
+ yylineno++;
+ } else if (current == '*' && next1 == '/') {
+ processComment(buffer16, pos16);
+ pos16 = 0;
+ state = Start;
+ shift(1);
+ } else {
+ record16(current);
+ }
+ break;
+ case InIdentifier:
+ if (isIdentLetter(current) || isDecimalDigit(current)) {
+ record16(current);
+ break;
+ }
+ setDone(Identifier);
+ break;
+ case InNum0:
+ if (current == 'x' || current == 'X') {
+ record8(current);
+ state = InHex;
+ } else if (current == '.') {
+ record8(current);
+ state = InDecimal;
+ } else if (current == 'e' || current == 'E') {
+ record8(current);
+ state = InExponentIndicator;
+ } else if (isOctalDigit(current)) {
+ record8(current);
+ state = InOctal;
+ } else if (isDecimalDigit(current)) {
+ record8(current);
+ state = InDecimal;
+ } else {
+ setDone(Number);
+ }
+ break;
+ case InHex:
+ if (isHexDigit(current))
+ record8(current);
+ else
+ setDone(Hex);
+ break;
+ case InOctal:
+ if (isOctalDigit(current)) {
+ record8(current);
+ } else if (isDecimalDigit(current)) {
+ record8(current);
+ state = InDecimal;
+ } else {
+ setDone(Octal);
+ }
+ break;
+ case InNum:
+ if (isDecimalDigit(current)) {
+ record8(current);
+ } else if (current == '.') {
+ record8(current);
+ state = InDecimal;
+ } else if (current == 'e' || current == 'E') {
+ record8(current);
+ state = InExponentIndicator;
+ } else {
+ setDone(Number);
+ }
+ break;
+ case InDecimal:
+ if (isDecimalDigit(current)) {
+ record8(current);
+ } else if (current == 'e' || current == 'E') {
+ record8(current);
+ state = InExponentIndicator;
+ } else {
+ setDone(Number);
+ }
+ break;
+ case InExponentIndicator:
+ if (current == '+' || current == '-') {
+ record8(current);
+ } else if (isDecimalDigit(current)) {
+ record8(current);
+ state = InExponent;
+ } else {
+ setDone(Bad);
+ err = IllegalExponentIndicator;
+ errmsg = LU::tr("Illegal syntax for exponential number");
+ }
+ break;
+ case InExponent:
+ if (isDecimalDigit(current)) {
+ record8(current);
+ } else {
+ setDone(Number);
+ }
+ break;
+ default:
+ Q_ASSERT_X(0, "Lexer::lex", "Unhandled state in switch statement");
+ }
+
+ // move on to the next character
+ if (!done)
+ shift(1);
+ if (state != Start && state != InSingleLineComment)
+ bol = false;
+ }
+
+ // no identifiers allowed directly after numeric literal, e.g. "3in" is bad
+ if ((state == Number || state == Octal || state == Hex)
+ && isIdentLetter(current)) {
+ state = Bad;
+ err = IllegalIdentifier;
+ errmsg = LU::tr("Identifier cannot start with numeric literal");
+ }
+
+ // terminate string
+ buffer8[pos8] = '\0';
+
+ double dval = 0;
+ if (state == Number) {
+ dval = qstrtod(buffer8, 0, 0);
+ } else if (state == Hex) { // scan hex numbers
+ dval = QScript::integerFromString(buffer8, pos8, 16);
+ state = Number;
+ } else if (state == Octal) { // scan octal number
+ dval = QScript::integerFromString(buffer8, pos8, 8);
+ state = Number;
+ }
+
+ restrKeyword = false;
+ delimited = false;
+
+ switch (parenthesesState) {
+ case IgnoreParentheses:
+ break;
+ case CountParentheses:
+ if (token == QScriptGrammar::T_RPAREN) {
+ --parenthesesCount;
+ if (parenthesesCount == 0)
+ parenthesesState = BalancedParentheses;
+ } else if (token == QScriptGrammar::T_LPAREN) {
+ ++parenthesesCount;
+ }
+ break;
+ case BalancedParentheses:
+ parenthesesState = IgnoreParentheses;
+ break;
+ }
+
+ switch (state) {
+ case Eof:
+ return 0;
+ case Other:
+ if(token == QScriptGrammar::T_RBRACE || token == QScriptGrammar::T_SEMICOLON)
+ delimited = true;
+ return token;
+ case Identifier:
+ if ((token = findReservedWord(buffer16, pos16)) < 0) {
+ /* TODO: close leak on parse error. same holds true for String */
+ qsyylval = QString(buffer16, pos16);
+ return QScriptGrammar::T_IDENTIFIER;
+ }
+ if (token == QScriptGrammar::T_CONTINUE || token == QScriptGrammar::T_BREAK
+ || token == QScriptGrammar::T_RETURN || token == QScriptGrammar::T_THROW) {
+ restrKeyword = true;
+ } else if (token == QScriptGrammar::T_IF || token == QScriptGrammar::T_FOR
+ || token == QScriptGrammar::T_WHILE || token == QScriptGrammar::T_WITH) {
+ parenthesesState = CountParentheses;
+ parenthesesCount = 0;
+ } else if (token == QScriptGrammar::T_DO) {
+ parenthesesState = BalancedParentheses;
+ }
+ return token;
+ case String:
+ qsyylval = QString(buffer16, pos16);
+ return QScriptGrammar::T_STRING_LITERAL;
+ case Number:
+ qsyylval = dval;
+ return QScriptGrammar::T_NUMERIC_LITERAL;
+ case Bad:
+ return -1;
+ default:
+ Q_ASSERT(!"unhandled numeration value in switch");
+ return -1;
+ }
+}
+
+bool QScript::Lexer::isWhiteSpace() const
+{
+ return (current == ' ' || current == '\t' ||
+ current == 0x0b || current == 0x0c);
+}
+
+bool QScript::Lexer::isLineTerminator() const
+{
+ return (current == '\n' || current == '\r');
+}
+
+bool QScript::Lexer::isIdentLetter(ushort c)
+{
+ /* TODO: allow other legitimate unicode chars */
+ return ((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || c == '$'
+ || c == '_');
+}
+
+bool QScript::Lexer::isDecimalDigit(ushort c)
+{
+ return (c >= '0' && c <= '9');
+}
+
+bool QScript::Lexer::isHexDigit(ushort c) const
+{
+ return ((c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'f')
+ || (c >= 'A' && c <= 'F'));
+}
+
+bool QScript::Lexer::isOctalDigit(ushort c) const
+{
+ return (c >= '0' && c <= '7');
+}
+
+int QScript::Lexer::matchPunctuator(ushort c1, ushort c2,
+ ushort c3, ushort c4)
+{
+ if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
+ shift(4);
+ return QScriptGrammar::T_GT_GT_GT_EQ;
+ } else if (c1 == '=' && c2 == '=' && c3 == '=') {
+ shift(3);
+ return QScriptGrammar::T_EQ_EQ_EQ;
+ } else if (c1 == '!' && c2 == '=' && c3 == '=') {
+ shift(3);
+ return QScriptGrammar::T_NOT_EQ_EQ;
+ } else if (c1 == '>' && c2 == '>' && c3 == '>') {
+ shift(3);
+ return QScriptGrammar::T_GT_GT_GT;
+ } else if (c1 == '<' && c2 == '<' && c3 == '=') {
+ shift(3);
+ return QScriptGrammar::T_LT_LT_EQ;
+ } else if (c1 == '>' && c2 == '>' && c3 == '=') {
+ shift(3);
+ return QScriptGrammar::T_GT_GT_EQ;
+ } else if (c1 == '<' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_LE;
+ } else if (c1 == '>' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_GE;
+ } else if (c1 == '!' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_NOT_EQ;
+ } else if (c1 == '+' && c2 == '+') {
+ shift(2);
+ return QScriptGrammar::T_PLUS_PLUS;
+ } else if (c1 == '-' && c2 == '-') {
+ shift(2);
+ return QScriptGrammar::T_MINUS_MINUS;
+ } else if (c1 == '=' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_EQ_EQ;
+ } else if (c1 == '+' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_PLUS_EQ;
+ } else if (c1 == '-' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_MINUS_EQ;
+ } else if (c1 == '*' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_STAR_EQ;
+ } else if (c1 == '/' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_DIVIDE_EQ;
+ } else if (c1 == '&' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_AND_EQ;
+ } else if (c1 == '^' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_XOR_EQ;
+ } else if (c1 == '%' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_REMAINDER_EQ;
+ } else if (c1 == '|' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_OR_EQ;
+ } else if (c1 == '<' && c2 == '<') {
+ shift(2);
+ return QScriptGrammar::T_LT_LT;
+ } else if (c1 == '>' && c2 == '>') {
+ shift(2);
+ return QScriptGrammar::T_GT_GT;
+ } else if (c1 == '&' && c2 == '&') {
+ shift(2);
+ return QScriptGrammar::T_AND_AND;
+ } else if (c1 == '|' && c2 == '|') {
+ shift(2);
+ return QScriptGrammar::T_OR_OR;
+ }
+
+ switch(c1) {
+ case '=': shift(1); return QScriptGrammar::T_EQ;
+ case '>': shift(1); return QScriptGrammar::T_GT;
+ case '<': shift(1); return QScriptGrammar::T_LT;
+ case ',': shift(1); return QScriptGrammar::T_COMMA;
+ case '!': shift(1); return QScriptGrammar::T_NOT;
+ case '~': shift(1); return QScriptGrammar::T_TILDE;
+ case '?': shift(1); return QScriptGrammar::T_QUESTION;
+ case ':': shift(1); return QScriptGrammar::T_COLON;
+ case '.': shift(1); return QScriptGrammar::T_DOT;
+ case '+': shift(1); return QScriptGrammar::T_PLUS;
+ case '-': shift(1); return QScriptGrammar::T_MINUS;
+ case '*': shift(1); return QScriptGrammar::T_STAR;
+ case '/': shift(1); return QScriptGrammar::T_DIVIDE_;
+ case '&': shift(1); return QScriptGrammar::T_AND;
+ case '|': shift(1); return QScriptGrammar::T_OR;
+ case '^': shift(1); return QScriptGrammar::T_XOR;
+ case '%': shift(1); return QScriptGrammar::T_REMAINDER;
+ case '(': shift(1); return QScriptGrammar::T_LPAREN;
+ case ')': shift(1); return QScriptGrammar::T_RPAREN;
+ case '{': shift(1); return QScriptGrammar::T_LBRACE;
+ case '}': shift(1); return QScriptGrammar::T_RBRACE;
+ case '[': shift(1); return QScriptGrammar::T_LBRACKET;
+ case ']': shift(1); return QScriptGrammar::T_RBRACKET;
+ case ';': shift(1); return QScriptGrammar::T_SEMICOLON;
+
+ default: return -1;
+ }
+}
+
+ushort QScript::Lexer::singleEscape(ushort c) const
+{
+ switch(c) {
+ case 'b':
+ return 0x08;
+ case 't':
+ return 0x09;
+ case 'n':
+ return 0x0A;
+ case 'v':
+ return 0x0B;
+ case 'f':
+ return 0x0C;
+ case 'r':
+ return 0x0D;
+ case '"':
+ return 0x22;
+ case '\'':
+ return 0x27;
+ case '\\':
+ return 0x5C;
+ default:
+ return c;
+ }
+}
+
+ushort QScript::Lexer::convertOctal(ushort c1, ushort c2,
+ ushort c3) const
+{
+ return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
+}
+
+unsigned char QScript::Lexer::convertHex(ushort c)
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ else if (c >= 'a' && c <= 'f')
+ return (c - 'a' + 10);
+ else
+ return (c - 'A' + 10);
+}
+
+unsigned char QScript::Lexer::convertHex(ushort c1, ushort c2)
+{
+ return ((convertHex(c1) << 4) + convertHex(c2));
+}
+
+QChar QScript::Lexer::convertUnicode(ushort c1, ushort c2,
+ ushort c3, ushort c4)
+{
+ return QChar((convertHex(c3) << 4) + convertHex(c4),
+ (convertHex(c1) << 4) + convertHex(c2));
+}
+
+void QScript::Lexer::record8(ushort c)
+{
+ Q_ASSERT(c <= 0xff);
+
+ // enlarge buffer if full
+ if (pos8 >= size8 - 1) {
+ char *tmp = new char[2 * size8];
+ memcpy(tmp, buffer8, size8 * sizeof(char));
+ delete [] buffer8;
+ buffer8 = tmp;
+ size8 *= 2;
+ }
+
+ buffer8[pos8++] = (char) c;
+}
+
+void QScript::Lexer::record16(QChar c)
+{
+ // enlarge buffer if full
+ if (pos16 >= size16 - 1) {
+ QChar *tmp = new QChar[2 * size16];
+ memcpy(tmp, buffer16, size16 * sizeof(QChar));
+ delete [] buffer16;
+ buffer16 = tmp;
+ size16 *= 2;
+ }
+
+ buffer16[pos16++] = c;
+}
+
+void QScript::Lexer::recordStartPos()
+{
+ startlineno = yylineno;
+ startcolumn = yycolumn;
+}
+
+bool QScript::Lexer::scanRegExp(RegExpBodyPrefix prefix)
+{
+ pos16 = 0;
+ bool lastWasEscape = false;
+
+ if (prefix == EqualPrefix)
+ record16(QLatin1Char('='));
+
+ while (1) {
+ if (isLineTerminator() || current == 0) {
+ errmsg = LU::tr("Unterminated regular expression literal");
+ return false;
+ }
+ else if (current != '/' || lastWasEscape == true)
+ {
+ record16(current);
+ lastWasEscape = !lastWasEscape && (current == '\\');
+ }
+ else {
+ pattern = QString(buffer16, pos16);
+ pos16 = 0;
+ shift(1);
+ break;
+ }
+ shift(1);
+ }
+
+ flags = 0;
+ while (isIdentLetter(current)) {
+ record16(current);
+ shift(1);
+ }
+
+ return true;
+}
+
+void QScript::Lexer::syncProhibitAutomaticSemicolon()
+{
+ if (parenthesesState == BalancedParentheses) {
+ // we have seen something like "if (foo)", which means we should
+ // never insert an automatic semicolon at this point, since it would
+ // then be expanded into an empty statement (ECMA-262 7.9.1)
+ prohibitAutomaticSemicolon = true;
+ parenthesesState = IgnoreParentheses;
+ } else {
+ prohibitAutomaticSemicolon = false;
+ }
+}
+
+void QScript::Lexer::processComment(const QChar *chars, int length)
+{
+ commentProcessor->processComment(chars, length);
+}
+
+
+class Translator;
+
+class QScriptParser: protected QScriptGrammar, public QScript::CommentProcessor
+{
+public:
+ QVariant val;
+
+ struct Location {
+ int startLine;
+ int startColumn;
+ int endLine;
+ int endColumn;
+ };
+
+public:
+ QScriptParser();
+ ~QScriptParser();
+
+ void setLexer(QScript::Lexer *);
+ void setTranslator(Translator *);
+
+ bool parse();
+
+ QString fileName() const
+ { return lexer->fileName(); }
+ inline QString errorMessage() const
+ { return error_message; }
+ inline int errorLineNumber() const
+ { return error_lineno; }
+ inline int errorColumnNumber() const
+ { return error_column; }
+
+protected:
+ inline void reallocateStack();
+
+ inline QVariant &sym(int index)
+ { return sym_stack [tos + index - 1]; }
+
+ inline Location &loc(int index)
+ { return location_stack [tos + index - 2]; }
+
+ std::ostream &yyMsg(int line = 0);
+
+ virtual void processComment(const QChar *, int);
+
+protected:
+ int tos;
+ int stack_size;
+ QVector<QVariant> sym_stack;
+ int *state_stack;
+ Location *location_stack;
+ QString error_message;
+ int error_lineno;
+ int error_column;
+
+private:
+ QScript::Lexer *lexer;
+ Translator *translator;
+ QString trcontext;
+ QString extracomment;
+ QString msgid;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
+};
+
+inline void QScriptParser::reallocateStack()
+{
+ if (! stack_size)
+ stack_size = 128;
+ else
+ stack_size <<= 1;
+
+ sym_stack.resize(stack_size);
+ state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
+ location_stack = reinterpret_cast<Location*> (qRealloc(location_stack, stack_size * sizeof(Location)));
+}
+
+inline static bool automatic(QScript::Lexer *lexer, int token)
+{
+ return (token == QScriptGrammar::T_RBRACE)
+ || (token == 0)
+ || lexer->prevTerminator();
+}
+
+QScriptParser::QScriptParser():
+ tos(0),
+ stack_size(0),
+ sym_stack(0),
+ state_stack(0),
+ location_stack(0),
+ lexer(0),
+ translator(0)
+{
+}
+
+QScriptParser::~QScriptParser()
+{
+ if (stack_size) {
+ qFree(state_stack);
+ qFree(location_stack);
+ }
+}
+
+static inline QScriptParser::Location location(QScript::Lexer *lexer)
+{
+ QScriptParser::Location loc;
+ loc.startLine = lexer->startLineNo();
+ loc.startColumn = lexer->startColumnNo();
+ loc.endLine = lexer->endLineNo();
+ loc.endColumn = lexer->endColumnNo();
+ return loc;
+}
+
+void QScriptParser::setLexer(QScript::Lexer *lex)
+{
+ lexer = lex;
+}
+
+void QScriptParser::setTranslator(Translator *tor)
+{
+ translator = tor;
+}
+
+bool QScriptParser::parse()
+{
+ Q_ASSERT(lexer != 0);
+ Q_ASSERT(translator != 0);
+ trcontext = QFileInfo(fileName()).baseName();
+
+ const int INITIAL_STATE = 0;
+
+ int yytoken = -1;
+ int saved_yytoken = -1;
+ int identLineNo = -1;
+
+ reallocateStack();
+
+ tos = 0;
+ state_stack[++tos] = INITIAL_STATE;
+
+ while (true)
+ {
+ const int state = state_stack [tos];
+ if (yytoken == -1 && - TERMINAL_COUNT != action_index [state])
+ {
+ if (saved_yytoken == -1)
+ {
+ yytoken = lexer->lex();
+ location_stack [tos] = location(lexer);
+ }
+ else
+ {
+ yytoken = saved_yytoken;
+ saved_yytoken = -1;
+ }
+ }
+
+ int act = t_action (state, yytoken);
+
+ if (act == ACCEPT_STATE)
+ return true;
+
+ else if (act > 0)
+ {
+ if (++tos == stack_size)
+ reallocateStack();
+
+ sym_stack [tos] = lexer->val ();
+ state_stack [tos] = act;
+ location_stack [tos] = location(lexer);
+ yytoken = -1;
+ }
+
+ else if (act < 0)
+ {
+ int r = - act - 1;
+
+ tos -= rhs [r];
+ act = state_stack [tos++];
+
+ switch (r) {
+
+case 1: {
+ sym(1) = sym(1).toByteArray();
+ identLineNo = lexer->startLineNo();
+} break;
+
+case 7: {
+ bool rx = lexer->scanRegExp(QScript::Lexer::NoPrefix);
+ if (!rx) {
+ error_message = lexer->errorMessage();
+ error_lineno = lexer->startLineNo();
+ error_column = lexer->startColumnNo();
+ return false;
+ }
+} break;
+
+case 8: {
+ bool rx = lexer->scanRegExp(QScript::Lexer::EqualPrefix);
+ if (!rx) {
+ error_message = lexer->errorMessage();
+ error_lineno = lexer->startLineNo();
+ error_column = lexer->startColumnNo();
+ return false;
+ }
+} break;
+
+case 66: {
+ QString name = sym(1).toString();
+ if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
+ QVariantList args = sym(2).toList();
+ if (args.size() < 2) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least two arguments.\n").arg(name));
+ } else {
+ if ((args.at(0).type() != QVariant::String)
+ || (args.at(1).type() != QVariant::String)) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): both arguments must be literal strings.\n").arg(name));
+ } else {
+ QString context = args.at(0).toString();
+ QString text = args.at(1).toString();
+ QString comment = args.value(2).toString();
+ bool plural = (args.size() > 4);
+ recordMessage(translator, context, text, comment, extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ } else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
+ QVariantList args = sym(2).toList();
+ if (args.size() < 1) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name));
+ } else {
+ if (args.at(0).type() != QVariant::String) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name));
+ } else {
+ QString text = args.at(0).toString();
+ QString comment = args.value(1).toString();
+ bool plural = (args.size() > 2);
+ recordMessage(translator, trcontext, text, comment, extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ } else if ((name == QLatin1String("qsTrId")) || (name == QLatin1String("QT_TRID_NOOP"))) {
+ if (!msgid.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//= cannot be used with %1(). Ignoring\n").arg(name));
+ QVariantList args = sym(2).toList();
+ if (args.size() < 1) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name));
+ } else {
+ if (args.at(0).type() != QVariant::String) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): identifier must be a literal string.\n").arg(name));
+ } else {
+ msgid = args.at(0).toString();
+ bool plural = (args.size() > 1);
+ recordMessage(translator, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
+} break;
+
+case 70: {
+ sym(1) = QVariantList();
+} break;
+
+case 71: {
+ sym(1) = sym(2);
+} break;
+
+case 72: {
+ sym(1) = QVariantList() << sym(1);
+} break;
+
+case 73: {
+ sym(1) = sym(1).toList() << sym(3);
+} break;
+
+case 94: {
+ if ((sym(1).type() == QVariant::String) || (sym(3).type() == QVariant::String))
+ sym(1) = sym(1).toString() + sym(3).toString();
+ else
+ sym(1) = QVariant();
+} break;
+
+ case 171:
+
+ case 172:
+
+ case 173:
+
+ case 174:
+
+ case 175:
+
+ case 176:
+
+ case 177:
+
+ case 178:
+
+ case 179:
+
+ case 180:
+
+ case 181:
+
+ case 182:
+
+ case 183:
+
+ case 184:
+
+ case 185:
+ if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) {
+ yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n"));
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
+ break;
+
+ } // switch
+
+ state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
+
+ if (rhs[r] > 1) {
+ location_stack[tos - 1].endLine = location_stack[tos + rhs[r] - 2].endLine;
+ location_stack[tos - 1].endColumn = location_stack[tos + rhs[r] - 2].endColumn;
+ location_stack[tos] = location_stack[tos + rhs[r] - 1];
+ }
+ }
+
+ else
+ {
+ if (saved_yytoken == -1 && automatic (lexer, yytoken) && t_action (state, T_AUTOMATIC_SEMICOLON) > 0)
+ {
+ saved_yytoken = yytoken;
+ yytoken = T_SEMICOLON;
+ continue;
+ }
+
+ else if ((state == INITIAL_STATE) && (yytoken == 0)) {
+ // accept empty input
+ yytoken = T_SEMICOLON;
+ continue;
+ }
+
+ int ers = state;
+ int shifts = 0;
+ int reduces = 0;
+ int expected_tokens [3];
+ for (int tk = 0; tk < TERMINAL_COUNT; ++tk)
+ {
+ int k = t_action (ers, tk);
+
+ if (! k)
+ continue;
+ else if (k < 0)
+ ++reduces;
+ else if (spell [tk])
+ {
+ if (shifts < 3)
+ expected_tokens [shifts] = tk;
+ ++shifts;
+ }
+ }
+
+ error_message.clear ();
+ if (shifts && shifts < 3)
+ {
+ bool first = true;
+
+ for (int s = 0; s < shifts; ++s)
+ {
+ if (first)
+ //: Beginning of the string that contains
+ //: comma-separated list of expected tokens
+ error_message += LU::tr("Expected ");
+ else
+ error_message += QLatin1String (", ");
+
+ first = false;
+ error_message += QLatin1String("`");
+ error_message += QLatin1String (spell [expected_tokens [s]]);
+ error_message += QLatin1String("'");
+ }
+ }
+
+ if (error_message.isEmpty())
+ error_message = lexer->errorMessage();
+
+ error_lineno = lexer->startLineNo();
+ error_column = lexer->startColumnNo();
+
+ return false;
+ }
+ }
+
+ return false;
+}
+
+std::ostream &QScriptParser::yyMsg(int line)
+{
+ return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": ";
+}
+
+void QScriptParser::processComment(const QChar *chars, int length)
+{
+ if (!length)
+ return;
+ // Try to match the logic of the C++ parser.
+ if (*chars == QLatin1Char(':') && chars[1].isSpace()) {
+ extracomment += QString(chars+2, length-2);
+ } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) {
+ msgid = QString(chars+2, length-2).simplified();
+ } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) {
+ QString text = QString(chars+2, length-2).trimmed();
+ int k = text.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ extra.insert(text.left(k), text.mid(k + 1).trimmed());
+ } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) {
+ sourcetext.reserve(sourcetext.length() + length-2);
+ ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length();
+ int p = 2, c;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"') {
+ yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n"));
+ break;
+ }
+ forever {
+ if (p >= length) {
+ whoops:
+ yyMsg() << qPrintable(LU::tr("Unterminated meta string\n"));
+ break;
+ }
+ c = chars[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= length)
+ goto whoops;
+ c = chars[p++].unicode();
+ if (c == '\n')
+ goto whoops;
+ *ptr++ = '\\';
+ }
+ *ptr++ = c;
+ }
+ }
+ sourcetext.resize(ptr - (ushort *)sourcetext.data());
+ } else {
+ int idx = 0;
+ ushort c;
+ while ((c = chars[idx].unicode()) == ' ' || c == '\t' || c == '\n')
+ ++idx;
+ if (!memcmp(chars + idx, MagicComment.unicode(), MagicComment.length() * 2)) {
+ idx += MagicComment.length();
+ QString comment = QString(chars + idx, length - idx).simplified();
+ int k = comment.indexOf(QLatin1Char(' '));
+ if (k == -1) {
+ trcontext = comment;
+ } else {
+ trcontext = comment.left(k);
+ comment.remove(0, k + 1);
+ TranslatorMessage msg(
+ trcontext, QString(),
+ comment, QString(),
+ fileName(), lexer->startLineNo(), QStringList(),
+ TranslatorMessage::Finished, /*plural=*/false);
+ msg.setExtraComment(extracomment.simplified());
+ extracomment.clear();
+ translator->append(msg);
+ translator->setExtras(extra);
+ extra.clear();
+ }
+ }
+ }
+}
+
+
+bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
+{
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
+ return false;
+ }
+ QTextStream ts(&file);
+ QByteArray codecName;
+ if (!cd.m_codecForSource.isEmpty())
+ codecName = cd.m_codecForSource;
+ else
+ codecName = translator.codecName(); // Just because it should be latin1 already
+ ts.setCodec(QTextCodec::codecForName(codecName));
+ ts.setAutoDetectUnicode(true);
+
+ QString code = ts.readAll();
+ QScriptParser parser;
+ QScript::Lexer lexer(&parser);
+ lexer.setCode(code, filename, /*lineNumber=*/1);
+ parser.setLexer(&lexer);
+ parser.setTranslator(&translator);
+ if (!parser.parse()) {
+ std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": "
+ << qPrintable(parser.errorMessage()) << std::endl;
+ return false;
+ }
+
+ // Java uses UTF-16 internally and Jambi makes UTF-8 for tr() purposes of it.
+ translator.setCodecName("UTF-8");
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/qscript.g b/src/linguist/lupdate/qscript.g
new file mode 100644
index 000000000..b8b7b5f19
--- /dev/null
+++ b/src/linguist/lupdate/qscript.g
@@ -0,0 +1,2261 @@
+----------------------------------------------------------------------------
+--
+-- Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+-- All rights reserved.
+-- Contact: Nokia Corporation (qt-info@nokia.com)
+--
+-- This file is part of the Qt Linguist of the Qt Toolkit.
+--
+-- $QT_BEGIN_LICENSE:LGPL$
+-- No Commercial Usage
+-- This file contains pre-release code and may not be distributed.
+-- You may use this file in accordance with the terms and conditions
+-- contained in the Technology Preview License Agreement accompanying
+-- this package.
+--
+-- GNU Lesser General Public License Usage
+-- Alternatively, this file may be used under the terms of the GNU Lesser
+-- General Public License version 2.1 as published by the Free Software
+-- Foundation and appearing in the file LICENSE.LGPL included in the
+-- packaging of this file. Please review the following information to
+-- ensure the GNU Lesser General Public License version 2.1 requirements
+-- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+--
+-- In addition, as a special exception, Nokia gives you certain additional
+-- rights. These rights are described in the Nokia Qt LGPL Exception
+-- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+--
+-- If you have questions regarding the use of this file, please contact
+-- Nokia at qt-info@nokia.com.
+--
+--
+--
+--
+--
+--
+--
+--
+-- $QT_END_LICENSE$
+--
+----------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- Process with "qlalr --no-debug --no-lines qscript.g" to update qscript.cpp --
+--------------------------------------------------------------------------------
+
+%parser QScriptGrammar
+%merged_output qscript.cpp
+%expect 3
+%expect-rr 1
+
+%token T_AND "&" T_AND_AND "&&" T_AND_EQ "&="
+%token T_BREAK "break" T_CASE "case" T_CATCH "catch"
+%token T_COLON ":" T_COMMA ";" T_CONTINUE "continue"
+%token T_DEFAULT "default" T_DELETE "delete" T_DIVIDE_ "/"
+%token T_DIVIDE_EQ "/=" T_DO "do" T_DOT "."
+%token T_ELSE "else" T_EQ "=" T_EQ_EQ "=="
+%token T_EQ_EQ_EQ "===" T_FINALLY "finally" T_FOR "for"
+%token T_FUNCTION "function" T_GE ">=" T_GT ">"
+%token T_GT_GT ">>" T_GT_GT_EQ ">>=" T_GT_GT_GT ">>>"
+%token T_GT_GT_GT_EQ ">>>=" T_IDENTIFIER "identifier" T_IF "if"
+%token T_IN "in" T_INSTANCEOF "instanceof" T_LBRACE "{"
+%token T_LBRACKET "[" T_LE "<=" T_LPAREN "("
+%token T_LT "<" T_LT_LT "<<" T_LT_LT_EQ "<<="
+%token T_MINUS "-" T_MINUS_EQ "-=" T_MINUS_MINUS "--"
+%token T_NEW "new" T_NOT "!" T_NOT_EQ "!="
+%token T_NOT_EQ_EQ "!==" T_NUMERIC_LITERAL "numeric literal" T_OR "|"
+%token T_OR_EQ "|=" T_OR_OR "||" T_PLUS "+"
+%token T_PLUS_EQ "+=" T_PLUS_PLUS "++" T_QUESTION "?"
+%token T_RBRACE "}" T_RBRACKET "]" T_REMAINDER "%"
+%token T_REMAINDER_EQ "%=" T_RETURN "return" T_RPAREN ")"
+%token T_SEMICOLON ";" T_AUTOMATIC_SEMICOLON T_STAR "*"
+%token T_STAR_EQ "*=" T_STRING_LITERAL "string literal"
+%token T_SWITCH "switch" T_THIS "this" T_THROW "throw"
+%token T_TILDE "~" T_TRY "try" T_TYPEOF "typeof"
+%token T_VAR "var" T_VOID "void" T_WHILE "while"
+%token T_WITH "with" T_XOR "^" T_XOR_EQ "^="
+%token T_NULL "null" T_TRUE "true" T_FALSE "false"
+%token T_CONST "const"
+%token T_DEBUGGER "debugger"
+%token T_RESERVED_WORD "reserved word"
+
+%start Program
+
+/.
+#include <translator.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/qdebug.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qtextcodec.h>
+#include <QtCore/qvariant.h>
+
+#include <iostream>
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+static QString MagicComment(QLatin1String("TRANSLATOR"));
+
+static void recordMessage(
+ Translator *tor, const QString &context, const QString &text, const QString &comment,
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool plural, const QString &fileName, int lineNo)
+{
+ TranslatorMessage msg(
+ context, text, comment, QString(),
+ fileName, lineNo, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ msg.setId(msgid);
+ msg.setExtras(extra);
+ tor->extend(msg);
+}
+
+
+namespace QScript
+{
+
+class CommentProcessor
+{
+public:
+ virtual ~CommentProcessor() {}
+ virtual void processComment(const QChar *chars, int length) = 0;
+};
+
+class Lexer
+{
+public:
+ Lexer(CommentProcessor *);
+ ~Lexer();
+
+ void setCode(const QString &c, const QString &fileName, int lineno);
+ int lex();
+
+ QString fileName() const { return yyfilename; }
+ int currentLineNo() const { return yylineno; }
+ int currentColumnNo() const { return yycolumn; }
+
+ int startLineNo() const { return startlineno; }
+ int startColumnNo() const { return startcolumn; }
+
+ int endLineNo() const { return currentLineNo(); }
+ int endColumnNo() const
+ { int col = currentColumnNo(); return (col > 0) ? col - 1 : col; }
+
+ bool prevTerminator() const { return terminator; }
+
+ enum State { Start,
+ Identifier,
+ InIdentifier,
+ InSingleLineComment,
+ InMultiLineComment,
+ InNum,
+ InNum0,
+ InHex,
+ InOctal,
+ InDecimal,
+ InExponentIndicator,
+ InExponent,
+ Hex,
+ Octal,
+ Number,
+ String,
+ Eof,
+ InString,
+ InEscapeSequence,
+ InHexEscape,
+ InUnicodeEscape,
+ Other,
+ Bad };
+
+ enum Error {
+ NoError,
+ IllegalCharacter,
+ UnclosedStringLiteral,
+ IllegalEscapeSequence,
+ IllegalUnicodeEscapeSequence,
+ UnclosedComment,
+ IllegalExponentIndicator,
+ IllegalIdentifier
+ };
+
+ enum ParenthesesState {
+ IgnoreParentheses,
+ CountParentheses,
+ BalancedParentheses
+ };
+
+ enum RegExpBodyPrefix {
+ NoPrefix,
+ EqualPrefix
+ };
+
+ bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix);
+
+ QString pattern;
+ int flags;
+
+ State lexerState() const
+ { return state; }
+
+ QString errorMessage() const
+ { return errmsg; }
+ void setErrorMessage(const QString &err)
+ { errmsg = err; }
+ void setErrorMessage(const char *err)
+ { setErrorMessage(QString::fromLatin1(err)); }
+
+ Error error() const
+ { return err; }
+ void clearError()
+ { err = NoError; }
+
+private:
+ QString yyfilename;
+ int yylineno;
+ bool done;
+ char *buffer8;
+ QChar *buffer16;
+ uint size8, size16;
+ uint pos8, pos16;
+ bool terminator;
+ bool restrKeyword;
+ // encountered delimiter like "'" and "}" on last run
+ bool delimited;
+ int stackToken;
+
+ State state;
+ void setDone(State s);
+ uint pos;
+ void shift(uint p);
+ int lookupKeyword(const char *);
+
+ bool isWhiteSpace() const;
+ bool isLineTerminator() const;
+ bool isHexDigit(ushort c) const;
+ bool isOctalDigit(ushort c) const;
+
+ int matchPunctuator(ushort c1, ushort c2,
+ ushort c3, ushort c4);
+ ushort singleEscape(ushort c) const;
+ ushort convertOctal(ushort c1, ushort c2,
+ ushort c3) const;
+public:
+ static unsigned char convertHex(ushort c1);
+ static unsigned char convertHex(ushort c1, ushort c2);
+ static QChar convertUnicode(ushort c1, ushort c2,
+ ushort c3, ushort c4);
+ static bool isIdentLetter(ushort c);
+ static bool isDecimalDigit(ushort c);
+
+ inline int ival() const { return qsyylval.toInt(); }
+ inline double dval() const { return qsyylval.toDouble(); }
+ inline QString ustr() const { return qsyylval.toString(); }
+ inline QVariant val() const { return qsyylval; }
+
+ const QChar *characterBuffer() const { return buffer16; }
+ int characterCount() const { return pos16; }
+
+private:
+ void record8(ushort c);
+ void record16(QChar c);
+ void recordStartPos();
+
+ int findReservedWord(const QChar *buffer, int size) const;
+
+ void syncProhibitAutomaticSemicolon();
+
+ void processComment(const QChar *, int);
+
+ const QChar *code;
+ uint length;
+ int yycolumn;
+ int startlineno;
+ int startcolumn;
+ int bol; // begin of line
+
+ QVariant qsyylval;
+
+ // current and following unicode characters
+ ushort current, next1, next2, next3;
+
+ struct keyword {
+ const char *name;
+ int token;
+ };
+
+ QString errmsg;
+ Error err;
+
+ bool wantRx;
+ bool check_reserved;
+
+ ParenthesesState parenthesesState;
+ int parenthesesCount;
+ bool prohibitAutomaticSemicolon;
+
+ CommentProcessor *commentProcessor;
+};
+
+} // namespace QScript
+
+extern double qstrtod(const char *s00, char const **se, bool *ok);
+
+#define shiftWindowsLineBreak() if(current == '\r' && next1 == '\n') shift(1);
+
+namespace QScript {
+
+static int toDigit(char c)
+{
+ if ((c >= '0') && (c <= '9'))
+ return c - '0';
+ else if ((c >= 'a') && (c <= 'z'))
+ return 10 + c - 'a';
+ else if ((c >= 'A') && (c <= 'Z'))
+ return 10 + c - 'A';
+ return -1;
+}
+
+double integerFromString(const char *buf, int size, int radix)
+{
+ if (size == 0)
+ return qSNaN();
+
+ double sign = 1.0;
+ int i = 0;
+ if (buf[0] == '+') {
+ ++i;
+ } else if (buf[0] == '-') {
+ sign = -1.0;
+ ++i;
+ }
+
+ if (((size-i) >= 2) && (buf[i] == '0')) {
+ if (((buf[i+1] == 'x') || (buf[i+1] == 'X'))
+ && (radix < 34)) {
+ if ((radix != 0) && (radix != 16))
+ return 0;
+ radix = 16;
+ i += 2;
+ } else {
+ if (radix == 0) {
+ radix = 8;
+ ++i;
+ }
+ }
+ } else if (radix == 0) {
+ radix = 10;
+ }
+
+ int j = i;
+ for ( ; i < size; ++i) {
+ int d = toDigit(buf[i]);
+ if ((d == -1) || (d >= radix))
+ break;
+ }
+ double result;
+ if (j == i) {
+ if (!qstrcmp(buf, "Infinity"))
+ result = qInf();
+ else
+ result = qSNaN();
+ } else {
+ result = 0;
+ double multiplier = 1;
+ for (--i ; i >= j; --i, multiplier *= radix)
+ result += toDigit(buf[i]) * multiplier;
+ }
+ result *= sign;
+ return result;
+}
+
+} // namespace QScript
+
+QScript::Lexer::Lexer(QScript::CommentProcessor *proc)
+ :
+ yylineno(0),
+ size8(128), size16(128), restrKeyword(false),
+ stackToken(-1), pos(0),
+ code(0), length(0),
+ bol(true),
+ current(0), next1(0), next2(0), next3(0),
+ err(NoError),
+ check_reserved(true),
+ parenthesesState(IgnoreParentheses),
+ prohibitAutomaticSemicolon(false),
+ commentProcessor(proc)
+{
+ // allocate space for read buffers
+ buffer8 = new char[size8];
+ buffer16 = new QChar[size16];
+ flags = 0;
+
+}
+
+QScript::Lexer::~Lexer()
+{
+ delete [] buffer8;
+ delete [] buffer16;
+}
+
+void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno)
+{
+ errmsg = QString();
+ yyfilename = fileName;
+ yylineno = lineno;
+ yycolumn = 1;
+ restrKeyword = false;
+ delimited = false;
+ stackToken = -1;
+ pos = 0;
+ code = c.unicode();
+ length = c.length();
+ bol = true;
+
+ // read first characters
+ current = (length > 0) ? code[0].unicode() : 0;
+ next1 = (length > 1) ? code[1].unicode() : 0;
+ next2 = (length > 2) ? code[2].unicode() : 0;
+ next3 = (length > 3) ? code[3].unicode() : 0;
+}
+
+void QScript::Lexer::shift(uint p)
+{
+ while (p--) {
+ ++pos;
+ ++yycolumn;
+ current = next1;
+ next1 = next2;
+ next2 = next3;
+ next3 = (pos + 3 < length) ? code[pos+3].unicode() : 0;
+ }
+}
+
+void QScript::Lexer::setDone(State s)
+{
+ state = s;
+ done = true;
+}
+
+int QScript::Lexer::findReservedWord(const QChar *c, int size) const
+{
+ switch (size) {
+ case 2: {
+ if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o'))
+ return QScriptGrammar::T_DO;
+ else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('f'))
+ return QScriptGrammar::T_IF;
+ else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n'))
+ return QScriptGrammar::T_IN;
+ } break;
+
+ case 3: {
+ if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('o') && c[2] == QLatin1Char('r'))
+ return QScriptGrammar::T_FOR;
+ else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('e') && c[2] == QLatin1Char('w'))
+ return QScriptGrammar::T_NEW;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') && c[2] == QLatin1Char('y'))
+ return QScriptGrammar::T_TRY;
+ else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('a') && c[2] == QLatin1Char('r'))
+ return QScriptGrammar::T_VAR;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') && c[2] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 4: {
+ if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
+ return QScriptGrammar::T_CASE;
+ else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('l')
+ && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
+ return QScriptGrammar::T_ELSE;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('s'))
+ return QScriptGrammar::T_THIS;
+ else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('d'))
+ return QScriptGrammar::T_VOID;
+ else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('i')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('h'))
+ return QScriptGrammar::T_WITH;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('e'))
+ return QScriptGrammar::T_TRUE;
+ else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('u')
+ && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('l'))
+ return QScriptGrammar::T_NULL;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('n')
+ && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('m'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('y')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('l') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('g'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('r'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('g') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('o'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 5: {
+ if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('e') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('k'))
+ return QScriptGrammar::T_BREAK;
+ else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('c')
+ && c[4] == QLatin1Char('h'))
+ return QScriptGrammar::T_CATCH;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
+ && c[4] == QLatin1Char('w'))
+ return QScriptGrammar::T_THROW;
+ else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('l')
+ && c[4] == QLatin1Char('e'))
+ return QScriptGrammar::T_WHILE;
+ else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('s')
+ && c[4] == QLatin1Char('t'))
+ return QScriptGrammar::T_CONST;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('s')
+ && c[4] == QLatin1Char('e'))
+ return QScriptGrammar::T_FALSE;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('r')
+ && c[4] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('u')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('r'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('l'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('l')
+ && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('s')
+ && c[4] == QLatin1Char('s'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('l')
+ && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 6: {
+ if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
+ && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('e'))
+ return QScriptGrammar::T_DELETE;
+ else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('u')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('n'))
+ return QScriptGrammar::T_RETURN;
+ else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('w')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('c') && c[5] == QLatin1Char('h'))
+ return QScriptGrammar::T_SWITCH;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('y')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('o') && c[5] == QLatin1Char('f'))
+ return QScriptGrammar::T_TYPEOF;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('t')
+ && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('b')
+ && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('u')
+ && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('l')
+ && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('i')
+ && c[4] == QLatin1Char('v') && c[5] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
+ && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
+ && c[4] == QLatin1Char('w') && c[5] == QLatin1Char('s'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 7: {
+ if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
+ && c[2] == QLatin1Char('f') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('u') && c[5] == QLatin1Char('l')
+ && c[6] == QLatin1Char('t'))
+ return QScriptGrammar::T_DEFAULT;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('l')
+ && c[6] == QLatin1Char('y'))
+ return QScriptGrammar::T_FINALLY;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('l')
+ && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('a')
+ && c[6] == QLatin1Char('n'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('n') && c[5] == QLatin1Char('d')
+ && c[6] == QLatin1Char('s'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('a')
+ && c[2] == QLatin1Char('c') && c[3] == QLatin1Char('k')
+ && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('g')
+ && c[6] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('v')
+ && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('t')
+ && c[6] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 8: {
+ if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('n')
+ && c[6] == QLatin1Char('u') && c[7] == QLatin1Char('e'))
+ return QScriptGrammar::T_CONTINUE;
+ else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('u')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
+ && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
+ && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n'))
+ return QScriptGrammar::T_FUNCTION;
+ else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
+ && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('u')
+ && c[4] == QLatin1Char('g') && c[5] == QLatin1Char('g')
+ && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('r'))
+ return QScriptGrammar::T_DEBUGGER;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('b')
+ && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('a')
+ && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
+ && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('a')
+ && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
+ && c[6] == QLatin1Char('l') && c[7] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 9: {
+ if (check_reserved) {
+ if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
+ && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
+ && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('f')
+ && c[6] == QLatin1Char('a') && c[7] == QLatin1Char('c')
+ && c[8] == QLatin1Char('e'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('n')
+ && c[4] == QLatin1Char('s') && c[5] == QLatin1Char('i')
+ && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
+ && c[8] == QLatin1Char('t'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
+ && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('c')
+ && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('e')
+ && c[8] == QLatin1Char('d'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 10: {
+ if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
+ && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
+ && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('n')
+ && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('e')
+ && c[8] == QLatin1Char('o') && c[9] == QLatin1Char('f'))
+ return QScriptGrammar::T_INSTANCEOF;
+ else if (check_reserved) {
+ if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
+ && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('l')
+ && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('m')
+ && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
+ && c[8] == QLatin1Char('t') && c[9] == QLatin1Char('s'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ case 12: {
+ if (check_reserved) {
+ if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('y')
+ && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
+ && c[4] == QLatin1Char('h') && c[5] == QLatin1Char('r')
+ && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n')
+ && c[8] == QLatin1Char('i') && c[9] == QLatin1Char('z')
+ && c[10] == QLatin1Char('e') && c[11] == QLatin1Char('d'))
+ return QScriptGrammar::T_RESERVED_WORD;
+ }
+ } break;
+
+ } // switch
+
+ return -1;
+}
+
+int QScript::Lexer::lex()
+{
+ int token = 0;
+ state = Start;
+ ushort stringType = 0; // either single or double quotes
+ pos8 = pos16 = 0;
+ done = false;
+ terminator = false;
+
+ // did we push a token on the stack previously ?
+ // (after an automatic semicolon insertion)
+ if (stackToken >= 0) {
+ setDone(Other);
+ token = stackToken;
+ stackToken = -1;
+ }
+
+ while (!done) {
+ switch (state) {
+ case Start:
+ if (isWhiteSpace()) {
+ // do nothing
+ } else if (current == '/' && next1 == '/') {
+ recordStartPos();
+ shift(1);
+ Q_ASSERT(pos16 == 0);
+ state = InSingleLineComment;
+ } else if (current == '/' && next1 == '*') {
+ recordStartPos();
+ shift(1);
+ Q_ASSERT(pos16 == 0);
+ state = InMultiLineComment;
+ } else if (current == 0) {
+ syncProhibitAutomaticSemicolon();
+ if (!terminator && !delimited && !prohibitAutomaticSemicolon) {
+ // automatic semicolon insertion if program incomplete
+ token = QScriptGrammar::T_SEMICOLON;
+ stackToken = 0;
+ setDone(Other);
+ } else {
+ setDone(Eof);
+ }
+ } else if (isLineTerminator()) {
+ shiftWindowsLineBreak();
+ yylineno++;
+ yycolumn = 0;
+ bol = true;
+ terminator = true;
+ syncProhibitAutomaticSemicolon();
+ if (restrKeyword) {
+ token = QScriptGrammar::T_SEMICOLON;
+ setDone(Other);
+ }
+ } else if (current == '"' || current == '\'') {
+ recordStartPos();
+ state = InString;
+ stringType = current;
+ } else if (isIdentLetter(current)) {
+ recordStartPos();
+ record16(current);
+ state = InIdentifier;
+ } else if (current == '0') {
+ recordStartPos();
+ record8(current);
+ state = InNum0;
+ } else if (isDecimalDigit(current)) {
+ recordStartPos();
+ record8(current);
+ state = InNum;
+ } else if (current == '.' && isDecimalDigit(next1)) {
+ recordStartPos();
+ record8(current);
+ state = InDecimal;
+ } else {
+ recordStartPos();
+ token = matchPunctuator(current, next1, next2, next3);
+ if (token != -1) {
+ if (terminator && !delimited && !prohibitAutomaticSemicolon
+ && (token == QScriptGrammar::T_PLUS_PLUS
+ || token == QScriptGrammar::T_MINUS_MINUS)) {
+ // automatic semicolon insertion
+ stackToken = token;
+ token = QScriptGrammar::T_SEMICOLON;
+ }
+ setDone(Other);
+ }
+ else {
+ setDone(Bad);
+ err = IllegalCharacter;
+ errmsg = LU::tr("Illegal character");
+ }
+ }
+ break;
+ case InString:
+ if (current == stringType) {
+ shift(1);
+ setDone(String);
+ } else if (current == 0 || isLineTerminator()) {
+ setDone(Bad);
+ err = UnclosedStringLiteral;
+ errmsg = LU::tr("Unclosed string at end of line");
+ } else if (current == '\\') {
+ state = InEscapeSequence;
+ } else {
+ record16(current);
+ }
+ break;
+ // Escape Sequences inside of strings
+ case InEscapeSequence:
+ if (isOctalDigit(current)) {
+ if (current >= '0' && current <= '3' &&
+ isOctalDigit(next1) && isOctalDigit(next2)) {
+ record16(convertOctal(current, next1, next2));
+ shift(2);
+ state = InString;
+ } else if (isOctalDigit(current) &&
+ isOctalDigit(next1)) {
+ record16(convertOctal('0', current, next1));
+ shift(1);
+ state = InString;
+ } else if (isOctalDigit(current)) {
+ record16(convertOctal('0', '0', current));
+ state = InString;
+ } else {
+ setDone(Bad);
+ err = IllegalEscapeSequence;
+ errmsg = LU::tr("Illegal escape sequence");
+ }
+ } else if (current == 'x')
+ state = InHexEscape;
+ else if (current == 'u')
+ state = InUnicodeEscape;
+ else {
+ record16(singleEscape(current));
+ state = InString;
+ }
+ break;
+ case InHexEscape:
+ if (isHexDigit(current) && isHexDigit(next1)) {
+ state = InString;
+ record16(QLatin1Char(convertHex(current, next1)));
+ shift(1);
+ } else if (current == stringType) {
+ record16(QLatin1Char('x'));
+ shift(1);
+ setDone(String);
+ } else {
+ record16(QLatin1Char('x'));
+ record16(current);
+ state = InString;
+ }
+ break;
+ case InUnicodeEscape:
+ if (isHexDigit(current) && isHexDigit(next1) &&
+ isHexDigit(next2) && isHexDigit(next3)) {
+ record16(convertUnicode(current, next1, next2, next3));
+ shift(3);
+ state = InString;
+ } else if (current == stringType) {
+ record16(QLatin1Char('u'));
+ shift(1);
+ setDone(String);
+ } else {
+ setDone(Bad);
+ err = IllegalUnicodeEscapeSequence;
+ errmsg = LU::tr("Illegal unicode escape sequence");
+ }
+ break;
+ case InSingleLineComment:
+ if (isLineTerminator()) {
+ record16(current); // include newline
+ processComment(buffer16, pos16);
+ shiftWindowsLineBreak();
+ yylineno++;
+ yycolumn = 0;
+ pos16 = 0;
+ terminator = true;
+ bol = true;
+ if (restrKeyword) {
+ token = QScriptGrammar::T_SEMICOLON;
+ setDone(Other);
+ } else
+ state = Start;
+ } else if (current == 0) {
+ setDone(Eof);
+ } else {
+ record16(current);
+ }
+ break;
+ case InMultiLineComment:
+ if (current == 0) {
+ setDone(Bad);
+ err = UnclosedComment;
+ errmsg = LU::tr("Unclosed comment at end of file");
+ } else if (isLineTerminator()) {
+ shiftWindowsLineBreak();
+ yylineno++;
+ } else if (current == '*' && next1 == '/') {
+ processComment(buffer16, pos16);
+ pos16 = 0;
+ state = Start;
+ shift(1);
+ } else {
+ record16(current);
+ }
+ break;
+ case InIdentifier:
+ if (isIdentLetter(current) || isDecimalDigit(current)) {
+ record16(current);
+ break;
+ }
+ setDone(Identifier);
+ break;
+ case InNum0:
+ if (current == 'x' || current == 'X') {
+ record8(current);
+ state = InHex;
+ } else if (current == '.') {
+ record8(current);
+ state = InDecimal;
+ } else if (current == 'e' || current == 'E') {
+ record8(current);
+ state = InExponentIndicator;
+ } else if (isOctalDigit(current)) {
+ record8(current);
+ state = InOctal;
+ } else if (isDecimalDigit(current)) {
+ record8(current);
+ state = InDecimal;
+ } else {
+ setDone(Number);
+ }
+ break;
+ case InHex:
+ if (isHexDigit(current))
+ record8(current);
+ else
+ setDone(Hex);
+ break;
+ case InOctal:
+ if (isOctalDigit(current)) {
+ record8(current);
+ } else if (isDecimalDigit(current)) {
+ record8(current);
+ state = InDecimal;
+ } else {
+ setDone(Octal);
+ }
+ break;
+ case InNum:
+ if (isDecimalDigit(current)) {
+ record8(current);
+ } else if (current == '.') {
+ record8(current);
+ state = InDecimal;
+ } else if (current == 'e' || current == 'E') {
+ record8(current);
+ state = InExponentIndicator;
+ } else {
+ setDone(Number);
+ }
+ break;
+ case InDecimal:
+ if (isDecimalDigit(current)) {
+ record8(current);
+ } else if (current == 'e' || current == 'E') {
+ record8(current);
+ state = InExponentIndicator;
+ } else {
+ setDone(Number);
+ }
+ break;
+ case InExponentIndicator:
+ if (current == '+' || current == '-') {
+ record8(current);
+ } else if (isDecimalDigit(current)) {
+ record8(current);
+ state = InExponent;
+ } else {
+ setDone(Bad);
+ err = IllegalExponentIndicator;
+ errmsg = LU::tr("Illegal syntax for exponential number");
+ }
+ break;
+ case InExponent:
+ if (isDecimalDigit(current)) {
+ record8(current);
+ } else {
+ setDone(Number);
+ }
+ break;
+ default:
+ Q_ASSERT_X(0, "Lexer::lex", "Unhandled state in switch statement");
+ }
+
+ // move on to the next character
+ if (!done)
+ shift(1);
+ if (state != Start && state != InSingleLineComment)
+ bol = false;
+ }
+
+ // no identifiers allowed directly after numeric literal, e.g. "3in" is bad
+ if ((state == Number || state == Octal || state == Hex)
+ && isIdentLetter(current)) {
+ state = Bad;
+ err = IllegalIdentifier;
+ errmsg = LU::tr("Identifier cannot start with numeric literal");
+ }
+
+ // terminate string
+ buffer8[pos8] = '\0';
+
+ double dval = 0;
+ if (state == Number) {
+ dval = qstrtod(buffer8, 0, 0);
+ } else if (state == Hex) { // scan hex numbers
+ dval = QScript::integerFromString(buffer8, pos8, 16);
+ state = Number;
+ } else if (state == Octal) { // scan octal number
+ dval = QScript::integerFromString(buffer8, pos8, 8);
+ state = Number;
+ }
+
+ restrKeyword = false;
+ delimited = false;
+
+ switch (parenthesesState) {
+ case IgnoreParentheses:
+ break;
+ case CountParentheses:
+ if (token == QScriptGrammar::T_RPAREN) {
+ --parenthesesCount;
+ if (parenthesesCount == 0)
+ parenthesesState = BalancedParentheses;
+ } else if (token == QScriptGrammar::T_LPAREN) {
+ ++parenthesesCount;
+ }
+ break;
+ case BalancedParentheses:
+ parenthesesState = IgnoreParentheses;
+ break;
+ }
+
+ switch (state) {
+ case Eof:
+ return 0;
+ case Other:
+ if(token == QScriptGrammar::T_RBRACE || token == QScriptGrammar::T_SEMICOLON)
+ delimited = true;
+ return token;
+ case Identifier:
+ if ((token = findReservedWord(buffer16, pos16)) < 0) {
+ /* TODO: close leak on parse error. same holds true for String */
+ qsyylval = QString(buffer16, pos16);
+ return QScriptGrammar::T_IDENTIFIER;
+ }
+ if (token == QScriptGrammar::T_CONTINUE || token == QScriptGrammar::T_BREAK
+ || token == QScriptGrammar::T_RETURN || token == QScriptGrammar::T_THROW) {
+ restrKeyword = true;
+ } else if (token == QScriptGrammar::T_IF || token == QScriptGrammar::T_FOR
+ || token == QScriptGrammar::T_WHILE || token == QScriptGrammar::T_WITH) {
+ parenthesesState = CountParentheses;
+ parenthesesCount = 0;
+ } else if (token == QScriptGrammar::T_DO) {
+ parenthesesState = BalancedParentheses;
+ }
+ return token;
+ case String:
+ qsyylval = QString(buffer16, pos16);
+ return QScriptGrammar::T_STRING_LITERAL;
+ case Number:
+ qsyylval = dval;
+ return QScriptGrammar::T_NUMERIC_LITERAL;
+ case Bad:
+ return -1;
+ default:
+ Q_ASSERT(!"unhandled numeration value in switch");
+ return -1;
+ }
+}
+
+bool QScript::Lexer::isWhiteSpace() const
+{
+ return (current == ' ' || current == '\t' ||
+ current == 0x0b || current == 0x0c);
+}
+
+bool QScript::Lexer::isLineTerminator() const
+{
+ return (current == '\n' || current == '\r');
+}
+
+bool QScript::Lexer::isIdentLetter(ushort c)
+{
+ /* TODO: allow other legitimate unicode chars */
+ return ((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || c == '$'
+ || c == '_');
+}
+
+bool QScript::Lexer::isDecimalDigit(ushort c)
+{
+ return (c >= '0' && c <= '9');
+}
+
+bool QScript::Lexer::isHexDigit(ushort c) const
+{
+ return ((c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'f')
+ || (c >= 'A' && c <= 'F'));
+}
+
+bool QScript::Lexer::isOctalDigit(ushort c) const
+{
+ return (c >= '0' && c <= '7');
+}
+
+int QScript::Lexer::matchPunctuator(ushort c1, ushort c2,
+ ushort c3, ushort c4)
+{
+ if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
+ shift(4);
+ return QScriptGrammar::T_GT_GT_GT_EQ;
+ } else if (c1 == '=' && c2 == '=' && c3 == '=') {
+ shift(3);
+ return QScriptGrammar::T_EQ_EQ_EQ;
+ } else if (c1 == '!' && c2 == '=' && c3 == '=') {
+ shift(3);
+ return QScriptGrammar::T_NOT_EQ_EQ;
+ } else if (c1 == '>' && c2 == '>' && c3 == '>') {
+ shift(3);
+ return QScriptGrammar::T_GT_GT_GT;
+ } else if (c1 == '<' && c2 == '<' && c3 == '=') {
+ shift(3);
+ return QScriptGrammar::T_LT_LT_EQ;
+ } else if (c1 == '>' && c2 == '>' && c3 == '=') {
+ shift(3);
+ return QScriptGrammar::T_GT_GT_EQ;
+ } else if (c1 == '<' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_LE;
+ } else if (c1 == '>' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_GE;
+ } else if (c1 == '!' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_NOT_EQ;
+ } else if (c1 == '+' && c2 == '+') {
+ shift(2);
+ return QScriptGrammar::T_PLUS_PLUS;
+ } else if (c1 == '-' && c2 == '-') {
+ shift(2);
+ return QScriptGrammar::T_MINUS_MINUS;
+ } else if (c1 == '=' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_EQ_EQ;
+ } else if (c1 == '+' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_PLUS_EQ;
+ } else if (c1 == '-' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_MINUS_EQ;
+ } else if (c1 == '*' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_STAR_EQ;
+ } else if (c1 == '/' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_DIVIDE_EQ;
+ } else if (c1 == '&' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_AND_EQ;
+ } else if (c1 == '^' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_XOR_EQ;
+ } else if (c1 == '%' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_REMAINDER_EQ;
+ } else if (c1 == '|' && c2 == '=') {
+ shift(2);
+ return QScriptGrammar::T_OR_EQ;
+ } else if (c1 == '<' && c2 == '<') {
+ shift(2);
+ return QScriptGrammar::T_LT_LT;
+ } else if (c1 == '>' && c2 == '>') {
+ shift(2);
+ return QScriptGrammar::T_GT_GT;
+ } else if (c1 == '&' && c2 == '&') {
+ shift(2);
+ return QScriptGrammar::T_AND_AND;
+ } else if (c1 == '|' && c2 == '|') {
+ shift(2);
+ return QScriptGrammar::T_OR_OR;
+ }
+
+ switch(c1) {
+ case '=': shift(1); return QScriptGrammar::T_EQ;
+ case '>': shift(1); return QScriptGrammar::T_GT;
+ case '<': shift(1); return QScriptGrammar::T_LT;
+ case ',': shift(1); return QScriptGrammar::T_COMMA;
+ case '!': shift(1); return QScriptGrammar::T_NOT;
+ case '~': shift(1); return QScriptGrammar::T_TILDE;
+ case '?': shift(1); return QScriptGrammar::T_QUESTION;
+ case ':': shift(1); return QScriptGrammar::T_COLON;
+ case '.': shift(1); return QScriptGrammar::T_DOT;
+ case '+': shift(1); return QScriptGrammar::T_PLUS;
+ case '-': shift(1); return QScriptGrammar::T_MINUS;
+ case '*': shift(1); return QScriptGrammar::T_STAR;
+ case '/': shift(1); return QScriptGrammar::T_DIVIDE_;
+ case '&': shift(1); return QScriptGrammar::T_AND;
+ case '|': shift(1); return QScriptGrammar::T_OR;
+ case '^': shift(1); return QScriptGrammar::T_XOR;
+ case '%': shift(1); return QScriptGrammar::T_REMAINDER;
+ case '(': shift(1); return QScriptGrammar::T_LPAREN;
+ case ')': shift(1); return QScriptGrammar::T_RPAREN;
+ case '{': shift(1); return QScriptGrammar::T_LBRACE;
+ case '}': shift(1); return QScriptGrammar::T_RBRACE;
+ case '[': shift(1); return QScriptGrammar::T_LBRACKET;
+ case ']': shift(1); return QScriptGrammar::T_RBRACKET;
+ case ';': shift(1); return QScriptGrammar::T_SEMICOLON;
+
+ default: return -1;
+ }
+}
+
+ushort QScript::Lexer::singleEscape(ushort c) const
+{
+ switch(c) {
+ case 'b':
+ return 0x08;
+ case 't':
+ return 0x09;
+ case 'n':
+ return 0x0A;
+ case 'v':
+ return 0x0B;
+ case 'f':
+ return 0x0C;
+ case 'r':
+ return 0x0D;
+ case '"':
+ return 0x22;
+ case '\'':
+ return 0x27;
+ case '\\':
+ return 0x5C;
+ default:
+ return c;
+ }
+}
+
+ushort QScript::Lexer::convertOctal(ushort c1, ushort c2,
+ ushort c3) const
+{
+ return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
+}
+
+unsigned char QScript::Lexer::convertHex(ushort c)
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ else if (c >= 'a' && c <= 'f')
+ return (c - 'a' + 10);
+ else
+ return (c - 'A' + 10);
+}
+
+unsigned char QScript::Lexer::convertHex(ushort c1, ushort c2)
+{
+ return ((convertHex(c1) << 4) + convertHex(c2));
+}
+
+QChar QScript::Lexer::convertUnicode(ushort c1, ushort c2,
+ ushort c3, ushort c4)
+{
+ return QChar((convertHex(c3) << 4) + convertHex(c4),
+ (convertHex(c1) << 4) + convertHex(c2));
+}
+
+void QScript::Lexer::record8(ushort c)
+{
+ Q_ASSERT(c <= 0xff);
+
+ // enlarge buffer if full
+ if (pos8 >= size8 - 1) {
+ char *tmp = new char[2 * size8];
+ memcpy(tmp, buffer8, size8 * sizeof(char));
+ delete [] buffer8;
+ buffer8 = tmp;
+ size8 *= 2;
+ }
+
+ buffer8[pos8++] = (char) c;
+}
+
+void QScript::Lexer::record16(QChar c)
+{
+ // enlarge buffer if full
+ if (pos16 >= size16 - 1) {
+ QChar *tmp = new QChar[2 * size16];
+ memcpy(tmp, buffer16, size16 * sizeof(QChar));
+ delete [] buffer16;
+ buffer16 = tmp;
+ size16 *= 2;
+ }
+
+ buffer16[pos16++] = c;
+}
+
+void QScript::Lexer::recordStartPos()
+{
+ startlineno = yylineno;
+ startcolumn = yycolumn;
+}
+
+bool QScript::Lexer::scanRegExp(RegExpBodyPrefix prefix)
+{
+ pos16 = 0;
+ bool lastWasEscape = false;
+
+ if (prefix == EqualPrefix)
+ record16(QLatin1Char('='));
+
+ while (1) {
+ if (isLineTerminator() || current == 0) {
+ errmsg = LU::tr("Unterminated regular expression literal");
+ return false;
+ }
+ else if (current != '/' || lastWasEscape == true)
+ {
+ record16(current);
+ lastWasEscape = !lastWasEscape && (current == '\\');
+ }
+ else {
+ pattern = QString(buffer16, pos16);
+ pos16 = 0;
+ shift(1);
+ break;
+ }
+ shift(1);
+ }
+
+ flags = 0;
+ while (isIdentLetter(current)) {
+ record16(current);
+ shift(1);
+ }
+
+ return true;
+}
+
+void QScript::Lexer::syncProhibitAutomaticSemicolon()
+{
+ if (parenthesesState == BalancedParentheses) {
+ // we have seen something like "if (foo)", which means we should
+ // never insert an automatic semicolon at this point, since it would
+ // then be expanded into an empty statement (ECMA-262 7.9.1)
+ prohibitAutomaticSemicolon = true;
+ parenthesesState = IgnoreParentheses;
+ } else {
+ prohibitAutomaticSemicolon = false;
+ }
+}
+
+void QScript::Lexer::processComment(const QChar *chars, int length)
+{
+ commentProcessor->processComment(chars, length);
+}
+
+
+class Translator;
+
+class QScriptParser: protected $table, public QScript::CommentProcessor
+{
+public:
+ QVariant val;
+
+ struct Location {
+ int startLine;
+ int startColumn;
+ int endLine;
+ int endColumn;
+ };
+
+public:
+ QScriptParser();
+ ~QScriptParser();
+
+ void setLexer(QScript::Lexer *);
+ void setTranslator(Translator *);
+
+ bool parse();
+
+ QString fileName() const
+ { return lexer->fileName(); }
+ inline QString errorMessage() const
+ { return error_message; }
+ inline int errorLineNumber() const
+ { return error_lineno; }
+ inline int errorColumnNumber() const
+ { return error_column; }
+
+protected:
+ inline void reallocateStack();
+
+ inline QVariant &sym(int index)
+ { return sym_stack [tos + index - 1]; }
+
+ inline Location &loc(int index)
+ { return location_stack [tos + index - 2]; }
+
+ std::ostream &yyMsg(int line = 0);
+
+ virtual void processComment(const QChar *, int);
+
+protected:
+ int tos;
+ int stack_size;
+ QVector<QVariant> sym_stack;
+ int *state_stack;
+ Location *location_stack;
+ QString error_message;
+ int error_lineno;
+ int error_column;
+
+private:
+ QScript::Lexer *lexer;
+ Translator *translator;
+ QString trcontext;
+ QString extracomment;
+ QString msgid;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
+};
+
+inline void QScriptParser::reallocateStack()
+{
+ if (! stack_size)
+ stack_size = 128;
+ else
+ stack_size <<= 1;
+
+ sym_stack.resize(stack_size);
+ state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
+ location_stack = reinterpret_cast<Location*> (qRealloc(location_stack, stack_size * sizeof(Location)));
+}
+
+inline static bool automatic(QScript::Lexer *lexer, int token)
+{
+ return (token == $table::T_RBRACE)
+ || (token == 0)
+ || lexer->prevTerminator();
+}
+
+QScriptParser::QScriptParser():
+ tos(0),
+ stack_size(0),
+ sym_stack(0),
+ state_stack(0),
+ location_stack(0),
+ lexer(0),
+ translator(0)
+{
+}
+
+QScriptParser::~QScriptParser()
+{
+ if (stack_size) {
+ qFree(state_stack);
+ qFree(location_stack);
+ }
+}
+
+static inline QScriptParser::Location location(QScript::Lexer *lexer)
+{
+ QScriptParser::Location loc;
+ loc.startLine = lexer->startLineNo();
+ loc.startColumn = lexer->startColumnNo();
+ loc.endLine = lexer->endLineNo();
+ loc.endColumn = lexer->endColumnNo();
+ return loc;
+}
+
+void QScriptParser::setLexer(QScript::Lexer *lex)
+{
+ lexer = lex;
+}
+
+void QScriptParser::setTranslator(Translator *tor)
+{
+ translator = tor;
+}
+
+bool QScriptParser::parse()
+{
+ Q_ASSERT(lexer != 0);
+ Q_ASSERT(translator != 0);
+ trcontext = QFileInfo(fileName()).baseName();
+
+ const int INITIAL_STATE = 0;
+
+ int yytoken = -1;
+ int saved_yytoken = -1;
+ int identLineNo = -1;
+
+ reallocateStack();
+
+ tos = 0;
+ state_stack[++tos] = INITIAL_STATE;
+
+ while (true)
+ {
+ const int state = state_stack [tos];
+ if (yytoken == -1 && - TERMINAL_COUNT != action_index [state])
+ {
+ if (saved_yytoken == -1)
+ {
+ yytoken = lexer->lex();
+ location_stack [tos] = location(lexer);
+ }
+ else
+ {
+ yytoken = saved_yytoken;
+ saved_yytoken = -1;
+ }
+ }
+
+ int act = t_action (state, yytoken);
+
+ if (act == ACCEPT_STATE)
+ return true;
+
+ else if (act > 0)
+ {
+ if (++tos == stack_size)
+ reallocateStack();
+
+ sym_stack [tos] = lexer->val ();
+ state_stack [tos] = act;
+ location_stack [tos] = location(lexer);
+ yytoken = -1;
+ }
+
+ else if (act < 0)
+ {
+ int r = - act - 1;
+
+ tos -= rhs [r];
+ act = state_stack [tos++];
+
+ switch (r) {
+./
+
+PrimaryExpression: T_THIS ;
+
+PrimaryExpression: T_IDENTIFIER ;
+/.
+case $rule_number: {
+ sym(1) = sym(1).toByteArray();
+ identLineNo = lexer->startLineNo();
+} break;
+./
+
+PrimaryExpression: T_NULL ;
+PrimaryExpression: T_TRUE ;
+PrimaryExpression: T_FALSE ;
+PrimaryExpression: T_NUMERIC_LITERAL ;
+PrimaryExpression: T_STRING_LITERAL ;
+
+PrimaryExpression: T_DIVIDE_ ;
+/:
+#define Q_SCRIPT_REGEXPLITERAL_RULE1 $rule_number
+:/
+/.
+case $rule_number: {
+ bool rx = lexer->scanRegExp(QScript::Lexer::NoPrefix);
+ if (!rx) {
+ error_message = lexer->errorMessage();
+ error_lineno = lexer->startLineNo();
+ error_column = lexer->startColumnNo();
+ return false;
+ }
+} break;
+./
+
+PrimaryExpression: T_DIVIDE_EQ ;
+/:
+#define Q_SCRIPT_REGEXPLITERAL_RULE2 $rule_number
+:/
+/.
+case $rule_number: {
+ bool rx = lexer->scanRegExp(QScript::Lexer::EqualPrefix);
+ if (!rx) {
+ error_message = lexer->errorMessage();
+ error_lineno = lexer->startLineNo();
+ error_column = lexer->startColumnNo();
+ return false;
+ }
+} break;
+./
+
+PrimaryExpression: T_LBRACKET ElisionOpt T_RBRACKET ;
+PrimaryExpression: T_LBRACKET ElementList T_RBRACKET ;
+PrimaryExpression: T_LBRACKET ElementList T_COMMA ElisionOpt T_RBRACKET ;
+PrimaryExpression: T_LBRACE PropertyNameAndValueListOpt T_RBRACE ;
+PrimaryExpression: T_LPAREN Expression T_RPAREN ;
+ElementList: ElisionOpt AssignmentExpression ;
+ElementList: ElementList T_COMMA ElisionOpt AssignmentExpression ;
+Elision: T_COMMA ;
+Elision: Elision T_COMMA ;
+ElisionOpt: ;
+ElisionOpt: Elision ;
+PropertyNameAndValueList: PropertyName T_COLON AssignmentExpression ;
+PropertyNameAndValueList: PropertyNameAndValueList T_COMMA PropertyName T_COLON AssignmentExpression ;
+PropertyName: T_IDENTIFIER ;
+PropertyName: T_STRING_LITERAL ;
+PropertyName: T_NUMERIC_LITERAL ;
+PropertyName: ReservedIdentifier ;
+ReservedIdentifier: T_BREAK ;
+ReservedIdentifier: T_CASE ;
+ReservedIdentifier: T_CATCH ;
+ReservedIdentifier: T_CONST ;
+ReservedIdentifier: T_CONTINUE ;
+ReservedIdentifier: T_DEBUGGER ;
+ReservedIdentifier: T_DEFAULT ;
+ReservedIdentifier: T_DELETE ;
+ReservedIdentifier: T_DO ;
+ReservedIdentifier: T_ELSE ;
+ReservedIdentifier: T_FALSE ;
+ReservedIdentifier: T_FINALLY ;
+ReservedIdentifier: T_FOR ;
+ReservedIdentifier: T_FUNCTION ;
+ReservedIdentifier: T_IF ;
+ReservedIdentifier: T_IN ;
+ReservedIdentifier: T_INSTANCEOF ;
+ReservedIdentifier: T_NEW ;
+ReservedIdentifier: T_NULL ;
+ReservedIdentifier: T_RESERVED_WORD ;
+ReservedIdentifier: T_RETURN ;
+ReservedIdentifier: T_SWITCH ;
+ReservedIdentifier: T_THIS ;
+ReservedIdentifier: T_THROW ;
+ReservedIdentifier: T_TRUE ;
+ReservedIdentifier: T_TRY ;
+ReservedIdentifier: T_TYPEOF ;
+ReservedIdentifier: T_VAR ;
+ReservedIdentifier: T_VOID ;
+ReservedIdentifier: T_WHILE ;
+ReservedIdentifier: T_WITH ;
+PropertyIdentifier: T_IDENTIFIER ;
+PropertyIdentifier: ReservedIdentifier ;
+
+MemberExpression: PrimaryExpression ;
+MemberExpression: FunctionExpression ;
+MemberExpression: MemberExpression T_LBRACKET Expression T_RBRACKET ;
+MemberExpression: MemberExpression T_DOT PropertyIdentifier ;
+MemberExpression: T_NEW MemberExpression Arguments ;
+NewExpression: MemberExpression ;
+NewExpression: T_NEW NewExpression ;
+
+CallExpression: MemberExpression Arguments ;
+/.
+case $rule_number: {
+ QString name = sym(1).toString();
+ if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
+ QVariantList args = sym(2).toList();
+ if (args.size() < 2) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least two arguments.\n").arg(name));
+ } else {
+ if ((args.at(0).type() != QVariant::String)
+ || (args.at(1).type() != QVariant::String)) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): both arguments must be literal strings.\n").arg(name));
+ } else {
+ QString context = args.at(0).toString();
+ QString text = args.at(1).toString();
+ QString comment = args.value(2).toString();
+ bool plural = (args.size() > 4);
+ recordMessage(translator, context, text, comment, extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ } else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
+ QVariantList args = sym(2).toList();
+ if (args.size() < 1) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name));
+ } else {
+ if (args.at(0).type() != QVariant::String) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name));
+ } else {
+ QString text = args.at(0).toString();
+ QString comment = args.value(1).toString();
+ bool plural = (args.size() > 2);
+ recordMessage(translator, trcontext, text, comment, extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ } else if ((name == QLatin1String("qsTrId")) || (name == QLatin1String("QT_TRID_NOOP"))) {
+ if (!msgid.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//= cannot be used with %1(). Ignoring\n").arg(name));
+ QVariantList args = sym(2).toList();
+ if (args.size() < 1) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name));
+ } else {
+ if (args.at(0).type() != QVariant::String) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): identifier must be a literal string.\n").arg(name));
+ } else {
+ msgid = args.at(0).toString();
+ bool plural = (args.size() > 1);
+ recordMessage(translator, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
+} break;
+./
+
+CallExpression: CallExpression Arguments ;
+CallExpression: CallExpression T_LBRACKET Expression T_RBRACKET ;
+CallExpression: CallExpression T_DOT PropertyIdentifier ;
+
+Arguments: T_LPAREN T_RPAREN ;
+/.
+case $rule_number: {
+ sym(1) = QVariantList();
+} break;
+./
+
+Arguments: T_LPAREN ArgumentList T_RPAREN ;
+/.
+case $rule_number: {
+ sym(1) = sym(2);
+} break;
+./
+
+ArgumentList: AssignmentExpression ;
+/.
+case $rule_number: {
+ sym(1) = QVariantList() << sym(1);
+} break;
+./
+
+ArgumentList: ArgumentList T_COMMA AssignmentExpression ;
+/.
+case $rule_number: {
+ sym(1) = sym(1).toList() << sym(3);
+} break;
+./
+
+LeftHandSideExpression: NewExpression ;
+LeftHandSideExpression: CallExpression ;
+PostfixExpression: LeftHandSideExpression ;
+PostfixExpression: LeftHandSideExpression T_PLUS_PLUS ;
+PostfixExpression: LeftHandSideExpression T_MINUS_MINUS ;
+UnaryExpression: PostfixExpression ;
+UnaryExpression: T_DELETE UnaryExpression ;
+UnaryExpression: T_VOID UnaryExpression ;
+UnaryExpression: T_TYPEOF UnaryExpression ;
+UnaryExpression: T_PLUS_PLUS UnaryExpression ;
+UnaryExpression: T_MINUS_MINUS UnaryExpression ;
+UnaryExpression: T_PLUS UnaryExpression ;
+UnaryExpression: T_MINUS UnaryExpression ;
+UnaryExpression: T_TILDE UnaryExpression ;
+UnaryExpression: T_NOT UnaryExpression ;
+MultiplicativeExpression: UnaryExpression ;
+MultiplicativeExpression: MultiplicativeExpression T_STAR UnaryExpression ;
+MultiplicativeExpression: MultiplicativeExpression T_DIVIDE_ UnaryExpression ;
+MultiplicativeExpression: MultiplicativeExpression T_REMAINDER UnaryExpression ;
+AdditiveExpression: MultiplicativeExpression ;
+
+AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression ;
+/.
+case $rule_number: {
+ if ((sym(1).type() == QVariant::String) || (sym(3).type() == QVariant::String))
+ sym(1) = sym(1).toString() + sym(3).toString();
+ else
+ sym(1) = QVariant();
+} break;
+./
+
+AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression ;
+ShiftExpression: AdditiveExpression ;
+ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression ;
+ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression ;
+ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression ;
+RelationalExpression: ShiftExpression ;
+RelationalExpression: RelationalExpression T_LT ShiftExpression ;
+RelationalExpression: RelationalExpression T_GT ShiftExpression ;
+RelationalExpression: RelationalExpression T_LE ShiftExpression ;
+RelationalExpression: RelationalExpression T_GE ShiftExpression ;
+RelationalExpression: RelationalExpression T_INSTANCEOF ShiftExpression ;
+RelationalExpression: RelationalExpression T_IN ShiftExpression ;
+RelationalExpressionNotIn: ShiftExpression ;
+RelationalExpressionNotIn: RelationalExpressionNotIn T_LT ShiftExpression ;
+RelationalExpressionNotIn: RelationalExpressionNotIn T_GT ShiftExpression ;
+RelationalExpressionNotIn: RelationalExpressionNotIn T_LE ShiftExpression ;
+RelationalExpressionNotIn: RelationalExpressionNotIn T_GE ShiftExpression ;
+RelationalExpressionNotIn: RelationalExpressionNotIn T_INSTANCEOF ShiftExpression ;
+EqualityExpression: RelationalExpression ;
+EqualityExpression: EqualityExpression T_EQ_EQ RelationalExpression ;
+EqualityExpression: EqualityExpression T_NOT_EQ RelationalExpression ;
+EqualityExpression: EqualityExpression T_EQ_EQ_EQ RelationalExpression ;
+EqualityExpression: EqualityExpression T_NOT_EQ_EQ RelationalExpression ;
+EqualityExpressionNotIn: RelationalExpressionNotIn ;
+EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ RelationalExpressionNotIn ;
+EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ RelationalExpressionNotIn;
+EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ_EQ RelationalExpressionNotIn ;
+EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ_EQ RelationalExpressionNotIn ;
+BitwiseANDExpression: EqualityExpression ;
+BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression ;
+BitwiseANDExpressionNotIn: EqualityExpressionNotIn ;
+BitwiseANDExpressionNotIn: BitwiseANDExpressionNotIn T_AND EqualityExpressionNotIn ;
+BitwiseXORExpression: BitwiseANDExpression ;
+BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression ;
+BitwiseXORExpressionNotIn: BitwiseANDExpressionNotIn ;
+BitwiseXORExpressionNotIn: BitwiseXORExpressionNotIn T_XOR BitwiseANDExpressionNotIn ;
+BitwiseORExpression: BitwiseXORExpression ;
+BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression ;
+BitwiseORExpressionNotIn: BitwiseXORExpressionNotIn ;
+BitwiseORExpressionNotIn: BitwiseORExpressionNotIn T_OR BitwiseXORExpressionNotIn ;
+LogicalANDExpression: BitwiseORExpression ;
+LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression ;
+LogicalANDExpressionNotIn: BitwiseORExpressionNotIn ;
+LogicalANDExpressionNotIn: LogicalANDExpressionNotIn T_AND_AND BitwiseORExpressionNotIn ;
+LogicalORExpression: LogicalANDExpression ;
+LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression ;
+LogicalORExpressionNotIn: LogicalANDExpressionNotIn ;
+LogicalORExpressionNotIn: LogicalORExpressionNotIn T_OR_OR LogicalANDExpressionNotIn ;
+ConditionalExpression: LogicalORExpression ;
+ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression ;
+ConditionalExpressionNotIn: LogicalORExpressionNotIn ;
+ConditionalExpressionNotIn: LogicalORExpressionNotIn T_QUESTION AssignmentExpressionNotIn T_COLON AssignmentExpressionNotIn ;
+AssignmentExpression: ConditionalExpression ;
+AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression ;
+AssignmentExpressionNotIn: ConditionalExpressionNotIn ;
+AssignmentExpressionNotIn: LeftHandSideExpression AssignmentOperator AssignmentExpressionNotIn ;
+AssignmentOperator: T_EQ ;
+AssignmentOperator: T_STAR_EQ ;
+AssignmentOperator: T_DIVIDE_EQ ;
+AssignmentOperator: T_REMAINDER_EQ ;
+AssignmentOperator: T_PLUS_EQ ;
+AssignmentOperator: T_MINUS_EQ ;
+AssignmentOperator: T_LT_LT_EQ ;
+AssignmentOperator: T_GT_GT_EQ ;
+AssignmentOperator: T_GT_GT_GT_EQ ;
+AssignmentOperator: T_AND_EQ ;
+AssignmentOperator: T_XOR_EQ ;
+AssignmentOperator: T_OR_EQ ;
+Expression: AssignmentExpression ;
+Expression: Expression T_COMMA AssignmentExpression ;
+ExpressionOpt: ;
+ExpressionOpt: Expression ;
+ExpressionNotIn: AssignmentExpressionNotIn ;
+ExpressionNotIn: ExpressionNotIn T_COMMA AssignmentExpressionNotIn ;
+ExpressionNotInOpt: ;
+ExpressionNotInOpt: ExpressionNotIn ;
+
+Statement: Block ;
+/.
+ case $rule_number:
+./
+Statement: VariableStatement ;
+/.
+ case $rule_number:
+./
+Statement: EmptyStatement ;
+/.
+ case $rule_number:
+./
+Statement: ExpressionStatement ;
+/.
+ case $rule_number:
+./
+Statement: IfStatement ;
+/.
+ case $rule_number:
+./
+Statement: IterationStatement ;
+/.
+ case $rule_number:
+./
+Statement: ContinueStatement ;
+/.
+ case $rule_number:
+./
+Statement: BreakStatement ;
+/.
+ case $rule_number:
+./
+Statement: ReturnStatement ;
+/.
+ case $rule_number:
+./
+Statement: WithStatement ;
+/.
+ case $rule_number:
+./
+Statement: LabelledStatement ;
+/.
+ case $rule_number:
+./
+Statement: SwitchStatement ;
+/.
+ case $rule_number:
+./
+Statement: ThrowStatement ;
+/.
+ case $rule_number:
+./
+Statement: TryStatement ;
+/.
+ case $rule_number:
+./
+Statement: DebuggerStatement ;
+/.
+ case $rule_number:
+ if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) {
+ yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n"));
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
+ break;
+./
+
+Block: T_LBRACE StatementListOpt T_RBRACE ;
+StatementList: Statement ;
+StatementList: StatementList Statement ;
+StatementListOpt: ;
+StatementListOpt: StatementList ;
+VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ;
+VariableDeclarationKind: T_CONST ;
+VariableDeclarationKind: T_VAR ;
+VariableDeclarationList: VariableDeclaration ;
+VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration ;
+VariableDeclarationListNotIn: VariableDeclarationNotIn ;
+VariableDeclarationListNotIn: VariableDeclarationListNotIn T_COMMA VariableDeclarationNotIn ;
+VariableDeclaration: T_IDENTIFIER InitialiserOpt ;
+VariableDeclarationNotIn: T_IDENTIFIER InitialiserNotInOpt ;
+Initialiser: T_EQ AssignmentExpression ;
+InitialiserOpt: ;
+InitialiserOpt: Initialiser ;
+InitialiserNotIn: T_EQ AssignmentExpressionNotIn ;
+InitialiserNotInOpt: ;
+InitialiserNotInOpt: InitialiserNotIn ;
+EmptyStatement: T_SEMICOLON ;
+ExpressionStatement: Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+ExpressionStatement: Expression T_SEMICOLON ;
+IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement T_ELSE Statement ;
+IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement ;
+IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_SEMICOLON ;
+IterationStatement: T_WHILE T_LPAREN Expression T_RPAREN Statement ;
+IterationStatement: T_FOR T_LPAREN ExpressionNotInOpt T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
+IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
+IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression T_RPAREN Statement ;
+IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationNotIn T_IN Expression T_RPAREN Statement ;
+ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+ContinueStatement: T_CONTINUE T_SEMICOLON ;
+ContinueStatement: T_CONTINUE T_IDENTIFIER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+ContinueStatement: T_CONTINUE T_IDENTIFIER T_SEMICOLON ;
+BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+BreakStatement: T_BREAK T_SEMICOLON ;
+BreakStatement: T_BREAK T_IDENTIFIER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+BreakStatement: T_BREAK T_IDENTIFIER T_SEMICOLON ;
+ReturnStatement: T_RETURN ExpressionOpt T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+ReturnStatement: T_RETURN ExpressionOpt T_SEMICOLON ;
+WithStatement: T_WITH T_LPAREN Expression T_RPAREN Statement ;
+SwitchStatement: T_SWITCH T_LPAREN Expression T_RPAREN CaseBlock ;
+CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE ;
+CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE ;
+CaseClauses: CaseClause ;
+CaseClauses: CaseClauses CaseClause ;
+CaseClausesOpt: ;
+CaseClausesOpt: CaseClauses ;
+CaseClause: T_CASE Expression T_COLON StatementListOpt ;
+DefaultClause: T_DEFAULT T_COLON StatementListOpt ;
+LabelledStatement: T_IDENTIFIER T_COLON Statement ;
+ThrowStatement: T_THROW Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
+ThrowStatement: T_THROW Expression T_SEMICOLON ;
+TryStatement: T_TRY Block Catch ;
+TryStatement: T_TRY Block Finally ;
+TryStatement: T_TRY Block Catch Finally ;
+Catch: T_CATCH T_LPAREN T_IDENTIFIER T_RPAREN Block ;
+Finally: T_FINALLY Block ;
+DebuggerStatement: T_DEBUGGER ;
+FunctionDeclaration: T_FUNCTION T_IDENTIFIER T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+FunctionExpression: T_FUNCTION IdentifierOpt T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+FormalParameterList: T_IDENTIFIER ;
+FormalParameterList: FormalParameterList T_COMMA T_IDENTIFIER ;
+FormalParameterListOpt: ;
+FormalParameterListOpt: FormalParameterList ;
+FunctionBodyOpt: ;
+FunctionBodyOpt: FunctionBody ;
+FunctionBody: SourceElements ;
+Program: SourceElements ;
+SourceElements: SourceElement ;
+SourceElements: SourceElements SourceElement ;
+SourceElement: Statement ;
+SourceElement: FunctionDeclaration ;
+IdentifierOpt: ;
+IdentifierOpt: T_IDENTIFIER ;
+PropertyNameAndValueListOpt: ;
+PropertyNameAndValueListOpt: PropertyNameAndValueList ;
+
+/.
+ } // switch
+
+ state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
+
+ if (rhs[r] > 1) {
+ location_stack[tos - 1].endLine = location_stack[tos + rhs[r] - 2].endLine;
+ location_stack[tos - 1].endColumn = location_stack[tos + rhs[r] - 2].endColumn;
+ location_stack[tos] = location_stack[tos + rhs[r] - 1];
+ }
+ }
+
+ else
+ {
+ if (saved_yytoken == -1 && automatic (lexer, yytoken) && t_action (state, T_AUTOMATIC_SEMICOLON) > 0)
+ {
+ saved_yytoken = yytoken;
+ yytoken = T_SEMICOLON;
+ continue;
+ }
+
+ else if ((state == INITIAL_STATE) && (yytoken == 0)) {
+ // accept empty input
+ yytoken = T_SEMICOLON;
+ continue;
+ }
+
+ int ers = state;
+ int shifts = 0;
+ int reduces = 0;
+ int expected_tokens [3];
+ for (int tk = 0; tk < TERMINAL_COUNT; ++tk)
+ {
+ int k = t_action (ers, tk);
+
+ if (! k)
+ continue;
+ else if (k < 0)
+ ++reduces;
+ else if (spell [tk])
+ {
+ if (shifts < 3)
+ expected_tokens [shifts] = tk;
+ ++shifts;
+ }
+ }
+
+ error_message.clear ();
+ if (shifts && shifts < 3)
+ {
+ bool first = true;
+
+ for (int s = 0; s < shifts; ++s)
+ {
+ if (first)
+ error_message += QLatin1String ("Expected ");
+ //: Beginning of the string that contains
+ //: comma-separated list of expected tokens
+ error_message += LU::tr("Expected ");
+ else
+ error_message += QLatin1String (", ");
+
+ first = false;
+ error_message += QLatin1String("`");
+ error_message += QLatin1String (spell [expected_tokens [s]]);
+ error_message += QLatin1String("'");
+ }
+ }
+
+ if (error_message.isEmpty())
+ error_message = lexer->errorMessage();
+
+ error_lineno = lexer->startLineNo();
+ error_column = lexer->startColumnNo();
+
+ return false;
+ }
+ }
+
+ return false;
+}
+
+std::ostream &QScriptParser::yyMsg(int line)
+{
+ return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": ";
+}
+
+void QScriptParser::processComment(const QChar *chars, int length)
+{
+ if (!length)
+ return;
+ // Try to match the logic of the C++ parser.
+ if (*chars == QLatin1Char(':') && chars[1].isSpace()) {
+ extracomment += QString(chars+2, length-2);
+ } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) {
+ msgid = QString(chars+2, length-2).simplified();
+ } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) {
+ QString text = QString(chars+2, length-2).trimmed();
+ int k = text.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ extra.insert(text.left(k), text.mid(k + 1).trimmed());
+ } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) {
+ sourcetext.reserve(sourcetext.length() + length-2);
+ ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length();
+ int p = 2, c;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"') {
+ yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n"));
+ break;
+ }
+ forever {
+ if (p >= length) {
+ whoops:
+ yyMsg() << qPrintable(LU::tr("Unterminated meta string\n"));
+ break;
+ }
+ c = chars[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= length)
+ goto whoops;
+ c = chars[p++].unicode();
+ if (c == '\n')
+ goto whoops;
+ *ptr++ = '\\';
+ }
+ *ptr++ = c;
+ }
+ }
+ sourcetext.resize(ptr - (ushort *)sourcetext.data());
+ } else {
+ int idx = 0;
+ ushort c;
+ while ((c = chars[idx].unicode()) == ' ' || c == '\t' || c == '\n')
+ ++idx;
+ if (!memcmp(chars + idx, MagicComment.unicode(), MagicComment.length() * 2)) {
+ idx += MagicComment.length();
+ QString comment = QString(chars + idx, length - idx).simplified();
+ int k = comment.indexOf(QLatin1Char(' '));
+ if (k == -1) {
+ trcontext = comment;
+ } else {
+ trcontext = comment.left(k);
+ comment.remove(0, k + 1);
+ TranslatorMessage msg(
+ trcontext, QString(),
+ comment, QString(),
+ fileName(), lexer->startLineNo(), QStringList(),
+ TranslatorMessage::Finished, /*plural=*/false);
+ msg.setExtraComment(extracomment.simplified());
+ extracomment.clear();
+ translator->append(msg);
+ translator->setExtras(extra);
+ extra.clear();
+ }
+ }
+ }
+}
+
+
+bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
+{
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
+ return false;
+ }
+ QTextStream ts(&file);
+ QByteArray codecName;
+ if (!cd.m_codecForSource.isEmpty())
+ codecName = cd.m_codecForSource;
+ else
+ codecName = translator.codecName(); // Just because it should be latin1 already
+ ts.setCodec(QTextCodec::codecForName(codecName));
+ ts.setAutoDetectUnicode(true);
+
+ QString code = ts.readAll();
+ QScriptParser parser;
+ QScript::Lexer lexer(&parser);
+ lexer.setCode(code, filename, /*lineNumber=*/1);
+ parser.setLexer(&lexer);
+ parser.setTranslator(&translator);
+ if (!parser.parse()) {
+ std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": "
+ << qPrintable(parser.errorMessage()) << std::endl;
+ return false;
+ }
+
+ // Java uses UTF-16 internally and Jambi makes UTF-8 for tr() purposes of it.
+ translator.setCodecName("UTF-8");
+ return true;
+}
+
+QT_END_NAMESPACE
+./
diff --git a/src/linguist/lupdate/ui.cpp b/src/linguist/lupdate/ui.cpp
new file mode 100644
index 000000000..6bbd189ed
--- /dev/null
+++ b/src/linguist/lupdate/ui.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lupdate.h"
+
+#include <translator.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QString>
+
+#include <QtXml/QXmlAttributes>
+#include <QtXml/QXmlDefaultHandler>
+#include <QtXml/QXmlLocator>
+#include <QtXml/QXmlParseException>
+
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+class UiReader : public QXmlDefaultHandler
+{
+public:
+ UiReader(Translator &translator, ConversionData &cd)
+ : m_translator(translator), m_cd(cd), m_lineNumber(-1), m_isTrString(false),
+ m_needUtf8(translator.codecName() != "UTF-8")
+ {}
+
+ bool startElement(const QString &namespaceURI, const QString &localName,
+ const QString &qName, const QXmlAttributes &atts);
+ bool endElement(const QString &namespaceURI, const QString &localName,
+ const QString &qName);
+ bool characters(const QString &ch);
+ bool fatalError(const QXmlParseException &exception);
+
+ void setDocumentLocator(QXmlLocator *locator) { m_locator = locator; }
+
+private:
+ void flush();
+
+ Translator &m_translator;
+ ConversionData &m_cd;
+ QString m_context;
+ QString m_source;
+ QString m_comment;
+ QString m_extracomment;
+ QXmlLocator *m_locator;
+
+ QString m_accum;
+ int m_lineNumber;
+ bool m_isTrString;
+ bool m_needUtf8;
+};
+
+bool UiReader::startElement(const QString &namespaceURI,
+ const QString &localName, const QString &qName, const QXmlAttributes &atts)
+{
+ Q_UNUSED(namespaceURI);
+ Q_UNUSED(localName);
+
+ if (qName == QLatin1String("item")) { // UI3 menu entries
+ flush();
+ if (!atts.value(QLatin1String("text")).isEmpty()) {
+ m_source = atts.value(QLatin1String("text"));
+ m_isTrString = true;
+ if (!m_cd.m_noUiLines)
+ m_lineNumber = m_locator->lineNumber();
+ }
+ } else if (qName == QLatin1String("string")) {
+ flush();
+ if (atts.value(QLatin1String("notr")).isEmpty() ||
+ atts.value(QLatin1String("notr")) != QLatin1String("true")) {
+ m_isTrString = true;
+ m_comment = atts.value(QLatin1String("comment"));
+ m_extracomment = atts.value(QLatin1String("extracomment"));
+ if (!m_cd.m_noUiLines)
+ m_lineNumber = m_locator->lineNumber();
+ } else {
+ m_isTrString = false;
+ }
+ }
+ m_accum.clear();
+ return true;
+}
+
+bool UiReader::endElement(const QString &namespaceURI,
+ const QString &localName, const QString &qName)
+{
+ Q_UNUSED(namespaceURI);
+ Q_UNUSED(localName);
+
+ m_accum.replace(QLatin1String("\r\n"), QLatin1String("\n"));
+
+ if (qName == QLatin1String("class")) { // UI "header"
+ if (m_context.isEmpty())
+ m_context = m_accum;
+ } else if (qName == QLatin1String("string") && m_isTrString) {
+ m_source = m_accum;
+ } else if (qName == QLatin1String("comment")) { // FIXME: what's that?
+ m_comment = m_accum;
+ flush();
+ } else if (qName == QLatin1String("function")) { // UI3 embedded code
+ fetchtrInlinedCpp(m_accum, m_translator, m_context);
+ } else {
+ flush();
+ }
+ return true;
+}
+
+bool UiReader::characters(const QString &ch)
+{
+ m_accum += ch;
+ return true;
+}
+
+bool UiReader::fatalError(const QXmlParseException &exception)
+{
+ QString msg = LU::tr("XML error: Parse error at line %1, column %2 (%3).")
+ .arg(exception.lineNumber()).arg(exception.columnNumber())
+ .arg(exception.message());
+ m_cd.appendError(msg);
+ return false;
+}
+
+void UiReader::flush()
+{
+ if (!m_context.isEmpty() && !m_source.isEmpty()) {
+ TranslatorMessage msg(m_context, m_source,
+ m_comment, QString(), m_cd.m_sourceFileName,
+ m_lineNumber, QStringList());
+ msg.setExtraComment(m_extracomment);
+ if (m_needUtf8 && msg.needs8Bit())
+ msg.setUtf8(true);
+ m_translator.extend(msg);
+ }
+ m_source.clear();
+ m_comment.clear();
+ m_extracomment.clear();
+}
+
+bool loadUI(Translator &translator, const QString &filename, ConversionData &cd)
+{
+ cd.m_sourceFileName = filename;
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
+ return false;
+ }
+ QXmlInputSource in(&file);
+ QXmlSimpleReader reader;
+ reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), false);
+ reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true);
+ reader.setFeature(QLatin1String(
+ "http://trolltech.com/xml/features/report-whitespace-only-CharData"), false);
+ UiReader handler(translator, cd);
+ reader.setContentHandler(&handler);
+ reader.setErrorHandler(&handler);
+ bool result = reader.parse(in);
+ if (!result)
+ cd.appendError(LU::tr("Parse error in UI file"));
+ reader.setContentHandler(0);
+ reader.setErrorHandler(0);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/winmanifest.rc b/src/linguist/lupdate/winmanifest.rc
new file mode 100644
index 000000000..45c493576
--- /dev/null
+++ b/src/linguist/lupdate/winmanifest.rc
@@ -0,0 +1,4 @@
+#define RT_MANIFEST 24
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "lupdate.exe.manifest"
diff --git a/src/linguist/phrasebooks/danish.qph b/src/linguist/phrasebooks/danish.qph
new file mode 100644
index 000000000..fb06e6f3c
--- /dev/null
+++ b/src/linguist/phrasebooks/danish.qph
@@ -0,0 +1,1018 @@
+<!DOCTYPE QPH><QPH language="da">
+<phrase>
+ <source>About</source>
+ <target>Om</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>hurtigtast</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>brugervenlighed</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>genvejshåndtag</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>aktiv</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>markeringsafslutning</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>aktivt objekt</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>aktivt vindue</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>værktøjselement</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Altid øverst</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>forankringspunkt</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Anvend</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>tekstboks med automatisk udgang</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>automatisk gentagelse</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>automatisk kæde</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>automatisk rulning</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>automatisk rulning</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Tilbage</target>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Gennemse</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Annuller</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>undermenu</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>afkrydsningsfelt</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>afkrydsning</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>underordnet vindue</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>vælge</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>klikke</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Udklipsholder</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Luk</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>lukknap</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>skjule</target>
+ <definition>outline/disposition</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>kolonneoverskrift</target>
+ <definition>control/kontrolelement</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>kombinationsboks</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>kommandoknap</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>objektbeholder</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>kontekstafhængig hjælp</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>kontekstafhængig</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>kontrolelement</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Kopier</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Kopier hertil</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Opret genvej</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Opret genvej her</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Klip</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>standard</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>standardknap</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Slet</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>skrivebord</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>destination</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>dialogboks</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>handicap</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>usammenhængende markering</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>forankre</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>dokument</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>dobbeltklikke</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>trække</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>trække og slippe</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>kombinationsboks med rullepil</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>rulleliste</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>rullemenu</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Rediger</target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>Menuen Rediger</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>ellipse</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>integreret objekt</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Afslut</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>udvide</target>
+ <definition>an outline/en disposition</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Stifinder</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>udvidet markering</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>liste</target>
+ <definition>der tillader udvidet markering</definition>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>fil</target>
+</phrase>
+<phrase>
+ <source>File menu</source>
+ <target>Menuen Filer</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Søg</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Find næste</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Søg efter</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>mappe</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>skrifttype</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>skriftstørrelse</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>typografi</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>funktionstast</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>gruppeboks</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>håndtag</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Hjælp</target>
+</phrase>
+<phrase>
+ <source>Help menu</source>
+ <target>Menuen Hjælp</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Skjul</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>hierarkisk markering</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>holde nede</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>aktivt punkt</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>aktiv zone</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>ikon</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>ikke-aktiv</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>ikke-aktivt vindue</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>inputfokus</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Menuen Indsæt</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Indsæt objekt</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>indsætningspunkt</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>kursiv</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>etiket</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>liggende</target>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>sammenkæde</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>kæde</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Indsæt kæde her</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>liste</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>listevisningsboks</target>
+ <definition>control/kontrolelement</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>manuel kæde</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Maksimer</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>maksimeringsknap</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>menu</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>menulinje</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>menuknap</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>menupunkt</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>menutitel</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>meddelelsesboks</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimer</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>minimeringsknap</target>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>blandet værdi</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>modal</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>tilstand</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>ikke-modal</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>ændringstast</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>mus</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Flyt</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Flyt hertil</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>multiple document interface</target>
+ <definition>MDI</definition>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>liste</target>
+ <definition>der tillader flere markeringer</definition>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Denne computer</target>
+ <definition>icon/ikon</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Andre computere</target>
+ <definition>icon/ikon</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Ny</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Næste</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>objekt</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>OLE-træk og slip</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>integreret OLE-objekt</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>sammenkædet OLE-objekt</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>interaktiv OLE-træk og slip</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Ã…bn</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Ã…bn med</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>alternativknap</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>aktiveret indstilling</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>objektpakke</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Sideopsætning</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>paletvindue</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>rude</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>overordnet vindue</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>adgangskode</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Sæt ind</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Indsæt kæde</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Indsæt genvej</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Indsæt speciel</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>sti</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Pause</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Afspil</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug and Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>punkt</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>pege</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>markør</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>pop-up-menu</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>pop-up-vindue</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>stående</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>trykke på</target>
+ <definition>and hold a mouse button/og holde en museknap nede</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>trykke på</target>
+ <definition>a key/en tast</definition>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>primært destinationsobjekt</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>primært vindue</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Udskriv</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>printer</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>statusindikator</target>
+ <definition>control/kontrolelement</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>projekt</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Egenskaber</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>egenskabsfremviser</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>egenskabsside</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>egenskabsark</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>kontrolelement på egenskabsark</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Hurtig visning</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>skrivebeskyttet</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Papirkurv</target>
+ <definition>Icon/ikon</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Annuller Fortryd</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>områdemarkering</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>registreringsdatabase</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Gentag</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Erstat</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Gendan</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>gendannelsesknap</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Fortsæt</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Forsøg igen</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>tekstboks til formateret tekst</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Kør</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Gem</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Gem som</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>rulle</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>rullepil</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>rullepanel</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>rulleboks</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>sekundært vindue</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>markere</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>vælge</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Marker alt</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>det markerede</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>markeringshåndtag</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Overfør til</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>separator</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Indstillinger</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Indstillinger</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Installation</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>genvej</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>genvejsknap</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>genvejsikon</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>genvejstast</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>kontrolelement til genvejstast</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Vis</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Luk computeren</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>liste</target>
+ <definition>der kun tillader en enkelt markering</definition>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Tilpas størrelse</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>størrelseshåndtag</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>skala</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>rotationsboks</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Opdel</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>delelinje</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>deleboks</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>startknap</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>Startmappe</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>statuslinje</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Stop</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>fane</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>proceslinje</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>opgaveafhængig Hjælp</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>skabelon</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>tekstboks</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>titellinje</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>titeltekst</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>til/fra-tast</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>verktøjslinje</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>verktøjstip</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>træstruktur</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>skrive</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>type</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>ikke tilgængelig</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Fortryd</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Fjern installationen</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>Menuen Vis</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>lokal redigering</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>grafikpalet</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Hvad er det?</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Menuen Vindue</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>vindue</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Windows Stifinder</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>guide</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>projektmappe</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>arbejdsgruppe</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>arbejdsområde</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Ja</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/dutch.qph b/src/linguist/phrasebooks/dutch.qph
new file mode 100644
index 000000000..f2db4e05f
--- /dev/null
+++ b/src/linguist/phrasebooks/dutch.qph
@@ -0,0 +1,1044 @@
+<!DOCTYPE QPH><QPH language="nl">
+<phrase>
+ <source>About</source>
+ <target>Info</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>toegangstoets</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>toegankelijkheid</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>bewerkingsgreep</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>actief</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>selecie-einde</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>actief object</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>actief venster</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>grafisch hulpmiddel</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Altijd op voorgrond</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>fixeerpunt</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Toepassen</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>automatisch verlaten</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>zich automatisch herhalen</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>automatisch herhalen</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>automatische koppeling</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>automatisch schuiven</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>automatisch schuiven</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Vorige</target>
+ <definition>wanneer het een logisch paar vormt met Volgende</definition>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Bladeren</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Annuleren</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>vervolgmenu</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>selectievakje</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>vinkje</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>subvenster</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>kiezen</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>klikken</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Klembord</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Sluiten</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>knop Sluiten</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>samenvouwen</target>
+ <definition>outline</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>kolomnaam</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>keuzelijst met invoervak</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>opdrachtknop</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>hoofdobject</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>contextafhankelijke Help</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>contextafhankelijk</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>besturingselement</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Kopiëren</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Hierheen kopiëren</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Snelkoppeling maken</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Hier snelkoppeling maken</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Knippen</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>standaard</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>standaardknop</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Verwijderen</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>bureaublad</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>doel</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>dialoogvenster</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>handicap</target>
+ <definition>voorzichtig in context, maar handicap niet verbloemen:VB: persoon met een handicap (beter dan gehandicapte)</definition>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>niet-aaneengesloten selectie</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>in werkbalkdok plaatsen</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>document</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>dubbelklikken</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>slepen</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>slepen en neerzetten</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>vervolgkeuzelijst met invoervak</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>vervolgkeuzelijst</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>menu</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Bewerken</target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>menu Bewerken</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>puntjes</target>
+ <definition>(...)</definition>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>ingesloten object</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Afsluiten</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>uitvouwen</target>
+ <definition>an outline</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Verkennen</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>uitgebreide selectie</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>keuzelijst met uitgebreide selectie</target>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>bestand</target>
+</phrase>
+<phrase>
+ <source>File menu</source>
+ <target>menu Bestand</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Zoeken</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Volgende zoeken</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Zoeken naar</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>map</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>lettertype</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>tekengrootte</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>tekenstijl</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>functietoets</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>groepsvak</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>greep</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Help</target>
+</phrase>
+<phrase>
+ <source>Help menu</source>
+ <target>menu Help</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Verbergen</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>hiërarchische selectie</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>ingedrukt houden</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>selectiepunt</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>selectiegebied</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>pictogram</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>niet-actief</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>niet-actief venster</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>invoerfocus</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>menu Invoegen</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Object Invoegen</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>invoegpositie</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>cursief</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>label</target>
+ <definition>gender, Masc.: de</definition>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>liggend</target>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>koppeling</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>koppelen</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Hier koppeling maken</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>keuzelijst</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>weergaveknoppen</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>handmatige koppeling</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Maximaliseren</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>knop Maximaliseren</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>menu</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>menubalk</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>menuknop</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>opdracht</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>menunaam</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>berichtvak</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimaliseren</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>knop Minimaliseren</target>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>met gemengde waarden</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>modusgebonden</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>modi</target>
+ <definition>plural</definition>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>modus</target>
+ <definition>singular</definition>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>niet-modusgebonden</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>modificatietoets</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>muis</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Verplaatsen</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Hierheen verplaatsen</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>interface voor meerdere documenten</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>keuzelijst met meervoudige selectie</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Deze computer</target>
+ <definition>icon/pictogram</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Netwerkomgeving</target>
+ <definition>icon/pictogram</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Nieuw</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Volgende</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>object</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+ <definition>OLE (objecten koppelen en insluiten): voluit alleen in doc en Help</definition>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>slepen en neerzetten</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>slepen en neerzetten via OLE</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>ingesloten OLE-object</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>gekoppeld OLE-object</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>Aangepast slepen en neerzetten</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>Aangepast slepen en neerzetten via OLE</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Openen</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Openen met</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>keuzerondje</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>opties</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>OLE-pakket</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Pagina-instelling</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>paletvenster</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>deelvenster</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>hoofdvenster</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>wachtwoord</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Plakken</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Koppeling plakken</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Snelkoppeling plakken</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Plakken speciaal</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>pad</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Pauze</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Afspelen</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug en Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>aanwijzen</target>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>aanwijzer</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>pop-up-menu</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>pop-up-venster</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>staand</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>drukken op</target>
+ <definition>a key/een toets</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>ingedrukt houden</target>
+ <definition>and hold a mouse button/een muisknop</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>een muisknop ingedrukt houden</target>
+ <definition>and hold a mouse button</definition>
+</phrase>
+<phrase>
+ <source>press a mouse botton</source>
+ <target>een muisknop indrukken </target>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>primair hoofdobject</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>primair venster</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Afdrukken</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>printer</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>voortgangsindicator</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>project</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Eigenschappen</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>eigenschappenweergave</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>eigenschappenpagina</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>eigenschappenblad</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>besturingselement op een eigenschappenblad</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Snel weergeven</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>alleen-lezen</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Prullenbak</target>
+ <definition>Icon/pictogram</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Opnieuw</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>gebiedsselectie</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>het Register</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Herhalen</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Vervangen</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Vorig formaat</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>knop Vorig formaat</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Doorgaan</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Nogmaals</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>RTF-vak</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Uitvoeren</target>
+ <definition>Maar: macro starten</definition>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Opslaan</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Opslaan als</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>schuiven door</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>schuifpijl</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>schuifbalk</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>schuifblok</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>secundair venster</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>selecteren</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Alles selecteren</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>selectie</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>selectiegreep</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Kopiëren naar</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>scheidingsteken</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Instellingen</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Instellen</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Setup</target>
+ <definition>als het programma Setup wordt bedoeld</definition>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>snelkoppeling</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>snelkoppelingsknop</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>snelkoppelingspictogram</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>sneltoets</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>sneltoetsvak</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Weergeven</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Afsluiten</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>keuzelijst met enkelvoudige selectie</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Formaat wijzigen</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>formaatgreep</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>schuifregelaar</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>kringveld</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Splitsen</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>splitsbalk</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>splitsblokje</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>knop Start</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>map Opstarten</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>statusbalk</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Stoppen</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>tab</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>taakbalk</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>taakgeoriënteerde Help</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>sjabloon</target>
+ <definition>de</definition>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>tekstvak</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>titelbalk</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>venstertitel</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>wisseltoets</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>werkbalk</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>knopinfo</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>besturingselement voor structuurweergave</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>structuurweergave</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>typen</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>type</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>niet beschikbaar</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Ongedaan maken</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Installatie ongedaan maken</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>menu Beeld</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>direct bewerken</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>keuzelijst met grafische opties</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Wat is dit?</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>menu Venster</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>venster</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Windows Verkenner</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>wizard</target>
+ <definition>geen hoofdletter meer in lopende tekst</definition>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>werkmap</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>werkgroep</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>werkruimte</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Ja</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/finnish.qph b/src/linguist/phrasebooks/finnish.qph
new file mode 100644
index 000000000..caef1972f
--- /dev/null
+++ b/src/linguist/phrasebooks/finnish.qph
@@ -0,0 +1,1033 @@
+<!DOCTYPE QPH><QPH language="fi">
+<phrase>
+ <source>About</source>
+ <target>Tietoja</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>valintanäppäin</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>helppokäyttötoiminto</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>toimintokahva</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>aktiivinen</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>valinnan aktiivinen päätöskohta</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>aktiivinen objekti</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>aktiivinen ikkuna</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>graafinen lisäke</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Aina päällimmäisenä</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>ankkurikohta</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Käytä</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>automaattinen siirtyminen</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>automaattinen toisto</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>automaattinen linkki</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>automaattinen vieritys</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>automaattinen vieritys</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Takaisin</target>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Selaa</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Peruuta</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>alivalikko</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>valintaruutu</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>valintamerkki</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>ali-ikkuna</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>valita</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>napsautta</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Leikepöytä</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Sulje</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>sulkemispainike</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>tiivistää</target>
+ <definition>outline/jäsennys</definition>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>kutistaa</target>
+ <definition>outline/jäsennys</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>saraketunnus</target>
+ <definition>control/ohjausobjekti</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>sarakeotsikko</target>
+ <definition>control/ohjausobjekti</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>yhdistelmäruutu</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>painike</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>komento painike</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>säilö</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>tilannekohtainen ohje</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>tilannekohtainen</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>ohjausobjekti</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Kopioi</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Kopioi tähän</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Luo pikakuvake</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Luo pikakuvake tähän</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Leikkaa</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>oletus</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>oletuspainike</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Poista</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>työpöytä</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>kohde</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>valintaikkuna</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>invaliditeetti</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>hajavalinta</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>telakoida</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>tiedosto</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>asiakirja</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>kaksoisnapsauttaa</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>vetää</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>vetää ja pudottaa</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>avattava yhdistelmäruutu</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>avattava luetteloruutu</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>avattava valikko</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Muokkaa</target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>Muokkaa-valikko</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>kolme pistettä</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>upotettu objekti</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Lopeta</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>laajentaa</target>
+ <definition>an outline/jäsennys</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Selaa</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>laajennettu valinta</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>laajennettu valinta-luetteloruutu</target>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>tiedosto</target>
+</phrase>
+<phrase>
+ <source>File menu</source>
+ <target>Tiedosto-valikko</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Etsi</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Etsi seuraava</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Etsittävä</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>kansio</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>fontti</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>fonttikoko</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>fonttityyli</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>funktionäppäin</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>ryhmän kehys</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>kahva</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Ohje</target>
+</phrase>
+<phrase>
+ <source>Help menu</source>
+ <target>Ohje-valikko</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Piilota</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>hierarkkinen valinta</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>pitää painettuna</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>kohdepiste</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>kohdealue</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>kuvake</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>passiivinen</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>passiivinen ikkuna</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>syöttöalue</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Lisää-valikko</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Lisää objekti</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>lisäyskohta</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>kursivoitu</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>otsikko</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>nimi</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>vaaka</target>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>linkki</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>linkittää</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Linkitä tähän</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>luetteloruutu</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>luettelonäyttö</target>
+ <definition>control/ohjausobjekti</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>manuaalinen linkki</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Suurenna</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>suurennuspainike</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>valikko</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>valikkorivi</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>valikkopainike</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>valikon vaihtoehto</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>valikon otsikko</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>sanomaruutu</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Pienennä</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>pienennyspainike</target>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>monitila</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>modaalinen</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>tila</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>ei-modaalinen</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>yhdistelmänäppäin</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>hiiri</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Siirrä</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Siirrä tähän</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>MDI-liittymä</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>monivalintainen luetteloruutu</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Oma tietokone</target>
+ <definition>icon/kuvake</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Verkkoympäristö</target>
+ <definition>icon/kuvake</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Uusi</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Seuraava</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>objekti</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>vedä ja pudota-OLE-toiminto</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>upotettu OLE-objekti</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>linkitetty OLE-objekti</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>käyttäjän määrittämä vedä ja pudota-OLE-toiminto</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Avaa</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Avaa sovelluksessa</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>valintanappi</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>valitsimen tila</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>pakkaus</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Sivun asetukset</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>valikoimaikkuna</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>ruutu</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>ylemmän tason ikkuna</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>salasana</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Liitä</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Liitä linkki</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Liitä pikakuvake</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Liitä määräten</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>polku</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Tauko</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Soita</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug and Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>piste</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>osoittaa</target>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>osoitin</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>pikavalikko</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>ponnahdusikkuna</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>pysty</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>painaa</target>
+ <definition>and hold a mouse button/ja pitää painettuna hiiripainiketta</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>painaa</target>
+ <definition>a key/näppäintä</definition>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>ensisijainen säilö</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>ensisijainen ikkuna</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Tulosta</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>kirjoitin</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>tilanneilmaisin</target>
+ <definition>control/ohjausobjekti</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>projekti</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Ominaisuudet</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>ominaisuuksien tarkastelu</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>ominaisuusryhmä</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>ominaisuusikkuna</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>ominaisuusikkuna-ohjausobjekti</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Pikanäyttö</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>vain luku</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Roskakori</target>
+ <definition>Icon/kuvake</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Tee uudelleen</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>aluevalinta</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>rekisteri</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Toista</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Korvaa</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Palauta</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>palautuspainike</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Jatka</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Yritä uudelleen</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>monimuotoruutu</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Suorita</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Tallenna</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Tallenna nimellä</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>vierittää</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>vieritysnuoli</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>vierityspalkki</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>vieritysruutu</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>toissijainen ikkuna</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>valita</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Valitse kaikki</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>valinta</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>valintakahva</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Lähetä tiedosto</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>erotin</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Asetukset</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Asennus</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>pika-</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>pikapainike</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>pikakuvake</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>pikanäppäin</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>pikanäppäin-ohjausobjekti</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Näytä</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Sammuta</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>yksivalintainen luetteloruutu</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Muuta kokoa</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>koonmuuttokahva</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>liukusäädin</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>askellusruutu</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Jaa</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>jakopalkki</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>jakoruutu</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>Käynnistä-painike</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>Käynnistys-kansio</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>tilarivi</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Pysäytä</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>välilehti</target>
+ <definition>ohjausobjekti</definition>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>tehtäväpalkki</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>tehtäväohje</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>malli</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>muokkausruutu</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>otsikkorivi</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>otsikkoteksti</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>tilanvaihtonäppäin</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>työkalurivi</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>työkaluvihje</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>puunäyttö</target>
+ <definition>ohjausobjekti</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>tyyppi</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>laji</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>kirjoittaa</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>ei käytettävissä</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Kumoa</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Pura asennus</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>Näytä-valikko</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>visuaalinen muokkaus</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>graafisen valinnan ohjausobjekti</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Lisätietoja</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Ikkuna-valikko</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>ikkuna</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Resurssienhallinta</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>ohjattu toiminto</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>työkirja</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>työryhmä</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>työtila</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Kyllä</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/french.qph b/src/linguist/phrasebooks/french.qph
new file mode 100644
index 000000000..1884ed3d1
--- /dev/null
+++ b/src/linguist/phrasebooks/french.qph
@@ -0,0 +1,1493 @@
+<!DOCTYPE QPH>
+<QPH language="fr">
+<phrase>
+ <source>About</source>
+ <target>A propos</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>touche d&apos;accès rapide</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>accessibilité</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>handle d&apos;action</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>actif</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>active</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>point de fin de sélecion</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>objet actif</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>fenêtre activ</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>barre</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Toujours visible</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>point de début de sélection</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Appliquer</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>sortie automatique</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>répétition automatique</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>Liaison automatique</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>défilement automatique</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>défilement automatique</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Précédent</target>
+</phrase>
+<phrase>
+ <source>barrel button</source>
+ <target>Bouton du stylet</target>
+</phrase>
+<phrase>
+ <source>barrel-tap</source>
+ <target>toucher-maintenir enfoncé</target>
+</phrase>
+<phrase>
+ <source>boxed edit</source>
+ <target>édition contrôlée</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Parcourir</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Annuler</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>menu en cascade</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>case à cocher</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>coche</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>fenêtre enfant</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>choisir</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>cliquer sur</target>
+ <definition>verb, à l&apos;écran</definition>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>clic</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>cliquer le</target>
+ <definition>verb, bouton souris</definition>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Presse-papiers</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Fermer</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Fermeture</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>Fermer</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>réduire</target>
+ <definition>outline</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>en-tête de colonne</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>zone de liste modifiable</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>bouton de commande</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>conteneur</target>
+ <definition>d&apos;objets</definition>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>aide contextuelle</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>contextuelle</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>contextuel</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>contrôle</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Copier</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Copier ici</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Copier un raccourci</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Copier un raccourci ice</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Couper</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>par défaut</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>bouton par défaut</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Supprimer</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>bureau</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>destination</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>boîte de dialogue</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>incapacité</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>sélection d&apos;objets disjoints</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>aligner</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>document</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>cliquer deux fois</target>
+</phrase>
+<phrase>
+ <source>double-tap</source>
+ <target>toucher deux fois</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>faire glisser</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>glisser-déplacer</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>zone de liste déroulante modifiable</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>zone de liste déroulante fixe</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>menu déroulant</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Edition</target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>modifier</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>points de suspension</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>objet incorporé</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Quitter</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>développer</target>
+ <definition>an outline</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Explorer</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>sélection étendue</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>zone de liste à sélection étendue</target>
+</phrase>
+<phrase>
+ <source>File</source>
+ <target>Fichier</target>
+ <definition>menu</definition>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>fichier</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Rechercher</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Suivant</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Rechercher</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>dossier</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>police</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>taille de police</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>style de police</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>touche de fonction</target>
+</phrase>
+<phrase>
+ <source>gesture</source>
+ <target>signe</target>
+</phrase>
+<phrase>
+ <source>glyph</source>
+ <target>glyphe</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>zone de groupe</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>handle</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>?</target>
+ <definition>menu</definition>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Aide</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Masquer</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>sélection hiérarchique</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>maintenir</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>point d&apos;impact</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>zone critique</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>icône</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>inactive</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>inactif</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>fenêtre inactive</target>
+</phrase>
+<phrase>
+ <source>ink</source>
+ <target>dessin à main levée</target>
+</phrase>
+<phrase>
+ <source>ink edit</source>
+ <target>éditeur de dissin à main levée</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>zone d&apos;interaction</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Insertion</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Insérer un objet</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>point d&apos;insertion</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>italique</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>nom de volume</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>étiquette</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>paysage</target>
+</phrase>
+<phrase>
+ <source>lasso-tap</source>
+ <target>toucher lasso</target>
+</phrase>
+<phrase>
+ <source>lens</source>
+ <target>loupe</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>lier</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>liaison</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Lier ici</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>zone de liste</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>presentación de iconos </target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>Liste icônes</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>liaison manuelle</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Agrandissement</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>agrandir</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>menu</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>barre de menus</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>bouton de menus</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>élément de menu</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>titre de menu</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>boîte de message</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Réduction</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>réduire</target>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>valeurs multiples</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>modal</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>mode</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>non modal</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>touche de modification</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>souris</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Déplacement</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Transférer ici</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>Interface documents multiples</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>zone de liste à sélection multiple</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Poste de travail</target>
+ <definition>icon</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Voisinage réseau</target>
+ <definition>icon</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Nouveau</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Suivant</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>objet</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>glisser-déplacer OLE</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>Objet OLE incorporé</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>Objet OLE lié</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>glisser-déplacer OLE non standard</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Ouvrir</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Ouvrir avec</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>case d&apos;option</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>état des caractéristiques</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>ensemble</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Mise en page</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>palette</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>volet</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>fenêtre parent</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>mot de passe</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Coller</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Coller avec liaison</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Coller le raccourci</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Collage spécial</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>chemin</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Pause</target>
+</phrase>
+<phrase>
+ <source>pen</source>
+ <target>stylet</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Exécuter</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug and Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>point</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>amener le pointeur sur</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>pointeur</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>menu autonome</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>fenêtre autonome</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>portrait</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>appuyer</target>
+ <definition>and hold a mouse button/et maintenir enfoncé</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>appuyer</target>
+ <definition>a key/sur une touche</definition>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>contenuer principale</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>fenêtre principale</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Imprimer</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>imprimante</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>indicateur d&apos;état</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>projet</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Propriétés</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>inspecteur de propriétés</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>page de propriétés</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>feuille de propriétés</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>feuille de propriétés</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Aperçu</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>en lecture seule</target>
+</phrase>
+<phrase>
+ <source>recognition</source>
+ <target>reconnaissance</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Corbeille</target>
+ <definition>Icon</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Rétablir</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>sélection par zone</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>base des registres</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Répéter</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Remplacer</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Restauration</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>Restaurer</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Reprendre</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Essayer de nouveau</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>zone de texte RTF</target>
+ <definition>Rich Text Format</definition>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Exécuter</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Enregistrer</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Enregistrer sous</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>faire défiler</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>flèche de défilement</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>barre de défilement</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>curseur de défilement</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>fenêtre secondaire</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>sélectionner</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Tout sélectionner</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>sélection</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>handle de sélection</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Envoyer vers</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>séparateur</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Paramètres</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Installation</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>INSTALL</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>raccourci</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>raccourci</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>raccourci</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>touche de raccourci</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>touche de raccourci</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Afficher</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Arrêter l&apos;ordinateur</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>zone de liste à sélection unique</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Dimension</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>poignée de redimensionnement</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>défileur</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>compteur</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Fractionner</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>barre de fractionnement</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>curseur de fractionnement</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>Démarrer</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>dossier de démarrage</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>barre d&apos;état</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Arrêter</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>onglet</target>
+</phrase>
+<phrase>
+ <source>tap</source>
+ <target>toucher</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>barre des tâches</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>aide spécifique aux tâches</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>modèle</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>zone de texte</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>barre de titre</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>texte de la barre de titre</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>touche bascule</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>barre d&apos;outils</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>info-bulle</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>arborescencel</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>type</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>taper</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>pas disponible</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Annuler</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Désinstaller</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>Affichage</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>activation sur place</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>sélection graphique</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Qu&apos;est-ce que c&apos;est?</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Fenêtre</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>fenêtre</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Explorateur Windows</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>assistant</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>classeur</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>groupe de travail</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>espace de travail</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Oui</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Scinder</target>
+</phrase>
+<phrase>
+ <source>&amp;Edit</source>
+ <target>&amp;Édition</target>
+</phrase>
+<phrase>
+ <source>debugger</source>
+ <target>débogueur</target>
+</phrase>
+<phrase>
+ <source>Start Debugger</source>
+ <target>Lancer le débogueur</target>
+</phrase>
+<phrase>
+ <source>Executable:</source>
+ <target>Exécutable:</target>
+</phrase>
+<phrase>
+ <source>Filter:</source>
+ <target>Filtre:</target>
+</phrase>
+<phrase>
+ <source>Clear</source>
+ <target>Effacer</target>
+</phrase>
+<phrase>
+ <source>Host and port:</source>
+ <target>Hôte et port:</target>
+</phrase>
+<phrase>
+ <source>Architecture:</source>
+ <target>Architecture:</target>
+</phrase>
+<phrase>
+ <source>Server start script:</source>
+ <target>Script de démarrage du serveur:</target>
+</phrase>
+<phrase>
+ <source>&amp;Undo</source>
+ <target>Annu&amp;ler</target>
+</phrase>
+<phrase>
+ <source>Add Bookmark</source>
+ <target>Ajouter un signet</target>
+</phrase>
+<phrase>
+ <source>Bookmark:</source>
+ <target>Signet:</target>
+</phrase>
+<phrase>
+ <source>Add in Folder:</source>
+ <target>Ajouter dans le dossier:</target>
+</phrase>
+<phrase>
+ <source>+</source>
+ <target>+</target>
+</phrase>
+<phrase>
+ <source>New Folder</source>
+ <target>Nouveau dossier</target>
+</phrase>
+<phrase>
+ <source>Bookmarks</source>
+ <target>Signets</target>
+</phrase>
+<phrase>
+ <source>Rename Folder</source>
+ <target>Renommer le dossier</target>
+</phrase>
+<phrase>
+ <source>Bookmark</source>
+ <target>Signet</target>
+</phrase>
+<phrase>
+ <source>Remove</source>
+ <target>Retirer</target>
+</phrase>
+<phrase>
+ <source>Delete Folder</source>
+ <target>Supprimer le dossier</target>
+</phrase>
+<phrase>
+ <source>Add</source>
+ <target>Ajouter</target>
+</phrase>
+<phrase>
+ <source>Move Up</source>
+ <target>Vers le Haut</target>
+</phrase>
+<phrase>
+ <source>Move Down</source>
+ <target>Vers le Bas</target>
+</phrase>
+<phrase>
+ <source>Show Bookmark</source>
+ <target>Afficher le signet</target>
+</phrase>
+<phrase>
+ <source>Show Bookmark in New Tab</source>
+ <target>Afficher le signet dans un nouvel onglet</target>
+</phrase>
+<phrase>
+ <source>Delete Bookmark</source>
+ <target>Supprimer le signet</target>
+</phrase>
+<phrase>
+ <source>Rename Bookmark</source>
+ <target>Renommer le signet</target>
+</phrase>
+<phrase>
+ <source>Previous Bookmark</source>
+ <target>Signet précédent</target>
+</phrase>
+<phrase>
+ <source>Next Bookmark</source>
+ <target>Signet suivant</target>
+</phrase>
+<phrase>
+ <source>Condition:</source>
+ <target>Condition:</target>
+</phrase>
+<phrase>
+ <source>Working Directory:</source>
+ <target>Répertoire de travail:</target>
+</phrase>
+<phrase>
+ <source>Environment</source>
+ <target>Environnement</target>
+</phrase>
+<phrase>
+ <source>Arguments</source>
+ <target>Arguments</target>
+</phrase>
+<phrase>
+ <source>Build directory:</source>
+ <target>Répertoire de compilation:</target>
+</phrase>
+<phrase>
+ <source>Path:</source>
+ <target>Chemin:</target>
+</phrase>
+<phrase>
+ <source>General</source>
+ <target>Général</target>
+</phrase>
+<phrase>
+ <source>Username:</source>
+ <target>Nom d&apos;utilisateur:</target>
+</phrase>
+<phrase>
+ <source>User interface</source>
+ <target>Interface utilisateur</target>
+</phrase>
+<phrase>
+ <source>Open Link</source>
+ <target>Ouvrir le lien</target>
+</phrase>
+<phrase>
+ <source> [read only]</source>
+ <target> [lecture seule]</target>
+</phrase>
+<phrase>
+ <source> [directory]</source>
+ <target> [répertoire]</target>
+</phrase>
+<phrase>
+ <source>Close All</source>
+ <target>Fermer tout</target>
+</phrase>
+<phrase>
+ <source>Failed!</source>
+ <target>Échec!</target>
+</phrase>
+<phrase>
+ <source>Proceed</source>
+ <target>Continuer</target>
+</phrase>
+<phrase>
+ <source>Make writable</source>
+ <target>Rendre inscriptible</target>
+</phrase>
+<phrase>
+ <source>Qt Creator</source>
+ <target>Qt Creator</target>
+</phrase>
+<phrase>
+ <source>&amp;File</source>
+ <target>&amp;Fichier</target>
+</phrase>
+<phrase>
+ <source>Activate %1</source>
+ <target>Activer %1</target>
+</phrase>
+<phrase>
+ <source>New Project</source>
+ <target>Nouveau projet</target>
+</phrase>
+<phrase>
+ <source>Close %1</source>
+ <target>Fermer %1</target>
+</phrase>
+<phrase>
+ <source>*</source>
+ <target>*</target>
+</phrase>
+<phrase>
+ <source>&amp;Change</source>
+ <target>&amp;Modifier</target>
+</phrase>
+<phrase>
+ <source>Close Other Editors</source>
+ <target>Fermer les autres éditeurs</target>
+</phrase>
+<phrase>
+ <source>Close All Except %1</source>
+ <target>Fermer tout sauf %1</target>
+</phrase>
+<phrase>
+ <source>Remove</source>
+ <target>Suppression</target>
+</phrase>
+<phrase>
+ <source>About...</source>
+ <target>À propos…</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimiser</target>
+</phrase>
+<phrase>
+ <source>Remove</source>
+ <target>Supprimer</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Sélectionner tout</target>
+</phrase>
+<phrase>
+ <source>Cannot create directory: %1</source>
+ <target>Impossible de créer le répertoire : %1</target>
+</phrase>
+<phrase>
+ <source></source>
+ <target></target>
+</phrase>
+<phrase>
+ <source>Whole &amp;words</source>
+ <target>M&amp;ots complets</target>
+</phrase>
+<phrase>
+ <source>Title:</source>
+ <target>Titre :</target>
+</phrase>
+<phrase>
+ <source>Fonts</source>
+ <target>Polices</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Insérer</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Taille</target>
+</phrase>
+<phrase>
+ <source>List View</source>
+ <target>Affichage liste</target>
+</phrase>
+<phrase>
+ <source>Read-only</source>
+ <target>Lecture seule</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Réduire</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Maximiser</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Réessayer</target>
+</phrase>
+<phrase>
+ <source>Dock</source>
+ <target>Attacher</target>
+</phrase>
+<phrase>
+ <source>&amp;Redo</source>
+ <target>&amp;Rétablir</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Éditer</target>
+</phrase>
+<phrase>
+ <source>PATH:</source>
+ <target>PATH :</target>
+</phrase>
+<phrase>
+ <source>Change:</source>
+ <target>Modification :</target>
+</phrase>
+<phrase>
+ <source>Edit...</source>
+ <target>Modifier...</target>
+</phrase>
+<phrase>
+ <source>&amp;Username:</source>
+ <target>&amp;Utilisateur :</target>
+</phrase>
+<phrase>
+ <source>Link</source>
+ <target>Lien</target>
+</phrase>
+<phrase>
+ <source>Paste:</source>
+ <target>Collage :</target>
+</phrase>
+<phrase>
+ <source>Label</source>
+ <target>Libellé</target>
+</phrase>
+<phrase>
+ <source>&amp;Debug</source>
+ <target>&amp;Déboguer</target>
+</phrase>
+<phrase>
+ <source>Slider</source>
+ <target>Barre de défilement</target>
+</phrase>
+<phrase>
+ <source>&amp;Restore</source>
+ <target>&amp;Restaurer</target>
+</phrase>
+<phrase>
+ <source>&amp;Move</source>
+ <target>&amp;Déplacer</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Créer</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Lecture</target>
+</phrase>
+<phrase>
+ <source>Slider</source>
+ <target>Barre de défilement</target>
+</phrase>
+<phrase>
+ <source>&amp;Restore</source>
+ <target>&amp;Restaurer</target>
+</phrase>
+<phrase>
+ <source>&amp;Move</source>
+ <target>&amp;Déplacer</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Créer</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Lecture</target>
+</phrase>
+<phrase>
+ <source>&amp;Redo</source>
+ <target>&amp;Refaire</target>
+</phrase>
+<phrase>
+ <source>Raised</source>
+ <target>Bombé</target>
+</phrase>
+<phrase>
+ <source>Sunken</source>
+ <target>Enfoncé</target>
+</phrase>
+<phrase>
+ <source>Run:</source>
+ <target>Exécution :</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/german.qph b/src/linguist/phrasebooks/german.qph
new file mode 100644
index 000000000..2be8c77bd
--- /dev/null
+++ b/src/linguist/phrasebooks/german.qph
@@ -0,0 +1,1075 @@
+<!DOCTYPE QPH><QPH language="de">
+<phrase>
+ <source>About</source>
+ <target>Info</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>Zugriffstaste</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>Eingabehilfe</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>Aktionspunkt</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>Aktiv</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>Aktives Ende</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>Aktives Objekt</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>Aktives Fenster</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>Zubehör</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Immer im Vordergrund</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>Ankerpunkt</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Zuweisen</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>Textfeld mit automatischer Freigabe</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>Automatische Wiederholung</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>Automatische OLE-Verknüpfung</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>Automatischer Bildlauf</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>Automatischer Bildlauf</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Zurück</target>
+</phrase>
+<phrase>
+ <source>barrel button</source>
+ <target>Pen-Knopf</target>
+ <definition>pen</definition>
+</phrase>
+<phrase>
+ <source>barrel-tap</source>
+ <target>Tippen mit Pen-Knopf</target>
+</phrase>
+<phrase>
+ <source>boxed edit</source>
+ <target>Texteditor</target>
+ <definition>control/Steuerelement</definition>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Durchsuchen</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Abbrechen</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>Überlappendes Menü</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>Kontrollkästchen</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>Markierung</target>
+ <definition>Kontrollkästchen</definition>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>Untergeordnetes Fenster</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>Wählen</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>Klicken</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Zwischenablage</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Schließen</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>Schließen</target>
+ <definition>Schaltfläche</definition>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>Ausblenden</target>
+ <definition>outline/Gliederung</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>Spaltenüberschrift</target>
+ <definition>control/Steuerelement</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>Kombinationsfeld</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>Schaltfläche</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>Container</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>Kontextbezogene Hilfe</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>Kontextbezogen</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>Steuerelement</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Kopieren</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Hierher kopieren</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Verknüpfung erstellen</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Hiermit verknüpfen</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Ausschneiden</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>Standard</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>Standardschaltfläche</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Löschen</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>Desktop</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>Ziel</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>Dialogfeld</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>Behinderung</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>Nichtzusammenhängende Auswahl</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>Verankern</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>Dokument</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>Doppelklicken</target>
+</phrase>
+<phrase>
+ <source>double-tap</source>
+ <target>Doppeltippen</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>Ziehen</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>Drag &amp; Drop</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>Dropdown-Kombinationsfeld</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>Dropdown-Listenfeld</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>Dropdown-Menü</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Bearbeiten</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Bearbeiten</target>
+ <definition>menu/Menü</definition>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>Auslassungspunkte</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>Eingebettetes</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Beenden</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>Einblenden</target>
+ <definition>an outline/einer Struktur</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Explorer</target>
+ <definition>Befehl</definition>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>Erweiterte Auswahl</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>Listenfeld für erweiterte Auswahl</target>
+</phrase>
+<phrase>
+ <source>File</source>
+ <target>Datei</target>
+ <definition>menu</definition>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>Datei</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Suchen</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Weitersuchen</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Suchen nach</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>Ordner</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>Schriftart</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>Schriftgrad</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>Schriftschnitt</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>Funktionstaste</target>
+</phrase>
+<phrase>
+ <source>gesture</source>
+ <target>Schriftzug</target>
+</phrase>
+<phrase>
+ <source>glyph</source>
+ <target>Zeichen</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>Gruppenfeld</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>Ziehpunkt</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>?</target>
+ <definition>menu</definition>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Hilfe</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Ausblenden</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>Hierarchische Auswahl</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>Halten</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>Hot Spot</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>Hot Zone</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>Symbol</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>Inaktiv</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>Inaktives Fenster</target>
+</phrase>
+<phrase>
+ <source>ink</source>
+ <target>Ink</target>
+</phrase>
+<phrase>
+ <source>ink edit</source>
+ <target>Inkeditor</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>Eingabefokus</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Einfügen</target>
+ <definition>Menü</definition>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Objekt einfügen</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>Einfügemarke</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>Kursiv</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>Bezeichnung</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>Querformat</target>
+</phrase>
+<phrase>
+ <source>lasso-tap</source>
+ <target>Lasso-tippen</target>
+</phrase>
+<phrase>
+ <source>lens</source>
+ <target>Lupe</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>Verknüpfung</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>Verknüpfen</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Hiermit verknüpfen</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>Listenfeld</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>Listenansicht</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>Manuelle OLE-Verknüpfung</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Maximieren</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>Maximieren</target>
+ <definition>Schaltfläche</definition>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>Menü</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>Menüleiste</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>Menü</target>
+ <definition>Schaltfläche</definition>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>Menüelement</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>Menütitel</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>Meldungsfeld</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimieren</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>Minimieren</target>
+ <definition>Schaltfläche</definition>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>Gemischt</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>Modal</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>Modus</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>Interaktiv</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>Zusatztaste</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>Maus</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Verschieben</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Hierher verschieben</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>MDI</target>
+ <definition>Multiple Document Interface</definition>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>Listenfeld für Mehrfachauswahl</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Arbeitsplatz</target>
+ <definition>icon/Symbol</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Netzwerk</target>
+ <definition>icon/Symbol</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Neu</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Weiter</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>Objekt</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>OLE-Drag &amp; Drop</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>Eingebettetes OLE-Objekt</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>Verknüpftes OLE-Objekt</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>Vom Standard abweichendes OLE-Drag &amp; Drop</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>Aangepast slepen en neerzetten via OLE</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Öffnen</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Öffnen mit</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>Optionsfeld</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>Aktivierte Option</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>Paket</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Seite einrichten</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>Palettenfenster</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>Fensterbereich</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>Ãœbergeordnetes Fenster</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>Kennwort</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Einfügen</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Verknüpfung einfügen</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Verknüpfung einfügen</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Inhalte einfügen</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>Pfad</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Anhalten</target>
+</phrase>
+<phrase>
+ <source>pen</source>
+ <target>Pen</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Wiedergeben</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug &amp; Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>Zeigen</target>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>Zeiger</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>Kontextmenü</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>Popup-Fenster</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>Hochformat</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>Drücken</target>
+ <definition>and hold a mouse button/und Halten einer Maustaste</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>Drücken</target>
+ <definition>a key/einer Taste</definition>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>Primär-Container</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>Primärfenster</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Drucken</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>Drucker</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>Statusanzeige</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>Projekt</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Eigenschaften</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>Eigenschaftenanzeige</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>Eigenschaftengruppe</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>Eigenschaftenfenster</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>Eigenschaftenfenster-Steuerelement</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Schnellansicht</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>Schreibgeschützt</target>
+</phrase>
+<phrase>
+ <source>recognition</source>
+ <target>Schrifterkennung</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Papierkorb</target>
+ <definition>Icon/Symbol</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Wiederherstellen</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>Bereichsauswahl</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>Registrierung</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Wiederholen</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Ersetzen</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Wiederherstellen</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>Wiederherstellen </target>
+ <definition>Schaltfläche</definition>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Fortsetzen</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Wiederholen</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>RTF-Textfeld</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Ausführen</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Speichern</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Speichern unter</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>Bildlauf durchführen</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>Bildlaufpfeil</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>Bildlaufleiste</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>Bildlauffeld</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>Sekundärfenster</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>Auswählen</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Alle markieren</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>Auswahl</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>Auswahlpunkt</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Senden an</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>Trennelement</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Einstellungen</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Einrichten</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>Verknüpfung</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>Verknüpfte Schaltfläche</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>Verknüpfungssymbol</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>Tastenkombination</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>Steuerelement für Tastenbelegung</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Anzeigen</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Beenden</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>Listenfeld für Einfachauswahl</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Größe ändern</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>Element für Größenänderung</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>Schieber</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>Drehfeld</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Teilen</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>Fensterteiler</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>Teilungsfeld</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>Start</target>
+ <definition>Schaltfläche</definition>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>Autostart</target>
+ <definition>Ordner</definition>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>Statusleiste</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Beenden</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>Register</target>
+</phrase>
+<phrase>
+ <source>tap</source>
+ <target>Tippen</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>Task-Leiste</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>Vorgangsbezogene Hilfe</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>Vorlage</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>Textfeld</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>Titelleiste</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>Titeltext</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>Ein-/Aus-Taste</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>Symbolleiste</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>QuickInfo</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>Strukturansicht</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>Eingeben</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>Typ</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>Nicht verfügbar</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Rückgängig</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Deinstallieren</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>Ansicht</target>
+ <definition>Menü</definition>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>Direkte Bearbeitung</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>Steuerelement zur Grafikanzeige</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Direkthilfe</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Fenster</target>
+ <definition>Menü</definition>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>Fenster</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Explorer</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>Assistent</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>Arbeitsmappe</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>Arbeitsgruppe</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>Arbeitsbereich</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Ja</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/hungarian.qph b/src/linguist/phrasebooks/hungarian.qph
new file mode 100644
index 000000000..0e1dd122a
--- /dev/null
+++ b/src/linguist/phrasebooks/hungarian.qph
@@ -0,0 +1,752 @@
+<!DOCTYPE QPH>
+<QPH language="hu_HU">
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>Bookmarks</source>
+ <target>Könyvjelzők</target>
+</phrase>
+<phrase>
+ <source>Remove</source>
+ <target>Törlés</target>
+</phrase>
+<phrase>
+ <source>New Folder</source>
+ <target>Új könyvtár</target>
+</phrase>
+<phrase>
+ <source>Add</source>
+ <target>Hozzáadás</target>
+</phrase>
+<phrase>
+ <source>Previous</source>
+ <target>Előző</target>
+</phrase>
+<phrase>
+ <source>Font</source>
+ <target>Betűtípus</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Segítség</target>
+</phrase>
+<phrase>
+ <source>Done</source>
+ <target>Kész</target>
+</phrase>
+<phrase>
+ <source>Install</source>
+ <target>Telepítés</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Mégsem</target>
+</phrase>
+<phrase>
+ <source>Installation Path:</source>
+ <target>Telepítési útvonal:</target>
+</phrase>
+<phrase>
+ <source>Index</source>
+ <target>Index</target>
+</phrase>
+<phrase>
+ <source>Contents</source>
+ <target>Tartalom</target>
+</phrase>
+<phrase>
+ <source>Search</source>
+ <target>Keresés</target>
+</phrase>
+<phrase>
+ <source>Print Preview...</source>
+ <target>Nyomtatási kép...</target>
+</phrase>
+<phrase>
+ <source>About...</source>
+ <target>Névjegy...</target>
+</phrase>
+<phrase>
+ <source>Toolbars</source>
+ <target>Eszköztárak</target>
+</phrase>
+<phrase>
+ <source>Address:</source>
+ <target>Cím:</target>
+</phrase>
+<phrase>
+ <source>Open Source Edition</source>
+ <target>Nyíltforrású kiadás</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Igen</target>
+</phrase>
+<phrase>
+ <source>No</source>
+ <target>Nem</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Alkalmaz</target>
+</phrase>
+<phrase>
+ <source>Ignore</source>
+ <target>Kihagyás</target>
+</phrase>
+<phrase>
+ <source>Abort</source>
+ <target>Megszakítás</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Lejátszás</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Szünet</target>
+</phrase>
+<phrase>
+ <source>File</source>
+ <target>Fájl</target>
+ <definition>menu</definition>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>fájl</target>
+</phrase>
+<phrase>
+ <source>directory</source>
+ <target>könyvtár</target>
+</phrase>
+<phrase>
+ <source>Symlink</source>
+ <target>Szimbolikus link</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Törlés</target>
+</phrase>
+<phrase>
+ <source>Rename</source>
+ <target>Ãtnevezés</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Vissza</target>
+</phrase>
+<phrase>
+ <source>Forward</source>
+ <target>Előre</target>
+</phrase>
+<phrase>
+ <source>Finish</source>
+ <target>Befejezés</target>
+</phrase>
+<phrase>
+ <source>Quit</source>
+ <target>Kilépés</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Kilépés</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Bezárás</target>
+</phrase>
+<phrase>
+ <source>Close All</source>
+ <target>Mindent bezár</target>
+</phrase>
+<phrase>
+ <source>Error</source>
+ <target>Hiba</target>
+</phrase>
+<phrase>
+ <source>Warning</source>
+ <target>Figyelmeztetés</target>
+</phrase>
+<phrase>
+ <source>Information</source>
+ <target>Információ</target>
+</phrase>
+<phrase>
+ <source>Question</source>
+ <target>Kérdés</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>dokumentum</target>
+</phrase>
+<phrase>
+ <source>author</source>
+ <target>szerző</target>
+</phrase>
+<phrase>
+ <source>subsidiary(-ies)</source>
+ <target>leányvállalata(i)</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Súgó</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Visszavonás</target>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Újra</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Megnyitás</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Mentés</target>
+</phrase>
+<phrase>
+ <source>Save all</source>
+ <target>Mindet menti</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>kattintás</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>kattintson</target>
+ <definition>ask</definition>
+</phrase>
+<phrase>
+ <source>Recent</source>
+ <target>Előző</target>
+ <definition>Recent files/Előző fájlok</definition>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Ablak</target>
+</phrase>
+<phrase>
+ <source>Cascade</source>
+ <target>Lépcsőzetes</target>
+</phrase>
+<phrase>
+ <source>Tile</source>
+ <target>Mozaikszerű</target>
+</phrase>
+<phrase>
+ <source>Game</source>
+ <target>Játék</target>
+</phrase>
+<phrase>
+ <source>New Game</source>
+ <target>Új játék</target>
+</phrase>
+<phrase>
+ <source>Untitled</source>
+ <target>Névtelen</target>
+</phrase>
+<phrase>
+ <source>Unknown error</source>
+ <target>Ismeretlen hiba</target>
+</phrase>
+<phrase>
+ <source>New Folder</source>
+ <target>Új mappa</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>mappa</target>
+</phrase>
+<phrase>
+ <source>New Directory</source>
+ <target>Új könyvtár</target>
+</phrase>
+<phrase>
+ <source>unknown</source>
+ <target>ismeretlen</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Másolás</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Kivágás</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Beillesztés</target>
+</phrase>
+<phrase>
+ <source>Paste special</source>
+ <target>Speciális beillesztés</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Beszúrás</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Másolás ide</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimalizálás</target>
+</phrase>
+<phrase>
+ <source>Zoom</source>
+ <target>Nagyítás</target>
+</phrase>
+<phrase>
+ <source>&amp;Edit</source>
+ <target>S&amp;zerkesztés</target>
+</phrase>
+<phrase>
+ <source>&amp;View</source>
+ <target>&amp;Nézet</target>
+</phrase>
+<phrase>
+ <source>Application</source>
+ <target>Alkalmazás</target>
+</phrase>
+<phrase>
+ <source>Documentation</source>
+ <target>Dokumentáció</target>
+</phrase>
+<phrase>
+ <source>Network</source>
+ <target>Hálózat</target>
+</phrase>
+<phrase>
+ <source>Current Page</source>
+ <target>Aktuális oldal</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Keresés</target>
+</phrase>
+<phrase>
+ <source>Locale</source>
+ <target>Nyelv</target>
+</phrase>
+<phrase>
+ <source>Cannot open &apos;%1&apos;.</source>
+ <target>&apos;%1&apos; nem nyitható meg.</target>
+</phrase>
+<phrase>
+ <source>Cannot find the string &apos;%1&apos;.</source>
+ <target>A szöveg nem található: &apos;%1&apos;.</target>
+</phrase>
+<phrase>
+ <source>A file called &apos;%1&apos; already exists. Please choose another name.</source>
+ <target>&apos;%1&apos; nevű fájl már létezik. Válasszon egy másik nevet.</target>
+</phrase>
+<phrase>
+ <source>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</source>
+ <target>Ez a program abban a reményben került közreadásra, hogy hasznos lesz, de minden egyéb GARANCIA NÉLKÃœL, az ELADHATÓSÃGRA vagy VALAMELY CÉLRA VALÓ ALKALMAZHATÓSÃGRA való származtatott garanciát is beleértve.</target>
+ <definition>License text in most Qt programs</definition>
+</phrase>
+<phrase>
+ <source>Open Link</source>
+ <target>Link megnyitása</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Következő</target>
+</phrase>
+<phrase>
+ <source>Case Sensitive</source>
+ <target>Kis/nagybetű érzékeny</target>
+</phrase>
+<phrase>
+ <source>Whole words</source>
+ <target>Teljes szó</target>
+</phrase>
+<phrase>
+ <source>Open Link in New Tab</source>
+ <target>Link megnyitása új lapon</target>
+</phrase>
+<phrase>
+ <source>Download canceled.</source>
+ <target>Letöltés megszakítva.</target>
+</phrase>
+<phrase>
+ <source>The file %1 already exists. Do you want to overwrite it?</source>
+ <target>A(z) &apos;%1&apos; nevű fájl már létezik. Felülírja?</target>
+</phrase>
+<phrase>
+ <source>Qt Assistant</source>
+ <target>Qt Asszisztens</target>
+</phrase>
+<phrase>
+ <source>Preferences...</source>
+ <target>Beállítások...</target>
+</phrase>
+<phrase>
+ <source>&amp;File</source>
+ <target>&amp;Fájl</target>
+</phrase>
+<phrase>
+ <source>Browser</source>
+ <target>Böngésző</target>
+</phrase>
+<phrase>
+ <source>Filters</source>
+ <target>Szűrők</target>
+</phrase>
+<phrase>
+ <source>Delete Folder</source>
+ <target>Mappa törlése</target>
+</phrase>
+<phrase>
+ <source>Rename Folder</source>
+ <target>Mappa átnevezése</target>
+</phrase>
+<phrase>
+ <source>You need a commercial Qt license for development of proprietary (closed source) applications. Please see &lt;a href=&quot;http://www.trolltech.com/company/model.html&quot;&gt;www.trolltech.com/company/model.html&lt;/a&gt; for an overview of Qt licensing.</source>
+ <target>Amennyiben zárt forrású alkalmazás fejlesztéséhez kívánja a Qt-t felhasználni, szüksége lesz a Qt kereskedelmi verziójára. Kérem tekintse meg az &lt;tt&gt;http://www.trolltech.com/company/model.html&lt;/tt&gt; oldalt a Qt licenszelésének áttekintéséhez.</target>
+</phrase>
+<phrase>
+ <source>New Tab</source>
+ <target>Új fül</target>
+</phrase>
+<phrase>
+ <source>Close Tab</source>
+ <target>Fül bezárása</target>
+</phrase>
+<phrase>
+ <source>Close Other Tabs</source>
+ <target>A többi fül bezárása</target>
+</phrase>
+<phrase>
+ <source>True</source>
+ <target>Igaz</target>
+</phrase>
+<phrase>
+ <source>False</source>
+ <target>Hamis</target>
+</phrase>
+<phrase>
+ <source>Update</source>
+ <target>Frissítés</target>
+</phrase>
+<phrase>
+ <source>Normal</source>
+ <target>Normál</target>
+</phrase>
+<phrase>
+ <source>Bold</source>
+ <target>Félkövér</target>
+</phrase>
+<phrase>
+ <source>Italic</source>
+ <target>DÅ‘lt</target>
+</phrase>
+<phrase>
+ <source>Greek</source>
+ <target>Görög</target>
+</phrase>
+<phrase>
+ <source>Cyrillic</source>
+ <target>Cirill</target>
+</phrase>
+<phrase>
+ <source>Armenian</source>
+ <target>Örmény</target>
+</phrase>
+<phrase>
+ <source>Hebrew</source>
+ <target>Héber</target>
+</phrase>
+<phrase>
+ <source>Arabic</source>
+ <target>Arab</target>
+</phrase>
+<phrase>
+ <source>Syriac</source>
+ <target>Szír</target>
+</phrase>
+<phrase>
+ <source>Permission denied</source>
+ <target>Hozzáférés megtagadva</target>
+</phrase>
+<phrase>
+ <source>Too many open files</source>
+ <target>Túl sok fájl van nyitva</target>
+</phrase>
+<phrase>
+ <source>No such file or directory</source>
+ <target>Nincs ilyen fájl vagy könyvtár</target>
+</phrase>
+<phrase>
+ <source>No space left on device</source>
+ <target>Nincs több hely az eszközön</target>
+</phrase>
+<phrase>
+ <source>Width:</source>
+ <target>Szélesség:</target>
+</phrase>
+<phrase>
+ <source>Height:</source>
+ <target>Magasság:</target>
+</phrase>
+<phrase>
+ <source>Margins</source>
+ <target>Margók</target>
+</phrase>
+<phrase>
+ <source>top margin</source>
+ <target>felső margó</target>
+</phrase>
+<phrase>
+ <source>left margin</source>
+ <target>bal margó</target>
+</phrase>
+<phrase>
+ <source>right margin</source>
+ <target>jobb margó</target>
+</phrase>
+<phrase>
+ <source>bottom margin</source>
+ <target>alsó margó</target>
+</phrase>
+<phrase>
+ <source>Next page</source>
+ <target>Következő oldal</target>
+</phrase>
+<phrase>
+ <source>Previous page</source>
+ <target>Előző oldal</target>
+</phrase>
+<phrase>
+ <source>First page</source>
+ <target>Első oldal</target>
+</phrase>
+<phrase>
+ <source>Last page</source>
+ <target>Utolsó oldal</target>
+</phrase>
+<phrase>
+ <source>Fit width</source>
+ <target>Szélesség igazítása</target>
+</phrase>
+<phrase>
+ <source>Fit page</source>
+ <target>Oldal igazítása</target>
+</phrase>
+<phrase>
+ <source>Zoom in</source>
+ <target>Nagyítás</target>
+</phrase>
+<phrase>
+ <source>Zoom out</source>
+ <target>Kicsinyítés</target>
+</phrase>
+<phrase>
+ <source>Portrait</source>
+ <target>Ãlló</target>
+</phrase>
+<phrase>
+ <source>Landscape</source>
+ <target>Fekvő</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Nyomtatás</target>
+</phrase>
+<phrase>
+ <source>Page setup</source>
+ <target>Oldalbeállítás</target>
+</phrase>
+<phrase>
+ <source>Color</source>
+ <target>Szín</target>
+</phrase>
+<phrase>
+ <source>Grayscale</source>
+ <target>Szürkeárnyalatos</target>
+</phrase>
+<phrase>
+ <source>None</source>
+ <target>Nincs</target>
+</phrase>
+<phrase>
+ <source>...</source>
+ <target>...</target>
+</phrase>
+<phrase>
+ <source>Menu</source>
+ <target>Menü</target>
+</phrase>
+<phrase>
+ <source>Keep</source>
+ <target>Meghagy</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Megállít</target>
+</phrase>
+<phrase>
+ <source>Log</source>
+ <target>Napló</target>
+</phrase>
+<phrase>
+ <source>Mi&amp;nimize</source>
+ <target>&amp;Kis méret</target>
+</phrase>
+<phrase>
+ <source>Press</source>
+ <target>Nyomja meg</target>
+</phrase>
+<phrase>
+ <source>Submit</source>
+ <target>Küldés</target>
+</phrase>
+<phrase>
+ <source>Underline</source>
+ <target>Aláhúzott</target>
+</phrase>
+<phrase>
+ <source>Outline</source>
+ <target>Ãthúzott</target>
+</phrase>
+<phrase>
+ <source>Direction</source>
+ <target>Irány</target>
+</phrase>
+<phrase>
+ <source>Configuration</source>
+ <target>Konfiguráció</target>
+</phrase>
+<phrase>
+ <source>None</source>
+ <target>Semmi</target>
+</phrase>
+<phrase>
+ <source>Save As...</source>
+ <target>Mentés másként...</target>
+</phrase>
+<phrase>
+ <source>Context</source>
+ <target>Környezet</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Szerkesztés</target>
+</phrase>
+<phrase>
+ <source>Toolbar</source>
+ <target>Eszköztár</target>
+</phrase>
+<phrase>
+ <source>&amp;Print...</source>
+ <target>&amp;Nyomtatás...</target>
+</phrase>
+<phrase>
+ <source>E&amp;xit</source>
+ <target>&amp;Kilépés</target>
+</phrase>
+<phrase>
+ <source>Sidebar</source>
+ <target>Oldalsáv</target>
+</phrase>
+<phrase>
+ <source>Bookmark</source>
+ <target>Könyvjelző</target>
+</phrase>
+<phrase>
+ <source>Save As</source>
+ <target>Mentés másként</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Összes kijelölése</target>
+</phrase>
+<phrase>
+ <source>Name</source>
+ <target>Név</target>
+</phrase>
+<phrase>
+ <source>Type</source>
+ <target>Típus</target>
+</phrase>
+<phrase>
+ <source>Date</source>
+ <target>Dátum</target>
+</phrase>
+<phrase>
+ <source>Name</source>
+ <target>Név</target>
+</phrase>
+<phrase>
+ <source>Unknown</source>
+ <target>Ismeretlen</target>
+</phrase>
+<phrase>
+ <source>Value</source>
+ <target>Érték</target>
+</phrase>
+<phrase>
+ <source>Default</source>
+ <target>Alapértelmezett</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Új</target>
+</phrase>
+<phrase>
+ <source>Level</source>
+ <target>Szint</target>
+</phrase>
+<phrase>
+ <source>Location</source>
+ <target>Hely</target>
+</phrase>
+<phrase>
+ <source>Reload</source>
+ <target>Újratöltés</target>
+</phrase>
+<phrase>
+ <source>Pictures</source>
+ <target>Képek</target>
+</phrase>
+<phrase>
+ <source>Battery</source>
+ <target>Elem</target>
+</phrase>
+<phrase>
+ <source>No error</source>
+ <target>Nincs hiba</target>
+</phrase>
+<phrase>
+ <source>Whole words</source>
+ <target>Teljes szó</target>
+</phrase>
+<phrase>
+ <source>(Új bejegyzés)</source>
+ <target></target>
+</phrase>
+<phrase>
+ <source>Horizontal</source>
+ <target>Vízszintes</target>
+</phrase>
+<phrase>
+ <source>Enabled</source>
+ <target>Engedélyezve</target>
+</phrase>
+<phrase>
+ <source>Up</source>
+ <target>Fel</target>
+</phrase>
+<phrase>
+ <source>Down</source>
+ <target>Le</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/italian.qph b/src/linguist/phrasebooks/italian.qph
new file mode 100644
index 000000000..0a4ea1dcc
--- /dev/null
+++ b/src/linguist/phrasebooks/italian.qph
@@ -0,0 +1,1105 @@
+<!DOCTYPE QPH><QPH language="it">
+<phrase>
+ <source>About</source>
+ <target>Informazioni su</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>tasto di scelta</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>accesso facilitato</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>identificatore dell&apos;azione</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>attivo</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>punto finale</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>oggetto attivo</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>finestra attiva</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>barra</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Sempre in primo piano</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>punto di ancoraggio</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Applica</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>ad uscita automatica</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>a ripetizione automatica</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>collegamento automatico</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>scorrimento automatico</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>scorrimento automatico</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Indietro</target>
+</phrase>
+<phrase>
+ <source>barrel button</source>
+ <target>pulsante della penna</target>
+ <definition>pen</definition>
+</phrase>
+<phrase>
+ <source>barrel-tap</source>
+ <target>tocco con il pulsante premuto</target>
+</phrase>
+<phrase>
+ <source>boxed edit</source>
+ <target>casella di testo a griglia</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Sfoglia</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Annulla</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>menu sovrapposto</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>casella di controllo</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>segno di spunta</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>finestra secondaria</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>scegliere</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>fare clic</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Appunti</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Chiudi</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>pulsante di chiusura</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>comprimere</target>
+ <definition>outline, verb</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>intestazione di colonna</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>casella combinata</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>pulsante di comando</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>contenitore</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>guida sensibile al contesto</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>contestuale</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>controllo</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Copia</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Copia</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Crea collegamento</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Crea collegamento</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Taglia</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>predefinito</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>pulsante predefinito</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Elimina</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>desktop</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>destinazione</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>finestra di dialogo</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>disabilità</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>selezione multipla</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>posizionare</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>documento</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>doppio clic</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>fare doppio clic</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>double-tap</source>
+ <target>toccare due volte in rapida successione</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>double-tap</source>
+ <target>doppio tocco</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>trascinare</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>trascinare e rilasciare</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>caratteristica Trascina selezione</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>casella combinata a discesa</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>casella di riepilogo a discesa</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>menu a discesa</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Modifica </target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>menu Modifica</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>puntini di sospensione</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>oggetto incorporato</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Esci</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>espandere</target>
+ <definition>an outline/una struttura</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Gestione risorse</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>selezione estesa</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>casella di riepilogo a selezione estesa</target>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>file</target>
+</phrase>
+<phrase>
+ <source>File menu</source>
+ <target>menu File</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Trova</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Trova successivo</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Trova</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>cartella</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>tipo di carattere</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>dimensione carattere</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>stile carattere</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>tasto funzione</target>
+</phrase>
+<phrase>
+ <source>gesture</source>
+ <target>segno</target>
+</phrase>
+<phrase>
+ <source>glyph</source>
+ <target>icona</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>casella di gruppo</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>quadratino di ridimensionamento </target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Guida</target>
+</phrase>
+<phrase>
+ <source>Help menu</source>
+ <target>menu ?</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Nascondi</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>selezione gerarchica</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>tenere premuto</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>area sensibile del puntatore</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>area sensibile dell&apos;oggetto</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>icona</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>inattivo</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>finestra inattiva</target>
+</phrase>
+<phrase>
+ <source>ink</source>
+ <target>tratto</target>
+</phrase>
+<phrase>
+ <source>ink edit</source>
+ <target>modifica tratto</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>elemento attivo</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>menu Inserisci</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Inserisci oggetto</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>punto di inserimento</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>corsivo</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>etichetta</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>orizzontale</target>
+</phrase>
+<phrase>
+ <source>lasso-tap</source>
+ <target>selezione circolare</target>
+</phrase>
+<phrase>
+ <source>lens</source>
+ <target>lente</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>collegamento</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>collegare</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Collega</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>casella di riepilogo</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>visualizzazione elementi</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>collegamento manuale</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Ingrandisci</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>pulsante di ingrandimento</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>menu</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>barra dei menu</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>pulsante menu</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>voce di menu</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>titolo di menu</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>finestra di messaggio</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Riduci a icona</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>pulsante di riduzione ad icona</target>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>valori misti</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>a scelta obbligatoria</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>modalità</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>non a scelta obbligatoria</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>tasto di modifica delle funzioni di tastiera</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>tasto di modifica dell&apos;output di tastiera</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>mouse</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Sposta</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Sposta</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>interfaccia a documenti multipli</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>casella di riepilogo a selezione multipla</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Risorse del computer</target>
+ <definition>icon/icono</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Risorse di rete</target>
+ <definition>icon</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Nuovo</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Avanti</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>oggetto</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>caratteristica Trascina selezione</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>oggetto incorporato OLE</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>oggetto collegato OLE</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>caratteristica Trascina selezione OLE non predefinita</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Apri</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Apri con</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>pulsante di opzione</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>opzione impostata</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>opzione attivata</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>package</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Imposta pagina</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>casella degli tavolozza di colori</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>casella degli strumenti</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>riquadro</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>finestra principale</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>password</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Incolla </target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Incolla collegamento</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Incolla collegamento</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Incolla speciale</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>percorso</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Interrompi</target>
+</phrase>
+<phrase>
+ <source>pen</source>
+ <target>penna</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Riproduci</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug and Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>punto</target>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>puntatore</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>menu di scelta rapida</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>finestra popup</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>verticale</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>premere</target>
+ <definition>a key/un tasto</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>premere</target>
+ <definition>and hold a mouse button/e tenere premuto un pulsante del mouse</definition>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>contenitore principale</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>finestra principale</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Stampa</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>stampante</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>indicatore di avanzamento del processo</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>progetto</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Proprietà</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>visualizzatore proprietà</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>scheda proprietà</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>finestra proprietà</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>controllo finestra proprietà</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Anteprima</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>sola lettura</target>
+</phrase>
+<phrase>
+ <source>recognition</source>
+ <target>riconoscimento</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Cestino</target>
+ <definition>Icon</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Ripeti</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>selezione dell&apos;area</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>registro di configurazione</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Ripeti</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Sostituisci</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Ripristina</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>pulsante di ripristino</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Riprendi</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Riprova</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>casello di testo RTF</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Esegui</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Salva</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Salva con nome</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>scorrere</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>freccia di scorrimento</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>barra di scorrimento</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>casella di scorrimento</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>finestra secondaria</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>selezionare</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Seleziona tutto</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>selezione</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>quadratino di selezione</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Invia a</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>separatore</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Impostazioni</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Imposta</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>collegamento</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>pulsante di collegamento</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>icona di collegamento</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>tasto di scelta rapida</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>controllo tasto di scelta rapida</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Mostra</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Chiudi sessione</target>
+ <definition>comando del menu Avvio</definition>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Arresta il sistema</target>
+ <definition>pulsanti e opzioni</definition>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>casella di riepilogo a selezione singola</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Dimensione</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>punto di ridimensionamento</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>dispositivo di scorrimento</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>casella di selezione</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Dividi</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>barra di divisione</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>casella di divisione</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>pulsante Avvio</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>cartella Esecuzione automatica</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>barra di stato</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Ferma</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>controllo a schede</target>
+</phrase>
+<phrase>
+ <source>tap</source>
+ <target>toccare</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>tap</source>
+ <target>tocco</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>barra delle applicazioni</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>guida orientata alle attività</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>modello</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>casella di testo</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>barra del titolo</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>testo della barra del titolo</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>tasto interruttore</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>barra degli strumenti</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>descrizione comando</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>controllo per la visualizzazione ad albero</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>inserire</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>digitare</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>tipo</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>non disponibile</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Annulla</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Rimozione</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>menu Visualizza</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>modifica diretta</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>controllo di selezione grafica</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Guida rapida</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>menu Finestra</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>finestra</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Gestione risorse</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>installazione guidata</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>cartella di lavoro</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>gruppo di lavoro</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>area di lavoro</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Sì</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/japanese.qph b/src/linguist/phrasebooks/japanese.qph
new file mode 100644
index 000000000..3ecd9e332
--- /dev/null
+++ b/src/linguist/phrasebooks/japanese.qph
@@ -0,0 +1,1021 @@
+<!DOCTYPE QPH><QPH language="ja">
+<phrase>
+ <source>About</source>
+ <target>ã«ã¤ã„ã¦</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>アクセスキー</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>ユーザー補助</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>アクションãƒãƒ³ãƒ‰ãƒ«</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>アクティブ</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>アクティブエンド</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>アクティブオブジェクト</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>アクティブウィンドウ</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>装飾</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>常ã«æ‰‹å‰ã«è¡¨ç¤º</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>アンカーãƒã‚¤ãƒ³ãƒˆ</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>é©ç”¨</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>自動終了</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>オートリンク</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>オートスクロール</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>自動繰り返ã—</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>自動スクロール</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>戻る</target>
+</phrase>
+<phrase>
+ <source>barrel button</source>
+ <target>丸ボタン</target>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>å‚ç…§</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>キャンセル</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>カスケードメニュー</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>ãƒã‚§ãƒƒã‚¯ãƒžãƒ¼ã‚¯</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>å­ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>é¸æŠž</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>クリック</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>クリップボード</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>é–‰ã˜ã‚‹</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>é–‰ã˜ã‚‹ãƒœã‚¿ãƒ³</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>éžè¡¨ç¤º</target>
+ <definition>セルãªã©</definition>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>折りãŸãŸã¿</target>
+ <definition>XML</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>列見出ã—</target>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>コンボボックス</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>コマンドボタン</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>コンテナ</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>文脈ä¾å­˜ã®ãƒ˜ãƒ«ãƒ—</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>文脈ã®</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>コントロール</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>コピー</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>ã“ã“ã«ã‚³ãƒ”ー</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>ショートカットを作æˆ</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>ショートカットをã“ã“ã«ä½œæˆ</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>切りå–ã‚Š</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>既定</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>既定ã®ãƒœã‚¿ãƒ³</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>削除</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>デスクトップ</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>コピー先</target>
+ <definition>ファイルãªã©</definition>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>é€ä¿¡å…ˆ</target>
+ <definition>FAXã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãªã©</definition>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>変æ›å…ˆ</target>
+ <definition>文字コードã€ãƒ•ã‚¡ã‚¤ãƒ«å½¢å¼ãªã©</definition>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>出力先</target>
+ <definition>ログã€ãƒ•ã‚¡ã‚¤ãƒ«ãªã©</definition>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>ダイアログボックス</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>障害</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>離れãŸè¤‡æ•°é …目をé¸æŠž</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>ドック</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>ドキュメント</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>ダブルクリック</target>
+</phrase>
+<phrase>
+ <source>double-tap</source>
+ <target>ダブルタップ</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>ドラッグ</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>ドラッグアンドドロップ</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>ドロップダウンコンボボックス</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>ドロップダウンリストボックス</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>ドロップダウンメニュー</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>編集</target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>編集メニュー</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>çœç•¥</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>埋ã‚è¾¼ã¿ã‚ªãƒ–ジェクト</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>終了</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>展開ã™ã‚‹</target>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>エクスプローラ</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>æ‹¡å¼µé¸æŠž</target>
+ <definition>F8</definition>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>æ‹¡å¼µé¸æŠžãƒªã‚¹ãƒˆãƒœãƒƒã‚¯ã‚¹</target>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>ファイル</target>
+</phrase>
+<phrase>
+ <source>File</source>
+ <target>ファイル</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>検索</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>次を検索</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>検索ã™ã‚‹æ–‡å­—列</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>フォルダ</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>フォント</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>フォントサイズ</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>フォントスタイル</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>ファンクションキー</target>
+</phrase>
+<phrase>
+ <source>gesture</source>
+ <target>ジェスãƒãƒ£ãƒ¼</target>
+</phrase>
+<phrase>
+ <source>glyph</source>
+ <target>標識</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>グループボックス</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>ãƒãƒ³ãƒ‰ãƒ«</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>ヘルプ</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>éžè¡¨ç¤º</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>ä¿ç•™</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>ホットスãƒãƒƒãƒˆ</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>ホットゾーン</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>アイコン</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>éžã‚¢ã‚¯ãƒ†ã‚£ãƒ–</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>éžã‚¢ã‚¯ãƒ†ã‚£ãƒ–ウィンドウ</target>
+</phrase>
+<phrase>
+ <source>ink</source>
+ <target>インク</target>
+</phrase>
+<phrase>
+ <source>ink edit</source>
+ <target>インクエディット</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>入力フォーカス</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>挿入</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>オブジェクトã®æŒ¿å…¥</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>挿入ä½ç½®</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>斜体</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>ラベル</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>横</target>
+</phrase>
+<phrase>
+ <source>lens</source>
+ <target>レンズ</target>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>リンク</target>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>ã“ã“ã«ãƒªãƒ³ã‚¯</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>リストボックス</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>一覧ã®è¡¨ç¤º</target>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>手動リンク</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>最大化</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>最大化ボタン</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>メニュー</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>メニューãƒãƒ¼</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>メニューボタン</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>メニュー項目</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>メニュータイトル</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>メッセージボックス</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>最å°åŒ–</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>最å°åŒ–ボタン</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>モーダル</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>モード</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>モードレス</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>修飾キー</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>マウス</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>移動</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>ã“ã“ã«ç§»å‹•</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>マルãƒãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ã‚¤ã‚¹</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>複数é¸æŠžãƒªã‚¹ãƒˆãƒœãƒƒã‚¯ã‚¹</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>マイコンピュータ</target>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚³ãƒ³ãƒ”ュータ</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>æ–°è¦</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>次ã¸</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>オブジェクト</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>OLEドラッグアンドドロップ</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>OLE 埋ã‚è¾¼ã¿ã‚ªãƒ–ジェクト</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>OLE リンクオブジェクト</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>OLE ノンデフォルトドラッグアンドドロップ</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>é–‹ã</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>アプリケーションã‹ã‚‰é–‹ã</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>オプションボタン</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>オプションセット</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>パッケージ</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>ページ設定</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>パレットウィンドウ</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>ペイン</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>親ウィンドウ</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>パスワード</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>貼り付ã‘</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>リンク貼り付ã‘</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>ショートカットã®è²¼ã‚Šä»˜ã‘</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>å½¢å¼ã‚’é¸æŠžã—ã¦è²¼ã‚Šä»˜ã‘</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>パス</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>一時åœæ­¢</target>
+</phrase>
+<phrase>
+ <source>pen</source>
+ <target>ペン</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>å†ç”Ÿ</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>プラグアンドプレイ</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>ãƒã‚¤ãƒ³ãƒˆ</target>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>ãƒã‚¤ãƒ³ã‚¿</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>ãƒãƒƒãƒ—アップメニュー</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>ãƒãƒƒãƒ—アップウィンドウ</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>縦</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>押ã™</target>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>プライマリコンテナ</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>プライマリウィンドウ</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>å°åˆ·</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>プリンタ</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>進行状æ³ã‚¤ãƒ³ã‚¸ã‚±ãƒ¼ã‚¿</target>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>プロジェクト</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>プロパティ</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>プロパティインスペクター</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>プロパティページ</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>プロパティシート</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>プロパティシートコントロール</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>クイックビューア</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>読ã¿å–り専用</target>
+</phrase>
+<phrase>
+ <source>recognition</source>
+ <target>èªè­˜</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>ã”ã¿ç®±</target>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>ã‚„ã‚Šç›´ã™</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>範囲é¸æŠž</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>レジストリ</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>ç¹°ã‚Šè¿”ã™</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>ç½®æ›</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>å…ƒã«æˆ»ã™</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>リストアボタン</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>å†é–‹</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>å†è©¦è¡Œ</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>リッãƒãƒ†ã‚­ã‚¹ãƒˆãƒœãƒƒã‚¯ã‚¹</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>ファイルåを指定ã—ã¦å®Ÿè¡Œ</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>ä¿å­˜</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>åå‰ã‚’付ã‘ã¦ä¿å­˜</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>スクロール</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>スクロール矢å°</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>スクロールãƒãƒ¼</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>スクロールボックス</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>セカンダリウィンドウ</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>é¸æŠž</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>ã™ã¹ã¦ã‚’é¸æŠž</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>é¸æŠžã—ãŸéƒ¨åˆ†</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>セレクションãƒãƒ³ãƒ‰ãƒ«</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>é€ã‚‹</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>セパレータ</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>設定</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>設定</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>ショートカット</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>ショートカットボタン</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>ショートカットアイコン</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>ショートカットキー</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>ショートカットキーコントロール</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>表示</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>シャットダウン</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>å˜ä¸€é¸æŠžãƒªã‚¹ãƒˆãƒœãƒƒã‚¯ã‚¹</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>サイズ</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>サイズグリップ</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>スライダー</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>スピンボックス</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>分割</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>分割ãƒãƒ¼</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>分割ボックス</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>スタートボタン</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>スタートアップフォルダ</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>ステータスãƒãƒ¼</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>åœæ­¢</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>タブコントロール</target>
+</phrase>
+<phrase>
+ <source>tap</source>
+ <target>タップ</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>タスクãƒãƒ¼</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>タスク志å‘ã®ãƒ˜ãƒ«ãƒ—</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>テンプレート</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>テキストボックス</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>タイトルãƒãƒ¼</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>タイトルテキスト</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>トグルキー</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>ツールãƒãƒ¼</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>ツールãƒãƒƒãƒ—</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>ツリービューコントロール</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>タイプ</target>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>利用ä¸å¯</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>å…ƒã«æˆ»ã™</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>アンインストール</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>表示</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>ç”»é¢ç·¨é›†</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>ヘルプ</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>ウィンドウ</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>ウィンドウ</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>ウィンドウズエクスプローラ</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>ウィザード</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>ワークブック</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>ワークグループ</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>ワークスペース</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>ã¯ã„</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/norwegian.qph b/src/linguist/phrasebooks/norwegian.qph
new file mode 100644
index 000000000..9fda2ad68
--- /dev/null
+++ b/src/linguist/phrasebooks/norwegian.qph
@@ -0,0 +1,1004 @@
+<!DOCTYPE QPH><QPH language="no">
+<phrase>
+ <source>About</source>
+ <target>Om</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>tilgangstast</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>tilgjengelighet</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>handlingshåndtak</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>aktiv</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>markeringsavslutning</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>aktivt objekt</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>aktivt vindu</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>verktøyselement</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Alltid øverst</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>forankringspunkt</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Bruk</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>automatisk avslutning</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>automatisk gjentagelse</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>automatisk kobling</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>automatisk rulling</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>autorulling</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Tilbake</target>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Bla gjennom</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Avbryt</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>undermeny</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>avmerkingsboks</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>merke</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>undervindu</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>velge</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>klikke</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>utklippstavle</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Lukk</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>lukkeknapp</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>skjule</target>
+ <definition>outline/disposisjon</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>kolonneoverskrift</target>
+ <definition>control/kontroll</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>kombinasjonsboks</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>kommandoknapp</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>beholder</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>kontekstavhengig hjelp</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>kontekstavhengig</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>kontroll</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Kopier</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Kopier hit</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Lag snarvei</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Lag snarvei her</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Klipp ut</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>standard</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>standardknapp</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Slett</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>skrivebord</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>mål</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>dialogboks</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>funksjonshemning</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>ikke sammenhengende utvalg</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>forankre</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>dokument</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>dobbeltklikke</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>dra</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>dra och slippe</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>kombinasjonsboks</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>rullegardinliste</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>rullegardinmeny</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Rediger</target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>Rediger-menyen</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>ellipse</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>innebygd objekt</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Avslutt</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>utvide</target>
+ <definition>an outline/en disposisjon</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Utforsk</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>utvidet merking</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>liste med utvidet merking</target>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>fil</target>
+</phrase>
+<phrase>
+ <source>File menu</source>
+ <target>Fil-menyen</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Søk etter</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Søk etter neste</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Søk etter</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>mappe</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>skrift</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>skriftstørrelse</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>skriftstil</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>funksjonstast</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>gruppeboks</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>håndtak</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Hjelp</target>
+</phrase>
+<phrase>
+ <source>Help menu</source>
+ <target>Hjelp-menyen</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Skjul</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>hierarkisk merking</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>holde</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>fokus</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>fokuseringssone</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>ikon</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>inaktiv</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>inaktivt vindu</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>indatafokus</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Sett inn-menyen</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Sett inn objekt</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>innsettingspunkt</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>kursiv</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>etikett</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>liggende</target>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>koble</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>kobling</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Lag kobling her</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>listeboks</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>listevisning</target>
+ <definition>control/kontroll</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>manuell kobling</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Maksimer</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>maksimeringsknapp</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>meny</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>menylinje</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>menyknapp</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>menyelement</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>menytittel</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>meldingsboks</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimer</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>minimeringsknapp</target>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>blandet verdi</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>modal</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>modus</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>icke-modal</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>modifiseringstast</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>mus</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Flytt</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Flytt hit</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>flerdokumentgrensesnitt</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>flervalgsliste</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Min datamaskin</target>
+ <definition>icon/ikon</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Andre maskiner</target>
+ <definition>icon/ikon</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Ny</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Neste</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>objekt</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>OLE dra og slipp</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>innebyggd OLE-objekt</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>koblet OLE-objekt</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>utvidet OLE dra og slipp</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Ã…pne</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Ã…pne i</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>alternativknapp</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>valgt alternativ</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>pakke</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Utskriftsformat</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>palettvindu</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>rute</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>hovedvindu</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>passord</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Lim inn</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Lim inn kobling</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Lim inn snarvei</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Lim inn utvalg</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>bane</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Pause</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Spill</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug and Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>punkt</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>peke</target>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>peker</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>hurtigmeny</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>forklaringsvindu</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>stående</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>klikke</target>
+ <definition>and hold a mouse button/og holde nede en musetast</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>trykke</target>
+ <definition>a key/en tast</definition>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>primærbeholder</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>primærvindu</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Skriv ut</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>skriver</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>fremdriftsindikator</target>
+ <definition>control/kontroll</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>prosjekt</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Egenskaper</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>egenskapsvisning</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>egenskapsside</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>egenskapsark</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>egenskapsarkkontroll</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Hurtigvisning</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>skrivebeskyttet</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Papirkurv</target>
+ <definition>Icon/ikon</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Gjør om</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>områdemerking</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>register</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Gjenta</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Erstatt</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Gjenopprett</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>gjenopprettingsknapp</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Fortsett</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Prøv på nytt</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>boks for rik tekst</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Kjør</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Lagre</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Lagre som</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>rulle</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>rullepil</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>rullefelt</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>rulleboks</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>sekundærvindu</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>merke</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Merk alt</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>merket område</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>markeringshåndtak</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Send til</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>skilletegn</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Innstillinger</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Installasjon</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>snarvei</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>snarveisknapp</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>snarveisikon</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>hurtigtast</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>hurtigtastkontroll</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Vis</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Avslutt</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>enkeltvalgsliste</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Størrelse</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>skaleringshåndtak</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>glidebryter</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>verdisettingsboks</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Del</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>delelinje</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>deleboks</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>startknapp</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>Oppstart-mappen</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>statuslinje</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Stopp</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>kategorikontroll</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>oppgavelinje</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>oppgaveorientert hjelp</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>mal</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>tekstboks</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>tittellinje</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>titteltekst</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>veksletast</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>verktøylinje</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>verktøytips</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>trevisningskontroll</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>skrive</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>type</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>ikke tilgjengelig</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Angre</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Avinstaller</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>Vis-meny</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>visuell redigering</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>grafikkontroll</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Hva er dette?</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Vindu-menyen</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>vindu</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Windows Utforsker</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>veiviser</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>arbeidsbok</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>arbeidsgruppe</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>arbeidsområde</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Ja</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/polish.qph b/src/linguist/phrasebooks/polish.qph
new file mode 100644
index 000000000..9cedaecae
--- /dev/null
+++ b/src/linguist/phrasebooks/polish.qph
@@ -0,0 +1,527 @@
+<!DOCTYPE QPH><QPH language="pl">
+<phrase>
+ <source>About</source>
+ <target>Informacje o</target>
+</phrase>
+<phrase>
+ <source>About Qt</source>
+ <target>Informacje o Qt</target>
+</phrase>
+<phrase>
+ <source>Accelerator</source>
+ <target>Klawisz szybkiego dostępu</target>
+</phrase>
+<phrase>
+ <source>Alloc</source>
+ <target>Przydzielić</target>
+</phrase>
+<phrase>
+ <source>Appearance</source>
+ <target>WyglÄ…d</target>
+</phrase>
+<phrase>
+ <source>at line</source>
+ <target>w linii</target>
+</phrase>
+<phrase>
+ <source>Background</source>
+ <target>TÅ‚o</target>
+</phrase>
+<phrase>
+ <source>Batch</source>
+ <target>Wsadowy....</target>
+</phrase>
+<phrase>
+ <source>Build </source>
+ <target>Wersja</target>
+</phrase>
+<phrase>
+ <source>Cannot create</source>
+ <target>Nie można utworzyć</target>
+</phrase>
+<phrase>
+ <source>Cannot find</source>
+ <target>Nie można znaleść</target>
+</phrase>
+<phrase>
+ <source>Cannot read</source>
+ <target>Nie można odczytać</target>
+</phrase>
+<phrase>
+ <source>Cannot save</source>
+ <target>Nie można zapisać</target>
+</phrase>
+<phrase>
+ <source>Case sensitive</source>
+ <target>Uwzględniaj wielkość liter</target>
+</phrase>
+<phrase>
+ <source>Child</source>
+ <target>Potomek Dziecko</target>
+</phrase>
+<phrase>
+ <source>Collapse</source>
+ <target>Zwinąć</target>
+</phrase>
+<phrase>
+ <source>ComboBox</source>
+ <target>Lista kombi</target>
+</phrase>
+<phrase>
+ <source>Conflicting</source>
+ <target>KolidujÄ…cy</target>
+</phrase>
+<phrase>
+ <source>Content</source>
+ <target>Treść</target>
+</phrase>
+<phrase>
+ <source>Contents</source>
+ <target>Treść Zawartość Spis treści</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Kopiuj</target>
+</phrase>
+<phrase>
+ <source>Custom</source>
+ <target>Niestandardowy, użytkownika</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Wytnij</target>
+</phrase>
+<phrase>
+ <source>Declare</source>
+ <target>Deklarować</target>
+</phrase>
+<phrase>
+ <source>Declared</source>
+ <target>Zadeklarować</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Usuń</target>
+</phrase>
+<phrase>
+ <source>Disable</source>
+ <target>Wyłącz, zablokuj</target>
+</phrase>
+<phrase>
+ <source>Display</source>
+ <target>Pokaż, wyświetl</target>
+</phrase>
+<phrase>
+ <source>Dock</source>
+ <target>Osadzony Zakotwiczony</target>
+</phrase>
+<phrase>
+ <source>Dock window</source>
+ <target>Okno osadzone Okno zakotwiczone</target>
+</phrase>
+<phrase>
+ <source>Down</source>
+ <target>W dół</target>
+</phrase>
+<phrase>
+ <source>Enable</source>
+ <target>WÅ‚Ä…cz</target>
+</phrase>
+<phrase>
+ <source>Enabled</source>
+ <target>WÅ‚Ä…czony</target>
+</phrase>
+<phrase>
+ <source>encoding name</source>
+ <target>nazwa kodowania</target>
+</phrase>
+<phrase>
+ <source>Entity</source>
+ <target>Obiekt</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Zakończ</target>
+</phrase>
+<phrase>
+ <source>Expand</source>
+ <target>Rozszerzyć</target>
+</phrase>
+<phrase>
+ <source>Fade</source>
+ <target>Wyłanianie</target>
+</phrase>
+<phrase>
+ <source>Failed to open</source>
+ <target>Nie można otworzyć</target>
+</phrase>
+<phrase>
+ <source>Feel</source>
+ <target>działanie</target>
+</phrase>
+<phrase>
+ <source>File</source>
+ <target>Plik</target>
+</phrase>
+<phrase>
+ <source>Find in text</source>
+ <target>Znajdź w tekście</target>
+</phrase>
+<phrase>
+ <source>Find next</source>
+ <target>Znajdź następne</target>
+</phrase>
+<phrase>
+ <source>Focal</source>
+ <target>Ogniskowa</target>
+</phrase>
+<phrase>
+ <source>Font family</source>
+ <target>Nazwa czcionki</target>
+</phrase>
+<phrase>
+ <source>Foreground</source>
+ <target>PIerwszy plan</target>
+</phrase>
+<phrase>
+ <source>Form</source>
+ <target>Okno formy</target>
+</phrase>
+<phrase>
+ <source>full text search</source>
+ <target>szukanie w treści tesktu</target>
+</phrase>
+<phrase>
+ <source>fulltext search</source>
+ <target>szukanie w treści tesktu</target>
+</phrase>
+<phrase>
+ <source>Go</source>
+ <target>Przejdź</target>
+ <definition>przy przeglÄ…darkach</definition>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Pomoc</target>
+</phrase>
+<phrase>
+ <source>Home</source>
+ <target>Strona startowa</target>
+ <definition>przy przeglÄ…darkach</definition>
+</phrase>
+<phrase>
+ <source>Illegal</source>
+ <target>Niepoprawny</target>
+</phrase>
+<phrase>
+ <source>Invalid</source>
+ <target>Niepoprawny</target>
+</phrase>
+<phrase>
+ <source>Invoke</source>
+ <target>Wywołaj</target>
+</phrase>
+<phrase>
+ <source>is missing</source>
+ <target>Brakuje ...</target>
+</phrase>
+<phrase>
+ <source>Item</source>
+ <target>Pozycja</target>
+</phrase>
+<phrase>
+ <source>Item</source>
+ <target>Wpis</target>
+</phrase>
+<phrase>
+ <source>Lay out</source>
+ <target>Ułóż</target>
+</phrase>
+<phrase>
+ <source>layout</source>
+ <target>ułożenie</target>
+</phrase>
+<phrase>
+ <source>Link</source>
+ <target>Odnośnik</target>
+ <definition>(w pliku HTML)</definition>
+</phrase>
+<phrase>
+ <source>Link</source>
+ <target>DowiÄ…zanie</target>
+ <definition>(lokalizacja)</definition>
+</phrase>
+<phrase>
+ <source>literal</source>
+ <target>stała znakowa</target>
+</phrase>
+<phrase>
+ <source>Load</source>
+ <target>Wczytaj</target>
+</phrase>
+<phrase>
+ <source>Look and feel</source>
+ <target>Wygląd i działanie</target>
+</phrase>
+<phrase>
+ <source>Marker</source>
+ <target>Znacznik</target>
+</phrase>
+<phrase>
+ <source>Match</source>
+ <target>dopasowanie</target>
+</phrase>
+<phrase>
+ <source>Menu bar</source>
+ <target>Pasek menu</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimalizuj</target>
+</phrase>
+<phrase>
+ <source>Mismatch</source>
+ <target>Niezgodność, niedopasowanie</target>
+</phrase>
+<phrase>
+ <source>Namespace</source>
+ <target>Przesteń nazw</target>
+</phrase>
+<phrase>
+ <source>Occure</source>
+ <target>Wystąpić</target>
+</phrase>
+<phrase>
+ <source>Occured</source>
+ <target>Wystąpił, pojawił się</target>
+</phrase>
+<phrase>
+ <source>Off The Spot</source>
+ <target>Na pasku stanu</target>
+ <definition>Zmiany wykonywane sa w dodatkowym miejscu np na pasku stanu i dopiero pozniej wprowadzane do tesktu</definition>
+</phrase>
+<phrase>
+ <source>On The Spot</source>
+ <target>W oknie dokumentu</target>
+ <definition>Metoda wprowadzania znaków - bezposrednio w oknie</definition>
+</phrase>
+<phrase>
+ <source>Open Source Edition</source>
+ <target>Wydanie Open Source</target>
+</phrase>
+<phrase>
+ <source>Over The Spot</source>
+ <target>Nad oknem dokumentu</target>
+ <definition>Zmiany są wprowadzane z wyższej warstwie i renderowane później</definition>
+</phrase>
+<phrase>
+ <source>Pad</source>
+ <target>Dopełnić, Podstawka, Dopełnienie</target>
+</phrase>
+<phrase>
+ <source>Parse</source>
+ <target>Przetwarzać</target>
+</phrase>
+<phrase>
+ <source>Parsing</source>
+ <target>Przetwarzanie</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Wklej</target>
+</phrase>
+<phrase>
+ <source>Pattern</source>
+ <target>Wzorzec</target>
+</phrase>
+<phrase>
+ <source>Phrase</source>
+ <target>Wyrażenie, fraza</target>
+</phrase>
+<phrase>
+ <source>Place</source>
+ <target>Wstaw</target>
+</phrase>
+<phrase>
+ <source>Preference</source>
+ <target>Wyróżnienie</target>
+</phrase>
+<phrase>
+ <source>Preferences</source>
+ <target>Wyróżnienia</target>
+</phrase>
+<phrase>
+ <source>Premature</source>
+ <target>Przedwczesny</target>
+</phrase>
+<phrase>
+ <source>Promote</source>
+ <target>Wypromuj</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Właściwości</target>
+</phrase>
+<phrase>
+ <source>Property</source>
+ <target>Właściwość</target>
+</phrase>
+<phrase>
+ <source>Quotation mark</source>
+ <target>Znak cudzysłowu</target>
+</phrase>
+<phrase>
+ <source>Reference</source>
+ <target>Odwołanie</target>
+</phrase>
+<phrase>
+ <source>Refresh</source>
+ <target>Odśwież</target>
+</phrase>
+<phrase>
+ <source>Render</source>
+ <target>Renderuj</target>
+ <definition>odnosi siÄ™ jedynie do grafiki</definition>
+</phrase>
+<phrase>
+ <source>Reset</source>
+ <target>Przywróc ustawienia</target>
+</phrase>
+<phrase>
+ <source>Root</source>
+ <target>W dodatkowym oknie</target>
+ <definition>Zmiany wprowadzane sa w zupelnie dodatkowym oknie i pozniej wprowadzane do calego tekstu</definition>
+</phrase>
+<phrase>
+ <source>Saturation</source>
+ <target>Nasycenie</target>
+</phrase>
+<phrase>
+ <source>search word</source>
+ <target>wyrażenie do szukania</target>
+</phrase>
+<phrase>
+ <source>Search wrapped</source>
+ <target>Szukanie od poczÄ…tku</target>
+</phrase>
+<phrase>
+ <source>searchword</source>
+ <target>wyrażenie do szukania</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Zaznacz wszystko</target>
+</phrase>
+<phrase>
+ <source>Sequence</source>
+ <target>CiÄ…g</target>
+</phrase>
+<phrase>
+ <source>Sidebar</source>
+ <target>Panel</target>
+</phrase>
+<phrase>
+ <source>Sidebar</source>
+ <target>Panel boczny</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Rozmiar</target>
+</phrase>
+<phrase>
+ <source>Slider</source>
+ <target>Suwak</target>
+</phrase>
+<phrase>
+ <source>Specified</source>
+ <target>Określony</target>
+</phrase>
+<phrase>
+ <source>Status</source>
+ <target>Stan</target>
+</phrase>
+<phrase>
+ <source>Status Bar</source>
+ <target>Pasek stanu</target>
+</phrase>
+<phrase>
+ <source>Style sheet</source>
+ <target>Wzorzec stylu</target>
+</phrase>
+<phrase>
+ <source>StyleSheet</source>
+ <target>Wzorzec stylu</target>
+</phrase>
+<phrase>
+ <source>superfluous</source>
+ <target>przypadkowe, niecelowe, zbędny</target>
+</phrase>
+<phrase>
+ <source>Support</source>
+ <target>Obsługa</target>
+</phrase>
+<phrase>
+ <source>supported</source>
+ <target>obsługiwany</target>
+</phrase>
+<phrase>
+ <source>This program is licensed</source>
+ <target>Ten program wydany jest na licencji Qt Commercial. Aby sprawdzić szczegóły licencji, proszę sprawdzić plik LICENSE, który dołączany jest do pakietu Qt.</target>
+</phrase>
+<phrase>
+ <source>This version of</source>
+ <target>Ta wersja Qt Assistant jest częścią wydania Qt Open Source, przeznaczonego dla tworzenia i publikowania aplikacji Open Source. Qt jest zaawansowanym zestawem bibliotek wykorzystywanym do pisania aplikacji cross-platformowych.</target>
+</phrase>
+<phrase>
+ <source>to display</source>
+ <target>pokazywać, wyświetlać</target>
+</phrase>
+<phrase>
+ <source>Tool tips</source>
+ <target>Etykietki narzędzi</target>
+</phrase>
+<phrase>
+ <source>Toolbox</source>
+ <target>Narzędzie</target>
+</phrase>
+<phrase>
+ <source>ToolTips</source>
+ <target>Etykietki narzędzi</target>
+</phrase>
+<phrase>
+ <source>Tune</source>
+ <target>Ustawić</target>
+</phrase>
+<phrase>
+ <source>unsupported</source>
+ <target>nieobsługiwany</target>
+</phrase>
+<phrase>
+ <source>Up</source>
+ <target>W górę</target>
+</phrase>
+<phrase>
+ <source>Update</source>
+ <target>Uaktualnij</target>
+</phrase>
+<phrase>
+ <source>Value</source>
+ <target>Wartość</target>
+</phrase>
+<phrase>
+ <source>Widget</source>
+ <target>Element interfejsu</target>
+</phrase>
+<phrase>
+ <source>You need a commercial</source>
+ <target>Aby móc sprzedawać aplikację utworzone przy pomocy Qt potrzebujesz wersji komercyjnej. Proszę sprawdzić &lt;a href=&quot;http://qt.nokia.com/about&quot;&gt;qt.nokia.com/about&lt;/a&gt; dla poznania sposobu licencjonowania Qt.</target>
+</phrase>
+<phrase>
+ <source>Zoom in</source>
+ <target>Zwiększ</target>
+</phrase>
+<phrase>
+ <source>Zoom out</source>
+ <target>Zmniejsz</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/russian.qph b/src/linguist/phrasebooks/russian.qph
new file mode 100644
index 000000000..5876ee9ab
--- /dev/null
+++ b/src/linguist/phrasebooks/russian.qph
@@ -0,0 +1,1219 @@
+<!DOCTYPE QPH>
+<QPH language="ru">
+<phrase>
+ <source>About</source>
+ <target>О программе</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>горÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>Ñпециальные возможноÑти</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>управление поведением</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>активный</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>окончание выбора</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>активный объект</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>активное окно</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>украшение</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Ð’Ñегда наверху</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>точка начала выбора</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Применить</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>автоматичеÑкий выход</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>авто-повтор</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>автоматичеÑкое ÑвÑзывание</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>автоматичеÑÐºÐ°Ñ Ð¿Ñ€Ð¾ÐºÑ€ÑƒÑ‚ÐºÐ°</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>авто-прокрутка</target>
+</phrase>
+<phrase>
+ <source>boxed edit</source>
+ <target>окно редактированиÑ</target>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Обзор</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Отмена</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>ниÑпадающее меню</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>флажок</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>флажок</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>дочернее окно</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>выбрать</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>щелчок</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Буфер обмена</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Закрыть</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>Кнопка закрытиÑ</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>Ñвернуть</target>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>заголовок колонки</target>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>поле Ñо ÑпиÑком</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>кнопка</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>контейнер</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>контекÑÑ‚Ð½Ð°Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒ</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>контекÑтный</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>Ñлемент управлениÑ</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Копировать</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Копировать Ñюда</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Создать Ñрлык</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Создать Ñрлык здеÑÑŒ</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Вырезать</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>по умолчанию</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>кнопка по умолчанию</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Удалить</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>рабочий Ñтол</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>цель</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>окно диалога</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>неÑпоÑобноÑÑ‚ÑŒ</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>разделить выбранные Ñлементы</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>документ</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>двойной щелчок</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>перетащить</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>drag-and-drop</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>раÑкрыть поле Ñо ÑпиÑком</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>прокрутить ÑпиÑок</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>открыть меню</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Правка</target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>меню Правка</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>ÑллипÑ</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>вÑтроенный объект</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Выход</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>развернуть</target>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>ИÑÑледовать</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>раÑширенный выбор</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>ÑпиÑок Ñ Ñ€Ð°Ñширенным выбором</target>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>файл</target>
+</phrase>
+<phrase>
+ <source>File menu</source>
+ <target>меню Файл</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>ПоиÑк</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Ðайти далее</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>ИÑкать</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>папка</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>шрифт</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>размер шрифта</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>начертание</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°</target>
+</phrase>
+<phrase>
+ <source>glyph</source>
+ <target>глиф</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>контейнер Ñлементов</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>управление</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Справка</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Скрыть</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>иерархичеÑкий выбор</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>удерживать</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>фокуÑ</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>Ð°ÐºÑ‚Ð¸Ð²Ð½Ð°Ñ Ð·Ð¾Ð½Ð°</target>
+</phrase>
+<phrase>
+ <source>Icon</source>
+ <target>Значок</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>неактивный</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>неактивное окно</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>Ñ„Ð¾ÐºÑƒÑ Ð²Ð²Ð¾Ð´Ð°</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Ð’Ñтавить</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Ð’Ñтавить объект</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>меÑто вÑтавки</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>курÑив</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>надпиÑÑŒ</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>альбомнаÑ</target>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>ÑÑылка</target>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>ÑвÑзать</target>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Создать ÑÑылку здеÑÑŒ</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>ÑпиÑок</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>ÑпиÑок</target>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>ручное ÑвÑзывание</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>РаÑпахнуть</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>кнопка макÑимизации</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>меню</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>Ñтрока меню</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>кнопка меню</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>Ñлемент меню</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>заголовок меню</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>окно Ñообщений</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Свернуть</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>кнопка минимизации</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>модальный</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>режим</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>немодальный</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>клавиша-модификатор</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>мышь</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>ПеремеÑтить</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>ПеремеÑтить Ñюда</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>Multiple Document Interface</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>ÑпиÑок Ñ Ð¼Ð½Ð¾Ð¶ÐµÑтвенным выбором</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Мой компьютер</target>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Сетевое окружение</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Ðовый</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Далее</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>объект</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>ОК</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>OLE-механизм</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>внедрённый OLE-объект</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>ÑвÑзанный OLE-объект</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>предопределённый OLE-механизм</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Открыть</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Открыть Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>переключатель</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>набор параметров</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>пакет</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Параметры Ñтраницы</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>окно выбора палитры</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>панель</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>родительÑкое окно</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>пароль</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Ð’Ñтавить</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Ð’Ñтавить ÑÑылку</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Ð’Ñтавить Ñрлык</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Ð¡Ð¿ÐµÑ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñтавка</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>путь</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Пауза</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>ВоÑпроизведение</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug and Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>пункт</target>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>указатель</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>вÑплывающее меню</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>вÑплывающее окно</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>книжнаÑ</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>нажать</target>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>корневой контейнер</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>главное окно</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Печать</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>принтер</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>индикатор хода процеÑÑа</target>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>проект</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>СвойÑтва</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>инÑпектор ÑвойÑтв</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>Ñтраница ÑвойÑтв</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>группа ÑвойÑтв</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>управление группой ÑвойÑтв</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>БыÑтрый проÑмотр</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>только чтение</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Корзина</target>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Повторить</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>облаÑÑ‚ÑŒ выделениÑ</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>рееÑÑ‚Ñ€</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Повторить</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Заменить</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>ВоÑÑтановить</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>Кнопка воÑÑтановлениÑ</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Продолжить</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Повторить</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>окно RTF-редактора</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Выполнить</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Сохранить</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Сохранить как</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>прокрутить</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>кнопка прокрутки</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>полоÑа прокрутки</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>окно Ñ Ð¿Ð¾Ð»Ð¾Ñами прокрутки</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>подчинённое окно</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>выбрать</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Выделить вÑÑ‘</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>выбор</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>оÑущеÑтвление выбора</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Отправить</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>разделитель</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>ÐаÑтройки</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>УÑтановить</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>Ñрлык</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>кнопка</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>пиктограмма</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñˆ</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>наÑтройка комбинации клавиш</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Показать</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Выключение</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>ÑпиÑок Ñ Ð¾Ð´Ð¸Ð½Ð¾Ñ‡Ð½Ñ‹Ð¼ выбором</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Размер</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>уголок Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð°</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>регулÑтор</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>поле Ñо Ñчетчиком</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Разделить</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ‡ÐµÑ€Ñ‚Ð°</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ€Ð°Ð¼ÐºÐ°</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>кнопка ПуÑк</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>каталог ÐвтозапуÑка</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>Ñтрока ÑоÑтоÑниÑ</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>ОÑтановить</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>вкладка</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>панель задач</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>контекÑÑ‚Ð½Ð°Ñ Ñправка</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>шаблон</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>текÑтовое поле</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>заголовок</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>текÑÑ‚ заголовка</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>кнопка-переключатель</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>панель инÑтрументов</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>древовидный ÑпиÑок</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>тип</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>набирать</target>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>недоÑтупный</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Отменить</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Удалить</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>Вид</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>визуальное редактирование</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>Ñлемент графичеÑкого интерфейÑа</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Что Ñто?</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Окно</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>окно</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Проводник Windows</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>маÑтер</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>учебник</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>Ñ€Ð°Ð±Ð¾Ñ‡Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>Ñ€Ð°Ð±Ð¾Ñ‡Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑ‚ÑŒ</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Да</target>
+</phrase>
+<phrase>
+ <source>No</source>
+ <target>Ðет</target>
+</phrase>
+<phrase>
+ <source>Options</source>
+ <target>Параметры</target>
+</phrase>
+<phrase>
+ <source>directory</source>
+ <target>каталог</target>
+</phrase>
+<phrase>
+ <source>Finish</source>
+ <target>Завершить</target>
+</phrase>
+<phrase>
+ <source>Continue</source>
+ <target>Продолжить</target>
+</phrase>
+<phrase>
+ <source>advanced</source>
+ <target>раÑширенный</target>
+</phrase>
+<phrase>
+ <source>layout</source>
+ <target>компоновка</target>
+</phrase>
+<phrase>
+ <source>layout</source>
+ <target>компоновщик</target>
+</phrase>
+<phrase>
+ <source>plugin</source>
+ <target>модуль</target>
+</phrase>
+<phrase>
+ <source>script</source>
+ <target>Ñценарий</target>
+</phrase>
+<phrase>
+ <source>spacer</source>
+ <target>разделитель</target>
+</phrase>
+<phrase>
+ <source>tabbar</source>
+ <target>панель вкладок</target>
+</phrase>
+<phrase>
+ <source>whitespace</source>
+ <target>Ñимвол пробела</target>
+</phrase>
+<phrase>
+ <source>Forward</source>
+ <target>Вперёд</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Ðазад</target>
+</phrase>
+<phrase>
+ <source>Search wrapped</source>
+ <target>ПоиÑк Ñ Ð½Ð°Ñ‡Ð°Ð»Ð°</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>Закрыть</target>
+</phrase>
+<phrase>
+ <source>Match case</source>
+ <target>С учётом региÑтра</target>
+</phrase>
+<phrase>
+ <source>Case Sensitive</source>
+ <target>Учитывать региÑÑ‚Ñ€</target>
+</phrase>
+<phrase>
+ <source>Whole words</source>
+ <target>Слова целиком</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Ðайти Ñледующее</target>
+</phrase>
+<phrase>
+ <source>Find Previous</source>
+ <target>Ðайти предыдущее</target>
+</phrase>
+<phrase>
+ <source>Case Sensitive</source>
+ <target>Учитывать региÑÑ‚Ñ€ Ñимволов</target>
+</phrase>
+<phrase>
+ <source>Whole words only</source>
+ <target>Только Ñлова целиком</target>
+</phrase>
+<phrase>
+ <source>Subwindow</source>
+ <target>Дочернее окно</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Следующий</target>
+</phrase>
+<phrase>
+ <source>tree view</source>
+ <target>древовидный ÑпиÑок</target>
+</phrase>
+<phrase>
+ <source>ToolTip</source>
+ <target>ПодÑказка</target>
+</phrase>
+<phrase>
+ <source>Checkable</source>
+ <target>Переключаемое</target>
+</phrase>
+<phrase>
+ <source>Style</source>
+ <target>Ðачертание</target>
+</phrase>
+<phrase>
+ <source>Point size</source>
+ <target>Размер</target>
+</phrase>
+<phrase>
+ <source>Family</source>
+ <target>Шрифт</target>
+</phrase>
+<phrase>
+ <source>Writing system</source>
+ <target>СиÑтема пиÑьма</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>Удалить</target>
+</phrase>
+<phrase>
+ <source>Style</source>
+ <target>Стиль</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Изменить</target>
+</phrase>
+<phrase>
+ <source>Invalid</source>
+ <target>Ðекорректный</target>
+</phrase>
+<phrase>
+ <source>Invalid</source>
+ <target>ÐекорректнаÑ</target>
+</phrase>
+<phrase>
+ <source>Invalid</source>
+ <target>Ðекорректное</target>
+</phrase>
+<phrase>
+ <source>tag</source>
+ <target>Ñ‚Ñг</target>
+</phrase>
+<phrase>
+ <source>tab order</source>
+ <target>порÑдок обхода</target>
+</phrase>
+<phrase>
+ <source>Ascending</source>
+ <target>По возраÑтанию</target>
+</phrase>
+<phrase>
+ <source>Descending</source>
+ <target>По убыванию</target>
+</phrase>
+<phrase>
+ <source>Reset</source>
+ <target>СброÑить</target>
+</phrase>
+<phrase>
+ <source>Sort order</source>
+ <target>ПорÑдок Ñортировки</target>
+</phrase>
+<phrase>
+ <source>Appearance</source>
+ <target>Внешний вид</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>ПроÑмотр</target>
+</phrase>
+<phrase>
+ <source>Actions</source>
+ <target>ДейÑтвиÑ</target>
+</phrase>
+<phrase>
+ <source>Table of Contents</source>
+ <target>Оглавление</target>
+</phrase>
+<phrase>
+ <source>parse</source>
+ <target>разобрать</target>
+</phrase>
+<phrase>
+ <source>parsing</source>
+ <target>разбор</target>
+</phrase>
+<phrase>
+ <source>phrasebook</source>
+ <target>глоÑÑарий</target>
+</phrase>
+<phrase>
+ <source>phrase book</source>
+ <target>глоÑÑарий</target>
+</phrase>
+<phrase>
+ <source>In use</source>
+ <target>ИÑпользуетÑÑ</target>
+</phrase>
+<phrase>
+ <source>Access denied</source>
+ <target>ДоÑтуп запрещён</target>
+</phrase>
+<phrase>
+ <source>No error</source>
+ <target>Ðет ошибки</target>
+</phrase>
+<phrase>
+ <source>Not supported</source>
+ <target>Ðе поддерживаетÑÑ</target>
+</phrase>
+<phrase>
+ <source>Already exists</source>
+ <target>Уже ÑущеÑтвует</target>
+</phrase>
+<phrase>
+ <source>Permission denied</source>
+ <target>ДоÑтуп запрещён</target>
+</phrase>
+<phrase>
+ <source>Previous</source>
+ <target>Предыдущий</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Следующее</target>
+</phrase>
+<phrase>
+ <source>Previous</source>
+ <target>Предыдущее</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/spanish.qph b/src/linguist/phrasebooks/spanish.qph
new file mode 100644
index 000000000..dacb6b5d2
--- /dev/null
+++ b/src/linguist/phrasebooks/spanish.qph
@@ -0,0 +1,1086 @@
+<!DOCTYPE QPH><QPH language="es">
+<phrase>
+ <source>About</source>
+ <target>Acerca de</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>tecla de acceso</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>accesibilidad</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>controlador de acciones</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>activo</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>fin de la selección activa</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>objeto activo</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>ventana activa</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>opción gráfica</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Siempre visible</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>inicio de la selección activa</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Aplicar</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>salida automática</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>repetición automática</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>vínculo automático</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>desplazamiento automático</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>desplazamiento automático</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Atrás</target>
+</phrase>
+<phrase>
+ <source>barrel button</source>
+ <target>botón del lápiz</target>
+ <definition>pen</definition>
+</phrase>
+<phrase>
+ <source>barrel-tap</source>
+ <target>puntenar con el botón presionado</target>
+</phrase>
+<phrase>
+ <source>boxed edit</source>
+ <target>edición en casilla</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Examinar</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Cancelar</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>menú en cascada</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>casilla de verificación</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>marca de verificación</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>ventana secundaria</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>elegir</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>hacer clic</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Portapapeles</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Cerrar</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>botón &amp;quot;Cerrar&amp;quot;</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>contraer</target>
+ <definition>outline/esquerna</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>encabezado de columna</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>cuadro combinado</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>botón de comando</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>contenedor</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>ayuda interactiva</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>contextual</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>control</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Copiar</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Copiar aquí</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Crear acceso directo</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Crear acceso directo aquí</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Cortar</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>predeterminado</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>botón predeterminado</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Eliminar</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>escritorio</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>destino</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>cuadro de diálogo</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>Discapacidades</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>selección disjunta</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>acoplar</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>documento</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>hacer doble clic</target>
+</phrase>
+<phrase>
+ <source>double-tap</source>
+ <target>puntear dos veces</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>arrastrar</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>arrastrar y colocar</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>cuadro combinado desplegable</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>cuadro de lista desplegable</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>menú desplegable</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Edición</target>
+</phrase>
+<phrase>
+ <source>Edit menu</source>
+ <target>menú Edición</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>puntos suspensivos</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>objeto incrustado</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Salir</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>expandir</target>
+ <definition>an outline/un esquema</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Explorar</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>selección extendida</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>cuadro de lista de selección extendida</target>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>archivo</target>
+</phrase>
+<phrase>
+ <source>File menu</source>
+ <target>menú Archivo</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Buscar</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Buscar siguiente</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Buscar</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>carpeta</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>fuente</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>tamaño de fuente</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>estilo de fuente</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>tecla de función</target>
+</phrase>
+<phrase>
+ <source>gesture</source>
+ <target>signo</target>
+</phrase>
+<phrase>
+ <source>glyph</source>
+ <target>símbolo gráfico</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>cuadro de grupo</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>controlar</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>controlador</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Ayuda</target>
+</phrase>
+<phrase>
+ <source>Help menu</source>
+ <target>menú Ayuda</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Ocultar</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>selección jerárquica</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>mantener presionado</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>punto interactivo</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>zona interactiva</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>icono</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>inactivo</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>ventana inactiva</target>
+</phrase>
+<phrase>
+ <source>ink</source>
+ <target>trazo</target>
+</phrase>
+<phrase>
+ <source>ink edit</source>
+ <target>editor de trazos</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>zona de entrada</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>zona de entrada de datos</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>menú Insertar</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Insertar objeto</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>punto de inserción</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>cursiva</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>etiqueta</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>horizontal</target>
+</phrase>
+<phrase>
+ <source>lasso-tap</source>
+ <target>punteo en la selección</target>
+</phrase>
+<phrase>
+ <source>lens</source>
+ <target>lente</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>vincular</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>vínculo</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Vincular aquí</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>cuadro de lista</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>ver lista</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>presentación de iconos </target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>vínculo manual</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Maximizar</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>botón de maximizar</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>menú</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>barra de menús</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>botón de menú</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>elemento de menú</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>título de menú</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>cuadro de mensaje</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimizar</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>botón de minimizar</target>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>valores mezclados</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>modal</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>modo</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>sin modo</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>tecla modificadora</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>mouse</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Mover</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Mover aquí</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>interfaz de documentos múltiples</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>cuadro de lista de selección múltiple</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Mi PC</target>
+ <definition>icon/icono</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Entorno de red</target>
+ <definition>icon/icono</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Nuevo</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Sigulente</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>objeto</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>Aceptar</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>Arrastrar y colocar de OLE</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>Objeto incrustado de OLE</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>Objeto vinculado de OLE</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>Arrastrar y colocar no predeterminado de OLE</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Abrir</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Abrir con</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>botón de opción</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>opción establecida</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>paquete</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Preparar página</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>ventana de paleta</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>panel</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>ventana principal</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>contraseña</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Pegar</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Pegar vínculo</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Pegar acceso directo</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Pegado especial</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>ruta de acceso</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Pausa</target>
+</phrase>
+<phrase>
+ <source>pen</source>
+ <target>lápiz</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Reproducir</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug and Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>señalar</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>punto</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>puntero</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>menú emergente</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>ventana emergente</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>vertical</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>presionar</target>
+ <definition>and hold a mouse button/y mantener presionado un botón del mouse</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>presionar</target>
+ <definition>a key/una tecla</definition>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>contenedor primario</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>ventana principal</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Imprimir</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>impresora</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>indicador de progreso</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>proyecto</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Propiedades</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>monitor de propiedades</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>página de propiedades</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>hoja de propiedades</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>control de la hoja de propiedades</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Vista rápida</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>sólo lectura</target>
+</phrase>
+<phrase>
+ <source>recognition</source>
+ <target>reconocimiento</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Papelera de reciclaje</target>
+ <definition>Icon/icono</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Rehacer</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>selección de área</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>Registro de configuraciones</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Repetir</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Reemplazar</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Restaurar</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>botón &amp;quot;Restaurar&amp;quot;</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Reanudar</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Reintentar</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>cuadro de texto enriquecido</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Ejecutar</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Guardar</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Guardar como</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>desplazar</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>flecha de desplazamiento</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>barra de desplazamiento</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>cuadro de desplazamiento</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>ventana secundaria</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>seleccionar</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Seleccionar todo</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>selección</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>controlador de selección</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Enviar a</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>separador</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Configuración</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Configurar</target>
+ <definition>for a device already installed</definition>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Instalar</target>
+ <definition>for an application</definition>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>acceso directo</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>botón de acceso directo</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>icono de acceso directo</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>tecla de método abreviado</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>control de la tecla de método abreviado</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Mostrar</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Apagar el sistema</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>cuadro de lista de selección simple</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Tamaño</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>ajuste de tamaño</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>control deslizante</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>cuadro selector</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Dividir</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>barra de división</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>cuadro de división</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>botón &amp;quot;Inicio&amp;quot;</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>carpeta Inicio</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>barra de estado</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Detener</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>control de fichas</target>
+</phrase>
+<phrase>
+ <source>tap</source>
+ <target>puntear</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>barra de tareas</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>Ayuda relativa a la tarea</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>plantilla</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>cuadro de texto</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>barra de título</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>texto de título</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>tecla para alternar</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>barra de herramientas</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>sugerencias</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>control de visión en árbol</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>escribir</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>tipo</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>no disponible</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Deshacer</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Desinstalar</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>menú Ver</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>edición visual</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>control de opciones gráficas</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>¿Qué es esto?</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>menú Ventana</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>ventana</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Explorador de Windows</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>asistente</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>libro</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>libro de trabajo</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>grupo de trabajo</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>área de trabajo</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Sí</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/phrasebooks/swedish.qph b/src/linguist/phrasebooks/swedish.qph
new file mode 100644
index 000000000..a88735ec7
--- /dev/null
+++ b/src/linguist/phrasebooks/swedish.qph
@@ -0,0 +1,1010 @@
+<!DOCTYPE QPH><QPH language="sv">
+<phrase>
+ <source>About</source>
+ <target>Om</target>
+</phrase>
+<phrase>
+ <source>access key</source>
+ <target>snabbtangent</target>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>Hjälpmedel</target>
+ <definition>ikonen Accessibility</definition>
+</phrase>
+<phrase>
+ <source>accessibility</source>
+ <target>tillgänglighet</target>
+</phrase>
+<phrase>
+ <source>action handle</source>
+ <target>funktionshandtag</target>
+</phrase>
+<phrase>
+ <source>active</source>
+ <target>aktiv</target>
+</phrase>
+<phrase>
+ <source>active end</source>
+ <target>aktiv slutpunkt</target>
+</phrase>
+<phrase>
+ <source>active object</source>
+ <target>aktivt objekt</target>
+</phrase>
+<phrase>
+ <source>active window</source>
+ <target>aktivt fönster</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>fönsterfält</target>
+</phrase>
+<phrase>
+ <source>Always on Top</source>
+ <target>Alltid överst</target>
+</phrase>
+<phrase>
+ <source>anchor point</source>
+ <target>startpunkt</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Verkställ</target>
+</phrase>
+<phrase>
+ <source>auto-exit</source>
+ <target>flytta automatiskt</target>
+</phrase>
+<phrase>
+ <source>auto-repeat</source>
+ <target>upprepa automatiskt</target>
+</phrase>
+<phrase>
+ <source>automatic link</source>
+ <target>automatisk länk</target>
+</phrase>
+<phrase>
+ <source>automatic scrolling</source>
+ <target>automatisk rullning</target>
+</phrase>
+<phrase>
+ <source>autoscroll</source>
+ <target>automatisk rullning</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Föregående</target>
+</phrase>
+<phrase>
+ <source>Browse</source>
+ <target>Bläddra</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Avbryt</target>
+</phrase>
+<phrase>
+ <source>cascading menu</source>
+ <target>undermeny</target>
+</phrase>
+<phrase>
+ <source>check box</source>
+ <target>kryssruta</target>
+</phrase>
+<phrase>
+ <source>check mark</source>
+ <target>markering</target>
+</phrase>
+<phrase>
+ <source>child window</source>
+ <target>underfönster</target>
+</phrase>
+<phrase>
+ <source>choose</source>
+ <target>välj</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>klicka</target>
+</phrase>
+<phrase>
+ <source>Clipboard</source>
+ <target>Urklipp</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Stäng</target>
+</phrase>
+<phrase>
+ <source>Close button</source>
+ <target>stängningsknapp</target>
+</phrase>
+<phrase>
+ <source>collapse</source>
+ <target>komprimera</target>
+ <definition>outline</definition>
+</phrase>
+<phrase>
+ <source>column heading</source>
+ <target>kolumnrubrik</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>combo box</source>
+ <target>kombinationsruta</target>
+</phrase>
+<phrase>
+ <source>command button</source>
+ <target>kommandoknapp</target>
+</phrase>
+<phrase>
+ <source>container</source>
+ <target>behållare</target>
+</phrase>
+<phrase>
+ <source>context-sensitive Help</source>
+ <target>sammanhangsberoende hjälp</target>
+</phrase>
+<phrase>
+ <source>contextual</source>
+ <target>sammanhangsberoende</target>
+</phrase>
+<phrase>
+ <source>control</source>
+ <target>kontroll</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Kopiera</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Kopiera hit</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut</source>
+ <target>Skapa genväg</target>
+</phrase>
+<phrase>
+ <source>Create Shortcut Here</source>
+ <target>Skapa genväg här</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Klipp ut</target>
+</phrase>
+<phrase>
+ <source>default</source>
+ <target>standard</target>
+</phrase>
+<phrase>
+ <source>default button</source>
+ <target>standardknapp</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Ta bort</target>
+</phrase>
+<phrase>
+ <source>desktop</source>
+ <target>skrivbord</target>
+</phrase>
+<phrase>
+ <source>destination</source>
+ <target>mål</target>
+</phrase>
+<phrase>
+ <source>dialog box</source>
+ <target>dialogruta</target>
+</phrase>
+<phrase>
+ <source>disability</source>
+ <target>oförmåga</target>
+</phrase>
+<phrase>
+ <source>disjoint selection</source>
+ <target>osammanhängande markering</target>
+</phrase>
+<phrase>
+ <source>dock</source>
+ <target>docka</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>dokument</target>
+</phrase>
+<phrase>
+ <source>double-click</source>
+ <target>dubbelklicka på</target>
+</phrase>
+<phrase>
+ <source>drag</source>
+ <target>dra</target>
+</phrase>
+<phrase>
+ <source>drag-and-drop</source>
+ <target>dra och släpp</target>
+</phrase>
+<phrase>
+ <source>drop-down combo box</source>
+ <target>nedrullningsbar kombinationsruta</target>
+</phrase>
+<phrase>
+ <source>drop-down list box</source>
+ <target>nedrullningsbar listruta</target>
+</phrase>
+<phrase>
+ <source>drop-down menu</source>
+ <target>nedrullningsbar meny</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Redigera</target>
+</phrase>
+<phrase>
+ <source>ellipsis</source>
+ <target>punkter</target>
+</phrase>
+<phrase>
+ <source>embedded object</source>
+ <target>inbäddat objekt</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Avsluta</target>
+</phrase>
+<phrase>
+ <source>expand</source>
+ <target>expandera</target>
+ <definition>an outline</definition>
+</phrase>
+<phrase>
+ <source>Explore</source>
+ <target>Utforska</target>
+</phrase>
+<phrase>
+ <source>extended selection</source>
+ <target>utökad markering</target>
+</phrase>
+<phrase>
+ <source>extended selection list box</source>
+ <target>listruta för utökad markering</target>
+</phrase>
+<phrase>
+ <source>File</source>
+ <target>Arkiv</target>
+ <definition>menu/meny</definition>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>fil</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Sök</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Sök nästa</target>
+</phrase>
+<phrase>
+ <source>Find What</source>
+ <target>Sök efter</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>mapp</target>
+</phrase>
+<phrase>
+ <source>font</source>
+ <target>teckensnitt</target>
+</phrase>
+<phrase>
+ <source>font size</source>
+ <target>teckenstorlek</target>
+</phrase>
+<phrase>
+ <source>font style</source>
+ <target>teckenstil</target>
+</phrase>
+<phrase>
+ <source>function key</source>
+ <target>funktionstangent</target>
+</phrase>
+<phrase>
+ <source>group box</source>
+ <target>gruppruta</target>
+</phrase>
+<phrase>
+ <source>handle</source>
+ <target>handtag</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Hjälp</target>
+</phrase>
+<phrase>
+ <source>Hide</source>
+ <target>Dölj</target>
+</phrase>
+<phrase>
+ <source>hierarchical selection</source>
+ <target>hierarkisk markering</target>
+</phrase>
+<phrase>
+ <source>hold</source>
+ <target>hålla ned</target>
+</phrase>
+<phrase>
+ <source>hot spot</source>
+ <target>aktiv punkt</target>
+</phrase>
+<phrase>
+ <source>hot zone</source>
+ <target>aktiveringszon</target>
+</phrase>
+<phrase>
+ <source>icon</source>
+ <target>ikon</target>
+</phrase>
+<phrase>
+ <source>inactive</source>
+ <target>inaktiv</target>
+</phrase>
+<phrase>
+ <source>inactive window</source>
+ <target>inaktivt fönster</target>
+</phrase>
+<phrase>
+ <source>input focus</source>
+ <target>inmatningsfokus</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Infoga-meny</target>
+</phrase>
+<phrase>
+ <source>Insert Object</source>
+ <target>Infoga objekt</target>
+</phrase>
+<phrase>
+ <source>insertion point</source>
+ <target>insättningspunkt</target>
+</phrase>
+<phrase>
+ <source>italic</source>
+ <target>kursiv</target>
+</phrase>
+<phrase>
+ <source>label</source>
+ <target>titel</target>
+</phrase>
+<phrase>
+ <source>landscape</source>
+ <target>liggande</target>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>länk</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>link</source>
+ <target>länka</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>Link Here</source>
+ <target>Länka hit</target>
+</phrase>
+<phrase>
+ <source>list box</source>
+ <target>listruta</target>
+</phrase>
+<phrase>
+ <source>list view</source>
+ <target>listvy</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>manual link</source>
+ <target>manuell länk</target>
+</phrase>
+<phrase>
+ <source>Maximize</source>
+ <target>Maximera</target>
+</phrase>
+<phrase>
+ <source>maximize button</source>
+ <target>maximeringsknapp</target>
+</phrase>
+<phrase>
+ <source>MDI</source>
+ <target>MDI</target>
+</phrase>
+<phrase>
+ <source>menu</source>
+ <target>meny</target>
+</phrase>
+<phrase>
+ <source>menu bar</source>
+ <target>menyrad</target>
+</phrase>
+<phrase>
+ <source>menu button</source>
+ <target>menyknapp</target>
+</phrase>
+<phrase>
+ <source>menu item</source>
+ <target>menyobjekt</target>
+</phrase>
+<phrase>
+ <source>menu title</source>
+ <target>menytitel</target>
+</phrase>
+<phrase>
+ <source>message box</source>
+ <target>meddelanderuta</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimera</target>
+</phrase>
+<phrase>
+ <source>minimize button</source>
+ <target>minimeringsknapp</target>
+</phrase>
+<phrase>
+ <source>mixed-value</source>
+ <target>blandvärde</target>
+</phrase>
+<phrase>
+ <source>modal</source>
+ <target>modal</target>
+</phrase>
+<phrase>
+ <source>mode</source>
+ <target>läge</target>
+</phrase>
+<phrase>
+ <source>modeless</source>
+ <target>icke-modal</target>
+</phrase>
+<phrase>
+ <source>modifier key</source>
+ <target>ändringstangent</target>
+</phrase>
+<phrase>
+ <source>mouse</source>
+ <target>mus</target>
+</phrase>
+<phrase>
+ <source>Move</source>
+ <target>Flytta</target>
+</phrase>
+<phrase>
+ <source>Move Here</source>
+ <target>Flytta hit</target>
+</phrase>
+<phrase>
+ <source>Multiple Document Interface</source>
+ <target>multiple document interface</target>
+</phrase>
+<phrase>
+ <source>multiple selection list box</source>
+ <target>listruta för multipel markering</target>
+</phrase>
+<phrase>
+ <source>My Computer</source>
+ <target>Den här datorn</target>
+ <definition>icon</definition>
+</phrase>
+<phrase>
+ <source>Network Neighborhood</source>
+ <target>Nätverket</target>
+ <definition>icon</definition>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Ny</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Nytt</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Nästa</target>
+</phrase>
+<phrase>
+ <source>object</source>
+ <target>objekt</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>OLE</source>
+ <target>OLE</target>
+</phrase>
+<phrase>
+ <source>OLE drag and drop</source>
+ <target>dra och släpp (OLE)</target>
+</phrase>
+<phrase>
+ <source>OLE embedded object</source>
+ <target>inbäddat objekt (OLE)</target>
+</phrase>
+<phrase>
+ <source>OLE linked object</source>
+ <target>länkat objekt (OLE)</target>
+</phrase>
+<phrase>
+ <source>OLE nondefault drag and drop</source>
+ <target>utökat drag och släpp (OLE)</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Öppna</target>
+</phrase>
+<phrase>
+ <source>Open With</source>
+ <target>Öppna med</target>
+</phrase>
+<phrase>
+ <source>option button</source>
+ <target>alternativknapp</target>
+</phrase>
+<phrase>
+ <source>option-set</source>
+ <target>valt alternativ</target>
+</phrase>
+<phrase>
+ <source>package</source>
+ <target>paket</target>
+</phrase>
+<phrase>
+ <source>Page Setup</source>
+ <target>Utskriftsformat</target>
+</phrase>
+<phrase>
+ <source>palette window</source>
+ <target>palettfönster</target>
+</phrase>
+<phrase>
+ <source>pane</source>
+ <target>fönsterruta</target>
+</phrase>
+<phrase>
+ <source>parent window</source>
+ <target>moderfönster</target>
+</phrase>
+<phrase>
+ <source>password</source>
+ <target>lösenord</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Klistra in</target>
+</phrase>
+<phrase>
+ <source>Paste Link</source>
+ <target>Klistra in länk</target>
+</phrase>
+<phrase>
+ <source>Paste Shortcut</source>
+ <target>Klistra in genväg</target>
+</phrase>
+<phrase>
+ <source>Paste Special</source>
+ <target>Klistra in special</target>
+</phrase>
+<phrase>
+ <source>path</source>
+ <target>sökväg</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Paus</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Spela upp</target>
+</phrase>
+<phrase>
+ <source>Plug and Play</source>
+ <target>Plug and Play</target>
+</phrase>
+<phrase>
+ <source>point</source>
+ <target>peka</target>
+</phrase>
+<phrase>
+ <source>pointer</source>
+ <target>pekare</target>
+</phrase>
+<phrase>
+ <source>pop-up menu</source>
+ <target>pop up-meny</target>
+</phrase>
+<phrase>
+ <source>pop-up window</source>
+ <target>pop up-fönster</target>
+</phrase>
+<phrase>
+ <source>portrait</source>
+ <target>stående</target>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>håll ned</target>
+ <definition>and hold a mouse button</definition>
+</phrase>
+<phrase>
+ <source>press</source>
+ <target>tryck på</target>
+ <definition>a key</definition>
+</phrase>
+<phrase>
+ <source>primary container</source>
+ <target>primär behållare</target>
+</phrase>
+<phrase>
+ <source>primary window</source>
+ <target>primärt fönster</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Skriv ut</target>
+</phrase>
+<phrase>
+ <source>printer</source>
+ <target>skrivare</target>
+</phrase>
+<phrase>
+ <source>progress indicator</source>
+ <target>förloppsindikator</target>
+ <definition>control</definition>
+</phrase>
+<phrase>
+ <source>project</source>
+ <target>projekt</target>
+</phrase>
+<phrase>
+ <source>Properties</source>
+ <target>Egenskaper</target>
+</phrase>
+<phrase>
+ <source>property inspector</source>
+ <target>egenskapsgranskare</target>
+</phrase>
+<phrase>
+ <source>property page</source>
+ <target>egenskapssida</target>
+</phrase>
+<phrase>
+ <source>property sheet</source>
+ <target>egenskapsförteckning</target>
+</phrase>
+<phrase>
+ <source>property sheet control</source>
+ <target>kontroll i egenskapsförteckning</target>
+</phrase>
+<phrase>
+ <source>Quick View</source>
+ <target>Snabbgranskning</target>
+</phrase>
+<phrase>
+ <source>read-only</source>
+ <target>skrivskydd</target>
+</phrase>
+<phrase>
+ <source>Recycle Bin</source>
+ <target>Papperskorgen</target>
+ <definition>Icon</definition>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Gör om</target>
+</phrase>
+<phrase>
+ <source>region selection</source>
+ <target>områdesmarkering</target>
+</phrase>
+<phrase>
+ <source>registry</source>
+ <target>Registret</target>
+</phrase>
+<phrase>
+ <source>Repeat</source>
+ <target>Upprepa</target>
+</phrase>
+<phrase>
+ <source>Replace</source>
+ <target>Ersätt</target>
+</phrase>
+<phrase>
+ <source>Restore</source>
+ <target>Återställ</target>
+</phrase>
+<phrase>
+ <source>Restore button</source>
+ <target>knappen Återställ</target>
+</phrase>
+<phrase>
+ <source>Resume</source>
+ <target>Fortsätt</target>
+</phrase>
+<phrase>
+ <source>Retry</source>
+ <target>Försök igen</target>
+</phrase>
+<phrase>
+ <source>rich-text box</source>
+ <target>rich text-ruta</target>
+</phrase>
+<phrase>
+ <source>Run</source>
+ <target>Kör</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Spara</target>
+</phrase>
+<phrase>
+ <source>Save as</source>
+ <target>Spara som</target>
+</phrase>
+<phrase>
+ <source>scroll</source>
+ <target>rulla</target>
+</phrase>
+<phrase>
+ <source>scroll arrow</source>
+ <target>rullningspil</target>
+</phrase>
+<phrase>
+ <source>scroll bar</source>
+ <target>rullningslist</target>
+</phrase>
+<phrase>
+ <source>scroll box</source>
+ <target>rullningsruta</target>
+</phrase>
+<phrase>
+ <source>secondary window</source>
+ <target>sekundärt fönster</target>
+</phrase>
+<phrase>
+ <source>select</source>
+ <target>markera</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Markera allt</target>
+</phrase>
+<phrase>
+ <source>selection</source>
+ <target>markering</target>
+</phrase>
+<phrase>
+ <source>selection handle</source>
+ <target>markeringshandtag</target>
+</phrase>
+<phrase>
+ <source>Send To</source>
+ <target>Skicka till</target>
+</phrase>
+<phrase>
+ <source>separator</source>
+ <target>avgränsare</target>
+</phrase>
+<phrase>
+ <source>Settings</source>
+ <target>Inställningar</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>installationsprogram</target>
+</phrase>
+<phrase>
+ <source>Setup</source>
+ <target>Inställningar</target>
+</phrase>
+<phrase>
+ <source>shortcut</source>
+ <target>genväg</target>
+</phrase>
+<phrase>
+ <source>shortcut button</source>
+ <target>genvägsknapp</target>
+</phrase>
+<phrase>
+ <source>shortcut icon</source>
+ <target>genvägsikon</target>
+</phrase>
+<phrase>
+ <source>shortcut key</source>
+ <target>kortkommando</target>
+</phrase>
+<phrase>
+ <source>shortcut key control</source>
+ <target>kortkommandokontroll</target>
+</phrase>
+<phrase>
+ <source>Show</source>
+ <target>Visa</target>
+</phrase>
+<phrase>
+ <source>Shutdown</source>
+ <target>Avsluta</target>
+</phrase>
+<phrase>
+ <source>single selection list box</source>
+ <target>listruta för enkel markering</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Ändra storlek</target>
+</phrase>
+<phrase>
+ <source>Size</source>
+ <target>Storlek</target>
+</phrase>
+<phrase>
+ <source>size grip</source>
+ <target>storleksgrepp</target>
+</phrase>
+<phrase>
+ <source>slider</source>
+ <target>skjutreglage</target>
+</phrase>
+<phrase>
+ <source>spin box</source>
+ <target>rotationsruta</target>
+</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Dela</target>
+</phrase>
+<phrase>
+ <source>split bar</source>
+ <target>delningslist</target>
+</phrase>
+<phrase>
+ <source>split box</source>
+ <target>delningsruta</target>
+</phrase>
+<phrase>
+ <source>Start button</source>
+ <target>startknappen</target>
+</phrase>
+<phrase>
+ <source>StartUp folder</source>
+ <target>mappen Autostart</target>
+</phrase>
+<phrase>
+ <source>status bar</source>
+ <target>statusfält</target>
+</phrase>
+<phrase>
+ <source>Stop</source>
+ <target>Stanna</target>
+</phrase>
+<phrase>
+ <source>tab control</source>
+ <target>flik</target>
+</phrase>
+<phrase>
+ <source>task bar</source>
+ <target>Aktivitetsfältet</target>
+</phrase>
+<phrase>
+ <source>task-oriented Help</source>
+ <target>aktivitetsberoende hjälp</target>
+</phrase>
+<phrase>
+ <source>template</source>
+ <target>mall</target>
+</phrase>
+<phrase>
+ <source>text box</source>
+ <target>textruta</target>
+</phrase>
+<phrase>
+ <source>title bar</source>
+ <target>namnlist</target>
+</phrase>
+<phrase>
+ <source>title text</source>
+ <target>text i namnlist</target>
+</phrase>
+<phrase>
+ <source>toggle key</source>
+ <target>växlingstangent</target>
+</phrase>
+<phrase>
+ <source>toolbar</source>
+ <target>verktygsfält</target>
+</phrase>
+<phrase>
+ <source>tooltip</source>
+ <target>funktionsbeskrivning</target>
+</phrase>
+<phrase>
+ <source>tree view control</source>
+ <target>trädkontroll</target>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>typ</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>type</source>
+ <target>skriva</target>
+ <definition>verb</definition>
+</phrase>
+<phrase>
+ <source>unavailable</source>
+ <target>ej tillgänglig</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Ã…ngra</target>
+</phrase>
+<phrase>
+ <source>Uninstall</source>
+ <target>Avinstallera</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>Visa-meny</target>
+</phrase>
+<phrase>
+ <source>visual editing</source>
+ <target>direktredigering</target>
+</phrase>
+<phrase>
+ <source>well control</source>
+ <target>grafikkontroll</target>
+</phrase>
+<phrase>
+ <source>What&apos;s This?</source>
+ <target>Förklaring</target>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Fönster-meny</target>
+</phrase>
+<phrase>
+ <source>window</source>
+ <target>fönster</target>
+</phrase>
+<phrase>
+ <source>Windows Explorer</source>
+ <target>Utforskaren</target>
+</phrase>
+<phrase>
+ <source>wizard</source>
+ <target>guide</target>
+</phrase>
+<phrase>
+ <source>workbook</source>
+ <target>arbetsbok</target>
+</phrase>
+<phrase>
+ <source>workgroup</source>
+ <target>arbetsgrupp</target>
+</phrase>
+<phrase>
+ <source>workspace</source>
+ <target>arbetsyta</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Ja</target>
+</phrase>
+</QPH>
diff --git a/src/linguist/qdoc.conf b/src/linguist/qdoc.conf
new file mode 100644
index 000000000..31d44d5a5
--- /dev/null
+++ b/src/linguist/qdoc.conf
@@ -0,0 +1,15 @@
+SOURCEDIRS = $QTDIR/tools/linguist/doc
+DOCDIRS = $QTDIR/tools/linguist/doc
+EXAMPLEDIRS = $QTDIR/tools/linguist/tutorial
+OUTPUTDIR = $QTDIR/tools/linguist/doc/html
+BASE = file:$QTDIR/tools/linguist/doc/html/
+COMPANY = Nokia Corporation and/or its subsidiary(-ies)
+PRODUCT = Qt Linguist
+VERSIONSYM = QT_VERSION_STR
+DEFINE = QT_QDOC QT_.*_SUPPORT _WS_.*_
+FALSE = 0 1
+INTERNAL = no
+STYLE = "h3.fn,span.fn { margin-left: 1cm; text-indent: -1cm; }
+a:link { color: #af4f00; text-decoration: none }
+a:visited { color: #8f2f00; text-decoration: none }
+body { background: #ffffff; color: black; }"
diff --git a/src/linguist/shared/abstractproitemvisitor.h b/src/linguist/shared/abstractproitemvisitor.h
new file mode 100644
index 000000000..259aba788
--- /dev/null
+++ b/src/linguist/shared/abstractproitemvisitor.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTPROITEMVISITOR
+#define ABSTRACTPROITEMVISITOR
+
+#include "proitems.h"
+
+QT_BEGIN_NAMESPACE
+
+struct AbstractProItemVisitor
+{
+ virtual ~AbstractProItemVisitor() {}
+
+ virtual ProItem::ProItemReturn visitBeginProBlock(ProBlock *block) = 0;
+ virtual void visitEndProBlock(ProBlock *block) = 0;
+
+ virtual ProItem::ProItemReturn visitProLoopIteration() = 0;
+ virtual void visitProLoopCleanup() = 0;
+
+ virtual void visitBeginProVariable(ProVariable *variable) = 0;
+ virtual void visitEndProVariable(ProVariable *variable) = 0;
+
+ virtual ProItem::ProItemReturn visitBeginProFile(ProFile *value) = 0;
+ virtual ProItem::ProItemReturn visitEndProFile(ProFile *value) = 0;
+
+ virtual void visitProValue(ProValue *value) = 0;
+ virtual ProItem::ProItemReturn visitProFunction(ProFunction *function) = 0;
+ virtual void visitProOperator(ProOperator *function) = 0;
+ virtual void visitProCondition(ProCondition *function) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // ABSTRACTPROITEMVISITOR
+
diff --git a/src/linguist/shared/formats.pri b/src/linguist/shared/formats.pri
new file mode 100644
index 000000000..985f6dbb8
--- /dev/null
+++ b/src/linguist/shared/formats.pri
@@ -0,0 +1,22 @@
+
+# infrastructure
+QT *= xml
+
+INCLUDEPATH *= $$PWD
+
+SOURCES += \
+ $$PWD/numerus.cpp \
+ $$PWD/translator.cpp \
+ $$PWD/translatormessage.cpp
+
+HEADERS += \
+ $$PWD/translator.h \
+ $$PWD/translatormessage.h
+
+# "real" formats readers and writers
+SOURCES += \
+ $$PWD/qm.cpp \
+ $$PWD/qph.cpp \
+ $$PWD/po.cpp \
+ $$PWD/ts.cpp \
+ $$PWD/xliff.cpp
diff --git a/src/linguist/shared/numerus.cpp b/src/linguist/shared/numerus.cpp
new file mode 100644
index 000000000..8fe263baf
--- /dev/null
+++ b/src/linguist/shared/numerus.cpp
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QMap>
+
+#include <private/qtranslator_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const uchar englishStyleRules[] =
+ { Q_EQ, 1 };
+static const uchar frenchStyleRules[] =
+ { Q_LEQ, 1 };
+static const uchar latvianRules[] =
+ { Q_MOD_10 | Q_EQ, 1, Q_AND, Q_MOD_100 | Q_NEQ, 11, Q_NEWRULE,
+ Q_NEQ, 0 };
+static const uchar icelandicRules[] =
+ { Q_MOD_10 | Q_EQ, 1, Q_AND, Q_MOD_100 | Q_NEQ, 11 };
+static const uchar irishStyleRules[] =
+ { Q_EQ, 1, Q_NEWRULE,
+ Q_EQ, 2 };
+static const uchar slovakStyleRules[] =
+ { Q_EQ, 1, Q_NEWRULE,
+ Q_BETWEEN, 2, 4 };
+static const uchar macedonianRules[] =
+ { Q_MOD_10 | Q_EQ, 1, Q_NEWRULE,
+ Q_MOD_10 | Q_EQ, 2 };
+static const uchar lithuanianRules[] =
+ { Q_MOD_10 | Q_EQ, 1, Q_AND, Q_MOD_100 | Q_NEQ, 11, Q_NEWRULE,
+ Q_MOD_10 | Q_NEQ, 0, Q_AND, Q_MOD_100 | Q_NOT_BETWEEN, 10, 19 };
+static const uchar russianStyleRules[] =
+ { Q_MOD_10 | Q_EQ, 1, Q_AND, Q_MOD_100 | Q_NEQ, 11, Q_NEWRULE,
+ Q_MOD_10 | Q_BETWEEN, 2, 4, Q_AND, Q_MOD_100 | Q_NOT_BETWEEN, 10, 19 };
+static const uchar polishRules[] =
+ { Q_EQ, 1, Q_NEWRULE,
+ Q_MOD_10 | Q_BETWEEN, 2, 4, Q_AND, Q_MOD_100 | Q_NOT_BETWEEN, 10, 19 };
+static const uchar romanianRules[] =
+ { Q_EQ, 1, Q_NEWRULE,
+ Q_EQ, 0, Q_OR, Q_MOD_100 | Q_BETWEEN, 1, 19 };
+static const uchar slovenianRules[] =
+ { Q_MOD_100 | Q_EQ, 1, Q_NEWRULE,
+ Q_MOD_100 | Q_EQ, 2, Q_NEWRULE,
+ Q_MOD_100 | Q_BETWEEN, 3, 4 };
+static const uchar malteseRules[] =
+ { Q_EQ, 1, Q_NEWRULE,
+ Q_EQ, 0, Q_OR, Q_MOD_100 | Q_BETWEEN, 1, 10, Q_NEWRULE,
+ Q_MOD_100 | Q_BETWEEN, 11, 19 };
+static const uchar welshRules[] =
+ { Q_EQ, 0, Q_NEWRULE,
+ Q_EQ, 1, Q_NEWRULE,
+ Q_BETWEEN, 2, 5, Q_NEWRULE,
+ Q_EQ, 6 };
+static const uchar arabicRules[] =
+ { Q_EQ, 0, Q_NEWRULE,
+ Q_EQ, 1, Q_NEWRULE,
+ Q_EQ, 2, Q_NEWRULE,
+ Q_MOD_100 | Q_BETWEEN, 3, 10, Q_NEWRULE,
+ Q_MOD_100 | Q_GEQ, 11 };
+static const uchar tagalogRules[] =
+ { Q_LEQ, 1, Q_NEWRULE,
+ Q_MOD_10 | Q_EQ, 4, Q_OR, Q_MOD_10 | Q_EQ, 6, Q_OR, Q_MOD_10 | Q_EQ, 9 };
+static const uchar catalanRules[] =
+ { Q_EQ, 1, Q_NEWRULE,
+ Q_LEAD_1000 | Q_EQ, 11 };
+
+static const char * const japaneseStyleForms[] = { "Universal Form", 0 };
+static const char * const englishStyleForms[] = { "Singular", "Plural", 0 };
+static const char * const frenchStyleForms[] = { "Singular", "Plural", 0 };
+static const char * const icelandicForms[] = { "Singular", "Plural", 0 };
+static const char * const latvianForms[] = { "Singular", "Plural", "Nullar", 0 };
+static const char * const irishStyleForms[] = { "Singular", "Dual", "Plural", 0 };
+static const char * const slovakStyleForms[] = { "Singular", "Paucal", "Plural", 0 };
+static const char * const macedonianForms[] = { "Singular", "Dual", "Plural", 0 };
+static const char * const lithuanianForms[] = { "Singular", "Paucal", "Plural", 0 };
+static const char * const russianStyleForms[] = { "Singular", "Dual", "Plural", 0 };
+static const char * const polishForms[] = { "Singular", "Paucal", "Plural", 0 };
+static const char * const romanianForms[] = { "Singular", "Paucal", "Plural", 0 };
+static const char * const slovenianForms[] = { "Singular", "Dual", "Trial", "Plural", 0 };
+static const char * const malteseForms[] =
+ { "Singular", "Paucal", "Greater Paucal", "Plural", 0 };
+static const char * const welshForms[] =
+ { "Nullar", "Singular", "Dual", "Sexal", "Plural", 0 };
+static const char * const arabicForms[] =
+ { "Nullar", "Singular", "Dual", "Minority Plural", "Plural", "Plural (100-102, ...)", 0 };
+static const char * const tagalogForms[] =
+ { "Singular", "Plural (consonant-ended)", "Plural (vowel-ended)", 0 };
+static const char * const catalanForms[] = { "Singular", "Undecal (11)", "Plural", 0 };
+
+#define EOL QLocale::C
+
+static const QLocale::Language japaneseStyleLanguages[] = {
+ QLocale::Afan,
+ QLocale::Armenian,
+ QLocale::Bhutani,
+ QLocale::Bislama,
+ QLocale::Burmese,
+ QLocale::Chinese,
+ QLocale::FijiLanguage,
+ QLocale::Guarani,
+ QLocale::Hungarian,
+ QLocale::Indonesian,
+ QLocale::Japanese,
+ QLocale::Javanese,
+ QLocale::Korean,
+ QLocale::Malay,
+ QLocale::NauruLanguage,
+ QLocale::Persian,
+ QLocale::Sundanese,
+ QLocale::Thai,
+ QLocale::Tibetan,
+ QLocale::Turkish,
+ QLocale::Vietnamese,
+ QLocale::Yoruba,
+ QLocale::Zhuang,
+ EOL
+};
+
+static const QLocale::Language englishStyleLanguages[] = {
+ QLocale::Abkhazian,
+ QLocale::Afar,
+ QLocale::Afrikaans,
+ QLocale::Albanian,
+ QLocale::Amharic,
+ QLocale::Assamese,
+ QLocale::Aymara,
+ QLocale::Azerbaijani,
+ QLocale::Bashkir,
+ QLocale::Basque,
+ QLocale::Bengali,
+ QLocale::Bihari,
+ // Missing: Bokmal,
+ QLocale::Bulgarian,
+ QLocale::Cambodian,
+ QLocale::Cornish,
+ QLocale::Corsican,
+ QLocale::Danish,
+ QLocale::Dutch,
+ QLocale::English,
+ QLocale::Esperanto,
+ QLocale::Estonian,
+ QLocale::Faroese,
+ QLocale::Finnish,
+ // Missing: Friulian,
+ QLocale::Frisian,
+ QLocale::Galician,
+ QLocale::Georgian,
+ QLocale::German,
+ QLocale::Greek,
+ QLocale::Greenlandic,
+ QLocale::Gujarati,
+ QLocale::Hausa,
+ QLocale::Hebrew,
+ QLocale::Hindi,
+ QLocale::Interlingua,
+ QLocale::Interlingue,
+ QLocale::Italian,
+ QLocale::Kannada,
+ QLocale::Kashmiri,
+ QLocale::Kazakh,
+ QLocale::Kinyarwanda,
+ QLocale::Kirghiz,
+ QLocale::Kurdish,
+ QLocale::Kurundi,
+ QLocale::Laothian,
+ QLocale::Latin,
+ // Missing: Letzeburgesch,
+ QLocale::Lingala,
+ QLocale::Malagasy,
+ QLocale::Malayalam,
+ QLocale::Marathi,
+ QLocale::Mongolian,
+ // Missing: Nahuatl,
+ QLocale::Nepali,
+ // Missing: Northern Sotho,
+ QLocale::Norwegian,
+ QLocale::Nynorsk,
+ QLocale::Occitan,
+ QLocale::Oriya,
+ QLocale::Pashto,
+ QLocale::Portuguese,
+ QLocale::Punjabi,
+ QLocale::Quechua,
+ QLocale::RhaetoRomance,
+ QLocale::Sesotho,
+ QLocale::Setswana,
+ QLocale::Shona,
+ QLocale::Sindhi,
+ QLocale::Singhalese,
+ QLocale::Siswati,
+ QLocale::Somali,
+ QLocale::Spanish,
+ QLocale::Swahili,
+ QLocale::Swedish,
+ QLocale::Tajik,
+ QLocale::Tamil,
+ QLocale::Tatar,
+ QLocale::Telugu,
+ QLocale::TongaLanguage,
+ QLocale::Tsonga,
+ QLocale::Turkmen,
+ QLocale::Twi,
+ QLocale::Uigur,
+ QLocale::Urdu,
+ QLocale::Uzbek,
+ QLocale::Volapuk,
+ QLocale::Wolof,
+ QLocale::Xhosa,
+ QLocale::Yiddish,
+ QLocale::Zulu,
+ EOL
+};
+static const QLocale::Language frenchStyleLanguages[] = {
+ // keep synchronized with frenchStyleCountries
+ QLocale::Breton,
+ QLocale::French,
+ QLocale::Portuguese,
+ // Missing: Filipino,
+ QLocale::Tigrinya,
+ // Missing: Walloon
+ EOL
+};
+static const QLocale::Language latvianLanguage[] = { QLocale::Latvian, EOL };
+static const QLocale::Language icelandicLanguage[] = { QLocale::Icelandic, EOL };
+static const QLocale::Language irishStyleLanguages[] = {
+ QLocale::Divehi,
+ QLocale::Gaelic,
+ QLocale::Inuktitut,
+ QLocale::Inupiak,
+ QLocale::Irish,
+ QLocale::Manx,
+ QLocale::Maori,
+ // Missing: Sami,
+ QLocale::Samoan,
+ QLocale::Sanskrit,
+ EOL
+};
+static const QLocale::Language slovakStyleLanguages[] = { QLocale::Slovak, QLocale::Czech, EOL };
+static const QLocale::Language macedonianLanguage[] = { QLocale::Macedonian, EOL };
+static const QLocale::Language lithuanianLanguage[] = { QLocale::Lithuanian, EOL };
+static const QLocale::Language russianStyleLanguages[] = {
+ QLocale::Bosnian,
+ QLocale::Byelorussian,
+ QLocale::Croatian,
+ QLocale::Russian,
+ QLocale::Serbian,
+ QLocale::SerboCroatian,
+ QLocale::Ukrainian,
+ EOL
+};
+static const QLocale::Language polishLanguage[] = { QLocale::Polish, EOL };
+static const QLocale::Language romanianLanguages[] = {
+ QLocale::Moldavian,
+ QLocale::Romanian,
+ EOL
+};
+static const QLocale::Language slovenianLanguage[] = { QLocale::Slovenian, EOL };
+static const QLocale::Language malteseLanguage[] = { QLocale::Maltese, EOL };
+static const QLocale::Language welshLanguage[] = { QLocale::Welsh, EOL };
+static const QLocale::Language arabicLanguage[] = { QLocale::Arabic, EOL };
+static const QLocale::Language tagalogLanguage[] = { QLocale::Tagalog, EOL };
+static const QLocale::Language catalanLanguage[] = { QLocale::Catalan, EOL };
+
+static const QLocale::Country frenchStyleCountries[] = {
+ // keep synchronized with frenchStyleLanguages
+ QLocale::AnyCountry,
+ QLocale::AnyCountry,
+ QLocale::Brazil,
+ QLocale::AnyCountry
+};
+struct NumerusTableEntry {
+ const uchar *rules;
+ int rulesSize;
+ const char * const *forms;
+ const QLocale::Language *languages;
+ const QLocale::Country *countries;
+ const char * const gettextRules;
+};
+
+static const NumerusTableEntry numerusTable[] = {
+ { 0, 0, japaneseStyleForms, japaneseStyleLanguages, 0, "nplurals=1; plural=0;" },
+ { englishStyleRules, sizeof(englishStyleRules), englishStyleForms, englishStyleLanguages, 0,
+ "nplurals=2; plural=(n != 1);" },
+ { frenchStyleRules, sizeof(frenchStyleRules), frenchStyleForms, frenchStyleLanguages,
+ frenchStyleCountries, "nplurals=2; plural=(n > 1);" },
+ { latvianRules, sizeof(latvianRules), latvianForms, latvianLanguage, 0,
+ "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" },
+ { icelandicRules, sizeof(icelandicRules), icelandicForms, icelandicLanguage, 0,
+ "nplurals=2; plural=(n%10==1 && n%100!=11 ? 0 : 1);" },
+ { irishStyleRules, sizeof(irishStyleRules), irishStyleForms, irishStyleLanguages, 0,
+ "nplurals=3; plural=(n==1 ? 0 : n==2 ? 1 : 2);" },
+ { slovakStyleRules, sizeof(slovakStyleRules), slovakStyleForms, slovakStyleLanguages, 0,
+ "nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);" },
+ { macedonianRules, sizeof(macedonianRules), macedonianForms, macedonianLanguage, 0,
+ "nplurals=3; plural=(n%100==1 ? 0 : n%100==2 ? 1 : 2);" },
+ { lithuanianRules, sizeof(lithuanianRules), lithuanianForms, lithuanianLanguage, 0,
+ "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+ { russianStyleRules, sizeof(russianStyleRules), russianStyleForms, russianStyleLanguages, 0,
+ "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+ { polishRules, sizeof(polishRules), polishForms, polishLanguage, 0,
+ "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+ { romanianRules, sizeof(romanianRules), romanianForms, romanianLanguages, 0,
+ "nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2);" },
+ { slovenianRules, sizeof(slovenianRules), slovenianForms, slovenianLanguage, 0,
+ "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" },
+ { malteseRules, sizeof(malteseRules), malteseForms, malteseLanguage, 0,
+ "nplurals=4; plural=(n==1 ? 0 : (n==0 || (n%100>=1 && n%100<=10)) ? 1 : (n%100>=11 && n%100<=19) ? 2 : 3);" },
+ { welshRules, sizeof(welshRules), welshForms, welshLanguage, 0,
+ "nplurals=5; plural=(n==0 ? 0 : n==1 ? 1 : (n>=2 && n<=5) ? 2 : n==6 ? 3 : 4);" },
+ { arabicRules, sizeof(arabicRules), arabicForms, arabicLanguage, 0,
+ "nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : (n%100>=3 && n%100<=10) ? 3 : n%100>=11 ? 4 : 5);" },
+ { tagalogRules, sizeof(tagalogRules), tagalogForms, tagalogLanguage, 0,
+ "nplurals=3; plural=(n==1 ? 0 : (n%10==4 || n%10==6 || n%10== 9) ? 1 : 2);" },
+ { catalanRules, sizeof(catalanRules), catalanForms, catalanLanguage, 0,
+ "nplurals=3; plural=(n==1 ? 0 : (n==11 || n/1000==11 || n/1000000==11 || n/1000000000==11) ? 1 : 2);" },
+};
+
+static const int NumerusTableSize = sizeof(numerusTable) / sizeof(numerusTable[0]);
+
+// magic number for the file
+static const int MagicLength = 16;
+static const uchar magic[MagicLength] = {
+ 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
+ 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd
+};
+
+bool getNumerusInfo(QLocale::Language language, QLocale::Country country,
+ QByteArray *rules, QStringList *forms, const char **gettextRules)
+{
+ while (true) {
+ for (int i = 0; i < NumerusTableSize; ++i) {
+ const NumerusTableEntry &entry = numerusTable[i];
+ for (int j = 0; entry.languages[j] != EOL; ++j) {
+ if (entry.languages[j] == language
+ && ((!entry.countries && country == QLocale::AnyCountry)
+ || (entry.countries && entry.countries[j] == country))) {
+ if (rules) {
+ *rules = QByteArray::fromRawData(reinterpret_cast<const char *>(entry.rules),
+ entry.rulesSize);
+ }
+ if (gettextRules)
+ *gettextRules = entry.gettextRules;
+ if (forms) {
+ forms->clear();
+ for (int k = 0; entry.forms[k]; ++k)
+ forms->append(QLatin1String(entry.forms[k]));
+ }
+ return true;
+ }
+ }
+ }
+
+ if (country == QLocale::AnyCountry)
+ break;
+ country = QLocale::AnyCountry;
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/po.cpp b/src/linguist/shared/po.cpp
new file mode 100644
index 000000000..c8127b529
--- /dev/null
+++ b/src/linguist/shared/po.cpp
@@ -0,0 +1,902 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QIODevice>
+#include <QtCore/QHash>
+#include <QtCore/QString>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+#include <ctype.h>
+
+// Uncomment if you wish to hard wrap long lines in .po files. Note that this
+// affects only msg strings, not comments.
+//#define HARD_WRAP_LONG_WORDS
+
+QT_BEGIN_NAMESPACE
+
+static const int MAX_LEN = 79;
+
+static QString poEscapedString(const QString &prefix, const QString &keyword,
+ bool noWrap, const QString &ba)
+{
+ QStringList lines;
+ int off = 0;
+ QString res;
+ while (off < ba.length()) {
+ ushort c = ba[off++].unicode();
+ switch (c) {
+ case '\n':
+ res += QLatin1String("\\n");
+ lines.append(res);
+ res.clear();
+ break;
+ case '\r':
+ res += QLatin1String("\\r");
+ break;
+ case '\t':
+ res += QLatin1String("\\t");
+ break;
+ case '\v':
+ res += QLatin1String("\\v");
+ break;
+ case '\a':
+ res += QLatin1String("\\a");
+ break;
+ case '\b':
+ res += QLatin1String("\\b");
+ break;
+ case '\f':
+ res += QLatin1String("\\f");
+ break;
+ case '"':
+ res += QLatin1String("\\\"");
+ break;
+ case '\\':
+ res += QLatin1String("\\\\");
+ break;
+ default:
+ if (c < 32) {
+ res += QLatin1String("\\x");
+ res += QString::number(c, 16);
+ if (off < ba.length() && isxdigit(ba[off].unicode()))
+ res += QLatin1String("\"\"");
+ } else {
+ res += QChar(c);
+ }
+ break;
+ }
+ }
+ if (!res.isEmpty())
+ lines.append(res);
+ if (!lines.isEmpty()) {
+ if (!noWrap) {
+ if (lines.count() != 1 ||
+ lines.first().length() > MAX_LEN - keyword.length() - prefix.length() - 3)
+ {
+ QStringList olines = lines;
+ lines = QStringList(QString());
+ const int maxlen = MAX_LEN - prefix.length() - 2;
+ foreach (const QString &line, olines) {
+ int off = 0;
+ while (off + maxlen < line.length()) {
+ int idx = line.lastIndexOf(QLatin1Char(' '), off + maxlen - 1) + 1;
+ if (idx == off) {
+#ifdef HARD_WRAP_LONG_WORDS
+ // This doesn't seem too nice, but who knows ...
+ idx = off + maxlen;
+#else
+ idx = line.indexOf(QLatin1Char(' '), off + maxlen) + 1;
+ if (!idx)
+ break;
+#endif
+ }
+ lines.append(line.mid(off, idx - off));
+ off = idx;
+ }
+ lines.append(line.mid(off));
+ }
+ }
+ } else if (lines.count() > 1) {
+ lines.prepend(QString());
+ }
+ }
+ return prefix + keyword + QLatin1String(" \"") +
+ lines.join(QLatin1String("\"\n") + prefix + QLatin1Char('"')) +
+ QLatin1String("\"\n");
+}
+
+static QString poEscapedLines(const QString &prefix, bool addSpace, const QStringList &lines)
+{
+ QString out;
+ foreach (const QString &line, lines) {
+ out += prefix;
+ if (addSpace && !line.isEmpty())
+ out += QLatin1Char(' ' );
+ out += line;
+ out += QLatin1Char('\n');
+ }
+ return out;
+}
+
+static QString poEscapedLines(const QString &prefix, bool addSpace, const QString &in0)
+{
+ QString in = in0;
+ if (in.endsWith(QLatin1Char('\n')))
+ in.chop(1);
+ return poEscapedLines(prefix, addSpace, in.split(QLatin1Char('\n')));
+}
+
+static QString poWrappedEscapedLines(const QString &prefix, bool addSpace, const QString &line)
+{
+ const int maxlen = MAX_LEN - prefix.length();
+ QStringList lines;
+ int off = 0;
+ while (off + maxlen < line.length()) {
+ int idx = line.lastIndexOf(QLatin1Char(' '), off + maxlen - 1);
+ if (idx < off) {
+#if 0 //def HARD_WRAP_LONG_WORDS
+ // This cannot work without messing up semantics, so do not even try.
+#else
+ idx = line.indexOf(QLatin1Char(' '), off + maxlen);
+ if (idx < 0)
+ break;
+#endif
+ }
+ lines.append(line.mid(off, idx - off));
+ off = idx + 1;
+ }
+ lines.append(line.mid(off));
+ return poEscapedLines(prefix, addSpace, lines);
+}
+
+struct PoItem
+{
+public:
+ PoItem()
+ : isPlural(false), isFuzzy(false)
+ {}
+
+
+public:
+ QByteArray id;
+ QByteArray context;
+ QByteArray tscomment;
+ QByteArray oldTscomment;
+ QByteArray lineNumber;
+ QByteArray fileName;
+ QByteArray references;
+ QByteArray translatorComments;
+ QByteArray automaticComments;
+ QByteArray msgId;
+ QByteArray oldMsgId;
+ QList<QByteArray> msgStr;
+ bool isPlural;
+ bool isFuzzy;
+ QHash<QString, QString> extra;
+};
+
+
+static bool isTranslationLine(const QByteArray &line)
+{
+ return line.startsWith("#~ msgstr") || line.startsWith("msgstr");
+}
+
+static QByteArray slurpEscapedString(const QList<QByteArray> &lines, int &l,
+ int offset, const QByteArray &prefix, ConversionData &cd)
+{
+ QByteArray msg;
+ int stoff;
+
+ for (; l < lines.size(); ++l) {
+ const QByteArray &line = lines.at(l);
+ if (line.isEmpty() || !line.startsWith(prefix))
+ break;
+ while (isspace(line[offset])) // No length check, as string has no trailing spaces.
+ offset++;
+ if (line[offset] != '"')
+ break;
+ offset++;
+ forever {
+ if (offset == line.length())
+ goto premature_eol;
+ uchar c = line[offset++];
+ if (c == '"') {
+ if (offset == line.length())
+ break;
+ while (isspace(line[offset]))
+ offset++;
+ if (line[offset++] != '"') {
+ cd.appendError(QString::fromLatin1(
+ "PO parsing error: extra characters on line %1.")
+ .arg(l + 1));
+ break;
+ }
+ continue;
+ }
+ if (c == '\\') {
+ if (offset == line.length())
+ goto premature_eol;
+ c = line[offset++];
+ switch (c) {
+ case 'r':
+ msg += '\r'; // Maybe just throw it away?
+ break;
+ case 'n':
+ msg += '\n';
+ break;
+ case 't':
+ msg += '\t';
+ break;
+ case 'v':
+ msg += '\v';
+ break;
+ case 'a':
+ msg += '\a';
+ break;
+ case 'b':
+ msg += '\b';
+ break;
+ case 'f':
+ msg += '\f';
+ break;
+ case '"':
+ msg += '"';
+ break;
+ case '\\':
+ msg += '\\';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ stoff = offset - 1;
+ while ((c = line[offset]) >= '0' && c <= '7')
+ if (++offset == line.length())
+ goto premature_eol;
+ msg += line.mid(stoff, offset - stoff).toUInt(0, 8);
+ break;
+ case 'x':
+ stoff = offset;
+ while (isxdigit(line[offset]))
+ if (++offset == line.length())
+ goto premature_eol;
+ msg += line.mid(stoff, offset - stoff).toUInt(0, 16);
+ break;
+ default:
+ cd.appendError(QString::fromLatin1(
+ "PO parsing error: invalid escape '\\%1' (line %2).")
+ .arg(QChar((uint)c)).arg(l + 1));
+ msg += '\\';
+ msg += c;
+ break;
+ }
+ } else {
+ msg += c;
+ }
+ }
+ offset = prefix.size();
+ }
+ --l;
+ return msg;
+
+premature_eol:
+ cd.appendError(QString::fromLatin1(
+ "PO parsing error: premature end of line %1.").arg(l + 1));
+ return QByteArray();
+}
+
+static void slurpComment(QByteArray &msg, const QList<QByteArray> &lines, int & l)
+{
+ QByteArray prefix = lines.at(l);
+ for (int i = 1; ; i++) {
+ if (prefix.at(i) != ' ') {
+ prefix.truncate(i);
+ break;
+ }
+ }
+ for (; l < lines.size(); ++l) {
+ const QByteArray &line = lines.at(l);
+ if (line.startsWith(prefix))
+ msg += line.mid(prefix.size());
+ else if (line != "#")
+ break;
+ msg += '\n';
+ }
+ --l;
+}
+
+static void splitContext(QByteArray *comment, QByteArray *context)
+{
+ char *data = comment->data();
+ int len = comment->size();
+ int sep = -1, j = 0;
+
+ for (int i = 0; i < len; i++, j++) {
+ if (data[i] == '~' && i + 1 < len)
+ i++;
+ else if (data[i] == '|')
+ sep = j;
+ data[j] = data[i];
+ }
+ if (sep >= 0) {
+ QByteArray tmp = comment->mid(sep + 1, j - sep - 1);
+ comment->truncate(sep);
+ *context = *comment;
+ *comment = tmp;
+ } else {
+ comment->truncate(j);
+ }
+}
+
+static QString makePoHeader(const QString &str)
+{
+ return QLatin1String("po-header-") + str.toLower().replace(QLatin1Char('-'), QLatin1Char('_'));
+}
+
+static QByteArray QByteArrayList_join(const QList<QByteArray> &that, char sep)
+{
+ int totalLength = 0;
+ const int size = that.size();
+
+ for (int i = 0; i < size; ++i)
+ totalLength += that.at(i).size();
+
+ if (size > 0)
+ totalLength += size - 1;
+
+ QByteArray res;
+ if (totalLength == 0)
+ return res;
+ res.reserve(totalLength);
+ for (int i = 0; i < that.size(); ++i) {
+ if (i)
+ res += sep;
+ res += that.at(i);
+ }
+ return res;
+}
+
+bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ QTextCodec *codec = QTextCodec::codecForName(
+ cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource);
+ bool error = false;
+
+ // format of a .po file entry:
+ // white-space
+ // # translator-comments
+ // #. automatic-comments
+ // #: reference...
+ // #, flag...
+ // #~ msgctxt, msgid*, msgstr - used for obsoleted messages
+ // #| msgctxt, msgid* previous untranslated-string - for fuzzy message
+ // msgctx string-context
+ // msgid untranslated-string
+ // -- For singular:
+ // msgstr translated-string
+ // -- For plural:
+ // msgid_plural untranslated-string-plural
+ // msgstr[0] translated-string
+ // ...
+
+ // we need line based lookahead below.
+ QList<QByteArray> lines;
+ while (!dev.atEnd())
+ lines.append(dev.readLine().trimmed());
+ lines.append(QByteArray());
+
+ int l = 0, lastCmtLine = -1;
+ bool qtContexts = false;
+ PoItem item;
+ for (; l != lines.size(); ++l) {
+ QByteArray line = lines.at(l);
+ if (line.isEmpty())
+ continue;
+ if (isTranslationLine(line)) {
+ bool isObsolete = line.startsWith("#~ msgstr");
+ const QByteArray prefix = isObsolete ? "#~ " : "";
+ while (true) {
+ int idx = line.indexOf(' ', prefix.length());
+ QByteArray str = slurpEscapedString(lines, l, idx, prefix, cd);
+ item.msgStr.append(str);
+ if (l + 1 >= lines.size() || !isTranslationLine(lines.at(l + 1)))
+ break;
+ ++l;
+ line = lines.at(l);
+ }
+ if (item.msgId.isEmpty()) {
+ QHash<QString, QByteArray> extras;
+ QList<QByteArray> hdrOrder;
+ QByteArray pluralForms;
+ foreach (const QByteArray &hdr, item.msgStr.first().split('\n')) {
+ if (hdr.isEmpty())
+ continue;
+ int idx = hdr.indexOf(':');
+ if (idx < 0) {
+ cd.appendError(QString::fromLatin1("Unexpected PO header format '%1'")
+ .arg(QString::fromLatin1(hdr)));
+ error = true;
+ break;
+ }
+ QByteArray hdrName = hdr.left(idx).trimmed();
+ QByteArray hdrValue = hdr.mid(idx + 1).trimmed();
+ hdrOrder << hdrName;
+ if (hdrName == "X-Language") {
+ translator.setLanguageCode(QString::fromLatin1(hdrValue));
+ } else if (hdrName == "X-Source-Language") {
+ translator.setSourceLanguageCode(QString::fromLatin1(hdrValue));
+ } else if (hdrName == "X-Qt-Contexts") {
+ qtContexts = (hdrValue == "true");
+ } else if (hdrName == "Plural-Forms") {
+ pluralForms = hdrValue;
+ } else if (hdrName == "MIME-Version") {
+ // just assume it is 1.0
+ } else if (hdrName == "Content-Type") {
+ if (cd.m_codecForSource.isEmpty()) {
+ if (!hdrValue.startsWith("text/plain; charset=")) {
+ cd.appendError(QString::fromLatin1("Unexpected Content-Type header '%1'")
+ .arg(QString::fromLatin1(hdrValue)));
+ error = true;
+ // This will avoid a flood of conversion errors.
+ codec = QTextCodec::codecForName("latin1");
+ } else {
+ QByteArray cod = hdrValue.mid(20);
+ QTextCodec *cdc = QTextCodec::codecForName(cod);
+ if (!cdc) {
+ cd.appendError(QString::fromLatin1("Unsupported codec '%1'")
+ .arg(QString::fromLatin1(cod)));
+ error = true;
+ // This will avoid a flood of conversion errors.
+ codec = QTextCodec::codecForName("latin1");
+ } else {
+ codec = cdc;
+ }
+ }
+ }
+ } else if (hdrName == "Content-Transfer-Encoding") {
+ if (hdrValue != "8bit") {
+ cd.appendError(QString::fromLatin1("Unexpected Content-Transfer-Encoding '%1'")
+ .arg(QString::fromLatin1(hdrValue)));
+ return false;
+ }
+ } else if (hdrName == "X-Virgin-Header") {
+ // legacy
+ } else {
+ extras[makePoHeader(QString::fromLatin1(hdrName))] = hdrValue;
+ }
+ }
+ if (!pluralForms.isEmpty()) {
+ if (translator.languageCode().isEmpty()) {
+ extras[makePoHeader(QLatin1String("Plural-Forms"))] = pluralForms;
+ } else {
+ // FIXME: have fun with making a consistency check ...
+ }
+ }
+ // Eliminate the field if only headers we added are present in standard order.
+ // Keep in sync with savePO
+ static const char * const dfltHdrs[] = {
+ "MIME-Version", "Content-Type", "Content-Transfer-Encoding",
+ "Plural-Forms", "X-Language", "X-Source-Language", "X-Qt-Contexts"
+ };
+ uint cdh = 0;
+ for (int cho = 0; cho < hdrOrder.length(); cho++) {
+ for (;; cdh++) {
+ if (cdh == sizeof(dfltHdrs)/sizeof(dfltHdrs[0])) {
+ extras[QLatin1String("po-headers")] =
+ QByteArrayList_join(hdrOrder, ',');
+ goto doneho;
+ }
+ if (hdrOrder.at(cho) == dfltHdrs[cdh]) {
+ cdh++;
+ break;
+ }
+ }
+ }
+ doneho:
+ if (lastCmtLine != -1)
+ extras[QLatin1String("po-header_comment")] =
+ QByteArrayList_join(lines.mid(0, lastCmtLine + 1), '\n');
+ for (QHash<QString, QByteArray>::ConstIterator it = extras.constBegin(),
+ end = extras.constEnd();
+ it != end; ++it)
+ translator.setExtra(it.key(), codec->toUnicode(it.value()));
+ item = PoItem();
+ continue;
+ }
+ // build translator message
+ TranslatorMessage msg;
+ msg.setContext(codec->toUnicode(item.context));
+ if (!item.references.isEmpty()) {
+ QString xrefs;
+ foreach (const QString &ref,
+ codec->toUnicode(item.references).split(
+ QRegExp(QLatin1String("\\s")), QString::SkipEmptyParts)) {
+ int pos = ref.indexOf(QLatin1Char(':'));
+ int lpos = ref.lastIndexOf(QLatin1Char(':'));
+ if (pos != -1 && pos == lpos) {
+ bool ok;
+ int lno = ref.mid(pos + 1).toInt(&ok);
+ if (ok) {
+ msg.addReference(ref.left(pos), lno);
+ continue;
+ }
+ }
+ if (!xrefs.isEmpty())
+ xrefs += QLatin1Char(' ');
+ xrefs += ref;
+ }
+ if (!xrefs.isEmpty())
+ item.extra[QLatin1String("po-references")] = xrefs;
+ }
+ msg.setId(codec->toUnicode(item.id));
+ msg.setSourceText(codec->toUnicode(item.msgId));
+ msg.setOldSourceText(codec->toUnicode(item.oldMsgId));
+ msg.setComment(codec->toUnicode(item.tscomment));
+ msg.setOldComment(codec->toUnicode(item.oldTscomment));
+ msg.setExtraComment(codec->toUnicode(item.automaticComments));
+ msg.setTranslatorComment(codec->toUnicode(item.translatorComments));
+ msg.setPlural(item.isPlural || item.msgStr.size() > 1);
+ QStringList translations;
+ foreach (const QByteArray &bstr, item.msgStr) {
+ QString str = codec->toUnicode(bstr);
+ str.replace(QChar(Translator::TextVariantSeparator),
+ QChar(Translator::BinaryVariantSeparator));
+ translations << str;
+ }
+ msg.setTranslations(translations);
+ if (isObsolete)
+ msg.setType(TranslatorMessage::Obsolete);
+ else if (item.isFuzzy || (!msg.sourceText().isEmpty() && !msg.isTranslated()))
+ msg.setType(TranslatorMessage::Unfinished);
+ else
+ msg.setType(TranslatorMessage::Finished);
+ msg.setExtras(item.extra);
+
+ //qDebug() << "WRITE: " << context;
+ //qDebug() << "SOURCE: " << msg.sourceText();
+ //qDebug() << flags << msg.m_extra;
+ translator.append(msg);
+ item = PoItem();
+ } else if (line.startsWith('#')) {
+ switch (line.size() < 2 ? 0 : line.at(1)) {
+ case ':':
+ item.references += line.mid(3);
+ item.references += '\n';
+ break;
+ case ',': {
+ QStringList flags =
+ QString::fromLatin1(line.mid(2)).split(
+ QRegExp(QLatin1String("[, ]")), QString::SkipEmptyParts);
+ if (flags.removeOne(QLatin1String("fuzzy")))
+ item.isFuzzy = true;
+ flags.removeOne(QLatin1String("qt-format"));
+ TranslatorMessage::ExtraData::const_iterator it =
+ item.extra.find(QLatin1String("po-flags"));
+ if (it != item.extra.end())
+ flags.prepend(*it);
+ if (!flags.isEmpty())
+ item.extra[QLatin1String("po-flags")] = flags.join(QLatin1String(", "));
+ break;
+ }
+ case 0:
+ item.translatorComments += '\n';
+ break;
+ case ' ':
+ slurpComment(item.translatorComments, lines, l);
+ break;
+ case '.':
+ if (line.startsWith("#. ts-context ")) { // legacy
+ item.context = line.mid(14);
+ } else if (line.startsWith("#. ts-id ")) {
+ item.id = line.mid(9);
+ } else {
+ item.automaticComments += line.mid(3);
+ item.automaticComments += '\n';
+ }
+ break;
+ case '|':
+ if (line.startsWith("#| msgid ")) {
+ item.oldMsgId = slurpEscapedString(lines, l, 9, "#| ", cd);
+ } else if (line.startsWith("#| msgid_plural ")) {
+ QByteArray extra = slurpEscapedString(lines, l, 16, "#| ", cd);
+ if (extra != item.oldMsgId)
+ item.extra[QLatin1String("po-old_msgid_plural")] =
+ codec->toUnicode(extra);
+ } else if (line.startsWith("#| msgctxt ")) {
+ item.oldTscomment = slurpEscapedString(lines, l, 11, "#| ", cd);
+ if (qtContexts)
+ splitContext(&item.oldTscomment, &item.context);
+ } else {
+ cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
+ .arg(l + 1).arg(codec->toUnicode(lines[l])));
+ error = true;
+ }
+ break;
+ case '~':
+ if (line.startsWith("#~ msgid ")) {
+ item.msgId = slurpEscapedString(lines, l, 9, "#~ ", cd);
+ } else if (line.startsWith("#~ msgid_plural ")) {
+ QByteArray extra = slurpEscapedString(lines, l, 16, "#~ ", cd);
+ if (extra != item.msgId)
+ item.extra[QLatin1String("po-msgid_plural")] =
+ codec->toUnicode(extra);
+ item.isPlural = true;
+ } else if (line.startsWith("#~ msgctxt ")) {
+ item.tscomment = slurpEscapedString(lines, l, 11, "#~ ", cd);
+ if (qtContexts)
+ splitContext(&item.tscomment, &item.context);
+ } else {
+ cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
+ .arg(l + 1).arg(codec->toUnicode(lines[l])));
+ error = true;
+ }
+ break;
+ default:
+ cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
+ .arg(l + 1).arg(codec->toUnicode(lines[l])));
+ error = true;
+ break;
+ }
+ lastCmtLine = l;
+ } else if (line.startsWith("msgctxt ")) {
+ item.tscomment = slurpEscapedString(lines, l, 8, QByteArray(), cd);
+ if (qtContexts)
+ splitContext(&item.tscomment, &item.context);
+ } else if (line.startsWith("msgid ")) {
+ item.msgId = slurpEscapedString(lines, l, 6, QByteArray(), cd);
+ } else if (line.startsWith("msgid_plural ")) {
+ QByteArray extra = slurpEscapedString(lines, l, 13, QByteArray(), cd);
+ if (extra != item.msgId)
+ item.extra[QLatin1String("po-msgid_plural")] = codec->toUnicode(extra);
+ item.isPlural = true;
+ } else {
+ cd.appendError(QString(QLatin1String("PO-format error in line %1: '%2'"))
+ .arg(l + 1).arg(codec->toUnicode(lines[l])));
+ error = true;
+ }
+ }
+ return !error && cd.errors().isEmpty();
+}
+
+static void addPoHeader(Translator::ExtraData &headers, QStringList &hdrOrder,
+ const char *name, const QString &value)
+{
+ QString qName = QLatin1String(name);
+ if (!hdrOrder.contains(qName))
+ hdrOrder << qName;
+ headers[makePoHeader(qName)] = value;
+}
+
+static QString escapeComment(const QString &in, bool escape)
+{
+ QString out = in;
+ if (escape) {
+ out.replace(QLatin1Char('~'), QLatin1String("~~"));
+ out.replace(QLatin1Char('|'), QLatin1String("~|"));
+ }
+ return out;
+}
+
+bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ QString str_format = QLatin1String("-format");
+
+ bool ok = true;
+ QTextStream out(&dev);
+ out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec);
+
+ bool qtContexts = false;
+ foreach (const TranslatorMessage &msg, translator.messages())
+ if (!msg.context().isEmpty()) {
+ qtContexts = true;
+ break;
+ }
+
+ QString cmt = translator.extra(QLatin1String("po-header_comment"));
+ if (!cmt.isEmpty())
+ out << cmt << '\n';
+ out << "msgid \"\"\n";
+ Translator::ExtraData headers = translator.extras();
+ QStringList hdrOrder = translator.extra(QLatin1String("po-headers")).split(
+ QLatin1Char(','), QString::SkipEmptyParts);
+ // Keep in sync with loadPO
+ addPoHeader(headers, hdrOrder, "MIME-Version", QLatin1String("1.0"));
+ addPoHeader(headers, hdrOrder, "Content-Type",
+ QLatin1String("text/plain; charset=" + out.codec()->name()));
+ addPoHeader(headers, hdrOrder, "Content-Transfer-Encoding", QLatin1String("8bit"));
+ if (!translator.languageCode().isEmpty()) {
+ QLocale::Language l;
+ QLocale::Country c;
+ Translator::languageAndCountry(translator.languageCode(), &l, &c);
+ const char *gettextRules;
+ if (getNumerusInfo(l, c, 0, 0, &gettextRules))
+ addPoHeader(headers, hdrOrder, "Plural-Forms", QLatin1String(gettextRules));
+ addPoHeader(headers, hdrOrder, "X-Language", translator.languageCode());
+ }
+ if (!translator.sourceLanguageCode().isEmpty())
+ addPoHeader(headers, hdrOrder, "X-Source-Language", translator.sourceLanguageCode());
+ if (qtContexts)
+ addPoHeader(headers, hdrOrder, "X-Qt-Contexts", QLatin1String("true"));
+ QString hdrStr;
+ foreach (const QString &hdr, hdrOrder) {
+ hdrStr += hdr;
+ hdrStr += QLatin1String(": ");
+ hdrStr += headers.value(makePoHeader(hdr));
+ hdrStr += QLatin1Char('\n');
+ }
+ out << poEscapedString(QString(), QString::fromLatin1("msgstr"), true, hdrStr);
+
+ foreach (const TranslatorMessage &msg, translator.messages()) {
+ out << endl;
+
+ if (!msg.translatorComment().isEmpty())
+ out << poEscapedLines(QLatin1String("#"), true, msg.translatorComment());
+
+ if (!msg.extraComment().isEmpty())
+ out << poEscapedLines(QLatin1String("#."), true, msg.extraComment());
+
+ if (!msg.id().isEmpty())
+ out << QLatin1String("#. ts-id ") << msg.id() << '\n';
+
+ QString xrefs = msg.extra(QLatin1String("po-references"));
+ if (!msg.fileName().isEmpty() || !xrefs.isEmpty()) {
+ QStringList refs;
+ foreach (const TranslatorMessage::Reference &ref, msg.allReferences())
+ refs.append(QString(QLatin1String("%2:%1"))
+ .arg(ref.lineNumber()).arg(ref.fileName()));
+ if (!xrefs.isEmpty())
+ refs << xrefs;
+ out << poWrappedEscapedLines(QLatin1String("#:"), true, refs.join(QLatin1String(" ")));
+ }
+
+ bool noWrap = false;
+ bool skipFormat = false;
+ QStringList flags;
+ if (msg.type() == TranslatorMessage::Unfinished && msg.isTranslated())
+ flags.append(QLatin1String("fuzzy"));
+ TranslatorMessage::ExtraData::const_iterator itr =
+ msg.extras().find(QLatin1String("po-flags"));
+ if (itr != msg.extras().end()) {
+ QStringList atoms = itr->split(QLatin1String(", "));
+ foreach (const QString &atom, atoms)
+ if (atom.endsWith(str_format)) {
+ skipFormat = true;
+ break;
+ }
+ if (atoms.contains(QLatin1String("no-wrap")))
+ noWrap = true;
+ flags.append(*itr);
+ }
+ if (!skipFormat) {
+ QString source = msg.sourceText();
+ // This is fuzzy logic, as we don't know whether the string is
+ // actually used with QString::arg().
+ for (int off = 0; (off = source.indexOf(QLatin1Char('%'), off)) >= 0; ) {
+ if (++off >= source.length())
+ break;
+ if (source.at(off) == QLatin1Char('n') || source.at(off).isDigit()) {
+ flags.append(QLatin1String("qt-format"));
+ break;
+ }
+ }
+ }
+ if (!flags.isEmpty())
+ out << "#, " << flags.join(QLatin1String(", ")) << '\n';
+
+ QString prefix = QLatin1String("#| ");
+ if (!msg.oldComment().isEmpty())
+ out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
+ escapeComment(msg.oldComment(), qtContexts));
+ if (!msg.oldSourceText().isEmpty())
+ out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.oldSourceText());
+ QString plural = msg.extra(QLatin1String("po-old_msgid_plural"));
+ if (!plural.isEmpty())
+ out << poEscapedString(prefix, QLatin1String("msgid_plural"), noWrap, plural);
+ prefix = QLatin1String((msg.type() == TranslatorMessage::Obsolete) ? "#~ " : "");
+ if (!msg.context().isEmpty())
+ out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
+ escapeComment(msg.context(), true) + QLatin1Char('|')
+ + escapeComment(msg.comment(), true));
+ else if (!msg.comment().isEmpty())
+ out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
+ escapeComment(msg.comment(), qtContexts));
+ out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.sourceText());
+ if (!msg.isPlural()) {
+ QString transl = msg.translation();
+ transl.replace(QChar(Translator::BinaryVariantSeparator),
+ QChar(Translator::TextVariantSeparator));
+ out << poEscapedString(prefix, QLatin1String("msgstr"), noWrap, transl);
+ } else {
+ QString plural = msg.extra(QLatin1String("po-msgid_plural"));
+ if (plural.isEmpty())
+ plural = msg.sourceText();
+ out << poEscapedString(prefix, QLatin1String("msgid_plural"), noWrap, plural);
+ const QStringList &translations = msg.translations();
+ for (int i = 0; i != translations.size(); ++i) {
+ QString str = translations.at(i);
+ str.replace(QChar(Translator::BinaryVariantSeparator),
+ QChar(Translator::TextVariantSeparator));
+ out << poEscapedString(prefix, QString::fromLatin1("msgstr[%1]").arg(i), noWrap,
+ str);
+ }
+ }
+ }
+ return ok;
+}
+
+static bool savePOT(const Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ Translator ttor = translator;
+ ttor.dropTranslations();
+ return savePO(ttor, dev, cd);
+}
+
+int initPO()
+{
+ Translator::FileFormat format;
+ format.extension = QLatin1String("po");
+ format.description = QObject::tr("GNU Gettext localization files");
+ format.loader = &loadPO;
+ format.saver = &savePO;
+ format.fileType = Translator::FileFormat::TranslationSource;
+ format.priority = 1;
+ Translator::registerFileFormat(format);
+ format.extension = QLatin1String("pot");
+ format.description = QObject::tr("GNU Gettext localization template files");
+ format.loader = &loadPO;
+ format.saver = &savePOT;
+ format.fileType = Translator::FileFormat::TranslationSource;
+ format.priority = -1;
+ Translator::registerFileFormat(format);
+ return 1;
+}
+
+Q_CONSTRUCTOR_FUNCTION(initPO)
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/profileevaluator.cpp b/src/linguist/shared/profileevaluator.cpp
new file mode 100644
index 000000000..94e66745b
--- /dev/null
+++ b/src/linguist/shared/profileevaluator.cpp
@@ -0,0 +1,2627 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "profileevaluator.h"
+#include "proparserutils.h"
+#include "proitems.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QDateTime>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QList>
+#include <QtCore/QRegExp>
+#include <QtCore/QSet>
+#include <QtCore/QStack>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+
+#ifdef Q_OS_UNIX
+#include <unistd.h>
+#include <sys/utsname.h>
+#else
+#include <Windows.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef Q_OS_WIN32
+#define QT_POPEN _popen
+#define QT_PCLOSE _pclose
+#else
+#define QT_POPEN popen
+#define QT_PCLOSE pclose
+#endif
+
+QT_BEGIN_NAMESPACE
+
+///////////////////////////////////////////////////////////////////////
+//
+// Option
+//
+///////////////////////////////////////////////////////////////////////
+
+QString
+Option::fixString(QString string, uchar flags)
+{
+ // XXX Ripped out caching, so this will be slow. Should not matter for current uses.
+
+ //fix the environment variables
+ if (flags & Option::FixEnvVars) {
+ int rep;
+ QRegExp reg_variableName(QLatin1String("\\$\\(.*\\)"));
+ reg_variableName.setMinimal(true);
+ while ((rep = reg_variableName.indexIn(string)) != -1)
+ string.replace(rep, reg_variableName.matchedLength(),
+ QString::fromLocal8Bit(qgetenv(string.mid(rep + 2, reg_variableName.matchedLength() - 3).toLatin1().constData()).constData()));
+ }
+
+ //canonicalize it (and treat as a path)
+ if (flags & Option::FixPathCanonicalize) {
+#if 0
+ string = QFileInfo(string).canonicalFilePath();
+#endif
+ string = QDir::cleanPath(string);
+ }
+
+ if (string.length() > 2 && string[0].isLetter() && string[1] == QLatin1Char(':'))
+ string[0] = string[0].toLower();
+
+ //fix separators
+ Q_ASSERT(!((flags & Option::FixPathToLocalSeparators) && (flags & Option::FixPathToTargetSeparators)));
+ if (flags & Option::FixPathToLocalSeparators) {
+#if defined(Q_OS_WIN32)
+ string = string.replace(QLatin1Char('/'), QLatin1Char('\\'));
+#else
+ string = string.replace(QLatin1Char('\\'), QLatin1Char('/'));
+#endif
+ } else if (flags & Option::FixPathToTargetSeparators) {
+ string = string.replace(QLatin1Char('/'), Option::dir_sep)
+ .replace(QLatin1Char('\\'), Option::dir_sep);
+ }
+
+ if ((string.startsWith(QLatin1Char('"')) && string.endsWith(QLatin1Char('"'))) ||
+ (string.startsWith(QLatin1Char('\'')) && string.endsWith(QLatin1Char('\''))))
+ string = string.mid(1, string.length() - 2);
+
+ return string;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// ProFileEvaluator::Private
+//
+///////////////////////////////////////////////////////////////////////
+
+class ProFileEvaluator::Private : public AbstractProItemVisitor
+{
+public:
+ Private(ProFileEvaluator *q_);
+
+ ProFileEvaluator *q;
+ int m_lineNo; // Error reporting
+ bool m_verbose;
+
+ /////////////// Reading pro file
+
+ bool read(ProFile *pro);
+
+ ProBlock *currentBlock();
+ void updateItem();
+ bool parseLine(const QString &line);
+ void insertVariable(const QString &line, int *i);
+ void insertOperator(const char op);
+ void insertComment(const QString &comment);
+ void enterScope(bool multiLine);
+ void leaveScope();
+ void finalizeBlock();
+
+ QStack<ProBlock *> m_blockstack;
+ ProBlock *m_block;
+
+ ProItem *m_commentItem;
+ QString m_proitem;
+ QString m_pendingComment;
+ bool m_syntaxError;
+ bool m_contNextLine;
+ bool m_inQuote;
+ int m_parens;
+
+ /////////////// Evaluating pro file contents
+
+ // implementation of AbstractProItemVisitor
+ ProItem::ProItemReturn visitBeginProBlock(ProBlock *block);
+ void visitEndProBlock(ProBlock *block);
+ ProItem::ProItemReturn visitProLoopIteration();
+ void visitProLoopCleanup();
+ void visitBeginProVariable(ProVariable *variable);
+ void visitEndProVariable(ProVariable *variable);
+ ProItem::ProItemReturn visitBeginProFile(ProFile *value);
+ ProItem::ProItemReturn visitEndProFile(ProFile *value);
+ void visitProValue(ProValue *value);
+ ProItem::ProItemReturn visitProFunction(ProFunction *function);
+ void visitProOperator(ProOperator *oper);
+ void visitProCondition(ProCondition *condition);
+
+ QStringList valuesDirect(const QString &variableName) const { return m_valuemap[variableName]; }
+ QStringList values(const QString &variableName) const;
+ QStringList values(const QString &variableName, const ProFile *pro) const;
+ QStringList values(const QString &variableName, const QHash<QString, QStringList> &place,
+ const ProFile *pro) const;
+ QString propertyValue(const QString &val) const;
+
+ bool isActiveConfig(const QString &config, bool regex = false);
+ QStringList expandVariableReferences(const QString &value);
+ void doVariableReplace(QString *str);
+ QStringList evaluateExpandFunction(const QString &function, const QString &arguments);
+ QString format(const char *format) const;
+
+ QString currentFileName() const;
+ QString currentDirectory() const;
+ ProFile *currentProFile() const;
+
+ ProItem::ProItemReturn evaluateConditionalFunction(const QString &function, const QString &arguments);
+ bool evaluateFile(const QString &fileName);
+ bool evaluateFeatureFile(const QString &fileName);
+
+ static inline ProItem::ProItemReturn returnBool(bool b)
+ { return b ? ProItem::ReturnTrue : ProItem::ReturnFalse; }
+
+ QStringList evaluateFunction(ProBlock *funcPtr, const QStringList &argumentsList, bool *ok);
+
+ QStringList qmakeFeaturePaths();
+
+ struct State {
+ bool condition;
+ bool prevCondition;
+ } m_sts;
+ bool m_invertNext; // Short-lived, so not in State
+ int m_skipLevel;
+ bool m_cumulative;
+ bool m_isFirstVariableValue;
+ QString m_lastVarName;
+ ProVariable::VariableOperator m_variableOperator;
+ QString m_origfile;
+ QString m_oldPath; // To restore the current path to the path
+ QStack<ProFile*> m_profileStack; // To handle 'include(a.pri), so we can track back to 'a.pro' when finished with 'a.pri'
+ struct ProLoop {
+ QString variable;
+ QStringList oldVarVal;
+ QStringList list;
+ int index;
+ bool infinite;
+ };
+ QStack<ProLoop> m_loopStack;
+
+ // we need the following two variables for handling
+ // CONFIG = foo bar $$CONFIG
+ QHash<QString, QStringList> m_tempValuemap; // used while evaluating (variable operator value1 value2 ...)
+ QHash<const ProFile*, QHash<QString, QStringList> > m_tempFilevaluemap; // used while evaluating (variable operator value1 value2 ...)
+
+ QHash<QString, QStringList> m_valuemap; // VariableName must be us-ascii, the content however can be non-us-ascii.
+ QHash<const ProFile*, QHash<QString, QStringList> > m_filevaluemap; // Variables per include file
+ QHash<QString, QString> m_properties;
+ QString m_outputDir;
+
+ bool m_definingTest;
+ QString m_definingFunc;
+ QHash<QString, ProBlock *> m_testFunctions;
+ QHash<QString, ProBlock *> m_replaceFunctions;
+ QStringList m_returnValue;
+ QStack<QHash<QString, QStringList> > m_valuemapStack;
+ QStack<QHash<const ProFile*, QHash<QString, QStringList> > > m_filevaluemapStack;
+
+ int m_prevLineNo; // Checking whether we're assigning the same TARGET
+ ProFile *m_prevProFile; // See m_prevLineNo
+};
+
+Q_DECLARE_TYPEINFO(ProFileEvaluator::Private::State, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(ProFileEvaluator::Private::ProLoop, Q_MOVABLE_TYPE);
+
+ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
+ : q(q_)
+{
+ // Global parser state
+ m_prevLineNo = 0;
+ m_prevProFile = 0;
+
+ // Configuration, more or less
+ m_verbose = true;
+ m_cumulative = true;
+
+ // Evaluator state
+ m_sts.condition = false;
+ m_sts.prevCondition = false;
+ m_invertNext = false;
+ m_skipLevel = 0;
+ m_isFirstVariableValue = true;
+ m_definingFunc.clear();
+}
+
+bool ProFileEvaluator::Private::read(ProFile *pro)
+{
+ QFile file(pro->fileName());
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ q->errorMessage(format("%1 not readable.").arg(pro->fileName()));
+ return false;
+ }
+
+ // Parser state
+ m_block = 0;
+ m_commentItem = 0;
+ m_inQuote = false;
+ m_parens = 0;
+ m_contNextLine = false;
+ m_syntaxError = false;
+ m_lineNo = 1;
+ m_blockstack.clear();
+ m_blockstack.push(pro);
+
+ QTextStream ts(&file);
+ while (!ts.atEnd()) {
+ QString line = ts.readLine();
+ if (!parseLine(line)) {
+ q->errorMessage(format(".pro parse failure."));
+ return false;
+ }
+ ++m_lineNo;
+ }
+ return true;
+}
+
+bool ProFileEvaluator::Private::parseLine(const QString &line0)
+{
+ if (m_blockstack.isEmpty())
+ return false;
+
+ int parens = m_parens;
+ bool inQuote = m_inQuote;
+ bool escaped = false;
+ QString line = line0.simplified();
+
+ for (int i = 0; !m_syntaxError && i < line.length(); ++i) {
+ ushort c = line.at(i).unicode();
+ if (c == '#') { // Yep - no escaping possible
+ insertComment(line.mid(i + 1));
+ escaped = m_contNextLine;
+ break;
+ }
+ if (!escaped) {
+ if (c == '\\') {
+ escaped = true;
+ m_proitem += c;
+ continue;
+ } else if (c == '"') {
+ inQuote = !inQuote;
+ m_proitem += c;
+ continue;
+ }
+ } else {
+ escaped = false;
+ }
+ if (!inQuote) {
+ if (c == '(') {
+ ++parens;
+ } else if (c == ')') {
+ --parens;
+ } else if (!parens) {
+ if (m_block && (m_block->blockKind() & ProBlock::VariableKind)) {
+ if (c == ' ')
+ updateItem();
+ else
+ m_proitem += c;
+ continue;
+ }
+ if (c == ':') {
+ enterScope(false);
+ continue;
+ }
+ if (c == '{') {
+ enterScope(true);
+ continue;
+ }
+ if (c == '}') {
+ leaveScope();
+ continue;
+ }
+ if (c == '=') {
+ insertVariable(line, &i);
+ continue;
+ }
+ if (c == '|' || c == '!') {
+ insertOperator(c);
+ continue;
+ }
+ }
+ }
+
+ m_proitem += c;
+ }
+ m_inQuote = inQuote;
+ m_parens = parens;
+ m_contNextLine = escaped;
+ if (escaped) {
+ m_proitem.chop(1);
+ updateItem();
+ return true;
+ } else {
+ if (!m_syntaxError) {
+ updateItem();
+ finalizeBlock();
+ return true;
+ }
+ return false;
+ }
+}
+
+void ProFileEvaluator::Private::finalizeBlock()
+{
+ if (m_blockstack.isEmpty()) {
+ m_syntaxError = true;
+ } else {
+ if (m_blockstack.top()->blockKind() & ProBlock::SingleLine)
+ leaveScope();
+ m_block = 0;
+ m_commentItem = 0;
+ }
+}
+
+void ProFileEvaluator::Private::insertVariable(const QString &line, int *i)
+{
+ ProVariable::VariableOperator opkind;
+
+ if (m_proitem.isEmpty()) // Line starting with '=', like a conflict marker
+ return;
+
+ switch (m_proitem.at(m_proitem.length() - 1).unicode()) {
+ case '+':
+ m_proitem.chop(1);
+ opkind = ProVariable::AddOperator;
+ break;
+ case '-':
+ m_proitem.chop(1);
+ opkind = ProVariable::RemoveOperator;
+ break;
+ case '*':
+ m_proitem.chop(1);
+ opkind = ProVariable::UniqueAddOperator;
+ break;
+ case '~':
+ m_proitem.chop(1);
+ opkind = ProVariable::ReplaceOperator;
+ break;
+ default:
+ opkind = ProVariable::SetOperator;
+ }
+
+ ProBlock *block = m_blockstack.top();
+ m_proitem = m_proitem.trimmed();
+ ProVariable *variable = new ProVariable(m_proitem, block);
+ variable->setLineNumber(m_lineNo);
+ variable->setVariableOperator(opkind);
+ block->appendItem(variable);
+ m_block = variable;
+
+ if (!m_pendingComment.isEmpty()) {
+ m_block->setComment(m_pendingComment);
+ m_pendingComment.clear();
+ }
+ m_commentItem = variable;
+
+ m_proitem.clear();
+
+ if (opkind == ProVariable::ReplaceOperator) {
+ // skip util end of line or comment
+ while (1) {
+ ++(*i);
+
+ // end of line?
+ if (*i >= line.count())
+ break;
+
+ // comment?
+ if (line.at(*i).unicode() == '#') {
+ --(*i);
+ break;
+ }
+
+ m_proitem += line.at(*i);
+ }
+ m_proitem = m_proitem.trimmed();
+ }
+}
+
+void ProFileEvaluator::Private::insertOperator(const char op)
+{
+ updateItem();
+
+ ProOperator::OperatorKind opkind;
+ switch(op) {
+ case '!':
+ opkind = ProOperator::NotOperator;
+ break;
+ case '|':
+ opkind = ProOperator::OrOperator;
+ break;
+ default:
+ opkind = ProOperator::OrOperator;
+ }
+
+ ProBlock * const block = currentBlock();
+ ProOperator * const proOp = new ProOperator(opkind);
+ proOp->setLineNumber(m_lineNo);
+ block->appendItem(proOp);
+ m_commentItem = proOp;
+}
+
+void ProFileEvaluator::Private::insertComment(const QString &comment)
+{
+ updateItem();
+
+ QString strComment;
+ if (!m_commentItem)
+ strComment = m_pendingComment;
+ else
+ strComment = m_commentItem->comment();
+
+ if (strComment.isEmpty())
+ strComment = comment;
+ else {
+ strComment += QLatin1Char('\n');
+ strComment += comment.trimmed();
+ }
+
+ strComment = strComment.trimmed();
+
+ if (!m_commentItem)
+ m_pendingComment = strComment;
+ else
+ m_commentItem->setComment(strComment);
+}
+
+void ProFileEvaluator::Private::enterScope(bool multiLine)
+{
+ updateItem();
+
+ ProBlock *parent = currentBlock();
+ ProBlock *block = new ProBlock(parent);
+ block->setLineNumber(m_lineNo);
+ parent->setBlockKind(ProBlock::ScopeKind);
+
+ parent->appendItem(block);
+
+ if (multiLine)
+ block->setBlockKind(ProBlock::ScopeContentsKind);
+ else
+ block->setBlockKind(ProBlock::ScopeContentsKind|ProBlock::SingleLine);
+
+ m_blockstack.push(block);
+ m_block = 0;
+}
+
+void ProFileEvaluator::Private::leaveScope()
+{
+ updateItem();
+ m_blockstack.pop();
+ finalizeBlock();
+}
+
+ProBlock *ProFileEvaluator::Private::currentBlock()
+{
+ if (m_block)
+ return m_block;
+
+ ProBlock *parent = m_blockstack.top();
+ m_block = new ProBlock(parent);
+ m_block->setLineNumber(m_lineNo);
+ parent->appendItem(m_block);
+
+ if (!m_pendingComment.isEmpty()) {
+ m_block->setComment(m_pendingComment);
+ m_pendingComment.clear();
+ }
+
+ m_commentItem = m_block;
+
+ return m_block;
+}
+
+void ProFileEvaluator::Private::updateItem()
+{
+ m_proitem = m_proitem.trimmed();
+ if (m_proitem.isEmpty())
+ return;
+
+ ProBlock *block = currentBlock();
+ if (block->blockKind() & ProBlock::VariableKind) {
+ m_commentItem = new ProValue(m_proitem, static_cast<ProVariable*>(block));
+ } else if (m_proitem.endsWith(QLatin1Char(')'))) {
+ m_commentItem = new ProFunction(m_proitem);
+ } else {
+ m_commentItem = new ProCondition(m_proitem);
+ }
+ m_commentItem->setLineNumber(m_lineNo);
+ block->appendItem(m_commentItem);
+
+ m_proitem.clear();
+}
+
+
+ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
+{
+ if (block->blockKind() & ProBlock::ScopeContentsKind) {
+ if (!m_definingFunc.isEmpty()) {
+ if (!m_skipLevel || m_cumulative) {
+ QHash<QString, ProBlock *> *hash =
+ (m_definingTest ? &m_testFunctions : &m_replaceFunctions);
+ if (ProBlock *def = hash->value(m_definingFunc))
+ def->deref();
+ hash->insert(m_definingFunc, block);
+ block->ref();
+ block->setBlockKind(block->blockKind() | ProBlock::FunctionBodyKind);
+ }
+ m_definingFunc.clear();
+ return ProItem::ReturnSkip;
+ } else if (!(block->blockKind() & ProBlock::FunctionBodyKind)) {
+ if (!m_sts.condition)
+ ++m_skipLevel;
+ else
+ Q_ASSERT(!m_skipLevel);
+ }
+ } else {
+ if (!m_skipLevel) {
+ if (m_sts.condition) {
+ m_sts.prevCondition = true;
+ m_sts.condition = false;
+ }
+ } else {
+ Q_ASSERT(!m_sts.condition);
+ }
+ }
+ return ProItem::ReturnTrue;
+}
+
+void ProFileEvaluator::Private::visitEndProBlock(ProBlock *block)
+{
+ if ((block->blockKind() & ProBlock::ScopeContentsKind)
+ && !(block->blockKind() & ProBlock::FunctionBodyKind)) {
+ if (m_skipLevel) {
+ Q_ASSERT(!m_sts.condition);
+ --m_skipLevel;
+ } else if (!(block->blockKind() & ProBlock::SingleLine)) {
+ // Conditionals contained inside this block may have changed the state.
+ // So we reset it here to make an else following us do the right thing.
+ m_sts.condition = true;
+ }
+ }
+}
+
+ProItem::ProItemReturn ProFileEvaluator::Private::visitProLoopIteration()
+{
+ ProLoop &loop = m_loopStack.top();
+
+ if (loop.infinite) {
+ if (!loop.variable.isEmpty())
+ m_valuemap[loop.variable] = QStringList(QString::number(loop.index++));
+ if (loop.index > 1000) {
+ q->errorMessage(format("ran into infinite loop (> 1000 iterations)."));
+ return ProItem::ReturnFalse;
+ }
+ } else {
+ QString val;
+ do {
+ if (loop.index >= loop.list.count())
+ return ProItem::ReturnFalse;
+ val = loop.list.at(loop.index++);
+ } while (val.isEmpty()); // stupid, but qmake is like that
+ m_valuemap[loop.variable] = QStringList(val);
+ }
+ return ProItem::ReturnTrue;
+}
+
+void ProFileEvaluator::Private::visitProLoopCleanup()
+{
+ ProLoop &loop = m_loopStack.top();
+ m_valuemap[loop.variable] = loop.oldVarVal;
+ m_loopStack.pop_back();
+}
+
+void ProFileEvaluator::Private::visitBeginProVariable(ProVariable *variable)
+{
+ m_lastVarName = variable->variable();
+ m_variableOperator = variable->variableOperator();
+ m_isFirstVariableValue = true;
+ m_tempValuemap = m_valuemap;
+ m_tempFilevaluemap = m_filevaluemap;
+}
+
+void ProFileEvaluator::Private::visitEndProVariable(ProVariable *variable)
+{
+ Q_UNUSED(variable);
+ m_valuemap = m_tempValuemap;
+ m_filevaluemap = m_tempFilevaluemap;
+ m_lastVarName.clear();
+}
+
+void ProFileEvaluator::Private::visitProOperator(ProOperator *oper)
+{
+ m_invertNext = (oper->operatorKind() == ProOperator::NotOperator);
+}
+
+void ProFileEvaluator::Private::visitProCondition(ProCondition *cond)
+{
+ if (!m_skipLevel) {
+ if (!cond->text().compare(QLatin1String("else"), Qt::CaseInsensitive)) {
+ m_sts.condition = !m_sts.prevCondition;
+ } else {
+ m_sts.prevCondition = false;
+ if (!m_sts.condition && isActiveConfig(cond->text(), true) ^ m_invertNext)
+ m_sts.condition = true;
+ }
+ }
+ m_invertNext = false;
+}
+
+ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
+{
+ PRE(pro);
+ m_lineNo = pro->lineNumber();
+ if (m_origfile.isEmpty())
+ m_origfile = pro->fileName();
+ if (m_oldPath.isEmpty()) {
+ // change the working directory for the initial profile we visit, since
+ // that is *the* profile. All the other times we reach this function will be due to
+ // include(file) or load(file)
+
+ m_oldPath = QDir::currentPath();
+
+ m_profileStack.push(pro);
+
+ const QString mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS"));
+ if (!mkspecDirectory.isEmpty()) {
+ bool cumulative = m_cumulative;
+ m_cumulative = false;
+ // This is what qmake does, everything set in the mkspec is also set
+ // But this also creates a lot of problems
+ evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"));
+ evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"));
+ m_cumulative = cumulative;
+ }
+
+ return returnBool(QDir::setCurrent(pro->directoryName()));
+ }
+
+ return ProItem::ReturnTrue;
+}
+
+ProItem::ProItemReturn ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
+{
+ PRE(pro);
+ m_lineNo = pro->lineNumber();
+ if (m_profileStack.count() == 1 && !m_oldPath.isEmpty()) {
+ const QString &mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS"));
+ if (!mkspecDirectory.isEmpty()) {
+ bool cumulative = m_cumulative;
+ m_cumulative = false;
+
+ evaluateFile(mkspecDirectory + QLatin1String("/features/default_post.prf"));
+
+ QSet<QString> processed;
+ forever {
+ bool finished = true;
+ QStringList configs = valuesDirect(QLatin1String("CONFIG"));
+ for (int i = configs.size() - 1; i >= 0; --i) {
+ const QString config = configs[i].toLower();
+ if (!processed.contains(config)) {
+ processed.insert(config);
+ if (evaluateFile(mkspecDirectory + QLatin1String("/features/")
+ + config + QLatin1String(".prf"))) {
+ finished = false;
+ break;
+ }
+ }
+ }
+ if (finished)
+ break;
+ }
+
+ foreach (ProBlock *itm, m_replaceFunctions)
+ itm->deref();
+ m_replaceFunctions.clear();
+ foreach (ProBlock *itm, m_testFunctions)
+ itm->deref();
+ m_testFunctions.clear();
+
+ m_cumulative = cumulative;
+ }
+
+ m_profileStack.pop();
+ return returnBool(QDir::setCurrent(m_oldPath));
+ }
+
+ return ProItem::ReturnTrue;
+}
+
+static void replaceInList(QStringList *varlist,
+ const QRegExp &regexp, const QString &replace, bool global)
+{
+ for (QStringList::Iterator varit = varlist->begin(); varit != varlist->end(); ) {
+ if ((*varit).contains(regexp)) {
+ (*varit).replace(regexp, replace);
+ if ((*varit).isEmpty())
+ varit = varlist->erase(varit);
+ else
+ ++varit;
+ if(!global)
+ break;
+ } else {
+ ++varit;
+ }
+ }
+}
+
+void ProFileEvaluator::Private::visitProValue(ProValue *value)
+{
+ PRE(value);
+ m_lineNo = value->lineNumber();
+ QString val = value->value();
+
+ QString varName = m_lastVarName;
+
+ QStringList v = expandVariableReferences(val);
+
+ // Since qmake combines different values for the TARGET variable, we join
+ // TARGET values that are on the same line. We can't do this later with all
+ // values because this parser isn't scope-aware, so we'd risk joining
+ // scope-specific targets together.
+ if (varName == QLatin1String("TARGET")
+ && m_lineNo == m_prevLineNo
+ && currentProFile() == m_prevProFile) {
+ QStringList targets = m_tempValuemap.value(QLatin1String("TARGET"));
+ m_tempValuemap.remove(QLatin1String("TARGET"));
+ QStringList lastTarget(targets.takeLast());
+ lastTarget << v.join(QLatin1String(" "));
+ targets.push_back(lastTarget.join(QLatin1String(" ")));
+ v = targets;
+ }
+ m_prevLineNo = m_lineNo;
+ m_prevProFile = currentProFile();
+
+ switch (m_variableOperator) {
+ case ProVariable::SetOperator: // =
+ if (!m_cumulative) {
+ if (!m_skipLevel) {
+ if (m_isFirstVariableValue) {
+ m_tempValuemap[varName] = v;
+ m_tempFilevaluemap[currentProFile()][varName] = v;
+ } else { // handle lines "CONFIG = foo bar"
+ m_tempValuemap[varName] += v;
+ m_tempFilevaluemap[currentProFile()][varName] += v;
+ }
+ }
+ } else {
+ // We are greedy for values.
+ m_tempValuemap[varName] += v;
+ m_tempFilevaluemap[currentProFile()][varName] += v;
+ }
+ break;
+ case ProVariable::UniqueAddOperator: // *=
+ if (!m_skipLevel || m_cumulative) {
+ insertUnique(&m_tempValuemap, varName, v);
+ insertUnique(&m_tempFilevaluemap[currentProFile()], varName, v);
+ }
+ break;
+ case ProVariable::AddOperator: // +=
+ if (!m_skipLevel || m_cumulative) {
+ m_tempValuemap[varName] += v;
+ m_tempFilevaluemap[currentProFile()][varName] += v;
+ }
+ break;
+ case ProVariable::RemoveOperator: // -=
+ if (!m_cumulative) {
+ if (!m_skipLevel) {
+ removeEach(&m_tempValuemap, varName, v);
+ removeEach(&m_tempFilevaluemap[currentProFile()], varName, v);
+ }
+ } else {
+ // We are stingy with our values, too.
+ }
+ break;
+ case ProVariable::ReplaceOperator: // ~=
+ {
+ // DEFINES ~= s/a/b/?[gqi]
+
+ doVariableReplace(&val);
+ if (val.length() < 4 || val[0] != QLatin1Char('s')) {
+ q->logMessage(format("the ~= operator can handle only the s/// function."));
+ break;
+ }
+ QChar sep = val.at(1);
+ QStringList func = val.split(sep);
+ if (func.count() < 3 || func.count() > 4) {
+ q->logMessage(format("the s/// function expects 3 or 4 arguments."));
+ break;
+ }
+
+ bool global = false, quote = false, case_sense = false;
+ if (func.count() == 4) {
+ global = func[3].indexOf(QLatin1Char('g')) != -1;
+ case_sense = func[3].indexOf(QLatin1Char('i')) == -1;
+ quote = func[3].indexOf(QLatin1Char('q')) != -1;
+ }
+ QString pattern = func[1];
+ QString replace = func[2];
+ if (quote)
+ pattern = QRegExp::escape(pattern);
+
+ QRegExp regexp(pattern, case_sense ? Qt::CaseSensitive : Qt::CaseInsensitive);
+
+ if (!m_skipLevel || m_cumulative) {
+ // We could make a union of modified and unmodified values,
+ // but this will break just as much as it fixes, so leave it as is.
+ replaceInList(&m_tempValuemap[varName], regexp, replace, global);
+ replaceInList(&m_tempFilevaluemap[currentProFile()][varName], regexp, replace, global);
+ }
+ }
+ break;
+
+ }
+ m_isFirstVariableValue = false;
+}
+
+ProItem::ProItemReturn ProFileEvaluator::Private::visitProFunction(ProFunction *func)
+{
+ // Make sure that called subblocks don't inherit & destroy the state
+ bool invertThis = m_invertNext;
+ m_invertNext = false;
+ if (!m_skipLevel)
+ m_sts.prevCondition = false;
+ if (m_cumulative || !m_sts.condition) {
+ QString text = func->text();
+ int lparen = text.indexOf(QLatin1Char('('));
+ int rparen = text.lastIndexOf(QLatin1Char(')'));
+ Q_ASSERT(lparen < rparen);
+ QString arguments = text.mid(lparen + 1, rparen - lparen - 1);
+ QString funcName = text.left(lparen);
+ m_lineNo = func->lineNumber();
+ ProItem::ProItemReturn result = evaluateConditionalFunction(funcName.trimmed(), arguments);
+ if (result != ProItem::ReturnFalse && result != ProItem::ReturnTrue)
+ return result;
+ if (!m_skipLevel && ((result == ProItem::ReturnTrue) ^ invertThis))
+ m_sts.condition = true;
+ }
+ return ProItem::ReturnTrue;
+}
+
+
+QStringList ProFileEvaluator::Private::qmakeFeaturePaths()
+{
+ QStringList concat;
+ {
+ const QString base_concat = QDir::separator() + QLatin1String("features");
+ concat << base_concat + QDir::separator() + QLatin1String("mac");
+ concat << base_concat + QDir::separator() + QLatin1String("macx");
+ concat << base_concat + QDir::separator() + QLatin1String("unix");
+ concat << base_concat + QDir::separator() + QLatin1String("win32");
+ concat << base_concat + QDir::separator() + QLatin1String("mac9");
+ concat << base_concat + QDir::separator() + QLatin1String("qnx6");
+ concat << base_concat;
+ }
+ const QString mkspecs_concat = QDir::separator() + QLatin1String("mkspecs");
+ QStringList feature_roots;
+ QByteArray mkspec_path = qgetenv("QMAKEFEATURES");
+ if (!mkspec_path.isNull())
+ feature_roots += splitPathList(QString::fromLocal8Bit(mkspec_path));
+ /*
+ if (prop)
+ feature_roots += splitPathList(prop->value("QMAKEFEATURES"));
+ if (!Option::mkfile::cachefile.isEmpty()) {
+ QString path;
+ int last_slash = Option::mkfile::cachefile.lastIndexOf(Option::dir_sep);
+ if (last_slash != -1)
+ path = Option::fixPathToLocalOS(Option::mkfile::cachefile.left(last_slash));
+ foreach (const QString &concat_it, concat)
+ feature_roots << (path + concat_it);
+ }
+ */
+
+ QByteArray qmakepath = qgetenv("QMAKEPATH");
+ if (!qmakepath.isNull()) {
+ const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath));
+ foreach (const QString &item, lst) {
+ foreach (const QString &concat_it, concat)
+ feature_roots << (item + mkspecs_concat + concat_it);
+ }
+ }
+ //if (!Option::mkfile::qmakespec.isEmpty())
+ // feature_roots << Option::mkfile::qmakespec + QDir::separator() + "features";
+ //if (!Option::mkfile::qmakespec.isEmpty()) {
+ // QFileInfo specfi(Option::mkfile::qmakespec);
+ // QDir specdir(specfi.absoluteFilePath());
+ // while (!specdir.isRoot()) {
+ // if (!specdir.cdUp() || specdir.isRoot())
+ // break;
+ // if (QFile::exists(specdir.path() + QDir::separator() + "features")) {
+ // foreach (const QString &concat_it, concat)
+ // feature_roots << (specdir.path() + concat_it);
+ // break;
+ // }
+ // }
+ //}
+ foreach (const QString &concat_it, concat)
+ feature_roots << (propertyValue(QLatin1String("QT_INSTALL_PREFIX")) +
+ mkspecs_concat + concat_it);
+ foreach (const QString &concat_it, concat)
+ feature_roots << (propertyValue(QLatin1String("QT_INSTALL_DATA")) +
+ mkspecs_concat + concat_it);
+ return feature_roots;
+}
+
+QString ProFileEvaluator::Private::propertyValue(const QString &name) const
+{
+ if (m_properties.contains(name))
+ return m_properties.value(name);
+ if (name == QLatin1String("QT_INSTALL_PREFIX"))
+ return QLibraryInfo::location(QLibraryInfo::PrefixPath);
+ if (name == QLatin1String("QT_INSTALL_DATA"))
+ return QLibraryInfo::location(QLibraryInfo::DataPath);
+ if (name == QLatin1String("QT_INSTALL_DOCS"))
+ return QLibraryInfo::location(QLibraryInfo::DocumentationPath);
+ if (name == QLatin1String("QT_INSTALL_HEADERS"))
+ return QLibraryInfo::location(QLibraryInfo::HeadersPath);
+ if (name == QLatin1String("QT_INSTALL_LIBS"))
+ return QLibraryInfo::location(QLibraryInfo::LibrariesPath);
+ if (name == QLatin1String("QT_INSTALL_BINS"))
+ return QLibraryInfo::location(QLibraryInfo::BinariesPath);
+ if (name == QLatin1String("QT_INSTALL_PLUGINS"))
+ return QLibraryInfo::location(QLibraryInfo::PluginsPath);
+ if (name == QLatin1String("QT_INSTALL_TRANSLATIONS"))
+ return QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (name == QLatin1String("QT_INSTALL_CONFIGURATION"))
+ return QLibraryInfo::location(QLibraryInfo::SettingsPath);
+ if (name == QLatin1String("QT_INSTALL_EXAMPLES"))
+ return QLibraryInfo::location(QLibraryInfo::ExamplesPath);
+ if (name == QLatin1String("QT_INSTALL_DEMOS"))
+ return QLibraryInfo::location(QLibraryInfo::DemosPath);
+ if (name == QLatin1String("QMAKE_MKSPECS"))
+ return qmake_mkspec_paths().join(Option::dirlist_sep);
+ if (name == QLatin1String("QMAKE_VERSION"))
+ return QLatin1String("1.0"); //### FIXME
+ //return qmake_version();
+#ifdef QT_VERSION_STR
+ if (name == QLatin1String("QT_VERSION"))
+ return QLatin1String(QT_VERSION_STR);
+#endif
+ return QLatin1String("UNKNOWN"); //###
+}
+
+ProFile *ProFileEvaluator::Private::currentProFile() const
+{
+ if (m_profileStack.count() > 0)
+ return m_profileStack.top();
+ return 0;
+}
+
+QString ProFileEvaluator::Private::currentFileName() const
+{
+ ProFile *pro = currentProFile();
+ if (pro)
+ return pro->fileName();
+ return QString();
+}
+
+QString ProFileEvaluator::Private::currentDirectory() const
+{
+ ProFile *cur = m_profileStack.top();
+ return cur->directoryName();
+}
+
+void ProFileEvaluator::Private::doVariableReplace(QString *str)
+{
+ *str = expandVariableReferences(*str).join(QString(Option::field_sep));
+}
+
+QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &str)
+{
+ QStringList ret;
+// if (ok)
+// *ok = true;
+ if (str.isEmpty())
+ return ret;
+
+ const ushort LSQUARE = '[';
+ const ushort RSQUARE = ']';
+ const ushort LCURLY = '{';
+ const ushort RCURLY = '}';
+ const ushort LPAREN = '(';
+ const ushort RPAREN = ')';
+ const ushort DOLLAR = '$';
+ const ushort BACKSLASH = '\\';
+ const ushort UNDERSCORE = '_';
+ const ushort DOT = '.';
+ const ushort SPACE = ' ';
+ const ushort TAB = '\t';
+ const ushort SINGLEQUOTE = '\'';
+ const ushort DOUBLEQUOTE = '"';
+
+ ushort unicode, quote = 0;
+ const QChar *str_data = str.data();
+ const int str_len = str.length();
+
+ ushort term;
+ QString var, args;
+
+ int replaced = 0;
+ QString current;
+ for (int i = 0; i < str_len; ++i) {
+ unicode = str_data[i].unicode();
+ const int start_var = i;
+ if (unicode == DOLLAR && str_len > i+2) {
+ unicode = str_data[++i].unicode();
+ if (unicode == DOLLAR) {
+ term = 0;
+ var.clear();
+ args.clear();
+ enum { VAR, ENVIRON, FUNCTION, PROPERTY } var_type = VAR;
+ unicode = str_data[++i].unicode();
+ if (unicode == LSQUARE) {
+ unicode = str_data[++i].unicode();
+ term = RSQUARE;
+ var_type = PROPERTY;
+ } else if (unicode == LCURLY) {
+ unicode = str_data[++i].unicode();
+ var_type = VAR;
+ term = RCURLY;
+ } else if (unicode == LPAREN) {
+ unicode = str_data[++i].unicode();
+ var_type = ENVIRON;
+ term = RPAREN;
+ }
+ forever {
+ if (!(unicode & (0xFF<<8)) &&
+ unicode != DOT && unicode != UNDERSCORE &&
+ //unicode != SINGLEQUOTE && unicode != DOUBLEQUOTE &&
+ (unicode < 'a' || unicode > 'z') && (unicode < 'A' || unicode > 'Z') &&
+ (unicode < '0' || unicode > '9'))
+ break;
+ var.append(QChar(unicode));
+ if (++i == str_len)
+ break;
+ unicode = str_data[i].unicode();
+ // at this point, i points to either the 'term' or 'next' character (which is in unicode)
+ }
+ if (var_type == VAR && unicode == LPAREN) {
+ var_type = FUNCTION;
+ int depth = 0;
+ forever {
+ if (++i == str_len)
+ break;
+ unicode = str_data[i].unicode();
+ if (unicode == LPAREN) {
+ depth++;
+ } else if (unicode == RPAREN) {
+ if (!depth)
+ break;
+ --depth;
+ }
+ args.append(QChar(unicode));
+ }
+ if (++i < str_len)
+ unicode = str_data[i].unicode();
+ else
+ unicode = 0;
+ // at this point i is pointing to the 'next' character (which is in unicode)
+ // this might actually be a term character since you can do $${func()}
+ }
+ if (term) {
+ if (unicode != term) {
+ q->logMessage(format("Missing %1 terminator [found %2]")
+ .arg(QChar(term))
+ .arg(unicode ? QString(unicode) : QString::fromLatin1(("end-of-line"))));
+// if (ok)
+// *ok = false;
+ return QStringList();
+ }
+ } else {
+ // move the 'cursor' back to the last char of the thing we were looking at
+ --i;
+ }
+ // since i never points to the 'next' character, there is no reason for this to be set
+ unicode = 0;
+
+ QStringList replacement;
+ if (var_type == ENVIRON) {
+ replacement = split_value_list(QString::fromLocal8Bit(qgetenv(var.toLatin1().constData())));
+ } else if (var_type == PROPERTY) {
+ replacement << propertyValue(var);
+ } else if (var_type == FUNCTION) {
+ replacement << evaluateExpandFunction(var, args);
+ } else if (var_type == VAR) {
+ replacement = values(var);
+ }
+ if (!(replaced++) && start_var)
+ current = str.left(start_var);
+ if (!replacement.isEmpty()) {
+ if (quote) {
+ current += replacement.join(QString(Option::field_sep));
+ } else {
+ current += replacement.takeFirst();
+ if (!replacement.isEmpty()) {
+ if (!current.isEmpty())
+ ret.append(current);
+ current = replacement.takeLast();
+ if (!replacement.isEmpty())
+ ret += replacement;
+ }
+ }
+ }
+ } else {
+ if (replaced)
+ current.append(QLatin1Char('$'));
+ }
+ }
+ if (quote && unicode == quote) {
+ unicode = 0;
+ quote = 0;
+ } else if (unicode == BACKSLASH) {
+ bool escape = false;
+ const char *symbols = "[]{}()$\\'\"";
+ for (const char *s = symbols; *s; ++s) {
+ if (str_data[i+1].unicode() == (ushort)*s) {
+ i++;
+ escape = true;
+ if (!(replaced++))
+ current = str.left(start_var);
+ current.append(str.at(i));
+ break;
+ }
+ }
+ if (escape || !replaced)
+ unicode =0;
+ } else if (!quote && (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE)) {
+ quote = unicode;
+ unicode = 0;
+ if (!(replaced++) && i)
+ current = str.left(i);
+ } else if (!quote && (unicode == SPACE || unicode == TAB)) {
+ unicode = 0;
+ if (!current.isEmpty()) {
+ ret.append(current);
+ current.clear();
+ }
+ }
+ if (replaced && unicode)
+ current.append(QChar(unicode));
+ }
+ if (!replaced)
+ ret = QStringList(str);
+ else if (!current.isEmpty())
+ ret.append(current);
+ return ret;
+}
+
+bool ProFileEvaluator::Private::isActiveConfig(const QString &config, bool regex)
+{
+ // magic types for easy flipping
+ if (config == QLatin1String("true"))
+ return true;
+ if (config == QLatin1String("false"))
+ return false;
+
+ // mkspecs
+ if ((Option::target_mode == Option::TARG_MACX_MODE
+ || Option::target_mode == Option::TARG_QNX6_MODE
+ || Option::target_mode == Option::TARG_UNIX_MODE)
+ && config == QLatin1String("unix"))
+ return true;
+ if (Option::target_mode == Option::TARG_MACX_MODE && config == QLatin1String("macx"))
+ return true;
+ if (Option::target_mode == Option::TARG_QNX6_MODE && config == QLatin1String("qnx6"))
+ return true;
+ if (Option::target_mode == Option::TARG_MAC9_MODE && config == QLatin1String("mac9"))
+ return true;
+ if ((Option::target_mode == Option::TARG_MAC9_MODE
+ || Option::target_mode == Option::TARG_MACX_MODE)
+ && config == QLatin1String("mac"))
+ return true;
+ if (Option::target_mode == Option::TARG_WIN_MODE && config == QLatin1String("win32"))
+ return true;
+
+ QRegExp re(config, Qt::CaseSensitive, QRegExp::Wildcard);
+ QString spec = Option::qmakespec;
+ if ((regex && re.exactMatch(spec)) || (!regex && spec == config))
+ return true;
+
+ return false;
+}
+
+QStringList ProFileEvaluator::Private::evaluateFunction(
+ ProBlock *funcPtr, const QStringList &argumentsList, bool *ok)
+{
+ bool oki;
+ QStringList ret;
+
+ if (m_valuemapStack.count() >= 100) {
+ q->errorMessage(format("ran into infinite recursion (depth > 100)."));
+ oki = false;
+ } else {
+ State sts = m_sts;
+ m_valuemapStack.push(m_valuemap);
+ m_filevaluemapStack.push(m_filevaluemap);
+
+ QStringList args;
+ for (int i = 0; i < argumentsList.count(); ++i) {
+ QStringList theArgs = expandVariableReferences(argumentsList[i]);
+ args += theArgs;
+ m_valuemap[QString::number(i+1)] = theArgs;
+ }
+ m_valuemap[QLatin1String("ARGS")] = args;
+ oki = (funcPtr->Accept(this) != ProItem::ReturnFalse); // True || Return
+ ret = m_returnValue;
+ m_returnValue.clear();
+
+ m_valuemap = m_valuemapStack.pop();
+ m_filevaluemap = m_filevaluemapStack.pop();
+ m_sts = sts;
+ }
+ if (ok)
+ *ok = oki;
+ if (oki)
+ return ret;
+ return QStringList();
+}
+
+QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &func, const QString &arguments)
+{
+ QStringList argumentsList = split_arg_list(arguments);
+
+ if (ProBlock *funcPtr = m_replaceFunctions.value(func, 0))
+ return evaluateFunction(funcPtr, argumentsList, 0);
+
+ QStringList args;
+ for (int i = 0; i < argumentsList.count(); ++i)
+ args += expandVariableReferences(argumentsList[i]).join(Option::field_sep);
+
+ enum ExpandFunc { E_MEMBER=1, E_FIRST, E_LAST, E_CAT, E_FROMFILE, E_EVAL, E_LIST,
+ E_SPRINTF, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
+ E_FIND, E_SYSTEM, E_UNIQUE, E_QUOTE, E_ESCAPE_EXPAND,
+ E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE,
+ E_REPLACE };
+
+ static QHash<QString, int> expands;
+ if (expands.isEmpty()) {
+ expands.insert(QLatin1String("member"), E_MEMBER);
+ expands.insert(QLatin1String("first"), E_FIRST);
+ expands.insert(QLatin1String("last"), E_LAST);
+ expands.insert(QLatin1String("cat"), E_CAT);
+ expands.insert(QLatin1String("fromfile"), E_FROMFILE); // implementation disabled (see comment below)
+ expands.insert(QLatin1String("eval"), E_EVAL);
+ expands.insert(QLatin1String("list"), E_LIST);
+ expands.insert(QLatin1String("sprintf"), E_SPRINTF);
+ expands.insert(QLatin1String("join"), E_JOIN);
+ expands.insert(QLatin1String("split"), E_SPLIT);
+ expands.insert(QLatin1String("basename"), E_BASENAME);
+ expands.insert(QLatin1String("dirname"), E_DIRNAME);
+ expands.insert(QLatin1String("section"), E_SECTION);
+ expands.insert(QLatin1String("find"), E_FIND);
+ expands.insert(QLatin1String("system"), E_SYSTEM);
+ expands.insert(QLatin1String("unique"), E_UNIQUE);
+ expands.insert(QLatin1String("quote"), E_QUOTE);
+ expands.insert(QLatin1String("escape_expand"), E_ESCAPE_EXPAND);
+ expands.insert(QLatin1String("upper"), E_UPPER);
+ expands.insert(QLatin1String("lower"), E_LOWER);
+ expands.insert(QLatin1String("re_escape"), E_RE_ESCAPE);
+ expands.insert(QLatin1String("files"), E_FILES);
+ expands.insert(QLatin1String("prompt"), E_PROMPT); // interactive, so cannot be implemented
+ expands.insert(QLatin1String("replace"), E_REPLACE);
+ }
+ ExpandFunc func_t = ExpandFunc(expands.value(func.toLower()));
+
+ QStringList ret;
+
+ switch (func_t) {
+ case E_BASENAME:
+ case E_DIRNAME:
+ case E_SECTION: {
+ bool regexp = false;
+ QString sep, var;
+ int beg = 0;
+ int end = -1;
+ if (func_t == E_SECTION) {
+ if (args.count() != 3 && args.count() != 4) {
+ q->logMessage(format("%1(var) section(var, sep, begin, end) "
+ "requires three or four arguments.").arg(func));
+ } else {
+ var = args[0];
+ sep = args[1];
+ beg = args[2].toInt();
+ if (args.count() == 4)
+ end = args[3].toInt();
+ }
+ } else {
+ if (args.count() != 1) {
+ q->logMessage(format("%1(var) requires one argument.").arg(func));
+ } else {
+ var = args[0];
+ regexp = true;
+ sep = QLatin1String("[\\\\/]");
+ if (func_t == E_DIRNAME)
+ end = -2;
+ else
+ beg = -1;
+ }
+ }
+ if (!var.isNull()) {
+ foreach (const QString str, values(var)) {
+ if (regexp)
+ ret += str.section(QRegExp(sep), beg, end);
+ else
+ ret += str.section(sep, beg, end);
+ }
+ }
+ break;
+ }
+ case E_SPRINTF:
+ if(args.count() < 1) {
+ q->logMessage(format("sprintf(format, ...) requires at least one argument"));
+ } else {
+ QString tmp = args.at(0);
+ for (int i = 1; i < args.count(); ++i)
+ tmp = tmp.arg(args.at(i));
+ ret = split_value_list(tmp);
+ }
+ break;
+ case E_JOIN: {
+ if (args.count() < 1 || args.count() > 4) {
+ q->logMessage(format("join(var, glue, before, after) requires one to four arguments."));
+ } else {
+ QString glue, before, after;
+ if (args.count() >= 2)
+ glue = args[1];
+ if (args.count() >= 3)
+ before = args[2];
+ if (args.count() == 4)
+ after = args[3];
+ const QStringList &var = values(args.first());
+ if (!var.isEmpty())
+ ret.append(before + var.join(glue) + after);
+ }
+ break;
+ }
+ case E_SPLIT: {
+ if (args.count() != 2) {
+ q->logMessage(format("split(var, sep) requires one or two arguments"));
+ } else {
+ const QString &sep = (args.count() == 2) ? args[1] : QString(Option::field_sep);
+ foreach (const QString &var, values(args.first()))
+ foreach (const QString &splt, var.split(sep))
+ ret.append(splt);
+ }
+ break;
+ }
+ case E_MEMBER: {
+ if (args.count() < 1 || args.count() > 3) {
+ q->logMessage(format("member(var, start, end) requires one to three arguments."));
+ } else {
+ bool ok = true;
+ const QStringList var = values(args.first());
+ int start = 0, end = 0;
+ if (args.count() >= 2) {
+ QString start_str = args[1];
+ start = start_str.toInt(&ok);
+ if (!ok) {
+ if (args.count() == 2) {
+ int dotdot = start_str.indexOf(QLatin1String(".."));
+ if (dotdot != -1) {
+ start = start_str.left(dotdot).toInt(&ok);
+ if (ok)
+ end = start_str.mid(dotdot+2).toInt(&ok);
+ }
+ }
+ if (!ok)
+ q->logMessage(format("member() argument 2 (start) '%2' invalid.")
+ .arg(start_str));
+ } else {
+ end = start;
+ if (args.count() == 3)
+ end = args[2].toInt(&ok);
+ if (!ok)
+ q->logMessage(format("member() argument 3 (end) '%2' invalid.\n")
+ .arg(args[2]));
+ }
+ }
+ if (ok) {
+ if (start < 0)
+ start += var.count();
+ if (end < 0)
+ end += var.count();
+ if (start < 0 || start >= var.count() || end < 0 || end >= var.count()) {
+ //nothing
+ } else if (start < end) {
+ for (int i = start; i <= end && var.count() >= i; i++)
+ ret.append(var[i]);
+ } else {
+ for (int i = start; i >= end && var.count() >= i && i >= 0; i--)
+ ret += var[i];
+ }
+ }
+ }
+ break;
+ }
+ case E_FIRST:
+ case E_LAST: {
+ if (args.count() != 1) {
+ q->logMessage(format("%1(var) requires one argument.").arg(func));
+ } else {
+ const QStringList var = values(args.first());
+ if (!var.isEmpty()) {
+ if (func_t == E_FIRST)
+ ret.append(var[0]);
+ else
+ ret.append(var.last());
+ }
+ }
+ break;
+ }
+ case E_CAT:
+ if (args.count() < 1 || args.count() > 2) {
+ q->logMessage(format("cat(file, singleline=true) requires one or two arguments."));
+ } else {
+ QString file = args[0];
+ file = Option::fixPathToLocalOS(file);
+
+ bool singleLine = true;
+ if (args.count() > 1)
+ singleLine = (!args[1].compare(QLatin1String("true"), Qt::CaseInsensitive));
+
+ QFile qfile(file);
+ if (qfile.open(QIODevice::ReadOnly)) {
+ QTextStream stream(&qfile);
+ while (!stream.atEnd()) {
+ ret += split_value_list(stream.readLine().trimmed());
+ if (!singleLine)
+ ret += QLatin1String("\n");
+ }
+ qfile.close();
+ }
+ }
+ break;
+#if 0 // Used only by Qt's configure for caching
+ case E_FROMFILE:
+ if (args.count() != 2) {
+ q->logMessage(format("fromfile(file, variable) requires two arguments."));
+ } else {
+ QString file = args[0], seek_variableName = args[1];
+
+ ProFile pro(Option::fixPathToLocalOS(file));
+
+ ProFileEvaluator visitor;
+ visitor.setVerbose(m_verbose);
+ visitor.setCumulative(m_cumulative);
+
+ if (!visitor.queryProFile(&pro))
+ break;
+
+ if (!visitor.accept(&pro))
+ break;
+
+ ret = visitor.values(seek_variableName);
+ }
+ break;
+#endif
+ case E_EVAL: {
+ if (args.count() != 1) {
+ q->logMessage(format("eval(variable) requires one argument"));
+
+ } else {
+ ret += values(args.at(0));
+ }
+ break; }
+ case E_LIST: {
+ static int x = 0;
+ QString tmp;
+ tmp.sprintf(".QMAKE_INTERNAL_TMP_variableName_%d", x++);
+ ret = QStringList(tmp);
+ QStringList lst;
+ foreach (const QString &arg, args)
+ lst += split_value_list(arg);
+ m_valuemap[tmp] = lst;
+ break; }
+ case E_FIND:
+ if (args.count() != 2) {
+ q->logMessage(format("find(var, str) requires two arguments."));
+ } else {
+ QRegExp regx(args[1]);
+ foreach (const QString &val, values(args.first()))
+ if (regx.indexIn(val) != -1)
+ ret += val;
+ }
+ break;
+ case E_SYSTEM:
+ if (!m_skipLevel) {
+ if (args.count() < 1 || args.count() > 2) {
+ q->logMessage(format("system(execute) requires one or two arguments."));
+ } else {
+ char buff[256];
+ FILE *proc = QT_POPEN(args[0].toLatin1(), "r");
+ bool singleLine = true;
+ if (args.count() > 1)
+ singleLine = (!args[1].compare(QLatin1String("true"), Qt::CaseInsensitive));
+ QString output;
+ while (proc && !feof(proc)) {
+ int read_in = int(fread(buff, 1, 255, proc));
+ if (!read_in)
+ break;
+ for (int i = 0; i < read_in; i++) {
+ if ((singleLine && buff[i] == '\n') || buff[i] == '\t')
+ buff[i] = ' ';
+ }
+ buff[read_in] = '\0';
+ output += QLatin1String(buff);
+ }
+ ret += split_value_list(output);
+ if (proc)
+ QT_PCLOSE(proc);
+ }
+ }
+ break;
+ case E_UNIQUE:
+ if(args.count() != 1) {
+ q->logMessage(format("unique(var) requires one argument."));
+ } else {
+ foreach (const QString &var, values(args.first()))
+ if (!ret.contains(var))
+ ret.append(var);
+ }
+ break;
+ case E_QUOTE:
+ for (int i = 0; i < args.count(); ++i)
+ ret += QStringList(args.at(i));
+ break;
+ case E_ESCAPE_EXPAND:
+ for (int i = 0; i < args.size(); ++i) {
+ QChar *i_data = args[i].data();
+ int i_len = args[i].length();
+ for (int x = 0; x < i_len; ++x) {
+ if (*(i_data+x) == QLatin1Char('\\') && x < i_len-1) {
+ if (*(i_data+x+1) == QLatin1Char('\\')) {
+ ++x;
+ } else {
+ struct {
+ char in, out;
+ } mapped_quotes[] = {
+ { 'n', '\n' },
+ { 't', '\t' },
+ { 'r', '\r' },
+ { 0, 0 }
+ };
+ for (int i = 0; mapped_quotes[i].in; ++i) {
+ if (*(i_data+x+1) == QLatin1Char(mapped_quotes[i].in)) {
+ *(i_data+x) = QLatin1Char(mapped_quotes[i].out);
+ if (x < i_len-2)
+ memmove(i_data+x+1, i_data+x+2, (i_len-x-2)*sizeof(QChar));
+ --i_len;
+ break;
+ }
+ }
+ }
+ }
+ }
+ ret.append(QString(i_data, i_len));
+ }
+ break;
+ case E_RE_ESCAPE:
+ for (int i = 0; i < args.size(); ++i)
+ ret += QRegExp::escape(args[i]);
+ break;
+ case E_UPPER:
+ case E_LOWER:
+ for (int i = 0; i < args.count(); ++i)
+ if (func_t == E_UPPER)
+ ret += args[i].toUpper();
+ else
+ ret += args[i].toLower();
+ break;
+ case E_FILES:
+ if (args.count() != 1 && args.count() != 2) {
+ q->logMessage(format("files(pattern, recursive=false) requires one or two arguments"));
+ } else {
+ bool recursive = false;
+ if (args.count() == 2)
+ recursive = (!args[1].compare(QLatin1String("true"), Qt::CaseInsensitive) || args[1].toInt());
+ QStringList dirs;
+ QString r = Option::fixPathToLocalOS(args[0]);
+ int slash = r.lastIndexOf(QDir::separator());
+ if (slash != -1) {
+ dirs.append(r.left(slash));
+ r = r.mid(slash+1);
+ } else {
+ dirs.append(QString());
+ }
+
+ const QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard);
+ for (int d = 0; d < dirs.count(); d++) {
+ QString dir = dirs[d];
+ if (!dir.isEmpty() && !dir.endsWith(Option::dir_sep))
+ dir += QLatin1Char('/');
+
+ QDir qdir(dir);
+ for (int i = 0; i < (int)qdir.count(); ++i) {
+ if (qdir[i] == QLatin1String(".") || qdir[i] == QLatin1String(".."))
+ continue;
+ QString fname = dir + qdir[i];
+ if (QFileInfo(fname).isDir()) {
+ if (recursive)
+ dirs.append(fname);
+ }
+ if (regex.exactMatch(qdir[i]))
+ ret += fname;
+ }
+ }
+ }
+ break;
+ case E_REPLACE:
+ if(args.count() != 3 ) {
+ q->logMessage(format("replace(var, before, after) requires three arguments"));
+ } else {
+ const QRegExp before(args[1]);
+ const QString after(args[2]);
+ foreach (QString val, values(args.first()))
+ ret += val.replace(before, after);
+ }
+ break;
+ case 0:
+ q->logMessage(format("'%1' is not a recognized replace function").arg(func));
+ break;
+ default:
+ q->logMessage(format("Function '%1' is not implemented").arg(func));
+ break;
+ }
+
+ return ret;
+}
+
+ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
+ const QString &function, const QString &arguments)
+{
+ QStringList argumentsList = split_arg_list(arguments);
+
+ if (ProBlock *funcPtr = m_testFunctions.value(function, 0)) {
+ bool ok;
+ QStringList ret = evaluateFunction(funcPtr, argumentsList, &ok);
+ if (ok) {
+ if (ret.isEmpty()) {
+ return ProItem::ReturnTrue;
+ } else {
+ if (ret.first() != QLatin1String("false")) {
+ if (ret.first() == QLatin1String("true")) {
+ return ProItem::ReturnTrue;
+ } else {
+ bool ok;
+ int val = ret.first().toInt(&ok);
+ if (ok) {
+ if (val)
+ return ProItem::ReturnTrue;
+ } else {
+ q->logMessage(format("Unexpected return value from test '%1': %2")
+ .arg(function).arg(ret.join(QLatin1String(" :: "))));
+ }
+ }
+ }
+ }
+ }
+ return ProItem::ReturnFalse;
+ }
+
+ QString sep;
+ sep.append(Option::field_sep);
+ QStringList args;
+ for (int i = 0; i < argumentsList.count(); ++i)
+ args += expandVariableReferences(argumentsList[i]).join(sep);
+
+ enum TestFunc { T_REQUIRES=1, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
+ T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
+ T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE,
+ T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_MESSAGE, T_IF,
+ T_FOR, T_DEFINE_TEST, T_DEFINE_REPLACE };
+
+ static QHash<QString, int> functions;
+ if (functions.isEmpty()) {
+ functions.insert(QLatin1String("requires"), T_REQUIRES);
+ functions.insert(QLatin1String("greaterThan"), T_GREATERTHAN);
+ functions.insert(QLatin1String("lessThan"), T_LESSTHAN);
+ functions.insert(QLatin1String("equals"), T_EQUALS);
+ functions.insert(QLatin1String("isEqual"), T_EQUALS);
+ functions.insert(QLatin1String("exists"), T_EXISTS);
+ functions.insert(QLatin1String("export"), T_EXPORT);
+ functions.insert(QLatin1String("clear"), T_CLEAR);
+ functions.insert(QLatin1String("unset"), T_UNSET);
+ functions.insert(QLatin1String("eval"), T_EVAL);
+ functions.insert(QLatin1String("CONFIG"), T_CONFIG);
+ functions.insert(QLatin1String("if"), T_IF);
+ functions.insert(QLatin1String("isActiveConfig"), T_CONFIG);
+ functions.insert(QLatin1String("system"), T_SYSTEM);
+ functions.insert(QLatin1String("return"), T_RETURN);
+ functions.insert(QLatin1String("break"), T_BREAK);
+ functions.insert(QLatin1String("next"), T_NEXT);
+ functions.insert(QLatin1String("defined"), T_DEFINED);
+ functions.insert(QLatin1String("contains"), T_CONTAINS);
+ functions.insert(QLatin1String("infile"), T_INFILE);
+ functions.insert(QLatin1String("count"), T_COUNT);
+ functions.insert(QLatin1String("isEmpty"), T_ISEMPTY);
+ functions.insert(QLatin1String("load"), T_LOAD); //v
+ functions.insert(QLatin1String("include"), T_INCLUDE); //v
+ functions.insert(QLatin1String("debug"), T_DEBUG);
+ functions.insert(QLatin1String("message"), T_MESSAGE); //v
+ functions.insert(QLatin1String("warning"), T_MESSAGE); //v
+ functions.insert(QLatin1String("error"), T_MESSAGE); //v
+ functions.insert(QLatin1String("for"), T_FOR); //v
+ functions.insert(QLatin1String("defineTest"), T_DEFINE_TEST); //v
+ functions.insert(QLatin1String("defineReplace"), T_DEFINE_REPLACE); //v
+ }
+
+ TestFunc func_t = (TestFunc)functions.value(function);
+
+ switch (func_t) {
+ case T_DEFINE_TEST:
+ m_definingTest = true;
+ goto defineFunc;
+ case T_DEFINE_REPLACE:
+ m_definingTest = false;
+ defineFunc:
+ if (args.count() != 1) {
+ q->logMessage(format("%s(function) requires one argument.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ m_definingFunc = args.first();
+ return ProItem::ReturnTrue;
+ case T_DEFINED:
+ if (args.count() < 1 || args.count() > 2) {
+ q->logMessage(format("defined(function, [\"test\"|\"replace\"])"
+ " requires one or two arguments."));
+ return ProItem::ReturnFalse;
+ }
+ if (args.count() > 1) {
+ if (args[1] == QLatin1String("test"))
+ return returnBool(m_testFunctions.contains(args[0]));
+ else if (args[1] == QLatin1String("replace"))
+ return returnBool(m_replaceFunctions.contains(args[0]));
+ q->logMessage(format("defined(function, type):"
+ " unexpected type [%1].\n").arg(args[1]));
+ return ProItem::ReturnFalse;
+ }
+ return returnBool(m_replaceFunctions.contains(args[0])
+ || m_testFunctions.contains(args[0]));
+ case T_RETURN:
+ m_returnValue = args;
+ // It is "safe" to ignore returns - due to qmake brokeness
+ // they cannot be used to terminate loops anyway.
+ if (m_skipLevel || m_cumulative)
+ return ProItem::ReturnTrue;
+ if (m_valuemapStack.isEmpty()) {
+ q->logMessage(format("unexpected return()."));
+ return ProItem::ReturnFalse;
+ }
+ return ProItem::ReturnReturn;
+ case T_EXPORT:
+ if (m_skipLevel && !m_cumulative)
+ return ProItem::ReturnTrue;
+ if (args.count() != 1) {
+ q->logMessage(format("export(variable) requires one argument."));
+ return ProItem::ReturnFalse;
+ }
+ for (int i = 0; i < m_valuemapStack.size(); ++i) {
+ m_valuemapStack[i][args[0]] = m_valuemap[args[0]];
+ m_filevaluemapStack[i][currentProFile()][args[0]] =
+ m_filevaluemap[currentProFile()][args[0]];
+ }
+ return ProItem::ReturnTrue;
+#if 0
+ case T_INFILE:
+ case T_REQUIRES:
+ case T_EVAL:
+#endif
+ case T_FOR: {
+ if (m_cumulative) // This is a no-win situation, so just pretend it's no loop
+ return ProItem::ReturnTrue;
+ if (m_skipLevel)
+ return ProItem::ReturnFalse;
+ if (args.count() > 2 || args.count() < 1) {
+ q->logMessage(format("for({var, list|var, forever|ever})"
+ " requires one or two arguments."));
+ return ProItem::ReturnFalse;
+ }
+ ProLoop loop;
+ loop.infinite = false;
+ loop.index = 0;
+ QString it_list;
+ if (args.count() == 1) {
+ doVariableReplace(&args[0]);
+ it_list = args[0];
+ if (args[0] != QLatin1String("ever")) {
+ q->logMessage(format("for({var, list|var, forever|ever})"
+ " requires one or two arguments."));
+ return ProItem::ReturnFalse;
+ }
+ it_list = QLatin1String("forever");
+ } else {
+ loop.variable = args[0];
+ loop.oldVarVal = m_valuemap.value(loop.variable);
+ doVariableReplace(&args[1]);
+ it_list = args[1];
+ }
+ loop.list = m_valuemap[it_list];
+ if (loop.list.isEmpty()) {
+ if (it_list == QLatin1String("forever")) {
+ loop.infinite = true;
+ } else {
+ int dotdot = it_list.indexOf(QLatin1String(".."));
+ if (dotdot != -1) {
+ bool ok;
+ int start = it_list.left(dotdot).toInt(&ok);
+ if (ok) {
+ int end = it_list.mid(dotdot+2).toInt(&ok);
+ if (ok) {
+ if (start < end) {
+ for (int i = start; i <= end; i++)
+ loop.list << QString::number(i);
+ } else {
+ for (int i = start; i >= end; i--)
+ loop.list << QString::number(i);
+ }
+ }
+ }
+ }
+ }
+ }
+ m_loopStack.push(loop);
+ m_sts.condition = true;
+ return ProItem::ReturnLoop;
+ }
+ case T_BREAK:
+ if (m_skipLevel)
+ return ProItem::ReturnFalse;
+ if (!m_loopStack.isEmpty())
+ return ProItem::ReturnBreak;
+ // ### missing: breaking out of multiline blocks
+ q->logMessage(format("unexpected break()."));
+ return ProItem::ReturnFalse;
+ case T_NEXT:
+ if (m_skipLevel)
+ return ProItem::ReturnFalse;
+ if (!m_loopStack.isEmpty())
+ return ProItem::ReturnNext;
+ q->logMessage(format("unexpected next()."));
+ return ProItem::ReturnFalse;
+ case T_IF: {
+ if (args.count() != 1) {
+ q->logMessage(format("if(condition) requires one argument."));
+ return ProItem::ReturnFalse;
+ }
+ QString cond = args.first();
+ bool escaped = false; // This is more than qmake does
+ bool quoted = false;
+ bool ret = true;
+ bool orOp = false;
+ bool invert = false;
+ bool isFunc = false;
+ int parens = 0;
+ QString test;
+ test.reserve(20);
+ QString args;
+ args.reserve(50);
+ const QChar *d = cond.unicode();
+ const QChar *ed = d + cond.length();
+ while (d < ed) {
+ ushort c = (d++)->unicode();
+ if (!escaped) {
+ if (c == '\\') {
+ escaped = true;
+ args += c; // Assume no-one quotes the test name
+ continue;
+ } else if (c == '"') {
+ quoted = !quoted;
+ args += c; // Ditto
+ continue;
+ }
+ } else {
+ escaped = false;
+ }
+ if (quoted) {
+ args += c; // Ditto
+ } else {
+ bool isOp = false;
+ if (c == '(') {
+ isFunc = true;
+ if (parens)
+ args += c;
+ ++parens;
+ } else if (c == ')') {
+ --parens;
+ if (parens)
+ args += c;
+ } else if (!parens) {
+ if (c == ':' || c == '|')
+ isOp = true;
+ else if (c == '!')
+ invert = true;
+ else
+ test += c;
+ } else {
+ args += c;
+ }
+ if (!parens && (isOp || d == ed)) {
+ // Yes, qmake doesn't shortcut evaluations here. We can't, either,
+ // as some test functions have side effects.
+ bool success;
+ if (isFunc) {
+ success = evaluateConditionalFunction(test, args);
+ } else {
+ success = isActiveConfig(test, true);
+ }
+ success ^= invert;
+ if (orOp)
+ ret |= success;
+ else
+ ret &= success;
+ orOp = (c == '|');
+ invert = false;
+ isFunc = false;
+ test.clear();
+ args.clear();
+ }
+ }
+ }
+ return returnBool(ret);
+ }
+ case T_CONFIG: {
+ if (args.count() < 1 || args.count() > 2) {
+ q->logMessage(format("CONFIG(config) requires one or two arguments."));
+ return ProItem::ReturnFalse;
+ }
+ if (args.count() == 1) {
+ //cond = isActiveConfig(args.first()); XXX
+ return ProItem::ReturnFalse;
+ }
+ const QStringList mutuals = args[1].split(QLatin1Char('|'));
+ const QStringList &configs = valuesDirect(QLatin1String("CONFIG"));
+ for (int i = configs.size() - 1; i >= 0; i--) {
+ for (int mut = 0; mut < mutuals.count(); mut++) {
+ if (configs[i] == mutuals[mut].trimmed()) {
+ return returnBool(configs[i] == args[0]);
+ }
+ }
+ }
+ return ProItem::ReturnFalse;
+ }
+ case T_CONTAINS: {
+ if (args.count() < 2 || args.count() > 3) {
+ q->logMessage(format("contains(var, val) requires two or three arguments."));
+ return ProItem::ReturnFalse;
+ }
+
+ QRegExp regx(args[1]);
+ const QStringList &l = values(args.first());
+ if (args.count() == 2) {
+ for (int i = 0; i < l.size(); ++i) {
+ const QString val = l[i];
+ if (regx.exactMatch(val) || val == args[1]) {
+ return ProItem::ReturnTrue;
+ }
+ }
+ } else {
+ const QStringList mutuals = args[2].split(QLatin1Char('|'));
+ for (int i = l.size() - 1; i >= 0; i--) {
+ const QString val = l[i];
+ for (int mut = 0; mut < mutuals.count(); mut++) {
+ if (val == mutuals[mut].trimmed()) {
+ return returnBool(regx.exactMatch(val) || val == args[1]);
+ }
+ }
+ }
+ }
+ return ProItem::ReturnFalse;
+ }
+ case T_COUNT: {
+ if (args.count() != 2 && args.count() != 3) {
+ q->logMessage(format("count(var, count, op=\"equals\") requires two or three arguments."));
+ return ProItem::ReturnFalse;
+ }
+ if (args.count() == 3) {
+ QString comp = args[2];
+ if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
+ return returnBool(values(args.first()).count() > args[1].toInt());
+ } else if (comp == QLatin1String(">=")) {
+ return returnBool(values(args.first()).count() >= args[1].toInt());
+ } else if (comp == QLatin1String("<") || comp == QLatin1String("lessThan")) {
+ return returnBool(values(args.first()).count() < args[1].toInt());
+ } else if (comp == QLatin1String("<=")) {
+ return returnBool(values(args.first()).count() <= args[1].toInt());
+ } else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
+ || comp == QLatin1String("=") || comp == QLatin1String("==")) {
+ return returnBool(values(args.first()).count() == args[1].toInt());
+ } else {
+ q->logMessage(format("unexpected modifier to count(%2)").arg(comp));
+ return ProItem::ReturnFalse;
+ }
+ }
+ return returnBool(values(args.first()).count() == args[1].toInt());
+ }
+ case T_GREATERTHAN:
+ case T_LESSTHAN: {
+ if (args.count() != 2) {
+ q->logMessage(format("%1(variable, value) requires two arguments.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ QString rhs(args[1]), lhs(values(args[0]).join(QString(Option::field_sep)));
+ bool ok;
+ int rhs_int = rhs.toInt(&ok);
+ if (ok) { // do integer compare
+ int lhs_int = lhs.toInt(&ok);
+ if (ok) {
+ if (func_t == T_GREATERTHAN)
+ return returnBool(lhs_int > rhs_int);
+ return returnBool(lhs_int < rhs_int);
+ }
+ }
+ if (func_t == T_GREATERTHAN)
+ return returnBool(lhs > rhs);
+ return returnBool(lhs < rhs);
+ }
+ case T_EQUALS:
+ if (args.count() != 2) {
+ q->logMessage(format("%1(variable, value) requires two arguments.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ return returnBool(values(args[0]).join(QString(Option::field_sep)) == args[1]);
+ case T_CLEAR: {
+ if (m_skipLevel && !m_cumulative)
+ return ProItem::ReturnFalse;
+ if (args.count() != 1) {
+ q->logMessage(format("%1(variable) requires one argument.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ QHash<QString, QStringList>::Iterator it = m_valuemap.find(args[0]);
+ if (it == m_valuemap.end())
+ return ProItem::ReturnFalse;
+ it->clear();
+ return ProItem::ReturnTrue;
+ }
+ case T_UNSET: {
+ if (m_skipLevel && !m_cumulative)
+ return ProItem::ReturnFalse;
+ if (args.count() != 1) {
+ q->logMessage(format("%1(variable) requires one argument.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ QHash<QString, QStringList>::Iterator it = m_valuemap.find(args[0]);
+ if (it == m_valuemap.end())
+ return ProItem::ReturnFalse;
+ m_valuemap.erase(it);
+ return ProItem::ReturnTrue;
+ }
+ case T_INCLUDE: {
+ if (m_skipLevel && !m_cumulative)
+ return ProItem::ReturnFalse;
+ QString parseInto;
+ // the third optional argument to include() controls warnings
+ // and is not used here
+ if ((args.count() == 2) || (args.count() == 3)) {
+ parseInto = args[1];
+ } else if (args.count() != 1) {
+ q->logMessage(format("include(file) requires one, two or three arguments."));
+ return ProItem::ReturnFalse;
+ }
+ QString fileName = args.first();
+ // ### this breaks if we have include(c:/reallystupid.pri) but IMHO that's really bad style.
+ QDir currentProPath(currentDirectory());
+ fileName = QDir::cleanPath(currentProPath.absoluteFilePath(fileName));
+ State sts = m_sts;
+ bool ok = evaluateFile(fileName);
+ m_sts = sts;
+ return returnBool(ok);
+ }
+ case T_LOAD: {
+ if (m_skipLevel && !m_cumulative)
+ return ProItem::ReturnFalse;
+ QString parseInto;
+ bool ignore_error = false;
+ if (args.count() == 2) {
+ QString sarg = args[1];
+ ignore_error = (!sarg.compare(QLatin1String("true"), Qt::CaseInsensitive) || sarg.toInt());
+ } else if (args.count() != 1) {
+ q->logMessage(format("load(feature) requires one or two arguments."));
+ return ProItem::ReturnFalse;
+ }
+ // XXX ignore_error unused
+ return returnBool(evaluateFeatureFile(args.first()));
+ }
+ case T_DEBUG:
+ // Yup - do nothing. Nothing is going to enable debug output anyway.
+ return ProItem::ReturnFalse;
+ case T_MESSAGE: {
+ if (args.count() != 1) {
+ q->logMessage(format("%1(message) requires one argument.").arg(function));
+ return ProItem::ReturnFalse;
+ }
+ QString msg = fixEnvVariables(args.first());
+ q->fileMessage(QString::fromLatin1("Project %1: %2").arg(function.toUpper(), msg));
+ // ### Consider real termination in non-cumulative mode
+ return returnBool(function != QLatin1String("error"));
+ }
+#if 0 // Way too dangerous to enable.
+ case T_SYSTEM: {
+ if (args.count() != 1) {
+ q->logMessage(format("system(exec) requires one argument."));
+ ProItem::ReturnFalse;
+ }
+ return returnBool(system(args.first().toLatin1().constData()) == 0);
+ }
+#endif
+ case T_ISEMPTY: {
+ if (args.count() != 1) {
+ q->logMessage(format("isEmpty(var) requires one argument."));
+ return ProItem::ReturnFalse;
+ }
+ QStringList sl = values(args.first());
+ if (sl.count() == 0) {
+ return ProItem::ReturnTrue;
+ } else if (sl.count() > 0) {
+ QString var = sl.first();
+ if (var.isEmpty())
+ return ProItem::ReturnTrue;
+ }
+ return ProItem::ReturnFalse;
+ }
+ case T_EXISTS: {
+ if (args.count() != 1) {
+ q->logMessage(format("exists(file) requires one argument."));
+ return ProItem::ReturnFalse;
+ }
+ QString file = args.first();
+ file = Option::fixPathToLocalOS(file);
+
+ if (QFile::exists(file)) {
+ return ProItem::ReturnTrue;
+ }
+ //regular expression I guess
+ QString dirstr = currentDirectory();
+ int slsh = file.lastIndexOf(Option::dir_sep);
+ if (slsh != -1) {
+ dirstr = file.left(slsh+1);
+ file = file.right(file.length() - slsh - 1);
+ }
+ if (file.contains(QLatin1Char('*')) || file.contains(QLatin1Char('?')))
+ if (!QDir(dirstr).entryList(QStringList(file)).isEmpty())
+ return ProItem::ReturnTrue;
+
+ return ProItem::ReturnFalse;
+ }
+ case 0:
+ q->logMessage(format("'%1' is not a recognized test function").arg(function));
+ return ProItem::ReturnFalse;
+ default:
+ q->logMessage(format("Function '%1' is not implemented").arg(function));
+ return ProItem::ReturnFalse;
+ }
+}
+
+QStringList ProFileEvaluator::Private::values(const QString &variableName,
+ const QHash<QString, QStringList> &place,
+ const ProFile *pro) const
+{
+ if (variableName == QLatin1String("LITERAL_WHITESPACE")) //a real space in a token
+ return QStringList(QLatin1String("\t"));
+ if (variableName == QLatin1String("LITERAL_DOLLAR")) //a real $
+ return QStringList(QLatin1String("$"));
+ if (variableName == QLatin1String("LITERAL_HASH")) //a real #
+ return QStringList(QLatin1String("#"));
+ if (variableName == QLatin1String("OUT_PWD")) //the out going dir
+ return QStringList(m_outputDir);
+ if (variableName == QLatin1String("PWD") || //current working dir (of _FILE_)
+ variableName == QLatin1String("IN_PWD"))
+ return QStringList(currentDirectory());
+ if (variableName == QLatin1String("DIR_SEPARATOR"))
+ return QStringList(Option::dir_sep);
+ if (variableName == QLatin1String("DIRLIST_SEPARATOR"))
+ return QStringList(Option::dirlist_sep);
+ if (variableName == QLatin1String("_LINE_")) //parser line number
+ return QStringList(QString::number(m_lineNo));
+ if (variableName == QLatin1String("_FILE_")) //parser file; qmake is a bit weird here
+ return QStringList(m_profileStack.size() == 1 ? pro->fileName() : QFileInfo(pro->fileName()).fileName());
+ if (variableName == QLatin1String("_DATE_")) //current date/time
+ return QStringList(QDateTime::currentDateTime().toString());
+ if (variableName == QLatin1String("_PRO_FILE_"))
+ return QStringList(m_origfile);
+ if (variableName == QLatin1String("_PRO_FILE_PWD_"))
+ return QStringList(QFileInfo(m_origfile).absolutePath());
+ if (variableName == QLatin1String("_QMAKE_CACHE_"))
+ return QStringList(); // FIXME?
+ if (variableName.startsWith(QLatin1String("QMAKE_HOST."))) {
+ QString ret, type = variableName.mid(11);
+#if defined(Q_OS_WIN32)
+ if (type == QLatin1String("os")) {
+ ret = QLatin1String("Windows");
+ } else if (type == QLatin1String("name")) {
+ DWORD name_length = 1024;
+ wchar_t name[1024];
+ if (GetComputerName(name, &name_length))
+ ret = QString::fromWCharArray(name);
+ } else if (type == QLatin1String("version") || type == QLatin1String("version_string")) {
+ QSysInfo::WinVersion ver = QSysInfo::WindowsVersion;
+ if (type == QLatin1String("version"))
+ ret = QString::number(ver);
+ else if (ver == QSysInfo::WV_Me)
+ ret = QLatin1String("WinMe");
+ else if (ver == QSysInfo::WV_95)
+ ret = QLatin1String("Win95");
+ else if (ver == QSysInfo::WV_98)
+ ret = QLatin1String("Win98");
+ else if (ver == QSysInfo::WV_NT)
+ ret = QLatin1String("WinNT");
+ else if (ver == QSysInfo::WV_2000)
+ ret = QLatin1String("Win2000");
+ else if (ver == QSysInfo::WV_2000)
+ ret = QLatin1String("Win2003");
+ else if (ver == QSysInfo::WV_XP)
+ ret = QLatin1String("WinXP");
+ else if (ver == QSysInfo::WV_VISTA)
+ ret = QLatin1String("WinVista");
+ else
+ ret = QLatin1String("Unknown");
+ } else if (type == QLatin1String("arch")) {
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ switch(info.wProcessorArchitecture) {
+#ifdef PROCESSOR_ARCHITECTURE_AMD64
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ ret = QLatin1String("x86_64");
+ break;
+#endif
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ ret = QLatin1String("x86");
+ break;
+ case PROCESSOR_ARCHITECTURE_IA64:
+#ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
+ case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+#endif
+ ret = QLatin1String("IA64");
+ break;
+ default:
+ ret = QLatin1String("Unknown");
+ break;
+ }
+ }
+#elif defined(Q_OS_UNIX)
+ struct utsname name;
+ if (!uname(&name)) {
+ if (type == QLatin1String("os"))
+ ret = QString::fromLatin1(name.sysname);
+ else if (type == QLatin1String("name"))
+ ret = QString::fromLatin1(name.nodename);
+ else if (type == QLatin1String("version"))
+ ret = QString::fromLatin1(name.release);
+ else if (type == QLatin1String("version_string"))
+ ret = QString::fromLatin1(name.version);
+ else if (type == QLatin1String("arch"))
+ ret = QString::fromLatin1(name.machine);
+ }
+#endif
+ return QStringList(ret);
+ }
+
+ QStringList result = place[variableName];
+ if (result.isEmpty()) {
+ if (variableName == QLatin1String("TARGET")) {
+ result.append(QFileInfo(m_origfile).baseName());
+ } else if (variableName == QLatin1String("TEMPLATE")) {
+ result.append(QLatin1String("app"));
+ } else if (variableName == QLatin1String("QMAKE_DIR_SEP")) {
+ result.append(Option::dirlist_sep);
+ }
+ }
+ return result;
+}
+
+QStringList ProFileEvaluator::Private::values(const QString &variableName) const
+{
+ return values(variableName, m_valuemap, currentProFile());
+}
+
+QStringList ProFileEvaluator::Private::values(const QString &variableName, const ProFile *pro) const
+{
+ return values(variableName, m_filevaluemap[pro], pro);
+}
+
+ProFile *ProFileEvaluator::parsedProFile(const QString &fileName)
+{
+ QFileInfo fi(fileName);
+ if (fi.exists()) {
+ QString fn = QDir::cleanPath(fi.absoluteFilePath());
+ foreach (const ProFile *pf, d->m_profileStack)
+ if (pf->fileName() == fn) {
+ errorMessage(d->format("circular inclusion of %1").arg(fn));
+ return 0;
+ }
+ ProFile *pro = new ProFile(fn);
+ if (d->read(pro))
+ return pro;
+ delete pro;
+ }
+ return 0;
+}
+
+void ProFileEvaluator::releaseParsedProFile(ProFile *proFile)
+{
+ delete proFile;
+}
+
+bool ProFileEvaluator::Private::evaluateFile(const QString &fileName)
+{
+ ProFile *pro = q->parsedProFile(fileName);
+ if (pro) {
+ m_profileStack.push(pro);
+ bool ok = (pro->Accept(this) == ProItem::ReturnTrue);
+ m_profileStack.pop();
+ q->releaseParsedProFile(pro);
+ return ok;
+ } else {
+ return false;
+ }
+}
+
+bool ProFileEvaluator::Private::evaluateFeatureFile(const QString &fileName)
+{
+ QString fn;
+ foreach (const QString &path, qmakeFeaturePaths()) {
+ QString fname = path + QLatin1Char('/') + fileName;
+ if (QFileInfo(fname).exists()) {
+ fn = fname;
+ break;
+ }
+ fname += QLatin1String(".prf");
+ if (QFileInfo(fname).exists()) {
+ fn = fname;
+ break;
+ }
+ }
+ if (fn.isEmpty())
+ return false;
+ bool cumulative = m_cumulative;
+ m_cumulative = false;
+ bool ok = evaluateFile(fn);
+ m_cumulative = cumulative;
+ return ok;
+}
+
+QString ProFileEvaluator::Private::format(const char *fmt) const
+{
+ ProFile *pro = currentProFile();
+ QString fileName = pro ? pro->fileName() : QLatin1String("Not a file");
+ int lineNumber = pro ? m_lineNo : 0;
+ return QString::fromLatin1("%1(%2):").arg(fileName).arg(lineNumber) + QString::fromAscii(fmt);
+}
+
+
+///////////////////////////////////////////////////////////////////////
+//
+// ProFileEvaluator
+//
+///////////////////////////////////////////////////////////////////////
+
+ProFileEvaluator::ProFileEvaluator()
+ : d(new Private(this))
+{
+ Option::init();
+}
+
+ProFileEvaluator::~ProFileEvaluator()
+{
+ delete d;
+}
+
+bool ProFileEvaluator::contains(const QString &variableName) const
+{
+ return d->m_valuemap.contains(variableName);
+}
+
+inline QStringList fixEnvVariables(const QStringList &x)
+{
+ QStringList ret;
+ foreach (const QString &str, x)
+ ret << Option::fixString(str, Option::FixEnvVars);
+ return ret;
+}
+
+
+QStringList ProFileEvaluator::values(const QString &variableName) const
+{
+ return fixEnvVariables(d->values(variableName));
+}
+
+QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const
+{
+ return fixEnvVariables(d->values(variableName, pro));
+}
+
+QStringList ProFileEvaluator::absolutePathValues(
+ const QString &variable, const QString &baseDirectory) const
+{
+ QStringList result;
+ foreach (const QString &el, values(variable)) {
+ const QFileInfo info = QFileInfo(baseDirectory, el);
+ if (info.isDir())
+ result << QDir::cleanPath(info.absoluteFilePath());
+ }
+ return result;
+}
+
+QStringList ProFileEvaluator::absoluteFileValues(
+ const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
+ const ProFile *pro) const
+{
+ QStringList result;
+ foreach (const QString &el, pro ? values(variable, pro) : values(variable)) {
+ QFileInfo info(el);
+ if (info.isAbsolute()) {
+ if (info.exists()) {
+ result << QDir::cleanPath(el);
+ goto next;
+ }
+ } else {
+ foreach (const QString &dir, searchDirs) {
+ QFileInfo info(dir, el);
+ if (info.isFile()) {
+ result << QDir::cleanPath(info.filePath());
+ goto next;
+ }
+ }
+ if (baseDirectory.isEmpty())
+ goto next;
+ info = QFileInfo(baseDirectory, el);
+ }
+ {
+ QFileInfo baseInfo(info.absolutePath());
+ if (baseInfo.exists()) {
+ QString wildcard = info.fileName();
+ if (wildcard.contains(QLatin1Char('*')) || wildcard.contains(QLatin1Char('?'))) {
+ QDir theDir(QDir::cleanPath(baseInfo.filePath()));
+ foreach (const QString &fn, theDir.entryList(QStringList(wildcard)))
+ if (fn != QLatin1String(".") && fn != QLatin1String(".."))
+ result << theDir.absoluteFilePath(fn);
+ }
+ }
+ }
+ next: ;
+ }
+ return result;
+}
+
+ProFileEvaluator::TemplateType ProFileEvaluator::templateType()
+{
+ QStringList templ = values(QLatin1String("TEMPLATE"));
+ if (templ.count() >= 1) {
+ const QString &t = templ.last();
+ if (!t.compare(QLatin1String("app"), Qt::CaseInsensitive))
+ return TT_Application;
+ if (!t.compare(QLatin1String("lib"), Qt::CaseInsensitive))
+ return TT_Library;
+ if (!t.compare(QLatin1String("script"), Qt::CaseInsensitive))
+ return TT_Script;
+ if (!t.compare(QLatin1String("subdirs"), Qt::CaseInsensitive))
+ return TT_Subdirs;
+ }
+ return TT_Unknown;
+}
+
+bool ProFileEvaluator::queryProFile(ProFile *pro)
+{
+ return d->read(pro);
+}
+
+bool ProFileEvaluator::accept(ProFile *pro)
+{
+ return pro->Accept(d);
+}
+
+QString ProFileEvaluator::propertyValue(const QString &name) const
+{
+ return d->propertyValue(name);
+}
+
+namespace {
+ template<class K, class T> void insert(QHash<K,T> *out, const QHash<K,T> &in)
+ {
+ typename QHash<K,T>::const_iterator i = in.begin();
+ while (i != in.end()) {
+ out->insert(i.key(), i.value());
+ ++i;
+ }
+ }
+} // anon namespace
+
+void ProFileEvaluator::addVariables(const QHash<QString, QStringList> &variables)
+{
+ insert(&(d->m_valuemap), variables);
+}
+
+void ProFileEvaluator::addProperties(const QHash<QString, QString> &properties)
+{
+ insert(&(d->m_properties), properties);
+}
+
+void ProFileEvaluator::logMessage(const QString &message)
+{
+ if (d->m_verbose && !d->m_skipLevel)
+ fprintf(stderr, "%s\n", qPrintable(message));
+}
+
+void ProFileEvaluator::fileMessage(const QString &message)
+{
+ if (!d->m_skipLevel)
+ fprintf(stderr, "%s\n", qPrintable(message));
+}
+
+void ProFileEvaluator::errorMessage(const QString &message)
+{
+ if (!d->m_skipLevel)
+ fprintf(stderr, "%s\n", qPrintable(message));
+}
+
+void ProFileEvaluator::setVerbose(bool on)
+{
+ d->m_verbose = on;
+}
+
+void ProFileEvaluator::setCumulative(bool on)
+{
+ d->m_cumulative = on;
+}
+
+void ProFileEvaluator::setOutputDir(const QString &dir)
+{
+ d->m_outputDir = dir;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/profileevaluator.h b/src/linguist/shared/profileevaluator.h
new file mode 100644
index 000000000..3bceec108
--- /dev/null
+++ b/src/linguist/shared/profileevaluator.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROFILEEVALUATOR_H
+#define PROFILEEVALUATOR_H
+
+#include "proitems.h"
+#include "abstractproitemvisitor.h"
+
+#include <QtCore/QIODevice>
+#include <QtCore/QHash>
+#include <QtCore/QStringList>
+#include <QtCore/QStack>
+
+#if (!defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) && !defined(__SUNPRO_CC)
+# define HAVE_TEMPLATE_CLASS_FRIENDS
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class ProFileEvaluator
+{
+#ifdef HAVE_TEMPLATE_CLASS_FRIENDS
+private:
+#else
+public:
+#endif
+ class Private;
+
+public:
+ enum TemplateType {
+ TT_Unknown = 0,
+ TT_Application,
+ TT_Library,
+ TT_Script,
+ TT_Subdirs
+ };
+
+ ProFileEvaluator();
+ virtual ~ProFileEvaluator();
+
+ ProFileEvaluator::TemplateType templateType();
+ virtual bool contains(const QString &variableName) const;
+ void setVerbose(bool on); // Default is false
+ void setCumulative(bool on); // Default is true!
+ void setOutputDir(const QString &dir); // Default is empty
+
+ bool queryProFile(ProFile *pro);
+ bool accept(ProFile *pro);
+
+ void addVariables(const QHash<QString, QStringList> &variables);
+ void addProperties(const QHash<QString, QString> &properties);
+ QStringList values(const QString &variableName) const;
+ QStringList values(const QString &variableName, const ProFile *pro) const;
+ QStringList absolutePathValues(const QString &variable, const QString &baseDirectory) const;
+ QStringList absoluteFileValues(
+ const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
+ const ProFile *pro) const;
+ QString propertyValue(const QString &val) const;
+
+ // for our descendents
+ virtual ProFile *parsedProFile(const QString &fileName);
+ virtual void releaseParsedProFile(ProFile *proFile);
+ virtual void logMessage(const QString &msg);
+ virtual void errorMessage(const QString &msg); // .pro parse errors
+ virtual void fileMessage(const QString &msg); // error() and message() from .pro file
+
+private:
+ Private *d;
+
+#ifdef HAVE_TEMPLATE_CLASS_FRIENDS
+ template<typename T> friend class QTypeInfo;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // PROFILEEVALUATOR_H
diff --git a/src/linguist/shared/proitems.cpp b/src/linguist/shared/proitems.cpp
new file mode 100644
index 000000000..934b43190
--- /dev/null
+++ b/src/linguist/shared/proitems.cpp
@@ -0,0 +1,358 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "proitems.h"
+#include "abstractproitemvisitor.h"
+
+#include <QtCore/QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+// --------------- ProItem ------------
+void ProItem::setComment(const QString &comment)
+{
+ m_comment = comment;
+}
+
+QString ProItem::comment() const
+{
+ return m_comment;
+}
+
+// --------------- ProBlock ----------------
+
+ProBlock::ProBlock(ProBlock *parent)
+{
+ m_blockKind = 0;
+ m_parent = parent;
+ m_refCount = 1;
+}
+
+ProBlock::~ProBlock()
+{
+ foreach (ProItem *itm, m_proitems)
+ if (itm->kind() == BlockKind)
+ static_cast<ProBlock *>(itm)->deref();
+ else
+ delete itm;
+}
+
+void ProBlock::appendItem(ProItem *proitem)
+{
+ m_proitems << proitem;
+}
+
+void ProBlock::setItems(const QList<ProItem *> &proitems)
+{
+ m_proitems = proitems;
+}
+
+QList<ProItem *> ProBlock::items() const
+{
+ return m_proitems;
+}
+
+void ProBlock::setBlockKind(int blockKind)
+{
+ m_blockKind = blockKind;
+}
+
+int ProBlock::blockKind() const
+{
+ return m_blockKind;
+}
+
+void ProBlock::setParent(ProBlock *parent)
+{
+ m_parent = parent;
+}
+
+ProBlock *ProBlock::parent() const
+{
+ return m_parent;
+}
+
+ProItem::ProItemKind ProBlock::kind() const
+{
+ return ProItem::BlockKind;
+}
+
+ProItem::ProItemReturn ProBlock::Accept(AbstractProItemVisitor *visitor)
+{
+ if (visitor->visitBeginProBlock(this) == ReturnSkip)
+ return ReturnTrue;
+ ProItemReturn rt = ReturnTrue;
+ for (int i = 0; i < m_proitems.count(); ++i) {
+ rt = m_proitems.at(i)->Accept(visitor);
+ if (rt != ReturnTrue && rt != ReturnFalse) {
+ if (rt == ReturnLoop) {
+ rt = ReturnTrue;
+ while (visitor->visitProLoopIteration())
+ for (int j = i; ++j < m_proitems.count(); ) {
+ rt = m_proitems.at(j)->Accept(visitor);
+ if (rt != ReturnTrue && rt != ReturnFalse) {
+ if (rt == ReturnNext) {
+ rt = ReturnTrue;
+ break;
+ }
+ if (rt == ReturnBreak)
+ rt = ReturnTrue;
+ goto do_break;
+ }
+ }
+ do_break:
+ visitor->visitProLoopCleanup();
+ }
+ break;
+ }
+ }
+ visitor->visitEndProBlock(this);
+ return rt;
+}
+
+// --------------- ProVariable ----------------
+ProVariable::ProVariable(const QString &name, ProBlock *parent)
+ : ProBlock(parent)
+{
+ setBlockKind(ProBlock::VariableKind);
+ m_variable = name;
+ m_variableKind = SetOperator;
+}
+
+void ProVariable::setVariableOperator(VariableOperator variableKind)
+{
+ m_variableKind = variableKind;
+}
+
+ProVariable::VariableOperator ProVariable::variableOperator() const
+{
+ return m_variableKind;
+}
+
+void ProVariable::setVariable(const QString &name)
+{
+ m_variable = name;
+}
+
+QString ProVariable::variable() const
+{
+ return m_variable;
+}
+
+ProItem::ProItemReturn ProVariable::Accept(AbstractProItemVisitor *visitor)
+{
+ visitor->visitBeginProVariable(this);
+ foreach (ProItem *item, m_proitems)
+ item->Accept(visitor); // cannot fail
+ visitor->visitEndProVariable(this);
+ return ReturnTrue;
+}
+
+// --------------- ProValue ----------------
+ProValue::ProValue(const QString &value, ProVariable *variable)
+{
+ m_variable = variable;
+ m_value = value;
+}
+
+void ProValue::setValue(const QString &value)
+{
+ m_value = value;
+}
+
+QString ProValue::value() const
+{
+ return m_value;
+}
+
+void ProValue::setVariable(ProVariable *variable)
+{
+ m_variable = variable;
+}
+
+ProVariable *ProValue::variable() const
+{
+ return m_variable;
+}
+
+ProItem::ProItemKind ProValue::kind() const
+{
+ return ProItem::ValueKind;
+}
+
+ProItem::ProItemReturn ProValue::Accept(AbstractProItemVisitor *visitor)
+{
+ visitor->visitProValue(this);
+ return ReturnTrue;
+}
+
+// --------------- ProFunction ----------------
+ProFunction::ProFunction(const QString &text)
+{
+ m_text = text;
+}
+
+void ProFunction::setText(const QString &text)
+{
+ m_text = text;
+}
+
+QString ProFunction::text() const
+{
+ return m_text;
+}
+
+ProItem::ProItemKind ProFunction::kind() const
+{
+ return ProItem::FunctionKind;
+}
+
+ProItem::ProItemReturn ProFunction::Accept(AbstractProItemVisitor *visitor)
+{
+ return visitor->visitProFunction(this);
+}
+
+// --------------- ProCondition ----------------
+ProCondition::ProCondition(const QString &text)
+{
+ m_text = text;
+}
+
+void ProCondition::setText(const QString &text)
+{
+ m_text = text;
+}
+
+QString ProCondition::text() const
+{
+ return m_text;
+}
+
+ProItem::ProItemKind ProCondition::kind() const
+{
+ return ProItem::ConditionKind;
+}
+
+ProItem::ProItemReturn ProCondition::Accept(AbstractProItemVisitor *visitor)
+{
+ visitor->visitProCondition(this);
+ return ReturnTrue;
+}
+
+// --------------- ProOperator ----------------
+ProOperator::ProOperator(OperatorKind operatorKind)
+{
+ m_operatorKind = operatorKind;
+}
+
+void ProOperator::setOperatorKind(OperatorKind operatorKind)
+{
+ m_operatorKind = operatorKind;
+}
+
+ProOperator::OperatorKind ProOperator::operatorKind() const
+{
+ return m_operatorKind;
+}
+
+ProItem::ProItemKind ProOperator::kind() const
+{
+ return ProItem::OperatorKind;
+}
+
+ProItem::ProItemReturn ProOperator::Accept(AbstractProItemVisitor *visitor)
+{
+ visitor->visitProOperator(this);
+ return ReturnTrue;
+}
+
+// --------------- ProFile ----------------
+ProFile::ProFile(const QString &fileName)
+ : ProBlock(0)
+{
+ m_modified = false;
+ setBlockKind(ProBlock::ProFileKind);
+ m_fileName = fileName;
+
+ QFileInfo fi(fileName);
+ m_displayFileName = fi.fileName();
+ m_directoryName = fi.absolutePath();
+}
+
+ProFile::~ProFile()
+{
+}
+
+QString ProFile::displayFileName() const
+{
+ return m_displayFileName;
+}
+
+QString ProFile::fileName() const
+{
+ return m_fileName;
+}
+
+QString ProFile::directoryName() const
+{
+ return m_directoryName;
+}
+
+void ProFile::setModified(bool modified)
+{
+ m_modified = modified;
+}
+
+bool ProFile::isModified() const
+{
+ return m_modified;
+}
+
+ProItem::ProItemReturn ProFile::Accept(AbstractProItemVisitor *visitor)
+{
+ ProItemReturn rt;
+ if ((rt = visitor->visitBeginProFile(this)) != ReturnTrue)
+ return rt;
+ ProBlock::Accept(visitor); // cannot fail
+ return visitor->visitEndProFile(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/proitems.h b/src/linguist/shared/proitems.h
new file mode 100644
index 000000000..12fdb7e72
--- /dev/null
+++ b/src/linguist/shared/proitems.h
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROITEMS_H
+#define PROITEMS_H
+
+#include <QtCore/QString>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+struct AbstractProItemVisitor;
+
+class ProItem
+{
+public:
+ enum ProItemKind {
+ ValueKind,
+ FunctionKind,
+ ConditionKind,
+ OperatorKind,
+ BlockKind
+ };
+
+ enum ProItemReturn {
+ ReturnFalse,
+ ReturnTrue,
+ ReturnBreak,
+ ReturnNext,
+ ReturnLoop,
+ ReturnSkip,
+ ReturnReturn
+ };
+
+ ProItem() : m_lineNumber(0) {}
+ virtual ~ProItem() {}
+
+ virtual ProItemKind kind() const = 0;
+
+ void setComment(const QString &comment);
+ QString comment() const;
+
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor) = 0;
+ int lineNumber() const { return m_lineNumber; }
+ void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; }
+
+private:
+ QString m_comment;
+ int m_lineNumber;
+};
+
+class ProBlock : public ProItem
+{
+public:
+ enum ProBlockKind {
+ NormalKind = 0x00,
+ ScopeKind = 0x01,
+ ScopeContentsKind = 0x02,
+ VariableKind = 0x04,
+ ProFileKind = 0x08,
+ FunctionBodyKind = 0x10,
+ SingleLine = 0x80
+ };
+
+ ProBlock(ProBlock *parent);
+ ~ProBlock();
+
+ void appendItem(ProItem *proitem);
+ void setItems(const QList<ProItem *> &proitems);
+ QList<ProItem *> items() const;
+
+ void setBlockKind(int blockKind);
+ int blockKind() const;
+
+ void setParent(ProBlock *parent);
+ ProBlock *parent() const;
+
+ void ref() { ++m_refCount; }
+ void deref() { if (!--m_refCount) delete this; }
+
+ ProItem::ProItemKind kind() const;
+
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
+protected:
+ QList<ProItem *> m_proitems;
+private:
+ ProBlock *m_parent;
+ int m_blockKind;
+ int m_refCount;
+};
+
+class ProVariable : public ProBlock
+{
+public:
+ enum VariableOperator {
+ AddOperator = 0,
+ RemoveOperator = 1,
+ ReplaceOperator = 2,
+ SetOperator = 3,
+ UniqueAddOperator = 4
+ };
+
+ ProVariable(const QString &name, ProBlock *parent);
+
+ void setVariableOperator(VariableOperator variableKind);
+ VariableOperator variableOperator() const;
+
+ void setVariable(const QString &name);
+ QString variable() const;
+
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
+private:
+ VariableOperator m_variableKind;
+ QString m_variable;
+};
+
+class ProValue : public ProItem
+{
+public:
+ ProValue(const QString &value, ProVariable *variable);
+
+ void setValue(const QString &value);
+ QString value() const;
+
+ void setVariable(ProVariable *variable);
+ ProVariable *variable() const;
+
+ ProItem::ProItemKind kind() const;
+
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
+private:
+ QString m_value;
+ ProVariable *m_variable;
+};
+
+class ProFunction : public ProItem
+{
+public:
+ explicit ProFunction(const QString &text);
+
+ void setText(const QString &text);
+ QString text() const;
+
+ ProItem::ProItemKind kind() const;
+
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
+private:
+ QString m_text;
+};
+
+class ProCondition : public ProItem
+{
+public:
+ explicit ProCondition(const QString &text);
+
+ void setText(const QString &text);
+ QString text() const;
+
+ ProItem::ProItemKind kind() const;
+
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
+private:
+ QString m_text;
+};
+
+class ProOperator : public ProItem
+{
+public:
+ enum OperatorKind {
+ OrOperator = 1,
+ NotOperator = 2
+ };
+
+ explicit ProOperator(OperatorKind operatorKind);
+
+ void setOperatorKind(OperatorKind operatorKind);
+ OperatorKind operatorKind() const;
+
+ ProItem::ProItemKind kind() const;
+
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
+private:
+ OperatorKind m_operatorKind;
+};
+
+class ProFile : public ProBlock
+{
+public:
+ explicit ProFile(const QString &fileName);
+ ~ProFile();
+
+ QString displayFileName() const;
+ QString fileName() const;
+ QString directoryName() const;
+
+ void setModified(bool modified);
+ bool isModified() const;
+
+ virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
+
+private:
+ QString m_fileName;
+ QString m_displayFileName;
+ QString m_directoryName;
+ bool m_modified;
+};
+
+QT_END_NAMESPACE
+
+#endif // PROITEMS_H
diff --git a/src/linguist/shared/proparser.pri b/src/linguist/shared/proparser.pri
new file mode 100644
index 000000000..372247e46
--- /dev/null
+++ b/src/linguist/shared/proparser.pri
@@ -0,0 +1,12 @@
+
+INCLUDEPATH *= $$PWD
+
+HEADERS += \
+ $$PWD/abstractproitemvisitor.h \
+ $$PWD/proitems.h \
+ $$PWD/profileevaluator.h \
+ $$PWD/proparserutils.h
+
+SOURCES += \
+ $$PWD/proitems.cpp \
+ $$PWD/profileevaluator.cpp
diff --git a/src/linguist/shared/proparserutils.h b/src/linguist/shared/proparserutils.h
new file mode 100644
index 000000000..b82398a4b
--- /dev/null
+++ b/src/linguist/shared/proparserutils.h
@@ -0,0 +1,324 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROPARSERUTILS_H
+#define PROPARSERUTILS_H
+
+#include <QtCore/QDir>
+#ifndef QT_BOOTSTRAPPED
+#include <QtCore/QLibraryInfo>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BOOTSTRAPPED
+// this is a stripped down version of the one found in QtCore
+class QLibraryInfo
+{
+public:
+ enum LibraryLocation
+ {
+ PrefixPath,
+ DocumentationPath,
+ HeadersPath,
+ LibrariesPath,
+ BinariesPath,
+ PluginsPath,
+ DataPath,
+ TranslationsPath,
+ SettingsPath,
+ DemosPath,
+ ExamplesPath
+ };
+ static QString location(LibraryLocation);
+};
+#endif
+
+// Pre- and postcondition macros
+#define PRE(cond) do {if (!(cond))qt_assert(#cond,__FILE__,__LINE__);} while (0)
+#define POST(cond) do {if (!(cond))qt_assert(#cond,__FILE__,__LINE__);} while (0)
+
+// This struct is from qmake, but we are not using everything.
+struct Option
+{
+ //simply global convenience
+ //static QString libtool_ext;
+ //static QString pkgcfg_ext;
+ //static QString prf_ext;
+ //static QString prl_ext;
+ //static QString ui_ext;
+ //static QStringList h_ext;
+ //static QStringList cpp_ext;
+ //static QString h_moc_ext;
+ //static QString cpp_moc_ext;
+ //static QString obj_ext;
+ //static QString lex_ext;
+ //static QString yacc_ext;
+ //static QString h_moc_mod;
+ //static QString cpp_moc_mod;
+ //static QString lex_mod;
+ //static QString yacc_mod;
+ static QString dir_sep;
+ static QString dirlist_sep;
+ static QString qmakespec;
+ static QChar field_sep;
+
+ enum TARG_MODE { TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, TARG_MAC9_MODE, TARG_QNX6_MODE };
+ static TARG_MODE target_mode;
+ //static QString pro_ext;
+ //static QString res_ext;
+
+ static void init()
+ {
+#ifdef Q_OS_WIN
+ Option::dirlist_sep = QLatin1Char(';');
+ Option::dir_sep = QLatin1Char('\\');
+#else
+ Option::dirlist_sep = QLatin1Char(':');
+ Option::dir_sep = QLatin1Char(QLatin1Char('/'));
+#endif
+ Option::qmakespec = QString::fromLatin1(qgetenv("QMAKESPEC").data());
+ Option::field_sep = QLatin1Char(' ');
+ }
+
+ enum StringFixFlags {
+ FixNone = 0x00,
+ FixEnvVars = 0x01,
+ FixPathCanonicalize = 0x02,
+ FixPathToLocalSeparators = 0x04,
+ FixPathToTargetSeparators = 0x08
+ };
+ static QString fixString(QString string, uchar flags);
+
+ inline static QString fixPathToLocalOS(const QString &in, bool fix_env = true, bool canonical = true)
+ {
+ uchar flags = FixPathToLocalSeparators;
+ if (fix_env)
+ flags |= FixEnvVars;
+ if (canonical)
+ flags |= FixPathCanonicalize;
+ return fixString(in, flags);
+ }
+};
+#if defined(Q_OS_WIN32)
+Option::TARG_MODE Option::target_mode = Option::TARG_WIN_MODE;
+#elif defined(Q_OS_MAC)
+Option::TARG_MODE Option::target_mode = Option::TARG_MACX_MODE;
+#elif defined(Q_OS_QNX6)
+Option::TARG_MODE Option::target_mode = Option::TARG_QNX6_MODE;
+#else
+Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE;
+#endif
+
+QString Option::qmakespec;
+QString Option::dirlist_sep;
+QString Option::dir_sep;
+QChar Option::field_sep;
+
+static void insertUnique(QHash<QString, QStringList> *map,
+ const QString &key, const QStringList &value)
+{
+ QStringList &sl = (*map)[key];
+ foreach (const QString &str, value)
+ if (!sl.contains(str))
+ sl.append(str);
+}
+
+static void removeEach(QHash<QString, QStringList> *map,
+ const QString &key, const QStringList &value)
+{
+ QStringList &sl = (*map)[key];
+ foreach (const QString &str, value)
+ sl.removeAll(str);
+}
+
+/*
+ See ProFileEvaluator::Private::visitProValue(...)
+
+static QStringList replaceInList(const QStringList &varList, const QRegExp &regexp,
+ const QString &replace, bool global)
+{
+ QStringList resultList = varList;
+
+ for (QStringList::Iterator varit = resultList.begin(); varit != resultList.end();) {
+ if (varit->contains(regexp)) {
+ *varit = varit->replace(regexp, replace);
+ if (varit->isEmpty())
+ varit = resultList.erase(varit);
+ else
+ ++varit;
+ if (!global)
+ break;
+ } else {
+ ++varit;
+ }
+ }
+ return resultList;
+}
+*/
+
+inline QString fixEnvVariables(const QString &x)
+{
+ return Option::fixString(x, Option::FixEnvVars);
+}
+
+inline QStringList splitPathList(const QString &paths)
+{
+ return paths.split(Option::dirlist_sep);
+}
+
+static QStringList split_arg_list(QString params)
+{
+ int quote = 0;
+ QStringList args;
+
+ const ushort LPAREN = '(';
+ const ushort RPAREN = ')';
+ const ushort SINGLEQUOTE = '\'';
+ const ushort DOUBLEQUOTE = '"';
+ const ushort COMMA = ',';
+ const ushort SPACE = ' ';
+ //const ushort TAB = '\t';
+
+ ushort unicode;
+ const QChar *params_data = params.data();
+ const int params_len = params.length();
+ int last = 0;
+ while (last < params_len && ((params_data+last)->unicode() == SPACE
+ /*|| (params_data+last)->unicode() == TAB*/))
+ ++last;
+ for (int x = last, parens = 0; x <= params_len; x++) {
+ unicode = (params_data+x)->unicode();
+ if (x == params_len) {
+ while (x && (params_data+(x-1))->unicode() == SPACE)
+ --x;
+ QString mid(params_data+last, x-last);
+ if (quote) {
+ if (mid[0] == quote && mid[(int)mid.length()-1] == quote)
+ mid = mid.mid(1, mid.length()-2);
+ quote = 0;
+ }
+ args << mid;
+ break;
+ }
+ if (unicode == LPAREN) {
+ --parens;
+ } else if (unicode == RPAREN) {
+ ++parens;
+ } else if (quote && unicode == quote) {
+ quote = 0;
+ } else if (!quote && (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE)) {
+ quote = unicode;
+ }
+ if (!parens && !quote && unicode == COMMA) {
+ QString mid = params.mid(last, x - last).trimmed();
+ args << mid;
+ last = x+1;
+ while (last < params_len && ((params_data+last)->unicode() == SPACE
+ /*|| (params_data+last)->unicode() == TAB*/))
+ ++last;
+ }
+ }
+ return args;
+}
+
+static QStringList split_value_list(const QString &vals, bool do_semicolon=false)
+{
+ QString build;
+ QStringList ret;
+ QStack<char> quote;
+
+ const ushort LPAREN = '(';
+ const ushort RPAREN = ')';
+ const ushort SINGLEQUOTE = '\'';
+ const ushort DOUBLEQUOTE = '"';
+ const ushort BACKSLASH = '\\';
+ const ushort SEMICOLON = ';';
+
+ ushort unicode;
+ const QChar *vals_data = vals.data();
+ const int vals_len = vals.length();
+ for (int x = 0, parens = 0; x < vals_len; x++) {
+ unicode = vals_data[x].unicode();
+ if (x != (int)vals_len-1 && unicode == BACKSLASH &&
+ (vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) {
+ build += vals_data[x++]; //get that 'escape'
+ } else if (!quote.isEmpty() && unicode == quote.top()) {
+ quote.pop();
+ } else if (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE) {
+ quote.push(unicode);
+ } else if (unicode == RPAREN) {
+ --parens;
+ } else if (unicode == LPAREN) {
+ ++parens;
+ }
+
+ if (!parens && quote.isEmpty() && ((do_semicolon && unicode == SEMICOLON) ||
+ vals_data[x] == Option::field_sep)) {
+ ret << build;
+ build.clear();
+ } else {
+ build += vals_data[x];
+ }
+ }
+ if (!build.isEmpty())
+ ret << build;
+ return ret;
+}
+
+static QStringList qmake_mkspec_paths()
+{
+ QStringList ret;
+ const QString concat = QDir::separator() + QLatin1String("mkspecs");
+ QByteArray qmakepath = qgetenv("QMAKEPATH");
+ if (!qmakepath.isEmpty()) {
+ const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath));
+ for (QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
+ ret << ((*it) + concat);
+ }
+ ret << QLibraryInfo::location(QLibraryInfo::DataPath) + concat;
+
+ return ret;
+}
+
+QT_END_NAMESPACE
+
+#endif // PROPARSERUTILS_H
diff --git a/src/linguist/shared/qm.cpp b/src/linguist/shared/qm.cpp
new file mode 100644
index 000000000..0b4bd9e32
--- /dev/null
+++ b/src/linguist/shared/qm.cpp
@@ -0,0 +1,803 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+
+#ifndef QT_BOOTSTRAPPED
+#include <QtCore/QCoreApplication>
+#endif
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QTextCodec>
+
+QT_BEGIN_NAMESPACE
+
+// magic number for the file
+static const int MagicLength = 16;
+static const uchar magic[MagicLength] = {
+ 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
+ 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd
+};
+
+
+namespace {
+
+enum Tag {
+ Tag_End = 1,
+ Tag_SourceText16 = 2,
+ Tag_Translation = 3,
+ Tag_Context16 = 4,
+ Tag_Obsolete1 = 5,
+ Tag_SourceText = 6,
+ Tag_Context = 7,
+ Tag_Comment = 8,
+ Tag_Obsolete2 = 9
+};
+
+enum Prefix {
+ NoPrefix,
+ Hash,
+ HashContext,
+ HashContextSourceText,
+ HashContextSourceTextComment
+};
+
+} // namespace anon
+
+static uint elfHash(const QByteArray &ba)
+{
+ const uchar *k = (const uchar *)ba.data();
+ uint h = 0;
+ uint g;
+
+ if (k) {
+ while (*k) {
+ h = (h << 4) + *k++;
+ if ((g = (h & 0xf0000000)) != 0)
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ }
+ if (!h)
+ h = 1;
+ return h;
+}
+
+class ByteTranslatorMessage
+{
+public:
+ ByteTranslatorMessage(
+ const QByteArray &context,
+ const QByteArray &sourceText,
+ const QByteArray &comment,
+ const QStringList &translations) :
+ m_context(context),
+ m_sourcetext(sourceText),
+ m_comment(comment),
+ m_translations(translations)
+ {}
+ const QByteArray &context() const { return m_context; }
+ const QByteArray &sourceText() const { return m_sourcetext; }
+ const QByteArray &comment() const { return m_comment; }
+ const QStringList &translations() const { return m_translations; }
+ bool operator<(const ByteTranslatorMessage& m) const;
+
+private:
+ QByteArray m_context;
+ QByteArray m_sourcetext;
+ QByteArray m_comment;
+ QStringList m_translations;
+};
+
+Q_DECLARE_TYPEINFO(ByteTranslatorMessage, Q_MOVABLE_TYPE);
+
+bool ByteTranslatorMessage::operator<(const ByteTranslatorMessage& m) const
+{
+ if (m_context != m.m_context)
+ return m_context < m.m_context;
+ if (m_sourcetext != m.m_sourcetext)
+ return m_sourcetext < m.m_sourcetext;
+ return m_comment < m.m_comment;
+}
+
+class Releaser
+{
+public:
+ struct Offset {
+ Offset()
+ : h(0), o(0)
+ {}
+ Offset(uint hash, uint offset)
+ : h(hash), o(offset)
+ {}
+
+ bool operator<(const Offset &other) const {
+ return (h != other.h) ? h < other.h : o < other.o;
+ }
+ bool operator==(const Offset &other) const {
+ return h == other.h && o == other.o;
+ }
+ uint h;
+ uint o;
+ };
+
+ enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88 };
+
+ Releaser() : m_codec(0) {}
+
+ void setCodecName(const QByteArray &codecName)
+ {
+ m_codec = QTextCodec::codecForName(codecName);
+ }
+
+ bool save(QIODevice *iod);
+
+ void insert(const TranslatorMessage &msg, const QStringList &tlns, bool forceComment);
+ void insertIdBased(const TranslatorMessage &message, const QStringList &tlns);
+
+ void squeeze(TranslatorSaveMode mode);
+
+ void setNumerusRules(const QByteArray &rules);
+
+private:
+ Q_DISABLE_COPY(Releaser)
+
+ // This should reproduce the byte array fetched from the source file, which
+ // on turn should be the same as passed to the actual tr(...) calls
+ QByteArray originalBytes(const QString &str, bool isUtf8) const;
+
+ void insertInternal(const TranslatorMessage &message, const QStringList &tlns,
+ bool forceComment, bool isUtf8);
+
+ static Prefix commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2);
+
+ static uint msgHash(const ByteTranslatorMessage &msg);
+
+ void writeMessage(const ByteTranslatorMessage & msg, QDataStream & stream,
+ TranslatorSaveMode strip, Prefix prefix) const;
+
+ // for squeezed but non-file data, this is what needs to be deleted
+ QByteArray m_messageArray;
+ QByteArray m_offsetArray;
+ QByteArray m_contextArray;
+ QMap<ByteTranslatorMessage, void *> m_messages;
+ QByteArray m_numerusRules;
+
+ // Used to reproduce the original bytes
+ QTextCodec *m_codec;
+};
+
+QByteArray Releaser::originalBytes(const QString &str, bool isUtf8) const
+{
+ if (str.isEmpty()) {
+ // Do not use QByteArray() here as the result of the serialization
+ // will be different.
+ return QByteArray("");
+ }
+ if (isUtf8)
+ return str.toUtf8();
+ return m_codec ? m_codec->fromUnicode(str) : str.toLatin1();
+}
+
+uint Releaser::msgHash(const ByteTranslatorMessage &msg)
+{
+ return elfHash(msg.sourceText() + msg.comment());
+}
+
+Prefix Releaser::commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2)
+{
+ if (msgHash(m1) != msgHash(m2))
+ return NoPrefix;
+ if (m1.context() != m2.context())
+ return Hash;
+ if (m1.sourceText() != m2.sourceText())
+ return HashContext;
+ if (m1.comment() != m2.comment())
+ return HashContextSourceText;
+ return HashContextSourceTextComment;
+}
+
+void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &stream,
+ TranslatorSaveMode mode, Prefix prefix) const
+{
+ for (int i = 0; i < msg.translations().count(); ++i)
+ stream << quint8(Tag_Translation) << msg.translations().at(i);
+
+ if (mode == SaveEverything)
+ prefix = HashContextSourceTextComment;
+
+ // lrelease produces "wrong" QM files for QByteArrays that are .isNull().
+ switch (prefix) {
+ default:
+ case HashContextSourceTextComment:
+ stream << quint8(Tag_Comment) << msg.comment();
+ // fall through
+ case HashContextSourceText:
+ stream << quint8(Tag_SourceText) << msg.sourceText();
+ // fall through
+ case HashContext:
+ stream << quint8(Tag_Context) << msg.context();
+ break;
+ }
+
+ stream << quint8(Tag_End);
+}
+
+
+bool Releaser::save(QIODevice *iod)
+{
+ QDataStream s(iod);
+ s.writeRawData((const char *)magic, MagicLength);
+
+ if (!m_offsetArray.isEmpty()) {
+ quint32 oas = quint32(m_offsetArray.size());
+ s << quint8(Hashes) << oas;
+ s.writeRawData(m_offsetArray.constData(), oas);
+ }
+ if (!m_messageArray.isEmpty()) {
+ quint32 mas = quint32(m_messageArray.size());
+ s << quint8(Messages) << mas;
+ s.writeRawData(m_messageArray.constData(), mas);
+ }
+ if (!m_contextArray.isEmpty()) {
+ quint32 cas = quint32(m_contextArray.size());
+ s << quint8(Contexts) << cas;
+ s.writeRawData(m_contextArray.constData(), cas);
+ }
+ if (!m_numerusRules.isEmpty()) {
+ quint32 nrs = m_numerusRules.size();
+ s << quint8(NumerusRules) << nrs;
+ s.writeRawData(m_numerusRules.constData(), nrs);
+ }
+ return true;
+}
+
+void Releaser::squeeze(TranslatorSaveMode mode)
+{
+ if (m_messages.isEmpty() && mode == SaveEverything)
+ return;
+
+ QMap<ByteTranslatorMessage, void *> messages = m_messages;
+
+ // re-build contents
+ m_messageArray.clear();
+ m_offsetArray.clear();
+ m_contextArray.clear();
+ m_messages.clear();
+
+ QMap<Offset, void *> offsets;
+
+ QDataStream ms(&m_messageArray, QIODevice::WriteOnly);
+ QMap<ByteTranslatorMessage, void *>::const_iterator it, next;
+ int cpPrev = 0, cpNext = 0;
+ for (it = messages.constBegin(); it != messages.constEnd(); ++it) {
+ cpPrev = cpNext;
+ next = it;
+ ++next;
+ if (next == messages.constEnd())
+ cpNext = 0;
+ else
+ cpNext = commonPrefix(it.key(), next.key());
+ offsets.insert(Offset(msgHash(it.key()), ms.device()->pos()), (void *)0);
+ writeMessage(it.key(), ms, mode, Prefix(qMax(cpPrev, cpNext + 1)));
+ }
+
+ QMap<Offset, void *>::Iterator offset;
+ offset = offsets.begin();
+ QDataStream ds(&m_offsetArray, QIODevice::WriteOnly);
+ while (offset != offsets.end()) {
+ Offset k = offset.key();
+ ++offset;
+ ds << quint32(k.h) << quint32(k.o);
+ }
+
+ if (mode == SaveStripped) {
+ QMap<QByteArray, int> contextSet;
+ for (it = messages.constBegin(); it != messages.constEnd(); ++it)
+ ++contextSet[it.key().context()];
+
+ quint16 hTableSize;
+ if (contextSet.size() < 200)
+ hTableSize = (contextSet.size() < 60) ? 151 : 503;
+ else if (contextSet.size() < 2500)
+ hTableSize = (contextSet.size() < 750) ? 1511 : 5003;
+ else
+ hTableSize = (contextSet.size() < 10000) ? 15013 : 3 * contextSet.size() / 2;
+
+ QMultiMap<int, QByteArray> hashMap;
+ QMap<QByteArray, int>::const_iterator c;
+ for (c = contextSet.constBegin(); c != contextSet.constEnd(); ++c)
+ hashMap.insert(elfHash(c.key()) % hTableSize, c.key());
+
+ /*
+ The contexts found in this translator are stored in a hash
+ table to provide fast lookup. The context array has the
+ following format:
+
+ quint16 hTableSize;
+ quint16 hTable[hTableSize];
+ quint8 contextPool[...];
+
+ The context pool stores the contexts as Pascal strings:
+
+ quint8 len;
+ quint8 data[len];
+
+ Let's consider the look-up of context "FunnyDialog". A
+ hash value between 0 and hTableSize - 1 is computed, say h.
+ If hTable[h] is 0, "FunnyDialog" is not covered by this
+ translator. Else, we check in the contextPool at offset
+ 2 * hTable[h] to see if "FunnyDialog" is one of the
+ contexts stored there, until we find it or we meet the
+ empty string.
+ */
+ m_contextArray.resize(2 + (hTableSize << 1));
+ QDataStream t(&m_contextArray, QIODevice::WriteOnly);
+
+ quint16 *hTable = new quint16[hTableSize];
+ memset(hTable, 0, hTableSize * sizeof(quint16));
+
+ t << hTableSize;
+ t.device()->seek(2 + (hTableSize << 1));
+ t << quint16(0); // the entry at offset 0 cannot be used
+ uint upto = 2;
+
+ QMap<int, QByteArray>::const_iterator entry = hashMap.constBegin();
+ while (entry != hashMap.constEnd()) {
+ int i = entry.key();
+ hTable[i] = quint16(upto >> 1);
+
+ do {
+ const char *con = entry.value().constData();
+ uint len = uint(entry.value().length());
+ len = qMin(len, 255u);
+ t << quint8(len);
+ t.writeRawData(con, len);
+ upto += 1 + len;
+ ++entry;
+ } while (entry != hashMap.constEnd() && entry.key() == i);
+ if (upto & 0x1) {
+ // offsets have to be even
+ t << quint8(0); // empty string
+ ++upto;
+ }
+ }
+ t.device()->seek(2);
+ for (int j = 0; j < hTableSize; j++)
+ t << hTable[j];
+ delete [] hTable;
+
+ if (upto > 131072) {
+ qWarning("Releaser::squeeze: Too many contexts");
+ m_contextArray.clear();
+ }
+ }
+}
+
+void Releaser::insertInternal(const TranslatorMessage &message, const QStringList &tlns,
+ bool forceComment, bool isUtf8)
+{
+ ByteTranslatorMessage bmsg(originalBytes(message.context(), isUtf8),
+ originalBytes(message.sourceText(), isUtf8),
+ originalBytes(message.comment(), isUtf8),
+ tlns);
+ if (!forceComment) {
+ ByteTranslatorMessage bmsg2(
+ bmsg.context(), bmsg.sourceText(), QByteArray(""), bmsg.translations());
+ if (!m_messages.contains(bmsg2)) {
+ m_messages.insert(bmsg2, 0);
+ return;
+ }
+ }
+ m_messages.insert(bmsg, 0);
+}
+
+void Releaser::insert(const TranslatorMessage &message, const QStringList &tlns, bool forceComment)
+{
+ insertInternal(message, tlns, forceComment, message.isUtf8());
+ if (message.isUtf8() && message.isNonUtf8())
+ insertInternal(message, tlns, forceComment, false);
+}
+
+void Releaser::insertIdBased(const TranslatorMessage &message, const QStringList &tlns)
+{
+ ByteTranslatorMessage bmsg("", originalBytes(message.id(), false), "", tlns);
+ m_messages.insert(bmsg, 0);
+}
+
+void Releaser::setNumerusRules(const QByteArray &rules)
+{
+ m_numerusRules = rules;
+}
+
+static quint8 read8(const uchar *data)
+{
+ return *data;
+}
+
+static quint32 read32(const uchar *data)
+{
+ return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
+}
+
+static void fromBytes(const char *str, int len, QTextCodec *codec, QTextCodec *utf8Codec,
+ QString *out, QString *utf8Out,
+ bool *isSystem, bool *isUtf8, bool *needs8Bit)
+{
+ for (int i = 0; i < len; ++i)
+ if (str[i] & 0x80) {
+ if (utf8Codec) {
+ QTextCodec::ConverterState cvtState;
+ *utf8Out = utf8Codec->toUnicode(str, len, &cvtState);
+ *isUtf8 = !cvtState.invalidChars;
+ }
+ QTextCodec::ConverterState cvtState;
+ *out = codec->toUnicode(str, len, &cvtState);
+ *isSystem = !cvtState.invalidChars;
+ *needs8Bit = true;
+ return;
+ }
+ *out = QString::fromLatin1(str, len);
+ *isSystem = true;
+ if (utf8Codec) {
+ *utf8Out = *out;
+ *isUtf8 = true;
+ }
+ *needs8Bit = false;
+}
+
+bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ QByteArray ba = dev.readAll();
+ const uchar *data = (uchar*)ba.data();
+ int len = ba.size();
+ if (len < MagicLength || memcmp(data, magic, MagicLength) != 0) {
+ cd.appendError(QLatin1String("QM-Format error: magic marker missing"));
+ return false;
+ }
+
+ enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88 };
+
+ // for squeezed but non-file data, this is what needs to be deleted
+ const uchar *messageArray = 0;
+ const uchar *offsetArray = 0;
+ const uchar *contextArray = 0;
+ const uchar *numerusRulesArray = 0;
+ uint messageLength = 0;
+ uint offsetLength = 0;
+ uint contextLength = 0;
+ uint numerusRulesLength = 0;
+
+ bool ok = true;
+ const uchar *end = data + len;
+
+ data += MagicLength;
+
+ while (data < end - 4) {
+ quint8 tag = read8(data++);
+ quint32 blockLen = read32(data);
+ //qDebug() << "TAG:" << tag << "BLOCKLEN:" << blockLen;
+ data += 4;
+ if (!tag || !blockLen)
+ break;
+ if (data + blockLen > end) {
+ ok = false;
+ break;
+ }
+
+ if (tag == Contexts) {
+ contextArray = data;
+ contextLength = blockLen;
+ //qDebug() << "CONTEXTS: " << contextLength << QByteArray((const char *)contextArray, contextLength).toHex();
+ } else if (tag == Hashes) {
+ offsetArray = data;
+ offsetLength = blockLen;
+ //qDebug() << "HASHES: " << offsetLength << QByteArray((const char *)offsetArray, offsetLength).toHex();
+ } else if (tag == Messages) {
+ messageArray = data;
+ messageLength = blockLen;
+ //qDebug() << "MESSAGES: " << messageLength << QByteArray((const char *)messageArray, messageLength).toHex();
+ } else if (tag == NumerusRules) {
+ numerusRulesArray = data;
+ numerusRulesLength = blockLen;
+ //qDebug() << "NUMERUSRULES: " << numerusRulesLength << QByteArray((const char *)numerusRulesArray, numerusRulesLength).toHex();
+ }
+
+ data += blockLen;
+ }
+
+
+ size_t numItems = offsetLength / (2 * sizeof(quint32));
+ //qDebug() << "NUMITEMS: " << numItems;
+
+ QTextCodec *codec = QTextCodec::codecForName(
+ cd.m_codecForSource.isEmpty() ? QByteArray("Latin1") : cd.m_codecForSource);
+ QTextCodec *utf8Codec = 0;
+ if (codec->name() != "UTF-8")
+ utf8Codec = QTextCodec::codecForName("UTF-8");
+
+ QString strProN = QLatin1String("%n");
+ QLocale::Language l;
+ QLocale::Country c;
+ Translator::languageAndCountry(translator.languageCode(), &l, &c);
+ QStringList numerusForms;
+ bool guessPlurals = true;
+ if (getNumerusInfo(l, c, 0, &numerusForms, 0))
+ guessPlurals = (numerusForms.count() == 1);
+
+ QString context, contextUtf8;
+ bool contextIsSystem, contextIsUtf8, contextNeeds8Bit;
+ QString sourcetext, sourcetextUtf8;
+ bool sourcetextIsSystem, sourcetextIsUtf8, sourcetextNeeds8Bit;
+ QString comment, commentUtf8;
+ bool commentIsSystem, commentIsUtf8, commentNeeds8Bit;
+ QStringList translations;
+
+ for (const uchar *start = offsetArray; start != offsetArray + (numItems << 3); start += 8) {
+ //quint32 hash = read32(start);
+ quint32 ro = read32(start + 4);
+ //qDebug() << "\nHASH:" << hash;
+ const uchar *m = messageArray + ro;
+
+ for (;;) {
+ uchar tag = read8(m++);
+ //qDebug() << "Tag:" << tag << " ADDR: " << m;
+ switch(tag) {
+ case Tag_End:
+ goto end;
+ case Tag_Translation: {
+ int len = read32(m);
+ if (len % 1) {
+ cd.appendError(QLatin1String("QM-Format error"));
+ return false;
+ }
+ m += 4;
+ QString str = QString((const QChar *)m, len/2);
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
+ for (int i = 0; i < str.length(); ++i)
+ str[i] = QChar((str.at(i).unicode() >> 8) +
+ ((str.at(i).unicode() << 8) & 0xff00));
+ }
+ translations << str;
+ m += len;
+ break;
+ }
+ case Tag_Obsolete1:
+ m += 4;
+ //qDebug() << "OBSOLETE";
+ break;
+ case Tag_SourceText: {
+ quint32 len = read32(m);
+ m += 4;
+ //qDebug() << "SOURCE LEN: " << len;
+ //qDebug() << "SOURCE: " << QByteArray((const char*)m, len);
+ fromBytes((const char*)m, len, codec, utf8Codec,
+ &sourcetext, &sourcetextUtf8,
+ &sourcetextIsSystem, &sourcetextIsUtf8, &sourcetextNeeds8Bit);
+ m += len;
+ break;
+ }
+ case Tag_Context: {
+ quint32 len = read32(m);
+ m += 4;
+ //qDebug() << "CONTEXT LEN: " << len;
+ //qDebug() << "CONTEXT: " << QByteArray((const char*)m, len);
+ fromBytes((const char*)m, len, codec, utf8Codec,
+ &context, &contextUtf8,
+ &contextIsSystem, &contextIsUtf8, &contextNeeds8Bit);
+ m += len;
+ break;
+ }
+ case Tag_Comment: {
+ quint32 len = read32(m);
+ m += 4;
+ //qDebug() << "COMMENT LEN: " << len;
+ //qDebug() << "COMMENT: " << QByteArray((const char*)m, len);
+ fromBytes((const char*)m, len, codec, utf8Codec,
+ &comment, &commentUtf8,
+ &commentIsSystem, &commentIsUtf8, &commentNeeds8Bit);
+ m += len;
+ break;
+ }
+ default:
+ //qDebug() << "UNKNOWN TAG" << tag;
+ break;
+ }
+ }
+ end:;
+ TranslatorMessage msg;
+ msg.setType(TranslatorMessage::Finished);
+ if (translations.count() > 1) {
+ // If guessPlurals is not false here, plural form discard messages
+ // will be spewn out later.
+ msg.setPlural(true);
+ } else if (guessPlurals) {
+ // This might cause false positives, so it is a fallback only.
+ if (sourcetext.contains(strProN))
+ msg.setPlural(true);
+ }
+ msg.setTranslations(translations);
+ translations.clear();
+ if (contextNeeds8Bit || sourcetextNeeds8Bit || commentNeeds8Bit) {
+ if (utf8Codec && contextIsUtf8 && sourcetextIsUtf8 && commentIsUtf8) {
+ // The message is utf-8, but file is not.
+ msg.setUtf8(true);
+ msg.setContext(contextUtf8);
+ msg.setSourceText(sourcetextUtf8);
+ msg.setComment(commentUtf8);
+ translator.append(msg);
+ continue;
+ }
+ if (!(contextIsSystem && sourcetextIsSystem && commentIsSystem)) {
+ cd.appendError(QLatin1String(
+ "Cannot read file with specified input codec"));
+ return false;
+ }
+ // The message is 8-bit in the file's encoding (utf-8 or not).
+ }
+ msg.setContext(context);
+ msg.setSourceText(sourcetext);
+ msg.setComment(comment);
+ translator.append(msg);
+ }
+ return ok;
+}
+
+
+
+static bool containsStripped(const Translator &translator, const TranslatorMessage &msg)
+{
+ foreach (const TranslatorMessage &tmsg, translator.messages())
+ if (tmsg.sourceText() == msg.sourceText()
+ && tmsg.context() == msg.context()
+ && tmsg.comment().isEmpty())
+ return true;
+ return false;
+}
+
+static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ Releaser releaser;
+ QLocale::Language l;
+ QLocale::Country c;
+ Translator::languageAndCountry(translator.languageCode(), &l, &c);
+ QByteArray rules;
+ if (getNumerusInfo(l, c, &rules, 0, 0))
+ releaser.setNumerusRules(rules);
+ releaser.setCodecName(translator.codecName());
+
+ int finished = 0;
+ int unfinished = 0;
+ int untranslated = 0;
+ int missingIds = 0;
+ int droppedData = 0;
+
+ for (int i = 0; i != translator.messageCount(); ++i) {
+ const TranslatorMessage &msg = translator.message(i);
+ TranslatorMessage::Type typ = msg.type();
+ if (typ != TranslatorMessage::Obsolete) {
+ if (cd.m_idBased && msg.id().isEmpty()) {
+ ++missingIds;
+ continue;
+ }
+ if (typ == TranslatorMessage::Unfinished) {
+ if (msg.translation().isEmpty() && !cd.m_idBased && cd.m_unTrPrefix.isEmpty()) {
+ ++untranslated;
+ continue;
+ } else {
+ if (cd.ignoreUnfinished())
+ continue;
+ ++unfinished;
+ }
+ } else {
+ ++finished;
+ }
+ QStringList tlns = msg.translations();
+ if (msg.type() == TranslatorMessage::Unfinished
+ && (cd.m_idBased || !cd.m_unTrPrefix.isEmpty()))
+ for (int j = 0; j < tlns.size(); ++j)
+ if (tlns.at(j).isEmpty())
+ tlns[j] = cd.m_unTrPrefix + msg.sourceText();
+ if (cd.m_idBased) {
+ if (!msg.context().isEmpty() || !msg.comment().isEmpty())
+ ++droppedData;
+ releaser.insertIdBased(msg, tlns);
+ } else {
+ // Drop the comment in (context, sourceText, comment),
+ // unless the context is empty,
+ // unless (context, sourceText, "") already exists or
+ // unless we already dropped the comment of (context,
+ // sourceText, comment0).
+ bool forceComment =
+ msg.comment().isEmpty()
+ || msg.context().isEmpty()
+ || containsStripped(translator, msg);
+ releaser.insert(msg, tlns, forceComment);
+ }
+ }
+ }
+
+ if (missingIds)
+ cd.appendError(QCoreApplication::translate("LRelease",
+ "Dropped %n message(s) which had no ID.", 0,
+ QCoreApplication::CodecForTr, missingIds));
+ if (droppedData)
+ cd.appendError(QCoreApplication::translate("LRelease",
+ "Excess context/disambiguation dropped from %n message(s).", 0,
+ QCoreApplication::CodecForTr, droppedData));
+
+ releaser.squeeze(cd.m_saveMode);
+ bool saved = releaser.save(&dev);
+ if (saved && cd.isVerbose()) {
+ int generatedCount = finished + unfinished;
+ cd.appendError(QCoreApplication::translate("LRelease",
+ " Generated %n translation(s) (%1 finished and %2 unfinished)", 0,
+ QCoreApplication::CodecForTr, generatedCount).arg(finished).arg(unfinished));
+ if (untranslated)
+ cd.appendError(QCoreApplication::translate("LRelease",
+ " Ignored %n untranslated source text(s)", 0,
+ QCoreApplication::CodecForTr, untranslated));
+ }
+ return saved;
+}
+
+int initQM()
+{
+ Translator::FileFormat format;
+
+ format.extension = QLatin1String("qm");
+ format.description = QObject::tr("Compiled Qt translations");
+ format.fileType = Translator::FileFormat::TranslationBinary;
+ format.priority = 0;
+ format.loader = &loadQM;
+ format.saver = &saveQM;
+ Translator::registerFileFormat(format);
+
+ return 1;
+}
+
+Q_CONSTRUCTOR_FUNCTION(initQM)
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/qph.cpp b/src/linguist/shared/qph.cpp
new file mode 100644
index 000000000..b22aa3fe8
--- /dev/null
+++ b/src/linguist/shared/qph.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QDebug>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+#include <QtXml/QXmlStreamReader>
+#include <QtXml/QXmlStreamAttribute>
+
+QT_BEGIN_NAMESPACE
+
+class QPHReader : public QXmlStreamReader
+{
+public:
+ QPHReader(QIODevice &dev)
+ : QXmlStreamReader(&dev)
+ {}
+
+ // the "real thing"
+ bool read(Translator &translator);
+
+private:
+ bool isWhiteSpace() const
+ {
+ return isCharacters() && text().toString().trimmed().isEmpty();
+ }
+
+ enum DataField { NoField, SourceField, TargetField, DefinitionField };
+ DataField m_currentField;
+ QString m_currentSource;
+ QString m_currentTarget;
+ QString m_currentDefinition;
+};
+
+bool QPHReader::read(Translator &translator)
+{
+ m_currentField = NoField;
+ QString result;
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == QLatin1String("source")) {
+ m_currentField = SourceField;
+ } else if (name() == QLatin1String("target")) {
+ m_currentField = TargetField;
+ } else if (name() == QLatin1String("definition")) {
+ m_currentField = DefinitionField;
+ } else {
+ m_currentField = NoField;
+ if (name() == QLatin1String("QPH")) {
+ QXmlStreamAttributes atts = attributes();
+ translator.setLanguageCode(atts.value(QLatin1String("language")).toString());
+ translator.setSourceLanguageCode(atts.value(QLatin1String("sourcelanguage")).toString());
+ }
+ }
+ } else if (isWhiteSpace()) {
+ // ignore these
+ } else if (isCharacters()) {
+ if (m_currentField == SourceField)
+ m_currentSource += text();
+ else if (m_currentField == TargetField)
+ m_currentTarget += text();
+ else if (m_currentField == DefinitionField)
+ m_currentDefinition += text();
+ } else if (isEndElement() && name() == QLatin1String("phrase")) {
+ m_currentTarget.replace(QChar(Translator::TextVariantSeparator),
+ QChar(Translator::BinaryVariantSeparator));
+ TranslatorMessage msg;
+ msg.setSourceText(m_currentSource);
+ msg.setTranslation(m_currentTarget);
+ msg.setComment(m_currentDefinition);
+ translator.append(msg);
+ m_currentSource.clear();
+ m_currentTarget.clear();
+ m_currentDefinition.clear();
+ }
+ }
+ return true;
+}
+
+static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &)
+{
+ translator.setLocationsType(Translator::NoLocations);
+ QPHReader reader(dev);
+ return reader.read(translator);
+}
+
+static QString protect(const QString &str)
+{
+ QString result;
+ result.reserve(str.length() * 12 / 10);
+ for (int i = 0; i != str.size(); ++i) {
+ uint c = str.at(i).unicode();
+ switch (c) {
+ case '\"':
+ result += QLatin1String("&quot;");
+ break;
+ case '&':
+ result += QLatin1String("&amp;");
+ break;
+ case '>':
+ result += QLatin1String("&gt;");
+ break;
+ case '<':
+ result += QLatin1String("&lt;");
+ break;
+ case '\'':
+ result += QLatin1String("&apos;");
+ break;
+ default:
+ if (c < 0x20 && c != '\r' && c != '\n' && c != '\t')
+ result += QString(QLatin1String("&#%1;")).arg(c);
+ else // this also covers surrogates
+ result += QChar(c);
+ }
+ }
+ return result;
+}
+
+static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &)
+{
+ QTextStream t(&dev);
+ t.setCodec(QTextCodec::codecForName("UTF-8"));
+ t << "<!DOCTYPE QPH>\n<QPH";
+ QString languageCode = translator.languageCode();
+ if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
+ t << " language=\"" << languageCode << "\"";
+ languageCode = translator.sourceLanguageCode();
+ if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
+ t << " sourcelanguage=\"" << languageCode << "\"";
+ t << ">\n";
+ foreach (const TranslatorMessage &msg, translator.messages()) {
+ t << "<phrase>\n";
+ t << " <source>" << protect(msg.sourceText()) << "</source>\n";
+ QString str = msg.translations().join(QLatin1String("@"));
+ str.replace(QChar(Translator::BinaryVariantSeparator),
+ QChar(Translator::TextVariantSeparator));
+ t << " <target>" << protect(str)
+ << "</target>\n";
+ if (!msg.comment().isEmpty())
+ t << " <definition>" << protect(msg.comment()) << "</definition>\n";
+ t << "</phrase>\n";
+ }
+ t << "</QPH>\n";
+ return true;
+}
+
+int initQPH()
+{
+ Translator::FileFormat format;
+
+ format.extension = QLatin1String("qph");
+ format.description = QObject::tr("Qt Linguist 'Phrase Book'");
+ format.fileType = Translator::FileFormat::TranslationSource;
+ format.priority = 0;
+ format.loader = &loadQPH;
+ format.saver = &saveQPH;
+ Translator::registerFileFormat(format);
+
+ return 1;
+}
+
+Q_CONSTRUCTOR_FUNCTION(initQPH)
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/simtexth.cpp b/src/linguist/shared/simtexth.cpp
new file mode 100644
index 000000000..58ea2eef5
--- /dev/null
+++ b/src/linguist/shared/simtexth.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "simtexth.h"
+#include "translator.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QString>
+#include <QtCore/QList>
+
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<TranslatorMessage> TML;
+
+/*
+ How similar are two texts? The approach used here relies on co-occurrence
+ matrices and is very efficient.
+
+ Let's see with an example: how similar are "here" and "hither"? The
+ co-occurrence matrix M for "here" is M[h,e] = 1, M[e,r] = 1, M[r,e] = 1, and 0
+ elsewhere; the matrix N for "hither" is N[h,i] = 1, N[i,t] = 1, ...,
+ N[h,e] = 1, N[e,r] = 1, and 0 elsewhere. The union U of both matrices is the
+ matrix U[i,j] = max { M[i,j], N[i,j] }, and the intersection V is
+ V[i,j] = min { M[i,j], N[i,j] }. The score for a pair of texts is
+
+ score = (sum of V[i,j] over all i, j) / (sum of U[i,j] over all i, j),
+
+ a formula suggested by Arnt Gulbrandsen. Here we have
+
+ score = 2 / 6,
+
+ or one third.
+
+ The implementation differs from this in a few details. Most importantly,
+ repetitions are ignored; for input "xxx", M[x,x] equals 1, not 2.
+*/
+
+/*
+ Every character is assigned to one of 20 buckets so that the co-occurrence
+ matrix requires only 20 * 20 = 400 bits, not 256 * 256 = 65536 bits or even
+ more if we want the whole Unicode. Which character falls in which bucket is
+ arbitrary.
+
+ The second half of the table is a replica of the first half, because of
+ laziness.
+*/
+static const int indexOf[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// ! " # $ % & ' ( ) * + , - . /
+ 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0,
+// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15,
+// @ A B C D E F G H I J K L M N O
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+// P Q R S T U V W X Y Z [ \ ] ^ _
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+// ` a b c d e f g h i j k l m n o
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+// p q r s t u v w x y z { | } ~
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0,
+ 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0
+};
+
+/*
+ The entry bitCount[i] (for i between 0 and 255) is the number of bits used to
+ represent i in binary.
+*/
+static const int bitCount[256] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
+
+struct CoMatrix
+{
+ /*
+ The matrix has 20 * 20 = 400 entries. This requires 50 bytes, or 13
+ words. Some operations are performed on words for more efficiency.
+ */
+ union {
+ quint8 b[52];
+ quint32 w[13];
+ };
+
+ CoMatrix() { memset( b, 0, 52 ); }
+
+ CoMatrix(const QString &str)
+ {
+ QByteArray ba = str.toUtf8();
+ const char *text = ba.constData();
+ char c = '\0', d;
+ memset( b, 0, 52 );
+ /*
+ The Knuth books are not in the office only for show; they help make
+ loops 30% faster and 20% as readable.
+ */
+ while ( (d = *text) != '\0' ) {
+ setCoOccurence( c, d );
+ if ( (c = *++text) != '\0' ) {
+ setCoOccurence( d, c );
+ text++;
+ }
+ }
+ }
+
+ void setCoOccurence( char c, char d ) {
+ int k = indexOf[(uchar) c] + 20 * indexOf[(uchar) d];
+ b[k >> 3] |= (1 << (k & 0x7));
+ }
+
+ int worth() const {
+ int w = 0;
+ for ( int i = 0; i < 50; i++ )
+ w += bitCount[b[i]];
+ return w;
+ }
+};
+
+static inline CoMatrix reunion(const CoMatrix &m, const CoMatrix &n)
+{
+ CoMatrix p;
+ for (int i = 0; i < 13; ++i)
+ p.w[i] = m.w[i] | n.w[i];
+ return p;
+}
+
+static inline CoMatrix intersection(const CoMatrix &m, const CoMatrix &n)
+{
+ CoMatrix p;
+ for (int i = 0; i < 13; ++i)
+ p.w[i] = m.w[i] & n.w[i];
+ return p;
+}
+
+StringSimilarityMatcher::StringSimilarityMatcher(const QString &stringToMatch)
+{
+ m_cm = new CoMatrix(stringToMatch);
+ m_length = stringToMatch.length();
+}
+
+int StringSimilarityMatcher::getSimilarityScore(const QString &strCandidate)
+{
+ CoMatrix cmTarget(strCandidate);
+ int delta = qAbs(m_length - strCandidate.size());
+ int score = ( (intersection(*m_cm, cmTarget).worth() + 1) << 10 ) /
+ ( reunion(*m_cm, cmTarget).worth() + (delta << 1) + 1 );
+ return score;
+}
+
+StringSimilarityMatcher::~StringSimilarityMatcher()
+{
+ delete m_cm;
+}
+
+/**
+ * Checks how similar two strings are.
+ * The return value is the score, and a higher score is more similar
+ * than one with a low score.
+ * Linguist considers a score over 190 to be a good match.
+ * \sa StringSimilarityMatcher
+ */
+int getSimilarityScore(const QString &str1, const QString &str2)
+{
+ CoMatrix cmTarget(str2);
+ CoMatrix cm(str1);
+ int delta = qAbs(str1.size() - str2.size());
+
+ int score = ( (intersection(cm, cmTarget).worth() + 1) << 10 )
+ / ( reunion(cm, cmTarget).worth() + (delta << 1) + 1 );
+
+ return score;
+}
+
+CandidateList similarTextHeuristicCandidates(const Translator *tor,
+ const QString &text, int maxCandidates)
+{
+ QList<int> scores;
+ CandidateList candidates;
+
+ TML all = tor->translatedMessages();
+
+ foreach (const TranslatorMessage &mtm, all) {
+ if (mtm.type() == TranslatorMessage::Unfinished
+ || mtm.translation().isEmpty())
+ continue;
+
+ QString s = mtm.sourceText();
+ int score = getSimilarityScore(s, text);
+
+ if (candidates.size() == maxCandidates && score > scores[maxCandidates - 1] )
+ candidates.removeLast();
+
+ if (candidates.size() < maxCandidates && score >= textSimilarityThreshold) {
+ Candidate cand( s, mtm.translation() );
+
+ int i;
+ for (i = 0; i < candidates.size(); i++) {
+ if (score >= scores.at(i)) {
+ if (score == scores.at(i)) {
+ if (candidates.at(i) == cand)
+ goto continue_outer_loop;
+ } else {
+ break;
+ }
+ }
+ }
+ scores.insert(i, score);
+ candidates.insert(i, cand);
+ }
+ continue_outer_loop:
+ ;
+ }
+ return candidates;
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/simtexth.h b/src/linguist/shared/simtexth.h
new file mode 100644
index 000000000..efbe75036
--- /dev/null
+++ b/src/linguist/shared/simtexth.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIMTEXTH_H
+#define SIMTEXTH_H
+
+const int textSimilarityThreshold = 190;
+
+#include <QString>
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+
+class Translator;
+
+struct Candidate
+{
+ Candidate() {}
+ Candidate(const QString& source0, const QString &target0)
+ : source(source0), target(target0)
+ {}
+
+ QString source;
+ QString target;
+};
+
+inline bool operator==( const Candidate& c, const Candidate& d ) {
+ return c.target == d.target && c.source == d.source;
+}
+inline bool operator!=( const Candidate& c, const Candidate& d ) {
+ return !operator==( c, d );
+}
+
+typedef QList<Candidate> CandidateList;
+
+struct CoMatrix;
+/**
+ * This class is more efficient for searching through a large array of candidate strings, since we only
+ * have to construct the CoMatrix for the \a stringToMatch once,
+ * after that we just call getSimilarityScore(strCandidate).
+ * \sa getSimilarityScore
+ */
+class StringSimilarityMatcher {
+public:
+ StringSimilarityMatcher(const QString &stringToMatch);
+ ~StringSimilarityMatcher();
+ int getSimilarityScore(const QString &strCandidate);
+
+private:
+ CoMatrix *m_cm;
+ int m_length;
+};
+
+int getSimilarityScore(const QString &str1, const QString &str2);
+
+CandidateList similarTextHeuristicCandidates( const Translator *tor,
+ const QString &text,
+ int maxCandidates );
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/linguist/shared/translator.cpp b/src/linguist/shared/translator.cpp
new file mode 100644
index 000000000..1e5f2cba5
--- /dev/null
+++ b/src/linguist/shared/translator.cpp
@@ -0,0 +1,759 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+
+#include "simtexth.h"
+
+#include <iostream>
+
+#include <stdio.h>
+#ifdef Q_OS_WIN
+// required for _setmode, to avoid _O_TEXT streams...
+# ifdef Q_OS_WINCE
+# include <stdlib.h>
+# else
+# include <io.h> // for _setmode
+# include <fcntl.h> // for _O_BINARY
+# endif
+#endif
+
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+#include <private/qtranslator_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BOOTSTRAPPED
+QString QObject::tr(const char *sourceText, const char *, int n)
+{
+ QString ret = QString::fromLatin1(sourceText);
+ if (n >= 0)
+ ret.replace(QLatin1String("%n"), QString::number(n));
+ return ret;
+}
+#endif
+
+Translator::Translator() :
+ m_codec(QTextCodec::codecForName("ISO-8859-1")),
+ m_locationsType(AbsoluteLocations)
+{
+}
+
+void Translator::registerFileFormat(const FileFormat &format)
+{
+ //qDebug() << "Translator: Registering format " << format.extension;
+ QList<Translator::FileFormat> &formats = registeredFileFormats();
+ for (int i = 0; i < formats.size(); ++i)
+ if (format.fileType == formats[i].fileType && format.priority < formats[i].priority) {
+ formats.insert(i, format);
+ return;
+ }
+ formats.append(format);
+}
+
+QList<Translator::FileFormat> &Translator::registeredFileFormats()
+{
+ static QList<Translator::FileFormat> theFormats;
+ return theFormats;
+}
+
+void Translator::replaceSorted(const TranslatorMessage &msg)
+{
+ int index = find(msg);
+ if (index == -1)
+ appendSorted(msg);
+ else
+ m_messages[index] = msg;
+}
+
+void Translator::extend(const TranslatorMessage &msg)
+{
+ int index = find(msg);
+ if (index == -1) {
+ m_messages.append(msg);
+ } else {
+ TranslatorMessage &emsg = m_messages[index];
+ emsg.addReferenceUniq(msg.fileName(), msg.lineNumber());
+ if (!msg.extraComment().isEmpty()) {
+ QString cmt = emsg.extraComment();
+ if (!cmt.isEmpty())
+ cmt.append(QLatin1String("\n----------\n"));
+ cmt.append(msg.extraComment());
+ emsg.setExtraComment(cmt);
+ }
+ if (msg.isUtf8() != emsg.isUtf8()) {
+ emsg.setUtf8(true);
+ emsg.setNonUtf8(true);
+ }
+ }
+}
+
+void Translator::append(const TranslatorMessage &msg)
+{
+ m_messages.append(msg);
+}
+
+void Translator::appendSorted(const TranslatorMessage &msg)
+{
+ int msgLine = msg.lineNumber();
+ if (msgLine < 0) {
+ m_messages.append(msg);
+ return;
+ }
+
+ int bestIdx = 0; // Best insertion point found so far
+ int bestScore = 0; // Its category: 0 = no hit, 1 = pre or post, 2 = middle
+ int bestSize = 0; // The length of the region. Longer is better within one category.
+
+ // The insertion point to use should this region turn out to be the best one so far
+ int thisIdx = 0;
+ int thisScore = 0;
+ int thisSize = 0;
+ // Working vars
+ int prevLine = 0;
+ int curIdx = 0;
+ foreach (const TranslatorMessage &mit, m_messages) {
+ bool sameFile = mit.fileName() == msg.fileName() && mit.context() == msg.context();
+ int curLine;
+ if (sameFile && (curLine = mit.lineNumber()) >= prevLine) {
+ if (msgLine >= prevLine && msgLine < curLine) {
+ thisIdx = curIdx;
+ thisScore = thisSize ? 2 : 1;
+ }
+ ++thisSize;
+ prevLine = curLine;
+ } else {
+ if (thisSize) {
+ if (!thisScore) {
+ thisIdx = curIdx;
+ thisScore = 1;
+ }
+ if (thisScore > bestScore || (thisScore == bestScore && thisSize > bestSize)) {
+ bestIdx = thisIdx;
+ bestScore = thisScore;
+ bestSize = thisSize;
+ }
+ thisScore = 0;
+ thisSize = sameFile ? 1 : 0;
+ prevLine = 0;
+ }
+ }
+ ++curIdx;
+ }
+ if (thisSize && !thisScore) {
+ thisIdx = curIdx;
+ thisScore = 1;
+ }
+ if (thisScore > bestScore || (thisScore == bestScore && thisSize > bestSize))
+ m_messages.insert(thisIdx, msg);
+ else if (bestScore)
+ m_messages.insert(bestIdx, msg);
+ else
+ m_messages.append(msg);
+}
+
+static QString guessFormat(const QString &filename, const QString &format)
+{
+ if (format != QLatin1String("auto"))
+ return format;
+
+ foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
+ if (filename.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive))
+ return fmt.extension;
+ }
+
+ // the default format.
+ // FIXME: change to something more widely distributed later.
+ return QLatin1String("ts");
+}
+
+bool Translator::load(const QString &filename, ConversionData &cd, const QString &format)
+{
+ cd.m_sourceDir = QFileInfo(filename).absoluteDir();
+ cd.m_sourceFileName = filename;
+
+ QFile file;
+ if (filename.isEmpty() || filename == QLatin1String("-")) {
+#ifdef Q_OS_WIN
+ // QFile is broken for text files
+# ifdef Q_OS_WINCE
+ ::_setmode(stdin, _O_BINARY);
+# else
+ ::_setmode(0, _O_BINARY);
+# endif
+#endif
+ if (!file.open(stdin, QIODevice::ReadOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot open stdin!? (%1)")
+ .arg(file.errorString()));
+ return false;
+ }
+ } else {
+ file.setFileName(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot open %1: %2")
+ .arg(filename, file.errorString()));
+ return false;
+ }
+ }
+
+ QString fmt = guessFormat(filename, format);
+
+ foreach (const FileFormat &format, registeredFileFormats()) {
+ if (fmt == format.extension) {
+ if (format.loader)
+ return (*format.loader)(*this, file, cd);
+ cd.appendError(QString(QLatin1String("No loader for format %1 found"))
+ .arg(fmt));
+ return false;
+ }
+ }
+
+ cd.appendError(QString(QLatin1String("Unknown format %1 for file %2"))
+ .arg(format, filename));
+ return false;
+}
+
+
+bool Translator::save(const QString &filename, ConversionData &cd, const QString &format) const
+{
+ QFile file;
+ if (filename.isEmpty() || filename == QLatin1String("-")) {
+#ifdef Q_OS_WIN
+ // QFile is broken for text files
+# ifdef Q_OS_WINCE
+ ::_setmode(stdout, _O_BINARY);
+# else
+ ::_setmode(1, _O_BINARY);
+# endif
+#endif
+ if (!file.open(stdout, QIODevice::WriteOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot open stdout!? (%1)")
+ .arg(file.errorString()));
+ return false;
+ }
+ } else {
+ file.setFileName(filename);
+ if (!file.open(QIODevice::WriteOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot create %1: %2")
+ .arg(filename, file.errorString()));
+ return false;
+ }
+ }
+
+ QString fmt = guessFormat(filename, format);
+ cd.m_targetDir = QFileInfo(filename).absoluteDir();
+
+ foreach (const FileFormat &format, registeredFileFormats()) {
+ if (fmt == format.extension) {
+ if (format.saver)
+ return (*format.saver)(*this, file, cd);
+ cd.appendError(QString(QLatin1String("Cannot save %1 files")).arg(fmt));
+ return false;
+ }
+ }
+
+ cd.appendError(QString(QLatin1String("Unknown format %1 for file %2"))
+ .arg(format).arg(filename));
+ return false;
+}
+
+QString Translator::makeLanguageCode(QLocale::Language language, QLocale::Country country)
+{
+ QLocale locale(language, country);
+ if (country == QLocale::AnyCountry) {
+ QString languageCode = locale.name().section(QLatin1Char('_'), 0, 0);
+ if (languageCode.length() <= 3)
+ return languageCode;
+ return QString();
+ } else {
+ return locale.name();
+ }
+}
+
+void Translator::languageAndCountry(const QString &languageCode,
+ QLocale::Language *lang, QLocale::Country *country)
+{
+ QLocale locale(languageCode);
+ if (lang)
+ *lang = locale.language();
+
+ if (country) {
+ if (languageCode.indexOf(QLatin1Char('_')) != -1)
+ *country = locale.country();
+ else
+ *country = QLocale::AnyCountry;
+ }
+}
+
+bool Translator::release(QFile *iod, ConversionData &cd) const
+{
+ foreach (const FileFormat &format, registeredFileFormats()) {
+ if (format.extension == QLatin1String("qm"))
+ return (*format.saver)(*this, *iod, cd);
+ }
+ cd.appendError(QLatin1String("No .qm saver available."));
+ return false;
+}
+
+int Translator::find(const TranslatorMessage &msg) const
+{
+ for (int i = 0; i < m_messages.count(); ++i) {
+ const TranslatorMessage &tmsg = m_messages.at(i);
+ if (msg.id().isEmpty() || tmsg.id().isEmpty()) {
+ if (msg.context() == tmsg.context()
+ && msg.sourceText() == tmsg.sourceText()
+ && msg.comment() == tmsg.comment())
+ return i;
+ } else {
+ if (msg.id() == tmsg.id())
+ return i;
+ }
+ }
+ return -1;
+}
+
+TranslatorMessage Translator::find(const QString &context,
+ const QString &comment, const TranslatorMessage::References &refs) const
+{
+ if (!refs.isEmpty()) {
+ for (TMM::ConstIterator it = m_messages.constBegin(); it != m_messages.constEnd(); ++it) {
+ if (it->context() == context && it->comment() == comment)
+ foreach (const TranslatorMessage::Reference &itref, it->allReferences())
+ foreach (const TranslatorMessage::Reference &ref, refs)
+ if (itref == ref)
+ return *it;
+ }
+ }
+ return TranslatorMessage();
+}
+
+bool Translator::contains(const QString &context) const
+{
+ foreach (const TranslatorMessage &msg, m_messages)
+ if (msg.context() == context && msg.sourceText().isEmpty() && msg.id().isEmpty())
+ return true;
+ return false;
+}
+
+TranslatorMessage Translator::find(const QString &context) const
+{
+ foreach (const TranslatorMessage &msg, m_messages)
+ if (msg.context() == context && msg.sourceText().isEmpty() && msg.id().isEmpty())
+ return msg;
+ return TranslatorMessage();
+}
+
+void Translator::stripObsoleteMessages()
+{
+ TMM newmm;
+ for (TMM::ConstIterator it = m_messages.begin(); it != m_messages.end(); ++it)
+ if (it->type() != TranslatorMessage::Obsolete)
+ newmm.append(*it);
+ m_messages = newmm;
+}
+
+void Translator::stripFinishedMessages()
+{
+ TMM newmm;
+ for (TMM::ConstIterator it = m_messages.begin(); it != m_messages.end(); ++it)
+ if (it->type() != TranslatorMessage::Finished)
+ newmm.append(*it);
+ m_messages = newmm;
+}
+
+void Translator::stripEmptyContexts()
+{
+ TMM newmm;
+ for (TMM::ConstIterator it = m_messages.begin(); it != m_messages.end(); ++it)
+ if (it->sourceText() != QLatin1String(ContextComment))
+ newmm.append(*it);
+ m_messages = newmm;
+}
+
+void Translator::stripNonPluralForms()
+{
+ TMM newmm;
+ for (TMM::ConstIterator it = m_messages.begin(); it != m_messages.end(); ++it)
+ if (it->isPlural())
+ newmm.append(*it);
+ m_messages = newmm;
+}
+
+void Translator::stripIdenticalSourceTranslations()
+{
+ TMM newmm;
+ for (TMM::ConstIterator it = m_messages.begin(); it != m_messages.end(); ++it) {
+ // we need to have just one translation, and it be equal to the source
+ if (it->translations().count() != 1)
+ newmm.append(*it);
+ else if (it->translation() != it->sourceText())
+ newmm.append(*it);
+ }
+ m_messages = newmm;
+}
+
+void Translator::dropTranslations()
+{
+ for (TMM::Iterator it = m_messages.begin(); it != m_messages.end(); ++it) {
+ if (it->type() == TranslatorMessage::Finished)
+ it->setType(TranslatorMessage::Unfinished);
+ it->setTranslation(QString());
+ }
+}
+
+void Translator::dropUiLines()
+{
+ QString uiXt = QLatin1String(".ui");
+ QString juiXt = QLatin1String(".jui");
+ for (TMM::Iterator it = m_messages.begin(); it != m_messages.end(); ++it) {
+ QHash<QString, int> have;
+ QList<TranslatorMessage::Reference> refs;
+ foreach (const TranslatorMessage::Reference &itref, it->allReferences()) {
+ const QString &fn = itref.fileName();
+ if (fn.endsWith(uiXt) || fn.endsWith(juiXt)) {
+ if (++have[fn] == 1)
+ refs.append(TranslatorMessage::Reference(fn, -1));
+ } else {
+ refs.append(itref);
+ }
+ }
+ it->setReferences(refs);
+ }
+}
+
+struct TranslatorMessageIdPtr {
+ explicit TranslatorMessageIdPtr(const TranslatorMessage &tm)
+ {
+ ptr = &tm;
+ }
+
+ inline const TranslatorMessage *operator->() const
+ {
+ return ptr;
+ }
+
+ const TranslatorMessage *ptr;
+};
+
+Q_DECLARE_TYPEINFO(TranslatorMessageIdPtr, Q_MOVABLE_TYPE);
+
+inline int qHash(TranslatorMessageIdPtr tmp)
+{
+ return qHash(tmp->id());
+}
+
+inline bool operator==(TranslatorMessageIdPtr tmp1, TranslatorMessageIdPtr tmp2)
+{
+ return tmp1->id() == tmp2->id();
+}
+
+struct TranslatorMessageContentPtr {
+ explicit TranslatorMessageContentPtr(const TranslatorMessage &tm)
+ {
+ ptr = &tm;
+ }
+
+ inline const TranslatorMessage *operator->() const
+ {
+ return ptr;
+ }
+
+ const TranslatorMessage *ptr;
+};
+
+Q_DECLARE_TYPEINFO(TranslatorMessageContentPtr, Q_MOVABLE_TYPE);
+
+inline int qHash(TranslatorMessageContentPtr tmp)
+{
+ int hash = qHash(tmp->context()) ^ qHash(tmp->sourceText());
+ if (!tmp->sourceText().isEmpty())
+ // Special treatment for context comments (empty source).
+ hash ^= qHash(tmp->comment());
+ return hash;
+}
+
+inline bool operator==(TranslatorMessageContentPtr tmp1, TranslatorMessageContentPtr tmp2)
+{
+ if (tmp1->context() != tmp2->context() || tmp1->sourceText() != tmp2->sourceText())
+ return false;
+ // Special treatment for context comments (empty source).
+ if (tmp1->sourceText().isEmpty())
+ return true;
+ return tmp1->comment() == tmp2->comment();
+}
+
+Translator::Duplicates Translator::resolveDuplicates()
+{
+ Duplicates dups;
+ QHash<TranslatorMessageIdPtr, int> idRefs;
+ QHash<TranslatorMessageContentPtr, int> contentRefs;
+ for (int i = 0; i < m_messages.count();) {
+ const TranslatorMessage &msg = m_messages.at(i);
+ TranslatorMessage *omsg;
+ int oi;
+ QSet<int> *pDup;
+ if (!msg.id().isEmpty()) {
+ QHash<TranslatorMessageIdPtr, int>::ConstIterator it =
+ idRefs.constFind(TranslatorMessageIdPtr(msg));
+ if (it != idRefs.constEnd()) {
+ oi = *it;
+ omsg = &m_messages[oi];
+ pDup = &dups.byId;
+ goto gotDupe;
+ }
+ }
+ {
+ QHash<TranslatorMessageContentPtr, int>::ConstIterator it =
+ contentRefs.constFind(TranslatorMessageContentPtr(msg));
+ if (it != contentRefs.constEnd()) {
+ oi = *it;
+ omsg = &m_messages[oi];
+ if (msg.id().isEmpty() || omsg->id().isEmpty()) {
+ if (!msg.id().isEmpty() && omsg->id().isEmpty()) {
+ omsg->setId(msg.id());
+ idRefs[TranslatorMessageIdPtr(*omsg)] = oi;
+ }
+ pDup = &dups.byContents;
+ goto gotDupe;
+ }
+ // This is really a content dupe, but with two distinct IDs.
+ }
+ }
+ if (!msg.id().isEmpty())
+ idRefs[TranslatorMessageIdPtr(msg)] = i;
+ contentRefs[TranslatorMessageContentPtr(msg)] = i;
+ ++i;
+ continue;
+ gotDupe:
+ if (omsg->isUtf8() != msg.isUtf8() && !omsg->isNonUtf8()) {
+ // Dual-encoded message
+ omsg->setUtf8(true);
+ omsg->setNonUtf8(true);
+ } else {
+ // Duplicate
+ pDup->insert(oi);
+ }
+ if (!omsg->isTranslated() && msg.isTranslated())
+ omsg->setTranslations(msg.translations());
+ m_messages.removeAt(i);
+ }
+ return dups;
+}
+
+void Translator::reportDuplicates(const Duplicates &dupes,
+ const QString &fileName, bool verbose)
+{
+ if (!dupes.byId.isEmpty() || !dupes.byContents.isEmpty()) {
+ std::cerr << "Warning: dropping duplicate messages in '" << qPrintable(fileName);
+ if (!verbose) {
+ std::cerr << "'\n(try -verbose for more info).\n";
+ } else {
+ std::cerr << "':\n";
+ foreach (int i, dupes.byId)
+ std::cerr << "\n* ID: " << qPrintable(message(i).id()) << std::endl;
+ foreach (int j, dupes.byContents) {
+ const TranslatorMessage &msg = message(j);
+ std::cerr << "\n* Context: " << qPrintable(msg.context())
+ << "\n* Source: " << qPrintable(msg.sourceText()) << std::endl;
+ if (!msg.comment().isEmpty())
+ std::cerr << "* Comment: " << qPrintable(msg.comment()) << std::endl;
+ }
+ std::cerr << std::endl;
+ }
+ }
+}
+
+// Used by lupdate to be able to search using absolute paths during merging
+void Translator::makeFileNamesAbsolute(const QDir &originalPath)
+{
+ TMM newmm;
+ for (TMM::iterator it = m_messages.begin(); it != m_messages.end(); ++it) {
+ TranslatorMessage msg = *it;
+ msg.setReferences(TranslatorMessage::References());
+ foreach (const TranslatorMessage::Reference &ref, it->allReferences()) {
+ QString fileName = ref.fileName();
+ QFileInfo fi (fileName);
+ if (fi.isRelative())
+ fileName = originalPath.absoluteFilePath(fileName);
+ msg.addReference(fileName, ref.lineNumber());
+ }
+ newmm.append(msg);
+ }
+ m_messages = newmm;
+}
+
+QList<TranslatorMessage> Translator::messages() const
+{
+ return m_messages;
+}
+
+QList<TranslatorMessage> Translator::translatedMessages() const
+{
+ TMM result;
+ for (TMM::ConstIterator it = m_messages.begin(); it != m_messages.end(); ++it)
+ if (it->type() == TranslatorMessage::Finished)
+ result.append(*it);
+ return result;
+}
+
+QStringList Translator::normalizedTranslations(const TranslatorMessage &msg, int numPlurals)
+{
+ QStringList translations = msg.translations();
+ int numTranslations = msg.isPlural() ? numPlurals : 1;
+
+ // make sure that the stringlist always have the size of the
+ // language's current numerus, or 1 if its not plural
+ if (translations.count() > numTranslations) {
+ for (int i = translations.count(); i > numTranslations; --i)
+ translations.removeLast();
+ } else if (translations.count() < numTranslations) {
+ for (int i = translations.count(); i < numTranslations; ++i)
+ translations.append(QString());
+ }
+ return translations;
+}
+
+void Translator::normalizeTranslations(ConversionData &cd)
+{
+ bool truncated = false;
+ QLocale::Language l;
+ QLocale::Country c;
+ languageAndCountry(languageCode(), &l, &c);
+ int numPlurals = 1;
+ if (l != QLocale::C) {
+ QStringList forms;
+ if (getNumerusInfo(l, c, 0, &forms, 0))
+ numPlurals = forms.count(); // includes singular
+ }
+ for (int i = 0; i < m_messages.count(); ++i) {
+ const TranslatorMessage &msg = m_messages.at(i);
+ QStringList tlns = msg.translations();
+ int ccnt = msg.isPlural() ? numPlurals : 1;
+ if (tlns.count() != ccnt) {
+ while (tlns.count() < ccnt)
+ tlns.append(QString());
+ while (tlns.count() > ccnt) {
+ tlns.removeLast();
+ truncated = true;
+ }
+ TranslatorMessage msg2(msg);
+ msg2.setTranslations(tlns);
+ m_messages[i] = msg2;
+ }
+ }
+ if (truncated)
+ cd.appendError(QLatin1String(
+ "Removed plural forms as the target language has less "
+ "forms.\nIf this sounds wrong, possibly the target language is "
+ "not set or recognized."));
+}
+
+QString Translator::guessLanguageCodeFromFileName(const QString &filename)
+{
+ QString str = filename;
+ foreach (const FileFormat &format, registeredFileFormats()) {
+ if (str.endsWith(format.extension)) {
+ str = str.left(str.size() - format.extension.size() - 1);
+ break;
+ }
+ }
+ static QRegExp re(QLatin1String("[\\._]"));
+ while (true) {
+ QLocale locale(str);
+ //qDebug() << "LANGUAGE FROM " << str << "LANG: " << locale.language();
+ if (locale.language() != QLocale::C) {
+ //qDebug() << "FOUND " << locale.name();
+ return locale.name();
+ }
+ int pos = str.indexOf(re);
+ if (pos == -1)
+ break;
+ str = str.mid(pos + 1);
+ }
+ //qDebug() << "LANGUAGE GUESSING UNSUCCESSFUL";
+ return QString();
+}
+
+bool Translator::hasExtra(const QString &key) const
+{
+ return m_extra.contains(key);
+}
+
+QString Translator::extra(const QString &key) const
+{
+ return m_extra[key];
+}
+
+void Translator::setExtra(const QString &key, const QString &value)
+{
+ m_extra[key] = value;
+}
+
+void Translator::setCodecName(const QByteArray &name)
+{
+ QTextCodec *codec = QTextCodec::codecForName(name);
+ if (!codec) {
+ if (!name.isEmpty())
+ std::cerr << "No QTextCodec for " << name.constData() << " available. Using Latin1.\n";
+ m_codec = QTextCodec::codecForName("ISO-8859-1");
+ } else {
+ m_codec = codec;
+ }
+}
+
+QByteArray Translator::codecName() const
+{
+ return m_codec->name();
+}
+
+void Translator::dump() const
+{
+ for (int i = 0; i != messageCount(); ++i)
+ message(i).dump();
+}
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/translator.h b/src/linguist/shared/translator.h
new file mode 100644
index 000000000..6a619414b
--- /dev/null
+++ b/src/linguist/shared/translator.h
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef METATRANSLATOR_H
+#define METATRANSLATOR_H
+
+#include "translatormessage.h"
+
+#include <QDir>
+#include <QList>
+#include <QLocale>
+#include <QMultiHash>
+#include <QString>
+#include <QSet>
+
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BOOTSTRAPPED
+class QObject {
+public:
+ static QString tr(const char *sourceText, const char * = 0, int n = -1);
+};
+class QCoreApplication : public QObject {
+public:
+ enum Encoding { CodecForTr };
+ static QString translate(const char *, const char *sourceText, const char * = 0,
+ Encoding = CodecForTr, int n = -1)
+ { return tr(sourceText, 0, n); }
+};
+#endif
+
+class QIODevice;
+
+// A struct of "interesting" data passed to and from the load and save routines
+class ConversionData
+{
+public:
+ ConversionData() :
+ m_verbose(false),
+ m_ignoreUnfinished(false),
+ m_sortContexts(false),
+ m_noUiLines(false),
+ m_idBased(false),
+ m_saveMode(SaveEverything)
+ {}
+
+ // tag manipulation
+ const QStringList &dropTags() const { return m_dropTags; }
+ QStringList &dropTags() { return m_dropTags; }
+ const QDir &targetDir() const { return m_targetDir; }
+ bool isVerbose() const { return m_verbose; }
+ bool ignoreUnfinished() const { return m_ignoreUnfinished; }
+ bool sortContexts() const { return m_sortContexts; }
+
+ void appendError(const QString &error) { m_errors.append(error); }
+ QString error() const { return m_errors.isEmpty() ? QString() : m_errors.join(QLatin1String("\n")) + QLatin1Char('\n'); }
+ QStringList errors() const { return m_errors; }
+ void clearErrors() { m_errors.clear(); }
+
+public:
+ QString m_defaultContext;
+ QByteArray m_codecForSource; // CPP, PO & QM specific
+ QByteArray m_outputCodec; // CPP & PO specific
+ QString m_unTrPrefix; // QM specific
+ QString m_sourceFileName;
+ QString m_targetFileName;
+ QDir m_sourceDir;
+ QDir m_targetDir; // FIXME: TS specific
+ QSet<QString> m_projectRoots;
+ QMultiHash<QString, QString> m_allCSources;
+ QStringList m_includePath;
+ QStringList m_dropTags; // tags to be dropped
+ QStringList m_errors;
+ bool m_verbose;
+ bool m_ignoreUnfinished;
+ bool m_sortContexts;
+ bool m_noUiLines;
+ bool m_idBased;
+ TranslatorSaveMode m_saveMode;
+};
+
+class Translator
+{
+public:
+ Translator();
+
+ bool load(const QString &filename, ConversionData &err, const QString &format /* = "auto" */);
+ bool save(const QString &filename, ConversionData &err, const QString &format /* = "auto" */) const;
+ bool release(QFile *iod, ConversionData &cd) const;
+
+ int find(const TranslatorMessage &msg) const;
+ TranslatorMessage find(const QString &context,
+ const QString &comment, const TranslatorMessage::References &refs) const;
+
+ bool contains(const QString &context) const;
+ TranslatorMessage find(const QString &context) const;
+
+ void replaceSorted(const TranslatorMessage &msg);
+ void extend(const TranslatorMessage &msg); // Only for single-location messages
+ void append(const TranslatorMessage &msg);
+ void appendSorted(const TranslatorMessage &msg);
+
+ void stripObsoleteMessages();
+ void stripFinishedMessages();
+ void stripEmptyContexts();
+ void stripNonPluralForms();
+ void stripIdenticalSourceTranslations();
+ void dropTranslations();
+ void dropUiLines();
+ void makeFileNamesAbsolute(const QDir &originalPath);
+
+ struct Duplicates { QSet<int> byId, byContents; };
+ Duplicates resolveDuplicates();
+ void reportDuplicates(const Duplicates &dupes, const QString &fileName, bool verbose);
+
+ void setCodecName(const QByteArray &name);
+ void setCodec(QTextCodec *codec) { m_codec = codec; }
+ QByteArray codecName() const;
+ QTextCodec *codec() const { return m_codec; }
+
+ QString languageCode() const { return m_language; }
+ QString sourceLanguageCode() const { return m_sourceLanguage; }
+
+ enum LocationsType { DefaultLocations, NoLocations, RelativeLocations, AbsoluteLocations };
+ void setLocationsType(LocationsType lt) { m_locationsType = lt; }
+ LocationsType locationsType() const { return m_locationsType; }
+
+ static QString makeLanguageCode(QLocale::Language language, QLocale::Country country);
+ static void languageAndCountry(const QString &languageCode,
+ QLocale::Language *lang, QLocale::Country *country);
+ void setLanguageCode(const QString &languageCode) { m_language = languageCode; }
+ void setSourceLanguageCode(const QString &languageCode) { m_sourceLanguage = languageCode; }
+ static QString guessLanguageCodeFromFileName(const QString &fileName);
+ QList<TranslatorMessage> messages() const;
+ QList<TranslatorMessage> translatedMessages() const;
+ static QStringList normalizedTranslations(const TranslatorMessage &m, int numPlurals);
+ void normalizeTranslations(ConversionData &cd);
+ QStringList normalizedTranslations(const TranslatorMessage &m, ConversionData &cd, bool *ok) const;
+
+ int messageCount() const { return m_messages.size(); }
+ TranslatorMessage &message(int i) { return m_messages[i]; }
+ const TranslatorMessage &message(int i) const { return m_messages.at(i); }
+ void dump() const;
+
+ // additional file format specific data
+ // note: use '<fileformat>:' as prefix for file format specific members,
+ // e.g. "po-flags", "po-msgid_plural"
+ typedef TranslatorMessage::ExtraData ExtraData;
+ QString extra(const QString &ba) const;
+ void setExtra(const QString &ba, const QString &var);
+ bool hasExtra(const QString &ba) const;
+ const ExtraData &extras() const { return m_extra; }
+ void setExtras(const ExtraData &extras) { m_extra = extras; }
+
+ // registration of file formats
+ typedef bool (*SaveFunction)(const Translator &, QIODevice &out, ConversionData &data);
+ typedef bool (*LoadFunction)(Translator &, QIODevice &in, ConversionData &data);
+ struct FileFormat {
+ FileFormat() : loader(0), saver(0), priority(-1) {}
+ QString extension; // such as "ts", "xlf", ...
+ QString description; // human-readable description
+ LoadFunction loader;
+ SaveFunction saver;
+ enum FileType { TranslationSource, TranslationBinary } fileType;
+ int priority; // 0 = highest, -1 = invisible
+ };
+ static void registerFileFormat(const FileFormat &format);
+ static QList<FileFormat> &registeredFileFormats();
+
+ enum {
+ TextVariantSeparator = 0x2762, // some weird character nobody ever heard of :-D
+ BinaryVariantSeparator = 0x9c // unicode "STRING TERMINATOR"
+ };
+
+private:
+ typedef QList<TranslatorMessage> TMM; // int stores the sequence position.
+
+ TMM m_messages;
+ QTextCodec *m_codec;
+ LocationsType m_locationsType;
+
+ // A string beginning with a 2 or 3 letter language code (ISO 639-1
+ // or ISO-639-2), followed by the optional country variant to distinguish
+ // between country-specific variations of the language. The language code
+ // and country code are always separated by '_'
+ // Note that the language part can also be a 3-letter ISO 639-2 code.
+ // Legal examples:
+ // 'pt' portuguese, assumes portuguese from portugal
+ // 'pt_BR' Brazilian portuguese (ISO 639-1 language code)
+ // 'por_BR' Brazilian portuguese (ISO 639-2 language code)
+ QString m_language;
+ QString m_sourceLanguage;
+ ExtraData m_extra;
+};
+
+bool getNumerusInfo(QLocale::Language language, QLocale::Country country,
+ QByteArray *rules, QStringList *forms, const char **gettextRules);
+
+/*
+ This is a quick hack. The proper way to handle this would be
+ to extend Translator's interface.
+*/
+#define ContextComment "QT_LINGUIST_INTERNAL_CONTEXT_COMMENT"
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/linguist/shared/translatormessage.cpp b/src/linguist/shared/translatormessage.cpp
new file mode 100644
index 000000000..8a0408a21
--- /dev/null
+++ b/src/linguist/shared/translatormessage.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translatormessage.h"
+
+#include <qplatformdefs.h>
+
+#ifndef QT_NO_TRANSLATION
+
+#include <QDataStream>
+#include <QDebug>
+
+#include <stdlib.h>
+
+
+QT_BEGIN_NAMESPACE
+
+TranslatorMessage::TranslatorMessage()
+ : m_lineNumber(-1), m_type(Unfinished), m_utf8(false), m_nonUtf8(false), m_plural(false)
+{
+}
+
+TranslatorMessage::TranslatorMessage(const QString &context,
+ const QString &sourceText, const QString &comment,
+ const QString &userData,
+ const QString &fileName, int lineNumber, const QStringList &translations,
+ Type type, bool plural)
+ : m_context(context), m_sourcetext(sourceText), m_comment(comment),
+ m_userData(userData),
+ m_translations(translations), m_fileName(fileName), m_lineNumber(lineNumber),
+ m_type(type), m_utf8(false), m_nonUtf8(false), m_plural(plural)
+{
+}
+
+void TranslatorMessage::addReference(const QString &fileName, int lineNumber)
+{
+ if (m_fileName.isEmpty()) {
+ m_fileName = fileName;
+ m_lineNumber = lineNumber;
+ } else {
+ m_extraRefs.append(Reference(fileName, lineNumber));
+ }
+}
+
+void TranslatorMessage::addReferenceUniq(const QString &fileName, int lineNumber)
+{
+ if (m_fileName.isEmpty()) {
+ m_fileName = fileName;
+ m_lineNumber = lineNumber;
+ } else {
+ if (fileName == m_fileName && lineNumber == m_lineNumber)
+ return;
+ if (!m_extraRefs.isEmpty()) // Rather common case, so special-case it
+ foreach (const Reference &ref, m_extraRefs)
+ if (fileName == ref.fileName() && lineNumber == ref.lineNumber())
+ return;
+ m_extraRefs.append(Reference(fileName, lineNumber));
+ }
+}
+
+void TranslatorMessage::clearReferences()
+{
+ m_fileName.clear();
+ m_lineNumber = -1;
+ m_extraRefs.clear();
+}
+
+void TranslatorMessage::setReferences(const TranslatorMessage::References &refs0)
+{
+ if (!refs0.isEmpty()) {
+ References refs = refs0;
+ const Reference &ref = refs.takeFirst();
+ m_fileName = ref.fileName();
+ m_lineNumber = ref.lineNumber();
+ m_extraRefs = refs;
+ } else {
+ clearReferences();
+ }
+}
+
+TranslatorMessage::References TranslatorMessage::allReferences() const
+{
+ References refs;
+ if (!m_fileName.isEmpty()) {
+ refs.append(Reference(m_fileName, m_lineNumber));
+ refs += m_extraRefs;
+ }
+ return refs;
+}
+
+static bool needs8BitHelper(const QString &ba)
+{
+ for (int i = ba.size(); --i >= 0; )
+ if (ba.at(i).unicode() >= 0x80)
+ return true;
+ return false;
+}
+
+bool TranslatorMessage::needs8Bit() const
+{
+ //dump();
+ return needs8BitHelper(m_sourcetext)
+ || needs8BitHelper(m_comment)
+ || needs8BitHelper(m_context);
+}
+
+
+bool TranslatorMessage::hasExtra(const QString &key) const
+{
+ return m_extra.contains(key);
+}
+
+QString TranslatorMessage::extra(const QString &key) const
+{
+ return m_extra[key];
+}
+
+void TranslatorMessage::setExtra(const QString &key, const QString &value)
+{
+ m_extra[key] = value;
+}
+
+void TranslatorMessage::unsetExtra(const QString &key)
+{
+ m_extra.remove(key);
+}
+
+void TranslatorMessage::dump() const
+{
+ qDebug()
+ << "\nId : " << m_id
+ << "\nContext : " << m_context
+ << "\nSource : " << m_sourcetext
+ << "\nComment : " << m_comment
+ << "\nUserData : " << m_userData
+ << "\nExtraComment : " << m_extraComment
+ << "\nTranslatorComment : " << m_translatorComment
+ << "\nTranslations : " << m_translations
+ << "\nFileName : " << m_fileName
+ << "\nLineNumber : " << m_lineNumber
+ << "\nType : " << m_type
+ << "\nPlural : " << m_plural
+ << "\nExtra : " << m_extra;
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TRANSLATION
diff --git a/src/linguist/shared/translatormessage.h b/src/linguist/shared/translatormessage.h
new file mode 100644
index 000000000..4bb5dc84a
--- /dev/null
+++ b/src/linguist/shared/translatormessage.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRANSLATORMESSAGE_H
+#define TRANSLATORMESSAGE_H
+
+#ifndef QT_NO_TRANSLATION
+
+#include <QString>
+#include <QStringList>
+#include <QHash>
+
+
+QT_BEGIN_NAMESPACE
+
+enum TranslatorSaveMode { SaveEverything, SaveStripped };
+
+class TranslatorMessage
+{
+public:
+ enum Type { Unfinished, Finished, Obsolete };
+ typedef QHash<QString, QString> ExtraData;
+ class Reference
+ {
+ QString m_fileName;
+ int m_lineNumber;
+ public:
+ Reference(const QString &n, int l) : m_fileName(n), m_lineNumber(l) {}
+ bool operator==(const Reference &other) const
+ { return fileName() == other.fileName() && lineNumber() == other.lineNumber(); }
+ QString fileName() const { return m_fileName; }
+ int lineNumber() const { return m_lineNumber; }
+ };
+ typedef QList<Reference> References;
+
+ TranslatorMessage();
+ TranslatorMessage(const QString &context, const QString &sourceText,
+ const QString &comment, const QString &userData,
+ const QString &fileName, int lineNumber,
+ const QStringList &translations = QStringList(),
+ Type type = Unfinished, bool plural = false);
+
+ uint hash() const;
+
+ QString id() const { return m_id; }
+ void setId(const QString &id) { m_id = id; }
+
+ QString context() const { return m_context; }
+ void setContext(const QString &context) { m_context = context; }
+
+ QString sourceText() const { return m_sourcetext; }
+ void setSourceText(const QString &sourcetext) { m_sourcetext = sourcetext; }
+ QString oldSourceText() const { return m_oldsourcetext; }
+ void setOldSourceText(const QString &oldsourcetext) { m_oldsourcetext = oldsourcetext; }
+
+ QString comment() const { return m_comment; }
+ void setComment(const QString &comment) { m_comment = comment; }
+ QString oldComment() const { return m_oldcomment; }
+ void setOldComment(const QString &oldcomment) { m_oldcomment = oldcomment; }
+
+ QStringList translations() const { return m_translations; }
+ void setTranslations(const QStringList &translations) { m_translations = translations; }
+ QString translation() const { return m_translations.value(0); }
+ void setTranslation(const QString &translation) { m_translations = QStringList(translation); }
+ void appendTranslation(const QString &translation) { m_translations.append(translation); }
+ bool isTranslated() const
+ {
+ foreach (const QString &trans, m_translations)
+ if (!trans.isEmpty())
+ return true;
+ return false;
+ }
+
+ QString fileName() const { return m_fileName; }
+ void setFileName(const QString &fileName) { m_fileName = fileName; }
+ int lineNumber() const { return m_lineNumber; }
+ void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; }
+ void clearReferences();
+ void setReferences(const References &refs);
+ void addReference(const QString &fileName, int lineNumber);
+ void addReference(const Reference &ref) { addReference(ref.fileName(), ref.lineNumber()); }
+ void addReferenceUniq(const QString &fileName, int lineNumber);
+ References extraReferences() const { return m_extraRefs; }
+ References allReferences() const;
+ QString userData() const { return m_userData; }
+ void setUserData(const QString &userData) { m_userData = userData; }
+ QString extraComment() const { return m_extraComment; }
+ void setExtraComment(const QString &extraComment) { m_extraComment = extraComment; }
+ QString translatorComment() const { return m_translatorComment; }
+ void setTranslatorComment(const QString &translatorComment) { m_translatorComment = translatorComment; }
+
+ bool isNull() const { return m_sourcetext.isNull() && m_lineNumber == -1 && m_translations.isEmpty(); }
+
+ Type type() const { return m_type; }
+ void setType(Type t) { m_type = t; }
+ bool isUtf8() const { return m_utf8; } // codecForTr override
+ void setUtf8(bool on) { m_utf8 = on; }
+ bool isNonUtf8() const { return m_nonUtf8; } // codecForTr override
+ void setNonUtf8(bool on) { m_nonUtf8 = on; }
+ bool isPlural() const { return m_plural; }
+ void setPlural(bool isplural) { m_plural = isplural; }
+
+ // note: use '<fileformat>:' as prefix for file format specific members,
+ // e.g. "po-msgid_plural"
+ QString extra(const QString &ba) const;
+ void setExtra(const QString &ba, const QString &var);
+ bool hasExtra(const QString &ba) const;
+ const ExtraData &extras() const { return m_extra; }
+ void setExtras(const ExtraData &extras) { m_extra = extras; }
+ void unsetExtra(const QString &key);
+
+ bool needs8Bit() const;
+ void dump() const;
+
+private:
+ QString m_id;
+ QString m_context;
+ QString m_sourcetext;
+ QString m_oldsourcetext;
+ QString m_comment;
+ QString m_oldcomment;
+ QString m_userData;
+ ExtraData m_extra; // PO flags, PO plurals
+ QString m_extraComment;
+ QString m_translatorComment;
+ QStringList m_translations;
+ QString m_fileName;
+ int m_lineNumber;
+ References m_extraRefs;
+
+ Type m_type;
+ bool m_utf8;
+ bool m_nonUtf8;
+ bool m_plural;
+};
+
+Q_DECLARE_TYPEINFO(TranslatorMessage, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TRANSLATION
+
+#endif // TRANSLATORMESSAGE_H
diff --git a/src/linguist/shared/ts.cpp b/src/linguist/shared/ts.cpp
new file mode 100644
index 000000000..4523bc55d
--- /dev/null
+++ b/src/linguist/shared/ts.cpp
@@ -0,0 +1,781 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QDebug>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+#include <QtXml/QXmlStreamReader>
+#include <QtXml/QXmlStreamAttribute>
+
+#define STRINGIFY_INTERNAL(x) #x
+#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
+#define STRING(s) static QString str##s(QLatin1String(STRINGIFY(s)))
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * The encodings are a total mess.
+ * A Translator has a codecForTr(). Each message's text will be passed to tr()
+ * in that encoding or as UTF-8 to trUtf8() if it is flagged as such.
+ * For ts 2.0, the file content is always uniformly in UTF-8. The file stores
+ * the codecForTr default and marks deviating messages accordingly.
+ * For ts 1.1, the file content is in mixed encoding. Each message is encoded
+ * the way it will be passed to tr() (with 8-bit characters encoded as numeric
+ * entities) or trUtf8(). The file stores the encoding and codecForTr in one
+ * attribute, for both the default and each deviating message.
+ */
+
+
+QDebug &operator<<(QDebug &d, const QXmlStreamAttribute &attr)
+{
+ return d << "[" << attr.name().toString() << "," << attr.value().toString() << "]";
+}
+
+
+class TSReader : public QXmlStreamReader
+{
+public:
+ TSReader(QIODevice &dev, ConversionData &cd)
+ : QXmlStreamReader(&dev), m_cd(cd)
+ {}
+
+ // the "real thing"
+ bool read(Translator &translator);
+
+private:
+ bool elementStarts(const QString &str) const
+ {
+ return isStartElement() && name() == str;
+ }
+
+ bool isWhiteSpace() const
+ {
+ return isCharacters() && text().toString().trimmed().isEmpty();
+ }
+
+ // needed to expand <byte ... />
+ QString readContents();
+ // needed to join <lengthvariant>s
+ QString readTransContents();
+
+ void handleError();
+
+ ConversionData &m_cd;
+};
+
+void TSReader::handleError()
+{
+ if (isComment())
+ return;
+ if (hasError() && error() == CustomError) // raised by readContents
+ return;
+
+ const QString loc = QString::fromLatin1("at %3:%1:%2")
+ .arg(lineNumber()).arg(columnNumber()).arg(m_cd.m_sourceFileName);
+
+ switch (tokenType()) {
+ case NoToken: // Cannot happen
+ default: // likewise
+ case Invalid:
+ raiseError(QString::fromLatin1("Parse error %1: %2").arg(loc, errorString()));
+ break;
+ case StartElement:
+ raiseError(QString::fromLatin1("Unexpected tag <%1> %2").arg(name().toString(), loc));
+ break;
+ case Characters:
+ {
+ QString tok = text().toString();
+ if (tok.length() > 30)
+ tok = tok.left(30) + QLatin1String("[...]");
+ raiseError(QString::fromLatin1("Unexpected characters '%1' %2").arg(tok, loc));
+ }
+ break;
+ case EntityReference:
+ raiseError(QString::fromLatin1("Unexpected entity '&%1;' %2").arg(name().toString(), loc));
+ break;
+ case ProcessingInstruction:
+ raiseError(QString::fromLatin1("Unexpected processing instruction %1").arg(loc));
+ break;
+ }
+}
+
+static QString byteValue(QString value)
+{
+ int base = 10;
+ if (value.startsWith(QLatin1String("x"))) {
+ base = 16;
+ value.remove(0, 1);
+ }
+ int n = value.toUInt(0, base);
+ return (n != 0) ? QString(QChar(n)) : QString();
+}
+
+QString TSReader::readContents()
+{
+ STRING(byte);
+ STRING(value);
+
+ QString result;
+ while (!atEnd()) {
+ readNext();
+ if (isEndElement()) {
+ break;
+ } else if (isCharacters()) {
+ result += text();
+ } else if (elementStarts(strbyte)) {
+ // <byte value="...">
+ result += byteValue(attributes().value(strvalue).toString());
+ readNext();
+ if (!isEndElement()) {
+ handleError();
+ break;
+ }
+ } else {
+ handleError();
+ break;
+ }
+ }
+ //qDebug() << "TEXT: " << result;
+ return result;
+}
+
+QString TSReader::readTransContents()
+{
+ STRING(lengthvariant);
+ STRING(variants);
+ STRING(yes);
+
+ if (attributes().value(strvariants) == stryes) {
+ QString result;
+ while (!atEnd()) {
+ readNext();
+ if (isEndElement()) {
+ break;
+ } else if (isWhiteSpace()) {
+ // ignore these, just whitespace
+ } else if (elementStarts(strlengthvariant)) {
+ if (!result.isEmpty())
+ result += QChar(Translator::BinaryVariantSeparator);
+ result += readContents();
+ } else {
+ handleError();
+ break;
+ }
+ }
+ return result;
+ } else {
+ return readContents();
+ }
+}
+
+bool TSReader::read(Translator &translator)
+{
+ STRING(both);
+ STRING(byte);
+ STRING(comment);
+ STRING(context);
+ STRING(defaultcodec);
+ STRING(encoding);
+ STRING(extracomment);
+ STRING(filename);
+ STRING(id);
+ STRING(language);
+ STRING(line);
+ STRING(location);
+ STRING(message);
+ STRING(name);
+ STRING(numerus);
+ STRING(numerusform);
+ STRING(obsolete);
+ STRING(oldcomment);
+ STRING(oldsource);
+ STRING(source);
+ STRING(sourcelanguage);
+ STRING(translation);
+ STRING(translatorcomment);
+ STRING(true);
+ STRING(TS);
+ STRING(type);
+ STRING(unfinished);
+ STRING(userdata);
+ STRING(utf8);
+ STRING(value);
+ //STRING(version);
+ STRING(yes);
+
+ static const QString strextrans(QLatin1String("extra-"));
+ static const QString strUtf8(QLatin1String("UTF-8"));
+
+ while (!atEnd()) {
+ readNext();
+ if (isStartDocument()) {
+ // <!DOCTYPE TS>
+ //qDebug() << attributes();
+ } else if (isEndDocument()) {
+ // <!DOCTYPE TS>
+ //qDebug() << attributes();
+ } else if (isDTD()) {
+ // <!DOCTYPE TS>
+ //qDebug() << tokenString();
+ } else if (elementStarts(strTS)) {
+ // <TS>
+ //qDebug() << "TS " << attributes();
+ QHash<QString, int> currentLine;
+ QString currentFile;
+ bool maybeRelative = false, maybeAbsolute = false;
+
+ QXmlStreamAttributes atts = attributes();
+ //QString version = atts.value(strversion).toString();
+ translator.setLanguageCode(atts.value(strlanguage).toString());
+ translator.setSourceLanguageCode(atts.value(strsourcelanguage).toString());
+ while (!atEnd()) {
+ readNext();
+ if (isEndElement()) {
+ // </TS> found, finish local loop
+ break;
+ } else if (isWhiteSpace()) {
+ // ignore these, just whitespace
+ } else if (elementStarts(strdefaultcodec)) {
+ // <defaultcodec>
+ const QString &codec = readElementText();
+ if (!codec.isEmpty())
+ translator.setCodecName(codec.toLatin1());
+ // </defaultcodec>
+ } else if (isStartElement()
+ && name().toString().startsWith(strextrans)) {
+ // <extra-...>
+ QString tag = name().toString();
+ translator.setExtra(tag.mid(6), readContents());
+ // </extra-...>
+ } else if (elementStarts(strcontext)) {
+ // <context>
+ QString context;
+ while (!atEnd()) {
+ readNext();
+ if (isEndElement()) {
+ // </context> found, finish local loop
+ break;
+ } else if (isWhiteSpace()) {
+ // ignore these, just whitespace
+ } else if (elementStarts(strname)) {
+ // <name>
+ context = readElementText();
+ // </name>
+ } else if (elementStarts(strmessage)) {
+ // <message>
+ TranslatorMessage::References refs;
+ QString currentMsgFile = currentFile;
+
+ TranslatorMessage msg;
+ msg.setId(attributes().value(strid).toString());
+ msg.setContext(context);
+ msg.setType(TranslatorMessage::Finished);
+ msg.setPlural(attributes().value(strnumerus) == stryes);
+ const QStringRef &utf8Attr = attributes().value(strutf8);
+ msg.setNonUtf8(utf8Attr == strboth);
+ msg.setUtf8(msg.isNonUtf8() || utf8Attr == strtrue
+ || attributes().value(strencoding) == strUtf8);
+ while (!atEnd()) {
+ readNext();
+ if (isEndElement()) {
+ // </message> found, finish local loop
+ msg.setReferences(refs);
+ translator.append(msg);
+ break;
+ } else if (isWhiteSpace()) {
+ // ignore these, just whitespace
+ } else if (elementStarts(strsource)) {
+ // <source>...</source>
+ msg.setSourceText(readContents());
+ } else if (elementStarts(stroldsource)) {
+ // <oldsource>...</oldsource>
+ msg.setOldSourceText(readContents());
+ } else if (elementStarts(stroldcomment)) {
+ // <oldcomment>...</oldcomment>
+ msg.setOldComment(readContents());
+ } else if (elementStarts(strextracomment)) {
+ // <extracomment>...</extracomment>
+ msg.setExtraComment(readContents());
+ } else if (elementStarts(strtranslatorcomment)) {
+ // <translatorcomment>...</translatorcomment>
+ msg.setTranslatorComment(readContents());
+ } else if (elementStarts(strlocation)) {
+ // <location/>
+ maybeAbsolute = true;
+ QXmlStreamAttributes atts = attributes();
+ QString fileName = atts.value(strfilename).toString();
+ if (fileName.isEmpty()) {
+ fileName = currentMsgFile;
+ maybeRelative = true;
+ } else {
+ if (refs.isEmpty())
+ currentFile = fileName;
+ currentMsgFile = fileName;
+ }
+ const QString lin = atts.value(strline).toString();
+ if (lin.isEmpty()) {
+ refs.append(TranslatorMessage::Reference(fileName, -1));
+ } else {
+ bool bOK;
+ int lineNo = lin.toInt(&bOK);
+ if (bOK) {
+ if (lin.startsWith(QLatin1Char('+')) || lin.startsWith(QLatin1Char('-'))) {
+ lineNo = (currentLine[fileName] += lineNo);
+ maybeRelative = true;
+ }
+ refs.append(TranslatorMessage::Reference(fileName, lineNo));
+ }
+ }
+ readContents();
+ } else if (elementStarts(strcomment)) {
+ // <comment>...</comment>
+ msg.setComment(readContents());
+ } else if (elementStarts(struserdata)) {
+ // <userdata>...</userdata>
+ msg.setUserData(readContents());
+ } else if (elementStarts(strtranslation)) {
+ // <translation>
+ QXmlStreamAttributes atts = attributes();
+ QStringRef type = atts.value(strtype);
+ if (type == strunfinished)
+ msg.setType(TranslatorMessage::Unfinished);
+ else if (type == strobsolete)
+ msg.setType(TranslatorMessage::Obsolete);
+ if (msg.isPlural()) {
+ QStringList translations;
+ while (!atEnd()) {
+ readNext();
+ if (isEndElement()) {
+ break;
+ } else if (isWhiteSpace()) {
+ // ignore these, just whitespace
+ } else if (elementStarts(strnumerusform)) {
+ translations.append(readTransContents());
+ } else {
+ handleError();
+ break;
+ }
+ }
+ msg.setTranslations(translations);
+ } else {
+ msg.setTranslation(readTransContents());
+ }
+ // </translation>
+ } else if (isStartElement()
+ && name().toString().startsWith(strextrans)) {
+ // <extra-...>
+ QString tag = name().toString();
+ msg.setExtra(tag.mid(6), readContents());
+ // </extra-...>
+ } else {
+ handleError();
+ }
+ }
+ // </message>
+ } else {
+ handleError();
+ }
+ }
+ // </context>
+ } else {
+ handleError();
+ }
+ translator.setLocationsType(maybeRelative ? Translator::RelativeLocations :
+ maybeAbsolute ? Translator::AbsoluteLocations :
+ Translator::NoLocations);
+ } // </TS>
+ } else {
+ handleError();
+ }
+ }
+ if (hasError()) {
+ m_cd.appendError(errorString());
+ return false;
+ }
+ return true;
+}
+
+static QString numericEntity(int ch)
+{
+ return QString(ch <= 0x20 ? QLatin1String("<byte value=\"x%1\"/>")
+ : QLatin1String("&#x%1;")) .arg(ch, 0, 16);
+}
+
+static QString protect(const QString &str)
+{
+ QString result;
+ result.reserve(str.length() * 12 / 10);
+ for (int i = 0; i != str.size(); ++i) {
+ uint c = str.at(i).unicode();
+ switch (c) {
+ case '\"':
+ result += QLatin1String("&quot;");
+ break;
+ case '&':
+ result += QLatin1String("&amp;");
+ break;
+ case '>':
+ result += QLatin1String("&gt;");
+ break;
+ case '<':
+ result += QLatin1String("&lt;");
+ break;
+ case '\'':
+ result += QLatin1String("&apos;");
+ break;
+ default:
+ if (c < 0x20 && c != '\r' && c != '\n' && c != '\t')
+ result += numericEntity(c);
+ else // this also covers surrogates
+ result += QChar(c);
+ }
+ }
+ return result;
+}
+
+static QString evilBytes(const QString& str,
+ bool isUtf8, int format, const QByteArray &codecName)
+{
+ //qDebug() << "EVIL: " << str << isUtf8 << format << codecName;
+ if (isUtf8)
+ return protect(str);
+ if (format == 20)
+ return protect(str);
+ if (codecName == "UTF-8")
+ return protect(str);
+ QTextCodec *codec = QTextCodec::codecForName(codecName);
+ if (!codec)
+ return protect(str);
+ QString t = QString::fromLatin1(codec->fromUnicode(protect(str)).data());
+ int len = (int) t.length();
+ QString result;
+ // FIXME: Factor is sensible only for latin scripts, probably.
+ result.reserve(t.length() * 2);
+ for (int k = 0; k < len; k++) {
+ if (t[k].unicode() >= 0x7f)
+ result += numericEntity(t[k].unicode());
+ else
+ result += t[k];
+ }
+ return result;
+}
+
+static void writeExtras(QTextStream &t, const char *indent,
+ const TranslatorMessage::ExtraData &extras, const QRegExp &drops)
+{
+ for (Translator::ExtraData::ConstIterator it = extras.begin(); it != extras.end(); ++it) {
+ if (!drops.exactMatch(it.key())) {
+ t << indent << "<extra-" << it.key() << '>'
+ << protect(it.value())
+ << "</extra-" << it.key() << ">\n";
+ }
+ }
+}
+
+static void writeVariants(QTextStream &t, const char *indent, const QString &input)
+{
+ int offset;
+ if ((offset = input.indexOf(QChar(Translator::BinaryVariantSeparator))) >= 0) {
+ t << " variants=\"yes\">";
+ int start = 0;
+ forever {
+ t << "\n " << indent << "<lengthvariant>"
+ << protect(input.mid(start, offset - start))
+ << "</lengthvariant>";
+ if (offset == input.length())
+ break;
+ start = offset + 1;
+ offset = input.indexOf(QChar(Translator::BinaryVariantSeparator), start);
+ if (offset < 0)
+ offset = input.length();
+ }
+ t << "\n" << indent;
+ } else {
+ t << ">" << protect(input);
+ }
+}
+
+bool saveTS(const Translator &translator, QIODevice &dev, ConversionData &cd, int format)
+{
+ bool result = true;
+ QTextStream t(&dev);
+ t.setCodec(QTextCodec::codecForName("UTF-8"));
+ bool trIsUtf8 = (translator.codecName() == "UTF-8");
+ //qDebug() << translator.codecName();
+ bool fileIsUtf8 = (format == 20 || trIsUtf8);
+
+ // The xml prolog allows processors to easily detect the correct encoding
+ t << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n";
+
+ if (format == 11)
+ t << "<TS version=\"1.1\"";
+ else
+ t << "<TS version=\"2.0\"";
+
+ QString languageCode = translator.languageCode();
+ if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
+ t << " language=\"" << languageCode << "\"";
+ if (format == 20) {
+ languageCode = translator.sourceLanguageCode();
+ if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
+ t << " sourcelanguage=\"" << languageCode << "\"";
+ }
+ t << ">\n";
+
+ QByteArray codecName = translator.codecName();
+ if (codecName != "ISO-8859-1")
+ t << "<defaultcodec>" << codecName << "</defaultcodec>\n";
+
+ QRegExp drops(cd.dropTags().join(QLatin1String("|")));
+
+ if (format == 20)
+ writeExtras(t, " ", translator.extras(), drops);
+
+ QHash<QString, QList<TranslatorMessage> > messageOrder;
+ QList<QString> contextOrder;
+ foreach (const TranslatorMessage &msg, translator.messages()) {
+ // no need for such noise
+ if (msg.type() == TranslatorMessage::Obsolete && msg.translation().isEmpty())
+ continue;
+
+ QList<TranslatorMessage> &context = messageOrder[msg.context()];
+ if (context.isEmpty())
+ contextOrder.append(msg.context());
+ context.append(msg);
+ }
+ if (cd.sortContexts())
+ qSort(contextOrder);
+
+ QHash<QString, int> currentLine;
+ QString currentFile;
+ foreach (const QString &context, contextOrder) {
+ const TranslatorMessage &firstMsg = messageOrder[context].first();
+ t << "<context" << ((!fileIsUtf8 && firstMsg.isUtf8()) ? " encoding=\"UTF-8\"" : "") << ">\n";
+
+ t << " <name>"
+ << evilBytes(context, firstMsg.isUtf8() || fileIsUtf8, format, codecName)
+ << "</name>\n";
+ foreach (const TranslatorMessage &msg, messageOrder[context]) {
+ //msg.dump();
+
+ bool isUtf8 = msg.isUtf8();
+ bool second = false;
+ forever {
+
+ t << " <message";
+ if (!msg.id().isEmpty())
+ t << " id=\"" << msg.id() << "\"";
+ if (!trIsUtf8) {
+ if (format == 11) {
+ if (isUtf8)
+ t << " encoding=\"UTF-8\"";
+ } else {
+ if (msg.isUtf8()) {
+ if (msg.isNonUtf8())
+ t << " utf8=\"both\"";
+ else
+ t << " utf8=\"true\"";
+ }
+ }
+ }
+ if (msg.isPlural())
+ t << " numerus=\"yes\"";
+ t << ">\n";
+ if (translator.locationsType() != Translator::NoLocations) {
+ QString cfile = currentFile;
+ bool first = true;
+ foreach (const TranslatorMessage::Reference &ref, msg.allReferences()) {
+ QString fn = cd.m_targetDir.relativeFilePath(ref.fileName())
+ .replace(QLatin1Char('\\'),QLatin1Char('/'));
+ int ln = ref.lineNumber();
+ QString ld;
+ if (translator.locationsType() == Translator::RelativeLocations) {
+ if (ln != -1) {
+ int dlt = ln - currentLine[fn];
+ if (dlt >= 0)
+ ld.append(QLatin1Char('+'));
+ ld.append(QString::number(dlt));
+ currentLine[fn] = ln;
+ }
+
+ if (fn != cfile) {
+ if (first)
+ currentFile = fn;
+ cfile = fn;
+ } else {
+ fn.clear();
+ }
+ first = false;
+ } else {
+ if (ln != -1)
+ ld = QString::number(ln);
+ }
+ t << " <location";
+ if (!fn.isEmpty())
+ t << " filename=\"" << fn << "\"";
+ if (!ld.isEmpty())
+ t << " line=\"" << ld << "\"";
+ t << "/>\n";
+ }
+ }
+
+ t << " <source>"
+ << evilBytes(msg.sourceText(), isUtf8, format, codecName)
+ << "</source>\n";
+
+ if (format != 11 && !msg.oldSourceText().isEmpty())
+ t << " <oldsource>" << protect(msg.oldSourceText()) << "</oldsource>\n";
+
+ if (!msg.comment().isEmpty()) {
+ t << " <comment>"
+ << evilBytes(msg.comment(), isUtf8, format, codecName)
+ << "</comment>\n";
+ }
+
+ if (format != 11) {
+
+ if (!msg.oldComment().isEmpty())
+ t << " <oldcomment>" << protect(msg.oldComment()) << "</oldcomment>\n";
+
+ if (!msg.extraComment().isEmpty())
+ t << " <extracomment>" << protect(msg.extraComment())
+ << "</extracomment>\n";
+
+ if (!msg.translatorComment().isEmpty())
+ t << " <translatorcomment>" << protect(msg.translatorComment())
+ << "</translatorcomment>\n";
+
+ }
+
+ t << " <translation";
+ if (msg.type() == TranslatorMessage::Unfinished)
+ t << " type=\"unfinished\"";
+ else if (msg.type() == TranslatorMessage::Obsolete)
+ t << " type=\"obsolete\"";
+ if (msg.isPlural()) {
+ t << ">";
+ const QStringList &translns = msg.translations();
+ for (int j = 0; j < translns.count(); ++j) {
+ t << "\n <numerusform";
+ writeVariants(t, " ", translns[j]);
+ t << "</numerusform>";
+ }
+ t << "\n ";
+ } else {
+ writeVariants(t, " ", msg.translation());
+ }
+ t << "</translation>\n";
+
+ if (format != 11)
+ writeExtras(t, " ", msg.extras(), drops);
+
+ if (!msg.userData().isEmpty())
+ t << " <userdata>" << msg.userData() << "</userdata>\n";
+ t << " </message>\n";
+
+ if (format != 11 || second || !msg.isUtf8() || !msg.isNonUtf8())
+ break;
+ isUtf8 = false;
+ second = true;
+ }
+ }
+ t << "</context>\n";
+ }
+
+ t << "</TS>\n";
+ return result;
+}
+
+bool loadTS(Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ TSReader reader(dev, cd);
+ return reader.read(translator);
+}
+
+bool saveTS11(const Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ return saveTS(translator, dev, cd, 11);
+}
+
+bool saveTS20(const Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ return saveTS(translator, dev, cd, 20);
+}
+
+int initTS()
+{
+ Translator::FileFormat format;
+
+ format.extension = QLatin1String("ts11");
+ format.fileType = Translator::FileFormat::TranslationSource;
+ format.priority = -1;
+ format.description = QObject::tr("Qt translation sources (format 1.1)");
+ format.loader = &loadTS;
+ format.saver = &saveTS11;
+ Translator::registerFileFormat(format);
+
+ format.extension = QLatin1String("ts20");
+ format.fileType = Translator::FileFormat::TranslationSource;
+ format.priority = -1;
+ format.description = QObject::tr("Qt translation sources (format 2.0)");
+ format.loader = &loadTS;
+ format.saver = &saveTS20;
+ Translator::registerFileFormat(format);
+
+ // "ts" is always the latest. right now it's ts20.
+ format.extension = QLatin1String("ts");
+ format.fileType = Translator::FileFormat::TranslationSource;
+ format.priority = 0;
+ format.description = QObject::tr("Qt translation sources (latest format)");
+ format.loader = &loadTS;
+ format.saver = &saveTS20;
+ Translator::registerFileFormat(format);
+
+ return 1;
+}
+
+Q_CONSTRUCTOR_FUNCTION(initTS)
+
+QT_END_NAMESPACE
diff --git a/src/linguist/shared/ts.dtd b/src/linguist/shared/ts.dtd
new file mode 100644
index 000000000..12d356201
--- /dev/null
+++ b/src/linguist/shared/ts.dtd
@@ -0,0 +1,100 @@
+<!--
+ !
+ ! Some notes to the DTD:
+ !
+ ! The location element is set as optional since it was introduced first in Qt 4.2.
+ ! The userdata element is set as optional since it was introduced first in Qt 4.4.
+ !
+ -->
+<!--
+ ! Macro used in order to escape byte entities not allowed in an xml document
+ ! for instance, only #x9, #xA and #xD are allowed characters below #x20.
+ -->
+<!ENTITY % evilstring '(#PCDATA | byte)*' >
+<!ELEMENT byte EMPTY>
+<!-- value contains decimal (e.g. 1000) or hex (e.g. x3e8) unicode encoding of one char -->
+<!ATTLIST byte
+ value CDATA #REQUIRED>
+<!--
+ ! This element wildcard is no valid DTD. No better solution available.
+ ! extra elements may appear in TS and message elements. Each element may appear
+ ! only once within each scope. The contents are preserved verbatim; any
+ ! attributes are dropped. Currently recognized extra tags include:
+ ! extra-po-msgid_plural, extra-po-old_msgid_plural
+ ! extra-po-flags (comma-space separated list)
+ ! extra-loc-layout_id
+ ! extra-loc-feature
+ ! extra-loc-blank
+ -->
+<!ELEMENT extra-* %evilstring; >
+<!ELEMENT TS (defaultcodec?, extra-**, (context|message)+) >
+<!ATTLIST TS
+ version CDATA #IMPLIED
+ sourcelanguage CDATA #IMPLIED
+ language CDATA #IMPLIED>
+<!-- The encoding to use in the QM file by default. Default is ISO-8859-1. -->
+<!ELEMENT defaultcodec (#PCDATA) >
+<!ELEMENT context (name, comment?, (context|message)+) >
+<!ATTLIST context
+ encoding CDATA #IMPLIED>
+<!ELEMENT name %evilstring; >
+<!-- This is "disambiguation" in the (new) API, or "msgctxt" in gettext speak -->
+<!ELEMENT comment %evilstring; >
+<!-- Previous content of comment (result of merge) -->
+<!ELEMENT oldcomment %evilstring; >
+<!-- The real comment (added by developer/designer) -->
+<!ELEMENT extracomment %evilstring; >
+<!-- Comment added by translator -->
+<!ELEMENT translatorcomment %evilstring; >
+<!ELEMENT message (location*, source?, oldsource?, comment?, oldcomment?, extracomment?, translatorcomment?, translation?, userdata?, extra-**) >
+<!--
+ ! If utf8 is "true", the defaultcodec is overridden and the message is encoded
+ ! in UTF-8 in the QM file. If it is "both", both source encodings are stored
+ ! in the QM file.
+ -->
+<!ATTLIST message
+ id CDATA #IMPLIED
+ utf8 (true|false|both) "false"
+ numerus (yes|no) "no">
+<!ELEMENT location EMPTY>
+<!--
+ ! If the line is omitted, the location specifies only a file.
+ !
+ ! location supports relative specifications as well. Line numbers are
+ ! relative (explicitly positive or negative) to the last reference to a
+ ! given filename; each file starts with current line 0. If the filename
+ ! is omitted, the "current" one is used. For the 1st location in a message,
+ ! "current" is the filename used for the 1st location of the previous message.
+ ! For subsequent locations, it is the filename used for the previous location.
+ ! A single TS file has either all absolute or all relative locations.
+ -->
+<!ATTLIST location
+ filename CDATA #IMPLIED
+ line CDATA #IMPLIED>
+<!ELEMENT source %evilstring;>
+<!-- Previous content of source (result of merge) -->
+<!ELEMENT oldsource %evilstring;>
+<!--
+ ! The following should really say one evilstring macro or several
+ ! numerusform or lengthvariant elements, but the DTD can't express this.
+ -->
+<!ELEMENT translation (#PCDATA|byte|numerusform|lengthvariant)* >
+<!--
+ ! If no type is set, the message is "finished".
+ ! Length variants must be ordered by falling display length.
+ ! variants may not be yes if the message has numerus yes.
+ -->
+<!ATTLIST translation
+ type (unfinished|obsolete) #IMPLIED
+ variants (yes|no) "no">
+<!-- Deprecated. Use extra-* -->
+<!ELEMENT userdata (#PCDATA)* >
+<!--
+ ! The following should really say one evilstring macro or several
+ ! lengthvariant elements, but the DTD can't express this.
+ ! Length variants must be ordered by falling display length.
+ -->
+<!ELEMENT numerusform (#PCDATA|byte|lengthvariant)* >
+<!ATTLIST numerusform
+ variants (yes|no) "no">
+<!ELEMENT lengthvariant %evilstring; >
diff --git a/src/linguist/shared/xliff.cpp b/src/linguist/shared/xliff.cpp
new file mode 100644
index 000000000..40fbcabc1
--- /dev/null
+++ b/src/linguist/shared/xliff.cpp
@@ -0,0 +1,851 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translator.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QMap>
+#include <QtCore/QStack>
+#include <QtCore/QString>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+#include <QtXml/QXmlAttributes>
+#include <QtXml/QXmlDefaultHandler>
+#include <QtXml/QXmlParseException>
+
+
+// The string value is historical and reflects the main purpose: Keeping
+// obsolete entries separate from the magic file message (which both have
+// no location information, but typically reside at opposite ends of the file).
+#define MAGIC_OBSOLETE_REFERENCE "Obsolete_PO_entries"
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * Implementation of XLIFF file format for Linguist
+ */
+//static const char *restypeDomain = "x-gettext-domain";
+static const char *restypeContext = "x-trolltech-linguist-context";
+static const char *restypePlurals = "x-gettext-plurals";
+static const char *restypeDummy = "x-dummy";
+static const char *dataTypeUIFile = "x-trolltech-designer-ui";
+static const char *contextMsgctxt = "x-gettext-msgctxt"; // XXX Troll invention, so far.
+static const char *contextOldMsgctxt = "x-gettext-previous-msgctxt"; // XXX Troll invention, so far.
+static const char *attribPlural = "trolltech:plural";
+static const char *XLIFF11namespaceURI = "urn:oasis:names:tc:xliff:document:1.1";
+static const char *XLIFF12namespaceURI = "urn:oasis:names:tc:xliff:document:1.2";
+static const char *TrollTsNamespaceURI = "urn:trolltech:names:ts:document:1.0";
+
+#define COMBINE4CHARS(c1, c2, c3, c4) \
+ (int(c1) << 24 | int(c2) << 16 | int(c3) << 8 | int(c4) )
+
+static QString dataType(const TranslatorMessage &m)
+{
+ QByteArray fileName = m.fileName().toAscii();
+ unsigned int extHash = 0;
+ int pos = fileName.count() - 1;
+ for (int pass = 0; pass < 4 && pos >=0; ++pass, --pos) {
+ if (fileName.at(pos) == '.')
+ break;
+ extHash |= ((int)fileName.at(pos) << (8*pass));
+ }
+
+ switch (extHash) {
+ case COMBINE4CHARS(0,'c','p','p'):
+ case COMBINE4CHARS(0,'c','x','x'):
+ case COMBINE4CHARS(0,'c','+','+'):
+ case COMBINE4CHARS(0,'h','p','p'):
+ case COMBINE4CHARS(0,'h','x','x'):
+ case COMBINE4CHARS(0,'h','+','+'):
+ return QLatin1String("cpp");
+ case COMBINE4CHARS(0, 0 , 0 ,'c'):
+ case COMBINE4CHARS(0, 0 , 0 ,'h'):
+ case COMBINE4CHARS(0, 0 ,'c','c'):
+ case COMBINE4CHARS(0, 0 ,'c','h'):
+ case COMBINE4CHARS(0, 0 ,'h','h'):
+ return QLatin1String("c");
+ case COMBINE4CHARS(0, 0 ,'u','i'):
+ return QLatin1String(dataTypeUIFile); //### form?
+ default:
+ return QLatin1String("plaintext"); // we give up
+ }
+}
+
+static void writeIndent(QTextStream &ts, int indent)
+{
+ ts << QString().fill(QLatin1Char(' '), indent * 2);
+}
+
+struct CharMnemonic
+{
+ char ch;
+ char escape;
+ const char *mnemonic;
+};
+
+static const CharMnemonic charCodeMnemonics[] = {
+ {0x07, 'a', "bel"},
+ {0x08, 'b', "bs"},
+ {0x09, 't', "tab"},
+ {0x0a, 'n', "lf"},
+ {0x0b, 'v', "vt"},
+ {0x0c, 'f', "ff"},
+ {0x0d, 'r', "cr"}
+};
+
+static char charFromEscape(char escape)
+{
+ for (uint i = 0; i < sizeof(charCodeMnemonics)/sizeof(CharMnemonic); ++i) {
+ CharMnemonic cm = charCodeMnemonics[i];
+ if (cm.escape == escape)
+ return cm.ch;
+ }
+ Q_ASSERT(0);
+ return escape;
+}
+
+static QString numericEntity(int ch, bool makePhs)
+{
+ // ### This needs to be reviewed, to reflect the updated XLIFF-PO spec.
+ if (!makePhs || ch < 7 || ch > 0x0d)
+ return QString::fromAscii("&#x%1;").arg(QString::number(ch, 16));
+
+ CharMnemonic cm = charCodeMnemonics[int(ch) - 7];
+ QString name = QLatin1String(cm.mnemonic);
+ char escapechar = cm.escape;
+
+ static int id = 0;
+ return QString::fromAscii("<ph id=\"ph%1\" ctype=\"x-ch-%2\">\\%3</ph>")
+ .arg(++id) .arg(name) .arg(escapechar);
+}
+
+static QString protect(const QString &str, bool makePhs = true)
+{
+ QString result;
+ int len = str.size();
+ for (int i = 0; i != len; ++i) {
+ uint c = str.at(i).unicode();
+ switch (c) {
+ case '\"':
+ result += QLatin1String("&quot;");
+ break;
+ case '&':
+ result += QLatin1String("&amp;");
+ break;
+ case '>':
+ result += QLatin1String("&gt;");
+ break;
+ case '<':
+ result += QLatin1String("&lt;");
+ break;
+ case '\'':
+ result += QLatin1String("&apos;");
+ break;
+ default:
+ if (c < 0x20 && c != '\r' && c != '\n' && c != '\t')
+ result += numericEntity(c, makePhs);
+ else // this also covers surrogates
+ result += QChar(c);
+ }
+ }
+ return result;
+}
+
+
+static void writeExtras(QTextStream &ts, int indent,
+ const TranslatorMessage::ExtraData &extras, const QRegExp &drops)
+{
+ for (Translator::ExtraData::ConstIterator it = extras.begin(); it != extras.end(); ++it) {
+ if (!drops.exactMatch(it.key())) {
+ writeIndent(ts, indent);
+ ts << "<trolltech:" << it.key() << '>'
+ << protect(it.value())
+ << "</trolltech:" << it.key() << ">\n";
+ }
+ }
+}
+
+static void writeLineNumber(QTextStream &ts, const TranslatorMessage &msg, int indent)
+{
+ if (msg.lineNumber() == -1)
+ return;
+ writeIndent(ts, indent);
+ ts << "<context-group purpose=\"location\"><context context-type=\"linenumber\">"
+ << msg.lineNumber() << "</context></context-group>\n";
+ foreach (const TranslatorMessage::Reference &ref, msg.extraReferences()) {
+ writeIndent(ts, indent);
+ ts << "<context-group purpose=\"location\">";
+ if (ref.fileName() != msg.fileName())
+ ts << "<context context-type=\"sourcefile\">" << ref.fileName() << "</context>";
+ ts << "<context context-type=\"linenumber\">" << ref.lineNumber()
+ << "</context></context-group>\n";
+ }
+}
+
+static void writeComment(QTextStream &ts, const TranslatorMessage &msg, const QRegExp &drops, int indent)
+{
+ if (!msg.comment().isEmpty()) {
+ writeIndent(ts, indent);
+ ts << "<context-group><context context-type=\"" << contextMsgctxt << "\">"
+ << protect(msg.comment(), false)
+ << "</context></context-group>\n";
+ }
+ if (!msg.oldComment().isEmpty()) {
+ writeIndent(ts, indent);
+ ts << "<context-group><context context-type=\"" << contextOldMsgctxt << "\">"
+ << protect(msg.oldComment(), false)
+ << "</context></context-group>\n";
+ }
+ writeExtras(ts, indent, msg.extras(), drops);
+ if (!msg.extraComment().isEmpty()) {
+ writeIndent(ts, indent);
+ ts << "<note annotates=\"source\" from=\"developer\">"
+ << protect(msg.extraComment()) << "</note>\n";
+ }
+ if (!msg.translatorComment().isEmpty()) {
+ writeIndent(ts, indent);
+ ts << "<note from=\"translator\">"
+ << protect(msg.translatorComment()) << "</note>\n";
+ }
+}
+
+static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const QRegExp &drops, int indent)
+{
+ static int msgid;
+ QString msgidstr = !msg.id().isEmpty() ? msg.id() : QString::fromAscii("_msg%1").arg(++msgid);
+
+ QStringList translns = msg.translations();
+ QHash<QString, QString>::const_iterator it;
+ QString pluralStr;
+ QStringList sources(msg.sourceText());
+ if ((it = msg.extras().find(QString::fromLatin1("po-msgid_plural"))) != msg.extras().end())
+ sources.append(*it);
+ QStringList oldsources;
+ if (!msg.oldSourceText().isEmpty())
+ oldsources.append(msg.oldSourceText());
+ if ((it = msg.extras().find(QString::fromLatin1("po-old_msgid_plural"))) != msg.extras().end()) {
+ if (oldsources.isEmpty()) {
+ if (sources.count() == 2)
+ oldsources.append(QString());
+ else
+ pluralStr = QLatin1Char(' ') + QLatin1String(attribPlural) + QLatin1String("=\"yes\"");
+ }
+ oldsources.append(*it);
+ }
+
+ QStringList::const_iterator
+ srcit = sources.begin(), srcend = sources.end(),
+ oldsrcit = oldsources.begin(), oldsrcend = oldsources.end(),
+ transit = translns.begin(), transend = translns.end();
+ int plural = 0;
+ QString source;
+ while (srcit != srcend || oldsrcit != oldsrcend || transit != transend) {
+ QByteArray attribs;
+ QByteArray state;
+ if (msg.type() == TranslatorMessage::Obsolete) {
+ if (!msg.isPlural())
+ attribs = " translate=\"no\"";
+ } else if (msg.type() == TranslatorMessage::Finished) {
+ attribs = " approved=\"yes\"";
+ } else if (transit != transend && !transit->isEmpty()) {
+ state = " state=\"needs-review-translation\"";
+ }
+ writeIndent(ts, indent);
+ ts << "<trans-unit id=\"" << msgidstr;
+ if (msg.isPlural())
+ ts << "[" << plural++ << "]";
+ ts << "\"" << attribs << ">\n";
+ ++indent;
+
+ writeIndent(ts, indent);
+ if (srcit != srcend) {
+ source = *srcit;
+ ++srcit;
+ } // else just repeat last element
+ ts << "<source xml:space=\"preserve\">" << protect(source) << "</source>\n";
+
+ bool puttrans = false;
+ QString translation;
+ if (transit != transend) {
+ translation = *transit;
+ translation.replace(QChar(Translator::BinaryVariantSeparator),
+ QChar(Translator::TextVariantSeparator));
+ ++transit;
+ puttrans = true;
+ }
+ do {
+ if (oldsrcit != oldsrcend && !oldsrcit->isEmpty()) {
+ writeIndent(ts, indent);
+ ts << "<alt-trans>\n";
+ ++indent;
+ writeIndent(ts, indent);
+ ts << "<source xml:space=\"preserve\"" << pluralStr << '>' << protect(*oldsrcit) << "</source>\n";
+ if (!puttrans) {
+ writeIndent(ts, indent);
+ ts << "<target restype=\"" << restypeDummy << "\"/>\n";
+ }
+ }
+
+ if (puttrans) {
+ writeIndent(ts, indent);
+ ts << "<target xml:space=\"preserve\"" << state << ">" << protect(translation) << "</target>\n";
+ }
+
+ if (oldsrcit != oldsrcend) {
+ if (!oldsrcit->isEmpty()) {
+ --indent;
+ writeIndent(ts, indent);
+ ts << "</alt-trans>\n";
+ }
+ ++oldsrcit;
+ }
+
+ puttrans = false;
+ } while (srcit == srcend && oldsrcit != oldsrcend);
+
+ if (!msg.isPlural()) {
+ writeLineNumber(ts, msg, indent);
+ writeComment(ts, msg, drops, indent);
+ }
+
+ --indent;
+ writeIndent(ts, indent);
+ ts << "</trans-unit>\n";
+ }
+}
+
+static void writeMessage(QTextStream &ts, const TranslatorMessage &msg, const QRegExp &drops, int indent)
+{
+ if (msg.isPlural()) {
+ writeIndent(ts, indent);
+ ts << "<group restype=\"" << restypePlurals << "\"";
+ if (!msg.id().isEmpty())
+ ts << " id=\"" << msg.id() << "\"";
+ if (msg.type() == TranslatorMessage::Obsolete)
+ ts << " translate=\"no\"";
+ ts << ">\n";
+ ++indent;
+ writeLineNumber(ts, msg, indent);
+ writeComment(ts, msg, drops, indent);
+
+ writeTransUnits(ts, msg, drops, indent);
+ --indent;
+ writeIndent(ts, indent);
+ ts << "</group>\n";
+ } else {
+ writeTransUnits(ts, msg, drops, indent);
+ }
+}
+
+
+class XLIFFHandler : public QXmlDefaultHandler
+{
+public:
+ XLIFFHandler(Translator &translator, ConversionData &cd);
+
+ bool startElement(const QString& namespaceURI, const QString &localName,
+ const QString &qName, const QXmlAttributes &atts );
+ bool endElement(const QString& namespaceURI, const QString &localName,
+ const QString &qName );
+ bool characters(const QString &ch);
+ bool fatalError(const QXmlParseException &exception);
+
+ bool endDocument();
+
+private:
+ enum XliffContext {
+ XC_xliff,
+ XC_group,
+ XC_trans_unit,
+ XC_context_group,
+ XC_context_group_any,
+ XC_context,
+ XC_context_filename,
+ XC_context_linenumber,
+ XC_context_context,
+ XC_context_comment,
+ XC_context_old_comment,
+ XC_ph,
+ XC_extra_comment,
+ XC_translator_comment,
+ XC_restype_context,
+ XC_restype_translation,
+ XC_restype_plurals,
+ XC_alt_trans
+ };
+ void pushContext(XliffContext ctx);
+ bool popContext(XliffContext ctx);
+ XliffContext currentContext() const;
+ bool hasContext(XliffContext ctx) const;
+ bool finalizeMessage(bool isPlural);
+
+private:
+ Translator &m_translator;
+ ConversionData &m_cd;
+ TranslatorMessage::Type m_type;
+ QString m_language;
+ QString m_sourceLanguage;
+ QString m_context;
+ QString m_id;
+ QStringList m_sources;
+ QStringList m_oldSources;
+ QString m_comment;
+ QString m_oldComment;
+ QString m_extraComment;
+ QString m_translatorComment;
+ bool m_isPlural;
+ bool m_hadAlt;
+ QStringList m_translations;
+ QString m_fileName;
+ int m_lineNumber;
+ QString m_extraFileName;
+ TranslatorMessage::References m_refs;
+ TranslatorMessage::ExtraData m_extra;
+
+ QString accum;
+ QString m_ctype;
+ const QString m_URITT; // convenience and efficiency
+ const QString m_URI; // ...
+ const QString m_URI12; // ...
+ QStack<int> m_contextStack;
+};
+
+XLIFFHandler::XLIFFHandler(Translator &translator, ConversionData &cd)
+ : m_translator(translator), m_cd(cd),
+ m_type(TranslatorMessage::Finished),
+ m_lineNumber(-1),
+ m_URITT(QLatin1String(TrollTsNamespaceURI)),
+ m_URI(QLatin1String(XLIFF11namespaceURI)),
+ m_URI12(QLatin1String(XLIFF12namespaceURI))
+{}
+
+
+void XLIFFHandler::pushContext(XliffContext ctx)
+{
+ m_contextStack.push_back(ctx);
+}
+
+// Only pops it off if the top of the stack contains ctx
+bool XLIFFHandler::popContext(XliffContext ctx)
+{
+ if (!m_contextStack.isEmpty() && m_contextStack.top() == ctx) {
+ m_contextStack.pop();
+ return true;
+ }
+ return false;
+}
+
+XLIFFHandler::XliffContext XLIFFHandler::currentContext() const
+{
+ if (!m_contextStack.isEmpty())
+ return (XliffContext)m_contextStack.top();
+ return XC_xliff;
+}
+
+// traverses to the top to check all of the parent contexes.
+bool XLIFFHandler::hasContext(XliffContext ctx) const
+{
+ for (int i = m_contextStack.count() - 1; i >= 0; --i) {
+ if (m_contextStack.at(i) == ctx)
+ return true;
+ }
+ return false;
+}
+
+bool XLIFFHandler::startElement(const QString& namespaceURI,
+ const QString &localName, const QString &qName, const QXmlAttributes &atts )
+{
+ Q_UNUSED(qName);
+ if (namespaceURI == m_URITT)
+ goto bail;
+ if (namespaceURI != m_URI && namespaceURI != m_URI12)
+ return false;
+ if (localName == QLatin1String("xliff")) {
+ // make sure that the stack is not empty during parsing
+ pushContext(XC_xliff);
+ } else if (localName == QLatin1String("file")) {
+ m_fileName = atts.value(QLatin1String("original"));
+ m_language = atts.value(QLatin1String("target-language"));
+ m_language.replace(QLatin1Char('-'), QLatin1Char('_'));
+ m_sourceLanguage = atts.value(QLatin1String("source-language"));
+ m_sourceLanguage.replace(QLatin1Char('-'), QLatin1Char('_'));
+ if (m_sourceLanguage == QLatin1String("en"))
+ m_sourceLanguage.clear();
+ } else if (localName == QLatin1String("group")) {
+ if (atts.value(QLatin1String("restype")) == QLatin1String(restypeContext)) {
+ m_context = atts.value(QLatin1String("resname"));
+ pushContext(XC_restype_context);
+ } else {
+ if (atts.value(QLatin1String("restype")) == QLatin1String(restypePlurals)) {
+ pushContext(XC_restype_plurals);
+ m_id = atts.value(QLatin1String("id"));
+ if (atts.value(QLatin1String("translate")) == QLatin1String("no"))
+ m_type = TranslatorMessage::Obsolete;
+ } else {
+ pushContext(XC_group);
+ }
+ }
+ } else if (localName == QLatin1String("trans-unit")) {
+ if (!hasContext(XC_restype_plurals) || m_sources.isEmpty() /* who knows ... */)
+ if (atts.value(QLatin1String("translate")) == QLatin1String("no"))
+ m_type = TranslatorMessage::Obsolete;
+ if (!hasContext(XC_restype_plurals)) {
+ m_id = atts.value(QLatin1String("id"));
+ if (m_id.startsWith(QLatin1String("_msg")))
+ m_id.clear();
+ }
+ if (m_type != TranslatorMessage::Obsolete &&
+ atts.value(QLatin1String("approved")) != QLatin1String("yes"))
+ m_type = TranslatorMessage::Unfinished;
+ pushContext(XC_trans_unit);
+ m_hadAlt = false;
+ } else if (localName == QLatin1String("alt-trans")) {
+ pushContext(XC_alt_trans);
+ } else if (localName == QLatin1String("source")) {
+ m_isPlural = atts.value(QLatin1String(attribPlural)) == QLatin1String("yes");
+ } else if (localName == QLatin1String("target")) {
+ if (atts.value(QLatin1String("restype")) != QLatin1String(restypeDummy))
+ pushContext(XC_restype_translation);
+ } else if (localName == QLatin1String("context-group")) {
+ QString purpose = atts.value(QLatin1String("purpose"));
+ if (purpose == QLatin1String("location"))
+ pushContext(XC_context_group);
+ else
+ pushContext(XC_context_group_any);
+ } else if (currentContext() == XC_context_group && localName == QLatin1String("context")) {
+ QString ctxtype = atts.value(QLatin1String("context-type"));
+ if (ctxtype == QLatin1String("linenumber"))
+ pushContext(XC_context_linenumber);
+ else if (ctxtype == QLatin1String("sourcefile"))
+ pushContext(XC_context_filename);
+ } else if (currentContext() == XC_context_group_any && localName == QLatin1String("context")) {
+ QString ctxtype = atts.value(QLatin1String("context-type"));
+ if (ctxtype == QLatin1String(contextMsgctxt))
+ pushContext(XC_context_comment);
+ else if (ctxtype == QLatin1String(contextOldMsgctxt))
+ pushContext(XC_context_old_comment);
+ } else if (localName == QLatin1String("note")) {
+ if (atts.value(QLatin1String("annotates")) == QLatin1String("source") &&
+ atts.value(QLatin1String("from")) == QLatin1String("developer"))
+ pushContext(XC_extra_comment);
+ else
+ pushContext(XC_translator_comment);
+ } else if (localName == QLatin1String("ph")) {
+ QString ctype = atts.value(QLatin1String("ctype"));
+ if (ctype.startsWith(QLatin1String("x-ch-")))
+ m_ctype = ctype.mid(5);
+ pushContext(XC_ph);
+ }
+bail:
+ if (currentContext() != XC_ph)
+ accum.clear();
+ return true;
+}
+
+bool XLIFFHandler::endElement(const QString &namespaceURI, const QString& localName,
+ const QString &qName)
+{
+ Q_UNUSED(qName);
+ if (namespaceURI == m_URITT) {
+ if (hasContext(XC_trans_unit) || hasContext(XC_restype_plurals))
+ m_extra[localName] = accum;
+ else
+ m_translator.setExtra(localName, accum);
+ return true;
+ }
+ if (namespaceURI != m_URI && namespaceURI != m_URI12)
+ return false;
+ //qDebug() << "URI:" << namespaceURI << "QNAME:" << qName;
+ if (localName == QLatin1String("xliff")) {
+ popContext(XC_xliff);
+ } else if (localName == QLatin1String("source")) {
+ if (hasContext(XC_alt_trans)) {
+ if (m_isPlural && m_oldSources.isEmpty())
+ m_oldSources.append(QString());
+ m_oldSources.append(accum);
+ m_hadAlt = true;
+ } else {
+ m_sources.append(accum);
+ }
+ } else if (localName == QLatin1String("target")) {
+ if (popContext(XC_restype_translation)) {
+ accum.replace(QChar(Translator::TextVariantSeparator),
+ QChar(Translator::BinaryVariantSeparator));
+ m_translations.append(accum);
+ }
+ } else if (localName == QLatin1String("context-group")) {
+ if (popContext(XC_context_group)) {
+ m_refs.append(TranslatorMessage::Reference(
+ m_extraFileName.isEmpty() ? m_fileName : m_extraFileName, m_lineNumber));
+ m_extraFileName.clear();
+ m_lineNumber = -1;
+ } else {
+ popContext(XC_context_group_any);
+ }
+ } else if (localName == QLatin1String("context")) {
+ if (popContext(XC_context_linenumber)) {
+ bool ok;
+ m_lineNumber = accum.trimmed().toInt(&ok);
+ if (!ok)
+ m_lineNumber = -1;
+ } else if (popContext(XC_context_filename)) {
+ m_extraFileName = accum;
+ } else if (popContext(XC_context_comment)) {
+ m_comment = accum;
+ } else if (popContext(XC_context_old_comment)) {
+ m_oldComment = accum;
+ }
+ } else if (localName == QLatin1String("note")) {
+ if (popContext(XC_extra_comment))
+ m_extraComment = accum;
+ else if (popContext(XC_translator_comment))
+ m_translatorComment = accum;
+ } else if (localName == QLatin1String("ph")) {
+ m_ctype.clear();
+ popContext(XC_ph);
+ } else if (localName == QLatin1String("trans-unit")) {
+ popContext(XC_trans_unit);
+ if (!m_hadAlt)
+ m_oldSources.append(QString());
+ if (!hasContext(XC_restype_plurals)) {
+ if (!finalizeMessage(false))
+ return false;
+ }
+ } else if (localName == QLatin1String("alt-trans")) {
+ popContext(XC_alt_trans);
+ } else if (localName == QLatin1String("group")) {
+ if (popContext(XC_restype_plurals)) {
+ if (!finalizeMessage(true))
+ return false;
+ } else if (popContext(XC_restype_context)) {
+ m_context.clear();
+ } else {
+ popContext(XC_group);
+ }
+ }
+ return true;
+}
+
+bool XLIFFHandler::characters(const QString &ch)
+{
+ if (currentContext() == XC_ph) {
+ // handle the content of <ph> elements
+ for (int i = 0; i < ch.count(); ++i) {
+ QChar chr = ch.at(i);
+ if (accum.endsWith(QLatin1Char('\\')))
+ accum[accum.size() - 1] = QLatin1Char(charFromEscape(chr.toAscii()));
+ else
+ accum.append(chr);
+ }
+ } else {
+ QString t = ch;
+ t.replace(QLatin1String("\r"), QLatin1String(""));
+ accum.append(t);
+ }
+ return true;
+}
+
+bool XLIFFHandler::endDocument()
+{
+ m_translator.setLanguageCode(m_language);
+ m_translator.setSourceLanguageCode(m_sourceLanguage);
+ return true;
+}
+
+bool XLIFFHandler::finalizeMessage(bool isPlural)
+{
+ if (m_sources.isEmpty()) {
+ m_cd.appendError(QLatin1String("XLIFF syntax error: Message without source string."));
+ return false;
+ }
+ if (m_type == TranslatorMessage::Obsolete && m_refs.size() == 1
+ && m_refs.at(0).fileName() == QLatin1String(MAGIC_OBSOLETE_REFERENCE))
+ m_refs.clear();
+ TranslatorMessage msg(m_context, m_sources[0],
+ m_comment, QString(), QString(), -1,
+ m_translations, m_type, isPlural);
+ msg.setId(m_id);
+ msg.setReferences(m_refs);
+ msg.setOldComment(m_oldComment);
+ msg.setExtraComment(m_extraComment);
+ msg.setTranslatorComment(m_translatorComment);
+ if (m_sources.count() > 1 && m_sources[1] != m_sources[0])
+ m_extra.insert(QLatin1String("po-msgid_plural"), m_sources[1]);
+ if (!m_oldSources.isEmpty()) {
+ if (!m_oldSources[0].isEmpty())
+ msg.setOldSourceText(m_oldSources[0]);
+ if (m_oldSources.count() > 1 && m_oldSources[1] != m_oldSources[0])
+ m_extra.insert(QLatin1String("po-old_msgid_plural"), m_oldSources[1]);
+ }
+ msg.setExtras(m_extra);
+ m_translator.append(msg);
+
+ m_id.clear();
+ m_sources.clear();
+ m_oldSources.clear();
+ m_translations.clear();
+ m_comment.clear();
+ m_oldComment.clear();
+ m_extraComment.clear();
+ m_translatorComment.clear();
+ m_extra.clear();
+ m_refs.clear();
+ m_type = TranslatorMessage::Finished;
+ return true;
+}
+
+bool XLIFFHandler::fatalError(const QXmlParseException &exception)
+{
+ QString msg;
+ msg.sprintf("XML error: Parse error at line %d, column %d (%s).\n",
+ exception.lineNumber(), exception.columnNumber(),
+ exception.message().toLatin1().data() );
+ m_cd.appendError(msg);
+ return false;
+}
+
+bool loadXLIFF(Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ QXmlInputSource in(&dev);
+ QXmlSimpleReader reader;
+ XLIFFHandler hand(translator, cd);
+ reader.setContentHandler(&hand);
+ reader.setErrorHandler(&hand);
+ return reader.parse(in);
+}
+
+bool saveXLIFF(const Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ bool ok = true;
+ int indent = 0;
+
+ QTextStream ts(&dev);
+ ts.setCodec(QTextCodec::codecForName("UTF-8"));
+
+ QStringList dtgs = cd.dropTags();
+ dtgs << QLatin1String("po-(old_)?msgid_plural");
+ QRegExp drops(dtgs.join(QLatin1String("|")));
+
+ QHash<QString, QHash<QString, QList<TranslatorMessage> > > messageOrder;
+ QHash<QString, QList<QString> > contextOrder;
+ QList<QString> fileOrder;
+ foreach (const TranslatorMessage &msg, translator.messages()) {
+ QString fn = msg.fileName();
+ if (fn.isEmpty() && msg.type() == TranslatorMessage::Obsolete)
+ fn = QLatin1String(MAGIC_OBSOLETE_REFERENCE);
+ QHash<QString, QList<TranslatorMessage> > &file = messageOrder[fn];
+ if (file.isEmpty())
+ fileOrder.append(fn);
+ QList<TranslatorMessage> &context = file[msg.context()];
+ if (context.isEmpty())
+ contextOrder[fn].append(msg.context());
+ context.append(msg);
+ }
+
+ ts.setFieldAlignment(QTextStream::AlignRight);
+ ts << "<?xml version=\"1.0\"";
+ ts << " encoding=\"utf-8\"?>\n";
+ ts << "<xliff version=\"1.2\" xmlns=\"" << XLIFF12namespaceURI
+ << "\" xmlns:trolltech=\"" << TrollTsNamespaceURI << "\">\n";
+ ++indent;
+ writeExtras(ts, indent, translator.extras(), drops);
+ QString sourceLanguageCode = translator.sourceLanguageCode();
+ if (sourceLanguageCode.isEmpty() || sourceLanguageCode == QLatin1String("C"))
+ sourceLanguageCode = QLatin1String("en");
+ else
+ sourceLanguageCode.replace(QLatin1Char('_'), QLatin1Char('-'));
+ QString languageCode = translator.languageCode();
+ languageCode.replace(QLatin1Char('_'), QLatin1Char('-'));
+ foreach (const QString &fn, fileOrder) {
+ writeIndent(ts, indent);
+ ts << "<file original=\"" << fn << "\""
+ << " datatype=\"" << dataType(messageOrder[fn].begin()->first()) << "\""
+ << " source-language=\"" << sourceLanguageCode.toLatin1() << "\""
+ << " target-language=\"" << languageCode.toLatin1() << "\""
+ << "><body>\n";
+ ++indent;
+
+ foreach (const QString &ctx, contextOrder[fn]) {
+ if (!ctx.isEmpty()) {
+ writeIndent(ts, indent);
+ ts << "<group restype=\"" << restypeContext << "\""
+ << " resname=\"" << protect(ctx) << "\">\n";
+ ++indent;
+ }
+
+ foreach (const TranslatorMessage &msg, messageOrder[fn][ctx])
+ writeMessage(ts, msg, drops, indent);
+
+ if (!ctx.isEmpty()) {
+ --indent;
+ writeIndent(ts, indent);
+ ts << "</group>\n";
+ }
+ }
+
+ --indent;
+ writeIndent(ts, indent);
+ ts << "</body></file>\n";
+ }
+ --indent;
+ writeIndent(ts, indent);
+ ts << "</xliff>\n";
+
+ return ok;
+}
+
+int initXLIFF()
+{
+ Translator::FileFormat format;
+ format.extension = QLatin1String("xlf");
+ format.description = QObject::tr("XLIFF localization files");
+ format.fileType = Translator::FileFormat::TranslationSource;
+ format.priority = 1;
+ format.loader = &loadXLIFF;
+ format.saver = &saveXLIFF;
+ Translator::registerFileFormat(format);
+ return 1;
+}
+
+Q_CONSTRUCTOR_FUNCTION(initXLIFF)
+
+QT_END_NAMESPACE
diff --git a/src/linguist/tests/data/main.cpp b/src/linguist/tests/data/main.cpp
new file mode 100644
index 000000000..dff1364dd
--- /dev/null
+++ b/src/linguist/tests/data/main.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include <QtCore>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QStringList args = app.arguments();
+
+ if (argc <= 1) {
+ qDebug() << "Usage: " << qPrintable(args[0]) << " <ts-file>";
+ return 1;
+ }
+
+ QTranslator trans;
+ trans.load(args[1], ".");
+ app.installTranslator(&trans);
+
+ QWidget w;
+ QVBoxLayout *layout = new QVBoxLayout(&w);
+
+ QLabel label1(QObject::tr("XXXXXXXXX \33 XXXXXXXXXXX • and → "), 0);
+ QLabel label2(QObject::tr("\32"), 0);
+ QLabel label3(QObject::tr("\176"), 0);
+ QLabel label4(QObject::tr("\301"), 0);
+
+ layout->addWidget(&label1);
+ layout->addWidget(&label2);
+ layout->addWidget(&label3);
+ layout->addWidget(&label4);
+
+ w.show();
+
+ return app.exec();
+}
diff --git a/src/linguist/tests/data/test.pro b/src/linguist/tests/data/test.pro
new file mode 100644
index 000000000..90e5704b4
--- /dev/null
+++ b/src/linguist/tests/data/test.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET +=
+DEPENDPATH += .
+INCLUDEPATH += .
+
+SOURCES += main.cpp
+
+TRANSLATIONS += t1_en.ts
+TRANSLATIONS += t1_de.ts
diff --git a/src/linguist/tests/tests.pro b/src/linguist/tests/tests.pro
new file mode 100644
index 000000000..a67725c46
--- /dev/null
+++ b/src/linguist/tests/tests.pro
@@ -0,0 +1,16 @@
+load(qttest_p4)
+
+QT += xml
+
+HEADERS += \
+ tst_linguist.h \
+ ../shared/translator.h
+
+SOURCES += \
+ tst_linguist.cpp \
+ tst_lupdate.cpp \
+ tst_simtexth.cpp \
+ ../shared/simtexth.cpp \
+ ../shared/translator.cpp \
+ ../shared/translatormessage.cpp \
+ ../shared/xliff.cpp
diff --git a/src/linguist/tests/tst_linguist.cpp b/src/linguist/tests/tst_linguist.cpp
new file mode 100644
index 000000000..7abefd226
--- /dev/null
+++ b/src/linguist/tests/tst_linguist.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tst_linguist.h"
+#include "moc_tst_linguist.cpp"
+
+QTEST_MAIN(tst_linguist)
diff --git a/src/linguist/tests/tst_linguist.h b/src/linguist/tests/tst_linguist.h
new file mode 100644
index 000000000..4b329b899
--- /dev/null
+++ b/src/linguist/tests/tst_linguist.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TST_LINGUIST
+#define TST_LINGUIST
+
+#include <QtTest/QtTest>
+#include <QtCore/QtCore>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+
+class tst_linguist : public QObject
+{
+ Q_OBJECT
+private slots:
+ void fetchtr();
+ void fetchtr_data();
+
+ void simtexth();
+ void simtexth_data();
+};
+
+#endif
diff --git a/src/linguist/tests/tst_lupdate.cpp b/src/linguist/tests/tst_lupdate.cpp
new file mode 100644
index 000000000..c39525622
--- /dev/null
+++ b/src/linguist/tests/tst_lupdate.cpp
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtCore/QtCore>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#include "tst_linguist.h"
+
+void tst_linguist::fetchtr()
+{
+ // FIXME: This probably should use some yet-to-be-invented
+ // binary interface to 'lupdate' instead of playing around
+ // with the filesystem,
+
+ QRegExp reg("\\s*");
+ QString lupdate("lupdate");
+
+ QFETCH(QString, input);
+
+ QFETCH(QString, name);
+ QFETCH(QString, file);
+ QFETCH(QString, line);
+ QFETCH(QString, src);
+
+ QString result;
+
+ QTemporaryFile profile("tst_lu_XXXXXX.pro");
+ QTemporaryFile cppfile("tst_lu_XXXXXX.cpp");
+ QTemporaryFile tsfile("tst_lu_XXXXXX.ts");
+
+ profile.open();
+ cppfile.open();
+ tsfile.open();
+
+#if 0
+ profile.setAutoRemove(false);
+ cppfile.setAutoRemove(false);
+ tsfile.setAutoRemove(false);
+
+ qDebug() << ".pro: " << profile.fileName();
+ qDebug() << ".cpp: " << cppfile.fileName();
+ qDebug() << ".ts: " << tsfile.fileName();
+#endif
+
+ QTextStream prots(&profile);
+ prots << "SOURCES += " << cppfile.fileName() << "\n";
+ prots << "TRANSLATIONS += " << tsfile.fileName() << "\n";
+ prots.flush();
+
+ QTextStream cppts(&cppfile);
+ cppts.setCodec("ISO 8859-1");
+ cppts << input << '\n';
+ cppts.flush();
+
+ QProcess proc;
+ proc.start(lupdate, QStringList() << profile.fileName());
+ proc.waitForFinished();
+
+ result = tsfile.readAll();
+
+ static QRegExp re(
+ "<name>(.+)</name>\\s*"
+ "<message.*>\\s*" // there might be a numerus="yes" attribiute
+ "<location filename=\"(.+)\" line=\"(\\d+)\"/>\\s*"
+ "<source>(.+)</source>\\s*"
+ "<translation type=\"unfinished\">.*</translation>\\s*"
+ );
+
+ re.indexIn(result);
+ QString resname = re.cap(1);
+ //QString resfile = re.cap(2);
+ QString resline = re.cap(3);
+ QString ressrc = re.cap(4);
+
+ //qDebug() << "pattern:" << re.pattern();
+ //qDebug() << "result:" << result;
+ //qDebug() << "resname:" << resname;
+ ////qDebug() << "resfile:" << resfile;
+ //qDebug() << "resline:" << resline;
+ //qDebug() << "ressource:" << ressrc;
+
+ QCOMPARE(src + ": " + resname, src + ": " + name);
+ QCOMPARE(src + ": " + resline, src + ": " + line);
+ QCOMPARE(src + ": " + ressrc, src + ": " + src);
+}
+
+void tst_linguist::fetchtr_data()
+{
+ using namespace QTest;
+
+ addColumn<QString>("input");
+ addColumn<QString>("name");
+ addColumn<QString>("file");
+ addColumn<QString>("line");
+ addColumn<QString>("src");
+
+ // plain stuff
+ newRow("00") << "int main() { tr(\"foo\"); }"
+ << "@default" << "XXXXXX" << "1" << "foo";
+
+ // space at beginning of text
+ newRow("01") << "int main() { tr(\" foo\"); }"
+ << "@default" << "XXXXXX" << "1" << " foo";
+ // space at end of text
+ newRow("02") << "int main() { tr(\"foo \"); }"
+ << "@default" << "XXXXXX" << "1" << "foo ";
+ // space in the middle of the text
+ newRow("03") << "int main() { tr(\"foo bar\"); }"
+ << "@default" << "XXXXXX" << "1" << "foo bar";
+
+ // tab at beginning of text
+ newRow("04") << "int main() { tr(\"\tfoo\"); }"
+ << "@default" << "XXXXXX" << "1" << "<byte value=\"x9\"/>foo";
+ // tab at end of text
+ newRow("05") << "int main() { tr(\"foo\t\"); }"
+ << "@default" << "XXXXXX" << "1" << "foo<byte value=\"x9\"/>";
+ // tab in the middle of the text
+ newRow("06") << "int main() { tr(\"foo\tbar\"); }"
+ << "@default" << "XXXXXX" << "1" << "foo<byte value=\"x9\"/>bar";
+
+ // check for unicode
+ newRow("07") << "int main() { tr(\"\32\"); }" // 26 dec
+ << "@default" << "XXXXXX" << "1" << "<byte value=\"x1a\"/>";
+ // check for unicode
+ newRow("08") << "int main() { tr(\"\33\"); }" // 27 dec
+ << "@default" << "XXXXXX" << "1" << "<byte value=\"x1b\"/>";
+ // check for unicode
+ newRow("09") << "int main() { tr(\"\176\"); }" // 124 dec
+ << "@default" << "XXXXXX" << "1" << "~";
+ // check for unicode
+ newRow("10") << "int main() { tr(\"\301\"); }" // 193 dec
+ << "@default" << "XXXXXX" << "1" << "&#xc1;";
+
+ // Bug 162562: lupdate does not find QCoreApplication::translate() strings
+ newRow("11") << "int main() { QString s = QCoreApplication::translate"
+ "(\"mycontext\", \"msg\", \"\", QCoreApplication::CodecForTr, 2);"
+ << "mycontext" << "XXXXXX" << "1" << "msg";
+
+ // Bug 161504: lupdate produces wrong ts file with context "N::QObject"
+ newRow("12") << "namespace N { QString foo() "
+ "{ return QObject::tr(\"msg\"); }"
+ << "QObject" << "XXXXXX" << "1" << "msg";
+
+ // Correct example from 161504:
+ newRow("13") << "namespace N { QString foo(); }"
+ "QString N::anyfunc() { return QObject::tr(\"msg\"); }"
+ << "QObject" << "XXXXXX" << "1" << "msg";
+
+ // Bug 161106: When specifying ::QObject::tr() then lupdate will
+ // take the previous word as being the namespace
+ newRow("14") << " std::cout << ::QObject::tr(\"msg\");"
+ << "QObject" << "XXXXXX" << "1" << "msg";
+
+}
diff --git a/src/linguist/tests/tst_simtexth.cpp b/src/linguist/tests/tst_simtexth.cpp
new file mode 100644
index 000000000..d254bd92c
--- /dev/null
+++ b/src/linguist/tests/tst_simtexth.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtCore/QtCore>
+
+//int getSimilarityScore(const QString &str1, const char* str2);
+#include "../shared/simtexth.h"
+#include "tst_linguist.h"
+
+void tst_linguist::simtexth()
+{
+ QFETCH(QString, one);
+ QFETCH(QString, two);
+ QFETCH(int, expected);
+
+ int measured = getSimilarityScore(one, two.toLatin1());
+ QCOMPARE(measured, expected);
+}
+
+
+void tst_linguist::simtexth_data()
+{
+ using namespace QTest;
+
+ addColumn<QString>("one");
+ addColumn<QString>("two");
+ addColumn<int>("expected");
+
+ newRow("00") << "" << "" << 1024;
+ newRow("01") << "a" << "a" << 1024;
+ newRow("02") << "ab" << "ab" << 1024;
+ newRow("03") << "abc" << "abc" << 1024;
+ newRow("04") << "abcd" << "abcd" << 1024;
+}
diff --git a/src/macdeployqt/macchangeqt/macchangeqt.pro b/src/macdeployqt/macchangeqt/macchangeqt.pro
new file mode 100644
index 000000000..c09fea3be
--- /dev/null
+++ b/src/macdeployqt/macchangeqt/macchangeqt.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET = macchangeqt
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += main.cpp ../shared/shared.cpp
+CONFIG += qt warn_on
+CONFIG -= app_bundle
diff --git a/src/macdeployqt/macchangeqt/main.cpp b/src/macdeployqt/macchangeqt/main.cpp
new file mode 100644
index 000000000..27ebac04c
--- /dev/null
+++ b/src/macdeployqt/macchangeqt/main.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "../shared/shared.h"
+
+int main(int argc, char **argv)
+{
+ // useDebugLibs should always be false because even if set all Qt
+ // libraries inside a binary to point to debug versions, as soon as
+ // one of them loads a Qt plugin, the plugin itself will load the
+ // release version of Qt, and as such, the app will crash.
+ bool useDebugLibs = false;
+
+ int optionsSpecified = 0;
+ for (int i = 2; i < argc; ++i) {
+ QByteArray argument = QByteArray(argv[i]);
+ if (argument.startsWith(QByteArray("-verbose="))) {
+ LogDebug() << "Argument found:" << argument;
+ optionsSpecified++;
+ int index = argument.indexOf("=");
+ bool ok = false;
+ int number = argument.mid(index+1).toInt(&ok);
+ if (!ok)
+ LogError() << "Could not parse verbose level";
+ else
+ logLevel = number;
+ }
+ }
+
+ if (argc != (3 + optionsSpecified)) {
+ qDebug() << "Changeqt: changes witch Qt frameworks an application links against.";
+ qDebug() << "Usage: changeqt app-bundle qt-dir <-verbose=[0-3]>";
+ return 0;
+ }
+
+ const QString appPath = QString::fromLocal8Bit(argv[1]);
+ const QString qtPath = QString::fromLocal8Bit(argv[2]);
+ changeQtFrameworks(appPath, qtPath, useDebugLibs);
+}
diff --git a/src/macdeployqt/macdeployqt.pro b/src/macdeployqt/macdeployqt.pro
new file mode 100644
index 000000000..09ed6989a
--- /dev/null
+++ b/src/macdeployqt/macdeployqt.pro
@@ -0,0 +1,7 @@
+
+mac {
+
+TEMPLATE = subdirs
+SUBDIRS = macdeployqt macchangeqt
+
+}
diff --git a/src/macdeployqt/macdeployqt/macdeployqt.pro b/src/macdeployqt/macdeployqt/macdeployqt.pro
new file mode 100644
index 000000000..3e56024fd
--- /dev/null
+++ b/src/macdeployqt/macdeployqt/macdeployqt.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = macdeployqt
+DEPENDPATH += .
+INCLUDEPATH += .
+DESTDIR = ../../../bin
+
+# Input
+SOURCES += main.cpp ../shared/shared.cpp
+CONFIG += qt warn_on
+CONFIG -= app_bundle
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/macdeployqt/macdeployqt/main.cpp b/src/macdeployqt/macdeployqt/main.cpp
new file mode 100644
index 000000000..9d326c27d
--- /dev/null
+++ b/src/macdeployqt/macdeployqt/main.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "../shared/shared.h"
+#include <qdir.h>
+
+int main(int argc, char **argv)
+{
+ QString appBundlePath;
+ if (argc > 1)
+ appBundlePath = QString::fromLocal8Bit(argv[1]);
+
+ if (argc < 2 || appBundlePath.startsWith("-")) {
+ qDebug() << "Usage: macdeployqt app-bundle [options]";
+ qDebug() << "";
+ qDebug() << "Options:";
+ qDebug() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug";
+ qDebug() << " -no-plugins : Skip plugin deployment";
+ qDebug() << " -dmg : Create a .dmg disk image";
+ qDebug() << " -no-strip : Don't run 'strip' on the binaries";
+ qDebug() << " -use-debug-libs : Deploy with debug versions of frameworks and plugins (implies -no-strip)";
+ qDebug() << "";
+ qDebug() << "macdeployqt takes an application bundle as input and makes it";
+ qDebug() << "self-contained by copying in the Qt frameworks and plugins that";
+ qDebug() << "the application uses.";
+ qDebug() << "";
+ qDebug() << "Plugins related to a framework are copied in with the";
+ qDebug() << "framework. The accessibilty, image formats, and text codec";
+ qDebug() << "plugins are always copied, unless \"-no-plugins\" is specified.";
+ qDebug() << "";
+ qDebug() << "See the \"Deploying an Application on Qt/Mac\" topic in the";
+ qDebug() << "documentation for more information about deployment on Mac OS X.";
+
+ return 0;
+ }
+
+ if (appBundlePath.endsWith("/"))
+ appBundlePath.chop(1);
+
+ if (QDir().exists(appBundlePath) == false) {
+ qDebug() << "Error: Could not find app bundle" << appBundlePath;
+ return 0;
+ }
+
+ bool plugins = true;
+ bool dmg = false;
+ bool useDebugLibs = false;
+ extern bool runStripEnabled;
+
+ for (int i = 2; i < argc; ++i) {
+ QByteArray argument = QByteArray(argv[i]);
+ if (argument == QByteArray("-no-plugins")) {
+ LogDebug() << "Argument found:" << argument;
+ plugins = false;
+ } else if (argument == QByteArray("-dmg")) {
+ LogDebug() << "Argument found:" << argument;
+ dmg = true;
+ } else if (argument == QByteArray("-no-strip")) {
+ LogDebug() << "Argument found:" << argument;
+ runStripEnabled = false;
+ } else if (argument == QByteArray("-use-debug-libs")) {
+ LogDebug() << "Argument found:" << argument;
+ useDebugLibs = true;
+ runStripEnabled = false;
+ } else if (argument.startsWith(QByteArray("-verbose"))) {
+ LogDebug() << "Argument found:" << argument;
+ int index = argument.indexOf("=");
+ bool ok = false;
+ int number = argument.mid(index+1).toInt(&ok);
+ if (!ok)
+ LogError() << "Could not parse verbose level";
+ else
+ logLevel = number;
+ } else if (argument.startsWith("-")) {
+ LogError() << "Unknown argument" << argument << "\n";
+ return 0;
+ }
+ }
+
+ DeploymentInfo deploymentInfo = deployQtFrameworks(appBundlePath, useDebugLibs);
+
+ if (plugins) {
+ if (deploymentInfo.qtPath.isEmpty())
+ deploymentInfo.pluginPath = "/Developer/Applications/Qt/plugins"; // Assume binary package.
+ else
+ deploymentInfo.pluginPath = deploymentInfo.qtPath + "/plugins";
+
+ LogNormal();
+ deployPlugins(appBundlePath, deploymentInfo, useDebugLibs);
+ createQtConf(appBundlePath);
+ }
+
+ if (dmg) {
+ LogNormal();
+ createDiskImage(appBundlePath);
+ }
+}
+
diff --git a/src/macdeployqt/shared/shared.cpp b/src/macdeployqt/shared/shared.cpp
new file mode 100644
index 000000000..36a080ce0
--- /dev/null
+++ b/src/macdeployqt/shared/shared.cpp
@@ -0,0 +1,586 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QString>
+#include <QStringList>
+#include <QDebug>
+#include <iostream>
+#include <QProcess>
+#include <QDir>
+#include <QRegExp>
+#include <QSet>
+#include <QDirIterator>
+#include "shared.h"
+
+bool runStripEnabled = true;
+int logLevel = 1;
+
+using std::cout;
+using std::endl;
+
+bool operator==(const FrameworkInfo &a, const FrameworkInfo &b)
+{
+ return ((a.frameworkPath == b.frameworkPath) && (a.binaryPath == b.binaryPath));
+}
+
+QDebug operator<<(QDebug debug, const FrameworkInfo &info)
+{
+ debug << "Framework name" << info.frameworkName << "\n";
+ debug << "Framework directory" << info.frameworkDirectory << "\n";
+ debug << "Framework path" << info.frameworkPath << "\n";
+ debug << "Binary directory" << info.binaryDirectory << "\n";
+ debug << "Binary name" << info.binaryName << "\n";
+ debug << "Binary path" << info.binaryPath << "\n";
+ debug << "Version" << info.version << "\n";
+ debug << "Install name" << info.installName << "\n";
+ debug << "Deployed install name" << info.deployedInstallName << "\n";
+ debug << "Source file Path" << info.sourceFilePath << "\n";
+ debug << "Deployed Directory (relative to bundle)" << info.destinationDirectory << "\n";
+
+ return debug;
+}
+
+const QString bundleFrameworkDirectory = "Contents/Frameworks";
+const QString bundleBinaryDirectory = "Contents/MacOS";
+
+inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info)
+{
+ debug << "Application bundle path" << info.path << "\n";
+ debug << "Binary path" << info.binaryPath << "\n";
+ return debug;
+}
+
+bool copyFilePrintStatus(const QString &from, const QString &to)
+{
+ if (QFile::copy(from, to)) {
+ LogNormal() << " copied:" << from;
+ LogNormal() << " to" << to;
+ return true;
+ } else {
+ LogError() << "file copy failed from" << from;
+ LogError() << " to" << to;
+ return false;
+ }
+}
+
+FrameworkInfo parseOtoolLibraryLine(const QString &line, bool useDebugLibs)
+{
+ FrameworkInfo info;
+ QString trimmed = line.trimmed();
+
+ if (trimmed.isEmpty())
+ return info;
+
+ // Don't deploy system libraries.
+ if (trimmed.startsWith("/System/Library/") ||
+ (trimmed.startsWith("/usr/lib/") && trimmed.contains("libQt") == false) // exception for libQtuitools and libQtlucene
+ || trimmed.startsWith("@executable_path"))
+ return info;
+
+ enum State {QtPath, FrameworkName, DylibName, Version, End};
+ State state = QtPath;
+ int part = 0;
+ QString name;
+ QString qtPath;
+ QString suffix = useDebugLibs ? "_debug" : "";
+
+ // Split the line into [Qt-path]/lib/qt[Module].framework/Versions/[Version]/
+ QStringList parts = trimmed.split("/");
+ while (part < parts.count()) {
+ const QString currentPart = parts.at(part).simplified() ;
+ ++part;
+ if (currentPart == "")
+ continue;
+
+ if (state == QtPath) {
+ // Check for library name part
+ if (part < parts.count() && parts.at(part).contains(".dylib ")) {
+ state = DylibName;
+ info.installName += "/" + (qtPath + "lib/").simplified();
+ info.frameworkDirectory = info.installName;
+ state = DylibName;
+ continue;
+ } else if (part < parts.count() && parts.at(part).endsWith(".framework")) {
+ info.installName += "/" + (qtPath + "lib/").simplified();
+ info.frameworkDirectory = info.installName;
+ state = FrameworkName;
+ continue;
+ } else if (trimmed.startsWith("/") == false) { // If the line does not contain a full path, the app is using a binary Qt package.
+ if (currentPart.contains(".framework")) {
+ info.frameworkDirectory = "/Library/Frameworks/";
+ state = FrameworkName;
+ } else {
+ info.frameworkDirectory = "/usr/lib/";
+ state = DylibName;
+ }
+
+ --part;
+ continue;
+ }
+ qtPath += (currentPart + "/");
+
+ } if (state == FrameworkName) {
+ // remove ".framework"
+ name = currentPart;
+ name.chop(QString(".framework").length());
+ info.frameworkName = currentPart;
+ state = Version;
+ ++part;
+ continue;
+ } if (state == DylibName) {
+ name = currentPart.split(" (compatibility").at(0);
+ info.frameworkName = name;
+ info.binaryName = name.left(name.indexOf('.')) + suffix + name.mid(name.indexOf('.'));
+ info.installName += name;
+ info.deployedInstallName = "@executable_path/../Frameworks/" + info.binaryName;
+ info.frameworkPath = info.frameworkDirectory + info.binaryName;
+ info.sourceFilePath = info.frameworkPath;
+ info.destinationDirectory = bundleFrameworkDirectory + "/";
+ info.binaryDirectory = info.frameworkDirectory;
+ info.binaryPath = info.frameworkPath;
+ state = End;
+ ++part;
+ continue;
+ } else if (state == Version) {
+ info.version = currentPart;
+ info.binaryDirectory = "Versions/" + info.version;
+ info.binaryName = name + suffix;
+ info.binaryPath = "/" + info.binaryDirectory + "/" + info.binaryName;
+ info.installName += info.frameworkName + "/" + info.binaryDirectory + "/" + name;
+ info.deployedInstallName = "@executable_path/../Frameworks/" + info.frameworkName + info.binaryPath;
+ info.frameworkPath = info.frameworkDirectory + info.frameworkName;
+ info.sourceFilePath = info.frameworkPath + info.binaryPath;
+ info.destinationDirectory = bundleFrameworkDirectory + "/" + info.frameworkName + "/" + info.binaryDirectory;
+ state = End;
+ } else if (state == End) {
+ break;
+ }
+ }
+
+ return info;
+}
+
+QString findAppBinary(const QString &appBundlePath)
+{
+ QString appName = QFileInfo(appBundlePath).completeBaseName();
+ QString binaryPath = appBundlePath + "/Contents/MacOS/" + appName;
+
+ if (QFile::exists(binaryPath))
+ return binaryPath;
+ LogError() << "Could not find bundle binary for" << appBundlePath;
+ return QString();
+}
+
+QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines, bool useDebugLibs)
+{
+ QList<FrameworkInfo> libraries;
+ foreach(const QString line, otoolLines) {
+ FrameworkInfo info = parseOtoolLibraryLine(line, useDebugLibs);
+ if (info.frameworkName.isEmpty() == false) {
+ LogDebug() << "Adding framework:";
+ LogDebug() << info;
+ libraries.append(info);
+ }
+ }
+ return libraries;
+}
+
+QList<FrameworkInfo> getQtFrameworks(const QString &path, bool useDebugLibs)
+{
+ LogDebug() << "Using otool:";
+ LogDebug() << " inspecting" << path;
+ QProcess otool;
+ otool.start("otool", QStringList() << "-L" << path);
+ otool.waitForFinished();
+
+ if (otool.exitCode() != 0) {
+ LogError() << otool.readAllStandardError();
+ }
+
+ QString output = otool.readAllStandardOutput();
+ QStringList outputLines = output.split("\n");
+ outputLines.removeFirst(); // remove line containing the binary path
+ if (path.contains(".framework") || path.contains(".dylib"))
+ outputLines.removeFirst(); // frameworks and dylibs lists themselves as a dependency.
+
+ return getQtFrameworks(outputLines, useDebugLibs);
+}
+
+// copies everything _inside_ sourcePath to destinationPath
+void recursiveCopy(const QString &sourcePath, const QString &destinationPath)
+{
+ QDir().mkpath(destinationPath);
+
+ QStringList files = QDir(sourcePath).entryList(QStringList() << "*", QDir::Files | QDir::NoDotAndDotDot);
+ foreach (QString file, files) {
+ const QString fileSourcePath = sourcePath + "/" + file;
+ const QString fileDestinationPath = destinationPath + "/" + file;
+ copyFilePrintStatus(fileSourcePath, fileDestinationPath);
+ }
+
+ QStringList subdirs = QDir(sourcePath).entryList(QStringList() << "*", QDir::Dirs | QDir::NoDotAndDotDot);
+ foreach (QString dir, subdirs) {
+ recursiveCopy(sourcePath + "/" + dir, destinationPath + "/" + dir);
+ }
+}
+
+QString copyFramework(const FrameworkInfo &framework, const QString path)
+{
+ QString from = framework.sourceFilePath;
+ QString toDir = path + "/" + framework.destinationDirectory;
+ QString to = toDir + "/" + framework.binaryName;
+
+ if (QFile::exists(from) == false) {
+ LogError() << "no file at" << from;
+ return QString();
+ }
+
+
+ QDir dir;
+ if (dir.mkpath(toDir) == false) {
+ LogError() << "could not create destination directory" << to;
+ return QString();
+ }
+
+
+ if (QFile::exists(to)) {
+ return QString();
+ }
+
+ copyFilePrintStatus(from, to);
+
+ const QString resourcesSourcePath = framework.frameworkPath + "/Resources";
+ const QString resourcesDestianationPath = path + "/Contents/Frameworks/" + framework.frameworkName + "/Resources";
+ recursiveCopy(resourcesSourcePath, resourcesDestianationPath);
+
+ return to;
+}
+
+void runInstallNameTool(QStringList options)
+{
+ QProcess installNametool;
+ installNametool.start("install_name_tool", options);
+ installNametool.waitForFinished();
+ if (installNametool.exitCode() != 0) {
+ LogError() << installNametool.readAllStandardError();
+ LogError() << installNametool.readAllStandardOutput();
+ }
+}
+
+void changeIdentification(const QString &id, const QString &binaryPath)
+{
+ LogDebug() << "Using install_name_tool:";
+ LogDebug() << " change identification in" << binaryPath;
+ LogDebug() << " to" << id;
+ runInstallNameTool(QStringList() << "-id" << id << binaryPath);
+}
+
+void changeInstallName(const QString &oldName, const QString &newName, const QString &binaryPath)
+{
+ LogDebug() << "Using install_name_tool:";
+ LogDebug() << " in" << binaryPath;
+ LogDebug() << " change reference" << oldName;
+ LogDebug() << " to" << newName;
+ runInstallNameTool(QStringList() << "-change" << oldName << newName << binaryPath);
+}
+
+void runStrip(const QString &binaryPath)
+{
+ if (runStripEnabled == false)
+ return;
+
+ LogDebug() << "Using strip:";
+ LogDebug() << " stripped" << binaryPath;
+ QProcess strip;
+ strip.start("strip", QStringList() << "-x" << binaryPath);
+ strip.waitForFinished();
+ if (strip.exitCode() != 0) {
+ LogError() << strip.readAllStandardError();
+ LogError() << strip.readAllStandardOutput();
+ }
+}
+
+/*
+ Deploys the the listed frameworks listed into an app bundle.
+ The frameworks are searched for dependencies, which are also deployed.
+ (deploying Qt3Support will also deploy QtNetwork and QtSql for example.)
+ Returns a DeploymentInfo structure containing the Qt path used and a
+ a list of actually deployed frameworks.
+*/
+DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
+ const QString &bundlePath, const QString &binaryPath, bool useDebugLibs)
+{
+ LogNormal();
+ LogNormal() << "Deploying Qt frameworks found inside:" << binaryPath;
+ QStringList copiedFrameworks;
+ DeploymentInfo deploymenInfo;
+
+ while (frameworks.isEmpty() == false) {
+ const FrameworkInfo framework = frameworks.takeFirst();
+ copiedFrameworks.append(framework.frameworkName);
+
+ // Get the qt path from one of the Qt frameworks;
+ if (deploymenInfo.qtPath.isNull() && framework.frameworkName.contains("Qt")
+ && framework.frameworkDirectory.contains("/lib"))
+ {
+ deploymenInfo.qtPath = framework.frameworkDirectory;
+ deploymenInfo.qtPath.chop(5); // remove "/lib/"
+ }
+
+ if (framework.installName.startsWith("/@executable_path/")) {
+ LogError() << framework.frameworkName << "already deployed, skipping.";
+ continue;
+ }
+
+ // Install_name_tool the new id into the binary
+ changeInstallName(framework.installName, framework.deployedInstallName, binaryPath);
+
+ // Copy farmework to app bundle.
+ const QString deployedBinaryPath = copyFramework(framework, bundlePath);
+ // Skip the rest if already was deployed.
+ if (deployedBinaryPath.isNull())
+ continue;
+
+ runStrip(deployedBinaryPath);
+
+ // Install_name_tool it a new id.
+ changeIdentification(framework.deployedInstallName, deployedBinaryPath);
+ // Check for framework dependencies
+ QList<FrameworkInfo> dependencies = getQtFrameworks(deployedBinaryPath, useDebugLibs);
+
+ foreach (FrameworkInfo dependency, dependencies) {
+ changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath);
+
+ // Deploy framework if necessary.
+ if (copiedFrameworks.contains(dependency.frameworkName) == false && frameworks.contains(dependency) == false) {
+ frameworks.append(dependency);
+ }
+ }
+ }
+ deploymenInfo.deployedFrameworks = copiedFrameworks;
+ return deploymenInfo;
+}
+
+DeploymentInfo deployQtFrameworks(const QString &appBundlePath, bool useDebugLibs)
+{
+ ApplicationBundleInfo applicationBundle;
+ applicationBundle.path = appBundlePath;
+ applicationBundle.binaryPath = findAppBinary(appBundlePath);
+ QList<FrameworkInfo> frameworks = getQtFrameworks(applicationBundle.binaryPath, useDebugLibs);
+ if (frameworks.isEmpty()) {
+ LogWarning();
+ LogWarning() << "Could not find any external Qt frameworks to deploy in" << appBundlePath;
+ LogWarning() << "Perhaps macdeployqt was already used on" << appBundlePath << "?";
+ LogWarning() << "If so, you will need to rebuild" << appBundlePath << "before trying again.";
+ return DeploymentInfo();
+ } else {
+ return deployQtFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, useDebugLibs);
+ }
+}
+
+void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pluginSourcePath,
+ const QString pluginDestinationPath, DeploymentInfo deploymentInfo, bool useDebugLibs)
+{
+ LogNormal() << "Deploying plugins from" << pluginSourcePath;
+ QStringList plugins = QDir(pluginSourcePath).entryList(QStringList() << "*.dylib");
+
+ foreach (QString pluginName, plugins) {
+ if (pluginSourcePath.contains(deploymentInfo.pluginPath)) {
+ QStringList deployedFrameworks = deploymentInfo.deployedFrameworks;
+
+ // Skip the debug versions of the plugins, unless specified otherwise.
+ if (!useDebugLibs && pluginName.endsWith("_debug.dylib"))
+ continue;
+
+ // Skip the release versions of the plugins, unless specified otherwise.
+ if (useDebugLibs && !pluginName.endsWith("_debug.dylib"))
+ continue;
+
+ // Skip the designer plugins
+ if (pluginSourcePath.contains("plugins/designer"))
+ continue;
+
+#ifndef QT_GRAPHICSSYSTEM_OPENGL
+ // SKip the opengl graphicssystem plugin when not in use.
+ if (pluginName.contains("libqglgraphicssystem"))
+ continue;
+#endif
+ // Deploy accessibility for Qt3Support only if the Qt3Support.framework is in use
+ if (deployedFrameworks.indexOf("Qt3Support.framework") == -1 && pluginName.contains("accessiblecompatwidgets"))
+ continue;
+
+ // Deploy the svg icon plugin if QtSvg.framework is in use.
+ if (deployedFrameworks.indexOf("QtSvg.framework") == -1 && pluginName.contains("svg"))
+ continue;
+
+ // Deploy the phonon plugins if phonon.framework is in use
+ if (deployedFrameworks.indexOf("phonon.framework") == -1 && pluginName.contains("phonon"))
+ continue;
+
+ // Deploy the sql plugins if QtSql.framework is in use
+ if (deployedFrameworks.indexOf("QtSql.framework") == -1 && pluginName.contains("sql"))
+ continue;
+
+ // Deploy the script plugins if QtScript.framework is in use
+ if (deployedFrameworks.indexOf("QtScript.framework") == -1 && pluginName.contains("script"))
+ continue;
+ }
+
+ QDir dir;
+ dir.mkpath(pluginDestinationPath);
+
+ const QString sourcePath = pluginSourcePath + "/" + pluginName;
+ const QString destinationPath = pluginDestinationPath + "/" + pluginName;
+ if (copyFilePrintStatus(sourcePath, destinationPath)) {
+
+ runStrip(destinationPath);
+
+ // Special case for the phonon plugin: CoreVideo is not available as a separate framework
+ // on panther, link against the QuartzCore framework instead. (QuartzCore contians CoreVideo.)
+ if (pluginName.contains("libphonon_qt7")) {
+ changeInstallName("/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo",
+ "/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore",
+ destinationPath);
+ }
+
+ QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath, useDebugLibs);
+ deployQtFrameworks(frameworks, appBundleInfo.path, destinationPath, useDebugLibs);
+ }
+ } // foreach plugins
+
+ QStringList subdirs = QDir(pluginSourcePath).entryList(QStringList() << "*", QDir::Dirs | QDir::NoDotAndDotDot);
+ foreach (const QString &subdir, subdirs)
+ deployPlugins(appBundleInfo, pluginSourcePath + "/" + subdir, pluginDestinationPath + "/" + subdir, deploymentInfo, useDebugLibs);
+}
+
+void createQtConf(const QString &appBundlePath)
+{
+ QByteArray contents = "[Paths]\nPlugins = PlugIns\n";
+ QString filePath = appBundlePath + "/Contents/Resources/";
+ QString fileName = filePath + "qt.conf";
+
+ QDir().mkpath(filePath);
+
+ QFile qtconf(fileName);
+ if (qtconf.exists()) {
+ LogWarning();
+ LogWarning() << fileName << "already exists, will not overwrite.";
+ LogWarning() << "To make sure the plugins are loaded from the correct location,";
+ LogWarning() << "please make sure qt.conf contains the following lines:";
+ LogWarning() << "[Paths]";
+ LogWarning() << " Plugins = PlugIns";
+ return;
+ }
+
+ qtconf.open(QIODevice::WriteOnly);
+ if (qtconf.write(contents) != -1) {
+ LogNormal() << "Created configuration file:" << fileName;
+ LogNormal() << "This file sets the plugin search path to" << appBundlePath + "/Contents/PlugIns";
+ }
+}
+
+void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo, bool useDebugLibs)
+{
+ ApplicationBundleInfo applicationBundle;
+ applicationBundle.path = appBundlePath;
+ applicationBundle.binaryPath = findAppBinary(appBundlePath);
+
+ const QString pluginDestinationPath = appBundlePath + "/" + "Contents/PlugIns";
+ deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo, useDebugLibs);
+}
+
+
+void changeQtFrameworks(const QList<FrameworkInfo> frameworks, const QString &appBinaryPath, const QString &absoluteQtPath)
+{
+ LogNormal() << "Changing" << appBinaryPath << "to link against";
+ LogNormal() << "Qt in" << absoluteQtPath;
+ QString finalQtPath = absoluteQtPath;
+
+ if (!absoluteQtPath.startsWith("/Library/Frameworks"))
+ finalQtPath += "/lib/";
+
+ foreach (FrameworkInfo framework, frameworks) {
+ const QString oldBinaryId = framework.installName;
+ const QString newBinaryId = finalQtPath + framework.frameworkName + framework.binaryPath;
+ changeInstallName(oldBinaryId, newBinaryId, appBinaryPath);
+ }
+}
+
+void changeQtFrameworks(const QString appPath, const QString &qtPath, bool useDebugLibs)
+{
+ const QString appBinaryPath = findAppBinary(appPath);
+ const QList<FrameworkInfo> frameworks = getQtFrameworks(appBinaryPath, useDebugLibs);
+ if (frameworks.isEmpty()) {
+ LogWarning();
+ LogWarning() << "Could not find any _external_ Qt frameworks to change in" << appPath;
+ return;
+ } else {
+ const QString absoluteQtPath = QDir(qtPath).absolutePath();
+ changeQtFrameworks(frameworks, appBinaryPath, absoluteQtPath);
+ }
+}
+
+
+void createDiskImage(const QString &appBundlePath)
+{
+ QString appBaseName = appBundlePath;
+ appBaseName.chop(4); // remove ".app" from end
+
+ QString dmgName = appBaseName + ".dmg";
+
+ QFile dmg(dmgName);
+
+ if (dmg.exists()) {
+ LogNormal() << "Disk image already exists, skipping .dmg creation for" << dmg.fileName();
+ } else {
+ LogNormal() << "Creating disk image (.dmg) for" << appBundlePath;
+ }
+
+ // More dmg options can be found in the hdiutil man page.
+ QStringList options = QStringList()
+ << "create" << dmgName
+ << "-srcfolder" << appBundlePath
+ << "-format" << "UDZO"
+ << "-volname" << appBaseName;
+
+ QProcess hdutil;
+ hdutil.start("hdiutil", options);
+ hdutil.waitForFinished(-1);
+}
diff --git a/src/macdeployqt/shared/shared.h b/src/macdeployqt/shared/shared.h
new file mode 100644
index 000000000..6bc876b0a
--- /dev/null
+++ b/src/macdeployqt/shared/shared.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MAC_DEPLOMYMENT_SHARED_H
+#define MAC_DEPLOMYMENT_SHARED_H
+
+#include <QString>
+#include <QStringList>
+#include <QDebug>
+
+extern int logLevel;
+#define LogError() if (logLevel < 1) {} else qDebug() << "ERROR:"
+#define LogWarning() if (logLevel < 1) {} else qDebug() << "WARNING:"
+#define LogNormal() if (logLevel < 2) {} else qDebug() << "Log:"
+#define LogDebug() if (logLevel < 3) {} else qDebug() << "Log:"
+
+extern bool runStripEnabled;
+
+class FrameworkInfo
+{
+public:
+ QString frameworkDirectory;
+ QString frameworkName;
+ QString frameworkPath;
+ QString binaryDirectory;
+ QString binaryName;
+ QString binaryPath;
+ QString version;
+ QString installName;
+ QString deployedInstallName;
+ QString sourceFilePath;
+ QString destinationDirectory;
+};
+
+bool operator==(const FrameworkInfo &a, const FrameworkInfo &b);
+QDebug operator<<(QDebug debug, const FrameworkInfo &info);
+
+class ApplicationBundleInfo
+{
+ public:
+ QString path;
+ QString binaryPath;
+};
+
+class DeploymentInfo
+{
+public:
+ QString qtPath;
+ QString pluginPath;
+ QStringList deployedFrameworks;
+};
+
+
+inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info);
+
+void changeQtFrameworks(const QString appPath, const QString &qtPath, bool useDebugLibs);
+void changeQtFrameworks(const QList<FrameworkInfo> frameworks, const QString &appBinaryPath, const QString &qtPath);
+
+FrameworkInfo parseOtoolLibraryLine(const QString &line, bool useDebugLibs);
+QString findAppBinary(const QString &appBundlePath);
+QList<FrameworkInfo> getQtFrameworks(const QString &path, bool useDebugLibs);
+QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines, bool useDebugLibs);
+QString copyFramework(const FrameworkInfo &framework, const QString path);
+DeploymentInfo deployQtFrameworks(const QString &appBundlePath, bool useDebugLibs);
+DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks, const QString &bundlePath, const QString &binaryPath);
+void createQtConf(const QString &appBundlePath);
+void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo, bool useDebugLibs);
+void changeIdentification(const QString &id, const QString &binaryPath);
+void changeInstallName(const QString &oldName, const QString &newName, const QString &binaryPath);
+QString findAppBinary(const QString &appBundlePath);
+void createDiskImage(const QString &appBundlePath);
+
+#endif
diff --git a/src/macdeployqt/tests/deployment_mac.pro b/src/macdeployqt/tests/deployment_mac.pro
new file mode 100644
index 000000000..1bde1fdc5
--- /dev/null
+++ b/src/macdeployqt/tests/deployment_mac.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+DEPENDPATH += . ../shared/
+INCLUDEPATH += . ../shared/
+TARGET=tst_deployment_mac
+CONFIG += qtestlib
+
+# Input
+SOURCES += tst_deployment_mac.cpp ../shared/shared.cpp
+HEADERS += ../shared/shared.h
+
diff --git a/src/macdeployqt/tests/tst_deployment_mac.cpp b/src/macdeployqt/tests/tst_deployment_mac.cpp
new file mode 100644
index 000000000..b1bd51875
--- /dev/null
+++ b/src/macdeployqt/tests/tst_deployment_mac.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore>
+#include <QtTest/QTest>
+#include <shared.h>
+
+class tst_deployment_mac : public QObject
+{
+Q_OBJECT
+private slots:
+ void testParseOtoolLibraryLine();
+ void testgetQtFrameworks();
+ void testFindAppBinarty();
+};
+
+void tst_deployment_mac::testParseOtoolLibraryLine()
+{
+{
+ QString line = " /Users/foo/build/qt-4.4/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.4.0, current version 4.4.0)";
+ FrameworkInfo info = parseOtoolLibraryLine(line);
+// qDebug() << info;
+ QCOMPARE(info.frameworkDirectory, QLatin1String("/Users/foo/build/qt-4.4/lib/"));
+ QCOMPARE(info.frameworkName, QLatin1String("QtGui.framework"));
+ QCOMPARE(info.frameworkPath, QLatin1String("/Users/foo/build/qt-4.4/lib/QtGui.framework"));
+ QCOMPARE(info.binaryDirectory, QLatin1String("Versions/4"));
+ QCOMPARE(info.binaryName, QLatin1String("QtGui"));
+ QCOMPARE(info.binaryPath, QLatin1String("/Versions/4/QtGui"));
+ QCOMPARE(info.version, QLatin1String("4"));
+ QCOMPARE(info.installName, QLatin1String("/Users/foo/build/qt-4.4/lib/QtGui.framework/Versions/4/QtGui"));
+ QCOMPARE(info.deployedInstallName, QLatin1String("@executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui"));
+ QCOMPARE(info.sourceFilePath, QLatin1String("/Users/foo/build/qt-4.4/lib/QtGui.framework/Versions/4/QtGui"));
+ QCOMPARE(info.destinationDirectory, QLatin1String("Contents/Frameworks/QtGui.framework/Versions/4"));
+}
+{
+ QString line = " /Users/foo/build/qt-4.4/lib/phonon.framework/Versions/4/phonon (compatibility version 4.1.0, current version 4.1.0)";
+ FrameworkInfo info = parseOtoolLibraryLine(line);
+// qDebug() << info;
+ QCOMPARE(info.frameworkDirectory, QLatin1String("/Users/foo/build/qt-4.4/lib/"));
+ QCOMPARE(info.frameworkName, QLatin1String("phonon.framework"));
+ QCOMPARE(info.frameworkPath, QLatin1String("/Users/foo/build/qt-4.4/lib/phonon.framework"));
+ QCOMPARE(info.binaryDirectory, QLatin1String("Versions/4"));
+ QCOMPARE(info.binaryName, QLatin1String("phonon"));
+ QCOMPARE(info.binaryPath, QLatin1String("/Versions/4/phonon"));
+ QCOMPARE(info.version, QLatin1String("4"));
+ QCOMPARE(info.installName, QLatin1String("/Users/foo/build/qt-4.4/lib/phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.deployedInstallName, QLatin1String("@executable_path/../Frameworks/phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.sourceFilePath, QLatin1String("/Users/foo/build/qt-4.4/lib/phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.destinationDirectory, QLatin1String("Contents/Frameworks/phonon.framework/Versions/4"));
+}
+
+{
+ QString line = " /usr/local/Trolltech/Qt-4.4.0/lib/phonon.framework/Versions/4/phonon (compatibility version 4.1.0, current version 4.1.0)";
+ FrameworkInfo info = parseOtoolLibraryLine(line);
+// qDebug() << info;
+ QCOMPARE(info.frameworkDirectory, QLatin1String("/usr/local/Trolltech/Qt-4.4.0/lib/"));
+ QCOMPARE(info.frameworkName, QLatin1String("phonon.framework"));
+ QCOMPARE(info.frameworkPath, QLatin1String("/usr/local/Trolltech/Qt-4.4.0/lib/phonon.framework"));
+ QCOMPARE(info.binaryDirectory, QLatin1String("Versions/4"));
+ QCOMPARE(info.binaryName, QLatin1String("phonon"));
+ QCOMPARE(info.binaryPath, QLatin1String("/Versions/4/phonon"));
+ QCOMPARE(info.version, QLatin1String("4"));
+ QCOMPARE(info.installName, QLatin1String("/usr/local/Trolltech/Qt-4.4.0/lib/phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.deployedInstallName, QLatin1String("@executable_path/../Frameworks/phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.sourceFilePath, QLatin1String("/usr/local/Trolltech/Qt-4.4.0/lib/phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.destinationDirectory, QLatin1String("Contents/Frameworks/phonon.framework/Versions/4"));
+}
+
+{
+ QString line = " QtGui.framework/Versions/4/QtGui (compatibility version 4.1.0, current version 4.1.0)";
+ FrameworkInfo info = parseOtoolLibraryLine(line);
+// qDebug() << info;
+ QCOMPARE(info.frameworkDirectory, QLatin1String("/Library/Frameworks/"));
+ QCOMPARE(info.frameworkName, QLatin1String("QtGui.framework"));
+ QCOMPARE(info.frameworkPath, QLatin1String("/Library/Frameworks/QtGui.framework"));
+ QCOMPARE(info.binaryDirectory, QLatin1String("Versions/4"));
+ QCOMPARE(info.binaryName, QLatin1String("QtGui"));
+ QCOMPARE(info.binaryPath, QLatin1String("/Versions/4/QtGui"));
+ QCOMPARE(info.version, QLatin1String("4"));
+ QCOMPARE(info.installName, QLatin1String("QtGui.framework/Versions/4/QtGui"));
+ QCOMPARE(info.deployedInstallName, QLatin1String("@executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui"));
+ QCOMPARE(info.sourceFilePath, QLatin1String("/Library/Frameworks/QtGui.framework/Versions/4/QtGui"));
+ QCOMPARE(info.destinationDirectory, QLatin1String("Contents/Frameworks/QtGui.framework/Versions/4"));
+}
+
+{
+ QString line = " phonon.framework/Versions/4/QtGui (compatibility version 4.1.0, current version 4.1.0)";
+ FrameworkInfo info = parseOtoolLibraryLine(line);
+// qDebug() << info;
+ QCOMPARE(info.frameworkDirectory, QLatin1String("/Library/Frameworks/"));
+ QCOMPARE(info.frameworkName, QLatin1String("phonon.framework"));
+ QCOMPARE(info.frameworkPath, QLatin1String("/Library/Frameworks/phonon.framework"));
+ QCOMPARE(info.binaryDirectory, QLatin1String("Versions/4"));
+ QCOMPARE(info.binaryName, QLatin1String("phonon"));
+ QCOMPARE(info.binaryPath, QLatin1String("/Versions/4/phonon"));
+ QCOMPARE(info.version, QLatin1String("4"));
+ QCOMPARE(info.installName, QLatin1String("phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.deployedInstallName, QLatin1String("@executable_path/../Frameworks/phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.sourceFilePath, QLatin1String("/Library/Frameworks/phonon.framework/Versions/4/phonon"));
+ QCOMPARE(info.destinationDirectory, QLatin1String("Contents/Frameworks/phonon.framework/Versions/4"));
+}
+
+{
+ QString line = " /Users/foo/build/qt-4.4/lib/libQtCLucene.4.dylib (compatibility version 4.4.0, current version 4.4.0)";
+ FrameworkInfo info = parseOtoolLibraryLine(line);
+// qDebug() << info;
+ QCOMPARE(info.frameworkDirectory, QLatin1String("/Users/foo/build/qt-4.4/lib/"));
+ QCOMPARE(info.binaryName, QLatin1String("libQtCLucene.4.dylib"));
+ QCOMPARE(info.frameworkName, QLatin1String("libQtCLucene.4.dylib"));
+ QCOMPARE(info.frameworkPath, QLatin1String("/Users/foo/build/qt-4.4/lib/libQtCLucene.4.dylib"));
+ QCOMPARE(info.installName, QLatin1String("/Users/foo/build/qt-4.4/lib/libQtCLucene.4.dylib"));
+ QCOMPARE(info.deployedInstallName, QLatin1String("@executable_path/../Frameworks/libQtCLucene.4.dylib"));
+ QCOMPARE(info.sourceFilePath, QLatin1String("/Users/foo/build/qt-4.4/lib/libQtCLucene.4.dylib"));
+ QCOMPARE(info.destinationDirectory, QLatin1String("Contents/Frameworks/"));
+}
+{
+ QString line = "libQtCLucene.4.dylib (compatibility version 4.4.0, current version 4.4.0)";
+ FrameworkInfo info = parseOtoolLibraryLine(line);
+// qDebug() << info;
+ QCOMPARE(info.frameworkDirectory, QLatin1String("/usr/lib/"));
+ QCOMPARE(info.binaryName, QLatin1String("libQtCLucene.4.dylib"));
+ QCOMPARE(info.frameworkName, QLatin1String("libQtCLucene.4.dylib"));
+ QCOMPARE(info.frameworkPath, QLatin1String("/usr/lib/libQtCLucene.4.dylib"));
+ QCOMPARE(info.installName, QLatin1String("libQtCLucene.4.dylib"));
+ QCOMPARE(info.deployedInstallName, QLatin1String("@executable_path/../Frameworks/libQtCLucene.4.dylib"));
+ QCOMPARE(info.sourceFilePath, QLatin1String("/usr/lib/libQtCLucene.4.dylib"));
+ QCOMPARE(info.destinationDirectory, QLatin1String("Contents/Frameworks/"));
+}
+{
+ QString line = "/foo"; //invalid
+ FrameworkInfo info = parseOtoolLibraryLine(line);
+ QCOMPARE(info.frameworkName, QString());
+}
+
+}
+
+void tst_deployment_mac::testgetQtFrameworks()
+{
+{
+ QStringList otool = QStringList()
+ << "/Users/foo/build/qt-4.4/lib/phonon.framework/Versions/4/phonon (compatibility version 4.1.0, current version 4.1.0)"
+ << "/Users/foo/build/qt-4.4/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.4.0, current version 4.4.0)"
+ << "/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 136.0.0)"
+ << "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 949.27.0)"
+ << "/Users/foo/build/qt-4.4/lib/QtCore.framework/Versions/4/QtCore (compatibility version 4.4.0, current version 4.4.0)"
+ << "/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)"
+ << "/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)"
+ << "/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)"
+ << "/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)"
+ << " "
+ ;
+
+ QList<FrameworkInfo> frameworks = getQtFrameworks(otool);
+ QCOMPARE(frameworks.count(), 3);
+ QCOMPARE(frameworks.at(0).binaryName, QLatin1String("phonon"));
+ QCOMPARE(frameworks.at(1).binaryName, QLatin1String("QtGui"));
+ QCOMPARE(frameworks.at(2).binaryName, QLatin1String("QtCore"));
+}
+{
+ QStringList otool = QStringList()
+ << "QtHelp.framework/Versions/4/QtHelp (compatibility version 4.4.0, current version 4.4.0)"
+ << "libQtCLucene.4.dylib (compatibility version 4.4.0, current version 4.4.0)"
+ << "QtSql.framework/Versions/4/QtSql (compatibility version 4.4.0, current version 4.4.0)"
+ << "QtXml.framework/Versions/4/QtXml (compatibility version 4.4.0, current version 4.4.0)"
+ << "QtGui.framework/Versions/4/QtGui (compatibility version 4.4.0, current version 4.4.0)"
+ << "/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 128.0.0)"
+ << "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 824.42.0)"
+ << "QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.4.0, current version 4.4.0)"
+ << "QtCore.framework/Versions/4/QtCore (compatibility version 4.4.0, current version 4.4.0)"
+ << "/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)"
+ << "/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.6)"
+ << "/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)"
+ << "/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)"
+ ;
+
+ QList<FrameworkInfo> frameworks = getQtFrameworks(otool);
+ QCOMPARE(frameworks.count(), 7);
+ QCOMPARE(frameworks.at(0).binaryName, QLatin1String("QtHelp"));
+ QCOMPARE(frameworks.at(1).binaryName, QLatin1String("libQtCLucene.4.dylib"));
+ QCOMPARE(frameworks.at(2).binaryName, QLatin1String("QtSql"));
+ QCOMPARE(frameworks.at(3).binaryName, QLatin1String("QtXml"));
+ QCOMPARE(frameworks.at(4).binaryName, QLatin1String("QtGui"));
+ QCOMPARE(frameworks.at(5).binaryName, QLatin1String("QtNetwork"));
+ QCOMPARE(frameworks.at(6).binaryName, QLatin1String("QtCore"));
+}
+
+}
+
+void tst_deployment_mac::testFindAppBinarty()
+{
+ QCOMPARE(findAppBinary("tst_deployment_mac.app"), QLatin1String("tst_deployment_mac.app/Contents/MacOS/tst_deployment_mac"));
+}
+
+QTEST_MAIN(tst_deployment_mac)
+
+#include "tst_deployment_mac.moc" \ No newline at end of file
diff --git a/src/makeqpf/Blocks.txt b/src/makeqpf/Blocks.txt
new file mode 100644
index 000000000..9cc87547f
--- /dev/null
+++ b/src/makeqpf/Blocks.txt
@@ -0,0 +1,185 @@
+# Blocks-5.0.0.txt
+# Date: 2006-02-15, 15:40:00 [KW]
+#
+# Unicode Character Database
+# Copyright (c) 1991-2006 Unicode, Inc.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For documentation, see UCD.html
+#
+# Note: The casing of block names is not normative.
+# For example, "Basic Latin" and "BASIC LATIN" are equivalent.
+#
+# Format:
+# Start Code..End Code; Block Name
+
+# ================================================
+
+# Note: When comparing block names, casing, whitespace, hyphens,
+# and underbars are ignored.
+# For example, "Latin Extended-A" and "latin extended a" are equivalent.
+# For more information on the comparison of property values,
+# see UCD.html.
+#
+# All code points not explicitly listed for Block
+# have the value No_Block.
+
+# Property: Block
+#
+# @missing: 0000..10FFFF; No_Block
+
+0000..007F; Basic Latin
+0080..00FF; Latin-1 Supplement
+0100..017F; Latin Extended-A
+0180..024F; Latin Extended-B
+0250..02AF; IPA Extensions
+02B0..02FF; Spacing Modifier Letters
+0300..036F; Combining Diacritical Marks
+0370..03FF; Greek and Coptic
+0400..04FF; Cyrillic
+0500..052F; Cyrillic Supplement
+0530..058F; Armenian
+0590..05FF; Hebrew
+0600..06FF; Arabic
+0700..074F; Syriac
+0750..077F; Arabic Supplement
+0780..07BF; Thaana
+07C0..07FF; NKo
+0900..097F; Devanagari
+0980..09FF; Bengali
+0A00..0A7F; Gurmukhi
+0A80..0AFF; Gujarati
+0B00..0B7F; Oriya
+0B80..0BFF; Tamil
+0C00..0C7F; Telugu
+0C80..0CFF; Kannada
+0D00..0D7F; Malayalam
+0D80..0DFF; Sinhala
+0E00..0E7F; Thai
+0E80..0EFF; Lao
+0F00..0FFF; Tibetan
+1000..109F; Myanmar
+10A0..10FF; Georgian
+1100..11FF; Hangul Jamo
+1200..137F; Ethiopic
+1380..139F; Ethiopic Supplement
+13A0..13FF; Cherokee
+1400..167F; Unified Canadian Aboriginal Syllabics
+1680..169F; Ogham
+16A0..16FF; Runic
+1700..171F; Tagalog
+1720..173F; Hanunoo
+1740..175F; Buhid
+1760..177F; Tagbanwa
+1780..17FF; Khmer
+1800..18AF; Mongolian
+1900..194F; Limbu
+1950..197F; Tai Le
+1980..19DF; New Tai Lue
+19E0..19FF; Khmer Symbols
+1A00..1A1F; Buginese
+1B00..1B7F; Balinese
+1D00..1D7F; Phonetic Extensions
+1D80..1DBF; Phonetic Extensions Supplement
+1DC0..1DFF; Combining Diacritical Marks Supplement
+1E00..1EFF; Latin Extended Additional
+1F00..1FFF; Greek Extended
+2000..206F; General Punctuation
+2070..209F; Superscripts and Subscripts
+20A0..20CF; Currency Symbols
+20D0..20FF; Combining Diacritical Marks for Symbols
+2100..214F; Letterlike Symbols
+2150..218F; Number Forms
+2190..21FF; Arrows
+2200..22FF; Mathematical Operators
+2300..23FF; Miscellaneous Technical
+2400..243F; Control Pictures
+2440..245F; Optical Character Recognition
+2460..24FF; Enclosed Alphanumerics
+2500..257F; Box Drawing
+2580..259F; Block Elements
+25A0..25FF; Geometric Shapes
+2600..26FF; Miscellaneous Symbols
+2700..27BF; Dingbats
+27C0..27EF; Miscellaneous Mathematical Symbols-A
+27F0..27FF; Supplemental Arrows-A
+2800..28FF; Braille Patterns
+2900..297F; Supplemental Arrows-B
+2980..29FF; Miscellaneous Mathematical Symbols-B
+2A00..2AFF; Supplemental Mathematical Operators
+2B00..2BFF; Miscellaneous Symbols and Arrows
+2C00..2C5F; Glagolitic
+2C60..2C7F; Latin Extended-C
+2C80..2CFF; Coptic
+2D00..2D2F; Georgian Supplement
+2D30..2D7F; Tifinagh
+2D80..2DDF; Ethiopic Extended
+2E00..2E7F; Supplemental Punctuation
+2E80..2EFF; CJK Radicals Supplement
+2F00..2FDF; Kangxi Radicals
+2FF0..2FFF; Ideographic Description Characters
+3000..303F; CJK Symbols and Punctuation
+3040..309F; Hiragana
+30A0..30FF; Katakana
+3100..312F; Bopomofo
+3130..318F; Hangul Compatibility Jamo
+3190..319F; Kanbun
+31A0..31BF; Bopomofo Extended
+31C0..31EF; CJK Strokes
+31F0..31FF; Katakana Phonetic Extensions
+3200..32FF; Enclosed CJK Letters and Months
+3300..33FF; CJK Compatibility
+3400..4DBF; CJK Unified Ideographs Extension A
+4DC0..4DFF; Yijing Hexagram Symbols
+4E00..9FFF; CJK Unified Ideographs
+A000..A48F; Yi Syllables
+A490..A4CF; Yi Radicals
+A700..A71F; Modifier Tone Letters
+A720..A7FF; Latin Extended-D
+A800..A82F; Syloti Nagri
+A840..A87F; Phags-pa
+AC00..D7AF; Hangul Syllables
+D800..DB7F; High Surrogates
+DB80..DBFF; High Private Use Surrogates
+DC00..DFFF; Low Surrogates
+E000..F8FF; Private Use Area
+F900..FAFF; CJK Compatibility Ideographs
+FB00..FB4F; Alphabetic Presentation Forms
+FB50..FDFF; Arabic Presentation Forms-A
+FE00..FE0F; Variation Selectors
+FE10..FE1F; Vertical Forms
+FE20..FE2F; Combining Half Marks
+FE30..FE4F; CJK Compatibility Forms
+FE50..FE6F; Small Form Variants
+FE70..FEFF; Arabic Presentation Forms-B
+FF00..FFEF; Halfwidth and Fullwidth Forms
+FFF0..FFFF; Specials
+10000..1007F; Linear B Syllabary
+10080..100FF; Linear B Ideograms
+10100..1013F; Aegean Numbers
+10140..1018F; Ancient Greek Numbers
+10300..1032F; Old Italic
+10330..1034F; Gothic
+10380..1039F; Ugaritic
+103A0..103DF; Old Persian
+10400..1044F; Deseret
+10450..1047F; Shavian
+10480..104AF; Osmanya
+10800..1083F; Cypriot Syllabary
+10900..1091F; Phoenician
+10A00..10A5F; Kharoshthi
+12000..123FF; Cuneiform
+12400..1247F; Cuneiform Numbers and Punctuation
+1D000..1D0FF; Byzantine Musical Symbols
+1D100..1D1FF; Musical Symbols
+1D200..1D24F; Ancient Greek Musical Notation
+1D300..1D35F; Tai Xuan Jing Symbols
+1D360..1D37F; Counting Rod Numerals
+1D400..1D7FF; Mathematical Alphanumeric Symbols
+20000..2A6DF; CJK Unified Ideographs Extension B
+2F800..2FA1F; CJK Compatibility Ideographs Supplement
+E0000..E007F; Tags
+E0100..E01EF; Variation Selectors Supplement
+F0000..FFFFF; Supplementary Private Use Area-A
+100000..10FFFF; Supplementary Private Use Area-B
+
+# EOF \ No newline at end of file
diff --git a/src/makeqpf/README b/src/makeqpf/README
new file mode 100644
index 000000000..665635545
--- /dev/null
+++ b/src/makeqpf/README
@@ -0,0 +1 @@
+This tool is used to create pre-rendered fonts for use with Qtopia Core.
diff --git a/src/makeqpf/main.cpp b/src/makeqpf/main.cpp
new file mode 100644
index 000000000..3debf8915
--- /dev/null
+++ b/src/makeqpf/main.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "qpf2.h"
+#include "mainwindow.h"
+
+#include <private/qfontengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static void help()
+{
+ printf("usage:\n");
+ printf("makeqpf fontname pixelsize [italic] [bold] [--exclude-cmap] [-v]\n");
+ printf("makeqpf -dump [-v] file.qpf2\n");
+ exit(0);
+}
+
+static int gui(const QString &customFont = QString())
+{
+ MainWindow mw(customFont);
+ mw.show();
+ return qApp->exec();
+}
+
+QT_END_NAMESPACE
+
+int main(int argc, char **argv)
+{
+ QT_USE_NAMESPACE
+
+ QApplication app(argc, argv);
+ app.setOrganizationName(QLatin1String("Trolltech"));
+ app.setApplicationName(QLatin1String("MakeQPF"));
+
+ const QStringList arguments = app.arguments();
+
+ if (arguments.count() <= 1) {
+ return gui();
+ } else if (arguments.count() == 2
+ && QFile::exists(arguments.at(1))) {
+ return gui(arguments.at(1));
+ }
+
+ const QString &firstArg = arguments.at(1);
+ if (firstArg == QLatin1String("-h") || firstArg == QLatin1String("--help"))
+ help();
+ if (firstArg == QLatin1String("-dump")) {
+ QString file;
+ for (int i = 2; i < arguments.count(); ++i) {
+ if (arguments.at(i).startsWith(QLatin1String("-v")))
+ QPF::debugVerbosity += arguments.at(i).length() - 1;
+ else if (file.isEmpty())
+ file = arguments.at(i);
+ else
+ help();
+ }
+
+ if (file.isEmpty())
+ help();
+
+ QFile f(file);
+ if (!f.open(QIODevice::ReadOnly)) {
+ printf("cannot open %s\n", qPrintable(file));
+ exit(1);
+ }
+
+ QByteArray qpf = f.readAll();
+ f.close();
+
+ QPF::dump(qpf);
+ return 0;
+ }
+
+ if (arguments.count() < 3) help();
+
+ QFont font;
+
+ QString fontName = firstArg;
+ if (QFile::exists(fontName)) {
+ int id = QFontDatabase::addApplicationFont(fontName);
+ if (id == -1) {
+ printf("cannot open font %s", qPrintable(fontName));
+ help();
+ }
+ QStringList families = QFontDatabase::applicationFontFamilies(id);
+ if (families.isEmpty()) {
+ printf("cannot find any font families in %s", qPrintable(fontName));
+ help();
+ }
+ fontName = families.first();
+ }
+ font.setFamily(fontName);
+
+ bool ok = false;
+ int pixelSize = arguments.at(2).toInt(&ok);
+ if (!ok) help();
+ font.setPixelSize(pixelSize);
+
+ int generationOptions = QPF::IncludeCMap | QPF::RenderGlyphs;
+
+ for (int i = 3; i < arguments.count(); ++i) {
+ const QString &arg = arguments.at(i);
+ if (arg == QLatin1String("italic")) {
+ font.setItalic(true);
+ } else if (arg == QLatin1String("bold")) {
+ font.setBold(true);
+ } else if (arg == QLatin1String("--exclude-cmap")) {
+ generationOptions &= ~QPF::IncludeCMap;
+ } else if (arg == QLatin1String("--exclude-glyphs")) {
+ generationOptions &= ~QPF::RenderGlyphs;
+ } else if (arg == QLatin1String("-v")) {
+ ++QPF::debugVerbosity;
+ } else {
+ printf("unknown option %s\n", qPrintable(arg));
+ help();
+ }
+ }
+
+ font.setStyleStrategy(QFont::NoFontMerging);
+
+ QList<QPF::CharacterRange> ranges;
+ ranges.append(QPF::CharacterRange()); // default range from 0 to 0xffff
+
+ QString origFont;
+ QByteArray qpf = QPF::generate(font, generationOptions, ranges, &origFont);
+
+ QString fileName = QPF::fileNameForFont(font);
+ QFile f(fileName);
+ f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ f.write(qpf);
+ f.close();
+
+ if (generationOptions & QPF::IncludeCMap) {
+ printf("Created %s from %s\n", qPrintable(fileName), qPrintable(origFont));
+ } else {
+ printf("Created %s from %s excluding the character-map\n", qPrintable(fileName), qPrintable(origFont));
+ printf("The TrueType font file is therefore required for the font to work\n");
+ }
+
+ return 0;
+}
+
diff --git a/src/makeqpf/mainwindow.cpp b/src/makeqpf/mainwindow.cpp
new file mode 100644
index 000000000..249f49c80
--- /dev/null
+++ b/src/makeqpf/mainwindow.cpp
@@ -0,0 +1,322 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+
+#include <QFontComboBox>
+#include <QFontDatabase>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QListWidget>
+#include <QDebug>
+#include <QShortcut>
+#include <QCompleter>
+#include <QDirModel>
+#include <QTextCodec>
+
+QT_BEGIN_NAMESPACE
+
+MainWindow::MainWindow(const QString &customFont)
+{
+ setupUi(this);
+ pixelSize->setValue(QFontInfo(QFont()).pixelSize());
+ populateCharacterRanges();
+
+ {
+ weightCombo->addItem(QLatin1String("Light"), QVariant(int(QFont::Light)));
+ const int normalIdx = weightCombo->count();
+ weightCombo->addItem(QLatin1String("Normal"), QVariant(int(QFont::Normal)));
+ weightCombo->addItem(QLatin1String("DemiBold"), QVariant(int(QFont::DemiBold)));
+ weightCombo->addItem(QLatin1String("Bold"), QVariant(int(QFont::Bold)));
+ weightCombo->addItem(QLatin1String("Black"), QVariant(int(QFont::Black)));
+
+ weightCombo->setCurrentIndex(normalIdx);
+ }
+
+ QShortcut *sc = new QShortcut(Qt::ControlModifier + Qt::Key_A, this);
+ connect(sc, SIGNAL(activated()),
+ this, SLOT(on_selectAll_clicked()));
+ sc = new QShortcut(Qt::ControlModifier + Qt::Key_D, this);
+ connect(sc, SIGNAL(activated()),
+ this, SLOT(on_deselectAll_clicked()));
+ sc = new QShortcut(Qt::ControlModifier + Qt::Key_I, this);
+ connect(sc, SIGNAL(activated()),
+ this, SLOT(on_invertSelection_clicked()));
+
+ QCompleter *completer = new QCompleter(this);
+ completer->setModel(new QDirModel(this));
+ path->setCompleter(completer);
+ path->setText(QDir::currentPath());
+
+ completer = new QCompleter(this);
+ completer->setModel(new QDirModel(this));
+ sampleFile->setCompleter(completer);
+ charCount->setText(QString());
+
+ if (!customFont.isEmpty())
+ addCustomFont(customFont);
+
+ fontChanged();
+
+ connect(fontComboBox, SIGNAL(currentFontChanged(QFont)),
+ this, SLOT(fontChanged()));
+ connect(pixelSize, SIGNAL(valueChanged(int)),
+ this, SLOT(fontChanged()));
+ connect(italic, SIGNAL(stateChanged(int)),
+ this, SLOT(fontChanged()));
+ connect(weightCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(fontChanged()));
+}
+
+void MainWindow::on_actionAdd_Custom_Font_triggered()
+{
+ QString fontFile = QFileDialog::getOpenFileName(this, tr("Add Custom Font"));
+ if (fontFile.isEmpty())
+ return;
+ addCustomFont(fontFile);
+}
+
+void MainWindow::on_selectAll_clicked()
+{
+ for (int i = 0; i < characterRangeView->count(); ++i)
+ characterRangeView->item(i)->setCheckState(Qt::Checked);
+}
+
+void MainWindow::on_deselectAll_clicked()
+{
+ for (int i = 0; i < characterRangeView->count(); ++i)
+ characterRangeView->item(i)->setCheckState(Qt::Unchecked);
+}
+
+void MainWindow::on_invertSelection_clicked()
+{
+ for (int i = 0; i < characterRangeView->count(); ++i) {
+ QListWidgetItem *item = characterRangeView->item(i);
+ if (item->checkState() == Qt::Checked)
+ item->setCheckState(Qt::Unchecked);
+ else
+ item->setCheckState(Qt::Checked);
+ }
+}
+
+void MainWindow::fontChanged()
+{
+ QFont f = preview->font();
+ f.setStyleStrategy(QFont::NoFontMerging);
+ f.setPixelSize(pixelSize->value());
+ f.setFamily(fontComboBox->currentFont().family());
+ f.setItalic(italic->isChecked());
+ f.setWeight(weightCombo->itemData(weightCombo->currentIndex()).toInt());
+
+ if (!preview->isModified()) {
+ QFontDatabase db;
+ QFontDatabase::WritingSystem ws = db.writingSystems(f.family()).value(0, QFontDatabase::Any);
+ QString sample = db.writingSystemSample(ws);
+ preview->setText(sample);
+ preview->setModified(false);
+ }
+
+ fileName->setText(QPF::fileNameForFont(f));
+
+ preview->setFont(f);
+}
+
+void MainWindow::on_browsePath_clicked()
+{
+ QString dir = QFileDialog::getExistingDirectory(this, tr("Select Directory"));
+ if (!dir.isEmpty())
+ path->setText(dir);
+}
+
+void MainWindow::on_browseSampleFile_clicked()
+{
+ QString dir = QFileDialog::getOpenFileName(this, tr("Select Sample File"));
+ if (!dir.isEmpty()) {
+ sampleFile->setText(dir);
+ on_sampleFile_editingFinished();
+ }
+}
+
+void MainWindow::on_generate_clicked()
+{
+ QFile f(path->text() + QDir::separator() + fileName->text());
+ if (f.exists()) {
+ if (QMessageBox::warning(this, QString(),
+ tr("%1 already exists.\nDo you want to replace it?").arg(f.fileName()),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
+ != QMessageBox::Yes) {
+ statusBar()->showMessage(tr("Pre-rendering aborted..."));
+ return;
+ }
+ }
+
+ QList<QPF::CharacterRange> ranges;
+
+ if (chooseFromSampleFile->isChecked()) {
+ ranges = sampleFileRanges;
+ } else if (chooseFromCodePoints->isChecked()) {
+ ranges.clear();
+ for (int i = 0; i < characterRangeView->count(); ++i) {
+ QListWidgetItem *item = characterRangeView->item(i);
+ if (item->checkState() != Qt::Checked)
+ continue;
+
+ QPF::CharacterRange range = qvariant_cast<QPF::CharacterRange>(item->data(Qt::UserRole));
+ ranges.append(range);
+ }
+ }
+
+ const int generationOptions = QPF::IncludeCMap | QPF::RenderGlyphs;
+ QByteArray qpf = QPF::generate(preview->font(), generationOptions, ranges);
+ f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ f.write(qpf);
+ f.close();
+
+ statusBar()->showMessage(tr("Font successfully pre-rendered to %1").arg(fileName->text()));
+}
+
+void MainWindow::on_sampleFile_editingFinished()
+{
+ sampleFileRanges.clear();
+ QFile f(sampleFile->text());
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ sampleFileRanges.append(QPF::CharacterRange()); // default = all
+ return;
+ }
+ QTextStream stream(&f);
+ stream.setCodec(QTextCodec::codecForName("utf-8"));
+ stream.setAutoDetectUnicode(true);
+ QString text = stream.readAll();
+
+ QSet<QChar> coverage;
+ for (int i = 0; i < text.length(); ++i)
+ coverage.insert(text.at(i));
+
+ QList<QChar> sortedCoverage = QList<QChar>::fromSet(coverage);
+ qSort(sortedCoverage);
+ // play simple :)
+ foreach (QChar ch, sortedCoverage) {
+ QPF::CharacterRange r;
+ r.start = ch.unicode();
+ r.end = r.start + 1;
+ sampleFileRanges.append(r);
+ }
+
+ charCount->setText(tr("(%1 unique characters found)").arg(sortedCoverage.count()));
+}
+
+void MainWindow::populateCharacterRanges()
+{
+ QFile f(":/Blocks.txt");
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ return;
+
+ QRegExp rangeExpr("([0-9a-f]+)\\.\\.([0-9a-f]+); (.+)");
+ rangeExpr.setCaseSensitivity(Qt::CaseInsensitive);
+
+ QString ellipsis(QChar(0x2026));
+ if (!characterRangeView->fontMetrics().inFont(ellipsis.at(0)))
+ ellipsis = QLatin1String("...");
+
+ while (!f.atEnd()) {
+ QString line = QString::fromAscii(f.readLine());
+
+ if (line.endsWith(QLatin1Char('\n')))
+ line.chop(1);
+ if (line.endsWith(QLatin1Char('\r')))
+ line.chop(1);
+
+ line = line.trimmed();
+
+ if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
+ continue;
+
+ if (!rangeExpr.exactMatch(line) || rangeExpr.captureCount() != 3)
+ continue;
+
+ QPF::CharacterRange range;
+
+ bool ok = false;
+ range.start = rangeExpr.cap(1).toUInt(&ok, /*base*/16);
+ if (!ok)
+ continue;
+ range.end = rangeExpr.cap(2).toUInt(&ok, /*base*/16);
+ if (!ok)
+ continue;
+
+ if (range.start >= 0xffff || range.end >= 0xffff)
+ continue;
+
+ QString description = rangeExpr.cap(3);
+
+ QListWidgetItem *item = new QListWidgetItem(characterRangeView);
+ QString text = description;
+ text.append(QLatin1String(" ("));
+ text.append(rangeExpr.cap(1));
+ text.append(ellipsis);
+ text.append(rangeExpr.cap(2));
+ text.append(QLatin1String(")"));
+ item->setText(text);
+ item->setCheckState(Qt::Checked);
+
+ item->setData(Qt::UserRole, QVariant::fromValue(range));
+ }
+}
+
+void MainWindow::addCustomFont(const QString &fontFile)
+{
+ int id = QFontDatabase::addApplicationFont(fontFile);
+ if (id < 0) {
+ QMessageBox::warning(this, tr("Error Adding Custom Font"),
+ tr("The custom font %s could not be loaded.").arg(fontFile));
+ return;
+ }
+ const QStringList families = QFontDatabase::applicationFontFamilies(id);
+ if (families.isEmpty()) {
+ QMessageBox::warning(this, tr("Error Adding Custom Font"),
+ tr("The custom font %s provides no font families.").arg(fontFile));
+ return;
+ }
+ QFont f(families.first());
+ fontComboBox->setCurrentFont(f);
+}
+
+QT_END_NAMESPACE
diff --git a/src/makeqpf/mainwindow.h b/src/makeqpf/mainwindow.h
new file mode 100644
index 000000000..33a6424ae
--- /dev/null
+++ b/src/makeqpf/mainwindow.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+#include "ui_mainwindow.h"
+#include "qpf2.h"
+
+QT_BEGIN_NAMESPACE
+
+class QListWidgetItem;
+
+class MainWindow : public QMainWindow, Ui::MainWindow
+{
+ Q_OBJECT
+public:
+ MainWindow(const QString &customFont);
+
+private Q_SLOTS:
+ void on_actionAdd_Custom_Font_triggered();
+ void on_selectAll_clicked();
+ void on_deselectAll_clicked();
+ void on_invertSelection_clicked();
+ void fontChanged();
+ void on_browsePath_clicked();
+ void on_browseSampleFile_clicked();
+ void on_generate_clicked();
+ void on_sampleFile_editingFinished();
+
+private:
+ void populateCharacterRanges();
+ void addCustomFont(const QString &fontFile);
+
+private:
+ QList<QPF::CharacterRange> sampleFileRanges;
+};
+
+QT_END_NAMESPACE
+
+#endif // MAINWINDOW_H
diff --git a/src/makeqpf/mainwindow.ui b/src/makeqpf/mainwindow.ui
new file mode 100644
index 000000000..f6eda4fdd
--- /dev/null
+++ b/src/makeqpf/mainwindow.ui
@@ -0,0 +1,502 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>829</width>
+ <height>813</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MakeQPF</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Font Properties</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Family:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFontComboBox" name="fontComboBox" />
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Pixel Size:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="pixelSize" >
+ <property name="minimum" >
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_7" >
+ <property name="text" >
+ <string>Weight:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="weightCombo" />
+ </item>
+ <item>
+ <widget class="QCheckBox" name="italic" >
+ <property name="text" >
+ <string>Italic</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Glyph Coverage</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="chooseFromCodePoints" >
+ <property name="text" >
+ <string>Choose from Unicode Codepoints:</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="characterRangeView" />
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="selectAll" >
+ <property name="text" >
+ <string>Select &amp;All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deselectAll" >
+ <property name="text" >
+ <string>&amp;Deselect All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="invertSelection" >
+ <property name="text" >
+ <string>&amp;Invert Selection</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="chooseFromSampleFile" >
+ <property name="text" >
+ <string>Choose from Sample Text File (UTF-8 Encoded):</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_5" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Path:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="sampleFile" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="browseSampleFile" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="charCount" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_3" >
+ <property name="title" >
+ <string>Preview</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="preview" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_4" >
+ <property name="title" >
+ <string>Output Options</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Path:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="path" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="browsePath" >
+ <property name="text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Filename:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="fileName" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="generate" >
+ <property name="text" >
+ <string>Generate Pre-Rendered Font...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>829</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile" >
+ <property name="title" >
+ <string>File</string>
+ </property>
+ <addaction name="actionAdd_Custom_Font" />
+ <addaction name="separator" />
+ <addaction name="action_Exit" />
+ </widget>
+ <addaction name="menuFile" />
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ <action name="actionAdd_Custom_Font" >
+ <property name="text" >
+ <string>&amp;Add Custom Font...</string>
+ </property>
+ </action>
+ <action name="action_Exit" >
+ <property name="text" >
+ <string>&amp;Exit</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>action_Exit</sender>
+ <signal>triggered()</signal>
+ <receiver>MainWindow</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>383</x>
+ <y>215</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>chooseFromCodePoints</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>characterRangeView</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>183</x>
+ <y>144</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>146</x>
+ <y>295</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>chooseFromCodePoints</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>selectAll</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>236</x>
+ <y>146</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>46</x>
+ <y>508</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>chooseFromCodePoints</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>deselectAll</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>280</x>
+ <y>147</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>158</x>
+ <y>502</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>chooseFromCodePoints</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>invertSelection</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>364</x>
+ <y>143</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>281</x>
+ <y>509</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>chooseFromSampleFile</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>sampleFile</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>134</x>
+ <y>544</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>64</x>
+ <y>569</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>chooseFromSampleFile</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>browseSampleFile</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>79</x>
+ <y>545</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>710</x>
+ <y>582</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>chooseFromSampleFile</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>charCount</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>274</x>
+ <y>544</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>790</x>
+ <y>569</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>chooseFromSampleFile</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>label_5</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>112</x>
+ <y>541</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>37</x>
+ <y>579</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/makeqpf/makeqpf.pro b/src/makeqpf/makeqpf.pro
new file mode 100644
index 000000000..c2dc9cc38
--- /dev/null
+++ b/src/makeqpf/makeqpf.pro
@@ -0,0 +1,20 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Wed Nov 29 16:21:49 2006
+######################################################################
+
+TEMPLATE = app
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += . ../../src/3rdparty/harfbuzz/src
+CONFIG += console
+DESTDIR = ../../bin
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+# Input
+HEADERS += qpf2.h mainwindow.h
+SOURCES += main.cpp qpf2.cpp mainwindow.cpp
+DEFINES += QT_NO_FREETYPE
+FORMS += mainwindow.ui
+RESOURCES += makeqpf.qrc
diff --git a/src/makeqpf/makeqpf.qrc b/src/makeqpf/makeqpf.qrc
new file mode 100644
index 000000000..b1d73b010
--- /dev/null
+++ b/src/makeqpf/makeqpf.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>Blocks.txt</file>
+</qresource>
+</RCC>
diff --git a/src/makeqpf/qpf2.cpp b/src/makeqpf/qpf2.cpp
new file mode 100644
index 000000000..f0dcf95ea
--- /dev/null
+++ b/src/makeqpf/qpf2.cpp
@@ -0,0 +1,767 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpf2.h"
+
+#include <math.h>
+#include <private/qfontengine_p.h>
+#include <QFile>
+#include <qendian.h>
+
+QT_BEGIN_NAMESPACE
+
+#include "../../src/gui/text/qpfutil.cpp"
+
+int QPF::debugVerbosity = 0;
+
+// ### copied from qfontdatabase.cpp
+
+// see the Unicode subset bitfields in the MSDN docs
+static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
+ // Any,
+ { 127, 127 },
+ // Latin,
+ { 0, 127 },
+ // Greek,
+ { 7, 127 },
+ // Cyrillic,
+ { 9, 127 },
+ // Armenian,
+ { 10, 127 },
+ // Hebrew,
+ { 11, 127 },
+ // Arabic,
+ { 13, 127 },
+ // Syriac,
+ { 71, 127 },
+ //Thaana,
+ { 72, 127 },
+ //Devanagari,
+ { 15, 127 },
+ //Bengali,
+ { 16, 127 },
+ //Gurmukhi,
+ { 17, 127 },
+ //Gujarati,
+ { 18, 127 },
+ //Oriya,
+ { 19, 127 },
+ //Tamil,
+ { 20, 127 },
+ //Telugu,
+ { 21, 127 },
+ //Kannada,
+ { 22, 127 },
+ //Malayalam,
+ { 23, 127 },
+ //Sinhala,
+ { 73, 127 },
+ //Thai,
+ { 24, 127 },
+ //Lao,
+ { 25, 127 },
+ //Tibetan,
+ { 70, 127 },
+ //Myanmar,
+ { 74, 127 },
+ // Georgian,
+ { 26, 127 },
+ // Khmer,
+ { 80, 127 },
+ // SimplifiedChinese,
+ { 126, 127 },
+ // TraditionalChinese,
+ { 126, 127 },
+ // Japanese,
+ { 126, 127 },
+ // Korean,
+ { 56, 127 },
+ // Vietnamese,
+ { 0, 127 }, // same as latin1
+ // Other,
+ { 126, 127 }
+};
+
+#define SimplifiedChineseCsbBit 18
+#define TraditionalChineseCsbBit 20
+#define JapaneseCsbBit 17
+#define KoreanCsbBit 21
+
+static QList<QFontDatabase::WritingSystem> determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
+{
+ QList<QFontDatabase::WritingSystem> writingSystems;
+ bool hasScript = false;
+
+ int i;
+ for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
+ int bit = requiredUnicodeBits[i][0];
+ int index = bit/32;
+ int flag = 1 << (bit&31);
+ if (bit != 126 && unicodeRange[index] & flag) {
+ bit = requiredUnicodeBits[i][1];
+ index = bit/32;
+
+ flag = 1 << (bit&31);
+ if (bit == 127 || unicodeRange[index] & flag) {
+ writingSystems.append(QFontDatabase::WritingSystem(i));
+ hasScript = true;
+ // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
+ }
+ }
+ }
+ if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
+ writingSystems.append(QFontDatabase::SimplifiedChinese);
+ hasScript = true;
+ //qDebug("font %s supports Simplified Chinese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
+ writingSystems.append(QFontDatabase::TraditionalChinese);
+ hasScript = true;
+ //qDebug("font %s supports Traditional Chinese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << JapaneseCsbBit)) {
+ writingSystems.append(QFontDatabase::Japanese);
+ hasScript = true;
+ //qDebug("font %s supports Japanese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << KoreanCsbBit)) {
+ writingSystems.append(QFontDatabase::Korean);
+ hasScript = true;
+ //qDebug("font %s supports Korean", familyName.latin1());
+ }
+ if (!hasScript)
+ writingSystems.append(QFontDatabase::Symbol);
+
+ return writingSystems;
+}
+
+static QByteArray getWritingSystems(QFontEngine *fontEngine)
+{
+ QByteArray os2Table = fontEngine->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
+ if (os2Table.isEmpty())
+ return QByteArray();
+
+ const uchar *data = reinterpret_cast<const uchar *>(os2Table.constData());
+
+ quint32 unicodeRange[4] = {
+ qFromBigEndian<quint32>(data + 42),
+ qFromBigEndian<quint32>(data + 46),
+ qFromBigEndian<quint32>(data + 50),
+ qFromBigEndian<quint32>(data + 54)
+ };
+ quint32 codePageRange[2] = { qFromBigEndian<quint32>(data + 78), qFromBigEndian<quint32>(data + 82) };
+ QList<QFontDatabase::WritingSystem> systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+
+ QByteArray bitField((QFontDatabase::WritingSystemsCount + 7) / 8, 0);
+
+ for (int i = 0; i < systems.count(); ++i) {
+ int bitPos = systems.at(i);
+ bitField[bitPos / 8] = bitField.at(bitPos / 8) | (1 << (bitPos % 8));
+ }
+
+ return bitField;
+}
+
+static QString stringify(const QByteArray &bits)
+{
+ QString result;
+ for (int i = 0; i < bits.count(); ++i) {
+ uchar currentByte = bits.at(i);
+ for (int j = 0; j < 8; ++j) {
+ if (currentByte & 1)
+ result += '1';
+ else
+ result += '0';
+ currentByte >>= 1;
+ }
+ }
+ return result;
+}
+
+static void dumpWritingSystems(const QByteArray &bits)
+{
+ QStringList writingSystems;
+
+ QString bitString = stringify(bits);
+ for (int i = 0; i < qMin(int(QFontDatabase::WritingSystemsCount), bitString.length()); ++i) {
+ if (bitString.at(i) == QLatin1Char('1'))
+ writingSystems << QFontDatabase::writingSystemName(QFontDatabase::WritingSystem(i));
+ }
+
+ qDebug() << "Supported writing systems:" << writingSystems;
+}
+
+static const char *headerTagNames[QFontEngineQPF::NumTags] = {
+ "FontName",
+ "FileName",
+ "FileIndex",
+ "FontRevision",
+ "FreeText",
+ "Ascent",
+ "Descent",
+ "Leading",
+ "XHeight",
+ "AverageCharWidth",
+ "MaxCharWidth",
+ "LineThickness",
+ "MinLeftBearing",
+ "MinRightBearing",
+ "UnderlinePosition",
+ "GlyphFormat",
+ "PixelSize",
+ "Weight",
+ "Style",
+ "EndOfHeader",
+ "WritingSystems"
+};
+
+QString QPF::fileNameForFont(const QFont &f)
+{
+ QString fileName = f.family().toLower() + "_" + QString::number(f.pixelSize())
+ + "_" + QString::number(f.weight())
+ + (f.italic() ? "_italic" : "")
+ + ".qpf2";
+ fileName.replace(QLatin1Char(' '), QLatin1Char('_'));
+ return fileName;
+}
+
+QByteArray QPF::generate(const QFont &font, int options, const QList<CharacterRange> &ranges, QString *originalFontFile)
+{
+ QTextEngine engine("Test", font);
+ engine.itemize();
+ engine.shape(0);
+ QFontEngine *fontEngine = engine.fontEngine(engine.layoutData->items[0]);
+ if (fontEngine->type() == QFontEngine::Multi)
+ fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(0);
+
+ if (originalFontFile)
+ *originalFontFile = QFile::decodeName(fontEngine->faceId().filename);
+
+ return generate(fontEngine, options, ranges);
+}
+
+QByteArray QPF::generate(QFontEngine *fontEngine, int options, const QList<CharacterRange> &ranges)
+{
+ QPF font;
+
+ font.options = options;
+ font.addHeader(fontEngine);
+ if (options & IncludeCMap)
+ font.addCMap(fontEngine);
+ font.addGlyphs(fontEngine, ranges);
+
+ return font.qpf;
+}
+
+void QPF::addHeader(QFontEngine *fontEngine)
+{
+ QFontEngineQPF::Header *header = reinterpret_cast<QFontEngineQPF::Header *>(addBytes(sizeof(QFontEngineQPF::Header)));
+
+ header->magic[0] = 'Q';
+ header->magic[1] = 'P';
+ header->magic[2] = 'F';
+ header->magic[3] = '2';
+ if (options & RenderGlyphs)
+ header->lock = 0xffffffff;
+ else
+ header->lock = 0;
+ header->majorVersion = QFontEngineQPF::CurrentMajorVersion;
+ header->minorVersion = QFontEngineQPF::CurrentMinorVersion;
+ header->dataSize = 0;
+ int oldSize = qpf.size();
+
+ addTaggedString(QFontEngineQPF::Tag_FontName, fontEngine->fontDef.family.toUtf8());
+
+ QFontEngine::FaceId face = fontEngine->faceId();
+ addTaggedString(QFontEngineQPF::Tag_FileName, face.filename);
+ addTaggedUInt32(QFontEngineQPF::Tag_FileIndex, face.index);
+
+ {
+ const QByteArray head = fontEngine->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));
+ const quint32 revision = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(head.constData()) + 4);
+ addTaggedUInt32(QFontEngineQPF::Tag_FontRevision, revision);
+ }
+
+ addTaggedQFixed(QFontEngineQPF::Tag_Ascent, fontEngine->ascent());
+ addTaggedQFixed(QFontEngineQPF::Tag_Descent, fontEngine->descent());
+ addTaggedQFixed(QFontEngineQPF::Tag_Leading, fontEngine->leading());
+ addTaggedQFixed(QFontEngineQPF::Tag_XHeight, fontEngine->xHeight());
+ addTaggedQFixed(QFontEngineQPF::Tag_AverageCharWidth, fontEngine->averageCharWidth());
+ addTaggedQFixed(QFontEngineQPF::Tag_MaxCharWidth, QFixed::fromReal(fontEngine->maxCharWidth()));
+ addTaggedQFixed(QFontEngineQPF::Tag_LineThickness, fontEngine->lineThickness());
+ addTaggedQFixed(QFontEngineQPF::Tag_MinLeftBearing, QFixed::fromReal(fontEngine->minLeftBearing()));
+ addTaggedQFixed(QFontEngineQPF::Tag_MinRightBearing, QFixed::fromReal(fontEngine->minRightBearing()));
+ addTaggedQFixed(QFontEngineQPF::Tag_UnderlinePosition, fontEngine->underlinePosition());
+ addTaggedUInt8(QFontEngineQPF::Tag_PixelSize, fontEngine->fontDef.pixelSize);
+ addTaggedUInt8(QFontEngineQPF::Tag_Weight, fontEngine->fontDef.weight);
+ addTaggedUInt8(QFontEngineQPF::Tag_Style, fontEngine->fontDef.style);
+
+ QByteArray writingSystemBitField = getWritingSystems(fontEngine);
+ if (!writingSystemBitField.isEmpty())
+ addTaggedString(QFontEngineQPF::Tag_WritingSystems, writingSystemBitField);
+
+ addTaggedUInt8(QFontEngineQPF::Tag_GlyphFormat, QFontEngineQPF::AlphamapGlyphs);
+
+ addTaggedString(QFontEngineQPF::Tag_EndOfHeader, QByteArray());
+ align4();
+ header = reinterpret_cast<QFontEngineQPF::Header *>(qpf.data());
+ header->dataSize = qToBigEndian<quint16>(qpf.size() - oldSize);
+}
+
+static uchar *appendBytes(QByteArray &array, int size)
+{
+ int oldSize = array.size();
+ array.resize(array.size() + size);
+ return reinterpret_cast<uchar *>(array.data() + oldSize);
+}
+
+#define APPEND(type, value) \
+ qToBigEndian<type>(value, appendBytes(cmap, sizeof(type)))
+
+struct CMapSegment
+{
+ int start; // codepoints
+ int end;
+ int startGlyphIndex;
+};
+
+static QByteArray generateTrueTypeCMap(QFontEngine *fe)
+{
+ QByteArray cmap;
+ const int glyphCount = fe->glyphCount();
+ if (!glyphCount)
+ return cmap;
+
+ // cmap header
+ APPEND(quint16, 0); // table version number
+ APPEND(quint16, 1); // number of tables
+
+ // encoding record
+ APPEND(quint16, 3); // platform-id
+ APPEND(quint16, 10); // encoding-id (ucs-4)
+ const int cmapOffset = cmap.size() + sizeof(quint32);
+ APPEND(quint32, cmapOffset); // offset to sub-table
+
+ APPEND(quint16, 4); // subtable format
+ const int cmapTableLengthOffset = cmap.size();
+ APPEND(quint16, 0); // length in bytes, will fill in later
+ APPEND(quint16, 0); // language field
+
+ QList<CMapSegment> segments;
+ CMapSegment currentSegment;
+ currentSegment.start = 0xffff;
+ currentSegment.end = 0;
+ currentSegment.startGlyphIndex = 0;
+ quint32 previousGlyphIndex = 0xfffffffe;
+ bool inSegment = false;
+
+ QGlyphLayoutArray<10> layout;
+ for (uint uc = 0; uc < 0x10000; ++uc) {
+ QChar ch(uc);
+ int nglyphs = 10;
+
+ bool validGlyph = fe->stringToCMap(&ch, 1, &layout, &nglyphs, /*flags*/ 0)
+ && nglyphs == 1 && layout.glyphs[0];
+
+ // leaving a segment?
+ if (inSegment && (!validGlyph || layout.glyphs[0] != previousGlyphIndex + 1)) {
+ Q_ASSERT(currentSegment.start != 0xffff);
+ // store the current segment
+ currentSegment.end = uc - 1;
+ segments.append(currentSegment);
+ currentSegment.start = 0xffff;
+ inSegment = false;
+ }
+ // entering a new segment?
+ if (validGlyph && (!inSegment || layout.glyphs[0] != previousGlyphIndex + 1)) {
+ currentSegment.start = uc;
+ currentSegment.startGlyphIndex = layout.glyphs[0];
+ inSegment = true;
+ }
+
+ if (validGlyph)
+ previousGlyphIndex = layout.glyphs[0];
+ else
+ previousGlyphIndex = 0xfffffffe;
+ }
+
+ currentSegment.start = 0xffff;
+ currentSegment.end = 0xffff;
+ currentSegment.startGlyphIndex = 0;
+ segments.append(currentSegment);
+
+ if (QPF::debugVerbosity > 3)
+ qDebug() << "segments:" << segments.count();
+
+ Q_ASSERT(!inSegment);
+
+ const quint16 entrySelector = int(log2(segments.count()));
+ const quint16 searchRange = 2 * (1 << entrySelector);
+ const quint16 rangeShift = segments.count() * 2 - searchRange;
+
+ if (QPF::debugVerbosity > 3)
+ qDebug() << "entrySelector" << entrySelector << "searchRange" << searchRange
+ << "rangeShift" << rangeShift;
+
+ APPEND(quint16, segments.count() * 2); // segCountX2
+ APPEND(quint16, searchRange);
+ APPEND(quint16, entrySelector);
+ APPEND(quint16, rangeShift);
+
+ // end character codes
+ for (int i = 0; i < segments.count(); ++i)
+ APPEND(quint16, segments.at(i).end);
+
+ APPEND(quint16, 0); // pad
+
+ // start character codes
+ for (int i = 0; i < segments.count(); ++i)
+ APPEND(quint16, segments.at(i).start);
+
+ // id deltas
+ for (int i = 0; i < segments.count(); ++i)
+ APPEND(quint16, segments.at(i).startGlyphIndex - segments.at(i).start);
+
+ // id range offsets
+ for (int i = 0; i < segments.count(); ++i)
+ APPEND(quint16, 0);
+
+ uchar *lengthPtr = reinterpret_cast<uchar *>(cmap.data()) + cmapTableLengthOffset;
+ qToBigEndian<quint16>(cmap.size() - cmapOffset, lengthPtr);
+
+ return cmap;
+}
+
+void QPF::addCMap(QFontEngine *fontEngine)
+{
+ QByteArray cmapTable = fontEngine->getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
+ if (cmapTable.isEmpty())
+ cmapTable = generateTrueTypeCMap(fontEngine);
+ addBlock(QFontEngineQPF::CMapBlock, cmapTable);
+}
+
+void QPF::addGlyphs(QFontEngine *fe, const QList<CharacterRange> &ranges)
+{
+ const quint16 glyphCount = fe->glyphCount();
+
+ QByteArray gmap;
+ gmap.resize(glyphCount * sizeof(quint32));
+ gmap.fill(char(0xff));
+ //qDebug() << "glyphCount" << glyphCount;
+
+ QByteArray glyphs;
+ if (options & RenderGlyphs) {
+ // this is only a rough estimation
+ glyphs.reserve(glyphCount
+ * (sizeof(QFontEngineQPF::Glyph)
+ + qRound(fe->maxCharWidth() * (fe->ascent() + fe->descent()).toReal())));
+
+ QGlyphLayoutArray<10> layout;
+
+ foreach (CharacterRange range, ranges) {
+ if (debugVerbosity > 2)
+ qDebug() << "rendering range from" << range.start << "to" << range.end;
+ for (uint uc = range.start; uc < range.end; ++uc) {
+ QChar ch(uc);
+ int nglyphs = 10;
+ if (!fe->stringToCMap(&ch, 1, &layout, &nglyphs, /*flags*/ 0))
+ continue;
+
+ if (nglyphs != 1)
+ continue;
+
+ const quint32 glyphIndex = layout.glyphs[0];
+
+ if (!glyphIndex)
+ continue;
+
+ Q_ASSERT(glyphIndex < glyphCount);
+
+ QImage img = fe->alphaMapForGlyph(glyphIndex).convertToFormat(QImage::Format_Indexed8);
+ glyph_metrics_t metrics = fe->boundingBox(glyphIndex);
+
+ const quint32 oldSize = glyphs.size();
+ glyphs.resize(glyphs.size() + sizeof(QFontEngineQPF::Glyph) + img.byteCount());
+ uchar *data = reinterpret_cast<uchar *>(glyphs.data() + oldSize);
+
+ uchar *gmapPtr = reinterpret_cast<uchar *>(gmap.data() + glyphIndex * sizeof(quint32));
+ qToBigEndian(oldSize, gmapPtr);
+
+ QFontEngineQPF::Glyph *glyph = reinterpret_cast<QFontEngineQPF::Glyph *>(data);
+ glyph->width = img.width();
+ glyph->height = img.height();
+ glyph->bytesPerLine = img.bytesPerLine();
+ glyph->x = qRound(metrics.x);
+ glyph->y = qRound(metrics.y);
+ glyph->advance = qRound(metrics.xoff);
+ data += sizeof(QFontEngineQPF::Glyph);
+
+ if (debugVerbosity && uc >= 'A' && uc <= 'z' || debugVerbosity > 1) {
+ qDebug() << "adding glyph with index" << glyphIndex << " uc =" << char(uc) << ":\n"
+ << " glyph->x =" << glyph->x << "rounded from" << metrics.x << "\n"
+ << " glyph->y =" << glyph->y << "rounded from" << metrics.y << "\n"
+ << " width =" << glyph->width << "height =" << glyph->height
+ << " advance =" << glyph->advance << "rounded from" << metrics.xoff
+ ;
+ }
+
+ memcpy(data, img.bits(), img.byteCount());
+ }
+ }
+ }
+
+ addBlock(QFontEngineQPF::GMapBlock, gmap);
+ addBlock(QFontEngineQPF::GlyphBlock, glyphs);
+}
+
+void QPF::addBlock(QFontEngineQPF::BlockTag tag, const QByteArray &blockData)
+{
+ addUInt16(tag);
+ addUInt16(0); // padding
+ const int padSize = ((blockData.size() + 3) / 4) * 4 - blockData.size();
+ addUInt32(blockData.size() + padSize);
+ addByteArray(blockData);
+ for (int i = 0; i < padSize; ++i)
+ addUInt8(0);
+}
+
+#define ADD_TAGGED_DATA(tag, qtype, type, value) \
+ addUInt16(tag); \
+ addUInt16(sizeof(qtype)); \
+ add##type(value)
+
+void QPF::addTaggedString(QFontEngineQPF::HeaderTag tag, const QByteArray &string)
+{
+ addUInt16(tag);
+ addUInt16(string.length());
+ addByteArray(string);
+}
+
+void QPF::addTaggedQFixed(QFontEngineQPF::HeaderTag tag, QFixed value)
+{
+ ADD_TAGGED_DATA(tag, quint32, UInt32, value.value());
+}
+
+void QPF::addTaggedUInt8(QFontEngineQPF::HeaderTag tag, quint8 value)
+{
+ ADD_TAGGED_DATA(tag, quint8, UInt8, value);
+}
+
+void QPF::addTaggedInt8(QFontEngineQPF::HeaderTag tag, qint8 value)
+{
+ ADD_TAGGED_DATA(tag, qint8, Int8, value);
+}
+
+void QPF::addTaggedUInt16(QFontEngineQPF::HeaderTag tag, quint16 value)
+{
+ ADD_TAGGED_DATA(tag, quint16, UInt16, value);
+}
+
+void QPF::addTaggedUInt32(QFontEngineQPF::HeaderTag tag, quint32 value)
+{
+ ADD_TAGGED_DATA(tag, quint32, UInt32, value);
+}
+
+void QPF::dump(const QByteArray &qpf)
+{
+ QPF font;
+ font.qpf = qpf;
+
+ const uchar *data = reinterpret_cast<const uchar *>(qpf.constData());
+ const uchar *endPtr = reinterpret_cast<const uchar *>(qpf.constData() + qpf.size());
+ data = font.dumpHeader(data);
+
+ const quint32 *gmap = 0;
+ quint32 glyphCount = 0;
+
+ while (data < endPtr) {
+ const QFontEngineQPF::Block *block = reinterpret_cast<const QFontEngineQPF::Block *>(data);
+ quint32 tag = qFromBigEndian(block->tag);
+ quint32 blockSize = qFromBigEndian(block->dataSize);
+ qDebug() << "Block: Tag =" << qFromBigEndian(block->tag) << "; Size =" << blockSize << "; Offset =" << hex << data - reinterpret_cast<const uchar *>(qpf.constData());
+ data += sizeof(QFontEngineQPF::Block);
+
+ if (debugVerbosity) {
+ if (tag == QFontEngineQPF::GMapBlock) {
+ gmap = reinterpret_cast<const quint32 *>(data);
+ glyphCount = blockSize / 4;
+ font.dumpGMapBlock(gmap, glyphCount);
+ } else if (tag == QFontEngineQPF::GlyphBlock
+ && gmap && debugVerbosity > 1) {
+ font.dumpGlyphBlock(gmap, glyphCount, data, data + blockSize);
+ }
+ }
+
+ data += blockSize;
+ }
+}
+
+const uchar *QPF::dumpHeader(const uchar *data)
+{
+ const QFontEngineQPF::Header *header = reinterpret_cast<const QFontEngineQPF::Header *>(data);
+ qDebug() << "Header:";
+ qDebug() << "magic ="
+ << header->magic[0]
+ << header->magic[1]
+ << header->magic[2]
+ << header->magic[3];
+ qDebug() << "lock =" << qFromBigEndian(header->lock);
+ qDebug() << "majorVersion =" << header->majorVersion;
+ qDebug() << "minorVersion =" << header->minorVersion;
+ qDebug() << "dataSize =" << qFromBigEndian(header->dataSize);
+
+ data += sizeof(QFontEngineQPF::Header);
+
+ const uchar *endPtr = data + qFromBigEndian(header->dataSize);
+
+ while (data && data < endPtr) {
+ data = dumpHeaderTag(data);
+ }
+
+ return endPtr;
+}
+
+const uchar *QPF::dumpHeaderTag(const uchar *data)
+{
+ const QFontEngineQPF::Tag *tagPtr = reinterpret_cast<const QFontEngineQPF::Tag *>(data);
+ quint16 tag = qFromBigEndian(tagPtr->tag);
+ quint16 size = qFromBigEndian(tagPtr->size);
+
+ qDebug() << "Tag =" << tag << headerTagNames[tag];
+ qDebug() << "Size =" << size;
+
+ if (tag == QFontEngineQPF::Tag_EndOfHeader)
+ return 0;
+
+ data += sizeof(QFontEngineQPF::Tag);
+
+ Q_ASSERT(tag < QFontEngineQPF::NumTags);
+
+ switch (tagTypes[tag]) {
+ case QFontEngineQPF::StringType:
+ qDebug() << "Payload =" << QString::fromUtf8(QByteArray(reinterpret_cast<const char *>(data), size));
+ break;
+ case QFontEngineQPF::FixedType:
+ Q_ASSERT(size == sizeof(quint32));
+ qDebug() << "Payload =" << QFixed::fromFixed(qFromBigEndian<quint32>(data)).toReal();
+ break;
+ case QFontEngineQPF::UInt8Type:
+ Q_ASSERT(size == sizeof(quint8));
+ qDebug() << "Payload =" << *data;
+ break;
+ case QFontEngineQPF::UInt32Type:
+ Q_ASSERT(size == sizeof(quint32));
+ qDebug() << "Payload =" << qFromBigEndian<quint32>(data);
+ break;
+ case QFontEngineQPF::BitFieldType: {
+ QByteArray bits(reinterpret_cast<const char *>(data), size);
+ qDebug() << "Payload =" << stringify(bits);
+ if (QPF::debugVerbosity > 2 && tag == QFontEngineQPF::Tag_WritingSystems)
+ dumpWritingSystems(bits);
+ } break;
+ }
+
+ data += size;
+ return data;
+}
+
+void QPF::dumpGMapBlock(const quint32 *gmap, int glyphCount)
+{
+ qDebug() << "glyphCount =" << glyphCount;
+ int renderedGlyphs = 0;
+ for (int i = 0; i < glyphCount; ++i) {
+ if (gmap[i] != 0xffffffff) {
+ const quint32 glyphPos = qFromBigEndian(gmap[i]);
+ qDebug("gmap[%d] = 0x%x / %u", i, glyphPos, glyphPos);
+ ++renderedGlyphs;
+ }
+ }
+ qDebug() << "Glyphs rendered:" << renderedGlyphs << "; Glyphs missing from the font:" << glyphCount - renderedGlyphs;
+}
+
+void QPF::dumpGlyphBlock(const quint32 *gmap, int glyphCount, const uchar *data, const uchar *endPtr)
+{
+ // glyphPos -> glyphIndex
+ QMap<quint32, quint32> reverseGlyphMap;
+ for (int i = 0; i < glyphCount; ++i) {
+ if (gmap[i] == 0xffffffff)
+ continue;
+ const quint32 glyphPos = qFromBigEndian(gmap[i]);
+ reverseGlyphMap[glyphPos] = i;
+ }
+
+ const uchar *glyphBlockBegin = data;
+ while (data < endPtr) {
+ const QFontEngineQPF::Glyph *g = reinterpret_cast<const QFontEngineQPF::Glyph *>(data);
+
+ const quint64 glyphOffset = data - glyphBlockBegin;
+ const quint32 glyphIndex = reverseGlyphMap.value(glyphOffset, 0xffffffff);
+
+ if (glyphIndex == 0xffffffff)
+ qDebug() << "############: Glyph present in glyph block is not listed in glyph map!";
+ qDebug("glyph at offset 0x%x glyphIndex = %u", quint32(glyphOffset), glyphIndex);
+ qDebug() << " width =" << g->width << "height =" << g->height << "x =" << g->x << "y =" << g->y;
+ qDebug() << " advance =" << g->advance << "bytesPerLine =" << g->bytesPerLine;
+
+ data += sizeof(*g);
+ if (glyphIndex == 0xffffffff || debugVerbosity > 4) {
+ dumpGlyph(data, g);
+ }
+
+ data += g->height * g->bytesPerLine;
+ }
+}
+
+void QPF::dumpGlyph(const uchar *data, const QFontEngineQPF::Glyph *glyph)
+{
+ fprintf(stderr, "---- glyph data:\n");
+ const char *alphas = " .o#";
+ for (int y = 0; y < glyph->height; ++y) {
+ for (int x = 0; x < glyph->width; ++x) {
+ const uchar value = data[y * glyph->bytesPerLine + x];
+ fprintf(stderr, "%c", alphas[value >> 6]);
+ }
+ fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "----\n");
+}
+
+QT_END_NAMESPACE
diff --git a/src/makeqpf/qpf2.h b/src/makeqpf/qpf2.h
new file mode 100644
index 000000000..5dc09b0ce
--- /dev/null
+++ b/src/makeqpf/qpf2.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPF2_H
+#define QPF2_H
+
+#include <private/qfontengine_qpf_p.h>
+#include <qmetatype.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFontEngine;
+
+class QPF
+{
+public:
+ static int debugVerbosity;
+
+ enum GenerationOption {
+ IncludeCMap = 0x1,
+ RenderGlyphs = 0x2
+ };
+
+ struct CharacterRange
+ {
+ inline CharacterRange() : start(0), end(0x10000) {}
+ uint start;
+ uint end;
+ };
+
+ static QString fileNameForFont(const QFont &f);
+
+ static QByteArray generate(const QFont &font, int options,
+ const QList<CharacterRange> &ranges,
+ QString *originalFontFile = 0);
+ static QByteArray generate(QFontEngine *fontEngine, int options, const QList<CharacterRange> &ranges);
+ void addHeader(QFontEngine *fontEngine);
+ void addCMap(QFontEngine *fontEngine);
+ void addGlyphs(QFontEngine *fontEngine, const QList<CharacterRange> &ranges);
+ void addBlock(QFontEngineQPF::BlockTag tag, const QByteArray &data);
+
+ void addTaggedString(QFontEngineQPF::HeaderTag tag, const QByteArray &string);
+ void addTaggedQFixed(QFontEngineQPF::HeaderTag tag, QFixed value);
+ void addTaggedUInt8(QFontEngineQPF::HeaderTag tag, quint8 value);
+ void addTaggedInt8(QFontEngineQPF::HeaderTag tag, qint8 value);
+ void addTaggedUInt16(QFontEngineQPF::HeaderTag tag, quint16 value);
+ void addTaggedUInt32(QFontEngineQPF::HeaderTag tag, quint32 value);
+
+ static void dump(const QByteArray &qpf);
+ const uchar *dumpHeader(const uchar *data);
+ const uchar *dumpHeaderTag(const uchar *data);
+ void dumpGMapBlock(const quint32 *gmap, int glyphCount);
+ void dumpGlyphBlock(const quint32 *gmap, int glyphCount, const uchar *data, const uchar *endPtr);
+ void dumpGlyph(const uchar *data, const QFontEngineQPF::Glyph *glyph);
+
+ void addUInt16(quint16 value) { qToBigEndian(value, addBytes(sizeof(value))); }
+ void addUInt32(quint32 value) { qToBigEndian(value, addBytes(sizeof(value))); }
+ void addUInt8(quint8 value) { *addBytes(sizeof(value)) = value; }
+ void addInt8(qint8 value) { *addBytes(sizeof(value)) = quint8(value); }
+ void addByteArray(const QByteArray &string) {
+ uchar *data = addBytes(string.length());
+ qMemCopy(data, string.constData(), string.length());
+ }
+
+ void align4() { while (qpf.size() & 3) { addUInt8('\0'); } }
+
+ uchar *addBytes(int size) {
+ const int oldSize = qpf.size();
+ qpf.resize(qpf.size() + size);
+ return reinterpret_cast<uchar *>(qpf.data() + oldSize);
+ }
+
+ QByteArray qpf;
+ int options;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QPF::CharacterRange)
+
+#endif // QPF2_H
diff --git a/src/pixeltool/Info_mac.plist b/src/pixeltool/Info_mac.plist
new file mode 100644
index 000000000..294db21b0
--- /dev/null
+++ b/src/pixeltool/Info_mac.plist
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>@ICON@</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.trolltech.pixeltool</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+</dict>
+</plist>
diff --git a/src/pixeltool/main.cpp b/src/pixeltool/main.cpp
new file mode 100644
index 000000000..202abd513
--- /dev/null
+++ b/src/pixeltool/main.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpixeltool.h"
+
+#include <qapplication.h>
+#include <qfileinfo.h>
+
+QT_USE_NAMESPACE
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QPixelTool pt;
+
+ if (app.arguments().size() > 1 && QFileInfo(app.arguments().at(1)).exists()) {
+ pt.setPreviewImage(QImage(app.arguments().at(1)));
+ }
+
+ pt.show();
+
+ QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
+
+ int ret = app.exec();
+ return ret;
+}
diff --git a/src/pixeltool/pixeltool.pro b/src/pixeltool/pixeltool.pro
new file mode 100644
index 000000000..c24e6edc7
--- /dev/null
+++ b/src/pixeltool/pixeltool.pro
@@ -0,0 +1,25 @@
+TEMPLATE = app
+CONFIG += qt warn_on
+QT += network
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+DESTDIR = ../../bin
+
+DEPENDPATH += .
+INCLUDEPATH += .
+TARGET = pixeltool
+
+mac {
+ QMAKE_INFO_PLIST=Info_mac.plist
+}
+
+# Input
+SOURCES += main.cpp qpixeltool.cpp
+HEADERS += qpixeltool.h
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/pixeltool/qpixeltool.cpp b/src/pixeltool/qpixeltool.cpp
new file mode 100644
index 000000000..d01d687a8
--- /dev/null
+++ b/src/pixeltool/qpixeltool.cpp
@@ -0,0 +1,536 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpixeltool.h"
+
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qapplication.h>
+#include <qclipboard.h>
+#include <qpainter.h>
+#include <qevent.h>
+#include <qfiledialog.h>
+#include <qsettings.h>
+#include <qmenu.h>
+#include <qactiongroup.h>
+
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+QPixelTool::QPixelTool(QWidget *parent)
+ : QWidget(parent)
+{
+ setWindowTitle(QLatin1String("PixelTool"));
+ QSettings settings(QLatin1String("Trolltech"), QLatin1String("QPixelTool"));
+
+ m_freeze = false;
+
+ m_autoUpdate = settings.value(QLatin1String("autoUpdate"), 0).toBool();
+
+ m_gridSize = settings.value(QLatin1String("gridSize"), 1).toInt();
+ m_gridActive = settings.value(QLatin1String("gridActive"), 1).toInt();
+ m_displayGridSize = false;
+ m_displayGridSizeId = 0;
+
+ m_zoom = settings.value(QLatin1String("zoom"), 4).toInt();
+
+ m_displayZoom = false;
+ m_displayZoomId = 0;
+
+ m_preview_mode = false;
+
+ m_currentColor = 0;
+
+ m_mouseDown = false;
+
+ m_initialSize = settings.value(QLatin1String("initialSize"), QSize(250, 200)).toSize();
+
+ move(settings.value(QLatin1String("position")).toPoint());
+
+ setMouseTracking(true);
+ setAttribute(Qt::WA_NoBackground);
+ m_updateId = startTimer(30);
+}
+
+QPixelTool::~QPixelTool()
+{
+ QSettings settings(QLatin1String("Trolltech"), QLatin1String("QPixelTool"));
+ settings.setValue(QLatin1String("autoUpdate"), int(m_autoUpdate));
+ settings.setValue(QLatin1String("gridSize"), m_gridSize);
+ settings.setValue(QLatin1String("gridActive"), m_gridActive);
+ settings.setValue(QLatin1String("zoom"), m_zoom);
+ settings.setValue(QLatin1String("initialSize"), size());
+ settings.setValue(QLatin1String("position"), pos());
+}
+
+void QPixelTool::setPreviewImage(const QImage &image)
+{
+ m_preview_mode = true;
+ m_preview_image = image;
+ m_freeze = true;
+}
+
+void QPixelTool::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_updateId && !m_freeze) {
+ grabScreen();
+ } else if (event->timerId() == m_displayZoomId) {
+ killTimer(m_displayZoomId);
+ setZoomVisible(false);
+ } else if (event->timerId() == m_displayGridSizeId) {
+ killTimer(m_displayGridSizeId);
+ m_displayGridSize = false;
+ }
+}
+
+void render_string(QPainter *p, int w, int h, const QString &text, int flags)
+{
+ p->setBrush(QColor(255, 255, 255, 191));
+ p->setPen(Qt::black);
+ QRect bounds;
+ p->drawText(0, 0, w, h, Qt::TextDontPrint | flags, text, &bounds);
+
+ if (bounds.x() == 0) bounds.adjust(0, 0, 10, 0);
+ else bounds.adjust(-10, 0, 0, 0);
+
+ if (bounds.y() == 0) bounds.adjust(0, 0, 0, 10);
+ else bounds.adjust(0, -10, 0, 0);
+
+ p->drawRect(bounds);
+ p->drawText(bounds, flags, text);
+}
+
+void QPixelTool::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+
+ if (m_preview_mode) {
+ QPixmap pixmap(40, 40);
+ QPainter pt(&pixmap);
+ pt.fillRect(0, 0, 20, 20, Qt::white);
+ pt.fillRect(20, 20, 20, 20, Qt::white);
+ pt.fillRect(20, 0, 20, 20, Qt::lightGray);
+ pt.fillRect(0, 20, 20, 20, Qt::lightGray);
+ pt.end();
+ p.fillRect(0, 0, width(), height(), pixmap);
+ }
+
+ int w = width();
+ int h = height();
+
+ p.save();
+ p.scale(m_zoom, m_zoom);
+ p.drawPixmap(0, 0, m_buffer);
+ p.scale(1/m_zoom, 1/m_zoom);
+ p.restore();
+
+ // Draw the grid on top.
+ if (m_gridActive) {
+ p.setPen(m_gridActive == 1 ? Qt::black : Qt::white);
+ int incr = m_gridSize * m_zoom;
+ for (int x=0; x<w; x+=incr)
+ p.drawLine(x, 0, x, h);
+ for (int y=0; y<h; y+=incr)
+ p.drawLine(0, y, w, y);
+ }
+
+ QFont f(QLatin1String("courier"));
+ f.setBold(true);
+ p.setFont(f);
+
+ if (m_displayZoom) {
+ render_string(&p, w, h,
+ QString::fromLatin1("Zoom: x%1").arg(m_zoom),
+ Qt::AlignTop | Qt::AlignRight);
+ }
+
+ if (m_displayGridSize) {
+ render_string(&p, w, h,
+ QString::fromLatin1("Grid size: %1").arg(m_gridSize),
+ Qt::AlignBottom | Qt::AlignLeft);
+ }
+
+ if (m_freeze) {
+ QString str;
+ str.sprintf("%8X (%3d,%3d,%3d,%3d)",
+ m_currentColor,
+ (0xff000000 & m_currentColor) >> 24,
+ (0x00ff0000 & m_currentColor) >> 16,
+ (0x0000ff00 & m_currentColor) >> 8,
+ (0x000000ff & m_currentColor));
+ render_string(&p, w, h,
+ str,
+ Qt::AlignBottom | Qt::AlignRight);
+ }
+
+ if (m_mouseDown && m_dragStart != m_dragCurrent) {
+ int x1 = (m_dragStart.x() / m_zoom) * m_zoom;
+ int y1 = (m_dragStart.y() / m_zoom) * m_zoom;
+ int x2 = (m_dragCurrent.x() / m_zoom) * m_zoom;
+ int y2 = (m_dragCurrent.y() / m_zoom) * m_zoom;
+ QRect r = QRect(x1, y1, x2 - x1, y2 - y1).normalized();
+ p.setBrush(Qt::NoBrush);
+ p.setPen(QPen(Qt::red, 3, Qt::SolidLine));
+ p.drawRect(r);
+ p.setPen(QPen(Qt::black, 1, Qt::SolidLine));
+ p.drawRect(r);
+
+ QString str;
+ str.sprintf("Rect: x=%d, y=%d, w=%d, h=%d",
+ r.x() / m_zoom,
+ r.y() / m_zoom,
+ r.width() / m_zoom,
+ r.height() / m_zoom);
+ render_string(&p, w, h, str, Qt::AlignBottom | Qt::AlignLeft);
+ }
+
+
+}
+
+void QPixelTool::keyPressEvent(QKeyEvent *e)
+{
+ switch (e->key()) {
+ case Qt::Key_Space:
+ toggleFreeze();
+ break;
+ case Qt::Key_Plus:
+ setZoom(m_zoom + 1);
+ break;
+ case Qt::Key_Minus:
+ setZoom(m_zoom - 1);
+ break;
+ case Qt::Key_PageUp:
+ setGridSize(m_gridSize + 1);
+ break;
+ case Qt::Key_PageDown:
+ setGridSize(m_gridSize - 1);
+ break;
+ case Qt::Key_G:
+ toggleGrid();
+ break;
+ case Qt::Key_A:
+ m_autoUpdate = !m_autoUpdate;
+ break;
+ case Qt::Key_C:
+ if (e->modifiers() & Qt::ControlModifier)
+ copyToClipboard();
+ break;
+ case Qt::Key_S:
+ if (e->modifiers() & Qt::ControlModifier) {
+ releaseKeyboard();
+ saveToFile();
+ }
+ break;
+ case Qt::Key_Control:
+ grabKeyboard();
+ break;
+ }
+}
+
+void QPixelTool::keyReleaseEvent(QKeyEvent *e)
+{
+ switch(e->key()) {
+ case Qt::Key_Control:
+ releaseKeyboard();
+ break;
+ default:
+ break;
+ }
+}
+
+void QPixelTool::resizeEvent(QResizeEvent *)
+{
+ grabScreen();
+}
+
+void QPixelTool::mouseMoveEvent(QMouseEvent *e)
+{
+ if (m_mouseDown)
+ m_dragCurrent = e->pos();
+
+ int x = e->x() / m_zoom;
+ int y = e->y() / m_zoom;
+
+ QImage im = m_buffer.toImage().convertToFormat(QImage::Format_ARGB32);
+ if (x < im.width() && y < im.height() && x >= 0 && y >= 0) {
+ m_currentColor = im.pixel(x, y);
+ update();
+ }
+}
+
+void QPixelTool::mousePressEvent(QMouseEvent *e)
+{
+ if (!m_freeze)
+ return;
+ m_mouseDown = true;
+ m_dragStart = e->pos();
+}
+
+void QPixelTool::mouseReleaseEvent(QMouseEvent *)
+{
+ m_mouseDown = false;
+}
+
+void QPixelTool::contextMenuEvent(QContextMenuEvent *e)
+{
+ bool tmpFreeze = m_freeze;
+ m_freeze = true;
+
+ QMenu menu;
+
+ QAction title(QLatin1String("Qt Pixel Zooming Tool"), &menu);
+ title.setEnabled(false);
+
+ // Grid color options...
+ QActionGroup gridGroup(this);
+ QAction whiteGrid(QLatin1String("White grid"), &gridGroup);
+ whiteGrid.setCheckable(true);
+ whiteGrid.setChecked(m_gridActive == 2);
+ whiteGrid.setShortcut(QKeySequence(Qt::Key_G));
+ QAction blackGrid(QLatin1String("Black grid"), &gridGroup);
+ blackGrid.setCheckable(true);
+ blackGrid.setChecked(m_gridActive == 1);
+ blackGrid.setShortcut(QKeySequence(Qt::Key_G));
+ QAction noGrid(QLatin1String("No grid"), &gridGroup);
+ noGrid.setCheckable(true);
+ noGrid.setChecked(m_gridActive == 0);
+ noGrid.setShortcut(QKeySequence(Qt::Key_G));
+
+ // Grid size options
+ QAction incrGrid(QLatin1String("Increase grid size"), &menu);
+ incrGrid.setShortcut(QKeySequence(Qt::Key_PageUp));
+ connect(&incrGrid, SIGNAL(triggered()), this, SLOT(increaseGridSize()));
+ QAction decrGrid(QLatin1String("Decrease grid size"), &menu);
+ decrGrid.setShortcut(QKeySequence(Qt::Key_PageDown));
+ connect(&decrGrid, SIGNAL(triggered()), this, SLOT(decreaseGridSize()));
+
+ // Zoom options
+ QAction incrZoom(QLatin1String("Zoom in"), &menu);
+ incrZoom.setShortcut(QKeySequence(Qt::Key_Plus));
+ connect(&incrZoom, SIGNAL(triggered()), this, SLOT(increaseZoom()));
+ QAction decrZoom(QLatin1String("Zoom out"), &menu);
+ decrZoom.setShortcut(QKeySequence(Qt::Key_Minus));
+ connect(&decrZoom, SIGNAL(triggered()), this, SLOT(decreaseZoom()));
+
+ // Freeze / Autoupdate
+ QAction freeze(QLatin1String("Frozen"), &menu);
+ freeze.setCheckable(true);
+ freeze.setChecked(tmpFreeze);
+ freeze.setShortcut(QKeySequence(Qt::Key_Space));
+ QAction autoUpdate(QLatin1String("Continuous update"), &menu);
+ autoUpdate.setCheckable(true);
+ autoUpdate.setChecked(m_autoUpdate);
+ autoUpdate.setShortcut(QKeySequence(Qt::Key_A));
+
+ // Copy to clipboard / save
+ QAction save(QLatin1String("Save as image"), &menu);
+ save.setShortcut(QKeySequence(QLatin1String("Ctrl+S")));
+ connect(&save, SIGNAL(triggered()), this, SLOT(saveToFile()));
+ QAction copy(QLatin1String("Copy to clipboard"), &menu);
+ copy.setShortcut(QKeySequence(QLatin1String("Ctrl+C")));
+ connect(&copy, SIGNAL(triggered()), this, SLOT(copyToClipboard()));
+
+ menu.addAction(&title);
+ menu.addSeparator();
+ menu.addAction(&whiteGrid);
+ menu.addAction(&blackGrid);
+ menu.addAction(&noGrid);
+ menu.addSeparator();
+ menu.addAction(&incrGrid);
+ menu.addAction(&decrGrid);
+ menu.addSeparator();
+ menu.addAction(&incrZoom);
+ menu.addAction(&decrZoom);
+ menu.addSeparator();
+ menu.addAction(&freeze);
+ menu.addAction(&autoUpdate);
+ menu.addSeparator();
+ menu.addAction(&save);
+ menu.addAction(&copy);
+
+ menu.exec(mapToGlobal(e->pos()));
+
+ // Read out grid settings
+ if (noGrid.isChecked()) m_gridActive = 0;
+ else if (blackGrid.isChecked()) m_gridActive = 1;
+ else m_gridActive = 2;
+
+ m_autoUpdate = autoUpdate.isChecked();
+ tmpFreeze = freeze.isChecked();
+
+
+ m_freeze = tmpFreeze;
+}
+
+QSize QPixelTool::sizeHint() const
+{
+ return m_initialSize;
+}
+
+void QPixelTool::grabScreen()
+{
+ if (m_preview_mode) {
+ int w = qMin(width() / m_zoom + 1, m_preview_image.width());
+ int h = qMin(height() / m_zoom + 1, m_preview_image.height());
+ m_buffer = QPixmap::fromImage(m_preview_image).copy(0, 0, w, h);
+ update();
+ return;
+ }
+
+ QPoint mousePos = QCursor::pos();
+ if (mousePos == m_lastMousePos && !m_autoUpdate)
+ return;
+
+ int w = int(width() / float(m_zoom));
+ int h = int(height() / float(m_zoom));
+
+ if (width() % m_zoom > 0)
+ ++w;
+ if (height() % m_zoom > 0)
+ ++h;
+
+ int x = mousePos.x() - w/2;
+ int y = mousePos.y() - h/2;
+
+ m_buffer = QPixmap::grabWindow(qApp->desktop()->winId(), x, y, w, h);
+
+ QRegion geom(x, y, w, h);
+ QRect screenRect;
+ for (int i=0; i<qApp->desktop()->numScreens(); ++i)
+ screenRect |= qApp->desktop()->screenGeometry(i);
+ geom -= screenRect;
+ QVector<QRect> rects = geom.rects();
+ if (rects.size() > 0) {
+ QPainter p(&m_buffer);
+ p.translate(-x, -y);
+ p.setPen(Qt::NoPen);
+ p.setBrush(palette().color(QPalette::Dark));
+ p.drawRects(rects);
+ }
+
+ update();
+
+ m_lastMousePos = mousePos;
+}
+
+void QPixelTool::startZoomVisibleTimer()
+{
+ if (m_displayZoomId > 0) {
+ killTimer(m_displayZoomId);
+ }
+ m_displayZoomId = startTimer(5000);
+ setZoomVisible(true);
+}
+
+void QPixelTool::startGridSizeVisibleTimer()
+{
+ if (m_gridActive) {
+ if (m_displayGridSizeId > 0)
+ killTimer(m_displayGridSizeId);
+ m_displayGridSizeId = startTimer(5000);
+ m_displayGridSize = true;
+ update();
+ }
+}
+
+void QPixelTool::setZoomVisible(bool visible)
+{
+ m_displayZoom = visible;
+ update();
+}
+
+void QPixelTool::toggleFreeze()
+{
+ m_freeze = !m_freeze;
+ if (!m_freeze)
+ m_dragStart = m_dragCurrent = QPoint();
+}
+
+void QPixelTool::setZoom(int zoom)
+{
+ if (zoom > 0) {
+ QPoint pos = m_lastMousePos;
+ m_lastMousePos = QPoint();
+ m_zoom = zoom;
+ grabScreen();
+ m_lastMousePos = pos;
+ m_dragStart = m_dragCurrent = QPoint();
+ startZoomVisibleTimer();
+ }
+}
+
+void QPixelTool::toggleGrid()
+{
+ if (++m_gridActive > 2)
+ m_gridActive = 0;
+ update();
+}
+
+void QPixelTool::setGridSize(int gridSize)
+{
+ if (m_gridActive && gridSize > 0) {
+ m_gridSize = gridSize;
+ startGridSizeVisibleTimer();
+ update();
+ }
+}
+
+void QPixelTool::copyToClipboard()
+{
+ QClipboard *cb = QApplication::clipboard();
+ cb->setPixmap(m_buffer);
+}
+
+void QPixelTool::saveToFile()
+{
+ bool oldFreeze = m_freeze;
+ m_freeze = true;
+ QString name = QFileDialog::getSaveFileName(this, QLatin1String("Save as image"), QString(), QLatin1String("*.png"));
+ if (!name.isEmpty()) {
+ if (!name.endsWith(QLatin1String(".png")))
+ name.append(QLatin1String(".png"));
+ m_buffer.save(name, "PNG");
+ }
+ m_freeze = oldFreeze;
+}
+
+QT_END_NAMESPACE
diff --git a/src/pixeltool/qpixeltool.h b/src/pixeltool/qpixeltool.h
new file mode 100644
index 000000000..7256f21d4
--- /dev/null
+++ b/src/pixeltool/qpixeltool.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPIXELTOOL_H
+#define QPIXELTOOL_H
+
+#include <qwidget.h>
+#include <qpixmap.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPixelTool : public QWidget
+{
+ Q_OBJECT
+public:
+ QPixelTool(QWidget *parent = 0);
+ ~QPixelTool();
+
+ void timerEvent(QTimerEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void contextMenuEvent(QContextMenuEvent *event);
+
+ QSize sizeHint() const;
+
+ void setPreviewImage(const QImage &image);
+
+public slots:
+ void setZoom(int zoom);
+ void setGridSize(int gridSize);
+ void toggleGrid();
+ void toggleFreeze();
+ void setZoomVisible(bool visible);
+ void copyToClipboard();
+ void saveToFile();
+ void increaseGridSize() { setGridSize(m_gridSize + 1); }
+ void decreaseGridSize() { setGridSize(m_gridSize - 1); }
+ void increaseZoom() { setZoom(m_zoom + 1); }
+ void decreaseZoom() { setZoom(m_zoom - 1); }
+
+private:
+ void grabScreen();
+ void startZoomVisibleTimer();
+ void startGridSizeVisibleTimer();
+
+ bool m_freeze;
+ bool m_displayZoom;
+ bool m_displayGridSize;
+ bool m_mouseDown;
+ bool m_autoUpdate;
+ bool m_preview_mode;
+
+ int m_gridActive;
+ int m_zoom;
+ int m_gridSize;
+
+ int m_updateId;
+ int m_displayZoomId;
+ int m_displayGridSizeId;
+
+ int m_currentColor;
+
+ QPoint m_lastMousePos;
+ QPoint m_dragStart;
+ QPoint m_dragCurrent;
+ QPixmap m_buffer;
+
+ QSize m_initialSize;
+
+ QImage m_preview_image;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPIXELTOOL_H
diff --git a/src/qconfig/feature.cpp b/src/qconfig/feature.cpp
new file mode 100644
index 000000000..358dec517
--- /dev/null
+++ b/src/qconfig/feature.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "feature.h"
+#include <QTextStream>
+#include <QRegExp>
+#include <QLibraryInfo>
+#include <QFileInfo>
+#include <QApplication>
+#include <QPalette>
+
+QT_BEGIN_NAMESPACE
+
+QMap<QString, Feature*> Feature::instances;
+
+Feature* Feature::getInstance(const QString &key)
+{
+ QString ukey = key.toUpper();
+ if (!instances.contains(ukey))
+ instances[ukey] = new Feature(ukey);
+ return instances[ukey];
+}
+
+Feature::~Feature()
+{
+ delete d;
+}
+
+void Feature::clear()
+{
+ foreach (Feature *f, instances.values())
+ delete f;
+ instances.clear();
+}
+
+static QString listToHtml(const QString &title, const QStringList &list)
+{
+ if (list.isEmpty())
+ return QString();
+
+ QString str;
+ QTextStream stream(&str);
+
+ stream << "<h3>" << title << ":</h3>";
+ stream << "<ul>";
+ foreach (QString l, list)
+ stream << "<li>" << l << "</li>";
+ stream << "</ul>";
+
+ return str;
+}
+
+static QString listToHtml(const QString &title, const QList<Feature*> &list)
+{
+ QStringList stringlist;
+ foreach (Feature *f, list) {
+ QString s("[%3] <a href=\"feature://%1\">%2</a>");
+ s = s.arg(f->key()).arg(f->key());
+ s = s.arg(f->selectable() && f->enabled() ? "On" : "Off");
+ stringlist << s;
+ }
+ return listToHtml(title, stringlist);
+}
+
+static QString linkify(const QString &src)
+{
+ static QRegExp classRegexp("\\b(Q[\\w]+)");
+ QString docRoot = QLibraryInfo::location(QLibraryInfo::DocumentationPath);
+ QString result = src;
+ int pos = 0;
+ while ((pos = classRegexp.indexIn(result, pos)) != -1) {
+ QString className = classRegexp.cap(1);
+ QString file = docRoot + "/html/" + className.toLower() + ".html";
+ QFileInfo info(file);
+ if (info.isFile()) {
+ QString link = QString("<a href=\"file://%1\">%2</a>")
+ .arg(file).arg(className);
+ result.replace(pos, className.length(), link);
+ pos += link.length();
+ } else {
+ pos += className.length();
+ }
+ }
+
+ return result;
+}
+
+QString Feature::toHtml() const
+{
+ QString str;
+ QTextStream stream(&str);
+
+ const QString linkColor = QApplication::palette().color(QPalette::Link).name();
+ stream << "<h2><font size=\"+2\" color=\"" << linkColor << "\">"
+ << key() << "</font></h2>"
+ << "<h2><font size=\"+2\">" << title() << "</font></h2>";
+ if (!description().isEmpty())
+ stream << "<p>" << description() << "</p>";
+ stream << listToHtml("Section", QStringList(section()))
+ << listToHtml("Requires", dependencies())
+ << listToHtml("Required for", supports())
+ << listToHtml("See also", relations());
+
+ return linkify(str);
+}
+
+Feature::Feature(const QString &key) : d(new FeaturePrivate(key)) {}
+
+void Feature::setTitle(const QString &title)
+{
+ d->title = title;
+}
+
+void Feature::setSection(const QString &section)
+{
+ d->section = section;
+}
+
+void Feature::setDescription(const QString &description)
+{
+ d->description = description;
+}
+
+void Feature::addRelation(const QString &key)
+{
+ d->relations.insert(getInstance(key));
+}
+
+void Feature::setRelations(const QStringList &keys)
+{
+ foreach(QString key, keys)
+ if (key != "???")
+ addRelation(key);
+}
+
+QList<Feature*> Feature::relations() const
+{
+ return d->relations.toList();
+}
+
+void Feature::addDependency(const QString &key)
+{
+ Feature *f = getInstance(key);
+ d->dependencies.insert(f);
+ f->d->supports.insert(this);
+}
+
+void Feature::setDependencies(const QStringList &keys)
+{
+ foreach(QString key, keys)
+ addDependency(key);
+}
+
+QList<Feature*> Feature::dependencies() const
+{
+ return d->dependencies.toList();
+}
+
+QList<Feature*> Feature::supports() const
+{
+ return d->supports.toList();
+}
+
+/*
+ Returns a html formatted detailed description of this Feature.
+*/
+QString Feature::getDocumentation() const
+{
+ return QString() + "<h2>" + d->title + "</h2>";
+
+}
+
+void Feature::setEnabled(bool on)
+{
+ if (on == d->enabled)
+ return;
+
+ d->enabled = on;
+ foreach (Feature *f, supports())
+ f->updateSelectable();
+ emit changed();
+}
+
+/*
+ Update whether this feature should be selectable.
+ A feature is selectable if all its dependencies are enabled.
+*/
+void Feature::updateSelectable()
+{
+ bool selectable = true;
+ foreach (Feature *f, dependencies())
+ if (!f->selectable() || !f->enabled())
+ selectable = false;
+ if (selectable != d->selectable) {
+ d->selectable = selectable;
+ foreach (Feature *f, supports())
+ f->updateSelectable();
+ emit changed();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/qconfig/feature.h b/src/qconfig/feature.h
new file mode 100644
index 000000000..b15b1c166
--- /dev/null
+++ b/src/qconfig/feature.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FEATURE_H
+#define FEATURE_H
+
+#include <QString>
+#include <QStringList>
+#include <QMap>
+#include <QSet>
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+
+class Feature;
+
+class FeaturePrivate
+{
+public:
+ FeaturePrivate(const QString &k)
+ : key(k), enabled(true), selectable(true) {};
+
+ const QString key;
+ QString section;
+ QString title;
+ QString description;
+ QSet<Feature*> dependencies;
+ QSet<Feature*> supports; // features who depends on this one
+ QSet<Feature*> relations;
+ bool enabled;
+ bool selectable;
+};
+
+class Feature : public QObject
+{
+ Q_OBJECT
+
+public:
+ static Feature* getInstance(const QString &key);
+ static void clear();
+
+public:
+ QString key() const { return d->key; }
+
+ void setTitle(const QString &title);
+ QString title() const { return d->title; }
+
+ void setSection(const QString &section);
+ QString section() const { return d->section; }
+
+ void setDescription(const QString &description);
+ QString description() const { return d->description; };
+
+ void addRelation(const QString &key);
+ void setRelations(const QStringList &keys);
+ QList<Feature*> relations() const;
+
+ void addDependency(const QString &dependency);
+ void setDependencies(const QStringList &dependencies);
+ QList<Feature*> dependencies() const;
+
+ QList<Feature*> supports() const;
+ QString getDocumentation() const;
+
+ void setEnabled(bool on);
+ bool enabled() const { return d->enabled; };
+
+ bool selectable() const { return d->selectable; }
+
+ QString toHtml() const;
+
+ ~Feature();
+
+signals:
+ void changed();
+
+private:
+ Feature(const QString &key);
+ void updateSelectable();
+
+ static QMap<QString, Feature*> instances;
+ FeaturePrivate *d;
+};
+
+QT_END_NAMESPACE
+
+#endif // FEATURE_H
diff --git a/src/qconfig/featuretreemodel.cpp b/src/qconfig/featuretreemodel.cpp
new file mode 100644
index 000000000..b67e1b540
--- /dev/null
+++ b/src/qconfig/featuretreemodel.cpp
@@ -0,0 +1,451 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "featuretreemodel.h"
+#include "feature.h"
+#include <QPalette>
+#include <QColor>
+#include <QApplication>
+#include <QtDebug>
+
+QT_BEGIN_NAMESPACE
+
+class Node
+{
+public:
+ Node(Feature *f, Node *p = 0) : feature(f), parent(p) {}
+ ~Node();
+ Node* find(const Feature *child) const;
+ bool contains(const Feature *child) const { return find(child) != 0; }
+ bool insert(Node *n);
+
+ Feature *feature;
+ Node *parent;
+ QList<Node*> children; // maybe convert to Map to get keys sorted
+};
+
+Node::~Node()
+{
+ while (!children.isEmpty())
+ delete children.takeFirst();
+}
+
+Node* Node::find(const Feature *f) const
+{
+ if (this->feature == f)
+ return const_cast<Node*>(this);
+
+ foreach (Node *n, children)
+ if (Node *m = n->find(f))
+ return m;
+
+ return 0;
+}
+
+static bool nodePtrLessThan(const Node *n1, const Node *n2)
+{
+ return (n1->feature->key() < n2->feature->key());
+}
+
+/*
+ Try insert \a n into the tree with this node as root.
+ n is inserted as a child if it has a dependency to this node.
+ Returns true if child is inserted into the tree, false otherwise.
+*/
+bool Node::insert(Node *n)
+{
+ Feature *f = const_cast<Feature*>(n->feature);
+ if (feature->supports().contains(f)) {
+ children.append(n);
+ qSort(children.begin(), children.end(), nodePtrLessThan);
+ n->parent = this;
+ return true;
+ }
+ foreach (Node *child, children)
+ if (child->insert(n))
+ return true;
+ return false;
+}
+
+static bool isSection(const QModelIndex &index)
+{
+ return index.isValid() && (index.internalId() == 0);
+}
+
+FeatureTreeModel::FeatureTreeModel(QObject *parent)
+ : QAbstractItemModel(parent)
+{
+}
+
+FeatureTreeModel::~FeatureTreeModel()
+{
+ foreach (QString section, sections.keys())
+ while (!sections[section].isEmpty())
+ delete sections[section].takeFirst();
+}
+
+/*
+ Returns true if the model already contains \a in \a section, false otherwise.
+*/
+bool FeatureTreeModel::contains(const QString &section, const Feature *f) const
+{
+ return (find(section, f) != 0);
+}
+
+Node* FeatureTreeModel::find(const QString &section, const Feature *f) const
+{
+ QList<Node*> roots = sections[section];
+ foreach (Node *root, roots)
+ if (Node *n = root->find(f))
+ return n;
+ return 0;
+}
+
+/*
+ Add new \a feature to the tree.
+ When all feature is added, buildTree() must be called to build the
+ dependency tree.
+*/
+void FeatureTreeModel::addFeature(Feature *feature)
+{
+ const QString section = feature->section();
+ Q_ASSERT(!contains(section, feature));
+
+ connect(feature, SIGNAL(changed()), this, SLOT(featureChanged()));
+
+ Node *node = new Node(feature, 0);
+
+ // try insert any toplevel nodes as child of this one
+ foreach (Node *n, sections[section])
+ if (node->insert(n))
+ sections[section].removeAll(n);
+
+ // try insert this node as a child of any existing node
+ foreach (Node *n, sections[section])
+ if (n->insert(node)) {
+ emit layoutChanged();
+ return;
+ }
+
+ // not a child, insert as a toplevel node
+ sections[section].append(node);
+ qSort(sections[section].begin(), sections[section].end(), nodePtrLessThan);
+ emit layoutChanged();
+}
+
+QModelIndex FeatureTreeModel::createIndex(int row, int column,
+ const QModelIndex &parent,
+ const Node *node) const
+{
+ QModelIndex index = QAbstractItemModel::createIndex(row, column,
+ (void*)node);
+ if (parent.isValid())
+ parentMap[index] = parent;
+ if (node)
+ featureIndexMap[node->feature] = index;
+ return index;
+}
+
+QModelIndex FeatureTreeModel::index(int row, int column,
+ const QModelIndex &parent) const
+{
+ if (!parent.isValid()) { // index is a section
+ if (row < sections.size() && column == 0)
+ return QAbstractItemModel::createIndex(row, column, 0);
+ return QModelIndex();
+ }
+
+ if (isSection(parent)) { // index is a toplevel feature
+ const int parentRow = parent.row();
+ if (parentRow < sections.size()) {
+ QString section = sections.keys().at(parentRow);
+ QList<Node*> nodes = sections[section];
+ if (row < nodes.size() && column < 2)
+ return createIndex(row, column, parent, nodes.at(row));
+ }
+ return QModelIndex();
+ }
+
+ // parent is a feature
+ Node *parentNode = static_cast<Node*>(parent.internalPointer());
+ QList<Node*> children = parentNode->children;
+ if (row < children.size() && column < 2)
+ return createIndex(row, column, parent, children.at(row));
+
+ return QModelIndex();
+}
+
+QModelIndex FeatureTreeModel::index(const QModelIndex &parent,
+ const Feature *feature) const
+{
+ const int rows = rowCount(parent);
+ for (int i = 0; i < rows; ++i) {
+ QModelIndex child = index(i, 0, parent);
+ Node *node = static_cast<Node*>(child.internalPointer());
+ if (node && node->feature == feature)
+ return child;
+ QModelIndex childSearch = index(child, feature);
+ if (childSearch.isValid())
+ return childSearch;
+ }
+ return QModelIndex();
+}
+
+QModelIndex FeatureTreeModel::index(const Feature *feature) const
+{
+ if (featureIndexMap.contains(feature))
+ return featureIndexMap.value(feature);
+
+ // exhaustive search
+ int sectionRow = sections.keys().indexOf(feature->section());
+ QModelIndex sectionIndex = index(sectionRow, 0, QModelIndex());
+
+ return index(sectionIndex, feature);
+}
+
+QModelIndex FeatureTreeModel::parent(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ if (parentMap.contains(index))
+ return parentMap.value(index);
+ return QModelIndex();
+}
+
+int FeatureTreeModel::rowCount(const QModelIndex &parent) const
+{
+ if (!parent.isValid())
+ return sections.size();
+
+ if (isSection(parent)) {
+ const QString section = sections.keys().at(parent.row());
+ return sections[section].size();
+ }
+
+ const Node *node = static_cast<Node*>(parent.internalPointer());
+ return node->children.size();
+}
+
+int FeatureTreeModel::columnCount(const QModelIndex &parent) const
+{
+#if 0
+ if (!parent.isValid())
+ return 0;
+
+ if (isSection(parent))
+ return 1;
+#endif
+ Q_UNUSED(parent);
+ return 2; // Feature: [key, name]
+}
+
+QVariant FeatureTreeModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ const Node *node = static_cast<Node*>(index.internalPointer());
+
+ switch (role) {
+ case Qt::DisplayRole: {
+ if (node == 0) // index is a section
+ return sections.keys().at(index.row());
+ if (index.column() == 0)
+ return node->feature->key();
+ Q_ASSERT(index.column() == 1);
+ return node->feature->title();
+ }
+ case Qt::CheckStateRole: {
+ if (node && index.column() == 0)
+ return (node->feature->enabled() ?
+ Qt::Checked : Qt::Unchecked);
+ break;
+ }
+ case Qt::TextColorRole: {
+ if (node && index.column() == 0) // feature key
+ if (node->feature->selectable())
+ return QApplication::palette().color(QPalette::Link);
+ break;
+ }
+ case Qt::TextAlignmentRole:
+ case Qt::BackgroundColorRole:
+ case Qt::FontRole:
+ case Qt::ToolTipRole: // TODO
+ case Qt::StatusTipRole: // TODO
+ case Qt::WhatsThisRole: // TODO
+ case Qt::DecorationRole:
+ case Qt::EditRole:
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+bool FeatureTreeModel::setData(const QModelIndex &index,
+ const QVariant &value, int role)
+{
+ if (!index.isValid())
+ return false;
+
+ Node *node = static_cast<Node*>(index.internalPointer());
+ if (!node)
+ return false;
+
+ if (role == Qt::CheckStateRole) {
+ Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
+ if (state == Qt::Checked)
+ node->feature->setEnabled(true);
+ else if (state == Qt::Unchecked)
+ node->feature->setEnabled(false);
+ emit dataChanged(index, index);
+ return true;
+ }
+ return false;
+}
+
+Qt::ItemFlags FeatureTreeModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid() || index.internalPointer() == 0)
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+
+ const Node *node = static_cast<Node*>(index.internalPointer());
+ const Feature *feature = node->feature;
+ Qt::ItemFlags flags = Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
+
+ if (feature->selectable())
+ flags |= Qt::ItemIsEnabled;
+
+ return flags;
+}
+
+QVariant FeatureTreeModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+ if (section == 0)
+ return QString("Id");
+ else if (section == 1)
+ return QString("Name");
+ }
+
+ return QVariant();
+}
+
+Feature* FeatureTreeModel::getFeature(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+ if (isSection(index))
+ return 0;
+ Node *node = static_cast<Node*>(index.internalPointer());
+ return const_cast<Feature*>(node->feature);
+}
+
+void FeatureTreeModel::featureChanged()
+{
+ Feature *feature = qobject_cast<Feature*>(sender());
+ if (feature) {
+ QModelIndex featureIndex = index(feature);
+ emit dataChanged(featureIndex, featureIndex);
+ } else {
+ emit layoutChanged();
+ }
+}
+
+void FeatureTreeModel::readConfig(QTextStream &stream)
+{
+ static QRegExp regexp("\\s*#\\s*define\\s+QT_NO_(\\S+)\\s*");
+
+ while (!stream.atEnd()) {
+ QString line = stream.readLine();
+ if (regexp.exactMatch(line)) {
+ Feature *f = Feature::getInstance(regexp.cap(1));
+ f->setEnabled(false);
+ }
+ }
+}
+/*
+ Search for all disabled child features of \a parent.
+ Returns a list of feature keys for the disabled items.
+*/
+QStringList FeatureTreeModel::findDisabled(const QModelIndex &parent) const
+{
+ QStringList stringList;
+
+ const int rows = rowCount(parent);
+ for (int i = 0; i < rows; ++i) {
+ QModelIndex child = index(i, 0, parent);
+ Node *node = static_cast<Node*>(child.internalPointer());
+ if (node && node->feature && !node->feature->enabled())
+ stringList << node->feature->key();
+ stringList << findDisabled(child);
+ }
+ return stringList;
+}
+
+void FeatureTreeModel::writeConfig(QTextStream &stream) const
+{
+ const int sectionCount = rowCount(QModelIndex());
+
+ for (int i = 0; i < sectionCount; ++i) {
+ QModelIndex section = index(i, 0, QModelIndex());
+ QStringList disabled = findDisabled(section);
+ if (disabled.size() > 0) {
+ stream << '\n' << "/* " << sections.keys().at(i) << " */" << '\n';
+ foreach (QString feature, disabled)
+ stream << "#ifndef QT_NO_" << feature << '\n'
+ << "# define QT_NO_" << feature << '\n'
+ << "#endif" << '\n';
+ }
+ }
+}
+
+void FeatureTreeModel::clear()
+{
+ Feature::clear();
+ sections.clear();
+ parentMap.clear();
+ featureIndexMap.clear();
+ emit layoutChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/qconfig/featuretreemodel.h b/src/qconfig/featuretreemodel.h
new file mode 100644
index 000000000..41b8a4bf0
--- /dev/null
+++ b/src/qconfig/featuretreemodel.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FEATURETREEMODEL_H
+#define FEATURETREEMODEL_H
+
+#include <QAbstractItemModel>
+#include <QMap>
+#include <QHash>
+#include <QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+class Feature;
+class Node;
+
+uint qHash(const QModelIndex&);
+
+class FeatureTreeModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ FeatureTreeModel(QObject *parent = 0);
+ ~FeatureTreeModel();
+
+ void clear();
+
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex index(const Feature *feature) const;
+ QModelIndex parent(const QModelIndex &index) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ void addFeature(Feature *feature);
+ Feature* getFeature(const QModelIndex &index) const;
+
+ void readConfig(QTextStream &stream);
+ void writeConfig(QTextStream &stream) const;
+
+public slots:
+ void featureChanged();
+
+private:
+ QModelIndex createIndex(int row, int column,
+ const QModelIndex &parent,
+ const Node *feature) const;
+ QModelIndex index(const QModelIndex &parent, const Feature *feature) const;
+ bool contains(const QString &section, const Feature *f) const;
+ Node* find(const QString &section, const Feature *f) const;
+ QStringList findDisabled(const QModelIndex &parent) const;
+
+ QMap<QString, QList<Node*> > sections;
+ mutable QHash<QModelIndex, QModelIndex> parentMap;
+ mutable QHash<const Feature*, QModelIndex> featureIndexMap;
+};
+
+QT_END_NAMESPACE
+
+#endif // FEATURETREEMODEL_H
diff --git a/src/qconfig/graphics.h b/src/qconfig/graphics.h
new file mode 100644
index 000000000..164d047d1
--- /dev/null
+++ b/src/qconfig/graphics.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+static const char *logo_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"50 50 17 1",
+/* colors */
+" c #000000",
+". c #495808",
+"X c #2A3304",
+"o c #242B04",
+"O c #030401",
+"+ c #9EC011",
+"@ c #93B310",
+"# c #748E0C",
+"$ c #A2C511",
+"% c #8BA90E",
+"& c #99BA10",
+"* c #060701",
+"= c #181D02",
+"- c #212804",
+"; c #61770A",
+": c #0B0D01",
+"/ c None",
+/* pixels */
+"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$@;.o=::=o.;@$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$+#X* **X#+$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$#oO* O **o#+$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$&.* OO O*.&$$$$$$$$$$$$$",
+"$$$$$$$$$$$$@XOO * OO X&$$$$$$$$$$$$",
+"$$$$$$$$$$$@XO OO O **:::OOO OOO X@$$$$$$$$$$$",
+"$$$$$$$$$$&XO O-;#@++@%.oOO X&$$$$$$$$$$",
+"$$$$$$$$$$.O : *-#+$$$$$$$$+#- : O O*.$$$$$$$$$$",
+"$$$$$$$$$#*OO O*.&$$$$$$$$$$$$+.OOOO **#$$$$$$$$$",
+"$$$$$$$$+-OO O *;$$$$$$$$$$$&$$$$;* o+$$$$$$$$",
+"$$$$$$$$#O* O .+$$$$$$$$$$@X;$$$+.O *#$$$$$$$$",
+"$$$$$$$$X* -&$$$$$$$$$$@- :;$$$&- OX$$$$$$$$",
+"$$$$$$$@*O *O#$$$$$$$$$$@oOO**;$$$# O*%$$$$$$$",
+"$$$$$$$; -+$$$$$$$$$@o O OO ;+$$-O *;$$$$$$$",
+"$$$$$$$. ;$$$$$$$$$@-OO OO X&$$;O .$$$$$$$",
+"$$$$$$$o *#$$$$$$$$@o O O O-@$$$#O *o$$$$$$$",
+"$$$$$$+= *@$$$$$$$@o* OO -@$$$$&: =$$$$$$$",
+"$$$$$$+: :+$$$$$$@- *-@$$$$$$: :+$$$$$$",
+"$$$$$$+: :+$$$$$@o* O *-@$$$$$$: :+$$$$$$",
+"$$$$$$$= :@$$$$@o*OOO -@$$$$@: =+$$$$$$",
+"$$$$$$$- O%$$$@o* O O O O-@$$$#* OX$$$$$$$",
+"$$$$$$$. O *O;$$&o O*O* *O -@$$; O.$$$$$$$",
+"$$$$$$$;* Oo+$$;O*O:OO-- Oo@+= *;$$$$$$$",
+"$$$$$$$@* O O#$$$;*OOOo@@-O Oo;O* **@$$$$$$$",
+"$$$$$$$$X* OOO-+$$$;O o@$$@- O O OX$$$$$$$$",
+"$$$$$$$$#* * O.$$$$;X@$$$$@-O O O#$$$$$$$$",
+"$$$$$$$$+oO O OO.+$$+&$$$$$$@-O o+$$$$$$$$",
+"$$$$$$$$$#* **.&$$$$$$$$$$@o OO:#$$$$$$$$$",
+"$$$$$$$$$+. O* O-#+$$$$$$$$+;O OOO:@$$$$$$$$$",
+"$$$$$$$$$$&X *O -;#@++@#;=O O -@$$$$$$$$",
+"$$$$$$$$$$$&X O O*O::::O OO Oo@$$$$$$$",
+"$$$$$$$$$$$$@XOO OO O*X+$$$$$$",
+"$$$$$$$$$$$$$&.* ** O :: *:#$$$$$$$",
+"$$$$$$$$$$$$$$$#o*OO O Oo#@-OOO=#$$$$$$$$",
+"$$$$$$$$$$$$$$$$+#X:* * O**X#+$$@-*:#$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$%;.o=::=o.#@$$$$$$@X#$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$+$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/",
+};
+
+static const char *expanded_xpm[] = {
+"32 32 3 1",
+" c None",
+"# c #000000",
+"a c #0000c0",
+" ## ",
+" ## ",
+" #############aaaaaaaaaaaaa ",
+" ## # ",
+" ## # ",
+" ## # ",
+" ## # ",
+" ## # ",
+" ## # ",
+" ## #aaaaaaaaaaaaa ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" #############aaaaaaaaaaaaa ",
+" ## # ",
+" ## # ",
+" ## # ",
+" ## # ",
+" ## # ",
+" ## #aaaaaaaaaaaaa ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" #############aaaaaaaaaaaaa ",
+" ## # ",
+" ## # ",
+" ## # ",
+" ## # "};
+
+static const char *collapsed_xpm[] = {
+"32 32 3 1",
+" c None",
+"# c #000000",
+"a c #0000c0",
+" ## ",
+" ## ",
+" ##aaaaaaaaaaaaaaaaaa ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ##aaaaaaaaaaaaaaaaaa ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ##aaaaaaaaaaaaaaaaaa ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ##aaaaaaaaaaaaaaaaaa ",
+" ## ",
+" ## ",
+" ## ",
+" ## ",
+" ## "};
+
+#endif // GRAPHICS_H
diff --git a/src/qconfig/main.cpp b/src/qconfig/main.cpp
new file mode 100644
index 000000000..1697a4bb2
--- /dev/null
+++ b/src/qconfig/main.cpp
@@ -0,0 +1,544 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "graphics.h"
+#include "feature.h"
+#include "featuretreemodel.h"
+
+#include <QtGui>
+
+QT_BEGIN_NAMESPACE
+
+static QString defaultPath;
+
+class FeatureTextBrowser : public QTextBrowser {
+ Q_OBJECT
+public:
+ FeatureTextBrowser(QWidget *parent) : QTextBrowser(parent) {
+ QString docRoot;
+ docRoot = QLibraryInfo::location(QLibraryInfo::DocumentationPath)
+ + "/html";
+ setSearchPaths(searchPaths() << docRoot);
+ }
+
+signals:
+ void featureClicked(const QString &feature);
+
+public slots:
+ void setSource(const QUrl &url)
+ {
+ if (url.scheme() == "feature")
+ emit featureClicked(url.authority());
+ else
+ QTextBrowser::setSource(url);
+ }
+};
+
+class Main : public QMainWindow {
+ Q_OBJECT
+public:
+ Main();
+ ~Main();
+ void loadFeatures(const QString& filename);
+ void loadConfig(const QString& filename);
+
+public slots:
+ void modelChanged();
+ void showInfo(const QModelIndex &index);
+ void showInfo(const QString &feature);
+ void openConfig();
+ void saveConfig();
+ void expandView();
+ void collapseView();
+ void about();
+ void aboutQt();
+ void quit();
+ void clear();
+ void enableAll();
+ void disableAll();
+
+private:
+ QTextBrowser *textBrowser;
+ QTreeView *featureTree;
+ FeatureTreeModel *featureModel;
+
+ void init();
+ void updateStatus(int numFeatures = -1);
+ void completelyExpandIndex(const QModelIndex &parent);
+};
+
+template<typename Func>
+void foreachIndex_helper(const QModelIndex &parent, Func func)
+{
+ const QAbstractItemModel *model = parent.model();
+ const int rows = model->rowCount(parent);
+ for (int i = 0; i < rows; ++i) {
+ const QModelIndex child = model->index(i, 0, parent);
+ func(child);
+ foreachIndex_helper(child, func);
+ }
+}
+
+template<typename Func>
+void foreachIndex(const QAbstractItemModel *model, Func func)
+{
+ const int rows = model->rowCount(QModelIndex());
+ for (int i = 0; i < rows; ++i) {
+ const QModelIndex child = model->index(i, 0, QModelIndex());
+ func(child);
+ foreachIndex_helper(child, func);
+ }
+}
+
+struct CheckStateSetter {
+
+ CheckStateSetter(Qt::CheckState state, QAbstractItemModel *m)
+ : checkState(state), model(m) {}
+
+ void operator()(const QModelIndex &index) {
+ model->setData(index, checkState, Qt::CheckStateRole);
+ }
+
+ Qt::CheckState checkState;
+ QAbstractItemModel *model;
+};
+
+void Main::disableAll()
+{
+ QAbstractItemModel *model = featureTree->model();
+ foreachIndex(model, CheckStateSetter(Qt::Unchecked, model));
+}
+
+void Main::enableAll()
+{
+ QAbstractItemModel *model = featureTree->model();
+ foreachIndex(model, CheckStateSetter(Qt::Checked, model));
+}
+
+Main::Main()
+{
+ setWindowIcon(QIcon(QPixmap(logo_xpm)));
+
+ QSplitter *splitter = new QSplitter(this);
+
+ featureModel = new FeatureTreeModel(this);
+ featureTree = new QTreeView(splitter);
+ splitter->addWidget(featureTree);
+ featureTree->setRootIsDecorated(true);
+ featureTree->setModel(featureModel);
+ featureTree->show();
+
+ textBrowser = new FeatureTextBrowser(splitter);
+ textBrowser->setFrameStyle(QFrame::WinPanel|QFrame::Sunken);
+ splitter->addWidget(textBrowser);
+ textBrowser->show();
+
+ connect(textBrowser, SIGNAL(featureClicked(QString)),
+ this, SLOT(showInfo(QString)));
+ connect(featureTree, SIGNAL(activated(QModelIndex)),
+ this, SLOT(showInfo(QModelIndex)));
+ connect(featureModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(modelChanged()));
+ connect(featureTree, SIGNAL(clicked(QModelIndex)),
+ this, SLOT(showInfo(QModelIndex)));
+
+ setCentralWidget(splitter);
+
+ QMenu *file = menuBar()->addMenu("&File");
+ file->addAction("&Open...", this, SLOT(openConfig()),
+ Qt::CTRL + Qt::Key_O);
+ file->addAction("&Save As...", this, SLOT(saveConfig()),
+ Qt::CTRL + Qt::Key_S);
+ file->addSeparator();
+ file->addAction("&Reset", this, SLOT(clear()));
+ file->addSeparator();
+ file->addAction("E&xit", this, SLOT(quit()), Qt::CTRL + Qt::Key_Q);
+
+ QMenu *edit = menuBar()->addMenu("&Tools");
+ edit->addAction("&Enable all features", this, SLOT(enableAll()));
+ edit->addAction("&Disable all features", this, SLOT(disableAll()));
+
+ menuBar()->addSeparator();
+
+ QMenu *help = menuBar()->addMenu("&Help");
+ help->addAction("&About", this, SLOT(about()));
+ help->addAction("About &Qt", this, SLOT(aboutQt()));
+
+ QToolBar *tb = new QToolBar("Expand/Collapse features");
+ QToolButton *button;
+
+ button = new QToolButton(tb);
+ button->setIcon(QIcon(QPixmap(collapsed_xpm)));
+ button->setText("Collapse");
+ button->setToolTip("Collapse");
+ connect(button, SIGNAL(clicked()), this, SLOT(collapseView()));
+ tb->addWidget(button);
+
+ button = new QToolButton(tb);
+ button->setIcon(QIcon(QPixmap(expanded_xpm)));
+ button->setText("Expand");
+ button->setToolTip("Expand");
+ connect(button, SIGNAL(clicked()), this, SLOT(expandView()));
+ tb->addWidget(button);
+ addToolBar(tb);
+
+ init();
+}
+
+Main::~Main()
+{
+ delete textBrowser;
+ delete featureModel;
+ delete featureTree;
+}
+
+void Main::clear()
+{
+ QSettings settings;
+ settings.clear();
+ featureModel->clear();
+ featureTree->reset();
+ init();
+}
+
+void Main::quit()
+{
+ if (isWindowModified()) {
+ int button = QMessageBox::question(this, "Quit Program",
+ "You have unsaved changes.\n"
+ "Do you want to quit anyway?",
+ QMessageBox::Yes,
+ QMessageBox::No);
+ if (static_cast<QMessageBox::Button>(button) != QMessageBox::Yes)
+ return;
+ }
+ QApplication::instance()->quit();
+}
+
+/*
+ Recursively expand expand \a parent and all of its children.
+*/
+void Main::completelyExpandIndex(const QModelIndex &parent)
+{
+ featureTree->setExpanded(parent, true);
+
+ const QAbstractItemModel *model = featureTree->model();
+ const int rows = model->rowCount(parent);
+ for (int i = 0; i < rows; ++i)
+ completelyExpandIndex(model->index(i, 0, parent));
+}
+
+void Main::expandView()
+{
+ completelyExpandIndex(QModelIndex());
+}
+
+void Main::collapseView()
+{
+ const QAbstractItemModel *model = featureTree->model();
+ const int rows = model->rowCount(QModelIndex());
+ for (int i = 0; i < rows; ++i) {
+ QModelIndex index = model->index(i, 0, QModelIndex());
+ featureTree->setExpanded(index, false);
+ }
+}
+
+void Main::updateStatus(int numFeatures)
+{
+ QSettings settings;
+ QString featureFile = settings.value("featureFile").toString();
+ QString configFile = settings.value("lastConfig").toString();
+ QString message("Using features from %1");
+
+ if (numFeatures >= 0) {
+ QString s("%1 features loaded from %2");
+ statusBar()->showMessage(s.arg(numFeatures).arg(featureFile));
+ }
+ QString appName = QApplication::applicationName();
+ if (configFile.isEmpty())
+ configFile = "New File";
+ setWindowTitle(appName + " - " + configFile + "[*]");
+}
+
+void Main::modelChanged()
+{
+ setWindowModified(true);
+}
+
+void Main::init()
+{
+ QSettings settings;
+ QString features = settings.value("featureFile").toString();
+
+ if (features.isEmpty() || !QFileInfo(features).isFile()) {
+ features = QFileDialog::getOpenFileName(this,
+ "Open a feature file",
+ defaultPath,
+ "Qt Features (qfeatures.txt)");
+ }
+ settings.setValue("featureFile", features);
+ loadFeatures(features);
+
+ expandView();
+ collapseView();
+
+ QString confFile = settings.value("lastConfig").toString();
+ if (confFile.isEmpty())
+ return;
+ loadConfig(confFile);
+}
+
+void Main::openConfig()
+{
+ QSettings settings;
+ QString configDir;
+
+ QString prevFile = settings.value("lastConfig").toString();
+ if (!prevFile.isEmpty())
+ configDir = QFileInfo(prevFile).path();
+
+ if (configDir.isEmpty())
+ configDir = defaultPath;
+
+ QString configFile;
+ configFile = QFileDialog::getOpenFileName(this,
+ "Open a configuration file",
+ configDir,
+ "Header files (*.h)");
+ enableAll();
+ if (!configFile.isEmpty())
+ loadConfig(configFile);
+ settings.setValue("lastConfig", QFileInfo(configFile).absoluteFilePath());
+}
+
+void Main::saveConfig()
+{
+ QSettings settings;
+ QString configDir;
+
+ QString prevFile = settings.value("lastConfig").toString();
+ if (!prevFile.isEmpty())
+ configDir = QFileInfo(prevFile).path();
+
+ if (configDir.isEmpty())
+ configDir = defaultPath;
+
+ QString configFile;
+ configFile = QFileDialog::getSaveFileName(this,
+ "Save configuration file",
+ configDir,
+ "Header files (*.h)");
+ if (configFile.isEmpty())
+ return;
+
+ QFile file(configFile);
+ if (!file.open(QIODevice::WriteOnly)) {
+ QMessageBox::warning(this,"Warning",
+ "Cannot write to file " + configFile);
+ return;
+ }
+
+ QTextStream stream(&file);
+ FeatureTreeModel *model;
+ model = static_cast<FeatureTreeModel*>(featureTree->model());
+ model->writeConfig(stream);
+
+ settings.setValue("lastConfig", QFileInfo(configFile).absoluteFilePath());
+ setWindowModified(false);
+ updateStatus();
+}
+
+void Main::loadConfig(const QString &filename)
+{
+ if (!QFileInfo(filename).isFile())
+ return;
+
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ QMessageBox::warning(this,"Warning", "Cannot open file " + filename);
+ return;
+ }
+
+ QTextStream stream(&file);
+ FeatureTreeModel *model;
+ model = static_cast<FeatureTreeModel*>(featureTree->model());
+ model->readConfig(stream);
+
+ QSettings settings;
+ settings.setValue("lastConfig", QFileInfo(filename).absoluteFilePath());
+ setWindowModified(false);
+ updateStatus();
+}
+
+void Main::loadFeatures(const QString &filename)
+{
+ Feature::clear();
+
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ QMessageBox::warning(this,"Warning", "Cannot open file " + filename);
+ return;
+ }
+
+ Feature *feature = 0;
+ int numFeatures = 0;
+ updateStatus(numFeatures);
+ QTextStream s(&file);
+ for (QString line = s.readLine(); !s.atEnd(); line = s.readLine()) {
+ line = line.simplified();
+ if (line.isEmpty())
+ continue;
+ if (line.startsWith('#'))
+ continue;
+
+ int colon = line.indexOf(':');
+ if (colon < 0) { // assume description
+ QString description = feature->description().simplified();
+ description += " " + line;
+ feature->setDescription(description);
+ continue;
+ }
+
+ QString tag = line.left(colon);
+ QString value = line.mid(colon+1).simplified();
+ if (tag == "Feature") {
+ if (feature)
+ featureModel->addFeature(feature);
+ feature = Feature::getInstance(value);
+ updateStatus(++numFeatures);
+ } else if (tag == "Requires") {
+ Q_ASSERT(feature);
+ feature->setDependencies(value.split(' ', QString::SkipEmptyParts));
+ } else if (tag == "Name") {
+ Q_ASSERT(feature);
+ feature->setTitle(value);
+ } else if (tag == "Section") {
+ Q_ASSERT(feature);
+ feature->setSection(value);
+ } else if (tag == "SeeAlso") {
+ Q_ASSERT(feature);
+ feature->setRelations(value.split(' ', QString::SkipEmptyParts));
+ } else if (tag == "Description") {
+ Q_ASSERT(feature);
+ feature->setDescription(value);
+ }
+ }
+ if (feature)
+ featureModel->addFeature(feature);
+
+ featureTree->resizeColumnToContents(0);
+
+ QSettings settings;
+ settings.setValue("featureFile", QFileInfo(filename).absoluteFilePath());
+
+ updateStatus();
+}
+
+void Main::showInfo(const QModelIndex &index)
+{
+ FeatureTreeModel *model;
+ model = static_cast<FeatureTreeModel*>(featureTree->model());
+
+ if (const Feature *feature = model->getFeature(index))
+ textBrowser->setHtml(feature->toHtml());
+
+ // Ensure index is visible
+ QModelIndex parent = model->parent(index);
+ while (parent.isValid()) {
+ featureTree->setExpanded(parent, true);
+ parent = model->parent(parent);
+ }
+
+ featureTree->scrollTo(index);
+ featureTree->setCurrentIndex(index);
+}
+
+void Main::showInfo(const QString &feature)
+{
+ const Feature *f = Feature::getInstance(feature);
+ FeatureTreeModel *model;
+ model = static_cast<FeatureTreeModel*>(featureTree->model());
+ showInfo(model->index(f));
+}
+
+void Main::about()
+{
+ QMessageBox::about(this, "About qconfig",
+ "<p><b><font size=\"+2\">Qtopia Core build configuration</font></b></p>"
+ "<p></p>"
+ "<p>Version 2.0</p>"
+ "<p>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).</p>"
+ "<p></p>"
+ );
+}
+
+void Main::aboutQt()
+{
+ QMessageBox::aboutQt( this, tr("qconfig") );
+}
+
+QT_END_NAMESPACE
+
+int main(int argc, char** argv)
+{
+ QT_USE_NAMESPACE
+ QApplication app(argc,argv);
+ app.setOrganizationDomain("trolltech.com");
+ app.setOrganizationName("Trolltech");
+ app.setApplicationName("QConfig");
+ Main m;
+
+ defaultPath = QLibraryInfo::location(QLibraryInfo::PrefixPath)
+ + "/src/corelib/global";
+
+ for (int i = 1; i < argc; ++i) {
+ QString arg = argv[i];
+ if (arg == "-f" && i+1 < argc)
+ m.loadFeatures(argv[++i]);
+ else if (arg == "-c" && i+1 < argc)
+ m.loadConfig(argv[++i]);
+ }
+ m.resize(m.sizeHint() + QSize(500,300));
+ m.show();
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/src/qconfig/qconfig.pro b/src/qconfig/qconfig.pro
new file mode 100644
index 000000000..171924fa4
--- /dev/null
+++ b/src/qconfig/qconfig.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+CONFIG += qt warn_on
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+HEADERS = feature.h featuretreemodel.h graphics.h
+SOURCES = main.cpp feature.cpp featuretreemodel.cpp
+TARGET = qconfig
diff --git a/src/qdbus/qdbus.pro b/src/qdbus/qdbus.pro
new file mode 100644
index 000000000..a264882bc
--- /dev/null
+++ b/src/qdbus/qdbus.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS = qdbus qdbusxml2cpp qdbuscpp2xml
+!contains(QT_CONFIG, no-gui): SUBDIRS += qdbusviewer
diff --git a/src/qdbus/qdbus/qdbus.cpp b/src/qdbus/qdbus/qdbus.cpp
new file mode 100644
index 000000000..a3821a1f4
--- /dev/null
+++ b/src/qdbus/qdbus/qdbus.cpp
@@ -0,0 +1,528 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QStringList>
+#include <QtCore/qmetaobject.h>
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomElement>
+#include <QtDBus/QtDBus>
+#include <private/qdbusutil_p.h>
+
+QT_BEGIN_NAMESPACE
+Q_DBUS_EXPORT extern bool qt_dbus_metaobject_skip_annotations;
+QT_END_NAMESPACE
+
+static QDBusConnection connection(QLatin1String(""));
+static bool printArgumentsLiterally = false;
+
+static void showUsage()
+{
+ printf("Usage: qdbus [--system] [--literal] [servicename] [path] [method] [args]\n"
+ "\n"
+ " servicename the service to connect to (e.g., org.freedesktop.DBus)\n"
+ " path the path to the object (e.g., /)\n"
+ " method the method to call, with or without the interface\n"
+ " args arguments to pass to the call\n"
+ "With 0 arguments, qdbus will list the services available on the bus\n"
+ "With just the servicename, qdbus will list the object paths available on the service\n"
+ "With service name and object path, qdbus will list the methods, signals and properties available on the object\n"
+ "\n"
+ "Options:\n"
+ " --system connect to the system bus\n"
+ " --literal print replies literally\n");
+}
+
+static void printArg(const QVariant &v)
+{
+ if (printArgumentsLiterally) {
+ printf("%s\n", qPrintable(QDBusUtil::argumentToString(v)));
+ return;
+ }
+
+ if (v.userType() == QVariant::StringList) {
+ foreach (QString s, v.toStringList())
+ printf("%s\n", qPrintable(s));
+ } else if (v.userType() == QVariant::List) {
+ foreach (const QVariant &var, v.toList())
+ printArg(var);
+ } else if (v.userType() == QVariant::Map) {
+ const QVariantMap map = v.toMap();
+ QVariantMap::ConstIterator it = map.constBegin();
+ for ( ; it != map.constEnd(); ++it) {
+ printf("%s: ", qPrintable(it.key()));
+ printArg(it.value());
+ }
+ } else if (v.userType() == qMetaTypeId<QDBusVariant>()) {
+ printArg(qvariant_cast<QDBusVariant>(v).variant());
+ } else if (v.userType() == qMetaTypeId<QDBusArgument>()) {
+ QDBusArgument arg = qvariant_cast<QDBusArgument>(v);
+ if (arg.currentSignature() == QLatin1String("av"))
+ printArg(qdbus_cast<QVariantList>(arg));
+ else if (arg.currentSignature() == QLatin1String("a{sv}"))
+ printArg(qdbus_cast<QVariantMap>(arg));
+ else
+ printf("qdbus: I don't know how to display an argument of type '%s', run with --literal.\n",
+ qPrintable(arg.currentSignature()));
+ } else {
+ printf("%s\n", qPrintable(v.toString()));
+ }
+}
+
+static void listObjects(const QString &service, const QString &path)
+{
+ // make a low-level call, to avoid introspecting the Introspectable interface
+ QDBusMessage call = QDBusMessage::createMethodCall(service, path.isEmpty() ? QLatin1String("/") : path,
+ QLatin1String("org.freedesktop.DBus.Introspectable"),
+ QLatin1String("Introspect"));
+ QDBusReply<QString> xml = connection.call(call);
+
+ if (path.isEmpty()) {
+ // top-level
+ if (xml.isValid()) {
+ printf("/\n");
+ } else {
+ QDBusError err = xml.error();
+ if (err.type() == QDBusError::ServiceUnknown)
+ fprintf(stderr, "Service '%s' does not exist.\n", qPrintable(service));
+ else
+ printf("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message()));
+ exit(2);
+ }
+ } else if (!xml.isValid()) {
+ // this is not the first object, just fail silently
+ return;
+ }
+
+ QDomDocument doc;
+ doc.setContent(xml);
+ QDomElement node = doc.documentElement();
+ QDomElement child = node.firstChildElement();
+ while (!child.isNull()) {
+ if (child.tagName() == QLatin1String("node")) {
+ QString sub = path + QLatin1Char('/') + child.attribute(QLatin1String("name"));
+ printf("%s\n", qPrintable(sub));
+ listObjects(service, sub);
+ }
+ child = child.nextSiblingElement();
+ }
+}
+
+static void listInterface(const QString &service, const QString &path, const QString &interface)
+{
+ QDBusInterface iface(service, path, interface, connection);
+ if (!iface.isValid()) {
+ QDBusError err(iface.lastError());
+ fprintf(stderr, "Interface '%s' not available in object %s at %s:\n%s (%s)\n",
+ qPrintable(interface), qPrintable(path), qPrintable(service),
+ qPrintable(err.name()), qPrintable(err.message()));
+ exit(1);
+ }
+ const QMetaObject *mo = iface.metaObject();
+
+ // properties
+ for (int i = mo->propertyOffset(); i < mo->propertyCount(); ++i) {
+ QMetaProperty mp = mo->property(i);
+ printf("property ");
+
+ if (mp.isReadable() && mp.isWritable())
+ printf("readwrite");
+ else if (mp.isReadable())
+ printf("read");
+ else
+ printf("write");
+
+ printf(" %s %s.%s\n", mp.typeName(), qPrintable(interface), mp.name());
+ }
+
+ // methods (signals and slots)
+ for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
+ QMetaMethod mm = mo->method(i);
+
+ QByteArray signature = mm.signature();
+ signature.truncate(signature.indexOf('('));
+ printf("%s %s%s%s %s.%s(",
+ mm.methodType() == QMetaMethod::Signal ? "signal" : "method",
+ mm.tag(), *mm.tag() ? " " : "",
+ *mm.typeName() ? mm.typeName() : "void",
+ qPrintable(interface), signature.constData());
+
+ QList<QByteArray> types = mm.parameterTypes();
+ QList<QByteArray> names = mm.parameterNames();
+ bool first = true;
+ for (int i = 0; i < types.count(); ++i) {
+ printf("%s%s",
+ first ? "" : ", ",
+ types.at(i).constData());
+ if (!names.at(i).isEmpty())
+ printf(" %s", names.at(i).constData());
+ first = false;
+ }
+ printf(")\n");
+ }
+}
+
+static void listAllInterfaces(const QString &service, const QString &path)
+{
+ // make a low-level call, to avoid introspecting the Introspectable interface
+ QDBusMessage call = QDBusMessage::createMethodCall(service, path.isEmpty() ? QLatin1String("/") : path,
+ QLatin1String("org.freedesktop.DBus.Introspectable"),
+ QLatin1String("Introspect"));
+ QDBusReply<QString> xml = connection.call(call);
+
+ if (!xml.isValid()) {
+ QDBusError err = xml.error();
+ if (err.type() == QDBusError::ServiceUnknown)
+ fprintf(stderr, "Service '%s' does not exist.\n", qPrintable(service));
+ else
+ printf("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message()));
+ exit(2);
+ }
+
+ QDomDocument doc;
+ doc.setContent(xml);
+ QDomElement node = doc.documentElement();
+ QDomElement child = node.firstChildElement();
+ while (!child.isNull()) {
+ if (child.tagName() == QLatin1String("interface")) {
+ QString ifaceName = child.attribute(QLatin1String("name"));
+ if (QDBusUtil::isValidInterfaceName(ifaceName))
+ listInterface(service, path, ifaceName);
+ else {
+ qWarning("Invalid D-BUS interface name '%s' found while parsing introspection",
+ qPrintable(ifaceName));
+ }
+ }
+ child = child.nextSiblingElement();
+ }
+}
+
+static QStringList readList(QStringList &args)
+{
+ args.takeFirst();
+
+ QStringList retval;
+ while (!args.isEmpty() && args.at(0) != QLatin1String(")"))
+ retval += args.takeFirst();
+
+ if (args.value(0) == QLatin1String(")"))
+ args.takeFirst();
+
+ return retval;
+}
+
+static int placeCall(const QString &service, const QString &path, const QString &interface,
+ const QString &member, const QStringList& arguments, bool try_prop=true)
+{
+ QDBusInterface iface(service, path, interface, connection);
+
+ // Don't check whether the interface is valid to allow DBus try to
+ // activate the service if possible.
+
+ QList<int> knownIds;
+ bool matchFound = false;
+ QStringList args = arguments;
+ QVariantList params;
+ if (!args.isEmpty()) {
+ const QMetaObject *mo = iface.metaObject();
+ QByteArray match = member.toLatin1();
+ match += '(';
+
+ for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
+ QMetaMethod mm = mo->method(i);
+ QByteArray signature = mm.signature();
+ if (signature.startsWith(match))
+ knownIds += i;
+ }
+
+
+ while (!matchFound) {
+ args = arguments; // reset
+ params.clear();
+ if (knownIds.isEmpty()) {
+ // Failed to set property after falling back?
+ // Bail out without displaying an error
+ if (!try_prop)
+ return 1;
+ if (try_prop && args.size() == 1) {
+ QStringList proparg;
+ proparg += interface;
+ proparg += member;
+ proparg += args.first();
+ if (!placeCall(service, path, "org.freedesktop.DBus.Properties", "Set", proparg, false))
+ return 0;
+ }
+ fprintf(stderr, "Cannot find '%s.%s' in object %s at %s\n",
+ qPrintable(interface), qPrintable(member), qPrintable(path),
+ qPrintable(service));
+ return 1;
+ }
+
+ QMetaMethod mm = mo->method(knownIds.takeFirst());
+ QList<QByteArray> types = mm.parameterTypes();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i).endsWith('&')) {
+ // reference (and not a reference to const): output argument
+ // we're done with the inputs
+ while (types.count() > i)
+ types.removeLast();
+ break;
+ }
+ }
+
+ for (int i = 0; !args.isEmpty() && i < types.count(); ++i) {
+ int id = QVariant::nameToType(types.at(i));
+ if (id == QVariant::UserType)
+ id = QMetaType::type(types.at(i));
+ if (!id) {
+ fprintf(stderr, "Cannot call method '%s' because type '%s' is unknown to this tool\n",
+ qPrintable(member), types.at(i).constData());
+ return 1;
+ }
+
+ QVariant p;
+ QString argument;
+ if ((id == QVariant::List || id == QVariant::StringList)
+ && args.at(0) == QLatin1String("("))
+ p = readList(args);
+ else
+ p = argument = args.takeFirst();
+
+ if (id == int(QMetaType::UChar)) {
+ // special case: QVariant::convert doesn't convert to/from
+ // UChar because it can't decide if it's a character or a number
+ p = QVariant::fromValue<uchar>(p.toUInt());
+ } else if (id < int(QMetaType::User) && id != int(QVariant::Map)) {
+ p.convert(QVariant::Type(id));
+ if (p.type() == QVariant::Invalid) {
+ fprintf(stderr, "Could not convert '%s' to type '%s'.\n",
+ qPrintable(argument), types.at(i).constData());
+ return 1 ;
+ }
+ } else if (id == qMetaTypeId<QDBusVariant>()) {
+ QDBusVariant tmp(p);
+ p = QVariant::fromValue(tmp);
+ } else if (id == qMetaTypeId<QDBusObjectPath>()) {
+ QDBusObjectPath path(argument);
+ if (path.path().isNull()) {
+ fprintf(stderr, "Cannot pass argument '%s' because it is not a valid object path.\n",
+ qPrintable(argument));
+ return 1;
+ }
+ p = QVariant::fromValue(path);
+ } else if (id == qMetaTypeId<QDBusSignature>()) {
+ QDBusSignature sig(argument);
+ if (sig.signature().isNull()) {
+ fprintf(stderr, "Cannot pass argument '%s' because it is not a valid signature.\n",
+ qPrintable(argument));
+ return 1;
+ }
+ p = QVariant::fromValue(sig);
+ } else {
+ fprintf(stderr, "Sorry, can't pass arg of type '%s'.\n",
+ types.at(i).constData());
+ return 1;
+ }
+ params += p;
+ }
+ if (params.count() == types.count() && args.isEmpty())
+ matchFound = true;
+ else if (knownIds.isEmpty()) {
+ fprintf(stderr, "Invalid number of parameters\n");
+ return 1;
+ }
+ } // while (!matchFound)
+ } // if (!args.isEmpty()
+
+ QDBusMessage reply = iface.callWithArgumentList(QDBus::Block, member, params);
+ if (reply.type() == QDBusMessage::ErrorMessage) {
+ QDBusError err = reply;
+ // Failed to retrieve property after falling back?
+ // Bail out without displaying an error
+ if (!try_prop)
+ return 1;
+ if (err.type() == QDBusError::UnknownMethod && try_prop) {
+ QStringList proparg;
+ proparg += interface;
+ proparg += member;
+ if (!placeCall(service, path, "org.freedesktop.DBus.Properties", "Get", proparg, false))
+ return 0;
+ }
+ if (err.type() == QDBusError::ServiceUnknown)
+ fprintf(stderr, "Service '%s' does not exist.\n", qPrintable(service));
+ else
+ printf("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message()));
+ return 2;
+ } else if (reply.type() != QDBusMessage::ReplyMessage) {
+ fprintf(stderr, "Invalid reply type %d\n", int(reply.type()));
+ return 1;
+ }
+
+ foreach (QVariant v, reply.arguments())
+ printArg(v);
+
+ return 0;
+}
+
+static bool globServices(QDBusConnectionInterface *bus, const QString &glob)
+{
+ QRegExp pattern(glob, Qt::CaseSensitive, QRegExp::Wildcard);
+ if (!pattern.isValid())
+ return false;
+
+ QStringList names = bus->registeredServiceNames();
+ names.sort();
+ foreach (const QString &name, names)
+ if (pattern.exactMatch(name))
+ printf("%s\n", qPrintable(name));
+
+ return true;
+}
+
+static void printAllServices(QDBusConnectionInterface *bus)
+{
+ const QStringList services = bus->registeredServiceNames();
+ QMap<QString, QStringList> servicesWithAliases;
+
+ foreach (QString serviceName, services) {
+ QDBusReply<QString> reply = bus->serviceOwner(serviceName);
+ QString owner = reply;
+ if (owner.isEmpty())
+ owner = serviceName;
+ servicesWithAliases[owner].append(serviceName);
+ }
+
+ for (QMap<QString,QStringList>::const_iterator it = servicesWithAliases.constBegin();
+ it != servicesWithAliases.constEnd(); ++it) {
+ QStringList names = it.value();
+ names.sort();
+ printf("%s\n", qPrintable(names.join(QLatin1String("\n "))));
+ }
+}
+
+int main(int argc, char **argv)
+{
+ QT_PREPEND_NAMESPACE(qt_dbus_metaobject_skip_annotations) = true;
+ QCoreApplication app(argc, argv);
+ QStringList args = app.arguments();
+ args.takeFirst();
+
+ bool connectionOpened = false;
+ while (!args.isEmpty() && args.at(0).startsWith(QLatin1Char('-'))) {
+ QString arg = args.takeFirst();
+ if (arg == QLatin1String("--system")) {
+ connection = QDBusConnection::systemBus();
+ connectionOpened = true;
+ } else if (arg == QLatin1String("--literal")) {
+ printArgumentsLiterally = true;
+ } else if (arg == QLatin1String("--help")) {
+ showUsage();
+ return 0;
+ }
+ }
+
+ if (!connectionOpened)
+ connection = QDBusConnection::sessionBus();
+
+ if (!connection.isConnected()) {
+ fprintf(stderr, "Could not connect to D-Bus server: %s: %s\n",
+ qPrintable(connection.lastError().name()),
+ qPrintable(connection.lastError().message()));
+ return 1;
+ }
+
+ QDBusConnectionInterface *bus = connection.interface();
+ if (args.isEmpty()) {
+ printAllServices(bus);
+ exit(0);
+ }
+
+ QString service = args.takeFirst();
+ if (!QDBusUtil::isValidBusName(service)) {
+ if (service.contains(QLatin1Char('*'))) {
+ if (globServices(bus, service))
+ return 0;
+ }
+ fprintf(stderr, "Service '%s' is not a valid name.\n", qPrintable(service));
+ exit(1);
+ }
+
+ if (args.isEmpty()) {
+ listObjects(service, QString());
+ exit(0);
+ }
+
+ QString path = args.takeFirst();
+ if (!QDBusUtil::isValidObjectPath(path)) {
+ fprintf(stderr, "Path '%s' is not a valid path name.\n", qPrintable(path));
+ exit(1);
+ }
+ if (args.isEmpty()) {
+ listAllInterfaces(service, path);
+ exit(0);
+ }
+
+ QString interface = args.takeFirst();
+ QString member;
+ int pos = interface.lastIndexOf(QLatin1Char('.'));
+ if (pos == -1) {
+ member = interface;
+ interface.clear();
+ } else {
+ member = interface.mid(pos + 1);
+ interface.truncate(pos);
+ }
+ if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) {
+ fprintf(stderr, "Interface '%s' is not a valid interface name.\n", qPrintable(interface));
+ exit(1);
+ }
+ if (!QDBusUtil::isValidMemberName(member)) {
+ fprintf(stderr, "Method name '%s' is not a valid member name.\n", qPrintable(member));
+ exit(1);
+ }
+
+ int ret = placeCall(service, path, interface, member, args);
+ exit(ret);
+}
+
diff --git a/src/qdbus/qdbus/qdbus.pro b/src/qdbus/qdbus/qdbus.pro
new file mode 100644
index 000000000..ea732ef28
--- /dev/null
+++ b/src/qdbus/qdbus/qdbus.pro
@@ -0,0 +1,10 @@
+SOURCES = qdbus.cpp
+DESTDIR = ../../../bin
+TARGET = qdbus
+QT = core xml
+CONFIG += qdbus
+CONFIG -= app_bundle
+win32:CONFIG += console
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp
new file mode 100644
index 000000000..18704e537
--- /dev/null
+++ b/src/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -0,0 +1,446 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QByteArray>
+#include <QString>
+#include <QVarLengthArray>
+#include <QFile>
+#include <QProcess>
+#include <QMetaObject>
+#include <QList>
+#include <QRegExp>
+#include <QCoreApplication>
+#include <QLibraryInfo>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "qdbusconnection.h" // for the Export* flags
+
+// copied from dbus-protocol.h:
+static const char docTypeHeader[] =
+ "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
+ "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n";
+
+// in qdbusxmlgenerator.cpp
+QT_BEGIN_NAMESPACE
+extern Q_DBUS_EXPORT QString qDBusGenerateMetaObjectXml(QString interface, const QMetaObject *mo,
+ const QMetaObject *base, int flags);
+QT_END_NAMESPACE
+
+#define PROGRAMNAME "qdbuscpp2xml"
+#define PROGRAMVERSION "0.1"
+#define PROGRAMCOPYRIGHT "Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+
+static QString outputFile;
+static int flags;
+
+static const char help[] =
+ "Usage: " PROGRAMNAME " [options...] [files...]\n"
+ "Parses the C++ source or header file containing a QObject-derived class and\n"
+ "produces the D-Bus Introspection XML."
+ "\n"
+ "Options:\n"
+ " -p|-s|-m Only parse scriptable Properties, Signals and Methods (slots)\n"
+ " -P|-S|-M Parse all Properties, Signals and Methods (slots)\n"
+ " -a Output all scriptable contents (equivalent to -psm)\n"
+ " -A Output all contents (equivalent to -PSM)\n"
+ " -o <filename> Write the output to file <filename>\n"
+ " -h Show this information\n"
+ " -V Show the program version and quit.\n"
+ "\n";
+
+class MocParser
+{
+ void parseError();
+ QByteArray readLine();
+ void loadIntData(uint *&data);
+ void loadStringData(char *&stringdata);
+
+ QIODevice *input;
+ const char *filename;
+ int lineNumber;
+public:
+ ~MocParser();
+ void parse(const char *filename, QIODevice *input, int lineNumber = 0);
+
+ QList<QMetaObject> objects;
+};
+
+void MocParser::parseError()
+{
+ fprintf(stderr, PROGRAMNAME ": error parsing input file '%s' line %d \n", filename, lineNumber);
+ exit(1);
+}
+
+QByteArray MocParser::readLine()
+{
+ ++lineNumber;
+ return input->readLine();
+}
+
+void MocParser::loadIntData(uint *&data)
+{
+ data = 0; // initialise
+ QVarLengthArray<uint> array;
+ QRegExp rx(QLatin1String("(\\d+|0x[0-9abcdef]+)"), Qt::CaseInsensitive);
+
+ while (!input->atEnd()) {
+ QString line = QLatin1String(readLine());
+ int pos = line.indexOf(QLatin1String("//"));
+ if (pos != -1)
+ line.truncate(pos); // drop comments
+
+ if (line == QLatin1String("};\n")) {
+ // end of data
+ data = new uint[array.count()];
+ memcpy(data, array.data(), array.count() * sizeof(*data));
+ return;
+ }
+
+ pos = 0;
+ while ((pos = rx.indexIn(line, pos)) != -1) {
+ QString num = rx.cap(1);
+ if (num.startsWith(QLatin1String("0x")))
+ array.append(num.mid(2).toUInt(0, 16));
+ else
+ array.append(num.toUInt());
+ pos += rx.matchedLength();
+ }
+ }
+
+ parseError();
+}
+
+void MocParser::loadStringData(char *&stringdata)
+{
+ stringdata = 0;
+ QVarLengthArray<char, 1024> array;
+
+ while (!input->atEnd()) {
+ QByteArray line = readLine();
+ if (line == "};\n") {
+ // end of data
+ stringdata = new char[array.count()];
+ memcpy(stringdata, array.data(), array.count() * sizeof(*stringdata));
+ return;
+ }
+
+ int start = line.indexOf('"');
+ if (start == -1)
+ parseError();
+
+ int len = line.length() - 1;
+ line.truncate(len); // drop ending \n
+ if (line.at(len - 1) != '"')
+ parseError();
+
+ --len;
+ ++start;
+ for ( ; start < len; ++start)
+ if (line.at(start) == '\\') {
+ // parse escaped sequence
+ ++start;
+ if (start == len)
+ parseError();
+
+ QChar c(QLatin1Char(line.at(start)));
+ if (!c.isDigit()) {
+ switch (c.toLatin1()) {
+ case 'a':
+ array.append('\a');
+ break;
+ case 'b':
+ array.append('\b');
+ break;
+ case 'f':
+ array.append('\f');
+ break;
+ case 'n':
+ array.append('\n');
+ break;
+ case 'r':
+ array.append('\r');
+ break;
+ case 't':
+ array.append('\t');
+ break;
+ case 'v':
+ array.append('\v');
+ break;
+ case '\\':
+ case '?':
+ case '\'':
+ case '"':
+ array.append(c.toLatin1());
+ break;
+
+ case 'x':
+ if (start + 2 <= len)
+ parseError();
+ array.append(char(line.mid(start + 1, 2).toInt(0, 16)));
+ break;
+
+ default:
+ array.append(c.toLatin1());
+ fprintf(stderr, PROGRAMNAME ": warning: invalid escape sequence '\\%c' found in input",
+ c.toLatin1());
+ }
+ } else {
+ // octal
+ QRegExp octal(QLatin1String("([0-7]+)"));
+ if (octal.indexIn(QLatin1String(line), start) == -1)
+ parseError();
+ array.append(char(octal.cap(1).toInt(0, 8)));
+ }
+ } else {
+ array.append(line.at(start));
+ }
+ }
+
+ parseError();
+}
+
+void MocParser::parse(const char *fname, QIODevice *io, int lineNum)
+{
+ filename = fname;
+ input = io;
+ lineNumber = lineNum;
+
+ while (!input->atEnd()) {
+ QByteArray line = readLine();
+ if (line.startsWith("static const uint qt_meta_data_")) {
+ // start of new class data
+ uint *data;
+ loadIntData(data);
+
+ // find the start of the string data
+ do {
+ line = readLine();
+ if (input->atEnd())
+ parseError();
+ } while (!line.startsWith("static const char qt_meta_stringdata_"));
+
+ char *stringdata;
+ loadStringData(stringdata);
+
+ QMetaObject mo;
+ mo.d.superdata = &QObject::staticMetaObject;
+ mo.d.stringdata = stringdata;
+ mo.d.data = data;
+ mo.d.extradata = 0;
+ objects.append(mo);
+ }
+ }
+
+ fname = 0;
+ input = 0;
+}
+
+MocParser::~MocParser()
+{
+ foreach (QMetaObject mo, objects) {
+ delete const_cast<char *>(mo.d.stringdata);
+ delete const_cast<uint *>(mo.d.data);
+ }
+}
+
+static void showHelp()
+{
+ printf("%s", help);
+ exit(0);
+}
+
+static void showVersion()
+{
+ printf("%s version %s\n", PROGRAMNAME, PROGRAMVERSION);
+ printf("D-Bus QObject-to-XML converter\n");
+ exit(0);
+}
+
+static void parseCmdLine(QStringList &arguments)
+{
+ for (int i = 1; i < arguments.count(); ++i) {
+ const QString arg = arguments.at(i);
+
+ if (arg == QLatin1String("--help"))
+ showHelp();
+
+ if (!arg.startsWith(QLatin1Char('-')))
+ continue;
+
+ char c = arg.count() == 2 ? arg.at(1).toLatin1() : char(0);
+ switch (c) {
+ case 'P':
+ flags |= QDBusConnection::ExportNonScriptableProperties;
+ // fall through
+ case 'p':
+ flags |= QDBusConnection::ExportScriptableProperties;
+ break;
+
+ case 'S':
+ flags |= QDBusConnection::ExportNonScriptableSignals;
+ // fall through
+ case 's':
+ flags |= QDBusConnection::ExportScriptableSignals;
+ break;
+
+ case 'M':
+ flags |= QDBusConnection::ExportNonScriptableSlots;
+ // fall through
+ case 'm':
+ flags |= QDBusConnection::ExportScriptableSlots;
+ break;
+
+ case 'A':
+ flags |= QDBusConnection::ExportNonScriptableContents;
+ // fall through
+ case 'a':
+ flags |= QDBusConnection::ExportScriptableContents;
+ break;
+
+ case 'o':
+ if (arguments.count() < i + 2 || arguments.at(i + 1).startsWith(QLatin1Char('-'))) {
+ printf("-o expects a filename\n");
+ exit(1);
+ }
+ outputFile = arguments.takeAt(i + 1);
+ break;
+
+ case 'h':
+ case '?':
+ showHelp();
+ break;
+
+ case 'V':
+ showVersion();
+ break;
+
+ default:
+ printf("unknown option: \"%s\"\n", qPrintable(arg));
+ exit(1);
+ }
+ }
+
+ if (flags == 0)
+ flags = QDBusConnection::ExportScriptableContents
+ | QDBusConnection::ExportNonScriptableContents;
+}
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ QStringList args = app.arguments();
+
+ MocParser parser;
+ parseCmdLine(args);
+
+ for (int i = 1; i < args.count(); ++i) {
+ const QString arg = args.at(i);
+ if (arg.startsWith(QLatin1Char('-')))
+ continue;
+
+ QFile f(arg);
+ if (!f.open(QIODevice::ReadOnly|QIODevice::Text)) {
+ fprintf(stderr, PROGRAMNAME ": could not open '%s': %s\n",
+ qPrintable(arg), qPrintable(f.errorString()));
+ return 1;
+ }
+
+ f.readLine();
+
+ QByteArray line = f.readLine();
+ if (line.contains("Meta object code from reading C++ file"))
+ // this is a moc-generated file
+ parser.parse(argv[i], &f, 3);
+ else {
+ // run moc on this file
+ QProcess proc;
+ proc.start(QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/moc"), QStringList() << QFile::decodeName(argv[i]), QIODevice::ReadOnly | QIODevice::Text);
+
+ if (!proc.waitForStarted()) {
+ fprintf(stderr, PROGRAMNAME ": could not execute moc! Aborting.\n");
+ return 1;
+ }
+
+ proc.closeWriteChannel();
+
+ if (!proc.waitForFinished() || proc.exitStatus() != QProcess::NormalExit ||
+ proc.exitCode() != 0) {
+ // output the moc errors:
+ fprintf(stderr, "%s", proc.readAllStandardError().constData());
+ fprintf(stderr, PROGRAMNAME ": exit code %d from moc. Aborting\n", proc.exitCode());
+ return 1;
+ }
+ fprintf(stderr, "%s", proc.readAllStandardError().constData());
+
+ parser.parse(argv[i], &proc, 1);
+ }
+
+ f.close();
+ }
+
+ QFile output;
+ if (outputFile.isEmpty()) {
+ output.open(stdout, QIODevice::WriteOnly);
+ } else {
+ output.setFileName(outputFile);
+ if (!output.open(QIODevice::WriteOnly)) {
+ fprintf(stderr, PROGRAMNAME ": could not open output file '%s': %s",
+ qPrintable(outputFile), qPrintable(output.errorString()));
+ return 1;
+ }
+ }
+
+ output.write(docTypeHeader);
+ output.write("<node>\n");
+ foreach (QMetaObject mo, parser.objects) {
+ QString xml = qDBusGenerateMetaObjectXml(QString(), &mo, &QObject::staticMetaObject,
+ flags);
+ output.write(xml.toLocal8Bit());
+ }
+ output.write("</node>\n");
+
+ return 0;
+}
+
diff --git a/src/qdbus/qdbuscpp2xml/qdbuscpp2xml.pro b/src/qdbus/qdbuscpp2xml/qdbuscpp2xml.pro
new file mode 100644
index 000000000..9ee1d3727
--- /dev/null
+++ b/src/qdbus/qdbuscpp2xml/qdbuscpp2xml.pro
@@ -0,0 +1,10 @@
+SOURCES = qdbuscpp2xml.cpp
+DESTDIR = ../../../bin
+TARGET = qdbuscpp2xml
+QT = core xml
+CONFIG += qdbus
+CONFIG -= app_bundle
+win32:CONFIG += console
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/qdbus/qdbusviewer/Info_mac.plist b/src/qdbus/qdbusviewer/Info_mac.plist
new file mode 100644
index 000000000..b35140997
--- /dev/null
+++ b/src/qdbus/qdbusviewer/Info_mac.plist
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>@ICON@</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.trolltech.dbusviewer</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+</dict>
+</plist>
diff --git a/src/qdbus/qdbusviewer/images/qdbusviewer-128.png b/src/qdbus/qdbusviewer/images/qdbusviewer-128.png
new file mode 100644
index 000000000..075491221
--- /dev/null
+++ b/src/qdbus/qdbusviewer/images/qdbusviewer-128.png
Binary files differ
diff --git a/src/qdbus/qdbusviewer/images/qdbusviewer.icns b/src/qdbus/qdbusviewer/images/qdbusviewer.icns
new file mode 100644
index 000000000..b6f39b9c2
--- /dev/null
+++ b/src/qdbus/qdbusviewer/images/qdbusviewer.icns
Binary files differ
diff --git a/src/qdbus/qdbusviewer/images/qdbusviewer.ico b/src/qdbus/qdbusviewer/images/qdbusviewer.ico
new file mode 100644
index 000000000..49edb09f0
--- /dev/null
+++ b/src/qdbus/qdbusviewer/images/qdbusviewer.ico
Binary files differ
diff --git a/src/qdbus/qdbusviewer/images/qdbusviewer.png b/src/qdbus/qdbusviewer/images/qdbusviewer.png
new file mode 100644
index 000000000..5a8c5a341
--- /dev/null
+++ b/src/qdbus/qdbusviewer/images/qdbusviewer.png
Binary files differ
diff --git a/src/qdbus/qdbusviewer/main.cpp b/src/qdbus/qdbusviewer/main.cpp
new file mode 100644
index 000000000..f3726204c
--- /dev/null
+++ b/src/qdbus/qdbusviewer/main.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qapplication.h>
+#include <QtGui/qmainwindow.h>
+#include <QtGui/qtabwidget.h>
+#include <QtDBus/qdbusconnection.h>
+#include "qdbusviewer.h"
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ QMainWindow mw;
+#ifndef Q_WS_MAC
+ app.setWindowIcon(QIcon(QLatin1String(":/trolltech/qdbusviewer/images/qdbusviewer.png")));
+#else
+ mw.setWindowTitle(qApp->translate("QtDBusViewer", "Qt D-Bus Viewer"));
+#endif
+
+
+ QTabWidget *mainWidget = new QTabWidget;
+ mw.setCentralWidget(mainWidget);
+ QDBusViewer *sessionBusViewer = new QDBusViewer(QDBusConnection::sessionBus());
+ QDBusViewer *systemBusViewer = new QDBusViewer(QDBusConnection::systemBus());
+ mainWidget->addTab(sessionBusViewer, QObject::tr("Session Bus"));
+ mainWidget->addTab(systemBusViewer, QObject::tr("System Bus"));
+
+ QMenu *fileMenu = mw.menuBar()->addMenu(QObject::tr("&File"));
+ QAction *quitAction = fileMenu->addAction(QObject::tr("&Quit"), &mw, SLOT(close()));
+ Q_UNUSED(quitAction);
+
+ QMenu *helpMenu = mw.menuBar()->addMenu(QObject::tr("&Help"));
+ QAction *aboutAction = helpMenu->addAction(QObject::tr("&About"));
+ aboutAction->setMenuRole(QAction::AboutRole);
+ QObject::connect(aboutAction, SIGNAL(triggered()), sessionBusViewer, SLOT(about()));
+
+ QAction *aboutQtAction = helpMenu->addAction(QObject::tr("About &Qt"));
+ aboutQtAction->setMenuRole(QAction::AboutQtRole);
+ QObject::connect(aboutQtAction, SIGNAL(triggered()), &app, SLOT(aboutQt()));
+
+ mw.show();
+
+ return app.exec();
+}
+
diff --git a/src/qdbus/qdbusviewer/propertydialog.cpp b/src/qdbus/qdbusviewer/propertydialog.cpp
new file mode 100644
index 000000000..b2b96df43
--- /dev/null
+++ b/src/qdbus/qdbusviewer/propertydialog.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "propertydialog.h"
+
+#include <QHeaderView>
+#include <QLayout>
+#include <QDebug>
+
+PropertyDialog::PropertyDialog(QWidget *parent, Qt::WindowFlags f)
+ : QDialog(parent, f)
+{
+ buttonBox = new QDialogButtonBox;
+ propertyTable = new QTableWidget;
+ label = new QLabel;
+
+ buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ propertyTable->setColumnCount(2);
+ const QStringList labels = QStringList() << QLatin1String("Name") << QLatin1String("Value");
+ propertyTable->setHorizontalHeaderLabels(labels);
+ propertyTable->horizontalHeader()->setStretchLastSection(true);
+ propertyTable->setEditTriggers(QAbstractItemView::AllEditTriggers);
+
+ connect(buttonBox, SIGNAL(accepted()), SLOT(accept()), Qt::QueuedConnection);
+ connect(buttonBox, SIGNAL(rejected()), SLOT(reject()), Qt::QueuedConnection);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addWidget(label);
+ layout->addWidget(propertyTable);
+ layout->addWidget(buttonBox);
+}
+
+void PropertyDialog::setInfo(const QString &caption)
+{
+ label->setText(caption);
+}
+
+void PropertyDialog::addProperty(const QString &aname, QVariant::Type type)
+{
+ int rowCount = propertyTable->rowCount();
+ propertyTable->setRowCount(rowCount + 1);
+
+ QString name = aname;
+ if (name.isEmpty())
+ name = QLatin1String("argument ") + QString::number(rowCount + 1);
+ name += QLatin1String(" (");
+ name += QLatin1String(QVariant::typeToName(type));
+ name += QLatin1String(")");
+ QTableWidgetItem *nameItem = new QTableWidgetItem(name);
+ nameItem->setFlags(nameItem->flags() &
+ ~(Qt::ItemIsEditable | Qt::ItemIsSelectable));
+ propertyTable->setItem(rowCount, 0, nameItem);
+
+ QTableWidgetItem *valueItem = new QTableWidgetItem;
+ valueItem->setData(Qt::DisplayRole, QVariant(type));
+ propertyTable->setItem(rowCount, 1, valueItem);
+}
+
+int PropertyDialog::exec()
+{
+ propertyTable->resizeColumnToContents(0);
+ propertyTable->setFocus();
+ propertyTable->setCurrentCell(0, 1);
+ return QDialog::exec();
+}
+
+QList<QVariant> PropertyDialog::values() const
+{
+ QList<QVariant> result;
+
+ for (int i = 0; i < propertyTable->rowCount(); ++i)
+ result << propertyTable->item(i, 1)->data(Qt::EditRole);
+
+ return result;
+}
+
diff --git a/src/qdbus/qdbusviewer/propertydialog.h b/src/qdbus/qdbusviewer/propertydialog.h
new file mode 100644
index 000000000..7c002bfe5
--- /dev/null
+++ b/src/qdbus/qdbusviewer/propertydialog.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROPERTYDIALOG_H
+#define PROPERTYDIALOG_H
+
+#include <QLabel>
+#include <QDialog>
+#include <QTableWidget>
+#include <QDialogButtonBox>
+
+class PropertyDialog: public QDialog
+{
+ Q_OBJECT
+public:
+ explicit PropertyDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
+
+ void addProperty(const QString &name, QVariant::Type type);
+ void setInfo(const QString &caption);
+
+ QList<QVariant> values() const;
+
+ int exec();
+
+private:
+ QLabel *label;
+ QTableWidget *propertyTable;
+ QDialogButtonBox *buttonBox;
+};
+
+#endif
+
diff --git a/src/qdbus/qdbusviewer/qdbusmodel.cpp b/src/qdbus/qdbusviewer/qdbusmodel.cpp
new file mode 100644
index 000000000..67ceda2e6
--- /dev/null
+++ b/src/qdbus/qdbusviewer/qdbusmodel.cpp
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdbusmodel.h"
+
+#include <QtCore/qvector.h>
+#include <QtXml/QtXml>
+
+struct QDBusItem
+{
+ inline QDBusItem(QDBusModel::Type aType, const QString &aName, QDBusItem *aParent = 0)
+ : type(aType), parent(aParent), isPrefetched(type != QDBusModel::PathItem), name(aName)
+ {}
+ inline ~QDBusItem()
+ {
+ qDeleteAll(children);
+ }
+
+ QString path() const
+ {
+ Q_ASSERT(type == QDBusModel::PathItem);
+
+ QString s;
+ const QDBusItem *item = this;
+ while (item) {
+ s.prepend(item->name);
+ item = item->parent;
+ }
+ if (s.length() > 1)
+ s.chop(1); // remove tailing slash
+ return s;
+ }
+
+ QDBusModel::Type type;
+ QDBusItem *parent;
+ QVector<QDBusItem *> children;
+ bool isPrefetched;
+ QString name;
+ QString caption;
+ QString typeSignature;
+};
+
+QDomDocument QDBusModel::introspect(const QString &path)
+{
+ QDomDocument doc;
+
+ QDBusInterface iface(service, path, QLatin1String("org.freedesktop.DBus.Introspectable"), c);
+ if (!iface.isValid()) {
+ QDBusError err(iface.lastError());
+ emit busError(QString::fromLatin1("Cannot introspect object %1 at %2:\n %3 (%4)\n").arg(path).arg(
+ service).arg(err.name()).arg(err.message()));
+ return doc;
+ }
+
+ QDBusReply<QString> xml = iface.call(QLatin1String("Introspect"));
+
+ if (!xml.isValid()) {
+ QDBusError err(xml.error());
+ if (err.isValid()) {
+ emit busError(QString::fromLatin1("Call to object %1 at %2:\n %3 (%4) failed\n").arg(
+ path).arg(service).arg(err.name()).arg(err.message()));
+ } else {
+ emit busError(QString::fromLatin1("Invalid XML received from object %1 at %2\n").arg(
+ path).arg(service));
+ }
+ return doc;
+ }
+
+ doc.setContent(xml);
+ return doc;
+}
+
+void QDBusModel::addMethods(QDBusItem *parent, const QDomElement &iface)
+{
+ Q_ASSERT(parent);
+
+ QDomElement child = iface.firstChildElement();
+ while (!child.isNull()) {
+ QDBusItem *item = 0;
+ if (child.tagName() == QLatin1String("method")) {
+ item = new QDBusItem(QDBusModel::MethodItem,
+ child.attribute(QLatin1String("name")), parent);
+ item->caption = QLatin1String("Method: ") + item->name;
+ //get "type" from <arg> where "direction" is "in"
+ QDomElement n = child.firstChildElement();
+ while (!n.isNull()) {
+ if (n.attribute(QLatin1String("direction")) == QLatin1String("in"))
+ item->typeSignature += n.attribute(QLatin1String("type"));
+ n = n.nextSiblingElement();
+ }
+ } else if (child.tagName() == QLatin1String("signal")) {
+ item = new QDBusItem(QDBusModel::SignalItem,
+ child.attribute(QLatin1String("name")), parent);
+ item->caption = QLatin1String("Signal: ") + item->name;
+ } else if (child.tagName() == QLatin1String("property")) {
+ item = new QDBusItem(QDBusModel::PropertyItem,
+ child.attribute(QLatin1String("name")), parent);
+ item->caption = QLatin1String("Property: ") + item->name;
+ } else {
+ qDebug() << "addMethods: unknown tag:" << child.tagName();
+ }
+ if (item)
+ parent->children.append(item);
+
+ child = child.nextSiblingElement();
+ }
+}
+
+void QDBusModel::addPath(QDBusItem *parent)
+{
+ Q_ASSERT(parent);
+
+ QString path = parent->path();
+
+ QDomDocument doc = introspect(path);
+ QDomElement node = doc.documentElement();
+ QDomElement child = node.firstChildElement();
+ while (!child.isNull()) {
+ if (child.tagName() == QLatin1String("node")) {
+ QDBusItem *item = new QDBusItem(QDBusModel::PathItem,
+ child.attribute(QLatin1String("name")) + QLatin1Char('/'), parent);
+ parent->children.append(item);
+
+ addMethods(item, child);
+ } else if (child.tagName() == QLatin1String("interface")) {
+ QDBusItem *item = new QDBusItem(QDBusModel::InterfaceItem,
+ child.attribute(QLatin1String("name")), parent);
+ parent->children.append(item);
+
+ addMethods(item, child);
+ } else {
+ qDebug() << "addPath: Unknown tag name:" << child.tagName();
+ }
+ child = child.nextSiblingElement();
+ }
+
+ parent->isPrefetched = true;
+}
+
+QDBusModel::QDBusModel(const QString &aService, const QDBusConnection &connection)
+ : service(aService), c(connection), root(0)
+{
+ root = new QDBusItem(QDBusModel::PathItem, QLatin1String("/"));
+}
+
+QDBusModel::~QDBusModel()
+{
+ delete root;
+}
+
+QModelIndex QDBusModel::index(int row, int column, const QModelIndex &parent) const
+{
+ const QDBusItem *item = static_cast<QDBusItem *>(parent.internalPointer());
+ if (!item)
+ item = root;
+
+ if (column != 0 || row < 0 || row >= item->children.count())
+ return QModelIndex();
+
+ return createIndex(row, 0, item->children.at(row));
+}
+
+QModelIndex QDBusModel::parent(const QModelIndex &child) const
+{
+ QDBusItem *item = static_cast<QDBusItem *>(child.internalPointer());
+ if (!item || !item->parent || !item->parent->parent)
+ return QModelIndex();
+
+ return createIndex(item->parent->parent->children.indexOf(item->parent), 0, item->parent);
+}
+
+int QDBusModel::rowCount(const QModelIndex &parent) const
+{
+ QDBusItem *item = static_cast<QDBusItem *>(parent.internalPointer());
+ if (!item)
+ item = root;
+ if (!item->isPrefetched)
+ const_cast<QDBusModel *>(this)->addPath(item);
+
+ return item->children.count();
+}
+
+int QDBusModel::columnCount(const QModelIndex &) const
+{
+ return 1;
+}
+
+QVariant QDBusModel::data(const QModelIndex &index, int role) const
+{
+ const QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ if (!item)
+ return QVariant();
+
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ return item->caption.isEmpty() ? item->name : item->caption;
+}
+
+QVariant QDBusModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role != Qt::DisplayRole || orientation == Qt::Vertical || section != 0)
+ return QVariant();
+
+ return QLatin1String("Methods");
+}
+
+QDBusModel::Type QDBusModel::itemType(const QModelIndex &index) const
+{
+ const QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ return item ? item->type : PathItem;
+}
+
+void QDBusModel::refresh(const QModelIndex &aIndex)
+{
+ QModelIndex index = aIndex;
+ while (index.isValid() && static_cast<QDBusItem *>(index.internalPointer())->type != PathItem) {
+ index = index.parent();
+ }
+
+ QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ if (!item)
+ item = root;
+
+ if (!item->children.isEmpty()) {
+ beginRemoveRows(index, 0, item->children.count() - 1);
+ qDeleteAll(item->children);
+ item->children.clear();
+ endRemoveRows();
+ }
+
+ addPath(item);
+ if (!item->children.isEmpty()) {
+ beginInsertRows(index, 0, item->children.count() - 1);
+ endInsertRows();
+ }
+}
+
+QString QDBusModel::dBusPath(const QModelIndex &aIndex) const
+{
+ QModelIndex index = aIndex;
+ while (index.isValid() && static_cast<QDBusItem *>(index.internalPointer())->type != PathItem) {
+ index = index.parent();
+ }
+
+ QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ if (!item)
+ item = root;
+
+ return item->path();
+}
+
+QString QDBusModel::dBusInterface(const QModelIndex &index) const
+{
+ QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ if (!item)
+ return QString();
+ if (item->type == InterfaceItem)
+ return item->name;
+ if (item->parent && item->parent->type == InterfaceItem)
+ return item->parent->name;
+ return QString();
+}
+
+QString QDBusModel::dBusMethodName(const QModelIndex &index) const
+{
+ QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ return item ? item->name : QString();
+}
+
+QString QDBusModel::dBusTypeSignature(const QModelIndex &index) const
+{
+ QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ return item ? item->typeSignature : QString();
+}
+
+QModelIndex QDBusModel::findObject(const QDBusObjectPath &objectPath)
+{
+ QStringList path = objectPath.path().split(QLatin1Char('/'), QString::SkipEmptyParts);
+
+ QDBusItem *item = root;
+ int childIdx = -1;
+ while (item && !path.isEmpty()) {
+ const QString branch = path.takeFirst() + QLatin1Char('/');
+ childIdx = -1;
+
+ // do a linear search over all the children
+ for (int i = 0; i < item->children.count(); ++i) {
+ QDBusItem *child = item->children.at(i);
+ if (child->type == PathItem && child->name == branch) {
+ item = child;
+ childIdx = i;
+
+ // prefetch the found branch
+ if (!item->isPrefetched)
+ addPath(item);
+ break;
+ }
+ }
+
+ // branch not found - bail out
+ if (childIdx == -1)
+ return QModelIndex();
+ }
+
+ // found the right item
+ if (childIdx != -1 && item && path.isEmpty())
+ return createIndex(childIdx, 0, item);
+
+ return QModelIndex();
+}
+
diff --git a/src/qdbus/qdbusviewer/qdbusmodel.h b/src/qdbus/qdbusviewer/qdbusmodel.h
new file mode 100644
index 000000000..726499ab3
--- /dev/null
+++ b/src/qdbus/qdbusviewer/qdbusmodel.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDBUSMODEL_H
+#define QDBUSMODEL_H
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtDBus/QtDBus>
+
+struct QDBusItem;
+
+QT_FORWARD_DECLARE_CLASS(QDomDocument);
+QT_FORWARD_DECLARE_CLASS(QDomElement);
+
+
+class QDBusModel: public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ enum Type { InterfaceItem, PathItem, MethodItem, SignalItem, PropertyItem };
+
+ QDBusModel(const QString &service, const QDBusConnection &connection);
+ ~QDBusModel();
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &child) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
+ Type itemType(const QModelIndex &index) const;
+ QString dBusPath(const QModelIndex &index) const;
+ QString dBusInterface(const QModelIndex &index) const;
+ QString dBusMethodName(const QModelIndex &index) const;
+ QString dBusTypeSignature(const QModelIndex &index) const;
+
+ void refresh(const QModelIndex &index = QModelIndex());
+
+ QModelIndex findObject(const QDBusObjectPath &objectPath);
+
+Q_SIGNALS:
+ void busError(const QString &text);
+
+private:
+ QDomDocument introspect(const QString &path);
+ void addMethods(QDBusItem *parent, const QDomElement &iface);
+ void addPath(QDBusItem *parent);
+
+ QString service;
+ QDBusConnection c;
+ QDBusItem *root;
+};
+
+#endif
+
diff --git a/src/qdbus/qdbusviewer/qdbusviewer.cpp b/src/qdbus/qdbusviewer/qdbusviewer.cpp
new file mode 100644
index 000000000..cab109386
--- /dev/null
+++ b/src/qdbus/qdbusviewer/qdbusviewer.cpp
@@ -0,0 +1,521 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdbusviewer.h"
+#include "qdbusmodel.h"
+#include "propertydialog.h"
+
+#include <QtXml/QtXml>
+#include <QtDBus/private/qdbusutil_p.h>
+
+class QDBusViewModel: public QDBusModel
+{
+public:
+ inline QDBusViewModel(const QString &service, const QDBusConnection &connection)
+ : QDBusModel(service, connection)
+ {}
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
+ {
+ if (role == Qt::FontRole && itemType(index) == InterfaceItem) {
+ QFont f;
+ f.setItalic(true);
+ return f;
+ }
+ return QDBusModel::data(index, role);
+ }
+};
+
+QDBusViewer::QDBusViewer(const QDBusConnection &connection, QWidget *parent) :
+ QWidget(parent),
+ c(connection),
+ objectPathRegExp(QLatin1String("\\[ObjectPath: (.*)\\]"))
+{
+ servicesModel = new QStringListModel(this);
+ servicesFilterModel = new QSortFilterProxyModel(this);
+ servicesFilterModel->setSourceModel(servicesModel);
+ servicesFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ serviceFilterLine = new QLineEdit(this);
+ serviceFilterLine->setPlaceholderText(tr("Search..."));
+ servicesView = new QListView(this);
+ servicesView->setModel(servicesFilterModel);
+
+ connect(serviceFilterLine, SIGNAL(textChanged(QString)), servicesFilterModel, SLOT(setFilterFixedString(QString)));
+
+ tree = new QTreeView;
+ tree->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(tree, SIGNAL(activated(QModelIndex)), this, SLOT(activate(QModelIndex)));
+
+ refreshAction = new QAction(tr("&Refresh"), tree);
+ refreshAction->setData(42); // increase the amount of 42 used as magic number by one
+ refreshAction->setShortcut(QKeySequence::Refresh);
+ connect(refreshAction, SIGNAL(triggered()), this, SLOT(refreshChildren()));
+
+ QShortcut *refreshShortcut = new QShortcut(QKeySequence::Refresh, tree);
+ connect(refreshShortcut, SIGNAL(activated()), this, SLOT(refreshChildren()));
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QSplitter *topSplitter = new QSplitter(Qt::Vertical, this);
+ layout->addWidget(topSplitter);
+
+ log = new QTextBrowser;
+ connect(log, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl)));
+
+ QSplitter *splitter = new QSplitter(topSplitter);
+ splitter->addWidget(servicesView);
+
+ QWidget *servicesWidget = new QWidget;
+ QVBoxLayout *servicesLayout = new QVBoxLayout(servicesWidget);
+ servicesLayout->addWidget(serviceFilterLine);
+ servicesLayout->addWidget(servicesView);
+ splitter->addWidget(servicesWidget);
+ splitter->addWidget(tree);
+
+ topSplitter->addWidget(splitter);
+ topSplitter->addWidget(log);
+
+ connect(servicesView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(serviceChanged(QModelIndex)));
+ connect(tree, SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(showContextMenu(QPoint)));
+
+ QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
+
+ if (c.isConnected()) {
+ logMessage(QLatin1String("Connected to D-Bus."));
+ QDBusConnectionInterface *iface = c.interface();
+ connect(iface, SIGNAL(serviceRegistered(QString)),
+ this, SLOT(serviceRegistered(QString)));
+ connect(iface, SIGNAL(serviceUnregistered(QString)),
+ this, SLOT(serviceUnregistered(QString)));
+ connect(iface, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
+ this, SLOT(serviceOwnerChanged(QString,QString,QString)));
+ } else {
+ logError(QLatin1String("Cannot connect to D-Bus: ") + c.lastError().message());
+ }
+
+ objectPathRegExp.setMinimal(true);
+
+}
+
+void QDBusViewer::logMessage(const QString &msg)
+{
+ log->append(msg + QLatin1Char('\n'));
+}
+
+void QDBusViewer::logError(const QString &msg)
+{
+ log->append(QLatin1String("<font color=\"red\">Error: </font>") + Qt::escape(msg) + QLatin1String("<br>"));
+}
+
+void QDBusViewer::refresh()
+{
+ servicesModel->removeRows(0, servicesModel->rowCount());
+
+ if (c.isConnected()) {
+ const QStringList serviceNames = c.interface()->registeredServiceNames();
+ servicesModel->setStringList(serviceNames);
+ }
+}
+
+void QDBusViewer::activate(const QModelIndex &item)
+{
+ if (!item.isValid())
+ return;
+
+ const QDBusModel *model = static_cast<const QDBusModel *>(item.model());
+
+ BusSignature sig;
+ sig.mService = currentService;
+ sig.mPath = model->dBusPath(item);
+ sig.mInterface = model->dBusInterface(item);
+ sig.mName = model->dBusMethodName(item);
+ sig.mTypeSig = model->dBusTypeSignature(item);
+
+ switch (model->itemType(item)) {
+ case QDBusModel::SignalItem:
+ connectionRequested(sig);
+ break;
+ case QDBusModel::MethodItem:
+ callMethod(sig);
+ break;
+ case QDBusModel::PropertyItem:
+ getProperty(sig);
+ break;
+ default:
+ break;
+ }
+}
+
+void QDBusViewer::getProperty(const BusSignature &sig)
+{
+ QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get"));
+ QList<QVariant> arguments;
+ arguments << sig.mInterface << sig.mName;
+ message.setArguments(arguments);
+ c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage)));
+}
+
+void QDBusViewer::setProperty(const BusSignature &sig)
+{
+ QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c);
+ QMetaProperty prop = iface.metaObject()->property(iface.metaObject()->indexOfProperty(sig.mName.toLatin1()));
+
+ bool ok;
+ QString input = QInputDialog::getText(this, tr("Arguments"),
+ tr("Please enter the value of the property %1 (type %2)").arg(
+ sig.mName, QString::fromLatin1(prop.typeName())),
+ QLineEdit::Normal, QString(), &ok);
+ if (!ok)
+ return;
+
+ QVariant value = input;
+ if (!value.convert(prop.type())) {
+ QMessageBox::warning(this, tr("Unable to marshall"),
+ tr("Value conversion failed, unable to set property"));
+ return;
+ }
+
+ QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Set"));
+ QList<QVariant> arguments;
+ arguments << sig.mInterface << sig.mName << QVariant::fromValue(QDBusVariant(value));
+ message.setArguments(arguments);
+ c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage)));
+
+}
+
+static QString getDbusSignature(const QMetaMethod& method)
+{
+ // create a D-Bus type signature from QMetaMethod's parameters
+ QString sig;
+ for (int i = 0; i < method.parameterTypes().count(); ++i) {
+ QVariant::Type type = QVariant::nameToType(method.parameterTypes().at(i));
+ sig.append(QString::fromLatin1(QDBusMetaType::typeToSignature(type)));
+ }
+ return sig;
+}
+
+void QDBusViewer::callMethod(const BusSignature &sig)
+{
+ QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c);
+ const QMetaObject *mo = iface.metaObject();
+
+ // find the method
+ QMetaMethod method;
+ for (int i = 0; i < mo->methodCount(); ++i) {
+ const QString signature = QString::fromLatin1(mo->method(i).signature());
+ if (signature.startsWith(sig.mName) && signature.at(sig.mName.length()) == QLatin1Char('('))
+ if (getDbusSignature(mo->method(i)) == sig.mTypeSig)
+ method = mo->method(i);
+ }
+ if (!method.signature()) {
+ QMessageBox::warning(this, tr("Unable to find method"),
+ tr("Unable to find method %1 on path %2 in interface %3").arg(
+ sig.mName).arg(sig.mPath).arg(sig.mInterface));
+ return;
+ }
+
+ PropertyDialog dialog;
+ QList<QVariant> args;
+
+ const QList<QByteArray> paramTypes = method.parameterTypes();
+ const QList<QByteArray> paramNames = method.parameterNames();
+ QList<int> types; // remember the low-level D-Bus type
+ for (int i = 0; i < paramTypes.count(); ++i) {
+ const QByteArray paramType = paramTypes.at(i);
+ if (paramType.endsWith('&'))
+ continue; // ignore OUT parameters
+
+ QVariant::Type type = QVariant::nameToType(paramType);
+ dialog.addProperty(QString::fromLatin1(paramNames.value(i)), type);
+ types.append(QMetaType::type(paramType));
+ }
+
+ if (!types.isEmpty()) {
+ dialog.setInfo(tr("Please enter parameters for the method \"%1\"").arg(sig.mName));
+
+ if (dialog.exec() != QDialog::Accepted)
+ return;
+
+ args = dialog.values();
+ }
+
+ // Special case - convert a value to a QDBusVariant if the
+ // interface wants a variant
+ for (int i = 0; i < args.count(); ++i) {
+ if (types.at(i) == qMetaTypeId<QDBusVariant>())
+ args[i] = QVariant::fromValue(QDBusVariant(args.at(i)));
+ }
+
+ QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, sig.mInterface,
+ sig.mName);
+ message.setArguments(args);
+ c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage)));
+}
+
+void QDBusViewer::showContextMenu(const QPoint &point)
+{
+ QModelIndex item = tree->indexAt(point);
+ if (!item.isValid())
+ return;
+
+ const QDBusModel *model = static_cast<const QDBusModel *>(item.model());
+
+ BusSignature sig;
+ sig.mService = currentService;
+ sig.mPath = model->dBusPath(item);
+ sig.mInterface = model->dBusInterface(item);
+ sig.mName = model->dBusMethodName(item);
+ sig.mTypeSig = model->dBusTypeSignature(item);
+
+ QMenu menu;
+ menu.addAction(refreshAction);
+
+ switch (model->itemType(item)) {
+ case QDBusModel::SignalItem: {
+ QAction *action = new QAction(tr("&Connect"), &menu);
+ action->setData(1);
+ menu.addAction(action);
+ break; }
+ case QDBusModel::MethodItem: {
+ QAction *action = new QAction(tr("&Call"), &menu);
+ action->setData(2);
+ menu.addAction(action);
+ break; }
+ case QDBusModel::PropertyItem: {
+ QAction *actionSet = new QAction(tr("&Set value"), &menu);
+ actionSet->setData(3);
+ QAction *actionGet = new QAction(tr("&Get value"), &menu);
+ actionGet->setData(4);
+ menu.addAction(actionSet);
+ menu.addAction(actionGet);
+ break; }
+ default:
+ break;
+ }
+
+ QAction *selectedAction = menu.exec(tree->viewport()->mapToGlobal(point));
+ if (!selectedAction)
+ return;
+
+ switch (selectedAction->data().toInt()) {
+ case 1:
+ connectionRequested(sig);
+ break;
+ case 2:
+ callMethod(sig);
+ break;
+ case 3:
+ setProperty(sig);
+ break;
+ case 4:
+ getProperty(sig);
+ break;
+ }
+}
+
+void QDBusViewer::connectionRequested(const BusSignature &sig)
+{
+ if (!c.connect(sig.mService, QString(), sig.mInterface, sig.mName, this,
+ SLOT(dumpMessage(QDBusMessage)))) {
+ logError(tr("Unable to connect to service %1, path %2, interface %3, signal %4").arg(
+ sig.mService).arg(sig.mPath).arg(sig.mInterface).arg(sig.mName));
+ }
+}
+
+void QDBusViewer::dumpMessage(const QDBusMessage &message)
+{
+ QList<QVariant> args = message.arguments();
+ QString out = QLatin1String("Received ");
+
+ switch (message.type()) {
+ case QDBusMessage::SignalMessage:
+ out += QLatin1String("signal ");
+ break;
+ case QDBusMessage::ErrorMessage:
+ out += QLatin1String("error message ");
+ break;
+ case QDBusMessage::ReplyMessage:
+ out += QLatin1String("reply ");
+ break;
+ default:
+ out += QLatin1String("message ");
+ break;
+ }
+
+ out += QLatin1String("from ");
+ out += message.service();
+ if (!message.path().isEmpty())
+ out += QLatin1String(", path ") + message.path();
+ if (!message.interface().isEmpty())
+ out += QLatin1String(", interface <i>") + message.interface() + QLatin1String("</i>");
+ if (!message.member().isEmpty())
+ out += QLatin1String(", member ") + message.member();
+ out += QLatin1String("<br>");
+ if (args.isEmpty()) {
+ out += QLatin1String("&nbsp;&nbsp;(no arguments)");
+ } else {
+ out += QLatin1String("&nbsp;&nbsp;Arguments: ");
+ foreach (QVariant arg, args) {
+ QString str = Qt::escape(QDBusUtil::argumentToString(arg));
+ // turn object paths into clickable links
+ str.replace(objectPathRegExp, QLatin1String("[ObjectPath: <a href=\"qdbus://bus\\1\">\\1</a>]"));
+ out += str;
+ out += QLatin1String(", ");
+ }
+ out.chop(2);
+ }
+
+ log->append(out);
+}
+
+void QDBusViewer::serviceChanged(const QModelIndex &index)
+{
+ delete tree->model();
+
+ currentService.clear();
+ if (!index.isValid())
+ return;
+ currentService = index.data().toString();
+
+ tree->setModel(new QDBusViewModel(currentService, c));
+ connect(tree->model(), SIGNAL(busError(QString)), this, SLOT(logError(QString)));
+}
+
+void QDBusViewer::serviceRegistered(const QString &service)
+{
+ if (service == c.baseService())
+ return;
+
+ servicesModel->insertRows(0, 1);
+ servicesModel->setData(servicesModel->index(0, 0), service);
+}
+
+static QModelIndex findItem(QStringListModel *servicesModel, const QString &name)
+{
+ QModelIndexList hits = servicesModel->match(servicesModel->index(0, 0), Qt::DisplayRole, name);
+ if (hits.isEmpty())
+ return QModelIndex();
+
+ return hits.first();
+}
+
+void QDBusViewer::serviceUnregistered(const QString &name)
+{
+ QModelIndex hit = findItem(servicesModel, name);
+ if (!hit.isValid())
+ return;
+ servicesModel->removeRows(hit.row(), 1);
+}
+
+void QDBusViewer::serviceOwnerChanged(const QString &name, const QString &oldOwner,
+ const QString &newOwner)
+{
+ QModelIndex hit = findItem(servicesModel, name);
+
+ if (!hit.isValid() && oldOwner.isEmpty() && !newOwner.isEmpty())
+ serviceRegistered(name);
+ else if (hit.isValid() && !oldOwner.isEmpty() && newOwner.isEmpty())
+ servicesModel->removeRows(hit.row(), 1);
+ else if (hit.isValid() && !oldOwner.isEmpty() && !newOwner.isEmpty()) {
+ servicesModel->removeRows(hit.row(), 1);
+ serviceRegistered(name);
+ }
+}
+
+void QDBusViewer::refreshChildren()
+{
+ QDBusModel *model = qobject_cast<QDBusModel *>(tree->model());
+ if (!model)
+ return;
+ model->refresh(tree->currentIndex());
+}
+
+void QDBusViewer::about()
+{
+ QMessageBox box(this);
+
+ box.setText(QString::fromLatin1("<center><img src=\":/trolltech/qdbusviewer/images/qdbusviewer-128.png\">"
+ "<h3>%1</h3>"
+ "<p>Version %2</p></center>"
+ "<p>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).</p>")
+ .arg(tr("D-Bus Viewer")).arg(QLatin1String(QT_VERSION_STR)));
+ box.setWindowTitle(tr("D-Bus Viewer"));
+ box.exec();
+}
+
+void QDBusViewer::anchorClicked(const QUrl &url)
+{
+ if (url.scheme() != QLatin1String("qdbus"))
+ // not ours
+ return;
+
+ // swallow the click without setting a new document
+ log->setSource(QUrl());
+
+ QDBusModel *model = qobject_cast<QDBusModel *>(tree->model());
+ if (!model)
+ return;
+
+ QModelIndex idx = model->findObject(QDBusObjectPath(url.path()));
+ if (!idx.isValid())
+ return;
+
+ tree->scrollTo(idx);
+ tree->setCurrentIndex(idx);
+}
+
+/*!
+ \page qdbusviewer.html
+ \title D-Bus Viewer
+ \keyword qdbusviewer
+
+ The Qt D-Bus Viewer is a tool that lets you introspect D-Bus objects and messages. You can
+ choose between the system bus and the session bus. Click on any service on the list
+ on the left side to see all the exported objects.
+
+ You can invoke methods by double-clicking on them. If a method takes one or more IN parameters,
+ a property editor opens.
+
+ Right-click on a signal to connect to it. All emitted signals including their parameters
+ are output in the message view on the lower side of the window.
+*/
diff --git a/src/qdbus/qdbusviewer/qdbusviewer.h b/src/qdbus/qdbusviewer/qdbusviewer.h
new file mode 100644
index 000000000..19777882c
--- /dev/null
+++ b/src/qdbus/qdbusviewer/qdbusviewer.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDBUSVIEWER_H
+#define QDBUSVIEWER_H
+
+#include <QtGui/QtGui>
+#include <QtDBus/QtDBus>
+
+QT_FORWARD_DECLARE_CLASS(QTreeView);
+QT_FORWARD_DECLARE_CLASS(QDomDocument);
+QT_FORWARD_DECLARE_CLASS(QDomElement);
+
+struct BusSignature
+{
+ QString mService, mPath, mInterface, mName;
+ QString mTypeSig;
+};
+
+class QDBusViewer: public QWidget
+{
+ Q_OBJECT
+public:
+ QDBusViewer(const QDBusConnection &connection, QWidget *parent = 0);
+
+public slots:
+ void refresh();
+ void about();
+
+private slots:
+ void serviceChanged(const QModelIndex &index);
+ void showContextMenu(const QPoint &);
+ void connectionRequested(const BusSignature &sig);
+ void callMethod(const BusSignature &sig);
+ void getProperty(const BusSignature &sig);
+ void setProperty(const BusSignature &sig);
+ void dumpMessage(const QDBusMessage &msg);
+ void refreshChildren();
+
+ void serviceRegistered(const QString &service);
+ void serviceUnregistered(const QString &service);
+ void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
+
+ void activate(const QModelIndex &item);
+
+ void logError(const QString &msg);
+ void anchorClicked(const QUrl &url);
+
+private:
+ void logMessage(const QString &msg);
+
+ QDBusConnection c;
+ QString currentService;
+ QTreeView *tree;
+ QAction *refreshAction;
+ QTreeWidget *services;
+ QStringListModel *servicesModel;
+ QSortFilterProxyModel *servicesFilterModel;
+ QLineEdit *serviceFilterLine;
+ QListView *servicesView;
+ QTextBrowser *log;
+ QRegExp objectPathRegExp;
+};
+
+#endif
diff --git a/src/qdbus/qdbusviewer/qdbusviewer.pro b/src/qdbus/qdbusviewer/qdbusviewer.pro
new file mode 100644
index 000000000..6727691c1
--- /dev/null
+++ b/src/qdbus/qdbusviewer/qdbusviewer.pro
@@ -0,0 +1,30 @@
+TEMPLATE = app
+TARGET = qdbusviewer
+
+HEADERS = qdbusviewer.h \
+ qdbusmodel.h \
+ propertydialog.h
+
+SOURCES = qdbusviewer.cpp \
+ qdbusmodel.cpp \
+ propertydialog.cpp \
+ main.cpp
+
+RESOURCES += qdbusviewer.qrc
+
+DESTDIR = ../../../bin
+
+CONFIG += qdbus
+QT += xml
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+mac {
+ ICON = images/qdbusviewer.icns
+ QMAKE_INFO_PLIST = Info_mac.plist
+}
+
+win32 {
+ RC_FILE = qdbusviewer.rc
+}
diff --git a/src/qdbus/qdbusviewer/qdbusviewer.qrc b/src/qdbus/qdbusviewer/qdbusviewer.qrc
new file mode 100644
index 000000000..7d592f32c
--- /dev/null
+++ b/src/qdbus/qdbusviewer/qdbusviewer.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/trolltech/qdbusviewer" >
+ <file>images/qdbusviewer-128.png</file>
+ <file>images/qdbusviewer.png</file>
+ </qresource>
+</RCC>
diff --git a/src/qdbus/qdbusviewer/qdbusviewer.rc b/src/qdbus/qdbusviewer/qdbusviewer.rc
new file mode 100644
index 000000000..c4b1d60b8
--- /dev/null
+++ b/src/qdbus/qdbusviewer/qdbusviewer.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "images/qdbusviewer.ico"
diff --git a/src/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
new file mode 100644
index 000000000..cfe848ef1
--- /dev/null
+++ b/src/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -0,0 +1,1144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qtextstream.h>
+#include <QtCore/qset.h>
+
+#include <QtDBus/QtDBus>
+#include "private/qdbusmetaobject_p.h"
+#include "private/qdbusintrospection_p.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define PROGRAMNAME "qdbusxml2cpp"
+#define PROGRAMVERSION "0.7"
+#define PROGRAMCOPYRIGHT "Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+
+#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
+
+static QString globalClassName;
+static QString parentClassName;
+static QString proxyFile;
+static QString adaptorFile;
+static QString inputFile;
+static bool skipNamespaces;
+static bool verbose;
+static bool includeMocs;
+static QString commandLine;
+static QStringList includes;
+static QStringList wantedInterfaces;
+
+static const char help[] =
+ "Usage: " PROGRAMNAME " [options...] [xml-or-xml-file] [interfaces...]\n"
+ "Produces the C++ code to implement the interfaces defined in the input file.\n"
+ "\n"
+ "Options:\n"
+ " -a <filename> Write the adaptor code to <filename>\n"
+ " -c <classname> Use <classname> as the class name for the generated classes\n"
+ " -h Show this information\n"
+ " -i <filename> Add #include to the output\n"
+ " -l <classname> When generating an adaptor, use <classname> as the parent class\n"
+ " -m Generate #include \"filename.moc\" statements in the .cpp files\n"
+ " -N Don't use namespaces\n"
+ " -p <filename> Write the proxy code to <filename>\n"
+ " -v Be verbose.\n"
+ " -V Show the program version and quit.\n"
+ "\n"
+ "If the file name given to the options -a and -p does not end in .cpp or .h, the\n"
+ "program will automatically append the suffixes and produce both files.\n"
+ "You can also use a colon (:) to separate the header name from the source file\n"
+ "name, as in '-a filename_p.h:filename.cpp'.\n"
+ "\n"
+ "If you pass a dash (-) as the argument to either -p or -a, the output is written\n"
+ "to the standard output\n";
+
+static const char includeList[] =
+ "#include <QtCore/QByteArray>\n"
+ "#include <QtCore/QList>\n"
+ "#include <QtCore/QMap>\n"
+ "#include <QtCore/QString>\n"
+ "#include <QtCore/QStringList>\n"
+ "#include <QtCore/QVariant>\n";
+
+static const char forwardDeclarations[] =
+ "class QByteArray;\n"
+ "template<class T> class QList;\n"
+ "template<class Key, class Value> class QMap;\n"
+ "class QString;\n"
+ "class QStringList;\n"
+ "class QVariant;\n";
+
+static void showHelp()
+{
+ printf("%s", help);
+ exit(0);
+}
+
+static void showVersion()
+{
+ printf("%s version %s\n", PROGRAMNAME, PROGRAMVERSION);
+ printf("D-Bus binding tool for Qt\n");
+ exit(0);
+}
+
+static QString nextArg(QStringList &args, int i, char opt)
+{
+ QString arg = args.value(i);
+ if (arg.isEmpty()) {
+ printf("-%c needs at least one argument\n", opt);
+ exit(1);
+ }
+ return args.takeAt(i);
+}
+
+static void parseCmdLine(QStringList args)
+{
+ args.takeFirst();
+
+ commandLine = QLatin1String(PROGRAMNAME " ");
+ commandLine += args.join(QLatin1String(" "));
+
+ int i = 0;
+ while (i < args.count()) {
+
+ if (!args.at(i).startsWith(QLatin1Char('-'))) {
+ ++i;
+ continue;
+ }
+ QString arg = args.takeAt(i);
+
+ char c = '\0';
+ if (arg.length() == 2)
+ c = arg.at(1).toLatin1();
+ else if (arg == QLatin1String("--help"))
+ c = 'h';
+
+ switch (c) {
+ case 'a':
+ adaptorFile = nextArg(args, i, 'a');
+ break;
+
+ case 'c':
+ globalClassName = nextArg(args, i, 'c');
+ break;
+
+ case 'v':
+ verbose = true;
+ break;
+
+ case 'i':
+ includes << nextArg(args, i, 'i');
+ break;
+
+ case 'l':
+ parentClassName = nextArg(args, i, 'l');
+ break;
+
+ case 'm':
+ includeMocs = true;
+ break;
+
+ case 'N':
+ skipNamespaces = true;
+ break;
+
+ case '?':
+ case 'h':
+ showHelp();
+ break;
+
+ case 'V':
+ showVersion();
+ break;
+
+ case 'p':
+ proxyFile = nextArg(args, i, 'p');
+ break;
+
+ default:
+ printf("unknown option: '%s'\n", qPrintable(arg));
+ exit(1);
+ }
+ }
+
+ if (!args.isEmpty())
+ inputFile = args.takeFirst();
+
+ wantedInterfaces << args;
+}
+
+static QDBusIntrospection::Interfaces readInput()
+{
+ QFile input(inputFile);
+ if (inputFile.isEmpty() || inputFile == QLatin1String("-"))
+ input.open(stdin, QIODevice::ReadOnly);
+ else
+ input.open(QIODevice::ReadOnly);
+
+ QByteArray data = input.readAll();
+
+ // check if the input is already XML
+ data = data.trimmed();
+ if (data.startsWith("<!DOCTYPE ") || data.startsWith("<?xml") ||
+ data.startsWith("<node") || data.startsWith("<interface"))
+ // already XML
+ return QDBusIntrospection::parseInterfaces(QString::fromUtf8(data));
+
+ fprintf(stderr, "Cannot process input: '%s'. Stop.\n", qPrintable(inputFile));
+ exit(1);
+}
+
+static void cleanInterfaces(QDBusIntrospection::Interfaces &interfaces)
+{
+ if (!wantedInterfaces.isEmpty()) {
+ QDBusIntrospection::Interfaces::Iterator it = interfaces.begin();
+ while (it != interfaces.end())
+ if (!wantedInterfaces.contains(it.key()))
+ it = interfaces.erase(it);
+ else
+ ++it;
+ }
+}
+
+// produce a header name from the file name
+static QString header(const QString &name)
+{
+ QStringList parts = name.split(QLatin1Char(':'));
+ QString retval = parts.first();
+
+ if (retval.isEmpty() || retval == QLatin1String("-"))
+ return retval;
+
+ if (!retval.endsWith(QLatin1String(".h")) && !retval.endsWith(QLatin1String(".cpp")) &&
+ !retval.endsWith(QLatin1String(".cc")))
+ retval.append(QLatin1String(".h"));
+
+ return retval;
+}
+
+// produce a cpp name from the file name
+static QString cpp(const QString &name)
+{
+ QStringList parts = name.split(QLatin1Char(':'));
+ QString retval = parts.last();
+
+ if (retval.isEmpty() || retval == QLatin1String("-"))
+ return retval;
+
+ if (!retval.endsWith(QLatin1String(".h")) && !retval.endsWith(QLatin1String(".cpp")) &&
+ !retval.endsWith(QLatin1String(".cc")))
+ retval.append(QLatin1String(".cpp"));
+
+ return retval;
+}
+
+// produce a moc name from the file name
+static QString moc(const QString &name)
+{
+ QString retval = header(name);
+ if (retval.isEmpty())
+ return retval;
+
+ retval.truncate(retval.length() - 1); // drop the h in .h
+ retval += QLatin1String("moc");
+ return retval;
+}
+
+static QTextStream &writeHeader(QTextStream &ts, bool changesWillBeLost)
+{
+ ts << "/*" << endl
+ << " * This file was generated by " PROGRAMNAME " version " PROGRAMVERSION << endl
+ << " * Command line was: " << commandLine << endl
+ << " *" << endl
+ << " * " PROGRAMNAME " is " PROGRAMCOPYRIGHT << endl
+ << " *" << endl
+ << " * This is an auto-generated file." << endl;
+
+ if (changesWillBeLost)
+ ts << " * Do not edit! All changes made to it will be lost." << endl;
+ else
+ ts << " * This file may have been hand-edited. Look for HAND-EDIT comments" << endl
+ << " * before re-generating it." << endl;
+
+ ts << " */" << endl
+ << endl;
+
+ return ts;
+}
+
+enum ClassType { Proxy, Adaptor };
+static QString classNameForInterface(const QString &interface, ClassType classType)
+{
+ if (!globalClassName.isEmpty())
+ return globalClassName;
+
+ QStringList parts = interface.split(QLatin1Char('.'));
+
+ QString retval;
+ if (classType == Proxy)
+ foreach (QString part, parts) {
+ part[0] = part[0].toUpper();
+ retval += part;
+ }
+ else {
+ retval = parts.last();
+ retval[0] = retval[0].toUpper();
+ }
+
+ if (classType == Proxy)
+ retval += QLatin1String("Interface");
+ else
+ retval += QLatin1String("Adaptor");
+
+ return retval;
+}
+
+static QByteArray qtTypeName(const QString &signature, const QDBusIntrospection::Annotations &annotations, int paramId = -1, const char *direction = "Out")
+{
+ int type = QDBusMetaType::signatureToType(signature.toLatin1());
+ if (type == QVariant::Invalid) {
+ QString annotationName = QString::fromLatin1("com.trolltech.QtDBus.QtTypeName");
+ if (paramId >= 0)
+ annotationName += QString::fromLatin1(".%1%2").arg(QLatin1String(direction)).arg(paramId);
+ QString qttype = annotations.value(annotationName);
+ if (!qttype.isEmpty())
+ return qttype.toLatin1();
+
+ fprintf(stderr, "Got unknown type `%s'\n", qPrintable(signature));
+ fprintf(stderr, "You should add <annotation name=\"%s\" value=\"<type>\"/> to the XML description\n",
+ qPrintable(annotationName));
+ exit(1);
+ }
+
+ return QVariant::typeToName(QVariant::Type(type));
+}
+
+static QString nonConstRefArg(const QByteArray &arg)
+{
+ return QLatin1String(arg + " &");
+}
+
+static QString templateArg(const QByteArray &arg)
+{
+ if (!arg.endsWith('>'))
+ return QLatin1String(arg);
+
+ return QLatin1String(arg + ' ');
+}
+
+static QString constRefArg(const QByteArray &arg)
+{
+ if (!arg.startsWith('Q'))
+ return QLatin1String(arg + ' ');
+ else
+ return QString( QLatin1String("const %1 &") ).arg( QLatin1String(arg) );
+}
+
+static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs,
+ const QDBusIntrospection::Arguments &outputArgs =
+ QDBusIntrospection::Arguments())
+{
+ QStringList retval;
+ for (int i = 0; i < inputArgs.count(); ++i) {
+ const QDBusIntrospection::Argument &arg = inputArgs.at(i);
+ QString name = arg.name;
+ if (name.isEmpty())
+ name = QString( QLatin1String("in%1") ).arg(i);
+ while (retval.contains(name))
+ name += QLatin1String("_");
+ retval << name;
+ }
+ for (int i = 0; i < outputArgs.count(); ++i) {
+ const QDBusIntrospection::Argument &arg = outputArgs.at(i);
+ QString name = arg.name;
+ if (name.isEmpty())
+ name = QString( QLatin1String("out%1") ).arg(i);
+ while (retval.contains(name))
+ name += QLatin1String("_");
+ retval << name;
+ }
+ return retval;
+}
+
+static void writeArgList(QTextStream &ts, const QStringList &argNames,
+ const QDBusIntrospection::Annotations &annotations,
+ const QDBusIntrospection::Arguments &inputArgs,
+ const QDBusIntrospection::Arguments &outputArgs = QDBusIntrospection::Arguments())
+{
+ // input args:
+ bool first = true;
+ int argPos = 0;
+ for (int i = 0; i < inputArgs.count(); ++i) {
+ const QDBusIntrospection::Argument &arg = inputArgs.at(i);
+ QString type = constRefArg(qtTypeName(arg.type, annotations, i, "In"));
+
+ if (!first)
+ ts << ", ";
+ ts << type << argNames.at(argPos++);
+ first = false;
+ }
+
+ argPos++;
+
+ // output args
+ // yes, starting from 1
+ for (int i = 1; i < outputArgs.count(); ++i) {
+ const QDBusIntrospection::Argument &arg = outputArgs.at(i);
+ QString name = arg.name;
+
+ if (!first)
+ ts << ", ";
+ ts << nonConstRefArg(qtTypeName(arg.type, annotations, i, "Out"))
+ << argNames.at(argPos++);
+ first = false;
+ }
+}
+
+static QString propertyGetter(const QDBusIntrospection::Property &property)
+{
+ QString getter = property.annotations.value(QLatin1String("com.trolltech.QtDBus.propertyGetter"));
+ if (getter.isEmpty()) {
+ getter = property.name;
+ getter[0] = getter[0].toLower();
+ }
+ return getter;
+}
+
+static QString propertySetter(const QDBusIntrospection::Property &property)
+{
+ QString setter = property.annotations.value(QLatin1String("com.trolltech.QtDBus.propertySetter"));
+ if (setter.isEmpty()) {
+ setter = QLatin1String("set") + property.name;
+ setter[3] = setter[3].toUpper();
+ }
+ return setter;
+}
+
+static QString stringify(const QString &data)
+{
+ QString retval;
+ int i;
+ for (i = 0; i < data.length(); ++i) {
+ retval += QLatin1Char('\"');
+ for ( ; i < data.length() && data[i] != QLatin1Char('\n'); ++i)
+ if (data[i] == QLatin1Char('\"'))
+ retval += QLatin1String("\\\"");
+ else
+ retval += data[i];
+ retval += QLatin1String("\\n\"\n");
+ }
+ return retval;
+}
+
+static void openFile(const QString &fileName, QFile &file)
+{
+ if (fileName.isEmpty())
+ return;
+
+ bool isOk = false;
+ if (fileName == QLatin1String("-")) {
+ isOk = file.open(stdout, QIODevice::WriteOnly | QIODevice::Text);
+ } else {
+ file.setFileName(fileName);
+ isOk = file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
+ }
+
+ if (!isOk)
+ fprintf(stderr, "Unable to open '%s': %s\n", qPrintable(fileName),
+ qPrintable(file.errorString()));
+}
+
+static void writeProxy(const QString &filename, const QDBusIntrospection::Interfaces &interfaces)
+{
+ // open the file
+ QString headerName = header(filename);
+ QByteArray headerData;
+ QTextStream hs(&headerData);
+
+ QString cppName = cpp(filename);
+ QByteArray cppData;
+ QTextStream cs(&cppData);
+
+ // write the header:
+ writeHeader(hs, true);
+ if (cppName != headerName)
+ writeHeader(cs, false);
+
+ // include guards:
+ QString includeGuard;
+ if (!headerName.isEmpty() && headerName != QLatin1String("-")) {
+ includeGuard = headerName.toUpper().replace(QLatin1Char('.'), QLatin1Char('_'));
+ int pos = includeGuard.lastIndexOf(QLatin1Char('/'));
+ if (pos != -1)
+ includeGuard = includeGuard.mid(pos + 1);
+ } else {
+ includeGuard = QLatin1String("QDBUSXML2CPP_PROXY");
+ }
+ includeGuard = QString(QLatin1String("%1_%2"))
+ .arg(includeGuard)
+ .arg(QDateTime::currentDateTime().toTime_t());
+ hs << "#ifndef " << includeGuard << endl
+ << "#define " << includeGuard << endl
+ << endl;
+
+ // include our stuff:
+ hs << "#include <QtCore/QObject>" << endl
+ << includeList
+ << "#include <QtDBus/QtDBus>" << endl;
+
+ foreach (QString include, includes) {
+ hs << "#include \"" << include << "\"" << endl;
+ if (headerName.isEmpty())
+ cs << "#include \"" << include << "\"" << endl;
+ }
+
+ hs << endl;
+
+ if (cppName != headerName) {
+ if (!headerName.isEmpty() && headerName != QLatin1String("-"))
+ cs << "#include \"" << headerName << "\"" << endl << endl;
+ }
+
+ foreach (const QDBusIntrospection::Interface *interface, interfaces) {
+ QString className = classNameForInterface(interface->name, Proxy);
+
+ // comment:
+ hs << "/*" << endl
+ << " * Proxy class for interface " << interface->name << endl
+ << " */" << endl;
+ cs << "/*" << endl
+ << " * Implementation of interface class " << className << endl
+ << " */" << endl
+ << endl;
+
+ // class header:
+ hs << "class " << className << ": public QDBusAbstractInterface" << endl
+ << "{" << endl
+ << " Q_OBJECT" << endl;
+
+ // the interface name
+ hs << "public:" << endl
+ << " static inline const char *staticInterfaceName()" << endl
+ << " { return \"" << interface->name << "\"; }" << endl
+ << endl;
+
+ // constructors/destructors:
+ hs << "public:" << endl
+ << " " << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);" << endl
+ << endl
+ << " ~" << className << "();" << endl
+ << endl;
+ cs << className << "::" << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)" << endl
+ << " : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)" << endl
+ << "{" << endl
+ << "}" << endl
+ << endl
+ << className << "::~" << className << "()" << endl
+ << "{" << endl
+ << "}" << endl
+ << endl;
+
+ // properties:
+ foreach (const QDBusIntrospection::Property &property, interface->properties) {
+ QByteArray type = qtTypeName(property.type, property.annotations);
+ QString templateType = templateArg(type);
+ QString constRefType = constRefArg(type);
+ QString getter = propertyGetter(property);
+ QString setter = propertySetter(property);
+
+ hs << " Q_PROPERTY(" << type << " " << property.name;
+
+ // getter:
+ if (property.access != QDBusIntrospection::Property::Write)
+ // it's readble
+ hs << " READ " << getter;
+
+ // setter
+ if (property.access != QDBusIntrospection::Property::Read)
+ // it's writeable
+ hs << " WRITE " << setter;
+
+ hs << ")" << endl;
+
+ // getter:
+ if (property.access != QDBusIntrospection::Property::Write) {
+ hs << " inline " << type << " " << getter << "() const" << endl
+ << " { return qvariant_cast< " << type << " >(property(\""
+ << property.name << "\")); }" << endl;
+ }
+
+ // setter:
+ if (property.access != QDBusIntrospection::Property::Read) {
+ hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl
+ << " { setProperty(\"" << property.name
+ << "\", QVariant::fromValue(value)); }" << endl;
+ }
+
+ hs << endl;
+ }
+
+ // methods:
+ hs << "public Q_SLOTS: // METHODS" << endl;
+ foreach (const QDBusIntrospection::Method &method, interface->methods) {
+ bool isDeprecated = method.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) == QLatin1String("true");
+ bool isNoReply =
+ method.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true");
+ if (isNoReply && !method.outputArgs.isEmpty()) {
+ fprintf(stderr, "warning: method %s in interface %s is marked 'no-reply' but has output arguments.\n",
+ qPrintable(method.name), qPrintable(interface->name));
+ continue;
+ }
+
+ hs << " inline "
+ << (isDeprecated ? "Q_DECL_DEPRECATED " : "");
+
+ if (isNoReply) {
+ hs << "Q_NOREPLY void ";
+ } else {
+ hs << "QDBusPendingReply<";
+ for (int i = 0; i < method.outputArgs.count(); ++i)
+ hs << (i > 0 ? ", " : "")
+ << templateArg(qtTypeName(method.outputArgs.at(i).type, method.annotations, i, "Out"));
+ hs << "> ";
+ }
+
+ hs << method.name << "(";
+
+ QStringList argNames = makeArgNames(method.inputArgs);
+ writeArgList(hs, argNames, method.annotations, method.inputArgs);
+
+ hs << ")" << endl
+ << " {" << endl
+ << " QList<QVariant> argumentList;" << endl;
+
+ if (!method.inputArgs.isEmpty()) {
+ hs << " argumentList";
+ for (int argPos = 0; argPos < method.inputArgs.count(); ++argPos)
+ hs << " << QVariant::fromValue(" << argNames.at(argPos) << ')';
+ hs << ";" << endl;
+ }
+
+ if (isNoReply)
+ hs << " callWithArgumentList(QDBus::NoBlock, "
+ << "QLatin1String(\"" << method.name << "\"), argumentList);" << endl;
+ else
+ hs << " return asyncCallWithArgumentList(QLatin1String(\""
+ << method.name << "\"), argumentList);" << endl;
+
+ // close the function:
+ hs << " }" << endl;
+
+ if (method.outputArgs.count() > 1) {
+ // generate the old-form QDBusReply methods with multiple incoming parameters
+ hs << " inline "
+ << (isDeprecated ? "Q_DECL_DEPRECATED " : "")
+ << "QDBusReply<"
+ << templateArg(qtTypeName(method.outputArgs.first().type, method.annotations, 0, "Out")) << "> ";
+ hs << method.name << "(";
+
+ QStringList argNames = makeArgNames(method.inputArgs, method.outputArgs);
+ writeArgList(hs, argNames, method.annotations, method.inputArgs, method.outputArgs);
+
+ hs << ")" << endl
+ << " {" << endl
+ << " QList<QVariant> argumentList;" << endl;
+
+ int argPos = 0;
+ if (!method.inputArgs.isEmpty()) {
+ hs << " argumentList";
+ for (argPos = 0; argPos < method.inputArgs.count(); ++argPos)
+ hs << " << QVariant::fromValue(" << argNames.at(argPos) << ')';
+ hs << ";" << endl;
+ }
+
+ hs << " QDBusMessage reply = callWithArgumentList(QDBus::Block, "
+ << "QLatin1String(\"" << method.name << "\"), argumentList);" << endl;
+
+ argPos++;
+ hs << " if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == "
+ << method.outputArgs.count() << ") {" << endl;
+
+ // yes, starting from 1
+ for (int i = 1; i < method.outputArgs.count(); ++i)
+ hs << " " << argNames.at(argPos++) << " = qdbus_cast<"
+ << templateArg(qtTypeName(method.outputArgs.at(i).type, method.annotations, i, "Out"))
+ << ">(reply.arguments().at(" << i << "));" << endl;
+ hs << " }" << endl
+ << " return reply;" << endl
+ << " }" << endl;
+ }
+
+ hs << endl;
+ }
+
+ hs << "Q_SIGNALS: // SIGNALS" << endl;
+ foreach (const QDBusIntrospection::Signal &signal, interface->signals_) {
+ hs << " ";
+ if (signal.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) ==
+ QLatin1String("true"))
+ hs << "Q_DECL_DEPRECATED ";
+
+ hs << "void " << signal.name << "(";
+
+ QStringList argNames = makeArgNames(signal.outputArgs);
+ writeArgList(hs, argNames, signal.annotations, signal.outputArgs);
+
+ hs << ");" << endl; // finished for header
+ }
+
+ // close the class:
+ hs << "};" << endl
+ << endl;
+ }
+
+ if (!skipNamespaces) {
+ QStringList last;
+ QDBusIntrospection::Interfaces::ConstIterator it = interfaces.constBegin();
+ do
+ {
+ QStringList current;
+ QString name;
+ if (it != interfaces.constEnd()) {
+ current = it->constData()->name.split(QLatin1Char('.'));
+ name = current.takeLast();
+ }
+
+ int i = 0;
+ while (i < current.count() && i < last.count() && current.at(i) == last.at(i))
+ ++i;
+
+ // i parts matched
+ // close last.arguments().count() - i namespaces:
+ for (int j = i; j < last.count(); ++j)
+ hs << QString((last.count() - j - 1 + i) * 2, QLatin1Char(' ')) << "}" << endl;
+
+ // open current.arguments().count() - i namespaces
+ for (int j = i; j < current.count(); ++j)
+ hs << QString(j * 2, QLatin1Char(' ')) << "namespace " << current.at(j) << " {" << endl;
+
+ // add this class:
+ if (!name.isEmpty()) {
+ hs << QString(current.count() * 2, QLatin1Char(' '))
+ << "typedef ::" << classNameForInterface(it->constData()->name, Proxy)
+ << " " << name << ";" << endl;
+ }
+
+ if (it == interfaces.constEnd())
+ break;
+ ++it;
+ last = current;
+ } while (true);
+ }
+
+ // close the include guard
+ hs << "#endif" << endl;
+
+ QString mocName = moc(filename);
+ if (includeMocs && !mocName.isEmpty())
+ cs << endl
+ << "#include \"" << mocName << "\"" << endl;
+
+ cs.flush();
+ hs.flush();
+
+ QFile file;
+ openFile(headerName, file);
+ file.write(headerData);
+
+ if (headerName == cppName) {
+ file.write(cppData);
+ } else {
+ QFile cppFile;
+ openFile(cppName, cppFile);
+ cppFile.write(cppData);
+ }
+}
+
+static void writeAdaptor(const QString &filename, const QDBusIntrospection::Interfaces &interfaces)
+{
+ // open the file
+ QString headerName = header(filename);
+ QByteArray headerData;
+ QTextStream hs(&headerData);
+
+ QString cppName = cpp(filename);
+ QByteArray cppData;
+ QTextStream cs(&cppData);
+
+ // write the headers
+ writeHeader(hs, false);
+ if (cppName != headerName)
+ writeHeader(cs, true);
+
+ // include guards:
+ QString includeGuard;
+ if (!headerName.isEmpty() && headerName != QLatin1String("-")) {
+ includeGuard = headerName.toUpper().replace(QLatin1Char('.'), QLatin1Char('_'));
+ int pos = includeGuard.lastIndexOf(QLatin1Char('/'));
+ if (pos != -1)
+ includeGuard = includeGuard.mid(pos + 1);
+ } else {
+ includeGuard = QLatin1String("QDBUSXML2CPP_ADAPTOR");
+ }
+ includeGuard = QString(QLatin1String("%1_%2"))
+ .arg(includeGuard)
+ .arg(QDateTime::currentDateTime().toTime_t());
+ hs << "#ifndef " << includeGuard << endl
+ << "#define " << includeGuard << endl
+ << endl;
+
+ // include our stuff:
+ hs << "#include <QtCore/QObject>" << endl;
+ if (cppName == headerName)
+ hs << "#include <QtCore/QMetaObject>" << endl
+ << "#include <QtCore/QVariant>" << endl;
+ hs << "#include <QtDBus/QtDBus>" << endl;
+
+ foreach (QString include, includes) {
+ hs << "#include \"" << include << "\"" << endl;
+ if (headerName.isEmpty())
+ cs << "#include \"" << include << "\"" << endl;
+ }
+
+ if (cppName != headerName) {
+ if (!headerName.isEmpty() && headerName != QLatin1String("-"))
+ cs << "#include \"" << headerName << "\"" << endl;
+
+ cs << "#include <QtCore/QMetaObject>" << endl
+ << includeList
+ << endl;
+ hs << forwardDeclarations;
+ } else {
+ hs << includeList;
+ }
+
+ hs << endl;
+
+ QString parent = parentClassName;
+ if (parentClassName.isEmpty())
+ parent = QLatin1String("QObject");
+
+ foreach (const QDBusIntrospection::Interface *interface, interfaces) {
+ QString className = classNameForInterface(interface->name, Adaptor);
+
+ // comment:
+ hs << "/*" << endl
+ << " * Adaptor class for interface " << interface->name << endl
+ << " */" << endl;
+ cs << "/*" << endl
+ << " * Implementation of adaptor class " << className << endl
+ << " */" << endl
+ << endl;
+
+ // class header:
+ hs << "class " << className << ": public QDBusAbstractAdaptor" << endl
+ << "{" << endl
+ << " Q_OBJECT" << endl
+ << " Q_CLASSINFO(\"D-Bus Interface\", \"" << interface->name << "\")" << endl
+ << " Q_CLASSINFO(\"D-Bus Introspection\", \"\"" << endl
+ << stringify(interface->introspection)
+ << " \"\")" << endl
+ << "public:" << endl
+ << " " << className << "(" << parent << " *parent);" << endl
+ << " virtual ~" << className << "();" << endl
+ << endl;
+
+ if (!parentClassName.isEmpty())
+ hs << " inline " << parent << " *parent() const" << endl
+ << " { return static_cast<" << parent << " *>(QObject::parent()); }" << endl
+ << endl;
+
+ // constructor/destructor
+ cs << className << "::" << className << "(" << parent << " *parent)" << endl
+ << " : QDBusAbstractAdaptor(parent)" << endl
+ << "{" << endl
+ << " // constructor" << endl
+ << " setAutoRelaySignals(true);" << endl
+ << "}" << endl
+ << endl
+ << className << "::~" << className << "()" << endl
+ << "{" << endl
+ << " // destructor" << endl
+ << "}" << endl
+ << endl;
+
+ hs << "public: // PROPERTIES" << endl;
+ foreach (const QDBusIntrospection::Property &property, interface->properties) {
+ QByteArray type = qtTypeName(property.type, property.annotations);
+ QString constRefType = constRefArg(type);
+ QString getter = propertyGetter(property);
+ QString setter = propertySetter(property);
+
+ hs << " Q_PROPERTY(" << type << " " << property.name;
+ if (property.access != QDBusIntrospection::Property::Write)
+ hs << " READ " << getter;
+ if (property.access != QDBusIntrospection::Property::Read)
+ hs << " WRITE " << setter;
+ hs << ")" << endl;
+
+ // getter:
+ if (property.access != QDBusIntrospection::Property::Write) {
+ hs << " " << type << " " << getter << "() const;" << endl;
+ cs << type << " "
+ << className << "::" << getter << "() const" << endl
+ << "{" << endl
+ << " // get the value of property " << property.name << endl
+ << " return qvariant_cast< " << type <<" >(parent()->property(\"" << property.name << "\"));" << endl
+ << "}" << endl
+ << endl;
+ }
+
+ // setter
+ if (property.access != QDBusIntrospection::Property::Read) {
+ hs << " void " << setter << "(" << constRefType << "value);" << endl;
+ cs << "void " << className << "::" << setter << "(" << constRefType << "value)" << endl
+ << "{" << endl
+ << " // set the value of property " << property.name << endl
+ << " parent()->setProperty(\"" << property.name << "\", QVariant::fromValue(value";
+ if (constRefType.contains(QLatin1String("QDBusVariant")))
+ cs << ".variant()";
+ cs << "));" << endl
+ << "}" << endl
+ << endl;
+ }
+
+ hs << endl;
+ }
+
+ hs << "public Q_SLOTS: // METHODS" << endl;
+ foreach (const QDBusIntrospection::Method &method, interface->methods) {
+ bool isNoReply =
+ method.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true");
+ if (isNoReply && !method.outputArgs.isEmpty()) {
+ fprintf(stderr, "warning: method %s in interface %s is marked 'no-reply' but has output arguments.\n",
+ qPrintable(method.name), qPrintable(interface->name));
+ continue;
+ }
+
+ hs << " ";
+ if (method.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) ==
+ QLatin1String("true"))
+ hs << "Q_DECL_DEPRECATED ";
+
+ QByteArray returnType;
+ if (isNoReply) {
+ hs << "Q_NOREPLY void ";
+ cs << "void ";
+ } else if (method.outputArgs.isEmpty()) {
+ hs << "void ";
+ cs << "void ";
+ } else {
+ returnType = qtTypeName(method.outputArgs.first().type, method.annotations, 0, "Out");
+ hs << returnType << " ";
+ cs << returnType << " ";
+ }
+
+ QString name = method.name;
+ hs << name << "(";
+ cs << className << "::" << name << "(";
+
+ QStringList argNames = makeArgNames(method.inputArgs, method.outputArgs);
+ writeArgList(hs, argNames, method.annotations, method.inputArgs, method.outputArgs);
+ writeArgList(cs, argNames, method.annotations, method.inputArgs, method.outputArgs);
+
+ hs << ");" << endl; // finished for header
+ cs << ")" << endl
+ << "{" << endl
+ << " // handle method call " << interface->name << "." << method.name << endl;
+
+ // make the call
+ bool usingInvokeMethod = false;
+ if (parentClassName.isEmpty() && method.inputArgs.count() <= 10
+ && method.outputArgs.count() <= 1)
+ usingInvokeMethod = true;
+
+ if (usingInvokeMethod) {
+ // we are using QMetaObject::invokeMethod
+ if (!returnType.isEmpty())
+ cs << " " << returnType << " " << argNames.at(method.inputArgs.count())
+ << ";" << endl;
+
+ static const char invoke[] = " QMetaObject::invokeMethod(parent(), \"";
+ cs << invoke << name << "\"";
+
+ if (!method.outputArgs.isEmpty())
+ cs << ", Q_RETURN_ARG("
+ << qtTypeName(method.outputArgs.at(0).type, method.annotations,
+ 0, "Out")
+ << ", "
+ << argNames.at(method.inputArgs.count())
+ << ")";
+
+ for (int i = 0; i < method.inputArgs.count(); ++i)
+ cs << ", Q_ARG("
+ << qtTypeName(method.inputArgs.at(i).type, method.annotations,
+ i, "In")
+ << ", "
+ << argNames.at(i)
+ << ")";
+
+ cs << ");" << endl;
+
+ if (!returnType.isEmpty())
+ cs << " return " << argNames.at(method.inputArgs.count()) << ";" << endl;
+ } else {
+ if (parentClassName.isEmpty())
+ cs << " //";
+ else
+ cs << " ";
+
+ if (!method.outputArgs.isEmpty())
+ cs << "return ";
+
+ if (parentClassName.isEmpty())
+ cs << "static_cast<YourObjectType *>(parent())->";
+ else
+ cs << "parent()->";
+ cs << name << "(";
+
+ int argPos = 0;
+ bool first = true;
+ for (int i = 0; i < method.inputArgs.count(); ++i) {
+ cs << (first ? "" : ", ") << argNames.at(argPos++);
+ first = false;
+ }
+ ++argPos; // skip retval, if any
+ for (int i = 1; i < method.outputArgs.count(); ++i) {
+ cs << (first ? "" : ", ") << argNames.at(argPos++);
+ first = false;
+ }
+
+ cs << ");" << endl;
+ }
+ cs << "}" << endl
+ << endl;
+ }
+
+ hs << "Q_SIGNALS: // SIGNALS" << endl;
+ foreach (const QDBusIntrospection::Signal &signal, interface->signals_) {
+ hs << " ";
+ if (signal.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) ==
+ QLatin1String("true"))
+ hs << "Q_DECL_DEPRECATED ";
+
+ hs << "void " << signal.name << "(";
+
+ QStringList argNames = makeArgNames(signal.outputArgs);
+ writeArgList(hs, argNames, signal.annotations, signal.outputArgs);
+
+ hs << ");" << endl; // finished for header
+ }
+
+ // close the class:
+ hs << "};" << endl
+ << endl;
+ }
+
+ // close the include guard
+ hs << "#endif" << endl;
+
+ QString mocName = moc(filename);
+ if (includeMocs && !mocName.isEmpty())
+ cs << endl
+ << "#include \"" << mocName << "\"" << endl;
+
+ cs.flush();
+ hs.flush();
+
+ QFile file;
+ openFile(headerName, file);
+ file.write(headerData);
+
+ if (headerName == cppName) {
+ file.write(cppData);
+ } else {
+ QFile cppFile;
+ openFile(cppName, cppFile);
+ cppFile.write(cppData);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ parseCmdLine(app.arguments());
+
+ QDBusIntrospection::Interfaces interfaces = readInput();
+ cleanInterfaces(interfaces);
+
+ if (!proxyFile.isEmpty() || adaptorFile.isEmpty())
+ writeProxy(proxyFile, interfaces);
+
+ if (!adaptorFile.isEmpty())
+ writeAdaptor(adaptorFile, interfaces);
+
+ return 0;
+}
+
+/*!
+ \page qdbusxml2cpp.html
+ \title QtDBus XML compiler (qdbusxml2cpp)
+ \keyword qdbusxml2cpp
+
+ The QtDBus XML compiler is a tool that can be used to parse interface descriptions and produce
+ static code representing those interfaces, which can then be used to make calls to remote
+ objects or implement said interfaces.
+
+ \c qdbusxml2cpp has two modes of operation, that correspond to the two possible outputs it can
+ produce: the interface (proxy) class or the adaptor class. The latter consists of both a C++
+ header and a source file, which are meant to be edited and adapted to your needs.
+
+ The \c qdbusxml2cpp tool is not meant to be run every time you compile your
+ application. Instead, it's meant to be used when developing the code or when the interface
+ changes.
+
+ The adaptor classes generated by \c qdbusxml2cpp are just a skeleton that must be completed. It
+ generates, by default, calls to slots with the same name on the object the adaptor is attached
+ to. However, you may modify those slots or the property accessor functions to suit your needs.
+*/
diff --git a/src/qdbus/qdbusxml2cpp/qdbusxml2cpp.pro b/src/qdbus/qdbusxml2cpp/qdbusxml2cpp.pro
new file mode 100644
index 000000000..6f78c7ca3
--- /dev/null
+++ b/src/qdbus/qdbusxml2cpp/qdbusxml2cpp.pro
@@ -0,0 +1,10 @@
+SOURCES = qdbusxml2cpp.cpp
+DESTDIR = ../../../bin
+TARGET = qdbusxml2cpp
+QT = core xml
+CONFIG += qdbus
+CONFIG -= app_bundle
+win32:CONFIG += console
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/qev/README b/src/qev/README
new file mode 100644
index 000000000..b695200cc
--- /dev/null
+++ b/src/qev/README
@@ -0,0 +1,2 @@
+This tool allows introspection of incoming events for a QWidget, similar to the X11 xev tool.
+
diff --git a/src/qev/qev.cpp b/src/qev/qev.cpp
new file mode 100644
index 000000000..f054403cd
--- /dev/null
+++ b/src/qev/qev.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+QT_USE_NAMESPACE
+
+class Widget : public QWidget
+{
+public:
+ Widget(){ setAttribute(Qt::WA_InputMethodEnabled); }
+ QSize sizeHint() const { return QSize(20, 20); }
+ bool event(QEvent *e) {
+ if (e->type() == QEvent::ContextMenu)
+ return false;
+ qDebug() << e;
+ return QWidget::event(e);
+ }
+};
+
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ Widget w;
+ w.show();
+ return app.exec();
+}
diff --git a/src/qev/qev.pro b/src/qev/qev.pro
new file mode 100644
index 000000000..962b9faf2
--- /dev/null
+++ b/src/qev/qev.pro
@@ -0,0 +1,11 @@
+######################################################################
+# Automatically generated by qmake (1.08a) Mon Oct 18 13:59:36 2004
+######################################################################
+
+TEMPLATE = app
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += qev.cpp
+CONFIG += qt warn_on create_prl link_prl
diff --git a/src/qmeegographicssystemhelper/qmeegofencesync.cpp b/src/qmeegographicssystemhelper/qmeegofencesync.cpp
new file mode 100644
index 000000000..9f3487683
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegofencesync.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegofencesync.h"
+#include "qmeegofencesync_p.h"
+#include "qmeegoruntime.h"
+
+/* QMeeGoFenceSyncPrivate */
+
+QMeeGoFenceSyncPrivate::QMeeGoFenceSyncPrivate() : syncObject(NULL)
+{
+}
+
+QMeeGoFenceSyncPrivate::~QMeeGoFenceSyncPrivate()
+{
+ if (syncObject) {
+ QMeeGoRuntime::destroyFenceSync(syncObject);
+ syncObject = NULL;
+ }
+}
+
+/* QMeeGoFenceSync */
+
+QMeeGoFenceSync::QMeeGoFenceSync(QWidget *parent) : QObject(parent), d_ptr(new QMeeGoFenceSyncPrivate())
+{
+ Q_D(QMeeGoFenceSync);
+ d->q_ptr = this;
+}
+
+QMeeGoFenceSync::~QMeeGoFenceSync()
+{
+}
+
+void QMeeGoFenceSync::setSyncPoint()
+{
+ Q_D(QMeeGoFenceSync);
+ if (d->syncObject)
+ QMeeGoRuntime::destroyFenceSync(d->syncObject);
+
+ d->syncObject = QMeeGoRuntime::createFenceSync();
+}
diff --git a/src/qmeegographicssystemhelper/qmeegofencesync.h b/src/qmeegographicssystemhelper/qmeegofencesync.h
new file mode 100644
index 000000000..959f1a672
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegofencesync.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEEGOFENCESYNC_H
+#define QMEEGOFENCESYNC_H
+
+#include <QWidget>
+
+class QMeeGoFenceSyncPrivate;
+
+//! A synchronization helper for GL pipeline.
+/*!
+ Fence syncs provide a mechanism for synchronizing access to certain GL primitives
+ and make it possible for the application developer to be sure that a certain point
+ in the GL processing pipeline has been already executed before continuing operation.
+
+ Currently fence syncs are only useful in conjunction with QMeeGoLivePixmaps.
+ \code
+ ...
+ // In your paint/expose event:
+ QImage *image = livePixmap->lock(&someGlobalFenceSync);
+ // Modify the image...
+ livePixmap->release(image);
+
+ painter->drawPixmap(0, 0, *livePixmap);
+ someGlobalFenceSync.setSyncPoint();
+ ...
+ \endcode
+
+ Assuming the paint/expose events come repeatedly, the lock operation
+ will block till the previous event completed painting the livePixmap.
+*/
+
+class Q_DECL_EXPORT QMeeGoFenceSync : public QObject
+{
+public:
+ //! Constructs a new fence sync.
+ /*!
+ The fence sync is created without a sync point. You need to set the sync point manually.
+ */
+ QMeeGoFenceSync(QWidget *parent = 0);
+
+ //! Destructor for the fence sync.
+ virtual ~QMeeGoFenceSync();
+
+ //! Sets the fence sync.
+ /*!
+ The fence sync synchronization point should be set after all drawing has been scheduled.
+ Setting a synchronization point always overrides the previous point -- whetver is was
+ used (waited upon) or not.
+ */
+ void setSyncPoint();
+
+private:
+ Q_DISABLE_COPY(QMeeGoFenceSync)
+ Q_DECLARE_PRIVATE(QMeeGoFenceSync)
+
+protected:
+ QScopedPointer<QMeeGoFenceSyncPrivate> d_ptr; //! Private bits.
+ friend class QMeeGoLivePixmap;
+};
+
+#endif
diff --git a/src/qmeegographicssystemhelper/qmeegofencesync_p.h b/src/qmeegographicssystemhelper/qmeegofencesync_p.h
new file mode 100644
index 000000000..681788c66
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegofencesync_p.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegofencesync.h"
+
+#ifndef QMEEGOFENCESYNC_P_H
+#define QMEEGOFENCESYNC_P_H
+
+class QMeeGoFenceSyncPrivate
+{
+public:
+ Q_DECLARE_PUBLIC(QMeeGoFenceSync);
+ QMeeGoFenceSyncPrivate();
+
+ virtual ~QMeeGoFenceSyncPrivate();
+
+ void* syncObject;
+
+ QMeeGoFenceSync *q_ptr;
+};
+
+#endif
diff --git a/src/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp b/src/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp
new file mode 100644
index 000000000..6778bd5e2
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define ENSURE_RUNNING_MEEGO {if (! QMeeGoGraphicsSystemHelper::isRunningMeeGo()) { qFatal("Using meego functionality but not running meego graphics system!"); }}
+
+#include "qmeegographicssystemhelper.h"
+#include <private/qapplication_p.h>
+#include <private/qgraphicssystem_runtime_p.h>
+#include <private/qpixmap_raster_p.h>
+#include <private/qwindowsurface_gl_p.h>
+#include "qmeegoruntime.h"
+
+QString QMeeGoGraphicsSystemHelper::runningGraphicsSystemName()
+{
+ if (! QApplicationPrivate::instance()) {
+ qWarning("Querying graphics system but application not running yet!");
+ return QString();
+ }
+
+ QString name = QApplicationPrivate::instance()->graphics_system_name;
+ if (name == QLatin1String("runtime")) {
+ QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
+ name = rsystem->graphicsSystemName();
+ }
+
+ return name;
+}
+
+bool QMeeGoGraphicsSystemHelper::isRunningMeeGo()
+{
+ return (runningGraphicsSystemName() == QLatin1String("meego"));
+}
+
+bool QMeeGoGraphicsSystemHelper::isRunningRuntime()
+{
+ return (QApplicationPrivate::instance()->graphics_system_name == QLatin1String("runtime"));
+}
+
+void QMeeGoGraphicsSystemHelper::switchToMeeGo()
+{
+ QMeeGoRuntime::switchToMeeGo();
+}
+
+void QMeeGoGraphicsSystemHelper::switchToRaster()
+{
+ QMeeGoRuntime::switchToRaster();
+}
+
+Qt::HANDLE QMeeGoGraphicsSystemHelper::imageToEGLSharedImage(const QImage &image)
+{
+ ENSURE_RUNNING_MEEGO;
+ return QMeeGoRuntime::imageToEGLSharedImage(image);
+}
+
+QPixmap QMeeGoGraphicsSystemHelper::pixmapFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage)
+{
+ // This function is supported when not running meego too. A raster-backed
+ // pixmap will be created... but when you switch back to 'meego', it'll
+ // be replaced with a EGL shared image backing.
+ return QPixmap(QMeeGoRuntime::pixmapDataFromEGLSharedImage(handle, softImage));
+}
+
+QPixmap QMeeGoGraphicsSystemHelper::pixmapWithGLTexture(int w, int h)
+{
+ ENSURE_RUNNING_MEEGO;
+ return QPixmap(QMeeGoRuntime::pixmapDataWithGLTexture(w, h));
+}
+
+bool QMeeGoGraphicsSystemHelper::destroyEGLSharedImage(Qt::HANDLE handle)
+{
+ ENSURE_RUNNING_MEEGO;
+ return QMeeGoRuntime::destroyEGLSharedImage(handle);
+}
+
+void QMeeGoGraphicsSystemHelper::updateEGLSharedImagePixmap(QPixmap *p)
+{
+ ENSURE_RUNNING_MEEGO;
+ return QMeeGoRuntime::updateEGLSharedImagePixmap(p);
+}
+
+void QMeeGoGraphicsSystemHelper::setTranslucent(bool translucent)
+{
+ ENSURE_RUNNING_MEEGO;
+ QMeeGoRuntime::setTranslucent(translucent);
+}
+
+void QMeeGoGraphicsSystemHelper::setSwapBehavior(SwapMode mode)
+{
+ ENSURE_RUNNING_MEEGO;
+
+ if (mode == AutomaticSwap)
+ QGLWindowSurface::swapBehavior = QGLWindowSurface::AutomaticSwap;
+ else if (mode == AlwaysFullSwap)
+ QGLWindowSurface::swapBehavior = QGLWindowSurface::AlwaysFullSwap;
+ else if (mode == AlwaysPartialSwap)
+ QGLWindowSurface::swapBehavior = QGLWindowSurface::AlwaysPartialSwap;
+ else if (mode == KillSwap)
+ QGLWindowSurface::swapBehavior = QGLWindowSurface::KillSwap;
+}
+
+void QMeeGoGraphicsSystemHelper::setSwitchPolicy(SwitchPolicy policy)
+{
+ QMeeGoRuntime::setSwitchPolicy(policy);
+}
+
+void QMeeGoGraphicsSystemHelper::enableSwitchEvents()
+{
+ QMeeGoRuntime::enableSwitchEvents();
+}
diff --git a/src/qmeegographicssystemhelper/qmeegographicssystemhelper.h b/src/qmeegographicssystemhelper/qmeegographicssystemhelper.h
new file mode 100644
index 000000000..461219068
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegographicssystemhelper.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEEGOGRAPHICSSYSTEMHELPER_H
+#define QMEEGOGRAPHICSSYSTEMHELPER_H
+
+#include <QPixmap>
+#include <QImage>
+#include "qmeegolivepixmap.h"
+
+class QLibrary;
+
+//! The base class for accressing special meego graphics system features.
+/*!
+ This class is a helper class with static-only methods for accessing various
+ meego graphics system functionalities. The way it works is that the helper
+ dynamically calls-in to the loaded graphicssystem plugin... therefore, you're
+ expected to make sure that you're indeed running with 'meego' before using any
+ of the specialized methods.
+
+ In example:
+
+ \code
+ QPixmap p;
+ if (QMeeGoGraphicsSystemHelper::isRunningMeeGo()) {
+ p = QMeeGoGraphicsSystemHelper::pixmapWithGLTexture(64, 64);
+ } else {
+ p = QPixmap(64, 64);
+ }
+ \endcode
+
+ Calling any of the meego-specific features while not running meego might
+ give unpredictable results. The only functions safe to call at all times are:
+
+ \code
+ QMeeGoGraphicsSystemHelper::isRunningMeeGo();
+ QMeeGoGraphicsSystemHelper::runningGraphicsSystemName();
+ QMeeGoGraphicsSystemHelper::switchToMeeGo();
+ QMeeGoGraphicsSystemHelper::switchToRaster();
+ \endcode
+*/
+
+class Q_DECL_EXPORT QMeeGoGraphicsSystemHelper
+{
+public:
+ //! Returns true if running meego.
+ /*!
+ Returns true if the currently active (running) system is 'meego' with OpenGL.
+ This returns both true if the app was started with 'meego' or was started with
+ 'runtime' graphics system and the currently active system through the runtime
+ switching is 'meego'.
+ */
+ static bool isRunningMeeGo();
+
+ //! Returns true if running with a 'runtime' graphicssystem.
+ /*!
+ This function can be used in combination with ::runningGraphicsSystemName to figure out
+ the existing situation.
+ */
+ static bool isRunningRuntime();
+
+ //! Enables the sending of QMeeGoSwitchEvent's when the graphicssystem switches.
+ /*!
+ An application that wishes to start receive QMeegoSwitchEvents must call this function.
+ */
+ static void enableSwitchEvents();
+
+ //! Switches to meego graphics system.
+ /*!
+ When running with the 'runtime' graphics system, sets the currently active
+ system to 'meego'. The window surface and all the resources are automatically
+ migrated to OpenGL. Will fail if the active graphics system is not 'runtime'.
+ Calling this function will emit QMeeGoSwitchEvent to the top level widgets.
+ If switch events are enabled, two events will be emitted for each switch --
+ one before the switch (QMeeGoSwitchEvent::WillSwitch) and one after the
+ switch (QMeeGoSwitchEvent::DidSwitch).
+ If the switch policy is set to NoSwitch, this function has no effect.
+ */
+ static void switchToMeeGo();
+
+ //! Switches to raster graphics system
+ /*!
+ When running with the 'runtime' graphics system, sets the currently active
+ system to 'raster'. The window surface and the graphics resources (including the
+ EGL shared image resources) are automatically migrated back to the CPU. All OpenGL
+ resources (surface, context, cache, font cache) are automaticall anihilated.
+ Calling this function will emit QMeeGoSwitchEvent to the top level widgets. If switch
+ events are enabled, two events will be emitted for each switch -- one before the
+ switch (QMeeGoSwitchEvent::WillSwitch) and one after the switch (QMeeGoSwitchEvent::DidSwitch).
+ If the switch policy is set to NoSwitch, this function has no effect.
+ */
+ static void switchToRaster();
+
+ //! Used to specify the policy for graphics system switching.
+ enum SwitchPolicy {
+ AutomaticSwitch, /**< Automatic switching */
+ ManualSwitch, /**< Switching is controleld by the application */
+ NoSwitch /**< Switching is disabled completely */
+ };
+
+ //! Sets the policy of graphicssystem switching
+ /*!
+ By default, the switch to raster happens automatically when all windows are either
+ minimized or when the last window is destroyed. This function lets the application
+ change the graphicssystem switching policy to prevent the switching from happening
+ automatically (that is if the application doesn't want switching at all or wishes
+ to control the switching manually).
+ */
+ static void setSwitchPolicy(SwitchPolicy policy);
+
+ //! Returns the name of the active graphics system
+ /*!
+ Returns the name of the currently active system. If running with 'runtime' graphics
+ system, returns the name of the active system inside the runtime graphics system
+ */
+ static QString runningGraphicsSystemName();
+
+ //! Creates a new EGL shared image.
+ /*!
+ Creates a new EGL shared image from the given image. The EGL shared image wraps
+ a GL texture in the native format and can be easily accessed from other processes.
+ */
+ static Qt::HANDLE imageToEGLSharedImage(const QImage &image);
+
+ //! Creates a QPixmap from an EGL shared image
+ /*!
+ Creates a new QPixmap from the given EGL shared image handle. The QPixmap can be
+ used for painting like any other pixmap. The softImage should point to an alternative,
+ software version of the graphical resource -- ie. obtained from theme daemon. The
+ softImage can be allocated on a QSharedMemory slice for easy sharing across processes
+ too. When the application is migrated ToRaster, this softImage will replace the
+ contents of the sharedImage.
+
+ It's ok to call this function too when not running 'meego' graphics system. In this
+ case it'll create a QPixmap backed with a raster data (from softImage)... but when
+ the system is switched back to 'meego', the QPixmap will be migrated to a EGL-shared image
+ backed storage (handle).
+ */
+ static QPixmap pixmapFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
+
+ //! Destroys an EGL shared image.
+ /*!
+ Destroys an EGLSharedImage previously created with an ::imageToEGLSharedImage call.
+ Returns true if the image was found and the destruction was successful. Notice that
+ this destroys the image for all processes using it.
+ */
+ static bool destroyEGLSharedImage(Qt::HANDLE handle);
+
+ //! Updates the QPixmap backed with an EGLShared image.
+ /*!
+ This function re-reads the softImage that was specified when creating the pixmap with
+ ::pixmapFromEGLSharedImage and updates the EGL Shared image contents. It can be used
+ to share cross-proccess mutable EGLShared images.
+ */
+ static void updateEGLSharedImagePixmap(QPixmap *p);
+
+ //! Create a new QPixmap with a GL texture.
+ /*!
+ Creates a new QPixmap which is backed by an OpenGL local texture. Drawing to this
+ QPixmap will be accelerated by hardware -- unlike the normal (new QPixmap()) pixmaps,
+ which are backed by a software engine and only migrated to GPU when used. Migrating those
+ GL-backed pixmaps when going ToRaster is expsensive (they need to be downloaded from
+ GPU to CPU) so use wisely.
+ */
+ static QPixmap pixmapWithGLTexture(int w, int h);
+
+ //! Sets translucency (alpha) on the base window surface.
+ /*!
+ This function needs to be called *before* any widget/content is created.
+ When called with true, the base window surface will be translucent and initialized
+ with QGLFormat.alpha == true.
+
+ This function is *deprecated*. Set Qt::WA_TranslucentBackground attribute
+ on the top-level widget *before* you show it instead.
+ */
+ static void setTranslucent(bool translucent);
+
+ //! Used to specify the mode for swapping buffers in double-buffered GL rendering.
+ enum SwapMode {
+ AutomaticSwap, /**< Automatically choose netween full and partial updates (25% threshold) */
+ AlwaysFullSwap, /**< Always do a full swap even if partial updates support present */
+ AlwaysPartialSwap, /**< Always do a partial swap (if support present) no matter what threshold */
+ KillSwap /**< Do not perform buffer swapping at all (no picture) */
+ };
+
+ //! Sets the buffer swapping mode.
+ /*!
+ This can be only called when running with the meego graphics system.
+ The KillSwap mode can be specififed to effectively block painting.
+
+ This functionality should be used only by applications counting on a specific behavior.
+ Most applications should use the default automatic behavior.
+ */
+ static void setSwapBehavior(SwapMode mode);
+};
+
+#endif
diff --git a/src/qmeegographicssystemhelper/qmeegographicssystemhelper.pro b/src/qmeegographicssystemhelper/qmeegographicssystemhelper.pro
new file mode 100644
index 000000000..7639ad7b6
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegographicssystemhelper.pro
@@ -0,0 +1,10 @@
+TEMPLATE = lib
+TARGET = QtMeeGoGraphicsSystemHelper
+
+include(../../src/qbase.pri)
+
+QT += gui opengl
+INCLUDEPATH += '../../src/plugins/graphicssystems/meego'
+
+HEADERS = qmeegographicssystemhelper.h qmeegooverlaywidget.h qmeegolivepixmap.h qmeegoruntime.h qmeegolivepixmap_p.h qmeegofencesync.h qmeegofencesync_p.h qmeegoswitchevent.h
+SOURCES = qmeegographicssystemhelper.cpp qmeegooverlaywidget.cpp qmeegoruntime.cpp qmeegolivepixmap.cpp qmeegographicssystemhelper.h qmeegooverlaywidget.h qmeegolivepixmap.h qmeegoruntime.h qmeegolivepixmap_p.h qmeegofencesync.h qmeegofencesync_p.h qmeegofencesync.cpp qmeegoswitchevent.cpp qmeegoswitchevent.h
diff --git a/src/qmeegographicssystemhelper/qmeegolivepixmap.cpp b/src/qmeegographicssystemhelper/qmeegolivepixmap.cpp
new file mode 100644
index 000000000..a666e8550
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegolivepixmap.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegolivepixmap.h"
+#include "qmeegolivepixmap_p.h"
+#include "qmeegofencesync_p.h"
+#include "qmeegoruntime.h"
+
+/* QMeeGoLivePixmapPrivate */
+
+QMeeGoLivePixmapPrivate::QMeeGoLivePixmapPrivate()
+{
+}
+
+QMeeGoLivePixmapPrivate::~QMeeGoLivePixmapPrivate()
+{
+}
+
+/* QMeeGoLivePixmap */
+
+QMeeGoLivePixmap* QMeeGoLivePixmap::livePixmapWithSize(int w, int h, Format format)
+{
+ QImage::Format qtFormat;
+ if (format == Format_RGB16)
+ qtFormat = QImage::Format_RGB16;
+ else if (format == Format_ARGB32_Premultiplied)
+ qtFormat = QImage::Format_ARGB32_Premultiplied;
+ else {
+ qWarning("Unsupported live pixmap format!");
+ return 0;
+ }
+
+ QPixmapData *pmd = QMeeGoRuntime::pixmapDataWithNewLiveTexture(w, h, qtFormat);
+ if (! pmd) {
+ qWarning("Failed to create a live texture with given size!");
+ return NULL;
+ }
+
+ return new QMeeGoLivePixmap(pmd);
+}
+
+QMeeGoLivePixmap::QMeeGoLivePixmap(QPixmapData *p) : QPixmap(p), d_ptr(new QMeeGoLivePixmapPrivate())
+{
+ Q_D(QMeeGoLivePixmap);
+ d->q_ptr = this;
+}
+
+QMeeGoLivePixmap* QMeeGoLivePixmap::fromHandle(Qt::HANDLE liveTextureHandle)
+{
+ QPixmapData *pmd = QMeeGoRuntime::pixmapDataFromLiveTextureHandle(liveTextureHandle);
+ if (! pmd) {
+ qWarning("Failed to create a live texture from given handle!");
+ return NULL;
+ }
+
+ return new QMeeGoLivePixmap(pmd);
+}
+
+Qt::HANDLE QMeeGoLivePixmap::handle()
+{
+ return QMeeGoRuntime::getLiveTextureHandle(this);
+}
+
+QMeeGoLivePixmap::~QMeeGoLivePixmap()
+{
+}
+
+QImage* QMeeGoLivePixmap::lock(QMeeGoFenceSync *fenceSync)
+{
+ if (fenceSync)
+ return QMeeGoRuntime::lockLiveTexture(this, fenceSync->d_func()->syncObject);
+ else
+ return QMeeGoRuntime::lockLiveTexture(this, NULL);
+}
+
+void QMeeGoLivePixmap::release(QImage *img)
+{
+ QMeeGoRuntime::releaseLiveTexture(this, img);
+}
diff --git a/src/qmeegographicssystemhelper/qmeegolivepixmap.h b/src/qmeegographicssystemhelper/qmeegolivepixmap.h
new file mode 100644
index 000000000..dc7f9dee2
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegolivepixmap.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEEGOLIVEPIXMAP_H
+#define QMEEGOLIVEPIXMAP_H
+
+#include <QPixmap>
+#include "qmeegofencesync.h"
+
+class QMeeGoLivePixmapPrivate;
+class QSharedMemory;
+class QImage;
+
+//! A pixmap representing streamed content.
+/*!
+*/
+
+class Q_DECL_EXPORT QMeeGoLivePixmap : public QPixmap
+{
+public:
+ enum Format {
+ Format_RGB16, //! 16bit, 5-6-5 RGB format.
+ Format_ARGB32_Premultiplied //! 32bit, AARRGGBB format. The typical Qt format.
+ };
+
+ //! Creates and returns a new live pixmap with the given parameters.
+ /*!
+ The new pixmap is created with the given width w and the given height h.
+ The format specifies the color format used by the pixmap.
+ */
+ static QMeeGoLivePixmap* livePixmapWithSize(int w, int h, Format format);
+
+ //! Creates a new QMeeGoLivePixmap from the specified handle.
+ /*!
+ The handle can be used to share QMeeGoLivePixmap cross-process.
+ */
+ static QMeeGoLivePixmap* fromHandle(Qt::HANDLE handle);
+
+ //! Returns the handle for this QMeeGoLivePixmap.
+ /*!
+ The handle can be used to share QMeeGoLivePixmap cross-process.
+ */
+ Qt::HANDLE handle();
+
+ //! Locks the access to the pixmap.
+ /*!
+ The returned image can be used for direct access.
+ You can optionally specify a fence sync to wait upon before unlocking. When
+ you specify a fence sync, you can be sure that this function will return only
+ when the previsouly set QMeeGoFenceSync synchronization point has been executed/passed
+ by the GL processing pipeline.
+ */
+ QImage* lock(QMeeGoFenceSync *fenceSync = NULL);
+
+ //! Unlocks the access to the pixmap.
+ /*!
+ */
+ void release(QImage *img);
+
+ //! Destroys the QMeeGoLivePixmap.
+ /*!
+ */
+ virtual ~QMeeGoLivePixmap();
+
+private:
+ QMeeGoLivePixmap(QPixmapData *p);
+ Q_DISABLE_COPY(QMeeGoLivePixmap)
+ Q_DECLARE_PRIVATE(QMeeGoLivePixmap)
+
+protected:
+ QScopedPointer<QMeeGoLivePixmapPrivate> d_ptr; //! Private bits.
+};
+
+#endif
diff --git a/src/qmeegographicssystemhelper/qmeegolivepixmap_p.h b/src/qmeegographicssystemhelper/qmeegolivepixmap_p.h
new file mode 100644
index 000000000..193e3be84
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegolivepixmap_p.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegolivepixmap.h"
+
+#ifndef QMEEGOLIVEPIXMAP_P_H
+#define QMEEGOLIVEPIXMAP_P_H
+
+class QMeeGoLivePixmapPrivate
+{
+public:
+ Q_DECLARE_PUBLIC(QMeeGoLivePixmap);
+ QMeeGoLivePixmapPrivate();
+ virtual ~QMeeGoLivePixmapPrivate();
+
+ QMeeGoLivePixmap *q_ptr;
+};
+
+#endif
diff --git a/src/qmeegographicssystemhelper/qmeegooverlaywidget.cpp b/src/qmeegographicssystemhelper/qmeegooverlaywidget.cpp
new file mode 100644
index 000000000..6d7385d0c
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegooverlaywidget.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QEvent>
+#include <QMouseEvent>
+#include <QApplication>
+#include <QDesktopWidget>
+#include "qmeegooverlaywidget.h"
+#include "qmeegographicssystemhelper.h"
+#include "qmeegoruntime.h"
+
+QMeeGoOverlayWidget::QMeeGoOverlayWidget(int surfaceWidth, int surfaceHeight, QWidget *parent) : QWidget(parent, 0),
+ sw(surfaceWidth),
+ sh(surfaceHeight)
+{
+ if (! QMeeGoGraphicsSystemHelper::isRunningMeeGo())
+ qFatal("QMeeGoOverlayWidget can only be used when running with 'meego' graphics system!");
+
+ const QRect desktop = QApplication::desktop()->screenGeometry(parent);
+
+ QMeeGoRuntime::setSurfaceFixedSize(surfaceWidth, surfaceHeight);
+
+ scaleW = sw / desktop.width();
+ scaleH = sh / desktop.height();
+ installEventFilter(this);
+}
+
+QPoint QMeeGoOverlayWidget::convertPoint(const QPoint &p)
+{
+ int x = p.x() * scaleW;
+ int y = p.y() * scaleH;
+ return QPoint(x, y);
+}
+
+void QMeeGoOverlayWidget::showEvent(QShowEvent *)
+{
+ QMeeGoRuntime::setSurfaceScaling(0, 0, width(), height());
+}
+
+bool QMeeGoOverlayWidget::eventFilter(QObject *, QEvent *event)
+{
+ if (event->spontaneous() == false)
+ return false;
+
+ switch(event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ {
+ QMouseEvent *e = static_cast <QMouseEvent *>(event);
+ QMouseEvent newEvent = QMouseEvent(e->type(),
+ convertPoint(e->pos()),
+ convertPoint(e->globalPos()),
+ e->button(),
+ e->buttons(),
+ e->modifiers());
+ QCoreApplication::sendEvent(this, &newEvent);
+ return true;
+ }
+
+ default:
+ return false;
+ }
+}
diff --git a/src/qmeegographicssystemhelper/qmeegooverlaywidget.h b/src/qmeegographicssystemhelper/qmeegooverlaywidget.h
new file mode 100644
index 000000000..5db7866ff
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegooverlaywidget.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEEGOOVERLAYWIDGET_H
+#define QMEEGOOVERLAYWIDGET_H
+
+#include <QWidget>
+
+//! A widget automatically scaling it's content.
+/*!
+*/
+
+class Q_DECL_EXPORT QMeeGoOverlayWidget : public QWidget
+{
+public:
+ //! Constructs a new scaling widget.
+ /*!
+ The real surface used for this widget will have the specified
+ width and height.
+ */
+ QMeeGoOverlayWidget(int surfaceWidth, int surfaceHeight, QWidget *parent = 0);
+
+
+ //! Event filtering function.
+ /*!
+ Converts coordinates for mouse/touch event. Do not
+ call manually.
+ */
+ bool eventFilter(QObject *obj, QEvent *event);
+
+ //! Standard override.
+ /*!
+ The surface scaling on the target paint device is being
+ set when the widget is displayed for the first time.
+ */
+ virtual void showEvent(QShowEvent *event);
+
+private:
+ //! Converts coordinates between real & virtual area of the widget.
+ QPoint convertPoint(const QPoint &p);
+
+ int sw; /// Surface real width.
+ int sh; /// Surface real height.
+ float scaleW; /// Width scaling factor.
+ float scaleH; /// Height scaling factor.
+};
+
+#endif
diff --git a/src/qmeegographicssystemhelper/qmeegoruntime.cpp b/src/qmeegographicssystemhelper/qmeegoruntime.cpp
new file mode 100644
index 000000000..928d01a4a
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegoruntime.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegoruntime.h"
+
+#include "qmeegoswitchevent.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QWidget>
+
+#include <private/qlibrary_p.h>
+#include <private/qfactoryloader_p.h>
+#include <private/qgraphicssystemplugin_p.h>
+#include <stdio.h>
+
+#define ENSURE_INITIALIZED {if (!initialized) initialize();}
+
+bool QMeeGoRuntime::initialized = false;
+bool QMeeGoRuntime::switchEventsEnabled = false;
+
+typedef int (*QMeeGoImageToEglSharedImageFunc) (const QImage&);
+typedef QPixmapData* (*QMeeGoPixmapDataFromEglSharedImageFunc) (Qt::HANDLE handle, const QImage&);
+typedef QPixmapData* (*QMeeGoPixmapDataWithGLTextureFunc) (int w, int h);
+typedef bool (*QMeeGoDestroyEGLSharedImageFunc) (Qt::HANDLE handle);
+typedef void (*QMeeGoUpdateEglSharedImagePixmapFunc) (QPixmap*);
+typedef void (*QMeeGoSetSurfaceFixedSizeFunc) (int w, int h);
+typedef void (*QMeeGoSetSurfaceScalingFunc) (int x, int y, int w, int h);
+typedef void (*QMeeGoSetTranslucentFunc) (bool translucent);
+typedef QPixmapData* (*QMeeGoPixmapDataWithNewLiveTextureFunc) (int w, int h, QImage::Format format);
+typedef QPixmapData* (*QMeeGoPixmapDataFromLiveTextureHandleFunc) (Qt::HANDLE h);
+typedef QImage* (*QMeeGoLiveTextureLockFunc) (QPixmap*, void* fenceSync);
+typedef bool (*QMeeGoLiveTextureReleaseFunc) (QPixmap*, QImage *i);
+typedef Qt::HANDLE (*QMeeGoLiveTextureGetHandleFunc) (QPixmap*);
+typedef void* (*QMeeGoCreateFenceSyncFunc) (void);
+typedef void (*QMeeGoDestroyFenceSyncFunc) (void *fs);
+typedef void (*QMeeGoInvalidateLiveSurfacesFunc) (void);
+typedef void (*QMeeGoSwitchToRasterFunc) (void);
+typedef void (*QMeeGoSwitchToMeeGoFunc) (void);
+typedef void (*QMeeGoRegisterSwitchCallbackFunc) (void (*callback)(int type, const char *name));
+typedef void (*QMeeGoSetSwitchPolicyFunc) (int policy);
+
+static QMeeGoImageToEglSharedImageFunc qt_meego_image_to_egl_shared_image = NULL;
+static QMeeGoPixmapDataFromEglSharedImageFunc qt_meego_pixmapdata_from_egl_shared_image = NULL;
+static QMeeGoPixmapDataWithGLTextureFunc qt_meego_pixmapdata_with_gl_texture = NULL;
+static QMeeGoDestroyEGLSharedImageFunc qt_meego_destroy_egl_shared_image = NULL;
+static QMeeGoUpdateEglSharedImagePixmapFunc qt_meego_update_egl_shared_image_pixmap = NULL;
+static QMeeGoSetSurfaceFixedSizeFunc qt_meego_set_surface_fixed_size = NULL;
+static QMeeGoSetSurfaceScalingFunc qt_meego_set_surface_scaling = NULL;
+static QMeeGoSetTranslucentFunc qt_meego_set_translucent = NULL;
+static QMeeGoPixmapDataWithNewLiveTextureFunc qt_meego_pixmapdata_with_new_live_texture = NULL;
+static QMeeGoPixmapDataFromLiveTextureHandleFunc qt_meego_pixmapdata_from_live_texture_handle = NULL;
+static QMeeGoLiveTextureLockFunc qt_meego_live_texture_lock = NULL;
+static QMeeGoLiveTextureReleaseFunc qt_meego_live_texture_release = NULL;
+static QMeeGoLiveTextureGetHandleFunc qt_meego_live_texture_get_handle = NULL;
+static QMeeGoCreateFenceSyncFunc qt_meego_create_fence_sync = NULL;
+static QMeeGoDestroyFenceSyncFunc qt_meego_destroy_fence_sync = NULL;
+static QMeeGoInvalidateLiveSurfacesFunc qt_meego_invalidate_live_surfaces = NULL;
+static QMeeGoSwitchToRasterFunc qt_meego_switch_to_raster = NULL;
+static QMeeGoSwitchToMeeGoFunc qt_meego_switch_to_meego = NULL;
+static QMeeGoRegisterSwitchCallbackFunc qt_meego_register_switch_callback = NULL;
+static QMeeGoSetSwitchPolicyFunc qt_meego_set_switch_policy = NULL;
+
+extern "C" void handleSwitch(int type, const char *name)
+{
+ QMeeGoSwitchEvent switchEvent((QLatin1String(name)), QMeeGoSwitchEvent::State(type));
+ foreach (QWidget *widget, QApplication::topLevelWidgets())
+ QCoreApplication::sendEvent(widget, &switchEvent);
+}
+
+void QMeeGoRuntime::initialize()
+{
+ QFactoryLoader loader(QGraphicsSystemFactoryInterface_iid, QLatin1String("/graphicssystems"), Qt::CaseInsensitive);
+
+ QLibraryPrivate *libraryPrivate = loader.library(QLatin1String("meego"));
+ Q_ASSERT(libraryPrivate);
+
+ QLibrary library(libraryPrivate->fileName, libraryPrivate->fullVersion);
+
+ bool success = library.load();
+
+ if (success) {
+ qt_meego_image_to_egl_shared_image = (QMeeGoImageToEglSharedImageFunc) library.resolve("qt_meego_image_to_egl_shared_image");
+ qt_meego_pixmapdata_from_egl_shared_image = (QMeeGoPixmapDataFromEglSharedImageFunc) library.resolve("qt_meego_pixmapdata_from_egl_shared_image");
+ qt_meego_pixmapdata_with_gl_texture = (QMeeGoPixmapDataWithGLTextureFunc) library.resolve("qt_meego_pixmapdata_with_gl_texture");
+ qt_meego_destroy_egl_shared_image = (QMeeGoDestroyEGLSharedImageFunc) library.resolve("qt_meego_destroy_egl_shared_image");
+ qt_meego_update_egl_shared_image_pixmap = (QMeeGoUpdateEglSharedImagePixmapFunc) library.resolve("qt_meego_update_egl_shared_image_pixmap");
+ qt_meego_set_surface_fixed_size = (QMeeGoSetSurfaceFixedSizeFunc) library.resolve("qt_meego_set_surface_fixed_size");
+ qt_meego_set_surface_scaling = (QMeeGoSetSurfaceScalingFunc) library.resolve("qt_meego_set_surface_scaling");
+ qt_meego_set_translucent = (QMeeGoSetTranslucentFunc) library.resolve("qt_meego_set_translucent");
+ qt_meego_pixmapdata_with_new_live_texture = (QMeeGoPixmapDataWithNewLiveTextureFunc) library.resolve("qt_meego_pixmapdata_with_new_live_texture");
+ qt_meego_pixmapdata_from_live_texture_handle = (QMeeGoPixmapDataFromLiveTextureHandleFunc) library.resolve("qt_meego_pixmapdata_from_live_texture_handle");
+ qt_meego_live_texture_lock = (QMeeGoLiveTextureLockFunc) library.resolve("qt_meego_live_texture_lock");
+ qt_meego_live_texture_release = (QMeeGoLiveTextureReleaseFunc) library.resolve("qt_meego_live_texture_release");
+ qt_meego_live_texture_get_handle = (QMeeGoLiveTextureGetHandleFunc) library.resolve("qt_meego_live_texture_get_handle");
+ qt_meego_create_fence_sync = (QMeeGoCreateFenceSyncFunc) library.resolve("qt_meego_create_fence_sync");
+ qt_meego_destroy_fence_sync = (QMeeGoDestroyFenceSyncFunc) library.resolve("qt_meego_destroy_fence_sync");
+ qt_meego_invalidate_live_surfaces = (QMeeGoInvalidateLiveSurfacesFunc) library.resolve("qt_meego_invalidate_live_surfaces");
+ qt_meego_switch_to_raster = (QMeeGoSwitchToRasterFunc) library.resolve("qt_meego_switch_to_raster");
+ qt_meego_switch_to_meego = (QMeeGoSwitchToMeeGoFunc) library.resolve("qt_meego_switch_to_meego");
+ qt_meego_register_switch_callback = (QMeeGoRegisterSwitchCallbackFunc) library.resolve("qt_meego_register_switch_callback");
+ qt_meego_set_switch_policy = (QMeeGoSetSwitchPolicyFunc) library.resolve("qt_meego_set_switch_policy");
+
+ if (qt_meego_image_to_egl_shared_image && qt_meego_pixmapdata_from_egl_shared_image &&
+ qt_meego_pixmapdata_with_gl_texture && qt_meego_destroy_egl_shared_image && qt_meego_update_egl_shared_image_pixmap &&
+ qt_meego_set_surface_fixed_size && qt_meego_set_surface_scaling && qt_meego_set_translucent &&
+ qt_meego_pixmapdata_with_new_live_texture && qt_meego_pixmapdata_from_live_texture_handle &&
+ qt_meego_live_texture_lock && qt_meego_live_texture_release && qt_meego_live_texture_get_handle &&
+ qt_meego_create_fence_sync && qt_meego_destroy_fence_sync && qt_meego_invalidate_live_surfaces &&
+ qt_meego_switch_to_raster && qt_meego_switch_to_meego && qt_meego_register_switch_callback &&
+ qt_meego_set_switch_policy)
+ {
+ qDebug("Successfully resolved MeeGo graphics system: %s %s\n", qPrintable(libraryPrivate->fileName), qPrintable(libraryPrivate->fullVersion));
+ } else {
+ Q_ASSERT(false);
+ }
+ } else {
+ Q_ASSERT(false);
+ }
+
+ initialized = true;
+}
+
+Qt::HANDLE QMeeGoRuntime::imageToEGLSharedImage(const QImage &image)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_image_to_egl_shared_image);
+ return qt_meego_image_to_egl_shared_image(image);
+}
+
+QPixmapData* QMeeGoRuntime::pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_pixmapdata_from_egl_shared_image);
+ return qt_meego_pixmapdata_from_egl_shared_image(handle, softImage);
+}
+
+QPixmapData* QMeeGoRuntime::pixmapDataWithGLTexture(int w, int h)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_pixmapdata_with_gl_texture);
+ return qt_meego_pixmapdata_with_gl_texture(w, h);
+}
+
+bool QMeeGoRuntime::destroyEGLSharedImage(Qt::HANDLE handle)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_destroy_egl_shared_image);
+ return qt_meego_destroy_egl_shared_image(handle);
+}
+
+void QMeeGoRuntime::updateEGLSharedImagePixmap(QPixmap *p)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_update_egl_shared_image_pixmap);
+ return qt_meego_update_egl_shared_image_pixmap(p);
+}
+
+void QMeeGoRuntime::setSurfaceFixedSize(int w, int h)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_set_surface_fixed_size);
+ qt_meego_set_surface_fixed_size(w, h);
+}
+
+void QMeeGoRuntime::setSurfaceScaling(int x, int y, int w, int h)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_set_surface_scaling);
+ qt_meego_set_surface_scaling(x, y, w, h);
+}
+
+void QMeeGoRuntime::setTranslucent(bool translucent)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_set_translucent);
+ qt_meego_set_translucent(translucent);
+}
+
+QPixmapData* QMeeGoRuntime::pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_pixmapdata_with_new_live_texture);
+ return qt_meego_pixmapdata_with_new_live_texture(w, h, format);
+}
+
+QPixmapData* QMeeGoRuntime::pixmapDataFromLiveTextureHandle(Qt::HANDLE h)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_pixmapdata_from_live_texture_handle);
+ return qt_meego_pixmapdata_from_live_texture_handle(h);
+}
+
+QImage* QMeeGoRuntime::lockLiveTexture(QPixmap *p, void* fenceSync)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_live_texture_lock);
+ return qt_meego_live_texture_lock(p, fenceSync);
+}
+
+bool QMeeGoRuntime::releaseLiveTexture(QPixmap *p, QImage *i)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_live_texture_release);
+ return qt_meego_live_texture_release(p, i);
+}
+
+Qt::HANDLE QMeeGoRuntime::getLiveTextureHandle(QPixmap *pixmap)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_live_texture_get_handle);
+ return qt_meego_live_texture_get_handle(pixmap);
+}
+
+void* QMeeGoRuntime::createFenceSync()
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_create_fence_sync);
+ return qt_meego_create_fence_sync();
+}
+
+void QMeeGoRuntime::destroyFenceSync(void *fs)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_destroy_fence_sync);
+ qt_meego_destroy_fence_sync(fs);
+}
+
+void QMeeGoRuntime::invalidateLiveSurfaces()
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_invalidate_live_surfaces);
+ qt_meego_invalidate_live_surfaces();
+}
+
+void QMeeGoRuntime::switchToRaster()
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_switch_to_raster);
+ qt_meego_switch_to_raster();
+}
+
+void QMeeGoRuntime::switchToMeeGo()
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_switch_to_meego);
+ qt_meego_switch_to_meego();
+}
+
+void QMeeGoRuntime::enableSwitchEvents()
+{
+ ENSURE_INITIALIZED;
+ if (!switchEventsEnabled) {
+ Q_ASSERT(qt_meego_register_switch_callback);
+ qt_meego_register_switch_callback(handleSwitch);
+ switchEventsEnabled = true;
+ }
+}
+
+void QMeeGoRuntime::setSwitchPolicy(QMeeGoGraphicsSystemHelper::SwitchPolicy policy)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_set_switch_policy);
+ qt_meego_set_switch_policy(int(policy));
+}
diff --git a/src/qmeegographicssystemhelper/qmeegoruntime.h b/src/qmeegographicssystemhelper/qmeegoruntime.h
new file mode 100644
index 000000000..b8986997a
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegoruntime.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QPixmap>
+#include <QImage>
+
+#include "qmeegographicssystemhelper.h"
+
+class QMeeGoRuntime
+{
+public:
+ static void initialize();
+
+ static Qt::HANDLE imageToEGLSharedImage(const QImage &image);
+ static QPixmapData* pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
+ static QPixmapData* pixmapDataWithGLTexture(int w, int h);
+ static bool destroyEGLSharedImage(Qt::HANDLE handle);
+ static void updateEGLSharedImagePixmap(QPixmap *p);
+ static void setSurfaceFixedSize(int w, int h);
+ static void setSurfaceScaling(int x, int y, int w, int h);
+ static void setTranslucent(bool translucent);
+ static QPixmapData* pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format);
+ static QPixmapData* pixmapDataFromLiveTextureHandle(Qt::HANDLE h);
+ static QImage* lockLiveTexture(QPixmap *pixmap, void *fenceSync);
+ static bool releaseLiveTexture(QPixmap *pixmap, QImage *image);
+ static Qt::HANDLE getLiveTextureHandle(QPixmap *pixmap);
+ static void* createFenceSync();
+ static void destroyFenceSync(void *fs);
+ static void invalidateLiveSurfaces();
+ static void switchToRaster();
+ static void switchToMeeGo();
+ static void enableSwitchEvents();
+ static void setSwitchPolicy(QMeeGoGraphicsSystemHelper::SwitchPolicy policy);
+
+private:
+ static bool initialized;
+ static bool switchEventsEnabled;
+};
diff --git a/src/qmeegographicssystemhelper/qmeegoswitchevent.cpp b/src/qmeegographicssystemhelper/qmeegoswitchevent.cpp
new file mode 100644
index 000000000..b833e31b0
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegoswitchevent.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegoswitchevent.h"
+
+static int switchEventNumber = -1;
+
+QMeeGoSwitchEvent::QMeeGoSwitchEvent(const QString &graphicsSystemName, QMeeGoSwitchEvent::State s) : QEvent(QMeeGoSwitchEvent::eventNumber())
+{
+ name = graphicsSystemName;
+ switchState = s;
+}
+
+QString QMeeGoSwitchEvent::graphicsSystemName() const
+{
+ return name;
+}
+
+QMeeGoSwitchEvent::State QMeeGoSwitchEvent::state() const
+{
+ return switchState;
+}
+
+QEvent::Type QMeeGoSwitchEvent::eventNumber()
+{
+ if (switchEventNumber < 0)
+ switchEventNumber = QEvent::registerEventType();
+
+ return (QEvent::Type) switchEventNumber;
+}
diff --git a/src/qmeegographicssystemhelper/qmeegoswitchevent.h b/src/qmeegographicssystemhelper/qmeegoswitchevent.h
new file mode 100644
index 000000000..734573f09
--- /dev/null
+++ b/src/qmeegographicssystemhelper/qmeegoswitchevent.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QEvent>
+#include <QString>
+
+//! A custom event representing a graphics system switch.
+/*!
+ This event is sent two times -- before the actual switch and after the switch.
+ The current mode of the event can be detected by looking at the State of the
+ event.
+
+ The end-user application can use the event to drop it's own allocated GL resources
+ when going to software mode.
+*/
+
+class Q_DECL_EXPORT QMeeGoSwitchEvent : public QEvent
+{
+public:
+
+ //! The state represented by this event.
+ enum State {
+ WillSwitch,
+ DidSwitch
+ };
+
+ //! Constructor for the event.
+ /*!
+ Creates a new event with the given name and the given state.
+ */
+ QMeeGoSwitchEvent(const QString &graphicsSystemName, State s);
+
+ //! Returns the name of the target graphics system.
+ /*!
+ Depending on the state, the name represents the system we're about to swtich to,
+ or the system we just switched to.
+ */
+ QString graphicsSystemName() const;
+
+ //! Returns the state represented by this event.
+ State state() const;
+
+ //! Returns the event type/number for QMeeGoSwitchEvent.
+ /*!
+ The type is registered on first access. Use this to detect incoming
+ QMeeGoSwitchEvents.
+ */
+ static QEvent::Type eventNumber();
+
+private:
+ QString name;
+ State switchState;
+};
diff --git a/src/qtconcurrent/codegenerator/codegenerator.pri b/src/qtconcurrent/codegenerator/codegenerator.pri
new file mode 100644
index 000000000..0aeabab91
--- /dev/null
+++ b/src/qtconcurrent/codegenerator/codegenerator.pri
@@ -0,0 +1,5 @@
+SOURCES += $$PWD/src/codegenerator.cpp
+HEADERS += $$PWD/src/codegenerator.h
+INCLUDEPATH += $$PWD/src
+DEPENDPATH += $$PWD/src
+
diff --git a/src/qtconcurrent/codegenerator/example/example.pro b/src/qtconcurrent/codegenerator/example/example.pro
new file mode 100644
index 000000000..df266fe63
--- /dev/null
+++ b/src/qtconcurrent/codegenerator/example/example.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET +=
+DEPENDPATH += .
+INCLUDEPATH += .
+
+include (../codegenerator.pri)
+
+# Input
+SOURCES += main.cpp
diff --git a/src/qtconcurrent/codegenerator/example/main.cpp b/src/qtconcurrent/codegenerator/example/main.cpp
new file mode 100644
index 000000000..15dcfc505
--- /dev/null
+++ b/src/qtconcurrent/codegenerator/example/main.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QDebug>
+#include "codegenerator.h"
+using namespace CodeGenerator;
+
+int main()
+{
+ // The code generator works on items. Each item has a generate() function:
+ Item item("");
+ qDebug() << item.generate(); // produces "".
+
+ // There are several Item subclasses. Text items contains a text string which they
+ // reproduce when generate is called:
+ Text text(" Hi there");
+ qDebug() << text.generate(); // produces " Hi there".
+
+ // Items can be concatenated:
+ Item sentence = text + Text(" Bye there") ;
+ qDebug() << sentence.generate(); // produces "Hi there Bye there".
+ // (Internally, this creates a tree of items, and generate is called recursively
+ // for items that have children.)
+
+ // Repeater items repeat their content when generate is called:
+ Repeater repeater = text;
+ repeater.setRepeatCount(3);
+ qDebug() << repeater.generate(); // produces "Hi there Hi there Hi there".
+
+ // Counters evaluate to the current repeat index.
+ Repeater repeater2 = text + Counter();
+ repeater2.setRepeatCount(3);
+ qDebug() << repeater2.generate(); // produces "Hi there0 Hi there1 Hi there2".
+
+ // Groups provide sub-groups which are repeated according to the current repeat index.
+ // Counters inside Groups evaluate to the local repeat index for the Group.
+ Group arguments("Arg" + Counter() + " arg" + Counter());
+ Repeater function("void foo(" + arguments + ");\n");
+ function.setRepeatCount(3);
+ qDebug() << function.generate();
+
+ // Produces:
+ // void foo(Arg1 arg1);
+ // void foo(Arg1 arg1, Arg2 arg2);
+ // void foo(Arg1 arg1, Arg2 arg2, Arg3 arg3);
+}
diff --git a/src/qtconcurrent/codegenerator/src/codegenerator.cpp b/src/qtconcurrent/codegenerator/src/codegenerator.cpp
new file mode 100644
index 000000000..dce7bad90
--- /dev/null
+++ b/src/qtconcurrent/codegenerator/src/codegenerator.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "codegenerator.h"
+#include <qdebug.h>
+namespace CodeGenerator
+{
+
+//Convenience constructor so you can say Item("foo")
+Item::Item(const char * const text) : generator(Text(QByteArray(text)).generator) {}
+
+int BaseGenerator::currentCount(GeneratorStack * const stack) const
+{
+ const int stackSize = stack->count();
+ for (int i = stackSize - 1; i >= 0; --i) {
+ BaseGenerator const * const generator = stack->at(i);
+ switch (generator->type) {
+ case RepeaterType: {
+ RepeaterGenerator const * const repeater = static_cast<RepeaterGenerator const * const>(generator);
+ return repeater->currentRepeat;
+ } break;
+ case GroupType: {
+ GroupGenerator const * const group = static_cast<GroupGenerator const * const>(generator);
+ return group->currentRepeat;
+ } break;
+ default:
+ break;
+ }
+ }
+ return -1;
+}
+
+int BaseGenerator::repeatCount(GeneratorStack * const stack) const
+{
+ const int stackSize = stack->count();
+ for (int i = stackSize - 1; i >= 0; --i) {
+ BaseGenerator const * const generator = stack->at(i);
+ switch (generator->type) {
+ case RepeaterType: {
+ RepeaterGenerator const * const repeater = static_cast<RepeaterGenerator const * const>(generator);
+ return repeater->currentRepeat;
+ } break;
+/* case GroupType: {
+ GroupGenerator const * const group = static_cast<GroupGenerator const * const>(generator);
+ return group->currentRepeat;
+ } break;
+*/
+ default:
+ break;
+ }
+ }
+ return -1;
+}
+
+QByteArray RepeaterGenerator::generate(GeneratorStack * const stack)
+{
+ GeneratorStacker stacker(stack, this);
+ QByteArray generated;
+ for (int i = repeatOffset; i < repeatCount + repeatOffset; ++i) {
+ currentRepeat = i;
+ generated += childGenerator->generate(stack);
+ }
+ return generated;
+};
+
+QByteArray GroupGenerator::generate(GeneratorStack * const stack)
+{
+ const int repeatCount = currentCount(stack);
+ GeneratorStacker stacker(stack, this);
+ QByteArray generated;
+
+ if (repeatCount > 0)
+ generated += prefix->generate(stack);
+
+ for (int i = 1; i <= repeatCount; ++i) {
+ currentRepeat = i;
+ generated += childGenerator->generate(stack);
+ if (i != repeatCount)
+ generated += separator->generate(stack);
+ }
+
+ if (repeatCount > 0)
+ generated += postfix->generate(stack);
+
+ return generated;
+};
+
+const Compound operator+(const Item &a, const Item &b)
+{
+ return Compound(a, b);
+}
+
+const Compound operator+(const Item &a, const char * const text)
+{
+ return Compound(a, Text(text));
+}
+
+const Compound operator+(const char * const text, const Item &b)
+{
+ return Compound(Text(text), b);
+}
+
+} \ No newline at end of file
diff --git a/src/qtconcurrent/codegenerator/src/codegenerator.h b/src/qtconcurrent/codegenerator/src/codegenerator.h
new file mode 100644
index 000000000..1d0fcd994
--- /dev/null
+++ b/src/qtconcurrent/codegenerator/src/codegenerator.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CODEGENERATOR_H
+#define CODEGENERATOR_H
+
+#include <QByteArray>
+#include <QString>
+#include <QList>
+#include <QStack>
+
+namespace CodeGenerator
+{
+ enum GeneratorType {NoopType, CompoundType, TextType, RepeaterType, CounterType, GroupType};
+ class BaseGenerator;
+ typedef QStack<BaseGenerator *> GeneratorStack;
+
+ template <typename ValueType>
+ class Stacker {
+ public:
+ Stacker(QStack<ValueType> *stack, ValueType value) : stack(stack) { stack->push(value); }
+ ~Stacker() { stack->pop();}
+ private:
+ QStack<ValueType> *stack;
+ };
+ typedef Stacker<BaseGenerator *> GeneratorStacker;
+
+ class BaseGenerator
+ {
+ public:
+ BaseGenerator(GeneratorType type = NoopType) : type(type) {}
+ virtual ~BaseGenerator() {};
+ virtual QByteArray generate(GeneratorStack *stack) { Q_UNUSED(stack); return QByteArray(); };
+ int currentCount(GeneratorStack *stack) const;
+ int repeatCount(GeneratorStack *stack) const;
+ GeneratorType type;
+ };
+
+ class Item
+ {
+ public:
+ Item(BaseGenerator * const base) : generator(base) {}
+ Item(const char * const text);
+ QByteArray generate() const
+ { GeneratorStack stack; return generator->generate(&stack); }
+ // ### TODO: Fix memory leak!
+ // QExplicitlySharedDataPointer<BaseGenerator> generator;
+ BaseGenerator * const generator;
+ };
+
+ class CompoundGenerator : public BaseGenerator
+ {
+ public:
+ CompoundGenerator(BaseGenerator * const a, BaseGenerator * const b)
+ : BaseGenerator(CompoundType), a(a), b(b) {}
+ virtual QByteArray generate(GeneratorStack *stack)
+ { return a->generate(stack) + b->generate(stack); };
+ protected:
+ BaseGenerator * const a;
+ BaseGenerator * const b;
+ };
+
+ class Compound : public Item
+ {
+ public:
+ Compound(const Item &a, const Item &b) : Item(new CompoundGenerator(a.generator, b.generator)) {}
+ };
+
+ class TextGenerator : public BaseGenerator
+ {
+ public:
+ TextGenerator(const QByteArray &text) : BaseGenerator(TextType), text(text) {}
+ virtual QByteArray generate(GeneratorStack *) { return text; };
+ protected:
+ QByteArray text;
+ };
+
+ class Text : public Item {
+ public:
+ Text(const QByteArray &text) : Item(new TextGenerator(text)) {}
+ Text(const char * const text) : Item(new TextGenerator(QByteArray(text))) {}
+ };
+
+ class RepeaterGenerator : public BaseGenerator
+ {
+ public:
+ RepeaterGenerator(BaseGenerator * const childGenerator)
+ : BaseGenerator(RepeaterType), repeatCount(1), repeatOffset(0), childGenerator(childGenerator) {}
+ virtual QByteArray generate(GeneratorStack *stack);
+
+ int repeatCount;
+ int repeatOffset;
+ int currentRepeat;
+ BaseGenerator * const childGenerator;
+ };
+
+ class Repeater : public Item {
+ public:
+ Repeater(const Item &item) : Item(new RepeaterGenerator(item.generator)) {}
+ void setRepeatCount(int count)
+ { static_cast<RepeaterGenerator * const>(generator)->repeatCount = count; }
+ void setRepeatOffset(int offset)
+ { static_cast<RepeaterGenerator * const>(generator)->repeatOffset = offset; }
+ };
+
+ class CounterGenerator : public BaseGenerator
+ {
+ public:
+ CounterGenerator() : BaseGenerator(CounterType), offset(0), increment(1), reverse(false) {}
+ QByteArray generate(GeneratorStack *stack)
+ {
+ if (reverse)
+ return QByteArray::number(repeatCount(stack) - (currentCount(stack) * increment) + offset + 1);
+ else
+ return QByteArray::number((currentCount(stack) * increment) + offset);
+ }
+ int offset;
+ int increment;
+ bool reverse;
+ };
+
+ class Counter : public Item {
+ public:
+ Counter() : Item(new CounterGenerator()) {}
+ Counter(int offset) : Item(new CounterGenerator()) { setOffset(offset); }
+ void setOffset(int offset)
+ { static_cast<CounterGenerator *>(generator)->offset = offset; }
+ void setIncrement(int increment)
+ { static_cast<CounterGenerator *>(generator)->increment = increment; }
+ void setReverse(bool reverse)
+ { static_cast<CounterGenerator *>(generator)->reverse = reverse; }
+
+ };
+
+ class GroupGenerator : public BaseGenerator
+ {
+ public:
+ GroupGenerator(BaseGenerator * const childGenerator)
+ : BaseGenerator(GroupType), currentRepeat(0), childGenerator(childGenerator),
+ separator(new BaseGenerator()), prefix(new BaseGenerator()), postfix(new BaseGenerator()) { }
+ virtual QByteArray generate(GeneratorStack *stack);
+ int currentRepeat;
+ BaseGenerator * const childGenerator;
+ BaseGenerator *separator;
+ BaseGenerator *prefix;
+ BaseGenerator *postfix;
+ };
+
+ class Group : public Item
+ {
+ public:
+ Group(const Item &item) : Item(new GroupGenerator(item.generator)) { setSeparator(", "); }
+ void setSeparator(const Item &separator)
+ { static_cast<GroupGenerator *>(generator)->separator = separator.generator; }
+ void setPrefix(const Item &prefix)
+ { static_cast<GroupGenerator *>(generator)->prefix = prefix.generator; }
+ void setPostfix(const Item &postfix)
+ { static_cast<GroupGenerator *>(generator)->postfix = postfix.generator; }
+ };
+
+ const Compound operator+(const Item &a, const Item &b);
+ const Compound operator+(const Item &a, const char * const text);
+ const Compound operator+(const char * const text, const Item &b);
+
+} //namespace CodeGenerator
+
+#endif
diff --git a/src/qtconcurrent/generaterun/main.cpp b/src/qtconcurrent/generaterun/main.cpp
new file mode 100644
index 000000000..051e3082c
--- /dev/null
+++ b/src/qtconcurrent/generaterun/main.cpp
@@ -0,0 +1,418 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QApplication>
+#include <QDebug>
+#include <QFile>
+
+#include "codegenerator.h"
+using namespace CodeGenerator;
+
+const Item argument = "arg" + Counter();
+const Item argumentRef = "&arg" + Counter();
+const Item argumentType = "Arg" + Counter();
+const Item constArgumentType = "const Arg" + Counter();
+const Item parameterType = "Param" + Counter();
+
+Group argumentTypes(argumentType); // expands to ",Arg1, Arg2, ..."
+Group argumentTypesNoPrefix(argumentType); // expands to "Arg1, Arg2, ..."
+Group arguments(argument); // expands to ",arg1, arg2, ..."
+Group argumentsNoPrefix(argument); // expands to "arg1, arg2, ..."
+Group parameterTypes(parameterType); // expands to ",Param1, Param2, ..."
+Group parameterTypesNoPrefix(parameterType); // expands to "Param1, Param2, ..."
+Group typenameTypes("typename " + parameterType + ", typename " + argumentType); // expands to " ,typename Param1, typename Arg1, ..."
+Group types(parameterType + ", " + argumentType); // expands to ", Param1, Arg1, ..."
+Group functionParameters(constArgumentType + " " + argumentRef);
+Group typenameArgumentTypes("typename " + argumentType);
+
+Group initializers(argument + "(" + argument + ")");
+Group classData(argumentType +" " + argument + ";");
+Group arglist(argument);
+Group typeList(argumentTypes);
+
+void init()
+{
+ argumentTypes.setPrefix(", ");
+ arguments.setPrefix(", ");
+ parameterTypes.setPrefix(", ");
+ typenameTypes.setPrefix(", ");
+ types.setPrefix(", ");
+ functionParameters.setPrefix(", ");
+ typenameArgumentTypes.setPrefix(", ");
+
+ initializers.setPrefix(", ");
+ classData.setSeparator(" ");
+ classData.setPrefix(" ");
+ arglist.setPrefix(", ");
+ typeList.setPrefix(", ");
+}
+
+
+Item Line(Item item)
+{
+ return item + "\n";
+}
+
+Item generateRunFunctions(int repeats)
+{
+ Item functionPointerType = "T (*)(" + parameterTypesNoPrefix + ")";
+
+ Item functionPointerParameter = "T (*functionPointer)(" + parameterTypesNoPrefix + ")";
+
+
+
+ // plain functions
+ Repeater functions = Line ("template <typename T" + typenameTypes + ">") +
+ Line ("QFuture<T> run(" + functionPointerParameter + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new QT_TYPENAME SelectStoredFunctorCall" + Counter() + "<T, " +
+ functionPointerType + argumentTypes + ">::type(functionPointer" + arguments + "))->start();") +
+ Line("}");
+ functions.setRepeatCount(repeats);
+
+ // function objects by value
+ Repeater functionObjects = Line ("template <typename FunctionObject" + typenameArgumentTypes + ">") +
+ Line ("QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject" + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new QT_TYPENAME SelectStoredFunctorCall" + Counter() +
+ "<QT_TYPENAME FunctionObject::result_type, FunctionObject" +
+ argumentTypes + ">::type(functionObject" + arguments + "))->start();") +
+ Line("}");
+ functionObjects.setRepeatCount(repeats);
+
+ // function objects by pointer
+ Repeater functionObjectsPointer = Line ("template <typename FunctionObject" + typenameArgumentTypes + ">") +
+ Line ("QFuture<typename FunctionObject::result_type> run(FunctionObject *functionObject" + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new QT_TYPENAME SelectStoredFunctorPointerCall" + Counter() +
+ "<QT_TYPENAME FunctionObject::result_type, FunctionObject" +
+ argumentTypes + ">::type(functionObject" + arguments + "))->start();") +
+ Line("}");
+ functionObjectsPointer.setRepeatCount(repeats);
+
+ // member functions by value
+ Repeater memberFunction = Line ("template <typename T, typename Class" + typenameTypes + ">") +
+ Line ("QFuture<T> run(const Class &object, T (Class::*fn)(" + parameterTypesNoPrefix + ")" + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new QT_TYPENAME SelectStoredMemberFunctionCall" + Counter() +
+ "<T, Class" +
+ types + ">::type(fn, object" + arguments + "))->start();") +
+ Line("}");
+ memberFunction.setRepeatCount(repeats);
+
+ // const member functions by value
+ Repeater constMemberFunction = Line ("template <typename T, typename Class" + typenameTypes + ">") +
+ Line ("QFuture<T> run(const Class &object, T (Class::*fn)(" + parameterTypesNoPrefix + ") const" + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new QT_TYPENAME SelectStoredConstMemberFunctionCall" + Counter() +
+ "<T, Class" +
+ types + ">::type(fn, object" + arguments + "))->start();") +
+ Line("}");
+ constMemberFunction.setRepeatCount(repeats);
+
+ // member functions by class pointer
+ Repeater memberFunctionPointer = Line ("template <typename T, typename Class" + typenameTypes + ">") +
+ Line ("QFuture<T> run(Class *object, T (Class::*fn)(" + parameterTypesNoPrefix + ")" + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new QT_TYPENAME SelectStoredMemberFunctionPointerCall" + Counter() +
+ "<T, Class" +
+ types + ">::type(fn, object" + arguments + "))->start();") +
+ Line("}");
+ memberFunctionPointer.setRepeatCount(repeats);
+
+ // const member functions by class pointer
+ Repeater constMemberFunctionPointer = Line ("template <typename T, typename Class" + typenameTypes + ">") +
+ Line ("QFuture<T> run(const Class *object, T (Class::*fn)(" + parameterTypesNoPrefix + ") const" + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new QT_TYPENAME SelectStoredConstMemberFunctionPointerCall" + Counter() +
+ "<T, Class" +
+ types + ">::type(fn, object" + arguments + "))->start();") +
+ Line("}");
+ constMemberFunctionPointer.setRepeatCount(repeats);
+
+
+ Item interfaceFunctionPointerType = "void (*)(QFutureInterface<T> &" + argumentTypes + ")";
+ Item interfaceFunctionPointerParameter = "void (*functionPointer)(QFutureInterface<T> &" + argumentTypes + ")";
+/*
+ // QFutureInterface functions
+ Repeater interfaceFunctions = Line ("template <typename T" + typenameTypes + ">") +
+ Line ("QFuture<T> run(" + interfaceFunctionPointerParameter + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new StoredInterfaceFunctionCall" + Counter() + "<T, " +
+ interfaceFunctionPointerType + typenameArgumentTypes + ">(functionPointer" + arguments + "))->start();") +
+ Line("}");
+ functions.setRepeatCount(repeats);
+ interfaceFunctions.setRepeatCount(repeats);
+
+ // member functions by class pointer
+ Repeater interfaceMemberFunction = Line ("template <typename Class, typename T" + typenameTypes + ">") +
+ Line ("QFuture<T> run(void (Class::*fn)(QFutureInterface<T> &), Class *object" + functionParameters + ")") +
+ Line("{") +
+ Line(" return (new StoredInterfaceMemberFunctionCall" + Counter() +
+ "<T, void (Class::*)(QFutureInterface<T> &), Class" +
+ typenameArgumentTypes + ">(fn, object" + arguments + "))->start();") +
+ Line("}");
+ memberFunctionPointer.setRepeatCount(repeats);
+*/
+ return functions + Line("") + functionObjects + Line("") + functionObjectsPointer + Line("")
+ + memberFunction + Line("") + constMemberFunction + Line("")
+ + memberFunctionPointer + Line("") + constMemberFunctionPointer + Line("")
+ /* + interfaceFunctions + Line("") + interfaceMemberFunction + Line("")*/
+ ;
+}
+
+
+Item functions(Item className, Item functorType, Item callLine)
+{
+ return
+ Line("template <typename T, typename FunctionPointer" + typenameArgumentTypes + ">") +
+ Line("struct " + className + Counter() +": public RunFunctionTask<T>") +
+ Line("{") +
+ Line(" inline " + className + Counter() + "(" + functorType + " function" + functionParameters +")") +
+ Line(" : function(function)" + initializers + " {}") +
+ Line(" void runFunctor() {" + callLine + argumentsNoPrefix + "); }") +
+ Line(" " + functorType + " function;") +
+ Line( classData) +
+ Line("};") +
+ Line("");
+}
+
+Item functionSelector(Item classNameBase)
+{
+ return
+ Line("template <typename T, typename FunctionPointer" + typenameArgumentTypes + ">") +
+ Line("struct Select" + classNameBase + Counter()) +
+ Line("{") +
+ Line(" typedef typename SelectSpecialization<T>::template") +
+ Line(" Type<" + classNameBase + Counter() + " <T, FunctionPointer" + argumentTypes + ">,") +
+ Line(" Void" + classNameBase + Counter() + "<T, FunctionPointer" + argumentTypes + "> >::type type;") +
+ Line("};");
+}
+
+Item memberFunctions(Item className, Item constFunction, Item objectArgument, Item objectMember, Item callLine)
+{
+ return
+ Line("template <typename T, typename Class" + typenameTypes + ">") +
+ Line("class " + className + Counter() + " : public RunFunctionTask<T>") +
+ Line("{") +
+ Line("public:")+
+ Line(" " + className + Counter() + "(T (Class::*fn)(" + parameterTypesNoPrefix + ") " + constFunction + ", " + objectArgument + functionParameters + ")") +
+ Line(" : fn(fn), object(object)" + initializers + "{ }" ) +
+ Line("")+
+ Line(" void runFunctor()")+
+ Line(" {")+
+ Line(" " + callLine + argumentsNoPrefix + ");")+
+ Line(" }")+
+ Line("private:")+
+ Line(" T (Class::*fn)(" + parameterTypesNoPrefix + ")" + constFunction + ";")+
+ Line(" " + objectMember + ";") +
+ Line( classData) +
+ Line("};");
+}
+
+Item memberFunctionSelector(Item classNameBase)
+{
+ return
+ Line("template <typename T, typename Class" + typenameTypes + ">") +
+ Line("struct Select" + classNameBase + Counter()) +
+ Line("{") +
+ Line(" typedef typename SelectSpecialization<T>::template") +
+ Line(" Type<" + classNameBase + Counter() + " <T, Class" + types + ">,") +
+ Line(" Void" + classNameBase + Counter() + "<T, Class" + types + "> >::type type;") +
+ Line("};");
+}
+
+Item generateSFCs(int repeats)
+{
+
+ Item functionPointerTypedef = "typedef void (*FunctionPointer)(" + argumentTypesNoPrefix + ");";
+
+ Repeater dataStructures =
+
+ // Function objects by value
+ functions(Item("StoredFunctorCall"), Item("FunctionPointer"), Item(" this->result = function(")) +
+ functions(Item("VoidStoredFunctorCall"), Item("FunctionPointer"), Item(" function(")) +
+ functionSelector(Item("StoredFunctorCall")) +
+
+ // Function objects by pointer
+ functions(Item("StoredFunctorPointerCall"), Item("FunctionPointer *"), Item(" this->result =(*function)(")) +
+ functions(Item("VoidStoredFunctorPointerCall"), Item("FunctionPointer *"), Item("(*function)(")) +
+ functionSelector(Item("StoredFunctorPointerCall")) +
+
+ // Member functions by value
+ memberFunctions(Item("StoredMemberFunctionCall"), Item(""), Item("const Class &object"), Item("Class object"), Item("this->result = (object.*fn)(")) +
+ memberFunctions(Item("VoidStoredMemberFunctionCall"), Item(""), Item("const Class &object"), Item("Class object"), Item("(object.*fn)(")) +
+ memberFunctionSelector(Item("StoredMemberFunctionCall")) +
+
+ // Const Member functions by value
+ memberFunctions(Item("StoredConstMemberFunctionCall"), Item("const"), Item("const Class &object"), Item("const Class object"), Item("this->result = (object.*fn)(")) +
+ memberFunctions(Item("VoidStoredConstMemberFunctionCall"), Item("const"), Item("const Class &object"), Item("const Class object"), Item("(object.*fn)(")) +
+ memberFunctionSelector(Item("StoredConstMemberFunctionCall")) +
+
+ // Member functions by pointer
+ memberFunctions(Item("StoredMemberFunctionPointerCall"), Item(""), Item("Class *object"), Item("Class *object"), Item("this->result = (object->*fn)(")) +
+ memberFunctions(Item("VoidStoredMemberFunctionPointerCall"), Item(""), Item("Class *object"), Item("Class *object"), Item("(object->*fn)(")) +
+ memberFunctionSelector(Item("StoredMemberFunctionPointerCall")) +
+
+ // const member functions by pointer
+ memberFunctions(Item("StoredConstMemberFunctionPointerCall"), Item("const"), Item("Class const *object"), Item("Class const *object"), Item("this->result = (object->*fn)(")) +
+ memberFunctions(Item("VoidStoredConstMemberFunctionPointerCall"), Item("const"), Item("Class const *object"), Item("Class const *object"), Item("(object->*fn)(")) +
+ memberFunctionSelector(Item("StoredConstMemberFunctionPointerCall"));
+
+ dataStructures.setRepeatCount(repeats);
+ return dataStructures;
+}
+
+void writeFile(QString fileName, QByteArray contents)
+{
+ QFile runFile(fileName);
+ if (runFile.open(QIODevice::WriteOnly) == false) {
+ qDebug() << "Write to" << fileName << "failed";
+ return;
+ }
+
+ runFile.write(contents);
+ runFile.close();
+ qDebug() << "Write to" << fileName << "Ok";
+}
+
+Item dollarQuote(Item item)
+{
+ return Item("$") + item + Item("$");
+}
+
+int main()
+{
+ const int repeats = 6;
+ init();
+ Item run = (
+ Line("/****************************************************************************") +
+ Line("**") +
+ Line("** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).") +
+ Line("** Contact: Nokia Corporation (qt-info@nokia.com)") +
+ Line("**") +
+ Line("** This file is part of the Qt Toolkit.") +
+ Line("**") +
+ Line("****************************************************************************/") +
+ Line("") +
+ Line("// Generated code, do not edit! Use generator at tools/qtconcurrent/generaterun/") +
+ Line("#ifndef QTCONCURRENT_RUN_H") +
+ Line("#define QTCONCURRENT_RUN_H") +
+ Line("") +
+ Line("#ifndef QT_NO_CONCURRENT") +
+ Line("") +
+ Line("#include <QtCore/qtconcurrentrunbase.h>") +
+ Line("#include <QtCore/qtconcurrentstoredfunctioncall.h>") +
+ Line("") +
+ Line("QT_BEGIN_HEADER") +
+ Line("QT_BEGIN_NAMESPACE") +
+ Line("") +
+ Line("QT_MODULE(Core)") +
+ Line("") +
+ Line("#ifdef qdoc") +
+ Line("") +
+ Line("namespace QtConcurrent {") +
+ Line("") +
+ Line(" template <typename T>") +
+ Line(" QFuture<T> run(Function function, ...);") +
+ Line("") +
+ Line("} // namespace QtConcurrent") +
+ Line("") +
+ Line("#else") +
+ Line("") +
+ Line("namespace QtConcurrent {") +
+ Line("") +
+ generateRunFunctions(repeats) +
+ Line("} //namespace QtConcurrent") +
+ Line("") +
+ Line("#endif // qdoc") +
+ Line("") +
+ Line("QT_END_NAMESPACE") +
+ Line("QT_END_HEADER") +
+ Line("") +
+ Line("#endif")
+ );
+
+ writeFile("../../../src/corelib/concurrent/qtconcurrentrun.h", run.generate());
+
+ Item storedFunctionCall = (
+ Line("/****************************************************************************") +
+ Line("**") +
+ Line("** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).") +
+ Line("** Contact: Nokia Corporation (qt-info@nokia.com)") +
+ Line("**") +
+ Line("** This file is part of the Qt Toolkit.") +
+ Line("**") +
+ Line("****************************************************************************/") +
+ Line("") +
+ Line("// Generated code, do not edit! Use generator at tools/qtconcurrent/generaterun/") +
+ Line("#ifndef QTCONCURRENT_STOREDFUNCTIONCALL_H") +
+ Line("#define QTCONCURRENT_STOREDFUNCTIONCALL_H") +
+ Line("") +
+ Line("#include <QtCore/qglobal.h>") +
+ Line("") +
+ Line("#ifndef QT_NO_CONCURRENT") +
+ Line("#include <QtCore/qtconcurrentrunbase.h>") +
+ Line("") +
+ Line("QT_BEGIN_HEADER") +
+ Line("QT_BEGIN_NAMESPACE") +
+ Line("") +
+ Line("QT_MODULE(Core)") +
+ Line("") +
+ Line("#ifndef qdoc") +
+ Line("") +
+ Line("namespace QtConcurrent {") +
+ generateSFCs(repeats) +
+ Line("} //namespace QtConcurrent") +
+ Line("") +
+ Line("#endif // qdoc") +
+ Line("") +
+ Line("QT_END_NAMESPACE") +
+ Line("QT_END_HEADER") +
+ Line("") +
+ Line("#endif // QT_NO_CONCURRENT") +
+ Line("") +
+ Line("#endif")
+ );
+
+ writeFile("../../../src/corelib/concurrent/qtconcurrentstoredfunctioncall.h", storedFunctionCall.generate());
+}
+
+
diff --git a/src/qtconcurrent/generaterun/run.pro b/src/qtconcurrent/generaterun/run.pro
new file mode 100644
index 000000000..76bc661ec
--- /dev/null
+++ b/src/qtconcurrent/generaterun/run.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET +=
+DEPENDPATH += .
+INCLUDEPATH += .
+
+include(../codegenerator/codegenerator.pri)
+
+# Input
+SOURCES += main.cpp
diff --git a/src/qtconfig/colorbutton.cpp b/src/qtconfig/colorbutton.cpp
new file mode 100644
index 000000000..33c1b25df
--- /dev/null
+++ b/src/qtconfig/colorbutton.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "colorbutton.h"
+
+#include <QApplication>
+#include <QtEvents>
+#include <QColorDialog>
+#include <QPainter>
+#include <QMimeData>
+#include <QStyle>
+#include <QStyleOption>
+
+QT_BEGIN_NAMESPACE
+
+ColorButton::ColorButton(QWidget *parent)
+ : QAbstractButton(parent)
+ , col(Qt::black)
+ , mousepressed(false)
+{
+ setAcceptDrops(true);
+ connect(this, SIGNAL(clicked()), SLOT(changeColor()));
+}
+
+
+ColorButton::ColorButton(const QColor &c, QWidget *parent)
+ : QAbstractButton(parent)
+ , col(c)
+{
+ setAcceptDrops(true);
+ connect(this, SIGNAL(clicked()), SLOT(changeColor()));
+}
+
+
+void ColorButton::setColor(const QColor &c)
+{
+ col = c;
+ update();
+}
+
+
+void ColorButton::changeColor()
+{
+ QColor c = QColorDialog::getColor(col, qApp->activeWindow());
+
+ if (c.isValid()) {
+ setColor(c);
+ emit colorChanged(color());
+ }
+}
+
+
+QSize ColorButton::sizeHint() const
+{
+ return QSize(40, 25);
+}
+
+
+QSize ColorButton::minimumSizeHint() const
+{
+ return QSize(40, 25);
+}
+
+
+void ColorButton::drawButton(QPainter *p)
+{
+ QStyleOptionButton buttonOptions;
+ buttonOptions.init(this);
+ buttonOptions.features = QStyleOptionButton::None;
+ buttonOptions.rect = rect();
+ buttonOptions.palette = palette();
+ buttonOptions.state = (isDown() ? QStyle::State_Sunken : QStyle::State_Raised);
+ style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &buttonOptions, p, this);
+
+ p->save();
+ drawButtonLabel(p);
+ p->restore();
+
+ QStyleOptionFocusRect frectOptions;
+ frectOptions.init(this);
+ frectOptions.rect = style()->subElementRect(QStyle::SE_PushButtonFocusRect, &buttonOptions, this);
+ if (hasFocus())
+ style()->drawPrimitive(QStyle::PE_FrameFocusRect, &frectOptions, p, this);
+}
+
+
+void ColorButton::drawButtonLabel(QPainter *p)
+{
+ QPalette::ColorGroup cg =
+ (isEnabled() ? (hasFocus() ? QPalette::Active : QPalette::Inactive) : QPalette::Disabled);
+
+ p->setPen(palette().color(cg, QPalette::ButtonText));
+ p->setBrush(col);
+ p->drawRect(width() / 4, height() / 4, width() / 2 - 1, height() / 2 - 1);
+}
+
+
+void ColorButton::dragEnterEvent(QDragEnterEvent *e)
+{
+ if (!e->mimeData()->hasColor()) {
+ e->ignore();
+ return;
+ }
+}
+
+
+void ColorButton::dragMoveEvent(QDragMoveEvent *e)
+{
+ if (!e->mimeData()->hasColor()) {
+ e->ignore();
+ return;
+ }
+
+ e->accept();
+}
+
+
+void ColorButton::dropEvent(QDropEvent *e)
+{
+ if (!e->mimeData()->hasColor()) {
+ e->ignore();
+ return;
+ }
+
+ QColor c = qvariant_cast<QColor>(e->mimeData()->colorData());
+ setColor(c);
+ emit colorChanged(color());
+}
+
+
+void ColorButton::mousePressEvent(QMouseEvent *e)
+{
+ presspos = e->pos();
+ mousepressed = true;
+ QAbstractButton::mousePressEvent(e);
+}
+
+
+void ColorButton::mouseReleaseEvent(QMouseEvent *e)
+{
+ mousepressed = false;
+ QAbstractButton::mouseReleaseEvent(e);
+}
+
+
+void ColorButton::mouseMoveEvent(QMouseEvent *e)
+{
+ if (!mousepressed)
+ return;
+
+ if ((presspos - e->pos()).manhattanLength() > QApplication::startDragDistance()) {
+ mousepressed = false;
+ setDown(false);
+
+ QDrag *drag = new QDrag(this);
+ QMimeData *data = new QMimeData;
+ data->setColorData(color());
+ drag->setMimeData(data);
+ drag->start(Qt::CopyAction);
+ }
+}
+
+void ColorButton::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ drawButton(&p);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qtconfig/colorbutton.h b/src/qtconfig/colorbutton.h
new file mode 100644
index 000000000..96ccbc8e2
--- /dev/null
+++ b/src/qtconfig/colorbutton.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COLORBUTTON_H
+#define COLORBUTTON_H
+
+#include <QAbstractButton>
+
+QT_BEGIN_NAMESPACE
+
+class ColorButton : public QAbstractButton
+{
+ Q_OBJECT
+
+public:
+ ColorButton(QWidget *);
+ ColorButton(const QColor &, QWidget *);
+
+ const QColor &color() const { return col; }
+
+ void setColor(const QColor &);
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void dragEnterEvent(QDragEnterEvent *);
+ void dragMoveEvent(QDragMoveEvent *);
+ void dropEvent(QDropEvent *);
+
+signals:
+ void colorChanged(const QColor &);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void drawButton(QPainter *);
+ void drawButtonLabel(QPainter *);
+
+private slots:
+ void changeColor();
+
+
+private:
+ QColor col;
+ QPoint presspos;
+ bool mousepressed;
+};
+
+QT_END_NAMESPACE
+
+#endif // COLORBUTTON_H
diff --git a/src/qtconfig/images/appicon.png b/src/qtconfig/images/appicon.png
new file mode 100644
index 000000000..009317778
--- /dev/null
+++ b/src/qtconfig/images/appicon.png
Binary files differ
diff --git a/src/qtconfig/main.cpp b/src/qtconfig/main.cpp
new file mode 100644
index 000000000..38435d9bf
--- /dev/null
+++ b/src/qtconfig/main.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include <QApplication>
+#include <QLibraryInfo>
+#include <QLocale>
+#include <QTranslator>
+
+QT_USE_NAMESPACE
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(qtconfig);
+
+ QApplication app(argc, argv);
+
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("qtconfig_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+
+ MainWindow mw;
+ mw.show();
+ return app.exec();
+}
diff --git a/src/qtconfig/mainwindow.cpp b/src/qtconfig/mainwindow.cpp
new file mode 100644
index 000000000..059adb307
--- /dev/null
+++ b/src/qtconfig/mainwindow.cpp
@@ -0,0 +1,956 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+#include "colorbutton.h"
+#include "previewframe.h"
+#include "paletteeditoradvanced.h"
+
+#include <QLabel>
+#include <QApplication>
+#include <QComboBox>
+#include <QStyleFactory>
+#include <QFontDatabase>
+#include <QLineEdit>
+#include <QSpinBox>
+#include <QCheckBox>
+#include <QFileDialog>
+#include <QAction>
+#include <QStatusBar>
+#include <QSettings>
+#include <QMessageBox>
+#include <QStyle>
+#include <QtEvents>
+#include <QInputContext>
+#include <QInputContextFactory>
+#include <QtDebug>
+#include <QPixmap>
+
+#include <stdlib.h>
+
+#ifndef QT_NO_GSTREAMER
+#include <gst/gst.h>
+#endif
+#ifdef HAVE_PHONON
+#include <phonon/phononnamespace.h>
+#endif
+
+#include <QtGui/private/qt_x11_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// from qapplication.cpp and qapplication_x11.cpp - These are NOT for
+// external use ignore them
+// extern bool Q_CORE_EXPORT qt_resolve_symlinks;
+
+static const char *appearance_text = QT_TRANSLATE_NOOP("MainWindow",
+"<p><b><font size+=2>Appearance</font></b></p>"
+"<hr>"
+"<p>Use this tab to customize the appearance of your Qt applications.</p>"
+"<p>You can select the default GUI Style from the drop down list and "
+"customize the colors.</p>"
+"<p>Any GUI Style plugins in your plugin path will automatically be added "
+"to the list of built-in Qt styles. (See the Library Paths tab for "
+"information on adding new plugin paths.)</p>"
+"<p>When you choose 3-D Effects and Window Background colors, the Qt "
+"Configuration program will automatically generate a palette for you. "
+"To customize colors further, press the Tune Palette button to open "
+"the advanced palette editor."
+"<p>The Preview Window shows what the selected Style and colors look "
+"like.");
+
+static const char *font_text = QT_TRANSLATE_NOOP("MainWindow",
+"<p><b><font size+=2>Fonts</font></b></p>"
+"<hr>"
+"<p>Use this tab to select the default font for your Qt applications. "
+"The selected font is shown (initially as 'Sample Text') in the line "
+"edit below the Family, "
+"Style and Point Size drop down lists.</p>"
+"<p>Qt has a powerful font substitution feature that allows you to "
+"specify a list of substitute fonts. Substitute fonts are used "
+"when a font cannot be loaded, or if the specified font doesn't have "
+"a particular character."
+"<p>For example, if you select the font Lucida, which doesn't have Korean "
+"characters, but need to show some Korean text using the Mincho font family "
+"you can do so by adding Mincho to the list. Once Mincho is added, any "
+"Korean characters that are not found in the Lucida font will be taken "
+"from the Mincho font. Because the font substitutions are "
+"lists, you can also select multiple families, such as Song Ti (for "
+"use with Chinese text).");
+
+static const char *interface_text = QT_TRANSLATE_NOOP("MainWindow",
+"<p><b><font size+=2>Interface</font></b></p>"
+"<hr>"
+"<p>Use this tab to customize the feel of your Qt applications.</p>"
+"<p>If the Resolve Symlinks checkbox is checked Qt will follow symlinks "
+"when handling URLs. For example, in the file dialog, if this setting is turned "
+"on and /usr/tmp is a symlink to /var/tmp, entering the /usr/tmp directory "
+"will cause the file dialog to change to /var/tmp. With this setting turned "
+"off, symlinks are not resolved or followed.</p>"
+"<p>The Global Strut setting is useful for people who require a "
+"minimum size for all widgets (e.g. when using a touch panel or for users "
+"who are visually impaired). Leaving the Global Strut width and height "
+"at 0 will disable the Global Strut feature</p>"
+"<p>XIM (Extended Input Methods) are used for entering characters in "
+"languages that have large character sets, for example, Chinese and "
+"Japanese.");
+// ### What does the 'Enhanced support for languages written R2L do?
+
+static const char *printer_text = QT_TRANSLATE_NOOP("MainWindow",
+"<p><b><font size+=2>Printer</font></b></p>"
+"<hr>"
+"<p>Use this tab to configure the way Qt generates output for the printer."
+"You can specify if Qt should try to embed fonts into its generated output."
+"If you enable font embedding, the resulting postscript will be more "
+"portable and will more accurately reflect the "
+"visual output on the screen; however the resulting postscript file "
+"size will be bigger."
+"<p>When using font embedding you can select additional directories where "
+"Qt should search for embeddable font files. By default, the X "
+"server font path is used.");
+
+static const char *phonon_text = QT_TRANSLATE_NOOP("MainWindow",
+"<p><b><font size+=2>Phonon</font></b></p>"
+"<hr>"
+"<p>Use this tab to configure the Phonon GStreamer multimedia backend. "
+"<p>It is reccommended to leave all settings on \"Auto\" to let "
+"Phonon determine your settings automatically.");
+
+
+QPalette::ColorGroup MainWindow::groupFromIndex(int item)
+{
+ switch (item) {
+ case 0:
+ default:
+ return QPalette::Active;
+ case 1:
+ return QPalette::Inactive;
+ case 2:
+ return QPalette::Disabled;
+ }
+}
+
+static void setStyleHelper(QWidget *w, QStyle *s)
+{
+ const QObjectList children = w->children();
+ for (int i = 0; i < children.size(); ++i) {
+ QObject *child = children.at(i);
+ if (child->isWidgetType())
+ setStyleHelper((QWidget *) child, s);
+ }
+ w->setStyle(s);
+}
+
+MainWindow::MainWindow()
+ : ui(new Ui::MainWindow),
+ editPalette(palette()),
+ previewPalette(palette()),
+ previewstyle(0)
+{
+ ui->setupUi(this);
+ statusBar();
+
+ // signals and slots connections
+ connect(ui->fontPathLineEdit, SIGNAL(returnPressed()), SLOT(addFontpath()));
+ connect(ui->addFontPathButton, SIGNAL(clicked()), SLOT(addFontpath()));
+ connect(ui->addSubstitutionButton, SIGNAL(clicked()), SLOT(addSubstitute()));
+ connect(ui->browseFontPathButton, SIGNAL(clicked()), SLOT(browseFontpath()));
+ connect(ui->fontStyleCombo, SIGNAL(activated(int)), SLOT(buildFont()));
+ connect(ui->pointSizeCombo, SIGNAL(activated(int)), SLOT(buildFont()));
+ connect(ui->downFontpathButton, SIGNAL(clicked()), SLOT(downFontpath()));
+ connect(ui->downSubstitutionButton, SIGNAL(clicked()), SLOT(downSubstitute()));
+ connect(ui->fontFamilyCombo, SIGNAL(activated(QString)), SLOT(familySelected(QString)));
+ connect(ui->fileExitAction, SIGNAL(triggered()), SLOT(fileExit()));
+ connect(ui->fileSaveAction, SIGNAL(triggered()), SLOT(fileSave()));
+ connect(ui->helpAboutAction, SIGNAL(triggered()), SLOT(helpAbout()));
+ connect(ui->helpAboutQtAction, SIGNAL(triggered()), SLOT(helpAboutQt()));
+ connect(ui->mainTabWidget, SIGNAL(currentChanged(int)), SLOT(pageChanged(int)));
+ connect(ui->paletteCombo, SIGNAL(activated(int)), SLOT(paletteSelected(int)));
+ connect(ui->removeFontpathButton, SIGNAL(clicked()), SLOT(removeFontpath()));
+ connect(ui->removeSubstitutionButton, SIGNAL(clicked()), SLOT(removeSubstitute()));
+ connect(ui->toolBoxEffectCombo, SIGNAL(activated(int)), SLOT(somethingModified()));
+ connect(ui->doubleClickIntervalSpinBox, SIGNAL(valueChanged(int)), SLOT(somethingModified()));
+ connect(ui->cursorFlashTimeSpinBox, SIGNAL(valueChanged(int)), SLOT(somethingModified()));
+ connect(ui->wheelScrollLinesSpinBox, SIGNAL(valueChanged(int)), SLOT(somethingModified()));
+ connect(ui->menuEffectCombo, SIGNAL(activated(int)), SLOT(somethingModified()));
+ connect(ui->comboEffectCombo, SIGNAL(activated(int)), SLOT(somethingModified()));
+ connect(ui->audiosinkCombo, SIGNAL(activated(int)), SLOT(somethingModified()));
+ connect(ui->videomodeCombo, SIGNAL(activated(int)), SLOT(somethingModified()));
+ connect(ui->toolTipEffectCombo, SIGNAL(activated(int)), SLOT(somethingModified()));
+ connect(ui->strutWidthSpinBox, SIGNAL(valueChanged(int)), SLOT(somethingModified()));
+ connect(ui->strutHeightSpinBox, SIGNAL(valueChanged(int)), SLOT(somethingModified()));
+ connect(ui->effectsCheckBox, SIGNAL(toggled(bool)), SLOT(somethingModified()));
+ connect(ui->resolveLinksCheckBox, SIGNAL(toggled(bool)), SLOT(somethingModified()));
+ connect(ui->fontEmbeddingCheckBox, SIGNAL(clicked()), SLOT(somethingModified()));
+ connect(ui->rtlExtensionsCheckBox, SIGNAL(toggled(bool)), SLOT(somethingModified()));
+ connect(ui->inputStyleCombo, SIGNAL(activated(int)), SLOT(somethingModified()));
+ connect(ui->inputMethodCombo, SIGNAL(activated(int)), SLOT(somethingModified()));
+ connect(ui->guiStyleCombo, SIGNAL(activated(QString)), SLOT(styleSelected(QString)));
+ connect(ui->familySubstitutionCombo, SIGNAL(activated(QString)), SLOT(substituteSelected(QString)));
+ connect(ui->tunePaletteButton, SIGNAL(clicked()), SLOT(tunePalette()));
+ connect(ui->upFontpathButton, SIGNAL(clicked()), SLOT(upFontpath()));
+ connect(ui->upSubstitutionButton, SIGNAL(clicked()), SLOT(upSubstitute()));
+
+ modified = true;
+ desktopThemeName = tr("Desktop Settings (Default)");
+ setWindowIcon(QPixmap(":/trolltech/qtconfig/images/appicon.png"));
+ QStringList gstyles = QStyleFactory::keys();
+ gstyles.sort();
+ ui->guiStyleCombo->addItem(desktopThemeName);
+ ui->guiStyleCombo->setItemData(ui->guiStyleCombo->findText(desktopThemeName),
+ tr("Choose style and palette based on your desktop settings."),
+ Qt::ToolTipRole);
+ ui->guiStyleCombo->addItems(gstyles);
+
+ QSettings settings(QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+
+ QString currentstyle = settings.value(QLatin1String("style")).toString();
+ if (currentstyle.isEmpty()) {
+ ui->guiStyleCombo->setCurrentIndex(ui->guiStyleCombo->findText(desktopThemeName));
+ currentstyle = QApplication::style()->objectName();
+ } else {
+ int index = ui->guiStyleCombo->findText(currentstyle, Qt::MatchFixedString);
+ if (index != -1) {
+ ui->guiStyleCombo->setCurrentIndex(index);
+ } else { // we give up
+ ui->guiStyleCombo->addItem(tr("Unknown"));
+ ui->guiStyleCombo->setCurrentIndex(ui->guiStyleCombo->count() - 1);
+ }
+ }
+ ui->buttonMainColor->setColor(palette().color(QPalette::Active, QPalette::Button));
+ ui->buttonWindowColor->setColor(palette().color(QPalette::Active, QPalette::Window));
+ connect(ui->buttonMainColor, SIGNAL(colorChanged(QColor)), SLOT(buildPalette()));
+ connect(ui->buttonWindowColor, SIGNAL(colorChanged(QColor)), SLOT(buildPalette()));
+
+ if (X11->desktopEnvironment == DE_KDE)
+ ui->colorConfig->hide();
+ else
+ ui->kdeNoteLabel->hide();
+
+ QFontDatabase db;
+ QStringList families = db.families();
+ ui->fontFamilyCombo->addItems(families);
+
+ QStringList fs = families;
+ QStringList fs2 = QFont::substitutions();
+ QStringList::Iterator fsit = fs2.begin();
+ while (fsit != fs2.end()) {
+ if (!fs.contains(*fsit))
+ fs += *fsit;
+ fsit++;
+ }
+ fs.sort();
+ ui->familySubstitutionCombo->addItems(fs);
+
+ ui->chooseSubstitutionCombo->addItems(families);
+ QList<int> sizes = db.standardSizes();
+ foreach(int i, sizes)
+ ui->pointSizeCombo->addItem(QString::number(i));
+
+ ui->doubleClickIntervalSpinBox->setValue(QApplication::doubleClickInterval());
+ ui->cursorFlashTimeSpinBox->setValue(QApplication::cursorFlashTime());
+ ui->wheelScrollLinesSpinBox->setValue(QApplication::wheelScrollLines());
+ // #############
+ // resolveLinksCheckBox->setChecked(qt_resolve_symlinks);
+
+ ui->effectsCheckBox->setChecked(QApplication::isEffectEnabled(Qt::UI_General));
+ ui->effectsFrame->setEnabled(ui->effectsCheckBox->isChecked());
+
+ if (QApplication::isEffectEnabled(Qt::UI_FadeMenu))
+ ui->menuEffectCombo->setCurrentIndex(2);
+ else if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu))
+ ui->menuEffectCombo->setCurrentIndex(1);
+
+ if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo))
+ ui->comboEffectCombo->setCurrentIndex(1);
+
+ if (QApplication::isEffectEnabled(Qt::UI_FadeTooltip))
+ ui->toolTipEffectCombo->setCurrentIndex(2);
+ else if (QApplication::isEffectEnabled(Qt::UI_AnimateTooltip))
+ ui->toolTipEffectCombo->setCurrentIndex(1);
+
+ if (QApplication::isEffectEnabled(Qt::UI_AnimateToolBox))
+ ui->toolBoxEffectCombo->setCurrentIndex(1);
+
+ QSize globalStrut = QApplication::globalStrut();
+ ui->strutWidthSpinBox->setValue(globalStrut.width());
+ ui->strutHeightSpinBox->setValue(globalStrut.height());
+
+ // find the default family
+ QStringList::Iterator sit = families.begin();
+ int i = 0, possible = -1;
+ while (sit != families.end()) {
+ if (*sit == QApplication::font().family())
+ break;
+ if ((*sit).contains(QApplication::font().family()))
+ possible = i;
+
+ i++;
+ sit++;
+ }
+ if (sit == families.end())
+ i = possible;
+ if (i == -1) // no clue about the current font
+ i = 0;
+
+ ui->fontFamilyCombo->setCurrentIndex(i);
+
+ QStringList styles = db.styles(ui->fontFamilyCombo->currentText());
+ ui->fontStyleCombo->addItems(styles);
+
+ QString stylestring = db.styleString(QApplication::font());
+ sit = styles.begin();
+ i = 0;
+ possible = -1;
+ while (sit != styles.end()) {
+ if (*sit == stylestring)
+ break;
+ if ((*sit).contains(stylestring))
+ possible = i;
+
+ i++;
+ sit++;
+ }
+ if (sit == styles.end())
+ i = possible;
+ if (i == -1) // no clue about the current font
+ i = 0;
+ ui->fontStyleCombo->setCurrentIndex(i);
+
+ i = 0;
+ for (int psize = QApplication::font().pointSize(); i < ui->pointSizeCombo->count(); ++i) {
+ const int sz = ui->pointSizeCombo->itemText(i).toInt();
+ if (sz == psize) {
+ ui->pointSizeCombo->setCurrentIndex(i);
+ break;
+ } else if(sz > psize) {
+ ui->pointSizeCombo->insertItem(i, QString::number(psize));
+ ui->pointSizeCombo->setCurrentIndex(i);
+ break;
+ }
+ }
+
+ QStringList subs = QFont::substitutes(ui->familySubstitutionCombo->currentText());
+ ui->substitutionsListBox->clear();
+ ui->substitutionsListBox->insertItems(0, subs);
+
+ ui->rtlExtensionsCheckBox->setChecked(settings.value(QLatin1String("useRtlExtensions"), false)
+ .toBool());
+
+#ifdef Q_WS_X11
+ QString settingsInputStyle = settings.value(QLatin1String("XIMInputStyle")).toString();
+ if (!settingsInputStyle.isEmpty())
+ ui->inputStyleCombo->setCurrentIndex(ui->inputStyleCombo->findText(settingsInputStyle));
+#else
+ ui->inputStyleCombo->hide();
+ ui->inputStyleComboLabel->hide();
+#endif
+
+#if defined(Q_WS_X11) && !defined(QT_NO_XIM)
+ QStringList inputMethodCombo = QInputContextFactory::keys();
+ int inputMethodComboIndex = -1;
+ QString defaultInputMethod = settings.value(QLatin1String("DefaultInputMethod"), QLatin1String("xim")).toString();
+ for (int i = inputMethodCombo.size()-1; i >= 0; --i) {
+ const QString &im = inputMethodCombo.at(i);
+ if (im.contains(QLatin1String("imsw"))) {
+ inputMethodCombo.removeAt(i);
+ if (inputMethodComboIndex > i)
+ --inputMethodComboIndex;
+ } else if (im == defaultInputMethod) {
+ inputMethodComboIndex = i;
+ }
+ }
+ if (inputMethodComboIndex == -1 && !inputMethodCombo.isEmpty())
+ inputMethodComboIndex = 0;
+ ui->inputMethodCombo->addItems(inputMethodCombo);
+ ui->inputMethodCombo->setCurrentIndex(inputMethodComboIndex);
+#else
+ ui->inputMethodCombo->hide();
+ ui->inputMethodComboLabel->hide();
+#endif
+
+ ui->fontEmbeddingCheckBox->setChecked(settings.value(QLatin1String("embedFonts"), true)
+ .toBool());
+ fontpaths = settings.value(QLatin1String("fontPath")).toStringList();
+ ui->fontpathListBox->insertItems(0, fontpaths);
+
+ ui->audiosinkCombo->addItem(tr("Auto (default)"), QLatin1String("Auto"));
+ ui->audiosinkCombo->setItemData(ui->audiosinkCombo->findText(tr("Auto (default)")),
+ tr("Choose audio output automatically."), Qt::ToolTipRole);
+ ui->audiosinkCombo->addItem(tr("aRts"), QLatin1String("artssink"));
+ ui->audiosinkCombo->setItemData(ui->audiosinkCombo->findText(tr("aRts")),
+ tr("Experimental aRts support for GStreamer."),
+ Qt::ToolTipRole);
+#ifdef HAVE_PHONON
+ ui->phononVersionLabel->setText(QLatin1String(Phonon::phononVersion()));
+#endif
+#ifndef QT_NO_GSTREAMER
+ if (gst_init_check(0, 0, 0)) {
+ gchar *versionString = gst_version_string();
+ ui->gstVersionLabel->setText(QLatin1String(versionString));
+ g_free(versionString);
+ GList *factoryList = gst_registry_get_feature_list(gst_registry_get_default(),
+ GST_TYPE_ELEMENT_FACTORY);
+ QString name, klass, description;
+ for (GList *iter = g_list_first(factoryList) ; iter != NULL ; iter = g_list_next(iter)) {
+ GstPluginFeature *feature = GST_PLUGIN_FEATURE(iter->data);
+ klass = QLatin1String(gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature)));
+ if (klass == QLatin1String("Sink/Audio")) {
+ name = QLatin1String(GST_PLUGIN_FEATURE_NAME(feature));
+ if (name == QLatin1String("sfsink"))
+ continue; // useless to output audio to file when you cannot set the file path
+ else if (name == QLatin1String("autoaudiosink"))
+ continue; //This is used implicitly from the auto setting
+ GstElement *sink = gst_element_factory_make (qPrintable(name), NULL);
+ if (sink) {
+ description = QLatin1String(gst_element_factory_get_description(GST_ELEMENT_FACTORY(feature)));
+ ui->audiosinkCombo->addItem(name, name);
+ ui->audiosinkCombo->setItemData(ui->audiosinkCombo->findText(name), description,
+ Qt::ToolTipRole);
+ gst_object_unref (sink);
+ }
+ }
+ }
+ g_list_free(factoryList);
+ }
+#else
+ ui->phononTab->setEnabled(false);
+ ui->phononLabel->setText(tr("Phonon GStreamer backend not available."));
+#endif
+
+ ui->videomodeCombo->addItem(tr("Auto (default)"), QLatin1String("Auto"));
+ ui->videomodeCombo->setItemData(ui->videomodeCombo->findText(tr("Auto (default)")),
+ tr("Choose render method automatically"), Qt::ToolTipRole);
+#ifdef Q_WS_X11
+ ui->videomodeCombo->addItem(tr("X11"), QLatin1String("X11"));
+ ui->videomodeCombo->setItemData(ui->videomodeCombo->findText(tr("X11")),
+ tr("Use X11 Overlays"), Qt::ToolTipRole);
+#endif
+#ifndef QT_NO_OPENGL
+ ui->videomodeCombo->addItem(tr("OpenGL"), QLatin1String("OpenGL"));
+ ui->videomodeCombo->setItemData(ui->videomodeCombo->findText(tr("OpenGL")),
+ tr("Use OpenGL if available"), Qt::ToolTipRole);
+#endif
+ ui->videomodeCombo->addItem(tr("Software"), QLatin1String("Software"));
+ ui->videomodeCombo->setItemData(ui->videomodeCombo->findText(tr("Software")),
+ tr("Use simple software rendering"), Qt::ToolTipRole);
+
+ QString audioSink = settings.value(QLatin1String("audiosink"), QLatin1String("Auto")).toString();
+ QString videoMode = settings.value(QLatin1String("videomode"), QLatin1String("Auto")).toString();
+ ui->audiosinkCombo->setCurrentIndex(ui->audiosinkCombo->findData(audioSink));
+ ui->videomodeCombo->setCurrentIndex(ui->videomodeCombo->findData(videoMode));
+
+ settings.endGroup(); // Qt
+
+ ui->helpView->setText(tr(appearance_text));
+
+ setModified(false);
+ updateStyleLayout();
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+#ifdef Q_WS_X11
+extern void qt_x11_apply_settings_in_all_apps();
+#endif
+
+void MainWindow::fileSave()
+{
+ if (! modified) {
+ statusBar()->showMessage(tr("No changes to be saved."), 2000);
+ return;
+ }
+
+ statusBar()->showMessage(tr("Saving changes..."));
+
+ {
+ QSettings settings(QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ QFontDatabase db;
+ QFont font = db.font(ui->fontFamilyCombo->currentText(),
+ ui->fontStyleCombo->currentText(),
+ ui->pointSizeCombo->currentText().toInt());
+
+ QStringList actcg, inactcg, discg;
+ bool overrideDesktopSettings = (ui->guiStyleCombo->currentText() != desktopThemeName);
+ if (overrideDesktopSettings) {
+ int i;
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ actcg << editPalette.color(QPalette::Active,
+ QPalette::ColorRole(i)).name();
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ inactcg << editPalette.color(QPalette::Inactive,
+ QPalette::ColorRole(i)).name();
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ discg << editPalette.color(QPalette::Disabled,
+ QPalette::ColorRole(i)).name();
+ }
+
+ settings.setValue(QLatin1String("font"), font.toString());
+ settings.setValue(QLatin1String("Palette/active"), actcg);
+ settings.setValue(QLatin1String("Palette/inactive"), inactcg);
+ settings.setValue(QLatin1String("Palette/disabled"), discg);
+
+ settings.setValue(QLatin1String("fontPath"), fontpaths);
+ settings.setValue(QLatin1String("embedFonts"), ui->fontEmbeddingCheckBox->isChecked());
+ settings.setValue(QLatin1String("style"),
+ overrideDesktopSettings ? ui->guiStyleCombo->currentText() : QString());
+
+ settings.setValue(QLatin1String("doubleClickInterval"), ui->doubleClickIntervalSpinBox->value());
+ settings.setValue(QLatin1String("cursorFlashTime"),
+ ui->cursorFlashTimeSpinBox->value() == 9 ? 0 : ui->cursorFlashTimeSpinBox->value());
+ settings.setValue(QLatin1String("wheelScrollLines"), ui->wheelScrollLinesSpinBox->value());
+ settings.setValue(QLatin1String("resolveSymlinks"), ui->resolveLinksCheckBox->isChecked());
+
+ QSize strut(ui->strutWidthSpinBox->value(), ui->strutHeightSpinBox->value());
+ settings.setValue(QLatin1String("globalStrut/width"), strut.width());
+ settings.setValue(QLatin1String("globalStrut/height"), strut.height());
+
+ settings.setValue(QLatin1String("useRtlExtensions"), ui->rtlExtensionsCheckBox->isChecked());
+
+#ifdef Q_WS_X11
+ QString style = ui->inputStyleCombo->currentText();
+ QString str = QLatin1String("On The Spot");
+ if (style == tr("Over The Spot"))
+ str = QLatin1String("Over The Spot");
+ else if (style == tr("Off The Spot"))
+ str = QLatin1String("Off The Spot");
+ else if (style == tr("Root"))
+ str = QLatin1String("Root");
+ settings.setValue(QLatin1String("XIMInputStyle"), str);
+#endif
+#if defined(Q_WS_X11) && !defined(QT_NO_XIM)
+ settings.setValue(QLatin1String("DefaultInputMethod"), ui->inputMethodCombo->currentText());
+#endif
+
+ QString audioSink = settings.value(QLatin1String("audiosink"), QLatin1String("Auto")).toString();
+ QString videoMode = settings.value(QLatin1String("videomode"), QLatin1String("Auto")).toString();
+ settings.setValue(QLatin1String("audiosink"),
+ ui->audiosinkCombo->itemData(ui->audiosinkCombo->currentIndex()));
+ settings.setValue(QLatin1String("videomode"),
+ ui->videomodeCombo->itemData(ui->videomodeCombo->currentIndex()));
+
+ QStringList effects;
+ if (ui->effectsCheckBox->isChecked()) {
+ effects << QLatin1String("general");
+
+ switch (ui->menuEffectCombo->currentIndex()) {
+ case 1: effects << QLatin1String("animatemenu"); break;
+ case 2: effects << QLatin1String("fademenu"); break;
+ }
+
+ switch (ui->comboEffectCombo->currentIndex()) {
+ case 1: effects << QLatin1String("animatecombo"); break;
+ }
+
+ switch (ui->toolTipEffectCombo->currentIndex()) {
+ case 1: effects << QLatin1String("animatetooltip"); break;
+ case 2: effects << QLatin1String("fadetooltip"); break;
+ }
+
+ switch (ui->toolBoxEffectCombo->currentIndex()) {
+ case 1: effects << QLatin1String("animatetoolbox"); break;
+ }
+ } else
+ effects << QLatin1String("none");
+ settings.setValue(QLatin1String("GUIEffects"), effects);
+
+ QStringList familysubs = QFont::substitutions();
+ QStringList::Iterator fit = familysubs.begin();
+ settings.beginGroup(QLatin1String("Font Substitutions"));
+ while (fit != familysubs.end()) {
+ QStringList subs = QFont::substitutes(*fit);
+ settings.setValue(*fit, subs);
+ fit++;
+ }
+ settings.endGroup(); // Font Substitutions
+ settings.endGroup(); // Qt
+ }
+
+#if defined(Q_WS_X11)
+ qt_x11_apply_settings_in_all_apps();
+#endif // Q_WS_X11
+
+ setModified(false);
+ statusBar()->showMessage(tr("Saved changes."));
+}
+
+void MainWindow::fileExit()
+{
+ qApp->closeAllWindows();
+}
+
+void MainWindow::setModified(bool m)
+{
+ if (modified == m)
+ return;
+
+ modified = m;
+ ui->fileSaveAction->setEnabled(m);
+}
+
+void MainWindow::buildPalette()
+{
+ QPalette temp(ui->buttonMainColor->color(), ui->buttonWindowColor->color());
+ for (int i = 0; i < QPalette::NColorGroups; i++)
+ temp = PaletteEditorAdvanced::buildEffect(QPalette::ColorGroup(i), temp);
+
+ editPalette = temp;
+ setPreviewPalette(editPalette);
+ updateColorButtons();
+
+ setModified(true);
+}
+
+void MainWindow::setPreviewPalette(const QPalette &pal)
+{
+ QPalette::ColorGroup colorGroup = groupFromIndex(ui->paletteCombo->currentIndex());
+
+ for (int i = 0; i < QPalette::NColorGroups; i++) {
+ for (int j = 0; j < QPalette::NColorRoles; j++) {
+ QPalette::ColorGroup targetGroup = QPalette::ColorGroup(i);
+ QPalette::ColorRole targetRole = QPalette::ColorRole(j);
+ previewPalette.setColor(targetGroup, targetRole, pal.color(colorGroup, targetRole));
+ }
+ }
+
+ ui->previewFrame->setPreviewPalette(previewPalette);
+}
+
+void MainWindow::updateColorButtons()
+{
+ ui->buttonMainColor->setColor(editPalette.color(QPalette::Active, QPalette::Button));
+ ui->buttonWindowColor->setColor(editPalette.color(QPalette::Active, QPalette::Window));
+}
+
+void MainWindow::tunePalette()
+{
+ bool ok;
+ QPalette pal = PaletteEditorAdvanced::getPalette(&ok, editPalette,
+ backgroundRole(), this);
+ if (!ok)
+ return;
+
+ editPalette = pal;
+ setPreviewPalette(editPalette);
+ setModified(true);
+}
+
+void MainWindow::paletteSelected(int)
+{
+ setPreviewPalette(editPalette);
+}
+
+void MainWindow::updateStyleLayout()
+{
+ QString currentStyle = ui->guiStyleCombo->currentText();
+ bool autoStyle = (currentStyle == desktopThemeName);
+ ui->previewFrame->setPreviewVisible(!autoStyle);
+ ui->buildPaletteGroup->setEnabled(currentStyle.toLower() != QLatin1String("gtk") && !autoStyle);
+}
+
+void MainWindow::styleSelected(const QString &stylename)
+{
+ QStyle *style = 0;
+ if (stylename == desktopThemeName) {
+ setModified(true);
+ } else {
+ style = QStyleFactory::create(stylename);
+ if (!style)
+ return;
+ setStyleHelper(ui->previewFrame, style);
+ delete previewstyle;
+ previewstyle = style;
+ setModified(true);
+ }
+ updateStyleLayout();
+}
+
+void MainWindow::familySelected(const QString &family)
+{
+ QFontDatabase db;
+ QStringList styles = db.styles(family);
+ ui->fontStyleCombo->clear();
+ ui->fontStyleCombo->addItems(styles);
+ ui->familySubstitutionCombo->addItem(family);
+ buildFont();
+}
+
+void MainWindow::buildFont()
+{
+ QFontDatabase db;
+ QFont font = db.font(ui->fontFamilyCombo->currentText(),
+ ui->fontStyleCombo->currentText(),
+ ui->pointSizeCombo->currentText().toInt());
+ ui->sampleLineEdit->setFont(font);
+ setModified(true);
+}
+
+void MainWindow::substituteSelected(const QString &family)
+{
+ QStringList subs = QFont::substitutes(family);
+ ui->substitutionsListBox->clear();
+ ui->substitutionsListBox->insertItems(0, subs);
+}
+
+void MainWindow::removeSubstitute()
+{
+ if (!ui->substitutionsListBox->currentItem())
+ return;
+
+ int row = ui->substitutionsListBox->currentRow();
+ QStringList subs = QFont::substitutes(ui->familySubstitutionCombo->currentText());
+ subs.removeAt(ui->substitutionsListBox->currentRow());
+ ui->substitutionsListBox->clear();
+ ui->substitutionsListBox->insertItems(0, subs);
+ if (row > ui->substitutionsListBox->count())
+ row = ui->substitutionsListBox->count() - 1;
+ ui->substitutionsListBox->setCurrentRow(row);
+ QFont::removeSubstitution(ui->familySubstitutionCombo->currentText());
+ QFont::insertSubstitutions(ui->familySubstitutionCombo->currentText(), subs);
+ setModified(true);
+}
+
+void MainWindow::addSubstitute()
+{
+ if (!ui->substitutionsListBox->currentItem()) {
+ QFont::insertSubstitution(ui->familySubstitutionCombo->currentText(),
+ ui->chooseSubstitutionCombo->currentText());
+ QStringList subs = QFont::substitutes(ui->familySubstitutionCombo->currentText());
+ ui->substitutionsListBox->clear();
+ ui->substitutionsListBox->insertItems(0, subs);
+ setModified(true);
+ return;
+ }
+
+ int row = ui->substitutionsListBox->currentRow();
+ QFont::insertSubstitution(ui->familySubstitutionCombo->currentText(), ui->chooseSubstitutionCombo->currentText());
+ QStringList subs = QFont::substitutes(ui->familySubstitutionCombo->currentText());
+ ui->substitutionsListBox->clear();
+ ui->substitutionsListBox->insertItems(0, subs);
+ ui->substitutionsListBox->setCurrentRow(row);
+ setModified(true);
+}
+
+void MainWindow::downSubstitute()
+{
+ if (!ui->substitutionsListBox->currentItem() || ui->substitutionsListBox->currentRow() >= ui->substitutionsListBox->count())
+ return;
+
+ int row = ui->substitutionsListBox->currentRow();
+ QStringList subs = QFont::substitutes(ui->familySubstitutionCombo->currentText());
+ QString fam = subs.at(row);
+ subs.removeAt(row);
+ subs.insert(row + 1, fam);
+ ui->substitutionsListBox->clear();
+ ui->substitutionsListBox->insertItems(0, subs);
+ ui->substitutionsListBox->setCurrentRow(row + 1);
+ QFont::removeSubstitution(ui->familySubstitutionCombo->currentText());
+ QFont::insertSubstitutions(ui->familySubstitutionCombo->currentText(), subs);
+ setModified(true);
+}
+
+void MainWindow::upSubstitute()
+{
+ if (!ui->substitutionsListBox->currentItem() || ui->substitutionsListBox->currentRow() < 1)
+ return;
+
+ int row = ui->substitutionsListBox->currentRow();
+ QStringList subs = QFont::substitutes(ui->familySubstitutionCombo->currentText());
+ QString fam = subs.at(row);
+ subs.removeAt(row);
+ subs.insert(row-1, fam);
+ ui->substitutionsListBox->clear();
+ ui->substitutionsListBox->insertItems(0, subs);
+ ui->substitutionsListBox->setCurrentRow(row - 1);
+ QFont::removeSubstitution(ui->familySubstitutionCombo->currentText());
+ QFont::insertSubstitutions(ui->familySubstitutionCombo->currentText(), subs);
+ setModified(true);
+}
+
+void MainWindow::removeFontpath()
+{
+ if (!ui->fontpathListBox->currentItem())
+ return;
+
+ int row = ui->fontpathListBox->currentRow();
+ fontpaths.removeAt(row);
+ ui->fontpathListBox->clear();
+ ui->fontpathListBox->insertItems(0, fontpaths);
+ if (row > ui->fontpathListBox->count())
+ row = ui->fontpathListBox->count() - 1;
+ ui->fontpathListBox->setCurrentRow(row);
+ setModified(true);
+}
+
+void MainWindow::addFontpath()
+{
+ if (ui->fontPathLineEdit->text().isEmpty())
+ return;
+
+ if (!ui->fontpathListBox->currentItem()) {
+ fontpaths.append(ui->fontPathLineEdit->text());
+ ui->fontpathListBox->clear();
+ ui->fontpathListBox->insertItems(0, fontpaths);
+ setModified(true);
+
+ return;
+ }
+
+ int row = ui->fontpathListBox->currentRow();
+ fontpaths.insert(row + 1, ui->fontPathLineEdit->text());
+ ui->fontpathListBox->clear();
+ ui->fontpathListBox->insertItems(0, fontpaths);
+ ui->fontpathListBox->setCurrentRow(row);
+ setModified(true);
+}
+
+void MainWindow::downFontpath()
+{
+ if (!ui->fontpathListBox->currentItem()
+ || ui->fontpathListBox->currentRow() >= (ui->fontpathListBox->count() - 1)) {
+ return;
+ }
+
+ int row = ui->fontpathListBox->currentRow();
+ QString fam = fontpaths.at(row);
+ fontpaths.removeAt(row);
+ fontpaths.insert(row + 1, fam);
+ ui->fontpathListBox->clear();
+ ui->fontpathListBox->insertItems(0, fontpaths);
+ ui->fontpathListBox->setCurrentRow(row + 1);
+ setModified(true);
+}
+
+void MainWindow::upFontpath()
+{
+ if (!ui->fontpathListBox->currentItem() || ui->fontpathListBox->currentRow() < 1)
+ return;
+
+ int row = ui->fontpathListBox->currentRow();
+ QString fam = fontpaths.at(row);
+ fontpaths.removeAt(row);
+ fontpaths.insert(row - 1, fam);
+ ui->fontpathListBox->clear();
+ ui->fontpathListBox->insertItems(0, fontpaths);
+ ui->fontpathListBox->setCurrentRow(row - 1);
+ setModified(true);
+}
+
+void MainWindow::browseFontpath()
+{
+ QString dirname = QFileDialog::getExistingDirectory(this, tr("Select a Directory"));
+ if (dirname.isNull())
+ return;
+
+ ui->fontPathLineEdit->setText(dirname);
+}
+
+void MainWindow::somethingModified()
+{
+ setModified(true);
+}
+
+void MainWindow::helpAbout()
+{
+ QMessageBox box(this);
+ box.setText(tr("<h3>%1</h3>"
+ "<br/>Version %2"
+ "<br/><br/>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).")
+ .arg(tr("Qt Configuration")).arg(QLatin1String(QT_VERSION_STR)));
+ box.setWindowTitle(tr("Qt Configuration"));
+ box.setIcon(QMessageBox::NoIcon);
+ box.exec();
+}
+
+void MainWindow::helpAboutQt()
+{
+ QMessageBox::aboutQt(this, tr("Qt Configuration"));
+}
+
+void MainWindow::pageChanged(int pageNumber)
+{
+ QWidget *page = ui->mainTabWidget->widget(pageNumber);
+ if (page == ui->interfaceTab)
+ ui->helpView->setText(tr(interface_text));
+ else if (page == ui->appearanceTab)
+ ui->helpView->setText(tr(appearance_text));
+ else if (page == ui->fontsTab)
+ ui->helpView->setText(tr(font_text));
+ else if (page == ui->printerTab)
+ ui->helpView->setText(tr(printer_text));
+ else if (page == ui->phononTab)
+ ui->helpView->setText(tr(phonon_text));
+}
+
+void MainWindow::closeEvent(QCloseEvent *e)
+{
+ if (modified) {
+ switch (QMessageBox::warning(this, tr("Save Changes"),
+ tr("Save changes to settings?"),
+ (QMessageBox::Yes | QMessageBox::No
+ | QMessageBox::Cancel))) {
+ case QMessageBox::Yes: // save
+ qApp->processEvents();
+ fileSave();
+
+ // fall through intended
+ case QMessageBox::No: // don't save
+ e->accept();
+ break;
+
+ case QMessageBox::Cancel: // cancel
+ e->ignore();
+ break;
+
+ default: break;
+ }
+ } else
+ e->accept();
+}
+
+QT_END_NAMESPACE
diff --git a/src/qtconfig/mainwindow.h b/src/qtconfig/mainwindow.h
new file mode 100644
index 000000000..6f4c8a52e
--- /dev/null
+++ b/src/qtconfig/mainwindow.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow();
+ ~MainWindow();
+
+ void closeEvent(QCloseEvent *);
+
+public slots:
+ virtual void buildPalette();
+ virtual void buildFont();
+ virtual void tunePalette();
+ virtual void paletteSelected(int);
+ virtual void styleSelected(const QString &);
+ virtual void familySelected(const QString &);
+ virtual void substituteSelected(const QString &);
+ virtual void removeSubstitute();
+ virtual void addSubstitute();
+ virtual void downSubstitute();
+ virtual void upSubstitute();
+ virtual void removeFontpath();
+ virtual void addFontpath();
+ virtual void downFontpath();
+ virtual void upFontpath();
+ virtual void browseFontpath();
+ virtual void fileSave();
+ virtual void fileExit();
+ virtual void somethingModified();
+ virtual void helpAbout();
+ virtual void helpAboutQt();
+ virtual void pageChanged(int);
+
+
+private:
+ void updateColorButtons();
+ void updateFontSample();
+ void updateStyleLayout();
+
+ static QPalette::ColorGroup groupFromIndex(int);
+
+ void setPreviewPalette(const QPalette &);
+
+ void setModified(bool);
+
+ Ui::MainWindow *ui;
+ QString desktopThemeName;
+ QPalette editPalette, previewPalette;
+ QStyle *previewstyle;
+ QStringList fontpaths;
+ bool modified;
+};
+
+QT_END_NAMESPACE
+
+#endif // MAINWINDOW_H
diff --git a/src/qtconfig/mainwindow.ui b/src/qtconfig/mainwindow.ui
new file mode 100644
index 000000000..d906800fe
--- /dev/null
+++ b/src/qtconfig/mainwindow.ui
@@ -0,0 +1,1388 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>815</width>
+ <height>716</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Qt Configuration</string>
+ </property>
+ <widget class="QWidget" name="widget">
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QTextEdit" name="helpView">
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QTabWidget" name="mainTabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="appearanceTab">
+ <attribute name="title">
+ <string>Appearance</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="guiStyleGroup">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>GUI Style</string>
+ </property>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="guiStyleLabel">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Select GUI &amp;Style:</string>
+ </property>
+ <property name="buddy">
+ <cstring>guiStyleCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="guiStyleCombo"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QGroupBox" name="previewGroup">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Preview</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QLabel" name="paletteLabel">
+ <property name="text">
+ <string>Select &amp;Palette:</string>
+ </property>
+ <property name="buddy">
+ <cstring>paletteCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="paletteCombo">
+ <item>
+ <property name="text">
+ <string>Active Palette</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Inactive Palette</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Disabled Palette</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="PreviewFrame" name="previewFrame" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>410</width>
+ <height>260</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="buildPaletteGroup">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Build Palette</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QWidget" name="colorConfig" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelMainColor">
+ <property name="text">
+ <string>&amp;Button Background:</string>
+ </property>
+ <property name="buddy">
+ <cstring>buttonMainColor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ColorButton" name="buttonMainColor" native="true"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelWindowColor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="midLineWidth">
+ <number>0</number>
+ </property>
+ <property name="text">
+ <string>Window Back&amp;ground:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="buddy">
+ <cstring>buttonWindowColor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ColorButton" name="buttonWindowColor" native="true"/>
+ </item>
+ <item>
+ <spacer name="spacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>70</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="tunePaletteButton">
+ <property name="text">
+ <string>&amp;Tune Palette...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="kdeNoteLabel">
+ <property name="text">
+ <string>Please use the KDE Control Center to set the palette.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="fontsTab">
+ <attribute name="title">
+ <string>Fonts</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QGroupBox" name="defaultFontGroup">
+ <property name="title">
+ <string>Default Font</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="fontStyleCombo">
+ <property name="autoCompletion">
+ <bool>true</bool>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="fontFamilyCombo">
+ <property name="autoCompletion">
+ <bool>true</bool>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="pointSizeCombo">
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="autoCompletion">
+ <bool>true</bool>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="fontStyleLabel">
+ <property name="text">
+ <string>&amp;Style:</string>
+ </property>
+ <property name="buddy">
+ <cstring>fontStyleCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="pointSizeLabel">
+ <property name="text">
+ <string>&amp;Point Size:</string>
+ </property>
+ <property name="buddy">
+ <cstring>pointSizeCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="fontFamilyLabel">
+ <property name="text">
+ <string>F&amp;amily:</string>
+ </property>
+ <property name="buddy">
+ <cstring>fontFamilyCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QLineEdit" name="sampleLineEdit">
+ <property name="text">
+ <string>Sample Text</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignHCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="fontSubstitutionGroup">
+ <property name="title">
+ <string>Font Substitution</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="familySubstitutionLabel">
+ <property name="text">
+ <string>S&amp;elect or Enter a Family:</string>
+ </property>
+ <property name="buddy">
+ <cstring>familySubstitutionCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="familySubstitutionCombo">
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="autoCompletion">
+ <bool>true</bool>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="Line1">
+ <property name="frameShape">
+ <enum>QFrame::HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="substitutionsLabel">
+ <property name="text">
+ <string>Current Substitutions:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="substitutionsListBox"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="upSubstitutionButton">
+ <property name="text">
+ <string>Up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="downSubstitutionButton">
+ <property name="text">
+ <string>Down</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeSubstitutionButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="Line2">
+ <property name="frameShape">
+ <enum>QFrame::HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="chooseSubstitutionLabel">
+ <property name="text">
+ <string>Select s&amp;ubstitute Family:</string>
+ </property>
+ <property name="buddy">
+ <cstring>chooseSubstitutionCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="chooseSubstitutionCombo">
+ <property name="autoCompletion">
+ <bool>true</bool>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addSubstitutionButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="interfaceTab">
+ <attribute name="title">
+ <string>Interface</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QGroupBox" name="feelSettingsGroup">
+ <property name="title">
+ <string>Feel Settings</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="doubleClickIntervalSpinBox">
+ <property name="suffix">
+ <string> ms</string>
+ </property>
+ <property name="minimum">
+ <number>10</number>
+ </property>
+ <property name="maximum">
+ <number>10000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="doubleClickIntervalLabel">
+ <property name="text">
+ <string>&amp;Double Click Interval:</string>
+ </property>
+ <property name="buddy">
+ <cstring>doubleClickIntervalSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="cursorFlashTimeSpinBox">
+ <property name="specialValueText">
+ <string>No blinking</string>
+ </property>
+ <property name="suffix">
+ <string> ms</string>
+ </property>
+ <property name="minimum">
+ <number>9</number>
+ </property>
+ <property name="maximum">
+ <number>10000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="cursorFlashTimeLabel">
+ <property name="text">
+ <string>&amp;Cursor Flash Time:</string>
+ </property>
+ <property name="buddy">
+ <cstring>cursorFlashTimeSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="wheelScrollLinesSpinBox">
+ <property name="suffix">
+ <string> lines</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="wheelScrollLinesLabel">
+ <property name="text">
+ <string>Wheel &amp;Scroll Lines:</string>
+ </property>
+ <property name="buddy">
+ <cstring>wheelScrollLinesSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QCheckBox" name="resolveLinksCheckBox">
+ <property name="text">
+ <string>Resolve symlinks in URLs</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="guiEffectsGroup">
+ <property name="title">
+ <string>GUI Effects</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="effectsCheckBox">
+ <property name="text">
+ <string>&amp;Enable</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+E</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="effectsFrame">
+ <layout class="QGridLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="menuEffectLabel">
+ <property name="text">
+ <string>&amp;Menu Effect:</string>
+ </property>
+ <property name="buddy">
+ <cstring>menuEffectCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="comboEffectLabel">
+ <property name="text">
+ <string>C&amp;omboBox Effect:</string>
+ </property>
+ <property name="buddy">
+ <cstring>comboEffectCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="toolTipEffectLabel">
+ <property name="text">
+ <string>&amp;ToolTip Effect:</string>
+ </property>
+ <property name="buddy">
+ <cstring>toolTipEffectCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="toolBoxEffectLabel">
+ <property name="text">
+ <string>Tool&amp;Box Effect:</string>
+ </property>
+ <property name="buddy">
+ <cstring>toolBoxEffectCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="menuEffectCombo">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <property name="autoCompletion">
+ <bool>true</bool>
+ </property>
+ <item>
+ <property name="text">
+ <string>Disable</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Animate</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Fade</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="comboEffectCombo">
+ <item>
+ <property name="text">
+ <string>Disable</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Animate</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="toolTipEffectCombo">
+ <item>
+ <property name="text">
+ <string>Disable</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Animate</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Fade</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="toolBoxEffectCombo">
+ <item>
+ <property name="text">
+ <string>Disable</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Animate</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="globalStrutGroup">
+ <property name="title">
+ <string>Global Strut</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="strutWidthLabel">
+ <property name="text">
+ <string>Minimum &amp;Width:</string>
+ </property>
+ <property name="buddy">
+ <cstring>strutWidthSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="strutHeightLabel">
+ <property name="text">
+ <string>Minimum Hei&amp;ght:</string>
+ </property>
+ <property name="buddy">
+ <cstring>strutHeightSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="strutWidthSpinBox">
+ <property name="suffix">
+ <string> pixels</string>
+ </property>
+ <property name="maximum">
+ <number>1000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="strutHeightSpinBox">
+ <property name="suffix">
+ <string> pixels</string>
+ </property>
+ <property name="maximum">
+ <number>1000</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="rtlExtensionsCheckBox">
+ <property name="text">
+ <string>Enhanced support for languages written right-to-left</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="inputStyleLabel">
+ <property name="text">
+ <string>XIM Input Style:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="inputStyleCombo">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>On The Spot</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Over The Spot</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Off The Spot</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Root</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="inputMethodLabel">
+ <property name="text">
+ <string>Default Input Method:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="inputMethodCombo">
+ <property name="currentIndex">
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="printerTab">
+ <attribute name="title">
+ <string>Printer</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QCheckBox" name="fontEmbeddingCheckBox">
+ <property name="text">
+ <string>Enable Font embedding</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="fontPathsGroup">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Font Paths</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="upFontpathButton">
+ <property name="text">
+ <string>Up</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="removeFontpathButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="downFontpathButton">
+ <property name="text">
+ <string>Down</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QListWidget" name="fontpathListBox"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item row="2" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="addFontPathButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="browseFontPathButton">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QLabel" name="browseFontPathLabel">
+ <property name="text">
+ <string>Press the &lt;b&gt;Browse&lt;/b&gt; button or enter a directory and press Enter to add them to the list.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <widget class="QLineEdit" name="fontPathLineEdit"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="phononTab">
+ <attribute name="title">
+ <string>Phonon</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="aboutPhononGroup">
+ <property name="title">
+ <string>About Phonon</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="phononVersionBuddyLabel">
+ <property name="text">
+ <string>Current Version:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="phononVersionLabel">
+ <property name="text">
+ <string>Not available</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="phononWebsiteBuddyLabel">
+ <property name="text">
+ <string>Website:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="phononWebsiteLabel">
+ <property name="text">
+ <string>&lt;a href=&quot;http://phonon.kde.org&quot;&gt;http://phonon.kde.org/&lt;/a&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="aboutGStreamerGroup">
+ <property name="title">
+ <string>About GStreamer</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="gstVersionBuddyLabel">
+ <property name="text">
+ <string>Current Version:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="gstVersionLabel">
+ <property name="text">
+ <string>Not available</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="gstWebsiteBuddyLabel">
+ <property name="text">
+ <string>Website:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="gstWebsiteLabel">
+ <property name="text">
+ <string>&lt;a href=&quot;http://gstreamer.freedesktop.org/&quot;&gt;http://gstreamer.freedesktop.org/&lt;/a&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="gstBackendGroup">
+ <property name="title">
+ <string>GStreamer backend settings</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="audiosinkLabel">
+ <property name="text">
+ <string>Preferred audio sink:</string>
+ </property>
+ <property name="buddy">
+ <cstring>audiosinkCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="audiosinkCombo"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="videomodeLabel">
+ <property name="text">
+ <string>Preferred render method:</string>
+ </property>
+ <property name="buddy">
+ <cstring>videomodeCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="videomodeCombo"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QLabel" name="gstBackendNoteLabel">
+ <property name="text">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Note: changes to these settings may prevent applications from starting up correctly.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="margin">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="phononLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="mainMenu">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>815</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="fileMenu">
+ <property name="geometry">
+ <rect>
+ <x>203</x>
+ <y>114</y>
+ <width>161</width>
+ <height>110</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <addaction name="fileSaveAction"/>
+ <addaction name="separator"/>
+ <addaction name="fileExitAction"/>
+ </widget>
+ <widget class="QMenu" name="saveMenu">
+ <property name="geometry">
+ <rect>
+ <x>543</x>
+ <y>98</y>
+ <width>161</width>
+ <height>106</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="helpAboutAction"/>
+ <addaction name="helpAboutQtAction"/>
+ </widget>
+ <addaction name="fileMenu"/>
+ <addaction name="separator"/>
+ <addaction name="saveMenu"/>
+ </widget>
+ <action name="fileSaveAction">
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ <property name="iconText">
+ <string>Save</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="fileExitAction">
+ <property name="text">
+ <string>E&amp;xit</string>
+ </property>
+ <property name="iconText">
+ <string>Exit</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="helpAboutAction">
+ <property name="text">
+ <string>&amp;About</string>
+ </property>
+ <property name="iconText">
+ <string>About</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ </action>
+ <action name="helpAboutQtAction">
+ <property name="text">
+ <string>About &amp;Qt</string>
+ </property>
+ <property name="iconText">
+ <string>About Qt</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ColorButton</class>
+ <extends></extends>
+ <header>colorbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>PreviewFrame</class>
+ <extends></extends>
+ <header>previewframe.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>helpView</tabstop>
+ <tabstop>mainTabWidget</tabstop>
+ <tabstop>guiStyleCombo</tabstop>
+ <tabstop>tunePaletteButton</tabstop>
+ <tabstop>paletteCombo</tabstop>
+ <tabstop>fontFamilyCombo</tabstop>
+ <tabstop>fontStyleCombo</tabstop>
+ <tabstop>pointSizeCombo</tabstop>
+ <tabstop>sampleLineEdit</tabstop>
+ <tabstop>familySubstitutionCombo</tabstop>
+ <tabstop>substitutionsListBox</tabstop>
+ <tabstop>upSubstitutionButton</tabstop>
+ <tabstop>downSubstitutionButton</tabstop>
+ <tabstop>removeSubstitutionButton</tabstop>
+ <tabstop>chooseSubstitutionCombo</tabstop>
+ <tabstop>addSubstitutionButton</tabstop>
+ <tabstop>doubleClickIntervalSpinBox</tabstop>
+ <tabstop>cursorFlashTimeSpinBox</tabstop>
+ <tabstop>wheelScrollLinesSpinBox</tabstop>
+ <tabstop>resolveLinksCheckBox</tabstop>
+ <tabstop>effectsCheckBox</tabstop>
+ <tabstop>menuEffectCombo</tabstop>
+ <tabstop>comboEffectCombo</tabstop>
+ <tabstop>toolTipEffectCombo</tabstop>
+ <tabstop>toolBoxEffectCombo</tabstop>
+ <tabstop>strutWidthSpinBox</tabstop>
+ <tabstop>strutHeightSpinBox</tabstop>
+ <tabstop>rtlExtensionsCheckBox</tabstop>
+ <tabstop>inputStyleCombo</tabstop>
+ <tabstop>inputMethodCombo</tabstop>
+ <tabstop>fontEmbeddingCheckBox</tabstop>
+ <tabstop>fontpathListBox</tabstop>
+ <tabstop>upFontpathButton</tabstop>
+ <tabstop>downFontpathButton</tabstop>
+ <tabstop>removeFontpathButton</tabstop>
+ <tabstop>fontPathLineEdit</tabstop>
+ <tabstop>browseFontPathButton</tabstop>
+ <tabstop>addFontPathButton</tabstop>
+ <tabstop>audiosinkCombo</tabstop>
+ <tabstop>videomodeCombo</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>effectsCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>effectsFrame</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>417</x>
+ <y>257</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>578</x>
+ <y>379</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fontEmbeddingCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>fontPathsGroup</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>449</x>
+ <y>69</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>447</x>
+ <y>94</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qtconfig/paletteeditoradvanced.cpp b/src/qtconfig/paletteeditoradvanced.cpp
new file mode 100644
index 000000000..4797ead93
--- /dev/null
+++ b/src/qtconfig/paletteeditoradvanced.cpp
@@ -0,0 +1,401 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "ui_paletteeditoradvanced.h"
+#include "paletteeditoradvanced.h"
+#include "colorbutton.h"
+
+QT_BEGIN_NAMESPACE
+
+PaletteEditorAdvanced::PaletteEditorAdvanced(QWidget *parent)
+ : QDialog(parent), ui(new Ui::PaletteEditorAdvanced), selectedPalette(0)
+{
+ ui->setupUi(this);
+
+ // create a ColorButton's
+ buttonCentral = new ColorButton(ui->groupCentral);
+ buttonCentral->setToolTip(tr("Choose a color"));
+ buttonCentral->setWhatsThis(tr("Choose a color for the selected central color role."));
+ ui->layoutCentral->addWidget(buttonCentral);
+ ui->labelCentral->setBuddy(buttonCentral);
+
+ buttonEffect = new ColorButton(ui->groupEffect);
+ buttonEffect->setToolTip(tr("Choose a color"));
+ buttonEffect->setWhatsThis(tr("Choose a color for the selected effect color role."));
+ buttonEffect->setEnabled(false);
+ ui->layoutEffect->addWidget(buttonEffect);
+ ui->labelEffect->setBuddy(buttonEffect);
+
+ // signals and slots connections
+ connect(ui->paletteCombo, SIGNAL(activated(int)), SLOT(paletteSelected(int)));
+ connect(ui->comboCentral, SIGNAL(activated(int)), SLOT(onCentral(int)));
+ connect(buttonCentral, SIGNAL(clicked()), SLOT(onChooseCentralColor()));
+ connect(buttonEffect, SIGNAL(clicked()), SLOT(onChooseEffectColor()));
+ connect(ui->comboEffect, SIGNAL(activated(int)), SLOT(onEffect(int)));
+ connect(ui->checkBuildEffect, SIGNAL(toggled(bool)), SLOT(onToggleBuildEffects(bool)));
+ connect(ui->checkBuildEffect, SIGNAL(toggled(bool)), buttonEffect, SLOT(setDisabled(bool)));
+ connect(ui->checkBuildInactive, SIGNAL(toggled(bool)), SLOT(onToggleBuildInactive(bool)));
+ connect(ui->checkBuildDisabled, SIGNAL(toggled(bool)), SLOT(onToggleBuildDisabled(bool)));
+
+ onToggleBuildEffects(true);
+
+ editPalette = QApplication::palette();
+}
+
+PaletteEditorAdvanced::~PaletteEditorAdvanced()
+{
+ delete ui;
+}
+
+void PaletteEditorAdvanced::onToggleBuildInactive(bool v)
+{
+ if (selectedPalette == 1) {
+ ui->groupCentral->setDisabled(v);
+ ui->groupEffect->setDisabled(v);
+ }
+
+ if (v) {
+ build(QPalette::Inactive);
+ updateColorButtons();
+ }
+}
+
+void PaletteEditorAdvanced::onToggleBuildDisabled(bool v)
+{
+ if (selectedPalette == 2) {
+ ui->groupCentral->setDisabled(v);
+ ui->groupEffect->setDisabled(v);
+ }
+
+ if (v) {
+ build(QPalette::Disabled);
+ updateColorButtons();
+ }
+}
+
+void PaletteEditorAdvanced::paletteSelected(int p)
+{
+ selectedPalette = p;
+
+ if(p == 1) { // inactive
+ ui->groupCentral->setDisabled(ui->checkBuildInactive->isChecked());
+ ui->groupEffect->setDisabled(ui->checkBuildInactive->isChecked());
+ } else if (p == 2) { // disabled
+ ui->groupCentral->setDisabled(ui->checkBuildDisabled->isChecked());
+ ui->groupEffect->setDisabled(ui->checkBuildDisabled->isChecked());
+ } else {
+ ui->groupCentral->setEnabled(true);
+ ui->groupEffect->setEnabled(true);
+ }
+ updateColorButtons();
+}
+
+void PaletteEditorAdvanced::onChooseCentralColor()
+{
+ QPalette::ColorGroup group = groupFromIndex(selectedPalette);
+ editPalette.setColor(group, centralFromIndex(ui->comboCentral->currentIndex()),
+ buttonCentral->color());
+
+ buildEffect(group);
+ if (group == QPalette::Active) {
+ if(ui->checkBuildInactive->isChecked())
+ build(QPalette::Inactive);
+ if(ui->checkBuildDisabled->isChecked())
+ build(QPalette::Disabled);
+ }
+
+ updateColorButtons();
+}
+
+void PaletteEditorAdvanced::onChooseEffectColor()
+{
+ QPalette::ColorGroup group = groupFromIndex(selectedPalette);
+ editPalette.setColor(group, effectFromIndex(ui->comboEffect->currentIndex()),
+ buttonEffect->color());
+
+ if (group == QPalette::Active) {
+ if(ui->checkBuildInactive->isChecked())
+ build(QPalette::Inactive);
+ if(ui->checkBuildDisabled->isChecked())
+ build(QPalette::Disabled);
+ }
+
+ updateColorButtons();
+}
+
+void PaletteEditorAdvanced::onToggleBuildEffects(bool on)
+{
+ if (on) {
+ for (int i = 0; i < QPalette::NColorGroups; i++)
+ buildEffect(QPalette::ColorGroup(i));
+ }
+}
+
+QPalette::ColorGroup PaletteEditorAdvanced::groupFromIndex(int item)
+{
+ switch (item) {
+ case 0:
+ default:
+ return QPalette::Active;
+ case 1:
+ return QPalette::Inactive;
+ case 2:
+ return QPalette::Disabled;
+ }
+}
+
+QPalette::ColorRole PaletteEditorAdvanced::centralFromIndex(int item)
+{
+ switch (item) {
+ case 0:
+ return QPalette::Window;
+ case 1:
+ return QPalette::WindowText;
+ case 2:
+ return QPalette::Base;
+ case 3:
+ return QPalette::AlternateBase;
+ case 4:
+ return QPalette::ToolTipBase;
+ case 5:
+ return QPalette::ToolTipText;
+ case 6:
+ return QPalette::Text;
+ case 7:
+ return QPalette::Button;
+ case 8:
+ return QPalette::ButtonText;
+ case 9:
+ return QPalette::BrightText;
+ case 10:
+ return QPalette::Highlight;
+ case 11:
+ return QPalette::HighlightedText;
+ case 12:
+ return QPalette::Link;
+ case 13:
+ return QPalette::LinkVisited;
+ default:
+ return QPalette::NoRole;
+ }
+}
+
+QPalette::ColorRole PaletteEditorAdvanced::effectFromIndex(int item)
+{
+ switch (item) {
+ case 0:
+ return QPalette::Light;
+ case 1:
+ return QPalette::Midlight;
+ case 2:
+ return QPalette::Mid;
+ case 3:
+ return QPalette::Dark;
+ case 4:
+ return QPalette::Shadow;
+ default:
+ return QPalette::NoRole;
+ }
+}
+
+void PaletteEditorAdvanced::onCentral(int item)
+{
+ QColor c = editPalette.color(groupFromIndex(selectedPalette), centralFromIndex(item));
+ buttonCentral->setColor(c);
+}
+
+void PaletteEditorAdvanced::onEffect(int item)
+{
+ QColor c = editPalette.color(groupFromIndex(selectedPalette), effectFromIndex(item));
+ buttonEffect->setColor(c);
+}
+
+QPalette PaletteEditorAdvanced::buildEffect(QPalette::ColorGroup colorGroup,
+ const QPalette &basePalette)
+{
+ QPalette result(basePalette);
+
+ if (colorGroup == QPalette::Active) {
+ QPalette calculatedPalette(basePalette.color(colorGroup, QPalette::Button),
+ basePalette.color(colorGroup, QPalette::Window));
+
+ for (int i = 0; i < 5; i++) {
+ QPalette::ColorRole effectRole = effectFromIndex(i);
+ result.setColor(colorGroup, effectRole,
+ calculatedPalette.color(colorGroup, effectRole));
+ }
+ } else {
+ QColor btn = basePalette.color(colorGroup, QPalette::Button);
+
+ result.setColor(colorGroup, QPalette::Light, btn.lighter());
+ result.setColor(colorGroup, QPalette::Midlight, btn.lighter(115));
+ result.setColor(colorGroup, QPalette::Mid, btn.darker(150));
+ result.setColor(colorGroup, QPalette::Dark, btn.darker());
+ result.setColor(colorGroup, QPalette::Shadow, Qt::black);
+ }
+
+ return result;
+}
+
+void PaletteEditorAdvanced::buildEffect(QPalette::ColorGroup colorGroup)
+{
+ editPalette = buildEffect(colorGroup, editPalette);
+ updateColorButtons();
+}
+
+void PaletteEditorAdvanced::build(QPalette::ColorGroup colorGroup)
+{
+ if (colorGroup != QPalette::Active) {
+ for (int i = 0; i < QPalette::NColorRoles; i++)
+ editPalette.setColor(colorGroup, QPalette::ColorRole(i),
+ editPalette.color(QPalette::Active, QPalette::ColorRole(i)));
+
+ if (colorGroup == QPalette::Disabled) {
+ editPalette.setColor(colorGroup, QPalette::ButtonText, Qt::darkGray);
+ editPalette.setColor(colorGroup, QPalette::WindowText, Qt::darkGray);
+ editPalette.setColor(colorGroup, QPalette::Text, Qt::darkGray);
+ editPalette.setColor(colorGroup, QPalette::HighlightedText, Qt::darkGray);
+ }
+
+ if (ui->checkBuildEffect->isChecked())
+ buildEffect(colorGroup);
+ else
+ updateColorButtons();
+ }
+}
+
+void PaletteEditorAdvanced::updateColorButtons()
+{
+ QPalette::ColorGroup colorGroup = groupFromIndex(selectedPalette);
+ buttonCentral->setColor(editPalette.color(colorGroup,
+ centralFromIndex(ui->comboCentral->currentIndex())));
+ buttonEffect->setColor(editPalette.color(colorGroup,
+ effectFromIndex(ui->comboEffect->currentIndex())));
+}
+
+void PaletteEditorAdvanced::setPal(const QPalette &pal)
+{
+ editPalette = pal;
+ updateColorButtons();
+}
+
+QPalette PaletteEditorAdvanced::pal() const
+{
+ return editPalette;
+}
+
+void PaletteEditorAdvanced::setupBackgroundRole(QPalette::ColorRole role)
+{
+ int initRole = 0;
+
+ switch (role) {
+ case QPalette::Window:
+ initRole = 0;
+ break;
+ case QPalette::WindowText:
+ initRole = 1;
+ break;
+ case QPalette::Base:
+ initRole = 2;
+ break;
+ case QPalette::AlternateBase:
+ initRole = 3;
+ break;
+ case QPalette::ToolTipBase:
+ initRole = 4;
+ break;
+ case QPalette::ToolTipText:
+ initRole = 5;
+ break;
+ case QPalette::Text:
+ initRole = 6;
+ break;
+ case QPalette::Button:
+ initRole = 7;
+ break;
+ case QPalette::ButtonText:
+ initRole = 8;
+ break;
+ case QPalette::BrightText:
+ initRole = 9;
+ break;
+ case QPalette::Highlight:
+ initRole = 10;
+ break;
+ case QPalette::HighlightedText:
+ initRole = 11;
+ break;
+ case QPalette::Link:
+ initRole = 12;
+ break;
+ case QPalette::LinkVisited:
+ initRole = 13;
+ break;
+ default:
+ initRole = -1;
+ break;
+ }
+
+ if (initRole != -1)
+ ui->comboCentral->setCurrentIndex(initRole);
+}
+
+QPalette PaletteEditorAdvanced::getPalette(bool *ok, const QPalette &init,
+ QPalette::ColorRole backgroundRole, QWidget *parent)
+{
+ PaletteEditorAdvanced *dlg = new PaletteEditorAdvanced(parent);
+ dlg->setupBackgroundRole(backgroundRole);
+
+ if (init != QPalette())
+ dlg->setPal(init);
+ int resultCode = dlg->exec();
+
+ QPalette result = init;
+ if (resultCode == QDialog::Accepted)
+ result = dlg->pal();
+
+ if (ok)
+ *ok = resultCode;
+
+ delete dlg;
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qtconfig/paletteeditoradvanced.h b/src/qtconfig/paletteeditoradvanced.h
new file mode 100644
index 000000000..4f6167670
--- /dev/null
+++ b/src/qtconfig/paletteeditoradvanced.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PALETTEEDITORADVANCED_H
+#define PALETTEEDITORADVANCED_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class PaletteEditorAdvanced;
+}
+
+class ColorButton;
+
+class PaletteEditorAdvanced : public QDialog
+{
+ Q_OBJECT
+public:
+ PaletteEditorAdvanced(QWidget *parent = 0);
+ ~PaletteEditorAdvanced();
+
+ static QPalette getPalette(bool *ok, const QPalette &pal,
+ QPalette::ColorRole backgroundRole = QPalette::Window,
+ QWidget *parent = 0);
+
+ static QPalette buildEffect(QPalette::ColorGroup colorGroup, const QPalette &basePalette);
+
+protected slots:
+ void paletteSelected(int);
+
+ void onCentral(int);
+ void onEffect(int);
+
+ void onChooseCentralColor();
+ void onChooseEffectColor();
+
+ void onToggleBuildEffects(bool);
+ void onToggleBuildInactive(bool);
+ void onToggleBuildDisabled(bool);
+
+protected:
+ void buildEffect(QPalette::ColorGroup);
+ void build(QPalette::ColorGroup);
+
+private:
+ void updateColorButtons();
+ void setupBackgroundRole(QPalette::ColorRole);
+
+ QPalette pal() const;
+ void setPal(const QPalette &);
+
+ static QPalette::ColorGroup groupFromIndex(int);
+ static QPalette::ColorRole centralFromIndex(int);
+ static QPalette::ColorRole effectFromIndex(int);
+ QPalette editPalette;
+
+ Ui::PaletteEditorAdvanced *ui;
+
+ int selectedPalette;
+ ColorButton *buttonCentral;
+ ColorButton *buttonEffect;
+};
+
+QT_END_NAMESPACE
+
+#endif // PALETTEEDITORADVANCED_H
diff --git a/src/qtconfig/paletteeditoradvanced.ui b/src/qtconfig/paletteeditoradvanced.ui
new file mode 100644
index 000000000..0b4ae6613
--- /dev/null
+++ b/src/qtconfig/paletteeditoradvanced.ui
@@ -0,0 +1,416 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>PaletteEditorAdvanced</class>
+ <widget class="QDialog" name="PaletteEditorAdvanced">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>239</width>
+ <height>344</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Tune Palette</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="paletteComboLabel">
+ <property name="text">
+ <string>Select &amp;Palette:</string>
+ </property>
+ <property name="buddy">
+ <cstring>paletteCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="paletteCombo">
+ <item>
+ <property name="text">
+ <string>Active Palette</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Inactive Palette</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Disabled Palette</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="autoGroupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Auto</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QCheckBox" name="checkBuildInactive">
+ <property name="text">
+ <string>Build inactive palette from active</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBuildDisabled">
+ <property name="text">
+ <string>Build disabled palette from active</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupCentral">
+ <property name="title">
+ <string>Central color &amp;roles</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QComboBox" name="comboCentral">
+ <property name="toolTip">
+ <string>Choose central color role</string>
+ </property>
+ <property name="whatsThis">
+ <string>&lt;b&gt;Select a color role.&lt;/b&gt;&lt;p&gt;Available central roles are: &lt;ul&gt; &lt;li&gt;Window - general background color.&lt;/li&gt; &lt;li&gt;WindowText - general foreground color. &lt;/li&gt; &lt;li&gt;Base - used as background color for e.g. text entry widgets, usually white or another light color. &lt;/li&gt; &lt;li&gt;Text - the foreground color used with Base. Usually this is the same as WindowText, in what case it must provide good contrast both with Window and Base. &lt;/li&gt; &lt;li&gt;Button - general button background color, where buttons need a background different from Window, as in the Macintosh style. &lt;/li&gt; &lt;li&gt;ButtonText - a foreground color used with the Button color. &lt;/li&gt; &lt;li&gt;Highlight - a color to indicate a selected or highlighted item. &lt;/li&gt; &lt;li&gt;HighlightedText - a text color that contrasts to Highlight. &lt;/li&gt; &lt;li&gt;BrightText - a text color that is very different from WindowText and contrasts well with e.g. black. &lt;/li&gt; &lt;/ul&gt; &lt;/p&gt;</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>Window</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>WindowText</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Base</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>AlternateBase</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ToolTipBase</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ToolTipText</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Text</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Button</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ButtonText</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BrightText</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Highlight</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>HighlightedText</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Link</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>LinkVisited</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="layoutCentral">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelCentral">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&amp;Select Color:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupEffect">
+ <property name="title">
+ <string>3-D shadow &amp;effects</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="checkBuildEffect">
+ <property name="toolTip">
+ <string>Generate shadings</string>
+ </property>
+ <property name="whatsThis">
+ <string>Check to let 3D-effect colors be calculated from button-color.</string>
+ </property>
+ <property name="text">
+ <string>Build &amp;from button color</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboEffect">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Choose 3D-effect color role</string>
+ </property>
+ <property name="whatsThis">
+ <string>&lt;b&gt;Select a color role.&lt;/b&gt;&lt;p&gt;Available effect roles are: &lt;ul&gt; &lt;li&gt;Light - lighter than Button color. &lt;/li&gt; &lt;li&gt;Midlight - between Button and Light. &lt;/li&gt; &lt;li&gt;Mid - between Button and Dark. &lt;/li&gt; &lt;li&gt;Dark - darker than Button. &lt;/li&gt; &lt;li&gt;Shadow - a very dark color. &lt;/li&gt; &lt;/ul&gt;</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>Light</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Midlight</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Mid</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Dark</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Shadow</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="layoutEffect">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelEffect">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Select Co&amp;lor:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>PaletteEditorAdvanced</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>238</x>
+ <y>384</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>PaletteEditorAdvanced</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>306</x>
+ <y>390</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>checkBuildEffect</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>comboEffect</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>82</x>
+ <y>262</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>190</x>
+ <y>262</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qtconfig/previewframe.cpp b/src/qtconfig/previewframe.cpp
new file mode 100644
index 000000000..c6df89950
--- /dev/null
+++ b/src/qtconfig/previewframe.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "previewframe.h"
+#include "previewwidget.h"
+
+#include <QBoxLayout>
+#include <QPainter>
+#include <QMdiSubWindow>
+
+QT_BEGIN_NAMESPACE
+
+PreviewFrame::PreviewFrame(QWidget *parent)
+ : QFrame(parent)
+{
+ setMinimumSize(200, 200);
+ setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ setLineWidth(1);
+
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ vbox->setMargin(0);
+ previewWidget = new PreviewWidget;
+ workspace = new Workspace(this);
+ vbox->addWidget(workspace);
+ previewWidget->setAutoFillBackground(true);
+}
+
+void PreviewFrame::setPreviewPalette(QPalette pal)
+{
+ previewWidget->setPalette(pal);
+}
+
+QString PreviewFrame::previewText() const
+{
+ return m_previewWindowText;
+}
+
+void PreviewFrame::setPreviewVisible(bool visible)
+{
+ previewWidget->parentWidget()->setVisible(visible);
+ if (visible)
+ m_previewWindowText = QLatin1String("The moose in the noose\nate the goose who was loose.");
+ else
+ m_previewWindowText = tr("Desktop settings will only take effect after an application restart.");
+ workspace->viewport()->update();
+}
+
+Workspace::Workspace(PreviewFrame *parent)
+ : QMdiArea(parent)
+{
+ previewFrame = parent;
+ PreviewWidget *previewWidget = previewFrame->widget();
+ QMdiSubWindow *frame = addSubWindow(previewWidget, Qt::Window);
+ frame->move(10, 10);
+ frame->show();
+}
+
+void Workspace::paintEvent(QPaintEvent *)
+{
+ QPainter p(viewport());
+ p.fillRect(rect(), palette().color(backgroundRole()).dark());
+ p.setPen(QPen(Qt::white));
+ p.drawText(0, height() / 2, width(), height(), Qt::AlignHCenter, previewFrame->previewText());
+}
+
+QT_END_NAMESPACE
diff --git a/src/qtconfig/previewframe.h b/src/qtconfig/previewframe.h
new file mode 100644
index 000000000..5cb0d59c1
--- /dev/null
+++ b/src/qtconfig/previewframe.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREVIEWFRAME_H
+#define PREVIEWFRAME_H
+
+#include <QMdiArea>
+
+QT_BEGIN_NAMESPACE
+
+class PreviewFrame;
+class Workspace : public QMdiArea
+{
+ Q_OBJECT
+
+public:
+ Workspace(PreviewFrame *parent = 0);
+ ~Workspace() {}
+
+protected:
+ void paintEvent(QPaintEvent *);
+private:
+ PreviewFrame *previewFrame;
+};
+
+class PreviewWidget;
+class PreviewFrame : public QFrame
+{
+ Q_OBJECT
+
+public:
+ PreviewFrame(QWidget *parent = 0);
+ void setPreviewPalette(QPalette);
+ void setPreviewVisible(bool val);
+ QString previewText() const;
+ PreviewWidget *widget() const { return previewWidget; }
+private:
+ Workspace *workspace;
+ PreviewWidget *previewWidget;
+ QString m_previewWindowText;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qtconfig/previewwidget.cpp b/src/qtconfig/previewwidget.cpp
new file mode 100644
index 000000000..66ebb92b6
--- /dev/null
+++ b/src/qtconfig/previewwidget.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "previewwidget.h"
+#include "ui_previewwidget.h"
+#include <QtEvents>
+
+QT_BEGIN_NAMESPACE
+
+PreviewWidget::PreviewWidget(QWidget *parent)
+ : QWidget(parent), ui(new Ui::PreviewWidget)
+{
+ ui->setupUi(this);
+
+ // install event filter on child widgets
+ QList<QWidget *> l = findChildren<QWidget *>();
+ foreach(QWidget *w, l) {
+ w->installEventFilter(this);
+ w->setFocusPolicy(Qt::NoFocus);
+ }
+}
+
+PreviewWidget::~PreviewWidget()
+{
+ delete ui;
+}
+
+bool PreviewWidget::eventFilter(QObject *, QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::Enter:
+ case QEvent::Leave:
+ return true; // ignore;
+ default:
+ break;
+ }
+ return false;
+}
+
+void PreviewWidget::closeEvent(QCloseEvent *e)
+{
+ e->ignore();
+}
+
+QT_END_NAMESPACE
diff --git a/src/qtconfig/previewwidget.h b/src/qtconfig/previewwidget.h
new file mode 100644
index 000000000..d39fd7540
--- /dev/null
+++ b/src/qtconfig/previewwidget.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREVIEWWIDGET_H
+#define PREVIEWWIDGET_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class PreviewWidget;
+}
+
+
+class PreviewWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ PreviewWidget(QWidget *parent = 0);
+ ~PreviewWidget();
+
+ bool eventFilter(QObject *, QEvent *);
+private:
+ void closeEvent(QCloseEvent *);
+ Ui::PreviewWidget *ui;
+};
+
+QT_END_NAMESPACE
+
+#endif // PREVIEWWIDGET_H
diff --git a/src/qtconfig/previewwidget.ui b/src/qtconfig/previewwidget.ui
new file mode 100644
index 000000000..fac4b6c34
--- /dev/null
+++ b/src/qtconfig/previewwidget.ui
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>PreviewWidget</class>
+ <widget class="QWidget" name="PreviewWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>398</width>
+ <height>282</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Preview Window</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="GroupBox1">
+ <property name="title">
+ <string>GroupBox</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="RadioButton1">
+ <property name="text">
+ <string>RadioButton1</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="RadioButton2">
+ <property name="text">
+ <string>RadioButton2</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="RadioButton3">
+ <property name="text">
+ <string>RadioButton3</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="GroupBox2">
+ <property name="title">
+ <string>GroupBox2</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="CheckBox1">
+ <property name="text">
+ <string>CheckBox1</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="CheckBox2">
+ <property name="text">
+ <string>CheckBox2</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="ProgressBar1">
+ <property name="value">
+ <number>50</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="LineEdit1">
+ <property name="text">
+ <string>LineEdit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="ComboBox1">
+ <item>
+ <property name="text">
+ <string>ComboBox</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="SpinBox1"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="PushButton1">
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QScrollBar" name="ScrollBar1">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="Slider1">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="textView">
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>55</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="html">
+ <string>&lt;p&gt;&lt;a href=&quot;http://qt.nokia.com&quot;&gt;http://qt.nokia.com&lt;/a&gt;&lt;/p&gt;
+&lt;p&gt;&lt;a href=&quot;http://www.kde.org&quot;&gt;http://www.kde.org&lt;/a&gt;&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="Spacer2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/qtconfig/qtconfig.pro b/src/qtconfig/qtconfig.pro
new file mode 100644
index 000000000..cb06e5a99
--- /dev/null
+++ b/src/qtconfig/qtconfig.pro
@@ -0,0 +1,28 @@
+TEMPLATE = app
+CONFIG += qt warn_on x11
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+LANGUAGE = C++
+
+contains(QT_CONFIG, gstreamer):LIBS += $$QT_LIBS_GSTREAMER -lgstinterfaces-0.10 -lgstvideo-0.10 -lgstbase-0.10
+contains(QT_CONFIG, gstreamer):QMAKE_CXXFLAGS += $$QT_CFLAGS_GSTREAMER
+contains(QT_CONFIG, phonon) {
+ QT += phonon
+ DEFINES += HAVE_PHONON
+}
+SOURCES += colorbutton.cpp main.cpp previewframe.cpp previewwidget.cpp mainwindow.cpp paletteeditoradvanced.cpp
+HEADERS += colorbutton.h previewframe.h previewwidget.h mainwindow.h paletteeditoradvanced.h
+
+FORMS = mainwindow.ui paletteeditoradvanced.ui previewwidget.ui
+RESOURCES = qtconfig.qrc
+
+PROJECTNAME = Qt Configuration
+TARGET = qtconfig
+DESTDIR = ../../bin
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+INCLUDEPATH += .
+DBFILE = qtconfig.db
diff --git a/src/qtconfig/qtconfig.qrc b/src/qtconfig/qtconfig.qrc
new file mode 100644
index 000000000..cd6656727
--- /dev/null
+++ b/src/qtconfig/qtconfig.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/qtconfig/">
+ <file>images/appicon.png</file>
+</qresource>
+</RCC>
diff --git a/src/qtestlib/qtestlib.pro b/src/qtestlib/qtestlib.pro
new file mode 100644
index 000000000..da94e81ec
--- /dev/null
+++ b/src/qtestlib/qtestlib.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+!wince*: SUBDIRS += updater
+wince*: contains(QT_CONFIG, cetest): SUBDIRS += wince
+CONFIG += ordered
diff --git a/src/qtestlib/updater/main.cpp b/src/qtestlib/updater/main.cpp
new file mode 100644
index 000000000..a6465a469
--- /dev/null
+++ b/src/qtestlib/updater/main.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QtCore>
+
+#include <stdio.h>
+
+QT_USE_NAMESPACE
+
+static void printHelp(char *argv[])
+{
+ qDebug("Usage: %s [-diff] FILES", argv[0] ? argv[0] : "qtest2to4");
+ qDebug("updates files from QtTestLib 2.x to QTestLib 4.1");
+ qDebug("\noptions:\n -diff Don't write any changes, output differences instead.");
+ exit(2);
+}
+
+int main(int argc, char *argv[])
+{
+ bool printDiff = false;
+ int i = 1;
+
+ if (argc == 1)
+ printHelp(argv);
+ if (argv[1][0] == '-') {
+ if (qstrcmp(argv[1], "-diff") == 0) {
+ printDiff = true;
+ ++i;
+ } else {
+ qDebug("Unknown option: %s\n", argv[1]);
+ printHelp(argv);
+ }
+ }
+
+ QRegExp dataHeaderRx(QLatin1String("_data(\\s*)\\((\\s*)QtTestTable\\s*\\&\\s*\\w*\\s*\\)"));
+ QRegExp defElemRx(QLatin1String("\\w+\\.defineElement\\s*\\(\\s*\"(.+)\"\\s*,\\s*\"(.+)\"\\s*\\)"));
+ defElemRx.setMinimal(true);
+ QRegExp addDataRx(QLatin1String("\\*\\w+\\.newData(\\s*)(\\(\\s*\".*\"\\s*\\))"));
+ addDataRx.setMinimal(true);
+ QRegExp nsRx(QLatin1String("namespace(\\s+)QtTest"));
+ QRegExp callRx(QLatin1String("QtTest(\\s*)::"));
+
+ enum { MacroCount = 11 };
+ static const char *macroNames[MacroCount] = {
+ "VERIFY", "FAIL", "VERIFY2", "COMPARE", "SKIP", "VERIFY_EVENT",
+ "EXPECT_FAIL", "FETCH", "FETCH_GLOBAL", "TEST", "WARN"
+ };
+
+ for (; i < argc; ++i) {
+ QFile f(QString::fromLocal8Bit(argv[i]));
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ qFatal("Unable to open file '%s' for reading: %s", argv[i], qPrintable(f.errorString()));
+
+ if (printDiff)
+ printf("diff %s\n", argv[i]);
+
+ QStringList contents;
+ int lineNumber = 0;
+ int changedLines = 0;
+ while (!f.atEnd()) {
+ QString origLine = QString::fromLatin1(f.readLine());
+ QString line = origLine;
+ ++lineNumber;
+
+ if (dataHeaderRx.indexIn(line) != -1) {
+ QString ws = dataHeaderRx.cap(1);
+ line.replace(dataHeaderRx, QString::fromLatin1("_data%1()").arg(ws));
+ }
+ if (defElemRx.indexIn(line) != -1) {
+ QString type = defElemRx.cap(1);
+ QString name = defElemRx.cap(2);
+ if (type.endsWith(QLatin1Char('>')))
+ type.append(QLatin1Char(' '));
+ line.replace(defElemRx, QString::fromLatin1("QTest::addColumn<%1>(\"%2\")").arg(
+ type).arg(name));
+ }
+ if (addDataRx.indexIn(line) != -1) {
+ QString repl = QLatin1String("QTest::newRow");
+ repl += addDataRx.cap(1);
+ repl += addDataRx.cap(2);
+ line.replace(addDataRx, repl);
+ }
+ if (nsRx.indexIn(line) != -1)
+ line.replace(nsRx, QString::fromLatin1("namespace%1QTest").arg(nsRx.cap(1)));
+ int pos = 0;
+ while ((pos = callRx.indexIn(line, pos)) != -1) {
+ line.replace(callRx, QString::fromLatin1("QTest%1::").arg(callRx.cap(1)));
+ pos += callRx.matchedLength();
+ }
+
+ line.replace(QLatin1String("QTTEST_MAIN"), QLatin1String("QTEST_MAIN"));
+ line.replace(QLatin1String("QTTEST_APPLESS_MAIN"), QLatin1String("QTEST_APPLESS_MAIN"));
+ line.replace(QLatin1String("QTTEST_NOOP_MAIN"), QLatin1String("QTEST_NOOP_MAIN"));
+ line.replace(QLatin1String("QtTestEventLoop"), QLatin1String("QTestEventLoop"));
+ line.replace(QLatin1String("QtTestEventList"), QLatin1String("QTestEventList"));
+ line.replace(QLatin1String("QtTestAccessibility"), QLatin1String("QTestAccessibility"));
+ line.replace(QLatin1String("QTest::sleep"), QLatin1String("QTest::qSleep"));
+ line.replace(QLatin1String("QTest::wait"), QLatin1String("QTest::qWait"));
+
+ for (int m = 0; m < MacroCount; ++m) {
+ QRegExp macroRe(QString::fromLatin1("\\b%1(\\s*\\()").arg(
+ QLatin1String(macroNames[m])));
+ QString newMacroName = QLatin1Char('Q') + QString::fromLatin1(macroNames[m]);
+ int pos = 0;
+ while ((pos = macroRe.indexIn(line)) != -1) {
+ line.replace(macroRe, newMacroName + macroRe.cap(1));
+ pos += macroRe.matchedLength();
+ }
+ }
+
+ if (line != origLine) {
+ if (printDiff) {
+ printf("%dc%d\n", lineNumber, lineNumber);
+ printf("<%s", qPrintable(origLine));
+ printf("---\n");
+ printf(">%s", qPrintable(line));
+ }
+ ++changedLines;
+ }
+
+ contents.append(line);
+ }
+ f.close();
+
+ if (printDiff)
+ continue;
+ qDebug("%s: %d change%s made.", argv[i], changedLines, changedLines == 1 ? "" : "s");
+ if (!changedLines)
+ continue;
+
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Text))
+ qFatal("Unable to open file '%s' for writing: %s", argv[i], qPrintable(f.errorString()));
+ foreach (QString s, contents)
+ f.write(s.toLatin1());
+ f.close();
+ }
+
+ return 0;
+}
+
diff --git a/src/qtestlib/updater/updater.pro b/src/qtestlib/updater/updater.pro
new file mode 100644
index 000000000..42e1b74bd
--- /dev/null
+++ b/src/qtestlib/updater/updater.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET +=
+DEPENDPATH += .
+INCLUDEPATH += .
+
+SOURCES += main.cpp
+
+QT = core
+
+DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
diff --git a/src/qtestlib/wince/cetcpsync/cetcpsync.pro b/src/qtestlib/wince/cetcpsync/cetcpsync.pro
new file mode 100644
index 000000000..d1d7c999a
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsync/cetcpsync.pro
@@ -0,0 +1,22 @@
+TARGET = cetcpsync
+DESTDIR = ../../../../bin
+CONFIG += console
+CONFIG -= app_bundle
+QT += network
+QT -= gui
+TEMPLATE = app
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+INCLUDEPATH += ../cetcpsyncserver
+
+SOURCES += main.cpp \
+ remoteconnection.cpp \
+ qtcesterconnection.cpp
+
+HEADERS += \
+ remoteconnection.h \
+ qtcesterconnection.h
diff --git a/src/qtestlib/wince/cetcpsync/main.cpp b/src/qtestlib/wince/cetcpsync/main.cpp
new file mode 100644
index 000000000..4d209e356
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsync/main.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <iostream>
+#include "qtcesterconnection.h"
+
+using namespace std;
+
+static void showUsage()
+{
+ cout << "cetcpsync is meant to be used by cetest internally." << endl
+ << "For usage instructions remoteconnection.h could be useful." << endl;
+}
+
+const int debugLevel = 0;
+void debugOutput(const QString& text, int level)
+{
+ if (level <= debugLevel)
+ cout << qPrintable(text) << endl;
+}
+
+class Exception
+{
+public:
+ Exception(const QString& msg = QString())
+ : m_message(msg)
+ {}
+
+ QString message() { return m_message; }
+
+protected:
+ QString m_message;
+};
+
+class TooFewParametersException : public Exception
+{
+public:
+ TooFewParametersException(const QLatin1String& cmd, int expectedParameterCount)
+ {
+ m_message = QLatin1String("Command ") + cmd + QLatin1String(" needs at least ");
+ m_message.append(QString::number(expectedParameterCount));
+ m_message.append(QLatin1String(" parameters."));
+ }
+};
+
+static void fileTimeFromString(FILETIME& ft, const QString& str)
+{
+ int idx = str.indexOf("*");
+ if (idx <= 0)
+ return;
+ ft.dwLowDateTime = str.left(idx).toULong();
+ ft.dwHighDateTime = str.mid(idx+1).toULong();
+}
+
+static QString fileTimeToString(FILETIME& ft)
+{
+ return QString::number(ft.dwLowDateTime) + "*" + QString::number(ft.dwHighDateTime);
+}
+
+static int execCommand(const QLatin1String& cmd, int argc, char* argv[])
+{
+ int retval = 0;
+ bool success = true;
+ QtCesterConnection connection;
+ if (cmd == "copyFileToDevice") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.copyFileToDevice(argv[0], argv[1], argv[2] == "true");
+ } else if (cmd == "copyDirectoryToDevice") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.copyDirectoryToDevice(argv[0], argv[1], argv[2] == "true");
+ } else if (cmd == "copyFileFromDevice") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.copyFileFromDevice(argv[0], argv[1], argv[2] == "true");
+ } else if (cmd == "copyDirectoryFromDevice") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.copyDirectoryFromDevice(argv[0], argv[1], argv[2] == "true");
+ } else if (cmd == "timeStampForLocalFileTime") {
+ if (argc < 1)
+ throw TooFewParametersException(cmd, 1);
+ FILETIME ft;
+ fileTimeFromString(ft, argv[0]);
+ success = connection.timeStampForLocalFileTime(&ft);
+ if (success)
+ cout << qPrintable(fileTimeToString(ft));
+ } else if (cmd == "fileCreationTime") {
+ if (argc < 1)
+ throw TooFewParametersException(cmd, 1);
+ FILETIME ft;
+ success = connection.fileCreationTime(argv[0], &ft);
+ if (success)
+ cout << qPrintable(fileTimeToString(ft));
+ } else if (cmd == "copyFile") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.copyFile(argv[0], argv[1], argv[2] == "true");
+ } else if (cmd == "copyDirectory") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.copyDirectory(argv[0], argv[1], argv[2] == "true");
+ } else if (cmd == "deleteFile") {
+ if (argc < 1)
+ throw TooFewParametersException(cmd, 1);
+ success = connection.deleteFile(argv[0]);
+ } else if (cmd == "deleteDirectory") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.deleteDirectory(argv[0], argv[1] == "true", argv[2] == "true");
+ } else if (cmd == "moveFile") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.moveFile(argv[0], argv[1], argv[2] == "true");
+ } else if (cmd == "moveDirectory") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ success = connection.moveDirectory(argv[0], argv[1], argv[2] == "true");
+ } else if (cmd == "createDirectory") {
+ if (argc < 2)
+ throw TooFewParametersException(cmd, 2);
+ success = connection.createDirectory(argv[0], argv[1] == "true");
+ } else if (cmd == "execute") {
+ if (argc < 3)
+ throw TooFewParametersException(cmd, 3);
+ int timeout = QString(argv[2]).toInt();
+ success = connection.execute(argv[0], argv[1], timeout, &retval);
+ } else if (cmd == "noop") {
+ // do nothing :)
+ success = true;
+ } else {
+ throw Exception("unknown command");
+ }
+
+ return success ? retval : 1;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc <= 1) {
+ showUsage();
+ return 0;
+ }
+
+ QLatin1String param(argv[1]);
+ int result = 1;
+ try {
+ result = execCommand(param, argc - 2, argv + 2);
+ } catch (Exception e) {
+ cerr << "Error: " << qPrintable(e.message());
+ }
+ return result;
+}
diff --git a/src/qtestlib/wince/cetcpsync/qtcesterconnection.cpp b/src/qtestlib/wince/cetcpsync/qtcesterconnection.cpp
new file mode 100644
index 000000000..5d358e80b
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsync/qtcesterconnection.cpp
@@ -0,0 +1,552 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qtcesterconnection.h"
+#include <transfer_global.h>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtNetwork/QTcpSocket>
+#include <QtNetwork/QHostAddress>
+
+extern void debugOutput(const QString& text, int level);
+
+#pragma warning(disable:4996)
+
+#define END_ERROR(s, a) \
+ if(a) qDebug() << a; \
+ _freeSocket(s); \
+ return false;
+
+QtCesterConnection::QtCesterConnection()
+ : AbstractRemoteConnection()
+{
+}
+
+QtCesterConnection::~QtCesterConnection()
+{
+}
+
+bool QtCesterConnection::connect(QVariantList&)
+{
+ // We connect with each command, so this is always true
+ // The command itself will fail then
+ connected = true;
+ return true;
+}
+
+void QtCesterConnection::disconnect()
+{
+ connected = false;
+}
+
+bool QtCesterConnection::isConnected() const
+{
+ return connected;
+}
+
+bool QtCesterConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists)
+{
+ debugOutput( qPrintable(QString::fromLatin1("Copy File: %1 -> %2").arg(localSource).arg(deviceDest)),0);
+ QFile localFile(localSource);
+ QFileInfo info(localSource);
+ if (!localFile.exists() || !localFile.open(QIODevice::ReadOnly)) {
+ qDebug() << "Could not open File!";
+ return false;
+ }
+
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_CREATE_FILE)) {
+ END_ERROR(socket, "Could not initialized command");
+ }
+
+ CreateFileOptions option;
+ strcpy(option.fileName, qPrintable(deviceDest));
+#ifdef Q_OS_WIN
+ // Copy FileTime for update verification
+ FILETIME creationTime, accessTime, writeTime;
+ HANDLE localHandle = CreateFile(localSource.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ if (localHandle != INVALID_HANDLE_VALUE) {
+ if (GetFileTime(localHandle, &creationTime, &accessTime, &writeTime)) {
+ LocalFileTimeToFileTime(&writeTime, &writeTime);
+ option.fileTime = writeTime;
+ }
+ CloseHandle(localHandle);
+ }
+ DWORD attributes = GetFileAttributes(localSource.utf16());
+ if (attributes != -1 )
+ option.fileAttributes = attributes;
+#endif
+ option.fileSize = info.size();
+ option.overwriteExisting = !failIfExists;
+
+ if (!_sendData(socket, (char*) &option, sizeof(option))) {
+ END_ERROR(socket, "Could not send options...");
+ }
+
+ if (!_checkResult(socket)) {
+ END_ERROR(socket, "Server did not accept configuration");
+ }
+
+ int bytesWritten = 0;
+ const int bufferSize = 1024;
+ QByteArray data;
+ while (bytesWritten < option.fileSize) {
+ data = localFile.read(bufferSize);
+ bytesWritten += data.size();
+#ifdef Q_OS_WIN
+ wprintf( L"%s -> %s (%d / %d) %d %%\r", localSource.utf16() , deviceDest.utf16(),
+ bytesWritten , option.fileSize, (100*bytesWritten)/option.fileSize );
+#endif
+ if (!_sendData(socket, data.constData(), data.size())) {
+ END_ERROR(socket, "Error during file transfer");
+ }
+ if (!_checkResult(socket)) {
+ END_ERROR(socket, "Got some strange result");
+ }
+ }
+#ifdef Q_OS_WIN
+ wprintf( L"\n"); // We should jump to next line...
+#endif
+ if (bytesWritten != option.fileSize) {
+ END_ERROR(socket, "Did not send sufficient data");
+ }
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive)
+{
+ QTcpSocket* socket = NULL;
+ QFileInfo info(localSource);
+ if (!info.exists() || !info.isDir()) {
+ END_ERROR(socket, "Input directory invalid");
+ }
+
+ createDirectory(deviceDest, true);
+ QDir dir(localSource);
+ QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
+ foreach(QFileInfo item, list) {
+ QString targetName = deviceDest + QLatin1String("\\") + item.fileName();
+ if (item.isDir()) {
+ if (recursive) {
+ if (!copyDirectoryToDevice(item.absoluteFilePath() , targetName, recursive))
+ return false;
+ }
+ } else {
+ if (!copyFileToDevice(item.absoluteFilePath(), targetName))
+ return false;
+ }
+ }
+ return true;
+}
+
+bool QtCesterConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists)
+{
+ QFile targetFile(localDest);
+ QTcpSocket* socket = 0;
+ if (targetFile.exists() && failIfExists) {
+ END_ERROR(socket, "Local file not supposed to be overwritten");
+ }
+
+ if (!targetFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ END_ERROR(socket, "Could not open local file for writing");
+ }
+
+ if (!_initCommand(socket, COMMAND_READ_FILE)) {
+ END_ERROR(socket, "Could not establish connection");
+ }
+
+ ReadFileOptions option;
+ strcpy(option.fileName, qPrintable(deviceSource));
+ if (!_sendData(socket, (char*) &option, sizeof(option))) {
+ END_ERROR(socket, "Could not send options");
+ }
+
+ QByteArray data;
+ if (!_receiveData(socket, data)) {
+ END_ERROR(socket, "Did not receive any data");
+ }
+
+ ReadFileReply* reply = (ReadFileReply*) data.data();
+ if (!reply->fileValid) {
+ END_ERROR(socket, "Requested file invalid");
+ }
+
+ int fileSize = reply->fileSize;
+ int currentSize = 0;
+ // ### TODO: make a little bit more error-prone
+ do {
+ _sendData(socket, COMMAND_SUCCESS, strlen(COMMAND_SUCCESS));
+ _receiveData(socket, data);
+ currentSize += data.size();
+ targetFile.write(data);
+ } while(currentSize < fileSize);
+
+ _freeSocket(socket);
+ targetFile.close();
+ return true;
+}
+
+bool QtCesterConnection::copyDirectoryFromDevice(const QString& /*deviceSource*/
+ , const QString& /*localDest*/
+ , bool /*recursive*/)
+{
+ qDebug() << "To be implemented!! Should not be needed for autotest system";
+ exit(-1);
+ return false;
+}
+
+bool QtCesterConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists)
+{
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_COPY_FILE)) {
+ END_ERROR(socket, "Could not establish connection for copy");
+ }
+
+ CopyFileOptions option;
+ strcpy(option.from, qPrintable(srcFile));
+ strcpy(option.to, qPrintable(destFile));
+ option.overwriteExisting = !failIfExists;
+ if (!_sendData(socket, (char*) &option, sizeof(option))) {
+ END_ERROR(socket, "Could not send copy options");
+ }
+
+ if (!_checkResult(socket)) {
+ END_ERROR(socket, "Copy failed");
+ }
+
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory,
+ bool recursive)
+{
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_COPY_DIRECTORY)) {
+ END_ERROR(socket, "Could not establish connection for dir copy");
+ }
+
+ CopyDirectoryOptions option;
+ strcpy(option.from, qPrintable(srcDirectory));
+ strcpy(option.to, qPrintable(destDirectory));
+ option.recursive = recursive;
+ if (!_sendData(socket, (char*) &option, sizeof(option))) {
+ END_ERROR(socket, "Could not send dir copy options");
+ }
+
+ if (!_checkResult(socket)) {
+ END_ERROR(socket, "Dir Copy failed");
+ }
+
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::deleteFile(const QString &fileName)
+{
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_DELETE_FILE)) {
+ END_ERROR(socket, "Could not establish connection for file deletion");
+ }
+
+ DeleteFileOptions option;
+ strcpy(option.fileName, qPrintable(fileName));
+ if (!_sendData(socket, (char*) &option, sizeof(option))) {
+ END_ERROR(socket, "Could not send file options");
+ }
+
+ if (!_checkResult(socket)) {
+ //END_ERROR(socket, "File Deletion failed");
+ // This is actually not an error so ignore it.
+ }
+
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists)
+{
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_DELETE_DIRECTORY)) {
+ END_ERROR(socket, "Could not establish connection for dir deletion");
+ }
+
+ DeleteDirectoryOptions option;
+ strcpy(option.dirName, qPrintable(directory));
+ option.recursive = recursive;
+ option.failIfContentExists = failIfContentExists;
+ if (!_sendData(socket, (char*) &option, sizeof(option))) {
+ END_ERROR(socket, "Could not send dir options");
+ }
+
+ if (!_checkResult(socket)) {
+ // we do not write an error as this will fail a lot on recursive.
+ END_ERROR(socket, 0);
+ }
+
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::execute(QString program,
+ QString arguments,
+ int timeout,
+ int *returnValue)
+{
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_EXECUTE)) {
+ END_ERROR(socket, "Could not establish connection for dir deletion");
+ }
+
+ ExecuteOptions options;
+ strcpy(options.appName, qPrintable(program));
+ QStringList argList = arguments.split(QLatin1Char(' '));
+ options.argumentsCount = qMin(argList.size(), MAX_ARGUMENTS);
+ options.waitForFinished = true;
+ options.timeout = timeout;
+ if (!_sendData(socket, (char*) &options, sizeof(options))) {
+ END_ERROR(socket, "Could not send dir options");
+ }
+ if (!_checkResult(socket)) {
+ END_ERROR(socket, "Did not receive an answer");
+ }
+
+ for (int i=0; i < options.argumentsCount; ++i) {
+ char someData[MAX_NAME_LENGTH];
+ strcpy(someData, qPrintable(argList[i]));
+ if (!_sendData(socket, someData, MAX_NAME_LENGTH)) {
+ END_ERROR(socket, "Could not send argument");
+ }
+ if (!_checkResult(socket)) {
+ END_ERROR(socket, "Failure in argument send");
+ }
+ }
+
+ // trigger the startup
+ if (!_sendData(socket, COMMAND_SUCCESS, strlen(COMMAND_SUCCESS))) {
+ END_ERROR(socket, "Could not trigger startup");
+ }
+
+ const int waitTime = 60 * 60 * 1000;
+ if (!socket->waitForReadyRead(waitTime)) {
+ END_ERROR(socket, "Process timed out");
+ }
+
+ QByteArray result = socket->readAll();
+ if (result != COMMAND_SUCCESS) {
+ if (returnValue)
+ *returnValue = -1; // just some at least
+ END_ERROR(socket, "Application did not start or returned error");
+ }
+
+ if (returnValue)
+ *returnValue = 0;
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::createDirectory(const QString &path, bool deleteBefore)
+{
+ if (deleteBefore)
+ deleteDirectory(path, true, true);
+
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_CREATE_DIRECTORY)) {
+ END_ERROR(socket, "Could not establish connection for dir creation");
+ }
+
+ CreateDirectoryOptions option;
+ strcpy(option.dirName, qPrintable(path));
+ option.recursively = true;
+ if (!_sendData(socket, (char*) &option, sizeof(option))) {
+ END_ERROR(socket, "Could not send dir options");
+ }
+
+ if (!_checkResult(socket)) {
+ END_ERROR(socket, "Dir creation failed");
+ }
+
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::timeStampForLocalFileTime(FILETIME* fTime) const
+{
+ if (!fTime)
+ return false;
+
+ FILETIME copyTime = *fTime;
+ LocalFileTimeToFileTime(&copyTime, &copyTime);
+
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_TIME_STAMP)) {
+ END_ERROR(socket, "Could not establish time stamp connection");
+ }
+
+ if (!_sendData(socket, (char*) &copyTime, sizeof(copyTime))) {
+ END_ERROR(socket, "Could not send stamp time");
+ }
+
+ QByteArray data;
+ if (!_receiveData(socket, data)) {
+ END_ERROR(socket, "Did not receive time stamp or connection interrupted");
+ }
+
+ copyTime = *((FILETIME*)data.data());
+ if (copyTime.dwLowDateTime == -1 && copyTime.dwHighDateTime == -1) {
+ END_ERROR(socket, "remote Time stamp failed!");
+ }
+
+ *fTime = copyTime;
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const
+{
+ if (!deviceCreationTime)
+ return false;
+
+ QTcpSocket* socket = 0;
+ if (!_initCommand(socket, COMMAND_FILE_TIME)) {
+ END_ERROR(socket, "Could not establish connection for file time access");
+ }
+
+ FileTimeOptions option;
+ strcpy(option.fileName, qPrintable(fileName));
+ if (!_sendData(socket, (char*) &option, sizeof(option))) {
+ END_ERROR(socket, "Could not send file time name");
+ }
+
+ QByteArray data;
+ if (!_receiveData(socket, data)) {
+ END_ERROR(socket, "File Time request failed");
+ }
+
+ FILETIME* resultTime = (FILETIME*) data.data();
+ if (resultTime->dwLowDateTime == -1 && resultTime->dwHighDateTime == -1) {
+ END_ERROR(socket, 0);
+ debugOutput("Could not access file time", 0);
+ }
+
+ *deviceCreationTime = *resultTime;
+ _freeSocket(socket);
+ return true;
+}
+
+bool QtCesterConnection::_createSocket(QTcpSocket*& result) const
+{
+ QTcpSocket* sock = new QTcpSocket();
+ QByteArray ipAddress = qgetenv("DEVICE_IP");
+ if (ipAddress.isEmpty()) {
+ qWarning("Error: You need to have DEVICE_IP set");
+ exit(0);
+ }
+ sock->connectToHost(QHostAddress(QString(ipAddress)), 12145);
+
+ if (!sock->waitForConnected()) {
+ qDebug() << "connection timeout...";
+ result = NULL;
+ return false;
+ }
+ result = sock;
+ return true;
+}
+
+void QtCesterConnection::_freeSocket(QTcpSocket*& sock) const
+{
+ if (!sock)
+ return;
+ if (sock->state() == QAbstractSocket::ConnectedState) {
+ sock->disconnectFromHost();
+ // seems like no need to wait
+ //sock->waitForDisconnected();
+ }
+ delete sock;
+ sock = NULL;
+#ifdef Q_OS_WIN
+ Sleep(100);
+#endif
+}
+
+bool QtCesterConnection::_initCommand(QTcpSocket*& sock, const char* command) const
+{
+ QTcpSocket* socket = NULL;
+ if (!_createSocket(socket)) {
+ END_ERROR(socket, "Could not connect to server");
+ }
+
+ if (!_sendData(socket, command, strlen(command)) ||
+ !_checkResult(socket)) {
+ END_ERROR(socket, "Cound not send command");
+ }
+ sock = socket;
+ return true;
+}
+
+bool QtCesterConnection::_sendData(QTcpSocket*& sock, const char* data, int dataSize) const
+{
+ int amount = sock->write(data, dataSize);
+ if (amount != dataSize) {
+ fprintf(stderr, "*******COULD NOT SEND ENOUGH DATA*************\n");
+ }
+ return sock->waitForBytesWritten();
+}
+
+bool QtCesterConnection::_receiveData(QTcpSocket*& sock, QByteArray& data) const
+{
+ if (!sock->waitForReadyRead()) {
+ qDebug() << "did not receive any data";
+ return false;
+ }
+ data = sock->readAll();
+ return true;
+}
+
+bool QtCesterConnection::_checkResult(QTcpSocket*& sock) const
+{
+ QByteArray response;
+ if (!_receiveData(sock, response) || response != COMMAND_SUCCESS)
+ return false;
+ return true;
+}
+
diff --git a/src/qtestlib/wince/cetcpsync/qtcesterconnection.h b/src/qtestlib/wince/cetcpsync/qtcesterconnection.h
new file mode 100644
index 000000000..c33935d90
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsync/qtcesterconnection.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef ACTIVESYNC_REMOTECONNECTION_H
+#define ACTIVESYNC_REMOTECONNECTION_H
+
+#include "remoteconnection.h"
+
+class QTcpSocket;
+
+class QtCesterConnection : public AbstractRemoteConnection
+{
+public:
+ QtCesterConnection();
+ virtual ~QtCesterConnection();
+
+ bool connect(QVariantList &list = QVariantList());
+ void disconnect();
+ bool isConnected() const;
+
+ // These functions are designed for transfer between desktop and device
+ // Caution: deviceDest path has to be device specific (eg. no drive letters for CE)
+ bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false);
+ bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true);
+ bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false);
+ bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true);
+
+ bool timeStampForLocalFileTime(FILETIME*) const;
+ bool fileCreationTime(const QString &fileName, FILETIME*) const;
+
+ // These functions only work on files existing on the device
+ bool copyFile(const QString&, const QString&, bool failIfExists = false);
+ bool copyDirectory(const QString&, const QString&, bool recursive = true);
+ bool deleteFile(const QString&);
+ bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false);
+ bool createDirectory(const QString&, bool deleteBefore=false);
+
+ bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL);
+private:
+ bool _createSocket(QTcpSocket*&) const;
+ void _freeSocket(QTcpSocket*&) const;
+ bool _initCommand(QTcpSocket*&, const char*) const;
+ bool _sendData(QTcpSocket*&, const char* data, int dataSize) const;
+ bool _receiveData(QTcpSocket*&, QByteArray&) const;
+ bool _checkResult(QTcpSocket*&) const;
+ bool connected;
+};
+
+#endif
diff --git a/src/qtestlib/wince/cetcpsync/remoteconnection.cpp b/src/qtestlib/wince/cetcpsync/remoteconnection.cpp
new file mode 100644
index 000000000..01a37201e
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsync/remoteconnection.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "remoteconnection.h"
+
+AbstractRemoteConnection::AbstractRemoteConnection()
+{
+}
+
+AbstractRemoteConnection::~AbstractRemoteConnection()
+{
+}
+
+// Slow but should be ok...
+bool AbstractRemoteConnection::moveFile(const QString &src, const QString &dest, bool FailIfExists)
+{
+ bool result = copyFile(src, dest, FailIfExists);
+ deleteFile(src);
+ return result;
+}
+
+// Slow but should be ok...
+bool AbstractRemoteConnection::moveDirectory(const QString &src, const QString &dest, bool recursive)
+{
+ bool result = copyDirectory(src, dest, true);
+ deleteDirectory(src, recursive);
+ return result;
+}
diff --git a/src/qtestlib/wince/cetcpsync/remoteconnection.h b/src/qtestlib/wince/cetcpsync/remoteconnection.h
new file mode 100644
index 000000000..bf0fcce17
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsync/remoteconnection.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef REMOTECONNECTION_H
+#define REMOTECONNECTION_H
+
+#include <QtCore/QString>
+#include <QtCore/QVariant>
+#include <windows.h>
+class AbstractRemoteConnection
+{
+public:
+ AbstractRemoteConnection();
+ virtual ~AbstractRemoteConnection();
+
+ virtual bool connect(QVariantList&) = 0;
+ virtual void disconnect() = 0;
+ virtual bool isConnected() const = 0;
+
+ // These functions are designed for transfer between desktop and device
+ // Caution: deviceDest path has to be device specific (eg. no drive letters for CE)
+ virtual bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false) = 0;
+ virtual bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true) = 0;
+ virtual bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false) = 0;
+ virtual bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true) = 0;
+
+ // For "intelligent deployment" we need to investigate on filetimes on the device
+ virtual bool timeStampForLocalFileTime(FILETIME*) const = 0;
+ virtual bool fileCreationTime(const QString &fileName, FILETIME*) const = 0;
+
+ // These functions only work on files existing on the device
+ virtual bool copyFile(const QString&, const QString&, bool failIfExists = false) = 0;
+ virtual bool copyDirectory(const QString&, const QString&, bool recursive = true) = 0;
+ virtual bool deleteFile(const QString&) = 0;
+ virtual bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false) = 0;
+ bool moveFile(const QString&, const QString&, bool FailIfExists = false);
+ bool moveDirectory(const QString&, const QString&, bool recursive = true);
+
+ virtual bool createDirectory(const QString&, bool deleteBefore=false) = 0;
+
+ virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0;
+};
+
+#endif
diff --git a/src/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro b/src/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro
new file mode 100644
index 000000000..bd01d2dab
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+TARGET = cetcpsyncsvr
+DEPENDPATH += .
+QT -= gui
+QT += network
+
+CONFIG += console
+
+HEADERS += \
+ connectionmanager.h \
+ commands.h \
+ transfer_global.h
+
+SOURCES += \
+ connectionmanager.cpp \
+ commands.cpp \
+ main.cpp
diff --git a/src/qtestlib/wince/cetcpsyncserver/commands.cpp b/src/qtestlib/wince/cetcpsyncserver/commands.cpp
new file mode 100644
index 000000000..aaf5431d5
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsyncserver/commands.cpp
@@ -0,0 +1,686 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "commands.h"
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QProcess>
+
+#ifdef Q_OS_WINCE
+#include <windows.h>
+#endif
+
+/////////////////////////////////////////////////////
+// Abstract Command Implementation //
+/////////////////////////////////////////////////////
+AbstractCommand::AbstractCommand()
+: m_socket(0)
+{
+}
+
+AbstractCommand::~AbstractCommand()
+{
+}
+
+void AbstractCommand::reportSuccess()
+{
+ m_socket->write(COMMAND_SUCCESS, strlen(COMMAND_SUCCESS));
+ m_socket->waitForBytesWritten();
+}
+
+void AbstractCommand::reportError()
+{
+ m_socket->write(COMMAND_ERROR, strlen(COMMAND_ERROR));
+ m_socket->waitForBytesWritten();
+}
+
+void AbstractCommand::dataReceived(QByteArray&)
+{
+ debugOutput(1, "AbstractCommand::dataReceived NOT SUPPOSED TO BE HERE");
+}
+
+void AbstractCommand::commandFinished()
+{
+ debugOutput(1, "AbstractCommand::commandFinished()NOT SUPPOSED TO BE HERE");
+}
+
+void AbstractCommand::setSocket(QTcpSocket* socket)
+{
+ debugOutput(0, "AbstractCommand::setSocket()");
+ Q_ASSERT(socket);
+ m_socket = socket;
+ connect(m_socket, SIGNAL(readyRead()), this, SLOT(_readData()));
+ reportSuccess();
+}
+
+QTcpSocket* AbstractCommand::socket()
+{
+ return m_socket;
+}
+
+void AbstractCommand::_readData()
+{
+ QByteArray arr = m_socket->readAll();
+ dataReceived(arr);
+}
+
+void AbstractCommand::_disconnect()
+{
+}
+
+/////////////////////////////////////////////////////
+// Create File Command Implementation //
+/////////////////////////////////////////////////////
+CreateFileCommand::CreateFileCommand()
+: m_dataCount(0)
+{
+ debugOutput(0, "CreateFileCommand::CreateFileCommand");
+ m_options.fileSize= -1;
+}
+
+CreateFileCommand::~CreateFileCommand()
+{
+ debugOutput(0, "CreateFileCommand::~CreateFileCommand");
+ if (m_file.isOpen()) {
+ fprintf(stderr, "****************FILE IS STILL OPENED AND HAVENT FINISHED WRITING**********************\n");
+ fprintf(stderr, "Current: %d Expected: %d\n", m_dataCount , m_options.fileSize);
+ m_file.close();
+ }
+}
+
+void CreateFileCommand::dataReceived(QByteArray &data)
+{
+ bool successful = true;
+ // If we haven't received the options yet
+ if (m_options.fileSize == -1) {
+ CreateFileOptions* opt = (CreateFileOptions*) data.data();
+ memcpy(&m_options , opt , sizeof(CreateFileOptions));
+
+ if (QFileInfo(QString::fromLatin1(m_options.fileName)).exists()) {
+ if (m_options.overwriteExisting) {
+#ifdef Q_OS_WINCE
+ SetFileAttributes(QFileInfo(m_options.fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL);
+#endif
+ QFile::remove(m_options.fileName);
+ } else
+ successful = false;
+ }
+ m_file.setFileName(QString::fromLatin1(m_options.fileName));
+ if (!m_file.open(QIODevice::WriteOnly))
+ successful = false;
+ else
+ debugOutput(3, QString::fromLatin1("Creating file: %1").arg(m_options.fileName));
+ } else { // write buffer on disc
+ if (!m_file.isOpen())
+ return;
+ m_file.write(data);
+ m_dataCount += data.size();
+ if (m_dataCount >= m_options.fileSize) {
+ // We do not care about more data than announced
+ m_file.close();
+ }
+ }
+
+ if (successful)
+ reportSuccess();
+ else
+ reportError();
+}
+
+void CreateFileCommand::commandFinished()
+{
+ debugOutput(0, "CreateFileCommand::commandFinished");
+#ifdef Q_OS_WIN
+ // We need to set the file attributes for intelligent time comparisons
+ QString tmpFile = QString::fromLatin1(m_options.fileName);
+ HANDLE handle = CreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+ if (handle != INVALID_HANDLE_VALUE) {
+ SetFileTime(handle, &(m_options.fileTime), NULL, NULL);
+ CloseHandle(handle);
+ }
+ SetFileAttributes(tmpFile.utf16(), m_options.fileAttributes);
+#endif
+}
+
+/////////////////////////////////////////////////////
+// Create Directory Command Implementation //
+/////////////////////////////////////////////////////
+CreateDirectoryCommand::CreateDirectoryCommand()
+ : AbstractCommand()
+{
+ debugOutput(0, "CreateDirectoryCommand::CreateDirectoryCommand");
+}
+
+CreateDirectoryCommand::~CreateDirectoryCommand()
+{
+ debugOutput(0, "CreateDirectoryCommand::~CreateDirectoryCommand()");
+}
+
+void CreateDirectoryCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "CreateDirectoryCommand::dataReceived()");
+ CreateDirectoryOptions* options = (CreateDirectoryOptions*) data.data();
+ debugOutput(3, QString::fromLatin1("Creating directory: %1").arg(options->dirName));
+ bool success = true;
+ QDir dir;
+ if (options->recursively)
+ success = dir.mkpath(options->dirName);
+ else
+ success = dir.mkdir(options->dirName);
+
+ if (success)
+ reportSuccess();
+ else
+ reportError();
+}
+
+void CreateDirectoryCommand::commandFinished()
+{
+ debugOutput(0, "CreateDirectoryCommand::commandFinished()");
+}
+
+/////////////////////////////////////////////////////
+// Copy File Command Implementation //
+/////////////////////////////////////////////////////
+CopyFileCommand::CopyFileCommand()
+ : AbstractCommand()
+{
+ debugOutput(0, "CopyFileCommand::CopyFileCommand()");
+}
+
+CopyFileCommand::~CopyFileCommand()
+{
+ debugOutput(0, "CopyFileCommand::~CopyFileCommand()");
+}
+
+void CopyFileCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "CopyFileCommand::dataReceived()");
+ CopyFileOptions* options = (CopyFileOptions*) data.data();
+ debugOutput(3, QString::fromLatin1("Copy File: %1 -> %2").arg(options->from).arg(options->to));
+ bool success = true;
+ if (QFileInfo(options->to).exists()) {
+ if (options->overwriteExisting)
+ QFile::remove(options->to);
+ else
+ success = false;
+ }
+ if (success)
+ if (!QFile::copy(options->from , options->to))
+ success = false;
+
+ if (success)
+ reportSuccess();
+ else
+ reportError();
+}
+
+void CopyFileCommand::commandFinished()
+{
+ debugOutput(0, "CopyFileCommand::commandFinished()");
+}
+
+/////////////////////////////////////////////////////
+// Copy Directory Command Implementation //
+/////////////////////////////////////////////////////
+CopyDirectoryCommand::CopyDirectoryCommand()
+ : AbstractCommand()
+{
+ debugOutput(0, "CopyDirectoryCommand::CopyDirectoryCommand()");
+}
+
+CopyDirectoryCommand::~CopyDirectoryCommand()
+{
+ debugOutput(0, "CopyDirectoryCommand::~CopyDirectoryCommand()");
+}
+
+void CopyDirectoryCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "CopyDirectoryCommand::dataReceived()");
+ CopyDirectoryOptions* options = (CopyDirectoryOptions*) data.data();
+ debugOutput(3, QString::fromLatin1("Copy Directory: %1 %2").arg(options->from).arg(options->to));
+ if (copyDir(QLatin1String(options->from) , QLatin1String(options->to) , options->recursive))
+ reportSuccess();
+ else
+ reportError();
+}
+
+void CopyDirectoryCommand::commandFinished()
+{
+ debugOutput(0, "CopyDirectoryCommand::commandFinished()");
+}
+
+bool CopyDirectoryCommand::copyDir(const QString &from, const QString &to, bool recursive)
+{
+ QDir().mkpath(to);
+ QDir sourceDir(from);
+ QDir destDir(to);
+ QStringList entries = sourceDir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
+ foreach (QString item , entries) {
+ QString itemFrom = sourceDir.absoluteFilePath(item);
+ QString itemTo = destDir.absoluteFilePath(item);
+ if (QFileInfo(item).isDir()) {
+ if (recursive && !copyDir(itemFrom, itemTo, recursive))
+ return false;
+ } else {
+ if (!QFile::copy(itemFrom, itemTo))
+ return false;
+ }
+ }
+ return true;
+}
+
+/////////////////////////////////////////////////////
+// Delete File Command Implementation //
+/////////////////////////////////////////////////////
+DeleteFileCommand::DeleteFileCommand()
+ : AbstractCommand()
+{
+ debugOutput(0, "DeleteFileCommand::DeleteFileCommand()");
+}
+
+DeleteFileCommand::~DeleteFileCommand()
+{
+ debugOutput(0, "DeleteFileCommand::~DeleteFileCommand()");
+}
+
+void DeleteFileCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "DeleteFileCommand::dataReceived()");
+ DeleteFileOptions* options = (DeleteFileOptions*) data.data();
+ debugOutput(3, QString::fromLatin1("Delete File: %1").arg(options->fileName));
+ bool success = true;
+ QFile file(options->fileName);
+ if (file.exists()) {
+#ifdef Q_OS_WINCE
+ SetFileAttributes(QFileInfo(options->fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL);
+#endif
+ success = file.remove();
+ } else
+ success = false;
+
+ if (success)
+ reportSuccess();
+ else
+ reportError();
+}
+
+void DeleteFileCommand::commandFinished()
+{
+ debugOutput(0, "DeleteFileCommand::commandFinished()");
+}
+
+/////////////////////////////////////////////////////
+// Delete Directory Command Implementation //
+/////////////////////////////////////////////////////
+DeleteDirectoryCommand::DeleteDirectoryCommand()
+ : AbstractCommand()
+{
+ debugOutput(0, "DeleteDirectoryCommand::DeleteDirectoryCommand()");
+}
+
+DeleteDirectoryCommand::~DeleteDirectoryCommand()
+{
+ debugOutput(0, "DeleteDirectoryCommand::~DeleteDirectoryCommand()");
+}
+
+void DeleteDirectoryCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "DeleteDirectoryCommand::dataReceived()");
+ DeleteDirectoryOptions* options = (DeleteDirectoryOptions*) data.data();
+ debugOutput(3, QString::fromLatin1("Delete directory: %1").arg(options->dirName));
+ if (deleteDirectory(QLatin1String(options->dirName), options->recursive, options->failIfContentExists))
+ reportSuccess();
+ else
+ reportError();
+}
+
+void DeleteDirectoryCommand::commandFinished()
+{
+ debugOutput(0, "DeleteDirectoryCommand::commandFinished()");
+}
+
+bool DeleteDirectoryCommand::deleteDirectory(const QString &dirName, bool recursive, bool failIfContentExists)
+{
+ QDir dir(dirName);
+ if (!dir.exists())
+ return false;
+
+ QStringList itemList = dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
+ if (itemList.size() > 0 && failIfContentExists)
+ return false;
+
+ foreach (QString item, itemList) {
+ QString itemName = dir.absoluteFilePath(item);
+ if (QFileInfo(itemName).isDir()) {
+ if (recursive && !deleteDirectory(itemName, recursive, failIfContentExists))
+ return false;
+ } else {
+ if (!dir.remove(item))
+ return false;
+ }
+ }
+ QString lastName = dir.dirName();
+ dir.cdUp();
+ dir.rmpath(lastName);
+ return true;
+}
+
+/////////////////////////////////////////////////////
+// Execute Command Implementation //
+/////////////////////////////////////////////////////
+ExecuteCommand::ExecuteCommand()
+ : AbstractCommand()
+ , m_argumentCount(0)
+ , m_timeout(-1)
+{
+ debugOutput(0, "ExecuteCommand::ExecuteCommand()");
+}
+
+ExecuteCommand::~ExecuteCommand()
+{
+ debugOutput(0, "ExecuteCommand::~ExecuteCommand()");
+}
+
+void ExecuteCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "ExecuteCommand::dataReceived()");
+
+ if (m_argumentCount == 0) {
+ ExecuteOptions* options = (ExecuteOptions*) data.data();
+ if (!QFileInfo(options->appName).exists()) {
+ debugOutput(1, "Error execute: application does not exist");
+ reportError();
+ return;
+ }
+
+ m_program = QLatin1String(options->appName);
+ m_argumentCount = options->argumentsCount;
+ m_waitFinished = options->waitForFinished;
+ m_timeout = options->timeout;
+ if (m_argumentCount == 0)
+ m_argumentCount = -1; // to trigger startup on next receive
+ reportSuccess();
+ } else if (m_arguments.size() < m_argumentCount) {
+ m_arguments += data;
+ reportSuccess();
+ } else { // do the execution
+ if (data == COMMAND_SUCCESS)
+ _doExecute();
+ }
+}
+
+void ExecuteCommand::_doExecute()
+{
+ debugOutput(0, "ExecuteCommand::_doExecute()");
+ debugOutput(3, QString::fromLatin1("Execute: %1 %2").arg(m_program).arg(m_arguments.join(" ")));
+ if (m_waitFinished) {
+ QProcess process;
+ process.start(m_program, m_arguments);
+ if (process.waitForFinished(m_timeout) == false || process.exitCode() < 0)
+ reportError();
+ else
+ reportSuccess();
+ } else {
+ if (QProcess::startDetached(m_program, m_arguments))
+ reportSuccess();
+ else
+ reportError();
+ }
+}
+void ExecuteCommand::commandFinished()
+{
+ debugOutput(0,"ExecuteCommand::commandFinished()");
+}
+
+/////////////////////////////////////////////////////
+// Read File Implementation //
+/////////////////////////////////////////////////////
+ReadFileCommand::ReadFileCommand()
+ : AbstractCommand()
+ , m_currentPos(0)
+{
+ debugOutput(0, "ReadFileCommand::ReadFileCommand()");
+ m_fileName.clear();
+}
+
+ReadFileCommand::~ReadFileCommand()
+{
+ debugOutput(0, "ReadFileCommand::~ReadFileCommand()");
+ if (m_file.isOpen())
+ m_file.close();
+}
+
+void ReadFileCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "ReadFileCommand::dataReceived()");
+ if (m_fileName.isEmpty()) {
+ ReadFileOptions* option = (ReadFileOptions*) data.data();
+ m_fileName = QLatin1String(option->fileName);
+ QFileInfo info(m_fileName);
+ m_file.setFileName(m_fileName);
+ ReadFileReply reply;
+ if (!info.exists() || !info.isFile() || !m_file.open(QIODevice::ReadOnly))
+ reply.fileValid = false;
+ else
+ reply.fileValid = true;
+ reply.fileSize = info.size();
+ m_fileSize = reply.fileSize;
+ socket()->write((char*) &reply, sizeof(reply));
+ debugOutput(3, QString::fromLatin1("Reading file: %1").arg(m_fileName));
+ } else {
+ QTcpSocket* sock = socket(); // design failure???
+ if (data != COMMAND_SUCCESS || m_currentPos >= m_fileSize) {
+ sock->disconnectFromHost();
+ return;
+ }
+ const int bufferSize = 1024;
+ QByteArray buffer = m_file.read(bufferSize);
+ m_currentPos += buffer.size();
+ sock->write(buffer);
+ sock->waitForBytesWritten();
+ }
+}
+
+void ReadFileCommand::commandFinished()
+{
+ debugOutput(0, "ReadFileCommand::commandFinished()");
+}
+
+/////////////////////////////////////////////////////
+// Read Directory Implementation //
+/////////////////////////////////////////////////////
+ReadDirectoryCommand::ReadDirectoryCommand()
+ : AbstractCommand()
+ , m_iterator(0)
+{
+ debugOutput(0, "ReadDirectoryCommand::ReadDirectoryCommand");
+ m_dirName.clear();
+}
+
+ReadDirectoryCommand::~ReadDirectoryCommand()
+{
+ debugOutput(0, "ReadDirectoryCommand::~ReadDirectoryCommand()");
+ delete m_iterator;
+}
+
+void ReadDirectoryCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "ReadDirectoryCommand::dataReceived()");
+ QTcpSocket* sock = socket();
+ if (m_dirName.isEmpty()) {
+ ReadDirectoryOptions* option = (ReadDirectoryOptions*) data.data();
+ QFileInfo info(QLatin1String(option->dirName));
+ debugOutput(3, QString::fromLatin1("Reading Directory entries: %1").arg(option->dirName));
+ ReadDirectoryReply reply;
+ if (!info.exists() || !info.isDir()) {
+ reply.itemCount = -1;
+ reply.entryValid = false;
+ } else {
+ m_dirName = QLatin1String(option->dirName);
+ m_dir.setPath(m_dirName);
+ m_iterator = new QDirIterator(m_dir);
+ reply.itemCount = m_dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot).size();
+ reply.entryValid = true;
+ }
+ sock->write((char*) &reply, sizeof(reply));
+ sock->waitForBytesWritten();
+ } else {
+ if (data != COMMAND_SUCCESS) {
+ qDebug() << "Something went wrong in the meantime";
+ return;
+ }
+ ReadDirectoryItem reply;
+ if (m_iterator->hasNext()) {
+ m_iterator->next();
+ QFileInfo info = m_iterator->fileInfo();
+ strcpy(reply.name, qPrintable(info.absoluteFilePath()));
+ reply.isDirectory = info.isDir();
+ if (!reply.isDirectory)
+ reply.size = info.size();
+ }
+ reply.hasMore = m_iterator->hasNext();
+ sock->write((char*) &reply, sizeof(reply));
+ sock->waitForBytesWritten();
+ }
+}
+
+void ReadDirectoryCommand::commandFinished()
+{
+ debugOutput(0, "ReadDirectoryCommand::commandFinished()");
+}
+
+/////////////////////////////////////////////////////
+// File Time Implementation //
+/////////////////////////////////////////////////////
+FileTimeCommand::FileTimeCommand()
+ : AbstractCommand()
+{
+ debugOutput(0, "FileTimeCommand::FileTimeCommand()");
+}
+
+FileTimeCommand::~FileTimeCommand()
+{
+ debugOutput(0, "FileTimeCommand::~FileTimeCommand()");
+}
+
+void FileTimeCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "FileTimeCommand::dataReceived()");
+ FileTimeOptions* option = (FileTimeOptions*) data.data();
+
+ FILETIME resultTime;
+ resultTime.dwLowDateTime = -1;
+ resultTime.dwHighDateTime = -1;
+
+#ifdef Q_OS_WIN
+ QString fileName = QLatin1String(option->fileName);
+ HANDLE deviceHandle = CreateFile(fileName.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ debugOutput(3, QString::fromLatin1("Asking FileTime: %1").arg(fileName));
+ if (deviceHandle != INVALID_HANDLE_VALUE) {
+ FILETIME deviceCreationTime;
+ if (GetFileTime(deviceHandle, &deviceCreationTime, NULL, NULL)) {
+ resultTime = deviceCreationTime;
+ }
+ CloseHandle(deviceHandle);
+ }
+#endif
+ QTcpSocket* sock = socket();
+ sock->write((char*) &resultTime, sizeof(resultTime));
+ sock->waitForBytesWritten();
+}
+
+void FileTimeCommand::commandFinished()
+{
+ debugOutput(0, "FileTimeCommand::commandFinished()");
+}
+
+/////////////////////////////////////////////////////
+// Time Stamp Implementation //
+/////////////////////////////////////////////////////
+TimeStampCommand::TimeStampCommand()
+ : AbstractCommand()
+{
+ debugOutput(0, "TimeStampCommand::TimeStampCommand()");
+}
+
+TimeStampCommand::~TimeStampCommand()
+{
+ debugOutput(0, "TimeStampCommand::~TimeStampCommand()");
+}
+
+void TimeStampCommand::dataReceived(QByteArray &data)
+{
+ debugOutput(0, "TimeStampCommand::dataReceived()");
+ FILETIME resultTime;
+ resultTime.dwLowDateTime = -1;
+ resultTime.dwHighDateTime = -1;
+
+#ifdef Q_OS_WIN
+ FILETIME stampTime = *((FILETIME*)data.data());
+
+ QString tmpFile = QString::fromLatin1("\\qt_tmp_ftime_convert");
+ HANDLE remoteHandle = CreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (remoteHandle != INVALID_HANDLE_VALUE) {
+ if (!SetFileTime(remoteHandle, &stampTime, NULL, NULL)) {
+ CloseHandle(remoteHandle);
+ } else {
+ CloseHandle(remoteHandle);
+ remoteHandle = CreateFile(tmpFile.utf16(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ if (remoteHandle != INVALID_HANDLE_VALUE) {
+ if (GetFileTime(remoteHandle, &stampTime, NULL, NULL))
+ resultTime = stampTime;
+ CloseHandle(remoteHandle);
+ DeleteFile(tmpFile.utf16());
+ }
+ }
+ }
+ debugOutput(3, QString::fromLatin1("Asking TimeStamp"));
+#endif
+ QTcpSocket* sock = socket();
+ sock->write((char*) &resultTime, sizeof(resultTime));
+ sock->waitForBytesWritten();
+}
+
+void TimeStampCommand::commandFinished()
+{
+ debugOutput(0, "TimeStampCommand::commandFinished()");
+}
diff --git a/src/qtestlib/wince/cetcpsyncserver/commands.h b/src/qtestlib/wince/cetcpsyncserver/commands.h
new file mode 100644
index 000000000..b880dcd1d
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsyncserver/commands.h
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef COMMANDS_INCL
+#define COMMANDS_INCL
+
+#include "transfer_global.h"
+
+#include <QtNetwork/QTcpSocket>
+#include <QtCore/QString>
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtCore/QDirIterator>
+#include <windows.h>
+
+// debug output
+#define DEBUG_LEVEL 2
+inline void debugOutput(int level, const char* text)
+{
+ if (level >= DEBUG_LEVEL)
+ qDebug() << text;
+}
+
+inline void debugOutput(int level, const QString &text)
+{
+ if (level >= DEBUG_LEVEL)
+ qDebug() << text;
+}
+// Basic abtract command class
+class AbstractCommand : public QObject
+{
+ Q_OBJECT
+public:
+ AbstractCommand();
+ virtual ~AbstractCommand();
+
+ void setSocket(QTcpSocket*);
+ QTcpSocket* socket();
+
+ void reportSuccess();
+ void reportError();
+
+public slots:
+ virtual void dataReceived(QByteArray&);
+ virtual void commandFinished();
+
+private slots:
+ void _readData();
+ void _disconnect();
+
+private:
+ QTcpSocket* m_socket;
+};
+
+// File Creation class
+class CreateFileCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ CreateFileCommand();
+ ~CreateFileCommand();
+
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+
+private:
+ CreateFileOptions m_options;
+ QFile m_file;
+ int m_dataCount;
+};
+
+inline AbstractCommand* instCreateFile() { return new CreateFileCommand(); }
+
+// Directory Creation class
+class CreateDirectoryCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ CreateDirectoryCommand();
+ ~CreateDirectoryCommand();
+
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+};
+inline AbstractCommand* instCreateDirectory() { return new CreateDirectoryCommand(); }
+
+// File copy class
+class CopyFileCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ CopyFileCommand();
+ ~CopyFileCommand();
+
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+};
+inline AbstractCommand* instCopyFile() { return new CopyFileCommand(); }
+
+// Copy directory class
+class CopyDirectoryCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ CopyDirectoryCommand();
+ ~CopyDirectoryCommand();
+
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+private:
+ bool copyDir(const QString &from, const QString &to, bool recursive);
+};
+inline AbstractCommand* instCopyDirectory() { return new CopyDirectoryCommand(); }
+
+// Delete File class
+class DeleteFileCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ DeleteFileCommand();
+ ~DeleteFileCommand();
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+};
+inline AbstractCommand* instDeleteFile() { return new DeleteFileCommand(); }
+
+// Delete Directory class
+class DeleteDirectoryCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ DeleteDirectoryCommand();
+ ~DeleteDirectoryCommand();
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+private:
+ bool deleteDirectory(const QString &dirName, bool recursive, bool failIfContentExists);
+};
+inline AbstractCommand* instDeleteDirectory() { return new DeleteDirectoryCommand(); }
+
+// Execute application class
+class ExecuteCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ ExecuteCommand();
+ ~ExecuteCommand();
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+private:
+ void _doExecute();
+ QString m_program;
+ QStringList m_arguments;
+ int m_argumentCount;
+ bool m_waitFinished;
+ int m_timeout;
+};
+inline AbstractCommand* instExecution() { return new ExecuteCommand(); }
+
+// Read File class
+class ReadFileCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ ReadFileCommand();
+ ~ReadFileCommand();
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+private:
+ QString m_fileName;
+ QFile m_file;
+ qint64 m_currentPos;
+ qint64 m_fileSize;
+};
+inline AbstractCommand* instReadFile() { return new ReadFileCommand(); }
+
+// Read Directory class
+class ReadDirectoryCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ ReadDirectoryCommand();
+ ~ReadDirectoryCommand();
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+private:
+ QString m_dirName;
+ QDir m_dir;
+ QDirIterator* m_iterator;
+};
+inline AbstractCommand* instReadDirectory() { return new ReadDirectoryCommand(); }
+
+// Read File Time class
+class FileTimeCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ FileTimeCommand();
+ ~FileTimeCommand();
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+};
+inline AbstractCommand* instFileTime() { return new FileTimeCommand(); }
+
+// Time stamp class
+class TimeStampCommand : public AbstractCommand
+{
+ Q_OBJECT
+public:
+ TimeStampCommand();
+ ~TimeStampCommand();
+public slots:
+ void dataReceived(QByteArray&);
+ void commandFinished();
+};
+inline AbstractCommand* instTimeStamp() { return new TimeStampCommand(); }
+
+// Access part
+typedef AbstractCommand* (*instantiator)();
+
+struct CommandInfo
+{
+ CommandInfo(const QString &name, instantiator func) : commandName(name) , commandFunc(func) { }
+ QString commandName;
+ instantiator commandFunc;
+};
+
+inline QList<CommandInfo> availableCommands()
+{
+ QList<CommandInfo> list;
+ list.append(CommandInfo(QLatin1String(COMMAND_CREATE_FILE), instCreateFile));
+ list.append(CommandInfo(QLatin1String(COMMAND_CREATE_DIRECTORY), instCreateDirectory));
+ list.append(CommandInfo(QLatin1String(COMMAND_COPY_FILE), instCopyFile));
+ list.append(CommandInfo(QLatin1String(COMMAND_COPY_DIRECTORY), instCopyDirectory));
+ list.append(CommandInfo(QLatin1String(COMMAND_DELETE_FILE), instDeleteFile));
+ list.append(CommandInfo(QLatin1String(COMMAND_DELETE_DIRECTORY), instDeleteDirectory));
+ list.append(CommandInfo(QLatin1String(COMMAND_EXECUTE), instExecution));
+ list.append(CommandInfo(QLatin1String(COMMAND_READ_FILE), instReadFile));
+ list.append(CommandInfo(QLatin1String(COMMAND_READ_DIRECTORY), instReadDirectory));
+ list.append(CommandInfo(QLatin1String(COMMAND_FILE_TIME), instFileTime));
+ list.append(CommandInfo(QLatin1String(COMMAND_TIME_STAMP), instTimeStamp));
+ return list;
+}
+
+#endif
diff --git a/src/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp b/src/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp
new file mode 100644
index 000000000..1d5600d1b
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "connectionmanager.h"
+#include "commands.h"
+#include <QtCore/QDebug>
+
+ConnectionManager::ConnectionManager()
+ : QObject()
+ , m_server(0)
+{
+ debugOutput(0, "ConnectionManager::ConnectionManager()");
+}
+
+ConnectionManager::~ConnectionManager()
+{
+ debugOutput(0, "ConnectionManager::~ConnectionManager()");
+ cleanUp();
+}
+
+bool ConnectionManager::init()
+{
+ debugOutput(0, "ConnectionManager::init()");
+ debugOutput(3, "Initializing server...");
+ cleanUp();
+ m_server = new QTcpServer(this);
+ connect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
+ bool result = m_server->listen(QHostAddress::Any, SERVER_PORT);
+ if (!result)
+ debugOutput(3, QString::fromLatin1(" Error: Server start failed:") + m_server->errorString());
+ debugOutput(3, " Waiting for action");
+ return result;
+}
+
+void ConnectionManager::cleanUp()
+{
+ debugOutput(0, "ConnectionManager::cleanUp()");
+
+ if (m_server) {
+ debugOutput(1, "Removing server instance...");
+ disconnect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
+ delete m_server;
+ m_server = 0;
+ }
+}
+
+void ConnectionManager::newConnection()
+{
+ debugOutput(0, "ConnectionManager::newConnection()");
+
+ QTcpSocket* connection = m_server->nextPendingConnection();
+ if (!connection) {
+ debugOutput(3, "Received connection has empty socket");
+ return;
+ }
+ debugOutput(0, QString::fromLatin1(" received a connection: %1").arg((int) connection));
+ new Connection(connection);
+}
+
+Connection::Connection(QTcpSocket *socket)
+ : QObject()
+ , m_connection(socket)
+ , m_command(0)
+{
+ connect(m_connection, SIGNAL(readyRead()), this, SLOT(receiveCommand()));
+ connect(m_connection, SIGNAL(disconnected()), this, SLOT(closedConnection()));
+}
+
+Connection::~Connection()
+{
+ if (m_command) {
+ m_command->commandFinished();
+ delete m_command;
+ m_command = 0;
+ }
+ delete m_connection;
+}
+
+void Connection::receiveCommand()
+{
+ QByteArray arr = m_connection->readAll();
+ debugOutput(1, QString::fromLatin1("Command received: ") + (arr));
+ QList<CommandInfo> commands = availableCommands();
+ for(QList<CommandInfo>::iterator it = commands.begin(); it != commands.end(); ++it) {
+ if (it->commandName == QString::fromLatin1(arr)) {
+ debugOutput(1, "Found command in list");
+ disconnect(m_connection, SIGNAL(readyRead()), this, SLOT(receiveCommand()));
+ AbstractCommand* command = (*it).commandFunc();
+ command->setSocket(m_connection);
+ m_command = command;
+ return;
+ }
+ }
+ debugOutput(2, QString::fromLatin1("Unknown command received: ") + (arr));
+}
+
+void Connection::closedConnection()
+{
+ debugOutput(0, "connection being closed...");
+ this->deleteLater();
+}
diff --git a/src/qtestlib/wince/cetcpsyncserver/connectionmanager.h b/src/qtestlib/wince/cetcpsyncserver/connectionmanager.h
new file mode 100644
index 000000000..e9f725cc8
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsyncserver/connectionmanager.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CONNECTION_MANAGER_INCL
+#define CONNECTION_MANAGER_INCL
+
+#include "transfer_global.h"
+#include "commands.h"
+
+#include <QtNetwork/QTcpServer>
+#include <QtNetwork/QTcpSocket>
+
+class Connection : public QObject
+{
+ Q_OBJECT
+public:
+ Connection(QTcpSocket* socket);
+ ~Connection();
+
+public slots:
+ void receiveCommand();
+ void closedConnection();
+
+private:
+ QTcpSocket* m_connection;
+ AbstractCommand* m_command;
+};
+
+class ConnectionManager : public QObject
+{
+ Q_OBJECT
+public:
+ ConnectionManager();
+ ~ConnectionManager();
+
+ bool init();
+
+public slots:
+ void cleanUp();
+ void newConnection();
+
+private:
+ QTcpServer* m_server;
+};
+
+#endif
diff --git a/src/qtestlib/wince/cetcpsyncserver/main.cpp b/src/qtestlib/wince/cetcpsyncserver/main.cpp
new file mode 100644
index 000000000..eccd86839
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsyncserver/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "connectionmanager.h"
+
+#include <QtCore>
+#include <QtNetwork>
+
+void messageOutput(QtMsgType type, const char *msg)
+{
+ switch(type) {
+ case QtDebugMsg: fprintf(stderr, "Debug: %s\n", msg); break;
+ case QtWarningMsg: fprintf(stderr, "Warning: %s\n", msg); break;
+ default: fprintf(stderr, "Some Msg: %s\n", msg); break;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ qInstallMsgHandler(messageOutput);
+
+ QCoreApplication app(argc, argv);
+ ConnectionManager manager;
+ manager.init();
+ return app.exec();
+}
diff --git a/src/qtestlib/wince/cetcpsyncserver/transfer_global.h b/src/qtestlib/wince/cetcpsyncserver/transfer_global.h
new file mode 100644
index 000000000..a2c029753
--- /dev/null
+++ b/src/qtestlib/wince/cetcpsyncserver/transfer_global.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef TRANSFER_GLOBAL_H
+#define TRANSFER_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+#ifdef Q_OS_WIN
+#include <windows.h>
+#endif
+
+#define SERVER_PORT 12145
+
+#define MAX_NAME_LENGTH 512
+#define MAX_ARGUMENTS 10
+
+// Defines for commands sent/received
+#define COMMAND_CREATE_FILE "CREATEFILE"
+#define COMMAND_CREATE_DIRECTORY "CREATEDIR"
+#define COMMAND_COPY_FILE "COPYFILE"
+#define COMMAND_COPY_DIRECTORY "COPYDIR"
+#define COMMAND_DELETE_FILE "DELETEFILE"
+#define COMMAND_DELETE_DIRECTORY "DELETEDIR"
+#define COMMAND_EXECUTE "EXECUTE"
+#define COMMAND_QUIT_SERVER "QUIT"
+#define COMMAND_FILE_TIME "FILETIME"
+#define COMMAND_TIME_STAMP "TIMESTAMP"
+
+// Report back commands
+#define COMMAND_SUCCESS "SUCCESS"
+#define COMMAND_ERROR "ERROR"
+
+// Defines for commands that send data back to requester
+#define COMMAND_READ_FILE "READFILE"
+#define COMMAND_READ_DIRECTORY "READDIR"
+
+#include <QtCore/qglobal.h>
+// Option-Structures for commands
+
+struct CreateFileOptions
+{
+ char fileName[MAX_NAME_LENGTH];
+#ifdef Q_OS_WIN
+ FILETIME fileTime;
+ DWORD fileAttributes;
+#endif
+ int fileSize;
+ bool overwriteExisting;
+};
+
+struct CreateDirectoryOptions
+{
+ char dirName[MAX_NAME_LENGTH];
+ bool recursively; // in case of \foo\bar create \foo if it does not exist
+};
+
+struct CopyFileOptions
+{
+ char from[MAX_NAME_LENGTH];
+ char to[MAX_NAME_LENGTH];
+ bool overwriteExisting;
+};
+
+struct CopyDirectoryOptions
+{
+ char from[MAX_NAME_LENGTH];
+ char to[MAX_NAME_LENGTH];
+ bool recursive;
+};
+
+struct DeleteFileOptions
+{
+ char fileName[MAX_NAME_LENGTH];
+};
+
+struct DeleteDirectoryOptions
+{
+ char dirName[MAX_NAME_LENGTH];
+ bool recursive;
+ bool failIfContentExists;
+};
+
+struct ExecuteOptions
+{
+ char appName[MAX_NAME_LENGTH];
+ int argumentsCount;
+ bool waitForFinished;
+ int timeout;
+};
+
+struct ReadFileOptions
+{
+ char fileName[MAX_NAME_LENGTH];
+};
+
+struct ReadFileReply
+{
+ qint64 fileSize;
+ bool fileValid;
+};
+
+struct ReadDirectoryOptions
+{
+ char dirName[MAX_NAME_LENGTH];
+};
+
+struct ReadDirectoryItem
+{
+ char name[MAX_NAME_LENGTH];
+ qint64 size;
+ bool isDirectory;
+ bool hasMore;
+};
+
+#define FileTimeOptions ReadFileOptions
+
+struct ReadDirectoryReply
+{
+ bool entryValid;
+ int itemCount; // might change during iteration
+};
+#endif
diff --git a/src/qtestlib/wince/cetest/activesyncconnection.cpp b/src/qtestlib/wince/cetest/activesyncconnection.cpp
new file mode 100644
index 000000000..c336c273b
--- /dev/null
+++ b/src/qtestlib/wince/cetest/activesyncconnection.cpp
@@ -0,0 +1,640 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "activesyncconnection.h"
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo>
+#include <rapi.h>
+
+extern void debugOutput(const QString& text, int level);
+
+ActiveSyncConnection::ActiveSyncConnection()
+ : AbstractRemoteConnection()
+ , connected(false)
+{
+}
+
+ActiveSyncConnection::~ActiveSyncConnection()
+{
+ if (isConnected())
+ disconnect();
+}
+
+bool ActiveSyncConnection::connect(QVariantList&)
+{
+ if (connected)
+ return true;
+ connected = false;
+ RAPIINIT init;
+ init.cbSize = sizeof(init);
+ if (CeRapiInitEx(&init) != S_OK)
+ return connected;
+
+ DWORD res;
+ res = WaitForMultipleObjects(1,&(init.heRapiInit),true, 5000);
+ if ((res == -1) || (res == WAIT_TIMEOUT) || (init.hrRapiInit != S_OK))
+ return connected;
+
+ connected = true;
+ return connected;
+}
+
+void ActiveSyncConnection::disconnect()
+{
+ connected = false;
+ CeRapiUninit();
+}
+
+bool ActiveSyncConnection::isConnected() const
+{
+ return connected;
+}
+
+bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists)
+{
+ if (failIfExists) {
+ CE_FIND_DATA search;
+ HANDLE searchHandle = CeFindFirstFile(deviceDest.utf16(), &search);
+ if (searchHandle != INVALID_HANDLE_VALUE) {
+ CeFindClose(searchHandle);
+ return false;
+ }
+ }
+
+ QFile file(localSource);
+ if (!file.exists())
+ return false;
+ if (!file.open(QIODevice::ReadOnly)) {
+ debugOutput(QString::fromLatin1(" Could not open source file"),2);
+ if (file.size() == 0) {
+ // Create an empy file
+ deleteFile(deviceDest);
+ HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (deviceHandle != INVALID_HANDLE_VALUE) {
+ CeCloseHandle(deviceHandle);
+ return true;
+ }
+ } else {
+ qWarning("Could not open %s: %s", qPrintable(localSource), qPrintable(file.errorString()));
+ }
+ return false;
+ }
+
+ deleteFile(deviceDest);
+ HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (deviceHandle == INVALID_HANDLE_VALUE) {
+ qWarning("Could not create %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData());
+ return false;
+ }
+
+ DWORD written = 0;
+ int currentPos = 0;
+ int size = file.size();
+ DWORD toWrite = 0;
+ const int bufferSize = 65000;
+ QByteArray data;
+ data.reserve(bufferSize);
+ while (currentPos < size) {
+ data = file.read(bufferSize);
+ if (data.size() <= 0) {
+ wprintf( L"Error while reading file!\n");
+ return false;
+ }
+ if (size - currentPos > bufferSize )
+ toWrite = bufferSize;
+ else
+ toWrite = size - currentPos;
+ if (toWrite == 0)
+ break;
+ if (!CeWriteFile(deviceHandle, data.data() , toWrite, &written, NULL)) {
+ qWarning("Could not write to %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData());
+ return false;
+ }
+ currentPos += written;
+ data.clear();
+ wprintf( L"%s -> %s (%d / %d) %d %%\r", localSource.utf16() , deviceDest.utf16(), currentPos , size, (100*currentPos)/size );
+ }
+ wprintf(L"\n");
+
+ // Copy FileTime for update verification
+ FILETIME creationTime, accessTime, writeTime;
+ HANDLE localHandle = CreateFile(localSource.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ if (localHandle != INVALID_HANDLE_VALUE) {
+ if (GetFileTime(localHandle, &creationTime, &accessTime, &writeTime)) {
+ LocalFileTimeToFileTime(&writeTime, &writeTime);
+ if (!CeSetFileTime(deviceHandle, &writeTime, NULL, NULL)) {
+ debugOutput(QString::fromLatin1(" Could not write time values"), 0);
+ }
+ }
+ CloseHandle(localHandle);
+ }
+ CeCloseHandle(deviceHandle);
+
+ DWORD attributes = GetFileAttributes(localSource.utf16());
+ if (attributes != -1 )
+ CeSetFileAttributes(deviceDest.utf16(), attributes);
+ return true;
+}
+
+bool ActiveSyncConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive)
+{
+ QDir dir(localSource);
+ if (!dir.exists())
+ return false;
+
+ deleteDirectory(deviceDest, recursive);
+ CeCreateDirectory(deviceDest.utf16(), NULL);
+ foreach(QString entry, dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot)) {
+ QString source = localSource + "\\" + entry;
+ QString target = deviceDest + "\\" + entry;
+ QFileInfo info(source);
+ if (info.isDir()) {
+ if (recursive) {
+ if (!copyDirectoryToDevice(source, target, recursive))
+ return false;
+ }
+ } else {
+ if (!copyFileToDevice(source, target))
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ActiveSyncConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists)
+{
+ QFile target(localDest);
+ if (failIfExists && target.exists()) {
+ debugOutput(QString::fromLatin1(" Not allowed to overwrite file"), 2);
+ return false;
+ }
+
+ if (target.exists())
+ target.remove();
+
+ HANDLE deviceHandle = CeCreateFile(deviceSource.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ if (deviceHandle == INVALID_HANDLE_VALUE) {
+ debugOutput(QString::fromLatin1(" Could not open file on device"), 2);
+ return false;
+ }
+
+ DWORD fileSize = CeGetFileSize( deviceHandle, NULL );
+ if (fileSize == -1) {
+ debugOutput(QString::fromLatin1(" Could not stat filesize of remote file"), 2);
+ CeCloseHandle(deviceHandle);
+ return false;
+ }
+
+ if (!target.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ debugOutput(QString::fromLatin1(" Could not open local file for writing"), 2);
+ CeCloseHandle(deviceHandle);
+ return false;
+ }
+
+ int bufferSize = 65000;
+ char *buffer = (char*) malloc(bufferSize);
+ DWORD bufferRead = 0;
+ DWORD bufferWritten = 0;
+ bool readUntilEnd = false;
+ while(CeReadFile(deviceHandle, buffer, bufferSize, &bufferRead, NULL)) {
+ if (bufferRead == 0) {
+ readUntilEnd = true;
+ break;
+ }
+ target.write(buffer, bufferRead);
+ bufferWritten += bufferRead;
+ wprintf(L"%s -> %s (%d / %d) %d %%\r", deviceSource.utf16(), localDest.utf16(), bufferWritten, fileSize, (100*bufferWritten)/fileSize);
+ }
+ wprintf(L"\n");
+
+ if (!readUntilEnd) {
+ debugOutput(QString::fromLatin1(" an error occurred during copy"), 2);
+ return false;
+ }
+
+ CeCloseHandle(deviceHandle);
+ return true;
+}
+
+bool ActiveSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive)
+{
+ if (!QDir(localDest).exists() && !QDir(localDest).mkpath(QDir(localDest).absolutePath())) {
+ debugOutput(QString::fromLatin1(" Could not create local path"), 2);
+ }
+
+ QString searchArg = deviceSource + "\\*";
+ CE_FIND_DATA data;
+ HANDLE searchHandle = CeFindFirstFile(searchArg.utf16(), &data);
+ if (searchHandle == INVALID_HANDLE_VALUE) {
+ // We return true because we might be in a recursive call
+ // where nothing is to copy and the copy process
+ // might still be correct
+ return true;
+ }
+
+ do {
+ QString srcFile = deviceSource + "\\" + QString::fromWCharArray(data.cFileName);
+ QString destFile = localDest + "\\" + QString::fromWCharArray(data.cFileName);
+ if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ if (recursive && !copyDirectoryFromDevice(srcFile, destFile, recursive)) {
+ wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16());
+ return false;
+ }
+ } else {
+ copyFileFromDevice(srcFile, destFile, false);
+ }
+ } while(CeFindNextFile(searchHandle, &data));
+ CeFindClose(searchHandle);
+ return true;
+}
+
+bool ActiveSyncConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists)
+{
+ return CeCopyFile(QDir::toNativeSeparators(srcFile).utf16(),
+ QDir::toNativeSeparators(destFile).utf16(), failIfExists);
+}
+
+bool ActiveSyncConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory,
+ bool recursive)
+{
+ CeCreateDirectory(destDirectory.utf16(), NULL);
+ QString searchArg = srcDirectory + "\\*";
+ CE_FIND_DATA data;
+ HANDLE searchHandle = CeFindFirstFile(searchArg.utf16(), &data);
+ if (searchHandle == INVALID_HANDLE_VALUE) {
+ // We return true because we might be in a recursive call
+ // where nothing is to copy and the copy process
+ // might still be correct
+ return true;
+ }
+
+ do {
+ QString srcFile = srcDirectory + "\\" + QString::fromWCharArray(data.cFileName);
+ QString destFile = destDirectory + "\\" + QString::fromWCharArray(data.cFileName);
+ if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ if (recursive && !copyDirectory(srcFile, destFile, recursive)) {
+ wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16());
+ return false;
+ }
+ } else {
+ debugOutput(QString::fromLatin1("Copy %1 -> %2\n").arg(srcFile).arg(destFile), 0);
+ CeCopyFile(srcFile.utf16(), destFile.utf16(), false);
+ }
+ } while(CeFindNextFile(searchHandle, &data));
+ CeFindClose(searchHandle);
+ return true;
+}
+
+bool ActiveSyncConnection::deleteFile(const QString &fileName)
+{
+ CeSetFileAttributes(fileName.utf16(), FILE_ATTRIBUTE_NORMAL);
+ return CeDeleteFile(fileName.utf16());
+}
+
+bool ActiveSyncConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists)
+{
+ HANDLE hFind;
+ CE_FIND_DATA FindFileData;
+ QString FileName = directory + "\\*";
+ hFind = CeFindFirstFile(FileName.utf16(), &FindFileData);
+ if( hFind == INVALID_HANDLE_VALUE )
+ return CeRemoveDirectory(directory.utf16());
+
+ if (failIfContentExists)
+ return false;
+
+ do {
+ QString FileName = directory + "\\" + QString::fromWCharArray(FindFileData.cFileName);
+ if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ if (recursive)
+ if (!deleteDirectory(FileName, recursive, failIfContentExists))
+ return false;
+ } else {
+ if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ CeSetFileAttributes(FileName.utf16(), FILE_ATTRIBUTE_NORMAL);
+ if( !CeDeleteFile(FileName.utf16()) )
+ break;
+ }
+ } while(CeFindNextFile(hFind,&FindFileData));
+ CeFindClose(hFind);
+
+ return CeRemoveDirectory(directory.utf16());
+}
+
+bool ActiveSyncConnection::execute(QString program, QString arguments, int timeout, int *returnValue)
+{
+ if (!isConnected()) {
+ qWarning("Cannot execute, connect to device first!");
+ return false;
+ }
+
+ PROCESS_INFORMATION* pid = new PROCESS_INFORMATION;
+ bool result = false;
+ if (timeout != 0) {
+ // If we want to wait, we have to use CeRapiInvoke, as CeCreateProcess has no way to wait
+ // until the process ends. The lib must have been build and also deployed already.
+ if (!isConnected() && !connect())
+ return false;
+
+ QString dllLocation = "\\Windows\\QtRemote.dll";
+ QString functionName = "qRemoteLaunch";
+
+ DWORD outputSize;
+ BYTE* output;
+ IRAPIStream *stream;
+ int returned = 0;
+ DWORD error = 0;
+ HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0);
+ if (S_OK != res) {
+ DWORD ce_error = CeGetLastError();
+ if (S_OK != ce_error) {
+ qWarning("Error invoking %s on %s: %s", qPrintable(functionName),
+ qPrintable(dllLocation), strwinerror(ce_error).constData());
+ } else {
+ qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName),
+ qPrintable(dllLocation), res);
+ }
+ } else {
+ DWORD written;
+ int strSize = program.length();
+ if (S_OK != stream->Write(&strSize, sizeof(strSize), &written)) {
+ qWarning(" Could not write appSize to process");
+ return false;
+ }
+ if (S_OK != stream->Write(program.utf16(), program.length()*sizeof(wchar_t), &written)) {
+ qWarning(" Could not write appName to process");
+ return false;
+ }
+ strSize = arguments.length();
+ if (S_OK != stream->Write(&strSize, sizeof(strSize), &written)) {
+ qWarning(" Could not write argumentSize to process");
+ return false;
+ }
+ if (S_OK != stream->Write(arguments.utf16(), arguments.length()*sizeof(wchar_t), &written)) {
+ qWarning(" Could not write arguments to process");
+ return false;
+ }
+ if (S_OK != stream->Write(&timeout, sizeof(timeout), &written)) {
+ qWarning(" Could not write waiting option to process");
+ return false;
+ }
+
+ if (S_OK != stream->Read(&returned, sizeof(returned), &written)) {
+ qWarning(" Could not access return value of process");
+ }
+ if (S_OK != stream->Read(&error, sizeof(error), &written)) {
+ qWarning(" Could not access error code");
+ }
+
+ if (error) {
+ qWarning("Error on target: %s", strwinerror(error).constData());
+ result = false;
+ }
+ else {
+ result = true;
+ }
+ }
+
+ if (returnValue)
+ *returnValue = returned;
+ } else {
+ // We do not need to invoke another lib etc, if we are not interested in results anyway...
+ result = CeCreateProcess(program.utf16(), arguments.utf16(), 0, 0, false, 0, 0, 0, 0, pid);
+ }
+ return result;
+}
+
+bool ActiveSyncConnection::setDeviceAwake(bool activate, int *returnValue)
+{
+ if (!isConnected()) {
+ qWarning("Cannot execute, connect to device first!");
+ return false;
+ }
+ bool result = false;
+
+ // If we want to wait, we have to use CeRapiInvoke, as CeCreateProcess has no way to wait
+ // until the process ends. The lib must have been build and also deployed already.
+ if (!isConnected() && !connect())
+ return false;
+
+ HRESULT res = S_OK;
+
+ //SYSTEM_POWER_STATUS_EX systemPowerState;
+
+ //res = CeGetSystemPowerStatusEx(&systemPowerState, true);
+
+ QString dllLocation = "\\Windows\\QtRemote.dll";
+ QString functionName = "qRemoteToggleUnattendedPowerMode";
+
+ DWORD outputSize;
+ BYTE* output;
+ IRAPIStream *stream;
+ int returned = 0;
+ int toggle = int(activate);
+
+ res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0);
+ if (S_OK != res) {
+ DWORD ce_error = CeGetLastError();
+ if (S_OK != ce_error) {
+ qWarning("Error invoking %s on %s: %s", qPrintable(functionName),
+ qPrintable(dllLocation), strwinerror(ce_error).constData());
+ } else {
+ qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName),
+ qPrintable(dllLocation), res);
+ }
+ } else {
+ DWORD written;
+
+ if (S_OK != stream->Write(&toggle, sizeof(toggle), &written)) {
+ qWarning(" Could not write toggle option to process");
+ return false;
+ }
+
+ if (S_OK != stream->Read(&returned, sizeof(returned), &written)) {
+ qWarning(" Could not access return value of process");
+ }
+ else
+ result = true;
+ }
+
+ if (returnValue)
+ *returnValue = returned;
+
+ return result;
+}
+
+bool ActiveSyncConnection::resetDevice()
+{
+ if (!isConnected()) {
+ qWarning("Cannot execute, connect to device first!");
+ return false;
+ }
+
+ bool result = false;
+ if (!isConnected() && !connect())
+ return false;
+
+ QString dllLocation = "\\Windows\\QtRemote.dll";
+ QString functionName = "qRemoteSoftReset";
+
+ DWORD outputSize;
+ BYTE* output;
+ IRAPIStream *stream;
+
+ int returned = 0;
+
+ HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0);
+ if (S_OK != res) {
+ DWORD ce_error = CeGetLastError();
+ if (S_OK != ce_error) {
+ qWarning("Error invoking %s on %s: %s", qPrintable(functionName),
+ qPrintable(dllLocation), strwinerror(ce_error).constData());
+ } else {
+ qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName),
+ qPrintable(dllLocation), res);
+ }
+ } else {
+ result = true;
+ }
+ return result;
+}
+
+bool ActiveSyncConnection::toggleDevicePower(int *returnValue)
+{
+ if (!isConnected()) {
+ qWarning("Cannot execute, connect to device first!");
+ return false;
+ }
+
+ bool result = false;
+ if (!isConnected() && !connect())
+ return false;
+
+ QString dllLocation = "\\Windows\\QtRemote.dll";
+ QString functionName = "qRemotePowerButton";
+
+ DWORD outputSize;
+ BYTE* output;
+ IRAPIStream *stream;
+ int returned = 0;
+
+ HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0);
+ if (S_OK != res) {
+ DWORD ce_error = CeGetLastError();
+ if (S_OK != ce_error) {
+ qWarning("Error invoking %s on %s: %s", qPrintable(functionName),
+ qPrintable(dllLocation), strwinerror(ce_error).constData());
+ } else {
+ qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName),
+ qPrintable(dllLocation), res);
+ }
+ } else {
+ DWORD written;
+ if (S_OK != stream->Read(&returned, sizeof(returned), &written)) {
+ qWarning(" Could not access return value of process");
+ }
+ else {
+ result = true;
+ }
+ }
+
+ if (returnValue)
+ *returnValue = returned;
+ return result;
+}
+
+bool ActiveSyncConnection::createDirectory(const QString &path, bool deleteBefore)
+{
+ if (deleteBefore)
+ deleteDirectory(path);
+ QStringList separated = path.split(QLatin1Char('\\'));
+ QString current = QLatin1String("\\");
+ bool result;
+ for (int i=1; i < separated.size(); ++i) {
+ current += separated.at(i);
+ result = CeCreateDirectory(current.utf16(), NULL);
+ current += QLatin1String("\\");
+ }
+ return result;
+}
+
+bool ActiveSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const
+{
+ QString tmpFile = QString::fromLatin1("\\qt_tmp_ftime_convert");
+ HANDLE remoteHandle = CeCreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (remoteHandle == INVALID_HANDLE_VALUE)
+ return false;
+
+ LocalFileTimeToFileTime(fTime, fTime);
+
+ if (!CeSetFileTime(remoteHandle, fTime, NULL, NULL)) {
+ CeCloseHandle(remoteHandle);
+ return false;
+ }
+
+ CeCloseHandle(remoteHandle);
+ remoteHandle = CeCreateFile(tmpFile.utf16(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ if (remoteHandle == INVALID_HANDLE_VALUE)
+ return false;
+ if (!CeGetFileTime(remoteHandle, fTime, NULL, NULL)) {
+ CeCloseHandle(remoteHandle);
+ return false;
+ }
+
+ CeCloseHandle(remoteHandle);
+ CeDeleteFile(tmpFile.utf16());
+ return true;
+}
+
+bool ActiveSyncConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const
+{
+ HANDLE deviceHandle = CeCreateFile(fileName.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ if (deviceHandle == INVALID_HANDLE_VALUE)
+ return false;
+
+ bool result = true;
+ if (!CeGetFileTime(deviceHandle, deviceCreationTime, NULL, NULL))
+ result = false;
+
+ CeCloseHandle(deviceHandle);
+ return result;
+}
diff --git a/src/qtestlib/wince/cetest/activesyncconnection.h b/src/qtestlib/wince/cetest/activesyncconnection.h
new file mode 100644
index 000000000..c23742e50
--- /dev/null
+++ b/src/qtestlib/wince/cetest/activesyncconnection.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ACTIVESYNC_REMOTECONNECTION_H
+#define ACTIVESYNC_REMOTECONNECTION_H
+
+#include "remoteconnection.h"
+
+#if defined(Q_OS_WIN32)
+#define REMOTELIBNAME "remotecommands"
+#endif
+
+class ActiveSyncConnection : public AbstractRemoteConnection
+{
+public:
+ ActiveSyncConnection();
+ virtual ~ActiveSyncConnection();
+
+ bool connect(QVariantList &list = QVariantList());
+ void disconnect();
+ bool isConnected() const;
+
+ // These functions are designed for transfer between desktop and device
+ // Caution: deviceDest path has to be device specific (eg. no drive letters for CE)
+ bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false);
+ bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true);
+ bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false);
+ bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true);
+
+ bool timeStampForLocalFileTime(FILETIME*) const;
+ bool fileCreationTime(const QString &fileName, FILETIME*) const;
+
+ // These functions only work on files existing on the device
+ bool copyFile(const QString&, const QString&, bool failIfExists = false);
+ bool copyDirectory(const QString&, const QString&, bool recursive = true);
+ bool deleteFile(const QString&);
+ bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false);
+ bool moveFile(const QString&, const QString&, bool FailIfExists = false);
+ bool moveDirectory(const QString&, const QString&, bool recursive = true);
+
+ bool createDirectory(const QString&, bool deleteBefore=false);
+
+ bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL);
+ bool resetDevice();
+ bool toggleDevicePower(int *returnValue = NULL);
+ bool setDeviceAwake(bool activate, int *returnValue = NULL);
+private:
+ bool connected;
+};
+
+#endif
diff --git a/src/qtestlib/wince/cetest/bootstrapped.pri b/src/qtestlib/wince/cetest/bootstrapped.pri
new file mode 100644
index 000000000..56c8ab7e9
--- /dev/null
+++ b/src/qtestlib/wince/cetest/bootstrapped.pri
@@ -0,0 +1,45 @@
+# Bootstrapped Input
+SOURCES += \
+ $$QT_SOURCE_TREE/src/corelib/tools/qstring.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfile.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qdir.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemiterator_win.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qtemporaryfile.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qdiriterator.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qiodevice.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qbuffer.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qtextstream.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qurl.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qsettings.cpp \
+ $$QT_SOURCE_TREE/src/corelib/io/qsettings_win.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qdatetime.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qlocale.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qbytearray.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qbytearraymatcher.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qvector.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qvsnprintf.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qlist.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qhash.cpp \
+ $$QT_SOURCE_TREE/src/corelib/global/qglobal.cpp \
+ $$QT_BUILD_TREE/src/corelib/global/qconfig.cpp \
+ $$QT_SOURCE_TREE/src/corelib/global/qmalloc.cpp \
+ $$QT_SOURCE_TREE/src/corelib/global/qnumeric.cpp \
+ $$QT_SOURCE_TREE/src/corelib/global/qlibraryinfo.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qregexp.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qmap.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qbitarray.cpp \
+ $$QT_SOURCE_TREE/src/corelib/kernel/qmetatype.cpp \
+ $$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp \
+ $$QT_SOURCE_TREE/src/corelib/codecs/qutfcodec.cpp \
+ $$QT_SOURCE_TREE/src/corelib/xml/qxmlstream.cpp \
+ $$QT_SOURCE_TREE/src/corelib/xml/qxmlutils.cpp
+
diff --git a/src/qtestlib/wince/cetest/cetcpsyncconnection.cpp b/src/qtestlib/wince/cetest/cetcpsyncconnection.cpp
new file mode 100644
index 000000000..ba55c3928
--- /dev/null
+++ b/src/qtestlib/wince/cetest/cetcpsyncconnection.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "CeTcpSyncConnection.h"
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo>
+
+static const QString ceTcpSyncProgram = "cetcpsync";
+extern void debugOutput(const QString& text, int level);
+
+CeTcpSyncConnection::CeTcpSyncConnection()
+ : AbstractRemoteConnection()
+ , connected(false)
+{
+}
+
+CeTcpSyncConnection::~CeTcpSyncConnection()
+{
+ if (isConnected())
+ disconnect();
+}
+
+bool CeTcpSyncConnection::connect(QVariantList&)
+{
+ // We connect with each command, so this is always true
+ // The command itself will fail then
+ const QString cmd = ceTcpSyncProgram + " noop";
+ if (system(qPrintable(cmd)) != 0)
+ return false;
+ connected = true;
+ return true;
+}
+
+void CeTcpSyncConnection::disconnect()
+{
+ connected = false;
+}
+
+bool CeTcpSyncConnection::isConnected() const
+{
+ return connected;
+}
+
+inline QString boolToString(bool b)
+{
+ return b ? "true" : "false";
+}
+
+static bool fileTimeFromString(FILETIME& ft, const QString& str)
+{
+ int idx = str.indexOf("*");
+ if (idx <= 0)
+ return false;
+ bool ok;
+ ft.dwLowDateTime = str.left(idx).toULong(&ok);
+ if (!ok)
+ return false;
+ ft.dwHighDateTime = str.mid(idx+1).toULong(&ok);
+ return ok;
+}
+
+static QString fileTimeToString(FILETIME& ft)
+{
+ return QString::number(ft.dwLowDateTime) + "*" + QString::number(ft.dwHighDateTime);
+}
+
+bool CeTcpSyncConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists)
+{
+ QString cmd = ceTcpSyncProgram + " copyFileToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(failIfExists);
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive)
+{
+ QString cmd = ceTcpSyncProgram + " copyDirectoryToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(recursive);
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists)
+{
+ QString cmd = ceTcpSyncProgram + " copyFileFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(failIfExists);
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive)
+{
+ QString cmd = ceTcpSyncProgram + " copyDirectoryFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(recursive);
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists)
+{
+ QString cmd = ceTcpSyncProgram + " copyFile \"" + srcFile + "\" \"" + destFile + "\" " + boolToString(failIfExists);
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory,
+ bool recursive)
+{
+ QString cmd = ceTcpSyncProgram + " copyDirectory \"" + srcDirectory + "\" \"" + destDirectory + "\" " + boolToString(recursive);
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::deleteFile(const QString &fileName)
+{
+ QString cmd = ceTcpSyncProgram + " deleteFile \"" + fileName + "\"";
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists)
+{
+ QString cmd = ceTcpSyncProgram + " deleteDirectory \"" + directory + "\" " + boolToString(recursive) + " " + boolToString(failIfContentExists);
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::execute(QString program, QString arguments, int timeout, int *returnValue)
+{
+ QString cmd = ceTcpSyncProgram + " execute \"" + program + "\" \"" + arguments + "\" " + QString::number(timeout);
+ int exitCode = system(qPrintable(cmd));
+ if (returnValue)
+ *returnValue = exitCode;
+ return true;
+}
+
+bool CeTcpSyncConnection::createDirectory(const QString &path, bool deleteBefore)
+{
+ QString cmd = ceTcpSyncProgram + " createDirectory \"" + path + "\" " + boolToString(deleteBefore);
+ return system(qPrintable(cmd)) == 0;
+}
+
+bool CeTcpSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const
+{
+ QString cmd = ceTcpSyncProgram + " timeStampForLocalFileTime " + fileTimeToString(*fTime) + " >qt_cetcpsyncdata.txt";
+ if (system(qPrintable(cmd)) != 0)
+ return false;
+
+ QFile file("qt_cetcpsyncdata.txt");
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+
+ bool result = fileTimeFromString(*fTime, file.readLine());
+ file.close();
+ file.remove();
+ return result;
+}
+
+bool CeTcpSyncConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const
+{
+ QString cmd = ceTcpSyncProgram + " fileCreationTime \"" + fileName + "\" >qt_cetcpsyncdata.txt";
+ if (system(qPrintable(cmd)) != 0)
+ return false;
+
+ QFile file("qt_cetcpsyncdata.txt");
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+
+ bool result = fileTimeFromString(*deviceCreationTime, file.readLine());
+ file.close();
+ file.remove();
+ return result;
+}
+
+bool CeTcpSyncConnection::resetDevice()
+{
+ qWarning("CeTcpSyncConnection::resetDevice not implemented");
+ return false;
+}
+
+bool CeTcpSyncConnection::toggleDevicePower(int *returnValue)
+{
+ Q_UNUSED(returnValue);
+ qWarning("CeTcpSyncConnection::toggleDevicePower not implemented");
+ return false;
+}
+
+bool CeTcpSyncConnection::setDeviceAwake(bool activate, int *returnValue)
+{
+ Q_UNUSED(activate);
+ Q_UNUSED(returnValue);
+ qWarning("CeTcpSyncConnection::setDeviceAwake not implemented");
+ return false;
+}
diff --git a/src/qtestlib/wince/cetest/cetcpsyncconnection.h b/src/qtestlib/wince/cetest/cetcpsyncconnection.h
new file mode 100644
index 000000000..47150a11b
--- /dev/null
+++ b/src/qtestlib/wince/cetest/cetcpsyncconnection.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CETCPSYNC_REMOTECONNECTION_H
+#define CETCPSYNC_REMOTECONNECTION_H
+
+#include "remoteconnection.h"
+
+class CeTcpSyncConnection : public AbstractRemoteConnection
+{
+public:
+ CeTcpSyncConnection();
+ virtual ~CeTcpSyncConnection();
+
+ bool connect(QVariantList &list = QVariantList());
+ void disconnect();
+ bool isConnected() const;
+
+ // These functions are designed for transfer between desktop and device
+ // Caution: deviceDest path has to be device specific (eg. no drive letters for CE)
+ bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false);
+ bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true);
+ bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false);
+ bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true);
+
+ bool timeStampForLocalFileTime(FILETIME*) const;
+ bool fileCreationTime(const QString &fileName, FILETIME*) const;
+
+ // These functions only work on files existing on the device
+ bool copyFile(const QString&, const QString&, bool failIfExists = false);
+ bool copyDirectory(const QString&, const QString&, bool recursive = true);
+ bool deleteFile(const QString&);
+ bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false);
+ bool moveFile(const QString&, const QString&, bool FailIfExists = false);
+ bool moveDirectory(const QString&, const QString&, bool recursive = true);
+
+ bool createDirectory(const QString&, bool deleteBefore=false);
+
+ bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL);
+ bool resetDevice();
+ bool toggleDevicePower(int *returnValue = NULL);
+ bool setDeviceAwake(bool activate, int *returnValue = NULL);
+private:
+ bool connected;
+};
+
+#endif
diff --git a/src/qtestlib/wince/cetest/cetest.pro b/src/qtestlib/wince/cetest/cetest.pro
new file mode 100644
index 000000000..82747dada
--- /dev/null
+++ b/src/qtestlib/wince/cetest/cetest.pro
@@ -0,0 +1,56 @@
+TEMPLATE = app
+TARGET = cetest
+DESTDIR = ../../../../bin
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+CONFIG += console no_batch
+CONFIG -= qt
+
+DEFINES += QT_BUILD_QMAKE QT_BOOTSTRAPPED QT_NO_CODECS QT_LITE_UNICODE QT_NO_LIBRARY \
+ QT_NO_STL QT_NO_COMPRESS QT_NO_DATASTREAM \
+ QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_NO_THREAD \
+ QT_NO_SYSTEMLOCALE QT_NO_GEOM_VARIANT \
+ QT_NODLL QT_NO_QOBJECT
+
+INCLUDEPATH = \
+ $$QT_SOURCE_TREE/tools/qtestlib/ce/cetest \
+ $$QT_SOURCE_TREE/qmake \
+ $$QT_SOURCE_TREE/qmake/generators/symbian \
+ $$QT_SOURCE_TREE/tools/shared \
+ $$QT_BUILD_TREE/include \
+ $$QT_BUILD_TREE/include/QtCore \
+ $$QT_BUILD_TREE/src/corelib/global
+
+VPATH += $$QT_SOURCE_TREE/tools/shared
+
+DEPENDPATH += $$QT_BUILD_TREE/src/corelib/tools $$QT_BUILD_TREE/src/corelib/io
+
+# Input
+HEADERS += \
+ remoteconnection.h \
+ deployment.h
+
+SOURCES += \
+ remoteconnection.cpp \
+ deployment.cpp \
+ main.cpp
+
+LIBS += ole32.lib advapi32.lib
+
+isEmpty(QT_CE_RAPI_INC) {
+ DEFINES += QT_CETEST_NO_ACTIVESYNC
+ HEADERS += cetcpsyncconnection.h
+ SOURCES += cetcpsyncconnection.cpp
+} else {
+ HEADERS += activesyncconnection.h
+ SOURCES += activesyncconnection.cpp
+ LIBS += rapi.lib
+ INCLUDEPATH += $$QT_CE_RAPI_INC
+ LIBS += -L$$QT_CE_RAPI_LIB
+}
+
+include(qmake_include.pri)
+include(bootstrapped.pri)
diff --git a/src/qtestlib/wince/cetest/deployment.cpp b/src/qtestlib/wince/cetest/deployment.cpp
new file mode 100644
index 000000000..cd6ce2806
--- /dev/null
+++ b/src/qtestlib/wince/cetest/deployment.cpp
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deployment.h"
+#include "remoteconnection.h"
+#include <option.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qstring.h>
+
+extern void debugOutput(const QString& text, int level);
+
+bool DeploymentHandler::deviceCopy(const DeploymentList &deploymentList)
+{
+ for (int i=0; i<deploymentList.size(); ++i) {
+ CopyItem item = deploymentList.at(i);
+ m_connection->createDirectory(item.to.left(item.to.lastIndexOf(QLatin1Char('\\'))));
+ if (!m_connection->copyFileToDevice(item.from , item.to)) {
+ debugOutput(QString::fromLatin1("Error while copy: %1 -> %2").arg(item.from).arg(item.to),0);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool DeploymentHandler::deviceDeploy(const DeploymentList &deploymentList)
+{
+ DeploymentList copyList;
+ for (int i=0; i<deploymentList.size(); ++i) {
+#if defined(Q_OS_WIN)
+ HANDLE localHandle = CreateFile(deploymentList.at(i).from.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ if (localHandle == INVALID_HANDLE_VALUE) {
+ copyList.append(deploymentList.at(i));
+ continue;
+ }
+ FILETIME localCreationTime;
+ if (!GetFileTime(localHandle, NULL, NULL, &localCreationTime) || !m_connection->timeStampForLocalFileTime(&localCreationTime)) {
+ copyList.append(deploymentList.at(i));
+ CloseHandle(localHandle);
+ continue;
+ }
+ CloseHandle(localHandle);
+
+ FILETIME deviceCreationTime;
+ if (!m_connection->fileCreationTime(deploymentList.at(i).to , &deviceCreationTime)) {
+ copyList.append(deploymentList.at(i));
+ continue;
+ }
+
+ int res = CompareFileTime(&localCreationTime, &deviceCreationTime);
+ if (res != 0)
+ copyList.append(deploymentList.at(i));
+ else
+ debugOutput(QString::fromLatin1("Skipping File %1, already latest version").arg(deploymentList.at(i).from),0);
+#else
+ copyList.append(deploymentList.at(i));
+#endif
+ }
+ return deviceCopy(copyList);
+}
+
+void DeploymentHandler::cleanup(const DeploymentList &deploymentList)
+{
+ for (int i=0; i<deploymentList.size(); ++i) {
+ m_connection->deleteFile(deploymentList.at(i).to);
+#ifdef Q_OS_WIN
+ QString path = deploymentList.at(i).to;
+ int pos;
+ while ( (pos = path.lastIndexOf(QLatin1Char('\\'))) > 0) {
+ path = path.left(pos);
+ if (!m_connection->deleteDirectory(path, false, true))
+ break;
+ }
+#endif
+ }
+}
+
+void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &deploymentList, const QString &testPath)
+{
+ QString targetPath = project->values("deploy.path").join(" ");
+ if (targetPath.isEmpty())
+ targetPath = testPath;
+ if (targetPath.endsWith("/") || targetPath.endsWith("\\"))
+ targetPath = targetPath.mid(0,targetPath.size()-1);
+
+ // Only deploy Qt libs for shared build
+ if (!project->values("QMAKE_QT_DLL").isEmpty() && !project->values("QMAKE_LIBDIR").isEmpty()) {
+ QStringList libs = project->values("LIBS");
+ QStringList qtLibs;
+ QStringList libPaths;
+ foreach (QString item, libs) {
+
+ if (item.startsWith("-L")) {
+ // -L -> a directory containing DLLs
+ libPaths << item.mid(2);
+ continue;
+ }
+
+ QStringList libCandidates;
+
+ if (item.startsWith("-l")) {
+ // -l -> a library located within one of the standard library paths
+ QString lib = item.mid(2);
+
+ // Check if it's a Qt library first, then check in all paths given with -L.
+ // Note Qt libraries get a `4' appended to them, others don't.
+ libCandidates << project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + lib + QLatin1String("4.dll");
+ foreach (QString const& libPath, libPaths) {
+ libCandidates << libPath + QDir::separator() + lib + QLatin1String(".dll");
+ }
+ } else {
+ libCandidates << item.replace(".lib",".dll");
+ }
+
+ foreach (QString const& file, libCandidates) {
+ QFileInfo info(file);
+ if (info.exists()) {
+ qtLibs += info.dir().absoluteFilePath(info.fileName());
+ break;
+ }
+ }
+ }
+ for (QStringList::ConstIterator it = qtLibs.constBegin(); it != qtLibs.constEnd(); ++it) {
+ QString dllName = *it;
+ QFileInfo info(dllName);
+ if (!info.exists())
+ continue;
+ deploymentList.append(CopyItem(Option::fixPathToLocalOS(info.absoluteFilePath()) ,
+ Option::fixPathToLocalOS(targetPath + "/" + info.fileName())));
+ }
+ }
+
+#ifndef QT_CETEST_NO_ACTIVESYNC
+ // QtRemote deployment. We always deploy to \Windows
+ if (!project->values("QMAKE_LIBDIR").isEmpty()) {
+ QString remoteLibName = QLatin1String("QtRemote.dll");
+ QString remoteLib = Option::fixPathToLocalOS(project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + remoteLibName);
+ if (QFile::exists(remoteLib))
+ deploymentList.append(CopyItem(remoteLib, QString::fromLatin1("\\Windows\\") + remoteLibName));
+ else
+ debugOutput(QString::fromLatin1("Could not find QtRemote. Might not be able to launch target executable"),0);
+ }
+#endif
+
+ // C-runtime deployment
+ QString runtime = project->values("QT_CE_C_RUNTIME").join(QLatin1String(" "));
+ debugOutput(QString::fromLatin1("Runtime:%1").arg(runtime), 2);
+ if (!runtime.isEmpty() && (runtime != QLatin1String("no"))) {
+ QString runtimeVersion = QLatin1String("msvcr");
+ const QString mkspec = project->values("QMAKESPEC").first();
+ if (mkspec.endsWith("2008"))
+ runtimeVersion.append("90");
+ else
+ runtimeVersion.append("80");
+ if (project->isActiveConfig("debug"))
+ runtimeVersion.append("d");
+ runtimeVersion.append(".dll");
+
+ if (runtime == "yes") {
+ // Auto-find C-runtime
+ QString vcInstallDir = qgetenv("VCINSTALLDIR");
+ if (!vcInstallDir.isEmpty()) {
+ vcInstallDir += "\\ce\\dll\\";
+ vcInstallDir += project->values("CE_ARCH").join(QLatin1String(" "));
+ if (!QFileInfo(vcInstallDir + QDir::separator() + runtimeVersion).exists())
+ runtime.clear();
+ else
+ runtime = vcInstallDir;
+ }
+ }
+
+ if (!runtime.isEmpty()) {
+ deploymentList.append(CopyItem(Option::fixPathToLocalOS(runtime + "/" + runtimeVersion ) ,
+ Option::fixPathToLocalOS(targetPath + "/" + runtimeVersion)));
+ }
+ }
+}
+
+void DeploymentHandler::initProjectDeploy(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath)
+{
+ QString targetPath = project->values("deploy.path").join(" ");
+ if (targetPath.isEmpty())
+ targetPath = testPath;
+ if (targetPath.endsWith("/") || targetPath.endsWith("\\"))
+ targetPath = targetPath.mid(0,targetPath.size()-1);
+
+ QStringList& list = project->values("DEPLOYMENT");
+ if (list.isEmpty())
+ return;
+
+ for (int it = 0; it < list.size(); ++it) {
+ QString argSource = list.at(it);
+ QString argPath = list.at(it) + QString(".path");
+ if (((project->values(argSource + QString(".files")).isEmpty() && project->values(argSource + QString(".sources")).isEmpty()) || project->values(argPath).isEmpty()) && list.at(it) != "deploy") {
+ debugOutput(QString::fromLatin1("cannot deploy \"%1\" because of missing data.").arg(list.at(it)), 0);
+ continue;
+ }
+
+ QString addPath = project->values(argPath).join(QLatin1String(" "));
+ if (addPath == QLatin1String("."))
+ addPath.clear();
+ if (!addPath.startsWith("/") && !addPath.startsWith(QLatin1String("\\")))
+ addPath = targetPath + "/" + addPath;
+
+ QStringList addSources = project->values(argSource + QString(".files")) + project->values(argSource + QString(".sources"));
+ addSources.replaceInStrings(QLatin1String("/"), QLatin1String("\\"));
+ for(int index=0; index < addSources.size(); ++index) {
+ QString dirstr = qmake_getpwd();
+ QString filestr = Option::fixPathToLocalOS(addSources.at(index), false, false);
+ int slsh = filestr.lastIndexOf(Option::dir_sep);
+ if(slsh != -1) {
+ dirstr = filestr.left(slsh+1);
+ filestr = filestr.right(filestr.length() - slsh - 1);
+ }
+ if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep)
+ dirstr += Option::dir_sep;
+ QFileInfo info(dirstr + filestr);
+
+ static int addQMakeDeployCounter = 0;
+ QStringList entryList = info.absoluteDir().entryList(QStringList() << info.fileName());
+ if (entryList.size() > 1) {
+ foreach(QString s, entryList) {
+ // We do not include directories when using wildcards
+ QFileInfo wildInfo(info.absolutePath() + "/" + s);
+ if (wildInfo.isDir()) {
+ continue;
+ }
+ QString appendedQmakeDeploy = QString::fromLatin1("_q_make_additional_deploy_%1").arg(addQMakeDeployCounter++);
+ project->parse(appendedQmakeDeploy + QLatin1String(".files = \"") + wildInfo.absoluteFilePath());
+ project->parse(appendedQmakeDeploy + QLatin1String(".path = \"") + addPath);
+ list.append(appendedQmakeDeploy);
+ }
+ continue;
+ }
+
+ if (info.isDir()) {
+ QDir additionalDir(dirstr + filestr);
+ QStringList additionalEntries = additionalDir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::NoSymLinks);
+ foreach(QString item, additionalEntries) {
+ QString appendedDeploy = QString::fromLatin1("_q_make_additional_deploy_%1").arg(addQMakeDeployCounter++);
+ project->parse(appendedDeploy + QLatin1String(".files = \"") + Option::fixPathToLocalOS(additionalDir.absoluteFilePath(item)) + QLatin1String("\""));
+ QString appendTargetPath = project->values(argPath).join(QLatin1String(" "));
+ if (appendTargetPath == QLatin1String("."))
+ appendTargetPath = filestr;
+ else
+ appendTargetPath.append(QLatin1String("\\") + filestr);
+ project->parse(appendedDeploy + QLatin1String(".path = ") + appendTargetPath);
+ list.append(appendedDeploy);
+ }
+ } else if (entryList.size() == 1)
+ deploymentList.append(CopyItem(Option::fixPathToLocalOS(info.absolutePath() + "/" + entryList.at(0)) ,
+ Option::fixPathToLocalOS(addPath + "/" + entryList.at(0))));
+ }
+ }
+}
diff --git a/src/qtestlib/wince/cetest/deployment.h b/src/qtestlib/wince/cetest/deployment.h
new file mode 100644
index 000000000..9d0b9caec
--- /dev/null
+++ b/src/qtestlib/wince/cetest/deployment.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEPLOYMENT_INCL
+#define DEPLOYMENT_INCL
+
+#include <qstring.h>
+#include <qlist.h>
+#include <project.h>
+
+class AbstractRemoteConnection;
+
+struct CopyItem
+{
+ CopyItem(const QString& f, const QString& t) : from(f) , to(t) { }
+ QString from;
+ QString to;
+};
+typedef QList<CopyItem> DeploymentList;
+
+class DeploymentHandler
+{
+public:
+ inline void setConnection(AbstractRemoteConnection*);
+ inline AbstractRemoteConnection* connection() const;
+ bool deviceCopy(const DeploymentList &deploymentList);
+ bool deviceDeploy(const DeploymentList &deploymentList);
+ void cleanup(const DeploymentList &deploymentList);
+ static void initProjectDeploy(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath = "\\Program Files\\qt_test");
+ static void initQtDeploy(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath = "\\Program Files\\qt_test");
+private:
+ AbstractRemoteConnection* m_connection;
+};
+
+inline void DeploymentHandler::setConnection(AbstractRemoteConnection *connection) { m_connection = connection; }
+inline AbstractRemoteConnection* DeploymentHandler::connection() const { return m_connection; }
+#endif \ No newline at end of file
diff --git a/src/qtestlib/wince/cetest/main.cpp b/src/qtestlib/wince/cetest/main.cpp
new file mode 100644
index 000000000..7e9ea5dfb
--- /dev/null
+++ b/src/qtestlib/wince/cetest/main.cpp
@@ -0,0 +1,445 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef QT_CETEST_NO_ACTIVESYNC
+# include "cetcpsyncconnection.h"
+#else
+# include "activesyncconnection.h"
+#endif
+
+const int SLEEP_AFTER_RESET = 60000; // sleep for 1 minute
+const int SLEEP_RECONNECT = 2000; // sleep for 2 seconds before trying another reconnect
+
+#include "deployment.h"
+#include <option.h>
+#include <project.h>
+#include <property.h>
+#include <qstringlist.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <iostream>
+using namespace std;
+
+const int debugLevel = 0;
+void debugOutput(const QString& text, int level)
+{
+ if (level <= debugLevel)
+ cout << qPrintable(text) << endl;
+}
+
+// needed for QMake sources to compile
+QString project_builtin_regx() { return QString();}
+static QString pwd;
+QString qmake_getpwd()
+{
+ if(pwd.isNull())
+ pwd = QDir::currentPath();
+ return pwd;
+}
+bool qmake_setpwd(const QString &p)
+{
+ if(QDir::setCurrent(p)) {
+ pwd = QDir::currentPath();
+ return true;
+ }
+ return false;
+}
+
+namespace TestConfiguration {
+ QString localExecutable;
+ QString localQtConf;
+ QString remoteTestPath;
+ QString remoteLibraryPath;
+ QString remoteExecutable;
+ QString remoteResultFile;
+
+ bool testDebug;
+ void init()
+ {
+ testDebug = true;
+ localQtConf = QLatin1String("no");
+ remoteTestPath = QLatin1String("\\Program Files\\qt_test");
+ remoteLibraryPath = remoteTestPath;
+ remoteResultFile = QLatin1String("\\qt_test_results.txt");
+ }
+}
+
+void usage()
+{
+ cout <<
+ "QTestLib options\n"
+ " -functions : Returns a list of current testfunctions\n"
+ " -xml : Outputs results as XML document\n"
+ " -lightxml : Outputs results as stream of XML tags\n"
+ " -o filename: Writes all output into a file\n"
+ " -silent : Only outputs warnings and failures\n"
+ " -v1 : Print enter messages for each testfunction\n"
+ " -v2 : Also print out each QVERIFY/QCOMPARE/QTEST\n"
+ " -vs : Print every signal emitted\n"
+ " -eventdelay ms : Set default delay for mouse and keyboard simulation to ms milliseconds\n"
+ " -keydelay ms : Set default delay for keyboard simulation to ms milliseconds\n"
+ " -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
+ " -keyevent-verbose : Turn on verbose messages for keyboard simulation\n"
+ " -maxwarnings n : Sets the maximum amount of messages to output.\n"
+ " 0 means unlimited, default: 2000\n"
+ " -help : This help\n";
+ cout <<
+ "cetest specific options\n"
+ " -debug : Test debug version[default]\n"
+ " -release : Test release version\n"
+ " -libpath <path> : Remote path to deploy Qt libraries to\n"
+ " -reset : Reset device before starting a test\n"
+ " -awake : Device does not go sleep mode\n"
+ " -qt-delete : Delete the Qt libraries after execution\n"
+ " -project-delete : Delete the project file(s) after execution\n"
+ " -delete : Delete everything deployed after execution\n"
+ " -conf : Specify location of qt.conf file\n"
+ " -f <file> : Specify project file\n"
+ " -cache <file> : Specify .qmake.cache file to use\n"
+ " -d : Increase qmake debugging \n"
+ " -timeout <value> : Specify a timeout value after which the test will be terminated\n"
+ " -1 specifies waiting forever (default)\n"
+ " 0 specifies starting the process detached\n"
+ " >0 wait <value> seconds\n"
+ "\n";
+}
+
+int main(int argc, char **argv)
+{
+ QStringList arguments;
+ for (int i=0; i<argc; ++i)
+ arguments.append(QString::fromLatin1(argv[i]));
+
+ TestConfiguration::init();
+
+ QStringList launchArguments;
+ QString resultFile;
+ QString proFile;
+ QString cacheFile;
+ int timeout = -1;
+ bool cleanupQt = false;
+ bool cleanupProject = false;
+ bool deviceReset = false;
+ bool keepAwake = false;
+
+ for (int i=1; i<arguments.size(); ++i) {
+ if (arguments.at(i).toLower() == QLatin1String("-help")
+ || arguments.at(i).toLower() == QLatin1String("--help")
+ || arguments.at(i).toLower() == QLatin1String("/?")) {
+ usage();
+ return 0;
+ } else if (arguments.at(i).toLower() == QLatin1String("-o")) {
+ if (++i == arguments.size()) {
+ cout << "Error: No output file specified!" << endl;
+ return -1;
+ }
+ resultFile = arguments.at(i);
+ } else if (arguments.at(i).toLower() == QLatin1String("-eventdelay")
+ || arguments.at(i).toLower() == QLatin1String("-keydelay")
+ || arguments.at(i).toLower() == QLatin1String("-mousedelay")
+ || arguments.at(i).toLower() == QLatin1String("-maxwarnings")) {
+ launchArguments.append(arguments.at(i++));
+ if (i == arguments.size()) {
+ cout << "Please specify value for:" << qPrintable(arguments.at(i-1).mid(1)) << endl;
+ return -1;
+ }
+ launchArguments.append(arguments.at(i));
+ } else if (arguments.at(i).toLower() == QLatin1String("-debug")) {
+ TestConfiguration::testDebug = true;
+ Option::before_user_vars.append("CONFIG-=release");
+ Option::before_user_vars.append("CONFIG+=debug");
+ } else if (arguments.at(i).toLower() == QLatin1String("-release")) {
+ TestConfiguration::testDebug = false;
+ Option::before_user_vars.append("CONFIG-=debug");
+ Option::before_user_vars.append("CONFIG+=release");
+ } else if (arguments.at(i).toLower() == QLatin1String("-libpath")) {
+ if (++i == arguments.size()) {
+ cout << "Error: No library path specified!" << endl;
+ return -1;
+ }
+ TestConfiguration::remoteLibraryPath = arguments.at(i);
+ } else if (arguments.at(i).toLower() == QLatin1String("-qt-delete")) {
+ cleanupQt = true;
+ } else if (arguments.at(i).toLower() == QLatin1String("-project-delete")) {
+ cleanupProject = true;
+ } else if (arguments.at(i).toLower() == QLatin1String("-delete")) {
+ cleanupQt = true;
+ cleanupProject = true;
+ } else if (arguments.at(i).toLower() == QLatin1String("-reset")) {
+ deviceReset = true;
+ } else if (arguments.at(i).toLower() == QLatin1String("-awake")) {
+ keepAwake = true;
+ } else if (arguments.at(i).toLower() == QLatin1String("-conf")) {
+ if (++i == arguments.size()) {
+ cout << "Error: No qt.conf file specified!" << endl;
+ return -1;
+ }
+ if (!QFileInfo(arguments.at(i)).exists())
+ cout << "Warning: could not find qt.conf file at:" << qPrintable(arguments.at(i)) << endl;
+ else
+ TestConfiguration::localQtConf = arguments.at(i);
+ } else if (arguments.at(i).toLower() == QLatin1String("-f")) {
+ if (++i == arguments.size()) {
+ cout << "Error: No output file specified!" << endl;
+ return -1;
+ }
+ proFile = arguments.at(i);
+ } else if (arguments.at(i).toLower() == QLatin1String("-cache")) {
+ if (++i == arguments.size()) {
+ cout << "Error: No cache file specified!" << endl;
+ return -1;
+ }
+ cacheFile = arguments.at(i);
+ } else if (arguments.at(i).toLower() == QLatin1String("-d")) {
+ Option::debug_level++;
+ } else if (arguments.at(i).toLower() == QLatin1String("-timeout")) {
+ if (++i == arguments.size()) {
+ cout << "Error: No timeout value specified!" << endl;
+ return -1;
+ }
+ timeout = QString(arguments.at(i)).toInt();
+ } else {
+ launchArguments.append(arguments.at(i));
+ }
+ }
+
+ // check for .pro file
+ if (proFile.isEmpty()) {
+ proFile = QDir::current().dirName() + QLatin1String(".pro");
+ if (!QFileInfo(proFile).exists()) {
+ cout << "Error: Could not find project file in current directory." << endl;
+ return -1;
+ }
+ debugOutput(QString::fromLatin1("Using Project File:").append(proFile),1);
+ }else {
+ if (!QFileInfo(proFile).exists()) {
+ cout << "Error: Project file does not exist " << qPrintable(proFile) << endl;
+ return -1;
+ }
+ }
+
+ Option::before_user_vars.append("CONFIG+=build_pass");
+
+ // read target and deployment rules passing the .pro to use instead of
+ // relying on qmake guessing the .pro to use
+ int qmakeArgc = 2;
+ QByteArray ba(QFile::encodeName(proFile));
+ char* proFileEncodedName = ba.data();
+ char* qmakeArgv[2] = { "qmake.exe", proFileEncodedName };
+
+ Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING;
+ Option::output_dir = qmake_getpwd();
+ if (!cacheFile.isEmpty())
+ Option::mkfile::cachefile = cacheFile;
+ int ret = Option::init(qmakeArgc, qmakeArgv);
+ if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
+ cout << "Error: could not parse " << qPrintable(proFile) << endl;
+ return -1;
+ }
+
+ QMakeProperty prop;
+ QMakeProject project(&prop);
+
+ project.read(proFile);
+ if (project.values("TEMPLATE").join(" ").toLower() != QString("app")) {
+ cout << "Error: Can only test executables!" << endl;
+ return -1;
+ }
+ // Check whether the project is still in debug/release mode after reading
+ // If .pro specifies to be one mode only, we need to accept this
+ if (project.isActiveConfig("debug") && !project.isActiveConfig("release")) {
+ TestConfiguration::testDebug = true;
+ debugOutput("ActiveConfig: debug only in .pro.", 1);
+ }
+ if (!project.isActiveConfig("debug") && project.isActiveConfig("release")) {
+ TestConfiguration::testDebug = false;
+ debugOutput("ActiveConfig: release only in .pro.", 1);
+ }
+
+ // determine what is the real mkspec to use if the default mkspec is being used
+ if (Option::mkfile::qmakespec.endsWith("/default"))
+ project.values("QMAKESPEC") = project.values("QMAKESPEC_ORIGINAL");
+ else
+ project.values("QMAKESPEC") = QStringList() << Option::mkfile::qmakespec;
+
+ // ensure that QMAKESPEC is non-empty .. to meet requirements of QList::at()
+ if (project.values("QMAKESPEC").isEmpty()){
+ cout << "Error: QMAKESPEC not set after parsing " << qPrintable(proFile) << endl;
+ return -1;
+ }
+
+ // ensure that QT_CE_C_RUNTIME is non-empty .. to meet requirements of QList::at()
+ if (project.values("QT_CE_C_RUNTIME").isEmpty()){
+ cout << "Error: QT_CE_C_RUNTIME not defined in mkspec/qconfig.pri " << qPrintable(project.values("QMAKESPEC").join(" "));
+ return -1;
+ }
+
+ QString destDir = project.values("DESTDIR").join(" ");
+ if (!destDir.isEmpty()) {
+ if (QDir::isRelativePath(destDir)) {
+ QFileInfo fi(proFile);
+ if (destDir == QLatin1String("."))
+ destDir = fi.absolutePath() + "/" + destDir + "/" + (TestConfiguration::testDebug ? "debug" : "release");
+ else
+ destDir = fi.absolutePath() + QDir::separator() + destDir;
+ }
+ } else {
+ QFileInfo fi(proFile);
+ destDir = fi.absolutePath();
+ destDir += QDir::separator() + QLatin1String(TestConfiguration::testDebug ? "debug" : "release");
+ }
+
+ DeploymentList qtDeploymentList;
+ DeploymentList projectDeploymentList;
+
+ TestConfiguration::localExecutable = Option::fixPathToLocalOS(destDir + QDir::separator() + project.values("TARGET").join(" ") + QLatin1String(".exe"));
+ TestConfiguration::remoteTestPath = QLatin1String("\\Program Files\\") + Option::fixPathToLocalOS(project.values("TARGET").join(QLatin1String(" ")));
+ if (!arguments.contains(QLatin1String("-libpath"), Qt::CaseInsensitive))
+ TestConfiguration::remoteLibraryPath = TestConfiguration::remoteTestPath;
+
+ QString targetExecutable = Option::fixPathToLocalOS(project.values("TARGET").join(QLatin1String(" ")));
+ int last = targetExecutable.lastIndexOf(QLatin1Char('\\'));
+ targetExecutable = targetExecutable.mid( last == -1 ? 0 : last+1 );
+ TestConfiguration::remoteExecutable = TestConfiguration::remoteTestPath + QDir::separator() + targetExecutable + QLatin1String(".exe");
+ projectDeploymentList.append(CopyItem(TestConfiguration::localExecutable , TestConfiguration::remoteExecutable));
+
+ // deploy
+#ifdef QT_CETEST_NO_ACTIVESYNC
+ CeTcpSyncConnection connection;
+#else
+ ActiveSyncConnection connection;
+#endif
+ if (!connection.connect()) {
+ cout << "Error: Could not connect to device!" << endl;
+ return -1;
+ }
+ DeploymentHandler deployment;
+ deployment.setConnection(&connection);
+
+ deployment.initQtDeploy(&project, qtDeploymentList, TestConfiguration::remoteLibraryPath);
+ deployment.initProjectDeploy(&project , projectDeploymentList, TestConfiguration::remoteTestPath);
+
+ // add qt.conf
+ if (TestConfiguration::localQtConf != QLatin1String("no")) {
+ QString qtConfOrigin = QFileInfo(TestConfiguration::localQtConf).absoluteFilePath();
+ QString qtConfTarget = Option::fixPathToLocalOS(TestConfiguration::remoteTestPath + QDir::separator() + QLatin1String("qt.conf"));
+ projectDeploymentList.append(CopyItem(qtConfOrigin, qtConfTarget));
+ }
+
+ if (!deployment.deviceDeploy(qtDeploymentList) || !deployment.deviceDeploy(projectDeploymentList)) {
+ cout << "Error: Could not copy file(s) to device" << endl;
+ return -1;
+ }
+ // device power mode
+ if (keepAwake)
+ {
+ int retVal = 0;
+ if (!connection.setDeviceAwake(true, &retVal)) {
+ cout << "Error: Could not set unattended mode on device" << endl;
+ return -1;
+ }
+ }
+
+ // reset device
+ if (deviceReset)
+ {
+ if (!connection.resetDevice()) {
+ //if (!connection.toggleDevicePower( &retVal)) {
+ cout << "Error: Could not reset the device" << endl;
+ return -1;
+ }
+ cout << " Entering sleep after reset for " << SLEEP_AFTER_RESET / 1000 << " seconds ... " << endl;
+ Sleep(SLEEP_AFTER_RESET);
+ cout << " ... woke up. " << endl;
+ connection.disconnect();
+ // reconnect after reset
+ int retryCount = 21;
+ while (--retryCount)
+ {
+ if (!connection.connect())
+ Sleep(SLEEP_RECONNECT);
+ else
+ break;
+ }
+ if (!connection.isConnected())
+ {
+ cout << "Error: Could not connect to device!" << endl;
+ return -1;
+ }
+ }
+
+ // launch
+ launchArguments.append("-o");
+ launchArguments.append(TestConfiguration::remoteResultFile);
+
+ cout << endl << "Remote Launch:" << qPrintable(TestConfiguration::remoteExecutable) << " " << qPrintable(launchArguments.join(" ")) << endl;
+ if (!connection.execute(TestConfiguration::remoteExecutable, launchArguments.join(" "), timeout)) {
+ cout << "Error: Could not execute target file" << endl;
+ return -1;
+ }
+
+
+ // copy result file
+ // show results
+ if (resultFile.isEmpty()) {
+ QString tempResultFile = Option::fixPathToLocalOS(QDir::tempPath() + "/qt_ce_temp_result_file.txt");
+ if (connection.copyFileFromDevice(TestConfiguration::remoteResultFile, tempResultFile)) {
+ QFile file(tempResultFile);
+ QByteArray arr;
+ if (file.open(QIODevice::ReadOnly)) {
+ arr = file.readAll();
+ cout << arr.constData() << endl;
+ }
+ file.close();
+ file.remove();
+ }
+ } else {
+ connection.copyFileFromDevice(TestConfiguration::remoteResultFile, resultFile);
+ }
+
+ // delete
+ connection.deleteFile(TestConfiguration::remoteResultFile);
+ if (cleanupQt)
+ deployment.cleanup(qtDeploymentList);
+ if (cleanupProject)
+ deployment.cleanup(projectDeploymentList);
+ return 0;
+}
diff --git a/src/qtestlib/wince/cetest/qmake_include.pri b/src/qtestlib/wince/cetest/qmake_include.pri
new file mode 100644
index 000000000..35fbc64a6
--- /dev/null
+++ b/src/qtestlib/wince/cetest/qmake_include.pri
@@ -0,0 +1,13 @@
+#qmake source files needed for cetest
+HEADERS += \
+ $$QT_SOURCE_TREE/qmake/option.h
+SOURCES += \
+ $$QT_SOURCE_TREE/qmake/option.cpp \
+ $$QT_SOURCE_TREE/qmake/project.cpp \
+ $$QT_SOURCE_TREE/qmake/property.cpp \
+ $$QT_SOURCE_TREE/qmake/generators/metamakefile.cpp \
+ $$QT_SOURCE_TREE/qmake/generators/symbian/initprojectdeploy_symbian.cpp \
+ $$QT_SOURCE_TREE/tools/shared/symbian/epocroot.cpp \
+ $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp
+
+DEFINES += QT_QMAKE_PARSER_ONLY
diff --git a/src/qtestlib/wince/cetest/remoteconnection.cpp b/src/qtestlib/wince/cetest/remoteconnection.cpp
new file mode 100644
index 000000000..aa3059cd3
--- /dev/null
+++ b/src/qtestlib/wince/cetest/remoteconnection.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "remoteconnection.h"
+
+QByteArray strwinerror(DWORD errorcode)
+{
+ QByteArray out(512, 0);
+
+ DWORD ok = FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ 0,
+ errorcode,
+ 0,
+ out.data(),
+ out.size(),
+ 0
+ );
+
+ if (!ok) {
+ qsnprintf(out.data(), out.size(),
+ "(error %d; additionally, error %d while looking up error string)",
+ (int)errorcode, (int)GetLastError());
+ }
+ else {
+ out.resize(qstrlen(out.constData()));
+ if (out.endsWith("\r\n"))
+ out.chop(2);
+
+ /* Append error number to error message for good measure */
+ out.append(" (0x");
+ out.append(QByteArray::number(uint(errorcode), 16).rightJustified(8, '0'));
+ out.append(")");
+ }
+ return out;
+}
+
+AbstractRemoteConnection::AbstractRemoteConnection()
+{
+}
+
+AbstractRemoteConnection::~AbstractRemoteConnection()
+{
+}
+
+
+// Slow but should be ok...
+bool AbstractRemoteConnection::moveFile(const QString &src, const QString &dest, bool FailIfExists)
+{
+ bool result = copyFile(src, dest, FailIfExists);
+ deleteFile(src);
+ return result;
+}
+
+// Slow but should be ok...
+bool AbstractRemoteConnection::moveDirectory(const QString &src, const QString &dest, bool recursive)
+{
+ bool result = copyDirectory(src, dest, true);
+ deleteDirectory(src, recursive);
+ return result;
+}
+
diff --git a/src/qtestlib/wince/cetest/remoteconnection.h b/src/qtestlib/wince/cetest/remoteconnection.h
new file mode 100644
index 000000000..d2671397d
--- /dev/null
+++ b/src/qtestlib/wince/cetest/remoteconnection.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef REMOTECONNECTION_H
+#define REMOTECONNECTION_H
+
+#include <QtCore/QString>
+#include <QtCore/QVariant>
+#include <windows.h>
+class AbstractRemoteConnection
+{
+public:
+ AbstractRemoteConnection();
+ virtual ~AbstractRemoteConnection();
+
+ virtual bool connect(QVariantList&) = 0;
+ virtual void disconnect() = 0;
+ virtual bool isConnected() const = 0;
+
+ // These functions are designed for transfer between desktop and device
+ // Caution: deviceDest path has to be device specific (eg. no drive letters for CE)
+ virtual bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false) = 0;
+ virtual bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true) = 0;
+ virtual bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false) = 0;
+ virtual bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true) = 0;
+
+ // For "intelligent deployment" we need to investigate on filetimes on the device
+ virtual bool timeStampForLocalFileTime(FILETIME*) const = 0;
+ virtual bool fileCreationTime(const QString &fileName, FILETIME*) const = 0;
+
+ // These functions only work on files existing on the device
+ virtual bool copyFile(const QString&, const QString&, bool failIfExists = false) = 0;
+ virtual bool copyDirectory(const QString&, const QString&, bool recursive = true) = 0;
+ virtual bool deleteFile(const QString&) = 0;
+ virtual bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false) = 0;
+ bool moveFile(const QString&, const QString&, bool FailIfExists = false);
+ bool moveDirectory(const QString&, const QString&, bool recursive = true);
+
+ virtual bool createDirectory(const QString&, bool deleteBefore=false) = 0;
+
+ virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0;
+};
+
+QByteArray strwinerror(DWORD);
+
+#endif
diff --git a/src/qtestlib/wince/remotelib/commands.cpp b/src/qtestlib/wince/remotelib/commands.cpp
new file mode 100644
index 000000000..32d6e33ae
--- /dev/null
+++ b/src/qtestlib/wince/remotelib/commands.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "commands.h"
+#include <Pm.h>
+#include <Pmpolicy.h>
+
+
+#define CLEAN_FAIL(a) {delete appName; \
+ delete arguments; \
+ return (a); }
+
+int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
+{
+ if (!stream)
+ return -1;
+
+ DWORD bytesRead;
+ int appLength;
+ wchar_t* appName = 0;
+ int argumentsLength;
+ wchar_t* arguments = 0;
+ int timeout = -1;
+ int returnValue = -2;
+ DWORD error = 0;
+
+ if (S_OK != stream->Read(&appLength, sizeof(appLength), &bytesRead))
+ CLEAN_FAIL(-2);
+ appName = (wchar_t*) malloc(sizeof(wchar_t)*(appLength + 1));
+ if (S_OK != stream->Read(appName, sizeof(wchar_t)*appLength, &bytesRead))
+ CLEAN_FAIL(-2);
+ appName[appLength] = '\0';
+
+ if (S_OK != stream->Read(&argumentsLength, sizeof(argumentsLength), &bytesRead))
+ CLEAN_FAIL(-2);
+ arguments = (wchar_t*) malloc(sizeof(wchar_t)*(argumentsLength + 1));
+ if (S_OK != stream->Read(arguments, sizeof(wchar_t)*argumentsLength, &bytesRead))
+ CLEAN_FAIL(-2);
+ arguments[argumentsLength] = '\0';
+
+ if (S_OK != stream->Read(&timeout, sizeof(timeout), &bytesRead))
+ CLEAN_FAIL(-2);
+
+ bool result = qRemoteExecute(appName, arguments, &returnValue, &error, timeout);
+
+ if (timeout != 0) {
+ if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead))
+ CLEAN_FAIL(-4);
+ if (S_OK != stream->Write(&error, sizeof(error), &bytesRead))
+ CLEAN_FAIL(-5);
+ }
+ delete appName;
+ delete arguments;
+ // We need to fail here for the execute, otherwise the calling application will wait
+ // forever for the returnValue.
+ if (!result)
+ return -3;
+ return S_OK;
+}
+
+
+bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, DWORD* error, int timeout)
+{
+ *error = 0;
+
+ if (!program)
+ return false;
+
+ PROCESS_INFORMATION pid;
+ if (!CreateProcess(program, arguments, NULL, NULL, false, 0, NULL, NULL, NULL, &pid)) {
+ *error = GetLastError();
+ wprintf(L"Could not launch: %s\n", program);
+ return false;
+ }
+
+ // Timeout is in seconds
+ DWORD waitingTime = (timeout == -1) ? INFINITE : timeout * 1000;
+
+ if (waitingTime != 0) {
+ DWORD waitStatus = WaitForSingleObject(pid.hProcess, waitingTime);
+ if (waitStatus == WAIT_TIMEOUT) {
+ TerminateProcess(pid.hProcess, 2);
+ return false;
+ } else if (waitStatus == WAIT_OBJECT_0 && returnValue) {
+ *returnValue = 0;
+ DWORD exitCode;
+ if (GetExitCodeProcess(pid.hProcess, &exitCode))
+ *returnValue = exitCode;
+ }
+ }
+ return true;
+}
+/**
+\brief Reset the device.
+*/
+int qRemoteSoftReset(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
+{
+ //POWER_STATE_ON On state
+ //POWER_STATE_OFF Off state
+ //POWER_STATE_CRITICAL Critical state
+ //POWER_STATE_BOOT Boot state
+ //POWER_STATE_IDLE Idle state
+ //POWER_STATE_SUSPEND Suspend state
+ //POWER_STATE_RESET Reset state
+
+ DWORD returnValue = SetSystemPowerState(0, POWER_STATE_RESET, POWER_FORCE);
+ return returnValue;
+}
+
+/**
+\brief Toggle the unattended powermode of the device
+*/
+int qRemoteToggleUnattendedPowerMode(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
+{
+ if (!stream)
+ return -1;
+
+ DWORD bytesRead;
+ int toggleVal = 0;
+ int returnValue = S_OK;
+
+ if (S_OK != stream->Read(&toggleVal, sizeof(toggleVal), &bytesRead))
+ return -2;
+
+ //PPN_REEVALUATESTATE 0x0001 Reserved. Set dwData to zero (0).
+ //PPN_POWERCHANGE 0x0002 Reserved. Set dwData to zero (0).
+ //PPN_UNATTENDEDMODE 0x0003 Set dwData to TRUE or FALSE.
+ //PPN_SUSPENDKEYPRESSED or
+ //PPN_POWERBUTTONPRESSED 0x0004 Reserved. Set dwData to zero (0).
+ //PPN_SUSPENDKEYRELEASED 0x0005 Reserved. Set dwData to zero (0).
+ //PPN_APPBUTTONPRESSED 0x0006 Reserved. Set dwData to zero (0).
+ //PPN_OEMBASE Greater than or equal to 0x10000
+ //You can define higher values, such as 0x10001, 0x10002, and so on.
+ // Reserved. Set dwData to zero (0).
+ returnValue = PowerPolicyNotify(PPN_UNATTENDEDMODE, toggleVal);
+
+ if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead))
+ return -3;
+ else
+ return S_OK;
+}
+
+/**
+\brief Virtually press the power button of the device
+*/
+int qRemotePowerButton(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
+{
+ if (!stream)
+ return -1;
+
+ DWORD bytesRead;
+ int toggleVal = 0;
+ int returnValue = S_OK;
+
+ if (S_OK != stream->Read(&toggleVal, sizeof(toggleVal), &bytesRead))
+ return -2;
+
+ //PPN_REEVALUATESTATE 0x0001 Reserved. Set dwData to zero (0).
+ //PPN_POWERCHANGE 0x0002 Reserved. Set dwData to zero (0).
+ //PPN_UNATTENDEDMODE 0x0003 Set dwData to TRUE or FALSE.
+ //PPN_SUSPENDKEYPRESSED or
+ //PPN_POWERBUTTONPRESSED 0x0004 Reserved. Set dwData to zero (0).
+ //PPN_SUSPENDKEYRELEASED 0x0005 Reserved. Set dwData to zero (0).
+ //PPN_APPBUTTONPRESSED 0x0006 Reserved. Set dwData to zero (0).
+ //PPN_OEMBASE Greater than or equal to 0x10000
+ //You can define higher values, such as 0x10001, 0x10002, and so on.
+ // Reserved. Set dwData to zero (0).
+ returnValue = PowerPolicyNotify(PPN_POWERBUTTONPRESSED, 0);
+
+ if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead))
+ return -3;
+ else
+ return S_OK;
+}
+
diff --git a/src/qtestlib/wince/remotelib/commands.h b/src/qtestlib/wince/remotelib/commands.h
new file mode 100644
index 000000000..959aed625
--- /dev/null
+++ b/src/qtestlib/wince/remotelib/commands.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QREMOTECOMMANDS_H
+#define QREMOTECOMMANDS_H
+#include <winbase.h>
+#include <rapi.h>
+
+extern "C" {
+ int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*);
+ int __declspec(dllexport) qRemoteSoftReset(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream);
+ int __declspec(dllexport) qRemoteToggleUnattendedPowerMode(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream);
+ int __declspec(dllexport) qRemotePowerButton(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream);
+ bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1);
+}
+
+#endif
diff --git a/src/qtestlib/wince/remotelib/remotelib.pro b/src/qtestlib/wince/remotelib/remotelib.pro
new file mode 100644
index 000000000..dc61c7ffd
--- /dev/null
+++ b/src/qtestlib/wince/remotelib/remotelib.pro
@@ -0,0 +1,15 @@
+TEMPLATE = lib
+CONFIG += dll
+CONFIG -= staticlib
+TARGET = QtRemote
+DESTDIR = ../../../../lib
+DEPENDPATH += .
+INCLUDEPATH += .
+QT =
+# Input
+HEADERS += commands.h
+SOURCES += commands.cpp
+
+INCLUDEPATH += $$QT_CE_RAPI_INC
+LIBS += -L$$QT_CE_RAPI_LIB
+
diff --git a/src/qtestlib/wince/wince.pro b/src/qtestlib/wince/wince.pro
new file mode 100644
index 000000000..7c88d6572
--- /dev/null
+++ b/src/qtestlib/wince/wince.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+wince*:SUBDIRS = remotelib \ No newline at end of file
diff --git a/src/qttracereplay/main.cpp b/src/qttracereplay/main.cpp
new file mode 100644
index 000000000..771801362
--- /dev/null
+++ b/src/qttracereplay/main.cpp
@@ -0,0 +1,351 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include <QtDebug>
+
+#include <private/qpaintengineex_p.h>
+#include <private/qpaintbuffer_p.h>
+
+class ReplayWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ ReplayWidget(const QString &filename, int from, int to, bool single, int frame);
+
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *event);
+
+public slots:
+ void updateRect();
+
+public:
+ QList<QRegion> updates;
+ QPaintBuffer buffer;
+
+ int currentFrame;
+ int currentIteration;
+ QTime timer;
+
+ QList<uint> visibleUpdates;
+
+ QVector<uint> iterationTimes;
+ QString filename;
+
+ int from;
+ int to;
+
+ bool single;
+
+ int frame;
+ int currentCommand;
+};
+
+void ReplayWidget::updateRect()
+{
+ if (frame >= 0 && !updates.isEmpty())
+ update(updates.at(frame));
+ else if (!visibleUpdates.isEmpty())
+ update(updates.at(visibleUpdates.at(currentFrame)));
+}
+
+const int singleFrameRepeatsPerCommand = 100;
+const int singleFrameIterations = 4;
+
+void ReplayWidget::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+
+ QTimer::singleShot(0, this, SLOT(updateRect()));
+
+// p.setClipRegion(frames.at(currentFrame).updateRegion);
+
+ if (frame >= 0) {
+ int start = buffer.frameStartIndex(frame);
+ int end = buffer.frameEndIndex(frame);
+
+ iterationTimes.resize(end - start);
+
+ int saveRestoreStackDepth = buffer.processCommands(&p, start, start + currentCommand);
+
+ for (int i = 0; i < saveRestoreStackDepth; ++i)
+ p.restore();
+
+ const int repeats = currentIteration >= 3 ? singleFrameRepeatsPerCommand : 1;
+
+ ++currentFrame;
+ if (currentFrame == repeats) {
+ currentFrame = 0;
+ if (currentIteration >= 3) {
+ iterationTimes[currentCommand - 1] = qMin(iterationTimes[currentCommand - 1], uint(timer.elapsed()));
+ timer.restart();
+ }
+
+ if (currentIteration >= singleFrameIterations + 3) {
+ printf(" # | ms | description\n");
+ printf("------+---------+------------------------------------------------------------\n");
+
+ qSort(iterationTimes);
+
+ int sum = 0;
+ for (int i = 0; i < iterationTimes.size(); ++i) {
+ int delta = iterationTimes.at(i);
+ if (i > 0)
+ delta -= iterationTimes.at(i-1);
+ sum += delta;
+ qreal deltaF = delta / qreal(repeats);
+ printf("%.5d | %.5f | %s\n", i, deltaF, qPrintable(buffer.commandDescription(start + i)));
+ }
+ printf("Total | %.5f | Total frame time\n", sum / qreal(repeats));
+ deleteLater();
+ return;
+ }
+
+ if (start + currentCommand >= end) {
+ currentCommand = 1;
+ ++currentIteration;
+ if (currentIteration == 3) {
+ timer.start();
+ iterationTimes.fill(uint(-1));
+ }
+ if (currentIteration >= 3 && currentIteration < singleFrameIterations + 3)
+ printf("Profiling iteration %d of %d\n", currentIteration - 2, singleFrameIterations);
+ } else {
+ ++currentCommand;
+ }
+ }
+
+ return;
+ }
+
+ buffer.draw(&p, visibleUpdates.at(currentFrame));
+
+ ++currentFrame;
+ if (currentFrame >= visibleUpdates.size()) {
+ currentFrame = 0;
+ ++currentIteration;
+
+ if (single) {
+ deleteLater();
+ return;
+ }
+
+ if (currentIteration == 3)
+ timer.start();
+ else if (currentIteration > 3) {
+ iterationTimes << timer.elapsed();
+ timer.restart();
+
+ if (iterationTimes.size() >= 3) {
+ qreal mean = 0;
+ qreal stddev = 0;
+ uint min = INT_MAX;
+
+ for (int i = 0; i < iterationTimes.size(); ++i) {
+ mean += iterationTimes.at(i);
+ min = qMin(min, iterationTimes.at(i));
+ }
+
+ mean /= qreal(iterationTimes.size());
+
+ for (int i = 0; i < iterationTimes.size(); ++i) {
+ qreal delta = iterationTimes.at(i) - mean;
+ stddev += delta * delta;
+ }
+
+ stddev = qSqrt(stddev / iterationTimes.size());
+
+ qSort(iterationTimes.begin(), iterationTimes.end());
+ uint median = iterationTimes.at(iterationTimes.size() / 2);
+
+ stddev = 100 * stddev / mean;
+
+ if (iterationTimes.size() >= 10 || stddev < 4) {
+ printf("%s, iterations: %d, frames: %d, min(ms): %d, median(ms): %d, stddev: %f %%, max(fps): %f\n", qPrintable(filename),
+ iterationTimes.size(), visibleUpdates.size(), min, median, stddev, 1000. * visibleUpdates.size() / min);
+ deleteLater();
+ return;
+ }
+ }
+ }
+ }
+}
+
+void ReplayWidget::resizeEvent(QResizeEvent *)
+{
+ visibleUpdates.clear();
+
+ QRect bounds = rect();
+
+ int first = qMax(0, from);
+ int last = qMin(unsigned(to), unsigned(updates.size()));
+ for (int i = first; i < last; ++i) {
+ if (updates.at(i).intersects(bounds))
+ visibleUpdates << i;
+ }
+
+ int range = last - first;
+
+ if (visibleUpdates.size() != range)
+ printf("Warning: skipped %d frames due to limited resolution\n", range - visibleUpdates.size());
+
+}
+
+ReplayWidget::ReplayWidget(const QString &filename_, int from_, int to_, bool single_, int frame_)
+ : currentFrame(0)
+ , currentIteration(0)
+ , filename(filename_)
+ , from(from_)
+ , to(to_)
+ , single(single_)
+ , frame(frame_)
+ , currentCommand(1)
+{
+ setWindowTitle(filename);
+ QFile file(filename);
+
+ if (!file.open(QIODevice::ReadOnly)) {
+ printf("Failed to load input file '%s'\n", qPrintable(filename_));
+ return;
+ }
+
+ QDataStream in(&file);
+
+ char *data;
+ uint size;
+ in.readBytes(data, size);
+ bool isTraceFile = size >= 7 && qstrncmp(data, "qttrace", 7) == 0;
+
+ uint version = 0;
+ if (size == 9 && qstrncmp(data, "qttraceV2", 9) == 0) {
+ in.setFloatingPointPrecision(QDataStream::SinglePrecision);
+ in >> version;
+ }
+
+ if (!isTraceFile) {
+ printf("File '%s' is not a trace file\n", qPrintable(filename_));
+ return;
+ }
+
+ in >> buffer >> updates;
+ printf("Read paint buffer version %d with %d frames\n", version, buffer.numFrames());
+
+ resize(buffer.boundingRect().size().toSize());
+
+ setAutoFillBackground(false);
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ QTimer::singleShot(10, this, SLOT(updateRect()));
+}
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ if (argc <= 1 || qstrcmp(argv[1], "-h") == 0 || qstrcmp(argv[1], "--help") == 0) {
+ printf("Replays a tracefile generated with '-graphicssystem trace'\n");
+ printf("Usage:\n > %s [OPTIONS] [traceFile]\n", argv[0]);
+ printf("OPTIONS\n"
+ " --range=from-to to specify a frame range.\n"
+ " --singlerun to do only one run (without statistics)\n"
+ " --instrumentframe=frame to instrument a single frame\n");
+ return 1;
+ }
+
+ QFile file(app.arguments().last());
+ if (!file.exists()) {
+ printf("%s does not exist\n", qPrintable(app.arguments().last()));
+ return 1;
+ }
+
+ bool single = false;
+
+ int frame = -1;
+
+ int from = 0;
+ int to = -1;
+ for (int i = 1; i < app.arguments().size() - 1; ++i) {
+ QString arg = app.arguments().at(i);
+ if (arg.startsWith(QLatin1String("--range="))) {
+ QString rest = arg.mid(8);
+ QStringList components = rest.split(QLatin1Char('-'));
+
+ bool ok1 = false;
+ bool ok2 = false;
+ int fromCandidate = 0;
+ int toCandidate = 0;
+ if (components.size() == 2) {
+ fromCandidate = components.first().toInt(&ok1);
+ toCandidate = components.last().toInt(&ok2);
+ }
+
+ if (ok1 && ok2) {
+ from = fromCandidate;
+ to = toCandidate;
+ } else {
+ printf("ERROR: malformed syntax in argument %s\n", qPrintable(arg));
+ }
+ } else if (arg == QLatin1String("--singlerun")) {
+ single = true;
+ } else if (arg.startsWith(QLatin1String("--instrumentframe="))) {
+ QString rest = arg.mid(18);
+ bool ok = false;
+ int frameCandidate = rest.toInt(&ok);
+ if (ok) {
+ frame = frameCandidate;
+ } else {
+ printf("ERROR: malformed syntax in argument %s\n", qPrintable(arg));
+ }
+ } else {
+ printf("Unrecognized argument: %s\n", qPrintable(arg));
+ return 1;
+ }
+ }
+
+ ReplayWidget *widget = new ReplayWidget(app.arguments().last(), from, to, single, frame);
+
+ if (!widget->updates.isEmpty()) {
+ widget->show();
+ return app.exec();
+ }
+
+}
+#include "main.moc"
diff --git a/src/qttracereplay/qttracereplay.pro b/src/qttracereplay/qttracereplay.pro
new file mode 100644
index 000000000..cc5b98dc0
--- /dev/null
+++ b/src/qttracereplay/qttracereplay.pro
@@ -0,0 +1,15 @@
+TEMPLATE = app
+
+DESTDIR = ../../bin
+
+DEPENDPATH += .
+INCLUDEPATH += . ../../src/3rdparty/harfbuzz/src
+TARGET = qttracereplay
+
+# Input
+SOURCES += main.cpp
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+CONFIG += console
diff --git a/src/qvfb/README b/src/qvfb/README
new file mode 100644
index 000000000..bfab467e0
--- /dev/null
+++ b/src/qvfb/README
@@ -0,0 +1,51 @@
+Qt for Embedded Linux Virtual Framebuffer
+===============================
+
+The virtual frame buffer allows a Qt for Embedded Linux program to be developed
+on your desktop machine, without switching between consoles and X11. The virtual
+framebuffer consists of a shared memory region (the virtual frame buffer)
+and a utility to display the framebuffer in a window. The display is updated
+periodically, so you will see discrete snapshots of the framebuffer rather
+than each individual drawing operation. For this reason drawing problems
+such as flickering may not be apparent until the program is run using a real
+framebuffer.
+
+To use the virtual framebuffer:
+
+1. Ensure QT_NO_QWS_VFB is not set in qconfig.h (when you configure Qt,
+ add the -qvfb option).
+2. Start qvfb (qvfb should be compiled as a normal Qt for X11 application,
+ NOT as a Qt for Embedded Linux application!).
+3. Start a Qt for Embedded Linux server (i.e. construct QApplication with
+ QApplication::GuiServer flag, or run a client with the -qws option).
+
+qvfb supports the following command line options:
+
+[-width width] the width of the virtual framebuffer (default: 240).
+[-height height] the height of the virtual framebuffer (default: 320).
+[-depth depth] the depth of the virtual framebuffer (1,4,8 or 32, default: 8).
+[-nocursor] do not display the X11 cursor in the framebuffer window.
+[-qwsdisplay] the Qt for Embedded Linux display ID, e.g. -qwsdisplay :1 (default :0).
+[-skin skinfile] tells qvfb to load a skin file, e.g. -skin pda.skin
+
+Please refer to the file "pda.skin" as an example of what a skin file looks like.
+The format for skin files is:
+ Image filename of skin with buttons in their up positions
+ Image filename of skin with buttons in their down positions
+ X offset of top left corner of the virtual screen on the skin image
+ Y offset of top left corner of the virtual screen on the skin image
+ Width of the virtual screen on the skin image
+ Height of the virtual screen on the skin image
+ Number of defined button regions
+Then for each button region the format is:
+ Button identifier
+ Qt scan codes to generate for the button
+ Top left X coordinate of the button region
+ Top left Y coordinate of the button region
+ Bottom right X coordinate of the button region
+ Bottom right Y coordinate of the button region
+
+The virtual framebuffer is a development tool only. No security issues have
+been considered in the virtual framebuffer design. It should not be used
+in a production environment and QT_NO_QWS_VFB should always be in force
+in production libraries.
diff --git a/src/qvfb/config.ui b/src/qvfb/config.ui
new file mode 100644
index 000000000..282a226ee
--- /dev/null
+++ b/src/qvfb/config.ui
@@ -0,0 +1,2472 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>Config</class>
+ <widget class="QDialog" name="Config">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>690</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Configure</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="ButtonGroup1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Size</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="size_176_220">
+ <property name="text">
+ <string>176x220 &quot;SmartPhone&quot;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_240_320">
+ <property name="text">
+ <string>240x320 &quot;PDA&quot;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_320_240">
+ <property name="text">
+ <string>320x240 &quot;TV&quot; / &quot;QVGA&quot;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_640_480">
+ <property name="text">
+ <string>640x480 &quot;VGA&quot;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_800_480">
+ <property name="text">
+ <string>800x480</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_800_600">
+ <property name="text">
+ <string>800x600</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_1024_768">
+ <property name="text">
+ <string>1024x768</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="size_custom">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Custom</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="size_width">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>1280</number>
+ </property>
+ <property name="singleStep">
+ <number>16</number>
+ </property>
+ <property name="value">
+ <number>400</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="size_height">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>1024</number>
+ </property>
+ <property name="singleStep">
+ <number>16</number>
+ </property>
+ <property name="value">
+ <number>300</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="ButtonGroup2">
+ <property name="title">
+ <string>Depth</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QRadioButton" name="depth_1">
+ <property name="text">
+ <string>1 bit monochrome</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_2gray">
+ <property name="text">
+ <string>2 bit grayscale</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_4gray">
+ <property name="text">
+ <string>4 bit grayscale</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_8">
+ <property name="text">
+ <string>8 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_12">
+ <property name="text">
+ <string>12 (16) bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_15">
+ <property name="text">
+ <string>15 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_16">
+ <property name="text">
+ <string>16 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_18">
+ <property name="text">
+ <string>18 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_24">
+ <property name="text">
+ <string>24 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_32">
+ <property name="text">
+ <string>32 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_32_argb">
+ <property name="text">
+ <string>32 bit ARGB</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="rgbSwapped">
+ <property name="toolTip">
+ <string>Swap red and blue channels</string>
+ </property>
+ <property name="text">
+ <string>BGR format</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1_3">
+ <property name="text">
+ <string>Skin</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="skin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>None</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="touchScreen">
+ <property name="text">
+ <string>Emulate touch screen (no mouse move)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="lcdScreen">
+ <property name="text">
+ <string>Emulate LCD screen (Only with fixed zoom of 3.0 times magnification)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth &lt;i&gt;above&lt;/i&gt;. You may freely modify the Gamma &lt;i&gt;below&lt;/i&gt;.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="GroupBox1">
+ <property name="title">
+ <string>Gamma</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="6" column="0">
+ <widget class="QLabel" name="TextLabel3">
+ <property name="text">
+ <string>Blue</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QSlider" name="bslider">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>38</red>
+ <green>38</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>38</red>
+ <green>38</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>38</red>
+ <green>38</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2">
+ <widget class="QLabel" name="blabel">
+ <property name="text">
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="TextLabel2">
+ <property name="text">
+ <string>Green</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QSlider" name="gslider">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>38</red>
+ <green>255</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>127</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>170</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>38</red>
+ <green>255</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>127</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>170</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>38</red>
+ <green>255</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>127</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>170</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QLabel" name="glabel">
+ <property name="text">
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel7">
+ <property name="text">
+ <string>All</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="TextLabel8">
+ <property name="text">
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSlider" name="gammaslider">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="TextLabel1_2">
+ <property name="text">
+ <string>Red</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="rlabel">
+ <property name="text">
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSlider" name="rslider">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>38</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>38</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>38</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0" colspan="3">
+ <widget class="QPushButton" name="PushButton3">
+ <property name="text">
+ <string>Set all to 1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" rowspan="9">
+ <widget class="GammaView" name="MyCustomWidget1" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonOk">
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel">
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>GammaView</class>
+ <extends></extends>
+ <header>gammaview.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>size_width</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>size_custom</receiver>
+ <slot>click()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>152</x>
+ <y>193</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>94</x>
+ <y>199</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>size_height</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>size_custom</receiver>
+ <slot>click()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>259</x>
+ <y>196</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>64</x>
+ <y>188</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qvfb/gammaview.h b/src/qvfb/gammaview.h
new file mode 100644
index 000000000..47bd61423
--- /dev/null
+++ b/src/qvfb/gammaview.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GAMMAVIEW_H
+#define GAMMAVIEW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class GammaView: public QWidget
+{
+ Q_OBJECT
+public:
+ GammaView( QWidget *parent = 0, Qt::WindowFlags f = 0 )
+ : QWidget(parent,f) { }
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/images/logo-nt.png b/src/qvfb/images/logo-nt.png
new file mode 100644
index 000000000..92f77d86b
--- /dev/null
+++ b/src/qvfb/images/logo-nt.png
Binary files differ
diff --git a/src/qvfb/images/logo.png b/src/qvfb/images/logo.png
new file mode 100644
index 000000000..009317778
--- /dev/null
+++ b/src/qvfb/images/logo.png
Binary files differ
diff --git a/src/qvfb/main.cpp b/src/qvfb/main.cpp
new file mode 100644
index 000000000..d06bd1462
--- /dev/null
+++ b/src/qvfb/main.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfb.h"
+
+#include <QApplication>
+#include <QRegExp>
+#include <QLibraryInfo>
+#include <QLocale>
+#include <QTranslator>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#ifdef Q_WS_X11
+#include <QX11Info>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+void fn_quit_qvfb(int)
+{
+ // pretend that we have quit normally
+ qApp->quit();
+}
+
+
+void usage( const char *app )
+{
+ printf( "Usage: %s [-width width] [-height height] [-depth depth] [-zoom zoom]"
+ "[-mmap] [-nocursor] [-qwsdisplay :id] [-x11display :id] [-skin skindirectory]\n"
+ "Supported depths: 1, 4, 8, 12, 15, 16, 18, 24, 32\n", app );
+}
+int qvfb_protocol = 0;
+
+int runQVfb( int argc, char *argv[] )
+{
+ Q_INIT_RESOURCE(qvfb);
+
+ QApplication app( argc, argv );
+
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("qvfb_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+
+ int width = 0;
+ int height = 0;
+ int depth = -32; // default, but overridable by skin
+ bool depthSet = false;
+ int rotation = 0;
+ bool cursor = true;
+ QVFb::DisplayType displayType = QVFb::QWS;
+ double zoom = 1.0;
+ QString displaySpec( ":0" );
+ QString skin;
+
+ for ( int i = 1; i < argc; i++ ){
+ QString arg = argv[i];
+ if ( arg == "-width" ) {
+ width = atoi( argv[++i] );
+ } else if ( arg == "-height" ) {
+ height = atoi( argv[++i] );
+ } else if ( arg == "-skin" ) {
+ skin = argv[++i];
+ } else if ( arg == "-depth" ) {
+ depth = atoi( argv[++i] );
+ depthSet = true;
+ } else if ( arg == "-nocursor" ) {
+ cursor = false;
+ } else if ( arg == "-mmap" ) {
+ qvfb_protocol = 1;
+ } else if ( arg == "-zoom" ) {
+ zoom = atof( argv[++i] );
+ } else if ( arg == "-qwsdisplay" ) {
+ displaySpec = argv[++i];
+ displayType = QVFb::QWS;
+#ifdef Q_WS_X11
+ } else if ( arg == "-x11display" ) {
+ displaySpec = argv[++i];
+ displayType = QVFb::X11;
+
+ // Usually only the default X11 depth will work with Xnest,
+ // so override the default of 32 with the actual X11 depth.
+ if (!depthSet)
+ depth = -QX11Info::appDepth(); // default, but overridable by skin
+#endif
+ } else {
+ printf( "Unknown parameter %s\n", arg.toLatin1().constData() );
+ usage( argv[0] );
+ exit(1);
+ }
+ }
+
+ int displayId = 0;
+ QRegExp r( ":[0-9]+" );
+ int m = r.indexIn( displaySpec, 0 );
+ int len = r.matchedLength();
+ if ( m >= 0 ) {
+ displayId = displaySpec.mid( m+1, len-1 ).toInt();
+ }
+ QRegExp rotRegExp( "Rot[0-9]+" );
+ m = rotRegExp.indexIn( displaySpec, 0 );
+ len = rotRegExp.matchedLength();
+ if ( m >= 0 ) {
+ rotation = displaySpec.mid( m+3, len-3 ).toInt();
+ }
+
+ signal(SIGINT, fn_quit_qvfb);
+ signal(SIGTERM, fn_quit_qvfb);
+
+ QVFb mw( displayId, width, height, depth, rotation, skin, displayType );
+ mw.setZoom(zoom);
+ //app.setMainWidget( &mw );
+ mw.enableCursor(cursor);
+ mw.show();
+
+ return app.exec();
+}
+
+QT_END_NAMESPACE
+
+int main( int argc, char *argv[] )
+{
+ return QT_PREPEND_NAMESPACE(runQVfb)(argc, argv);
+}
diff --git a/src/qvfb/qanimationwriter.cpp b/src/qvfb/qanimationwriter.cpp
new file mode 100644
index 000000000..c91a9164d
--- /dev/null
+++ b/src/qvfb/qanimationwriter.cpp
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanimationwriter.h"
+#include <QFile>
+#include <QString>
+#include <QPainter>
+#include <png.h>
+#include <limits.h>
+#include <netinet/in.h> // for htonl
+
+#ifdef QT_LINUXBASE
+# include <arpa/inet.h> // for htonl (LSB only)
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QAnimationWriterData
+{
+public:
+ QAnimationWriterData(QIODevice* d) : framerate(1000), dev(d) {}
+ void setFrameRate(int d) { framerate = d; }
+ virtual ~QAnimationWriterData() { }
+ virtual void setImage(const QImage& src)=0;
+ virtual bool canCompose() const { return false; }
+ virtual void composeImage(const QImage&, const QPoint& ) {}
+
+protected:
+ int framerate;
+ QIODevice* dev;
+};
+
+
+class QAnimationWriterMNG : public QAnimationWriterData {
+ bool first;
+ png_structp png_ptr;
+ png_infop info_ptr;
+public:
+ QAnimationWriterMNG(QIODevice* d) : QAnimationWriterData(d)
+ {
+ first = true;
+ begin_png();
+ }
+
+ ~QAnimationWriterMNG()
+ {
+ if (first) {
+ // Eh? Not images.
+ QImage dummy(1,1,QImage::Format_RGB32);
+ setImage(dummy);
+ }
+ writeMEND();
+ end_png();
+ }
+
+ void begin_png()
+ {
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
+ info_ptr = png_create_info_struct(png_ptr);
+ png_set_compression_level(png_ptr,9);
+ png_set_write_fn(png_ptr, (void*)this, write, 0);
+ }
+
+ void end_png()
+ {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ }
+
+ static void write( png_structp png_ptr, png_bytep data, png_size_t length)
+ {
+ QAnimationWriterMNG* that = (QAnimationWriterMNG*)png_get_io_ptr(png_ptr);
+ /*uint nw =*/ that->dev->write((const char*)data,length);
+ }
+
+ void writePNG(const QImage& image)
+ {
+#if !defined(QT_LINUXBASE) && \
+ (PNG_LIBPNG_VER_MAJOR < 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR <= 4))
+ // LSB disallows accessing the info_ptr directly. LSB's png_set_IHDR sets
+ // the channels anyways, so just comment it out for LSB usage.
+ // In libpng >= 1.5, the png_info struct is no longer exported.
+ info_ptr->channels = 4;
+#endif
+ png_set_sig_bytes(png_ptr, 8); // Pretend we already wrote the sig
+ png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
+ 8, image.hasAlphaChannel()
+ ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
+ 0, 0, 0);
+ png_write_info(png_ptr, info_ptr);
+ if (!image.hasAlphaChannel())
+ png_set_filler(png_ptr, 0,
+ QSysInfo::ByteOrder == QSysInfo::BigEndian ?
+ PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
+ //if ( QImage::systemByteOrder() == QImage::BigEndian ) {
+ //png_set_swap_alpha(png_ptr);
+ //}
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
+ png_set_bgr(png_ptr);
+ }
+
+ int height = image.height();
+ png_bytep *row_pointers = new png_bytep[height];
+ for (int i = 0; i < height; ++i)
+ row_pointers[i] = (png_bytep)image.scanLine(i);
+ png_write_image(png_ptr, row_pointers);
+ delete [] row_pointers;
+ png_write_end(png_ptr, info_ptr);
+ end_png();
+ begin_png();
+ }
+
+ void writeMHDR(const QSize& size, int framerate)
+ {
+ dev->write("\212MNG\r\n\032\n", 8);
+
+ struct {
+ int width;
+ int height;
+ int framerate;
+ int a,b,c;
+ int profile;
+ } chunk;
+ chunk.width = htonl(size.width());
+ chunk.height = htonl(size.height());
+ chunk.framerate = htonl(framerate);
+ chunk.a=0;
+ chunk.b=0;
+ chunk.c=0;
+ chunk.profile = htonl(0x00000003);
+
+ png_write_chunk(png_ptr, (png_byte*)"MHDR", (png_byte*)&chunk, sizeof(chunk));
+ }
+
+ void writeMEND()
+ {
+ png_write_chunk(png_ptr, (png_byte*)"MEND", 0, 0);
+ }
+
+ void writeDEFI(const QPoint& offset, const QSize& /*size*/)
+ {
+ struct {
+ ushort o;
+ uchar s;
+ uchar concrete;
+ int x,y;
+ int lc,rc,tc,bc;
+ } chunk;
+ chunk.o=0;
+ chunk.s=0;
+ chunk.concrete=1;
+ chunk.x=htonl(offset.x());
+ chunk.y=htonl(offset.y());
+ chunk.lc=0;
+ chunk.rc=0;
+ chunk.tc=htonl(INT_MAX);
+ chunk.bc=htonl(INT_MAX);
+
+ png_write_chunk(png_ptr, (png_byte*)"DEFI", (png_byte*)&chunk, sizeof(chunk));
+ }
+
+ void writeFRAM(const QSize& size)
+ {
+ struct {
+ uchar mode;
+ uchar n;
+ uchar nu;
+ uchar d;
+ uchar t;
+ uchar clip;
+ uchar s;
+ uchar deltatype;
+ uint left;
+ uint right;
+ uint top;
+ uint bottom;
+ } chunk;
+ chunk.mode=1;
+ chunk.n='a';
+ chunk.nu=0;
+ chunk.d=0;
+ chunk.clip=1;
+ chunk.t=0;
+ chunk.s=0;
+ chunk.deltatype=0;
+ chunk.left=0;
+ chunk.right=htonl(size.width());
+ chunk.top=0;
+ chunk.bottom=htonl(size.height());
+
+ png_write_chunk(png_ptr, (png_byte*)"FRAM", (png_byte*)&chunk, sizeof(chunk));
+ }
+
+ void writeMOVE(const QPoint& offset)
+ {
+ struct {
+ uchar filler[3];
+ uchar z[5];
+ int x,y;
+ } chunk;
+ memset(chunk.z,0,5);
+ chunk.x=htonl(offset.x());
+ chunk.y=htonl(offset.y());
+
+ png_write_chunk(png_ptr, (png_byte*)"MOVE", ((png_byte*)&chunk)+3, sizeof(chunk)-3);
+ }
+
+ void setImage(const QImage& src)
+ {
+ if (first) {
+ first = false;
+ writeMHDR(src.size(),framerate);
+ }
+ composeImage(src,QPoint(0,0));
+ }
+
+ bool canCompose() const { return true; }
+
+ void composeImage(const QImage& src, const QPoint& offset)
+ {
+ writeMOVE(offset);
+ //writeFRAM(src.size());
+ writePNG(src);
+ }
+};
+
+QAnimationWriter::QAnimationWriter(const QString& filename, const char* format)
+{
+ if (qstrncmp(format, "MNG", 4)) {
+ qWarning("Format \"%s\" not supported, only MNG", format);
+ dev = 0;
+ d = 0;
+ } else {
+ QFile *f = new QFile(filename);
+ f->open(QIODevice::WriteOnly);
+ dev = f;
+ d = new QAnimationWriterMNG(dev);
+ }
+}
+
+bool QAnimationWriter::okay() const
+{
+ if (!dev)
+ return false;
+ QFile *file = qobject_cast<QFile*>(dev);
+ Q_ASSERT(file);
+ return (file->error() == QFile::NoError);
+}
+
+QAnimationWriter::~QAnimationWriter()
+{
+ delete d;
+ delete dev;
+}
+
+void QAnimationWriter::setFrameRate(int r)
+{
+ if (d)
+ d->setFrameRate(r);
+}
+
+void QAnimationWriter::appendFrame(const QImage& frm, const QPoint& offset)
+{
+ if (!dev)
+ return;
+
+ const QImage frame = frm.convertToFormat(QImage::Format_RGB32);
+ const int alignx = 1;
+ if (prev.isNull() || !d->canCompose()) {
+ d->setImage(frame);
+ } else {
+ bool done;
+ int minx, maxx, miny, maxy;
+ int w = frame.width();
+ int h = frame.height();
+
+ const quint32 *framePtr = reinterpret_cast<const quint32*>(frame.bits());
+ const quint32 *prevPtr = reinterpret_cast<const quint32*>(prev.bits());
+ const int frameStride = frame.bytesPerLine() / sizeof(quint32);
+ const int prevStride = prev.bytesPerLine() / sizeof(quint32);
+
+ // Find left edge of change
+ done = false;
+ for (minx = 0; minx < w && !done; ++minx) {
+ const quint32 *p1 = framePtr + minx;
+ const quint32 *p2 = prevPtr + minx + offset.x();
+ for (int y = 0; y < h; ++y) {
+ if (*p1 != *p2) {
+ done = true;
+ break;
+ }
+ p1 += frameStride;
+ p2 += prevStride;
+ }
+ }
+ --minx;
+
+ // Find right edge of change
+ done = false;
+ for (maxx = w-1; maxx >= 0 && !done; --maxx) {
+ const quint32 *p1 = framePtr + maxx;
+ const quint32 *p2 = prevPtr + maxx + offset.x();
+ for (int y = 0; y < h; ++y) {
+ if (*p1 != *p2) {
+ done = true;
+ break;
+ }
+ p1 += frameStride;
+ p2 += prevStride;
+ }
+ }
+ ++maxx;
+
+ // Find top edge of change
+ done = false;
+ for (miny = 0; miny < h && !done; ++miny) {
+ const quint32 *p1 = framePtr + miny * frameStride;
+ const quint32 *p2 = prevPtr + miny * prevStride + offset.x();
+ for (int x = 0; x < w; ++x) {
+ if (*p1 != *p2) {
+ done = true;
+ break;
+ }
+ ++p1;
+ ++p2;
+ }
+ }
+ --miny;
+
+ // Find right edge of change
+ done = false;
+ for (maxy = h-1; maxy >= 0 && !done; --maxy) {
+ const quint32 *p1 = framePtr + maxy * frameStride;
+ const quint32 *p2 = prevPtr + maxy * prevStride + offset.x();
+ for (int x = 0; x < w; ++x) {
+ if (*p1 != *p2) {
+ done = true;
+ break;
+ }
+ ++p1;
+ ++p2;
+ }
+ }
+ ++maxy;
+
+ if (minx > maxx)
+ minx = maxx = 0;
+ if (miny > maxy)
+ miny = maxy = 0;
+
+ if (alignx > 1) {
+ minx -= minx % alignx;
+ maxx = maxx - maxx % alignx + alignx - 1;
+ }
+
+ int dw = maxx - minx + 1;
+ int dh = maxy - miny + 1;
+
+ QImage diff(dw, dh, QImage::Format_ARGB32);
+
+ int x, y;
+ for (y = 0; y < dh; ++y) {
+ QRgb* li = (QRgb*)frame.scanLine(y+miny)+minx;
+ QRgb* lp = (QRgb*)prev.scanLine(y+miny+offset.y())+minx+offset.x();
+ QRgb* ld = (QRgb*)diff.scanLine(y);
+ if (alignx) {
+ for (x = 0; x < dw; x += alignx) {
+ int i;
+ for (i = 0; i < alignx; ++i) {
+ if (li[x+i] != lp[x+i])
+ break;
+ }
+ if (i == alignx) {
+ // All the same
+ for (i = 0; i < alignx; ++i)
+ ld[x+i] = qRgba(0,0,0,0);
+ } else {
+ // Some different
+ for (i = 0; i < alignx; ++i)
+ ld[x+i] = 0xff000000 | li[x+i];
+ }
+ }
+ } else {
+ for (x = 0; x < dw; ++x) {
+ if (li[x] != lp[x])
+ ld[x] = 0xff000000 | li[x];
+ else
+ ld[x] = qRgba(0,0,0,0);
+ }
+ }
+ }
+
+ d->composeImage(diff, QPoint(minx, miny) + offset);
+ }
+ if (prev.isNull() || (prev.size() == frame.size() && offset == QPoint(0,0))) {
+ prev = frame;
+ } else {
+ QPainter p(&prev);
+ p.drawImage(offset.x(), offset.y(), frame, 0, 0,
+ frame.width(), frame.height());
+ }
+}
+
+void QAnimationWriter::appendFrame(const QImage& frm)
+{
+ appendFrame(frm, QPoint(0,0));
+}
+
+void QAnimationWriter::appendBlankFrame()
+{
+ QImage i(1,1,QImage::Format_ARGB32);
+ i.fill(0);
+ d->composeImage(i, QPoint(0,0));
+}
+
+QT_END_NAMESPACE
diff --git a/src/qvfb/qanimationwriter.h b/src/qvfb/qanimationwriter.h
new file mode 100644
index 000000000..55b43f1a1
--- /dev/null
+++ b/src/qvfb/qanimationwriter.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANIMATIONWRITER_H
+#define QANIMATIONWRITER_H
+
+#include <QImage>
+
+QT_BEGIN_NAMESPACE
+
+class QAnimationWriterData;
+
+class QAnimationWriter
+{
+public:
+ QAnimationWriter(const QString& filename, const char* format = "MNG");
+ ~QAnimationWriter();
+
+ bool okay() const;
+ void setFrameRate(int);
+ void appendBlankFrame();
+ void appendFrame(const QImage&);
+ void appendFrame(const QImage&, const QPoint& offset);
+
+private:
+ QImage prev;
+ QIODevice* dev;
+ QAnimationWriterData* d;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/qtopiakeysym.h b/src/qvfb/qtopiakeysym.h
new file mode 100644
index 000000000..21853ae3f
--- /dev/null
+++ b/src/qvfb/qtopiakeysym.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTKEYSYM_H
+#define QTKEYSYM_H
+
+/* Special keys used by Qtopia, mapped into the X11 private keypad range */
+#define QTOPIAXK_Select 0x11000601
+#define QTOPIAXK_Yes 0x11000602
+#define QTOPIAXK_No 0x11000603
+
+#define QTOPIAXK_Cancel 0x11000604
+#define QTOPIAXK_Printer 0x11000605
+#define QTOPIAXK_Execute 0x11000606
+#define QTOPIAXK_Sleep 0x11000607
+#define QTOPIAXK_Play 0x11000608
+#define QTOPIAXK_Zoom 0x11000609
+
+#define QTOPIAXK_Context1 0x1100060A
+#define QTOPIAXK_Context2 0x1100060B
+#define QTOPIAXK_Context3 0x1100060C
+#define QTOPIAXK_Context4 0x1100060D
+#define QTOPIAXK_Call 0x1100060E
+#define QTOPIAXK_Hangup 0x1100060F
+#define QTOPIAXK_Flip 0x11000610
+
+#define QTOPIAXK_Min QTOPIAXK_Select
+#define QTOPIAXK_Max QTOPIAXK_Flip
+
+#endif
diff --git a/src/qvfb/qvfb.cpp b/src/qvfb/qvfb.cpp
new file mode 100644
index 000000000..db598b9c7
--- /dev/null
+++ b/src/qvfb/qvfb.cpp
@@ -0,0 +1,1147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfb.h"
+#include "qvfbview.h"
+#include "qvfbhdr.h"
+#ifdef Q_WS_X11
+#include "qvfbx11view.h"
+#endif
+#include "qvfbratedlg.h"
+#include "ui_config.h"
+#include "qanimationwriter.h"
+
+#include <deviceskin.h>
+
+#include <QMenuBar>
+#include <QMenu>
+#include <QApplication>
+#include <QMessageBox>
+#include <QComboBox>
+#include <QLabel>
+#include <QFileDialog>
+#include <QSlider>
+#include <QSpinBox>
+#include <QLayout>
+#include <QRadioButton>
+#include <QImage>
+#include <QPixmap>
+#include <QCheckBox>
+#include <QCursor>
+#include <QTime>
+#include <QScrollArea>
+#include <QProgressBar>
+#include <QPushButton>
+#include <QTextStream>
+#include <QFile>
+#include <QFileInfo>
+#include <QDebug>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+QT_BEGIN_NAMESPACE
+
+// =====================================================================
+
+static const char *red_on_led_xpm[] = {
+"11 11 10 1",
+" c None",
+". c #FF0000",
+"+ c #FF4C4C",
+"@ c #FF7A7A",
+"# c #D30000",
+"$ c #FF9393",
+"% c #BA0000",
+"& c #FFFFFF",
+"* c #7F0000",
+"= c #000000",
+" ",
+" .++@@ ",
+" .....+@ ",
+" ##...$.+@ ",
+" %#..$&$.+ ",
+" *#...$..+ ",
+" *%#...... ",
+" =*%#..... ",
+" =*%###. ",
+" ===*. ",
+" "};
+
+static const char *red_off_led_xpm[] = {
+"11 11 12 1",
+" c None",
+". c #CDB7B4",
+"+ c #D2BFBD",
+"@ c #DBCBCA",
+"# c #E5D9D8",
+"$ c #BC9E9B",
+"% c #E2D6D5",
+"& c #AD8986",
+"* c #FFFFFF",
+"= c #A8817D",
+"- c #B2908D",
+"; c #6F4D4A",
+" ",
+" .++@# ",
+" .....@# ",
+" $$...%.@# ",
+" &$..%*%.@ ",
+" =-...%..+ ",
+" =&-...... ",
+" ;==-..... ",
+" ;=&-$$. ",
+" ;==&$ ",
+" "};
+
+static bool copyButtonConfiguration(const QString &prefix, int displayId)
+{
+ const QString destDir = QT_VFB_DATADIR(displayId).append("/");
+ const QFileInfo src(prefix + QLatin1String("defaultbuttons.conf"));
+ const QFileInfo dst(destDir + QLatin1String("defaultbuttons.conf"));
+ unlink(dst.absoluteFilePath().toLatin1().constData());
+ if (!src.exists())
+ return false;
+ const bool rc = QFile::copy(src.absoluteFilePath(), dst.absoluteFilePath());
+ if (!rc)
+ qWarning() << "Failed to copy the button configuration file " << src.absoluteFilePath() << " to " << dst.absoluteFilePath() << '.';
+ return rc;
+}
+
+// =====================================================================
+
+class AnimationSaveWidget : public QWidget {
+ Q_OBJECT
+public:
+ AnimationSaveWidget(QVFbAbstractView *v);
+ ~AnimationSaveWidget();
+ bool detectPpmtoMpegCommand();
+ void timerEvent(QTimerEvent *te);
+ void convertToMpeg(QString filename);
+ void removeTemporaryFiles();
+protected slots:
+ void toggleRecord();
+ void reset();
+ void save();
+private:
+ QVFbAbstractView *view;
+ QProgressBar *progressBar;
+ QLabel *statusText;
+ bool haveMpeg, savingAsMpeg, recording;
+ QCheckBox *mpegSave;
+ QAnimationWriter *animation;
+ QPushButton *recBt, *resetBt, *saveBt;
+ QLabel *timeDpy, *recLED;
+ int timerId, progressTimerId;
+ QPixmap recOn, recOff;
+ QTime tm;
+ int elapsed, imageNum;
+};
+
+// =====================================================================
+
+Zoomer::Zoomer(QVFb* target) :
+ qvfb(target)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QSlider *sl = new QSlider(Qt::Horizontal);
+ sl->setMinimum(10);
+ sl->setMaximum(64);
+ sl->setPageStep(1);
+ sl->setValue(32);
+ layout->addWidget(sl);
+ connect(sl,SIGNAL(valueChanged(int)),this,SLOT(zoom(int)));
+ label = new QLabel();
+ layout->addWidget(label);
+}
+
+void Zoomer::zoom(int z)
+{
+ double d = (double)z/32.0;
+ qvfb->setZoom(d);
+ label->setText(QString::number(d,'g',2));
+}
+
+// =====================================================================
+
+QVFb::QVFb( int display_id, int w, int h, int d, int r, const QString &skin, DisplayType displayType, QWidget *parent, Qt::WindowFlags flags )
+ : QMainWindow( parent, flags )
+{
+ this->displayType = displayType;
+ view = 0;
+ secondaryView = 0;
+ scroller = 0;
+ this->skin = 0;
+ currentSkinIndex = -1;
+ findSkins(skin);
+ zoomer = 0;
+ QPixmap pix(":/res/images/logo.png");
+ setWindowIcon( pix );
+ rateDlg = 0;
+ refreshRate = 30;
+ // Create the menu first to avoid scroll bars in the main window
+ createMenu( menuBar() );
+ init( display_id, w, h, d, r, skin );
+ enableCursor( true );
+}
+
+QVFb::~QVFb()
+{
+}
+
+void QVFb::popupMenu()
+{
+ QMenu *pm = new QMenu( this );
+ createMenu( pm );
+ pm->exec(QCursor::pos());
+}
+
+void QVFb::init( int display_id, int pw, int ph, int d, int r, const QString& skin_name )
+{
+ delete view;
+ view = 0;
+ delete secondaryView;
+ secondaryView = 0;
+ delete scroller;
+ scroller = 0;
+ delete skin;
+ skin = 0;
+
+ skinscaleH = skinscaleV = 1.0;
+ QVFbView::Rotation rot = ((r == 90) ? QVFbView::Rot90 :
+ ((r == 180) ? QVFbView::Rot180 :
+ ((r == 270) ? QVFbView::Rot270 :
+ QVFbView::Rot0 )));
+ if ( !skin_name.isEmpty() ) {
+ const bool vis = isVisible();
+ DeviceSkinParameters parameters;
+ QString readError;
+ if (parameters.read(skin_name,DeviceSkinParameters::ReadAll, &readError)) {
+ skin = new DeviceSkin(parameters, this);
+ connect(skin, SIGNAL(popupMenu()), this, SLOT(popupMenu()));
+ const int sw = parameters.screenSize().width();
+ const int sh = parameters.screenSize().height();
+ const int sd = parameters.screenDepth;
+ if (!pw) pw = sw;
+ if (!ph) ph = sh;
+ if (d < 0) {
+ if (sd)
+ d = sd;
+ else
+ d = -d;
+ }
+ if (vis)
+ hide();
+ menuBar()->hide();
+ scroller = 0;
+#ifdef Q_WS_X11
+ if (displayType == X11)
+ view = new QVFbX11View( display_id, pw, ph, d, rot, skin );
+ else
+#endif
+ view = new QVFbView( display_id, pw, ph, d, rot, skin );
+ skin->setView( view );
+ view->setContentsMargins( 0, 0, 0, 0 );
+ view->setTouchscreenEmulation(!parameters.hasMouseHover);
+ connect(skin, SIGNAL(skinKeyPressEvent(int,QString,bool)), view, SLOT(skinKeyPressEvent(int,QString,bool)));
+ connect(skin, SIGNAL(skinKeyReleaseEvent(int,QString,bool)), view, SLOT(skinKeyReleaseEvent(int,QString,bool)));
+
+ copyButtonConfiguration(skin->prefix(), view->displayId());
+
+ setCentralWidget( skin );
+ adjustSize();
+ skinscaleH = (double)sw/pw;
+ skinscaleV = (double)sh/ph;
+ if ( skinscaleH != 1.0 || skinscaleH != 1.0 )
+ setZoom(skinscaleH);
+ view->show();
+
+ if (parameters.hasSecondaryScreen()) {
+ const QSize ssize = parameters.secondaryScreenSize();
+ // assumes same depth and rotation
+#ifdef Q_WS_X11
+ if (displayType == X11)
+ secondaryView = new QVFbX11View( display_id+1, ssize.width(), ssize.height(), d, rot, skin );
+ else
+#endif
+ secondaryView = new QVFbView( display_id+1, ssize.width(), ssize.height(), d, rot, skin );
+ skin->setSecondaryView(secondaryView);
+ secondaryView->show();
+ }
+
+ if ( vis ) show();
+ } else {
+ qWarning("%s", qPrintable(readError));
+ }
+ }
+
+ // If we failed to get a skin or we were not supplied
+ // with one then fallback to a framebuffer without
+ // a skin
+ if (!skin){
+ // Default values
+ if (!pw)
+ pw = 240;
+ if (!ph)
+ ph = 320;
+ if (!d)
+ d = 32;
+ else if (d < 0)
+ d = -d;
+
+ if (currentSkinIndex != -1) {
+ clearMask();
+ setParent( 0, 0 );
+ move( pos() );
+ show();
+ //unset fixed size:
+ setMinimumSize(0,0);
+ setMaximumSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX);
+ }
+ menuBar()->show();
+ scroller = new QScrollArea(this);
+ scroller->setFocusPolicy(Qt::NoFocus); // don't steal key events from the embedded app
+#ifdef Q_WS_X11
+ if (displayType == X11)
+ view = new QVFbX11View( display_id, pw, ph, d, rot, scroller );
+ else
+#endif
+ view = new QVFbView( display_id, pw, ph, d, rot, scroller );
+ scroller->setWidget(view);
+ view->setContentsMargins( 0, 0, 0, 0 );
+ setCentralWidget(scroller);
+ ph += 2; // avoid scrollbar
+ scroller->show();
+ // delete defaultbuttons.conf if it was left behind...
+ unlink(QFileInfo(QT_VFB_DATADIR(view->displayId()).append("/defaultbuttons.conf")).absoluteFilePath().toLatin1().constData());
+ if (secondaryView)
+ unlink(QFileInfo(QT_VFB_DATADIR(view->displayId() + 1).append("/defaultbuttons.conf")).absoluteFilePath().toLatin1().constData());
+ }
+ view->setRate(refreshRate);
+ if (secondaryView) {
+ secondaryView->setRate(refreshRate);
+ }
+ // Resize QVFb to the new size
+ QSize newSize = view->sizeHint();
+
+ // ... fudge factor
+ newSize += QSize(20, 35);
+
+ resize(newSize);
+
+ setWindowTitle(QString("Virtual framebuffer %1x%2 %3bpp Display :%4 Rotate %5")
+ .arg(view->displayWidth()).arg(view->displayHeight())
+ .arg(d).arg(display_id).arg(r));
+}
+
+void QVFb::enableCursor( bool e )
+{
+ if ( skin && skin->hasCursor() ) {
+ view->setCursor( Qt::BlankCursor );
+ if (secondaryView)
+ secondaryView->setCursor( Qt::BlankCursor );
+ } else {
+ view->setCursor( e ? Qt::ArrowCursor : Qt::BlankCursor );
+ if (secondaryView)
+ secondaryView->setCursor( e ? Qt::ArrowCursor : Qt::BlankCursor );
+ }
+ cursorAction->setChecked( e );
+}
+
+template <typename T>
+void QVFb::createMenu(T *menu)
+{
+ menu->addMenu( createFileMenu() );
+ menu->addMenu( createViewMenu() );
+ menu->addSeparator();
+ menu->addMenu( createHelpMenu() );
+}
+
+QMenu* QVFb::createFileMenu()
+{
+ QMenu *file = new QMenu( tr("&File"), this );
+ file->addAction( tr("&Configure..."), this, SLOT(configure()), QKeySequence::Preferences );
+ file->addSeparator();
+ file->addAction( tr("&Save image..."), this, SLOT(saveImage()), QKeySequence::Save );
+ file->addAction( tr("&Animation..."), this, SLOT(toggleAnimation()), 0 );
+ file->addSeparator();
+ file->addAction( tr("&Quit"), qApp, SLOT(quit()), QKeySequence::Quit );
+ return file;
+}
+
+QMenu* QVFb::createViewMenu()
+{
+ viewMenu = new QMenu( tr("&View"), this );
+ cursorAction = viewMenu->addAction( tr("Show &Cursor"), this,
+ SLOT(toggleCursor()) );
+ cursorAction->setCheckable(true);
+ if ( view )
+ enableCursor(true);
+ viewMenu->addAction( tr("&Refresh Rate..."), this, SLOT(changeRate()) );
+ viewMenu->addSeparator();
+ viewMenu->addAction( tr("&No rotation"), this, SLOT(setRot0()) );
+ viewMenu->addAction( tr("&90\260 rotation"), this, SLOT(setRot90()) );
+ viewMenu->addAction( tr("1&80\260 rotation"), this, SLOT(setRot180()) );
+ viewMenu->addAction( tr("2&70\260 rotation"), this, SLOT(setRot270()) );
+ viewMenu->addSeparator();
+ viewMenu->addAction( tr("Zoom scale &0.5"), this, SLOT(setZoomHalf()) );
+ viewMenu->addAction( tr("Zoom scale 0.7&5"), this, SLOT(setZoom075()) );
+ viewMenu->addAction( tr("Zoom scale &1"), this, SLOT(setZoom1()) );
+ viewMenu->addAction( tr("Zoom scale &2"), this, SLOT(setZoom2()) );
+ viewMenu->addAction( tr("Zoom scale &3"), this, SLOT(setZoom3()) );
+ viewMenu->addAction( tr("Zoom scale &4"), this, SLOT(setZoom4()) );
+ viewMenu->addSeparator();
+ viewMenu->addAction( tr("Zoom &scale..."), this, SLOT(setZoom()) );
+ return viewMenu;
+}
+
+
+QMenu* QVFb::createHelpMenu()
+{
+ QMenu *help = new QMenu( tr("&Help"), this );
+ help->addAction(tr("&About..."), this, SLOT(about()));
+ return help;
+}
+
+void QVFb::setZoom(double z)
+{
+ view->setZoom(z,z*skinscaleV/skinscaleH);
+ if (secondaryView)
+ secondaryView->setZoom(z,z*skinscaleV/skinscaleH);
+
+ if (skin) {
+ skin->setTransform(QMatrix().scale(z/skinscaleH,z/skinscaleV).rotate(90*view->displayRotation()));
+ if (secondaryView)
+ secondaryView->setFixedSize(
+ int(secondaryView->displayWidth()*z),
+ int(secondaryView->displayHeight()*z*skinscaleV/skinscaleH));
+ }
+}
+
+void QVFb::setRotation(QVFbView::Rotation r)
+{
+ view->setRotation(r);
+ if (secondaryView)
+ secondaryView->setRotation(r);
+ setZoom(view->zoomH());
+}
+
+void QVFb::setRot0()
+{
+ setRotation(QVFbView::Rot0);
+}
+
+void QVFb::setRot90()
+{
+ setRotation(QVFbView::Rot90);
+}
+
+void QVFb::setRot180()
+{
+ setRotation(QVFbView::Rot180);
+}
+
+void QVFb::setRot270()
+{
+ setRotation(QVFbView::Rot270);
+}
+
+void QVFb::setZoomHalf()
+{
+ setZoom(0.5);
+}
+
+void QVFb::setZoom075()
+{
+ setZoom(0.75);
+}
+
+void QVFb::setZoom1()
+{
+ setZoom(1);
+}
+
+void QVFb::setZoom()
+{
+ if ( !zoomer )
+ zoomer = new Zoomer(this);
+ zoomer->show();
+}
+
+void QVFb::setZoom2()
+{
+ setZoom(2);
+}
+
+void QVFb::setZoom3()
+{
+ setZoom(3);
+}
+
+void QVFb::setZoom4()
+{
+ setZoom(4);
+}
+
+void QVFb::saveImage()
+{
+ QImage img = view->image();
+ QString filename = QFileDialog::getSaveFileName(this, tr("Save Main Screen image"), tr("snapshot.png"), tr("Portable Network Graphics (*.png)"));
+ if (!filename.isEmpty()){
+ if(!img.save(filename,"PNG"))
+ QMessageBox::critical(this, tr("Save Main Screen Image"), tr("Save failed. Check that you have permission to write to the target directory."));
+ }
+ if (secondaryView) {
+ QImage img = view->image();
+ QString filename = QFileDialog::getSaveFileName(this, tr("Save Second Screen image"), tr("snapshot.png"), tr("Portable Network Graphics (*.png)"));
+ if (!filename.isEmpty()) {
+ if(!img.save(filename,"PNG"))
+ QMessageBox::critical(this, tr("Save Second Screen Image"), tr("Save failed. Check that you have permission to write to the target directory."));
+ }
+ }
+}
+
+void QVFb::toggleAnimation()
+{
+ static AnimationSaveWidget *animWidget = 0;
+ if ( !animWidget )
+ animWidget = new AnimationSaveWidget(view);
+ if ( animWidget->isVisible() )
+ animWidget->hide();
+ else
+ animWidget->show();
+}
+
+void QVFb::toggleCursor()
+{
+ enableCursor(cursorAction->isChecked());
+}
+
+void QVFb::changeRate()
+{
+ if ( !rateDlg ) {
+ rateDlg = new QVFbRateDialog( refreshRate, this );
+ connect( rateDlg, SIGNAL(updateRate(int)), this, SLOT(setRate(int)) );
+ }
+
+ rateDlg->show();
+}
+
+void QVFb::setRate(int i)
+{
+ refreshRate = i;
+ view->setRate(i);
+ if (secondaryView)
+ secondaryView->setRate(i);
+}
+
+
+void QVFb::about()
+{
+ QMessageBox::about(this, tr("About QVFB"), tr(
+ "<h2>The Qt for Embedded Linux Virtual X11 Framebuffer</h2>"
+ "<p>This application runs under Qt for X11, emulating a simple framebuffer, "
+ "which the Qt for Embedded Linux server and clients can attach to just as if "
+ "it was a hardware Linux framebuffer. "
+ "<p>With the aid of this development tool, you can develop Qt for Embedded "
+ "Linux applications under X11 without having to switch to a virtual console. "
+ "This means you can comfortably use your other development tools such "
+ "as GUI profilers and debuggers."
+ ));
+}
+
+void QVFb::findSkins(const QString &currentSkin)
+{
+ skinnames.clear();
+ skinfiles.clear();
+ QDir dir(":/skins/","*.skin");
+ const QFileInfoList l = dir.entryInfoList();
+ int i = 1; // "None" is already in list at index 0
+ for (QFileInfoList::const_iterator it = l.begin(); it != l.end(); ++it) {
+ skinnames.append((*it).baseName()); // should perhaps be in file
+ skinfiles.append((*it).filePath());
+ if (((*it).baseName() + ".skin") == currentSkin)
+ currentSkinIndex = i;
+ i++;
+ }
+}
+
+class Config : public QDialog, public Ui::Config
+{
+public:
+ Config(QWidget *parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ setModal(true);
+
+ connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
+ }
+};
+
+void QVFb::configure()
+{
+ config = new Config(this);
+
+ int w = view->displayWidth();
+ int h = view->displayHeight();
+
+ // Need to block signals, because we connect to animateClick(),
+ // since QCheckBox doesn't have setChecked(bool) in 2.x.
+ chooseSize(QSize(w,h));
+ config->skin->insertItems(config->skin->count(), skinnames);
+ if (currentSkinIndex > 0)
+ config->skin->setCurrentIndex(currentSkinIndex);
+ config->skin->addItem(tr("Browse..."));
+ config->touchScreen->setChecked(view->touchScreenEmulation());
+ config->lcdScreen->setChecked(view->lcdScreenEmulation());
+ chooseDepth(view->displayDepth(), view->displayFormat());
+ config->rgbSwapped->setChecked(view->rgbSwapped());
+ connect(config->skin, SIGNAL(activated(int)), this, SLOT(skinConfigChosen(int)));
+ if ( view->gammaRed() == view->gammaGreen() && view->gammaGreen() == view->gammaBlue() ) {
+ config->gammaslider->setValue(int(view->gammaRed()*400));
+ config->rslider->setValue(100);
+ config->gslider->setValue(100);
+ config->bslider->setValue(100);
+ } else {
+ config->gammaslider->setValue(100);
+ config->rslider->setValue(int(view->gammaRed()*400));
+ config->gslider->setValue(int(view->gammaGreen()*400));
+ config->bslider->setValue(int(view->gammaBlue()*400));
+ }
+ connect(config->gammaslider, SIGNAL(valueChanged(int)), this, SLOT(setGamma400(int)));
+ connect(config->rslider, SIGNAL(valueChanged(int)), this, SLOT(setR400(int)));
+ connect(config->gslider, SIGNAL(valueChanged(int)), this, SLOT(setG400(int)));
+ connect(config->bslider, SIGNAL(valueChanged(int)), this, SLOT(setB400(int)));
+ updateGammaLabels();
+
+ double ogr=view->gammaRed(), ogg=view->gammaGreen(), ogb=view->gammaBlue();
+ qApp->setQuitOnLastWindowClosed(false);
+
+ hide();
+ if ( config->exec() ) {
+ int id = view->displayId(); // not settable yet
+ if ( config->size_176_220->isChecked() ) {
+ w=176; h=220;
+ } else if ( config->size_240_320->isChecked() ) {
+ w=240; h=320;
+ } else if ( config->size_320_240->isChecked() ) {
+ w=320; h=240;
+ } else if ( config->size_640_480->isChecked() ) {
+ w=640; h=480;
+ } else if ( config->size_800_480->isChecked() ) {
+ w=800; h=480;
+ } else if ( config->size_800_600->isChecked() ) {
+ w=800; h=600;
+ } else if ( config->size_1024_768->isChecked() ) {
+ w=1024; h=768;
+ } else {
+ w=config->size_width->value();
+ h=config->size_height->value();
+ }
+ int d;
+ if ( config->depth_1->isChecked() )
+ d=1;
+ else if ( config->depth_2gray->isChecked() )
+ d=2;
+ else if ( config->depth_4gray->isChecked() )
+ d=4;
+ else if ( config->depth_8->isChecked() )
+ d=8;
+ else if ( config->depth_12->isChecked() )
+ d=12;
+ else if ( config->depth_15->isChecked() )
+ d = 15;
+ else if ( config->depth_16->isChecked() )
+ d=16;
+ else if ( config->depth_18->isChecked() )
+ d=18;
+ else if ( config->depth_24->isChecked() )
+ d=24;
+ else
+ d=32;
+ QVFbView::PixelFormat displayFormat = config->depth_32_argb->isChecked()
+ ? QVFbView::ARGBFormat : QVFbView::DefaultFormat;
+ int skinIndex = config->skin->currentIndex();
+ if ( w != view->displayWidth() || h != view->displayHeight()
+ || d != view->displayDepth() || skinIndex != currentSkinIndex ) {
+ QVFbView::Rotation rot = view->displayRotation();
+ int r = ((rot == QVFbView::Rot90) ? 90 :
+ ((rot == QVFbView::Rot180) ? 180 :
+ ((rot == QVFbView::Rot270) ? 270 : 0 )));
+ currentSkinIndex = skinIndex;
+ init( id, w, h, d, r, skinIndex > 0 ? skinfiles[skinIndex-1] : QString::null );
+ }
+ view->setViewFormat(displayFormat);
+ view->setTouchscreenEmulation( config->touchScreen->isChecked() );
+ if (view->rgbSwapped() != config->rgbSwapped->isChecked()) {
+ //### the windowTitle logic is inside init(), and init isn't always invoked
+ QString caption = windowTitle();
+ if (!config->rgbSwapped->isChecked())
+ caption.replace(QLatin1String(" BGR"), QString());
+ else
+ caption.append(QLatin1String(" BGR"));
+ setWindowTitle(caption);
+ view->setRgbSwapped(config->rgbSwapped->isChecked());
+ }
+ bool lcdEmulation = config->lcdScreen->isChecked();
+ view->setLcdScreenEmulation( lcdEmulation );
+ if ( lcdEmulation )
+ setZoom3();
+ } else {
+ view->setGamma(ogr, ogg, ogb);
+ }
+ show();
+ qApp->setQuitOnLastWindowClosed(true);
+ delete config;
+ config=0;
+}
+
+void QVFb::chooseSize(const QSize& sz)
+{
+ config->size_width->blockSignals(true);
+ config->size_height->blockSignals(true);
+ config->size_width->setValue(sz.width());
+ config->size_height->setValue(sz.height());
+ config->size_width->blockSignals(false);
+ config->size_height->blockSignals(false);
+ config->size_custom->setChecked(true); // unless changed by settings below
+ config->size_176_220->setChecked(sz == QSize(176,220));
+ config->size_240_320->setChecked(sz == QSize(240,320));
+ config->size_320_240->setChecked(sz == QSize(320,240));
+ config->size_640_480->setChecked(sz == QSize(640,480));
+ config->size_800_480->setChecked(sz == QSize(800,480));
+ config->size_800_600->setChecked(sz == QSize(800,600));
+ config->size_1024_768->setChecked(sz == QSize(1024,768));
+}
+
+void QVFb::chooseDepth(int depth, QVFbView::PixelFormat displayFormat)
+{
+ config->depth_1->setChecked(depth==1);
+ config->depth_2gray->setChecked(depth==2);
+ config->depth_4gray->setChecked(depth==4);
+ config->depth_8->setChecked(depth==8);
+ config->depth_12->setChecked(depth==12);
+ config->depth_15->setChecked(depth==15);
+ config->depth_16->setChecked(depth==16);
+ config->depth_18->setChecked(depth==18);
+ config->depth_24->setChecked(depth==24);
+ config->depth_32->setChecked(depth==32 && displayFormat != QVFbView::ARGBFormat);
+ config->depth_32_argb->setChecked(depth==32 && displayFormat == QVFbView::ARGBFormat);
+}
+
+void QVFb::skinConfigChosen(int i)
+{
+ if (i == config->skin->count() - 1) { // Browse... ?
+ QFileDialog dlg(this);
+ dlg.setFileMode(QFileDialog::DirectoryOnly);
+ dlg.setWindowTitle(tr("Load Custom Skin..."));
+ dlg.setFilter(tr("All QVFB Skins (*.skin)"));
+ dlg.setDirectory(QDir::current());
+ if (dlg.exec() && dlg.selectedFiles().count() == 1) {
+ skinfiles.append(dlg.selectedFiles().first());
+ i = skinfiles.count();
+ config->skin->insertItem(i, QFileInfo(skinfiles.last()).baseName());
+ config->skin->setCurrentIndex(i);
+ } else {
+ i = 0;
+ }
+ }
+ if ( i ) {
+ DeviceSkinParameters parameters;
+ QString readError;
+ if (parameters.read(skinfiles[i-1], DeviceSkinParameters::ReadSizeOnly, &readError)) {
+ chooseSize(parameters.screenSize());
+ if (parameters.screenDepth)
+ chooseDepth(parameters.screenDepth,QVFbView::ARGBFormat);
+ config->touchScreen->setChecked(!parameters.hasMouseHover);
+ } else {
+ qWarning("%s", qPrintable(readError));
+ }
+ }
+}
+
+void QVFb::setGamma400(int n)
+{
+ double g = n/100.0;
+ view->setGamma(config->rslider->value()/100.0*g,
+ config->gslider->value()/100.0*g,
+ config->bslider->value()/100.0*g);
+ updateGammaLabels();
+}
+
+void QVFb::setR400(int n)
+{
+ double g = n/100.0;
+ view->setGamma(config->rslider->value()/100.0*g,
+ view->gammaGreen(),
+ view->gammaBlue());
+ updateGammaLabels();
+}
+
+void QVFb::setG400(int n)
+{
+ double g = n/100.0;
+ view->setGamma(view->gammaRed(),
+ config->gslider->value()/100.0*g,
+ view->gammaBlue());
+ updateGammaLabels();
+}
+
+void QVFb::setB400(int n)
+{
+ double g = n/100.0;
+ view->setGamma(view->gammaRed(),
+ view->gammaGreen(),
+ config->bslider->value()/100.0*g);
+ updateGammaLabels();
+}
+
+void QVFb::updateGammaLabels()
+{
+ config->rlabel->setText(QString::number(view->gammaRed(),'g',2));
+ config->glabel->setText(QString::number(view->gammaGreen(),'g',2));
+ config->blabel->setText(QString::number(view->gammaBlue(),'g',2));
+}
+
+QSize QVFb::sizeHint() const
+{
+ return QSize(int(view->displayWidth()*view->zoomH()),
+ int(menuBar()->height()+view->displayHeight()*view->zoomV()));
+}
+
+// =====================================================================
+
+AnimationSaveWidget::AnimationSaveWidget(QVFbAbstractView *v) :
+ QWidget((QWidget*)0,0),
+ view(v), recording(false), animation(0),
+ timerId(-1), progressTimerId(-1),
+ recOn(red_on_led_xpm), recOff(red_off_led_xpm),
+ imageNum(0)
+{
+ // Create the animation record UI dialog
+ QVBoxLayout *vlayout = new QVBoxLayout( this );
+
+ QWidget *hbox = new QWidget( this );
+ vlayout->addWidget(hbox);
+ QHBoxLayout *hlayout = new QHBoxLayout(hbox);
+ recBt = new QPushButton( tr("Record"), hbox );
+ hlayout->addWidget(recBt);
+ resetBt = new QPushButton( tr("Reset"), hbox );
+ hlayout->addWidget(resetBt);
+ saveBt = new QPushButton( tr("Save"), hbox );
+ hlayout->addWidget(saveBt);
+ recBt->setFixedWidth( 100 );
+ resetBt->setFixedWidth( 100 );
+ saveBt->setFixedWidth( 100 );
+ timeDpy = new QLabel( "00:00", hbox );
+ hlayout->addWidget(timeDpy);
+ recLED = new QLabel( hbox );
+ hlayout->addWidget(recLED);
+ recLED->setPixmap( recOff );
+ timeDpy->setMargin( 5 );
+ connect( recBt, SIGNAL(clicked()), this, SLOT(toggleRecord()) );
+ connect( resetBt, SIGNAL(clicked()), this, SLOT(reset()) );
+ connect( saveBt, SIGNAL(clicked()), this, SLOT(save()) );
+ elapsed = 0;
+ vlayout->setMargin( 5 );
+ vlayout->setSpacing( 5 );
+ haveMpeg = detectPpmtoMpegCommand();
+ mpegSave = new QCheckBox( tr("Save in MPEG format (requires netpbm package installed)"), this );
+ vlayout->addWidget(mpegSave);
+ mpegSave->setChecked( haveMpeg );
+ mpegSave->setEnabled( haveMpeg );
+ savingAsMpeg = haveMpeg;
+ QWidget *hbox2 = new QWidget( this );
+ vlayout->addWidget(hbox2);
+ QHBoxLayout *hlayout2 = new QHBoxLayout( hbox2 );
+ statusText = new QLabel( tr("Click record to begin recording."), hbox2 );
+ hlayout2->addWidget(statusText);
+ progressBar = new QProgressBar( hbox2 );
+ progressBar->setValue( 0 );
+ hlayout2->addWidget(progressBar);
+ progressBar->hide();
+}
+
+AnimationSaveWidget::~AnimationSaveWidget()
+{
+ // clean up
+ removeTemporaryFiles();
+ delete animation;
+}
+
+// returns true if we have ppmtompeg command, else returns false
+bool AnimationSaveWidget::detectPpmtoMpegCommand()
+{
+ // search the PATH for the ppmtompeg command to test we can record to mpeg
+ QStringList paths = QString(::getenv("PATH")).split(":");
+ for ( int i = 0; i < paths.count(); i++ )
+ if ( QFile::exists( paths[i] + "/" + "ppmtompeg" ) )
+ return true;
+ return false;
+}
+
+void AnimationSaveWidget::timerEvent( QTimerEvent *te )
+{
+ QString str;
+
+ // Recording timer
+ if ( te->timerId() == timerId ) {
+
+ // Add a frame to the animation
+ if ( savingAsMpeg && view )
+ view->image().save( str.sprintf("/tmp/qvfb_tmp_image_%04d.ppm", imageNum), "PPM");
+ else if ( animation && view )
+ animation->appendFrame(view->image());//QPoint(0,0));
+ imageNum++;
+
+ // Update the display of number of seconds that have been recorded.
+ int tmMsec = tm.elapsed();
+ timeDpy->setText( str.sprintf("%02d:%02d", tmMsec/60000, (tmMsec%60000)/1000) );
+ QObject::timerEvent( te );
+
+ // Make the recording LED blink
+ static int tick = 0;
+ static bool on = false;
+ if ( tick > 10 ) {
+ tick = 0;
+ if ( on )
+ recLED->setPixmap( recOff );
+ else
+ recLED->setPixmap( recOn );
+ on = !on;
+ }
+ tick++;
+ }
+
+ // Saving progress timer
+ if ( te->timerId() == progressTimerId ) {
+ // Parse output log file to work out the encoding progress.
+ QFile f("/tmp/qvfb_tmp_output.log");
+ f.open(QIODevice::ReadOnly);
+ int largestNum = 0;
+ bool done = false;
+ char buffer[1024];
+ while ( !f.atEnd() ) {
+ // example of the output log entries
+ // During each frame:
+ // "FRAME 764 (B): I BLOCKS: 0......
+ // When complete:
+ // "======FRAMES READ: 766"
+ f.readLine(buffer, 1024);
+ str = QString(buffer);
+ if ( str.left(6) == "FRAME " ) {
+ int num = str.mid(6, str.indexOf(QChar(' '), 6) - 6).toInt();
+ if ( num > largestNum )
+ largestNum = num;
+ } else if ( str.left(18) == "======FRAMES READ:" ) {
+ done = true;
+ }
+ }
+ f.close();
+
+ // Update the progress bar with the frame we are up to
+ progressBar->setValue( largestNum );
+
+ // Finished saving
+ if ( done ) {
+ progressBar->hide();
+ statusText->setText( tr("Finished saving."));
+ removeTemporaryFiles();
+ killTimer( progressTimerId );
+ progressTimerId = -1;
+ reset();
+ }
+ }
+}
+
+// Takes the saved ppm files and converts them to a mpeg file named filename
+void AnimationSaveWidget::convertToMpeg(QString filename)
+{
+ recLED->setPixmap( recOff );
+ killTimer( timerId );
+
+ progressBar->show();
+ progressBar->setRange( 0, imageNum );
+ progressBar->setValue( 0 );
+
+ // Build parameter file required by ppmtompeg
+ QFile file("/tmp/qvfb_tmp_ppmtompeg.params");
+ if ( file.open( QIODevice::WriteOnly ) ) {
+ QTextStream t( &file );
+ t << "PATTERN IBBPBBPBBPBBPBB\n";
+ t << "OUTPUT " << filename << "\n";
+ t << "INPUT_DIR /tmp\n";
+ t << "INPUT\n";
+ QString str;
+ str = str.sprintf("%04d", imageNum - 1);
+ t << "qvfb_tmp_image_*.ppm [0000-" << str << "]\n";
+ t << "END_INPUT\n";
+ t << "BASE_FILE_FORMAT PPM\n";
+ t << "INPUT_CONVERT *\n";
+ t << "GOP_SIZE 15\n";
+ t << "SLICES_PER_FRAME 1\n";
+ t << "PIXEL HALF\n";
+ t << "RANGE 5\n";
+ t << "PSEARCH_ALG LOGARITHMIC\n";
+ t << "BSEARCH_ALG SIMPLE\n";
+ t << "IQSCALE 1\n";
+ t << "PQSCALE 1\n";
+ t << "BQSCALE 1\n";
+ t << "REFERENCE_FRAME DECODED\n";
+ t << "ASPECT_RATIO 1\n";
+ t << "FRAME_RATE 24\n";
+ t << "BIT_RATE 64000\n"; // Quality
+ t << "BUFFER_SIZE 2048\n";
+ }
+ file.close();
+
+ // ### can't use QProcess, not in Qt 2.3
+ // ### but it's certainly in Qt 4! use it?
+ // Execute the ppmtompeg command as a separate process to do the encoding
+ pid_t pid = ::fork();
+ if ( !pid ) {
+ // Child process
+ // redirect stdout to log file
+ freopen("/tmp/qvfb_tmp_output.log", "w", stdout);
+ // ppmtompeg tool is from the netpbm package
+ ::execlp("ppmtompeg", "ppmtompeg", "/tmp/qvfb_tmp_ppmtompeg.params", (void *)0);
+ exit(0);
+ }
+
+ // Update the saving progress bar every 200ms
+ progressTimerId = startTimer( 200 );
+}
+
+// Cleanup temporary files created during creating a mpeg file
+void AnimationSaveWidget::removeTemporaryFiles()
+{
+ QString str;
+ for ( int i = 0; i < imageNum; i++ )
+ QFile::remove( str.sprintf("/tmp/qvfb_tmp_image_%04d.ppm", i) );
+ QFile::remove("/tmp/qvfb_tmp_ppmtompeg.params");
+ QFile::remove("/tmp/qvfb_tmp_output.log");
+ imageNum = 0;
+}
+
+// toggles between recording and paused (usually when record button clicked)
+void AnimationSaveWidget::toggleRecord()
+{
+ if ( recording ) {
+ recLED->setPixmap( recOff );
+ recBt->setText( tr("Record") );
+ statusText->setText( tr("Paused. Click record to resume, or save if done."));
+ killTimer( timerId );
+ timerId = -1;
+ elapsed = tm.elapsed();
+ } else {
+ recLED->setPixmap( recOn );
+ recBt->setText( tr("Pause") );
+ statusText->setText( tr("Recording..."));
+ tm.start();
+ if ( elapsed == 0 ) {
+ savingAsMpeg = mpegSave->isChecked();
+ if ( !savingAsMpeg ) {
+ delete animation;
+ animation = new QAnimationWriter("/tmp/qvfb_tmp_animation.mng","MNG");
+ animation->setFrameRate(24);
+ if ( view )
+ animation->appendFrame(view->image());
+ }
+ }
+ tm = tm.addMSecs(-elapsed);
+ elapsed = 0;
+ timerId = startTimer(1000 / 24);
+ }
+ recording = !recording;
+}
+
+// Reset everything to initial state of not recording
+void AnimationSaveWidget::reset()
+{
+ if ( recording ) {
+ toggleRecord();
+ statusText->setText( tr("Click record to begin recording."));
+ removeTemporaryFiles();
+ }
+ progressBar->setValue( 0 );
+ timeDpy->setText( "00:00" );
+ elapsed = 0;
+ imageNum = 0;
+ delete animation;
+ animation = 0;
+}
+
+// Prompt for filename to save to and put animation in that file
+void AnimationSaveWidget::save()
+{
+ if ( recording )
+ toggleRecord(); // pauses
+ statusText->setText( tr("Saving... "));
+
+ QString filename;
+ if ( savingAsMpeg ) {
+ filename = QFileDialog::getSaveFileName(this, tr("Save animation..."), "", "*.mpg");
+ if ( !filename.isNull() )
+ convertToMpeg(filename);
+ } else {
+ filename = QFileDialog::getSaveFileName(this, tr("Save animation..."), "", "*.mng");
+ if (filename.isNull()) {
+ statusText->setText(tr("Save canceled."));
+ } else {
+ QFile::remove(filename);
+ bool success = QFile::rename(QLatin1String("/tmp/qvfb_tmp_animation.mng"),
+ filename);
+ if (success) {
+ statusText->setText(tr("Finished saving."));
+ reset();
+ } else {
+ statusText->setText(tr("Save failed!"));
+ }
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "qvfb.moc"
diff --git a/src/qvfb/qvfb.h b/src/qvfb/qvfb.h
new file mode 100644
index 000000000..d2827278e
--- /dev/null
+++ b/src/qvfb/qvfb.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVFB_H
+#define QVFB_H
+
+#include <QMainWindow>
+#include <QStringList>
+#include "qvfbview.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVFbAbstractView;
+class QVFbRateDialog;
+class QPopupMenu;
+class QMenuData;
+class QAction;
+class Config;
+class DeviceSkin;
+class QVFb;
+class QLabel;
+class QMenu;
+class QScrollArea;
+
+class Zoomer : public QWidget {
+ Q_OBJECT
+public:
+ Zoomer(QVFb* target);
+
+private slots:
+ void zoom(int);
+
+private:
+ QVFb *qvfb;
+ QLabel *label;
+};
+
+class QVFb: public QMainWindow
+{
+ Q_OBJECT
+public:
+ enum DisplayType { QWS, X11 };
+
+ QVFb( int display_id, int w, int h, int d, int r, const QString &skin, DisplayType displayType, QWidget *parent = 0, Qt::WindowFlags wflags = 0 );
+ ~QVFb();
+
+ void enableCursor( bool e );
+
+ QSize sizeHint() const;
+
+public slots:
+ void popupMenu();
+
+protected slots:
+ void saveImage();
+ void toggleAnimation();
+ void toggleCursor();
+ void changeRate();
+ void setRate(int);
+ void about();
+
+ void configure();
+ void skinConfigChosen(int i);
+ void chooseSize(const QSize& sz);
+ void chooseDepth(int depth, QVFbView::PixelFormat displayFormat);
+
+ void setZoom1();
+ void setZoom2();
+ void setZoom3();
+ void setZoom4();
+ void setZoomHalf();
+ void setZoom075();
+
+ void setZoom();
+
+ void setRot0();
+ void setRot90();
+ void setRot180();
+ void setRot270();
+
+public slots:
+ void setZoom(double);
+ void setRotation(QVFbView::Rotation);
+
+protected:
+ template <typename T>
+ void createMenu(T *menu);
+ QMenu* createFileMenu();
+ QMenu* createViewMenu();
+ QMenu* createHelpMenu();
+
+private:
+ void findSkins(const QString &currentSkin);
+ void init( int display_id, int w, int h, int d, int r, const QString& skin );
+ DeviceSkin *skin;
+ double skinscaleH,skinscaleV;
+ QVFbAbstractView *view;
+ QVFbAbstractView *secondaryView;
+ QVFbRateDialog *rateDlg;
+ QMenu *viewMenu;
+ QAction *cursorAction;
+ Config* config;
+ QStringList skinnames;
+ QStringList skinfiles;
+ int currentSkinIndex;
+ Zoomer *zoomer;
+ QScrollArea* scroller;
+ DisplayType displayType;
+
+ int refreshRate;
+private slots:
+ void setGamma400(int n);
+ void setR400(int n);
+ void setG400(int n);
+ void setB400(int n);
+ void updateGammaLabels();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/qvfb.pro b/src/qvfb/qvfb.pro
new file mode 100644
index 000000000..c101d00a5
--- /dev/null
+++ b/src/qvfb/qvfb.pro
@@ -0,0 +1,64 @@
+TEMPLATE = app
+CONFIG += qt warn_on uic
+TARGET = qvfb
+DESTDIR = ../../bin
+
+!win32:!embedded:!mac:CONFIG += x11
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+DEPENDPATH = ../../include
+INCLUDEPATH += ../../src/gui/embedded
+
+FORMS = config.ui
+HEADERS = qvfb.h \
+ qvfbview.h \
+ qvfbratedlg.h \
+ qanimationwriter.h \
+ gammaview.h \
+ qvfbprotocol.h \
+ qvfbshmem.h \
+ qvfbmmap.h \
+ ../../src/gui/embedded/qvfbhdr.h \
+ ../../src/gui/embedded/qlock_p.h \
+ ../../src/gui/embedded/qwssignalhandler_p.h
+
+SOURCES = qvfb.cpp \
+ qvfbview.cpp \
+ qvfbratedlg.cpp \
+ main.cpp \
+ qanimationwriter.cpp \
+ qvfbprotocol.cpp \
+ qvfbshmem.cpp \
+ qvfbmmap.cpp \
+ ../../src/gui/embedded/qlock.cpp \
+ ../../src/gui/embedded/qwssignalhandler.cpp
+
+include(../shared/deviceskin/deviceskin.pri)
+
+contains(QT_CONFIG, opengl) {
+ QT += opengl
+}
+
+contains(QT_CONFIG, system-png) {
+ LIBS += -lpng
+} else {
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/libpng
+}
+contains(QT_CONFIG, system-zlib) {
+ LIBS += -lz
+} else {
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/zlib
+}
+
+unix:x11 {
+ HEADERS += qvfbx11view.h \
+ x11keyfaker.h \
+ qtopiakeysym.h
+ SOURCES += qvfbx11view.cpp \
+ x11keyfaker.cpp
+ LIBS += -lXtst
+}
+
+RESOURCES += qvfb.qrc
diff --git a/src/qvfb/qvfb.qrc b/src/qvfb/qvfb.qrc
new file mode 100644
index 000000000..27c39df7a
--- /dev/null
+++ b/src/qvfb/qvfb.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res">
+ <file>images/logo.png</file>
+ <file>images/logo-nt.png</file>
+</qresource>
+</RCC>
+
diff --git a/src/qvfb/qvfbmmap.cpp b/src/qvfb/qvfbmmap.cpp
new file mode 100644
index 000000000..809ffe561
--- /dev/null
+++ b/src/qvfb/qvfbmmap.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbmmap.h"
+#include "qvfbhdr.h"
+
+#include <QTimer>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+QMMapViewProtocol::QMMapViewProtocol(int displayid, const QSize &s,
+ int d, QObject *parent)
+ : QVFbViewProtocol(displayid, parent), hdr(0), dataCache(0), windowId(0)
+{
+ switch (d) {
+ case 1:
+ case 4:
+ case 8:
+ case 12:
+ case 15:
+ case 16:
+ case 18:
+ case 24:
+ case 32:
+ break;
+ default:
+ qFatal("Unsupported bit depth %d\n", d);
+ }
+
+ fileName = QString("/tmp/.qtvfb_map-%1").arg(displayid);
+
+ int w = s.width();
+ int h = s.height();
+
+
+ kh = new QVFbKeyPipeProtocol(displayid);
+ mh = new QVFbMouseLinuxTP(displayid);
+
+ int bpl;
+ if (d < 8)
+ bpl = (w * d + 7) / 8;
+ else
+ bpl = w * ((d + 7) / 8);
+
+ displaySize = bpl * h;
+
+ unsigned char *data;
+ uint data_offset_value = sizeof(QVFbHeader);
+ const int page_size = getpagesize();
+ if (data_offset_value % page_size)
+ data_offset_value += page_size - (data_offset_value % page_size);
+
+ dataSize = bpl * h + data_offset_value;
+
+ unlink(fileName.toLocal8Bit().data());
+ fd = ::open( fileName.toLocal8Bit().data(), O_CREAT|O_RDWR, 0666 );
+ ::lseek(fd, dataSize, SEEK_SET);
+ ::write(fd, "\0", 1);
+ if (fd < 0) {
+ data = (unsigned char *)-1;
+ } else {
+ // might need to do something about size?
+ data = (unsigned char *)mmap(NULL, dataSize, PROT_WRITE | PROT_READ,
+ MAP_SHARED, fd, 0);
+ if (data == MAP_FAILED)
+ data = (unsigned char *)-1;
+ }
+
+ if ( (long)data == -1 ){
+ delete kh;
+ delete mh;
+ qFatal( "Cannot attach to mapped file %s", fileName.toLocal8Bit().data());
+ }
+ dataCache = (unsigned char *)malloc(displaySize);
+ memset(dataCache, 0, displaySize);
+ memset(data+sizeof(QVFbHeader), 0, displaySize);
+
+ hdr = (QVFbHeader *)data;
+ hdr->width = w;
+ hdr->height = h;
+ hdr->depth = d;
+ hdr->linestep = bpl;
+ hdr->numcols = 0;
+ hdr->dataoffset = data_offset_value;
+ hdr->update = QRect();
+ hdr->brightness = 255;
+ hdr->windowId = 0;
+
+ mRefreshTimer = new QTimer(this);
+ connect(mRefreshTimer, SIGNAL(timeout()), this, SLOT(flushChanges()));
+}
+
+QMMapViewProtocol::~QMMapViewProtocol()
+{
+ munmap((char *)hdr, dataSize);
+ ::close(fd);
+ unlink(fileName.toLocal8Bit().constData());
+ free(dataCache);
+ delete kh;
+ delete mh;
+}
+
+int QMMapViewProtocol::brightness() const
+{
+ return hdr->brightness;
+}
+
+int QMMapViewProtocol::width() const
+{
+ return hdr->width;
+}
+
+int QMMapViewProtocol::height() const
+{
+ return hdr->height;
+}
+
+int QMMapViewProtocol::depth() const
+{
+ return hdr->depth;
+}
+
+int QMMapViewProtocol::linestep() const
+{
+ return hdr->linestep;
+}
+
+int QMMapViewProtocol::numcols() const
+{
+ return hdr->numcols;
+}
+
+QVector<QRgb> QMMapViewProtocol::clut() const
+{
+ QVector<QRgb> vector(hdr->numcols);
+ for (int i=0; i < hdr->numcols; ++i)
+ vector[i] = hdr->clut[i];
+
+ return vector;
+}
+
+unsigned char *QMMapViewProtocol::data() const
+{
+ return dataCache;
+ //return ((unsigned char *)hdr)+hdr->dataoffset;
+}
+
+void QMMapViewProtocol::flushChanges()
+{
+ // based of dirty rect, copy changes from hdr to hdrcopy
+ memcpy(dataCache, ((char *)hdr) + hdr->dataoffset, displaySize);
+ emit displayDataChanged(QRect(0, 0, width(), height()));
+}
+
+void QMMapViewProtocol::setRate(int interval)
+{
+ if (interval > 0)
+ return mRefreshTimer->start(1000/interval);
+ else
+ mRefreshTimer->stop();
+}
+
+int QMMapViewProtocol::rate() const
+{
+ int i = mRefreshTimer->interval();
+ if (i > 0)
+ return 1000/i;
+ else
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qvfb/qvfbmmap.h b/src/qvfb/qvfbmmap.h
new file mode 100644
index 000000000..e7085d56d
--- /dev/null
+++ b/src/qvfb/qvfbmmap.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QVFB_MMAP_PROTOCOL_H
+#define QVFB_MMAP_PROTOCOL_H
+
+#include "qvfbprotocol.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVFbHeader;
+class QTimer;
+class QMMapViewProtocol : public QVFbViewProtocol
+{
+ Q_OBJECT
+public:
+ QMMapViewProtocol(int display_id, const QSize &size, int depth, QObject *parent = 0);
+ ~QMMapViewProtocol();
+
+ int width() const;
+ int height() const;
+ int depth() const;
+ int linestep() const;
+ int numcols() const;
+ QVector<QRgb> clut() const;
+ unsigned char *data() const;
+ int brightness() const;
+
+ void setRate(int);
+ int rate() const;
+
+protected slots:
+ void flushChanges();
+
+protected:
+ QVFbKeyProtocol *keyHandler() const { return kh; }
+ QVFbMouseProtocol *mouseHandler() const { return mh; }
+
+private:
+ QVFbKeyPipeProtocol *kh;
+ QVFbMouseLinuxTP *mh;
+ QVFbHeader *hdr;
+ QString fileName;
+ int fd;
+ size_t dataSize;
+ size_t displaySize;
+ unsigned char *dataCache;
+ QTimer *mRefreshTimer;
+ WId windowId;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/qvfbprotocol.cpp b/src/qvfb/qvfbprotocol.cpp
new file mode 100644
index 000000000..34a526429
--- /dev/null
+++ b/src/qvfb/qvfbprotocol.cpp
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbprotocol.h"
+#include "qvfbhdr.h"
+
+#include <QDebug>
+#include <QTimer>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <math.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef Q_OS_UNIX
+#include <unistd.h>
+#endif
+
+#include "qvfbshmem.h"
+
+QT_BEGIN_NAMESPACE
+
+QVFbViewProtocol::QVFbViewProtocol(int display_id, QObject *parent) :
+ QObject(parent), mDisplayId(display_id) { }
+
+QVFbViewProtocol::~QVFbViewProtocol() {}
+
+void QVFbViewProtocol::flushChanges() {}
+
+void QVFbViewProtocol::sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat)
+{
+ if (keyHandler())
+ keyHandler()->sendKeyboardData(unicode, keycode, modifiers, press, repeat);
+}
+
+void QVFbViewProtocol::sendMouseData(const QPoint &pos, int buttons, int wheel)
+{
+ if (mouseHandler())
+ mouseHandler()->sendMouseData(pos, buttons, wheel);
+}
+
+static int openPipe(const char *fileName)
+{
+ unlink(fileName);
+
+ mkfifo(fileName, 0666);
+ int fd = ::open(fileName, O_RDWR | O_NDELAY);
+ return fd;
+}
+
+QVFbKeyPipeProtocol::QVFbKeyPipeProtocol(int display_id)
+ : QVFbKeyProtocol(display_id)
+{
+ fileName = QT_VFB_KEYBOARD_PIPE(display_id);
+ fd = openPipe(fileName.toLocal8Bit().constData());
+
+ if (fd == -1)
+ qFatal("Cannot open keyboard pipe %s", fileName.toLocal8Bit().data());
+}
+
+QVFbKeyPipeProtocol::~QVFbKeyPipeProtocol()
+{
+ sendKeyboardData(0, 0, 0, true, false); // magic die key
+ ::close(fd);
+ unlink(fileName.toLocal8Bit().constData());
+}
+
+void QVFbKeyPipeProtocol::sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat)
+{
+ QVFbKeyData kd;
+ kd.unicode = unicode[0].unicode();
+ kd.keycode = keycode;
+ kd.modifiers = static_cast<Qt::KeyboardModifier>(modifiers);
+ kd.press = press;
+ kd.repeat = repeat;
+ write(fd, &kd, sizeof(QVFbKeyData));
+}
+
+QVFbMousePipe::QVFbMousePipe(int display_id)
+ : QVFbMouseProtocol(display_id)
+{
+ fileName = QT_VFB_MOUSE_PIPE(display_id);
+ fd = openPipe(fileName.toLocal8Bit().constData());
+
+ if (fd == -1)
+ qFatal("Cannot open mouse pipe %s", fileName.toLocal8Bit().data());
+}
+
+QVFbMousePipe::~QVFbMousePipe()
+{
+ ::close(fd);
+ unlink(fileName.toLocal8Bit().constData());
+}
+
+
+void QVFbMousePipe::sendMouseData(const QPoint &pos, int buttons, int wheel)
+{
+ write(fd, &pos, sizeof(QPoint));
+ write(fd, &buttons, sizeof(int));
+ write(fd, &wheel, sizeof(int));
+}
+
+QVFbMouseLinuxTP::QVFbMouseLinuxTP(int display_id)
+ : QObject(), QVFbMousePipe(display_id), lastPos(-1,-1)
+{
+ /* the timer is needed because a real touch screen send data as long as
+ there is pressure. And the linux tp driver will filter, requiring
+ a minimum of 5 samples before it even registers a press.
+ */
+ repeater = new QTimer(this);
+ connect(repeater, SIGNAL(timeout()), this, SLOT(repeatLastPress()));
+}
+
+QVFbMouseLinuxTP::~QVFbMouseLinuxTP()
+{
+}
+
+
+void QVFbMouseLinuxTP::sendMouseData(const QPoint &pos, int buttons, int)
+{
+ if (buttons & Qt::LeftButton) {
+ // press
+ repeater->start(5);
+ writeToPipe(pos, 1);
+ lastPos = pos;
+ } else {
+ // release
+ if (lastPos == QPoint(-1,-1))
+ return; /* only send one release */
+ repeater->stop();
+ writeToPipe(pos, 0);
+ lastPos = QPoint(-1,-1);
+ }
+}
+
+void QVFbMouseLinuxTP::writeToPipe(const QPoint &pos, ushort pressure)
+{
+ ushort v;
+ write(fd, &pressure, sizeof(ushort));
+ v = pos.x();
+ write(fd, &v, sizeof(ushort));
+ v = pos.y();
+ write(fd, &v, sizeof(ushort));
+ v = 1; // pad
+ write(fd, &v, sizeof(ushort));
+}
+
+void QVFbMouseLinuxTP::repeatLastPress()
+{
+ writeToPipe(lastPos, 1);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qvfb/qvfbprotocol.h b/src/qvfb/qvfbprotocol.h
new file mode 100644
index 000000000..d959b205a
--- /dev/null
+++ b/src/qvfb/qvfbprotocol.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QVFBPROTOCOL_H
+#define QVFBPROTOCOL_H
+
+#include <QImage>
+#include <QVector>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+class QVFbKeyProtocol;
+class QVFbMouseProtocol;
+class QVFbViewProtocol : public QObject
+{
+ Q_OBJECT
+public:
+ QVFbViewProtocol(int display_id, QObject *parent = 0);
+
+ virtual ~QVFbViewProtocol();
+
+ int id() const { return mDisplayId; }
+
+ void sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat);
+ void sendMouseData(const QPoint &pos, int buttons, int wheel);
+
+ virtual int width() const = 0;
+ virtual int height() const = 0;
+ virtual int depth() const = 0;
+ virtual int linestep() const = 0;
+ virtual int numcols() const = 0;
+ virtual QVector<QRgb> clut() const = 0;
+ virtual unsigned char *data() const = 0;
+ virtual int brightness() const = 0;
+
+ virtual void setRate(int) {}
+public slots:
+ virtual void flushChanges();
+
+signals:
+ void displayDataChanged(const QRect &);
+ void displayEmbedRequested(WId windowId);
+
+protected:
+ virtual QVFbKeyProtocol *keyHandler() const = 0;
+ virtual QVFbMouseProtocol *mouseHandler() const = 0;
+
+private:
+ int mDisplayId;
+};
+
+class QVFbKeyProtocol
+{
+public:
+ QVFbKeyProtocol(int display_id) : mDisplayId(display_id) {}
+ virtual ~QVFbKeyProtocol() {}
+
+ int id() const { return mDisplayId; }
+
+ virtual void sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat) = 0;
+
+private:
+ int mDisplayId;
+};
+
+class QVFbMouseProtocol
+{
+public:
+ QVFbMouseProtocol(int display_id) : mDisplayId(display_id) {}
+ virtual ~QVFbMouseProtocol() {}
+
+ int id() const { return mDisplayId; }
+
+ virtual void sendMouseData(const QPoint &pos, int buttons, int wheel) = 0;
+
+private:
+ int mDisplayId;
+};
+
+/* since there is very little variation in input protocols defaults are
+ provided */
+
+class QVFbKeyPipeProtocol : public QVFbKeyProtocol
+{
+public:
+ QVFbKeyPipeProtocol(int display_id);
+ ~QVFbKeyPipeProtocol();
+
+ void sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat);
+
+ QString pipeName() const { return fileName; }
+private:
+ int fd;
+ QString fileName;
+};
+
+class QVFbMousePipe: public QVFbMouseProtocol
+{
+public:
+ QVFbMousePipe(int display_id);
+ ~QVFbMousePipe();
+
+ void sendMouseData(const QPoint &pos, int buttons, int wheel);
+
+ QString pipeName() const { return fileName; }
+protected:
+ int fd;
+ QString fileName;
+};
+
+class QTimer;
+class QVFbMouseLinuxTP : public QObject, public QVFbMousePipe
+{
+ Q_OBJECT
+public:
+ QVFbMouseLinuxTP(int display_id);
+ ~QVFbMouseLinuxTP();
+
+ void sendMouseData(const QPoint &pos, int buttons, int wheel);
+
+protected slots:
+ void repeatLastPress();
+
+protected:
+ void writeToPipe(const QPoint &pos, ushort pressure);
+ QPoint lastPos;
+ QTimer *repeater;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/qvfbratedlg.cpp b/src/qvfb/qvfbratedlg.cpp
new file mode 100644
index 000000000..608cd7b2b
--- /dev/null
+++ b/src/qvfb/qvfbratedlg.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbratedlg.h"
+#include <QLayout>
+#include <QLabel>
+#include <qslider.h>
+#include <QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+QVFbRateDialog::QVFbRateDialog(int rate, QWidget *parent)
+ : QDialog(parent)
+{
+ oldRate = rate;
+
+ QVBoxLayout *tl = new QVBoxLayout(this);
+ tl->setMargin(5);
+
+ QLabel *label = new QLabel(tr("Target frame rate:"), this);
+ tl->addWidget(label);
+
+ QHBoxLayout *hl = new QHBoxLayout();
+ tl->addItem(hl);
+ rateSlider = new QSlider(Qt::Horizontal);
+ rateSlider->setMinimum(1);
+ rateSlider->setMaximum(100);
+ rateSlider->setPageStep(10);
+ rateSlider->setValue(rate);
+ hl->addWidget(rateSlider);
+ connect(rateSlider, SIGNAL(valueChanged(int)), this, SLOT(rateChanged(int)));
+ rateLabel = new QLabel(tr("%1fps").arg(rate), this);
+ hl->addWidget(rateLabel);
+
+ hl = new QHBoxLayout();
+ tl->addItem(hl);
+ QPushButton *pb = new QPushButton(tr("OK"), this);
+ connect(pb, SIGNAL(clicked()), this, SLOT(ok()));
+ hl->addWidget(pb);
+ pb = new QPushButton(tr("Cancel"), this);
+ connect(pb, SIGNAL(clicked()), this, SLOT(cancel()));
+ hl->addWidget(pb);
+}
+
+void QVFbRateDialog::rateChanged(int r)
+{
+ if (rateSlider->value() != r)
+ rateSlider->setValue(r);
+ rateLabel->setText(tr("%1fps").arg(r));
+ emit updateRate(r);
+}
+
+void QVFbRateDialog::cancel()
+{
+ rateChanged(oldRate);
+ reject();
+}
+
+void QVFbRateDialog::ok()
+{
+ oldRate = rateSlider->value();
+ accept();
+}
+
+QT_END_NAMESPACE
diff --git a/src/qvfb/qvfbratedlg.h b/src/qvfb/qvfbratedlg.h
new file mode 100644
index 000000000..7997f1b03
--- /dev/null
+++ b/src/qvfb/qvfbratedlg.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVFBRATEDLG_H
+#define QVFBRATEDLG_H
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QLabel;
+class QSlider;
+
+class QVFbRateDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ QVFbRateDialog(int value, QWidget *parent = 0);
+
+signals:
+ void updateRate(int r);
+
+protected slots:
+ void rateChanged(int r);
+ void cancel();
+ void ok();
+
+private:
+ QLabel *rateLabel;
+ QSlider *rateSlider;
+ int oldRate;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/qvfbshmem.cpp b/src/qvfb/qvfbshmem.cpp
new file mode 100644
index 000000000..45f276f89
--- /dev/null
+++ b/src/qvfb/qvfbshmem.cpp
@@ -0,0 +1,314 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlock_p.h"
+
+#include "qvfbshmem.h"
+#include "qvfbhdr.h"
+
+#include <QFile>
+#include <QTimer>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_WS_QWS
+#error qvfb must be compiled with the Qt for X11 package
+#endif
+
+// Get the name of the directory where Qt for Embedded Linux temporary data should
+// live.
+static QString qws_dataDir(int qws_display_id)
+{
+ QByteArray dataDir = QT_VFB_DATADIR(qws_display_id).toLocal8Bit();
+ if (mkdir(dataDir, 0700)) {
+ if (errno != EEXIST) {
+ qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
+ }
+ }
+
+ struct stat buf;
+ if (lstat(dataDir, &buf))
+ qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData());
+
+ if (!S_ISDIR(buf.st_mode))
+ qFatal("%s is not a directory", dataDir.constData());
+ if (buf.st_uid != getuid())
+ qFatal("Qt for Embedded Linux data directory is not owned by user %uh", getuid());
+
+ if ((buf.st_mode & 0677) != 0600)
+ qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
+ dataDir += "/";
+
+ return QString(dataDir);
+}
+
+
+static QString displayPipe;
+static QString displayPiped;
+class DisplayLock
+{
+public:
+ DisplayLock() : qlock(0) {
+ if (QFile::exists(displayPiped)) {
+ qlock = new QLock(displayPipe, 'd', false);
+ qlock->lock(QLock::Read);
+ }
+ }
+ ~DisplayLock() {
+ if (qlock) {
+ qlock->unlock();
+ delete qlock;
+ qlock = 0;
+ }
+ }
+private:
+ QLock *qlock;
+};
+
+QShMemViewProtocol::QShMemViewProtocol(int displayid, const QSize &s,
+ int d, QObject *parent)
+ : QVFbViewProtocol(displayid, parent), hdr(0), dataCache(0), lockId(-1),
+ windowId(0)
+{
+ int w = s.width();
+ int h = s.height();
+
+ QString username = "unknown";
+ const char *logname = getenv("LOGNAME");
+ if ( logname )
+ username = logname;
+
+ qws_dataDir(displayid);
+
+ QString oldPipe = "/tmp/qtembedded-" + username + "/" + QString("QtEmbedded-%1").arg(displayid);
+ int oldPipeSemkey = ftok(oldPipe.toLatin1().constData(), 'd');
+ if (oldPipeSemkey != -1) {
+ int oldPipeLockId = semget(oldPipeSemkey, 0, 0);
+ if (oldPipeLockId >= 0){
+ sembuf sops;
+ sops.sem_num = 0;
+ sops.sem_op = 1;
+ sops.sem_flg = SEM_UNDO;
+ int rv;
+ do {
+ rv = semop(lockId,&sops,1);
+ } while (rv == -1 && errno == EINTR);
+
+ perror("QShMemViewProtocol::QShMemViewProtocol");
+ qFatal("Cannot create lock file as an old version of QVFb has "
+ "opened %s. Close other QVFb and try again",
+ oldPipe.toLatin1().constData());
+ }
+ }
+
+ displayPipe = QTE_PIPE_QVFB(displayid);
+
+ kh = new QVFbKeyPipeProtocol(displayid);
+ /* should really depend on receiving qt version, but how can
+ one tell? */
+ mh = new QVFbMousePipe(displayid);
+
+ QString mousePipe = mh->pipeName();
+
+ key_t key = ftok(mousePipe.toLatin1().constData(), 'b');
+
+ int bpl;
+ if (d < 8)
+ bpl = (w * d + 7) / 8;
+ else
+ bpl = w * ((d + 7) / 8);
+
+ displaySize = bpl * h;
+
+ unsigned char *data;
+ uint data_offset_value = sizeof(QVFbHeader);
+
+ int dataSize = bpl * h + data_offset_value;
+ shmId = shmget(key, dataSize, IPC_CREAT | 0666);
+ if (shmId != -1)
+ data = (unsigned char *)shmat(shmId, 0, 0);
+ else {
+ struct shmid_ds shm;
+ shmctl(shmId, IPC_RMID, &shm);
+ shmId = shmget(key, dataSize, IPC_CREAT | 0666);
+ if (shmId == -1) {
+ perror("QShMemViewProtocol::QShMemViewProtocol");
+ qFatal("Cannot get shared memory 0x%08x", key);
+ }
+ data = (unsigned char *)shmat(shmId, 0, 0);
+ }
+
+ if ((long)data == -1) {
+ delete kh;
+ delete mh;
+ perror("QShMemViewProtocol::QShMemViewProtocol");
+ qFatal("Cannot attach to shared memory %d",shmId);
+ }
+ dataCache = (unsigned char *)malloc(displaySize);
+ memset(dataCache, 0, displaySize);
+ memset(data+sizeof(QVFbHeader), 0, displaySize);
+
+ hdr = (QVFbHeader *)data;
+ hdr->width = w;
+ hdr->height = h;
+ hdr->depth = d;
+ hdr->linestep = bpl;
+ hdr->dataoffset = data_offset_value;
+ hdr->update = QRect();
+ hdr->dirty = 0;
+ hdr->numcols = 0;
+ hdr->viewerVersion = QT_VERSION;
+ hdr->brightness = 255;
+ hdr->windowId = 0;
+
+ displayPiped = displayPipe + 'd';
+
+
+ mRefreshTimer = new QTimer(this);
+ connect(mRefreshTimer, SIGNAL(timeout()), this, SLOT(flushChanges()));
+}
+
+QShMemViewProtocol::~QShMemViewProtocol()
+{
+ struct shmid_ds shm;
+ shmdt( (char*)hdr );
+ shmctl( shmId, IPC_RMID, &shm );
+ free(dataCache);
+ delete kh;
+ delete mh;
+}
+
+int QShMemViewProtocol::width() const
+{
+ return hdr->width;
+}
+
+int QShMemViewProtocol::height() const
+{
+ return hdr->height;
+}
+
+int QShMemViewProtocol::depth() const
+{
+ return hdr->depth;
+}
+
+int QShMemViewProtocol::linestep() const
+{
+ return hdr->linestep;
+}
+
+int QShMemViewProtocol::numcols() const
+{
+ return hdr->numcols;
+}
+
+QVector<QRgb> QShMemViewProtocol::clut() const
+{
+ QVector<QRgb> vector(hdr->numcols);
+ for (int i=0; i < hdr->numcols; ++i)
+ vector[i]=hdr->clut[i];
+
+ return vector;
+}
+
+unsigned char *QShMemViewProtocol::data() const
+{
+ return dataCache;
+ //return ((unsigned char *)hdr)+hdr->dataoffset;
+}
+
+int QShMemViewProtocol::brightness() const
+{
+ return hdr->brightness;
+}
+
+void QShMemViewProtocol::flushChanges()
+{
+ QRect r;
+ if (hdr->dirty) {
+ DisplayLock();
+
+ hdr->dirty = false;
+ r = hdr->update;
+ hdr->update = QRect();
+
+ if (hdr->windowId != windowId) {
+ windowId = hdr->windowId;
+ emit displayEmbedRequested(hdr->windowId);
+ } else if (!hdr->windowId) {
+ // copy the memory area, for now, be inefficient.
+ memcpy(dataCache, ((char *)hdr) + hdr->dataoffset, displaySize);
+ }
+ }
+ emit displayDataChanged(r);
+}
+
+void QShMemViewProtocol::setRate(int interval)
+{
+ if (interval > 0)
+ return mRefreshTimer->start(1000/interval);
+ else
+ mRefreshTimer->stop();
+}
+
+int QShMemViewProtocol::rate() const
+{
+ int i = mRefreshTimer->interval();
+ if (i > 0)
+ return 1000/i;
+ else
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qvfb/qvfbshmem.h b/src/qvfb/qvfbshmem.h
new file mode 100644
index 000000000..18fb9d478
--- /dev/null
+++ b/src/qvfb/qvfbshmem.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QVFB_SHM_PROTOCOL_H
+#define QVFB_SHM_PROTOCOL_H
+
+#include "qvfbprotocol.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVFbHeader;
+class QTimer;
+class QShMemViewProtocol : public QVFbViewProtocol
+{
+ Q_OBJECT
+public:
+ QShMemViewProtocol(int display_id, const QSize &size, int depth, QObject *parent = 0);
+ ~QShMemViewProtocol();
+
+ int width() const;
+ int height() const;
+ int depth() const;
+ int linestep() const;
+ int numcols() const;
+ QVector<QRgb> clut() const;
+ unsigned char *data() const;
+ int brightness() const;
+
+ void setRate(int);
+ int rate() const;
+
+protected slots:
+ void flushChanges();
+
+protected:
+ QVFbKeyProtocol *keyHandler() const { return kh; }
+ QVFbMouseProtocol *mouseHandler() const { return mh; }
+
+private:
+ QVFbKeyPipeProtocol *kh;
+ QVFbMousePipe *mh;
+ QVFbHeader *hdr;
+ size_t displaySize;
+ unsigned char *dataCache;
+ int lockId;
+ int shmId;
+ QTimer *mRefreshTimer;
+ WId windowId;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/qvfbview.cpp b/src/qvfb/qvfbview.cpp
new file mode 100644
index 000000000..850c21339
--- /dev/null
+++ b/src/qvfb/qvfbview.cpp
@@ -0,0 +1,888 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbview.h"
+#include "qvfbshmem.h"
+#include "qvfbmmap.h"
+
+#include "qanimationwriter.h"
+#include <QApplication>
+#include <QPainter>
+#include <QImage>
+#include <QBitmap>
+#include <QMatrix>
+#include <QPaintEvent>
+#include <QScrollArea>
+#include <QFile>
+#include <QDebug>
+
+#ifdef Q_WS_X11
+#include <QX11EmbedContainer>
+#include <QHBoxLayout>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+extern int qvfb_protocol;
+
+QVFbAbstractView::QVFbAbstractView( QWidget *parent )
+#ifdef QVFB_USE_GLWIDGET
+ : QGLWidget( parent )
+#else
+ : QWidget( parent )
+#endif
+{
+}
+
+QVFbAbstractView::~QVFbAbstractView()
+{
+}
+
+QVFbView::QVFbView(int id, int w, int h, int d, Rotation r, QWidget *parent)
+ : QVFbAbstractView(parent),
+ viewdepth(d), viewFormat(DefaultFormat), rgb_swapped(0), rsh(0), gsh(0), bsh(0), rmax(15), gmax(15), bmax(15),
+ contentsWidth(w), contentsHeight(h), gred(1.0), ggreen(1.0), gblue(1.0),
+ gammatable(0), refreshRate(30), animation(0),
+ hzm(0.0), vzm(0.0), mView(0),
+ emulateTouchscreen(false), emulateLcdScreen(false), rotation(r)
+#ifdef Q_WS_X11
+ , embedContainer(0)
+#endif
+{
+ switch(qvfb_protocol) {
+ default:
+ case 0:
+ mView = new QShMemViewProtocol(id, QSize(w, h), d, this);
+ break;
+ case 1:
+ mView = new QMMapViewProtocol(id, QSize(w, h), d, this);
+ break;
+ }
+
+ connect(mView, SIGNAL(displayDataChanged(QRect)),
+ SLOT(refreshDisplay(QRect)));
+#ifdef Q_WS_X11
+ connect(mView, SIGNAL(displayEmbedRequested(WId)),
+ this, SLOT(embedDisplay(WId)));
+#endif
+
+ setAttribute(Qt::WA_PaintOnScreen, viewFormat != ARGBFormat);
+ setMouseTracking(true);
+ setFocusPolicy(Qt::StrongFocus);
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ setZoom(1.0,1.0);
+
+ setGamma(1.0,1.0,1.0);
+ mView->setRate(30);
+}
+
+QVFbView::~QVFbView()
+{
+ stopAnimation();
+ sendKeyboardData(0, 0, 0, true, false); // magic die key
+#ifdef Q_WS_X11
+ delete embedContainer;
+#endif
+}
+
+QSize QVFbView::sizeHint() const
+{
+ return QSize(contentsWidth, contentsHeight);
+}
+
+void QVFbView::setRate(int i)
+{
+ mView->setRate(i);
+}
+
+void QVFbView::setGamma(double gr, double gg, double gb)
+{
+ gred = gr; ggreen = gg; gblue = gb;
+
+ switch (viewdepth) {
+ case 12:
+ rsh = 12;
+ gsh = 7;
+ bsh = 1;
+ rmax = 15;
+ gmax = 15;
+ bmax = 15;
+ break;
+ case 15:
+ rsh = 10;
+ gsh = 5;
+ bsh = 0;
+ rmax = 31;
+ gmax = 31;
+ bmax = 31;
+ break;
+ case 16:
+ rsh = 11;
+ gsh = 5;
+ bsh = 0;
+ rmax = 31;
+ gmax = 63;
+ bmax = 31;
+ break;
+ case 18:
+ rsh = 12;
+ gsh = 6;
+ bsh = 0;
+ rmax = 63;
+ gmax = 63;
+ bmax = 63;
+ break;
+ case 24:
+ case 32:
+ rsh = 16;
+ gsh = 8;
+ bsh = 0;
+ rmax = 255;
+ gmax = 255;
+ bmax = 255;
+ }
+ int mm = qMax(rmax,qMax(gmax,bmax))+1;
+ if (gammatable)
+ delete [] gammatable;
+ gammatable = new QRgb[mm];
+ for (int i=0; i<mm; i++) {
+ int r = int(pow(i,gr)*255/rmax);
+ int g = int(pow(i,gg)*255/gmax);
+ int b = int(pow(i,gb)*255/bmax);
+ if (r > 255) r = 255;
+ if (g > 255) g = 255;
+ if (b > 255) b = 255;
+ gammatable[i] = qRgb(r,g,b);
+//qDebug("%d: %d,%d,%d",i,r,g,b);
+ }
+
+ mView->flushChanges();
+}
+
+void QVFbView::getGamma(int i, QRgb& rgb)
+{
+ if (i > 255) i = 255;
+ if (i < 0) i = 0;
+ rgb = qRgb(qRed(gammatable[i*rmax/255]),
+ qGreen(gammatable[i*rmax/255]),
+ qBlue(gammatable[i*rmax/255]));
+}
+
+int QVFbView::displayId() const
+{
+ return mView->id();
+}
+
+int QVFbView::displayWidth() const
+{
+ return mView->width();
+}
+
+int QVFbView::displayHeight() const
+{
+ return mView->height();
+}
+
+int QVFbView::displayDepth() const
+{
+ return viewdepth;
+}
+
+QVFbView::PixelFormat QVFbView::displayFormat() const
+{
+ return viewFormat;
+}
+
+QVFbView::Rotation QVFbView::displayRotation() const
+{
+ return rotation;
+}
+
+void QVFbView::setZoom(double hz, double vz)
+{
+ if (hzm != hz || vzm != vz) {
+ hzm = hz;
+ vzm = vz;
+ mView->flushChanges();
+
+ contentsWidth = int(displayWidth()*hz);
+ contentsHeight = int(displayHeight()*vz);
+ if (rotation & 1)
+ qSwap(contentsWidth,contentsHeight);
+ resize(contentsWidth, contentsHeight);
+
+ if (isVisible()) {
+ updateGeometry();
+ qApp->sendPostedEvents();
+ topLevelWidget()->adjustSize();
+ update();
+ }
+ }
+}
+
+void QVFbView::setRotation(QVFbView::Rotation r)
+{
+ rotation = r;
+ // Force update...
+ double ohzm = hzm;
+ hzm=0.0;
+ setZoom(ohzm,vzm);
+}
+
+static QRect mapToDevice(const QRect &r, const QSize &s, QVFbView::Rotation rotation)
+{
+ int x1 = r.x();
+ int y1 = r.y();
+ int x2 = r.right();
+ int y2 = r.bottom();
+ int w = s.width();
+ int h = s.height();
+ switch (rotation) {
+ case QVFbView::Rot90:
+ return QRect(
+ QPoint(y1, w - x1),
+ QPoint(y2, w - x2)).normalized();
+ case QVFbView::Rot180:
+ return QRect(
+ QPoint(w - x1, h - y1),
+ QPoint(w - x2, h - y2)).normalized();
+ case QVFbView::Rot270:
+ return QRect(
+ QPoint(h - y1, x1),
+ QPoint(h - y2, x2)).normalized();
+ default:
+ break;
+ }
+ return r;
+}
+
+static QRect mapFromDevice(const QRect &r, const QSize &s, QVFbView::Rotation rotation)
+{
+ return mapToDevice(r,s,QVFbView::Rotation(4-(int)rotation));
+}
+
+void QVFbView::sendMouseData(const QPoint &pos, int buttons, int wheel)
+{
+ QPoint p = mapToDevice(QRect(pos,QSize(1,1)), QSize(int(width()/hzm), int(height()/vzm)), rotation).topLeft();
+ mView->sendMouseData(p, buttons, wheel);
+}
+
+void QVFbView::sendKeyboardData(QString unicode, int keycode, int modifiers,
+ bool press, bool repeat)
+{
+ mView->sendKeyboardData(unicode, keycode, modifiers, press, repeat);
+}
+
+void QVFbView::refreshDisplay(const QRect &r)
+{
+ if (animation) {
+ if (r.isEmpty()) {
+ animation->appendBlankFrame();
+ } else {
+ int l;
+ QImage img = getBuffer(r, l);
+ animation->appendFrame(img,QPoint(r.x(),r.y()));
+ }
+ }
+ if (!r.isNull()) {
+ if (hzm == 1.0 && vzm == 1.0) // hw: workaround for 4.3.1
+ update(mapFromDevice(r, QSize(displayWidth(), displayHeight()), rotation));
+ else
+ update();
+ }
+}
+
+static void dim(QRgb* rgb, int n, int brightness)
+{
+ uchar* b = (uchar*)rgb;
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ b++;
+#endif
+ while (n--) {
+ b[0] = (uint)b[0] * brightness / 255;
+ b[1] = (uint)b[1] * brightness / 255;
+ b[2] = (uint)b[2] * brightness / 255;
+ b += 4;
+ }
+}
+
+QImage QVFbView::getBuffer(const QRect &r, int &leading) const
+{
+ const int brightness = mView->brightness();
+ if ( brightness == 0 ) {
+ QImage img(r.size(),QImage::Format_RGB32);
+ img.fill(0);
+ leading = 0;
+ return img;
+ }
+
+ static QByteArray buffer;
+
+ const int requiredSize = r.width() * r.height() * 4;
+
+ QImage img;
+ leading = 0;
+
+ switch (viewdepth) {
+ case 1: {
+ if (requiredSize > buffer.size())
+ buffer.resize(requiredSize);
+
+ // XXX: hw: replace by drawhelper functionality
+
+ const int pixelsPerByte = 8;
+ quint8 *src = reinterpret_cast<quint8*>(mView->data())
+ + r.y() * mView->linestep() + r.x() / pixelsPerByte;
+ const int align = qMin(r.width(), (8 - (r.x() & 7)) & 7);
+ const int doAlign = (align > 0 ? 1 : 0);
+ const int tail = qMin(r.width(), (r.width() - align) & 7);
+ const int doTail = (tail > 0 ? 1 : 0);
+ const int width8 = (r.width() - align) / pixelsPerByte;
+ const int stride = mView->linestep() - (width8 + doAlign);
+
+ uchar *b = reinterpret_cast<uchar*>(buffer.data());
+ img = QImage(b, r.width(), r.height(), QImage::Format_RGB32);
+ for (int y = 0; y < r.height(); ++y) {
+ quint32 *dest = reinterpret_cast<quint32*>(img.scanLine(y));
+ quint8 c;
+
+ if (doAlign) {
+ switch (align) {
+ case 7: c = ((*src & 0x40) >> 6) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 6: c = ((*src & 0x20) >> 5) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 5: c = ((*src & 0x10) >> 4) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 4: c = ((*src & 0x08) >> 3) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 3: c = ((*src & 0x04) >> 2) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 2: c = ((*src & 0x02) >> 1) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 1: c = ((*src & 0x01)) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ }
+ ++src;
+ }
+ for (int i = 0; i < width8; ++i) {
+ c = ((*src & 0x80) >> 7) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x40) >> 6) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x20) >> 5) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x10) >> 4) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x08) >> 3) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x04) >> 2) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x02) >> 1) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x01)) * 0xff;
+ *dest++ = qRgb(c, c, c);
+
+ ++src;
+ }
+ if (doTail) {
+ switch (tail) {
+ case 7: c = ((*src & 0x02) >> 1) * 0xff;
+ dest[6] = qRgb(c, c, c);
+ case 6: c = ((*src & 0x04) >> 2) * 0xff;
+ dest[5] = qRgb(c, c, c);
+ case 5: c = ((*src & 0x08) >> 3) * 0xff;
+ dest[4] = qRgb(c, c, c);
+ case 4: c = ((*src & 0x10) >> 4) * 0xff;
+ dest[3] = qRgb(c, c, c);
+ case 3: c = ((*src & 0x20) >> 5) * 0xff;
+ dest[2] = qRgb(c, c, c);
+ case 2: c = ((*src & 0x40) >> 6) * 0xff;
+ dest[1] = qRgb(c, c, c);
+ case 1: c = ((*src & 0x80) >> 7) * 0xff;
+ dest[0] = qRgb(c, c, c);
+ }
+ }
+ src += stride;
+ }
+ break;
+ }
+
+ case 2: {
+ if (requiredSize > buffer.size())
+ buffer.resize(requiredSize);
+
+ // XXX: hw: replace by drawhelper functionality
+
+ const int pixelsPerByte = 4;
+ quint8 *src = reinterpret_cast<quint8*>(mView->data())
+ + r.y() * mView->linestep() + r.x() / pixelsPerByte;
+ const int align = qMin(r.width(), (4 - (r.x() & 3)) & 3);
+ const int doAlign = (align > 0 ? 1 : 0);
+ const int tail = qMin(r.width(), (r.width() - align) & 3);
+ const int doTail = (tail > 0 ? 1 : 0);
+ const int width8 = (r.width() - align) / pixelsPerByte;
+ const int stride = mView->linestep() - (width8 + doAlign);
+
+ uchar *b = reinterpret_cast<uchar*>(buffer.data());
+ img = QImage(b, r.width(), r.height(), QImage::Format_RGB32);
+ for (int y = 0; y < r.height(); ++y) {
+ quint32 *dest = reinterpret_cast<quint32*>(img.scanLine(y));
+ quint8 c;
+
+ if (doAlign) {
+ switch (align) {
+ case 3: c = ((*src & 0x30) >> 4) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ case 2: c = ((*src & 0x0c) >> 2) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ case 1: c = ((*src & 0x03)) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ }
+ ++src;
+ }
+ for (int i = 0; i < width8; ++i) {
+ c = ((*src & 0xc0) >> 6) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x30) >> 4) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x0c) >> 2) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x03)) * 0x55;
+ *dest++ = qRgb(c, c, c);
+
+ ++src;
+ }
+ if (doTail) {
+ switch (tail) {
+ case 3: c = ((*src & 0x0c) >> 2) * 0x55;
+ dest[2] = qRgb(c, c, c);
+ case 2: c = ((*src & 0x30) >> 4) * 0x55;
+ dest[1] = qRgb(c, c, c);
+ case 1: c = ((*src & 0xc0) >> 6) * 0x55;
+ dest[0] = qRgb(c, c, c);
+ }
+ }
+ src += stride;
+ }
+ break;
+ }
+
+ case 4: {
+ if (requiredSize > buffer.size())
+ buffer.resize(requiredSize);
+
+ // XXX: hw: replace by drawhelper functionality
+
+ const int pixelsPerByte = 2;
+ const int doAlign = r.x() & 1;
+ const int doTail = (r.width() - doAlign) & 1;
+ const int width8 = (r.width() - doAlign) / pixelsPerByte;
+
+ uchar *b = reinterpret_cast<uchar*>(buffer.data());
+ img = QImage(b, r.width(), r.height(), QImage::Format_RGB32);
+ for (int y = 0; y < r.height(); ++y) {
+ const quint8 *sptr = mView->data()
+ + (r.y() + y) * mView->linestep()
+ + r.x() / pixelsPerByte;
+ quint32 *dptr = reinterpret_cast<quint32*>(img.scanLine(y));
+
+ if (doAlign) {
+ quint8 c = (*sptr++ & 0x0f);
+ c |= (c << 4);
+ *dptr++ = qRgb(c, c, c);
+ }
+
+ for (int i = 0; i < width8; ++i) {
+ quint8 c1 = (*sptr >> 4);
+ quint8 c2 = (*sptr & 0x0f);
+ c1 |= (c1 << 4);
+ c2 |= (c2 << 4);
+ *dptr++ = qRgb(c1, c1, c1);
+ *dptr++ = qRgb(c2, c2, c2);
+ ++sptr;
+ }
+
+ if (doTail) {
+ quint8 c = *sptr >> 4;
+ c |= (c << 4);
+ *dptr = qRgb(c, c, c);
+ }
+ }
+ break;
+ }
+ case 12:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 2),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB444);
+ break;
+ case 15:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 2),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB555);
+ break;
+ case 16:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 2),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB16);
+ break;
+ case 18:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 3),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB666);
+ break;
+ case 24:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 3),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB888);
+ break;
+ case 32:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 4),
+ r.width(), r.height(), mView->linestep(),
+ viewFormat == ARGBFormat ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
+ break;
+ case 8:
+ img = QImage(mView->data() + r.y() * mView->linestep() + r.x(),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_Indexed8);
+ img.setColorTable(mView->clut());
+ if (img.colorCount() <= 0)
+ img = QImage();
+ break;
+ }
+
+ if (rgb_swapped)
+ img = img.rgbSwapped();
+
+ if ( brightness != 255 ) {
+ if (img.format() == QImage::Format_Indexed8) {
+ QVector<QRgb> c = img.colorTable();
+ dim(c.data(),c.count(),brightness);
+ img.setColorTable(c);
+ } else {
+ if ( img.format() != QImage::Format_ARGB32_Premultiplied )
+ img = img.convertToFormat(QImage::Format_RGB32);
+
+ // NOTE: calling bits() may change byteCount(), so do not
+ // pass them as parameters (which are evaluated right-to-left).
+ QRgb *b = (QRgb*)img.bits();
+ int n = img.byteCount()/4;
+ dim(b,n,brightness);
+ }
+ }
+
+ return img;
+}
+
+static int findMultiple(int start, double m, int limit, int step)
+{
+ int r = start;
+ while (r != limit) {
+ if (int(int(r * m)/m) == r)
+ break;
+ r += step;
+ }
+ return r;
+}
+
+void QVFbView::drawScreen(const QRect &rect)
+{
+ QRect r = QRect(0, 0, mView->width(), mView->height());
+
+ if (hzm == 1.0 && vzm == 1.0) // hw: workaround for 4.3.1
+ r &= rect;
+
+ if (int(hzm) != hzm || int(vzm) != vzm) {
+ r.setLeft(findMultiple(r.left(),hzm,0,-1));
+ r.setTop(findMultiple(r.top(),vzm,0,-1));
+ int w = findMultiple(r.width(),hzm,mView->width(),1);
+ int h = findMultiple(r.height(),vzm,mView->height(),1);
+ r.setRight(r.left()+w-1);
+ r.setBottom(r.top()+h-1);
+ }
+
+ int leading;
+ const QImage img = getBuffer(r, leading);
+
+ QPixmap pm;
+ if (hzm == 1.0 && vzm == 1.0) {
+ pm = QPixmap::fromImage(img);
+ } else if (emulateLcdScreen && hzm == 3.0 && vzm == 3.0) {
+ QImage img2(img.width()*3, img.height(), QImage::Format_RGB32);
+ for (int row = 0; row < img2.height(); row++) {
+ QRgb *dptr = (QRgb*)img2.scanLine(row);
+ QRgb *sptr = (QRgb*)img.scanLine(row);
+ for (int col = 0; col < img.width(); col++) {
+ QRgb s = *sptr++;
+ *dptr++ = qRgb(qRed(s),0,0);
+ *dptr++ = qRgb(0,qGreen(s),0);
+ *dptr++ = qRgb(0,0,qBlue(s));
+ }
+ }
+ QMatrix m;
+ m.scale(1.0, 3.0);
+ pm = QPixmap::fromImage(img2);
+ pm = pm.transformed(m);
+ } else if (int(hzm) == hzm && int(vzm) == vzm) {
+ QMatrix m;
+ m.scale(hzm,vzm);
+ pm = QPixmap::fromImage(img);
+ pm = pm.transformed(m);
+ } else {
+ pm = QPixmap::fromImage(img.scaled(int(img.width()*hzm),int(img.height()*vzm), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+
+ int x1 = r.x();
+ int y1 = r.y();
+ int leadingX = leading;
+ int leadingY = 0;
+
+ // Do the rotation thing
+ int rotX1 = mView->width() - x1 - img.width();
+ int rotY1 = mView->height() - y1 - img.height();
+ int rotLeadingX = (leading) ? mView->width() - leadingX - img.width() : 0;
+ int rotLeadingY = 0;
+ switch (rotation) {
+ case Rot0:
+ break;
+ case Rot90:
+ leadingY = leadingX;
+ leadingX = rotLeadingY;
+ y1 = x1;
+ x1 = rotY1;
+ break;
+ case Rot180:
+ leadingX = rotLeadingX;
+ leadingY = leadingY;
+ x1 = rotX1;
+ y1 = rotY1;
+ break;
+ case Rot270:
+ leadingX = leadingY;
+ leadingY = rotLeadingX;
+ x1 = y1;
+ y1 = rotX1;
+ break;
+ default:
+ break;
+ }
+ x1 = int(x1*hzm);
+ y1 = int(y1*vzm);
+ leadingX = int(leadingX*hzm);
+ leadingY = int(leadingY*vzm);
+ if (rotation != 0) {
+ QMatrix m;
+ m.rotate(rotation * 90.0);
+ pm = pm.transformed(m);
+ }
+
+ QPainter p(this);
+ if (viewFormat == ARGBFormat) {
+ QPixmap bg(":/res/images/logo-nt.png");
+ p.fillRect(x1,y1,pm.width(), pm.height(), QBrush(bg));
+ }
+ p.drawPixmap(x1, y1, pm, leadingX, leadingY, pm.width(), pm.height());
+}
+
+//bool QVFbView::eventFilter(QObject *obj, QEvent *e)
+//{
+// if (obj == this &&
+// (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut))
+// return true;
+//
+// return QWidgetView::eventFilter(obj, e);
+//}
+
+void QVFbView::paintEvent(QPaintEvent *e)
+{
+ drawScreen(mapToDevice(e->rect(),QSize(int(width()/hzm), int(height()/vzm)),rotation));
+}
+
+void QVFbView::mousePressEvent(QMouseEvent *e)
+{
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::contextMenuEvent(QContextMenuEvent*)
+{
+
+}
+
+void QVFbView::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::mouseReleaseEvent(QMouseEvent *e)
+{
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::skinMouseEvent(QMouseEvent *e)
+{
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::mouseMoveEvent(QMouseEvent *e)
+{
+ if (!emulateTouchscreen || (e->buttons() & Qt::MouseButtonMask))
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::wheelEvent(QWheelEvent *e)
+{
+ if (!e)
+ return;
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), e->delta());
+}
+
+void QVFbView::setTouchscreenEmulation(bool b)
+{
+ emulateTouchscreen = b;
+}
+
+void QVFbView::setLcdScreenEmulation(bool b)
+{
+ emulateLcdScreen = b;
+}
+
+void QVFbView::setViewFormat(PixelFormat f)
+{
+ if (viewFormat == f)
+ return;
+ viewFormat = f;
+ setAttribute(Qt::WA_PaintOnScreen, viewFormat != ARGBFormat);
+}
+
+#ifdef Q_WS_X11
+void QVFbView::embedDisplay(WId windowId)
+{
+ if (windowId == 0) {
+ delete embedContainer;
+ embedContainer = 0;
+ return;
+ }
+
+ if (!embedContainer) {
+ embedContainer = new QX11EmbedContainer(this);
+ embedContainer->setGeometry(rect());
+ embedContainer->show();
+ }
+ embedContainer->embedClient(windowId);
+}
+#endif
+
+bool QVFbView::event(QEvent *e)
+{
+ if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ sendKeyboardData(ke->text(), ke->key(),
+ ke->modifiers()&(Qt::ShiftModifier|Qt::ControlModifier|Qt::AltModifier),
+ ke->type() == QEvent::KeyPress, ke->isAutoRepeat());
+ ke->accept();
+ return true;
+ }
+ return QVFbAbstractView::event(e);
+}
+
+void QVFbView::keyPressEvent(QKeyEvent *e)
+{
+ sendKeyboardData(e->text(), e->key(),
+ e->modifiers()&(Qt::ShiftModifier|Qt::ControlModifier|Qt::AltModifier),
+ true, e->isAutoRepeat());
+}
+
+void QVFbView::keyReleaseEvent(QKeyEvent *e)
+{
+ sendKeyboardData(e->text(), e->key(),
+ e->modifiers()&(Qt::ShiftModifier|Qt::ControlModifier|Qt::AltModifier),
+ false, e->isAutoRepeat());
+}
+
+
+QImage QVFbView::image() const
+{
+ int l;
+ QImage r = getBuffer(QRect(0, 0, mView->width(), mView->height()), l).copy();
+ return r;
+}
+
+void QVFbView::startAnimation(const QString& filename)
+{
+ delete animation;
+ animation = new QAnimationWriter(filename,"MNG");
+ animation->setFrameRate(refreshRate);
+ animation->appendFrame(QImage(mView->data(),
+ mView->width(), mView->height(), QImage::Format_RGB32));
+}
+
+void QVFbView::stopAnimation()
+{
+ delete animation;
+ animation = 0;
+}
+
+
+void QVFbView::skinKeyPressEvent(int code, const QString& text, bool autorep)
+{
+ QKeyEvent e(QEvent::KeyPress,code,0,text,autorep);
+ keyPressEvent(&e);
+}
+
+void QVFbView::skinKeyReleaseEvent(int code, const QString& text, bool autorep)
+{
+ QKeyEvent e(QEvent::KeyRelease,code,0,text,autorep);
+ keyReleaseEvent(&e);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qvfb/qvfbview.h b/src/qvfb/qvfbview.h
new file mode 100644
index 000000000..07d11ffc4
--- /dev/null
+++ b/src/qvfb/qvfbview.h
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVFBVIEW_H
+#define QVFBVIEW_H
+
+//#ifdef QT_NO_OPENGL
+#include <QWidget>
+//#else
+//#define QVFB_USE_GLWIDGET
+//#include <QGLWidget>
+//#endif
+
+QT_BEGIN_NAMESPACE
+
+class QImage;
+class QTimer;
+class QAnimationWriter;
+struct QVFbHeader;
+class QVFbViewProtocol;
+class QX11EmbedContainer;
+
+class QVFbAbstractView :
+#ifdef QVFB_USE_GLWIDGET
+ public QGLWidget
+#else
+ public QWidget
+#endif
+{
+ Q_OBJECT
+public:
+ enum Rotation { Rot0, Rot90, Rot180, Rot270 };
+ enum PixelFormat { DefaultFormat, GrayscaleFormat, RGBFormat, ARGBFormat };
+ QVFbAbstractView( QWidget *parent = 0);
+ virtual ~QVFbAbstractView();
+
+ virtual int displayId() const = 0;
+ virtual int displayWidth() const = 0;
+ virtual int displayHeight() const = 0;
+ virtual int displayDepth() const = 0;
+ virtual PixelFormat displayFormat() const { return DefaultFormat; }
+ virtual bool rgbSwapped() const { return false; }
+ virtual Rotation displayRotation() const = 0;
+
+ virtual void setGamma(double gr, double gg, double gb) = 0;
+ virtual double gammaRed() const = 0;
+ virtual double gammaGreen() const = 0;
+ virtual double gammaBlue() const = 0;
+ virtual void getGamma(int i, QRgb& rgb) = 0;
+
+ virtual bool touchScreenEmulation() const = 0;
+ virtual bool lcdScreenEmulation() const = 0;
+ virtual int rate() = 0;
+ virtual bool animating() const = 0;
+ virtual QImage image() const = 0;
+ virtual void setRate(int) = 0;
+
+ virtual double zoomH() const = 0;
+ virtual double zoomV() const = 0;
+
+public slots:
+ virtual void setTouchscreenEmulation( bool ) = 0;
+ virtual void setLcdScreenEmulation( bool ) = 0;
+ virtual void setZoom( double, double ) = 0;
+ virtual void setRotation(Rotation) = 0;
+ virtual void startAnimation( const QString& ) = 0;
+ virtual void stopAnimation() = 0;
+ virtual void skinKeyPressEvent( int code, const QString& text, bool autorep=FALSE ) = 0;
+ virtual void skinKeyReleaseEvent( int code, const QString& text, bool autorep=FALSE ) = 0;
+ virtual void setViewFormat(PixelFormat) {}
+ virtual void setRgbSwapped( bool ) {};
+ virtual void embedDisplay(WId) {}
+};
+
+class QVFbView : public QVFbAbstractView
+{
+ Q_OBJECT
+public:
+ QVFbView(int id, int w, int h, int d, Rotation r, QWidget *parent = 0);
+ virtual ~QVFbView();
+
+ int displayId() const;
+ int displayWidth() const;
+ int displayHeight() const;
+ int displayDepth() const;
+ PixelFormat displayFormat() const;
+ bool rgbSwapped() const { return rgb_swapped; }
+ Rotation displayRotation() const;
+
+ bool touchScreenEmulation() const { return emulateTouchscreen; }
+ bool lcdScreenEmulation() const { return emulateLcdScreen; }
+ int rate() { return refreshRate; }
+ bool animating() const { return !!animation; }
+ QImage image() const;
+
+ void setGamma(double gr, double gg, double gb);
+ double gammaRed() const { return gred; }
+ double gammaGreen() const { return ggreen; }
+ double gammaBlue() const { return gblue; }
+ void getGamma(int i, QRgb& rgb);
+ void skinMouseEvent(QMouseEvent *e);
+
+ double zoomH() const { return hzm; }
+ double zoomV() const { return vzm; }
+
+ QSize sizeHint() const;
+ void setRate(int);
+
+public slots:
+ void setTouchscreenEmulation(bool);
+ void setLcdScreenEmulation(bool);
+ void setZoom(double, double);
+ void setRotation(Rotation);
+ void startAnimation(const QString&);
+ void stopAnimation();
+ void skinKeyPressEvent(int code, const QString& text, bool autorep=FALSE);
+ void skinKeyReleaseEvent(int code, const QString& text, bool autorep=FALSE);
+ void setViewFormat(PixelFormat);
+ void setRgbSwapped(bool b) { rgb_swapped = b; }
+#ifdef Q_WS_X11
+ void embedDisplay(WId id);
+#endif
+
+protected slots:
+ void refreshDisplay(const QRect &);
+
+protected:
+ QImage getBuffer(const QRect &r, int &leading) const;
+ void drawScreen(const QRect &r);
+ void sendMouseData(const QPoint &pos, int buttons, int wheel);
+ void sendKeyboardData(QString unicode, int keycode, int modifiers,
+ bool press, bool repeat);
+ //virtual bool eventFilter(QObject *obj, QEvent *e);
+ virtual void paintEvent(QPaintEvent *pe);
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void wheelEvent(QWheelEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void keyReleaseEvent(QKeyEvent *e);
+ virtual bool event(QEvent *event);
+
+private:
+ void setDirty(const QRect&);
+ int viewdepth; // "faked" depth
+ PixelFormat viewFormat;
+ bool rgb_swapped;
+ int rsh;
+ int gsh;
+ int bsh;
+ int rmax;
+ int gmax;
+ int bmax;
+ int contentsWidth;
+ int contentsHeight;
+ double gred, ggreen, gblue;
+ QRgb* gammatable;
+
+ int refreshRate;
+ QAnimationWriter *animation;
+ double hzm,vzm;
+ QVFbViewProtocol *mView;
+ bool emulateTouchscreen;
+ bool emulateLcdScreen;
+ Rotation rotation;
+
+#ifdef Q_WS_X11
+ QX11EmbedContainer *embedContainer;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/qvfbx11view.cpp b/src/qvfb/qvfbx11view.cpp
new file mode 100644
index 000000000..bb91aa4f2
--- /dev/null
+++ b/src/qvfb/qvfbx11view.cpp
@@ -0,0 +1,389 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbx11view.h"
+#include "x11keyfaker.h"
+#include <qevent.h>
+#include <QX11Info>
+#include <QTimer>
+#include <QProcess>
+#include <QDebug>
+#include <QUuid>
+#include <QDataStream>
+#include <QTemporaryFile>
+#include <X11/Xlib.h>
+
+QT_BEGIN_NAMESPACE
+
+QVFbX11View::QVFbX11View
+ (int id, int w, int h, int d, Rotation r, QWidget *parent)
+ : QVFbAbstractView(parent)
+{
+ this->id = id;
+ this->w = w;
+ this->h = h;
+ this->d = d;
+ this->rotation = r;
+ this->gr = 1.0;
+ this->gg = 1.0;
+ this->gb = 1.0;
+ this->touchscreen = false;
+ this->lcd = false;
+ this->keyFaker = 0;
+ this->xnest = 0;
+ this->serverAuthFile = 0;
+ this->shutdown = false;
+
+ // Try to find Xephyr, as it is better than Xnest in many ways.
+ if (QFile::exists("/usr/bin/Xephyr"))
+ xserver = "/usr/bin/Xephyr";
+ else if (QFile::exists("/usr/local/bin/Xephyr"))
+ xserver = "/usr/local/bin/Xephyr";
+ else if (QFile::exists("/usr/X11R6/bin/Xephyr"))
+ xserver = "/usr/X11R6/bin/Xephyr";
+ else
+ xserver = "Xnest";
+}
+
+QVFbX11View::~QVFbX11View()
+{
+ shutdown = true;
+ if (xnest) {
+ xnest->terminate();
+ xnestStopped();
+ }
+}
+
+int QVFbX11View::displayId() const
+{
+ return id;
+}
+
+int QVFbX11View::displayWidth() const
+{
+ return ( (int)rotation & 0x01 ) ? h : w;
+}
+
+int QVFbX11View::displayHeight() const
+{
+ return ( (int)rotation & 0x01 ) ? w : h;
+}
+
+int QVFbX11View::displayDepth() const
+{
+ return d;
+}
+
+QVFbX11View::Rotation QVFbX11View::displayRotation() const
+{
+ return rotation;
+}
+
+void QVFbX11View::skinKeyPressEvent(int code, const QString&, bool)
+{
+ if (keyFaker)
+ keyFaker->sendKeyEvent(code, true);
+}
+
+void QVFbX11View::skinKeyReleaseEvent(int code, const QString&, bool)
+{
+ if (keyFaker)
+ keyFaker->sendKeyEvent(code, false);
+}
+
+void QVFbX11View::setGamma(double gr, double gg, double gb)
+{
+ // We remember the values, but don't do anything with them.
+ this->gr = gr;
+ this->gg = gg;
+ this->gb = gb;
+}
+
+double QVFbX11View::gammaRed() const
+{
+ return gr;
+}
+
+double QVFbX11View::gammaGreen() const
+{
+ return gg;
+}
+
+double QVFbX11View::gammaBlue() const
+{
+ return gb;
+}
+
+void QVFbX11View::getGamma(int, QRgb& rgb)
+{
+ rgb = qRgb(255, 255, 255);
+}
+
+bool QVFbX11View::touchScreenEmulation() const
+{
+ return touchscreen;
+}
+
+bool QVFbX11View::lcdScreenEmulation() const
+{
+ return lcd;
+}
+
+int QVFbX11View::rate()
+{
+ // We don't support refresh rates, so return a default value.
+ return 30;
+}
+
+bool QVFbX11View::animating() const
+{
+ // We don't support animation.
+ return false;
+}
+
+QImage QVFbX11View::image() const
+{
+ // We don't support image capture.
+ return QImage();
+}
+
+void QVFbX11View::setRate(int)
+{
+ // We don't support rate adjustments.
+}
+
+
+double QVFbX11View::zoomH() const
+{
+ // Zoom is not possible with Xnest.
+ return 1.0;
+}
+
+double QVFbX11View::zoomV() const
+{
+ // Zoom is not possible with Xnest.
+ return 1.0;
+}
+
+QSize QVFbX11View::sizeHint() const
+{
+ return QSize(w, h);
+}
+
+void QVFbX11View::setTouchscreenEmulation( bool flag )
+{
+ touchscreen = flag;
+}
+
+void QVFbX11View::setLcdScreenEmulation( bool flag )
+{
+ lcd = flag;
+}
+
+void QVFbX11View::setZoom( double, double )
+{
+ // Zoom is not possible with Xnest.
+}
+
+void QVFbX11View::setRotation( Rotation )
+{
+ // Rotation is not possible with Xnest.
+}
+
+void QVFbX11View::startAnimation( const QString& )
+{
+ // Animation is not supported.
+}
+
+void QVFbX11View::stopAnimation()
+{
+ // Animation is not supported.
+}
+
+// Generate a 16-byte magic cookie string.
+static QString generateMagicCookie()
+{
+ static const char hexchars[] = "0123456789abcdef";
+ QUuid uuid = QUuid::createUuid();
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ stream << uuid;
+ QString value;
+ foreach ( char ch, ba ) {
+ value += QChar( hexchars[(ch >> 4) & 0x0F] );
+ value += QChar( hexchars[ch & 0x0F] );
+ }
+ return value;
+}
+
+void QVFbX11View::showEvent(QShowEvent *e)
+{
+ if (!xnest)
+ startXnest();
+ QWidget::showEvent(e);
+}
+
+void QVFbX11View::keyPressEvent(QKeyEvent *e)
+{
+ if (keyFaker)
+ keyFaker->sendKeyEvent(e->key(), true);
+ QWidget::keyPressEvent(e);
+}
+
+void QVFbX11View::keyReleaseEvent(QKeyEvent *e)
+{
+ if (keyFaker)
+ keyFaker->sendKeyEvent(e->key(), false);
+ QWidget::keyReleaseEvent(e);
+}
+
+void QVFbX11View::startXnest()
+{
+ // Add authentication credentials to the XAUTHORITY file.
+ QString cookie = generateMagicCookie();
+ QStringList xauthargs;
+ xauthargs += "add";
+ xauthargs += ":" + QString::number(displayId());
+ xauthargs += "MIT-MAGIC-COOKIE-1";
+ xauthargs += cookie;
+ if (QProcess::execute("xauth", xauthargs) != 0)
+ qWarning() << "xauth: failed to add Xnest client authentication credentials";
+
+ // Write the credentials to another authentication file for the server.
+ serverAuthFile = new QTemporaryFile(this);
+ QString authFilename;
+ if (serverAuthFile->open()) {
+ authFilename = serverAuthFile->fileName();
+ serverAuthFile->close();
+ xauthargs.clear();
+ xauthargs += "-f";
+ xauthargs += authFilename;
+ xauthargs += "add";
+ xauthargs += ":" + QString::number(displayId());
+ xauthargs += "MIT-MAGIC-COOKIE-1";
+ xauthargs += cookie;
+ if (QProcess::execute("xauth", xauthargs) != 0)
+ qWarning() << "xauth: failed to add Xnest server authentication credentials";
+ }
+
+ // Create a raw X11 window to act as the Xnest's root window.
+ // We cannot use winId() directly because qvfb is already
+ // selecting for events that Xnest wants to select for.
+ WId root = XCreateSimpleWindow
+ (QX11Info::display(), winId(), 0, 0, w, h, 0,
+ BlackPixel(QX11Info::display(), QX11Info::appScreen()),
+ BlackPixel(QX11Info::display(), QX11Info::appScreen()));
+ XMapWindow(QX11Info::display(), root);
+
+ // Warn the user if the visual number looks wrong. Xnest expects
+ // its root window to be on the default visual.
+ if (QX11Info::appVisual() != DefaultVisual(QX11Info::display(), QX11Info::appScreen())) {
+ qWarning() << "*** Qt is not using the default visual. Xnest may fail "
+ "with a BadMatch error.";
+ qWarning() << "*** If it fails, then restart qvfb with \" -visual"
+ << DefaultVisual(QX11Info::display(), QX11Info::appScreen())
+ ->visualid << "\"";
+ }
+
+ // Make sure the root window is in the X server before Xnest starts.
+ XSync(QX11Info::display(), False);
+
+ // Start the Xnest process.
+ xnest = new QProcess(this);
+ connect(xnest, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(xnestStopped()));
+ connect(xnest, SIGNAL(finished(int,QProcess::ExitStatus)),
+ this, SLOT(xnestStopped()));
+ QStringList args;
+ args += "-auth";
+ args += authFilename;
+ if (!xserver.contains("Xephyr")) {
+ args += "-geometry";
+ args += QString::number(w) + "x" + QString::number(h) + "+0+0";
+ args += "-depth";
+ args += QString::number(d);
+ }
+ args += "-br"; // Start Xnest with a black background.
+ args += "-parent";
+ args += "0x" + QString::number(root, 16);
+ args += ":" + QString::number(displayId());
+ xnest->setProcessChannelMode(QProcess::ForwardedChannels);
+ xnest->start(xserver, args);
+ //qDebug() << args;
+
+ QTimer::singleShot(200, this, SLOT(startKeyFaker()));
+}
+
+void QVFbX11View::xnestStopped()
+{
+ if (!shutdown) {
+ if (xnest && xnest->error() == QProcess::FailedToStart)
+ qWarning() << xserver << "could not be started";
+ else
+ qWarning() << xserver << "stopped unexpectedly";
+ }
+ if (keyFaker) {
+ delete keyFaker;
+ keyFaker = 0;
+ }
+ if (xnest) {
+ xnest->deleteLater();
+ xnest = 0;
+
+ QStringList xauthargs;
+ xauthargs += "remove";
+ xauthargs += ":" + QString::number(displayId());
+ if (QProcess::execute("xauth", xauthargs) != 0)
+ qWarning() << "xauth: failed to remove Xnest authentication credentials";
+ }
+ if (serverAuthFile) {
+ delete serverAuthFile;
+ serverAuthFile = 0;
+ }
+}
+
+void QVFbX11View::startKeyFaker()
+{
+ if (!keyFaker && xnest)
+ keyFaker = new X11KeyFaker(":" + QString::number(displayId()), this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qvfb/qvfbx11view.h b/src/qvfb/qvfbx11view.h
new file mode 100644
index 000000000..d4406d118
--- /dev/null
+++ b/src/qvfb/qvfbx11view.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVFBX11VIEW_H
+#define QVFBX11VIEW_H
+
+#include "qvfbview.h"
+
+QT_BEGIN_NAMESPACE
+
+class X11KeyFaker;
+class QProcess;
+class QTemporaryFile;
+
+class QVFbX11View : public QVFbAbstractView
+{
+ Q_OBJECT
+public:
+ QVFbX11View( int id, int w, int h, int d, Rotation r, QWidget *parent = 0);
+ virtual ~QVFbX11View();
+
+ QString xServerPath() const { return xserver; }
+ void setXServerPath(const QString& path) { xserver = path; }
+
+ int displayId() const;
+ int displayWidth() const;
+ int displayHeight() const;
+ int displayDepth() const;
+ Rotation displayRotation() const;
+
+ void skinKeyPressEvent( int code, const QString& text, bool autorep=FALSE );
+ void skinKeyReleaseEvent( int code, const QString& text, bool autorep=FALSE );
+
+ void setGamma(double gr, double gg, double gb);
+ double gammaRed() const;
+ double gammaGreen() const;
+ double gammaBlue() const;
+ void getGamma(int i, QRgb& rgb);
+
+ bool touchScreenEmulation() const;
+ bool lcdScreenEmulation() const;
+ int rate();
+ bool animating() const;
+ QImage image() const;
+ void setRate(int);
+
+ double zoomH() const;
+ double zoomV() const;
+
+ QSize sizeHint() const;
+
+public slots:
+ void setTouchscreenEmulation( bool );
+ void setLcdScreenEmulation( bool );
+ void setZoom( double, double );
+ void setRotation(Rotation);
+ void startAnimation( const QString& );
+ void stopAnimation();
+
+protected:
+ void showEvent(QShowEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void keyReleaseEvent(QKeyEvent *);
+
+private slots:
+ void startXnest();
+ void xnestStopped();
+ void startKeyFaker();
+
+private:
+ int id, w, h, d;
+ Rotation rotation;
+ double gr, gg, gb;
+ bool touchscreen, lcd;
+ X11KeyFaker *keyFaker;
+ QProcess *xnest;
+ QTemporaryFile *serverAuthFile;
+ bool shutdown;
+ QString xserver;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qvfb/x11keyfaker.cpp b/src/qvfb/x11keyfaker.cpp
new file mode 100644
index 000000000..aa8c8c50f
--- /dev/null
+++ b/src/qvfb/x11keyfaker.cpp
@@ -0,0 +1,627 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "x11keyfaker.h"
+#include <QTimer>
+#include <QSocketNotifier>
+#include <QDebug>
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysym.h>
+#include <X11/XF86keysym.h>
+#include "qtopiakeysym.h"
+#include <unistd.h>
+#include <fcntl.h>
+
+QT_BEGIN_NAMESPACE
+
+X11KeyFaker::X11KeyFaker(const QString& displayName, QObject *parent)
+ : QObject(parent)
+{
+ this->displayName = displayName;
+ this->dpy = 0;
+ this->retryCount = 0;
+ this->shiftKeycode = 0;
+ this->modeSwitchKeycode = 0;
+ this->modifiers = 0;
+ connect();
+}
+
+X11KeyFaker::~X11KeyFaker()
+{
+ if (dpy)
+ XCloseDisplay(dpy);
+}
+
+void X11KeyFaker::sendKeyEvent(int qtCode, bool isPress)
+{
+ if (!dpy)
+ return;
+
+ // Convert the Qt key code into an X keysym.
+ KeySym keysym = NoSymbol;
+ switch (qtCode) {
+ case Qt::Key_Escape: keysym = XK_Escape; break;
+ case Qt::Key_Tab: keysym = XK_Tab; break;
+ case Qt::Key_Backtab: keysym = XK_ISO_Left_Tab; break;
+ case Qt::Key_Backspace: keysym = XK_BackSpace; break;
+ case Qt::Key_Return: keysym = XK_Return; break;
+ case Qt::Key_Enter: keysym = XK_KP_Enter; break;
+ case Qt::Key_Insert: keysym = XK_KP_Insert; break;
+ case Qt::Key_Delete: keysym = XK_KP_Delete; break;
+ case Qt::Key_Pause: keysym = XK_Pause; break;
+ case Qt::Key_Print: keysym = XK_Print; break;
+ case Qt::Key_SysReq: keysym = 0x1005FF60; break;
+ case Qt::Key_Clear: keysym = XK_KP_Begin; break;
+ case Qt::Key_Home: keysym = XK_Home; break;
+ case Qt::Key_End: keysym = XK_End; break;
+ case Qt::Key_Left: keysym = XK_Left; break;
+ case Qt::Key_Up: keysym = XK_Up; break;
+ case Qt::Key_Right: keysym = XK_Right; break;
+ case Qt::Key_Down: keysym = XK_Down; break;
+ case Qt::Key_PageUp: keysym = XK_Prior; break;
+ case Qt::Key_PageDown: keysym = XK_Next; break;
+ case Qt::Key_Shift: keysym = XK_Shift_L; break;
+ case Qt::Key_Control: keysym = XK_Control_L; break;
+ case Qt::Key_Meta: keysym = XK_Meta_L; break;
+ case Qt::Key_Alt: keysym = XK_Alt_L; break;
+ case Qt::Key_CapsLock: keysym = XK_Caps_Lock; break;
+ case Qt::Key_NumLock: keysym = XK_Num_Lock; break;
+ case Qt::Key_ScrollLock: keysym = XK_Scroll_Lock; break;
+ case Qt::Key_F1: keysym = XK_F1; break;
+ case Qt::Key_F2: keysym = XK_F2; break;
+ case Qt::Key_F3: keysym = XK_F3; break;
+ case Qt::Key_F4: keysym = XK_F4; break;
+ case Qt::Key_F5: keysym = XK_F5; break;
+ case Qt::Key_F6: keysym = XK_F6; break;
+ case Qt::Key_F7: keysym = XK_F7; break;
+ case Qt::Key_F8: keysym = XK_F8; break;
+ case Qt::Key_F9: keysym = XK_F9; break;
+ case Qt::Key_F10: keysym = XK_F10; break;
+ case Qt::Key_F11: keysym = XK_F11; break;
+ case Qt::Key_F12: keysym = XK_F12; break;
+ case Qt::Key_F13: keysym = XK_F13; break;
+ case Qt::Key_F14: keysym = XK_F14; break;
+ case Qt::Key_F15: keysym = XK_F15; break;
+ case Qt::Key_F16: keysym = XK_F16; break;
+ case Qt::Key_F17: keysym = XK_F17; break;
+ case Qt::Key_F18: keysym = XK_F18; break;
+ case Qt::Key_F19: keysym = XK_F19; break;
+ case Qt::Key_F20: keysym = XK_F20; break;
+ case Qt::Key_F21: keysym = XK_F21; break;
+ case Qt::Key_F22: keysym = XK_F22; break;
+ case Qt::Key_F23: keysym = XK_F23; break;
+ case Qt::Key_F24: keysym = XK_F24; break;
+ case Qt::Key_F25: keysym = XK_F25; break;
+ case Qt::Key_F26: keysym = XK_F26; break;
+ case Qt::Key_F27: keysym = XK_F27; break;
+ case Qt::Key_F28: keysym = XK_F28; break;
+ case Qt::Key_F29: keysym = XK_F29; break;
+ case Qt::Key_F30: keysym = XK_F30; break;
+ case Qt::Key_F31: keysym = XK_F31; break;
+ case Qt::Key_F32: keysym = XK_F32; break;
+ case Qt::Key_F33: keysym = XK_F33; break;
+ case Qt::Key_F34: keysym = XK_F34; break;
+ case Qt::Key_F35: keysym = XK_F35; break;
+ case Qt::Key_Super_L: keysym = XK_Super_L; break;
+ case Qt::Key_Super_R: keysym = XK_Super_R; break;
+ case Qt::Key_Menu: keysym = XK_Menu; break;
+ case Qt::Key_Hyper_L: keysym = XK_Hyper_L; break;
+ case Qt::Key_Hyper_R: keysym = XK_Hyper_R; break;
+ case Qt::Key_Help: keysym = XK_Help; break;
+ case Qt::Key_Direction_L: keysym = NoSymbol; break; // ???
+ case Qt::Key_Direction_R: keysym = NoSymbol; break; // ???
+ case Qt::Key_Space: keysym = XK_space; break;
+ case Qt::Key_Exclam: keysym = XK_exclam; break;
+ case Qt::Key_QuoteDbl: keysym = XK_quotedbl; break;
+ case Qt::Key_NumberSign: keysym = XK_numbersign; break;
+ case Qt::Key_Dollar: keysym = XK_dollar; break;
+ case Qt::Key_Percent: keysym = XK_percent; break;
+ case Qt::Key_Ampersand: keysym = XK_ampersand; break;
+ case Qt::Key_Apostrophe: keysym = XK_apostrophe; break;
+ case Qt::Key_ParenLeft: keysym = XK_parenleft; break;
+ case Qt::Key_ParenRight: keysym = XK_parenright; break;
+ case Qt::Key_Asterisk: keysym = XK_asterisk; break;
+ case Qt::Key_Plus: keysym = XK_plus; break;
+ case Qt::Key_Comma: keysym = XK_comma; break;
+ case Qt::Key_Minus: keysym = XK_minus; break;
+ case Qt::Key_Period: keysym = XK_period; break;
+ case Qt::Key_Slash: keysym = XK_slash; break;
+ case Qt::Key_0: keysym = XK_0; break;
+ case Qt::Key_1: keysym = XK_1; break;
+ case Qt::Key_2: keysym = XK_2; break;
+ case Qt::Key_3: keysym = XK_3; break;
+ case Qt::Key_4: keysym = XK_4; break;
+ case Qt::Key_5: keysym = XK_5; break;
+ case Qt::Key_6: keysym = XK_6; break;
+ case Qt::Key_7: keysym = XK_7; break;
+ case Qt::Key_8: keysym = XK_8; break;
+ case Qt::Key_9: keysym = XK_9; break;
+ case Qt::Key_Colon: keysym = XK_colon; break;
+ case Qt::Key_Semicolon: keysym = XK_semicolon; break;
+ case Qt::Key_Less: keysym = XK_less; break;
+ case Qt::Key_Equal: keysym = XK_equal; break;
+ case Qt::Key_Greater: keysym = XK_greater; break;
+ case Qt::Key_Question: keysym = XK_question; break;
+ case Qt::Key_At: keysym = XK_at; break;
+ case Qt::Key_A: keysym = XK_a; break; // Must be lower case keysyms
+ case Qt::Key_B: keysym = XK_b; break; // for correct shift handling.
+ case Qt::Key_C: keysym = XK_c; break;
+ case Qt::Key_D: keysym = XK_d; break;
+ case Qt::Key_E: keysym = XK_e; break;
+ case Qt::Key_F: keysym = XK_f; break;
+ case Qt::Key_G: keysym = XK_g; break;
+ case Qt::Key_H: keysym = XK_h; break;
+ case Qt::Key_I: keysym = XK_i; break;
+ case Qt::Key_J: keysym = XK_j; break;
+ case Qt::Key_K: keysym = XK_k; break;
+ case Qt::Key_L: keysym = XK_l; break;
+ case Qt::Key_M: keysym = XK_m; break;
+ case Qt::Key_N: keysym = XK_n; break;
+ case Qt::Key_O: keysym = XK_o; break;
+ case Qt::Key_P: keysym = XK_p; break;
+ case Qt::Key_Q: keysym = XK_q; break;
+ case Qt::Key_R: keysym = XK_r; break;
+ case Qt::Key_S: keysym = XK_s; break;
+ case Qt::Key_T: keysym = XK_t; break;
+ case Qt::Key_U: keysym = XK_u; break;
+ case Qt::Key_V: keysym = XK_v; break;
+ case Qt::Key_W: keysym = XK_w; break;
+ case Qt::Key_X: keysym = XK_x; break;
+ case Qt::Key_Y: keysym = XK_y; break;
+ case Qt::Key_Z: keysym = XK_z; break;
+ case Qt::Key_BracketLeft: keysym = XK_bracketleft; break;
+ case Qt::Key_Backslash: keysym = XK_backslash; break;
+ case Qt::Key_BracketRight: keysym = XK_bracketright; break;
+ case Qt::Key_AsciiCircum: keysym = XK_asciicircum; break;
+ case Qt::Key_Underscore: keysym = XK_underscore; break;
+ case Qt::Key_QuoteLeft: keysym = XK_quoteleft; break;
+ case Qt::Key_BraceLeft: keysym = XK_braceleft; break;
+ case Qt::Key_Bar: keysym = XK_bar; break;
+ case Qt::Key_BraceRight: keysym = XK_braceright; break;
+ case Qt::Key_AsciiTilde: keysym = XK_asciitilde; break;
+
+ case Qt::Key_nobreakspace: keysym = XK_nobreakspace; break;
+ case Qt::Key_exclamdown: keysym = XK_exclamdown; break;
+ case Qt::Key_cent: keysym = XK_cent; break;
+ case Qt::Key_sterling: keysym = XK_sterling; break;
+ case Qt::Key_currency: keysym = XK_currency; break;
+ case Qt::Key_yen: keysym = XK_yen; break;
+ case Qt::Key_brokenbar: keysym = XK_brokenbar; break;
+ case Qt::Key_section: keysym = XK_section; break;
+ case Qt::Key_diaeresis: keysym = XK_diaeresis; break;
+ case Qt::Key_copyright: keysym = XK_copyright; break;
+ case Qt::Key_ordfeminine: keysym = XK_ordfeminine; break;
+ case Qt::Key_guillemotleft: keysym = XK_guillemotleft; break;
+ case Qt::Key_notsign: keysym = XK_notsign; break;
+ case Qt::Key_hyphen: keysym = XK_hyphen; break;
+ case Qt::Key_registered: keysym = XK_registered; break;
+ case Qt::Key_macron: keysym = XK_macron; break;
+ case Qt::Key_degree: keysym = XK_degree; break;
+ case Qt::Key_plusminus: keysym = XK_plusminus; break;
+ case Qt::Key_twosuperior: keysym = XK_twosuperior; break;
+ case Qt::Key_threesuperior: keysym = XK_threesuperior; break;
+ case Qt::Key_acute: keysym = XK_acute; break;
+ case Qt::Key_mu: keysym = XK_mu; break;
+ case Qt::Key_paragraph: keysym = XK_paragraph; break;
+ case Qt::Key_periodcentered: keysym = XK_periodcentered; break;
+ case Qt::Key_cedilla: keysym = XK_cedilla; break;
+ case Qt::Key_onesuperior: keysym = XK_onesuperior; break;
+ case Qt::Key_masculine: keysym = XK_masculine; break;
+ case Qt::Key_guillemotright: keysym = XK_guillemotright; break;
+ case Qt::Key_onequarter: keysym = XK_onequarter; break;
+ case Qt::Key_onehalf: keysym = XK_onehalf; break;
+ case Qt::Key_threequarters: keysym = XK_threequarters; break;
+ case Qt::Key_questiondown: keysym = XK_questiondown; break;
+ case Qt::Key_Agrave: keysym = XK_agrave; break; // Lower case keysyms
+ case Qt::Key_Aacute: keysym = XK_aacute; break; // for shift handling.
+ case Qt::Key_Acircumflex: keysym = XK_acircumflex; break;
+ case Qt::Key_Atilde: keysym = XK_atilde; break;
+ case Qt::Key_Adiaeresis: keysym = XK_adiaeresis; break;
+ case Qt::Key_Aring: keysym = XK_aring; break;
+ case Qt::Key_AE: keysym = XK_ae; break;
+ case Qt::Key_Ccedilla: keysym = XK_ccedilla; break;
+ case Qt::Key_Egrave: keysym = XK_egrave; break;
+ case Qt::Key_Eacute: keysym = XK_eacute; break;
+ case Qt::Key_Ecircumflex: keysym = XK_ecircumflex; break;
+ case Qt::Key_Ediaeresis: keysym = XK_ediaeresis; break;
+ case Qt::Key_Igrave: keysym = XK_igrave; break;
+ case Qt::Key_Iacute: keysym = XK_iacute; break;
+ case Qt::Key_Icircumflex: keysym = XK_icircumflex; break;
+ case Qt::Key_Idiaeresis: keysym = XK_idiaeresis; break;
+ case Qt::Key_ETH: keysym = XK_eth; break;
+ case Qt::Key_Ntilde: keysym = XK_ntilde; break;
+ case Qt::Key_Ograve: keysym = XK_ograve; break;
+ case Qt::Key_Oacute: keysym = XK_oacute; break;
+ case Qt::Key_Ocircumflex: keysym = XK_ocircumflex; break;
+ case Qt::Key_Otilde: keysym = XK_otilde; break;
+ case Qt::Key_Odiaeresis: keysym = XK_odiaeresis; break;
+ case Qt::Key_multiply: keysym = XK_multiply; break;
+ case Qt::Key_Ooblique: keysym = XK_ooblique; break;
+ case Qt::Key_Ugrave: keysym = XK_ugrave; break;
+ case Qt::Key_Uacute: keysym = XK_uacute; break;
+ case Qt::Key_Ucircumflex: keysym = XK_ucircumflex; break;
+ case Qt::Key_Udiaeresis: keysym = XK_udiaeresis; break;
+ case Qt::Key_Yacute: keysym = XK_yacute; break;
+ case Qt::Key_THORN: keysym = XK_thorn; break;
+ case Qt::Key_ssharp: keysym = XK_ssharp; break;
+ case Qt::Key_division: keysym = XK_division; break;
+ case Qt::Key_ydiaeresis: keysym = XK_ydiaeresis; break;
+
+ case Qt::Key_AltGr: keysym = XK_ISO_Level3_Shift; break;
+ case Qt::Key_Multi_key: keysym = XK_Multi_key; break;
+ case Qt::Key_Codeinput: keysym = XK_Codeinput; break;
+ case Qt::Key_SingleCandidate: keysym = XK_SingleCandidate; break;
+ case Qt::Key_MultipleCandidate: keysym = XK_MultipleCandidate; break;
+ case Qt::Key_PreviousCandidate: keysym = XK_PreviousCandidate; break;
+
+ case Qt::Key_Mode_switch: keysym = XK_Mode_switch; break;
+
+ case Qt::Key_Kanji: keysym = XK_Kanji; break;
+ case Qt::Key_Muhenkan: keysym = XK_Muhenkan; break;
+ case Qt::Key_Henkan: keysym = XK_Henkan; break;
+ case Qt::Key_Romaji: keysym = XK_Romaji; break;
+ case Qt::Key_Hiragana: keysym = XK_Hiragana; break;
+ case Qt::Key_Katakana: keysym = XK_Katakana; break;
+ case Qt::Key_Hiragana_Katakana: keysym = XK_Hiragana_Katakana; break;
+ case Qt::Key_Zenkaku: keysym = XK_Zenkaku; break;
+ case Qt::Key_Hankaku: keysym = XK_Hankaku; break;
+ case Qt::Key_Zenkaku_Hankaku: keysym = XK_Zenkaku_Hankaku; break;
+ case Qt::Key_Touroku: keysym = XK_Touroku; break;
+ case Qt::Key_Massyo: keysym = XK_Massyo; break;
+ case Qt::Key_Kana_Lock: keysym = XK_Kana_Lock; break;
+ case Qt::Key_Kana_Shift: keysym = XK_Kana_Shift; break;
+ case Qt::Key_Eisu_Shift: keysym = XK_Eisu_Shift; break;
+ case Qt::Key_Eisu_toggle: keysym = XK_Eisu_toggle; break;
+
+ case Qt::Key_Hangul: keysym = XK_Hangul; break;
+ case Qt::Key_Hangul_Start: keysym = XK_Hangul_Start; break;
+ case Qt::Key_Hangul_End: keysym = XK_Hangul_End; break;
+ case Qt::Key_Hangul_Hanja: keysym = XK_Hangul_Hanja; break;
+ case Qt::Key_Hangul_Jamo: keysym = XK_Hangul_Jamo; break;
+ case Qt::Key_Hangul_Romaja: keysym = XK_Hangul_Romaja; break;
+ case Qt::Key_Hangul_Jeonja: keysym = XK_Hangul_Jeonja; break;
+ case Qt::Key_Hangul_Banja: keysym = XK_Hangul_Banja; break;
+ case Qt::Key_Hangul_PreHanja: keysym = XK_Hangul_PreHanja; break;
+ case Qt::Key_Hangul_PostHanja: keysym = XK_Hangul_PostHanja; break;
+ case Qt::Key_Hangul_Special: keysym = XK_Hangul_Special; break;
+
+ case Qt::Key_Dead_Grave: keysym = XK_dead_grave; break;
+ case Qt::Key_Dead_Acute: keysym = XK_dead_acute; break;
+ case Qt::Key_Dead_Circumflex: keysym = XK_dead_circumflex; break;
+ case Qt::Key_Dead_Tilde: keysym = XK_dead_tilde; break;
+ case Qt::Key_Dead_Macron: keysym = XK_dead_macron; break;
+ case Qt::Key_Dead_Breve: keysym = XK_dead_breve; break;
+ case Qt::Key_Dead_Abovedot: keysym = XK_dead_abovedot; break;
+ case Qt::Key_Dead_Diaeresis: keysym = XK_dead_diaeresis; break;
+ case Qt::Key_Dead_Abovering: keysym = XK_dead_abovering; break;
+ case Qt::Key_Dead_Doubleacute: keysym = XK_dead_doubleacute; break;
+ case Qt::Key_Dead_Caron: keysym = XK_dead_caron; break;
+ case Qt::Key_Dead_Cedilla: keysym = XK_dead_cedilla; break;
+ case Qt::Key_Dead_Ogonek: keysym = XK_dead_ogonek; break;
+ case Qt::Key_Dead_Iota: keysym = XK_dead_iota; break;
+ case Qt::Key_Dead_Voiced_Sound: keysym = XK_dead_voiced_sound; break;
+ case Qt::Key_Dead_Semivoiced_Sound: keysym = XK_dead_semivoiced_sound; break;
+ case Qt::Key_Dead_Belowdot: keysym = XK_dead_belowdot; break;
+ case Qt::Key_Dead_Hook: keysym = XK_dead_hook; break;
+ case Qt::Key_Dead_Horn: keysym = XK_dead_horn; break;
+
+ case Qt::Key_Back: keysym = XF86XK_Back; break;
+ case Qt::Key_Forward: keysym = XF86XK_Forward; break;
+ case Qt::Key_Stop: keysym = XF86XK_Stop; break;
+ case Qt::Key_Refresh: keysym = XF86XK_Refresh; break;
+
+ case Qt::Key_VolumeDown: keysym = XF86XK_AudioLowerVolume; break;
+ case Qt::Key_VolumeMute: keysym = XF86XK_AudioMute; break;
+ case Qt::Key_VolumeUp: keysym = XF86XK_AudioRaiseVolume; break;
+ case Qt::Key_BassBoost: keysym = NoSymbol; break; // ???
+ case Qt::Key_BassUp: keysym = NoSymbol; break; // ???
+ case Qt::Key_BassDown: keysym = NoSymbol; break; // ???
+ case Qt::Key_TrebleUp: keysym = NoSymbol; break; // ???
+ case Qt::Key_TrebleDown: keysym = NoSymbol; break; // ???
+
+ case Qt::Key_MediaPlay: keysym = XF86XK_AudioPlay; break;
+ case Qt::Key_MediaStop: keysym = XF86XK_AudioStop; break;
+ case Qt::Key_MediaPrevious: keysym = XF86XK_AudioPrev; break;
+ case Qt::Key_MediaNext: keysym = XF86XK_AudioNext; break;
+ case Qt::Key_MediaRecord: keysym = XF86XK_AudioRecord; break;
+
+ case Qt::Key_HomePage: keysym = XF86XK_HomePage; break;
+ case Qt::Key_Favorites: keysym = XF86XK_Favorites; break;
+ case Qt::Key_Search: keysym = XF86XK_Search; break;
+ case Qt::Key_Standby: keysym = XF86XK_Standby; break;
+ case Qt::Key_OpenUrl: keysym = XF86XK_OpenURL; break;
+
+ case Qt::Key_LaunchMail: keysym = XF86XK_Mail; break;
+ case Qt::Key_LaunchMedia: keysym = XF86XK_AudioMedia; break;
+ case Qt::Key_Launch0: keysym = XF86XK_Launch0; break;
+ case Qt::Key_Launch1: keysym = XF86XK_Launch1; break;
+ case Qt::Key_Launch2: keysym = XF86XK_Launch2; break;
+ case Qt::Key_Launch3: keysym = XF86XK_Launch3; break;
+ case Qt::Key_Launch4: keysym = XF86XK_Launch4; break;
+ case Qt::Key_Launch5: keysym = XF86XK_Launch5; break;
+ case Qt::Key_Launch6: keysym = XF86XK_Launch6; break;
+ case Qt::Key_Launch7: keysym = XF86XK_Launch7; break;
+ case Qt::Key_Launch8: keysym = XF86XK_Launch8; break;
+ case Qt::Key_Launch9: keysym = XF86XK_Launch9; break;
+ case Qt::Key_LaunchA: keysym = XF86XK_LaunchA; break;
+ case Qt::Key_LaunchB: keysym = XF86XK_LaunchB; break;
+ case Qt::Key_LaunchC: keysym = XF86XK_LaunchC; break;
+ case Qt::Key_LaunchD: keysym = XF86XK_LaunchD; break;
+ case Qt::Key_LaunchE: keysym = XF86XK_LaunchE; break;
+ case Qt::Key_LaunchF: keysym = XF86XK_LaunchF; break;
+
+ case Qt::Key_MediaLast: keysym = NoSymbol; break; // ???
+
+ case Qt::Key_Select: keysym = QTOPIAXK_Select; break;
+ case Qt::Key_Yes: keysym = QTOPIAXK_Yes; break;
+ case Qt::Key_No: keysym = QTOPIAXK_No; break;
+
+ case Qt::Key_Cancel: keysym = QTOPIAXK_Cancel; break;
+ case Qt::Key_Printer: keysym = QTOPIAXK_Printer; break;
+ case Qt::Key_Execute: keysym = QTOPIAXK_Execute; break;
+ case Qt::Key_Sleep: keysym = QTOPIAXK_Sleep; break;
+ case Qt::Key_Play: keysym = QTOPIAXK_Play; break;
+ case Qt::Key_Zoom: keysym = QTOPIAXK_Zoom; break;
+
+ case Qt::Key_Context1: keysym = QTOPIAXK_Context1; break;
+ case Qt::Key_Context2: keysym = QTOPIAXK_Context2; break;
+ case Qt::Key_Context3: keysym = QTOPIAXK_Context3; break;
+ case Qt::Key_Context4: keysym = QTOPIAXK_Context4; break;
+ case Qt::Key_Call: keysym = QTOPIAXK_Call; break;
+ case Qt::Key_Hangup: keysym = QTOPIAXK_Hangup; break;
+ case Qt::Key_Flip: keysym = QTOPIAXK_Flip; break;
+
+ case Qt::Key_unknown: keysym = NoSymbol; break;
+ }
+ if (keysym == NoSymbol)
+ return;
+
+ // Convert the X keysym into an X keycode.
+ KeyCode keycode = XKeysymToKeycode(dpy, keysym);
+ if (keycode == NoSymbol)
+ return;
+
+ // Determine if we need to fake shift keys as well.
+ int index = 0;
+ while (index < 4 && XKeycodeToKeysym(dpy, keycode, index) != keysym)
+ ++index;
+ int extraModifiers = 0;
+ if ((index & 1) != 0)
+ extraModifiers |= ShiftMask;
+ if ((index & 2) != 0)
+ extraModifiers |= Mod2Mask;
+ if ((modifiers & LockMask) != 0) {
+ // If Caps Lock is set, then flip the shift state for alphabetic keys.
+ if (qtCode >= Qt::Key_A && qtCode <= Qt::Key_Z)
+ extraModifiers ^= ShiftMask;
+ if (qtCode >= Qt::Key_Agrave && qtCode <= Qt::Key_THORN &&
+ qtCode != Qt::Key_multiply)
+ extraModifiers ^= ShiftMask;
+ }
+
+ // Adjust modifier keys for the shift states. This is needed for
+ // things like the * and # phone keys, which need Shift to be pressed
+ // when entering from a keyboard, but don't need Shift from a skin.
+ unsigned long delay = 0;
+ if (extraModifiers != 0) {
+ if ((extraModifiers & ShiftMask) != 0) {
+ if ((modifiers & ShiftMask) == 0)
+ XTestFakeKeyEvent(dpy, shiftKeycode, true, delay++);
+ } else {
+ if ((modifiers & ShiftMask) != 0)
+ XTestFakeKeyEvent(dpy, shiftKeycode, false, delay++);
+ }
+ if ((extraModifiers & Mod2Mask) != 0) {
+ if ((modifiers & Mod2Mask) == 0)
+ XTestFakeKeyEvent(dpy, modeSwitchKeycode, true, delay++);
+ } else {
+ if ((modifiers & Mod2Mask) != 0)
+ XTestFakeKeyEvent(dpy, modeSwitchKeycode, false, delay++);
+ }
+ }
+
+ // Fake the actual key.
+ XTestFakeKeyEvent(dpy, keycode, (Bool)isPress, delay++);
+
+ // Adjust the modifiers back.
+ if (extraModifiers != 0) {
+ if ((extraModifiers & ShiftMask) != 0) {
+ if ((modifiers & ShiftMask) == 0)
+ XTestFakeKeyEvent(dpy, shiftKeycode, false, delay++);
+ } else {
+ if ((modifiers & ShiftMask) != 0)
+ XTestFakeKeyEvent(dpy, shiftKeycode, true, delay++);
+ }
+ if ((extraModifiers & Mod2Mask) != 0) {
+ if ((modifiers & Mod2Mask) == 0)
+ XTestFakeKeyEvent(dpy, modeSwitchKeycode, false, delay++);
+ } else {
+ if ((modifiers & Mod2Mask) != 0)
+ XTestFakeKeyEvent(dpy, modeSwitchKeycode, true, delay++);
+ }
+ }
+
+ // Flush the key events.
+ XFlush(dpy);
+
+ // Update the modifiers if this was a shift key.
+ if (isPress) {
+ if (qtCode == Qt::Key_Shift)
+ modifiers |= ShiftMask;
+ if (qtCode == Qt::Key_CapsLock)
+ modifiers |= LockMask;
+ if (qtCode == Qt::Key_Mode_switch)
+ modifiers |= Mod2Mask;
+ } else {
+ if (qtCode == Qt::Key_Shift)
+ modifiers &= ~ShiftMask;
+ if (qtCode == Qt::Key_CapsLock)
+ modifiers &= ~LockMask;
+ if (qtCode == Qt::Key_Mode_switch)
+ modifiers &= ~Mod2Mask;
+ }
+}
+
+// Determine if an X11 keycode is currently mapped to one or more keysyms.
+static bool keycodeInUse(Display *dpy, int keycode)
+{
+ for (int index = 0; index < 8; ++index) {
+ if (XKeycodeToKeysym(dpy, keycode, index) != NoSymbol)
+ return true;
+ }
+ return false;
+}
+
+// Allocate a keycode for a special keysym.
+static bool allocateSpecialKeysym
+ (Display *dpy, int& min_keycode, int& max_keycode, KeySym key)
+{
+ if (XKeysymToKeycode(dpy, key) != NoSymbol)
+ return true; // There is already a mapping for this key. Good!
+ while (max_keycode >= min_keycode) {
+ if (!keycodeInUse(dpy, max_keycode))
+ break;
+ --max_keycode;
+ }
+ if (max_keycode < min_keycode)
+ return false;
+ XChangeKeyboardMapping(dpy, max_keycode, 1, &key, 1);
+ --max_keycode;
+ return true;
+}
+
+void X11KeyFaker::connect()
+{
+ // Open the display.
+ dpy = XOpenDisplay(displayName.toLatin1().data());
+ if (!dpy) {
+ // Try again in a few milliseconds. Xnest may not be alive yet.
+ // Give up after 10 seconds.
+ if (++retryCount < 50)
+ QTimer::singleShot(200, this, SLOT(connect()));
+ else
+ QTimer::singleShot(0, this, SIGNAL(couldNotConnect()));
+ return;
+ }
+
+ // Query the XTest extension, which we need to fake the key events.
+ int event_base, error_base, major, minor;
+ if (!XTestQueryExtension
+ (dpy, &event_base, &error_base, &major, &minor)) {
+ XCloseDisplay(dpy);
+ dpy = 0;
+ QTimer::singleShot(0, this, SIGNAL(couldNotConnect()));
+ return;
+ }
+
+ // Modify the Xnest's keyboard mappings to add Qtopia's special keysyms.
+ int min_keycode = 1, max_keycode = 255;
+ XDisplayKeycodes(dpy, &min_keycode, &max_keycode);
+ bool ok = true;
+ for (KeySym key = QTOPIAXK_Max; key >= QTOPIAXK_Min; --key) {
+ // This is an extension keysym, not part of the standard X11 set.
+ if (!allocateSpecialKeysym(dpy, min_keycode, max_keycode, key)) {
+ ok = false;
+ break;
+ }
+ }
+ static const KeySym specials[] = {
+ XF86XK_Back, // Qt::Key_Back
+ XF86XK_AudioLowerVolume, // Qt::Key_VolumeUp
+ XF86XK_AudioRaiseVolume, // Qt::Key_VolumeDown
+ XK_F28, // Qt::Key_F28
+ NoSymbol
+ };
+ int index = 0;
+ while (ok && specials[index] != NoSymbol) {
+ // This is a standard X11/XFree86 keysym that Qtopia uses,
+ // but it may not be on the user's physical keyboard.
+ if (!allocateSpecialKeysym
+ (dpy, min_keycode, max_keycode, specials[index]))
+ ok = false;
+ ++index;
+ }
+ if (!ok)
+ qWarning() << "There are insufficient spare X11 keycodes to allocate the special Qtopia keys";
+
+ // Change the root cursor to something more reasonable than "X".
+ Cursor cursor = XCreateFontCursor(dpy, XC_left_ptr);
+ XDefineCursor(dpy, RootWindow(dpy, DefaultScreen(dpy)), cursor);
+
+ // Look up the shift keys.
+ shiftKeycode = XKeysymToKeycode(dpy, XK_Shift_L);
+ if (shiftKeycode == NoSymbol)
+ shiftKeycode = XKeysymToKeycode(dpy, XK_Shift_R);
+ modeSwitchKeycode = XKeysymToKeycode(dpy, XK_Mode_switch);
+
+ // Make sure all of the above changes are flushed.
+ XFlush(dpy);
+
+ // Set up event handling for the display.
+ QSocketNotifier *notifier = new QSocketNotifier
+ (ConnectionNumber(dpy), QSocketNotifier::Read, this);
+ QObject::connect(notifier, SIGNAL(activated(int)), this, SLOT(readyRead()));
+
+ // Make sure the file descriptor is not inherited across exec's.
+ fcntl(ConnectionNumber(dpy), F_SETFD, 1);
+
+ // Notify interested parties that we are now connected to the X display.
+ QTimer::singleShot(0, this, SIGNAL(connected()));
+}
+
+void X11KeyFaker::readyRead()
+{
+ if (dpy) {
+ // Read incoming events and discard them. The only event
+ // we care about is keyboard mapping changes. Since we
+ // don't have any active windows, there's nothing more to do.
+ while (XEventsQueued(dpy, QueuedAfterFlush)) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+ if (event.xany.type == MappingNotify)
+ XRefreshKeyboardMapping(&event.xmapping);
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/qvfb/x11keyfaker.h b/src/qvfb/x11keyfaker.h
new file mode 100644
index 000000000..86cc34880
--- /dev/null
+++ b/src/qvfb/x11keyfaker.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef X11KEYFAKER_H
+#define X11KEYFAKER_H
+
+#include <QObject>
+#include <QX11Info>
+#include <qnamespace.h>
+
+QT_BEGIN_NAMESPACE
+
+class X11KeyFaker : public QObject
+{
+ Q_OBJECT
+public:
+ X11KeyFaker(const QString& displayName, QObject *parent = 0);
+ ~X11KeyFaker();
+
+ bool isConnected() const { return dpy != 0; }
+
+ void sendKeyEvent(int qtCode, bool isPress);
+
+private slots:
+ void connect();
+ void readyRead();
+
+signals:
+ void connected();
+ void couldNotConnect();
+
+private:
+ QString displayName;
+ Display *dpy;
+ int retryCount;
+ int shiftKeycode;
+ int modeSwitchKeycode;
+ int modifiers;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/runonphone/main.cpp b/src/runonphone/main.cpp
new file mode 100644
index 000000000..528154438
--- /dev/null
+++ b/src/runonphone/main.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QTextStream>
+#include <QStringList>
+#include <QScopedPointer>
+#include <QTimer>
+#include <QFileInfo>
+#include "symbianutils/trkutils.h"
+#include "symbianutils/trkdevice.h"
+#include "symbianutils/launcher.h"
+
+#include "trksignalhandler.h"
+#include "serenum.h"
+#include "ossignalconverter.h"
+
+void printUsage(QTextStream& outstream, QString exeName)
+{
+ outstream << exeName << " [options] [program] [program arguments]" << endl
+ << "-s, --sis <local file> specify sis file to install" << endl
+ << "-p, --portname <COMx> specify COM port to use by device name" << endl
+ << "-f, --portfriendlyname <substring> specify COM port to use by friendly name" << endl
+ << "-t, --timeout <milliseconds> terminate test if timeout occurs" << endl
+ << "-v, --verbose show debugging output" << endl
+ << "-q, --quiet hide progress messages" << endl
+ << "-u, --upload <local file> upload executable file to phone" << endl
+ << "-d, --download <remote file> <local file> copy file from phone to PC after running test" << endl
+ << "--nocrashlog Don't capture call stack if test crashes" << endl
+ << "--crashlogpath <dir> Path to save crash logs (default=working dir)" << endl
+ << endl
+ << "USB COM ports can usually be autodetected, use -p or -f to force a specific port." << endl
+ << "If using System TRK, it is possible to copy the program directly to sys/bin on the phone." << endl
+ << "-s can be used with both System and Application TRK to install the program" << endl;
+}
+
+#define CHECK_PARAMETER_EXISTS if(!it.hasNext()) { printUsage(outstream, args[0]); return 1; }
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ QString serialPortName;
+ QString serialPortFriendlyName;
+ QString sisFile;
+ QString exeFile;
+ QStringList cmdLine;
+ QStringList args = QCoreApplication::arguments();
+ QTextStream outstream(stdout);
+ QTextStream errstream(stderr);
+ QString uploadLocalFile;
+ QString downloadRemoteFile;
+ QString downloadLocalFile;
+ int loglevel=1;
+ int timeout=0;
+ bool crashlog = true;
+ QString crashlogpath;
+ QListIterator<QString> it(args);
+ it.next(); //skip name of program
+ while (it.hasNext()) {
+ QString arg = it.next();
+
+ if (arg.startsWith("-")) {
+ if (arg == "--portname" || arg == "-p") {
+ CHECK_PARAMETER_EXISTS
+ serialPortName = it.next();
+ }
+ else if (arg == "--portfriendlyname" || arg == "-f") {
+ CHECK_PARAMETER_EXISTS
+ serialPortFriendlyName = it.next();
+ }
+ else if (arg == "--sis" || arg == "-s") {
+ CHECK_PARAMETER_EXISTS
+ sisFile = it.next();
+ if (!QFileInfo(sisFile).exists()) {
+ errstream << "Sis file (" << sisFile << ") doesn't exist" << endl;
+ return 1;
+ }
+ }
+ else if (arg == "--upload" || arg == "-u") {
+ CHECK_PARAMETER_EXISTS
+ uploadLocalFile = it.next();
+ if (!QFileInfo(uploadLocalFile).exists()) {
+ errstream << "Executable file (" << uploadLocalFile << ") doesn't exist" << endl;
+ return 1;
+ }
+ if (!(QFileInfo(uploadLocalFile).suffix() == "exe")) {
+ errstream << "File (" << uploadLocalFile << ") must be an executable" << endl;
+ return 1;
+ }
+ }
+ else if (arg == "--download" || arg == "-d") {
+ CHECK_PARAMETER_EXISTS
+ downloadRemoteFile = it.next();
+ CHECK_PARAMETER_EXISTS
+ downloadLocalFile = it.next();
+ }
+ else if (arg == "--timeout" || arg == "-t") {
+ CHECK_PARAMETER_EXISTS
+ bool ok;
+ timeout = it.next().toInt(&ok);
+ if (!ok) {
+ errstream << "Timeout must be specified in milliseconds" << endl;
+ return 1;
+ }
+ }
+ else if (arg == "--verbose" || arg == "-v")
+ loglevel=2;
+ else if (arg == "--quiet" || arg == "-q")
+ loglevel=0;
+ else if (arg == "--nocrashlog")
+ crashlog = false;
+ else if (arg == "--crashlogpath") {
+ CHECK_PARAMETER_EXISTS
+ crashlogpath = it.next();
+ }
+ else
+ errstream << "unknown command line option " << arg << endl;
+ } else {
+ exeFile = arg;
+ while(it.hasNext()) {
+ cmdLine.append(it.next());
+ }
+ }
+ }
+
+ if (exeFile.isEmpty() && sisFile.isEmpty() && uploadLocalFile.isEmpty() &&
+ (downloadLocalFile.isEmpty() || downloadRemoteFile.isEmpty())) {
+ printUsage(outstream, args[0]);
+ return 1;
+ }
+
+ if (!uploadLocalFile.isEmpty() && (!downloadLocalFile.isEmpty() || !downloadRemoteFile.isEmpty())) {
+ errstream << "Upload option can't be used together with download" << endl;
+ printUsage(outstream, args[0]);
+ return 1;
+ }
+
+ if (serialPortName.isEmpty()) {
+ if (loglevel > 0)
+ outstream << "Detecting serial ports" << endl;
+ foreach (const SerialPortId &id, enumerateSerialPorts(loglevel)) {
+ if (loglevel > 0)
+ outstream << "Port Name: " << id.portName << ", "
+ << "Friendly Name:" << id.friendlyName << endl;
+ if (!id.friendlyName.isEmpty()
+ && serialPortFriendlyName.isEmpty()
+ && (id.friendlyName.contains("symbian", Qt::CaseInsensitive)
+ || id.friendlyName.contains("s60", Qt::CaseInsensitive)
+ || id.friendlyName.contains("nokia", Qt::CaseInsensitive))) {
+ serialPortName = id.portName;
+ break;
+ } else if (!id.friendlyName.isEmpty()
+ && !serialPortFriendlyName.isEmpty()
+ && id.friendlyName.contains(serialPortFriendlyName)) {
+ serialPortName = id.portName;
+ break;
+ }
+ }
+ if (serialPortName.isEmpty()) {
+ errstream << "No phone found, ensure USB cable is connected or specify manually with -p" << endl;
+ return 1;
+ }
+ }
+
+ QScopedPointer<trk::Launcher> launcher;
+ launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly));
+ QFileInfo exeInfo(exeFile);
+ QFileInfo uploadInfo(uploadLocalFile);
+ if (!sisFile.isEmpty()) {
+ launcher->addStartupActions(trk::Launcher::ActionCopyInstall);
+ launcher->setCopyFileName(sisFile, "c:\\data\\testtemp.sis");
+ launcher->setInstallFileName("c:\\data\\testtemp.sis");
+ }
+ else if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) {
+ launcher->addStartupActions(trk::Launcher::ActionCopy);
+ launcher->setCopyFileName(uploadLocalFile, QString("c:\\sys\\bin\\") + uploadInfo.fileName());
+ }
+ if (!exeFile.isEmpty()) {
+ launcher->addStartupActions(trk::Launcher::ActionRun);
+ launcher->setFileName(QString("c:\\sys\\bin\\") + exeInfo.fileName());
+ launcher->setCommandLineArgs(cmdLine);
+ }
+ if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) {
+ launcher->addStartupActions(trk::Launcher::ActionDownload);
+ launcher->setDownloadFileName(downloadRemoteFile, downloadLocalFile);
+ }
+ if (loglevel > 0)
+ outstream << "Connecting to target via " << serialPortName << endl;
+ launcher->setTrkServerName(serialPortName);
+
+ if (loglevel > 1)
+ launcher->setVerbose(1);
+
+ TrkSignalHandler handler;
+ handler.setLogLevel(loglevel);
+ handler.setCrashLogging(crashlog);
+ handler.setCrashLogPath(crashlogpath);
+
+ QObject::connect(launcher.data(), SIGNAL(copyingStarted()), &handler, SLOT(copyingStarted()));
+ QObject::connect(launcher.data(), SIGNAL(canNotConnect(const QString &)), &handler, SLOT(canNotConnect(const QString &)));
+ QObject::connect(launcher.data(), SIGNAL(canNotCreateFile(const QString &, const QString &)), &handler, SLOT(canNotCreateFile(const QString &, const QString &)));
+ QObject::connect(launcher.data(), SIGNAL(canNotWriteFile(const QString &, const QString &)), &handler, SLOT(canNotWriteFile(const QString &, const QString &)));
+ QObject::connect(launcher.data(), SIGNAL(canNotCloseFile(const QString &, const QString &)), &handler, SLOT(canNotCloseFile(const QString &, const QString &)));
+ QObject::connect(launcher.data(), SIGNAL(installingStarted()), &handler, SLOT(installingStarted()));
+ QObject::connect(launcher.data(), SIGNAL(canNotInstall(const QString &, const QString &)), &handler, SLOT(canNotInstall(const QString &, const QString &)));
+ QObject::connect(launcher.data(), SIGNAL(installingFinished()), &handler, SLOT(installingFinished()));
+ QObject::connect(launcher.data(), SIGNAL(startingApplication()), &handler, SLOT(startingApplication()));
+ QObject::connect(launcher.data(), SIGNAL(applicationRunning(uint)), &handler, SLOT(applicationRunning(uint)));
+ QObject::connect(launcher.data(), SIGNAL(canNotRun(const QString &)), &handler, SLOT(canNotRun(const QString &)));
+ QObject::connect(launcher.data(), SIGNAL(applicationOutputReceived(const QString &)), &handler, SLOT(applicationOutputReceived(const QString &)));
+ QObject::connect(launcher.data(), SIGNAL(copyProgress(int)), &handler, SLOT(copyProgress(int)));
+ QObject::connect(launcher.data(), SIGNAL(stateChanged(int)), &handler, SLOT(stateChanged(int)));
+ QObject::connect(launcher.data(), SIGNAL(processStopped(uint,uint,uint,QString)), &handler, SLOT(stopped(uint,uint,uint,QString)));
+ QObject::connect(launcher.data(), SIGNAL(libraryLoaded(trk::Library)), &handler, SLOT(libraryLoaded(trk::Library)));
+ QObject::connect(launcher.data(), SIGNAL(libraryUnloaded(trk::Library)), &handler, SLOT(libraryUnloaded(trk::Library)));
+ QObject::connect(launcher.data(), SIGNAL(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)), &handler, SLOT(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)));
+ QObject::connect(&handler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resumeProcess(uint,uint)));
+ QObject::connect(&handler, SIGNAL(terminate()), launcher.data(), SLOT(terminate()));
+ QObject::connect(&handler, SIGNAL(getRegistersAndCallStack(uint,uint)), launcher.data(), SLOT(getRegistersAndCallStack(uint,uint)));
+ QObject::connect(launcher.data(), SIGNAL(finished()), &handler, SLOT(finished()));
+
+ QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), launcher.data(), SLOT(terminate()), Qt::QueuedConnection);
+
+ QTimer timer;
+ timer.setSingleShot(true);
+ QObject::connect(&timer, SIGNAL(timeout()), &handler, SLOT(timeout()));
+ if (timeout > 0) {
+ timer.start(timeout);
+ }
+
+ QString errorMessage;
+ if (!launcher->startServer(&errorMessage)) {
+ errstream << errorMessage << endl;
+ return 1;
+ }
+
+ return a.exec();
+}
+
diff --git a/src/runonphone/ossignalconverter.cpp b/src/runonphone/ossignalconverter.cpp
new file mode 100644
index 000000000..71e705fee
--- /dev/null
+++ b/src/runonphone/ossignalconverter.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ossignalconverter_p.h"
+#include <signal.h>
+#include <QTimer>
+#include <stdio.h>
+
+Q_GLOBAL_STATIC(OsSignalConverter, osSignalConverter);
+
+OsSignalConverter* OsSignalConverter::instance()
+{
+ return osSignalConverter();
+}
+
+OsSignalConverter::OsSignalConverter()
+: d(new OsSignalConverterPrivate(this))
+{
+};
+
+OsSignalConverter::~OsSignalConverter()
+{
+}
+
+OsSignalConverterPrivate::OsSignalConverterPrivate(OsSignalConverter* owner)
+: QObject(owner), q(owner), poller(new QTimer(this))
+{
+ trap();
+ connect(poller, SIGNAL(timeout()), this, SLOT(poll()));
+ poller->start(1000);
+}
+
+OsSignalConverterPrivate::~OsSignalConverterPrivate()
+{
+ untrap();
+}
+
+void OsSignalConverterPrivate::trap()
+{
+ signal(SIGINT, handler);
+ signal(SIGTERM, handler);
+#ifdef SIGBREAK
+ signal(SIGBREAK, handler);
+#endif
+#ifdef SIGHUP
+ signal(SIGHUP, handler);
+#endif
+#ifdef SIGQUIT
+ signal(SIGQUIT, handler);
+#endif
+}
+
+void OsSignalConverterPrivate::untrap()
+{
+ signal(SIGINT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+#ifdef SIGBREAK
+ signal(SIGBREAK, SIG_DFL);
+#endif
+#ifdef SIGHUP
+ signal(SIGHUP, SIG_DFL);
+#endif
+#ifdef SIGQUIT
+ signal(SIGQUIT, SIG_DFL);
+#endif
+}
+
+void OsSignalConverterPrivate::handler(int sig)
+{
+ untrap(); //allow 2nd ctrl-c to really kill us
+ terminateRequest = sig;
+}
+
+void OsSignalConverterPrivate::poll()
+{
+ if (terminateRequest) {
+ fprintf(stderr, "\n*** caught signal %d, terminating ***\n", terminateRequest);
+ poller->stop();
+ emit q->terminate();
+ }
+}
+
+sig_atomic_t OsSignalConverterPrivate::terminateRequest;
diff --git a/src/runonphone/ossignalconverter.h b/src/runonphone/ossignalconverter.h
new file mode 100644
index 000000000..7c69a4b44
--- /dev/null
+++ b/src/runonphone/ossignalconverter.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OSSIGNALCONVERTER_H
+#define OSSIGNALCONVERTER_H
+#include <QObject>
+
+class OsSignalConverterPrivate;
+
+class OsSignalConverter : public QObject
+{
+ friend class OsSignalConverterPrivate;
+ Q_OBJECT
+public:
+ static OsSignalConverter* instance();
+ OsSignalConverter();
+ ~OsSignalConverter();
+signals:
+ //emitted when this process is asked to quit, e.g. by SIGINT
+ void terminate();
+private:
+ OsSignalConverterPrivate *d;
+};
+
+#endif // OSSIGNALCONVERTER_H
diff --git a/src/runonphone/ossignalconverter_p.h b/src/runonphone/ossignalconverter_p.h
new file mode 100644
index 000000000..b7991c845
--- /dev/null
+++ b/src/runonphone/ossignalconverter_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OSSIGNALCONVERTER_P_H
+#define OSSIGNALCONVERTER_P_H
+#include "ossignalconverter.h"
+#include <signal.h>
+
+class QTimer;
+class OsSignalConverterPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ OsSignalConverterPrivate(OsSignalConverter* owner);
+ ~OsSignalConverterPrivate();
+private:
+
+ static void trap();
+ static void untrap();
+ static void handler(int signal);
+
+private slots:
+
+ void poll();
+
+private:
+
+ OsSignalConverter* q;
+ static sig_atomic_t terminateRequest;
+ QTimer *poller;
+};
+
+#endif // OSSIGNALCONVERTER_P_H
diff --git a/src/runonphone/runonphone.pro b/src/runonphone/runonphone.pro
new file mode 100644
index 000000000..7ff361ccf
--- /dev/null
+++ b/src/runonphone/runonphone.pro
@@ -0,0 +1,35 @@
+TEMPLATE = app
+
+QT -= gui
+CONFIG += console
+CONFIG -= app_bundle
+
+include(symbianutils/symbianutils.pri)
+
+SOURCES += main.cpp \
+ trksignalhandler.cpp \
+ ossignalconverter.cpp
+
+HEADERS += trksignalhandler.h \
+ serenum.h \
+ ossignalconverter.h \
+ ossignalconverter_p.h
+
+DEFINES += SYMBIANUTILS_INCLUDE_PRI
+
+windows {
+ SOURCES += serenum_win.cpp
+ LIBS += -lsetupapi \
+ -luuid \
+ -ladvapi32
+}
+else:unix:!symbian {
+ SOURCES += serenum_unix.cpp
+ LIBS += -lusb
+}
+else {
+ SOURCES += serenum_stub.cpp
+}
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/runonphone/serenum.h b/src/runonphone/serenum.h
new file mode 100644
index 000000000..4ed7d4daa
--- /dev/null
+++ b/src/runonphone/serenum.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WIN32SERENUM_H
+#define WIN32SERENUM_H
+
+#include <QString>
+#include <QList>
+
+struct SerialPortId
+{
+ QString portName;
+ QString friendlyName;
+};
+
+QList<SerialPortId> enumerateSerialPorts(int loglevel);
+
+#endif // WIN32SERENUM_H
diff --git a/src/runonphone/serenum_stub.cpp b/src/runonphone/serenum_stub.cpp
new file mode 100644
index 000000000..08b0fabd9
--- /dev/null
+++ b/src/runonphone/serenum_stub.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "serenum.h"
+#include <QByteArray>
+#include <QString>
+#include <QDebug>
+
+QList<SerialPortId> enumerateSerialPorts()
+{
+ QList<SerialPortId> list;
+ qWarning() << "enumerateSerialPorts not implemented";
+ return list;
+}
+
diff --git a/src/runonphone/serenum_unix.cpp b/src/runonphone/serenum_unix.cpp
new file mode 100644
index 000000000..8cc0b82a4
--- /dev/null
+++ b/src/runonphone/serenum_unix.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "serenum.h"
+#include <QByteArray>
+#include <QString>
+#include <QDebug>
+#include <QFileInfo>
+#include <QDir>
+
+#include <usb.h>
+
+class InterfaceInfo
+{
+public:
+ InterfaceInfo(const QString &mf, const QString &pr, int mfid, int prid);
+ QString manufacturer;
+ QString product;
+ int manufacturerid;
+ int productid;
+};
+
+InterfaceInfo::InterfaceInfo(const QString &mf, const QString &pr, int mfid, int prid) :
+ manufacturer(mf),
+ product(pr),
+ manufacturerid(mfid),
+ productid(prid)
+{
+ if(mf.isEmpty())
+ manufacturer = QString("[%1]").arg(mfid, 4, 16, QChar('0'));
+ if(pr.isEmpty())
+ product = QString("[%1]").arg(prid, 4, 16, QChar('0'));
+}
+
+QList<SerialPortId> enumerateSerialPorts(int loglevel)
+{
+ QList<QString> eligibleInterfaces;
+ QList<InterfaceInfo> eligibleInterfacesInfo;
+ QList<SerialPortId> list;
+
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) {
+ for (struct usb_device *device = bus->devices; device; device = device->next) {
+ for (int n = 0; n < device->descriptor.bNumConfigurations && device->config; ++n) {
+ struct usb_config_descriptor &usbConfig =device->config[n];
+ QList<int> usableInterfaces;
+ for (int m = 0; m < usbConfig.bNumInterfaces; ++m) {
+ for (int o = 0; o < usbConfig.interface[m].num_altsetting; ++o) {
+ struct usb_interface_descriptor &descriptor = usbConfig.interface[m].altsetting[o];
+ if (descriptor.bInterfaceClass != 2 // "Communication"
+ || descriptor.bInterfaceSubClass != 2 // Abstract (modem)
+ || descriptor.bInterfaceProtocol != 255) // Vendor Specific
+ continue;
+
+ unsigned char *buf = descriptor.extra;
+ unsigned int size = descriptor.extralen;
+ while (size >= 2 * sizeof(u_int8_t)) {
+ // for Communication devices there is a slave interface for the actual
+ // data transmission.
+ // the extra info stores that as a index for the interface
+ if (buf[0] >= 5 && buf[1] == 36 && buf[2] == 6) { // CDC Union
+ for (int i = 3; i < buf[0]; i++)
+ usableInterfaces.append((int) buf[i]);
+ }
+ size -= buf[0];
+ buf += buf[0];
+ }
+ }
+ }
+
+ if (usableInterfaces.isEmpty())
+ continue;
+
+ QString manufacturerString;
+ QString productString;
+
+ usb_dev_handle *devh = usb_open(device);
+ if (devh) {
+ QByteArray buf;
+ buf.resize(256);
+ int err = usb_get_string_simple(devh, device->descriptor.iManufacturer, buf.data(), buf.size());
+ if (err < 0) {
+ if (loglevel > 1)
+ qDebug() << " can't read manufacturer name, error:" << err;
+ } else {
+ manufacturerString = QString::fromAscii(buf);
+ if (loglevel > 1)
+ qDebug() << " manufacturer:" << manufacturerString;
+ }
+
+ buf.resize(256);
+ err = usb_get_string_simple(devh, device->descriptor.iProduct, buf.data(), buf.size());
+ if (err < 0) {
+ if (loglevel > 1)
+ qDebug() << " can't read product name, error:" << err;
+ } else {
+ productString = QString::fromAscii(buf);
+ if (loglevel > 1)
+ qDebug() << " product:" << productString;
+ }
+ usb_close(devh);
+ } else if (loglevel > 0) {
+ qDebug() << " can't open usb device";
+ }
+
+ // second loop to find the actual data interface.
+ foreach (int i, usableInterfaces) {
+#ifdef Q_OS_MAC
+ eligibleInterfaces << QString("^cu\\.usbmodem.*%1$")
+ .arg(QString("%1").arg(descriptor.bInterfaceNumber, 1, 16).toUpper());
+#else
+ // ### manufacturer and product strings are only readable as root :(
+ if (!manufacturerString.isEmpty() && !productString.isEmpty()) {
+ eligibleInterfaces << QString("usb-%1_%2-if%3")
+ .arg(manufacturerString.replace(QChar(' '), QChar('_')))
+ .arg(productString.replace(QChar(' '), QChar('_')))
+ .arg(i, 2, 16, QChar('0'));
+ } else {
+ eligibleInterfaces << QString("if%1").arg(i, 2, 16, QChar('0')); // fix!
+ }
+#endif
+ }
+ eligibleInterfacesInfo << InterfaceInfo(manufacturerString, productString, device->descriptor.idVendor, device->descriptor.idProduct);
+ }
+ }
+ }
+
+ if (loglevel > 1)
+ qDebug() << " searching for interfaces:" << eligibleInterfaces;
+
+#ifdef Q_OS_MAC
+ QDir dir("/dev/");
+ bool allowAny = false;
+#else
+ QDir dir("/dev/serial/by-id/");
+ bool allowAny = eligibleInterfaces.isEmpty();
+#endif
+ foreach (const QFileInfo &info, dir.entryInfoList(QDir::System)) {
+ if (!info.isDir()) {
+ bool usable = allowAny;
+ QString friendlyName = info.fileName();
+ foreach (const QString &iface, eligibleInterfaces) {
+ if (info.fileName().contains(QRegExp(iface))) {
+ if (loglevel > 1)
+ qDebug() << " found device file:" << info.fileName() << endl;
+#ifdef Q_OS_MAC
+ friendlyName = eligibleInterfacesInfo[eligibleInterfaces.indexOf(iface)].product;
+#endif
+ usable = true;
+ break;
+ }
+ }
+ if (!usable)
+ continue;
+
+ SerialPortId id;
+ id.friendlyName = friendlyName;
+ id.portName = info.canonicalFilePath();
+ list << id;
+ }
+ }
+
+ if (list.isEmpty() && !eligibleInterfacesInfo.isEmpty() && loglevel > 0) {
+ qDebug() << "Possible USB devices found, but without serial drivers:";
+ foreach(const InterfaceInfo &iface, eligibleInterfacesInfo) {
+ qDebug() << " Manufacturer:"
+ << iface.manufacturer
+ << "Product:"
+ << iface.product
+#ifdef Q_OS_LINUX
+ << endl
+ << " Load generic driver using:"
+ << QString("sudo modprobe usbserial vendor=0x%1 product=0x%2")
+ .arg(iface.manufacturerid, 4, 16, QChar('0'))
+ .arg(iface.productid, 4, 16, QChar('0'));
+#else
+ ;
+#endif
+ }
+ }
+ return list;
+}
+
diff --git a/src/runonphone/serenum_win.cpp b/src/runonphone/serenum_win.cpp
new file mode 100644
index 000000000..7cc9d5215
--- /dev/null
+++ b/src/runonphone/serenum_win.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "serenum.h"
+#include <QByteArray>
+#include <QString>
+#include <QDebug>
+#include <windows.h>
+#include <windef.h>
+#include <setupapi.h>
+#include <devguid.h>
+#include <winreg.h>
+#include <shlwapi.h>
+
+//{4d36e978-e325-11ce-bfc1-08002be10318}
+//DEFINE_GUID(GUID_DEVCLASS_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 );
+
+QList<SerialPortId> enumerateSerialPorts(int)
+{
+ DWORD index=0;
+ SP_DEVINFO_DATA info;
+ GUID guid = GUID_DEVCLASS_PORTS;
+ HDEVINFO infoset = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT);
+ QString valueName(16384, 0);
+ QList<SerialPortId> list;
+
+ for (index=0;;index++) {
+ ZeroMemory(&info, sizeof(SP_DEVINFO_DATA));
+ info.cbSize = sizeof(SP_DEVINFO_DATA);
+ if (!SetupDiEnumDeviceInfo(infoset, index, &info))
+ break;
+ QString friendlyName;
+ QString portName;
+ DWORD size=0;
+ SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, 0, 0, &size);
+ QByteArray ba(size, 0);
+ if(SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, (BYTE*)(ba.data()), size, 0)) {
+ friendlyName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1);
+ }
+ HKEY key = SetupDiOpenDevRegKey(infoset, &info, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
+ if(key != INVALID_HANDLE_VALUE) {
+ //RegGetValue not supported on XP, SHRegGetValue not supported by mingw, so use the old method of enumerating all the values
+ for (DWORD dwi=0;;dwi++) {
+ DWORD vsize = valueName.size();
+ if (ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, 0, &size)) {
+ if (valueName.startsWith("PortName")) {
+ QByteArray ba(size, 0);
+ vsize = valueName.size();
+ if(ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, (BYTE*)(ba.data()), &size)) {
+ portName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1);
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ RegCloseKey(key);
+ }
+ SerialPortId id;
+ id.portName = portName;
+ id.friendlyName = friendlyName;
+ list.append(id);
+ }
+ SetupDiDestroyDeviceInfoList(infoset);
+ return list;
+}
+
diff --git a/src/runonphone/symbianutils/bluetoothlistener.cpp b/src/runonphone/symbianutils/bluetoothlistener.cpp
new file mode 100644
index 000000000..be232db04
--- /dev/null
+++ b/src/runonphone/symbianutils/bluetoothlistener.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bluetoothlistener.h"
+#include "trkdevice.h"
+
+#include <QtCore/QDebug>
+
+#ifdef Q_OS_UNIX
+# include <unistd.h>
+# include <signal.h>
+#else
+# include <windows.h>
+#endif
+
+// Process id helpers.
+#ifdef Q_OS_WIN
+inline DWORD processId(const QProcess &p)
+{
+ if (const Q_PID processInfoStruct = p.pid())
+ return processInfoStruct->dwProcessId;
+ return 0;
+}
+#else
+inline Q_PID processId(const QProcess &p)
+{
+ return p.pid();
+}
+#endif
+
+
+enum { debug = 0 };
+
+namespace trk {
+
+struct BluetoothListenerPrivate {
+ BluetoothListenerPrivate();
+ QString device;
+ QProcess process;
+#ifdef Q_OS_WIN
+ DWORD pid;
+#else
+ Q_PID pid;
+#endif
+ bool printConsoleMessages;
+ BluetoothListener::Mode mode;
+};
+
+BluetoothListenerPrivate::BluetoothListenerPrivate() :
+ pid(0),
+ printConsoleMessages(false),
+ mode(BluetoothListener::Listen)
+{
+}
+
+BluetoothListener::BluetoothListener(QObject *parent) :
+ QObject(parent),
+ d(new BluetoothListenerPrivate)
+{
+ d->process.setProcessChannelMode(QProcess::MergedChannels);
+
+ connect(&d->process, SIGNAL(readyReadStandardError()),
+ this, SLOT(slotStdError()));
+ connect(&d->process, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(slotStdOutput()));
+ connect(&d->process, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(slotProcessFinished(int,QProcess::ExitStatus)));
+ connect(&d->process, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(slotProcessError(QProcess::ProcessError)));
+}
+
+BluetoothListener::~BluetoothListener()
+{
+ const int trc = terminateProcess();
+ if (debug)
+ qDebug() << "~BluetoothListener: terminated" << trc;
+ delete d;
+}
+
+BluetoothListener::Mode BluetoothListener::mode() const
+{
+ return d->mode;
+}
+
+void BluetoothListener::setMode(Mode m)
+{
+ d->mode = m;
+}
+
+bool BluetoothListener::printConsoleMessages() const
+{
+ return d->printConsoleMessages;
+}
+
+void BluetoothListener::setPrintConsoleMessages(bool p)
+{
+ d->printConsoleMessages = p;
+}
+
+int BluetoothListener::terminateProcess()
+{
+ enum { TimeOutMS = 200 };
+ if (debug)
+ qDebug() << "terminateProcess" << d->process.pid() << d->process.state();
+ if (d->process.state() == QProcess::NotRunning)
+ return -1;
+ emitMessage(tr("%1: Stopping listener %2...").arg(d->device).arg(processId(d->process)));
+ // When listening, the process should terminate by itself after closing the connection
+ if (mode() == Listen && d->process.waitForFinished(TimeOutMS))
+ return 0;
+#ifdef Q_OS_UNIX
+ kill(d->process.pid(), SIGHUP); // Listens for SIGHUP
+ if (d->process.waitForFinished(TimeOutMS))
+ return 1;
+#endif
+ d->process.terminate();
+ if (d->process.waitForFinished(TimeOutMS))
+ return 2;
+ d->process.kill();
+ return 3;
+}
+
+bool BluetoothListener::start(const QString &device, QString *errorMessage)
+{
+ if (d->process.state() != QProcess::NotRunning) {
+ *errorMessage = QLatin1String("Internal error: Still running.");
+ return false;
+ }
+ d->device = device;
+ const QString binary = QLatin1String("rfcomm");
+ QStringList arguments;
+ arguments << QLatin1String("-r")
+ << (d->mode == Listen ? QLatin1String("listen") : QLatin1String("watch"))
+ << device << QString(QLatin1Char('1'));
+ if (debug)
+ qDebug() << binary << arguments;
+ emitMessage(tr("%1: Starting Bluetooth listener %2...").arg(device, binary));
+ d->pid = 0;
+ d->process.start(binary, arguments);
+ if (!d->process.waitForStarted()) {
+ *errorMessage = tr("Unable to run '%1': %2").arg(binary, d->process.errorString());
+ return false;
+ }
+ d->pid = processId(d->process); // Forgets it after crash/termination
+ emitMessage(tr("%1: Bluetooth listener running (%2).").arg(device).arg(processId(d->process)));
+ return true;
+}
+
+void BluetoothListener::slotStdOutput()
+{
+ emitMessage(QString::fromLocal8Bit(d->process.readAllStandardOutput()));
+}
+
+void BluetoothListener::emitMessage(const QString &m)
+{
+ if (d->printConsoleMessages || debug)
+ qDebug("%s\n", qPrintable(m));
+ emit message(m);
+}
+
+void BluetoothListener::slotStdError()
+{
+ emitMessage(QString::fromLocal8Bit(d->process.readAllStandardError()));
+}
+
+void BluetoothListener::slotProcessFinished(int ex, QProcess::ExitStatus state)
+{
+ switch (state) {
+ case QProcess::NormalExit:
+ emitMessage(tr("%1: Process %2 terminated with exit code %3.")
+ .arg(d->device).arg(d->pid).arg(ex));
+ break;
+ case QProcess::CrashExit:
+ emitMessage(tr("%1: Process %2 crashed.").arg(d->device).arg(d->pid));
+ break;
+ }
+ emit terminated();
+}
+
+void BluetoothListener::slotProcessError(QProcess::ProcessError error)
+{
+ emitMessage(tr("%1: Process error %2: %3")
+ .arg(d->device).arg(error).arg(d->process.errorString()));
+}
+
+} // namespace trk
diff --git a/src/runonphone/symbianutils/bluetoothlistener.h b/src/runonphone/symbianutils/bluetoothlistener.h
new file mode 100644
index 000000000..38757275e
--- /dev/null
+++ b/src/runonphone/symbianutils/bluetoothlistener.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BLUETOOTHLISTENER_H
+#define BLUETOOTHLISTENER_H
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QProcess>
+
+namespace trk {
+struct BluetoothListenerPrivate;
+
+/* BluetoothListener: Starts a helper process watching connections on a
+ * Bluetooth device, Linux only:
+ * The rfcomm command is used. It process can be started in the background
+ * while connection attempts (TrkDevice::open()) are made in the foreground. */
+
+class SYMBIANUTILS_EXPORT BluetoothListener : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(BluetoothListener)
+public:
+ // The Mode property must be set before calling start().
+ enum Mode {
+ Listen, /* Terminate after client closed (read: Trk app
+ * on the phone terminated or disconnected).*/
+ Watch // Keep running, watch for next connection from client
+ };
+
+ explicit BluetoothListener(QObject *parent = 0);
+ virtual ~BluetoothListener();
+
+ Mode mode() const;
+ void setMode(Mode m);
+
+ bool start(const QString &device, QString *errorMessage);
+
+ // Print messages on the console.
+ bool printConsoleMessages() const;
+ void setPrintConsoleMessages(bool p);
+
+signals:
+ void terminated();
+ void message(const QString &);
+
+public slots:
+ void emitMessage(const QString &m); // accessed by starter
+
+private slots:
+ void slotStdOutput();
+ void slotStdError();
+ void slotProcessFinished(int, QProcess::ExitStatus);
+ void slotProcessError(QProcess::ProcessError error);
+
+private:
+ int terminateProcess();
+
+ BluetoothListenerPrivate *d;
+};
+
+} // namespace trk
+
+#endif // BLUETOOTHLISTENER_H
diff --git a/src/runonphone/symbianutils/bluetoothlistener_gui.cpp b/src/runonphone/symbianutils/bluetoothlistener_gui.cpp
new file mode 100644
index 000000000..c3f36b23a
--- /dev/null
+++ b/src/runonphone/symbianutils/bluetoothlistener_gui.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bluetoothlistener_gui.h"
+#include "bluetoothlistener.h"
+#include "communicationstarter.h"
+
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+
+namespace trk {
+
+SYMBIANUTILS_EXPORT PromptStartCommunicationResult
+ promptStartCommunication(BaseCommunicationStarter &starter,
+ const QString &msgBoxTitle,
+ const QString &msgBoxText,
+ QWidget *msgBoxParent,
+ QString *errorMessage)
+{
+ errorMessage->clear();
+ // Initial connection attempt.
+ switch (starter.start()) {
+ case BaseCommunicationStarter::Started:
+ break;
+ case BaseCommunicationStarter::ConnectionSucceeded:
+ return PromptStartCommunicationConnected;
+ case BaseCommunicationStarter::StartError:
+ *errorMessage = starter.errorString();
+ return PromptStartCommunicationError;
+ }
+ // Run the starter with the event loop of a message box, have the box
+ // closed by the signals of the starter.
+ QMessageBox messageBox(QMessageBox::Information, msgBoxTitle, msgBoxText, QMessageBox::Cancel, msgBoxParent);
+ QObject::connect(&starter, SIGNAL(connected()), &messageBox, SLOT(close()));
+ QObject::connect(&starter, SIGNAL(timeout()), &messageBox, SLOT(close()));
+ messageBox.exec();
+ // Only starter.state() is reliable here to obtain the state.
+ switch (starter.state()) {
+ case AbstractBluetoothStarter::Running:
+ *errorMessage = QCoreApplication::translate("trk::promptStartCommunication", "Connection on %1 canceled.").arg(starter.device());
+ return PromptStartCommunicationCanceled;
+ case AbstractBluetoothStarter::TimedOut:
+ *errorMessage = starter.errorString();
+ return PromptStartCommunicationError;
+ case AbstractBluetoothStarter::Connected:
+ break;
+ }
+ return PromptStartCommunicationConnected;
+}
+
+SYMBIANUTILS_EXPORT PromptStartCommunicationResult
+ promptStartSerial(BaseCommunicationStarter &starter,
+ QWidget *msgBoxParent,
+ QString *errorMessage)
+{
+ const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK");
+ const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK to start on %1...").arg(starter.device());
+ return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage);
+}
+
+SYMBIANUTILS_EXPORT PromptStartCommunicationResult
+ promptStartBluetooth(BaseCommunicationStarter &starter,
+ QWidget *msgBoxParent,
+ QString *errorMessage)
+{
+ const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for Bluetooth Connection");
+ const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Connecting to %1...").arg(starter.device());
+ return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage);
+}
+
+} // namespace trk
diff --git a/src/runonphone/symbianutils/bluetoothlistener_gui.h b/src/runonphone/symbianutils/bluetoothlistener_gui.h
new file mode 100644
index 000000000..d0edc7a26
--- /dev/null
+++ b/src/runonphone/symbianutils/bluetoothlistener_gui.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BLUETOOTHLISTENER_GUI_H
+#define BLUETOOTHLISTENER_GUI_H
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+class QWidget;
+QT_END_NAMESPACE
+
+namespace trk {
+class BaseCommunicationStarter;
+
+/* promptStartCommunication(): Convenience functions that
+ * prompt the user to start a communication (launching or
+ * connecting TRK) using a modal message box in which they can cancel.
+ * Pass in the starter with device and parameters set up. */
+
+enum PromptStartCommunicationResult {
+ PromptStartCommunicationConnected,
+ PromptStartCommunicationCanceled,
+ PromptStartCommunicationError
+};
+
+SYMBIANUTILS_EXPORT PromptStartCommunicationResult
+ promptStartCommunication(BaseCommunicationStarter &starter,
+ const QString &msgBoxTitle,
+ const QString &msgBoxText,
+ QWidget *msgBoxParent,
+ QString *errorMessage);
+
+// Convenience to start a serial connection (messages prompting
+// to launch Trk).
+SYMBIANUTILS_EXPORT PromptStartCommunicationResult
+ promptStartSerial(BaseCommunicationStarter &starter,
+ QWidget *msgBoxParent,
+ QString *errorMessage);
+
+// Convenience to start blue tooth connection (messages
+// prompting to connect).
+SYMBIANUTILS_EXPORT PromptStartCommunicationResult
+ promptStartBluetooth(BaseCommunicationStarter &starter,
+ QWidget *msgBoxParent,
+ QString *errorMessage);
+} // namespace trk
+
+#endif // BLUETOOTHLISTENER_GUI_H
diff --git a/src/runonphone/symbianutils/callback.h b/src/runonphone/symbianutils/callback.h
new file mode 100644
index 000000000..4ee77ea31
--- /dev/null
+++ b/src/runonphone/symbianutils/callback.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEBUGGER_CALLBACK_H
+#define DEBUGGER_CALLBACK_H
+
+#include "symbianutils_global.h"
+
+namespace trk {
+namespace Internal {
+
+/* Helper class for the 1-argument functor:
+ * Cloneable base class for the implementation which is
+ * invokeable with the argument. */
+template <class Argument>
+class CallbackImplBase
+{
+ Q_DISABLE_COPY(CallbackImplBase)
+public:
+ CallbackImplBase() {}
+ virtual CallbackImplBase *clone() const = 0;
+ virtual void invoke(Argument a) = 0;
+ virtual ~CallbackImplBase() {}
+};
+
+/* Helper class for the 1-argument functor: Implementation for
+ * a class instance with a member function pointer. */
+template <class Class, class Argument>
+class CallbackMemberPtrImpl : public CallbackImplBase<Argument>
+{
+public:
+ typedef void (Class::*MemberFuncPtr)(Argument);
+
+ CallbackMemberPtrImpl(Class *instance,
+ MemberFuncPtr memberFunc) :
+ m_instance(instance),
+ m_memberFunc(memberFunc) {}
+
+ virtual CallbackImplBase<Argument> *clone() const
+ {
+ return new CallbackMemberPtrImpl<Class, Argument>(m_instance, m_memberFunc);
+ }
+
+ virtual void invoke(Argument a)
+ { (m_instance->*m_memberFunc)(a); }
+private:
+ Class *m_instance;
+ MemberFuncPtr m_memberFunc;
+};
+
+} // namespace Internal
+
+/* Default-constructible, copyable 1-argument functor providing an
+ * operator()(Argument) that invokes a member function of a class:
+ * \code
+class Foo {
+public:
+ void print(const std::string &);
+};
+...
+Foo foo;
+Callback<const std::string &> f1(&foo, &Foo::print);
+f1("test");
+\endcode */
+
+template <class Argument>
+class Callback
+{
+public:
+ Callback() : m_impl(0) {}
+
+ template <class Class>
+ Callback(Class *instance, void (Class::*memberFunc)(Argument)) :
+ m_impl(new Internal::CallbackMemberPtrImpl<Class,Argument>(instance, memberFunc))
+ {}
+
+ ~Callback()
+ {
+ clean();
+ }
+
+ Callback(const Callback &rhs) :
+ m_impl(0)
+ {
+ if (rhs.m_impl)
+ m_impl = rhs.m_impl->clone();
+ }
+
+ Callback &operator=(const Callback &rhs)
+ {
+ if (this != &rhs) {
+ clean();
+ if (rhs.m_impl)
+ m_impl = rhs.m_impl->clone();
+ }
+ return *this;
+ }
+
+ bool isNull() const { return m_impl == 0; }
+ operator bool() const { return !isNull(); }
+
+ void operator()(Argument a)
+ {
+ if (m_impl)
+ m_impl->invoke(a);
+ }
+
+private:
+ void clean()
+ {
+ if (m_impl) {
+ delete m_impl;
+ m_impl = 0;
+ }
+ }
+
+ Internal::CallbackImplBase<Argument> *m_impl;
+};
+
+} // namespace trk
+
+#endif // DEBUGGER_CALLBACK_H
diff --git a/src/runonphone/symbianutils/communicationstarter.cpp b/src/runonphone/symbianutils/communicationstarter.cpp
new file mode 100644
index 000000000..602786b61
--- /dev/null
+++ b/src/runonphone/symbianutils/communicationstarter.cpp
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "communicationstarter.h"
+#include "bluetoothlistener.h"
+#include "trkdevice.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QEventLoop>
+
+namespace trk {
+
+// --------------- AbstractBluetoothStarter
+struct BaseCommunicationStarterPrivate {
+ explicit BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d);
+
+ const BaseCommunicationStarter::TrkDevicePtr trkDevice;
+ BluetoothListener *listener;
+ QTimer *timer;
+ int intervalMS;
+ int attempts;
+ int n;
+ QString errorString;
+ BaseCommunicationStarter::State state;
+};
+
+BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d) :
+ trkDevice(d),
+ listener(0),
+ timer(0),
+ intervalMS(1000),
+ attempts(-1),
+ n(0),
+ state(BaseCommunicationStarter::TimedOut)
+{
+}
+
+BaseCommunicationStarter::BaseCommunicationStarter(const TrkDevicePtr &trkDevice, QObject *parent) :
+ QObject(parent),
+ d(new BaseCommunicationStarterPrivate(trkDevice))
+{
+}
+
+BaseCommunicationStarter::~BaseCommunicationStarter()
+{
+ stopTimer();
+ delete d;
+}
+
+void BaseCommunicationStarter::stopTimer()
+{
+ if (d->timer && d->timer->isActive())
+ d->timer->stop();
+}
+
+bool BaseCommunicationStarter::initializeStartupResources(QString *errorMessage)
+{
+ errorMessage->clear();
+ return true;
+}
+
+BaseCommunicationStarter::StartResult BaseCommunicationStarter::start()
+{
+ if (state() == Running) {
+ d->errorString = QLatin1String("Internal error, attempt to re-start BaseCommunicationStarter.\n");
+ return StartError;
+ }
+ // Before we instantiate timers, and such, try to open the device,
+ // which should succeed if another listener is already running in
+ // 'Watch' mode
+ if (d->trkDevice->open(&(d->errorString)))
+ return ConnectionSucceeded;
+ // Pull up resources for next attempt
+ d->n = 0;
+ if (!initializeStartupResources(&(d->errorString)))
+ return StartError;
+ // Start timer
+ if (!d->timer) {
+ d->timer = new QTimer;
+ connect(d->timer, SIGNAL(timeout()), this, SLOT(slotTimer()));
+ }
+ d->timer->setInterval(d->intervalMS);
+ d->timer->setSingleShot(false);
+ d->timer->start();
+ d->state = Running;
+ return Started;
+}
+
+BaseCommunicationStarter::State BaseCommunicationStarter::state() const
+{
+ return d->state;
+}
+
+int BaseCommunicationStarter::intervalMS() const
+{
+ return d->intervalMS;
+}
+
+void BaseCommunicationStarter::setIntervalMS(int i)
+{
+ d->intervalMS = i;
+ if (d->timer)
+ d->timer->setInterval(i);
+}
+
+int BaseCommunicationStarter::attempts() const
+{
+ return d->attempts;
+}
+
+void BaseCommunicationStarter::setAttempts(int a)
+{
+ d->attempts = a;
+}
+
+QString BaseCommunicationStarter::device() const
+{
+ return d->trkDevice->port();
+}
+
+QString BaseCommunicationStarter::errorString() const
+{
+ return d->errorString;
+}
+
+void BaseCommunicationStarter::slotTimer()
+{
+ ++d->n;
+ // Check for timeout
+ if (d->attempts >= 0 && d->n >= d->attempts) {
+ stopTimer();
+ d->errorString = tr("%1: timed out after %n attempts using an interval of %2ms.", 0, d->n)
+ .arg(d->trkDevice->port()).arg(d->intervalMS);
+ d->state = TimedOut;
+ emit timeout();
+ } else {
+ // Attempt n to connect?
+ if (d->trkDevice->open(&(d->errorString))) {
+ stopTimer();
+ const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->trkDevice->port()).arg(d->n);
+ emit message(msg);
+ d->state = Connected;
+ emit connected();
+ } else {
+ const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...")
+ .arg(d->trkDevice->port()).arg(d->n).arg(d->errorString);
+ emit message(msg);
+ }
+ }
+}
+
+// --------------- AbstractBluetoothStarter
+
+AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) :
+ BaseCommunicationStarter(trkDevice, parent)
+{
+}
+
+bool AbstractBluetoothStarter::initializeStartupResources(QString *errorMessage)
+{
+ // Create the listener and forward messages to it.
+ BluetoothListener *listener = createListener();
+ connect(this, SIGNAL(message(QString)), listener, SLOT(emitMessage(QString)));
+ return listener->start(device(), errorMessage);
+}
+
+// -------- ConsoleBluetoothStarter
+ConsoleBluetoothStarter::ConsoleBluetoothStarter(const TrkDevicePtr &trkDevice,
+ QObject *listenerParent,
+ QObject *parent) :
+AbstractBluetoothStarter(trkDevice, parent),
+m_listenerParent(listenerParent)
+{
+}
+
+BluetoothListener *ConsoleBluetoothStarter::createListener()
+{
+ BluetoothListener *rc = new BluetoothListener(m_listenerParent);
+ rc->setMode(BluetoothListener::Listen);
+ rc->setPrintConsoleMessages(true);
+ return rc;
+}
+
+bool ConsoleBluetoothStarter::startBluetooth(const TrkDevicePtr &trkDevice,
+ QObject *listenerParent,
+ int attempts,
+ QString *errorMessage)
+{
+ // Set up a console starter to print to stdout.
+ ConsoleBluetoothStarter starter(trkDevice, listenerParent);
+ starter.setAttempts(attempts);
+ switch (starter.start()) {
+ case Started:
+ break;
+ case ConnectionSucceeded:
+ return true;
+ case StartError:
+ *errorMessage = starter.errorString();
+ return false;
+ }
+ // Run the starter with an event loop. @ToDo: Implement
+ // some asynchronous keypress read to cancel.
+ QEventLoop eventLoop;
+ connect(&starter, SIGNAL(connected()), &eventLoop, SLOT(quit()));
+ connect(&starter, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
+ eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
+ if (starter.state() != AbstractBluetoothStarter::Connected) {
+ *errorMessage = starter.errorString();
+ return false;
+ }
+ return true;
+}
+} // namespace trk
diff --git a/src/runonphone/symbianutils/communicationstarter.h b/src/runonphone/symbianutils/communicationstarter.h
new file mode 100644
index 000000000..9fec5893c
--- /dev/null
+++ b/src/runonphone/symbianutils/communicationstarter.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMMUNICATIONSTARTER_H
+#define COMMUNICATIONSTARTER_H
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QSharedPointer>
+#include <QtCore/QObject>
+
+namespace trk {
+class TrkDevice;
+class BluetoothListener;
+struct BaseCommunicationStarterPrivate;
+
+/* BaseCommunicationStarter: A QObject that repeatedly tries to open a
+ * trk device until a connection succeeds or a timeout occurs (emitting
+ * signals), allowing to do something else in the foreground (local event loop
+ * [say QMessageBox] or some asynchronous operation). If the initial
+ * connection attempt in start() fails, the
+ * virtual initializeStartupResources() is called to initialize resources
+ * required to pull up the communication (namely Bluetooth listeners).
+ * The base class can be used as is to prompt the user to launch App TRK for a
+ * serial communication as this requires no further resource setup. */
+
+class SYMBIANUTILS_EXPORT BaseCommunicationStarter : public QObject {
+ Q_OBJECT
+ Q_DISABLE_COPY(BaseCommunicationStarter)
+public:
+ typedef QSharedPointer<TrkDevice> TrkDevicePtr;
+
+ enum State { Running, Connected, TimedOut };
+
+ explicit BaseCommunicationStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0);
+ virtual ~BaseCommunicationStarter();
+
+ int intervalMS() const;
+ void setIntervalMS(int i);
+
+ int attempts() const;
+ void setAttempts(int a);
+
+ QString device() const;
+
+ State state() const;
+ QString errorString() const;
+
+ enum StartResult {
+ Started, // Starter is now running.
+ ConnectionSucceeded, /* Initial connection attempt succeeded,
+ * no need to keep running. */
+ StartError // Error occurred during start.
+ };
+
+ StartResult start();
+
+signals:
+ void connected();
+ void timeout();
+ void message(const QString &);
+
+private slots:
+ void slotTimer();
+
+protected:
+ virtual bool initializeStartupResources(QString *errorMessage);
+
+private:
+ inline void stopTimer();
+
+ BaseCommunicationStarterPrivate *d;
+};
+
+/* AbstractBluetoothStarter: Repeatedly tries to open a trk Bluetooth
+ * device. Note that in case a Listener is already running mode, the
+ * connection will succeed immediately.
+ * initializeStartupResources() is implemented to fire up the listener.
+ * Introduces a new virtual createListener() that derived classes must
+ * implement as a factory function that creates and sets up the
+ * listener (mode, message connection, etc). */
+
+class SYMBIANUTILS_EXPORT AbstractBluetoothStarter : public BaseCommunicationStarter {
+ Q_OBJECT
+ Q_DISABLE_COPY(AbstractBluetoothStarter)
+public:
+
+protected:
+ explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0);
+
+ // Implemented to fire up the listener.
+ virtual bool initializeStartupResources(QString *errorMessage);
+ // New virtual: Overwrite to create and parametrize the listener.
+ virtual BluetoothListener *createListener() = 0;
+};
+
+/* ConsoleBluetoothStarter: Convenience class for console processes. Creates a
+ * listener in "Listen" mode with the messages redirected to standard output. */
+
+class SYMBIANUTILS_EXPORT ConsoleBluetoothStarter : public AbstractBluetoothStarter {
+ Q_OBJECT
+ Q_DISABLE_COPY(ConsoleBluetoothStarter)
+public:
+ static bool startBluetooth(const TrkDevicePtr& trkDevice,
+ QObject *listenerParent,
+ int attempts,
+ QString *errorMessage);
+
+protected:
+ virtual BluetoothListener *createListener();
+
+private:
+ explicit ConsoleBluetoothStarter(const TrkDevicePtr& trkDevice,
+ QObject *listenerParent,
+ QObject *parent = 0);
+
+ QObject *m_listenerParent;
+};
+
+} // namespace trk
+
+#endif // COMMUNICATIONSTARTER_H
diff --git a/src/runonphone/symbianutils/json.cpp b/src/runonphone/symbianutils/json.cpp
new file mode 100644
index 000000000..755df5e1d
--- /dev/null
+++ b/src/runonphone/symbianutils/json.cpp
@@ -0,0 +1,490 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "json.h"
+
+#ifdef TODO_USE_CREATOR
+#include <utils/qtcassert.h>
+#endif // TODO_USE_CREATOR
+
+#include <QtCore/QByteArray>
+#include <QtCore/QTextStream>
+#include <QtCore/QDebug>
+#include <QtCore/QStringList>
+
+#include <ctype.h>
+
+//#define DEBUG_JASON
+#ifdef DEBUG_JASON
+#define JDEBUG(s) qDebug() << s
+#else
+#define JDEBUG(s)
+#endif
+
+namespace tcftrk {
+
+static void skipSpaces(const char *&from, const char *to)
+{
+ while (from != to && isspace(*from))
+ ++from;
+}
+
+QTextStream &operator<<(QTextStream &os, const JsonValue &mi)
+{
+ return os << mi.toString();
+}
+
+void JsonValue::parsePair(const char *&from, const char *to)
+{
+ skipSpaces(from, to);
+ JDEBUG("parsePair: " << QByteArray(from, to - from));
+ m_name = parseCString(from, to);
+ skipSpaces(from, to);
+ while (from < to && *from != ':') {
+ JDEBUG("not a colon" << *from);
+ ++from;
+ }
+ ++from;
+ parseValue(from, to);
+ skipSpaces(from, to);
+}
+
+QByteArray JsonValue::parseNumber(const char *&from, const char *to)
+{
+ QByteArray result;
+ if (from < to && *from == '-') // Leading '-'.
+ result.append(*from++);
+ while (from < to && *from >= '0' && *from <= '9')
+ result.append(*from++);
+ return result;
+}
+
+QByteArray JsonValue::parseCString(const char *&from, const char *to)
+{
+ QByteArray result;
+ JDEBUG("parseCString: " << QByteArray(from, to - from));
+ if (*from != '"') {
+ qDebug() << "JSON Parse Error, double quote expected";
+ ++from; // So we don't hang
+ return QByteArray();
+ }
+ const char *ptr = from;
+ ++ptr;
+ while (ptr < to) {
+ if (*ptr == '"') {
+ ++ptr;
+ result = QByteArray(from + 1, ptr - from - 2);
+ break;
+ }
+ if (*ptr == '\\') {
+ ++ptr;
+ if (ptr == to) {
+ qDebug() << "JSON Parse Error, unterminated backslash escape";
+ from = ptr; // So we don't hang
+ return QByteArray();
+ }
+ }
+ ++ptr;
+ }
+ from = ptr;
+
+ int idx = result.indexOf('\\');
+ if (idx >= 0) {
+ char *dst = result.data() + idx;
+ const char *src = dst + 1, *end = result.data() + result.length();
+ do {
+ char c = *src++;
+ switch (c) {
+ case 'a': *dst++ = '\a'; break;
+ case 'b': *dst++ = '\b'; break;
+ case 'f': *dst++ = '\f'; break;
+ case 'n': *dst++ = '\n'; break;
+ case 'r': *dst++ = '\r'; break;
+ case 't': *dst++ = '\t'; break;
+ case 'v': *dst++ = '\v'; break;
+ case '"': *dst++ = '"'; break;
+ case '\\': *dst++ = '\\'; break;
+ default:
+ {
+ int chars = 0;
+ uchar prod = 0;
+ forever {
+ if (c < '0' || c > '7') {
+ --src;
+ break;
+ }
+ prod = prod * 8 + c - '0';
+ if (++chars == 3 || src == end)
+ break;
+ c = *src++;
+ }
+ if (!chars) {
+ qDebug() << "JSON Parse Error, unrecognized backslash escape";
+ return QByteArray();
+ }
+ *dst++ = prod;
+ }
+ }
+ while (src != end) {
+ char c = *src++;
+ if (c == '\\')
+ break;
+ *dst++ = c;
+ }
+ } while (src != end);
+ *dst = 0;
+ result.truncate(dst - result.data());
+ }
+
+ JDEBUG("parseCString, got " << result);
+ return result;
+}
+
+
+
+void JsonValue::parseValue(const char *&from, const char *to)
+{
+ JDEBUG("parseValue: " << QByteArray(from, to - from));
+ switch (*from) {
+ case '{':
+ parseObject(from, to);
+ break;
+ case 't':
+ if (to - from >= 4 && qstrncmp(from, "true", 4) == 0) {
+ m_data = QByteArray(from, 4);
+ from += m_data.size();
+ m_type = Boolean;
+ }
+ break;
+ case 'f':
+ if (to - from >= 5 && qstrncmp(from, "false", 5) == 0) {
+ m_data = QByteArray(from, 5);
+ from += m_data.size();
+ m_type = Boolean;
+ }
+ break;
+ case 'n':
+ if (to - from >= 4 && qstrncmp(from, "null", 4) == 0) {
+ m_data = QByteArray(from, 4);
+ from += m_data.size();
+ m_type = NullObject;
+ }
+ break;
+ case '[':
+ parseArray(from, to);
+ break;
+ case '"':
+ m_type = String;
+ m_data = parseCString(from, to);
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case '-':
+ m_type = Number;
+ m_data = parseNumber(from, to);
+ default:
+ break;
+ }
+}
+
+void JsonValue::parseObject(const char *&from, const char *to)
+{
+ JDEBUG("parseObject: " << QByteArray(from, to - from));
+#ifdef TODO_USE_CREATOR
+ QTC_ASSERT(*from == '{', /**/);
+#endif
+ ++from;
+ m_type = Object;
+ while (from < to) {
+ if (*from == '}') {
+ ++from;
+ break;
+ }
+ JsonValue child;
+ child.parsePair(from, to);
+ if (!child.isValid())
+ return;
+ m_children += child;
+ if (*from == ',')
+ ++from;
+ }
+}
+
+void JsonValue::parseArray(const char *&from, const char *to)
+{
+ JDEBUG("parseArray: " << QByteArray(from, to - from));
+#ifdef TODO_USE_CREATOR
+ QTC_ASSERT(*from == '[', /**/);
+#endif
+ ++from;
+ m_type = Array;
+ while (from < to) {
+ if (*from == ']') {
+ ++from;
+ break;
+ }
+ JsonValue child;
+ child.parseValue(from, to);
+ if (child.isValid())
+ m_children += child;
+ if (*from == ',')
+ ++from;
+ }
+}
+
+void JsonValue::setStreamOutput(const QByteArray &name, const QByteArray &content)
+{
+ if (content.isEmpty())
+ return;
+ JsonValue child;
+ child.m_type = String;
+ child.m_name = name;
+ child.m_data = content;
+ m_children += child;
+ if (m_type == Invalid)
+ m_type = Object;
+}
+
+static QByteArray ind(int indent)
+{
+ return QByteArray(2 * indent, ' ');
+}
+
+void JsonValue::dumpChildren(QByteArray * str, bool multiline, int indent) const
+{
+ for (int i = 0; i < m_children.size(); ++i) {
+ if (i != 0) {
+ *str += ',';
+ if (multiline)
+ *str += '\n';
+ }
+ if (multiline)
+ *str += ind(indent);
+ *str += m_children.at(i).toString(multiline, indent);
+ }
+}
+
+class MyString : public QString {
+public:
+ ushort at(int i) const { return constData()[i].unicode(); }
+};
+
+template<class ST, typename CT>
+inline ST escapeCStringTpl(const ST &ba)
+{
+ ST ret;
+ ret.reserve(ba.length() * 2);
+ for (int i = 0; i < ba.length(); ++i) {
+ CT c = ba.at(i);
+ switch (c) {
+ case '\\': ret += "\\\\"; break;
+ case '\a': ret += "\\a"; break;
+ case '\b': ret += "\\b"; break;
+ case '\f': ret += "\\f"; break;
+ case '\n': ret += "\\n"; break;
+ case '\r': ret += "\\r"; break;
+ case '\t': ret += "\\t"; break;
+ case '\v': ret += "\\v"; break;
+ case '"': ret += "\\\""; break;
+ default:
+ if (c < 32 || c == 127) {
+ ret += '\\';
+ ret += '0' + (c >> 6);
+ ret += '0' + ((c >> 3) & 7);
+ ret += '0' + (c & 7);
+ } else {
+ ret += c;
+ }
+ }
+ }
+ return ret;
+}
+
+QString JsonValue::escapeCString(const QString &ba)
+{
+ return escapeCStringTpl<MyString, ushort>(static_cast<const MyString &>(ba));
+}
+
+QByteArray JsonValue::escapeCString(const QByteArray &ba)
+{
+ return escapeCStringTpl<QByteArray, uchar>(ba);
+}
+
+QByteArray JsonValue::toString(bool multiline, int indent) const
+{
+ QByteArray result;
+ switch (m_type) {
+ case Invalid:
+ if (multiline)
+ result += ind(indent) + "Invalid\n";
+ else
+ result += "Invalid";
+ break;
+ case String:
+ if (!m_name.isEmpty())
+ result += m_name + "=";
+ result += '"' + escapeCString(m_data) + '"';
+ break;
+ case Number:
+ if (!m_name.isEmpty())
+ result += '"' + m_name + "\":";
+ result += m_data;
+ break;
+ case Boolean:
+ case NullObject:
+ if (!m_name.isEmpty())
+ result += '"' + m_name + "\":";
+ result += m_data;
+ break;
+ case Object:
+ if (!m_name.isEmpty())
+ result += m_name + '=';
+ if (multiline) {
+ result += "{\n";
+ dumpChildren(&result, multiline, indent + 1);
+ result += '\n' + ind(indent) + "}";
+ } else {
+ result += "{";
+ dumpChildren(&result, multiline, indent + 1);
+ result += "}";
+ }
+ break;
+ case Array:
+ if (!m_name.isEmpty())
+ result += m_name + "=";
+ if (multiline) {
+ result += "[\n";
+ dumpChildren(&result, multiline, indent + 1);
+ result += '\n' + ind(indent) + "]";
+ } else {
+ result += "[";
+ dumpChildren(&result, multiline, indent + 1);
+ result += "]";
+ }
+ break;
+ }
+ return result;
+}
+
+void JsonValue::fromString(const QByteArray &ba)
+{
+ const char *from = ba.constBegin();
+ const char *to = ba.constEnd();
+ parseValue(from, to);
+}
+
+JsonValue JsonValue::findChild(const char *name) const
+{
+ for (int i = 0; i < m_children.size(); ++i)
+ if (m_children.at(i).m_name == name)
+ return m_children.at(i);
+ return JsonValue();
+}
+
+void JsonInputStream::appendCString(const char *s)
+{
+ m_target.append('"');
+ for (const char *p = s; *p; p++) {
+ if (*p == '"' || *p == '\\')
+ m_target.append('\\');
+ m_target.append(*p);
+ }
+ m_target.append('"');
+}
+
+void JsonInputStream::appendString(const QString &in)
+{
+ if (in.isEmpty()) {
+ m_target.append("\"\"");
+ return;
+ }
+
+ const QChar doubleQuote('"');
+ const QChar backSlash('\\');
+ QString rc;
+ const int inSize = in.size();
+ rc.reserve(in.size() + 5);
+ rc.append(doubleQuote);
+ for (int i = 0; i < inSize; i++) {
+ const QChar c = in.at(i);
+ if (c == doubleQuote || c == backSlash)
+ rc.append(backSlash);
+ rc.append(c);
+ }
+ rc.append(doubleQuote);
+ m_target.append(rc.toUtf8());
+ return;
+}
+
+JsonInputStream &JsonInputStream::operator<<(const QStringList &in)
+{
+ m_target.append('[');
+ const int count = in.size();
+ for (int i = 0 ; i < count; i++) {
+ if (i)
+ m_target.append(',');
+ appendString(in.at(i));
+ }
+ m_target.append(']');
+ return *this;
+}
+
+JsonInputStream &JsonInputStream::operator<<(const QVector<QByteArray> &ba)
+{
+ m_target.append('[');
+ const int count = ba.size();
+ for (int i = 0 ; i < count; i++) {
+ if (i)
+ m_target.append(',');
+ appendCString(ba.at(i).constData());
+ }
+ m_target.append(']');
+ return *this;
+}
+
+JsonInputStream &JsonInputStream::operator<<(bool b)
+{
+ m_target.append(b ? "true" : "false");
+ return *this;
+}
+
+} // namespace tcftrk
+
diff --git a/src/runonphone/symbianutils/json.h b/src/runonphone/symbianutils/json.h
new file mode 100644
index 000000000..a9190f812
--- /dev/null
+++ b/src/runonphone/symbianutils/json.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SYMBIANUTILS_JSON_H
+#define SYMBIANUTILS_JSON_H
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+
+namespace tcftrk {
+
+class SYMBIANUTILS_EXPORT JsonValue
+{
+public:
+ JsonValue() : m_type(Invalid) {}
+ explicit JsonValue(const QByteArray &str) { fromString(str); }
+
+ QByteArray m_name;
+ QByteArray m_data;
+ QList<JsonValue> m_children;
+
+ enum Type {
+ Invalid,
+ String,
+ Number,
+ Boolean,
+ Object,
+ NullObject,
+ Array,
+ };
+
+ Type m_type;
+
+ inline Type type() const { return m_type; }
+ inline QByteArray name() const { return m_name; }
+ inline bool hasName(const char *name) const { return m_name == name; }
+
+ inline bool isValid() const { return m_type != Invalid; }
+ inline bool isNumber() const { return m_type == Number; }
+ inline bool isString() const { return m_type == String; }
+ inline bool isObject() const { return m_type == Object; }
+ inline bool isArray() const { return m_type == Array; }
+
+
+ inline QByteArray data() const { return m_data; }
+ inline const QList<JsonValue> &children() const { return m_children; }
+ inline int childCount() const { return m_children.size(); }
+
+ const JsonValue &childAt(int index) const { return m_children[index]; }
+ JsonValue &childAt(int index) { return m_children[index]; }
+ JsonValue findChild(const char *name) const;
+
+ QByteArray toString(bool multiline = false, int indent = 0) const;
+ void fromString(const QByteArray &str);
+ void setStreamOutput(const QByteArray &name, const QByteArray &content);
+
+private:
+ static QByteArray parseCString(const char *&from, const char *to);
+ static QByteArray parseNumber(const char *&from, const char *to);
+ static QByteArray escapeCString(const QByteArray &ba);
+ static QString escapeCString(const QString &ba);
+ void parsePair(const char *&from, const char *to);
+ void parseValue(const char *&from, const char *to);
+ void parseObject(const char *&from, const char *to);
+ void parseArray(const char *&from, const char *to);
+
+ void dumpChildren(QByteArray *str, bool multiline, int indent) const;
+};
+
+/* Thin wrapper around QByteArray for formatting JSON input. Use as in:
+ * JsonInputStream(byteArray) << '{' << "bla" << ':' << "blup" << '}';
+ * Note that strings get double quotes and JSON-escaping, characters should be
+ * used for the array/hash delimiters.
+ * */
+class SYMBIANUTILS_EXPORT JsonInputStream {
+public:
+ explicit JsonInputStream(QByteArray &a) : m_target(a) {}
+
+ JsonInputStream &operator<<(char c) { m_target.append(c); return *this; }
+ JsonInputStream &operator<<(const char *c) { appendCString(c); return *this; }
+ JsonInputStream &operator<<(const QByteArray &a) { appendCString(a.constData()); return *this; }
+ JsonInputStream &operator<<(const QString &c) { appendString(c); return *this; }
+
+ // Format as array
+ JsonInputStream &operator<<(const QStringList &c);
+
+ // Format as array
+ JsonInputStream &operator<<(const QVector<QByteArray> &ba);
+
+ JsonInputStream &operator<<(bool b);
+
+ JsonInputStream &operator<<(int i)
+ { m_target.append(QByteArray::number(i)); return *this; }
+ JsonInputStream &operator<<(unsigned i)
+ { m_target.append(QByteArray::number(i)); return *this; }
+ JsonInputStream &operator<<(quint64 i)
+ { m_target.append(QByteArray::number(i)); return *this; }
+
+private:
+ void appendString(const QString &);
+ void appendCString(const char *c);
+
+ QByteArray &m_target;
+};
+
+} // namespace tcftrk
+
+#endif // SYMBIANUTILS_JSON_H
diff --git a/src/runonphone/symbianutils/launcher.cpp b/src/runonphone/symbianutils/launcher.cpp
new file mode 100644
index 000000000..a5d3d68ae
--- /dev/null
+++ b/src/runonphone/symbianutils/launcher.cpp
@@ -0,0 +1,1036 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "launcher.h"
+#include "trkutils.h"
+#include "trkutils_p.h"
+#include "trkdevice.h"
+#include "bluetoothlistener.h"
+#include "symbiandevicemanager.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QDateTime>
+#include <QtCore/QVariant>
+#include <QtCore/QDebug>
+#include <QtCore/QQueue>
+#include <QtCore/QFile>
+#include <QtCore/QScopedPointer>
+
+#include <cstdio>
+
+namespace trk {
+
+struct CrashReportState {
+ CrashReportState();
+ void clear();
+
+ typedef uint Thread;
+ typedef QList<Thread> Threads;
+ Threads threads;
+
+ QList<uint> registers;
+ QByteArray stack;
+ uint sp;
+ uint fetchingStackPID;
+ uint fetchingStackTID;
+};
+
+CrashReportState::CrashReportState()
+{
+ clear();
+}
+
+void CrashReportState::clear()
+{
+ threads.clear();
+ stack.clear();
+ sp = fetchingStackPID = fetchingStackTID = 0;
+}
+
+struct LauncherPrivate {
+ struct CopyState {
+ QString sourceFileName;
+ QString destinationFileName;
+ uint copyFileHandle;
+ QScopedPointer<QByteArray> data;
+ qint64 position;
+ QScopedPointer<QFile> localFile;
+ };
+
+ explicit LauncherPrivate(const TrkDevicePtr &d);
+
+ TrkDevicePtr m_device;
+ QByteArray m_trkReadBuffer;
+ Launcher::State m_state;
+
+ void logMessage(const QString &msg);
+ // Debuggee state
+ Session m_session; // global-ish data (process id, target information)
+
+ CopyState m_copyState;
+ CopyState m_downloadState;
+ QString m_fileName;
+ QStringList m_commandLineArgs;
+ QString m_installFileName;
+ int m_verbose;
+ Launcher::Actions m_startupActions;
+ bool m_closeDevice;
+ CrashReportState m_crashReportState;
+};
+
+LauncherPrivate::LauncherPrivate(const TrkDevicePtr &d) :
+ m_device(d),
+ m_state(Launcher::Disconnected),
+ m_verbose(0),
+ m_closeDevice(true)
+{
+ if (m_device.isNull())
+ m_device = TrkDevicePtr(new TrkDevice);
+}
+
+Launcher::Launcher(Actions startupActions,
+ const TrkDevicePtr &dev,
+ QObject *parent) :
+ QObject(parent),
+ d(new LauncherPrivate(dev))
+{
+ d->m_startupActions = startupActions;
+ connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult)));
+}
+
+Launcher::~Launcher()
+{
+ // Destroyed before protocol was through: Close
+ if (d->m_closeDevice && d->m_device->isOpen())
+ d->m_device->close();
+ emit destroyed(d->m_device->port());
+ logMessage("Shutting down.\n");
+ delete d;
+}
+
+Launcher::State Launcher::state() const
+{
+ return d->m_state;
+}
+
+void Launcher::setState(State s)
+{
+ if (s != d->m_state) {
+ d->m_state = s;
+ emit stateChanged(s);
+ }
+}
+
+void Launcher::addStartupActions(trk::Launcher::Actions startupActions)
+{
+ d->m_startupActions = Actions(d->m_startupActions | startupActions);
+}
+
+void Launcher::setTrkServerName(const QString &name)
+{
+ d->m_device->setPort(name);
+}
+
+QString Launcher::trkServerName() const
+{
+ return d->m_device->port();
+}
+
+TrkDevicePtr Launcher::trkDevice() const
+{
+ return d->m_device;
+}
+
+void Launcher::setFileName(const QString &name)
+{
+ d->m_fileName = name;
+}
+
+void Launcher::setCopyFileName(const QString &srcName, const QString &dstName)
+{
+ d->m_copyState.sourceFileName = srcName;
+ d->m_copyState.destinationFileName = dstName;
+}
+
+void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName)
+{
+ d->m_downloadState.sourceFileName = srcName;
+ d->m_downloadState.destinationFileName = dstName;
+}
+
+void Launcher::setInstallFileName(const QString &name)
+{
+ d->m_installFileName = name;
+}
+
+void Launcher::setCommandLineArgs(const QStringList &args)
+{
+ d->m_commandLineArgs = args;
+}
+
+void Launcher::setSerialFrame(bool b)
+{
+ d->m_device->setSerialFrame(b);
+}
+
+bool Launcher::serialFrame() const
+{
+ return d->m_device->serialFrame();
+}
+
+
+bool Launcher::closeDevice() const
+{
+ return d->m_closeDevice;
+}
+
+void Launcher::setCloseDevice(bool c)
+{
+ d->m_closeDevice = c;
+}
+
+bool Launcher::startServer(QString *errorMessage)
+{
+ errorMessage->clear();
+ d->m_crashReportState.clear();
+ if (d->m_verbose) {
+ QString msg;
+ QTextStream str(&msg);
+ str.setIntegerBase(16);
+ str << "Actions=0x" << d->m_startupActions;
+ str.setIntegerBase(10);
+ str << " Port=" << trkServerName();
+ if (!d->m_fileName.isEmpty())
+ str << " Executable=" << d->m_fileName;
+ if (!d->m_commandLineArgs.isEmpty())
+ str << " Arguments= " << d->m_commandLineArgs.join(QString(QLatin1Char(' ')));
+ if (!d->m_copyState.sourceFileName.isEmpty())
+ str << " Package/Source=" << d->m_copyState.sourceFileName;
+ if (!d->m_copyState.destinationFileName.isEmpty())
+ str << " Remote Package/Destination=" << d->m_copyState.destinationFileName;
+ if (!d->m_downloadState.sourceFileName.isEmpty())
+ str << " Source=" << d->m_downloadState.sourceFileName;
+ if (!d->m_downloadState.destinationFileName.isEmpty())
+ str << " Destination=" << d->m_downloadState.destinationFileName;
+ if (!d->m_installFileName.isEmpty())
+ str << " Install file=" << d->m_installFileName;
+ logMessage(msg);
+ }
+ if (d->m_startupActions & ActionCopy) {
+ if (d->m_copyState.sourceFileName.isEmpty()) {
+ qWarning("No local filename given for copying package.");
+ return false;
+ } else if (d->m_copyState.destinationFileName.isEmpty()) {
+ qWarning("No remote filename given for copying package.");
+ return false;
+ }
+ }
+ if (d->m_startupActions & ActionInstall && d->m_installFileName.isEmpty()) {
+ qWarning("No package name given for installing.");
+ return false;
+ }
+ if (d->m_startupActions & ActionRun && d->m_fileName.isEmpty()) {
+ qWarning("No remote executable given for running.");
+ return false;
+ }
+ if (!d->m_device->isOpen() && !d->m_device->open(errorMessage))
+ return false;
+ setState(Connecting);
+ // Set up the temporary 'waiting' state if we do not get immediate connection
+ QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk()));
+ d->m_device->sendTrkInitialPing();
+ d->m_device->sendTrkMessage(TrkDisconnect); // Disconnect, as trk might be still connected
+ d->m_device->sendTrkMessage(TrkSupported, TrkCallback(this, &Launcher::handleSupportMask));
+ d->m_device->sendTrkMessage(TrkCpuType, TrkCallback(this, &Launcher::handleCpuType));
+ d->m_device->sendTrkMessage(TrkVersions, TrkCallback(this, &Launcher::handleTrkVersion));
+ if (d->m_startupActions != ActionPingOnly)
+ d->m_device->sendTrkMessage(TrkConnect, TrkCallback(this, &Launcher::handleConnect));
+ return true;
+}
+
+void Launcher::slotWaitingForTrk()
+{
+ // Set temporary state if we are still in connected state
+ if (state() == Connecting)
+ setState(WaitingForTrk);
+}
+
+void Launcher::handleConnect(const TrkResult &result)
+{
+ if (result.errorCode()) {
+ emit canNotConnect(result.errorString());
+ return;
+ }
+ setState(Connected);
+ if (d->m_startupActions & ActionCopy)
+ copyFileToRemote();
+ else if (d->m_startupActions & ActionInstall)
+ installRemotePackageSilently();
+ else if (d->m_startupActions & ActionRun)
+ startInferiorIfNeeded();
+ else if (d->m_startupActions & ActionDownload)
+ copyFileFromRemote();
+}
+
+void Launcher::setVerbose(int v)
+{
+ d->m_verbose = v;
+ d->m_device->setVerbose(v);
+}
+
+void Launcher::logMessage(const QString &msg)
+{
+ if (d->m_verbose)
+ qDebug() << "LAUNCHER: " << qPrintable(msg);
+}
+
+void Launcher::handleFinished()
+{
+ if (d->m_closeDevice)
+ d->m_device->close();
+ emit finished();
+}
+
+void Launcher::terminate()
+{
+ switch (state()) {
+ case DeviceDescriptionReceived:
+ case Connected:
+ if (d->m_session.pid) {
+ QByteArray ba;
+ appendShort(&ba, 0x0000, TargetByteOrder);
+ appendInt(&ba, d->m_session.pid, TargetByteOrder);
+ d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(this, &Launcher::handleRemoteProcessKilled), ba);
+ return;
+ }
+ if (d->m_copyState.copyFileHandle)
+ closeRemoteFile(true);
+ disconnectTrk();
+ break;
+ case Disconnected:
+ break;
+ case Connecting:
+ case WaitingForTrk:
+ setState(Disconnected);
+ handleFinished();
+ break;
+ }
+}
+
+void Launcher::handleRemoteProcessKilled(const TrkResult &result)
+{
+ Q_UNUSED(result)
+ disconnectTrk();
+}
+
+QString Launcher::msgStopped(uint pid, uint tid, uint address, const QString &why)
+{
+ return QString::fromLatin1("Process %1, thread %2 stopped at 0x%3: %4").
+ arg(pid).arg(tid).arg(address, 0, 16).
+ arg(why.isEmpty() ? QString::fromLatin1("<Unknown reason>") : why);
+}
+
+bool Launcher::parseNotifyStopped(const QByteArray &dataBA,
+ uint *pid, uint *tid, uint *address,
+ QString *why /* = 0 */)
+{
+ if (why)
+ why->clear();
+ *address = *pid = *tid = 0;
+ if (dataBA.size() < 12)
+ return false;
+ const char *data = dataBA.data();
+ *address = extractInt(data);
+ *pid = extractInt(data + 4);
+ *tid = extractInt(data + 8);
+ if (why && dataBA.size() >= 14) {
+ const unsigned short len = extractShort(data + 12);
+ if (len > 0)
+ *why = QString::fromLatin1(data + 14, len);
+ }
+ return true;
+}
+
+void Launcher::handleResult(const TrkResult &result)
+{
+ QByteArray prefix = "READ BUF: ";
+ QByteArray str = result.toString().toUtf8();
+ if (result.isDebugOutput) { // handle application output
+ QString msg;
+ if (result.multiplex == MuxTextTrace) {
+ if (result.data.length() > 8) {
+ quint64 timestamp = extractInt64(result.data) & 0x0FFFFFFFFFFFFFFFULL;
+ quint64 secs = timestamp / 1000000000;
+ quint64 ns = timestamp % 1000000000;
+ msg = QString("[%1.%2] %3").arg(secs).arg(ns).arg(QString(result.data.mid(8)));
+ logMessage("TEXT TRACE: " + msg);
+ }
+ } else {
+ logMessage("APPLICATION OUTPUT: " + stringFromArray(result.data));
+ msg = result.data;
+ }
+ msg.replace("\r\n", "\n");
+ if(!msg.endsWith('\n')) msg.append('\n');
+ emit applicationOutputReceived(msg);
+ return;
+ }
+ switch (result.code) {
+ case TrkNotifyAck:
+ break;
+ case TrkNotifyNak: { // NAK
+ logMessage(prefix + "NAK: " + str);
+ //logMessage(prefix << "TOKEN: " << result.token);
+ logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0)));
+ break;
+ }
+ case TrkNotifyStopped: { // Notified Stopped
+ QString reason;
+ uint pc;
+ uint pid;
+ uint tid;
+ parseNotifyStopped(result.data, &pid, &tid, &pc, &reason);
+ logMessage(prefix + msgStopped(pid, tid, pc, reason));
+ emit(processStopped(pc, pid, tid, reason));
+ d->m_device->sendTrkAck(result.token);
+ break;
+ }
+ case TrkNotifyException: { // Notify Exception (obsolete)
+ logMessage(prefix + "NOTE: EXCEPTION " + str);
+ d->m_device->sendTrkAck(result.token);
+ break;
+ }
+ case TrkNotifyInternalError: { //
+ logMessage(prefix + "NOTE: INTERNAL ERROR: " + str);
+ d->m_device->sendTrkAck(result.token);
+ break;
+ }
+
+ // target->host OS notification
+ case TrkNotifyCreated: { // Notify Created
+
+ if (result.data.size() < 10)
+ break;
+ const char *data = result.data.constData();
+ const byte error = result.data.at(0);
+ Q_UNUSED(error)
+ const byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2.
+ const uint tid = extractInt(data + 6); //threadID: 4 bytes
+ Q_UNUSED(tid)
+ if (type == kDSOSDLLItem && result.data.size() >=20) {
+ const Library lib = Library(result);
+ d->m_session.libraries.push_back(lib);
+ emit libraryLoaded(lib);
+ }
+ QByteArray ba;
+ ba.append(result.data.mid(2, 8));
+ d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
+ break;
+ }
+ case TrkNotifyDeleted: { // NotifyDeleted
+ const ushort itemType = (unsigned char)result.data.at(1);
+ const uint pid = result.data.size() >= 6 ? extractShort(result.data.constData() + 2) : 0;
+ const uint tid = result.data.size() >= 10 ? extractShort(result.data.constData() + 6) : 0;
+ Q_UNUSED(tid)
+ const ushort len = result.data.size() > 12 ? extractShort(result.data.constData() + 10) : ushort(0);
+ const QString name = len ? QString::fromAscii(result.data.mid(12, len)) : QString();
+ logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3").
+ arg(QString::fromAscii(prefix)).arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS")).
+ arg(name));
+ d->m_device->sendTrkAck(result.token);
+ if (itemType == kDSOSProcessItem // process
+ && result.data.size() >= 10
+ && d->m_session.pid == extractInt(result.data.data() + 6)) {
+ if (d->m_startupActions & ActionDownload)
+ copyFileFromRemote();
+ else
+ disconnectTrk();
+ }
+ else if (itemType == kDSOSDLLItem && len) {
+ // Remove libraries of process.
+ for (QList<Library>::iterator it = d->m_session.libraries.begin(); it != d->m_session.libraries.end(); ) {
+ if ((*it).pid == pid && (*it).name == name) {
+ emit libraryUnloaded(*it);
+ it = d->m_session.libraries.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+ break;
+ }
+ case TrkNotifyProcessorStarted: { // NotifyProcessorStarted
+ logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str);
+ d->m_device->sendTrkAck(result.token);
+ break;
+ }
+ case TrkNotifyProcessorStandBy: { // NotifyProcessorStandby
+ logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str);
+ d->m_device->sendTrkAck(result.token);
+ break;
+ }
+ case TrkNotifyProcessorReset: { // NotifyProcessorReset
+ logMessage(prefix + "NOTE: PROCESSOR RESET: " + str);
+ d->m_device->sendTrkAck(result.token);
+ break;
+ }
+ default: {
+ logMessage(prefix + "INVALID: " + str);
+ break;
+ }
+ }
+}
+
+QString Launcher::deviceDescription(unsigned verbose) const
+{
+ return d->m_session.deviceDescription(verbose);
+}
+
+void Launcher::handleTrkVersion(const TrkResult &result)
+{
+ if (result.errorCode() || result.data.size() < 5) {
+ if (d->m_startupActions == ActionPingOnly) {
+ setState(Disconnected);
+ handleFinished();
+ }
+ return;
+ }
+ d->m_session.trkAppVersion.trkMajor = result.data.at(1);
+ d->m_session.trkAppVersion.trkMinor = result.data.at(2);
+ d->m_session.trkAppVersion.protocolMajor = result.data.at(3);
+ d->m_session.trkAppVersion.protocolMinor = result.data.at(4);
+ setState(DeviceDescriptionReceived);
+ const QString msg = deviceDescription();
+ emit deviceDescriptionReceived(trkServerName(), msg);
+ // Ping mode: Log & Terminate
+ if (d->m_startupActions == ActionPingOnly) {
+ qWarning("%s", qPrintable(msg));
+ setState(Disconnected);
+ handleFinished();
+ }
+}
+
+static inline QString msgCannotOpenRemoteFile(const QString &fileName, const QString &message)
+{
+ return Launcher::tr("Cannot open remote file '%1': %2").arg(fileName, message);
+}
+
+static inline QString msgCannotOpenLocalFile(const QString &fileName, const QString &message)
+{
+ return Launcher::tr("Cannot open '%1': %2").arg(fileName, message);
+}
+
+void Launcher::handleFileCreation(const TrkResult &result)
+{
+ if (result.errorCode() || result.data.size() < 6) {
+ const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileName, result.errorString());
+ logMessage(msg);
+ emit canNotCreateFile(d->m_copyState.destinationFileName, msg);
+ disconnectTrk();
+ return;
+ }
+ const char *data = result.data.data();
+ d->m_copyState.copyFileHandle = extractInt(data + 2);
+ const QString localFileName = d->m_copyState.sourceFileName;
+ QFile file(localFileName);
+ d->m_copyState.position = 0;
+ if (!file.open(QIODevice::ReadOnly)) {
+ const QString msg = msgCannotOpenLocalFile(localFileName, file.errorString());
+ logMessage(msg);
+ emit canNotOpenLocalFile(localFileName, msg);
+ closeRemoteFile(true);
+ disconnectTrk();
+ return;
+ }
+ d->m_copyState.data.reset(new QByteArray(file.readAll()));
+ file.close();
+ continueCopying();
+}
+
+void Launcher::handleFileOpened(const TrkResult &result)
+{
+ if (result.errorCode() || result.data.size() < 6) {
+ const QString msg = msgCannotOpenRemoteFile(d->m_downloadState.sourceFileName, result.errorString());
+ logMessage(msg);
+ emit canNotOpenFile(d->m_downloadState.sourceFileName, msg);
+ disconnectTrk();
+ return;
+ }
+ d->m_downloadState.position = 0;
+ const QString localFileName = d->m_downloadState.destinationFileName;
+ bool opened = false;
+ if (localFileName == QLatin1String("-")) {
+ d->m_downloadState.localFile.reset(new QFile);
+ opened = d->m_downloadState.localFile->open(stdout, QFile::WriteOnly);
+ } else {
+ d->m_downloadState.localFile.reset(new QFile(localFileName));
+ opened = d->m_downloadState.localFile->open(QFile::WriteOnly | QFile::Truncate);
+ }
+ if (!opened) {
+ const QString msg = msgCannotOpenLocalFile(localFileName, d->m_downloadState.localFile->errorString());
+ logMessage(msg);
+ emit canNotOpenLocalFile(localFileName, msg);
+ closeRemoteFile(true);
+ disconnectTrk();
+ }
+ continueReading();
+}
+
+void Launcher::continueReading()
+{
+ QByteArray ba;
+ appendInt(&ba, d->m_downloadState.copyFileHandle, TargetByteOrder);
+ appendShort(&ba, 2048, TargetByteOrder);
+ d->m_device->sendTrkMessage(TrkReadFile, TrkCallback(this, &Launcher::handleRead), ba);
+}
+
+void Launcher::handleRead(const TrkResult &result)
+{
+ if (result.errorCode() || result.data.size() < 4) {
+ d->m_downloadState.localFile->close();
+ closeRemoteFile(true);
+ disconnectTrk();
+ } else {
+ int length = extractShort(result.data.data() + 2);
+ //TRK doesn't tell us the file length, so we need to keep reading until it returns 0 length
+ if (length > 0) {
+ d->m_downloadState.localFile->write(result.data.data() + 4, length);
+ continueReading();
+ } else {
+ closeRemoteFile(true);
+ disconnectTrk();
+ }
+ }
+}
+
+void Launcher::handleCopy(const TrkResult &result)
+{
+ if (result.errorCode() || result.data.size() < 4) {
+ closeRemoteFile(true);
+ emit canNotWriteFile(d->m_copyState.destinationFileName, result.errorString());
+ disconnectTrk();
+ } else {
+ continueCopying(extractShort(result.data.data() + 2));
+ }
+}
+
+void Launcher::continueCopying(uint lastCopiedBlockSize)
+{
+ qint64 size = d->m_copyState.data->length();
+ d->m_copyState.position += lastCopiedBlockSize;
+ if (size == 0)
+ emit copyProgress(100);
+ else {
+ const qint64 hundred = 100;
+ const qint64 percent = qMin( (d->m_copyState.position * hundred) / size, hundred);
+ emit copyProgress(static_cast<int>(percent));
+ }
+ if (d->m_copyState.position < size) {
+ QByteArray ba;
+ appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder);
+ appendString(&ba, d->m_copyState.data->mid(d->m_copyState.position, 2048), TargetByteOrder, false);
+ d->m_device->sendTrkMessage(TrkWriteFile, TrkCallback(this, &Launcher::handleCopy), ba);
+ } else {
+ closeRemoteFile();
+ }
+}
+
+void Launcher::closeRemoteFile(bool failed)
+{
+ QByteArray ba;
+ appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder);
+ appendDateTime(&ba, QDateTime::currentDateTime(), TargetByteOrder);
+ d->m_device->sendTrkMessage(TrkCloseFile,
+ failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied),
+ ba);
+ d->m_copyState.data.reset();
+ d->m_copyState.copyFileHandle = 0;
+ d->m_copyState.position = 0;
+}
+
+void Launcher::handleFileCopied(const TrkResult &result)
+{
+ if (result.errorCode())
+ emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString());
+ if (d->m_startupActions & ActionInstall)
+ installRemotePackageSilently();
+ else if (d->m_startupActions & ActionRun)
+ startInferiorIfNeeded();
+ else if (d->m_startupActions & ActionDownload)
+ copyFileFromRemote();
+ else
+ disconnectTrk();
+}
+
+void Launcher::handleCpuType(const TrkResult &result)
+{
+ logMessage("HANDLE CPU TYPE: " + result.toString());
+ if(result.errorCode() || result.data.size() < 7)
+ return;
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 03 00 04 00 00 04 00 00 00]
+ d->m_session.cpuMajor = result.data.at(1);
+ d->m_session.cpuMinor = result.data.at(2);
+ d->m_session.bigEndian = result.data.at(3);
+ d->m_session.defaultTypeSize = result.data.at(4);
+ d->m_session.fpTypeSize = result.data.at(5);
+ d->m_session.extended1TypeSize = result.data.at(6);
+ //d->m_session.extended2TypeSize = result.data[6];
+}
+
+void Launcher::handleCreateProcess(const TrkResult &result)
+{
+ if (result.errorCode()) {
+ emit canNotRun(result.errorString());
+ disconnectTrk();
+ return;
+ }
+ // 40 00 00]
+ //logMessage(" RESULT: " + result.toString());
+ // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00]
+ const char *data = result.data.data();
+ d->m_session.pid = extractInt(data + 1);
+ d->m_session.tid = extractInt(data + 5);
+ d->m_session.codeseg = extractInt(data + 9);
+ d->m_session.dataseg = extractInt(data + 13);
+ if (d->m_verbose) {
+ const QString msg = QString::fromLatin1("Process id: %1 Thread id: %2 code: 0x%3 data: 0x%4").
+ arg(d->m_session.pid).arg(d->m_session.tid).arg(d->m_session.codeseg, 0, 16).
+ arg(d->m_session.dataseg, 0 ,16);
+ logMessage(msg);
+ }
+ emit applicationRunning(d->m_session.pid);
+ //create a "library" entry for the executable which launched the process
+ Library lib;
+ lib.pid = d->m_session.pid;
+ lib.codeseg = d->m_session.codeseg;
+ lib.dataseg = d->m_session.dataseg;
+ lib.name = d->m_fileName.toUtf8();
+ d->m_session.libraries << lib;
+ emit libraryLoaded(lib);
+
+ QByteArray ba;
+ appendInt(&ba, d->m_session.pid);
+ appendInt(&ba, d->m_session.tid);
+ d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
+}
+
+void Launcher::handleWaitForFinished(const TrkResult &result)
+{
+ logMessage(" FINISHED: " + stringFromArray(result.data));
+ setState(Disconnected);
+ handleFinished();
+}
+
+void Launcher::handleSupportMask(const TrkResult &result)
+{
+ if (result.errorCode() || result.data.size() < 32)
+ return;
+ const char *data = result.data.data() + 1;
+
+ if (d->m_verbose > 1) {
+ QString str = QLatin1String("SUPPORTED: ");
+ for (int i = 0; i < 32; ++i) {
+ for (int j = 0; j < 8; ++j) {
+ if (data[i] & (1 << j)) {
+ str.append(QString::number(i * 8 + j, 16));
+ str.append(QLatin1Char(' '));
+ }
+ }
+ }
+ logMessage(str);
+ }
+}
+
+void Launcher::cleanUp()
+{
+ //
+ //---IDE------------------------------------------------------
+ // Command: 0x41 Delete Item
+ // Sub Cmd: Delete Process
+ //ProcessID: 0x0000071F (1823)
+ // [41 24 00 00 00 00 07 1F]
+ QByteArray ba(2, char(0));
+ appendInt(&ba, d->m_session.pid);
+ d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(), ba, "Delete process");
+
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 24 00]
+
+ //---IDE------------------------------------------------------
+ // Command: 0x1C Clear Break
+ // [1C 25 00 00 00 0A 78 6A 43 40]
+
+ //---TRK------------------------------------------------------
+ // Command: 0xA1 Notify Deleted
+ // [A1 09 00 00 00 00 00 00 00 00 07 1F]
+ //---IDE------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 09 00]
+
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 25 00]
+
+ //---IDE------------------------------------------------------
+ // Command: 0x1C Clear Break
+ // [1C 26 00 00 00 0B 78 6A 43 70]
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 26 00]
+
+
+ //---IDE------------------------------------------------------
+ // Command: 0x02 Disconnect
+ // [02 27]
+// sendTrkMessage(0x02, TrkCallback(this, &Launcher::handleDisconnect));
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+}
+
+void Launcher::disconnectTrk()
+{
+ d->m_device->sendTrkMessage(TrkDisconnect, TrkCallback(this, &Launcher::handleWaitForFinished));
+}
+
+void Launcher::copyFileToRemote()
+{
+ emit copyingStarted();
+ QByteArray ba;
+ ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary
+ appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false);
+ d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba);
+}
+
+void Launcher::copyFileFromRemote()
+{
+ emit copyingStarted();
+ QByteArray ba;
+ ba.append(char(9)); //kDSFileOpenRead | kDSFileOpenBinary
+ appendString(&ba, d->m_downloadState.sourceFileName.toLocal8Bit(), TargetByteOrder, false);
+ d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileOpened), ba);
+}
+
+void Launcher::installRemotePackageSilently()
+{
+ emit installingStarted();
+ QByteArray ba;
+ ba.append('C');
+ appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false);
+ d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba);
+}
+
+void Launcher::handleInstallPackageFinished(const TrkResult &result)
+{
+ if (result.errorCode()) {
+ emit canNotInstall(d->m_installFileName, result.errorString());
+ disconnectTrk();
+ return;
+ } else {
+ emit installingFinished();
+ }
+ if (d->m_startupActions & ActionRun) {
+ startInferiorIfNeeded();
+ } else if (d->m_startupActions & ActionDownload) {
+ copyFileFromRemote();
+ } else {
+ disconnectTrk();
+ }
+}
+
+QByteArray Launcher::startProcessMessage(const QString &executable,
+ const QStringList &arguments)
+{
+ // It's not started yet
+ QByteArray ba;
+ appendShort(&ba, 0, TargetByteOrder); // create new process (kDSOSProcessItem)
+ ba.append(char(0)); // options - currently unused
+ // One string consisting of binary terminated by '\0' and arguments terminated by '\0'
+ QByteArray commandLineBa = executable.toLocal8Bit();
+ commandLineBa.append(char(0));
+ if (!arguments.isEmpty())
+ commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit());
+ appendString(&ba, commandLineBa, TargetByteOrder, true);
+ return ba;
+}
+
+QByteArray Launcher::readMemoryMessage(uint pid, uint tid, uint from, uint len)
+{
+ QByteArray ba;
+ ba.reserve(11);
+ ba.append(char(0x8)); // Options, FIXME: why?
+ appendShort(&ba, len);
+ appendInt(&ba, from);
+ appendInt(&ba, pid);
+ appendInt(&ba, tid);
+ return ba;
+}
+
+QByteArray Launcher::readRegistersMessage(uint pid, uint tid)
+{
+ QByteArray ba;
+ ba.reserve(15);
+ ba.append(char(0)); // Register set, only 0 supported
+ appendShort(&ba, 0); //R0
+ appendShort(&ba, 16); // last register CPSR
+ appendInt(&ba, pid);
+ appendInt(&ba, tid);
+ return ba;
+}
+
+void Launcher::startInferiorIfNeeded()
+{
+ emit startingApplication();
+ if (d->m_session.pid != 0) {
+ logMessage("Process already 'started'");
+ return;
+ }
+ d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess),
+ startProcessMessage(d->m_fileName, d->m_commandLineArgs)); // Create Item
+}
+
+void Launcher::resumeProcess(uint pid, uint tid)
+{
+ QByteArray ba;
+ appendInt(&ba, pid, BigEndian);
+ appendInt(&ba, tid, BigEndian);
+ d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
+}
+
+// Acquire a device from SymbianDeviceManager, return 0 if not available.
+Launcher *Launcher::acquireFromDeviceManager(const QString &serverName,
+ QObject *parent,
+ QString *errorMessage)
+{
+ SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
+ const QSharedPointer<trk::TrkDevice> device = sdm->acquireDevice(serverName);
+ if (device.isNull()) {
+ *errorMessage = tr("Unable to acquire a device for port '%1'. It appears to be in use.").arg(serverName);
+ return 0;
+ }
+ // Wire release signal.
+ Launcher *rc = new Launcher(trk::Launcher::ActionPingOnly, device, parent);
+ connect(rc, SIGNAL(deviceDescriptionReceived(QString,QString)),
+ sdm, SLOT(setAdditionalInformation(QString,QString)));
+ connect(rc, SIGNAL(destroyed(QString)), sdm, SLOT(releaseDevice(QString)));
+ return rc;
+}
+
+// Preliminary release of device, disconnecting the signal.
+void Launcher::releaseToDeviceManager(Launcher *launcher)
+{
+ SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
+ // Disentangle launcher and its device, remove connection from destroyed
+ launcher->setCloseDevice(false);
+ TrkDevice *device = launcher->trkDevice().data();
+ launcher->disconnect(device);
+ device->disconnect(launcher);
+ launcher->disconnect(sdm);
+ sdm->releaseDevice(launcher->trkServerName());
+}
+
+void Launcher::getRegistersAndCallStack(uint pid, uint tid)
+{
+ d->m_device->sendTrkMessage(TrkReadRegisters,
+ TrkCallback(this, &Launcher::handleReadRegisters),
+ Launcher::readRegistersMessage(pid, tid));
+ d->m_crashReportState.fetchingStackPID = pid;
+ d->m_crashReportState.fetchingStackTID = tid;
+}
+
+void Launcher::handleReadRegisters(const TrkResult &result)
+{
+ if(result.errorCode() || result.data.size() < (17*4)) {
+ terminate();
+ return;
+ }
+ const char* data = result.data.constData() + 1;
+ d->m_crashReportState.registers.clear();
+ d->m_crashReportState.stack.clear();
+ for (int i=0;i<17;i++) {
+ uint r = extractInt(data);
+ data += 4;
+ d->m_crashReportState.registers.append(r);
+ }
+ d->m_crashReportState.sp = d->m_crashReportState.registers.at(13);
+
+ const ushort len = 1024 - (d->m_crashReportState.sp % 1024); //read to 1k boundary first
+ const QByteArray ba = Launcher::readMemoryMessage(d->m_crashReportState.fetchingStackPID,
+ d->m_crashReportState.fetchingStackTID,
+ d->m_crashReportState.sp,
+ len);
+ d->m_device->sendTrkMessage(TrkReadMemory, TrkCallback(this, &Launcher::handleReadStack), ba);
+ d->m_crashReportState.sp += len;
+}
+
+void Launcher::handleReadStack(const TrkResult &result)
+{
+ if (result.errorCode()) {
+ //error implies memory fault when reaching end of stack
+ emit registersAndCallStackReadComplete(d->m_crashReportState.registers, d->m_crashReportState.stack);
+ return;
+ }
+
+ const uint len = extractShort(result.data.constData() + 1);
+ d->m_crashReportState.stack.append(result.data.mid(3, len));
+
+ if (d->m_crashReportState.sp - d->m_crashReportState.registers.at(13) > 0x10000) {
+ //read enough stack, stop here
+ emit registersAndCallStackReadComplete(d->m_crashReportState.registers, d->m_crashReportState.stack);
+ return;
+ }
+ //read 1k more
+ const QByteArray ba = Launcher::readMemoryMessage(d->m_crashReportState.fetchingStackPID,
+ d->m_crashReportState.fetchingStackTID,
+ d->m_crashReportState.sp,
+ 1024);
+ d->m_device->sendTrkMessage(TrkReadMemory, TrkCallback(this, &Launcher::handleReadStack), ba);
+ d->m_crashReportState.sp += 1024;
+}
+
+} // namespace trk
diff --git a/src/runonphone/symbianutils/launcher.h b/src/runonphone/symbianutils/launcher.h
new file mode 100644
index 000000000..fac65b569
--- /dev/null
+++ b/src/runonphone/symbianutils/launcher.h
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LAUNCHER_H
+#define LAUNCHER_H
+
+#include "trkdevice.h"
+#include "trkutils.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+#include <QtCore/QSharedPointer>
+
+namespace trk {
+
+struct TrkResult;
+struct TrkMessage;
+struct LauncherPrivate;
+
+typedef QSharedPointer<TrkDevice> TrkDevicePtr;
+
+class SYMBIANUTILS_EXPORT Launcher : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(Launcher)
+public:
+ typedef void (Launcher::*TrkCallBack)(const TrkResult &);
+
+ enum Actions {
+ ActionPingOnly = 0x0,
+ ActionCopy = 0x1,
+ ActionInstall = 0x2,
+ ActionCopyInstall = ActionCopy | ActionInstall,
+ ActionRun = 0x4,
+ ActionDownload = 0x8,
+ ActionCopyRun = ActionCopy | ActionRun,
+ ActionInstallRun = ActionInstall | ActionRun,
+ ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun
+ };
+
+ enum State { Disconnected, Connecting, Connected,
+ WaitingForTrk, // This occurs only if the initial ping times out after
+ // a reasonable timeout, indicating that Trk is not
+ // running. Note that this will never happen with
+ // Bluetooth as communication immediately starts
+ // after connecting.
+ DeviceDescriptionReceived };
+
+ explicit Launcher(trk::Launcher::Actions startupActions = trk::Launcher::ActionPingOnly,
+ const TrkDevicePtr &trkDevice = TrkDevicePtr(),
+ QObject *parent = 0);
+ ~Launcher();
+
+ State state() const;
+
+ void addStartupActions(trk::Launcher::Actions startupActions);
+ void setTrkServerName(const QString &name);
+ QString trkServerName() const;
+ void setFileName(const QString &name);
+ void setCopyFileName(const QString &srcName, const QString &dstName);
+ void setDownloadFileName(const QString &srcName, const QString &dstName);
+ void setInstallFileName(const QString &name);
+ void setCommandLineArgs(const QStringList &args);
+ bool startServer(QString *errorMessage);
+ void setVerbose(int v);
+ void setSerialFrame(bool b);
+ bool serialFrame() const;
+ // Close device or leave it open
+ bool closeDevice() const;
+ void setCloseDevice(bool c);
+
+ TrkDevicePtr trkDevice() const;
+
+ // becomes valid after successful execution of ActionPingOnly
+ QString deviceDescription(unsigned verbose = 0u) const;
+
+ // Acquire a device from SymbianDeviceManager, return 0 if not available.
+ // The device will be released on destruction.
+ static Launcher *acquireFromDeviceManager(const QString &serverName,
+ QObject *parent,
+ QString *errorMessage);
+ // Preliminary release of device, disconnecting the signal.
+ static void releaseToDeviceManager(Launcher *l);
+
+ // Create Trk message to start a process.
+ static QByteArray startProcessMessage(const QString &executable,
+ const QStringList &arguments);
+ // Create Trk message to read memory
+ static QByteArray readMemoryMessage(uint pid, uint tid, uint from, uint len);
+ static QByteArray readRegistersMessage(uint pid, uint tid);
+ // Parse a TrkNotifyStopped message
+ static bool parseNotifyStopped(const QByteArray &a,
+ uint *pid, uint *tid, uint *address,
+ QString *why = 0);
+ // Helper message
+ static QString msgStopped(uint pid, uint tid, uint address, const QString &why);
+
+signals:
+ void deviceDescriptionReceived(const QString &port, const QString &description);
+ void copyingStarted();
+ void canNotConnect(const QString &errorMessage);
+ void canNotCreateFile(const QString &filename, const QString &errorMessage);
+ void canNotOpenFile(const QString &filename, const QString &errorMessage);
+ void canNotOpenLocalFile(const QString &filename, const QString &errorMessage);
+ void canNotWriteFile(const QString &filename, const QString &errorMessage);
+ void canNotCloseFile(const QString &filename, const QString &errorMessage);
+ void installingStarted();
+ void canNotInstall(const QString &packageFilename, const QString &errorMessage);
+ void installingFinished();
+ void startingApplication();
+ void applicationRunning(uint pid);
+ void canNotRun(const QString &errorMessage);
+ void finished();
+ void applicationOutputReceived(const QString &output);
+ void copyProgress(int percent);
+ void stateChanged(int);
+ void processStopped(uint pc, uint pid, uint tid, const QString& reason);
+ void processResumed(uint pid, uint tid);
+ void libraryLoaded(const trk::Library &lib);
+ void libraryUnloaded(const trk::Library &lib);
+ void registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack);
+ // Emitted by the destructor, for releasing devices of SymbianDeviceManager by name
+ void destroyed(const QString &serverName);
+
+public slots:
+ void terminate();
+ void resumeProcess(uint pid, uint tid);
+ //can be used to obtain traceback after a breakpoint / exception
+ void getRegistersAndCallStack(uint pid, uint tid);
+
+private slots:
+ void handleResult(const trk::TrkResult &data);
+ void slotWaitingForTrk();
+
+private:
+ // kill process and breakpoints
+ void cleanUp();
+ void disconnectTrk();
+
+ void handleRemoteProcessKilled(const TrkResult &result);
+ void handleConnect(const TrkResult &result);
+ void handleFileCreation(const TrkResult &result);
+ void handleFileOpened(const TrkResult &result);
+ void handleCopy(const TrkResult &result);
+ void handleRead(const TrkResult &result);
+ void continueCopying(uint lastCopiedBlockSize = 0);
+ void continueReading();
+ void closeRemoteFile(bool failed = false);
+ void handleFileCopied(const TrkResult &result);
+ void handleInstallPackageFinished(const TrkResult &result);
+ void handleCpuType(const TrkResult &result);
+ void handleCreateProcess(const TrkResult &result);
+ void handleWaitForFinished(const TrkResult &result);
+ void handleStop(const TrkResult &result);
+ void handleSupportMask(const TrkResult &result);
+ void handleTrkVersion(const TrkResult &result);
+ void handleReadRegisters(const TrkResult &result);
+ void handleReadStack(const TrkResult &result);
+
+ void copyFileToRemote();
+ void copyFileFromRemote();
+ void installRemotePackageSilently();
+ void startInferiorIfNeeded();
+ void handleFinished();
+
+ void logMessage(const QString &msg);
+ void setState(State s);
+
+ LauncherPrivate *d;
+};
+
+} // namespace Trk
+
+#endif // LAUNCHER_H
diff --git a/src/runonphone/symbianutils/symbiandevicemanager.cpp b/src/runonphone/symbianutils/symbiandevicemanager.cpp
new file mode 100644
index 000000000..8d65d182c
--- /dev/null
+++ b/src/runonphone/symbianutils/symbiandevicemanager.cpp
@@ -0,0 +1,489 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "symbiandevicemanager.h"
+#include "trkdevice.h"
+
+#include <QtCore/QSettings>
+#include <QtCore/QStringList>
+#include <QtCore/QFileInfo>
+#include <QtCore/QtDebug>
+#include <QtCore/QTextStream>
+#include <QtCore/QSharedData>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QSignalMapper>
+
+namespace SymbianUtils {
+
+enum { debug = 0 };
+
+static const char REGKEY_CURRENT_CONTROL_SET[] = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet";
+static const char USBSER[] = "Services/usbser/Enum";
+
+const char *SymbianDeviceManager::linuxBlueToothDeviceRootC = "/dev/rfcomm";
+
+// ------------- SymbianDevice
+class SymbianDeviceData : public QSharedData {
+public:
+ SymbianDeviceData();
+ ~SymbianDeviceData();
+
+ inline bool isOpen() const { return !device.isNull() && device->isOpen(); }
+ void forcedClose();
+
+ QString portName;
+ QString friendlyName;
+ QString deviceDesc;
+ QString manufacturer;
+ QString additionalInformation;
+
+ DeviceCommunicationType type;
+ QSharedPointer<trk::TrkDevice> device;
+ bool deviceAcquired;
+};
+
+SymbianDeviceData::SymbianDeviceData() :
+ type(SerialPortCommunication),
+ deviceAcquired(false)
+{
+}
+
+SymbianDeviceData::~SymbianDeviceData()
+{
+ forcedClose();
+}
+
+void SymbianDeviceData::forcedClose()
+{
+ // Close the device when unplugging. Should devices be in 'acquired' state,
+ // their owners should hit on write failures.
+ // Apart from the <shared item> destructor, also called by the devicemanager
+ // to ensure it also happens if other shared instances are still around.
+ if (isOpen()) {
+ if (deviceAcquired)
+ qWarning("Device on '%s' unplugged while an operation is in progress.",
+ qPrintable(portName));
+ device->close();
+ }
+}
+
+SymbianDevice::SymbianDevice(SymbianDeviceData *data) :
+ m_data(data)
+{
+}
+
+SymbianDevice::SymbianDevice() :
+ m_data(new SymbianDeviceData)
+{
+}
+SymbianDevice::SymbianDevice(const SymbianDevice &rhs) :
+ m_data(rhs.m_data)
+{
+}
+
+SymbianDevice &SymbianDevice::operator=(const SymbianDevice &rhs)
+{
+ if (this != &rhs)
+ m_data = rhs.m_data;
+ return *this;
+}
+
+SymbianDevice::~SymbianDevice()
+{
+}
+
+void SymbianDevice::forcedClose()
+{
+ m_data->forcedClose();
+}
+
+QString SymbianDevice::portName() const
+{
+ return m_data->portName;
+}
+
+QString SymbianDevice::friendlyName() const
+{
+ return m_data->friendlyName;
+}
+
+QString SymbianDevice::additionalInformation() const
+{
+ return m_data->additionalInformation;
+}
+
+void SymbianDevice::setAdditionalInformation(const QString &a)
+{
+ m_data->additionalInformation = a;
+}
+
+SymbianDevice::TrkDevicePtr SymbianDevice::acquireDevice()
+{
+ if (debug)
+ qDebug() << "SymbianDevice::acquireDevice" << m_data->portName
+ << "acquired: " << m_data->deviceAcquired << " open: " << isOpen();
+ if (isNull() || m_data->deviceAcquired)
+ return TrkDevicePtr();
+ if (m_data->device.isNull()) {
+ m_data->device = TrkDevicePtr(new trk::TrkDevice);
+ m_data->device->setPort(m_data->portName);
+ m_data->device->setSerialFrame(m_data->type == SerialPortCommunication);
+ }
+ m_data->deviceAcquired = true;
+ return m_data->device;
+}
+
+void SymbianDevice::releaseDevice(TrkDevicePtr *ptr /* = 0 */)
+{
+ if (debug)
+ qDebug() << "SymbianDevice::releaseDevice" << m_data->portName
+ << " open: " << isOpen();
+ if (m_data->deviceAcquired) {
+ if (m_data->device->isOpen())
+ m_data->device->clearWriteQueue();
+ // Release if a valid pointer was passed in.
+ if (ptr && !ptr->isNull()) {
+ ptr->data()->disconnect();
+ *ptr = TrkDevicePtr();
+ }
+ m_data->deviceAcquired = false;
+ } else {
+ qWarning("Internal error: Attempt to release device that is not acquired.");
+ }
+}
+
+QString SymbianDevice::deviceDesc() const
+{
+ return m_data->deviceDesc;
+}
+
+QString SymbianDevice::manufacturer() const
+{
+ return m_data->manufacturer;
+}
+
+DeviceCommunicationType SymbianDevice::type() const
+{
+ return m_data->type;
+}
+
+bool SymbianDevice::isNull() const
+{
+ return m_data->portName.isEmpty();
+}
+
+bool SymbianDevice::isOpen() const
+{
+ return m_data->isOpen();
+}
+
+QString SymbianDevice::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ format(str);
+ return rc;
+}
+
+void SymbianDevice::format(QTextStream &str) const
+{
+ str << (m_data->type == BlueToothCommunication ? "Bluetooth: " : "Serial: ")
+ << m_data->portName;
+ if (!m_data->friendlyName.isEmpty()) {
+ str << " (" << m_data->friendlyName;
+ if (!m_data->deviceDesc.isEmpty())
+ str << " / " << m_data->deviceDesc;
+ str << ')';
+ }
+ if (!m_data->manufacturer.isEmpty())
+ str << " [" << m_data->manufacturer << ']';
+}
+
+// Compare by port and friendly name
+int SymbianDevice::compare(const SymbianDevice &rhs) const
+{
+ if (const int prc = m_data->portName.compare(rhs.m_data->portName))
+ return prc;
+ if (const int frc = m_data->friendlyName.compare(rhs.m_data->friendlyName))
+ return frc;
+ return 0;
+}
+
+SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &cd)
+{
+ d.nospace() << cd.toString();
+ return d;
+}
+
+// ------------- SymbianDeviceManagerPrivate
+struct SymbianDeviceManagerPrivate {
+ SymbianDeviceManagerPrivate() : m_initialized(false), m_destroyReleaseMapper(0) {}
+
+ bool m_initialized;
+ SymbianDeviceManager::SymbianDeviceList m_devices;
+ QSignalMapper *m_destroyReleaseMapper;
+};
+
+SymbianDeviceManager::SymbianDeviceManager(QObject *parent) :
+ QObject(parent),
+ d(new SymbianDeviceManagerPrivate)
+{
+}
+
+SymbianDeviceManager::~SymbianDeviceManager()
+{
+ delete d;
+}
+
+SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::devices() const
+{
+ ensureInitialized();
+ return d->m_devices;
+}
+
+QString SymbianDeviceManager::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << d->m_devices.size() << " devices:\n";
+ const int count = d->m_devices.size();
+ for (int i = 0; i < count; i++) {
+ str << '#' << i << ' ';
+ d->m_devices.at(i).format(str);
+ str << '\n';
+ }
+ return rc;
+}
+
+int SymbianDeviceManager::findByPortName(const QString &p) const
+{
+ ensureInitialized();
+ const int count = d->m_devices.size();
+ for (int i = 0; i < count; i++)
+ if (d->m_devices.at(i).portName() == p)
+ return i;
+ return -1;
+}
+
+QString SymbianDeviceManager::friendlyNameForPort(const QString &port) const
+{
+ const int idx = findByPortName(port);
+ return idx == -1 ? QString() : d->m_devices.at(idx).friendlyName();
+}
+
+SymbianDeviceManager::TrkDevicePtr
+ SymbianDeviceManager::acquireDevice(const QString &port)
+{
+ ensureInitialized();
+ const int idx = findByPortName(port);
+ if (idx == -1) {
+ qWarning("Attempt to acquire device '%s' that does not exist.", qPrintable(port));
+ if (debug)
+ qDebug() << *this;
+ return TrkDevicePtr();
+ }
+ const TrkDevicePtr rc = d->m_devices[idx].acquireDevice();
+ if (debug)
+ qDebug() << "SymbianDeviceManager::acquireDevice" << port << " returns " << !rc.isNull();
+ return rc;
+}
+
+void SymbianDeviceManager::update()
+{
+ update(true);
+}
+
+void SymbianDeviceManager::releaseDevice(const QString &port)
+{
+ const int idx = findByPortName(port);
+ if (debug)
+ qDebug() << "SymbianDeviceManager::releaseDevice" << port << idx << sender();
+ if (idx != -1) {
+ d->m_devices[idx].releaseDevice();
+ } else {
+ qWarning("Attempt to release non-existing device %s.", qPrintable(port));
+ }
+}
+
+void SymbianDeviceManager::setAdditionalInformation(const QString &port, const QString &ai)
+{
+ const int idx = findByPortName(port);
+ if (idx != -1)
+ d->m_devices[idx].setAdditionalInformation(ai);
+}
+
+void SymbianDeviceManager::ensureInitialized() const
+{
+ if (!d->m_initialized) // Flag is set in update()
+ const_cast<SymbianDeviceManager*>(this)->update(false);
+}
+
+void SymbianDeviceManager::update(bool emitSignals)
+{
+ static int n = 0;
+ typedef SymbianDeviceList::iterator SymbianDeviceListIterator;
+
+ if (debug)
+ qDebug(">SerialDeviceLister::update(#%d, signals=%d)\n%s", n++, int(emitSignals),
+ qPrintable(toString()));
+
+ d->m_initialized = true;
+ // Get ordered new list
+ SymbianDeviceList newDevices = serialPorts() + blueToothDevices();
+ if (newDevices.size() > 1)
+ qStableSort(newDevices.begin(), newDevices.end());
+ if (d->m_devices == newDevices) { // Happy, nothing changed.
+ if (debug)
+ qDebug("<SerialDeviceLister::update: unchanged\n");
+ return;
+ }
+ // Merge the lists and emit the respective added/removed signals, assuming
+ // no one can plug a different device on the same port at the speed of lightning
+ if (!d->m_devices.isEmpty()) {
+ // Find deleted devices
+ for (SymbianDeviceListIterator oldIt = d->m_devices.begin(); oldIt != d->m_devices.end(); ) {
+ if (newDevices.contains(*oldIt)) {
+ ++oldIt;
+ } else {
+ SymbianDevice toBeDeleted = *oldIt;
+ toBeDeleted.forcedClose();
+ oldIt = d->m_devices.erase(oldIt);
+ if (emitSignals)
+ emit deviceRemoved(toBeDeleted);
+ }
+ }
+ }
+ if (!newDevices.isEmpty()) {
+ // Find new devices and insert in order
+ foreach(const SymbianDevice &newDevice, newDevices) {
+ if (!d->m_devices.contains(newDevice)) {
+ d->m_devices.append(newDevice);
+ if (emitSignals)
+ emit deviceAdded(newDevice);
+ }
+ }
+ if (d->m_devices.size() > 1)
+ qStableSort(d->m_devices.begin(), d->m_devices.end());
+ }
+ if (emitSignals)
+ emit updated();
+
+ if (debug)
+ qDebug("<SerialDeviceLister::update\n%s\n", qPrintable(toString()));
+}
+
+SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::serialPorts() const
+{
+ SymbianDeviceList rc;
+#ifdef Q_OS_WIN
+ const QSettings registry(REGKEY_CURRENT_CONTROL_SET, QSettings::NativeFormat);
+ const QString usbSerialRootKey = QLatin1String(USBSER) + QLatin1Char('/');
+ const int count = registry.value(usbSerialRootKey + QLatin1String("Count")).toInt();
+ for (int i = 0; i < count; ++i) {
+ QString driver = registry.value(usbSerialRootKey + QString::number(i)).toString();
+ if (driver.contains(QLatin1String("JAVACOMM"))) {
+ driver.replace(QLatin1Char('\\'), QLatin1Char('/'));
+ const QString driverRootKey = QLatin1String("Enum/") + driver + QLatin1Char('/');
+ if (debug > 1)
+ qDebug() << "SerialDeviceLister::serialPorts(): Checking " << i << count
+ << REGKEY_CURRENT_CONTROL_SET << usbSerialRootKey << driverRootKey;
+ QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData);
+ device->type = SerialPortCommunication;
+ device->friendlyName = registry.value(driverRootKey + QLatin1String("FriendlyName")).toString();
+ device->portName = registry.value(driverRootKey + QLatin1String("Device Parameters/PortName")).toString();
+ device->deviceDesc = registry.value(driverRootKey + QLatin1String("DeviceDesc")).toString();
+ device->manufacturer = registry.value(driverRootKey + QLatin1String("Mfg")).toString();
+ rc.append(SymbianDevice(device.take()));
+ }
+ }
+#endif
+ return rc;
+}
+
+SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices() const
+{
+ SymbianDeviceList rc;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
+ // Bluetooth devices are created on connection. List the existing ones
+ // or at least the first one.
+ const QString prefix = QLatin1String(linuxBlueToothDeviceRootC);
+ const QString blueToothfriendlyFormat = QLatin1String("Bluetooth device (%1)");
+ for (int d = 0; d < 4; d++) {
+ QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData);
+ device->type = BlueToothCommunication;
+ device->portName = prefix + QString::number(d);
+ if (d == 0 || QFileInfo(device->portName).exists()) {
+ device->friendlyName = blueToothfriendlyFormat.arg(device->portName);
+ rc.push_back(SymbianDevice(device.take()));
+ }
+ }
+ // New kernel versions support /dev/ttyUSB0, /dev/ttyUSB1. Trk responds
+ // on the latter (usually), try first.
+ static const char *usbTtyDevices[] = { "/dev/ttyUSB1", "/dev/ttyUSB0" };
+ const int usbTtyCount = sizeof(usbTtyDevices)/sizeof(const char *);
+ for (int d = 0; d < usbTtyCount; d++) {
+ const QString ttyUSBDevice = QLatin1String(usbTtyDevices[d]);
+ if (QFileInfo(ttyUSBDevice).exists()) {
+ SymbianDeviceData *device = new SymbianDeviceData;
+ device->type = SerialPortCommunication;
+ device->portName = ttyUSBDevice;
+ device->friendlyName = QString::fromLatin1("USB/Serial device (%1)").arg(device->portName);
+ rc.push_back(SymbianDevice(device));
+ }
+ }
+#endif
+ return rc;
+}
+
+Q_GLOBAL_STATIC(SymbianDeviceManager, symbianDeviceManager)
+
+SymbianDeviceManager *SymbianDeviceManager::instance()
+{
+ return symbianDeviceManager();
+}
+
+SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm)
+{
+ d.nospace() << sdm.toString();
+ return d;
+}
+
+} // namespace SymbianUtilsInternal
diff --git a/src/runonphone/symbianutils/symbiandevicemanager.h b/src/runonphone/symbianutils/symbiandevicemanager.h
new file mode 100644
index 000000000..b4edd7884
--- /dev/null
+++ b/src/runonphone/symbianutils/symbiandevicemanager.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SYMBIANDEVICEMANAGER_H
+#define SYMBIANDEVICEMANAGER_H
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+class QDebug;
+class QTextStream;
+QT_END_NAMESPACE
+
+namespace trk {
+ class TrkDevice;
+}
+
+namespace SymbianUtils {
+
+struct SymbianDeviceManagerPrivate;
+class SymbianDeviceData;
+
+enum DeviceCommunicationType {
+ SerialPortCommunication = 0,
+ BlueToothCommunication = 1
+};
+
+// SymbianDevice: Explicitly shared device data and a TrkDevice
+// instance that can be acquired (exclusively) for use.
+// A device removal from the manager will result in the
+// device being closed.
+class SYMBIANUTILS_EXPORT SymbianDevice {
+ explicit SymbianDevice(SymbianDeviceData *data);
+ friend class SymbianDeviceManager;
+public:
+ typedef QSharedPointer<trk::TrkDevice> TrkDevicePtr;
+
+ SymbianDevice();
+ SymbianDevice(const SymbianDevice &rhs);
+ SymbianDevice &operator=(const SymbianDevice &rhs);
+ ~SymbianDevice();
+ int compare(const SymbianDevice &rhs) const;
+
+ DeviceCommunicationType type() const;
+ bool isNull() const;
+ QString portName() const;
+ QString friendlyName() const;
+ QString additionalInformation() const;
+ void setAdditionalInformation(const QString &);
+
+ // Acquire: Mark the device as 'out' and return a shared pointer
+ // unless it is already in use by another owner. The result should not
+ // be passed on further.
+ TrkDevicePtr acquireDevice();
+ // Give back a device and mark it as 'free'.
+ void releaseDevice(TrkDevicePtr *ptr = 0);
+
+ bool isOpen() const;
+
+ // Windows only.
+ QString deviceDesc() const;
+ QString manufacturer() const;
+
+ void format(QTextStream &str) const;
+ QString toString() const;
+
+private:
+ void forcedClose();
+
+ QExplicitlySharedDataPointer<SymbianDeviceData> m_data;
+};
+
+SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &);
+
+inline bool operator==(const SymbianDevice &d1, const SymbianDevice &d2)
+ { return d1.compare(d2) == 0; }
+inline bool operator!=(const SymbianDevice &d1, const SymbianDevice &d2)
+ { return d1.compare(d2) != 0; }
+inline bool operator<(const SymbianDevice &d1, const SymbianDevice &d2)
+ { return d1.compare(d2) < 0; }
+
+/* SymbianDeviceManager: Singleton that maintains a list of Symbian devices.
+ * and emits change signals.
+ * On Windows, the update slot must be connected to a [delayed] signal
+ * emitted from an event handler listening for WM_DEVICECHANGE.
+ * Device removal will result in the device being closed. */
+class SYMBIANUTILS_EXPORT SymbianDeviceManager : public QObject
+{
+ Q_OBJECT
+public:
+ typedef QList<SymbianDevice> SymbianDeviceList;
+ typedef QSharedPointer<trk::TrkDevice> TrkDevicePtr;
+
+ static const char *linuxBlueToothDeviceRootC;
+
+ // Do not use this constructor, it is just public for Q_GLOBAL_STATIC
+ explicit SymbianDeviceManager(QObject *parent = 0);
+ virtual ~SymbianDeviceManager();
+
+ // Singleton access.
+ static SymbianDeviceManager *instance();
+
+ SymbianDeviceList devices() const;
+ QString toString() const;
+
+ // Acquire a device for use. See releaseDevice().
+ TrkDevicePtr acquireDevice(const QString &port);
+
+ int findByPortName(const QString &p) const;
+ QString friendlyNameForPort(const QString &port) const;
+
+public slots:
+ void update();
+ // Relase a device, make it available for further use.
+ void releaseDevice(const QString &port);
+ void setAdditionalInformation(const QString &port, const QString &ai);
+
+signals:
+ void deviceRemoved(const SymbianUtils::SymbianDevice &d);
+ void deviceAdded(const SymbianUtils::SymbianDevice &d);
+ void updated();
+
+private:
+ void ensureInitialized() const;
+ void update(bool emitSignals);
+ SymbianDeviceList serialPorts() const;
+ SymbianDeviceList blueToothDevices() const;
+
+ SymbianDeviceManagerPrivate *d;
+};
+
+SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &);
+
+} // namespace SymbianUtils
+
+#endif // SYMBIANDEVICEMANAGER_H
diff --git a/src/runonphone/symbianutils/symbianutils.pri b/src/runonphone/symbianutils/symbianutils.pri
new file mode 100644
index 000000000..f07e494ed
--- /dev/null
+++ b/src/runonphone/symbianutils/symbianutils.pri
@@ -0,0 +1,35 @@
+INCLUDEPATH *= $$PWD
+
+QT += network
+
+# Input
+HEADERS += $$PWD/symbianutils_global.h \
+ $$PWD/callback.h \
+ $$PWD/trkutils.h \
+ $$PWD/trkutils_p.h \
+ $$PWD/trkdevice.h \
+ $$PWD/launcher.h \
+ $$PWD/bluetoothlistener.h \
+ $$PWD/communicationstarter.h \
+ $$PWD/symbiandevicemanager.h \
+ $$PWD/tcftrkdevice.h \
+ $$PWD/tcftrkmessage.h \
+ $$PWD/json.h
+
+SOURCES += $$PWD/trkutils.cpp \
+ $$PWD/trkdevice.cpp \
+ $$PWD/launcher.cpp \
+ $$PWD/bluetoothlistener.cpp \
+ $$PWD/communicationstarter.cpp \
+ $$PWD/symbiandevicemanager.cpp \
+ $$PWD/tcftrkdevice.cpp \
+ $$PWD/tcftrkmessage.cpp \
+ $$PWD/json.cpp
+
+# Tests/trklauncher is a console application
+contains(QT, gui) {
+ HEADERS += $$PWD/bluetoothlistener_gui.h
+ SOURCES += $$PWD/bluetoothlistener_gui.cpp
+} else {
+ message(Trk: Console ...)
+}
diff --git a/src/runonphone/symbianutils/symbianutils_global.h b/src/runonphone/symbianutils/symbianutils_global.h
new file mode 100644
index 000000000..d7acabffd
--- /dev/null
+++ b/src/runonphone/symbianutils/symbianutils_global.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SYMBIANUTILS_GLOBAL_H
+#define SYMBIANUTILS_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(SYMBIANUTILS_BUILD_LIB)
+# define SYMBIANUTILS_EXPORT Q_DECL_EXPORT
+#elif defined(SYMBIANUTILS_BUILD_STATIC_LIB) || defined(SYMBIANUTILS_INCLUDE_PRI)
+# define SYMBIANUTILS_EXPORT
+#else
+# define SYMBIANUTILS_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // SYMBIANUTILS_GLOBAL_H
diff --git a/src/runonphone/symbianutils/tcftrkdevice.cpp b/src/runonphone/symbianutils/tcftrkdevice.cpp
new file mode 100644
index 000000000..5b923ee90
--- /dev/null
+++ b/src/runonphone/symbianutils/tcftrkdevice.cpp
@@ -0,0 +1,929 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tcftrkdevice.h"
+#include "json.h"
+
+#include <QtNetwork/QAbstractSocket>
+#include <QtCore/QDebug>
+#include <QtCore/QVector>
+#include <QtCore/QQueue>
+#include <QtCore/QTextStream>
+#include <QtCore/QDateTime>
+#include <QtCore/QFileInfo>
+
+enum { debug = 0 };
+
+static const char messageTerminatorC[] = "\003\001";
+
+namespace tcftrk {
+// ------------- TcfTrkCommandError
+
+TcfTrkCommandError::TcfTrkCommandError() : timeMS(0), code(0), alternativeCode(0)
+{
+}
+
+void TcfTrkCommandError::clear()
+{
+ timeMS = 0;
+ code = alternativeCode = 0;
+ format.clear();
+ alternativeOrganization.clear();
+}
+
+void TcfTrkCommandError::write(QTextStream &str) const
+{
+ if (timeMS) {
+ const QDateTime time(QDate(1970, 1, 1));
+ str << time.addMSecs(timeMS).toString(Qt::ISODate) << ": Error code: " << code
+ << " '" << format << '\'';
+ if (!alternativeOrganization.isEmpty())
+ str << " ('" << alternativeOrganization << "', code: " << alternativeCode << ')';
+ } else{
+ str << "<No error>";
+ }
+}
+
+QString TcfTrkCommandError::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ write(str);
+ return rc;
+}
+
+/* {"Time":1277459762255,"Code":1,"AltCode":-6,"AltOrg":"POSIX","Format":"Unknown error: -6"} */
+bool TcfTrkCommandError::parse(const QVector<JsonValue> &values)
+{
+ // Parse an arbitrary hash (that could as well be a command response)
+ // and check for error elements.
+ unsigned errorKeyCount = 0;
+ clear();
+ do {
+ if (values.isEmpty() || values.front().type() != JsonValue::Object)
+ break;
+ foreach (const JsonValue &c, values.front().children()) {
+ if (c.name() == "Time") {
+ timeMS = c.data().toULongLong();
+ errorKeyCount++;
+ } else if (c.name() == "Code") {
+ code = c.data().toInt();
+ errorKeyCount++;
+ } else if (c.name() == "Format") {
+ format = c.data();
+ errorKeyCount++;
+ } else if (c.name() == "AltCode") {
+ alternativeCode = c.data().toInt();
+ errorKeyCount++;
+ } else if (c.name() == "AltOrg") {
+ alternativeOrganization = c.data();
+ errorKeyCount++;
+ }
+ }
+ } while (false);
+ const bool errorFound = errorKeyCount >= 2u; // Should be at least 'Time', 'Code'.
+ if (!errorFound)
+ clear();
+ if (debug) {
+ qDebug() << "TcfTrkCommandError::parse: Found error: " << errorFound;
+ if (!values.isEmpty())
+ qDebug() << values.front().toString();
+ }
+ return errorFound;
+}
+
+// ------------ TcfTrkCommandResult
+
+TcfTrkCommandResult::TcfTrkCommandResult(Type t) :
+ type(t), service(LocatorService)
+{
+}
+
+TcfTrkCommandResult::TcfTrkCommandResult(char typeChar, Services s,
+ const QByteArray &r,
+ const QVector<JsonValue> &v,
+ const QVariant &ck) :
+ type(FailReply), service(s), request(r), values(v), cookie(ck)
+{
+ switch (typeChar) {
+ case 'N':
+ type = FailReply;
+ break;
+ case 'P':
+ type = ProgressReply;
+ break;
+ case 'R':
+ type = commandError.parse(values) ? CommandErrorReply : SuccessReply;
+ break;
+ default:
+ qWarning("Unknown TCF reply type '%c'", typeChar);
+ }
+}
+
+QString TcfTrkCommandResult::errorString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+
+ switch (type) {
+ case SuccessReply:
+ case ProgressReply:
+ str << "<No error>";
+ return rc;
+ case FailReply:
+ str << "NAK";
+ case CommandErrorReply:
+ commandError.write(str);
+ break;
+ }
+ // Append the failed command for reference
+ str << " (Command was: '";
+ QByteArray printableRequest = request;
+ printableRequest.replace('\0', '|');
+ str << printableRequest << "')";
+ return rc;
+}
+
+QString TcfTrkCommandResult::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << "Command answer ";
+ switch (type) {
+ case SuccessReply:
+ str << "[success]";
+ break;
+ case CommandErrorReply:
+ str << "[command error]";
+ break;
+ case FailReply:
+ str << "[fail (NAK)]";
+ break;
+ case ProgressReply:
+ str << "[progress]";
+ break;
+ }
+ str << ", " << values.size() << " values(s) to request: '";
+ QByteArray printableRequest = request;
+ printableRequest.replace('\0', '|');
+ str << printableRequest << "' ";
+ if (cookie.isValid())
+ str << " cookie: " << cookie.toString();
+ str << '\n';
+ for (int i = 0, count = values.size(); i < count; i++)
+ str << '#' << i << ' ' << values.at(i).toString() << '\n';
+ if (type == CommandErrorReply)
+ str << "Error: " << errorString();
+ return rc;
+}
+
+struct TcfTrkSendQueueEntry
+{
+ typedef TcfTrkDevice::MessageType MessageType;
+
+ explicit TcfTrkSendQueueEntry(MessageType mt,
+ int tok,
+ Services s,
+ const QByteArray &d,
+ const TcfTrkCallback &cb= TcfTrkCallback(),
+ const QVariant &ck = QVariant()) :
+ messageType(mt), service(s), data(d), token(tok), cookie(ck), callback(cb) {}
+
+ MessageType messageType;
+ Services service;
+ QByteArray data;
+ int token;
+ QVariant cookie;
+ TcfTrkCallback callback;
+};
+
+struct TcfTrkDevicePrivate {
+ typedef TcfTrkDevice::IODevicePtr IODevicePtr;
+ typedef QHash<int, TcfTrkSendQueueEntry> TokenWrittenMessageMap;
+
+ TcfTrkDevicePrivate();
+
+ const QByteArray m_messageTerminator;
+
+ IODevicePtr m_device;
+ unsigned m_verbose;
+ QByteArray m_readBuffer;
+ int m_token;
+ QQueue<TcfTrkSendQueueEntry> m_sendQueue;
+ TokenWrittenMessageMap m_writtenMessages;
+ QVector<QByteArray> m_registerNames;
+};
+
+TcfTrkDevicePrivate::TcfTrkDevicePrivate() :
+ m_messageTerminator(messageTerminatorC),
+ m_verbose(0), m_token(0)
+{
+}
+
+TcfTrkDevice::TcfTrkDevice(QObject *parent) :
+ QObject(parent), d(new TcfTrkDevicePrivate)
+{
+}
+
+TcfTrkDevice::~TcfTrkDevice()
+{
+ delete d;
+}
+
+QVector<QByteArray> TcfTrkDevice::registerNames() const
+{
+ return d->m_registerNames;
+}
+
+void TcfTrkDevice::setRegisterNames(const QVector<QByteArray>& n)
+{
+ d->m_registerNames = n;
+ if (d->m_verbose) {
+ QString msg;
+ QTextStream str(&msg);
+ const int count = n.size();
+ str << "Registers (" << count << "): ";
+ for (int i = 0; i < count; i++)
+ str << '#' << i << '=' << n.at(i) << ' ';
+ emitLogMessage(msg);
+ }
+}
+
+TcfTrkDevice::IODevicePtr TcfTrkDevice::device() const
+{
+ return d->m_device;
+}
+
+TcfTrkDevice::IODevicePtr TcfTrkDevice::takeDevice()
+{
+ const IODevicePtr old = d->m_device;
+ if (!old.isNull()) {
+ old.data()->disconnect(this);
+ d->m_device = IODevicePtr();
+ }
+ d->m_readBuffer.clear();
+ d->m_token = 0;
+ d->m_sendQueue.clear();
+ return old;
+}
+
+void TcfTrkDevice::setDevice(const IODevicePtr &dp)
+{
+ if (dp.data() == d->m_device.data())
+ return;
+ if (dp.isNull()) {
+ emitLogMessage(QLatin1String("Internal error: Attempt to set NULL device."));
+ return;
+ }
+ takeDevice();
+ d->m_device = dp;
+ connect(dp.data(), SIGNAL(readyRead()), this, SLOT(slotDeviceReadyRead()));
+ if (QAbstractSocket *s = qobject_cast<QAbstractSocket *>(dp.data())) {
+ connect(s, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotDeviceError()));
+ connect(s, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(slotDeviceSocketStateChanged()));
+ }
+}
+
+void TcfTrkDevice::slotDeviceError()
+{
+ const QString message = d->m_device->errorString();
+ emitLogMessage(message);
+ emit error(message);
+}
+
+void TcfTrkDevice::slotDeviceSocketStateChanged()
+{
+ if (const QAbstractSocket *s = qobject_cast<const QAbstractSocket *>(d->m_device.data())) {
+ const QAbstractSocket::SocketState st = s->state();
+ switch (st) {
+ case QAbstractSocket::UnconnectedState:
+ emitLogMessage(QLatin1String("Unconnected"));
+ break;
+ case QAbstractSocket::HostLookupState:
+ emitLogMessage(QLatin1String("HostLookupState"));
+ break;
+ case QAbstractSocket::ConnectingState:
+ emitLogMessage(QLatin1String("Connecting"));
+ break;
+ case QAbstractSocket::ConnectedState:
+ emitLogMessage(QLatin1String("Connected"));
+ break;
+ case QAbstractSocket::ClosingState:
+ emitLogMessage(QLatin1String("Closing"));
+ break;
+ default:
+ emitLogMessage(QString::fromLatin1("State %1").arg(st));
+ break;
+ }
+ }
+}
+
+static inline QString debugMessage(QByteArray message, const char *prefix = 0)
+{
+ message.replace('\0', '|');
+ const QString messageS = QString::fromLatin1(message);
+ return prefix ?
+ (QLatin1String(prefix) + messageS) : messageS;
+}
+
+void TcfTrkDevice::slotDeviceReadyRead()
+{
+ d->m_readBuffer += d->m_device->readAll();
+ // Take complete message off front of readbuffer.
+ do {
+ const int messageEndPos = d->m_readBuffer.indexOf(d->m_messageTerminator);
+ if (messageEndPos == -1)
+ break;
+ const QByteArray message = d->m_readBuffer.left(messageEndPos);
+ if (debug)
+ qDebug("Read:\n%s", qPrintable(formatData(message)));
+ if (const int errorCode = parseMessage(message)) {
+ emitLogMessage(QString::fromLatin1("Parse error %1 for: %2").arg(errorCode).arg(debugMessage(message)));
+ }
+ d->m_readBuffer.remove(0, messageEndPos + d->m_messageTerminator.size());
+ } while (!d->m_readBuffer.isEmpty());
+ checkSendQueue(); // Send off further message
+}
+
+// Split \0-terminated message into tokens, skipping the initial type character
+static inline QVector<QByteArray> splitMessage(const QByteArray &message)
+{
+ QVector<QByteArray> tokens;
+ tokens.reserve(7);
+ const int messageSize = message.size();
+ for (int pos = 2; pos < messageSize; ) {
+ const int nextPos = message.indexOf('\0', pos);
+ if (nextPos == -1)
+ break;
+ tokens.push_back(message.mid(pos, nextPos - pos));
+ pos = nextPos + 1;
+ }
+ return tokens;
+}
+
+int TcfTrkDevice::parseMessage(const QByteArray &message)
+{
+ if (d->m_verbose)
+ emitLogMessage(debugMessage(message, "TCF ->"));
+ // Special JSON parse error message or protocol format error.
+ // The port is usually closed after receiving it.
+ // "\3\2{"Time":1276096098255,"Code":3,"Format": "Protocol format error"}"
+ if (message.startsWith("\003\002")) {
+ QByteArray text = message.mid(2);
+ const QString errorMessage = QString::fromLatin1("Parse error received: %1").arg(QString::fromAscii(text));
+ emit error(errorMessage);
+ return 0;
+ }
+ if (message.size() < 4 || message.at(1) != '\0')
+ return 1;
+ // Split into tokens
+ const char type = message.at(0);
+ const QVector<QByteArray> tokens = splitMessage(message);
+ switch (type) {
+ case 'E':
+ return parseTcfEvent(tokens);
+ case 'R': // Command replies
+ case 'N':
+ case 'P':
+ return parseTcfCommandReply(type, tokens);
+ default:
+ emitLogMessage(QString::fromLatin1("Unhandled message type: %1").arg(debugMessage(message)));
+ return 756;
+ }
+ return 0;
+}
+
+int TcfTrkDevice::parseTcfCommandReply(char type, const QVector<QByteArray> &tokens)
+{
+ typedef TcfTrkDevicePrivate::TokenWrittenMessageMap::iterator TokenWrittenMessageMapIterator;
+ // Find the corresponding entry in the written messages hash.
+ const int tokenCount = tokens.size();
+ if (tokenCount < 1)
+ return 234;
+ bool tokenOk;
+ const int token = tokens.at(0).toInt(&tokenOk);
+ if (!tokenOk)
+ return 235;
+ const TokenWrittenMessageMapIterator it = d->m_writtenMessages.find(token);
+ if (it == d->m_writtenMessages.end()) {
+ qWarning("TcfTrkDevice: Internal error: token %d not found for '%s'",
+ token, qPrintable(joinByteArrays(tokens)));
+ return 236;
+ }
+ // No callback: remove entry from map, happy
+ if (!it.value().callback) {
+ d->m_writtenMessages.erase(it);
+ return 0;
+ }
+ // Parse values into JSON
+ QVector<JsonValue> values;
+ values.reserve(tokenCount);
+ for (int i = 1; i < tokenCount; i++) {
+ if (!tokens.at(i).isEmpty()) { // Strange: Empty tokens occur.
+ const JsonValue value(tokens.at(i));
+ if (value.isValid()) {
+ values.push_back(value);
+ } else {
+ qWarning("JSON parse error for reply to command token %d: #%d '%s'",
+ token, i, tokens.at(i).constData());
+ d->m_writtenMessages.erase(it);
+ return -1;
+ }
+ }
+ }
+
+ // Construct result and invoke callback, remove entry from map.
+ TcfTrkCallback callback = it.value().callback;
+ TcfTrkCommandResult result(type, it.value().service, it.value().data,
+ values, it.value().cookie);
+ d->m_writtenMessages.erase(it);
+ callback(result);
+ return 0;
+}
+
+static const char locatorAnswerC[] = "E\0Locator\0Hello\0[\"Locator\"]";
+
+int TcfTrkDevice::parseTcfEvent(const QVector<QByteArray> &tokens)
+{
+ // Event: Ignore the periodical heartbeat event, answer 'Hello',
+ // emit signal for the rest
+ if (tokens.size() < 3)
+ return 433;
+ const Services service = serviceFromName(tokens.at(0).constData());
+ if (service == LocatorService && tokens.at(1) == "peerHeartBeat")
+ return 0;
+ QVector<JsonValue> values;
+ for (int i = 2; i < tokens.size(); i++) {
+ const JsonValue value(tokens.at(i));
+ if (!value.isValid())
+ return 434;
+ values.push_back(value);
+ }
+ // Parse known events, emit signals
+ QScopedPointer<TcfTrkEvent> knownEvent(TcfTrkEvent::parseEvent(service, tokens.at(1), values));
+ if (!knownEvent.isNull()) {
+ // Answer hello event.
+ if (knownEvent->type() == TcfTrkEvent::LocatorHello)
+ writeMessage(QByteArray(locatorAnswerC, sizeof(locatorAnswerC)));
+ emit tcfEvent(*knownEvent);
+ }
+ emit genericTcfEvent(service, tokens.at(1), values);
+
+ if (debug || d->m_verbose) {
+ QString msg;
+ QTextStream str(&msg);
+ if (knownEvent.isNull()) {
+ str << "Event: " << tokens.at(0) << ' ' << tokens.at(1) << '\n';
+ foreach(const JsonValue &val, values)
+ str << " " << val.toString() << '\n';
+ } else {
+ str << knownEvent->toString();
+ }
+ emitLogMessage(msg);
+ }
+
+ return 0;
+}
+
+unsigned TcfTrkDevice::verbose() const
+{
+ return d->m_verbose;
+}
+
+void TcfTrkDevice::setVerbose(unsigned v)
+{
+ d->m_verbose = v;
+}
+
+void TcfTrkDevice::emitLogMessage(const QString &m)
+{
+ if (debug)
+ qWarning("%s", qPrintable(m));
+ emit logMessage(m);
+}
+
+bool TcfTrkDevice::checkOpen()
+{
+ if (d->m_device.isNull()) {
+ emitLogMessage(QLatin1String("Internal error: No device set on TcfTrkDevice."));
+ return false;
+ }
+ if (!d->m_device->isOpen()) {
+ emitLogMessage(QLatin1String("Internal error: Device not open in TcfTrkDevice."));
+ return false;
+ }
+ return true;
+}
+
+void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command,
+ const char *commandParameters, int commandParametersLength,
+ const TcfTrkCallback &callBack,
+ const QVariant &cookie)
+
+{
+ if (!checkOpen())
+ return;
+ // Format the message
+ const int token = d->m_token++;
+ QByteArray data;
+ data.reserve(30 + commandParametersLength);
+ data.append('C');
+ data.append('\0');
+ data.append(QByteArray::number(token));
+ data.append('\0');
+ data.append(serviceName(service));
+ data.append('\0');
+ data.append(command);
+ data.append('\0');
+ if (commandParametersLength)
+ data.append(commandParameters, commandParametersLength);
+ const TcfTrkSendQueueEntry entry(mt, token, service, data, callBack, cookie);
+ d->m_sendQueue.enqueue(entry);
+ checkSendQueue();
+}
+
+void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command,
+ const QByteArray &commandParameters,
+ const TcfTrkCallback &callBack,
+ const QVariant &cookie)
+{
+ sendTcfTrkMessage(mt, service, command, commandParameters.constData(), commandParameters.size(),
+ callBack, cookie);
+}
+
+// Enclose in message frame and write.
+void TcfTrkDevice::writeMessage(QByteArray data)
+{
+ if (!checkOpen())
+ return;
+
+ if (d->m_verbose)
+ emitLogMessage(debugMessage(data, "TCF <-"));
+
+ // Ensure \0-termination which easily gets lost in QByteArray CT.
+ if (!data.endsWith('\0'))
+ data.append('\0');
+ data += d->m_messageTerminator;
+
+ if (debug > 1)
+ qDebug("Writing:\n%s", qPrintable(formatData(data)));
+
+ d->m_device->write(data);
+ if (QAbstractSocket *as = qobject_cast<QAbstractSocket *>(d->m_device.data()))
+ as->flush();
+}
+
+void TcfTrkDevice::checkSendQueue()
+{
+ // Fire off messages or invoke noops until a message with reply is found
+ // and an entry to writtenMessages is made.
+ while (d->m_writtenMessages.empty()) {
+ if (d->m_sendQueue.isEmpty())
+ break;
+ TcfTrkSendQueueEntry entry = d->m_sendQueue.dequeue();
+ switch (entry.messageType) {
+ case MessageWithReply:
+ d->m_writtenMessages.insert(entry.token, entry);
+ writeMessage(entry.data);
+ break;
+ case MessageWithoutReply:
+ writeMessage(entry.data);
+ break;
+ case NoopMessage: // Invoke the noop-callback for synchronization
+ if (entry.callback) {
+ TcfTrkCommandResult noopResult(TcfTrkCommandResult::SuccessReply);
+ noopResult.cookie = entry.cookie;
+ entry.callback(noopResult);
+ }
+ break;
+ }
+ }
+}
+
+// Fix slashes
+static inline QString fixFileName(QString in)
+{
+ in.replace(QLatin1Char('/'), QLatin1Char('\\'));
+ return in;
+}
+
+// Start a process (consisting of a non-reply setSettings and start).
+void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack,
+ const QString &binaryIn,
+ unsigned uid,
+ QStringList arguments,
+ QString workingDirectory,
+ bool debugControl,
+ const QStringList &additionalLibraries,
+ const QVariant &cookie)
+{
+ // Obtain the bin directory, expand by c:/sys/bin if missing
+ const QChar backSlash('\\');
+ int slashPos = binaryIn.lastIndexOf(QLatin1Char('/'));
+ if (slashPos == -1)
+ slashPos = binaryIn.lastIndexOf(backSlash);
+ const QString sysBin = QLatin1String("c:/sys/bin");
+ const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1);
+ const QString binaryDirectory = slashPos == -1 ? sysBin : binaryIn.left(slashPos);
+ const QString binary = fixFileName(binaryDirectory + QLatin1Char('/') + binaryFileName);
+
+ // Fixup: Does argv[0] convention exist on Symbian?
+ arguments.push_front(binary);
+ if (workingDirectory.isEmpty())
+ workingDirectory = sysBin;
+
+ // Format settings with empty dummy parameter
+ QByteArray setData;
+ JsonInputStream setStr(setData);
+ setStr << "" << '\0'
+ << '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ']'
+ << '\0' << '['
+ << binary << ','
+ << '{' << binaryFileName << ':' << QString::number(uid, 16) << '}' << ','
+ << additionalLibraries
+ << ']';
+ sendTcfTrkMessage(MessageWithoutReply, SettingsService, "set", setData);
+
+ QByteArray startData;
+ JsonInputStream startStr(startData);
+ startStr << fixFileName(workingDirectory)
+ << '\0' << binary << '\0' << arguments << '\0'
+ << QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard)
+ << debugControl;
+ sendTcfTrkMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie);
+}
+
+void TcfTrkDevice::sendProcessTerminateCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << id;
+ sendTcfTrkMessage(MessageWithReply, ProcessesService, "terminate", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendRunControlTerminateCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << id;
+ sendTcfTrkMessage(MessageWithReply, RunControlService, "terminate", data, callBack, cookie);
+}
+
+// Non-standard: Remove executable from settings
+void TcfTrkDevice::sendSettingsRemoveExecutableCommand(const QString &binaryIn,
+ unsigned uid,
+ const QStringList &additionalLibraries,
+ const QVariant &cookie)
+{
+ QByteArray setData;
+ JsonInputStream setStr(setData);
+ setStr << "" << '\0'
+ << '[' << "removedExecutables" << ',' << "removedLibraries" << ']'
+ << '\0' << '['
+ << '{' << QFileInfo(binaryIn).fileName() << ':' << QString::number(uid, 16) << '}' << ','
+ << additionalLibraries
+ << ']';
+ sendTcfTrkMessage(MessageWithoutReply, SettingsService, "set", setData, TcfTrkCallback(), cookie);
+}
+
+void TcfTrkDevice::sendRunControlResumeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ RunControlResumeMode mode,
+ unsigned count,
+ quint64 rangeStart,
+ quint64 rangeEnd,
+ const QVariant &cookie)
+{
+ QByteArray resumeData;
+ JsonInputStream str(resumeData);
+ str << id << '\0' << int(mode) << '\0' << count;
+ switch (mode) {
+ case RM_STEP_OVER_RANGE:
+ case RM_STEP_INTO_RANGE:
+ case RM_REVERSE_STEP_OVER_RANGE:
+ case RM_REVERSE_STEP_INTO_RANGE:
+ str << '\0' << '{' << "RANGE_START" << ':' << rangeStart
+ << ',' << "RANGE_END" << ':' << rangeEnd << '}';
+ break;
+ default:
+ break;
+ }
+ sendTcfTrkMessage(MessageWithReply, RunControlService, "resume", resumeData, callBack, cookie);
+}
+
+void TcfTrkDevice::sendRunControlSuspendCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << id;
+ sendTcfTrkMessage(MessageWithReply, RunControlService, "suspend", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendRunControlResumeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ sendRunControlResumeCommand(callBack, id, RM_RESUME, 1, 0, 0, cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsAddCommand(const TcfTrkCallback &callBack,
+ const Breakpoint &bp,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << bp;
+ sendTcfTrkMessage(MessageWithReply, BreakpointsService, "add", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ sendBreakpointsRemoveCommand(callBack, QVector<QByteArray>(1, id), cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack,
+ const QVector<QByteArray> &ids,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << ids;
+ sendTcfTrkMessage(MessageWithReply, BreakpointsService, "remove", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsEnableCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ bool enable,
+ const QVariant &cookie)
+{
+ sendBreakpointsEnableCommand(callBack, QVector<QByteArray>(1, id), enable, cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsEnableCommand(const TcfTrkCallback &callBack,
+ const QVector<QByteArray> &ids,
+ bool enable,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << ids;
+ sendTcfTrkMessage(MessageWithReply, BreakpointsService,
+ enable ? "enable" : "disable",
+ data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendMemorySetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ quint64 start, const QByteArray& data,
+ const QVariant &cookie)
+{
+ QByteArray getData;
+ JsonInputStream str(getData);
+ // start/word size/mode. Mode should ideally be 1 (continue on error?)
+ str << contextId << '\0' << start << '\0' << 1 << '\0' << data.size() << '\0' << 1
+ << '\0' << data.toBase64();
+ sendTcfTrkMessage(MessageWithReply, MemoryService, "set", getData, callBack, cookie);
+}
+
+void TcfTrkDevice::sendMemoryGetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ quint64 start, quint64 size,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ // start/word size/mode. Mode should ideally be 1 (continue on error?)
+ str << contextId << '\0' << start << '\0' << 1 << '\0' << size << '\0' << 1;
+ sendTcfTrkMessage(MessageWithReply, MemoryService, "get", data, callBack, cookie);
+}
+
+QByteArray TcfTrkDevice::parseMemoryGet(const TcfTrkCommandResult &r)
+{
+ if (r.type != TcfTrkCommandResult::SuccessReply || r.values.size() < 1)
+ return QByteArray();
+ const JsonValue &memoryV = r.values.front();
+
+ if (memoryV.type() != JsonValue::String || memoryV.data().size() < 2
+ || !memoryV.data().endsWith('='))
+ return QByteArray();
+ // Catch errors reported as hash:
+ // R.4."TlVMTA==".{"Time":1276786871255,"Code":1,"AltCode":-38,"AltOrg":"POSIX","Format":"BadDescriptor"}
+ // Not sure what to make of it.
+ if (r.values.size() >= 2 && r.values.at(1).type() == JsonValue::Object)
+ qWarning("Error retrieving memory: %s", r.values.at(1).toString(false).constData());
+ // decode
+ const QByteArray memory = QByteArray::fromBase64(memoryV.data());
+ if (memory.isEmpty())
+ qWarning("Base64 decoding of %s failed.", memoryV.data().constData());
+ if (debug)
+ qDebug("TcfTrkDevice::parseMemoryGet: received %d bytes", memory.size());
+ return memory;
+}
+
+void TcfTrkDevice::sendRegistersGetMCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ const QVector<QByteArray> &ids,
+ const QVariant &cookie)
+{
+ // TODO: use "Registers" (which uses base64-encoded values)
+ QByteArray data;
+ JsonInputStream str(data);
+ str << contextId << '\0' << ids;
+ sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "get", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ unsigned start, unsigned count)
+{
+ const unsigned end = start + count;
+ if (end > (unsigned)d->m_registerNames.size()) {
+ qWarning("TcfTrkDevice: No register name set for index %u (size: %d).", end, d->m_registerNames.size());
+ return;
+ }
+
+ QVector<QByteArray> ids;
+ ids.reserve(count);
+ for (unsigned i = start; i < end; i++)
+ ids.push_back(d->m_registerNames.at(i));
+ sendRegistersGetMCommand(callBack, contextId, ids, QVariant(start));
+}
+
+// Set register
+void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ const QByteArray &id,
+ unsigned value,
+ const QVariant &cookie)
+{
+ // TODO: use "Registers" (which uses base64-encoded values)
+ QByteArray data;
+ JsonInputStream str(data);
+ str << contextId << '\0' << QVector<QByteArray>(1, id)
+ << '\0' << QVector<QByteArray>(1, QByteArray::number(value, 16));
+ sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "set", data, callBack, cookie);
+}
+
+// Set register
+void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ unsigned registerNumber,
+ unsigned value,
+ const QVariant &cookie)
+{
+ if (registerNumber >= (unsigned)d->m_registerNames.size()) {
+ qWarning("TcfTrkDevice: No register name set for index %u (size: %d).", registerNumber, d->m_registerNames.size());
+ return;
+ }
+ sendRegistersSetCommand(callBack, contextId,
+ d->m_registerNames[registerNumber],
+ value, cookie);
+}
+
+} // namespace tcftrk
diff --git a/src/runonphone/symbianutils/tcftrkdevice.h b/src/runonphone/symbianutils/tcftrkdevice.h
new file mode 100644
index 000000000..d42f3f3cb
--- /dev/null
+++ b/src/runonphone/symbianutils/tcftrkdevice.h
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TCFTRKENGINE_H
+#define TCFTRKENGINE_H
+
+#include "symbianutils_global.h"
+#include "tcftrkmessage.h"
+#include "callback.h"
+#include "json.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QVector>
+#include <QtCore/QVariant>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+class QIODevice;
+class QTextStream;
+QT_END_NAMESPACE
+
+namespace tcftrk {
+
+struct TcfTrkDevicePrivate;
+struct Breakpoint;
+
+/* Command error handling in TCF:
+ * 1) 'Severe' errors (JSON format, parameter format): Trk emits a
+ * nonstandard message (\3\2 error parameters) and closes the connection.
+ * 2) Protocol errors: 'N' without error message is returned.
+ * 3) Errors in command execution: 'R' with a TCF error hash is returned
+ * (see TcfTrkCommandError). */
+
+/* Error code return in 'R' reply to command
+ * (see top of 'Services' documentation). */
+struct SYMBIANUTILS_EXPORT TcfTrkCommandError {
+ TcfTrkCommandError();
+ void clear();
+ operator bool() const { return timeMS != 0; }
+ QString toString() const;
+ void write(QTextStream &str) const;
+ bool parse(const QVector<JsonValue> &values);
+
+ quint64 timeMS; // Since 1.1.1970
+ int code;
+ QByteArray format; // message
+ // 'Alternative' meaning, like altOrg="POSIX"/altCode=<some errno>
+ QByteArray alternativeOrganization;
+ int alternativeCode;
+};
+
+/* Answer to a Tcf command passed to the callback. */
+struct SYMBIANUTILS_EXPORT TcfTrkCommandResult {
+ enum Type {
+ SuccessReply, // 'R' and no error -> all happy.
+ CommandErrorReply, // 'R' with TcfTrkCommandError received
+ ProgressReply, // 'P', progress indicator
+ FailReply // 'N' Protocol NAK, severe error
+ };
+
+ explicit TcfTrkCommandResult(Type t = SuccessReply);
+ explicit TcfTrkCommandResult(char typeChar, Services service,
+ const QByteArray &request,
+ const QVector<JsonValue> &values,
+ const QVariant &cookie);
+
+ QString toString() const;
+ QString errorString() const;
+ operator bool() const { return type == SuccessReply || type == ProgressReply; }
+
+ Type type;
+ Services service;
+ QByteArray request;
+ TcfTrkCommandError commandError;
+ QVector<JsonValue> values;
+ QVariant cookie;
+};
+
+typedef trk::Callback<const TcfTrkCommandResult &> TcfTrkCallback;
+
+/* TcfTrkDevice: TCF communication helper using an asynchronous QIODevice
+ * implementing the TCF protocol according to:
+http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Specification.html
+http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html
+ * Commands can be sent along with callbacks that are passed a
+ * TcfTrkCommandResult and an opaque QVariant cookie. In addition, events are emitted.
+*/
+
+class SYMBIANUTILS_EXPORT TcfTrkDevice : public QObject
+{
+ Q_PROPERTY(unsigned verbose READ verbose WRITE setVerbose)
+ Q_OBJECT
+public:
+ enum MessageType { MessageWithReply,
+ MessageWithoutReply, /* Non-standard: "Settings:set" command does not reply */
+ NoopMessage };
+
+ typedef QSharedPointer<QIODevice> IODevicePtr;
+
+ explicit TcfTrkDevice(QObject *parent = 0);
+ virtual ~TcfTrkDevice();
+
+ unsigned verbose() const;
+
+ // Mapping of register names for indices
+ QVector<QByteArray> registerNames() const;
+ void setRegisterNames(const QVector<QByteArray>& n);
+
+ IODevicePtr device() const;
+ IODevicePtr takeDevice();
+ void setDevice(const IODevicePtr &dp);
+
+ void sendTcfTrkMessage(MessageType mt, Services service,
+ const char *command,
+ const char *commandParameters, int commandParametersLength,
+ const TcfTrkCallback &callBack = TcfTrkCallback(),
+ const QVariant &cookie = QVariant());
+
+ void sendTcfTrkMessage(MessageType mt, Services service, const char *command,
+ const QByteArray &commandParameters,
+ const TcfTrkCallback &callBack = TcfTrkCallback(),
+ const QVariant &cookie = QVariant());
+
+ // Convenience messages: Start a process
+ void sendProcessStartCommand(const TcfTrkCallback &callBack,
+ const QString &binary,
+ unsigned uid,
+ QStringList arguments = QStringList(),
+ QString workingDirectory = QString(),
+ bool debugControl = true,
+ const QStringList &additionalLibraries = QStringList(),
+ const QVariant &cookie = QVariant());
+
+ // Preferred over Processes:Terminate by TCF TRK.
+ void sendRunControlTerminateCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ void sendProcessTerminateCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ // Non-standard: Remove executable from settings.
+ // Probably needs to be called after stopping. This command has no response.
+ void sendSettingsRemoveExecutableCommand(const QString &binaryIn,
+ unsigned uid,
+ const QStringList &additionalLibraries = QStringList(),
+ const QVariant &cookie = QVariant());
+
+ void sendRunControlSuspendCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ // Resume / Step (see RunControlResumeMode).
+ void sendRunControlResumeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ RunControlResumeMode mode,
+ unsigned count /* = 1, currently ignored. */,
+ quint64 rangeStart, quint64 rangeEnd,
+ const QVariant &cookie = QVariant());
+
+ // Convenience to resume a suspended process
+ void sendRunControlResumeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsAddCommand(const TcfTrkCallback &callBack,
+ const Breakpoint &b,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack,
+ const QVector<QByteArray> &id,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ bool enable,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack,
+ const QVector<QByteArray> &id,
+ bool enable,
+ const QVariant &cookie = QVariant());
+
+
+ void sendMemoryGetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ quint64 start, quint64 size,
+ const QVariant &cookie = QVariant());
+
+ void sendMemorySetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ quint64 start, const QByteArray& data,
+ const QVariant &cookie = QVariant());
+
+ // Reply is an array of hexvalues
+ void sendRegistersGetMCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ const QVector<QByteArray> &ids,
+ const QVariant &cookie = QVariant());
+
+ // Convenience to get a range of register "R0" .. "R<n>".
+ // Cookie will be an int containing "start".
+ void sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ unsigned start, unsigned count);
+
+ // Set register
+ void sendRegistersSetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ const QByteArray &ids,
+ unsigned value,
+ const QVariant &cookie = QVariant());
+ // Set register
+ void sendRegistersSetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ unsigned registerNumber,
+ unsigned value,
+ const QVariant &cookie = QVariant());
+
+ static QByteArray parseMemoryGet(const TcfTrkCommandResult &r);
+
+signals:
+ void genericTcfEvent(int service, const QByteArray &name, const QVector<tcftrk::JsonValue> &value);
+ void tcfEvent(const tcftrk::TcfTrkEvent &knownEvent);
+
+ void logMessage(const QString &);
+ void error(const QString &);
+
+public slots:
+ void setVerbose(unsigned v);
+
+private slots:
+ void slotDeviceError();
+ void slotDeviceSocketStateChanged();
+ void slotDeviceReadyRead();
+
+private:
+ bool checkOpen();
+ void checkSendQueue();
+ void writeMessage(QByteArray data);
+ void emitLogMessage(const QString &);
+ int parseMessage(const QByteArray &);
+ int parseTcfCommandReply(char type, const QVector<QByteArray> &tokens);
+ int parseTcfEvent(const QVector<QByteArray> &tokens);
+
+ TcfTrkDevicePrivate *d;
+};
+
+} // namespace tcftrk
+
+#endif // TCFTRKENGINE_H
diff --git a/src/runonphone/symbianutils/tcftrkmessage.cpp b/src/runonphone/symbianutils/tcftrkmessage.cpp
new file mode 100644
index 000000000..8d62dece2
--- /dev/null
+++ b/src/runonphone/symbianutils/tcftrkmessage.cpp
@@ -0,0 +1,562 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tcftrkmessage.h"
+#include "json.h"
+
+#include <QtCore/QString>
+#include <QtCore/QTextStream>
+
+// Names matching the enum
+static const char *serviceNamesC[] =
+{ "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints",
+ "Registers", "SimpleRegisters",
+ "UnknownService"};
+
+namespace tcftrk {
+
+SYMBIANUTILS_EXPORT QString joinByteArrays(const QVector<QByteArray> &a, char sep)
+{
+ QString rc;
+ const int count = a.size();
+ for (int i = 0; i < count; i++) {
+ if (i)
+ rc += QLatin1Char(sep);
+ rc += QString::fromUtf8(a.at(i));
+ }
+ return rc;
+}
+
+static inline bool jsonToBool(const JsonValue& js)
+{
+ return js.type() == JsonValue::Boolean && js.data() == "true";
+}
+
+SYMBIANUTILS_EXPORT const char *serviceName(Services s)
+{
+ return serviceNamesC[s];
+}
+
+SYMBIANUTILS_EXPORT Services serviceFromName(const char *n)
+{
+ const int count = sizeof(serviceNamesC)/sizeof(char *);
+ for (int i = 0; i < count; i++)
+ if (!qstrcmp(serviceNamesC[i], n))
+ return static_cast<Services>(i);
+ return UnknownService;
+}
+
+SYMBIANUTILS_EXPORT QString formatData(const QByteArray &a)
+{
+ const int columns = 16;
+ QString rc;
+ QTextStream str(&rc);
+ str.setIntegerBase(16);
+ str.setPadChar(QLatin1Char('0'));
+ const unsigned char *start = reinterpret_cast<const unsigned char *>(a.constData());
+ const unsigned char *end = start + a.size();
+ for (const unsigned char *p = start; p < end ; ) {
+ str << "0x";
+ str.setFieldWidth(4);
+ str << (p - start);
+ str.setFieldWidth(0);
+ str << ' ';
+ QString asc;
+ int c = 0;
+ for ( ; c < columns && p < end; c++, p++) {
+ const unsigned u = *p;
+ str.setFieldWidth(2);
+ str << u;
+ str.setFieldWidth(0);
+ str << ' ';
+ switch (u) {
+ case '\n':
+ asc += QLatin1String("\\n");
+ break;
+ case '\r':
+ asc += QLatin1String("\\r");
+ break;
+ case '\t':
+ asc += QLatin1String("\\t");
+ break;
+ default:
+ if (u >= 32 && u < 128) {
+ asc += QLatin1Char(' ');
+ asc += QLatin1Char(u);
+ } else {
+ asc += QLatin1String(" .");
+ }
+ break;
+ }
+ }
+ if (const int remainder = columns - c)
+ str << QString(3 * remainder, QLatin1Char(' '));
+ str << ' ' << asc << '\n';
+ }
+ return rc;
+}
+
+// ----------- RunControlContext
+RunControlContext::RunControlContext() :
+ flags(0), resumeFlags(0)
+{
+}
+
+void RunControlContext::clear()
+{
+ flags =0;
+ resumeFlags = 0;
+ id.clear();
+ osid.clear();
+ parentId.clear();
+}
+
+RunControlContext::Type RunControlContext::typeFromTcfId(const QByteArray &id)
+{
+ // "p12" or "p12.t34"?
+ return id.contains(".t") ? Thread : Process;
+}
+
+unsigned RunControlContext::processId() const
+{
+ return processIdFromTcdfId(id);
+}
+
+unsigned RunControlContext::threadId() const
+{
+ return threadIdFromTcdfId(id);
+}
+
+unsigned RunControlContext::processIdFromTcdfId(const QByteArray &id)
+{
+ // Cut out process id from "p12" or "p12.t34"?
+ if (!id.startsWith('p'))
+ return 0;
+ const int dotPos = id.indexOf('.');
+ const int pLen = dotPos == -1 ? id.size() : dotPos;
+ return id.mid(1, pLen - 1).toUInt();
+}
+
+unsigned RunControlContext::threadIdFromTcdfId(const QByteArray &id)
+{
+ const int tPos = id.indexOf(".t");
+ return tPos != -1 ? id.mid(tPos + 2).toUInt() : uint(0);
+}
+
+QByteArray RunControlContext::tcfId(unsigned processId, unsigned threadId /* = 0 */)
+{
+ QByteArray rc("p");
+ rc += QByteArray::number(processId);
+ if (threadId) {
+ rc += ".t";
+ rc += QByteArray::number(threadId);
+ }
+ return rc;
+}
+
+RunControlContext::Type RunControlContext::type() const
+{
+ return RunControlContext::typeFromTcfId(id);
+}
+
+bool RunControlContext::parse(const JsonValue &val)
+{
+ clear();
+ if (val.type() != JsonValue::Object)
+ return false;
+ foreach(const JsonValue &c, val.children()) {
+ if (c.name() == "ID") {
+ id = c.data();
+ } else if (c.name() == "OSID") {
+ osid = c.data();
+ } else if (c.name() == "ParentID") {
+ parentId = c.data();
+ } else if (c.name() == "IsContainer") {
+ if (jsonToBool(c))
+ flags |= Container;
+ } else if (c.name() == "CanTerminate") {
+ if (jsonToBool(c))
+ flags |= CanTerminate;
+ } else if (c.name() == "CanResume") {
+ resumeFlags = c.data().toUInt();
+ } else if (c.name() == "HasState") {
+ if (jsonToBool(c))
+ flags |= HasState;
+ } else if (c.name() == "CanSuspend") {
+ if (jsonToBool(c))
+ flags |= CanSuspend;
+ }
+ }
+ return true;
+}
+
+QString RunControlContext::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ format(str);
+ return rc;
+}
+
+void RunControlContext::format(QTextStream &str) const
+{
+ str << " id='" << id << "' osid='" << osid
+ << "' parentId='" << parentId <<"' ";
+ if (flags & Container)
+ str << "[container] ";
+ if (flags & HasState)
+ str << "[has state] ";
+ if (flags & CanSuspend)
+ str << "[can suspend] ";
+ if (flags & CanSuspend)
+ str << "[can terminate] ";
+ str.setIntegerBase(16);
+ str << " resume_flags: 0x" << resumeFlags;
+ str.setIntegerBase(10);
+}
+
+// ------ ModuleLoadEventInfo
+ModuleLoadEventInfo::ModuleLoadEventInfo() :
+ loaded(false), codeAddress(0), dataAddress(0), requireResume(false)
+{
+}
+
+void ModuleLoadEventInfo::clear()
+{
+ loaded = requireResume = false;
+ codeAddress = dataAddress =0;
+}
+
+bool ModuleLoadEventInfo::parse(const JsonValue &val)
+{
+ clear();
+ if (val.type() != JsonValue::Object)
+ return false;
+ foreach(const JsonValue &c, val.children()) {
+ if (c.name() == "Name") {
+ name = c.data();
+ } else if (c.name() == "File") {
+ file = c.data();
+ } else if (c.name() == "CodeAddress") {
+ codeAddress = c.data().toULongLong();
+ } else if (c.name() == "DataAddress") {
+ dataAddress = c.data().toULongLong();
+ } else if (c.name() == "Loaded") {
+ loaded = jsonToBool(c);
+ } else if (c.name() == "RequireResume") {
+ requireResume =jsonToBool(c);
+ }
+ }
+ return true;
+}
+void ModuleLoadEventInfo::format(QTextStream &str) const
+{
+ str << "name='" << name << "' file='" << file << "' " <<
+ (loaded ? "[loaded] " : "[not loaded] ");
+ if (requireResume)
+ str << "[requires resume] ";
+ str.setIntegerBase(16);
+ str << " code: 0x" << codeAddress << " data: 0x" << dataAddress;
+ str.setIntegerBase(10);
+}
+
+// ---------------------- Breakpoint
+
+// Types matching enum
+static const char *breakPointTypesC[] = {"Software", "Hardware", "Auto"};
+
+Breakpoint::Breakpoint(quint64 loc) :
+ type(Auto), enabled(true), ignoreCount(0), location(loc), size(1), thumb(true)
+{
+ if (loc)
+ id = idFromLocation(location);
+}
+
+void Breakpoint::setContextId(unsigned processId, unsigned threadId)
+{
+ contextIds = QVector<QByteArray>(1, RunControlContext::tcfId(processId, threadId));
+}
+
+QByteArray Breakpoint::idFromLocation(quint64 loc)
+{
+ return QByteArray("BP_0x") + QByteArray::number(loc, 16);
+}
+
+QString Breakpoint::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str.setIntegerBase(16);
+ str << "Breakpoint '" << id << "' " << breakPointTypesC[type] << " for contexts '"
+ << joinByteArrays(contextIds, ',') << "' at 0x" << location;
+ str.setIntegerBase(10);
+ str << " size " << size;
+ if (enabled)
+ str << " [enabled]";
+ if (thumb)
+ str << " [thumb]";
+ if (ignoreCount)
+ str << " IgnoreCount " << ignoreCount;
+ return rc;
+}
+
+JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b)
+{
+ if (b.contextIds.isEmpty())
+ qWarning("tcftrk::Breakpoint: No context ids specified");
+
+ str << '{' << "ID" << ':' << QString::fromUtf8(b.id) << ','
+ << "BreakpointType" << ':' << breakPointTypesC[b.type] << ','
+ << "Enabled" << ':' << b.enabled << ','
+ << "IgnoreCount" << ':' << b.ignoreCount << ','
+ << "ContextIds" << ':' << b.contextIds << ','
+ << "Location" << ':' << QString::number(b.location) << ','
+ << "Size" << ':' << b.size << ','
+ << "THUMB_BREAKPOINT" << ':' << b.thumb
+ << '}';
+ return str;
+}
+
+// --- Events
+TcfTrkEvent::TcfTrkEvent(Type type) : m_type(type)
+{
+}
+
+TcfTrkEvent::~TcfTrkEvent()
+{
+}
+
+TcfTrkEvent::Type TcfTrkEvent::type() const
+{
+ return m_type;
+}
+
+QString TcfTrkEvent::toString() const
+{
+ return QString();
+}
+
+static const char sharedLibrarySuspendReasonC[] = "Shared Library";
+
+TcfTrkEvent *TcfTrkEvent::parseEvent(Services s, const QByteArray &nameBA, const QVector<JsonValue> &values)
+{
+ switch (s) {
+ case LocatorService:
+ if (nameBA == "Hello" && values.size() == 1 && values.front().type() == JsonValue::Array) {
+ QStringList services;
+ foreach (const JsonValue &jv, values.front().children())
+ services.push_back(QString::fromUtf8(jv.data()));
+ return new TcfTrkLocatorHelloEvent(services);
+ }
+ break;
+ case RunControlService:
+ if (values.empty())
+ return 0;
+ // "id/PC/Reason/Data"
+ if (nameBA == "contextSuspended" && values.size() == 4) {
+ const QByteArray idBA = values.at(0).data();
+ const quint64 pc = values.at(1).data().toULongLong();
+ const QByteArray reasonBA = values.at(2).data();
+ // Module load: Special
+ if (reasonBA == sharedLibrarySuspendReasonC) {
+ ModuleLoadEventInfo info;
+ if (!info.parse(values.at(3)))
+ return 0;
+ return new TcfTrkRunControlModuleLoadContextSuspendedEvent(idBA, reasonBA, pc, info);
+ }
+ return new TcfTrkRunControlContextSuspendedEvent(idBA, reasonBA, pc);
+ } // "contextSuspended"
+ if (nameBA == "contextAdded")
+ return TcfTrkRunControlContextAddedEvent::parseEvent(values);
+ if (nameBA == "contextRemoved" && values.front().type() == JsonValue::Array) {
+ QVector<QByteArray> ids;
+ foreach(const JsonValue &c, values.front().children())
+ ids.push_back(c.data());
+ return new TcfTrkRunControlContextRemovedEvent(ids);
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+// -------------- TcfTrkServiceHelloEvent
+TcfTrkLocatorHelloEvent::TcfTrkLocatorHelloEvent(const QStringList &s) :
+ TcfTrkEvent(LocatorHello),
+ m_services(s)
+{
+}
+
+QString TcfTrkLocatorHelloEvent::toString() const
+{
+ return QLatin1String("ServiceHello: ") + m_services.join(QLatin1String(", "));
+}
+
+// -------------- TcfTrkIdEvent
+TcfTrkIdEvent::TcfTrkIdEvent(Type t, const QByteArray &id) :
+ TcfTrkEvent(t), m_id(id)
+{
+}
+
+// ---------- TcfTrkIdsEvent
+TcfTrkIdsEvent::TcfTrkIdsEvent(Type t, const QVector<QByteArray> &ids) :
+ TcfTrkEvent(t), m_ids(ids)
+{
+}
+
+QString TcfTrkIdsEvent::joinedIdString(const char sep) const
+{
+ return joinByteArrays(m_ids, sep);
+}
+
+// ---------------- TcfTrkRunControlContextAddedEvent
+TcfTrkRunControlContextAddedEvent::TcfTrkRunControlContextAddedEvent(const RunControlContexts &c) :
+ TcfTrkEvent(RunControlContextAdded), m_contexts(c)
+{
+}
+
+TcfTrkRunControlContextAddedEvent
+ *TcfTrkRunControlContextAddedEvent::parseEvent(const QVector<JsonValue> &values)
+{
+ // Parse array of contexts
+ if (values.size() < 1 || values.front().type() != JsonValue::Array)
+ return 0;
+
+ RunControlContexts contexts;
+ foreach (const JsonValue &v, values.front().children()) {
+ RunControlContext context;
+ if (context.parse(v))
+ contexts.push_back(context);
+ }
+ return new TcfTrkRunControlContextAddedEvent(contexts);
+}
+
+QString TcfTrkRunControlContextAddedEvent::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << "RunControl: " << m_contexts.size() << " context(s) "
+ << (type() == RunControlContextAdded ? "added" : "removed")
+ << '\n';
+ foreach (const RunControlContext &c, m_contexts) {
+ c.format(str);
+ str << '\n';
+ }
+ return rc;
+}
+
+// --------------- TcfTrkRunControlContextRemovedEvent
+TcfTrkRunControlContextRemovedEvent::TcfTrkRunControlContextRemovedEvent(const QVector<QByteArray> &ids) :
+ TcfTrkIdsEvent(RunControlContextRemoved, ids)
+{
+}
+
+QString TcfTrkRunControlContextRemovedEvent::toString() const
+{
+ return QLatin1String("RunControl: Removed contexts '") + joinedIdString() + ("'.");
+}
+
+// --------------- TcfTrkRunControlContextSuspendedEvent
+TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc) :
+ TcfTrkIdEvent(RunControlSuspended, id), m_pc(pc), m_reason(reason)
+{
+}
+
+TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(Type t,
+ const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc) :
+ TcfTrkIdEvent(t, id), m_pc(pc), m_reason(reason)
+{
+}
+
+void TcfTrkRunControlContextSuspendedEvent::format(QTextStream &str) const
+{
+ str.setIntegerBase(16);
+ str << "RunControl: '" << idString() << "' suspended at 0x"
+ << m_pc << ": '" << m_reason << "'.";
+ str.setIntegerBase(10);
+}
+
+QString TcfTrkRunControlContextSuspendedEvent::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ format(str);
+ return rc;
+}
+
+TcfTrkRunControlContextSuspendedEvent::Reason TcfTrkRunControlContextSuspendedEvent::reason() const
+{
+ if (m_reason == sharedLibrarySuspendReasonC)
+ return ModuleLoad;
+ if (m_reason == "Breakpoint")
+ return BreakPoint;
+ // 'Data abort exception'/'Thread has panicked' ... unfortunately somewhat unspecific.
+ if (m_reason.contains("exception") || m_reason.contains("panick"))
+ return Crash;
+ return Other;
+}
+
+TcfTrkRunControlModuleLoadContextSuspendedEvent::TcfTrkRunControlModuleLoadContextSuspendedEvent(const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc,
+ const ModuleLoadEventInfo &mi) :
+ TcfTrkRunControlContextSuspendedEvent(RunControlModuleLoadSuspended, id, reason, pc),
+ m_mi(mi)
+{
+}
+
+QString TcfTrkRunControlModuleLoadContextSuspendedEvent::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ TcfTrkRunControlContextSuspendedEvent::format(str);
+ str << ' ';
+ m_mi.format(str);
+ return rc;
+}
+
+
+} // namespace tcftrk
diff --git a/src/runonphone/symbianutils/tcftrkmessage.h b/src/runonphone/symbianutils/tcftrkmessage.h
new file mode 100644
index 000000000..f2c8022e3
--- /dev/null
+++ b/src/runonphone/symbianutils/tcftrkmessage.h
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRCFTRKMESSAGE_H
+#define TRCFTRKMESSAGE_H
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+class QTextStream;
+QT_END_NAMESPACE
+
+namespace tcftrk {
+
+class JsonValue;
+class JsonInputStream;
+
+enum Services {
+ LocatorService,
+ RunControlService,
+ ProcessesService,
+ MemoryService,
+ SettingsService, // non-standard, trk specific
+ BreakpointsService,
+ RegistersService,
+ SimpleRegistersService, // non-standard, trk specific
+ UnknownService
+}; // Note: Check string array 'serviceNamesC' of same size when modifying this.
+
+// Modes of RunControl/'Resume' (see EDF documentation).
+// As of 24.6.2010, RM_RESUME, RM_STEP_OVER, RM_STEP_INTO,
+// RM_STEP_OVER_RANGE, RM_STEP_INTO_RANGE are supported with
+// RANG_START/RANGE_END parameters.
+enum RunControlResumeMode {
+ RM_RESUME = 0,
+ RM_STEP_OVER = 1, RM_STEP_INTO = 2,
+ RM_STEP_OVER_LINE = 3, RM_STEP_INTO_LINE = 4,
+ RM_STEP_OUT = 5, RM_REVERSE_RESUME = 6,
+ RM_REVERSE_STEP_OVER = 7, RM_REVERSE_STEP_INTO = 8,
+ RM_REVERSE_STEP_OVER_LINE = 9, RM_REVERSE_STEP_INTO_LINE = 10,
+ RM_REVERSE_STEP_OUT = 11, RM_STEP_OVER_RANGE = 12,
+ RM_STEP_INTO_RANGE = 13, RM_REVERSE_STEP_OVER_RANGE = 14,
+ RM_REVERSE_STEP_INTO_RANGE = 15
+};
+
+SYMBIANUTILS_EXPORT const char *serviceName(Services s);
+SYMBIANUTILS_EXPORT Services serviceFromName(const char *);
+
+// Debug helpers
+SYMBIANUTILS_EXPORT QString formatData(const QByteArray &a);
+SYMBIANUTILS_EXPORT QString joinByteArrays(const QVector<QByteArray> &a, char sep = ',');
+
+// Context used in 'RunControl contextAdded' events and in reply
+// to 'Processes start'. Could be thread or process.
+struct SYMBIANUTILS_EXPORT RunControlContext {
+ enum Flags {
+ Container = 0x1, HasState = 0x2, CanSuspend = 0x4,
+ CanTerminate = 0x8
+ };
+ enum Type { Process, Thread };
+
+ RunControlContext();
+ Type type() const;
+ unsigned processId() const;
+ unsigned threadId() const;
+
+ void clear();
+ bool parse(const JsonValue &v);
+ void format(QTextStream &str) const;
+ QString toString() const;
+
+ // Helper for converting the TCF ids ("p12" or "p12.t34")
+ static Type typeFromTcfId(const QByteArray &id);
+ static unsigned processIdFromTcdfId(const QByteArray &id);
+ static unsigned threadIdFromTcdfId(const QByteArray &id);
+ static QByteArray tcfId(unsigned processId, unsigned threadId = 0);
+
+ unsigned flags;
+ unsigned resumeFlags;
+ QByteArray id; // "p434.t699"
+ QByteArray osid; // Non-standard: Process or thread id
+ QByteArray parentId; // Parent process id of a thread.
+};
+
+// Module load information occurring with 'RunControl contextSuspended' events
+struct SYMBIANUTILS_EXPORT ModuleLoadEventInfo {
+ ModuleLoadEventInfo();
+ void clear();
+ bool parse(const JsonValue &v);
+ void format(QTextStream &str) const;
+
+ QByteArray name;
+ QByteArray file;
+ bool loaded;
+ quint64 codeAddress;
+ quint64 dataAddress;
+ bool requireResume;
+};
+
+// Breakpoint as supported by TcfTrk source June 2010
+// TODO: Add watchpoints,etc once they are implemented
+struct SYMBIANUTILS_EXPORT Breakpoint {
+ enum Type { Software, Hardware, Auto };
+
+ explicit Breakpoint(quint64 loc = 0);
+ void setContextId(unsigned processId, unsigned threadId = 0);
+ QString toString() const;
+
+ static QByteArray idFromLocation(quint64 loc); // Automagically determine from location
+
+ Type type;
+ bool enabled;
+ int ignoreCount;
+ QVector<QByteArray> contextIds; // Process or thread ids.
+ QByteArray id; // Id of the breakpoint;
+ quint64 location;
+ unsigned size;
+ bool thumb;
+};
+
+SYMBIANUTILS_EXPORT JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b);
+
+// Event hierarchy
+class SYMBIANUTILS_EXPORT TcfTrkEvent {
+ Q_DISABLE_COPY(TcfTrkEvent)
+public:
+ enum Type { None,
+ LocatorHello,
+ RunControlContextAdded,
+ RunControlContextRemoved,
+ RunControlSuspended,
+ RunControlBreakpointSuspended,
+ RunControlModuleLoadSuspended,
+ RunControlResumed
+ };
+
+ virtual ~TcfTrkEvent();
+
+ Type type() const;
+ virtual QString toString() const;
+
+ static TcfTrkEvent *parseEvent(Services s, const QByteArray &name, const QVector<JsonValue> &val);
+
+protected:
+ explicit TcfTrkEvent(Type type = None);
+
+private:
+ const Type m_type;
+};
+
+// ServiceHello
+class SYMBIANUTILS_EXPORT TcfTrkLocatorHelloEvent : public TcfTrkEvent {
+public:
+ explicit TcfTrkLocatorHelloEvent(const QStringList &);
+
+ const QStringList &services() { return m_services; }
+ virtual QString toString() const;
+
+private:
+ QStringList m_services;
+};
+
+// Base for events that just have one id as parameter
+// (simple suspend)
+class SYMBIANUTILS_EXPORT TcfTrkIdEvent : public TcfTrkEvent {
+protected:
+ explicit TcfTrkIdEvent(Type t, const QByteArray &id);
+public:
+ QByteArray id() const { return m_id; }
+ QString idString() const { return QString::fromUtf8(m_id); }
+
+private:
+ const QByteArray m_id;
+};
+
+// Base for events that just have some ids as parameter
+// (context removed)
+class SYMBIANUTILS_EXPORT TcfTrkIdsEvent : public TcfTrkEvent {
+protected:
+ explicit TcfTrkIdsEvent(Type t, const QVector<QByteArray> &ids);
+
+public:
+ QVector<QByteArray> ids() const { return m_ids; }
+ QString joinedIdString(const char sep = ',') const;
+
+private:
+ const QVector<QByteArray> m_ids;
+};
+
+// RunControlContextAdded
+class SYMBIANUTILS_EXPORT TcfTrkRunControlContextAddedEvent : public TcfTrkEvent {
+public:
+ typedef QVector<RunControlContext> RunControlContexts;
+
+ explicit TcfTrkRunControlContextAddedEvent(const RunControlContexts &c);
+
+ const RunControlContexts &contexts() const { return m_contexts; }
+ virtual QString toString() const;
+
+ static TcfTrkRunControlContextAddedEvent *parseEvent(const QVector<JsonValue> &val);
+
+private:
+ const RunControlContexts m_contexts;
+};
+
+// RunControlContextRemoved
+class SYMBIANUTILS_EXPORT TcfTrkRunControlContextRemovedEvent : public TcfTrkIdsEvent {
+public:
+ explicit TcfTrkRunControlContextRemovedEvent(const QVector<QByteArray> &id);
+ virtual QString toString() const;
+};
+
+// Simple RunControlContextSuspended (process/thread)
+class SYMBIANUTILS_EXPORT TcfTrkRunControlContextSuspendedEvent : public TcfTrkIdEvent {
+public:
+ enum Reason { BreakPoint, ModuleLoad, Crash, Other } ;
+
+ explicit TcfTrkRunControlContextSuspendedEvent(const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc = 0);
+ virtual QString toString() const;
+
+ quint64 pc() const { return m_pc; }
+ QByteArray reasonID() const { return m_reason; }
+ Reason reason() const;
+
+protected:
+ explicit TcfTrkRunControlContextSuspendedEvent(Type t,
+ const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc = 0);
+ void format(QTextStream &str) const;
+
+private:
+ const quint64 m_pc;
+ const QByteArray m_reason;
+};
+
+// RunControlContextSuspended due to module load
+class SYMBIANUTILS_EXPORT TcfTrkRunControlModuleLoadContextSuspendedEvent : public TcfTrkRunControlContextSuspendedEvent {
+public:
+ explicit TcfTrkRunControlModuleLoadContextSuspendedEvent(const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc,
+ const ModuleLoadEventInfo &mi);
+
+ virtual QString toString() const;
+ const ModuleLoadEventInfo &info() const { return m_mi; }
+
+private:
+ const ModuleLoadEventInfo m_mi;
+};
+
+} // namespace tcftrk
+#endif // TRCFTRKMESSAGE_H
diff --git a/src/runonphone/symbianutils/trkdevice.cpp b/src/runonphone/symbianutils/trkdevice.cpp
new file mode 100644
index 000000000..2825b5f9b
--- /dev/null
+++ b/src/runonphone/symbianutils/trkdevice.cpp
@@ -0,0 +1,1184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "trkdevice.h"
+#include "trkutils.h"
+#include "trkutils_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+#include <QtCore/QQueue>
+#include <QtCore/QHash>
+#include <QtCore/QMap>
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtCore/QWaitCondition>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QMetaType>
+
+#ifdef Q_OS_WIN
+# include <windows.h>
+#else
+# include <QtCore/QFile>
+
+# include <stdio.h>
+# include <sys/ioctl.h>
+# include <sys/types.h>
+# include <termios.h>
+# include <errno.h>
+# include <string.h>
+# include <unistd.h>
+/* Required headers for select() according to POSIX.1-2001 */
+# include <sys/select.h>
+/* Required headers for select() according to earlier standards:
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+*/
+#endif
+
+#ifdef Q_OS_WIN
+
+// Format windows error from GetLastError() value:
+// TODO: Use the one provided by the utils lib.
+QString winErrorMessage(unsigned long error)
+{
+ QString rc = QString::fromLatin1("#%1: ").arg(error);
+ ushort *lpMsgBuf;
+
+ const int len = FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, error, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
+ if (len) {
+ rc = QString::fromUtf16(lpMsgBuf, len);
+ LocalFree(lpMsgBuf);
+ } else {
+ rc += QString::fromLatin1("<unknown error>");
+ }
+ return rc;
+}
+
+#endif
+
+enum { verboseTrk = 0 };
+
+static inline QString msgAccessingClosedDevice(const QString &msg)
+{
+ return QString::fromLatin1("Error: Attempt to access device '%1', which is closed.").arg(msg);
+}
+
+namespace trk {
+
+///////////////////////////////////////////////////////////////////////
+//
+// TrkMessage
+//
+///////////////////////////////////////////////////////////////////////
+
+/* A message to be send to TRK, triggering a callback on receipt
+ * of the answer. */
+struct TrkMessage
+{
+ explicit TrkMessage(byte code = 0u, byte token = 0u,
+ TrkCallback callback = TrkCallback());
+
+ byte code;
+ byte token;
+ QByteArray data;
+ QVariant cookie;
+ TrkCallback callback;
+};
+
+TrkMessage::TrkMessage(byte c, byte t, TrkCallback cb) :
+ code(c),
+ token(t),
+ callback(cb)
+{
+}
+
+QDebug operator<<(QDebug d, const TrkMessage &msg)
+{
+ return d << "Message: Code: " << msg.code
+ << " Token: " << msg.token << " " << msg.data.toHex();
+}
+
+} // namespace trk
+
+Q_DECLARE_METATYPE(trk::TrkMessage)
+Q_DECLARE_METATYPE(trk::TrkResult)
+
+namespace trk {
+
+///////////////////////////////////////////////////////////////////////
+//
+// TrkWriteQueue: Mixin class that manages a write queue of Trk messages.
+// pendingMessage()/notifyWriteResult() should be called from a worked/timer
+// that writes the messages. The class does not take precautions for multithreading.
+// A no-op message is simply taken off the queue. The calling class
+// can use the helper invokeNoopMessage() to trigger its callback.
+//
+///////////////////////////////////////////////////////////////////////
+
+class TrkWriteQueue
+{
+ Q_DISABLE_COPY(TrkWriteQueue)
+public:
+ explicit TrkWriteQueue();
+ void clear();
+
+ // Enqueue messages.
+ void queueTrkMessage(byte code, TrkCallback callback,
+ const QByteArray &data, const QVariant &cookie);
+ void queueTrkInitialPing();
+
+ // Call this from the device read notification with the results.
+ void slotHandleResult(const TrkResult &result, QMutex *mutex = 0);
+
+ // pendingMessage() can be called periodically in a timer to retrieve
+ // the pending messages to be sent.
+ enum PendingMessageResult {
+ NoMessage, // No message in queue.
+ PendingMessage, /* There is a queued message. The calling class
+ * can write it out and use notifyWriteResult()
+ * to notify about the result. */
+ NoopMessageDequeued // A no-op message has been dequeued. see invokeNoopMessage().
+ };
+
+ PendingMessageResult pendingMessage(TrkMessage *message);
+ // Notify the queue about the success of the write operation
+ // after taking the pendingMessage off.
+ enum WriteResult {
+ WriteOk,
+ WriteFailedDiscard, // Discard failed message
+ WriteFailedKeep, // Keep failed message
+ };
+ void notifyWriteResult(WriteResult ok);
+
+ // Helper function that invokes the callback of a no-op message
+ static void invokeNoopMessage(trk::TrkMessage);
+
+private:
+ typedef QMap<byte, TrkMessage> TokenMessageMap;
+
+ byte nextTrkWriteToken();
+
+ byte m_trkWriteToken;
+ QQueue<TrkMessage> m_trkWriteQueue;
+ TokenMessageMap m_writtenTrkMessages;
+ bool m_trkWriteBusy;
+};
+
+TrkWriteQueue::TrkWriteQueue() :
+ m_trkWriteToken(0),
+ m_trkWriteBusy(false)
+{
+}
+
+void TrkWriteQueue::clear()
+{
+ m_trkWriteToken = 0;
+ m_trkWriteBusy = false;
+ m_trkWriteQueue.clear();
+ const int discarded = m_writtenTrkMessages.size();
+ m_writtenTrkMessages.clear();
+ if (verboseTrk)
+ qDebug() << "TrkWriteQueue::clear: discarded " << discarded;
+}
+
+byte TrkWriteQueue::nextTrkWriteToken()
+{
+ ++m_trkWriteToken;
+ if (m_trkWriteToken == 0)
+ ++m_trkWriteToken;
+ if (verboseTrk)
+ qDebug() << "nextTrkWriteToken:" << m_trkWriteToken;
+ return m_trkWriteToken;
+}
+
+void TrkWriteQueue::queueTrkMessage(byte code, TrkCallback callback,
+ const QByteArray &data, const QVariant &cookie)
+{
+ const byte token = code == TRK_WRITE_QUEUE_NOOP_CODE ?
+ byte(0) : nextTrkWriteToken();
+ TrkMessage msg(code, token, callback);
+ msg.data = data;
+ msg.cookie = cookie;
+ m_trkWriteQueue.append(msg);
+}
+
+TrkWriteQueue::PendingMessageResult TrkWriteQueue::pendingMessage(TrkMessage *message)
+{
+ // Invoked from timer, try to flush out message queue
+ if (m_trkWriteBusy || m_trkWriteQueue.isEmpty())
+ return NoMessage;
+ // Handle the noop message, just invoke CB in slot (ower thread)
+ if (m_trkWriteQueue.front().code == TRK_WRITE_QUEUE_NOOP_CODE) {
+ *message = m_trkWriteQueue.dequeue();
+ return NoopMessageDequeued;
+ }
+ // Insert into map fir answers (as reading threads might get an
+ // answer before notifyWriteResult(true)) is called.
+ *message = m_trkWriteQueue.front();
+ m_writtenTrkMessages.insert(message->token, *message);
+ m_trkWriteBusy = true;
+ return PendingMessage;
+}
+
+void TrkWriteQueue::invokeNoopMessage(trk::TrkMessage noopMessage)
+{
+ TrkResult result;
+ result.code = noopMessage.code;
+ result.token = noopMessage.token;
+ result.data = noopMessage.data;
+ result.cookie = noopMessage.cookie;
+ noopMessage.callback(result);
+}
+
+void TrkWriteQueue::notifyWriteResult(WriteResult wr)
+{
+ // On success, dequeue message and await result
+ const byte token = m_trkWriteQueue.front().token;
+ switch (wr) {
+ case WriteOk:
+ m_trkWriteQueue.dequeue();
+ break;
+ case WriteFailedKeep:
+ case WriteFailedDiscard:
+ m_writtenTrkMessages.remove(token);
+ m_trkWriteBusy = false;
+ if (wr == WriteFailedDiscard)
+ m_trkWriteQueue.dequeue();
+ break;
+ }
+}
+
+void TrkWriteQueue::slotHandleResult(const TrkResult &result, QMutex *mutex)
+{
+ // Find which request the message belongs to and invoke callback
+ // if ACK or on NAK if desired.
+ if (mutex)
+ mutex->lock();
+ m_trkWriteBusy = false;
+ const TokenMessageMap::iterator it = m_writtenTrkMessages.find(result.token);
+ if (it == m_writtenTrkMessages.end()) {
+ if (mutex)
+ mutex->unlock();
+ return;
+ }
+ TrkCallback callback = it.value().callback;
+ const QVariant cookie = it.value().cookie;
+ m_writtenTrkMessages.erase(it);
+ if (mutex)
+ mutex->unlock();
+ // Invoke callback
+ if (callback) {
+ TrkResult result1 = result;
+ result1.cookie = cookie;
+ callback(result1);
+ }
+}
+
+void TrkWriteQueue::queueTrkInitialPing()
+{
+ // Ping, reset sequence count
+ m_trkWriteToken = 0;
+ m_trkWriteQueue.append(TrkMessage(TrkPing, 0));
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// DeviceContext to be shared between threads
+//
+///////////////////////////////////////////////////////////////////////
+
+struct DeviceContext {
+ DeviceContext();
+#ifdef Q_OS_WIN
+ HANDLE device;
+ OVERLAPPED readOverlapped;
+ OVERLAPPED writeOverlapped;
+#else
+ QFile file;
+#endif
+ bool serialFrame;
+ QMutex mutex;
+};
+
+DeviceContext::DeviceContext() :
+#ifdef Q_OS_WIN
+ device(INVALID_HANDLE_VALUE),
+#endif
+ serialFrame(true)
+{
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// TrkWriterThread: A thread operating a TrkWriteQueue.
+// with exception of the handling of the TRK_WRITE_QUEUE_NOOP_CODE
+// synchronization message. The invocation of the callback is then
+// done by the thread owning the TrkWriteQueue, while pendingMessage() is called
+// from another thread. This happens via a Qt::BlockingQueuedConnection.
+
+///////////////////////////////////////////////////////////////////////
+
+class WriterThread : public QThread
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(WriterThread)
+public:
+ explicit WriterThread(const QSharedPointer<DeviceContext> &context);
+
+ // Enqueue messages.
+ void queueTrkMessage(byte code, TrkCallback callback,
+ const QByteArray &data, const QVariant &cookie);
+ void queueTrkInitialPing();
+
+ void clearWriteQueue();
+
+ // Call this from the device read notification with the results.
+ void slotHandleResult(const TrkResult &result);
+
+ virtual void run();
+
+signals:
+ void error(const QString &);
+ void internalNoopMessageDequeued(const trk::TrkMessage&);
+
+public slots:
+ bool trkWriteRawMessage(const TrkMessage &msg);
+ void terminate();
+ void tryWrite();
+
+private slots:
+ void invokeNoopMessage(const trk::TrkMessage &);
+
+private:
+ bool write(const QByteArray &data, QString *errorMessage);
+ inline int writePendingMessage();
+
+ const QSharedPointer<DeviceContext> m_context;
+ QMutex m_dataMutex;
+ QMutex m_waitMutex;
+ QWaitCondition m_waitCondition;
+ TrkWriteQueue m_queue;
+ bool m_terminate;
+};
+
+WriterThread::WriterThread(const QSharedPointer<DeviceContext> &context) :
+ m_context(context),
+ m_terminate(false)
+{
+ static const int trkMessageMetaId = qRegisterMetaType<trk::TrkMessage>();
+ Q_UNUSED(trkMessageMetaId)
+ connect(this, SIGNAL(internalNoopMessageDequeued(trk::TrkMessage)),
+ this, SLOT(invokeNoopMessage(trk::TrkMessage)), Qt::BlockingQueuedConnection);
+}
+
+void WriterThread::run()
+{
+ while (writePendingMessage() == 0) ;
+}
+
+int WriterThread::writePendingMessage()
+{
+ enum { MaxAttempts = 100, RetryIntervalMS = 200 };
+
+ // Wait. Use a timeout in case something is already queued before we
+ // start up or some weird hanging exit condition
+ m_waitMutex.lock();
+ m_waitCondition.wait(&m_waitMutex, 100);
+ m_waitMutex.unlock();
+ if (m_terminate)
+ return 1;
+
+ // Send off message
+ m_dataMutex.lock();
+ TrkMessage message;
+ const TrkWriteQueue::PendingMessageResult pr = m_queue.pendingMessage(&message);
+ m_dataMutex.unlock();
+
+ switch (pr) {
+ case TrkWriteQueue::NoMessage:
+ break;
+ case TrkWriteQueue::PendingMessage: {
+ //qDebug() << "Write pending message " << message;
+ // Untested: try to re-send a few times
+ bool success = false;
+ for (int r = 0; !success && (r < MaxAttempts); r++) {
+ success = trkWriteRawMessage(message);
+ if (!success) {
+ emit error(QString::fromLatin1("Write failure, attempt %1 of %2.").arg(r).arg(int(MaxAttempts)));
+ if (m_terminate)
+ return 1;
+ QThread::msleep(RetryIntervalMS);
+ }
+ }
+ // Notify queue. If still failed, give up.
+ m_dataMutex.lock();
+ m_queue.notifyWriteResult(success ? TrkWriteQueue::WriteOk : TrkWriteQueue::WriteFailedDiscard);
+ m_dataMutex.unlock();
+ }
+ break;
+ case TrkWriteQueue::NoopMessageDequeued:
+ // Sync with thread that owns us via a blocking signal
+ if (verboseTrk)
+ qDebug() << "Noop message dequeued" << message;
+ emit internalNoopMessageDequeued(message);
+ break;
+ } // switch
+ return 0;
+}
+
+void WriterThread::invokeNoopMessage(const trk::TrkMessage &msg)
+{
+ TrkWriteQueue::invokeNoopMessage(msg);
+}
+
+void WriterThread::terminate()
+{
+ m_terminate = true;
+ m_waitCondition.wakeAll();
+ wait();
+ m_terminate = false;
+ m_queue.clear();
+}
+
+#ifdef Q_OS_WIN
+
+static inline QString msgTerminated(int size)
+{
+ return QString::fromLatin1("Terminated with %1 bytes pending.").arg(size);
+}
+
+// Interruptible synchronous write function.
+static inline bool overlappedSyncWrite(HANDLE file,
+ const bool &terminateFlag,
+ const char *data,
+ DWORD size, DWORD *charsWritten,
+ OVERLAPPED *overlapped,
+ QString *errorMessage)
+{
+ if (WriteFile(file, data, size, charsWritten, overlapped))
+ return true;
+ const DWORD writeError = GetLastError();
+ if (writeError != ERROR_IO_PENDING) {
+ *errorMessage = QString::fromLatin1("WriteFile failed: %1").arg(winErrorMessage(writeError));
+ return false;
+ }
+ // Wait for written or thread terminated
+ const DWORD timeoutMS = 200;
+ const unsigned maxAttempts = 20;
+ DWORD wr = WaitForSingleObject(overlapped->hEvent, timeoutMS);
+ for (unsigned n = 0; wr == WAIT_TIMEOUT && n < maxAttempts && !terminateFlag;
+ wr = WaitForSingleObject(overlapped->hEvent, timeoutMS), n++);
+ if (terminateFlag) {
+ *errorMessage = msgTerminated(size);
+ return false;
+ }
+ switch (wr) {
+ case WAIT_OBJECT_0:
+ break;
+ case WAIT_TIMEOUT:
+ *errorMessage = QString::fromLatin1("Write timed out.");
+ return false;
+ default:
+ *errorMessage = QString::fromLatin1("Error while waiting for WriteFile results: %1").arg(winErrorMessage(GetLastError()));
+ return false;
+ }
+ if (!GetOverlappedResult(file, overlapped, charsWritten, TRUE)) {
+ *errorMessage = QString::fromLatin1("Error writing %1 bytes: %2").arg(size).arg(winErrorMessage(GetLastError()));
+ return false;
+ }
+ return true;
+}
+#endif
+
+bool WriterThread::write(const QByteArray &data, QString *errorMessage)
+{
+ if (verboseTrk)
+ qDebug() << "Write raw data: " << stringFromArray(data).toLatin1();
+ QMutexLocker locker(&m_context->mutex);
+#ifdef Q_OS_WIN
+ DWORD charsWritten;
+ if (!overlappedSyncWrite(m_context->device, m_terminate, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped, errorMessage)) {
+ return false;
+ }
+ FlushFileBuffers(m_context->device);
+ return true;
+#else
+ if (m_context->file.write(data) == -1 || !m_context->file.flush()) {
+ *errorMessage = QString::fromLatin1("Cannot write: %1").arg(m_context->file.errorString());
+ return false;
+ }
+ return true;
+#endif
+}
+
+bool WriterThread::trkWriteRawMessage(const TrkMessage &msg)
+{
+ const QByteArray ba = frameMessage(msg.code, msg.token, msg.data, m_context->serialFrame);
+ QString errorMessage;
+ const bool rc = write(ba, &errorMessage);
+ if (!rc) {
+ qWarning("%s\n", qPrintable(errorMessage));
+ emit error(errorMessage);
+ }
+ return rc;
+}
+
+void WriterThread::tryWrite()
+{
+ m_waitCondition.wakeAll();
+}
+
+void WriterThread::queueTrkMessage(byte code, TrkCallback callback,
+ const QByteArray &data, const QVariant &cookie)
+{
+ m_dataMutex.lock();
+ m_queue.queueTrkMessage(code, callback, data, cookie);
+ m_dataMutex.unlock();
+ tryWrite();
+}
+
+void WriterThread::clearWriteQueue()
+{
+ m_dataMutex.lock();
+ m_queue.clear();
+ m_dataMutex.unlock();
+}
+
+void WriterThread::queueTrkInitialPing()
+{
+ m_dataMutex.lock();
+ m_queue.queueTrkInitialPing();
+ m_dataMutex.unlock();
+ tryWrite();
+}
+
+// Call this from the device read notification with the results.
+void WriterThread::slotHandleResult(const TrkResult &result)
+{
+ m_queue.slotHandleResult(result, &m_dataMutex);
+ tryWrite(); // Have messages been enqueued in-between?
+}
+
+
+///////////////////////////////////////////////////////////////////////
+//
+// ReaderThreadBase: Base class for a thread that reads data from
+// the device, decodes the messages and emit signals for the messages.
+// A Qt::BlockingQueuedConnection should be used for the message signal
+// to ensure messages are processed in the correct sequence.
+//
+///////////////////////////////////////////////////////////////////////
+
+class ReaderThreadBase : public QThread
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(ReaderThreadBase)
+public:
+
+ int bytesPending() const { return m_trkReadBuffer.size(); }
+
+signals:
+ void messageReceived(const trk::TrkResult &result, const QByteArray &rawData);
+
+protected:
+ explicit ReaderThreadBase(const QSharedPointer<DeviceContext> &context);
+ void processData(const QByteArray &a);
+ void processData(char c);
+
+ const QSharedPointer<DeviceContext> m_context;
+
+private:
+ void readMessages();
+
+ QByteArray m_trkReadBuffer;
+ bool linkEstablishmentMode;
+};
+
+ReaderThreadBase::ReaderThreadBase(const QSharedPointer<DeviceContext> &context) :
+ m_context(context), linkEstablishmentMode(true)
+{
+ static const int trkResultMetaId = qRegisterMetaType<trk::TrkResult>();
+ Q_UNUSED(trkResultMetaId)
+}
+
+void ReaderThreadBase::processData(const QByteArray &a)
+{
+ m_trkReadBuffer += a;
+ readMessages();
+}
+
+void ReaderThreadBase::processData(char c)
+{
+ m_trkReadBuffer += c;
+ if (m_trkReadBuffer.size() > 1)
+ readMessages();
+}
+
+void ReaderThreadBase::readMessages()
+{
+ TrkResult r;
+ QByteArray rawData;
+ while (extractResult(&m_trkReadBuffer, m_context->serialFrame, &r, linkEstablishmentMode, &rawData)) {
+ emit messageReceived(r, rawData);
+ }
+}
+
+#ifdef Q_OS_WIN
+///////////////////////////////////////////////////////////////////////
+//
+// WinReaderThread: A thread reading from the device using Windows API.
+// Waits on an overlapped I/O handle and an event that tells the thread to
+// terminate.
+//
+///////////////////////////////////////////////////////////////////////
+
+class WinReaderThread : public ReaderThreadBase
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(WinReaderThread)
+public:
+ explicit WinReaderThread(const QSharedPointer<DeviceContext> &context);
+ ~WinReaderThread();
+
+ virtual void run();
+
+signals:
+ void error(const QString &);
+
+public slots:
+ void terminate();
+
+private:
+ enum Handles { FileHandle, TerminateEventHandle, HandleCount };
+
+ inline int tryRead();
+
+ HANDLE m_handles[HandleCount];
+};
+
+WinReaderThread::WinReaderThread(const QSharedPointer<DeviceContext> &context) :
+ ReaderThreadBase(context)
+{
+ m_handles[FileHandle] = NULL;
+ m_handles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL);
+}
+
+WinReaderThread::~WinReaderThread()
+{
+ CloseHandle(m_handles[TerminateEventHandle]);
+}
+
+// Return 0 to continue or error code
+int WinReaderThread::tryRead()
+{
+ enum { BufSize = 1024 };
+ char buffer[BufSize];
+ // Check if there are already bytes waiting. If not, wait for first byte
+ COMSTAT comStat;
+ if (!ClearCommError(m_context->device, NULL, &comStat)){
+ emit error(QString::fromLatin1("ClearCommError failed: %1").arg(winErrorMessage(GetLastError())));
+ return -7;
+ }
+ const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize)));
+ // Trigger read
+ DWORD bytesRead = 0;
+ if (ReadFile(m_context->device, &buffer, bytesToRead, &bytesRead, &m_context->readOverlapped)) {
+ if (bytesRead == 1) {
+ processData(buffer[0]);
+ } else {
+ processData(QByteArray(buffer, bytesRead));
+ }
+ return 0;
+ }
+ const DWORD readError = GetLastError();
+ if (readError != ERROR_IO_PENDING) {
+ emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError)));
+ return -1;
+ }
+ // Wait for either termination or data
+ const DWORD wr = WaitForMultipleObjects(HandleCount, m_handles, false, INFINITE);
+ if (wr == WAIT_FAILED) {
+ emit error(QString::fromLatin1("Wait failed: %1").arg(winErrorMessage(GetLastError())));
+ return -2;
+ }
+ if (wr - WAIT_OBJECT_0 == TerminateEventHandle) {
+ return 1; // Terminate
+ }
+ // Check data
+ if (!GetOverlappedResult(m_context->device, &m_context->readOverlapped, &bytesRead, true)) {
+ emit error(QString::fromLatin1("GetOverlappedResult failed: %1").arg(winErrorMessage(GetLastError())));
+ return -3;
+ }
+ if (bytesRead == 1) {
+ processData(buffer[0]);
+ } else {
+ processData(QByteArray(buffer, bytesRead));
+ }
+ return 0;
+}
+
+void WinReaderThread::run()
+{
+ m_handles[FileHandle] = m_context->readOverlapped.hEvent;
+ while ( tryRead() == 0) ;
+}
+
+void WinReaderThread::terminate()
+{
+ SetEvent(m_handles[TerminateEventHandle]);
+ wait();
+}
+
+typedef WinReaderThread ReaderThread;
+
+#else
+
+///////////////////////////////////////////////////////////////////////
+//
+// UnixReaderThread: A thread reading from the device.
+// Uses select() to wait and a special ioctl() to find out the number
+// of bytes queued. For clean termination, the self-pipe trick is used.
+// The class maintains a pipe, on whose read end the select waits besides
+// the device file handle. To terminate, a byte is written to the pipe.
+//
+///////////////////////////////////////////////////////////////////////
+
+static inline QString msgUnixCallFailedErrno(const char *func, int errorNumber)
+{
+ return QString::fromLatin1("Call to %1() failed: %2").arg(QLatin1String(func), QString::fromLocal8Bit(strerror(errorNumber)));
+}
+
+class UnixReaderThread : public ReaderThreadBase {
+ Q_OBJECT
+ Q_DISABLE_COPY(UnixReaderThread)
+public:
+ explicit UnixReaderThread(const QSharedPointer<DeviceContext> &context);
+ ~UnixReaderThread();
+
+ virtual void run();
+
+signals:
+ void error(const QString &);
+
+public slots:
+ void terminate();
+
+private:
+ inline int tryRead();
+
+ int m_terminatePipeFileDescriptors[2];
+};
+
+UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) :
+ ReaderThreadBase(context)
+{
+ m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1;
+ // Set up pipes for termination. Should not fail
+ if (pipe(m_terminatePipeFileDescriptors) < 0)
+ qWarning("%s\n", qPrintable(msgUnixCallFailedErrno("pipe", errno)));
+}
+
+UnixReaderThread::~UnixReaderThread()
+{
+ close(m_terminatePipeFileDescriptors[0]);
+ close(m_terminatePipeFileDescriptors[1]);
+}
+
+int UnixReaderThread::tryRead()
+{
+ fd_set readSet, tempReadSet, tempExceptionSet;
+ struct timeval timeOut;
+ const int fileDescriptor = m_context->file.handle();
+ FD_ZERO(&readSet);
+ FD_SET(fileDescriptor, &readSet);
+ FD_SET(m_terminatePipeFileDescriptors[0], &readSet);
+ const int maxFileDescriptor = qMax(m_terminatePipeFileDescriptors[0], fileDescriptor);
+ int result = 0;
+ do {
+ memcpy(&tempReadSet, &readSet, sizeof(fd_set));
+ memcpy(&tempExceptionSet, &readSet, sizeof(fd_set));
+ timeOut.tv_sec = 1;
+ timeOut.tv_usec = 0;
+ result = select(maxFileDescriptor + 1, &tempReadSet, NULL, &tempExceptionSet, &timeOut);
+ } while ( result < 0 && errno == EINTR );
+ // Timeout?
+ if (result == 0)
+ return 0;
+ // Something wrong?
+ if (result < 0) {
+ emit error(msgUnixCallFailedErrno("select", errno));
+ return -1;
+ }
+ // Did the exception set trigger on the device?
+ if (FD_ISSET(fileDescriptor,&tempExceptionSet)) {
+ emit error(QLatin1String("An Exception occurred on the device."));
+ return -2;
+ }
+ // Check termination pipe.
+ if (FD_ISSET(m_terminatePipeFileDescriptors[0], &tempReadSet)
+ || FD_ISSET(m_terminatePipeFileDescriptors[0], &tempExceptionSet))
+ return 1;
+
+ // determine number of pending bytes and read
+ int numBytes;
+ if (ioctl(fileDescriptor, FIONREAD, &numBytes) < 0) {
+ emit error(msgUnixCallFailedErrno("ioctl", errno));
+ return -1;
+ }
+ m_context->mutex.lock();
+ const QByteArray data = m_context->file.read(numBytes);
+ m_context->mutex.unlock();
+ processData(data);
+ return 0;
+}
+
+void UnixReaderThread::run()
+{
+ // Read loop
+ while (tryRead() == 0)
+ ;
+}
+
+void UnixReaderThread::terminate()
+{
+ // Trigger select() by writing to the pipe
+ char c = 0;
+ const int written = write(m_terminatePipeFileDescriptors[1], &c, 1);
+ Q_UNUSED(written)
+ wait();
+}
+
+typedef UnixReaderThread ReaderThread;
+
+#endif
+
+///////////////////////////////////////////////////////////////////////
+//
+// TrkDevicePrivate
+//
+///////////////////////////////////////////////////////////////////////
+
+struct TrkDevicePrivate
+{
+ TrkDevicePrivate();
+
+ QSharedPointer<DeviceContext> deviceContext;
+ QScopedPointer<WriterThread> writerThread;
+ QScopedPointer<ReaderThread> readerThread;
+
+ QByteArray trkReadBuffer;
+ int verbose;
+ QString errorString;
+ QString port;
+};
+
+///////////////////////////////////////////////////////////////////////
+//
+// TrkDevice
+//
+///////////////////////////////////////////////////////////////////////
+
+TrkDevicePrivate::TrkDevicePrivate() :
+ deviceContext(new DeviceContext),
+ verbose(0)
+{
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// TrkDevice
+//
+///////////////////////////////////////////////////////////////////////
+
+TrkDevice::TrkDevice(QObject *parent) :
+ QObject(parent),
+ d(new TrkDevicePrivate)
+{}
+
+TrkDevice::~TrkDevice()
+{
+ close();
+ delete d;
+}
+
+bool TrkDevice::open(QString *errorMessage)
+{
+ if (d->verbose || verboseTrk)
+ qDebug() << "Opening" << port() << "is open: " << isOpen() << " serialFrame=" << serialFrame();
+ if (isOpen())
+ return true;
+ if (d->port.isEmpty()) {
+ *errorMessage = QLatin1String("Internal error: No port set on TrkDevice");
+ return false;
+ }
+#ifdef Q_OS_WIN
+ const QString fullPort = QLatin1String("\\\\.\\") + d->port;
+ d->deviceContext->device = CreateFile(reinterpret_cast<const WCHAR*>(fullPort.utf16()),
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ if (INVALID_HANDLE_VALUE == d->deviceContext->device) {
+ *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port(), winErrorMessage(GetLastError()));
+ return false;
+ }
+ memset(&d->deviceContext->readOverlapped, 0, sizeof(OVERLAPPED));
+ d->deviceContext->readOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ memset(&d->deviceContext->writeOverlapped, 0, sizeof(OVERLAPPED));
+ d->deviceContext->writeOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (d->deviceContext->readOverlapped.hEvent == NULL || d->deviceContext->writeOverlapped.hEvent == NULL) {
+ *errorMessage = QString::fromLatin1("Failed to create events: %1").arg(winErrorMessage(GetLastError()));
+ return false;
+ }
+#else
+ d->deviceContext->file.setFileName(d->port);
+ if (!d->deviceContext->file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) {
+ *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(d->port, d->deviceContext->file.errorString());
+ return false;
+ }
+
+ struct termios termInfo;
+ if (tcgetattr(d->deviceContext->file.handle(), &termInfo) < 0) {
+ *errorMessage = QString::fromLatin1("Unable to retrieve terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno)));
+ return false;
+ }
+ // Turn off terminal echo as not get messages back, among other things
+ termInfo.c_cflag |= CREAD|CLOCAL;
+ termInfo.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG));
+ termInfo.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY));
+ termInfo.c_oflag &= (~OPOST);
+ termInfo.c_cc[VMIN] = 0;
+ termInfo.c_cc[VINTR] = _POSIX_VDISABLE;
+ termInfo.c_cc[VQUIT] = _POSIX_VDISABLE;
+ termInfo.c_cc[VSTART] = _POSIX_VDISABLE;
+ termInfo.c_cc[VSTOP] = _POSIX_VDISABLE;
+ termInfo.c_cc[VSUSP] = _POSIX_VDISABLE;
+ if (tcsetattr(d->deviceContext->file.handle(), TCSAFLUSH, &termInfo) < 0) {
+ *errorMessage = QString::fromLatin1("Unable to apply terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno)));
+ return false;
+ }
+#endif
+ d->readerThread.reset(new ReaderThread(d->deviceContext));
+ connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)),
+ Qt::QueuedConnection);
+ connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)),
+ this, SLOT(slotMessageReceived(trk::TrkResult,QByteArray)),
+ Qt::QueuedConnection);
+ d->readerThread->start();
+
+ d->writerThread.reset(new WriterThread(d->deviceContext));
+ connect(d->writerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)),
+ Qt::QueuedConnection);
+ d->writerThread->start();
+
+ if (d->verbose || verboseTrk)
+ qDebug() << "Opened" << d->port << d->readerThread.data() << d->writerThread.data();
+ return true;
+}
+
+void TrkDevice::close()
+{
+ if (verboseTrk)
+ qDebug() << "close" << d->port << " is open: " << isOpen()
+ << " read pending " << (d->readerThread.isNull() ? 0 : d->readerThread->bytesPending())
+ << sender();
+ if (!isOpen())
+ return;
+ if (d->readerThread)
+ d->readerThread->terminate();
+ if (d->writerThread)
+ d->writerThread->terminate();
+#ifdef Q_OS_WIN
+ CloseHandle(d->deviceContext->device);
+ d->deviceContext->device = INVALID_HANDLE_VALUE;
+ CloseHandle(d->deviceContext->readOverlapped.hEvent);
+ CloseHandle(d->deviceContext->writeOverlapped.hEvent);
+ d->deviceContext->readOverlapped.hEvent = d->deviceContext->writeOverlapped.hEvent = NULL;
+#else
+ d->deviceContext->file.close();
+#endif
+
+ if (d->verbose)
+ emitLogMessage("Close");
+}
+
+bool TrkDevice::isOpen() const
+{
+#ifdef Q_OS_WIN
+ return d->deviceContext->device != INVALID_HANDLE_VALUE;
+#else
+ return d->deviceContext->file.isOpen();
+#endif
+}
+
+QString TrkDevice::port() const
+{
+ return d->port;
+}
+
+void TrkDevice::setPort(const QString &p)
+{
+ if (verboseTrk)
+ qDebug() << "setPort" << p;
+ d->port = p;
+}
+
+QString TrkDevice::errorString() const
+{
+ return d->errorString;
+}
+
+bool TrkDevice::serialFrame() const
+{
+ return d->deviceContext->serialFrame;
+}
+
+void TrkDevice::setSerialFrame(bool f)
+{
+ if (verboseTrk)
+ qDebug() << "setSerialFrame" << f;
+ d->deviceContext->serialFrame = f;
+}
+
+int TrkDevice::verbose() const
+{
+ return d->verbose;
+}
+
+void TrkDevice::setVerbose(int b)
+{
+ d->verbose = b;
+}
+
+void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData)
+{
+ if (isOpen()) { // Might receive bytes after closing due to queued connections.
+ d->writerThread->slotHandleResult(result);
+ if (d->verbose > 1)
+ qDebug() << "Received: " << result.toString();
+ emit messageReceived(result);
+ if (!rawData.isEmpty())
+ emit rawDataReceived(rawData);
+ }
+}
+
+void TrkDevice::emitError(const QString &s)
+{
+ d->errorString = s;
+ qWarning("%s\n", qPrintable(s));
+ emit error(s);
+}
+
+void TrkDevice::clearWriteQueue()
+{
+ if (isOpen())
+ d->writerThread->clearWriteQueue();
+}
+
+void TrkDevice::sendTrkMessage(byte code, TrkCallback callback,
+ const QByteArray &data, const QVariant &cookie)
+{
+ if (!isOpen()) {
+ emitError(msgAccessingClosedDevice(d->port));
+ return;
+ }
+ if (!d->writerThread.isNull()) {
+ if (d->verbose > 1) {
+ QByteArray msg = "Sending: 0x";
+ msg += QByteArray::number(code, 16);
+ msg += ": ";
+ msg += stringFromArray(data).toLatin1();
+ if (cookie.isValid())
+ msg += " Cookie: " + cookie.toString().toLatin1();
+ qDebug("%s", msg.data());
+ }
+ d->writerThread->queueTrkMessage(code, callback, data, cookie);
+ }
+}
+
+void TrkDevice::sendTrkInitialPing()
+{
+ if (!isOpen()) {
+ emitError(msgAccessingClosedDevice(d->port));
+ return;
+ }
+ if (!d->writerThread.isNull())
+ d->writerThread->queueTrkInitialPing();
+}
+
+bool TrkDevice::sendTrkAck(byte token)
+{
+ if (!isOpen()) {
+ emitError(msgAccessingClosedDevice(d->port));
+ return false;
+ }
+ if (d->writerThread.isNull())
+ return false;
+ // The acknowledgement must not be queued!
+ TrkMessage msg(0x80, token);
+ msg.token = token;
+ msg.data.append('\0');
+ if (verboseTrk)
+ qDebug() << "Write synchroneous message: " << msg;
+ return d->writerThread->trkWriteRawMessage(msg);
+ // 01 90 00 07 7e 80 01 00 7d 5e 7e
+}
+
+void TrkDevice::emitLogMessage(const QString &msg)
+{
+ if (d->verbose)
+ qDebug("%s\n", qPrintable(msg));
+ emit logMessage(msg);
+}
+
+} // namespace trk
+
+#include "trkdevice.moc"
diff --git a/src/runonphone/symbianutils/trkdevice.h b/src/runonphone/symbianutils/trkdevice.h
new file mode 100644
index 000000000..bb54be520
--- /dev/null
+++ b/src/runonphone/symbianutils/trkdevice.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRKDEVICE_H
+#define TRKDEVICE_H
+
+#include "symbianutils_global.h"
+#include "callback.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+#include <QtCore/QByteArray>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+class QIODevice;
+QT_END_NAMESPACE
+
+namespace trk {
+
+struct TrkResult;
+struct TrkMessage;
+struct TrkDevicePrivate;
+
+/* TrkDevice: Implements a Windows COM or Linux device for
+ * Trk communications. Provides synchronous write and asynchronous
+ * read operation.
+ * The serialFrames property specifies whether packets are encapsulated in
+ * "0x90 <length>" frames, which is currently the case for serial ports.
+ * Contains a write message queue allowing
+ * for queueing messages with a notification callback. If the message receives
+ * an ACK, the callback is invoked.
+ * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronization.
+ * The respective message will not be sent, the callback is just invoked.
+ * Note that calling open/close in quick succession can cause crashes
+ * due to the use of queused signals. */
+
+enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f };
+
+typedef trk::Callback<const TrkResult &> TrkCallback;
+
+class SYMBIANUTILS_EXPORT TrkDevice : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame)
+ Q_PROPERTY(bool verbose READ verbose WRITE setVerbose)
+ Q_PROPERTY(QString port READ port WRITE setPort)
+public:
+ explicit TrkDevice(QObject *parent = 0);
+ virtual ~TrkDevice();
+
+ bool open(QString *errorMessage);
+ bool isOpen() const;
+
+ QString port() const;
+ void setPort(const QString &p);
+
+ QString errorString() const;
+
+ bool serialFrame() const;
+ void setSerialFrame(bool f);
+
+ int verbose() const;
+ void setVerbose(int b);
+
+ // Enqueue a message with a notification callback.
+ void sendTrkMessage(unsigned char code,
+ TrkCallback callBack = TrkCallback(),
+ const QByteArray &data = QByteArray(),
+ const QVariant &cookie = QVariant());
+
+ // Enqeue an initial ping
+ void sendTrkInitialPing();
+
+ // Send an Ack synchronously, bypassing the queue
+ bool sendTrkAck(unsigned char token);
+
+public slots:
+ void clearWriteQueue();
+
+signals:
+ void messageReceived(const trk::TrkResult &result);
+ // Emitted with the contents of messages enclosed in 07e, not for log output
+ void rawDataReceived(const QByteArray &data);
+ void error(const QString &msg);
+ void logMessage(const QString &msg);
+
+private slots:
+ void slotMessageReceived(const trk::TrkResult &result, const QByteArray &a);
+
+protected slots:
+ void emitError(const QString &msg);
+ void emitLogMessage(const QString &msg);
+
+public slots:
+ void close();
+
+private:
+ void readMessages();
+ TrkDevicePrivate *d;
+};
+
+} // namespace trk
+
+#endif // TRKDEVICE_H
diff --git a/src/runonphone/symbianutils/trkutils.cpp b/src/runonphone/symbianutils/trkutils.cpp
new file mode 100644
index 000000000..168f53960
--- /dev/null
+++ b/src/runonphone/symbianutils/trkutils.cpp
@@ -0,0 +1,603 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "trkutils.h"
+#include <ctype.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QDate>
+#include <QtCore/QDateTime>
+#include <QtCore/QTime>
+
+#define logMessage(s) do { qDebug() << "TRKCLIENT: " << s; } while (0)
+
+namespace trk {
+
+Library::Library() : codeseg(0), dataseg(0), pid(0)
+{
+}
+
+Library::Library(const TrkResult &result) : codeseg(0), dataseg(0), pid(0)
+{
+ if (result.data.size() < 20) {
+ qWarning("Invalid trk creation notification received.");
+ return;
+ }
+
+ const char *data = result.data.constData();
+ pid = extractInt(data + 2);
+ codeseg = extractInt(data + 10);
+ dataseg = extractInt(data + 14);
+ const uint len = extractShort(data + 18);
+ name = result.data.mid(20, len);
+}
+
+TrkAppVersion::TrkAppVersion()
+{
+ reset();
+}
+
+void TrkAppVersion::reset()
+{
+ trkMajor = trkMinor= protocolMajor = protocolMinor = 0;
+}
+
+Session::Session()
+{
+ reset();
+}
+
+void Session::reset()
+{
+ cpuMajor = 0;
+ cpuMinor = 0;
+ bigEndian = 0;
+ defaultTypeSize = 0;
+ fpTypeSize = 0;
+ extended1TypeSize = 0;
+ extended2TypeSize = 0;
+ pid = 0;
+ mainTid = 0;
+ tid = 0;
+ codeseg = 0;
+ dataseg = 0;
+
+ libraries.clear();
+ trkAppVersion.reset();
+}
+
+static QString formatCpu(int major, int minor)
+{
+ //: CPU description of an S60 device
+ //: %1 major verison, %2 minor version
+ //: %3 real name of major verison, %4 real name of minor version
+ const QString str = QCoreApplication::translate("trk::Session", "CPU: v%1.%2%3%4");
+ QString majorStr;
+ QString minorStr;
+ switch (major) {
+ case 0x04:
+ majorStr = " ARM";
+ break;
+ }
+ switch (minor) {
+ case 0x00:
+ minorStr = " 920T";
+ break;
+ }
+ return str.arg(major).arg(minor).arg(majorStr).arg(minorStr);
+ }
+
+QString formatTrkVersion(const TrkAppVersion &version)
+{
+ QString str = QCoreApplication::translate("trk::Session",
+ "App TRK: v%1.%2 TRK protocol: v%3.%4");
+ str = str.arg(version.trkMajor).arg(version.trkMinor);
+ return str.arg(version.protocolMajor).arg(version.protocolMinor);
+}
+
+QString Session::deviceDescription(unsigned verbose) const
+{
+ if (!cpuMajor)
+ return QString();
+
+ //: s60description
+ //: description of an S60 device
+ //: %1 CPU description, %2 endianness
+ //: %3 default type size (if any), %4 float size (if any)
+ //: %5 TRK version
+ QString msg = QCoreApplication::translate("trk::Session", "%1, %2%3%4, %5");
+ QString endianness = bigEndian
+ ? QCoreApplication::translate("trk::Session", "big endian")
+ : QCoreApplication::translate("trk::Session", "little endian");
+ msg = msg.arg(formatCpu(cpuMajor, cpuMinor)).arg(endianness);
+ //: The separator in a list of strings
+ QString defaultTypeSizeStr;
+ QString fpTypeSizeStr;
+ if (verbose && defaultTypeSize)
+ //: will be inserted into s60description
+ defaultTypeSizeStr = QCoreApplication::translate("trk::Session", ", type size: %1").arg(defaultTypeSize);
+ if (verbose && fpTypeSize)
+ //: will be inserted into s60description
+ fpTypeSizeStr = QCoreApplication::translate("trk::Session", ", float size: %1").arg(fpTypeSize);
+ msg = msg.arg(defaultTypeSizeStr).arg(fpTypeSizeStr);
+ return msg.arg(formatTrkVersion(trkAppVersion));
+}
+
+QByteArray Session::gdbLibraryList() const
+{
+ const int count = libraries.size();
+ QByteArray response = "l<library-list>";
+ for (int i = 0; i != count; ++i) {
+ const trk::Library &lib = libraries.at(i);
+ response += "<library name=\"";
+ response += lib.name;
+ response += "\">";
+ response += "<section address=\"0x";
+ response += trk::hexNumber(lib.codeseg);
+ response += "\"/>";
+ response += "<section address=\"0x";
+ response += trk::hexNumber(lib.dataseg);
+ response += "\"/>";
+ response += "<section address=\"0x";
+ response += trk::hexNumber(lib.dataseg);
+ response += "\"/>";
+ response += "</library>";
+ }
+ response += "</library-list>";
+ return response;
+}
+
+QByteArray Session::gdbQsDllInfo(int start, int count) const
+{
+ // Happens with gdb 6.4.50.20060226-cvs / CodeSourcery.
+ // Never made it into FSF gdb that got qXfer:libraries:read instead.
+ // http://sourceware.org/ml/gdb/2007-05/msg00038.html
+ // Name=hexname,TextSeg=textaddr[,DataSeg=dataaddr]
+ const int libraryCount = libraries.size();
+ const int end = count < 0 ? libraryCount : qMin(libraryCount, start + count);
+ QByteArray response(1, end == libraryCount ? 'l' : 'm');
+ for (int i = start; i < end; ++i) {
+ if (i != start)
+ response += ';';
+ const Library &lib = libraries.at(i);
+ response += "Name=";
+ response += lib.name.toHex();
+ response += ",TextSeg=";
+ response += hexNumber(lib.codeseg);
+ response += ",DataSeg=";
+ response += hexNumber(lib.dataseg);
+ }
+ return response;
+}
+
+QString Session::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << "Session: " << deviceDescription(false) << '\n'
+ << "pid: " << pid << "main thread: " << mainTid
+ << " current thread: " << tid << ' ';
+ str.setIntegerBase(16);
+ str << " code: 0x" << codeseg << " data: 0x" << dataseg << '\n';
+ if (const int libCount = libraries.size()) {
+ str << "Libraries:\n";
+ for (int i = 0; i < libCount; i++)
+ str << " #" << i << ' ' << libraries.at(i).name
+ << " code: 0x" << libraries.at(i).codeseg
+ << " data: 0x" << libraries.at(i).dataseg << '\n';
+ }
+ if (const int moduleCount = modules.size()) {
+ str << "Modules:\n";
+ for (int i = 0; i < moduleCount; i++)
+ str << " #" << i << ' ' << modules.at(i) << '\n';
+ }
+ str.setIntegerBase(10);
+ if (!addressToBP.isEmpty()) {
+ typedef QHash<uint, uint>::const_iterator BP_ConstIterator;
+ str << "Breakpoints:\n";
+ const BP_ConstIterator cend = addressToBP.constEnd();
+ for (BP_ConstIterator it = addressToBP.constBegin(); it != cend; ++it) {
+ str.setIntegerBase(16);
+ str << " 0x" << it.key();
+ str.setIntegerBase(10);
+ str << ' ' << it.value() << '\n';
+ }
+ }
+
+ return rc;
+}
+
+// --------------
+
+QByteArray decode7d(const QByteArray &ba)
+{
+ QByteArray res;
+ res.reserve(ba.size());
+ for (int i = 0; i < ba.size(); ++i) {
+ byte c = byte(ba.at(i));
+ if (c == 0x7d) {
+ ++i;
+ c = 0x20 ^ byte(ba.at(i));
+ }
+ res.append(c);
+ }
+ return res;
+}
+
+QByteArray encode7d(const QByteArray &ba)
+{
+ QByteArray res;
+ res.reserve(ba.size() + 2);
+ for (int i = 0; i < ba.size(); ++i) {
+ byte c = byte(ba.at(i));
+ if (c == 0x7e || c == 0x7d) {
+ res.append(0x7d);
+ res.append(0x20 ^ c);
+ } else {
+ res.append(c);
+ }
+ }
+ return res;
+}
+
+// FIXME: Use the QByteArray based version below?
+static inline QString stringFromByte(byte c)
+{
+ return QString::fromLatin1("%1").arg(c, 2, 16, QChar('0'));
+}
+
+SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen)
+{
+ QString str;
+ QString ascii;
+ const int size = maxLen == -1 ? ba.size() : qMin(ba.size(), maxLen);
+ for (int i = 0; i < size; ++i) {
+ const int c = byte(ba.at(i));
+ str += QString::fromAscii("%1 ").arg(c, 2, 16, QChar('0'));
+ ascii += QChar(c).isPrint() ? QChar(c) : QChar('.');
+ }
+ if (size != ba.size()) {
+ str += QLatin1String("...");
+ ascii += QLatin1String("...");
+ }
+ return str + QLatin1String(" ") + ascii;
+}
+
+SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits)
+{
+ QByteArray ba = QByteArray::number(n, 16);
+ if (digits == 0 || ba.size() == digits)
+ return ba;
+ return QByteArray(digits - ba.size(), '0') + ba;
+}
+
+SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits)
+{
+ return "0x" + hexNumber(n, digits);
+}
+
+TrkResult::TrkResult() :
+ code(0),
+ token(0),
+ isDebugOutput(false)
+{
+}
+
+void TrkResult::clear()
+{
+ code = token= 0;
+ isDebugOutput = false;
+ data.clear();
+ cookie = QVariant();
+}
+
+QString TrkResult::toString() const
+{
+ QString res = stringFromByte(code);
+ res += QLatin1String(" [");
+ res += stringFromByte(token);
+ res += QLatin1Char(']');
+ res += QLatin1Char(' ');
+ res += stringFromArray(data);
+ return res;
+}
+
+QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame)
+{
+ byte s = command + token;
+ for (int i = 0; i != data.size(); ++i)
+ s += data.at(i);
+ byte checksum = 255 - (s & 0xff);
+ //int x = s + ~s;
+ //logMessage("check: " << s << checksum << x;
+
+ QByteArray response;
+ response.reserve(data.size() + 3);
+ response.append(char(command));
+ response.append(char(token));
+ response.append(data);
+ response.append(char(checksum));
+
+ QByteArray encodedData = encode7d(response);
+
+ QByteArray ba;
+ ba.reserve(encodedData.size() + 6);
+ if (serialFrame) {
+ ba.append(char(0x01));
+ ba.append(char(0x90));
+ const ushort encodedSize = encodedData.size() + 2; // 2 x 0x7e
+ appendShort(&ba, encodedSize, BigEndian);
+ }
+ ba.append(char(0x7e));
+ ba.append(encodedData);
+ ba.append(char(0x7e));
+
+ return ba;
+}
+
+/* returns 0 if array doesn't represent a result,
+otherwise returns the length of the result data */
+ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame, ushort& mux)
+{
+ if (serialFrame) {
+ // Serial protocol with length info
+ if (buffer.length() < 4)
+ return 0;
+ mux = extractShort(buffer.data());
+ const ushort len = extractShort(buffer.data() + 2);
+ return (buffer.size() >= len + 4) ? len : ushort(0);
+ }
+ // Frameless protocol without length info
+ const char delimiter = char(0x7e);
+ const int firstDelimiterPos = buffer.indexOf(delimiter);
+ // Regular message delimited by 0x7e..0x7e
+ if (firstDelimiterPos == 0) {
+ mux = MuxTrk;
+ const int endPos = buffer.indexOf(delimiter, firstDelimiterPos + 1);
+ return endPos != -1 ? endPos + 1 - firstDelimiterPos : 0;
+ }
+ // Some ASCII log message up to first delimiter or all
+ return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size();
+}
+
+bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, bool &linkEstablishmentMode, QByteArray *rawData)
+{
+ result->clear();
+ if(rawData)
+ rawData->clear();
+ ushort len = isValidTrkResult(*buffer, serialFrame, result->multiplex);
+ // handle receiving application output, which is not a regular command
+ const int delimiterPos = serialFrame ? 4 : 0;
+ if (linkEstablishmentMode) {
+ //when "hot connecting" a device, we can receive partial frames.
+ //this code resyncs by discarding data until a TRK frame is found
+ while (buffer->length() > delimiterPos
+ && result->multiplex != MuxTextTrace
+ && !(result->multiplex == MuxTrk && buffer->at(delimiterPos) == 0x7e)) {
+ buffer->remove(0,1);
+ len = isValidTrkResult(*buffer, serialFrame, result->multiplex);
+ }
+ }
+ if (!len)
+ return false;
+ if (buffer->at(delimiterPos) != 0x7e) {
+ result->isDebugOutput = true;
+ result->data = buffer->mid(delimiterPos, len);
+ buffer->remove(0, delimiterPos + len);
+ return true;
+ }
+ // FIXME: what happens if the length contains 0xfe?
+ // Assume for now that it passes unencoded!
+ const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2));
+ if(rawData)
+ *rawData = data;
+ buffer->remove(0, delimiterPos + len);
+
+ byte sum = 0;
+ for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum
+ sum += byte(data.at(i));
+ if (sum != 0xff)
+ logMessage("*** CHECKSUM ERROR: " << byte(sum));
+
+ result->code = data.at(0);
+ result->token = data.at(1);
+ result->data = data.mid(2, data.size() - 3);
+ //logMessage(" REST BUF: " << stringFromArray(*buffer));
+ //logMessage(" CURR DATA: " << stringFromArray(data));
+ //QByteArray prefix = "READ BUF: ";
+ //logMessage((prefix + "HEADER: " + stringFromArray(header).toLatin1()).data());
+ linkEstablishmentMode = false; //have received a good TRK packet, therefore in sync
+ return true;
+}
+
+SYMBIANUTILS_EXPORT ushort extractShort(const char *data)
+{
+ return byte(data[0]) * 256 + byte(data[1]);
+}
+
+SYMBIANUTILS_EXPORT uint extractInt(const char *data)
+{
+ uint res = byte(data[0]);
+ res *= 256; res += byte(data[1]);
+ res *= 256; res += byte(data[2]);
+ res *= 256; res += byte(data[3]);
+ return res;
+}
+
+SYMBIANUTILS_EXPORT quint64 extractInt64(const char *data)
+{
+ quint64 res = byte(data[0]);
+ res <<= 8; res += byte(data[1]);
+ res <<= 8; res += byte(data[2]);
+ res <<= 8; res += byte(data[3]);
+ res <<= 8; res += byte(data[4]);
+ res <<= 8; res += byte(data[5]);
+ res <<= 8; res += byte(data[6]);
+ res <<= 8; res += byte(data[7]);
+ return res;
+}
+
+SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba)
+{
+ QString res;
+ char buf[10];
+ for (int i = 0, n = ba.size(); i != n; ++i) {
+ const byte c = ba.at(i);
+ if (isprint(c)) {
+ res += c;
+ } else {
+ qsnprintf(buf, sizeof(buf) - 1, "\\%x", int(c));
+ res += buf;
+ }
+ }
+ return res;
+}
+
+SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness endian)
+{
+ if (endian == BigEndian) {
+ ba->append(s / 256);
+ ba->append(s % 256);
+ } else {
+ ba->append(s % 256);
+ ba->append(s / 256);
+ }
+}
+
+SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness endian)
+{
+ const uchar b3 = i % 256; i /= 256;
+ const uchar b2 = i % 256; i /= 256;
+ const uchar b1 = i % 256; i /= 256;
+ const uchar b0 = i;
+ ba->reserve(ba->size() + 4);
+ if (endian == BigEndian) {
+ ba->append(b0);
+ ba->append(b1);
+ ba->append(b2);
+ ba->append(b3);
+ } else {
+ ba->append(b3);
+ ba->append(b2);
+ ba->append(b1);
+ ba->append(b0);
+ }
+}
+
+void appendString(QByteArray *ba, const QByteArray &str, Endianness endian, bool appendNullTerminator)
+{
+ const int fullSize = str.size() + (appendNullTerminator ? 1 : 0);
+ appendShort(ba, fullSize, endian); // count the terminating \0
+ ba->append(str);
+ if (appendNullTerminator)
+ ba->append('\0');
+}
+
+void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness endian)
+{
+ // convert the QDateTime to UTC and append its representation to QByteArray
+ // format is the same as in FAT file system
+ dateTime = dateTime.toUTC();
+ const QTime utcTime = dateTime.time();
+ const QDate utcDate = dateTime.date();
+ uint fatDateTime = (utcTime.hour() << 11 | utcTime.minute() << 5 | utcTime.second()/2) << 16;
+ fatDateTime |= (utcDate.year()-1980) << 9 | utcDate.month() << 5 | utcDate.day();
+ appendInt(ba, fatDateTime, endian);
+}
+
+QByteArray errorMessage(byte code)
+{
+ switch (code) {
+ case 0x00: return "No error";
+ case 0x01: return "Generic error in CWDS message";
+ case 0x02: return "Unexpected packet size in send msg";
+ case 0x03: return "Internal error occurred in CWDS";
+ case 0x04: return "Escape followed by frame flag";
+ case 0x05: return "Bad FCS in packet";
+ case 0x06: return "Packet too long";
+ case 0x07: return "Sequence ID not expected (gap in sequence)";
+
+ case 0x10: return "Command not supported";
+ case 0x11: return "Command param out of range";
+ case 0x12: return "An option was not supported";
+ case 0x13: return "Read/write to invalid memory";
+ case 0x14: return "Read/write invalid registers";
+ case 0x15: return "Exception occurred in CWDS";
+ case 0x16: return "Targeted system or thread is running";
+ case 0x17: return "Breakpoint resources (HW or SW) exhausted";
+ case 0x18: return "Requested breakpoint conflicts with existing one";
+
+ case 0x20: return "General OS-related error";
+ case 0x21: return "Request specified invalid process";
+ case 0x22: return "Request specified invalid thread";
+ }
+ return "Unknown error";
+}
+
+uint swapEndian(uint in)
+{
+ return (in>>24) | ((in<<8) & 0x00FF0000) | ((in>>8) & 0x0000FF00) | (in<<24);
+}
+
+int TrkResult::errorCode() const
+{
+ // NAK means always error, else data sized 1 with a non-null element
+ const bool isNAK = code == 0xff;
+ if (data.size() != 1 && !isNAK)
+ return 0;
+ if (const int errorCode = data.at(0))
+ return errorCode;
+ return isNAK ? 0xff : 0;
+}
+
+QString TrkResult::errorString() const
+{
+ // NAK means always error, else data sized 1 with a non-null element
+ if (code == 0xff)
+ return "NAK";
+ if (data.size() < 1)
+ return "Unknown error packet";
+ return errorMessage(data.at(0));
+}
+
+} // namespace trk
+
diff --git a/src/runonphone/symbianutils/trkutils.h b/src/runonphone/symbianutils/trkutils.h
new file mode 100644
index 000000000..c22df865a
--- /dev/null
+++ b/src/runonphone/symbianutils/trkutils.h
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEBUGGER_TRK_UTILS
+#define DEBUGGER_TRK_UTILS
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QHash>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+class QDateTime;
+QT_END_NAMESPACE
+
+namespace trk {
+
+typedef unsigned char byte;
+struct TrkResult;
+
+enum Command {
+ //meta commands
+ TrkPing = 0x00,
+ TrkConnect = 0x01,
+ TrkDisconnect = 0x02,
+ TrkReset = 0x03,
+ TrkVersions = 0x04,
+ TrkSupported = 0x05,
+ TrkCpuType = 0x06,
+ TrkConfigTransport = 0x07,
+ TrkVersions2 = 0x08,
+ TrkHostVersions = 0x09,
+
+ //state commands
+ TrkReadMemory = 0x10,
+ TrkWriteMemory = 0x11,
+ TrkReadRegisters = 0x12,
+ TrkWriteRegisters = 0x13,
+ TrkFillMemory = 0x14,
+ TrkCopyMemory = 0x15,
+ TrkFlushCache = 0x16,
+
+ //execution commands
+ TrkContinue = 0x18,
+ TrkStep = 0x19,
+ TrkStop = 0x1a,
+ TrkSetBreak = 0x1b,
+ TrkClearBreak = 0x1c,
+ TrkDownload = 0x1d,
+ TrkModifyBreakThread = 0x1e,
+
+ //host -> target IO management
+ TrkNotifyFileInput = 0x20,
+ TrkBlockFileIo = 0x21,
+
+ //host -> target os commands
+ TrkCreateItem = 0x40,
+ TrkDeleteItem = 0x41,
+ TrkReadInfo = 0x42,
+ TrkWriteInfo = 0x43,
+
+ TrkWriteFile = 0x48,
+ TrkReadFile = 0x49,
+ TrkOpenFile = 0x4a,
+ TrkCloseFile = 0x4b,
+ TrkPositionFile = 0x4c,
+ TrkInstallFile = 0x4d,
+ TrkInstallFile2 = 0x4e,
+
+ TrkPhoneSwVersion = 0x4f,
+ TrkPhoneName = 0x50,
+ TrkVersions3 = 0x51,
+
+ //replies
+ TrkNotifyAck = 0x80,
+ TrkNotifyNak = 0xff,
+
+ //target -> host notification
+ TrkNotifyStopped = 0x90,
+ TrkNotifyException = 0x91,
+ TrkNotifyInternalError = 0x92,
+ TrkNotifyStopped2 = 0x94,
+
+ //target -> host OS notification
+ TrkNotifyCreated = 0xa0,
+ TrkNotifyDeleted = 0xa1,
+ TrkNotifyProcessorStarted = 0xa2,
+ TrkNotifyProcessorStandBy = 0xa6,
+ TrkNotifyProcessorReset = 0xa7,
+
+ //target -> host support commands (these are defined but not implemented in TRK)
+ TrkDSWriteFile = 0xd0,
+ TrkDSReadFile = 0xd1,
+ TrkDSOpenFile = 0xd2,
+ TrkDSCloseFile = 0xd3,
+ TrkDSPositionFile = 0xd4
+};
+
+enum DSOSItemTypes {
+ kDSOSProcessItem = 0x0000,
+ kDSOSThreadItem = 0x0001,
+ kDSOSDLLItem = 0x0002,
+ kDSOSAppItem = 0x0003,
+ kDSOSMemBlockItem = 0x0004,
+ kDSOSProcAttachItem = 0x0005,
+ kDSOSThreadAttachItem = 0x0006,
+ kDSOSProcAttach2Item = 0x0007,
+ kDSOSProcRunItem = 0x0008,
+ /* 0x0009 - 0x00ff reserved for general expansion */
+ /* 0x0100 - 0xffff available for target-specific use */
+};
+
+enum SerialMultiplexor {
+ MuxRaw = 0,
+ MuxTextTrace = 0x0102,
+ MuxTrk = 0x0190
+};
+
+inline byte extractByte(const char *data) { return *data; }
+SYMBIANUTILS_EXPORT ushort extractShort(const char *data);
+SYMBIANUTILS_EXPORT uint extractInt(const char *data);
+SYMBIANUTILS_EXPORT quint64 extractInt64(const char *data);
+
+SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba);
+
+// produces "xx xx xx "
+SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen = - 1);
+
+enum Endianness
+{
+ LittleEndian,
+ BigEndian,
+ TargetByteOrder = BigEndian,
+};
+
+SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder);
+SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder);
+SYMBIANUTILS_EXPORT void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true);
+
+struct SYMBIANUTILS_EXPORT Library
+{
+ Library();
+ explicit Library(const TrkResult &r);
+
+ QByteArray name;
+ uint codeseg;
+ uint dataseg;
+ //library addresses are valid for a given process (depending on memory model, they might be loaded at the same address in all processes or not)
+ uint pid;
+};
+
+struct SYMBIANUTILS_EXPORT TrkAppVersion
+{
+ TrkAppVersion();
+ void reset();
+
+ int trkMajor;
+ int trkMinor;
+ int protocolMajor;
+ int protocolMinor;
+};
+
+struct SYMBIANUTILS_EXPORT Session
+{
+ Session();
+ void reset();
+ QString deviceDescription(unsigned verbose) const;
+ QString toString() const;
+ // Answer to qXfer::libraries
+ QByteArray gdbLibraryList() const;
+ // Answer to qsDllInfo, can be sent chunk-wise.
+ QByteArray gdbQsDllInfo(int start = 0, int count = -1) const;
+
+ // Trk feedback
+ byte cpuMajor;
+ byte cpuMinor;
+ byte bigEndian;
+ byte defaultTypeSize;
+ byte fpTypeSize;
+ byte extended1TypeSize;
+ byte extended2TypeSize;
+ TrkAppVersion trkAppVersion;
+ uint pid;
+ uint mainTid;
+ uint tid;
+ uint codeseg;
+ uint dataseg;
+ QHash<uint, uint> addressToBP;
+
+ typedef QList<Library> Libraries;
+ Libraries libraries;
+
+ // Gdb request
+ QStringList modules;
+};
+
+struct SYMBIANUTILS_EXPORT TrkResult
+{
+ TrkResult();
+ void clear();
+ QString toString() const;
+ // 0 for no error.
+ int errorCode() const;
+ QString errorString() const;
+
+ ushort multiplex;
+ byte code;
+ byte token;
+ QByteArray data;
+ QVariant cookie;
+ bool isDebugOutput;
+};
+
+SYMBIANUTILS_EXPORT QByteArray errorMessage(byte code);
+SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits = 0);
+SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too
+SYMBIANUTILS_EXPORT uint swapEndian(uint in);
+
+} // namespace trk
+
+#endif // DEBUGGER_TRK_UTILS
diff --git a/src/runonphone/symbianutils/trkutils_p.h b/src/runonphone/symbianutils/trkutils_p.h
new file mode 100644
index 000000000..df9504c5e
--- /dev/null
+++ b/src/runonphone/symbianutils/trkutils_p.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEBUGGER_TRK_PRIVATE_UTILS
+#define DEBUGGER_TRK_PRIVATE_UTILS
+
+#include "trkutils.h"
+#include "symbianutils_global.h"
+
+QT_BEGIN_NAMESPACE
+class QDateTime;
+QT_END_NAMESPACE
+
+namespace trk {
+
+void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder);
+// returns a QByteArray containing optionally
+// the serial frame [0x01 0x90 <len>] and 0x7e encoded7d(ba) 0x7e
+QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame);
+bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, bool& linkEstablishmentMode, QByteArray *rawData = 0);
+
+} // namespace trk
+
+#endif // DEBUGGER_TRK_PRIVATE_UTILS
diff --git a/src/runonphone/trksignalhandler.cpp b/src/runonphone/trksignalhandler.cpp
new file mode 100644
index 000000000..a2b8f6f27
--- /dev/null
+++ b/src/runonphone/trksignalhandler.cpp
@@ -0,0 +1,368 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QCoreApplication>
+#include <QObject>
+#include <QFile>
+#include <QDir>
+#include "trksignalhandler.h"
+#include "trkutils.h"
+
+class CrashState
+{
+public:
+ uint pid;
+ uint tid;
+ QString crashReason;
+ uint crashPC;
+};
+
+class TrkSignalHandlerPrivate
+{
+ friend class TrkSignalHandler;
+public:
+ TrkSignalHandlerPrivate();
+ ~TrkSignalHandlerPrivate();
+private:
+ QTextStream out;
+ QTextStream err;
+ int loglevel;
+ int lastpercent;
+ QList<trk::Library> libraries;
+ QFile crashlogtextfile;
+ QFile crashstackfile;
+ QList<CrashState> queuedCrashes;
+ QList<int> dyingThreads;
+ QString crashlogPath;
+ bool crashlog;
+ bool terminateNeeded;
+};
+
+void TrkSignalHandler::copyingStarted()
+{
+ if (d->loglevel > 0)
+ d->out << "Copying..." << endl;
+}
+
+void TrkSignalHandler::canNotConnect(const QString &errorMessage)
+{
+ d->err << "Cannot connect - " << errorMessage << endl;
+}
+
+void TrkSignalHandler::canNotCreateFile(const QString &filename, const QString &errorMessage)
+{
+ d->err << "Cannot create file (" << filename << ") - " << errorMessage << endl;
+}
+
+void TrkSignalHandler::canNotWriteFile(const QString &filename, const QString &errorMessage)
+{
+ d->err << "Cannot write file (" << filename << ") - " << errorMessage << endl;
+}
+
+void TrkSignalHandler::canNotCloseFile(const QString &filename, const QString &errorMessage)
+{
+ d->err << "Cannot close file (" << filename << ") - " << errorMessage << endl;
+}
+
+void TrkSignalHandler::installingStarted()
+{
+ if (d->loglevel > 0)
+ d->out << "Installing..." << endl;
+}
+
+void TrkSignalHandler::canNotInstall(const QString &packageFilename, const QString &errorMessage)
+{
+ d->err << "Cannot install file (" << packageFilename << ") - " << errorMessage << endl;
+}
+
+void TrkSignalHandler::installingFinished()
+{
+ if (d->loglevel > 0)
+ d->out << "Installing finished" << endl;
+}
+
+void TrkSignalHandler::startingApplication()
+{
+ if (d->loglevel > 0)
+ d->out << "Starting app..." << endl;
+}
+
+void TrkSignalHandler::applicationRunning(uint pid)
+{
+ Q_UNUSED(pid)
+ if (d->loglevel > 0)
+ d->out << "Running..." << endl;
+}
+
+void TrkSignalHandler::canNotRun(const QString &errorMessage)
+{
+ d->err << "Cannot run - " << errorMessage << endl;
+}
+
+void TrkSignalHandler::finished()
+{
+ if (d->loglevel > 0)
+ d->out << "Done." << endl;
+ QCoreApplication::quit();
+}
+
+void TrkSignalHandler::applicationOutputReceived(const QString &output)
+{
+ d->out << output << flush;
+}
+
+void TrkSignalHandler::copyProgress(int percent)
+{
+ if (d->loglevel > 0) {
+ if (d->lastpercent == 0)
+ d->out << "[ ]\r[" << flush;
+ while (percent > d->lastpercent) {
+ d->out << QLatin1Char('#');
+ d->lastpercent+=2; //because typical console is 80 chars wide
+ }
+ d->out.flush();
+ if (percent==100)
+ d->out << endl;
+ }
+}
+
+void TrkSignalHandler::stateChanged(int state)
+{
+ if (d->loglevel > 1)
+ d->out << "State" << state << endl;
+}
+
+void TrkSignalHandler::setLogLevel(int level)
+{
+ d->loglevel = level;
+}
+
+void TrkSignalHandler::setCrashLogging(bool enabled)
+{
+ d->crashlog = enabled;
+}
+
+void TrkSignalHandler::setCrashLogPath(QString path)
+{
+ d->crashlogPath = path;
+}
+
+bool lessThanCodeBase(const trk::Library& cs1, const trk::Library& cs2)
+{
+ return cs1.codeseg < cs2.codeseg;
+}
+
+void TrkSignalHandler::stopped(uint pc, uint pid, uint tid, const QString& reason)
+{
+ d->err << "STOPPED: pc=" << hex << pc << " pid=" << pid
+ << " tid=" << tid << dec << " - " << reason << endl;
+
+ if (d->crashlog) {
+ CrashState cs;
+ cs.pid = pid;
+ cs.tid = tid;
+ cs.crashPC = pc;
+ cs.crashReason = reason;
+
+ if (d->dyingThreads.contains(tid)) {
+ if(d->queuedCrashes.isEmpty())
+ emit terminate();
+ else
+ d->terminateNeeded = true;
+ } else {
+ d->queuedCrashes.append(cs);
+ d->dyingThreads.append(tid);
+
+ if (d->queuedCrashes.count() == 1) {
+ d->err << "Fetching registers and stack..." << endl;
+ emit getRegistersAndCallStack(pid, tid);
+ }
+ }
+ }
+ else
+ emit terminate();
+}
+
+void TrkSignalHandler::registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack)
+{
+ CrashState cs = d->queuedCrashes.first();
+ QDir dir(d->crashlogPath);
+ d->crashlogtextfile.setFileName(dir.filePath(QString("d_exc_%1.txt").arg(cs.tid)));
+ d->crashstackfile.setFileName(dir.filePath(QString("d_exc_%1.stk").arg(cs.tid)));
+ d->crashlogtextfile.open(QIODevice::WriteOnly);
+ QTextStream crashlog(&d->crashlogtextfile);
+
+ crashlog << "-----------------------------------------------------------------------------" << endl;
+ crashlog << "EKA2 USER CRASH LOG" << endl;
+ crashlog << "Thread Name: " << QString("ProcessID-%1::ThreadID-%2").arg(cs.pid).arg(cs.tid) << endl;
+ crashlog << "Thread ID: " << cs.tid << endl;
+ //this is wrong, but TRK doesn't make stack limit available so we lie
+ crashlog << QString("User Stack %1-%2").arg(registers.at(13), 8, 16, QChar('0')).arg(registers.at(13) + stack.size(), 8, 16, QChar('0')) << endl;
+ //this is also wrong, but TRK doesn't give all information for exceptions
+ crashlog << QString("Panic: PC=%1 ").arg(cs.crashPC, 8, 16, QChar('0')) << cs.crashReason << endl;
+ crashlog << endl;
+ crashlog << "USER REGISTERS:" << endl;
+ crashlog << QString("CPSR=%1").arg(registers.at(16), 8, 16, QChar('0')) << endl;
+ for (int i=0;i<16;i+=4) {
+ crashlog << QString("r%1=%2 %3 %4 %5")
+ .arg(i, 2, 10, QChar('0'))
+ .arg(registers.at(i), 8, 16, QChar('0'))
+ .arg(registers.at(i+1), 8, 16, QChar('0'))
+ .arg(registers.at(i+2), 8, 16, QChar('0'))
+ .arg(registers.at(i+3), 8, 16, QChar('0')) << endl;
+ }
+ crashlog << endl;
+
+ //emit info for post mortem debug
+ qSort(d->libraries.begin(), d->libraries.end(), lessThanCodeBase);
+ d->err << "Code Segments:" << endl;
+ crashlog << "CODE SEGMENTS:" << endl;
+ for(int i=0; i<d->libraries.count(); i++) {
+ const trk::Library& seg = d->libraries.at(i);
+ if(seg.pid != cs.pid)
+ continue;
+ if (d->loglevel > 1) {
+ d->err << QString("Code: %1 Data: %2 Name: ")
+ .arg(seg.codeseg, 8, 16, QChar('0'))
+ .arg(seg.dataseg, 8, 16, QChar('0'))
+ << seg.name << endl;
+ }
+
+ //produce fake code segment end addresses since we don't get the real ones from TRK
+ uint end;
+ if (i+1 < d->libraries.count())
+ end = d->libraries.at(i+1).codeseg - 1;
+ else
+ end = 0xFFFFFFFF;
+
+ crashlog << QString("%1-%2 ")
+ .arg(seg.codeseg, 8, 16, QChar('0'))
+ .arg(end, 8, 16, QChar('0'))
+ << seg.name << endl;
+ }
+
+ d->crashlogtextfile.close();
+
+ if (d->loglevel > 1) {
+ d->err << "Registers:" << endl;
+ for (int i=0;i<16;i++) {
+ d->err << QString("R%1: %2 ").arg(i, 2, 10, QChar('0')).arg(registers.at(i), 8, 16, QChar('0'));
+ if (i % 4 == 3)
+ d->err << endl;
+ }
+ d->err << QString("CPSR: %1").arg(registers.at(16), 8, 16, QChar('0')) << endl;
+
+ d->err << "Stack:" << endl;
+ uint sp = registers.at(13);
+ for(int i=0; i<stack.size(); i+=16, sp+=16) {
+ d->err << QString("%1: ").arg(sp, 8, 16, QChar('0'));
+ d->err << trk::stringFromArray(stack.mid(i,16));
+ d->err << endl;
+ }
+ }
+ d->crashstackfile.open(QIODevice::WriteOnly);
+ d->crashstackfile.write(stack);
+ d->crashstackfile.close();
+
+ if (d->loglevel > 0)
+ d->err << "Crash logs saved to " << d->crashlogtextfile.fileName() << " & " << d->crashstackfile.fileName() << endl;
+
+ // resume the thread to allow Symbian OS to handle the panic normally.
+ // terminate when a non main thread is suspended reboots the phone (TRK bug)
+ emit resume(cs.pid, cs.tid);
+
+ //fetch next crashed thread
+ d->queuedCrashes.removeFirst();
+ if (d->queuedCrashes.count()) {
+ cs = d->queuedCrashes.first();
+ d->err << "Fetching registers and stack..." << endl;
+ emit getRegistersAndCallStack(cs.pid, cs.tid);
+ }
+ else if (d->terminateNeeded)
+ emit terminate();
+
+}
+
+void TrkSignalHandler::libraryLoaded(const trk::Library &lib)
+{
+ d->libraries << lib;
+}
+
+void TrkSignalHandler::libraryUnloaded(const trk::Library &lib)
+{
+ for (QList<trk::Library>::iterator i = d->libraries.begin(); i != d->libraries.end(); i++) {
+ if((*i).name == lib.name && (*i).pid == lib.pid)
+ i = d->libraries.erase(i);
+ }
+}
+
+void TrkSignalHandler::timeout()
+{
+ d->err << "FAILED: stopping test due to timeout" << endl;
+ emit terminate();
+}
+
+TrkSignalHandlerPrivate::TrkSignalHandlerPrivate()
+ : out(stdout),
+ err(stderr),
+ loglevel(0),
+ lastpercent(0),
+ terminateNeeded(false)
+{
+
+}
+
+TrkSignalHandlerPrivate::~TrkSignalHandlerPrivate()
+{
+ out.flush();
+ err.flush();
+}
+
+TrkSignalHandler::TrkSignalHandler()
+ : d(new TrkSignalHandlerPrivate())
+{
+}
+
+TrkSignalHandler::~TrkSignalHandler()
+{
+ delete d;
+}
diff --git a/src/runonphone/trksignalhandler.h b/src/runonphone/trksignalhandler.h
new file mode 100644
index 000000000..f8331800c
--- /dev/null
+++ b/src/runonphone/trksignalhandler.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRKSIGNALHANDLER_H
+#define TRKSIGNALHANDLER_H
+#include <QObject>
+#include <QString>
+#include "symbianutils/trkutils.h"
+
+class TrkSignalHandlerPrivate;
+class TrkSignalHandler : public QObject
+{
+ Q_OBJECT
+public slots:
+ void copyingStarted();
+ void canNotConnect(const QString &errorMessage);
+ void canNotCreateFile(const QString &filename, const QString &errorMessage);
+ void canNotWriteFile(const QString &filename, const QString &errorMessage);
+ void canNotCloseFile(const QString &filename, const QString &errorMessage);
+ void installingStarted();
+ void canNotInstall(const QString &packageFilename, const QString &errorMessage);
+ void installingFinished();
+ void startingApplication();
+ void applicationRunning(uint pid);
+ void canNotRun(const QString &errorMessage);
+ void finished();
+ void applicationOutputReceived(const QString &output);
+ void copyProgress(int percent);
+ void stateChanged(int);
+ void stopped(uint pc, uint pid, uint tid, const QString& reason);
+ void timeout();
+ void libraryLoaded(const trk::Library &lib);
+ void libraryUnloaded(const trk::Library &lib);
+ void registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack);
+signals:
+ void resume(uint pid, uint tid);
+ void stop(uint pid, uint tid);
+ void terminate();
+ void getRegistersAndCallStack(uint pid, uint tid);
+public:
+ TrkSignalHandler();
+ ~TrkSignalHandler();
+ void setLogLevel(int);
+ void setCrashLogging(bool);
+ void setCrashLogPath(QString);
+private:
+ TrkSignalHandlerPrivate *d;
+};
+
+#endif // TRKSIGNALHANDLER_H
diff --git a/src/shared/deviceskin/deviceskin.cpp b/src/shared/deviceskin/deviceskin.cpp
new file mode 100644
index 000000000..1e3748fe8
--- /dev/null
+++ b/src/shared/deviceskin/deviceskin.cpp
@@ -0,0 +1,857 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceskin.h"
+
+#include <QtCore/qnamespace.h>
+#include <QtGui/QApplication>
+#include <QtGui/QBitmap>
+#include <QtGui/QPixmap>
+#include <QtGui/QPainter>
+#include <QtCore/QTextStream>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtGui/QImage>
+#include <QtCore/QTimer>
+#include <QtCore/QDir>
+#include <QtCore/QRegExp>
+#include <QtGui/QMouseEvent>
+#include <QtCore/QDebug>
+
+#ifdef TEST_SKIN
+# include <QtGui/QMainWindow>
+# include <QtGui/QDialog>
+# include <QtGui/QDialogButtonBox>
+# include <QtGui/QHBoxLayout>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { joydistance = 10, key_repeat_period = 50, key_repeat_delay = 500 };
+ enum { debugDeviceSkin = 0 };
+}
+
+static void parseRect(const QString &value, QRect *rect) {
+ const QStringList l = value.split(QLatin1Char(' '));
+ rect->setRect(l[0].toInt(), l[1].toInt(), l[2].toInt(), l[3].toInt());
+}
+
+static QString msgImageNotLoaded(const QString &f) {
+ return DeviceSkin::tr("The image file '%1' could not be loaded.").arg(f);
+}
+
+// ------------ DeviceSkinButtonArea
+DeviceSkinButtonArea::DeviceSkinButtonArea() :
+ keyCode(0),
+ activeWhenClosed(0)
+{
+}
+
+QDebug &operator<<(QDebug &str, const DeviceSkinButtonArea &a)
+{
+
+ str << "Area: " << a.name << " keyCode=" << a.keyCode << " area=" << a.area
+ << " text=" << a.text << " activeWhenClosed=" << a.activeWhenClosed;
+ return str;
+}
+
+// ------------ DeviceSkinParameters
+
+QDebug operator<<(QDebug str, const DeviceSkinParameters &p)
+{
+ str << "Images " << p.skinImageUpFileName << ','
+ << p.skinImageDownFileName<< ',' << p.skinImageClosedFileName
+ << ',' << p.skinCursorFileName <<"\nScreen: " << p.screenRect
+ << " back: " << p.backScreenRect << " closed: " << p.closedScreenRect
+ << " cursor: " << p.cursorHot << " Prefix: " << p.prefix
+ << " Joystick: " << p.joystick << " MouseHover" << p.hasMouseHover;
+ const int numAreas = p.buttonAreas.size();
+ for (int i = 0; i < numAreas; i++)
+ str << p.buttonAreas[i];
+ return str;
+}
+
+QSize DeviceSkinParameters::secondaryScreenSize() const
+{
+ return backScreenRect.isNull() ? closedScreenRect .size(): backScreenRect.size();
+}
+
+bool DeviceSkinParameters::hasSecondaryScreen() const
+{
+ return secondaryScreenSize() != QSize(0, 0);
+}
+
+bool DeviceSkinParameters::read(const QString &skinDirectory, ReadMode rm, QString *errorMessage)
+{
+ // Figure out the name. remove ending '/' if present
+ QString skinFile = skinDirectory;
+ if (skinFile.endsWith(QLatin1Char('/')))
+ skinFile.truncate(skinFile.length() - 1);
+
+ QFileInfo fi(skinFile);
+ QString fn;
+ if ( fi.isDir() ) {
+ prefix = skinFile;
+ prefix += QLatin1Char('/');
+ fn = prefix;
+ fn += fi.baseName();
+ fn += QLatin1String(".skin");
+ } else if (fi.isFile()){
+ fn = skinFile;
+ prefix = fi.path();
+ prefix += QLatin1Char('/');
+ } else {
+ *errorMessage = DeviceSkin::tr("The skin directory '%1' does not contain a configuration file.").arg(skinDirectory);
+ return false;
+ }
+ QFile f(fn);
+ if (!f.open(QIODevice::ReadOnly )) {
+ *errorMessage = DeviceSkin::tr("The skin configuration file '%1' could not be opened.").arg(fn);
+ return false;
+ }
+ QTextStream ts(&f);
+ const bool rc = read(ts, rm, errorMessage);
+ if (!rc)
+ *errorMessage = DeviceSkin::tr("The skin configuration file '%1' could not be read: %2").arg(fn).arg(*errorMessage);
+ return rc;
+}
+bool DeviceSkinParameters::read(QTextStream &ts, ReadMode rm, QString *errorMessage)
+{
+ QStringList closedAreas;
+ QStringList toggleAreas;
+ QStringList toggleActiveAreas;
+ int nareas = 0;
+ screenDepth = 0;
+ QString mark;
+ ts >> mark;
+ hasMouseHover = true; // historical default
+ if ( mark == QLatin1String("[SkinFile]") ) {
+ const QString UpKey = QLatin1String("Up");
+ const QString DownKey = QLatin1String("Down");
+ const QString ClosedKey = QLatin1String("Closed");
+ const QString ClosedAreasKey = QLatin1String("ClosedAreas");
+ const QString ScreenKey = QLatin1String("Screen");
+ const QString ScreenDepthKey = QLatin1String("ScreenDepth");
+ const QString BackScreenKey = QLatin1String("BackScreen");
+ const QString ClosedScreenKey = QLatin1String("ClosedScreen");
+ const QString CursorKey = QLatin1String("Cursor");
+ const QString AreasKey = QLatin1String("Areas");
+ const QString ToggleAreasKey = QLatin1String("ToggleAreas");
+ const QString ToggleActiveAreasKey = QLatin1String("ToggleActiveAreas");
+ const QString HasMouseHoverKey = QLatin1String("HasMouseHover");
+ // New
+ while (!nareas) {
+ QString line = ts.readLine();
+ if ( line.isNull() )
+ break;
+ if ( line[0] != QLatin1Char('#') && !line.isEmpty() ) {
+ int eq = line.indexOf(QLatin1Char('='));
+ if ( eq >= 0 ) {
+ const QString key = line.left(eq);
+ eq++;
+ while (eq<line.length()-1 && line[eq].isSpace())
+ eq++;
+ const QString value = line.mid(eq);
+ if ( key == UpKey ) {
+ skinImageUpFileName = value;
+ } else if ( key == DownKey ) {
+ skinImageDownFileName = value;
+ } else if ( key == ClosedKey ) {
+ skinImageClosedFileName = value;
+ } else if ( key == ClosedAreasKey ) {
+ closedAreas = value.split(QLatin1Char(' '));
+ } else if ( key == ScreenKey ) {
+ parseRect( value, &screenRect);
+ } else if ( key == ScreenDepthKey ) {
+ screenDepth = value.toInt();
+ } else if ( key == BackScreenKey ) {
+ parseRect(value, &backScreenRect);
+ } else if ( key == ClosedScreenKey ) {
+ parseRect( value, &closedScreenRect );
+ } else if ( key == CursorKey ) {
+ QStringList l = value.split(QLatin1Char(' '));
+ skinCursorFileName = l[0];
+ cursorHot = QPoint(l[1].toInt(),l[2].toInt());
+ } else if ( key == AreasKey ) {
+ nareas = value.toInt();
+ } else if ( key == ToggleAreasKey ) {
+ toggleAreas = value.split(QLatin1Char(' '));
+ } else if ( key == ToggleActiveAreasKey ) {
+ toggleActiveAreas = value.split(QLatin1Char(' '));
+ } else if ( key == HasMouseHoverKey ) {
+ hasMouseHover = value == QLatin1String("true") || value == QLatin1String("1");
+ }
+ } else {
+ *errorMessage = DeviceSkin::tr("Syntax error: %1").arg(line);
+ return false;
+ }
+ }
+ }
+ } else {
+ // Old
+ skinImageUpFileName = mark;
+ QString s;
+ int x,y,w,h,na;
+ ts >> s >> x >> y >> w >> h >> na;
+ skinImageDownFileName = s;
+ screenRect.setRect(x, y, w, h);
+ nareas = na;
+ }
+ // Done for short mode
+ if (rm == ReadSizeOnly)
+ return true;
+ // verify skin files exist
+ skinImageUpFileName.insert(0, prefix);
+ if (!QFile(skinImageUpFileName).exists()) {
+ *errorMessage = DeviceSkin::tr("The skin \"up\" image file '%1' does not exist.").arg(skinImageUpFileName);
+ return false;
+ }
+ if (!skinImageUp.load(skinImageUpFileName)) {
+ *errorMessage = msgImageNotLoaded(skinImageUpFileName);
+ return false;
+ }
+
+ skinImageDownFileName.insert(0, prefix);
+ if (!QFile(skinImageDownFileName).exists()) {
+ *errorMessage = DeviceSkin::tr("The skin \"down\" image file '%1' does not exist.").arg(skinImageDownFileName);
+ return false;
+ }
+ if (!skinImageDown.load(skinImageDownFileName)) {
+ *errorMessage = msgImageNotLoaded(skinImageDownFileName);
+ return false;
+ }
+
+ if (!skinImageClosedFileName.isEmpty()) {
+ skinImageClosedFileName.insert(0, prefix);
+ if (!QFile(skinImageClosedFileName).exists()) {
+ *errorMessage = DeviceSkin::tr("The skin \"closed\" image file '%1' does not exist.").arg(skinImageClosedFileName);
+ return false;
+ }
+ if (!skinImageClosed.load(skinImageClosedFileName)) {
+ *errorMessage = msgImageNotLoaded(skinImageClosedFileName);
+ return false;
+ }
+ }
+
+ if (!skinCursorFileName.isEmpty()) {
+ skinCursorFileName.insert(0, prefix);
+ if (!QFile(skinCursorFileName).exists()) {
+ *errorMessage = DeviceSkin::tr("The skin cursor image file '%1' does not exist.").arg(skinCursorFileName);
+ return false;
+ }
+ if (!skinCursor.load(skinCursorFileName)) {
+ *errorMessage = msgImageNotLoaded(skinCursorFileName);
+ return false;
+ }
+ }
+
+ // read areas
+ if (!nareas)
+ return true;
+ buttonAreas.reserve(nareas);
+
+ int i = 0;
+ ts.readLine(); // eol
+ joystick = -1;
+ const QString Joystick = QLatin1String("Joystick");
+ while (i < nareas && !ts.atEnd() ) {
+ buttonAreas.push_back(DeviceSkinButtonArea());
+ DeviceSkinButtonArea &area = buttonAreas.back();
+ const QString line = ts.readLine();
+ if ( !line.isEmpty() && line[0] != QLatin1Char('#') ) {
+ const QStringList tok = line.split(QRegExp(QLatin1String("[ \t][ \t]*")));
+ if ( tok.count()<6 ) {
+ *errorMessage = DeviceSkin::tr("Syntax error in area definition: %1").arg(line);
+ return false;
+ } else {
+ area.name = tok[0];
+ QString k = tok[1];
+ if ( k.left(2).toLower() == QLatin1String("0x")) {
+ area.keyCode = k.mid(2).toInt(0,16);
+ } else {
+ area.keyCode = k.toInt();
+ }
+
+ int p=0;
+ for (int j=2; j < tok.count() - 1; ) {
+ const int x = tok[j++].toInt();
+ const int y = tok[j++].toInt();
+ area.area.putPoints(p++,1,x,y);
+ }
+
+ const QChar doubleQuote = QLatin1Char('"');
+ if ( area.name[0] == doubleQuote && area.name.endsWith(doubleQuote)) {
+ area.name.truncate(area.name.size() - 1);
+ area.name.remove(0, 1);
+ }
+ if ( area.name.length() == 1 )
+ area.text = area.name;
+ if ( area.name == Joystick)
+ joystick = i;
+ area.activeWhenClosed = closedAreas.contains(area.name)
+ || area.keyCode == Qt::Key_Flip; // must be to work
+ area.toggleArea = toggleAreas.contains(area.name);
+ area.toggleActiveArea = toggleActiveAreas.contains(area.name);
+ if ( area.toggleArea )
+ toggleAreaList += i;
+ i++;
+ }
+ }
+ }
+ if (i != nareas) {
+ qWarning() << DeviceSkin::tr("Mismatch in number of areas, expected %1, got %2.")
+ .arg(nareas).arg(i);
+ }
+ if (debugDeviceSkin)
+ qDebug() << *this;
+ return true;
+}
+
+// --------- CursorWindow declaration
+
+namespace qvfb_internal {
+
+class CursorWindow : public QWidget
+{
+public:
+ explicit CursorWindow(const QImage &cursor, QPoint hot, QWidget *sk);
+
+ void setView(QWidget*);
+ void setPos(QPoint);
+ bool handleMouseEvent(QEvent *ev);
+
+protected:
+ bool event( QEvent *);
+ bool eventFilter( QObject*, QEvent *);
+
+private:
+ QWidget *mouseRecipient;
+ QWidget *m_view;
+ QWidget *skin;
+ QPoint hotspot;
+};
+}
+
+// --------- Skin
+
+DeviceSkin::DeviceSkin(const DeviceSkinParameters &parameters, QWidget *p ) :
+ QWidget(p),
+ m_parameters(parameters),
+ buttonRegions(parameters.buttonAreas.size(), QRegion()),
+ parent(p),
+ m_view(0),
+ m_secondaryView(0),
+ buttonPressed(false),
+ buttonIndex(0),
+ cursorw(0),
+ joydown(0),
+ t_skinkey(new QTimer(this)),
+ t_parentmove(new QTimer(this)),
+ flipped_open(true)
+{
+ Q_ASSERT(p);
+ setMouseTracking(true);
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ setZoom(1.0);
+ connect( t_skinkey, SIGNAL(timeout()), this, SLOT(skinKeyRepeat()) );
+ t_parentmove->setSingleShot( true );
+ connect( t_parentmove, SIGNAL(timeout()), this, SLOT(moveParent()) );
+}
+
+void DeviceSkin::skinKeyRepeat()
+{
+ if ( m_view ) {
+ const DeviceSkinButtonArea &area = m_parameters.buttonAreas[buttonIndex];
+ emit skinKeyReleaseEvent( area.keyCode,area.text, true );
+ emit skinKeyPressEvent( area.keyCode, area.text, true );
+ t_skinkey->start(key_repeat_period);
+ }
+}
+
+void DeviceSkin::calcRegions()
+{
+ const int numAreas = m_parameters.buttonAreas.size();
+ for (int i=0; i<numAreas; i++) {
+ QPolygon xa(m_parameters.buttonAreas[i].area.count());
+ int n = m_parameters.buttonAreas[i].area.count();
+ for (int p=0; p<n; p++) {
+ xa.setPoint(p,transform.map(m_parameters.buttonAreas[i].area[p]));
+ }
+ if ( n == 2 ) {
+ buttonRegions[i] = QRegion(xa.boundingRect());
+ } else {
+ buttonRegions[i] = QRegion(xa);
+ }
+ }
+}
+
+void DeviceSkin::loadImages()
+{
+ QImage iup = m_parameters.skinImageUp;
+ QImage idown = m_parameters.skinImageDown;
+
+ QImage iclosed;
+ const bool hasClosedImage = !m_parameters.skinImageClosed.isNull();
+
+ if (hasClosedImage)
+ iclosed = m_parameters.skinImageClosed;
+ QImage icurs;
+ const bool hasCursorImage = !m_parameters.skinCursor.isNull();
+ if (hasCursorImage)
+ icurs = m_parameters.skinCursor;
+
+ if (!transform.isIdentity()) {
+ iup = iup.transformed(transform, Qt::SmoothTransformation);
+ idown = idown.transformed(transform, Qt::SmoothTransformation);
+ if (hasClosedImage)
+ iclosed = iclosed.transformed(transform, Qt::SmoothTransformation);
+ if (hasCursorImage)
+ icurs = icurs.transformed(transform, Qt::SmoothTransformation);
+ }
+ const Qt::ImageConversionFlags conv = Qt::ThresholdAlphaDither|Qt::AvoidDither;
+ skinImageUp = QPixmap::fromImage(iup);
+ skinImageDown = QPixmap::fromImage(idown, conv);
+ if (hasClosedImage)
+ skinImageClosed = QPixmap::fromImage(iclosed, conv);
+ if (hasCursorImage)
+ skinCursor = QPixmap::fromImage(icurs, conv);
+
+ setFixedSize( skinImageUp.size() );
+ if (!skinImageUp.mask())
+ skinImageUp.setMask(skinImageUp.createHeuristicMask());
+ if (!skinImageClosed.mask())
+ skinImageClosed.setMask(skinImageClosed.createHeuristicMask());
+
+ QWidget* parent = parentWidget();
+ parent->setMask( skinImageUp.mask() );
+ parent->setFixedSize( skinImageUp.size() );
+
+ delete cursorw;
+ cursorw = 0;
+ if (hasCursorImage) {
+ cursorw = new qvfb_internal::CursorWindow(m_parameters.skinCursor, m_parameters.cursorHot, this);
+ if ( m_view )
+ cursorw->setView(m_view);
+ }
+}
+
+DeviceSkin::~DeviceSkin( )
+{
+ delete cursorw;
+}
+
+void DeviceSkin::setTransform( const QMatrix& wm )
+{
+ transform = QImage::trueMatrix(wm,m_parameters.skinImageUp.width(),m_parameters.skinImageUp.height());
+ calcRegions();
+ loadImages();
+ if ( m_view ) {
+ QPoint p = transform.map(QPolygon(m_parameters.screenRect)).boundingRect().topLeft();
+ m_view->move(p);
+ }
+ updateSecondaryScreen();
+}
+
+void DeviceSkin::setZoom( double z )
+{
+ setTransform(QMatrix().scale(z,z));
+}
+
+void DeviceSkin::updateSecondaryScreen()
+{
+ if (!m_secondaryView)
+ return;
+ if (flipped_open) {
+ if (m_parameters.backScreenRect.isNull()) {
+ m_secondaryView->hide();
+ } else {
+ m_secondaryView->move(transform.map(QPolygon(m_parameters.backScreenRect)).boundingRect().topLeft());
+ m_secondaryView->show();
+ }
+ } else {
+ if (m_parameters.closedScreenRect.isNull()) {
+ m_secondaryView->hide();
+ } else {
+ m_secondaryView->move(transform.map(QPolygon(m_parameters.closedScreenRect)).boundingRect().topLeft());
+ m_secondaryView->show();
+ }
+ }
+}
+
+void DeviceSkin::setView( QWidget *v )
+{
+ m_view = v;
+ m_view->setFocus();
+ m_view->move(transform.map(QPolygon(m_parameters.screenRect)).boundingRect().topLeft());
+ if ( cursorw )
+ cursorw->setView(v);
+}
+
+void DeviceSkin::setSecondaryView( QWidget *v )
+{
+ m_secondaryView = v;
+ updateSecondaryScreen();
+}
+
+void DeviceSkin::paintEvent( QPaintEvent *)
+{
+ QPainter p( this );
+ if ( flipped_open ) {
+ p.drawPixmap( 0, 0, skinImageUp );
+ } else {
+ p.drawPixmap( 0, 0, skinImageClosed );
+ }
+ QList<int> toDraw;
+ if ( buttonPressed == true ) {
+ toDraw += buttonIndex;
+ }
+ foreach (int toggle, m_parameters.toggleAreaList) {
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[toggle];
+ if ( flipped_open || ba.activeWhenClosed ) {
+ if ( ba.toggleArea && ba.toggleActiveArea )
+ toDraw += toggle;
+ }
+ }
+ foreach (int button, toDraw ) {
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[button];
+ const QRect r = buttonRegions[button].boundingRect();
+ if ( ba.area.count() > 2 )
+ p.setClipRegion(buttonRegions[button]);
+ p.drawPixmap( r.topLeft(), skinImageDown, r);
+ }
+}
+
+void DeviceSkin::mousePressEvent( QMouseEvent *e )
+{
+ if (e->button() == Qt::RightButton) {
+ emit popupMenu();
+ } else {
+ buttonPressed = false;
+
+ onjoyrelease = -1;
+ const int numAreas = m_parameters.buttonAreas.size();
+ for (int i = 0; i < numAreas ; i++) {
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[i];
+ if ( buttonRegions[i].contains( e->pos() ) ) {
+ if ( flipped_open || ba.activeWhenClosed ) {
+ if ( m_parameters.joystick == i ) {
+ joydown = true;
+ } else {
+ if ( joydown )
+ onjoyrelease = i;
+ else
+ startPress(i);
+ break;
+ if (debugDeviceSkin)// Debug message to be sure we are clicking the right areas
+ qDebug()<< m_parameters.buttonAreas[i].name << " clicked";
+ }
+ }
+ }
+ }
+ clickPos = e->pos();
+// This is handy for finding the areas to define rectangles for new skins
+ if (debugDeviceSkin)
+ qDebug()<< "Clicked in " << e->pos().x() << ',' << e->pos().y();
+ clickPos = e->pos();
+ }
+}
+
+void DeviceSkin::flip(bool open)
+{
+ if ( flipped_open == open )
+ return;
+ if ( open ) {
+ parent->setMask( skinImageUp.mask() );
+ emit skinKeyReleaseEvent( Qt::Key(Qt::Key_Flip), QString(), false);
+ } else {
+ parent->setMask( skinImageClosed.mask() );
+ emit skinKeyPressEvent( Qt::Key(Qt::Key_Flip), QString(), false);
+ }
+ flipped_open = open;
+ updateSecondaryScreen();
+ repaint();
+}
+
+void DeviceSkin::startPress(int i)
+{
+ buttonPressed = true;
+ buttonIndex = i;
+ if (m_view) {
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[buttonIndex];
+ if ( ba.keyCode == Qt::Key_Flip ) {
+ flip(!flipped_open);
+ } else if ( ba.toggleArea ) {
+ bool active = !ba.toggleActiveArea;
+ const_cast<DeviceSkinButtonArea &>(ba).toggleActiveArea = active;
+ if ( active )
+ emit skinKeyPressEvent( ba.keyCode, ba.text, false);
+ else
+ emit skinKeyReleaseEvent( ba.keyCode, ba.text, false);
+ } else {
+ emit skinKeyPressEvent( ba.keyCode, ba.text, false);
+ t_skinkey->start(key_repeat_delay);
+ }
+ repaint( buttonRegions[buttonIndex].boundingRect() );
+ }
+}
+
+void DeviceSkin::endPress()
+{
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[buttonIndex];
+ if (m_view && ba.keyCode != Qt::Key_Flip && !ba.toggleArea )
+ emit skinKeyReleaseEvent(ba.keyCode, ba.text, false );
+ t_skinkey->stop();
+ buttonPressed = false;
+ repaint( buttonRegions[buttonIndex].boundingRect() );
+}
+
+void DeviceSkin::mouseMoveEvent( QMouseEvent *e )
+{
+ if ( e->buttons() & Qt::LeftButton ) {
+ const int joystick = m_parameters.joystick;
+ QPoint newpos = e->globalPos() - clickPos;
+ if ( joydown ) {
+ int k1=0, k2=0;
+ if ( newpos.x() < -joydistance ) {
+ k1 = joystick+1;
+ } else if ( newpos.x() > +joydistance ) {
+ k1 = joystick+3;
+ }
+ if ( newpos.y() < -joydistance ) {
+ k2 = joystick+2;
+ } else if ( newpos.y() > +joydistance ) {
+ k2 = joystick+4;
+ }
+ if ( k1 || k2 ) {
+ if ( !buttonPressed ) {
+ onjoyrelease = -1;
+ if ( k1 && k2 ) {
+ startPress(k2);
+ endPress();
+ }
+ startPress(k1 ? k1 : k2);
+ }
+ } else if ( buttonPressed ) {
+ endPress();
+ }
+ } else if ( buttonPressed == false ) {
+ parentpos = newpos;
+ if ( !t_parentmove->isActive() )
+ t_parentmove->start(50);
+ }
+ }
+ if ( cursorw )
+ cursorw->setPos(e->globalPos());
+}
+
+void DeviceSkin::moveParent()
+{
+ parent->move( parentpos );
+}
+
+void DeviceSkin::mouseReleaseEvent( QMouseEvent * )
+{
+ if ( buttonPressed )
+ endPress();
+ if ( joydown ) {
+ joydown = false;
+ if ( onjoyrelease >= 0 ) {
+ startPress(onjoyrelease);
+ endPress();
+ }
+ }
+}
+
+bool DeviceSkin::hasCursor() const
+{
+ return !skinCursor.isNull();
+}
+
+// ------------------ CursorWindow implementation
+
+namespace qvfb_internal {
+
+bool CursorWindow::eventFilter( QObject *, QEvent *ev)
+{
+ handleMouseEvent(ev);
+ return false;
+}
+
+bool CursorWindow::event( QEvent *ev )
+{
+ if (handleMouseEvent(ev))
+ return true;
+ return QWidget::event(ev);
+}
+
+bool CursorWindow::handleMouseEvent(QEvent *ev)
+{
+ bool handledEvent = false;
+ static int inhere=0;
+ if ( !inhere ) {
+ inhere++;
+ if ( m_view ) {
+ if ( ev->type() >= QEvent::MouseButtonPress && ev->type() <= QEvent::MouseMove ) {
+ QMouseEvent *e = (QMouseEvent*)ev;
+ QPoint gp = e->globalPos();
+ QPoint vp = m_view->mapFromGlobal(gp);
+ QPoint sp = skin->mapFromGlobal(gp);
+ if ( e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick ) {
+ if ( m_view->rect().contains(vp) )
+ mouseRecipient = m_view;
+ else if ( skin->parentWidget()->geometry().contains(gp) )
+ mouseRecipient = skin;
+ else
+ mouseRecipient = 0;
+ }
+ if ( mouseRecipient ) {
+ setPos(gp);
+ QMouseEvent me(e->type(),mouseRecipient==skin ? sp : vp,gp,e->button(),e->buttons(),e->modifiers());
+ QApplication::sendEvent(mouseRecipient, &me);
+ } else if ( !skin->parentWidget()->geometry().contains(gp) ) {
+ hide();
+ } else {
+ setPos(gp);
+ }
+ if ( e->type() == QEvent::MouseButtonRelease )
+ mouseRecipient = 0;
+ handledEvent = true;
+ }
+ }
+ inhere--;
+ }
+ return handledEvent;
+}
+
+void CursorWindow::setView(QWidget* v)
+{
+ if ( m_view ) {
+ m_view->removeEventFilter(this);
+ m_view->removeEventFilter(this);
+ }
+ m_view = v;
+ m_view->installEventFilter(this);
+ m_view->installEventFilter(this);
+ mouseRecipient = 0;
+}
+
+CursorWindow::CursorWindow(const QImage &img, QPoint hot, QWidget* sk)
+ :QWidget(0),
+ m_view(0), skin(sk),
+ hotspot(hot)
+{
+ setWindowFlags( Qt::FramelessWindowHint );
+ mouseRecipient = 0;
+ setMouseTracking(true);
+#ifndef QT_NO_CURSOR
+ setCursor(Qt::BlankCursor);
+#endif
+ QPixmap p;
+ p = QPixmap::fromImage(img);
+ if (!p.mask()) {
+ if ( img.hasAlphaChannel() ) {
+ QBitmap bm;
+ bm = QPixmap::fromImage(img.createAlphaMask());
+ p.setMask( bm );
+ } else {
+ QBitmap bm;
+ bm = QPixmap::fromImage(img.createHeuristicMask());
+ p.setMask( bm );
+ }
+ }
+ QPalette palette;
+ palette.setBrush(backgroundRole(), QBrush(p));
+ setPalette(palette);
+ setFixedSize( p.size() );
+ if ( !p.mask().isNull() )
+ setMask( p.mask() );
+}
+
+void CursorWindow::setPos(QPoint p)
+{
+ move(p-hotspot);
+ show();
+ raise();
+}
+}
+
+#ifdef TEST_SKIN
+
+int main(int argc,char *argv[])
+{
+ if (argc < 1)
+ return 1;
+ const QString skinFile = QString::fromUtf8(argv[1]);
+ QApplication app(argc,argv);
+ QMainWindow mw;
+
+ DeviceSkinParameters params;
+ QString errorMessage;
+ if (!params.read(skinFile, DeviceSkinParameters::ReadAll, &errorMessage)) {
+ qWarning() << errorMessage;
+ return 1;
+ }
+ DeviceSkin ds(params, &mw);
+ // View Dialog
+ QDialog *dialog = new QDialog();
+ QHBoxLayout *dialogLayout = new QHBoxLayout();
+ dialog->setLayout(dialogLayout);
+ QDialogButtonBox *dialogButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
+ QObject::connect(dialogButtonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
+ QObject::connect(dialogButtonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
+ dialogLayout->addWidget(dialogButtonBox);
+ dialog->setFixedSize(params.screenSize());
+ dialog->setParent(&ds, Qt::SubWindow);
+ dialog->setAutoFillBackground(true);
+ ds.setView(dialog);
+
+ QObject::connect(&ds, SIGNAL(popupMenu()), &mw, SLOT(close()));
+ QObject::connect(&ds, SIGNAL(skinKeyPressEvent(int,QString,bool)), &mw, SLOT(close()));
+ mw.show();
+ return app.exec();
+}
+
+#endif
+
+QT_END_NAMESPACE
+
diff --git a/src/shared/deviceskin/deviceskin.h b/src/shared/deviceskin/deviceskin.h
new file mode 100644
index 000000000..8a53acffd
--- /dev/null
+++ b/src/shared/deviceskin/deviceskin.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SKIN_H
+#define SKIN_H
+
+#include <QtGui/QWidget>
+#include <QtGui/QPolygon>
+#include <QtGui/QRegion>
+#include <QtGui/QPixmap>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+namespace qvfb_internal {
+ class CursorWindow;
+}
+
+class QTextStream;
+
+// ------- Button Area
+struct DeviceSkinButtonArea {
+ DeviceSkinButtonArea();
+ QString name;
+ int keyCode;
+ QPolygon area;
+ QString text;
+ bool activeWhenClosed;
+ bool toggleArea;
+ bool toggleActiveArea;
+};
+
+// -------- Parameters
+struct DeviceSkinParameters {
+ enum ReadMode { ReadAll, ReadSizeOnly };
+ bool read(const QString &skinDirectory, ReadMode rm, QString *errorMessage);
+ bool read(QTextStream &ts, ReadMode rm, QString *errorMessage);
+
+ QSize screenSize() const { return screenRect.size(); }
+ QSize secondaryScreenSize() const;
+ bool hasSecondaryScreen() const;
+
+ QString skinImageUpFileName;
+ QString skinImageDownFileName;
+ QString skinImageClosedFileName;
+ QString skinCursorFileName;
+
+ QImage skinImageUp;
+ QImage skinImageDown;
+ QImage skinImageClosed;
+ QImage skinCursor;
+
+ QRect screenRect;
+ QRect backScreenRect;
+ QRect closedScreenRect;
+ int screenDepth;
+ QPoint cursorHot;
+ QVector<DeviceSkinButtonArea> buttonAreas;
+ QList<int> toggleAreaList;
+
+ int joystick;
+ QString prefix;
+ bool hasMouseHover;
+};
+
+// --------- Skin Widget
+class DeviceSkin : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit DeviceSkin(const DeviceSkinParameters &parameters, QWidget *p );
+ ~DeviceSkin( );
+
+ QWidget *view() const { return m_view; }
+ void setView( QWidget *v );
+
+ QWidget *secondaryView() const { return m_secondaryView; }
+ void setSecondaryView( QWidget *v );
+
+ void setZoom( double );
+ void setTransform( const QMatrix& );
+
+ bool hasCursor() const;
+
+ QString prefix() const {return m_parameters.prefix;}
+
+signals:
+ void popupMenu();
+ void skinKeyPressEvent(int code, const QString& text, bool autorep);
+ void skinKeyReleaseEvent(int code, const QString& text, bool autorep);
+
+protected slots:
+ void skinKeyRepeat();
+ void moveParent();
+
+protected:
+ virtual void paintEvent( QPaintEvent * );
+ virtual void mousePressEvent( QMouseEvent *e );
+ virtual void mouseMoveEvent( QMouseEvent *e );
+ virtual void mouseReleaseEvent( QMouseEvent * );
+
+private:
+ void calcRegions();
+ void flip(bool open);
+ void updateSecondaryScreen();
+ void loadImages();
+ void startPress(int);
+ void endPress();
+
+ const DeviceSkinParameters m_parameters;
+ QVector<QRegion> buttonRegions;
+ QPixmap skinImageUp;
+ QPixmap skinImageDown;
+ QPixmap skinImageClosed;
+ QPixmap skinCursor;
+ QWidget *parent;
+ QWidget *m_view;
+ QWidget *m_secondaryView;
+ QPoint parentpos;
+ QPoint clickPos;
+ bool buttonPressed;
+ int buttonIndex;
+ QMatrix transform;
+ qvfb_internal::CursorWindow *cursorw;
+
+ bool joydown;
+ QTimer *t_skinkey;
+ QTimer *t_parentmove;
+ int onjoyrelease;
+
+ bool flipped_open;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/deviceskin/deviceskin.pri b/src/shared/deviceskin/deviceskin.pri
new file mode 100644
index 000000000..3e9935abb
--- /dev/null
+++ b/src/shared/deviceskin/deviceskin.pri
@@ -0,0 +1,12 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/deviceskin.h
+SOURCES += $$PWD/deviceskin.cpp
+RESOURCES += $$PWD/skins/ClamshellPhone.qrc \
+ $$PWD/skins/SmartPhone2.qrc \
+ $$PWD/skins/SmartPhone.qrc \
+ $$PWD/skins/SmartPhoneWithButtons.qrc \
+ $$PWD/skins/TouchscreenPhone.qrc \
+ $$PWD/skins/PortableMedia.qrc \
+ $$PWD/skins/S60-QVGA-Candybar.qrc \
+ $$PWD/skins/S60-nHD-Touchscreen.qrc
+
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.qrc b/src/shared/deviceskin/skins/ClamshellPhone.qrc
new file mode 100644
index 000000000..39cd42274
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>ClamshellPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin
new file mode 100644
index 000000000..cb24a8e14
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin
@@ -0,0 +1,30 @@
+[SkinFile]
+Up=ClamshellPhone1-5.png
+Down=ClamshellPhone1-5-pressed.png
+Closed=ClamshellPhone1-5-closed.png
+Screen=72 84 176 208
+Areas=22
+HasMouseHover=false
+
+"Power" 0x0100000a 205 563 249 586
+"1" 0x0031 62 414 119 438
+"2" 0x0032 130 414 189 438
+"3" 0x0033 198 413 257 438
+"4" 0x0034 54 444 117 470
+"5" 0x0035 128 444 189 471
+"6" 0x0036 202 444 264 471
+"7" 0x0037 47 477 113 507
+"8" 0x0038 126 477 190 507
+"9" 0x0039 205 478 270 509
+"*" 0x002a 39 515 110 552
+"0" 0x0030 122 515 195 553
+"#" 0x0023 207 516 280 553
+"Context1" 0x01100000 137 360 108 383 123 410 90 409 60 387 63 378 100 362
+"Back" 0x01000061 184 361 206 376 213 387 197 410 226 410 256 392 258 381 244 369
+"Backspace" 0x01000003 68 563 113 587
+"Select" 0x01010000 160 391 172 390 181 386 184 381 180 377 173 373 165 372 155 372 145 375 138 378 136 382 138 387 147 390
+"Left" 0x1000012 141 390 136 385 136 381 143 375 132 371 120 380 121 393 129 401
+"Down" 0x1000015 143 389 130 402 162 412 191 404 175 390
+"Right" 0x1000014 186 370 176 375 184 382 182 387 175 390 190 404 201 396 202 375
+"Up" 0x1000013 133 370 143 374 176 374 185 370 169 362 149 362
+"Flip" 0x01100006 98 325 225 353
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
new file mode 100644
index 000000000..88ba3a147
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
new file mode 100644
index 000000000..971cdef64
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png
new file mode 100644
index 000000000..f3550ee7d
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf
new file mode 100644
index 000000000..e349dbc1f
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Flip
+Key4=Backspace
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#=#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/PortableMedia.qrc b/src/shared/deviceskin/skins/PortableMedia.qrc
new file mode 100644
index 000000000..a902f1a73
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>PortableMedia.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin b/src/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin
new file mode 100644
index 000000000..b76e5cfad
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin
@@ -0,0 +1,14 @@
+[SkinFile]
+Up=portablemedia.png
+Down=portablemedia-pressed.png
+Screen=18 20 480 272
+Areas=7
+HasMouseHover=false
+
+"Context1" 0x01100000 530 192 565 223
+"Back" 0x01000061 530 138 565 173
+"Select" 0x01010000 530 65 565 98
+"Left" 0x1000012 529 67 519 57 511 65 511 104 519 110 529 100 529 98
+"Down" 0x1000015 530 102 520 111 529 120 569 120 577 114 566 103 564 103
+"Right" 0x1000014 565 65 576 52 585 67 585 102 578 113 567 104
+"Up" 0x1000013 530 65 519 55 528 48 567 48 573 51 564 66
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf
new file mode 100644
index 000000000..514e8816e
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf
@@ -0,0 +1,23 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Map=123
+Default=1
+1=Applications/mediaplayer.desktop
+2=Applications/photoedit.desktop
+3=Settings
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png
new file mode 100644
index 000000000..730e76287
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png
new file mode 100644
index 000000000..e44cbe160
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf
new file mode 100644
index 000000000..127e07c8e
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.qrc b/src/shared/deviceskin/skins/S60-QVGA-Candybar.qrc
new file mode 100644
index 000000000..813848479
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>S60-QVGA-Candybar.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png
new file mode 100644
index 000000000..89d40cbed
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png
new file mode 100644
index 000000000..0d0e598b9
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin
new file mode 100644
index 000000000..4f8fe5dca
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin
@@ -0,0 +1,15 @@
+[SkinFile]
+Up=S60-QVGA-Candybar.png
+Down=S60-QVGA-Candybar-down.png
+Screen=61 93 240 320
+Areas=7
+HasMouseHover=false
+
+
+"Context1" 0x01100000 54 469 151 469 140 483 88 485 81 496 54 498
+"Back" 0x01000061 211 468 307 467 307 498 278 497 219 486
+"Select" 0x01010000 165 491 196 522
+"Left" 0x1000012 149 474 166 492 163 519 143 538 142 481
+"Down" 0x1000015 164 521 195 522 212 539 204 545 154 544 145 536
+"Right" 0x1000014 214 475 219 487 219 528 212 539 196 522 197 492
+"Up" 0x1000013 150 474 156 467 209 467 213 476 197 489 165 489
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf
new file mode 100644
index 000000000..e349dbc1f
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Flip
+Key4=Backspace
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#=#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc
new file mode 100644
index 000000000..daf0cc363
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>S60-nHD-Touchscreen.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png
new file mode 100644
index 000000000..7253e3801
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png
new file mode 100644
index 000000000..675563e5c
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin
new file mode 100644
index 000000000..ed25d0eac
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin
@@ -0,0 +1,10 @@
+[SkinFile]
+Up=S60-nHD-Touchscreen.png
+Down=S60-nHD-Touchscreen-down.png
+Screen=53 183 360 640
+Areas=3
+HasMouseHover=false
+
+"Call" 0x01100004 76 874 171 899
+"Hangup" 0x01100005 300 876 393 899
+"Home" 0x1000010 174 878 298 899
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf
new file mode 100644
index 000000000..6665125c9
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf
@@ -0,0 +1,53 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/mediaplayer.desktop
+3=Applications/simapp.desktop,Applications/calculator.desktop
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Applications/datebook.desktop
+7=Games
+8=Settings/beaming.desktop
+9=Applications/todolist.desktop
+*=Settings
+0=Applications
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Back
+Key2=Select
+Key3=Call
+Key4=Hangup
+[Device]
+PrimaryInput=Touchscreen
+[Button]
+Count=2
+[Button0]
+Name[]=Home Button
+Key=Home
+PressedActionMappable=0
+PressedActionService=TaskManager
+PressedActionMessage=multitask()
+HeldActionMappable=0
+HeldActionService=TaskManager
+HeldActionMessage=showRunningTasks()
+[Button1]
+Name=Power Button
+Key=Hangup
+HeldActionService=Launcher
+HeldActionMessage=execute(QString)
+HeldActionArgs=@ByteArray(\0\0\0\x1\0\0\0\n\0\0\0\0\x10\0s\0h\0u\0t\0\x64\0o\0w\0n)
diff --git a/src/shared/deviceskin/skins/SmartPhone.qrc b/src/shared/deviceskin/skins/SmartPhone.qrc
new file mode 100644
index 000000000..8bb53259a
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png
new file mode 100644
index 000000000..d0db2ed35
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png
new file mode 100644
index 000000000..e6ac5a0f3
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin
new file mode 100644
index 000000000..2f44c5aa8
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin
@@ -0,0 +1,28 @@
+[SkinFile]
+Up=SmartPhone.png
+Down=SmartPhone-pressed.png
+Screen=90 107 176 208
+Areas=21
+HasMouseHover=false
+
+"1" 0x0031 138 459 149 473 142 483 120 484 102 477 95 464 99 457 121 454
+"2" 0x0032 153 467 202 492
+"3" 0x0033 258 457 260 470 243 483 215 484 207 474 218 460 248 453
+"4" 0x0034 138 492 149 506 142 516 120 517 102 510 95 497 99 490 121 487
+"5" 0x0035 153 499 202 524
+"6" 0x0036 258 489 260 502 243 515 215 516 207 506 218 492 248 485
+"7" 0x0037 138 524 149 538 142 548 120 549 102 542 95 529 99 522 121 519
+"8" 0x0038 153 531 202 556
+"9" 0x0039 258 521 260 534 243 547 215 548 207 538 218 524 248 517
+"*" 0x002a 138 556 149 570 142 580 120 581 102 574 95 561 99 554 121 551
+"0" 0x0030 153 564 202 589
+"#" 0x0023 258 554 260 567 243 580 215 581 207 571 218 557 248 550
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Select" 0x01010000 160 338 195 371
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
diff --git a/src/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf
new file mode 100644
index 000000000..110335055
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Call
+Key4=Hangup
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#='#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/SmartPhone2.qrc b/src/shared/deviceskin/skins/SmartPhone2.qrc
new file mode 100644
index 000000000..751e9852b
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhone2.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png
new file mode 100644
index 000000000..d4eb5b0c8
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png
new file mode 100644
index 000000000..48ccc1c5a
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin
new file mode 100644
index 000000000..16884bfb5
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin
@@ -0,0 +1,25 @@
+SmartPhone2.png SmartPhone2-pressed.png
+90 107
+176 220
+21
+"Menu" 0x01100000 70 400 115 427
+"Backspace" 0x01000003 238 400 285 427
+"1" 0x0031 138 437 149 451 142 461 120 462 102 455 95 442 99 435 121 432
+"2" 0x0032 153 445 202 470
+"3" 0x0033 258 435 260 448 243 461 215 462 207 452 218 438 248 431
+"4" 0x0034 138 470 149 484 142 494 120 495 102 488 95 475 99 468 121 465
+"5" 0x0035 153 477 202 502
+"6" 0x0036 258 467 260 480 243 493 215 494 207 484 218 470 248 463
+"7" 0x0037 138 502 149 516 142 526 120 527 102 520 95 507 99 500 121 497
+"8" 0x0038 153 509 202 534
+"9" 0x0039 258 499 260 512 243 525 215 526 207 516 218 502 248 495
+"*" 0x002a 138 534 149 548 142 558 120 559 102 552 95 539 99 532 121 529
+"0" 0x0030 153 542 202 567
+"#" 0x0023 258 532 260 545 243 558 215 559 207 549 218 535 248 528
+"Yes" 0x01010001 91 343 141 393
+"No" 0x01010002 219 343 269 393
+"Select" 0x01010000 160 356 195 389
+"Left" 0x1000012 159 356 149 346 141 354 141 391 149 399 159 389 159 387
+"Down" 0x1000015 160 391 150 400 159 409 199 409 207 403 196 392 194 392
+"Right" 0x1000014 195 354 206 341 215 356 215 391 208 402 197 393
+"Up" 0x1000013 160 354 149 344 158 337 197 337 203 340 194 355
diff --git a/src/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf
new file mode 100644
index 000000000..b08320347
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf
@@ -0,0 +1,52 @@
+[Button]
+[IMethod]
+key_count = 5
+key_hold_action_1 = insertText
+key_hold_action_2 = insertText
+key_hold_action_3 = insertSymbol
+key_hold_action_4 = changeMode
+key_hold_arg_1 = 1
+key_hold_arg_2 = 0
+key_id_1 = 1
+key_id_2 = 0
+key_id_3 = *
+key_id_4 = #
+key_id_5 = *
+key_mode_1 = Abc
+key_mode_2 = Abc
+key_mode_3 = Abc
+key_mode_4 = Abc
+key_mode_5 = Phone
+key_tap_action_1 = insertText
+key_tap_action_2 = insertSpace
+key_tap_action_3 = modifyText
+key_tap_action_4 = changeShift
+key_tap_action_5 = insertText
+key_tap_arg_1 = .,'?!-@:〓
+key_tap_arg_5 = *+pw
+[Menu]
+1 = Applications/camera.desktop
+2 = Applications/datebook.desktop
+3 = Games
+4 = Applications/qtmail.desktop
+5 = Applications/addressbook.desktop
+6 = Settings
+7 = Settings/Beaming.desktop
+8 = Applications
+9 = Documents
+Columns = 3
+Default = 5
+Map = 123456789
+Rows = 3
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+[SystemButtons]
+Count=5
+Key0=Yes
+Key1=Select
+Key2=No
+Key3=Menu
+Key4=Backspace
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.qrc b/src/shared/deviceskin/skins/SmartPhoneWithButtons.qrc
new file mode 100644
index 000000000..f3393ba9d
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhoneWithButtons.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
new file mode 100644
index 000000000..456a068ee
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
new file mode 100644
index 000000000..5ffbd6e4e
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
new file mode 100644
index 000000000..9afa67f30
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
@@ -0,0 +1,31 @@
+[SkinFile]
+Up=SmartPhoneWithButtons.png
+Down=SmartPhoneWithButtons-pressed.png
+Screen=90 107 176 208
+Areas=24
+HasMouseHover=false
+
+"1" 0x0031 138 459 149 473 142 483 120 484 102 477 95 464 99 457 121 454
+"2" 0x0032 153 467 202 492
+"3" 0x0033 258 457 260 470 243 483 215 484 207 474 218 460 248 453
+"4" 0x0034 138 492 149 506 142 516 120 517 102 510 95 497 99 490 121 487
+"5" 0x0035 153 499 202 524
+"6" 0x0036 258 489 260 502 243 515 215 516 207 506 218 492 248 485
+"7" 0x0037 138 524 149 538 142 548 120 549 102 542 95 529 99 522 121 519
+"8" 0x0038 153 531 202 556
+"9" 0x0039 258 521 260 534 243 547 215 548 207 538 218 524 248 517
+"*" 0x002a 138 556 149 570 142 580 120 581 102 574 95 561 99 554 121 551
+"0" 0x0030 153 564 202 589
+"#" 0x0023 258 554 260 567 243 580 215 581 207 571 218 557 248 550
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Select" 0x01010000 160 338 195 371
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
+"Home" 0x1000010 164 402 195 434
+"F1" 0x1000030 138 422 163 448
+"F2" 0x1000031 196 422 220 448
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf
new file mode 100644
index 000000000..ebd6926ae
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf
@@ -0,0 +1,103 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Button]
+Count=3
+[Button0]
+Name[]=Calendar Button
+Key=F1
+PressedActionService=Calendar
+PressedActionMessage=raiseToday()
+HeldActionService=Calendar
+HeldActionMessage=newEvent()
+[Button1]
+Name[]=Tasks Button
+Key=F2
+PressedActionService=Tasks
+PressedActionMessage=raise()
+HeldActionService=Tasks
+HeldActionMessage=newTask()
+[Button2]
+Name[]=Home Button
+Key=Home
+PressedActionMappable=0
+PressedActionService=TaskManager
+PressedActionMessage=multitask()
+HeldActionMappable=0
+HeldActionService=TaskManager
+HeldActionMessage=showRunningTasks()
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Call
+Key4=Hangup
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#='#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.qrc b/src/shared/deviceskin/skins/TouchscreenPhone.qrc
new file mode 100644
index 000000000..023144d2f
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>TouchscreenPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
new file mode 100644
index 000000000..01acb8654
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png
new file mode 100644
index 000000000..e90de0de4
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin
new file mode 100644
index 000000000..24316a1b4
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin
@@ -0,0 +1,16 @@
+[SkinFile]
+Up=TouchscreenPhone.png
+Down=TouchscreenPhone-pressed.png
+Screen=90 107 176 208
+Areas=9
+HasMouseHover=false
+
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
+"Select" 0x01010000 160 338 195 371
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf
new file mode 100644
index 000000000..a13dfdc3b
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf
@@ -0,0 +1,45 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Back
+Key2=Select
+Key3=Call
+Key4=Hangup
+[Button]
+Count=1
+[Button0]
+Name=Power Button
+Key=Hangup
+HeldActionService=Launcher
+HeldActionMessage=execute(QString)
+HeldActionArgs=@ByteArray(\0\0\0\x1\0\0\0\n\0\0\0\0\x10\0s\0h\0u\0t\0\x64\0o\0w\0n)
+[Device]
+PrimaryInput=Touchscreen
+
diff --git a/src/shared/findwidget/abstractfindwidget.cpp b/src/shared/findwidget/abstractfindwidget.cpp
new file mode 100644
index 000000000..b9f7a811e
--- /dev/null
+++ b/src/shared/findwidget/abstractfindwidget.cpp
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*! \class AbstractFindWidget
+
+ \brief A search bar that is commonly added below a searchable widget.
+
+ \internal
+
+ This widget implements a search bar which becomes visible when the user
+ wants to start searching. It is a modern replacement for the commonly used
+ search dialog. It is usually placed below the target widget using a QVBoxLayout.
+
+ The search is incremental and can be set to case sensitive or whole words
+ using buttons available on the search bar.
+ */
+
+#include "abstractfindwidget.h"
+
+#include <QtCore/QEvent>
+#include <QtCore/QFile>
+#include <QtCore/QTimer>
+
+#include <QtGui/QCheckBox>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+static QIcon createIconSet(const QString &name)
+{
+ QStringList candidates = QStringList()
+ << (QString::fromUtf8(":/trolltech/shared/images/") + name)
+#ifdef Q_WS_MAC
+ << (QString::fromUtf8(":/trolltech/shared/images/mac/") + name);
+#else
+ << (QString::fromUtf8(":/trolltech/shared/images/win/") + name);
+#endif
+
+ foreach (const QString &f, candidates) {
+ if (QFile::exists(f))
+ return QIcon(f);
+ }
+
+ return QIcon();
+}
+
+/*!
+ Constructs an AbstractFindWidget.
+
+ \a flags can change the layout and turn off certain features.
+ \a parent is passed to the QWidget constructor.
+ */
+AbstractFindWidget::AbstractFindWidget(FindFlags flags, QWidget *parent)
+ : QWidget(parent)
+{
+ QBoxLayout *topLayOut;
+ QBoxLayout *layOut;
+ if (flags & NarrowLayout) {
+ topLayOut = new QVBoxLayout(this);
+ layOut = new QHBoxLayout;
+ topLayOut->addLayout(layOut);
+ } else {
+ topLayOut = layOut = new QHBoxLayout(this);
+ }
+#ifndef Q_OS_MAC
+ topLayOut->setSpacing(6);
+ topLayOut->setMargin(0);
+#endif
+
+ m_toolClose = new QToolButton(this);
+ m_toolClose->setIcon(createIconSet(QLatin1String("closetab.png")));
+ m_toolClose->setAutoRaise(true);
+ layOut->addWidget(m_toolClose);
+ connect(m_toolClose, SIGNAL(clicked()), SLOT(deactivate()));
+
+ m_editFind = new QLineEdit(this);
+ layOut->addWidget(m_editFind);
+ connect(m_editFind, SIGNAL(returnPressed()), SLOT(findNext()));
+ connect(m_editFind, SIGNAL(textChanged(QString)), SLOT(findCurrentText()));
+ connect(m_editFind, SIGNAL(textChanged(QString)), SLOT(updateButtons()));
+
+ m_toolPrevious = new QToolButton(this);
+ m_toolPrevious->setAutoRaise(true);
+ m_toolPrevious->setText(tr("&Previous"));
+ m_toolPrevious->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ m_toolPrevious->setIcon(createIconSet(QLatin1String("previous.png")));
+ layOut->addWidget(m_toolPrevious);
+ connect(m_toolPrevious, SIGNAL(clicked()), SLOT(findPrevious()));
+
+ m_toolNext = new QToolButton(this);
+ m_toolNext->setAutoRaise(true);
+ m_toolNext->setText(tr("&Next"));
+ m_toolNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ m_toolNext->setIcon(createIconSet(QLatin1String("next.png")));
+ layOut->addWidget(m_toolNext);
+ connect(m_toolNext, SIGNAL(clicked()), SLOT(findNext()));
+
+ if (flags & NarrowLayout) {
+ QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ m_toolPrevious->setSizePolicy(sp);
+ m_toolPrevious->setMinimumWidth(m_toolPrevious->minimumSizeHint().height());
+ m_toolNext->setSizePolicy(sp);
+ m_toolNext->setMinimumWidth(m_toolNext->minimumSizeHint().height());
+
+ QSpacerItem *spacerItem =
+ new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ layOut->addItem(spacerItem);
+
+ layOut = new QHBoxLayout;
+ topLayOut->addLayout(layOut);
+ } else {
+ m_editFind->setMinimumWidth(150);
+ }
+
+ if (!(flags & NoCaseSensitive)) {
+ m_checkCase = new QCheckBox(tr("&Case sensitive"), this);
+ layOut->addWidget(m_checkCase);
+ connect(m_checkCase, SIGNAL(toggled(bool)), SLOT(findCurrentText()));
+ } else {
+ m_checkCase = 0;
+ }
+
+ if (!(flags & NoWholeWords)) {
+ m_checkWholeWords = new QCheckBox(tr("Whole &words"), this);
+ layOut->addWidget(m_checkWholeWords);
+ connect(m_checkWholeWords, SIGNAL(toggled(bool)), SLOT(findCurrentText()));
+ } else {
+ m_checkWholeWords = 0;
+ }
+
+ m_labelWrapped = new QLabel(this);
+ m_labelWrapped->setTextFormat(Qt::RichText);
+ m_labelWrapped->setAlignment(
+ Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
+ m_labelWrapped->setText(
+ tr("<img src=\":/trolltech/shared/images/wrap.png\">"
+ "&nbsp;Search wrapped"));
+ m_labelWrapped->hide();
+ layOut->addWidget(m_labelWrapped);
+
+ QSpacerItem *spacerItem =
+ new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ layOut->addItem(spacerItem);
+
+ setMinimumWidth(minimumSizeHint().width());
+
+ updateButtons();
+ hide();
+}
+
+/*!
+ Destroys the AbstractFindWidget.
+ */
+AbstractFindWidget::~AbstractFindWidget()
+{
+}
+
+/*!
+ Returns the icon set to be used for the action that initiates a search.
+ */
+QIcon AbstractFindWidget::findIconSet()
+{
+ return createIconSet(QLatin1String("searchfind.png"));
+}
+
+/*!
+ Activates the find widget, making it visible and having focus on its input
+ field.
+ */
+void AbstractFindWidget::activate()
+{
+ show();
+ m_editFind->selectAll();
+ m_editFind->setFocus(Qt::ShortcutFocusReason);
+}
+
+/*!
+ Deactivates the find widget, making it invisible and handing focus to any
+ associated QTextEdit.
+ */
+void AbstractFindWidget::deactivate()
+{
+ hide();
+}
+
+void AbstractFindWidget::findNext()
+{
+ findInternal(m_editFind->text(), true, false);
+}
+
+void AbstractFindWidget::findPrevious()
+{
+ findInternal(m_editFind->text(), true, true);
+}
+
+void AbstractFindWidget::findCurrentText()
+{
+ findInternal(m_editFind->text(), false, false);
+}
+
+void AbstractFindWidget::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Escape) {
+ deactivate();
+ return;
+ }
+
+ QWidget::keyPressEvent(event);
+}
+
+void AbstractFindWidget::updateButtons()
+{
+ const bool en = !m_editFind->text().isEmpty();
+ m_toolPrevious->setEnabled(en);
+ m_toolNext->setEnabled(en);
+}
+
+void AbstractFindWidget::findInternal(const QString &ttf, bool skipCurrent, bool backward)
+{
+ bool found = false;
+ bool wrapped = false;
+ find(ttf, skipCurrent, backward, &found, &wrapped);
+ QPalette p;
+ p.setColor(QPalette::Active, QPalette::Base, found ? Qt::white : QColor(255, 102, 102));
+ m_editFind->setPalette(p);
+ m_labelWrapped->setVisible(wrapped);
+}
+
+bool AbstractFindWidget::caseSensitive() const
+{
+ return m_checkCase && m_checkCase->isChecked();
+}
+
+bool AbstractFindWidget::wholeWords() const
+{
+ return m_checkWholeWords && m_checkWholeWords->isChecked();
+}
+
+bool AbstractFindWidget::eventFilter(QObject *object, QEvent *e)
+{
+ if (isVisible() && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ if (ke->key() == Qt::Key_Escape) {
+ hide();
+ return true;
+ }
+ }
+
+ return QWidget::eventFilter(object, e);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/findwidget/abstractfindwidget.h b/src/shared/findwidget/abstractfindwidget.h
new file mode 100644
index 000000000..6592911a8
--- /dev/null
+++ b/src/shared/findwidget/abstractfindwidget.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTFINDWIDGET_H
+#define ABSTRACTFINDWIDGET_H
+
+#include <QtGui/QIcon>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QCheckBox;
+class QEvent;
+class QKeyEvent;
+class QLabel;
+class QLineEdit;
+class QObject;
+class QToolButton;
+
+class AbstractFindWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum FindFlag {
+ /// Use a layout that is roughly half as wide and twice as high as the regular one.
+ NarrowLayout = 1,
+ /// Do not show the "Whole words" checkbox.
+ NoWholeWords = 2,
+ /// Do not show the "Case sensitive" checkbox.
+ NoCaseSensitive = 4
+ };
+ Q_DECLARE_FLAGS(FindFlags, FindFlag)
+
+ explicit AbstractFindWidget(FindFlags flags = FindFlags(), QWidget *parent = 0);
+ virtual ~AbstractFindWidget();
+
+ bool eventFilter(QObject *object, QEvent *e);
+
+ static QIcon findIconSet();
+
+public slots:
+ void activate();
+ virtual void deactivate();
+ void findNext();
+ void findPrevious();
+ void findCurrentText();
+
+protected:
+ void keyPressEvent(QKeyEvent *event);
+
+private slots:
+ void updateButtons();
+
+protected:
+ virtual void find(const QString &textToFind, bool skipCurrent, bool backward, bool *found, bool *wrapped) = 0;
+
+ bool caseSensitive() const;
+ bool wholeWords() const;
+
+private:
+ void findInternal(const QString &textToFind, bool skipCurrent, bool backward);
+
+ QLineEdit *m_editFind;
+ QLabel *m_labelWrapped;
+ QToolButton *m_toolNext;
+ QToolButton *m_toolClose;
+ QToolButton *m_toolPrevious;
+ QCheckBox *m_checkCase;
+ QCheckBox *m_checkWholeWords;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractFindWidget::FindFlags)
+
+QT_END_NAMESPACE
+
+#endif // ABSTRACTFINDWIDGET_H
diff --git a/src/shared/findwidget/findwidget.pri b/src/shared/findwidget/findwidget.pri
new file mode 100644
index 000000000..6e0f58aff
--- /dev/null
+++ b/src/shared/findwidget/findwidget.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/abstractfindwidget.h $$PWD/texteditfindwidget.h $$PWD/itemviewfindwidget.h
+SOURCES += $$PWD/abstractfindwidget.cpp $$PWD/texteditfindwidget.cpp $$PWD/itemviewfindwidget.cpp
+RESOURCES += $$PWD/findwidget.qrc
diff --git a/src/shared/findwidget/findwidget.qrc b/src/shared/findwidget/findwidget.qrc
new file mode 100644
index 000000000..1d45b25dd
--- /dev/null
+++ b/src/shared/findwidget/findwidget.qrc
@@ -0,0 +1,14 @@
+<RCC>
+ <qresource prefix="/trolltech/shared">
+ <file>images/mac/closetab.png</file>
+ <file>images/mac/next.png</file>
+ <file>images/mac/previous.png</file>
+ <file>images/mac/searchfind.png</file>
+ <file>images/win/closetab.png</file>
+ <file>images/win/next.png</file>
+ <file>images/win/previous.png</file>
+ <file>images/win/searchfind.png</file>
+ <file>images/wrap.png</file>
+ </qresource>
+</RCC>
+
diff --git a/src/shared/findwidget/images/mac/closetab.png b/src/shared/findwidget/images/mac/closetab.png
new file mode 100644
index 000000000..ab9d669ee
--- /dev/null
+++ b/src/shared/findwidget/images/mac/closetab.png
Binary files differ
diff --git a/src/shared/findwidget/images/mac/next.png b/src/shared/findwidget/images/mac/next.png
new file mode 100644
index 000000000..a585cab80
--- /dev/null
+++ b/src/shared/findwidget/images/mac/next.png
Binary files differ
diff --git a/src/shared/findwidget/images/mac/previous.png b/src/shared/findwidget/images/mac/previous.png
new file mode 100644
index 000000000..612fb34dc
--- /dev/null
+++ b/src/shared/findwidget/images/mac/previous.png
Binary files differ
diff --git a/src/shared/findwidget/images/mac/searchfind.png b/src/shared/findwidget/images/mac/searchfind.png
new file mode 100644
index 000000000..3561745f0
--- /dev/null
+++ b/src/shared/findwidget/images/mac/searchfind.png
Binary files differ
diff --git a/src/shared/findwidget/images/win/closetab.png b/src/shared/findwidget/images/win/closetab.png
new file mode 100644
index 000000000..ef9e02086
--- /dev/null
+++ b/src/shared/findwidget/images/win/closetab.png
Binary files differ
diff --git a/src/shared/findwidget/images/win/next.png b/src/shared/findwidget/images/win/next.png
new file mode 100644
index 000000000..8df4127a0
--- /dev/null
+++ b/src/shared/findwidget/images/win/next.png
Binary files differ
diff --git a/src/shared/findwidget/images/win/previous.png b/src/shared/findwidget/images/win/previous.png
new file mode 100644
index 000000000..0780bc23d
--- /dev/null
+++ b/src/shared/findwidget/images/win/previous.png
Binary files differ
diff --git a/src/shared/findwidget/images/win/searchfind.png b/src/shared/findwidget/images/win/searchfind.png
new file mode 100644
index 000000000..6ea35e930
--- /dev/null
+++ b/src/shared/findwidget/images/win/searchfind.png
Binary files differ
diff --git a/src/shared/findwidget/images/wrap.png b/src/shared/findwidget/images/wrap.png
new file mode 100644
index 000000000..90f18d9f7
--- /dev/null
+++ b/src/shared/findwidget/images/wrap.png
Binary files differ
diff --git a/src/shared/findwidget/itemviewfindwidget.cpp b/src/shared/findwidget/itemviewfindwidget.cpp
new file mode 100644
index 000000000..9249ed5f7
--- /dev/null
+++ b/src/shared/findwidget/itemviewfindwidget.cpp
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*! \class ItemViewFindWidget
+
+ \brief A search bar that is commonly added below the searchable item view.
+
+ \internal
+
+ This widget implements a search bar which becomes visible when the user
+ wants to start searching. It is a modern replacement for the commonly used
+ search dialog. It is usually placed below a QAbstractItemView using a QVBoxLayout.
+
+ The QAbstractItemView instance will need to be associated with this class using
+ setItemView().
+
+ The search is incremental and can be set to case sensitive or whole words
+ using buttons available on the search bar.
+
+ The item traversal order should fit QTreeView, QTableView and QListView alike.
+ More complex tree structures will work as well, assuming the branch structure
+ is painted left to the items, without crossing lines.
+
+ \sa QAbstractItemView
+ */
+
+#include "itemviewfindwidget.h"
+
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QCheckBox>
+#include <QtGui/QTreeView>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Constructs a ItemViewFindWidget.
+
+ \a flags is passed to the AbstractFindWidget constructor.
+ \a parent is passed to the QWidget constructor.
+ */
+ItemViewFindWidget::ItemViewFindWidget(FindFlags flags, QWidget *parent)
+ : AbstractFindWidget(flags, parent)
+ , m_itemView(0)
+{
+}
+
+/*!
+ Associates a QAbstractItemView with this find widget. Searches done using this find
+ widget will then apply to the given QAbstractItemView.
+
+ An event filter is set on the QAbstractItemView which intercepts the ESC key while
+ the find widget is active, and uses it to deactivate the find widget.
+
+ If the find widget is already associated with a QAbstractItemView, the event filter
+ is removed from this QAbstractItemView first.
+
+ \a itemView may be NULL.
+ */
+void ItemViewFindWidget::setItemView(QAbstractItemView *itemView)
+{
+ if (m_itemView)
+ m_itemView->removeEventFilter(this);
+
+ m_itemView = itemView;
+
+ if (m_itemView)
+ m_itemView->installEventFilter(this);
+}
+
+/*!
+ \reimp
+ */
+void ItemViewFindWidget::deactivate()
+{
+ if (m_itemView)
+ m_itemView->setFocus();
+
+ AbstractFindWidget::deactivate();
+}
+
+// Sorting is needed to find the start/end of the selection.
+// This is utter black magic. And it is damn slow.
+static bool indexLessThan(const QModelIndex &a, const QModelIndex &b)
+{
+ // First determine the nesting of each index in the tree.
+ QModelIndex aa = a;
+ int aDepth = 0;
+ while (aa.parent() != QModelIndex()) {
+ // As a side effect, check if one of the items is the parent of the other.
+ // Children are always displayed below their parents, so sort them further down.
+ if (aa.parent() == b)
+ return true;
+ aa = aa.parent();
+ aDepth++;
+ }
+ QModelIndex ba = b;
+ int bDepth = 0;
+ while (ba.parent() != QModelIndex()) {
+ if (ba.parent() == a)
+ return false;
+ ba = ba.parent();
+ bDepth++;
+ }
+ // Now find indices at comparable depth.
+ for (aa = a; aDepth > bDepth; aDepth--)
+ aa = aa.parent();
+ for (ba = b; aDepth < bDepth; bDepth--)
+ ba = ba.parent();
+ // If they have the same parent, sort them within a top-to-bottom, left-to-right rectangle.
+ if (aa.parent() == ba.parent()) {
+ if (aa.row() < ba.row())
+ return true;
+ if (aa.row() > ba.row())
+ return false;
+ return aa.column() < ba.column();
+ }
+ // Now try to find indices that have the same grandparent. This ends latest at the root node.
+ while (aa.parent().parent() != ba.parent().parent()) {
+ aa = aa.parent();
+ ba = ba.parent();
+ }
+ // A bigger row is always displayed further down.
+ if (aa.parent().row() < ba.parent().row())
+ return true;
+ if (aa.parent().row() > ba.parent().row())
+ return false;
+ // Here's the trick: a child spawned from a bigger column is displayed further *up*.
+ // That's because the tree lines are on the left and are supposed not to cross each other.
+ // This case is mostly academical, as "all" models spawn children from the first column.
+ return aa.parent().column() > ba.parent().column();
+}
+
+/*!
+ \reimp
+ */
+void ItemViewFindWidget::find(const QString &ttf, bool skipCurrent, bool backward, bool *found, bool *wrapped)
+{
+ if (!m_itemView || !m_itemView->model()->hasChildren())
+ return;
+
+ QModelIndex idx;
+ if (skipCurrent && m_itemView->selectionModel()->hasSelection()) {
+ QModelIndexList il = m_itemView->selectionModel()->selectedIndexes();
+ qSort(il.begin(), il.end(), indexLessThan);
+ idx = backward ? il.first() : il.last();
+ } else {
+ idx = m_itemView->currentIndex();
+ }
+
+ *found = true;
+ QModelIndex newIdx = idx;
+
+ if (!ttf.isEmpty()) {
+ if (newIdx.isValid()) {
+ int column = newIdx.column();
+ if (skipCurrent)
+ if (QTreeView *tv = qobject_cast<QTreeView *>(m_itemView))
+ if (tv->allColumnsShowFocus())
+ column = backward ? 0 : m_itemView->model()->columnCount(newIdx.parent()) - 1;
+ newIdx = findHelper(ttf, skipCurrent, backward,
+ newIdx.parent(), newIdx.row(), column);
+ }
+ if (!newIdx.isValid()) {
+ int row = backward ? m_itemView->model()->rowCount() : 0;
+ int column = backward ? 0 : -1;
+ newIdx = findHelper(ttf, true, backward, m_itemView->rootIndex(), row, column);
+ if (!newIdx.isValid()) {
+ *found = false;
+ newIdx = idx;
+ } else {
+ *wrapped = true;
+ }
+ }
+ }
+
+ if (!isVisible())
+ show();
+
+ m_itemView->setCurrentIndex(newIdx);
+}
+
+// You are not expected to understand the following two functions.
+// The traversal order is described in the indexLessThan() comments above.
+
+static inline bool skipForward(const QAbstractItemModel *model, QModelIndex &parent, int &row, int &column)
+{
+ forever {
+ column++;
+ if (column < model->columnCount(parent))
+ return true;
+ forever {
+ while (--column >= 0) {
+ QModelIndex nIdx = model->index(row, column, parent);
+ if (nIdx.isValid()) {
+ if (model->hasChildren(nIdx)) {
+ row = 0;
+ column = 0;
+ parent = nIdx;
+ return true;
+ }
+ }
+ }
+ if (++row < model->rowCount(parent))
+ break;
+ if (!parent.isValid())
+ return false;
+ row = parent.row();
+ column = parent.column();
+ parent = parent.parent();
+ }
+ }
+}
+
+static inline bool skipBackward(const QAbstractItemModel *model, QModelIndex &parent, int &row, int &column)
+{
+ column--;
+ if (column == -1) {
+ if (--row < 0) {
+ if (!parent.isValid())
+ return false;
+ row = parent.row();
+ column = parent.column();
+ parent = parent.parent();
+ }
+ while (++column < model->columnCount(parent)) {
+ QModelIndex nIdx = model->index(row, column, parent);
+ if (nIdx.isValid()) {
+ if (model->hasChildren(nIdx)) {
+ row = model->rowCount(nIdx) - 1;
+ column = -1;
+ parent = nIdx;
+ }
+ }
+ }
+ column--;
+ }
+ return true;
+}
+
+// QAbstractItemModel::match() does not support backwards searching. Still using it would
+// be just a bit inefficient (not much worse than when no match is found).
+// The bigger problem is that QAbstractItemView does not provide a method to sort a
+// set of indices in traversal order (to find the start and end of the selection).
+// Consequently, we do everything by ourselves to be consistent. Of course, this puts
+// constraints on the allowable visualizations.
+QModelIndex ItemViewFindWidget::findHelper(const QString &textToFind, bool skipCurrent, bool backward,
+ QModelIndex parent, int row, int column)
+{
+ const QAbstractItemModel *model = m_itemView->model();
+ forever {
+ if (skipCurrent) {
+ if (backward) {
+ if (!skipBackward(model, parent, row, column))
+ return QModelIndex();
+ } else {
+ if (!skipForward(model, parent, row, column))
+ return QModelIndex();
+ }
+ }
+
+ QModelIndex idx = model->index(row, column, parent);
+ if (idx.isValid()) {
+ Qt::CaseSensitivity cs = caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
+
+ if (wholeWords()) {
+ QString rx = QLatin1String("\\b") + QRegExp::escape(textToFind) + QLatin1String("\\b");
+ if (idx.data().toString().indexOf(QRegExp(rx, cs)) >= 0)
+ return idx;
+ } else {
+ if (idx.data().toString().indexOf(textToFind, 0, cs) >= 0)
+ return idx;
+ }
+ }
+
+ skipCurrent = true;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/findwidget/itemviewfindwidget.h b/src/shared/findwidget/itemviewfindwidget.h
new file mode 100644
index 000000000..c42804a5f
--- /dev/null
+++ b/src/shared/findwidget/itemviewfindwidget.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ITEMVIEWFINDWIDGET_H
+#define ITEMVIEWFINDWIDGET_H
+
+#include "abstractfindwidget.h"
+
+#include <QModelIndex>
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractItemView;
+
+class ItemViewFindWidget : public AbstractFindWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ItemViewFindWidget(FindFlags flags = FindFlags(), QWidget *parent = 0);
+
+ QAbstractItemView *itemView() const
+ { return m_itemView; }
+
+ void setItemView(QAbstractItemView *itemView);
+
+protected:
+ virtual void deactivate();
+ virtual void find(const QString &textToFind, bool skipCurrent, bool backward, bool *found, bool *wrapped);
+
+private:
+ QModelIndex findHelper(const QString &textToFind, bool skipCurrent, bool backward,
+ QModelIndex parent, int row, int column);
+
+ QAbstractItemView *m_itemView;
+};
+
+QT_END_NAMESPACE
+
+#endif // ITEMVIEWFINDWIDGET_H
diff --git a/src/shared/findwidget/texteditfindwidget.cpp b/src/shared/findwidget/texteditfindwidget.cpp
new file mode 100644
index 000000000..f02bdcc33
--- /dev/null
+++ b/src/shared/findwidget/texteditfindwidget.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*! \class TextEditFindWidget
+
+ \brief A search bar that is commonly added below the searchable text.
+
+ \internal
+
+ This widget implements a search bar which becomes visible when the user
+ wants to start searching. It is a modern replacement for the commonly used
+ search dialog. It is usually placed below a QTextEdit using a QVBoxLayout.
+
+ The QTextEdit instance will need to be associated with this class using
+ setTextEdit().
+
+ The search is incremental and can be set to case sensitive or whole words
+ using buttons available on the search bar.
+
+ \sa QTextEdit
+ */
+
+#include "texteditfindwidget.h"
+
+#include <QtGui/QCheckBox>
+#include <QtGui/QTextCursor>
+#include <QtGui/QTextEdit>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Constructs a TextEditFindWidget.
+
+ \a flags is passed to the AbstractFindWidget constructor.
+ \a parent is passed to the QWidget constructor.
+ */
+TextEditFindWidget::TextEditFindWidget(FindFlags flags, QWidget *parent)
+ : AbstractFindWidget(flags, parent)
+ , m_textEdit(0)
+{
+}
+
+/*!
+ Associates a QTextEdit with this find widget. Searches done using this find
+ widget will then apply to the given QTextEdit.
+
+ An event filter is set on the QTextEdit which intercepts the ESC key while
+ the find widget is active, and uses it to deactivate the find widget.
+
+ If the find widget is already associated with a QTextEdit, the event filter
+ is removed from this QTextEdit first.
+
+ \a textEdit may be NULL.
+ */
+void TextEditFindWidget::setTextEdit(QTextEdit *textEdit)
+{
+ if (m_textEdit)
+ m_textEdit->removeEventFilter(this);
+
+ m_textEdit = textEdit;
+
+ if (m_textEdit)
+ m_textEdit->installEventFilter(this);
+}
+
+/*!
+ \reimp
+ */
+void TextEditFindWidget::deactivate()
+{
+ // Pass focus to the text edit
+ if (m_textEdit)
+ m_textEdit->setFocus();
+
+ AbstractFindWidget::deactivate();
+}
+
+/*!
+ \reimp
+ */
+void TextEditFindWidget::find(const QString &ttf, bool skipCurrent, bool backward, bool *found, bool *wrapped)
+{
+ if (!m_textEdit)
+ return;
+
+ QTextCursor cursor = m_textEdit->textCursor();
+ QTextDocument *doc = m_textEdit->document();
+
+ if (!doc || cursor.isNull())
+ return;
+
+ if (cursor.hasSelection())
+ cursor.setPosition((skipCurrent && !backward) ? cursor.position() : cursor.anchor());
+
+ *found = true;
+ QTextCursor newCursor = cursor;
+
+ if (!ttf.isEmpty()) {
+ QTextDocument::FindFlags options;
+
+ if (backward)
+ options |= QTextDocument::FindBackward;
+
+ if (caseSensitive())
+ options |= QTextDocument::FindCaseSensitively;
+
+ if (wholeWords())
+ options |= QTextDocument::FindWholeWords;
+
+ newCursor = doc->find(ttf, cursor, options);
+ if (newCursor.isNull()) {
+ QTextCursor ac(doc);
+ ac.movePosition(options & QTextDocument::FindBackward
+ ? QTextCursor::End : QTextCursor::Start);
+ newCursor = doc->find(ttf, ac, options);
+ if (newCursor.isNull()) {
+ *found = false;
+ newCursor = cursor;
+ } else {
+ *wrapped = true;
+ }
+ }
+ }
+
+ if (!isVisible())
+ show();
+
+ m_textEdit->setTextCursor(newCursor);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/findwidget/texteditfindwidget.h b/src/shared/findwidget/texteditfindwidget.h
new file mode 100644
index 000000000..5429acfb8
--- /dev/null
+++ b/src/shared/findwidget/texteditfindwidget.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTEDITFINDWIDGET_H
+#define TEXTEDITFINDWIDGET_H
+
+#include "abstractfindwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+
+class TextEditFindWidget : public AbstractFindWidget
+{
+ Q_OBJECT
+
+public:
+ explicit TextEditFindWidget(FindFlags flags = FindFlags(), QWidget *parent = 0);
+
+ QTextEdit *textEdit() const
+ { return m_textEdit; }
+
+ void setTextEdit(QTextEdit *textEdit);
+
+protected:
+ virtual void deactivate();
+ virtual void find(const QString &textToFind, bool skipCurrent, bool backward, bool *found, bool *wrapped);
+
+private:
+ QTextEdit *m_textEdit;
+};
+
+QT_END_NAMESPACE
+
+#endif // TEXTEDITFINDWIDGET_H
diff --git a/src/shared/fontpanel/fontpanel.cpp b/src/shared/fontpanel/fontpanel.cpp
new file mode 100644
index 000000000..9bcef2a4b
--- /dev/null
+++ b/src/shared/fontpanel/fontpanel.cpp
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fontpanel.h"
+
+#include <QtGui/QLabel>
+#include <QtGui/QComboBox>
+#include <QtGui/QFormLayout>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QFontComboBox>
+#include <QtCore/QTimer>
+#include <QtGui/QLineEdit>
+
+QT_BEGIN_NAMESPACE
+
+FontPanel::FontPanel(QWidget *parentWidget) :
+ QGroupBox(parentWidget),
+ m_previewLineEdit(new QLineEdit),
+ m_writingSystemComboBox(new QComboBox),
+ m_familyComboBox(new QFontComboBox),
+ m_styleComboBox(new QComboBox),
+ m_pointSizeComboBox(new QComboBox),
+ m_previewFontUpdateTimer(0)
+{
+ setTitle(tr("Font"));
+
+ QFormLayout *formLayout = new QFormLayout(this);
+ // writing systems
+ m_writingSystemComboBox->setEditable(false);
+
+ QList<QFontDatabase::WritingSystem> writingSystems = m_fontDatabase.writingSystems();
+ writingSystems.push_front(QFontDatabase::Any);
+ foreach (QFontDatabase::WritingSystem ws, writingSystems)
+ m_writingSystemComboBox->addItem(QFontDatabase::writingSystemName(ws), QVariant(ws));
+ connect(m_writingSystemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotWritingSystemChanged(int)));
+ formLayout->addRow(tr("&Writing system"), m_writingSystemComboBox);
+
+ connect(m_familyComboBox, SIGNAL(currentFontChanged(QFont)), this, SLOT(slotFamilyChanged(QFont)));
+ formLayout->addRow(tr("&Family"), m_familyComboBox);
+
+ m_styleComboBox->setEditable(false);
+ connect(m_styleComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotStyleChanged(int)));
+ formLayout->addRow(tr("&Style"), m_styleComboBox);
+
+ m_pointSizeComboBox->setEditable(false);
+ connect(m_pointSizeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotPointSizeChanged(int)));
+ formLayout->addRow(tr("&Point size"), m_pointSizeComboBox);
+
+ m_previewLineEdit->setReadOnly(true);
+ formLayout->addRow(m_previewLineEdit);
+
+ setWritingSystem(QFontDatabase::Any);
+}
+
+QFont FontPanel::selectedFont() const
+{
+ QFont rc = m_familyComboBox->currentFont();
+ const QString family = rc.family();
+ rc.setPointSize(pointSize());
+ const QString styleDescription = styleString();
+ if (styleDescription.contains(QLatin1String("Italic")))
+ rc.setStyle(QFont::StyleItalic);
+ else if (styleDescription.contains(QLatin1String("Oblique")))
+ rc.setStyle(QFont::StyleOblique);
+ else
+ rc.setStyle(QFont::StyleNormal);
+ rc.setBold(m_fontDatabase.bold(family, styleDescription));
+
+ // Weight < 0 asserts...
+ const int weight = m_fontDatabase.weight(family, styleDescription);
+ if (weight >= 0)
+ rc.setWeight(weight);
+ return rc;
+}
+
+void FontPanel::setSelectedFont(const QFont &f)
+{
+ m_familyComboBox->setCurrentFont(f);
+ if (m_familyComboBox->currentIndex() < 0) {
+ // family not in writing system - find the corresponding one?
+ QList<QFontDatabase::WritingSystem> familyWritingSystems = m_fontDatabase.writingSystems(f.family());
+ if (familyWritingSystems.empty())
+ return;
+
+ setWritingSystem(familyWritingSystems.front());
+ m_familyComboBox->setCurrentFont(f);
+ }
+
+ updateFamily(family());
+
+ const int pointSizeIndex = closestPointSizeIndex(f.pointSize());
+ m_pointSizeComboBox->setCurrentIndex( pointSizeIndex);
+
+ const QString styleString = m_fontDatabase.styleString(f);
+ const int styleIndex = m_styleComboBox->findText(styleString);
+ m_styleComboBox->setCurrentIndex(styleIndex);
+ slotUpdatePreviewFont();
+}
+
+
+QFontDatabase::WritingSystem FontPanel::writingSystem() const
+{
+ const int currentIndex = m_writingSystemComboBox->currentIndex();
+ if ( currentIndex == -1)
+ return QFontDatabase::Latin;
+ return static_cast<QFontDatabase::WritingSystem>(m_writingSystemComboBox->itemData(currentIndex).toInt());
+}
+
+QString FontPanel::family() const
+{
+ const int currentIndex = m_familyComboBox->currentIndex();
+ return currentIndex != -1 ? m_familyComboBox->currentFont().family() : QString();
+}
+
+int FontPanel::pointSize() const
+{
+ const int currentIndex = m_pointSizeComboBox->currentIndex();
+ return currentIndex != -1 ? m_pointSizeComboBox->itemData(currentIndex).toInt() : 9;
+}
+
+QString FontPanel::styleString() const
+{
+ const int currentIndex = m_styleComboBox->currentIndex();
+ return currentIndex != -1 ? m_styleComboBox->itemText(currentIndex) : QString();
+}
+
+void FontPanel::setWritingSystem(QFontDatabase::WritingSystem ws)
+{
+ m_writingSystemComboBox->setCurrentIndex(m_writingSystemComboBox->findData(QVariant(ws)));
+ updateWritingSystem(ws);
+}
+
+
+void FontPanel::slotWritingSystemChanged(int)
+{
+ updateWritingSystem(writingSystem());
+ delayedPreviewFontUpdate();
+}
+
+void FontPanel::slotFamilyChanged(const QFont &)
+{
+ updateFamily(family());
+ delayedPreviewFontUpdate();
+}
+
+void FontPanel::slotStyleChanged(int)
+{
+ updatePointSizes(family(), styleString());
+ delayedPreviewFontUpdate();
+}
+
+void FontPanel::slotPointSizeChanged(int)
+{
+ delayedPreviewFontUpdate();
+}
+
+void FontPanel::updateWritingSystem(QFontDatabase::WritingSystem ws)
+{
+
+ m_previewLineEdit->setText(QFontDatabase::writingSystemSample(ws));
+ m_familyComboBox->setWritingSystem (ws);
+ // Current font not in WS ... set index 0.
+ if (m_familyComboBox->currentIndex() < 0) {
+ m_familyComboBox->setCurrentIndex(0);
+ updateFamily(family());
+ }
+}
+
+void FontPanel::updateFamily(const QString &family)
+{
+ // Update styles and trigger update of point sizes.
+ // Try to maintain selection or select normal
+ const QString oldStyleString = styleString();
+
+ const QStringList styles = m_fontDatabase.styles(family);
+ const bool hasStyles = !styles.empty();
+
+ m_styleComboBox->setCurrentIndex(-1);
+ m_styleComboBox->clear();
+ m_styleComboBox->setEnabled(hasStyles);
+
+ int normalIndex = -1;
+ const QString normalStyle = QLatin1String("Normal");
+
+ if (hasStyles) {
+ foreach (const QString &style, styles) {
+ // try to maintain selection or select 'normal' preferably
+ const int newIndex = m_styleComboBox->count();
+ m_styleComboBox->addItem(style);
+ if (oldStyleString == style) {
+ m_styleComboBox->setCurrentIndex(newIndex);
+ } else {
+ if (oldStyleString == normalStyle)
+ normalIndex = newIndex;
+ }
+ }
+ if (m_styleComboBox->currentIndex() == -1 && normalIndex != -1)
+ m_styleComboBox->setCurrentIndex(normalIndex);
+ }
+ updatePointSizes(family, styleString());
+}
+
+int FontPanel::closestPointSizeIndex(int desiredPointSize) const
+{
+ // try to maintain selection or select closest.
+ int closestIndex = -1;
+ int closestAbsError = 0xFFFF;
+
+ const int pointSizeCount = m_pointSizeComboBox->count();
+ for (int i = 0; i < pointSizeCount; i++) {
+ const int itemPointSize = m_pointSizeComboBox->itemData(i).toInt();
+ const int absError = qAbs(desiredPointSize - itemPointSize);
+ if (absError < closestAbsError) {
+ closestIndex = i;
+ closestAbsError = absError;
+ if (closestAbsError == 0)
+ break;
+ } else { // past optimum
+ if (absError > closestAbsError) {
+ break;
+ }
+ }
+ }
+ return closestIndex;
+}
+
+
+void FontPanel::updatePointSizes(const QString &family, const QString &styleString)
+{
+ const int oldPointSize = pointSize();
+
+ QList<int> pointSizes = m_fontDatabase.pointSizes(family, styleString);
+ if (pointSizes.empty())
+ pointSizes = QFontDatabase::standardSizes();
+
+ const bool hasSizes = !pointSizes.empty();
+ m_pointSizeComboBox->clear();
+ m_pointSizeComboBox->setEnabled(hasSizes);
+ m_pointSizeComboBox->setCurrentIndex(-1);
+
+ // try to maintain selection or select closest.
+ if (hasSizes) {
+ QString n;
+ foreach (int pointSize, pointSizes)
+ m_pointSizeComboBox->addItem(n.setNum(pointSize), QVariant(pointSize));
+ const int closestIndex = closestPointSizeIndex(oldPointSize);
+ if (closestIndex != -1)
+ m_pointSizeComboBox->setCurrentIndex(closestIndex);
+ }
+}
+
+void FontPanel::slotUpdatePreviewFont()
+{
+ m_previewLineEdit->setFont(selectedFont());
+}
+
+void FontPanel::delayedPreviewFontUpdate()
+{
+ if (!m_previewFontUpdateTimer) {
+ m_previewFontUpdateTimer = new QTimer(this);
+ connect(m_previewFontUpdateTimer, SIGNAL(timeout()), this, SLOT(slotUpdatePreviewFont()));
+ m_previewFontUpdateTimer->setInterval(0);
+ m_previewFontUpdateTimer->setSingleShot(true);
+ }
+ if (m_previewFontUpdateTimer->isActive())
+ return;
+ m_previewFontUpdateTimer->start();
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/fontpanel/fontpanel.h b/src/shared/fontpanel/fontpanel.h
new file mode 100644
index 000000000..204ff7d4a
--- /dev/null
+++ b/src/shared/fontpanel/fontpanel.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Qt tools. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef FONTPANEL_H
+#define FONTPANEL_H
+
+#include <QtGui/QGroupBox>
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+
+QT_BEGIN_NAMESPACE
+
+class QComboBox;
+class QFontComboBox;
+class QTimer;
+class QLineEdit;
+
+class FontPanel: public QGroupBox
+{
+ Q_OBJECT
+public:
+ FontPanel(QWidget *parentWidget = 0);
+
+ QFont selectedFont() const;
+ void setSelectedFont(const QFont &);
+
+ QFontDatabase::WritingSystem writingSystem() const;
+ void setWritingSystem(QFontDatabase::WritingSystem ws);
+
+private slots:
+ void slotWritingSystemChanged(int);
+ void slotFamilyChanged(const QFont &);
+ void slotStyleChanged(int);
+ void slotPointSizeChanged(int);
+ void slotUpdatePreviewFont();
+
+private:
+ QString family() const;
+ QString styleString() const;
+ int pointSize() const;
+ int closestPointSizeIndex(int ps) const;
+
+ void updateWritingSystem(QFontDatabase::WritingSystem ws);
+ void updateFamily(const QString &family);
+ void updatePointSizes(const QString &family, const QString &style);
+ void delayedPreviewFontUpdate();
+
+ QFontDatabase m_fontDatabase;
+ QLineEdit *m_previewLineEdit;
+ QComboBox *m_writingSystemComboBox;
+ QFontComboBox* m_familyComboBox;
+ QComboBox *m_styleComboBox;
+ QComboBox *m_pointSizeComboBox;
+ QTimer *m_previewFontUpdateTimer;
+};
+
+QT_END_NAMESPACE
+
+#endif // FONTPANEL_H
diff --git a/src/shared/fontpanel/fontpanel.pri b/src/shared/fontpanel/fontpanel.pri
new file mode 100644
index 000000000..9504853a7
--- /dev/null
+++ b/src/shared/fontpanel/fontpanel.pri
@@ -0,0 +1,3 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/fontpanel.h
+SOURCES += $$PWD/fontpanel.cpp
diff --git a/src/shared/qtgradienteditor/images/down.png b/src/shared/qtgradienteditor/images/down.png
new file mode 100644
index 000000000..29d1d4439
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/down.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/edit.png b/src/shared/qtgradienteditor/images/edit.png
new file mode 100644
index 000000000..4231bd9a9
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/edit.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/editdelete.png b/src/shared/qtgradienteditor/images/editdelete.png
new file mode 100644
index 000000000..df2a147d2
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/editdelete.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/minus.png b/src/shared/qtgradienteditor/images/minus.png
new file mode 100644
index 000000000..d6f233d73
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/minus.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/plus.png b/src/shared/qtgradienteditor/images/plus.png
new file mode 100644
index 000000000..40df1134f
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/plus.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadpad.png b/src/shared/qtgradienteditor/images/spreadpad.png
new file mode 100644
index 000000000..104c0a23d
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadpad.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadreflect.png b/src/shared/qtgradienteditor/images/spreadreflect.png
new file mode 100644
index 000000000..17b82b711
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadreflect.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadrepeat.png b/src/shared/qtgradienteditor/images/spreadrepeat.png
new file mode 100644
index 000000000..7aea898b1
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadrepeat.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typeconical.png b/src/shared/qtgradienteditor/images/typeconical.png
new file mode 100644
index 000000000..5479811df
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typeconical.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typelinear.png b/src/shared/qtgradienteditor/images/typelinear.png
new file mode 100644
index 000000000..dbd8a1f5a
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typelinear.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typeradial.png b/src/shared/qtgradienteditor/images/typeradial.png
new file mode 100644
index 000000000..dc5888dca
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typeradial.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/up.png b/src/shared/qtgradienteditor/images/up.png
new file mode 100644
index 000000000..e43731221
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/up.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/zoomin.png b/src/shared/qtgradienteditor/images/zoomin.png
new file mode 100644
index 000000000..2e586fc7b
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/zoomin.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/zoomout.png b/src/shared/qtgradienteditor/images/zoomout.png
new file mode 100644
index 000000000..a736d3934
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/zoomout.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.cpp b/src/shared/qtgradienteditor/qtcolorbutton.cpp
new file mode 100644
index 000000000..96a8b26ca
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtcolorbutton.h"
+#include <QtGui/QColorDialog>
+#include <QtGui/QPainter>
+#include <QtCore/QMimeData>
+#include <QtGui/QDragEnterEvent>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorButtonPrivate
+{
+ QtColorButton *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorButton)
+public:
+ QColor m_color;
+#ifndef QT_NO_DRAGANDDROP
+ QColor m_dragColor;
+ QPoint m_dragStart;
+ bool m_dragging;
+#endif
+ bool m_backgroundCheckered;
+
+ void slotEditColor();
+ QColor shownColor() const;
+ QPixmap generatePixmap() const;
+};
+
+void QtColorButtonPrivate::slotEditColor()
+{
+ const QColor newColor = QColorDialog::getColor(m_color, q_ptr, QString(), QColorDialog::ShowAlphaChannel);
+ if (!newColor.isValid() || newColor == q_ptr->color())
+ return;
+ q_ptr->setColor(newColor);
+ emit q_ptr->colorChanged(m_color);
+}
+
+QColor QtColorButtonPrivate::shownColor() const
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (m_dragging)
+ return m_dragColor;
+#endif
+ return m_color;
+}
+
+QPixmap QtColorButtonPrivate::generatePixmap() const
+{
+ QPixmap pix(24, 24);
+
+ int pixSize = 20;
+ QBrush br(shownColor());
+
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, shownColor());
+ br = QBrush(pm);
+
+ QPainter p(&pix);
+ int corr = 1;
+ QRect r = pix.rect().adjusted(corr, corr, -corr, -corr);
+ p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
+ p.fillRect(r, br);
+
+ p.fillRect(r.width() / 4 + corr, r.height() / 4 + corr,
+ r.width() / 2, r.height() / 2,
+ QColor(shownColor().rgb()));
+ p.drawRect(pix.rect().adjusted(0, 0, -1, -1));
+
+ return pix;
+}
+
+///////////////
+
+QtColorButton::QtColorButton(QWidget *parent)
+ : QToolButton(parent), d_ptr(new QtColorButtonPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_dragging = false;
+ d_ptr->m_backgroundCheckered = true;
+
+ setAcceptDrops(true);
+
+ connect(this, SIGNAL(clicked()), this, SLOT(slotEditColor()));
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
+}
+
+QtColorButton::~QtColorButton()
+{
+}
+
+void QtColorButton::setColor(const QColor &color)
+{
+ if (d_ptr->m_color == color)
+ return;
+ d_ptr->m_color = color;
+ update();
+}
+
+QColor QtColorButton::color() const
+{
+ return d_ptr->m_color;
+}
+
+void QtColorButton::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtColorButton::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtColorButton::paintEvent(QPaintEvent *event)
+{
+ QToolButton::paintEvent(event);
+ if (!isEnabled())
+ return;
+
+ const int pixSize = 10;
+ QBrush br(d_ptr->shownColor());
+ if (d_ptr->m_backgroundCheckered) {
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+ pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, d_ptr->shownColor());
+ br = QBrush(pm);
+ }
+
+ QPainter p(this);
+ const int corr = 4;
+ QRect r = rect().adjusted(corr, corr, -corr, -corr);
+ p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
+ p.fillRect(r, br);
+
+ //const int adjX = qRound(r.width() / 4.0);
+ //const int adjY = qRound(r.height() / 4.0);
+ //p.fillRect(r.adjusted(adjX, adjY, -adjX, -adjY),
+ // QColor(d_ptr->shownColor().rgb()));
+ /*
+ p.fillRect(r.adjusted(0, r.height() * 3 / 4, 0, 0),
+ QColor(d_ptr->shownColor().rgb()));
+ p.fillRect(r.adjusted(0, 0, 0, -r.height() * 3 / 4),
+ QColor(d_ptr->shownColor().rgb()));
+ */
+ /*
+ const QColor frameColor0(0, 0, 0, qRound(0.2 * (0xFF - d_ptr->shownColor().alpha())));
+ p.setPen(frameColor0);
+ p.drawRect(r.adjusted(adjX, adjY, -adjX - 1, -adjY - 1));
+ */
+
+ const QColor frameColor1(0, 0, 0, 26);
+ p.setPen(frameColor1);
+ p.drawRect(r.adjusted(1, 1, -2, -2));
+ const QColor frameColor2(0, 0, 0, 51);
+ p.setPen(frameColor2);
+ p.drawRect(r.adjusted(0, 0, -1, -1));
+}
+
+void QtColorButton::mousePressEvent(QMouseEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (event->button() == Qt::LeftButton)
+ d_ptr->m_dragStart = event->pos();
+#endif
+ QToolButton::mousePressEvent(event);
+}
+
+void QtColorButton::mouseMoveEvent(QMouseEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (event->buttons() & Qt::LeftButton &&
+ (d_ptr->m_dragStart - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
+ QMimeData *mime = new QMimeData;
+ mime->setColorData(color());
+ QDrag *drg = new QDrag(this);
+ drg->setMimeData(mime);
+ drg->setPixmap(d_ptr->generatePixmap());
+ setDown(false);
+ event->accept();
+ drg->start();
+ return;
+ }
+#endif
+ QToolButton::mouseMoveEvent(event);
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QtColorButton::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ if (!mime->hasColor())
+ return;
+
+ event->accept();
+ d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
+ d_ptr->m_dragging = true;
+ update();
+}
+
+void QtColorButton::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ event->accept();
+ d_ptr->m_dragging = false;
+ update();
+}
+
+void QtColorButton::dropEvent(QDropEvent *event)
+{
+ event->accept();
+ d_ptr->m_dragging = false;
+ if (d_ptr->m_dragColor == color())
+ return;
+ setColor(d_ptr->m_dragColor);
+ emit colorChanged(color());
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qtcolorbutton.cpp"
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.h b/src/shared/qtgradienteditor/qtcolorbutton.h
new file mode 100644
index 000000000..42fcfc113
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCOLORBUTTON_H
+#define QTCOLORBUTTON_H
+
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorButton : public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtColorButton(QWidget *parent = 0);
+ ~QtColorButton();
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ QColor color() const;
+
+public slots:
+
+ void setColor(const QColor &color);
+
+signals:
+ void colorChanged(const QColor &color);
+protected:
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+#endif
+private:
+ QScopedPointer<class QtColorButtonPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorButton)
+ Q_DISABLE_COPY(QtColorButton)
+ Q_PRIVATE_SLOT(d_func(), void slotEditColor())
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.pri b/src/shared/qtgradienteditor/qtcolorbutton.pri
new file mode 100644
index 000000000..0e41068f8
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qtcolorbutton.cpp
+HEADERS += $$PWD/qtcolorbutton.h
diff --git a/src/shared/qtgradienteditor/qtcolorline.cpp b/src/shared/qtgradienteditor/qtcolorline.cpp
new file mode 100644
index 000000000..f4eda3f9b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorline.cpp
@@ -0,0 +1,1122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtcolorline.h"
+#include "qdrawutil.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QPaintEvent>
+#include <QtGui/QStyleOption>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorLinePrivate
+{
+ QtColorLine *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorLine)
+public:
+ QtColorLinePrivate();
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+ QtColorLine::ColorComponent colorComponent() const;
+ void setColorComponent(QtColorLine::ColorComponent component);
+
+ void setIndicatorSize(int size);
+ int indicatorSize() const;
+
+ void setIndicatorSpace(int space);
+ int indicatorSpace() const;
+
+ void setFlip(bool flip);
+ bool flip() const;
+
+ void setBackgroundCheckered(bool checkered);
+ bool isBackgroundCheckered() const;
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+private:
+ void checkColor();
+ bool isMainPixmapValid() const;
+ void validate();
+ void recreateMainPixmap();
+ QSize pixmapSizeFromGeometrySize(const QSize &geometrySize) const;
+ QPixmap gradientPixmap(int size, Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const;
+ QPixmap gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const;
+ QPixmap hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped = false,
+ int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const;
+ QPixmap hueGradientPixmap(Qt::Orientation orientation, bool flipped = false,
+ int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const;
+
+ QVector<QRect> rects(const QPointF &point) const;
+
+ QColor colorFromPoint(const QPointF &point) const;
+ QPointF pointFromColor(const QColor &color) const;
+
+ QColor m_color;
+ QtColorLine::ColorComponent m_component;
+ bool m_flipped;
+ bool m_backgroundCheckered;
+ Qt::Orientation m_orientation;
+ bool m_dragging;
+ bool m_combiningAlpha;
+ int m_indicatorSize;
+ int m_indicatorSpace;
+ QPointF m_point;
+ QPoint m_clickOffset;
+
+ QPixmap m_mainPixmap;
+ QPixmap m_alphalessPixmap;
+ QPixmap m_semiAlphaPixmap;
+ QSize m_pixmapSize;
+
+ struct PixData {
+ QSize size;
+ QColor color;
+ QtColorLine::ColorComponent component;
+ bool flipped;
+ Qt::Orientation orientation;
+ };
+
+ PixData m_lastValidMainPixmapData;
+};
+
+QtColorLinePrivate::QtColorLinePrivate()
+ : m_color(Qt::black), m_component(QtColorLine::Value),
+ m_flipped(false), m_backgroundCheckered(true), m_orientation(Qt::Horizontal), m_dragging(false), m_combiningAlpha(false)
+{
+ m_indicatorSize = 22;
+ m_indicatorSpace = 0;
+ m_pixmapSize = QSize(0, 0);
+ m_point = pointFromColor(m_color);
+}
+
+void QtColorLinePrivate::setColor(const QColor &color)
+{
+ if (m_color == color)
+ return;
+ if (!color.isValid())
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ m_color = color;
+ checkColor();
+ QColor c = colorFromPoint(m_point);
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+QColor QtColorLinePrivate::color() const
+{
+ return m_color;
+}
+
+void QtColorLinePrivate::setColorComponent(QtColorLine::ColorComponent component)
+{
+ if (m_component == component)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ m_component = component;
+ checkColor();
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+QtColorLine::ColorComponent QtColorLinePrivate::colorComponent() const
+{
+ return m_component;
+}
+
+void QtColorLinePrivate::setIndicatorSize(int size)
+{
+ if (size <= 0)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_indicatorSize == size)
+ return;
+ m_indicatorSize = size;
+ m_pixmapSize = pixmapSizeFromGeometrySize(q_ptr->contentsRect().size());
+ q_ptr->update();
+ q_ptr->updateGeometry();
+}
+
+int QtColorLinePrivate::indicatorSize() const
+{
+ return m_indicatorSize;
+}
+
+void QtColorLinePrivate::setIndicatorSpace(int space)
+{
+ if (space < 0)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_indicatorSpace == space)
+ return;
+ m_indicatorSpace = space;
+ m_pixmapSize = pixmapSizeFromGeometrySize(q_ptr->contentsRect().size());
+ q_ptr->update();
+}
+
+int QtColorLinePrivate::indicatorSpace() const
+{
+ return m_indicatorSpace;
+}
+
+void QtColorLinePrivate::setFlip(bool flip)
+{
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_flipped == flip)
+ return;
+ m_flipped = flip;
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+bool QtColorLinePrivate::flip() const
+{
+ return m_flipped;
+}
+
+void QtColorLinePrivate::setBackgroundCheckered(bool checkered)
+{
+ if (m_backgroundCheckered == checkered)
+ return;
+ m_backgroundCheckered = checkered;
+ q_ptr->update();
+}
+
+bool QtColorLinePrivate::isBackgroundCheckered() const
+{
+ return m_backgroundCheckered;
+}
+
+void QtColorLinePrivate::setOrientation(Qt::Orientation orientation)
+{
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_orientation == orientation)
+ return;
+
+ m_orientation = orientation;
+ if (!q_ptr->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
+ QSizePolicy sp = q_ptr->sizePolicy();
+ sp.transpose();
+ q_ptr->setSizePolicy(sp);
+ q_ptr->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
+ }
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+ q_ptr->updateGeometry();
+}
+
+Qt::Orientation QtColorLinePrivate::orientation() const
+{
+ return m_orientation;
+}
+
+void QtColorLinePrivate::checkColor()
+{
+ switch (m_component) {
+ case QtColorLine::Red:
+ case QtColorLine::Green:
+ case QtColorLine::Blue:
+ if (m_color.spec() != QColor::Rgb)
+ m_color = m_color.toRgb();
+ break;
+ case QtColorLine::Hue:
+ case QtColorLine::Saturation:
+ case QtColorLine::Value:
+ if (m_color.spec() != QColor::Hsv)
+ m_color = m_color.toHsv();
+ break;
+ default:
+ break;
+ }
+ if (m_color.spec() == QColor::Hsv) {
+ if (m_color.hue() == 360 || m_color.hue() == -1) {
+ m_color.setHsvF(0.0, m_color.saturationF(), m_color.valueF(), m_color.alphaF());
+ }
+ }
+}
+
+bool QtColorLinePrivate::isMainPixmapValid() const
+{
+ if (m_mainPixmap.isNull()) {
+ if (m_pixmapSize.isEmpty())
+ return true;
+ else
+ return false;
+ }
+ if (m_lastValidMainPixmapData.component != m_component)
+ return false;
+ if (m_lastValidMainPixmapData.size != m_pixmapSize)
+ return false;
+ if (m_lastValidMainPixmapData.flipped != m_flipped)
+ return false;
+ if (m_lastValidMainPixmapData.orientation != m_orientation)
+ return false;
+ if (m_lastValidMainPixmapData.color == m_color)
+ return true;
+ switch (m_component) {
+ case QtColorLine::Red:
+ if (m_color.green() == m_lastValidMainPixmapData.color.green() &&
+ m_color.blue() == m_lastValidMainPixmapData.color.blue() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Green:
+ if (m_color.red() == m_lastValidMainPixmapData.color.red() &&
+ m_color.blue() == m_lastValidMainPixmapData.color.blue() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Blue:
+ if (m_color.red() == m_lastValidMainPixmapData.color.red() &&
+ m_color.green() == m_lastValidMainPixmapData.color.green() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Hue:
+ if (m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Saturation:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Value:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Alpha:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value())
+ return true;
+ }
+ return false;
+}
+
+void QtColorLinePrivate::validate()
+{
+ if (isMainPixmapValid())
+ return;
+
+ recreateMainPixmap();
+}
+
+QPixmap QtColorLinePrivate::gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped) const
+{
+ int size = m_pixmapSize.width();
+ if (orientation == Qt::Vertical)
+ size = m_pixmapSize.height();
+ return gradientPixmap(size, orientation, begin, end, flipped);
+}
+
+QPixmap QtColorLinePrivate::gradientPixmap(int size, Qt::Orientation orientation,
+ const QColor &begin, const QColor &end, bool flipped) const
+{
+ int gradW = size;
+ int gradH = size;
+ int w = size;
+ int h = size;
+ if (orientation == Qt::Horizontal) {
+ gradH = 0;
+ h = 1;
+ } else {
+ gradW = 0;
+ w = 1;
+ }
+ QColor c1 = begin;
+ QColor c2 = end;
+ if (flipped) {
+ c1 = end;
+ c2 = begin;
+ }
+ QLinearGradient lg(0, 0, gradW, gradH);
+ lg.setColorAt(0, c1);
+ lg.setColorAt(1, c2);
+ QImage img(w, h, QImage::Format_ARGB32);
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, w, h), lg);
+ return QPixmap::fromImage(img);
+}
+
+QPixmap QtColorLinePrivate::hueGradientPixmap(Qt::Orientation orientation, bool flipped,
+ int saturation, int value, int alpha) const
+{
+ int size = m_pixmapSize.width();
+ if (orientation == Qt::Vertical)
+ size = m_pixmapSize.height();
+ return hueGradientPixmap(size, orientation, flipped, saturation, value, alpha);
+}
+
+QPixmap QtColorLinePrivate::hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped,
+ int saturation, int value, int alpha) const
+{
+ int gradW = size + 1;
+ int gradH = size + 1;
+ int w = size;
+ int h = size;
+ if (orientation == Qt::Horizontal) {
+ gradH = 0;
+ h = 1;
+ } else {
+ gradW = 0;
+ w = 1;
+ }
+ QList<QColor> colorList;
+ colorList << QColor::fromHsv(0, saturation, value, alpha);
+ colorList << QColor::fromHsv(60, saturation, value, alpha);
+ colorList << QColor::fromHsv(120, saturation, value, alpha);
+ colorList << QColor::fromHsv(180, saturation, value, alpha);
+ colorList << QColor::fromHsv(240, saturation, value, alpha);
+ colorList << QColor::fromHsv(300, saturation, value, alpha);
+ colorList << QColor::fromHsv(0, saturation, value, alpha);
+ QLinearGradient lg(0, 0, gradW, gradH);
+ for (int i = 0; i <= 6; i++)
+ lg.setColorAt((double)i / 6.0, flipped ? colorList.at(6 - i) : colorList.at(i));
+ QImage img(w, h, QImage::Format_ARGB32);
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, w, h), lg);
+ return QPixmap::fromImage(img);
+}
+
+void QtColorLinePrivate::recreateMainPixmap()
+{
+ m_lastValidMainPixmapData.size = m_pixmapSize;
+ m_lastValidMainPixmapData.component = m_component;
+ m_lastValidMainPixmapData.color = m_color;
+ m_lastValidMainPixmapData.flipped = m_flipped;
+ m_lastValidMainPixmapData.orientation = m_orientation;
+
+ if (m_pixmapSize.isEmpty()) {
+ m_mainPixmap = QPixmap();
+ m_alphalessPixmap = QPixmap();
+ m_semiAlphaPixmap = QPixmap();
+ return;
+ }
+
+ if (m_mainPixmap.size() != m_pixmapSize) {
+ m_mainPixmap = QPixmap(m_pixmapSize);
+ m_alphalessPixmap = QPixmap(m_pixmapSize);
+ m_semiAlphaPixmap = QPixmap(m_pixmapSize);
+ }
+
+ Qt::Orientation orient = m_orientation;
+ const bool flip = m_flipped;
+
+ const int r = m_color.red();
+ const int g = m_color.green();
+ const int b = m_color.blue();
+ const int h = m_color.hue();
+ const int s = m_color.saturation();
+ const int v = m_color.value();
+ const int a = m_color.alpha();
+ const double coef = 0.5;
+ const int semi = qRound(a * coef + 0xFF * (1.0 - coef));
+
+ if (m_component == QtColorLine::Hue) {
+ m_alphalessPixmap = hueGradientPixmap(orient, flip, s, v, 0xFF);
+ if (m_combiningAlpha) {
+ m_mainPixmap = hueGradientPixmap(orient, flip, s, v, a);
+ m_semiAlphaPixmap = hueGradientPixmap(orient, flip, s, v, semi);
+ }
+ } else if (m_component == QtColorLine::Saturation) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, 0xFF), QColor::fromHsv(h, 0xFF, v, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, a), QColor::fromHsv(h, 0xFF, v, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, semi), QColor::fromHsv(h, 0xFF, v, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Value) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, 0xFF), QColor::fromHsv(h, s, 0xFF, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, a), QColor::fromHsv(h, s, 0xFF, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, semi), QColor::fromHsv(h, s, 0xFF, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Red) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, 0xFF), QColor::fromRgb(0xFF, g, b, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, a), QColor::fromRgb(0xFF, g, b, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, semi), QColor::fromRgb(0xFF, g, b, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Green) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, 0xFF), QColor::fromRgb(r, 0xFF, b, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, a), QColor::fromRgb(r, 0xFF, b, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, semi), QColor::fromRgb(r, 0xFF, b, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Blue) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, 0xFF), QColor::fromRgb(r, g, 0xFF, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, a), QColor::fromRgb(r, g, 0xFF, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, semi), QColor::fromRgb(r, g, 0xFF, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Alpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0), QColor::fromRgb(r, g, b, 0xFF), flip);
+
+// m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0xFF), QColor::fromRgb(r, g, b, 0xFF), flip);
+// m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, semi), QColor::fromRgb(r, g, b, semi), flip);
+ }
+ if (!m_combiningAlpha && m_component != QtColorLine::Alpha)
+ m_mainPixmap = m_alphalessPixmap;
+}
+
+QSize QtColorLinePrivate::pixmapSizeFromGeometrySize(
+ const QSize &geometrySize) const
+{
+ QSize size(m_indicatorSize + 2 * m_indicatorSpace - 1,
+ m_indicatorSize + 2 * m_indicatorSpace - 1);
+ if (m_orientation == Qt::Horizontal)
+ size.setHeight(0);
+ else
+ size.setWidth(0);
+ return geometrySize - size;
+}
+
+QColor QtColorLinePrivate::colorFromPoint(const QPointF &point) const
+{
+ QPointF p = point;
+ if (p.x() < 0)
+ p.setX(0.0);
+ else if (p.x() > 1)
+ p.setX(1.0);
+ if (p.y() < 0)
+ p.setY(0.0);
+ else if (p.y() > 1)
+ p.setY(1.0);
+
+ double pos = p.x();
+ if (m_orientation == Qt::Vertical)
+ pos = p.y();
+ if (m_flipped)
+ pos = 1.0 - pos;
+ QColor c;
+ qreal hue;
+ switch (m_component) {
+ case QtColorLine::Red:
+ c.setRgbF(pos, m_color.greenF(), m_color.blueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Green:
+ c.setRgbF(m_color.redF(), pos, m_color.blueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Blue:
+ c.setRgbF(m_color.redF(), m_color.greenF(), pos, m_color.alphaF());
+ break;
+ case QtColorLine::Hue:
+ hue = pos;
+ hue *= 35999.0 / 36000.0;
+ c.setHsvF(hue, m_color.saturationF(), m_color.valueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Saturation:
+ c.setHsvF(m_color.hueF(), pos, m_color.valueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Value:
+ c.setHsvF(m_color.hueF(), m_color.saturationF(), pos, m_color.alphaF());
+ break;
+ case QtColorLine::Alpha:
+ c.setHsvF(m_color.hueF(), m_color.saturationF(), m_color.valueF(), pos);
+ break;
+ }
+ return c;
+}
+
+QPointF QtColorLinePrivate::pointFromColor(const QColor &color) const
+{
+ qreal hue = color.hueF();
+ if (color.hue() == 360)
+ hue = 0.0;
+ else
+ hue *= 36000.0 / 35999.0;
+
+ double pos = 0.0;
+ switch (m_component) {
+ case QtColorLine::Red:
+ pos = color.redF();
+ break;
+ case QtColorLine::Green:
+ pos = color.greenF();
+ break;
+ case QtColorLine::Blue:
+ pos = color.blueF();
+ break;
+ case QtColorLine::Hue:
+ pos = hue;
+ break;
+ case QtColorLine::Saturation:
+ pos = color.saturationF();
+ break;
+ case QtColorLine::Value:
+ pos = color.valueF();
+ break;
+ case QtColorLine::Alpha:
+ pos = color.alphaF();
+ break;
+ }
+ if (m_flipped)
+ pos = 1.0 - pos;
+ QPointF p(pos, pos);
+ if (m_orientation == Qt::Horizontal)
+ p.setY(0);
+ else
+ p.setX(0);
+ return p;
+}
+
+QVector<QRect> QtColorLinePrivate::rects(const QPointF &point) const
+{
+ QRect r = q_ptr->geometry();
+ r.moveTo(0, 0);
+
+ int x1 = (int)((r.width() - m_indicatorSize - 2 * m_indicatorSpace) * point.x() + 0.5);
+ int x2 = x1 + m_indicatorSize + 2 * m_indicatorSpace;
+ int y1 = (int)((r.height() - m_indicatorSize - 2 * m_indicatorSpace) * point.y() + 0.5);
+ int y2 = y1 + m_indicatorSize + 2 * m_indicatorSpace;
+
+ QVector<QRect> rects;
+ if (m_orientation == Qt::Horizontal) {
+ // r0 r1 r2
+ QRect r0(0, 0, x1, r.height());
+ QRect r1(x1 + m_indicatorSpace, 0, m_indicatorSize, r.height());
+ QRect r2(x2, 0, r.width() - x2, r.height());
+
+ rects << r0 << r1 << r2;
+ } else {
+ // r0
+ // r1
+ // r2
+ QRect r0(0, 0, r.width(), y1);
+ QRect r1(0, y1 + m_indicatorSpace, r.width(), m_indicatorSize);
+ QRect r2(0, y2, r.width(), r.height() - y2);
+
+ rects << r0 << r1 << r2;
+ }
+ return rects;
+}
+
+void QtColorLinePrivate::resizeEvent(QResizeEvent *event)
+{
+ m_pixmapSize = pixmapSizeFromGeometrySize(event->size());
+}
+
+void QtColorLinePrivate::paintEvent(QPaintEvent *)
+{
+ QRect rect = q_ptr->rect();
+
+ QVector<QRect> r = rects(m_point);
+
+ QColor cBack = q_ptr->palette().color(QPalette::Active, QPalette::Window);
+ QColor c = colorFromPoint(m_point);
+ if (!m_combiningAlpha && m_component != QtColorLine::Alpha)
+ c.setAlpha(0xFF);
+
+ QPainter p(q_ptr);
+ if (q_ptr->isEnabled()) {
+ if (m_backgroundCheckered) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+ pmp.end();
+
+ p.setBrushOrigin((rect.width() % pixSize + pixSize) / 2, (rect.height() % pixSize + pixSize) / 2);
+ p.setClipRect(r[1].adjusted(4, 4, -4, -4));
+ p.setClipRect(QRect(rect.topLeft(), QPoint(r[1].left() + 0, rect.bottom())), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(r[1].right() - 0, rect.top()), rect.bottomRight()), Qt::UniteClip);
+ p.setClipRect(QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 0)), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(rect.left(), r[1].bottom() - 0), rect.bottomRight()), Qt::UniteClip);
+ /*
+ p.setClipRect(r[1].adjusted(3, 3, -3, -3));
+ p.setClipRect(QRect(rect.topLeft(), QPoint(r[1].left() + 1, rect.bottom())), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(r[1].right() - 1, rect.top()), rect.bottomRight()), Qt::UniteClip);
+ p.setClipRect(QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 1)), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(rect.left(), r[1].bottom() - 1), rect.bottomRight()), Qt::UniteClip);
+ */
+ p.fillRect(rect, pm);
+ p.setBrushOrigin(0, 0);
+ p.setClipping(false);
+ }
+
+ validate();
+
+ QSize fieldSize = pixmapSizeFromGeometrySize(q_ptr->geometry().size());
+
+ QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace);
+ int x = posOnField.x();
+ int y = posOnField.y();
+ int w = fieldSize.width();
+ int h = fieldSize.height();
+
+ QRect r0, r2;
+ if (m_orientation == Qt::Horizontal) {
+ r0 = QRect(0, 0, x, m_pixmapSize.height());
+ r2 = QRect(x + 1, 0, w - x - 1, m_pixmapSize.height());
+ } else {
+ r0 = QRect(0, 0, m_pixmapSize.width(), y);
+ r2 = QRect(0, y + 1, m_pixmapSize.width(), h - y - 1);
+ }
+
+ p.setBrush(m_mainPixmap);
+ p.setPen(Qt::NoPen);
+ if (r[0].isValid()) {
+ p.drawRect(r[0]);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ p.drawRect(r[2]);
+ }
+ if (m_indicatorSpace) {
+ p.setBrush(c);
+ if (m_orientation == Qt::Horizontal) {
+ p.drawRect(r[1].adjusted(-m_indicatorSpace, 0, -r[1].width(), 0));
+ p.drawRect(r[1].adjusted(r[1].width(), 0, m_indicatorSpace, 0));
+ } else {
+ p.drawRect(r[1].adjusted(0, -m_indicatorSpace, 0, -r[1].height()));
+ p.drawRect(r[1].adjusted(0, r[1].height(), 0, m_indicatorSpace));
+ }
+ }
+
+ QPen pen(c);
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ if (r[1].isValid()) {
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+ }
+ double coef = 9.0 / 10;
+ p.setPen(Qt::NoPen);
+ if (m_component != QtColorLine::Alpha && m_combiningAlpha) {
+ p.setBrush(m_alphalessPixmap);
+ if (r[0].isValid()) {
+ p.setBrushOrigin(QPoint(0, 0));
+ QRect thinRect1 = r[0];
+ QRect thinRect2 = r[0];
+ QRect thinRect = r[0];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef), 0, 0);
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef));
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef), 0, 0, 0);
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef), 0);
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ QRect thinRect1 = r[2];
+ QRect thinRect2 = r[2];
+ QRect thinRect = r[2];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef), 0, 0);
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef));
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef), 0, 0, 0);
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef), 0);
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ /*
+
+*/
+
+
+
+
+
+ p.setPen(Qt::NoPen);
+
+ p.setBrush(m_semiAlphaPixmap);
+ if (r[0].isValid()) {
+ p.setBrushOrigin(QPoint(0, 0));
+ QRect thinRect1 = r[0];
+ QRect thinRect2 = r[0];
+ QRect thinRect = r[0];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef) - 1, 0, 0);
+ thinRect1.setBottom(thinRect1.top());
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef) + 1);
+ thinRect2.setTop(thinRect2.bottom());
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef) - 1, 0, 0, 0);
+ thinRect1.setRight(thinRect1.left());
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef) + 1, 0);
+ thinRect2.setLeft(thinRect2.right());
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ QRect thinRect1 = r[2];
+ QRect thinRect2 = r[2];
+ QRect thinRect = r[2];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef) - 1, 0, 0);
+ thinRect1.setBottom(thinRect1.top());
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef) + 1);
+ thinRect2.setTop(thinRect2.bottom());
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef) - 1, 0, 0, 0);
+ thinRect1.setRight(thinRect1.left());
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef) + 1, 0);
+ thinRect2.setLeft(thinRect2.right());
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ p.setBrush(m_alphalessPixmap);
+ if (m_orientation == Qt::Horizontal) {
+ p.setClipRect(r[1].adjusted(0, qRound(r[1].height() * coef), 0, 0));
+ p.setClipRect(r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef)), Qt::UniteClip);
+ } else {
+ p.setClipRect(r[1].adjusted(qRound(r[1].width() * coef), 0, 0, 0));
+ p.setClipRect(r[1].adjusted(0, 0, -qRound(r[1].width() * coef), 0), Qt::UniteClip);
+ }
+ p.setBrush(Qt::NoBrush);
+ p.setPen(QPen(QColor(c.rgb())));
+
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+/*
+ p.setBrush(m_semiAlphaPixmap);
+ if (m_orientation == Qt::Horizontal) {
+ QRect top = r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef) + 1);
+ top.setTop(top.bottom());
+ QRect bottom = r[1].adjusted(0, qRound(r[1].height() * coef) - 1, 0, 0);
+ top.setBottom(bottom.top());
+ p.setClipRect(top);
+ p.setClipRect(bottom, Qt::UniteClip);
+ } else {
+
+ }
+ QColor semiColor(c.rgb());
+ semiColor.setAlpha((c.alpha() + 0xFF) / 2);
+ p.setPen(QPen(semiColor));
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+*/
+ p.setClipping(false);
+ }
+ }
+
+ p.setBrush(Qt::NoBrush);
+ int lw = 4;
+ //int br = 1;
+ int br = 0;
+ r[1].adjust(br, br, -br, -br);
+ if (r[1].adjusted(lw, lw, -lw, -lw).isValid()) {
+ QStyleOptionFrame opt;
+ opt.init(q_ptr);
+ opt.rect = r[1];
+ opt.lineWidth = 2;
+ opt.midLineWidth = 1;
+ if (m_dragging)
+ opt.state |= QStyle::State_Sunken;
+ else
+ opt.state |= QStyle::State_Raised;
+ q_ptr->style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, q_ptr);
+ QRect colorRect = r[1].adjusted(lw, lw, -lw, -lw);
+ if (q_ptr->isEnabled()) {
+ p.fillRect(colorRect, c);
+ const QColor frameColor(0, 0, 0, 38);
+ p.setPen(frameColor);
+ p.drawRect(colorRect.adjusted(0, 0, -1, -1));
+ /*
+ p.fillRect(colorRect.width() / 4 + colorRect.left(),
+ colorRect.height() / 4 + colorRect.top(),
+ colorRect.width() / 2,
+ colorRect.height() / 2,
+ QColor(c.rgb()));
+ */
+ /*
+ if (m_component != QtColorLine::Alpha) {
+ p.fillRect(colorRect.adjusted(0, colorRect.height() * 4 / 5, 0, 0), QColor(c.rgb()));
+ p.fillRect(colorRect.adjusted(0, 0, 0, -colorRect.height() * 4 / 5), QColor(c.rgb()));
+ }
+ */
+ }
+ }
+}
+
+void QtColorLinePrivate::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ QVector<QRect> r = rects(m_point);
+ QPoint clickPos = event->pos();
+
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+ QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace);
+ m_clickOffset = posOnField - clickPos;
+
+ if (!r[1].contains(clickPos))
+ return;
+ m_dragging = true;
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseMoveEvent(QMouseEvent *event)
+{
+ if (!m_dragging)
+ return;
+ QPoint newPos = event->pos();
+
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+ QPoint newPosOnField = newPos + m_clickOffset;
+ if (newPosOnField.x() < 0)
+ newPosOnField.setX(0);
+ else if (newPosOnField.x() > fieldSize.width())
+ newPosOnField.setX(fieldSize.width());
+ if (newPosOnField.y() < 0)
+ newPosOnField.setY(0);
+ else if (newPosOnField.y() > fieldSize.height())
+ newPosOnField.setY(fieldSize.height());
+
+ double x = (double)newPosOnField.x() / fieldSize.width();
+ double y = (double)newPosOnField.y() / fieldSize.height();
+ m_point = QPointF(x, y);
+ QColor color = colorFromPoint(m_point);
+ if (m_color == color)
+ return;
+ m_color = color;
+ emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+ m_dragging = false;
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ QVector<QRect> r = rects(m_point);
+ QPoint clickPos = event->pos();
+ if (!r[0].contains(clickPos) && !r[2].contains(clickPos))
+ return;
+ QPoint newPosOnField = clickPos;
+ if (r[2].contains(clickPos))
+ newPosOnField -= QPoint(m_indicatorSize + 2 * m_indicatorSpace - 2, m_indicatorSize + 2 * m_indicatorSpace - 2);
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+
+ double x = (double)newPosOnField.x() / fieldSize.width();
+ double y = (double)newPosOnField.y() / fieldSize.height();
+ m_point = QPointF(x, y);
+ QColor color = colorFromPoint(m_point);
+ if (m_color == color)
+ return;
+ m_color = color;
+ emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above
+ q_ptr->update();
+}
+
+////////////////////////////////////////////////////
+
+QtColorLine::QtColorLine(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtColorLinePrivate)
+{
+ d_ptr->q_ptr = this;
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+}
+
+QtColorLine::~QtColorLine()
+{
+}
+
+QSize QtColorLine::minimumSizeHint() const
+{
+ return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize);
+}
+
+QSize QtColorLine::sizeHint() const
+{
+ return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize);
+}
+
+void QtColorLine::setColor(const QColor &color)
+{
+ d_ptr->setColor(color);
+}
+
+QColor QtColorLine::color() const
+{
+ return d_ptr->color();
+}
+
+void QtColorLine::setColorComponent(QtColorLine::ColorComponent component)
+{
+ d_ptr->setColorComponent(component);
+}
+
+QtColorLine::ColorComponent QtColorLine::colorComponent() const
+{
+ return d_ptr->colorComponent();
+}
+
+void QtColorLine::setIndicatorSize(int size)
+{
+ d_ptr->setIndicatorSize(size);
+}
+
+int QtColorLine::indicatorSize() const
+{
+ return d_ptr->indicatorSize();
+}
+
+void QtColorLine::setIndicatorSpace(int space)
+{
+ d_ptr->setIndicatorSpace(space);
+}
+
+int QtColorLine::indicatorSpace() const
+{
+ return d_ptr->indicatorSpace();
+}
+
+void QtColorLine::setFlip(bool flip)
+{
+ d_ptr->setFlip(flip);
+}
+
+bool QtColorLine::flip() const
+{
+ return d_ptr->flip();
+}
+
+void QtColorLine::setBackgroundCheckered(bool checkered)
+{
+ d_ptr->setBackgroundCheckered(checkered);
+}
+
+bool QtColorLine::isBackgroundCheckered() const
+{
+ return d_ptr->isBackgroundCheckered();
+}
+
+void QtColorLine::setOrientation(Qt::Orientation orientation)
+{
+ d_ptr->setOrientation(orientation);
+}
+
+Qt::Orientation QtColorLine::orientation() const
+{
+ return d_ptr->orientation();
+}
+void QtColorLine::resizeEvent(QResizeEvent *event)
+{
+ d_ptr->resizeEvent(event);
+}
+
+void QtColorLine::paintEvent(QPaintEvent *event)
+{
+ d_ptr->paintEvent(event);
+}
+
+void QtColorLine::mousePressEvent(QMouseEvent *event)
+{
+ d_ptr->mousePressEvent(event);
+}
+
+void QtColorLine::mouseMoveEvent(QMouseEvent *event)
+{
+ d_ptr->mouseMoveEvent(event);
+}
+
+void QtColorLine::mouseReleaseEvent(QMouseEvent *event)
+{
+ d_ptr->mouseReleaseEvent(event);
+}
+
+void QtColorLine::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ d_ptr->mouseDoubleClickEvent(event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtcolorline.h b/src/shared/qtgradienteditor/qtcolorline.h
new file mode 100644
index 000000000..8d04a7ca7
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorline.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCOLORLINE_H
+#define QTCOLORLINE_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorLine : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor color READ color WRITE setColor)
+ Q_PROPERTY(int indicatorSpace READ indicatorSpace WRITE setIndicatorSpace)
+ Q_PROPERTY(int indicatorSize READ indicatorSize WRITE setIndicatorSize)
+ Q_PROPERTY(bool flip READ flip WRITE setFlip)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(ColorComponent colorComponent READ colorComponent WRITE setColorComponent)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_ENUMS(ColorComponent)
+public:
+
+ enum ColorComponent {
+ Red,
+ Green,
+ Blue,
+ Hue,
+ Saturation,
+ Value,
+ Alpha
+ };
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+ QtColorLine(QWidget *parent = 0);
+ ~QtColorLine();
+
+ QColor color() const;
+
+ void setIndicatorSize(int size);
+ int indicatorSize() const;
+
+ void setIndicatorSpace(int space);
+ int indicatorSpace() const;
+
+ void setFlip(bool flip);
+ bool flip() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void setColorComponent(ColorComponent component);
+ ColorComponent colorComponent() const;
+
+public slots:
+
+ void setColor(const QColor &color);
+
+signals:
+
+ void colorChanged(const QColor &color);
+
+protected:
+
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+
+private:
+
+ QScopedPointer<class QtColorLinePrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorLine)
+ Q_DISABLE_COPY(QtColorLine)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.cpp b/src/shared/qtgradienteditor/qtgradientdialog.cpp
new file mode 100644
index 000000000..dbeeb1f20
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.cpp
@@ -0,0 +1,353 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientdialog.h"
+#include "ui_qtgradientdialog.h"
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientDialogPrivate
+{
+ QtGradientDialog *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientDialog)
+public:
+
+ void slotAboutToShowDetails(bool details, int extensionWidthHint);
+
+ Ui::QtGradientDialog m_ui;
+};
+
+void QtGradientDialogPrivate::slotAboutToShowDetails(bool details, int extensionWidthHint)
+{
+ if (details) {
+ q_ptr->resize(q_ptr->size() + QSize(extensionWidthHint, 0));
+ } else {
+ q_ptr->setMinimumSize(1, 1);
+ q_ptr->resize(q_ptr->size() - QSize(extensionWidthHint, 0));
+ q_ptr->setMinimumSize(0, 0);
+ }
+}
+
+/*!
+ \class QtGradientDialog
+
+ \brief The QtGradientDialog class provides a dialog for specifying gradients.
+
+ The gradient dialog's function is to allow users to edit gradients.
+ For example, you might use this in a drawing program to allow the user to set the brush gradient.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialog.png
+ \o \inlineimage qtgradientdialogextension.png
+ \header
+ \o Details extension hidden
+ \o Details extension visible
+ \endtable
+
+ Starting from the top of the dialog there are several buttons:
+
+ \image qtgradientdialogtopbuttons.png
+
+ The first three buttons allow for changing a type of the gradient (QGradient::Type), while the second three allow for
+ changing spread of the gradient (QGradient::Spread). The last button shows or hides the details extension of the dialog.
+ Conceptually the default view with hidden details provides the full functional control over gradient editing.
+ The additional extension with details allows to set gradient's parameters more precisely. The visibility
+ of extension can be controlled by detailsVisible property. Moreover, if you don't want the user to
+ switch on or off the visibility of extension you can set the detailsButtonVisible property to false.
+
+ Below top buttons there is an area where edited gradient is interactively previewed.
+ In addition the user can edit gradient type's specific parameters directly in this area by dragging
+ appropriate handles.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialoglineareditor.png
+ \o \inlineimage qtgradientdialogradialeditor.png
+ \o \inlineimage qtgradientdialogconicaleditor.png
+ \header
+ \o Editing linear type
+ \o Editing radial type
+ \o Editing conical type
+ \row
+ \o The user can change the start and final point positions by dragging the circular handles.
+ \o The user can change the center and focal point positions by dragging the circular handles
+ and can change the gradient's radius by dragging horizontal or vertical line.
+ \o The user can change the center point by dragging the circular handle
+ and can change the gradient's angle by dragging the big wheel.
+ \endtable
+
+ In the middle of the dialog there is an area where the user can edit gradient stops.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogstops.png
+ \o \inlineimage qtgradientdialogstopszoomed.png
+ \endtable
+
+ The top part of this area contains stop handles, and bottom part shows the preview of gradient stops path.
+ In order to create a new gradient stop double click inside the view over the desired position.
+ If you double click on existing stop handle in the top part of the view, clicked handle will be duplicated
+ (duplicate will contain the same color).
+ The stop can be activated by clicking on its handle. You can activate previous or next stop by pressing
+ left or right key respectively. To jump to the first or last stop press home or end key respectively.
+ The gradient stops editor supports multiselection.
+ Clicking a handle holding the shift modifier key down will select a range of stops between
+ the active stop and clicked one. Clicking a handle holding control modifier key down will remove from or
+ add to selection the clicked stop depending if it was or wasn't already selected respectively.
+ Multiselection can also be created using rubberband (by pressing the left mouse button outside
+ of any handle and dragging).
+ Sometimes it's hard to select a stop because its handle can be partially covered by other handle.
+ In that case the user can zoom in the view by spinning mouse wheel.
+ The selected stop handles can be moved by drag & drop. In order to remove selected stops press delete key.
+ For convenience context menu is provided with the following actions:
+
+ \list
+ \o New Stop - creates a new gradient stop
+ \o Delete - removes the active and all selected stops
+ \o Flip All - mirrors all stops
+ \o Select All - selects all stops
+ \o Zoom In - zooms in
+ \o Zoom Out - zooms out
+ \o Zoom All - goes back to original 100% zoom
+ \endlist
+
+ The bottom part of the QtGradientDialog contains a set of widgets allowing to control the color of
+ the active and selected stops.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogcolorhsv.png
+ \o \inlineimage qtgradientdialogcolorrgb.png
+ \endtable
+
+
+ The color button shows the color of the active gradient stop. It also allows for choosing
+ a color from standard color dialog and applying it to the
+ active stop and all selected stops. It's also possible to drag a color directly from the color button
+ and to drop it in gradient stops editor at desired position (it will create new stop with dragged color)
+ or at desired stop handle (it will change the color of that handle).
+
+ To the right of color button there is a set of 2 radio buttons which allows to switch between
+ HVS and RGB color spec.
+
+ Finally there are 4 color sliders working either in HSVA (hue saturation value alpha) or
+ RGBA (red green blue alpha) mode, depending on which radio button is chosen. The radio buttons
+ can be controlled programatically by spec() and setSpec() methods. The sliders show the
+ color of the active stop. By double clicking inside color slider you can set directly the desired color.
+ Changes of slider's are applied to stop selection in the way that the color
+ component being changed is applied to stops in selection only, while other components
+ remain unchanged in selected stops (e.g. when the user is changing the saturation,
+ new saturation is applied to selected stops preventing original hue, value and alpha in multiselection).
+
+ The convenient static functions getGradient() provide modal gradient dialogs, e.g.:
+
+ \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 0
+
+ In order to have more control over the properties of QtGradientDialog use
+ standard QDialog::exec() method:
+
+ \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 1
+
+ \sa {Gradient View Example}
+*/
+
+/*!
+ Constructs a gradient dialog with \a parent as parent widget.
+*/
+
+QtGradientDialog::QtGradientDialog(QWidget *parent)
+ : QDialog(parent), d_ptr(new QtGradientDialogPrivate())
+{
+// setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ d_ptr->q_ptr = this;
+ d_ptr->m_ui.setupUi(this);
+ QPushButton *button = d_ptr->m_ui.buttonBox->button(QDialogButtonBox::Ok);
+ if (button)
+ button->setAutoDefault(false);
+ button = d_ptr->m_ui.buttonBox->button(QDialogButtonBox::Cancel);
+ if (button)
+ button->setAutoDefault(false);
+ connect(d_ptr->m_ui.gradientEditor, SIGNAL(aboutToShowDetails(bool,int)),
+ this, SLOT(slotAboutToShowDetails(bool,int)));
+}
+
+/*!
+ Destroys the gradient dialog
+*/
+
+QtGradientDialog::~QtGradientDialog()
+{
+}
+
+/*!
+ \property QtGradientDialog::gradient
+ \brief the gradient of the dialog
+*/
+void QtGradientDialog::setGradient(const QGradient &gradient)
+{
+ d_ptr->m_ui.gradientEditor->setGradient(gradient);
+}
+
+QGradient QtGradientDialog::gradient() const
+{
+ return d_ptr->m_ui.gradientEditor->gradient();
+}
+
+/*!
+ \property QtGradientDialog::backgroundCheckered
+ \brief whether the background of widgets able to show the colors with alpha channel is checkered.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogbackgroundcheckered.png
+ \o \inlineimage qtgradientdialogbackgroundtransparent.png
+ \row
+ \o \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 2
+ \o \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 3
+ \endtable
+
+ When this property is set to true (the default) widgets inside gradient dialog like color button,
+ color sliders, gradient stops editor and gradient editor will show checkered background
+ in case of transparent colors. Otherwise the background of these widgets is transparent.
+*/
+
+bool QtGradientDialog::isBackgroundCheckered() const
+{
+ return d_ptr->m_ui.gradientEditor->isBackgroundCheckered();
+}
+
+void QtGradientDialog::setBackgroundCheckered(bool checkered)
+{
+ d_ptr->m_ui.gradientEditor->setBackgroundCheckered(checkered);
+}
+
+/*!
+ \property QtGradientDialog::detailsVisible
+ \brief whether details extension is visible.
+
+ When this property is set to true the details extension is visible. By default
+ this property is set to false and the details extension is hidden.
+
+ \sa detailsButtonVisible
+*/
+bool QtGradientDialog::detailsVisible() const
+{
+ return d_ptr->m_ui.gradientEditor->detailsVisible();
+}
+
+void QtGradientDialog::setDetailsVisible(bool visible)
+{
+ d_ptr->m_ui.gradientEditor->setDetailsVisible(visible);
+}
+
+/*!
+ \property QtGradientDialog::detailsButtonVisible
+ \brief whether the details button allowing for showing and hiding details extension is visible.
+
+ When this property is set to true (the default) the details button is visible and the user
+ can show and hide details extension interactively. Otherwise the button is hidden and the details
+ extension is always visible or hidded depending on the value of detailsVisible property.
+
+ \sa detailsVisible
+*/
+bool QtGradientDialog::isDetailsButtonVisible() const
+{
+ return d_ptr->m_ui.gradientEditor->isDetailsButtonVisible();
+}
+
+void QtGradientDialog::setDetailsButtonVisible(bool visible)
+{
+ d_ptr->m_ui.gradientEditor->setDetailsButtonVisible(visible);
+}
+
+/*!
+ Returns the current QColor::Spec used for the color sliders in the dialog.
+*/
+QColor::Spec QtGradientDialog::spec() const
+{
+ return d_ptr->m_ui.gradientEditor->spec();
+}
+
+/*!
+ Sets the current QColor::Spec to \a spec used for the color sliders in the dialog.
+*/
+void QtGradientDialog::setSpec(QColor::Spec spec)
+{
+ d_ptr->m_ui.gradientEditor->setSpec(spec);
+}
+
+/*!
+ Executes a modal gradient dialog, lets the user to specify a gradient, and returns that gradient.
+
+ If the user clicks \gui OK, the gradient specified by the user is returned. If the user clicks \gui Cancel, the \a initial gradient is returned.
+
+ The dialog is constructed with the given \a parent. \a caption is shown as the window title of the dialog and
+ \a initial is the initial gradient shown in the dialog. If the \a ok parameter is not-null,
+ the value it refers to is set to true if the user clicks \gui OK, and set to false if the user clicks \gui Cancel.
+*/
+QGradient QtGradientDialog::getGradient(bool *ok, const QGradient &initial, QWidget *parent, const QString &caption)
+{
+ QtGradientDialog dlg(parent);
+ if (!caption.isEmpty())
+ dlg.setWindowTitle(caption);
+ dlg.setGradient(initial);
+ const int res = dlg.exec();
+ if (ok) {
+ *ok = (res == QDialog::Accepted) ? true : false;
+ }
+ if (res == QDialog::Accepted)
+ return dlg.gradient();
+ return initial;
+}
+
+/*!
+ This method calls getGradient(ok, QLinearGradient(), parent, caption).
+*/
+QGradient QtGradientDialog::getGradient(bool *ok, QWidget *parent, const QString &caption)
+{
+ return getGradient(ok, QLinearGradient(), parent, caption);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientdialog.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.h b/src/shared/qtgradienteditor/qtgradientdialog.h
new file mode 100644
index 000000000..c6330d164
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTDIALOG_H
+#define QTGRADIENTDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientDialog : public QDialog
+{
+ Q_OBJECT
+ Q_PROPERTY(QGradient gradient READ gradient WRITE setGradient)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(bool detailsVisible READ detailsVisible WRITE setDetailsVisible)
+ Q_PROPERTY(bool detailsButtonVisible READ isDetailsButtonVisible WRITE setDetailsButtonVisible)
+public:
+ QtGradientDialog(QWidget *parent = 0);
+ ~QtGradientDialog();
+
+ void setGradient(const QGradient &gradient);
+ QGradient gradient() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ bool detailsVisible() const;
+ void setDetailsVisible(bool visible);
+
+ bool isDetailsButtonVisible() const;
+ void setDetailsButtonVisible(bool visible);
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+ static QGradient getGradient(bool *ok, const QGradient &initial, QWidget *parent = 0, const QString &caption = QString());
+ static QGradient getGradient(bool *ok, QWidget *parent = 0, const QString &caption = QString());
+
+private:
+ QScopedPointer<class QtGradientDialogPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientDialog)
+ Q_DISABLE_COPY(QtGradientDialog)
+ Q_PRIVATE_SLOT(d_func(), void slotAboutToShowDetails(bool details, int extensionWidthHint))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.ui b/src/shared/qtgradienteditor/qtgradientdialog.ui
new file mode 100644
index 000000000..0652c1636
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.ui
@@ -0,0 +1,121 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientDialog</class>
+ <widget class="QDialog" name="QtGradientDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>178</width>
+ <height>81</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Edit Gradient</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QtGradientEditor" name="gradientEditor" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtGradientEditor</class>
+ <extends>QFrame</extends>
+ <header>qtgradienteditor.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtGradientDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>72</x>
+ <y>224</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>21</x>
+ <y>243</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtGradientDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>168</x>
+ <y>233</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>152</x>
+ <y>251</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.cpp b/src/shared/qtgradienteditor/qtgradienteditor.cpp
new file mode 100644
index 000000000..2855389d2
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.cpp
@@ -0,0 +1,952 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradienteditor.h"
+#include "qtgradientstopscontroller.h"
+#include "ui_qtgradienteditor.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientEditorPrivate
+{
+ QtGradientEditor *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientEditor)
+public:
+ QtGradientEditorPrivate() : m_gradient(QLinearGradient()) {}
+
+ void slotGradientStopsChanged(const QGradientStops &stops);
+ void slotTypeChanged(int type);
+ void slotSpreadChanged(int spread);
+ void slotStartLinearXChanged(double value);
+ void slotStartLinearYChanged(double value);
+ void slotEndLinearXChanged(double value);
+ void slotEndLinearYChanged(double value);
+ void slotCentralRadialXChanged(double value);
+ void slotCentralRadialYChanged(double value);
+ void slotFocalRadialXChanged(double value);
+ void slotFocalRadialYChanged(double value);
+ void slotRadiusRadialChanged(double value);
+ void slotCentralConicalXChanged(double value);
+ void slotCentralConicalYChanged(double value);
+ void slotAngleConicalChanged(double value);
+
+ void slotDetailsChanged(bool details);
+
+ void startLinearChanged(const QPointF &point);
+ void endLinearChanged(const QPointF &point);
+ void centralRadialChanged(const QPointF &point);
+ void focalRadialChanged(const QPointF &point);
+ void radiusRadialChanged(qreal radius);
+ void centralConicalChanged(const QPointF &point);
+ void angleConicalChanged(qreal angle);
+
+ void setStartLinear(const QPointF &point);
+ void setEndLinear(const QPointF &point);
+ void setCentralRadial(const QPointF &point);
+ void setFocalRadial(const QPointF &point);
+ void setRadiusRadial(qreal radius);
+ void setCentralConical(const QPointF &point);
+ void setAngleConical(qreal angle);
+
+ void setType(QGradient::Type type);
+ void showDetails(bool details);
+
+ void setSpinBox(QDoubleSpinBox *spinBox, const char *slot, double max = 1.0, double step = 0.01, int decimals = 3);
+ void reset();
+ void setLayout(bool details);
+ void layoutDetails(bool details);
+ bool row4Visible() const;
+ bool row5Visible() const;
+ int extensionWidthHint() const;
+
+ void setCombos(bool combos);
+
+ QGradient gradient() const;
+ void updateGradient(bool emitSignal);
+
+ Ui::QtGradientEditor m_ui;
+ QtGradientStopsController *m_gradientStopsController;
+
+ QDoubleSpinBox *startLinearXSpinBox;
+ QDoubleSpinBox *startLinearYSpinBox;
+ QDoubleSpinBox *endLinearXSpinBox;
+ QDoubleSpinBox *endLinearYSpinBox;
+ QDoubleSpinBox *centralRadialXSpinBox;
+ QDoubleSpinBox *centralRadialYSpinBox;
+ QDoubleSpinBox *focalRadialXSpinBox;
+ QDoubleSpinBox *focalRadialYSpinBox;
+ QDoubleSpinBox *radiusRadialSpinBox;
+ QDoubleSpinBox *centralConicalXSpinBox;
+ QDoubleSpinBox *centralConicalYSpinBox;
+ QDoubleSpinBox *angleConicalSpinBox;
+
+ QButtonGroup *m_typeGroup;
+ QButtonGroup *m_spreadGroup;
+
+ QGradient::Type m_type;
+
+ QGridLayout *m_gridLayout;
+ QWidget *m_hiddenWidget;
+ QGridLayout *m_hiddenLayout;
+ bool m_details;
+ bool m_detailsButtonVisible;
+ bool m_backgroundCheckered;
+
+ QGradient m_gradient;
+
+ bool m_combos;
+};
+
+QGradient QtGradientEditorPrivate::gradient() const
+{
+ QGradient *gradient = 0;
+ switch (m_ui.gradientWidget->gradientType()) {
+ case QGradient::LinearGradient:
+ gradient = new QLinearGradient(m_ui.gradientWidget->startLinear(),
+ m_ui.gradientWidget->endLinear());
+ break;
+ case QGradient::RadialGradient:
+ gradient = new QRadialGradient(m_ui.gradientWidget->centralRadial(),
+ m_ui.gradientWidget->radiusRadial(),
+ m_ui.gradientWidget->focalRadial());
+ break;
+ case QGradient::ConicalGradient:
+ gradient = new QConicalGradient(m_ui.gradientWidget->centralConical(),
+ m_ui.gradientWidget->angleConical());
+ break;
+ default:
+ break;
+ }
+ if (!gradient)
+ return QGradient();
+ gradient->setStops(m_ui.gradientWidget->gradientStops());
+ gradient->setSpread(m_ui.gradientWidget->gradientSpread());
+ gradient->setCoordinateMode(QGradient::StretchToDeviceMode);
+ QGradient gr = *gradient;
+ delete gradient;
+ return gr;
+}
+
+void QtGradientEditorPrivate::updateGradient(bool emitSignal)
+{
+ QGradient grad = gradient();
+ if (m_gradient == grad)
+ return;
+
+ m_gradient = grad;
+ if (emitSignal)
+ emit q_ptr->gradientChanged(m_gradient);
+}
+
+void QtGradientEditorPrivate::setCombos(bool combos)
+{
+ if (m_combos == combos)
+ return;
+
+ m_combos = combos;
+ m_ui.linearButton->setVisible(!m_combos);
+ m_ui.radialButton->setVisible(!m_combos);
+ m_ui.conicalButton->setVisible(!m_combos);
+ m_ui.padButton->setVisible(!m_combos);
+ m_ui.repeatButton->setVisible(!m_combos);
+ m_ui.reflectButton->setVisible(!m_combos);
+ m_ui.typeComboBox->setVisible(m_combos);
+ m_ui.spreadComboBox->setVisible(m_combos);
+}
+
+void QtGradientEditorPrivate::setLayout(bool details)
+{
+ QHBoxLayout *hboxLayout = new QHBoxLayout();
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ hboxLayout->addWidget(m_ui.typeComboBox);
+ hboxLayout->addWidget(m_ui.spreadComboBox);
+ QHBoxLayout *typeLayout = new QHBoxLayout();
+ typeLayout->setSpacing(0);
+ typeLayout->addWidget(m_ui.linearButton);
+ typeLayout->addWidget(m_ui.radialButton);
+ typeLayout->addWidget(m_ui.conicalButton);
+ hboxLayout->addLayout(typeLayout);
+ QHBoxLayout *spreadLayout = new QHBoxLayout();
+ spreadLayout->setSpacing(0);
+ spreadLayout->addWidget(m_ui.padButton);
+ spreadLayout->addWidget(m_ui.repeatButton);
+ spreadLayout->addWidget(m_ui.reflectButton);
+ hboxLayout->addLayout(spreadLayout);
+ hboxLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ hboxLayout->addWidget(m_ui.detailsButton);
+ m_gridLayout->addLayout(hboxLayout, 0, 0, 1, 2);
+ int span = 1;
+ if (details)
+ span = 7;
+ m_gridLayout->addWidget(m_ui.frame, 1, 0, span, 2);
+ int row = 2;
+ if (details) {
+ row = 8;
+ span = 4;
+ }
+ m_gridLayout->addWidget(m_ui.gradientStopsWidget, row, 0, span, 2);
+ QHBoxLayout *hboxLayout1 = new QHBoxLayout();
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
+ hboxLayout1->addWidget(m_ui.colorLabel);
+ hboxLayout1->addWidget(m_ui.colorButton);
+ hboxLayout1->addWidget(m_ui.hsvRadioButton);
+ hboxLayout1->addWidget(m_ui.rgbRadioButton);
+ hboxLayout1->addItem(new QSpacerItem(16, 23, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ int addRow = 0;
+ if (details)
+ addRow = 9;
+ m_gridLayout->addLayout(hboxLayout1, 3 + addRow, 0, 1, 2);
+ m_gridLayout->addWidget(m_ui.hLabel, 4 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_2, 4 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.sLabel, 5 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_5, 5 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.vLabel, 6 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_3, 6 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.aLabel, 7 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_4, 7 + addRow, 1, 1, 1);
+
+ if (details) {
+ layoutDetails(details);
+ }
+}
+
+void QtGradientEditorPrivate::layoutDetails(bool details)
+{
+ QGridLayout *gridLayout = m_gridLayout;
+ int col = 2;
+ if (!details) {
+ col = 0;
+ if (!m_hiddenWidget) {
+ m_hiddenWidget = new QWidget();
+ m_hiddenLayout = new QGridLayout(m_hiddenWidget);
+ m_hiddenLayout->setContentsMargins(0, 0, 0, 0);
+ m_hiddenLayout->setSizeConstraint(QLayout::SetFixedSize);
+ }
+ gridLayout = m_hiddenLayout;
+ }
+ gridLayout->addWidget(m_ui.label1, 1, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox1, 1, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label2, 2, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox2, 2, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label3, 3, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox3, 3, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label4, 4, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox4, 4, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label5, 5, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox5, 5, col + 1, 1, 1);
+ gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 6, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.line1Widget, 7, col + 0, 1, 2);
+ gridLayout->addWidget(m_ui.zoomLabel, 8, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.zoomWidget, 8, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.zoomButtonsWidget, 9, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.zoomAllButton, 9, col + 1, 1, 1);
+ gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Preferred), 10, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.line2Widget, 11, col + 0, 1, 2);
+ gridLayout->addWidget(m_ui.positionLabel, 12, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.positionWidget, 12, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.hueLabel, 13, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.hueWidget, 13, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.saturationLabel, 14, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.saturationWidget, 14, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.valueLabel, 15, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.valueWidget, 15, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.alphaLabel, 16, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.alphaWidget, 16, col + 1, 1, 1);
+
+ if (details) {
+ if (m_hiddenLayout) {
+ delete m_hiddenLayout;
+ m_hiddenLayout = 0;
+ }
+ if (m_hiddenWidget) {
+ delete m_hiddenWidget;
+ m_hiddenWidget = 0;
+ }
+ }
+}
+
+int QtGradientEditorPrivate::extensionWidthHint() const
+{
+ if (m_details)
+ return q_ptr->size().width() - m_ui.gradientStopsWidget->size().width();
+
+ const int space = m_ui.spinBox1->geometry().left() - m_ui.label1->geometry().right();
+
+ return m_hiddenLayout->minimumSize().width() + space;
+}
+
+void QtGradientEditorPrivate::slotDetailsChanged(bool details)
+{
+ showDetails(details);
+}
+
+bool QtGradientEditorPrivate::row4Visible() const
+{
+ if (m_type == QGradient::ConicalGradient)
+ return false;
+ return true;
+}
+
+bool QtGradientEditorPrivate::row5Visible() const
+{
+ if (m_type == QGradient::RadialGradient)
+ return true;
+ return false;
+}
+
+void QtGradientEditorPrivate::showDetails(bool details)
+{
+ if (m_details == details)
+ return;
+
+ bool blocked = m_ui.detailsButton->signalsBlocked();
+ m_ui.detailsButton->blockSignals(true);
+ m_ui.detailsButton->setChecked(details);
+ m_ui.detailsButton->blockSignals(blocked);
+
+ bool updates = q_ptr->updatesEnabled();
+ q_ptr->setUpdatesEnabled(false);
+
+ if (m_gridLayout) {
+ m_gridLayout->setEnabled(false);
+ delete m_gridLayout;
+ m_gridLayout = 0;
+ }
+
+ if (!details) {
+ layoutDetails(details);
+ }
+
+ emit q_ptr->aboutToShowDetails(details, extensionWidthHint());
+ m_details = details;
+
+ m_gridLayout = new QGridLayout(q_ptr);
+ m_gridLayout->setEnabled(false);
+ m_gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ m_gridLayout->setContentsMargins(0, 0, 0, 0);
+
+ m_ui.label4->setVisible(row4Visible());
+ m_ui.label5->setVisible(row5Visible());
+ m_ui.spinBox4->setVisible(row4Visible());
+ m_ui.spinBox5->setVisible(row5Visible());
+
+ setLayout(details);
+ m_gridLayout->setEnabled(true);
+
+ q_ptr->setUpdatesEnabled(updates);
+ q_ptr->update();
+}
+
+void QtGradientEditorPrivate::setSpinBox(QDoubleSpinBox *spinBox, const char *slot, double max, double step, int decimals)
+{
+ bool blocked = spinBox->signalsBlocked();
+ spinBox->blockSignals(true);
+ spinBox->setDecimals(decimals);
+ spinBox->setMaximum(max);
+ spinBox->setSingleStep(step);
+ spinBox->blockSignals(blocked);
+ QObject::connect(spinBox, SIGNAL(valueChanged(double)), q_ptr, slot);
+}
+
+void QtGradientEditorPrivate::reset()
+{
+ startLinearXSpinBox = 0;
+ startLinearYSpinBox = 0;
+ endLinearXSpinBox = 0;
+ endLinearYSpinBox = 0;
+ centralRadialXSpinBox = 0;
+ centralRadialYSpinBox = 0;
+ focalRadialXSpinBox = 0;
+ focalRadialYSpinBox = 0;
+ radiusRadialSpinBox = 0;
+ centralConicalXSpinBox = 0;
+ centralConicalYSpinBox = 0;
+ angleConicalSpinBox = 0;
+}
+
+void QtGradientEditorPrivate::setType(QGradient::Type type)
+{
+ if (m_type == type)
+ return;
+
+ m_type = type;
+ m_ui.spinBox1->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox2->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox3->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox4->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox5->disconnect(SIGNAL(valueChanged(double)));
+
+ reset();
+
+ bool ena = true;
+
+ if (m_gridLayout) {
+ ena = m_gridLayout->isEnabled();
+ m_gridLayout->setEnabled(false);
+ }
+
+ bool spreadEnabled = true;
+
+ if (type == QGradient::LinearGradient) {
+ startLinearXSpinBox = m_ui.spinBox1;
+ setSpinBox(startLinearXSpinBox, SLOT(slotStartLinearXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Start X", 0, QApplication::UnicodeUTF8));
+
+ startLinearYSpinBox = m_ui.spinBox2;
+ setSpinBox(startLinearYSpinBox, SLOT(slotStartLinearYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Start Y", 0, QApplication::UnicodeUTF8));
+
+ endLinearXSpinBox = m_ui.spinBox3;
+ setSpinBox(endLinearXSpinBox, SLOT(slotEndLinearXChanged(double)));
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Final X", 0, QApplication::UnicodeUTF8));
+
+ endLinearYSpinBox = m_ui.spinBox4;
+ setSpinBox(endLinearYSpinBox, SLOT(slotEndLinearYChanged(double)));
+ m_ui.label4->setText(QApplication::translate("QtGradientEditor", "Final Y", 0, QApplication::UnicodeUTF8));
+
+ setStartLinear(m_ui.gradientWidget->startLinear());
+ setEndLinear(m_ui.gradientWidget->endLinear());
+ } else if (type == QGradient::RadialGradient) {
+ centralRadialXSpinBox = m_ui.spinBox1;
+ setSpinBox(centralRadialXSpinBox, SLOT(slotCentralRadialXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Central X", 0, QApplication::UnicodeUTF8));
+
+ centralRadialYSpinBox = m_ui.spinBox2;
+ setSpinBox(centralRadialYSpinBox, SLOT(slotCentralRadialYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Central Y", 0, QApplication::UnicodeUTF8));
+
+ focalRadialXSpinBox = m_ui.spinBox3;
+ setSpinBox(focalRadialXSpinBox, SLOT(slotFocalRadialXChanged(double)));
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Focal X", 0, QApplication::UnicodeUTF8));
+
+ focalRadialYSpinBox = m_ui.spinBox4;
+ setSpinBox(focalRadialYSpinBox, SLOT(slotFocalRadialYChanged(double)));
+ m_ui.label4->setText(QApplication::translate("QtGradientEditor", "Focal Y", 0, QApplication::UnicodeUTF8));
+
+ radiusRadialSpinBox = m_ui.spinBox5;
+ setSpinBox(radiusRadialSpinBox, SLOT(slotRadiusRadialChanged(double)), 2.0);
+ m_ui.label5->setText(QApplication::translate("QtGradientEditor", "Radius", 0, QApplication::UnicodeUTF8));
+
+ setCentralRadial(m_ui.gradientWidget->centralRadial());
+ setFocalRadial(m_ui.gradientWidget->focalRadial());
+ setRadiusRadial(m_ui.gradientWidget->radiusRadial());
+ } else if (type == QGradient::ConicalGradient) {
+ centralConicalXSpinBox = m_ui.spinBox1;
+ setSpinBox(centralConicalXSpinBox, SLOT(slotCentralConicalXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Central X", 0, QApplication::UnicodeUTF8));
+
+ centralConicalYSpinBox = m_ui.spinBox2;
+ setSpinBox(centralConicalYSpinBox, SLOT(slotCentralConicalYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Central Y", 0, QApplication::UnicodeUTF8));
+
+ angleConicalSpinBox = m_ui.spinBox3;
+ setSpinBox(angleConicalSpinBox, SLOT(slotAngleConicalChanged(double)), 360.0, 1.0, 1);
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Angle", 0, QApplication::UnicodeUTF8));
+
+ setCentralConical(m_ui.gradientWidget->centralConical());
+ setAngleConical(m_ui.gradientWidget->angleConical());
+
+ spreadEnabled = false;
+ }
+ m_ui.spreadComboBox->setEnabled(spreadEnabled);
+ m_ui.padButton->setEnabled(spreadEnabled);
+ m_ui.repeatButton->setEnabled(spreadEnabled);
+ m_ui.reflectButton->setEnabled(spreadEnabled);
+
+ m_ui.label4->setVisible(row4Visible());
+ m_ui.spinBox4->setVisible(row4Visible());
+ m_ui.label5->setVisible(row5Visible());
+ m_ui.spinBox5->setVisible(row5Visible());
+
+ if (m_gridLayout) {
+ m_gridLayout->setEnabled(ena);
+ }
+}
+
+void QtGradientEditorPrivate::slotGradientStopsChanged(const QGradientStops &stops)
+{
+ m_ui.gradientWidget->setGradientStops(stops);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotTypeChanged(int idx)
+{
+ QGradient::Type type = QGradient::NoGradient;
+ if (idx == 0)
+ type = QGradient::LinearGradient;
+ else if (idx == 1)
+ type = QGradient::RadialGradient;
+ else if (idx == 2)
+ type = QGradient::ConicalGradient;
+ setType(type);
+ m_ui.typeComboBox->setCurrentIndex(idx);
+ m_typeGroup->button(idx)->setChecked(true);
+ m_ui.gradientWidget->setGradientType(type);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotSpreadChanged(int spread)
+{
+ if (spread == 0) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::PadSpread);
+ } else if (spread == 1) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::RepeatSpread);
+ } else if (spread == 2) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::ReflectSpread);
+ }
+ m_ui.spreadComboBox->setCurrentIndex(spread);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotStartLinearXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->startLinear();
+ point.setX(value);
+ m_ui.gradientWidget->setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotStartLinearYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->startLinear();
+ point.setY(value);
+ m_ui.gradientWidget->setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotEndLinearXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->endLinear();
+ point.setX(value);
+ m_ui.gradientWidget->setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotEndLinearYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->endLinear();
+ point.setY(value);
+ m_ui.gradientWidget->setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralRadialXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralRadial();
+ point.setX(value);
+ m_ui.gradientWidget->setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralRadialYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralRadial();
+ point.setY(value);
+ m_ui.gradientWidget->setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotFocalRadialXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->focalRadial();
+ point.setX(value);
+ m_ui.gradientWidget->setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotFocalRadialYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->focalRadial();
+ point.setY(value);
+ m_ui.gradientWidget->setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotRadiusRadialChanged(double value)
+{
+ m_ui.gradientWidget->setRadiusRadial(value);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralConicalXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralConical();
+ point.setX(value);
+ m_ui.gradientWidget->setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralConicalYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralConical();
+ point.setY(value);
+ m_ui.gradientWidget->setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotAngleConicalChanged(double value)
+{
+ m_ui.gradientWidget->setAngleConical(value);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::startLinearChanged(const QPointF &point)
+{
+ setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::endLinearChanged(const QPointF &point)
+{
+ setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::centralRadialChanged(const QPointF &point)
+{
+ setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::focalRadialChanged(const QPointF &point)
+{
+ setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::radiusRadialChanged(qreal radius)
+{
+ setRadiusRadial(radius);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::centralConicalChanged(const QPointF &point)
+{
+ setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::angleConicalChanged(qreal angle)
+{
+ setAngleConical(angle);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::setStartLinear(const QPointF &point)
+{
+ if (startLinearXSpinBox)
+ startLinearXSpinBox->setValue(point.x());
+ if (startLinearYSpinBox)
+ startLinearYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setEndLinear(const QPointF &point)
+{
+ if (endLinearXSpinBox)
+ endLinearXSpinBox->setValue(point.x());
+ if (endLinearYSpinBox)
+ endLinearYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setCentralRadial(const QPointF &point)
+{
+ if (centralRadialXSpinBox)
+ centralRadialXSpinBox->setValue(point.x());
+ if (centralRadialYSpinBox)
+ centralRadialYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setFocalRadial(const QPointF &point)
+{
+ if (focalRadialXSpinBox)
+ focalRadialXSpinBox->setValue(point.x());
+ if (focalRadialYSpinBox)
+ focalRadialYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setRadiusRadial(qreal radius)
+{
+ if (radiusRadialSpinBox)
+ radiusRadialSpinBox->setValue(radius);
+}
+
+void QtGradientEditorPrivate::setCentralConical(const QPointF &point)
+{
+ if (centralConicalXSpinBox)
+ centralConicalXSpinBox->setValue(point.x());
+ if (centralConicalYSpinBox)
+ centralConicalYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setAngleConical(qreal angle)
+{
+ if (angleConicalSpinBox)
+ angleConicalSpinBox->setValue(angle);
+}
+
+QtGradientEditor::QtGradientEditor(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtGradientEditorPrivate())
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_type = QGradient::RadialGradient;
+ d_ptr->m_ui.setupUi(this);
+ d_ptr->m_gridLayout = 0;
+ d_ptr->m_hiddenLayout = 0;
+ d_ptr->m_hiddenWidget = 0;
+ bool detailsDefault = false;
+ d_ptr->m_details = !detailsDefault;
+ d_ptr->m_detailsButtonVisible = true;
+ bool checkeredDefault = true;
+ d_ptr->m_backgroundCheckered = !checkeredDefault;
+ d_ptr->m_gradientStopsController = new QtGradientStopsController(this);
+ d_ptr->m_gradientStopsController->setUi(&d_ptr->m_ui);
+ d_ptr->reset();
+ d_ptr->setType(QGradient::LinearGradient);
+ d_ptr->m_combos = true;
+ d_ptr->setCombos(!d_ptr->m_combos);
+
+ d_ptr->showDetails(detailsDefault);
+ setBackgroundCheckered(checkeredDefault);
+
+ d_ptr->setStartLinear(QPointF(0, 0));
+ d_ptr->setEndLinear(QPointF(1, 1));
+ d_ptr->setCentralRadial(QPointF(0.5, 0.5));
+ d_ptr->setFocalRadial(QPointF(0.5, 0.5));
+ d_ptr->setRadiusRadial(0.5);
+ d_ptr->setCentralConical(QPointF(0.5, 0.5));
+ d_ptr->setAngleConical(0);
+
+ QIcon icon;
+ icon.addPixmap(style()->standardPixmap(QStyle::SP_ArrowRight), QIcon::Normal, QIcon::Off);
+ icon.addPixmap(style()->standardPixmap(QStyle::SP_ArrowLeft), QIcon::Normal, QIcon::On);
+ d_ptr->m_ui.detailsButton->setIcon(icon);
+
+ connect(d_ptr->m_ui.detailsButton, SIGNAL(clicked(bool)), this, SLOT(slotDetailsChanged(bool)));
+ connect(d_ptr->m_gradientStopsController, SIGNAL(gradientStopsChanged(QGradientStops)),
+ this, SLOT(slotGradientStopsChanged(QGradientStops)));
+
+ QIcon iconLinear(QLatin1String(":/trolltech/qtgradienteditor/images/typelinear.png"));
+ QIcon iconRadial(QLatin1String(":/trolltech/qtgradienteditor/images/typeradial.png"));
+ QIcon iconConical(QLatin1String(":/trolltech/qtgradienteditor/images/typeconical.png"));
+
+ d_ptr->m_ui.typeComboBox->addItem(iconLinear, tr("Linear"));
+ d_ptr->m_ui.typeComboBox->addItem(iconRadial, tr("Radial"));
+ d_ptr->m_ui.typeComboBox->addItem(iconConical, tr("Conical"));
+
+ d_ptr->m_ui.linearButton->setIcon(iconLinear);
+ d_ptr->m_ui.radialButton->setIcon(iconRadial);
+ d_ptr->m_ui.conicalButton->setIcon(iconConical);
+
+ d_ptr->m_typeGroup = new QButtonGroup(this);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.linearButton, 0);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.radialButton, 1);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.conicalButton, 2);
+
+ connect(d_ptr->m_typeGroup, SIGNAL(buttonClicked(int)),
+ this, SLOT(slotTypeChanged(int)));
+ connect(d_ptr->m_ui.typeComboBox, SIGNAL(activated(int)),
+ this, SLOT(slotTypeChanged(int)));
+
+ QIcon iconPad(QLatin1String(":/trolltech/qtgradienteditor/images/spreadpad.png"));
+ QIcon iconRepeat(QLatin1String(":/trolltech/qtgradienteditor/images/spreadrepeat.png"));
+ QIcon iconReflect(QLatin1String(":/trolltech/qtgradienteditor/images/spreadreflect.png"));
+
+ d_ptr->m_ui.spreadComboBox->addItem(iconPad, tr("Pad"));
+ d_ptr->m_ui.spreadComboBox->addItem(iconRepeat, tr("Repeat"));
+ d_ptr->m_ui.spreadComboBox->addItem(iconReflect, tr("Reflect"));
+
+ d_ptr->m_ui.padButton->setIcon(iconPad);
+ d_ptr->m_ui.repeatButton->setIcon(iconRepeat);
+ d_ptr->m_ui.reflectButton->setIcon(iconReflect);
+
+ d_ptr->m_spreadGroup = new QButtonGroup(this);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.padButton, 0);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.repeatButton, 1);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.reflectButton, 2);
+ connect(d_ptr->m_spreadGroup, SIGNAL(buttonClicked(int)),
+ this, SLOT(slotSpreadChanged(int)));
+ connect(d_ptr->m_ui.spreadComboBox, SIGNAL(activated(int)),
+ this, SLOT(slotSpreadChanged(int)));
+
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(startLinearChanged(QPointF)),
+ this, SLOT(startLinearChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(endLinearChanged(QPointF)),
+ this, SLOT(endLinearChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralRadialChanged(QPointF)),
+ this, SLOT(centralRadialChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(focalRadialChanged(QPointF)),
+ this, SLOT(focalRadialChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(radiusRadialChanged(qreal)),
+ this, SLOT(radiusRadialChanged(qreal)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralConicalChanged(QPointF)),
+ this, SLOT(centralConicalChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(angleConicalChanged(qreal)),
+ this, SLOT(angleConicalChanged(qreal)));
+
+ QGradientStops stops = gradient().stops();
+ d_ptr->m_gradientStopsController->setGradientStops(stops);
+ d_ptr->m_ui.gradientWidget->setGradientStops(stops);
+}
+
+QtGradientEditor::~QtGradientEditor()
+{
+ if (d_ptr->m_hiddenWidget)
+ delete d_ptr->m_hiddenWidget;
+}
+
+void QtGradientEditor::setGradient(const QGradient &grad)
+{
+ if (grad == gradient())
+ return;
+
+ QGradient::Type type = grad.type();
+ int idx = 0;
+ switch (type) {
+ case QGradient::LinearGradient: idx = 0; break;
+ case QGradient::RadialGradient: idx = 1; break;
+ case QGradient::ConicalGradient: idx = 2; break;
+ default: return;
+ }
+ d_ptr->setType(type);
+ d_ptr->m_ui.typeComboBox->setCurrentIndex(idx);
+ d_ptr->m_ui.gradientWidget->setGradientType(type);
+ d_ptr->m_typeGroup->button(idx)->setChecked(true);
+
+ QGradient::Spread spread = grad.spread();
+ switch (spread) {
+ case QGradient::PadSpread: idx = 0; break;
+ case QGradient::RepeatSpread: idx = 1; break;
+ case QGradient::ReflectSpread: idx = 2; break;
+ default: idx = 0; break;
+ }
+ d_ptr->m_ui.spreadComboBox->setCurrentIndex(idx);
+ d_ptr->m_ui.gradientWidget->setGradientSpread(spread);
+ d_ptr->m_spreadGroup->button(idx)->setChecked(true);
+
+ if (type == QGradient::LinearGradient) {
+ QLinearGradient *gr = (QLinearGradient *)(&grad);
+ d_ptr->setStartLinear(gr->start());
+ d_ptr->setEndLinear(gr->finalStop());
+ d_ptr->m_ui.gradientWidget->setStartLinear(gr->start());
+ d_ptr->m_ui.gradientWidget->setEndLinear(gr->finalStop());
+ } else if (type == QGradient::RadialGradient) {
+ QRadialGradient *gr = (QRadialGradient *)(&grad);
+ d_ptr->setCentralRadial(gr->center());
+ d_ptr->setFocalRadial(gr->focalPoint());
+ d_ptr->setRadiusRadial(gr->radius());
+ d_ptr->m_ui.gradientWidget->setCentralRadial(gr->center());
+ d_ptr->m_ui.gradientWidget->setFocalRadial(gr->focalPoint());
+ d_ptr->m_ui.gradientWidget->setRadiusRadial(gr->radius());
+ } else if (type == QGradient::ConicalGradient) {
+ QConicalGradient *gr = (QConicalGradient *)(&grad);
+ d_ptr->setCentralConical(gr->center());
+ d_ptr->setAngleConical(gr->angle());
+ d_ptr->m_ui.gradientWidget->setCentralConical(gr->center());
+ d_ptr->m_ui.gradientWidget->setAngleConical(gr->angle());
+ }
+
+ d_ptr->m_gradientStopsController->setGradientStops(grad.stops());
+ d_ptr->m_ui.gradientWidget->setGradientStops(grad.stops());
+ d_ptr->updateGradient(false);
+}
+
+QGradient QtGradientEditor::gradient() const
+{
+ return d_ptr->m_gradient;
+}
+
+bool QtGradientEditor::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientEditor::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+
+ d_ptr->m_backgroundCheckered = checkered;
+ d_ptr->m_ui.hueColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.saturationColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.valueColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.alphaColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.gradientWidget->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.gradientStopsWidget->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.colorButton->setBackgroundCheckered(checkered);
+}
+
+bool QtGradientEditor::detailsVisible() const
+{
+ return d_ptr->m_details;
+}
+
+void QtGradientEditor::setDetailsVisible(bool visible)
+{
+ d_ptr->showDetails(visible);
+}
+
+bool QtGradientEditor::isDetailsButtonVisible() const
+{
+ return d_ptr->m_detailsButtonVisible;
+}
+
+void QtGradientEditor::setDetailsButtonVisible(bool visible)
+{
+ if (d_ptr->m_detailsButtonVisible == visible)
+ return;
+
+ d_ptr->m_detailsButtonVisible = visible;
+ d_ptr->m_ui.detailsButton->setVisible(visible);
+}
+
+QColor::Spec QtGradientEditor::spec() const
+{
+ return d_ptr->m_gradientStopsController->spec();
+}
+
+void QtGradientEditor::setSpec(QColor::Spec spec)
+{
+ d_ptr->m_gradientStopsController->setSpec(spec);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradienteditor.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.h b/src/shared/qtgradienteditor/qtgradienteditor.h
new file mode 100644
index 000000000..77e1d3470
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTEDITOR_H
+#define QTGRADIENTEDITOR_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientEditor : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QGradient gradient READ gradient WRITE setGradient)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(bool detailsVisible READ detailsVisible WRITE setDetailsVisible)
+ Q_PROPERTY(bool detailsButtonVisible READ isDetailsButtonVisible WRITE setDetailsButtonVisible)
+public:
+ QtGradientEditor(QWidget *parent = 0);
+ ~QtGradientEditor();
+
+ void setGradient(const QGradient &gradient);
+ QGradient gradient() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ bool detailsVisible() const;
+ void setDetailsVisible(bool visible);
+
+ bool isDetailsButtonVisible() const;
+ void setDetailsButtonVisible(bool visible);
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+signals:
+
+ void gradientChanged(const QGradient &gradient);
+ void aboutToShowDetails(bool details, int extenstionWidthHint);
+
+private:
+ QScopedPointer<class QtGradientEditorPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientEditor)
+ Q_DISABLE_COPY(QtGradientEditor)
+ Q_PRIVATE_SLOT(d_func(), void slotGradientStopsChanged(const QGradientStops &stops))
+ Q_PRIVATE_SLOT(d_func(), void slotTypeChanged(int type))
+ Q_PRIVATE_SLOT(d_func(), void slotSpreadChanged(int type))
+ Q_PRIVATE_SLOT(d_func(), void slotStartLinearXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotStartLinearYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotEndLinearXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotEndLinearYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralRadialXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralRadialYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotFocalRadialXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotFocalRadialYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotRadiusRadialChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralConicalXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralConicalYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotAngleConicalChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotDetailsChanged(bool details))
+ Q_PRIVATE_SLOT(d_func(), void startLinearChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void endLinearChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void centralRadialChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void focalRadialChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void radiusRadialChanged(qreal))
+ Q_PRIVATE_SLOT(d_func(), void centralConicalChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void angleConicalChanged(qreal))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.pri b/src/shared/qtgradienteditor/qtgradienteditor.pri
new file mode 100644
index 000000000..4cf059e1f
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.pri
@@ -0,0 +1,33 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+FORMS += $$PWD/qtgradienteditor.ui \
+ $$PWD/qtgradientdialog.ui \
+ $$PWD/qtgradientview.ui \
+ $$PWD/qtgradientviewdialog.ui
+SOURCES += $$PWD/qtgradientstopsmodel.cpp \
+ $$PWD/qtgradientstopswidget.cpp \
+ $$PWD/qtgradientstopscontroller.cpp \
+ $$PWD/qtgradientwidget.cpp \
+ $$PWD/qtgradienteditor.cpp \
+ $$PWD/qtgradientdialog.cpp \
+ $$PWD/qtcolorbutton.cpp \
+ $$PWD/qtcolorline.cpp \
+ $$PWD/qtgradientview.cpp \
+ $$PWD/qtgradientviewdialog.cpp \
+ $$PWD/qtgradientmanager.cpp \
+ $$PWD/qtgradientutils.cpp
+HEADERS += $$PWD/qtgradientstopsmodel.h \
+ $$PWD/qtgradientstopswidget.h \
+ $$PWD/qtgradientstopscontroller.h \
+ $$PWD/qtgradientwidget.h \
+ $$PWD/qtgradienteditor.h \
+ $$PWD/qtgradientdialog.h \
+ $$PWD/qtcolorbutton.h \
+ $$PWD/qtcolorline.h \
+ $$PWD/qtgradientview.h \
+ $$PWD/qtgradientviewdialog.h \
+ $$PWD/qtgradientmanager.h \
+ $$PWD/qtgradientutils.h
+RESOURCES += $$PWD/qtgradienteditor.qrc
+
+QT += xml
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.qrc b/src/shared/qtgradienteditor/qtgradienteditor.qrc
new file mode 100644
index 000000000..cce7ba622
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.qrc
@@ -0,0 +1,18 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/trolltech/qtgradienteditor">
+ <file>images/edit.png</file>
+ <file>images/zoomin.png</file>
+ <file>images/zoomout.png</file>
+ <file>images/up.png</file>
+ <file>images/down.png</file>
+ <file>images/plus.png</file>
+ <file>images/minus.png</file>
+ <file>images/editdelete.png</file>
+ <file>images/spreadpad.png</file>
+ <file>images/spreadrepeat.png</file>
+ <file>images/spreadreflect.png</file>
+ <file>images/typelinear.png</file>
+ <file>images/typeradial.png</file>
+ <file>images/typeconical.png</file>
+ </qresource>
+</RCC>
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.ui b/src/shared/qtgradienteditor/qtgradienteditor.ui
new file mode 100644
index 000000000..5a842ffe4
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.ui
@@ -0,0 +1,1377 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientEditor</class>
+ <widget class="QWidget" name="QtGradientEditor" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>364</width>
+ <height>518</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <widget class="QFrame" name="frame" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>69</y>
+ <width>193</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtGradientWidget" native="1" name="gradientWidget" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Gradient Editor</string>
+ </property>
+ <property name="whatsThis" >
+ <string>This area shows a preview of the gradient being edited. It also allows you to edit parameters specific to the gradient's type such as start and final point, radius, etc. by drag &amp; drop.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="label1" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>69</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox1" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>69</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label2" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>99</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>2</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox2" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>99</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label3" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>129</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>3</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox3" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>129</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label4" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>159</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>4</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox4" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>159</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label5" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>189</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>5</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox5" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>189</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QtGradientStopsWidget" native="1" name="gradientStopsWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>225</y>
+ <width>193</width>
+ <height>67</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Gradient Stops Editor</string>
+ </property>
+ <property name="whatsThis" >
+ <string>This area allows you to edit gradient stops. Double click on the existing stop handle to duplicate it. Double click outside of the existing stop handles to create a new stop. Drag &amp; drop the handle to reposition it. Use right mouse button to popup context menu with extra actions.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="zoomLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>231</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Zoom</string>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="zoomAllButton" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>260</y>
+ <width>72</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Reset Zoom</string>
+ </property>
+ <property name="text" >
+ <string>Reset Zoom</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="positionLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>304</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Position</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="hLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>335</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Hue</string>
+ </property>
+ <property name="text" >
+ <string>H</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_2" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>333</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="hueColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Hue</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="hueLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>335</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Hue</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="sLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>364</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Saturation</string>
+ </property>
+ <property name="text" >
+ <string>S</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_5" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>362</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="saturationColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Saturation</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="saturationLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>364</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Sat</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="vLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>393</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Value</string>
+ </property>
+ <property name="text" >
+ <string>V</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_3" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>391</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="valueColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Value</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="valueLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>393</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Val</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="aLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>422</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Alpha</string>
+ </property>
+ <property name="text" >
+ <string>A</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_4" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>420</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="alphaColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Alpha</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="alphaLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>422</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Alpha</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" name="typeComboBox" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>40</y>
+ <width>79</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Type</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" name="spreadComboBox" >
+ <property name="geometry" >
+ <rect>
+ <x>96</x>
+ <y>40</y>
+ <width>72</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Spread</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="colorLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>298</y>
+ <width>32</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Color</string>
+ </property>
+ </widget>
+ <widget class="QtColorButton" name="colorButton" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>300</y>
+ <width>26</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Current stop's color</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="hsvRadioButton" >
+ <property name="geometry" >
+ <rect>
+ <x>80</x>
+ <y>301</y>
+ <width>49</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Show HSV specification</string>
+ </property>
+ <property name="text" >
+ <string>HSV</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="rgbRadioButton" >
+ <property name="geometry" >
+ <rect>
+ <x>135</x>
+ <y>301</y>
+ <width>49</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Show RGB specification</string>
+ </property>
+ <property name="text" >
+ <string>RGB</string>
+ </property>
+ </widget>
+ <widget class="QWidget" native="1" name="positionWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>304</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QDoubleSpinBox" name="positionSpinBox" >
+ <property name="toolTip" >
+ <string>Current stop's position</string>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="minimum" >
+ <double>0.000000000000000</double>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value" >
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="hueWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>333</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="hueSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>359</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="saturationWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>362</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="saturationSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="valueWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>391</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="valueSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="alphaWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>420</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="alphaSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="zoomWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>231</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="zoomSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="suffix" >
+ <string>%</string>
+ </property>
+ <property name="minimum" >
+ <number>100</number>
+ </property>
+ <property name="maximum" >
+ <number>10000</number>
+ </property>
+ <property name="singleStep" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="line1Widget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>219</y>
+ <width>143</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Line" name="line1" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="line2Widget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>292</y>
+ <width>143</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Line" name="line2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="zoomButtonsWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>260</y>
+ <width>64</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="zoomInButton" >
+ <property name="toolTip" >
+ <string>Zoom In</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="zoomOutButton" >
+ <property name="toolTip" >
+ <string>Zoom Out</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QToolButton" name="detailsButton" >
+ <property name="geometry" >
+ <rect>
+ <x>176</x>
+ <y>40</y>
+ <width>25</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Ignored" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Toggle details extension</string>
+ </property>
+ <property name="text" >
+ <string>></string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="linearButton" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Linear Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="radialButton" >
+ <property name="geometry" >
+ <rect>
+ <x>40</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Radial Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="conicalButton" >
+ <property name="geometry" >
+ <rect>
+ <x>70</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Conical Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="padButton" >
+ <property name="geometry" >
+ <rect>
+ <x>110</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Pad Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="repeatButton" >
+ <property name="geometry" >
+ <rect>
+ <x>140</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Repeat Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="reflectButton" >
+ <property name="geometry" >
+ <rect>
+ <x>170</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Reflect Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtColorButton</class>
+ <extends>QToolButton</extends>
+ <header>qtcolorbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QtColorLine</class>
+ <extends>QWidget</extends>
+ <header>qtcolorline.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>QtGradientStopsWidget</class>
+ <extends>QWidget</extends>
+ <header>qtgradientstopswidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>QtGradientWidget</class>
+ <extends>QWidget</extends>
+ <header>qtgradientwidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>typeComboBox</tabstop>
+ <tabstop>spreadComboBox</tabstop>
+ <tabstop>detailsButton</tabstop>
+ <tabstop>spinBox1</tabstop>
+ <tabstop>spinBox2</tabstop>
+ <tabstop>spinBox3</tabstop>
+ <tabstop>spinBox4</tabstop>
+ <tabstop>spinBox5</tabstop>
+ <tabstop>zoomSpinBox</tabstop>
+ <tabstop>zoomInButton</tabstop>
+ <tabstop>zoomOutButton</tabstop>
+ <tabstop>zoomAllButton</tabstop>
+ <tabstop>colorButton</tabstop>
+ <tabstop>hsvRadioButton</tabstop>
+ <tabstop>rgbRadioButton</tabstop>
+ <tabstop>positionSpinBox</tabstop>
+ <tabstop>hueSpinBox</tabstop>
+ <tabstop>saturationSpinBox</tabstop>
+ <tabstop>valueSpinBox</tabstop>
+ <tabstop>alphaSpinBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientmanager.cpp b/src/shared/qtgradienteditor/qtgradientmanager.cpp
new file mode 100644
index 000000000..afa26c042
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientmanager.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientmanager.h"
+#include <QtGui/QPixmap>
+#include <QtCore/QMetaEnum>
+
+QT_BEGIN_NAMESPACE
+
+QtGradientManager::QtGradientManager(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QMap<QString, QGradient> QtGradientManager::gradients() const
+{
+ return m_idToGradient;
+}
+
+QString QtGradientManager::uniqueId(const QString &id) const
+{
+ if (!m_idToGradient.contains(id))
+ return id;
+
+ QString base = id;
+ while (base.count() > 0 && base.at(base.count() - 1).isDigit())
+ base = base.left(base.count() - 1);
+ QString newId = base;
+ int counter = 0;
+ while (m_idToGradient.contains(newId)) {
+ ++counter;
+ newId = base + QString::number(counter);
+ }
+ return newId;
+}
+
+QString QtGradientManager::addGradient(const QString &id, const QGradient &gradient)
+{
+ QString newId = uniqueId(id);
+
+ m_idToGradient[newId] = gradient;
+
+ emit gradientAdded(newId, gradient);
+
+ return newId;
+}
+
+void QtGradientManager::removeGradient(const QString &id)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ emit gradientRemoved(id);
+
+ m_idToGradient.remove(id);
+}
+
+void QtGradientManager::renameGradient(const QString &id, const QString &newId)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ if (newId == id)
+ return;
+
+ QString changedId = uniqueId(newId);
+ QGradient gradient = m_idToGradient.value(id);
+
+ emit gradientRenamed(id, changedId);
+
+ m_idToGradient.remove(id);
+ m_idToGradient[changedId] = gradient;
+}
+
+void QtGradientManager::changeGradient(const QString &id, const QGradient &newGradient)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ if (m_idToGradient.value(id) == newGradient)
+ return;
+
+ emit gradientChanged(id, newGradient);
+
+ m_idToGradient[id] = newGradient;
+}
+
+void QtGradientManager::clear()
+{
+ QMap<QString, QGradient> grads = gradients();
+ QMapIterator<QString, QGradient> itGrad(grads);
+ while (itGrad.hasNext()) {
+ removeGradient(itGrad.next().key());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientmanager.h b/src/shared/qtgradienteditor/qtgradientmanager.h
new file mode 100644
index 000000000..c0ad6c2b9
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientmanager.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTMANAGER_H
+#define GRADIENTMANAGER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtCore/QSize>
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomElement>
+#include <QtGui/QGradient>
+
+QT_BEGIN_NAMESPACE
+
+class QGradient;
+class QPixmap;
+class QColor;
+
+class QtGradientManager : public QObject
+{
+ Q_OBJECT
+public:
+ QtGradientManager(QObject *parent = 0);
+
+ QMap<QString, QGradient> gradients() const;
+
+ QString uniqueId(const QString &id) const;
+
+public slots:
+
+ QString addGradient(const QString &id, const QGradient &gradient);
+ void renameGradient(const QString &id, const QString &newId);
+ void changeGradient(const QString &id, const QGradient &newGradient);
+ void removeGradient(const QString &id);
+
+ //utils
+ void clear();
+
+signals:
+
+ void gradientAdded(const QString &id, const QGradient &gradient);
+ void gradientRenamed(const QString &id, const QString &newId);
+ void gradientChanged(const QString &id, const QGradient &newGradient);
+ void gradientRemoved(const QString &id);
+
+private:
+
+ QMap<QString, QGradient> m_idToGradient;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp b/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
new file mode 100644
index 000000000..0e65e015c
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
@@ -0,0 +1,724 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopscontroller.h"
+#include "ui_qtgradienteditor.h"
+#include "qtgradientstopsmodel.h"
+
+#include <QtCore/QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsControllerPrivate
+{
+ QtGradientStopsController *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsController)
+public:
+ typedef QMap<qreal, QColor> PositionColorMap;
+ typedef QMap<qreal, QtGradientStop *> PositionStopMap;
+
+ void slotHsvClicked();
+ void slotRgbClicked();
+
+ void slotCurrentStopChanged(QtGradientStop *stop);
+ void slotStopMoved(QtGradientStop *stop, qreal newPos);
+ void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void slotStopChanged(QtGradientStop *stop, const QColor &newColor);
+ void slotStopSelected(QtGradientStop *stop, bool selected);
+ void slotStopAdded(QtGradientStop *stop);
+ void slotStopRemoved(QtGradientStop *stop);
+ void slotUpdatePositionSpinBox();
+
+ void slotChangeColor(const QColor &color);
+ void slotChangeHue(const QColor &color);
+ void slotChangeSaturation(const QColor &color);
+ void slotChangeValue(const QColor &color);
+ void slotChangeAlpha(const QColor &color);
+ void slotChangeHue(int color);
+ void slotChangeSaturation(int color);
+ void slotChangeValue(int color);
+ void slotChangeAlpha(int color);
+ void slotChangePosition(double value);
+
+ void slotChangeZoom(int value);
+ void slotZoomIn();
+ void slotZoomOut();
+ void slotZoomAll();
+ void slotZoomChanged(double zoom);
+
+ void enableCurrent(bool enable);
+ void setColorSpinBoxes(const QColor &color);
+ PositionColorMap stopsData(const PositionStopMap &stops) const;
+ QGradientStops makeGradientStops(const PositionColorMap &data) const;
+ void updateZoom(double zoom);
+
+ QtGradientStopsModel *m_model;
+ QColor::Spec m_spec;
+
+ Ui::QtGradientEditor *m_ui;
+};
+
+void QtGradientStopsControllerPrivate::enableCurrent(bool enable)
+{
+ m_ui->positionLabel->setEnabled(enable);
+ m_ui->colorLabel->setEnabled(enable);
+ m_ui->hLabel->setEnabled(enable);
+ m_ui->sLabel->setEnabled(enable);
+ m_ui->vLabel->setEnabled(enable);
+ m_ui->aLabel->setEnabled(enable);
+ m_ui->hueLabel->setEnabled(enable);
+ m_ui->saturationLabel->setEnabled(enable);
+ m_ui->valueLabel->setEnabled(enable);
+ m_ui->alphaLabel->setEnabled(enable);
+
+ m_ui->positionSpinBox->setEnabled(enable);
+ m_ui->colorButton->setEnabled(enable);
+
+ m_ui->hueColorLine->setEnabled(enable);
+ m_ui->saturationColorLine->setEnabled(enable);
+ m_ui->valueColorLine->setEnabled(enable);
+ m_ui->alphaColorLine->setEnabled(enable);
+
+ m_ui->hueSpinBox->setEnabled(enable);
+ m_ui->saturationSpinBox->setEnabled(enable);
+ m_ui->valueSpinBox->setEnabled(enable);
+ m_ui->alphaSpinBox->setEnabled(enable);
+}
+
+QtGradientStopsControllerPrivate::PositionColorMap QtGradientStopsControllerPrivate::stopsData(const PositionStopMap &stops) const
+{
+ PositionColorMap data;
+ PositionStopMap::ConstIterator itStop = stops.constBegin();
+ while (itStop != stops.constEnd()) {
+ QtGradientStop *stop = itStop.value();
+ data[stop->position()] = stop->color();
+
+ ++itStop;
+ }
+ return data;
+}
+
+QGradientStops QtGradientStopsControllerPrivate::makeGradientStops(const PositionColorMap &data) const
+{
+ QGradientStops stops;
+ PositionColorMap::ConstIterator itData = data.constBegin();
+ while (itData != data.constEnd()) {
+ stops << QPair<qreal, QColor>(itData.key(), itData.value());
+
+ ++itData;
+ }
+ return stops;
+}
+
+void QtGradientStopsControllerPrivate::updateZoom(double zoom)
+{
+ m_ui->gradientStopsWidget->setZoom(zoom);
+ m_ui->zoomSpinBox->blockSignals(true);
+ m_ui->zoomSpinBox->setValue(qRound(zoom * 100));
+ m_ui->zoomSpinBox->blockSignals(false);
+ bool zoomInEnabled = true;
+ bool zoomOutEnabled = true;
+ bool zoomAllEnabled = true;
+ if (zoom <= 1) {
+ zoomAllEnabled = false;
+ zoomOutEnabled = false;
+ } else if (zoom >= 100) {
+ zoomInEnabled = false;
+ }
+ m_ui->zoomInButton->setEnabled(zoomInEnabled);
+ m_ui->zoomOutButton->setEnabled(zoomOutEnabled);
+ m_ui->zoomAllButton->setEnabled(zoomAllEnabled);
+}
+
+void QtGradientStopsControllerPrivate::slotHsvClicked()
+{
+ QString h = QApplication::translate("qdesigner_internal::QtGradientStopsController", "H", 0, QApplication::UnicodeUTF8);
+ QString s = QApplication::translate("qdesigner_internal::QtGradientStopsController", "S", 0, QApplication::UnicodeUTF8);
+ QString v = QApplication::translate("qdesigner_internal::QtGradientStopsController", "V", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setText(h);
+ m_ui->sLabel->setText(s);
+ m_ui->vLabel->setText(v);
+
+ h = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Hue", 0, QApplication::UnicodeUTF8);
+ s = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Sat", 0, QApplication::UnicodeUTF8);
+ v = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Val", 0, QApplication::UnicodeUTF8);
+
+ const QString hue = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Hue", 0, QApplication::UnicodeUTF8);
+ const QString saturation = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Saturation", 0, QApplication::UnicodeUTF8);
+ const QString value = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Value", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setToolTip(hue);
+ m_ui->hueLabel->setText(h);
+ m_ui->hueColorLine->setToolTip(hue);
+ m_ui->hueColorLine->setColorComponent(QtColorLine::Hue);
+
+ m_ui->sLabel->setToolTip(saturation);
+ m_ui->saturationLabel->setText(s);
+ m_ui->saturationColorLine->setToolTip(saturation);
+ m_ui->saturationColorLine->setColorComponent(QtColorLine::Saturation);
+
+ m_ui->vLabel->setToolTip(value);
+ m_ui->valueLabel->setText(v);
+ m_ui->valueColorLine->setToolTip(value);
+ m_ui->valueColorLine->setColorComponent(QtColorLine::Value);
+
+ setColorSpinBoxes(m_ui->colorButton->color());
+}
+
+void QtGradientStopsControllerPrivate::slotRgbClicked()
+{
+ QString r = QApplication::translate("qdesigner_internal::QtGradientStopsController", "R", 0, QApplication::UnicodeUTF8);
+ QString g = QApplication::translate("qdesigner_internal::QtGradientStopsController", "G", 0, QApplication::UnicodeUTF8);
+ QString b = QApplication::translate("qdesigner_internal::QtGradientStopsController", "B", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setText(r);
+ m_ui->sLabel->setText(g);
+ m_ui->vLabel->setText(b);
+
+ QString red = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Red", 0, QApplication::UnicodeUTF8);
+ QString green = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Green", 0, QApplication::UnicodeUTF8);
+ QString blue = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Blue", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setToolTip(red);
+ m_ui->hueLabel->setText(red);
+ m_ui->hueColorLine->setToolTip(red);
+ m_ui->hueColorLine->setColorComponent(QtColorLine::Red);
+
+ m_ui->sLabel->setToolTip(green);
+ m_ui->saturationLabel->setText(green);
+ m_ui->saturationColorLine->setToolTip(green);
+ m_ui->saturationColorLine->setColorComponent(QtColorLine::Green);
+
+ m_ui->vLabel->setToolTip(blue);
+ m_ui->valueLabel->setText(blue);
+ m_ui->valueColorLine->setToolTip(blue);
+ m_ui->valueColorLine->setColorComponent(QtColorLine::Blue);
+
+ setColorSpinBoxes(m_ui->colorButton->color());
+}
+
+void QtGradientStopsControllerPrivate::setColorSpinBoxes(const QColor &color)
+{
+ m_ui->hueSpinBox->blockSignals(true);
+ m_ui->saturationSpinBox->blockSignals(true);
+ m_ui->valueSpinBox->blockSignals(true);
+ m_ui->alphaSpinBox->blockSignals(true);
+ if (m_ui->hsvRadioButton->isChecked()) {
+ if (m_ui->hueSpinBox->maximum() != 359)
+ m_ui->hueSpinBox->setMaximum(359);
+ if (m_ui->hueSpinBox->value() != color.hue())
+ m_ui->hueSpinBox->setValue(color.hue());
+ if (m_ui->saturationSpinBox->value() != color.saturation())
+ m_ui->saturationSpinBox->setValue(color.saturation());
+ if (m_ui->valueSpinBox->value() != color.value())
+ m_ui->valueSpinBox->setValue(color.value());
+ } else {
+ if (m_ui->hueSpinBox->maximum() != 255)
+ m_ui->hueSpinBox->setMaximum(255);
+ if (m_ui->hueSpinBox->value() != color.red())
+ m_ui->hueSpinBox->setValue(color.red());
+ if (m_ui->saturationSpinBox->value() != color.green())
+ m_ui->saturationSpinBox->setValue(color.green());
+ if (m_ui->valueSpinBox->value() != color.blue())
+ m_ui->valueSpinBox->setValue(color.blue());
+ }
+ m_ui->alphaSpinBox->setValue(color.alpha());
+ m_ui->hueSpinBox->blockSignals(false);
+ m_ui->saturationSpinBox->blockSignals(false);
+ m_ui->valueSpinBox->blockSignals(false);
+ m_ui->alphaSpinBox->blockSignals(false);
+}
+
+void QtGradientStopsControllerPrivate::slotCurrentStopChanged(QtGradientStop *stop)
+{
+ if (!stop) {
+ enableCurrent(false);
+ return;
+ }
+ enableCurrent(true);
+
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ m_ui->colorButton->setColor(stop->color());
+ m_ui->hueColorLine->setColor(stop->color());
+ m_ui->saturationColorLine->setColor(stop->color());
+ m_ui->valueColorLine->setColor(stop->color());
+ m_ui->alphaColorLine->setColor(stop->color());
+ setColorSpinBoxes(stop->color());
+}
+
+void QtGradientStopsControllerPrivate::slotStopMoved(QtGradientStop *stop, qreal newPos)
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops.remove(stop->position());
+ stops[newPos] = stop->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ const qreal pos1 = stop1->position();
+ const qreal pos2 = stop2->position();
+ stops[pos1] = stop2->color();
+ stops[pos2] = stop1->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopAdded(QtGradientStop *stop)
+{
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops[stop->position()] = stop->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopRemoved(QtGradientStop *stop)
+{
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops.remove(stop->position());
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopChanged(QtGradientStop *stop, const QColor &newColor)
+{
+ if (m_model->currentStop() == stop) {
+ m_ui->colorButton->setColor(newColor);
+ m_ui->hueColorLine->setColor(newColor);
+ m_ui->saturationColorLine->setColor(newColor);
+ m_ui->valueColorLine->setColor(newColor);
+ m_ui->alphaColorLine->setColor(newColor);
+ setColorSpinBoxes(newColor);
+ }
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops[stop->position()] = newColor;
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopSelected(QtGradientStop *stop, bool selected)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(selected)
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+}
+
+void QtGradientStopsControllerPrivate::slotUpdatePositionSpinBox()
+{
+ QtGradientStop *current = m_model->currentStop();
+ if (!current)
+ return;
+
+ qreal min = 0.0;
+ qreal max = 1.0;
+ const qreal pos = current->position();
+
+ QtGradientStop *first = m_model->firstSelected();
+ QtGradientStop *last = m_model->lastSelected();
+
+ if (first && last) {
+ const qreal minPos = pos - first->position() - 0.0004999;
+ const qreal maxPos = pos + 1.0 - last->position() + 0.0004999;
+
+ if (max > maxPos)
+ max = maxPos;
+ if (min < minPos)
+ min = minPos;
+
+ if (first->position() == 0.0)
+ min = pos;
+ if (last->position() == 1.0)
+ max = pos;
+ }
+
+ const int spinMin = qRound(m_ui->positionSpinBox->minimum() * 1000);
+ const int spinMax = qRound(m_ui->positionSpinBox->maximum() * 1000);
+
+ const int newMin = qRound(min * 1000);
+ const int newMax = qRound(max * 1000);
+
+ m_ui->positionSpinBox->blockSignals(true);
+ if (spinMin != newMin || spinMax != newMax) {
+ m_ui->positionSpinBox->setRange((double)newMin / 1000, (double)newMax / 1000);
+ }
+ if (m_ui->positionSpinBox->value() != pos)
+ m_ui->positionSpinBox->setValue(pos);
+ m_ui->positionSpinBox->blockSignals(false);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeColor(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop)
+ m_model->changeStop(s, color);
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeHue(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(color.hueF(), c.saturationF(), c.valueF(), c.alphaF());
+ else
+ c.setRgbF(color.redF(), c.greenF(), c.blueF(), c.alphaF());
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeHue(int color)
+{
+ QColor c = m_ui->hueColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF((qreal)color / 360.0, c.saturationF(), c.valueF(), c.alphaF());
+ else
+ c.setRed(color);
+ slotChangeHue(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeSaturation(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), color.saturationF(), c.valueF(), c.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), color.greenF(), c.blueF(), c.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeSaturation(int color)
+{
+ QColor c = m_ui->saturationColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), (qreal)color / 255, c.valueF(), c.alphaF());
+ else
+ c.setGreen(color);
+ slotChangeSaturation(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeValue(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), c.saturationF(), color.valueF(), c.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), c.greenF(), color.blueF(), c.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeValue(int color)
+{
+ QColor c = m_ui->valueColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), c.saturationF(), (qreal)color / 255, c.alphaF());
+ else
+ c.setBlue(color);
+ slotChangeValue(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeAlpha(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), c.saturationF(), c.valueF(), color.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), c.greenF(), c.blueF(), color.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeAlpha(int color)
+{
+ QColor c = m_ui->alphaColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), c.saturationF(), c.valueF(), (qreal)color / 255);
+ else
+ c.setAlpha(color);
+ slotChangeAlpha(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangePosition(double value)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+
+ m_model->moveStops(value);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeZoom(int value)
+{
+ updateZoom(value / 100.0);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomIn()
+{
+ double newZoom = m_ui->gradientStopsWidget->zoom() * 2;
+ if (newZoom > 100)
+ newZoom = 100;
+ updateZoom(newZoom);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomOut()
+{
+ double newZoom = m_ui->gradientStopsWidget->zoom() / 2;
+ if (newZoom < 1)
+ newZoom = 1;
+ updateZoom(newZoom);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomAll()
+{
+ updateZoom(1);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomChanged(double zoom)
+{
+ updateZoom(zoom);
+}
+
+QtGradientStopsController::QtGradientStopsController(QObject *parent)
+ : QObject(parent), d_ptr(new QtGradientStopsControllerPrivate())
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_spec = QColor::Hsv;
+}
+
+void QtGradientStopsController::setUi(Ui::QtGradientEditor *ui)
+{
+ d_ptr->m_ui = ui;
+
+ d_ptr->m_ui->hueColorLine->setColorComponent(QtColorLine::Hue);
+ d_ptr->m_ui->saturationColorLine->setColorComponent(QtColorLine::Saturation);
+ d_ptr->m_ui->valueColorLine->setColorComponent(QtColorLine::Value);
+ d_ptr->m_ui->alphaColorLine->setColorComponent(QtColorLine::Alpha);
+
+ d_ptr->m_model = new QtGradientStopsModel(this);
+ d_ptr->m_ui->gradientStopsWidget->setGradientStopsModel(d_ptr->m_model);
+ connect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ connect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ connect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ connect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+
+ connect(d_ptr->m_ui->hueColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeHue(QColor)));
+ connect(d_ptr->m_ui->saturationColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeSaturation(QColor)));
+ connect(d_ptr->m_ui->valueColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeValue(QColor)));
+ connect(d_ptr->m_ui->alphaColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeAlpha(QColor)));
+ connect(d_ptr->m_ui->colorButton, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeColor(QColor)));
+
+ connect(d_ptr->m_ui->hueSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeHue(int)));
+ connect(d_ptr->m_ui->saturationSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeSaturation(int)));
+ connect(d_ptr->m_ui->valueSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeValue(int)));
+ connect(d_ptr->m_ui->alphaSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeAlpha(int)));
+
+ connect(d_ptr->m_ui->positionSpinBox, SIGNAL(valueChanged(double)),
+ this, SLOT(slotChangePosition(double)));
+
+ connect(d_ptr->m_ui->zoomSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeZoom(int)));
+ connect(d_ptr->m_ui->zoomInButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomIn()));
+ connect(d_ptr->m_ui->zoomOutButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomOut()));
+ connect(d_ptr->m_ui->zoomAllButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomAll()));
+ connect(d_ptr->m_ui->gradientStopsWidget, SIGNAL(zoomChanged(double)),
+ this, SLOT(slotZoomChanged(double)));
+
+ connect(d_ptr->m_ui->hsvRadioButton, SIGNAL(clicked()),
+ this, SLOT(slotHsvClicked()));
+ connect(d_ptr->m_ui->rgbRadioButton, SIGNAL(clicked()),
+ this, SLOT(slotRgbClicked()));
+
+ d_ptr->enableCurrent(false);
+ d_ptr->m_ui->zoomInButton->setIcon(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/zoomin.png")));
+ d_ptr->m_ui->zoomOutButton->setIcon(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/zoomout.png")));
+ d_ptr->updateZoom(1);
+}
+
+QtGradientStopsController::~QtGradientStopsController()
+{
+}
+
+void QtGradientStopsController::setGradientStops(const QGradientStops &stops)
+{
+ d_ptr->m_model->clear();
+ QVectorIterator<QPair<qreal, QColor> > it(stops);
+ QtGradientStop *first = 0;
+ while (it.hasNext()) {
+ QPair<qreal, QColor> pair = it.next();
+ QtGradientStop *stop = d_ptr->m_model->addStop(pair.first, pair.second);
+ if (!first)
+ first = stop;
+ }
+ if (first)
+ d_ptr->m_model->setCurrentStop(first);
+}
+
+QGradientStops QtGradientStopsController::gradientStops() const
+{
+ QGradientStops stops;
+ QList<QtGradientStop *> stopsList = d_ptr->m_model->stops().values();
+ QListIterator<QtGradientStop *> itStop(stopsList);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+ stops << QPair<qreal, QColor>(stop->position(), stop->color());
+ }
+ return stops;
+}
+
+QColor::Spec QtGradientStopsController::spec() const
+{
+ return d_ptr->m_spec;
+}
+
+void QtGradientStopsController::setSpec(QColor::Spec spec)
+{
+ if (d_ptr->m_spec == spec)
+ return;
+
+ d_ptr->m_spec = spec;
+ if (d_ptr->m_spec == QColor::Rgb) {
+ d_ptr->m_ui->rgbRadioButton->setChecked(true);
+ d_ptr->slotRgbClicked();
+ } else {
+ d_ptr->m_ui->hsvRadioButton->setChecked(true);
+ d_ptr->slotHsvClicked();
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientstopscontroller.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientstopscontroller.h b/src/shared/qtgradienteditor/qtgradientstopscontroller.h
new file mode 100644
index 000000000..1ae96aafe
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopscontroller.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSCONTROLLER_H
+#define QTGRADIENTSTOPSCONTROLLER_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class QtGradientEditor;
+}
+
+class QtGradientStopsController : public QObject
+{
+ Q_OBJECT
+public:
+ QtGradientStopsController(QObject *parent = 0);
+ ~QtGradientStopsController();
+
+ void setUi(Ui::QtGradientEditor *editor);
+
+ void setGradientStops(const QGradientStops &stops);
+ QGradientStops gradientStops() const;
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+signals:
+
+ void gradientStopsChanged(const QGradientStops &stops);
+
+private:
+ QScopedPointer<class QtGradientStopsControllerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsController)
+ Q_DISABLE_COPY(QtGradientStopsController)
+ Q_PRIVATE_SLOT(d_func(), void slotHsvClicked())
+ Q_PRIVATE_SLOT(d_func(), void slotRgbClicked())
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentStopChanged(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopMoved(QtGradientStop *stop, qreal newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2))
+ Q_PRIVATE_SLOT(d_func(), void slotStopChanged(QtGradientStop *stop, const QColor &newColor))
+ Q_PRIVATE_SLOT(d_func(), void slotStopSelected(QtGradientStop *stop, bool selected))
+ Q_PRIVATE_SLOT(d_func(), void slotStopAdded(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopRemoved(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotUpdatePositionSpinBox())
+ Q_PRIVATE_SLOT(d_func(), void slotChangeColor(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeHue(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeSaturation(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeValue(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeAlpha(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeHue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeSaturation(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeAlpha(int))
+ //Q_PRIVATE_SLOT(d_func(), void slotChangePosition(double newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotChangePosition(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeZoom(int value))
+ Q_PRIVATE_SLOT(d_func(), void slotZoomIn())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomOut())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomAll())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomChanged(double))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp b/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
new file mode 100644
index 000000000..427e6eed3
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
@@ -0,0 +1,477 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopsmodel.h"
+#include <QtGui/QColor>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopPrivate
+{
+public:
+ qreal m_position;
+ QColor m_color;
+ QtGradientStopsModel *m_model;
+};
+
+qreal QtGradientStop::position() const
+{
+ return d_ptr->m_position;
+}
+
+QColor QtGradientStop::color() const
+{
+ return d_ptr->m_color;
+}
+
+QtGradientStopsModel *QtGradientStop::gradientModel() const
+{
+ return d_ptr->m_model;
+}
+
+void QtGradientStop::setColor(const QColor &color)
+{
+ d_ptr->m_color = color;
+}
+
+void QtGradientStop::setPosition(qreal position)
+{
+ d_ptr->m_position = position;
+}
+
+QtGradientStop::QtGradientStop(QtGradientStopsModel *model)
+ : d_ptr(new QtGradientStopPrivate())
+{
+ d_ptr->m_position = 0;
+ d_ptr->m_color = Qt::white;
+ d_ptr->m_model = model;
+}
+
+QtGradientStop::~QtGradientStop()
+{
+}
+
+class QtGradientStopsModelPrivate
+{
+ QtGradientStopsModel *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsModel)
+public:
+ QMap<qreal, QtGradientStop *> m_posToStop;
+ QMap<QtGradientStop *, qreal> m_stopToPos;
+ QMap<QtGradientStop *, bool> m_selection;
+ QtGradientStop *m_current;
+};
+
+
+
+QtGradientStopsModel::QtGradientStopsModel(QObject *parent)
+ : QObject(parent), d_ptr(new QtGradientStopsModelPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_current = 0;
+}
+
+QtGradientStopsModel::~QtGradientStopsModel()
+{
+ clear();
+}
+
+QtGradientStopsModel::PositionStopMap QtGradientStopsModel::stops() const
+{
+ return d_ptr->m_posToStop;
+}
+
+QtGradientStop *QtGradientStopsModel::at(qreal pos) const
+{
+ if (d_ptr->m_posToStop.contains(pos))
+ return d_ptr->m_posToStop[pos];
+ return 0;
+}
+
+QColor QtGradientStopsModel::color(qreal pos) const
+{
+ PositionStopMap gradStops = stops();
+ if (gradStops.isEmpty())
+ return QColor::fromRgbF(pos, pos, pos, 1.0);
+ if (gradStops.contains(pos))
+ return gradStops[pos]->color();
+
+ gradStops[pos] = 0;
+ PositionStopMap::ConstIterator itStop = gradStops.constFind(pos);
+ if (itStop == gradStops.constBegin()) {
+ ++itStop;
+ return itStop.value()->color();
+ }
+ if (itStop == --gradStops.constEnd()) {
+ --itStop;
+ return itStop.value()->color();
+ }
+ PositionStopMap::ConstIterator itPrev = itStop;
+ PositionStopMap::ConstIterator itNext = itStop;
+ --itPrev;
+ ++itNext;
+
+ double prevX = itPrev.key();
+ double nextX = itNext.key();
+
+ double coefX = (pos - prevX) / (nextX - prevX);
+ QColor prevCol = itPrev.value()->color();
+ QColor nextCol = itNext.value()->color();
+
+ QColor newColor;
+ newColor.setRgbF((nextCol.redF() - prevCol.redF() ) * coefX + prevCol.redF(),
+ (nextCol.greenF() - prevCol.greenF()) * coefX + prevCol.greenF(),
+ (nextCol.blueF() - prevCol.blueF() ) * coefX + prevCol.blueF(),
+ (nextCol.alphaF() - prevCol.alphaF()) * coefX + prevCol.alphaF());
+ return newColor;
+}
+
+QList<QtGradientStop *> QtGradientStopsModel::selectedStops() const
+{
+ return d_ptr->m_selection.keys();
+}
+
+QtGradientStop *QtGradientStopsModel::currentStop() const
+{
+ return d_ptr->m_current;
+}
+
+bool QtGradientStopsModel::isSelected(QtGradientStop *stop) const
+{
+ if (d_ptr->m_selection.contains(stop))
+ return true;
+ return false;
+}
+
+QtGradientStop *QtGradientStopsModel::addStop(qreal pos, const QColor &color)
+{
+ qreal newPos = pos;
+ if (pos < 0.0)
+ newPos = 0.0;
+ if (pos > 1.0)
+ newPos = 1.0;
+ if (d_ptr->m_posToStop.contains(newPos))
+ return 0;
+ QtGradientStop *stop = new QtGradientStop();
+ stop->setPosition(newPos);
+ stop->setColor(color);
+
+ d_ptr->m_posToStop[newPos] = stop;
+ d_ptr->m_stopToPos[stop] = newPos;
+
+ emit stopAdded(stop);
+
+ return stop;
+}
+
+void QtGradientStopsModel::removeStop(QtGradientStop *stop)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (currentStop() == stop)
+ setCurrentStop(0);
+ selectStop(stop, false);
+
+ emit stopRemoved(stop);
+
+ qreal pos = d_ptr->m_stopToPos[stop];
+ d_ptr->m_stopToPos.remove(stop);
+ d_ptr->m_posToStop.remove(pos);
+ delete stop;
+}
+
+void QtGradientStopsModel::moveStop(QtGradientStop *stop, qreal newPos)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (d_ptr->m_posToStop.contains(newPos))
+ return;
+
+ if (newPos > 1.0)
+ newPos = 1.0;
+ else if (newPos < 0.0)
+ newPos = 0.0;
+
+ emit stopMoved(stop, newPos);
+
+ const qreal oldPos = stop->position();
+ stop->setPosition(newPos);
+ d_ptr->m_stopToPos[stop] = newPos;
+ d_ptr->m_posToStop.remove(oldPos);
+ d_ptr->m_posToStop[newPos] = stop;
+}
+
+void QtGradientStopsModel::swapStops(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ if (stop1 == stop2)
+ return;
+ if (!d_ptr->m_stopToPos.contains(stop1))
+ return;
+ if (!d_ptr->m_stopToPos.contains(stop2))
+ return;
+
+ emit stopsSwapped(stop1, stop2);
+
+ const qreal pos1 = stop1->position();
+ const qreal pos2 = stop2->position();
+ stop1->setPosition(pos2);
+ stop2->setPosition(pos1);
+ d_ptr->m_stopToPos[stop1] = pos2;
+ d_ptr->m_stopToPos[stop2] = pos1;
+ d_ptr->m_posToStop[pos1] = stop2;
+ d_ptr->m_posToStop[pos2] = stop1;
+}
+
+void QtGradientStopsModel::changeStop(QtGradientStop *stop, const QColor &newColor)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (stop->color() == newColor)
+ return;
+
+ emit stopChanged(stop, newColor);
+
+ stop->setColor(newColor);
+}
+
+void QtGradientStopsModel::selectStop(QtGradientStop *stop, bool select)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ bool selected = d_ptr->m_selection.contains(stop);
+ if (select == selected)
+ return;
+
+ emit stopSelected(stop, select);
+
+ if (select)
+ d_ptr->m_selection[stop] = true;
+ else
+ d_ptr->m_selection.remove(stop);
+}
+
+void QtGradientStopsModel::setCurrentStop(QtGradientStop *stop)
+{
+ if (stop && !d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (stop == currentStop())
+ return;
+
+ emit currentStopChanged(stop);
+
+ d_ptr->m_current = stop;
+}
+
+QtGradientStop *QtGradientStopsModel::firstSelected() const
+{
+ PositionStopMap stopList = stops();
+ PositionStopMap::ConstIterator itStop = stopList.constBegin();
+ while (itStop != stopList.constEnd()) {
+ QtGradientStop *stop = itStop.value();
+ if (isSelected(stop))
+ return stop;
+ ++itStop;
+ };
+ return 0;
+}
+
+QtGradientStop *QtGradientStopsModel::lastSelected() const
+{
+ PositionStopMap stopList = stops();
+ PositionStopMap::ConstIterator itStop = stopList.constEnd();
+ while (itStop != stopList.constBegin()) {
+ --itStop;
+
+ QtGradientStop *stop = itStop.value();
+ if (isSelected(stop))
+ return stop;
+ };
+ return 0;
+}
+
+QtGradientStopsModel *QtGradientStopsModel::clone() const
+{
+ QtGradientStopsModel *model = new QtGradientStopsModel();
+
+ QMap<qreal, QtGradientStop *> stopsToClone = stops();
+ QMapIterator<qreal, QtGradientStop *> it(stopsToClone);
+ while (it.hasNext()) {
+ it.next();
+ model->addStop(it.key(), it.value()->color());
+ }
+ // clone selection and current also
+ return model;
+}
+
+void QtGradientStopsModel::moveStops(double newPosition)
+{
+ QtGradientStop *current = currentStop();
+ if (!current)
+ return;
+
+ double newPos = newPosition;
+
+ if (newPos > 1)
+ newPos = 1;
+ else if (newPos < 0)
+ newPos = 0;
+
+ if (newPos == current->position())
+ return;
+
+ double offset = newPos - current->position();
+
+ QtGradientStop *first = firstSelected();
+ QtGradientStop *last = lastSelected();
+
+ if (first && last) { // multiselection
+ double maxOffset = 1.0 - last->position();
+ double minOffset = -first->position();
+
+ if (offset > maxOffset)
+ offset = maxOffset;
+ else if (offset < minOffset)
+ offset = minOffset;
+
+ }
+
+ if (offset == 0)
+ return;
+
+ bool forward = (offset > 0) ? false : true;
+
+ PositionStopMap stopList;
+
+ QList<QtGradientStop *> selected = selectedStops();
+ QListIterator<QtGradientStop *> it(selected);
+ while (it.hasNext()) {
+ QtGradientStop *stop = it.next();
+ stopList[stop->position()] = stop;
+ }
+ stopList[current->position()] = current;
+
+ PositionStopMap::ConstIterator itStop = forward ? stopList.constBegin() : stopList.constEnd();
+ while (itStop != (forward ? stopList.constEnd() : stopList.constBegin())) {
+ if (!forward)
+ --itStop;
+ QtGradientStop *stop = itStop.value();
+ double pos = stop->position() + offset;
+ if (pos > 1)
+ pos = 1;
+ if (pos < 0)
+ pos = 0;
+
+ if (current == stop)
+ pos = newPos;
+
+ QtGradientStop *oldStop = at(pos);
+ if (oldStop && !stopList.values().contains(oldStop))
+ removeStop(oldStop);
+ moveStop(stop, pos);
+
+ if (forward)
+ ++itStop;
+ }
+}
+
+void QtGradientStopsModel::clear()
+{
+ QList<QtGradientStop *> stopsList = stops().values();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ removeStop(it.next());
+}
+
+void QtGradientStopsModel::clearSelection()
+{
+ QList<QtGradientStop *> stopsList = selectedStops();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ selectStop(it.next(), false);
+}
+
+void QtGradientStopsModel::flipAll()
+{
+ QMap<qreal, QtGradientStop *> stopsMap = stops();
+ QMapIterator<qreal, QtGradientStop *> itStop(stopsMap);
+ itStop.toBack();
+
+ QMap<QtGradientStop *, bool> swappedList;
+
+ while (itStop.hasPrevious()) {
+ itStop.previous();
+
+ QtGradientStop *stop = itStop.value();
+ if (swappedList.contains(stop))
+ continue;
+ const double newPos = 1.0 - itStop.key();
+ if (stopsMap.contains(newPos)) {
+ QtGradientStop *swapped = stopsMap.value(newPos);
+ swappedList[swapped] = true;
+ swapStops(stop, swapped);
+ } else {
+ moveStop(stop, newPos);
+ }
+ }
+}
+
+void QtGradientStopsModel::selectAll()
+{
+ QList<QtGradientStop *> stopsList = stops().values();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ selectStop(it.next(), true);
+}
+
+void QtGradientStopsModel::deleteStops()
+{
+ QList<QtGradientStop *> selected = selectedStops();
+ QListIterator<QtGradientStop *> itSel(selected);
+ while (itSel.hasNext()) {
+ QtGradientStop *stop = itSel.next();
+ removeStop(stop);
+ }
+ QtGradientStop *current = currentStop();
+ if (current)
+ removeStop(current);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientstopsmodel.h b/src/shared/qtgradienteditor/qtgradientstopsmodel.h
new file mode 100644
index 000000000..fac7d5642
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopsmodel.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSMODEL_H
+#define QTGRADIENTSTOPSMODEL_H
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QColor;
+
+class QtGradientStopsModel;
+
+class QtGradientStop
+{
+public:
+ qreal position() const;
+ QColor color() const;
+ QtGradientStopsModel *gradientModel() const;
+
+private:
+ void setColor(const QColor &color);
+ void setPosition(qreal position);
+ friend class QtGradientStopsModel;
+ QtGradientStop(QtGradientStopsModel *model = 0);
+ ~QtGradientStop();
+ QScopedPointer<class QtGradientStopPrivate> d_ptr;
+};
+
+class QtGradientStopsModel : public QObject
+{
+ Q_OBJECT
+public:
+ typedef QMap<qreal, QtGradientStop *> PositionStopMap;
+
+ QtGradientStopsModel(QObject *parent = 0);
+ ~QtGradientStopsModel();
+
+ PositionStopMap stops() const;
+ QtGradientStop *at(qreal pos) const;
+ QColor color(qreal pos) const; // calculated between points
+ QList<QtGradientStop *> selectedStops() const;
+ QtGradientStop *currentStop() const;
+ bool isSelected(QtGradientStop *stop) const;
+ QtGradientStop *firstSelected() const;
+ QtGradientStop *lastSelected() const;
+ QtGradientStopsModel *clone() const;
+
+ QtGradientStop *addStop(qreal pos, const QColor &color);
+ void removeStop(QtGradientStop *stop);
+ void moveStop(QtGradientStop *stop, qreal newPos);
+ void swapStops(QtGradientStop *stop1, QtGradientStop *stop2);
+ void changeStop(QtGradientStop *stop, const QColor &newColor);
+ void selectStop(QtGradientStop *stop, bool select);
+ void setCurrentStop(QtGradientStop *stop);
+
+ void moveStops(double newPosition); // moves current stop to newPos and all selected stops are moved accordingly
+ void clear();
+ void clearSelection();
+ void flipAll();
+ void selectAll();
+ void deleteStops();
+
+signals:
+ void stopAdded(QtGradientStop *stop);
+ void stopRemoved(QtGradientStop *stop);
+ void stopMoved(QtGradientStop *stop, qreal newPos);
+ void stopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void stopChanged(QtGradientStop *stop, const QColor &newColor);
+ void stopSelected(QtGradientStop *stop, bool selected);
+ void currentStopChanged(QtGradientStop *stop);
+
+private:
+ QScopedPointer<class QtGradientStopsModelPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsModel)
+ Q_DISABLE_COPY(QtGradientStopsModel)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopswidget.cpp b/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
new file mode 100644
index 000000000..a4104327b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
@@ -0,0 +1,1154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopswidget.h"
+#include "qtgradientstopsmodel.h"
+
+#include <QtCore/QMap>
+#include <QtGui/QImage>
+#include <QtGui/QPainter>
+#include <QtGui/QScrollBar>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QRubberBand>
+#include <QtGui/QMenu>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsWidgetPrivate
+{
+ QtGradientStopsWidget *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsWidget)
+public:
+ typedef QMap<qreal, QColor> PositionColorMap;
+ typedef QMap<QtGradientStop *, qreal> StopPositionMap;
+
+ void slotStopAdded(QtGradientStop *stop);
+ void slotStopRemoved(QtGradientStop *stop);
+ void slotStopMoved(QtGradientStop *stop, qreal newPos);
+ void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void slotStopChanged(QtGradientStop *stop, const QColor &newColor);
+ void slotStopSelected(QtGradientStop *stop, bool selected);
+ void slotCurrentStopChanged(QtGradientStop *stop);
+ void slotNewStop();
+ void slotDelete();
+ void slotFlipAll();
+ void slotSelectAll();
+ void slotZoomIn();
+ void slotZoomOut();
+ void slotResetZoom();
+
+ double fromViewport(int x) const;
+ double toViewport(double x) const;
+ QtGradientStop *stopAt(const QPoint &viewportPos) const;
+ QList<QtGradientStop *> stopsAt(const QPoint &viewportPos) const;
+ void setupMove(QtGradientStop *stop, int x);
+ void ensureVisible(double x); // x = stop position
+ void ensureVisible(QtGradientStop *stop);
+ QtGradientStop *newStop(const QPoint &viewportPos);
+
+ bool m_backgroundCheckered;
+ QtGradientStopsModel *m_model;
+ double m_handleSize;
+ int m_scaleFactor;
+ double m_zoom;
+
+#ifndef QT_NO_DRAGANDDROP
+ QtGradientStop *m_dragStop;
+ QtGradientStop *m_changedStop;
+ QtGradientStop *m_clonedStop;
+ QtGradientStopsModel *m_dragModel;
+ QColor m_dragColor;
+ void clearDrag();
+ void removeClonedStop();
+ void restoreChangedStop();
+ void changeStop(qreal pos);
+ void cloneStop(qreal pos);
+#endif
+
+ QRubberBand *m_rubber;
+ QPoint m_clickPos;
+
+ QList<QtGradientStop *> m_stops;
+
+ bool m_moving;
+ int m_moveOffset;
+ StopPositionMap m_moveStops;
+
+ PositionColorMap m_moveOriginal;
+};
+
+double QtGradientStopsWidgetPrivate::fromViewport(int x) const
+{
+ QSize size = q_ptr->viewport()->size();
+ int w = size.width();
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int val = q_ptr->horizontalScrollBar()->value();
+ return ((double)x * m_scaleFactor + w * val) / (w * (m_scaleFactor + max));
+}
+
+double QtGradientStopsWidgetPrivate::toViewport(double x) const
+{
+ QSize size = q_ptr->viewport()->size();
+ int w = size.width();
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int val = q_ptr->horizontalScrollBar()->value();
+ return w * (x * (m_scaleFactor + max) - val) / m_scaleFactor;
+}
+
+QtGradientStop *QtGradientStopsWidgetPrivate::stopAt(const QPoint &viewportPos) const
+{
+ double posY = m_handleSize / 2;
+ QListIterator<QtGradientStop *> itStop(m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+
+ double posX = toViewport(stop->position());
+
+ double x = viewportPos.x() - posX;
+ double y = viewportPos.y() - posY;
+
+ if ((m_handleSize * m_handleSize / 4) > (x * x + y * y))
+ return stop;
+ }
+ return 0;
+}
+
+QList<QtGradientStop *> QtGradientStopsWidgetPrivate::stopsAt(const QPoint &viewportPos) const
+{
+ QList<QtGradientStop *> stops;
+ double posY = m_handleSize / 2;
+ QListIterator<QtGradientStop *> itStop(m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+
+ double posX = toViewport(stop->position());
+
+ double x = viewportPos.x() - posX;
+ double y = viewportPos.y() - posY;
+
+ if ((m_handleSize * m_handleSize / 4) > (x * x + y * y))
+ stops.append(stop);
+ }
+ return stops;
+}
+
+void QtGradientStopsWidgetPrivate::setupMove(QtGradientStop *stop, int x)
+{
+ m_model->setCurrentStop(stop);
+
+ int viewportX = qRound(toViewport(stop->position()));
+ m_moveOffset = x - viewportX;
+
+ QList<QtGradientStop *> stops = m_stops;
+ m_stops.clear();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (m_model->isSelected(s) || s == stop) {
+ m_moveStops[s] = s->position() - stop->position();
+ m_stops.append(s);
+ } else {
+ m_moveOriginal[s->position()] = s->color();
+ }
+ }
+ itStop.toFront();
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (!m_model->isSelected(s))
+ m_stops.append(s);
+ }
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+}
+
+void QtGradientStopsWidgetPrivate::ensureVisible(double x)
+{
+ double viewX = toViewport(x);
+ if (viewX < 0 || viewX > q_ptr->viewport()->size().width()) {
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int newVal = qRound(x * (max + m_scaleFactor) - m_scaleFactor / 2);
+ q_ptr->horizontalScrollBar()->setValue(newVal);
+ }
+}
+
+void QtGradientStopsWidgetPrivate::ensureVisible(QtGradientStop *stop)
+{
+ if (!stop)
+ return;
+ ensureVisible(stop->position());
+}
+
+QtGradientStop *QtGradientStopsWidgetPrivate::newStop(const QPoint &viewportPos)
+{
+ QtGradientStop *copyStop = stopAt(viewportPos);
+ double posX = fromViewport(viewportPos.x());
+ QtGradientStop *stop = m_model->at(posX);
+ if (!stop) {
+ QColor newColor;
+ if (copyStop)
+ newColor = copyStop->color();
+ else
+ newColor = m_model->color(posX);
+ if (!newColor.isValid())
+ newColor = Qt::white;
+ stop = m_model->addStop(posX, newColor);
+ }
+ return stop;
+}
+
+void QtGradientStopsWidgetPrivate::slotStopAdded(QtGradientStop *stop)
+{
+ m_stops.append(stop);
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopRemoved(QtGradientStop *stop)
+{
+ m_stops.removeAll(stop);
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopMoved(QtGradientStop *stop, qreal newPos)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(newPos)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ Q_UNUSED(stop1)
+ Q_UNUSED(stop2)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopChanged(QtGradientStop *stop, const QColor &newColor)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(newColor)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopSelected(QtGradientStop *stop, bool selected)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(selected)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotCurrentStopChanged(QtGradientStop *stop)
+{
+ Q_UNUSED(stop)
+
+ if (!m_model)
+ return;
+ q_ptr->viewport()->update();
+ if (stop) {
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+ }
+}
+
+void QtGradientStopsWidgetPrivate::slotNewStop()
+{
+ if (!m_model)
+ return;
+
+ QtGradientStop *stop = newStop(m_clickPos);
+
+ if (!stop)
+ return;
+
+ m_model->clearSelection();
+ m_model->selectStop(stop, true);
+ m_model->setCurrentStop(stop);
+}
+
+void QtGradientStopsWidgetPrivate::slotDelete()
+{
+ if (!m_model)
+ return;
+
+ m_model->deleteStops();
+}
+
+void QtGradientStopsWidgetPrivate::slotFlipAll()
+{
+ if (!m_model)
+ return;
+
+ m_model->flipAll();
+}
+
+void QtGradientStopsWidgetPrivate::slotSelectAll()
+{
+ if (!m_model)
+ return;
+
+ m_model->selectAll();
+}
+
+void QtGradientStopsWidgetPrivate::slotZoomIn()
+{
+ double newZoom = q_ptr->zoom() * 2;
+ if (newZoom > 100)
+ newZoom = 100;
+ if (newZoom == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(newZoom);
+ emit q_ptr->zoomChanged(q_ptr->zoom());
+}
+
+void QtGradientStopsWidgetPrivate::slotZoomOut()
+{
+ double newZoom = q_ptr->zoom() / 2;
+ if (newZoom < 1)
+ newZoom = 1;
+ if (newZoom == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(newZoom);
+ emit q_ptr->zoomChanged(q_ptr->zoom());
+}
+
+void QtGradientStopsWidgetPrivate::slotResetZoom()
+{
+ if (1 == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(1);
+ emit q_ptr->zoomChanged(1);
+}
+
+QtGradientStopsWidget::QtGradientStopsWidget(QWidget *parent)
+ : QAbstractScrollArea(parent), d_ptr(new QtGradientStopsWidgetPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_backgroundCheckered = true;
+ d_ptr->m_model = 0;
+ d_ptr->m_handleSize = 25.0;
+ d_ptr->m_scaleFactor = 1000;
+ d_ptr->m_moving = false;
+ d_ptr->m_zoom = 1;
+ d_ptr->m_rubber = new QRubberBand(QRubberBand::Rectangle, this);
+#ifndef QT_NO_DRAGANDDROP
+ d_ptr->m_dragStop = 0;
+ d_ptr->m_changedStop = 0;
+ d_ptr->m_clonedStop = 0;
+ d_ptr->m_dragModel = 0;
+#endif
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ horizontalScrollBar()->setRange(0, (int)(d_ptr->m_scaleFactor * (d_ptr->m_zoom - 1) + 0.5));
+ horizontalScrollBar()->setPageStep(d_ptr->m_scaleFactor);
+ horizontalScrollBar()->setSingleStep(4);
+ viewport()->setAutoFillBackground(false);
+
+ setAcceptDrops(true);
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
+}
+
+QtGradientStopsWidget::~QtGradientStopsWidget()
+{
+}
+
+QSize QtGradientStopsWidget::sizeHint() const
+{
+ return QSize(qRound(2 * d_ptr->m_handleSize), qRound(3 * d_ptr->m_handleSize) + horizontalScrollBar()->sizeHint().height());
+}
+
+QSize QtGradientStopsWidget::minimumSizeHint() const
+{
+ return QSize(qRound(2 * d_ptr->m_handleSize), qRound(3 * d_ptr->m_handleSize) + horizontalScrollBar()->minimumSizeHint().height());
+}
+
+void QtGradientStopsWidget::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtGradientStopsWidget::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientStopsWidget::setGradientStopsModel(QtGradientStopsModel *model)
+{
+ if (d_ptr->m_model == model)
+ return;
+
+ if (d_ptr->m_model) {
+ disconnect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ disconnect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ disconnect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ disconnect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+
+ d_ptr->m_stops.clear();
+ }
+
+ d_ptr->m_model = model;
+
+ if (d_ptr->m_model) {
+ connect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ connect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ connect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ connect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+
+ QList<QtGradientStop *> stops = d_ptr->m_model->stops().values();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext())
+ d_ptr->slotStopAdded(itStop.next());
+
+ QList<QtGradientStop *> selected = d_ptr->m_model->selectedStops();
+ QListIterator<QtGradientStop *> itSelect(selected);
+ while (itSelect.hasNext())
+ d_ptr->slotStopSelected(itSelect.next(), true);
+
+ d_ptr->slotCurrentStopChanged(d_ptr->m_model->currentStop());
+ }
+}
+
+void QtGradientStopsWidget::mousePressEvent(QMouseEvent *e)
+{
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ d_ptr->m_moving = true;
+
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+ d_ptr->m_clickPos = e->pos();
+ QtGradientStop *stop = d_ptr->stopAt(e->pos());
+ if (stop) {
+ if (e->modifiers() & Qt::ControlModifier) {
+ d_ptr->m_model->selectStop(stop, !d_ptr->m_model->isSelected(stop));
+ } else if (e->modifiers() & Qt::ShiftModifier) {
+ QtGradientStop *oldCurrent = d_ptr->m_model->currentStop();
+ if (oldCurrent) {
+ PositionStopMap stops = d_ptr->m_model->stops();
+ PositionStopMap::ConstIterator itSt = stops.constFind(oldCurrent->position());
+ if (itSt != stops.constEnd()) {
+ while (itSt != stops.constFind(stop->position())) {
+ d_ptr->m_model->selectStop(itSt.value(), true);
+ if (oldCurrent->position() < stop->position())
+ ++itSt;
+ else
+ --itSt;
+ }
+ }
+ }
+ d_ptr->m_model->selectStop(stop, true);
+ } else {
+ if (!d_ptr->m_model->isSelected(stop)) {
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(stop, true);
+ }
+ }
+ d_ptr->setupMove(stop, e->pos().x());
+ } else {
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_rubber->setGeometry(QRect(d_ptr->m_clickPos, QSize()));
+ d_ptr->m_rubber->show();
+ }
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ d_ptr->m_moving = false;
+ d_ptr->m_rubber->hide();
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+}
+
+void QtGradientStopsWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ typedef QtGradientStopsWidgetPrivate::PositionColorMap PositionColorMap;
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ typedef QtGradientStopsWidgetPrivate::StopPositionMap StopPositionMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (!(e->buttons() & Qt::LeftButton))
+ return;
+
+ if (!d_ptr->m_moving)
+ return;
+
+ if (!d_ptr->m_moveStops.isEmpty()) {
+ double maxOffset = 0.0;
+ double minOffset = 0.0;
+ bool first = true;
+ StopPositionMap::ConstIterator itStop = d_ptr->m_moveStops.constBegin();
+ while (itStop != d_ptr->m_moveStops.constEnd()) {
+ double offset = itStop.value();
+
+ if (first) {
+ maxOffset = offset;
+ minOffset = offset;
+ first = false;
+ } else {
+ if (maxOffset < offset)
+ maxOffset = offset;
+ else if (minOffset > offset)
+ minOffset = offset;
+ }
+ ++itStop;
+ }
+
+ double viewportMin = d_ptr->toViewport(-minOffset);
+ double viewportMax = d_ptr->toViewport(1.0 - maxOffset);
+
+ PositionStopMap newPositions;
+
+ int viewportX = e->pos().x() - d_ptr->m_moveOffset;
+
+ if (viewportX > viewport()->size().width())
+ viewportX = viewport()->size().width();
+ else if (viewportX < 0)
+ viewportX = 0;
+
+ double posX = d_ptr->fromViewport(viewportX);
+
+ if (viewportX > viewportMax)
+ posX = 1.0 - maxOffset;
+ else if (viewportX < viewportMin)
+ posX = -minOffset;
+
+ itStop = d_ptr->m_moveStops.constBegin();
+ while (itStop != d_ptr->m_moveStops.constEnd()) {
+ QtGradientStop *stop = itStop.key();
+
+ newPositions[posX + itStop.value()] = stop;
+
+ ++itStop;
+ }
+
+ bool forward = true;
+ PositionStopMap::ConstIterator itNewPos = newPositions.constBegin();
+ if (itNewPos.value()->position() < itNewPos.key())
+ forward = false;
+
+ itNewPos = forward ? newPositions.constBegin() : newPositions.constEnd();
+ while (itNewPos != (forward ? newPositions.constEnd() : newPositions.constBegin())) {
+ if (!forward)
+ --itNewPos;
+ QtGradientStop *stop = itNewPos.value();
+ double newPos = itNewPos.key();
+ if (newPos > 1)
+ newPos = 1;
+ else if (newPos < 0)
+ newPos = 0;
+
+ QtGradientStop *existingStop = d_ptr->m_model->at(newPos);
+ if (existingStop && !d_ptr->m_moveStops.contains(existingStop))
+ d_ptr->m_model->removeStop(existingStop);
+ d_ptr->m_model->moveStop(stop, newPos);
+
+ if (forward)
+ ++itNewPos;
+ }
+
+ PositionColorMap::ConstIterator itOld = d_ptr->m_moveOriginal.constBegin();
+ while (itOld != d_ptr->m_moveOriginal.constEnd()) {
+ double position = itOld.key();
+ if (!d_ptr->m_model->at(position))
+ d_ptr->m_model->addStop(position, itOld.value());
+
+ ++itOld;
+ }
+
+ } else {
+ QRect r(QRect(d_ptr->m_clickPos, e->pos()).normalized());
+ r.translate(1, 0);
+ d_ptr->m_rubber->setGeometry(r);
+ //d_ptr->m_model->clearSelection();
+
+ int xv1 = d_ptr->m_clickPos.x();
+ int xv2 = e->pos().x();
+ if (xv1 > xv2) {
+ int temp = xv1;
+ xv1 = xv2;
+ xv2 = temp;
+ }
+ int yv1 = d_ptr->m_clickPos.y();
+ int yv2 = e->pos().y();
+ if (yv1 > yv2) {
+ int temp = yv1;
+ yv1 = yv2;
+ yv2 = temp;
+ }
+
+ QPoint p1, p2;
+
+ if (yv2 < d_ptr->m_handleSize / 2) {
+ p1 = QPoint(xv1, yv2);
+ p2 = QPoint(xv2, yv2);
+ } else if (yv1 > d_ptr->m_handleSize / 2) {
+ p1 = QPoint(xv1, yv1);
+ p2 = QPoint(xv2, yv1);
+ } else {
+ p1 = QPoint(xv1, qRound(d_ptr->m_handleSize / 2));
+ p2 = QPoint(xv2, qRound(d_ptr->m_handleSize / 2));
+ }
+
+ QList<QtGradientStop *> beginList = d_ptr->stopsAt(p1);
+ QList<QtGradientStop *> endList = d_ptr->stopsAt(p2);
+
+ double x1 = d_ptr->fromViewport(xv1);
+ double x2 = d_ptr->fromViewport(xv2);
+
+ QListIterator<QtGradientStop *> itStop(d_ptr->m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+ if ((stop->position() >= x1 && stop->position() <= x2) ||
+ beginList.contains(stop) || endList.contains(stop))
+ d_ptr->m_model->selectStop(stop, true);
+ else
+ d_ptr->m_model->selectStop(stop, false);
+ }
+ }
+}
+
+void QtGradientStopsWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ if (d_ptr->m_clickPos != e->pos()) {
+ mousePressEvent(e);
+ return;
+ }
+ d_ptr->m_moving = true;
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+
+ QtGradientStop *stop = d_ptr->newStop(e->pos());
+
+ if (!stop)
+ return;
+
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(stop, true);
+
+ d_ptr->setupMove(stop, e->pos().x());
+
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::keyPressEvent(QKeyEvent *e)
+{
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) {
+ d_ptr->m_model->deleteStops();
+ } else if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right ||
+ e->key() == Qt::Key_Home || e->key() == Qt::Key_End) {
+ PositionStopMap stops = d_ptr->m_model->stops();
+ if (stops.isEmpty())
+ return;
+ QtGradientStop *newCurrent = 0;
+ QtGradientStop *current = d_ptr->m_model->currentStop();
+ if (!current || e->key() == Qt::Key_Home || e->key() == Qt::Key_End) {
+ if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Home)
+ newCurrent = stops.constBegin().value();
+ else if (e->key() == Qt::Key_Right || e->key() == Qt::Key_End)
+ newCurrent = (--stops.constEnd()).value();
+ } else {
+ PositionStopMap::ConstIterator itStop = stops.constBegin();
+ while (itStop.value() != current)
+ ++itStop;
+ if (e->key() == Qt::Key_Left && itStop != stops.constBegin())
+ --itStop;
+ else if (e->key() == Qt::Key_Right && itStop != --stops.constEnd())
+ ++itStop;
+ newCurrent = itStop.value();
+ }
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(newCurrent, true);
+ d_ptr->m_model->setCurrentStop(newCurrent);
+ d_ptr->ensureVisible(newCurrent);
+ } else if (e->key() == Qt::Key_A) {
+ if (e->modifiers() & Qt::ControlModifier)
+ d_ptr->m_model->selectAll();
+ }
+}
+
+void QtGradientStopsWidget::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e)
+ if (!d_ptr->m_model)
+ return;
+
+ QtGradientStopsModel *model = d_ptr->m_model;
+#ifndef QT_NO_DRAGANDDROP
+ if (d_ptr->m_dragModel)
+ model = d_ptr->m_dragModel;
+#endif
+
+ QSize size = viewport()->size();
+ int w = size.width();
+ double h = size.height() - d_ptr->m_handleSize;
+ if (w <= 0)
+ return;
+
+ QPixmap pix(size);
+ QPainter p;
+
+ if (d_ptr->m_backgroundCheckered) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+
+ p.begin(&pix);
+ p.setBrushOrigin((size.width() % pixSize + pixSize) / 2, (size.height() % pixSize + pixSize) / 2);
+ p.fillRect(viewport()->rect(), pm);
+ p.setBrushOrigin(0, 0);
+ } else {
+ p.begin(viewport());
+ }
+
+ double viewBegin = (double)w * horizontalScrollBar()->value() / d_ptr->m_scaleFactor;
+
+ int val = horizontalScrollBar()->value();
+ int max = horizontalScrollBar()->maximum();
+
+ double begin = (double)val / (d_ptr->m_scaleFactor + max);
+ double end = (double)(val + d_ptr->m_scaleFactor) / (d_ptr->m_scaleFactor + max);
+ double width = end - begin;
+
+ if (h > 0) {
+ QLinearGradient lg(0, 0, w, 0);
+ QMap<qreal, QtGradientStop *> stops = model->stops();
+ QMapIterator<qreal, QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next().value();
+ double pos = stop->position();
+ if (pos >= begin && pos <= end) {
+ double gradPos = (pos - begin) / width;
+ QColor c = stop->color();
+ lg.setColorAt(gradPos, c);
+ }
+ //lg.setColorAt(stop->position(), stop->color());
+ }
+ lg.setColorAt(0, model->color(begin));
+ lg.setColorAt(1, model->color(end));
+ QImage img(w, 1, QImage::Format_ARGB32_Premultiplied);
+ QPainter p1(&img);
+ p1.setCompositionMode(QPainter::CompositionMode_Source);
+
+ /*
+ if (viewBegin != 0)
+ p1.translate(-viewBegin, 0);
+ if (d_ptr->m_zoom != 1)
+ p1.scale(d_ptr->m_zoom, 1);
+ */
+ p1.fillRect(0, 0, w, 1, lg);
+
+ p.fillRect(QRectF(0, d_ptr->m_handleSize, w, h), QPixmap::fromImage(img));
+ }
+
+
+ double handleWidth = d_ptr->m_handleSize * d_ptr->m_scaleFactor / (w * (d_ptr->m_scaleFactor + max));
+
+ QColor insideColor = QColor::fromRgb(0x20, 0x20, 0x20, 0xFF);
+ QColor borderColor = QColor(Qt::white);
+ QColor drawColor;
+ QColor back1 = QColor(Qt::lightGray);
+ QColor back2 = QColor(Qt::darkGray);
+ QColor back = QColor::fromRgb((back1.red() + back2.red()) / 2,
+ (back1.green() + back2.green()) / 2,
+ (back1.blue() + back2.blue()) / 2);
+
+ QPen pen;
+ p.setRenderHint(QPainter::Antialiasing);
+ QListIterator<QtGradientStop *> itStop(d_ptr->m_stops);
+ itStop.toBack();
+ while (itStop.hasPrevious()) {
+ QtGradientStop *stop = itStop.previous();
+ double x = stop->position();
+ if (x >= begin - handleWidth / 2 && x <= end + handleWidth / 2) {
+ double viewX = x * w * (d_ptr->m_scaleFactor + max) / d_ptr->m_scaleFactor - viewBegin;
+ p.save();
+ QColor c = stop->color();
+#ifndef QT_NO_DRAGANDDROP
+ if (stop == d_ptr->m_dragStop)
+ c = d_ptr->m_dragColor;
+#endif
+ if ((0.3 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF()) * c.alphaF() +
+ (0.3 * back.redF() + 0.59 * back.greenF() + 0.11 * back.blueF()) * (1.0 - c.alphaF()) < 0.5) {
+ drawColor = QColor::fromRgb(0xC0, 0xC0, 0xC0, 0xB0);
+ } else {
+ drawColor = QColor::fromRgb(0x40, 0x40, 0x40, 0x80);
+ }
+ QRectF rect(viewX - d_ptr->m_handleSize / 2, 0, d_ptr->m_handleSize, d_ptr->m_handleSize);
+ rect.adjust(0.5, 0.5, -0.5, -0.5);
+ if (h > 0) {
+ pen.setWidthF(1);
+ QLinearGradient lg(0, d_ptr->m_handleSize, 0, d_ptr->m_handleSize + h / 2);
+ lg.setColorAt(0, drawColor);
+ QColor alphaZero = drawColor;
+ alphaZero.setAlpha(0);
+ lg.setColorAt(1, alphaZero);
+ pen.setBrush(lg);
+ p.setPen(pen);
+ p.drawLine(QPointF(viewX, d_ptr->m_handleSize), QPointF(viewX, d_ptr->m_handleSize + h / 2));
+
+ pen.setWidthF(1);
+ pen.setBrush(drawColor);
+ p.setPen(pen);
+ QRectF r1 = rect.adjusted(0.5, 0.5, -0.5, -0.5);
+ QRectF r2 = rect.adjusted(1.5, 1.5, -1.5, -1.5);
+ QColor inColor = QColor::fromRgb(0x80, 0x80, 0x80, 0x80);
+ if (!d_ptr->m_model->isSelected(stop)) {
+ p.setBrush(c);
+ p.drawEllipse(rect);
+ } else {
+ pen.setBrush(insideColor);
+ pen.setWidthF(2);
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ p.drawEllipse(r1);
+
+ pen.setBrush(inColor);
+ pen.setWidthF(1);
+ p.setPen(pen);
+ p.setBrush(c);
+ p.drawEllipse(r2);
+ }
+
+ if (d_ptr->m_model->currentStop() == stop) {
+ p.setBrush(Qt::NoBrush);
+ pen.setWidthF(5);
+ pen.setBrush(drawColor);
+ int corr = 4;
+ if (!d_ptr->m_model->isSelected(stop)) {
+ corr = 3;
+ pen.setWidthF(7);
+ }
+ p.setPen(pen);
+ p.drawEllipse(rect.adjusted(corr, corr, -corr, -corr));
+ }
+
+ }
+ p.restore();
+ }
+ }
+ if (d_ptr->m_backgroundCheckered) {
+ p.end();
+ p.begin(viewport());
+ p.drawPixmap(0, 0, pix);
+ }
+ p.end();
+}
+
+void QtGradientStopsWidget::focusInEvent(QFocusEvent *e)
+{
+ Q_UNUSED(e)
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::focusOutEvent(QFocusEvent *e)
+{
+ Q_UNUSED(e)
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::contextMenuEvent(QContextMenuEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ d_ptr->m_clickPos = e->pos();
+
+ QMenu menu(this);
+ QAction *newStopAction = new QAction(tr("New Stop"), &menu);
+ QAction *deleteAction = new QAction(tr("Delete"), &menu);
+ QAction *flipAllAction = new QAction(tr("Flip All"), &menu);
+ QAction *selectAllAction = new QAction(tr("Select All"), &menu);
+ QAction *zoomInAction = new QAction(tr("Zoom In"), &menu);
+ QAction *zoomOutAction = new QAction(tr("Zoom Out"), &menu);
+ QAction *zoomAllAction = new QAction(tr("Reset Zoom"), &menu);
+ if (d_ptr->m_model->selectedStops().isEmpty() && !d_ptr->m_model->currentStop())
+ deleteAction->setEnabled(false);
+ if (zoom() <= 1) {
+ zoomOutAction->setEnabled(false);
+ zoomAllAction->setEnabled(false);
+ } else if (zoom() >= 100) {
+ zoomInAction->setEnabled(false);
+ }
+ connect(newStopAction, SIGNAL(triggered()), this, SLOT(slotNewStop()));
+ connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotDelete()));
+ connect(flipAllAction, SIGNAL(triggered()), this, SLOT(slotFlipAll()));
+ connect(selectAllAction, SIGNAL(triggered()), this, SLOT(slotSelectAll()));
+ connect(zoomInAction, SIGNAL(triggered()), this, SLOT(slotZoomIn()));
+ connect(zoomOutAction, SIGNAL(triggered()), this, SLOT(slotZoomOut()));
+ connect(zoomAllAction, SIGNAL(triggered()), this, SLOT(slotResetZoom()));
+ menu.addAction(newStopAction);
+ menu.addAction(deleteAction);
+ menu.addAction(flipAllAction);
+ menu.addAction(selectAllAction);
+ menu.addSeparator();
+ menu.addAction(zoomInAction);
+ menu.addAction(zoomOutAction);
+ menu.addAction(zoomAllAction);
+ menu.exec(e->globalPos());
+}
+
+void QtGradientStopsWidget::wheelEvent(QWheelEvent *e)
+{
+ int numDegrees = e->delta() / 8;
+ int numSteps = numDegrees / 15;
+
+ int shift = numSteps;
+ if (shift < 0)
+ shift = -shift;
+ int pow = 1 << shift;
+ //const double c = 0.7071067; // 2 steps per doubled value
+ const double c = 0.5946036; // 4 steps pre doubled value
+ // in general c = pow(2, 1 / n) / 2; where n is the step
+ double factor = pow * c;
+
+ double newZoom = zoom();
+ if (numSteps < 0)
+ newZoom /= factor;
+ else
+ newZoom *= factor;
+ if (newZoom > 100)
+ newZoom = 100;
+ if (newZoom < 1)
+ newZoom = 1;
+
+ if (newZoom == zoom())
+ return;
+
+ setZoom(newZoom);
+ emit zoomChanged(zoom());
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QtGradientStopsWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ if (!mime->hasColor())
+ return;
+ event->accept();
+ d_ptr->m_dragModel = d_ptr->m_model->clone();
+
+ d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
+ update();
+}
+
+void QtGradientStopsWidget::dragMoveEvent(QDragMoveEvent *event)
+{
+ QRectF rect = viewport()->rect();
+ rect.adjust(0, d_ptr->m_handleSize, 0, 0);
+ double x = d_ptr->fromViewport(event->pos().x());
+ QtGradientStop *dragStop = d_ptr->stopAt(event->pos());
+ if (dragStop) {
+ event->accept();
+ d_ptr->removeClonedStop();
+ d_ptr->changeStop(dragStop->position());
+ } else if (rect.contains(event->pos())) {
+ event->accept();
+ if (d_ptr->m_model->at(x)) {
+ d_ptr->removeClonedStop();
+ d_ptr->changeStop(x);
+ } else {
+ d_ptr->restoreChangedStop();
+ d_ptr->cloneStop(x);
+ }
+ } else {
+ event->ignore();
+ d_ptr->removeClonedStop();
+ d_ptr->restoreChangedStop();
+ }
+
+ update();
+}
+
+void QtGradientStopsWidget::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ event->accept();
+ d_ptr->clearDrag();
+ update();
+}
+
+void QtGradientStopsWidget::dropEvent(QDropEvent *event)
+{
+ event->accept();
+ if (!d_ptr->m_dragModel)
+ return;
+
+ if (d_ptr->m_changedStop)
+ d_ptr->m_model->changeStop(d_ptr->m_model->at(d_ptr->m_changedStop->position()), d_ptr->m_dragColor);
+ else if (d_ptr->m_clonedStop)
+ d_ptr->m_model->addStop(d_ptr->m_clonedStop->position(), d_ptr->m_dragColor);
+
+ d_ptr->clearDrag();
+ update();
+}
+
+void QtGradientStopsWidgetPrivate::clearDrag()
+{
+ removeClonedStop();
+ restoreChangedStop();
+ delete m_dragModel;
+ m_dragModel = 0;
+}
+
+void QtGradientStopsWidgetPrivate::removeClonedStop()
+{
+ if (!m_clonedStop)
+ return;
+ m_dragModel->removeStop(m_clonedStop);
+ m_clonedStop = 0;
+}
+
+void QtGradientStopsWidgetPrivate::restoreChangedStop()
+{
+ if (!m_changedStop)
+ return;
+ m_dragModel->changeStop(m_changedStop, m_model->at(m_changedStop->position())->color());
+ m_changedStop = 0;
+ m_dragStop = 0;
+}
+
+void QtGradientStopsWidgetPrivate::changeStop(qreal pos)
+{
+ QtGradientStop *stop = m_dragModel->at(pos);
+ if (!stop)
+ return;
+
+ m_dragModel->changeStop(stop, m_dragColor);
+ m_changedStop = stop;
+ m_dragStop = m_model->at(stop->position());
+}
+
+void QtGradientStopsWidgetPrivate::cloneStop(qreal pos)
+{
+ if (m_clonedStop) {
+ m_dragModel->moveStop(m_clonedStop, pos);
+ return;
+ }
+ QtGradientStop *stop = m_dragModel->at(pos);
+ if (stop)
+ return;
+
+ m_clonedStop = m_dragModel->addStop(pos, m_dragColor);
+}
+
+#endif
+
+void QtGradientStopsWidget::setZoom(double zoom)
+{
+ double z = zoom;
+ if (z < 1)
+ z = 1;
+ else if (z > 100)
+ z = 100;
+
+ if (d_ptr->m_zoom == z)
+ return;
+
+ d_ptr->m_zoom = z;
+ int oldMax = horizontalScrollBar()->maximum();
+ int oldVal = horizontalScrollBar()->value();
+ horizontalScrollBar()->setRange(0, qRound(d_ptr->m_scaleFactor * (d_ptr->m_zoom - 1)));
+ int newMax = horizontalScrollBar()->maximum();
+ double newVal = (oldVal + (double)d_ptr->m_scaleFactor / 2) * (newMax + d_ptr->m_scaleFactor)
+ / (oldMax + d_ptr->m_scaleFactor) - (double)d_ptr->m_scaleFactor / 2;
+ horizontalScrollBar()->setValue(qRound(newVal));
+ viewport()->update();
+}
+
+double QtGradientStopsWidget::zoom() const
+{
+ return d_ptr->m_zoom;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientstopswidget.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientstopswidget.h b/src/shared/qtgradienteditor/qtgradientstopswidget.h
new file mode 100644
index 000000000..a6893c07b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopswidget.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSWIDGET_H
+#define QTGRADIENTSTOPSWIDGET_H
+
+#include <QtGui/QAbstractScrollArea>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsModel;
+class QtGradientStopsWidgetPrivate;
+
+class QtGradientStopsWidget : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtGradientStopsWidget(QWidget *parent = 0);
+ ~QtGradientStopsWidget();
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ void setGradientStopsModel(QtGradientStopsModel *model);
+
+ void setZoom(double zoom);
+ double zoom() const;
+
+signals:
+
+ void zoomChanged(double zoom);
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void contextMenuEvent(QContextMenuEvent *e);
+ void wheelEvent(QWheelEvent *e);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+#endif
+
+private:
+ QScopedPointer<QtGradientStopsWidgetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsWidget)
+ Q_DISABLE_COPY(QtGradientStopsWidget)
+ Q_PRIVATE_SLOT(d_func(), void slotStopAdded(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopRemoved(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopMoved(QtGradientStop *stop, qreal newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2))
+ Q_PRIVATE_SLOT(d_func(), void slotStopChanged(QtGradientStop *stop, const QColor &newColor))
+ Q_PRIVATE_SLOT(d_func(), void slotStopSelected(QtGradientStop *stop, bool selected))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentStopChanged(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotNewStop())
+ Q_PRIVATE_SLOT(d_func(), void slotDelete())
+ Q_PRIVATE_SLOT(d_func(), void slotFlipAll())
+ Q_PRIVATE_SLOT(d_func(), void slotSelectAll())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomIn())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomOut())
+ Q_PRIVATE_SLOT(d_func(), void slotResetZoom())
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientutils.cpp b/src/shared/qtgradienteditor/qtgradientutils.cpp
new file mode 100644
index 000000000..cfc4c25b8
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientutils.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientutils.h"
+#include "qtgradientmanager.h"
+#include <QtGui/QLinearGradient>
+#include <QtGui/QRadialGradient>
+#include <QtGui/QConicalGradient>
+#include <QtXml/QDomDocument>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static QString gradientTypeToString(QGradient::Type type)
+{
+ if (type == QGradient::LinearGradient)
+ return QLatin1String("LinearGradient");
+ if (type == QGradient::RadialGradient)
+ return QLatin1String("RadialGradient");
+ if (type == QGradient::ConicalGradient)
+ return QLatin1String("ConicalGradient");
+ return QLatin1String("NoGradient");
+}
+
+static QGradient::Type stringToGradientType(const QString &name)
+{
+ if (name == QLatin1String("LinearGradient"))
+ return QGradient::LinearGradient;
+ if (name == QLatin1String("RadialGradient"))
+ return QGradient::RadialGradient;
+ if (name == QLatin1String("ConicalGradient"))
+ return QGradient::ConicalGradient;
+ return QGradient::NoGradient;
+}
+
+static QString gradientSpreadToString(QGradient::Spread spread)
+{
+ if (spread == QGradient::PadSpread)
+ return QLatin1String("PadSpread");
+ if (spread == QGradient::RepeatSpread)
+ return QLatin1String("RepeatSpread");
+ if (spread == QGradient::ReflectSpread)
+ return QLatin1String("ReflectSpread");
+ return QLatin1String("PadSpread");
+}
+
+static QGradient::Spread stringToGradientSpread(const QString &name)
+{
+ if (name == QLatin1String("PadSpread"))
+ return QGradient::PadSpread;
+ if (name == QLatin1String("RepeatSpread"))
+ return QGradient::RepeatSpread;
+ if (name == QLatin1String("ReflectSpread"))
+ return QGradient::ReflectSpread;
+ return QGradient::PadSpread;
+}
+
+static QString gradientCoordinateModeToString(QGradient::CoordinateMode mode)
+{
+ if (mode == QGradient::LogicalMode)
+ return QLatin1String("LogicalMode");
+ if (mode == QGradient::StretchToDeviceMode)
+ return QLatin1String("StretchToDeviceMode");
+ if (mode == QGradient::ObjectBoundingMode)
+ return QLatin1String("ObjectBoundingMode");
+ return QLatin1String("StretchToDeviceMode");
+}
+
+static QGradient::CoordinateMode stringToGradientCoordinateMode(const QString &name)
+{
+ if (name == QLatin1String("LogicalMode"))
+ return QGradient::LogicalMode;
+ if (name == QLatin1String("StretchToDeviceMode"))
+ return QGradient::StretchToDeviceMode;
+ if (name == QLatin1String("ObjectBoundingMode"))
+ return QGradient::ObjectBoundingMode;
+ return QGradient::StretchToDeviceMode;
+}
+
+static QDomElement saveColor(QDomDocument &doc, const QColor &color)
+{
+ QDomElement colorElem = doc.createElement(QLatin1String("colorData"));
+
+ colorElem.setAttribute(QLatin1String("r"), QString::number(color.red()));
+ colorElem.setAttribute(QLatin1String("g"), QString::number(color.green()));
+ colorElem.setAttribute(QLatin1String("b"), QString::number(color.blue()));
+ colorElem.setAttribute(QLatin1String("a"), QString::number(color.alpha()));
+
+ return colorElem;
+}
+
+static QDomElement saveGradientStop(QDomDocument &doc, const QGradientStop &stop)
+{
+ QDomElement stopElem = doc.createElement(QLatin1String("stopData"));
+
+ stopElem.setAttribute(QLatin1String("position"), QString::number(stop.first));
+
+ const QDomElement colorElem = saveColor(doc, stop.second);
+ stopElem.appendChild(colorElem);
+
+ return stopElem;
+}
+
+static QDomElement saveGradient(QDomDocument &doc, const QGradient &gradient)
+{
+ QDomElement gradElem = doc.createElement(QLatin1String("gradientData"));
+
+ const QGradient::Type type = gradient.type();
+ gradElem.setAttribute(QLatin1String("type"), gradientTypeToString(type));
+ gradElem.setAttribute(QLatin1String("spread"), gradientSpreadToString(gradient.spread()));
+ gradElem.setAttribute(QLatin1String("coordinateMode"), gradientCoordinateModeToString(gradient.coordinateMode()));
+
+ QGradientStops stops = gradient.stops();
+ QVectorIterator<QGradientStop > it(stops);
+ while (it.hasNext())
+ gradElem.appendChild(saveGradientStop(doc, it.next()));
+
+ if (type == QGradient::LinearGradient) {
+ const QLinearGradient &g = *static_cast<const QLinearGradient *>(&gradient);
+ gradElem.setAttribute(QLatin1String("startX"), QString::number(g.start().x()));
+ gradElem.setAttribute(QLatin1String("startY"), QString::number(g.start().y()));
+ gradElem.setAttribute(QLatin1String("endX"), QString::number(g.finalStop().x()));
+ gradElem.setAttribute(QLatin1String("endY"), QString::number(g.finalStop().y()));
+ } else if (type == QGradient::RadialGradient) {
+ const QRadialGradient &g = *static_cast<const QRadialGradient *>(&gradient);
+ gradElem.setAttribute(QLatin1String("centerX"), QString::number(g.center().x()));
+ gradElem.setAttribute(QLatin1String("centerY"), QString::number(g.center().y()));
+ gradElem.setAttribute(QLatin1String("focalX"), QString::number(g.focalPoint().x()));
+ gradElem.setAttribute(QLatin1String("focalY"), QString::number(g.focalPoint().y()));
+ gradElem.setAttribute(QLatin1String("radius"), QString::number(g.radius()));
+ } else if (type == QGradient::ConicalGradient) {
+ const QConicalGradient &g = *static_cast<const QConicalGradient*>(&gradient);
+ gradElem.setAttribute(QLatin1String("centerX"), QString::number(g.center().x()));
+ gradElem.setAttribute(QLatin1String("centerY"), QString::number(g.center().y()));
+ gradElem.setAttribute(QLatin1String("angle"), QString::number(g.angle()));
+ }
+
+ return gradElem;
+}
+
+static QColor loadColor(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("colorData"))
+ return QColor();
+
+ return QColor(elem.attribute(QLatin1String("r")).toInt(),
+ elem.attribute(QLatin1String("g")).toInt(),
+ elem.attribute(QLatin1String("b")).toInt(),
+ elem.attribute(QLatin1String("a")).toInt());
+}
+
+static QGradientStop loadGradientStop(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("stopData"))
+ return QGradientStop();
+
+ const qreal pos = static_cast<qreal>(elem.attribute(QLatin1String("position")).toDouble());
+ return qMakePair(pos, loadColor(elem.firstChild().toElement()));
+}
+
+static QGradient loadGradient(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("gradientData"))
+ return QLinearGradient();
+
+ const QGradient::Type type = stringToGradientType(elem.attribute(QLatin1String("type")));
+ const QGradient::Spread spread = stringToGradientSpread(elem.attribute(QLatin1String("spread")));
+ const QGradient::CoordinateMode mode = stringToGradientCoordinateMode(elem.attribute(QLatin1String("coordinateMode")));
+
+ QGradient gradient = QLinearGradient();
+
+ if (type == QGradient::LinearGradient) {
+ QLinearGradient g;
+ g.setStart(elem.attribute(QLatin1String("startX")).toDouble(), elem.attribute(QLatin1String("startY")).toDouble());
+ g.setFinalStop(elem.attribute(QLatin1String("endX")).toDouble(), elem.attribute(QLatin1String("endY")).toDouble());
+ gradient = g;
+ } else if (type == QGradient::RadialGradient) {
+ QRadialGradient g;
+ g.setCenter(elem.attribute(QLatin1String("centerX")).toDouble(), elem.attribute(QLatin1String("centerY")).toDouble());
+ g.setFocalPoint(elem.attribute(QLatin1String("focalX")).toDouble(), elem.attribute(QLatin1String("focalY")).toDouble());
+ g.setRadius(elem.attribute(QLatin1String("radius")).toDouble());
+ gradient = g;
+ } else if (type == QGradient::ConicalGradient) {
+ QConicalGradient g;
+ g.setCenter(elem.attribute(QLatin1String("centerX")).toDouble(), elem.attribute(QLatin1String("centerY")).toDouble());
+ g.setAngle(elem.attribute(QLatin1String("angle")).toDouble());
+ gradient = g;
+ }
+
+ QDomElement stopElem = elem.firstChildElement();
+ while (!stopElem.isNull()) {
+ QGradientStop stop = loadGradientStop(stopElem);
+
+ gradient.setColorAt(stop.first, stop.second);
+
+ stopElem = stopElem.nextSiblingElement();
+ }
+
+ gradient.setSpread(spread);
+ gradient.setCoordinateMode(mode);
+
+ return gradient;
+}
+
+QString QtGradientUtils::saveState(const QtGradientManager *manager)
+{
+ QDomDocument doc;
+
+ QDomElement rootElem = doc.createElement(QLatin1String("gradients"));
+
+ QMap<QString, QGradient> grads = manager->gradients();
+ QMapIterator<QString, QGradient> itGrad(grads);
+ while (itGrad.hasNext()) {
+ itGrad.next();
+ QDomElement idElem = doc.createElement(QLatin1String("gradient"));
+ idElem.setAttribute(QLatin1String("name"), itGrad.key());
+ QDomElement gradElem = saveGradient(doc, itGrad.value());
+ idElem.appendChild(gradElem);
+
+ rootElem.appendChild(idElem);
+ }
+
+ doc.appendChild(rootElem);
+
+ return doc.toString();
+}
+
+void QtGradientUtils::restoreState(QtGradientManager *manager, const QString &state)
+{
+ manager->clear();
+
+ QDomDocument doc;
+ doc.setContent(state);
+
+ QDomElement rootElem = doc.documentElement();
+
+ QDomElement gradElem = rootElem.firstChildElement();
+ while (!gradElem.isNull()) {
+ const QString name = gradElem.attribute(QLatin1String("name"));
+ const QGradient gradient = loadGradient(gradElem.firstChildElement());
+
+ manager->addGradient(name, gradient);
+ gradElem = gradElem.nextSiblingElement();
+ }
+}
+
+QPixmap QtGradientUtils::gradientPixmap(const QGradient &gradient, const QSize &size, bool checkeredBackground)
+{
+ QImage image(size, QImage::Format_ARGB32);
+ QPainter p(&image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+
+ if (checkeredBackground) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
+
+ p.setBrushOrigin((size.width() % pixSize + pixSize) / 2, (size.height() % pixSize + pixSize) / 2);
+ p.fillRect(0, 0, size.width(), size.height(), pm);
+ p.setBrushOrigin(0, 0);
+ p.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ }
+
+ const qreal scaleFactor = 0.999999;
+ p.scale(scaleFactor, scaleFactor);
+ QGradient grad = gradient;
+ grad.setCoordinateMode(QGradient::StretchToDeviceMode);
+ p.fillRect(QRect(0, 0, size.width(), size.height()), grad);
+ p.drawRect(QRect(0, 0, size.width() - 1, size.height() - 1));
+
+ return QPixmap::fromImage(image);
+}
+
+static QString styleSheetFillName(const QGradient &gradient)
+{
+ QString result;
+
+ switch (gradient.type()) {
+ case QGradient::LinearGradient:
+ result += QLatin1String("qlineargradient");
+ break;
+ case QGradient::RadialGradient:
+ result += QLatin1String("qradialgradient");
+ break;
+ case QGradient::ConicalGradient:
+ result += QLatin1String("qconicalgradient");
+ break;
+ default:
+ qWarning() << "QtGradientUtils::styleSheetFillName(): gradient type" << gradient.type() << "not supported!";
+ break;
+ }
+
+ return result;
+}
+
+static QStringList styleSheetParameters(const QGradient &gradient)
+{
+ QStringList result;
+
+ if (gradient.type() != QGradient::ConicalGradient) {
+ QString spread;
+ switch (gradient.spread()) {
+ case QGradient::PadSpread:
+ spread = QLatin1String("pad");
+ break;
+ case QGradient::ReflectSpread:
+ spread = QLatin1String("reflect");
+ break;
+ case QGradient::RepeatSpread:
+ spread = QLatin1String("repeat");
+ break;
+ default:
+ qWarning() << "QtGradientUtils::styleSheetParameters(): gradient spread" << gradient.spread() << "not supported!";
+ break;
+ }
+ result << QLatin1String("spread:") + spread;
+ }
+
+ switch (gradient.type()) {
+ case QGradient::LinearGradient: {
+ const QLinearGradient *linearGradient = static_cast<const QLinearGradient*>(&gradient);
+ result << QLatin1String("x1:") + QString::number(linearGradient->start().x())
+ << QLatin1String("y1:") + QString::number(linearGradient->start().y())
+ << QLatin1String("x2:") + QString::number(linearGradient->finalStop().x())
+ << QLatin1String("y2:") + QString::number(linearGradient->finalStop().y());
+ break;
+ }
+ case QGradient::RadialGradient: {
+ const QRadialGradient *radialGradient = static_cast<const QRadialGradient*>(&gradient);
+ result << QLatin1String("cx:") + QString::number(radialGradient->center().x())
+ << QLatin1String("cy:") + QString::number(radialGradient->center().y())
+ << QLatin1String("radius:") + QString::number(radialGradient->radius())
+ << QLatin1String("fx:") + QString::number(radialGradient->focalPoint().x())
+ << QLatin1String("fy:") + QString::number(radialGradient->focalPoint().y());
+ break;
+ }
+ case QGradient::ConicalGradient: {
+ const QConicalGradient *conicalGradient = static_cast<const QConicalGradient*>(&gradient);
+ result << QLatin1String("cx:") + QString::number(conicalGradient->center().x())
+ << QLatin1String("cy:") + QString::number(conicalGradient->center().y())
+ << QLatin1String("angle:") + QString::number(conicalGradient->angle());
+ break;
+ }
+ default:
+ qWarning() << "QtGradientUtils::styleSheetParameters(): gradient type" << gradient.type() << "not supported!";
+ break;
+ }
+
+ return result;
+}
+
+static QStringList styleSheetStops(const QGradient &gradient)
+{
+ QStringList result;
+ foreach (const QGradientStop &stop, gradient.stops()) {
+ const QColor color = stop.second;
+
+ const QString stopDescription = QLatin1String("stop:") + QString::number(stop.first) + QLatin1String(" rgba(")
+ + QString::number(color.red()) + QLatin1String(", ")
+ + QString::number(color.green()) + QLatin1String(", ")
+ + QString::number(color.blue()) + QLatin1String(", ")
+ + QString::number(color.alpha()) + QLatin1Char(')');
+ result << stopDescription;
+ }
+
+ return result;
+}
+
+QString QtGradientUtils::styleSheetCode(const QGradient &gradient)
+{
+ QStringList gradientParameters;
+ gradientParameters << styleSheetParameters(gradient) << styleSheetStops(gradient);
+
+ return styleSheetFillName(gradient) + QLatin1Char('(') + gradientParameters.join(QLatin1String(", ")) + QLatin1Char(')');
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientutils.h b/src/shared/qtgradienteditor/qtgradientutils.h
new file mode 100644
index 000000000..6c0d75e60
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientutils.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTUTILS_H
+#define GRADIENTUTILS_H
+
+#include <QtGui/QGradient>
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+
+class QtGradientUtils
+{
+public:
+ static QString styleSheetCode(const QGradient &gradient);
+ // utils methods, they could be outside of this class
+ static QString saveState(const QtGradientManager *manager);
+ static void restoreState(QtGradientManager *manager, const QString &state);
+
+ static QPixmap gradientPixmap(const QGradient &gradient, const QSize &size = QSize(64, 64), bool checkeredBackground = false);
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientview.cpp b/src/shared/qtgradienteditor/qtgradientview.cpp
new file mode 100644
index 000000000..a3d17950d
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientview.h"
+#include "qtgradientmanager.h"
+#include "qtgradientdialog.h"
+#include "qtgradientutils.h"
+#include <QtGui/QPainter>
+#include <QtGui/QMessageBox>
+#include <QtGui/QClipboard>
+
+QT_BEGIN_NAMESPACE
+
+void QtGradientView::slotGradientAdded(const QString &id, const QGradient &gradient)
+{
+ QListWidgetItem *item = new QListWidgetItem(QtGradientUtils::gradientPixmap(gradient), id, m_ui.listWidget);
+ item->setToolTip(id);
+ item->setSizeHint(QSize(72, 84));
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+
+ m_idToItem[id] = item;
+ m_itemToId[item] = id;
+}
+
+void QtGradientView::slotGradientRenamed(const QString &id, const QString &newId)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ item->setText(newId);
+ item->setToolTip(newId);
+ m_itemToId[item] = newId;
+ m_idToItem.remove(id);
+ m_idToItem[newId] = item;
+}
+
+void QtGradientView::slotGradientChanged(const QString &id, const QGradient &newGradient)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ item->setIcon(QtGradientUtils::gradientPixmap(newGradient));
+}
+
+void QtGradientView::slotGradientRemoved(const QString &id)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ delete item;
+ m_itemToId.remove(item);
+ m_idToItem.remove(id);
+}
+
+void QtGradientView::slotNewGradient()
+{
+ bool ok;
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ QGradient grad = QLinearGradient();
+ if (item)
+ grad = m_manager->gradients().value(m_itemToId.value(item));
+ QGradient gradient = QtGradientDialog::getGradient(&ok, grad, this);
+ if (!ok)
+ return;
+
+ QString id = m_manager->addGradient(tr("Grad"), gradient);
+ m_ui.listWidget->setCurrentItem(m_idToItem.value(id));
+}
+
+void QtGradientView::slotEditGradient()
+{
+ bool ok;
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ QGradient grad = m_manager->gradients().value(id);
+ QGradient gradient = QtGradientDialog::getGradient(&ok, grad, this);
+ if (!ok)
+ return;
+
+ m_manager->changeGradient(id, gradient);
+}
+
+void QtGradientView::slotRemoveGradient()
+{
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ if (QMessageBox::question(this, tr("Remove Gradient"),
+ tr("Are you sure you want to remove the selected gradient?"),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Yes)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ m_manager->removeGradient(id);
+}
+
+void QtGradientView::slotRenameGradient()
+{
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ m_ui.listWidget->editItem(item);
+}
+
+void QtGradientView::slotRenameGradient(QListWidgetItem *item)
+{
+ if (!item)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ m_manager->renameGradient(id, item->text());
+}
+
+void QtGradientView::slotCurrentItemChanged(QListWidgetItem *item)
+{
+ m_editAction->setEnabled(item);
+ m_renameAction->setEnabled(item);
+ m_removeAction->setEnabled(item);
+ emit currentGradientChanged(m_itemToId.value(item));
+}
+
+void QtGradientView::slotGradientActivated(QListWidgetItem *item)
+{
+ const QString id = m_itemToId.value(item);
+ if (!id.isEmpty())
+ emit gradientActivated(id);
+}
+
+QtGradientView::QtGradientView(QWidget *parent)
+ : QWidget(parent)
+{
+ m_manager = 0;
+
+ m_ui.setupUi(this);
+
+ m_ui.listWidget->setViewMode(QListView::IconMode);
+ m_ui.listWidget->setMovement(QListView::Static);
+ m_ui.listWidget->setTextElideMode(Qt::ElideRight);
+ m_ui.listWidget->setResizeMode(QListWidget::Adjust);
+ m_ui.listWidget->setIconSize(QSize(64, 64));
+ m_ui.listWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ QPalette pal = m_ui.listWidget->viewport()->palette();
+ int pixSize = 18;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QColor c1 = palette().color(QPalette::Midlight);
+ QColor c2 = palette().color(QPalette::Dark);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, c1);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, c1);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, c2);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, c2);
+
+ pal.setBrush(QPalette::Base, QBrush(pm));
+ m_ui.listWidget->viewport()->setPalette(pal);
+
+ connect(m_ui.listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotGradientActivated(QListWidgetItem*)));
+ connect(m_ui.listWidget, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(slotRenameGradient(QListWidgetItem*)));
+ connect(m_ui.listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(slotCurrentItemChanged(QListWidgetItem*)));
+
+ m_newAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/plus.png")), tr("New..."), this);
+ m_editAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/edit.png")), tr("Edit..."), this);
+ m_renameAction = new QAction(tr("Rename"), this);
+ m_removeAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/minus.png")), tr("Remove"), this);
+
+ connect(m_newAction, SIGNAL(triggered()), this, SLOT(slotNewGradient()));
+ connect(m_editAction, SIGNAL(triggered()), this, SLOT(slotEditGradient()));
+ connect(m_removeAction, SIGNAL(triggered()), this, SLOT(slotRemoveGradient()));
+ connect(m_renameAction, SIGNAL(triggered()), this, SLOT(slotRenameGradient()));
+
+ m_ui.listWidget->addAction(m_newAction);
+ m_ui.listWidget->addAction(m_editAction);
+ m_ui.listWidget->addAction(m_renameAction);
+ m_ui.listWidget->addAction(m_removeAction);
+
+ m_ui.newButton->setDefaultAction(m_newAction);
+ m_ui.editButton->setDefaultAction(m_editAction);
+ m_ui.renameButton->setDefaultAction(m_renameAction);
+ m_ui.removeButton->setDefaultAction(m_removeAction);
+
+ m_ui.listWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
+}
+
+void QtGradientView::setGradientManager(QtGradientManager *manager)
+{
+ if (m_manager == manager)
+ return;
+
+ if (m_manager) {
+ disconnect(m_manager, SIGNAL(gradientAdded(QString,QGradient)),
+ this, SLOT(slotGradientAdded(QString,QGradient)));
+ disconnect(m_manager, SIGNAL(gradientRenamed(QString,QString)),
+ this, SLOT(slotGradientRenamed(QString,QString)));
+ disconnect(m_manager, SIGNAL(gradientChanged(QString,QGradient)),
+ this, SLOT(slotGradientChanged(QString,QGradient)));
+ disconnect(m_manager, SIGNAL(gradientRemoved(QString)),
+ this, SLOT(slotGradientRemoved(QString)));
+
+ m_ui.listWidget->clear();
+ m_idToItem.clear();
+ m_itemToId.clear();
+ }
+
+ m_manager = manager;
+
+ if (!m_manager)
+ return;
+
+ QMap<QString, QGradient> gradients = m_manager->gradients();
+ QMapIterator<QString, QGradient> itGrad(gradients);
+ while (itGrad.hasNext()) {
+ itGrad.next();
+ slotGradientAdded(itGrad.key(), itGrad.value());
+ }
+
+ connect(m_manager, SIGNAL(gradientAdded(QString,QGradient)),
+ this, SLOT(slotGradientAdded(QString,QGradient)));
+ connect(m_manager, SIGNAL(gradientRenamed(QString,QString)),
+ this, SLOT(slotGradientRenamed(QString,QString)));
+ connect(m_manager, SIGNAL(gradientChanged(QString,QGradient)),
+ this, SLOT(slotGradientChanged(QString,QGradient)));
+ connect(m_manager, SIGNAL(gradientRemoved(QString)),
+ this, SLOT(slotGradientRemoved(QString)));
+}
+
+QtGradientManager *QtGradientView::gradientManager() const
+{
+ return m_manager;
+}
+
+void QtGradientView::setCurrentGradient(const QString &id)
+{
+ QListWidgetItem *item = m_idToItem.value(id);
+ if (!item)
+ return;
+
+ m_ui.listWidget->setCurrentItem(item);
+}
+
+QString QtGradientView::currentGradient() const
+{
+ return m_itemToId.value(m_ui.listWidget->currentItem());
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientview.h b/src/shared/qtgradienteditor/qtgradientview.h
new file mode 100644
index 000000000..8a45ecfcb
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTVIEW_H
+#define GRADIENTVIEW_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QMap>
+#include "ui_qtgradientview.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+class QListViewItem;
+class QAction;
+
+class QtGradientView : public QWidget
+{
+ Q_OBJECT
+public:
+ QtGradientView(QWidget *parent = 0);
+
+ void setGradientManager(QtGradientManager *manager);
+ QtGradientManager *gradientManager() const;
+
+ void setCurrentGradient(const QString &id);
+ QString currentGradient() const;
+
+signals:
+ void currentGradientChanged(const QString &id);
+ void gradientActivated(const QString &id);
+
+private slots:
+ void slotGradientAdded(const QString &id, const QGradient &gradient);
+ void slotGradientRenamed(const QString &id, const QString &newId);
+ void slotGradientChanged(const QString &id, const QGradient &newGradient);
+ void slotGradientRemoved(const QString &id);
+ void slotNewGradient();
+ void slotEditGradient();
+ void slotRemoveGradient();
+ void slotRenameGradient();
+ void slotRenameGradient(QListWidgetItem *item);
+ void slotCurrentItemChanged(QListWidgetItem *item);
+ void slotGradientActivated(QListWidgetItem *item);
+
+private:
+ QMap<QString, QListWidgetItem *> m_idToItem;
+ QMap<QListWidgetItem *, QString> m_itemToId;
+
+ QAction *m_newAction;
+ QAction *m_editAction;
+ QAction *m_renameAction;
+ QAction *m_removeAction;
+
+ QtGradientManager *m_manager;
+ Ui::QtGradientView m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientview.ui b/src/shared/qtgradienteditor/qtgradientview.ui
new file mode 100644
index 000000000..af7267ea2
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.ui
@@ -0,0 +1,135 @@
+<ui version="4.0" >
+ <class>QtGradientView</class>
+ <widget class="QWidget" name="QtGradientView" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>484</width>
+ <height>228</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Gradient View</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QToolButton" name="newButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>New...</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="editButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Edit...</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="renameButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Rename</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>71</width>
+ <height>26</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget" />
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>listWidget</tabstop>
+ <tabstop>newButton</tabstop>
+ <tabstop>editButton</tabstop>
+ <tabstop>renameButton</tabstop>
+ <tabstop>removeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.cpp b/src/shared/qtgradienteditor/qtgradientviewdialog.cpp
new file mode 100644
index 000000000..260641d32
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientviewdialog.h"
+#include "qtgradientmanager.h"
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+QtGradientViewDialog::QtGradientViewDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ m_ui.setupUi(this);
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+ connect(m_ui.gradientView, SIGNAL(currentGradientChanged(QString)),
+ this, SLOT(slotGradientSelected(QString)));
+ connect(m_ui.gradientView, SIGNAL(gradientActivated(QString)),
+ this, SLOT(slotGradientActivated(QString)));
+}
+
+void QtGradientViewDialog::setGradientManager(QtGradientManager *manager)
+{
+ m_ui.gradientView->setGradientManager(manager);
+}
+
+QGradient QtGradientViewDialog::getGradient(bool *ok, QtGradientManager *manager, QWidget *parent, const QString &caption)
+{
+ QtGradientViewDialog dlg(parent);
+ dlg.setGradientManager(manager);
+ dlg.setWindowTitle(caption);
+ QGradient grad = QLinearGradient();
+ const int res = dlg.exec();
+ if (res == QDialog::Accepted)
+ grad = dlg.m_ui.gradientView->gradientManager()->gradients().value(dlg.m_ui.gradientView->currentGradient());
+ if (ok)
+ *ok = res == QDialog::Accepted;
+ return grad;
+}
+
+void QtGradientViewDialog::slotGradientSelected(const QString &id)
+{
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!id.isEmpty());
+}
+
+void QtGradientViewDialog::slotGradientActivated(const QString &id)
+{
+ Q_UNUSED(id)
+ accept();
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.h b/src/shared/qtgradienteditor/qtgradientviewdialog.h
new file mode 100644
index 000000000..66cfeea40
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTVIEWDIALOG_H
+#define GRADIENTVIEWDIALOG_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QMap>
+#include "ui_qtgradientviewdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+
+class QtGradientViewDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ QtGradientViewDialog(QWidget *parent = 0);
+
+ void setGradientManager(QtGradientManager *manager);
+ QtGradientManager *gradientManager() const;
+
+ static QGradient getGradient(bool *ok, QtGradientManager *manager, QWidget *parent = 0, const QString &caption = tr("Select Gradient", 0));
+
+private slots:
+ void slotGradientSelected(const QString &id);
+ void slotGradientActivated(const QString &id);
+
+private:
+ Ui::QtGradientViewDialog m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.ui b/src/shared/qtgradienteditor/qtgradientviewdialog.ui
new file mode 100644
index 000000000..1aa32a323
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.ui
@@ -0,0 +1,121 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientViewDialog</class>
+ <widget class="QDialog" name="QtGradientViewDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>178</width>
+ <height>72</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Select Gradient</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QtGradientView" name="gradientView" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtGradientView</class>
+ <extends>QFrame</extends>
+ <header>qtgradientview.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtGradientViewDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>72</x>
+ <y>224</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>21</x>
+ <y>243</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtGradientViewDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>168</x>
+ <y>233</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>152</x>
+ <y>251</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientwidget.cpp b/src/shared/qtgradienteditor/qtgradientwidget.cpp
new file mode 100644
index 000000000..d9056a703
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientwidget.cpp
@@ -0,0 +1,815 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientwidget.h"
+#include <QtCore/QMap>
+#include <QtGui/QImage>
+#include <QtGui/QPainter>
+#include <QtGui/QScrollBar>
+#include <QtGui/QMouseEvent>
+
+#define _USE_MATH_DEFINES
+
+
+#include "math.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientWidgetPrivate
+{
+ QtGradientWidget *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientWidget)
+public:
+ QPointF fromViewport(const QPointF &point) const;
+ QPointF toViewport(const QPointF &point) const;
+// void setupDrag(QtGradientStop *stop, int x);
+
+ QPointF checkRange(const QPointF &point) const;
+ QRectF pointRect(const QPointF &point, double size) const;
+
+ double correctAngle(double angle) const;
+ void setAngleConical(double angle);
+
+ void paintPoint(QPainter *painter, const QPointF &point, double size) const;
+
+ double m_handleSize;
+ bool m_backgroundCheckered;
+
+ QGradientStops m_gradientStops;
+ QGradient::Type m_gradientType;
+ QGradient::Spread m_gradientSpread;
+ QPointF m_startLinear;
+ QPointF m_endLinear;
+ QPointF m_centralRadial;
+ QPointF m_focalRadial;
+ qreal m_radiusRadial;
+ QPointF m_centralConical;
+ qreal m_angleConical;
+
+ enum Handle {
+ NoHandle,
+ StartLinearHandle,
+ EndLinearHandle,
+ CentralRadialHandle,
+ FocalRadialHandle,
+ RadiusRadialHandle,
+ CentralConicalHandle,
+ AngleConicalHandle
+ };
+
+ Handle m_dragHandle;
+ QPointF m_dragOffset;
+ //double m_radiusOffset;
+ double m_radiusFactor;
+ double m_dragRadius;
+ double m_angleOffset;
+ double m_dragAngle;
+};
+
+double QtGradientWidgetPrivate::correctAngle(double angle) const
+{
+ double a = angle;
+ while (a >= 360)
+ a -= 360;
+ while (a < 0)
+ a += 360;
+ return a;
+}
+
+void QtGradientWidgetPrivate::setAngleConical(double angle)
+{
+ double a = correctAngle(angle);
+ if (m_angleConical == a)
+ return;
+ m_angleConical = a;
+ emit q_ptr->angleConicalChanged(m_angleConical);
+}
+
+QRectF QtGradientWidgetPrivate::pointRect(const QPointF &point, double size) const
+{
+ return QRectF(point.x() - size / 2, point.y() - size / 2, size, size);
+}
+
+QPointF QtGradientWidgetPrivate::checkRange(const QPointF &point) const
+{
+ QPointF p = point;
+ if (p.x() > 1)
+ p.setX(1);
+ else if (p.x() < 0)
+ p.setX(0);
+ if (p.y() > 1)
+ p.setY(1);
+ else if (p.y() < 0)
+ p.setY(0);
+ return p;
+}
+
+QPointF QtGradientWidgetPrivate::fromViewport(const QPointF &point) const
+{
+ QSize size = q_ptr->size();
+ return QPointF(point.x() / size.width(), point.y() / size.height());
+}
+
+QPointF QtGradientWidgetPrivate::toViewport(const QPointF &point) const
+{
+ QSize size = q_ptr->size();
+ return QPointF(point.x() * size.width(), point.y() * size.height());
+}
+
+void QtGradientWidgetPrivate::paintPoint(QPainter *painter, const QPointF &point, double size) const
+{
+ QPointF pf = toViewport(point);
+ QRectF rf = pointRect(pf, size);
+
+ QPen pen;
+ pen.setWidthF(1);
+ QColor alphaZero = Qt::white;
+ alphaZero.setAlpha(0);
+
+ painter->save();
+ painter->drawEllipse(rf);
+
+ /*
+ painter->save();
+
+ QLinearGradient lgV(0, rf.top(), 0, rf.bottom());
+ lgV.setColorAt(0, alphaZero);
+ lgV.setColorAt(0.25, Qt::white);
+ lgV.setColorAt(0.25, Qt::white);
+ lgV.setColorAt(1, alphaZero);
+ pen.setBrush(lgV);
+ painter->setPen(pen);
+
+ painter->drawLine(QPointF(pf.x(), rf.top()), QPointF(pf.x(), rf.bottom()));
+
+ QLinearGradient lgH(rf.left(), 0, rf.right(), 0);
+ lgH.setColorAt(0, alphaZero);
+ lgH.setColorAt(0.5, Qt::white);
+ lgH.setColorAt(1, alphaZero);
+ pen.setBrush(lgH);
+ painter->setPen(pen);
+
+ painter->drawLine(QPointF(rf.left(), pf.y()), QPointF(rf.right(), pf.y()));
+
+ painter->restore();
+ */
+
+ painter->restore();
+}
+
+/*
+void QtGradientWidgetPrivate::setupDrag(QtGradientStop *stop, int x)
+{
+ m_model->setCurrentStop(stop);
+
+ int viewportX = qRound(toViewport(stop->position()));
+ m_dragOffset = x - viewportX;
+
+ QList<QtGradientStop *> stops = m_stops;
+ m_stops.clear();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (m_model->isSelected(s) || s == stop) {
+ m_dragStops[s] = s->position() - stop->position();
+ m_stops.append(s);
+ } else {
+ m_dragOriginal[s->position()] = s->color();
+ }
+ }
+ itStop.toFront();
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (!m_model->isSelected(s))
+ m_stops.append(s);
+ }
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+}
+*/
+////////////////////////////
+
+QtGradientWidget::QtGradientWidget(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtGradientWidgetPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_backgroundCheckered = true;
+ d_ptr->m_handleSize = 20.0;
+ d_ptr->m_gradientType = QGradient::LinearGradient;
+ d_ptr->m_startLinear = QPointF(0, 0);
+ d_ptr->m_endLinear = QPointF(1, 1);
+ d_ptr->m_centralRadial = QPointF(0.5, 0.5);
+ d_ptr->m_focalRadial = QPointF(0.5, 0.5);
+ d_ptr->m_radiusRadial = 0.5;
+ d_ptr->m_centralConical = QPointF(0.5, 0.5);
+ d_ptr->m_angleConical = 0;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
+}
+
+QtGradientWidget::~QtGradientWidget()
+{
+}
+
+QSize QtGradientWidget::sizeHint() const
+{
+ return QSize(176, 176);
+}
+
+QSize QtGradientWidget::minimumSizeHint() const
+{
+ return QSize(128, 128);
+}
+
+int QtGradientWidget::heightForWidth(int w) const
+{
+ return w;
+}
+
+void QtGradientWidget::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtGradientWidget::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientWidget::mousePressEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ QPoint p = e->pos();
+ if (d_ptr->m_gradientType == QGradient::LinearGradient) {
+ QPointF startPoint = d_ptr->toViewport(d_ptr->m_startLinear);
+ double x = p.x() - startPoint.x();
+ double y = p.y() - startPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::StartLinearHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF endPoint = d_ptr->toViewport(d_ptr->m_endLinear);
+ x = p.x() - endPoint.x();
+ y = p.y() - endPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::EndLinearHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+ } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
+ QPointF focalPoint = d_ptr->toViewport(d_ptr->m_focalRadial);
+ double x = p.x() - focalPoint.x();
+ double y = p.y() - focalPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 9) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::FocalRadialHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralRadial);
+ x = p.x() - centralPoint.x();
+ y = p.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralRadialHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralRadial);
+ QRectF r = d_ptr->pointRect(central, 2 * d_ptr->m_handleSize / 3);
+ QRectF r1(0, r.y(), size().width(), r.height());
+ QRectF r2(r.x(), 0, r.width(), r.y());
+ QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
+ QPointF pF(p.x(), p.y());
+ if (r1.contains(pF) || r2.contains(pF) || r3.contains(pF)) {
+ x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
+ y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
+ double clickRadius = sqrt(x * x + y * y);
+ //d_ptr->m_radiusOffset = d_ptr->m_radiusRadial - clickRadius;
+ d_ptr->m_radiusFactor = d_ptr->m_radiusRadial / clickRadius;
+ if (d_ptr->m_radiusFactor == 0)
+ d_ptr->m_radiusFactor = 1;
+ d_ptr->m_dragRadius = d_ptr->m_radiusRadial;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::RadiusRadialHandle;
+ mouseMoveEvent(e);
+ update();
+ return;
+ }
+ } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralConical);
+ double x = p.x() - centralPoint.x();
+ double y = p.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralConicalHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+ double radius = size().width();
+ if (size().height() < radius)
+ radius = size().height();
+ radius /= 2;
+ double corr = d_ptr->m_handleSize / 3;
+ radius -= corr;
+ QPointF vp = d_ptr->toViewport(d_ptr->m_centralConical);
+ x = p.x() - vp.x();
+ y = p.y() - vp.y();
+ if (((radius - corr) * (radius - corr) < (x * x + y * y)) &&
+ ((radius + corr) * (radius + corr) > (x * x + y * y))) {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF current(e->pos().x(), e->pos().y());
+ x = current.x() - central.x();
+ y = current.y() - central.y();
+ x /= size().width() / 2;
+ y /= size().height() / 2;
+ double r = sqrt(x * x + y * y);
+
+ double arcSin = asin(y / r);
+ double arcCos = acos(x / r);
+
+ double angle = arcCos * 180 / M_PI;
+ if (arcSin > 0) {
+ angle = -angle;
+ }
+
+ d_ptr->m_angleOffset = d_ptr->m_angleConical - angle;
+ d_ptr->m_dragAngle = d_ptr->m_angleConical;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::AngleConicalHandle;
+ update();
+ return;
+ }
+ }
+}
+
+void QtGradientWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_UNUSED(e)
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
+ update();
+}
+
+void QtGradientWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::NoHandle)
+ return;
+
+ QPointF newPos = QPointF((double)e->pos().x() - d_ptr->m_dragOffset.x(),
+ (double)e->pos().y() - d_ptr->m_dragOffset.y());
+ QPointF newPoint = d_ptr->fromViewport(newPos);
+ if (newPoint.x() < 0)
+ newPoint.setX(0);
+ else if (newPoint.x() > 1)
+ newPoint.setX(1);
+ if (newPoint.y() < 0)
+ newPoint.setY(0);
+ else if (newPoint.y() > 1)
+ newPoint.setY(1);
+
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle) {
+ d_ptr->m_startLinear = newPoint;
+ emit startLinearChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle) {
+ d_ptr->m_endLinear = newPoint;
+ emit endLinearChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle) {
+ d_ptr->m_centralRadial = newPoint;
+ emit centralRadialChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle) {
+ d_ptr->m_focalRadial = newPoint;
+ emit focalRadialChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralRadial);
+ QPointF pF(e->pos().x(), e->pos().y());
+ double x = pF.x() - centralPoint.x();
+ double y = pF.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ if (d_ptr->m_radiusRadial != d_ptr->m_dragRadius) {
+ d_ptr->m_radiusRadial = d_ptr->m_dragRadius;
+ emit radiusRadialChanged(d_ptr->m_radiusRadial);
+ }
+ } else {
+ x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
+ y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
+ double moveRadius = sqrt(x * x + y * y);
+ //double newRadius = moveRadius + d_ptr->m_radiusOffset;
+ double newRadius = moveRadius * d_ptr->m_radiusFactor;
+ if (newRadius > 2)
+ newRadius = 2;
+ d_ptr->m_radiusRadial = newRadius;
+ emit radiusRadialChanged(d_ptr->m_radiusRadial);
+ }
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle) {
+ d_ptr->m_centralConical = newPoint;
+ emit centralConicalChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF pF(e->pos().x(), e->pos().y());
+ double x = pF.x() - centralPoint.x();
+ double y = pF.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ if (d_ptr->m_angleConical != d_ptr->m_dragAngle) {
+ d_ptr->m_angleConical = d_ptr->m_dragAngle;
+ emit angleConicalChanged(d_ptr->m_angleConical);
+ }
+ } else {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF current = pF;
+ x = current.x() - central.x();
+ y = current.y() - central.y();
+ x /= size().width() / 2;
+ y /= size().height() / 2;
+ double r = sqrt(x * x + y * y);
+
+ double arcSin = asin(y / r);
+ double arcCos = acos(x / r);
+
+ double angle = arcCos * 180 / M_PI;
+ if (arcSin > 0) {
+ angle = -angle;
+ }
+
+ angle += d_ptr->m_angleOffset;
+
+ d_ptr->setAngleConical(angle);
+ }
+ }
+ update();
+}
+
+void QtGradientWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ mousePressEvent(e);
+}
+
+void QtGradientWidget::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e)
+
+ QPainter p(this);
+
+ if (d_ptr->m_backgroundCheckered) {
+ int pixSize = 40;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+
+ p.setBrushOrigin((size().width() % pixSize + pixSize) / 2, (size().height() % pixSize + pixSize) / 2);
+ p.fillRect(rect(), pm);
+ p.setBrushOrigin(0, 0);
+ }
+
+ QGradient *gradient = 0;
+ switch (d_ptr->m_gradientType) {
+ case QGradient::LinearGradient:
+ gradient = new QLinearGradient(d_ptr->m_startLinear, d_ptr->m_endLinear);
+ break;
+ case QGradient::RadialGradient:
+ gradient = new QRadialGradient(d_ptr->m_centralRadial, d_ptr->m_radiusRadial, d_ptr->m_focalRadial);
+ break;
+ case QGradient::ConicalGradient:
+ gradient = new QConicalGradient(d_ptr->m_centralConical, d_ptr->m_angleConical);
+ break;
+ default:
+ break;
+ }
+ if (!gradient)
+ return;
+
+ gradient->setStops(d_ptr->m_gradientStops);
+ gradient->setSpread(d_ptr->m_gradientSpread);
+
+ p.save();
+ p.scale(size().width(), size().height());
+ p.fillRect(QRect(0, 0, 1, 1), *gradient);
+ p.restore();
+
+ p.setRenderHint(QPainter::Antialiasing);
+
+ QColor c = QColor::fromRgbF(0.5, 0.5, 0.5, 0.5);
+ QBrush br(c);
+ p.setBrush(br);
+ QPen pen(Qt::white);
+ pen.setWidthF(1);
+ p.setPen(pen);
+ QPen dragPen = pen;
+ dragPen.setWidthF(2);
+ if (d_ptr->m_gradientType == QGradient::LinearGradient) {
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_startLinear, d_ptr->m_handleSize);
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_endLinear, d_ptr->m_handleSize);
+ p.restore();
+ } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralRadial);
+
+ p.save();
+ QRectF r = d_ptr->pointRect(central, 2 * d_ptr->m_handleSize / 3);
+ QRectF r1(0, r.y(), size().width(), r.height());
+ QRectF r2(r.x(), 0, r.width(), r.y());
+ QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
+ p.fillRect(r1, c);
+ p.fillRect(r2, c);
+ p.fillRect(r3, c);
+ p.setBrush(Qt::NoBrush);
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_centralRadial, d_ptr->m_handleSize);
+ p.restore();
+
+ QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial * size().width(),
+ central.y() - d_ptr->m_radiusRadial * size().height(),
+ 2 * d_ptr->m_radiusRadial * size().width(),
+ 2 * d_ptr->m_radiusRadial * size().height());
+ p.setClipRect(r1);
+ p.setClipRect(r2, Qt::UniteClip);
+ p.setClipRect(r3, Qt::UniteClip);
+ p.drawEllipse(rect);
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
+ p.save();
+ p.setPen(dragPen);
+ QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
+ central.y() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height(),
+ 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
+ 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height());
+ p.drawEllipse(rect);
+
+ p.restore();
+ }
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_focalRadial, 2 * d_ptr->m_handleSize / 3);
+ p.restore();
+ } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
+ double radius = size().width();
+ if (size().height() < radius)
+ radius = size().height();
+ radius /= 2;
+ double corr = d_ptr->m_handleSize / 3;
+ radius -= corr;
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+
+ p.save();
+ p.setBrush(Qt::NoBrush);
+ QPen pen2(c);
+ pen2.setWidthF(2 * d_ptr->m_handleSize / 3);
+ p.setPen(pen2);
+ p.drawEllipse(d_ptr->pointRect(central, 2 * radius));
+ p.restore();
+
+ p.save();
+ p.setBrush(Qt::NoBrush);
+ int pointCount = 2;
+ for (int i = 0; i < pointCount; i++) {
+ QPointF ang(cos(M_PI * (i * 180.0 / pointCount + d_ptr->m_angleConical) / 180) * size().width() / 2,
+ -sin(M_PI * (i * 180.0 / pointCount + d_ptr->m_angleConical) / 180) * size().height() / 2);
+ double mod = sqrt(ang.x() * ang.x() + ang.y() * ang.y());
+ p.drawLine(QPointF(central.x() + ang.x() * (radius - corr) / mod,
+ central.y() + ang.y() * (radius - corr) / mod),
+ QPointF(central.x() + ang.x() * (radius + corr) / mod,
+ central.y() + ang.y() * (radius + corr) / mod));
+ p.drawLine(QPointF(central.x() - ang.x() * (radius - corr) / mod,
+ central.y() - ang.y() * (radius - corr) / mod),
+ QPointF(central.x() - ang.x() * (radius + corr) / mod,
+ central.y() - ang.y() * (radius + corr) / mod));
+ }
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
+ p.save();
+ p.setPen(dragPen);
+ QPointF ang(cos(M_PI * (d_ptr->m_angleConical - d_ptr->m_angleOffset) / 180) * size().width() / 2,
+ -sin(M_PI * (d_ptr->m_angleConical - d_ptr->m_angleOffset) / 180) * size().height() / 2);
+ double mod = sqrt(ang.x() * ang.x() + ang.y() * ang.y());
+ p.drawLine(QPointF(central.x() + ang.x() * (radius - corr) / mod,
+ central.y() + ang.y() * (radius - corr) / mod),
+ QPointF(central.x() + ang.x() * (radius + corr) / mod,
+ central.y() + ang.y() * (radius + corr) / mod));
+ p.restore();
+ }
+
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_centralConical, d_ptr->m_handleSize);
+ p.restore();
+
+ }
+
+ delete gradient;
+}
+
+void QtGradientWidget::setGradientStops(const QGradientStops &stops)
+{
+ d_ptr->m_gradientStops = stops;
+ update();
+}
+
+QGradientStops QtGradientWidget::gradientStops() const
+{
+ return d_ptr->m_gradientStops;
+}
+
+void QtGradientWidget::setGradientType(QGradient::Type type)
+{
+ if (type == QGradient::NoGradient)
+ return;
+ if (d_ptr->m_gradientType == type)
+ return;
+
+ d_ptr->m_gradientType = type;
+ update();
+}
+
+QGradient::Type QtGradientWidget::gradientType() const
+{
+ return d_ptr->m_gradientType;
+}
+
+void QtGradientWidget::setGradientSpread(QGradient::Spread spread)
+{
+ if (d_ptr->m_gradientSpread == spread)
+ return;
+
+ d_ptr->m_gradientSpread = spread;
+ update();
+}
+
+QGradient::Spread QtGradientWidget::gradientSpread() const
+{
+ return d_ptr->m_gradientSpread;
+}
+
+void QtGradientWidget::setStartLinear(const QPointF &point)
+{
+ if (d_ptr->m_startLinear == point)
+ return;
+
+ d_ptr->m_startLinear = d_ptr->checkRange(point);
+ update();
+}
+
+QPointF QtGradientWidget::startLinear() const
+{
+ return d_ptr->m_startLinear;
+}
+
+void QtGradientWidget::setEndLinear(const QPointF &point)
+{
+ if (d_ptr->m_endLinear == point)
+ return;
+
+ d_ptr->m_endLinear = d_ptr->checkRange(point);
+ update();
+}
+
+QPointF QtGradientWidget::endLinear() const
+{
+ return d_ptr->m_endLinear;
+}
+
+void QtGradientWidget::setCentralRadial(const QPointF &point)
+{
+ if (d_ptr->m_centralRadial == point)
+ return;
+
+ d_ptr->m_centralRadial = point;
+ update();
+}
+
+QPointF QtGradientWidget::centralRadial() const
+{
+ return d_ptr->m_centralRadial;
+}
+
+void QtGradientWidget::setFocalRadial(const QPointF &point)
+{
+ if (d_ptr->m_focalRadial == point)
+ return;
+
+ d_ptr->m_focalRadial = point;
+ update();
+}
+
+QPointF QtGradientWidget::focalRadial() const
+{
+ return d_ptr->m_focalRadial;
+}
+
+void QtGradientWidget::setRadiusRadial(qreal radius)
+{
+ if (d_ptr->m_radiusRadial == radius)
+ return;
+
+ d_ptr->m_radiusRadial = radius;
+ update();
+}
+
+qreal QtGradientWidget::radiusRadial() const
+{
+ return d_ptr->m_radiusRadial;
+}
+
+void QtGradientWidget::setCentralConical(const QPointF &point)
+{
+ if (d_ptr->m_centralConical == point)
+ return;
+
+ d_ptr->m_centralConical = point;
+ update();
+}
+
+QPointF QtGradientWidget::centralConical() const
+{
+ return d_ptr->m_centralConical;
+}
+
+void QtGradientWidget::setAngleConical(qreal angle)
+{
+ if (d_ptr->m_angleConical == angle)
+ return;
+
+ d_ptr->m_angleConical = angle;
+ update();
+}
+
+qreal QtGradientWidget::angleConical() const
+{
+ return d_ptr->m_angleConical;
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientwidget.h b/src/shared/qtgradienteditor/qtgradientwidget.h
new file mode 100644
index 000000000..ee866feb9
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientwidget.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTWIDGET_H
+#define QTGRADIENTWIDGET_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtGradientWidget(QWidget *parent = 0);
+ ~QtGradientWidget();
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+ int heightForWidth(int w) const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ QGradientStops gradientStops() const;
+
+ void setGradientType(QGradient::Type type);
+ QGradient::Type gradientType() const;
+
+ void setGradientSpread(QGradient::Spread spread);
+ QGradient::Spread gradientSpread() const;
+
+ void setStartLinear(const QPointF &point);
+ QPointF startLinear() const;
+
+ void setEndLinear(const QPointF &point);
+ QPointF endLinear() const;
+
+ void setCentralRadial(const QPointF &point);
+ QPointF centralRadial() const;
+
+ void setFocalRadial(const QPointF &point);
+ QPointF focalRadial() const;
+
+ void setRadiusRadial(qreal radius);
+ qreal radiusRadial() const;
+
+ void setCentralConical(const QPointF &point);
+ QPointF centralConical() const;
+
+ void setAngleConical(qreal angle);
+ qreal angleConical() const;
+
+public slots:
+ void setGradientStops(const QGradientStops &stops);
+signals:
+
+ void startLinearChanged(const QPointF &point);
+ void endLinearChanged(const QPointF &point);
+ void centralRadialChanged(const QPointF &point);
+ void focalRadialChanged(const QPointF &point);
+ void radiusRadialChanged(qreal radius);
+ void centralConicalChanged(const QPointF &point);
+ void angleConicalChanged(qreal angle);
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *e);
+
+private:
+ QScopedPointer<class QtGradientWidgetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientWidget)
+ Q_DISABLE_COPY(QtGradientWidget)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/images/cursor-arrow.png b/src/shared/qtpropertybrowser/images/cursor-arrow.png
new file mode 100644
index 000000000..a69ef4eb6
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-arrow.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-busy.png b/src/shared/qtpropertybrowser/images/cursor-busy.png
new file mode 100644
index 000000000..53717e499
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-busy.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-closedhand.png b/src/shared/qtpropertybrowser/images/cursor-closedhand.png
new file mode 100644
index 000000000..b78dd1dac
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-closedhand.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-cross.png b/src/shared/qtpropertybrowser/images/cursor-cross.png
new file mode 100644
index 000000000..fe38e7448
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-cross.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-forbidden.png b/src/shared/qtpropertybrowser/images/cursor-forbidden.png
new file mode 100644
index 000000000..2b08c4e2a
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-forbidden.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-hand.png b/src/shared/qtpropertybrowser/images/cursor-hand.png
new file mode 100644
index 000000000..d2004aefa
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-hand.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-hsplit.png b/src/shared/qtpropertybrowser/images/cursor-hsplit.png
new file mode 100644
index 000000000..a5667e3ff
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-hsplit.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-ibeam.png b/src/shared/qtpropertybrowser/images/cursor-ibeam.png
new file mode 100644
index 000000000..097fc5fa7
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-ibeam.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-openhand.png b/src/shared/qtpropertybrowser/images/cursor-openhand.png
new file mode 100644
index 000000000..9181c859e
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-openhand.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizeall.png b/src/shared/qtpropertybrowser/images/cursor-sizeall.png
new file mode 100644
index 000000000..69f13eb34
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizeall.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizeb.png b/src/shared/qtpropertybrowser/images/cursor-sizeb.png
new file mode 100644
index 000000000..f37d7b91e
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizeb.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizef.png b/src/shared/qtpropertybrowser/images/cursor-sizef.png
new file mode 100644
index 000000000..3b127a05d
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizef.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizeh.png b/src/shared/qtpropertybrowser/images/cursor-sizeh.png
new file mode 100644
index 000000000..a9f40cbc3
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizeh.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizev.png b/src/shared/qtpropertybrowser/images/cursor-sizev.png
new file mode 100644
index 000000000..1edbab27a
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizev.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-uparrow.png b/src/shared/qtpropertybrowser/images/cursor-uparrow.png
new file mode 100644
index 000000000..d3e70ef4c
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-uparrow.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-vsplit.png b/src/shared/qtpropertybrowser/images/cursor-vsplit.png
new file mode 100644
index 000000000..1beda2570
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-vsplit.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-wait.png b/src/shared/qtpropertybrowser/images/cursor-wait.png
new file mode 100644
index 000000000..69056c479
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-wait.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-whatsthis.png b/src/shared/qtpropertybrowser/images/cursor-whatsthis.png
new file mode 100644
index 000000000..b47601c37
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-whatsthis.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp
new file mode 100644
index 000000000..09571243f
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp
@@ -0,0 +1,627 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtbuttonpropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtCore/QTimer>
+#include <QtCore/QMap>
+#include <QtGui/QToolButton>
+#include <QtGui/QStyle>
+
+QT_BEGIN_NAMESPACE
+
+class QtButtonPropertyBrowserPrivate
+{
+ QtButtonPropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtButtonPropertyBrowser)
+public:
+
+ void init(QWidget *parent);
+
+ void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex);
+ void propertyRemoved(QtBrowserItem *index);
+ void propertyChanged(QtBrowserItem *index);
+ QWidget *createEditor(QtProperty *property, QWidget *parent) const
+ { return q_ptr->createEditor(property, parent); }
+
+ void slotEditorDestroyed();
+ void slotUpdate();
+ void slotToggled(bool checked);
+
+ struct WidgetItem
+ {
+ WidgetItem() : widget(0), label(0), widgetLabel(0),
+ button(0), container(0), layout(0), /*line(0), */parent(0), expanded(false) { }
+ QWidget *widget; // can be null
+ QLabel *label; // main label with property name
+ QLabel *widgetLabel; // label substitute showing the current value if there is no widget
+ QToolButton *button; // expandable button for items with children
+ QWidget *container; // container which is expanded when the button is clicked
+ QGridLayout *layout; // layout in container
+ WidgetItem *parent;
+ QList<WidgetItem *> children;
+ bool expanded;
+ };
+private:
+ void updateLater();
+ void updateItem(WidgetItem *item);
+ void insertRow(QGridLayout *layout, int row) const;
+ void removeRow(QGridLayout *layout, int row) const;
+ int gridRow(WidgetItem *item) const;
+ int gridSpan(WidgetItem *item) const;
+ void setExpanded(WidgetItem *item, bool expanded);
+ QToolButton *createButton(QWidget *panret = 0) const;
+
+ QMap<QtBrowserItem *, WidgetItem *> m_indexToItem;
+ QMap<WidgetItem *, QtBrowserItem *> m_itemToIndex;
+ QMap<QWidget *, WidgetItem *> m_widgetToItem;
+ QMap<QObject *, WidgetItem *> m_buttonToItem;
+ QGridLayout *m_mainLayout;
+ QList<WidgetItem *> m_children;
+ QList<WidgetItem *> m_recreateQueue;
+};
+
+QToolButton *QtButtonPropertyBrowserPrivate::createButton(QWidget *parent) const
+{
+ QToolButton *button = new QToolButton(parent);
+ button->setCheckable(true);
+ button->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+ button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ button->setArrowType(Qt::DownArrow);
+ button->setIconSize(QSize(3, 16));
+ /*
+ QIcon icon;
+ icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowDown), QIcon::Normal, QIcon::Off);
+ icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowUp), QIcon::Normal, QIcon::On);
+ button->setIcon(icon);
+ */
+ return button;
+}
+
+int QtButtonPropertyBrowserPrivate::gridRow(WidgetItem *item) const
+{
+ QList<WidgetItem *> siblings;
+ if (item->parent)
+ siblings = item->parent->children;
+ else
+ siblings = m_children;
+
+ int row = 0;
+ QListIterator<WidgetItem *> it(siblings);
+ while (it.hasNext()) {
+ WidgetItem *sibling = it.next();
+ if (sibling == item)
+ return row;
+ row += gridSpan(sibling);
+ }
+ return -1;
+}
+
+int QtButtonPropertyBrowserPrivate::gridSpan(WidgetItem *item) const
+{
+ if (item->container && item->expanded)
+ return 2;
+ return 1;
+}
+
+void QtButtonPropertyBrowserPrivate::init(QWidget *parent)
+{
+ m_mainLayout = new QGridLayout();
+ parent->setLayout(m_mainLayout);
+ QLayoutItem *item = new QSpacerItem(0, 0,
+ QSizePolicy::Fixed, QSizePolicy::Expanding);
+ m_mainLayout->addItem(item, 0, 0);
+}
+
+void QtButtonPropertyBrowserPrivate::slotEditorDestroyed()
+{
+ QWidget *editor = qobject_cast<QWidget *>(q_ptr->sender());
+ if (!editor)
+ return;
+ if (!m_widgetToItem.contains(editor))
+ return;
+ m_widgetToItem[editor]->widget = 0;
+ m_widgetToItem.remove(editor);
+}
+
+void QtButtonPropertyBrowserPrivate::slotUpdate()
+{
+ QListIterator<WidgetItem *> itItem(m_recreateQueue);
+ while (itItem.hasNext()) {
+ WidgetItem *item = itItem.next();
+
+ WidgetItem *parent = item->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ const int oldRow = gridRow(item);
+ if (parent) {
+ w = parent->container;
+ l = parent->layout;
+ } else {
+ w = q_ptr;
+ l = m_mainLayout;
+ }
+
+ int span = 1;
+ if (!item->widget && !item->widgetLabel)
+ span = 2;
+ item->label = new QLabel(w);
+ item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ l->addWidget(item->label, oldRow, 0, 1, span);
+
+ updateItem(item);
+ }
+ m_recreateQueue.clear();
+}
+
+void QtButtonPropertyBrowserPrivate::setExpanded(WidgetItem *item, bool expanded)
+{
+ if (item->expanded == expanded)
+ return;
+
+ if (!item->container)
+ return;
+
+ item->expanded = expanded;
+ const int row = gridRow(item);
+ WidgetItem *parent = item->parent;
+ QGridLayout *l = 0;
+ if (parent)
+ l = parent->layout;
+ else
+ l = m_mainLayout;
+
+ if (expanded) {
+ insertRow(l, row + 1);
+ l->addWidget(item->container, row + 1, 0, 1, 2);
+ item->container->show();
+ } else {
+ l->removeWidget(item->container);
+ item->container->hide();
+ removeRow(l, row + 1);
+ }
+
+ item->button->setChecked(expanded);
+ item->button->setArrowType(expanded ? Qt::UpArrow : Qt::DownArrow);
+}
+
+void QtButtonPropertyBrowserPrivate::slotToggled(bool checked)
+{
+ WidgetItem *item = m_buttonToItem.value(q_ptr->sender());
+ if (!item)
+ return;
+
+ setExpanded(item, checked);
+
+ if (checked)
+ emit q_ptr->expanded(m_itemToIndex.value(item));
+ else
+ emit q_ptr->collapsed(m_itemToIndex.value(item));
+}
+
+void QtButtonPropertyBrowserPrivate::updateLater()
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdate()));
+}
+
+void QtButtonPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex)
+{
+ WidgetItem *afterItem = m_indexToItem.value(afterIndex);
+ WidgetItem *parentItem = m_indexToItem.value(index->parent());
+
+ WidgetItem *newItem = new WidgetItem();
+ newItem->parent = parentItem;
+
+ QGridLayout *layout = 0;
+ QWidget *parentWidget = 0;
+ int row = -1;
+ if (!afterItem) {
+ row = 0;
+ if (parentItem)
+ parentItem->children.insert(0, newItem);
+ else
+ m_children.insert(0, newItem);
+ } else {
+ row = gridRow(afterItem) + gridSpan(afterItem);
+ if (parentItem)
+ parentItem->children.insert(parentItem->children.indexOf(afterItem) + 1, newItem);
+ else
+ m_children.insert(m_children.indexOf(afterItem) + 1, newItem);
+ }
+
+ if (!parentItem) {
+ layout = m_mainLayout;
+ parentWidget = q_ptr;
+ } else {
+ if (!parentItem->container) {
+ m_recreateQueue.removeAll(parentItem);
+ WidgetItem *grandParent = parentItem->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ const int oldRow = gridRow(parentItem);
+ if (grandParent) {
+ w = grandParent->container;
+ l = grandParent->layout;
+ } else {
+ w = q_ptr;
+ l = m_mainLayout;
+ }
+ QFrame *container = new QFrame();
+ container->setFrameShape(QFrame::Panel);
+ container->setFrameShadow(QFrame::Raised);
+ parentItem->container = container;
+ parentItem->button = createButton();
+ m_buttonToItem[parentItem->button] = parentItem;
+ q_ptr->connect(parentItem->button, SIGNAL(toggled(bool)), q_ptr, SLOT(slotToggled(bool)));
+ parentItem->layout = new QGridLayout();
+ container->setLayout(parentItem->layout);
+ if (parentItem->label) {
+ l->removeWidget(parentItem->label);
+ delete parentItem->label;
+ parentItem->label = 0;
+ }
+ int span = 1;
+ if (!parentItem->widget && !parentItem->widgetLabel)
+ span = 2;
+ l->addWidget(parentItem->button, oldRow, 0, 1, span);
+ updateItem(parentItem);
+ }
+ layout = parentItem->layout;
+ parentWidget = parentItem->container;
+ }
+
+ newItem->label = new QLabel(parentWidget);
+ newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ newItem->widget = createEditor(index->property(), parentWidget);
+ if (newItem->widget) {
+ QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed()));
+ m_widgetToItem[newItem->widget] = newItem;
+ } else if (index->property()->hasValue()) {
+ newItem->widgetLabel = new QLabel(parentWidget);
+ newItem->widgetLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
+ }
+
+ insertRow(layout, row);
+ int span = 1;
+ if (newItem->widget)
+ layout->addWidget(newItem->widget, row, 1);
+ else if (newItem->widgetLabel)
+ layout->addWidget(newItem->widgetLabel, row, 1);
+ else
+ span = 2;
+ layout->addWidget(newItem->label, row, 0, span, 1);
+
+ m_itemToIndex[newItem] = index;
+ m_indexToItem[index] = newItem;
+
+ updateItem(newItem);
+}
+
+void QtButtonPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ m_indexToItem.remove(index);
+ m_itemToIndex.remove(item);
+
+ WidgetItem *parentItem = item->parent;
+
+ const int row = gridRow(item);
+
+ if (parentItem)
+ parentItem->children.removeAt(parentItem->children.indexOf(item));
+ else
+ m_children.removeAt(m_children.indexOf(item));
+
+ const int colSpan = gridSpan(item);
+
+ m_buttonToItem.remove(item->button);
+
+ if (item->widget)
+ delete item->widget;
+ if (item->label)
+ delete item->label;
+ if (item->widgetLabel)
+ delete item->widgetLabel;
+ if (item->button)
+ delete item->button;
+ if (item->container)
+ delete item->container;
+
+ if (!parentItem) {
+ removeRow(m_mainLayout, row);
+ if (colSpan > 1)
+ removeRow(m_mainLayout, row);
+ } else if (parentItem->children.count() != 0) {
+ removeRow(parentItem->layout, row);
+ if (colSpan > 1)
+ removeRow(parentItem->layout, row);
+ } else {
+ const WidgetItem *grandParent = parentItem->parent;
+ QGridLayout *l = 0;
+ if (grandParent) {
+ l = grandParent->layout;
+ } else {
+ l = m_mainLayout;
+ }
+
+ const int parentRow = gridRow(parentItem);
+ const int parentSpan = gridSpan(parentItem);
+
+ l->removeWidget(parentItem->button);
+ l->removeWidget(parentItem->container);
+ delete parentItem->button;
+ delete parentItem->container;
+ parentItem->button = 0;
+ parentItem->container = 0;
+ parentItem->layout = 0;
+ if (!m_recreateQueue.contains(parentItem))
+ m_recreateQueue.append(parentItem);
+ if (parentSpan > 1)
+ removeRow(l, parentRow + 1);
+
+ updateLater();
+ }
+ m_recreateQueue.removeAll(item);
+
+ delete item;
+}
+
+void QtButtonPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r >= row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for(QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+void QtButtonPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r > row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for(QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+void QtButtonPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ updateItem(item);
+}
+
+void QtButtonPropertyBrowserPrivate::updateItem(WidgetItem *item)
+{
+ QtProperty *property = m_itemToIndex[item]->property();
+ if (item->button) {
+ QFont font = item->button->font();
+ font.setUnderline(property->isModified());
+ item->button->setFont(font);
+ item->button->setText(property->propertyName());
+ item->button->setToolTip(property->toolTip());
+ item->button->setStatusTip(property->statusTip());
+ item->button->setWhatsThis(property->whatsThis());
+ item->button->setEnabled(property->isEnabled());
+ }
+ if (item->label) {
+ QFont font = item->label->font();
+ font.setUnderline(property->isModified());
+ item->label->setFont(font);
+ item->label->setText(property->propertyName());
+ item->label->setToolTip(property->toolTip());
+ item->label->setStatusTip(property->statusTip());
+ item->label->setWhatsThis(property->whatsThis());
+ item->label->setEnabled(property->isEnabled());
+ }
+ if (item->widgetLabel) {
+ QFont font = item->widgetLabel->font();
+ font.setUnderline(false);
+ item->widgetLabel->setFont(font);
+ item->widgetLabel->setText(property->valueText());
+ item->widgetLabel->setToolTip(property->valueText());
+ item->widgetLabel->setEnabled(property->isEnabled());
+ }
+ if (item->widget) {
+ QFont font = item->widget->font();
+ font.setUnderline(false);
+ item->widget->setFont(font);
+ item->widget->setEnabled(property->isEnabled());
+ item->widget->setToolTip(property->valueText());
+ }
+}
+
+
+
+/*!
+ \class QtButtonPropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtButtonPropertyBrowser class provides a drop down QToolButton
+ based property browser.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ QtButtonPropertyBrowser provides drop down button for all nested
+ properties, i.e. subproperties are enclosed by a container associated with
+ the drop down button. The parent property's name is displayed as button text. For example:
+
+ \image qtbuttonpropertybrowser.png
+
+ Use the QtAbstractPropertyBrowser API to add, insert and remove
+ properties from an instance of the QtButtonPropertyBrowser
+ class. The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class.
+
+ \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser
+*/
+
+/*!
+ \fn void QtButtonPropertyBrowser::collapsed(QtBrowserItem *item)
+
+ This signal is emitted when the \a item is collapsed.
+
+ \sa expanded(), setExpanded()
+*/
+
+/*!
+ \fn void QtButtonPropertyBrowser::expanded(QtBrowserItem *item)
+
+ This signal is emitted when the \a item is expanded.
+
+ \sa collapsed(), setExpanded()
+*/
+
+/*!
+ Creates a property browser with the given \a parent.
+*/
+QtButtonPropertyBrowser::QtButtonPropertyBrowser(QWidget *parent)
+ : QtAbstractPropertyBrowser(parent), d_ptr(new QtButtonPropertyBrowserPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->init(this);
+}
+
+/*!
+ Destroys this property browser.
+
+ Note that the properties that were inserted into this browser are
+ \e not destroyed since they may still be used in other
+ browsers. The properties are owned by the manager that created
+ them.
+
+ \sa QtProperty, QtAbstractPropertyManager
+*/
+QtButtonPropertyBrowser::~QtButtonPropertyBrowser()
+{
+ const QMap<QtButtonPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator icend = d_ptr->m_itemToIndex.constEnd();
+ for (QMap<QtButtonPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it)
+ delete it.key();
+}
+
+/*!
+ \reimp
+*/
+void QtButtonPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem)
+{
+ d_ptr->propertyInserted(item, afterItem);
+}
+
+/*!
+ \reimp
+*/
+void QtButtonPropertyBrowser::itemRemoved(QtBrowserItem *item)
+{
+ d_ptr->propertyRemoved(item);
+}
+
+/*!
+ \reimp
+*/
+void QtButtonPropertyBrowser::itemChanged(QtBrowserItem *item)
+{
+ d_ptr->propertyChanged(item);
+}
+
+/*!
+ Sets the \a item to either collapse or expanded, depending on the value of \a expanded.
+
+ \sa isExpanded(), expanded(), collapsed()
+*/
+
+void QtButtonPropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded)
+{
+ QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item);
+ if (itm)
+ d_ptr->setExpanded(itm, expanded);
+}
+
+/*!
+ Returns true if the \a item is expanded; otherwise returns false.
+
+ \sa setExpanded()
+*/
+
+bool QtButtonPropertyBrowser::isExpanded(QtBrowserItem *item) const
+{
+ QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item);
+ if (itm)
+ return itm->expanded;
+ return false;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtbuttonpropertybrowser.cpp"
diff --git a/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.h b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.h
new file mode 100644
index 000000000..53067ccf5
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTBUTTONPROPERTYBROWSER_H
+#define QTBUTTONPROPERTYBROWSER_H
+
+#include "qtpropertybrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtButtonPropertyBrowserPrivate;
+
+class QtButtonPropertyBrowser : public QtAbstractPropertyBrowser
+{
+ Q_OBJECT
+public:
+
+ QtButtonPropertyBrowser(QWidget *parent = 0);
+ ~QtButtonPropertyBrowser();
+
+ void setExpanded(QtBrowserItem *item, bool expanded);
+ bool isExpanded(QtBrowserItem *item) const;
+
+Q_SIGNALS:
+
+ void collapsed(QtBrowserItem *item);
+ void expanded(QtBrowserItem *item);
+
+protected:
+ virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem);
+ virtual void itemRemoved(QtBrowserItem *item);
+ virtual void itemChanged(QtBrowserItem *item);
+
+private:
+
+ QScopedPointer<QtButtonPropertyBrowserPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtButtonPropertyBrowser)
+ Q_DISABLE_COPY(QtButtonPropertyBrowser)
+ Q_PRIVATE_SLOT(d_func(), void slotUpdate())
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void slotToggled(bool))
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qteditorfactory.cpp b/src/shared/qtpropertybrowser/qteditorfactory.cpp
new file mode 100644
index 000000000..90ba3d3a2
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qteditorfactory.cpp
@@ -0,0 +1,2560 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qteditorfactory.h"
+#include "qtpropertybrowserutils_p.h"
+#include <QtGui/QSpinBox>
+#include <QtGui/QScrollBar>
+#include <QtGui/QComboBox>
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QLineEdit>
+#include <QtGui/QDateTimeEdit>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QMenu>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QApplication>
+#include <QtGui/QLabel>
+#include <QtGui/QToolButton>
+#include <QtGui/QColorDialog>
+#include <QtGui/QFontDialog>
+#include <QtGui/QSpacerItem>
+#include <QtCore/QMap>
+
+#if defined(Q_CC_MSVC)
+# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// Set a hard coded left margin to account for the indentation
+// of the tree view icon when switching to an editor
+
+static inline void setupTreeViewEditorMargin(QLayout *lt)
+{
+ enum { DecorationMargin = 4 };
+ if (QApplication::layoutDirection() == Qt::LeftToRight)
+ lt->setContentsMargins(DecorationMargin, 0, 0, 0);
+ else
+ lt->setContentsMargins(0, 0, DecorationMargin, 0);
+}
+
+// ---------- EditorFactoryPrivate :
+// Base class for editor factory private classes. Manages mapping of properties to editors and vice versa.
+
+template <class Editor>
+class EditorFactoryPrivate
+{
+public:
+
+ typedef QList<Editor *> EditorList;
+ typedef QMap<QtProperty *, EditorList> PropertyToEditorListMap;
+ typedef QMap<Editor *, QtProperty *> EditorToPropertyMap;
+
+ Editor *createEditor(QtProperty *property, QWidget *parent);
+ void initializeEditor(QtProperty *property, Editor *e);
+ void slotEditorDestroyed(QObject *object);
+
+ PropertyToEditorListMap m_createdEditors;
+ EditorToPropertyMap m_editorToProperty;
+};
+
+template <class Editor>
+Editor *EditorFactoryPrivate<Editor>::createEditor(QtProperty *property, QWidget *parent)
+{
+ Editor *editor = new Editor(parent);
+ initializeEditor(property, editor);
+ return editor;
+}
+
+template <class Editor>
+void EditorFactoryPrivate<Editor>::initializeEditor(QtProperty *property, Editor *editor)
+{
+ Q_TYPENAME PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
+ if (it == m_createdEditors.end())
+ it = m_createdEditors.insert(property, EditorList());
+ it.value().append(editor);
+ m_editorToProperty.insert(editor, property);
+}
+
+template <class Editor>
+void EditorFactoryPrivate<Editor>::slotEditorDestroyed(QObject *object)
+{
+ const Q_TYPENAME EditorToPropertyMap::iterator ecend = m_editorToProperty.end();
+ for (Q_TYPENAME EditorToPropertyMap::iterator itEditor = m_editorToProperty.begin(); itEditor != ecend; ++itEditor) {
+ if (itEditor.key() == object) {
+ Editor *editor = itEditor.key();
+ QtProperty *property = itEditor.value();
+ const Q_TYPENAME PropertyToEditorListMap::iterator pit = m_createdEditors.find(property);
+ if (pit != m_createdEditors.end()) {
+ pit.value().removeAll(editor);
+ if (pit.value().empty())
+ m_createdEditors.erase(pit);
+ }
+ m_editorToProperty.erase(itEditor);
+ return;
+ }
+ }
+}
+
+// ------------ QtSpinBoxFactory
+
+class QtSpinBoxFactoryPrivate : public EditorFactoryPrivate<QSpinBox>
+{
+ QtSpinBoxFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtSpinBoxFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, int value);
+ void slotRangeChanged(QtProperty *property, int min, int max);
+ void slotSingleStepChanged(QtProperty *property, int step);
+ void slotSetValue(int value);
+};
+
+void QtSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSpinBox *editor = itEditor.next();
+ if (editor->value() != value) {
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+ }
+}
+
+void QtSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setRange(min, max);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setSingleStep(step);
+ editor->blockSignals(false);
+ }
+}
+
+void QtSpinBoxFactoryPrivate::slotSetValue(int value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QSpinBox *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QSpinBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) {
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+ }
+}
+
+/*!
+ \class QtSpinBoxFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSpinBoxFactory class provides QSpinBox widgets for
+ properties created by QtIntPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtIntPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtSpinBoxFactory::QtSpinBoxFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtSpinBoxFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtSpinBoxFactory::~QtSpinBoxFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtSpinBoxFactory::connectPropertyManager(QtIntPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtSpinBoxFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QSpinBox *editor = d_ptr->createEditor(property, parent);
+ editor->setSingleStep(manager->singleStep(property));
+ editor->setRange(manager->minimum(property), manager->maximum(property));
+ editor->setValue(manager->value(property));
+ editor->setKeyboardTracking(false);
+
+ connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtSpinBoxFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ disconnect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+// QtSliderFactory
+
+class QtSliderFactoryPrivate : public EditorFactoryPrivate<QSlider>
+{
+ QtSliderFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtSliderFactory)
+public:
+ void slotPropertyChanged(QtProperty *property, int value);
+ void slotRangeChanged(QtProperty *property, int min, int max);
+ void slotSingleStepChanged(QtProperty *property, int step);
+ void slotSetValue(int value);
+};
+
+void QtSliderFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QSlider *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSlider *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtSliderFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QSlider *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSlider *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setRange(min, max);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtSliderFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QSlider *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSlider *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setSingleStep(step);
+ editor->blockSignals(false);
+ }
+}
+
+void QtSliderFactoryPrivate::slotSetValue(int value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QSlider *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QSlider *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor ) {
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+ }
+}
+
+/*!
+ \class QtSliderFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSliderFactory class provides QSlider widgets for
+ properties created by QtIntPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtIntPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtSliderFactory::QtSliderFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtSliderFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtSliderFactory::~QtSliderFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtSliderFactory::connectPropertyManager(QtIntPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtSliderFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QSlider *editor = new QSlider(Qt::Horizontal, parent);
+ d_ptr->initializeEditor(property, editor);
+ editor->setSingleStep(manager->singleStep(property));
+ editor->setRange(manager->minimum(property), manager->maximum(property));
+ editor->setValue(manager->value(property));
+
+ connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtSliderFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ disconnect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+// QtSliderFactory
+
+class QtScrollBarFactoryPrivate : public EditorFactoryPrivate<QScrollBar>
+{
+ QtScrollBarFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtScrollBarFactory)
+public:
+ void slotPropertyChanged(QtProperty *property, int value);
+ void slotRangeChanged(QtProperty *property, int min, int max);
+ void slotSingleStepChanged(QtProperty *property, int step);
+ void slotSetValue(int value);
+};
+
+void QtScrollBarFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QScrollBar *> itEditor( m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QScrollBar *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtScrollBarFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QScrollBar *> itEditor( m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QScrollBar *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setRange(min, max);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtScrollBarFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QScrollBar *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QScrollBar *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setSingleStep(step);
+ editor->blockSignals(false);
+ }
+}
+
+void QtScrollBarFactoryPrivate::slotSetValue(int value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QScrollBar *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QScrollBar *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtScrollBarFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtScrollBarFactory class provides QScrollBar widgets for
+ properties created by QtIntPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtIntPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtScrollBarFactory::QtScrollBarFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtScrollBarFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtScrollBarFactory::~QtScrollBarFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtScrollBarFactory::connectPropertyManager(QtIntPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtScrollBarFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QScrollBar *editor = new QScrollBar(Qt::Horizontal, parent);
+ d_ptr->initializeEditor(property, editor);
+ editor->setSingleStep(manager->singleStep(property));
+ editor->setRange(manager->minimum(property), manager->maximum(property));
+ editor->setValue(manager->value(property));
+ connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtScrollBarFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ disconnect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+// QtCheckBoxFactory
+
+class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate<QtBoolEdit>
+{
+ QtCheckBoxFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtCheckBoxFactory)
+public:
+ void slotPropertyChanged(QtProperty *property, bool value);
+ void slotSetValue(bool value);
+};
+
+void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QtBoolEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QtBoolEdit *editor = itEditor.next();
+ editor->blockCheckBoxSignals(true);
+ editor->setChecked(value);
+ editor->blockCheckBoxSignals(false);
+ }
+}
+
+void QtCheckBoxFactoryPrivate::slotSetValue(bool value)
+{
+ QObject *object = q_ptr->sender();
+
+ const QMap<QtBoolEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QtBoolEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtBoolPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtCheckBoxFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCheckBoxFactory class provides QCheckBox widgets for
+ properties created by QtBoolPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtBoolPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtCheckBoxFactory::QtCheckBoxFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtBoolPropertyManager>(parent), d_ptr(new QtCheckBoxFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtCheckBoxFactory::~QtCheckBoxFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCheckBoxFactory::connectPropertyManager(QtBoolPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotPropertyChanged(QtProperty*,bool)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QtBoolEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setChecked(manager->value(property));
+
+ connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCheckBoxFactory::disconnectPropertyManager(QtBoolPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotPropertyChanged(QtProperty*,bool)));
+}
+
+// QtDoubleSpinBoxFactory
+
+class QtDoubleSpinBoxFactoryPrivate : public EditorFactoryPrivate<QDoubleSpinBox>
+{
+ QtDoubleSpinBoxFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, double value);
+ void slotRangeChanged(QtProperty *property, double min, double max);
+ void slotSingleStepChanged(QtProperty *property, double step);
+ void slotDecimalsChanged(QtProperty *property, int prec);
+ void slotSetValue(double value);
+};
+
+void QtDoubleSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, double value)
+{
+ QList<QDoubleSpinBox *> editors = m_createdEditors[property];
+ QListIterator<QDoubleSpinBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QDoubleSpinBox *editor = itEditor.next();
+ if (editor->value() != value) {
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+ }
+}
+
+void QtDoubleSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property,
+ double min, double max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QList<QDoubleSpinBox *> editors = m_createdEditors[property];
+ QListIterator<QDoubleSpinBox *> itEditor(editors);
+ while (itEditor.hasNext()) {
+ QDoubleSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setRange(min, max);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtDoubleSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, double step)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QList<QDoubleSpinBox *> editors = m_createdEditors[property];
+ QListIterator<QDoubleSpinBox *> itEditor(editors);
+ while (itEditor.hasNext()) {
+ QDoubleSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setSingleStep(step);
+ editor->blockSignals(false);
+ }
+}
+
+void QtDoubleSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty *property, int prec)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QList<QDoubleSpinBox *> editors = m_createdEditors[property];
+ QListIterator<QDoubleSpinBox *> itEditor(editors);
+ while (itEditor.hasNext()) {
+ QDoubleSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setDecimals(prec);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtDoubleSpinBoxFactoryPrivate::slotSetValue(double value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QDoubleSpinBox *, QtProperty *>::ConstIterator itcend = m_editorToProperty.constEnd();
+ for (QMap<QDoubleSpinBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != itcend; ++itEditor) {
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+ }
+}
+
+/*! \class QtDoubleSpinBoxFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDoubleSpinBoxFactory class provides QDoubleSpinBox
+ widgets for properties created by QtDoublePropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtDoublePropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtDoublePropertyManager>(parent), d_ptr(new QtDoubleSpinBoxFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDoubleSpinBoxFactory::connectPropertyManager(QtDoublePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotPropertyChanged(QtProperty*,double)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ connect(manager, SIGNAL(singleStepChanged(QtProperty*,double)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,double)));
+ connect(manager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtDoubleSpinBoxFactory::createEditor(QtDoublePropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QDoubleSpinBox *editor = d_ptr->createEditor(property, parent);
+ editor->setSingleStep(manager->singleStep(property));
+ editor->setDecimals(manager->decimals(property));
+ editor->setRange(manager->minimum(property), manager->maximum(property));
+ editor->setValue(manager->value(property));
+ editor->setKeyboardTracking(false);
+
+ connect(editor, SIGNAL(valueChanged(double)), this, SLOT(slotSetValue(double)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDoubleSpinBoxFactory::disconnectPropertyManager(QtDoublePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotPropertyChanged(QtProperty*,double)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ disconnect(manager, SIGNAL(singleStepChanged(QtProperty*,double)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,double)));
+ disconnect(manager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+}
+
+// QtLineEditFactory
+
+class QtLineEditFactoryPrivate : public EditorFactoryPrivate<QLineEdit>
+{
+ QtLineEditFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtLineEditFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QString &value);
+ void slotRegExpChanged(QtProperty *property, const QRegExp &regExp);
+ void slotSetValue(const QString &value);
+};
+
+void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QString &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QLineEdit *> itEditor( m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QLineEdit *editor = itEditor.next();
+ if (editor->text() != value)
+ editor->setText(value);
+ }
+}
+
+void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property,
+ const QRegExp &regExp)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtStringPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QLineEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QLineEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ const QValidator *oldValidator = editor->validator();
+ QValidator *newValidator = 0;
+ if (regExp.isValid()) {
+ newValidator = new QRegExpValidator(regExp, editor);
+ }
+ editor->setValidator(newValidator);
+ if (oldValidator)
+ delete oldValidator;
+ editor->blockSignals(false);
+ }
+}
+
+void QtLineEditFactoryPrivate::slotSetValue(const QString &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QLineEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QLineEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtStringPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtLineEditFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtLineEditFactory class provides QLineEdit widgets for
+ properties created by QtStringPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtStringPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtLineEditFactory::QtLineEditFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtStringPropertyManager>(parent), d_ptr(new QtLineEditFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtLineEditFactory::~QtLineEditFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QString)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QString)));
+ connect(manager, SIGNAL(regExpChanged(QtProperty*,QRegExp)),
+ this, SLOT(slotRegExpChanged(QtProperty*,QRegExp)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+
+ QLineEdit *editor = d_ptr->createEditor(property, parent);
+ QRegExp regExp = manager->regExp(property);
+ if (regExp.isValid()) {
+ QValidator *validator = new QRegExpValidator(regExp, editor);
+ editor->setValidator(validator);
+ }
+ editor->setText(manager->value(property));
+
+ connect(editor, SIGNAL(textEdited(QString)),
+ this, SLOT(slotSetValue(QString)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtLineEditFactory::disconnectPropertyManager(QtStringPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QString)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QString)));
+ disconnect(manager, SIGNAL(regExpChanged(QtProperty*,QRegExp)),
+ this, SLOT(slotRegExpChanged(QtProperty*,QRegExp)));
+}
+
+// QtDateEditFactory
+
+class QtDateEditFactoryPrivate : public EditorFactoryPrivate<QDateEdit>
+{
+ QtDateEditFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtDateEditFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QDate &value);
+ void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max);
+ void slotSetValue(const QDate &value);
+};
+
+void QtDateEditFactoryPrivate::slotPropertyChanged(QtProperty *property, const QDate &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QDateEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QDateEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setDate(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtDateEditFactoryPrivate::slotRangeChanged(QtProperty *property,
+ const QDate &min, const QDate &max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtDatePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QDateEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QDateEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setDateRange(min, max);
+ editor->setDate(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtDateEditFactoryPrivate::slotSetValue(const QDate &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QDateEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QDateEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtDatePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtDateEditFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDateEditFactory class provides QDateEdit widgets for
+ properties created by QtDatePropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtDatePropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtDateEditFactory::QtDateEditFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtDatePropertyManager>(parent), d_ptr(new QtDateEditFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtDateEditFactory::~QtDateEditFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDateEditFactory::connectPropertyManager(QtDatePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QDate)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QDate)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,QDate,QDate)),
+ this, SLOT(slotRangeChanged(QtProperty*,QDate,QDate)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtDateEditFactory::createEditor(QtDatePropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QDateEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setDisplayFormat(QtPropertyBrowserUtils::dateFormat());
+ editor->setCalendarPopup(true);
+ editor->setDateRange(manager->minimum(property), manager->maximum(property));
+ editor->setDate(manager->value(property));
+
+ connect(editor, SIGNAL(dateChanged(QDate)),
+ this, SLOT(slotSetValue(QDate)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDateEditFactory::disconnectPropertyManager(QtDatePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QDate)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QDate)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,QDate,QDate)),
+ this, SLOT(slotRangeChanged(QtProperty*,QDate,QDate)));
+}
+
+// QtTimeEditFactory
+
+class QtTimeEditFactoryPrivate : public EditorFactoryPrivate<QTimeEdit>
+{
+ QtTimeEditFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtTimeEditFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QTime &value);
+ void slotSetValue(const QTime &value);
+};
+
+void QtTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property, const QTime &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QTimeEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QTimeEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setTime(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtTimeEditFactoryPrivate::slotSetValue(const QTime &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QTimeEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QTimeEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtTimePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtTimeEditFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtTimeEditFactory class provides QTimeEdit widgets for
+ properties created by QtTimePropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtTimePropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtTimeEditFactory::QtTimeEditFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtTimePropertyManager>(parent), d_ptr(new QtTimeEditFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtTimeEditFactory::~QtTimeEditFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtTimeEditFactory::connectPropertyManager(QtTimePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QTime)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QTime)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtTimeEditFactory::createEditor(QtTimePropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QTimeEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setDisplayFormat(QtPropertyBrowserUtils::timeFormat());
+ editor->setTime(manager->value(property));
+
+ connect(editor, SIGNAL(timeChanged(QTime)),
+ this, SLOT(slotSetValue(QTime)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtTimeEditFactory::disconnectPropertyManager(QtTimePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QTime)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QTime)));
+}
+
+// QtDateTimeEditFactory
+
+class QtDateTimeEditFactoryPrivate : public EditorFactoryPrivate<QDateTimeEdit>
+{
+ QtDateTimeEditFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtDateTimeEditFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QDateTime &value);
+ void slotSetValue(const QDateTime &value);
+
+};
+
+void QtDateTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QDateTime &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QDateTimeEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QDateTimeEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setDateTime(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtDateTimeEditFactoryPrivate::slotSetValue(const QDateTime &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QDateTimeEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QDateTimeEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtDateTimePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtDateTimeEditFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDateTimeEditFactory class provides QDateTimeEdit
+ widgets for properties created by QtDateTimePropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtDateTimePropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtDateTimeEditFactory::QtDateTimeEditFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtDateTimePropertyManager>(parent), d_ptr(new QtDateTimeEditFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtDateTimeEditFactory::~QtDateTimeEditFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDateTimeEditFactory::connectPropertyManager(QtDateTimePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QDateTime)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QDateTime)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtDateTimeEditFactory::createEditor(QtDateTimePropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QDateTimeEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setDisplayFormat(QtPropertyBrowserUtils::dateTimeFormat());
+ editor->setDateTime(manager->value(property));
+
+ connect(editor, SIGNAL(dateTimeChanged(QDateTime)),
+ this, SLOT(slotSetValue(QDateTime)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDateTimeEditFactory::disconnectPropertyManager(QtDateTimePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QDateTime)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QDateTime)));
+}
+
+// QtKeySequenceEditorFactory
+
+class QtKeySequenceEditorFactoryPrivate : public EditorFactoryPrivate<QtKeySequenceEdit>
+{
+ QtKeySequenceEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QKeySequence &value);
+ void slotSetValue(const QKeySequence &value);
+};
+
+void QtKeySequenceEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QKeySequence &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QtKeySequenceEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QtKeySequenceEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setKeySequence(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtKeySequenceEditorFactoryPrivate::slotSetValue(const QKeySequence &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QtKeySequenceEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QtKeySequenceEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtKeySequencePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtKeySequenceEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtKeySequenceEditorFactory class provides editor
+ widgets for properties created by QtKeySequencePropertyManager objects.
+
+ \sa QtAbstractEditorFactory
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtKeySequenceEditorFactory::QtKeySequenceEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtKeySequencePropertyManager>(parent), d_ptr(new QtKeySequenceEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtKeySequenceEditorFactory::connectPropertyManager(QtKeySequencePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QKeySequence)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QKeySequence)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtKeySequenceEditorFactory::createEditor(QtKeySequencePropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QtKeySequenceEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setKeySequence(manager->value(property));
+
+ connect(editor, SIGNAL(keySequenceChanged(QKeySequence)),
+ this, SLOT(slotSetValue(QKeySequence)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtKeySequenceEditorFactory::disconnectPropertyManager(QtKeySequencePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QKeySequence)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QKeySequence)));
+}
+
+// QtCharEdit
+
+class QtCharEdit : public QWidget
+{
+ Q_OBJECT
+public:
+ QtCharEdit(QWidget *parent = 0);
+
+ QChar value() const;
+ bool eventFilter(QObject *o, QEvent *e);
+public Q_SLOTS:
+ void setValue(const QChar &value);
+Q_SIGNALS:
+ void valueChanged(const QChar &value);
+protected:
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
+ bool event(QEvent *e);
+private slots:
+ void slotClearChar();
+private:
+ void handleKeyEvent(QKeyEvent *e);
+
+ QChar m_value;
+ QLineEdit *m_lineEdit;
+};
+
+QtCharEdit::QtCharEdit(QWidget *parent)
+ : QWidget(parent), m_lineEdit(new QLineEdit(this))
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->addWidget(m_lineEdit);
+ layout->setMargin(0);
+ m_lineEdit->installEventFilter(this);
+ m_lineEdit->setReadOnly(true);
+ m_lineEdit->setFocusProxy(this);
+ setFocusPolicy(m_lineEdit->focusPolicy());
+ setAttribute(Qt::WA_InputMethodEnabled);
+}
+
+bool QtCharEdit::eventFilter(QObject *o, QEvent *e)
+{
+ if (o == m_lineEdit && e->type() == QEvent::ContextMenu) {
+ QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
+ QMenu *menu = m_lineEdit->createStandardContextMenu();
+ QList<QAction *> actions = menu->actions();
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ action->setShortcut(QKeySequence());
+ QString actionString = action->text();
+ const int pos = actionString.lastIndexOf(QLatin1Char('\t'));
+ if (pos > 0)
+ actionString = actionString.remove(pos, actionString.length() - pos);
+ action->setText(actionString);
+ }
+ QAction *actionBefore = 0;
+ if (actions.count() > 0)
+ actionBefore = actions[0];
+ QAction *clearAction = new QAction(tr("Clear Char"), menu);
+ menu->insertAction(actionBefore, clearAction);
+ menu->insertSeparator(actionBefore);
+ clearAction->setEnabled(!m_value.isNull());
+ connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearChar()));
+ menu->exec(c->globalPos());
+ delete menu;
+ e->accept();
+ return true;
+ }
+
+ return QWidget::eventFilter(o, e);
+}
+
+void QtCharEdit::slotClearChar()
+{
+ if (m_value.isNull())
+ return;
+ setValue(QChar());
+ emit valueChanged(m_value);
+}
+
+void QtCharEdit::handleKeyEvent(QKeyEvent *e)
+{
+ const int key = e->key();
+ switch (key) {
+ case Qt::Key_Control:
+ case Qt::Key_Shift:
+ case Qt::Key_Meta:
+ case Qt::Key_Alt:
+ case Qt::Key_Super_L:
+ case Qt::Key_Return:
+ return;
+ default:
+ break;
+ }
+
+ const QString text = e->text();
+ if (text.count() != 1)
+ return;
+
+ const QChar c = text.at(0);
+ if (!c.isPrint())
+ return;
+
+ if (m_value == c)
+ return;
+
+ m_value = c;
+ const QString str = m_value.isNull() ? QString() : QString(m_value);
+ m_lineEdit->setText(str);
+ e->accept();
+ emit valueChanged(m_value);
+}
+
+void QtCharEdit::setValue(const QChar &value)
+{
+ if (value == m_value)
+ return;
+
+ m_value = value;
+ QString str = value.isNull() ? QString() : QString(value);
+ m_lineEdit->setText(str);
+}
+
+QChar QtCharEdit::value() const
+{
+ return m_value;
+}
+
+void QtCharEdit::focusInEvent(QFocusEvent *e)
+{
+ m_lineEdit->event(e);
+ m_lineEdit->selectAll();
+ QWidget::focusInEvent(e);
+}
+
+void QtCharEdit::focusOutEvent(QFocusEvent *e)
+{
+ m_lineEdit->event(e);
+ QWidget::focusOutEvent(e);
+}
+
+void QtCharEdit::keyPressEvent(QKeyEvent *e)
+{
+ handleKeyEvent(e);
+ e->accept();
+}
+
+void QtCharEdit::keyReleaseEvent(QKeyEvent *e)
+{
+ m_lineEdit->event(e);
+}
+
+bool QtCharEdit::event(QEvent *e)
+{
+ switch(e->type()) {
+ case QEvent::Shortcut:
+ case QEvent::ShortcutOverride:
+ case QEvent::KeyRelease:
+ e->accept();
+ return true;
+ default:
+ break;
+ }
+ return QWidget::event(e);
+}
+
+// QtCharEditorFactory
+
+class QtCharEditorFactoryPrivate : public EditorFactoryPrivate<QtCharEdit>
+{
+ QtCharEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtCharEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QChar &value);
+ void slotSetValue(const QChar &value);
+
+};
+
+void QtCharEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QChar &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QtCharEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QtCharEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtCharEditorFactoryPrivate::slotSetValue(const QChar &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QtCharEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QtCharEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtCharPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtCharEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCharEditorFactory class provides editor
+ widgets for properties created by QtCharPropertyManager objects.
+
+ \sa QtAbstractEditorFactory
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtCharEditorFactory::QtCharEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtCharPropertyManager>(parent), d_ptr(new QtCharEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtCharEditorFactory::~QtCharEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCharEditorFactory::connectPropertyManager(QtCharPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QChar)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QChar)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtCharEditorFactory::createEditor(QtCharPropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QtCharEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setValue(manager->value(property));
+
+ connect(editor, SIGNAL(valueChanged(QChar)),
+ this, SLOT(slotSetValue(QChar)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QChar)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QChar)));
+}
+
+// QtEnumEditorFactory
+
+class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate<QComboBox>
+{
+ QtEnumEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtEnumEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, int value);
+ void slotEnumNamesChanged(QtProperty *property, const QStringList &);
+ void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &);
+ void slotSetValue(int value);
+};
+
+void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QComboBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setCurrentIndex(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property,
+ const QStringList &enumNames)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QMap<int, QIcon> enumIcons = manager->enumIcons(property);
+
+ QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QComboBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->clear();
+ editor->addItems(enumNames);
+ const int nameCount = enumNames.count();
+ for (int i = 0; i < nameCount; i++)
+ editor->setItemIcon(i, enumIcons.value(i));
+ editor->setCurrentIndex(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property,
+ const QMap<int, QIcon> &enumIcons)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ const QStringList enumNames = manager->enumNames(property);
+ QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QComboBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ const int nameCount = enumNames.count();
+ for (int i = 0; i < nameCount; i++)
+ editor->setItemIcon(i, enumIcons.value(i));
+ editor->setCurrentIndex(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtEnumEditorFactoryPrivate::slotSetValue(int value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QComboBox *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QComboBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtEnumEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtEnumEditorFactory class provides QComboBox widgets for
+ properties created by QtEnumPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtEnumPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtEnumEditorFactory::QtEnumEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtEnumPropertyManager>(parent), d_ptr(new QtEnumEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtEnumEditorFactory::~QtEnumEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ connect(manager, SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QComboBox *editor = d_ptr->createEditor(property, parent);
+ editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
+ editor->view()->setTextElideMode(Qt::ElideRight);
+ QStringList enumNames = manager->enumNames(property);
+ editor->addItems(enumNames);
+ QMap<int, QIcon> enumIcons = manager->enumIcons(property);
+ const int enumNamesCount = enumNames.count();
+ for (int i = 0; i < enumNamesCount; i++)
+ editor->setItemIcon(i, enumIcons.value(i));
+ editor->setCurrentIndex(manager->value(property));
+
+ connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtEnumEditorFactory::disconnectPropertyManager(QtEnumPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ disconnect(manager, SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+}
+
+// QtCursorEditorFactory
+
+Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase)
+
+class QtCursorEditorFactoryPrivate
+{
+ QtCursorEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtCursorEditorFactory)
+public:
+ QtCursorEditorFactoryPrivate();
+
+ void slotPropertyChanged(QtProperty *property, const QCursor &cursor);
+ void slotEnumChanged(QtProperty *property, int value);
+ void slotEditorDestroyed(QObject *object);
+
+ QtEnumEditorFactory *m_enumEditorFactory;
+ QtEnumPropertyManager *m_enumPropertyManager;
+
+ QMap<QtProperty *, QtProperty *> m_propertyToEnum;
+ QMap<QtProperty *, QtProperty *> m_enumToProperty;
+ QMap<QtProperty *, QList<QWidget *> > m_enumToEditors;
+ QMap<QWidget *, QtProperty *> m_editorToEnum;
+ bool m_updatingEnum;
+};
+
+QtCursorEditorFactoryPrivate::QtCursorEditorFactoryPrivate()
+ : m_updatingEnum(false)
+{
+
+}
+
+void QtCursorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, const QCursor &cursor)
+{
+ // update enum property
+ QtProperty *enumProp = m_propertyToEnum.value(property);
+ if (!enumProp)
+ return;
+
+ m_updatingEnum = true;
+ m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(cursor));
+ m_updatingEnum = false;
+}
+
+void QtCursorEditorFactoryPrivate::slotEnumChanged(QtProperty *property, int value)
+{
+ if (m_updatingEnum)
+ return;
+ // update cursor property
+ QtProperty *prop = m_enumToProperty.value(property);
+ if (!prop)
+ return;
+ QtCursorPropertyManager *cursorManager = q_ptr->propertyManager(prop);
+ if (!cursorManager)
+ return;
+#ifndef QT_NO_CURSOR
+ cursorManager->setValue(prop, QCursor(cursorDatabase()->valueToCursor(value)));
+#endif
+}
+
+void QtCursorEditorFactoryPrivate::slotEditorDestroyed(QObject *object)
+{
+ // remove from m_editorToEnum map;
+ // remove from m_enumToEditors map;
+ // if m_enumToEditors doesn't contains more editors delete enum property;
+ const QMap<QWidget *, QtProperty *>::ConstIterator ecend = m_editorToEnum.constEnd();
+ for (QMap<QWidget *, QtProperty *>::ConstIterator itEditor = m_editorToEnum.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QWidget *editor = itEditor.key();
+ QtProperty *enumProp = itEditor.value();
+ m_editorToEnum.remove(editor);
+ m_enumToEditors[enumProp].removeAll(editor);
+ if (m_enumToEditors[enumProp].isEmpty()) {
+ m_enumToEditors.remove(enumProp);
+ QtProperty *property = m_enumToProperty.value(enumProp);
+ m_enumToProperty.remove(enumProp);
+ m_propertyToEnum.remove(property);
+ delete enumProp;
+ }
+ return;
+ }
+}
+
+/*!
+ \class QtCursorEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCursorEditorFactory class provides QComboBox widgets for
+ properties created by QtCursorPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtCursorPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtCursorEditorFactory::QtCursorEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtCursorPropertyManager>(parent), d_ptr(new QtCursorEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_enumEditorFactory = new QtEnumEditorFactory(this);
+ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotEnumChanged(QtProperty*,int)));
+ d_ptr->m_enumEditorFactory->addPropertyManager(d_ptr->m_enumPropertyManager);
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtCursorEditorFactory::~QtCursorEditorFactory()
+{
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCursorEditorFactory::connectPropertyManager(QtCursorPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QCursor)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QCursor)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtCursorEditorFactory::createEditor(QtCursorPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QtProperty *enumProp = 0;
+ if (d_ptr->m_propertyToEnum.contains(property)) {
+ enumProp = d_ptr->m_propertyToEnum[property];
+ } else {
+ enumProp = d_ptr->m_enumPropertyManager->addProperty(property->propertyName());
+ d_ptr->m_enumPropertyManager->setEnumNames(enumProp, cursorDatabase()->cursorShapeNames());
+ d_ptr->m_enumPropertyManager->setEnumIcons(enumProp, cursorDatabase()->cursorShapeIcons());
+#ifndef QT_NO_CURSOR
+ d_ptr->m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(manager->value(property)));
+#endif
+ d_ptr->m_propertyToEnum[property] = enumProp;
+ d_ptr->m_enumToProperty[enumProp] = property;
+ }
+ QtAbstractEditorFactoryBase *af = d_ptr->m_enumEditorFactory;
+ QWidget *editor = af->createEditor(enumProp, parent);
+ d_ptr->m_enumToEditors[enumProp].append(editor);
+ d_ptr->m_editorToEnum[editor] = enumProp;
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCursorEditorFactory::disconnectPropertyManager(QtCursorPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QCursor)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QCursor)));
+}
+
+// QtColorEditWidget
+
+class QtColorEditWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ QtColorEditWidget(QWidget *parent);
+
+ bool eventFilter(QObject *obj, QEvent *ev);
+
+public Q_SLOTS:
+ void setValue(const QColor &value);
+
+private Q_SLOTS:
+ void buttonClicked();
+
+Q_SIGNALS:
+ void valueChanged(const QColor &value);
+
+private:
+ QColor m_color;
+ QLabel *m_pixmapLabel;
+ QLabel *m_label;
+ QToolButton *m_button;
+};
+
+QtColorEditWidget::QtColorEditWidget(QWidget *parent) :
+ QWidget(parent),
+ m_pixmapLabel(new QLabel),
+ m_label(new QLabel),
+ m_button(new QToolButton)
+{
+ QHBoxLayout *lt = new QHBoxLayout(this);
+ setupTreeViewEditorMargin(lt);
+ lt->setSpacing(0);
+ lt->addWidget(m_pixmapLabel);
+ lt->addWidget(m_label);
+ lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
+
+ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+ m_button->setFixedWidth(20);
+ setFocusProxy(m_button);
+ setFocusPolicy(m_button->focusPolicy());
+ m_button->setText(tr("..."));
+ m_button->installEventFilter(this);
+ connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+ lt->addWidget(m_button);
+ m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(m_color)));
+ m_label->setText(QtPropertyBrowserUtils::colorValueText(m_color));
+}
+
+void QtColorEditWidget::setValue(const QColor &c)
+{
+ if (m_color != c) {
+ m_color = c;
+ m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(c)));
+ m_label->setText(QtPropertyBrowserUtils::colorValueText(c));
+ }
+}
+
+void QtColorEditWidget::buttonClicked()
+{
+ const QColor newColor = QColorDialog::getColor(m_color, this, QString(), QColorDialog::ShowAlphaChannel);
+ if (newColor.isValid() && newColor != m_color) {
+ setValue(newColor);
+ emit valueChanged(m_color);
+ }
+}
+
+bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev)
+{
+ if (obj == m_button) {
+ switch (ev->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
+ switch (static_cast<const QKeyEvent*>(ev)->key()) {
+ case Qt::Key_Escape:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ ev->ignore();
+ return true;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return QWidget::eventFilter(obj, ev);
+}
+
+// QtColorEditorFactoryPrivate
+
+class QtColorEditorFactoryPrivate : public EditorFactoryPrivate<QtColorEditWidget>
+{
+ QtColorEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QColor &value);
+ void slotSetValue(const QColor &value);
+};
+
+void QtColorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QColor &value)
+{
+ const PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
+ if (it == m_createdEditors.end())
+ return;
+ QListIterator<QtColorEditWidget *> itEditor(it.value());
+
+ while (itEditor.hasNext())
+ itEditor.next()->setValue(value);
+}
+
+void QtColorEditorFactoryPrivate::slotSetValue(const QColor &value)
+{
+ QObject *object = q_ptr->sender();
+ const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtColorPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtColorEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtColorEditorFactory class provides color editing for
+ properties created by QtColorPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtColorPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtColorEditorFactory::QtColorEditorFactory(QObject *parent) :
+ QtAbstractEditorFactory<QtColorPropertyManager>(parent),
+ d_ptr(new QtColorEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtColorEditorFactory::~QtColorEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtColorEditorFactory::connectPropertyManager(QtColorPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QColor)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QColor)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtColorEditorFactory::createEditor(QtColorPropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QtColorEditWidget *editor = d_ptr->createEditor(property, parent);
+ editor->setValue(manager->value(property));
+ connect(editor, SIGNAL(valueChanged(QColor)), this, SLOT(slotSetValue(QColor)));
+ connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtColorEditorFactory::disconnectPropertyManager(QtColorPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QColor)), this, SLOT(slotPropertyChanged(QtProperty*,QColor)));
+}
+
+// QtFontEditWidget
+
+class QtFontEditWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ QtFontEditWidget(QWidget *parent);
+
+ bool eventFilter(QObject *obj, QEvent *ev);
+
+public Q_SLOTS:
+ void setValue(const QFont &value);
+
+private Q_SLOTS:
+ void buttonClicked();
+
+Q_SIGNALS:
+ void valueChanged(const QFont &value);
+
+private:
+ QFont m_font;
+ QLabel *m_pixmapLabel;
+ QLabel *m_label;
+ QToolButton *m_button;
+};
+
+QtFontEditWidget::QtFontEditWidget(QWidget *parent) :
+ QWidget(parent),
+ m_pixmapLabel(new QLabel),
+ m_label(new QLabel),
+ m_button(new QToolButton)
+{
+ QHBoxLayout *lt = new QHBoxLayout(this);
+ setupTreeViewEditorMargin(lt);
+ lt->setSpacing(0);
+ lt->addWidget(m_pixmapLabel);
+ lt->addWidget(m_label);
+ lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
+
+ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+ m_button->setFixedWidth(20);
+ setFocusProxy(m_button);
+ setFocusPolicy(m_button->focusPolicy());
+ m_button->setText(tr("..."));
+ m_button->installEventFilter(this);
+ connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+ lt->addWidget(m_button);
+ m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(m_font));
+ m_label->setText(QtPropertyBrowserUtils::fontValueText(m_font));
+}
+
+void QtFontEditWidget::setValue(const QFont &f)
+{
+ if (m_font != f) {
+ m_font = f;
+ m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(f));
+ m_label->setText(QtPropertyBrowserUtils::fontValueText(f));
+ }
+}
+
+void QtFontEditWidget::buttonClicked()
+{
+ bool ok = false;
+ QFont newFont = QFontDialog::getFont(&ok, m_font, this, tr("Select Font"));
+ if (ok && newFont != m_font) {
+ QFont f = m_font;
+ // prevent mask for unchanged attributes, don't change other attributes (like kerning, etc...)
+ if (m_font.family() != newFont.family())
+ f.setFamily(newFont.family());
+ if (m_font.pointSize() != newFont.pointSize())
+ f.setPointSize(newFont.pointSize());
+ if (m_font.bold() != newFont.bold())
+ f.setBold(newFont.bold());
+ if (m_font.italic() != newFont.italic())
+ f.setItalic(newFont.italic());
+ if (m_font.underline() != newFont.underline())
+ f.setUnderline(newFont.underline());
+ if (m_font.strikeOut() != newFont.strikeOut())
+ f.setStrikeOut(newFont.strikeOut());
+ setValue(f);
+ emit valueChanged(m_font);
+ }
+}
+
+bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev)
+{
+ if (obj == m_button) {
+ switch (ev->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
+ switch (static_cast<const QKeyEvent*>(ev)->key()) {
+ case Qt::Key_Escape:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ ev->ignore();
+ return true;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return QWidget::eventFilter(obj, ev);
+}
+
+// QtFontEditorFactoryPrivate
+
+class QtFontEditorFactoryPrivate : public EditorFactoryPrivate<QtFontEditWidget>
+{
+ QtFontEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtFontEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QFont &value);
+ void slotSetValue(const QFont &value);
+};
+
+void QtFontEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QFont &value)
+{
+ const PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
+ if (it == m_createdEditors.end())
+ return;
+ QListIterator<QtFontEditWidget *> itEditor(it.value());
+
+ while (itEditor.hasNext())
+ itEditor.next()->setValue(value);
+}
+
+void QtFontEditorFactoryPrivate::slotSetValue(const QFont &value)
+{
+ QObject *object = q_ptr->sender();
+ const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtFontPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtFontEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtFontEditorFactory class provides font editing for
+ properties created by QtFontPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtFontPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtFontEditorFactory::QtFontEditorFactory(QObject *parent) :
+ QtAbstractEditorFactory<QtFontPropertyManager>(parent),
+ d_ptr(new QtFontEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtFontEditorFactory::~QtFontEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtFontEditorFactory::connectPropertyManager(QtFontPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QFont)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QFont)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtFontEditorFactory::createEditor(QtFontPropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QtFontEditWidget *editor = d_ptr->createEditor(property, parent);
+ editor->setValue(manager->value(property));
+ connect(editor, SIGNAL(valueChanged(QFont)), this, SLOT(slotSetValue(QFont)));
+ connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont)));
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qteditorfactory.cpp"
+#include "qteditorfactory.moc"
diff --git a/src/shared/qtpropertybrowser/qteditorfactory.h b/src/shared/qtpropertybrowser/qteditorfactory.h
new file mode 100644
index 000000000..95564f02b
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qteditorfactory.h
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEDITORFACTORY_H
+#define QTEDITORFACTORY_H
+
+#include "qtpropertymanager.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtSpinBoxFactoryPrivate;
+
+class QtSpinBoxFactory : public QtAbstractEditorFactory<QtIntPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtSpinBoxFactory(QObject *parent = 0);
+ ~QtSpinBoxFactory();
+protected:
+ void connectPropertyManager(QtIntPropertyManager *manager);
+ QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtIntPropertyManager *manager);
+private:
+ QScopedPointer<QtSpinBoxFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSpinBoxFactory)
+ Q_DISABLE_COPY(QtSpinBoxFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtSliderFactoryPrivate;
+
+class QtSliderFactory : public QtAbstractEditorFactory<QtIntPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtSliderFactory(QObject *parent = 0);
+ ~QtSliderFactory();
+protected:
+ void connectPropertyManager(QtIntPropertyManager *manager);
+ QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtIntPropertyManager *manager);
+private:
+ QScopedPointer<QtSliderFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSliderFactory)
+ Q_DISABLE_COPY(QtSliderFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtScrollBarFactoryPrivate;
+
+class QtScrollBarFactory : public QtAbstractEditorFactory<QtIntPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtScrollBarFactory(QObject *parent = 0);
+ ~QtScrollBarFactory();
+protected:
+ void connectPropertyManager(QtIntPropertyManager *manager);
+ QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtIntPropertyManager *manager);
+private:
+ QScopedPointer<QtScrollBarFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtScrollBarFactory)
+ Q_DISABLE_COPY(QtScrollBarFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtCheckBoxFactoryPrivate;
+
+class QtCheckBoxFactory : public QtAbstractEditorFactory<QtBoolPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtCheckBoxFactory(QObject *parent = 0);
+ ~QtCheckBoxFactory();
+protected:
+ void connectPropertyManager(QtBoolPropertyManager *manager);
+ QWidget *createEditor(QtBoolPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtBoolPropertyManager *manager);
+private:
+ QScopedPointer<QtCheckBoxFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCheckBoxFactory)
+ Q_DISABLE_COPY(QtCheckBoxFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtDoubleSpinBoxFactoryPrivate;
+
+class QtDoubleSpinBoxFactory : public QtAbstractEditorFactory<QtDoublePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtDoubleSpinBoxFactory(QObject *parent = 0);
+ ~QtDoubleSpinBoxFactory();
+protected:
+ void connectPropertyManager(QtDoublePropertyManager *manager);
+ QWidget *createEditor(QtDoublePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtDoublePropertyManager *manager);
+private:
+ QScopedPointer<QtDoubleSpinBoxFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDoubleSpinBoxFactory)
+ Q_DISABLE_COPY(QtDoubleSpinBoxFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(double))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtLineEditFactoryPrivate;
+
+class QtLineEditFactory : public QtAbstractEditorFactory<QtStringPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtLineEditFactory(QObject *parent = 0);
+ ~QtLineEditFactory();
+protected:
+ void connectPropertyManager(QtStringPropertyManager *manager);
+ QWidget *createEditor(QtStringPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtStringPropertyManager *manager);
+private:
+ QScopedPointer<QtLineEditFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtLineEditFactory)
+ Q_DISABLE_COPY(QtLineEditFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtDateEditFactoryPrivate;
+
+class QtDateEditFactory : public QtAbstractEditorFactory<QtDatePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtDateEditFactory(QObject *parent = 0);
+ ~QtDateEditFactory();
+protected:
+ void connectPropertyManager(QtDatePropertyManager *manager);
+ QWidget *createEditor(QtDatePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtDatePropertyManager *manager);
+private:
+ QScopedPointer<QtDateEditFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDateEditFactory)
+ Q_DISABLE_COPY(QtDateEditFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *,
+ const QDate &, const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtTimeEditFactoryPrivate;
+
+class QtTimeEditFactory : public QtAbstractEditorFactory<QtTimePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtTimeEditFactory(QObject *parent = 0);
+ ~QtTimeEditFactory();
+protected:
+ void connectPropertyManager(QtTimePropertyManager *manager);
+ QWidget *createEditor(QtTimePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtTimePropertyManager *manager);
+private:
+ QScopedPointer<QtTimeEditFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtTimeEditFactory)
+ Q_DISABLE_COPY(QtTimeEditFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtDateTimeEditFactoryPrivate;
+
+class QtDateTimeEditFactory : public QtAbstractEditorFactory<QtDateTimePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtDateTimeEditFactory(QObject *parent = 0);
+ ~QtDateTimeEditFactory();
+protected:
+ void connectPropertyManager(QtDateTimePropertyManager *manager);
+ QWidget *createEditor(QtDateTimePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtDateTimePropertyManager *manager);
+private:
+ QScopedPointer<QtDateTimeEditFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDateTimeEditFactory)
+ Q_DISABLE_COPY(QtDateTimeEditFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDateTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDateTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtKeySequenceEditorFactoryPrivate;
+
+class QtKeySequenceEditorFactory : public QtAbstractEditorFactory<QtKeySequencePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtKeySequenceEditorFactory(QObject *parent = 0);
+ ~QtKeySequenceEditorFactory();
+protected:
+ void connectPropertyManager(QtKeySequencePropertyManager *manager);
+ QWidget *createEditor(QtKeySequencePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtKeySequencePropertyManager *manager);
+private:
+ QScopedPointer<QtKeySequenceEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtKeySequenceEditorFactory)
+ Q_DISABLE_COPY(QtKeySequenceEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QKeySequence &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QKeySequence &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtCharEditorFactoryPrivate;
+
+class QtCharEditorFactory : public QtAbstractEditorFactory<QtCharPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtCharEditorFactory(QObject *parent = 0);
+ ~QtCharEditorFactory();
+protected:
+ void connectPropertyManager(QtCharPropertyManager *manager);
+ QWidget *createEditor(QtCharPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtCharPropertyManager *manager);
+private:
+ QScopedPointer<QtCharEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCharEditorFactory)
+ Q_DISABLE_COPY(QtCharEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QChar &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QChar &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtEnumEditorFactoryPrivate;
+
+class QtEnumEditorFactory : public QtAbstractEditorFactory<QtEnumPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtEnumEditorFactory(QObject *parent = 0);
+ ~QtEnumEditorFactory();
+protected:
+ void connectPropertyManager(QtEnumPropertyManager *manager);
+ QWidget *createEditor(QtEnumPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtEnumPropertyManager *manager);
+private:
+ QScopedPointer<QtEnumEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtEnumEditorFactory)
+ Q_DISABLE_COPY(QtEnumEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *,
+ const QStringList &))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *,
+ const QMap<int, QIcon> &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtCursorEditorFactoryPrivate;
+
+class QtCursorEditorFactory : public QtAbstractEditorFactory<QtCursorPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtCursorEditorFactory(QObject *parent = 0);
+ ~QtCursorEditorFactory();
+protected:
+ void connectPropertyManager(QtCursorPropertyManager *manager);
+ QWidget *createEditor(QtCursorPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtCursorPropertyManager *manager);
+private:
+ QScopedPointer<QtCursorEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCursorEditorFactory)
+ Q_DISABLE_COPY(QtCursorEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QCursor &))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtColorEditorFactoryPrivate;
+
+class QtColorEditorFactory : public QtAbstractEditorFactory<QtColorPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtColorEditorFactory(QObject *parent = 0);
+ ~QtColorEditorFactory();
+protected:
+ void connectPropertyManager(QtColorPropertyManager *manager);
+ QWidget *createEditor(QtColorPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtColorPropertyManager *manager);
+private:
+ QScopedPointer<QtColorEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorEditorFactory)
+ Q_DISABLE_COPY(QtColorEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QColor &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QColor &))
+};
+
+class QtFontEditorFactoryPrivate;
+
+class QtFontEditorFactory : public QtAbstractEditorFactory<QtFontPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtFontEditorFactory(QObject *parent = 0);
+ ~QtFontEditorFactory();
+protected:
+ void connectPropertyManager(QtFontPropertyManager *manager);
+ QWidget *createEditor(QtFontPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtFontPropertyManager *manager);
+private:
+ QScopedPointer<QtFontEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtFontEditorFactory)
+ Q_DISABLE_COPY(QtFontEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QFont &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp
new file mode 100644
index 000000000..0633aa4f6
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp
@@ -0,0 +1,529 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgroupboxpropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QGroupBox>
+#include <QtCore/QTimer>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QtGroupBoxPropertyBrowserPrivate
+{
+ QtGroupBoxPropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtGroupBoxPropertyBrowser)
+public:
+
+ void init(QWidget *parent);
+
+ void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex);
+ void propertyRemoved(QtBrowserItem *index);
+ void propertyChanged(QtBrowserItem *index);
+ QWidget *createEditor(QtProperty *property, QWidget *parent) const
+ { return q_ptr->createEditor(property, parent); }
+
+ void slotEditorDestroyed();
+ void slotUpdate();
+
+ struct WidgetItem
+ {
+ WidgetItem() : widget(0), label(0), widgetLabel(0),
+ groupBox(0), layout(0), line(0), parent(0) { }
+ QWidget *widget; // can be null
+ QLabel *label;
+ QLabel *widgetLabel;
+ QGroupBox *groupBox;
+ QGridLayout *layout;
+ QFrame *line;
+ WidgetItem *parent;
+ QList<WidgetItem *> children;
+ };
+private:
+ void updateLater();
+ void updateItem(WidgetItem *item);
+ void insertRow(QGridLayout *layout, int row) const;
+ void removeRow(QGridLayout *layout, int row) const;
+
+ bool hasHeader(WidgetItem *item) const;
+
+ QMap<QtBrowserItem *, WidgetItem *> m_indexToItem;
+ QMap<WidgetItem *, QtBrowserItem *> m_itemToIndex;
+ QMap<QWidget *, WidgetItem *> m_widgetToItem;
+ QGridLayout *m_mainLayout;
+ QList<WidgetItem *> m_children;
+ QList<WidgetItem *> m_recreateQueue;
+};
+
+void QtGroupBoxPropertyBrowserPrivate::init(QWidget *parent)
+{
+ m_mainLayout = new QGridLayout();
+ parent->setLayout(m_mainLayout);
+ QLayoutItem *item = new QSpacerItem(0, 0,
+ QSizePolicy::Fixed, QSizePolicy::Expanding);
+ m_mainLayout->addItem(item, 0, 0);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::slotEditorDestroyed()
+{
+ QWidget *editor = qobject_cast<QWidget *>(q_ptr->sender());
+ if (!editor)
+ return;
+ if (!m_widgetToItem.contains(editor))
+ return;
+ m_widgetToItem[editor]->widget = 0;
+ m_widgetToItem.remove(editor);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::slotUpdate()
+{
+ QListIterator<WidgetItem *> itItem(m_recreateQueue);
+ while (itItem.hasNext()) {
+ WidgetItem *item = itItem.next();
+
+ WidgetItem *par = item->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(item);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(item);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+
+ if (item->widget) {
+ item->widget->setParent(w);
+ } else if (item->widgetLabel) {
+ item->widgetLabel->setParent(w);
+ } else {
+ item->widgetLabel = new QLabel(w);
+ }
+ int span = 1;
+ if (item->widget)
+ l->addWidget(item->widget, oldRow, 1, 1, 1);
+ else if (item->widgetLabel)
+ l->addWidget(item->widgetLabel, oldRow, 1, 1, 1);
+ else
+ span = 2;
+ item->label = new QLabel(w);
+ item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ l->addWidget(item->label, oldRow, 0, 1, span);
+
+ updateItem(item);
+ }
+ m_recreateQueue.clear();
+}
+
+void QtGroupBoxPropertyBrowserPrivate::updateLater()
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdate()));
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex)
+{
+ WidgetItem *afterItem = m_indexToItem.value(afterIndex);
+ WidgetItem *parentItem = m_indexToItem.value(index->parent());
+
+ WidgetItem *newItem = new WidgetItem();
+ newItem->parent = parentItem;
+
+ QGridLayout *layout = 0;
+ QWidget *parentWidget = 0;
+ int row = -1;
+ if (!afterItem) {
+ row = 0;
+ if (parentItem)
+ parentItem->children.insert(0, newItem);
+ else
+ m_children.insert(0, newItem);
+ } else {
+ if (parentItem) {
+ row = parentItem->children.indexOf(afterItem) + 1;
+ parentItem->children.insert(row, newItem);
+ } else {
+ row = m_children.indexOf(afterItem) + 1;
+ m_children.insert(row, newItem);
+ }
+ }
+ if (parentItem && hasHeader(parentItem))
+ row += 2;
+
+ if (!parentItem) {
+ layout = m_mainLayout;
+ parentWidget = q_ptr;;
+ } else {
+ if (!parentItem->groupBox) {
+ m_recreateQueue.removeAll(parentItem);
+ WidgetItem *par = parentItem->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(parentItem);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(parentItem);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+ parentItem->groupBox = new QGroupBox(w);
+ parentItem->layout = new QGridLayout();
+ parentItem->groupBox->setLayout(parentItem->layout);
+ if (parentItem->label) {
+ l->removeWidget(parentItem->label);
+ delete parentItem->label;
+ parentItem->label = 0;
+ }
+ if (parentItem->widget) {
+ l->removeWidget(parentItem->widget);
+ parentItem->widget->setParent(parentItem->groupBox);
+ parentItem->layout->addWidget(parentItem->widget, 0, 0, 1, 2);
+ parentItem->line = new QFrame(parentItem->groupBox);
+ } else if (parentItem->widgetLabel) {
+ l->removeWidget(parentItem->widgetLabel);
+ delete parentItem->widgetLabel;
+ parentItem->widgetLabel = 0;
+ }
+ if (parentItem->line) {
+ parentItem->line->setFrameShape(QFrame::HLine);
+ parentItem->line->setFrameShadow(QFrame::Sunken);
+ parentItem->layout->addWidget(parentItem->line, 1, 0, 1, 2);
+ }
+ l->addWidget(parentItem->groupBox, oldRow, 0, 1, 2);
+ updateItem(parentItem);
+ }
+ layout = parentItem->layout;
+ parentWidget = parentItem->groupBox;
+ }
+
+ newItem->label = new QLabel(parentWidget);
+ newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ newItem->widget = createEditor(index->property(), parentWidget);
+ if (!newItem->widget) {
+ newItem->widgetLabel = new QLabel(parentWidget);
+ } else {
+ QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed()));
+ m_widgetToItem[newItem->widget] = newItem;
+ }
+
+ insertRow(layout, row);
+ int span = 1;
+ if (newItem->widget)
+ layout->addWidget(newItem->widget, row, 1);
+ else if (newItem->widgetLabel)
+ layout->addWidget(newItem->widgetLabel, row, 1);
+ else
+ span = 2;
+ layout->addWidget(newItem->label, row, 0, 1, span);
+
+ m_itemToIndex[newItem] = index;
+ m_indexToItem[index] = newItem;
+
+ updateItem(newItem);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ m_indexToItem.remove(index);
+ m_itemToIndex.remove(item);
+
+ WidgetItem *parentItem = item->parent;
+
+ int row = -1;
+
+ if (parentItem) {
+ row = parentItem->children.indexOf(item);
+ parentItem->children.removeAt(row);
+ if (hasHeader(parentItem))
+ row += 2;
+ } else {
+ row = m_children.indexOf(item);
+ m_children.removeAt(row);
+ }
+
+ if (item->widget)
+ delete item->widget;
+ if (item->label)
+ delete item->label;
+ if (item->widgetLabel)
+ delete item->widgetLabel;
+ if (item->groupBox)
+ delete item->groupBox;
+
+ if (!parentItem) {
+ removeRow(m_mainLayout, row);
+ } else if (parentItem->children.count() != 0) {
+ removeRow(parentItem->layout, row);
+ } else {
+ WidgetItem *par = parentItem->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(parentItem);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(parentItem);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+
+ if (parentItem->widget) {
+ parentItem->widget->hide();
+ parentItem->widget->setParent(0);
+ } else if (parentItem->widgetLabel) {
+ parentItem->widgetLabel->hide();
+ parentItem->widgetLabel->setParent(0);
+ } else {
+ //parentItem->widgetLabel = new QLabel(w);
+ }
+ l->removeWidget(parentItem->groupBox);
+ delete parentItem->groupBox;
+ parentItem->groupBox = 0;
+ parentItem->line = 0;
+ parentItem->layout = 0;
+ if (!m_recreateQueue.contains(parentItem))
+ m_recreateQueue.append(parentItem);
+ updateLater();
+ }
+ m_recreateQueue.removeAll(item);
+
+ delete item;
+}
+
+void QtGroupBoxPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r >= row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for (QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+void QtGroupBoxPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r > row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for (QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+bool QtGroupBoxPropertyBrowserPrivate::hasHeader(WidgetItem *item) const
+{
+ if (item->widget)
+ return true;
+ return false;
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ updateItem(item);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::updateItem(WidgetItem *item)
+{
+ QtProperty *property = m_itemToIndex[item]->property();
+ if (item->groupBox) {
+ QFont font = item->groupBox->font();
+ font.setUnderline(property->isModified());
+ item->groupBox->setFont(font);
+ item->groupBox->setTitle(property->propertyName());
+ item->groupBox->setToolTip(property->toolTip());
+ item->groupBox->setStatusTip(property->statusTip());
+ item->groupBox->setWhatsThis(property->whatsThis());
+ item->groupBox->setEnabled(property->isEnabled());
+ }
+ if (item->label) {
+ QFont font = item->label->font();
+ font.setUnderline(property->isModified());
+ item->label->setFont(font);
+ item->label->setText(property->propertyName());
+ item->label->setToolTip(property->toolTip());
+ item->label->setStatusTip(property->statusTip());
+ item->label->setWhatsThis(property->whatsThis());
+ item->label->setEnabled(property->isEnabled());
+ }
+ if (item->widgetLabel) {
+ QFont font = item->widgetLabel->font();
+ font.setUnderline(false);
+ item->widgetLabel->setFont(font);
+ item->widgetLabel->setText(property->valueText());
+ item->widgetLabel->setEnabled(property->isEnabled());
+ }
+ if (item->widget) {
+ QFont font = item->widget->font();
+ font.setUnderline(false);
+ item->widget->setFont(font);
+ item->widget->setEnabled(property->isEnabled());
+ item->widget->setToolTip(property->valueText());
+ }
+ //item->setIcon(1, property->valueIcon());
+}
+
+
+
+/*!
+ \class QtGroupBoxPropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtGroupBoxPropertyBrowser class provides a QGroupBox
+ based property browser.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ QtGroupBoxPropertyBrowser provides group boxes for all nested
+ properties, i.e. subproperties are enclosed by a group box with
+ the parent property's name as its title. For example:
+
+ \image qtgroupboxpropertybrowser.png
+
+ Use the QtAbstractPropertyBrowser API to add, insert and remove
+ properties from an instance of the QtGroupBoxPropertyBrowser
+ class. The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class.
+
+ \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser
+*/
+
+/*!
+ Creates a property browser with the given \a parent.
+*/
+QtGroupBoxPropertyBrowser::QtGroupBoxPropertyBrowser(QWidget *parent)
+ : QtAbstractPropertyBrowser(parent), d_ptr(new QtGroupBoxPropertyBrowserPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->init(this);
+}
+
+/*!
+ Destroys this property browser.
+
+ Note that the properties that were inserted into this browser are
+ \e not destroyed since they may still be used in other
+ browsers. The properties are owned by the manager that created
+ them.
+
+ \sa QtProperty, QtAbstractPropertyManager
+*/
+QtGroupBoxPropertyBrowser::~QtGroupBoxPropertyBrowser()
+{
+ const QMap<QtGroupBoxPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator icend = d_ptr->m_itemToIndex.constEnd();
+ for (QMap<QtGroupBoxPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it)
+ delete it.key();
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem)
+{
+ d_ptr->propertyInserted(item, afterItem);
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemRemoved(QtBrowserItem *item)
+{
+ d_ptr->propertyRemoved(item);
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemChanged(QtBrowserItem *item)
+{
+ d_ptr->propertyChanged(item);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgroupboxpropertybrowser.cpp"
diff --git a/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h
new file mode 100644
index 000000000..d53d9492d
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGROUPBOXPROPERTYBROWSER_H
+#define QTGROUPBOXPROPERTYBROWSER_H
+
+#include "qtpropertybrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGroupBoxPropertyBrowserPrivate;
+
+class QtGroupBoxPropertyBrowser : public QtAbstractPropertyBrowser
+{
+ Q_OBJECT
+public:
+
+ QtGroupBoxPropertyBrowser(QWidget *parent = 0);
+ ~QtGroupBoxPropertyBrowser();
+
+protected:
+ virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem);
+ virtual void itemRemoved(QtBrowserItem *item);
+ virtual void itemChanged(QtBrowserItem *item);
+
+private:
+
+ QScopedPointer<QtGroupBoxPropertyBrowserPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGroupBoxPropertyBrowser)
+ Q_DISABLE_COPY(QtGroupBoxPropertyBrowser)
+ Q_PRIVATE_SLOT(d_func(), void slotUpdate())
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed())
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtpropertybrowser.cpp
new file mode 100644
index 000000000..3771ef686
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.cpp
@@ -0,0 +1,1955 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtpropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtCore/QMap>
+#include <QtGui/QIcon>
+
+#if defined(Q_CC_MSVC)
+# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QtPropertyPrivate
+{
+public:
+ QtPropertyPrivate(QtAbstractPropertyManager *manager) : m_enabled(true), m_modified(false), m_manager(manager) {}
+ QtProperty *q_ptr;
+
+ QSet<QtProperty *> m_parentItems;
+ QList<QtProperty *> m_subItems;
+
+ QString m_toolTip;
+ QString m_statusTip;
+ QString m_whatsThis;
+ QString m_name;
+ bool m_enabled;
+ bool m_modified;
+
+ QtAbstractPropertyManager * const m_manager;
+};
+
+class QtAbstractPropertyManagerPrivate
+{
+ QtAbstractPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtAbstractPropertyManager)
+public:
+ void propertyDestroyed(QtProperty *property);
+ void propertyChanged(QtProperty *property) const;
+ void propertyRemoved(QtProperty *property,
+ QtProperty *parentProperty) const;
+ void propertyInserted(QtProperty *property, QtProperty *parentProperty,
+ QtProperty *afterProperty) const;
+
+ QSet<QtProperty *> m_properties;
+};
+
+/*!
+ \class QtProperty
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtProperty class encapsulates an instance of a property.
+
+ Properties are created by objects of QtAbstractPropertyManager
+ subclasses; a manager can create properties of a given type, and
+ is used in conjunction with the QtAbstractPropertyBrowser class. A
+ property is always owned by the manager that created it, which can
+ be retrieved using the propertyManager() function.
+
+ QtProperty contains the most common property attributes, and
+ provides functions for retrieving as well as setting their values:
+
+ \table
+ \header \o Getter \o Setter
+ \row
+ \o propertyName() \o setPropertyName()
+ \row
+ \o statusTip() \o setStatusTip()
+ \row
+ \o toolTip() \o setToolTip()
+ \row
+ \o whatsThis() \o setWhatsThis()
+ \row
+ \o isEnabled() \o setEnabled()
+ \row
+ \o isModified() \o setModified()
+ \row
+ \o valueText() \o Nop
+ \row
+ \o valueIcon() \o Nop
+ \endtable
+
+ It is also possible to nest properties: QtProperty provides the
+ addSubProperty(), insertSubProperty() and removeSubProperty() functions to
+ manipulate the set of subproperties. Use the subProperties()
+ function to retrieve a property's current set of subproperties.
+ Note that nested properties are not owned by the parent property,
+ i.e. each subproperty is owned by the manager that created it.
+
+ \sa QtAbstractPropertyManager, QtBrowserItem
+*/
+
+/*!
+ Creates a property with the given \a manager.
+
+ This constructor is only useful when creating a custom QtProperty
+ subclass (e.g. QtVariantProperty). To create a regular QtProperty
+ object, use the QtAbstractPropertyManager::addProperty()
+ function instead.
+
+ \sa QtAbstractPropertyManager::addProperty()
+*/
+QtProperty::QtProperty(QtAbstractPropertyManager *manager)
+ : d_ptr(new QtPropertyPrivate(manager))
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this property.
+
+ Note that subproperties are detached but not destroyed, i.e. they
+ can still be used in another context.
+
+ \sa QtAbstractPropertyManager::clear()
+
+*/
+QtProperty::~QtProperty()
+{
+ QSetIterator<QtProperty *> itParent(d_ptr->m_parentItems);
+ while (itParent.hasNext()) {
+ QtProperty *property = itParent.next();
+ property->d_ptr->m_manager->d_ptr->propertyRemoved(this, property);
+ }
+
+ d_ptr->m_manager->d_ptr->propertyDestroyed(this);
+
+ QListIterator<QtProperty *> itChild(d_ptr->m_subItems);
+ while (itChild.hasNext()) {
+ QtProperty *property = itChild.next();
+ property->d_ptr->m_parentItems.remove(this);
+ }
+
+ itParent.toFront();
+ while (itParent.hasNext()) {
+ QtProperty *property = itParent.next();
+ property->d_ptr->m_subItems.removeAll(this);
+ }
+}
+
+/*!
+ Returns the set of subproperties.
+
+ Note that subproperties are not owned by \e this property, but by
+ the manager that created them.
+
+ \sa insertSubProperty(), removeSubProperty()
+*/
+QList<QtProperty *> QtProperty::subProperties() const
+{
+ return d_ptr->m_subItems;
+}
+
+/*!
+ Returns a pointer to the manager that owns this property.
+*/
+QtAbstractPropertyManager *QtProperty::propertyManager() const
+{
+ return d_ptr->m_manager;
+}
+
+/*!
+ Returns the property's tool tip.
+
+ \sa setToolTip()
+*/
+QString QtProperty::toolTip() const
+{
+ return d_ptr->m_toolTip;
+}
+
+/*!
+ Returns the property's status tip.
+
+ \sa setStatusTip()
+*/
+QString QtProperty::statusTip() const
+{
+ return d_ptr->m_statusTip;
+}
+
+/*!
+ Returns the property's "What's This" help text.
+
+ \sa setWhatsThis()
+*/
+QString QtProperty::whatsThis() const
+{
+ return d_ptr->m_whatsThis;
+}
+
+/*!
+ Returns the property's name.
+
+ \sa setPropertyName()
+*/
+QString QtProperty::propertyName() const
+{
+ return d_ptr->m_name;
+}
+
+/*!
+ Returns whether the property is enabled.
+
+ \sa setEnabled()
+*/
+bool QtProperty::isEnabled() const
+{
+ return d_ptr->m_enabled;
+}
+
+/*!
+ Returns whether the property is modified.
+
+ \sa setModified()
+*/
+bool QtProperty::isModified() const
+{
+ return d_ptr->m_modified;
+}
+
+/*!
+ Returns whether the property has a value.
+
+ \sa QtAbstractPropertyManager::hasValue()
+*/
+bool QtProperty::hasValue() const
+{
+ return d_ptr->m_manager->hasValue(this);
+}
+
+/*!
+ Returns an icon representing the current state of this property.
+
+ If the given property type can not generate such an icon, this
+ function returns an invalid icon.
+
+ \sa QtAbstractPropertyManager::valueIcon()
+*/
+QIcon QtProperty::valueIcon() const
+{
+ return d_ptr->m_manager->valueIcon(this);
+}
+
+/*!
+ Returns a string representing the current state of this property.
+
+ If the given property type can not generate such a string, this
+ function returns an empty string.
+
+ \sa QtAbstractPropertyManager::valueText()
+*/
+QString QtProperty::valueText() const
+{
+ return d_ptr->m_manager->valueText(this);
+}
+
+/*!
+ Sets the property's tool tip to the given \a text.
+
+ \sa toolTip()
+*/
+void QtProperty::setToolTip(const QString &text)
+{
+ if (d_ptr->m_toolTip == text)
+ return;
+
+ d_ptr->m_toolTip = text;
+ propertyChanged();
+}
+
+/*!
+ Sets the property's status tip to the given \a text.
+
+ \sa statusTip()
+*/
+void QtProperty::setStatusTip(const QString &text)
+{
+ if (d_ptr->m_statusTip == text)
+ return;
+
+ d_ptr->m_statusTip = text;
+ propertyChanged();
+}
+
+/*!
+ Sets the property's "What's This" help text to the given \a text.
+
+ \sa whatsThis()
+*/
+void QtProperty::setWhatsThis(const QString &text)
+{
+ if (d_ptr->m_whatsThis == text)
+ return;
+
+ d_ptr->m_whatsThis = text;
+ propertyChanged();
+}
+
+/*!
+ \fn void QtProperty::setPropertyName(const QString &name)
+
+ Sets the property's name to the given \a name.
+
+ \sa propertyName()
+*/
+void QtProperty::setPropertyName(const QString &text)
+{
+ if (d_ptr->m_name == text)
+ return;
+
+ d_ptr->m_name = text;
+ propertyChanged();
+}
+
+/*!
+ Enables or disables the property according to the passed \a enable value.
+
+ \sa isEnabled()
+*/
+void QtProperty::setEnabled(bool enable)
+{
+ if (d_ptr->m_enabled == enable)
+ return;
+
+ d_ptr->m_enabled = enable;
+ propertyChanged();
+}
+
+/*!
+ Sets the property's modified state according to the passed \a modified value.
+
+ \sa isModified()
+*/
+void QtProperty::setModified(bool modified)
+{
+ if (d_ptr->m_modified == modified)
+ return;
+
+ d_ptr->m_modified = modified;
+ propertyChanged();
+}
+
+/*!
+ Appends the given \a property to this property's subproperties.
+
+ If the given \a property already is added, this function does
+ nothing.
+
+ \sa insertSubProperty(), removeSubProperty()
+*/
+void QtProperty::addSubProperty(QtProperty *property)
+{
+ QtProperty *after = 0;
+ if (d_ptr->m_subItems.count() > 0)
+ after = d_ptr->m_subItems.last();
+ insertSubProperty(property, after);
+}
+
+/*!
+ \fn void QtProperty::insertSubProperty(QtProperty *property, QtProperty *precedingProperty)
+
+ Inserts the given \a property after the specified \a
+ precedingProperty into this property's list of subproperties. If
+ \a precedingProperty is 0, the specified \a property is inserted
+ at the beginning of the list.
+
+ If the given \a property already is inserted, this function does
+ nothing.
+
+ \sa addSubProperty(), removeSubProperty()
+*/
+void QtProperty::insertSubProperty(QtProperty *property,
+ QtProperty *afterProperty)
+{
+ if (!property)
+ return;
+
+ if (property == this)
+ return;
+
+ // traverse all children of item. if this item is a child of item then cannot add.
+ QList<QtProperty *> pendingList = property->subProperties();
+ QMap<QtProperty *, bool> visited;
+ while (!pendingList.isEmpty()) {
+ QtProperty *i = pendingList.first();
+ if (i == this)
+ return;
+ pendingList.removeFirst();
+ if (visited.contains(i))
+ continue;
+ visited[i] = true;
+ pendingList += i->subProperties();
+ }
+
+ pendingList = subProperties();
+ int pos = 0;
+ int newPos = 0;
+ QtProperty *properAfterProperty = 0;
+ while (pos < pendingList.count()) {
+ QtProperty *i = pendingList.at(pos);
+ if (i == property)
+ return; // if item is already inserted in this item then cannot add.
+ if (i == afterProperty) {
+ newPos = pos + 1;
+ properAfterProperty = afterProperty;
+ }
+ pos++;
+ }
+
+ d_ptr->m_subItems.insert(newPos, property);
+ property->d_ptr->m_parentItems.insert(this);
+
+ d_ptr->m_manager->d_ptr->propertyInserted(property, this, properAfterProperty);
+}
+
+/*!
+ Removes the given \a property from the list of subproperties
+ without deleting it.
+
+ \sa addSubProperty(), insertSubProperty()
+*/
+void QtProperty::removeSubProperty(QtProperty *property)
+{
+ if (!property)
+ return;
+
+ d_ptr->m_manager->d_ptr->propertyRemoved(property, this);
+
+ QList<QtProperty *> pendingList = subProperties();
+ int pos = 0;
+ while (pos < pendingList.count()) {
+ if (pendingList.at(pos) == property) {
+ d_ptr->m_subItems.removeAt(pos);
+ property->d_ptr->m_parentItems.remove(this);
+
+ return;
+ }
+ pos++;
+ }
+}
+
+/*!
+ \internal
+*/
+void QtProperty::propertyChanged()
+{
+ d_ptr->m_manager->d_ptr->propertyChanged(this);
+}
+
+////////////////////////////////
+
+void QtAbstractPropertyManagerPrivate::propertyDestroyed(QtProperty *property)
+{
+ if (m_properties.contains(property)) {
+ emit q_ptr->propertyDestroyed(property);
+ q_ptr->uninitializeProperty(property);
+ m_properties.remove(property);
+ }
+}
+
+void QtAbstractPropertyManagerPrivate::propertyChanged(QtProperty *property) const
+{
+ emit q_ptr->propertyChanged(property);
+}
+
+void QtAbstractPropertyManagerPrivate::propertyRemoved(QtProperty *property,
+ QtProperty *parentProperty) const
+{
+ emit q_ptr->propertyRemoved(property, parentProperty);
+}
+
+void QtAbstractPropertyManagerPrivate::propertyInserted(QtProperty *property,
+ QtProperty *parentProperty, QtProperty *afterProperty) const
+{
+ emit q_ptr->propertyInserted(property, parentProperty, afterProperty);
+}
+
+/*!
+ \class QtAbstractPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtAbstractPropertyManager provides an interface for
+ property managers.
+
+ A manager can create and manage properties of a given type, and is
+ used in conjunction with the QtAbstractPropertyBrowser class.
+
+ When using a property browser widget, the properties are created
+ and managed by implementations of the QtAbstractPropertyManager
+ class. To ensure that the properties' values will be displayed
+ using suitable editing widgets, the managers are associated with
+ objects of QtAbstractEditorFactory subclasses. The property browser
+ will use these associations to determine which factories it should
+ use to create the preferred editing widgets.
+
+ The QtAbstractPropertyManager class provides common functionality
+ like creating a property using the addProperty() function, and
+ retrieving the properties created by the manager using the
+ properties() function. The class also provides signals that are
+ emitted when the manager's properties change: propertyInserted(),
+ propertyRemoved(), propertyChanged() and propertyDestroyed().
+
+ QtAbstractPropertyManager subclasses are supposed to provide their
+ own type specific API. Note that several ready-made
+ implementations are available:
+
+ \list
+ \o QtBoolPropertyManager
+ \o QtColorPropertyManager
+ \o QtDatePropertyManager
+ \o QtDateTimePropertyManager
+ \o QtDoublePropertyManager
+ \o QtEnumPropertyManager
+ \o QtFlagPropertyManager
+ \o QtFontPropertyManager
+ \o QtGroupPropertyManager
+ \o QtIntPropertyManager
+ \o QtPointPropertyManager
+ \o QtRectPropertyManager
+ \o QtSizePropertyManager
+ \o QtSizePolicyPropertyManager
+ \o QtStringPropertyManager
+ \o QtTimePropertyManager
+ \o QtVariantPropertyManager
+ \endlist
+
+ \sa QtAbstractEditorFactoryBase, QtAbstractPropertyBrowser, QtProperty
+*/
+
+/*!
+ \fn void QtAbstractPropertyManager::propertyInserted(QtProperty *newProperty,
+ QtProperty *parentProperty, QtProperty *precedingProperty)
+
+ This signal is emitted when a new subproperty is inserted into an
+ existing property, passing pointers to the \a newProperty, \a
+ parentProperty and \a precedingProperty as parameters.
+
+ If \a precedingProperty is 0, the \a newProperty was inserted at
+ the beginning of the \a parentProperty's subproperties list.
+
+ Note that signal is emitted only if the \a parentProperty is created
+ by this manager.
+
+ \sa QtAbstractPropertyBrowser::itemInserted()
+*/
+
+/*!
+ \fn void QtAbstractPropertyManager::propertyChanged(QtProperty *property)
+
+ This signal is emitted whenever a property's data changes, passing
+ a pointer to the \a property as parameter.
+
+ Note that signal is only emitted for properties that are created by
+ this manager.
+
+ \sa QtAbstractPropertyBrowser::itemChanged()
+*/
+
+/*!
+ \fn void QtAbstractPropertyManager::propertyRemoved(QtProperty *property, QtProperty *parent)
+
+ This signal is emitted when a subproperty is removed, passing
+ pointers to the removed \a property and the \a parent property as
+ parameters.
+
+ Note that signal is emitted only when the \a parent property is
+ created by this manager.
+
+ \sa QtAbstractPropertyBrowser::itemRemoved()
+*/
+
+/*!
+ \fn void QtAbstractPropertyManager::propertyDestroyed(QtProperty *property)
+
+ This signal is emitted when the specified \a property is about to
+ be destroyed.
+
+ Note that signal is only emitted for properties that are created
+ by this manager.
+
+ \sa clear(), uninitializeProperty()
+*/
+
+/*!
+ \fn void QtAbstractPropertyBrowser::currentItemChanged(QtBrowserItem *current)
+
+ This signal is emitted when the current item changes. The current item is specified by \a current.
+
+ \sa QtAbstractPropertyBrowser::setCurrentItem()
+*/
+
+/*!
+ Creates an abstract property manager with the given \a parent.
+*/
+QtAbstractPropertyManager::QtAbstractPropertyManager(QObject *parent)
+ : QObject(parent), d_ptr(new QtAbstractPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys the manager. All properties created by the manager are
+ destroyed.
+*/
+QtAbstractPropertyManager::~QtAbstractPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Destroys all the properties that this manager has created.
+
+ \sa propertyDestroyed(), uninitializeProperty()
+*/
+void QtAbstractPropertyManager::clear() const
+{
+ while (!properties().isEmpty()) {
+ QSetIterator<QtProperty *> itProperty(properties());
+ QtProperty *prop = itProperty.next();
+ delete prop;
+ }
+}
+
+/*!
+ Returns the set of properties created by this manager.
+
+ \sa addProperty()
+*/
+QSet<QtProperty *> QtAbstractPropertyManager::properties() const
+{
+ return d_ptr->m_properties;
+}
+
+/*!
+ Returns whether the given \a property has a value.
+
+ The default implementation of this function returns true.
+
+ \sa QtProperty::hasValue()
+*/
+bool QtAbstractPropertyManager::hasValue(const QtProperty *property) const
+{
+ Q_UNUSED(property)
+ return true;
+}
+
+/*!
+ Returns an icon representing the current state of the given \a
+ property.
+
+ The default implementation of this function returns an invalid
+ icon.
+
+ \sa QtProperty::valueIcon()
+*/
+QIcon QtAbstractPropertyManager::valueIcon(const QtProperty *property) const
+{
+ Q_UNUSED(property)
+ return QIcon();
+}
+
+/*!
+ Returns a string representing the current state of the given \a
+ property.
+
+ The default implementation of this function returns an empty
+ string.
+
+ \sa QtProperty::valueText()
+*/
+QString QtAbstractPropertyManager::valueText(const QtProperty *property) const
+{
+ Q_UNUSED(property)
+ return QString();
+}
+
+/*!
+ Creates a property with the given \a name which then is owned by this manager.
+
+ Internally, this function calls the createProperty() and
+ initializeProperty() functions.
+
+ \sa initializeProperty(), properties()
+*/
+QtProperty *QtAbstractPropertyManager::addProperty(const QString &name)
+{
+ QtProperty *property = createProperty();
+ if (property) {
+ property->setPropertyName(name);
+ d_ptr->m_properties.insert(property);
+ initializeProperty(property);
+ }
+ return property;
+}
+
+/*!
+ Creates a property.
+
+ The base implementation produce QtProperty instances; Reimplement
+ this function to make this manager produce objects of a QtProperty
+ subclass.
+
+ \sa addProperty(), initializeProperty()
+*/
+QtProperty *QtAbstractPropertyManager::createProperty()
+{
+ return new QtProperty(this);
+}
+
+/*!
+ \fn void QtAbstractPropertyManager::initializeProperty(QtProperty *property) = 0
+
+ This function is called whenever a new valid property pointer has
+ been created, passing the pointer as parameter.
+
+ The purpose is to let the manager know that the \a property has
+ been created so that it can provide additional attributes for the
+ new property, e.g. QtIntPropertyManager adds \l
+ {QtIntPropertyManager::value()}{value}, \l
+ {QtIntPropertyManager::minimum()}{minimum} and \l
+ {QtIntPropertyManager::maximum()}{maximum} attributes. Since each manager
+ subclass adds type specific attributes, this function is pure
+ virtual and must be reimplemented when deriving from the
+ QtAbstractPropertyManager class.
+
+ \sa addProperty(), createProperty()
+*/
+
+/*!
+ This function is called just before the specified \a property is destroyed.
+
+ The purpose is to let the property manager know that the \a
+ property is being destroyed so that it can remove the property's
+ additional attributes.
+
+ \sa clear(), propertyDestroyed()
+*/
+void QtAbstractPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ Q_UNUSED(property)
+}
+
+////////////////////////////////////
+
+/*!
+ \class QtAbstractEditorFactoryBase
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtAbstractEditorFactoryBase provides an interface for
+ editor factories.
+
+ An editor factory is a class that is able to create an editing
+ widget of a specified type (e.g. line edits or comboboxes) for a
+ given QtProperty object, and it is used in conjunction with the
+ QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.
+
+ When using a property browser widget, the properties are created
+ and managed by implementations of the QtAbstractPropertyManager
+ class. To ensure that the properties' values will be displayed
+ using suitable editing widgets, the managers are associated with
+ objects of QtAbstractEditorFactory subclasses. The property browser
+ will use these associations to determine which factories it should
+ use to create the preferred editing widgets.
+
+ Typically, an editor factory is created by subclassing the
+ QtAbstractEditorFactory template class which inherits
+ QtAbstractEditorFactoryBase. But note that several ready-made
+ implementations are available:
+
+ \list
+ \o QtCheckBoxFactory
+ \o QtDateEditFactory
+ \o QtDateTimeEditFactory
+ \o QtDoubleSpinBoxFactory
+ \o QtEnumEditorFactory
+ \o QtLineEditFactory
+ \o QtScrollBarFactory
+ \o QtSliderFactory
+ \o QtSpinBoxFactory
+ \o QtTimeEditFactory
+ \o QtVariantEditorFactory
+ \endlist
+
+ \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser
+*/
+
+/*!
+ \fn virtual QWidget *QtAbstractEditorFactoryBase::createEditor(QtProperty *property,
+ QWidget *parent) = 0
+
+ Creates an editing widget (with the given \a parent) for the given
+ \a property.
+
+ This function is reimplemented in QtAbstractEditorFactory template class
+ which also provides a pure virtual convenience overload of this
+ function enabling access to the property's manager.
+
+ \sa QtAbstractEditorFactory::createEditor()
+*/
+
+/*!
+ \fn QtAbstractEditorFactoryBase::QtAbstractEditorFactoryBase(QObject *parent = 0)
+
+ Creates an abstract editor factory with the given \a parent.
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactoryBase::breakConnection(QtAbstractPropertyManager *manager) = 0
+
+ \internal
+
+ Detaches property manager from factory.
+ This method is reimplemented in QtAbstractEditorFactory template subclass.
+ You don't need to reimplement it in your subclasses. Instead implement more convenient
+ QtAbstractEditorFactory::disconnectPropertyManager() which gives you access to particular manager subclass.
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactoryBase::managerDestroyed(QObject *manager) = 0
+
+ \internal
+
+ This method is called when property manager is being destroyed.
+ Basically it notifies factory not to produce editors for properties owned by \a manager.
+ You don't need to reimplement it in your subclass. This method is implemented in
+ QtAbstractEditorFactory template subclass.
+*/
+
+/*!
+ \class QtAbstractEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtAbstractEditorFactory is the base template class for editor
+ factories.
+
+ An editor factory is a class that is able to create an editing
+ widget of a specified type (e.g. line edits or comboboxes) for a
+ given QtProperty object, and it is used in conjunction with the
+ QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.
+
+ Note that the QtAbstractEditorFactory functions are using the
+ PropertyManager template argument class which can be any
+ QtAbstractPropertyManager subclass. For example:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 0
+
+ Note that QtSpinBoxFactory by definition creates editing widgets
+ \e only for properties created by QtIntPropertyManager.
+
+ When using a property browser widget, the properties are created
+ and managed by implementations of the QtAbstractPropertyManager
+ class. To ensure that the properties' values will be displayed
+ using suitable editing widgets, the managers are associated with
+ objects of QtAbstractEditorFactory subclasses. The property browser will
+ use these associations to determine which factories it should use
+ to create the preferred editing widgets.
+
+ A QtAbstractEditorFactory object is capable of producing editors for
+ several property managers at the same time. To create an
+ association between this factory and a given manager, use the
+ addPropertyManager() function. Use the removePropertyManager() function to make
+ this factory stop producing editors for a given property
+ manager. Use the propertyManagers() function to retrieve the set of
+ managers currently associated with this factory.
+
+ Several ready-made implementations of the QtAbstractEditorFactory class
+ are available:
+
+ \list
+ \o QtCheckBoxFactory
+ \o QtDateEditFactory
+ \o QtDateTimeEditFactory
+ \o QtDoubleSpinBoxFactory
+ \o QtEnumEditorFactory
+ \o QtLineEditFactory
+ \o QtScrollBarFactory
+ \o QtSliderFactory
+ \o QtSpinBoxFactory
+ \o QtTimeEditFactory
+ \o QtVariantEditorFactory
+ \endlist
+
+ When deriving from the QtAbstractEditorFactory class, several pure virtual
+ functions must be implemented: the connectPropertyManager() function is
+ used by the factory to connect to the given manager's signals, the
+ createEditor() function is supposed to create an editor for the
+ given property controlled by the given manager, and finally the
+ disconnectPropertyManager() function is used by the factory to disconnect
+ from the specified manager's signals.
+
+ \sa QtAbstractEditorFactoryBase, QtAbstractPropertyManager
+*/
+
+/*!
+ \fn QtAbstractEditorFactory::QtAbstractEditorFactory(QObject *parent = 0)
+
+ Creates an editor factory with the given \a parent.
+
+ \sa addPropertyManager()
+*/
+
+/*!
+ \fn QWidget *QtAbstractEditorFactory::createEditor(QtProperty *property, QWidget *parent)
+
+ Creates an editing widget (with the given \a parent) for the given
+ \a property.
+*/
+
+/*!
+ \fn void QtAbstractEditorFactory::addPropertyManager(PropertyManager *manager)
+
+ Adds the given \a manager to this factory's set of managers,
+ making this factory produce editing widgets for properties created
+ by the given manager.
+
+ The PropertyManager type is a template argument class, and represents the chosen
+ QtAbstractPropertyManager subclass.
+
+ \sa propertyManagers(), removePropertyManager()
+*/
+
+/*!
+ \fn void QtAbstractEditorFactory::removePropertyManager(PropertyManager *manager)
+
+ Removes the given \a manager from this factory's set of
+ managers. The PropertyManager type is a template argument class, and may be
+ any QtAbstractPropertyManager subclass.
+
+ \sa propertyManagers(), addPropertyManager()
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactory::connectPropertyManager(PropertyManager *manager) = 0
+
+ Connects this factory to the given \a manager's signals. The
+ PropertyManager type is a template argument class, and represents
+ the chosen QtAbstractPropertyManager subclass.
+
+ This function is used internally by the addPropertyManager() function, and
+ makes it possible to update an editing widget when the associated
+ property's data changes. This is typically done in custom slots
+ responding to the signals emitted by the property's manager,
+ e.g. QtIntPropertyManager::valueChanged() and
+ QtIntPropertyManager::rangeChanged().
+
+ \sa propertyManagers(), disconnectPropertyManager()
+*/
+
+/*!
+ \fn virtual QWidget *QtAbstractEditorFactory::createEditor(PropertyManager *manager, QtProperty *property,
+ QWidget *parent) = 0
+
+ Creates an editing widget with the given \a parent for the
+ specified \a property created by the given \a manager. The
+ PropertyManager type is a template argument class, and represents
+ the chosen QtAbstractPropertyManager subclass.
+
+ This function must be implemented in derived classes: It is
+ recommended to store a pointer to the widget and map it to the
+ given \a property, since the widget must be updated whenever the
+ associated property's data changes. This is typically done in
+ custom slots responding to the signals emitted by the property's
+ manager, e.g. QtIntPropertyManager::valueChanged() and
+ QtIntPropertyManager::rangeChanged().
+
+ \sa connectPropertyManager()
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactory::disconnectPropertyManager(PropertyManager *manager) = 0
+
+ Disconnects this factory from the given \a manager's signals. The
+ PropertyManager type is a template argument class, and represents
+ the chosen QtAbstractPropertyManager subclass.
+
+ This function is used internally by the removePropertyManager() function.
+
+ \sa propertyManagers(), connectPropertyManager()
+*/
+
+/*!
+ \fn QSet<PropertyManager *> QtAbstractEditorFactory::propertyManagers() const
+
+ Returns the factory's set of associated managers. The
+ PropertyManager type is a template argument class, and represents
+ the chosen QtAbstractPropertyManager subclass.
+
+ \sa addPropertyManager(), removePropertyManager()
+*/
+
+/*!
+ \fn PropertyManager *QtAbstractEditorFactory::propertyManager(QtProperty *property) const
+
+ Returns the property manager for the given \a property, or 0 if
+ the given \a property doesn't belong to any of this factory's
+ registered managers.
+
+ The PropertyManager type is a template argument class, and represents the chosen
+ QtAbstractPropertyManager subclass.
+
+ \sa propertyManagers()
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactory::managerDestroyed(QObject *manager)
+
+ \internal
+ \reimp
+*/
+
+////////////////////////////////////
+class QtBrowserItemPrivate
+{
+public:
+ QtBrowserItemPrivate(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent)
+ : m_browser(browser), m_property(property), m_parent(parent), q_ptr(0) {}
+
+ void addChild(QtBrowserItem *index, QtBrowserItem *after);
+ void removeChild(QtBrowserItem *index);
+
+ QtAbstractPropertyBrowser * const m_browser;
+ QtProperty *m_property;
+ QtBrowserItem *m_parent;
+
+ QtBrowserItem *q_ptr;
+
+ QList<QtBrowserItem *> m_children;
+
+};
+
+void QtBrowserItemPrivate::addChild(QtBrowserItem *index, QtBrowserItem *after)
+{
+ if (m_children.contains(index))
+ return;
+ int idx = m_children.indexOf(after) + 1; // we insert after returned idx, if it was -1 then we set idx to 0;
+ m_children.insert(idx, index);
+}
+
+void QtBrowserItemPrivate::removeChild(QtBrowserItem *index)
+{
+ m_children.removeAll(index);
+}
+
+
+/*!
+ \class QtBrowserItem
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtBrowserItem class represents a property in
+ a property browser instance.
+
+ Browser items are created whenever a QtProperty is inserted to the
+ property browser. A QtBrowserItem uniquely identifies a
+ browser's item. Thus, if the same QtProperty is inserted multiple
+ times, each occurrence gets its own unique QtBrowserItem. The
+ items are owned by QtAbstractPropertyBrowser and automatically
+ deleted when they are removed from the browser.
+
+ You can traverse a browser's properties by calling parent() and
+ children(). The property and the browser associated with an item
+ are available as property() and browser().
+
+ \sa QtAbstractPropertyBrowser, QtProperty
+*/
+
+/*!
+ Returns the property which is accosiated with this item. Note that
+ several items can be associated with the same property instance in
+ the same property browser.
+
+ \sa QtAbstractPropertyBrowser::items()
+*/
+
+QtProperty *QtBrowserItem::property() const
+{
+ return d_ptr->m_property;
+}
+
+/*!
+ Returns the parent item of \e this item. Returns 0 if \e this item
+ is associated with top-level property in item's property browser.
+
+ \sa children()
+*/
+
+QtBrowserItem *QtBrowserItem::parent() const
+{
+ return d_ptr->m_parent;
+}
+
+/*!
+ Returns the children items of \e this item. The properties
+ reproduced from children items are always the same as
+ reproduced from associated property' children, for example:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 1
+
+ The \e childrenItems list represents the same list as \e childrenProperties.
+*/
+
+QList<QtBrowserItem *> QtBrowserItem::children() const
+{
+ return d_ptr->m_children;
+}
+
+/*!
+ Returns the property browser which owns \e this item.
+*/
+
+QtAbstractPropertyBrowser *QtBrowserItem::browser() const
+{
+ return d_ptr->m_browser;
+}
+
+QtBrowserItem::QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent)
+ : d_ptr(new QtBrowserItemPrivate(browser, property, parent))
+{
+ d_ptr->q_ptr = this;
+}
+
+QtBrowserItem::~QtBrowserItem()
+{
+}
+
+
+////////////////////////////////////
+
+typedef QMap<QtAbstractPropertyBrowser *, QMap<QtAbstractPropertyManager *,
+ QtAbstractEditorFactoryBase *> > Map1;
+typedef QMap<QtAbstractPropertyManager *, QMap<QtAbstractEditorFactoryBase *,
+ QList<QtAbstractPropertyBrowser *> > > Map2;
+Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory)
+Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews)
+
+class QtAbstractPropertyBrowserPrivate
+{
+ QtAbstractPropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtAbstractPropertyBrowser)
+public:
+ QtAbstractPropertyBrowserPrivate();
+
+ void insertSubTree(QtProperty *property,
+ QtProperty *parentProperty);
+ void removeSubTree(QtProperty *property,
+ QtProperty *parentProperty);
+ void createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty);
+ void removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty);
+ QtBrowserItem *createBrowserIndex(QtProperty *property, QtBrowserItem *parentIndex, QtBrowserItem *afterIndex);
+ void removeBrowserIndex(QtBrowserItem *index);
+ void clearIndex(QtBrowserItem *index);
+
+ void slotPropertyInserted(QtProperty *property,
+ QtProperty *parentProperty, QtProperty *afterProperty);
+ void slotPropertyRemoved(QtProperty *property, QtProperty *parentProperty);
+ void slotPropertyDestroyed(QtProperty *property);
+ void slotPropertyDataChanged(QtProperty *property);
+
+ QList<QtProperty *> m_subItems;
+ QMap<QtAbstractPropertyManager *, QList<QtProperty *> > m_managerToProperties;
+ QMap<QtProperty *, QList<QtProperty *> > m_propertyToParents;
+
+ QMap<QtProperty *, QtBrowserItem *> m_topLevelPropertyToIndex;
+ QList<QtBrowserItem *> m_topLevelIndexes;
+ QMap<QtProperty *, QList<QtBrowserItem *> > m_propertyToIndexes;
+
+ QtBrowserItem *m_currentItem;
+};
+
+QtAbstractPropertyBrowserPrivate::QtAbstractPropertyBrowserPrivate() :
+ m_currentItem(0)
+{
+}
+
+void QtAbstractPropertyBrowserPrivate::insertSubTree(QtProperty *property,
+ QtProperty *parentProperty)
+{
+ if (m_propertyToParents.contains(property)) {
+ // property was already inserted, so its manager is connected
+ // and all its children are inserted and theirs managers are connected
+ // we just register new parent (parent has to be new).
+ m_propertyToParents[property].append(parentProperty);
+ // don't need to update m_managerToProperties map since
+ // m_managerToProperties[manager] already contains property.
+ return;
+ }
+ QtAbstractPropertyManager *manager = property->propertyManager();
+ if (m_managerToProperties[manager].isEmpty()) {
+ // connect manager's signals
+ q_ptr->connect(manager, SIGNAL(propertyInserted(QtProperty *,
+ QtProperty *, QtProperty *)),
+ q_ptr, SLOT(slotPropertyInserted(QtProperty *,
+ QtProperty *, QtProperty *)));
+ q_ptr->connect(manager, SIGNAL(propertyRemoved(QtProperty *,
+ QtProperty *)),
+ q_ptr, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ q_ptr->connect(manager, SIGNAL(propertyDestroyed(QtProperty*)),
+ q_ptr, SLOT(slotPropertyDestroyed(QtProperty*)));
+ q_ptr->connect(manager, SIGNAL(propertyChanged(QtProperty*)),
+ q_ptr, SLOT(slotPropertyDataChanged(QtProperty*)));
+ }
+ m_managerToProperties[manager].append(property);
+ m_propertyToParents[property].append(parentProperty);
+
+ QList<QtProperty *> subList = property->subProperties();
+ QListIterator<QtProperty *> itSub(subList);
+ while (itSub.hasNext()) {
+ QtProperty *subProperty = itSub.next();
+ insertSubTree(subProperty, property);
+ }
+}
+
+void QtAbstractPropertyBrowserPrivate::removeSubTree(QtProperty *property,
+ QtProperty *parentProperty)
+{
+ if (!m_propertyToParents.contains(property)) {
+ // ASSERT
+ return;
+ }
+
+ m_propertyToParents[property].removeAll(parentProperty);
+ if (!m_propertyToParents[property].isEmpty())
+ return;
+
+ m_propertyToParents.remove(property);
+ QtAbstractPropertyManager *manager = property->propertyManager();
+ m_managerToProperties[manager].removeAll(property);
+ if (m_managerToProperties[manager].isEmpty()) {
+ // disconnect manager's signals
+ q_ptr->disconnect(manager, SIGNAL(propertyInserted(QtProperty *,
+ QtProperty *, QtProperty *)),
+ q_ptr, SLOT(slotPropertyInserted(QtProperty *,
+ QtProperty *, QtProperty *)));
+ q_ptr->disconnect(manager, SIGNAL(propertyRemoved(QtProperty *,
+ QtProperty *)),
+ q_ptr, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ q_ptr->disconnect(manager, SIGNAL(propertyDestroyed(QtProperty*)),
+ q_ptr, SLOT(slotPropertyDestroyed(QtProperty*)));
+ q_ptr->disconnect(manager, SIGNAL(propertyChanged(QtProperty*)),
+ q_ptr, SLOT(slotPropertyDataChanged(QtProperty*)));
+
+ m_managerToProperties.remove(manager);
+ }
+
+ QList<QtProperty *> subList = property->subProperties();
+ QListIterator<QtProperty *> itSub(subList);
+ while (itSub.hasNext()) {
+ QtProperty *subProperty = itSub.next();
+ removeSubTree(subProperty, property);
+ }
+}
+
+void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty)
+{
+ QMap<QtBrowserItem *, QtBrowserItem *> parentToAfter;
+ if (afterProperty) {
+ QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
+ m_propertyToIndexes.find(afterProperty);
+ if (it == m_propertyToIndexes.constEnd())
+ return;
+
+ QList<QtBrowserItem *> indexes = it.value();
+ QListIterator<QtBrowserItem *> itIndex(indexes);
+ while (itIndex.hasNext()) {
+ QtBrowserItem *idx = itIndex.next();
+ QtBrowserItem *parentIdx = idx->parent();
+ if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx))
+ parentToAfter[idx->parent()] = idx;
+ }
+ } else if (parentProperty) {
+ QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
+ m_propertyToIndexes.find(parentProperty);
+ if (it == m_propertyToIndexes.constEnd())
+ return;
+
+ QList<QtBrowserItem *> indexes = it.value();
+ QListIterator<QtBrowserItem *> itIndex(indexes);
+ while (itIndex.hasNext()) {
+ QtBrowserItem *idx = itIndex.next();
+ parentToAfter[idx] = 0;
+ }
+ } else {
+ parentToAfter[0] = 0;
+ }
+
+ const QMap<QtBrowserItem *, QtBrowserItem *>::ConstIterator pcend = parentToAfter.constEnd();
+ for (QMap<QtBrowserItem *, QtBrowserItem *>::ConstIterator it = parentToAfter.constBegin(); it != pcend; ++it)
+ createBrowserIndex(property, it.key(), it.value());
+}
+
+QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *property,
+ QtBrowserItem *parentIndex, QtBrowserItem *afterIndex)
+{
+ QtBrowserItem *newIndex = new QtBrowserItem(q_ptr, property, parentIndex);
+ if (parentIndex) {
+ parentIndex->d_ptr->addChild(newIndex, afterIndex);
+ } else {
+ m_topLevelPropertyToIndex[property] = newIndex;
+ m_topLevelIndexes.insert(m_topLevelIndexes.indexOf(afterIndex) + 1, newIndex);
+ }
+ m_propertyToIndexes[property].append(newIndex);
+
+ q_ptr->itemInserted(newIndex, afterIndex);
+
+ QList<QtProperty *> subItems = property->subProperties();
+ QListIterator<QtProperty *> itChild(subItems);
+ QtBrowserItem *afterChild = 0;
+ while (itChild.hasNext()) {
+ QtProperty *child = itChild.next();
+ afterChild = createBrowserIndex(child, newIndex, afterChild);
+ }
+ return newIndex;
+}
+
+void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty)
+{
+ QList<QtBrowserItem *> toRemove;
+ QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
+ m_propertyToIndexes.find(property);
+ if (it == m_propertyToIndexes.constEnd())
+ return;
+
+ QList<QtBrowserItem *> indexes = it.value();
+ QListIterator<QtBrowserItem *> itIndex(indexes);
+ while (itIndex.hasNext()) {
+ QtBrowserItem *idx = itIndex.next();
+ QtBrowserItem *parentIdx = idx->parent();
+ if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx))
+ toRemove.append(idx);
+ }
+
+ QListIterator<QtBrowserItem *> itRemove(toRemove);
+ while (itRemove.hasNext()) {
+ QtBrowserItem *index = itRemove.next();
+ removeBrowserIndex(index);
+ }
+}
+
+void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index)
+{
+ QList<QtBrowserItem *> children = index->children();
+ for (int i = children.count(); i > 0; i--) {
+ removeBrowserIndex(children.at(i - 1));
+ }
+
+ q_ptr->itemRemoved(index);
+
+ if (index->parent()) {
+ index->parent()->d_ptr->removeChild(index);
+ } else {
+ m_topLevelPropertyToIndex.remove(index->property());
+ m_topLevelIndexes.removeAll(index);
+ }
+
+ QtProperty *property = index->property();
+
+ m_propertyToIndexes[property].removeAll(index);
+ if (m_propertyToIndexes[property].isEmpty())
+ m_propertyToIndexes.remove(property);
+
+ delete index;
+}
+
+void QtAbstractPropertyBrowserPrivate::clearIndex(QtBrowserItem *index)
+{
+ QList<QtBrowserItem *> children = index->children();
+ QListIterator<QtBrowserItem *> itChild(children);
+ while (itChild.hasNext()) {
+ clearIndex(itChild.next());
+ }
+ delete index;
+}
+
+void QtAbstractPropertyBrowserPrivate::slotPropertyInserted(QtProperty *property,
+ QtProperty *parentProperty, QtProperty *afterProperty)
+{
+ if (!m_propertyToParents.contains(parentProperty))
+ return;
+ createBrowserIndexes(property, parentProperty, afterProperty);
+ insertSubTree(property, parentProperty);
+ //q_ptr->propertyInserted(property, parentProperty, afterProperty);
+}
+
+void QtAbstractPropertyBrowserPrivate::slotPropertyRemoved(QtProperty *property,
+ QtProperty *parentProperty)
+{
+ if (!m_propertyToParents.contains(parentProperty))
+ return;
+ removeSubTree(property, parentProperty); // this line should be probably moved down after propertyRemoved call
+ //q_ptr->propertyRemoved(property, parentProperty);
+ removeBrowserIndexes(property, parentProperty);
+}
+
+void QtAbstractPropertyBrowserPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (!m_subItems.contains(property))
+ return;
+ q_ptr->removeProperty(property);
+}
+
+void QtAbstractPropertyBrowserPrivate::slotPropertyDataChanged(QtProperty *property)
+{
+ if (!m_propertyToParents.contains(property))
+ return;
+
+ QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
+ m_propertyToIndexes.find(property);
+ if (it == m_propertyToIndexes.constEnd())
+ return;
+
+ QList<QtBrowserItem *> indexes = it.value();
+ QListIterator<QtBrowserItem *> itIndex(indexes);
+ while (itIndex.hasNext()) {
+ QtBrowserItem *idx = itIndex.next();
+ q_ptr->itemChanged(idx);
+ }
+ //q_ptr->propertyChanged(property);
+}
+
+/*!
+ \class QtAbstractPropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief QtAbstractPropertyBrowser provides a base class for
+ implementing property browsers.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ \image qtpropertybrowser.png
+
+ The top level properties can be retrieved using the
+ properties() function. To traverse each property's
+ subproperties, use the QtProperty::subProperties() function. In
+ addition, the set of top level properties can be manipulated using
+ the addProperty(), insertProperty() and removeProperty()
+ functions. Note that the QtProperty class provides a corresponding
+ set of functions making it possible to manipulate the set of
+ subproperties as well.
+
+ To remove all the properties from the property browser widget, use
+ the clear() function. This function will clear the editor, but it
+ will not delete the properties since they can still be used in
+ other editors.
+
+ The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class. A manager
+ can handle (i.e. create and manage) properties of a given type. In
+ the property browser the managers are associated with
+ implementations of the QtAbstractEditorFactory: A factory is a
+ class able to create an editing widget of a specified type.
+
+ When using a property browser widget, managers must be created for
+ each of the required property types before the properties
+ themselves can be created. To ensure that the properties' values
+ will be displayed using suitable editing widgets, the managers
+ must be associated with objects of the preferred factory
+ implementations using the setFactoryForManager() function. The
+ property browser will use these associations to determine which
+ factory it should use to create the preferred editing widget.
+
+ Note that a factory can be associated with many managers, but a
+ manager can only be associated with one single factory within the
+ context of a single property browser. The associations between
+ managers and factories can at any time be removed using the
+ unsetFactoryForManager() function.
+
+ Whenever the property data changes or a property is inserted or
+ removed, the itemChanged(), itemInserted() or
+ itemRemoved() functions are called, respectively. These
+ functions must be reimplemented in derived classes in order to
+ update the property browser widget. Be aware that some property
+ instances can appear several times in an abstract tree
+ structure. For example:
+
+ \table 100%
+ \row
+ \o
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 2
+ \o \image qtpropertybrowser-duplicate.png
+ \endtable
+
+ The addProperty() function returns a QtBrowserItem that uniquely
+ identifies the created item.
+
+ To make a property editable in the property browser, the
+ createEditor() function must be called to provide the
+ property with a suitable editing widget.
+
+ Note that there are two ready-made property browser
+ implementations:
+
+ \list
+ \o QtGroupBoxPropertyBrowser
+ \o QtTreePropertyBrowser
+ \endlist
+
+ \sa QtAbstractPropertyManager, QtAbstractEditorFactoryBase
+*/
+
+/*!
+ \fn void QtAbstractPropertyBrowser::setFactoryForManager(PropertyManager *manager,
+ QtAbstractEditorFactory<PropertyManager> *factory)
+
+ Connects the given \a manager to the given \a factory, ensuring
+ that properties of the \a manager's type will be displayed with an
+ editing widget suitable for their value.
+
+ For example:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 3
+
+ In this example the \c myInteger property's value is displayed
+ with a QSpinBox widget, while the \c myDouble property's value is
+ displayed with a QDoubleSpinBox widget.
+
+ Note that a factory can be associated with many managers, but a
+ manager can only be associated with one single factory. If the
+ given \a manager already is associated with another factory, the
+ old association is broken before the new one established.
+
+ This function ensures that the given \a manager and the given \a
+ factory are compatible, and it automatically calls the
+ QtAbstractEditorFactory::addPropertyManager() function if necessary.
+
+ \sa unsetFactoryForManager()
+*/
+
+/*!
+ \fn virtual void QtAbstractPropertyBrowser::itemInserted(QtBrowserItem *insertedItem,
+ QtBrowserItem *precedingItem) = 0
+
+ This function is called to update the widget whenever a property
+ is inserted or added to the property browser, passing pointers to
+ the \a insertedItem of property and the specified
+ \a precedingItem as parameters.
+
+ If \a precedingItem is 0, the \a insertedItem was put at
+ the beginning of its parent item's list of subproperties. If
+ the parent of \a insertedItem is 0, the \a insertedItem was added as a top
+ level property of \e this property browser.
+
+ This function must be reimplemented in derived classes. Note that
+ if the \a insertedItem's property has subproperties, this
+ method will be called for those properties as soon as the current call is finished.
+
+ \sa insertProperty(), addProperty()
+*/
+
+/*!
+ \fn virtual void QtAbstractPropertyBrowser::itemRemoved(QtBrowserItem *item) = 0
+
+ This function is called to update the widget whenever a property
+ is removed from the property browser, passing the pointer to the
+ \a item of the property as parameters. The passed \a item is
+ deleted just after this call is finished.
+
+ If the the parent of \a item is 0, the removed \a item was a
+ top level property in this editor.
+
+ This function must be reimplemented in derived classes. Note that
+ if the removed \a item's property has subproperties, this
+ method will be called for those properties just before the current call is started.
+
+ \sa removeProperty()
+*/
+
+/*!
+ \fn virtual void QtAbstractPropertyBrowser::itemChanged(QtBrowserItem *item) = 0
+
+ This function is called whenever a property's data changes,
+ passing a pointer to the \a item of property as parameter.
+
+ This function must be reimplemented in derived classes in order to
+ update the property browser widget whenever a property's name,
+ tool tip, status tip, "what's this" text, value text or value icon
+ changes.
+
+ Note that if the property browser contains several occurrences of
+ the same property, this method will be called once for each
+ occurrence (with a different item each time).
+
+ \sa QtProperty, items()
+*/
+
+/*!
+ Creates an abstract property browser with the given \a parent.
+*/
+QtAbstractPropertyBrowser::QtAbstractPropertyBrowser(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtAbstractPropertyBrowserPrivate)
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys the property browser, and destroys all the items that were
+ created by this property browser.
+
+ Note that the properties that were displayed in the editor are not
+ deleted since they still can be used in other editors. Neither
+ does the destructor delete the property managers and editor
+ factories that were used by this property browser widget unless
+ this widget was their parent.
+
+ \sa QtAbstractPropertyManager::~QtAbstractPropertyManager()
+*/
+QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser()
+{
+ QList<QtBrowserItem *> indexes = topLevelItems();
+ QListIterator<QtBrowserItem *> itItem(indexes);
+ while (itItem.hasNext())
+ d_ptr->clearIndex(itItem.next());
+}
+
+/*!
+ Returns the property browser's list of top level properties.
+
+ To traverse the subproperties, use the QtProperty::subProperties()
+ function.
+
+ \sa addProperty(), insertProperty(), removeProperty()
+*/
+QList<QtProperty *> QtAbstractPropertyBrowser::properties() const
+{
+ return d_ptr->m_subItems;
+}
+
+/*!
+ Returns the property browser's list of all items associated
+ with the given \a property.
+
+ There is one item per instance of the property in the browser.
+
+ \sa topLevelItem()
+*/
+
+QList<QtBrowserItem *> QtAbstractPropertyBrowser::items(QtProperty *property) const
+{
+ return d_ptr->m_propertyToIndexes.value(property);
+}
+
+/*!
+ Returns the top-level items associated with the given \a property.
+
+ Returns 0 if \a property wasn't inserted into this property
+ browser or isn't a top-level one.
+
+ \sa topLevelItems(), items()
+*/
+
+QtBrowserItem *QtAbstractPropertyBrowser::topLevelItem(QtProperty *property) const
+{
+ return d_ptr->m_topLevelPropertyToIndex.value(property);
+}
+
+/*!
+ Returns the list of top-level items.
+
+ \sa topLevelItem()
+*/
+
+QList<QtBrowserItem *> QtAbstractPropertyBrowser::topLevelItems() const
+{
+ return d_ptr->m_topLevelIndexes;
+}
+
+/*!
+ Removes all the properties from the editor, but does not delete
+ them since they can still be used in other editors.
+
+ \sa removeProperty(), QtAbstractPropertyManager::clear()
+*/
+void QtAbstractPropertyBrowser::clear()
+{
+ QList<QtProperty *> subList = properties();
+ QListIterator<QtProperty *> itSub(subList);
+ itSub.toBack();
+ while (itSub.hasPrevious()) {
+ QtProperty *property = itSub.previous();
+ removeProperty(property);
+ }
+}
+
+/*!
+ Appends the given \a property (and its subproperties) to the
+ property browser's list of top level properties. Returns the item
+ created by property browser which is associated with the \a property.
+ In order to get all children items created by the property
+ browser in this call, the returned item should be traversed.
+
+ If the specified \a property is already added, this function does
+ nothing and returns 0.
+
+ \sa insertProperty(), QtProperty::addSubProperty(), properties()
+*/
+QtBrowserItem *QtAbstractPropertyBrowser::addProperty(QtProperty *property)
+{
+ QtProperty *afterProperty = 0;
+ if (d_ptr->m_subItems.count() > 0)
+ afterProperty = d_ptr->m_subItems.last();
+ return insertProperty(property, afterProperty);
+}
+
+/*!
+ \fn QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
+ QtProperty *afterProperty)
+
+ Inserts the given \a property (and its subproperties) after
+ the specified \a afterProperty in the browser's list of top
+ level properties. Returns item created by property browser which
+ is associated with the \a property. In order to get all children items
+ created by the property browser in this call returned item should be traversed.
+
+ If the specified \a afterProperty is 0, the given \a property is
+ inserted at the beginning of the list. If \a property is
+ already inserted, this function does nothing and returns 0.
+
+ \sa addProperty(), QtProperty::insertSubProperty(), properties()
+*/
+QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
+ QtProperty *afterProperty)
+{
+ if (!property)
+ return 0;
+
+ // if item is already inserted in this item then cannot add.
+ QList<QtProperty *> pendingList = properties();
+ int pos = 0;
+ int newPos = 0;
+ QtProperty *properAfterProperty = 0;
+ while (pos < pendingList.count()) {
+ QtProperty *prop = pendingList.at(pos);
+ if (prop == property)
+ return 0;
+ if (prop == afterProperty) {
+ newPos = pos + 1;
+ properAfterProperty = afterProperty;
+ }
+ pos++;
+ }
+ d_ptr->createBrowserIndexes(property, 0, afterProperty);
+
+ // traverse inserted subtree and connect to manager's signals
+ d_ptr->insertSubTree(property, 0);
+
+ d_ptr->m_subItems.insert(newPos, property);
+ //propertyInserted(property, 0, properAfterProperty);
+ return topLevelItem(property);
+}
+
+/*!
+ Removes the specified \a property (and its subproperties) from the
+ property browser's list of top level properties. All items
+ that were associated with the given \a property and its children
+ are deleted.
+
+ Note that the properties are \e not deleted since they can still
+ be used in other editors.
+
+ \sa clear(), QtProperty::removeSubProperty(), properties()
+*/
+void QtAbstractPropertyBrowser::removeProperty(QtProperty *property)
+{
+ if (!property)
+ return;
+
+ QList<QtProperty *> pendingList = properties();
+ int pos = 0;
+ while (pos < pendingList.count()) {
+ if (pendingList.at(pos) == property) {
+ d_ptr->m_subItems.removeAt(pos); //perhaps this two lines
+ d_ptr->removeSubTree(property, 0); //should be moved down after propertyRemoved call.
+ //propertyRemoved(property, 0);
+
+ d_ptr->removeBrowserIndexes(property, 0);
+
+ // when item is deleted, item will call removeItem for top level items,
+ // and itemRemoved for nested items.
+
+ return;
+ }
+ pos++;
+ }
+}
+
+/*!
+ Creates an editing widget (with the given \a parent) for the given
+ \a property according to the previously established associations
+ between property managers and editor factories.
+
+ If the property is created by a property manager which was not
+ associated with any of the existing factories in \e this property
+ editor, the function returns 0.
+
+ To make a property editable in the property browser, the
+ createEditor() function must be called to provide the
+ property with a suitable editing widget.
+
+ Reimplement this function to provide additional decoration for the
+ editing widgets created by the installed factories.
+
+ \sa setFactoryForManager()
+*/
+QWidget *QtAbstractPropertyBrowser::createEditor(QtProperty *property,
+ QWidget *parent)
+{
+ QtAbstractEditorFactoryBase *factory = 0;
+ QtAbstractPropertyManager *manager = property->propertyManager();
+
+ if (m_viewToManagerToFactory()->contains(this) &&
+ (*m_viewToManagerToFactory())[this].contains(manager)) {
+ factory = (*m_viewToManagerToFactory())[this][manager];
+ }
+
+ if (!factory)
+ return 0;
+ return factory->createEditor(property, parent);
+}
+
+bool QtAbstractPropertyBrowser::addFactory(QtAbstractPropertyManager *abstractManager,
+ QtAbstractEditorFactoryBase *abstractFactory)
+{
+ bool connectNeeded = false;
+ if (!m_managerToFactoryToViews()->contains(abstractManager) ||
+ !(*m_managerToFactoryToViews())[abstractManager].contains(abstractFactory)) {
+ connectNeeded = true;
+ } else if ((*m_managerToFactoryToViews())[abstractManager][abstractFactory]
+ .contains(this)) {
+ return connectNeeded;
+ }
+
+ if (m_viewToManagerToFactory()->contains(this) &&
+ (*m_viewToManagerToFactory())[this].contains(abstractManager)) {
+ unsetFactoryForManager(abstractManager);
+ }
+
+ (*m_managerToFactoryToViews())[abstractManager][abstractFactory].append(this);
+ (*m_viewToManagerToFactory())[this][abstractManager] = abstractFactory;
+
+ return connectNeeded;
+}
+
+/*!
+ Removes the association between the given \a manager and the
+ factory bound to it, automatically calling the
+ QtAbstractEditorFactory::removePropertyManager() function if necessary.
+
+ \sa setFactoryForManager()
+*/
+void QtAbstractPropertyBrowser::unsetFactoryForManager(QtAbstractPropertyManager *manager)
+{
+ if (!m_viewToManagerToFactory()->contains(this) ||
+ !(*m_viewToManagerToFactory())[this].contains(manager)) {
+ return;
+ }
+
+ QtAbstractEditorFactoryBase *abstractFactory =
+ (*m_viewToManagerToFactory())[this][manager];
+ (*m_viewToManagerToFactory())[this].remove(manager);
+ if ((*m_viewToManagerToFactory())[this].isEmpty()) {
+ (*m_viewToManagerToFactory()).remove(this);
+ }
+
+ (*m_managerToFactoryToViews())[manager][abstractFactory].removeAll(this);
+ if ((*m_managerToFactoryToViews())[manager][abstractFactory].isEmpty()) {
+ (*m_managerToFactoryToViews())[manager].remove(abstractFactory);
+ abstractFactory->breakConnection(manager);
+ if ((*m_managerToFactoryToViews())[manager].isEmpty()) {
+ (*m_managerToFactoryToViews()).remove(manager);
+ }
+ }
+}
+
+/*!
+ Returns the current item in the property browser.
+
+ \sa setCurrentItem()
+*/
+QtBrowserItem *QtAbstractPropertyBrowser::currentItem() const
+{
+ return d_ptr->m_currentItem;
+}
+
+/*!
+ Sets the current item in the property browser to \a item.
+
+ \sa currentItem(), currentItemChanged()
+*/
+void QtAbstractPropertyBrowser::setCurrentItem(QtBrowserItem *item)
+{
+ QtBrowserItem *oldItem = d_ptr->m_currentItem;
+ d_ptr->m_currentItem = item;
+ if (oldItem != item)
+ emit currentItemChanged(item);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtpropertybrowser.cpp"
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.h b/src/shared/qtpropertybrowser/qtpropertybrowser.h
new file mode 100644
index 000000000..619f43501
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.h
@@ -0,0 +1,309 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTPROPERTYBROWSER_H
+#define QTPROPERTYBROWSER_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+class QtAbstractPropertyManager;
+class QtPropertyPrivate;
+
+class QtProperty
+{
+public:
+ virtual ~QtProperty();
+
+ QList<QtProperty *> subProperties() const;
+
+ QtAbstractPropertyManager *propertyManager() const;
+
+ QString toolTip() const;
+ QString statusTip() const;
+ QString whatsThis() const;
+ QString propertyName() const;
+ bool isEnabled() const;
+ bool isModified() const;
+
+ bool hasValue() const;
+ QIcon valueIcon() const;
+ QString valueText() const;
+
+ void setToolTip(const QString &text);
+ void setStatusTip(const QString &text);
+ void setWhatsThis(const QString &text);
+ void setPropertyName(const QString &text);
+ void setEnabled(bool enable);
+ void setModified(bool modified);
+
+ void addSubProperty(QtProperty *property);
+ void insertSubProperty(QtProperty *property, QtProperty *afterProperty);
+ void removeSubProperty(QtProperty *property);
+protected:
+ explicit QtProperty(QtAbstractPropertyManager *manager);
+ void propertyChanged();
+private:
+ friend class QtAbstractPropertyManager;
+ QScopedPointer<QtPropertyPrivate> d_ptr;
+};
+
+class QtAbstractPropertyManagerPrivate;
+
+class QtAbstractPropertyManager : public QObject
+{
+ Q_OBJECT
+public:
+
+ explicit QtAbstractPropertyManager(QObject *parent = 0);
+ ~QtAbstractPropertyManager();
+
+ QSet<QtProperty *> properties() const;
+ void clear() const;
+
+ QtProperty *addProperty(const QString &name = QString());
+Q_SIGNALS:
+
+ void propertyInserted(QtProperty *property,
+ QtProperty *parent, QtProperty *after);
+ void propertyChanged(QtProperty *property);
+ void propertyRemoved(QtProperty *property, QtProperty *parent);
+ void propertyDestroyed(QtProperty *property);
+protected:
+ virtual bool hasValue(const QtProperty *property) const;
+ virtual QIcon valueIcon(const QtProperty *property) const;
+ virtual QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property) = 0;
+ virtual void uninitializeProperty(QtProperty *property);
+ virtual QtProperty *createProperty();
+private:
+ friend class QtProperty;
+ QScopedPointer<QtAbstractPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtAbstractPropertyManager)
+ Q_DISABLE_COPY(QtAbstractPropertyManager)
+};
+
+class QtAbstractEditorFactoryBase : public QObject
+{
+ Q_OBJECT
+public:
+ virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0;
+protected:
+ explicit QtAbstractEditorFactoryBase(QObject *parent = 0)
+ : QObject(parent) {}
+
+ virtual void breakConnection(QtAbstractPropertyManager *manager) = 0;
+protected Q_SLOTS:
+ virtual void managerDestroyed(QObject *manager) = 0;
+
+ friend class QtAbstractPropertyBrowser;
+};
+
+template <class PropertyManager>
+class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase
+{
+public:
+ explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {}
+ QWidget *createEditor(QtProperty *property, QWidget *parent)
+ {
+ QSetIterator<PropertyManager *> it(m_managers);
+ while (it.hasNext()) {
+ PropertyManager *manager = it.next();
+ if (manager == property->propertyManager()) {
+ return createEditor(manager, property, parent);
+ }
+ }
+ return 0;
+ }
+ void addPropertyManager(PropertyManager *manager)
+ {
+ if (m_managers.contains(manager))
+ return;
+ m_managers.insert(manager);
+ connectPropertyManager(manager);
+ connect(manager, SIGNAL(destroyed(QObject *)),
+ this, SLOT(managerDestroyed(QObject *)));
+ }
+ void removePropertyManager(PropertyManager *manager)
+ {
+ if (!m_managers.contains(manager))
+ return;
+ disconnect(manager, SIGNAL(destroyed(QObject *)),
+ this, SLOT(managerDestroyed(QObject *)));
+ disconnectPropertyManager(manager);
+ m_managers.remove(manager);
+ }
+ QSet<PropertyManager *> propertyManagers() const
+ {
+ return m_managers;
+ }
+ PropertyManager *propertyManager(QtProperty *property) const
+ {
+ QtAbstractPropertyManager *manager = property->propertyManager();
+ QSetIterator<PropertyManager *> itManager(m_managers);
+ while (itManager.hasNext()) {
+ PropertyManager *m = itManager.next();
+ if (m == manager) {
+ return m;
+ }
+ }
+ return 0;
+ }
+protected:
+ virtual void connectPropertyManager(PropertyManager *manager) = 0;
+ virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property,
+ QWidget *parent) = 0;
+ virtual void disconnectPropertyManager(PropertyManager *manager) = 0;
+ void managerDestroyed(QObject *manager)
+ {
+ QSetIterator<PropertyManager *> it(m_managers);
+ while (it.hasNext()) {
+ PropertyManager *m = it.next();
+ if (m == manager) {
+ m_managers.remove(m);
+ return;
+ }
+ }
+ }
+private:
+ void breakConnection(QtAbstractPropertyManager *manager)
+ {
+ QSetIterator<PropertyManager *> it(m_managers);
+ while (it.hasNext()) {
+ PropertyManager *m = it.next();
+ if (m == manager) {
+ removePropertyManager(m);
+ return;
+ }
+ }
+ }
+private:
+ QSet<PropertyManager *> m_managers;
+ friend class QtAbstractPropertyEditor;
+};
+
+class QtAbstractPropertyBrowser;
+class QtBrowserItemPrivate;
+
+class QtBrowserItem
+{
+public:
+ QtProperty *property() const;
+ QtBrowserItem *parent() const;
+ QList<QtBrowserItem *> children() const;
+ QtAbstractPropertyBrowser *browser() const;
+private:
+ explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent);
+ ~QtBrowserItem();
+ QScopedPointer<QtBrowserItemPrivate> d_ptr;
+ friend class QtAbstractPropertyBrowserPrivate;
+};
+
+class QtAbstractPropertyBrowserPrivate;
+
+class QtAbstractPropertyBrowser : public QWidget
+{
+ Q_OBJECT
+public:
+
+ explicit QtAbstractPropertyBrowser(QWidget *parent = 0);
+ ~QtAbstractPropertyBrowser();
+
+ QList<QtProperty *> properties() const;
+ QList<QtBrowserItem *> items(QtProperty *property) const;
+ QtBrowserItem *topLevelItem(QtProperty *property) const;
+ QList<QtBrowserItem *> topLevelItems() const;
+ void clear();
+
+ template <class PropertyManager>
+ void setFactoryForManager(PropertyManager *manager,
+ QtAbstractEditorFactory<PropertyManager> *factory) {
+ QtAbstractPropertyManager *abstractManager = manager;
+ QtAbstractEditorFactoryBase *abstractFactory = factory;
+
+ if (addFactory(abstractManager, abstractFactory))
+ factory->addPropertyManager(manager);
+ }
+
+ void unsetFactoryForManager(QtAbstractPropertyManager *manager);
+
+ QtBrowserItem *currentItem() const;
+ void setCurrentItem(QtBrowserItem *);
+
+Q_SIGNALS:
+ void currentItemChanged(QtBrowserItem *);
+
+public Q_SLOTS:
+
+ QtBrowserItem *addProperty(QtProperty *property);
+ QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty);
+ void removeProperty(QtProperty *property);
+
+protected:
+
+ virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0;
+ virtual void itemRemoved(QtBrowserItem *item) = 0;
+ // can be tooltip, statustip, whatsthis, name, icon, text.
+ virtual void itemChanged(QtBrowserItem *item) = 0;
+
+ virtual QWidget *createEditor(QtProperty *property, QWidget *parent);
+private:
+
+ bool addFactory(QtAbstractPropertyManager *abstractManager,
+ QtAbstractEditorFactoryBase *abstractFactory);
+
+ QScopedPointer<QtAbstractPropertyBrowserPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser)
+ Q_DISABLE_COPY(QtAbstractPropertyBrowser)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *,
+ QtProperty *, QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *,
+ QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *))
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QTPROPERTYBROWSER_H
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.pri b/src/shared/qtpropertybrowser/qtpropertybrowser.pri
new file mode 100644
index 000000000..85c2b8d70
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.pri
@@ -0,0 +1,19 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qtpropertybrowser.cpp \
+ $$PWD/qtpropertymanager.cpp \
+ $$PWD/qteditorfactory.cpp \
+ $$PWD/qtvariantproperty.cpp \
+ $$PWD/qttreepropertybrowser.cpp \
+ $$PWD/qtbuttonpropertybrowser.cpp \
+ $$PWD/qtgroupboxpropertybrowser.cpp \
+ $$PWD/qtpropertybrowserutils.cpp
+HEADERS += $$PWD/qtpropertybrowser.h \
+ $$PWD/qtpropertymanager.h \
+ $$PWD/qteditorfactory.h \
+ $$PWD/qtvariantproperty.h \
+ $$PWD/qttreepropertybrowser.h \
+ $$PWD/qtbuttonpropertybrowser.h \
+ $$PWD/qtgroupboxpropertybrowser.h \
+ $$PWD/qtpropertybrowserutils_p.h
+RESOURCES += $$PWD/qtpropertybrowser.qrc
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.qrc b/src/shared/qtpropertybrowser/qtpropertybrowser.qrc
new file mode 100644
index 000000000..4f91ab782
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.qrc
@@ -0,0 +1,23 @@
+<RCC version="1.0">
+ <qresource prefix="/trolltech/qtpropertybrowser">
+ <file>images/cursor-arrow.png</file>
+ <file>images/cursor-busy.png</file>
+ <file>images/cursor-closedhand.png</file>
+ <file>images/cursor-cross.png</file>
+ <file>images/cursor-forbidden.png</file>
+ <file>images/cursor-hand.png</file>
+ <file>images/cursor-hsplit.png</file>
+ <file>images/cursor-ibeam.png</file>
+ <file>images/cursor-openhand.png</file>
+ <file>images/cursor-sizeall.png</file>
+ <file>images/cursor-sizeb.png</file>
+ <file>images/cursor-sizef.png</file>
+ <file>images/cursor-sizeh.png</file>
+ <file>images/cursor-sizev.png</file>
+ <file>images/cursor-uparrow.png</file>
+ <file>images/cursor-vsplit.png</file>
+ <file>images/cursor-wait.png</file>
+ <file>images/cursor-whatsthis.png</file>
+ </qresource>
+</RCC>
+
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowserutils.cpp b/src/shared/qtpropertybrowser/qtpropertybrowserutils.cpp
new file mode 100644
index 000000000..0b57cff88
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowserutils.cpp
@@ -0,0 +1,456 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtpropertybrowserutils_p.h"
+#include <QtGui/QApplication>
+#include <QtGui/QPainter>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QCheckBox>
+#include <QtGui/QLineEdit>
+#include <QtGui/QMenu>
+#include <QtCore/QLocale>
+
+QT_BEGIN_NAMESPACE
+
+QtCursorDatabase::QtCursorDatabase()
+{
+ appendCursor(Qt::ArrowCursor, QApplication::translate("QtCursorDatabase", "Arrow", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-arrow.png")));
+ appendCursor(Qt::UpArrowCursor, QApplication::translate("QtCursorDatabase", "Up Arrow", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-uparrow.png")));
+ appendCursor(Qt::CrossCursor, QApplication::translate("QtCursorDatabase", "Cross", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-cross.png")));
+ appendCursor(Qt::WaitCursor, QApplication::translate("QtCursorDatabase", "Wait", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-wait.png")));
+ appendCursor(Qt::IBeamCursor, QApplication::translate("QtCursorDatabase", "IBeam", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-ibeam.png")));
+ appendCursor(Qt::SizeVerCursor, QApplication::translate("QtCursorDatabase", "Size Vertical", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizev.png")));
+ appendCursor(Qt::SizeHorCursor, QApplication::translate("QtCursorDatabase", "Size Horizontal", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeh.png")));
+ appendCursor(Qt::SizeFDiagCursor, QApplication::translate("QtCursorDatabase", "Size Backslash", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizef.png")));
+ appendCursor(Qt::SizeBDiagCursor, QApplication::translate("QtCursorDatabase", "Size Slash", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeb.png")));
+ appendCursor(Qt::SizeAllCursor, QApplication::translate("QtCursorDatabase", "Size All", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeall.png")));
+ appendCursor(Qt::BlankCursor, QApplication::translate("QtCursorDatabase", "Blank", 0,
+ QApplication::UnicodeUTF8), QIcon());
+ appendCursor(Qt::SplitVCursor, QApplication::translate("QtCursorDatabase", "Split Vertical", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-vsplit.png")));
+ appendCursor(Qt::SplitHCursor, QApplication::translate("QtCursorDatabase", "Split Horizontal", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-hsplit.png")));
+ appendCursor(Qt::PointingHandCursor, QApplication::translate("QtCursorDatabase", "Pointing Hand", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-hand.png")));
+ appendCursor(Qt::ForbiddenCursor, QApplication::translate("QtCursorDatabase", "Forbidden", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-forbidden.png")));
+ appendCursor(Qt::OpenHandCursor, QApplication::translate("QtCursorDatabase", "Open Hand", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-openhand.png")));
+ appendCursor(Qt::ClosedHandCursor, QApplication::translate("QtCursorDatabase", "Closed Hand", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-closedhand.png")));
+ appendCursor(Qt::WhatsThisCursor, QApplication::translate("QtCursorDatabase", "What's This", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-whatsthis.png")));
+ appendCursor(Qt::BusyCursor, QApplication::translate("QtCursorDatabase", "Busy", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-busy.png")));
+}
+
+void QtCursorDatabase::clear()
+{
+ m_cursorNames.clear();
+ m_cursorIcons.clear();
+ m_valueToCursorShape.clear();
+ m_cursorShapeToValue.clear();
+}
+
+void QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon)
+{
+ if (m_cursorShapeToValue.contains(shape))
+ return;
+ const int value = m_cursorNames.count();
+ m_cursorNames.append(name);
+ m_cursorIcons.insert(value, icon);
+ m_valueToCursorShape.insert(value, shape);
+ m_cursorShapeToValue.insert(shape, value);
+}
+
+QStringList QtCursorDatabase::cursorShapeNames() const
+{
+ return m_cursorNames;
+}
+
+QMap<int, QIcon> QtCursorDatabase::cursorShapeIcons() const
+{
+ return m_cursorIcons;
+}
+
+QString QtCursorDatabase::cursorToShapeName(const QCursor &cursor) const
+{
+ int val = cursorToValue(cursor);
+ if (val >= 0)
+ return m_cursorNames.at(val);
+ return QString();
+}
+
+QIcon QtCursorDatabase::cursorToShapeIcon(const QCursor &cursor) const
+{
+ int val = cursorToValue(cursor);
+ return m_cursorIcons.value(val);
+}
+
+int QtCursorDatabase::cursorToValue(const QCursor &cursor) const
+{
+#ifndef QT_NO_CURSOR
+ Qt::CursorShape shape = cursor.shape();
+ if (m_cursorShapeToValue.contains(shape))
+ return m_cursorShapeToValue[shape];
+#endif
+ return -1;
+}
+
+#ifndef QT_NO_CURSOR
+QCursor QtCursorDatabase::valueToCursor(int value) const
+{
+ if (m_valueToCursorShape.contains(value))
+ return QCursor(m_valueToCursorShape[value]);
+ return QCursor();
+}
+#endif
+
+QPixmap QtPropertyBrowserUtils::brushValuePixmap(const QBrush &b)
+{
+ QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+
+ QPainter painter(&img);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.fillRect(0, 0, img.width(), img.height(), b);
+ QColor color = b.color();
+ if (color.alpha() != 255) { // indicate alpha by an inset
+ QBrush opaqueBrush = b;
+ color.setAlpha(255);
+ opaqueBrush.setColor(color);
+ painter.fillRect(img.width() / 4, img.height() / 4,
+ img.width() / 2, img.height() / 2, opaqueBrush);
+ }
+ painter.end();
+ return QPixmap::fromImage(img);
+}
+
+QIcon QtPropertyBrowserUtils::brushValueIcon(const QBrush &b)
+{
+ return QIcon(brushValuePixmap(b));
+}
+
+QString QtPropertyBrowserUtils::colorValueText(const QColor &c)
+{
+ return QApplication::translate("QtPropertyBrowserUtils", "[%1, %2, %3] (%4)", 0, QApplication::UnicodeUTF8)
+ .arg(QString::number(c.red()))
+ .arg(QString::number(c.green()))
+ .arg(QString::number(c.blue()))
+ .arg(QString::number(c.alpha()));
+}
+
+QPixmap QtPropertyBrowserUtils::fontValuePixmap(const QFont &font)
+{
+ QFont f = font;
+ QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+ QPainter p(&img);
+ p.setRenderHint(QPainter::TextAntialiasing, true);
+ p.setRenderHint(QPainter::Antialiasing, true);
+ f.setPointSize(13);
+ p.setFont(f);
+ QTextOption t;
+ t.setAlignment(Qt::AlignCenter);
+ p.drawText(QRect(0, 0, 16, 16), QString(QLatin1Char('A')), t);
+ return QPixmap::fromImage(img);
+}
+
+QIcon QtPropertyBrowserUtils::fontValueIcon(const QFont &f)
+{
+ return QIcon(fontValuePixmap(f));
+}
+
+QString QtPropertyBrowserUtils::fontValueText(const QFont &f)
+{
+ return QApplication::translate("QtPropertyBrowserUtils", "[%1, %2]", 0, QApplication::UnicodeUTF8)
+ .arg(f.family())
+ .arg(f.pointSize());
+}
+
+QString QtPropertyBrowserUtils::dateFormat()
+{
+ QLocale loc;
+ return loc.dateFormat(QLocale::ShortFormat);
+}
+
+QString QtPropertyBrowserUtils::timeFormat()
+{
+ QLocale loc;
+ // ShortFormat is missing seconds on UNIX.
+ return loc.timeFormat(QLocale::LongFormat);
+}
+
+QString QtPropertyBrowserUtils::dateTimeFormat()
+{
+ QString format = dateFormat();
+ format += QLatin1Char(' ');
+ format += timeFormat();
+ return format;
+}
+
+QtBoolEdit::QtBoolEdit(QWidget *parent) :
+ QWidget(parent),
+ m_checkBox(new QCheckBox(this)),
+ m_textVisible(true)
+{
+ QHBoxLayout *lt = new QHBoxLayout;
+ if (QApplication::layoutDirection() == Qt::LeftToRight)
+ lt->setContentsMargins(4, 0, 0, 0);
+ else
+ lt->setContentsMargins(0, 0, 4, 0);
+ lt->addWidget(m_checkBox);
+ setLayout(lt);
+ connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
+ setFocusProxy(m_checkBox);
+ m_checkBox->setText(tr("True"));
+}
+
+void QtBoolEdit::setTextVisible(bool textVisible)
+{
+ if (m_textVisible == textVisible)
+ return;
+
+ m_textVisible = textVisible;
+ if (m_textVisible)
+ m_checkBox->setText(isChecked() ? tr("True") : tr("False"));
+ else
+ m_checkBox->setText(QString());
+}
+
+Qt::CheckState QtBoolEdit::checkState() const
+{
+ return m_checkBox->checkState();
+}
+
+void QtBoolEdit::setCheckState(Qt::CheckState state)
+{
+ m_checkBox->setCheckState(state);
+}
+
+bool QtBoolEdit::isChecked() const
+{
+ return m_checkBox->isChecked();
+}
+
+void QtBoolEdit::setChecked(bool c)
+{
+ m_checkBox->setChecked(c);
+ if (!m_textVisible)
+ return;
+ m_checkBox->setText(isChecked() ? tr("True") : tr("False"));
+}
+
+bool QtBoolEdit::blockCheckBoxSignals(bool block)
+{
+ return m_checkBox->blockSignals(block);
+}
+
+void QtBoolEdit::mousePressEvent(QMouseEvent *event)
+{
+ if (event->buttons() == Qt::LeftButton) {
+ m_checkBox->click();
+ event->accept();
+ } else {
+ QWidget::mousePressEvent(event);
+ }
+}
+
+
+QtKeySequenceEdit::QtKeySequenceEdit(QWidget *parent)
+ : QWidget(parent), m_num(0), m_lineEdit(new QLineEdit(this))
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->addWidget(m_lineEdit);
+ layout->setMargin(0);
+ m_lineEdit->installEventFilter(this);
+ m_lineEdit->setReadOnly(true);
+ m_lineEdit->setFocusProxy(this);
+ setFocusPolicy(m_lineEdit->focusPolicy());
+ setAttribute(Qt::WA_InputMethodEnabled);
+}
+
+bool QtKeySequenceEdit::eventFilter(QObject *o, QEvent *e)
+{
+ if (o == m_lineEdit && e->type() == QEvent::ContextMenu) {
+ QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
+ QMenu *menu = m_lineEdit->createStandardContextMenu();
+ const QList<QAction *> actions = menu->actions();
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ action->setShortcut(QKeySequence());
+ QString actionString = action->text();
+ const int pos = actionString.lastIndexOf(QLatin1Char('\t'));
+ if (pos > 0)
+ actionString.remove(pos, actionString.length() - pos);
+ action->setText(actionString);
+ }
+ QAction *actionBefore = 0;
+ if (actions.count() > 0)
+ actionBefore = actions[0];
+ QAction *clearAction = new QAction(tr("Clear Shortcut"), menu);
+ menu->insertAction(actionBefore, clearAction);
+ menu->insertSeparator(actionBefore);
+ clearAction->setEnabled(!m_keySequence.isEmpty());
+ connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearShortcut()));
+ menu->exec(c->globalPos());
+ delete menu;
+ e->accept();
+ return true;
+ }
+
+ return QWidget::eventFilter(o, e);
+}
+
+void QtKeySequenceEdit::slotClearShortcut()
+{
+ if (m_keySequence.isEmpty())
+ return;
+ setKeySequence(QKeySequence());
+ emit keySequenceChanged(m_keySequence);
+}
+
+void QtKeySequenceEdit::handleKeyEvent(QKeyEvent *e)
+{
+ int nextKey = e->key();
+ if (nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift ||
+ nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt ||
+ nextKey == Qt::Key_Super_L || nextKey == Qt::Key_AltGr)
+ return;
+
+ nextKey |= translateModifiers(e->modifiers(), e->text());
+ int k0 = m_keySequence[0];
+ int k1 = m_keySequence[1];
+ int k2 = m_keySequence[2];
+ int k3 = m_keySequence[3];
+ switch (m_num) {
+ case 0: k0 = nextKey; k1 = 0; k2 = 0; k3 = 0; break;
+ case 1: k1 = nextKey; k2 = 0; k3 = 0; break;
+ case 2: k2 = nextKey; k3 = 0; break;
+ case 3: k3 = nextKey; break;
+ default: break;
+ }
+ ++m_num;
+ if (m_num > 3)
+ m_num = 0;
+ m_keySequence = QKeySequence(k0, k1, k2, k3);
+ m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
+ e->accept();
+ emit keySequenceChanged(m_keySequence);
+}
+
+void QtKeySequenceEdit::setKeySequence(const QKeySequence &sequence)
+{
+ if (sequence == m_keySequence)
+ return;
+ m_num = 0;
+ m_keySequence = sequence;
+ m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
+}
+
+QKeySequence QtKeySequenceEdit::keySequence() const
+{
+ return m_keySequence;
+}
+
+int QtKeySequenceEdit::translateModifiers(Qt::KeyboardModifiers state, const QString &text) const
+{
+ int result = 0;
+ if ((state & Qt::ShiftModifier) && (text.size() == 0 || !text.at(0).isPrint() || text.at(0).isLetter() || text.at(0).isSpace()))
+ result |= Qt::SHIFT;
+ if (state & Qt::ControlModifier)
+ result |= Qt::CTRL;
+ if (state & Qt::MetaModifier)
+ result |= Qt::META;
+ if (state & Qt::AltModifier)
+ result |= Qt::ALT;
+ return result;
+}
+
+void QtKeySequenceEdit::focusInEvent(QFocusEvent *e)
+{
+ m_lineEdit->event(e);
+ m_lineEdit->selectAll();
+ QWidget::focusInEvent(e);
+}
+
+void QtKeySequenceEdit::focusOutEvent(QFocusEvent *e)
+{
+ m_num = 0;
+ m_lineEdit->event(e);
+ QWidget::focusOutEvent(e);
+}
+
+void QtKeySequenceEdit::keyPressEvent(QKeyEvent *e)
+{
+ handleKeyEvent(e);
+ e->accept();
+}
+
+void QtKeySequenceEdit::keyReleaseEvent(QKeyEvent *e)
+{
+ m_lineEdit->event(e);
+}
+
+bool QtKeySequenceEdit::event(QEvent *e)
+{
+ if (e->type() == QEvent::Shortcut ||
+ e->type() == QEvent::ShortcutOverride ||
+ e->type() == QEvent::KeyRelease) {
+ e->accept();
+ return true;
+ }
+ return QWidget::event(e);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowserutils.pri b/src/shared/qtpropertybrowser/qtpropertybrowserutils.pri
new file mode 100644
index 000000000..17554481c
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowserutils.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qtpropertybrowserutils.cpp
+HEADERS += $$PWD/qtpropertybrowserutils_p.h
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowserutils_p.h b/src/shared/qtpropertybrowser/qtpropertybrowserutils_p.h
new file mode 100644
index 000000000..440ec9a11
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowserutils_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QTPROPERTYBROWSERUTILS_H
+#define QTPROPERTYBROWSERUTILS_H
+
+#include <QtCore/QMap>
+#include <QtGui/QIcon>
+#include <QtGui/QWidget>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QMouseEvent;
+class QCheckBox;
+class QLineEdit;
+
+class QtCursorDatabase
+{
+public:
+ QtCursorDatabase();
+ void clear();
+
+ QStringList cursorShapeNames() const;
+ QMap<int, QIcon> cursorShapeIcons() const;
+ QString cursorToShapeName(const QCursor &cursor) const;
+ QIcon cursorToShapeIcon(const QCursor &cursor) const;
+ int cursorToValue(const QCursor &cursor) const;
+#ifndef QT_NO_CURSOR
+ QCursor valueToCursor(int value) const;
+#endif
+private:
+ void appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon);
+ QStringList m_cursorNames;
+ QMap<int, QIcon> m_cursorIcons;
+ QMap<int, Qt::CursorShape> m_valueToCursorShape;
+ QMap<Qt::CursorShape, int> m_cursorShapeToValue;
+};
+
+class QtPropertyBrowserUtils
+{
+public:
+ static QPixmap brushValuePixmap(const QBrush &b);
+ static QIcon brushValueIcon(const QBrush &b);
+ static QString colorValueText(const QColor &c);
+ static QPixmap fontValuePixmap(const QFont &f);
+ static QIcon fontValueIcon(const QFont &f);
+ static QString fontValueText(const QFont &f);
+ static QString dateFormat();
+ static QString timeFormat();
+ static QString dateTimeFormat();
+};
+
+class QtBoolEdit : public QWidget {
+ Q_OBJECT
+public:
+ QtBoolEdit(QWidget *parent = 0);
+
+ bool textVisible() const { return m_textVisible; }
+ void setTextVisible(bool textVisible);
+
+ Qt::CheckState checkState() const;
+ void setCheckState(Qt::CheckState state);
+
+ bool isChecked() const;
+ void setChecked(bool c);
+
+ bool blockCheckBoxSignals(bool block);
+
+Q_SIGNALS:
+ void toggled(bool);
+
+protected:
+ void mousePressEvent(QMouseEvent * event);
+
+private:
+ QCheckBox *m_checkBox;
+ bool m_textVisible;
+};
+
+class QtKeySequenceEdit : public QWidget
+{
+ Q_OBJECT
+public:
+ QtKeySequenceEdit(QWidget *parent = 0);
+
+ QKeySequence keySequence() const;
+ bool eventFilter(QObject *o, QEvent *e);
+public Q_SLOTS:
+ void setKeySequence(const QKeySequence &sequence);
+Q_SIGNALS:
+ void keySequenceChanged(const QKeySequence &sequence);
+protected:
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
+ bool event(QEvent *e);
+private slots:
+ void slotClearShortcut();
+private:
+ void handleKeyEvent(QKeyEvent *e);
+ int translateModifiers(Qt::KeyboardModifiers state, const QString &text) const;
+
+ int m_num;
+ QKeySequence m_keySequence;
+ QLineEdit *m_lineEdit;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qtpropertymanager.cpp b/src/shared/qtpropertybrowser/qtpropertymanager.cpp
new file mode 100644
index 000000000..962e35727
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertymanager.cpp
@@ -0,0 +1,6451 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtpropertymanager.h"
+#include "qtpropertybrowserutils_p.h"
+#include <QtCore/QDateTime>
+#include <QtCore/QLocale>
+#include <QtCore/QMap>
+#include <QtCore/QTimer>
+#include <QtGui/QIcon>
+#include <QtCore/QMetaEnum>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QStyleOption>
+#include <QtGui/QStyle>
+#include <QtGui/QApplication>
+#include <QtGui/QPainter>
+#include <QtGui/QLabel>
+
+#include <limits.h>
+#include <float.h>
+
+#if defined(Q_CC_MSVC)
+# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
+#endif
+
+QT_BEGIN_NAMESPACE
+
+template <class PrivateData, class Value>
+static void setSimpleMinimumData(PrivateData *data, const Value &minVal)
+{
+ data->minVal = minVal;
+ if (data->maxVal < data->minVal)
+ data->maxVal = data->minVal;
+
+ if (data->val < data->minVal)
+ data->val = data->minVal;
+}
+
+template <class PrivateData, class Value>
+static void setSimpleMaximumData(PrivateData *data, const Value &maxVal)
+{
+ data->maxVal = maxVal;
+ if (data->minVal > data->maxVal)
+ data->minVal = data->maxVal;
+
+ if (data->val > data->maxVal)
+ data->val = data->maxVal;
+}
+
+template <class PrivateData, class Value>
+static void setSizeMinimumData(PrivateData *data, const Value &newMinVal)
+{
+ data->minVal = newMinVal;
+ if (data->maxVal.width() < data->minVal.width())
+ data->maxVal.setWidth(data->minVal.width());
+ if (data->maxVal.height() < data->minVal.height())
+ data->maxVal.setHeight(data->minVal.height());
+
+ if (data->val.width() < data->minVal.width())
+ data->val.setWidth(data->minVal.width());
+ if (data->val.height() < data->minVal.height())
+ data->val.setHeight(data->minVal.height());
+}
+
+template <class PrivateData, class Value>
+static void setSizeMaximumData(PrivateData *data, const Value &newMaxVal)
+{
+ data->maxVal = newMaxVal;
+ if (data->minVal.width() > data->maxVal.width())
+ data->minVal.setWidth(data->maxVal.width());
+ if (data->minVal.height() > data->maxVal.height())
+ data->minVal.setHeight(data->maxVal.height());
+
+ if (data->val.width() > data->maxVal.width())
+ data->val.setWidth(data->maxVal.width());
+ if (data->val.height() > data->maxVal.height())
+ data->val.setHeight(data->maxVal.height());
+}
+
+template <class SizeValue>
+static SizeValue qBoundSize(const SizeValue &minVal, const SizeValue &val, const SizeValue &maxVal)
+{
+ SizeValue croppedVal = val;
+ if (minVal.width() > val.width())
+ croppedVal.setWidth(minVal.width());
+ else if (maxVal.width() < val.width())
+ croppedVal.setWidth(maxVal.width());
+
+ if (minVal.height() > val.height())
+ croppedVal.setHeight(minVal.height());
+ else if (maxVal.height() < val.height())
+ croppedVal.setHeight(maxVal.height());
+
+ return croppedVal;
+}
+
+// Match the exact signature of qBound for VS 6.
+QSize qBound(QSize minVal, QSize val, QSize maxVal)
+{
+ return qBoundSize(minVal, val, maxVal);
+}
+
+QSizeF qBound(QSizeF minVal, QSizeF val, QSizeF maxVal)
+{
+ return qBoundSize(minVal, val, maxVal);
+}
+
+namespace {
+
+namespace {
+template <class Value>
+void orderBorders(Value &minVal, Value &maxVal)
+{
+ if (minVal > maxVal)
+ qSwap(minVal, maxVal);
+}
+
+template <class Value>
+static void orderSizeBorders(Value &minVal, Value &maxVal)
+{
+ Value fromSize = minVal;
+ Value toSize = maxVal;
+ if (fromSize.width() > toSize.width()) {
+ fromSize.setWidth(maxVal.width());
+ toSize.setWidth(minVal.width());
+ }
+ if (fromSize.height() > toSize.height()) {
+ fromSize.setHeight(maxVal.height());
+ toSize.setHeight(minVal.height());
+ }
+ minVal = fromSize;
+ maxVal = toSize;
+}
+
+void orderBorders(QSize &minVal, QSize &maxVal)
+{
+ orderSizeBorders(minVal, maxVal);
+}
+
+void orderBorders(QSizeF &minVal, QSizeF &maxVal)
+{
+ orderSizeBorders(minVal, maxVal);
+}
+
+}
+}
+////////
+
+template <class Value, class PrivateData>
+static Value getData(const QMap<const QtProperty *, PrivateData> &propertyMap,
+ Value PrivateData::*data,
+ const QtProperty *property, const Value &defaultValue = Value())
+{
+ typedef QMap<const QtProperty *, PrivateData> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::const_iterator PropertyToDataConstIterator;
+ const PropertyToDataConstIterator it = propertyMap.constFind(property);
+ if (it == propertyMap.constEnd())
+ return defaultValue;
+ return it.value().*data;
+}
+
+template <class Value, class PrivateData>
+static Value getValue(const QMap<const QtProperty *, PrivateData> &propertyMap,
+ const QtProperty *property, const Value &defaultValue = Value())
+{
+ return getData<Value>(propertyMap, &PrivateData::val, property, defaultValue);
+}
+
+template <class Value, class PrivateData>
+static Value getMinimum(const QMap<const QtProperty *, PrivateData> &propertyMap,
+ const QtProperty *property, const Value &defaultValue = Value())
+{
+ return getData<Value>(propertyMap, &PrivateData::minVal, property, defaultValue);
+}
+
+template <class Value, class PrivateData>
+static Value getMaximum(const QMap<const QtProperty *, PrivateData> &propertyMap,
+ const QtProperty *property, const Value &defaultValue = Value())
+{
+ return getData<Value>(propertyMap, &PrivateData::maxVal, property, defaultValue);
+}
+
+template <class ValueChangeParameter, class Value, class PropertyManager>
+static void setSimpleValue(QMap<const QtProperty *, Value> &propertyMap,
+ PropertyManager *manager,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ QtProperty *property, const Value &val)
+{
+ typedef QMap<const QtProperty *, Value> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator;
+ const PropertyToDataIterator it = propertyMap.find(property);
+ if (it == propertyMap.end())
+ return;
+
+ if (it.value() == val)
+ return;
+
+ it.value() = val;
+
+ emit (manager->*propertyChangedSignal)(property);
+ emit (manager->*valueChangedSignal)(property, val);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value>
+static void setValueInRange(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ QtProperty *property, const Value &val,
+ void (PropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, ValueChangeParameter))
+{
+ typedef Q_TYPENAME PropertyManagerPrivate::Data PrivateData;
+ typedef QMap<const QtProperty *, PrivateData> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator;
+ const PropertyToDataIterator it = managerPrivate->m_values.find(property);
+ if (it == managerPrivate->m_values.end())
+ return;
+
+ PrivateData &data = it.value();
+
+ if (data.val == val)
+ return;
+
+ const Value oldVal = data.val;
+
+ data.val = qBound(data.minVal, val, data.maxVal);
+
+ if (data.val == oldVal)
+ return;
+
+ if (setSubPropertyValue)
+ (managerPrivate->*setSubPropertyValue)(property, data.val);
+
+ emit (manager->*propertyChangedSignal)(property);
+ emit (manager->*valueChangedSignal)(property, data.val);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value>
+static void setBorderValues(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter),
+ QtProperty *property, const Value &minVal, const Value &maxVal,
+ void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *,
+ ValueChangeParameter, ValueChangeParameter, ValueChangeParameter))
+{
+ typedef Q_TYPENAME PropertyManagerPrivate::Data PrivateData;
+ typedef QMap<const QtProperty *, PrivateData> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator;
+ const PropertyToDataIterator it = managerPrivate->m_values.find(property);
+ if (it == managerPrivate->m_values.end())
+ return;
+
+ Value fromVal = minVal;
+ Value toVal = maxVal;
+ orderBorders(fromVal, toVal);
+
+ PrivateData &data = it.value();
+
+ if (data.minVal == fromVal && data.maxVal == toVal)
+ return;
+
+ const Value oldVal = data.val;
+
+ data.setMinimumValue(fromVal);
+ data.setMaximumValue(toVal);
+
+ emit (manager->*rangeChangedSignal)(property, data.minVal, data.maxVal);
+
+ if (setSubPropertyRange)
+ (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val);
+
+ if (data.val == oldVal)
+ return;
+
+ emit (manager->*propertyChangedSignal)(property);
+ emit (manager->*valueChangedSignal)(property, data.val);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
+static void setBorderValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter),
+ QtProperty *property,
+ Value (PrivateData::*getRangeVal)() const,
+ void (PrivateData::*setRangeVal)(ValueChangeParameter), const Value &borderVal,
+ void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *,
+ ValueChangeParameter, ValueChangeParameter, ValueChangeParameter))
+{
+ typedef QMap<const QtProperty *, PrivateData> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator;
+ const PropertyToDataIterator it = managerPrivate->m_values.find(property);
+ if (it == managerPrivate->m_values.end())
+ return;
+
+ PrivateData &data = it.value();
+
+ if ((data.*getRangeVal)() == borderVal)
+ return;
+
+ const Value oldVal = data.val;
+
+ (data.*setRangeVal)(borderVal);
+
+ emit (manager->*rangeChangedSignal)(property, data.minVal, data.maxVal);
+
+ if (setSubPropertyRange)
+ (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val);
+
+ if (data.val == oldVal)
+ return;
+
+ emit (manager->*propertyChangedSignal)(property);
+ emit (manager->*valueChangedSignal)(property, data.val);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
+static void setMinimumValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter),
+ QtProperty *property, const Value &minVal)
+{
+ void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *,
+ ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0;
+ setBorderValue<ValueChangeParameter, PropertyManagerPrivate, PropertyManager, Value, PrivateData>(manager, managerPrivate,
+ propertyChangedSignal, valueChangedSignal, rangeChangedSignal,
+ property, &PropertyManagerPrivate::Data::minimumValue, &PropertyManagerPrivate::Data::setMinimumValue, minVal, setSubPropertyRange);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
+static void setMaximumValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter),
+ QtProperty *property, const Value &maxVal)
+{
+ void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *,
+ ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0;
+ setBorderValue<ValueChangeParameter, PropertyManagerPrivate, PropertyManager, Value, PrivateData>(manager, managerPrivate,
+ propertyChangedSignal, valueChangedSignal, rangeChangedSignal,
+ property, &PropertyManagerPrivate::Data::maximumValue, &PropertyManagerPrivate::Data::setMaximumValue, maxVal, setSubPropertyRange);
+}
+
+class QtMetaEnumWrapper : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QSizePolicy::Policy policy READ policy)
+public:
+ QSizePolicy::Policy policy() const { return QSizePolicy::Ignored; }
+private:
+ QtMetaEnumWrapper(QObject *parent) : QObject(parent) {}
+};
+
+class QtMetaEnumProvider
+{
+public:
+ QtMetaEnumProvider();
+
+ QStringList policyEnumNames() const { return m_policyEnumNames; }
+ QStringList languageEnumNames() const { return m_languageEnumNames; }
+ QStringList countryEnumNames(QLocale::Language language) const { return m_countryEnumNames.value(language); }
+
+ QSizePolicy::Policy indexToSizePolicy(int index) const;
+ int sizePolicyToIndex(QSizePolicy::Policy policy) const;
+
+ void indexToLocale(int languageIndex, int countryIndex, QLocale::Language *language, QLocale::Country *country) const;
+ void localeToIndex(QLocale::Language language, QLocale::Country country, int *languageIndex, int *countryIndex) const;
+
+private:
+ void initLocale();
+
+ QStringList m_policyEnumNames;
+ QStringList m_languageEnumNames;
+ QMap<QLocale::Language, QStringList> m_countryEnumNames;
+ QMap<int, QLocale::Language> m_indexToLanguage;
+ QMap<QLocale::Language, int> m_languageToIndex;
+ QMap<int, QMap<int, QLocale::Country> > m_indexToCountry;
+ QMap<QLocale::Language, QMap<QLocale::Country, int> > m_countryToIndex;
+ QMetaEnum m_policyEnum;
+};
+
+static QList<QLocale::Country> sortCountries(const QList<QLocale::Country> &countries)
+{
+ QMultiMap<QString, QLocale::Country> nameToCountry;
+ QListIterator<QLocale::Country> itCountry(countries);
+ while (itCountry.hasNext()) {
+ QLocale::Country country = itCountry.next();
+ nameToCountry.insert(QLocale::countryToString(country), country);
+ }
+ return nameToCountry.values();
+}
+
+void QtMetaEnumProvider::initLocale()
+{
+ QMultiMap<QString, QLocale::Language> nameToLanguage;
+ QLocale::Language language = QLocale::C;
+ while (language <= QLocale::LastLanguage) {
+ QLocale locale(language);
+ if (locale.language() == language)
+ nameToLanguage.insert(QLocale::languageToString(language), language);
+ language = (QLocale::Language)((uint)language + 1); // ++language
+ }
+
+ const QLocale system = QLocale::system();
+ if (!nameToLanguage.contains(QLocale::languageToString(system.language())))
+ nameToLanguage.insert(QLocale::languageToString(system.language()), system.language());
+
+ QList<QLocale::Language> languages = nameToLanguage.values();
+ QListIterator<QLocale::Language> itLang(languages);
+ while (itLang.hasNext()) {
+ QLocale::Language language = itLang.next();
+ QList<QLocale::Country> countries;
+ countries = QLocale::countriesForLanguage(language);
+ if (countries.isEmpty() && language == system.language())
+ countries << system.country();
+
+ if (!countries.isEmpty() && !m_languageToIndex.contains(language)) {
+ countries = sortCountries(countries);
+ int langIdx = m_languageEnumNames.count();
+ m_indexToLanguage[langIdx] = language;
+ m_languageToIndex[language] = langIdx;
+ QStringList countryNames;
+ QListIterator<QLocale::Country> it(countries);
+ int countryIdx = 0;
+ while (it.hasNext()) {
+ QLocale::Country country = it.next();
+ countryNames << QLocale::countryToString(country);
+ m_indexToCountry[langIdx][countryIdx] = country;
+ m_countryToIndex[language][country] = countryIdx;
+ ++countryIdx;
+ }
+ m_languageEnumNames << QLocale::languageToString(language);
+ m_countryEnumNames[language] = countryNames;
+ }
+ }
+}
+
+QtMetaEnumProvider::QtMetaEnumProvider()
+{
+ QMetaProperty p;
+
+ p = QtMetaEnumWrapper::staticMetaObject.property(
+ QtMetaEnumWrapper::staticMetaObject.propertyOffset() + 0);
+ m_policyEnum = p.enumerator();
+ const int keyCount = m_policyEnum.keyCount();
+ for (int i = 0; i < keyCount; i++)
+ m_policyEnumNames << QLatin1String(m_policyEnum.key(i));
+
+ initLocale();
+}
+
+QSizePolicy::Policy QtMetaEnumProvider::indexToSizePolicy(int index) const
+{
+ return static_cast<QSizePolicy::Policy>(m_policyEnum.value(index));
+}
+
+int QtMetaEnumProvider::sizePolicyToIndex(QSizePolicy::Policy policy) const
+{
+ const int keyCount = m_policyEnum.keyCount();
+ for (int i = 0; i < keyCount; i++)
+ if (indexToSizePolicy(i) == policy)
+ return i;
+ return -1;
+}
+
+void QtMetaEnumProvider::indexToLocale(int languageIndex, int countryIndex, QLocale::Language *language, QLocale::Country *country) const
+{
+ QLocale::Language l = QLocale::C;
+ QLocale::Country c = QLocale::AnyCountry;
+ if (m_indexToLanguage.contains(languageIndex)) {
+ l = m_indexToLanguage[languageIndex];
+ if (m_indexToCountry.contains(languageIndex) && m_indexToCountry[languageIndex].contains(countryIndex))
+ c = m_indexToCountry[languageIndex][countryIndex];
+ }
+ if (language)
+ *language = l;
+ if (country)
+ *country = c;
+}
+
+void QtMetaEnumProvider::localeToIndex(QLocale::Language language, QLocale::Country country, int *languageIndex, int *countryIndex) const
+{
+ int l = -1;
+ int c = -1;
+ if (m_languageToIndex.contains(language)) {
+ l = m_languageToIndex[language];
+ if (m_countryToIndex.contains(language) && m_countryToIndex[language].contains(country))
+ c = m_countryToIndex[language][country];
+ }
+
+ if (languageIndex)
+ *languageIndex = l;
+ if (countryIndex)
+ *countryIndex = c;
+}
+
+Q_GLOBAL_STATIC(QtMetaEnumProvider, metaEnumProvider)
+
+// QtGroupPropertyManager
+
+/*!
+ \class QtGroupPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtGroupPropertyManager provides and manages group properties.
+
+ This class is intended to provide a grouping element without any value.
+
+ \sa QtAbstractPropertyManager
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtGroupPropertyManager::QtGroupPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent)
+{
+
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtGroupPropertyManager::~QtGroupPropertyManager()
+{
+
+}
+
+/*!
+ \reimp
+*/
+bool QtGroupPropertyManager::hasValue(const QtProperty *property) const
+{
+ Q_UNUSED(property)
+ return false;
+}
+
+/*!
+ \reimp
+*/
+void QtGroupPropertyManager::initializeProperty(QtProperty *property)
+{
+ Q_UNUSED(property)
+}
+
+/*!
+ \reimp
+*/
+void QtGroupPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ Q_UNUSED(property)
+}
+
+// QtIntPropertyManager
+
+class QtIntPropertyManagerPrivate
+{
+ QtIntPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtIntPropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1) {}
+ int val;
+ int minVal;
+ int maxVal;
+ int singleStep;
+ int minimumValue() const { return minVal; }
+ int maximumValue() const { return maxVal; }
+ void setMinimumValue(int newMinVal) { setSimpleMinimumData(this, newMinVal); }
+ void setMaximumValue(int newMaxVal) { setSimpleMaximumData(this, newMaxVal); }
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*!
+ \class QtIntPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtIntPropertyManager provides and manages int properties.
+
+ An int property has a current value, and a range specifying the
+ valid values. The range is defined by a minimum and a maximum
+ value.
+
+ The property's value and range can be retrieved using the value(),
+ minimum() and maximum() functions, and can be set using the
+ setValue(), setMinimum() and setMaximum() slots. Alternatively,
+ the range can be defined in one go using the setRange() slot.
+
+ In addition, QtIntPropertyManager provides the valueChanged() signal which
+ is emitted whenever a property created by this manager changes,
+ and the rangeChanged() signal which is emitted whenever such a
+ property changes its range of valid values.
+
+ \sa QtAbstractPropertyManager, QtSpinBoxFactory, QtSliderFactory, QtScrollBarFactory
+*/
+
+/*!
+ \fn void QtIntPropertyManager::valueChanged(QtProperty *property, int value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtIntPropertyManager::rangeChanged(QtProperty *property, int minimum, int maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid values, passing a pointer to the
+ \a property and the new \a minimum and \a maximum values.
+
+ \sa setRange()
+*/
+
+/*!
+ \fn void QtIntPropertyManager::singleStepChanged(QtProperty *property, int step)
+
+ This signal is emitted whenever a property created by this manager
+ changes its single step property, passing a pointer to the
+ \a property and the new \a step value
+
+ \sa setSingleStep()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtIntPropertyManager::QtIntPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtIntPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtIntPropertyManager::~QtIntPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns 0.
+
+ \sa setValue()
+*/
+int QtIntPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<int>(d_ptr->m_values, property, 0);
+}
+
+/*!
+ Returns the given \a property's minimum value.
+
+ \sa setMinimum(), maximum(), setRange()
+*/
+int QtIntPropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<int>(d_ptr->m_values, property, 0);
+}
+
+/*!
+ Returns the given \a property's maximum value.
+
+ \sa setMaximum(), minimum(), setRange()
+*/
+int QtIntPropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<int>(d_ptr->m_values, property, 0);
+}
+
+/*!
+ Returns the given \a property's step value.
+
+ The step is typically used to increment or decrement a property value while pressing an arrow key.
+
+ \sa setSingleStep()
+*/
+int QtIntPropertyManager::singleStep(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtIntPropertyManagerPrivate::Data::singleStep, property, 0);
+}
+
+/*!
+ \reimp
+*/
+QString QtIntPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtIntPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return QString::number(it.value().val);
+}
+
+/*!
+ \fn void QtIntPropertyManager::setValue(QtProperty *property, int value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not valid according to the given \a
+ property's range, the \a value is adjusted to the nearest valid
+ value within the range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtIntPropertyManager::setValue(QtProperty *property, int val)
+{
+ void (QtIntPropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, int) = 0;
+ setValueInRange<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int>(this, d_ptr.data(),
+ &QtIntPropertyManager::propertyChanged,
+ &QtIntPropertyManager::valueChanged,
+ property, val, setSubPropertyValue);
+}
+
+/*!
+ Sets the minimum value for the given \a property to \a minVal.
+
+ When setting the minimum value, the maximum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within the range).
+
+ \sa minimum(), setRange(), rangeChanged()
+*/
+void QtIntPropertyManager::setMinimum(QtProperty *property, int minVal)
+{
+ setMinimumValue<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int, QtIntPropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtIntPropertyManager::propertyChanged,
+ &QtIntPropertyManager::valueChanged,
+ &QtIntPropertyManager::rangeChanged,
+ property, minVal);
+}
+
+/*!
+ Sets the maximum value for the given \a property to \a maxVal.
+
+ When setting maximum value, the minimum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within the range).
+
+ \sa maximum(), setRange(), rangeChanged()
+*/
+void QtIntPropertyManager::setMaximum(QtProperty *property, int maxVal)
+{
+ setMaximumValue<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int, QtIntPropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtIntPropertyManager::propertyChanged,
+ &QtIntPropertyManager::valueChanged,
+ &QtIntPropertyManager::rangeChanged,
+ property, maxVal);
+}
+
+/*!
+ \fn void QtIntPropertyManager::setRange(QtProperty *property, int minimum, int maximum)
+
+ Sets the range of valid values.
+
+ This is a convenience function defining the range of valid values
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new range, the current value is adjusted if
+ necessary (ensuring that the value remains within range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtIntPropertyManager::setRange(QtProperty *property, int minVal, int maxVal)
+{
+ void (QtIntPropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, int, int, int) = 0;
+ setBorderValues<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int>(this, d_ptr.data(),
+ &QtIntPropertyManager::propertyChanged,
+ &QtIntPropertyManager::valueChanged,
+ &QtIntPropertyManager::rangeChanged,
+ property, minVal, maxVal, setSubPropertyRange);
+}
+
+/*!
+ Sets the step value for the given \a property to \a step.
+
+ The step is typically used to increment or decrement a property value while pressing an arrow key.
+
+ \sa singleStep()
+*/
+void QtIntPropertyManager::setSingleStep(QtProperty *property, int step)
+{
+ const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtIntPropertyManagerPrivate::Data data = it.value();
+
+ if (step < 0)
+ step = 0;
+
+ if (data.singleStep == step)
+ return;
+
+ data.singleStep = step;
+
+ it.value() = data;
+
+ emit singleStepChanged(property, data.singleStep);
+}
+
+/*!
+ \reimp
+*/
+void QtIntPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtIntPropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtIntPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtDoublePropertyManager
+
+class QtDoublePropertyManagerPrivate
+{
+ QtDoublePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtDoublePropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1), decimals(2) {}
+ double val;
+ double minVal;
+ double maxVal;
+ double singleStep;
+ int decimals;
+ double minimumValue() const { return minVal; }
+ double maximumValue() const { return maxVal; }
+ void setMinimumValue(double newMinVal) { setSimpleMinimumData(this, newMinVal); }
+ void setMaximumValue(double newMaxVal) { setSimpleMaximumData(this, newMaxVal); }
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*!
+ \class QtDoublePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDoublePropertyManager provides and manages double properties.
+
+ A double property has a current value, and a range specifying the
+ valid values. The range is defined by a minimum and a maximum
+ value.
+
+ The property's value and range can be retrieved using the value(),
+ minimum() and maximum() functions, and can be set using the
+ setValue(), setMinimum() and setMaximum() slots.
+ Alternatively, the range can be defined in one go using the
+ setRange() slot.
+
+ In addition, QtDoublePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the rangeChanged() signal which is emitted whenever
+ such a property changes its range of valid values.
+
+ \sa QtAbstractPropertyManager, QtDoubleSpinBoxFactory
+*/
+
+/*!
+ \fn void QtDoublePropertyManager::valueChanged(QtProperty *property, double value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtDoublePropertyManager::rangeChanged(QtProperty *property, double minimum, double maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid values, passing a pointer to the
+ \a property and the new \a minimum and \a maximum values
+
+ \sa setRange()
+*/
+
+/*!
+ \fn void QtDoublePropertyManager::decimalsChanged(QtProperty *property, int prec)
+
+ This signal is emitted whenever a property created by this manager
+ changes its precision of value, passing a pointer to the
+ \a property and the new \a prec value
+
+ \sa setDecimals()
+*/
+
+/*!
+ \fn void QtDoublePropertyManager::singleStepChanged(QtProperty *property, double step)
+
+ This signal is emitted whenever a property created by this manager
+ changes its single step property, passing a pointer to the
+ \a property and the new \a step value
+
+ \sa setSingleStep()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtDoublePropertyManager::QtDoublePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtDoublePropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtDoublePropertyManager::~QtDoublePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns 0.
+
+ \sa setValue()
+*/
+double QtDoublePropertyManager::value(const QtProperty *property) const
+{
+ return getValue<double>(d_ptr->m_values, property, 0.0);
+}
+
+/*!
+ Returns the given \a property's minimum value.
+
+ \sa maximum(), setRange()
+*/
+double QtDoublePropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<double>(d_ptr->m_values, property, 0.0);
+}
+
+/*!
+ Returns the given \a property's maximum value.
+
+ \sa minimum(), setRange()
+*/
+double QtDoublePropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<double>(d_ptr->m_values, property, 0.0);
+}
+
+/*!
+ Returns the given \a property's step value.
+
+ The step is typically used to increment or decrement a property value while pressing an arrow key.
+
+ \sa setSingleStep()
+*/
+double QtDoublePropertyManager::singleStep(const QtProperty *property) const
+{
+ return getData<double>(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::singleStep, property, 0);
+}
+
+/*!
+ Returns the given \a property's precision, in decimals.
+
+ \sa setDecimals()
+*/
+int QtDoublePropertyManager::decimals(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::decimals, property, 0);
+}
+
+/*!
+ \reimp
+*/
+QString QtDoublePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtDoublePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return QString::number(it.value().val, 'f', it.value().decimals);
+}
+
+/*!
+ \fn void QtDoublePropertyManager::setValue(QtProperty *property, double value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not valid according to the given
+ \a property's range, the \a value is adjusted to the nearest valid value
+ within the range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtDoublePropertyManager::setValue(QtProperty *property, double val)
+{
+ void (QtDoublePropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, double) = 0;
+ setValueInRange<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double>(this, d_ptr.data(),
+ &QtDoublePropertyManager::propertyChanged,
+ &QtDoublePropertyManager::valueChanged,
+ property, val, setSubPropertyValue);
+}
+
+/*!
+ Sets the step value for the given \a property to \a step.
+
+ The step is typically used to increment or decrement a property value while pressing an arrow key.
+
+ \sa singleStep()
+*/
+void QtDoublePropertyManager::setSingleStep(QtProperty *property, double step)
+{
+ const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtDoublePropertyManagerPrivate::Data data = it.value();
+
+ if (step < 0)
+ step = 0;
+
+ if (data.singleStep == step)
+ return;
+
+ data.singleStep = step;
+
+ it.value() = data;
+
+ emit singleStepChanged(property, data.singleStep);
+}
+
+/*!
+ \fn void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec)
+
+ Sets the precision of the given \a property to \a prec.
+
+ The valid decimal range is 0-13. The default is 2.
+
+ \sa decimals()
+*/
+void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec)
+{
+ const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtDoublePropertyManagerPrivate::Data data = it.value();
+
+ if (prec > 13)
+ prec = 13;
+ else if (prec < 0)
+ prec = 0;
+
+ if (data.decimals == prec)
+ return;
+
+ data.decimals = prec;
+
+ it.value() = data;
+
+ emit decimalsChanged(property, data.decimals);
+}
+
+/*!
+ Sets the minimum value for the given \a property to \a minVal.
+
+ When setting the minimum value, the maximum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within in the range).
+
+ \sa minimum(), setRange(), rangeChanged()
+*/
+void QtDoublePropertyManager::setMinimum(QtProperty *property, double minVal)
+{
+ setMinimumValue<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double, QtDoublePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtDoublePropertyManager::propertyChanged,
+ &QtDoublePropertyManager::valueChanged,
+ &QtDoublePropertyManager::rangeChanged,
+ property, minVal);
+}
+
+/*!
+ Sets the maximum value for the given \a property to \a maxVal.
+
+ When setting the maximum value, the minimum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within in the range).
+
+ \sa maximum(), setRange(), rangeChanged()
+*/
+void QtDoublePropertyManager::setMaximum(QtProperty *property, double maxVal)
+{
+ setMaximumValue<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double, QtDoublePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtDoublePropertyManager::propertyChanged,
+ &QtDoublePropertyManager::valueChanged,
+ &QtDoublePropertyManager::rangeChanged,
+ property, maxVal);
+}
+
+/*!
+ \fn void QtDoublePropertyManager::setRange(QtProperty *property, double minimum, double maximum)
+
+ Sets the range of valid values.
+
+ This is a convenience function defining the range of valid values
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new range, the current value is adjusted if
+ necessary (ensuring that the value remains within range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtDoublePropertyManager::setRange(QtProperty *property, double minVal, double maxVal)
+{
+ void (QtDoublePropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, double, double, double) = 0;
+ setBorderValues<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double>(this, d_ptr.data(),
+ &QtDoublePropertyManager::propertyChanged,
+ &QtDoublePropertyManager::valueChanged,
+ &QtDoublePropertyManager::rangeChanged,
+ property, minVal, maxVal, setSubPropertyRange);
+}
+
+/*!
+ \reimp
+*/
+void QtDoublePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtDoublePropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtDoublePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtStringPropertyManager
+
+class QtStringPropertyManagerPrivate
+{
+ QtStringPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtStringPropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : regExp(QString(QLatin1Char('*')), Qt::CaseSensitive, QRegExp::Wildcard)
+ {
+ }
+ QString val;
+ QRegExp regExp;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ QMap<const QtProperty *, Data> m_values;
+};
+
+/*!
+ \class QtStringPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtStringPropertyManager provides and manages QString properties.
+
+ A string property's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ The current value can be checked against a regular expression. To
+ set the regular expression use the setRegExp() slot, use the
+ regExp() function to retrieve the currently set expression.
+
+ In addition, QtStringPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the regExpChanged() signal which is emitted whenever
+ such a property changes its currently set regular expression.
+
+ \sa QtAbstractPropertyManager, QtLineEditFactory
+*/
+
+/*!
+ \fn void QtStringPropertyManager::valueChanged(QtProperty *property, const QString &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtStringPropertyManager::regExpChanged(QtProperty *property, const QRegExp &regExp)
+
+ This signal is emitted whenever a property created by this manager
+ changes its currenlty set regular expression, passing a pointer to
+ the \a property and the new \a regExp as parameters.
+
+ \sa setRegExp()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtStringPropertyManager::QtStringPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtStringPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtStringPropertyManager::~QtStringPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns an empty string.
+
+ \sa setValue()
+*/
+QString QtStringPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QString>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's currently set regular expression.
+
+ If the given \a property is not managed by this manager, this
+ function returns an empty expression.
+
+ \sa setRegExp()
+*/
+QRegExp QtStringPropertyManager::regExp(const QtProperty *property) const
+{
+ return getData<QRegExp>(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::regExp, property, QRegExp());
+}
+
+/*!
+ \reimp
+*/
+QString QtStringPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtStringPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().val;
+}
+
+/*!
+ \fn void QtStringPropertyManager::setValue(QtProperty *property, const QString &value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value doesn't match the given \a property's
+ regular expression, this function does nothing.
+
+ \sa value(), setRegExp(), valueChanged()
+*/
+void QtStringPropertyManager::setValue(QtProperty *property, const QString &val)
+{
+ const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtStringPropertyManagerPrivate::Data data = it.value();
+
+ if (data.val == val)
+ return;
+
+ if (data.regExp.isValid() && !data.regExp.exactMatch(val))
+ return;
+
+ data.val = val;
+
+ it.value() = data;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the regular expression of the given \a property to \a regExp.
+
+ \sa regExp(), setValue(), regExpChanged()
+*/
+void QtStringPropertyManager::setRegExp(QtProperty *property, const QRegExp &regExp)
+{
+ const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtStringPropertyManagerPrivate::Data data = it.value() ;
+
+ if (data.regExp == regExp)
+ return;
+
+ data.regExp = regExp;
+
+ it.value() = data;
+
+ emit regExpChanged(property, data.regExp);
+}
+
+/*!
+ \reimp
+*/
+void QtStringPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtStringPropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtStringPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtBoolPropertyManager
+// Return an icon containing a check box indicator
+static QIcon drawCheckBox(bool value)
+{
+ QStyleOptionButton opt;
+ opt.state |= value ? QStyle::State_On : QStyle::State_Off;
+ opt.state |= QStyle::State_Enabled;
+ const QStyle *style = QApplication::style();
+ // Figure out size of an indicator and make sure it is not scaled down in a list view item
+ // by making the pixmap as big as a list view icon and centering the indicator in it.
+ // (if it is smaller, it can't be helped)
+ const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt);
+ const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt);
+ const int listViewIconSize = indicatorWidth;
+ const int pixmapWidth = indicatorWidth;
+ const int pixmapHeight = qMax(indicatorHeight, listViewIconSize);
+
+ opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight);
+ QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight);
+ pixmap.fill(Qt::transparent);
+ {
+ // Center?
+ const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0;
+ const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0;
+ QPainter painter(&pixmap);
+ painter.translate(xoff, yoff);
+ style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter);
+ }
+ return QIcon(pixmap);
+}
+
+class QtBoolPropertyManagerPrivate
+{
+ QtBoolPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtBoolPropertyManager)
+public:
+ QtBoolPropertyManagerPrivate();
+
+ QMap<const QtProperty *, bool> m_values;
+ const QIcon m_checkedIcon;
+ const QIcon m_uncheckedIcon;
+};
+
+QtBoolPropertyManagerPrivate::QtBoolPropertyManagerPrivate() :
+ m_checkedIcon(drawCheckBox(true)),
+ m_uncheckedIcon(drawCheckBox(false))
+{
+}
+
+/*!
+ \class QtBoolPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtBoolPropertyManager class provides and manages boolean properties.
+
+ The property's value can be retrieved using the value() function,
+ and set using the setValue() slot.
+
+ In addition, QtBoolPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager, QtCheckBoxFactory
+*/
+
+/*!
+ \fn void QtBoolPropertyManager::valueChanged(QtProperty *property, bool value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtBoolPropertyManager::QtBoolPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtBoolPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtBoolPropertyManager::~QtBoolPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by \e this manager, this
+ function returns false.
+
+ \sa setValue()
+*/
+bool QtBoolPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, false);
+}
+
+/*!
+ \reimp
+*/
+QString QtBoolPropertyManager::valueText(const QtProperty *property) const
+{
+ const QMap<const QtProperty *, bool>::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ static const QString trueText = tr("True");
+ static const QString falseText = tr("False");
+ return it.value() ? trueText : falseText;
+}
+
+/*!
+ \reimp
+*/
+QIcon QtBoolPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QMap<const QtProperty *, bool>::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+
+ return it.value() ? d_ptr->m_checkedIcon : d_ptr->m_uncheckedIcon;
+}
+
+/*!
+ \fn void QtBoolPropertyManager::setValue(QtProperty *property, bool value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value()
+*/
+void QtBoolPropertyManager::setValue(QtProperty *property, bool val)
+{
+ setSimpleValue<bool, bool, QtBoolPropertyManager>(d_ptr->m_values, this,
+ &QtBoolPropertyManager::propertyChanged,
+ &QtBoolPropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtBoolPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = false;
+}
+
+/*!
+ \reimp
+*/
+void QtBoolPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtDatePropertyManager
+
+class QtDatePropertyManagerPrivate
+{
+ QtDatePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtDatePropertyManager)
+public:
+ explicit QtDatePropertyManagerPrivate(QtDatePropertyManager *q);
+
+ struct Data
+ {
+ Data() : val(QDate::currentDate()), minVal(QDate(1752, 9, 14)),
+ maxVal(QDate(7999, 12, 31)) {}
+ QDate val;
+ QDate minVal;
+ QDate maxVal;
+ QDate minimumValue() const { return minVal; }
+ QDate maximumValue() const { return maxVal; }
+ void setMinimumValue(const QDate &newMinVal) { setSimpleMinimumData(this, newMinVal); }
+ void setMaximumValue(const QDate &newMaxVal) { setSimpleMaximumData(this, newMaxVal); }
+ };
+
+ QString m_format;
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ QMap<const QtProperty *, Data> m_values;
+};
+
+QtDatePropertyManagerPrivate::QtDatePropertyManagerPrivate(QtDatePropertyManager *q) :
+ q_ptr(q),
+ m_format(QtPropertyBrowserUtils::dateFormat())
+{
+}
+
+/*!
+ \class QtDatePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDatePropertyManager provides and manages QDate properties.
+
+ A date property has a current value, and a range specifying the
+ valid dates. The range is defined by a minimum and a maximum
+ value.
+
+ The property's values can be retrieved using the minimum(),
+ maximum() and value() functions, and can be set using the
+ setMinimum(), setMaximum() and setValue() slots. Alternatively,
+ the range can be defined in one go using the setRange() slot.
+
+ In addition, QtDatePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the rangeChanged() signal which is emitted whenever
+ such a property changes its range of valid dates.
+
+ \sa QtAbstractPropertyManager, QtDateEditFactory, QtDateTimePropertyManager
+*/
+
+/*!
+ \fn void QtDatePropertyManager::valueChanged(QtProperty *property, const QDate &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtDatePropertyManager::rangeChanged(QtProperty *property, const QDate &minimum, const QDate &maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid dates, passing a pointer to the \a
+ property and the new \a minimum and \a maximum dates.
+
+ \sa setRange()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtDatePropertyManager::QtDatePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtDatePropertyManagerPrivate(this))
+{
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtDatePropertyManager::~QtDatePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by \e this manager, this
+ function returns an invalid date.
+
+ \sa setValue()
+*/
+QDate QtDatePropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QDate>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's minimum date.
+
+ \sa maximum(), setRange()
+*/
+QDate QtDatePropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<QDate>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's maximum date.
+
+ \sa minimum(), setRange()
+*/
+QDate QtDatePropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<QDate>(d_ptr->m_values, property);
+}
+
+/*!
+ \reimp
+*/
+QString QtDatePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtDatePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().val.toString(d_ptr->m_format);
+}
+
+/*!
+ \fn void QtDatePropertyManager::setValue(QtProperty *property, const QDate &value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not a valid date according to the
+ given \a property's range, the value is adjusted to the nearest
+ valid value within the range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtDatePropertyManager::setValue(QtProperty *property, const QDate &val)
+{
+ void (QtDatePropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, const QDate &) = 0;
+ setValueInRange<const QDate &, QtDatePropertyManagerPrivate, QtDatePropertyManager, const QDate>(this, d_ptr.data(),
+ &QtDatePropertyManager::propertyChanged,
+ &QtDatePropertyManager::valueChanged,
+ property, val, setSubPropertyValue);
+}
+
+/*!
+ Sets the minimum value for the given \a property to \a minVal.
+
+ When setting the minimum value, the maximum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within in the range).
+
+ \sa minimum(), setRange()
+*/
+void QtDatePropertyManager::setMinimum(QtProperty *property, const QDate &minVal)
+{
+ setMinimumValue<const QDate &, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate, QtDatePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtDatePropertyManager::propertyChanged,
+ &QtDatePropertyManager::valueChanged,
+ &QtDatePropertyManager::rangeChanged,
+ property, minVal);
+}
+
+/*!
+ Sets the maximum value for the given \a property to \a maxVal.
+
+ When setting the maximum value, the minimum and current
+ values are adjusted if necessary (ensuring that the range remains
+ valid and that the current value is within in the range).
+
+ \sa maximum(), setRange()
+*/
+void QtDatePropertyManager::setMaximum(QtProperty *property, const QDate &maxVal)
+{
+ setMaximumValue<const QDate &, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate, QtDatePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtDatePropertyManager::propertyChanged,
+ &QtDatePropertyManager::valueChanged,
+ &QtDatePropertyManager::rangeChanged,
+ property, maxVal);
+}
+
+/*!
+ \fn void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minimum, const QDate &maximum)
+
+ Sets the range of valid dates.
+
+ This is a convenience function defining the range of valid dates
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new date range, the current value is adjusted if
+ necessary (ensuring that the value remains in date range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minVal, const QDate &maxVal)
+{
+ void (QtDatePropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, const QDate &,
+ const QDate &, const QDate &) = 0;
+ setBorderValues<const QDate &, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate>(this, d_ptr.data(),
+ &QtDatePropertyManager::propertyChanged,
+ &QtDatePropertyManager::valueChanged,
+ &QtDatePropertyManager::rangeChanged,
+ property, minVal, maxVal, setSubPropertyRange);
+}
+
+/*!
+ \reimp
+*/
+void QtDatePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtDatePropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtDatePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtTimePropertyManager
+
+class QtTimePropertyManagerPrivate
+{
+ QtTimePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtTimePropertyManager)
+public:
+ explicit QtTimePropertyManagerPrivate(QtTimePropertyManager *q);
+
+ const QString m_format;
+
+ typedef QMap<const QtProperty *, QTime> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+QtTimePropertyManagerPrivate::QtTimePropertyManagerPrivate(QtTimePropertyManager *q) :
+ q_ptr(q),
+ m_format(QtPropertyBrowserUtils::timeFormat())
+{
+}
+
+/*!
+ \class QtTimePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtTimePropertyManager provides and manages QTime properties.
+
+ A time property's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ In addition, QtTimePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager, QtTimeEditFactory
+*/
+
+/*!
+ \fn void QtTimePropertyManager::valueChanged(QtProperty *property, const QTime &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtTimePropertyManager::QtTimePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtTimePropertyManagerPrivate(this))
+{
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtTimePropertyManager::~QtTimePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns an invalid time object.
+
+ \sa setValue()
+*/
+QTime QtTimePropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QTime());
+}
+
+/*!
+ \reimp
+*/
+QString QtTimePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().toString(d_ptr->m_format);
+}
+
+/*!
+ \fn void QtTimePropertyManager::setValue(QtProperty *property, const QTime &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtTimePropertyManager::setValue(QtProperty *property, const QTime &val)
+{
+ setSimpleValue<const QTime &, QTime, QtTimePropertyManager>(d_ptr->m_values, this,
+ &QtTimePropertyManager::propertyChanged,
+ &QtTimePropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtTimePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QTime::currentTime();
+}
+
+/*!
+ \reimp
+*/
+void QtTimePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtDateTimePropertyManager
+
+class QtDateTimePropertyManagerPrivate
+{
+ QtDateTimePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtDateTimePropertyManager)
+public:
+ explicit QtDateTimePropertyManagerPrivate(QtDateTimePropertyManager *q);
+
+ const QString m_format;
+
+ typedef QMap<const QtProperty *, QDateTime> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+QtDateTimePropertyManagerPrivate::QtDateTimePropertyManagerPrivate(QtDateTimePropertyManager *q) :
+ q_ptr(q),
+ m_format(QtPropertyBrowserUtils::dateTimeFormat())
+{
+}
+
+/*! \class QtDateTimePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDateTimePropertyManager provides and manages QDateTime properties.
+
+ A date and time property has a current value which can be
+ retrieved using the value() function, and set using the setValue()
+ slot. In addition, QtDateTimePropertyManager provides the
+ valueChanged() signal which is emitted whenever a property created
+ by this manager changes.
+
+ \sa QtAbstractPropertyManager, QtDateTimeEditFactory, QtDatePropertyManager
+*/
+
+/*!
+ \fn void QtDateTimePropertyManager::valueChanged(QtProperty *property, const QDateTime &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtDateTimePropertyManager::QtDateTimePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtDateTimePropertyManagerPrivate(this))
+{
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtDateTimePropertyManager::~QtDateTimePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid QDateTime object.
+
+ \sa setValue()
+*/
+QDateTime QtDateTimePropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QDateTime());
+}
+
+/*!
+ \reimp
+*/
+QString QtDateTimePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtDateTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().toString(d_ptr->m_format);
+}
+
+/*!
+ \fn void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &val)
+{
+ setSimpleValue<const QDateTime &, QDateTime, QtDateTimePropertyManager>(d_ptr->m_values, this,
+ &QtDateTimePropertyManager::propertyChanged,
+ &QtDateTimePropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtDateTimePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QDateTime::currentDateTime();
+}
+
+/*!
+ \reimp
+*/
+void QtDateTimePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtKeySequencePropertyManager
+
+class QtKeySequencePropertyManagerPrivate
+{
+ QtKeySequencePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtKeySequencePropertyManager)
+public:
+
+ QString m_format;
+
+ typedef QMap<const QtProperty *, QKeySequence> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*! \class QtKeySequencePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtKeySequencePropertyManager provides and manages QKeySequence properties.
+
+ A key sequence's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ In addition, QtKeySequencePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager
+*/
+
+/*!
+ \fn void QtKeySequencePropertyManager::valueChanged(QtProperty *property, const QKeySequence &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtKeySequencePropertyManager::QtKeySequencePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtKeySequencePropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtKeySequencePropertyManager::~QtKeySequencePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an empty QKeySequence object.
+
+ \sa setValue()
+*/
+QKeySequence QtKeySequencePropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QKeySequence());
+}
+
+/*!
+ \reimp
+*/
+QString QtKeySequencePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtKeySequencePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().toString(QKeySequence::NativeText);
+}
+
+/*!
+ \fn void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &val)
+{
+ setSimpleValue<const QKeySequence &, QKeySequence, QtKeySequencePropertyManager>(d_ptr->m_values, this,
+ &QtKeySequencePropertyManager::propertyChanged,
+ &QtKeySequencePropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtKeySequencePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QKeySequence();
+}
+
+/*!
+ \reimp
+*/
+void QtKeySequencePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtCharPropertyManager
+
+class QtCharPropertyManagerPrivate
+{
+ QtCharPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtCharPropertyManager)
+public:
+
+ typedef QMap<const QtProperty *, QChar> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*! \class QtCharPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCharPropertyManager provides and manages QChar properties.
+
+ A char's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ In addition, QtCharPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager
+*/
+
+/*!
+ \fn void QtCharPropertyManager::valueChanged(QtProperty *property, const QChar &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtCharPropertyManager::QtCharPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtCharPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtCharPropertyManager::~QtCharPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an null QChar object.
+
+ \sa setValue()
+*/
+QChar QtCharPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QChar());
+}
+
+/*!
+ \reimp
+*/
+QString QtCharPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtCharPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QChar c = it.value();
+ return c.isNull() ? QString() : QString(c);
+}
+
+/*!
+ \fn void QtCharPropertyManager::setValue(QtProperty *property, const QChar &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtCharPropertyManager::setValue(QtProperty *property, const QChar &val)
+{
+ setSimpleValue<const QChar &, QChar, QtCharPropertyManager>(d_ptr->m_values, this,
+ &QtCharPropertyManager::propertyChanged,
+ &QtCharPropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtCharPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QChar();
+}
+
+/*!
+ \reimp
+*/
+void QtCharPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtLocalePropertyManager
+
+class QtLocalePropertyManagerPrivate
+{
+ QtLocalePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtLocalePropertyManager)
+public:
+
+ QtLocalePropertyManagerPrivate();
+
+ void slotEnumChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, QLocale> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtEnumPropertyManager *m_enumPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToLanguage;
+ QMap<const QtProperty *, QtProperty *> m_propertyToCountry;
+
+ QMap<const QtProperty *, QtProperty *> m_languageToProperty;
+ QMap<const QtProperty *, QtProperty *> m_countryToProperty;
+};
+
+QtLocalePropertyManagerPrivate::QtLocalePropertyManagerPrivate()
+{
+}
+
+void QtLocalePropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_languageToProperty.value(property, 0)) {
+ const QLocale loc = m_values[prop];
+ QLocale::Language newLanguage = loc.language();
+ QLocale::Country newCountry = loc.country();
+ metaEnumProvider()->indexToLocale(value, 0, &newLanguage, 0);
+ QLocale newLoc(newLanguage, newCountry);
+ q_ptr->setValue(prop, newLoc);
+ } else if (QtProperty *prop = m_countryToProperty.value(property, 0)) {
+ const QLocale loc = m_values[prop];
+ QLocale::Language newLanguage = loc.language();
+ QLocale::Country newCountry = loc.country();
+ metaEnumProvider()->indexToLocale(m_enumPropertyManager->value(m_propertyToLanguage.value(prop)), value, &newLanguage, &newCountry);
+ QLocale newLoc(newLanguage, newCountry);
+ q_ptr->setValue(prop, newLoc);
+ }
+}
+
+void QtLocalePropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *subProp = m_languageToProperty.value(property, 0)) {
+ m_propertyToLanguage[subProp] = 0;
+ m_languageToProperty.remove(property);
+ } else if (QtProperty *subProp = m_countryToProperty.value(property, 0)) {
+ m_propertyToCountry[subProp] = 0;
+ m_countryToProperty.remove(property);
+ }
+}
+
+/*!
+ \class QtLocalePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtLocalePropertyManager provides and manages QLocale properties.
+
+ A locale property has nested \e language and \e country
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by QtEnumPropertyManager object.
+ These submanager can be retrieved using the subEnumPropertyManager()
+ function. In order to provide editing widgets for the subproperties
+ in a property browser widget, this manager must be associated with editor factory.
+
+ In addition, QtLocalePropertyManager provides the valueChanged()
+ signal which is emitted whenever a property created by this
+ manager changes.
+
+ \sa QtAbstractPropertyManager, QtEnumPropertyManager
+*/
+
+/*!
+ \fn void QtLocalePropertyManager::valueChanged(QtProperty *property, const QLocale &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtLocalePropertyManager::QtLocalePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtLocalePropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotEnumChanged(QtProperty*,int)));
+
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtLocalePropertyManager::~QtLocalePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e language
+ and \e country subproperties.
+
+ In order to provide editing widgets for the mentioned subproperties
+ in a property browser widget, this manager must be associated with
+ an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtEnumPropertyManager *QtLocalePropertyManager::subEnumPropertyManager() const
+{
+ return d_ptr->m_enumPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns the default locale.
+
+ \sa setValue()
+*/
+QLocale QtLocalePropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QLocale());
+}
+
+/*!
+ \reimp
+*/
+QString QtLocalePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtLocalePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ const QLocale loc = it.value();
+
+ int langIdx = 0;
+ int countryIdx = 0;
+ const QtMetaEnumProvider *me = metaEnumProvider();
+ me->localeToIndex(loc.language(), loc.country(), &langIdx, &countryIdx);
+ if (langIdx < 0) {
+ qWarning("QtLocalePropertyManager::valueText: Unknown language %d", loc.language());
+ return tr("<Invalid>");
+ }
+ const QString languageName = me->languageEnumNames().at(langIdx);
+ if (countryIdx < 0) {
+ qWarning("QtLocalePropertyManager::valueText: Unknown country %d for %s", loc.country(), qPrintable(languageName));
+ return languageName;
+ }
+ const QString countryName = me->countryEnumNames(loc.language()).at(countryIdx);
+ return tr("%1, %2").arg(languageName, countryName);
+}
+
+/*!
+ \fn void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &val)
+{
+ const QtLocalePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ const QLocale loc = it.value();
+ if (loc == val)
+ return;
+
+ it.value() = val;
+
+ int langIdx = 0;
+ int countryIdx = 0;
+ metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx);
+ if (loc.language() != val.language()) {
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToLanguage.value(property), langIdx);
+ d_ptr->m_enumPropertyManager->setEnumNames(d_ptr->m_propertyToCountry.value(property),
+ metaEnumProvider()->countryEnumNames(val.language()));
+ }
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToCountry.value(property), countryIdx);
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtLocalePropertyManager::initializeProperty(QtProperty *property)
+{
+ QLocale val;
+ d_ptr->m_values[property] = val;
+
+ int langIdx = 0;
+ int countryIdx = 0;
+ metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx);
+
+ QtProperty *languageProp = d_ptr->m_enumPropertyManager->addProperty();
+ languageProp->setPropertyName(tr("Language"));
+ d_ptr->m_enumPropertyManager->setEnumNames(languageProp, metaEnumProvider()->languageEnumNames());
+ d_ptr->m_enumPropertyManager->setValue(languageProp, langIdx);
+ d_ptr->m_propertyToLanguage[property] = languageProp;
+ d_ptr->m_languageToProperty[languageProp] = property;
+ property->addSubProperty(languageProp);
+
+ QtProperty *countryProp = d_ptr->m_enumPropertyManager->addProperty();
+ countryProp->setPropertyName(tr("Country"));
+ d_ptr->m_enumPropertyManager->setEnumNames(countryProp, metaEnumProvider()->countryEnumNames(val.language()));
+ d_ptr->m_enumPropertyManager->setValue(countryProp, countryIdx);
+ d_ptr->m_propertyToCountry[property] = countryProp;
+ d_ptr->m_countryToProperty[countryProp] = property;
+ property->addSubProperty(countryProp);
+}
+
+/*!
+ \reimp
+*/
+void QtLocalePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *languageProp = d_ptr->m_propertyToLanguage[property];
+ if (languageProp) {
+ d_ptr->m_languageToProperty.remove(languageProp);
+ delete languageProp;
+ }
+ d_ptr->m_propertyToLanguage.remove(property);
+
+ QtProperty *countryProp = d_ptr->m_propertyToCountry[property];
+ if (countryProp) {
+ d_ptr->m_countryToProperty.remove(countryProp);
+ delete countryProp;
+ }
+ d_ptr->m_propertyToCountry.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtPointPropertyManager
+
+class QtPointPropertyManagerPrivate
+{
+ QtPointPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtPointPropertyManager)
+public:
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, QPoint> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToX;
+ QMap<const QtProperty *, QtProperty *> m_propertyToY;
+
+ QMap<const QtProperty *, QtProperty *> m_xToProperty;
+ QMap<const QtProperty *, QtProperty *> m_yToProperty;
+};
+
+void QtPointPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *xprop = m_xToProperty.value(property, 0)) {
+ QPoint p = m_values[xprop];
+ p.setX(value);
+ q_ptr->setValue(xprop, p);
+ } else if (QtProperty *yprop = m_yToProperty.value(property, 0)) {
+ QPoint p = m_values[yprop];
+ p.setY(value);
+ q_ptr->setValue(yprop, p);
+ }
+}
+
+void QtPointPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
+ m_propertyToX[pointProp] = 0;
+ m_xToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
+ m_propertyToY[pointProp] = 0;
+ m_yToProperty.remove(property);
+ }
+}
+
+/*! \class QtPointPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtPointPropertyManager provides and manages QPoint properties.
+
+ A point property has nested \e x and \e y subproperties. The
+ top-level property's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ The subproperties are created by a QtIntPropertyManager object. This
+ manager can be retrieved using the subIntPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ In addition, QtPointPropertyManager provides the valueChanged() signal which
+ is emitted whenever a property created by this manager changes.
+
+ \sa QtAbstractPropertyManager, QtIntPropertyManager, QtPointFPropertyManager
+*/
+
+/*!
+ \fn void QtPointPropertyManager::valueChanged(QtProperty *property, const QPoint &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtPointPropertyManager::QtPointPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtPointPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtPointPropertyManager::~QtPointPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e x and \e y
+ subproperties.
+
+ In order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtPointPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns a point with coordinates (0, 0).
+
+ \sa setValue()
+*/
+QPoint QtPointPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QPoint());
+}
+
+/*!
+ \reimp
+*/
+QString QtPointPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtPointPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QPoint v = it.value();
+ return tr("(%1, %2)").arg(QString::number(v.x()))
+ .arg(QString::number(v.y()));
+}
+
+/*!
+ \fn void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &val)
+{
+ const QtPointPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value() == val)
+ return;
+
+ it.value() = val;
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], val.x());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], val.y());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtPointPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QPoint(0, 0);
+
+ QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty();
+ xProp->setPropertyName(tr("X"));
+ d_ptr->m_intPropertyManager->setValue(xProp, 0);
+ d_ptr->m_propertyToX[property] = xProp;
+ d_ptr->m_xToProperty[xProp] = property;
+ property->addSubProperty(xProp);
+
+ QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty();
+ yProp->setPropertyName(tr("Y"));
+ d_ptr->m_intPropertyManager->setValue(yProp, 0);
+ d_ptr->m_propertyToY[property] = yProp;
+ d_ptr->m_yToProperty[yProp] = property;
+ property->addSubProperty(yProp);
+}
+
+/*!
+ \reimp
+*/
+void QtPointPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *xProp = d_ptr->m_propertyToX[property];
+ if (xProp) {
+ d_ptr->m_xToProperty.remove(xProp);
+ delete xProp;
+ }
+ d_ptr->m_propertyToX.remove(property);
+
+ QtProperty *yProp = d_ptr->m_propertyToY[property];
+ if (yProp) {
+ d_ptr->m_yToProperty.remove(yProp);
+ delete yProp;
+ }
+ d_ptr->m_propertyToY.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtPointFPropertyManager
+
+class QtPointFPropertyManagerPrivate
+{
+ QtPointFPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtPointFPropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : decimals(2) {}
+ QPointF val;
+ int decimals;
+ };
+
+ void slotDoubleChanged(QtProperty *property, double value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtDoublePropertyManager *m_doublePropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToX;
+ QMap<const QtProperty *, QtProperty *> m_propertyToY;
+
+ QMap<const QtProperty *, QtProperty *> m_xToProperty;
+ QMap<const QtProperty *, QtProperty *> m_yToProperty;
+};
+
+void QtPointFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value)
+{
+ if (QtProperty *prop = m_xToProperty.value(property, 0)) {
+ QPointF p = m_values[prop].val;
+ p.setX(value);
+ q_ptr->setValue(prop, p);
+ } else if (QtProperty *prop = m_yToProperty.value(property, 0)) {
+ QPointF p = m_values[prop].val;
+ p.setY(value);
+ q_ptr->setValue(prop, p);
+ }
+}
+
+void QtPointFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
+ m_propertyToX[pointProp] = 0;
+ m_xToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
+ m_propertyToY[pointProp] = 0;
+ m_yToProperty.remove(property);
+ }
+}
+
+/*! \class QtPointFPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtPointFPropertyManager provides and manages QPointF properties.
+
+ A point property has nested \e x and \e y subproperties. The
+ top-level property's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ The subproperties are created by a QtDoublePropertyManager object. This
+ manager can be retrieved using the subDoublePropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ In addition, QtPointFPropertyManager provides the valueChanged() signal which
+ is emitted whenever a property created by this manager changes.
+
+ \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtPointPropertyManager
+*/
+
+/*!
+ \fn void QtPointFPropertyManager::valueChanged(QtProperty *property, const QPointF &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtPointFPropertyManager::decimalsChanged(QtProperty *property, int prec)
+
+ This signal is emitted whenever a property created by this manager
+ changes its precision of value, passing a pointer to the
+ \a property and the new \a prec value
+
+ \sa setDecimals()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtPointFPropertyManager::QtPointFPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtPointFPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this);
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotDoubleChanged(QtProperty*,double)));
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtPointFPropertyManager::~QtPointFPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e x and \e y
+ subproperties.
+
+ In order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtDoublePropertyManager *QtPointFPropertyManager::subDoublePropertyManager() const
+{
+ return d_ptr->m_doublePropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns a point with coordinates (0, 0).
+
+ \sa setValue()
+*/
+QPointF QtPointFPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QPointF>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's precision, in decimals.
+
+ \sa setDecimals()
+*/
+int QtPointFPropertyManager::decimals(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtPointFPropertyManagerPrivate::Data::decimals, property, 0);
+}
+
+/*!
+ \reimp
+*/
+QString QtPointFPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtPointFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QPointF v = it.value().val;
+ const int dec = it.value().decimals;
+ return tr("(%1, %2)").arg(QString::number(v.x(), 'f', dec))
+ .arg(QString::number(v.y(), 'f', dec));
+}
+
+/*!
+ \fn void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &val)
+{
+ const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value().val == val)
+ return;
+
+ it.value().val = val;
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], val.x());
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], val.y());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \fn void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec)
+
+ Sets the precision of the given \a property to \a prec.
+
+ The valid decimal range is 0-13. The default is 2.
+
+ \sa decimals()
+*/
+void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec)
+{
+ const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtPointFPropertyManagerPrivate::Data data = it.value();
+
+ if (prec > 13)
+ prec = 13;
+ else if (prec < 0)
+ prec = 0;
+
+ if (data.decimals == prec)
+ return;
+
+ data.decimals = prec;
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec);
+
+ it.value() = data;
+
+ emit decimalsChanged(property, data.decimals);
+}
+
+/*!
+ \reimp
+*/
+void QtPointFPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtPointFPropertyManagerPrivate::Data();
+
+ QtProperty *xProp = d_ptr->m_doublePropertyManager->addProperty();
+ xProp->setPropertyName(tr("X"));
+ d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(xProp, 0);
+ d_ptr->m_propertyToX[property] = xProp;
+ d_ptr->m_xToProperty[xProp] = property;
+ property->addSubProperty(xProp);
+
+ QtProperty *yProp = d_ptr->m_doublePropertyManager->addProperty();
+ yProp->setPropertyName(tr("Y"));
+ d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(yProp, 0);
+ d_ptr->m_propertyToY[property] = yProp;
+ d_ptr->m_yToProperty[yProp] = property;
+ property->addSubProperty(yProp);
+}
+
+/*!
+ \reimp
+*/
+void QtPointFPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *xProp = d_ptr->m_propertyToX[property];
+ if (xProp) {
+ d_ptr->m_xToProperty.remove(xProp);
+ delete xProp;
+ }
+ d_ptr->m_propertyToX.remove(property);
+
+ QtProperty *yProp = d_ptr->m_propertyToY[property];
+ if (yProp) {
+ d_ptr->m_yToProperty.remove(yProp);
+ delete yProp;
+ }
+ d_ptr->m_propertyToY.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtSizePropertyManager
+
+class QtSizePropertyManagerPrivate
+{
+ QtSizePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtSizePropertyManager)
+public:
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void setValue(QtProperty *property, const QSize &val);
+ void setRange(QtProperty *property,
+ const QSize &minVal, const QSize &maxVal, const QSize &val);
+
+ struct Data
+ {
+ Data() : val(QSize(0, 0)), minVal(QSize(0, 0)), maxVal(QSize(INT_MAX, INT_MAX)) {}
+ QSize val;
+ QSize minVal;
+ QSize maxVal;
+ QSize minimumValue() const { return minVal; }
+ QSize maximumValue() const { return maxVal; }
+ void setMinimumValue(const QSize &newMinVal) { setSizeMinimumData(this, newMinVal); }
+ void setMaximumValue(const QSize &newMaxVal) { setSizeMaximumData(this, newMaxVal); }
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToW;
+ QMap<const QtProperty *, QtProperty *> m_propertyToH;
+
+ QMap<const QtProperty *, QtProperty *> m_wToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hToProperty;
+};
+
+void QtSizePropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_wToProperty.value(property, 0)) {
+ QSize s = m_values[prop].val;
+ s.setWidth(value);
+ q_ptr->setValue(prop, s);
+ } else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
+ QSize s = m_values[prop].val;
+ s.setHeight(value);
+ q_ptr->setValue(prop, s);
+ }
+}
+
+void QtSizePropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
+ m_propertyToW[pointProp] = 0;
+ m_wToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
+ m_propertyToH[pointProp] = 0;
+ m_hToProperty.remove(property);
+ }
+}
+
+void QtSizePropertyManagerPrivate::setValue(QtProperty *property, const QSize &val)
+{
+ m_intPropertyManager->setValue(m_propertyToW.value(property), val.width());
+ m_intPropertyManager->setValue(m_propertyToH.value(property), val.height());
+}
+
+void QtSizePropertyManagerPrivate::setRange(QtProperty *property,
+ const QSize &minVal, const QSize &maxVal, const QSize &val)
+{
+ QtProperty *wProperty = m_propertyToW.value(property);
+ QtProperty *hProperty = m_propertyToH.value(property);
+ m_intPropertyManager->setRange(wProperty, minVal.width(), maxVal.width());
+ m_intPropertyManager->setValue(wProperty, val.width());
+ m_intPropertyManager->setRange(hProperty, minVal.height(), maxVal.height());
+ m_intPropertyManager->setValue(hProperty, val.height());
+}
+
+/*!
+ \class QtSizePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSizePropertyManager provides and manages QSize properties.
+
+ A size property has nested \e width and \e height
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtIntPropertyManager object. This
+ manager can be retrieved using the subIntPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ A size property also has a range of valid values defined by a
+ minimum size and a maximum size. These sizes can be retrieved
+ using the minimum() and the maximum() functions, and set using the
+ setMinimum() and setMaximum() slots. Alternatively, the range can
+ be defined in one go using the setRange() slot.
+
+ In addition, QtSizePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the rangeChanged() signal which is emitted whenever
+ such a property changes its range of valid sizes.
+
+ \sa QtAbstractPropertyManager, QtIntPropertyManager, QtSizeFPropertyManager
+*/
+
+/*!
+ \fn void QtSizePropertyManager::valueChanged(QtProperty *property, const QSize &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtSizePropertyManager::rangeChanged(QtProperty *property, const QSize &minimum, const QSize &maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid sizes, passing a pointer to the \a
+ property and the new \a minimum and \a maximum sizes.
+
+ \sa setRange()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtSizePropertyManager::QtSizePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtSizePropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtSizePropertyManager::~QtSizePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e width and \e height
+ subproperties.
+
+ In order to provide editing widgets for the \e width and \e height
+ properties in a property browser widget, this manager must be
+ associated with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtSizePropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid size
+
+ \sa setValue()
+*/
+QSize QtSizePropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QSize>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's minimum size value.
+
+ \sa setMinimum(), maximum(), setRange()
+*/
+QSize QtSizePropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<QSize>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's maximum size value.
+
+ \sa setMaximum(), minimum(), setRange()
+*/
+QSize QtSizePropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<QSize>(d_ptr->m_values, property);
+}
+
+/*!
+ \reimp
+*/
+QString QtSizePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtSizePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QSize v = it.value().val;
+ return tr("%1 x %2").arg(QString::number(v.width()))
+ .arg(QString::number(v.height()));
+}
+
+/*!
+ \fn void QtSizePropertyManager::setValue(QtProperty *property, const QSize &value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not valid according to the given \a
+ property's size range, the \a value is adjusted to the nearest
+ valid value within the size range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtSizePropertyManager::setValue(QtProperty *property, const QSize &val)
+{
+ setValueInRange<const QSize &, QtSizePropertyManagerPrivate, QtSizePropertyManager, const QSize>(this, d_ptr.data(),
+ &QtSizePropertyManager::propertyChanged,
+ &QtSizePropertyManager::valueChanged,
+ property, val, &QtSizePropertyManagerPrivate::setValue);
+}
+
+/*!
+ Sets the minimum size value for the given \a property to \a minVal.
+
+ When setting the minimum size value, the maximum and current
+ values are adjusted if necessary (ensuring that the size range
+ remains valid and that the current value is within the range).
+
+ \sa minimum(), setRange(), rangeChanged()
+*/
+void QtSizePropertyManager::setMinimum(QtProperty *property, const QSize &minVal)
+{
+ setBorderValue<const QSize &, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize, QtSizePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtSizePropertyManager::propertyChanged,
+ &QtSizePropertyManager::valueChanged,
+ &QtSizePropertyManager::rangeChanged,
+ property,
+ &QtSizePropertyManagerPrivate::Data::minimumValue,
+ &QtSizePropertyManagerPrivate::Data::setMinimumValue,
+ minVal, &QtSizePropertyManagerPrivate::setRange);
+}
+
+/*!
+ Sets the maximum size value for the given \a property to \a maxVal.
+
+ When setting the maximum size value, the minimum and current
+ values are adjusted if necessary (ensuring that the size range
+ remains valid and that the current value is within the range).
+
+ \sa maximum(), setRange(), rangeChanged()
+*/
+void QtSizePropertyManager::setMaximum(QtProperty *property, const QSize &maxVal)
+{
+ setBorderValue<const QSize &, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize, QtSizePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtSizePropertyManager::propertyChanged,
+ &QtSizePropertyManager::valueChanged,
+ &QtSizePropertyManager::rangeChanged,
+ property,
+ &QtSizePropertyManagerPrivate::Data::maximumValue,
+ &QtSizePropertyManagerPrivate::Data::setMaximumValue,
+ maxVal, &QtSizePropertyManagerPrivate::setRange);
+}
+
+/*!
+ \fn void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minimum, const QSize &maximum)
+
+ Sets the range of valid values.
+
+ This is a convenience function defining the range of valid values
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new range, the current value is adjusted if
+ necessary (ensuring that the value remains within the range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minVal, const QSize &maxVal)
+{
+ setBorderValues<const QSize &, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize>(this, d_ptr.data(),
+ &QtSizePropertyManager::propertyChanged,
+ &QtSizePropertyManager::valueChanged,
+ &QtSizePropertyManager::rangeChanged,
+ property, minVal, maxVal, &QtSizePropertyManagerPrivate::setRange);
+}
+
+/*!
+ \reimp
+*/
+void QtSizePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtSizePropertyManagerPrivate::Data();
+
+ QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty();
+ wProp->setPropertyName(tr("Width"));
+ d_ptr->m_intPropertyManager->setValue(wProp, 0);
+ d_ptr->m_intPropertyManager->setMinimum(wProp, 0);
+ d_ptr->m_propertyToW[property] = wProp;
+ d_ptr->m_wToProperty[wProp] = property;
+ property->addSubProperty(wProp);
+
+ QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty();
+ hProp->setPropertyName(tr("Height"));
+ d_ptr->m_intPropertyManager->setValue(hProp, 0);
+ d_ptr->m_intPropertyManager->setMinimum(hProp, 0);
+ d_ptr->m_propertyToH[property] = hProp;
+ d_ptr->m_hToProperty[hProp] = property;
+ property->addSubProperty(hProp);
+}
+
+/*!
+ \reimp
+*/
+void QtSizePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *wProp = d_ptr->m_propertyToW[property];
+ if (wProp) {
+ d_ptr->m_wToProperty.remove(wProp);
+ delete wProp;
+ }
+ d_ptr->m_propertyToW.remove(property);
+
+ QtProperty *hProp = d_ptr->m_propertyToH[property];
+ if (hProp) {
+ d_ptr->m_hToProperty.remove(hProp);
+ delete hProp;
+ }
+ d_ptr->m_propertyToH.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtSizeFPropertyManager
+
+class QtSizeFPropertyManagerPrivate
+{
+ QtSizeFPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtSizeFPropertyManager)
+public:
+
+ void slotDoubleChanged(QtProperty *property, double value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void setValue(QtProperty *property, const QSizeF &val);
+ void setRange(QtProperty *property,
+ const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val);
+
+ struct Data
+ {
+ Data() : val(QSizeF(0, 0)), minVal(QSizeF(0, 0)), maxVal(QSizeF(INT_MAX, INT_MAX)), decimals(2) {}
+ QSizeF val;
+ QSizeF minVal;
+ QSizeF maxVal;
+ int decimals;
+ QSizeF minimumValue() const { return minVal; }
+ QSizeF maximumValue() const { return maxVal; }
+ void setMinimumValue(const QSizeF &newMinVal) { setSizeMinimumData(this, newMinVal); }
+ void setMaximumValue(const QSizeF &newMaxVal) { setSizeMaximumData(this, newMaxVal); }
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtDoublePropertyManager *m_doublePropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToW;
+ QMap<const QtProperty *, QtProperty *> m_propertyToH;
+
+ QMap<const QtProperty *, QtProperty *> m_wToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hToProperty;
+};
+
+void QtSizeFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value)
+{
+ if (QtProperty *prop = m_wToProperty.value(property, 0)) {
+ QSizeF s = m_values[prop].val;
+ s.setWidth(value);
+ q_ptr->setValue(prop, s);
+ } else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
+ QSizeF s = m_values[prop].val;
+ s.setHeight(value);
+ q_ptr->setValue(prop, s);
+ }
+}
+
+void QtSizeFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
+ m_propertyToW[pointProp] = 0;
+ m_wToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
+ m_propertyToH[pointProp] = 0;
+ m_hToProperty.remove(property);
+ }
+}
+
+void QtSizeFPropertyManagerPrivate::setValue(QtProperty *property, const QSizeF &val)
+{
+ m_doublePropertyManager->setValue(m_propertyToW.value(property), val.width());
+ m_doublePropertyManager->setValue(m_propertyToH.value(property), val.height());
+}
+
+void QtSizeFPropertyManagerPrivate::setRange(QtProperty *property,
+ const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val)
+{
+ m_doublePropertyManager->setRange(m_propertyToW[property], minVal.width(), maxVal.width());
+ m_doublePropertyManager->setValue(m_propertyToW[property], val.width());
+ m_doublePropertyManager->setRange(m_propertyToH[property], minVal.height(), maxVal.height());
+ m_doublePropertyManager->setValue(m_propertyToH[property], val.height());
+}
+
+/*!
+ \class QtSizeFPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSizeFPropertyManager provides and manages QSizeF properties.
+
+ A size property has nested \e width and \e height
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtDoublePropertyManager object. This
+ manager can be retrieved using the subDoublePropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ A size property also has a range of valid values defined by a
+ minimum size and a maximum size. These sizes can be retrieved
+ using the minimum() and the maximum() functions, and set using the
+ setMinimum() and setMaximum() slots. Alternatively, the range can
+ be defined in one go using the setRange() slot.
+
+ In addition, QtSizeFPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the rangeChanged() signal which is emitted whenever
+ such a property changes its range of valid sizes.
+
+ \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtSizePropertyManager
+*/
+
+/*!
+ \fn void QtSizeFPropertyManager::valueChanged(QtProperty *property, const QSizeF &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtSizeFPropertyManager::rangeChanged(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid sizes, passing a pointer to the \a
+ property and the new \a minimum and \a maximum sizes.
+
+ \sa setRange()
+*/
+
+/*!
+ \fn void QtSizeFPropertyManager::decimalsChanged(QtProperty *property, int prec)
+
+ This signal is emitted whenever a property created by this manager
+ changes its precision of value, passing a pointer to the
+ \a property and the new \a prec value
+
+ \sa setDecimals()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtSizeFPropertyManager::QtSizeFPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtSizeFPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this);
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotDoubleChanged(QtProperty*,double)));
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtSizeFPropertyManager::~QtSizeFPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e width and \e height
+ subproperties.
+
+ In order to provide editing widgets for the \e width and \e height
+ properties in a property browser widget, this manager must be
+ associated with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtDoublePropertyManager *QtSizeFPropertyManager::subDoublePropertyManager() const
+{
+ return d_ptr->m_doublePropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid size
+
+ \sa setValue()
+*/
+QSizeF QtSizeFPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QSizeF>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's precision, in decimals.
+
+ \sa setDecimals()
+*/
+int QtSizeFPropertyManager::decimals(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtSizeFPropertyManagerPrivate::Data::decimals, property, 0);
+}
+
+/*!
+ Returns the given \a property's minimum size value.
+
+ \sa setMinimum(), maximum(), setRange()
+*/
+QSizeF QtSizeFPropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<QSizeF>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's maximum size value.
+
+ \sa setMaximum(), minimum(), setRange()
+*/
+QSizeF QtSizeFPropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<QSizeF>(d_ptr->m_values, property);
+}
+
+/*!
+ \reimp
+*/
+QString QtSizeFPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtSizeFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QSizeF v = it.value().val;
+ const int dec = it.value().decimals;
+ return tr("%1 x %2").arg(QString::number(v.width(), 'f', dec))
+ .arg(QString::number(v.height(), 'f', dec));
+}
+
+/*!
+ \fn void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not valid according to the given \a
+ property's size range, the \a value is adjusted to the nearest
+ valid value within the size range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &val)
+{
+ setValueInRange<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF>(this, d_ptr.data(),
+ &QtSizeFPropertyManager::propertyChanged,
+ &QtSizeFPropertyManager::valueChanged,
+ property, val, &QtSizeFPropertyManagerPrivate::setValue);
+}
+
+/*!
+ \fn void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec)
+
+ Sets the precision of the given \a property to \a prec.
+
+ The valid decimal range is 0-13. The default is 2.
+
+ \sa decimals()
+*/
+void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec)
+{
+ const QtSizeFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtSizeFPropertyManagerPrivate::Data data = it.value();
+
+ if (prec > 13)
+ prec = 13;
+ else if (prec < 0)
+ prec = 0;
+
+ if (data.decimals == prec)
+ return;
+
+ data.decimals = prec;
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec);
+
+ it.value() = data;
+
+ emit decimalsChanged(property, data.decimals);
+}
+
+/*!
+ Sets the minimum size value for the given \a property to \a minVal.
+
+ When setting the minimum size value, the maximum and current
+ values are adjusted if necessary (ensuring that the size range
+ remains valid and that the current value is within the range).
+
+ \sa minimum(), setRange(), rangeChanged()
+*/
+void QtSizeFPropertyManager::setMinimum(QtProperty *property, const QSizeF &minVal)
+{
+ setBorderValue<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF, QtSizeFPropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtSizeFPropertyManager::propertyChanged,
+ &QtSizeFPropertyManager::valueChanged,
+ &QtSizeFPropertyManager::rangeChanged,
+ property,
+ &QtSizeFPropertyManagerPrivate::Data::minimumValue,
+ &QtSizeFPropertyManagerPrivate::Data::setMinimumValue,
+ minVal, &QtSizeFPropertyManagerPrivate::setRange);
+}
+
+/*!
+ Sets the maximum size value for the given \a property to \a maxVal.
+
+ When setting the maximum size value, the minimum and current
+ values are adjusted if necessary (ensuring that the size range
+ remains valid and that the current value is within the range).
+
+ \sa maximum(), setRange(), rangeChanged()
+*/
+void QtSizeFPropertyManager::setMaximum(QtProperty *property, const QSizeF &maxVal)
+{
+ setBorderValue<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF, QtSizeFPropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtSizeFPropertyManager::propertyChanged,
+ &QtSizeFPropertyManager::valueChanged,
+ &QtSizeFPropertyManager::rangeChanged,
+ property,
+ &QtSizeFPropertyManagerPrivate::Data::maximumValue,
+ &QtSizeFPropertyManagerPrivate::Data::setMaximumValue,
+ maxVal, &QtSizeFPropertyManagerPrivate::setRange);
+}
+
+/*!
+ \fn void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum)
+
+ Sets the range of valid values.
+
+ This is a convenience function defining the range of valid values
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new range, the current value is adjusted if
+ necessary (ensuring that the value remains within the range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal)
+{
+ setBorderValues<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF>(this, d_ptr.data(),
+ &QtSizeFPropertyManager::propertyChanged,
+ &QtSizeFPropertyManager::valueChanged,
+ &QtSizeFPropertyManager::rangeChanged,
+ property, minVal, maxVal, &QtSizeFPropertyManagerPrivate::setRange);
+}
+
+/*!
+ \reimp
+*/
+void QtSizeFPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtSizeFPropertyManagerPrivate::Data();
+
+ QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty();
+ wProp->setPropertyName(tr("Width"));
+ d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(wProp, 0);
+ d_ptr->m_doublePropertyManager->setMinimum(wProp, 0);
+ d_ptr->m_propertyToW[property] = wProp;
+ d_ptr->m_wToProperty[wProp] = property;
+ property->addSubProperty(wProp);
+
+ QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty();
+ hProp->setPropertyName(tr("Height"));
+ d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(hProp, 0);
+ d_ptr->m_doublePropertyManager->setMinimum(hProp, 0);
+ d_ptr->m_propertyToH[property] = hProp;
+ d_ptr->m_hToProperty[hProp] = property;
+ property->addSubProperty(hProp);
+}
+
+/*!
+ \reimp
+*/
+void QtSizeFPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *wProp = d_ptr->m_propertyToW[property];
+ if (wProp) {
+ d_ptr->m_wToProperty.remove(wProp);
+ delete wProp;
+ }
+ d_ptr->m_propertyToW.remove(property);
+
+ QtProperty *hProp = d_ptr->m_propertyToH[property];
+ if (hProp) {
+ d_ptr->m_hToProperty.remove(hProp);
+ delete hProp;
+ }
+ d_ptr->m_propertyToH.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtRectPropertyManager
+
+class QtRectPropertyManagerPrivate
+{
+ QtRectPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtRectPropertyManager)
+public:
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void setConstraint(QtProperty *property, const QRect &constraint, const QRect &val);
+
+ struct Data
+ {
+ Data() : val(0, 0, 0, 0) {}
+ QRect val;
+ QRect constraint;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToX;
+ QMap<const QtProperty *, QtProperty *> m_propertyToY;
+ QMap<const QtProperty *, QtProperty *> m_propertyToW;
+ QMap<const QtProperty *, QtProperty *> m_propertyToH;
+
+ QMap<const QtProperty *, QtProperty *> m_xToProperty;
+ QMap<const QtProperty *, QtProperty *> m_yToProperty;
+ QMap<const QtProperty *, QtProperty *> m_wToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hToProperty;
+};
+
+void QtRectPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_xToProperty.value(property, 0)) {
+ QRect r = m_values[prop].val;
+ r.moveLeft(value);
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_yToProperty.value(property)) {
+ QRect r = m_values[prop].val;
+ r.moveTop(value);
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_wToProperty.value(property, 0)) {
+ Data data = m_values[prop];
+ QRect r = data.val;
+ r.setWidth(value);
+ if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) {
+ r.moveLeft(data.constraint.left() + data.constraint.width() - r.width());
+ }
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
+ Data data = m_values[prop];
+ QRect r = data.val;
+ r.setHeight(value);
+ if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) {
+ r.moveTop(data.constraint.top() + data.constraint.height() - r.height());
+ }
+ q_ptr->setValue(prop, r);
+ }
+}
+
+void QtRectPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
+ m_propertyToX[pointProp] = 0;
+ m_xToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
+ m_propertyToY[pointProp] = 0;
+ m_yToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
+ m_propertyToW[pointProp] = 0;
+ m_wToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
+ m_propertyToH[pointProp] = 0;
+ m_hToProperty.remove(property);
+ }
+}
+
+void QtRectPropertyManagerPrivate::setConstraint(QtProperty *property,
+ const QRect &constraint, const QRect &val)
+{
+ const bool isNull = constraint.isNull();
+ const int left = isNull ? INT_MIN : constraint.left();
+ const int right = isNull ? INT_MAX : constraint.left() + constraint.width();
+ const int top = isNull ? INT_MIN : constraint.top();
+ const int bottom = isNull ? INT_MAX : constraint.top() + constraint.height();
+ const int width = isNull ? INT_MAX : constraint.width();
+ const int height = isNull ? INT_MAX : constraint.height();
+
+ m_intPropertyManager->setRange(m_propertyToX[property], left, right);
+ m_intPropertyManager->setRange(m_propertyToY[property], top, bottom);
+ m_intPropertyManager->setRange(m_propertyToW[property], 0, width);
+ m_intPropertyManager->setRange(m_propertyToH[property], 0, height);
+
+ m_intPropertyManager->setValue(m_propertyToX[property], val.x());
+ m_intPropertyManager->setValue(m_propertyToY[property], val.y());
+ m_intPropertyManager->setValue(m_propertyToW[property], val.width());
+ m_intPropertyManager->setValue(m_propertyToH[property], val.height());
+}
+
+/*!
+ \class QtRectPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtRectPropertyManager provides and manages QRect properties.
+
+ A rectangle property has nested \e x, \e y, \e width and \e height
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtIntPropertyManager object. This
+ manager can be retrieved using the subIntPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ A rectangle property also has a constraint rectangle which can be
+ retrieved using the constraint() function, and set using the
+ setConstraint() slot.
+
+ In addition, QtRectPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the constraintChanged() signal which is emitted
+ whenever such a property changes its constraint rectangle.
+
+ \sa QtAbstractPropertyManager, QtIntPropertyManager, QtRectFPropertyManager
+*/
+
+/*!
+ \fn void QtRectPropertyManager::valueChanged(QtProperty *property, const QRect &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtRectPropertyManager::constraintChanged(QtProperty *property, const QRect &constraint)
+
+ This signal is emitted whenever property changes its constraint
+ rectangle, passing a pointer to the \a property and the new \a
+ constraint rectangle as parameters.
+
+ \sa setConstraint()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtRectPropertyManager::QtRectPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtRectPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtRectPropertyManager::~QtRectPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e x, \e y, \e width
+ and \e height subproperties.
+
+ In order to provide editing widgets for the mentioned
+ subproperties in a property browser widget, this manager must be
+ associated with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtRectPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid rectangle.
+
+ \sa setValue(), constraint()
+*/
+QRect QtRectPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QRect>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's constraining rectangle. If returned value is null QRect it means there is no constraint applied.
+
+ \sa value(), setConstraint()
+*/
+QRect QtRectPropertyManager::constraint(const QtProperty *property) const
+{
+ return getData<QRect>(d_ptr->m_values, &QtRectPropertyManagerPrivate::Data::constraint, property, QRect());
+}
+
+/*!
+ \reimp
+*/
+QString QtRectPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtRectPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QRect v = it.value().val;
+ return tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x()))
+ .arg(QString::number(v.y()))
+ .arg(QString::number(v.width()))
+ .arg(QString::number(v.height()));
+}
+
+/*!
+ \fn void QtRectPropertyManager::setValue(QtProperty *property, const QRect &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ If the specified \a value is not inside the given \a property's
+ constraining rectangle, the value is adjusted accordingly to fit
+ within the constraint.
+
+ \sa value(), setConstraint(), valueChanged()
+*/
+void QtRectPropertyManager::setValue(QtProperty *property, const QRect &val)
+{
+ const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectPropertyManagerPrivate::Data data = it.value();
+
+ QRect newRect = val.normalized();
+ if (!data.constraint.isNull() && !data.constraint.contains(newRect)) {
+ const QRect r1 = data.constraint;
+ const QRect r2 = newRect;
+ newRect.setLeft(qMax(r1.left(), r2.left()));
+ newRect.setRight(qMin(r1.right(), r2.right()));
+ newRect.setTop(qMax(r1.top(), r2.top()));
+ newRect.setBottom(qMin(r1.bottom(), r2.bottom()));
+ if (newRect.width() < 0 || newRect.height() < 0)
+ return;
+ }
+
+ if (data.val == newRect)
+ return;
+
+ data.val = newRect;
+
+ it.value() = data;
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's constraining rectangle to \a
+ constraint.
+
+ When setting the constraint, the current value is adjusted if
+ necessary (ensuring that the current rectangle value is inside the
+ constraint). In order to reset the constraint pass a null QRect value.
+
+ \sa setValue(), constraint(), constraintChanged()
+*/
+void QtRectPropertyManager::setConstraint(QtProperty *property, const QRect &constraint)
+{
+ const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectPropertyManagerPrivate::Data data = it.value();
+
+ QRect newConstraint = constraint.normalized();
+ if (data.constraint == newConstraint)
+ return;
+
+ const QRect oldVal = data.val;
+
+ data.constraint = newConstraint;
+
+ if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) {
+ QRect r1 = data.constraint;
+ QRect r2 = data.val;
+
+ if (r2.width() > r1.width())
+ r2.setWidth(r1.width());
+ if (r2.height() > r1.height())
+ r2.setHeight(r1.height());
+ if (r2.left() < r1.left())
+ r2.moveLeft(r1.left());
+ else if (r2.right() > r1.right())
+ r2.moveRight(r1.right());
+ if (r2.top() < r1.top())
+ r2.moveTop(r1.top());
+ else if (r2.bottom() > r1.bottom())
+ r2.moveBottom(r1.bottom());
+
+ data.val = r2;
+ }
+
+ it.value() = data;
+
+ emit constraintChanged(property, data.constraint);
+
+ d_ptr->setConstraint(property, data.constraint, data.val);
+
+ if (data.val == oldVal)
+ return;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ \reimp
+*/
+void QtRectPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtRectPropertyManagerPrivate::Data();
+
+ QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty();
+ xProp->setPropertyName(tr("X"));
+ d_ptr->m_intPropertyManager->setValue(xProp, 0);
+ d_ptr->m_propertyToX[property] = xProp;
+ d_ptr->m_xToProperty[xProp] = property;
+ property->addSubProperty(xProp);
+
+ QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty();
+ yProp->setPropertyName(tr("Y"));
+ d_ptr->m_intPropertyManager->setValue(yProp, 0);
+ d_ptr->m_propertyToY[property] = yProp;
+ d_ptr->m_yToProperty[yProp] = property;
+ property->addSubProperty(yProp);
+
+ QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty();
+ wProp->setPropertyName(tr("Width"));
+ d_ptr->m_intPropertyManager->setValue(wProp, 0);
+ d_ptr->m_intPropertyManager->setMinimum(wProp, 0);
+ d_ptr->m_propertyToW[property] = wProp;
+ d_ptr->m_wToProperty[wProp] = property;
+ property->addSubProperty(wProp);
+
+ QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty();
+ hProp->setPropertyName(tr("Height"));
+ d_ptr->m_intPropertyManager->setValue(hProp, 0);
+ d_ptr->m_intPropertyManager->setMinimum(hProp, 0);
+ d_ptr->m_propertyToH[property] = hProp;
+ d_ptr->m_hToProperty[hProp] = property;
+ property->addSubProperty(hProp);
+}
+
+/*!
+ \reimp
+*/
+void QtRectPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *xProp = d_ptr->m_propertyToX[property];
+ if (xProp) {
+ d_ptr->m_xToProperty.remove(xProp);
+ delete xProp;
+ }
+ d_ptr->m_propertyToX.remove(property);
+
+ QtProperty *yProp = d_ptr->m_propertyToY[property];
+ if (yProp) {
+ d_ptr->m_yToProperty.remove(yProp);
+ delete yProp;
+ }
+ d_ptr->m_propertyToY.remove(property);
+
+ QtProperty *wProp = d_ptr->m_propertyToW[property];
+ if (wProp) {
+ d_ptr->m_wToProperty.remove(wProp);
+ delete wProp;
+ }
+ d_ptr->m_propertyToW.remove(property);
+
+ QtProperty *hProp = d_ptr->m_propertyToH[property];
+ if (hProp) {
+ d_ptr->m_hToProperty.remove(hProp);
+ delete hProp;
+ }
+ d_ptr->m_propertyToH.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtRectFPropertyManager
+
+class QtRectFPropertyManagerPrivate
+{
+ QtRectFPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtRectFPropertyManager)
+public:
+
+ void slotDoubleChanged(QtProperty *property, double value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void setConstraint(QtProperty *property, const QRectF &constraint, const QRectF &val);
+
+ struct Data
+ {
+ Data() : val(0, 0, 0, 0), decimals(2) {}
+ QRectF val;
+ QRectF constraint;
+ int decimals;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtDoublePropertyManager *m_doublePropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToX;
+ QMap<const QtProperty *, QtProperty *> m_propertyToY;
+ QMap<const QtProperty *, QtProperty *> m_propertyToW;
+ QMap<const QtProperty *, QtProperty *> m_propertyToH;
+
+ QMap<const QtProperty *, QtProperty *> m_xToProperty;
+ QMap<const QtProperty *, QtProperty *> m_yToProperty;
+ QMap<const QtProperty *, QtProperty *> m_wToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hToProperty;
+};
+
+void QtRectFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value)
+{
+ if (QtProperty *prop = m_xToProperty.value(property, 0)) {
+ QRectF r = m_values[prop].val;
+ r.moveLeft(value);
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_yToProperty.value(property, 0)) {
+ QRectF r = m_values[prop].val;
+ r.moveTop(value);
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_wToProperty.value(property, 0)) {
+ Data data = m_values[prop];
+ QRectF r = data.val;
+ r.setWidth(value);
+ if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) {
+ r.moveLeft(data.constraint.left() + data.constraint.width() - r.width());
+ }
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
+ Data data = m_values[prop];
+ QRectF r = data.val;
+ r.setHeight(value);
+ if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) {
+ r.moveTop(data.constraint.top() + data.constraint.height() - r.height());
+ }
+ q_ptr->setValue(prop, r);
+ }
+}
+
+void QtRectFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
+ m_propertyToX[pointProp] = 0;
+ m_xToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
+ m_propertyToY[pointProp] = 0;
+ m_yToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
+ m_propertyToW[pointProp] = 0;
+ m_wToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
+ m_propertyToH[pointProp] = 0;
+ m_hToProperty.remove(property);
+ }
+}
+
+void QtRectFPropertyManagerPrivate::setConstraint(QtProperty *property,
+ const QRectF &constraint, const QRectF &val)
+{
+ const bool isNull = constraint.isNull();
+ const float left = isNull ? FLT_MIN : constraint.left();
+ const float right = isNull ? FLT_MAX : constraint.left() + constraint.width();
+ const float top = isNull ? FLT_MIN : constraint.top();
+ const float bottom = isNull ? FLT_MAX : constraint.top() + constraint.height();
+ const float width = isNull ? FLT_MAX : constraint.width();
+ const float height = isNull ? FLT_MAX : constraint.height();
+
+ m_doublePropertyManager->setRange(m_propertyToX[property], left, right);
+ m_doublePropertyManager->setRange(m_propertyToY[property], top, bottom);
+ m_doublePropertyManager->setRange(m_propertyToW[property], 0, width);
+ m_doublePropertyManager->setRange(m_propertyToH[property], 0, height);
+
+ m_doublePropertyManager->setValue(m_propertyToX[property], val.x());
+ m_doublePropertyManager->setValue(m_propertyToY[property], val.y());
+ m_doublePropertyManager->setValue(m_propertyToW[property], val.width());
+ m_doublePropertyManager->setValue(m_propertyToH[property], val.height());
+}
+
+/*!
+ \class QtRectFPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtRectFPropertyManager provides and manages QRectF properties.
+
+ A rectangle property has nested \e x, \e y, \e width and \e height
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtDoublePropertyManager object. This
+ manager can be retrieved using the subDoublePropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ A rectangle property also has a constraint rectangle which can be
+ retrieved using the constraint() function, and set using the
+ setConstraint() slot.
+
+ In addition, QtRectFPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the constraintChanged() signal which is emitted
+ whenever such a property changes its constraint rectangle.
+
+ \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtRectPropertyManager
+*/
+
+/*!
+ \fn void QtRectFPropertyManager::valueChanged(QtProperty *property, const QRectF &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtRectFPropertyManager::constraintChanged(QtProperty *property, const QRectF &constraint)
+
+ This signal is emitted whenever property changes its constraint
+ rectangle, passing a pointer to the \a property and the new \a
+ constraint rectangle as parameters.
+
+ \sa setConstraint()
+*/
+
+/*!
+ \fn void QtRectFPropertyManager::decimalsChanged(QtProperty *property, int prec)
+
+ This signal is emitted whenever a property created by this manager
+ changes its precision of value, passing a pointer to the
+ \a property and the new \a prec value
+
+ \sa setDecimals()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtRectFPropertyManager::QtRectFPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtRectFPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this);
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotDoubleChanged(QtProperty*,double)));
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtRectFPropertyManager::~QtRectFPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e x, \e y, \e width
+ and \e height subproperties.
+
+ In order to provide editing widgets for the mentioned
+ subproperties in a property browser widget, this manager must be
+ associated with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtDoublePropertyManager *QtRectFPropertyManager::subDoublePropertyManager() const
+{
+ return d_ptr->m_doublePropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid rectangle.
+
+ \sa setValue(), constraint()
+*/
+QRectF QtRectFPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QRectF>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's precision, in decimals.
+
+ \sa setDecimals()
+*/
+int QtRectFPropertyManager::decimals(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::decimals, property, 0);
+}
+
+/*!
+ Returns the given \a property's constraining rectangle. If returned value is null QRectF it means there is no constraint applied.
+
+ \sa value(), setConstraint()
+*/
+QRectF QtRectFPropertyManager::constraint(const QtProperty *property) const
+{
+ return getData<QRectF>(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::constraint, property, QRect());
+}
+
+/*!
+ \reimp
+*/
+QString QtRectFPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtRectFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QRectF v = it.value().val;
+ const int dec = it.value().decimals;
+ return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x(), 'f', dec))
+ .arg(QString::number(v.y(), 'f', dec))
+ .arg(QString::number(v.width(), 'f', dec))
+ .arg(QString::number(v.height(), 'f', dec)));
+}
+
+/*!
+ \fn void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ If the specified \a value is not inside the given \a property's
+ constraining rectangle, the value is adjusted accordingly to fit
+ within the constraint.
+
+ \sa value(), setConstraint(), valueChanged()
+*/
+void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &val)
+{
+ const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectFPropertyManagerPrivate::Data data = it.value();
+
+ QRectF newRect = val.normalized();
+ if (!data.constraint.isNull() && !data.constraint.contains(newRect)) {
+ const QRectF r1 = data.constraint;
+ const QRectF r2 = newRect;
+ newRect.setLeft(qMax(r1.left(), r2.left()));
+ newRect.setRight(qMin(r1.right(), r2.right()));
+ newRect.setTop(qMax(r1.top(), r2.top()));
+ newRect.setBottom(qMin(r1.bottom(), r2.bottom()));
+ if (newRect.width() < 0 || newRect.height() < 0)
+ return;
+ }
+
+ if (data.val == newRect)
+ return;
+
+ data.val = newRect;
+
+ it.value() = data;
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x());
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y());
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width());
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's constraining rectangle to \a
+ constraint.
+
+ When setting the constraint, the current value is adjusted if
+ necessary (ensuring that the current rectangle value is inside the
+ constraint). In order to reset the constraint pass a null QRectF value.
+
+ \sa setValue(), constraint(), constraintChanged()
+*/
+void QtRectFPropertyManager::setConstraint(QtProperty *property, const QRectF &constraint)
+{
+ const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectFPropertyManagerPrivate::Data data = it.value();
+
+ QRectF newConstraint = constraint.normalized();
+ if (data.constraint == newConstraint)
+ return;
+
+ const QRectF oldVal = data.val;
+
+ data.constraint = newConstraint;
+
+ if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) {
+ QRectF r1 = data.constraint;
+ QRectF r2 = data.val;
+
+ if (r2.width() > r1.width())
+ r2.setWidth(r1.width());
+ if (r2.height() > r1.height())
+ r2.setHeight(r1.height());
+ if (r2.left() < r1.left())
+ r2.moveLeft(r1.left());
+ else if (r2.right() > r1.right())
+ r2.moveRight(r1.right());
+ if (r2.top() < r1.top())
+ r2.moveTop(r1.top());
+ else if (r2.bottom() > r1.bottom())
+ r2.moveBottom(r1.bottom());
+
+ data.val = r2;
+ }
+
+ it.value() = data;
+
+ emit constraintChanged(property, data.constraint);
+
+ d_ptr->setConstraint(property, data.constraint, data.val);
+
+ if (data.val == oldVal)
+ return;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ \fn void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec)
+
+ Sets the precision of the given \a property to \a prec.
+
+ The valid decimal range is 0-13. The default is 2.
+
+ \sa decimals()
+*/
+void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec)
+{
+ const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectFPropertyManagerPrivate::Data data = it.value();
+
+ if (prec > 13)
+ prec = 13;
+ else if (prec < 0)
+ prec = 0;
+
+ if (data.decimals == prec)
+ return;
+
+ data.decimals = prec;
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec);
+
+ it.value() = data;
+
+ emit decimalsChanged(property, data.decimals);
+}
+
+/*!
+ \reimp
+*/
+void QtRectFPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtRectFPropertyManagerPrivate::Data();
+
+ QtProperty *xProp = d_ptr->m_doublePropertyManager->addProperty();
+ xProp->setPropertyName(tr("X"));
+ d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(xProp, 0);
+ d_ptr->m_propertyToX[property] = xProp;
+ d_ptr->m_xToProperty[xProp] = property;
+ property->addSubProperty(xProp);
+
+ QtProperty *yProp = d_ptr->m_doublePropertyManager->addProperty();
+ yProp->setPropertyName(tr("Y"));
+ d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(yProp, 0);
+ d_ptr->m_propertyToY[property] = yProp;
+ d_ptr->m_yToProperty[yProp] = property;
+ property->addSubProperty(yProp);
+
+ QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty();
+ wProp->setPropertyName(tr("Width"));
+ d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(wProp, 0);
+ d_ptr->m_doublePropertyManager->setMinimum(wProp, 0);
+ d_ptr->m_propertyToW[property] = wProp;
+ d_ptr->m_wToProperty[wProp] = property;
+ property->addSubProperty(wProp);
+
+ QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty();
+ hProp->setPropertyName(tr("Height"));
+ d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(hProp, 0);
+ d_ptr->m_doublePropertyManager->setMinimum(hProp, 0);
+ d_ptr->m_propertyToH[property] = hProp;
+ d_ptr->m_hToProperty[hProp] = property;
+ property->addSubProperty(hProp);
+}
+
+/*!
+ \reimp
+*/
+void QtRectFPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *xProp = d_ptr->m_propertyToX[property];
+ if (xProp) {
+ d_ptr->m_xToProperty.remove(xProp);
+ delete xProp;
+ }
+ d_ptr->m_propertyToX.remove(property);
+
+ QtProperty *yProp = d_ptr->m_propertyToY[property];
+ if (yProp) {
+ d_ptr->m_yToProperty.remove(yProp);
+ delete yProp;
+ }
+ d_ptr->m_propertyToY.remove(property);
+
+ QtProperty *wProp = d_ptr->m_propertyToW[property];
+ if (wProp) {
+ d_ptr->m_wToProperty.remove(wProp);
+ delete wProp;
+ }
+ d_ptr->m_propertyToW.remove(property);
+
+ QtProperty *hProp = d_ptr->m_propertyToH[property];
+ if (hProp) {
+ d_ptr->m_hToProperty.remove(hProp);
+ delete hProp;
+ }
+ d_ptr->m_propertyToH.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtEnumPropertyManager
+
+class QtEnumPropertyManagerPrivate
+{
+ QtEnumPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtEnumPropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : val(-1) {}
+ int val;
+ QStringList enumNames;
+ QMap<int, QIcon> enumIcons;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*!
+ \class QtEnumPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtEnumPropertyManager provides and manages enum properties.
+
+ Each enum property has an associated list of enum names which can
+ be retrieved using the enumNames() function, and set using the
+ corresponding setEnumNames() function. An enum property's value is
+ represented by an index in this list, and can be retrieved and set
+ using the value() and setValue() slots respectively.
+
+ Each enum value can also have an associated icon. The mapping from
+ values to icons can be set using the setEnumIcons() function and
+ queried with the enumIcons() function.
+
+ In addition, QtEnumPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes. The enumNamesChanged() or enumIconsChanged() signal is emitted
+ whenever the list of enum names or icons is altered.
+
+ \sa QtAbstractPropertyManager, QtEnumEditorFactory
+*/
+
+/*!
+ \fn void QtEnumPropertyManager::valueChanged(QtProperty *property, int value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtEnumPropertyManager::enumNamesChanged(QtProperty *property, const QStringList &names)
+
+ This signal is emitted whenever a property created by this manager
+ changes its enum names, passing a pointer to the \a property and
+ the new \a names as parameters.
+
+ \sa setEnumNames()
+*/
+
+/*!
+ \fn void QtEnumPropertyManager::enumIconsChanged(QtProperty *property, const QMap<int, QIcon> &icons)
+
+ This signal is emitted whenever a property created by this manager
+ changes its enum icons, passing a pointer to the \a property and
+ the new mapping of values to \a icons as parameters.
+
+ \sa setEnumIcons()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtEnumPropertyManager::QtEnumPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtEnumPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtEnumPropertyManager::~QtEnumPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value which is an index in the
+ list returned by enumNames()
+
+ If the given property is not managed by this manager, this
+ function returns -1.
+
+ \sa enumNames(), setValue()
+*/
+int QtEnumPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<int>(d_ptr->m_values, property, -1);
+}
+
+/*!
+ Returns the given \a property's list of enum names.
+
+ \sa value(), setEnumNames()
+*/
+QStringList QtEnumPropertyManager::enumNames(const QtProperty *property) const
+{
+ return getData<QStringList>(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumNames, property, QStringList());
+}
+
+/*!
+ Returns the given \a property's map of enum values to their icons.
+
+ \sa value(), setEnumIcons()
+*/
+QMap<int, QIcon> QtEnumPropertyManager::enumIcons(const QtProperty *property) const
+{
+ return getData<QMap<int, QIcon> >(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumIcons, property, QMap<int, QIcon>());
+}
+
+/*!
+ \reimp
+*/
+QString QtEnumPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ const QtEnumPropertyManagerPrivate::Data &data = it.value();
+
+ const int v = data.val;
+ if (v >= 0 && v < data.enumNames.count())
+ return data.enumNames.at(v);
+ return QString();
+}
+
+/*!
+ \reimp
+*/
+QIcon QtEnumPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+
+ const QtEnumPropertyManagerPrivate::Data &data = it.value();
+
+ const int v = data.val;
+ return data.enumIcons.value(v);
+}
+
+/*!
+ \fn void QtEnumPropertyManager::setValue(QtProperty *property, int value)
+
+ Sets the value of the given \a property to \a value.
+
+ The specified \a value must be less than the size of the given \a
+ property's enumNames() list, and larger than (or equal to) 0.
+
+ \sa value(), valueChanged()
+*/
+void QtEnumPropertyManager::setValue(QtProperty *property, int val)
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtEnumPropertyManagerPrivate::Data data = it.value();
+
+ if (val >= data.enumNames.count())
+ return;
+
+ if (val < 0 && data.enumNames.count() > 0)
+ return;
+
+ if (val < 0)
+ val = -1;
+
+ if (data.val == val)
+ return;
+
+ data.val = val;
+
+ it.value() = data;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's list of enum names to \a
+ enumNames. The \a property's current value is reset to 0
+ indicating the first item of the list.
+
+ If the specified \a enumNames list is empty, the \a property's
+ current value is set to -1.
+
+ \sa enumNames(), enumNamesChanged()
+*/
+void QtEnumPropertyManager::setEnumNames(QtProperty *property, const QStringList &enumNames)
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtEnumPropertyManagerPrivate::Data data = it.value();
+
+ if (data.enumNames == enumNames)
+ return;
+
+ data.enumNames = enumNames;
+
+ data.val = -1;
+
+ if (enumNames.count() > 0)
+ data.val = 0;
+
+ it.value() = data;
+
+ emit enumNamesChanged(property, data.enumNames);
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's map of enum values to their icons to \a
+ enumIcons.
+
+ Each enum value can have associated icon. This association is represented with passed \a enumIcons map.
+
+ \sa enumNames(), enumNamesChanged()
+*/
+void QtEnumPropertyManager::setEnumIcons(QtProperty *property, const QMap<int, QIcon> &enumIcons)
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ it.value().enumIcons = enumIcons;
+
+ emit enumIconsChanged(property, it.value().enumIcons);
+
+ emit propertyChanged(property);
+}
+
+/*!
+ \reimp
+*/
+void QtEnumPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtEnumPropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtEnumPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtFlagPropertyManager
+
+class QtFlagPropertyManagerPrivate
+{
+ QtFlagPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtFlagPropertyManager)
+public:
+
+ void slotBoolChanged(QtProperty *property, bool value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ struct Data
+ {
+ Data() : val(-1) {}
+ int val;
+ QStringList flagNames;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtBoolPropertyManager *m_boolPropertyManager;
+
+ QMap<const QtProperty *, QList<QtProperty *> > m_propertyToFlags;
+
+ QMap<const QtProperty *, QtProperty *> m_flagToProperty;
+};
+
+void QtFlagPropertyManagerPrivate::slotBoolChanged(QtProperty *property, bool value)
+{
+ QtProperty *prop = m_flagToProperty.value(property, 0);
+ if (prop == 0)
+ return;
+
+ QListIterator<QtProperty *> itProp(m_propertyToFlags[prop]);
+ int level = 0;
+ while (itProp.hasNext()) {
+ QtProperty *p = itProp.next();
+ if (p == property) {
+ int v = m_values[prop].val;
+ if (value) {
+ v |= (1 << level);
+ } else {
+ v &= ~(1 << level);
+ }
+ q_ptr->setValue(prop, v);
+ return;
+ }
+ level++;
+ }
+}
+
+void QtFlagPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ QtProperty *flagProperty = m_flagToProperty.value(property, 0);
+ if (flagProperty == 0)
+ return;
+
+ m_propertyToFlags[flagProperty].replace(m_propertyToFlags[flagProperty].indexOf(property), 0);
+ m_flagToProperty.remove(property);
+}
+
+/*!
+ \class QtFlagPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtFlagPropertyManager provides and manages flag properties.
+
+ Each flag property has an associated list of flag names which can
+ be retrieved using the flagNames() function, and set using the
+ corresponding setFlagNames() function.
+
+ The flag manager provides properties with nested boolean
+ subproperties representing each flag, i.e. a flag property's value
+ is the binary combination of the subproperties' values. A
+ property's value can be retrieved and set using the value() and
+ setValue() slots respectively. The combination of flags is represented
+ by single int value - that's why it's possible to store up to
+ 32 independent flags in one flag property.
+
+ The subproperties are created by a QtBoolPropertyManager object. This
+ manager can be retrieved using the subBoolPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ In addition, QtFlagPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the flagNamesChanged() signal which is emitted
+ whenever the list of flag names is altered.
+
+ \sa QtAbstractPropertyManager, QtBoolPropertyManager
+*/
+
+/*!
+ \fn void QtFlagPropertyManager::valueChanged(QtProperty *property, int value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtFlagPropertyManager::flagNamesChanged(QtProperty *property, const QStringList &names)
+
+ This signal is emitted whenever a property created by this manager
+ changes its flag names, passing a pointer to the \a property and the
+ new \a names as parameters.
+
+ \sa setFlagNames()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtFlagPropertyManager::QtFlagPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtFlagPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this);
+ connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotBoolChanged(QtProperty*,bool)));
+ connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtFlagPropertyManager::~QtFlagPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that produces the nested boolean subproperties
+ representing each flag.
+
+ In order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtBoolPropertyManager *QtFlagPropertyManager::subBoolPropertyManager() const
+{
+ return d_ptr->m_boolPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns 0.
+
+ \sa flagNames(), setValue()
+*/
+int QtFlagPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<int>(d_ptr->m_values, property, 0);
+}
+
+/*!
+ Returns the given \a property's list of flag names.
+
+ \sa value(), setFlagNames()
+*/
+QStringList QtFlagPropertyManager::flagNames(const QtProperty *property) const
+{
+ return getData<QStringList>(d_ptr->m_values, &QtFlagPropertyManagerPrivate::Data::flagNames, property, QStringList());
+}
+
+/*!
+ \reimp
+*/
+QString QtFlagPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtFlagPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ const QtFlagPropertyManagerPrivate::Data &data = it.value();
+
+ QString str;
+ int level = 0;
+ const QChar bar = QLatin1Char('|');
+ const QStringList::const_iterator fncend = data.flagNames.constEnd();
+ for (QStringList::const_iterator it = data.flagNames.constBegin(); it != fncend; ++it) {
+ if (data.val & (1 << level)) {
+ if (!str.isEmpty())
+ str += bar;
+ str += *it;
+ }
+
+ level++;
+ }
+ return str;
+}
+
+/*!
+ \fn void QtFlagPropertyManager::setValue(QtProperty *property, int value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ The specified \a value must be less than the binary combination of
+ the property's flagNames() list size (i.e. less than 2\sup n,
+ where \c n is the size of the list) and larger than (or equal to)
+ 0.
+
+ \sa value(), valueChanged()
+*/
+void QtFlagPropertyManager::setValue(QtProperty *property, int val)
+{
+ const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtFlagPropertyManagerPrivate::Data data = it.value();
+
+ if (data.val == val)
+ return;
+
+ if (val > (1 << data.flagNames.count()) - 1)
+ return;
+
+ if (val < 0)
+ return;
+
+ data.val = val;
+
+ it.value() = data;
+
+ QListIterator<QtProperty *> itProp(d_ptr->m_propertyToFlags[property]);
+ int level = 0;
+ while (itProp.hasNext()) {
+ QtProperty *prop = itProp.next();
+ if (prop)
+ d_ptr->m_boolPropertyManager->setValue(prop, val & (1 << level));
+ level++;
+ }
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's list of flag names to \a flagNames. The
+ property's current value is reset to 0 indicating the first item
+ of the list.
+
+ \sa flagNames(), flagNamesChanged()
+*/
+void QtFlagPropertyManager::setFlagNames(QtProperty *property, const QStringList &flagNames)
+{
+ const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtFlagPropertyManagerPrivate::Data data = it.value();
+
+ if (data.flagNames == flagNames)
+ return;
+
+ data.flagNames = flagNames;
+ data.val = 0;
+
+ it.value() = data;
+
+ QListIterator<QtProperty *> itProp(d_ptr->m_propertyToFlags[property]);
+ while (itProp.hasNext()) {
+ QtProperty *prop = itProp.next();
+ if (prop) {
+ delete prop;
+ d_ptr->m_flagToProperty.remove(prop);
+ }
+ }
+ d_ptr->m_propertyToFlags[property].clear();
+
+ QStringListIterator itFlag(flagNames);
+ while (itFlag.hasNext()) {
+ const QString flagName = itFlag.next();
+ QtProperty *prop = d_ptr->m_boolPropertyManager->addProperty();
+ prop->setPropertyName(flagName);
+ property->addSubProperty(prop);
+ d_ptr->m_propertyToFlags[property].append(prop);
+ d_ptr->m_flagToProperty[prop] = property;
+ }
+
+ emit flagNamesChanged(property, data.flagNames);
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ \reimp
+*/
+void QtFlagPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtFlagPropertyManagerPrivate::Data();
+
+ d_ptr->m_propertyToFlags[property] = QList<QtProperty *>();
+}
+
+/*!
+ \reimp
+*/
+void QtFlagPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QListIterator<QtProperty *> itProp(d_ptr->m_propertyToFlags[property]);
+ while (itProp.hasNext()) {
+ QtProperty *prop = itProp.next();
+ if (prop) {
+ delete prop;
+ d_ptr->m_flagToProperty.remove(prop);
+ }
+ }
+ d_ptr->m_propertyToFlags.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtSizePolicyPropertyManager
+
+class QtSizePolicyPropertyManagerPrivate
+{
+ QtSizePolicyPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtSizePolicyPropertyManager)
+public:
+
+ QtSizePolicyPropertyManagerPrivate();
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotEnumChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, QSizePolicy> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+ QtEnumPropertyManager *m_enumPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToHPolicy;
+ QMap<const QtProperty *, QtProperty *> m_propertyToVPolicy;
+ QMap<const QtProperty *, QtProperty *> m_propertyToHStretch;
+ QMap<const QtProperty *, QtProperty *> m_propertyToVStretch;
+
+ QMap<const QtProperty *, QtProperty *> m_hPolicyToProperty;
+ QMap<const QtProperty *, QtProperty *> m_vPolicyToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hStretchToProperty;
+ QMap<const QtProperty *, QtProperty *> m_vStretchToProperty;
+};
+
+QtSizePolicyPropertyManagerPrivate::QtSizePolicyPropertyManagerPrivate()
+{
+}
+
+void QtSizePolicyPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_hStretchToProperty.value(property, 0)) {
+ QSizePolicy sp = m_values[prop];
+ sp.setHorizontalStretch(value);
+ q_ptr->setValue(prop, sp);
+ } else if (QtProperty *prop = m_vStretchToProperty.value(property, 0)) {
+ QSizePolicy sp = m_values[prop];
+ sp.setVerticalStretch(value);
+ q_ptr->setValue(prop, sp);
+ }
+}
+
+void QtSizePolicyPropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_hPolicyToProperty.value(property, 0)) {
+ QSizePolicy sp = m_values[prop];
+ sp.setHorizontalPolicy(metaEnumProvider()->indexToSizePolicy(value));
+ q_ptr->setValue(prop, sp);
+ } else if (QtProperty *prop = m_vPolicyToProperty.value(property, 0)) {
+ QSizePolicy sp = m_values[prop];
+ sp.setVerticalPolicy(metaEnumProvider()->indexToSizePolicy(value));
+ q_ptr->setValue(prop, sp);
+ }
+}
+
+void QtSizePolicyPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_hStretchToProperty.value(property, 0)) {
+ m_propertyToHStretch[pointProp] = 0;
+ m_hStretchToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_vStretchToProperty.value(property, 0)) {
+ m_propertyToVStretch[pointProp] = 0;
+ m_vStretchToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hPolicyToProperty.value(property, 0)) {
+ m_propertyToHPolicy[pointProp] = 0;
+ m_hPolicyToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_vPolicyToProperty.value(property, 0)) {
+ m_propertyToVPolicy[pointProp] = 0;
+ m_vPolicyToProperty.remove(property);
+ }
+}
+
+/*!
+ \class QtSizePolicyPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSizePolicyPropertyManager provides and manages QSizePolicy properties.
+
+ A size policy property has nested \e horizontalPolicy, \e
+ verticalPolicy, \e horizontalStretch and \e verticalStretch
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by QtIntPropertyManager and QtEnumPropertyManager
+ objects. These managers can be retrieved using the subIntPropertyManager()
+ and subEnumPropertyManager() functions respectively. In order to provide
+ editing widgets for the subproperties in a property browser widget,
+ these managers must be associated with editor factories.
+
+ In addition, QtSizePolicyPropertyManager provides the valueChanged()
+ signal which is emitted whenever a property created by this
+ manager changes.
+
+ \sa QtAbstractPropertyManager, QtIntPropertyManager, QtEnumPropertyManager
+*/
+
+/*!
+ \fn void QtSizePolicyPropertyManager::valueChanged(QtProperty *property, const QSizePolicy &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtSizePolicyPropertyManager::QtSizePolicyPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtSizePolicyPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotEnumChanged(QtProperty*,int)));
+
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtSizePolicyPropertyManager::~QtSizePolicyPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e horizontalStretch
+ and \e verticalStretch subproperties.
+
+ In order to provide editing widgets for the mentioned subproperties
+ in a property browser widget, this manager must be associated with
+ an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtSizePolicyPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the manager that creates the nested \e horizontalPolicy
+ and \e verticalPolicy subproperties.
+
+ In order to provide editing widgets for the mentioned subproperties
+ in a property browser widget, this manager must be associated with
+ an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtEnumPropertyManager *QtSizePolicyPropertyManager::subEnumPropertyManager() const
+{
+ return d_ptr->m_enumPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns the default size policy.
+
+ \sa setValue()
+*/
+QSizePolicy QtSizePolicyPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QSizePolicy());
+}
+
+/*!
+ \reimp
+*/
+QString QtSizePolicyPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ const QSizePolicy sp = it.value();
+ const QtMetaEnumProvider *mep = metaEnumProvider();
+ const int hIndex = mep->sizePolicyToIndex(sp.horizontalPolicy());
+ const int vIndex = mep->sizePolicyToIndex(sp.verticalPolicy());
+ //! Unknown size policy on reading invalid uic3 files
+ const QString hPolicy = hIndex != -1 ? mep->policyEnumNames().at(hIndex) : tr("<Invalid>");
+ const QString vPolicy = vIndex != -1 ? mep->policyEnumNames().at(vIndex) : tr("<Invalid>");
+ const QString str = tr("[%1, %2, %3, %4]").arg(hPolicy, vPolicy).arg(sp.horizontalStretch()).arg(sp.verticalStretch());
+ return str;
+}
+
+/*!
+ \fn void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &val)
+{
+ const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value() == val)
+ return;
+
+ it.value() = val;
+
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToHPolicy[property],
+ metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy()));
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToVPolicy[property],
+ metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy()));
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToHStretch[property],
+ val.horizontalStretch());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToVStretch[property],
+ val.verticalStretch());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtSizePolicyPropertyManager::initializeProperty(QtProperty *property)
+{
+ QSizePolicy val;
+ d_ptr->m_values[property] = val;
+
+ QtProperty *hPolicyProp = d_ptr->m_enumPropertyManager->addProperty();
+ hPolicyProp->setPropertyName(tr("Horizontal Policy"));
+ d_ptr->m_enumPropertyManager->setEnumNames(hPolicyProp, metaEnumProvider()->policyEnumNames());
+ d_ptr->m_enumPropertyManager->setValue(hPolicyProp,
+ metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy()));
+ d_ptr->m_propertyToHPolicy[property] = hPolicyProp;
+ d_ptr->m_hPolicyToProperty[hPolicyProp] = property;
+ property->addSubProperty(hPolicyProp);
+
+ QtProperty *vPolicyProp = d_ptr->m_enumPropertyManager->addProperty();
+ vPolicyProp->setPropertyName(tr("Vertical Policy"));
+ d_ptr->m_enumPropertyManager->setEnumNames(vPolicyProp, metaEnumProvider()->policyEnumNames());
+ d_ptr->m_enumPropertyManager->setValue(vPolicyProp,
+ metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy()));
+ d_ptr->m_propertyToVPolicy[property] = vPolicyProp;
+ d_ptr->m_vPolicyToProperty[vPolicyProp] = property;
+ property->addSubProperty(vPolicyProp);
+
+ QtProperty *hStretchProp = d_ptr->m_intPropertyManager->addProperty();
+ hStretchProp->setPropertyName(tr("Horizontal Stretch"));
+ d_ptr->m_intPropertyManager->setValue(hStretchProp, val.horizontalStretch());
+ d_ptr->m_intPropertyManager->setRange(hStretchProp, 0, 0xff);
+ d_ptr->m_propertyToHStretch[property] = hStretchProp;
+ d_ptr->m_hStretchToProperty[hStretchProp] = property;
+ property->addSubProperty(hStretchProp);
+
+ QtProperty *vStretchProp = d_ptr->m_intPropertyManager->addProperty();
+ vStretchProp->setPropertyName(tr("Vertical Stretch"));
+ d_ptr->m_intPropertyManager->setValue(vStretchProp, val.verticalStretch());
+ d_ptr->m_intPropertyManager->setRange(vStretchProp, 0, 0xff);
+ d_ptr->m_propertyToVStretch[property] = vStretchProp;
+ d_ptr->m_vStretchToProperty[vStretchProp] = property;
+ property->addSubProperty(vStretchProp);
+
+}
+
+/*!
+ \reimp
+*/
+void QtSizePolicyPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *hPolicyProp = d_ptr->m_propertyToHPolicy[property];
+ if (hPolicyProp) {
+ d_ptr->m_hPolicyToProperty.remove(hPolicyProp);
+ delete hPolicyProp;
+ }
+ d_ptr->m_propertyToHPolicy.remove(property);
+
+ QtProperty *vPolicyProp = d_ptr->m_propertyToVPolicy[property];
+ if (vPolicyProp) {
+ d_ptr->m_vPolicyToProperty.remove(vPolicyProp);
+ delete vPolicyProp;
+ }
+ d_ptr->m_propertyToVPolicy.remove(property);
+
+ QtProperty *hStretchProp = d_ptr->m_propertyToHStretch[property];
+ if (hStretchProp) {
+ d_ptr->m_hStretchToProperty.remove(hStretchProp);
+ delete hStretchProp;
+ }
+ d_ptr->m_propertyToHStretch.remove(property);
+
+ QtProperty *vStretchProp = d_ptr->m_propertyToVStretch[property];
+ if (vStretchProp) {
+ d_ptr->m_vStretchToProperty.remove(vStretchProp);
+ delete vStretchProp;
+ }
+ d_ptr->m_propertyToVStretch.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtFontPropertyManager:
+// QtFontPropertyManagerPrivate has a mechanism for reacting
+// to QApplication::fontDatabaseChanged() [4.5], which is emitted
+// when someone loads an application font. The signals are compressed
+// using a timer with interval 0, which then causes the family
+// enumeration manager to re-set its strings and index values
+// for each property.
+
+Q_GLOBAL_STATIC(QFontDatabase, fontDatabase)
+
+class QtFontPropertyManagerPrivate
+{
+ QtFontPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtFontPropertyManager)
+public:
+
+ QtFontPropertyManagerPrivate();
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotEnumChanged(QtProperty *property, int value);
+ void slotBoolChanged(QtProperty *property, bool value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void slotFontDatabaseChanged();
+ void slotFontDatabaseDelayedChange();
+
+ QStringList m_familyNames;
+
+ typedef QMap<const QtProperty *, QFont> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+ QtEnumPropertyManager *m_enumPropertyManager;
+ QtBoolPropertyManager *m_boolPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToFamily;
+ QMap<const QtProperty *, QtProperty *> m_propertyToPointSize;
+ QMap<const QtProperty *, QtProperty *> m_propertyToBold;
+ QMap<const QtProperty *, QtProperty *> m_propertyToItalic;
+ QMap<const QtProperty *, QtProperty *> m_propertyToUnderline;
+ QMap<const QtProperty *, QtProperty *> m_propertyToStrikeOut;
+ QMap<const QtProperty *, QtProperty *> m_propertyToKerning;
+
+ QMap<const QtProperty *, QtProperty *> m_familyToProperty;
+ QMap<const QtProperty *, QtProperty *> m_pointSizeToProperty;
+ QMap<const QtProperty *, QtProperty *> m_boldToProperty;
+ QMap<const QtProperty *, QtProperty *> m_italicToProperty;
+ QMap<const QtProperty *, QtProperty *> m_underlineToProperty;
+ QMap<const QtProperty *, QtProperty *> m_strikeOutToProperty;
+ QMap<const QtProperty *, QtProperty *> m_kerningToProperty;
+
+ bool m_settingValue;
+ QTimer *m_fontDatabaseChangeTimer;
+};
+
+QtFontPropertyManagerPrivate::QtFontPropertyManagerPrivate() :
+ m_settingValue(false),
+ m_fontDatabaseChangeTimer(0)
+{
+}
+
+void QtFontPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (m_settingValue)
+ return;
+ if (QtProperty *prop = m_pointSizeToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setPointSize(value);
+ q_ptr->setValue(prop, f);
+ }
+}
+
+void QtFontPropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value)
+{
+ if (m_settingValue)
+ return;
+ if (QtProperty *prop = m_familyToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setFamily(m_familyNames.at(value));
+ q_ptr->setValue(prop, f);
+ }
+}
+
+void QtFontPropertyManagerPrivate::slotBoolChanged(QtProperty *property, bool value)
+{
+ if (m_settingValue)
+ return;
+ if (QtProperty *prop = m_boldToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setBold(value);
+ q_ptr->setValue(prop, f);
+ } else if (QtProperty *prop = m_italicToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setItalic(value);
+ q_ptr->setValue(prop, f);
+ } else if (QtProperty *prop = m_underlineToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setUnderline(value);
+ q_ptr->setValue(prop, f);
+ } else if (QtProperty *prop = m_strikeOutToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setStrikeOut(value);
+ q_ptr->setValue(prop, f);
+ } else if (QtProperty *prop = m_kerningToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setKerning(value);
+ q_ptr->setValue(prop, f);
+ }
+}
+
+void QtFontPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_pointSizeToProperty.value(property, 0)) {
+ m_propertyToPointSize[pointProp] = 0;
+ m_pointSizeToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_familyToProperty.value(property, 0)) {
+ m_propertyToFamily[pointProp] = 0;
+ m_familyToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_boldToProperty.value(property, 0)) {
+ m_propertyToBold[pointProp] = 0;
+ m_boldToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_italicToProperty.value(property, 0)) {
+ m_propertyToItalic[pointProp] = 0;
+ m_italicToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_underlineToProperty.value(property, 0)) {
+ m_propertyToUnderline[pointProp] = 0;
+ m_underlineToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_strikeOutToProperty.value(property, 0)) {
+ m_propertyToStrikeOut[pointProp] = 0;
+ m_strikeOutToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_kerningToProperty.value(property, 0)) {
+ m_propertyToKerning[pointProp] = 0;
+ m_kerningToProperty.remove(property);
+ }
+}
+
+void QtFontPropertyManagerPrivate::slotFontDatabaseChanged()
+{
+ if (!m_fontDatabaseChangeTimer) {
+ m_fontDatabaseChangeTimer = new QTimer(q_ptr);
+ m_fontDatabaseChangeTimer->setInterval(0);
+ m_fontDatabaseChangeTimer->setSingleShot(true);
+ QObject::connect(m_fontDatabaseChangeTimer, SIGNAL(timeout()), q_ptr, SLOT(slotFontDatabaseDelayedChange()));
+ }
+ if (!m_fontDatabaseChangeTimer->isActive())
+ m_fontDatabaseChangeTimer->start();
+}
+
+void QtFontPropertyManagerPrivate::slotFontDatabaseDelayedChange()
+{
+ typedef QMap<const QtProperty *, QtProperty *> PropertyPropertyMap;
+ // rescan available font names
+ const QStringList oldFamilies = m_familyNames;
+ m_familyNames = fontDatabase()->families();
+
+ // Adapt all existing properties
+ if (!m_propertyToFamily.empty()) {
+ PropertyPropertyMap::const_iterator cend = m_propertyToFamily.constEnd();
+ for (PropertyPropertyMap::const_iterator it = m_propertyToFamily.constBegin(); it != cend; ++it) {
+ QtProperty *familyProp = it.value();
+ const int oldIdx = m_enumPropertyManager->value(familyProp);
+ int newIdx = m_familyNames.indexOf(oldFamilies.at(oldIdx));
+ if (newIdx < 0)
+ newIdx = 0;
+ m_enumPropertyManager->setEnumNames(familyProp, m_familyNames);
+ m_enumPropertyManager->setValue(familyProp, newIdx);
+ }
+ }
+}
+
+/*!
+ \class QtFontPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtFontPropertyManager provides and manages QFont properties.
+
+ A font property has nested \e family, \e pointSize, \e bold, \e
+ italic, \e underline, \e strikeOut and \e kerning subproperties. The top-level
+ property's value can be retrieved using the value() function, and
+ set using the setValue() slot.
+
+ The subproperties are created by QtIntPropertyManager, QtEnumPropertyManager and
+ QtBoolPropertyManager objects. These managers can be retrieved using the
+ corresponding subIntPropertyManager(), subEnumPropertyManager() and
+ subBoolPropertyManager() functions. In order to provide editing widgets
+ for the subproperties in a property browser widget, these managers
+ must be associated with editor factories.
+
+ In addition, QtFontPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager, QtEnumPropertyManager, QtIntPropertyManager, QtBoolPropertyManager
+*/
+
+/*!
+ \fn void QtFontPropertyManager::valueChanged(QtProperty *property, const QFont &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtFontPropertyManager::QtFontPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtFontPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+ QObject::connect(qApp, SIGNAL(fontDatabaseChanged()), this, SLOT(slotFontDatabaseChanged()));
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotEnumChanged(QtProperty*,int)));
+ d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this);
+ connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotBoolChanged(QtProperty*,bool)));
+
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+ connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtFontPropertyManager::~QtFontPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the \e pointSize subproperty.
+
+ In order to provide editing widgets for the \e pointSize property
+ in a property browser widget, this manager must be associated
+ with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtFontPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the manager that create the \e family subproperty.
+
+ In order to provide editing widgets for the \e family property
+ in a property browser widget, this manager must be associated
+ with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtEnumPropertyManager *QtFontPropertyManager::subEnumPropertyManager() const
+{
+ return d_ptr->m_enumPropertyManager;
+}
+
+/*!
+ Returns the manager that creates the \e bold, \e italic, \e underline,
+ \e strikeOut and \e kerning subproperties.
+
+ In order to provide editing widgets for the mentioned properties
+ in a property browser widget, this manager must be associated with
+ an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtBoolPropertyManager *QtFontPropertyManager::subBoolPropertyManager() const
+{
+ return d_ptr->m_boolPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns a font object that uses the application's default
+ font.
+
+ \sa setValue()
+*/
+QFont QtFontPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QFont());
+}
+
+/*!
+ \reimp
+*/
+QString QtFontPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ return QtPropertyBrowserUtils::fontValueText(it.value());
+}
+
+/*!
+ \reimp
+*/
+QIcon QtFontPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+
+ return QtPropertyBrowserUtils::fontValueIcon(it.value());
+}
+
+/*!
+ \fn void QtFontPropertyManager::setValue(QtProperty *property, const QFont &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtFontPropertyManager::setValue(QtProperty *property, const QFont &val)
+{
+ const QtFontPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ const QFont oldVal = it.value();
+ if (oldVal == val && oldVal.resolve() == val.resolve())
+ return;
+
+ it.value() = val;
+
+ int idx = d_ptr->m_familyNames.indexOf(val.family());
+ if (idx == -1)
+ idx = 0;
+ bool settingValue = d_ptr->m_settingValue;
+ d_ptr->m_settingValue = true;
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToFamily[property], idx);
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToPointSize[property], val.pointSize());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToBold[property], val.bold());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToItalic[property], val.italic());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToUnderline[property], val.underline());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToStrikeOut[property], val.strikeOut());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToKerning[property], val.kerning());
+ d_ptr->m_settingValue = settingValue;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtFontPropertyManager::initializeProperty(QtProperty *property)
+{
+ QFont val;
+ d_ptr->m_values[property] = val;
+
+ QtProperty *familyProp = d_ptr->m_enumPropertyManager->addProperty();
+ familyProp->setPropertyName(tr("Family"));
+ if (d_ptr->m_familyNames.empty())
+ d_ptr->m_familyNames = fontDatabase()->families();
+ d_ptr->m_enumPropertyManager->setEnumNames(familyProp, d_ptr->m_familyNames);
+ int idx = d_ptr->m_familyNames.indexOf(val.family());
+ if (idx == -1)
+ idx = 0;
+ d_ptr->m_enumPropertyManager->setValue(familyProp, idx);
+ d_ptr->m_propertyToFamily[property] = familyProp;
+ d_ptr->m_familyToProperty[familyProp] = property;
+ property->addSubProperty(familyProp);
+
+ QtProperty *pointSizeProp = d_ptr->m_intPropertyManager->addProperty();
+ pointSizeProp->setPropertyName(tr("Point Size"));
+ d_ptr->m_intPropertyManager->setValue(pointSizeProp, val.pointSize());
+ d_ptr->m_intPropertyManager->setMinimum(pointSizeProp, 1);
+ d_ptr->m_propertyToPointSize[property] = pointSizeProp;
+ d_ptr->m_pointSizeToProperty[pointSizeProp] = property;
+ property->addSubProperty(pointSizeProp);
+
+ QtProperty *boldProp = d_ptr->m_boolPropertyManager->addProperty();
+ boldProp->setPropertyName(tr("Bold"));
+ d_ptr->m_boolPropertyManager->setValue(boldProp, val.bold());
+ d_ptr->m_propertyToBold[property] = boldProp;
+ d_ptr->m_boldToProperty[boldProp] = property;
+ property->addSubProperty(boldProp);
+
+ QtProperty *italicProp = d_ptr->m_boolPropertyManager->addProperty();
+ italicProp->setPropertyName(tr("Italic"));
+ d_ptr->m_boolPropertyManager->setValue(italicProp, val.italic());
+ d_ptr->m_propertyToItalic[property] = italicProp;
+ d_ptr->m_italicToProperty[italicProp] = property;
+ property->addSubProperty(italicProp);
+
+ QtProperty *underlineProp = d_ptr->m_boolPropertyManager->addProperty();
+ underlineProp->setPropertyName(tr("Underline"));
+ d_ptr->m_boolPropertyManager->setValue(underlineProp, val.underline());
+ d_ptr->m_propertyToUnderline[property] = underlineProp;
+ d_ptr->m_underlineToProperty[underlineProp] = property;
+ property->addSubProperty(underlineProp);
+
+ QtProperty *strikeOutProp = d_ptr->m_boolPropertyManager->addProperty();
+ strikeOutProp->setPropertyName(tr("Strikeout"));
+ d_ptr->m_boolPropertyManager->setValue(strikeOutProp, val.strikeOut());
+ d_ptr->m_propertyToStrikeOut[property] = strikeOutProp;
+ d_ptr->m_strikeOutToProperty[strikeOutProp] = property;
+ property->addSubProperty(strikeOutProp);
+
+ QtProperty *kerningProp = d_ptr->m_boolPropertyManager->addProperty();
+ kerningProp->setPropertyName(tr("Kerning"));
+ d_ptr->m_boolPropertyManager->setValue(kerningProp, val.kerning());
+ d_ptr->m_propertyToKerning[property] = kerningProp;
+ d_ptr->m_kerningToProperty[kerningProp] = property;
+ property->addSubProperty(kerningProp);
+}
+
+/*!
+ \reimp
+*/
+void QtFontPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *familyProp = d_ptr->m_propertyToFamily[property];
+ if (familyProp) {
+ d_ptr->m_familyToProperty.remove(familyProp);
+ delete familyProp;
+ }
+ d_ptr->m_propertyToFamily.remove(property);
+
+ QtProperty *pointSizeProp = d_ptr->m_propertyToPointSize[property];
+ if (pointSizeProp) {
+ d_ptr->m_pointSizeToProperty.remove(pointSizeProp);
+ delete pointSizeProp;
+ }
+ d_ptr->m_propertyToPointSize.remove(property);
+
+ QtProperty *boldProp = d_ptr->m_propertyToBold[property];
+ if (boldProp) {
+ d_ptr->m_boldToProperty.remove(boldProp);
+ delete boldProp;
+ }
+ d_ptr->m_propertyToBold.remove(property);
+
+ QtProperty *italicProp = d_ptr->m_propertyToItalic[property];
+ if (italicProp) {
+ d_ptr->m_italicToProperty.remove(italicProp);
+ delete italicProp;
+ }
+ d_ptr->m_propertyToItalic.remove(property);
+
+ QtProperty *underlineProp = d_ptr->m_propertyToUnderline[property];
+ if (underlineProp) {
+ d_ptr->m_underlineToProperty.remove(underlineProp);
+ delete underlineProp;
+ }
+ d_ptr->m_propertyToUnderline.remove(property);
+
+ QtProperty *strikeOutProp = d_ptr->m_propertyToStrikeOut[property];
+ if (strikeOutProp) {
+ d_ptr->m_strikeOutToProperty.remove(strikeOutProp);
+ delete strikeOutProp;
+ }
+ d_ptr->m_propertyToStrikeOut.remove(property);
+
+ QtProperty *kerningProp = d_ptr->m_propertyToKerning[property];
+ if (kerningProp) {
+ d_ptr->m_kerningToProperty.remove(kerningProp);
+ delete kerningProp;
+ }
+ d_ptr->m_propertyToKerning.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtColorPropertyManager
+
+class QtColorPropertyManagerPrivate
+{
+ QtColorPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorPropertyManager)
+public:
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, QColor> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToR;
+ QMap<const QtProperty *, QtProperty *> m_propertyToG;
+ QMap<const QtProperty *, QtProperty *> m_propertyToB;
+ QMap<const QtProperty *, QtProperty *> m_propertyToA;
+
+ QMap<const QtProperty *, QtProperty *> m_rToProperty;
+ QMap<const QtProperty *, QtProperty *> m_gToProperty;
+ QMap<const QtProperty *, QtProperty *> m_bToProperty;
+ QMap<const QtProperty *, QtProperty *> m_aToProperty;
+};
+
+void QtColorPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_rToProperty.value(property, 0)) {
+ QColor c = m_values[prop];
+ c.setRed(value);
+ q_ptr->setValue(prop, c);
+ } else if (QtProperty *prop = m_gToProperty.value(property, 0)) {
+ QColor c = m_values[prop];
+ c.setGreen(value);
+ q_ptr->setValue(prop, c);
+ } else if (QtProperty *prop = m_bToProperty.value(property, 0)) {
+ QColor c = m_values[prop];
+ c.setBlue(value);
+ q_ptr->setValue(prop, c);
+ } else if (QtProperty *prop = m_aToProperty.value(property, 0)) {
+ QColor c = m_values[prop];
+ c.setAlpha(value);
+ q_ptr->setValue(prop, c);
+ }
+}
+
+void QtColorPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_rToProperty.value(property, 0)) {
+ m_propertyToR[pointProp] = 0;
+ m_rToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_gToProperty.value(property, 0)) {
+ m_propertyToG[pointProp] = 0;
+ m_gToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_bToProperty.value(property, 0)) {
+ m_propertyToB[pointProp] = 0;
+ m_bToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_aToProperty.value(property, 0)) {
+ m_propertyToA[pointProp] = 0;
+ m_aToProperty.remove(property);
+ }
+}
+
+/*!
+ \class QtColorPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtColorPropertyManager provides and manages QColor properties.
+
+ A color property has nested \e red, \e green and \e blue
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtIntPropertyManager object. This
+ manager can be retrieved using the subIntPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ In addition, QtColorPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser, QtIntPropertyManager
+*/
+
+/*!
+ \fn void QtColorPropertyManager::valueChanged(QtProperty *property, const QColor &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtColorPropertyManager::QtColorPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtColorPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtColorPropertyManager::~QtColorPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that produces the nested \e red, \e green and
+ \e blue subproperties.
+
+ In order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtColorPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by \e this manager, this
+ function returns an invalid color.
+
+ \sa setValue()
+*/
+QColor QtColorPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QColor());
+}
+
+/*!
+ \reimp
+*/
+
+QString QtColorPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ return QtPropertyBrowserUtils::colorValueText(it.value());
+}
+
+/*!
+ \reimp
+*/
+
+QIcon QtColorPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+ return QtPropertyBrowserUtils::brushValueIcon(QBrush(it.value()));
+}
+
+/*!
+ \fn void QtColorPropertyManager::setValue(QtProperty *property, const QColor &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtColorPropertyManager::setValue(QtProperty *property, const QColor &val)
+{
+ const QtColorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value() == val)
+ return;
+
+ it.value() = val;
+
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToR[property], val.red());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToG[property], val.green());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToB[property], val.blue());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToA[property], val.alpha());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtColorPropertyManager::initializeProperty(QtProperty *property)
+{
+ QColor val;
+ d_ptr->m_values[property] = val;
+
+ QtProperty *rProp = d_ptr->m_intPropertyManager->addProperty();
+ rProp->setPropertyName(tr("Red"));
+ d_ptr->m_intPropertyManager->setValue(rProp, val.red());
+ d_ptr->m_intPropertyManager->setRange(rProp, 0, 0xFF);
+ d_ptr->m_propertyToR[property] = rProp;
+ d_ptr->m_rToProperty[rProp] = property;
+ property->addSubProperty(rProp);
+
+ QtProperty *gProp = d_ptr->m_intPropertyManager->addProperty();
+ gProp->setPropertyName(tr("Green"));
+ d_ptr->m_intPropertyManager->setValue(gProp, val.green());
+ d_ptr->m_intPropertyManager->setRange(gProp, 0, 0xFF);
+ d_ptr->m_propertyToG[property] = gProp;
+ d_ptr->m_gToProperty[gProp] = property;
+ property->addSubProperty(gProp);
+
+ QtProperty *bProp = d_ptr->m_intPropertyManager->addProperty();
+ bProp->setPropertyName(tr("Blue"));
+ d_ptr->m_intPropertyManager->setValue(bProp, val.blue());
+ d_ptr->m_intPropertyManager->setRange(bProp, 0, 0xFF);
+ d_ptr->m_propertyToB[property] = bProp;
+ d_ptr->m_bToProperty[bProp] = property;
+ property->addSubProperty(bProp);
+
+ QtProperty *aProp = d_ptr->m_intPropertyManager->addProperty();
+ aProp->setPropertyName(tr("Alpha"));
+ d_ptr->m_intPropertyManager->setValue(aProp, val.alpha());
+ d_ptr->m_intPropertyManager->setRange(aProp, 0, 0xFF);
+ d_ptr->m_propertyToA[property] = aProp;
+ d_ptr->m_aToProperty[aProp] = property;
+ property->addSubProperty(aProp);
+}
+
+/*!
+ \reimp
+*/
+void QtColorPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *rProp = d_ptr->m_propertyToR[property];
+ if (rProp) {
+ d_ptr->m_rToProperty.remove(rProp);
+ delete rProp;
+ }
+ d_ptr->m_propertyToR.remove(property);
+
+ QtProperty *gProp = d_ptr->m_propertyToG[property];
+ if (gProp) {
+ d_ptr->m_gToProperty.remove(gProp);
+ delete gProp;
+ }
+ d_ptr->m_propertyToG.remove(property);
+
+ QtProperty *bProp = d_ptr->m_propertyToB[property];
+ if (bProp) {
+ d_ptr->m_bToProperty.remove(bProp);
+ delete bProp;
+ }
+ d_ptr->m_propertyToB.remove(property);
+
+ QtProperty *aProp = d_ptr->m_propertyToA[property];
+ if (aProp) {
+ d_ptr->m_aToProperty.remove(aProp);
+ delete aProp;
+ }
+ d_ptr->m_propertyToA.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtCursorPropertyManager
+
+// Make sure icons are removed as soon as QApplication is destroyed, otherwise,
+// handles are leaked on X11.
+static void clearCursorDatabase();
+Q_GLOBAL_STATIC_WITH_INITIALIZER(QtCursorDatabase, cursorDatabase, qAddPostRoutine(clearCursorDatabase))
+
+static void clearCursorDatabase()
+{
+ cursorDatabase()->clear();
+}
+
+class QtCursorPropertyManagerPrivate
+{
+ QtCursorPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtCursorPropertyManager)
+public:
+ typedef QMap<const QtProperty *, QCursor> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*!
+ \class QtCursorPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCursorPropertyManager provides and manages QCursor properties.
+
+ A cursor property has a current value which can be
+ retrieved using the value() function, and set using the setValue()
+ slot. In addition, QtCursorPropertyManager provides the
+ valueChanged() signal which is emitted whenever a property created
+ by this manager changes.
+
+ \sa QtAbstractPropertyManager
+*/
+
+/*!
+ \fn void QtCursorPropertyManager::valueChanged(QtProperty *property, const QCursor &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtCursorPropertyManager::QtCursorPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtCursorPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtCursorPropertyManager::~QtCursorPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns a default QCursor object.
+
+ \sa setValue()
+*/
+#ifndef QT_NO_CURSOR
+QCursor QtCursorPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QCursor());
+}
+#endif
+
+/*!
+ \reimp
+*/
+QString QtCursorPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ return cursorDatabase()->cursorToShapeName(it.value());
+}
+
+/*!
+ \reimp
+*/
+QIcon QtCursorPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+
+ return cursorDatabase()->cursorToShapeIcon(it.value());
+}
+
+/*!
+ \fn void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value)
+{
+#ifndef QT_NO_CURSOR
+ const QtCursorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value().shape() == value.shape() && value.shape() != Qt::BitmapCursor)
+ return;
+
+ it.value() = value;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, value);
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QtCursorPropertyManager::initializeProperty(QtProperty *property)
+{
+#ifndef QT_NO_CURSOR
+ d_ptr->m_values[property] = QCursor();
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QtCursorPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtpropertymanager.cpp"
+#include "qtpropertymanager.moc"
diff --git a/src/shared/qtpropertybrowser/qtpropertymanager.h b/src/shared/qtpropertybrowser/qtpropertymanager.h
new file mode 100644
index 000000000..f821ff152
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertymanager.h
@@ -0,0 +1,746 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTPROPERTYMANAGER_H
+#define QTPROPERTYMANAGER_H
+
+#include "qtpropertybrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDate;
+class QTime;
+class QDateTime;
+class QLocale;
+
+class QtGroupPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtGroupPropertyManager(QObject *parent = 0);
+ ~QtGroupPropertyManager();
+
+protected:
+ virtual bool hasValue(const QtProperty *property) const;
+
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+};
+
+class QtIntPropertyManagerPrivate;
+
+class QtIntPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtIntPropertyManager(QObject *parent = 0);
+ ~QtIntPropertyManager();
+
+ int value(const QtProperty *property) const;
+ int minimum(const QtProperty *property) const;
+ int maximum(const QtProperty *property) const;
+ int singleStep(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, int val);
+ void setMinimum(QtProperty *property, int minVal);
+ void setMaximum(QtProperty *property, int maxVal);
+ void setRange(QtProperty *property, int minVal, int maxVal);
+ void setSingleStep(QtProperty *property, int step);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, int val);
+ void rangeChanged(QtProperty *property, int minVal, int maxVal);
+ void singleStepChanged(QtProperty *property, int step);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtIntPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtIntPropertyManager)
+ Q_DISABLE_COPY(QtIntPropertyManager)
+};
+
+class QtBoolPropertyManagerPrivate;
+
+class QtBoolPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtBoolPropertyManager(QObject *parent = 0);
+ ~QtBoolPropertyManager();
+
+ bool value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, bool val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, bool val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtBoolPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtBoolPropertyManager)
+ Q_DISABLE_COPY(QtBoolPropertyManager)
+};
+
+class QtDoublePropertyManagerPrivate;
+
+class QtDoublePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtDoublePropertyManager(QObject *parent = 0);
+ ~QtDoublePropertyManager();
+
+ double value(const QtProperty *property) const;
+ double minimum(const QtProperty *property) const;
+ double maximum(const QtProperty *property) const;
+ double singleStep(const QtProperty *property) const;
+ int decimals(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, double val);
+ void setMinimum(QtProperty *property, double minVal);
+ void setMaximum(QtProperty *property, double maxVal);
+ void setRange(QtProperty *property, double minVal, double maxVal);
+ void setSingleStep(QtProperty *property, double step);
+ void setDecimals(QtProperty *property, int prec);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, double val);
+ void rangeChanged(QtProperty *property, double minVal, double maxVal);
+ void singleStepChanged(QtProperty *property, double step);
+ void decimalsChanged(QtProperty *property, int prec);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtDoublePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDoublePropertyManager)
+ Q_DISABLE_COPY(QtDoublePropertyManager)
+};
+
+class QtStringPropertyManagerPrivate;
+
+class QtStringPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtStringPropertyManager(QObject *parent = 0);
+ ~QtStringPropertyManager();
+
+ QString value(const QtProperty *property) const;
+ QRegExp regExp(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QString &val);
+ void setRegExp(QtProperty *property, const QRegExp &regExp);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QString &val);
+ void regExpChanged(QtProperty *property, const QRegExp &regExp);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtStringPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtStringPropertyManager)
+ Q_DISABLE_COPY(QtStringPropertyManager)
+};
+
+class QtDatePropertyManagerPrivate;
+
+class QtDatePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtDatePropertyManager(QObject *parent = 0);
+ ~QtDatePropertyManager();
+
+ QDate value(const QtProperty *property) const;
+ QDate minimum(const QtProperty *property) const;
+ QDate maximum(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QDate &val);
+ void setMinimum(QtProperty *property, const QDate &minVal);
+ void setMaximum(QtProperty *property, const QDate &maxVal);
+ void setRange(QtProperty *property, const QDate &minVal, const QDate &maxVal);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QDate &val);
+ void rangeChanged(QtProperty *property, const QDate &minVal, const QDate &maxVal);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtDatePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDatePropertyManager)
+ Q_DISABLE_COPY(QtDatePropertyManager)
+};
+
+class QtTimePropertyManagerPrivate;
+
+class QtTimePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtTimePropertyManager(QObject *parent = 0);
+ ~QtTimePropertyManager();
+
+ QTime value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QTime &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QTime &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtTimePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtTimePropertyManager)
+ Q_DISABLE_COPY(QtTimePropertyManager)
+};
+
+class QtDateTimePropertyManagerPrivate;
+
+class QtDateTimePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtDateTimePropertyManager(QObject *parent = 0);
+ ~QtDateTimePropertyManager();
+
+ QDateTime value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QDateTime &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QDateTime &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtDateTimePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDateTimePropertyManager)
+ Q_DISABLE_COPY(QtDateTimePropertyManager)
+};
+
+class QtKeySequencePropertyManagerPrivate;
+
+class QtKeySequencePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtKeySequencePropertyManager(QObject *parent = 0);
+ ~QtKeySequencePropertyManager();
+
+ QKeySequence value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QKeySequence &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QKeySequence &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtKeySequencePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtKeySequencePropertyManager)
+ Q_DISABLE_COPY(QtKeySequencePropertyManager)
+};
+
+class QtCharPropertyManagerPrivate;
+
+class QtCharPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtCharPropertyManager(QObject *parent = 0);
+ ~QtCharPropertyManager();
+
+ QChar value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QChar &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QChar &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtCharPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCharPropertyManager)
+ Q_DISABLE_COPY(QtCharPropertyManager)
+};
+
+class QtEnumPropertyManager;
+class QtLocalePropertyManagerPrivate;
+
+class QtLocalePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtLocalePropertyManager(QObject *parent = 0);
+ ~QtLocalePropertyManager();
+
+ QtEnumPropertyManager *subEnumPropertyManager() const;
+
+ QLocale value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QLocale &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QLocale &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtLocalePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtLocalePropertyManager)
+ Q_DISABLE_COPY(QtLocalePropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtPointPropertyManagerPrivate;
+
+class QtPointPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtPointPropertyManager(QObject *parent = 0);
+ ~QtPointPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+
+ QPoint value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QPoint &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QPoint &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtPointPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtPointPropertyManager)
+ Q_DISABLE_COPY(QtPointPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtPointFPropertyManagerPrivate;
+
+class QtPointFPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtPointFPropertyManager(QObject *parent = 0);
+ ~QtPointFPropertyManager();
+
+ QtDoublePropertyManager *subDoublePropertyManager() const;
+
+ QPointF value(const QtProperty *property) const;
+ int decimals(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QPointF &val);
+ void setDecimals(QtProperty *property, int prec);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QPointF &val);
+ void decimalsChanged(QtProperty *property, int prec);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtPointFPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtPointFPropertyManager)
+ Q_DISABLE_COPY(QtPointFPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtSizePropertyManagerPrivate;
+
+class QtSizePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtSizePropertyManager(QObject *parent = 0);
+ ~QtSizePropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+
+ QSize value(const QtProperty *property) const;
+ QSize minimum(const QtProperty *property) const;
+ QSize maximum(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QSize &val);
+ void setMinimum(QtProperty *property, const QSize &minVal);
+ void setMaximum(QtProperty *property, const QSize &maxVal);
+ void setRange(QtProperty *property, const QSize &minVal, const QSize &maxVal);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QSize &val);
+ void rangeChanged(QtProperty *property, const QSize &minVal, const QSize &maxVal);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtSizePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSizePropertyManager)
+ Q_DISABLE_COPY(QtSizePropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtSizeFPropertyManagerPrivate;
+
+class QtSizeFPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtSizeFPropertyManager(QObject *parent = 0);
+ ~QtSizeFPropertyManager();
+
+ QtDoublePropertyManager *subDoublePropertyManager() const;
+
+ QSizeF value(const QtProperty *property) const;
+ QSizeF minimum(const QtProperty *property) const;
+ QSizeF maximum(const QtProperty *property) const;
+ int decimals(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QSizeF &val);
+ void setMinimum(QtProperty *property, const QSizeF &minVal);
+ void setMaximum(QtProperty *property, const QSizeF &maxVal);
+ void setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal);
+ void setDecimals(QtProperty *property, int prec);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QSizeF &val);
+ void rangeChanged(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal);
+ void decimalsChanged(QtProperty *property, int prec);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtSizeFPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSizeFPropertyManager)
+ Q_DISABLE_COPY(QtSizeFPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtRectPropertyManagerPrivate;
+
+class QtRectPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtRectPropertyManager(QObject *parent = 0);
+ ~QtRectPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+
+ QRect value(const QtProperty *property) const;
+ QRect constraint(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QRect &val);
+ void setConstraint(QtProperty *property, const QRect &constraint);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QRect &val);
+ void constraintChanged(QtProperty *property, const QRect &constraint);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtRectPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtRectPropertyManager)
+ Q_DISABLE_COPY(QtRectPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtRectFPropertyManagerPrivate;
+
+class QtRectFPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtRectFPropertyManager(QObject *parent = 0);
+ ~QtRectFPropertyManager();
+
+ QtDoublePropertyManager *subDoublePropertyManager() const;
+
+ QRectF value(const QtProperty *property) const;
+ QRectF constraint(const QtProperty *property) const;
+ int decimals(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QRectF &val);
+ void setConstraint(QtProperty *property, const QRectF &constraint);
+ void setDecimals(QtProperty *property, int prec);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QRectF &val);
+ void constraintChanged(QtProperty *property, const QRectF &constraint);
+ void decimalsChanged(QtProperty *property, int prec);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtRectFPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtRectFPropertyManager)
+ Q_DISABLE_COPY(QtRectFPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtEnumPropertyManagerPrivate;
+
+class QtEnumPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtEnumPropertyManager(QObject *parent = 0);
+ ~QtEnumPropertyManager();
+
+ int value(const QtProperty *property) const;
+ QStringList enumNames(const QtProperty *property) const;
+ QMap<int, QIcon> enumIcons(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, int val);
+ void setEnumNames(QtProperty *property, const QStringList &names);
+ void setEnumIcons(QtProperty *property, const QMap<int, QIcon> &icons);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, int val);
+ void enumNamesChanged(QtProperty *property, const QStringList &names);
+ void enumIconsChanged(QtProperty *property, const QMap<int, QIcon> &icons);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtEnumPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtEnumPropertyManager)
+ Q_DISABLE_COPY(QtEnumPropertyManager)
+};
+
+class QtFlagPropertyManagerPrivate;
+
+class QtFlagPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtFlagPropertyManager(QObject *parent = 0);
+ ~QtFlagPropertyManager();
+
+ QtBoolPropertyManager *subBoolPropertyManager() const;
+
+ int value(const QtProperty *property) const;
+ QStringList flagNames(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, int val);
+ void setFlagNames(QtProperty *property, const QStringList &names);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, int val);
+ void flagNamesChanged(QtProperty *property, const QStringList &names);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtFlagPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtFlagPropertyManager)
+ Q_DISABLE_COPY(QtFlagPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty *, bool))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtSizePolicyPropertyManagerPrivate;
+
+class QtSizePolicyPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtSizePolicyPropertyManager(QObject *parent = 0);
+ ~QtSizePolicyPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+ QtEnumPropertyManager *subEnumPropertyManager() const;
+
+ QSizePolicy value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QSizePolicy &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QSizePolicy &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtSizePolicyPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSizePolicyPropertyManager)
+ Q_DISABLE_COPY(QtSizePolicyPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtFontPropertyManagerPrivate;
+
+class QtFontPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtFontPropertyManager(QObject *parent = 0);
+ ~QtFontPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+ QtEnumPropertyManager *subEnumPropertyManager() const;
+ QtBoolPropertyManager *subBoolPropertyManager() const;
+
+ QFont value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QFont &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QFont &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtFontPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtFontPropertyManager)
+ Q_DISABLE_COPY(QtFontPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty *, bool))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseChanged())
+ Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseDelayedChange())
+};
+
+class QtColorPropertyManagerPrivate;
+
+class QtColorPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtColorPropertyManager(QObject *parent = 0);
+ ~QtColorPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+
+ QColor value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QColor &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QColor &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtColorPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorPropertyManager)
+ Q_DISABLE_COPY(QtColorPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtCursorPropertyManagerPrivate;
+
+class QtCursorPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtCursorPropertyManager(QObject *parent = 0);
+ ~QtCursorPropertyManager();
+
+#ifndef QT_NO_CURSOR
+ QCursor value(const QtProperty *property) const;
+#endif
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QCursor &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QCursor &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtCursorPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCursorPropertyManager)
+ Q_DISABLE_COPY(QtCursorPropertyManager)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qttreepropertybrowser.cpp b/src/shared/qtpropertybrowser/qttreepropertybrowser.cpp
new file mode 100644
index 000000000..58a29e0e2
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qttreepropertybrowser.cpp
@@ -0,0 +1,1042 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qttreepropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtGui/QIcon>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QItemDelegate>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QHeaderView>
+#include <QtGui/QPainter>
+#include <QtGui/QApplication>
+#include <QtGui/QFocusEvent>
+#include <QtGui/QStyle>
+#include <QtGui/QPalette>
+
+QT_BEGIN_NAMESPACE
+
+class QtPropertyEditorView;
+
+class QtTreePropertyBrowserPrivate
+{
+ QtTreePropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtTreePropertyBrowser)
+
+public:
+ QtTreePropertyBrowserPrivate();
+ void init(QWidget *parent);
+
+ void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex);
+ void propertyRemoved(QtBrowserItem *index);
+ void propertyChanged(QtBrowserItem *index);
+ QWidget *createEditor(QtProperty *property, QWidget *parent) const
+ { return q_ptr->createEditor(property, parent); }
+ QtProperty *indexToProperty(const QModelIndex &index) const;
+ QTreeWidgetItem *indexToItem(const QModelIndex &index) const;
+ QtBrowserItem *indexToBrowserItem(const QModelIndex &index) const;
+ bool lastColumn(int column) const;
+ void disableItem(QTreeWidgetItem *item) const;
+ void enableItem(QTreeWidgetItem *item) const;
+ bool hasValue(QTreeWidgetItem *item) const;
+
+ void slotCollapsed(const QModelIndex &index);
+ void slotExpanded(const QModelIndex &index);
+
+ QColor calculatedBackgroundColor(QtBrowserItem *item) const;
+
+ QtPropertyEditorView *treeWidget() const { return m_treeWidget; }
+ bool markPropertiesWithoutValue() const { return m_markPropertiesWithoutValue; }
+
+ QtBrowserItem *currentItem() const;
+ void setCurrentItem(QtBrowserItem *browserItem, bool block);
+ void editItem(QtBrowserItem *browserItem);
+
+ void slotCurrentBrowserItemChanged(QtBrowserItem *item);
+ void slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *);
+
+ QTreeWidgetItem *editedItem() const;
+
+private:
+ void updateItem(QTreeWidgetItem *item);
+
+ QMap<QtBrowserItem *, QTreeWidgetItem *> m_indexToItem;
+ QMap<QTreeWidgetItem *, QtBrowserItem *> m_itemToIndex;
+
+ QMap<QtBrowserItem *, QColor> m_indexToBackgroundColor;
+
+ QtPropertyEditorView *m_treeWidget;
+
+ bool m_headerVisible;
+ QtTreePropertyBrowser::ResizeMode m_resizeMode;
+ class QtPropertyEditorDelegate *m_delegate;
+ bool m_markPropertiesWithoutValue;
+ bool m_browserChangedBlocked;
+ QIcon m_expandIcon;
+};
+
+// ------------ QtPropertyEditorView
+class QtPropertyEditorView : public QTreeWidget
+{
+ Q_OBJECT
+public:
+ QtPropertyEditorView(QWidget *parent = 0);
+
+ void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate)
+ { m_editorPrivate = editorPrivate; }
+
+ QTreeWidgetItem *indexToItem(const QModelIndex &index) const
+ { return itemFromIndex(index); }
+
+protected:
+ void keyPressEvent(QKeyEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+private:
+ QtTreePropertyBrowserPrivate *m_editorPrivate;
+};
+
+QtPropertyEditorView::QtPropertyEditorView(QWidget *parent) :
+ QTreeWidget(parent),
+ m_editorPrivate(0)
+{
+ connect(header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(resizeColumnToContents(int)));
+}
+
+void QtPropertyEditorView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ QStyleOptionViewItemV3 opt = option;
+ bool hasValue = true;
+ if (m_editorPrivate) {
+ QtProperty *property = m_editorPrivate->indexToProperty(index);
+ if (property)
+ hasValue = property->hasValue();
+ }
+ if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) {
+ const QColor c = option.palette.color(QPalette::Dark);
+ painter->fillRect(option.rect, c);
+ opt.palette.setColor(QPalette::AlternateBase, c);
+ } else {
+ const QColor c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index));
+ if (c.isValid()) {
+ painter->fillRect(option.rect, c);
+ opt.palette.setColor(QPalette::AlternateBase, c.lighter(112));
+ }
+ }
+ QTreeWidget::drawRow(painter, opt, index);
+ QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt));
+ painter->save();
+ painter->setPen(QPen(color));
+ painter->drawLine(opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom());
+ painter->restore();
+}
+
+void QtPropertyEditorView::keyPressEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ case Qt::Key_Space: // Trigger Edit
+ if (!m_editorPrivate->editedItem())
+ if (const QTreeWidgetItem *item = currentItem())
+ if (item->columnCount() >= 2 && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) {
+ event->accept();
+ // If the current position is at column 0, move to 1.
+ QModelIndex index = currentIndex();
+ if (index.column() == 0) {
+ index = index.sibling(index.row(), 1);
+ setCurrentIndex(index);
+ }
+ edit(index);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ QTreeWidget::keyPressEvent(event);
+}
+
+void QtPropertyEditorView::mousePressEvent(QMouseEvent *event)
+{
+ QTreeWidget::mousePressEvent(event);
+ QTreeWidgetItem *item = itemAt(event->pos());
+
+ if (item) {
+ if ((item != m_editorPrivate->editedItem()) && (event->button() == Qt::LeftButton)
+ && (header()->logicalIndexAt(event->pos().x()) == 1)
+ && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) {
+ editItem(item, 1);
+ } else if (!m_editorPrivate->hasValue(item) && m_editorPrivate->markPropertiesWithoutValue() && !rootIsDecorated()) {
+ if (event->pos().x() + header()->offset() < 20)
+ item->setExpanded(!item->isExpanded());
+ }
+ }
+}
+
+// ------------ QtPropertyEditorDelegate
+class QtPropertyEditorDelegate : public QItemDelegate
+{
+ Q_OBJECT
+public:
+ QtPropertyEditorDelegate(QObject *parent = 0)
+ : QItemDelegate(parent), m_editorPrivate(0), m_editedItem(0), m_editedWidget(0)
+ {}
+
+ void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate)
+ { m_editorPrivate = editorPrivate; }
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ void setModelData(QWidget *, QAbstractItemModel *,
+ const QModelIndex &) const {}
+
+ void setEditorData(QWidget *, const QModelIndex &) const {}
+
+ bool eventFilter(QObject *object, QEvent *event);
+ void closeEditor(QtProperty *property);
+
+ QTreeWidgetItem *editedItem() const { return m_editedItem; }
+
+private slots:
+ void slotEditorDestroyed(QObject *object);
+
+private:
+ int indentation(const QModelIndex &index) const;
+
+ typedef QMap<QWidget *, QtProperty *> EditorToPropertyMap;
+ mutable EditorToPropertyMap m_editorToProperty;
+
+ typedef QMap<QtProperty *, QWidget *> PropertyToEditorMap;
+ mutable PropertyToEditorMap m_propertyToEditor;
+ QtTreePropertyBrowserPrivate *m_editorPrivate;
+ mutable QTreeWidgetItem *m_editedItem;
+ mutable QWidget *m_editedWidget;
+};
+
+int QtPropertyEditorDelegate::indentation(const QModelIndex &index) const
+{
+ if (!m_editorPrivate)
+ return 0;
+
+ QTreeWidgetItem *item = m_editorPrivate->indexToItem(index);
+ int indent = 0;
+ while (item->parent()) {
+ item = item->parent();
+ ++indent;
+ }
+ if (m_editorPrivate->treeWidget()->rootIsDecorated())
+ ++indent;
+ return indent * m_editorPrivate->treeWidget()->indentation();
+}
+
+void QtPropertyEditorDelegate::slotEditorDestroyed(QObject *object)
+{
+ if (QWidget *w = qobject_cast<QWidget *>(object)) {
+ const EditorToPropertyMap::iterator it = m_editorToProperty.find(w);
+ if (it != m_editorToProperty.end()) {
+ m_propertyToEditor.remove(it.value());
+ m_editorToProperty.erase(it);
+ }
+ if (m_editedWidget == w) {
+ m_editedWidget = 0;
+ m_editedItem = 0;
+ }
+ }
+}
+
+void QtPropertyEditorDelegate::closeEditor(QtProperty *property)
+{
+ if (QWidget *w = m_propertyToEditor.value(property, 0))
+ w->deleteLater();
+}
+
+QWidget *QtPropertyEditorDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem &, const QModelIndex &index) const
+{
+ if (index.column() == 1 && m_editorPrivate) {
+ QtProperty *property = m_editorPrivate->indexToProperty(index);
+ QTreeWidgetItem *item = m_editorPrivate->indexToItem(index);
+ if (property && item && (item->flags() & Qt::ItemIsEnabled)) {
+ QWidget *editor = m_editorPrivate->createEditor(property, parent);
+ if (editor) {
+ editor->setAutoFillBackground(true);
+ editor->installEventFilter(const_cast<QtPropertyEditorDelegate *>(this));
+ connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ m_propertyToEditor[property] = editor;
+ m_editorToProperty[editor] = property;
+ m_editedItem = item;
+ m_editedWidget = editor;
+ }
+ return editor;
+ }
+ }
+ return 0;
+}
+
+void QtPropertyEditorDelegate::updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ editor->setGeometry(option.rect.adjusted(0, 0, 0, -1));
+}
+
+void QtPropertyEditorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ bool hasValue = true;
+ if (m_editorPrivate) {
+ QtProperty *property = m_editorPrivate->indexToProperty(index);
+ if (property)
+ hasValue = property->hasValue();
+ }
+ QStyleOptionViewItemV3 opt = option;
+ if ((m_editorPrivate && index.column() == 0) || !hasValue) {
+ QtProperty *property = m_editorPrivate->indexToProperty(index);
+ if (property && property->isModified()) {
+ opt.font.setBold(true);
+ opt.fontMetrics = QFontMetrics(opt.font);
+ }
+ }
+ QColor c;
+ if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) {
+ c = opt.palette.color(QPalette::Dark);
+ opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::BrightText));
+ } else {
+ c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index));
+ if (c.isValid() && (opt.features & QStyleOptionViewItemV2::Alternate))
+ c = c.lighter(112);
+ }
+ if (c.isValid())
+ painter->fillRect(option.rect, c);
+ opt.state &= ~QStyle::State_HasFocus;
+ QItemDelegate::paint(painter, opt, index);
+
+ opt.palette.setCurrentColorGroup(QPalette::Active);
+ QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt));
+ painter->save();
+ painter->setPen(QPen(color));
+ if (!m_editorPrivate || (!m_editorPrivate->lastColumn(index.column()) && hasValue)) {
+ int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left();
+ painter->drawLine(right, option.rect.y(), right, option.rect.bottom());
+ }
+ painter->restore();
+}
+
+QSize QtPropertyEditorDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ return QItemDelegate::sizeHint(option, index) + QSize(3, 4);
+}
+
+bool QtPropertyEditorDelegate::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::FocusOut) {
+ QFocusEvent *fe = static_cast<QFocusEvent *>(event);
+ if (fe->reason() == Qt::ActiveWindowFocusReason)
+ return false;
+ }
+ return QItemDelegate::eventFilter(object, event);
+}
+
+// -------- QtTreePropertyBrowserPrivate implementation
+QtTreePropertyBrowserPrivate::QtTreePropertyBrowserPrivate() :
+ m_treeWidget(0),
+ m_headerVisible(true),
+ m_resizeMode(QtTreePropertyBrowser::Stretch),
+ m_delegate(0),
+ m_markPropertiesWithoutValue(false),
+ m_browserChangedBlocked(false)
+{
+}
+
+// Draw an icon indicating opened/closing branches
+static QIcon drawIndicatorIcon(const QPalette &palette, QStyle *style)
+{
+ QPixmap pix(14, 14);
+ pix.fill(Qt::transparent);
+ QStyleOption branchOption;
+ QRect r(QPoint(0, 0), pix.size());
+ branchOption.rect = QRect(2, 2, 9, 9); // ### hardcoded in qcommonstyle.cpp
+ branchOption.palette = palette;
+ branchOption.state = QStyle::State_Children;
+
+ QPainter p;
+ // Draw closed state
+ p.begin(&pix);
+ style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p);
+ p.end();
+ QIcon rc = pix;
+ rc.addPixmap(pix, QIcon::Selected, QIcon::Off);
+ // Draw opened state
+ branchOption.state |= QStyle::State_Open;
+ pix.fill(Qt::transparent);
+ p.begin(&pix);
+ style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p);
+ p.end();
+
+ rc.addPixmap(pix, QIcon::Normal, QIcon::On);
+ rc.addPixmap(pix, QIcon::Selected, QIcon::On);
+ return rc;
+}
+
+void QtTreePropertyBrowserPrivate::init(QWidget *parent)
+{
+ QHBoxLayout *layout = new QHBoxLayout(parent);
+ layout->setMargin(0);
+ m_treeWidget = new QtPropertyEditorView(parent);
+ m_treeWidget->setEditorPrivate(this);
+ m_treeWidget->setIconSize(QSize(18, 18));
+ layout->addWidget(m_treeWidget);
+
+ m_treeWidget->setColumnCount(2);
+ QStringList labels;
+ labels.append(QApplication::translate("QtTreePropertyBrowser", "Property", 0, QApplication::UnicodeUTF8));
+ labels.append(QApplication::translate("QtTreePropertyBrowser", "Value", 0, QApplication::UnicodeUTF8));
+ m_treeWidget->setHeaderLabels(labels);
+ m_treeWidget->setAlternatingRowColors(true);
+ m_treeWidget->setEditTriggers(QAbstractItemView::EditKeyPressed);
+ m_delegate = new QtPropertyEditorDelegate(parent);
+ m_delegate->setEditorPrivate(this);
+ m_treeWidget->setItemDelegate(m_delegate);
+ m_treeWidget->header()->setMovable(false);
+ m_treeWidget->header()->setResizeMode(QHeaderView::Stretch);
+
+ m_expandIcon = drawIndicatorIcon(q_ptr->palette(), q_ptr->style());
+
+ QObject::connect(m_treeWidget, SIGNAL(collapsed(QModelIndex)), q_ptr, SLOT(slotCollapsed(QModelIndex)));
+ QObject::connect(m_treeWidget, SIGNAL(expanded(QModelIndex)), q_ptr, SLOT(slotExpanded(QModelIndex)));
+ QObject::connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), q_ptr, SLOT(slotCurrentTreeItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
+}
+
+QtBrowserItem *QtTreePropertyBrowserPrivate::currentItem() const
+{
+ if (QTreeWidgetItem *treeItem = m_treeWidget->currentItem())
+ return m_itemToIndex.value(treeItem);
+ return 0;
+}
+
+void QtTreePropertyBrowserPrivate::setCurrentItem(QtBrowserItem *browserItem, bool block)
+{
+ const bool blocked = block ? m_treeWidget->blockSignals(true) : false;
+ if (browserItem == 0)
+ m_treeWidget->setCurrentItem(0);
+ else
+ m_treeWidget->setCurrentItem(m_indexToItem.value(browserItem));
+ if (block)
+ m_treeWidget->blockSignals(blocked);
+}
+
+QtProperty *QtTreePropertyBrowserPrivate::indexToProperty(const QModelIndex &index) const
+{
+ QTreeWidgetItem *item = m_treeWidget->indexToItem(index);
+ QtBrowserItem *idx = m_itemToIndex.value(item);
+ if (idx)
+ return idx->property();
+ return 0;
+}
+
+QtBrowserItem *QtTreePropertyBrowserPrivate::indexToBrowserItem(const QModelIndex &index) const
+{
+ QTreeWidgetItem *item = m_treeWidget->indexToItem(index);
+ return m_itemToIndex.value(item);
+}
+
+QTreeWidgetItem *QtTreePropertyBrowserPrivate::indexToItem(const QModelIndex &index) const
+{
+ return m_treeWidget->indexToItem(index);
+}
+
+bool QtTreePropertyBrowserPrivate::lastColumn(int column) const
+{
+ return m_treeWidget->header()->visualIndex(column) == m_treeWidget->columnCount() - 1;
+}
+
+void QtTreePropertyBrowserPrivate::disableItem(QTreeWidgetItem *item) const
+{
+ Qt::ItemFlags flags = item->flags();
+ if (flags & Qt::ItemIsEnabled) {
+ flags &= ~Qt::ItemIsEnabled;
+ item->setFlags(flags);
+ m_delegate->closeEditor(m_itemToIndex[item]->property());
+ const int childCount = item->childCount();
+ for (int i = 0; i < childCount; i++) {
+ QTreeWidgetItem *child = item->child(i);
+ disableItem(child);
+ }
+ }
+}
+
+void QtTreePropertyBrowserPrivate::enableItem(QTreeWidgetItem *item) const
+{
+ Qt::ItemFlags flags = item->flags();
+ flags |= Qt::ItemIsEnabled;
+ item->setFlags(flags);
+ const int childCount = item->childCount();
+ for (int i = 0; i < childCount; i++) {
+ QTreeWidgetItem *child = item->child(i);
+ QtProperty *property = m_itemToIndex[child]->property();
+ if (property->isEnabled()) {
+ enableItem(child);
+ }
+ }
+}
+
+bool QtTreePropertyBrowserPrivate::hasValue(QTreeWidgetItem *item) const
+{
+ QtBrowserItem *browserItem = m_itemToIndex.value(item);
+ if (browserItem)
+ return browserItem->property()->hasValue();
+ return false;
+}
+
+void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex)
+{
+ QTreeWidgetItem *afterItem = m_indexToItem.value(afterIndex);
+ QTreeWidgetItem *parentItem = m_indexToItem.value(index->parent());
+
+ QTreeWidgetItem *newItem = 0;
+ if (parentItem) {
+ newItem = new QTreeWidgetItem(parentItem, afterItem);
+ } else {
+ newItem = new QTreeWidgetItem(m_treeWidget, afterItem);
+ }
+ m_itemToIndex[newItem] = index;
+ m_indexToItem[index] = newItem;
+
+ newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
+ m_treeWidget->setItemExpanded(newItem, true);
+
+ updateItem(newItem);
+}
+
+void QtTreePropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index)
+{
+ QTreeWidgetItem *item = m_indexToItem.value(index);
+
+ if (m_treeWidget->currentItem() == item) {
+ m_treeWidget->setCurrentItem(0);
+ }
+
+ delete item;
+
+ m_indexToItem.remove(index);
+ m_itemToIndex.remove(item);
+ m_indexToBackgroundColor.remove(index);
+}
+
+void QtTreePropertyBrowserPrivate::propertyChanged(QtBrowserItem *index)
+{
+ QTreeWidgetItem *item = m_indexToItem.value(index);
+
+ updateItem(item);
+}
+
+void QtTreePropertyBrowserPrivate::updateItem(QTreeWidgetItem *item)
+{
+ QtProperty *property = m_itemToIndex[item]->property();
+ QIcon expandIcon;
+ if (property->hasValue()) {
+ QString toolTip = property->toolTip();
+ if (toolTip.isEmpty())
+ toolTip = property->valueText();
+ item->setToolTip(1, toolTip);
+ item->setIcon(1, property->valueIcon());
+ item->setText(1, property->valueText());
+ } else if (markPropertiesWithoutValue() && !m_treeWidget->rootIsDecorated()) {
+ expandIcon = m_expandIcon;
+ }
+ item->setIcon(0, expandIcon);
+ item->setFirstColumnSpanned(!property->hasValue());
+ item->setToolTip(0, property->propertyName());
+ item->setStatusTip(0, property->statusTip());
+ item->setWhatsThis(0, property->whatsThis());
+ item->setText(0, property->propertyName());
+ bool wasEnabled = item->flags() & Qt::ItemIsEnabled;
+ bool isEnabled = wasEnabled;
+ if (property->isEnabled()) {
+ QTreeWidgetItem *parent = item->parent();
+ if (!parent || (parent->flags() & Qt::ItemIsEnabled))
+ isEnabled = true;
+ else
+ isEnabled = false;
+ } else {
+ isEnabled = false;
+ }
+ if (wasEnabled != isEnabled) {
+ if (isEnabled)
+ enableItem(item);
+ else
+ disableItem(item);
+ }
+ m_treeWidget->viewport()->update();
+}
+
+QColor QtTreePropertyBrowserPrivate::calculatedBackgroundColor(QtBrowserItem *item) const
+{
+ QtBrowserItem *i = item;
+ const QMap<QtBrowserItem *, QColor>::const_iterator itEnd = m_indexToBackgroundColor.constEnd();
+ while (i) {
+ QMap<QtBrowserItem *, QColor>::const_iterator it = m_indexToBackgroundColor.constFind(i);
+ if (it != itEnd)
+ return it.value();
+ i = i->parent();
+ }
+ return QColor();
+}
+
+void QtTreePropertyBrowserPrivate::slotCollapsed(const QModelIndex &index)
+{
+ QTreeWidgetItem *item = indexToItem(index);
+ QtBrowserItem *idx = m_itemToIndex.value(item);
+ if (item)
+ emit q_ptr->collapsed(idx);
+}
+
+void QtTreePropertyBrowserPrivate::slotExpanded(const QModelIndex &index)
+{
+ QTreeWidgetItem *item = indexToItem(index);
+ QtBrowserItem *idx = m_itemToIndex.value(item);
+ if (item)
+ emit q_ptr->expanded(idx);
+}
+
+void QtTreePropertyBrowserPrivate::slotCurrentBrowserItemChanged(QtBrowserItem *item)
+{
+ if (!m_browserChangedBlocked && item != currentItem())
+ setCurrentItem(item, true);
+}
+
+void QtTreePropertyBrowserPrivate::slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *)
+{
+ QtBrowserItem *browserItem = newItem ? m_itemToIndex.value(newItem) : 0;
+ m_browserChangedBlocked = true;
+ q_ptr->setCurrentItem(browserItem);
+ m_browserChangedBlocked = false;
+}
+
+QTreeWidgetItem *QtTreePropertyBrowserPrivate::editedItem() const
+{
+ return m_delegate->editedItem();
+}
+
+void QtTreePropertyBrowserPrivate::editItem(QtBrowserItem *browserItem)
+{
+ if (QTreeWidgetItem *treeItem = m_indexToItem.value(browserItem, 0)) {
+ m_treeWidget->setCurrentItem (treeItem, 1);
+ m_treeWidget->editItem(treeItem, 1);
+ }
+}
+
+/*!
+ \class QtTreePropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtTreePropertyBrowser class provides QTreeWidget based
+ property browser.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ QtTreePropertyBrowser provides a tree based view for all nested
+ properties, i.e. properties that have subproperties can be in an
+ expanded (subproperties are visible) or collapsed (subproperties
+ are hidden) state. For example:
+
+ \image qttreepropertybrowser.png
+
+ Use the QtAbstractPropertyBrowser API to add, insert and remove
+ properties from an instance of the QtTreePropertyBrowser class.
+ The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class.
+
+ \sa QtGroupBoxPropertyBrowser, QtAbstractPropertyBrowser
+*/
+
+/*!
+ \fn void QtTreePropertyBrowser::collapsed(QtBrowserItem *item)
+
+ This signal is emitted when the \a item is collapsed.
+
+ \sa expanded(), setExpanded()
+*/
+
+/*!
+ \fn void QtTreePropertyBrowser::expanded(QtBrowserItem *item)
+
+ This signal is emitted when the \a item is expanded.
+
+ \sa collapsed(), setExpanded()
+*/
+
+/*!
+ Creates a property browser with the given \a parent.
+*/
+QtTreePropertyBrowser::QtTreePropertyBrowser(QWidget *parent)
+ : QtAbstractPropertyBrowser(parent), d_ptr(new QtTreePropertyBrowserPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->init(this);
+ connect(this, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentBrowserItemChanged(QtBrowserItem*)));
+}
+
+/*!
+ Destroys this property browser.
+
+ Note that the properties that were inserted into this browser are
+ \e not destroyed since they may still be used in other
+ browsers. The properties are owned by the manager that created
+ them.
+
+ \sa QtProperty, QtAbstractPropertyManager
+*/
+QtTreePropertyBrowser::~QtTreePropertyBrowser()
+{
+}
+
+/*!
+ \property QtTreePropertyBrowser::indentation
+ \brief indentation of the items in the tree view.
+*/
+int QtTreePropertyBrowser::indentation() const
+{
+ return d_ptr->m_treeWidget->indentation();
+}
+
+void QtTreePropertyBrowser::setIndentation(int i)
+{
+ d_ptr->m_treeWidget->setIndentation(i);
+}
+
+/*!
+ \property QtTreePropertyBrowser::rootIsDecorated
+ \brief whether to show controls for expanding and collapsing root items.
+*/
+bool QtTreePropertyBrowser::rootIsDecorated() const
+{
+ return d_ptr->m_treeWidget->rootIsDecorated();
+}
+
+void QtTreePropertyBrowser::setRootIsDecorated(bool show)
+{
+ d_ptr->m_treeWidget->setRootIsDecorated(show);
+ QMapIterator<QTreeWidgetItem *, QtBrowserItem *> it(d_ptr->m_itemToIndex);
+ while (it.hasNext()) {
+ QtProperty *property = it.next().value()->property();
+ if (!property->hasValue())
+ d_ptr->updateItem(it.key());
+ }
+}
+
+/*!
+ \property QtTreePropertyBrowser::alternatingRowColors
+ \brief whether to draw the background using alternating colors.
+ By default this property is set to true.
+*/
+bool QtTreePropertyBrowser::alternatingRowColors() const
+{
+ return d_ptr->m_treeWidget->alternatingRowColors();
+}
+
+void QtTreePropertyBrowser::setAlternatingRowColors(bool enable)
+{
+ d_ptr->m_treeWidget->setAlternatingRowColors(enable);
+ QMapIterator<QTreeWidgetItem *, QtBrowserItem *> it(d_ptr->m_itemToIndex);
+}
+
+/*!
+ \property QtTreePropertyBrowser::headerVisible
+ \brief whether to show the header.
+*/
+bool QtTreePropertyBrowser::isHeaderVisible() const
+{
+ return d_ptr->m_headerVisible;
+}
+
+void QtTreePropertyBrowser::setHeaderVisible(bool visible)
+{
+ if (d_ptr->m_headerVisible == visible)
+ return;
+
+ d_ptr->m_headerVisible = visible;
+ d_ptr->m_treeWidget->header()->setVisible(visible);
+}
+
+/*!
+ \enum QtTreePropertyBrowser::ResizeMode
+
+ The resize mode specifies the behavior of the header sections.
+
+ \value Interactive The user can resize the sections.
+ The sections can also be resized programmatically using setSplitterPosition().
+
+ \value Fixed The user cannot resize the section.
+ The section can only be resized programmatically using setSplitterPosition().
+
+ \value Stretch QHeaderView will automatically resize the section to fill the available space.
+ The size cannot be changed by the user or programmatically.
+
+ \value ResizeToContents QHeaderView will automatically resize the section to its optimal
+ size based on the contents of the entire column.
+ The size cannot be changed by the user or programmatically.
+
+ \sa setResizeMode()
+*/
+
+/*!
+ \property QtTreePropertyBrowser::resizeMode
+ \brief the resize mode of setions in the header.
+*/
+
+QtTreePropertyBrowser::ResizeMode QtTreePropertyBrowser::resizeMode() const
+{
+ return d_ptr->m_resizeMode;
+}
+
+void QtTreePropertyBrowser::setResizeMode(QtTreePropertyBrowser::ResizeMode mode)
+{
+ if (d_ptr->m_resizeMode == mode)
+ return;
+
+ d_ptr->m_resizeMode = mode;
+ QHeaderView::ResizeMode m = QHeaderView::Stretch;
+ switch (mode) {
+ case QtTreePropertyBrowser::Interactive: m = QHeaderView::Interactive; break;
+ case QtTreePropertyBrowser::Fixed: m = QHeaderView::Fixed; break;
+ case QtTreePropertyBrowser::ResizeToContents: m = QHeaderView::ResizeToContents; break;
+ case QtTreePropertyBrowser::Stretch:
+ default: m = QHeaderView::Stretch; break;
+ }
+ d_ptr->m_treeWidget->header()->setResizeMode(m);
+}
+
+/*!
+ \property QtTreePropertyBrowser::splitterPosition
+ \brief the position of the splitter between the colunms.
+*/
+
+int QtTreePropertyBrowser::splitterPosition() const
+{
+ return d_ptr->m_treeWidget->header()->sectionSize(0);
+}
+
+void QtTreePropertyBrowser::setSplitterPosition(int position)
+{
+ d_ptr->m_treeWidget->header()->resizeSection(0, position);
+}
+
+/*!
+ Sets the \a item to either collapse or expanded, depending on the value of \a expanded.
+
+ \sa isExpanded(), expanded(), collapsed()
+*/
+
+void QtTreePropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded)
+{
+ QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item);
+ if (treeItem)
+ treeItem->setExpanded(expanded);
+}
+
+/*!
+ Returns true if the \a item is expanded; otherwise returns false.
+
+ \sa setExpanded()
+*/
+
+bool QtTreePropertyBrowser::isExpanded(QtBrowserItem *item) const
+{
+ QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item);
+ if (treeItem)
+ return treeItem->isExpanded();
+ return false;
+}
+
+/*!
+ Returns true if the \a item is visible; otherwise returns false.
+
+ \sa setItemVisible()
+ \since 4.5
+*/
+
+bool QtTreePropertyBrowser::isItemVisible(QtBrowserItem *item) const
+{
+ if (const QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item))
+ return !treeItem->isHidden();
+ return false;
+}
+
+/*!
+ Sets the \a item to be visible, depending on the value of \a visible.
+
+ \sa isItemVisible()
+ \since 4.5
+*/
+
+void QtTreePropertyBrowser::setItemVisible(QtBrowserItem *item, bool visible)
+{
+ if (QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item))
+ treeItem->setHidden(!visible);
+}
+
+/*!
+ Sets the \a item's background color to \a color. Note that while item's background
+ is rendered every second row is being drawn with alternate color (which is a bit lighter than items \a color)
+
+ \sa backgroundColor(), calculatedBackgroundColor()
+*/
+
+void QtTreePropertyBrowser::setBackgroundColor(QtBrowserItem *item, const QColor &color)
+{
+ if (!d_ptr->m_indexToItem.contains(item))
+ return;
+ if (color.isValid())
+ d_ptr->m_indexToBackgroundColor[item] = color;
+ else
+ d_ptr->m_indexToBackgroundColor.remove(item);
+ d_ptr->m_treeWidget->viewport()->update();
+}
+
+/*!
+ Returns the \a item's color. If there is no color set for item it returns invalid color.
+
+ \sa calculatedBackgroundColor(), setBackgroundColor()
+*/
+
+QColor QtTreePropertyBrowser::backgroundColor(QtBrowserItem *item) const
+{
+ return d_ptr->m_indexToBackgroundColor.value(item);
+}
+
+/*!
+ Returns the \a item's color. If there is no color set for item it returns parent \a item's
+ color (if there is no color set for parent it returns grandparent's color and so on). In case
+ the color is not set for \a item and it's top level item it returns invalid color.
+
+ \sa backgroundColor(), setBackgroundColor()
+*/
+
+QColor QtTreePropertyBrowser::calculatedBackgroundColor(QtBrowserItem *item) const
+{
+ return d_ptr->calculatedBackgroundColor(item);
+}
+
+/*!
+ \property QtTreePropertyBrowser::propertiesWithoutValueMarked
+ \brief whether to enable or disable marking properties without value.
+
+ When marking is enabled the item's background is rendered in dark color and item's
+ foreground is rendered with light color.
+
+ \sa propertiesWithoutValueMarked()
+*/
+void QtTreePropertyBrowser::setPropertiesWithoutValueMarked(bool mark)
+{
+ if (d_ptr->m_markPropertiesWithoutValue == mark)
+ return;
+
+ d_ptr->m_markPropertiesWithoutValue = mark;
+ QMapIterator<QTreeWidgetItem *, QtBrowserItem *> it(d_ptr->m_itemToIndex);
+ while (it.hasNext()) {
+ QtProperty *property = it.next().value()->property();
+ if (!property->hasValue())
+ d_ptr->updateItem(it.key());
+ }
+ d_ptr->m_treeWidget->viewport()->update();
+}
+
+bool QtTreePropertyBrowser::propertiesWithoutValueMarked() const
+{
+ return d_ptr->m_markPropertiesWithoutValue;
+}
+
+/*!
+ \reimp
+*/
+void QtTreePropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem)
+{
+ d_ptr->propertyInserted(item, afterItem);
+}
+
+/*!
+ \reimp
+*/
+void QtTreePropertyBrowser::itemRemoved(QtBrowserItem *item)
+{
+ d_ptr->propertyRemoved(item);
+}
+
+/*!
+ \reimp
+*/
+void QtTreePropertyBrowser::itemChanged(QtBrowserItem *item)
+{
+ d_ptr->propertyChanged(item);
+}
+
+/*!
+ Sets the current item to \a item and opens the relevant editor for it.
+*/
+void QtTreePropertyBrowser::editItem(QtBrowserItem *item)
+{
+ d_ptr->editItem(item);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qttreepropertybrowser.cpp"
+#include "qttreepropertybrowser.moc"
diff --git a/src/shared/qtpropertybrowser/qttreepropertybrowser.h b/src/shared/qtpropertybrowser/qttreepropertybrowser.h
new file mode 100644
index 000000000..c0d8e4cb1
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qttreepropertybrowser.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTTREEPROPERTYBROWSER_H
+#define QTTREEPROPERTYBROWSER_H
+
+#include "qtpropertybrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTreeWidgetItem;
+class QtTreePropertyBrowserPrivate;
+
+class QtTreePropertyBrowser : public QtAbstractPropertyBrowser
+{
+ Q_OBJECT
+ Q_ENUMS(ResizeMode)
+ Q_PROPERTY(int indentation READ indentation WRITE setIndentation)
+ Q_PROPERTY(bool rootIsDecorated READ rootIsDecorated WRITE setRootIsDecorated)
+ Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors)
+ Q_PROPERTY(bool headerVisible READ isHeaderVisible WRITE setHeaderVisible)
+ Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode)
+ Q_PROPERTY(int splitterPosition READ splitterPosition WRITE setSplitterPosition)
+ Q_PROPERTY(bool propertiesWithoutValueMarked READ propertiesWithoutValueMarked WRITE setPropertiesWithoutValueMarked)
+public:
+
+ enum ResizeMode
+ {
+ Interactive,
+ Stretch,
+ Fixed,
+ ResizeToContents
+ };
+
+ QtTreePropertyBrowser(QWidget *parent = 0);
+ ~QtTreePropertyBrowser();
+
+ int indentation() const;
+ void setIndentation(int i);
+
+ bool rootIsDecorated() const;
+ void setRootIsDecorated(bool show);
+
+ bool alternatingRowColors() const;
+ void setAlternatingRowColors(bool enable);
+
+ bool isHeaderVisible() const;
+ void setHeaderVisible(bool visible);
+
+ ResizeMode resizeMode() const;
+ void setResizeMode(ResizeMode mode);
+
+ int splitterPosition() const;
+ void setSplitterPosition(int position);
+
+ void setExpanded(QtBrowserItem *item, bool expanded);
+ bool isExpanded(QtBrowserItem *item) const;
+
+ bool isItemVisible(QtBrowserItem *item) const;
+ void setItemVisible(QtBrowserItem *item, bool visible);
+
+ void setBackgroundColor(QtBrowserItem *item, const QColor &color);
+ QColor backgroundColor(QtBrowserItem *item) const;
+ QColor calculatedBackgroundColor(QtBrowserItem *item) const;
+
+ void setPropertiesWithoutValueMarked(bool mark);
+ bool propertiesWithoutValueMarked() const;
+
+ void editItem(QtBrowserItem *item);
+
+Q_SIGNALS:
+
+ void collapsed(QtBrowserItem *item);
+ void expanded(QtBrowserItem *item);
+
+protected:
+ virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem);
+ virtual void itemRemoved(QtBrowserItem *item);
+ virtual void itemChanged(QtBrowserItem *item);
+
+private:
+
+ QScopedPointer<QtTreePropertyBrowserPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtTreePropertyBrowser)
+ Q_DISABLE_COPY(QtTreePropertyBrowser)
+
+ Q_PRIVATE_SLOT(d_func(), void slotCollapsed(const QModelIndex &))
+ Q_PRIVATE_SLOT(d_func(), void slotExpanded(const QModelIndex &))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentBrowserItemChanged(QtBrowserItem *))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentTreeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qtvariantproperty.cpp b/src/shared/qtpropertybrowser/qtvariantproperty.cpp
new file mode 100644
index 000000000..9647b3ac7
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtvariantproperty.cpp
@@ -0,0 +1,2268 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtvariantproperty.h"
+#include "qtpropertymanager.h"
+#include "qteditorfactory.h"
+#include <QtCore/QVariant>
+#include <QtGui/QIcon>
+#include <QtCore/QDate>
+#include <QtCore/QLocale>
+
+#if defined(Q_CC_MSVC)
+# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QtEnumPropertyType
+{
+};
+
+
+class QtFlagPropertyType
+{
+};
+
+
+class QtGroupPropertyType
+{
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QtEnumPropertyType)
+Q_DECLARE_METATYPE(QtFlagPropertyType)
+Q_DECLARE_METATYPE(QtGroupPropertyType)
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Returns the type id for an enum property.
+
+ Note that the property's value type can be retrieved using the
+ valueType() function (which is QVariant::Int for the enum property
+ type).
+
+ \sa propertyType(), valueType()
+*/
+int QtVariantPropertyManager::enumTypeId()
+{
+ return qMetaTypeId<QtEnumPropertyType>();
+}
+
+/*!
+ Returns the type id for a flag property.
+
+ Note that the property's value type can be retrieved using the
+ valueType() function (which is QVariant::Int for the flag property
+ type).
+
+ \sa propertyType(), valueType()
+*/
+int QtVariantPropertyManager::flagTypeId()
+{
+ return qMetaTypeId<QtFlagPropertyType>();
+}
+
+/*!
+ Returns the type id for a group property.
+
+ Note that the property's value type can be retrieved using the
+ valueType() function (which is QVariant::Invalid for the group
+ property type, since it doesn't provide any value).
+
+ \sa propertyType(), valueType()
+*/
+int QtVariantPropertyManager::groupTypeId()
+{
+ return qMetaTypeId<QtGroupPropertyType>();
+}
+
+/*!
+ Returns the type id for a icon map attribute.
+
+ Note that the property's attribute type can be retrieved using the
+ attributeType() function.
+
+ \sa attributeType(), QtEnumPropertyManager::enumIcons()
+*/
+int QtVariantPropertyManager::iconMapTypeId()
+{
+ return qMetaTypeId<QtIconMap>();
+}
+
+typedef QMap<const QtProperty *, QtProperty *> PropertyMap;
+Q_GLOBAL_STATIC(PropertyMap, propertyToWrappedProperty)
+
+static QtProperty *wrappedProperty(QtProperty *property)
+{
+ return propertyToWrappedProperty()->value(property, 0);
+}
+
+class QtVariantPropertyPrivate
+{
+ QtVariantProperty *q_ptr;
+public:
+ QtVariantPropertyPrivate(QtVariantPropertyManager *m) : manager(m) {}
+
+ QtVariantPropertyManager *manager;
+};
+
+/*!
+ \class QtVariantProperty
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtVariantProperty class is a convenience class handling
+ QVariant based properties.
+
+ QtVariantProperty provides additional API: A property's type,
+ value type, attribute values and current value can easily be
+ retrieved using the propertyType(), valueType(), attributeValue()
+ and value() functions respectively. In addition, the attribute
+ values and the current value can be set using the corresponding
+ setValue() and setAttribute() functions.
+
+ For example, instead of writing:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp 0
+
+ you can write:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp 1
+
+ QtVariantProperty instances can only be created by the
+ QtVariantPropertyManager class.
+
+ \sa QtProperty, QtVariantPropertyManager, QtVariantEditorFactory
+*/
+
+/*!
+ Creates a variant property using the given \a manager.
+
+ Do not use this constructor to create variant property instances;
+ use the QtVariantPropertyManager::addProperty() function
+ instead. This constructor is used internally by the
+ QtVariantPropertyManager::createProperty() function.
+
+ \sa QtVariantPropertyManager
+*/
+QtVariantProperty::QtVariantProperty(QtVariantPropertyManager *manager)
+ : QtProperty(manager), d_ptr(new QtVariantPropertyPrivate(manager))
+{
+}
+
+/*!
+ Destroys this property.
+
+ \sa QtProperty::~QtProperty()
+*/
+QtVariantProperty::~QtVariantProperty()
+{
+}
+
+/*!
+ Returns the property's current value.
+
+ \sa valueType(), setValue()
+*/
+QVariant QtVariantProperty::value() const
+{
+ return d_ptr->manager->value(this);
+}
+
+/*!
+ Returns this property's value for the specified \a attribute.
+
+ QtVariantPropertyManager provides a couple of related functions:
+ \l{QtVariantPropertyManager::attributes()}{attributes()} and
+ \l{QtVariantPropertyManager::attributeType()}{attributeType()}.
+
+ \sa setAttribute()
+*/
+QVariant QtVariantProperty::attributeValue(const QString &attribute) const
+{
+ return d_ptr->manager->attributeValue(this, attribute);
+}
+
+/*!
+ Returns the type of this property's value.
+
+ \sa propertyType()
+*/
+int QtVariantProperty::valueType() const
+{
+ return d_ptr->manager->valueType(this);
+}
+
+/*!
+ Returns this property's type.
+
+ QtVariantPropertyManager provides several related functions:
+ \l{QtVariantPropertyManager::enumTypeId()}{enumTypeId()},
+ \l{QtVariantPropertyManager::flagTypeId()}{flagTypeId()} and
+ \l{QtVariantPropertyManager::groupTypeId()}{groupTypeId()}.
+
+ \sa valueType()
+*/
+int QtVariantProperty::propertyType() const
+{
+ return d_ptr->manager->propertyType(this);
+}
+
+/*!
+ Sets the value of this property to \a value.
+
+ The specified \a value must be of the type returned by
+ valueType(), or of a type that can be converted to valueType()
+ using the QVariant::canConvert() function; otherwise this function
+ does nothing.
+
+ \sa value()
+*/
+void QtVariantProperty::setValue(const QVariant &value)
+{
+ d_ptr->manager->setValue(this, value);
+}
+
+/*!
+ Sets the \a attribute of property to \a value.
+
+ QtVariantPropertyManager provides the related
+ \l{QtVariantPropertyManager::setAttribute()}{setAttribute()}
+ function.
+
+ \sa attributeValue()
+*/
+void QtVariantProperty::setAttribute(const QString &attribute, const QVariant &value)
+{
+ d_ptr->manager->setAttribute(this, attribute, value);
+}
+
+class QtVariantPropertyManagerPrivate
+{
+ QtVariantPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtVariantPropertyManager)
+public:
+ QtVariantPropertyManagerPrivate();
+
+ bool m_creatingProperty;
+ bool m_creatingSubProperties;
+ bool m_destroyingSubProperties;
+ int m_propertyType;
+
+ void slotValueChanged(QtProperty *property, int val);
+ void slotRangeChanged(QtProperty *property, int min, int max);
+ void slotSingleStepChanged(QtProperty *property, int step);
+ void slotValueChanged(QtProperty *property, double val);
+ void slotRangeChanged(QtProperty *property, double min, double max);
+ void slotSingleStepChanged(QtProperty *property, double step);
+ void slotDecimalsChanged(QtProperty *property, int prec);
+ void slotValueChanged(QtProperty *property, bool val);
+ void slotValueChanged(QtProperty *property, const QString &val);
+ void slotRegExpChanged(QtProperty *property, const QRegExp &regExp);
+ void slotValueChanged(QtProperty *property, const QDate &val);
+ void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max);
+ void slotValueChanged(QtProperty *property, const QTime &val);
+ void slotValueChanged(QtProperty *property, const QDateTime &val);
+ void slotValueChanged(QtProperty *property, const QKeySequence &val);
+ void slotValueChanged(QtProperty *property, const QChar &val);
+ void slotValueChanged(QtProperty *property, const QLocale &val);
+ void slotValueChanged(QtProperty *property, const QPoint &val);
+ void slotValueChanged(QtProperty *property, const QPointF &val);
+ void slotValueChanged(QtProperty *property, const QSize &val);
+ void slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max);
+ void slotValueChanged(QtProperty *property, const QSizeF &val);
+ void slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max);
+ void slotValueChanged(QtProperty *property, const QRect &val);
+ void slotConstraintChanged(QtProperty *property, const QRect &val);
+ void slotValueChanged(QtProperty *property, const QRectF &val);
+ void slotConstraintChanged(QtProperty *property, const QRectF &val);
+ void slotValueChanged(QtProperty *property, const QColor &val);
+ void slotEnumChanged(QtProperty *property, int val);
+ void slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames);
+ void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &enumIcons);
+ void slotValueChanged(QtProperty *property, const QSizePolicy &val);
+ void slotValueChanged(QtProperty *property, const QFont &val);
+ void slotValueChanged(QtProperty *property, const QCursor &val);
+ void slotFlagChanged(QtProperty *property, int val);
+ void slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames);
+ void slotPropertyInserted(QtProperty *property, QtProperty *parent, QtProperty *after);
+ void slotPropertyRemoved(QtProperty *property, QtProperty *parent);
+
+ void valueChanged(QtProperty *property, const QVariant &val);
+
+ int internalPropertyToType(QtProperty *property) const;
+ QtVariantProperty *createSubProperty(QtVariantProperty *parent, QtVariantProperty *after,
+ QtProperty *internal);
+ void removeSubProperty(QtVariantProperty *property);
+
+ QMap<int, QtAbstractPropertyManager *> m_typeToPropertyManager;
+ QMap<int, QMap<QString, int> > m_typeToAttributeToAttributeType;
+
+ QMap<const QtProperty *, QPair<QtVariantProperty *, int> > m_propertyToType;
+
+ QMap<int, int> m_typeToValueType;
+
+
+ QMap<QtProperty *, QtVariantProperty *> m_internalToProperty;
+
+ const QString m_constraintAttribute;
+ const QString m_singleStepAttribute;
+ const QString m_decimalsAttribute;
+ const QString m_enumIconsAttribute;
+ const QString m_enumNamesAttribute;
+ const QString m_flagNamesAttribute;
+ const QString m_maximumAttribute;
+ const QString m_minimumAttribute;
+ const QString m_regExpAttribute;
+};
+
+QtVariantPropertyManagerPrivate::QtVariantPropertyManagerPrivate() :
+ m_constraintAttribute(QLatin1String("constraint")),
+ m_singleStepAttribute(QLatin1String("singleStep")),
+ m_decimalsAttribute(QLatin1String("decimals")),
+ m_enumIconsAttribute(QLatin1String("enumIcons")),
+ m_enumNamesAttribute(QLatin1String("enumNames")),
+ m_flagNamesAttribute(QLatin1String("flagNames")),
+ m_maximumAttribute(QLatin1String("maximum")),
+ m_minimumAttribute(QLatin1String("minimum")),
+ m_regExpAttribute(QLatin1String("regExp"))
+{
+}
+
+int QtVariantPropertyManagerPrivate::internalPropertyToType(QtProperty *property) const
+{
+ int type = 0;
+ QtAbstractPropertyManager *internPropertyManager = property->propertyManager();
+ if (qobject_cast<QtIntPropertyManager *>(internPropertyManager))
+ type = QVariant::Int;
+ else if (qobject_cast<QtEnumPropertyManager *>(internPropertyManager))
+ type = QtVariantPropertyManager::enumTypeId();
+ else if (qobject_cast<QtBoolPropertyManager *>(internPropertyManager))
+ type = QVariant::Bool;
+ else if (qobject_cast<QtDoublePropertyManager *>(internPropertyManager))
+ type = QVariant::Double;
+ return type;
+}
+
+QtVariantProperty *QtVariantPropertyManagerPrivate::createSubProperty(QtVariantProperty *parent,
+ QtVariantProperty *after, QtProperty *internal)
+{
+ int type = internalPropertyToType(internal);
+ if (!type)
+ return 0;
+
+ bool wasCreatingSubProperties = m_creatingSubProperties;
+ m_creatingSubProperties = true;
+
+ QtVariantProperty *varChild = q_ptr->addProperty(type, internal->propertyName());
+
+ m_creatingSubProperties = wasCreatingSubProperties;
+
+ varChild->setPropertyName(internal->propertyName());
+ varChild->setToolTip(internal->toolTip());
+ varChild->setStatusTip(internal->statusTip());
+ varChild->setWhatsThis(internal->whatsThis());
+
+ parent->insertSubProperty(varChild, after);
+
+ m_internalToProperty[internal] = varChild;
+ propertyToWrappedProperty()->insert(varChild, internal);
+ return varChild;
+}
+
+void QtVariantPropertyManagerPrivate::removeSubProperty(QtVariantProperty *property)
+{
+ QtProperty *internChild = wrappedProperty(property);
+ bool wasDestroyingSubProperties = m_destroyingSubProperties;
+ m_destroyingSubProperties = true;
+ delete property;
+ m_destroyingSubProperties = wasDestroyingSubProperties;
+ m_internalToProperty.remove(internChild);
+ propertyToWrappedProperty()->remove(property);
+}
+
+void QtVariantPropertyManagerPrivate::slotPropertyInserted(QtProperty *property,
+ QtProperty *parent, QtProperty *after)
+{
+ if (m_creatingProperty)
+ return;
+
+ QtVariantProperty *varParent = m_internalToProperty.value(parent, 0);
+ if (!varParent)
+ return;
+
+ QtVariantProperty *varAfter = 0;
+ if (after) {
+ varAfter = m_internalToProperty.value(after, 0);
+ if (!varAfter)
+ return;
+ }
+
+ createSubProperty(varParent, varAfter, property);
+}
+
+void QtVariantPropertyManagerPrivate::slotPropertyRemoved(QtProperty *property, QtProperty *parent)
+{
+ Q_UNUSED(parent)
+
+ QtVariantProperty *varProperty = m_internalToProperty.value(property, 0);
+ if (!varProperty)
+ return;
+
+ removeSubProperty(varProperty);
+}
+
+void QtVariantPropertyManagerPrivate::valueChanged(QtProperty *property, const QVariant &val)
+{
+ QtVariantProperty *varProp = m_internalToProperty.value(property, 0);
+ if (!varProp)
+ return;
+ emit q_ptr->valueChanged(varProp, val);
+ emit q_ptr->propertyChanged(varProp);
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, int val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, int min, int max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, int step)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, double val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, double min, double max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, double step)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step));
+}
+
+void QtVariantPropertyManagerPrivate::slotDecimalsChanged(QtProperty *property, int prec)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_decimalsAttribute, QVariant(prec));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, bool val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QString &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRegExpChanged(QtProperty *property, const QRegExp &regExp)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_regExpAttribute, QVariant(regExp));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDate &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QTime &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDateTime &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QKeySequence &val)
+{
+ QVariant v;
+ v.setValue(val);
+ valueChanged(property, v);
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QChar &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QLocale &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPoint &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPointF &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSize &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizeF &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRect &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRect &constraint)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRectF &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRectF &constraint)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QColor &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_enumNamesAttribute, QVariant(enumNames));
+}
+
+void QtVariantPropertyManagerPrivate::slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &enumIcons)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ QVariant v;
+ v.setValue(enumIcons);
+ emit q_ptr->attributeChanged(varProp, m_enumIconsAttribute, v);
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizePolicy &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QFont &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QCursor &val)
+{
+#ifndef QT_NO_CURSOR
+ valueChanged(property, QVariant(val));
+#endif
+}
+
+void QtVariantPropertyManagerPrivate::slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_flagNamesAttribute, QVariant(flagNames));
+}
+
+/*!
+ \class QtVariantPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtVariantPropertyManager class provides and manages QVariant based properties.
+
+ QtVariantPropertyManager provides the addProperty() function which
+ creates QtVariantProperty objects. The QtVariantProperty class is
+ a convenience class handling QVariant based properties inheriting
+ QtProperty. A QtProperty object created by a
+ QtVariantPropertyManager instance can be converted into a
+ QtVariantProperty object using the variantProperty() function.
+
+ The property's value can be retrieved using the value(), and set
+ using the setValue() slot. In addition the property's type, and
+ the type of its value, can be retrieved using the propertyType()
+ and valueType() functions respectively.
+
+ A property's type is a QVariant::Type enumerator value, and
+ usually a property's type is the same as its value type. But for
+ some properties the types differ, for example for enums, flags and
+ group types in which case QtVariantPropertyManager provides the
+ enumTypeId(), flagTypeId() and groupTypeId() functions,
+ respectively, to identify their property type (the value types are
+ QVariant::Int for the enum and flag types, and QVariant::Invalid
+ for the group type).
+
+ Use the isPropertyTypeSupported() function to check if a particular
+ property type is supported. The currently supported property types
+ are:
+
+ \table
+ \header
+ \o Property Type
+ \o Property Type Id
+ \row
+ \o int
+ \o QVariant::Int
+ \row
+ \o double
+ \o QVariant::Double
+ \row
+ \o bool
+ \o QVariant::Bool
+ \row
+ \o QString
+ \o QVariant::String
+ \row
+ \o QDate
+ \o QVariant::Date
+ \row
+ \o QTime
+ \o QVariant::Time
+ \row
+ \o QDateTime
+ \o QVariant::DateTime
+ \row
+ \o QKeySequence
+ \o QVariant::KeySequence
+ \row
+ \o QChar
+ \o QVariant::Char
+ \row
+ \o QLocale
+ \o QVariant::Locale
+ \row
+ \o QPoint
+ \o QVariant::Point
+ \row
+ \o QPointF
+ \o QVariant::PointF
+ \row
+ \o QSize
+ \o QVariant::Size
+ \row
+ \o QSizeF
+ \o QVariant::SizeF
+ \row
+ \o QRect
+ \o QVariant::Rect
+ \row
+ \o QRectF
+ \o QVariant::RectF
+ \row
+ \o QColor
+ \o QVariant::Color
+ \row
+ \o QSizePolicy
+ \o QVariant::SizePolicy
+ \row
+ \o QFont
+ \o QVariant::Font
+ \row
+ \o QCursor
+ \o QVariant::Cursor
+ \row
+ \o enum
+ \o enumTypeId()
+ \row
+ \o flag
+ \o flagTypeId()
+ \row
+ \o group
+ \o groupTypeId()
+ \endtable
+
+ Each property type can provide additional attributes,
+ e.g. QVariant::Int and QVariant::Double provides minimum and
+ maximum values. The currently supported attributes are:
+
+ \table
+ \header
+ \o Property Type
+ \o Attribute Name
+ \o Attribute Type
+ \row
+ \o \c int
+ \o minimum
+ \o QVariant::Int
+ \row
+ \o
+ \o maximum
+ \o QVariant::Int
+ \row
+ \o
+ \o singleStep
+ \o QVariant::Int
+ \row
+ \o \c double
+ \o minimum
+ \o QVariant::Double
+ \row
+ \o
+ \o maximum
+ \o QVariant::Double
+ \row
+ \o
+ \o singleStep
+ \o QVariant::Double
+ \row
+ \o
+ \o decimals
+ \o QVariant::Int
+ \row
+ \o QString
+ \o regExp
+ \o QVariant::RegExp
+ \row
+ \o QDate
+ \o minimum
+ \o QVariant::Date
+ \row
+ \o
+ \o maximum
+ \o QVariant::Date
+ \row
+ \o QPointF
+ \o decimals
+ \o QVariant::Int
+ \row
+ \o QSize
+ \o minimum
+ \o QVariant::Size
+ \row
+ \o
+ \o maximum
+ \o QVariant::Size
+ \row
+ \o QSizeF
+ \o minimum
+ \o QVariant::SizeF
+ \row
+ \o
+ \o maximum
+ \o QVariant::SizeF
+ \row
+ \o
+ \o decimals
+ \o QVariant::Int
+ \row
+ \o QRect
+ \o constraint
+ \o QVariant::Rect
+ \row
+ \o QRectF
+ \o constraint
+ \o QVariant::RectF
+ \row
+ \o
+ \o decimals
+ \o QVariant::Int
+ \row
+ \o \c enum
+ \o enumNames
+ \o QVariant::StringList
+ \row
+ \o
+ \o enumIcons
+ \o iconMapTypeId()
+ \row
+ \o \c flag
+ \o flagNames
+ \o QVariant::StringList
+ \endtable
+
+ The attributes for a given property type can be retrieved using
+ the attributes() function. Each attribute has a value type which
+ can be retrieved using the attributeType() function, and a value
+ accessible through the attributeValue() function. In addition, the
+ value can be set using the setAttribute() slot.
+
+ QtVariantManager also provides the valueChanged() signal which is
+ emitted whenever a property created by this manager change, and
+ the attributeChanged() signal which is emitted whenever an
+ attribute of such a property changes.
+
+ \sa QtVariantProperty, QtVariantEditorFactory
+*/
+
+/*!
+ \fn void QtVariantPropertyManager::valueChanged(QtProperty *property, const QVariant &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtVariantPropertyManager::attributeChanged(QtProperty *property,
+ const QString &attribute, const QVariant &value)
+
+ This signal is emitted whenever an attribute of a property created
+ by this manager changes its value, passing a pointer to the \a
+ property, the \a attribute and the new \a value as parameters.
+
+ \sa setAttribute()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtVariantPropertyManager::QtVariantPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtVariantPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_creatingProperty = false;
+ d_ptr->m_creatingSubProperties = false;
+ d_ptr->m_destroyingSubProperties = false;
+ d_ptr->m_propertyType = 0;
+
+ // IntPropertyManager
+ QtIntPropertyManager *intPropertyManager = new QtIntPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Int] = intPropertyManager;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_minimumAttribute] = QVariant::Int;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_maximumAttribute] = QVariant::Int;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_singleStepAttribute] = QVariant::Int;
+ d_ptr->m_typeToValueType[QVariant::Int] = QVariant::Int;
+ connect(intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(intPropertyManager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(intPropertyManager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+ // DoublePropertyManager
+ QtDoublePropertyManager *doublePropertyManager = new QtDoublePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Double] = doublePropertyManager;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_minimumAttribute] =
+ QVariant::Double;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_maximumAttribute] =
+ QVariant::Double;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_singleStepAttribute] =
+ QVariant::Double;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_decimalsAttribute] =
+ QVariant::Int;
+ d_ptr->m_typeToValueType[QVariant::Double] = QVariant::Double;
+ connect(doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotValueChanged(QtProperty*,double)));
+ connect(doublePropertyManager, SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ connect(doublePropertyManager, SIGNAL(singleStepChanged(QtProperty*,double)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,double)));
+ connect(doublePropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+ // BoolPropertyManager
+ QtBoolPropertyManager *boolPropertyManager = new QtBoolPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Bool] = boolPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Bool] = QVariant::Bool;
+ connect(boolPropertyManager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotValueChanged(QtProperty*,bool)));
+ // StringPropertyManager
+ QtStringPropertyManager *stringPropertyManager = new QtStringPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::String] = stringPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::String] = QVariant::String;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_regExpAttribute] =
+ QVariant::RegExp;
+ connect(stringPropertyManager, SIGNAL(valueChanged(QtProperty*,QString)),
+ this, SLOT(slotValueChanged(QtProperty*,QString)));
+ connect(stringPropertyManager, SIGNAL(regExpChanged(QtProperty*,QRegExp)),
+ this, SLOT(slotRegExpChanged(QtProperty*,QRegExp)));
+ // DatePropertyManager
+ QtDatePropertyManager *datePropertyManager = new QtDatePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Date] = datePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Date] = QVariant::Date;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Date][d_ptr->m_minimumAttribute] =
+ QVariant::Date;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Date][d_ptr->m_maximumAttribute] =
+ QVariant::Date;
+ connect(datePropertyManager, SIGNAL(valueChanged(QtProperty*,QDate)),
+ this, SLOT(slotValueChanged(QtProperty*,QDate)));
+ connect(datePropertyManager, SIGNAL(rangeChanged(QtProperty*,QDate,QDate)),
+ this, SLOT(slotRangeChanged(QtProperty*,QDate,QDate)));
+ // TimePropertyManager
+ QtTimePropertyManager *timePropertyManager = new QtTimePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Time] = timePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Time] = QVariant::Time;
+ connect(timePropertyManager, SIGNAL(valueChanged(QtProperty*,QTime)),
+ this, SLOT(slotValueChanged(QtProperty*,QTime)));
+ // DateTimePropertyManager
+ QtDateTimePropertyManager *dateTimePropertyManager = new QtDateTimePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::DateTime] = dateTimePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::DateTime] = QVariant::DateTime;
+ connect(dateTimePropertyManager, SIGNAL(valueChanged(QtProperty*,QDateTime)),
+ this, SLOT(slotValueChanged(QtProperty*,QDateTime)));
+ // KeySequencePropertyManager
+ QtKeySequencePropertyManager *keySequencePropertyManager = new QtKeySequencePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::KeySequence] = keySequencePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::KeySequence] = QVariant::KeySequence;
+ connect(keySequencePropertyManager, SIGNAL(valueChanged(QtProperty*,QKeySequence)),
+ this, SLOT(slotValueChanged(QtProperty*,QKeySequence)));
+ // CharPropertyManager
+ QtCharPropertyManager *charPropertyManager = new QtCharPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Char] = charPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Char] = QVariant::Char;
+ connect(charPropertyManager, SIGNAL(valueChanged(QtProperty*,QChar)),
+ this, SLOT(slotValueChanged(QtProperty*,QChar)));
+ // LocalePropertyManager
+ QtLocalePropertyManager *localePropertyManager = new QtLocalePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Locale] = localePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Locale] = QVariant::Locale;
+ connect(localePropertyManager, SIGNAL(valueChanged(QtProperty*,QLocale)),
+ this, SLOT(slotValueChanged(QtProperty*,QLocale)));
+ connect(localePropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(localePropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(localePropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // PointPropertyManager
+ QtPointPropertyManager *pointPropertyManager = new QtPointPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Point] = pointPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Point] = QVariant::Point;
+ connect(pointPropertyManager, SIGNAL(valueChanged(QtProperty*,QPoint)),
+ this, SLOT(slotValueChanged(QtProperty*,QPoint)));
+ connect(pointPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(pointPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(pointPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // PointFPropertyManager
+ QtPointFPropertyManager *pointFPropertyManager = new QtPointFPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::PointF] = pointFPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::PointF] = QVariant::PointF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::PointF][d_ptr->m_decimalsAttribute] =
+ QVariant::Int;
+ connect(pointFPropertyManager, SIGNAL(valueChanged(QtProperty*,QPointF)),
+ this, SLOT(slotValueChanged(QtProperty*,QPointF)));
+ connect(pointFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+ connect(pointFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotValueChanged(QtProperty*,double)));
+ connect(pointFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(pointFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // SizePropertyManager
+ QtSizePropertyManager *sizePropertyManager = new QtSizePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Size] = sizePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Size] = QVariant::Size;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Size][d_ptr->m_minimumAttribute] =
+ QVariant::Size;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Size][d_ptr->m_maximumAttribute] =
+ QVariant::Size;
+ connect(sizePropertyManager, SIGNAL(valueChanged(QtProperty*,QSize)),
+ this, SLOT(slotValueChanged(QtProperty*,QSize)));
+ connect(sizePropertyManager, SIGNAL(rangeChanged(QtProperty*,QSize,QSize)),
+ this, SLOT(slotRangeChanged(QtProperty*,QSize,QSize)));
+ connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(sizePropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(sizePropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // SizeFPropertyManager
+ QtSizeFPropertyManager *sizeFPropertyManager = new QtSizeFPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::SizeF] = sizeFPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::SizeF] = QVariant::SizeF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_minimumAttribute] =
+ QVariant::SizeF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_maximumAttribute] =
+ QVariant::SizeF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_decimalsAttribute] =
+ QVariant::Int;
+ connect(sizeFPropertyManager, SIGNAL(valueChanged(QtProperty*,QSizeF)),
+ this, SLOT(slotValueChanged(QtProperty*,QSizeF)));
+ connect(sizeFPropertyManager, SIGNAL(rangeChanged(QtProperty*,QSizeF,QSizeF)),
+ this, SLOT(slotRangeChanged(QtProperty*,QSizeF,QSizeF)));
+ connect(sizeFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+ connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotValueChanged(QtProperty*,double)));
+ connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ connect(sizeFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(sizeFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // RectPropertyManager
+ QtRectPropertyManager *rectPropertyManager = new QtRectPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Rect] = rectPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Rect] = QVariant::Rect;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Rect][d_ptr->m_constraintAttribute] =
+ QVariant::Rect;
+ connect(rectPropertyManager, SIGNAL(valueChanged(QtProperty*,QRect)),
+ this, SLOT(slotValueChanged(QtProperty*,QRect)));
+ connect(rectPropertyManager, SIGNAL(constraintChanged(QtProperty*,QRect)),
+ this, SLOT(slotConstraintChanged(QtProperty*,QRect)));
+ connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(rectPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(rectPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // RectFPropertyManager
+ QtRectFPropertyManager *rectFPropertyManager = new QtRectFPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::RectF] = rectFPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::RectF] = QVariant::RectF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::RectF][d_ptr->m_constraintAttribute] =
+ QVariant::RectF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::RectF][d_ptr->m_decimalsAttribute] =
+ QVariant::Int;
+ connect(rectFPropertyManager, SIGNAL(valueChanged(QtProperty*,QRectF)),
+ this, SLOT(slotValueChanged(QtProperty*,QRectF)));
+ connect(rectFPropertyManager, SIGNAL(constraintChanged(QtProperty*,QRectF)),
+ this, SLOT(slotConstraintChanged(QtProperty*,QRectF)));
+ connect(rectFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+ connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotValueChanged(QtProperty*,double)));
+ connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ connect(rectFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(rectFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // ColorPropertyManager
+ QtColorPropertyManager *colorPropertyManager = new QtColorPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Color] = colorPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Color] = QVariant::Color;
+ connect(colorPropertyManager, SIGNAL(valueChanged(QtProperty*,QColor)),
+ this, SLOT(slotValueChanged(QtProperty*,QColor)));
+ connect(colorPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(colorPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(colorPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // EnumPropertyManager
+ int enumId = enumTypeId();
+ QtEnumPropertyManager *enumPropertyManager = new QtEnumPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[enumId] = enumPropertyManager;
+ d_ptr->m_typeToValueType[enumId] = QVariant::Int;
+ d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumNamesAttribute] =
+ QVariant::StringList;
+ d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumIconsAttribute] =
+ iconMapTypeId();
+ connect(enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(enumPropertyManager, SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+ connect(enumPropertyManager, SIGNAL(enumIconsChanged(QtProperty*,QMap<int,QIcon>)),
+ this, SLOT(slotEnumIconsChanged(QtProperty*,QMap<int,QIcon>)));
+ // SizePolicyPropertyManager
+ QtSizePolicyPropertyManager *sizePolicyPropertyManager = new QtSizePolicyPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::SizePolicy] = sizePolicyPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::SizePolicy] = QVariant::SizePolicy;
+ connect(sizePolicyPropertyManager, SIGNAL(valueChanged(QtProperty*,QSizePolicy)),
+ this, SLOT(slotValueChanged(QtProperty*,QSizePolicy)));
+ connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(sizePolicyPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(sizePolicyPropertyManager->subEnumPropertyManager(),
+ SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+ connect(sizePolicyPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(sizePolicyPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // FontPropertyManager
+ QtFontPropertyManager *fontPropertyManager = new QtFontPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Font] = fontPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Font] = QVariant::Font;
+ connect(fontPropertyManager, SIGNAL(valueChanged(QtProperty*,QFont)),
+ this, SLOT(slotValueChanged(QtProperty*,QFont)));
+ connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(fontPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(fontPropertyManager->subEnumPropertyManager(),
+ SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+ connect(fontPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotValueChanged(QtProperty*,bool)));
+ connect(fontPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(fontPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // CursorPropertyManager
+ QtCursorPropertyManager *cursorPropertyManager = new QtCursorPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Cursor] = cursorPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Cursor] = QVariant::Cursor;
+ connect(cursorPropertyManager, SIGNAL(valueChanged(QtProperty*,QCursor)),
+ this, SLOT(slotValueChanged(QtProperty*,QCursor)));
+ // FlagPropertyManager
+ int flagId = flagTypeId();
+ QtFlagPropertyManager *flagPropertyManager = new QtFlagPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[flagId] = flagPropertyManager;
+ d_ptr->m_typeToValueType[flagId] = QVariant::Int;
+ d_ptr->m_typeToAttributeToAttributeType[flagId][d_ptr->m_flagNamesAttribute] =
+ QVariant::StringList;
+ connect(flagPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(flagPropertyManager, SIGNAL(flagNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotFlagNamesChanged(QtProperty*,QStringList)));
+ connect(flagPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotValueChanged(QtProperty*,bool)));
+ connect(flagPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(flagPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // FlagPropertyManager
+ int groupId = groupTypeId();
+ QtGroupPropertyManager *groupPropertyManager = new QtGroupPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[groupId] = groupPropertyManager;
+ d_ptr->m_typeToValueType[groupId] = QVariant::Invalid;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtVariantPropertyManager::~QtVariantPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property converted into a QtVariantProperty.
+
+ If the \a property was not created by this variant manager, the
+ function returns 0.
+
+ \sa createProperty()
+*/
+QtVariantProperty *QtVariantPropertyManager::variantProperty(const QtProperty *property) const
+{
+ const QMap<const QtProperty *, QPair<QtVariantProperty *, int> >::const_iterator it = d_ptr->m_propertyToType.constFind(property);
+ if (it == d_ptr->m_propertyToType.constEnd())
+ return 0;
+ return it.value().first;
+}
+
+/*!
+ Returns true if the given \a propertyType is supported by this
+ variant manager; otherwise false.
+
+ \sa propertyType()
+*/
+bool QtVariantPropertyManager::isPropertyTypeSupported(int propertyType) const
+{
+ if (d_ptr->m_typeToValueType.contains(propertyType))
+ return true;
+ return false;
+}
+
+/*!
+ Creates and returns a variant property of the given \a propertyType
+ with the given \a name.
+
+ If the specified \a propertyType is not supported by this variant
+ manager, this function returns 0.
+
+ Do not use the inherited
+ QtAbstractPropertyManager::addProperty() function to create a
+ variant property (that function will always return 0 since it will
+ not be clear what type the property should have).
+
+ \sa isPropertyTypeSupported()
+*/
+QtVariantProperty *QtVariantPropertyManager::addProperty(int propertyType, const QString &name)
+{
+ if (!isPropertyTypeSupported(propertyType))
+ return 0;
+
+ bool wasCreating = d_ptr->m_creatingProperty;
+ d_ptr->m_creatingProperty = true;
+ d_ptr->m_propertyType = propertyType;
+ QtProperty *property = QtAbstractPropertyManager::addProperty(name);
+ d_ptr->m_creatingProperty = wasCreating;
+ d_ptr->m_propertyType = 0;
+
+ if (!property)
+ return 0;
+
+ return variantProperty(property);
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid variant.
+
+ \sa setValue()
+*/
+QVariant QtVariantPropertyManager::value(const QtProperty *property) const
+{
+ QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ if (internProp == 0)
+ return QVariant();
+
+ QtAbstractPropertyManager *manager = internProp->propertyManager();
+ if (QtIntPropertyManager *intManager = qobject_cast<QtIntPropertyManager *>(manager)) {
+ return intManager->value(internProp);
+ } else if (QtDoublePropertyManager *doubleManager = qobject_cast<QtDoublePropertyManager *>(manager)) {
+ return doubleManager->value(internProp);
+ } else if (QtBoolPropertyManager *boolManager = qobject_cast<QtBoolPropertyManager *>(manager)) {
+ return boolManager->value(internProp);
+ } else if (QtStringPropertyManager *stringManager = qobject_cast<QtStringPropertyManager *>(manager)) {
+ return stringManager->value(internProp);
+ } else if (QtDatePropertyManager *dateManager = qobject_cast<QtDatePropertyManager *>(manager)) {
+ return dateManager->value(internProp);
+ } else if (QtTimePropertyManager *timeManager = qobject_cast<QtTimePropertyManager *>(manager)) {
+ return timeManager->value(internProp);
+ } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast<QtDateTimePropertyManager *>(manager)) {
+ return dateTimeManager->value(internProp);
+ } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast<QtKeySequencePropertyManager *>(manager)) {
+ return keySequenceManager->value(internProp);
+ } else if (QtCharPropertyManager *charManager = qobject_cast<QtCharPropertyManager *>(manager)) {
+ return charManager->value(internProp);
+ } else if (QtLocalePropertyManager *localeManager = qobject_cast<QtLocalePropertyManager *>(manager)) {
+ return localeManager->value(internProp);
+ } else if (QtPointPropertyManager *pointManager = qobject_cast<QtPointPropertyManager *>(manager)) {
+ return pointManager->value(internProp);
+ } else if (QtPointFPropertyManager *pointFManager = qobject_cast<QtPointFPropertyManager *>(manager)) {
+ return pointFManager->value(internProp);
+ } else if (QtSizePropertyManager *sizeManager = qobject_cast<QtSizePropertyManager *>(manager)) {
+ return sizeManager->value(internProp);
+ } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast<QtSizeFPropertyManager *>(manager)) {
+ return sizeFManager->value(internProp);
+ } else if (QtRectPropertyManager *rectManager = qobject_cast<QtRectPropertyManager *>(manager)) {
+ return rectManager->value(internProp);
+ } else if (QtRectFPropertyManager *rectFManager = qobject_cast<QtRectFPropertyManager *>(manager)) {
+ return rectFManager->value(internProp);
+ } else if (QtColorPropertyManager *colorManager = qobject_cast<QtColorPropertyManager *>(manager)) {
+ return colorManager->value(internProp);
+ } else if (QtEnumPropertyManager *enumManager = qobject_cast<QtEnumPropertyManager *>(manager)) {
+ return enumManager->value(internProp);
+ } else if (QtSizePolicyPropertyManager *sizePolicyManager =
+ qobject_cast<QtSizePolicyPropertyManager *>(manager)) {
+ return sizePolicyManager->value(internProp);
+ } else if (QtFontPropertyManager *fontManager = qobject_cast<QtFontPropertyManager *>(manager)) {
+ return fontManager->value(internProp);
+#ifndef QT_NO_CURSOR
+ } else if (QtCursorPropertyManager *cursorManager = qobject_cast<QtCursorPropertyManager *>(manager)) {
+ return cursorManager->value(internProp);
+#endif
+ } else if (QtFlagPropertyManager *flagManager = qobject_cast<QtFlagPropertyManager *>(manager)) {
+ return flagManager->value(internProp);
+ }
+ return QVariant();
+}
+
+/*!
+ Returns the given \a property's value type.
+
+ \sa propertyType()
+*/
+int QtVariantPropertyManager::valueType(const QtProperty *property) const
+{
+ int propType = propertyType(property);
+ return valueType(propType);
+}
+
+/*!
+ \overload
+
+ Returns the value type associated with the given \a propertyType.
+*/
+int QtVariantPropertyManager::valueType(int propertyType) const
+{
+ if (d_ptr->m_typeToValueType.contains(propertyType))
+ return d_ptr->m_typeToValueType[propertyType];
+ return 0;
+}
+
+/*!
+ Returns the given \a property's type.
+
+ \sa valueType()
+*/
+int QtVariantPropertyManager::propertyType(const QtProperty *property) const
+{
+ const QMap<const QtProperty *, QPair<QtVariantProperty *, int> >::const_iterator it = d_ptr->m_propertyToType.constFind(property);
+ if (it == d_ptr->m_propertyToType.constEnd())
+ return 0;
+ return it.value().second;
+}
+
+/*!
+ Returns the given \a property's value for the specified \a
+ attribute
+
+ If the given \a property was not created by \e this manager, or if
+ the specified \a attribute does not exist, this function returns
+ an invalid variant.
+
+ \sa attributes(), attributeType(), setAttribute()
+*/
+QVariant QtVariantPropertyManager::attributeValue(const QtProperty *property, const QString &attribute) const
+{
+ int propType = propertyType(property);
+ if (!propType)
+ return QVariant();
+
+ QMap<int, QMap<QString, int> >::ConstIterator it =
+ d_ptr->m_typeToAttributeToAttributeType.find(propType);
+ if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd())
+ return QVariant();
+
+ QMap<QString, int> attributes = it.value();
+ QMap<QString, int>::ConstIterator itAttr = attributes.find(attribute);
+ if (itAttr == attributes.constEnd())
+ return QVariant();
+
+ QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ if (internProp == 0)
+ return QVariant();
+
+ QtAbstractPropertyManager *manager = internProp->propertyManager();
+ if (QtIntPropertyManager *intManager = qobject_cast<QtIntPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return intManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return intManager->minimum(internProp);
+ if (attribute == d_ptr->m_singleStepAttribute)
+ return intManager->singleStep(internProp);
+ return QVariant();
+ } else if (QtDoublePropertyManager *doubleManager = qobject_cast<QtDoublePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return doubleManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return doubleManager->minimum(internProp);
+ if (attribute == d_ptr->m_singleStepAttribute)
+ return doubleManager->singleStep(internProp);
+ if (attribute == d_ptr->m_decimalsAttribute)
+ return doubleManager->decimals(internProp);
+ return QVariant();
+ } else if (QtStringPropertyManager *stringManager = qobject_cast<QtStringPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_regExpAttribute)
+ return stringManager->regExp(internProp);
+ return QVariant();
+ } else if (QtDatePropertyManager *dateManager = qobject_cast<QtDatePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return dateManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return dateManager->minimum(internProp);
+ return QVariant();
+ } else if (QtPointFPropertyManager *pointFManager = qobject_cast<QtPointFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_decimalsAttribute)
+ return pointFManager->decimals(internProp);
+ return QVariant();
+ } else if (QtSizePropertyManager *sizeManager = qobject_cast<QtSizePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return sizeManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return sizeManager->minimum(internProp);
+ return QVariant();
+ } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast<QtSizeFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return sizeFManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return sizeFManager->minimum(internProp);
+ if (attribute == d_ptr->m_decimalsAttribute)
+ return sizeFManager->decimals(internProp);
+ return QVariant();
+ } else if (QtRectPropertyManager *rectManager = qobject_cast<QtRectPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_constraintAttribute)
+ return rectManager->constraint(internProp);
+ return QVariant();
+ } else if (QtRectFPropertyManager *rectFManager = qobject_cast<QtRectFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_constraintAttribute)
+ return rectFManager->constraint(internProp);
+ if (attribute == d_ptr->m_decimalsAttribute)
+ return rectFManager->decimals(internProp);
+ return QVariant();
+ } else if (QtEnumPropertyManager *enumManager = qobject_cast<QtEnumPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_enumNamesAttribute)
+ return enumManager->enumNames(internProp);
+ if (attribute == d_ptr->m_enumIconsAttribute) {
+ QVariant v;
+ v.setValue(enumManager->enumIcons(internProp));
+ return v;
+ }
+ return QVariant();
+ } else if (QtFlagPropertyManager *flagManager = qobject_cast<QtFlagPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_flagNamesAttribute)
+ return flagManager->flagNames(internProp);
+ return QVariant();
+ }
+ return QVariant();
+}
+
+/*!
+ Returns a list of the given \a propertyType 's attributes.
+
+ \sa attributeValue(), attributeType()
+*/
+QStringList QtVariantPropertyManager::attributes(int propertyType) const
+{
+ QMap<int, QMap<QString, int> >::ConstIterator it =
+ d_ptr->m_typeToAttributeToAttributeType.find(propertyType);
+ if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd())
+ return QStringList();
+ return it.value().keys();
+}
+
+/*!
+ Returns the type of the specified \a attribute of the given \a
+ propertyType.
+
+ If the given \a propertyType is not supported by \e this manager,
+ or if the given \a propertyType does not possess the specified \a
+ attribute, this function returns QVariant::Invalid.
+
+ \sa attributes(), valueType()
+*/
+int QtVariantPropertyManager::attributeType(int propertyType, const QString &attribute) const
+{
+ QMap<int, QMap<QString, int> >::ConstIterator it =
+ d_ptr->m_typeToAttributeToAttributeType.find(propertyType);
+ if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd())
+ return 0;
+
+ QMap<QString, int> attributes = it.value();
+ QMap<QString, int>::ConstIterator itAttr = attributes.find(attribute);
+ if (itAttr == attributes.constEnd())
+ return 0;
+ return itAttr.value();
+}
+
+/*!
+ \fn void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &value)
+
+ Sets the value of the given \a property to \a value.
+
+ The specified \a value must be of a type returned by valueType(),
+ or of type that can be converted to valueType() using the
+ QVariant::canConvert() function, otherwise this function does
+ nothing.
+
+ \sa value(), QtVariantProperty::setValue(), valueChanged()
+*/
+void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &val)
+{
+ int propType = val.userType();
+ if (!propType)
+ return;
+
+ int valType = valueType(property);
+
+ if (propType != valType && !val.canConvert(static_cast<QVariant::Type>(valType)))
+ return;
+
+ QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ if (internProp == 0)
+ return;
+
+
+ QtAbstractPropertyManager *manager = internProp->propertyManager();
+ if (QtIntPropertyManager *intManager = qobject_cast<QtIntPropertyManager *>(manager)) {
+ intManager->setValue(internProp, qvariant_cast<int>(val));
+ return;
+ } else if (QtDoublePropertyManager *doubleManager = qobject_cast<QtDoublePropertyManager *>(manager)) {
+ doubleManager->setValue(internProp, qvariant_cast<double>(val));
+ return;
+ } else if (QtBoolPropertyManager *boolManager = qobject_cast<QtBoolPropertyManager *>(manager)) {
+ boolManager->setValue(internProp, qvariant_cast<bool>(val));
+ return;
+ } else if (QtStringPropertyManager *stringManager = qobject_cast<QtStringPropertyManager *>(manager)) {
+ stringManager->setValue(internProp, qvariant_cast<QString>(val));
+ return;
+ } else if (QtDatePropertyManager *dateManager = qobject_cast<QtDatePropertyManager *>(manager)) {
+ dateManager->setValue(internProp, qvariant_cast<QDate>(val));
+ return;
+ } else if (QtTimePropertyManager *timeManager = qobject_cast<QtTimePropertyManager *>(manager)) {
+ timeManager->setValue(internProp, qvariant_cast<QTime>(val));
+ return;
+ } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast<QtDateTimePropertyManager *>(manager)) {
+ dateTimeManager->setValue(internProp, qvariant_cast<QDateTime>(val));
+ return;
+ } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast<QtKeySequencePropertyManager *>(manager)) {
+ keySequenceManager->setValue(internProp, qvariant_cast<QKeySequence>(val));
+ return;
+ } else if (QtCharPropertyManager *charManager = qobject_cast<QtCharPropertyManager *>(manager)) {
+ charManager->setValue(internProp, qvariant_cast<QChar>(val));
+ return;
+ } else if (QtLocalePropertyManager *localeManager = qobject_cast<QtLocalePropertyManager *>(manager)) {
+ localeManager->setValue(internProp, qvariant_cast<QLocale>(val));
+ return;
+ } else if (QtPointPropertyManager *pointManager = qobject_cast<QtPointPropertyManager *>(manager)) {
+ pointManager->setValue(internProp, qvariant_cast<QPoint>(val));
+ return;
+ } else if (QtPointFPropertyManager *pointFManager = qobject_cast<QtPointFPropertyManager *>(manager)) {
+ pointFManager->setValue(internProp, qvariant_cast<QPointF>(val));
+ return;
+ } else if (QtSizePropertyManager *sizeManager = qobject_cast<QtSizePropertyManager *>(manager)) {
+ sizeManager->setValue(internProp, qvariant_cast<QSize>(val));
+ return;
+ } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast<QtSizeFPropertyManager *>(manager)) {
+ sizeFManager->setValue(internProp, qvariant_cast<QSizeF>(val));
+ return;
+ } else if (QtRectPropertyManager *rectManager = qobject_cast<QtRectPropertyManager *>(manager)) {
+ rectManager->setValue(internProp, qvariant_cast<QRect>(val));
+ return;
+ } else if (QtRectFPropertyManager *rectFManager = qobject_cast<QtRectFPropertyManager *>(manager)) {
+ rectFManager->setValue(internProp, qvariant_cast<QRectF>(val));
+ return;
+ } else if (QtColorPropertyManager *colorManager = qobject_cast<QtColorPropertyManager *>(manager)) {
+ colorManager->setValue(internProp, qvariant_cast<QColor>(val));
+ return;
+ } else if (QtEnumPropertyManager *enumManager = qobject_cast<QtEnumPropertyManager *>(manager)) {
+ enumManager->setValue(internProp, qvariant_cast<int>(val));
+ return;
+ } else if (QtSizePolicyPropertyManager *sizePolicyManager =
+ qobject_cast<QtSizePolicyPropertyManager *>(manager)) {
+ sizePolicyManager->setValue(internProp, qvariant_cast<QSizePolicy>(val));
+ return;
+ } else if (QtFontPropertyManager *fontManager = qobject_cast<QtFontPropertyManager *>(manager)) {
+ fontManager->setValue(internProp, qvariant_cast<QFont>(val));
+ return;
+#ifndef QT_NO_CURSOR
+ } else if (QtCursorPropertyManager *cursorManager = qobject_cast<QtCursorPropertyManager *>(manager)) {
+ cursorManager->setValue(internProp, qvariant_cast<QCursor>(val));
+ return;
+#endif
+ } else if (QtFlagPropertyManager *flagManager = qobject_cast<QtFlagPropertyManager *>(manager)) {
+ flagManager->setValue(internProp, qvariant_cast<int>(val));
+ return;
+ }
+}
+
+/*!
+ Sets the value of the specified \a attribute of the given \a
+ property, to \a value.
+
+ The new \a value's type must be of the type returned by
+ attributeType(), or of a type that can be converted to
+ attributeType() using the QVariant::canConvert() function,
+ otherwise this function does nothing.
+
+ \sa attributeValue(), QtVariantProperty::setAttribute(), attributeChanged()
+*/
+void QtVariantPropertyManager::setAttribute(QtProperty *property,
+ const QString &attribute, const QVariant &value)
+{
+ QVariant oldAttr = attributeValue(property, attribute);
+ if (!oldAttr.isValid())
+ return;
+
+ int attrType = value.userType();
+ if (!attrType)
+ return;
+
+ if (attrType != attributeType(propertyType(property), attribute) &&
+ !value.canConvert((QVariant::Type)attrType))
+ return;
+
+ QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ if (internProp == 0)
+ return;
+
+ QtAbstractPropertyManager *manager = internProp->propertyManager();
+ if (QtIntPropertyManager *intManager = qobject_cast<QtIntPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ intManager->setMaximum(internProp, qvariant_cast<int>(value));
+ else if (attribute == d_ptr->m_minimumAttribute)
+ intManager->setMinimum(internProp, qvariant_cast<int>(value));
+ else if (attribute == d_ptr->m_singleStepAttribute)
+ intManager->setSingleStep(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtDoublePropertyManager *doubleManager = qobject_cast<QtDoublePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ doubleManager->setMaximum(internProp, qvariant_cast<double>(value));
+ if (attribute == d_ptr->m_minimumAttribute)
+ doubleManager->setMinimum(internProp, qvariant_cast<double>(value));
+ if (attribute == d_ptr->m_singleStepAttribute)
+ doubleManager->setSingleStep(internProp, qvariant_cast<double>(value));
+ if (attribute == d_ptr->m_decimalsAttribute)
+ doubleManager->setDecimals(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtStringPropertyManager *stringManager = qobject_cast<QtStringPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_regExpAttribute)
+ stringManager->setRegExp(internProp, qvariant_cast<QRegExp>(value));
+ return;
+ } else if (QtDatePropertyManager *dateManager = qobject_cast<QtDatePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ dateManager->setMaximum(internProp, qvariant_cast<QDate>(value));
+ if (attribute == d_ptr->m_minimumAttribute)
+ dateManager->setMinimum(internProp, qvariant_cast<QDate>(value));
+ return;
+ } else if (QtPointFPropertyManager *pointFManager = qobject_cast<QtPointFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_decimalsAttribute)
+ pointFManager->setDecimals(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtSizePropertyManager *sizeManager = qobject_cast<QtSizePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ sizeManager->setMaximum(internProp, qvariant_cast<QSize>(value));
+ if (attribute == d_ptr->m_minimumAttribute)
+ sizeManager->setMinimum(internProp, qvariant_cast<QSize>(value));
+ return;
+ } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast<QtSizeFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ sizeFManager->setMaximum(internProp, qvariant_cast<QSizeF>(value));
+ if (attribute == d_ptr->m_minimumAttribute)
+ sizeFManager->setMinimum(internProp, qvariant_cast<QSizeF>(value));
+ if (attribute == d_ptr->m_decimalsAttribute)
+ sizeFManager->setDecimals(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtRectPropertyManager *rectManager = qobject_cast<QtRectPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_constraintAttribute)
+ rectManager->setConstraint(internProp, qvariant_cast<QRect>(value));
+ return;
+ } else if (QtRectFPropertyManager *rectFManager = qobject_cast<QtRectFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_constraintAttribute)
+ rectFManager->setConstraint(internProp, qvariant_cast<QRectF>(value));
+ if (attribute == d_ptr->m_decimalsAttribute)
+ rectFManager->setDecimals(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtEnumPropertyManager *enumManager = qobject_cast<QtEnumPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_enumNamesAttribute)
+ enumManager->setEnumNames(internProp, qvariant_cast<QStringList>(value));
+ if (attribute == d_ptr->m_enumIconsAttribute)
+ enumManager->setEnumIcons(internProp, qvariant_cast<QtIconMap>(value));
+ return;
+ } else if (QtFlagPropertyManager *flagManager = qobject_cast<QtFlagPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_flagNamesAttribute)
+ flagManager->setFlagNames(internProp, qvariant_cast<QStringList>(value));
+ return;
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QtVariantPropertyManager::hasValue(const QtProperty *property) const
+{
+ if (propertyType(property) == groupTypeId())
+ return false;
+ return true;
+}
+
+/*!
+ \reimp
+*/
+QString QtVariantPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ return internProp ? internProp->valueText() : QString();
+}
+
+/*!
+ \reimp
+*/
+QIcon QtVariantPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ return internProp ? internProp->valueIcon() : QIcon();
+}
+
+/*!
+ \reimp
+*/
+void QtVariantPropertyManager::initializeProperty(QtProperty *property)
+{
+ QtVariantProperty *varProp = variantProperty(property);
+ if (!varProp)
+ return;
+
+ QMap<int, QtAbstractPropertyManager *>::ConstIterator it =
+ d_ptr->m_typeToPropertyManager.find(d_ptr->m_propertyType);
+ if (it != d_ptr->m_typeToPropertyManager.constEnd()) {
+ QtProperty *internProp = 0;
+ if (!d_ptr->m_creatingSubProperties) {
+ QtAbstractPropertyManager *manager = it.value();
+ internProp = manager->addProperty();
+ d_ptr->m_internalToProperty[internProp] = varProp;
+ }
+ propertyToWrappedProperty()->insert(varProp, internProp);
+ if (internProp) {
+ QList<QtProperty *> children = internProp->subProperties();
+ QListIterator<QtProperty *> itChild(children);
+ QtVariantProperty *lastProperty = 0;
+ while (itChild.hasNext()) {
+ QtVariantProperty *prop = d_ptr->createSubProperty(varProp, lastProperty, itChild.next());
+ lastProperty = prop ? prop : lastProperty;
+ }
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+void QtVariantPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ const QMap<const QtProperty *, QPair<QtVariantProperty *, int> >::iterator type_it = d_ptr->m_propertyToType.find(property);
+ if (type_it == d_ptr->m_propertyToType.end())
+ return;
+
+ PropertyMap::iterator it = propertyToWrappedProperty()->find(property);
+ if (it != propertyToWrappedProperty()->end()) {
+ QtProperty *internProp = it.value();
+ if (internProp) {
+ d_ptr->m_internalToProperty.remove(internProp);
+ if (!d_ptr->m_destroyingSubProperties) {
+ delete internProp;
+ }
+ }
+ propertyToWrappedProperty()->erase(it);
+ }
+ d_ptr->m_propertyToType.erase(type_it);
+}
+
+/*!
+ \reimp
+*/
+QtProperty *QtVariantPropertyManager::createProperty()
+{
+ if (!d_ptr->m_creatingProperty)
+ return 0;
+
+ QtVariantProperty *property = new QtVariantProperty(this);
+ d_ptr->m_propertyToType.insert(property, qMakePair(property, d_ptr->m_propertyType));
+
+ return property;
+}
+
+/////////////////////////////
+
+class QtVariantEditorFactoryPrivate
+{
+ QtVariantEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtVariantEditorFactory)
+public:
+
+ QtSpinBoxFactory *m_spinBoxFactory;
+ QtDoubleSpinBoxFactory *m_doubleSpinBoxFactory;
+ QtCheckBoxFactory *m_checkBoxFactory;
+ QtLineEditFactory *m_lineEditFactory;
+ QtDateEditFactory *m_dateEditFactory;
+ QtTimeEditFactory *m_timeEditFactory;
+ QtDateTimeEditFactory *m_dateTimeEditFactory;
+ QtKeySequenceEditorFactory *m_keySequenceEditorFactory;
+ QtCharEditorFactory *m_charEditorFactory;
+ QtEnumEditorFactory *m_comboBoxFactory;
+ QtCursorEditorFactory *m_cursorEditorFactory;
+ QtColorEditorFactory *m_colorEditorFactory;
+ QtFontEditorFactory *m_fontEditorFactory;
+
+ QMap<QtAbstractEditorFactoryBase *, int> m_factoryToType;
+ QMap<int, QtAbstractEditorFactoryBase *> m_typeToFactory;
+};
+
+/*!
+ \class QtVariantEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtVariantEditorFactory class provides widgets for properties
+ created by QtVariantPropertyManager objects.
+
+ The variant factory provides the following widgets for the
+ specified property types:
+
+ \table
+ \header
+ \o Property Type
+ \o Widget
+ \row
+ \o \c int
+ \o QSpinBox
+ \row
+ \o \c double
+ \o QDoubleSpinBox
+ \row
+ \o \c bool
+ \o QCheckBox
+ \row
+ \o QString
+ \o QLineEdit
+ \row
+ \o QDate
+ \o QDateEdit
+ \row
+ \o QTime
+ \o QTimeEdit
+ \row
+ \o QDateTime
+ \o QDateTimeEdit
+ \row
+ \o QKeySequence
+ \o customized editor
+ \row
+ \o QChar
+ \o customized editor
+ \row
+ \o \c enum
+ \o QComboBox
+ \row
+ \o QCursor
+ \o QComboBox
+ \endtable
+
+ Note that QtVariantPropertyManager supports several additional property
+ types for which the QtVariantEditorFactory class does not provide
+ editing widgets, e.g. QPoint and QSize. To provide widgets for other
+ types using the variant approach, derive from the QtVariantEditorFactory
+ class.
+
+ \sa QtAbstractEditorFactory, QtVariantPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtVariantEditorFactory::QtVariantEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtVariantPropertyManager>(parent), d_ptr(new QtVariantEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_spinBoxFactory = new QtSpinBoxFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_spinBoxFactory] = QVariant::Int;
+ d_ptr->m_typeToFactory[QVariant::Int] = d_ptr->m_spinBoxFactory;
+
+ d_ptr->m_doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_doubleSpinBoxFactory] = QVariant::Double;
+ d_ptr->m_typeToFactory[QVariant::Double] = d_ptr->m_doubleSpinBoxFactory;
+
+ d_ptr->m_checkBoxFactory = new QtCheckBoxFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_checkBoxFactory] = QVariant::Bool;
+ d_ptr->m_typeToFactory[QVariant::Bool] = d_ptr->m_checkBoxFactory;
+
+ d_ptr->m_lineEditFactory = new QtLineEditFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_lineEditFactory] = QVariant::String;
+ d_ptr->m_typeToFactory[QVariant::String] = d_ptr->m_lineEditFactory;
+
+ d_ptr->m_dateEditFactory = new QtDateEditFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_dateEditFactory] = QVariant::Date;
+ d_ptr->m_typeToFactory[QVariant::Date] = d_ptr->m_dateEditFactory;
+
+ d_ptr->m_timeEditFactory = new QtTimeEditFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_timeEditFactory] = QVariant::Time;
+ d_ptr->m_typeToFactory[QVariant::Time] = d_ptr->m_timeEditFactory;
+
+ d_ptr->m_dateTimeEditFactory = new QtDateTimeEditFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_dateTimeEditFactory] = QVariant::DateTime;
+ d_ptr->m_typeToFactory[QVariant::DateTime] = d_ptr->m_dateTimeEditFactory;
+
+ d_ptr->m_keySequenceEditorFactory = new QtKeySequenceEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_keySequenceEditorFactory] = QVariant::KeySequence;
+ d_ptr->m_typeToFactory[QVariant::KeySequence] = d_ptr->m_keySequenceEditorFactory;
+
+ d_ptr->m_charEditorFactory = new QtCharEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_charEditorFactory] = QVariant::Char;
+ d_ptr->m_typeToFactory[QVariant::Char] = d_ptr->m_charEditorFactory;
+
+ d_ptr->m_cursorEditorFactory = new QtCursorEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_cursorEditorFactory] = QVariant::Cursor;
+ d_ptr->m_typeToFactory[QVariant::Cursor] = d_ptr->m_cursorEditorFactory;
+
+ d_ptr->m_colorEditorFactory = new QtColorEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_colorEditorFactory] = QVariant::Color;
+ d_ptr->m_typeToFactory[QVariant::Color] = d_ptr->m_colorEditorFactory;
+
+ d_ptr->m_fontEditorFactory = new QtFontEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_fontEditorFactory] = QVariant::Font;
+ d_ptr->m_typeToFactory[QVariant::Font] = d_ptr->m_fontEditorFactory;
+
+ d_ptr->m_comboBoxFactory = new QtEnumEditorFactory(this);
+ const int enumId = QtVariantPropertyManager::enumTypeId();
+ d_ptr->m_factoryToType[d_ptr->m_comboBoxFactory] = enumId;
+ d_ptr->m_typeToFactory[enumId] = d_ptr->m_comboBoxFactory;
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtVariantEditorFactory::~QtVariantEditorFactory()
+{
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager)
+{
+ QList<QtIntPropertyManager *> intPropertyManagers = manager->findChildren<QtIntPropertyManager *>();
+ QListIterator<QtIntPropertyManager *> itInt(intPropertyManagers);
+ while (itInt.hasNext())
+ d_ptr->m_spinBoxFactory->addPropertyManager(itInt.next());
+
+ QList<QtDoublePropertyManager *> doublePropertyManagers = manager->findChildren<QtDoublePropertyManager *>();
+ QListIterator<QtDoublePropertyManager *> itDouble(doublePropertyManagers);
+ while (itDouble.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itDouble.next());
+
+ QList<QtBoolPropertyManager *> boolPropertyManagers = manager->findChildren<QtBoolPropertyManager *>();
+ QListIterator<QtBoolPropertyManager *> itBool(boolPropertyManagers);
+ while (itBool.hasNext())
+ d_ptr->m_checkBoxFactory->addPropertyManager(itBool.next());
+
+ QList<QtStringPropertyManager *> stringPropertyManagers = manager->findChildren<QtStringPropertyManager *>();
+ QListIterator<QtStringPropertyManager *> itString(stringPropertyManagers);
+ while (itString.hasNext())
+ d_ptr->m_lineEditFactory->addPropertyManager(itString.next());
+
+ QList<QtDatePropertyManager *> datePropertyManagers = manager->findChildren<QtDatePropertyManager *>();
+ QListIterator<QtDatePropertyManager *> itDate(datePropertyManagers);
+ while (itDate.hasNext())
+ d_ptr->m_dateEditFactory->addPropertyManager(itDate.next());
+
+ QList<QtTimePropertyManager *> timePropertyManagers = manager->findChildren<QtTimePropertyManager *>();
+ QListIterator<QtTimePropertyManager *> itTime(timePropertyManagers);
+ while (itTime.hasNext())
+ d_ptr->m_timeEditFactory->addPropertyManager(itTime.next());
+
+ QList<QtDateTimePropertyManager *> dateTimePropertyManagers = manager->findChildren<QtDateTimePropertyManager *>();
+ QListIterator<QtDateTimePropertyManager *> itDateTime(dateTimePropertyManagers);
+ while (itDateTime.hasNext())
+ d_ptr->m_dateTimeEditFactory->addPropertyManager(itDateTime.next());
+
+ QList<QtKeySequencePropertyManager *> keySequencePropertyManagers = manager->findChildren<QtKeySequencePropertyManager *>();
+ QListIterator<QtKeySequencePropertyManager *> itKeySequence(keySequencePropertyManagers);
+ while (itKeySequence.hasNext())
+ d_ptr->m_keySequenceEditorFactory->addPropertyManager(itKeySequence.next());
+
+ QList<QtCharPropertyManager *> charPropertyManagers = manager->findChildren<QtCharPropertyManager *>();
+ QListIterator<QtCharPropertyManager *> itChar(charPropertyManagers);
+ while (itChar.hasNext())
+ d_ptr->m_charEditorFactory->addPropertyManager(itChar.next());
+
+ QList<QtLocalePropertyManager *> localePropertyManagers = manager->findChildren<QtLocalePropertyManager *>();
+ QListIterator<QtLocalePropertyManager *> itLocale(localePropertyManagers);
+ while (itLocale.hasNext())
+ d_ptr->m_comboBoxFactory->addPropertyManager(itLocale.next()->subEnumPropertyManager());
+
+ QList<QtPointPropertyManager *> pointPropertyManagers = manager->findChildren<QtPointPropertyManager *>();
+ QListIterator<QtPointPropertyManager *> itPoint(pointPropertyManagers);
+ while (itPoint.hasNext())
+ d_ptr->m_spinBoxFactory->addPropertyManager(itPoint.next()->subIntPropertyManager());
+
+ QList<QtPointFPropertyManager *> pointFPropertyManagers = manager->findChildren<QtPointFPropertyManager *>();
+ QListIterator<QtPointFPropertyManager *> itPointF(pointFPropertyManagers);
+ while (itPointF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itPointF.next()->subDoublePropertyManager());
+
+ QList<QtSizePropertyManager *> sizePropertyManagers = manager->findChildren<QtSizePropertyManager *>();
+ QListIterator<QtSizePropertyManager *> itSize(sizePropertyManagers);
+ while (itSize.hasNext())
+ d_ptr->m_spinBoxFactory->addPropertyManager(itSize.next()->subIntPropertyManager());
+
+ QList<QtSizeFPropertyManager *> sizeFPropertyManagers = manager->findChildren<QtSizeFPropertyManager *>();
+ QListIterator<QtSizeFPropertyManager *> itSizeF(sizeFPropertyManagers);
+ while (itSizeF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itSizeF.next()->subDoublePropertyManager());
+
+ QList<QtRectPropertyManager *> rectPropertyManagers = manager->findChildren<QtRectPropertyManager *>();
+ QListIterator<QtRectPropertyManager *> itRect(rectPropertyManagers);
+ while (itRect.hasNext())
+ d_ptr->m_spinBoxFactory->addPropertyManager(itRect.next()->subIntPropertyManager());
+
+ QList<QtRectFPropertyManager *> rectFPropertyManagers = manager->findChildren<QtRectFPropertyManager *>();
+ QListIterator<QtRectFPropertyManager *> itRectF(rectFPropertyManagers);
+ while (itRectF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itRectF.next()->subDoublePropertyManager());
+
+ QList<QtColorPropertyManager *> colorPropertyManagers = manager->findChildren<QtColorPropertyManager *>();
+ QListIterator<QtColorPropertyManager *> itColor(colorPropertyManagers);
+ while (itColor.hasNext()) {
+ QtColorPropertyManager *manager = itColor.next();
+ d_ptr->m_colorEditorFactory->addPropertyManager(manager);
+ d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
+ }
+
+ QList<QtEnumPropertyManager *> enumPropertyManagers = manager->findChildren<QtEnumPropertyManager *>();
+ QListIterator<QtEnumPropertyManager *> itEnum(enumPropertyManagers);
+ while (itEnum.hasNext())
+ d_ptr->m_comboBoxFactory->addPropertyManager(itEnum.next());
+
+ QList<QtSizePolicyPropertyManager *> sizePolicyPropertyManagers = manager->findChildren<QtSizePolicyPropertyManager *>();
+ QListIterator<QtSizePolicyPropertyManager *> itSizePolicy(sizePolicyPropertyManagers);
+ while (itSizePolicy.hasNext()) {
+ QtSizePolicyPropertyManager *manager = itSizePolicy.next();
+ d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
+ d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager());
+ }
+
+ QList<QtFontPropertyManager *> fontPropertyManagers = manager->findChildren<QtFontPropertyManager *>();
+ QListIterator<QtFontPropertyManager *> itFont(fontPropertyManagers);
+ while (itFont.hasNext()) {
+ QtFontPropertyManager *manager = itFont.next();
+ d_ptr->m_fontEditorFactory->addPropertyManager(manager);
+ d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
+ d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager());
+ d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager());
+ }
+
+ QList<QtCursorPropertyManager *> cursorPropertyManagers = manager->findChildren<QtCursorPropertyManager *>();
+ QListIterator<QtCursorPropertyManager *> itCursor(cursorPropertyManagers);
+ while (itCursor.hasNext())
+ d_ptr->m_cursorEditorFactory->addPropertyManager(itCursor.next());
+
+ QList<QtFlagPropertyManager *> flagPropertyManagers = manager->findChildren<QtFlagPropertyManager *>();
+ QListIterator<QtFlagPropertyManager *> itFlag(flagPropertyManagers);
+ while (itFlag.hasNext())
+ d_ptr->m_checkBoxFactory->addPropertyManager(itFlag.next()->subBoolPropertyManager());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtVariantEditorFactory::createEditor(QtVariantPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ const int propType = manager->propertyType(property);
+ QtAbstractEditorFactoryBase *factory = d_ptr->m_typeToFactory.value(propType, 0);
+ if (!factory)
+ return 0;
+ return factory->createEditor(wrappedProperty(property), parent);
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager)
+{
+ QList<QtIntPropertyManager *> intPropertyManagers = manager->findChildren<QtIntPropertyManager *>();
+ QListIterator<QtIntPropertyManager *> itInt(intPropertyManagers);
+ while (itInt.hasNext())
+ d_ptr->m_spinBoxFactory->removePropertyManager(itInt.next());
+
+ QList<QtDoublePropertyManager *> doublePropertyManagers = manager->findChildren<QtDoublePropertyManager *>();
+ QListIterator<QtDoublePropertyManager *> itDouble(doublePropertyManagers);
+ while (itDouble.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itDouble.next());
+
+ QList<QtBoolPropertyManager *> boolPropertyManagers = manager->findChildren<QtBoolPropertyManager *>();
+ QListIterator<QtBoolPropertyManager *> itBool(boolPropertyManagers);
+ while (itBool.hasNext())
+ d_ptr->m_checkBoxFactory->removePropertyManager(itBool.next());
+
+ QList<QtStringPropertyManager *> stringPropertyManagers = manager->findChildren<QtStringPropertyManager *>();
+ QListIterator<QtStringPropertyManager *> itString(stringPropertyManagers);
+ while (itString.hasNext())
+ d_ptr->m_lineEditFactory->removePropertyManager(itString.next());
+
+ QList<QtDatePropertyManager *> datePropertyManagers = manager->findChildren<QtDatePropertyManager *>();
+ QListIterator<QtDatePropertyManager *> itDate(datePropertyManagers);
+ while (itDate.hasNext())
+ d_ptr->m_dateEditFactory->removePropertyManager(itDate.next());
+
+ QList<QtTimePropertyManager *> timePropertyManagers = manager->findChildren<QtTimePropertyManager *>();
+ QListIterator<QtTimePropertyManager *> itTime(timePropertyManagers);
+ while (itTime.hasNext())
+ d_ptr->m_timeEditFactory->removePropertyManager(itTime.next());
+
+ QList<QtDateTimePropertyManager *> dateTimePropertyManagers = manager->findChildren<QtDateTimePropertyManager *>();
+ QListIterator<QtDateTimePropertyManager *> itDateTime(dateTimePropertyManagers);
+ while (itDateTime.hasNext())
+ d_ptr->m_dateTimeEditFactory->removePropertyManager(itDateTime.next());
+
+ QList<QtKeySequencePropertyManager *> keySequencePropertyManagers = manager->findChildren<QtKeySequencePropertyManager *>();
+ QListIterator<QtKeySequencePropertyManager *> itKeySequence(keySequencePropertyManagers);
+ while (itKeySequence.hasNext())
+ d_ptr->m_keySequenceEditorFactory->removePropertyManager(itKeySequence.next());
+
+ QList<QtCharPropertyManager *> charPropertyManagers = manager->findChildren<QtCharPropertyManager *>();
+ QListIterator<QtCharPropertyManager *> itChar(charPropertyManagers);
+ while (itChar.hasNext())
+ d_ptr->m_charEditorFactory->removePropertyManager(itChar.next());
+
+ QList<QtLocalePropertyManager *> localePropertyManagers = manager->findChildren<QtLocalePropertyManager *>();
+ QListIterator<QtLocalePropertyManager *> itLocale(localePropertyManagers);
+ while (itLocale.hasNext())
+ d_ptr->m_comboBoxFactory->removePropertyManager(itLocale.next()->subEnumPropertyManager());
+
+ QList<QtPointPropertyManager *> pointPropertyManagers = manager->findChildren<QtPointPropertyManager *>();
+ QListIterator<QtPointPropertyManager *> itPoint(pointPropertyManagers);
+ while (itPoint.hasNext())
+ d_ptr->m_spinBoxFactory->removePropertyManager(itPoint.next()->subIntPropertyManager());
+
+ QList<QtPointFPropertyManager *> pointFPropertyManagers = manager->findChildren<QtPointFPropertyManager *>();
+ QListIterator<QtPointFPropertyManager *> itPointF(pointFPropertyManagers);
+ while (itPointF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itPointF.next()->subDoublePropertyManager());
+
+ QList<QtSizePropertyManager *> sizePropertyManagers = manager->findChildren<QtSizePropertyManager *>();
+ QListIterator<QtSizePropertyManager *> itSize(sizePropertyManagers);
+ while (itSize.hasNext())
+ d_ptr->m_spinBoxFactory->removePropertyManager(itSize.next()->subIntPropertyManager());
+
+ QList<QtSizeFPropertyManager *> sizeFPropertyManagers = manager->findChildren<QtSizeFPropertyManager *>();
+ QListIterator<QtSizeFPropertyManager *> itSizeF(sizeFPropertyManagers);
+ while (itSizeF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itSizeF.next()->subDoublePropertyManager());
+
+ QList<QtRectPropertyManager *> rectPropertyManagers = manager->findChildren<QtRectPropertyManager *>();
+ QListIterator<QtRectPropertyManager *> itRect(rectPropertyManagers);
+ while (itRect.hasNext())
+ d_ptr->m_spinBoxFactory->removePropertyManager(itRect.next()->subIntPropertyManager());
+
+ QList<QtRectFPropertyManager *> rectFPropertyManagers = manager->findChildren<QtRectFPropertyManager *>();
+ QListIterator<QtRectFPropertyManager *> itRectF(rectFPropertyManagers);
+ while (itRectF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itRectF.next()->subDoublePropertyManager());
+
+ QList<QtColorPropertyManager *> colorPropertyManagers = manager->findChildren<QtColorPropertyManager *>();
+ QListIterator<QtColorPropertyManager *> itColor(colorPropertyManagers);
+ while (itColor.hasNext()) {
+ QtColorPropertyManager *manager = itColor.next();
+ d_ptr->m_colorEditorFactory->removePropertyManager(manager);
+ d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
+ }
+
+ QList<QtEnumPropertyManager *> enumPropertyManagers = manager->findChildren<QtEnumPropertyManager *>();
+ QListIterator<QtEnumPropertyManager *> itEnum(enumPropertyManagers);
+ while (itEnum.hasNext())
+ d_ptr->m_comboBoxFactory->removePropertyManager(itEnum.next());
+
+ QList<QtSizePolicyPropertyManager *> sizePolicyPropertyManagers = manager->findChildren<QtSizePolicyPropertyManager *>();
+ QListIterator<QtSizePolicyPropertyManager *> itSizePolicy(sizePolicyPropertyManagers);
+ while (itSizePolicy.hasNext()) {
+ QtSizePolicyPropertyManager *manager = itSizePolicy.next();
+ d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
+ d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager());
+ }
+
+ QList<QtFontPropertyManager *> fontPropertyManagers = manager->findChildren<QtFontPropertyManager *>();
+ QListIterator<QtFontPropertyManager *> itFont(fontPropertyManagers);
+ while (itFont.hasNext()) {
+ QtFontPropertyManager *manager = itFont.next();
+ d_ptr->m_fontEditorFactory->removePropertyManager(manager);
+ d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
+ d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager());
+ d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager());
+ }
+
+ QList<QtCursorPropertyManager *> cursorPropertyManagers = manager->findChildren<QtCursorPropertyManager *>();
+ QListIterator<QtCursorPropertyManager *> itCursor(cursorPropertyManagers);
+ while (itCursor.hasNext())
+ d_ptr->m_cursorEditorFactory->removePropertyManager(itCursor.next());
+
+ QList<QtFlagPropertyManager *> flagPropertyManagers = manager->findChildren<QtFlagPropertyManager *>();
+ QListIterator<QtFlagPropertyManager *> itFlag(flagPropertyManagers);
+ while (itFlag.hasNext())
+ d_ptr->m_checkBoxFactory->removePropertyManager(itFlag.next()->subBoolPropertyManager());
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtvariantproperty.cpp"
diff --git a/src/shared/qtpropertybrowser/qtvariantproperty.h b/src/shared/qtpropertybrowser/qtvariantproperty.h
new file mode 100644
index 000000000..b5fe1f928
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtvariantproperty.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTVARIANTPROPERTY_H
+#define QTVARIANTPROPERTY_H
+
+#include "qtpropertybrowser.h"
+#include <QtCore/QVariant>
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+typedef QMap<int, QIcon> QtIconMap;
+
+class QtVariantPropertyManager;
+
+class QtVariantProperty : public QtProperty
+{
+public:
+ ~QtVariantProperty();
+ QVariant value() const;
+ QVariant attributeValue(const QString &attribute) const;
+ int valueType() const;
+ int propertyType() const;
+
+ void setValue(const QVariant &value);
+ void setAttribute(const QString &attribute, const QVariant &value);
+protected:
+ QtVariantProperty(QtVariantPropertyManager *manager);
+private:
+ friend class QtVariantPropertyManager;
+ QScopedPointer<class QtVariantPropertyPrivate> d_ptr;
+};
+
+class QtVariantPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtVariantPropertyManager(QObject *parent = 0);
+ ~QtVariantPropertyManager();
+
+ virtual QtVariantProperty *addProperty(int propertyType, const QString &name = QString());
+
+ int propertyType(const QtProperty *property) const;
+ int valueType(const QtProperty *property) const;
+ QtVariantProperty *variantProperty(const QtProperty *property) const;
+
+ virtual bool isPropertyTypeSupported(int propertyType) const;
+ virtual int valueType(int propertyType) const;
+ virtual QStringList attributes(int propertyType) const;
+ virtual int attributeType(int propertyType, const QString &attribute) const;
+
+ virtual QVariant value(const QtProperty *property) const;
+ virtual QVariant attributeValue(const QtProperty *property, const QString &attribute) const;
+
+ static int enumTypeId();
+ static int flagTypeId();
+ static int groupTypeId();
+ static int iconMapTypeId();
+public Q_SLOTS:
+ virtual void setValue(QtProperty *property, const QVariant &val);
+ virtual void setAttribute(QtProperty *property,
+ const QString &attribute, const QVariant &value);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QVariant &val);
+ void attributeChanged(QtProperty *property,
+ const QString &attribute, const QVariant &val);
+protected:
+ virtual bool hasValue(const QtProperty *property) const;
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+ virtual QtProperty *createProperty();
+private:
+ QScopedPointer<class QtVariantPropertyManagerPrivate> d_ptr;
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, bool))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QDate &, const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDateTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QKeySequence &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QChar &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QLocale &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPoint &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSize &))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSize &, const QSize &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizeF &))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSizeF &, const QSizeF &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRect &))
+ Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRect &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRectF &))
+ Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRectF &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QColor &))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *, const QStringList &))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *, const QMap<int, QIcon> &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizePolicy &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QFont &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QCursor &))
+ Q_PRIVATE_SLOT(d_func(), void slotFlagNamesChanged(QtProperty *, const QStringList &))
+
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, QtProperty *))
+ Q_DECLARE_PRIVATE(QtVariantPropertyManager)
+ Q_DISABLE_COPY(QtVariantPropertyManager)
+};
+
+class QtVariantEditorFactory : public QtAbstractEditorFactory<QtVariantPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtVariantEditorFactory(QObject *parent = 0);
+ ~QtVariantEditorFactory();
+protected:
+ void connectPropertyManager(QtVariantPropertyManager *manager);
+ QWidget *createEditor(QtVariantPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtVariantPropertyManager *manager);
+private:
+ QScopedPointer<class QtVariantEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtVariantEditorFactory)
+ Q_DISABLE_COPY(QtVariantEditorFactory)
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QIcon)
+Q_DECLARE_METATYPE(QtIconMap)
+#endif
diff --git a/src/shared/qttoolbardialog/images/back.png b/src/shared/qttoolbardialog/images/back.png
new file mode 100644
index 000000000..e58177f43
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/back.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/down.png b/src/shared/qttoolbardialog/images/down.png
new file mode 100644
index 000000000..29d1d4439
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/down.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/forward.png b/src/shared/qttoolbardialog/images/forward.png
new file mode 100644
index 000000000..34b91f09f
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/forward.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/minus.png b/src/shared/qttoolbardialog/images/minus.png
new file mode 100644
index 000000000..d6f233d73
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/minus.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/plus.png b/src/shared/qttoolbardialog/images/plus.png
new file mode 100644
index 000000000..40df1134f
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/plus.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/up.png b/src/shared/qttoolbardialog/images/up.png
new file mode 100644
index 000000000..e43731221
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/up.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.cpp b/src/shared/qttoolbardialog/qttoolbardialog.cpp
new file mode 100644
index 000000000..b45bef290
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.cpp
@@ -0,0 +1,1871 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qttoolbardialog.h"
+#include "ui_qttoolbardialog.h"
+
+#include <QtCore/QSet>
+#include <QtGui/QtEvents>
+#include <QtGui/QAction>
+#include <QtGui/QToolBar>
+#include <QtGui/QMainWindow>
+#include <QtGui/QHeaderView>
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+class QtFullToolBarManagerPrivate;
+
+class QtFullToolBarManager : public QObject
+{
+ Q_OBJECT
+public:
+ QtFullToolBarManager(QObject *parent);
+ ~QtFullToolBarManager();
+
+ void setMainWindow(QMainWindow *mainWindow);
+ QMainWindow *mainWindow() const;
+
+ void addCategory(const QString &category);
+ bool hasCategory(const QString &category) const;
+ QStringList categories() const;
+ QList<QAction *> categoryActions(const QString &category) const;
+ QString actionCategory(QAction *action) const;
+
+ // only non-separator
+ void addAction(QAction *action, const QString &category);
+
+ void removeAction(QAction *action);
+
+ QSet<QAction *> actions() const;
+ bool isWidgetAction(QAction *action) const;
+
+ /*
+ Adds (registers) toolBar. Adds (registers) actions that already exists in toolBar.
+ Remembers toolbar and its actions as a default.
+ */
+ void addDefaultToolBar(QToolBar *toolBar, const QString &category);
+
+ void removeDefaultToolBar(QToolBar *toolBar);
+ // NULL on action list means separator.
+ QMap<QToolBar *, QList<QAction *> > defaultToolBars() const;
+ bool isDefaultToolBar(QToolBar *toolBar) const;
+
+ QToolBar *createToolBar(const QString &toolBarName);
+ void deleteToolBar(QToolBar *toolBar); // only those which were created, not added
+
+ QList<QAction *> actions(QToolBar *toolBar) const;
+
+ void setToolBars(const QMap<QToolBar *, QList<QAction *> > &actions);
+ void setToolBar(QToolBar *toolBar, const QList<QAction *> &actions);
+
+ QMap<QToolBar *, QList<QAction *> > toolBarsActions() const;
+ QByteArray saveState(int version = 0) const;
+ bool restoreState(const QByteArray &state, int version = 0);
+
+public slots:
+
+ void resetToolBar(QToolBar *toolBar);
+ void resetAllToolBars();
+
+signals:
+ void toolBarCreated(QToolBar *toolBar);
+ void toolBarRemoved(QToolBar *toolBar);
+
+ /*
+ If QToolBarWidgetAction was in another tool bar and is inserted into
+ this toolBar, toolBarChanged is first emitted for other toolbar - without
+ that action. (Another approach may be that user first must call setToolBar
+ without that action for old tool bar)
+ */
+ void toolBarChanged(QToolBar *toolBar, const QList<QAction *> &actions);
+
+private:
+ QScopedPointer<QtFullToolBarManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtFullToolBarManager)
+ Q_DISABLE_COPY(QtFullToolBarManager)
+};
+
+class QtFullToolBarManagerPrivate
+{
+ class QtFullToolBarManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtFullToolBarManager)
+
+public:
+
+ QToolBar *toolBarWidgetAction(QAction *action) const;
+ void removeWidgetActions(const QMap<QToolBar *, QList<QAction *> > &actions);
+
+ enum {
+ VersionMarker = 0xff,
+ ToolBarMarker = 0xfe,
+ CustomToolBarMarker = 0xfd,
+ };
+
+ void saveState(QDataStream &stream) const;
+ bool restoreState(QDataStream &stream) const;
+ QToolBar *findDefaultToolBar(const QString &objectName) const;
+ QAction *findAction(const QString &actionName) const;
+
+ QToolBar *toolBarByName(const QString &toolBarName) const;
+
+ QtFullToolBarManagerPrivate();
+
+ QMap<QString, QList<QAction *> > categoryToActions;
+ QMap<QAction *, QString> actionToCategory;
+
+ QSet<QAction *> allActions;
+ QMap<QAction *, QToolBar *> widgetActions;
+ QSet<QAction *> regularActions;
+ QMap<QAction *, QList<QToolBar *> > actionToToolBars;
+
+ QMap<QToolBar *, QList<QAction *> > toolBars;
+ QMap<QToolBar *, QList<QAction *> > toolBarsWithSeparators;
+ QMap<QToolBar *, QList<QAction *> > defaultToolBars;
+ QList<QToolBar *> customToolBars;
+
+ QMainWindow *theMainWindow;
+};
+
+
+
+
+QtFullToolBarManagerPrivate::QtFullToolBarManagerPrivate()
+ : theMainWindow(0)
+{
+}
+
+QToolBar *QtFullToolBarManagerPrivate::toolBarWidgetAction(QAction *action) const
+{
+ if (widgetActions.contains(action))
+ return widgetActions.value(action);
+ return 0;
+}
+
+void QtFullToolBarManagerPrivate::removeWidgetActions(const QMap<QToolBar *, QList<QAction *> >
+ &actions)
+{
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = actions.constBegin();
+ while (itToolBar != actions.constEnd()) {
+ QToolBar *toolBar = itToolBar.key();
+ QList<QAction *> newActions = toolBars.value(toolBar);
+ QList<QAction *> newActionsWithSeparators = toolBarsWithSeparators.value(toolBar);
+
+ QList<QAction *> removedActions;
+ QList<QAction *> actionList = itToolBar.value();
+ QListIterator<QAction *> itAction(actionList);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (newActions.contains(action) && toolBarWidgetAction(action) == toolBar) {
+ newActions.removeAll(action);
+ newActionsWithSeparators.removeAll(action);
+ removedActions.append(action);
+ }
+ }
+
+ //emit q_ptr->toolBarChanged(toolBar, newActions);
+
+ toolBars.insert(toolBar, newActions);
+ toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
+ QListIterator<QAction *> itRemovedAction(removedActions);
+ while (itRemovedAction.hasNext()) {
+ QAction *oldAction = itRemovedAction.next();
+ widgetActions.insert(oldAction, 0);
+ actionToToolBars[oldAction].removeAll(toolBar);
+ }
+
+ ++itToolBar;
+ }
+}
+
+void QtFullToolBarManagerPrivate::saveState(QDataStream &stream) const
+{
+ stream << (uchar) ToolBarMarker;
+ stream << defaultToolBars.size();
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar =
+ defaultToolBars.constBegin();
+ while (itToolBar != defaultToolBars.constEnd()) {
+ QToolBar *tb = itToolBar.key();
+ if (tb->objectName().isEmpty()) {
+ qWarning("QtToolBarManager::saveState(): 'objectName' not set for QToolBar "
+ "%p '%s', using 'windowTitle' instead",
+ tb, tb->windowTitle().toLocal8Bit().constData());
+ stream << tb->windowTitle();
+ } else {
+ stream << tb->objectName();
+ }
+
+ stream << toolBars[tb].size();
+ QListIterator<QAction *> itAction(toolBars[tb]);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+
+ if (action) {
+ if (action->objectName().isEmpty()) {
+ qWarning("QtToolBarManager::saveState(): 'objectName' not set for QAction "
+ "%p '%s', using 'text' instead",
+ action, action->text().toLocal8Bit().constData());
+ stream << action->text();
+ } else {
+ stream << action->objectName();
+ }
+ } else {
+ stream << QString();
+ }
+ }
+ ++itToolBar;
+ }
+
+
+ stream << (uchar) CustomToolBarMarker;
+ stream << toolBars.size() - defaultToolBars.size();
+ itToolBar = toolBars.constBegin();
+ while (itToolBar != toolBars.constEnd()) {
+ QToolBar *tb = itToolBar.key();
+ if (!defaultToolBars.contains(tb)) {
+ stream << tb->objectName();
+ stream << tb->windowTitle();
+
+ stream << toolBars[tb].size();
+ QListIterator<QAction *> itAction(toolBars[tb]);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+
+ if (action) {
+ if (action->objectName().isEmpty()) {
+ qWarning("QtToolBarManager::saveState(): 'objectName' not set for QAction "
+ "%p '%s', using 'text' instead",
+ action, action->text().toLocal8Bit().constData());
+ stream << action->text();
+ } else {
+ stream << action->objectName();
+ }
+ } else {
+ stream << QString();
+ }
+ }
+ }
+ ++itToolBar;
+ }
+}
+
+bool QtFullToolBarManagerPrivate::restoreState(QDataStream &stream) const
+{
+ uchar tmarker;
+ stream >> tmarker;
+ if (tmarker != ToolBarMarker)
+ return false;
+
+ int toolBars;
+ stream >> toolBars;
+ for (int i = 0; i < toolBars; i++) {
+ QString objectName;
+ stream >> objectName;
+ int actionCount;
+ stream >> actionCount;
+ QList<QAction *> actions;
+ for (int j = 0; j < actionCount; j++) {
+ QString actionName;
+ stream >> actionName;
+
+ if (actionName.isEmpty())
+ actions.append(0);
+ else {
+ QAction *action = findAction(actionName);
+ if (action)
+ actions.append(action);
+ }
+ }
+
+ QToolBar *toolBar = findDefaultToolBar(objectName);
+ if (toolBar)
+ q_ptr->setToolBar(toolBar, actions);
+ }
+
+
+
+ uchar ctmarker;
+ stream >> ctmarker;
+ if (ctmarker != CustomToolBarMarker)
+ return false;
+
+ QList<QToolBar *> oldCustomToolBars = customToolBars;
+
+ stream >> toolBars;
+ for (int i = 0; i < toolBars; i++) {
+ QString objectName;
+ QString toolBarName;
+ int actionCount;
+ stream >> objectName;
+ stream >> toolBarName;
+ stream >> actionCount;
+ QList<QAction *> actions;
+ for (int j = 0; j < actionCount; j++) {
+ QString actionName;
+ stream >> actionName;
+
+ if (actionName.isEmpty())
+ actions.append(0);
+ else {
+ QAction *action = findAction(actionName);
+ if (action)
+ actions.append(action);
+ }
+ }
+
+ QToolBar *toolBar = toolBarByName(objectName);
+ if (toolBar) {
+ toolBar->setWindowTitle(toolBarName);
+ oldCustomToolBars.removeAll(toolBar);
+ }
+ else
+ toolBar = q_ptr->createToolBar(toolBarName);
+ if (toolBar) {
+ toolBar->setObjectName(objectName);
+ q_ptr->setToolBar(toolBar, actions);
+ }
+ }
+ QListIterator<QToolBar *> itToolBar(oldCustomToolBars);
+ while (itToolBar.hasNext())
+ q_ptr->deleteToolBar(itToolBar.next());
+ return true;
+}
+
+QToolBar *QtFullToolBarManagerPrivate::findDefaultToolBar(const QString &objectName) const
+{
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar =
+ defaultToolBars.constBegin();
+ while (itToolBar != defaultToolBars.constEnd()) {
+ QToolBar *tb = itToolBar.key();
+ if (tb->objectName() == objectName)
+ return tb;
+
+ ++itToolBar;
+ }
+
+ qWarning("QtToolBarManager::restoreState(): cannot find a QToolBar named "
+ "'%s', trying to match using 'windowTitle' instead.",
+ objectName.toLocal8Bit().constData());
+
+ itToolBar = defaultToolBars.constBegin();
+ while (itToolBar != defaultToolBars.constEnd()) {
+ QToolBar *tb = itToolBar.key();
+ if (tb->windowTitle() == objectName)
+ return tb;
+
+ ++itToolBar;
+ }
+ qWarning("QtToolBarManager::restoreState(): cannot find a QToolBar with "
+ "matching 'windowTitle' (looking for '%s').",
+ objectName.toLocal8Bit().constData());
+
+ return 0;
+}
+
+QAction *QtFullToolBarManagerPrivate::findAction(const QString &actionName) const
+{
+ QSetIterator<QAction *> itAction(allActions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+
+ if (action->objectName() == actionName)
+ return action;
+ }
+ qWarning("QtToolBarManager::restoreState(): cannot find a QAction named "
+ "'%s', trying to match using 'text' instead.",
+ actionName.toLocal8Bit().constData());
+
+ itAction.toFront();
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+
+ if (action->text() == actionName)
+ return action;
+ }
+ qWarning("QtToolBarManager::restoreState(): cannot find a QAction with "
+ "matching 'text' (looking for '%s').",
+ actionName.toLocal8Bit().constData());
+
+ return 0;
+}
+
+QToolBar *QtFullToolBarManagerPrivate::toolBarByName(const QString &toolBarName) const
+{
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = toolBars.constBegin();
+ while (itToolBar != toolBars.constEnd()) {
+ QToolBar *toolBar = itToolBar.key();
+ if (toolBar->objectName() == toolBarName)
+ return toolBar;
+
+ ++itToolBar;
+ }
+ return 0;
+}
+
+//////////////////////////////
+
+QtFullToolBarManager::QtFullToolBarManager(QObject *parent)
+ : QObject(parent), d_ptr(new QtFullToolBarManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+QtFullToolBarManager::~QtFullToolBarManager()
+{
+}
+
+void QtFullToolBarManager::setMainWindow(QMainWindow *mainWindow)
+{
+ d_ptr->theMainWindow = mainWindow;
+}
+
+QMainWindow *QtFullToolBarManager::mainWindow() const
+{
+ return d_ptr->theMainWindow;
+}
+
+void QtFullToolBarManager::addCategory(const QString &category)
+{
+ d_ptr->categoryToActions[category] = QList<QAction *>();
+}
+
+bool QtFullToolBarManager::hasCategory(const QString &category) const
+{
+ return d_ptr->categoryToActions.contains(category);
+}
+
+QStringList QtFullToolBarManager::categories() const
+{
+ return d_ptr->categoryToActions.keys();
+}
+
+QList<QAction *> QtFullToolBarManager::categoryActions(const QString &category) const
+{
+ QMap<QString, QList<QAction *> >::ConstIterator it =
+ d_ptr->categoryToActions.find(category);
+ if (it != d_ptr->categoryToActions.constEnd())
+ return it.value();
+ return QList<QAction *>();
+}
+
+QString QtFullToolBarManager::actionCategory(QAction *action) const
+{
+ QMap<QAction *, QString>::ConstIterator it = d_ptr->actionToCategory.find(action);
+ if (it != d_ptr->actionToCategory.constEnd())
+ return it.value();
+ return QString();
+}
+
+void QtFullToolBarManager::addAction(QAction *action, const QString &category)
+{
+ if (!action)
+ return;
+ if (action->isSeparator())
+ return;
+ if (d_ptr->allActions.contains(action))
+ return;
+ if (QLatin1String(action->metaObject()->className()) ==
+ QLatin1String("QToolBarWidgetAction"))
+ d_ptr->widgetActions.insert(action, 0);
+ else
+ d_ptr->regularActions.insert(action);
+ d_ptr->allActions.insert(action);
+ d_ptr->categoryToActions[category].append(action);
+ d_ptr->actionToCategory[action] = category;
+}
+
+void QtFullToolBarManager::removeAction(QAction *action)
+{
+ if (!d_ptr->allActions.contains(action))
+ return;
+
+ QList<QToolBar *> toolBars = d_ptr->actionToToolBars[action];
+ QListIterator<QToolBar *> itToolBar(toolBars);
+ while (itToolBar.hasNext()) {
+ QToolBar *toolBar = itToolBar.next();
+
+ d_ptr->toolBars[toolBar].removeAll(action);
+ d_ptr->toolBarsWithSeparators[toolBar].removeAll(action);
+
+ toolBar->removeAction(action);
+ }
+
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itDefault =
+ d_ptr->defaultToolBars.constBegin();
+ while (itDefault != d_ptr->defaultToolBars.constEnd()) {
+ if (itDefault.value().contains(action))
+ d_ptr->defaultToolBars[itDefault.key()].removeAll(action);
+
+ itDefault++;
+ }
+
+ d_ptr->allActions.remove(action);
+ d_ptr->widgetActions.remove(action);
+ d_ptr->regularActions.remove(action);
+ d_ptr->actionToToolBars.remove(action);
+
+ QString category = d_ptr->actionToCategory.value(action);
+ d_ptr->actionToCategory.remove(action);
+ d_ptr->categoryToActions[category].removeAll(action);
+
+ if (d_ptr->categoryToActions[category].isEmpty())
+ d_ptr->categoryToActions.remove(category);
+}
+
+QSet<QAction *> QtFullToolBarManager::actions() const
+{
+ return d_ptr->allActions;
+}
+
+bool QtFullToolBarManager::isWidgetAction(QAction *action) const
+{
+ if (d_ptr->widgetActions.contains(action))
+ return true;
+ return false;
+}
+
+void QtFullToolBarManager::addDefaultToolBar(QToolBar *toolBar, const QString &category)
+{
+ if (!toolBar)
+ return;
+ if (d_ptr->toolBars.contains(toolBar))
+ return;
+ // could be also checked if toolBar belongs to mainwindow
+
+ QList<QAction *> newActionsWithSeparators;
+ QList<QAction *> newActions;
+ QList<QAction *> actions = toolBar->actions();
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ addAction(action, category);
+ if (d_ptr->widgetActions.contains(action))
+ d_ptr->widgetActions.insert(action, toolBar);
+ newActionsWithSeparators.append(action);
+ if (action->isSeparator())
+ action = 0;
+ else
+ d_ptr->actionToToolBars[action].append(toolBar);
+ newActions.append(action);
+ }
+ d_ptr->defaultToolBars.insert(toolBar, newActions);
+ //Below could be done by call setToolBar() if we want signal emission here.
+ d_ptr->toolBars.insert(toolBar, newActions);
+ d_ptr->toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
+}
+
+void QtFullToolBarManager::removeDefaultToolBar(QToolBar *toolBar)
+{
+ if (!d_ptr->defaultToolBars.contains(toolBar))
+ return;
+
+ QList<QAction *> defaultActions = d_ptr->defaultToolBars[toolBar];
+ setToolBar(toolBar, QList<QAction *>());
+ QListIterator<QAction *> itAction(defaultActions);
+ while (itAction.hasNext())
+ removeAction(itAction.next());
+
+ d_ptr->toolBars.remove(toolBar);
+ d_ptr->toolBarsWithSeparators.remove(toolBar);
+ d_ptr->defaultToolBars.remove(toolBar);
+
+ itAction.toFront();
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (action)
+ toolBar->insertAction(0, action);
+ else
+ toolBar->insertSeparator(0);
+ }
+}
+
+QMap<QToolBar *, QList<QAction *> > QtFullToolBarManager::defaultToolBars() const
+{
+ return d_ptr->defaultToolBars;
+}
+
+bool QtFullToolBarManager::isDefaultToolBar(QToolBar *toolBar) const
+{
+ if (d_ptr->defaultToolBars.contains(toolBar))
+ return true;
+ return false;
+}
+
+QToolBar *QtFullToolBarManager::createToolBar(const QString &toolBarName)
+{
+ if (!mainWindow())
+ return 0;
+ QToolBar *toolBar = new QToolBar(toolBarName, mainWindow());
+ int i = 1;
+ const QString prefix = QLatin1String("_Custom_Toolbar_%1");
+ QString name = prefix.arg(i);
+ while (d_ptr->toolBarByName(name))
+ name = prefix.arg(++i);
+ toolBar->setObjectName(name);
+ mainWindow()->addToolBar(toolBar);
+ d_ptr->customToolBars.append(toolBar);
+ d_ptr->toolBars.insert(toolBar, QList<QAction *>());
+ d_ptr->toolBarsWithSeparators.insert(toolBar, QList<QAction *>());
+ return toolBar;
+}
+
+void QtFullToolBarManager::deleteToolBar(QToolBar *toolBar)
+{
+ if (!d_ptr->toolBars.contains(toolBar))
+ return;
+ if (d_ptr->defaultToolBars.contains(toolBar))
+ return;
+ setToolBar(toolBar, QList<QAction *>());
+ d_ptr->customToolBars.removeAll(toolBar);
+ d_ptr->toolBars.remove(toolBar);
+ d_ptr->toolBarsWithSeparators.remove(toolBar);
+ delete toolBar;
+}
+
+QList<QAction *> QtFullToolBarManager::actions(QToolBar *toolBar) const
+{
+ if (d_ptr->toolBars.contains(toolBar))
+ return d_ptr->toolBars.value(toolBar);
+ return QList<QAction *>();
+}
+
+void QtFullToolBarManager::setToolBars(const QMap<QToolBar *, QList<QAction *> > &actions)
+{
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator it = actions.constBegin();
+ while (it != actions.constEnd()) {
+ setToolBar(it.key(), it.value());
+ ++it;
+ }
+}
+
+void QtFullToolBarManager::setToolBar(QToolBar *toolBar, const QList<QAction *> &actions)
+{
+ if (!toolBar)
+ return;
+ if (!d_ptr->toolBars.contains(toolBar))
+ return;
+
+ if (actions == d_ptr->toolBars[toolBar])
+ return;
+
+ QMap<QToolBar *, QList<QAction *> > toRemove;
+
+ QList<QAction *> newActions;
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (!action || (!newActions.contains(action) && d_ptr->allActions.contains(action)))
+ newActions.append(action);
+
+ QToolBar *oldToolBar = d_ptr->toolBarWidgetAction(action);
+ if (oldToolBar && oldToolBar != toolBar)
+ toRemove[oldToolBar].append(action);
+ }
+
+ d_ptr->removeWidgetActions(toRemove);
+
+ QList<QAction *> oldActions = d_ptr->toolBarsWithSeparators.value(toolBar);
+ QListIterator<QAction *> itOldAction(oldActions);
+ while (itOldAction.hasNext()) {
+ QAction *action = itOldAction.next();
+ /*
+ When addDefaultToolBar() separator actions could be checked if they are
+ inserted in other toolbars - if yes then create new one.
+ */
+ if (d_ptr->toolBarWidgetAction(action) == toolBar)
+ d_ptr->widgetActions.insert(action, 0);
+ toolBar->removeAction(action);
+ if (action->isSeparator())
+ delete action;
+ else
+ d_ptr->actionToToolBars[action].removeAll(toolBar);
+ }
+
+ QList<QAction *> newActionsWithSeparators;
+ QListIterator<QAction *> itNewActions(newActions);
+ while (itNewActions.hasNext()) {
+ QAction *action = itNewActions.next();
+ QAction *newAction = 0;
+ if (!action)
+ newAction = toolBar->insertSeparator(0);
+ if (d_ptr->allActions.contains(action)) {
+ toolBar->insertAction(0, action);
+ newAction = action;
+ d_ptr->actionToToolBars[action].append(toolBar);
+ }
+ newActionsWithSeparators.append(newAction);
+ }
+ d_ptr->toolBars.insert(toolBar, newActions);
+ d_ptr->toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
+}
+
+QMap<QToolBar *, QList<QAction *> > QtFullToolBarManager::toolBarsActions() const
+{
+ return d_ptr->toolBars;
+}
+
+void QtFullToolBarManager::resetToolBar(QToolBar *toolBar)
+{
+ if (!isDefaultToolBar(toolBar))
+ return;
+ setToolBar(toolBar, defaultToolBars().value(toolBar));
+}
+
+void QtFullToolBarManager::resetAllToolBars()
+{
+ setToolBars(defaultToolBars());
+ QList<QToolBar *> oldCustomToolBars = d_ptr->customToolBars;
+ QListIterator<QToolBar *> itToolBar(oldCustomToolBars);
+ while (itToolBar.hasNext()) {
+ deleteToolBar(itToolBar.next());
+ }
+}
+
+QByteArray QtFullToolBarManager::saveState(int version) const
+{
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << QtFullToolBarManagerPrivate::VersionMarker;
+ stream << version;
+ d_ptr->saveState(stream);
+ return data;
+}
+
+bool QtFullToolBarManager::restoreState(const QByteArray &state, int version)
+{
+ QByteArray sd = state;
+ QDataStream stream(&sd, QIODevice::ReadOnly);
+ int marker, v;
+ stream >> marker;
+ stream >> v;
+ if (marker != QtFullToolBarManagerPrivate::VersionMarker || v != version)
+ return false;
+ return d_ptr->restoreState(stream);
+}
+
+
+class QtToolBarManagerPrivate
+{
+ class QtToolBarManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtToolBarManager)
+public:
+ QtFullToolBarManager *manager;
+};
+
+//////////////////////////////////////
+
+/*! \class QtToolBarManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtToolBarManager class provides toolbar management for
+ main windows.
+
+ The QtToolBarManager is typically used with a QtToolBarDialog
+ which allows the user to customize the toolbars for a given main
+ window. The QtToolBarDialog class's functionality is controlled by
+ an instance of the QtToolBarManager class, and the main window is
+ specified using the QtToolBarManager class's setMainWindow()
+ function.
+
+ The currently specified main window can be retrieved using the
+ mainWindow() function.
+
+ The toolbar manager holds lists of the given main window's actions
+ and toolbars, and can add actions and toolbars to these
+ lists using the addAction() and addToolBar() functions
+ respectively. The actions can in addition be categorized
+ acccording to the user's preferences. The toolbar manager can also
+ remove custom actions and toolbars using the removeAction() and
+ removeToolBar() functions.
+
+ Finally, the QtToolBarManager is able to save the customized state
+ of its toolbars using the saveState() function as well as restore
+ the toolbars' saved state using restoreState() function.
+
+ \sa QtToolBarDialog
+*/
+
+/*!
+ Creates a toolbar manager with the given \a parent.
+*/
+QtToolBarManager::QtToolBarManager(QObject *parent)
+ : QObject(parent), d_ptr(new QtToolBarManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->manager = new QtFullToolBarManager(this);
+}
+
+/*!
+ Destroys the toolbar manager.
+*/
+QtToolBarManager::~QtToolBarManager()
+{
+}
+
+/*!
+ Sets the main window upon which the toolbar manager operates, to
+ be the given \a mainWindow.
+*/
+void QtToolBarManager::setMainWindow(QMainWindow *mainWindow)
+{
+ d_ptr->manager->setMainWindow(mainWindow);
+}
+
+/*!
+ Returns the main window associated this toolbar manager.
+*/
+QMainWindow *QtToolBarManager::mainWindow() const
+{
+ return d_ptr->manager->mainWindow();
+}
+
+/*!
+ Adds the given \a action to the given \a category in the manager's
+ list of actions. If the \a category doesn't exist it is created.
+ Only non separator actions can be added. If the action is already
+ added to the list, the function doesn't do anything.
+
+ \sa removeAction()
+*/
+void QtToolBarManager::addAction(QAction *action, const QString &category)
+{
+ d_ptr->manager->addAction(action, category);
+}
+
+/*!
+ Removes the specified \a action from the manager's list of
+ actions. The action is also removed from all the registered
+ toolbars. If the specified \a action is the only action in its
+ category, that category is removed as well.
+
+ \sa addAction()
+*/
+void QtToolBarManager::removeAction(QAction *action)
+{
+ d_ptr->manager->removeAction(action);
+}
+
+/*!
+ Adds the given \a toolBar to the manager's toolbar list.
+
+ All the \a toolBar's actions are automatically added to the given
+ \a category in the manager's list of actions if they're not
+ already there. The manager remembers which toolbar the actions
+ belonged to, so, when the \a toolBar is removed, its actions will
+ be removed as well.
+
+ Custom toolbars are created with the main window returned by
+ the mainWindow() function, as its parent.
+
+ \sa removeToolBar()
+*/
+void QtToolBarManager::addToolBar(QToolBar *toolBar, const QString &category)
+{
+ d_ptr->manager->addDefaultToolBar(toolBar, category);
+}
+
+/*!
+ Removes the specified \a toolBar from the manager's list. All the
+ actions that existed in the specified \a toolBar when it was
+ added are removed as well.
+
+ \sa addToolBar()
+*/
+void QtToolBarManager::removeToolBar(QToolBar *toolBar)
+{
+ d_ptr->manager->removeDefaultToolBar(toolBar);
+}
+
+/*!
+ Returns the manager's toolbar list.
+*/
+QList<QToolBar *> QtToolBarManager::toolBars() const
+{
+ return d_ptr->manager->toolBarsActions().keys();
+}
+
+/*
+void QtToolBarManager::resetToolBar(QToolBar *toolBar)
+{
+ d_ptr->manager->resetToolBar(toolBar);
+}
+
+void QtToolBarManager::resetAllToolBars()
+{
+ d_ptr->manager->resetAllToolBars();
+}
+*/
+
+/*!
+ Saves the state of the toolbar manager's toolbars. The \a version
+ number is stored as part of the data.
+
+ Identifies all the QToolBar and QAction objects by their object
+ name property. Ensure that this property is unique for each
+ QToolBar and QAction that you add using the QtToolBarManager.
+
+ Returns an identifier for the state which can be passed along with
+ the version number to the restoreState() function to restore the
+ saved state.
+
+ \sa restoreState()
+*/
+QByteArray QtToolBarManager::saveState(int version) const
+{
+ return d_ptr->manager->saveState(version);
+}
+
+/*!
+ Restores the saved state of the toolbar manager's toolbars. The
+ \a version number is compared with the version number of the
+ stored \a state.
+
+ Returns true if the version numbers are matching and the toolbar
+ manager's state is restored; otherwise the toolbar manager's state
+ is left unchanged and the function returns false.
+
+ Note that the state of the toolbar manager's toolbars should be
+ restored before restoring the state of the main window's toolbars
+ and dockwidgets using the QMainWindow::restoreState() function. In
+ that way the restoreState() function can create the custom
+ toolbars before the QMainWindow::restoreState() function restores
+ the custom toolbars' positions.
+
+ \sa saveState()
+*/
+bool QtToolBarManager::restoreState(const QByteArray &state, int version)
+{
+ return d_ptr->manager->restoreState(state, version);
+}
+
+//////////////////////
+
+class ToolBarItem {
+public:
+ ToolBarItem() : tb(0) {}
+ ToolBarItem(QToolBar *toolBar) : tb(toolBar) {}
+ ToolBarItem(QToolBar *toolBar, const QString &toolBarName)
+ : tb(toolBar), tbName(toolBarName) {}
+ ToolBarItem(const QString &toolBarName) : tb(0), tbName(toolBarName) {}
+ QToolBar *toolBar() const
+ { return tb; }
+ void setToolBar(QToolBar *toolBar)
+ { tb = toolBar; }
+ QString toolBarName() const
+ { return tbName; }
+ void setToolBarName(const QString &toolBarName)
+ { tbName = toolBarName; }
+private:
+ QToolBar *tb;
+ QString tbName;
+};
+
+class QtToolBarDialogPrivate {
+ QtToolBarDialog *q_ptr;
+ Q_DECLARE_PUBLIC(QtToolBarDialog)
+public:
+ QtToolBarDialogPrivate()
+ : toolBarManager(0),
+ currentAction(0),
+ currentToolBar(0)
+ { }
+
+ ToolBarItem *createItem(QToolBar *toolBar);
+ ToolBarItem *createItem(const QString &toolBarName);
+ void deleteItem(ToolBarItem *item);
+
+ void newClicked();
+ void removeClicked();
+ void defaultClicked();
+ void okClicked();
+ void applyClicked();
+ void cancelClicked();
+ void upClicked();
+ void downClicked();
+ void leftClicked();
+ void rightClicked();
+ void renameClicked();
+ void toolBarRenamed(QListWidgetItem *item);
+ void currentActionChanged(QTreeWidgetItem *current);
+ void currentToolBarChanged(QListWidgetItem *current);
+ void currentToolBarActionChanged(QListWidgetItem *current);
+
+ void removeToolBar(ToolBarItem *item);
+ bool isDefaultToolBar(ToolBarItem *item) const;
+ void setButtons();
+ void clearOld();
+ void fillNew();
+ QtFullToolBarManager *toolBarManager;
+ QMap<ToolBarItem *, QList<QAction *> > currentState;
+ QMap<QToolBar *, ToolBarItem *> toolBarItems;
+ QSet<ToolBarItem *> createdItems;
+ QSet<ToolBarItem *> removedItems;
+
+ QSet<ToolBarItem *> allToolBarItems;
+
+ // static
+ QTreeWidgetItem *currentAction;
+ QMap<QAction *, QTreeWidgetItem *> actionToItem;
+ QMap<QTreeWidgetItem *, QAction *> itemToAction;
+
+ // dynamic
+ ToolBarItem *currentToolBar;
+ QMap<ToolBarItem *, QListWidgetItem *> toolBarToItem;
+ QMap<QListWidgetItem *, ToolBarItem *> itemToToolBar;
+
+ // dynamic
+ QMap<QAction *, QListWidgetItem *> actionToCurrentItem;
+ QMap<QListWidgetItem *, QAction *> currentItemToAction;
+
+ QMap<QAction *, ToolBarItem *> widgetActionToToolBar;
+ QMap<ToolBarItem *, QSet<QAction *> > toolBarToWidgetActions;
+
+ QString separatorText;
+ Ui::QtToolBarDialog ui;
+};
+
+ToolBarItem *QtToolBarDialogPrivate::createItem(QToolBar *toolBar)
+{
+ if (!toolBar)
+ return 0;
+ ToolBarItem *item = new ToolBarItem(toolBar, toolBar->windowTitle());
+ allToolBarItems.insert(item);
+ return item;
+}
+
+ToolBarItem *QtToolBarDialogPrivate::createItem(const QString &toolBarName)
+{
+ ToolBarItem *item = new ToolBarItem(toolBarName);
+ allToolBarItems.insert(item);
+ return item;
+}
+
+void QtToolBarDialogPrivate::deleteItem(ToolBarItem *item)
+{
+ if (!allToolBarItems.contains(item))
+ return;
+ allToolBarItems.remove(item);
+ delete item;
+}
+
+void QtToolBarDialogPrivate::clearOld()
+{
+ ui.actionTree->clear();
+ ui.toolBarList->clear();
+ ui.currentToolBarList->clear();
+ ui.removeButton->setEnabled(false);
+ ui.newButton->setEnabled(false);
+ ui.upButton->setEnabled(false);
+ ui.downButton->setEnabled(false);
+ ui.leftButton->setEnabled(false);
+ ui.rightButton->setEnabled(false);
+
+ actionToItem.clear();
+ itemToAction.clear();
+ toolBarToItem.clear();
+ itemToToolBar.clear();
+ actionToCurrentItem.clear();
+ currentItemToAction.clear();
+ widgetActionToToolBar.clear();
+ toolBarToWidgetActions.clear();
+
+ toolBarItems.clear();
+ currentState.clear();
+ createdItems.clear();
+ removedItems.clear();
+ QSetIterator<ToolBarItem *> itItem(allToolBarItems);
+ while (itItem.hasNext())
+ delete itItem.next();
+ allToolBarItems.clear();
+
+ currentToolBar = 0;
+ currentAction = 0;
+}
+
+void QtToolBarDialogPrivate::fillNew()
+{
+ if (!toolBarManager)
+ return;
+
+ QTreeWidgetItem *item = new QTreeWidgetItem(ui.actionTree);
+ item->setText(0, separatorText);
+ ui.actionTree->setCurrentItem(item);
+ currentAction = item;
+ actionToItem.insert(0, item);
+ itemToAction.insert(item, 0);
+ QStringList categories = toolBarManager->categories();
+ QStringListIterator itCategory(categories);
+ while (itCategory.hasNext()) {
+ QString category = itCategory.next();
+ QTreeWidgetItem *categoryItem = new QTreeWidgetItem(ui.actionTree);
+ categoryItem->setText(0, category);
+ QList<QAction *> actions = toolBarManager->categoryActions(category);
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ item = new QTreeWidgetItem(categoryItem);
+ item->setText(0, action->text());
+ item->setIcon(0, action->icon());
+ item->setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic);
+ actionToItem.insert(action, item);
+ itemToAction.insert(item, action);
+ if (toolBarManager->isWidgetAction(action)) {
+ item->setData(0, Qt::TextColorRole, QColor(Qt::blue));
+ widgetActionToToolBar.insert(action, 0);
+ }
+ item->setFlags(item->flags() | Qt::ItemIsDragEnabled);
+ }
+ ui.actionTree->setItemExpanded(categoryItem, true);
+ }
+ //ui.actionTree->sortItems(0, Qt::AscendingOrder);
+
+ QMap<QToolBar *, QList<QAction *> > toolBars = toolBarManager->toolBarsActions();
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator it = toolBars.constBegin();
+ while (it != toolBars.constEnd()) {
+ QToolBar *toolBar = it.key();
+ ToolBarItem *tbItem = createItem(toolBar);
+ toolBarItems.insert(toolBar, tbItem);
+ QListWidgetItem *item = new QListWidgetItem(toolBar->windowTitle(),
+ ui.toolBarList);
+ toolBarToItem.insert(tbItem, item);
+ itemToToolBar.insert(item, tbItem);
+ QList<QAction *> actions = it.value();
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (toolBarManager->isWidgetAction(action)) {
+ widgetActionToToolBar.insert(action, tbItem);
+ toolBarToWidgetActions[tbItem].insert(action);
+ }
+ }
+ currentState.insert(tbItem, actions);
+ if (it == toolBars.constBegin())
+ ui.toolBarList->setCurrentItem(item);
+ if (isDefaultToolBar(tbItem))
+ item->setData(Qt::TextColorRole, QColor(Qt::darkGreen));
+ else
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+
+ ++it;
+ }
+ ui.toolBarList->sortItems();
+ setButtons();
+}
+
+bool QtToolBarDialogPrivate::isDefaultToolBar(ToolBarItem *item) const
+{
+ if (!item)
+ return false;
+ if (!item->toolBar())
+ return false;
+ return toolBarManager->isDefaultToolBar(item->toolBar());
+}
+
+void QtToolBarDialogPrivate::setButtons()
+{
+ bool newEnabled = false;
+ bool removeEnabled = false;
+ bool renameEnabled = false;
+ bool upEnabled = false;
+ bool downEnabled = false;
+ bool leftEnabled = false;
+ bool rightEnabled = false;
+
+ if (toolBarManager) {
+ newEnabled = true;
+ removeEnabled = !isDefaultToolBar(currentToolBar);
+ renameEnabled = removeEnabled;
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+ if (currentToolBarAction) {
+ int row = ui.currentToolBarList->row(currentToolBarAction);
+ upEnabled = row > 0;
+ downEnabled = row < ui.currentToolBarList->count() - 1;
+ leftEnabled = true;
+ }
+ if (currentAction && currentToolBar)
+ rightEnabled = true;
+ }
+ ui.newButton->setEnabled(newEnabled);
+ ui.removeButton->setEnabled(removeEnabled);
+ ui.renameButton->setEnabled(renameEnabled);
+ ui.upButton->setEnabled(upEnabled);
+ ui.downButton->setEnabled(downEnabled);
+ ui.leftButton->setEnabled(leftEnabled);
+ ui.rightButton->setEnabled(rightEnabled);
+}
+
+void QtToolBarDialogPrivate::newClicked()
+{
+ QString toolBarName = QtToolBarDialog::tr("Custom Toolbar"); // = QInputDialog::getString();
+ // produce unique name
+ ToolBarItem *item = createItem(toolBarName);
+ currentState.insert(item, QList<QAction *>());
+ createdItems.insert(item);
+ QListWidgetItem *i = new QListWidgetItem(toolBarName, ui.toolBarList);
+ i->setFlags(i->flags() | Qt::ItemIsEditable);
+ ui.toolBarList->setCurrentItem(i);
+ itemToToolBar.insert(i, item);
+ toolBarToItem.insert(item, i);
+ ui.toolBarList->sortItems();
+ ui.toolBarList->setCurrentItem(i);
+ currentToolBarChanged(i);
+ renameClicked();
+}
+
+void QtToolBarDialogPrivate::removeToolBar(ToolBarItem *item)
+{
+ if (!item)
+ return;
+ if (item->toolBar() && toolBarManager->isDefaultToolBar(item->toolBar()))
+ return;
+ if (!toolBarToItem.contains(item))
+ return;
+ QListWidgetItem *i = toolBarToItem.value(item);
+ bool wasCurrent = false;
+ if (i == ui.toolBarList->currentItem())
+ wasCurrent = true;
+ int row = ui.toolBarList->row(i);
+ QMap<ToolBarItem *, QSet<QAction *> >::ConstIterator itToolBar =
+ toolBarToWidgetActions.find(item);
+ if (itToolBar != toolBarToWidgetActions.constEnd()) {
+ QSet<QAction *> actions = itToolBar.value();
+ QSetIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ widgetActionToToolBar.insert(action, 0);
+ }
+ toolBarToWidgetActions.remove(item);
+ }
+
+ currentState.remove(item);
+ createdItems.remove(item);
+ toolBarToItem.remove(item);
+ itemToToolBar.remove(i);
+ delete i;
+ if (item->toolBar())
+ removedItems.insert(item);
+ else
+ deleteItem(item);
+ if (wasCurrent) {
+ if (row == ui.toolBarList->count())
+ row--;
+ if (row < 0)
+ ;
+ else
+ ui.toolBarList->setCurrentRow(row);
+ }
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::removeClicked()
+{
+ QListWidgetItem *i = ui.toolBarList->currentItem();
+ if (!i)
+ return;
+ ToolBarItem *item = itemToToolBar.value(i);
+ removeToolBar(item);
+}
+
+void QtToolBarDialogPrivate::defaultClicked()
+{
+ QMap<QToolBar *, QList<QAction *> > defaultToolBars = toolBarManager->defaultToolBars();
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = defaultToolBars.constBegin();
+ while (itToolBar != defaultToolBars.constEnd()) {
+ QToolBar *toolBar = itToolBar.key();
+ ToolBarItem *toolBarItem = toolBarItems.value(toolBar);
+
+ if (toolBarToWidgetActions.contains(toolBarItem)) {
+ QSetIterator<QAction *> itAction(toolBarToWidgetActions.value(toolBarItem));
+ while (itAction.hasNext())
+ widgetActionToToolBar.insert(itAction.next(), 0);
+ toolBarToWidgetActions.remove(toolBarItem);
+ }
+
+ currentState.remove(toolBarItem);
+
+ QListIterator<QAction *> itAction(itToolBar.value());
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (toolBarManager->isWidgetAction(action)) {
+ ToolBarItem *otherToolBar = widgetActionToToolBar.value(action);
+ if (otherToolBar) {
+ toolBarToWidgetActions[otherToolBar].remove(action);
+ currentState[otherToolBar].removeAll(action);
+ }
+ widgetActionToToolBar.insert(action, toolBarItem);
+ toolBarToWidgetActions[toolBarItem].insert(action);
+ }
+ }
+ currentState.insert(toolBarItem, itToolBar.value());
+
+ ++itToolBar;
+ }
+ currentToolBarChanged(toolBarToItem.value(currentToolBar));
+
+ QList<ToolBarItem *> toolBars = currentState.keys();
+ QListIterator<ToolBarItem *> itTb(toolBars);
+ while (itTb.hasNext())
+ removeToolBar(itTb.next());
+}
+
+void QtToolBarDialogPrivate::okClicked()
+{
+ applyClicked();
+ q_ptr->accept();
+}
+
+void QtToolBarDialogPrivate::applyClicked()
+{
+ QMap<ToolBarItem *, QList<QAction *> > toolBars = currentState;
+ QMap<ToolBarItem *, QList<QAction *> >::ConstIterator itToolBar = toolBars.constBegin();
+ while (itToolBar != toolBars.constEnd()) {
+ ToolBarItem *item = itToolBar.key();
+ QToolBar *toolBar = item->toolBar();
+ if (toolBar) {
+ toolBarManager->setToolBar(toolBar, itToolBar.value());
+ toolBar->setWindowTitle(item->toolBarName());
+ }
+
+ ++itToolBar;
+ }
+
+ QSet<ToolBarItem *> toRemove = removedItems;
+ QSetIterator<ToolBarItem *> itRemove(toRemove);
+ while (itRemove.hasNext()) {
+ ToolBarItem *item = itRemove.next();
+ QToolBar *toolBar = item->toolBar();
+ removedItems.remove(item);
+ currentState.remove(item);
+ deleteItem(item);
+ if (toolBar)
+ toolBarManager->deleteToolBar(toolBar);
+ }
+
+ QSet<ToolBarItem *> toCreate = createdItems;
+ QSetIterator<ToolBarItem *> itCreate(toCreate);
+ while (itCreate.hasNext()) {
+ ToolBarItem *item = itCreate.next();
+ QString toolBarName = item->toolBarName();
+ createdItems.remove(item);
+ QList<QAction *> actions = currentState.value(item);
+ QToolBar *toolBar = toolBarManager->createToolBar(toolBarName);
+ item->setToolBar(toolBar);
+ toolBarManager->setToolBar(toolBar, actions);
+ }
+}
+
+void QtToolBarDialogPrivate::upClicked()
+{
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+ if (!currentToolBarAction)
+ return;
+ int row = ui.currentToolBarList->row(currentToolBarAction);
+ if (row == 0)
+ return;
+ ui.currentToolBarList->takeItem(row);
+ int newRow = row - 1;
+ ui.currentToolBarList->insertItem(newRow, currentToolBarAction);
+ QList<QAction *> actions = currentState.value(currentToolBar);
+ QAction *action = actions.at(row);
+ actions.removeAt(row);
+ actions.insert(newRow, action);
+ currentState.insert(currentToolBar, actions);
+ ui.currentToolBarList->setCurrentItem(currentToolBarAction);
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::downClicked()
+{
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+ if (!currentToolBarAction)
+ return;
+ int row = ui.currentToolBarList->row(currentToolBarAction);
+ if (row == ui.currentToolBarList->count() - 1)
+ return;
+ ui.currentToolBarList->takeItem(row);
+ int newRow = row + 1;
+ ui.currentToolBarList->insertItem(newRow, currentToolBarAction);
+ QList<QAction *> actions = currentState.value(currentToolBar);
+ QAction *action = actions.at(row);
+ actions.removeAt(row);
+ actions.insert(newRow, action);
+ currentState.insert(currentToolBar, actions);
+ ui.currentToolBarList->setCurrentItem(currentToolBarAction);
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::leftClicked()
+{
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+ if (!currentToolBarAction)
+ return;
+ int row = ui.currentToolBarList->row(currentToolBarAction);
+ currentState[currentToolBar].removeAt(row);
+ QAction *action = currentItemToAction.value(currentToolBarAction);
+ if (widgetActionToToolBar.contains(action)) {
+ ToolBarItem *item = widgetActionToToolBar.value(action);
+ if (item == currentToolBar) { // have to be
+ toolBarToWidgetActions[item].remove(action);
+ if (toolBarToWidgetActions[item].empty())
+ toolBarToWidgetActions.remove(item);
+ }
+ widgetActionToToolBar.insert(action, 0);
+ }
+ if (action)
+ actionToCurrentItem.remove(action);
+ currentItemToAction.remove(currentToolBarAction);
+ delete currentToolBarAction;
+ if (row == ui.currentToolBarList->count())
+ row--;
+ if (row >= 0) {
+ QListWidgetItem *item = ui.currentToolBarList->item(row);
+ ui.currentToolBarList->setCurrentItem(item);
+ }
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::rightClicked()
+{
+ if (!currentAction)
+ return;
+ if (!currentToolBar)
+ return;
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+
+ QAction *action = itemToAction.value(currentAction);
+ QListWidgetItem *item = 0;
+ if (action) {
+ if (currentState[currentToolBar].contains(action)) {
+ item = actionToCurrentItem.value(action);
+ if (item == currentToolBarAction)
+ return;
+ int row = ui.currentToolBarList->row(item);
+ ui.currentToolBarList->takeItem(row);
+ currentState[currentToolBar].removeAt(row);
+ // only reorder here
+ } else {
+ item = new QListWidgetItem(action->text());
+ item->setIcon(action->icon());
+ item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic);
+ currentItemToAction.insert(item, action);
+ actionToCurrentItem.insert(action, item);
+ if (widgetActionToToolBar.contains(action)) {
+ item->setData(Qt::TextColorRole, QColor(Qt::blue));
+ ToolBarItem *toolBar = widgetActionToToolBar.value(action);
+ if (toolBar) {
+ currentState[toolBar].removeAll(action);
+ toolBarToWidgetActions[toolBar].remove(action);
+ if (toolBarToWidgetActions[toolBar].empty())
+ toolBarToWidgetActions.remove(toolBar);
+ }
+ widgetActionToToolBar.insert(action, currentToolBar);
+ toolBarToWidgetActions[currentToolBar].insert(action);
+ }
+ }
+ } else {
+ item = new QListWidgetItem(separatorText);
+ currentItemToAction.insert(item, 0);
+ }
+
+ int row = ui.currentToolBarList->count();
+ if (currentToolBarAction) {
+ row = ui.currentToolBarList->row(currentToolBarAction) + 1;
+ }
+ ui.currentToolBarList->insertItem(row, item);
+ currentState[currentToolBar].insert(row, action);
+ ui.currentToolBarList->setCurrentItem(item);
+
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::renameClicked()
+{
+ if (!currentToolBar)
+ return;
+
+ QListWidgetItem *item = toolBarToItem.value(currentToolBar);
+ ui.toolBarList->editItem(item);
+}
+
+void QtToolBarDialogPrivate::toolBarRenamed(QListWidgetItem *item)
+{
+ if (!currentToolBar)
+ return;
+
+ ToolBarItem *tbItem = itemToToolBar.value(item);
+ if (!tbItem)
+ return;
+ tbItem->setToolBarName(item->text());
+ //ui.toolBarList->sortItems();
+}
+
+void QtToolBarDialogPrivate::currentActionChanged(QTreeWidgetItem *current)
+{
+ if (itemToAction.contains(current))
+ currentAction = current;
+ else
+ currentAction = NULL;
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::currentToolBarChanged(QListWidgetItem *current)
+{
+ currentToolBar = itemToToolBar.value(current);
+ ui.currentToolBarList->clear();
+ actionToCurrentItem.clear();
+ currentItemToAction.clear();
+ setButtons();
+ if (!currentToolBar) {
+ return;
+ }
+ QList<QAction *> actions = currentState.value(currentToolBar);
+ QListIterator<QAction *> itAction(actions);
+ QListWidgetItem *first = 0;
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ QString actionName = separatorText;
+ if (action)
+ actionName = action->text();
+ QListWidgetItem *item = new QListWidgetItem(actionName, ui.currentToolBarList);
+ if (action) {
+ item->setIcon(action->icon());
+ item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic);
+ actionToCurrentItem.insert(action, item);
+ if (widgetActionToToolBar.contains(action))
+ item->setData(Qt::TextColorRole, QColor(Qt::blue));
+ }
+ currentItemToAction.insert(item, action);
+ if (!first)
+ first = item;
+ }
+ if (first)
+ ui.currentToolBarList->setCurrentItem(first);
+}
+
+void QtToolBarDialogPrivate::currentToolBarActionChanged(QListWidgetItem *)
+{
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::cancelClicked()
+{
+ // just nothing
+ q_ptr->reject();
+}
+
+//////////////////////
+/*
+class FeedbackItemDelegate : public QItemDelegate
+{
+ Q_OBJECT
+public:
+ FeedbackItemDelegate(QObject *parent = 0) : QItemDelegate(parent) { }
+
+ virtual void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex & index) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+};
+
+void FeedbackItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if ()
+ painter->save();
+ QRect r = option.rect;
+ float yCentral = r.height() / 2.0;
+ float margin = 2.0;
+ float arrowWidth = 5.0;
+ float width = 20;
+ qDebug("rect: x %d, y %d, w %d, h %d", r.x(), r.y(), r.width(), r.height());
+ QLineF lineBase(0.0 + margin, r.y() + yCentral, width - margin, r.y() + yCentral);
+ QLineF lineArrowLeft(width - margin - arrowWidth, r.y() + yCentral - arrowWidth,
+ width - margin, r.y() + yCentral);
+ QLineF lineArrowRight(width - margin - arrowWidth, r.y() + yCentral + arrowWidth,
+ width - margin, r.y() + yCentral);
+ painter->drawLine(lineBase);
+ painter->drawLine(lineArrowLeft);
+ painter->drawLine(lineArrowRight);
+ painter->translate(QPoint(width, 0));
+ QItemDelegate::paint(painter, option, index);
+ painter->restore();
+}
+
+QSize FeedbackItemDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ //return QItemDelegate::sizeHint(option, index);
+ QSize s = QItemDelegate::sizeHint(option, index);
+ s.setWidth(s.width() - 20);
+ return s;
+}
+
+class QtToolBarListWidget : public QListWidget
+{
+ Q_OBJECT
+public:
+ QtToolBarListWidget(QWidget *parent) : QListWidget(parent), actionDrag(false) {}
+
+protected:
+ void startDrag(Qt::DropActions supportedActions);
+
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *);
+ void dropEvent(QDropEvent *event);
+
+ void setDragAction(const QString *action) { actionName = action; }
+private:
+ QPersistentModelIndex lastDropIndicator;
+ QString actionName;
+ bool actionDrag;
+};
+
+void QtToolBarListWidget::startDrag(Qt::DropActions supportedActions)
+{
+ QListWidgetItem *item = currentItem();
+ if (item) {
+ actionName = QString();
+ emit aboutToDrag(item);
+ if (!actionName.isEmpty()) {
+ QDrag *drag = new QDrag(this);
+ QMimeData *data = new QMimeData;
+ data->setData("action", actionName.toLocal8Bit().constData());
+ drag->setMimeData(data);
+ drag->start(supportedActions);
+ }
+ }
+}
+
+void QtToolBarListWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ actionDrag = mime->hasFormat("action");
+ if (actionDrag)
+ event->accept();
+ else
+ event->ignore();
+}
+
+void QtToolBarListWidget::dragMoveEvent(QDragMoveEvent *event)
+{
+ event->ignore();
+ if (actionDrag) {
+ QPoint p = event->pos();
+ QListWidgetItem *item = itemAt(p);
+ Indicator indic = QtToolBarListWidget::None;
+ if (item) {
+ QRect rect = visualItemRect(item);
+ if (p.y() - rect.top() < rect.height() / 2)
+ indic = QtToolBarListWidget::Above;
+ else
+ indic = QtToolBarListWidget::Below;
+ }
+ setIndicator(item, indic);
+ event->accept();
+ }
+}
+
+void QtToolBarListWidget::dragLeaveEvent(QDragLeaveEvent *)
+{
+ if (actionDrag) {
+ actionDrag = false;
+ setIndicator(item, QtToolBarListWidget::None);
+ }
+}
+
+void QtToolBarListWidget::dropEvent(QDropEvent *event)
+{
+ if (actionDrag) {
+ QListWidgetItem *item = indicatorItem();
+ Indicator indic = indicator();
+ QByteArray array = event->mimeData()->data("action");
+ QDataStream stream(&array, QIODevice::ReadOnly);
+ QString action;
+ stream >> action;
+ emit actionDropped(action, item, );
+
+ actionDrag = false;
+ setIndicator(item, QtToolBarListWidget::None);
+ }
+}
+*/
+
+/*! \class QtToolBarDialog
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtToolBarDialog class provides a dialog for customizing
+ toolbars.
+
+ QtToolBarDialog allows the user to customize the toolbars for a
+ given main window.
+
+ \image qttoolbardialog.png
+
+ The dialog lets the users add, rename and remove custom toolbars.
+ Note that built-in toolbars are marked with a green color, and
+ cannot be removed or renamed.
+
+ The users can also add and remove actions from the toolbars. An
+ action can be added to many toolbars, but a toolbar can only
+ contain one instance of each action. Actions that contains a
+ widget are marked with a blue color in the list of actions, and
+ can only be added to one single toolbar.
+
+ Finally, the users can add separators to the toolbars.
+
+ The original toolbars can be restored by clicking the \gui
+ {Restore all} button. All custom toolbars will then be removed,
+ and all built-in toolbars will be restored to their original state.
+
+ The QtToolBarDialog class's functionality is controlled by an
+ instance of the QtToolBarManager class, and the main window is
+ specified using the QtToolBarManager::setMainWindow() function.
+
+ All you need to do to use QtToolBarDialog is to specify an
+ QtToolBarManager instance and call the QDialog::exec() slot:
+
+ \snippet doc/src/snippets/code/tools_shared_qttoolbardialog_qttoolbardialog.cpp 0
+
+ \sa QtToolBarManager
+*/
+
+/*!
+ Creates a toolbar dialog with the given \a parent and the specified
+ window \a flags.
+*/
+QtToolBarDialog::QtToolBarDialog(QWidget *parent, Qt::WindowFlags flags)
+ : QDialog(parent, flags), d_ptr(new QtToolBarDialogPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->ui.setupUi(this);
+ d_ptr->separatorText = tr("< S E P A R A T O R >");
+
+ d_ptr->ui.actionTree->setColumnCount(1);
+ d_ptr->ui.actionTree->setRootIsDecorated(false);
+ d_ptr->ui.actionTree->header()->hide();
+
+ d_ptr->ui.upButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/up.png")));
+ d_ptr->ui.downButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/down.png")));
+ d_ptr->ui.leftButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/back.png")));
+ d_ptr->ui.rightButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/forward.png")));
+ d_ptr->ui.newButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/plus.png")));
+ d_ptr->ui.removeButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/minus.png")));
+
+ connect(d_ptr->ui.newButton, SIGNAL(clicked()), this, SLOT(newClicked()));
+ connect(d_ptr->ui.removeButton, SIGNAL(clicked()), this, SLOT(removeClicked()));
+ connect(d_ptr->ui.renameButton, SIGNAL(clicked()), this, SLOT(renameClicked()));
+ connect(d_ptr->ui.upButton, SIGNAL(clicked()), this, SLOT(upClicked()));
+ connect(d_ptr->ui.downButton, SIGNAL(clicked()), this, SLOT(downClicked()));
+ connect(d_ptr->ui.leftButton, SIGNAL(clicked()), this, SLOT(leftClicked()));
+ connect(d_ptr->ui.rightButton, SIGNAL(clicked()), this, SLOT(rightClicked()));
+
+ connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()), this, SLOT(defaultClicked()));
+ connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(okClicked()));
+ connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyClicked()));
+ connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(cancelClicked()));
+
+ connect(d_ptr->ui.actionTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ this, SLOT(currentActionChanged(QTreeWidgetItem*)));
+ connect(d_ptr->ui.toolBarList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ this, SLOT(currentToolBarChanged(QListWidgetItem*)));
+ connect(d_ptr->ui.currentToolBarList,
+ SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ this, SLOT(currentToolBarActionChanged(QListWidgetItem*)));
+
+ connect(d_ptr->ui.actionTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
+ this, SLOT(rightClicked()));
+ connect(d_ptr->ui.currentToolBarList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
+ this, SLOT(leftClicked()));
+ connect(d_ptr->ui.toolBarList, SIGNAL(itemChanged(QListWidgetItem*)),
+ this, SLOT(toolBarRenamed(QListWidgetItem*)));
+}
+
+/*!
+ Destroys the toolbar dialog.
+*/
+QtToolBarDialog::~QtToolBarDialog()
+{
+ d_ptr->clearOld();
+}
+
+/*!
+ Connects the toolbar dialog to the given \a toolBarManager. Then,
+ when exec() is called, the toolbar dialog will operate using the
+ given \a toolBarManager.
+*/
+void QtToolBarDialog::setToolBarManager(QtToolBarManager *toolBarManager)
+{
+ if (d_ptr->toolBarManager == toolBarManager->d_ptr->manager)
+ return;
+ if (isVisible())
+ d_ptr->clearOld();
+ d_ptr->toolBarManager = toolBarManager->d_ptr->manager;
+ if (isVisible())
+ d_ptr->fillNew();
+}
+
+/*!
+ \reimp
+*/
+void QtToolBarDialog::showEvent(QShowEvent *event)
+{
+ if (!event->spontaneous())
+ d_ptr->fillNew();
+}
+
+/*!
+ \reimp
+*/
+void QtToolBarDialog::hideEvent(QHideEvent *event)
+{
+ if (!event->spontaneous())
+ d_ptr->clearOld();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qttoolbardialog.cpp"
+#include "qttoolbardialog.moc"
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.h b/src/shared/qttoolbardialog/qttoolbardialog.h
new file mode 100644
index 000000000..925662e4b
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QTTOOLBARDIALOG_H
+#define QTTOOLBARDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QMainWindow;
+class QAction;
+class QToolBar;
+
+class QtToolBarManagerPrivate;
+
+class QtToolBarManager : public QObject
+{
+ Q_OBJECT
+public:
+
+ explicit QtToolBarManager(QObject *parent = 0);
+ ~QtToolBarManager();
+
+ void setMainWindow(QMainWindow *mainWindow);
+ QMainWindow *mainWindow() const;
+
+ void addAction(QAction *action, const QString &category);
+ void removeAction(QAction *action);
+
+ void addToolBar(QToolBar *toolBar, const QString &category);
+ void removeToolBar(QToolBar *toolBar);
+
+ QList<QToolBar *> toolBars() const;
+
+ QByteArray saveState(int version = 0) const;
+ bool restoreState(const QByteArray &state, int version = 0);
+
+private:
+
+ friend class QtToolBarDialog;
+ QScopedPointer<QtToolBarManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtToolBarManager)
+ Q_DISABLE_COPY(QtToolBarManager)
+};
+
+class QtToolBarDialogPrivate;
+
+class QtToolBarDialog : public QDialog
+{
+ Q_OBJECT
+public:
+
+ explicit QtToolBarDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QtToolBarDialog();
+
+ void setToolBarManager(QtToolBarManager *toolBarManager);
+
+protected:
+
+ void showEvent(QShowEvent *event);
+ void hideEvent(QHideEvent *event);
+
+private:
+
+ QScopedPointer<QtToolBarDialogPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtToolBarDialog)
+ Q_DISABLE_COPY(QtToolBarDialog)
+
+ Q_PRIVATE_SLOT(d_func(), void newClicked())
+ Q_PRIVATE_SLOT(d_func(), void removeClicked())
+ Q_PRIVATE_SLOT(d_func(), void defaultClicked())
+ Q_PRIVATE_SLOT(d_func(), void okClicked())
+ Q_PRIVATE_SLOT(d_func(), void applyClicked())
+ Q_PRIVATE_SLOT(d_func(), void cancelClicked())
+ Q_PRIVATE_SLOT(d_func(), void upClicked())
+ Q_PRIVATE_SLOT(d_func(), void downClicked())
+ Q_PRIVATE_SLOT(d_func(), void leftClicked())
+ Q_PRIVATE_SLOT(d_func(), void rightClicked())
+ Q_PRIVATE_SLOT(d_func(), void renameClicked())
+ Q_PRIVATE_SLOT(d_func(), void toolBarRenamed(QListWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void currentActionChanged(QTreeWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void currentToolBarChanged(QListWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void currentToolBarActionChanged(QListWidgetItem *))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.pri b/src/shared/qttoolbardialog/qttoolbardialog.pri
new file mode 100644
index 000000000..5aca44757
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.pri
@@ -0,0 +1,6 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qttoolbardialog.cpp
+HEADERS += $$PWD/qttoolbardialog.h
+FORMS += $$PWD/qttoolbardialog.ui
+RESOURCES += $$PWD/qttoolbardialog.qrc
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.qrc b/src/shared/qttoolbardialog/qttoolbardialog.qrc
new file mode 100644
index 000000000..ce0336682
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.qrc
@@ -0,0 +1,10 @@
+<RCC version="1.0">
+ <qresource prefix="/trolltech/qttoolbardialog">
+ <file>images/up.png</file>
+ <file>images/down.png</file>
+ <file>images/forward.png</file>
+ <file>images/back.png</file>
+ <file>images/plus.png</file>
+ <file>images/minus.png</file>
+ </qresource>
+</RCC>
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.ui b/src/shared/qttoolbardialog/qttoolbardialog.ui
new file mode 100644
index 000000000..c4ad934f8
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.ui
@@ -0,0 +1,207 @@
+<ui version="4.0" >
+ <class>QtToolBarDialog</class>
+ <widget class="QDialog" name="QtToolBarDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>583</width>
+ <height>508</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Customize Toolbars</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item rowspan="3" row="1" column="0" >
+ <widget class="QTreeWidget" name="actionTree" >
+ <column>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Actions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Toolbars</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newButton" >
+ <property name="toolTip" >
+ <string>Add new toolbar</string>
+ </property>
+ <property name="text" >
+ <string>New</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeButton" >
+ <property name="toolTip" >
+ <string>Remove selected toolbar</string>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="renameButton" >
+ <property name="toolTip" >
+ <string>Rename toolbar</string>
+ </property>
+ <property name="text" >
+ <string>Rename</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="1" >
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="upButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Move action up</string>
+ </property>
+ <property name="text" >
+ <string>Up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="leftButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Remove action from toolbar</string>
+ </property>
+ <property name="text" >
+ <string>&lt;-</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="rightButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Add action to toolbar</string>
+ </property>
+ <property name="text" >
+ <string>-></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="downButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Move action down</string>
+ </property>
+ <property name="text" >
+ <string>Down</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>29</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="2" >
+ <widget class="QListWidget" name="currentToolBarList" />
+ </item>
+ <item row="2" column="1" colspan="2" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Current Toolbar Actions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2" >
+ <widget class="QListWidget" name="toolBarList" />
+ </item>
+ <item row="5" column="0" colspan="3" >
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>newButton</tabstop>
+ <tabstop>removeButton</tabstop>
+ <tabstop>renameButton</tabstop>
+ <tabstop>toolBarList</tabstop>
+ <tabstop>upButton</tabstop>
+ <tabstop>leftButton</tabstop>
+ <tabstop>rightButton</tabstop>
+ <tabstop>downButton</tabstop>
+ <tabstop>currentToolBarList</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/tools.pro b/src/tools.pro
new file mode 100644
index 000000000..f090b86bf
--- /dev/null
+++ b/src/tools.pro
@@ -0,0 +1,49 @@
+TEMPLATE = subdirs
+
+!contains(QT_CONFIG, no-gui) {
+ no-png {
+ message("Some graphics-related tools are unavailable without PNG support")
+ } else {
+ symbian {
+ SUBDIRS = designer
+ } else:wince* {
+ SUBDIRS = qtestlib designer
+ } else {
+ SUBDIRS = assistant \
+ pixeltool \
+ porting \
+ qtestlib \
+ qttracereplay
+ contains(QT_EDITION, Console) {
+ SUBDIRS += designer/src/uitools # Linguist depends on this
+ } else {
+ SUBDIRS += designer
+ }
+ }
+ unix:!symbian:!mac:!embedded:!qpa:SUBDIRS += qtconfig
+ win32:!wince*:SUBDIRS += activeqt
+ }
+ contains(QT_CONFIG, declarative):SUBDIRS += qml
+}
+
+!wince*:!symbian:SUBDIRS += linguist
+
+mac {
+ SUBDIRS += macdeployqt
+}
+
+embedded:SUBDIRS += kmap2qmap
+
+contains(QT_CONFIG, dbus):SUBDIRS += qdbus
+# We don't need these command line utilities on embedded platforms.
+!wince*:!symbian:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator
+embedded: SUBDIRS += makeqpf
+
+!wince*:!cross_compile:SUBDIRS += qdoc3
+
+CONFIG+=ordered
+QTDIR_build:REQUIRES = "contains(QT_CONFIG, full-config)"
+
+!win32:!embedded:!mac:!symbian:CONFIG += x11
+
+x11:contains(QT_CONFIG, opengles2):contains(QT_CONFIG, egl):SUBDIRS += qmeegographicssystemhelper
diff --git a/tests/README b/tests/README
new file mode 100644
index 000000000..f94d5a2f1
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,18 @@
+This directory contains autotests and benchmarks based on QTestlib. In order
+to run the autotests reliably, you need to configure a desktop to match the
+test environment that these tests are written for.
+
+Linux X11:
+
+ * The user must be logged in to an active desktop; you can't run the
+ autotests without a valid DISPLAY that allows X11 connections.
+
+ * The tests are run against a KDE3 or KDE4 desktop.
+
+ * Window manager uses "click to focus", and not "focus follows mouse". Many
+ tests move the mouse cursor around and expect this to not affect focus
+ and activation.
+
+ * Disable "click to activate", i.e., when a window is opened, the window
+ manager should automatically activate it (give it input focus) and not
+ wait for the user to click the window.
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
new file mode 100644
index 000000000..c1e3bd18f
--- /dev/null
+++ b/tests/auto/auto.pro
@@ -0,0 +1,9 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qhelpcontentmodel \
+ qhelpenginecore \
+ qhelpgenerator \
+ qhelpindexmodel \
+ qhelpprojectdata \
+
+SUBDIRS += linguist
diff --git a/tests/auto/bic/.gitignore b/tests/auto/bic/.gitignore
new file mode 100644
index 000000000..6f26b868f
--- /dev/null
+++ b/tests/auto/bic/.gitignore
@@ -0,0 +1,2 @@
+qt_temp.*.*lass
+test.cpp
diff --git a/tests/auto/bic/data/QtDesigner.4.2.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtDesigner.4.2.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..a5d192762
--- /dev/null
+++ b/tests/auto/bic/data/QtDesigner.4.2.0.linux-gcc-ia32.txt
@@ -0,0 +1,1985 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb7866380) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb7866440) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb7866540) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb7866580) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb7866a00) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb7866b00) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb7866b40) 0
+
+Class QBasicAtomic
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomic (0xb7866c40) 0
+
+Class QAtomic
+ size=4 align=4
+ base size=4 base align=4
+QAtomic (0xb7866cc0) 0
+ QBasicAtomic (0xb7866d00) 0
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb7866e00) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb7866e80) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb7866e40) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb7866ec0) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb73fb280) 0 empty
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb73fb300) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb73fb380) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb73fb2c0) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb73fb480) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb73fb4c0) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb73fb540) 0
+ QString (0xb73fb580) 0
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb73fb600) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb73fb640) 0
+ QGenericArgument (0xb73fb680) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb73fb800) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb73fb940) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb73fb9c0) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb73fba00) 0 nearly-empty
+ primary-for std::bad_exception (0xb73fb9c0)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::exception::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb73fba80) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb73fbac0) 0 nearly-empty
+ primary-for std::bad_alloc (0xb73fba80)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb73fbb40) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb73fbbc0) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb73fbb80) 0
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=28 align=4
+ base size=28 base align=4
+QObjectData (0xb73fbe00) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb73fbf80) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb73fb3c0) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Vtable for QAbstractExtensionFactory
+QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionFactory)
+8 QAbstractExtensionFactory::~QAbstractExtensionFactory
+12 QAbstractExtensionFactory::~QAbstractExtensionFactory
+16 __cxa_pure_virtual
+
+Class QAbstractExtensionFactory
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionFactory (0xb73fba40) 0 nearly-empty
+ vptr=((& QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory) + 8u)
+
+Vtable for QAbstractExtensionManager
+QAbstractExtensionManager::_ZTV25QAbstractExtensionManager: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionManager)
+8 QAbstractExtensionManager::~QAbstractExtensionManager
+12 QAbstractExtensionManager::~QAbstractExtensionManager
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QAbstractExtensionManager
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionManager (0xb73fbb00) 0 nearly-empty
+ vptr=((& QAbstractExtensionManager::_ZTV25QAbstractExtensionManager) + 8u)
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb73fbfc0) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb73fbf40) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb7119040) 0 empty
+
+Vtable for QExtensionManager
+QExtensionManager::_ZTV17QExtensionManager: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QExtensionManager)
+8 QExtensionManager::metaObject
+12 QExtensionManager::qt_metacast
+16 QExtensionManager::qt_metacall
+20 QExtensionManager::~QExtensionManager
+24 QExtensionManager::~QExtensionManager
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QExtensionManager::registerExtensions
+60 QExtensionManager::unregisterExtensions
+64 QExtensionManager::extension
+68 (int (*)(...))-0x00000000000000008
+72 (int (*)(...))(& _ZTI17QExtensionManager)
+76 QExtensionManager::_ZThn8_N17QExtensionManagerD1Ev
+80 QExtensionManager::_ZThn8_N17QExtensionManagerD0Ev
+84 QExtensionManager::_ZThn8_N17QExtensionManager18registerExtensionsEP25QAbstractExtensionFactoryRK7QString
+88 QExtensionManager::_ZThn8_N17QExtensionManager20unregisterExtensionsEP25QAbstractExtensionFactoryRK7QString
+92 QExtensionManager::_ZThn8_NK17QExtensionManager9extensionEP7QObjectRK7QString
+
+Class QExtensionManager
+ size=20 align=4
+ base size=20 base align=4
+QExtensionManager (0xb7119780) 0
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 8u)
+ QObject (0xb71197c0) 0
+ primary-for QExtensionManager (0xb7119780)
+ QAbstractExtensionManager (0xb7119800) 8 nearly-empty
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 76u)
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb7119ac0) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb7119d40) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb7119640) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb7119940) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb7119a80) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb7119c00) 0
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb7119b40) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb7119c40) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb7119d80) 0
+ primary-for QIODevice (0xb7119c40)
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb7119e80) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb7119f00) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb7119ec0) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb6da20c0) 0
+ QList<QString> (0xb6da2100) 0
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb6da2280) 0
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb6da2480) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb6da2680) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb6da26c0) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb6da2780) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb6da2ac0) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb6da2b00) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb6da2b40) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb6da2dc0) 0
+ QVector<QPoint> (0xb6da2e00) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb6da2f00) 0
+ QVector<QPointF> (0xb6da2f40) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb6da23c0) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb6da2f80) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb6da2400) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb6d12000) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb6d12080) 0
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb6d12100) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb6d12140) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb6d12180) 0
+ primary-for QImage (0xb6d12140)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb6d12300) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb6d12340) 0
+ primary-for QPixmap (0xb6d12300)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb6d12480) 0
+
+Class QBrushData
+ size=72 align=4
+ base size=72 base align=4
+QBrushData (0xb6d12500) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb6d12540) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb6d12780) 0
+ QGradient (0xb6d127c0) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb6d12800) 0
+ QGradient (0xb6d12840) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb6d12880) 0
+ QGradient (0xb6d128c0) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb6d12900) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb6d12980) 0
+ QPalette (0xb6d129c0) 0
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb6d12a40) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb6d12b40) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb6d12b80) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb6d12bc0) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb6d12c00) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb6d12cc0) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb6d12d00) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb6d12e00) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x00000000000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb6d12e40) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb6d12e80) 0
+ primary-for QWidget (0xb6d12e40)
+ QPaintDevice (0xb6d12ec0) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Vtable for QDesignerActionEditorInterface
+QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+8 QDesignerActionEditorInterface::metaObject
+12 QDesignerActionEditorInterface::qt_metacast
+16 QDesignerActionEditorInterface::qt_metacall
+20 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+24 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerActionEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 (int (*)(...))-0x00000000000000008
+244 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+248 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD1Ev
+252 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerActionEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerActionEditorInterface (0xb6d12200) 0
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 8u)
+ QWidget (0xb6d12240) 0
+ primary-for QDesignerActionEditorInterface (0xb6d12200)
+ QObject (0xb6d121c0) 0
+ primary-for QWidget (0xb6d12240)
+ QPaintDevice (0xb6d12380) 8
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 248u)
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb6d123c0) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb6d12400) 0
+
+Vtable for QDesignerBrushManagerInterface
+QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerBrushManagerInterface)
+8 QDesignerBrushManagerInterface::metaObject
+12 QDesignerBrushManagerInterface::qt_metacast
+16 QDesignerBrushManagerInterface::qt_metacall
+20 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+24 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerBrushManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerBrushManagerInterface (0xb69f40c0) 0
+ vptr=((& QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface) + 8u)
+ QObject (0xb69f4100) 0
+ primary-for QDesignerBrushManagerInterface (0xb69f40c0)
+
+Vtable for QDesignerDnDItemInterface
+QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QDesignerDnDItemInterface)
+8 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+12 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerDnDItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDnDItemInterface (0xb69f4180) 0 nearly-empty
+ vptr=((& QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface) + 8u)
+
+Vtable for QDesignerFormEditorInterface
+QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormEditorInterface)
+8 QDesignerFormEditorInterface::metaObject
+12 QDesignerFormEditorInterface::qt_metacast
+16 QDesignerFormEditorInterface::qt_metacall
+20 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+24 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QDesignerFormEditorInterface
+ size=60 align=4
+ base size=60 base align=4
+QDesignerFormEditorInterface (0xb69f4240) 0
+ vptr=((& QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface) + 8u)
+ QObject (0xb69f4280) 0
+ primary-for QDesignerFormEditorInterface (0xb69f4240)
+
+Vtable for QDesignerFormEditorPluginInterface
+QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormEditorPluginInterface)
+8 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+12 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QDesignerFormEditorPluginInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormEditorPluginInterface (0xb69f4900) 0 nearly-empty
+ vptr=((& QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface) + 8u)
+
+Vtable for QDesignerFormWindowInterface
+QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface: 114u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+8 QDesignerFormWindowInterface::metaObject
+12 QDesignerFormWindowInterface::qt_metacast
+16 QDesignerFormWindowInterface::qt_metacall
+20 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+24 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 __cxa_pure_virtual
+280 __cxa_pure_virtual
+284 __cxa_pure_virtual
+288 __cxa_pure_virtual
+292 __cxa_pure_virtual
+296 __cxa_pure_virtual
+300 __cxa_pure_virtual
+304 QDesignerFormWindowInterface::core
+308 __cxa_pure_virtual
+312 __cxa_pure_virtual
+316 __cxa_pure_virtual
+320 __cxa_pure_virtual
+324 __cxa_pure_virtual
+328 __cxa_pure_virtual
+332 __cxa_pure_virtual
+336 __cxa_pure_virtual
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 __cxa_pure_virtual
+368 __cxa_pure_virtual
+372 __cxa_pure_virtual
+376 __cxa_pure_virtual
+380 __cxa_pure_virtual
+384 __cxa_pure_virtual
+388 __cxa_pure_virtual
+392 __cxa_pure_virtual
+396 __cxa_pure_virtual
+400 __cxa_pure_virtual
+404 __cxa_pure_virtual
+408 __cxa_pure_virtual
+412 __cxa_pure_virtual
+416 __cxa_pure_virtual
+420 __cxa_pure_virtual
+424 __cxa_pure_virtual
+428 (int (*)(...))-0x00000000000000008
+432 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+436 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD1Ev
+440 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD0Ev
+444 QWidget::_ZThn8_NK7QWidget7devTypeEv
+448 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+452 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerFormWindowInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerFormWindowInterface (0xb69f4980) 0
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 8u)
+ QWidget (0xb69f49c0) 0
+ primary-for QDesignerFormWindowInterface (0xb69f4980)
+ QObject (0xb69f4a00) 0
+ primary-for QWidget (0xb69f49c0)
+ QPaintDevice (0xb69f4a40) 8
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 436u)
+
+Vtable for QDesignerFormWindowCursorInterface
+QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormWindowCursorInterface)
+8 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+12 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+
+Class QDesignerFormWindowCursorInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormWindowCursorInterface (0xb69f4ac0) 0 nearly-empty
+ vptr=((& QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface) + 8u)
+
+Vtable for QDesignerFormWindowManagerInterface
+QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface: 39u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI35QDesignerFormWindowManagerInterface)
+8 QDesignerFormWindowManagerInterface::metaObject
+12 QDesignerFormWindowManagerInterface::qt_metacast
+16 QDesignerFormWindowManagerInterface::qt_metacall
+20 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+24 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerFormWindowManagerInterface::actionCut
+60 QDesignerFormWindowManagerInterface::actionCopy
+64 QDesignerFormWindowManagerInterface::actionPaste
+68 QDesignerFormWindowManagerInterface::actionDelete
+72 QDesignerFormWindowManagerInterface::actionSelectAll
+76 QDesignerFormWindowManagerInterface::actionLower
+80 QDesignerFormWindowManagerInterface::actionRaise
+84 QDesignerFormWindowManagerInterface::actionUndo
+88 QDesignerFormWindowManagerInterface::actionRedo
+92 QDesignerFormWindowManagerInterface::actionHorizontalLayout
+96 QDesignerFormWindowManagerInterface::actionVerticalLayout
+100 QDesignerFormWindowManagerInterface::actionSplitHorizontal
+104 QDesignerFormWindowManagerInterface::actionSplitVertical
+108 QDesignerFormWindowManagerInterface::actionGridLayout
+112 QDesignerFormWindowManagerInterface::actionBreakLayout
+116 QDesignerFormWindowManagerInterface::actionAdjustSize
+120 QDesignerFormWindowManagerInterface::activeFormWindow
+124 QDesignerFormWindowManagerInterface::formWindowCount
+128 QDesignerFormWindowManagerInterface::formWindow
+132 QDesignerFormWindowManagerInterface::createFormWindow
+136 QDesignerFormWindowManagerInterface::core
+140 __cxa_pure_virtual
+144 QDesignerFormWindowManagerInterface::addFormWindow
+148 QDesignerFormWindowManagerInterface::removeFormWindow
+152 QDesignerFormWindowManagerInterface::setActiveFormWindow
+
+Class QDesignerFormWindowManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowManagerInterface (0xb69f4b40) 0
+ vptr=((& QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface) + 8u)
+ QObject (0xb69f4b80) 0
+ primary-for QDesignerFormWindowManagerInterface (0xb69f4b40)
+
+Vtable for QDesignerFormWindowToolInterface
+QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerFormWindowToolInterface)
+8 QDesignerFormWindowToolInterface::metaObject
+12 QDesignerFormWindowToolInterface::qt_metacast
+16 QDesignerFormWindowToolInterface::qt_metacall
+20 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+24 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QDesignerFormWindowToolInterface::saveToDom
+84 QDesignerFormWindowToolInterface::loadFromDom
+88 __cxa_pure_virtual
+
+Class QDesignerFormWindowToolInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowToolInterface (0xb69f4c00) 0
+ vptr=((& QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface) + 8u)
+ QObject (0xb69f4c40) 0
+ primary-for QDesignerFormWindowToolInterface (0xb69f4c00)
+
+Vtable for QDesignerIconCacheInterface
+QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerIconCacheInterface)
+8 QDesignerIconCacheInterface::metaObject
+12 QDesignerIconCacheInterface::qt_metacast
+16 QDesignerIconCacheInterface::qt_metacall
+20 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+24 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QDesignerIconCacheInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerIconCacheInterface (0xb69f4cc0) 0
+ vptr=((& QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface) + 8u)
+ QObject (0xb69f4d00) 0
+ primary-for QDesignerIconCacheInterface (0xb69f4cc0)
+
+Vtable for QDesignerLanguageExtension
+QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerLanguageExtension)
+8 QDesignerLanguageExtension::~QDesignerLanguageExtension
+12 QDesignerLanguageExtension::~QDesignerLanguageExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QDesignerLanguageExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLanguageExtension (0xb69f4d80) 0 nearly-empty
+ vptr=((& QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension) + 8u)
+
+Vtable for QDesignerMetaDataBaseItemInterface
+QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerMetaDataBaseItemInterface)
+8 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+12 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMetaDataBaseItemInterface (0xb69f4ec0) 0 nearly-empty
+ vptr=((& QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerMetaDataBaseInterface
+QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerMetaDataBaseInterface)
+8 QDesignerMetaDataBaseInterface::metaObject
+12 QDesignerMetaDataBaseInterface::qt_metacast
+16 QDesignerMetaDataBaseInterface::qt_metacall
+20 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+24 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerMetaDataBaseInterface (0xb69f4f40) 0
+ vptr=((& QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface) + 8u)
+ QObject (0xb69f4f80) 0
+ primary-for QDesignerMetaDataBaseInterface (0xb69f4f40)
+
+Vtable for QDesignerObjectInspectorInterface
+QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+8 QDesignerObjectInspectorInterface::metaObject
+12 QDesignerObjectInspectorInterface::qt_metacast
+16 QDesignerObjectInspectorInterface::qt_metacall
+20 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+24 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerObjectInspectorInterface::core
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x00000000000000008
+236 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+240 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD1Ev
+244 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerObjectInspectorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerObjectInspectorInterface (0xb69f4140) 0
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 8u)
+ QWidget (0xb69f41c0) 0
+ primary-for QDesignerObjectInspectorInterface (0xb69f4140)
+ QObject (0xb69f42c0) 0
+ primary-for QWidget (0xb69f41c0)
+ QPaintDevice (0xb69f4340) 8
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 240u)
+
+Vtable for QDesignerPropertyEditorInterface
+QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface: 70u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+8 QDesignerPropertyEditorInterface::metaObject
+12 QDesignerPropertyEditorInterface::qt_metacast
+16 QDesignerPropertyEditorInterface::qt_metacall
+20 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+24 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerPropertyEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 (int (*)(...))-0x00000000000000008
+256 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+260 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD1Ev
+264 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD0Ev
+268 QWidget::_ZThn8_NK7QWidget7devTypeEv
+272 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+276 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerPropertyEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerPropertyEditorInterface (0xb69f43c0) 0
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 8u)
+ QWidget (0xb69f4440) 0
+ primary-for QDesignerPropertyEditorInterface (0xb69f43c0)
+ QObject (0xb69f44c0) 0
+ primary-for QWidget (0xb69f4440)
+ QPaintDevice (0xb69f4540) 8
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 260u)
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb69f45c0) 0 empty
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb68f8a00) 0
+
+Class QDesignerWidgetBoxInterface::Widget
+ size=16 align=4
+ base size=16 base align=4
+QDesignerWidgetBoxInterface::Widget (0xb68f8c00) 0
+
+Class QDesignerWidgetBoxInterface::Category
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetBoxInterface::Category (0xb68f8c40) 0
+
+Vtable for QDesignerWidgetBoxInterface
+QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface: 76u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+8 QDesignerWidgetBoxInterface::metaObject
+12 QDesignerWidgetBoxInterface::qt_metacast
+16 QDesignerWidgetBoxInterface::qt_metacall
+20 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+24 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 (int (*)(...))-0x00000000000000008
+280 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+284 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD1Ev
+288 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD0Ev
+292 QWidget::_ZThn8_NK7QWidget7devTypeEv
+296 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+300 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerWidgetBoxInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerWidgetBoxInterface (0xb68f8b00) 0
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 8u)
+ QWidget (0xb68f8b40) 0
+ primary-for QDesignerWidgetBoxInterface (0xb68f8b00)
+ QObject (0xb68f8b80) 0
+ primary-for QWidget (0xb68f8b40)
+ QPaintDevice (0xb68f8bc0) 8
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 284u)
+
+Vtable for QDesignerWidgetDataBaseItemInterface
+QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI36QDesignerWidgetDataBaseItemInterface)
+8 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+12 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+
+Class QDesignerWidgetDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerWidgetDataBaseItemInterface (0xb68f8f40) 0 nearly-empty
+ vptr=((& QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerWidgetDataBaseInterface
+QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerWidgetDataBaseInterface)
+8 QDesignerWidgetDataBaseInterface::metaObject
+12 QDesignerWidgetDataBaseInterface::qt_metacast
+16 QDesignerWidgetDataBaseInterface::qt_metacall
+20 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+24 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerWidgetDataBaseInterface::count
+60 QDesignerWidgetDataBaseInterface::item
+64 QDesignerWidgetDataBaseInterface::indexOf
+68 QDesignerWidgetDataBaseInterface::insert
+72 QDesignerWidgetDataBaseInterface::append
+76 QDesignerWidgetDataBaseInterface::indexOfObject
+80 QDesignerWidgetDataBaseInterface::indexOfClassName
+84 QDesignerWidgetDataBaseInterface::core
+
+Class QDesignerWidgetDataBaseInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetDataBaseInterface (0xb68f8fc0) 0
+ vptr=((& QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface) + 8u)
+ QObject (0xb68f8a40) 0
+ primary-for QDesignerWidgetDataBaseInterface (0xb68f8fc0)
+
+Vtable for QDesignerWidgetFactoryInterface
+QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerWidgetFactoryInterface)
+8 QDesignerWidgetFactoryInterface::metaObject
+12 QDesignerWidgetFactoryInterface::qt_metacast
+16 QDesignerWidgetFactoryInterface::qt_metacall
+20 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+24 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerWidgetFactoryInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerWidgetFactoryInterface (0xb6786040) 0
+ vptr=((& QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface) + 8u)
+ QObject (0xb6786080) 0
+ primary-for QDesignerWidgetFactoryInterface (0xb6786040)
+
+Vtable for QDesignerExtraInfoExtension
+QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerExtraInfoExtension)
+8 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+12 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerExtraInfoExtension
+ size=8 align=4
+ base size=8 base align=4
+QDesignerExtraInfoExtension (0xb6786100) 0
+ vptr=((& QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension) + 8u)
+
+Vtable for QDesignerLayoutDecorationExtension
+QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerLayoutDecorationExtension)
+8 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+12 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerLayoutDecorationExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLayoutDecorationExtension (0xb6786240) 0 nearly-empty
+ vptr=((& QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension) + 8u)
+
+Vtable for QDesignerMemberSheetExtension
+QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerMemberSheetExtension)
+8 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+12 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+
+Class QDesignerMemberSheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMemberSheetExtension (0xb67862c0) 0 nearly-empty
+ vptr=((& QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension) + 8u)
+
+Vtable for QDesignerPropertySheetExtension
+QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerPropertySheetExtension)
+8 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+12 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPropertySheetExtension (0xb6786400) 0 nearly-empty
+ vptr=((& QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension) + 8u)
+
+Vtable for QDesignerTaskMenuExtension
+QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerTaskMenuExtension)
+8 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+12 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+16 QDesignerTaskMenuExtension::preferredEditAction
+20 __cxa_pure_virtual
+
+Class QDesignerTaskMenuExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerTaskMenuExtension (0xb6786540) 0 nearly-empty
+ vptr=((& QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension) + 8u)
+
+Class __gconv_trans_data
+ size=20 align=4
+ base size=20 base align=4
+__gconv_trans_data (0xb67867c0) 0
+
+Class __gconv_step
+ size=60 align=4
+ base size=60 base align=4
+__gconv_step (0xb6786800) 0
+
+Class __gconv_step_data
+ size=36 align=4
+ base size=36 base align=4
+__gconv_step_data (0xb6786840) 0
+
+Class __gconv_info
+ size=8 align=4
+ base size=8 base align=4
+__gconv_info (0xb6786880) 0
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb6786940) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb6786980) 0
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb6786a00) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb6786a40) 0
+ primary-for QFile (0xb6786a00)
+ QObject (0xb6786a80) 0
+ primary-for QIODevice (0xb6786a40)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb6786b40) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb6786cc0) 0
+
+Vtable for QAbstractFormBuilder
+QAbstractFormBuilder::_ZTV20QAbstractFormBuilder: 48u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QAbstractFormBuilder)
+8 QAbstractFormBuilder::~QAbstractFormBuilder
+12 QAbstractFormBuilder::~QAbstractFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QAbstractFormBuilder::create
+32 QAbstractFormBuilder::create
+36 QAbstractFormBuilder::create
+40 QAbstractFormBuilder::create
+44 QAbstractFormBuilder::create
+48 QAbstractFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QAbstractFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QAbstractFormBuilder::createWidget
+68 QAbstractFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QAbstractFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QAbstractFormBuilder::addItem
+96 QAbstractFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+
+Class QAbstractFormBuilder
+ size=28 align=4
+ base size=28 base align=4
+QAbstractFormBuilder (0xb6786e00) 0
+ vptr=((& QAbstractFormBuilder::_ZTV20QAbstractFormBuilder) + 8u)
+
+Vtable for QDesignerContainerExtension
+QDesignerContainerExtension::_ZTV27QDesignerContainerExtension: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerContainerExtension)
+8 QDesignerContainerExtension::~QDesignerContainerExtension
+12 QDesignerContainerExtension::~QDesignerContainerExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerContainerExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerContainerExtension (0xb6786300) 0 nearly-empty
+ vptr=((& QDesignerContainerExtension::_ZTV27QDesignerContainerExtension) + 8u)
+
+Vtable for QDesignerCustomWidgetInterface
+QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerCustomWidgetInterface)
+8 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+12 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 QDesignerCustomWidgetInterface::isInitialized
+52 QDesignerCustomWidgetInterface::initialize
+56 QDesignerCustomWidgetInterface::domXml
+60 QDesignerCustomWidgetInterface::codeTemplate
+
+Class QDesignerCustomWidgetInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetInterface (0xb6786e40) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface) + 8u)
+
+Vtable for QDesignerCustomWidgetCollectionInterface
+QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI40QDesignerCustomWidgetCollectionInterface)
+8 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+12 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+16 __cxa_pure_virtual
+
+Class QDesignerCustomWidgetCollectionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetCollectionInterface (0xb66d9080) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface) + 8u)
+
+Vtable for QFormBuilder
+QFormBuilder::_ZTV12QFormBuilder: 49u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QFormBuilder)
+8 QFormBuilder::~QFormBuilder
+12 QFormBuilder::~QFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QFormBuilder::create
+32 QFormBuilder::create
+36 QFormBuilder::create
+40 QFormBuilder::create
+44 QFormBuilder::create
+48 QFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QFormBuilder::createWidget
+68 QFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QFormBuilder::addItem
+96 QFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+192 QFormBuilder::updateCustomWidgets
+
+Class QFormBuilder
+ size=36 align=4
+ base size=36 base align=4
+QFormBuilder (0xb66d9100) 0
+ vptr=((& QFormBuilder::_ZTV12QFormBuilder) + 8u)
+ QAbstractFormBuilder (0xb66d9140) 0
+ primary-for QFormBuilder (0xb66d9100)
+
diff --git a/tests/auto/bic/data/QtDesigner.4.3.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtDesigner.4.3.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..d99f316f7
--- /dev/null
+++ b/tests/auto/bic/data/QtDesigner.4.3.0.linux-gcc-ia32.txt
@@ -0,0 +1,2169 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb7793400) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb7793500) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb7793600) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb7793640) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb7793ac0) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb7793f00) 0 empty
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb7793f80) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb7793fc0) 0
+ QGenericArgument (0xb7299000) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb7299180) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb7299240) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb7299280) 0
+
+Class QBasicAtomic
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomic (0xb7299340) 0
+
+Class QAtomic
+ size=4 align=4
+ base size=4 base align=4
+QAtomic (0xb72993c0) 0
+ QBasicAtomic (0xb7299400) 0
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb7299500) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb7299580) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb7299540) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb7299600) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb72996c0) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb7299740) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb7299680) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb72998c0) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb7299900) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb7299980) 0
+ QString (0xb72999c0) 0
+
+Class QStringRef
+ size=12 align=4
+ base size=12 base align=4
+QStringRef (0xb7299a40) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb7299b00) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb7299b80) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb7299bc0) 0 nearly-empty
+ primary-for std::bad_exception (0xb7299b80)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::exception::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb7299c40) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb7299c80) 0 nearly-empty
+ primary-for std::bad_alloc (0xb7299c40)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb7299d00) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb7299d80) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb7299d40) 0
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=24 align=4
+ base size=24 base align=4
+QObjectData (0xb7299fc0) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb7299f00) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb6e93040) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb6e93140) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb6e933c0) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb6e93680) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb6e93900) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb6e93b80) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb6e93cc0) 0
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb6e93dc0) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb6e93ec0) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb6e93f00) 0
+ primary-for QIODevice (0xb6e93ec0)
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb6e93000) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb6e931c0) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb6e93240) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb6e93180) 0
+ QList<QString> (0xb6e93400) 0
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb6e93580) 0
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb6e93880) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb6e93a80) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb6e93ac0) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb6e93c00) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb6d0e1c0) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb6d0e200) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb6d0e240) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb6d0e4c0) 0
+ QVector<QPoint> (0xb6d0e500) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb6d0e600) 0
+ QVector<QPointF> (0xb6d0e640) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb6d0e7c0) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb6d0e680) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb6d0e800) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb6d0e880) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb6d0e900) 0
+
+Class QPainterPath::Element
+ size=20 align=4
+ base size=20 base align=4
+QPainterPath::Element (0xb6d0e9c0) 0
+
+Class QPainterPath
+ size=4 align=4
+ base size=4 base align=4
+QPainterPath (0xb6d0e980) 0
+
+Class QPainterPathPrivate
+ size=8 align=4
+ base size=8 base align=4
+QPainterPathPrivate (0xb6d0ea80) 0
+
+Class QPainterPathStroker
+ size=4 align=4
+ base size=4 base align=4
+QPainterPathStroker (0xb6d0ec80) 0
+
+Class QTransform
+ size=80 align=4
+ base size=80 base align=4
+QTransform (0xb6d0ed40) 0
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb6d0ee00) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb6d0ee40) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb6d0ee80) 0
+ primary-for QImage (0xb6d0ee40)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb6d0e6c0) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb6d0e700) 0
+ primary-for QPixmap (0xb6d0e6c0)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb6d0e740) 0
+
+Class QBrushData
+ size=108 align=4
+ base size=105 base align=4
+QBrushData (0xb6d0ea40) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb6d0eec0) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb6965140) 0
+ QGradient (0xb6965180) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb69651c0) 0
+ QGradient (0xb6965200) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb6965240) 0
+ QGradient (0xb6965280) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb69652c0) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb6965340) 0
+ QPalette (0xb6965380) 0
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb6965400) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb6965500) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb6965540) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb6965580) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb69655c0) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb6965700) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb6965740) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb6965840) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x00000000000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb6965880) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb69658c0) 0
+ primary-for QWidget (0xb6965880)
+ QPaintDevice (0xb6965900) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Vtable for QDesignerPropertyEditorInterface
+QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface: 70u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+8 QDesignerPropertyEditorInterface::metaObject
+12 QDesignerPropertyEditorInterface::qt_metacast
+16 QDesignerPropertyEditorInterface::qt_metacall
+20 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+24 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerPropertyEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 (int (*)(...))-0x00000000000000008
+256 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+260 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD1Ev
+264 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD0Ev
+268 QWidget::_ZThn8_NK7QWidget7devTypeEv
+272 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+276 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerPropertyEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerPropertyEditorInterface (0xb6965b80) 0
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 8u)
+ QWidget (0xb6965bc0) 0
+ primary-for QDesignerPropertyEditorInterface (0xb6965b80)
+ QObject (0xb6965c00) 0
+ primary-for QWidget (0xb6965bc0)
+ QPaintDevice (0xb6965c40) 8
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 260u)
+
+Vtable for QDesignerActionEditorInterface
+QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+8 QDesignerActionEditorInterface::metaObject
+12 QDesignerActionEditorInterface::qt_metacast
+16 QDesignerActionEditorInterface::qt_metacall
+20 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+24 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerActionEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 (int (*)(...))-0x00000000000000008
+244 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+248 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD1Ev
+252 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerActionEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerActionEditorInterface (0xb6965cc0) 0
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 8u)
+ QWidget (0xb6965d00) 0
+ primary-for QDesignerActionEditorInterface (0xb6965cc0)
+ QObject (0xb6965d40) 0
+ primary-for QWidget (0xb6965d00)
+ QPaintDevice (0xb6965d80) 8
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 248u)
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb6965e00) 0 empty
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb675b840) 0
+
+Class QDesignerWidgetBoxInterface::Widget
+ size=16 align=4
+ base size=16 base align=4
+QDesignerWidgetBoxInterface::Widget (0xb675ba40) 0
+
+Class QDesignerWidgetBoxInterface::Category
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetBoxInterface::Category (0xb675ba80) 0
+
+Vtable for QDesignerWidgetBoxInterface
+QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface: 76u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+8 QDesignerWidgetBoxInterface::metaObject
+12 QDesignerWidgetBoxInterface::qt_metacast
+16 QDesignerWidgetBoxInterface::qt_metacall
+20 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+24 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 (int (*)(...))-0x00000000000000008
+280 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+284 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD1Ev
+288 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD0Ev
+292 QWidget::_ZThn8_NK7QWidget7devTypeEv
+296 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+300 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerWidgetBoxInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerWidgetBoxInterface (0xb675b940) 0
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 8u)
+ QWidget (0xb675b980) 0
+ primary-for QDesignerWidgetBoxInterface (0xb675b940)
+ QObject (0xb675b9c0) 0
+ primary-for QWidget (0xb675b980)
+ QPaintDevice (0xb675ba00) 8
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 284u)
+
+Vtable for QDesignerFormWindowInterface
+QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface: 114u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+8 QDesignerFormWindowInterface::metaObject
+12 QDesignerFormWindowInterface::qt_metacast
+16 QDesignerFormWindowInterface::qt_metacall
+20 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+24 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 __cxa_pure_virtual
+280 __cxa_pure_virtual
+284 __cxa_pure_virtual
+288 __cxa_pure_virtual
+292 __cxa_pure_virtual
+296 __cxa_pure_virtual
+300 __cxa_pure_virtual
+304 QDesignerFormWindowInterface::core
+308 __cxa_pure_virtual
+312 __cxa_pure_virtual
+316 __cxa_pure_virtual
+320 __cxa_pure_virtual
+324 __cxa_pure_virtual
+328 __cxa_pure_virtual
+332 __cxa_pure_virtual
+336 __cxa_pure_virtual
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 __cxa_pure_virtual
+368 __cxa_pure_virtual
+372 __cxa_pure_virtual
+376 __cxa_pure_virtual
+380 __cxa_pure_virtual
+384 __cxa_pure_virtual
+388 __cxa_pure_virtual
+392 __cxa_pure_virtual
+396 __cxa_pure_virtual
+400 __cxa_pure_virtual
+404 __cxa_pure_virtual
+408 __cxa_pure_virtual
+412 __cxa_pure_virtual
+416 __cxa_pure_virtual
+420 __cxa_pure_virtual
+424 __cxa_pure_virtual
+428 (int (*)(...))-0x00000000000000008
+432 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+436 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD1Ev
+440 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD0Ev
+444 QWidget::_ZThn8_NK7QWidget7devTypeEv
+448 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+452 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerFormWindowInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerFormWindowInterface (0xb675bd80) 0
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 8u)
+ QWidget (0xb675bdc0) 0
+ primary-for QDesignerFormWindowInterface (0xb675bd80)
+ QObject (0xb675be00) 0
+ primary-for QWidget (0xb675bdc0)
+ QPaintDevice (0xb675be40) 8
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 436u)
+
+Vtable for QAbstractExtensionFactory
+QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionFactory)
+8 QAbstractExtensionFactory::~QAbstractExtensionFactory
+12 QAbstractExtensionFactory::~QAbstractExtensionFactory
+16 __cxa_pure_virtual
+
+Class QAbstractExtensionFactory
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionFactory (0xb675bec0) 0 nearly-empty
+ vptr=((& QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory) + 8u)
+
+Vtable for QAbstractExtensionManager
+QAbstractExtensionManager::_ZTV25QAbstractExtensionManager: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionManager)
+8 QAbstractExtensionManager::~QAbstractExtensionManager
+12 QAbstractExtensionManager::~QAbstractExtensionManager
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QAbstractExtensionManager
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionManager (0xb675bf40) 0 nearly-empty
+ vptr=((& QAbstractExtensionManager::_ZTV25QAbstractExtensionManager) + 8u)
+
+Vtable for QDesignerTaskMenuExtension
+QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerTaskMenuExtension)
+8 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+12 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+16 QDesignerTaskMenuExtension::preferredEditAction
+20 __cxa_pure_virtual
+
+Class QDesignerTaskMenuExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerTaskMenuExtension (0xb675b880) 0 nearly-empty
+ vptr=((& QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension) + 8u)
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb675bf80) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb675bf00) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb680f040) 0 empty
+
+Class QDesignerPromotionInterface::PromotedClass
+ size=8 align=4
+ base size=8 base align=4
+QDesignerPromotionInterface::PromotedClass (0xb680f700) 0
+
+Vtable for QDesignerPromotionInterface
+QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerPromotionInterface)
+8 QDesignerPromotionInterface::~QDesignerPromotionInterface
+12 QDesignerPromotionInterface::~QDesignerPromotionInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerPromotionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPromotionInterface (0xb680f6c0) 0 nearly-empty
+ vptr=((& QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface) + 8u)
+
+Vtable for QDesignerResourceBrowserInterface
+QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+8 QDesignerResourceBrowserInterface::metaObject
+12 QDesignerResourceBrowserInterface::qt_metacast
+16 QDesignerResourceBrowserInterface::qt_metacall
+20 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+24 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x00000000000000008
+236 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+240 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD1Ev
+244 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerResourceBrowserInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerResourceBrowserInterface (0xb680f780) 0
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 8u)
+ QWidget (0xb680f7c0) 0
+ primary-for QDesignerResourceBrowserInterface (0xb680f780)
+ QObject (0xb680f800) 0
+ primary-for QWidget (0xb680f7c0)
+ QPaintDevice (0xb680f840) 8
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 240u)
+
+Vtable for QDesignerDynamicPropertySheetExtension
+QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI38QDesignerDynamicPropertySheetExtension)
+8 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+12 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+
+Class QDesignerDynamicPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDynamicPropertySheetExtension (0xb680f8c0) 0 nearly-empty
+ vptr=((& QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension) + 8u)
+
+Vtable for QDesignerMetaDataBaseItemInterface
+QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerMetaDataBaseItemInterface)
+8 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+12 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMetaDataBaseItemInterface (0xb680f940) 0 nearly-empty
+ vptr=((& QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerMetaDataBaseInterface
+QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerMetaDataBaseInterface)
+8 QDesignerMetaDataBaseInterface::metaObject
+12 QDesignerMetaDataBaseInterface::qt_metacast
+16 QDesignerMetaDataBaseInterface::qt_metacall
+20 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+24 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerMetaDataBaseInterface (0xb680f9c0) 0
+ vptr=((& QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface) + 8u)
+ QObject (0xb680fa00) 0
+ primary-for QDesignerMetaDataBaseInterface (0xb680f9c0)
+
+Vtable for QDesignerDnDItemInterface
+QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QDesignerDnDItemInterface)
+8 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+12 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerDnDItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDnDItemInterface (0xb680fa80) 0 nearly-empty
+ vptr=((& QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface) + 8u)
+
+Vtable for QDesignerIntegrationInterface
+QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerIntegrationInterface)
+8 QDesignerIntegrationInterface::metaObject
+12 QDesignerIntegrationInterface::qt_metacast
+16 QDesignerIntegrationInterface::qt_metacall
+20 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+24 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+
+Class QDesignerIntegrationInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerIntegrationInterface (0xb680fb00) 0
+ vptr=((& QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface) + 8u)
+ QObject (0xb680fb40) 0
+ primary-for QDesignerIntegrationInterface (0xb680fb00)
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb680fc00) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb680fbc0) 0
+
+Vtable for QDesignerBrushManagerInterface
+QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerBrushManagerInterface)
+8 QDesignerBrushManagerInterface::metaObject
+12 QDesignerBrushManagerInterface::qt_metacast
+16 QDesignerBrushManagerInterface::qt_metacall
+20 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+24 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerBrushManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerBrushManagerInterface (0xb680f740) 0
+ vptr=((& QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface) + 8u)
+ QObject (0xb680f880) 0
+ primary-for QDesignerBrushManagerInterface (0xb680f740)
+
+Vtable for QDesignerExtraInfoExtension
+QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerExtraInfoExtension)
+8 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+12 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerExtraInfoExtension
+ size=8 align=4
+ base size=8 base align=4
+QDesignerExtraInfoExtension (0xb680f900) 0
+ vptr=((& QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension) + 8u)
+
+Vtable for QDesignerFormWindowToolInterface
+QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerFormWindowToolInterface)
+8 QDesignerFormWindowToolInterface::metaObject
+12 QDesignerFormWindowToolInterface::qt_metacast
+16 QDesignerFormWindowToolInterface::qt_metacall
+20 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+24 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QDesignerFormWindowToolInterface::saveToDom
+84 QDesignerFormWindowToolInterface::loadFromDom
+88 __cxa_pure_virtual
+
+Class QDesignerFormWindowToolInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowToolInterface (0xb680fb80) 0
+ vptr=((& QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface) + 8u)
+ QObject (0xb680fec0) 0
+ primary-for QDesignerFormWindowToolInterface (0xb680fb80)
+
+Vtable for QDesignerLayoutDecorationExtension
+QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerLayoutDecorationExtension)
+8 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+12 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerLayoutDecorationExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLayoutDecorationExtension (0xb65e4040) 0 nearly-empty
+ vptr=((& QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension) + 8u)
+
+Vtable for QDesignerPropertySheetExtension
+QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerPropertySheetExtension)
+8 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+12 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPropertySheetExtension (0xb65e40c0) 0 nearly-empty
+ vptr=((& QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension) + 8u)
+
+Vtable for QDesignerObjectInspectorInterface
+QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+8 QDesignerObjectInspectorInterface::metaObject
+12 QDesignerObjectInspectorInterface::qt_metacast
+16 QDesignerObjectInspectorInterface::qt_metacall
+20 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+24 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerObjectInspectorInterface::core
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x00000000000000008
+236 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+240 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD1Ev
+244 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerObjectInspectorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerObjectInspectorInterface (0xb65e4200) 0
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 8u)
+ QWidget (0xb65e4240) 0
+ primary-for QDesignerObjectInspectorInterface (0xb65e4200)
+ QObject (0xb65e4280) 0
+ primary-for QWidget (0xb65e4240)
+ QPaintDevice (0xb65e42c0) 8
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 240u)
+
+Vtable for QDesignerFormWindowManagerInterface
+QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface: 39u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI35QDesignerFormWindowManagerInterface)
+8 QDesignerFormWindowManagerInterface::metaObject
+12 QDesignerFormWindowManagerInterface::qt_metacast
+16 QDesignerFormWindowManagerInterface::qt_metacall
+20 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+24 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerFormWindowManagerInterface::actionCut
+60 QDesignerFormWindowManagerInterface::actionCopy
+64 QDesignerFormWindowManagerInterface::actionPaste
+68 QDesignerFormWindowManagerInterface::actionDelete
+72 QDesignerFormWindowManagerInterface::actionSelectAll
+76 QDesignerFormWindowManagerInterface::actionLower
+80 QDesignerFormWindowManagerInterface::actionRaise
+84 QDesignerFormWindowManagerInterface::actionUndo
+88 QDesignerFormWindowManagerInterface::actionRedo
+92 QDesignerFormWindowManagerInterface::actionHorizontalLayout
+96 QDesignerFormWindowManagerInterface::actionVerticalLayout
+100 QDesignerFormWindowManagerInterface::actionSplitHorizontal
+104 QDesignerFormWindowManagerInterface::actionSplitVertical
+108 QDesignerFormWindowManagerInterface::actionGridLayout
+112 QDesignerFormWindowManagerInterface::actionBreakLayout
+116 QDesignerFormWindowManagerInterface::actionAdjustSize
+120 QDesignerFormWindowManagerInterface::activeFormWindow
+124 QDesignerFormWindowManagerInterface::formWindowCount
+128 QDesignerFormWindowManagerInterface::formWindow
+132 QDesignerFormWindowManagerInterface::createFormWindow
+136 QDesignerFormWindowManagerInterface::core
+140 __cxa_pure_virtual
+144 QDesignerFormWindowManagerInterface::addFormWindow
+148 QDesignerFormWindowManagerInterface::removeFormWindow
+152 QDesignerFormWindowManagerInterface::setActiveFormWindow
+
+Class QDesignerFormWindowManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowManagerInterface (0xb65e4340) 0
+ vptr=((& QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface) + 8u)
+ QObject (0xb65e4380) 0
+ primary-for QDesignerFormWindowManagerInterface (0xb65e4340)
+
+Vtable for QDesignerMemberSheetExtension
+QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerMemberSheetExtension)
+8 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+12 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+
+Class QDesignerMemberSheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMemberSheetExtension (0xb65e4400) 0 nearly-empty
+ vptr=((& QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension) + 8u)
+
+Vtable for QDesignerIconCacheInterface
+QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerIconCacheInterface)
+8 QDesignerIconCacheInterface::metaObject
+12 QDesignerIconCacheInterface::qt_metacast
+16 QDesignerIconCacheInterface::qt_metacall
+20 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+24 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QDesignerIconCacheInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerIconCacheInterface (0xb65e4540) 0
+ vptr=((& QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface) + 8u)
+ QObject (0xb65e4580) 0
+ primary-for QDesignerIconCacheInterface (0xb65e4540)
+
+Vtable for QDesignerWidgetDataBaseItemInterface
+QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI36QDesignerWidgetDataBaseItemInterface)
+8 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+12 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+
+Class QDesignerWidgetDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerWidgetDataBaseItemInterface (0xb65e4600) 0 nearly-empty
+ vptr=((& QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerWidgetDataBaseInterface
+QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerWidgetDataBaseInterface)
+8 QDesignerWidgetDataBaseInterface::metaObject
+12 QDesignerWidgetDataBaseInterface::qt_metacast
+16 QDesignerWidgetDataBaseInterface::qt_metacall
+20 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+24 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerWidgetDataBaseInterface::count
+60 QDesignerWidgetDataBaseInterface::item
+64 QDesignerWidgetDataBaseInterface::indexOf
+68 QDesignerWidgetDataBaseInterface::insert
+72 QDesignerWidgetDataBaseInterface::append
+76 QDesignerWidgetDataBaseInterface::indexOfObject
+80 QDesignerWidgetDataBaseInterface::indexOfClassName
+84 QDesignerWidgetDataBaseInterface::core
+
+Class QDesignerWidgetDataBaseInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetDataBaseInterface (0xb65e4680) 0
+ vptr=((& QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface) + 8u)
+ QObject (0xb65e46c0) 0
+ primary-for QDesignerWidgetDataBaseInterface (0xb65e4680)
+
+Vtable for QDesignerFormWindowCursorInterface
+QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormWindowCursorInterface)
+8 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+12 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+
+Class QDesignerFormWindowCursorInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormWindowCursorInterface (0xb65e4840) 0 nearly-empty
+ vptr=((& QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface) + 8u)
+
+Vtable for QDesignerFormEditorInterface
+QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormEditorInterface)
+8 QDesignerFormEditorInterface::metaObject
+12 QDesignerFormEditorInterface::qt_metacast
+16 QDesignerFormEditorInterface::qt_metacall
+20 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+24 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QDesignerFormEditorInterface
+ size=60 align=4
+ base size=60 base align=4
+QDesignerFormEditorInterface (0xb65e4900) 0
+ vptr=((& QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface) + 8u)
+ QObject (0xb65e4940) 0
+ primary-for QDesignerFormEditorInterface (0xb65e4900)
+
+Vtable for QDesignerWidgetFactoryInterface
+QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerWidgetFactoryInterface)
+8 QDesignerWidgetFactoryInterface::metaObject
+12 QDesignerWidgetFactoryInterface::qt_metacast
+16 QDesignerWidgetFactoryInterface::qt_metacall
+20 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+24 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerWidgetFactoryInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerWidgetFactoryInterface (0xb65e4fc0) 0
+ vptr=((& QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface) + 8u)
+ QObject (0xb65e4000) 0
+ primary-for QDesignerWidgetFactoryInterface (0xb65e4fc0)
+
+Vtable for QDesignerFormEditorPluginInterface
+QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormEditorPluginInterface)
+8 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+12 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QDesignerFormEditorPluginInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormEditorPluginInterface (0xb65e4080) 0 nearly-empty
+ vptr=((& QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface) + 8u)
+
+Vtable for QDesignerLanguageExtension
+QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension: 13u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerLanguageExtension)
+8 QDesignerLanguageExtension::~QDesignerLanguageExtension
+12 QDesignerLanguageExtension::~QDesignerLanguageExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QDesignerLanguageExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLanguageExtension (0xb65e4100) 0 nearly-empty
+ vptr=((& QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension) + 8u)
+
+Vtable for QDesignerCustomWidgetInterface
+QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerCustomWidgetInterface)
+8 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+12 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 QDesignerCustomWidgetInterface::isInitialized
+52 QDesignerCustomWidgetInterface::initialize
+56 QDesignerCustomWidgetInterface::domXml
+60 QDesignerCustomWidgetInterface::codeTemplate
+
+Class QDesignerCustomWidgetInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetInterface (0xb65e45c0) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface) + 8u)
+
+Vtable for QDesignerCustomWidgetCollectionInterface
+QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI40QDesignerCustomWidgetCollectionInterface)
+8 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+12 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+16 __cxa_pure_virtual
+
+Class QDesignerCustomWidgetCollectionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetCollectionInterface (0xb65e4880) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface) + 8u)
+
+Class __gconv_trans_data
+ size=20 align=4
+ base size=20 base align=4
+__gconv_trans_data (0xb65e4b80) 0
+
+Class __gconv_step
+ size=60 align=4
+ base size=60 base align=4
+__gconv_step (0xb65e4c00) 0
+
+Class __gconv_step_data
+ size=36 align=4
+ base size=36 base align=4
+__gconv_step_data (0xb65e4c80) 0
+
+Class __gconv_info
+ size=8 align=4
+ base size=8 base align=4
+__gconv_info (0xb65e4d00) 0
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb65e4e80) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb65e4f00) 0
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb64f2000) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb64f2040) 0
+ primary-for QFile (0xb64f2000)
+ QObject (0xb64f2080) 0
+ primary-for QIODevice (0xb64f2040)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb64f2140) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb64f22c0) 0
+
+Vtable for QAbstractFormBuilder
+QAbstractFormBuilder::_ZTV20QAbstractFormBuilder: 48u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QAbstractFormBuilder)
+8 QAbstractFormBuilder::~QAbstractFormBuilder
+12 QAbstractFormBuilder::~QAbstractFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QAbstractFormBuilder::create
+32 QAbstractFormBuilder::create
+36 QAbstractFormBuilder::create
+40 QAbstractFormBuilder::create
+44 QAbstractFormBuilder::create
+48 QAbstractFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QAbstractFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QAbstractFormBuilder::createWidget
+68 QAbstractFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QAbstractFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QAbstractFormBuilder::addItem
+96 QAbstractFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+
+Class QAbstractFormBuilder
+ size=28 align=4
+ base size=28 base align=4
+QAbstractFormBuilder (0xb64f2400) 0
+ vptr=((& QAbstractFormBuilder::_ZTV20QAbstractFormBuilder) + 8u)
+
+Vtable for QDesignerContainerExtension
+QDesignerContainerExtension::_ZTV27QDesignerContainerExtension: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerContainerExtension)
+8 QDesignerContainerExtension::~QDesignerContainerExtension
+12 QDesignerContainerExtension::~QDesignerContainerExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerContainerExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerContainerExtension (0xb64f2800) 0 nearly-empty
+ vptr=((& QDesignerContainerExtension::_ZTV27QDesignerContainerExtension) + 8u)
+
+Vtable for QFormBuilder
+QFormBuilder::_ZTV12QFormBuilder: 49u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QFormBuilder)
+8 QFormBuilder::~QFormBuilder
+12 QFormBuilder::~QFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QFormBuilder::create
+32 QFormBuilder::create
+36 QFormBuilder::create
+40 QFormBuilder::create
+44 QFormBuilder::create
+48 QFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QFormBuilder::createWidget
+68 QFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QFormBuilder::addItem
+96 QFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+192 QFormBuilder::updateCustomWidgets
+
+Class QFormBuilder
+ size=36 align=4
+ base size=36 base align=4
+QFormBuilder (0xb64f2940) 0
+ vptr=((& QFormBuilder::_ZTV12QFormBuilder) + 8u)
+ QAbstractFormBuilder (0xb64f2980) 0
+ primary-for QFormBuilder (0xb64f2940)
+
+Vtable for QExtensionManager
+QExtensionManager::_ZTV17QExtensionManager: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QExtensionManager)
+8 QExtensionManager::metaObject
+12 QExtensionManager::qt_metacast
+16 QExtensionManager::qt_metacall
+20 QExtensionManager::~QExtensionManager
+24 QExtensionManager::~QExtensionManager
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QExtensionManager::registerExtensions
+60 QExtensionManager::unregisterExtensions
+64 QExtensionManager::extension
+68 (int (*)(...))-0x00000000000000008
+72 (int (*)(...))(& _ZTI17QExtensionManager)
+76 QExtensionManager::_ZThn8_N17QExtensionManagerD1Ev
+80 QExtensionManager::_ZThn8_N17QExtensionManagerD0Ev
+84 QExtensionManager::_ZThn8_N17QExtensionManager18registerExtensionsEP25QAbstractExtensionFactoryRK7QString
+88 QExtensionManager::_ZThn8_N17QExtensionManager20unregisterExtensionsEP25QAbstractExtensionFactoryRK7QString
+92 QExtensionManager::_ZThn8_NK17QExtensionManager9extensionEP7QObjectRK7QString
+
+Class QExtensionManager
+ size=20 align=4
+ base size=20 base align=4
+QExtensionManager (0xb64f2b40) 0
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 8u)
+ QObject (0xb64f2b80) 0
+ primary-for QExtensionManager (0xb64f2b40)
+ QAbstractExtensionManager (0xb64f2bc0) 8 nearly-empty
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 76u)
+
diff --git a/tests/auto/bic/data/QtDesigner.4.4.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtDesigner.4.4.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..01f5de5e7
--- /dev/null
+++ b/tests/auto/bic/data/QtDesigner.4.4.0.linux-gcc-ia32.txt
@@ -0,0 +1,4431 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb77a5c6c) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb77b3294) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb77b3c30) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb77b3ce4) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb77cace4) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb77e3780) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb77e3bf4) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0xb69fc384) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0xb6a21640) 0
+ QBasicAtomicInt (0xb6a23348) 0
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb6a34294) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb6a6f474) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb6a34870) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb6a9e474) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb699df3c) 0 empty
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb67ec258) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb67f4780) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb69b20b4) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb68623c0) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb68b4c6c) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb6706f00) 0
+ QString (0xb6761708) 0
+
+Class QStringRef
+ size=12 align=4
+ base size=12 base align=4
+QStringRef (0xb67798ac) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb67c5618) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::bad_exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb65d3500) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb67c5924) 0 nearly-empty
+ primary-for std::bad_exception (0xb65d3500)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb65d3640) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb67c5bf4) 0 nearly-empty
+ primary-for std::bad_alloc (0xb65d3640)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb67c5ec4) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb65e7078) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb65e703c) 0
+
+Class QTextCodec::ConverterState
+ size=28 align=4
+ base size=28 base align=4
+QTextCodec::ConverterState (0xb6684168) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTextCodec)
+8 __cxa_pure_virtual
+12 QTextCodec::aliases
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QTextCodec::~QTextCodec
+32 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=4 align=4
+ base size=4 base align=4
+QTextCodec (0xb66716cc) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 8u)
+
+Class QTextEncoder
+ size=32 align=4
+ base size=32 base align=4
+QTextEncoder (0xb66b0c6c) 0
+
+Class QTextDecoder
+ size=32 align=4
+ base size=32 base align=4
+QTextDecoder (0xb66bc1e0) 0
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb66bc7bc) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb66bd400) 0
+ QGenericArgument (0xb66bcbf4) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb66bcf00) 0
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=24 align=4
+ base size=24 base align=4
+QObjectData (0xb64e012c) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb64e0384) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb65168e8) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb652e280) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb652c258) 0
+ primary-for QIODevice (0xb652e280)
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb65623fc) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb6583474) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb65aad5c) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb65ad380) 0
+ QList<QString> (0xb65b730c) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QFactoryInterface)
+8 QFactoryInterface::~QFactoryInterface
+12 QFactoryInterface::~QFactoryInterface
+16 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QFactoryInterface (0xb63fc30c) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 8u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+8 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+12 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QTextCodecFactoryInterface (0xb63fb340) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 8u)
+ QFactoryInterface (0xb63fc8e8) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb63fb340)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+8 QTextCodecPlugin::metaObject
+12 QTextCodecPlugin::qt_metacast
+16 QTextCodecPlugin::qt_metacall
+20 QTextCodecPlugin::~QTextCodecPlugin
+24 QTextCodecPlugin::~QTextCodecPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 QTextCodecPlugin::keys
+80 QTextCodecPlugin::create
+84 (int (*)(...))-0x000000008
+88 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+92 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD1Ev
+96 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD0Ev
+100 QTextCodecPlugin::_ZThn8_NK16QTextCodecPlugin4keysEv
+104 QTextCodecPlugin::_ZThn8_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=12 align=4
+ base size=12 base align=4
+QTextCodecPlugin (0xb63fef00) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 8u)
+ QObject (0xb63fcc30) 0
+ primary-for QTextCodecPlugin (0xb63fef00)
+ QTextCodecFactoryInterface (0xb63fb4c0) 8 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 92u)
+ QFactoryInterface (0xb63fcc6c) 8 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb63fb4c0)
+
+Class QMutex
+ size=4 align=4
+ base size=4 base align=4
+QMutex (0xb64124b0) 0
+
+Class QMutexLocker
+ size=4 align=4
+ base size=4 base align=4
+QMutexLocker (0xb6412d98) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+8 QtConcurrent::Exception::~Exception
+12 QtConcurrent::Exception::~Exception
+16 std::exception::what
+20 QtConcurrent::Exception::raise
+24 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::Exception (0xb63fbd80) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 8u)
+ std::exception (0xb6425294) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb63fbd80)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+8 QtConcurrent::UnhandledException::~UnhandledException
+12 QtConcurrent::UnhandledException::~UnhandledException
+16 std::exception::what
+20 QtConcurrent::UnhandledException::raise
+24 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::UnhandledException (0xb63fbe40) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 8u)
+ QtConcurrent::Exception (0xb63fbe80) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0xb63fbe40)
+ std::exception (0xb6425438) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb63fbe80)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionHolder (0xb64255dc) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionStore (0xb64257bc) 0
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb6425834) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb64257f8) 0
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb62e40f0) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb62e40b4) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb62ed9d8) 0 empty
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb636ec30) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb636ec6c) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTextStream)
+8 QTextStream::~QTextStream
+12 QTextStream::~QTextStream
+
+Class QTextStream
+ size=8 align=4
+ base size=8 base align=4
+QTextStream (0xb636ed20) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 8u)
+
+Class QTextStreamManipulator
+ size=24 align=4
+ base size=22 base align=4
+QTextStreamManipulator (0xb61d512c) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextIStream)
+8 QTextIStream::~QTextIStream
+12 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=8 align=4
+ base size=8 base align=4
+QTextIStream (0xb61dd200) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 8u)
+ QTextStream (0xb61e81a4) 0
+ primary-for QTextIStream (0xb61dd200)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextOStream)
+8 QTextOStream::~QTextOStream
+12 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=8 align=4
+ base size=8 base align=4
+QTextOStream (0xb61dd4c0) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 8u)
+ QTextStream (0xb61e8c30) 0
+ primary-for QTextOStream (0xb61dd4c0)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb61f5618) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb61f5924) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb61f5960) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb61f5a8c) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb620e078) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb620e0b4) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb620e0f0) 0
+
+Class QDebug::Stream
+ size=24 align=4
+ base size=22 base align=4
+QDebug::Stream (0xb60d403c) 0
+
+Class QDebug
+ size=4 align=4
+ base size=4 base align=4
+QDebug (0xb60d4000) 0
+
+Class QtConcurrent::ResultItem
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultItem (0xb6117dd4) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultIteratorBase (0xb61338ac) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+8 QtConcurrent::ResultStoreBase::~ResultStoreBase
+12 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=28 align=4
+ base size=28 base align=4
+QtConcurrent::ResultStoreBase (0xb6133e88) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 8u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+8 QFutureInterfaceBase::~QFutureInterfaceBase
+12 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureInterfaceBase (0xb61565a0) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 8u)
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+8 QFutureWatcherBase::metaObject
+12 QFutureWatcherBase::qt_metacast
+16 QFutureWatcherBase::qt_metacall
+20 QFutureWatcherBase::~QFutureWatcherBase
+24 QFutureWatcherBase::~QFutureWatcherBase
+28 QFutureWatcherBase::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QFutureWatcherBase::connectNotify
+52 QFutureWatcherBase::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureWatcherBase (0xb5fc9ac0) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 8u)
+ QObject (0xb5fcff00) 0
+ primary-for QFutureWatcherBase (0xb5fc9ac0)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QRunnable)
+8 __cxa_pure_virtual
+12 QRunnable::~QRunnable
+16 QRunnable::~QRunnable
+
+Class QRunnable
+ size=8 align=4
+ base size=8 base align=4
+QRunnable (0xb5ff6924) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 8u)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QThread)
+8 QThread::metaObject
+12 QThread::qt_metacast
+16 QThread::qt_metacall
+20 QThread::~QThread
+24 QThread::~QThread
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QThread::run
+
+Class QThread
+ size=8 align=4
+ base size=8 base align=4
+QThread (0xb5fedcc0) 0
+ vptr=((& QThread::_ZTV7QThread) + 8u)
+ QObject (0xb600621c) 0
+ primary-for QThread (0xb5fedcc0)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QThreadPool)
+8 QThreadPool::metaObject
+12 QThreadPool::qt_metacast
+16 QThreadPool::qt_metacall
+20 QThreadPool::~QThreadPool
+24 QThreadPool::~QThreadPool
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QThreadPool
+ size=8 align=4
+ base size=8 base align=4
+QThreadPool (0xb601b000) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 8u)
+ QObject (0xb601903c) 0
+ primary-for QThreadPool (0xb601b000)
+
+Class QWaitCondition
+ size=4 align=4
+ base size=4 base align=4
+QWaitCondition (0xb6019a50) 0
+
+Class QtConcurrent::ThreadEngineSemaphore
+ size=12 align=4
+ base size=12 base align=4
+QtConcurrent::ThreadEngineSemaphore (0xb6019d20) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+8 QtConcurrent::ThreadEngineBase::run
+12 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+16 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+20 QtConcurrent::ThreadEngineBase::start
+24 QtConcurrent::ThreadEngineBase::finish
+28 QtConcurrent::ThreadEngineBase::threadFunction
+32 QtConcurrent::ThreadEngineBase::shouldStartThread
+36 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+40 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=32 align=4
+ base size=32 base align=4
+QtConcurrent::ThreadEngineBase (0xb601b6c0) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 8u)
+ QRunnable (0xb602ea14) 0
+ primary-for QtConcurrent::ThreadEngineBase (0xb601b6c0)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 12u)
+4 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 68u)
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0xb6041d20) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0xb6041d5c) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0xb6044540) 0 empty
+ std::input_iterator_tag (0xb6041d98) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0xb60445c0) 0 empty
+ std::forward_iterator_tag (0xb6044600) 0 empty
+ std::input_iterator_tag (0xb6041dd4) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0xb6044680) 0 empty
+ std::bidirectional_iterator_tag (0xb60446c0) 0 empty
+ std::forward_iterator_tag (0xb6044700) 0 empty
+ std::input_iterator_tag (0xb6041e10) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0xb605e0b4) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0xb605e0f0) 0 empty
+
+Class lconv
+ size=56 align=4
+ base size=56 base align=4
+lconv (0xb5f52e10) 0
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0xb5f5f078) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0xb5f5f0b4) 0
+
+Class tm
+ size=44 align=4
+ base size=44 base align=4
+tm (0xb5f5f168) 0
+
+Class itimerspec
+ size=16 align=4
+ base size=16 base align=4
+itimerspec (0xb5f5f1e0) 0
+
+Class _pthread_cleanup_buffer
+ size=16 align=4
+ base size=16 base align=4
+_pthread_cleanup_buffer (0xb5f5f3fc) 0
+
+Class __pthread_cleanup_frame
+ size=16 align=4
+ base size=16 base align=4
+__pthread_cleanup_frame (0xb5f5f5a0) 0
+
+Class __pthread_cleanup_class
+ size=16 align=4
+ base size=16 base align=4
+__pthread_cleanup_class (0xb5f5f5dc) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+8 __cxxabiv1::__forced_unwind::~__forced_unwind
+12 __cxxabiv1::__forced_unwind::~__forced_unwind
+16 __cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=4 align=4
+ base size=4 base align=4
+__cxxabiv1::__forced_unwind (0xb5e050b4) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 8u)
+
+Class std::locale
+ size=4 align=4
+ base size=4 base align=4
+std::locale (0xb5cfd9d8) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTINSt6locale5facetE)
+8 std::locale::facet::~facet
+12 std::locale::facet::~facet
+
+Class std::locale::facet
+ size=8 align=4
+ base size=8 base align=4
+std::locale::facet (0xb5db9e4c) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 8u)
+
+Class std::locale::id
+ size=4 align=4
+ base size=4 base align=4
+std::locale::id (0xb5dc4834) 0
+
+Class std::locale::_Impl
+ size=20 align=4
+ base size=20 base align=4
+std::locale::_Impl (0xb5dc4b7c) 0
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTINSt8ios_base7failureE)
+8 std::ios_base::failure::~failure
+12 std::ios_base::failure::~failure
+16 std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=8 align=4
+ base size=8 base align=4
+std::ios_base::failure (0xb5c0b340) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureE) + 8u)
+ std::exception (0xb5c09a14) 0 nearly-empty
+ primary-for std::ios_base::failure (0xb5c0b340)
+
+Class std::ios_base::_Callback_list
+ size=16 align=4
+ base size=16 base align=4
+std::ios_base::_Callback_list (0xb5c18ca8) 0
+
+Class std::ios_base::_Words
+ size=8 align=4
+ base size=8 base align=4
+std::ios_base::_Words (0xb5c1a258) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0xb5c1a654) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt8ios_base)
+8 std::ios_base::~ios_base
+12 std::ios_base::~ios_base
+
+Class std::ios_base
+ size=112 align=4
+ base size=112 base align=4
+std::ios_base (0xb5c099d8) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 8u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0xb5c66564) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0xb5afe078) 0 empty
+
+VTT for std::basic_ostream<char, std::char_traits<char> >
+std::basic_ostream<char, std::char_traits<char> >::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 12u)
+4 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 32u)
+
+VTT for std::basic_ostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 32u)
+
+VTT for std::basic_istream<char, std::char_traits<char> >
+std::basic_istream<char, std::char_traits<char> >::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 12u)
+4 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 32u)
+
+VTT for std::basic_istream<wchar_t, std::char_traits<wchar_t> >
+std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 32u)
+
+Construction vtable for std::basic_istream<char, std::char_traits<char> > (0xb58c2780 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si: 10u entries
+0 12u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISi)
+12 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+16 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+20 -12u
+24 (int (*)(...))-0x00000000c
+28 (int (*)(...))(& _ZTISi)
+32 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n12_NSiD1Ev
+36 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n12_NSiD0Ev
+
+Construction vtable for std::basic_ostream<char, std::char_traits<char> > (0xb58c2800 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So: 10u entries
+0 4u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISo)
+12 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+16 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+20 -4u
+24 (int (*)(...))-0x000000004
+28 (int (*)(...))(& _ZTISo)
+32 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n12_NSoD1Ev
+36 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n12_NSoD0Ev
+
+VTT for std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 12u)
+4 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 12u)
+8 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 32u)
+12 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So) + 12u)
+16 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So) + 32u)
+20 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 52u)
+24 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 32u)
+
+Construction vtable for std::basic_istream<wchar_t, std::char_traits<wchar_t> > (0xb58c2b00 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 12u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+12 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+16 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+20 -12u
+24 (int (*)(...))-0x00000000c
+28 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+32 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED1Ev
+36 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED0Ev
+
+Construction vtable for std::basic_ostream<wchar_t, std::char_traits<wchar_t> > (0xb58c2b80 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E: 10u entries
+0 4u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+12 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+16 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+20 -4u
+24 (int (*)(...))-0x000000004
+28 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+32 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev
+36 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev
+
+VTT for std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 12u)
+8 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 32u)
+12 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E) + 12u)
+16 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E) + 32u)
+20 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 52u)
+24 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 32u)
+
+Class QtConcurrent::BlockSizeManager
+ size=72 align=4
+ base size=72 base align=4
+QtConcurrent::BlockSizeManager (0xb58f6168) 0
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0xb577399c) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb5789200) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb5789240) 0
+ primary-for QFile (0xb5789200)
+ QObject (0xb5773a8c) 0
+ primary-for QIODevice (0xb5789240)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb57a7fb4) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb55d77bc) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0xb563899c) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0xb56389d8) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=20 align=4
+ base size=20 base align=4
+QAbstractFileEngine::MapExtensionOption (0xb5614640) 0
+ QAbstractFileEngine::ExtensionOption (0xb5638a14) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::MapExtensionReturn (0xb56146c0) 0
+ QAbstractFileEngine::ExtensionReturn (0xb5638b04) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::UnMapExtensionOption (0xb5614740) 0
+ QAbstractFileEngine::ExtensionOption (0xb5638b40) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+8 QAbstractFileEngine::~QAbstractFileEngine
+12 QAbstractFileEngine::~QAbstractFileEngine
+16 QAbstractFileEngine::open
+20 QAbstractFileEngine::close
+24 QAbstractFileEngine::flush
+28 QAbstractFileEngine::size
+32 QAbstractFileEngine::pos
+36 QAbstractFileEngine::seek
+40 QAbstractFileEngine::isSequential
+44 QAbstractFileEngine::remove
+48 QAbstractFileEngine::copy
+52 QAbstractFileEngine::rename
+56 QAbstractFileEngine::link
+60 QAbstractFileEngine::mkdir
+64 QAbstractFileEngine::rmdir
+68 QAbstractFileEngine::setSize
+72 QAbstractFileEngine::caseSensitive
+76 QAbstractFileEngine::isRelativePath
+80 QAbstractFileEngine::entryList
+84 QAbstractFileEngine::fileFlags
+88 QAbstractFileEngine::setPermissions
+92 QAbstractFileEngine::fileName
+96 QAbstractFileEngine::ownerId
+100 QAbstractFileEngine::owner
+104 QAbstractFileEngine::fileTime
+108 QAbstractFileEngine::setFileName
+112 QAbstractFileEngine::handle
+116 QAbstractFileEngine::beginEntryList
+120 QAbstractFileEngine::endEntryList
+124 QAbstractFileEngine::read
+128 QAbstractFileEngine::readLine
+132 QAbstractFileEngine::write
+136 QAbstractFileEngine::extension
+140 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngine (0xb56380f0) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 8u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+8 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+12 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+16 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngineHandler (0xb565703c) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 8u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+8 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+12 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QAbstractFileEngineIterator::currentFileInfo
+32 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngineIterator (0xb56571e0) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 8u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QBuffer)
+8 QBuffer::metaObject
+12 QBuffer::qt_metacast
+16 QBuffer::qt_metacall
+20 QBuffer::~QBuffer
+24 QBuffer::~QBuffer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QBuffer::open
+64 QBuffer::close
+68 QBuffer::pos
+72 QBuffer::size
+76 QBuffer::seek
+80 QBuffer::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QBuffer::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QBuffer::readData
+112 QIODevice::readLineData
+116 QBuffer::writeData
+
+Class QBuffer
+ size=8 align=4
+ base size=8 base align=4
+QBuffer (0xb5614980) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 8u)
+ QIODevice (0xb56149c0) 0
+ primary-for QBuffer (0xb5614980)
+ QObject (0xb5657708) 0
+ primary-for QIODevice (0xb56149c0)
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QDirIterator)
+8 QDirIterator::~QDirIterator
+12 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=8 align=4
+ base size=8 base align=4
+QDirIterator (0xb5669384) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 8u)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+8 QFileSystemWatcher::metaObject
+12 QFileSystemWatcher::qt_metacast
+16 QFileSystemWatcher::qt_metacall
+20 QFileSystemWatcher::~QFileSystemWatcher
+24 QFileSystemWatcher::~QFileSystemWatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=8 align=4
+ base size=8 base align=4
+QFileSystemWatcher (0xb5614e00) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 8u)
+ QObject (0xb5677960) 0
+ primary-for QFileSystemWatcher (0xb5614e00)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QFSFileEngine)
+8 QFSFileEngine::~QFSFileEngine
+12 QFSFileEngine::~QFSFileEngine
+16 QFSFileEngine::open
+20 QFSFileEngine::close
+24 QFSFileEngine::flush
+28 QFSFileEngine::size
+32 QFSFileEngine::pos
+36 QFSFileEngine::seek
+40 QFSFileEngine::isSequential
+44 QFSFileEngine::remove
+48 QFSFileEngine::copy
+52 QFSFileEngine::rename
+56 QFSFileEngine::link
+60 QFSFileEngine::mkdir
+64 QFSFileEngine::rmdir
+68 QFSFileEngine::setSize
+72 QFSFileEngine::caseSensitive
+76 QFSFileEngine::isRelativePath
+80 QFSFileEngine::entryList
+84 QFSFileEngine::fileFlags
+88 QFSFileEngine::setPermissions
+92 QFSFileEngine::fileName
+96 QFSFileEngine::ownerId
+100 QFSFileEngine::owner
+104 QFSFileEngine::fileTime
+108 QFSFileEngine::setFileName
+112 QFSFileEngine::handle
+116 QFSFileEngine::beginEntryList
+120 QFSFileEngine::endEntryList
+124 QFSFileEngine::read
+128 QFSFileEngine::readLine
+132 QFSFileEngine::write
+136 QFSFileEngine::extension
+140 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QFSFileEngine (0xb568c0c0) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 8u)
+ QAbstractFileEngine (0xb568d30c) 0
+ primary-for QFSFileEngine (0xb568c0c0)
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QProcess)
+8 QProcess::metaObject
+12 QProcess::qt_metacast
+16 QProcess::qt_metacall
+20 QProcess::~QProcess
+24 QProcess::~QProcess
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QProcess::isSequential
+60 QIODevice::open
+64 QProcess::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QProcess::atEnd
+84 QIODevice::reset
+88 QProcess::bytesAvailable
+92 QProcess::bytesToWrite
+96 QProcess::canReadLine
+100 QProcess::waitForReadyRead
+104 QProcess::waitForBytesWritten
+108 QProcess::readData
+112 QIODevice::readLineData
+116 QProcess::writeData
+120 QProcess::setupChildProcess
+
+Class QProcess
+ size=8 align=4
+ base size=8 base align=4
+QProcess (0xb568c1c0) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 8u)
+ QIODevice (0xb568c200) 0
+ primary-for QProcess (0xb568c1c0)
+ QObject (0xb568dce4) 0
+ primary-for QIODevice (0xb568c200)
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSystemLocale)
+8 QSystemLocale::~QSystemLocale
+12 QSystemLocale::~QSystemLocale
+16 QSystemLocale::query
+20 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=4 align=4
+ base size=4 base align=4
+QSystemLocale (0xb56ad708) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 8u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0xb54c7b40) 0
+
+Class QLocale
+ size=4 align=4
+ base size=4 base align=4
+QLocale (0xb56ad924) 0
+
+Class QResource
+ size=4 align=4
+ base size=4 base align=4
+QResource (0xb54e1924) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb54e1e10) 0 empty
+
+Class QVariant::PrivateShared
+ size=8 align=4
+ base size=8 base align=4
+QVariant::PrivateShared (0xb55544b0) 0
+
+Class QVariant::Private::Data
+ size=8 align=4
+ base size=8 base align=4
+QVariant::Private::Data (0xb5554690) 0
+
+Class QVariant::Private
+ size=12 align=4
+ base size=12 base align=4
+QVariant::Private (0xb5554564) 0
+
+Class QVariant::Handler
+ size=36 align=4
+ base size=36 base align=4
+QVariant::Handler (0xb5554d5c) 0
+
+Class QVariant
+ size=12 align=4
+ base size=12 base align=4
+QVariant (0xb553d7f8) 0
+
+Class QVariantComparisonHelper
+ size=4 align=4
+ base size=4 base align=4
+QVariantComparisonHelper (0xb55ad708) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QSettings)
+8 QSettings::metaObject
+12 QSettings::qt_metacast
+16 QSettings::qt_metacall
+20 QSettings::~QSettings
+24 QSettings::~QSettings
+28 QSettings::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSettings
+ size=8 align=4
+ base size=8 base align=4
+QSettings (0xb55b66c0) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 8u)
+ QObject (0xb53bd2d0) 0
+ primary-for QSettings (0xb55b66c0)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QTemporaryFile)
+8 QTemporaryFile::metaObject
+12 QTemporaryFile::qt_metacast
+16 QTemporaryFile::qt_metacall
+20 QTemporaryFile::~QTemporaryFile
+24 QTemporaryFile::~QTemporaryFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QTemporaryFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=8 align=4
+ base size=8 base align=4
+QTemporaryFile (0xb53ea2c0) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 8u)
+ QFile (0xb53ea300) 0
+ primary-for QTemporaryFile (0xb53ea2c0)
+ QIODevice (0xb53ea340) 0
+ primary-for QFile (0xb53ea300)
+ QObject (0xb53f7000) 0
+ primary-for QIODevice (0xb53ea340)
+
+Class QUrl
+ size=4 align=4
+ base size=4 base align=4
+QUrl (0xb5403168) 0
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QEventLoop)
+8 QEventLoop::metaObject
+12 QEventLoop::qt_metacast
+16 QEventLoop::qt_metacall
+20 QEventLoop::~QEventLoop
+24 QEventLoop::~QEventLoop
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QEventLoop
+ size=8 align=4
+ base size=8 base align=4
+QEventLoop (0xb53eaec0) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 8u)
+ QObject (0xb543b99c) 0
+ primary-for QEventLoop (0xb53eaec0)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+8 QAbstractEventDispatcher::metaObject
+12 QAbstractEventDispatcher::qt_metacast
+16 QAbstractEventDispatcher::qt_metacall
+20 QAbstractEventDispatcher::~QAbstractEventDispatcher
+24 QAbstractEventDispatcher::~QAbstractEventDispatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 QAbstractEventDispatcher::startingUp
+104 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=8 align=4
+ base size=8 base align=4
+QAbstractEventDispatcher (0xb5454240) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 8u)
+ QObject (0xb545f384) 0
+ primary-for QAbstractEventDispatcher (0xb5454240)
+
+Class QModelIndex
+ size=16 align=4
+ base size=16 base align=4
+QModelIndex (0xb547321c) 0
+
+Class QPersistentModelIndex
+ size=4 align=4
+ base size=4 base align=4
+QPersistentModelIndex (0xb5484708) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractItemModel)
+8 QAbstractItemModel::metaObject
+12 QAbstractItemModel::qt_metacast
+16 QAbstractItemModel::qt_metacall
+20 QAbstractItemModel::~QAbstractItemModel
+24 QAbstractItemModel::~QAbstractItemModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractItemModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemModel (0xb5454e00) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 8u)
+ QObject (0xb5484f3c) 0
+ primary-for QAbstractItemModel (0xb5454e00)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTableModel)
+8 QAbstractTableModel::metaObject
+12 QAbstractTableModel::qt_metacast
+16 QAbstractTableModel::qt_metacall
+20 QAbstractTableModel::~QAbstractTableModel
+24 QAbstractTableModel::~QAbstractTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractTableModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTableModel (0xb54ab2c0) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 8u)
+ QAbstractItemModel (0xb54ab300) 0
+ primary-for QAbstractTableModel (0xb54ab2c0)
+ QObject (0xb54aeac8) 0
+ primary-for QAbstractItemModel (0xb54ab300)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractListModel)
+8 QAbstractListModel::metaObject
+12 QAbstractListModel::qt_metacast
+16 QAbstractListModel::qt_metacall
+20 QAbstractListModel::~QAbstractListModel
+24 QAbstractListModel::~QAbstractListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 __cxa_pure_virtual
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractListModel (0xb54ab540) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 8u)
+ QAbstractItemModel (0xb54ab580) 0
+ primary-for QAbstractListModel (0xb54ab540)
+ QObject (0xb52ba528) 0
+ primary-for QAbstractItemModel (0xb54ab580)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0xb52cbfb4) 0
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QEvent)
+8 QEvent::~QEvent
+12 QEvent::~QEvent
+
+Class QEvent
+ size=12 align=4
+ base size=12 base align=4
+QEvent (0xb52d9834) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 8u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTimerEvent)
+8 QTimerEvent::~QTimerEvent
+12 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=16 align=4
+ base size=16 base align=4
+QTimerEvent (0xb54abf80) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 8u)
+ QEvent (0xb52eb528) 0
+ primary-for QTimerEvent (0xb54abf80)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QChildEvent)
+8 QChildEvent::~QChildEvent
+12 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=16 align=4
+ base size=16 base align=4
+QChildEvent (0xb52ef040) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 8u)
+ QEvent (0xb52eb780) 0
+ primary-for QChildEvent (0xb52ef040)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QCustomEvent)
+8 QCustomEvent::~QCustomEvent
+12 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=12 align=4
+ base size=12 base align=4
+QCustomEvent (0xb52ef200) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 8u)
+ QEvent (0xb52eb654) 0
+ primary-for QCustomEvent (0xb52ef200)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+8 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+12 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=16 align=4
+ base size=16 base align=4
+QDynamicPropertyChangeEvent (0xb52ef300) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 8u)
+ QEvent (0xb52fb384) 0
+ primary-for QDynamicPropertyChangeEvent (0xb52ef300)
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QCoreApplication)
+8 QCoreApplication::metaObject
+12 QCoreApplication::qt_metacast
+16 QCoreApplication::qt_metacall
+20 QCoreApplication::~QCoreApplication
+24 QCoreApplication::~QCoreApplication
+28 QCoreApplication::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QCoreApplication::notify
+60 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=8 align=4
+ base size=8 base align=4
+QCoreApplication (0xb52ef3c0) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 8u)
+ QObject (0xb52fb5dc) 0
+ primary-for QCoreApplication (0xb52ef3c0)
+
+Class __exception
+ size=32 align=4
+ base size=32 base align=4
+__exception (0xb5340000) 0
+
+Class QMetaMethod
+ size=8 align=4
+ base size=8 base align=4
+QMetaMethod (0xb5340384) 0
+
+Class QMetaEnum
+ size=8 align=4
+ base size=8 base align=4
+QMetaEnum (0xb5340924) 0
+
+Class QMetaProperty
+ size=20 align=4
+ base size=20 base align=4
+QMetaProperty (0xb5340e4c) 0
+
+Class QMetaClassInfo
+ size=8 align=4
+ base size=8 base align=4
+QMetaClassInfo (0xb5357168) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QMimeData)
+8 QMimeData::metaObject
+12 QMimeData::qt_metacast
+16 QMimeData::qt_metacall
+20 QMimeData::~QMimeData
+24 QMimeData::~QMimeData
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QMimeData::hasFormat
+60 QMimeData::formats
+64 QMimeData::retrieveData
+
+Class QMimeData
+ size=8 align=4
+ base size=8 base align=4
+QMimeData (0xb5349640) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 8u)
+ QObject (0xb53575a0) 0
+ primary-for QMimeData (0xb5349640)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+8 QObjectCleanupHandler::metaObject
+12 QObjectCleanupHandler::qt_metacast
+16 QObjectCleanupHandler::qt_metacall
+20 QObjectCleanupHandler::~QObjectCleanupHandler
+24 QObjectCleanupHandler::~QObjectCleanupHandler
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=12 align=4
+ base size=12 base align=4
+QObjectCleanupHandler (0xb5349900) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 8u)
+ QObject (0xb536a0f0) 0
+ primary-for QObjectCleanupHandler (0xb5349900)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSharedMemory)
+8 QSharedMemory::metaObject
+12 QSharedMemory::qt_metacast
+16 QSharedMemory::qt_metacall
+20 QSharedMemory::~QSharedMemory
+24 QSharedMemory::~QSharedMemory
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=8 align=4
+ base size=8 base align=4
+QSharedMemory (0xb5349b40) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 8u)
+ QObject (0xb536a99c) 0
+ primary-for QSharedMemory (0xb5349b40)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSignalMapper)
+8 QSignalMapper::metaObject
+12 QSignalMapper::qt_metacast
+16 QSignalMapper::qt_metacall
+20 QSignalMapper::~QSignalMapper
+24 QSignalMapper::~QSignalMapper
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=8 align=4
+ base size=8 base align=4
+QSignalMapper (0xb5349e00) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 8u)
+ QObject (0xb537b780) 0
+ primary-for QSignalMapper (0xb5349e00)
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QSocketNotifier)
+8 QSocketNotifier::metaObject
+12 QSocketNotifier::qt_metacast
+16 QSocketNotifier::qt_metacall
+20 QSocketNotifier::~QSocketNotifier
+24 QSocketNotifier::~QSocketNotifier
+28 QSocketNotifier::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=20 align=4
+ base size=17 base align=4
+QSocketNotifier (0xb538d0c0) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 8u)
+ QObject (0xb5385924) 0
+ primary-for QSocketNotifier (0xb538d0c0)
+
+Class QSystemSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSystemSemaphore (0xb5396960) 0
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QTimer)
+8 QTimer::metaObject
+12 QTimer::qt_metacast
+16 QTimer::qt_metacall
+20 QTimer::~QTimer
+24 QTimer::~QTimer
+28 QObject::event
+32 QObject::eventFilter
+36 QTimer::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QTimer
+ size=24 align=4
+ base size=21 base align=4
+QTimer (0xb538d440) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 8u)
+ QObject (0xb5396e88) 0
+ primary-for QTimer (0xb538d440)
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTranslator)
+8 QTranslator::metaObject
+12 QTranslator::qt_metacast
+16 QTranslator::qt_metacall
+20 QTranslator::~QTranslator
+24 QTranslator::~QTranslator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTranslator::translate
+60 QTranslator::isEmpty
+
+Class QTranslator
+ size=8 align=4
+ base size=8 base align=4
+QTranslator (0xb538d8c0) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 8u)
+ QObject (0xb53a03c0) 0
+ primary-for QTranslator (0xb538d8c0)
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QLibrary)
+8 QLibrary::metaObject
+12 QLibrary::qt_metacast
+16 QLibrary::qt_metacall
+20 QLibrary::~QLibrary
+24 QLibrary::~QLibrary
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QLibrary
+ size=16 align=4
+ base size=13 base align=4
+QLibrary (0xb538dbc0) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 8u)
+ QObject (0xb53b4e10) 0
+ primary-for QLibrary (0xb538dbc0)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QPluginLoader)
+8 QPluginLoader::metaObject
+12 QPluginLoader::qt_metacast
+16 QPluginLoader::qt_metacall
+20 QPluginLoader::~QPluginLoader
+24 QPluginLoader::~QPluginLoader
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=16 align=4
+ base size=13 base align=4
+QPluginLoader (0xb538df40) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 8u)
+ QObject (0xb51d48e8) 0
+ primary-for QPluginLoader (0xb538df40)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0xb51e64b0) 0
+
+Class QReadWriteLock
+ size=4 align=4
+ base size=4 base align=4
+QReadWriteLock (0xb51f730c) 0
+
+Class QReadLocker
+ size=4 align=4
+ base size=4 base align=4
+QReadLocker (0xb51f7690) 0
+
+Class QWriteLocker
+ size=4 align=4
+ base size=4 base align=4
+QWriteLocker (0xb5206b7c) 0
+
+Class QSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSemaphore (0xb5215078) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0xb5215348) 0
+
+Class QBitArray
+ size=4 align=4
+ base size=4 base align=4
+QBitArray (0xb5215744) 0
+
+Class QBitRef
+ size=8 align=4
+ base size=8 base align=4
+QBitRef (0xb524e474) 0
+
+Class QByteArrayMatcher
+ size=1032 align=4
+ base size=1032 base align=4
+QByteArrayMatcher (0xb52593fc) 0
+
+Class QCryptographicHash
+ size=4 align=4
+ base size=4 base align=4
+QCryptographicHash (0xb5259dd4) 0
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0xb527f168) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0xb528abf4) 0
+
+Class QDateTime
+ size=4 align=4
+ base size=4 base align=4
+QDateTime (0xb52a1258) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb52a8b40) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb50acb40) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb50ceb04) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb50fb03c) 0
+
+Class QLinkedListData
+ size=20 align=4
+ base size=20 base align=4
+QLinkedListData (0xb5125690) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb518399c) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb4fb9618) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb4fe4474) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb5037f3c) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0xb5092b04) 0
+
+Class QTextBoundaryFinder
+ size=28 align=4
+ base size=28 base align=4
+QTextBoundaryFinder (0xb4e9dd20) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTimeLine)
+8 QTimeLine::metaObject
+12 QTimeLine::qt_metacast
+16 QTimeLine::qt_metacall
+20 QTimeLine::~QTimeLine
+24 QTimeLine::~QTimeLine
+28 QObject::event
+32 QObject::eventFilter
+36 QTimeLine::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=8 align=4
+ base size=8 base align=4
+QTimeLine (0xb4eb3bc0) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 8u)
+ QObject (0xb4ec16cc) 0
+ primary-for QTimeLine (0xb4eb3bc0)
+
+Class QXmlStreamStringRef
+ size=12 align=4
+ base size=12 base align=4
+QXmlStreamStringRef (0xb4ed3a8c) 0
+
+Class QXmlStreamAttribute
+ size=56 align=4
+ base size=53 base align=4
+QXmlStreamAttribute (0xb4ef6c30) 0
+
+Class QXmlStreamAttributes
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamAttributes (0xb4ef7640) 0
+ QVector<QXmlStreamAttribute> (0xb4f0f348) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=28 align=4
+ base size=28 base align=4
+QXmlStreamNamespaceDeclaration (0xb4f0f384) 0
+
+Class QXmlStreamNotationDeclaration
+ size=40 align=4
+ base size=40 base align=4
+QXmlStreamNotationDeclaration (0xb4f0fec4) 0
+
+Class QXmlStreamEntityDeclaration
+ size=64 align=4
+ base size=64 base align=4
+QXmlStreamEntityDeclaration (0xb4f32bb8) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+8 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+12 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+16 QXmlStreamEntityResolver::resolveEntity
+20 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamEntityResolver (0xb4f45c6c) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 8u)
+
+Class QXmlStreamReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamReader (0xb4f45e10) 0
+
+Class QXmlStreamWriter
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamWriter (0xb4f763fc) 0
+
+Class QDomImplementation
+ size=4 align=4
+ base size=4 base align=4
+QDomImplementation (0xb4f769d8) 0
+
+Class QDomNode
+ size=4 align=4
+ base size=4 base align=4
+QDomNode (0xb4f76ec4) 0
+
+Class QDomNodeList
+ size=4 align=4
+ base size=4 base align=4
+QDomNodeList (0xb4f960f0) 0
+
+Class QDomDocumentType
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentType (0xb4f70400) 0
+ QDomNode (0xb4f968ac) 0
+
+Class QDomDocument
+ size=4 align=4
+ base size=4 base align=4
+QDomDocument (0xb4f704c0) 0
+ QDomNode (0xb4f96e4c) 0
+
+Class QDomNamedNodeMap
+ size=4 align=4
+ base size=4 base align=4
+QDomNamedNodeMap (0xb4d9c5dc) 0
+
+Class QDomDocumentFragment
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentFragment (0xb4f70680) 0
+ QDomNode (0xb4d9cca8) 0
+
+Class QDomCharacterData
+ size=4 align=4
+ base size=4 base align=4
+QDomCharacterData (0xb4f70740) 0
+ QDomNode (0xb4daa258) 0
+
+Class QDomAttr
+ size=4 align=4
+ base size=4 base align=4
+QDomAttr (0xb4f70780) 0
+ QDomNode (0xb4daa780) 0
+
+Class QDomElement
+ size=4 align=4
+ base size=4 base align=4
+QDomElement (0xb4f70880) 0
+ QDomNode (0xb4daad20) 0
+
+Class QDomText
+ size=4 align=4
+ base size=4 base align=4
+QDomText (0xb4f70a40) 0
+ QDomCharacterData (0xb4f70a80) 0
+ QDomNode (0xb4db75a0) 0
+
+Class QDomComment
+ size=4 align=4
+ base size=4 base align=4
+QDomComment (0xb4f70b40) 0
+ QDomCharacterData (0xb4f70b80) 0
+ QDomNode (0xb4db7bf4) 0
+
+Class QDomCDATASection
+ size=4 align=4
+ base size=4 base align=4
+QDomCDATASection (0xb4f70c40) 0
+ QDomText (0xb4f70c80) 0
+ QDomCharacterData (0xb4f70cc0) 0
+ QDomNode (0xb4dc11a4) 0
+
+Class QDomNotation
+ size=4 align=4
+ base size=4 base align=4
+QDomNotation (0xb4f70d80) 0
+ QDomNode (0xb4dc1744) 0
+
+Class QDomEntity
+ size=4 align=4
+ base size=4 base align=4
+QDomEntity (0xb4f70e40) 0
+ QDomNode (0xb4dc1ce4) 0
+
+Class QDomEntityReference
+ size=4 align=4
+ base size=4 base align=4
+QDomEntityReference (0xb4f70f00) 0
+ QDomNode (0xb4dc7294) 0
+
+Class QDomProcessingInstruction
+ size=4 align=4
+ base size=4 base align=4
+QDomProcessingInstruction (0xb4f70fc0) 0
+ QDomNode (0xb4dc7834) 0
+
+Class QXmlNamespaceSupport
+ size=4 align=4
+ base size=4 base align=4
+QXmlNamespaceSupport (0xb4dc7dd4) 0
+
+Class QXmlAttributes::Attribute
+ size=16 align=4
+ base size=16 base align=4
+QXmlAttributes::Attribute (0xb4dd3168) 0
+
+Vtable for QXmlAttributes
+QXmlAttributes::_ZTV14QXmlAttributes: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlAttributes)
+8 QXmlAttributes::~QXmlAttributes
+12 QXmlAttributes::~QXmlAttributes
+
+Class QXmlAttributes
+ size=12 align=4
+ base size=12 base align=4
+QXmlAttributes (0xb4dd30b4) 0
+ vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 8u)
+
+Vtable for QXmlInputSource
+QXmlInputSource::_ZTV15QXmlInputSource: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlInputSource)
+8 QXmlInputSource::~QXmlInputSource
+12 QXmlInputSource::~QXmlInputSource
+16 QXmlInputSource::setData
+20 QXmlInputSource::setData
+24 QXmlInputSource::fetchData
+28 QXmlInputSource::data
+32 QXmlInputSource::next
+36 QXmlInputSource::reset
+40 QXmlInputSource::fromRawData
+
+Class QXmlInputSource
+ size=8 align=4
+ base size=8 base align=4
+QXmlInputSource (0xb4dd38e8) 0
+ vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 8u)
+
+Class QXmlParseException
+ size=4 align=4
+ base size=4 base align=4
+QXmlParseException (0xb4dd3b40) 0
+
+Vtable for QXmlReader
+QXmlReader::_ZTV10QXmlReader: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QXmlReader)
+8 QXmlReader::~QXmlReader
+12 QXmlReader::~QXmlReader
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+
+Class QXmlReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlReader (0xb4dd3ca8) 0 nearly-empty
+ vptr=((& QXmlReader::_ZTV10QXmlReader) + 8u)
+
+Vtable for QXmlSimpleReader
+QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlSimpleReader)
+8 QXmlSimpleReader::~QXmlSimpleReader
+12 QXmlSimpleReader::~QXmlSimpleReader
+16 QXmlSimpleReader::feature
+20 QXmlSimpleReader::setFeature
+24 QXmlSimpleReader::hasFeature
+28 QXmlSimpleReader::property
+32 QXmlSimpleReader::setProperty
+36 QXmlSimpleReader::hasProperty
+40 QXmlSimpleReader::setEntityResolver
+44 QXmlSimpleReader::entityResolver
+48 QXmlSimpleReader::setDTDHandler
+52 QXmlSimpleReader::DTDHandler
+56 QXmlSimpleReader::setContentHandler
+60 QXmlSimpleReader::contentHandler
+64 QXmlSimpleReader::setErrorHandler
+68 QXmlSimpleReader::errorHandler
+72 QXmlSimpleReader::setLexicalHandler
+76 QXmlSimpleReader::lexicalHandler
+80 QXmlSimpleReader::setDeclHandler
+84 QXmlSimpleReader::declHandler
+88 QXmlSimpleReader::parse
+92 QXmlSimpleReader::parse
+96 QXmlSimpleReader::parse
+100 QXmlSimpleReader::parseContinue
+
+Class QXmlSimpleReader
+ size=8 align=4
+ base size=8 base align=4
+QXmlSimpleReader (0xb4dcd500) 0
+ vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 8u)
+ QXmlReader (0xb4dd33c0) 0 nearly-empty
+ primary-for QXmlSimpleReader (0xb4dcd500)
+
+Vtable for QXmlLocator
+QXmlLocator::_ZTV11QXmlLocator: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QXmlLocator)
+8 QXmlLocator::~QXmlLocator
+12 QXmlLocator::~QXmlLocator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlLocator
+ size=4 align=4
+ base size=4 base align=4
+QXmlLocator (0xb4e014b0) 0 nearly-empty
+ vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 8u)
+
+Vtable for QXmlContentHandler
+QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlContentHandler)
+8 QXmlContentHandler::~QXmlContentHandler
+12 QXmlContentHandler::~QXmlContentHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QXmlContentHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlContentHandler (0xb4e01690) 0 nearly-empty
+ vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 8u)
+
+Vtable for QXmlErrorHandler
+QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlErrorHandler)
+8 QXmlErrorHandler::~QXmlErrorHandler
+12 QXmlErrorHandler::~QXmlErrorHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlErrorHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlErrorHandler (0xb4e019d8) 0 nearly-empty
+ vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 8u)
+
+Vtable for QXmlDTDHandler
+QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlDTDHandler)
+8 QXmlDTDHandler::~QXmlDTDHandler
+12 QXmlDTDHandler::~QXmlDTDHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QXmlDTDHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDTDHandler (0xb4e01d20) 0 nearly-empty
+ vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 8u)
+
+Vtable for QXmlEntityResolver
+QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlEntityResolver)
+8 QXmlEntityResolver::~QXmlEntityResolver
+12 QXmlEntityResolver::~QXmlEntityResolver
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlEntityResolver (0xb4e017bc) 0 nearly-empty
+ vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 8u)
+
+Vtable for QXmlLexicalHandler
+QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlLexicalHandler)
+8 QXmlLexicalHandler::~QXmlLexicalHandler
+12 QXmlLexicalHandler::~QXmlLexicalHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+
+Class QXmlLexicalHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlLexicalHandler (0xb4e132d0) 0 nearly-empty
+ vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 8u)
+
+Vtable for QXmlDeclHandler
+QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlDeclHandler)
+8 QXmlDeclHandler::~QXmlDeclHandler
+12 QXmlDeclHandler::~QXmlDeclHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlDeclHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDeclHandler (0xb4e13618) 0 nearly-empty
+ vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 8u)
+
+Vtable for QXmlDefaultHandler
+QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+8 QXmlDefaultHandler::~QXmlDefaultHandler
+12 QXmlDefaultHandler::~QXmlDefaultHandler
+16 QXmlDefaultHandler::setDocumentLocator
+20 QXmlDefaultHandler::startDocument
+24 QXmlDefaultHandler::endDocument
+28 QXmlDefaultHandler::startPrefixMapping
+32 QXmlDefaultHandler::endPrefixMapping
+36 QXmlDefaultHandler::startElement
+40 QXmlDefaultHandler::endElement
+44 QXmlDefaultHandler::characters
+48 QXmlDefaultHandler::ignorableWhitespace
+52 QXmlDefaultHandler::processingInstruction
+56 QXmlDefaultHandler::skippedEntity
+60 QXmlDefaultHandler::errorString
+64 QXmlDefaultHandler::warning
+68 QXmlDefaultHandler::error
+72 QXmlDefaultHandler::fatalError
+76 QXmlDefaultHandler::notationDecl
+80 QXmlDefaultHandler::unparsedEntityDecl
+84 QXmlDefaultHandler::resolveEntity
+88 QXmlDefaultHandler::startDTD
+92 QXmlDefaultHandler::endDTD
+96 QXmlDefaultHandler::startEntity
+100 QXmlDefaultHandler::endEntity
+104 QXmlDefaultHandler::startCDATA
+108 QXmlDefaultHandler::endCDATA
+112 QXmlDefaultHandler::comment
+116 QXmlDefaultHandler::attributeDecl
+120 QXmlDefaultHandler::internalEntityDecl
+124 QXmlDefaultHandler::externalEntityDecl
+128 (int (*)(...))-0x000000004
+132 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+136 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD1Ev
+140 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD0Ev
+144 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler7warningERK18QXmlParseException
+148 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler5errorERK18QXmlParseException
+152 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException
+156 QXmlDefaultHandler::_ZThn4_NK18QXmlDefaultHandler11errorStringEv
+160 (int (*)(...))-0x000000008
+164 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+168 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev
+172 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev
+176 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_
+180 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_
+184 QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv
+188 (int (*)(...))-0x00000000c
+192 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+196 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD1Ev
+200 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD0Ev
+204 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource
+208 QXmlDefaultHandler::_ZThn12_NK18QXmlDefaultHandler11errorStringEv
+212 (int (*)(...))-0x000000010
+216 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+220 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev
+224 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev
+228 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_
+232 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler6endDTDEv
+236 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler11startEntityERK7QString
+240 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler9endEntityERK7QString
+244 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler10startCDATAEv
+248 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8endCDATAEv
+252 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler7commentERK7QString
+256 QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv
+260 (int (*)(...))-0x000000014
+264 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+268 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD1Ev
+272 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD0Ev
+276 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_
+280 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_
+284 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_
+288 QXmlDefaultHandler::_ZThn20_NK18QXmlDefaultHandler11errorStringEv
+
+Class QXmlDefaultHandler
+ size=28 align=4
+ base size=28 base align=4
+QXmlDefaultHandler (0xb4e1c8f0) 0
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 8u)
+ QXmlContentHandler (0xb4e13960) 0 nearly-empty
+ primary-for QXmlDefaultHandler (0xb4e1c8f0)
+ QXmlErrorHandler (0xb4e1399c) 4 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 136u)
+ QXmlDTDHandler (0xb4e139d8) 8 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 168u)
+ QXmlEntityResolver (0xb4e13a14) 12 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 196u)
+ QXmlLexicalHandler (0xb4e13a50) 16 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 220u)
+ QXmlDeclHandler (0xb4e13a8c) 20 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 268u)
+
+Vtable for QAbstractExtensionFactory
+QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionFactory)
+8 QAbstractExtensionFactory::~QAbstractExtensionFactory
+12 QAbstractExtensionFactory::~QAbstractExtensionFactory
+16 __cxa_pure_virtual
+
+Class QAbstractExtensionFactory
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionFactory (0xb4e3f2d0) 0 nearly-empty
+ vptr=((& QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory) + 8u)
+
+Vtable for QAbstractExtensionManager
+QAbstractExtensionManager::_ZTV25QAbstractExtensionManager: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionManager)
+8 QAbstractExtensionManager::~QAbstractExtensionManager
+12 QAbstractExtensionManager::~QAbstractExtensionManager
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QAbstractExtensionManager
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionManager (0xb4e3f834) 0 nearly-empty
+ vptr=((& QAbstractExtensionManager::_ZTV25QAbstractExtensionManager) + 8u)
+
+Vtable for QExtensionManager
+QExtensionManager::_ZTV17QExtensionManager: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QExtensionManager)
+8 QExtensionManager::metaObject
+12 QExtensionManager::qt_metacast
+16 QExtensionManager::qt_metacall
+20 QExtensionManager::~QExtensionManager
+24 QExtensionManager::~QExtensionManager
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QExtensionManager::registerExtensions
+60 QExtensionManager::unregisterExtensions
+64 QExtensionManager::extension
+68 (int (*)(...))-0x000000008
+72 (int (*)(...))(& _ZTI17QExtensionManager)
+76 QExtensionManager::_ZThn8_N17QExtensionManagerD1Ev
+80 QExtensionManager::_ZThn8_N17QExtensionManagerD0Ev
+84 QExtensionManager::_ZThn8_N17QExtensionManager18registerExtensionsEP25QAbstractExtensionFactoryRK7QString
+88 QExtensionManager::_ZThn8_N17QExtensionManager20unregisterExtensionsEP25QAbstractExtensionFactoryRK7QString
+92 QExtensionManager::_ZThn8_NK17QExtensionManager9extensionEP7QObjectRK7QString
+
+Class QExtensionManager
+ size=20 align=4
+ base size=20 base align=4
+QExtensionManager (0xb4e4f870) 0
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 8u)
+ QObject (0xb4e3fdd4) 0
+ primary-for QExtensionManager (0xb4e4f870)
+ QAbstractExtensionManager (0xb4e3fe10) 8 nearly-empty
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 76u)
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb4e59ca8) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb4c965a0) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb4e8fd40) 0
+ QVector<QPoint> (0xb4cbe99c) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb4ce1340) 0
+ QVector<QPointF> (0xb4cdea8c) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb4d13ce4) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb4cfe99c) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb4d18960) 0
+
+Class QPainterPath::Element
+ size=20 align=4
+ base size=20 base align=4
+QPainterPath::Element (0xb4d337bc) 0
+
+Class QPainterPath
+ size=4 align=4
+ base size=4 base align=4
+QPainterPath (0xb4d33780) 0
+
+Class QPainterPathPrivate
+ size=8 align=4
+ base size=8 base align=4
+QPainterPathPrivate (0xb4d5e438) 0
+
+Class QPainterPathStroker
+ size=4 align=4
+ base size=4 base align=4
+QPainterPathStroker (0xb4d5ea14) 0
+
+Class QTransform
+ size=80 align=4
+ base size=80 base align=4
+QTransform (0xb4b980f0) 0
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb4bc8d98) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb4baac80) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb4bde9d8) 0
+ primary-for QImage (0xb4baac80)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb4c36580) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb4c411e0) 0
+ primary-for QPixmap (0xb4c36580)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb4c668e8) 0
+
+Class QBrushData
+ size=124 align=4
+ base size=121 base align=4
+QBrushData (0xb4c77654) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb4c77c30) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb4c88300) 0
+ QGradient (0xb4c8a99c) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb4c88400) 0
+ QGradient (0xb4c8abf4) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb4c88500) 0
+ QGradient (0xb4c8aec4) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb4aaa03c) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb4c88f40) 0
+ QPalette (0xb4ace8ac) 0
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb4aedbb8) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb4b09a14) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb4b17474) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb4b17bf4) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb4b281a4) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb4b895dc) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb4b89a14) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb4995f78) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb49aeb90) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb4995fb4) 0
+ primary-for QWidget (0xb49aeb90)
+ QPaintDevice (0xb4995780) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Vtable for QDesignerActionEditorInterface
+QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+8 QDesignerActionEditorInterface::metaObject
+12 QDesignerActionEditorInterface::qt_metacast
+16 QDesignerActionEditorInterface::qt_metacall
+20 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+24 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerActionEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 (int (*)(...))-0x000000008
+244 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+248 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD1Ev
+252 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerActionEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerActionEditorInterface (0xb4a62500) 0
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 8u)
+ QWidget (0xb4a66f00) 0
+ primary-for QDesignerActionEditorInterface (0xb4a62500)
+ QObject (0xb4a74744) 0
+ primary-for QWidget (0xb4a66f00)
+ QPaintDevice (0xb4a74780) 8
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 248u)
+
+Vtable for QDesignerBrushManagerInterface
+QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerBrushManagerInterface)
+8 QDesignerBrushManagerInterface::metaObject
+12 QDesignerBrushManagerInterface::qt_metacast
+16 QDesignerBrushManagerInterface::qt_metacall
+20 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+24 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerBrushManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerBrushManagerInterface (0xb4a62740) 0
+ vptr=((& QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface) + 8u)
+ QObject (0xb4a74f78) 0
+ primary-for QDesignerBrushManagerInterface (0xb4a62740)
+
+Vtable for QDesignerDnDItemInterface
+QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QDesignerDnDItemInterface)
+8 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+12 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerDnDItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDnDItemInterface (0xb4a8c834) 0 nearly-empty
+ vptr=((& QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface) + 8u)
+
+Vtable for QDesignerFormEditorInterface
+QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormEditorInterface)
+8 QDesignerFormEditorInterface::metaObject
+12 QDesignerFormEditorInterface::qt_metacast
+16 QDesignerFormEditorInterface::qt_metacall
+20 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+24 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QDesignerFormEditorInterface
+ size=60 align=4
+ base size=60 base align=4
+QDesignerFormEditorInterface (0xb4a62c00) 0
+ vptr=((& QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface) + 8u)
+ QObject (0xb4a8cdd4) 0
+ primary-for QDesignerFormEditorInterface (0xb4a62c00)
+
+Vtable for QDesignerFormEditorPluginInterface
+QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormEditorPluginInterface)
+8 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+12 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QDesignerFormEditorPluginInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormEditorPluginInterface (0xb48a9e10) 0 nearly-empty
+ vptr=((& QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface) + 8u)
+
+Vtable for QDesignerFormWindowInterface
+QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface: 114u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+8 QDesignerFormWindowInterface::metaObject
+12 QDesignerFormWindowInterface::qt_metacast
+16 QDesignerFormWindowInterface::qt_metacall
+20 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+24 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 __cxa_pure_virtual
+280 __cxa_pure_virtual
+284 __cxa_pure_virtual
+288 __cxa_pure_virtual
+292 __cxa_pure_virtual
+296 __cxa_pure_virtual
+300 __cxa_pure_virtual
+304 QDesignerFormWindowInterface::core
+308 __cxa_pure_virtual
+312 __cxa_pure_virtual
+316 __cxa_pure_virtual
+320 __cxa_pure_virtual
+324 __cxa_pure_virtual
+328 __cxa_pure_virtual
+332 __cxa_pure_virtual
+336 __cxa_pure_virtual
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 __cxa_pure_virtual
+368 __cxa_pure_virtual
+372 __cxa_pure_virtual
+376 __cxa_pure_virtual
+380 __cxa_pure_virtual
+384 __cxa_pure_virtual
+388 __cxa_pure_virtual
+392 __cxa_pure_virtual
+396 __cxa_pure_virtual
+400 __cxa_pure_virtual
+404 __cxa_pure_virtual
+408 __cxa_pure_virtual
+412 __cxa_pure_virtual
+416 __cxa_pure_virtual
+420 __cxa_pure_virtual
+424 __cxa_pure_virtual
+428 (int (*)(...))-0x000000008
+432 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+436 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD1Ev
+440 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD0Ev
+444 QWidget::_ZThn8_NK7QWidget7devTypeEv
+448 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+452 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerFormWindowInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerFormWindowInterface (0xb48cd340) 0
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 8u)
+ QWidget (0xb48d61e0) 0
+ primary-for QDesignerFormWindowInterface (0xb48cd340)
+ QObject (0xb48d70f0) 0
+ primary-for QWidget (0xb48d61e0)
+ QPaintDevice (0xb48d712c) 8
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 436u)
+
+Vtable for QDesignerFormWindowCursorInterface
+QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormWindowCursorInterface)
+8 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+12 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+
+Class QDesignerFormWindowCursorInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormWindowCursorInterface (0xb48ec3c0) 0 nearly-empty
+ vptr=((& QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface) + 8u)
+
+Vtable for QDesignerFormWindowManagerInterface
+QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface: 39u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI35QDesignerFormWindowManagerInterface)
+8 QDesignerFormWindowManagerInterface::metaObject
+12 QDesignerFormWindowManagerInterface::qt_metacast
+16 QDesignerFormWindowManagerInterface::qt_metacall
+20 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+24 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerFormWindowManagerInterface::actionCut
+60 QDesignerFormWindowManagerInterface::actionCopy
+64 QDesignerFormWindowManagerInterface::actionPaste
+68 QDesignerFormWindowManagerInterface::actionDelete
+72 QDesignerFormWindowManagerInterface::actionSelectAll
+76 QDesignerFormWindowManagerInterface::actionLower
+80 QDesignerFormWindowManagerInterface::actionRaise
+84 QDesignerFormWindowManagerInterface::actionUndo
+88 QDesignerFormWindowManagerInterface::actionRedo
+92 QDesignerFormWindowManagerInterface::actionHorizontalLayout
+96 QDesignerFormWindowManagerInterface::actionVerticalLayout
+100 QDesignerFormWindowManagerInterface::actionSplitHorizontal
+104 QDesignerFormWindowManagerInterface::actionSplitVertical
+108 QDesignerFormWindowManagerInterface::actionGridLayout
+112 QDesignerFormWindowManagerInterface::actionBreakLayout
+116 QDesignerFormWindowManagerInterface::actionAdjustSize
+120 QDesignerFormWindowManagerInterface::activeFormWindow
+124 QDesignerFormWindowManagerInterface::formWindowCount
+128 QDesignerFormWindowManagerInterface::formWindow
+132 QDesignerFormWindowManagerInterface::createFormWindow
+136 QDesignerFormWindowManagerInterface::core
+140 __cxa_pure_virtual
+144 QDesignerFormWindowManagerInterface::addFormWindow
+148 QDesignerFormWindowManagerInterface::removeFormWindow
+152 QDesignerFormWindowManagerInterface::setActiveFormWindow
+
+Class QDesignerFormWindowManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowManagerInterface (0xb48cd680) 0
+ vptr=((& QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface) + 8u)
+ QObject (0xb48ec8ac) 0
+ primary-for QDesignerFormWindowManagerInterface (0xb48cd680)
+
+Vtable for QDesignerFormWindowToolInterface
+QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerFormWindowToolInterface)
+8 QDesignerFormWindowToolInterface::metaObject
+12 QDesignerFormWindowToolInterface::qt_metacast
+16 QDesignerFormWindowToolInterface::qt_metacall
+20 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+24 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QDesignerFormWindowToolInterface::saveToDom
+84 QDesignerFormWindowToolInterface::loadFromDom
+88 __cxa_pure_virtual
+
+Class QDesignerFormWindowToolInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowToolInterface (0xb48cd8c0) 0
+ vptr=((& QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface) + 8u)
+ QObject (0xb490421c) 0
+ primary-for QDesignerFormWindowToolInterface (0xb48cd8c0)
+
+Vtable for QDesignerIconCacheInterface
+QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerIconCacheInterface)
+8 QDesignerIconCacheInterface::metaObject
+12 QDesignerIconCacheInterface::qt_metacast
+16 QDesignerIconCacheInterface::qt_metacall
+20 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+24 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QDesignerIconCacheInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerIconCacheInterface (0xb48cdb80) 0
+ vptr=((& QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface) + 8u)
+ QObject (0xb4904a8c) 0
+ primary-for QDesignerIconCacheInterface (0xb48cdb80)
+
+Vtable for QDesignerIntegrationInterface
+QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerIntegrationInterface)
+8 QDesignerIntegrationInterface::metaObject
+12 QDesignerIntegrationInterface::qt_metacast
+16 QDesignerIntegrationInterface::qt_metacall
+20 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+24 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+
+Class QDesignerIntegrationInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerIntegrationInterface (0xb48cde80) 0
+ vptr=((& QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface) + 8u)
+ QObject (0xb49173c0) 0
+ primary-for QDesignerIntegrationInterface (0xb48cde80)
+
+Vtable for QDesignerLanguageExtension
+QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension: 13u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerLanguageExtension)
+8 QDesignerLanguageExtension::~QDesignerLanguageExtension
+12 QDesignerLanguageExtension::~QDesignerLanguageExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QDesignerLanguageExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLanguageExtension (0xb4917bb8) 0 nearly-empty
+ vptr=((& QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension) + 8u)
+
+Vtable for QDesignerMetaDataBaseItemInterface
+QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerMetaDataBaseItemInterface)
+8 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+12 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMetaDataBaseItemInterface (0xb492c1e0) 0 nearly-empty
+ vptr=((& QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerMetaDataBaseInterface
+QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerMetaDataBaseInterface)
+8 QDesignerMetaDataBaseInterface::metaObject
+12 QDesignerMetaDataBaseInterface::qt_metacast
+16 QDesignerMetaDataBaseInterface::qt_metacall
+20 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+24 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerMetaDataBaseInterface (0xb4922540) 0
+ vptr=((& QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface) + 8u)
+ QObject (0xb492c528) 0
+ primary-for QDesignerMetaDataBaseInterface (0xb4922540)
+
+Vtable for QDesignerObjectInspectorInterface
+QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+8 QDesignerObjectInspectorInterface::metaObject
+12 QDesignerObjectInspectorInterface::qt_metacast
+16 QDesignerObjectInspectorInterface::qt_metacall
+20 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+24 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerObjectInspectorInterface::core
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+240 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD1Ev
+244 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerObjectInspectorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerObjectInspectorInterface (0xb4922780) 0
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 8u)
+ QWidget (0xb4936c80) 0
+ primary-for QDesignerObjectInspectorInterface (0xb4922780)
+ QObject (0xb492cfb4) 0
+ primary-for QWidget (0xb4936c80)
+ QPaintDevice (0xb492c30c) 8
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 240u)
+
+Class QDesignerPromotionInterface::PromotedClass
+ size=8 align=4
+ base size=8 base align=4
+QDesignerPromotionInterface::PromotedClass (0xb49407f8) 0
+
+Vtable for QDesignerPromotionInterface
+QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerPromotionInterface)
+8 QDesignerPromotionInterface::~QDesignerPromotionInterface
+12 QDesignerPromotionInterface::~QDesignerPromotionInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerPromotionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPromotionInterface (0xb4940780) 0 nearly-empty
+ vptr=((& QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface) + 8u)
+
+Vtable for QDesignerPropertyEditorInterface
+QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface: 70u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+8 QDesignerPropertyEditorInterface::metaObject
+12 QDesignerPropertyEditorInterface::qt_metacast
+16 QDesignerPropertyEditorInterface::qt_metacall
+20 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+24 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerPropertyEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 (int (*)(...))-0x000000008
+256 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+260 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD1Ev
+264 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD0Ev
+268 QWidget::_ZThn8_NK7QWidget7devTypeEv
+272 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+276 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerPropertyEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerPropertyEditorInterface (0xb4922a00) 0
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 8u)
+ QWidget (0xb4949690) 0
+ primary-for QDesignerPropertyEditorInterface (0xb4922a00)
+ QObject (0xb4940b40) 0
+ primary-for QWidget (0xb4949690)
+ QPaintDevice (0xb4940b7c) 8
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 260u)
+
+Vtable for QDesignerResourceBrowserInterface
+QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+8 QDesignerResourceBrowserInterface::metaObject
+12 QDesignerResourceBrowserInterface::qt_metacast
+16 QDesignerResourceBrowserInterface::qt_metacall
+20 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+24 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+240 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD1Ev
+244 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerResourceBrowserInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerResourceBrowserInterface (0xb4922c80) 0
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 8u)
+ QWidget (0xb494faa0) 0
+ primary-for QDesignerResourceBrowserInterface (0xb4922c80)
+ QObject (0xb49583c0) 0
+ primary-for QWidget (0xb494faa0)
+ QPaintDevice (0xb49583fc) 8
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 240u)
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb4958bf4) 0
+
+Class QDesignerWidgetBoxInterface::Widget
+ size=16 align=4
+ base size=16 base align=4
+QDesignerWidgetBoxInterface::Widget (0xb497c12c) 0
+
+Class QDesignerWidgetBoxInterface::Category
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetBoxInterface::Category (0xb497c4ec) 0
+
+Vtable for QDesignerWidgetBoxInterface
+QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface: 76u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+8 QDesignerWidgetBoxInterface::metaObject
+12 QDesignerWidgetBoxInterface::qt_metacast
+16 QDesignerWidgetBoxInterface::qt_metacall
+20 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+24 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 (int (*)(...))-0x000000008
+280 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+284 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD1Ev
+288 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD0Ev
+292 QWidget::_ZThn8_NK7QWidget7devTypeEv
+296 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+300 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerWidgetBoxInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerWidgetBoxInterface (0xb49752c0) 0
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 8u)
+ QWidget (0xb496fc30) 0
+ primary-for QDesignerWidgetBoxInterface (0xb49752c0)
+ QObject (0xb497c078) 0
+ primary-for QWidget (0xb496fc30)
+ QPaintDevice (0xb497c0b4) 8
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 284u)
+
+Vtable for QDesignerWidgetDataBaseItemInterface
+QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI36QDesignerWidgetDataBaseItemInterface)
+8 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+12 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+
+Class QDesignerWidgetDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerWidgetDataBaseItemInterface (0xb47c07f8) 0 nearly-empty
+ vptr=((& QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerWidgetDataBaseInterface
+QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerWidgetDataBaseInterface)
+8 QDesignerWidgetDataBaseInterface::metaObject
+12 QDesignerWidgetDataBaseInterface::qt_metacast
+16 QDesignerWidgetDataBaseInterface::qt_metacall
+20 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+24 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerWidgetDataBaseInterface::count
+60 QDesignerWidgetDataBaseInterface::item
+64 QDesignerWidgetDataBaseInterface::indexOf
+68 QDesignerWidgetDataBaseInterface::insert
+72 QDesignerWidgetDataBaseInterface::append
+76 QDesignerWidgetDataBaseInterface::indexOfObject
+80 QDesignerWidgetDataBaseInterface::indexOfClassName
+84 QDesignerWidgetDataBaseInterface::core
+
+Class QDesignerWidgetDataBaseInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetDataBaseInterface (0xb47b5940) 0
+ vptr=((& QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface) + 8u)
+ QObject (0xb47c0b40) 0
+ primary-for QDesignerWidgetDataBaseInterface (0xb47b5940)
+
+Vtable for QDesignerWidgetFactoryInterface
+QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerWidgetFactoryInterface)
+8 QDesignerWidgetFactoryInterface::metaObject
+12 QDesignerWidgetFactoryInterface::qt_metacast
+16 QDesignerWidgetFactoryInterface::qt_metacall
+20 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+24 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerWidgetFactoryInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerWidgetFactoryInterface (0xb47b5c40) 0
+ vptr=((& QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface) + 8u)
+ QObject (0xb47e63c0) 0
+ primary-for QDesignerWidgetFactoryInterface (0xb47b5c40)
+
+Vtable for QDesignerDynamicPropertySheetExtension
+QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI38QDesignerDynamicPropertySheetExtension)
+8 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+12 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+
+Class QDesignerDynamicPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDynamicPropertySheetExtension (0xb47e6b7c) 0 nearly-empty
+ vptr=((& QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension) + 8u)
+
+Vtable for QDesignerExtraInfoExtension
+QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerExtraInfoExtension)
+8 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+12 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerExtraInfoExtension
+ size=8 align=4
+ base size=8 base align=4
+QDesignerExtraInfoExtension (0xb47fa1a4) 0
+ vptr=((& QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension) + 8u)
+
+Vtable for QDesignerLayoutDecorationExtension
+QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerLayoutDecorationExtension)
+8 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+12 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerLayoutDecorationExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLayoutDecorationExtension (0xb47fa834) 0 nearly-empty
+ vptr=((& QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension) + 8u)
+
+Vtable for QDesignerMemberSheetExtension
+QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerMemberSheetExtension)
+8 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+12 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+
+Class QDesignerMemberSheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMemberSheetExtension (0xb47faf78) 0 nearly-empty
+ vptr=((& QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension) + 8u)
+
+Vtable for QDesignerPropertySheetExtension
+QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerPropertySheetExtension)
+8 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+12 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPropertySheetExtension (0xb48185a0) 0 nearly-empty
+ vptr=((& QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension) + 8u)
+
+Vtable for QDesignerTaskMenuExtension
+QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerTaskMenuExtension)
+8 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+12 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+16 QDesignerTaskMenuExtension::preferredEditAction
+20 __cxa_pure_virtual
+
+Class QDesignerTaskMenuExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerTaskMenuExtension (0xb4818c30) 0 nearly-empty
+ vptr=((& QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension) + 8u)
+
+Vtable for QAbstractFormBuilder
+QAbstractFormBuilder::_ZTV20QAbstractFormBuilder: 48u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QAbstractFormBuilder)
+8 QAbstractFormBuilder::~QAbstractFormBuilder
+12 QAbstractFormBuilder::~QAbstractFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QAbstractFormBuilder::create
+32 QAbstractFormBuilder::create
+36 QAbstractFormBuilder::create
+40 QAbstractFormBuilder::create
+44 QAbstractFormBuilder::create
+48 QAbstractFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QAbstractFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QAbstractFormBuilder::createWidget
+68 QAbstractFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QAbstractFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QAbstractFormBuilder::addItem
+96 QAbstractFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+
+Class QAbstractFormBuilder
+ size=28 align=4
+ base size=28 base align=4
+QAbstractFormBuilder (0xb4830384) 0
+ vptr=((& QAbstractFormBuilder::_ZTV20QAbstractFormBuilder) + 8u)
+
+Vtable for QDesignerContainerExtension
+QDesignerContainerExtension::_ZTV27QDesignerContainerExtension: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerContainerExtension)
+8 QDesignerContainerExtension::~QDesignerContainerExtension
+12 QDesignerContainerExtension::~QDesignerContainerExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerContainerExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerContainerExtension (0xb4830f78) 0 nearly-empty
+ vptr=((& QDesignerContainerExtension::_ZTV27QDesignerContainerExtension) + 8u)
+
+Vtable for QDesignerCustomWidgetInterface
+QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerCustomWidgetInterface)
+8 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+12 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 QDesignerCustomWidgetInterface::isInitialized
+52 QDesignerCustomWidgetInterface::initialize
+56 QDesignerCustomWidgetInterface::domXml
+60 QDesignerCustomWidgetInterface::codeTemplate
+
+Class QDesignerCustomWidgetInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetInterface (0xb4876474) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface) + 8u)
+
+Vtable for QDesignerCustomWidgetCollectionInterface
+QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI40QDesignerCustomWidgetCollectionInterface)
+8 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+12 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+16 __cxa_pure_virtual
+
+Class QDesignerCustomWidgetCollectionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetCollectionInterface (0xb4876e88) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface) + 8u)
+
+Vtable for QFormBuilder
+QFormBuilder::_ZTV12QFormBuilder: 49u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QFormBuilder)
+8 QFormBuilder::~QFormBuilder
+12 QFormBuilder::~QFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QFormBuilder::create
+32 QFormBuilder::create
+36 QFormBuilder::create
+40 QFormBuilder::create
+44 QFormBuilder::create
+48 QFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QFormBuilder::createWidget
+68 QFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QFormBuilder::addItem
+96 QFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+192 QFormBuilder::updateCustomWidgets
+
+Class QFormBuilder
+ size=36 align=4
+ base size=36 base align=4
+QFormBuilder (0xb4853b40) 0
+ vptr=((& QFormBuilder::_ZTV12QFormBuilder) + 8u)
+ QAbstractFormBuilder (0xb488c384) 0
+ primary-for QFormBuilder (0xb4853b40)
+
diff --git a/tests/auto/bic/data/QtDesigner.4.5.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtDesigner.4.5.0.linux-gcc-amd64.txt
new file mode 100644
index 000000000..d430a8429
--- /dev/null
+++ b/tests/auto/bic/data/QtDesigner.4.5.0.linux-gcc-amd64.txt
@@ -0,0 +1,4460 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0x7f09f7532540) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0x7f09f7545230) 0
+
+Class qIsNull(double)::U
+ size=8 align=8
+ base size=8 base align=8
+qIsNull(double)::U (0x7f09f755c620) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0x7f09f755c8c0) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0x7f09f7592700) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0x7f09f7592ee0) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0x7f09f6b71620) 0 empty
+
+Class QGenericArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericArgument (0x7f09f6b71930) 0
+
+Class QGenericReturnArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericReturnArgument (0x7f09f6b8c4d0) 0
+ QGenericArgument (0x7f09f6b8c540) 0
+
+Class QMetaObject
+ size=32 align=8
+ base size=32 base align=8
+QMetaObject (0x7f09f6b8cd90) 0
+
+Class QMetaObjectExtraData
+ size=16 align=8
+ base size=16 base align=8
+QMetaObjectExtraData (0x7f09f69b2d90) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0x7f09f69bc7e0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0x7f09f69c2380) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0x7f09f6a2f460) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0x7f09f6a6ae00) 0
+ QBasicAtomicInt (0x7f09f6a6ae70) 0
+
+Class __locale_struct
+ size=232 align=8
+ base size=232 base align=8
+__locale_struct (0x7f09f6a8f2a0) 0
+
+Class QByteArray::Data
+ size=32 align=8
+ base size=32 base align=8
+QByteArray::Data (0x7f09f69088c0) 0
+
+Class QByteArray
+ size=8 align=8
+ base size=8 base align=8
+QByteArray (0x7f09f68c4620) 0
+
+Class QByteRef
+ size=16 align=8
+ base size=12 base align=8
+QByteRef (0x7f09f695eb60) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0x7f09f68667e0) 0 empty
+
+Class QString::Data
+ size=32 align=8
+ base size=32 base align=8
+QString::Data (0x7f09f687f000) 0
+
+Class QString
+ size=8 align=8
+ base size=8 base align=8
+QString (0x7f09f67e4690) 0
+
+Class QLatin1String
+ size=8 align=8
+ base size=8 base align=8
+QLatin1String (0x7f09f67500e0) 0
+
+Class QCharRef
+ size=16 align=8
+ base size=12 base align=8
+QCharRef (0x7f09f65e6700) 0
+
+Class QConstString
+ size=8 align=8
+ base size=8 base align=8
+QConstString (0x7f09f653a000) 0
+ QString (0x7f09f653a070) 0
+
+Class QStringRef
+ size=16 align=8
+ base size=16 base align=8
+QStringRef (0x7f09f6553cb0) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9exception)
+16 std::exception::~exception
+24 std::exception::~exception
+32 std::exception::what
+
+Class std::exception
+ size=8 align=8
+ base size=8 base align=8
+std::exception (0x7f09f640b7e0) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 16u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13bad_exception)
+16 std::bad_exception::~bad_exception
+24 std::bad_exception::~bad_exception
+32 std::bad_exception::what
+
+Class std::bad_exception
+ size=8 align=8
+ base size=8 base align=8
+std::bad_exception (0x7f09f642e0e0) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u)
+ std::exception (0x7f09f642e150) 0 nearly-empty
+ primary-for std::bad_exception (0x7f09f642e0e0)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9bad_alloc)
+16 std::bad_alloc::~bad_alloc
+24 std::bad_alloc::~bad_alloc
+32 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=8 align=8
+ base size=8 base align=8
+std::bad_alloc (0x7f09f642e9a0) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u)
+ std::exception (0x7f09f642ea10) 0 nearly-empty
+ primary-for std::bad_alloc (0x7f09f642e9a0)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0x7f09f643e1c0) 0 empty
+
+Class QListData::Data
+ size=32 align=8
+ base size=32 base align=8
+QListData::Data (0x7f09f643e700) 0
+
+Class QListData
+ size=8 align=8
+ base size=8 base align=8
+QListData (0x7f09f643e690) 0
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QObjectData)
+16 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QObjectData
+ size=40 align=8
+ base size=40 base align=8
+QObjectData (0x7f09f6342cb0) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 16u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QObject)
+16 QObject::metaObject
+24 QObject::qt_metacast
+32 QObject::qt_metacall
+40 QObject::~QObject
+48 QObject::~QObject
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QObject
+ size=16 align=8
+ base size=16 base align=8
+QObject (0x7f09f6342f50) 0
+ vptr=((& QObject::_ZTV7QObject) + 16u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QObjectUserData)
+16 QObjectUserData::~QObjectUserData
+24 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=8 align=8
+ base size=8 base align=8
+QObjectUserData (0x7f09f61d34d0) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QIODevice)
+16 QIODevice::metaObject
+24 QIODevice::qt_metacast
+32 QIODevice::qt_metacall
+40 QIODevice::~QIODevice
+48 QIODevice::~QIODevice
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QIODevice::isSequential
+120 QIODevice::open
+128 QIODevice::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QIODevice::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 __cxa_pure_virtual
+224 QIODevice::readLineData
+232 __cxa_pure_virtual
+
+Class QIODevice
+ size=16 align=8
+ base size=16 base align=8
+QIODevice (0x7f09f61d3a10) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 16u)
+ QObject (0x7f09f61d3a80) 0
+ primary-for QIODevice (0x7f09f61d3a10)
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QDataStream)
+16 QDataStream::~QDataStream
+24 QDataStream::~QDataStream
+
+Class QDataStream
+ size=40 align=8
+ base size=40 base align=8
+QDataStream (0x7f09f6248380) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 16u)
+
+Class QHashData::Node
+ size=16 align=8
+ base size=16 base align=8
+QHashData::Node (0x7f09f60ce230) 0
+
+Class QHashData
+ size=40 align=8
+ base size=40 base align=8
+QHashData (0x7f09f60ce1c0) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0x7f09f60e3000) 0 empty
+
+Class QMapData::Node
+ size=16 align=8
+ base size=16 base align=8
+QMapData::Node (0x7f09f5ff2770) 0
+
+Class QMapData
+ size=128 align=8
+ base size=128 base align=8
+QMapData (0x7f09f5ff2700) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSystemLocale)
+16 QSystemLocale::~QSystemLocale
+24 QSystemLocale::~QSystemLocale
+32 QSystemLocale::query
+40 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=8 align=8
+ base size=8 base align=8
+QSystemLocale (0x7f09f5f07ee0) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 16u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0x7f09f5f644d0) 0
+
+Class QLocale
+ size=8 align=8
+ base size=8 base align=8
+QLocale (0x7f09f5f241c0) 0
+
+Class QTextCodec::ConverterState
+ size=32 align=8
+ base size=32 base align=8
+QTextCodec::ConverterState (0x7f09f5db2f50) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextCodec)
+16 __cxa_pure_virtual
+24 QTextCodec::aliases
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QTextCodec::~QTextCodec
+64 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=8 align=8
+ base size=8 base align=8
+QTextCodec (0x7f09f5d9db60) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u)
+
+Class QTextEncoder
+ size=40 align=8
+ base size=40 base align=8
+QTextEncoder (0x7f09f5e1f4d0) 0
+
+Class QTextDecoder
+ size=40 align=8
+ base size=40 base align=8
+QTextDecoder (0x7f09f5e27310) 0
+
+Class _IO_marker
+ size=24 align=8
+ base size=24 base align=8
+_IO_marker (0x7f09f5e31380) 0
+
+Class _IO_FILE
+ size=216 align=8
+ base size=216 base align=8
+_IO_FILE (0x7f09f5e313f0) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextStream)
+16 QTextStream::~QTextStream
+24 QTextStream::~QTextStream
+
+Class QTextStream
+ size=16 align=8
+ base size=16 base align=8
+QTextStream (0x7f09f5e314d0) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 16u)
+
+Class QTextStreamManipulator
+ size=40 align=8
+ base size=38 base align=8
+QTextStreamManipulator (0x7f09f5cd5000) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextIStream)
+16 QTextIStream::~QTextIStream
+24 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=16 align=8
+ base size=16 base align=8
+QTextIStream (0x7f09f5cf52a0) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 16u)
+ QTextStream (0x7f09f5cf5310) 0
+ primary-for QTextIStream (0x7f09f5cf52a0)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextOStream)
+16 QTextOStream::~QTextOStream
+24 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=16 align=8
+ base size=16 base align=8
+QTextOStream (0x7f09f5d0a150) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 16u)
+ QTextStream (0x7f09f5d0a1c0) 0
+ primary-for QTextOStream (0x7f09f5d0a150)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0x7f09f5d21000) 0
+
+Class timespec
+ size=16 align=8
+ base size=16 base align=8
+timespec (0x7f09f5d21310) 0
+
+Class timeval
+ size=16 align=8
+ base size=16 base align=8
+timeval (0x7f09f5d21380) 0
+
+Class __pthread_internal_list
+ size=16 align=8
+ base size=16 base align=8
+__pthread_internal_list (0x7f09f5d214d0) 0
+
+Class random_data
+ size=48 align=8
+ base size=48 base align=8
+random_data (0x7f09f5d21a80) 0
+
+Class drand48_data
+ size=24 align=8
+ base size=24 base align=8
+drand48_data (0x7f09f5d21af0) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0x7f09f5d21b60) 0
+
+Class QDebug::Stream
+ size=40 align=8
+ base size=34 base align=8
+QDebug::Stream (0x7f09f5a9e310) 0
+
+Class QDebug
+ size=8 align=8
+ base size=8 base align=8
+QDebug (0x7f09f5a9e2a0) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0x7f09f5b3d150) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QFile)
+16 QFile::metaObject
+24 QFile::qt_metacast
+32 QFile::qt_metacall
+40 QFile::~QFile
+48 QFile::~QFile
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFile::isSequential
+120 QFile::open
+128 QFile::close
+136 QFile::pos
+144 QFile::size
+152 QFile::seek
+160 QFile::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QFile::readData
+224 QFile::readLineData
+232 QFile::writeData
+240 QFile::fileEngine
+
+Class QFile
+ size=16 align=8
+ base size=16 base align=8
+QFile (0x7f09f5b4c700) 0
+ vptr=((& QFile::_ZTV5QFile) + 16u)
+ QIODevice (0x7f09f5b4c770) 0
+ primary-for QFile (0x7f09f5b4c700)
+ QObject (0x7f09f5b4c7e0) 0
+ primary-for QIODevice (0x7f09f5b4c770)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTemporaryFile)
+16 QTemporaryFile::metaObject
+24 QTemporaryFile::qt_metacast
+32 QTemporaryFile::qt_metacall
+40 QTemporaryFile::~QTemporaryFile
+48 QTemporaryFile::~QTemporaryFile
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFile::isSequential
+120 QTemporaryFile::open
+128 QFile::close
+136 QFile::pos
+144 QFile::size
+152 QFile::seek
+160 QFile::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QFile::readData
+224 QFile::readLineData
+232 QFile::writeData
+240 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=16 align=8
+ base size=16 base align=8
+QTemporaryFile (0x7f09f59b9930) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u)
+ QFile (0x7f09f59b99a0) 0
+ primary-for QTemporaryFile (0x7f09f59b9930)
+ QIODevice (0x7f09f59b9a10) 0
+ primary-for QFile (0x7f09f59b99a0)
+ QObject (0x7f09f59b9a80) 0
+ primary-for QIODevice (0x7f09f59b9a10)
+
+Class QFileInfo
+ size=8 align=8
+ base size=8 base align=8
+QFileInfo (0x7f09f59e1070) 0
+
+Class QRegExp
+ size=8 align=8
+ base size=8 base align=8
+QRegExp (0x7f09f5a35850) 0
+
+Class QStringMatcher
+ size=1048 align=8
+ base size=1048 base align=8
+QStringMatcher (0x7f09f5a82690) 0
+
+Class QStringList
+ size=8 align=8
+ base size=8 base align=8
+QStringList (0x7f09f5894150) 0
+ QList<QString> (0x7f09f58941c0) 0
+
+Class QDir
+ size=8 align=8
+ base size=8 base align=8
+QDir (0x7f09f5925d90) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0x7f09f57bef50) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0x7f09f57d1000) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=24 align=8
+ base size=20 base align=8
+QAbstractFileEngine::MapExtensionOption (0x7f09f57d1070) 0
+ QAbstractFileEngine::ExtensionOption (0x7f09f57d10e0) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngine::MapExtensionReturn (0x7f09f57d12a0) 0
+ QAbstractFileEngine::ExtensionReturn (0x7f09f57d1310) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngine::UnMapExtensionOption (0x7f09f57d1380) 0
+ QAbstractFileEngine::ExtensionOption (0x7f09f57d13f0) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+16 QAbstractFileEngine::~QAbstractFileEngine
+24 QAbstractFileEngine::~QAbstractFileEngine
+32 QAbstractFileEngine::open
+40 QAbstractFileEngine::close
+48 QAbstractFileEngine::flush
+56 QAbstractFileEngine::size
+64 QAbstractFileEngine::pos
+72 QAbstractFileEngine::seek
+80 QAbstractFileEngine::isSequential
+88 QAbstractFileEngine::remove
+96 QAbstractFileEngine::copy
+104 QAbstractFileEngine::rename
+112 QAbstractFileEngine::link
+120 QAbstractFileEngine::mkdir
+128 QAbstractFileEngine::rmdir
+136 QAbstractFileEngine::setSize
+144 QAbstractFileEngine::caseSensitive
+152 QAbstractFileEngine::isRelativePath
+160 QAbstractFileEngine::entryList
+168 QAbstractFileEngine::fileFlags
+176 QAbstractFileEngine::setPermissions
+184 QAbstractFileEngine::fileName
+192 QAbstractFileEngine::ownerId
+200 QAbstractFileEngine::owner
+208 QAbstractFileEngine::fileTime
+216 QAbstractFileEngine::setFileName
+224 QAbstractFileEngine::handle
+232 QAbstractFileEngine::beginEntryList
+240 QAbstractFileEngine::endEntryList
+248 QAbstractFileEngine::read
+256 QAbstractFileEngine::readLine
+264 QAbstractFileEngine::write
+272 QAbstractFileEngine::extension
+280 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=16 align=8
+ base size=16 base align=8
+QAbstractFileEngine (0x7f09f57aeee0) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 16u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+16 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+24 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+32 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngineHandler (0x7f09f58030e0) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 16u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+16 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+24 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QAbstractFileEngineIterator::currentFileInfo
+64 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=16 align=8
+ base size=16 base align=8
+QAbstractFileEngineIterator (0x7f09f58032a0) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 16u)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFSFileEngine)
+16 QFSFileEngine::~QFSFileEngine
+24 QFSFileEngine::~QFSFileEngine
+32 QFSFileEngine::open
+40 QFSFileEngine::close
+48 QFSFileEngine::flush
+56 QFSFileEngine::size
+64 QFSFileEngine::pos
+72 QFSFileEngine::seek
+80 QFSFileEngine::isSequential
+88 QFSFileEngine::remove
+96 QFSFileEngine::copy
+104 QFSFileEngine::rename
+112 QFSFileEngine::link
+120 QFSFileEngine::mkdir
+128 QFSFileEngine::rmdir
+136 QFSFileEngine::setSize
+144 QFSFileEngine::caseSensitive
+152 QFSFileEngine::isRelativePath
+160 QFSFileEngine::entryList
+168 QFSFileEngine::fileFlags
+176 QFSFileEngine::setPermissions
+184 QFSFileEngine::fileName
+192 QFSFileEngine::ownerId
+200 QFSFileEngine::owner
+208 QFSFileEngine::fileTime
+216 QFSFileEngine::setFileName
+224 QFSFileEngine::handle
+232 QFSFileEngine::beginEntryList
+240 QFSFileEngine::endEntryList
+248 QFSFileEngine::read
+256 QFSFileEngine::readLine
+264 QFSFileEngine::write
+272 QFSFileEngine::extension
+280 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=16 align=8
+ base size=16 base align=8
+QFSFileEngine (0x7f09f5803af0) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 16u)
+ QAbstractFileEngine (0x7f09f5803b60) 0
+ primary-for QFSFileEngine (0x7f09f5803af0)
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QProcess)
+16 QProcess::metaObject
+24 QProcess::qt_metacast
+32 QProcess::qt_metacall
+40 QProcess::~QProcess
+48 QProcess::~QProcess
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QProcess::isSequential
+120 QIODevice::open
+128 QProcess::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QProcess::atEnd
+168 QIODevice::reset
+176 QProcess::bytesAvailable
+184 QProcess::bytesToWrite
+192 QProcess::canReadLine
+200 QProcess::waitForReadyRead
+208 QProcess::waitForBytesWritten
+216 QProcess::readData
+224 QIODevice::readLineData
+232 QProcess::writeData
+240 QProcess::setupChildProcess
+
+Class QProcess
+ size=16 align=8
+ base size=16 base align=8
+QProcess (0x7f09f5818e00) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 16u)
+ QIODevice (0x7f09f5818e70) 0
+ primary-for QProcess (0x7f09f5818e00)
+ QObject (0x7f09f5818ee0) 0
+ primary-for QIODevice (0x7f09f5818e70)
+
+Class QResource
+ size=8 align=8
+ base size=8 base align=8
+QResource (0x7f09f5857310) 0
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QDirIterator)
+16 QDirIterator::~QDirIterator
+24 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=16 align=8
+ base size=16 base align=8
+QDirIterator (0x7f09f5857d90) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 16u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBuffer)
+16 QBuffer::metaObject
+24 QBuffer::qt_metacast
+32 QBuffer::qt_metacall
+40 QBuffer::~QBuffer
+48 QBuffer::~QBuffer
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QBuffer::connectNotify
+104 QBuffer::disconnectNotify
+112 QIODevice::isSequential
+120 QBuffer::open
+128 QBuffer::close
+136 QBuffer::pos
+144 QBuffer::size
+152 QBuffer::seek
+160 QBuffer::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QBuffer::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QBuffer::readData
+224 QIODevice::readLineData
+232 QBuffer::writeData
+
+Class QBuffer
+ size=16 align=8
+ base size=16 base align=8
+QBuffer (0x7f09f5887b60) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 16u)
+ QIODevice (0x7f09f5887bd0) 0
+ primary-for QBuffer (0x7f09f5887b60)
+ QObject (0x7f09f5887c40) 0
+ primary-for QIODevice (0x7f09f5887bd0)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+16 QFileSystemWatcher::metaObject
+24 QFileSystemWatcher::qt_metacast
+32 QFileSystemWatcher::qt_metacall
+40 QFileSystemWatcher::~QFileSystemWatcher
+48 QFileSystemWatcher::~QFileSystemWatcher
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemWatcher (0x7f09f568e770) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u)
+ QObject (0x7f09f568e7e0) 0
+ primary-for QFileSystemWatcher (0x7f09f568e770)
+
+Class QUrl
+ size=8 align=8
+ base size=8 base align=8
+QUrl (0x7f09f56a2cb0) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0x7f09f572b4d0) 0 empty
+
+Class QVariant::PrivateShared
+ size=16 align=8
+ base size=12 base align=8
+QVariant::PrivateShared (0x7f09f55ffa10) 0
+
+Class QVariant::Private::Data
+ size=8 align=8
+ base size=8 base align=8
+QVariant::Private::Data (0x7f09f55ffd20) 0
+
+Class QVariant::Private
+ size=16 align=8
+ base size=12 base align=8
+QVariant::Private (0x7f09f55ffaf0) 0
+
+Class QVariant::Handler
+ size=72 align=8
+ base size=72 base align=8
+QVariant::Handler (0x7f09f560da10) 0
+
+Class QVariant
+ size=16 align=8
+ base size=16 base align=8
+QVariant (0x7f09f55cfbd0) 0
+
+Class QVariantComparisonHelper
+ size=8 align=8
+ base size=8 base align=8
+QVariantComparisonHelper (0x7f09f54b2d90) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSettings)
+16 QSettings::metaObject
+24 QSettings::qt_metacast
+32 QSettings::qt_metacall
+40 QSettings::~QSettings
+48 QSettings::~QSettings
+56 QSettings::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSettings
+ size=16 align=8
+ base size=16 base align=8
+QSettings (0x7f09f54d7d90) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 16u)
+ QObject (0x7f09f54d7e00) 0
+ primary-for QSettings (0x7f09f54d7d90)
+
+Class QXmlStreamStringRef
+ size=16 align=8
+ base size=16 base align=8
+QXmlStreamStringRef (0x7f09f555a150) 0
+
+Class QXmlStreamAttribute
+ size=80 align=8
+ base size=73 base align=8
+QXmlStreamAttribute (0x7f09f53759a0) 0
+
+Class QXmlStreamAttributes
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamAttributes (0x7f09f539f460) 0
+ QVector<QXmlStreamAttribute> (0x7f09f539f4d0) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=40 align=8
+ base size=40 base align=8
+QXmlStreamNamespaceDeclaration (0x7f09f539f930) 0
+
+Class QXmlStreamNotationDeclaration
+ size=56 align=8
+ base size=56 base align=8
+QXmlStreamNotationDeclaration (0x7f09f53df2a0) 0
+
+Class QXmlStreamEntityDeclaration
+ size=88 align=8
+ base size=88 base align=8
+QXmlStreamEntityDeclaration (0x7f09f53ff150) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+16 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+24 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+32 QXmlStreamEntityResolver::resolveEntity
+40 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamEntityResolver (0x7f09f541ca80) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u)
+
+Class QXmlStreamReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamReader (0x7f09f541cc40) 0
+
+Class QXmlStreamWriter
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamWriter (0x7f09f5458af0) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0x7f09f5292230) 0
+
+Class QPointF
+ size=16 align=8
+ base size=16 base align=8
+QPointF (0x7f09f52cde70) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0x7f09f5309cb0) 0
+
+Class QLineF
+ size=32 align=8
+ base size=32 base align=8
+QLineF (0x7f09f5343b60) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0x7f09f519e620) 0
+
+Class QSizeF
+ size=16 align=8
+ base size=16 base align=8
+QSizeF (0x7f09f51ec460) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0x7f09f5238a80) 0
+
+Class QRectF
+ size=32 align=8
+ base size=32 base align=8
+QRectF (0x7f09f50ee460) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0x7f09f4f93230) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+16 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+24 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+32 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=16 align=8
+ base size=16 base align=8
+QtSharedPointer::ExternalRefCountData (0x7f09f4fc0bd0) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 16u)
+
+Class QLinkedListData
+ size=32 align=8
+ base size=32 base align=8
+QLinkedListData (0x7f09f5048d20) 0
+
+Class QBitArray
+ size=8 align=8
+ base size=8 base align=8
+QBitArray (0x7f09f4f14c40) 0
+
+Class QBitRef
+ size=16 align=8
+ base size=12 base align=8
+QBitRef (0x7f09f4d88a10) 0
+
+Class QByteArrayMatcher
+ size=1040 align=8
+ base size=1040 base align=8
+QByteArrayMatcher (0x7f09f4da43f0) 0
+
+Class QCryptographicHash
+ size=8 align=8
+ base size=8 base align=8
+QCryptographicHash (0x7f09f4db4af0) 0
+
+Class QTextBoundaryFinder
+ size=48 align=8
+ base size=48 base align=8
+QTextBoundaryFinder (0x7f09f4de3540) 0
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0x7f09f4df98c0) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0x7f09f4e22850) 0
+
+Class QDateTime
+ size=8 align=8
+ base size=8 base align=8
+QDateTime (0x7f09f4e3ee00) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeLine)
+16 QTimeLine::metaObject
+24 QTimeLine::qt_metacast
+32 QTimeLine::qt_metacall
+40 QTimeLine::~QTimeLine
+48 QTimeLine::~QTimeLine
+56 QObject::event
+64 QObject::eventFilter
+72 QTimeLine::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=16 align=8
+ base size=16 base align=8
+QTimeLine (0x7f09f4c742a0) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u)
+ QObject (0x7f09f4c74310) 0
+ primary-for QTimeLine (0x7f09f4c742a0)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QRunnable)
+16 __cxa_pure_virtual
+24 QRunnable::~QRunnable
+32 QRunnable::~QRunnable
+
+Class QRunnable
+ size=16 align=8
+ base size=12 base align=8
+QRunnable (0x7f09f4c9c150) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 16u)
+
+Class QMutex
+ size=8 align=8
+ base size=8 base align=8
+QMutex (0x7f09f4ca77e0) 0
+
+Class QMutexLocker
+ size=8 align=8
+ base size=8 base align=8
+QMutexLocker (0x7f09f4cb7380) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+16 QtConcurrent::Exception::~Exception
+24 QtConcurrent::Exception::~Exception
+32 std::exception::what
+40 QtConcurrent::Exception::raise
+48 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::Exception (0x7f09f4ccc690) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 16u)
+ std::exception (0x7f09f4ccc700) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0x7f09f4ccc690)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+16 QtConcurrent::UnhandledException::~UnhandledException
+24 QtConcurrent::UnhandledException::~UnhandledException
+32 std::exception::what
+40 QtConcurrent::UnhandledException::raise
+48 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::UnhandledException (0x7f09f4ccc930) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 16u)
+ QtConcurrent::Exception (0x7f09f4ccc9a0) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0x7f09f4ccc930)
+ std::exception (0x7f09f4ccca10) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0x7f09f4ccc9a0)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::internal::ExceptionHolder (0x7f09f4cccc40) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::internal::ExceptionStore (0x7f09f4ccc8c0) 0
+
+Class QtConcurrent::ResultItem
+ size=16 align=8
+ base size=16 base align=8
+QtConcurrent::ResultItem (0x7f09f4cccbd0) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=16 align=8
+ base size=12 base align=8
+QtConcurrent::ResultIteratorBase (0x7f09f4ce3f50) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+16 QtConcurrent::ResultStoreBase::~ResultStoreBase
+24 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=48 align=8
+ base size=44 base align=8
+QtConcurrent::ResultStoreBase (0x7f09f4ce9af0) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 16u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+16 QFutureInterfaceBase::~QFutureInterfaceBase
+24 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureInterfaceBase (0x7f09f4d28f50) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QThread)
+16 QThread::metaObject
+24 QThread::qt_metacast
+32 QThread::qt_metacall
+40 QThread::~QThread
+48 QThread::~QThread
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QThread::run
+
+Class QThread
+ size=16 align=8
+ base size=16 base align=8
+QThread (0x7f09f4c0bee0) 0
+ vptr=((& QThread::_ZTV7QThread) + 16u)
+ QObject (0x7f09f4c0bf50) 0
+ primary-for QThread (0x7f09f4c0bee0)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QThreadPool)
+16 QThreadPool::metaObject
+24 QThreadPool::qt_metacast
+32 QThreadPool::qt_metacall
+40 QThreadPool::~QThreadPool
+48 QThreadPool::~QThreadPool
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QThreadPool
+ size=16 align=8
+ base size=16 base align=8
+QThreadPool (0x7f09f4c3ed90) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u)
+ QObject (0x7f09f4c3ee00) 0
+ primary-for QThreadPool (0x7f09f4c3ed90)
+
+Class QWaitCondition
+ size=8 align=8
+ base size=8 base align=8
+QWaitCondition (0x7f09f4c5a620) 0
+
+Class QtConcurrent::ThreadEngineSemaphore
+ size=24 align=8
+ base size=24 base align=8
+QtConcurrent::ThreadEngineSemaphore (0x7f09f4c5ab60) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+16 QtConcurrent::ThreadEngineBase::run
+24 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+32 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+40 QtConcurrent::ThreadEngineBase::start
+48 QtConcurrent::ThreadEngineBase::finish
+56 QtConcurrent::ThreadEngineBase::threadFunction
+64 QtConcurrent::ThreadEngineBase::shouldStartThread
+72 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+80 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=64 align=8
+ base size=64 base align=8
+QtConcurrent::ThreadEngineBase (0x7f09f4a78540) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 16u)
+ QRunnable (0x7f09f4a785b0) 0
+ primary-for QtConcurrent::ThreadEngineBase (0x7f09f4a78540)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 24u)
+8 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 136u)
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0x7f09f4ab9930) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0x7f09f4ab99a0) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0x7f09f4ab9a10) 0 empty
+ std::input_iterator_tag (0x7f09f4ab9a80) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0x7f09f4ab9af0) 0 empty
+ std::forward_iterator_tag (0x7f09f4ab9b60) 0 empty
+ std::input_iterator_tag (0x7f09f4ab9bd0) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0x7f09f4ab9c40) 0 empty
+ std::bidirectional_iterator_tag (0x7f09f4ab9cb0) 0 empty
+ std::forward_iterator_tag (0x7f09f4ab9d20) 0 empty
+ std::input_iterator_tag (0x7f09f4ab9d90) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0x7f09f4ac9380) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0x7f09f4ac93f0) 0 empty
+
+Class lconv
+ size=96 align=8
+ base size=96 base align=8
+lconv (0x7f09f48a7700) 0
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0x7f09f48a7b60) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0x7f09f48a7bd0) 0
+
+Class tm
+ size=56 align=8
+ base size=56 base align=8
+tm (0x7f09f48a7cb0) 0
+
+Class itimerspec
+ size=32 align=8
+ base size=32 base align=8
+itimerspec (0x7f09f48a7d90) 0
+
+Class _pthread_cleanup_buffer
+ size=32 align=8
+ base size=32 base align=8
+_pthread_cleanup_buffer (0x7f09f48a7e00) 0
+
+Class __pthread_cleanup_frame
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_frame (0x7f09f48a7f50) 0
+
+Class __pthread_cleanup_class
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_class (0x7f09f4905000) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+16 __cxxabiv1::__forced_unwind::~__forced_unwind
+24 __cxxabiv1::__forced_unwind::~__forced_unwind
+32 __cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=8 align=8
+ base size=8 base align=8
+__cxxabiv1::__forced_unwind (0x7f09f47bcb60) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u)
+
+Class std::locale
+ size=8 align=8
+ base size=8 base align=8
+std::locale (0x7f09f446c690) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6locale5facetE)
+16 std::locale::facet::~facet
+24 std::locale::facet::~facet
+
+Class std::locale::facet
+ size=16 align=8
+ base size=12 base align=8
+std::locale::facet (0x7f09f4511d90) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u)
+
+Class std::locale::id
+ size=8 align=8
+ base size=8 base align=8
+std::locale::id (0x7f09f4525380) 0
+
+Class std::locale::_Impl
+ size=40 align=8
+ base size=40 base align=8
+std::locale::_Impl (0x7f09f45259a0) 0
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt8ios_base7failureE)
+16 std::ios_base::failure::~failure
+24 std::ios_base::failure::~failure
+32 std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=16 align=8
+ base size=16 base align=8
+std::ios_base::failure (0x7f09f43b2150) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureE) + 16u)
+ std::exception (0x7f09f43b21c0) 0 nearly-empty
+ primary-for std::ios_base::failure (0x7f09f43b2150)
+
+Class std::ios_base::_Callback_list
+ size=24 align=8
+ base size=24 base align=8
+std::ios_base::_Callback_list (0x7f09f43c13f0) 0
+
+Class std::ios_base::_Words
+ size=16 align=8
+ base size=16 base align=8
+std::ios_base::_Words (0x7f09f43c1e70) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0x7f09f43c65b0) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8ios_base)
+16 std::ios_base::~ios_base
+24 std::ios_base::~ios_base
+
+Class std::ios_base
+ size=216 align=8
+ base size=216 base align=8
+std::ios_base (0x7f09f43b20e0) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0x7f09f443ca10) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0x7f09f415e2a0) 0 empty
+
+VTT for std::basic_ostream<char, std::char_traits<char> >
+std::basic_ostream<char, std::char_traits<char> >::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 24u)
+8 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 64u)
+
+VTT for std::basic_ostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u)
+
+VTT for std::basic_istream<char, std::char_traits<char> >
+std::basic_istream<char, std::char_traits<char> >::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 24u)
+8 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 64u)
+
+VTT for std::basic_istream<wchar_t, std::char_traits<wchar_t> >
+std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u)
+
+Construction vtable for std::basic_istream<char, std::char_traits<char> > (0x7f09f3e8b3f0 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISi)
+24 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+32 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+40 -24u
+48 (int (*)(...))-0x00000000000000018
+56 (int (*)(...))(& _ZTISi)
+64 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n24_NSiD1Ev
+72 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n24_NSiD0Ev
+
+Construction vtable for std::basic_ostream<char, std::char_traits<char> > (0x7f09f3e8b540 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd16_So: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISo)
+24 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+32 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+40 -8u
+48 (int (*)(...))-0x00000000000000008
+56 (int (*)(...))(& _ZTISo)
+64 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n24_NSoD1Ev
+72 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n24_NSoD0Ev
+
+VTT for std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 24u)
+8 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 24u)
+16 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 64u)
+24 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd16_So) + 24u)
+32 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd16_So) + 64u)
+40 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 104u)
+48 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 64u)
+
+Construction vtable for std::basic_istream<wchar_t, std::char_traits<wchar_t> > (0x7f09f3e8b700 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+24 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+32 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+40 -24u
+48 (int (*)(...))-0x00000000000000018
+56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+64 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED1Ev
+72 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED0Ev
+
+Construction vtable for std::basic_ostream<wchar_t, std::char_traits<wchar_t> > (0x7f09f3e8b850 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+24 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+32 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+40 -8u
+48 (int (*)(...))-0x00000000000000008
+56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+64 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev
+72 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev
+
+VTT for std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u)
+16 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u)
+24 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u)
+32 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u)
+40 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u)
+48 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u)
+
+Class QtConcurrent::BlockSizeManager
+ size=96 align=8
+ base size=92 base align=8
+QtConcurrent::BlockSizeManager (0x7f09f3efb310) 0
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+16 QFutureWatcherBase::metaObject
+24 QFutureWatcherBase::qt_metacast
+32 QFutureWatcherBase::qt_metacall
+40 QFutureWatcherBase::~QFutureWatcherBase
+48 QFutureWatcherBase::~QFutureWatcherBase
+56 QFutureWatcherBase::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QFutureWatcherBase::connectNotify
+104 QFutureWatcherBase::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureWatcherBase (0x7f09f3ac2cb0) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u)
+ QObject (0x7f09f3ac2d20) 0
+ primary-for QFutureWatcherBase (0x7f09f3ac2cb0)
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFactoryInterface)
+16 QFactoryInterface::~QFactoryInterface
+24 QFactoryInterface::~QFactoryInterface
+32 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QFactoryInterface (0x7f09f39deee0) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+16 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+24 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QTextCodecFactoryInterface (0x7f09f3a0b000) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 16u)
+ QFactoryInterface (0x7f09f3a0b070) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0x7f09f3a0b000)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+16 QTextCodecPlugin::metaObject
+24 QTextCodecPlugin::qt_metacast
+32 QTextCodecPlugin::qt_metacall
+40 QTextCodecPlugin::~QTextCodecPlugin
+48 QTextCodecPlugin::~QTextCodecPlugin
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 QTextCodecPlugin::keys
+160 QTextCodecPlugin::create
+168 (int (*)(...))-0x00000000000000010
+176 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+184 QTextCodecPlugin::_ZThn16_N16QTextCodecPluginD1Ev
+192 QTextCodecPlugin::_ZThn16_N16QTextCodecPluginD0Ev
+200 QTextCodecPlugin::_ZThn16_NK16QTextCodecPlugin4keysEv
+208 QTextCodecPlugin::_ZThn16_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=24 align=8
+ base size=24 base align=8
+QTextCodecPlugin (0x7f09f3a05e80) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 16u)
+ QObject (0x7f09f3a0b8c0) 0
+ primary-for QTextCodecPlugin (0x7f09f3a05e80)
+ QTextCodecFactoryInterface (0x7f09f3a0b930) 16 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 184u)
+ QFactoryInterface (0x7f09f3a0b9a0) 16 nearly-empty
+ primary-for QTextCodecFactoryInterface (0x7f09f3a0b930)
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0x7f09f3a247e0) 0 empty
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTranslator)
+16 QTranslator::metaObject
+24 QTranslator::qt_metacast
+32 QTranslator::qt_metacall
+40 QTranslator::~QTranslator
+48 QTranslator::~QTranslator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTranslator::translate
+120 QTranslator::isEmpty
+
+Class QTranslator
+ size=16 align=8
+ base size=16 base align=8
+QTranslator (0x7f09f38630e0) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 16u)
+ QObject (0x7f09f3863150) 0
+ primary-for QTranslator (0x7f09f38630e0)
+
+Class __exception
+ size=40 align=8
+ base size=40 base align=8
+__exception (0x7f09f3881070) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QMimeData)
+16 QMimeData::metaObject
+24 QMimeData::qt_metacast
+32 QMimeData::qt_metacall
+40 QMimeData::~QMimeData
+48 QMimeData::~QMimeData
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QMimeData::hasFormat
+120 QMimeData::formats
+128 QMimeData::retrieveData
+
+Class QMimeData
+ size=16 align=8
+ base size=16 base align=8
+QMimeData (0x7f09f38e3230) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 16u)
+ QObject (0x7f09f38e32a0) 0
+ primary-for QMimeData (0x7f09f38e3230)
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QEventLoop)
+16 QEventLoop::metaObject
+24 QEventLoop::qt_metacast
+32 QEventLoop::qt_metacall
+40 QEventLoop::~QEventLoop
+48 QEventLoop::~QEventLoop
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QEventLoop
+ size=16 align=8
+ base size=16 base align=8
+QEventLoop (0x7f09f38fda80) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u)
+ QObject (0x7f09f38fdaf0) 0
+ primary-for QEventLoop (0x7f09f38fda80)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QEvent)
+16 QEvent::~QEvent
+24 QEvent::~QEvent
+
+Class QEvent
+ size=24 align=8
+ base size=20 base align=8
+QEvent (0x7f09f393c3f0) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 16u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTimerEvent)
+16 QTimerEvent::~QTimerEvent
+24 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=24 align=8
+ base size=24 base align=8
+QTimerEvent (0x7f09f375a000) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u)
+ QEvent (0x7f09f375a070) 0
+ primary-for QTimerEvent (0x7f09f375a000)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QChildEvent)
+16 QChildEvent::~QChildEvent
+24 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=32 align=8
+ base size=32 base align=8
+QChildEvent (0x7f09f375a460) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u)
+ QEvent (0x7f09f375a4d0) 0
+ primary-for QChildEvent (0x7f09f375a460)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QCustomEvent)
+16 QCustomEvent::~QCustomEvent
+24 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=24 align=8
+ base size=20 base align=8
+QCustomEvent (0x7f09f376c700) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 16u)
+ QEvent (0x7f09f376c770) 0
+ primary-for QCustomEvent (0x7f09f376c700)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+16 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+24 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=32 align=8
+ base size=32 base align=8
+QDynamicPropertyChangeEvent (0x7f09f376cee0) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u)
+ QEvent (0x7f09f376cf50) 0
+ primary-for QDynamicPropertyChangeEvent (0x7f09f376cee0)
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QCoreApplication)
+16 QCoreApplication::metaObject
+24 QCoreApplication::qt_metacast
+32 QCoreApplication::qt_metacall
+40 QCoreApplication::~QCoreApplication
+48 QCoreApplication::~QCoreApplication
+56 QCoreApplication::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QCoreApplication::notify
+120 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=16 align=8
+ base size=16 base align=8
+QCoreApplication (0x7f09f377a380) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u)
+ QObject (0x7f09f377a3f0) 0
+ primary-for QCoreApplication (0x7f09f377a380)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSharedMemory)
+16 QSharedMemory::metaObject
+24 QSharedMemory::qt_metacast
+32 QSharedMemory::qt_metacall
+40 QSharedMemory::~QSharedMemory
+48 QSharedMemory::~QSharedMemory
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=16 align=8
+ base size=16 base align=8
+QSharedMemory (0x7f09f37a6b60) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u)
+ QObject (0x7f09f37a6bd0) 0
+ primary-for QSharedMemory (0x7f09f37a6b60)
+
+Class QModelIndex
+ size=24 align=8
+ base size=24 base align=8
+QModelIndex (0x7f09f37c5930) 0
+
+Class QPersistentModelIndex
+ size=8 align=8
+ base size=8 base align=8
+QPersistentModelIndex (0x7f09f37f03f0) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractItemModel)
+16 QAbstractItemModel::metaObject
+24 QAbstractItemModel::qt_metacast
+32 QAbstractItemModel::qt_metacall
+40 QAbstractItemModel::~QAbstractItemModel
+48 QAbstractItemModel::~QAbstractItemModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 QAbstractItemModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractItemModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemModel (0x7f09f37fc700) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u)
+ QObject (0x7f09f37fc770) 0
+ primary-for QAbstractItemModel (0x7f09f37fc700)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTableModel)
+16 QAbstractTableModel::metaObject
+24 QAbstractTableModel::qt_metacast
+32 QAbstractTableModel::qt_metacall
+40 QAbstractTableModel::~QAbstractTableModel
+48 QAbstractTableModel::~QAbstractTableModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 QAbstractTableModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTableModel (0x7f09f364fa10) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u)
+ QAbstractItemModel (0x7f09f364fa80) 0
+ primary-for QAbstractTableModel (0x7f09f364fa10)
+ QObject (0x7f09f364faf0) 0
+ primary-for QAbstractItemModel (0x7f09f364fa80)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractListModel)
+16 QAbstractListModel::metaObject
+24 QAbstractListModel::qt_metacast
+32 QAbstractListModel::qt_metacall
+40 QAbstractListModel::~QAbstractListModel
+48 QAbstractListModel::~QAbstractListModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractListModel::index
+120 QAbstractListModel::parent
+128 __cxa_pure_virtual
+136 QAbstractListModel::columnCount
+144 QAbstractListModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractListModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractListModel (0x7f09f365b310) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u)
+ QAbstractItemModel (0x7f09f3668000) 0
+ primary-for QAbstractListModel (0x7f09f365b310)
+ QObject (0x7f09f3668070) 0
+ primary-for QAbstractItemModel (0x7f09f3668000)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSignalMapper)
+16 QSignalMapper::metaObject
+24 QSignalMapper::qt_metacast
+32 QSignalMapper::qt_metacall
+40 QSignalMapper::~QSignalMapper
+48 QSignalMapper::~QSignalMapper
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=16 align=8
+ base size=16 base align=8
+QSignalMapper (0x7f09f369b0e0) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u)
+ QObject (0x7f09f369b150) 0
+ primary-for QSignalMapper (0x7f09f369b0e0)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+16 QObjectCleanupHandler::metaObject
+24 QObjectCleanupHandler::qt_metacast
+32 QObjectCleanupHandler::qt_metacall
+40 QObjectCleanupHandler::~QObjectCleanupHandler
+48 QObjectCleanupHandler::~QObjectCleanupHandler
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=24 align=8
+ base size=24 base align=8
+QObjectCleanupHandler (0x7f09f36b44d0) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u)
+ QObject (0x7f09f36b4540) 0
+ primary-for QObjectCleanupHandler (0x7f09f36b44d0)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0x7f09f36c5620) 0
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSocketNotifier)
+16 QSocketNotifier::metaObject
+24 QSocketNotifier::qt_metacast
+32 QSocketNotifier::qt_metacall
+40 QSocketNotifier::~QSocketNotifier
+48 QSocketNotifier::~QSocketNotifier
+56 QSocketNotifier::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=32 align=8
+ base size=25 base align=8
+QSocketNotifier (0x7f09f36cda10) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u)
+ QObject (0x7f09f36cda80) 0
+ primary-for QSocketNotifier (0x7f09f36cda10)
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QTimer)
+16 QTimer::metaObject
+24 QTimer::qt_metacast
+32 QTimer::qt_metacall
+40 QTimer::~QTimer
+48 QTimer::~QTimer
+56 QObject::event
+64 QObject::eventFilter
+72 QTimer::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QTimer
+ size=32 align=8
+ base size=29 base align=8
+QTimer (0x7f09f36e9d90) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 16u)
+ QObject (0x7f09f36e9e00) 0
+ primary-for QTimer (0x7f09f36e9d90)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+16 QAbstractEventDispatcher::metaObject
+24 QAbstractEventDispatcher::qt_metacast
+32 QAbstractEventDispatcher::qt_metacall
+40 QAbstractEventDispatcher::~QAbstractEventDispatcher
+48 QAbstractEventDispatcher::~QAbstractEventDispatcher
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+192 __cxa_pure_virtual
+200 QAbstractEventDispatcher::startingUp
+208 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=16 align=8
+ base size=16 base align=8
+QAbstractEventDispatcher (0x7f09f370e380) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u)
+ QObject (0x7f09f370e3f0) 0
+ primary-for QAbstractEventDispatcher (0x7f09f370e380)
+
+Class QMetaMethod
+ size=16 align=8
+ base size=12 base align=8
+QMetaMethod (0x7f09f3729230) 0
+
+Class QMetaEnum
+ size=16 align=8
+ base size=12 base align=8
+QMetaEnum (0x7f09f3744690) 0
+
+Class QMetaProperty
+ size=32 align=8
+ base size=32 base align=8
+QMetaProperty (0x7f09f35513f0) 0
+
+Class QMetaClassInfo
+ size=16 align=8
+ base size=12 base align=8
+QMetaClassInfo (0x7f09f3551a80) 0
+
+Class QSystemSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSystemSemaphore (0x7f09f35635b0) 0
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QLibrary)
+16 QLibrary::metaObject
+24 QLibrary::qt_metacast
+32 QLibrary::qt_metacall
+40 QLibrary::~QLibrary
+48 QLibrary::~QLibrary
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QLibrary
+ size=32 align=8
+ base size=25 base align=8
+QLibrary (0x7f09f3563ee0) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 16u)
+ QObject (0x7f09f3563f50) 0
+ primary-for QLibrary (0x7f09f3563ee0)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPluginLoader)
+16 QPluginLoader::metaObject
+24 QPluginLoader::qt_metacast
+32 QPluginLoader::qt_metacall
+40 QPluginLoader::~QPluginLoader
+48 QPluginLoader::~QPluginLoader
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=32 align=8
+ base size=25 base align=8
+QPluginLoader (0x7f09f35aa9a0) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u)
+ QObject (0x7f09f35aaa10) 0
+ primary-for QPluginLoader (0x7f09f35aa9a0)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0x7f09f35cd150) 0
+
+Class QSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSemaphore (0x7f09f35eba80) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0x7f09f35fd000) 0
+
+Class QReadWriteLock
+ size=8 align=8
+ base size=8 base align=8
+QReadWriteLock (0x7f09f35fd770) 0
+
+Class QReadLocker
+ size=8 align=8
+ base size=8 base align=8
+QReadLocker (0x7f09f35fde00) 0
+
+Class QWriteLocker
+ size=8 align=8
+ base size=8 base align=8
+QWriteLocker (0x7f09f362b1c0) 0
+
+Class QDomImplementation
+ size=8 align=8
+ base size=8 base align=8
+QDomImplementation (0x7f09f363d540) 0
+
+Class QDomNode
+ size=8 align=8
+ base size=8 base align=8
+QDomNode (0x7f09f363de70) 0
+
+Class QDomNodeList
+ size=8 align=8
+ base size=8 base align=8
+QDomNodeList (0x7f09f34690e0) 0
+
+Class QDomDocumentType
+ size=8 align=8
+ base size=8 base align=8
+QDomDocumentType (0x7f09f3473150) 0
+ QDomNode (0x7f09f34731c0) 0
+
+Class QDomDocument
+ size=8 align=8
+ base size=8 base align=8
+QDomDocument (0x7f09f3473cb0) 0
+ QDomNode (0x7f09f3473d20) 0
+
+Class QDomNamedNodeMap
+ size=8 align=8
+ base size=8 base align=8
+QDomNamedNodeMap (0x7f09f347bbd0) 0
+
+Class QDomDocumentFragment
+ size=8 align=8
+ base size=8 base align=8
+QDomDocumentFragment (0x7f09f348da10) 0
+ QDomNode (0x7f09f348da80) 0
+
+Class QDomCharacterData
+ size=8 align=8
+ base size=8 base align=8
+QDomCharacterData (0x7f09f349a5b0) 0
+ QDomNode (0x7f09f349a620) 0
+
+Class QDomAttr
+ size=8 align=8
+ base size=8 base align=8
+QDomAttr (0x7f09f34a1000) 0
+ QDomNode (0x7f09f34a1070) 0
+
+Class QDomElement
+ size=8 align=8
+ base size=8 base align=8
+QDomElement (0x7f09f34a1b60) 0
+ QDomNode (0x7f09f34a1bd0) 0
+
+Class QDomText
+ size=8 align=8
+ base size=8 base align=8
+QDomText (0x7f09f34a8e00) 0
+ QDomCharacterData (0x7f09f34a8e70) 0
+ QDomNode (0x7f09f34a8ee0) 0
+
+Class QDomComment
+ size=8 align=8
+ base size=8 base align=8
+QDomComment (0x7f09f34bfb60) 0
+ QDomCharacterData (0x7f09f34bfbd0) 0
+ QDomNode (0x7f09f34bfc40) 0
+
+Class QDomCDATASection
+ size=8 align=8
+ base size=8 base align=8
+QDomCDATASection (0x7f09f34c4770) 0
+ QDomText (0x7f09f34c47e0) 0
+ QDomCharacterData (0x7f09f34c4850) 0
+ QDomNode (0x7f09f34c48c0) 0
+
+Class QDomNotation
+ size=8 align=8
+ base size=8 base align=8
+QDomNotation (0x7f09f34c83f0) 0
+ QDomNode (0x7f09f34c8460) 0
+
+Class QDomEntity
+ size=8 align=8
+ base size=8 base align=8
+QDomEntity (0x7f09f34c8f50) 0
+ QDomNode (0x7f09f34d0000) 0
+
+Class QDomEntityReference
+ size=8 align=8
+ base size=8 base align=8
+QDomEntityReference (0x7f09f34d0af0) 0
+ QDomNode (0x7f09f34d0b60) 0
+
+Class QDomProcessingInstruction
+ size=8 align=8
+ base size=8 base align=8
+QDomProcessingInstruction (0x7f09f34d4690) 0
+ QDomNode (0x7f09f34d4700) 0
+
+Class QXmlNamespaceSupport
+ size=8 align=8
+ base size=8 base align=8
+QXmlNamespaceSupport (0x7f09f34dc230) 0
+
+Class QXmlAttributes::Attribute
+ size=32 align=8
+ base size=32 base align=8
+QXmlAttributes::Attribute (0x7f09f34dc8c0) 0
+
+Vtable for QXmlAttributes
+QXmlAttributes::_ZTV14QXmlAttributes: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QXmlAttributes)
+16 QXmlAttributes::~QXmlAttributes
+24 QXmlAttributes::~QXmlAttributes
+
+Class QXmlAttributes
+ size=24 align=8
+ base size=24 base align=8
+QXmlAttributes (0x7f09f34dc770) 0
+ vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 16u)
+
+Vtable for QXmlInputSource
+QXmlInputSource::_ZTV15QXmlInputSource: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QXmlInputSource)
+16 QXmlInputSource::~QXmlInputSource
+24 QXmlInputSource::~QXmlInputSource
+32 QXmlInputSource::setData
+40 QXmlInputSource::setData
+48 QXmlInputSource::fetchData
+56 QXmlInputSource::data
+64 QXmlInputSource::next
+72 QXmlInputSource::reset
+80 QXmlInputSource::fromRawData
+
+Class QXmlInputSource
+ size=16 align=8
+ base size=16 base align=8
+QXmlInputSource (0x7f09f351d000) 0
+ vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 16u)
+
+Class QXmlParseException
+ size=8 align=8
+ base size=8 base align=8
+QXmlParseException (0x7f09f351d310) 0
+
+Vtable for QXmlReader
+QXmlReader::_ZTV10QXmlReader: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QXmlReader)
+16 QXmlReader::~QXmlReader
+24 QXmlReader::~QXmlReader
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+
+Class QXmlReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlReader (0x7f09f351d5b0) 0 nearly-empty
+ vptr=((& QXmlReader::_ZTV10QXmlReader) + 16u)
+
+Vtable for QXmlSimpleReader
+QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QXmlSimpleReader)
+16 QXmlSimpleReader::~QXmlSimpleReader
+24 QXmlSimpleReader::~QXmlSimpleReader
+32 QXmlSimpleReader::feature
+40 QXmlSimpleReader::setFeature
+48 QXmlSimpleReader::hasFeature
+56 QXmlSimpleReader::property
+64 QXmlSimpleReader::setProperty
+72 QXmlSimpleReader::hasProperty
+80 QXmlSimpleReader::setEntityResolver
+88 QXmlSimpleReader::entityResolver
+96 QXmlSimpleReader::setDTDHandler
+104 QXmlSimpleReader::DTDHandler
+112 QXmlSimpleReader::setContentHandler
+120 QXmlSimpleReader::contentHandler
+128 QXmlSimpleReader::setErrorHandler
+136 QXmlSimpleReader::errorHandler
+144 QXmlSimpleReader::setLexicalHandler
+152 QXmlSimpleReader::lexicalHandler
+160 QXmlSimpleReader::setDeclHandler
+168 QXmlSimpleReader::declHandler
+176 QXmlSimpleReader::parse
+184 QXmlSimpleReader::parse
+192 QXmlSimpleReader::parse
+200 QXmlSimpleReader::parseContinue
+
+Class QXmlSimpleReader
+ size=16 align=8
+ base size=16 base align=8
+QXmlSimpleReader (0x7f09f351d2a0) 0
+ vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 16u)
+ QXmlReader (0x7f09f351d690) 0 nearly-empty
+ primary-for QXmlSimpleReader (0x7f09f351d2a0)
+
+Vtable for QXmlLocator
+QXmlLocator::_ZTV11QXmlLocator: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QXmlLocator)
+16 QXmlLocator::~QXmlLocator
+24 QXmlLocator::~QXmlLocator
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QXmlLocator
+ size=8 align=8
+ base size=8 base align=8
+QXmlLocator (0x7f09f3539a10) 0 nearly-empty
+ vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 16u)
+
+Vtable for QXmlContentHandler
+QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlContentHandler)
+16 QXmlContentHandler::~QXmlContentHandler
+24 QXmlContentHandler::~QXmlContentHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QXmlContentHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlContentHandler (0x7f09f3539c40) 0 nearly-empty
+ vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 16u)
+
+Vtable for QXmlErrorHandler
+QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QXmlErrorHandler)
+16 QXmlErrorHandler::~QXmlErrorHandler
+24 QXmlErrorHandler::~QXmlErrorHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+
+Class QXmlErrorHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlErrorHandler (0x7f09f3352540) 0 nearly-empty
+ vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 16u)
+
+Vtable for QXmlDTDHandler
+QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QXmlDTDHandler)
+16 QXmlDTDHandler::~QXmlDTDHandler
+24 QXmlDTDHandler::~QXmlDTDHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QXmlDTDHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlDTDHandler (0x7f09f3352f50) 0 nearly-empty
+ vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 16u)
+
+Vtable for QXmlEntityResolver
+QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlEntityResolver)
+16 QXmlEntityResolver::~QXmlEntityResolver
+24 QXmlEntityResolver::~QXmlEntityResolver
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QXmlEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlEntityResolver (0x7f09f3361930) 0 nearly-empty
+ vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 16u)
+
+Vtable for QXmlLexicalHandler
+QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlLexicalHandler)
+16 QXmlLexicalHandler::~QXmlLexicalHandler
+24 QXmlLexicalHandler::~QXmlLexicalHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QXmlLexicalHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlLexicalHandler (0x7f09f336c310) 0 nearly-empty
+ vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 16u)
+
+Vtable for QXmlDeclHandler
+QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QXmlDeclHandler)
+16 QXmlDeclHandler::~QXmlDeclHandler
+24 QXmlDeclHandler::~QXmlDeclHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+
+Class QXmlDeclHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlDeclHandler (0x7f09f336cd20) 0 nearly-empty
+ vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 16u)
+
+Vtable for QXmlDefaultHandler
+QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+16 QXmlDefaultHandler::~QXmlDefaultHandler
+24 QXmlDefaultHandler::~QXmlDefaultHandler
+32 QXmlDefaultHandler::setDocumentLocator
+40 QXmlDefaultHandler::startDocument
+48 QXmlDefaultHandler::endDocument
+56 QXmlDefaultHandler::startPrefixMapping
+64 QXmlDefaultHandler::endPrefixMapping
+72 QXmlDefaultHandler::startElement
+80 QXmlDefaultHandler::endElement
+88 QXmlDefaultHandler::characters
+96 QXmlDefaultHandler::ignorableWhitespace
+104 QXmlDefaultHandler::processingInstruction
+112 QXmlDefaultHandler::skippedEntity
+120 QXmlDefaultHandler::errorString
+128 QXmlDefaultHandler::warning
+136 QXmlDefaultHandler::error
+144 QXmlDefaultHandler::fatalError
+152 QXmlDefaultHandler::notationDecl
+160 QXmlDefaultHandler::unparsedEntityDecl
+168 QXmlDefaultHandler::resolveEntity
+176 QXmlDefaultHandler::startDTD
+184 QXmlDefaultHandler::endDTD
+192 QXmlDefaultHandler::startEntity
+200 QXmlDefaultHandler::endEntity
+208 QXmlDefaultHandler::startCDATA
+216 QXmlDefaultHandler::endCDATA
+224 QXmlDefaultHandler::comment
+232 QXmlDefaultHandler::attributeDecl
+240 QXmlDefaultHandler::internalEntityDecl
+248 QXmlDefaultHandler::externalEntityDecl
+256 (int (*)(...))-0x00000000000000008
+264 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+272 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev
+280 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev
+288 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler7warningERK18QXmlParseException
+296 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler5errorERK18QXmlParseException
+304 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException
+312 QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv
+320 (int (*)(...))-0x00000000000000010
+328 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+336 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev
+344 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev
+352 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_
+360 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_
+368 QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv
+376 (int (*)(...))-0x00000000000000018
+384 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+392 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandlerD1Ev
+400 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandlerD0Ev
+408 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource
+416 QXmlDefaultHandler::_ZThn24_NK18QXmlDefaultHandler11errorStringEv
+424 (int (*)(...))-0x00000000000000020
+432 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+440 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandlerD1Ev
+448 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandlerD0Ev
+456 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_
+464 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler6endDTDEv
+472 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler11startEntityERK7QString
+480 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler9endEntityERK7QString
+488 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler10startCDATAEv
+496 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler8endCDATAEv
+504 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler7commentERK7QString
+512 QXmlDefaultHandler::_ZThn32_NK18QXmlDefaultHandler11errorStringEv
+520 (int (*)(...))-0x00000000000000028
+528 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+536 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandlerD1Ev
+544 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandlerD0Ev
+552 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_
+560 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_
+568 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_
+576 QXmlDefaultHandler::_ZThn40_NK18QXmlDefaultHandler11errorStringEv
+
+Class QXmlDefaultHandler
+ size=56 align=8
+ base size=56 base align=8
+QXmlDefaultHandler (0x7f09f3376c80) 0
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 16u)
+ QXmlContentHandler (0x7f09f337d690) 0 nearly-empty
+ primary-for QXmlDefaultHandler (0x7f09f3376c80)
+ QXmlErrorHandler (0x7f09f337d700) 8 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 272u)
+ QXmlDTDHandler (0x7f09f337d770) 16 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 336u)
+ QXmlEntityResolver (0x7f09f337d7e0) 24 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 392u)
+ QXmlLexicalHandler (0x7f09f337d850) 32 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 440u)
+ QXmlDeclHandler (0x7f09f337d8c0) 40 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 536u)
+
+Vtable for QAbstractExtensionFactory
+QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAbstractExtensionFactory)
+16 QAbstractExtensionFactory::~QAbstractExtensionFactory
+24 QAbstractExtensionFactory::~QAbstractExtensionFactory
+32 __cxa_pure_virtual
+
+Class QAbstractExtensionFactory
+ size=8 align=8
+ base size=8 base align=8
+QAbstractExtensionFactory (0x7f09f33d1230) 0 nearly-empty
+ vptr=((& QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory) + 16u)
+
+Vtable for QAbstractExtensionManager
+QAbstractExtensionManager::_ZTV25QAbstractExtensionManager: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAbstractExtensionManager)
+16 QAbstractExtensionManager::~QAbstractExtensionManager
+24 QAbstractExtensionManager::~QAbstractExtensionManager
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QAbstractExtensionManager
+ size=8 align=8
+ base size=8 base align=8
+QAbstractExtensionManager (0x7f09f33de310) 0 nearly-empty
+ vptr=((& QAbstractExtensionManager::_ZTV25QAbstractExtensionManager) + 16u)
+
+Vtable for QDesignerMemberSheetExtension
+QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QDesignerMemberSheetExtension)
+16 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+24 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+
+Class QDesignerMemberSheetExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerMemberSheetExtension (0x7f09f33ea460) 0 nearly-empty
+ vptr=((& QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension) + 16u)
+
+Vtable for QDesignerWidgetFactoryInterface
+QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface: 21u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI31QDesignerWidgetFactoryInterface)
+16 QDesignerWidgetFactoryInterface::metaObject
+24 QDesignerWidgetFactoryInterface::qt_metacast
+32 QDesignerWidgetFactoryInterface::qt_metacall
+40 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+48 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+
+Class QDesignerWidgetFactoryInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerWidgetFactoryInterface (0x7f09f33feaf0) 0
+ vptr=((& QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface) + 16u)
+ QObject (0x7f09f33feb60) 0
+ primary-for QDesignerWidgetFactoryInterface (0x7f09f33feaf0)
+
+Vtable for QDesignerFormEditorPluginInterface
+QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI34QDesignerFormEditorPluginInterface)
+16 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+24 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+
+Class QDesignerFormEditorPluginInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerFormEditorPluginInterface (0x7f09f3415a80) 0 nearly-empty
+ vptr=((& QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface) + 16u)
+
+Vtable for QDesignerExtraInfoExtension
+QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerExtraInfoExtension)
+16 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+24 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerExtraInfoExtension
+ size=16 align=8
+ base size=16 base align=8
+QDesignerExtraInfoExtension (0x7f09f341fc40) 0
+ vptr=((& QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension) + 16u)
+
+Vtable for QDesignerDynamicPropertySheetExtension
+QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI38QDesignerDynamicPropertySheetExtension)
+16 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+24 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+
+Class QDesignerDynamicPropertySheetExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerDynamicPropertySheetExtension (0x7f09f343b4d0) 0 nearly-empty
+ vptr=((& QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension) + 16u)
+
+Vtable for QDesignerFormWindowToolInterface
+QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QDesignerFormWindowToolInterface)
+16 QDesignerFormWindowToolInterface::metaObject
+24 QDesignerFormWindowToolInterface::qt_metacast
+32 QDesignerFormWindowToolInterface::qt_metacall
+40 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+48 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 QDesignerFormWindowToolInterface::saveToDom
+168 QDesignerFormWindowToolInterface::loadFromDom
+176 __cxa_pure_virtual
+
+Class QDesignerFormWindowToolInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerFormWindowToolInterface (0x7f09f3249b60) 0
+ vptr=((& QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface) + 16u)
+ QObject (0x7f09f3249bd0) 0
+ primary-for QDesignerFormWindowToolInterface (0x7f09f3249b60)
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintDevice)
+16 QPaintDevice::~QPaintDevice
+24 QPaintDevice::~QPaintDevice
+32 QPaintDevice::devType
+40 __cxa_pure_virtual
+48 QPaintDevice::metric
+
+Class QPaintDevice
+ size=16 align=8
+ base size=10 base align=8
+QPaintDevice (0x7f09f325ec40) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0x7f09f329a000) 0
+
+Class QPolygon
+ size=8 align=8
+ base size=8 base align=8
+QPolygon (0x7f09f32e93f0) 0
+ QVector<QPoint> (0x7f09f32e9460) 0
+
+Class QPolygonF
+ size=8 align=8
+ base size=8 base align=8
+QPolygonF (0x7f09f332d540) 0
+ QVector<QPointF> (0x7f09f332d5b0) 0
+
+Class QRegion::QRegionData
+ size=32 align=8
+ base size=32 base align=8
+QRegion::QRegionData (0x7f09f3185af0) 0
+
+Class QRegion
+ size=8 align=8
+ base size=8 base align=8
+QRegion (0x7f09f316d1c0) 0
+
+Class QMatrix
+ size=48 align=8
+ base size=48 base align=8
+QMatrix (0x7f09f31a2310) 0
+
+Class QPainterPath::Element
+ size=24 align=8
+ base size=24 base align=8
+QPainterPath::Element (0x7f09f31d2d20) 0
+
+Class QPainterPath
+ size=8 align=8
+ base size=8 base align=8
+QPainterPath (0x7f09f31d2cb0) 0
+
+Class QPainterPathPrivate
+ size=16 align=8
+ base size=16 base align=8
+QPainterPathPrivate (0x7f09f321b0e0) 0
+
+Class QPainterPathStroker
+ size=8 align=8
+ base size=8 base align=8
+QPainterPathStroker (0x7f09f321bc40) 0
+
+Class QTransform
+ size=88 align=8
+ base size=88 base align=8
+QTransform (0x7f09f307a7e0) 0
+
+Class QImageTextKeyLang
+ size=16 align=8
+ base size=16 base align=8
+QImageTextKeyLang (0x7f09f30f8af0) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QImage)
+16 QImage::~QImage
+24 QImage::~QImage
+32 QImage::devType
+40 QImage::paintEngine
+48 QImage::metric
+
+Class QImage
+ size=24 align=8
+ base size=24 base align=8
+QImage (0x7f09f3148380) 0
+ vptr=((& QImage::_ZTV6QImage) + 16u)
+ QPaintDevice (0x7f09f31483f0) 0
+ primary-for QImage (0x7f09f3148380)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QPixmap)
+16 QPixmap::~QPixmap
+24 QPixmap::~QPixmap
+32 QPixmap::devType
+40 QPixmap::paintEngine
+48 QPixmap::metric
+
+Class QPixmap
+ size=24 align=8
+ base size=24 base align=8
+QPixmap (0x7f09f2f3ed90) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 16u)
+ QPaintDevice (0x7f09f2f3ee00) 0
+ primary-for QPixmap (0x7f09f2f3ed90)
+
+Class QBrush
+ size=8 align=8
+ base size=8 base align=8
+QBrush (0x7f09f2f91f50) 0
+
+Class QBrushData
+ size=112 align=8
+ base size=112 base align=8
+QBrushData (0x7f09f2fb2b60) 0
+
+Class QGradient
+ size=64 align=8
+ base size=64 base align=8
+QGradient (0x7f09f2fc0d20) 0
+
+Class QLinearGradient
+ size=64 align=8
+ base size=64 base align=8
+QLinearGradient (0x7f09f2dfe7e0) 0
+ QGradient (0x7f09f2dfe850) 0
+
+Class QRadialGradient
+ size=64 align=8
+ base size=64 base align=8
+QRadialGradient (0x7f09f2dfecb0) 0
+ QGradient (0x7f09f2dfed20) 0
+
+Class QConicalGradient
+ size=64 align=8
+ base size=64 base align=8
+QConicalGradient (0x7f09f2e112a0) 0
+ QGradient (0x7f09f2e11310) 0
+
+Class QPalette
+ size=16 align=8
+ base size=12 base align=8
+QPalette (0x7f09f2e11620) 0
+
+Class QColorGroup
+ size=16 align=8
+ base size=12 base align=8
+QColorGroup (0x7f09f2e5ef50) 0
+ QPalette (0x7f09f2e67000) 0
+
+Class QFont
+ size=16 align=8
+ base size=12 base align=8
+QFont (0x7f09f2ea02a0) 0
+
+Class QFontMetrics
+ size=8 align=8
+ base size=8 base align=8
+QFontMetrics (0x7f09f2cd6ee0) 0
+
+Class QFontMetricsF
+ size=8 align=8
+ base size=8 base align=8
+QFontMetricsF (0x7f09f2cf2380) 0
+
+Class QFontInfo
+ size=8 align=8
+ base size=8 base align=8
+QFontInfo (0x7f09f2d072a0) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0x7f09f2d07d90) 0
+
+Class QCursor
+ size=8 align=8
+ base size=8 base align=8
+QCursor (0x7f09f2bcdaf0) 0
+
+Class QKeySequence
+ size=8 align=8
+ base size=8 base align=8
+QKeySequence (0x7f09f2bd3310) 0
+
+Class QWidgetData
+ size=88 align=8
+ base size=88 base align=8
+QWidgetData (0x7f09f2bf5ee0) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWidget)
+16 QWidget::metaObject
+24 QWidget::qt_metacast
+32 QWidget::qt_metacall
+40 QWidget::~QWidget
+48 QWidget::~QWidget
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI7QWidget)
+464 QWidget::_ZThn16_N7QWidgetD1Ev
+472 QWidget::_ZThn16_N7QWidgetD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=40 align=8
+ base size=40 base align=8
+QWidget (0x7f09f2c1c180) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 16u)
+ QObject (0x7f09f2bf5f50) 0
+ primary-for QWidget (0x7f09f2c1c180)
+ QPaintDevice (0x7f09f2c2f000) 16
+ vptr=((& QWidget::_ZTV7QWidget) + 464u)
+
+Class QIcon
+ size=8 align=8
+ base size=8 base align=8
+QIcon (0x7f09f2b81d20) 0
+
+Class QDesignerWidgetBoxInterface::Widget
+ size=32 align=8
+ base size=28 base align=8
+QDesignerWidgetBoxInterface::Widget (0x7f09f2bada80) 0
+
+Class QDesignerWidgetBoxInterface::Category
+ size=24 align=8
+ base size=24 base align=8
+QDesignerWidgetBoxInterface::Category (0x7f09f29c51c0) 0
+
+Vtable for QDesignerWidgetBoxInterface
+QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface: 76u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+16 QDesignerWidgetBoxInterface::metaObject
+24 QDesignerWidgetBoxInterface::qt_metacast
+32 QDesignerWidgetBoxInterface::qt_metacall
+40 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+48 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 __cxa_pure_virtual
+456 __cxa_pure_virtual
+464 __cxa_pure_virtual
+472 __cxa_pure_virtual
+480 __cxa_pure_virtual
+488 __cxa_pure_virtual
+496 __cxa_pure_virtual
+504 __cxa_pure_virtual
+512 __cxa_pure_virtual
+520 __cxa_pure_virtual
+528 __cxa_pure_virtual
+536 __cxa_pure_virtual
+544 __cxa_pure_virtual
+552 (int (*)(...))-0x00000000000000010
+560 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+568 QDesignerWidgetBoxInterface::_ZThn16_N27QDesignerWidgetBoxInterfaceD1Ev
+576 QDesignerWidgetBoxInterface::_ZThn16_N27QDesignerWidgetBoxInterfaceD0Ev
+584 QWidget::_ZThn16_NK7QWidget7devTypeEv
+592 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+600 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerWidgetBoxInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerWidgetBoxInterface (0x7f09f2bad8c0) 0
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 16u)
+ QWidget (0x7f09f2bb4580) 0
+ primary-for QDesignerWidgetBoxInterface (0x7f09f2bad8c0)
+ QObject (0x7f09f2bad930) 0
+ primary-for QWidget (0x7f09f2bb4580)
+ QPaintDevice (0x7f09f2bad9a0) 16
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 568u)
+
+Class QDesignerPromotionInterface::PromotedClass
+ size=16 align=8
+ base size=16 base align=8
+QDesignerPromotionInterface::PromotedClass (0x7f09f2a48150) 0
+
+Vtable for QDesignerPromotionInterface
+QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerPromotionInterface)
+16 QDesignerPromotionInterface::~QDesignerPromotionInterface
+24 QDesignerPromotionInterface::~QDesignerPromotionInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerPromotionInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerPromotionInterface (0x7f09f2a48070) 0 nearly-empty
+ vptr=((& QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface) + 16u)
+
+Vtable for QDesignerFormWindowInterface
+QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface: 114u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+16 QDesignerFormWindowInterface::metaObject
+24 QDesignerFormWindowInterface::qt_metacast
+32 QDesignerFormWindowInterface::qt_metacall
+40 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+48 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 __cxa_pure_virtual
+456 __cxa_pure_virtual
+464 __cxa_pure_virtual
+472 __cxa_pure_virtual
+480 __cxa_pure_virtual
+488 __cxa_pure_virtual
+496 __cxa_pure_virtual
+504 __cxa_pure_virtual
+512 __cxa_pure_virtual
+520 __cxa_pure_virtual
+528 __cxa_pure_virtual
+536 __cxa_pure_virtual
+544 __cxa_pure_virtual
+552 __cxa_pure_virtual
+560 __cxa_pure_virtual
+568 __cxa_pure_virtual
+576 __cxa_pure_virtual
+584 __cxa_pure_virtual
+592 __cxa_pure_virtual
+600 __cxa_pure_virtual
+608 QDesignerFormWindowInterface::core
+616 __cxa_pure_virtual
+624 __cxa_pure_virtual
+632 __cxa_pure_virtual
+640 __cxa_pure_virtual
+648 __cxa_pure_virtual
+656 __cxa_pure_virtual
+664 __cxa_pure_virtual
+672 __cxa_pure_virtual
+680 __cxa_pure_virtual
+688 __cxa_pure_virtual
+696 __cxa_pure_virtual
+704 __cxa_pure_virtual
+712 __cxa_pure_virtual
+720 __cxa_pure_virtual
+728 __cxa_pure_virtual
+736 __cxa_pure_virtual
+744 __cxa_pure_virtual
+752 __cxa_pure_virtual
+760 __cxa_pure_virtual
+768 __cxa_pure_virtual
+776 __cxa_pure_virtual
+784 __cxa_pure_virtual
+792 __cxa_pure_virtual
+800 __cxa_pure_virtual
+808 __cxa_pure_virtual
+816 __cxa_pure_virtual
+824 __cxa_pure_virtual
+832 __cxa_pure_virtual
+840 __cxa_pure_virtual
+848 __cxa_pure_virtual
+856 (int (*)(...))-0x00000000000000010
+864 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+872 QDesignerFormWindowInterface::_ZThn16_N28QDesignerFormWindowInterfaceD1Ev
+880 QDesignerFormWindowInterface::_ZThn16_N28QDesignerFormWindowInterfaceD0Ev
+888 QWidget::_ZThn16_NK7QWidget7devTypeEv
+896 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+904 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerFormWindowInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerFormWindowInterface (0x7f09f2a48620) 0
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 16u)
+ QWidget (0x7f09f2a4e000) 0
+ primary-for QDesignerFormWindowInterface (0x7f09f2a48620)
+ QObject (0x7f09f2a48690) 0
+ primary-for QWidget (0x7f09f2a4e000)
+ QPaintDevice (0x7f09f2a48700) 16
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 872u)
+
+Vtable for QDesignerObjectInspectorInterface
+QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+16 QDesignerObjectInspectorInterface::metaObject
+24 QDesignerObjectInspectorInterface::qt_metacast
+32 QDesignerObjectInspectorInterface::qt_metacall
+40 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+48 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QDesignerObjectInspectorInterface::core
+456 __cxa_pure_virtual
+464 (int (*)(...))-0x00000000000000010
+472 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+480 QDesignerObjectInspectorInterface::_ZThn16_N33QDesignerObjectInspectorInterfaceD1Ev
+488 QDesignerObjectInspectorInterface::_ZThn16_N33QDesignerObjectInspectorInterfaceD0Ev
+496 QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerObjectInspectorInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerObjectInspectorInterface (0x7f09f2a76a10) 0
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 16u)
+ QWidget (0x7f09f2a4e900) 0
+ primary-for QDesignerObjectInspectorInterface (0x7f09f2a76a10)
+ QObject (0x7f09f2a76a80) 0
+ primary-for QWidget (0x7f09f2a4e900)
+ QPaintDevice (0x7f09f2a76af0) 16
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 480u)
+
+Vtable for QDesignerIconCacheInterface
+QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerIconCacheInterface)
+16 QDesignerIconCacheInterface::metaObject
+24 QDesignerIconCacheInterface::qt_metacast
+32 QDesignerIconCacheInterface::qt_metacall
+40 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+48 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+
+Class QDesignerIconCacheInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerIconCacheInterface (0x7f09f2a8a9a0) 0
+ vptr=((& QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface) + 16u)
+ QObject (0x7f09f2a8aa10) 0
+ primary-for QDesignerIconCacheInterface (0x7f09f2a8a9a0)
+
+Vtable for QDesignerMetaDataBaseItemInterface
+QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI34QDesignerMetaDataBaseItemInterface)
+16 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+24 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseItemInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerMetaDataBaseItemInterface (0x7f09f2aa80e0) 0 nearly-empty
+ vptr=((& QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface) + 16u)
+
+Vtable for QDesignerMetaDataBaseInterface
+QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QDesignerMetaDataBaseInterface)
+16 QDesignerMetaDataBaseInterface::metaObject
+24 QDesignerMetaDataBaseInterface::qt_metacast
+32 QDesignerMetaDataBaseInterface::qt_metacall
+40 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+48 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerMetaDataBaseInterface (0x7f09f2aa8af0) 0
+ vptr=((& QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface) + 16u)
+ QObject (0x7f09f2aa8b60) 0
+ primary-for QDesignerMetaDataBaseInterface (0x7f09f2aa8af0)
+
+Vtable for QDesignerLayoutDecorationExtension
+QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI34QDesignerLayoutDecorationExtension)
+16 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+24 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+
+Class QDesignerLayoutDecorationExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerLayoutDecorationExtension (0x7f09f28b9380) 0 nearly-empty
+ vptr=((& QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension) + 16u)
+
+Vtable for QDesignerPropertySheetExtension
+QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI31QDesignerPropertySheetExtension)
+16 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+24 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+
+Class QDesignerPropertySheetExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerPropertySheetExtension (0x7f09f28da770) 0 nearly-empty
+ vptr=((& QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension) + 16u)
+
+Vtable for QDesignerActionEditorInterface
+QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+16 QDesignerActionEditorInterface::metaObject
+24 QDesignerActionEditorInterface::qt_metacast
+32 QDesignerActionEditorInterface::qt_metacall
+40 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+48 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QDesignerActionEditorInterface::core
+456 __cxa_pure_virtual
+464 __cxa_pure_virtual
+472 __cxa_pure_virtual
+480 (int (*)(...))-0x00000000000000010
+488 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+496 QDesignerActionEditorInterface::_ZThn16_N30QDesignerActionEditorInterfaceD1Ev
+504 QDesignerActionEditorInterface::_ZThn16_N30QDesignerActionEditorInterfaceD0Ev
+512 QWidget::_ZThn16_NK7QWidget7devTypeEv
+520 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+528 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerActionEditorInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerActionEditorInterface (0x7f09f28eae00) 0
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 16u)
+ QWidget (0x7f09f28ebb00) 0
+ primary-for QDesignerActionEditorInterface (0x7f09f28eae00)
+ QObject (0x7f09f28eae70) 0
+ primary-for QWidget (0x7f09f28ebb00)
+ QPaintDevice (0x7f09f28eaee0) 16
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 496u)
+
+Vtable for QDesignerIntegrationInterface
+QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QDesignerIntegrationInterface)
+16 QDesignerIntegrationInterface::metaObject
+24 QDesignerIntegrationInterface::qt_metacast
+32 QDesignerIntegrationInterface::qt_metacall
+40 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+48 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+
+Class QDesignerIntegrationInterface
+ size=24 align=8
+ base size=24 base align=8
+QDesignerIntegrationInterface (0x7f09f28f9e00) 0
+ vptr=((& QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface) + 16u)
+ QObject (0x7f09f28f9e70) 0
+ primary-for QDesignerIntegrationInterface (0x7f09f28f9e00)
+
+Vtable for QDesignerTaskMenuExtension
+QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QDesignerTaskMenuExtension)
+16 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+24 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+32 QDesignerTaskMenuExtension::preferredEditAction
+40 __cxa_pure_virtual
+
+Class QDesignerTaskMenuExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerTaskMenuExtension (0x7f09f2912e70) 0 nearly-empty
+ vptr=((& QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension) + 16u)
+
+Vtable for QDesignerFormWindowCursorInterface
+QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI34QDesignerFormWindowCursorInterface)
+16 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+24 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+
+Class QDesignerFormWindowCursorInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerFormWindowCursorInterface (0x7f09f292a690) 0 nearly-empty
+ vptr=((& QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface) + 16u)
+
+Vtable for QDesignerWidgetDataBaseItemInterface
+QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI36QDesignerWidgetDataBaseItemInterface)
+16 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+24 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+192 __cxa_pure_virtual
+200 __cxa_pure_virtual
+208 __cxa_pure_virtual
+216 __cxa_pure_virtual
+224 __cxa_pure_virtual
+232 __cxa_pure_virtual
+
+Class QDesignerWidgetDataBaseItemInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerWidgetDataBaseItemInterface (0x7f09f293b380) 0 nearly-empty
+ vptr=((& QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface) + 16u)
+
+Vtable for QDesignerWidgetDataBaseInterface
+QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QDesignerWidgetDataBaseInterface)
+16 QDesignerWidgetDataBaseInterface::metaObject
+24 QDesignerWidgetDataBaseInterface::qt_metacast
+32 QDesignerWidgetDataBaseInterface::qt_metacall
+40 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+48 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QDesignerWidgetDataBaseInterface::count
+120 QDesignerWidgetDataBaseInterface::item
+128 QDesignerWidgetDataBaseInterface::indexOf
+136 QDesignerWidgetDataBaseInterface::insert
+144 QDesignerWidgetDataBaseInterface::append
+152 QDesignerWidgetDataBaseInterface::indexOfObject
+160 QDesignerWidgetDataBaseInterface::indexOfClassName
+168 QDesignerWidgetDataBaseInterface::core
+
+Class QDesignerWidgetDataBaseInterface
+ size=24 align=8
+ base size=24 base align=8
+QDesignerWidgetDataBaseInterface (0x7f09f293bd90) 0
+ vptr=((& QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface) + 16u)
+ QObject (0x7f09f293be00) 0
+ primary-for QDesignerWidgetDataBaseInterface (0x7f09f293bd90)
+
+Vtable for QDesignerPropertyEditorInterface
+QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface: 70u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+16 QDesignerPropertyEditorInterface::metaObject
+24 QDesignerPropertyEditorInterface::qt_metacast
+32 QDesignerPropertyEditorInterface::qt_metacall
+40 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+48 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QDesignerPropertyEditorInterface::core
+456 __cxa_pure_virtual
+464 __cxa_pure_virtual
+472 __cxa_pure_virtual
+480 __cxa_pure_virtual
+488 __cxa_pure_virtual
+496 __cxa_pure_virtual
+504 (int (*)(...))-0x00000000000000010
+512 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+520 QDesignerPropertyEditorInterface::_ZThn16_N32QDesignerPropertyEditorInterfaceD1Ev
+528 QDesignerPropertyEditorInterface::_ZThn16_N32QDesignerPropertyEditorInterfaceD0Ev
+536 QWidget::_ZThn16_NK7QWidget7devTypeEv
+544 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+552 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerPropertyEditorInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerPropertyEditorInterface (0x7f09f29521c0) 0
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 16u)
+ QWidget (0x7f09f2982280) 0
+ primary-for QDesignerPropertyEditorInterface (0x7f09f29521c0)
+ QObject (0x7f09f2952380) 0
+ primary-for QWidget (0x7f09f2982280)
+ QPaintDevice (0x7f09f2988000) 16
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 520u)
+
+Vtable for QDesignerFormEditorInterface
+QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QDesignerFormEditorInterface)
+16 QDesignerFormEditorInterface::metaObject
+24 QDesignerFormEditorInterface::qt_metacast
+32 QDesignerFormEditorInterface::qt_metacall
+40 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+48 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QDesignerFormEditorInterface
+ size=120 align=8
+ base size=120 base align=8
+QDesignerFormEditorInterface (0x7f09f299f070) 0
+ vptr=((& QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface) + 16u)
+ QObject (0x7f09f299f0e0) 0
+ primary-for QDesignerFormEditorInterface (0x7f09f299f070)
+
+Vtable for QDesignerResourceBrowserInterface
+QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+16 QDesignerResourceBrowserInterface::metaObject
+24 QDesignerResourceBrowserInterface::qt_metacast
+32 QDesignerResourceBrowserInterface::qt_metacall
+40 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+48 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 __cxa_pure_virtual
+456 __cxa_pure_virtual
+464 (int (*)(...))-0x00000000000000010
+472 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+480 QDesignerResourceBrowserInterface::_ZThn16_N33QDesignerResourceBrowserInterfaceD1Ev
+488 QDesignerResourceBrowserInterface::_ZThn16_N33QDesignerResourceBrowserInterfaceD0Ev
+496 QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerResourceBrowserInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerResourceBrowserInterface (0x7f09f2807770) 0
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 16u)
+ QWidget (0x7f09f27fe600) 0
+ primary-for QDesignerResourceBrowserInterface (0x7f09f2807770)
+ QObject (0x7f09f28077e0) 0
+ primary-for QWidget (0x7f09f27fe600)
+ QPaintDevice (0x7f09f2807850) 16
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 480u)
+
+Vtable for QDesignerBrushManagerInterface
+QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface: 21u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QDesignerBrushManagerInterface)
+16 QDesignerBrushManagerInterface::metaObject
+24 QDesignerBrushManagerInterface::qt_metacast
+32 QDesignerBrushManagerInterface::qt_metacall
+40 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+48 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+
+Class QDesignerBrushManagerInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerBrushManagerInterface (0x7f09f281e700) 0
+ vptr=((& QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface) + 16u)
+ QObject (0x7f09f281e770) 0
+ primary-for QDesignerBrushManagerInterface (0x7f09f281e700)
+
+Vtable for QDesignerDnDItemInterface
+QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QDesignerDnDItemInterface)
+16 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+24 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerDnDItemInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerDnDItemInterface (0x7f09f2832cb0) 0 nearly-empty
+ vptr=((& QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface) + 16u)
+
+Vtable for QDesignerFormWindowManagerInterface
+QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI35QDesignerFormWindowManagerInterface)
+16 QDesignerFormWindowManagerInterface::metaObject
+24 QDesignerFormWindowManagerInterface::qt_metacast
+32 QDesignerFormWindowManagerInterface::qt_metacall
+40 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+48 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QDesignerFormWindowManagerInterface::actionCut
+120 QDesignerFormWindowManagerInterface::actionCopy
+128 QDesignerFormWindowManagerInterface::actionPaste
+136 QDesignerFormWindowManagerInterface::actionDelete
+144 QDesignerFormWindowManagerInterface::actionSelectAll
+152 QDesignerFormWindowManagerInterface::actionLower
+160 QDesignerFormWindowManagerInterface::actionRaise
+168 QDesignerFormWindowManagerInterface::actionUndo
+176 QDesignerFormWindowManagerInterface::actionRedo
+184 QDesignerFormWindowManagerInterface::actionHorizontalLayout
+192 QDesignerFormWindowManagerInterface::actionVerticalLayout
+200 QDesignerFormWindowManagerInterface::actionSplitHorizontal
+208 QDesignerFormWindowManagerInterface::actionSplitVertical
+216 QDesignerFormWindowManagerInterface::actionGridLayout
+224 QDesignerFormWindowManagerInterface::actionBreakLayout
+232 QDesignerFormWindowManagerInterface::actionAdjustSize
+240 QDesignerFormWindowManagerInterface::activeFormWindow
+248 QDesignerFormWindowManagerInterface::formWindowCount
+256 QDesignerFormWindowManagerInterface::formWindow
+264 QDesignerFormWindowManagerInterface::createFormWindow
+272 QDesignerFormWindowManagerInterface::core
+280 __cxa_pure_virtual
+288 QDesignerFormWindowManagerInterface::addFormWindow
+296 QDesignerFormWindowManagerInterface::removeFormWindow
+304 QDesignerFormWindowManagerInterface::setActiveFormWindow
+
+Class QDesignerFormWindowManagerInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerFormWindowManagerInterface (0x7f09f283dc40) 0
+ vptr=((& QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface) + 16u)
+ QObject (0x7f09f283dcb0) 0
+ primary-for QDesignerFormWindowManagerInterface (0x7f09f283dc40)
+
+Vtable for QDesignerLanguageExtension
+QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QDesignerLanguageExtension)
+16 QDesignerLanguageExtension::~QDesignerLanguageExtension
+24 QDesignerLanguageExtension::~QDesignerLanguageExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+
+Class QDesignerLanguageExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerLanguageExtension (0x7f09f285f000) 0 nearly-empty
+ vptr=((& QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension) + 16u)
+
+Vtable for QAbstractFormBuilder
+QAbstractFormBuilder::_ZTV20QAbstractFormBuilder: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QAbstractFormBuilder)
+16 QAbstractFormBuilder::~QAbstractFormBuilder
+24 QAbstractFormBuilder::~QAbstractFormBuilder
+32 QAbstractFormBuilder::load
+40 QAbstractFormBuilder::save
+48 QAbstractFormBuilder::loadExtraInfo
+56 QAbstractFormBuilder::create
+64 QAbstractFormBuilder::create
+72 QAbstractFormBuilder::create
+80 QAbstractFormBuilder::create
+88 QAbstractFormBuilder::create
+96 QAbstractFormBuilder::create
+104 QAbstractFormBuilder::addMenuAction
+112 QAbstractFormBuilder::applyProperties
+120 QAbstractFormBuilder::applyTabStops
+128 QAbstractFormBuilder::createWidget
+136 QAbstractFormBuilder::createLayout
+144 QAbstractFormBuilder::createAction
+152 QAbstractFormBuilder::createActionGroup
+160 QAbstractFormBuilder::createCustomWidgets
+168 QAbstractFormBuilder::createConnections
+176 QAbstractFormBuilder::createResources
+184 QAbstractFormBuilder::addItem
+192 QAbstractFormBuilder::addItem
+200 QAbstractFormBuilder::saveExtraInfo
+208 QAbstractFormBuilder::saveDom
+216 QAbstractFormBuilder::createActionRefDom
+224 QAbstractFormBuilder::createDom
+232 QAbstractFormBuilder::createDom
+240 QAbstractFormBuilder::createDom
+248 QAbstractFormBuilder::createDom
+256 QAbstractFormBuilder::createDom
+264 QAbstractFormBuilder::createDom
+272 QAbstractFormBuilder::saveConnections
+280 QAbstractFormBuilder::saveCustomWidgets
+288 QAbstractFormBuilder::saveTabStops
+296 QAbstractFormBuilder::saveResources
+304 QAbstractFormBuilder::computeProperties
+312 QAbstractFormBuilder::checkProperty
+320 QAbstractFormBuilder::createProperty
+328 QAbstractFormBuilder::layoutInfo
+336 QAbstractFormBuilder::nameToIcon
+344 QAbstractFormBuilder::iconToFilePath
+352 QAbstractFormBuilder::iconToQrcPath
+360 QAbstractFormBuilder::nameToPixmap
+368 QAbstractFormBuilder::pixmapToFilePath
+376 QAbstractFormBuilder::pixmapToQrcPath
+
+Class QAbstractFormBuilder
+ size=48 align=8
+ base size=48 base align=8
+QAbstractFormBuilder (0x7f09f286e690) 0
+ vptr=((& QAbstractFormBuilder::_ZTV20QAbstractFormBuilder) + 16u)
+
+Vtable for QFormBuilder
+QFormBuilder::_ZTV12QFormBuilder: 49u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QFormBuilder)
+16 QFormBuilder::~QFormBuilder
+24 QFormBuilder::~QFormBuilder
+32 QAbstractFormBuilder::load
+40 QAbstractFormBuilder::save
+48 QAbstractFormBuilder::loadExtraInfo
+56 QFormBuilder::create
+64 QFormBuilder::create
+72 QFormBuilder::create
+80 QFormBuilder::create
+88 QFormBuilder::create
+96 QFormBuilder::create
+104 QAbstractFormBuilder::addMenuAction
+112 QFormBuilder::applyProperties
+120 QAbstractFormBuilder::applyTabStops
+128 QFormBuilder::createWidget
+136 QFormBuilder::createLayout
+144 QAbstractFormBuilder::createAction
+152 QAbstractFormBuilder::createActionGroup
+160 QAbstractFormBuilder::createCustomWidgets
+168 QFormBuilder::createConnections
+176 QAbstractFormBuilder::createResources
+184 QFormBuilder::addItem
+192 QFormBuilder::addItem
+200 QAbstractFormBuilder::saveExtraInfo
+208 QAbstractFormBuilder::saveDom
+216 QAbstractFormBuilder::createActionRefDom
+224 QAbstractFormBuilder::createDom
+232 QAbstractFormBuilder::createDom
+240 QAbstractFormBuilder::createDom
+248 QAbstractFormBuilder::createDom
+256 QAbstractFormBuilder::createDom
+264 QAbstractFormBuilder::createDom
+272 QAbstractFormBuilder::saveConnections
+280 QAbstractFormBuilder::saveCustomWidgets
+288 QAbstractFormBuilder::saveTabStops
+296 QAbstractFormBuilder::saveResources
+304 QAbstractFormBuilder::computeProperties
+312 QAbstractFormBuilder::checkProperty
+320 QAbstractFormBuilder::createProperty
+328 QAbstractFormBuilder::layoutInfo
+336 QAbstractFormBuilder::nameToIcon
+344 QAbstractFormBuilder::iconToFilePath
+352 QAbstractFormBuilder::iconToQrcPath
+360 QAbstractFormBuilder::nameToPixmap
+368 QAbstractFormBuilder::pixmapToFilePath
+376 QAbstractFormBuilder::pixmapToQrcPath
+384 QFormBuilder::updateCustomWidgets
+
+Class QFormBuilder
+ size=64 align=8
+ base size=64 base align=8
+QFormBuilder (0x7f09f26baaf0) 0
+ vptr=((& QFormBuilder::_ZTV12QFormBuilder) + 16u)
+ QAbstractFormBuilder (0x7f09f26bab60) 0
+ primary-for QFormBuilder (0x7f09f26baaf0)
+
+Vtable for QDesignerCustomWidgetInterface
+QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QDesignerCustomWidgetInterface)
+16 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+24 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 QDesignerCustomWidgetInterface::isInitialized
+104 QDesignerCustomWidgetInterface::initialize
+112 QDesignerCustomWidgetInterface::domXml
+120 QDesignerCustomWidgetInterface::codeTemplate
+
+Class QDesignerCustomWidgetInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerCustomWidgetInterface (0x7f09f26baee0) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface) + 16u)
+
+Vtable for QDesignerCustomWidgetCollectionInterface
+QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI40QDesignerCustomWidgetCollectionInterface)
+16 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+24 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+32 __cxa_pure_virtual
+
+Class QDesignerCustomWidgetCollectionInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerCustomWidgetCollectionInterface (0x7f09f27309a0) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface) + 16u)
+
+Vtable for QDesignerContainerExtension
+QDesignerContainerExtension::_ZTV27QDesignerContainerExtension: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerContainerExtension)
+16 QDesignerContainerExtension::~QDesignerContainerExtension
+24 QDesignerContainerExtension::~QDesignerContainerExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerContainerExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerContainerExtension (0x7f09f2740a80) 0 nearly-empty
+ vptr=((& QDesignerContainerExtension::_ZTV27QDesignerContainerExtension) + 16u)
+
+Vtable for QExtensionManager
+QExtensionManager::_ZTV17QExtensionManager: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QExtensionManager)
+16 QExtensionManager::metaObject
+24 QExtensionManager::qt_metacast
+32 QExtensionManager::qt_metacall
+40 QExtensionManager::~QExtensionManager
+48 QExtensionManager::~QExtensionManager
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QExtensionManager::registerExtensions
+120 QExtensionManager::unregisterExtensions
+128 QExtensionManager::extension
+136 (int (*)(...))-0x00000000000000010
+144 (int (*)(...))(& _ZTI17QExtensionManager)
+152 QExtensionManager::_ZThn16_N17QExtensionManagerD1Ev
+160 QExtensionManager::_ZThn16_N17QExtensionManagerD0Ev
+168 QExtensionManager::_ZThn16_N17QExtensionManager18registerExtensionsEP25QAbstractExtensionFactoryRK7QString
+176 QExtensionManager::_ZThn16_N17QExtensionManager20unregisterExtensionsEP25QAbstractExtensionFactoryRK7QString
+184 QExtensionManager::_ZThn16_NK17QExtensionManager9extensionEP7QObjectRK7QString
+
+Class QExtensionManager
+ size=40 align=8
+ base size=40 base align=8
+QExtensionManager (0x7f09f274fc80) 0
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 16u)
+ QObject (0x7f09f2759150) 0
+ primary-for QExtensionManager (0x7f09f274fc80)
+ QAbstractExtensionManager (0x7f09f27591c0) 16 nearly-empty
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 152u)
+
diff --git a/tests/auto/bic/data/QtDesigner.4.5.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtDesigner.4.5.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..2b75c25df
--- /dev/null
+++ b/tests/auto/bic/data/QtDesigner.4.5.0.linux-gcc-ia32.txt
@@ -0,0 +1,4460 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb6fd4bb8) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb6fd4d5c) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb65f4438) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb65f44ec) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb65f4d20) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0xb65f4e4c) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb6632ce4) 0 empty
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb6632d20) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb6538200) 0
+ QGenericArgument (0xb6632f3c) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb65400b4) 0
+
+Class QMetaObjectExtraData
+ size=8 align=4
+ base size=8 base align=4
+QMetaObjectExtraData (0xb65401e0) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb65403c0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb65405a0) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0xb658ace4) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0xb65b1800) 0
+ QBasicAtomicInt (0xb65a73fc) 0
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb65a78e8) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb65a7d5c) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb65a7d20) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb642cc30) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb64774ec) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb6477528) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb64774b0) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb6342078) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb6387d5c) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb624a0c0) 0
+ QString (0xb62454b0) 0
+
+Class QStringRef
+ size=12 align=4
+ base size=12 base align=4
+QStringRef (0xb62458e8) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb628799c) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::bad_exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb62baf00) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb6287a8c) 0 nearly-empty
+ primary-for std::bad_exception (0xb62baf00)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb62d1080) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb6287ce4) 0 nearly-empty
+ primary-for std::bad_alloc (0xb62d1080)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb6287f3c) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb62da03c) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb62da000) 0
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=24 align=4
+ base size=24 base align=4
+QObjectData (0xb62da7bc) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb62da870) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb61b20b4) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb61ac640) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb61b21e0) 0
+ primary-for QIODevice (0xb61ac640)
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb61b2f3c) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb6002ac8) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb6002a8c) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb603c168) 0 empty
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb603c8ac) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb603c870) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSystemLocale)
+8 QSystemLocale::~QSystemLocale
+12 QSystemLocale::~QSystemLocale
+16 QSystemLocale::query
+20 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=4 align=4
+ base size=4 base align=4
+QSystemLocale (0xb603cbb8) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 8u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0xb603cc30) 0
+
+Class QLocale
+ size=4 align=4
+ base size=4 base align=4
+QLocale (0xb603cbf4) 0
+
+Class QTextCodec::ConverterState
+ size=28 align=4
+ base size=28 base align=4
+QTextCodec::ConverterState (0xb5fb5294) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTextCodec)
+8 __cxa_pure_virtual
+12 QTextCodec::aliases
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QTextCodec::~QTextCodec
+32 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=4 align=4
+ base size=4 base align=4
+QTextCodec (0xb5fb5258) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 8u)
+
+Class QTextEncoder
+ size=32 align=4
+ base size=32 base align=4
+QTextEncoder (0xb5fb5e88) 0
+
+Class QTextDecoder
+ size=32 align=4
+ base size=32 base align=4
+QTextDecoder (0xb5dff0f0) 0
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb5dff474) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb5dff4b0) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTextStream)
+8 QTextStream::~QTextStream
+12 QTextStream::~QTextStream
+
+Class QTextStream
+ size=8 align=4
+ base size=8 base align=4
+QTextStream (0xb5dff528) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 8u)
+
+Class QTextStreamManipulator
+ size=24 align=4
+ base size=22 base align=4
+QTextStreamManipulator (0xb5dffb04) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextIStream)
+8 QTextIStream::~QTextIStream
+12 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=8 align=4
+ base size=8 base align=4
+QTextIStream (0xb5e45b80) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 8u)
+ QTextStream (0xb5e63c30) 0
+ primary-for QTextIStream (0xb5e45b80)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextOStream)
+8 QTextOStream::~QTextOStream
+12 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=8 align=4
+ base size=8 base align=4
+QTextOStream (0xb5e45e40) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 8u)
+ QTextStream (0xb5e762d0) 0
+ primary-for QTextOStream (0xb5e45e40)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb5e76960) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb5e76b04) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb5e76b40) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb5e76bf4) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb5e76f00) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb5e76f3c) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb5e76f78) 0
+
+Class QDebug::Stream
+ size=24 align=4
+ base size=22 base align=4
+QDebug::Stream (0xb5eac2d0) 0
+
+Class QDebug
+ size=4 align=4
+ base size=4 base align=4
+QDebug (0xb5eac294) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0xb5d88d98) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb5db1580) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb5db15c0) 0
+ primary-for QFile (0xb5db1580)
+ QObject (0xb5dc003c) 0
+ primary-for QIODevice (0xb5db15c0)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QTemporaryFile)
+8 QTemporaryFile::metaObject
+12 QTemporaryFile::qt_metacast
+16 QTemporaryFile::qt_metacall
+20 QTemporaryFile::~QTemporaryFile
+24 QTemporaryFile::~QTemporaryFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QTemporaryFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=8 align=4
+ base size=8 base align=4
+QTemporaryFile (0xb5db1b80) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 8u)
+ QFile (0xb5db1bc0) 0
+ primary-for QTemporaryFile (0xb5db1b80)
+ QIODevice (0xb5db1c00) 0
+ primary-for QFile (0xb5db1bc0)
+ QObject (0xb5dc04b0) 0
+ primary-for QIODevice (0xb5db1c00)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb5dc07bc) 0
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb5dc0d5c) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb5c59708) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb5c0ed00) 0
+ QList<QString> (0xb5c59870) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb5c89dd4) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0xb5ad84b0) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0xb5ad84ec) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=20 align=4
+ base size=20 base align=4
+QAbstractFileEngine::MapExtensionOption (0xb5add5c0) 0
+ QAbstractFileEngine::ExtensionOption (0xb5ad8528) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::MapExtensionReturn (0xb5add640) 0
+ QAbstractFileEngine::ExtensionReturn (0xb5ad8564) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::UnMapExtensionOption (0xb5add6c0) 0
+ QAbstractFileEngine::ExtensionOption (0xb5ad85a0) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+8 QAbstractFileEngine::~QAbstractFileEngine
+12 QAbstractFileEngine::~QAbstractFileEngine
+16 QAbstractFileEngine::open
+20 QAbstractFileEngine::close
+24 QAbstractFileEngine::flush
+28 QAbstractFileEngine::size
+32 QAbstractFileEngine::pos
+36 QAbstractFileEngine::seek
+40 QAbstractFileEngine::isSequential
+44 QAbstractFileEngine::remove
+48 QAbstractFileEngine::copy
+52 QAbstractFileEngine::rename
+56 QAbstractFileEngine::link
+60 QAbstractFileEngine::mkdir
+64 QAbstractFileEngine::rmdir
+68 QAbstractFileEngine::setSize
+72 QAbstractFileEngine::caseSensitive
+76 QAbstractFileEngine::isRelativePath
+80 QAbstractFileEngine::entryList
+84 QAbstractFileEngine::fileFlags
+88 QAbstractFileEngine::setPermissions
+92 QAbstractFileEngine::fileName
+96 QAbstractFileEngine::ownerId
+100 QAbstractFileEngine::owner
+104 QAbstractFileEngine::fileTime
+108 QAbstractFileEngine::setFileName
+112 QAbstractFileEngine::handle
+116 QAbstractFileEngine::beginEntryList
+120 QAbstractFileEngine::endEntryList
+124 QAbstractFileEngine::read
+128 QAbstractFileEngine::readLine
+132 QAbstractFileEngine::write
+136 QAbstractFileEngine::extension
+140 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngine (0xb5ad8474) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 8u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+8 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+12 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+16 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngineHandler (0xb5ad8744) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 8u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+8 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+12 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QAbstractFileEngineIterator::currentFileInfo
+32 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngineIterator (0xb5ad8780) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 8u)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QFSFileEngine)
+8 QFSFileEngine::~QFSFileEngine
+12 QFSFileEngine::~QFSFileEngine
+16 QFSFileEngine::open
+20 QFSFileEngine::close
+24 QFSFileEngine::flush
+28 QFSFileEngine::size
+32 QFSFileEngine::pos
+36 QFSFileEngine::seek
+40 QFSFileEngine::isSequential
+44 QFSFileEngine::remove
+48 QFSFileEngine::copy
+52 QFSFileEngine::rename
+56 QFSFileEngine::link
+60 QFSFileEngine::mkdir
+64 QFSFileEngine::rmdir
+68 QFSFileEngine::setSize
+72 QFSFileEngine::caseSensitive
+76 QFSFileEngine::isRelativePath
+80 QFSFileEngine::entryList
+84 QFSFileEngine::fileFlags
+88 QFSFileEngine::setPermissions
+92 QFSFileEngine::fileName
+96 QFSFileEngine::ownerId
+100 QFSFileEngine::owner
+104 QFSFileEngine::fileTime
+108 QFSFileEngine::setFileName
+112 QFSFileEngine::handle
+116 QFSFileEngine::beginEntryList
+120 QFSFileEngine::endEntryList
+124 QFSFileEngine::read
+128 QFSFileEngine::readLine
+132 QFSFileEngine::write
+136 QFSFileEngine::extension
+140 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QFSFileEngine (0xb5add9c0) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 8u)
+ QAbstractFileEngine (0xb5ad87bc) 0
+ primary-for QFSFileEngine (0xb5add9c0)
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QProcess)
+8 QProcess::metaObject
+12 QProcess::qt_metacast
+16 QProcess::qt_metacall
+20 QProcess::~QProcess
+24 QProcess::~QProcess
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QProcess::isSequential
+60 QIODevice::open
+64 QProcess::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QProcess::atEnd
+84 QIODevice::reset
+88 QProcess::bytesAvailable
+92 QProcess::bytesToWrite
+96 QProcess::canReadLine
+100 QProcess::waitForReadyRead
+104 QProcess::waitForBytesWritten
+108 QProcess::readData
+112 QIODevice::readLineData
+116 QProcess::writeData
+120 QProcess::setupChildProcess
+
+Class QProcess
+ size=8 align=4
+ base size=8 base align=4
+QProcess (0xb5addac0) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 8u)
+ QIODevice (0xb5addb00) 0
+ primary-for QProcess (0xb5addac0)
+ QObject (0xb5ad88e8) 0
+ primary-for QIODevice (0xb5addb00)
+
+Class QResource
+ size=4 align=4
+ base size=4 base align=4
+QResource (0xb5ad8b04) 0
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QDirIterator)
+8 QDirIterator::~QDirIterator
+12 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=8 align=4
+ base size=8 base align=4
+QDirIterator (0xb5ad8bf4) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 8u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QBuffer)
+8 QBuffer::metaObject
+12 QBuffer::qt_metacast
+16 QBuffer::qt_metacall
+20 QBuffer::~QBuffer
+24 QBuffer::~QBuffer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QBuffer::connectNotify
+52 QBuffer::disconnectNotify
+56 QIODevice::isSequential
+60 QBuffer::open
+64 QBuffer::close
+68 QBuffer::pos
+72 QBuffer::size
+76 QBuffer::seek
+80 QBuffer::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QBuffer::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QBuffer::readData
+112 QIODevice::readLineData
+116 QBuffer::writeData
+
+Class QBuffer
+ size=8 align=4
+ base size=8 base align=4
+QBuffer (0xb5b74080) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 8u)
+ QIODevice (0xb5b740c0) 0
+ primary-for QBuffer (0xb5b74080)
+ QObject (0xb5ad8d20) 0
+ primary-for QIODevice (0xb5b740c0)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+8 QFileSystemWatcher::metaObject
+12 QFileSystemWatcher::qt_metacast
+16 QFileSystemWatcher::qt_metacall
+20 QFileSystemWatcher::~QFileSystemWatcher
+24 QFileSystemWatcher::~QFileSystemWatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=8 align=4
+ base size=8 base align=4
+QFileSystemWatcher (0xb5b743c0) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 8u)
+ QObject (0xb5ad8f3c) 0
+ primary-for QFileSystemWatcher (0xb5b743c0)
+
+Class QUrl
+ size=4 align=4
+ base size=4 base align=4
+QUrl (0xb5b8e168) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb5b8e744) 0 empty
+
+Class QVariant::PrivateShared
+ size=8 align=4
+ base size=8 base align=4
+QVariant::PrivateShared (0xb5a2d1a4) 0
+
+Class QVariant::Private::Data
+ size=8 align=4
+ base size=8 base align=4
+QVariant::Private::Data (0xb5a2d21c) 0
+
+Class QVariant::Private
+ size=12 align=4
+ base size=12 base align=4
+QVariant::Private (0xb5a2d1e0) 0
+
+Class QVariant::Handler
+ size=36 align=4
+ base size=36 base align=4
+QVariant::Handler (0xb5a2d258) 0
+
+Class QVariant
+ size=12 align=4
+ base size=12 base align=4
+QVariant (0xb5a2d168) 0
+
+Class QVariantComparisonHelper
+ size=4 align=4
+ base size=4 base align=4
+QVariantComparisonHelper (0xb5a6e834) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QSettings)
+8 QSettings::metaObject
+12 QSettings::qt_metacast
+16 QSettings::qt_metacall
+20 QSettings::~QSettings
+24 QSettings::~QSettings
+28 QSettings::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSettings
+ size=8 align=4
+ base size=8 base align=4
+QSettings (0xb5aa5ec0) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 8u)
+ QObject (0xb5a6ece4) 0
+ primary-for QSettings (0xb5aa5ec0)
+
+Class QXmlStreamStringRef
+ size=12 align=4
+ base size=12 base align=4
+QXmlStreamStringRef (0xb58f17f8) 0
+
+Class QXmlStreamAttribute
+ size=56 align=4
+ base size=53 base align=4
+QXmlStreamAttribute (0xb59134b0) 0
+
+Class QXmlStreamAttributes
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamAttributes (0xb591e3c0) 0
+ QVector<QXmlStreamAttribute> (0xb5913f00) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=28 align=4
+ base size=28 base align=4
+QXmlStreamNamespaceDeclaration (0xb5946000) 0
+
+Class QXmlStreamNotationDeclaration
+ size=40 align=4
+ base size=40 base align=4
+QXmlStreamNotationDeclaration (0xb5946474) 0
+
+Class QXmlStreamEntityDeclaration
+ size=64 align=4
+ base size=64 base align=4
+QXmlStreamEntityDeclaration (0xb5946a50) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+8 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+12 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+16 QXmlStreamEntityResolver::resolveEntity
+20 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamEntityResolver (0xb596f30c) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 8u)
+
+Class QXmlStreamReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamReader (0xb596f348) 0
+
+Class QXmlStreamWriter
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamWriter (0xb596f3fc) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb596f528) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb59c7ac8) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb57ed1e0) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb57edf00) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb5841000) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb5858a8c) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb5884690) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb56e62d0) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0xb573f03c) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+8 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+12 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+16 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=12 align=4
+ base size=12 base align=4
+QtSharedPointer::ExternalRefCountData (0xb573f30c) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 8u)
+
+Class QLinkedListData
+ size=20 align=4
+ base size=20 base align=4
+QLinkedListData (0xb573fc30) 0
+
+Class QBitArray
+ size=4 align=4
+ base size=4 base align=4
+QBitArray (0xb573fe4c) 0
+
+Class QBitRef
+ size=8 align=4
+ base size=8 base align=4
+QBitRef (0xb564c384) 0
+
+Class QByteArrayMatcher
+ size=1032 align=4
+ base size=1032 base align=4
+QByteArrayMatcher (0xb564ca50) 0
+
+Class QCryptographicHash
+ size=4 align=4
+ base size=4 base align=4
+QCryptographicHash (0xb564cc30) 0
+
+Class QTextBoundaryFinder
+ size=28 align=4
+ base size=28 base align=4
+QTextBoundaryFinder (0xb564cca8) 0
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0xb564cd5c) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0xb56a0384) 0
+
+Class QDateTime
+ size=4 align=4
+ base size=4 base align=4
+QDateTime (0xb56a08e8) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTimeLine)
+8 QTimeLine::metaObject
+12 QTimeLine::qt_metacast
+16 QTimeLine::qt_metacall
+20 QTimeLine::~QTimeLine
+24 QTimeLine::~QTimeLine
+28 QObject::event
+32 QObject::eventFilter
+36 QTimeLine::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=8 align=4
+ base size=8 base align=4
+QTimeLine (0xb56c9400) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 8u)
+ QObject (0xb56a0b7c) 0
+ primary-for QTimeLine (0xb56c9400)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QRunnable)
+8 __cxa_pure_virtual
+12 QRunnable::~QRunnable
+16 QRunnable::~QRunnable
+
+Class QRunnable
+ size=8 align=4
+ base size=8 base align=4
+QRunnable (0xb56a0d98) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 8u)
+
+Class QMutex
+ size=4 align=4
+ base size=4 base align=4
+QMutex (0xb54e821c) 0
+
+Class QMutexLocker
+ size=4 align=4
+ base size=4 base align=4
+QMutexLocker (0xb54e88ac) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+8 QtConcurrent::Exception::~Exception
+12 QtConcurrent::Exception::~Exception
+16 std::exception::what
+20 QtConcurrent::Exception::raise
+24 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::Exception (0xb54fd380) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 8u)
+ std::exception (0xb54e8d98) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb54fd380)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+8 QtConcurrent::UnhandledException::~UnhandledException
+12 QtConcurrent::UnhandledException::~UnhandledException
+16 std::exception::what
+20 QtConcurrent::UnhandledException::raise
+24 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::UnhandledException (0xb54fd480) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 8u)
+ QtConcurrent::Exception (0xb54fd4c0) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0xb54fd480)
+ std::exception (0xb54e8dd4) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb54fd4c0)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionHolder (0xb54e8e10) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionStore (0xb54e8e4c) 0
+
+Class QtConcurrent::ResultItem
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultItem (0xb54e8e88) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultIteratorBase (0xb5508474) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+8 QtConcurrent::ResultStoreBase::~ResultStoreBase
+12 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=28 align=4
+ base size=28 base align=4
+QtConcurrent::ResultStoreBase (0xb55085a0) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 8u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+8 QFutureInterfaceBase::~QFutureInterfaceBase
+12 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureInterfaceBase (0xb55089d8) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 8u)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QThread)
+8 QThread::metaObject
+12 QThread::qt_metacast
+16 QThread::qt_metacall
+20 QThread::~QThread
+24 QThread::~QThread
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QThread::run
+
+Class QThread
+ size=8 align=4
+ base size=8 base align=4
+QThread (0xb55ae4c0) 0
+ vptr=((& QThread::_ZTV7QThread) + 8u)
+ QObject (0xb55a36cc) 0
+ primary-for QThread (0xb55ae4c0)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QThreadPool)
+8 QThreadPool::metaObject
+12 QThreadPool::qt_metacast
+16 QThreadPool::qt_metacall
+20 QThreadPool::~QThreadPool
+24 QThreadPool::~QThreadPool
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QThreadPool
+ size=8 align=4
+ base size=8 base align=4
+QThreadPool (0xb55ae800) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 8u)
+ QObject (0xb55a3960) 0
+ primary-for QThreadPool (0xb55ae800)
+
+Class QWaitCondition
+ size=4 align=4
+ base size=4 base align=4
+QWaitCondition (0xb55a3bb8) 0
+
+Class QtConcurrent::ThreadEngineSemaphore
+ size=12 align=4
+ base size=12 base align=4
+QtConcurrent::ThreadEngineSemaphore (0xb55a3bf4) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+8 QtConcurrent::ThreadEngineBase::run
+12 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+16 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+20 QtConcurrent::ThreadEngineBase::start
+24 QtConcurrent::ThreadEngineBase::finish
+28 QtConcurrent::ThreadEngineBase::threadFunction
+32 QtConcurrent::ThreadEngineBase::shouldStartThread
+36 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+40 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=32 align=4
+ base size=32 base align=4
+QtConcurrent::ThreadEngineBase (0xb53dc340) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 8u)
+ QRunnable (0xb53db474) 0
+ primary-for QtConcurrent::ThreadEngineBase (0xb53dc340)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 12u)
+4 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 68u)
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0xb53ffa50) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0xb53ffa8c) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0xb53fb900) 0 empty
+ std::input_iterator_tag (0xb53ffac8) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0xb53fb980) 0 empty
+ std::forward_iterator_tag (0xb53fb9c0) 0 empty
+ std::input_iterator_tag (0xb53ffb04) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0xb53fba40) 0 empty
+ std::bidirectional_iterator_tag (0xb53fba80) 0 empty
+ std::forward_iterator_tag (0xb53fbac0) 0 empty
+ std::input_iterator_tag (0xb53ffb40) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0xb53ffc6c) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0xb53ffca8) 0 empty
+
+Class lconv
+ size=56 align=4
+ base size=56 base align=4
+lconv (0xb54bfe88) 0
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0xb531303c) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0xb5313078) 0
+
+Class tm
+ size=44 align=4
+ base size=44 base align=4
+tm (0xb53130f0) 0
+
+Class itimerspec
+ size=16 align=4
+ base size=16 base align=4
+itimerspec (0xb531312c) 0
+
+Class _pthread_cleanup_buffer
+ size=16 align=4
+ base size=16 base align=4
+_pthread_cleanup_buffer (0xb5313168) 0
+
+Class __pthread_cleanup_frame
+ size=16 align=4
+ base size=16 base align=4
+__pthread_cleanup_frame (0xb531321c) 0
+
+Class __pthread_cleanup_class
+ size=16 align=4
+ base size=16 base align=4
+__pthread_cleanup_class (0xb5313258) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+8 __cxxabiv1::__forced_unwind::~__forced_unwind
+12 __cxxabiv1::__forced_unwind::~__forced_unwind
+16 __cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=4 align=4
+ base size=4 base align=4
+__cxxabiv1::__forced_unwind (0xb5394564) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 8u)
+
+Class std::locale
+ size=4 align=4
+ base size=4 base align=4
+std::locale (0xb51fa99c) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTINSt6locale5facetE)
+8 std::locale::facet::~facet
+12 std::locale::facet::~facet
+
+Class std::locale::facet
+ size=8 align=4
+ base size=8 base align=4
+std::locale::facet (0xb51faa14) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 8u)
+
+Class std::locale::id
+ size=4 align=4
+ base size=4 base align=4
+std::locale::id (0xb51fae10) 0
+
+Class std::locale::_Impl
+ size=20 align=4
+ base size=20 base align=4
+std::locale::_Impl (0xb51fae4c) 0
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTINSt8ios_base7failureE)
+8 std::ios_base::failure::~failure
+12 std::ios_base::failure::~failure
+16 std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=8 align=4
+ base size=8 base align=4
+std::ios_base::failure (0xb51aae00) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureE) + 8u)
+ std::exception (0xb51c21a4) 0 nearly-empty
+ primary-for std::ios_base::failure (0xb51aae00)
+
+Class std::ios_base::_Callback_list
+ size=16 align=4
+ base size=16 base align=4
+std::ios_base::_Callback_list (0xb51c21e0) 0
+
+Class std::ios_base::_Words
+ size=8 align=4
+ base size=8 base align=4
+std::ios_base::_Words (0xb51c221c) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0xb51c2258) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt8ios_base)
+8 std::ios_base::~ios_base
+12 std::ios_base::~ios_base
+
+Class std::ios_base
+ size=112 align=4
+ base size=112 base align=4
+std::ios_base (0xb51c2168) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 8u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0xb4fe65a0) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0xb50ab078) 0 empty
+
+VTT for std::basic_ostream<char, std::char_traits<char> >
+std::basic_ostream<char, std::char_traits<char> >::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 12u)
+4 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 32u)
+
+VTT for std::basic_ostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 32u)
+
+VTT for std::basic_istream<char, std::char_traits<char> >
+std::basic_istream<char, std::char_traits<char> >::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 12u)
+4 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 32u)
+
+VTT for std::basic_istream<wchar_t, std::char_traits<wchar_t> >
+std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 32u)
+
+Construction vtable for std::basic_istream<char, std::char_traits<char> > (0xb4e62840 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si: 10u entries
+0 12u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISi)
+12 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+16 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+20 -12u
+24 (int (*)(...))-0x00000000c
+28 (int (*)(...))(& _ZTISi)
+32 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n12_NSiD1Ev
+36 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n12_NSiD0Ev
+
+Construction vtable for std::basic_ostream<char, std::char_traits<char> > (0xb4e628c0 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So: 10u entries
+0 4u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISo)
+12 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+16 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+20 -4u
+24 (int (*)(...))-0x000000004
+28 (int (*)(...))(& _ZTISo)
+32 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n12_NSoD1Ev
+36 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n12_NSoD0Ev
+
+VTT for std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 12u)
+4 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 12u)
+8 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 32u)
+12 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So) + 12u)
+16 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So) + 32u)
+20 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 52u)
+24 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 32u)
+
+Construction vtable for std::basic_istream<wchar_t, std::char_traits<wchar_t> > (0xb4e62bc0 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 12u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+12 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+16 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+20 -12u
+24 (int (*)(...))-0x00000000c
+28 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+32 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED1Ev
+36 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED0Ev
+
+Construction vtable for std::basic_ostream<wchar_t, std::char_traits<wchar_t> > (0xb4e62c40 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E: 10u entries
+0 4u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+12 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+16 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+20 -4u
+24 (int (*)(...))-0x000000004
+28 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+32 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev
+36 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev
+
+VTT for std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 12u)
+8 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 32u)
+12 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E) + 12u)
+16 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E) + 32u)
+20 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 52u)
+24 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 32u)
+
+Class QtConcurrent::BlockSizeManager
+ size=72 align=4
+ base size=72 base align=4
+QtConcurrent::BlockSizeManager (0xb4e7412c) 0
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+8 QFutureWatcherBase::metaObject
+12 QFutureWatcherBase::qt_metacast
+16 QFutureWatcherBase::qt_metacall
+20 QFutureWatcherBase::~QFutureWatcherBase
+24 QFutureWatcherBase::~QFutureWatcherBase
+28 QFutureWatcherBase::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QFutureWatcherBase::connectNotify
+52 QFutureWatcherBase::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureWatcherBase (0xb4c7ce00) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 8u)
+ QObject (0xb4c32924) 0
+ primary-for QFutureWatcherBase (0xb4c7ce00)
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QFactoryInterface)
+8 QFactoryInterface::~QFactoryInterface
+12 QFactoryInterface::~QFactoryInterface
+16 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QFactoryInterface (0xb4af5744) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 8u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+8 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+12 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QTextCodecFactoryInterface (0xb4b33000) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 8u)
+ QFactoryInterface (0xb4af5c30) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4b33000)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+8 QTextCodecPlugin::metaObject
+12 QTextCodecPlugin::qt_metacast
+16 QTextCodecPlugin::qt_metacall
+20 QTextCodecPlugin::~QTextCodecPlugin
+24 QTextCodecPlugin::~QTextCodecPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 QTextCodecPlugin::keys
+80 QTextCodecPlugin::create
+84 (int (*)(...))-0x000000008
+88 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+92 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD1Ev
+96 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD0Ev
+100 QTextCodecPlugin::_ZThn8_NK16QTextCodecPlugin4keysEv
+104 QTextCodecPlugin::_ZThn8_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=12 align=4
+ base size=12 base align=4
+QTextCodecPlugin (0xb4b30f50) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 8u)
+ QObject (0xb4af5ec4) 0
+ primary-for QTextCodecPlugin (0xb4b30f50)
+ QTextCodecFactoryInterface (0xb4b33200) 8 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 92u)
+ QFactoryInterface (0xb4af5f00) 8 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4b33200)
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0xb4b4303c) 0 empty
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTranslator)
+8 QTranslator::metaObject
+12 QTranslator::qt_metacast
+16 QTranslator::qt_metacall
+20 QTranslator::~QTranslator
+24 QTranslator::~QTranslator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTranslator::translate
+60 QTranslator::isEmpty
+
+Class QTranslator
+ size=8 align=4
+ base size=8 base align=4
+QTranslator (0xb4b5adc0) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 8u)
+ QObject (0xb4b563fc) 0
+ primary-for QTranslator (0xb4b5adc0)
+
+Class __exception
+ size=32 align=4
+ base size=32 base align=4
+__exception (0xb4b566cc) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QMimeData)
+8 QMimeData::metaObject
+12 QMimeData::qt_metacast
+16 QMimeData::qt_metacall
+20 QMimeData::~QMimeData
+24 QMimeData::~QMimeData
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QMimeData::hasFormat
+60 QMimeData::formats
+64 QMimeData::retrieveData
+
+Class QMimeData
+ size=8 align=4
+ base size=8 base align=4
+QMimeData (0xb4b72740) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 8u)
+ QObject (0xb4b56c6c) 0
+ primary-for QMimeData (0xb4b72740)
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QEventLoop)
+8 QEventLoop::metaObject
+12 QEventLoop::qt_metacast
+16 QEventLoop::qt_metacall
+20 QEventLoop::~QEventLoop
+24 QEventLoop::~QEventLoop
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QEventLoop
+ size=8 align=4
+ base size=8 base align=4
+QEventLoop (0xb4b72a00) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 8u)
+ QObject (0xb4b56e88) 0
+ primary-for QEventLoop (0xb4b72a00)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QEvent)
+8 QEvent::~QEvent
+12 QEvent::~QEvent
+
+Class QEvent
+ size=12 align=4
+ base size=12 base align=4
+QEvent (0xb49c91a4) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 8u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTimerEvent)
+8 QTimerEvent::~QTimerEvent
+12 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=16 align=4
+ base size=16 base align=4
+QTimerEvent (0xb49e80c0) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 8u)
+ QEvent (0xb49c9384) 0
+ primary-for QTimerEvent (0xb49e80c0)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QChildEvent)
+8 QChildEvent::~QChildEvent
+12 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=16 align=4
+ base size=16 base align=4
+QChildEvent (0xb49e8180) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 8u)
+ QEvent (0xb49c93fc) 0
+ primary-for QChildEvent (0xb49e8180)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QCustomEvent)
+8 QCustomEvent::~QCustomEvent
+12 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=12 align=4
+ base size=12 base align=4
+QCustomEvent (0xb49e8440) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 8u)
+ QEvent (0xb49c9564) 0
+ primary-for QCustomEvent (0xb49e8440)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+8 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+12 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=16 align=4
+ base size=16 base align=4
+QDynamicPropertyChangeEvent (0xb49e8540) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 8u)
+ QEvent (0xb49c9654) 0
+ primary-for QDynamicPropertyChangeEvent (0xb49e8540)
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QCoreApplication)
+8 QCoreApplication::metaObject
+12 QCoreApplication::qt_metacast
+16 QCoreApplication::qt_metacall
+20 QCoreApplication::~QCoreApplication
+24 QCoreApplication::~QCoreApplication
+28 QCoreApplication::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QCoreApplication::notify
+60 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=8 align=4
+ base size=8 base align=4
+QCoreApplication (0xb49e8600) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 8u)
+ QObject (0xb49c9708) 0
+ primary-for QCoreApplication (0xb49e8600)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSharedMemory)
+8 QSharedMemory::metaObject
+12 QSharedMemory::qt_metacast
+16 QSharedMemory::qt_metacall
+20 QSharedMemory::~QSharedMemory
+24 QSharedMemory::~QSharedMemory
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=8 align=4
+ base size=8 base align=4
+QSharedMemory (0xb49e8c00) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 8u)
+ QObject (0xb49c9ca8) 0
+ primary-for QSharedMemory (0xb49e8c00)
+
+Class QModelIndex
+ size=16 align=4
+ base size=16 base align=4
+QModelIndex (0xb49c9ec4) 0
+
+Class QPersistentModelIndex
+ size=4 align=4
+ base size=4 base align=4
+QPersistentModelIndex (0xb4a37384) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractItemModel)
+8 QAbstractItemModel::metaObject
+12 QAbstractItemModel::qt_metacast
+16 QAbstractItemModel::qt_metacall
+20 QAbstractItemModel::~QAbstractItemModel
+24 QAbstractItemModel::~QAbstractItemModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractItemModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemModel (0xb4a2c840) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 8u)
+ QObject (0xb4a374ec) 0
+ primary-for QAbstractItemModel (0xb4a2c840)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTableModel)
+8 QAbstractTableModel::metaObject
+12 QAbstractTableModel::qt_metacast
+16 QAbstractTableModel::qt_metacall
+20 QAbstractTableModel::~QAbstractTableModel
+24 QAbstractTableModel::~QAbstractTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractTableModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTableModel (0xb4a2ce80) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 8u)
+ QAbstractItemModel (0xb4a2cec0) 0
+ primary-for QAbstractTableModel (0xb4a2ce80)
+ QObject (0xb4a37e4c) 0
+ primary-for QAbstractItemModel (0xb4a2cec0)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractListModel)
+8 QAbstractListModel::metaObject
+12 QAbstractListModel::qt_metacast
+16 QAbstractListModel::qt_metacall
+20 QAbstractListModel::~QAbstractListModel
+24 QAbstractListModel::~QAbstractListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 __cxa_pure_virtual
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractListModel (0xb4a74100) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 8u)
+ QAbstractItemModel (0xb4a74140) 0
+ primary-for QAbstractListModel (0xb4a74100)
+ QObject (0xb4a37f78) 0
+ primary-for QAbstractItemModel (0xb4a74140)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSignalMapper)
+8 QSignalMapper::metaObject
+12 QSignalMapper::qt_metacast
+16 QSignalMapper::qt_metacall
+20 QSignalMapper::~QSignalMapper
+24 QSignalMapper::~QSignalMapper
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=8 align=4
+ base size=8 base align=4
+QSignalMapper (0xb4a74840) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 8u)
+ QObject (0xb4a83e4c) 0
+ primary-for QSignalMapper (0xb4a74840)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+8 QObjectCleanupHandler::metaObject
+12 QObjectCleanupHandler::qt_metacast
+16 QObjectCleanupHandler::qt_metacall
+20 QObjectCleanupHandler::~QObjectCleanupHandler
+24 QObjectCleanupHandler::~QObjectCleanupHandler
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=12 align=4
+ base size=12 base align=4
+QObjectCleanupHandler (0xb4a74b00) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 8u)
+ QObject (0xb4aa2078) 0
+ primary-for QObjectCleanupHandler (0xb4a74b00)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0xb4aa21a4) 0
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QSocketNotifier)
+8 QSocketNotifier::metaObject
+12 QSocketNotifier::qt_metacast
+16 QSocketNotifier::qt_metacall
+20 QSocketNotifier::~QSocketNotifier
+24 QSocketNotifier::~QSocketNotifier
+28 QSocketNotifier::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=20 align=4
+ base size=17 base align=4
+QSocketNotifier (0xb48b1100) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 8u)
+ QObject (0xb4aa2438) 0
+ primary-for QSocketNotifier (0xb48b1100)
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QTimer)
+8 QTimer::metaObject
+12 QTimer::qt_metacast
+16 QTimer::qt_metacall
+20 QTimer::~QTimer
+24 QTimer::~QTimer
+28 QObject::event
+32 QObject::eventFilter
+36 QTimer::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QTimer
+ size=24 align=4
+ base size=21 base align=4
+QTimer (0xb48b1480) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 8u)
+ QObject (0xb4aa2708) 0
+ primary-for QTimer (0xb48b1480)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+8 QAbstractEventDispatcher::metaObject
+12 QAbstractEventDispatcher::qt_metacast
+16 QAbstractEventDispatcher::qt_metacall
+20 QAbstractEventDispatcher::~QAbstractEventDispatcher
+24 QAbstractEventDispatcher::~QAbstractEventDispatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 QAbstractEventDispatcher::startingUp
+104 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=8 align=4
+ base size=8 base align=4
+QAbstractEventDispatcher (0xb48b1980) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 8u)
+ QObject (0xb4aa299c) 0
+ primary-for QAbstractEventDispatcher (0xb48b1980)
+
+Class QMetaMethod
+ size=8 align=4
+ base size=8 base align=4
+QMetaMethod (0xb4aa2bb8) 0
+
+Class QMetaEnum
+ size=8 align=4
+ base size=8 base align=4
+QMetaEnum (0xb4aa2ec4) 0
+
+Class QMetaProperty
+ size=20 align=4
+ base size=20 base align=4
+QMetaProperty (0xb48f512c) 0
+
+Class QMetaClassInfo
+ size=8 align=4
+ base size=8 base align=4
+QMetaClassInfo (0xb48f51e0) 0
+
+Class QSystemSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSystemSemaphore (0xb48f5438) 0
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QLibrary)
+8 QLibrary::metaObject
+12 QLibrary::qt_metacast
+16 QLibrary::qt_metacall
+20 QLibrary::~QLibrary
+24 QLibrary::~QLibrary
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QLibrary
+ size=16 align=4
+ base size=13 base align=4
+QLibrary (0xb48f6480) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 8u)
+ QObject (0xb48f54b0) 0
+ primary-for QLibrary (0xb48f6480)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QPluginLoader)
+8 QPluginLoader::metaObject
+12 QPluginLoader::qt_metacast
+16 QPluginLoader::qt_metacall
+20 QPluginLoader::~QPluginLoader
+24 QPluginLoader::~QPluginLoader
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=16 align=4
+ base size=13 base align=4
+QPluginLoader (0xb48f6880) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 8u)
+ QObject (0xb48f5708) 0
+ primary-for QPluginLoader (0xb48f6880)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0xb48f5834) 0
+
+Class QSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSemaphore (0xb4942834) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0xb4942870) 0
+
+Class QReadWriteLock
+ size=4 align=4
+ base size=4 base align=4
+QReadWriteLock (0xb49428e8) 0
+
+Class QReadLocker
+ size=4 align=4
+ base size=4 base align=4
+QReadLocker (0xb4942924) 0
+
+Class QWriteLocker
+ size=4 align=4
+ base size=4 base align=4
+QWriteLocker (0xb4942e10) 0
+
+Class QDomImplementation
+ size=4 align=4
+ base size=4 base align=4
+QDomImplementation (0xb497230c) 0
+
+Class QDomNode
+ size=4 align=4
+ base size=4 base align=4
+QDomNode (0xb4972348) 0
+
+Class QDomNodeList
+ size=4 align=4
+ base size=4 base align=4
+QDomNodeList (0xb4972384) 0
+
+Class QDomDocumentType
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentType (0xb496ba40) 0
+ QDomNode (0xb4972474) 0
+
+Class QDomDocument
+ size=4 align=4
+ base size=4 base align=4
+QDomDocument (0xb496bb00) 0
+ QDomNode (0xb49724ec) 0
+
+Class QDomNamedNodeMap
+ size=4 align=4
+ base size=4 base align=4
+QDomNamedNodeMap (0xb4972564) 0
+
+Class QDomDocumentFragment
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentFragment (0xb496bd00) 0
+ QDomNode (0xb4972618) 0
+
+Class QDomCharacterData
+ size=4 align=4
+ base size=4 base align=4
+QDomCharacterData (0xb496bdc0) 0
+ QDomNode (0xb4972690) 0
+
+Class QDomAttr
+ size=4 align=4
+ base size=4 base align=4
+QDomAttr (0xb496be40) 0
+ QDomNode (0xb49726cc) 0
+
+Class QDomElement
+ size=4 align=4
+ base size=4 base align=4
+QDomElement (0xb496bf00) 0
+ QDomNode (0xb4972744) 0
+
+Class QDomText
+ size=4 align=4
+ base size=4 base align=4
+QDomText (0xb47b50c0) 0
+ QDomCharacterData (0xb47b5100) 0
+ QDomNode (0xb49728ac) 0
+
+Class QDomComment
+ size=4 align=4
+ base size=4 base align=4
+QDomComment (0xb47b51c0) 0
+ QDomCharacterData (0xb47b5200) 0
+ QDomNode (0xb4972924) 0
+
+Class QDomCDATASection
+ size=4 align=4
+ base size=4 base align=4
+QDomCDATASection (0xb47b52c0) 0
+ QDomText (0xb47b5300) 0
+ QDomCharacterData (0xb47b5340) 0
+ QDomNode (0xb497299c) 0
+
+Class QDomNotation
+ size=4 align=4
+ base size=4 base align=4
+QDomNotation (0xb47b5400) 0
+ QDomNode (0xb4972a14) 0
+
+Class QDomEntity
+ size=4 align=4
+ base size=4 base align=4
+QDomEntity (0xb47b54c0) 0
+ QDomNode (0xb4972a8c) 0
+
+Class QDomEntityReference
+ size=4 align=4
+ base size=4 base align=4
+QDomEntityReference (0xb47b5580) 0
+ QDomNode (0xb4972b04) 0
+
+Class QDomProcessingInstruction
+ size=4 align=4
+ base size=4 base align=4
+QDomProcessingInstruction (0xb47b5640) 0
+ QDomNode (0xb4972b7c) 0
+
+Class QXmlNamespaceSupport
+ size=4 align=4
+ base size=4 base align=4
+QXmlNamespaceSupport (0xb4972bf4) 0
+
+Class QXmlAttributes::Attribute
+ size=16 align=4
+ base size=16 base align=4
+QXmlAttributes::Attribute (0xb4972c6c) 0
+
+Vtable for QXmlAttributes
+QXmlAttributes::_ZTV14QXmlAttributes: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlAttributes)
+8 QXmlAttributes::~QXmlAttributes
+12 QXmlAttributes::~QXmlAttributes
+
+Class QXmlAttributes
+ size=12 align=4
+ base size=12 base align=4
+QXmlAttributes (0xb4972c30) 0
+ vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 8u)
+
+Vtable for QXmlInputSource
+QXmlInputSource::_ZTV15QXmlInputSource: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlInputSource)
+8 QXmlInputSource::~QXmlInputSource
+12 QXmlInputSource::~QXmlInputSource
+16 QXmlInputSource::setData
+20 QXmlInputSource::setData
+24 QXmlInputSource::fetchData
+28 QXmlInputSource::data
+32 QXmlInputSource::next
+36 QXmlInputSource::reset
+40 QXmlInputSource::fromRawData
+
+Class QXmlInputSource
+ size=8 align=4
+ base size=8 base align=4
+QXmlInputSource (0xb47ed21c) 0
+ vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 8u)
+
+Class QXmlParseException
+ size=4 align=4
+ base size=4 base align=4
+QXmlParseException (0xb47ed258) 0
+
+Vtable for QXmlReader
+QXmlReader::_ZTV10QXmlReader: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QXmlReader)
+8 QXmlReader::~QXmlReader
+12 QXmlReader::~QXmlReader
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+
+Class QXmlReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlReader (0xb47ed294) 0 nearly-empty
+ vptr=((& QXmlReader::_ZTV10QXmlReader) + 8u)
+
+Vtable for QXmlSimpleReader
+QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlSimpleReader)
+8 QXmlSimpleReader::~QXmlSimpleReader
+12 QXmlSimpleReader::~QXmlSimpleReader
+16 QXmlSimpleReader::feature
+20 QXmlSimpleReader::setFeature
+24 QXmlSimpleReader::hasFeature
+28 QXmlSimpleReader::property
+32 QXmlSimpleReader::setProperty
+36 QXmlSimpleReader::hasProperty
+40 QXmlSimpleReader::setEntityResolver
+44 QXmlSimpleReader::entityResolver
+48 QXmlSimpleReader::setDTDHandler
+52 QXmlSimpleReader::DTDHandler
+56 QXmlSimpleReader::setContentHandler
+60 QXmlSimpleReader::contentHandler
+64 QXmlSimpleReader::setErrorHandler
+68 QXmlSimpleReader::errorHandler
+72 QXmlSimpleReader::setLexicalHandler
+76 QXmlSimpleReader::lexicalHandler
+80 QXmlSimpleReader::setDeclHandler
+84 QXmlSimpleReader::declHandler
+88 QXmlSimpleReader::parse
+92 QXmlSimpleReader::parse
+96 QXmlSimpleReader::parse
+100 QXmlSimpleReader::parseContinue
+
+Class QXmlSimpleReader
+ size=8 align=4
+ base size=8 base align=4
+QXmlSimpleReader (0xb47b5d80) 0
+ vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 8u)
+ QXmlReader (0xb47ed4b0) 0 nearly-empty
+ primary-for QXmlSimpleReader (0xb47b5d80)
+
+Vtable for QXmlLocator
+QXmlLocator::_ZTV11QXmlLocator: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QXmlLocator)
+8 QXmlLocator::~QXmlLocator
+12 QXmlLocator::~QXmlLocator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlLocator
+ size=4 align=4
+ base size=4 base align=4
+QXmlLocator (0xb47ed564) 0 nearly-empty
+ vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 8u)
+
+Vtable for QXmlContentHandler
+QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlContentHandler)
+8 QXmlContentHandler::~QXmlContentHandler
+12 QXmlContentHandler::~QXmlContentHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QXmlContentHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlContentHandler (0xb47ed5a0) 0 nearly-empty
+ vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 8u)
+
+Vtable for QXmlErrorHandler
+QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlErrorHandler)
+8 QXmlErrorHandler::~QXmlErrorHandler
+12 QXmlErrorHandler::~QXmlErrorHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlErrorHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlErrorHandler (0xb47ed7bc) 0 nearly-empty
+ vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 8u)
+
+Vtable for QXmlDTDHandler
+QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlDTDHandler)
+8 QXmlDTDHandler::~QXmlDTDHandler
+12 QXmlDTDHandler::~QXmlDTDHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QXmlDTDHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDTDHandler (0xb47ed9d8) 0 nearly-empty
+ vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 8u)
+
+Vtable for QXmlEntityResolver
+QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlEntityResolver)
+8 QXmlEntityResolver::~QXmlEntityResolver
+12 QXmlEntityResolver::~QXmlEntityResolver
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlEntityResolver (0xb47edbf4) 0 nearly-empty
+ vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 8u)
+
+Vtable for QXmlLexicalHandler
+QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlLexicalHandler)
+8 QXmlLexicalHandler::~QXmlLexicalHandler
+12 QXmlLexicalHandler::~QXmlLexicalHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+
+Class QXmlLexicalHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlLexicalHandler (0xb47ede10) 0 nearly-empty
+ vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 8u)
+
+Vtable for QXmlDeclHandler
+QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlDeclHandler)
+8 QXmlDeclHandler::~QXmlDeclHandler
+12 QXmlDeclHandler::~QXmlDeclHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlDeclHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDeclHandler (0xb481f03c) 0 nearly-empty
+ vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 8u)
+
+Vtable for QXmlDefaultHandler
+QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+8 QXmlDefaultHandler::~QXmlDefaultHandler
+12 QXmlDefaultHandler::~QXmlDefaultHandler
+16 QXmlDefaultHandler::setDocumentLocator
+20 QXmlDefaultHandler::startDocument
+24 QXmlDefaultHandler::endDocument
+28 QXmlDefaultHandler::startPrefixMapping
+32 QXmlDefaultHandler::endPrefixMapping
+36 QXmlDefaultHandler::startElement
+40 QXmlDefaultHandler::endElement
+44 QXmlDefaultHandler::characters
+48 QXmlDefaultHandler::ignorableWhitespace
+52 QXmlDefaultHandler::processingInstruction
+56 QXmlDefaultHandler::skippedEntity
+60 QXmlDefaultHandler::errorString
+64 QXmlDefaultHandler::warning
+68 QXmlDefaultHandler::error
+72 QXmlDefaultHandler::fatalError
+76 QXmlDefaultHandler::notationDecl
+80 QXmlDefaultHandler::unparsedEntityDecl
+84 QXmlDefaultHandler::resolveEntity
+88 QXmlDefaultHandler::startDTD
+92 QXmlDefaultHandler::endDTD
+96 QXmlDefaultHandler::startEntity
+100 QXmlDefaultHandler::endEntity
+104 QXmlDefaultHandler::startCDATA
+108 QXmlDefaultHandler::endCDATA
+112 QXmlDefaultHandler::comment
+116 QXmlDefaultHandler::attributeDecl
+120 QXmlDefaultHandler::internalEntityDecl
+124 QXmlDefaultHandler::externalEntityDecl
+128 (int (*)(...))-0x000000004
+132 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+136 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD1Ev
+140 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD0Ev
+144 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler7warningERK18QXmlParseException
+148 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler5errorERK18QXmlParseException
+152 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException
+156 QXmlDefaultHandler::_ZThn4_NK18QXmlDefaultHandler11errorStringEv
+160 (int (*)(...))-0x000000008
+164 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+168 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev
+172 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev
+176 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_
+180 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_
+184 QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv
+188 (int (*)(...))-0x00000000c
+192 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+196 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD1Ev
+200 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD0Ev
+204 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource
+208 QXmlDefaultHandler::_ZThn12_NK18QXmlDefaultHandler11errorStringEv
+212 (int (*)(...))-0x000000010
+216 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+220 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev
+224 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev
+228 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_
+232 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler6endDTDEv
+236 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler11startEntityERK7QString
+240 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler9endEntityERK7QString
+244 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler10startCDATAEv
+248 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8endCDATAEv
+252 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler7commentERK7QString
+256 QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv
+260 (int (*)(...))-0x000000014
+264 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+268 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD1Ev
+272 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD0Ev
+276 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_
+280 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_
+284 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_
+288 QXmlDefaultHandler::_ZThn20_NK18QXmlDefaultHandler11errorStringEv
+
+Class QXmlDefaultHandler
+ size=28 align=4
+ base size=28 base align=4
+QXmlDefaultHandler (0xb47e8c24) 0
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 8u)
+ QXmlContentHandler (0xb481f258) 0 nearly-empty
+ primary-for QXmlDefaultHandler (0xb47e8c24)
+ QXmlErrorHandler (0xb481f294) 4 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 136u)
+ QXmlDTDHandler (0xb481f2d0) 8 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 168u)
+ QXmlEntityResolver (0xb481f30c) 12 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 196u)
+ QXmlLexicalHandler (0xb481f348) 16 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 220u)
+ QXmlDeclHandler (0xb481f384) 20 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 268u)
+
+Vtable for QAbstractExtensionFactory
+QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionFactory)
+8 QAbstractExtensionFactory::~QAbstractExtensionFactory
+12 QAbstractExtensionFactory::~QAbstractExtensionFactory
+16 __cxa_pure_virtual
+
+Class QAbstractExtensionFactory
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionFactory (0xb484c1e0) 0 nearly-empty
+ vptr=((& QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory) + 8u)
+
+Vtable for QAbstractExtensionManager
+QAbstractExtensionManager::_ZTV25QAbstractExtensionManager: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionManager)
+8 QAbstractExtensionManager::~QAbstractExtensionManager
+12 QAbstractExtensionManager::~QAbstractExtensionManager
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QAbstractExtensionManager
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionManager (0xb484c654) 0 nearly-empty
+ vptr=((& QAbstractExtensionManager::_ZTV25QAbstractExtensionManager) + 8u)
+
+Vtable for QDesignerMemberSheetExtension
+QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerMemberSheetExtension)
+8 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+12 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+
+Class QDesignerMemberSheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMemberSheetExtension (0xb484cac8) 0 nearly-empty
+ vptr=((& QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension) + 8u)
+
+Vtable for QDesignerWidgetFactoryInterface
+QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerWidgetFactoryInterface)
+8 QDesignerWidgetFactoryInterface::metaObject
+12 QDesignerWidgetFactoryInterface::qt_metacast
+16 QDesignerWidgetFactoryInterface::qt_metacall
+20 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+24 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerWidgetFactoryInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerWidgetFactoryInterface (0xb4851c00) 0
+ vptr=((& QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface) + 8u)
+ QObject (0xb486a12c) 0
+ primary-for QDesignerWidgetFactoryInterface (0xb4851c00)
+
+Vtable for QDesignerFormEditorPluginInterface
+QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormEditorPluginInterface)
+8 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+12 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QDesignerFormEditorPluginInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormEditorPluginInterface (0xb486a258) 0 nearly-empty
+ vptr=((& QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface) + 8u)
+
+Vtable for QDesignerExtraInfoExtension
+QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerExtraInfoExtension)
+8 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+12 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerExtraInfoExtension
+ size=8 align=4
+ base size=8 base align=4
+QDesignerExtraInfoExtension (0xb486a6cc) 0
+ vptr=((& QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension) + 8u)
+
+Vtable for QDesignerDynamicPropertySheetExtension
+QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI38QDesignerDynamicPropertySheetExtension)
+8 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+12 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+
+Class QDesignerDynamicPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDynamicPropertySheetExtension (0xb486ae10) 0 nearly-empty
+ vptr=((& QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension) + 8u)
+
+Vtable for QDesignerFormWindowToolInterface
+QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerFormWindowToolInterface)
+8 QDesignerFormWindowToolInterface::metaObject
+12 QDesignerFormWindowToolInterface::qt_metacast
+16 QDesignerFormWindowToolInterface::qt_metacall
+20 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+24 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QDesignerFormWindowToolInterface::saveToDom
+84 QDesignerFormWindowToolInterface::loadFromDom
+88 __cxa_pure_virtual
+
+Class QDesignerFormWindowToolInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowToolInterface (0xb4877b80) 0
+ vptr=((& QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface) + 8u)
+ QObject (0xb488b474) 0
+ primary-for QDesignerFormWindowToolInterface (0xb4877b80)
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb488b5a0) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb46b70b4) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb46d2740) 0
+ QVector<QPoint> (0xb46b7708) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb46d2d40) 0
+ QVector<QPointF> (0xb47080b4) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb47089d8) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb470899c) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb4708d20) 0
+
+Class QPainterPath::Element
+ size=20 align=4
+ base size=20 base align=4
+QPainterPath::Element (0xb47534b0) 0
+
+Class QPainterPath
+ size=4 align=4
+ base size=4 base align=4
+QPainterPath (0xb4753474) 0
+
+Class QPainterPathPrivate
+ size=8 align=4
+ base size=8 base align=4
+QPainterPathPrivate (0xb4753924) 0
+
+Class QPainterPathStroker
+ size=4 align=4
+ base size=4 base align=4
+QPainterPathStroker (0xb4753a50) 0
+
+Class QTransform
+ size=80 align=4
+ base size=80 base align=4
+QTransform (0xb45ab8e8) 0
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb45eef00) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb45ecac0) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb46028e8) 0
+ primary-for QImage (0xb45ecac0)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb4662400) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb46615a0) 0
+ primary-for QPixmap (0xb4662400)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb4661bf4) 0
+
+Class QBrushData
+ size=104 align=4
+ base size=104 base align=4
+QBrushData (0xb4661e4c) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb44ac21c) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb44ce240) 0
+ QGradient (0xb44ac4b0) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb44ce340) 0
+ QGradient (0xb44ac4ec) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb44ce440) 0
+ QGradient (0xb44ac528) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb44ac564) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb44cee80) 0
+ QPalette (0xb44ace4c) 0
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb450efb4) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb453e1a4) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb453e3fc) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb453e4b0) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb453e4ec) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb43ad3c0) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb43ad3fc) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb43ad708) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb43f4690) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb43ad744) 0
+ primary-for QWidget (0xb43f4690)
+ QPaintDevice (0xb43ad780) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb4494d98) 0
+
+Class QDesignerWidgetBoxInterface::Widget
+ size=16 align=4
+ base size=16 base align=4
+QDesignerWidgetBoxInterface::Widget (0xb42c9168) 0
+
+Class QDesignerWidgetBoxInterface::Category
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetBoxInterface::Category (0xb42c91a4) 0
+
+Vtable for QDesignerWidgetBoxInterface
+QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface: 76u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+8 QDesignerWidgetBoxInterface::metaObject
+12 QDesignerWidgetBoxInterface::qt_metacast
+16 QDesignerWidgetBoxInterface::qt_metacall
+20 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+24 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 (int (*)(...))-0x000000008
+280 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+284 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD1Ev
+288 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD0Ev
+292 QWidget::_ZThn8_NK7QWidget7devTypeEv
+296 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+300 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerWidgetBoxInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerWidgetBoxInterface (0xb42ce080) 0
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 8u)
+ QWidget (0xb42c1fa0) 0
+ primary-for QDesignerWidgetBoxInterface (0xb42ce080)
+ QObject (0xb42c90f0) 0
+ primary-for QWidget (0xb42c1fa0)
+ QPaintDevice (0xb42c912c) 8
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 284u)
+
+Class QDesignerPromotionInterface::PromotedClass
+ size=8 align=4
+ base size=8 base align=4
+QDesignerPromotionInterface::PromotedClass (0xb4310ca8) 0
+
+Vtable for QDesignerPromotionInterface
+QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerPromotionInterface)
+8 QDesignerPromotionInterface::~QDesignerPromotionInterface
+12 QDesignerPromotionInterface::~QDesignerPromotionInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerPromotionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPromotionInterface (0xb4310c6c) 0 nearly-empty
+ vptr=((& QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface) + 8u)
+
+Vtable for QDesignerFormWindowInterface
+QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface: 114u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+8 QDesignerFormWindowInterface::metaObject
+12 QDesignerFormWindowInterface::qt_metacast
+16 QDesignerFormWindowInterface::qt_metacall
+20 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+24 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 __cxa_pure_virtual
+280 __cxa_pure_virtual
+284 __cxa_pure_virtual
+288 __cxa_pure_virtual
+292 __cxa_pure_virtual
+296 __cxa_pure_virtual
+300 __cxa_pure_virtual
+304 QDesignerFormWindowInterface::core
+308 __cxa_pure_virtual
+312 __cxa_pure_virtual
+316 __cxa_pure_virtual
+320 __cxa_pure_virtual
+324 __cxa_pure_virtual
+328 __cxa_pure_virtual
+332 __cxa_pure_virtual
+336 __cxa_pure_virtual
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 __cxa_pure_virtual
+368 __cxa_pure_virtual
+372 __cxa_pure_virtual
+376 __cxa_pure_virtual
+380 __cxa_pure_virtual
+384 __cxa_pure_virtual
+388 __cxa_pure_virtual
+392 __cxa_pure_virtual
+396 __cxa_pure_virtual
+400 __cxa_pure_virtual
+404 __cxa_pure_virtual
+408 __cxa_pure_virtual
+412 __cxa_pure_virtual
+416 __cxa_pure_virtual
+420 __cxa_pure_virtual
+424 __cxa_pure_virtual
+428 (int (*)(...))-0x000000008
+432 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+436 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD1Ev
+440 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD0Ev
+444 QWidget::_ZThn8_NK7QWidget7devTypeEv
+448 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+452 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerFormWindowInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerFormWindowInterface (0xb4313680) 0
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 8u)
+ QWidget (0xb431daf0) 0
+ primary-for QDesignerFormWindowInterface (0xb4313680)
+ QObject (0xb4310ce4) 0
+ primary-for QWidget (0xb431daf0)
+ QPaintDevice (0xb4310d20) 8
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 436u)
+
+Vtable for QDesignerObjectInspectorInterface
+QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+8 QDesignerObjectInspectorInterface::metaObject
+12 QDesignerObjectInspectorInterface::qt_metacast
+16 QDesignerObjectInspectorInterface::qt_metacall
+20 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+24 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerObjectInspectorInterface::core
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+240 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD1Ev
+244 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerObjectInspectorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerObjectInspectorInterface (0xb43138c0) 0
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 8u)
+ QWidget (0xb4337000) 0
+ primary-for QDesignerObjectInspectorInterface (0xb43138c0)
+ QObject (0xb4310e4c) 0
+ primary-for QWidget (0xb4337000)
+ QPaintDevice (0xb4310e88) 8
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 240u)
+
+Vtable for QDesignerIconCacheInterface
+QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerIconCacheInterface)
+8 QDesignerIconCacheInterface::metaObject
+12 QDesignerIconCacheInterface::qt_metacast
+16 QDesignerIconCacheInterface::qt_metacall
+20 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+24 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QDesignerIconCacheInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerIconCacheInterface (0xb4313b00) 0
+ vptr=((& QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface) + 8u)
+ QObject (0xb4310fb4) 0
+ primary-for QDesignerIconCacheInterface (0xb4313b00)
+
+Vtable for QDesignerMetaDataBaseItemInterface
+QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerMetaDataBaseItemInterface)
+8 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+12 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMetaDataBaseItemInterface (0xb434b30c) 0 nearly-empty
+ vptr=((& QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerMetaDataBaseInterface
+QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerMetaDataBaseInterface)
+8 QDesignerMetaDataBaseInterface::metaObject
+12 QDesignerMetaDataBaseInterface::qt_metacast
+16 QDesignerMetaDataBaseInterface::qt_metacall
+20 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+24 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerMetaDataBaseInterface (0xb4356000) 0
+ vptr=((& QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface) + 8u)
+ QObject (0xb434b528) 0
+ primary-for QDesignerMetaDataBaseInterface (0xb4356000)
+
+Vtable for QDesignerLayoutDecorationExtension
+QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerLayoutDecorationExtension)
+8 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+12 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerLayoutDecorationExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLayoutDecorationExtension (0xb434b654) 0 nearly-empty
+ vptr=((& QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension) + 8u)
+
+Vtable for QDesignerPropertySheetExtension
+QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerPropertySheetExtension)
+8 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+12 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPropertySheetExtension (0xb434bca8) 0 nearly-empty
+ vptr=((& QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension) + 8u)
+
+Vtable for QDesignerActionEditorInterface
+QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+8 QDesignerActionEditorInterface::metaObject
+12 QDesignerActionEditorInterface::qt_metacast
+16 QDesignerActionEditorInterface::qt_metacall
+20 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+24 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerActionEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 (int (*)(...))-0x000000008
+244 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+248 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD1Ev
+252 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerActionEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerActionEditorInterface (0xb4356b40) 0
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 8u)
+ QWidget (0xb4371a50) 0
+ primary-for QDesignerActionEditorInterface (0xb4356b40)
+ QObject (0xb437830c) 0
+ primary-for QWidget (0xb4371a50)
+ QPaintDevice (0xb4378348) 8
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 248u)
+
+Vtable for QDesignerIntegrationInterface
+QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerIntegrationInterface)
+8 QDesignerIntegrationInterface::metaObject
+12 QDesignerIntegrationInterface::qt_metacast
+16 QDesignerIntegrationInterface::qt_metacall
+20 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+24 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+
+Class QDesignerIntegrationInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerIntegrationInterface (0xb4356d80) 0
+ vptr=((& QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface) + 8u)
+ QObject (0xb4378474) 0
+ primary-for QDesignerIntegrationInterface (0xb4356d80)
+
+Vtable for QDesignerTaskMenuExtension
+QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerTaskMenuExtension)
+8 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+12 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+16 QDesignerTaskMenuExtension::preferredEditAction
+20 __cxa_pure_virtual
+
+Class QDesignerTaskMenuExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerTaskMenuExtension (0xb43785dc) 0 nearly-empty
+ vptr=((& QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension) + 8u)
+
+Vtable for QDesignerFormWindowCursorInterface
+QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormWindowCursorInterface)
+8 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+12 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+
+Class QDesignerFormWindowCursorInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormWindowCursorInterface (0xb4378d20) 0 nearly-empty
+ vptr=((& QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface) + 8u)
+
+Vtable for QDesignerWidgetDataBaseItemInterface
+QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI36QDesignerWidgetDataBaseItemInterface)
+8 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+12 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+
+Class QDesignerWidgetDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerWidgetDataBaseItemInterface (0xb4378f3c) 0 nearly-empty
+ vptr=((& QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerWidgetDataBaseInterface
+QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerWidgetDataBaseInterface)
+8 QDesignerWidgetDataBaseInterface::metaObject
+12 QDesignerWidgetDataBaseInterface::qt_metacast
+16 QDesignerWidgetDataBaseInterface::qt_metacall
+20 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+24 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerWidgetDataBaseInterface::count
+60 QDesignerWidgetDataBaseInterface::item
+64 QDesignerWidgetDataBaseInterface::indexOf
+68 QDesignerWidgetDataBaseInterface::insert
+72 QDesignerWidgetDataBaseInterface::append
+76 QDesignerWidgetDataBaseInterface::indexOfObject
+80 QDesignerWidgetDataBaseInterface::indexOfClassName
+84 QDesignerWidgetDataBaseInterface::core
+
+Class QDesignerWidgetDataBaseInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetDataBaseInterface (0xb438c8c0) 0
+ vptr=((& QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface) + 8u)
+ QObject (0xb41a6168) 0
+ primary-for QDesignerWidgetDataBaseInterface (0xb438c8c0)
+
+Vtable for QDesignerPropertyEditorInterface
+QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface: 70u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+8 QDesignerPropertyEditorInterface::metaObject
+12 QDesignerPropertyEditorInterface::qt_metacast
+16 QDesignerPropertyEditorInterface::qt_metacall
+20 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+24 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerPropertyEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 (int (*)(...))-0x000000008
+256 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+260 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD1Ev
+264 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD0Ev
+268 QWidget::_ZThn8_NK7QWidget7devTypeEv
+272 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+276 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerPropertyEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerPropertyEditorInterface (0xb438cbc0) 0
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 8u)
+ QWidget (0xb41beb40) 0
+ primary-for QDesignerPropertyEditorInterface (0xb438cbc0)
+ QObject (0xb41a630c) 0
+ primary-for QWidget (0xb41beb40)
+ QPaintDevice (0xb41a6348) 8
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 260u)
+
+Vtable for QDesignerFormEditorInterface
+QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormEditorInterface)
+8 QDesignerFormEditorInterface::metaObject
+12 QDesignerFormEditorInterface::qt_metacast
+16 QDesignerFormEditorInterface::qt_metacall
+20 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+24 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QDesignerFormEditorInterface
+ size=60 align=4
+ base size=60 base align=4
+QDesignerFormEditorInterface (0xb438ce00) 0
+ vptr=((& QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface) + 8u)
+ QObject (0xb41a6474) 0
+ primary-for QDesignerFormEditorInterface (0xb438ce00)
+
+Vtable for QDesignerResourceBrowserInterface
+QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+8 QDesignerResourceBrowserInterface::metaObject
+12 QDesignerResourceBrowserInterface::qt_metacast
+16 QDesignerResourceBrowserInterface::qt_metacall
+20 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+24 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+240 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD1Ev
+244 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerResourceBrowserInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerResourceBrowserInterface (0xb41f3340) 0
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 8u)
+ QWidget (0xb4208aa0) 0
+ primary-for QDesignerResourceBrowserInterface (0xb41f3340)
+ QObject (0xb41a6870) 0
+ primary-for QWidget (0xb4208aa0)
+ QPaintDevice (0xb41a68ac) 8
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 240u)
+
+Vtable for QDesignerBrushManagerInterface
+QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerBrushManagerInterface)
+8 QDesignerBrushManagerInterface::metaObject
+12 QDesignerBrushManagerInterface::qt_metacast
+16 QDesignerBrushManagerInterface::qt_metacall
+20 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+24 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerBrushManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerBrushManagerInterface (0xb41f3580) 0
+ vptr=((& QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface) + 8u)
+ QObject (0xb41a69d8) 0
+ primary-for QDesignerBrushManagerInterface (0xb41f3580)
+
+Vtable for QDesignerDnDItemInterface
+QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QDesignerDnDItemInterface)
+8 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+12 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerDnDItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDnDItemInterface (0xb41a6d20) 0 nearly-empty
+ vptr=((& QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface) + 8u)
+
+Vtable for QDesignerFormWindowManagerInterface
+QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface: 39u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI35QDesignerFormWindowManagerInterface)
+8 QDesignerFormWindowManagerInterface::metaObject
+12 QDesignerFormWindowManagerInterface::qt_metacast
+16 QDesignerFormWindowManagerInterface::qt_metacall
+20 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+24 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerFormWindowManagerInterface::actionCut
+60 QDesignerFormWindowManagerInterface::actionCopy
+64 QDesignerFormWindowManagerInterface::actionPaste
+68 QDesignerFormWindowManagerInterface::actionDelete
+72 QDesignerFormWindowManagerInterface::actionSelectAll
+76 QDesignerFormWindowManagerInterface::actionLower
+80 QDesignerFormWindowManagerInterface::actionRaise
+84 QDesignerFormWindowManagerInterface::actionUndo
+88 QDesignerFormWindowManagerInterface::actionRedo
+92 QDesignerFormWindowManagerInterface::actionHorizontalLayout
+96 QDesignerFormWindowManagerInterface::actionVerticalLayout
+100 QDesignerFormWindowManagerInterface::actionSplitHorizontal
+104 QDesignerFormWindowManagerInterface::actionSplitVertical
+108 QDesignerFormWindowManagerInterface::actionGridLayout
+112 QDesignerFormWindowManagerInterface::actionBreakLayout
+116 QDesignerFormWindowManagerInterface::actionAdjustSize
+120 QDesignerFormWindowManagerInterface::activeFormWindow
+124 QDesignerFormWindowManagerInterface::formWindowCount
+128 QDesignerFormWindowManagerInterface::formWindow
+132 QDesignerFormWindowManagerInterface::createFormWindow
+136 QDesignerFormWindowManagerInterface::core
+140 __cxa_pure_virtual
+144 QDesignerFormWindowManagerInterface::addFormWindow
+148 QDesignerFormWindowManagerInterface::removeFormWindow
+152 QDesignerFormWindowManagerInterface::setActiveFormWindow
+
+Class QDesignerFormWindowManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowManagerInterface (0xb41f3b40) 0
+ vptr=((& QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface) + 8u)
+ QObject (0xb422e000) 0
+ primary-for QDesignerFormWindowManagerInterface (0xb41f3b40)
+
+Vtable for QDesignerLanguageExtension
+QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension: 13u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerLanguageExtension)
+8 QDesignerLanguageExtension::~QDesignerLanguageExtension
+12 QDesignerLanguageExtension::~QDesignerLanguageExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QDesignerLanguageExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLanguageExtension (0xb422e12c) 0 nearly-empty
+ vptr=((& QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension) + 8u)
+
+Vtable for QAbstractFormBuilder
+QAbstractFormBuilder::_ZTV20QAbstractFormBuilder: 48u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QAbstractFormBuilder)
+8 QAbstractFormBuilder::~QAbstractFormBuilder
+12 QAbstractFormBuilder::~QAbstractFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QAbstractFormBuilder::create
+32 QAbstractFormBuilder::create
+36 QAbstractFormBuilder::create
+40 QAbstractFormBuilder::create
+44 QAbstractFormBuilder::create
+48 QAbstractFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QAbstractFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QAbstractFormBuilder::createWidget
+68 QAbstractFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QAbstractFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QAbstractFormBuilder::addItem
+96 QAbstractFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+
+Class QAbstractFormBuilder
+ size=28 align=4
+ base size=28 base align=4
+QAbstractFormBuilder (0xb422e780) 0
+ vptr=((& QAbstractFormBuilder::_ZTV20QAbstractFormBuilder) + 8u)
+
+Vtable for QFormBuilder
+QFormBuilder::_ZTV12QFormBuilder: 49u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QFormBuilder)
+8 QFormBuilder::~QFormBuilder
+12 QFormBuilder::~QFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QFormBuilder::create
+32 QFormBuilder::create
+36 QFormBuilder::create
+40 QFormBuilder::create
+44 QFormBuilder::create
+48 QFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QFormBuilder::createWidget
+68 QFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QFormBuilder::addItem
+96 QFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+192 QFormBuilder::updateCustomWidgets
+
+Class QFormBuilder
+ size=36 align=4
+ base size=36 base align=4
+QFormBuilder (0xb4242600) 0
+ vptr=((& QFormBuilder::_ZTV12QFormBuilder) + 8u)
+ QAbstractFormBuilder (0xb422e924) 0
+ primary-for QFormBuilder (0xb4242600)
+
+Vtable for QDesignerCustomWidgetInterface
+QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerCustomWidgetInterface)
+8 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+12 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 QDesignerCustomWidgetInterface::isInitialized
+52 QDesignerCustomWidgetInterface::initialize
+56 QDesignerCustomWidgetInterface::domXml
+60 QDesignerCustomWidgetInterface::codeTemplate
+
+Class QDesignerCustomWidgetInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetInterface (0xb422e9d8) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface) + 8u)
+
+Vtable for QDesignerCustomWidgetCollectionInterface
+QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI40QDesignerCustomWidgetCollectionInterface)
+8 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+12 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+16 __cxa_pure_virtual
+
+Class QDesignerCustomWidgetCollectionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetCollectionInterface (0xb40af000) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface) + 8u)
+
+Vtable for QDesignerContainerExtension
+QDesignerContainerExtension::_ZTV27QDesignerContainerExtension: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerContainerExtension)
+8 QDesignerContainerExtension::~QDesignerContainerExtension
+12 QDesignerContainerExtension::~QDesignerContainerExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerContainerExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerContainerExtension (0xb40af474) 0 nearly-empty
+ vptr=((& QDesignerContainerExtension::_ZTV27QDesignerContainerExtension) + 8u)
+
+Vtable for QExtensionManager
+QExtensionManager::_ZTV17QExtensionManager: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QExtensionManager)
+8 QExtensionManager::metaObject
+12 QExtensionManager::qt_metacast
+16 QExtensionManager::qt_metacall
+20 QExtensionManager::~QExtensionManager
+24 QExtensionManager::~QExtensionManager
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QExtensionManager::registerExtensions
+60 QExtensionManager::unregisterExtensions
+64 QExtensionManager::extension
+68 (int (*)(...))-0x000000008
+72 (int (*)(...))(& _ZTI17QExtensionManager)
+76 QExtensionManager::_ZThn8_N17QExtensionManagerD1Ev
+80 QExtensionManager::_ZThn8_N17QExtensionManagerD0Ev
+84 QExtensionManager::_ZThn8_N17QExtensionManager18registerExtensionsEP25QAbstractExtensionFactoryRK7QString
+88 QExtensionManager::_ZThn8_N17QExtensionManager20unregisterExtensionsEP25QAbstractExtensionFactoryRK7QString
+92 QExtensionManager::_ZThn8_NK17QExtensionManager9extensionEP7QObjectRK7QString
+
+Class QExtensionManager
+ size=20 align=4
+ base size=20 base align=4
+QExtensionManager (0xb40bd690) 0
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 8u)
+ QObject (0xb40afac8) 0
+ primary-for QExtensionManager (0xb40bd690)
+ QAbstractExtensionManager (0xb40afb04) 8 nearly-empty
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 76u)
+
diff --git a/tests/auto/bic/data/QtDesigner.4.6.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtDesigner.4.6.0.linux-gcc-amd64.txt
new file mode 100644
index 000000000..349907e1e
--- /dev/null
+++ b/tests/auto/bic/data/QtDesigner.4.6.0.linux-gcc-amd64.txt
@@ -0,0 +1,4741 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0x7f0d42e42380) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0x7f0d42e5a000) 0
+
+Class qIsNull(double)::U
+ size=8 align=8
+ base size=8 base align=8
+qIsNull(double)::U (0x7f0d42e6f690) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0x7f0d42e6f930) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0x7f0d42ea67e0) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0x7f0d42ebe000) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0x7f0d42ed6700) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0x7f0d42efd2a0) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0x7f0d42543460) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0x7f0d42580e00) 0
+ QBasicAtomicInt (0x7f0d42580e70) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0x7f0d423cf620) 0 empty
+
+Class __locale_struct
+ size=232 align=8
+ base size=232 base align=8
+__locale_struct (0x7f0d423cf850) 0
+
+Class QByteArray::Data
+ size=32 align=8
+ base size=32 base align=8
+QByteArray::Data (0x7f0d42210c40) 0
+
+Class QByteArray
+ size=8 align=8
+ base size=8 base align=8
+QByteArray (0x7f0d42210bd0) 0
+
+Class QByteRef
+ size=16 align=8
+ base size=12 base align=8
+QByteRef (0x7f0d422b24d0) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0x7f0d421b4e70) 0 empty
+
+Class QString::Data
+ size=32 align=8
+ base size=32 base align=8
+QString::Data (0x7f0d421ca700) 0
+
+Class QString
+ size=8 align=8
+ base size=8 base align=8
+QString (0x7f0d4212cd20) 0
+
+Class QLatin1String
+ size=8 align=8
+ base size=8 base align=8
+QLatin1String (0x7f0d420a4af0) 0
+
+Class QCharRef
+ size=16 align=8
+ base size=12 base align=8
+QCharRef (0x7f0d41f42150) 0
+
+Class QConstString
+ size=8 align=8
+ base size=8 base align=8
+QConstString (0x7f0d41e8ba10) 0
+ QString (0x7f0d41e8ba80) 0
+
+Class QStringRef
+ size=16 align=8
+ base size=16 base align=8
+QStringRef (0x7f0d41eb2460) 0
+
+Class QGenericArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericArgument (0x7f0d41d2b850) 0
+
+Class QGenericReturnArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericReturnArgument (0x7f0d41d363f0) 0
+ QGenericArgument (0x7f0d41d36460) 0
+
+Class QMetaObject
+ size=32 align=8
+ base size=32 base align=8
+QMetaObject (0x7f0d41d36cb0) 0
+
+Class QMetaObjectExtraData
+ size=16 align=8
+ base size=16 base align=8
+QMetaObjectExtraData (0x7f0d41d5cd20) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9exception)
+16 std::exception::~exception
+24 std::exception::~exception
+32 std::exception::what
+
+Class std::exception
+ size=8 align=8
+ base size=8 base align=8
+std::exception (0x7f0d41db0310) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 16u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13bad_exception)
+16 std::bad_exception::~bad_exception
+24 std::bad_exception::~bad_exception
+32 std::bad_exception::what
+
+Class std::bad_exception
+ size=8 align=8
+ base size=8 base align=8
+std::bad_exception (0x7f0d41db08c0) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u)
+ std::exception (0x7f0d41db0930) 0 nearly-empty
+ primary-for std::bad_exception (0x7f0d41db08c0)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9bad_alloc)
+16 std::bad_alloc::~bad_alloc
+24 std::bad_alloc::~bad_alloc
+32 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=8 align=8
+ base size=8 base align=8
+std::bad_alloc (0x7f0d41dc60e0) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u)
+ std::exception (0x7f0d41dc6150) 0 nearly-empty
+ primary-for std::bad_alloc (0x7f0d41dc60e0)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0x7f0d41dc69a0) 0 empty
+
+Class QListData::Data
+ size=32 align=8
+ base size=32 base align=8
+QListData::Data (0x7f0d41dc6ee0) 0
+
+Class QListData
+ size=8 align=8
+ base size=8 base align=8
+QListData (0x7f0d41dc6e70) 0
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0x7f0d41aef9a0) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QObjectData)
+16 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QObjectData
+ size=48 align=8
+ base size=48 base align=8
+QObjectData (0x7f0d41b103f0) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 16u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QObject)
+16 QObject::metaObject
+24 QObject::qt_metacast
+32 QObject::qt_metacall
+40 QObject::~QObject
+48 QObject::~QObject
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QObject
+ size=16 align=8
+ base size=16 base align=8
+QObject (0x7f0d41b10700) 0
+ vptr=((& QObject::_ZTV7QObject) + 16u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QObjectUserData)
+16 QObjectUserData::~QObjectUserData
+24 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=8 align=8
+ base size=8 base align=8
+QObjectUserData (0x7f0d41b96cb0) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QIODevice)
+16 QIODevice::metaObject
+24 QIODevice::qt_metacast
+32 QIODevice::qt_metacall
+40 QIODevice::~QIODevice
+48 QIODevice::~QIODevice
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QIODevice::isSequential
+120 QIODevice::open
+128 QIODevice::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QIODevice::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 __cxa_pure_virtual
+224 QIODevice::readLineData
+232 __cxa_pure_virtual
+
+Class QIODevice
+ size=16 align=8
+ base size=16 base align=8
+QIODevice (0x7f0d41ba62a0) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 16u)
+ QObject (0x7f0d41ba6310) 0
+ primary-for QIODevice (0x7f0d41ba62a0)
+
+Class _IO_marker
+ size=24 align=8
+ base size=24 base align=8
+_IO_marker (0x7f0d41a08e00) 0
+
+Class _IO_FILE
+ size=216 align=8
+ base size=216 base align=8
+_IO_FILE (0x7f0d41a08e70) 0
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QFile)
+16 QFile::metaObject
+24 QFile::qt_metacast
+32 QFile::qt_metacall
+40 QFile::~QFile
+48 QFile::~QFile
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFile::isSequential
+120 QFile::open
+128 QFile::close
+136 QFile::pos
+144 QFile::size
+152 QFile::seek
+160 QFile::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QFile::readData
+224 QFile::readLineData
+232 QFile::writeData
+240 QFile::fileEngine
+
+Class QFile
+ size=16 align=8
+ base size=16 base align=8
+QFile (0x7f0d41a08f50) 0
+ vptr=((& QFile::_ZTV5QFile) + 16u)
+ QIODevice (0x7f0d41a4e000) 0
+ primary-for QFile (0x7f0d41a08f50)
+ QObject (0x7f0d41a4e070) 0
+ primary-for QIODevice (0x7f0d41a4e000)
+
+Class QFileInfo
+ size=8 align=8
+ base size=8 base align=8
+QFileInfo (0x7f0d41aab1c0) 0
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QDataStream)
+16 QDataStream::~QDataStream
+24 QDataStream::~QDataStream
+
+Class QDataStream
+ size=40 align=8
+ base size=40 base align=8
+QDataStream (0x7f0d41900b60) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 16u)
+
+Class QRegExp
+ size=8 align=8
+ base size=8 base align=8
+QRegExp (0x7f0d419a1000) 0
+
+Class QStringMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QStringMatcher::Data (0x7f0d419d03f0) 0
+
+Class QStringMatcher
+ size=1048 align=8
+ base size=1048 base align=8
+QStringMatcher (0x7f0d419c5d90) 0
+
+Class QStringList
+ size=8 align=8
+ base size=8 base align=8
+QStringList (0x7f0d419d09a0) 0
+ QList<QString> (0x7f0d419d0a10) 0
+
+Class QDir
+ size=8 align=8
+ base size=8 base align=8
+QDir (0x7f0d41870620) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0x7f0d41711a10) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0x7f0d41711a80) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=24 align=8
+ base size=20 base align=8
+QAbstractFileEngine::MapExtensionOption (0x7f0d41711af0) 0
+ QAbstractFileEngine::ExtensionOption (0x7f0d41711b60) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngine::MapExtensionReturn (0x7f0d41711d20) 0
+ QAbstractFileEngine::ExtensionReturn (0x7f0d41711d90) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngine::UnMapExtensionOption (0x7f0d41711e00) 0
+ QAbstractFileEngine::ExtensionOption (0x7f0d41711e70) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+16 QAbstractFileEngine::~QAbstractFileEngine
+24 QAbstractFileEngine::~QAbstractFileEngine
+32 QAbstractFileEngine::open
+40 QAbstractFileEngine::close
+48 QAbstractFileEngine::flush
+56 QAbstractFileEngine::size
+64 QAbstractFileEngine::pos
+72 QAbstractFileEngine::seek
+80 QAbstractFileEngine::isSequential
+88 QAbstractFileEngine::remove
+96 QAbstractFileEngine::copy
+104 QAbstractFileEngine::rename
+112 QAbstractFileEngine::link
+120 QAbstractFileEngine::mkdir
+128 QAbstractFileEngine::rmdir
+136 QAbstractFileEngine::setSize
+144 QAbstractFileEngine::caseSensitive
+152 QAbstractFileEngine::isRelativePath
+160 QAbstractFileEngine::entryList
+168 QAbstractFileEngine::fileFlags
+176 QAbstractFileEngine::setPermissions
+184 QAbstractFileEngine::fileName
+192 QAbstractFileEngine::ownerId
+200 QAbstractFileEngine::owner
+208 QAbstractFileEngine::fileTime
+216 QAbstractFileEngine::setFileName
+224 QAbstractFileEngine::handle
+232 QAbstractFileEngine::beginEntryList
+240 QAbstractFileEngine::endEntryList
+248 QAbstractFileEngine::read
+256 QAbstractFileEngine::readLine
+264 QAbstractFileEngine::write
+272 QAbstractFileEngine::extension
+280 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=16 align=8
+ base size=16 base align=8
+QAbstractFileEngine (0x7f0d416fc9a0) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 16u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+16 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+24 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+32 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngineHandler (0x7f0d4174dd20) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 16u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+16 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+24 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QAbstractFileEngineIterator::currentFileInfo
+64 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=16 align=8
+ base size=16 base align=8
+QAbstractFileEngineIterator (0x7f0d4174dee0) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 16u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBuffer)
+16 QBuffer::metaObject
+24 QBuffer::qt_metacast
+32 QBuffer::qt_metacall
+40 QBuffer::~QBuffer
+48 QBuffer::~QBuffer
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QBuffer::connectNotify
+104 QBuffer::disconnectNotify
+112 QIODevice::isSequential
+120 QBuffer::open
+128 QBuffer::close
+136 QBuffer::pos
+144 QBuffer::size
+152 QBuffer::seek
+160 QBuffer::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QBuffer::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QBuffer::readData
+224 QIODevice::readLineData
+232 QBuffer::writeData
+
+Class QBuffer
+ size=16 align=8
+ base size=16 base align=8
+QBuffer (0x7f0d4175f7e0) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 16u)
+ QIODevice (0x7f0d4175f850) 0
+ primary-for QBuffer (0x7f0d4175f7e0)
+ QObject (0x7f0d4175f8c0) 0
+ primary-for QIODevice (0x7f0d4175f850)
+
+Class QHashData::Node
+ size=16 align=8
+ base size=16 base align=8
+QHashData::Node (0x7f0d417a2f50) 0
+
+Class QHashData
+ size=40 align=8
+ base size=40 base align=8
+QHashData (0x7f0d417a2ee0) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0x7f0d417c42a0) 0 empty
+
+Class QMapData::Node
+ size=16 align=8
+ base size=16 base align=8
+QMapData::Node (0x7f0d416c4bd0) 0
+
+Class QMapData
+ size=128 align=8
+ base size=128 base align=8
+QMapData (0x7f0d416c4b60) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSystemLocale)
+16 QSystemLocale::~QSystemLocale
+24 QSystemLocale::~QSystemLocale
+32 QSystemLocale::query
+40 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=8 align=8
+ base size=8 base align=8
+QSystemLocale (0x7f0d414007e0) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 16u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0x7f0d4144fee0) 0
+
+Class QLocale
+ size=8 align=8
+ base size=8 base align=8
+QLocale (0x7f0d41400c40) 0
+
+Class QTextCodec::ConverterState
+ size=32 align=8
+ base size=32 base align=8
+QTextCodec::ConverterState (0x7f0d414a8d20) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextCodec)
+16 __cxa_pure_virtual
+24 QTextCodec::aliases
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QTextCodec::~QTextCodec
+64 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=8 align=8
+ base size=8 base align=8
+QTextCodec (0x7f0d414985b0) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u)
+
+Class QTextEncoder
+ size=40 align=8
+ base size=40 base align=8
+QTextEncoder (0x7f0d413162a0) 0
+
+Class QTextDecoder
+ size=40 align=8
+ base size=40 base align=8
+QTextDecoder (0x7f0d4131d0e0) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextStream)
+16 QTextStream::~QTextStream
+24 QTextStream::~QTextStream
+
+Class QTextStream
+ size=16 align=8
+ base size=16 base align=8
+QTextStream (0x7f0d4131dee0) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 16u)
+
+Class QTextStreamManipulator
+ size=40 align=8
+ base size=38 base align=8
+QTextStreamManipulator (0x7f0d41397bd0) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextIStream)
+16 QTextIStream::~QTextIStream
+24 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=16 align=8
+ base size=16 base align=8
+QTextIStream (0x7f0d413c81c0) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 16u)
+ QTextStream (0x7f0d413c8230) 0
+ primary-for QTextIStream (0x7f0d413c81c0)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextOStream)
+16 QTextOStream::~QTextOStream
+24 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=16 align=8
+ base size=16 base align=8
+QTextOStream (0x7f0d413db070) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 16u)
+ QTextStream (0x7f0d413db0e0) 0
+ primary-for QTextOStream (0x7f0d413db070)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0x7f0d411e7ee0) 0
+
+Class timespec
+ size=16 align=8
+ base size=16 base align=8
+timespec (0x7f0d411f2230) 0
+
+Class timeval
+ size=16 align=8
+ base size=16 base align=8
+timeval (0x7f0d411f22a0) 0
+
+Class __pthread_internal_list
+ size=16 align=8
+ base size=16 base align=8
+__pthread_internal_list (0x7f0d411f23f0) 0
+
+Class random_data
+ size=48 align=8
+ base size=48 base align=8
+random_data (0x7f0d411f29a0) 0
+
+Class drand48_data
+ size=24 align=8
+ base size=24 base align=8
+drand48_data (0x7f0d411f2a10) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0x7f0d411f2a80) 0
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0x7f0d411aa770) 0
+
+Class QDebug::Stream
+ size=40 align=8
+ base size=34 base align=8
+QDebug::Stream (0x7f0d4100e2a0) 0
+
+Class QDebug
+ size=8 align=8
+ base size=8 base align=8
+QDebug (0x7f0d4100e230) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0x7f0d410c0230) 0 empty
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QDirIterator)
+16 QDirIterator::~QDirIterator
+24 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=16 align=8
+ base size=16 base align=8
+QDirIterator (0x7f0d40ed18c0) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 16u)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+16 QFileSystemWatcher::metaObject
+24 QFileSystemWatcher::qt_metacast
+32 QFileSystemWatcher::qt_metacall
+40 QFileSystemWatcher::~QFileSystemWatcher
+48 QFileSystemWatcher::~QFileSystemWatcher
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemWatcher (0x7f0d40f21690) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u)
+ QObject (0x7f0d40f21700) 0
+ primary-for QFileSystemWatcher (0x7f0d40f21690)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFSFileEngine)
+16 QFSFileEngine::~QFSFileEngine
+24 QFSFileEngine::~QFSFileEngine
+32 QFSFileEngine::open
+40 QFSFileEngine::close
+48 QFSFileEngine::flush
+56 QFSFileEngine::size
+64 QFSFileEngine::pos
+72 QFSFileEngine::seek
+80 QFSFileEngine::isSequential
+88 QFSFileEngine::remove
+96 QFSFileEngine::copy
+104 QFSFileEngine::rename
+112 QFSFileEngine::link
+120 QFSFileEngine::mkdir
+128 QFSFileEngine::rmdir
+136 QFSFileEngine::setSize
+144 QFSFileEngine::caseSensitive
+152 QFSFileEngine::isRelativePath
+160 QFSFileEngine::entryList
+168 QFSFileEngine::fileFlags
+176 QFSFileEngine::setPermissions
+184 QFSFileEngine::fileName
+192 QFSFileEngine::ownerId
+200 QFSFileEngine::owner
+208 QFSFileEngine::fileTime
+216 QFSFileEngine::setFileName
+224 QFSFileEngine::handle
+232 QFSFileEngine::beginEntryList
+240 QFSFileEngine::endEntryList
+248 QFSFileEngine::read
+256 QFSFileEngine::readLine
+264 QFSFileEngine::write
+272 QFSFileEngine::extension
+280 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=16 align=8
+ base size=16 base align=8
+QFSFileEngine (0x7f0d40f3ebd0) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 16u)
+ QAbstractFileEngine (0x7f0d40f3ec40) 0
+ primary-for QFSFileEngine (0x7f0d40f3ebd0)
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0x7f0d40f4f9a0) 0
+
+Class QProcessEnvironment
+ size=8 align=8
+ base size=8 base align=8
+QProcessEnvironment (0x7f0d40f97310) 0
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QProcess)
+16 QProcess::metaObject
+24 QProcess::qt_metacast
+32 QProcess::qt_metacall
+40 QProcess::~QProcess
+48 QProcess::~QProcess
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QProcess::isSequential
+120 QIODevice::open
+128 QProcess::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QProcess::atEnd
+168 QIODevice::reset
+176 QProcess::bytesAvailable
+184 QProcess::bytesToWrite
+192 QProcess::canReadLine
+200 QProcess::waitForReadyRead
+208 QProcess::waitForBytesWritten
+216 QProcess::readData
+224 QIODevice::readLineData
+232 QProcess::writeData
+240 QProcess::setupChildProcess
+
+Class QProcess
+ size=16 align=8
+ base size=16 base align=8
+QProcess (0x7f0d40f97e00) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 16u)
+ QIODevice (0x7f0d40f97e70) 0
+ primary-for QProcess (0x7f0d40f97e00)
+ QObject (0x7f0d40f97ee0) 0
+ primary-for QIODevice (0x7f0d40f97e70)
+
+Class QResource
+ size=8 align=8
+ base size=8 base align=8
+QResource (0x7f0d40de0310) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0x7f0d40de0460) 0 empty
+
+Class QVariant::PrivateShared
+ size=16 align=8
+ base size=12 base align=8
+QVariant::PrivateShared (0x7f0d40cdf850) 0
+
+Class QVariant::Private::Data
+ size=8 align=8
+ base size=8 base align=8
+QVariant::Private::Data (0x7f0d40cdfb60) 0
+
+Class QVariant::Private
+ size=16 align=8
+ base size=12 base align=8
+QVariant::Private (0x7f0d40cdf930) 0
+
+Class QVariant::Handler
+ size=72 align=8
+ base size=72 base align=8
+QVariant::Handler (0x7f0d40cee850) 0
+
+Class QVariant
+ size=16 align=8
+ base size=16 base align=8
+QVariant (0x7f0d40eae930) 0
+
+Class QVariantComparisonHelper
+ size=8 align=8
+ base size=8 base align=8
+QVariantComparisonHelper (0x7f0d40da4af0) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSettings)
+16 QSettings::metaObject
+24 QSettings::qt_metacast
+32 QSettings::qt_metacall
+40 QSettings::~QSettings
+48 QSettings::~QSettings
+56 QSettings::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSettings
+ size=16 align=8
+ base size=16 base align=8
+QSettings (0x7f0d40bd0070) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 16u)
+ QObject (0x7f0d40bd00e0) 0
+ primary-for QSettings (0x7f0d40bd0070)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTemporaryFile)
+16 QTemporaryFile::metaObject
+24 QTemporaryFile::qt_metacast
+32 QTemporaryFile::qt_metacall
+40 QTemporaryFile::~QTemporaryFile
+48 QTemporaryFile::~QTemporaryFile
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFile::isSequential
+120 QTemporaryFile::open
+128 QFile::close
+136 QFile::pos
+144 QFile::size
+152 QFile::seek
+160 QFile::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QFile::readData
+224 QFile::readLineData
+232 QFile::writeData
+240 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=16 align=8
+ base size=16 base align=8
+QTemporaryFile (0x7f0d40c493f0) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u)
+ QFile (0x7f0d40c49460) 0
+ primary-for QTemporaryFile (0x7f0d40c493f0)
+ QIODevice (0x7f0d40c494d0) 0
+ primary-for QFile (0x7f0d40c49460)
+ QObject (0x7f0d40c49540) 0
+ primary-for QIODevice (0x7f0d40c494d0)
+
+Class QUrl
+ size=8 align=8
+ base size=8 base align=8
+QUrl (0x7f0d40c64af0) 0
+
+Class QXmlStreamStringRef
+ size=16 align=8
+ base size=16 base align=8
+QXmlStreamStringRef (0x7f0d40aed1c0) 0
+
+Class QXmlStreamAttribute
+ size=80 align=8
+ base size=73 base align=8
+QXmlStreamAttribute (0x7f0d40b0aa10) 0
+
+Class QXmlStreamAttributes
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamAttributes (0x7f0d40b33460) 0
+ QVector<QXmlStreamAttribute> (0x7f0d40b334d0) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=40 align=8
+ base size=40 base align=8
+QXmlStreamNamespaceDeclaration (0x7f0d40b33930) 0
+
+Class QXmlStreamNotationDeclaration
+ size=56 align=8
+ base size=56 base align=8
+QXmlStreamNotationDeclaration (0x7f0d40b74310) 0
+
+Class QXmlStreamEntityDeclaration
+ size=88 align=8
+ base size=88 base align=8
+QXmlStreamEntityDeclaration (0x7f0d40b8f1c0) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+16 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+24 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+32 QXmlStreamEntityResolver::resolveEntity
+40 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamEntityResolver (0x7f0d40bb1af0) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u)
+
+Class QXmlStreamReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamReader (0x7f0d40bb1cb0) 0
+
+Class QXmlStreamWriter
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamWriter (0x7f0d409f6d90) 0
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QAbstractState)
+16 QAbstractState::metaObject
+24 QAbstractState::qt_metacast
+32 QAbstractState::qt_metacall
+40 QAbstractState::~QAbstractState
+48 QAbstractState::~QAbstractState
+56 QAbstractState::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QAbstractState
+ size=16 align=8
+ base size=16 base align=8
+QAbstractState (0x7f0d40a02bd0) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u)
+ QObject (0x7f0d40a02c40) 0
+ primary-for QAbstractState (0x7f0d40a02bd0)
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTransition)
+16 QAbstractTransition::metaObject
+24 QAbstractTransition::qt_metacast
+32 QAbstractTransition::qt_metacall
+40 QAbstractTransition::~QAbstractTransition
+48 QAbstractTransition::~QAbstractTransition
+56 QAbstractTransition::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QAbstractTransition
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTransition (0x7f0d40a333f0) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u)
+ QObject (0x7f0d40a33460) 0
+ primary-for QAbstractTransition (0x7f0d40a333f0)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QEvent)
+16 QEvent::~QEvent
+24 QEvent::~QEvent
+
+Class QEvent
+ size=24 align=8
+ base size=20 base align=8
+QEvent (0x7f0d40a47c40) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 16u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTimerEvent)
+16 QTimerEvent::~QTimerEvent
+24 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=24 align=8
+ base size=24 base align=8
+QTimerEvent (0x7f0d40a68850) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u)
+ QEvent (0x7f0d40a688c0) 0
+ primary-for QTimerEvent (0x7f0d40a68850)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QChildEvent)
+16 QChildEvent::~QChildEvent
+24 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=32 align=8
+ base size=32 base align=8
+QChildEvent (0x7f0d40a68cb0) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u)
+ QEvent (0x7f0d40a68d20) 0
+ primary-for QChildEvent (0x7f0d40a68cb0)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QCustomEvent)
+16 QCustomEvent::~QCustomEvent
+24 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=24 align=8
+ base size=20 base align=8
+QCustomEvent (0x7f0d40a72f50) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 16u)
+ QEvent (0x7f0d40a81000) 0
+ primary-for QCustomEvent (0x7f0d40a72f50)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+16 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+24 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=32 align=8
+ base size=32 base align=8
+QDynamicPropertyChangeEvent (0x7f0d40a81770) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u)
+ QEvent (0x7f0d40a817e0) 0
+ primary-for QDynamicPropertyChangeEvent (0x7f0d40a81770)
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QEventTransition)
+16 QEventTransition::metaObject
+24 QEventTransition::qt_metacast
+32 QEventTransition::qt_metacall
+40 QEventTransition::~QEventTransition
+48 QEventTransition::~QEventTransition
+56 QEventTransition::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QEventTransition::eventTest
+120 QEventTransition::onTransition
+
+Class QEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QEventTransition (0x7f0d40a81c40) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u)
+ QAbstractTransition (0x7f0d40a81cb0) 0
+ primary-for QEventTransition (0x7f0d40a81c40)
+ QObject (0x7f0d40a81d20) 0
+ primary-for QAbstractTransition (0x7f0d40a81cb0)
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFinalState)
+16 QFinalState::metaObject
+24 QFinalState::qt_metacast
+32 QFinalState::qt_metacall
+40 QFinalState::~QFinalState
+48 QFinalState::~QFinalState
+56 QFinalState::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFinalState::onEntry
+120 QFinalState::onExit
+
+Class QFinalState
+ size=16 align=8
+ base size=16 base align=8
+QFinalState (0x7f0d40a9daf0) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 16u)
+ QAbstractState (0x7f0d40a9db60) 0
+ primary-for QFinalState (0x7f0d40a9daf0)
+ QObject (0x7f0d40a9dbd0) 0
+ primary-for QAbstractState (0x7f0d40a9db60)
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QHistoryState)
+16 QHistoryState::metaObject
+24 QHistoryState::qt_metacast
+32 QHistoryState::qt_metacall
+40 QHistoryState::~QHistoryState
+48 QHistoryState::~QHistoryState
+56 QHistoryState::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QHistoryState::onEntry
+120 QHistoryState::onExit
+
+Class QHistoryState
+ size=16 align=8
+ base size=16 base align=8
+QHistoryState (0x7f0d408b7380) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u)
+ QAbstractState (0x7f0d408b73f0) 0
+ primary-for QHistoryState (0x7f0d408b7380)
+ QObject (0x7f0d408b7460) 0
+ primary-for QAbstractState (0x7f0d408b73f0)
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSignalTransition)
+16 QSignalTransition::metaObject
+24 QSignalTransition::qt_metacast
+32 QSignalTransition::qt_metacall
+40 QSignalTransition::~QSignalTransition
+48 QSignalTransition::~QSignalTransition
+56 QSignalTransition::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QSignalTransition::eventTest
+120 QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=16 align=8
+ base size=16 base align=8
+QSignalTransition (0x7f0d408d10e0) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u)
+ QAbstractTransition (0x7f0d408d1150) 0
+ primary-for QSignalTransition (0x7f0d408d10e0)
+ QObject (0x7f0d408d11c0) 0
+ primary-for QAbstractTransition (0x7f0d408d1150)
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QState)
+16 QState::metaObject
+24 QState::qt_metacast
+32 QState::qt_metacall
+40 QState::~QState
+48 QState::~QState
+56 QState::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QState::onEntry
+120 QState::onExit
+
+Class QState
+ size=16 align=8
+ base size=16 base align=8
+QState (0x7f0d408e6c40) 0
+ vptr=((& QState::_ZTV6QState) + 16u)
+ QAbstractState (0x7f0d408e6cb0) 0
+ primary-for QState (0x7f0d408e6c40)
+ QObject (0x7f0d408e6d20) 0
+ primary-for QAbstractState (0x7f0d408e6cb0)
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+16 QStateMachine::SignalEvent::~SignalEvent
+24 QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=48 align=8
+ base size=48 base align=8
+QStateMachine::SignalEvent (0x7f0d4090a2a0) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u)
+ QEvent (0x7f0d4090a310) 0
+ primary-for QStateMachine::SignalEvent (0x7f0d4090a2a0)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+16 QStateMachine::WrappedEvent::~WrappedEvent
+24 QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=40 align=8
+ base size=40 base align=8
+QStateMachine::WrappedEvent (0x7f0d4090a850) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u)
+ QEvent (0x7f0d4090a8c0) 0
+ primary-for QStateMachine::WrappedEvent (0x7f0d4090a850)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStateMachine)
+16 QStateMachine::metaObject
+24 QStateMachine::qt_metacast
+32 QStateMachine::qt_metacall
+40 QStateMachine::~QStateMachine
+48 QStateMachine::~QStateMachine
+56 QStateMachine::event
+64 QStateMachine::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QStateMachine::onEntry
+120 QStateMachine::onExit
+128 QStateMachine::beginSelectTransitions
+136 QStateMachine::endSelectTransitions
+144 QStateMachine::beginMicrostep
+152 QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=16 align=8
+ base size=16 base align=8
+QStateMachine (0x7f0d4090a070) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u)
+ QState (0x7f0d4090a0e0) 0
+ primary-for QStateMachine (0x7f0d4090a070)
+ QAbstractState (0x7f0d4090a150) 0
+ primary-for QState (0x7f0d4090a0e0)
+ QObject (0x7f0d4090a1c0) 0
+ primary-for QAbstractState (0x7f0d4090a150)
+
+Class QBitArray
+ size=8 align=8
+ base size=8 base align=8
+QBitArray (0x7f0d4093a2a0) 0
+
+Class QBitRef
+ size=16 align=8
+ base size=12 base align=8
+QBitRef (0x7f0d4098df50) 0
+
+Class QByteArrayMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QByteArrayMatcher::Data (0x7f0d409a2c40) 0
+
+Class QByteArrayMatcher
+ size=1040 align=8
+ base size=1040 base align=8
+QByteArrayMatcher (0x7f0d409a2620) 0
+
+Class QCryptographicHash
+ size=8 align=8
+ base size=8 base align=8
+QCryptographicHash (0x7f0d407d32a0) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+16 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+24 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+32 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=16 align=8
+ base size=16 base align=8
+QtSharedPointer::ExternalRefCountData (0x7f0d408031c0) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 16u)
+
+Vtable for QtSharedPointer::ExternalRefCountWithDestroyFn
+QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN15QtSharedPointer29ExternalRefCountWithDestroyFnE)
+16 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+24 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+32 QtSharedPointer::ExternalRefCountWithDestroyFn::destroy
+
+Class QtSharedPointer::ExternalRefCountWithDestroyFn
+ size=24 align=8
+ base size=24 base align=8
+QtSharedPointer::ExternalRefCountWithDestroyFn (0x7f0d4081ba80) 0
+ vptr=((& QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE) + 16u)
+ QtSharedPointer::ExternalRefCountData (0x7f0d4081baf0) 0
+ primary-for QtSharedPointer::ExternalRefCountWithDestroyFn (0x7f0d4081ba80)
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0x7f0d408a0700) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0x7f0d406d2690) 0
+
+Class QDateTime
+ size=8 align=8
+ base size=8 base align=8
+QDateTime (0x7f0d406efc40) 0
+
+Class QEasingCurve
+ size=8 align=8
+ base size=8 base align=8
+QEasingCurve (0x7f0d40736150) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0x7f0d40746000) 0
+
+Class QPointF
+ size=16 align=8
+ base size=16 base align=8
+QPointF (0x7f0d40778c40) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0x7f0d407b6c40) 0
+
+Class QLineF
+ size=32 align=8
+ base size=32 base align=8
+QLineF (0x7f0d405ebaf0) 0
+
+Class QLinkedListData
+ size=32 align=8
+ base size=32 base align=8
+QLinkedListData (0x7f0d406465b0) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0x7f0d405064d0) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0x7f0d405322a0) 0
+
+Class QSizeF
+ size=16 align=8
+ base size=16 base align=8
+QSizeF (0x7f0d40574f50) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0x7f0d403c84d0) 0
+
+Class QRectF
+ size=32 align=8
+ base size=32 base align=8
+QRectF (0x7f0d40476e70) 0
+
+Class QLatin1Literal
+ size=16 align=8
+ base size=16 base align=8
+QLatin1Literal (0x7f0d40334000) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0x7f0d40334540) 0 empty
+
+Class QTextBoundaryFinder
+ size=48 align=8
+ base size=48 base align=8
+QTextBoundaryFinder (0x7f0d4036c4d0) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeLine)
+16 QTimeLine::metaObject
+24 QTimeLine::qt_metacast
+32 QTimeLine::qt_metacall
+40 QTimeLine::~QTimeLine
+48 QTimeLine::~QTimeLine
+56 QObject::event
+64 QObject::eventFilter
+72 QTimeLine::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=16 align=8
+ base size=16 base align=8
+QTimeLine (0x7f0d40378850) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u)
+ QObject (0x7f0d403788c0) 0
+ primary-for QTimeLine (0x7f0d40378850)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QRunnable)
+16 __cxa_pure_virtual
+24 QRunnable::~QRunnable
+32 QRunnable::~QRunnable
+
+Class QRunnable
+ size=16 align=8
+ base size=12 base align=8
+QRunnable (0x7f0d401c40e0) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 16u)
+
+Class QMutex
+ size=8 align=8
+ base size=8 base align=8
+QMutex (0x7f0d401da770) 0
+
+Class QMutexLocker
+ size=8 align=8
+ base size=8 base align=8
+QMutexLocker (0x7f0d401e9310) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+16 QtConcurrent::Exception::~Exception
+24 QtConcurrent::Exception::~Exception
+32 std::exception::what
+40 QtConcurrent::Exception::raise
+48 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::Exception (0x7f0d401ff620) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 16u)
+ std::exception (0x7f0d401ff690) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0x7f0d401ff620)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+16 QtConcurrent::UnhandledException::~UnhandledException
+24 QtConcurrent::UnhandledException::~UnhandledException
+32 std::exception::what
+40 QtConcurrent::UnhandledException::raise
+48 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::UnhandledException (0x7f0d401ff8c0) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 16u)
+ QtConcurrent::Exception (0x7f0d401ff930) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0x7f0d401ff8c0)
+ std::exception (0x7f0d401ff9a0) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0x7f0d401ff930)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::internal::ExceptionHolder (0x7f0d401ffbd0) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::internal::ExceptionStore (0x7f0d401fff50) 0
+
+Class QtConcurrent::ResultItem
+ size=16 align=8
+ base size=16 base align=8
+QtConcurrent::ResultItem (0x7f0d401ff850) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=16 align=8
+ base size=12 base align=8
+QtConcurrent::ResultIteratorBase (0x7f0d40217ee0) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+16 QtConcurrent::ResultStoreBase::~ResultStoreBase
+24 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=48 align=8
+ base size=44 base align=8
+QtConcurrent::ResultStoreBase (0x7f0d4021ba80) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 16u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+16 QFutureInterfaceBase::~QFutureInterfaceBase
+24 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureInterfaceBase (0x7f0d4025bee0) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u)
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+16 QFutureWatcherBase::metaObject
+24 QFutureWatcherBase::qt_metacast
+32 QFutureWatcherBase::qt_metacall
+40 QFutureWatcherBase::~QFutureWatcherBase
+48 QFutureWatcherBase::~QFutureWatcherBase
+56 QFutureWatcherBase::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QFutureWatcherBase::connectNotify
+104 QFutureWatcherBase::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureWatcherBase (0x7f0d4013f7e0) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u)
+ QObject (0x7f0d4013f850) 0
+ primary-for QFutureWatcherBase (0x7f0d4013f7e0)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QThread)
+16 QThread::metaObject
+24 QThread::qt_metacast
+32 QThread::qt_metacall
+40 QThread::~QThread
+48 QThread::~QThread
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QThread::run
+
+Class QThread
+ size=16 align=8
+ base size=16 base align=8
+QThread (0x7f0d40190bd0) 0
+ vptr=((& QThread::_ZTV7QThread) + 16u)
+ QObject (0x7f0d40190c40) 0
+ primary-for QThread (0x7f0d40190bd0)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QThreadPool)
+16 QThreadPool::metaObject
+24 QThreadPool::qt_metacast
+32 QThreadPool::qt_metacall
+40 QThreadPool::~QThreadPool
+48 QThreadPool::~QThreadPool
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QThreadPool
+ size=16 align=8
+ base size=16 base align=8
+QThreadPool (0x7f0d3ffb9a80) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u)
+ QObject (0x7f0d3ffb9af0) 0
+ primary-for QThreadPool (0x7f0d3ffb9a80)
+
+Class QWaitCondition
+ size=8 align=8
+ base size=8 base align=8
+QWaitCondition (0x7f0d3ffd2070) 0
+
+Class QSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSemaphore (0x7f0d3ffd25b0) 0
+
+Class QtConcurrent::ThreadEngineBarrier
+ size=24 align=8
+ base size=24 base align=8
+QtConcurrent::ThreadEngineBarrier (0x7f0d3ffd2af0) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+16 QtConcurrent::ThreadEngineBase::run
+24 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+32 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+40 QtConcurrent::ThreadEngineBase::start
+48 QtConcurrent::ThreadEngineBase::finish
+56 QtConcurrent::ThreadEngineBase::threadFunction
+64 QtConcurrent::ThreadEngineBase::shouldStartThread
+72 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+80 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=64 align=8
+ base size=64 base align=8
+QtConcurrent::ThreadEngineBase (0x7f0d3ffd2bd0) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 16u)
+ QRunnable (0x7f0d3ffd2c40) 0
+ primary-for QtConcurrent::ThreadEngineBase (0x7f0d3ffd2bd0)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 24u)
+8 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 136u)
+
+Class QtConcurrent::BlockSizeManager
+ size=96 align=8
+ base size=92 base align=8
+QtConcurrent::BlockSizeManager (0x7f0d40028070) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFactoryInterface)
+16 QFactoryInterface::~QFactoryInterface
+24 QFactoryInterface::~QFactoryInterface
+32 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QFactoryInterface (0x7f0d3fabfe70) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+16 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+24 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QTextCodecFactoryInterface (0x7f0d3faf5150) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 16u)
+ QFactoryInterface (0x7f0d3faf51c0) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0x7f0d3faf5150)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+16 QTextCodecPlugin::metaObject
+24 QTextCodecPlugin::qt_metacast
+32 QTextCodecPlugin::qt_metacall
+40 QTextCodecPlugin::~QTextCodecPlugin
+48 QTextCodecPlugin::~QTextCodecPlugin
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 QTextCodecPlugin::keys
+160 QTextCodecPlugin::create
+168 (int (*)(...))-0x00000000000000010
+176 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+184 QTextCodecPlugin::_ZThn16_N16QTextCodecPluginD1Ev
+192 QTextCodecPlugin::_ZThn16_N16QTextCodecPluginD0Ev
+200 QTextCodecPlugin::_ZThn16_NK16QTextCodecPlugin4keysEv
+208 QTextCodecPlugin::_ZThn16_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=24 align=8
+ base size=24 base align=8
+QTextCodecPlugin (0x7f0d3fafc600) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 16u)
+ QObject (0x7f0d3faf5bd0) 0
+ primary-for QTextCodecPlugin (0x7f0d3fafc600)
+ QTextCodecFactoryInterface (0x7f0d3faf5c40) 16 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 184u)
+ QFactoryInterface (0x7f0d3faf5cb0) 16 nearly-empty
+ primary-for QTextCodecFactoryInterface (0x7f0d3faf5c40)
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0x7f0d3fb4a2a0) 0 empty
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QEventLoop)
+16 QEventLoop::metaObject
+24 QEventLoop::qt_metacast
+32 QEventLoop::qt_metacall
+40 QEventLoop::~QEventLoop
+48 QEventLoop::~QEventLoop
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QEventLoop
+ size=16 align=8
+ base size=16 base align=8
+QEventLoop (0x7f0d3fb4a3f0) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u)
+ QObject (0x7f0d3fb4a460) 0
+ primary-for QEventLoop (0x7f0d3fb4a3f0)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+16 QAbstractEventDispatcher::metaObject
+24 QAbstractEventDispatcher::qt_metacast
+32 QAbstractEventDispatcher::qt_metacall
+40 QAbstractEventDispatcher::~QAbstractEventDispatcher
+48 QAbstractEventDispatcher::~QAbstractEventDispatcher
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+192 __cxa_pure_virtual
+200 QAbstractEventDispatcher::startingUp
+208 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=16 align=8
+ base size=16 base align=8
+QAbstractEventDispatcher (0x7f0d3fb85d20) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u)
+ QObject (0x7f0d3fb85d90) 0
+ primary-for QAbstractEventDispatcher (0x7f0d3fb85d20)
+
+Class QModelIndex
+ size=24 align=8
+ base size=24 base align=8
+QModelIndex (0x7f0d3f9acbd0) 0
+
+Class QPersistentModelIndex
+ size=8 align=8
+ base size=8 base align=8
+QPersistentModelIndex (0x7f0d3f9d9690) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractItemModel)
+16 QAbstractItemModel::metaObject
+24 QAbstractItemModel::qt_metacast
+32 QAbstractItemModel::qt_metacall
+40 QAbstractItemModel::~QAbstractItemModel
+48 QAbstractItemModel::~QAbstractItemModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 QAbstractItemModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractItemModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemModel (0x7f0d3f9e19a0) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u)
+ QObject (0x7f0d3f9e1a10) 0
+ primary-for QAbstractItemModel (0x7f0d3f9e19a0)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTableModel)
+16 QAbstractTableModel::metaObject
+24 QAbstractTableModel::qt_metacast
+32 QAbstractTableModel::qt_metacall
+40 QAbstractTableModel::~QAbstractTableModel
+48 QAbstractTableModel::~QAbstractTableModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 QAbstractTableModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTableModel (0x7f0d3fa3dcb0) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u)
+ QAbstractItemModel (0x7f0d3fa3dd20) 0
+ primary-for QAbstractTableModel (0x7f0d3fa3dcb0)
+ QObject (0x7f0d3fa3dd90) 0
+ primary-for QAbstractItemModel (0x7f0d3fa3dd20)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractListModel)
+16 QAbstractListModel::metaObject
+24 QAbstractListModel::qt_metacast
+32 QAbstractListModel::qt_metacall
+40 QAbstractListModel::~QAbstractListModel
+48 QAbstractListModel::~QAbstractListModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractListModel::index
+120 QAbstractListModel::parent
+128 __cxa_pure_virtual
+136 QAbstractListModel::columnCount
+144 QAbstractListModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractListModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractListModel (0x7f0d3fa58230) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u)
+ QAbstractItemModel (0x7f0d3fa582a0) 0
+ primary-for QAbstractListModel (0x7f0d3fa58230)
+ QObject (0x7f0d3fa58310) 0
+ primary-for QAbstractItemModel (0x7f0d3fa582a0)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0x7f0d3fa89380) 0
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QCoreApplication)
+16 QCoreApplication::metaObject
+24 QCoreApplication::qt_metacast
+32 QCoreApplication::qt_metacall
+40 QCoreApplication::~QCoreApplication
+48 QCoreApplication::~QCoreApplication
+56 QCoreApplication::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QCoreApplication::notify
+120 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=16 align=8
+ base size=16 base align=8
+QCoreApplication (0x7f0d3fa95770) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u)
+ QObject (0x7f0d3fa957e0) 0
+ primary-for QCoreApplication (0x7f0d3fa95770)
+
+Class __exception
+ size=40 align=8
+ base size=40 base align=8
+__exception (0x7f0d3f8cb460) 0
+
+Class QMetaMethod
+ size=16 align=8
+ base size=12 base align=8
+QMetaMethod (0x7f0d3f9388c0) 0
+
+Class QMetaEnum
+ size=16 align=8
+ base size=12 base align=8
+QMetaEnum (0x7f0d3f952d20) 0
+
+Class QMetaProperty
+ size=32 align=8
+ base size=32 base align=8
+QMetaProperty (0x7f0d3f961a80) 0
+
+Class QMetaClassInfo
+ size=16 align=8
+ base size=12 base align=8
+QMetaClassInfo (0x7f0d3f971150) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QMimeData)
+16 QMimeData::metaObject
+24 QMimeData::qt_metacast
+32 QMimeData::qt_metacall
+40 QMimeData::~QMimeData
+48 QMimeData::~QMimeData
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QMimeData::hasFormat
+120 QMimeData::formats
+128 QMimeData::retrieveData
+
+Class QMimeData
+ size=16 align=8
+ base size=16 base align=8
+QMimeData (0x7f0d3f971c40) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 16u)
+ QObject (0x7f0d3f971cb0) 0
+ primary-for QMimeData (0x7f0d3f971c40)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+16 QObjectCleanupHandler::metaObject
+24 QObjectCleanupHandler::qt_metacast
+32 QObjectCleanupHandler::qt_metacall
+40 QObjectCleanupHandler::~QObjectCleanupHandler
+48 QObjectCleanupHandler::~QObjectCleanupHandler
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=24 align=8
+ base size=24 base align=8
+QObjectCleanupHandler (0x7f0d3f9944d0) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u)
+ QObject (0x7f0d3f994540) 0
+ primary-for QObjectCleanupHandler (0x7f0d3f9944d0)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSharedMemory)
+16 QSharedMemory::metaObject
+24 QSharedMemory::qt_metacast
+32 QSharedMemory::qt_metacall
+40 QSharedMemory::~QSharedMemory
+48 QSharedMemory::~QSharedMemory
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=16 align=8
+ base size=16 base align=8
+QSharedMemory (0x7f0d3f9a6620) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u)
+ QObject (0x7f0d3f9a6690) 0
+ primary-for QSharedMemory (0x7f0d3f9a6620)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSignalMapper)
+16 QSignalMapper::metaObject
+24 QSignalMapper::qt_metacast
+32 QSignalMapper::qt_metacall
+40 QSignalMapper::~QSignalMapper
+48 QSignalMapper::~QSignalMapper
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=16 align=8
+ base size=16 base align=8
+QSignalMapper (0x7f0d3f7c23f0) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u)
+ QObject (0x7f0d3f7c2460) 0
+ primary-for QSignalMapper (0x7f0d3f7c23f0)
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSocketNotifier)
+16 QSocketNotifier::metaObject
+24 QSocketNotifier::qt_metacast
+32 QSocketNotifier::qt_metacall
+40 QSocketNotifier::~QSocketNotifier
+48 QSocketNotifier::~QSocketNotifier
+56 QSocketNotifier::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=32 align=8
+ base size=25 base align=8
+QSocketNotifier (0x7f0d3f7da7e0) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u)
+ QObject (0x7f0d3f7da850) 0
+ primary-for QSocketNotifier (0x7f0d3f7da7e0)
+
+Class QSystemSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSystemSemaphore (0x7f0d3f7f4b60) 0
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QTimer)
+16 QTimer::metaObject
+24 QTimer::qt_metacast
+32 QTimer::qt_metacall
+40 QTimer::~QTimer
+48 QTimer::~QTimer
+56 QObject::event
+64 QObject::eventFilter
+72 QTimer::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QTimer
+ size=32 align=8
+ base size=29 base align=8
+QTimer (0x7f0d3f8005b0) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 16u)
+ QObject (0x7f0d3f800620) 0
+ primary-for QTimer (0x7f0d3f8005b0)
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTranslator)
+16 QTranslator::metaObject
+24 QTranslator::qt_metacast
+32 QTranslator::qt_metacall
+40 QTranslator::~QTranslator
+48 QTranslator::~QTranslator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTranslator::translate
+120 QTranslator::isEmpty
+
+Class QTranslator
+ size=16 align=8
+ base size=16 base align=8
+QTranslator (0x7f0d3f825af0) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 16u)
+ QObject (0x7f0d3f825b60) 0
+ primary-for QTranslator (0x7f0d3f825af0)
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QLibrary)
+16 QLibrary::metaObject
+24 QLibrary::qt_metacast
+32 QLibrary::qt_metacall
+40 QLibrary::~QLibrary
+48 QLibrary::~QLibrary
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QLibrary
+ size=32 align=8
+ base size=25 base align=8
+QLibrary (0x7f0d3f840a80) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 16u)
+ QObject (0x7f0d3f840af0) 0
+ primary-for QLibrary (0x7f0d3f840a80)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPluginLoader)
+16 QPluginLoader::metaObject
+24 QPluginLoader::qt_metacast
+32 QPluginLoader::qt_metacall
+40 QPluginLoader::~QPluginLoader
+48 QPluginLoader::~QPluginLoader
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=32 align=8
+ base size=25 base align=8
+QPluginLoader (0x7f0d3f88f540) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u)
+ QObject (0x7f0d3f88f5b0) 0
+ primary-for QPluginLoader (0x7f0d3f88f540)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0x7f0d3f897d20) 0
+
+Class QReadWriteLock
+ size=8 align=8
+ base size=8 base align=8
+QReadWriteLock (0x7f0d3f6c4620) 0
+
+Class QReadLocker
+ size=8 align=8
+ base size=8 base align=8
+QReadLocker (0x7f0d3f6c4cb0) 0
+
+Class QWriteLocker
+ size=8 align=8
+ base size=8 base align=8
+QWriteLocker (0x7f0d3f6ea070) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0x7f0d3f6fa3f0) 0
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractAnimation)
+16 QAbstractAnimation::metaObject
+24 QAbstractAnimation::qt_metacast
+32 QAbstractAnimation::qt_metacall
+40 QAbstractAnimation::~QAbstractAnimation
+48 QAbstractAnimation::~QAbstractAnimation
+56 QAbstractAnimation::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 QAbstractAnimation::updateState
+136 QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=16 align=8
+ base size=16 base align=8
+QAbstractAnimation (0x7f0d3f6fab60) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u)
+ QObject (0x7f0d3f6fabd0) 0
+ primary-for QAbstractAnimation (0x7f0d3f6fab60)
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAnimationGroup)
+16 QAnimationGroup::metaObject
+24 QAnimationGroup::qt_metacast
+32 QAnimationGroup::qt_metacall
+40 QAnimationGroup::~QAnimationGroup
+48 QAnimationGroup::~QAnimationGroup
+56 QAnimationGroup::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 QAbstractAnimation::updateState
+136 QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QAnimationGroup (0x7f0d3f7332a0) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u)
+ QAbstractAnimation (0x7f0d3f733310) 0
+ primary-for QAnimationGroup (0x7f0d3f7332a0)
+ QObject (0x7f0d3f733380) 0
+ primary-for QAbstractAnimation (0x7f0d3f733310)
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+16 QParallelAnimationGroup::metaObject
+24 QParallelAnimationGroup::qt_metacast
+32 QParallelAnimationGroup::qt_metacall
+40 QParallelAnimationGroup::~QParallelAnimationGroup
+48 QParallelAnimationGroup::~QParallelAnimationGroup
+56 QParallelAnimationGroup::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QParallelAnimationGroup::duration
+120 QParallelAnimationGroup::updateCurrentTime
+128 QParallelAnimationGroup::updateState
+136 QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QParallelAnimationGroup (0x7f0d3f74d150) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u)
+ QAnimationGroup (0x7f0d3f74d1c0) 0
+ primary-for QParallelAnimationGroup (0x7f0d3f74d150)
+ QAbstractAnimation (0x7f0d3f74d230) 0
+ primary-for QAnimationGroup (0x7f0d3f74d1c0)
+ QObject (0x7f0d3f74d2a0) 0
+ primary-for QAbstractAnimation (0x7f0d3f74d230)
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QPauseAnimation)
+16 QPauseAnimation::metaObject
+24 QPauseAnimation::qt_metacast
+32 QPauseAnimation::qt_metacall
+40 QPauseAnimation::~QPauseAnimation
+48 QPauseAnimation::~QPauseAnimation
+56 QPauseAnimation::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QPauseAnimation::duration
+120 QPauseAnimation::updateCurrentTime
+128 QAbstractAnimation::updateState
+136 QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPauseAnimation (0x7f0d3f765000) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u)
+ QAbstractAnimation (0x7f0d3f765070) 0
+ primary-for QPauseAnimation (0x7f0d3f765000)
+ QObject (0x7f0d3f7650e0) 0
+ primary-for QAbstractAnimation (0x7f0d3f765070)
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QVariantAnimation)
+16 QVariantAnimation::metaObject
+24 QVariantAnimation::qt_metacast
+32 QVariantAnimation::qt_metacall
+40 QVariantAnimation::~QVariantAnimation
+48 QVariantAnimation::~QVariantAnimation
+56 QVariantAnimation::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QVariantAnimation::duration
+120 QVariantAnimation::updateCurrentTime
+128 QVariantAnimation::updateState
+136 QAbstractAnimation::updateDirection
+144 __cxa_pure_virtual
+152 QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=16 align=8
+ base size=16 base align=8
+QVariantAnimation (0x7f0d3f779a10) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u)
+ QAbstractAnimation (0x7f0d3f779a80) 0
+ primary-for QVariantAnimation (0x7f0d3f779a10)
+ QObject (0x7f0d3f779af0) 0
+ primary-for QAbstractAnimation (0x7f0d3f779a80)
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPropertyAnimation)
+16 QPropertyAnimation::metaObject
+24 QPropertyAnimation::qt_metacast
+32 QPropertyAnimation::qt_metacall
+40 QPropertyAnimation::~QPropertyAnimation
+48 QPropertyAnimation::~QPropertyAnimation
+56 QPropertyAnimation::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QVariantAnimation::duration
+120 QVariantAnimation::updateCurrentTime
+128 QPropertyAnimation::updateState
+136 QAbstractAnimation::updateDirection
+144 QPropertyAnimation::updateCurrentValue
+152 QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPropertyAnimation (0x7f0d3f797cb0) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u)
+ QVariantAnimation (0x7f0d3f797d20) 0
+ primary-for QPropertyAnimation (0x7f0d3f797cb0)
+ QAbstractAnimation (0x7f0d3f797d90) 0
+ primary-for QVariantAnimation (0x7f0d3f797d20)
+ QObject (0x7f0d3f797e00) 0
+ primary-for QAbstractAnimation (0x7f0d3f797d90)
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+16 QSequentialAnimationGroup::metaObject
+24 QSequentialAnimationGroup::qt_metacast
+32 QSequentialAnimationGroup::qt_metacall
+40 QSequentialAnimationGroup::~QSequentialAnimationGroup
+48 QSequentialAnimationGroup::~QSequentialAnimationGroup
+56 QSequentialAnimationGroup::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QSequentialAnimationGroup::duration
+120 QSequentialAnimationGroup::updateCurrentTime
+128 QSequentialAnimationGroup::updateState
+136 QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QSequentialAnimationGroup (0x7f0d3f5afcb0) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u)
+ QAnimationGroup (0x7f0d3f5afd20) 0
+ primary-for QSequentialAnimationGroup (0x7f0d3f5afcb0)
+ QAbstractAnimation (0x7f0d3f5afd90) 0
+ primary-for QAnimationGroup (0x7f0d3f5afd20)
+ QObject (0x7f0d3f5afe00) 0
+ primary-for QAbstractAnimation (0x7f0d3f5afd90)
+
+Class QDomImplementation
+ size=8 align=8
+ base size=8 base align=8
+QDomImplementation (0x7f0d3f5c9d20) 0
+
+Class QDomNode
+ size=8 align=8
+ base size=8 base align=8
+QDomNode (0x7f0d3f5d7690) 0
+
+Class QDomNodeList
+ size=8 align=8
+ base size=8 base align=8
+QDomNodeList (0x7f0d3f5e68c0) 0
+
+Class QDomDocumentType
+ size=8 align=8
+ base size=8 base align=8
+QDomDocumentType (0x7f0d3f5fd930) 0
+ QDomNode (0x7f0d3f5fd9a0) 0
+
+Class QDomDocument
+ size=8 align=8
+ base size=8 base align=8
+QDomDocument (0x7f0d3f6054d0) 0
+ QDomNode (0x7f0d3f605540) 0
+
+Class QDomNamedNodeMap
+ size=8 align=8
+ base size=8 base align=8
+QDomNamedNodeMap (0x7f0d3f6113f0) 0
+
+Class QDomDocumentFragment
+ size=8 align=8
+ base size=8 base align=8
+QDomDocumentFragment (0x7f0d3f625230) 0
+ QDomNode (0x7f0d3f6252a0) 0
+
+Class QDomCharacterData
+ size=8 align=8
+ base size=8 base align=8
+QDomCharacterData (0x7f0d3f625d90) 0
+ QDomNode (0x7f0d3f625e00) 0
+
+Class QDomAttr
+ size=8 align=8
+ base size=8 base align=8
+QDomAttr (0x7f0d3f62b7e0) 0
+ QDomNode (0x7f0d3f62b850) 0
+
+Class QDomElement
+ size=8 align=8
+ base size=8 base align=8
+QDomElement (0x7f0d3f634380) 0
+ QDomNode (0x7f0d3f6343f0) 0
+
+Class QDomText
+ size=8 align=8
+ base size=8 base align=8
+QDomText (0x7f0d3f648620) 0
+ QDomCharacterData (0x7f0d3f648690) 0
+ QDomNode (0x7f0d3f648700) 0
+
+Class QDomComment
+ size=8 align=8
+ base size=8 base align=8
+QDomComment (0x7f0d3f64e380) 0
+ QDomCharacterData (0x7f0d3f64e3f0) 0
+ QDomNode (0x7f0d3f64e460) 0
+
+Class QDomCDATASection
+ size=8 align=8
+ base size=8 base align=8
+QDomCDATASection (0x7f0d3f64ef50) 0
+ QDomText (0x7f0d3f656000) 0
+ QDomCharacterData (0x7f0d3f656070) 0
+ QDomNode (0x7f0d3f6560e0) 0
+
+Class QDomNotation
+ size=8 align=8
+ base size=8 base align=8
+QDomNotation (0x7f0d3f656bd0) 0
+ QDomNode (0x7f0d3f656c40) 0
+
+Class QDomEntity
+ size=8 align=8
+ base size=8 base align=8
+QDomEntity (0x7f0d3f65b770) 0
+ QDomNode (0x7f0d3f65b7e0) 0
+
+Class QDomEntityReference
+ size=8 align=8
+ base size=8 base align=8
+QDomEntityReference (0x7f0d3f662310) 0
+ QDomNode (0x7f0d3f662380) 0
+
+Class QDomProcessingInstruction
+ size=8 align=8
+ base size=8 base align=8
+QDomProcessingInstruction (0x7f0d3f662e70) 0
+ QDomNode (0x7f0d3f662ee0) 0
+
+Class QXmlNamespaceSupport
+ size=8 align=8
+ base size=8 base align=8
+QXmlNamespaceSupport (0x7f0d3f668a10) 0
+
+Class QXmlAttributes::Attribute
+ size=32 align=8
+ base size=32 base align=8
+QXmlAttributes::Attribute (0x7f0d3f6760e0) 0
+
+Vtable for QXmlAttributes
+QXmlAttributes::_ZTV14QXmlAttributes: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QXmlAttributes)
+16 QXmlAttributes::~QXmlAttributes
+24 QXmlAttributes::~QXmlAttributes
+
+Class QXmlAttributes
+ size=24 align=8
+ base size=24 base align=8
+QXmlAttributes (0x7f0d3f668f50) 0
+ vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 16u)
+
+Vtable for QXmlInputSource
+QXmlInputSource::_ZTV15QXmlInputSource: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QXmlInputSource)
+16 QXmlInputSource::~QXmlInputSource
+24 QXmlInputSource::~QXmlInputSource
+32 QXmlInputSource::setData
+40 QXmlInputSource::setData
+48 QXmlInputSource::fetchData
+56 QXmlInputSource::data
+64 QXmlInputSource::next
+72 QXmlInputSource::reset
+80 QXmlInputSource::fromRawData
+
+Class QXmlInputSource
+ size=16 align=8
+ base size=16 base align=8
+QXmlInputSource (0x7f0d3f4a87e0) 0
+ vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 16u)
+
+Class QXmlParseException
+ size=8 align=8
+ base size=8 base align=8
+QXmlParseException (0x7f0d3f4a8af0) 0
+
+Vtable for QXmlReader
+QXmlReader::_ZTV10QXmlReader: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QXmlReader)
+16 QXmlReader::~QXmlReader
+24 QXmlReader::~QXmlReader
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+
+Class QXmlReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlReader (0x7f0d3f4a8a80) 0 nearly-empty
+ vptr=((& QXmlReader::_ZTV10QXmlReader) + 16u)
+
+Vtable for QXmlSimpleReader
+QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QXmlSimpleReader)
+16 QXmlSimpleReader::~QXmlSimpleReader
+24 QXmlSimpleReader::~QXmlSimpleReader
+32 QXmlSimpleReader::feature
+40 QXmlSimpleReader::setFeature
+48 QXmlSimpleReader::hasFeature
+56 QXmlSimpleReader::property
+64 QXmlSimpleReader::setProperty
+72 QXmlSimpleReader::hasProperty
+80 QXmlSimpleReader::setEntityResolver
+88 QXmlSimpleReader::entityResolver
+96 QXmlSimpleReader::setDTDHandler
+104 QXmlSimpleReader::DTDHandler
+112 QXmlSimpleReader::setContentHandler
+120 QXmlSimpleReader::contentHandler
+128 QXmlSimpleReader::setErrorHandler
+136 QXmlSimpleReader::errorHandler
+144 QXmlSimpleReader::setLexicalHandler
+152 QXmlSimpleReader::lexicalHandler
+160 QXmlSimpleReader::setDeclHandler
+168 QXmlSimpleReader::declHandler
+176 QXmlSimpleReader::parse
+184 QXmlSimpleReader::parse
+192 QXmlSimpleReader::parse
+200 QXmlSimpleReader::parseContinue
+
+Class QXmlSimpleReader
+ size=16 align=8
+ base size=16 base align=8
+QXmlSimpleReader (0x7f0d3f4ca930) 0
+ vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 16u)
+ QXmlReader (0x7f0d3f4ca9a0) 0 nearly-empty
+ primary-for QXmlSimpleReader (0x7f0d3f4ca930)
+
+Vtable for QXmlLocator
+QXmlLocator::_ZTV11QXmlLocator: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QXmlLocator)
+16 QXmlLocator::~QXmlLocator
+24 QXmlLocator::~QXmlLocator
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QXmlLocator
+ size=8 align=8
+ base size=8 base align=8
+QXmlLocator (0x7f0d3f4e8540) 0 nearly-empty
+ vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 16u)
+
+Vtable for QXmlContentHandler
+QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlContentHandler)
+16 QXmlContentHandler::~QXmlContentHandler
+24 QXmlContentHandler::~QXmlContentHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QXmlContentHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlContentHandler (0x7f0d3f4e8770) 0 nearly-empty
+ vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 16u)
+
+Vtable for QXmlErrorHandler
+QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QXmlErrorHandler)
+16 QXmlErrorHandler::~QXmlErrorHandler
+24 QXmlErrorHandler::~QXmlErrorHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+
+Class QXmlErrorHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlErrorHandler (0x7f0d3f4f80e0) 0 nearly-empty
+ vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 16u)
+
+Vtable for QXmlDTDHandler
+QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QXmlDTDHandler)
+16 QXmlDTDHandler::~QXmlDTDHandler
+24 QXmlDTDHandler::~QXmlDTDHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QXmlDTDHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlDTDHandler (0x7f0d3f4f8af0) 0 nearly-empty
+ vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 16u)
+
+Vtable for QXmlEntityResolver
+QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlEntityResolver)
+16 QXmlEntityResolver::~QXmlEntityResolver
+24 QXmlEntityResolver::~QXmlEntityResolver
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QXmlEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlEntityResolver (0x7f0d3f507460) 0 nearly-empty
+ vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 16u)
+
+Vtable for QXmlLexicalHandler
+QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlLexicalHandler)
+16 QXmlLexicalHandler::~QXmlLexicalHandler
+24 QXmlLexicalHandler::~QXmlLexicalHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QXmlLexicalHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlLexicalHandler (0x7f0d3f507ee0) 0 nearly-empty
+ vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 16u)
+
+Vtable for QXmlDeclHandler
+QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QXmlDeclHandler)
+16 QXmlDeclHandler::~QXmlDeclHandler
+24 QXmlDeclHandler::~QXmlDeclHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+
+Class QXmlDeclHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlDeclHandler (0x7f0d3f518850) 0 nearly-empty
+ vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 16u)
+
+Vtable for QXmlDefaultHandler
+QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+16 QXmlDefaultHandler::~QXmlDefaultHandler
+24 QXmlDefaultHandler::~QXmlDefaultHandler
+32 QXmlDefaultHandler::setDocumentLocator
+40 QXmlDefaultHandler::startDocument
+48 QXmlDefaultHandler::endDocument
+56 QXmlDefaultHandler::startPrefixMapping
+64 QXmlDefaultHandler::endPrefixMapping
+72 QXmlDefaultHandler::startElement
+80 QXmlDefaultHandler::endElement
+88 QXmlDefaultHandler::characters
+96 QXmlDefaultHandler::ignorableWhitespace
+104 QXmlDefaultHandler::processingInstruction
+112 QXmlDefaultHandler::skippedEntity
+120 QXmlDefaultHandler::errorString
+128 QXmlDefaultHandler::warning
+136 QXmlDefaultHandler::error
+144 QXmlDefaultHandler::fatalError
+152 QXmlDefaultHandler::notationDecl
+160 QXmlDefaultHandler::unparsedEntityDecl
+168 QXmlDefaultHandler::resolveEntity
+176 QXmlDefaultHandler::startDTD
+184 QXmlDefaultHandler::endDTD
+192 QXmlDefaultHandler::startEntity
+200 QXmlDefaultHandler::endEntity
+208 QXmlDefaultHandler::startCDATA
+216 QXmlDefaultHandler::endCDATA
+224 QXmlDefaultHandler::comment
+232 QXmlDefaultHandler::attributeDecl
+240 QXmlDefaultHandler::internalEntityDecl
+248 QXmlDefaultHandler::externalEntityDecl
+256 (int (*)(...))-0x00000000000000008
+264 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+272 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev
+280 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev
+288 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler7warningERK18QXmlParseException
+296 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler5errorERK18QXmlParseException
+304 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException
+312 QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv
+320 (int (*)(...))-0x00000000000000010
+328 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+336 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev
+344 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev
+352 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_
+360 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_
+368 QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv
+376 (int (*)(...))-0x00000000000000018
+384 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+392 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandlerD1Ev
+400 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandlerD0Ev
+408 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource
+416 QXmlDefaultHandler::_ZThn24_NK18QXmlDefaultHandler11errorStringEv
+424 (int (*)(...))-0x00000000000000020
+432 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+440 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandlerD1Ev
+448 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandlerD0Ev
+456 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_
+464 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler6endDTDEv
+472 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler11startEntityERK7QString
+480 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler9endEntityERK7QString
+488 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler10startCDATAEv
+496 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler8endCDATAEv
+504 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler7commentERK7QString
+512 QXmlDefaultHandler::_ZThn32_NK18QXmlDefaultHandler11errorStringEv
+520 (int (*)(...))-0x00000000000000028
+528 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+536 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandlerD1Ev
+544 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandlerD0Ev
+552 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_
+560 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_
+568 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_
+576 QXmlDefaultHandler::_ZThn40_NK18QXmlDefaultHandler11errorStringEv
+
+Class QXmlDefaultHandler
+ size=56 align=8
+ base size=56 base align=8
+QXmlDefaultHandler (0x7f0d3f51f6e0) 0
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 16u)
+ QXmlContentHandler (0x7f0d3f525230) 0 nearly-empty
+ primary-for QXmlDefaultHandler (0x7f0d3f51f6e0)
+ QXmlErrorHandler (0x7f0d3f5252a0) 8 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 272u)
+ QXmlDTDHandler (0x7f0d3f525310) 16 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 336u)
+ QXmlEntityResolver (0x7f0d3f525380) 24 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 392u)
+ QXmlLexicalHandler (0x7f0d3f5253f0) 32 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 440u)
+ QXmlDeclHandler (0x7f0d3f525460) 40 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 536u)
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintDevice)
+16 QPaintDevice::~QPaintDevice
+24 QPaintDevice::~QPaintDevice
+32 QPaintDevice::devType
+40 __cxa_pure_virtual
+48 QPaintDevice::metric
+
+Class QPaintDevice
+ size=16 align=8
+ base size=10 base align=8
+QPaintDevice (0x7f0d3f56ed90) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0x7f0d3f5a5700) 0
+
+Class QPolygon
+ size=8 align=8
+ base size=8 base align=8
+QPolygon (0x7f0d3f3fcee0) 0
+ QVector<QPoint> (0x7f0d3f3fcf50) 0
+
+Class QPolygonF
+ size=8 align=8
+ base size=8 base align=8
+QPolygonF (0x7f0d3f44a460) 0
+ QVector<QPointF> (0x7f0d3f44a4d0) 0
+
+Class QRegion::QRegionData
+ size=32 align=8
+ base size=32 base align=8
+QRegion::QRegionData (0x7f0d3f4a4ee0) 0
+
+Class QRegion
+ size=8 align=8
+ base size=8 base align=8
+QRegion (0x7f0d3f48a5b0) 0
+
+Class QMatrix
+ size=48 align=8
+ base size=48 base align=8
+QMatrix (0x7f0d3f2bf700) 0
+
+Class QPainterPath::Element
+ size=24 align=8
+ base size=24 base align=8
+QPainterPath::Element (0x7f0d3f302850) 0
+
+Class QPainterPath
+ size=8 align=8
+ base size=8 base align=8
+QPainterPath (0x7f0d3f3027e0) 0
+
+Class QPainterPathPrivate
+ size=16 align=8
+ base size=16 base align=8
+QPainterPathPrivate (0x7f0d3f355f50) 0
+
+Class QPainterPathStroker
+ size=8 align=8
+ base size=8 base align=8
+QPainterPathStroker (0x7f0d3f35ea80) 0
+
+Class QTransform
+ size=88 align=8
+ base size=88 base align=8
+QTransform (0x7f0d3f1caa80) 0
+
+Class QImageTextKeyLang
+ size=16 align=8
+ base size=16 base align=8
+QImageTextKeyLang (0x7f0d3f2770e0) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QImage)
+16 QImage::~QImage
+24 QImage::~QImage
+32 QImage::devType
+40 QImage::paintEngine
+48 QImage::metric
+
+Class QImage
+ size=24 align=8
+ base size=24 base align=8
+QImage (0x7f0d3f2a1930) 0
+ vptr=((& QImage::_ZTV6QImage) + 16u)
+ QPaintDevice (0x7f0d3f2a19a0) 0
+ primary-for QImage (0x7f0d3f2a1930)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QPixmap)
+16 QPixmap::~QPixmap
+24 QPixmap::~QPixmap
+32 QPixmap::devType
+40 QPixmap::paintEngine
+48 QPixmap::metric
+
+Class QPixmap
+ size=24 align=8
+ base size=24 base align=8
+QPixmap (0x7f0d3f1480e0) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 16u)
+ QPaintDevice (0x7f0d3f148150) 0
+ primary-for QPixmap (0x7f0d3f1480e0)
+
+Class QBrush
+ size=8 align=8
+ base size=8 base align=8
+QBrush (0x7f0d3f1a63f0) 0
+
+Class QBrushData
+ size=112 align=8
+ base size=112 base align=8
+QBrushData (0x7f0d3efc0e00) 0
+
+Class QGradient
+ size=64 align=8
+ base size=64 base align=8
+QGradient (0x7f0d3efe6000) 0
+
+Class QLinearGradient
+ size=64 align=8
+ base size=64 base align=8
+QLinearGradient (0x7f0d3f014a80) 0
+ QGradient (0x7f0d3f014af0) 0
+
+Class QRadialGradient
+ size=64 align=8
+ base size=64 base align=8
+QRadialGradient (0x7f0d3f014f50) 0
+ QGradient (0x7f0d3f021000) 0
+
+Class QConicalGradient
+ size=64 align=8
+ base size=64 base align=8
+QConicalGradient (0x7f0d3f021540) 0
+ QGradient (0x7f0d3f0215b0) 0
+
+Class QPalette
+ size=16 align=8
+ base size=12 base align=8
+QPalette (0x7f0d3f0218c0) 0
+
+Class QColorGroup
+ size=16 align=8
+ base size=12 base align=8
+QColorGroup (0x7f0d3f07e230) 0
+ QPalette (0x7f0d3f07e2a0) 0
+
+Class QFont
+ size=16 align=8
+ base size=12 base align=8
+QFont (0x7f0d3eeb6540) 0
+
+Class QFontMetrics
+ size=8 align=8
+ base size=8 base align=8
+QFontMetrics (0x7f0d3eeff230) 0
+
+Class QFontMetricsF
+ size=8 align=8
+ base size=8 base align=8
+QFontMetricsF (0x7f0d3ef13690) 0
+
+Class QFontInfo
+ size=8 align=8
+ base size=8 base align=8
+QFontInfo (0x7f0d3ef275b0) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0x7f0d3ef340e0) 0
+
+Class QCursor
+ size=8 align=8
+ base size=8 base align=8
+QCursor (0x7f0d3edf80e0) 0
+
+Class QKeySequence
+ size=8 align=8
+ base size=8 base align=8
+QKeySequence (0x7f0d3edf88c0) 0
+
+Class QWidgetData
+ size=88 align=8
+ base size=88 base align=8
+QWidgetData (0x7f0d3ee41230) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWidget)
+16 QWidget::metaObject
+24 QWidget::qt_metacast
+32 QWidget::qt_metacall
+40 QWidget::~QWidget
+48 QWidget::~QWidget
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI7QWidget)
+464 QWidget::_ZThn16_N7QWidgetD1Ev
+472 QWidget::_ZThn16_N7QWidgetD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=40 align=8
+ base size=40 base align=8
+QWidget (0x7f0d3ee33d00) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 16u)
+ QObject (0x7f0d3ee412a0) 0
+ primary-for QWidget (0x7f0d3ee33d00)
+ QPaintDevice (0x7f0d3ee41310) 16
+ vptr=((& QWidget::_ZTV7QWidget) + 464u)
+
+Vtable for QDesignerActionEditorInterface
+QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+16 QDesignerActionEditorInterface::metaObject
+24 QDesignerActionEditorInterface::qt_metacast
+32 QDesignerActionEditorInterface::qt_metacall
+40 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+48 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QDesignerActionEditorInterface::core
+456 __cxa_pure_virtual
+464 __cxa_pure_virtual
+472 __cxa_pure_virtual
+480 (int (*)(...))-0x00000000000000010
+488 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+496 QDesignerActionEditorInterface::_ZThn16_N30QDesignerActionEditorInterfaceD1Ev
+504 QDesignerActionEditorInterface::_ZThn16_N30QDesignerActionEditorInterfaceD0Ev
+512 QWidget::_ZThn16_NK7QWidget7devTypeEv
+520 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+528 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerActionEditorInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerActionEditorInterface (0x7f0d3ebbc310) 0
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 16u)
+ QWidget (0x7f0d3ebb5980) 0
+ primary-for QDesignerActionEditorInterface (0x7f0d3ebbc310)
+ QObject (0x7f0d3ebbc380) 0
+ primary-for QWidget (0x7f0d3ebb5980)
+ QPaintDevice (0x7f0d3ebbc3f0) 16
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 496u)
+
+Vtable for QDesignerBrushManagerInterface
+QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface: 21u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QDesignerBrushManagerInterface)
+16 QDesignerBrushManagerInterface::metaObject
+24 QDesignerBrushManagerInterface::qt_metacast
+32 QDesignerBrushManagerInterface::qt_metacall
+40 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+48 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+
+Class QDesignerBrushManagerInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerBrushManagerInterface (0x7f0d3ebd32a0) 0
+ vptr=((& QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface) + 16u)
+ QObject (0x7f0d3ebd3310) 0
+ primary-for QDesignerBrushManagerInterface (0x7f0d3ebd32a0)
+
+Vtable for QDesignerDnDItemInterface
+QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QDesignerDnDItemInterface)
+16 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+24 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerDnDItemInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerDnDItemInterface (0x7f0d3ebe7850) 0 nearly-empty
+ vptr=((& QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface) + 16u)
+
+Vtable for QDesignerFormEditorInterface
+QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QDesignerFormEditorInterface)
+16 QDesignerFormEditorInterface::metaObject
+24 QDesignerFormEditorInterface::qt_metacast
+32 QDesignerFormEditorInterface::qt_metacall
+40 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+48 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QDesignerFormEditorInterface
+ size=120 align=8
+ base size=120 base align=8
+QDesignerFormEditorInterface (0x7f0d3ebf27e0) 0
+ vptr=((& QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface) + 16u)
+ QObject (0x7f0d3ebf2850) 0
+ primary-for QDesignerFormEditorInterface (0x7f0d3ebf27e0)
+
+Vtable for QDesignerFormEditorPluginInterface
+QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI34QDesignerFormEditorPluginInterface)
+16 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+24 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+
+Class QDesignerFormEditorPluginInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerFormEditorPluginInterface (0x7f0d3ec54000) 0 nearly-empty
+ vptr=((& QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface) + 16u)
+
+Vtable for QDesignerFormWindowInterface
+QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface: 114u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+16 QDesignerFormWindowInterface::metaObject
+24 QDesignerFormWindowInterface::qt_metacast
+32 QDesignerFormWindowInterface::qt_metacall
+40 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+48 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 __cxa_pure_virtual
+456 __cxa_pure_virtual
+464 __cxa_pure_virtual
+472 __cxa_pure_virtual
+480 __cxa_pure_virtual
+488 __cxa_pure_virtual
+496 __cxa_pure_virtual
+504 __cxa_pure_virtual
+512 __cxa_pure_virtual
+520 __cxa_pure_virtual
+528 __cxa_pure_virtual
+536 __cxa_pure_virtual
+544 __cxa_pure_virtual
+552 __cxa_pure_virtual
+560 __cxa_pure_virtual
+568 __cxa_pure_virtual
+576 __cxa_pure_virtual
+584 __cxa_pure_virtual
+592 __cxa_pure_virtual
+600 __cxa_pure_virtual
+608 QDesignerFormWindowInterface::core
+616 __cxa_pure_virtual
+624 __cxa_pure_virtual
+632 __cxa_pure_virtual
+640 __cxa_pure_virtual
+648 __cxa_pure_virtual
+656 __cxa_pure_virtual
+664 __cxa_pure_virtual
+672 __cxa_pure_virtual
+680 __cxa_pure_virtual
+688 __cxa_pure_virtual
+696 __cxa_pure_virtual
+704 __cxa_pure_virtual
+712 __cxa_pure_virtual
+720 __cxa_pure_virtual
+728 __cxa_pure_virtual
+736 __cxa_pure_virtual
+744 __cxa_pure_virtual
+752 __cxa_pure_virtual
+760 __cxa_pure_virtual
+768 __cxa_pure_virtual
+776 __cxa_pure_virtual
+784 __cxa_pure_virtual
+792 __cxa_pure_virtual
+800 __cxa_pure_virtual
+808 __cxa_pure_virtual
+816 __cxa_pure_virtual
+824 __cxa_pure_virtual
+832 __cxa_pure_virtual
+840 __cxa_pure_virtual
+848 __cxa_pure_virtual
+856 (int (*)(...))-0x00000000000000010
+864 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+872 QDesignerFormWindowInterface::_ZThn16_N28QDesignerFormWindowInterfaceD1Ev
+880 QDesignerFormWindowInterface::_ZThn16_N28QDesignerFormWindowInterfaceD0Ev
+888 QWidget::_ZThn16_NK7QWidget7devTypeEv
+896 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+904 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerFormWindowInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerFormWindowInterface (0x7f0d3ec77310) 0
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 16u)
+ QWidget (0x7f0d3ec74580) 0
+ primary-for QDesignerFormWindowInterface (0x7f0d3ec77310)
+ QObject (0x7f0d3ec77380) 0
+ primary-for QWidget (0x7f0d3ec74580)
+ QPaintDevice (0x7f0d3ec773f0) 16
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 872u)
+
+Vtable for QDesignerFormWindowCursorInterface
+QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI34QDesignerFormWindowCursorInterface)
+16 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+24 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+
+Class QDesignerFormWindowCursorInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerFormWindowCursorInterface (0x7f0d3eaa0770) 0 nearly-empty
+ vptr=((& QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface) + 16u)
+
+Vtable for QDesignerFormWindowManagerInterface
+QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI35QDesignerFormWindowManagerInterface)
+16 QDesignerFormWindowManagerInterface::metaObject
+24 QDesignerFormWindowManagerInterface::qt_metacast
+32 QDesignerFormWindowManagerInterface::qt_metacall
+40 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+48 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QDesignerFormWindowManagerInterface::actionCut
+120 QDesignerFormWindowManagerInterface::actionCopy
+128 QDesignerFormWindowManagerInterface::actionPaste
+136 QDesignerFormWindowManagerInterface::actionDelete
+144 QDesignerFormWindowManagerInterface::actionSelectAll
+152 QDesignerFormWindowManagerInterface::actionLower
+160 QDesignerFormWindowManagerInterface::actionRaise
+168 QDesignerFormWindowManagerInterface::actionUndo
+176 QDesignerFormWindowManagerInterface::actionRedo
+184 QDesignerFormWindowManagerInterface::actionHorizontalLayout
+192 QDesignerFormWindowManagerInterface::actionVerticalLayout
+200 QDesignerFormWindowManagerInterface::actionSplitHorizontal
+208 QDesignerFormWindowManagerInterface::actionSplitVertical
+216 QDesignerFormWindowManagerInterface::actionGridLayout
+224 QDesignerFormWindowManagerInterface::actionBreakLayout
+232 QDesignerFormWindowManagerInterface::actionAdjustSize
+240 QDesignerFormWindowManagerInterface::activeFormWindow
+248 QDesignerFormWindowManagerInterface::formWindowCount
+256 QDesignerFormWindowManagerInterface::formWindow
+264 QDesignerFormWindowManagerInterface::createFormWindow
+272 QDesignerFormWindowManagerInterface::core
+280 __cxa_pure_virtual
+288 QDesignerFormWindowManagerInterface::addFormWindow
+296 QDesignerFormWindowManagerInterface::removeFormWindow
+304 QDesignerFormWindowManagerInterface::setActiveFormWindow
+
+Class QDesignerFormWindowManagerInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerFormWindowManagerInterface (0x7f0d3eaaf460) 0
+ vptr=((& QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface) + 16u)
+ QObject (0x7f0d3eaaf4d0) 0
+ primary-for QDesignerFormWindowManagerInterface (0x7f0d3eaaf460)
+
+Vtable for QDesignerFormWindowToolInterface
+QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QDesignerFormWindowToolInterface)
+16 QDesignerFormWindowToolInterface::metaObject
+24 QDesignerFormWindowToolInterface::qt_metacast
+32 QDesignerFormWindowToolInterface::qt_metacall
+40 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+48 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 QDesignerFormWindowToolInterface::saveToDom
+168 QDesignerFormWindowToolInterface::loadFromDom
+176 __cxa_pure_virtual
+
+Class QDesignerFormWindowToolInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerFormWindowToolInterface (0x7f0d3eacc7e0) 0
+ vptr=((& QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface) + 16u)
+ QObject (0x7f0d3eacc850) 0
+ primary-for QDesignerFormWindowToolInterface (0x7f0d3eacc7e0)
+
+Vtable for QDesignerIconCacheInterface
+QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerIconCacheInterface)
+16 QDesignerIconCacheInterface::metaObject
+24 QDesignerIconCacheInterface::qt_metacast
+32 QDesignerIconCacheInterface::qt_metacall
+40 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+48 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+
+Class QDesignerIconCacheInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerIconCacheInterface (0x7f0d3eadf8c0) 0
+ vptr=((& QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface) + 16u)
+ QObject (0x7f0d3eadf930) 0
+ primary-for QDesignerIconCacheInterface (0x7f0d3eadf8c0)
+
+Vtable for QDesignerIntegrationInterface
+QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QDesignerIntegrationInterface)
+16 QDesignerIntegrationInterface::metaObject
+24 QDesignerIntegrationInterface::qt_metacast
+32 QDesignerIntegrationInterface::qt_metacall
+40 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+48 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+
+Class QDesignerIntegrationInterface
+ size=24 align=8
+ base size=24 base align=8
+QDesignerIntegrationInterface (0x7f0d3eafb000) 0
+ vptr=((& QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface) + 16u)
+ QObject (0x7f0d3eafb070) 0
+ primary-for QDesignerIntegrationInterface (0x7f0d3eafb000)
+
+Vtable for QAbstractExtensionFactory
+QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAbstractExtensionFactory)
+16 QAbstractExtensionFactory::~QAbstractExtensionFactory
+24 QAbstractExtensionFactory::~QAbstractExtensionFactory
+32 __cxa_pure_virtual
+
+Class QAbstractExtensionFactory
+ size=8 align=8
+ base size=8 base align=8
+QAbstractExtensionFactory (0x7f0d3eb0d070) 0 nearly-empty
+ vptr=((& QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory) + 16u)
+
+Vtable for QAbstractExtensionManager
+QAbstractExtensionManager::_ZTV25QAbstractExtensionManager: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAbstractExtensionManager)
+16 QAbstractExtensionManager::~QAbstractExtensionManager
+24 QAbstractExtensionManager::~QAbstractExtensionManager
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QAbstractExtensionManager
+ size=8 align=8
+ base size=8 base align=8
+QAbstractExtensionManager (0x7f0d3eb19310) 0 nearly-empty
+ vptr=((& QAbstractExtensionManager::_ZTV25QAbstractExtensionManager) + 16u)
+
+Vtable for QDesignerLanguageExtension
+QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QDesignerLanguageExtension)
+16 QDesignerLanguageExtension::~QDesignerLanguageExtension
+24 QDesignerLanguageExtension::~QDesignerLanguageExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+
+Class QDesignerLanguageExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerLanguageExtension (0x7f0d3eb29620) 0 nearly-empty
+ vptr=((& QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension) + 16u)
+
+Vtable for QDesignerMetaDataBaseItemInterface
+QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI34QDesignerMetaDataBaseItemInterface)
+16 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+24 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseItemInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerMetaDataBaseItemInterface (0x7f0d3eb39e70) 0 nearly-empty
+ vptr=((& QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface) + 16u)
+
+Vtable for QDesignerMetaDataBaseInterface
+QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QDesignerMetaDataBaseInterface)
+16 QDesignerMetaDataBaseInterface::metaObject
+24 QDesignerMetaDataBaseInterface::qt_metacast
+32 QDesignerMetaDataBaseInterface::qt_metacall
+40 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+48 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerMetaDataBaseInterface (0x7f0d3eb4b850) 0
+ vptr=((& QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface) + 16u)
+ QObject (0x7f0d3eb4b8c0) 0
+ primary-for QDesignerMetaDataBaseInterface (0x7f0d3eb4b850)
+
+Vtable for QDesignerObjectInspectorInterface
+QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+16 QDesignerObjectInspectorInterface::metaObject
+24 QDesignerObjectInspectorInterface::qt_metacast
+32 QDesignerObjectInspectorInterface::qt_metacall
+40 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+48 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QDesignerObjectInspectorInterface::core
+456 __cxa_pure_virtual
+464 (int (*)(...))-0x00000000000000010
+472 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+480 QDesignerObjectInspectorInterface::_ZThn16_N33QDesignerObjectInspectorInterfaceD1Ev
+488 QDesignerObjectInspectorInterface::_ZThn16_N33QDesignerObjectInspectorInterfaceD0Ev
+496 QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerObjectInspectorInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerObjectInspectorInterface (0x7f0d3eb56d90) 0
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 16u)
+ QWidget (0x7f0d3eb4dd00) 0
+ primary-for QDesignerObjectInspectorInterface (0x7f0d3eb56d90)
+ QObject (0x7f0d3eb56e00) 0
+ primary-for QWidget (0x7f0d3eb4dd00)
+ QPaintDevice (0x7f0d3eb56e70) 16
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 480u)
+
+Class QDesignerPromotionInterface::PromotedClass
+ size=16 align=8
+ base size=16 base align=8
+QDesignerPromotionInterface::PromotedClass (0x7f0d3eb64e00) 0
+
+Vtable for QDesignerPromotionInterface
+QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerPromotionInterface)
+16 QDesignerPromotionInterface::~QDesignerPromotionInterface
+24 QDesignerPromotionInterface::~QDesignerPromotionInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerPromotionInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerPromotionInterface (0x7f0d3eb64d20) 0 nearly-empty
+ vptr=((& QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface) + 16u)
+
+Vtable for QDesignerPropertyEditorInterface
+QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface: 70u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+16 QDesignerPropertyEditorInterface::metaObject
+24 QDesignerPropertyEditorInterface::qt_metacast
+32 QDesignerPropertyEditorInterface::qt_metacall
+40 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+48 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QDesignerPropertyEditorInterface::core
+456 __cxa_pure_virtual
+464 __cxa_pure_virtual
+472 __cxa_pure_virtual
+480 __cxa_pure_virtual
+488 __cxa_pure_virtual
+496 __cxa_pure_virtual
+504 (int (*)(...))-0x00000000000000010
+512 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+520 QDesignerPropertyEditorInterface::_ZThn16_N32QDesignerPropertyEditorInterfaceD1Ev
+528 QDesignerPropertyEditorInterface::_ZThn16_N32QDesignerPropertyEditorInterfaceD0Ev
+536 QWidget::_ZThn16_NK7QWidget7devTypeEv
+544 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+552 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerPropertyEditorInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerPropertyEditorInterface (0x7f0d3eb772a0) 0
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 16u)
+ QWidget (0x7f0d3eb6f500) 0
+ primary-for QDesignerPropertyEditorInterface (0x7f0d3eb772a0)
+ QObject (0x7f0d3eb77310) 0
+ primary-for QWidget (0x7f0d3eb6f500)
+ QPaintDevice (0x7f0d3eb77380) 16
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 520u)
+
+Vtable for QDesignerResourceBrowserInterface
+QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+16 QDesignerResourceBrowserInterface::metaObject
+24 QDesignerResourceBrowserInterface::qt_metacast
+32 QDesignerResourceBrowserInterface::qt_metacall
+40 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+48 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 __cxa_pure_virtual
+456 __cxa_pure_virtual
+464 (int (*)(...))-0x00000000000000010
+472 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+480 QDesignerResourceBrowserInterface::_ZThn16_N33QDesignerResourceBrowserInterfaceD1Ev
+488 QDesignerResourceBrowserInterface::_ZThn16_N33QDesignerResourceBrowserInterfaceD0Ev
+496 QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerResourceBrowserInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerResourceBrowserInterface (0x7f0d3eb91380) 0
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 16u)
+ QWidget (0x7f0d3eb6fc00) 0
+ primary-for QDesignerResourceBrowserInterface (0x7f0d3eb91380)
+ QObject (0x7f0d3eb913f0) 0
+ primary-for QWidget (0x7f0d3eb6fc00)
+ QPaintDevice (0x7f0d3eb91460) 16
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 480u)
+
+Class QIcon
+ size=8 align=8
+ base size=8 base align=8
+QIcon (0x7f0d3e9a6310) 0
+
+Class QDesignerWidgetBoxInterface::Widget
+ size=32 align=8
+ base size=28 base align=8
+QDesignerWidgetBoxInterface::Widget (0x7f0d3e9d90e0) 0
+
+Class QDesignerWidgetBoxInterface::Category
+ size=24 align=8
+ base size=24 base align=8
+QDesignerWidgetBoxInterface::Category (0x7f0d3e9d97e0) 0
+
+Vtable for QDesignerWidgetBoxInterface
+QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface: 76u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+16 QDesignerWidgetBoxInterface::metaObject
+24 QDesignerWidgetBoxInterface::qt_metacast
+32 QDesignerWidgetBoxInterface::qt_metacall
+40 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+48 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 __cxa_pure_virtual
+456 __cxa_pure_virtual
+464 __cxa_pure_virtual
+472 __cxa_pure_virtual
+480 __cxa_pure_virtual
+488 __cxa_pure_virtual
+496 __cxa_pure_virtual
+504 __cxa_pure_virtual
+512 __cxa_pure_virtual
+520 __cxa_pure_virtual
+528 __cxa_pure_virtual
+536 __cxa_pure_virtual
+544 __cxa_pure_virtual
+552 (int (*)(...))-0x00000000000000010
+560 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+568 QDesignerWidgetBoxInterface::_ZThn16_N27QDesignerWidgetBoxInterfaceD1Ev
+576 QDesignerWidgetBoxInterface::_ZThn16_N27QDesignerWidgetBoxInterfaceD0Ev
+584 QWidget::_ZThn16_NK7QWidget7devTypeEv
+592 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+600 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerWidgetBoxInterface
+ size=40 align=8
+ base size=40 base align=8
+QDesignerWidgetBoxInterface (0x7f0d3e9caee0) 0
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 16u)
+ QWidget (0x7f0d3e9ccc00) 0
+ primary-for QDesignerWidgetBoxInterface (0x7f0d3e9caee0)
+ QObject (0x7f0d3e9caf50) 0
+ primary-for QWidget (0x7f0d3e9ccc00)
+ QPaintDevice (0x7f0d3e9d9000) 16
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 568u)
+
+Vtable for QDesignerWidgetDataBaseItemInterface
+QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI36QDesignerWidgetDataBaseItemInterface)
+16 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+24 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+192 __cxa_pure_virtual
+200 __cxa_pure_virtual
+208 __cxa_pure_virtual
+216 __cxa_pure_virtual
+224 __cxa_pure_virtual
+232 __cxa_pure_virtual
+
+Class QDesignerWidgetDataBaseItemInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerWidgetDataBaseItemInterface (0x7f0d3ea61690) 0 nearly-empty
+ vptr=((& QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface) + 16u)
+
+Vtable for QDesignerWidgetDataBaseInterface
+QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QDesignerWidgetDataBaseInterface)
+16 QDesignerWidgetDataBaseInterface::metaObject
+24 QDesignerWidgetDataBaseInterface::qt_metacast
+32 QDesignerWidgetDataBaseInterface::qt_metacall
+40 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+48 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QDesignerWidgetDataBaseInterface::count
+120 QDesignerWidgetDataBaseInterface::item
+128 QDesignerWidgetDataBaseInterface::indexOf
+136 QDesignerWidgetDataBaseInterface::insert
+144 QDesignerWidgetDataBaseInterface::append
+152 QDesignerWidgetDataBaseInterface::indexOfObject
+160 QDesignerWidgetDataBaseInterface::indexOfClassName
+168 QDesignerWidgetDataBaseInterface::core
+
+Class QDesignerWidgetDataBaseInterface
+ size=24 align=8
+ base size=24 base align=8
+QDesignerWidgetDataBaseInterface (0x7f0d3ea77070) 0
+ vptr=((& QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface) + 16u)
+ QObject (0x7f0d3ea770e0) 0
+ primary-for QDesignerWidgetDataBaseInterface (0x7f0d3ea77070)
+
+Vtable for QDesignerWidgetFactoryInterface
+QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface: 21u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI31QDesignerWidgetFactoryInterface)
+16 QDesignerWidgetFactoryInterface::metaObject
+24 QDesignerWidgetFactoryInterface::qt_metacast
+32 QDesignerWidgetFactoryInterface::qt_metacall
+40 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+48 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+
+Class QDesignerWidgetFactoryInterface
+ size=16 align=8
+ base size=16 base align=8
+QDesignerWidgetFactoryInterface (0x7f0d3e81d230) 0
+ vptr=((& QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface) + 16u)
+ QObject (0x7f0d3e81d2a0) 0
+ primary-for QDesignerWidgetFactoryInterface (0x7f0d3e81d230)
+
+Vtable for QDesignerDynamicPropertySheetExtension
+QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI38QDesignerDynamicPropertySheetExtension)
+16 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+24 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+
+Class QDesignerDynamicPropertySheetExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerDynamicPropertySheetExtension (0x7f0d3e82e1c0) 0 nearly-empty
+ vptr=((& QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension) + 16u)
+
+Vtable for QDesignerExtraInfoExtension
+QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerExtraInfoExtension)
+16 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+24 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerExtraInfoExtension
+ size=16 align=8
+ base size=16 base align=8
+QDesignerExtraInfoExtension (0x7f0d3e83fa10) 0
+ vptr=((& QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension) + 16u)
+
+Vtable for QDesignerLayoutDecorationExtension
+QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI34QDesignerLayoutDecorationExtension)
+16 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+24 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+
+Class QDesignerLayoutDecorationExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerLayoutDecorationExtension (0x7f0d3e85e460) 0 nearly-empty
+ vptr=((& QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension) + 16u)
+
+Vtable for QDesignerMemberSheetExtension
+QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QDesignerMemberSheetExtension)
+16 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+24 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+
+Class QDesignerMemberSheetExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerMemberSheetExtension (0x7f0d3e870e00) 0 nearly-empty
+ vptr=((& QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension) + 16u)
+
+Vtable for QDesignerPropertySheetExtension
+QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI31QDesignerPropertySheetExtension)
+16 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+24 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+
+Class QDesignerPropertySheetExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerPropertySheetExtension (0x7f0d3e891690) 0 nearly-empty
+ vptr=((& QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension) + 16u)
+
+Vtable for QDesignerTaskMenuExtension
+QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QDesignerTaskMenuExtension)
+16 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+24 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+32 QDesignerTaskMenuExtension::preferredEditAction
+40 __cxa_pure_virtual
+
+Class QDesignerTaskMenuExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerTaskMenuExtension (0x7f0d3e89fee0) 0 nearly-empty
+ vptr=((& QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension) + 16u)
+
+Vtable for QAbstractFormBuilder
+QAbstractFormBuilder::_ZTV20QAbstractFormBuilder: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QAbstractFormBuilder)
+16 QAbstractFormBuilder::~QAbstractFormBuilder
+24 QAbstractFormBuilder::~QAbstractFormBuilder
+32 QAbstractFormBuilder::load
+40 QAbstractFormBuilder::save
+48 QAbstractFormBuilder::loadExtraInfo
+56 QAbstractFormBuilder::create
+64 QAbstractFormBuilder::create
+72 QAbstractFormBuilder::create
+80 QAbstractFormBuilder::create
+88 QAbstractFormBuilder::create
+96 QAbstractFormBuilder::create
+104 QAbstractFormBuilder::addMenuAction
+112 QAbstractFormBuilder::applyProperties
+120 QAbstractFormBuilder::applyTabStops
+128 QAbstractFormBuilder::createWidget
+136 QAbstractFormBuilder::createLayout
+144 QAbstractFormBuilder::createAction
+152 QAbstractFormBuilder::createActionGroup
+160 QAbstractFormBuilder::createCustomWidgets
+168 QAbstractFormBuilder::createConnections
+176 QAbstractFormBuilder::createResources
+184 QAbstractFormBuilder::addItem
+192 QAbstractFormBuilder::addItem
+200 QAbstractFormBuilder::saveExtraInfo
+208 QAbstractFormBuilder::saveDom
+216 QAbstractFormBuilder::createActionRefDom
+224 QAbstractFormBuilder::createDom
+232 QAbstractFormBuilder::createDom
+240 QAbstractFormBuilder::createDom
+248 QAbstractFormBuilder::createDom
+256 QAbstractFormBuilder::createDom
+264 QAbstractFormBuilder::createDom
+272 QAbstractFormBuilder::saveConnections
+280 QAbstractFormBuilder::saveCustomWidgets
+288 QAbstractFormBuilder::saveTabStops
+296 QAbstractFormBuilder::saveResources
+304 QAbstractFormBuilder::computeProperties
+312 QAbstractFormBuilder::checkProperty
+320 QAbstractFormBuilder::createProperty
+328 QAbstractFormBuilder::layoutInfo
+336 QAbstractFormBuilder::nameToIcon
+344 QAbstractFormBuilder::iconToFilePath
+352 QAbstractFormBuilder::iconToQrcPath
+360 QAbstractFormBuilder::nameToPixmap
+368 QAbstractFormBuilder::pixmapToFilePath
+376 QAbstractFormBuilder::pixmapToQrcPath
+
+Class QAbstractFormBuilder
+ size=48 align=8
+ base size=48 base align=8
+QAbstractFormBuilder (0x7f0d3e8bd930) 0
+ vptr=((& QAbstractFormBuilder::_ZTV20QAbstractFormBuilder) + 16u)
+
+Vtable for QDesignerContainerExtension
+QDesignerContainerExtension::_ZTV27QDesignerContainerExtension: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDesignerContainerExtension)
+16 QDesignerContainerExtension::~QDesignerContainerExtension
+24 QDesignerContainerExtension::~QDesignerContainerExtension
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerContainerExtension
+ size=8 align=8
+ base size=8 base align=8
+QDesignerContainerExtension (0x7f0d3e8e7e70) 0 nearly-empty
+ vptr=((& QDesignerContainerExtension::_ZTV27QDesignerContainerExtension) + 16u)
+
+Vtable for QDesignerCustomWidgetInterface
+QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QDesignerCustomWidgetInterface)
+16 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+24 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 QDesignerCustomWidgetInterface::isInitialized
+104 QDesignerCustomWidgetInterface::initialize
+112 QDesignerCustomWidgetInterface::domXml
+120 QDesignerCustomWidgetInterface::codeTemplate
+
+Class QDesignerCustomWidgetInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerCustomWidgetInterface (0x7f0d3e75c460) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface) + 16u)
+
+Vtable for QDesignerCustomWidgetCollectionInterface
+QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI40QDesignerCustomWidgetCollectionInterface)
+16 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+24 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+32 __cxa_pure_virtual
+
+Class QDesignerCustomWidgetCollectionInterface
+ size=8 align=8
+ base size=8 base align=8
+QDesignerCustomWidgetCollectionInterface (0x7f0d3e777380) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface) + 16u)
+
+Vtable for QFormBuilder
+QFormBuilder::_ZTV12QFormBuilder: 49u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QFormBuilder)
+16 QFormBuilder::~QFormBuilder
+24 QFormBuilder::~QFormBuilder
+32 QAbstractFormBuilder::load
+40 QAbstractFormBuilder::save
+48 QAbstractFormBuilder::loadExtraInfo
+56 QFormBuilder::create
+64 QFormBuilder::create
+72 QFormBuilder::create
+80 QFormBuilder::create
+88 QFormBuilder::create
+96 QFormBuilder::create
+104 QAbstractFormBuilder::addMenuAction
+112 QFormBuilder::applyProperties
+120 QAbstractFormBuilder::applyTabStops
+128 QFormBuilder::createWidget
+136 QFormBuilder::createLayout
+144 QAbstractFormBuilder::createAction
+152 QAbstractFormBuilder::createActionGroup
+160 QAbstractFormBuilder::createCustomWidgets
+168 QFormBuilder::createConnections
+176 QAbstractFormBuilder::createResources
+184 QFormBuilder::addItem
+192 QFormBuilder::addItem
+200 QAbstractFormBuilder::saveExtraInfo
+208 QAbstractFormBuilder::saveDom
+216 QAbstractFormBuilder::createActionRefDom
+224 QAbstractFormBuilder::createDom
+232 QAbstractFormBuilder::createDom
+240 QAbstractFormBuilder::createDom
+248 QAbstractFormBuilder::createDom
+256 QAbstractFormBuilder::createDom
+264 QAbstractFormBuilder::createDom
+272 QAbstractFormBuilder::saveConnections
+280 QAbstractFormBuilder::saveCustomWidgets
+288 QAbstractFormBuilder::saveTabStops
+296 QAbstractFormBuilder::saveResources
+304 QAbstractFormBuilder::computeProperties
+312 QAbstractFormBuilder::checkProperty
+320 QAbstractFormBuilder::createProperty
+328 QAbstractFormBuilder::layoutInfo
+336 QAbstractFormBuilder::nameToIcon
+344 QAbstractFormBuilder::iconToFilePath
+352 QAbstractFormBuilder::iconToQrcPath
+360 QAbstractFormBuilder::nameToPixmap
+368 QAbstractFormBuilder::pixmapToFilePath
+376 QAbstractFormBuilder::pixmapToQrcPath
+384 QFormBuilder::updateCustomWidgets
+
+Class QFormBuilder
+ size=64 align=8
+ base size=64 base align=8
+QFormBuilder (0x7f0d3e786620) 0
+ vptr=((& QFormBuilder::_ZTV12QFormBuilder) + 16u)
+ QAbstractFormBuilder (0x7f0d3e786690) 0
+ primary-for QFormBuilder (0x7f0d3e786620)
+
+Vtable for QExtensionManager
+QExtensionManager::_ZTV17QExtensionManager: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QExtensionManager)
+16 QExtensionManager::metaObject
+24 QExtensionManager::qt_metacast
+32 QExtensionManager::qt_metacall
+40 QExtensionManager::~QExtensionManager
+48 QExtensionManager::~QExtensionManager
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QExtensionManager::registerExtensions
+120 QExtensionManager::unregisterExtensions
+128 QExtensionManager::extension
+136 (int (*)(...))-0x00000000000000010
+144 (int (*)(...))(& _ZTI17QExtensionManager)
+152 QExtensionManager::_ZThn16_N17QExtensionManagerD1Ev
+160 QExtensionManager::_ZThn16_N17QExtensionManagerD0Ev
+168 QExtensionManager::_ZThn16_N17QExtensionManager18registerExtensionsEP25QAbstractExtensionFactoryRK7QString
+176 QExtensionManager::_ZThn16_N17QExtensionManager20unregisterExtensionsEP25QAbstractExtensionFactoryRK7QString
+184 QExtensionManager::_ZThn16_NK17QExtensionManager9extensionEP7QObjectRK7QString
+
+Class QExtensionManager
+ size=40 align=8
+ base size=40 base align=8
+QExtensionManager (0x7f0d3e782c00) 0
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 16u)
+ QObject (0x7f0d3e786a10) 0
+ primary-for QExtensionManager (0x7f0d3e782c00)
+ QAbstractExtensionManager (0x7f0d3e786a80) 16 nearly-empty
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 152u)
+
diff --git a/tests/auto/bic/data/QtDesigner.4.6.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtDesigner.4.6.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..c42758248
--- /dev/null
+++ b/tests/auto/bic/data/QtDesigner.4.6.0.linux-gcc-ia32.txt
@@ -0,0 +1,4741 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb6fa8a8c) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb6fa8c30) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb6f5530c) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb6f553c0) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb6f55bf4) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0xb6f55d20) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb6f55f78) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb65ce168) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0xb65ff8ac) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0xb6631080) 0
+ QBasicAtomicInt (0xb65fffb4) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb652e3c0) 0 empty
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb652e3fc) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb652e870) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb652e834) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb63db780) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb63faf3c) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb63faf78) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb63faf00) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb62d7bf4) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb633b8e8) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb61afdc0) 0
+ QString (0xb61f703c) 0
+
+Class QStringRef
+ size=12 align=4
+ base size=12 base align=4
+QStringRef (0xb61f7384) 0
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb62452d0) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb623e680) 0
+ QGenericArgument (0xb62454ec) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb6245654) 0
+
+Class QMetaObjectExtraData
+ size=8 align=4
+ base size=8 base align=4
+QMetaObjectExtraData (0xb6245780) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb6245ac8) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::bad_exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb6096300) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb6245bb8) 0 nearly-empty
+ primary-for std::bad_exception (0xb6096300)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb6096480) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb6245e10) 0 nearly-empty
+ primary-for std::bad_alloc (0xb6096480)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb60a2078) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb60a2168) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb60a212c) 0
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0xb60a299c) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=28 align=4
+ base size=28 base align=4
+QObjectData (0xb60a2a50) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb60a2b04) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb5f8e384) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb5f89b40) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb5f8e4b0) 0
+ primary-for QIODevice (0xb5f89b40)
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb5fcb348) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb5fcb384) 0
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb5fbf7c0) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb5fbf800) 0
+ primary-for QFile (0xb5fbf7c0)
+ QObject (0xb5fcb3fc) 0
+ primary-for QIODevice (0xb5fbf800)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb5fcb870) 0
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb5fcbec4) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb60885dc) 0
+
+Class QStringMatcher::Data
+ size=264 align=4
+ base size=264 base align=4
+QStringMatcher::Data (0xb5ec8000) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb6088fb4) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb5e9aec0) 0
+ QList<QString> (0xb5ec812c) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb5f0e690) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0xb5f0ee10) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0xb5f0ee4c) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=20 align=4
+ base size=20 base align=4
+QAbstractFileEngine::MapExtensionOption (0xb5f437c0) 0
+ QAbstractFileEngine::ExtensionOption (0xb5f0ee88) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::MapExtensionReturn (0xb5f43840) 0
+ QAbstractFileEngine::ExtensionReturn (0xb5f0eec4) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::UnMapExtensionOption (0xb5f438c0) 0
+ QAbstractFileEngine::ExtensionOption (0xb5f0ef00) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+8 QAbstractFileEngine::~QAbstractFileEngine
+12 QAbstractFileEngine::~QAbstractFileEngine
+16 QAbstractFileEngine::open
+20 QAbstractFileEngine::close
+24 QAbstractFileEngine::flush
+28 QAbstractFileEngine::size
+32 QAbstractFileEngine::pos
+36 QAbstractFileEngine::seek
+40 QAbstractFileEngine::isSequential
+44 QAbstractFileEngine::remove
+48 QAbstractFileEngine::copy
+52 QAbstractFileEngine::rename
+56 QAbstractFileEngine::link
+60 QAbstractFileEngine::mkdir
+64 QAbstractFileEngine::rmdir
+68 QAbstractFileEngine::setSize
+72 QAbstractFileEngine::caseSensitive
+76 QAbstractFileEngine::isRelativePath
+80 QAbstractFileEngine::entryList
+84 QAbstractFileEngine::fileFlags
+88 QAbstractFileEngine::setPermissions
+92 QAbstractFileEngine::fileName
+96 QAbstractFileEngine::ownerId
+100 QAbstractFileEngine::owner
+104 QAbstractFileEngine::fileTime
+108 QAbstractFileEngine::setFileName
+112 QAbstractFileEngine::handle
+116 QAbstractFileEngine::beginEntryList
+120 QAbstractFileEngine::endEntryList
+124 QAbstractFileEngine::read
+128 QAbstractFileEngine::readLine
+132 QAbstractFileEngine::write
+136 QAbstractFileEngine::extension
+140 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngine (0xb5f0edd4) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 8u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+8 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+12 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+16 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngineHandler (0xb5d8d168) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 8u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+8 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+12 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QAbstractFileEngineIterator::currentFileInfo
+32 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngineIterator (0xb5d8d1a4) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 8u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QBuffer)
+8 QBuffer::metaObject
+12 QBuffer::qt_metacast
+16 QBuffer::qt_metacall
+20 QBuffer::~QBuffer
+24 QBuffer::~QBuffer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QBuffer::connectNotify
+52 QBuffer::disconnectNotify
+56 QIODevice::isSequential
+60 QBuffer::open
+64 QBuffer::close
+68 QBuffer::pos
+72 QBuffer::size
+76 QBuffer::seek
+80 QBuffer::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QBuffer::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QBuffer::readData
+112 QIODevice::readLineData
+116 QBuffer::writeData
+
+Class QBuffer
+ size=8 align=4
+ base size=8 base align=4
+QBuffer (0xb5f43c00) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 8u)
+ QIODevice (0xb5f43c40) 0
+ primary-for QBuffer (0xb5f43c00)
+ QObject (0xb5d8d21c) 0
+ primary-for QIODevice (0xb5f43c40)
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb5d8d8e8) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb5d8d8ac) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb5dd6000) 0 empty
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb5dd6744) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb5dd6708) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSystemLocale)
+8 QSystemLocale::~QSystemLocale
+12 QSystemLocale::~QSystemLocale
+16 QSystemLocale::query
+20 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=4 align=4
+ base size=4 base align=4
+QSystemLocale (0xb5dd6a50) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 8u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0xb5dd6ac8) 0
+
+Class QLocale
+ size=4 align=4
+ base size=4 base align=4
+QLocale (0xb5dd6a8c) 0
+
+Class QTextCodec::ConverterState
+ size=28 align=4
+ base size=28 base align=4
+QTextCodec::ConverterState (0xb5d5912c) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTextCodec)
+8 __cxa_pure_virtual
+12 QTextCodec::aliases
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QTextCodec::~QTextCodec
+32 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=4 align=4
+ base size=4 base align=4
+QTextCodec (0xb5d590f0) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 8u)
+
+Class QTextEncoder
+ size=32 align=4
+ base size=32 base align=4
+QTextEncoder (0xb5d59e10) 0
+
+Class QTextDecoder
+ size=32 align=4
+ base size=32 base align=4
+QTextDecoder (0xb5ba2078) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTextStream)
+8 QTextStream::~QTextStream
+12 QTextStream::~QTextStream
+
+Class QTextStream
+ size=8 align=4
+ base size=8 base align=4
+QTextStream (0xb5ba22d0) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 8u)
+
+Class QTextStreamManipulator
+ size=24 align=4
+ base size=22 base align=4
+QTextStreamManipulator (0xb5ba2960) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextIStream)
+8 QTextIStream::~QTextIStream
+12 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=8 align=4
+ base size=8 base align=4
+QTextIStream (0xb5bd0940) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 8u)
+ QTextStream (0xb5bf4b40) 0
+ primary-for QTextIStream (0xb5bd0940)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextOStream)
+8 QTextOStream::~QTextOStream
+12 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=8 align=4
+ base size=8 base align=4
+QTextOStream (0xb5bd0c00) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 8u)
+ QTextStream (0xb5c071e0) 0
+ primary-for QTextOStream (0xb5bd0c00)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb5c07870) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb5c07a14) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb5c07a50) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb5c07b04) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb5c07e10) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb5c07e4c) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb5c07e88) 0
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0xb5ab51a4) 0
+
+Class QDebug::Stream
+ size=24 align=4
+ base size=22 base align=4
+QDebug::Stream (0xb5ab5384) 0
+
+Class QDebug
+ size=4 align=4
+ base size=4 base align=4
+QDebug (0xb5ab5348) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0xb5b81fb4) 0 empty
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QDirIterator)
+8 QDirIterator::~QDirIterator
+12 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=8 align=4
+ base size=8 base align=4
+QDirIterator (0xb59ab258) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 8u)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+8 QFileSystemWatcher::metaObject
+12 QFileSystemWatcher::qt_metacast
+16 QFileSystemWatcher::qt_metacall
+20 QFileSystemWatcher::~QFileSystemWatcher
+24 QFileSystemWatcher::~QFileSystemWatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=8 align=4
+ base size=8 base align=4
+QFileSystemWatcher (0xb59d3100) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 8u)
+ QObject (0xb59ab3c0) 0
+ primary-for QFileSystemWatcher (0xb59d3100)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QFSFileEngine)
+8 QFSFileEngine::~QFSFileEngine
+12 QFSFileEngine::~QFSFileEngine
+16 QFSFileEngine::open
+20 QFSFileEngine::close
+24 QFSFileEngine::flush
+28 QFSFileEngine::size
+32 QFSFileEngine::pos
+36 QFSFileEngine::seek
+40 QFSFileEngine::isSequential
+44 QFSFileEngine::remove
+48 QFSFileEngine::copy
+52 QFSFileEngine::rename
+56 QFSFileEngine::link
+60 QFSFileEngine::mkdir
+64 QFSFileEngine::rmdir
+68 QFSFileEngine::setSize
+72 QFSFileEngine::caseSensitive
+76 QFSFileEngine::isRelativePath
+80 QFSFileEngine::entryList
+84 QFSFileEngine::fileFlags
+88 QFSFileEngine::setPermissions
+92 QFSFileEngine::fileName
+96 QFSFileEngine::ownerId
+100 QFSFileEngine::owner
+104 QFSFileEngine::fileTime
+108 QFSFileEngine::setFileName
+112 QFSFileEngine::handle
+116 QFSFileEngine::beginEntryList
+120 QFSFileEngine::endEntryList
+124 QFSFileEngine::read
+128 QFSFileEngine::readLine
+132 QFSFileEngine::write
+136 QFSFileEngine::extension
+140 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QFSFileEngine (0xb59d33c0) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 8u)
+ QAbstractFileEngine (0xb59ab5dc) 0
+ primary-for QFSFileEngine (0xb59d33c0)
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0xb59ab708) 0
+
+Class QProcessEnvironment
+ size=4 align=4
+ base size=4 base align=4
+QProcessEnvironment (0xb59ab924) 0
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QProcess)
+8 QProcess::metaObject
+12 QProcess::qt_metacast
+16 QProcess::qt_metacall
+20 QProcess::~QProcess
+24 QProcess::~QProcess
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QProcess::isSequential
+60 QIODevice::open
+64 QProcess::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QProcess::atEnd
+84 QIODevice::reset
+88 QProcess::bytesAvailable
+92 QProcess::bytesToWrite
+96 QProcess::canReadLine
+100 QProcess::waitForReadyRead
+104 QProcess::waitForBytesWritten
+108 QProcess::readData
+112 QIODevice::readLineData
+116 QProcess::writeData
+120 QProcess::setupChildProcess
+
+Class QProcess
+ size=8 align=4
+ base size=8 base align=4
+QProcess (0xb5a19440) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 8u)
+ QIODevice (0xb5a19480) 0
+ primary-for QProcess (0xb5a19440)
+ QObject (0xb59ab9d8) 0
+ primary-for QIODevice (0xb5a19480)
+
+Class QResource
+ size=4 align=4
+ base size=4 base align=4
+QResource (0xb59abbf4) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb59abd98) 0 empty
+
+Class QVariant::PrivateShared
+ size=8 align=4
+ base size=8 base align=4
+QVariant::PrivateShared (0xb5892a50) 0
+
+Class QVariant::Private::Data
+ size=8 align=4
+ base size=8 base align=4
+QVariant::Private::Data (0xb5892ac8) 0
+
+Class QVariant::Private
+ size=12 align=4
+ base size=12 base align=4
+QVariant::Private (0xb5892a8c) 0
+
+Class QVariant::Handler
+ size=36 align=4
+ base size=36 base align=4
+QVariant::Handler (0xb5892b40) 0
+
+Class QVariant
+ size=12 align=4
+ base size=12 base align=4
+QVariant (0xb5892a14) 0
+
+Class QVariantComparisonHelper
+ size=4 align=4
+ base size=4 base align=4
+QVariantComparisonHelper (0xb592f3fc) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QSettings)
+8 QSettings::metaObject
+12 QSettings::qt_metacast
+16 QSettings::qt_metacall
+20 QSettings::~QSettings
+24 QSettings::~QSettings
+28 QSettings::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSettings
+ size=8 align=4
+ base size=8 base align=4
+QSettings (0xb592af40) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 8u)
+ QObject (0xb592fa14) 0
+ primary-for QSettings (0xb592af40)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QTemporaryFile)
+8 QTemporaryFile::metaObject
+12 QTemporaryFile::qt_metacast
+16 QTemporaryFile::qt_metacall
+20 QTemporaryFile::~QTemporaryFile
+24 QTemporaryFile::~QTemporaryFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QTemporaryFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=8 align=4
+ base size=8 base align=4
+QTemporaryFile (0xb596fb40) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 8u)
+ QFile (0xb596fb80) 0
+ primary-for QTemporaryFile (0xb596fb40)
+ QIODevice (0xb596fbc0) 0
+ primary-for QFile (0xb596fb80)
+ QObject (0xb5985528) 0
+ primary-for QIODevice (0xb596fbc0)
+
+Class QUrl
+ size=4 align=4
+ base size=4 base align=4
+QUrl (0xb5985834) 0
+
+Class QXmlStreamStringRef
+ size=12 align=4
+ base size=12 base align=4
+QXmlStreamStringRef (0xb5985d20) 0
+
+Class QXmlStreamAttribute
+ size=56 align=4
+ base size=53 base align=4
+QXmlStreamAttribute (0xb57f09d8) 0
+
+Class QXmlStreamAttributes
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamAttributes (0xb5811180) 0
+ QVector<QXmlStreamAttribute> (0xb580f438) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=28 align=4
+ base size=28 base align=4
+QXmlStreamNamespaceDeclaration (0xb580f528) 0
+
+Class QXmlStreamNotationDeclaration
+ size=40 align=4
+ base size=40 base align=4
+QXmlStreamNotationDeclaration (0xb580f99c) 0
+
+Class QXmlStreamEntityDeclaration
+ size=64 align=4
+ base size=64 base align=4
+QXmlStreamEntityDeclaration (0xb580ff78) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+8 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+12 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+16 QXmlStreamEntityResolver::resolveEntity
+20 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamEntityResolver (0xb5847834) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 8u)
+
+Class QXmlStreamReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamReader (0xb5847870) 0
+
+Class QXmlStreamWriter
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamWriter (0xb58479d8) 0
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QAbstractState)
+8 QAbstractState::metaObject
+12 QAbstractState::qt_metacast
+16 QAbstractState::qt_metacall
+20 QAbstractState::~QAbstractState
+24 QAbstractState::~QAbstractState
+28 QAbstractState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QAbstractState
+ size=8 align=4
+ base size=8 base align=4
+QAbstractState (0xb587d140) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 8u)
+ QObject (0xb5847b40) 0
+ primary-for QAbstractState (0xb587d140)
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTransition)
+8 QAbstractTransition::metaObject
+12 QAbstractTransition::qt_metacast
+16 QAbstractTransition::qt_metacall
+20 QAbstractTransition::~QAbstractTransition
+24 QAbstractTransition::~QAbstractTransition
+28 QAbstractTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QAbstractTransition
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTransition (0xb587d400) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 8u)
+ QObject (0xb5847d5c) 0
+ primary-for QAbstractTransition (0xb587d400)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QEvent)
+8 QEvent::~QEvent
+12 QEvent::~QEvent
+
+Class QEvent
+ size=12 align=4
+ base size=12 base align=4
+QEvent (0xb5847f78) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 8u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTimerEvent)
+8 QTimerEvent::~QTimerEvent
+12 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=16 align=4
+ base size=16 base align=4
+QTimerEvent (0xb587d980) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 8u)
+ QEvent (0xb56b4168) 0
+ primary-for QTimerEvent (0xb587d980)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QChildEvent)
+8 QChildEvent::~QChildEvent
+12 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=16 align=4
+ base size=16 base align=4
+QChildEvent (0xb587da40) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 8u)
+ QEvent (0xb56b41e0) 0
+ primary-for QChildEvent (0xb587da40)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QCustomEvent)
+8 QCustomEvent::~QCustomEvent
+12 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=12 align=4
+ base size=12 base align=4
+QCustomEvent (0xb587dd00) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 8u)
+ QEvent (0xb56b4348) 0
+ primary-for QCustomEvent (0xb587dd00)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+8 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+12 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=16 align=4
+ base size=16 base align=4
+QDynamicPropertyChangeEvent (0xb587de00) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 8u)
+ QEvent (0xb56b4438) 0
+ primary-for QDynamicPropertyChangeEvent (0xb587de00)
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QEventTransition)
+8 QEventTransition::metaObject
+12 QEventTransition::qt_metacast
+16 QEventTransition::qt_metacall
+20 QEventTransition::~QEventTransition
+24 QEventTransition::~QEventTransition
+28 QEventTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QEventTransition::eventTest
+60 QEventTransition::onTransition
+
+Class QEventTransition
+ size=8 align=4
+ base size=8 base align=4
+QEventTransition (0xb587dec0) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 8u)
+ QAbstractTransition (0xb587df00) 0
+ primary-for QEventTransition (0xb587dec0)
+ QObject (0xb56b44ec) 0
+ primary-for QAbstractTransition (0xb587df00)
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QFinalState)
+8 QFinalState::metaObject
+12 QFinalState::qt_metacast
+16 QFinalState::qt_metacall
+20 QFinalState::~QFinalState
+24 QFinalState::~QFinalState
+28 QFinalState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFinalState::onEntry
+60 QFinalState::onExit
+
+Class QFinalState
+ size=8 align=4
+ base size=8 base align=4
+QFinalState (0xb56cf1c0) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 8u)
+ QAbstractState (0xb56cf200) 0
+ primary-for QFinalState (0xb56cf1c0)
+ QObject (0xb56b4708) 0
+ primary-for QAbstractState (0xb56cf200)
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QHistoryState)
+8 QHistoryState::metaObject
+12 QHistoryState::qt_metacast
+16 QHistoryState::qt_metacall
+20 QHistoryState::~QHistoryState
+24 QHistoryState::~QHistoryState
+28 QHistoryState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QHistoryState::onEntry
+60 QHistoryState::onExit
+
+Class QHistoryState
+ size=8 align=4
+ base size=8 base align=4
+QHistoryState (0xb56cf4c0) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 8u)
+ QAbstractState (0xb56cf500) 0
+ primary-for QHistoryState (0xb56cf4c0)
+ QObject (0xb56b4924) 0
+ primary-for QAbstractState (0xb56cf500)
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QSignalTransition)
+8 QSignalTransition::metaObject
+12 QSignalTransition::qt_metacast
+16 QSignalTransition::qt_metacall
+20 QSignalTransition::~QSignalTransition
+24 QSignalTransition::~QSignalTransition
+28 QSignalTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSignalTransition::eventTest
+60 QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=8 align=4
+ base size=8 base align=4
+QSignalTransition (0xb56cf7c0) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 8u)
+ QAbstractTransition (0xb56cf800) 0
+ primary-for QSignalTransition (0xb56cf7c0)
+ QObject (0xb56b4b40) 0
+ primary-for QAbstractTransition (0xb56cf800)
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QState)
+8 QState::metaObject
+12 QState::qt_metacast
+16 QState::qt_metacall
+20 QState::~QState
+24 QState::~QState
+28 QState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QState::onEntry
+60 QState::onExit
+
+Class QState
+ size=8 align=4
+ base size=8 base align=4
+QState (0xb56cfac0) 0
+ vptr=((& QState::_ZTV6QState) + 8u)
+ QAbstractState (0xb56cfb00) 0
+ primary-for QState (0xb56cfac0)
+ QObject (0xb56b4d5c) 0
+ primary-for QAbstractState (0xb56cfb00)
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+8 QStateMachine::SignalEvent::~SignalEvent
+12 QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=24 align=4
+ base size=24 base align=4
+QStateMachine::SignalEvent (0xb56cff00) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 8u)
+ QEvent (0xb56b4fb4) 0
+ primary-for QStateMachine::SignalEvent (0xb56cff00)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+8 QStateMachine::WrappedEvent::~WrappedEvent
+12 QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=20 align=4
+ base size=20 base align=4
+QStateMachine::WrappedEvent (0xb56cff80) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 8u)
+ QEvent (0xb5710000) 0
+ primary-for QStateMachine::WrappedEvent (0xb56cff80)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QStateMachine)
+8 QStateMachine::metaObject
+12 QStateMachine::qt_metacast
+16 QStateMachine::qt_metacall
+20 QStateMachine::~QStateMachine
+24 QStateMachine::~QStateMachine
+28 QStateMachine::event
+32 QStateMachine::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QStateMachine::onEntry
+60 QStateMachine::onExit
+64 QStateMachine::beginSelectTransitions
+68 QStateMachine::endSelectTransitions
+72 QStateMachine::beginMicrostep
+76 QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=8 align=4
+ base size=8 base align=4
+QStateMachine (0xb56cfdc0) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 8u)
+ QState (0xb56cfe00) 0
+ primary-for QStateMachine (0xb56cfdc0)
+ QAbstractState (0xb56cfe40) 0
+ primary-for QState (0xb56cfe00)
+ QObject (0xb56b4f78) 0
+ primary-for QAbstractState (0xb56cfe40)
+
+Class QBitArray
+ size=4 align=4
+ base size=4 base align=4
+QBitArray (0xb5710384) 0
+
+Class QBitRef
+ size=8 align=4
+ base size=8 base align=4
+QBitRef (0xb5749834) 0
+
+Class QByteArrayMatcher::Data
+ size=264 align=4
+ base size=264 base align=4
+QByteArrayMatcher::Data (0xb5749e4c) 0
+
+Class QByteArrayMatcher
+ size=1032 align=4
+ base size=1032 base align=4
+QByteArrayMatcher (0xb5749e10) 0
+
+Class QCryptographicHash
+ size=4 align=4
+ base size=4 base align=4
+QCryptographicHash (0xb576512c) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+8 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+12 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+16 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=12 align=4
+ base size=12 base align=4
+QtSharedPointer::ExternalRefCountData (0xb57652d0) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 8u)
+
+Vtable for QtSharedPointer::ExternalRefCountWithDestroyFn
+QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer29ExternalRefCountWithDestroyFnE)
+8 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+12 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+16 QtSharedPointer::ExternalRefCountWithDestroyFn::destroy
+
+Class QtSharedPointer::ExternalRefCountWithDestroyFn
+ size=16 align=4
+ base size=16 base align=4
+QtSharedPointer::ExternalRefCountWithDestroyFn (0xb5585d40) 0
+ vptr=((& QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE) + 8u)
+ QtSharedPointer::ExternalRefCountData (0xb5765ac8) 0
+ primary-for QtSharedPointer::ExternalRefCountWithDestroyFn (0xb5585d40)
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0xb55f1000) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0xb55f1618) 0
+
+Class QDateTime
+ size=4 align=4
+ base size=4 base align=4
+QDateTime (0xb55f1b7c) 0
+
+Class QEasingCurve
+ size=4 align=4
+ base size=4 base align=4
+QEasingCurve (0xb55f1e4c) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb55f1ec4) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb5658474) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb566fb7c) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb54848ac) 0
+
+Class QLinkedListData
+ size=20 align=4
+ base size=20 base align=4
+QLinkedListData (0xb54af99c) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0xb54afbb8) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb5539d20) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb555e7bc) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb538c3c0) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb53ed000) 0
+
+Class QLatin1Literal
+ size=8 align=4
+ base size=8 base align=4
+QLatin1Literal (0xb5437d98) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0xb5437e4c) 0 empty
+
+Class QTextBoundaryFinder
+ size=28 align=4
+ base size=28 base align=4
+QTextBoundaryFinder (0xb546c0f0) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTimeLine)
+8 QTimeLine::metaObject
+12 QTimeLine::qt_metacast
+16 QTimeLine::qt_metacall
+20 QTimeLine::~QTimeLine
+24 QTimeLine::~QTimeLine
+28 QObject::event
+32 QObject::eventFilter
+36 QTimeLine::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=8 align=4
+ base size=8 base align=4
+QTimeLine (0xb546a440) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 8u)
+ QObject (0xb546c1a4) 0
+ primary-for QTimeLine (0xb546a440)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QRunnable)
+8 __cxa_pure_virtual
+12 QRunnable::~QRunnable
+16 QRunnable::~QRunnable
+
+Class QRunnable
+ size=8 align=4
+ base size=8 base align=4
+QRunnable (0xb546c438) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 8u)
+
+Class QMutex
+ size=4 align=4
+ base size=4 base align=4
+QMutex (0xb546c8ac) 0
+
+Class QMutexLocker
+ size=4 align=4
+ base size=4 base align=4
+QMutexLocker (0xb546cf3c) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+8 QtConcurrent::Exception::~Exception
+12 QtConcurrent::Exception::~Exception
+16 std::exception::what
+20 QtConcurrent::Exception::raise
+24 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::Exception (0xb52b85c0) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 8u)
+ std::exception (0xb52b6438) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb52b85c0)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+8 QtConcurrent::UnhandledException::~UnhandledException
+12 QtConcurrent::UnhandledException::~UnhandledException
+16 std::exception::what
+20 QtConcurrent::UnhandledException::raise
+24 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::UnhandledException (0xb52b86c0) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 8u)
+ QtConcurrent::Exception (0xb52b8700) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0xb52b86c0)
+ std::exception (0xb52b6474) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb52b8700)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionHolder (0xb52b64b0) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionStore (0xb52b64ec) 0
+
+Class QtConcurrent::ResultItem
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultItem (0xb52b6528) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultIteratorBase (0xb52b6b04) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+8 QtConcurrent::ResultStoreBase::~ResultStoreBase
+12 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=28 align=4
+ base size=28 base align=4
+QtConcurrent::ResultStoreBase (0xb52b6c30) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 8u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+8 QFutureInterfaceBase::~QFutureInterfaceBase
+12 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureInterfaceBase (0xb52ed078) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 8u)
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+8 QFutureWatcherBase::metaObject
+12 QFutureWatcherBase::qt_metacast
+16 QFutureWatcherBase::qt_metacall
+20 QFutureWatcherBase::~QFutureWatcherBase
+24 QFutureWatcherBase::~QFutureWatcherBase
+28 QFutureWatcherBase::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QFutureWatcherBase::connectNotify
+52 QFutureWatcherBase::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureWatcherBase (0xb5366500) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 8u)
+ QObject (0xb5355a50) 0
+ primary-for QFutureWatcherBase (0xb5366500)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QThread)
+8 QThread::metaObject
+12 QThread::qt_metacast
+16 QThread::qt_metacall
+20 QThread::~QThread
+24 QThread::~QThread
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QThread::run
+
+Class QThread
+ size=8 align=4
+ base size=8 base align=4
+QThread (0xb518a6c0) 0
+ vptr=((& QThread::_ZTV7QThread) + 8u)
+ QObject (0xb5189a50) 0
+ primary-for QThread (0xb518a6c0)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QThreadPool)
+8 QThreadPool::metaObject
+12 QThreadPool::qt_metacast
+16 QThreadPool::qt_metacall
+20 QThreadPool::~QThreadPool
+24 QThreadPool::~QThreadPool
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QThreadPool
+ size=8 align=4
+ base size=8 base align=4
+QThreadPool (0xb518aa00) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 8u)
+ QObject (0xb5189ce4) 0
+ primary-for QThreadPool (0xb518aa00)
+
+Class QWaitCondition
+ size=4 align=4
+ base size=4 base align=4
+QWaitCondition (0xb5189f00) 0
+
+Class QSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSemaphore (0xb5189f3c) 0
+
+Class QtConcurrent::ThreadEngineBarrier
+ size=12 align=4
+ base size=12 base align=4
+QtConcurrent::ThreadEngineBarrier (0xb5189f78) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+8 QtConcurrent::ThreadEngineBase::run
+12 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+16 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+20 QtConcurrent::ThreadEngineBase::start
+24 QtConcurrent::ThreadEngineBase::finish
+28 QtConcurrent::ThreadEngineBase::threadFunction
+32 QtConcurrent::ThreadEngineBase::shouldStartThread
+36 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+40 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=32 align=4
+ base size=32 base align=4
+QtConcurrent::ThreadEngineBase (0xb518ad80) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 8u)
+ QRunnable (0xb5189fb4) 0
+ primary-for QtConcurrent::ThreadEngineBase (0xb518ad80)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 12u)
+4 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 68u)
+
+Class QtConcurrent::BlockSizeManager
+ size=72 align=4
+ base size=72 base align=4
+QtConcurrent::BlockSizeManager (0xb51dd5a0) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QFactoryInterface)
+8 QFactoryInterface::~QFactoryInterface
+12 QFactoryInterface::~QFactoryInterface
+16 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QFactoryInterface (0xb4ff0e88) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 8u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+8 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+12 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QTextCodecFactoryInterface (0xb4e7d180) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 8u)
+ QFactoryInterface (0xb507c438) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4e7d180)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+8 QTextCodecPlugin::metaObject
+12 QTextCodecPlugin::qt_metacast
+16 QTextCodecPlugin::qt_metacall
+20 QTextCodecPlugin::~QTextCodecPlugin
+24 QTextCodecPlugin::~QTextCodecPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 QTextCodecPlugin::keys
+80 QTextCodecPlugin::create
+84 (int (*)(...))-0x000000008
+88 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+92 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD1Ev
+96 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD0Ev
+100 QTextCodecPlugin::_ZThn8_NK16QTextCodecPlugin4keysEv
+104 QTextCodecPlugin::_ZThn8_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=12 align=4
+ base size=12 base align=4
+QTextCodecPlugin (0xb4e840f0) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 8u)
+ QObject (0xb507c744) 0
+ primary-for QTextCodecPlugin (0xb4e840f0)
+ QTextCodecFactoryInterface (0xb4e7d440) 8 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 92u)
+ QFactoryInterface (0xb507c780) 8 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4e7d440)
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0xb4e9abf4) 0 empty
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QEventLoop)
+8 QEventLoop::metaObject
+12 QEventLoop::qt_metacast
+16 QEventLoop::qt_metacall
+20 QEventLoop::~QEventLoop
+24 QEventLoop::~QEventLoop
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QEventLoop
+ size=8 align=4
+ base size=8 base align=4
+QEventLoop (0xb4eb2000) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 8u)
+ QObject (0xb4e9ac6c) 0
+ primary-for QEventLoop (0xb4eb2000)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+8 QAbstractEventDispatcher::metaObject
+12 QAbstractEventDispatcher::qt_metacast
+16 QAbstractEventDispatcher::qt_metacall
+20 QAbstractEventDispatcher::~QAbstractEventDispatcher
+24 QAbstractEventDispatcher::~QAbstractEventDispatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 QAbstractEventDispatcher::startingUp
+104 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=8 align=4
+ base size=8 base align=4
+QAbstractEventDispatcher (0xb4eb2400) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 8u)
+ QObject (0xb4e9af78) 0
+ primary-for QAbstractEventDispatcher (0xb4eb2400)
+
+Class QModelIndex
+ size=16 align=4
+ base size=16 base align=4
+QModelIndex (0xb4ee01a4) 0
+
+Class QPersistentModelIndex
+ size=4 align=4
+ base size=4 base align=4
+QPersistentModelIndex (0xb4ef1654) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractItemModel)
+8 QAbstractItemModel::metaObject
+12 QAbstractItemModel::qt_metacast
+16 QAbstractItemModel::qt_metacall
+20 QAbstractItemModel::~QAbstractItemModel
+24 QAbstractItemModel::~QAbstractItemModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractItemModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemModel (0xb4f04040) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 8u)
+ QObject (0xb4ef17bc) 0
+ primary-for QAbstractItemModel (0xb4f04040)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTableModel)
+8 QAbstractTableModel::metaObject
+12 QAbstractTableModel::qt_metacast
+16 QAbstractTableModel::qt_metacall
+20 QAbstractTableModel::~QAbstractTableModel
+24 QAbstractTableModel::~QAbstractTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractTableModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTableModel (0xb4f04680) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 8u)
+ QAbstractItemModel (0xb4f046c0) 0
+ primary-for QAbstractTableModel (0xb4f04680)
+ QObject (0xb4f3212c) 0
+ primary-for QAbstractItemModel (0xb4f046c0)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractListModel)
+8 QAbstractListModel::metaObject
+12 QAbstractListModel::qt_metacast
+16 QAbstractListModel::qt_metacall
+20 QAbstractListModel::~QAbstractListModel
+24 QAbstractListModel::~QAbstractListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 __cxa_pure_virtual
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractListModel (0xb4f04900) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 8u)
+ QAbstractItemModel (0xb4f04940) 0
+ primary-for QAbstractListModel (0xb4f04900)
+ QObject (0xb4f32258) 0
+ primary-for QAbstractItemModel (0xb4f04940)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0xb4f5712c) 0
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QCoreApplication)
+8 QCoreApplication::metaObject
+12 QCoreApplication::qt_metacast
+16 QCoreApplication::qt_metacall
+20 QCoreApplication::~QCoreApplication
+24 QCoreApplication::~QCoreApplication
+28 QCoreApplication::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QCoreApplication::notify
+60 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=8 align=4
+ base size=8 base align=4
+QCoreApplication (0xb4f5a400) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 8u)
+ QObject (0xb4f573c0) 0
+ primary-for QCoreApplication (0xb4f5a400)
+
+Class __exception
+ size=32 align=4
+ base size=32 base align=4
+__exception (0xb4f57960) 0
+
+Class QMetaMethod
+ size=8 align=4
+ base size=8 base align=4
+QMetaMethod (0xb4db1690) 0
+
+Class QMetaEnum
+ size=8 align=4
+ base size=8 base align=4
+QMetaEnum (0xb4db199c) 0
+
+Class QMetaProperty
+ size=20 align=4
+ base size=20 base align=4
+QMetaProperty (0xb4db1bf4) 0
+
+Class QMetaClassInfo
+ size=8 align=4
+ base size=8 base align=4
+QMetaClassInfo (0xb4db1ca8) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QMimeData)
+8 QMimeData::metaObject
+12 QMimeData::qt_metacast
+16 QMimeData::qt_metacall
+20 QMimeData::~QMimeData
+24 QMimeData::~QMimeData
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QMimeData::hasFormat
+60 QMimeData::formats
+64 QMimeData::retrieveData
+
+Class QMimeData
+ size=8 align=4
+ base size=8 base align=4
+QMimeData (0xb4dd9240) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 8u)
+ QObject (0xb4db1f00) 0
+ primary-for QMimeData (0xb4dd9240)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+8 QObjectCleanupHandler::metaObject
+12 QObjectCleanupHandler::qt_metacast
+16 QObjectCleanupHandler::qt_metacall
+20 QObjectCleanupHandler::~QObjectCleanupHandler
+24 QObjectCleanupHandler::~QObjectCleanupHandler
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=12 align=4
+ base size=12 base align=4
+QObjectCleanupHandler (0xb4dd9500) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 8u)
+ QObject (0xb4dea12c) 0
+ primary-for QObjectCleanupHandler (0xb4dd9500)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSharedMemory)
+8 QSharedMemory::metaObject
+12 QSharedMemory::qt_metacast
+16 QSharedMemory::qt_metacall
+20 QSharedMemory::~QSharedMemory
+24 QSharedMemory::~QSharedMemory
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=8 align=4
+ base size=8 base align=4
+QSharedMemory (0xb4dd9740) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 8u)
+ QObject (0xb4dea258) 0
+ primary-for QSharedMemory (0xb4dd9740)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSignalMapper)
+8 QSignalMapper::metaObject
+12 QSignalMapper::qt_metacast
+16 QSignalMapper::qt_metacall
+20 QSignalMapper::~QSignalMapper
+24 QSignalMapper::~QSignalMapper
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=8 align=4
+ base size=8 base align=4
+QSignalMapper (0xb4dd9a00) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 8u)
+ QObject (0xb4dea474) 0
+ primary-for QSignalMapper (0xb4dd9a00)
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QSocketNotifier)
+8 QSocketNotifier::metaObject
+12 QSocketNotifier::qt_metacast
+16 QSocketNotifier::qt_metacall
+20 QSocketNotifier::~QSocketNotifier
+24 QSocketNotifier::~QSocketNotifier
+28 QSocketNotifier::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=20 align=4
+ base size=17 base align=4
+QSocketNotifier (0xb4dd9cc0) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 8u)
+ QObject (0xb4dea690) 0
+ primary-for QSocketNotifier (0xb4dd9cc0)
+
+Class QSystemSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSystemSemaphore (0xb4dea960) 0
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QTimer)
+8 QTimer::metaObject
+12 QTimer::qt_metacast
+16 QTimer::qt_metacall
+20 QTimer::~QTimer
+24 QTimer::~QTimer
+28 QObject::event
+32 QObject::eventFilter
+36 QTimer::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QTimer
+ size=24 align=4
+ base size=21 base align=4
+QTimer (0xb4e23080) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 8u)
+ QObject (0xb4deaa14) 0
+ primary-for QTimer (0xb4e23080)
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTranslator)
+8 QTranslator::metaObject
+12 QTranslator::qt_metacast
+16 QTranslator::qt_metacall
+20 QTranslator::~QTranslator
+24 QTranslator::~QTranslator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTranslator::translate
+60 QTranslator::isEmpty
+
+Class QTranslator
+ size=8 align=4
+ base size=8 base align=4
+QTranslator (0xb4e235c0) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 8u)
+ QObject (0xb4deaca8) 0
+ primary-for QTranslator (0xb4e235c0)
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QLibrary)
+8 QLibrary::metaObject
+12 QLibrary::qt_metacast
+16 QLibrary::qt_metacall
+20 QLibrary::~QLibrary
+24 QLibrary::~QLibrary
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QLibrary
+ size=16 align=4
+ base size=13 base align=4
+QLibrary (0xb4e23900) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 8u)
+ QObject (0xb4deaf78) 0
+ primary-for QLibrary (0xb4e23900)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QPluginLoader)
+8 QPluginLoader::metaObject
+12 QPluginLoader::qt_metacast
+16 QPluginLoader::qt_metacall
+20 QPluginLoader::~QPluginLoader
+24 QPluginLoader::~QPluginLoader
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=16 align=4
+ base size=13 base align=4
+QPluginLoader (0xb4e23d00) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 8u)
+ QObject (0xb4e571e0) 0
+ primary-for QPluginLoader (0xb4e23d00)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0xb4e5730c) 0
+
+Class QReadWriteLock
+ size=4 align=4
+ base size=4 base align=4
+QReadWriteLock (0xb4c8d30c) 0
+
+Class QReadLocker
+ size=4 align=4
+ base size=4 base align=4
+QReadLocker (0xb4c8d348) 0
+
+Class QWriteLocker
+ size=4 align=4
+ base size=4 base align=4
+QWriteLocker (0xb4c8d834) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0xb4c8dd20) 0
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractAnimation)
+8 QAbstractAnimation::metaObject
+12 QAbstractAnimation::qt_metacast
+16 QAbstractAnimation::qt_metacall
+20 QAbstractAnimation::~QAbstractAnimation
+24 QAbstractAnimation::~QAbstractAnimation
+28 QAbstractAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=8 align=4
+ base size=8 base align=4
+QAbstractAnimation (0xb4ca9c00) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 8u)
+ QObject (0xb4c8dd98) 0
+ primary-for QAbstractAnimation (0xb4ca9c00)
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QAnimationGroup)
+8 QAnimationGroup::metaObject
+12 QAnimationGroup::qt_metacast
+16 QAnimationGroup::qt_metacall
+20 QAnimationGroup::~QAnimationGroup
+24 QAnimationGroup::~QAnimationGroup
+28 QAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QAnimationGroup (0xb4ca9ec0) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 8u)
+ QAbstractAnimation (0xb4ca9f00) 0
+ primary-for QAnimationGroup (0xb4ca9ec0)
+ QObject (0xb4cc8000) 0
+ primary-for QAbstractAnimation (0xb4ca9f00)
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+8 QParallelAnimationGroup::metaObject
+12 QParallelAnimationGroup::qt_metacast
+16 QParallelAnimationGroup::qt_metacall
+20 QParallelAnimationGroup::~QParallelAnimationGroup
+24 QParallelAnimationGroup::~QParallelAnimationGroup
+28 QParallelAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QParallelAnimationGroup::duration
+60 QParallelAnimationGroup::updateCurrentTime
+64 QParallelAnimationGroup::updateState
+68 QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QParallelAnimationGroup (0xb4cd11c0) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 8u)
+ QAnimationGroup (0xb4cd1200) 0
+ primary-for QParallelAnimationGroup (0xb4cd11c0)
+ QAbstractAnimation (0xb4cd1240) 0
+ primary-for QAnimationGroup (0xb4cd1200)
+ QObject (0xb4cc821c) 0
+ primary-for QAbstractAnimation (0xb4cd1240)
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QPauseAnimation)
+8 QPauseAnimation::metaObject
+12 QPauseAnimation::qt_metacast
+16 QPauseAnimation::qt_metacall
+20 QPauseAnimation::~QPauseAnimation
+24 QPauseAnimation::~QPauseAnimation
+28 QPauseAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QPauseAnimation::duration
+60 QPauseAnimation::updateCurrentTime
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=8 align=4
+ base size=8 base align=4
+QPauseAnimation (0xb4cd1500) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 8u)
+ QAbstractAnimation (0xb4cd1540) 0
+ primary-for QPauseAnimation (0xb4cd1500)
+ QObject (0xb4cc8438) 0
+ primary-for QAbstractAnimation (0xb4cd1540)
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QVariantAnimation)
+8 QVariantAnimation::metaObject
+12 QVariantAnimation::qt_metacast
+16 QVariantAnimation::qt_metacall
+20 QVariantAnimation::~QVariantAnimation
+24 QVariantAnimation::~QVariantAnimation
+28 QVariantAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QVariantAnimation::duration
+60 QVariantAnimation::updateCurrentTime
+64 QVariantAnimation::updateState
+68 QAbstractAnimation::updateDirection
+72 __cxa_pure_virtual
+76 QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=8 align=4
+ base size=8 base align=4
+QVariantAnimation (0xb4cd1800) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 8u)
+ QAbstractAnimation (0xb4cd1840) 0
+ primary-for QVariantAnimation (0xb4cd1800)
+ QObject (0xb4cc8654) 0
+ primary-for QAbstractAnimation (0xb4cd1840)
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QPropertyAnimation)
+8 QPropertyAnimation::metaObject
+12 QPropertyAnimation::qt_metacast
+16 QPropertyAnimation::qt_metacall
+20 QPropertyAnimation::~QPropertyAnimation
+24 QPropertyAnimation::~QPropertyAnimation
+28 QPropertyAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QVariantAnimation::duration
+60 QVariantAnimation::updateCurrentTime
+64 QPropertyAnimation::updateState
+68 QAbstractAnimation::updateDirection
+72 QPropertyAnimation::updateCurrentValue
+76 QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=8 align=4
+ base size=8 base align=4
+QPropertyAnimation (0xb4cd1c40) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 8u)
+ QVariantAnimation (0xb4cd1c80) 0
+ primary-for QPropertyAnimation (0xb4cd1c40)
+ QAbstractAnimation (0xb4cd1cc0) 0
+ primary-for QVariantAnimation (0xb4cd1c80)
+ QObject (0xb4cc8870) 0
+ primary-for QAbstractAnimation (0xb4cd1cc0)
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+8 QSequentialAnimationGroup::metaObject
+12 QSequentialAnimationGroup::qt_metacast
+16 QSequentialAnimationGroup::qt_metacall
+20 QSequentialAnimationGroup::~QSequentialAnimationGroup
+24 QSequentialAnimationGroup::~QSequentialAnimationGroup
+28 QSequentialAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSequentialAnimationGroup::duration
+60 QSequentialAnimationGroup::updateCurrentTime
+64 QSequentialAnimationGroup::updateState
+68 QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QSequentialAnimationGroup (0xb4cd1f80) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 8u)
+ QAnimationGroup (0xb4cd1fc0) 0
+ primary-for QSequentialAnimationGroup (0xb4cd1f80)
+ QAbstractAnimation (0xb4d0d000) 0
+ primary-for QAnimationGroup (0xb4cd1fc0)
+ QObject (0xb4cc8a8c) 0
+ primary-for QAbstractAnimation (0xb4d0d000)
+
+Class QDomImplementation
+ size=4 align=4
+ base size=4 base align=4
+QDomImplementation (0xb4cc8ca8) 0
+
+Class QDomNode
+ size=4 align=4
+ base size=4 base align=4
+QDomNode (0xb4cc8ce4) 0
+
+Class QDomNodeList
+ size=4 align=4
+ base size=4 base align=4
+QDomNodeList (0xb4cc8d20) 0
+
+Class QDomDocumentType
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentType (0xb4d0d4c0) 0
+ QDomNode (0xb4cc8e10) 0
+
+Class QDomDocument
+ size=4 align=4
+ base size=4 base align=4
+QDomDocument (0xb4d0d580) 0
+ QDomNode (0xb4cc8e88) 0
+
+Class QDomNamedNodeMap
+ size=4 align=4
+ base size=4 base align=4
+QDomNamedNodeMap (0xb4cc8f00) 0
+
+Class QDomDocumentFragment
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentFragment (0xb4d0d780) 0
+ QDomNode (0xb4cc8fb4) 0
+
+Class QDomCharacterData
+ size=4 align=4
+ base size=4 base align=4
+QDomCharacterData (0xb4d0d840) 0
+ QDomNode (0xb4d4c03c) 0
+
+Class QDomAttr
+ size=4 align=4
+ base size=4 base align=4
+QDomAttr (0xb4d0d8c0) 0
+ QDomNode (0xb4d4c078) 0
+
+Class QDomElement
+ size=4 align=4
+ base size=4 base align=4
+QDomElement (0xb4d0d980) 0
+ QDomNode (0xb4d4c0f0) 0
+
+Class QDomText
+ size=4 align=4
+ base size=4 base align=4
+QDomText (0xb4d0db40) 0
+ QDomCharacterData (0xb4d0db80) 0
+ QDomNode (0xb4d4c258) 0
+
+Class QDomComment
+ size=4 align=4
+ base size=4 base align=4
+QDomComment (0xb4d0dc40) 0
+ QDomCharacterData (0xb4d0dc80) 0
+ QDomNode (0xb4d4c2d0) 0
+
+Class QDomCDATASection
+ size=4 align=4
+ base size=4 base align=4
+QDomCDATASection (0xb4d0dd40) 0
+ QDomText (0xb4d0dd80) 0
+ QDomCharacterData (0xb4d0ddc0) 0
+ QDomNode (0xb4d4c348) 0
+
+Class QDomNotation
+ size=4 align=4
+ base size=4 base align=4
+QDomNotation (0xb4d0de80) 0
+ QDomNode (0xb4d4c3c0) 0
+
+Class QDomEntity
+ size=4 align=4
+ base size=4 base align=4
+QDomEntity (0xb4d0df40) 0
+ QDomNode (0xb4d4c438) 0
+
+Class QDomEntityReference
+ size=4 align=4
+ base size=4 base align=4
+QDomEntityReference (0xb4d6a000) 0
+ QDomNode (0xb4d4c4b0) 0
+
+Class QDomProcessingInstruction
+ size=4 align=4
+ base size=4 base align=4
+QDomProcessingInstruction (0xb4d6a0c0) 0
+ QDomNode (0xb4d4c528) 0
+
+Class QXmlNamespaceSupport
+ size=4 align=4
+ base size=4 base align=4
+QXmlNamespaceSupport (0xb4d4c5a0) 0
+
+Class QXmlAttributes::Attribute
+ size=16 align=4
+ base size=16 base align=4
+QXmlAttributes::Attribute (0xb4d4c618) 0
+
+Vtable for QXmlAttributes
+QXmlAttributes::_ZTV14QXmlAttributes: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlAttributes)
+8 QXmlAttributes::~QXmlAttributes
+12 QXmlAttributes::~QXmlAttributes
+
+Class QXmlAttributes
+ size=12 align=4
+ base size=12 base align=4
+QXmlAttributes (0xb4d4c5dc) 0
+ vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 8u)
+
+Vtable for QXmlInputSource
+QXmlInputSource::_ZTV15QXmlInputSource: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlInputSource)
+8 QXmlInputSource::~QXmlInputSource
+12 QXmlInputSource::~QXmlInputSource
+16 QXmlInputSource::setData
+20 QXmlInputSource::setData
+24 QXmlInputSource::fetchData
+28 QXmlInputSource::data
+32 QXmlInputSource::next
+36 QXmlInputSource::reset
+40 QXmlInputSource::fromRawData
+
+Class QXmlInputSource
+ size=8 align=4
+ base size=8 base align=4
+QXmlInputSource (0xb4d4cbb8) 0
+ vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 8u)
+
+Class QXmlParseException
+ size=4 align=4
+ base size=4 base align=4
+QXmlParseException (0xb4d4cbf4) 0
+
+Vtable for QXmlReader
+QXmlReader::_ZTV10QXmlReader: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QXmlReader)
+8 QXmlReader::~QXmlReader
+12 QXmlReader::~QXmlReader
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+
+Class QXmlReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlReader (0xb4d4cc6c) 0 nearly-empty
+ vptr=((& QXmlReader::_ZTV10QXmlReader) + 8u)
+
+Vtable for QXmlSimpleReader
+QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlSimpleReader)
+8 QXmlSimpleReader::~QXmlSimpleReader
+12 QXmlSimpleReader::~QXmlSimpleReader
+16 QXmlSimpleReader::feature
+20 QXmlSimpleReader::setFeature
+24 QXmlSimpleReader::hasFeature
+28 QXmlSimpleReader::property
+32 QXmlSimpleReader::setProperty
+36 QXmlSimpleReader::hasProperty
+40 QXmlSimpleReader::setEntityResolver
+44 QXmlSimpleReader::entityResolver
+48 QXmlSimpleReader::setDTDHandler
+52 QXmlSimpleReader::DTDHandler
+56 QXmlSimpleReader::setContentHandler
+60 QXmlSimpleReader::contentHandler
+64 QXmlSimpleReader::setErrorHandler
+68 QXmlSimpleReader::errorHandler
+72 QXmlSimpleReader::setLexicalHandler
+76 QXmlSimpleReader::lexicalHandler
+80 QXmlSimpleReader::setDeclHandler
+84 QXmlSimpleReader::declHandler
+88 QXmlSimpleReader::parse
+92 QXmlSimpleReader::parse
+96 QXmlSimpleReader::parse
+100 QXmlSimpleReader::parseContinue
+
+Class QXmlSimpleReader
+ size=8 align=4
+ base size=8 base align=4
+QXmlSimpleReader (0xb4d6a840) 0
+ vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 8u)
+ QXmlReader (0xb4d4ce88) 0 nearly-empty
+ primary-for QXmlSimpleReader (0xb4d6a840)
+
+Vtable for QXmlLocator
+QXmlLocator::_ZTV11QXmlLocator: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QXmlLocator)
+8 QXmlLocator::~QXmlLocator
+12 QXmlLocator::~QXmlLocator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlLocator
+ size=4 align=4
+ base size=4 base align=4
+QXmlLocator (0xb4b94000) 0 nearly-empty
+ vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 8u)
+
+Vtable for QXmlContentHandler
+QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlContentHandler)
+8 QXmlContentHandler::~QXmlContentHandler
+12 QXmlContentHandler::~QXmlContentHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QXmlContentHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlContentHandler (0xb4b9403c) 0 nearly-empty
+ vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 8u)
+
+Vtable for QXmlErrorHandler
+QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlErrorHandler)
+8 QXmlErrorHandler::~QXmlErrorHandler
+12 QXmlErrorHandler::~QXmlErrorHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlErrorHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlErrorHandler (0xb4b94258) 0 nearly-empty
+ vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 8u)
+
+Vtable for QXmlDTDHandler
+QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlDTDHandler)
+8 QXmlDTDHandler::~QXmlDTDHandler
+12 QXmlDTDHandler::~QXmlDTDHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QXmlDTDHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDTDHandler (0xb4b94474) 0 nearly-empty
+ vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 8u)
+
+Vtable for QXmlEntityResolver
+QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlEntityResolver)
+8 QXmlEntityResolver::~QXmlEntityResolver
+12 QXmlEntityResolver::~QXmlEntityResolver
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlEntityResolver (0xb4b94690) 0 nearly-empty
+ vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 8u)
+
+Vtable for QXmlLexicalHandler
+QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlLexicalHandler)
+8 QXmlLexicalHandler::~QXmlLexicalHandler
+12 QXmlLexicalHandler::~QXmlLexicalHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+
+Class QXmlLexicalHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlLexicalHandler (0xb4b948ac) 0 nearly-empty
+ vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 8u)
+
+Vtable for QXmlDeclHandler
+QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlDeclHandler)
+8 QXmlDeclHandler::~QXmlDeclHandler
+12 QXmlDeclHandler::~QXmlDeclHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlDeclHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDeclHandler (0xb4b94ac8) 0 nearly-empty
+ vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 8u)
+
+Vtable for QXmlDefaultHandler
+QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+8 QXmlDefaultHandler::~QXmlDefaultHandler
+12 QXmlDefaultHandler::~QXmlDefaultHandler
+16 QXmlDefaultHandler::setDocumentLocator
+20 QXmlDefaultHandler::startDocument
+24 QXmlDefaultHandler::endDocument
+28 QXmlDefaultHandler::startPrefixMapping
+32 QXmlDefaultHandler::endPrefixMapping
+36 QXmlDefaultHandler::startElement
+40 QXmlDefaultHandler::endElement
+44 QXmlDefaultHandler::characters
+48 QXmlDefaultHandler::ignorableWhitespace
+52 QXmlDefaultHandler::processingInstruction
+56 QXmlDefaultHandler::skippedEntity
+60 QXmlDefaultHandler::errorString
+64 QXmlDefaultHandler::warning
+68 QXmlDefaultHandler::error
+72 QXmlDefaultHandler::fatalError
+76 QXmlDefaultHandler::notationDecl
+80 QXmlDefaultHandler::unparsedEntityDecl
+84 QXmlDefaultHandler::resolveEntity
+88 QXmlDefaultHandler::startDTD
+92 QXmlDefaultHandler::endDTD
+96 QXmlDefaultHandler::startEntity
+100 QXmlDefaultHandler::endEntity
+104 QXmlDefaultHandler::startCDATA
+108 QXmlDefaultHandler::endCDATA
+112 QXmlDefaultHandler::comment
+116 QXmlDefaultHandler::attributeDecl
+120 QXmlDefaultHandler::internalEntityDecl
+124 QXmlDefaultHandler::externalEntityDecl
+128 (int (*)(...))-0x000000004
+132 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+136 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD1Ev
+140 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD0Ev
+144 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler7warningERK18QXmlParseException
+148 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler5errorERK18QXmlParseException
+152 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException
+156 QXmlDefaultHandler::_ZThn4_NK18QXmlDefaultHandler11errorStringEv
+160 (int (*)(...))-0x000000008
+164 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+168 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev
+172 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev
+176 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_
+180 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_
+184 QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv
+188 (int (*)(...))-0x00000000c
+192 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+196 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD1Ev
+200 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD0Ev
+204 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource
+208 QXmlDefaultHandler::_ZThn12_NK18QXmlDefaultHandler11errorStringEv
+212 (int (*)(...))-0x000000010
+216 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+220 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev
+224 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev
+228 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_
+232 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler6endDTDEv
+236 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler11startEntityERK7QString
+240 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler9endEntityERK7QString
+244 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler10startCDATAEv
+248 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8endCDATAEv
+252 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler7commentERK7QString
+256 QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv
+260 (int (*)(...))-0x000000014
+264 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+268 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD1Ev
+272 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD0Ev
+276 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_
+280 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_
+284 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_
+288 QXmlDefaultHandler::_ZThn20_NK18QXmlDefaultHandler11errorStringEv
+
+Class QXmlDefaultHandler
+ size=28 align=4
+ base size=28 base align=4
+QXmlDefaultHandler (0xb4b6ec24) 0
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 8u)
+ QXmlContentHandler (0xb4b94ce4) 0 nearly-empty
+ primary-for QXmlDefaultHandler (0xb4b6ec24)
+ QXmlErrorHandler (0xb4b94d20) 4 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 136u)
+ QXmlDTDHandler (0xb4b94d5c) 8 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 168u)
+ QXmlEntityResolver (0xb4b94d98) 12 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 196u)
+ QXmlLexicalHandler (0xb4b94dd4) 16 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 220u)
+ QXmlDeclHandler (0xb4b94e10) 20 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 268u)
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb4bd3c6c) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb4bed834) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb4c1e3c0) 0
+ QVector<QPoint> (0xb4bedec4) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb4c1ea00) 0
+ QVector<QPointF> (0xb4c438ac) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb4a7021c) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb4a701e0) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb4a70564) 0
+
+Class QPainterPath::Element
+ size=20 align=4
+ base size=20 base align=4
+QPainterPath::Element (0xb4aa5708) 0
+
+Class QPainterPath
+ size=4 align=4
+ base size=4 base align=4
+QPainterPath (0xb4aa56cc) 0
+
+Class QPainterPathPrivate
+ size=8 align=4
+ base size=8 base align=4
+QPainterPathPrivate (0xb4aa5bf4) 0
+
+Class QPainterPathStroker
+ size=4 align=4
+ base size=4 base align=4
+QPainterPathStroker (0xb4aa5d20) 0
+
+Class QTransform
+ size=80 align=4
+ base size=80 base align=4
+QTransform (0xb4b04ca8) 0
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb496ebf4) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb49a1040) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb497b5dc) 0
+ primary-for QImage (0xb49a1040)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb49a1940) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb49df1a4) 0
+ primary-for QPixmap (0xb49a1940)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb49df834) 0
+
+Class QBrushData
+ size=104 align=4
+ base size=104 base align=4
+QBrushData (0xb49df9d8) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb49dfd98) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb4a287c0) 0
+ QGradient (0xb4a5703c) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb4a288c0) 0
+ QGradient (0xb4a57078) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb4a289c0) 0
+ QGradient (0xb4a570b4) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb4a570f0) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb4881400) 0
+ QPalette (0xb4a579d8) 0
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb4898b40) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb4898d5c) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb4898fb4) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb48ea078) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb48ea0b4) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb492cf78) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb492cfb4) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb47771e0) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb47868c0) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb477721c) 0
+ primary-for QWidget (0xb47868c0)
+ QPaintDevice (0xb4777258) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Vtable for QDesignerActionEditorInterface
+QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+8 QDesignerActionEditorInterface::metaObject
+12 QDesignerActionEditorInterface::qt_metacast
+16 QDesignerActionEditorInterface::qt_metacall
+20 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+24 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerActionEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 (int (*)(...))-0x000000008
+244 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+248 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD1Ev
+252 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerActionEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerActionEditorInterface (0xb4849280) 0
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 8u)
+ QWidget (0xb48550a0) 0
+ primary-for QDesignerActionEditorInterface (0xb4849280)
+ QObject (0xb483799c) 0
+ primary-for QWidget (0xb48550a0)
+ QPaintDevice (0xb48379d8) 8
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 248u)
+
+Vtable for QDesignerBrushManagerInterface
+QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerBrushManagerInterface)
+8 QDesignerBrushManagerInterface::metaObject
+12 QDesignerBrushManagerInterface::qt_metacast
+16 QDesignerBrushManagerInterface::qt_metacall
+20 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+24 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerBrushManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerBrushManagerInterface (0xb48494c0) 0
+ vptr=((& QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface) + 8u)
+ QObject (0xb4837b04) 0
+ primary-for QDesignerBrushManagerInterface (0xb48494c0)
+
+Vtable for QDesignerDnDItemInterface
+QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QDesignerDnDItemInterface)
+8 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+12 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerDnDItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDnDItemInterface (0xb4837e4c) 0 nearly-empty
+ vptr=((& QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface) + 8u)
+
+Vtable for QDesignerFormEditorInterface
+QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormEditorInterface)
+8 QDesignerFormEditorInterface::metaObject
+12 QDesignerFormEditorInterface::qt_metacast
+16 QDesignerFormEditorInterface::qt_metacall
+20 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+24 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QDesignerFormEditorInterface
+ size=60 align=4
+ base size=60 base align=4
+QDesignerFormEditorInterface (0xb4849a80) 0
+ vptr=((& QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface) + 8u)
+ QObject (0xb466d12c) 0
+ primary-for QDesignerFormEditorInterface (0xb4849a80)
+
+Vtable for QDesignerFormEditorPluginInterface
+QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormEditorPluginInterface)
+8 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+12 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QDesignerFormEditorPluginInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormEditorPluginInterface (0xb466d528) 0 nearly-empty
+ vptr=((& QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface) + 8u)
+
+Vtable for QDesignerFormWindowInterface
+QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface: 114u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+8 QDesignerFormWindowInterface::metaObject
+12 QDesignerFormWindowInterface::qt_metacast
+16 QDesignerFormWindowInterface::qt_metacall
+20 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+24 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 __cxa_pure_virtual
+280 __cxa_pure_virtual
+284 __cxa_pure_virtual
+288 __cxa_pure_virtual
+292 __cxa_pure_virtual
+296 __cxa_pure_virtual
+300 __cxa_pure_virtual
+304 QDesignerFormWindowInterface::core
+308 __cxa_pure_virtual
+312 __cxa_pure_virtual
+316 __cxa_pure_virtual
+320 __cxa_pure_virtual
+324 __cxa_pure_virtual
+328 __cxa_pure_virtual
+332 __cxa_pure_virtual
+336 __cxa_pure_virtual
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 __cxa_pure_virtual
+368 __cxa_pure_virtual
+372 __cxa_pure_virtual
+376 __cxa_pure_virtual
+380 __cxa_pure_virtual
+384 __cxa_pure_virtual
+388 __cxa_pure_virtual
+392 __cxa_pure_virtual
+396 __cxa_pure_virtual
+400 __cxa_pure_virtual
+404 __cxa_pure_virtual
+408 __cxa_pure_virtual
+412 __cxa_pure_virtual
+416 __cxa_pure_virtual
+420 __cxa_pure_virtual
+424 __cxa_pure_virtual
+428 (int (*)(...))-0x000000008
+432 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+436 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD1Ev
+440 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD0Ev
+444 QWidget::_ZThn8_NK7QWidget7devTypeEv
+448 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+452 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerFormWindowInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerFormWindowInterface (0xb46ad400) 0
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 8u)
+ QWidget (0xb46afa00) 0
+ primary-for QDesignerFormWindowInterface (0xb46ad400)
+ QObject (0xb466da14) 0
+ primary-for QWidget (0xb46afa00)
+ QPaintDevice (0xb466da50) 8
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 436u)
+
+Vtable for QDesignerFormWindowCursorInterface
+QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormWindowCursorInterface)
+8 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+12 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+
+Class QDesignerFormWindowCursorInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormWindowCursorInterface (0xb466db7c) 0 nearly-empty
+ vptr=((& QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface) + 8u)
+
+Vtable for QDesignerFormWindowManagerInterface
+QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface: 39u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI35QDesignerFormWindowManagerInterface)
+8 QDesignerFormWindowManagerInterface::metaObject
+12 QDesignerFormWindowManagerInterface::qt_metacast
+16 QDesignerFormWindowManagerInterface::qt_metacall
+20 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+24 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerFormWindowManagerInterface::actionCut
+60 QDesignerFormWindowManagerInterface::actionCopy
+64 QDesignerFormWindowManagerInterface::actionPaste
+68 QDesignerFormWindowManagerInterface::actionDelete
+72 QDesignerFormWindowManagerInterface::actionSelectAll
+76 QDesignerFormWindowManagerInterface::actionLower
+80 QDesignerFormWindowManagerInterface::actionRaise
+84 QDesignerFormWindowManagerInterface::actionUndo
+88 QDesignerFormWindowManagerInterface::actionRedo
+92 QDesignerFormWindowManagerInterface::actionHorizontalLayout
+96 QDesignerFormWindowManagerInterface::actionVerticalLayout
+100 QDesignerFormWindowManagerInterface::actionSplitHorizontal
+104 QDesignerFormWindowManagerInterface::actionSplitVertical
+108 QDesignerFormWindowManagerInterface::actionGridLayout
+112 QDesignerFormWindowManagerInterface::actionBreakLayout
+116 QDesignerFormWindowManagerInterface::actionAdjustSize
+120 QDesignerFormWindowManagerInterface::activeFormWindow
+124 QDesignerFormWindowManagerInterface::formWindowCount
+128 QDesignerFormWindowManagerInterface::formWindow
+132 QDesignerFormWindowManagerInterface::createFormWindow
+136 QDesignerFormWindowManagerInterface::core
+140 __cxa_pure_virtual
+144 QDesignerFormWindowManagerInterface::addFormWindow
+148 QDesignerFormWindowManagerInterface::removeFormWindow
+152 QDesignerFormWindowManagerInterface::setActiveFormWindow
+
+Class QDesignerFormWindowManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowManagerInterface (0xb46ad840) 0
+ vptr=((& QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface) + 8u)
+ QObject (0xb466dd98) 0
+ primary-for QDesignerFormWindowManagerInterface (0xb46ad840)
+
+Vtable for QDesignerFormWindowToolInterface
+QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerFormWindowToolInterface)
+8 QDesignerFormWindowToolInterface::metaObject
+12 QDesignerFormWindowToolInterface::qt_metacast
+16 QDesignerFormWindowToolInterface::qt_metacall
+20 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+24 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QDesignerFormWindowToolInterface::saveToDom
+84 QDesignerFormWindowToolInterface::loadFromDom
+88 __cxa_pure_virtual
+
+Class QDesignerFormWindowToolInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowToolInterface (0xb46ada80) 0
+ vptr=((& QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface) + 8u)
+ QObject (0xb466dec4) 0
+ primary-for QDesignerFormWindowToolInterface (0xb46ada80)
+
+Vtable for QDesignerIconCacheInterface
+QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerIconCacheInterface)
+8 QDesignerIconCacheInterface::metaObject
+12 QDesignerIconCacheInterface::qt_metacast
+16 QDesignerIconCacheInterface::qt_metacall
+20 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+24 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QDesignerIconCacheInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerIconCacheInterface (0xb46add40) 0
+ vptr=((& QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface) + 8u)
+ QObject (0xb46ed000) 0
+ primary-for QDesignerIconCacheInterface (0xb46add40)
+
+Vtable for QDesignerIntegrationInterface
+QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerIntegrationInterface)
+8 QDesignerIntegrationInterface::metaObject
+12 QDesignerIntegrationInterface::qt_metacast
+16 QDesignerIntegrationInterface::qt_metacall
+20 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+24 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+
+Class QDesignerIntegrationInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerIntegrationInterface (0xb46fc040) 0
+ vptr=((& QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface) + 8u)
+ QObject (0xb46ed348) 0
+ primary-for QDesignerIntegrationInterface (0xb46fc040)
+
+Vtable for QAbstractExtensionFactory
+QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionFactory)
+8 QAbstractExtensionFactory::~QAbstractExtensionFactory
+12 QAbstractExtensionFactory::~QAbstractExtensionFactory
+16 __cxa_pure_virtual
+
+Class QAbstractExtensionFactory
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionFactory (0xb46ed4b0) 0 nearly-empty
+ vptr=((& QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory) + 8u)
+
+Vtable for QAbstractExtensionManager
+QAbstractExtensionManager::_ZTV25QAbstractExtensionManager: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionManager)
+8 QAbstractExtensionManager::~QAbstractExtensionManager
+12 QAbstractExtensionManager::~QAbstractExtensionManager
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QAbstractExtensionManager
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionManager (0xb46ed99c) 0 nearly-empty
+ vptr=((& QAbstractExtensionManager::_ZTV25QAbstractExtensionManager) + 8u)
+
+Vtable for QDesignerLanguageExtension
+QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension: 13u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerLanguageExtension)
+8 QDesignerLanguageExtension::~QDesignerLanguageExtension
+12 QDesignerLanguageExtension::~QDesignerLanguageExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QDesignerLanguageExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLanguageExtension (0xb46ede88) 0 nearly-empty
+ vptr=((& QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension) + 8u)
+
+Vtable for QDesignerMetaDataBaseItemInterface
+QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerMetaDataBaseItemInterface)
+8 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+12 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMetaDataBaseItemInterface (0xb471b564) 0 nearly-empty
+ vptr=((& QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerMetaDataBaseInterface
+QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerMetaDataBaseInterface)
+8 QDesignerMetaDataBaseInterface::metaObject
+12 QDesignerMetaDataBaseInterface::qt_metacast
+16 QDesignerMetaDataBaseInterface::qt_metacall
+20 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+24 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerMetaDataBaseInterface (0xb4721440) 0
+ vptr=((& QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface) + 8u)
+ QObject (0xb471b780) 0
+ primary-for QDesignerMetaDataBaseInterface (0xb4721440)
+
+Vtable for QDesignerObjectInspectorInterface
+QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+8 QDesignerObjectInspectorInterface::metaObject
+12 QDesignerObjectInspectorInterface::qt_metacast
+16 QDesignerObjectInspectorInterface::qt_metacall
+20 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+24 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerObjectInspectorInterface::core
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+240 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD1Ev
+244 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerObjectInspectorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerObjectInspectorInterface (0xb4721680) 0
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 8u)
+ QWidget (0xb472ac80) 0
+ primary-for QDesignerObjectInspectorInterface (0xb4721680)
+ QObject (0xb471b8ac) 0
+ primary-for QWidget (0xb472ac80)
+ QPaintDevice (0xb471b8e8) 8
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 240u)
+
+Class QDesignerPromotionInterface::PromotedClass
+ size=8 align=4
+ base size=8 base align=4
+QDesignerPromotionInterface::PromotedClass (0xb471ba50) 0
+
+Vtable for QDesignerPromotionInterface
+QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerPromotionInterface)
+8 QDesignerPromotionInterface::~QDesignerPromotionInterface
+12 QDesignerPromotionInterface::~QDesignerPromotionInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerPromotionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPromotionInterface (0xb471ba14) 0 nearly-empty
+ vptr=((& QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface) + 8u)
+
+Vtable for QDesignerPropertyEditorInterface
+QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface: 70u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+8 QDesignerPropertyEditorInterface::metaObject
+12 QDesignerPropertyEditorInterface::qt_metacast
+16 QDesignerPropertyEditorInterface::qt_metacall
+20 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+24 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerPropertyEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 (int (*)(...))-0x000000008
+256 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+260 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD1Ev
+264 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD0Ev
+268 QWidget::_ZThn8_NK7QWidget7devTypeEv
+272 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+276 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerPropertyEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerPropertyEditorInterface (0xb4721940) 0
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 8u)
+ QWidget (0xb473e7d0) 0
+ primary-for QDesignerPropertyEditorInterface (0xb4721940)
+ QObject (0xb471ba8c) 0
+ primary-for QWidget (0xb473e7d0)
+ QPaintDevice (0xb471bac8) 8
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 260u)
+
+Vtable for QDesignerResourceBrowserInterface
+QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+8 QDesignerResourceBrowserInterface::metaObject
+12 QDesignerResourceBrowserInterface::qt_metacast
+16 QDesignerResourceBrowserInterface::qt_metacall
+20 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+24 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+240 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD1Ev
+244 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerResourceBrowserInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerResourceBrowserInterface (0xb4721b80) 0
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 8u)
+ QWidget (0xb4741d20) 0
+ primary-for QDesignerResourceBrowserInterface (0xb4721b80)
+ QObject (0xb471bbf4) 0
+ primary-for QWidget (0xb4741d20)
+ QPaintDevice (0xb471bc30) 8
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 240u)
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb471bd5c) 0
+
+Class QDesignerWidgetBoxInterface::Widget
+ size=16 align=4
+ base size=16 base align=4
+QDesignerWidgetBoxInterface::Widget (0xb457403c) 0
+
+Class QDesignerWidgetBoxInterface::Category
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetBoxInterface::Category (0xb4574078) 0
+
+Vtable for QDesignerWidgetBoxInterface
+QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface: 76u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+8 QDesignerWidgetBoxInterface::metaObject
+12 QDesignerWidgetBoxInterface::qt_metacast
+16 QDesignerWidgetBoxInterface::qt_metacall
+20 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+24 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 (int (*)(...))-0x000000008
+280 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+284 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD1Ev
+288 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD0Ev
+292 QWidget::_ZThn8_NK7QWidget7devTypeEv
+296 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+300 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerWidgetBoxInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerWidgetBoxInterface (0xb456e1c0) 0
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 8u)
+ QWidget (0xb456d9b0) 0
+ primary-for QDesignerWidgetBoxInterface (0xb456e1c0)
+ QObject (0xb471bfb4) 0
+ primary-for QWidget (0xb456d9b0)
+ QPaintDevice (0xb4574000) 8
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 284u)
+
+Vtable for QDesignerWidgetDataBaseItemInterface
+QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI36QDesignerWidgetDataBaseItemInterface)
+8 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+12 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+
+Class QDesignerWidgetDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerWidgetDataBaseItemInterface (0xb45b3b40) 0 nearly-empty
+ vptr=((& QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerWidgetDataBaseInterface
+QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerWidgetDataBaseInterface)
+8 QDesignerWidgetDataBaseInterface::metaObject
+12 QDesignerWidgetDataBaseInterface::qt_metacast
+16 QDesignerWidgetDataBaseInterface::qt_metacall
+20 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+24 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerWidgetDataBaseInterface::count
+60 QDesignerWidgetDataBaseInterface::item
+64 QDesignerWidgetDataBaseInterface::indexOf
+68 QDesignerWidgetDataBaseInterface::insert
+72 QDesignerWidgetDataBaseInterface::append
+76 QDesignerWidgetDataBaseInterface::indexOfObject
+80 QDesignerWidgetDataBaseInterface::indexOfClassName
+84 QDesignerWidgetDataBaseInterface::core
+
+Class QDesignerWidgetDataBaseInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetDataBaseInterface (0xb45af940) 0
+ vptr=((& QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface) + 8u)
+ QObject (0xb45b3d5c) 0
+ primary-for QDesignerWidgetDataBaseInterface (0xb45af940)
+
+Vtable for QDesignerWidgetFactoryInterface
+QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerWidgetFactoryInterface)
+8 QDesignerWidgetFactoryInterface::metaObject
+12 QDesignerWidgetFactoryInterface::qt_metacast
+16 QDesignerWidgetFactoryInterface::qt_metacall
+20 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+24 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerWidgetFactoryInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerWidgetFactoryInterface (0xb45afc40) 0
+ vptr=((& QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface) + 8u)
+ QObject (0xb45b3f00) 0
+ primary-for QDesignerWidgetFactoryInterface (0xb45afc40)
+
+Vtable for QDesignerDynamicPropertySheetExtension
+QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI38QDesignerDynamicPropertySheetExtension)
+8 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+12 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+
+Class QDesignerDynamicPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDynamicPropertySheetExtension (0xb45f103c) 0 nearly-empty
+ vptr=((& QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension) + 8u)
+
+Vtable for QDesignerExtraInfoExtension
+QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerExtraInfoExtension)
+8 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+12 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerExtraInfoExtension
+ size=8 align=4
+ base size=8 base align=4
+QDesignerExtraInfoExtension (0xb45f1708) 0
+ vptr=((& QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension) + 8u)
+
+Vtable for QDesignerLayoutDecorationExtension
+QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerLayoutDecorationExtension)
+8 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+12 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerLayoutDecorationExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLayoutDecorationExtension (0xb45f1ec4) 0 nearly-empty
+ vptr=((& QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension) + 8u)
+
+Vtable for QDesignerMemberSheetExtension
+QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerMemberSheetExtension)
+8 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+12 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+
+Class QDesignerMemberSheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMemberSheetExtension (0xb46105a0) 0 nearly-empty
+ vptr=((& QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension) + 8u)
+
+Vtable for QDesignerPropertySheetExtension
+QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerPropertySheetExtension)
+8 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+12 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPropertySheetExtension (0xb4610c6c) 0 nearly-empty
+ vptr=((& QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension) + 8u)
+
+Vtable for QDesignerTaskMenuExtension
+QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerTaskMenuExtension)
+8 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+12 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+16 QDesignerTaskMenuExtension::preferredEditAction
+20 __cxa_pure_virtual
+
+Class QDesignerTaskMenuExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerTaskMenuExtension (0xb462f348) 0 nearly-empty
+ vptr=((& QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension) + 8u)
+
+Vtable for QAbstractFormBuilder
+QAbstractFormBuilder::_ZTV20QAbstractFormBuilder: 48u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QAbstractFormBuilder)
+8 QAbstractFormBuilder::~QAbstractFormBuilder
+12 QAbstractFormBuilder::~QAbstractFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QAbstractFormBuilder::create
+32 QAbstractFormBuilder::create
+36 QAbstractFormBuilder::create
+40 QAbstractFormBuilder::create
+44 QAbstractFormBuilder::create
+48 QAbstractFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QAbstractFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QAbstractFormBuilder::createWidget
+68 QAbstractFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QAbstractFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QAbstractFormBuilder::addItem
+96 QAbstractFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+
+Class QAbstractFormBuilder
+ size=28 align=4
+ base size=28 base align=4
+QAbstractFormBuilder (0xb462fb40) 0
+ vptr=((& QAbstractFormBuilder::_ZTV20QAbstractFormBuilder) + 8u)
+
+Vtable for QDesignerContainerExtension
+QDesignerContainerExtension::_ZTV27QDesignerContainerExtension: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerContainerExtension)
+8 QDesignerContainerExtension::~QDesignerContainerExtension
+12 QDesignerContainerExtension::~QDesignerContainerExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerContainerExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerContainerExtension (0xb462fce4) 0 nearly-empty
+ vptr=((& QDesignerContainerExtension::_ZTV27QDesignerContainerExtension) + 8u)
+
+Vtable for QDesignerCustomWidgetInterface
+QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerCustomWidgetInterface)
+8 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+12 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 QDesignerCustomWidgetInterface::isInitialized
+52 QDesignerCustomWidgetInterface::initialize
+56 QDesignerCustomWidgetInterface::domXml
+60 QDesignerCustomWidgetInterface::codeTemplate
+
+Class QDesignerCustomWidgetInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetInterface (0xb44853c0) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface) + 8u)
+
+Vtable for QDesignerCustomWidgetCollectionInterface
+QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI40QDesignerCustomWidgetCollectionInterface)
+8 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+12 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+16 __cxa_pure_virtual
+
+Class QDesignerCustomWidgetCollectionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetCollectionInterface (0xb4485a50) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface) + 8u)
+
+Vtable for QFormBuilder
+QFormBuilder::_ZTV12QFormBuilder: 49u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QFormBuilder)
+8 QFormBuilder::~QFormBuilder
+12 QFormBuilder::~QFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QFormBuilder::create
+32 QFormBuilder::create
+36 QFormBuilder::create
+40 QFormBuilder::create
+44 QFormBuilder::create
+48 QFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QFormBuilder::createWidget
+68 QFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QFormBuilder::addItem
+96 QFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+192 QFormBuilder::updateCustomWidgets
+
+Class QFormBuilder
+ size=36 align=4
+ base size=36 base align=4
+QFormBuilder (0xb449a480) 0
+ vptr=((& QFormBuilder::_ZTV12QFormBuilder) + 8u)
+ QAbstractFormBuilder (0xb4485f3c) 0
+ primary-for QFormBuilder (0xb449a480)
+
+Vtable for QExtensionManager
+QExtensionManager::_ZTV17QExtensionManager: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QExtensionManager)
+8 QExtensionManager::metaObject
+12 QExtensionManager::qt_metacast
+16 QExtensionManager::qt_metacall
+20 QExtensionManager::~QExtensionManager
+24 QExtensionManager::~QExtensionManager
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QExtensionManager::registerExtensions
+60 QExtensionManager::unregisterExtensions
+64 QExtensionManager::extension
+68 (int (*)(...))-0x000000008
+72 (int (*)(...))(& _ZTI17QExtensionManager)
+76 QExtensionManager::_ZThn8_N17QExtensionManagerD1Ev
+80 QExtensionManager::_ZThn8_N17QExtensionManagerD0Ev
+84 QExtensionManager::_ZThn8_N17QExtensionManager18registerExtensionsEP25QAbstractExtensionFactoryRK7QString
+88 QExtensionManager::_ZThn8_N17QExtensionManager20unregisterExtensionsEP25QAbstractExtensionFactoryRK7QString
+92 QExtensionManager::_ZThn8_NK17QExtensionManager9extensionEP7QObjectRK7QString
+
+Class QExtensionManager
+ size=20 align=4
+ base size=20 base align=4
+QExtensionManager (0xb44b6690) 0
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 8u)
+ QObject (0xb44b9000) 0
+ primary-for QExtensionManager (0xb44b6690)
+ QAbstractExtensionManager (0xb44b903c) 8 nearly-empty
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 76u)
+
diff --git a/tests/auto/bic/data/QtDesigner.4.7.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtDesigner.4.7.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..92479f241
--- /dev/null
+++ b/tests/auto/bic/data/QtDesigner.4.7.0.linux-gcc-ia32.txt
@@ -0,0 +1,4746 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb6c21a8c) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb6c21c30) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb6bc230c) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb6bc23c0) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb6bc2bf4) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0xb6bc2d20) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb629be88) 0 empty
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb629bec4) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb611a940) 0
+ QGenericArgument (0xb616a0f0) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb616a294) 0
+
+Class QMetaObjectExtraData
+ size=8 align=4
+ base size=8 base align=4
+QMetaObjectExtraData (0xb616a3c0) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb616a5a0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb616a780) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0xb61b7ec4) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0xb61ef280) 0
+ QBasicAtomicInt (0xb61cc5dc) 0
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb61ccac8) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb61ccf3c) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb61ccf00) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb605be4c) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb60a5618) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb60a5654) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb60a55dc) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb5f72258) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb5fb5f3c) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb5e43a40) 0
+ QString (0xb5e73690) 0
+
+Class QStringRef
+ size=12 align=4
+ base size=12 base align=4
+QStringRef (0xb5e739d8) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb5eb7a8c) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::bad_exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb5cf6640) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb5eb7b7c) 0 nearly-empty
+ primary-for std::bad_exception (0xb5cf6640)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb5cf67c0) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb5eb7dd4) 0 nearly-empty
+ primary-for std::bad_alloc (0xb5cf67c0)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb5d0a03c) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb5d0a12c) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb5d0a0f0) 0
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0xb5d0a960) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=28 align=4
+ base size=28 base align=4
+QObjectData (0xb5d0aa14) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb5d0aac8) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb5c0b348) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb5c0c540) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb5c0b474) 0
+ primary-for QIODevice (0xb5c0c540)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb5c481e0) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb5c483c0) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb5c483fc) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb5c484b0) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb5c487bc) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb5c487f8) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb5c48834) 0
+
+Class QXmlStreamStringRef
+ size=12 align=4
+ base size=12 base align=4
+QXmlStreamStringRef (0xb5c48a14) 0
+
+Class QXmlStreamAttribute
+ size=56 align=4
+ base size=53 base align=4
+QXmlStreamAttribute (0xb5b176cc) 0
+
+Class QXmlStreamAttributes
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamAttributes (0xb5b0bc40) 0
+ QVector<QXmlStreamAttribute> (0xb5b3212c) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=28 align=4
+ base size=28 base align=4
+QXmlStreamNamespaceDeclaration (0xb5b3221c) 0
+
+Class QXmlStreamNotationDeclaration
+ size=40 align=4
+ base size=40 base align=4
+QXmlStreamNotationDeclaration (0xb5b32690) 0
+
+Class QXmlStreamEntityDeclaration
+ size=64 align=4
+ base size=64 base align=4
+QXmlStreamEntityDeclaration (0xb5b32c6c) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+8 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+12 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+16 QXmlStreamEntityResolver::resolveEntity
+20 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamEntityResolver (0xb5b72528) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 8u)
+
+Class QXmlStreamReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamReader (0xb5b72564) 0
+
+Class QXmlStreamWriter
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamWriter (0xb5b726cc) 0
+
+Class QBitArray
+ size=4 align=4
+ base size=4 base align=4
+QBitArray (0xb5b72834) 0
+
+Class QBitRef
+ size=8 align=4
+ base size=8 base align=4
+QBitRef (0xb5bbcce4) 0
+
+Class QByteArrayMatcher::Data
+ size=264 align=4
+ base size=264 base align=4
+QByteArrayMatcher::Data (0xb5be130c) 0
+
+Class QByteArrayMatcher
+ size=1032 align=4
+ base size=1032 base align=4
+QByteArrayMatcher (0xb5be12d0) 0
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb5be1564) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb5a3a12c) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb5a3a0f0) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb5a3a834) 0 empty
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0xb5a3afb4) 0
+
+Class QCryptographicHash
+ size=4 align=4
+ base size=4 base align=4
+QCryptographicHash (0xb58fc168) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0xb58fc1a4) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+8 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+12 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+16 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=12 align=4
+ base size=12 base align=4
+QtSharedPointer::ExternalRefCountData (0xb58fc528) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 8u)
+
+Vtable for QtSharedPointer::ExternalRefCountWithDestroyFn
+QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer29ExternalRefCountWithDestroyFnE)
+8 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+12 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+16 QtSharedPointer::ExternalRefCountWithDestroyFn::destroy
+
+Class QtSharedPointer::ExternalRefCountWithDestroyFn
+ size=16 align=4
+ base size=16 base align=4
+QtSharedPointer::ExternalRefCountWithDestroyFn (0xb596e7c0) 0
+ vptr=((& QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE) + 8u)
+ QtSharedPointer::ExternalRefCountData (0xb58fcd20) 0
+ primary-for QtSharedPointer::ExternalRefCountWithDestroyFn (0xb596e7c0)
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0xb5980258) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0xb5980870) 0
+
+Class QDateTime
+ size=4 align=4
+ base size=4 base align=4
+QDateTime (0xb5980dd4) 0
+
+Class QEasingCurve
+ size=4 align=4
+ base size=4 base align=4
+QEasingCurve (0xb580d0b4) 0
+
+Class QElapsedTimer
+ size=16 align=4
+ base size=16 base align=4
+QElapsedTimer (0xb580d12c) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb580d348) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb583e8e8) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb5864000) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb5864d20) 0
+
+Class QLinkedListData
+ size=20 align=4
+ base size=20 base align=4
+QLinkedListData (0xb5895e10) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSystemLocale)
+8 QSystemLocale::~QSystemLocale
+12 QSystemLocale::~QSystemLocale
+16 QSystemLocale::query
+20 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=4 align=4
+ base size=4 base align=4
+QSystemLocale (0xb570e03c) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 8u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0xb570e0b4) 0
+
+Class QLocale
+ size=4 align=4
+ base size=4 base align=4
+QLocale (0xb570e078) 0
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb570e708) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb570e6cc) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0xb570ea14) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb5619b7c) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb5646618) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb566d21c) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb56bde4c) 0
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb551bbb8) 0
+
+Class QLatin1Literal
+ size=8 align=4
+ base size=8 base align=4
+QLatin1Literal (0xb553f708) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0xb553f7bc) 0 empty
+
+Class QStringMatcher::Data
+ size=264 align=4
+ base size=264 base align=4
+QStringMatcher::Data (0xb559fd98) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb559fd5c) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb55b0700) 0
+ QList<QString> (0xb559fec4) 0
+
+Class QTextBoundaryFinder
+ size=28 align=4
+ base size=28 base align=4
+QTextBoundaryFinder (0xb5412438) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTimeLine)
+8 QTimeLine::metaObject
+12 QTimeLine::qt_metacast
+16 QTimeLine::qt_metacall
+20 QTimeLine::~QTimeLine
+24 QTimeLine::~QTimeLine
+28 QObject::event
+32 QObject::eventFilter
+36 QTimeLine::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=8 align=4
+ base size=8 base align=4
+QTimeLine (0xb5404680) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 8u)
+ QObject (0xb54124ec) 0
+ primary-for QTimeLine (0xb5404680)
+
+Class QMutex
+ size=4 align=4
+ base size=4 base align=4
+QMutex (0xb5412780) 0
+
+Class QMutexLocker
+ size=4 align=4
+ base size=4 base align=4
+QMutexLocker (0xb5412e10) 0
+
+Class QReadWriteLock
+ size=4 align=4
+ base size=4 base align=4
+QReadWriteLock (0xb5459384) 0
+
+Class QReadLocker
+ size=4 align=4
+ base size=4 base align=4
+QReadLocker (0xb54593c0) 0
+
+Class QWriteLocker
+ size=4 align=4
+ base size=4 base align=4
+QWriteLocker (0xb54598ac) 0
+
+Class QSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSemaphore (0xb5459d98) 0
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QThread)
+8 QThread::metaObject
+12 QThread::qt_metacast
+16 QThread::qt_metacall
+20 QThread::~QThread
+24 QThread::~QThread
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QThread::run
+
+Class QThread
+ size=8 align=4
+ base size=8 base align=4
+QThread (0xb5471640) 0
+ vptr=((& QThread::_ZTV7QThread) + 8u)
+ QObject (0xb5459dd4) 0
+ primary-for QThread (0xb5471640)
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0xb548d078) 0
+
+Class QWaitCondition
+ size=4 align=4
+ base size=4 base align=4
+QWaitCondition (0xb548d0f0) 0
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QAbstractState)
+8 QAbstractState::metaObject
+12 QAbstractState::qt_metacast
+16 QAbstractState::qt_metacall
+20 QAbstractState::~QAbstractState
+24 QAbstractState::~QAbstractState
+28 QAbstractState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QAbstractState
+ size=8 align=4
+ base size=8 base align=4
+QAbstractState (0xb5498100) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 8u)
+ QObject (0xb548d12c) 0
+ primary-for QAbstractState (0xb5498100)
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTransition)
+8 QAbstractTransition::metaObject
+12 QAbstractTransition::qt_metacast
+16 QAbstractTransition::qt_metacall
+20 QAbstractTransition::~QAbstractTransition
+24 QAbstractTransition::~QAbstractTransition
+28 QAbstractTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QAbstractTransition
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTransition (0xb54983c0) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 8u)
+ QObject (0xb548d348) 0
+ primary-for QAbstractTransition (0xb54983c0)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QEvent)
+8 QEvent::~QEvent
+12 QEvent::~QEvent
+
+Class QEvent
+ size=12 align=4
+ base size=12 base align=4
+QEvent (0xb548d564) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 8u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTimerEvent)
+8 QTimerEvent::~QTimerEvent
+12 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=16 align=4
+ base size=16 base align=4
+QTimerEvent (0xb5498940) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 8u)
+ QEvent (0xb548d744) 0
+ primary-for QTimerEvent (0xb5498940)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QChildEvent)
+8 QChildEvent::~QChildEvent
+12 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=16 align=4
+ base size=16 base align=4
+QChildEvent (0xb5498a00) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 8u)
+ QEvent (0xb548d7bc) 0
+ primary-for QChildEvent (0xb5498a00)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QCustomEvent)
+8 QCustomEvent::~QCustomEvent
+12 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=12 align=4
+ base size=12 base align=4
+QCustomEvent (0xb5498cc0) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 8u)
+ QEvent (0xb548d924) 0
+ primary-for QCustomEvent (0xb5498cc0)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+8 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+12 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=16 align=4
+ base size=16 base align=4
+QDynamicPropertyChangeEvent (0xb5498dc0) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 8u)
+ QEvent (0xb548da14) 0
+ primary-for QDynamicPropertyChangeEvent (0xb5498dc0)
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QEventTransition)
+8 QEventTransition::metaObject
+12 QEventTransition::qt_metacast
+16 QEventTransition::qt_metacall
+20 QEventTransition::~QEventTransition
+24 QEventTransition::~QEventTransition
+28 QEventTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QEventTransition::eventTest
+60 QEventTransition::onTransition
+
+Class QEventTransition
+ size=8 align=4
+ base size=8 base align=4
+QEventTransition (0xb5498e80) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 8u)
+ QAbstractTransition (0xb5498ec0) 0
+ primary-for QEventTransition (0xb5498e80)
+ QObject (0xb548dac8) 0
+ primary-for QAbstractTransition (0xb5498ec0)
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QFinalState)
+8 QFinalState::metaObject
+12 QFinalState::qt_metacast
+16 QFinalState::qt_metacall
+20 QFinalState::~QFinalState
+24 QFinalState::~QFinalState
+28 QFinalState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFinalState::onEntry
+60 QFinalState::onExit
+
+Class QFinalState
+ size=8 align=4
+ base size=8 base align=4
+QFinalState (0xb54df180) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 8u)
+ QAbstractState (0xb54df1c0) 0
+ primary-for QFinalState (0xb54df180)
+ QObject (0xb548dce4) 0
+ primary-for QAbstractState (0xb54df1c0)
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QHistoryState)
+8 QHistoryState::metaObject
+12 QHistoryState::qt_metacast
+16 QHistoryState::qt_metacall
+20 QHistoryState::~QHistoryState
+24 QHistoryState::~QHistoryState
+28 QHistoryState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QHistoryState::onEntry
+60 QHistoryState::onExit
+
+Class QHistoryState
+ size=8 align=4
+ base size=8 base align=4
+QHistoryState (0xb54df480) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 8u)
+ QAbstractState (0xb54df4c0) 0
+ primary-for QHistoryState (0xb54df480)
+ QObject (0xb548df00) 0
+ primary-for QAbstractState (0xb54df4c0)
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QSignalTransition)
+8 QSignalTransition::metaObject
+12 QSignalTransition::qt_metacast
+16 QSignalTransition::qt_metacall
+20 QSignalTransition::~QSignalTransition
+24 QSignalTransition::~QSignalTransition
+28 QSignalTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSignalTransition::eventTest
+60 QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=8 align=4
+ base size=8 base align=4
+QSignalTransition (0xb54df780) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 8u)
+ QAbstractTransition (0xb54df7c0) 0
+ primary-for QSignalTransition (0xb54df780)
+ QObject (0xb52fa12c) 0
+ primary-for QAbstractTransition (0xb54df7c0)
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QState)
+8 QState::metaObject
+12 QState::qt_metacast
+16 QState::qt_metacall
+20 QState::~QState
+24 QState::~QState
+28 QState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QState::onEntry
+60 QState::onExit
+
+Class QState
+ size=8 align=4
+ base size=8 base align=4
+QState (0xb54dfa80) 0
+ vptr=((& QState::_ZTV6QState) + 8u)
+ QAbstractState (0xb54dfac0) 0
+ primary-for QState (0xb54dfa80)
+ QObject (0xb52fa348) 0
+ primary-for QAbstractState (0xb54dfac0)
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb52fa564) 0 empty
+
+Class QVariant::PrivateShared
+ size=8 align=4
+ base size=8 base align=4
+QVariant::PrivateShared (0xb5379384) 0
+
+Class QVariant::Private::Data
+ size=8 align=4
+ base size=8 base align=4
+QVariant::Private::Data (0xb53793fc) 0
+
+Class QVariant::Private
+ size=12 align=4
+ base size=12 base align=4
+QVariant::Private (0xb53793c0) 0
+
+Class QVariant::Handler
+ size=36 align=4
+ base size=36 base align=4
+QVariant::Handler (0xb5379474) 0
+
+Class QVariant
+ size=12 align=4
+ base size=12 base align=4
+QVariant (0xb5379348) 0
+
+Class QVariantComparisonHelper
+ size=4 align=4
+ base size=4 base align=4
+QVariantComparisonHelper (0xb53c1d20) 0
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+8 QStateMachine::SignalEvent::~SignalEvent
+12 QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=24 align=4
+ base size=24 base align=4
+QStateMachine::SignalEvent (0xb52128c0) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 8u)
+ QEvent (0xb52201e0) 0
+ primary-for QStateMachine::SignalEvent (0xb52128c0)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+8 QStateMachine::WrappedEvent::~WrappedEvent
+12 QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=20 align=4
+ base size=20 base align=4
+QStateMachine::WrappedEvent (0xb5212940) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 8u)
+ QEvent (0xb522021c) 0
+ primary-for QStateMachine::WrappedEvent (0xb5212940)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QStateMachine)
+8 QStateMachine::metaObject
+12 QStateMachine::qt_metacast
+16 QStateMachine::qt_metacall
+20 QStateMachine::~QStateMachine
+24 QStateMachine::~QStateMachine
+28 QStateMachine::event
+32 QStateMachine::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QStateMachine::onEntry
+60 QStateMachine::onExit
+64 QStateMachine::beginSelectTransitions
+68 QStateMachine::endSelectTransitions
+72 QStateMachine::beginMicrostep
+76 QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=8 align=4
+ base size=8 base align=4
+QStateMachine (0xb5212780) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 8u)
+ QState (0xb52127c0) 0
+ primary-for QStateMachine (0xb5212780)
+ QAbstractState (0xb5212800) 0
+ primary-for QState (0xb52127c0)
+ QObject (0xb52201a4) 0
+ primary-for QAbstractState (0xb5212800)
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QFactoryInterface)
+8 QFactoryInterface::~QFactoryInterface
+12 QFactoryInterface::~QFactoryInterface
+16 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QFactoryInterface (0xb52205a0) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 8u)
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QLibrary)
+8 QLibrary::metaObject
+12 QLibrary::qt_metacast
+16 QLibrary::qt_metacall
+20 QLibrary::~QLibrary
+24 QLibrary::~QLibrary
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QLibrary
+ size=16 align=4
+ base size=13 base align=4
+QLibrary (0xb52432c0) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 8u)
+ QObject (0xb5220b40) 0
+ primary-for QLibrary (0xb52432c0)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QPluginLoader)
+8 QPluginLoader::metaObject
+12 QPluginLoader::qt_metacast
+16 QPluginLoader::qt_metacall
+20 QPluginLoader::~QPluginLoader
+24 QPluginLoader::~QPluginLoader
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=16 align=4
+ base size=13 base align=4
+QPluginLoader (0xb5277100) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 8u)
+ QObject (0xb5220dd4) 0
+ primary-for QPluginLoader (0xb5277100)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0xb5220f00) 0
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QEventLoop)
+8 QEventLoop::metaObject
+12 QEventLoop::qt_metacast
+16 QEventLoop::qt_metacall
+20 QEventLoop::~QEventLoop
+24 QEventLoop::~QEventLoop
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QEventLoop
+ size=8 align=4
+ base size=8 base align=4
+QEventLoop (0xb5277980) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 8u)
+ QObject (0xb528cf00) 0
+ primary-for QEventLoop (0xb5277980)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+8 QAbstractEventDispatcher::metaObject
+12 QAbstractEventDispatcher::qt_metacast
+16 QAbstractEventDispatcher::qt_metacall
+20 QAbstractEventDispatcher::~QAbstractEventDispatcher
+24 QAbstractEventDispatcher::~QAbstractEventDispatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 QAbstractEventDispatcher::startingUp
+104 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=8 align=4
+ base size=8 base align=4
+QAbstractEventDispatcher (0xb5277d80) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 8u)
+ QObject (0xb52a721c) 0
+ primary-for QAbstractEventDispatcher (0xb5277d80)
+
+Class QModelIndex
+ size=16 align=4
+ base size=16 base align=4
+QModelIndex (0xb52a7438) 0
+
+Class QPersistentModelIndex
+ size=4 align=4
+ base size=4 base align=4
+QPersistentModelIndex (0xb52d48e8) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractItemModel)
+8 QAbstractItemModel::metaObject
+12 QAbstractItemModel::qt_metacast
+16 QAbstractItemModel::qt_metacall
+20 QAbstractItemModel::~QAbstractItemModel
+24 QAbstractItemModel::~QAbstractItemModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractItemModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemModel (0xb52c79c0) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 8u)
+ QObject (0xb52d4a50) 0
+ primary-for QAbstractItemModel (0xb52c79c0)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTableModel)
+8 QAbstractTableModel::metaObject
+12 QAbstractTableModel::qt_metacast
+16 QAbstractTableModel::qt_metacall
+20 QAbstractTableModel::~QAbstractTableModel
+24 QAbstractTableModel::~QAbstractTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractTableModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTableModel (0xb5115000) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 8u)
+ QAbstractItemModel (0xb5115040) 0
+ primary-for QAbstractTableModel (0xb5115000)
+ QObject (0xb51123c0) 0
+ primary-for QAbstractItemModel (0xb5115040)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractListModel)
+8 QAbstractListModel::metaObject
+12 QAbstractListModel::qt_metacast
+16 QAbstractListModel::qt_metacall
+20 QAbstractListModel::~QAbstractListModel
+24 QAbstractListModel::~QAbstractListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 __cxa_pure_virtual
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractListModel (0xb5115280) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 8u)
+ QAbstractItemModel (0xb51152c0) 0
+ primary-for QAbstractListModel (0xb5115280)
+ QObject (0xb51124ec) 0
+ primary-for QAbstractItemModel (0xb51152c0)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0xb51393c0) 0
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QCoreApplication)
+8 QCoreApplication::metaObject
+12 QCoreApplication::qt_metacast
+16 QCoreApplication::qt_metacall
+20 QCoreApplication::~QCoreApplication
+24 QCoreApplication::~QCoreApplication
+28 QCoreApplication::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QCoreApplication::notify
+60 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=8 align=4
+ base size=8 base align=4
+QCoreApplication (0xb5115d80) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 8u)
+ QObject (0xb5139654) 0
+ primary-for QCoreApplication (0xb5115d80)
+
+Class __exception
+ size=32 align=4
+ base size=32 base align=4
+__exception (0xb5139bf4) 0
+
+Class QMetaMethod
+ size=8 align=4
+ base size=8 base align=4
+QMetaMethod (0xb5192924) 0
+
+Class QMetaEnum
+ size=8 align=4
+ base size=8 base align=4
+QMetaEnum (0xb5192c30) 0
+
+Class QMetaProperty
+ size=20 align=4
+ base size=20 base align=4
+QMetaProperty (0xb5192e88) 0
+
+Class QMetaClassInfo
+ size=8 align=4
+ base size=8 base align=4
+QMetaClassInfo (0xb5192f3c) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QMimeData)
+8 QMimeData::metaObject
+12 QMimeData::qt_metacast
+16 QMimeData::qt_metacall
+20 QMimeData::~QMimeData
+24 QMimeData::~QMimeData
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QMimeData::hasFormat
+60 QMimeData::formats
+64 QMimeData::retrieveData
+
+Class QMimeData
+ size=8 align=4
+ base size=8 base align=4
+QMimeData (0xb519bbc0) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 8u)
+ QObject (0xb51bc1a4) 0
+ primary-for QMimeData (0xb519bbc0)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+8 QObjectCleanupHandler::metaObject
+12 QObjectCleanupHandler::qt_metacast
+16 QObjectCleanupHandler::qt_metacall
+20 QObjectCleanupHandler::~QObjectCleanupHandler
+24 QObjectCleanupHandler::~QObjectCleanupHandler
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=12 align=4
+ base size=12 base align=4
+QObjectCleanupHandler (0xb519be80) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 8u)
+ QObject (0xb51bc3c0) 0
+ primary-for QObjectCleanupHandler (0xb519be80)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSharedMemory)
+8 QSharedMemory::metaObject
+12 QSharedMemory::qt_metacast
+16 QSharedMemory::qt_metacall
+20 QSharedMemory::~QSharedMemory
+24 QSharedMemory::~QSharedMemory
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=8 align=4
+ base size=8 base align=4
+QSharedMemory (0xb51d60c0) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 8u)
+ QObject (0xb51bc4ec) 0
+ primary-for QSharedMemory (0xb51d60c0)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSignalMapper)
+8 QSignalMapper::metaObject
+12 QSignalMapper::qt_metacast
+16 QSignalMapper::qt_metacall
+20 QSignalMapper::~QSignalMapper
+24 QSignalMapper::~QSignalMapper
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=8 align=4
+ base size=8 base align=4
+QSignalMapper (0xb51d6380) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 8u)
+ QObject (0xb51bc708) 0
+ primary-for QSignalMapper (0xb51d6380)
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QSocketNotifier)
+8 QSocketNotifier::metaObject
+12 QSocketNotifier::qt_metacast
+16 QSocketNotifier::qt_metacall
+20 QSocketNotifier::~QSocketNotifier
+24 QSocketNotifier::~QSocketNotifier
+28 QSocketNotifier::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=20 align=4
+ base size=17 base align=4
+QSocketNotifier (0xb51d6640) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 8u)
+ QObject (0xb51bc924) 0
+ primary-for QSocketNotifier (0xb51d6640)
+
+Class QSystemSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSystemSemaphore (0xb51bcbf4) 0
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QTimer)
+8 QTimer::metaObject
+12 QTimer::qt_metacast
+16 QTimer::qt_metacall
+20 QTimer::~QTimer
+24 QTimer::~QTimer
+28 QObject::event
+32 QObject::eventFilter
+36 QTimer::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QTimer
+ size=24 align=4
+ base size=21 base align=4
+QTimer (0xb51d6a00) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 8u)
+ QObject (0xb51bcca8) 0
+ primary-for QTimer (0xb51d6a00)
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTranslator)
+8 QTranslator::metaObject
+12 QTranslator::qt_metacast
+16 QTranslator::qt_metacall
+20 QTranslator::~QTranslator
+24 QTranslator::~QTranslator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTranslator::translate
+60 QTranslator::isEmpty
+
+Class QTranslator
+ size=8 align=4
+ base size=8 base align=4
+QTranslator (0xb51d6f40) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 8u)
+ QObject (0xb51bcf3c) 0
+ primary-for QTranslator (0xb51d6f40)
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb502a30c) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb502a348) 0
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb5024440) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb5024480) 0
+ primary-for QFile (0xb5024440)
+ QObject (0xb502a3c0) 0
+ primary-for QIODevice (0xb5024480)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb502a834) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb502ae88) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0xb4ee7618) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0xb4ee7654) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=20 align=4
+ base size=20 base align=4
+QAbstractFileEngine::MapExtensionOption (0xb50a3c80) 0
+ QAbstractFileEngine::ExtensionOption (0xb4ee7690) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::MapExtensionReturn (0xb50a3d00) 0
+ QAbstractFileEngine::ExtensionReturn (0xb4ee76cc) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::UnMapExtensionOption (0xb50a3d80) 0
+ QAbstractFileEngine::ExtensionOption (0xb4ee7708) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+8 QAbstractFileEngine::~QAbstractFileEngine
+12 QAbstractFileEngine::~QAbstractFileEngine
+16 QAbstractFileEngine::open
+20 QAbstractFileEngine::close
+24 QAbstractFileEngine::flush
+28 QAbstractFileEngine::size
+32 QAbstractFileEngine::pos
+36 QAbstractFileEngine::seek
+40 QAbstractFileEngine::isSequential
+44 QAbstractFileEngine::remove
+48 QAbstractFileEngine::copy
+52 QAbstractFileEngine::rename
+56 QAbstractFileEngine::link
+60 QAbstractFileEngine::mkdir
+64 QAbstractFileEngine::rmdir
+68 QAbstractFileEngine::setSize
+72 QAbstractFileEngine::caseSensitive
+76 QAbstractFileEngine::isRelativePath
+80 QAbstractFileEngine::entryList
+84 QAbstractFileEngine::fileFlags
+88 QAbstractFileEngine::setPermissions
+92 QAbstractFileEngine::fileName
+96 QAbstractFileEngine::ownerId
+100 QAbstractFileEngine::owner
+104 QAbstractFileEngine::fileTime
+108 QAbstractFileEngine::setFileName
+112 QAbstractFileEngine::handle
+116 QAbstractFileEngine::beginEntryList
+120 QAbstractFileEngine::endEntryList
+124 QAbstractFileEngine::read
+128 QAbstractFileEngine::readLine
+132 QAbstractFileEngine::write
+136 QAbstractFileEngine::extension
+140 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngine (0xb4ee75dc) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 8u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+8 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+12 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+16 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngineHandler (0xb4ee7960) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 8u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+8 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+12 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QAbstractFileEngineIterator::currentFileInfo
+32 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngineIterator (0xb4ee799c) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 8u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QBuffer)
+8 QBuffer::metaObject
+12 QBuffer::qt_metacast
+16 QBuffer::qt_metacall
+20 QBuffer::~QBuffer
+24 QBuffer::~QBuffer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QBuffer::connectNotify
+52 QBuffer::disconnectNotify
+56 QIODevice::isSequential
+60 QBuffer::open
+64 QBuffer::close
+68 QBuffer::pos
+72 QBuffer::size
+76 QBuffer::seek
+80 QBuffer::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QBuffer::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QBuffer::readData
+112 QIODevice::readLineData
+116 QBuffer::writeData
+
+Class QBuffer
+ size=8 align=4
+ base size=8 base align=4
+QBuffer (0xb4f420c0) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 8u)
+ QIODevice (0xb4f42100) 0
+ primary-for QBuffer (0xb4f420c0)
+ QObject (0xb4ee7a14) 0
+ primary-for QIODevice (0xb4f42100)
+
+Class QTextCodec::ConverterState
+ size=28 align=4
+ base size=28 base align=4
+QTextCodec::ConverterState (0xb4ee7c6c) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTextCodec)
+8 __cxa_pure_virtual
+12 QTextCodec::aliases
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QTextCodec::~QTextCodec
+32 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=4 align=4
+ base size=4 base align=4
+QTextCodec (0xb4ee7c30) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 8u)
+
+Class QTextEncoder
+ size=32 align=4
+ base size=32 base align=4
+QTextEncoder (0xb4f73960) 0
+
+Class QTextDecoder
+ size=32 align=4
+ base size=32 base align=4
+QTextDecoder (0xb4f73bb8) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTextStream)
+8 QTextStream::~QTextStream
+12 QTextStream::~QTextStream
+
+Class QTextStream
+ size=8 align=4
+ base size=8 base align=4
+QTextStream (0xb4f73e10) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 8u)
+
+Class QTextStreamManipulator
+ size=24 align=4
+ base size=22 base align=4
+QTextStreamManipulator (0xb4fd64b0) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextIStream)
+8 QTextIStream::~QTextIStream
+12 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=8 align=4
+ base size=8 base align=4
+QTextIStream (0xb4fd5b00) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 8u)
+ QTextStream (0xb4dfb690) 0
+ primary-for QTextIStream (0xb4fd5b00)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextOStream)
+8 QTextOStream::~QTextOStream
+12 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=8 align=4
+ base size=8 base align=4
+QTextOStream (0xb4fd5dc0) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 8u)
+ QTextStream (0xb4dfbd20) 0
+ primary-for QTextOStream (0xb4fd5dc0)
+
+Class QDebug::Stream
+ size=24 align=4
+ base size=22 base align=4
+QDebug::Stream (0xb4e153fc) 0
+
+Class QDebug
+ size=4 align=4
+ base size=4 base align=4
+QDebug (0xb4e153c0) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0xb4e9103c) 0 empty
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QDirIterator)
+8 QDirIterator::~QDirIterator
+12 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=8 align=4
+ base size=8 base align=4
+QDirIterator (0xb4e912d0) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 8u)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+8 QFileSystemWatcher::metaObject
+12 QFileSystemWatcher::qt_metacast
+16 QFileSystemWatcher::qt_metacall
+20 QFileSystemWatcher::~QFileSystemWatcher
+24 QFileSystemWatcher::~QFileSystemWatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=8 align=4
+ base size=8 base align=4
+QFileSystemWatcher (0xb4eab780) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 8u)
+ QObject (0xb4e91438) 0
+ primary-for QFileSystemWatcher (0xb4eab780)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QFSFileEngine)
+8 QFSFileEngine::~QFSFileEngine
+12 QFSFileEngine::~QFSFileEngine
+16 QFSFileEngine::open
+20 QFSFileEngine::close
+24 QFSFileEngine::flush
+28 QFSFileEngine::size
+32 QFSFileEngine::pos
+36 QFSFileEngine::seek
+40 QFSFileEngine::isSequential
+44 QFSFileEngine::remove
+48 QFSFileEngine::copy
+52 QFSFileEngine::rename
+56 QFSFileEngine::link
+60 QFSFileEngine::mkdir
+64 QFSFileEngine::rmdir
+68 QFSFileEngine::setSize
+72 QFSFileEngine::caseSensitive
+76 QFSFileEngine::isRelativePath
+80 QFSFileEngine::entryList
+84 QFSFileEngine::fileFlags
+88 QFSFileEngine::setPermissions
+92 QFSFileEngine::fileName
+96 QFSFileEngine::ownerId
+100 QFSFileEngine::owner
+104 QFSFileEngine::fileTime
+108 QFSFileEngine::setFileName
+112 QFSFileEngine::handle
+116 QFSFileEngine::beginEntryList
+120 QFSFileEngine::endEntryList
+124 QFSFileEngine::read
+128 QFSFileEngine::readLine
+132 QFSFileEngine::write
+136 QFSFileEngine::extension
+140 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QFSFileEngine (0xb4eaba40) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 8u)
+ QAbstractFileEngine (0xb4e91654) 0
+ primary-for QFSFileEngine (0xb4eaba40)
+
+Class QProcessEnvironment
+ size=4 align=4
+ base size=4 base align=4
+QProcessEnvironment (0xb4e91780) 0
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QProcess)
+8 QProcess::metaObject
+12 QProcess::qt_metacast
+16 QProcess::qt_metacall
+20 QProcess::~QProcess
+24 QProcess::~QProcess
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QProcess::isSequential
+60 QIODevice::open
+64 QProcess::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QProcess::atEnd
+84 QIODevice::reset
+88 QProcess::bytesAvailable
+92 QProcess::bytesToWrite
+96 QProcess::canReadLine
+100 QProcess::waitForReadyRead
+104 QProcess::waitForBytesWritten
+108 QProcess::readData
+112 QIODevice::readLineData
+116 QProcess::writeData
+120 QProcess::setupChildProcess
+
+Class QProcess
+ size=8 align=4
+ base size=8 base align=4
+QProcess (0xb4eabc00) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 8u)
+ QIODevice (0xb4eabc40) 0
+ primary-for QProcess (0xb4eabc00)
+ QObject (0xb4e91834) 0
+ primary-for QIODevice (0xb4eabc40)
+
+Class QResource
+ size=4 align=4
+ base size=4 base align=4
+QResource (0xb4e91a50) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QSettings)
+8 QSettings::metaObject
+12 QSettings::qt_metacast
+16 QSettings::qt_metacall
+20 QSettings::~QSettings
+24 QSettings::~QSettings
+28 QSettings::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSettings
+ size=8 align=4
+ base size=8 base align=4
+QSettings (0xb4d31080) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 8u)
+ QObject (0xb4e91bf4) 0
+ primary-for QSettings (0xb4d31080)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QTemporaryFile)
+8 QTemporaryFile::metaObject
+12 QTemporaryFile::qt_metacast
+16 QTemporaryFile::qt_metacall
+20 QTemporaryFile::~QTemporaryFile
+24 QTemporaryFile::~QTemporaryFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QTemporaryFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=8 align=4
+ base size=8 base align=4
+QTemporaryFile (0xb4d31c80) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 8u)
+ QFile (0xb4d31cc0) 0
+ primary-for QTemporaryFile (0xb4d31c80)
+ QIODevice (0xb4d31d00) 0
+ primary-for QFile (0xb4d31cc0)
+ QObject (0xb4d61708) 0
+ primary-for QIODevice (0xb4d31d00)
+
+Class QUrl
+ size=4 align=4
+ base size=4 base align=4
+QUrl (0xb4d61a14) 0
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0xb4beb5dc) 0 empty
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QRunnable)
+8 __cxa_pure_virtual
+12 QRunnable::~QRunnable
+16 QRunnable::~QRunnable
+
+Class QRunnable
+ size=8 align=4
+ base size=8 base align=4
+QRunnable (0xb4beb618) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 8u)
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+8 QtConcurrent::Exception::~Exception
+12 QtConcurrent::Exception::~Exception
+16 std::exception::what
+20 QtConcurrent::Exception::raise
+24 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::Exception (0xb4c00040) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 8u)
+ std::exception (0xb4beba8c) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb4c00040)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+8 QtConcurrent::UnhandledException::~UnhandledException
+12 QtConcurrent::UnhandledException::~UnhandledException
+16 std::exception::what
+20 QtConcurrent::UnhandledException::raise
+24 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::UnhandledException (0xb4c00140) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 8u)
+ QtConcurrent::Exception (0xb4c00180) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0xb4c00140)
+ std::exception (0xb4bebac8) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb4c00180)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionHolder (0xb4bebb04) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionStore (0xb4bebb40) 0
+
+Class QtConcurrent::ResultItem
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultItem (0xb4bebb7c) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultIteratorBase (0xb4c0d168) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+8 QtConcurrent::ResultStoreBase::~ResultStoreBase
+12 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=28 align=4
+ base size=28 base align=4
+QtConcurrent::ResultStoreBase (0xb4c0d294) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 8u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+8 QFutureInterfaceBase::~QFutureInterfaceBase
+12 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureInterfaceBase (0xb4c0d6cc) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 8u)
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+8 QFutureWatcherBase::metaObject
+12 QFutureWatcherBase::qt_metacast
+16 QFutureWatcherBase::qt_metacall
+20 QFutureWatcherBase::~QFutureWatcherBase
+24 QFutureWatcherBase::~QFutureWatcherBase
+28 QFutureWatcherBase::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QFutureWatcherBase::connectNotify
+52 QFutureWatcherBase::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureWatcherBase (0xb4c97f80) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 8u)
+ QObject (0xb4cab0b4) 0
+ primary-for QFutureWatcherBase (0xb4c97f80)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QThreadPool)
+8 QThreadPool::metaObject
+12 QThreadPool::qt_metacast
+16 QThreadPool::qt_metacall
+20 QThreadPool::~QThreadPool
+24 QThreadPool::~QThreadPool
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QThreadPool
+ size=8 align=4
+ base size=8 base align=4
+QThreadPool (0xb4cdc140) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 8u)
+ QObject (0xb4cd80b4) 0
+ primary-for QThreadPool (0xb4cdc140)
+
+Class QtConcurrent::ThreadEngineBarrier
+ size=12 align=4
+ base size=12 base align=4
+QtConcurrent::ThreadEngineBarrier (0xb4cd82d0) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+8 QtConcurrent::ThreadEngineBase::run
+12 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+16 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+20 QtConcurrent::ThreadEngineBase::start
+24 QtConcurrent::ThreadEngineBase::finish
+28 QtConcurrent::ThreadEngineBase::threadFunction
+32 QtConcurrent::ThreadEngineBase::shouldStartThread
+36 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+40 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=32 align=4
+ base size=32 base align=4
+QtConcurrent::ThreadEngineBase (0xb4cdc440) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 8u)
+ QRunnable (0xb4cd830c) 0
+ primary-for QtConcurrent::ThreadEngineBase (0xb4cdc440)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 12u)
+4 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 68u)
+
+Class QtConcurrent::BlockSizeManager
+ size=72 align=4
+ base size=72 base align=4
+QtConcurrent::BlockSizeManager (0xb4b0a8e8) 0
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+8 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+12 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QTextCodecFactoryInterface (0xb49889c0) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 8u)
+ QFactoryInterface (0xb49911a4) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb49889c0)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+8 QTextCodecPlugin::metaObject
+12 QTextCodecPlugin::qt_metacast
+16 QTextCodecPlugin::qt_metacall
+20 QTextCodecPlugin::~QTextCodecPlugin
+24 QTextCodecPlugin::~QTextCodecPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 QTextCodecPlugin::keys
+80 QTextCodecPlugin::create
+84 (int (*)(...))-0x000000008
+88 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+92 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD1Ev
+96 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD0Ev
+100 QTextCodecPlugin::_ZThn8_NK16QTextCodecPlugin4keysEv
+104 QTextCodecPlugin::_ZThn8_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=12 align=4
+ base size=12 base align=4
+QTextCodecPlugin (0xb49a4140) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 8u)
+ QObject (0xb49914b0) 0
+ primary-for QTextCodecPlugin (0xb49a4140)
+ QTextCodecFactoryInterface (0xb4988c80) 8 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 92u)
+ QFactoryInterface (0xb49914ec) 8 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4988c80)
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractAnimation)
+8 QAbstractAnimation::metaObject
+12 QAbstractAnimation::qt_metacast
+16 QAbstractAnimation::qt_metacall
+20 QAbstractAnimation::~QAbstractAnimation
+24 QAbstractAnimation::~QAbstractAnimation
+28 QAbstractAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=8 align=4
+ base size=8 base align=4
+QAbstractAnimation (0xb4988ec0) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 8u)
+ QObject (0xb4991618) 0
+ primary-for QAbstractAnimation (0xb4988ec0)
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QAnimationGroup)
+8 QAnimationGroup::metaObject
+12 QAnimationGroup::qt_metacast
+16 QAnimationGroup::qt_metacall
+20 QAnimationGroup::~QAnimationGroup
+24 QAnimationGroup::~QAnimationGroup
+28 QAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QAnimationGroup (0xb49bc180) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 8u)
+ QAbstractAnimation (0xb49bc1c0) 0
+ primary-for QAnimationGroup (0xb49bc180)
+ QObject (0xb4991870) 0
+ primary-for QAbstractAnimation (0xb49bc1c0)
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+8 QParallelAnimationGroup::metaObject
+12 QParallelAnimationGroup::qt_metacast
+16 QParallelAnimationGroup::qt_metacall
+20 QParallelAnimationGroup::~QParallelAnimationGroup
+24 QParallelAnimationGroup::~QParallelAnimationGroup
+28 QParallelAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QParallelAnimationGroup::duration
+60 QParallelAnimationGroup::updateCurrentTime
+64 QParallelAnimationGroup::updateState
+68 QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QParallelAnimationGroup (0xb49bc480) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 8u)
+ QAnimationGroup (0xb49bc4c0) 0
+ primary-for QParallelAnimationGroup (0xb49bc480)
+ QAbstractAnimation (0xb49bc500) 0
+ primary-for QAnimationGroup (0xb49bc4c0)
+ QObject (0xb4991a8c) 0
+ primary-for QAbstractAnimation (0xb49bc500)
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QPauseAnimation)
+8 QPauseAnimation::metaObject
+12 QPauseAnimation::qt_metacast
+16 QPauseAnimation::qt_metacall
+20 QPauseAnimation::~QPauseAnimation
+24 QPauseAnimation::~QPauseAnimation
+28 QPauseAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QPauseAnimation::duration
+60 QPauseAnimation::updateCurrentTime
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=8 align=4
+ base size=8 base align=4
+QPauseAnimation (0xb49bc7c0) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 8u)
+ QAbstractAnimation (0xb49bc800) 0
+ primary-for QPauseAnimation (0xb49bc7c0)
+ QObject (0xb4991ca8) 0
+ primary-for QAbstractAnimation (0xb49bc800)
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QVariantAnimation)
+8 QVariantAnimation::metaObject
+12 QVariantAnimation::qt_metacast
+16 QVariantAnimation::qt_metacall
+20 QVariantAnimation::~QVariantAnimation
+24 QVariantAnimation::~QVariantAnimation
+28 QVariantAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QVariantAnimation::duration
+60 QVariantAnimation::updateCurrentTime
+64 QVariantAnimation::updateState
+68 QAbstractAnimation::updateDirection
+72 __cxa_pure_virtual
+76 QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=8 align=4
+ base size=8 base align=4
+QVariantAnimation (0xb49bcac0) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 8u)
+ QAbstractAnimation (0xb49bcb00) 0
+ primary-for QVariantAnimation (0xb49bcac0)
+ QObject (0xb4991ec4) 0
+ primary-for QAbstractAnimation (0xb49bcb00)
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QPropertyAnimation)
+8 QPropertyAnimation::metaObject
+12 QPropertyAnimation::qt_metacast
+16 QPropertyAnimation::qt_metacall
+20 QPropertyAnimation::~QPropertyAnimation
+24 QPropertyAnimation::~QPropertyAnimation
+28 QPropertyAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QVariantAnimation::duration
+60 QVariantAnimation::updateCurrentTime
+64 QPropertyAnimation::updateState
+68 QAbstractAnimation::updateDirection
+72 QPropertyAnimation::updateCurrentValue
+76 QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=8 align=4
+ base size=8 base align=4
+QPropertyAnimation (0xb49bcf00) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 8u)
+ QVariantAnimation (0xb49bcf40) 0
+ primary-for QPropertyAnimation (0xb49bcf00)
+ QAbstractAnimation (0xb49bcf80) 0
+ primary-for QVariantAnimation (0xb49bcf40)
+ QObject (0xb47f60f0) 0
+ primary-for QAbstractAnimation (0xb49bcf80)
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+8 QSequentialAnimationGroup::metaObject
+12 QSequentialAnimationGroup::qt_metacast
+16 QSequentialAnimationGroup::qt_metacall
+20 QSequentialAnimationGroup::~QSequentialAnimationGroup
+24 QSequentialAnimationGroup::~QSequentialAnimationGroup
+28 QSequentialAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSequentialAnimationGroup::duration
+60 QSequentialAnimationGroup::updateCurrentTime
+64 QSequentialAnimationGroup::updateState
+68 QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QSequentialAnimationGroup (0xb47f9240) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 8u)
+ QAnimationGroup (0xb47f9280) 0
+ primary-for QSequentialAnimationGroup (0xb47f9240)
+ QAbstractAnimation (0xb47f92c0) 0
+ primary-for QAnimationGroup (0xb47f9280)
+ QObject (0xb47f630c) 0
+ primary-for QAbstractAnimation (0xb47f92c0)
+
+Class QXmlNamespaceSupport
+ size=4 align=4
+ base size=4 base align=4
+QXmlNamespaceSupport (0xb47f6528) 0
+
+Class QXmlAttributes::Attribute
+ size=16 align=4
+ base size=16 base align=4
+QXmlAttributes::Attribute (0xb47f65a0) 0
+
+Vtable for QXmlAttributes
+QXmlAttributes::_ZTV14QXmlAttributes: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlAttributes)
+8 QXmlAttributes::~QXmlAttributes
+12 QXmlAttributes::~QXmlAttributes
+
+Class QXmlAttributes
+ size=12 align=4
+ base size=12 base align=4
+QXmlAttributes (0xb47f6564) 0
+ vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 8u)
+
+Vtable for QXmlInputSource
+QXmlInputSource::_ZTV15QXmlInputSource: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlInputSource)
+8 QXmlInputSource::~QXmlInputSource
+12 QXmlInputSource::~QXmlInputSource
+16 QXmlInputSource::setData
+20 QXmlInputSource::setData
+24 QXmlInputSource::fetchData
+28 QXmlInputSource::data
+32 QXmlInputSource::next
+36 QXmlInputSource::reset
+40 QXmlInputSource::fromRawData
+
+Class QXmlInputSource
+ size=8 align=4
+ base size=8 base align=4
+QXmlInputSource (0xb47f6b40) 0
+ vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 8u)
+
+Class QXmlParseException
+ size=4 align=4
+ base size=4 base align=4
+QXmlParseException (0xb47f6b7c) 0
+
+Vtable for QXmlReader
+QXmlReader::_ZTV10QXmlReader: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QXmlReader)
+8 QXmlReader::~QXmlReader
+12 QXmlReader::~QXmlReader
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+
+Class QXmlReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlReader (0xb47f6bf4) 0 nearly-empty
+ vptr=((& QXmlReader::_ZTV10QXmlReader) + 8u)
+
+Vtable for QXmlSimpleReader
+QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlSimpleReader)
+8 QXmlSimpleReader::~QXmlSimpleReader
+12 QXmlSimpleReader::~QXmlSimpleReader
+16 QXmlSimpleReader::feature
+20 QXmlSimpleReader::setFeature
+24 QXmlSimpleReader::hasFeature
+28 QXmlSimpleReader::property
+32 QXmlSimpleReader::setProperty
+36 QXmlSimpleReader::hasProperty
+40 QXmlSimpleReader::setEntityResolver
+44 QXmlSimpleReader::entityResolver
+48 QXmlSimpleReader::setDTDHandler
+52 QXmlSimpleReader::DTDHandler
+56 QXmlSimpleReader::setContentHandler
+60 QXmlSimpleReader::contentHandler
+64 QXmlSimpleReader::setErrorHandler
+68 QXmlSimpleReader::errorHandler
+72 QXmlSimpleReader::setLexicalHandler
+76 QXmlSimpleReader::lexicalHandler
+80 QXmlSimpleReader::setDeclHandler
+84 QXmlSimpleReader::declHandler
+88 QXmlSimpleReader::parse
+92 QXmlSimpleReader::parse
+96 QXmlSimpleReader::parse
+100 QXmlSimpleReader::parseContinue
+
+Class QXmlSimpleReader
+ size=8 align=4
+ base size=8 base align=4
+QXmlSimpleReader (0xb47f9c40) 0
+ vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 8u)
+ QXmlReader (0xb47f6e10) 0 nearly-empty
+ primary-for QXmlSimpleReader (0xb47f9c40)
+
+Vtable for QXmlLocator
+QXmlLocator::_ZTV11QXmlLocator: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QXmlLocator)
+8 QXmlLocator::~QXmlLocator
+12 QXmlLocator::~QXmlLocator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlLocator
+ size=4 align=4
+ base size=4 base align=4
+QXmlLocator (0xb47f6f78) 0 nearly-empty
+ vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 8u)
+
+Vtable for QXmlContentHandler
+QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlContentHandler)
+8 QXmlContentHandler::~QXmlContentHandler
+12 QXmlContentHandler::~QXmlContentHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QXmlContentHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlContentHandler (0xb47f6fb4) 0 nearly-empty
+ vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 8u)
+
+Vtable for QXmlErrorHandler
+QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlErrorHandler)
+8 QXmlErrorHandler::~QXmlErrorHandler
+12 QXmlErrorHandler::~QXmlErrorHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlErrorHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlErrorHandler (0xb485e1e0) 0 nearly-empty
+ vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 8u)
+
+Vtable for QXmlDTDHandler
+QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlDTDHandler)
+8 QXmlDTDHandler::~QXmlDTDHandler
+12 QXmlDTDHandler::~QXmlDTDHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QXmlDTDHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDTDHandler (0xb485e3fc) 0 nearly-empty
+ vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 8u)
+
+Vtable for QXmlEntityResolver
+QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlEntityResolver)
+8 QXmlEntityResolver::~QXmlEntityResolver
+12 QXmlEntityResolver::~QXmlEntityResolver
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlEntityResolver (0xb485e618) 0 nearly-empty
+ vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 8u)
+
+Vtable for QXmlLexicalHandler
+QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlLexicalHandler)
+8 QXmlLexicalHandler::~QXmlLexicalHandler
+12 QXmlLexicalHandler::~QXmlLexicalHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+
+Class QXmlLexicalHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlLexicalHandler (0xb485e834) 0 nearly-empty
+ vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 8u)
+
+Vtable for QXmlDeclHandler
+QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlDeclHandler)
+8 QXmlDeclHandler::~QXmlDeclHandler
+12 QXmlDeclHandler::~QXmlDeclHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlDeclHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDeclHandler (0xb485ea50) 0 nearly-empty
+ vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 8u)
+
+Vtable for QXmlDefaultHandler
+QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+8 QXmlDefaultHandler::~QXmlDefaultHandler
+12 QXmlDefaultHandler::~QXmlDefaultHandler
+16 QXmlDefaultHandler::setDocumentLocator
+20 QXmlDefaultHandler::startDocument
+24 QXmlDefaultHandler::endDocument
+28 QXmlDefaultHandler::startPrefixMapping
+32 QXmlDefaultHandler::endPrefixMapping
+36 QXmlDefaultHandler::startElement
+40 QXmlDefaultHandler::endElement
+44 QXmlDefaultHandler::characters
+48 QXmlDefaultHandler::ignorableWhitespace
+52 QXmlDefaultHandler::processingInstruction
+56 QXmlDefaultHandler::skippedEntity
+60 QXmlDefaultHandler::errorString
+64 QXmlDefaultHandler::warning
+68 QXmlDefaultHandler::error
+72 QXmlDefaultHandler::fatalError
+76 QXmlDefaultHandler::notationDecl
+80 QXmlDefaultHandler::unparsedEntityDecl
+84 QXmlDefaultHandler::resolveEntity
+88 QXmlDefaultHandler::startDTD
+92 QXmlDefaultHandler::endDTD
+96 QXmlDefaultHandler::startEntity
+100 QXmlDefaultHandler::endEntity
+104 QXmlDefaultHandler::startCDATA
+108 QXmlDefaultHandler::endCDATA
+112 QXmlDefaultHandler::comment
+116 QXmlDefaultHandler::attributeDecl
+120 QXmlDefaultHandler::internalEntityDecl
+124 QXmlDefaultHandler::externalEntityDecl
+128 (int (*)(...))-0x000000004
+132 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+136 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD1Ev
+140 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD0Ev
+144 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler7warningERK18QXmlParseException
+148 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler5errorERK18QXmlParseException
+152 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException
+156 QXmlDefaultHandler::_ZThn4_NK18QXmlDefaultHandler11errorStringEv
+160 (int (*)(...))-0x000000008
+164 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+168 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev
+172 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev
+176 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_
+180 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_
+184 QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv
+188 (int (*)(...))-0x00000000c
+192 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+196 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD1Ev
+200 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD0Ev
+204 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource
+208 QXmlDefaultHandler::_ZThn12_NK18QXmlDefaultHandler11errorStringEv
+212 (int (*)(...))-0x000000010
+216 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+220 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev
+224 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev
+228 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_
+232 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler6endDTDEv
+236 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler11startEntityERK7QString
+240 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler9endEntityERK7QString
+244 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler10startCDATAEv
+248 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8endCDATAEv
+252 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler7commentERK7QString
+256 QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv
+260 (int (*)(...))-0x000000014
+264 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+268 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD1Ev
+272 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD0Ev
+276 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_
+280 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_
+284 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_
+288 QXmlDefaultHandler::_ZThn20_NK18QXmlDefaultHandler11errorStringEv
+
+Class QXmlDefaultHandler
+ size=28 align=4
+ base size=28 base align=4
+QXmlDefaultHandler (0xb48760a8) 0
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 8u)
+ QXmlContentHandler (0xb485ec6c) 0 nearly-empty
+ primary-for QXmlDefaultHandler (0xb48760a8)
+ QXmlErrorHandler (0xb485eca8) 4 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 136u)
+ QXmlDTDHandler (0xb485ece4) 8 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 168u)
+ QXmlEntityResolver (0xb485ed20) 12 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 196u)
+ QXmlLexicalHandler (0xb485ed5c) 16 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 220u)
+ QXmlDeclHandler (0xb485ed98) 20 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 268u)
+
+Class QDomImplementation
+ size=4 align=4
+ base size=4 base align=4
+QDomImplementation (0xb489abf4) 0
+
+Class QDomNode
+ size=4 align=4
+ base size=4 base align=4
+QDomNode (0xb489ac30) 0
+
+Class QDomNodeList
+ size=4 align=4
+ base size=4 base align=4
+QDomNodeList (0xb489ac6c) 0
+
+Class QDomDocumentType
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentType (0xb48bb000) 0
+ QDomNode (0xb489ad5c) 0
+
+Class QDomDocument
+ size=4 align=4
+ base size=4 base align=4
+QDomDocument (0xb48bb0c0) 0
+ QDomNode (0xb489add4) 0
+
+Class QDomNamedNodeMap
+ size=4 align=4
+ base size=4 base align=4
+QDomNamedNodeMap (0xb489ae4c) 0
+
+Class QDomDocumentFragment
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentFragment (0xb48bb2c0) 0
+ QDomNode (0xb489af00) 0
+
+Class QDomCharacterData
+ size=4 align=4
+ base size=4 base align=4
+QDomCharacterData (0xb48bb380) 0
+ QDomNode (0xb489af78) 0
+
+Class QDomAttr
+ size=4 align=4
+ base size=4 base align=4
+QDomAttr (0xb48bb400) 0
+ QDomNode (0xb489afb4) 0
+
+Class QDomElement
+ size=4 align=4
+ base size=4 base align=4
+QDomElement (0xb48bb4c0) 0
+ QDomNode (0xb48d803c) 0
+
+Class QDomText
+ size=4 align=4
+ base size=4 base align=4
+QDomText (0xb48bb680) 0
+ QDomCharacterData (0xb48bb6c0) 0
+ QDomNode (0xb48d81a4) 0
+
+Class QDomComment
+ size=4 align=4
+ base size=4 base align=4
+QDomComment (0xb48bb780) 0
+ QDomCharacterData (0xb48bb7c0) 0
+ QDomNode (0xb48d821c) 0
+
+Class QDomCDATASection
+ size=4 align=4
+ base size=4 base align=4
+QDomCDATASection (0xb48bb880) 0
+ QDomText (0xb48bb8c0) 0
+ QDomCharacterData (0xb48bb900) 0
+ QDomNode (0xb48d8294) 0
+
+Class QDomNotation
+ size=4 align=4
+ base size=4 base align=4
+QDomNotation (0xb48bb9c0) 0
+ QDomNode (0xb48d830c) 0
+
+Class QDomEntity
+ size=4 align=4
+ base size=4 base align=4
+QDomEntity (0xb48bba80) 0
+ QDomNode (0xb48d8384) 0
+
+Class QDomEntityReference
+ size=4 align=4
+ base size=4 base align=4
+QDomEntityReference (0xb48bbb40) 0
+ QDomNode (0xb48d83fc) 0
+
+Class QDomProcessingInstruction
+ size=4 align=4
+ base size=4 base align=4
+QDomProcessingInstruction (0xb48bbc00) 0
+ QDomNode (0xb48d8474) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb48d84ec) 0
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb471d690) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb473fe80) 0
+ QVector<QPoint> (0xb471dd20) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb478e4c0) 0
+ QVector<QPointF> (0xb478f708) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb47be078) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb47be03c) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb47be3c0) 0
+
+Class QPainterPath::Element
+ size=20 align=4
+ base size=20 base align=4
+QPainterPath::Element (0xb45ed564) 0
+
+Class QPainterPath
+ size=4 align=4
+ base size=4 base align=4
+QPainterPath (0xb45ed528) 0
+
+Class QPainterPathPrivate
+ size=8 align=4
+ base size=8 base align=4
+QPainterPathPrivate (0xb45eda50) 0
+
+Class QPainterPathStroker
+ size=4 align=4
+ base size=4 base align=4
+QPainterPathStroker (0xb45edb7c) 0
+
+Class QTransform
+ size=80 align=4
+ base size=80 base align=4
+QTransform (0xb4652b04) 0
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb46bba50) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb44ce348) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb44d5200) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb44ced20) 0
+ primary-for QImage (0xb44d5200)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb44d5b00) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb452f8e8) 0
+ primary-for QPixmap (0xb44d5b00)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb452ff3c) 0
+
+Class QBrushData
+ size=104 align=4
+ base size=104 base align=4
+QBrushData (0xb45870f0) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb45874b0) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb4573940) 0
+ QGradient (0xb4587744) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb4573a40) 0
+ QGradient (0xb4587780) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb4573b40) 0
+ QGradient (0xb45877bc) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb45877f8) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb43da580) 0
+ QPalette (0xb43e50f0) 0
+
+Vtable for QAbstractFormBuilder
+QAbstractFormBuilder::_ZTV20QAbstractFormBuilder: 48u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QAbstractFormBuilder)
+8 QAbstractFormBuilder::~QAbstractFormBuilder
+12 QAbstractFormBuilder::~QAbstractFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QAbstractFormBuilder::create
+32 QAbstractFormBuilder::create
+36 QAbstractFormBuilder::create
+40 QAbstractFormBuilder::create
+44 QAbstractFormBuilder::create
+48 QAbstractFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QAbstractFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QAbstractFormBuilder::createWidget
+68 QAbstractFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QAbstractFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QAbstractFormBuilder::addItem
+96 QAbstractFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+
+Class QAbstractFormBuilder
+ size=28 align=4
+ base size=28 base align=4
+QAbstractFormBuilder (0xb4402258) 0
+ vptr=((& QAbstractFormBuilder::_ZTV20QAbstractFormBuilder) + 8u)
+
+Vtable for QAbstractExtensionFactory
+QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionFactory)
+8 QAbstractExtensionFactory::~QAbstractExtensionFactory
+12 QAbstractExtensionFactory::~QAbstractExtensionFactory
+16 __cxa_pure_virtual
+
+Class QAbstractExtensionFactory
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionFactory (0xb44023fc) 0 nearly-empty
+ vptr=((& QAbstractExtensionFactory::_ZTV25QAbstractExtensionFactory) + 8u)
+
+Vtable for QAbstractExtensionManager
+QAbstractExtensionManager::_ZTV25QAbstractExtensionManager: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QAbstractExtensionManager)
+8 QAbstractExtensionManager::~QAbstractExtensionManager
+12 QAbstractExtensionManager::~QAbstractExtensionManager
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QAbstractExtensionManager
+ size=4 align=4
+ base size=4 base align=4
+QAbstractExtensionManager (0xb44028e8) 0 nearly-empty
+ vptr=((& QAbstractExtensionManager::_ZTV25QAbstractExtensionManager) + 8u)
+
+Vtable for QDesignerContainerExtension
+QDesignerContainerExtension::_ZTV27QDesignerContainerExtension: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerContainerExtension)
+8 QDesignerContainerExtension::~QDesignerContainerExtension
+12 QDesignerContainerExtension::~QDesignerContainerExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerContainerExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerContainerExtension (0xb4402dd4) 0 nearly-empty
+ vptr=((& QDesignerContainerExtension::_ZTV27QDesignerContainerExtension) + 8u)
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb44664b0) 0
+
+Vtable for QDesignerCustomWidgetInterface
+QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerCustomWidgetInterface)
+8 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+12 QDesignerCustomWidgetInterface::~QDesignerCustomWidgetInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 QDesignerCustomWidgetInterface::isInitialized
+52 QDesignerCustomWidgetInterface::initialize
+56 QDesignerCustomWidgetInterface::domXml
+60 QDesignerCustomWidgetInterface::codeTemplate
+
+Class QDesignerCustomWidgetInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetInterface (0xb4466708) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetInterface::_ZTV30QDesignerCustomWidgetInterface) + 8u)
+
+Vtable for QDesignerCustomWidgetCollectionInterface
+QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI40QDesignerCustomWidgetCollectionInterface)
+8 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+12 QDesignerCustomWidgetCollectionInterface::~QDesignerCustomWidgetCollectionInterface
+16 __cxa_pure_virtual
+
+Class QDesignerCustomWidgetCollectionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerCustomWidgetCollectionInterface (0xb4466d98) 0 nearly-empty
+ vptr=((& QDesignerCustomWidgetCollectionInterface::_ZTV40QDesignerCustomWidgetCollectionInterface) + 8u)
+
+Vtable for QFormBuilder
+QFormBuilder::_ZTV12QFormBuilder: 49u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QFormBuilder)
+8 QFormBuilder::~QFormBuilder
+12 QFormBuilder::~QFormBuilder
+16 QAbstractFormBuilder::load
+20 QAbstractFormBuilder::save
+24 QAbstractFormBuilder::loadExtraInfo
+28 QFormBuilder::create
+32 QFormBuilder::create
+36 QFormBuilder::create
+40 QFormBuilder::create
+44 QFormBuilder::create
+48 QFormBuilder::create
+52 QAbstractFormBuilder::addMenuAction
+56 QFormBuilder::applyProperties
+60 QAbstractFormBuilder::applyTabStops
+64 QFormBuilder::createWidget
+68 QFormBuilder::createLayout
+72 QAbstractFormBuilder::createAction
+76 QAbstractFormBuilder::createActionGroup
+80 QAbstractFormBuilder::createCustomWidgets
+84 QFormBuilder::createConnections
+88 QAbstractFormBuilder::createResources
+92 QFormBuilder::addItem
+96 QFormBuilder::addItem
+100 QAbstractFormBuilder::saveExtraInfo
+104 QAbstractFormBuilder::saveDom
+108 QAbstractFormBuilder::createActionRefDom
+112 QAbstractFormBuilder::createDom
+116 QAbstractFormBuilder::createDom
+120 QAbstractFormBuilder::createDom
+124 QAbstractFormBuilder::createDom
+128 QAbstractFormBuilder::createDom
+132 QAbstractFormBuilder::createDom
+136 QAbstractFormBuilder::saveConnections
+140 QAbstractFormBuilder::saveCustomWidgets
+144 QAbstractFormBuilder::saveTabStops
+148 QAbstractFormBuilder::saveResources
+152 QAbstractFormBuilder::computeProperties
+156 QAbstractFormBuilder::checkProperty
+160 QAbstractFormBuilder::createProperty
+164 QAbstractFormBuilder::layoutInfo
+168 QAbstractFormBuilder::nameToIcon
+172 QAbstractFormBuilder::iconToFilePath
+176 QAbstractFormBuilder::iconToQrcPath
+180 QAbstractFormBuilder::nameToPixmap
+184 QAbstractFormBuilder::pixmapToFilePath
+188 QAbstractFormBuilder::pixmapToQrcPath
+192 QFormBuilder::updateCustomWidgets
+
+Class QFormBuilder
+ size=36 align=4
+ base size=36 base align=4
+QFormBuilder (0xb449a240) 0
+ vptr=((& QFormBuilder::_ZTV12QFormBuilder) + 8u)
+ QAbstractFormBuilder (0xb449c294) 0
+ primary-for QFormBuilder (0xb449a240)
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb449c348) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb449c564) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb449c7bc) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb449c870) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb449c8ac) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb449c8e8) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb449cb04) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb43287d0) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb449cb40) 0
+ primary-for QWidget (0xb43287d0)
+ QPaintDevice (0xb449cb7c) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Vtable for QDesignerActionEditorInterface
+QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+8 QDesignerActionEditorInterface::metaObject
+12 QDesignerActionEditorInterface::qt_metacast
+16 QDesignerActionEditorInterface::qt_metacall
+20 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+24 QDesignerActionEditorInterface::~QDesignerActionEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerActionEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 (int (*)(...))-0x000000008
+244 (int (*)(...))(& _ZTI30QDesignerActionEditorInterface)
+248 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD1Ev
+252 QDesignerActionEditorInterface::_ZThn8_N30QDesignerActionEditorInterfaceD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerActionEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerActionEditorInterface (0xb41d07c0) 0
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 8u)
+ QWidget (0xb41e6fa0) 0
+ primary-for QDesignerActionEditorInterface (0xb41d07c0)
+ QObject (0xb41df2d0) 0
+ primary-for QWidget (0xb41e6fa0)
+ QPaintDevice (0xb41df30c) 8
+ vptr=((& QDesignerActionEditorInterface::_ZTV30QDesignerActionEditorInterface) + 248u)
+
+Vtable for QDesignerBrushManagerInterface
+QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerBrushManagerInterface)
+8 QDesignerBrushManagerInterface::metaObject
+12 QDesignerBrushManagerInterface::qt_metacast
+16 QDesignerBrushManagerInterface::qt_metacall
+20 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+24 QDesignerBrushManagerInterface::~QDesignerBrushManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerBrushManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerBrushManagerInterface (0xb41d0a00) 0
+ vptr=((& QDesignerBrushManagerInterface::_ZTV30QDesignerBrushManagerInterface) + 8u)
+ QObject (0xb41df438) 0
+ primary-for QDesignerBrushManagerInterface (0xb41d0a00)
+
+Vtable for QDesignerDnDItemInterface
+QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QDesignerDnDItemInterface)
+8 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+12 QDesignerDnDItemInterface::~QDesignerDnDItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerDnDItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDnDItemInterface (0xb41df780) 0 nearly-empty
+ vptr=((& QDesignerDnDItemInterface::_ZTV25QDesignerDnDItemInterface) + 8u)
+
+Vtable for QDesignerFormEditorInterface
+QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormEditorInterface)
+8 QDesignerFormEditorInterface::metaObject
+12 QDesignerFormEditorInterface::qt_metacast
+16 QDesignerFormEditorInterface::qt_metacall
+20 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+24 QDesignerFormEditorInterface::~QDesignerFormEditorInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QDesignerFormEditorInterface
+ size=60 align=4
+ base size=60 base align=4
+QDesignerFormEditorInterface (0xb41d0fc0) 0
+ vptr=((& QDesignerFormEditorInterface::_ZTV28QDesignerFormEditorInterface) + 8u)
+ QObject (0xb41dfa50) 0
+ primary-for QDesignerFormEditorInterface (0xb41d0fc0)
+
+Vtable for QDesignerFormEditorPluginInterface
+QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormEditorPluginInterface)
+8 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+12 QDesignerFormEditorPluginInterface::~QDesignerFormEditorPluginInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QDesignerFormEditorPluginInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormEditorPluginInterface (0xb41dfe4c) 0 nearly-empty
+ vptr=((& QDesignerFormEditorPluginInterface::_ZTV34QDesignerFormEditorPluginInterface) + 8u)
+
+Vtable for QDesignerFormWindowInterface
+QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface: 114u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+8 QDesignerFormWindowInterface::metaObject
+12 QDesignerFormWindowInterface::qt_metacast
+16 QDesignerFormWindowInterface::qt_metacall
+20 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+24 QDesignerFormWindowInterface::~QDesignerFormWindowInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 __cxa_pure_virtual
+280 __cxa_pure_virtual
+284 __cxa_pure_virtual
+288 __cxa_pure_virtual
+292 __cxa_pure_virtual
+296 __cxa_pure_virtual
+300 __cxa_pure_virtual
+304 QDesignerFormWindowInterface::core
+308 __cxa_pure_virtual
+312 __cxa_pure_virtual
+316 __cxa_pure_virtual
+320 __cxa_pure_virtual
+324 __cxa_pure_virtual
+328 __cxa_pure_virtual
+332 __cxa_pure_virtual
+336 __cxa_pure_virtual
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 __cxa_pure_virtual
+368 __cxa_pure_virtual
+372 __cxa_pure_virtual
+376 __cxa_pure_virtual
+380 __cxa_pure_virtual
+384 __cxa_pure_virtual
+388 __cxa_pure_virtual
+392 __cxa_pure_virtual
+396 __cxa_pure_virtual
+400 __cxa_pure_virtual
+404 __cxa_pure_virtual
+408 __cxa_pure_virtual
+412 __cxa_pure_virtual
+416 __cxa_pure_virtual
+420 __cxa_pure_virtual
+424 __cxa_pure_virtual
+428 (int (*)(...))-0x000000008
+432 (int (*)(...))(& _ZTI28QDesignerFormWindowInterface)
+436 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD1Ev
+440 QDesignerFormWindowInterface::_ZThn8_N28QDesignerFormWindowInterfaceD0Ev
+444 QWidget::_ZThn8_NK7QWidget7devTypeEv
+448 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+452 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerFormWindowInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerFormWindowInterface (0xb420d940) 0
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 8u)
+ QWidget (0xb424d8c0) 0
+ primary-for QDesignerFormWindowInterface (0xb420d940)
+ QObject (0xb424e348) 0
+ primary-for QWidget (0xb424d8c0)
+ QPaintDevice (0xb424e384) 8
+ vptr=((& QDesignerFormWindowInterface::_ZTV28QDesignerFormWindowInterface) + 436u)
+
+Vtable for QDesignerFormWindowCursorInterface
+QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerFormWindowCursorInterface)
+8 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+12 QDesignerFormWindowCursorInterface::~QDesignerFormWindowCursorInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+
+Class QDesignerFormWindowCursorInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerFormWindowCursorInterface (0xb424e4b0) 0 nearly-empty
+ vptr=((& QDesignerFormWindowCursorInterface::_ZTV34QDesignerFormWindowCursorInterface) + 8u)
+
+Vtable for QDesignerFormWindowManagerInterface
+QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface: 39u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI35QDesignerFormWindowManagerInterface)
+8 QDesignerFormWindowManagerInterface::metaObject
+12 QDesignerFormWindowManagerInterface::qt_metacast
+16 QDesignerFormWindowManagerInterface::qt_metacall
+20 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+24 QDesignerFormWindowManagerInterface::~QDesignerFormWindowManagerInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerFormWindowManagerInterface::actionCut
+60 QDesignerFormWindowManagerInterface::actionCopy
+64 QDesignerFormWindowManagerInterface::actionPaste
+68 QDesignerFormWindowManagerInterface::actionDelete
+72 QDesignerFormWindowManagerInterface::actionSelectAll
+76 QDesignerFormWindowManagerInterface::actionLower
+80 QDesignerFormWindowManagerInterface::actionRaise
+84 QDesignerFormWindowManagerInterface::actionUndo
+88 QDesignerFormWindowManagerInterface::actionRedo
+92 QDesignerFormWindowManagerInterface::actionHorizontalLayout
+96 QDesignerFormWindowManagerInterface::actionVerticalLayout
+100 QDesignerFormWindowManagerInterface::actionSplitHorizontal
+104 QDesignerFormWindowManagerInterface::actionSplitVertical
+108 QDesignerFormWindowManagerInterface::actionGridLayout
+112 QDesignerFormWindowManagerInterface::actionBreakLayout
+116 QDesignerFormWindowManagerInterface::actionAdjustSize
+120 QDesignerFormWindowManagerInterface::activeFormWindow
+124 QDesignerFormWindowManagerInterface::formWindowCount
+128 QDesignerFormWindowManagerInterface::formWindow
+132 QDesignerFormWindowManagerInterface::createFormWindow
+136 QDesignerFormWindowManagerInterface::core
+140 __cxa_pure_virtual
+144 QDesignerFormWindowManagerInterface::addFormWindow
+148 QDesignerFormWindowManagerInterface::removeFormWindow
+152 QDesignerFormWindowManagerInterface::setActiveFormWindow
+
+Class QDesignerFormWindowManagerInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowManagerInterface (0xb420dd80) 0
+ vptr=((& QDesignerFormWindowManagerInterface::_ZTV35QDesignerFormWindowManagerInterface) + 8u)
+ QObject (0xb424e6cc) 0
+ primary-for QDesignerFormWindowManagerInterface (0xb420dd80)
+
+Vtable for QDesignerFormWindowToolInterface
+QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerFormWindowToolInterface)
+8 QDesignerFormWindowToolInterface::metaObject
+12 QDesignerFormWindowToolInterface::qt_metacast
+16 QDesignerFormWindowToolInterface::qt_metacall
+20 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+24 QDesignerFormWindowToolInterface::~QDesignerFormWindowToolInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QDesignerFormWindowToolInterface::saveToDom
+84 QDesignerFormWindowToolInterface::loadFromDom
+88 __cxa_pure_virtual
+
+Class QDesignerFormWindowToolInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerFormWindowToolInterface (0xb420dfc0) 0
+ vptr=((& QDesignerFormWindowToolInterface::_ZTV32QDesignerFormWindowToolInterface) + 8u)
+ QObject (0xb424e7f8) 0
+ primary-for QDesignerFormWindowToolInterface (0xb420dfc0)
+
+Vtable for QDesignerIconCacheInterface
+QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerIconCacheInterface)
+8 QDesignerIconCacheInterface::metaObject
+12 QDesignerIconCacheInterface::qt_metacast
+16 QDesignerIconCacheInterface::qt_metacall
+20 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+24 QDesignerIconCacheInterface::~QDesignerIconCacheInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QDesignerIconCacheInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerIconCacheInterface (0xb4281280) 0
+ vptr=((& QDesignerIconCacheInterface::_ZTV27QDesignerIconCacheInterface) + 8u)
+ QObject (0xb424e924) 0
+ primary-for QDesignerIconCacheInterface (0xb4281280)
+
+Vtable for QDesignerIntegrationInterface
+QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerIntegrationInterface)
+8 QDesignerIntegrationInterface::metaObject
+12 QDesignerIntegrationInterface::qt_metacast
+16 QDesignerIntegrationInterface::qt_metacall
+20 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+24 QDesignerIntegrationInterface::~QDesignerIntegrationInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+
+Class QDesignerIntegrationInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerIntegrationInterface (0xb4281580) 0
+ vptr=((& QDesignerIntegrationInterface::_ZTV29QDesignerIntegrationInterface) + 8u)
+ QObject (0xb424ec6c) 0
+ primary-for QDesignerIntegrationInterface (0xb4281580)
+
+Vtable for QDesignerLanguageExtension
+QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension: 13u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerLanguageExtension)
+8 QDesignerLanguageExtension::~QDesignerLanguageExtension
+12 QDesignerLanguageExtension::~QDesignerLanguageExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QDesignerLanguageExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLanguageExtension (0xb424edd4) 0 nearly-empty
+ vptr=((& QDesignerLanguageExtension::_ZTV26QDesignerLanguageExtension) + 8u)
+
+Vtable for QDesignerMetaDataBaseItemInterface
+QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerMetaDataBaseItemInterface)
+8 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+12 QDesignerMetaDataBaseItemInterface::~QDesignerMetaDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMetaDataBaseItemInterface (0xb42a74b0) 0 nearly-empty
+ vptr=((& QDesignerMetaDataBaseItemInterface::_ZTV34QDesignerMetaDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerMetaDataBaseInterface
+QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI30QDesignerMetaDataBaseInterface)
+8 QDesignerMetaDataBaseInterface::metaObject
+12 QDesignerMetaDataBaseInterface::qt_metacast
+16 QDesignerMetaDataBaseInterface::qt_metacall
+20 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+24 QDesignerMetaDataBaseInterface::~QDesignerMetaDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerMetaDataBaseInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerMetaDataBaseInterface (0xb42b3040) 0
+ vptr=((& QDesignerMetaDataBaseInterface::_ZTV30QDesignerMetaDataBaseInterface) + 8u)
+ QObject (0xb42a76cc) 0
+ primary-for QDesignerMetaDataBaseInterface (0xb42b3040)
+
+Vtable for QDesignerObjectInspectorInterface
+QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+8 QDesignerObjectInspectorInterface::metaObject
+12 QDesignerObjectInspectorInterface::qt_metacast
+16 QDesignerObjectInspectorInterface::qt_metacall
+20 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+24 QDesignerObjectInspectorInterface::~QDesignerObjectInspectorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerObjectInspectorInterface::core
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI33QDesignerObjectInspectorInterface)
+240 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD1Ev
+244 QDesignerObjectInspectorInterface::_ZThn8_N33QDesignerObjectInspectorInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerObjectInspectorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerObjectInspectorInterface (0xb42b3280) 0
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 8u)
+ QWidget (0xb40b31e0) 0
+ primary-for QDesignerObjectInspectorInterface (0xb42b3280)
+ QObject (0xb42a77f8) 0
+ primary-for QWidget (0xb40b31e0)
+ QPaintDevice (0xb42a7834) 8
+ vptr=((& QDesignerObjectInspectorInterface::_ZTV33QDesignerObjectInspectorInterface) + 240u)
+
+Class QDesignerPromotionInterface::PromotedClass
+ size=8 align=4
+ base size=8 base align=4
+QDesignerPromotionInterface::PromotedClass (0xb42a799c) 0
+
+Vtable for QDesignerPromotionInterface
+QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerPromotionInterface)
+8 QDesignerPromotionInterface::~QDesignerPromotionInterface
+12 QDesignerPromotionInterface::~QDesignerPromotionInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QDesignerPromotionInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPromotionInterface (0xb42a7960) 0 nearly-empty
+ vptr=((& QDesignerPromotionInterface::_ZTV27QDesignerPromotionInterface) + 8u)
+
+Vtable for QDesignerPropertyEditorInterface
+QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface: 70u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+8 QDesignerPropertyEditorInterface::metaObject
+12 QDesignerPropertyEditorInterface::qt_metacast
+16 QDesignerPropertyEditorInterface::qt_metacall
+20 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+24 QDesignerPropertyEditorInterface::~QDesignerPropertyEditorInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QDesignerPropertyEditorInterface::core
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 (int (*)(...))-0x000000008
+256 (int (*)(...))(& _ZTI32QDesignerPropertyEditorInterface)
+260 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD1Ev
+264 QDesignerPropertyEditorInterface::_ZThn8_N32QDesignerPropertyEditorInterfaceD0Ev
+268 QWidget::_ZThn8_NK7QWidget7devTypeEv
+272 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+276 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerPropertyEditorInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerPropertyEditorInterface (0xb42b3540) 0
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 8u)
+ QWidget (0xb40bbdc0) 0
+ primary-for QDesignerPropertyEditorInterface (0xb42b3540)
+ QObject (0xb42a79d8) 0
+ primary-for QWidget (0xb40bbdc0)
+ QPaintDevice (0xb42a7a14) 8
+ vptr=((& QDesignerPropertyEditorInterface::_ZTV32QDesignerPropertyEditorInterface) + 260u)
+
+Vtable for QDesignerResourceBrowserInterface
+QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+8 QDesignerResourceBrowserInterface::metaObject
+12 QDesignerResourceBrowserInterface::qt_metacast
+16 QDesignerResourceBrowserInterface::qt_metacall
+20 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+24 QDesignerResourceBrowserInterface::~QDesignerResourceBrowserInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI33QDesignerResourceBrowserInterface)
+240 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD1Ev
+244 QDesignerResourceBrowserInterface::_ZThn8_N33QDesignerResourceBrowserInterfaceD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerResourceBrowserInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerResourceBrowserInterface (0xb42b3780) 0
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 8u)
+ QWidget (0xb40cd280) 0
+ primary-for QDesignerResourceBrowserInterface (0xb42b3780)
+ QObject (0xb42a7b40) 0
+ primary-for QWidget (0xb40cd280)
+ QPaintDevice (0xb42a7b7c) 8
+ vptr=((& QDesignerResourceBrowserInterface::_ZTV33QDesignerResourceBrowserInterface) + 240u)
+
+Class QDesignerWidgetBoxInterface::Widget
+ size=16 align=4
+ base size=16 base align=4
+QDesignerWidgetBoxInterface::Widget (0xb42a7d20) 0
+
+Class QDesignerWidgetBoxInterface::Category
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetBoxInterface::Category (0xb42a7d5c) 0
+
+Vtable for QDesignerWidgetBoxInterface
+QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface: 76u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+8 QDesignerWidgetBoxInterface::metaObject
+12 QDesignerWidgetBoxInterface::qt_metacast
+16 QDesignerWidgetBoxInterface::qt_metacall
+20 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+24 QDesignerWidgetBoxInterface::~QDesignerWidgetBoxInterface
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 __cxa_pure_virtual
+228 __cxa_pure_virtual
+232 __cxa_pure_virtual
+236 __cxa_pure_virtual
+240 __cxa_pure_virtual
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 __cxa_pure_virtual
+260 __cxa_pure_virtual
+264 __cxa_pure_virtual
+268 __cxa_pure_virtual
+272 __cxa_pure_virtual
+276 (int (*)(...))-0x000000008
+280 (int (*)(...))(& _ZTI27QDesignerWidgetBoxInterface)
+284 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD1Ev
+288 QDesignerWidgetBoxInterface::_ZThn8_N27QDesignerWidgetBoxInterfaceD0Ev
+292 QWidget::_ZThn8_NK7QWidget7devTypeEv
+296 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+300 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QDesignerWidgetBoxInterface
+ size=20 align=4
+ base size=20 base align=4
+QDesignerWidgetBoxInterface (0xb42b39c0) 0
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 8u)
+ QWidget (0xb40d53c0) 0
+ primary-for QDesignerWidgetBoxInterface (0xb42b39c0)
+ QObject (0xb42a7ca8) 0
+ primary-for QWidget (0xb40d53c0)
+ QPaintDevice (0xb42a7ce4) 8
+ vptr=((& QDesignerWidgetBoxInterface::_ZTV27QDesignerWidgetBoxInterface) + 284u)
+
+Vtable for QDesignerWidgetDataBaseItemInterface
+QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI36QDesignerWidgetDataBaseItemInterface)
+8 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+12 QDesignerWidgetDataBaseItemInterface::~QDesignerWidgetDataBaseItemInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+
+Class QDesignerWidgetDataBaseItemInterface
+ size=4 align=4
+ base size=4 base align=4
+QDesignerWidgetDataBaseItemInterface (0xb411c834) 0 nearly-empty
+ vptr=((& QDesignerWidgetDataBaseItemInterface::_ZTV36QDesignerWidgetDataBaseItemInterface) + 8u)
+
+Vtable for QDesignerWidgetDataBaseInterface
+QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI32QDesignerWidgetDataBaseInterface)
+8 QDesignerWidgetDataBaseInterface::metaObject
+12 QDesignerWidgetDataBaseInterface::qt_metacast
+16 QDesignerWidgetDataBaseInterface::qt_metacall
+20 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+24 QDesignerWidgetDataBaseInterface::~QDesignerWidgetDataBaseInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDesignerWidgetDataBaseInterface::count
+60 QDesignerWidgetDataBaseInterface::item
+64 QDesignerWidgetDataBaseInterface::indexOf
+68 QDesignerWidgetDataBaseInterface::insert
+72 QDesignerWidgetDataBaseInterface::append
+76 QDesignerWidgetDataBaseInterface::indexOfObject
+80 QDesignerWidgetDataBaseInterface::indexOfClassName
+84 QDesignerWidgetDataBaseInterface::core
+
+Class QDesignerWidgetDataBaseInterface
+ size=12 align=4
+ base size=12 base align=4
+QDesignerWidgetDataBaseInterface (0xb412d140) 0
+ vptr=((& QDesignerWidgetDataBaseInterface::_ZTV32QDesignerWidgetDataBaseInterface) + 8u)
+ QObject (0xb411ca50) 0
+ primary-for QDesignerWidgetDataBaseInterface (0xb412d140)
+
+Vtable for QDesignerWidgetFactoryInterface
+QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerWidgetFactoryInterface)
+8 QDesignerWidgetFactoryInterface::metaObject
+12 QDesignerWidgetFactoryInterface::qt_metacast
+16 QDesignerWidgetFactoryInterface::qt_metacall
+20 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+24 QDesignerWidgetFactoryInterface::~QDesignerWidgetFactoryInterface
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+
+Class QDesignerWidgetFactoryInterface
+ size=8 align=4
+ base size=8 base align=4
+QDesignerWidgetFactoryInterface (0xb412d440) 0
+ vptr=((& QDesignerWidgetFactoryInterface::_ZTV31QDesignerWidgetFactoryInterface) + 8u)
+ QObject (0xb411cbf4) 0
+ primary-for QDesignerWidgetFactoryInterface (0xb412d440)
+
+Vtable for QDesignerDynamicPropertySheetExtension
+QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI38QDesignerDynamicPropertySheetExtension)
+8 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+12 QDesignerDynamicPropertySheetExtension::~QDesignerDynamicPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+
+Class QDesignerDynamicPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerDynamicPropertySheetExtension (0xb411cd20) 0 nearly-empty
+ vptr=((& QDesignerDynamicPropertySheetExtension::_ZTV38QDesignerDynamicPropertySheetExtension) + 8u)
+
+Vtable for QDesignerExtraInfoExtension
+QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension: 10u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDesignerExtraInfoExtension)
+8 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+12 QDesignerExtraInfoExtension::~QDesignerExtraInfoExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+
+Class QDesignerExtraInfoExtension
+ size=8 align=4
+ base size=8 base align=4
+QDesignerExtraInfoExtension (0xb41623fc) 0
+ vptr=((& QDesignerExtraInfoExtension::_ZTV27QDesignerExtraInfoExtension) + 8u)
+
+Vtable for QDesignerLayoutDecorationExtension
+QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI34QDesignerLayoutDecorationExtension)
+8 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+12 QDesignerLayoutDecorationExtension::~QDesignerLayoutDecorationExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerLayoutDecorationExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerLayoutDecorationExtension (0xb4162bb8) 0 nearly-empty
+ vptr=((& QDesignerLayoutDecorationExtension::_ZTV34QDesignerLayoutDecorationExtension) + 8u)
+
+Vtable for QDesignerMemberSheetExtension
+QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI29QDesignerMemberSheetExtension)
+8 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+12 QDesignerMemberSheetExtension::~QDesignerMemberSheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+
+Class QDesignerMemberSheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerMemberSheetExtension (0xb4180294) 0 nearly-empty
+ vptr=((& QDesignerMemberSheetExtension::_ZTV29QDesignerMemberSheetExtension) + 8u)
+
+Vtable for QDesignerPropertySheetExtension
+QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension: 19u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI31QDesignerPropertySheetExtension)
+8 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+12 QDesignerPropertySheetExtension::~QDesignerPropertySheetExtension
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+
+Class QDesignerPropertySheetExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerPropertySheetExtension (0xb4180960) 0 nearly-empty
+ vptr=((& QDesignerPropertySheetExtension::_ZTV31QDesignerPropertySheetExtension) + 8u)
+
+Vtable for QDesignerTaskMenuExtension
+QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QDesignerTaskMenuExtension)
+8 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+12 QDesignerTaskMenuExtension::~QDesignerTaskMenuExtension
+16 QDesignerTaskMenuExtension::preferredEditAction
+20 __cxa_pure_virtual
+
+Class QDesignerTaskMenuExtension
+ size=4 align=4
+ base size=4 base align=4
+QDesignerTaskMenuExtension (0xb419d03c) 0 nearly-empty
+ vptr=((& QDesignerTaskMenuExtension::_ZTV26QDesignerTaskMenuExtension) + 8u)
+
+Vtable for QExtensionManager
+QExtensionManager::_ZTV17QExtensionManager: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QExtensionManager)
+8 QExtensionManager::metaObject
+12 QExtensionManager::qt_metacast
+16 QExtensionManager::qt_metacall
+20 QExtensionManager::~QExtensionManager
+24 QExtensionManager::~QExtensionManager
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QExtensionManager::registerExtensions
+60 QExtensionManager::unregisterExtensions
+64 QExtensionManager::extension
+68 (int (*)(...))-0x000000008
+72 (int (*)(...))(& _ZTI17QExtensionManager)
+76 QExtensionManager::_ZThn8_N17QExtensionManagerD1Ev
+80 QExtensionManager::_ZThn8_N17QExtensionManagerD0Ev
+84 QExtensionManager::_ZThn8_N17QExtensionManager18registerExtensionsEP25QAbstractExtensionFactoryRK7QString
+88 QExtensionManager::_ZThn8_N17QExtensionManager20unregisterExtensionsEP25QAbstractExtensionFactoryRK7QString
+92 QExtensionManager::_ZThn8_NK17QExtensionManager9extensionEP7QObjectRK7QString
+
+Class QExtensionManager
+ size=20 align=4
+ base size=20 base align=4
+QExtensionManager (0xb41a18c0) 0
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 8u)
+ QObject (0xb419d834) 0
+ primary-for QExtensionManager (0xb41a18c0)
+ QAbstractExtensionManager (0xb419d870) 8 nearly-empty
+ vptr=((& QExtensionManager::_ZTV17QExtensionManager) + 76u)
+
diff --git a/tests/auto/bic/data/QtHelp.4.5.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtHelp.4.5.0.linux-gcc-amd64.txt
new file mode 100644
index 000000000..2c50e2e14
--- /dev/null
+++ b/tests/auto/bic/data/QtHelp.4.5.0.linux-gcc-amd64.txt
@@ -0,0 +1,6357 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0x7f0a726b2460) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0x7f0a726c8150) 0
+
+Class qIsNull(double)::U
+ size=8 align=8
+ base size=8 base align=8
+qIsNull(double)::U (0x7f0a726dd540) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0x7f0a726dd7e0) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0x7f0a71cf4620) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0x7f0a71cf4e00) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0x7f0a71af1540) 0 empty
+
+Class QGenericArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericArgument (0x7f0a71af1850) 0
+
+Class QGenericReturnArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericReturnArgument (0x7f0a71b0d3f0) 0
+ QGenericArgument (0x7f0a71b0d460) 0
+
+Class QMetaObject
+ size=32 align=8
+ base size=32 base align=8
+QMetaObject (0x7f0a71b0dcb0) 0
+
+Class QMetaObjectExtraData
+ size=16 align=8
+ base size=16 base align=8
+QMetaObjectExtraData (0x7f0a71b33cb0) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0x7f0a71b3e700) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0x7f0a71b442a0) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0x7f0a71bb0380) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0x7f0a719e6d20) 0
+ QBasicAtomicInt (0x7f0a719e6d90) 0
+
+Class __locale_struct
+ size=232 align=8
+ base size=232 base align=8
+__locale_struct (0x7f0a71a0c1c0) 0
+
+Class QByteArray::Data
+ size=32 align=8
+ base size=32 base align=8
+QByteArray::Data (0x7f0a71a897e0) 0
+
+Class QByteArray
+ size=8 align=8
+ base size=8 base align=8
+QByteArray (0x7f0a71a44540) 0
+
+Class QByteRef
+ size=16 align=8
+ base size=12 base align=8
+QByteRef (0x7f0a718dea80) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0x7f0a717e7700) 0 empty
+
+Class QString::Data
+ size=32 align=8
+ base size=32 base align=8
+QString::Data (0x7f0a717f6ee0) 0
+
+Class QString
+ size=8 align=8
+ base size=8 base align=8
+QString (0x7f0a719675b0) 0
+
+Class QLatin1String
+ size=8 align=8
+ base size=8 base align=8
+QLatin1String (0x7f0a718d1000) 0
+
+Class QCharRef
+ size=16 align=8
+ base size=12 base align=8
+QCharRef (0x7f0a71767620) 0
+
+Class QConstString
+ size=8 align=8
+ base size=8 base align=8
+QConstString (0x7f0a716b1ee0) 0
+ QString (0x7f0a716b1f50) 0
+
+Class QStringRef
+ size=16 align=8
+ base size=16 base align=8
+QStringRef (0x7f0a716d3bd0) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9exception)
+16 std::exception::~exception
+24 std::exception::~exception
+32 std::exception::what
+
+Class std::exception
+ size=8 align=8
+ base size=8 base align=8
+std::exception (0x7f0a7158c620) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 16u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13bad_exception)
+16 std::bad_exception::~bad_exception
+24 std::bad_exception::~bad_exception
+32 std::bad_exception::what
+
+Class std::bad_exception
+ size=8 align=8
+ base size=8 base align=8
+std::bad_exception (0x7f0a715af000) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u)
+ std::exception (0x7f0a715af070) 0 nearly-empty
+ primary-for std::bad_exception (0x7f0a715af000)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9bad_alloc)
+16 std::bad_alloc::~bad_alloc
+24 std::bad_alloc::~bad_alloc
+32 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=8 align=8
+ base size=8 base align=8
+std::bad_alloc (0x7f0a715af8c0) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u)
+ std::exception (0x7f0a715af930) 0 nearly-empty
+ primary-for std::bad_alloc (0x7f0a715af8c0)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0x7f0a715c00e0) 0 empty
+
+Class QListData::Data
+ size=32 align=8
+ base size=32 base align=8
+QListData::Data (0x7f0a715c0620) 0
+
+Class QListData
+ size=8 align=8
+ base size=8 base align=8
+QListData (0x7f0a715c05b0) 0
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QObjectData)
+16 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QObjectData
+ size=40 align=8
+ base size=40 base align=8
+QObjectData (0x7f0a714c2bd0) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 16u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QObject)
+16 QObject::metaObject
+24 QObject::qt_metacast
+32 QObject::qt_metacall
+40 QObject::~QObject
+48 QObject::~QObject
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QObject
+ size=16 align=8
+ base size=16 base align=8
+QObject (0x7f0a714c2ee0) 0
+ vptr=((& QObject::_ZTV7QObject) + 16u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QObjectUserData)
+16 QObjectUserData::~QObjectUserData
+24 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=8 align=8
+ base size=8 base align=8
+QObjectUserData (0x7f0a713563f0) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QIODevice)
+16 QIODevice::metaObject
+24 QIODevice::qt_metacast
+32 QIODevice::qt_metacall
+40 QIODevice::~QIODevice
+48 QIODevice::~QIODevice
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QIODevice::isSequential
+120 QIODevice::open
+128 QIODevice::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QIODevice::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 __cxa_pure_virtual
+224 QIODevice::readLineData
+232 __cxa_pure_virtual
+
+Class QIODevice
+ size=16 align=8
+ base size=16 base align=8
+QIODevice (0x7f0a71356930) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 16u)
+ QObject (0x7f0a713569a0) 0
+ primary-for QIODevice (0x7f0a71356930)
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QDataStream)
+16 QDataStream::~QDataStream
+24 QDataStream::~QDataStream
+
+Class QDataStream
+ size=40 align=8
+ base size=40 base align=8
+QDataStream (0x7f0a713cc2a0) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 16u)
+
+Class QHashData::Node
+ size=16 align=8
+ base size=16 base align=8
+QHashData::Node (0x7f0a71251150) 0
+
+Class QHashData
+ size=40 align=8
+ base size=40 base align=8
+QHashData (0x7f0a712510e0) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0x7f0a71260ee0) 0 empty
+
+Class QMapData::Node
+ size=16 align=8
+ base size=16 base align=8
+QMapData::Node (0x7f0a71173690) 0
+
+Class QMapData
+ size=128 align=8
+ base size=128 base align=8
+QMapData (0x7f0a71173620) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSystemLocale)
+16 QSystemLocale::~QSystemLocale
+24 QSystemLocale::~QSystemLocale
+32 QSystemLocale::query
+40 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=8 align=8
+ base size=8 base align=8
+QSystemLocale (0x7f0a71089e00) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 16u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0x7f0a70ee63f0) 0
+
+Class QLocale
+ size=8 align=8
+ base size=8 base align=8
+QLocale (0x7f0a710a90e0) 0
+
+Class QTextCodec::ConverterState
+ size=32 align=8
+ base size=32 base align=8
+QTextCodec::ConverterState (0x7f0a70f34e70) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextCodec)
+16 __cxa_pure_virtual
+24 QTextCodec::aliases
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QTextCodec::~QTextCodec
+64 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=8 align=8
+ base size=8 base align=8
+QTextCodec (0x7f0a70f1ea80) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u)
+
+Class QTextEncoder
+ size=40 align=8
+ base size=40 base align=8
+QTextEncoder (0x7f0a70fa13f0) 0
+
+Class QTextDecoder
+ size=40 align=8
+ base size=40 base align=8
+QTextDecoder (0x7f0a70fa8230) 0
+
+Class _IO_marker
+ size=24 align=8
+ base size=24 base align=8
+_IO_marker (0x7f0a70fb22a0) 0
+
+Class _IO_FILE
+ size=216 align=8
+ base size=216 base align=8
+_IO_FILE (0x7f0a70fb2310) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextStream)
+16 QTextStream::~QTextStream
+24 QTextStream::~QTextStream
+
+Class QTextStream
+ size=16 align=8
+ base size=16 base align=8
+QTextStream (0x7f0a70fb23f0) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 16u)
+
+Class QTextStreamManipulator
+ size=40 align=8
+ base size=38 base align=8
+QTextStreamManipulator (0x7f0a70e4aee0) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextIStream)
+16 QTextIStream::~QTextIStream
+24 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=16 align=8
+ base size=16 base align=8
+QTextIStream (0x7f0a70e771c0) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 16u)
+ QTextStream (0x7f0a70e77230) 0
+ primary-for QTextIStream (0x7f0a70e771c0)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextOStream)
+16 QTextOStream::~QTextOStream
+24 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=16 align=8
+ base size=16 base align=8
+QTextOStream (0x7f0a70e8a070) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 16u)
+ QTextStream (0x7f0a70e8a0e0) 0
+ primary-for QTextOStream (0x7f0a70e8a070)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0x7f0a70e98ee0) 0
+
+Class timespec
+ size=16 align=8
+ base size=16 base align=8
+timespec (0x7f0a70ea4230) 0
+
+Class timeval
+ size=16 align=8
+ base size=16 base align=8
+timeval (0x7f0a70ea42a0) 0
+
+Class __pthread_internal_list
+ size=16 align=8
+ base size=16 base align=8
+__pthread_internal_list (0x7f0a70ea43f0) 0
+
+Class random_data
+ size=48 align=8
+ base size=48 base align=8
+random_data (0x7f0a70ea49a0) 0
+
+Class drand48_data
+ size=24 align=8
+ base size=24 base align=8
+drand48_data (0x7f0a70ea4a10) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0x7f0a70ea4a80) 0
+
+Class QDebug::Stream
+ size=40 align=8
+ base size=34 base align=8
+QDebug::Stream (0x7f0a70c1f230) 0
+
+Class QDebug
+ size=8 align=8
+ base size=8 base align=8
+QDebug (0x7f0a70c1f1c0) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0x7f0a70cbe070) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QFile)
+16 QFile::metaObject
+24 QFile::qt_metacast
+32 QFile::qt_metacall
+40 QFile::~QFile
+48 QFile::~QFile
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFile::isSequential
+120 QFile::open
+128 QFile::close
+136 QFile::pos
+144 QFile::size
+152 QFile::seek
+160 QFile::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QFile::readData
+224 QFile::readLineData
+232 QFile::writeData
+240 QFile::fileEngine
+
+Class QFile
+ size=16 align=8
+ base size=16 base align=8
+QFile (0x7f0a70ccf620) 0
+ vptr=((& QFile::_ZTV5QFile) + 16u)
+ QIODevice (0x7f0a70ccf690) 0
+ primary-for QFile (0x7f0a70ccf620)
+ QObject (0x7f0a70ccf700) 0
+ primary-for QIODevice (0x7f0a70ccf690)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTemporaryFile)
+16 QTemporaryFile::metaObject
+24 QTemporaryFile::qt_metacast
+32 QTemporaryFile::qt_metacall
+40 QTemporaryFile::~QTemporaryFile
+48 QTemporaryFile::~QTemporaryFile
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFile::isSequential
+120 QTemporaryFile::open
+128 QFile::close
+136 QFile::pos
+144 QFile::size
+152 QFile::seek
+160 QFile::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QFile::readData
+224 QFile::readLineData
+232 QFile::writeData
+240 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=16 align=8
+ base size=16 base align=8
+QTemporaryFile (0x7f0a70b39850) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u)
+ QFile (0x7f0a70b398c0) 0
+ primary-for QTemporaryFile (0x7f0a70b39850)
+ QIODevice (0x7f0a70b39930) 0
+ primary-for QFile (0x7f0a70b398c0)
+ QObject (0x7f0a70b399a0) 0
+ primary-for QIODevice (0x7f0a70b39930)
+
+Class QFileInfo
+ size=8 align=8
+ base size=8 base align=8
+QFileInfo (0x7f0a70b5af50) 0
+
+Class QRegExp
+ size=8 align=8
+ base size=8 base align=8
+QRegExp (0x7f0a70bb8770) 0
+
+Class QStringMatcher
+ size=1048 align=8
+ base size=1048 base align=8
+QStringMatcher (0x7f0a70a045b0) 0
+
+Class QStringList
+ size=8 align=8
+ base size=8 base align=8
+QStringList (0x7f0a70a16070) 0
+ QList<QString> (0x7f0a70a160e0) 0
+
+Class QDir
+ size=8 align=8
+ base size=8 base align=8
+QDir (0x7f0a70aa5cb0) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0x7f0a7093fe70) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0x7f0a7093fee0) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=24 align=8
+ base size=20 base align=8
+QAbstractFileEngine::MapExtensionOption (0x7f0a7093ff50) 0
+ QAbstractFileEngine::ExtensionOption (0x7f0a70954000) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngine::MapExtensionReturn (0x7f0a709541c0) 0
+ QAbstractFileEngine::ExtensionReturn (0x7f0a70954230) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngine::UnMapExtensionOption (0x7f0a709542a0) 0
+ QAbstractFileEngine::ExtensionOption (0x7f0a70954310) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+16 QAbstractFileEngine::~QAbstractFileEngine
+24 QAbstractFileEngine::~QAbstractFileEngine
+32 QAbstractFileEngine::open
+40 QAbstractFileEngine::close
+48 QAbstractFileEngine::flush
+56 QAbstractFileEngine::size
+64 QAbstractFileEngine::pos
+72 QAbstractFileEngine::seek
+80 QAbstractFileEngine::isSequential
+88 QAbstractFileEngine::remove
+96 QAbstractFileEngine::copy
+104 QAbstractFileEngine::rename
+112 QAbstractFileEngine::link
+120 QAbstractFileEngine::mkdir
+128 QAbstractFileEngine::rmdir
+136 QAbstractFileEngine::setSize
+144 QAbstractFileEngine::caseSensitive
+152 QAbstractFileEngine::isRelativePath
+160 QAbstractFileEngine::entryList
+168 QAbstractFileEngine::fileFlags
+176 QAbstractFileEngine::setPermissions
+184 QAbstractFileEngine::fileName
+192 QAbstractFileEngine::ownerId
+200 QAbstractFileEngine::owner
+208 QAbstractFileEngine::fileTime
+216 QAbstractFileEngine::setFileName
+224 QAbstractFileEngine::handle
+232 QAbstractFileEngine::beginEntryList
+240 QAbstractFileEngine::endEntryList
+248 QAbstractFileEngine::read
+256 QAbstractFileEngine::readLine
+264 QAbstractFileEngine::write
+272 QAbstractFileEngine::extension
+280 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=16 align=8
+ base size=16 base align=8
+QAbstractFileEngine (0x7f0a7092fe00) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 16u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+16 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+24 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+32 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngineHandler (0x7f0a70983000) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 16u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+16 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+24 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QAbstractFileEngineIterator::currentFileInfo
+64 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=16 align=8
+ base size=16 base align=8
+QAbstractFileEngineIterator (0x7f0a709831c0) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 16u)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFSFileEngine)
+16 QFSFileEngine::~QFSFileEngine
+24 QFSFileEngine::~QFSFileEngine
+32 QFSFileEngine::open
+40 QFSFileEngine::close
+48 QFSFileEngine::flush
+56 QFSFileEngine::size
+64 QFSFileEngine::pos
+72 QFSFileEngine::seek
+80 QFSFileEngine::isSequential
+88 QFSFileEngine::remove
+96 QFSFileEngine::copy
+104 QFSFileEngine::rename
+112 QFSFileEngine::link
+120 QFSFileEngine::mkdir
+128 QFSFileEngine::rmdir
+136 QFSFileEngine::setSize
+144 QFSFileEngine::caseSensitive
+152 QFSFileEngine::isRelativePath
+160 QFSFileEngine::entryList
+168 QFSFileEngine::fileFlags
+176 QFSFileEngine::setPermissions
+184 QFSFileEngine::fileName
+192 QFSFileEngine::ownerId
+200 QFSFileEngine::owner
+208 QFSFileEngine::fileTime
+216 QFSFileEngine::setFileName
+224 QFSFileEngine::handle
+232 QFSFileEngine::beginEntryList
+240 QFSFileEngine::endEntryList
+248 QFSFileEngine::read
+256 QFSFileEngine::readLine
+264 QFSFileEngine::write
+272 QFSFileEngine::extension
+280 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=16 align=8
+ base size=16 base align=8
+QFSFileEngine (0x7f0a70983a10) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 16u)
+ QAbstractFileEngine (0x7f0a70983a80) 0
+ primary-for QFSFileEngine (0x7f0a70983a10)
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QProcess)
+16 QProcess::metaObject
+24 QProcess::qt_metacast
+32 QProcess::qt_metacall
+40 QProcess::~QProcess
+48 QProcess::~QProcess
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QProcess::isSequential
+120 QIODevice::open
+128 QProcess::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QProcess::atEnd
+168 QIODevice::reset
+176 QProcess::bytesAvailable
+184 QProcess::bytesToWrite
+192 QProcess::canReadLine
+200 QProcess::waitForReadyRead
+208 QProcess::waitForBytesWritten
+216 QProcess::readData
+224 QIODevice::readLineData
+232 QProcess::writeData
+240 QProcess::setupChildProcess
+
+Class QProcess
+ size=16 align=8
+ base size=16 base align=8
+QProcess (0x7f0a7099ad20) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 16u)
+ QIODevice (0x7f0a7099ad90) 0
+ primary-for QProcess (0x7f0a7099ad20)
+ QObject (0x7f0a7099ae00) 0
+ primary-for QIODevice (0x7f0a7099ad90)
+
+Class QResource
+ size=8 align=8
+ base size=8 base align=8
+QResource (0x7f0a707b7230) 0
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QDirIterator)
+16 QDirIterator::~QDirIterator
+24 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=16 align=8
+ base size=16 base align=8
+QDirIterator (0x7f0a707b7cb0) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 16u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBuffer)
+16 QBuffer::metaObject
+24 QBuffer::qt_metacast
+32 QBuffer::qt_metacall
+40 QBuffer::~QBuffer
+48 QBuffer::~QBuffer
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QBuffer::connectNotify
+104 QBuffer::disconnectNotify
+112 QIODevice::isSequential
+120 QBuffer::open
+128 QBuffer::close
+136 QBuffer::pos
+144 QBuffer::size
+152 QBuffer::seek
+160 QBuffer::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QBuffer::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QBuffer::readData
+224 QIODevice::readLineData
+232 QBuffer::writeData
+
+Class QBuffer
+ size=16 align=8
+ base size=16 base align=8
+QBuffer (0x7f0a707e7a80) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 16u)
+ QIODevice (0x7f0a707e7af0) 0
+ primary-for QBuffer (0x7f0a707e7a80)
+ QObject (0x7f0a707e7b60) 0
+ primary-for QIODevice (0x7f0a707e7af0)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+16 QFileSystemWatcher::metaObject
+24 QFileSystemWatcher::qt_metacast
+32 QFileSystemWatcher::qt_metacall
+40 QFileSystemWatcher::~QFileSystemWatcher
+48 QFileSystemWatcher::~QFileSystemWatcher
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemWatcher (0x7f0a7080f690) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u)
+ QObject (0x7f0a7080f700) 0
+ primary-for QFileSystemWatcher (0x7f0a7080f690)
+
+Class QUrl
+ size=8 align=8
+ base size=8 base align=8
+QUrl (0x7f0a70823bd0) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0x7f0a708ad3f0) 0 empty
+
+Class QVariant::PrivateShared
+ size=16 align=8
+ base size=12 base align=8
+QVariant::PrivateShared (0x7f0a7077e930) 0
+
+Class QVariant::Private::Data
+ size=8 align=8
+ base size=8 base align=8
+QVariant::Private::Data (0x7f0a7077ec40) 0
+
+Class QVariant::Private
+ size=16 align=8
+ base size=12 base align=8
+QVariant::Private (0x7f0a7077ea10) 0
+
+Class QVariant::Handler
+ size=72 align=8
+ base size=72 base align=8
+QVariant::Handler (0x7f0a7078d930) 0
+
+Class QVariant
+ size=16 align=8
+ base size=16 base align=8
+QVariant (0x7f0a7074eaf0) 0
+
+Class QVariantComparisonHelper
+ size=8 align=8
+ base size=8 base align=8
+QVariantComparisonHelper (0x7f0a70635cb0) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSettings)
+16 QSettings::metaObject
+24 QSettings::qt_metacast
+32 QSettings::qt_metacall
+40 QSettings::~QSettings
+48 QSettings::~QSettings
+56 QSettings::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSettings
+ size=16 align=8
+ base size=16 base align=8
+QSettings (0x7f0a70659cb0) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 16u)
+ QObject (0x7f0a70659d20) 0
+ primary-for QSettings (0x7f0a70659cb0)
+
+Class QXmlStreamStringRef
+ size=16 align=8
+ base size=16 base align=8
+QXmlStreamStringRef (0x7f0a704da070) 0
+
+Class QXmlStreamAttribute
+ size=80 align=8
+ base size=73 base align=8
+QXmlStreamAttribute (0x7f0a704f8850) 0
+
+Class QXmlStreamAttributes
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamAttributes (0x7f0a70520380) 0
+ QVector<QXmlStreamAttribute> (0x7f0a705203f0) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=40 align=8
+ base size=40 base align=8
+QXmlStreamNamespaceDeclaration (0x7f0a70520850) 0
+
+Class QXmlStreamNotationDeclaration
+ size=56 align=8
+ base size=56 base align=8
+QXmlStreamNotationDeclaration (0x7f0a705611c0) 0
+
+Class QXmlStreamEntityDeclaration
+ size=88 align=8
+ base size=88 base align=8
+QXmlStreamEntityDeclaration (0x7f0a7057f070) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+16 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+24 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+32 QXmlStreamEntityResolver::resolveEntity
+40 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamEntityResolver (0x7f0a7059c9a0) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u)
+
+Class QXmlStreamReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamReader (0x7f0a7059cb60) 0
+
+Class QXmlStreamWriter
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamWriter (0x7f0a703daa10) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0x7f0a70418150) 0
+
+Class QPointF
+ size=16 align=8
+ base size=16 base align=8
+QPointF (0x7f0a7044ed90) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0x7f0a7048bbd0) 0
+
+Class QLineF
+ size=32 align=8
+ base size=32 base align=8
+QLineF (0x7f0a702c6a80) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0x7f0a70322540) 0
+
+Class QSizeF
+ size=16 align=8
+ base size=16 base align=8
+QSizeF (0x7f0a7036d380) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0x7f0a701ba9a0) 0
+
+Class QRectF
+ size=32 align=8
+ base size=32 base align=8
+QRectF (0x7f0a70271380) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0x7f0a70115150) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+16 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+24 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+32 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=16 align=8
+ base size=16 base align=8
+QtSharedPointer::ExternalRefCountData (0x7f0a70144af0) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 16u)
+
+Class QLinkedListData
+ size=32 align=8
+ base size=32 base align=8
+QLinkedListData (0x7f0a6ffcbc40) 0
+
+Class QBitArray
+ size=8 align=8
+ base size=8 base align=8
+QBitArray (0x7f0a70097b60) 0
+
+Class QBitRef
+ size=16 align=8
+ base size=12 base align=8
+QBitRef (0x7f0a6ff0b930) 0
+
+Class QByteArrayMatcher
+ size=1040 align=8
+ base size=1040 base align=8
+QByteArrayMatcher (0x7f0a6ff25310) 0
+
+Class QCryptographicHash
+ size=8 align=8
+ base size=8 base align=8
+QCryptographicHash (0x7f0a6ff36a10) 0
+
+Class QTextBoundaryFinder
+ size=48 align=8
+ base size=48 base align=8
+QTextBoundaryFinder (0x7f0a6ff64460) 0
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0x7f0a6ff797e0) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0x7f0a6fda3770) 0
+
+Class QDateTime
+ size=8 align=8
+ base size=8 base align=8
+QDateTime (0x7f0a6fdc1d20) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeLine)
+16 QTimeLine::metaObject
+24 QTimeLine::qt_metacast
+32 QTimeLine::qt_metacall
+40 QTimeLine::~QTimeLine
+48 QTimeLine::~QTimeLine
+56 QObject::event
+64 QObject::eventFilter
+72 QTimeLine::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=16 align=8
+ base size=16 base align=8
+QTimeLine (0x7f0a6fdf51c0) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u)
+ QObject (0x7f0a6fdf5230) 0
+ primary-for QTimeLine (0x7f0a6fdf51c0)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QRunnable)
+16 __cxa_pure_virtual
+24 QRunnable::~QRunnable
+32 QRunnable::~QRunnable
+
+Class QRunnable
+ size=16 align=8
+ base size=12 base align=8
+QRunnable (0x7f0a6fe1b070) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 16u)
+
+Class QMutex
+ size=8 align=8
+ base size=8 base align=8
+QMutex (0x7f0a6fe29700) 0
+
+Class QMutexLocker
+ size=8 align=8
+ base size=8 base align=8
+QMutexLocker (0x7f0a6fe372a0) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+16 QtConcurrent::Exception::~Exception
+24 QtConcurrent::Exception::~Exception
+32 std::exception::what
+40 QtConcurrent::Exception::raise
+48 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::Exception (0x7f0a6fe4e5b0) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 16u)
+ std::exception (0x7f0a6fe4e620) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0x7f0a6fe4e5b0)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+16 QtConcurrent::UnhandledException::~UnhandledException
+24 QtConcurrent::UnhandledException::~UnhandledException
+32 std::exception::what
+40 QtConcurrent::UnhandledException::raise
+48 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::UnhandledException (0x7f0a6fe4e850) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 16u)
+ QtConcurrent::Exception (0x7f0a6fe4e8c0) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0x7f0a6fe4e850)
+ std::exception (0x7f0a6fe4e930) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0x7f0a6fe4e8c0)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::internal::ExceptionHolder (0x7f0a6fe4eb60) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::internal::ExceptionStore (0x7f0a6fe4eee0) 0
+
+Class QtConcurrent::ResultItem
+ size=16 align=8
+ base size=16 base align=8
+QtConcurrent::ResultItem (0x7f0a6fe4ef50) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=16 align=8
+ base size=12 base align=8
+QtConcurrent::ResultIteratorBase (0x7f0a6fe66e70) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+16 QtConcurrent::ResultStoreBase::~ResultStoreBase
+24 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=48 align=8
+ base size=44 base align=8
+QtConcurrent::ResultStoreBase (0x7f0a6fe69a10) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 16u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+16 QFutureInterfaceBase::~QFutureInterfaceBase
+24 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureInterfaceBase (0x7f0a6fca9e70) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QThread)
+16 QThread::metaObject
+24 QThread::qt_metacast
+32 QThread::qt_metacall
+40 QThread::~QThread
+48 QThread::~QThread
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QThread::run
+
+Class QThread
+ size=16 align=8
+ base size=16 base align=8
+QThread (0x7f0a6fd8be00) 0
+ vptr=((& QThread::_ZTV7QThread) + 16u)
+ QObject (0x7f0a6fd8be70) 0
+ primary-for QThread (0x7f0a6fd8be00)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QThreadPool)
+16 QThreadPool::metaObject
+24 QThreadPool::qt_metacast
+32 QThreadPool::qt_metacall
+40 QThreadPool::~QThreadPool
+48 QThreadPool::~QThreadPool
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QThreadPool
+ size=16 align=8
+ base size=16 base align=8
+QThreadPool (0x7f0a6fbc0cb0) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u)
+ QObject (0x7f0a6fbc0d20) 0
+ primary-for QThreadPool (0x7f0a6fbc0cb0)
+
+Class QWaitCondition
+ size=8 align=8
+ base size=8 base align=8
+QWaitCondition (0x7f0a6fbd9540) 0
+
+Class QtConcurrent::ThreadEngineSemaphore
+ size=24 align=8
+ base size=24 base align=8
+QtConcurrent::ThreadEngineSemaphore (0x7f0a6fbd9a80) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+16 QtConcurrent::ThreadEngineBase::run
+24 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+32 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+40 QtConcurrent::ThreadEngineBase::start
+48 QtConcurrent::ThreadEngineBase::finish
+56 QtConcurrent::ThreadEngineBase::threadFunction
+64 QtConcurrent::ThreadEngineBase::shouldStartThread
+72 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+80 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=64 align=8
+ base size=64 base align=8
+QtConcurrent::ThreadEngineBase (0x7f0a6fbf9460) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 16u)
+ QRunnable (0x7f0a6fbf94d0) 0
+ primary-for QtConcurrent::ThreadEngineBase (0x7f0a6fbf9460)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 24u)
+8 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 136u)
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0x7f0a6fc3c850) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0x7f0a6fc3c8c0) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0x7f0a6fc3c930) 0 empty
+ std::input_iterator_tag (0x7f0a6fc3c9a0) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0x7f0a6fc3ca10) 0 empty
+ std::forward_iterator_tag (0x7f0a6fc3ca80) 0 empty
+ std::input_iterator_tag (0x7f0a6fc3caf0) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0x7f0a6fc3cb60) 0 empty
+ std::bidirectional_iterator_tag (0x7f0a6fc3cbd0) 0 empty
+ std::forward_iterator_tag (0x7f0a6fc3cc40) 0 empty
+ std::input_iterator_tag (0x7f0a6fc3ccb0) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0x7f0a6fc4d2a0) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0x7f0a6fc4d310) 0 empty
+
+Class lconv
+ size=96 align=8
+ base size=96 base align=8
+lconv (0x7f0a6fa29620) 0
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0x7f0a6fa29a80) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0x7f0a6fa29af0) 0
+
+Class tm
+ size=56 align=8
+ base size=56 base align=8
+tm (0x7f0a6fa29bd0) 0
+
+Class itimerspec
+ size=32 align=8
+ base size=32 base align=8
+itimerspec (0x7f0a6fa29cb0) 0
+
+Class _pthread_cleanup_buffer
+ size=32 align=8
+ base size=32 base align=8
+_pthread_cleanup_buffer (0x7f0a6fa29d20) 0
+
+Class __pthread_cleanup_frame
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_frame (0x7f0a6fa29e70) 0
+
+Class __pthread_cleanup_class
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_class (0x7f0a6fa29ee0) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+16 __cxxabiv1::__forced_unwind::~__forced_unwind
+24 __cxxabiv1::__forced_unwind::~__forced_unwind
+32 __cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=8 align=8
+ base size=8 base align=8
+__cxxabiv1::__forced_unwind (0x7f0a6f93da80) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u)
+
+Class std::locale
+ size=8 align=8
+ base size=8 base align=8
+std::locale (0x7f0a6f5ee5b0) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6locale5facetE)
+16 std::locale::facet::~facet
+24 std::locale::facet::~facet
+
+Class std::locale::facet
+ size=16 align=8
+ base size=12 base align=8
+std::locale::facet (0x7f0a6f692cb0) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u)
+
+Class std::locale::id
+ size=8 align=8
+ base size=8 base align=8
+std::locale::id (0x7f0a6f4a62a0) 0
+
+Class std::locale::_Impl
+ size=40 align=8
+ base size=40 base align=8
+std::locale::_Impl (0x7f0a6f4a68c0) 0
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt8ios_base7failureE)
+16 std::ios_base::failure::~failure
+24 std::ios_base::failure::~failure
+32 std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=16 align=8
+ base size=16 base align=8
+std::ios_base::failure (0x7f0a6f534070) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureE) + 16u)
+ std::exception (0x7f0a6f5340e0) 0 nearly-empty
+ primary-for std::ios_base::failure (0x7f0a6f534070)
+
+Class std::ios_base::_Callback_list
+ size=24 align=8
+ base size=24 base align=8
+std::ios_base::_Callback_list (0x7f0a6f541310) 0
+
+Class std::ios_base::_Words
+ size=16 align=8
+ base size=16 base align=8
+std::ios_base::_Words (0x7f0a6f541d90) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0x7f0a6f54a4d0) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8ios_base)
+16 std::ios_base::~ios_base
+24 std::ios_base::~ios_base
+
+Class std::ios_base
+ size=216 align=8
+ base size=216 base align=8
+std::ios_base (0x7f0a6f534000) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0x7f0a6f3c1930) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0x7f0a6f2dd1c0) 0 empty
+
+VTT for std::basic_ostream<char, std::char_traits<char> >
+std::basic_ostream<char, std::char_traits<char> >::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 24u)
+8 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 64u)
+
+VTT for std::basic_ostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u)
+
+VTT for std::basic_istream<char, std::char_traits<char> >
+std::basic_istream<char, std::char_traits<char> >::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 24u)
+8 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 64u)
+
+VTT for std::basic_istream<wchar_t, std::char_traits<wchar_t> >
+std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u)
+
+Construction vtable for std::basic_istream<char, std::char_traits<char> > (0x7f0a6f012310 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISi)
+24 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+32 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+40 -24u
+48 (int (*)(...))-0x00000000000000018
+56 (int (*)(...))(& _ZTISi)
+64 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n24_NSiD1Ev
+72 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n24_NSiD0Ev
+
+Construction vtable for std::basic_ostream<char, std::char_traits<char> > (0x7f0a6f012460 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd16_So: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISo)
+24 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+32 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+40 -8u
+48 (int (*)(...))-0x00000000000000008
+56 (int (*)(...))(& _ZTISo)
+64 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n24_NSoD1Ev
+72 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n24_NSoD0Ev
+
+VTT for std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 24u)
+8 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 24u)
+16 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 64u)
+24 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd16_So) + 24u)
+32 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd16_So) + 64u)
+40 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 104u)
+48 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 64u)
+
+Construction vtable for std::basic_istream<wchar_t, std::char_traits<wchar_t> > (0x7f0a6f012620 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+24 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+32 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+40 -24u
+48 (int (*)(...))-0x00000000000000018
+56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+64 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED1Ev
+72 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED0Ev
+
+Construction vtable for std::basic_ostream<wchar_t, std::char_traits<wchar_t> > (0x7f0a6f012770 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+24 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+32 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+40 -8u
+48 (int (*)(...))-0x00000000000000008
+56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+64 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev
+72 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev
+
+VTT for std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u)
+16 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u)
+24 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u)
+32 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u)
+40 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u)
+48 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u)
+
+Class QtConcurrent::BlockSizeManager
+ size=96 align=8
+ base size=92 base align=8
+QtConcurrent::BlockSizeManager (0x7f0a6f07d230) 0
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+16 QFutureWatcherBase::metaObject
+24 QFutureWatcherBase::qt_metacast
+32 QFutureWatcherBase::qt_metacall
+40 QFutureWatcherBase::~QFutureWatcherBase
+48 QFutureWatcherBase::~QFutureWatcherBase
+56 QFutureWatcherBase::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QFutureWatcherBase::connectNotify
+104 QFutureWatcherBase::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureWatcherBase (0x7f0a6ec46bd0) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u)
+ QObject (0x7f0a6ec46c40) 0
+ primary-for QFutureWatcherBase (0x7f0a6ec46bd0)
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFactoryInterface)
+16 QFactoryInterface::~QFactoryInterface
+24 QFactoryInterface::~QFactoryInterface
+32 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QFactoryInterface (0x7f0a6eb5ee00) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+16 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+24 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QTextCodecFactoryInterface (0x7f0a6eb81ee0) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 16u)
+ QFactoryInterface (0x7f0a6eb81f50) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0x7f0a6eb81ee0)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+16 QTextCodecPlugin::metaObject
+24 QTextCodecPlugin::qt_metacast
+32 QTextCodecPlugin::qt_metacall
+40 QTextCodecPlugin::~QTextCodecPlugin
+48 QTextCodecPlugin::~QTextCodecPlugin
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 QTextCodecPlugin::keys
+160 QTextCodecPlugin::create
+168 (int (*)(...))-0x00000000000000010
+176 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+184 QTextCodecPlugin::_ZThn16_N16QTextCodecPluginD1Ev
+192 QTextCodecPlugin::_ZThn16_N16QTextCodecPluginD0Ev
+200 QTextCodecPlugin::_ZThn16_NK16QTextCodecPlugin4keysEv
+208 QTextCodecPlugin::_ZThn16_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=24 align=8
+ base size=24 base align=8
+QTextCodecPlugin (0x7f0a6eb84e00) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 16u)
+ QObject (0x7f0a6eb8d7e0) 0
+ primary-for QTextCodecPlugin (0x7f0a6eb84e00)
+ QTextCodecFactoryInterface (0x7f0a6eb8d850) 16 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 184u)
+ QFactoryInterface (0x7f0a6eb8d8c0) 16 nearly-empty
+ primary-for QTextCodecFactoryInterface (0x7f0a6eb8d850)
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0x7f0a6e9a3700) 0 empty
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTranslator)
+16 QTranslator::metaObject
+24 QTranslator::qt_metacast
+32 QTranslator::qt_metacall
+40 QTranslator::~QTranslator
+48 QTranslator::~QTranslator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTranslator::translate
+120 QTranslator::isEmpty
+
+Class QTranslator
+ size=16 align=8
+ base size=16 base align=8
+QTranslator (0x7f0a6e9e6000) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 16u)
+ QObject (0x7f0a6e9e6070) 0
+ primary-for QTranslator (0x7f0a6e9e6000)
+
+Class __exception
+ size=40 align=8
+ base size=40 base align=8
+__exception (0x7f0a6e9f9f50) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QMimeData)
+16 QMimeData::metaObject
+24 QMimeData::qt_metacast
+32 QMimeData::qt_metacall
+40 QMimeData::~QMimeData
+48 QMimeData::~QMimeData
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QMimeData::hasFormat
+120 QMimeData::formats
+128 QMimeData::retrieveData
+
+Class QMimeData
+ size=16 align=8
+ base size=16 base align=8
+QMimeData (0x7f0a6ea64150) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 16u)
+ QObject (0x7f0a6ea641c0) 0
+ primary-for QMimeData (0x7f0a6ea64150)
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QEventLoop)
+16 QEventLoop::metaObject
+24 QEventLoop::qt_metacast
+32 QEventLoop::qt_metacall
+40 QEventLoop::~QEventLoop
+48 QEventLoop::~QEventLoop
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QEventLoop
+ size=16 align=8
+ base size=16 base align=8
+QEventLoop (0x7f0a6ea7d9a0) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u)
+ QObject (0x7f0a6ea7da10) 0
+ primary-for QEventLoop (0x7f0a6ea7d9a0)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QEvent)
+16 QEvent::~QEvent
+24 QEvent::~QEvent
+
+Class QEvent
+ size=24 align=8
+ base size=20 base align=8
+QEvent (0x7f0a6e8be310) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 16u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTimerEvent)
+16 QTimerEvent::~QTimerEvent
+24 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=24 align=8
+ base size=24 base align=8
+QTimerEvent (0x7f0a6e8d6ee0) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u)
+ QEvent (0x7f0a6e8d6f50) 0
+ primary-for QTimerEvent (0x7f0a6e8d6ee0)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QChildEvent)
+16 QChildEvent::~QChildEvent
+24 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=32 align=8
+ base size=32 base align=8
+QChildEvent (0x7f0a6e8db380) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u)
+ QEvent (0x7f0a6e8db3f0) 0
+ primary-for QChildEvent (0x7f0a6e8db380)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QCustomEvent)
+16 QCustomEvent::~QCustomEvent
+24 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=24 align=8
+ base size=20 base align=8
+QCustomEvent (0x7f0a6e8eb620) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 16u)
+ QEvent (0x7f0a6e8eb690) 0
+ primary-for QCustomEvent (0x7f0a6e8eb620)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+16 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+24 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=32 align=8
+ base size=32 base align=8
+QDynamicPropertyChangeEvent (0x7f0a6e8ebe00) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u)
+ QEvent (0x7f0a6e8ebe70) 0
+ primary-for QDynamicPropertyChangeEvent (0x7f0a6e8ebe00)
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QCoreApplication)
+16 QCoreApplication::metaObject
+24 QCoreApplication::qt_metacast
+32 QCoreApplication::qt_metacall
+40 QCoreApplication::~QCoreApplication
+48 QCoreApplication::~QCoreApplication
+56 QCoreApplication::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QCoreApplication::notify
+120 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=16 align=8
+ base size=16 base align=8
+QCoreApplication (0x7f0a6e8fb230) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u)
+ QObject (0x7f0a6e8fb2a0) 0
+ primary-for QCoreApplication (0x7f0a6e8fb230)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSharedMemory)
+16 QSharedMemory::metaObject
+24 QSharedMemory::qt_metacast
+32 QSharedMemory::qt_metacall
+40 QSharedMemory::~QSharedMemory
+48 QSharedMemory::~QSharedMemory
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=16 align=8
+ base size=16 base align=8
+QSharedMemory (0x7f0a6e925a80) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u)
+ QObject (0x7f0a6e925af0) 0
+ primary-for QSharedMemory (0x7f0a6e925a80)
+
+Class QModelIndex
+ size=24 align=8
+ base size=24 base align=8
+QModelIndex (0x7f0a6e946850) 0
+
+Class QPersistentModelIndex
+ size=8 align=8
+ base size=8 base align=8
+QPersistentModelIndex (0x7f0a6e96f310) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractItemModel)
+16 QAbstractItemModel::metaObject
+24 QAbstractItemModel::qt_metacast
+32 QAbstractItemModel::qt_metacall
+40 QAbstractItemModel::~QAbstractItemModel
+48 QAbstractItemModel::~QAbstractItemModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 QAbstractItemModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractItemModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemModel (0x7f0a6e97c5b0) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u)
+ QObject (0x7f0a6e97c620) 0
+ primary-for QAbstractItemModel (0x7f0a6e97c5b0)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTableModel)
+16 QAbstractTableModel::metaObject
+24 QAbstractTableModel::qt_metacast
+32 QAbstractTableModel::qt_metacall
+40 QAbstractTableModel::~QAbstractTableModel
+48 QAbstractTableModel::~QAbstractTableModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 QAbstractTableModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTableModel (0x7f0a6e7ce930) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u)
+ QAbstractItemModel (0x7f0a6e7ce9a0) 0
+ primary-for QAbstractTableModel (0x7f0a6e7ce930)
+ QObject (0x7f0a6e7cea10) 0
+ primary-for QAbstractItemModel (0x7f0a6e7ce9a0)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractListModel)
+16 QAbstractListModel::metaObject
+24 QAbstractListModel::qt_metacast
+32 QAbstractListModel::qt_metacall
+40 QAbstractListModel::~QAbstractListModel
+48 QAbstractListModel::~QAbstractListModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractListModel::index
+120 QAbstractListModel::parent
+128 __cxa_pure_virtual
+136 QAbstractListModel::columnCount
+144 QAbstractListModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractListModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractListModel (0x7f0a6e7daee0) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u)
+ QAbstractItemModel (0x7f0a6e7daf50) 0
+ primary-for QAbstractListModel (0x7f0a6e7daee0)
+ QObject (0x7f0a6e7da230) 0
+ primary-for QAbstractItemModel (0x7f0a6e7daf50)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSignalMapper)
+16 QSignalMapper::metaObject
+24 QSignalMapper::qt_metacast
+32 QSignalMapper::qt_metacall
+40 QSignalMapper::~QSignalMapper
+48 QSignalMapper::~QSignalMapper
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=16 align=8
+ base size=16 base align=8
+QSignalMapper (0x7f0a6e81c000) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u)
+ QObject (0x7f0a6e81c070) 0
+ primary-for QSignalMapper (0x7f0a6e81c000)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+16 QObjectCleanupHandler::metaObject
+24 QObjectCleanupHandler::qt_metacast
+32 QObjectCleanupHandler::qt_metacall
+40 QObjectCleanupHandler::~QObjectCleanupHandler
+48 QObjectCleanupHandler::~QObjectCleanupHandler
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=24 align=8
+ base size=24 base align=8
+QObjectCleanupHandler (0x7f0a6e8343f0) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u)
+ QObject (0x7f0a6e834460) 0
+ primary-for QObjectCleanupHandler (0x7f0a6e8343f0)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0x7f0a6e845540) 0
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSocketNotifier)
+16 QSocketNotifier::metaObject
+24 QSocketNotifier::qt_metacast
+32 QSocketNotifier::qt_metacall
+40 QSocketNotifier::~QSocketNotifier
+48 QSocketNotifier::~QSocketNotifier
+56 QSocketNotifier::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=32 align=8
+ base size=25 base align=8
+QSocketNotifier (0x7f0a6e851930) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u)
+ QObject (0x7f0a6e8519a0) 0
+ primary-for QSocketNotifier (0x7f0a6e851930)
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QTimer)
+16 QTimer::metaObject
+24 QTimer::qt_metacast
+32 QTimer::qt_metacall
+40 QTimer::~QTimer
+48 QTimer::~QTimer
+56 QObject::event
+64 QObject::eventFilter
+72 QTimer::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QTimer
+ size=32 align=8
+ base size=29 base align=8
+QTimer (0x7f0a6e86ccb0) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 16u)
+ QObject (0x7f0a6e86cd20) 0
+ primary-for QTimer (0x7f0a6e86ccb0)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+16 QAbstractEventDispatcher::metaObject
+24 QAbstractEventDispatcher::qt_metacast
+32 QAbstractEventDispatcher::qt_metacall
+40 QAbstractEventDispatcher::~QAbstractEventDispatcher
+48 QAbstractEventDispatcher::~QAbstractEventDispatcher
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+192 __cxa_pure_virtual
+200 QAbstractEventDispatcher::startingUp
+208 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=16 align=8
+ base size=16 base align=8
+QAbstractEventDispatcher (0x7f0a6e68f2a0) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u)
+ QObject (0x7f0a6e68f310) 0
+ primary-for QAbstractEventDispatcher (0x7f0a6e68f2a0)
+
+Class QMetaMethod
+ size=16 align=8
+ base size=12 base align=8
+QMetaMethod (0x7f0a6e6aa150) 0
+
+Class QMetaEnum
+ size=16 align=8
+ base size=12 base align=8
+QMetaEnum (0x7f0a6e6c55b0) 0
+
+Class QMetaProperty
+ size=32 align=8
+ base size=32 base align=8
+QMetaProperty (0x7f0a6e6d2310) 0
+
+Class QMetaClassInfo
+ size=16 align=8
+ base size=12 base align=8
+QMetaClassInfo (0x7f0a6e6d29a0) 0
+
+Class QSystemSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSystemSemaphore (0x7f0a6e6e54d0) 0
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QLibrary)
+16 QLibrary::metaObject
+24 QLibrary::qt_metacast
+32 QLibrary::qt_metacall
+40 QLibrary::~QLibrary
+48 QLibrary::~QLibrary
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QLibrary
+ size=32 align=8
+ base size=25 base align=8
+QLibrary (0x7f0a6e6e5e00) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 16u)
+ QObject (0x7f0a6e6e5e70) 0
+ primary-for QLibrary (0x7f0a6e6e5e00)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPluginLoader)
+16 QPluginLoader::metaObject
+24 QPluginLoader::qt_metacast
+32 QPluginLoader::qt_metacall
+40 QPluginLoader::~QPluginLoader
+48 QPluginLoader::~QPluginLoader
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=32 align=8
+ base size=25 base align=8
+QPluginLoader (0x7f0a6e72a8c0) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u)
+ QObject (0x7f0a6e72a930) 0
+ primary-for QPluginLoader (0x7f0a6e72a8c0)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0x7f0a6e74e070) 0
+
+Class QSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSemaphore (0x7f0a6e76c9a0) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0x7f0a6e76cee0) 0
+
+Class QReadWriteLock
+ size=8 align=8
+ base size=8 base align=8
+QReadWriteLock (0x7f0a6e77e690) 0
+
+Class QReadLocker
+ size=8 align=8
+ base size=8 base align=8
+QReadLocker (0x7f0a6e77ed20) 0
+
+Class QWriteLocker
+ size=8 align=8
+ base size=8 base align=8
+QWriteLocker (0x7f0a6e5ad0e0) 0
+
+Class QSqlRecord
+ size=8 align=8
+ base size=8 base align=8
+QSqlRecord (0x7f0a6e5bf460) 0
+
+Class QSqlIndex
+ size=32 align=8
+ base size=32 base align=8
+QSqlIndex (0x7f0a6e5d30e0) 0
+ QSqlRecord (0x7f0a6e5d3150) 0
+
+Vtable for QSqlResult
+QSqlResult::_ZTV10QSqlResult: 29u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSqlResult)
+16 QSqlResult::~QSqlResult
+24 QSqlResult::~QSqlResult
+32 QSqlResult::handle
+40 QSqlResult::setAt
+48 QSqlResult::setActive
+56 QSqlResult::setLastError
+64 QSqlResult::setQuery
+72 QSqlResult::setSelect
+80 QSqlResult::setForwardOnly
+88 QSqlResult::exec
+96 QSqlResult::prepare
+104 QSqlResult::savePrepare
+112 QSqlResult::bindValue
+120 QSqlResult::bindValue
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 QSqlResult::fetchNext
+168 QSqlResult::fetchPrevious
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+192 __cxa_pure_virtual
+200 __cxa_pure_virtual
+208 QSqlResult::record
+216 QSqlResult::lastInsertId
+224 QSqlResult::virtual_hook
+
+Class QSqlResult
+ size=16 align=8
+ base size=16 base align=8
+QSqlResult (0x7f0a6e627620) 0
+ vptr=((& QSqlResult::_ZTV10QSqlResult) + 16u)
+
+Vtable for QSqlDriverCreatorBase
+QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QSqlDriverCreatorBase)
+16 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+24 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+32 __cxa_pure_virtual
+
+Class QSqlDriverCreatorBase
+ size=8 align=8
+ base size=8 base align=8
+QSqlDriverCreatorBase (0x7f0a6e627ee0) 0 nearly-empty
+ vptr=((& QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase) + 16u)
+
+Class QSqlDatabase
+ size=8 align=8
+ base size=8 base align=8
+QSqlDatabase (0x7f0a6e6549a0) 0
+
+Class QSqlQuery
+ size=8 align=8
+ base size=8 base align=8
+QSqlQuery (0x7f0a6e665d90) 0
+
+Vtable for QSqlDriverFactoryInterface
+QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QSqlDriverFactoryInterface)
+16 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+24 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QSqlDriverFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QSqlDriverFactoryInterface (0x7f0a6e66f850) 0 nearly-empty
+ vptr=((& QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface) + 16u)
+ QFactoryInterface (0x7f0a6e66f8c0) 0 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0x7f0a6e66f850)
+
+Vtable for QSqlDriverPlugin
+QSqlDriverPlugin::_ZTV16QSqlDriverPlugin: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+16 QSqlDriverPlugin::metaObject
+24 QSqlDriverPlugin::qt_metacast
+32 QSqlDriverPlugin::qt_metacall
+40 QSqlDriverPlugin::~QSqlDriverPlugin
+48 QSqlDriverPlugin::~QSqlDriverPlugin
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 (int (*)(...))-0x00000000000000010
+136 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+144 QSqlDriverPlugin::_ZThn16_N16QSqlDriverPluginD1Ev
+152 QSqlDriverPlugin::_ZThn16_N16QSqlDriverPluginD0Ev
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+
+Class QSqlDriverPlugin
+ size=24 align=8
+ base size=24 base align=8
+QSqlDriverPlugin (0x7f0a6e659c80) 0
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 16u)
+ QObject (0x7f0a6e6890e0) 0
+ primary-for QSqlDriverPlugin (0x7f0a6e659c80)
+ QSqlDriverFactoryInterface (0x7f0a6e689150) 16 nearly-empty
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 144u)
+ QFactoryInterface (0x7f0a6e6891c0) 16 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0x7f0a6e689150)
+
+Vtable for QSqlDriver
+QSqlDriver::_ZTV10QSqlDriver: 32u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSqlDriver)
+16 QSqlDriver::metaObject
+24 QSqlDriver::qt_metacast
+32 QSqlDriver::qt_metacall
+40 QSqlDriver::~QSqlDriver
+48 QSqlDriver::~QSqlDriver
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QSqlDriver::isOpen
+120 QSqlDriver::beginTransaction
+128 QSqlDriver::commitTransaction
+136 QSqlDriver::rollbackTransaction
+144 QSqlDriver::tables
+152 QSqlDriver::primaryIndex
+160 QSqlDriver::record
+168 QSqlDriver::formatValue
+176 QSqlDriver::escapeIdentifier
+184 QSqlDriver::sqlStatement
+192 QSqlDriver::handle
+200 __cxa_pure_virtual
+208 __cxa_pure_virtual
+216 __cxa_pure_virtual
+224 __cxa_pure_virtual
+232 QSqlDriver::setOpen
+240 QSqlDriver::setOpenError
+248 QSqlDriver::setLastError
+
+Class QSqlDriver
+ size=16 align=8
+ base size=16 base align=8
+QSqlDriver (0x7f0a6e498070) 0
+ vptr=((& QSqlDriver::_ZTV10QSqlDriver) + 16u)
+ QObject (0x7f0a6e4980e0) 0
+ primary-for QSqlDriver (0x7f0a6e498070)
+
+Class QSqlError
+ size=24 align=8
+ base size=24 base align=8
+QSqlError (0x7f0a6e4be700) 0
+
+Class QSqlField
+ size=24 align=8
+ base size=24 base align=8
+QSqlField (0x7f0a6e4c7620) 0
+
+Vtable for QSqlQueryModel
+QSqlQueryModel::_ZTV14QSqlQueryModel: 44u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QSqlQueryModel)
+16 QSqlQueryModel::metaObject
+24 QSqlQueryModel::qt_metacast
+32 QSqlQueryModel::qt_metacall
+40 QSqlQueryModel::~QSqlQueryModel
+48 QSqlQueryModel::~QSqlQueryModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 QSqlQueryModel::rowCount
+136 QSqlQueryModel::columnCount
+144 QAbstractTableModel::hasChildren
+152 QSqlQueryModel::data
+160 QAbstractItemModel::setData
+168 QSqlQueryModel::headerData
+176 QSqlQueryModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QSqlQueryModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QSqlQueryModel::removeColumns
+264 QSqlQueryModel::fetchMore
+272 QSqlQueryModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+336 QSqlQueryModel::clear
+344 QSqlQueryModel::queryChange
+
+Class QSqlQueryModel
+ size=16 align=8
+ base size=16 base align=8
+QSqlQueryModel (0x7f0a6e4d9ee0) 0
+ vptr=((& QSqlQueryModel::_ZTV14QSqlQueryModel) + 16u)
+ QAbstractTableModel (0x7f0a6e4d9f50) 0
+ primary-for QSqlQueryModel (0x7f0a6e4d9ee0)
+ QAbstractItemModel (0x7f0a6e4e4000) 0
+ primary-for QAbstractTableModel (0x7f0a6e4d9f50)
+ QObject (0x7f0a6e4e4070) 0
+ primary-for QAbstractItemModel (0x7f0a6e4e4000)
+
+Vtable for QSqlTableModel
+QSqlTableModel::_ZTV14QSqlTableModel: 55u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QSqlTableModel)
+16 QSqlTableModel::metaObject
+24 QSqlTableModel::qt_metacast
+32 QSqlTableModel::qt_metacall
+40 QSqlTableModel::~QSqlTableModel
+48 QSqlTableModel::~QSqlTableModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 QSqlTableModel::rowCount
+136 QSqlQueryModel::columnCount
+144 QAbstractTableModel::hasChildren
+152 QSqlTableModel::data
+160 QSqlTableModel::setData
+168 QSqlTableModel::headerData
+176 QSqlQueryModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QSqlTableModel::insertRows
+240 QSqlQueryModel::insertColumns
+248 QSqlTableModel::removeRows
+256 QSqlTableModel::removeColumns
+264 QSqlQueryModel::fetchMore
+272 QSqlQueryModel::canFetchMore
+280 QSqlTableModel::flags
+288 QSqlTableModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QSqlTableModel::submit
+328 QSqlTableModel::revert
+336 QSqlTableModel::clear
+344 QSqlQueryModel::queryChange
+352 QSqlTableModel::select
+360 QSqlTableModel::setTable
+368 QSqlTableModel::setEditStrategy
+376 QSqlTableModel::setSort
+384 QSqlTableModel::setFilter
+392 QSqlTableModel::revertRow
+400 QSqlTableModel::updateRowInTable
+408 QSqlTableModel::insertRowIntoTable
+416 QSqlTableModel::deleteRowFromTable
+424 QSqlTableModel::orderByClause
+432 QSqlTableModel::selectStatement
+
+Class QSqlTableModel
+ size=16 align=8
+ base size=16 base align=8
+QSqlTableModel (0x7f0a6e501850) 0
+ vptr=((& QSqlTableModel::_ZTV14QSqlTableModel) + 16u)
+ QSqlQueryModel (0x7f0a6e5018c0) 0
+ primary-for QSqlTableModel (0x7f0a6e501850)
+ QAbstractTableModel (0x7f0a6e501930) 0
+ primary-for QSqlQueryModel (0x7f0a6e5018c0)
+ QAbstractItemModel (0x7f0a6e5019a0) 0
+ primary-for QAbstractTableModel (0x7f0a6e501930)
+ QObject (0x7f0a6e501a10) 0
+ primary-for QAbstractItemModel (0x7f0a6e5019a0)
+
+Class QSqlRelation
+ size=24 align=8
+ base size=24 base align=8
+QSqlRelation (0x7f0a6e52d380) 0
+
+Vtable for QSqlRelationalTableModel
+QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel: 57u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QSqlRelationalTableModel)
+16 QSqlRelationalTableModel::metaObject
+24 QSqlRelationalTableModel::qt_metacast
+32 QSqlRelationalTableModel::qt_metacall
+40 QSqlRelationalTableModel::~QSqlRelationalTableModel
+48 QSqlRelationalTableModel::~QSqlRelationalTableModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 QSqlTableModel::rowCount
+136 QSqlQueryModel::columnCount
+144 QAbstractTableModel::hasChildren
+152 QSqlRelationalTableModel::data
+160 QSqlRelationalTableModel::setData
+168 QSqlTableModel::headerData
+176 QSqlQueryModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QSqlTableModel::insertRows
+240 QSqlQueryModel::insertColumns
+248 QSqlTableModel::removeRows
+256 QSqlRelationalTableModel::removeColumns
+264 QSqlQueryModel::fetchMore
+272 QSqlQueryModel::canFetchMore
+280 QSqlTableModel::flags
+288 QSqlTableModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QSqlTableModel::submit
+328 QSqlTableModel::revert
+336 QSqlRelationalTableModel::clear
+344 QSqlQueryModel::queryChange
+352 QSqlRelationalTableModel::select
+360 QSqlRelationalTableModel::setTable
+368 QSqlTableModel::setEditStrategy
+376 QSqlTableModel::setSort
+384 QSqlTableModel::setFilter
+392 QSqlRelationalTableModel::revertRow
+400 QSqlRelationalTableModel::updateRowInTable
+408 QSqlRelationalTableModel::insertRowIntoTable
+416 QSqlTableModel::deleteRowFromTable
+424 QSqlRelationalTableModel::orderByClause
+432 QSqlRelationalTableModel::selectStatement
+440 QSqlRelationalTableModel::setRelation
+448 QSqlRelationalTableModel::relationModel
+
+Class QSqlRelationalTableModel
+ size=16 align=8
+ base size=16 base align=8
+QSqlRelationalTableModel (0x7f0a6e543cb0) 0
+ vptr=((& QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel) + 16u)
+ QSqlTableModel (0x7f0a6e543d20) 0
+ primary-for QSqlRelationalTableModel (0x7f0a6e543cb0)
+ QSqlQueryModel (0x7f0a6e543d90) 0
+ primary-for QSqlTableModel (0x7f0a6e543d20)
+ QAbstractTableModel (0x7f0a6e543e00) 0
+ primary-for QSqlQueryModel (0x7f0a6e543d90)
+ QAbstractItemModel (0x7f0a6e543e70) 0
+ primary-for QAbstractTableModel (0x7f0a6e543e00)
+ QObject (0x7f0a6e543ee0) 0
+ primary-for QAbstractItemModel (0x7f0a6e543e70)
+
+Class QDomImplementation
+ size=8 align=8
+ base size=8 base align=8
+QDomImplementation (0x7f0a6e563540) 0
+
+Class QDomNode
+ size=8 align=8
+ base size=8 base align=8
+QDomNode (0x7f0a6e563e70) 0
+
+Class QDomNodeList
+ size=8 align=8
+ base size=8 base align=8
+QDomNodeList (0x7f0a6e38f0e0) 0
+
+Class QDomDocumentType
+ size=8 align=8
+ base size=8 base align=8
+QDomDocumentType (0x7f0a6e398150) 0
+ QDomNode (0x7f0a6e3981c0) 0
+
+Class QDomDocument
+ size=8 align=8
+ base size=8 base align=8
+QDomDocument (0x7f0a6e398cb0) 0
+ QDomNode (0x7f0a6e398d20) 0
+
+Class QDomNamedNodeMap
+ size=8 align=8
+ base size=8 base align=8
+QDomNamedNodeMap (0x7f0a6e39ebd0) 0
+
+Class QDomDocumentFragment
+ size=8 align=8
+ base size=8 base align=8
+QDomDocumentFragment (0x7f0a6e3b0a10) 0
+ QDomNode (0x7f0a6e3b0a80) 0
+
+Class QDomCharacterData
+ size=8 align=8
+ base size=8 base align=8
+QDomCharacterData (0x7f0a6e3bd5b0) 0
+ QDomNode (0x7f0a6e3bd620) 0
+
+Class QDomAttr
+ size=8 align=8
+ base size=8 base align=8
+QDomAttr (0x7f0a6e3c5000) 0
+ QDomNode (0x7f0a6e3c5070) 0
+
+Class QDomElement
+ size=8 align=8
+ base size=8 base align=8
+QDomElement (0x7f0a6e3c5b60) 0
+ QDomNode (0x7f0a6e3c5bd0) 0
+
+Class QDomText
+ size=8 align=8
+ base size=8 base align=8
+QDomText (0x7f0a6e3cbe00) 0
+ QDomCharacterData (0x7f0a6e3cbe70) 0
+ QDomNode (0x7f0a6e3cbee0) 0
+
+Class QDomComment
+ size=8 align=8
+ base size=8 base align=8
+QDomComment (0x7f0a6e3e1b60) 0
+ QDomCharacterData (0x7f0a6e3e1bd0) 0
+ QDomNode (0x7f0a6e3e1c40) 0
+
+Class QDomCDATASection
+ size=8 align=8
+ base size=8 base align=8
+QDomCDATASection (0x7f0a6e3e7770) 0
+ QDomText (0x7f0a6e3e77e0) 0
+ QDomCharacterData (0x7f0a6e3e7850) 0
+ QDomNode (0x7f0a6e3e78c0) 0
+
+Class QDomNotation
+ size=8 align=8
+ base size=8 base align=8
+QDomNotation (0x7f0a6e3ed3f0) 0
+ QDomNode (0x7f0a6e3ed460) 0
+
+Class QDomEntity
+ size=8 align=8
+ base size=8 base align=8
+QDomEntity (0x7f0a6e3edf50) 0
+ QDomNode (0x7f0a6e3f3000) 0
+
+Class QDomEntityReference
+ size=8 align=8
+ base size=8 base align=8
+QDomEntityReference (0x7f0a6e3f3af0) 0
+ QDomNode (0x7f0a6e3f3b60) 0
+
+Class QDomProcessingInstruction
+ size=8 align=8
+ base size=8 base align=8
+QDomProcessingInstruction (0x7f0a6e3fa690) 0
+ QDomNode (0x7f0a6e3fa700) 0
+
+Class QXmlNamespaceSupport
+ size=8 align=8
+ base size=8 base align=8
+QXmlNamespaceSupport (0x7f0a6e400230) 0
+
+Class QXmlAttributes::Attribute
+ size=32 align=8
+ base size=32 base align=8
+QXmlAttributes::Attribute (0x7f0a6e4008c0) 0
+
+Vtable for QXmlAttributes
+QXmlAttributes::_ZTV14QXmlAttributes: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QXmlAttributes)
+16 QXmlAttributes::~QXmlAttributes
+24 QXmlAttributes::~QXmlAttributes
+
+Class QXmlAttributes
+ size=24 align=8
+ base size=24 base align=8
+QXmlAttributes (0x7f0a6e400770) 0
+ vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 16u)
+
+Vtable for QXmlInputSource
+QXmlInputSource::_ZTV15QXmlInputSource: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QXmlInputSource)
+16 QXmlInputSource::~QXmlInputSource
+24 QXmlInputSource::~QXmlInputSource
+32 QXmlInputSource::setData
+40 QXmlInputSource::setData
+48 QXmlInputSource::fetchData
+56 QXmlInputSource::data
+64 QXmlInputSource::next
+72 QXmlInputSource::reset
+80 QXmlInputSource::fromRawData
+
+Class QXmlInputSource
+ size=16 align=8
+ base size=16 base align=8
+QXmlInputSource (0x7f0a6e441000) 0
+ vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 16u)
+
+Class QXmlParseException
+ size=8 align=8
+ base size=8 base align=8
+QXmlParseException (0x7f0a6e441310) 0
+
+Vtable for QXmlReader
+QXmlReader::_ZTV10QXmlReader: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QXmlReader)
+16 QXmlReader::~QXmlReader
+24 QXmlReader::~QXmlReader
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+
+Class QXmlReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlReader (0x7f0a6e4415b0) 0 nearly-empty
+ vptr=((& QXmlReader::_ZTV10QXmlReader) + 16u)
+
+Vtable for QXmlSimpleReader
+QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QXmlSimpleReader)
+16 QXmlSimpleReader::~QXmlSimpleReader
+24 QXmlSimpleReader::~QXmlSimpleReader
+32 QXmlSimpleReader::feature
+40 QXmlSimpleReader::setFeature
+48 QXmlSimpleReader::hasFeature
+56 QXmlSimpleReader::property
+64 QXmlSimpleReader::setProperty
+72 QXmlSimpleReader::hasProperty
+80 QXmlSimpleReader::setEntityResolver
+88 QXmlSimpleReader::entityResolver
+96 QXmlSimpleReader::setDTDHandler
+104 QXmlSimpleReader::DTDHandler
+112 QXmlSimpleReader::setContentHandler
+120 QXmlSimpleReader::contentHandler
+128 QXmlSimpleReader::setErrorHandler
+136 QXmlSimpleReader::errorHandler
+144 QXmlSimpleReader::setLexicalHandler
+152 QXmlSimpleReader::lexicalHandler
+160 QXmlSimpleReader::setDeclHandler
+168 QXmlSimpleReader::declHandler
+176 QXmlSimpleReader::parse
+184 QXmlSimpleReader::parse
+192 QXmlSimpleReader::parse
+200 QXmlSimpleReader::parseContinue
+
+Class QXmlSimpleReader
+ size=16 align=8
+ base size=16 base align=8
+QXmlSimpleReader (0x7f0a6e4412a0) 0
+ vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 16u)
+ QXmlReader (0x7f0a6e441690) 0 nearly-empty
+ primary-for QXmlSimpleReader (0x7f0a6e4412a0)
+
+Vtable for QXmlLocator
+QXmlLocator::_ZTV11QXmlLocator: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QXmlLocator)
+16 QXmlLocator::~QXmlLocator
+24 QXmlLocator::~QXmlLocator
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QXmlLocator
+ size=8 align=8
+ base size=8 base align=8
+QXmlLocator (0x7f0a6e45ea10) 0 nearly-empty
+ vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 16u)
+
+Vtable for QXmlContentHandler
+QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlContentHandler)
+16 QXmlContentHandler::~QXmlContentHandler
+24 QXmlContentHandler::~QXmlContentHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+96 __cxa_pure_virtual
+104 __cxa_pure_virtual
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QXmlContentHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlContentHandler (0x7f0a6e45ec40) 0 nearly-empty
+ vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 16u)
+
+Vtable for QXmlErrorHandler
+QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QXmlErrorHandler)
+16 QXmlErrorHandler::~QXmlErrorHandler
+24 QXmlErrorHandler::~QXmlErrorHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+
+Class QXmlErrorHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlErrorHandler (0x7f0a6e478540) 0 nearly-empty
+ vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 16u)
+
+Vtable for QXmlDTDHandler
+QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QXmlDTDHandler)
+16 QXmlDTDHandler::~QXmlDTDHandler
+24 QXmlDTDHandler::~QXmlDTDHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+
+Class QXmlDTDHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlDTDHandler (0x7f0a6e478f50) 0 nearly-empty
+ vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 16u)
+
+Vtable for QXmlEntityResolver
+QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlEntityResolver)
+16 QXmlEntityResolver::~QXmlEntityResolver
+24 QXmlEntityResolver::~QXmlEntityResolver
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QXmlEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlEntityResolver (0x7f0a6e485930) 0 nearly-empty
+ vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 16u)
+
+Vtable for QXmlLexicalHandler
+QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlLexicalHandler)
+16 QXmlLexicalHandler::~QXmlLexicalHandler
+24 QXmlLexicalHandler::~QXmlLexicalHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+64 __cxa_pure_virtual
+72 __cxa_pure_virtual
+80 __cxa_pure_virtual
+88 __cxa_pure_virtual
+
+Class QXmlLexicalHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlLexicalHandler (0x7f0a6e293310) 0 nearly-empty
+ vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 16u)
+
+Vtable for QXmlDeclHandler
+QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QXmlDeclHandler)
+16 QXmlDeclHandler::~QXmlDeclHandler
+24 QXmlDeclHandler::~QXmlDeclHandler
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 __cxa_pure_virtual
+
+Class QXmlDeclHandler
+ size=8 align=8
+ base size=8 base align=8
+QXmlDeclHandler (0x7f0a6e293d20) 0 nearly-empty
+ vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 16u)
+
+Vtable for QXmlDefaultHandler
+QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+16 QXmlDefaultHandler::~QXmlDefaultHandler
+24 QXmlDefaultHandler::~QXmlDefaultHandler
+32 QXmlDefaultHandler::setDocumentLocator
+40 QXmlDefaultHandler::startDocument
+48 QXmlDefaultHandler::endDocument
+56 QXmlDefaultHandler::startPrefixMapping
+64 QXmlDefaultHandler::endPrefixMapping
+72 QXmlDefaultHandler::startElement
+80 QXmlDefaultHandler::endElement
+88 QXmlDefaultHandler::characters
+96 QXmlDefaultHandler::ignorableWhitespace
+104 QXmlDefaultHandler::processingInstruction
+112 QXmlDefaultHandler::skippedEntity
+120 QXmlDefaultHandler::errorString
+128 QXmlDefaultHandler::warning
+136 QXmlDefaultHandler::error
+144 QXmlDefaultHandler::fatalError
+152 QXmlDefaultHandler::notationDecl
+160 QXmlDefaultHandler::unparsedEntityDecl
+168 QXmlDefaultHandler::resolveEntity
+176 QXmlDefaultHandler::startDTD
+184 QXmlDefaultHandler::endDTD
+192 QXmlDefaultHandler::startEntity
+200 QXmlDefaultHandler::endEntity
+208 QXmlDefaultHandler::startCDATA
+216 QXmlDefaultHandler::endCDATA
+224 QXmlDefaultHandler::comment
+232 QXmlDefaultHandler::attributeDecl
+240 QXmlDefaultHandler::internalEntityDecl
+248 QXmlDefaultHandler::externalEntityDecl
+256 (int (*)(...))-0x00000000000000008
+264 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+272 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev
+280 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev
+288 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler7warningERK18QXmlParseException
+296 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler5errorERK18QXmlParseException
+304 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException
+312 QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv
+320 (int (*)(...))-0x00000000000000010
+328 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+336 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev
+344 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev
+352 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_
+360 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_
+368 QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv
+376 (int (*)(...))-0x00000000000000018
+384 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+392 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandlerD1Ev
+400 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandlerD0Ev
+408 QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource
+416 QXmlDefaultHandler::_ZThn24_NK18QXmlDefaultHandler11errorStringEv
+424 (int (*)(...))-0x00000000000000020
+432 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+440 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandlerD1Ev
+448 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandlerD0Ev
+456 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_
+464 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler6endDTDEv
+472 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler11startEntityERK7QString
+480 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler9endEntityERK7QString
+488 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler10startCDATAEv
+496 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler8endCDATAEv
+504 QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler7commentERK7QString
+512 QXmlDefaultHandler::_ZThn32_NK18QXmlDefaultHandler11errorStringEv
+520 (int (*)(...))-0x00000000000000028
+528 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+536 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandlerD1Ev
+544 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandlerD0Ev
+552 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_
+560 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_
+568 QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_
+576 QXmlDefaultHandler::_ZThn40_NK18QXmlDefaultHandler11errorStringEv
+
+Class QXmlDefaultHandler
+ size=56 align=8
+ base size=56 base align=8
+QXmlDefaultHandler (0x7f0a6e29f8c0) 0
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 16u)
+ QXmlContentHandler (0x7f0a6e2a2690) 0 nearly-empty
+ primary-for QXmlDefaultHandler (0x7f0a6e29f8c0)
+ QXmlErrorHandler (0x7f0a6e2a2700) 8 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 272u)
+ QXmlDTDHandler (0x7f0a6e2a2770) 16 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 336u)
+ QXmlEntityResolver (0x7f0a6e2a27e0) 24 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 392u)
+ QXmlLexicalHandler (0x7f0a6e2a2850) 32 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 440u)
+ QXmlDeclHandler (0x7f0a6e2a28c0) 40 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 536u)
+
+Class QSslCertificate
+ size=8 align=8
+ base size=8 base align=8
+QSslCertificate (0x7f0a6e2f6230) 0
+
+Class QSslError
+ size=8 align=8
+ base size=8 base align=8
+QSslError (0x7f0a6e30ccb0) 0
+
+Class QSslCipher
+ size=8 align=8
+ base size=8 base align=8
+QSslCipher (0x7f0a6e315a80) 0
+
+Vtable for QAbstractSocket
+QAbstractSocket::_ZTV15QAbstractSocket: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractSocket)
+16 QAbstractSocket::metaObject
+24 QAbstractSocket::qt_metacast
+32 QAbstractSocket::qt_metacall
+40 QAbstractSocket::~QAbstractSocket
+48 QAbstractSocket::~QAbstractSocket
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractSocket::isSequential
+120 QIODevice::open
+128 QAbstractSocket::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QAbstractSocket::atEnd
+168 QIODevice::reset
+176 QAbstractSocket::bytesAvailable
+184 QAbstractSocket::bytesToWrite
+192 QAbstractSocket::canReadLine
+200 QAbstractSocket::waitForReadyRead
+208 QAbstractSocket::waitForBytesWritten
+216 QAbstractSocket::readData
+224 QAbstractSocket::readLineData
+232 QAbstractSocket::writeData
+
+Class QAbstractSocket
+ size=16 align=8
+ base size=16 base align=8
+QAbstractSocket (0x7f0a6e3223f0) 0
+ vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16u)
+ QIODevice (0x7f0a6e322460) 0
+ primary-for QAbstractSocket (0x7f0a6e3223f0)
+ QObject (0x7f0a6e3224d0) 0
+ primary-for QIODevice (0x7f0a6e322460)
+
+Vtable for QTcpSocket
+QTcpSocket::_ZTV10QTcpSocket: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTcpSocket)
+16 QTcpSocket::metaObject
+24 QTcpSocket::qt_metacast
+32 QTcpSocket::qt_metacall
+40 QTcpSocket::~QTcpSocket
+48 QTcpSocket::~QTcpSocket
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractSocket::isSequential
+120 QIODevice::open
+128 QAbstractSocket::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QAbstractSocket::atEnd
+168 QIODevice::reset
+176 QAbstractSocket::bytesAvailable
+184 QAbstractSocket::bytesToWrite
+192 QAbstractSocket::canReadLine
+200 QAbstractSocket::waitForReadyRead
+208 QAbstractSocket::waitForBytesWritten
+216 QAbstractSocket::readData
+224 QAbstractSocket::readLineData
+232 QAbstractSocket::writeData
+
+Class QTcpSocket
+ size=16 align=8
+ base size=16 base align=8
+QTcpSocket (0x7f0a6e35da80) 0
+ vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16u)
+ QAbstractSocket (0x7f0a6e35daf0) 0
+ primary-for QTcpSocket (0x7f0a6e35da80)
+ QIODevice (0x7f0a6e35db60) 0
+ primary-for QAbstractSocket (0x7f0a6e35daf0)
+ QObject (0x7f0a6e35dbd0) 0
+ primary-for QIODevice (0x7f0a6e35db60)
+
+Vtable for QSslSocket
+QSslSocket::_ZTV10QSslSocket: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSslSocket)
+16 QSslSocket::metaObject
+24 QSslSocket::qt_metacast
+32 QSslSocket::qt_metacall
+40 QSslSocket::~QSslSocket
+48 QSslSocket::~QSslSocket
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractSocket::isSequential
+120 QIODevice::open
+128 QSslSocket::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QSslSocket::atEnd
+168 QIODevice::reset
+176 QSslSocket::bytesAvailable
+184 QSslSocket::bytesToWrite
+192 QSslSocket::canReadLine
+200 QSslSocket::waitForReadyRead
+208 QSslSocket::waitForBytesWritten
+216 QSslSocket::readData
+224 QAbstractSocket::readLineData
+232 QSslSocket::writeData
+
+Class QSslSocket
+ size=16 align=8
+ base size=16 base align=8
+QSslSocket (0x7f0a6e37b540) 0
+ vptr=((& QSslSocket::_ZTV10QSslSocket) + 16u)
+ QTcpSocket (0x7f0a6e37b5b0) 0
+ primary-for QSslSocket (0x7f0a6e37b540)
+ QAbstractSocket (0x7f0a6e37b620) 0
+ primary-for QTcpSocket (0x7f0a6e37b5b0)
+ QIODevice (0x7f0a6e37b690) 0
+ primary-for QAbstractSocket (0x7f0a6e37b620)
+ QObject (0x7f0a6e37b700) 0
+ primary-for QIODevice (0x7f0a6e37b690)
+
+Class QSslConfiguration
+ size=8 align=8
+ base size=8 base align=8
+QSslConfiguration (0x7f0a6e1b12a0) 0
+
+Class QSslKey
+ size=8 align=8
+ base size=8 base align=8
+QSslKey (0x7f0a6e1cb000) 0
+
+Vtable for QHttpHeader
+QHttpHeader::_ZTV11QHttpHeader: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHttpHeader)
+16 QHttpHeader::~QHttpHeader
+24 QHttpHeader::~QHttpHeader
+32 QHttpHeader::toString
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QHttpHeader::parseLine
+
+Class QHttpHeader
+ size=16 align=8
+ base size=16 base align=8
+QHttpHeader (0x7f0a6e1cbb60) 0
+ vptr=((& QHttpHeader::_ZTV11QHttpHeader) + 16u)
+
+Vtable for QHttpResponseHeader
+QHttpResponseHeader::_ZTV19QHttpResponseHeader: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QHttpResponseHeader)
+16 QHttpResponseHeader::~QHttpResponseHeader
+24 QHttpResponseHeader::~QHttpResponseHeader
+32 QHttpResponseHeader::toString
+40 QHttpResponseHeader::majorVersion
+48 QHttpResponseHeader::minorVersion
+56 QHttpResponseHeader::parseLine
+
+Class QHttpResponseHeader
+ size=16 align=8
+ base size=16 base align=8
+QHttpResponseHeader (0x7f0a6e1da850) 0
+ vptr=((& QHttpResponseHeader::_ZTV19QHttpResponseHeader) + 16u)
+ QHttpHeader (0x7f0a6e1da8c0) 0
+ primary-for QHttpResponseHeader (0x7f0a6e1da850)
+
+Vtable for QHttpRequestHeader
+QHttpRequestHeader::_ZTV18QHttpRequestHeader: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QHttpRequestHeader)
+16 QHttpRequestHeader::~QHttpRequestHeader
+24 QHttpRequestHeader::~QHttpRequestHeader
+32 QHttpRequestHeader::toString
+40 QHttpRequestHeader::majorVersion
+48 QHttpRequestHeader::minorVersion
+56 QHttpRequestHeader::parseLine
+
+Class QHttpRequestHeader
+ size=16 align=8
+ base size=16 base align=8
+QHttpRequestHeader (0x7f0a6e1f24d0) 0
+ vptr=((& QHttpRequestHeader::_ZTV18QHttpRequestHeader) + 16u)
+ QHttpHeader (0x7f0a6e1f2540) 0
+ primary-for QHttpRequestHeader (0x7f0a6e1f24d0)
+
+Vtable for QHttp
+QHttp::_ZTV5QHttp: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QHttp)
+16 QHttp::metaObject
+24 QHttp::qt_metacast
+32 QHttp::qt_metacall
+40 QHttp::~QHttp
+48 QHttp::~QHttp
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QHttp
+ size=16 align=8
+ base size=16 base align=8
+QHttp (0x7f0a6e1fe0e0) 0
+ vptr=((& QHttp::_ZTV5QHttp) + 16u)
+ QObject (0x7f0a6e1fe150) 0
+ primary-for QHttp (0x7f0a6e1fe0e0)
+
+Class QNetworkRequest
+ size=8 align=8
+ base size=8 base align=8
+QNetworkRequest (0x7f0a6e22c310) 0
+
+Vtable for QNetworkAccessManager
+QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QNetworkAccessManager)
+16 QNetworkAccessManager::metaObject
+24 QNetworkAccessManager::qt_metacast
+32 QNetworkAccessManager::qt_metacall
+40 QNetworkAccessManager::~QNetworkAccessManager
+48 QNetworkAccessManager::~QNetworkAccessManager
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QNetworkAccessManager::createRequest
+
+Class QNetworkAccessManager
+ size=16 align=8
+ base size=16 base align=8
+QNetworkAccessManager (0x7f0a6e249230) 0
+ vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16u)
+ QObject (0x7f0a6e2492a0) 0
+ primary-for QNetworkAccessManager (0x7f0a6e249230)
+
+Class QNetworkCookie
+ size=8 align=8
+ base size=8 base align=8
+QNetworkCookie (0x7f0a6e263770) 0
+
+Vtable for QNetworkCookieJar
+QNetworkCookieJar::_ZTV17QNetworkCookieJar: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QNetworkCookieJar)
+16 QNetworkCookieJar::metaObject
+24 QNetworkCookieJar::qt_metacast
+32 QNetworkCookieJar::qt_metacall
+40 QNetworkCookieJar::~QNetworkCookieJar
+48 QNetworkCookieJar::~QNetworkCookieJar
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QNetworkCookieJar::cookiesForUrl
+120 QNetworkCookieJar::setCookiesFromUrl
+
+Class QNetworkCookieJar
+ size=16 align=8
+ base size=16 base align=8
+QNetworkCookieJar (0x7f0a6e2708c0) 0
+ vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16u)
+ QObject (0x7f0a6e270930) 0
+ primary-for QNetworkCookieJar (0x7f0a6e2708c0)
+
+Vtable for QNetworkReply
+QNetworkReply::_ZTV13QNetworkReply: 33u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QNetworkReply)
+16 QNetworkReply::metaObject
+24 QNetworkReply::qt_metacast
+32 QNetworkReply::qt_metacall
+40 QNetworkReply::~QNetworkReply
+48 QNetworkReply::~QNetworkReply
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QNetworkReply::isSequential
+120 QIODevice::open
+128 QNetworkReply::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QIODevice::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 __cxa_pure_virtual
+224 QIODevice::readLineData
+232 QNetworkReply::writeData
+240 __cxa_pure_virtual
+248 QNetworkReply::setReadBufferSize
+256 QNetworkReply::ignoreSslErrors
+
+Class QNetworkReply
+ size=16 align=8
+ base size=16 base align=8
+QNetworkReply (0x7f0a6e016770) 0
+ vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16u)
+ QIODevice (0x7f0a6e0167e0) 0
+ primary-for QNetworkReply (0x7f0a6e016770)
+ QObject (0x7f0a6e016850) 0
+ primary-for QIODevice (0x7f0a6e0167e0)
+
+Vtable for QUrlInfo
+QUrlInfo::_ZTV8QUrlInfo: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QUrlInfo)
+16 QUrlInfo::~QUrlInfo
+24 QUrlInfo::~QUrlInfo
+32 QUrlInfo::setName
+40 QUrlInfo::setDir
+48 QUrlInfo::setFile
+56 QUrlInfo::setSymLink
+64 QUrlInfo::setOwner
+72 QUrlInfo::setGroup
+80 QUrlInfo::setSize
+88 QUrlInfo::setWritable
+96 QUrlInfo::setReadable
+104 QUrlInfo::setPermissions
+112 QUrlInfo::setLastModified
+
+Class QUrlInfo
+ size=16 align=8
+ base size=16 base align=8
+QUrlInfo (0x7f0a6e0433f0) 0
+ vptr=((& QUrlInfo::_ZTV8QUrlInfo) + 16u)
+
+Vtable for QFtp
+QFtp::_ZTV4QFtp: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI4QFtp)
+16 QFtp::metaObject
+24 QFtp::qt_metacast
+32 QFtp::qt_metacall
+40 QFtp::~QFtp
+48 QFtp::~QFtp
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QFtp
+ size=16 align=8
+ base size=16 base align=8
+QFtp (0x7f0a6e053380) 0
+ vptr=((& QFtp::_ZTV4QFtp) + 16u)
+ QObject (0x7f0a6e0533f0) 0
+ primary-for QFtp (0x7f0a6e053380)
+
+Class QNetworkCacheMetaData
+ size=8 align=8
+ base size=8 base align=8
+QNetworkCacheMetaData (0x7f0a6e0849a0) 0
+
+Vtable for QAbstractNetworkCache
+QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QAbstractNetworkCache)
+16 QAbstractNetworkCache::metaObject
+24 QAbstractNetworkCache::qt_metacast
+32 QAbstractNetworkCache::qt_metacall
+40 QAbstractNetworkCache::~QAbstractNetworkCache
+48 QAbstractNetworkCache::~QAbstractNetworkCache
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+
+Class QAbstractNetworkCache
+ size=16 align=8
+ base size=16 base align=8
+QAbstractNetworkCache (0x7f0a6e08ccb0) 0
+ vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16u)
+ QObject (0x7f0a6e08cd20) 0
+ primary-for QAbstractNetworkCache (0x7f0a6e08ccb0)
+
+Vtable for QNetworkDiskCache
+QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QNetworkDiskCache)
+16 QNetworkDiskCache::metaObject
+24 QNetworkDiskCache::qt_metacast
+32 QNetworkDiskCache::qt_metacall
+40 QNetworkDiskCache::~QNetworkDiskCache
+48 QNetworkDiskCache::~QNetworkDiskCache
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QNetworkDiskCache::metaData
+120 QNetworkDiskCache::updateMetaData
+128 QNetworkDiskCache::data
+136 QNetworkDiskCache::remove
+144 QNetworkDiskCache::cacheSize
+152 QNetworkDiskCache::prepare
+160 QNetworkDiskCache::insert
+168 QNetworkDiskCache::clear
+176 QNetworkDiskCache::expire
+
+Class QNetworkDiskCache
+ size=16 align=8
+ base size=16 base align=8
+QNetworkDiskCache (0x7f0a6e0b5620) 0
+ vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16u)
+ QAbstractNetworkCache (0x7f0a6e0b5690) 0
+ primary-for QNetworkDiskCache (0x7f0a6e0b5620)
+ QObject (0x7f0a6e0b5700) 0
+ primary-for QAbstractNetworkCache (0x7f0a6e0b5690)
+
+Class QIPv6Address
+ size=16 align=1
+ base size=16 base align=1
+QIPv6Address (0x7f0a6e0c5f50) 0
+
+Class QHostAddress
+ size=8 align=8
+ base size=8 base align=8
+QHostAddress (0x7f0a6e0cd5b0) 0
+
+Class QNetworkAddressEntry
+ size=8 align=8
+ base size=8 base align=8
+QNetworkAddressEntry (0x7f0a6e0f4540) 0
+
+Class QNetworkInterface
+ size=8 align=8
+ base size=8 base align=8
+QNetworkInterface (0x7f0a6e0f4d90) 0
+
+Class QAuthenticator
+ size=8 align=8
+ base size=8 base align=8
+QAuthenticator (0x7f0a6df37af0) 0
+
+Class QHostInfo
+ size=8 align=8
+ base size=8 base align=8
+QHostInfo (0x7f0a6df483f0) 0
+
+Class QNetworkProxyQuery
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxyQuery (0x7f0a6df48c40) 0
+
+Class QNetworkProxy
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxy (0x7f0a6df5af50) 0
+
+Vtable for QNetworkProxyFactory
+QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QNetworkProxyFactory)
+16 QNetworkProxyFactory::~QNetworkProxyFactory
+24 QNetworkProxyFactory::~QNetworkProxyFactory
+32 __cxa_pure_virtual
+
+Class QNetworkProxyFactory
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxyFactory (0x7f0a6dfba380) 0 nearly-empty
+ vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16u)
+
+Vtable for QLocalServer
+QLocalServer::_ZTV12QLocalServer: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QLocalServer)
+16 QLocalServer::metaObject
+24 QLocalServer::qt_metacast
+32 QLocalServer::qt_metacall
+40 QLocalServer::~QLocalServer
+48 QLocalServer::~QLocalServer
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QLocalServer::hasPendingConnections
+120 QLocalServer::nextPendingConnection
+128 QLocalServer::incomingConnection
+
+Class QLocalServer
+ size=16 align=8
+ base size=16 base align=8
+QLocalServer (0x7f0a6dfba690) 0
+ vptr=((& QLocalServer::_ZTV12QLocalServer) + 16u)
+ QObject (0x7f0a6dfba700) 0
+ primary-for QLocalServer (0x7f0a6dfba690)
+
+Vtable for QLocalSocket
+QLocalSocket::_ZTV12QLocalSocket: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QLocalSocket)
+16 QLocalSocket::metaObject
+24 QLocalSocket::qt_metacast
+32 QLocalSocket::qt_metacall
+40 QLocalSocket::~QLocalSocket
+48 QLocalSocket::~QLocalSocket
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QLocalSocket::isSequential
+120 QIODevice::open
+128 QLocalSocket::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QIODevice::atEnd
+168 QIODevice::reset
+176 QLocalSocket::bytesAvailable
+184 QLocalSocket::bytesToWrite
+192 QLocalSocket::canReadLine
+200 QLocalSocket::waitForReadyRead
+208 QLocalSocket::waitForBytesWritten
+216 QLocalSocket::readData
+224 QIODevice::readLineData
+232 QLocalSocket::writeData
+
+Class QLocalSocket
+ size=16 align=8
+ base size=16 base align=8
+QLocalSocket (0x7f0a6dfd9070) 0
+ vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16u)
+ QIODevice (0x7f0a6dfd90e0) 0
+ primary-for QLocalSocket (0x7f0a6dfd9070)
+ QObject (0x7f0a6dfd9150) 0
+ primary-for QIODevice (0x7f0a6dfd90e0)
+
+Vtable for QTcpServer
+QTcpServer::_ZTV10QTcpServer: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTcpServer)
+16 QTcpServer::metaObject
+24 QTcpServer::qt_metacast
+32 QTcpServer::qt_metacall
+40 QTcpServer::~QTcpServer
+48 QTcpServer::~QTcpServer
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTcpServer::hasPendingConnections
+120 QTcpServer::nextPendingConnection
+128 QTcpServer::incomingConnection
+
+Class QTcpServer
+ size=16 align=8
+ base size=16 base align=8
+QTcpServer (0x7f0a6dffc230) 0
+ vptr=((& QTcpServer::_ZTV10QTcpServer) + 16u)
+ QObject (0x7f0a6dffc2a0) 0
+ primary-for QTcpServer (0x7f0a6dffc230)
+
+Vtable for QUdpSocket
+QUdpSocket::_ZTV10QUdpSocket: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QUdpSocket)
+16 QUdpSocket::metaObject
+24 QUdpSocket::qt_metacast
+32 QUdpSocket::qt_metacall
+40 QUdpSocket::~QUdpSocket
+48 QUdpSocket::~QUdpSocket
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractSocket::isSequential
+120 QIODevice::open
+128 QAbstractSocket::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QAbstractSocket::atEnd
+168 QIODevice::reset
+176 QAbstractSocket::bytesAvailable
+184 QAbstractSocket::bytesToWrite
+192 QAbstractSocket::canReadLine
+200 QAbstractSocket::waitForReadyRead
+208 QAbstractSocket::waitForBytesWritten
+216 QAbstractSocket::readData
+224 QAbstractSocket::readLineData
+232 QAbstractSocket::writeData
+
+Class QUdpSocket
+ size=16 align=8
+ base size=16 base align=8
+QUdpSocket (0x7f0a6de10d20) 0
+ vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16u)
+ QAbstractSocket (0x7f0a6de10d90) 0
+ primary-for QUdpSocket (0x7f0a6de10d20)
+ QIODevice (0x7f0a6de10e00) 0
+ primary-for QAbstractSocket (0x7f0a6de10d90)
+ QObject (0x7f0a6de10e70) 0
+ primary-for QIODevice (0x7f0a6de10e00)
+
+Class QFont
+ size=16 align=8
+ base size=12 base align=8
+QFont (0x7f0a6de4fa80) 0
+
+Vtable for QAbstractUndoItem
+QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAbstractUndoItem)
+16 __cxa_pure_virtual
+24 __cxa_pure_virtual
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QAbstractUndoItem
+ size=8 align=8
+ base size=8 base align=8
+QAbstractUndoItem (0x7f0a6de9a700) 0 nearly-empty
+ vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u)
+
+Vtable for QTextDocument
+QTextDocument::_ZTV13QTextDocument: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QTextDocument)
+16 QTextDocument::metaObject
+24 QTextDocument::qt_metacast
+32 QTextDocument::qt_metacall
+40 QTextDocument::~QTextDocument
+48 QTextDocument::~QTextDocument
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTextDocument::clear
+120 QTextDocument::createObject
+128 QTextDocument::loadResource
+
+Class QTextDocument
+ size=16 align=8
+ base size=16 base align=8
+QTextDocument (0x7f0a6deab150) 0
+ vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u)
+ QObject (0x7f0a6deab1c0) 0
+ primary-for QTextDocument (0x7f0a6deab150)
+
+Class QHelpGlobal
+ size=1 align=1
+ base size=0 base align=1
+QHelpGlobal (0x7f0a6dd0a150) 0 empty
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintDevice)
+16 QPaintDevice::~QPaintDevice
+24 QPaintDevice::~QPaintDevice
+32 QPaintDevice::devType
+40 __cxa_pure_virtual
+48 QPaintDevice::metric
+
+Class QPaintDevice
+ size=16 align=8
+ base size=10 base align=8
+QPaintDevice (0x7f0a6dd31620) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0x7f0a6dd619a0) 0
+
+Class QPolygon
+ size=8 align=8
+ base size=8 base align=8
+QPolygon (0x7f0a6ddaed90) 0
+ QVector<QPoint> (0x7f0a6ddaee00) 0
+
+Class QPolygonF
+ size=8 align=8
+ base size=8 base align=8
+QPolygonF (0x7f0a6ddf4ee0) 0
+ QVector<QPointF> (0x7f0a6ddf4f50) 0
+
+Class QRegion::QRegionData
+ size=32 align=8
+ base size=32 base align=8
+QRegion::QRegionData (0x7f0a6dc553f0) 0
+
+Class QRegion
+ size=8 align=8
+ base size=8 base align=8
+QRegion (0x7f0a6dc34b60) 0
+
+Class QMatrix
+ size=48 align=8
+ base size=48 base align=8
+QMatrix (0x7f0a6dc6acb0) 0
+
+Class QPainterPath::Element
+ size=24 align=8
+ base size=24 base align=8
+QPainterPath::Element (0x7f0a6dca0700) 0
+
+Class QPainterPath
+ size=8 align=8
+ base size=8 base align=8
+QPainterPath (0x7f0a6dca0690) 0
+
+Class QPainterPathPrivate
+ size=16 align=8
+ base size=16 base align=8
+QPainterPathPrivate (0x7f0a6dce5a80) 0
+
+Class QPainterPathStroker
+ size=8 align=8
+ base size=8 base align=8
+QPainterPathStroker (0x7f0a6dcec620) 0
+
+Class QTransform
+ size=88 align=8
+ base size=88 base align=8
+QTransform (0x7f0a6db531c0) 0
+
+Class QImageTextKeyLang
+ size=16 align=8
+ base size=16 base align=8
+QImageTextKeyLang (0x7f0a6dbcc4d0) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QImage)
+16 QImage::~QImage
+24 QImage::~QImage
+32 QImage::devType
+40 QImage::paintEngine
+48 QImage::metric
+
+Class QImage
+ size=24 align=8
+ base size=24 base align=8
+QImage (0x7f0a6dbf2d20) 0
+ vptr=((& QImage::_ZTV6QImage) + 16u)
+ QPaintDevice (0x7f0a6dbf2d90) 0
+ primary-for QImage (0x7f0a6dbf2d20)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QPixmap)
+16 QPixmap::~QPixmap
+24 QPixmap::~QPixmap
+32 QPixmap::devType
+40 QPixmap::paintEngine
+48 QPixmap::metric
+
+Class QPixmap
+ size=24 align=8
+ base size=24 base align=8
+QPixmap (0x7f0a6da93770) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 16u)
+ QPaintDevice (0x7f0a6da937e0) 0
+ primary-for QPixmap (0x7f0a6da93770)
+
+Class QBrush
+ size=8 align=8
+ base size=8 base align=8
+QBrush (0x7f0a6dae8930) 0
+
+Class QBrushData
+ size=112 align=8
+ base size=112 base align=8
+QBrushData (0x7f0a6d90c540) 0
+
+Class QGradient
+ size=64 align=8
+ base size=64 base align=8
+QGradient (0x7f0a6d914700) 0
+
+Class QLinearGradient
+ size=64 align=8
+ base size=64 base align=8
+QLinearGradient (0x7f0a6d9551c0) 0
+ QGradient (0x7f0a6d955230) 0
+
+Class QRadialGradient
+ size=64 align=8
+ base size=64 base align=8
+QRadialGradient (0x7f0a6d955690) 0
+ QGradient (0x7f0a6d955700) 0
+
+Class QConicalGradient
+ size=64 align=8
+ base size=64 base align=8
+QConicalGradient (0x7f0a6d955c40) 0
+ QGradient (0x7f0a6d955cb0) 0
+
+Class QPalette
+ size=16 align=8
+ base size=12 base align=8
+QPalette (0x7f0a6d96d000) 0
+
+Class QColorGroup
+ size=16 align=8
+ base size=12 base align=8
+QColorGroup (0x7f0a6d9b4930) 0
+ QPalette (0x7f0a6d9b49a0) 0
+
+Class QFontMetrics
+ size=8 align=8
+ base size=8 base align=8
+QFontMetrics (0x7f0a6d9eec40) 0
+
+Class QFontMetricsF
+ size=8 align=8
+ base size=8 base align=8
+QFontMetricsF (0x7f0a6d80f0e0) 0
+
+Class QFontInfo
+ size=8 align=8
+ base size=8 base align=8
+QFontInfo (0x7f0a6d821000) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0x7f0a6d821af0) 0
+
+Class QCursor
+ size=8 align=8
+ base size=8 base align=8
+QCursor (0x7f0a6d8fb850) 0
+
+Class QKeySequence
+ size=8 align=8
+ base size=8 base align=8
+QKeySequence (0x7f0a6d709070) 0
+
+Class QWidgetData
+ size=88 align=8
+ base size=88 base align=8
+QWidgetData (0x7f0a6d735c40) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWidget)
+16 QWidget::metaObject
+24 QWidget::qt_metacast
+32 QWidget::qt_metacall
+40 QWidget::~QWidget
+48 QWidget::~QWidget
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI7QWidget)
+464 QWidget::_ZThn16_N7QWidgetD1Ev
+472 QWidget::_ZThn16_N7QWidgetD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=40 align=8
+ base size=40 base align=8
+QWidget (0x7f0a6d74a180) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 16u)
+ QObject (0x7f0a6d735cb0) 0
+ primary-for QWidget (0x7f0a6d74a180)
+ QPaintDevice (0x7f0a6d735d20) 16
+ vptr=((& QWidget::_ZTV7QWidget) + 464u)
+
+Vtable for QFrame
+QFrame::_ZTV6QFrame: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QFrame)
+16 QFrame::metaObject
+24 QFrame::qt_metacast
+32 QFrame::qt_metacall
+40 QFrame::~QFrame
+48 QFrame::~QFrame
+56 QFrame::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QFrame::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QFrame::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI6QFrame)
+464 QFrame::_ZThn16_N6QFrameD1Ev
+472 QFrame::_ZThn16_N6QFrameD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QFrame
+ size=40 align=8
+ base size=40 base align=8
+QFrame (0x7f0a6d6c0a80) 0
+ vptr=((& QFrame::_ZTV6QFrame) + 16u)
+ QWidget (0x7f0a6d6bdb80) 0
+ primary-for QFrame (0x7f0a6d6c0a80)
+ QObject (0x7f0a6d6c0af0) 0
+ primary-for QWidget (0x7f0a6d6bdb80)
+ QPaintDevice (0x7f0a6d6c0b60) 16
+ vptr=((& QFrame::_ZTV6QFrame) + 464u)
+
+Vtable for QAbstractScrollArea
+QAbstractScrollArea::_ZTV19QAbstractScrollArea: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+16 QAbstractScrollArea::metaObject
+24 QAbstractScrollArea::qt_metacast
+32 QAbstractScrollArea::qt_metacall
+40 QAbstractScrollArea::~QAbstractScrollArea
+48 QAbstractScrollArea::~QAbstractScrollArea
+56 QAbstractScrollArea::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractScrollArea::mousePressEvent
+168 QAbstractScrollArea::mouseReleaseEvent
+176 QAbstractScrollArea::mouseDoubleClickEvent
+184 QAbstractScrollArea::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QAbstractScrollArea::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QAbstractScrollArea::paintEvent
+256 QWidget::moveEvent
+264 QAbstractScrollArea::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractScrollArea::dragEnterEvent
+312 QAbstractScrollArea::dragMoveEvent
+320 QAbstractScrollArea::dragLeaveEvent
+328 QAbstractScrollArea::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractScrollArea::viewportEvent
+456 QAbstractScrollArea::scrollContentsBy
+464 (int (*)(...))-0x00000000000000010
+472 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+480 QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD1Ev
+488 QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD0Ev
+496 QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractScrollArea
+ size=40 align=8
+ base size=40 base align=8
+QAbstractScrollArea (0x7f0a6d6ed0e0) 0
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 16u)
+ QFrame (0x7f0a6d6ed150) 0
+ primary-for QAbstractScrollArea (0x7f0a6d6ed0e0)
+ QWidget (0x7f0a6d6cde80) 0
+ primary-for QFrame (0x7f0a6d6ed150)
+ QObject (0x7f0a6d6ed1c0) 0
+ primary-for QWidget (0x7f0a6d6cde80)
+ QPaintDevice (0x7f0a6d6ed230) 16
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 480u)
+
+Class QItemSelectionRange
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionRange (0x7f0a6d500000) 0
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QItemSelectionModel)
+16 QItemSelectionModel::metaObject
+24 QItemSelectionModel::qt_metacast
+32 QItemSelectionModel::qt_metacall
+40 QItemSelectionModel::~QItemSelectionModel
+48 QItemSelectionModel::~QItemSelectionModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QItemSelectionModel::select
+120 QItemSelectionModel::select
+128 QItemSelectionModel::clear
+136 QItemSelectionModel::reset
+
+Class QItemSelectionModel
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionModel (0x7f0a6d5674d0) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u)
+ QObject (0x7f0a6d567540) 0
+ primary-for QItemSelectionModel (0x7f0a6d5674d0)
+
+Class QItemSelection
+ size=8 align=8
+ base size=8 base align=8
+QItemSelection (0x7f0a6d5a59a0) 0
+ QList<QItemSelectionRange> (0x7f0a6d5a5a10) 0
+
+Vtable for QValidator
+QValidator::_ZTV10QValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QValidator)
+16 QValidator::metaObject
+24 QValidator::qt_metacast
+32 QValidator::qt_metacall
+40 QValidator::~QValidator
+48 QValidator::~QValidator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 QValidator::fixup
+
+Class QValidator
+ size=16 align=8
+ base size=16 base align=8
+QValidator (0x7f0a6d5e52a0) 0
+ vptr=((& QValidator::_ZTV10QValidator) + 16u)
+ QObject (0x7f0a6d5e5310) 0
+ primary-for QValidator (0x7f0a6d5e52a0)
+
+Vtable for QIntValidator
+QIntValidator::_ZTV13QIntValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QIntValidator)
+16 QIntValidator::metaObject
+24 QIntValidator::qt_metacast
+32 QIntValidator::qt_metacall
+40 QIntValidator::~QIntValidator
+48 QIntValidator::~QIntValidator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QIntValidator::validate
+120 QValidator::fixup
+128 QIntValidator::setRange
+
+Class QIntValidator
+ size=24 align=8
+ base size=24 base align=8
+QIntValidator (0x7f0a6d3fe0e0) 0
+ vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u)
+ QValidator (0x7f0a6d3fe150) 0
+ primary-for QIntValidator (0x7f0a6d3fe0e0)
+ QObject (0x7f0a6d3fe1c0) 0
+ primary-for QValidator (0x7f0a6d3fe150)
+
+Vtable for QDoubleValidator
+QDoubleValidator::_ZTV16QDoubleValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QDoubleValidator)
+16 QDoubleValidator::metaObject
+24 QDoubleValidator::qt_metacast
+32 QDoubleValidator::qt_metacall
+40 QDoubleValidator::~QDoubleValidator
+48 QDoubleValidator::~QDoubleValidator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QDoubleValidator::validate
+120 QValidator::fixup
+128 QDoubleValidator::setRange
+
+Class QDoubleValidator
+ size=40 align=8
+ base size=36 base align=8
+QDoubleValidator (0x7f0a6d416070) 0
+ vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u)
+ QValidator (0x7f0a6d4160e0) 0
+ primary-for QDoubleValidator (0x7f0a6d416070)
+ QObject (0x7f0a6d416150) 0
+ primary-for QValidator (0x7f0a6d4160e0)
+
+Vtable for QRegExpValidator
+QRegExpValidator::_ZTV16QRegExpValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QRegExpValidator)
+16 QRegExpValidator::metaObject
+24 QRegExpValidator::qt_metacast
+32 QRegExpValidator::qt_metacall
+40 QRegExpValidator::~QRegExpValidator
+48 QRegExpValidator::~QRegExpValidator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QRegExpValidator::validate
+120 QValidator::fixup
+
+Class QRegExpValidator
+ size=24 align=8
+ base size=24 base align=8
+QRegExpValidator (0x7f0a6d431930) 0
+ vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u)
+ QValidator (0x7f0a6d4319a0) 0
+ primary-for QRegExpValidator (0x7f0a6d431930)
+ QObject (0x7f0a6d431a10) 0
+ primary-for QValidator (0x7f0a6d4319a0)
+
+Vtable for QAbstractSpinBox
+QAbstractSpinBox::_ZTV16QAbstractSpinBox: 68u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+16 QAbstractSpinBox::metaObject
+24 QAbstractSpinBox::qt_metacast
+32 QAbstractSpinBox::qt_metacall
+40 QAbstractSpinBox::~QAbstractSpinBox
+48 QAbstractSpinBox::~QAbstractSpinBox
+56 QAbstractSpinBox::event
+64 QObject::eventFilter
+72 QAbstractSpinBox::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractSpinBox::sizeHint
+136 QAbstractSpinBox::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractSpinBox::mousePressEvent
+168 QAbstractSpinBox::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QAbstractSpinBox::mouseMoveEvent
+192 QAbstractSpinBox::wheelEvent
+200 QAbstractSpinBox::keyPressEvent
+208 QAbstractSpinBox::keyReleaseEvent
+216 QAbstractSpinBox::focusInEvent
+224 QAbstractSpinBox::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QAbstractSpinBox::paintEvent
+256 QWidget::moveEvent
+264 QAbstractSpinBox::resizeEvent
+272 QAbstractSpinBox::closeEvent
+280 QAbstractSpinBox::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QAbstractSpinBox::showEvent
+344 QAbstractSpinBox::hideEvent
+352 QWidget::x11Event
+360 QAbstractSpinBox::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractSpinBox::validate
+456 QAbstractSpinBox::fixup
+464 QAbstractSpinBox::stepBy
+472 QAbstractSpinBox::clear
+480 QAbstractSpinBox::stepEnabled
+488 (int (*)(...))-0x00000000000000010
+496 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+504 QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD1Ev
+512 QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD0Ev
+520 QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSpinBox
+ size=40 align=8
+ base size=40 base align=8
+QAbstractSpinBox (0x7f0a6d4465b0) 0
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 16u)
+ QWidget (0x7f0a6d42ce80) 0
+ primary-for QAbstractSpinBox (0x7f0a6d4465b0)
+ QObject (0x7f0a6d446620) 0
+ primary-for QWidget (0x7f0a6d42ce80)
+ QPaintDevice (0x7f0a6d446690) 16
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 504u)
+
+Class QIcon
+ size=8 align=8
+ base size=8 base align=8
+QIcon (0x7f0a6d4a35b0) 0
+
+Vtable for QAbstractSlider
+QAbstractSlider::_ZTV15QAbstractSlider: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractSlider)
+16 QAbstractSlider::metaObject
+24 QAbstractSlider::qt_metacast
+32 QAbstractSlider::qt_metacall
+40 QAbstractSlider::~QAbstractSlider
+48 QAbstractSlider::~QAbstractSlider
+56 QAbstractSlider::event
+64 QObject::eventFilter
+72 QAbstractSlider::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QAbstractSlider::wheelEvent
+200 QAbstractSlider::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QAbstractSlider::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractSlider::sliderChange
+456 (int (*)(...))-0x00000000000000010
+464 (int (*)(...))(& _ZTI15QAbstractSlider)
+472 QAbstractSlider::_ZThn16_N15QAbstractSliderD1Ev
+480 QAbstractSlider::_ZThn16_N15QAbstractSliderD0Ev
+488 QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSlider
+ size=40 align=8
+ base size=40 base align=8
+QAbstractSlider (0x7f0a6d4d7150) 0
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 16u)
+ QWidget (0x7f0a6d4cdb00) 0
+ primary-for QAbstractSlider (0x7f0a6d4d7150)
+ QObject (0x7f0a6d4d71c0) 0
+ primary-for QWidget (0x7f0a6d4cdb00)
+ QPaintDevice (0x7f0a6d4d7230) 16
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 472u)
+
+Vtable for QSlider
+QSlider::_ZTV7QSlider: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QSlider)
+16 QSlider::metaObject
+24 QSlider::qt_metacast
+32 QSlider::qt_metacall
+40 QSlider::~QSlider
+48 QSlider::~QSlider
+56 QSlider::event
+64 QObject::eventFilter
+72 QAbstractSlider::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QSlider::sizeHint
+136 QSlider::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QSlider::mousePressEvent
+168 QSlider::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QSlider::mouseMoveEvent
+192 QAbstractSlider::wheelEvent
+200 QAbstractSlider::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QSlider::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QAbstractSlider::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractSlider::sliderChange
+456 (int (*)(...))-0x00000000000000010
+464 (int (*)(...))(& _ZTI7QSlider)
+472 QSlider::_ZThn16_N7QSliderD1Ev
+480 QSlider::_ZThn16_N7QSliderD0Ev
+488 QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QSlider
+ size=40 align=8
+ base size=40 base align=8
+QSlider (0x7f0a6d305f50) 0
+ vptr=((& QSlider::_ZTV7QSlider) + 16u)
+ QAbstractSlider (0x7f0a6d30a000) 0
+ primary-for QSlider (0x7f0a6d305f50)
+ QWidget (0x7f0a6d303b00) 0
+ primary-for QAbstractSlider (0x7f0a6d30a000)
+ QObject (0x7f0a6d30a070) 0
+ primary-for QWidget (0x7f0a6d303b00)
+ QPaintDevice (0x7f0a6d30a0e0) 16
+ vptr=((& QSlider::_ZTV7QSlider) + 472u)
+
+Vtable for QStyle
+QStyle::_ZTV6QStyle: 35u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QStyle)
+16 QStyle::metaObject
+24 QStyle::qt_metacast
+32 QStyle::qt_metacall
+40 QStyle::~QStyle
+48 QStyle::~QStyle
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QStyle::polish
+120 QStyle::unpolish
+128 QStyle::polish
+136 QStyle::unpolish
+144 QStyle::polish
+152 QStyle::itemTextRect
+160 QStyle::itemPixmapRect
+168 QStyle::drawItemText
+176 QStyle::drawItemPixmap
+184 QStyle::standardPalette
+192 __cxa_pure_virtual
+200 __cxa_pure_virtual
+208 __cxa_pure_virtual
+216 __cxa_pure_virtual
+224 __cxa_pure_virtual
+232 __cxa_pure_virtual
+240 __cxa_pure_virtual
+248 __cxa_pure_virtual
+256 __cxa_pure_virtual
+264 __cxa_pure_virtual
+272 __cxa_pure_virtual
+
+Class QStyle
+ size=16 align=8
+ base size=16 base align=8
+QStyle (0x7f0a6d332540) 0
+ vptr=((& QStyle::_ZTV6QStyle) + 16u)
+ QObject (0x7f0a6d3325b0) 0
+ primary-for QStyle (0x7f0a6d332540)
+
+Vtable for QTabBar
+QTabBar::_ZTV7QTabBar: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QTabBar)
+16 QTabBar::metaObject
+24 QTabBar::qt_metacast
+32 QTabBar::qt_metacall
+40 QTabBar::~QTabBar
+48 QTabBar::~QTabBar
+56 QTabBar::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QTabBar::sizeHint
+136 QTabBar::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QTabBar::mousePressEvent
+168 QTabBar::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QTabBar::mouseMoveEvent
+192 QTabBar::wheelEvent
+200 QTabBar::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QTabBar::paintEvent
+256 QWidget::moveEvent
+264 QTabBar::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QTabBar::showEvent
+344 QTabBar::hideEvent
+352 QWidget::x11Event
+360 QTabBar::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QTabBar::tabSizeHint
+456 QTabBar::tabInserted
+464 QTabBar::tabRemoved
+472 QTabBar::tabLayoutChange
+480 (int (*)(...))-0x00000000000000010
+488 (int (*)(...))(& _ZTI7QTabBar)
+496 QTabBar::_ZThn16_N7QTabBarD1Ev
+504 QTabBar::_ZThn16_N7QTabBarD0Ev
+512 QWidget::_ZThn16_NK7QWidget7devTypeEv
+520 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+528 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabBar
+ size=40 align=8
+ base size=40 base align=8
+QTabBar (0x7f0a6d3ef2a0) 0
+ vptr=((& QTabBar::_ZTV7QTabBar) + 16u)
+ QWidget (0x7f0a6d3bc600) 0
+ primary-for QTabBar (0x7f0a6d3ef2a0)
+ QObject (0x7f0a6d3ef310) 0
+ primary-for QWidget (0x7f0a6d3bc600)
+ QPaintDevice (0x7f0a6d3ef380) 16
+ vptr=((& QTabBar::_ZTV7QTabBar) + 496u)
+
+Vtable for QTabWidget
+QTabWidget::_ZTV10QTabWidget: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTabWidget)
+16 QTabWidget::metaObject
+24 QTabWidget::qt_metacast
+32 QTabWidget::qt_metacall
+40 QTabWidget::~QTabWidget
+48 QTabWidget::~QTabWidget
+56 QTabWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QTabWidget::sizeHint
+136 QTabWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QTabWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QTabWidget::paintEvent
+256 QWidget::moveEvent
+264 QTabWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QTabWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QTabWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QTabWidget::tabInserted
+456 QTabWidget::tabRemoved
+464 (int (*)(...))-0x00000000000000010
+472 (int (*)(...))(& _ZTI10QTabWidget)
+480 QTabWidget::_ZThn16_N10QTabWidgetD1Ev
+488 QTabWidget::_ZThn16_N10QTabWidgetD0Ev
+496 QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabWidget
+ size=40 align=8
+ base size=40 base align=8
+QTabWidget (0x7f0a6d2178c0) 0
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 16u)
+ QWidget (0x7f0a6d210900) 0
+ primary-for QTabWidget (0x7f0a6d2178c0)
+ QObject (0x7f0a6d217930) 0
+ primary-for QWidget (0x7f0a6d210900)
+ QPaintDevice (0x7f0a6d2179a0) 16
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 480u)
+
+Vtable for QRubberBand
+QRubberBand::_ZTV11QRubberBand: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QRubberBand)
+16 QRubberBand::metaObject
+24 QRubberBand::qt_metacast
+32 QRubberBand::qt_metacall
+40 QRubberBand::~QRubberBand
+48 QRubberBand::~QRubberBand
+56 QRubberBand::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QRubberBand::paintEvent
+256 QRubberBand::moveEvent
+264 QRubberBand::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QRubberBand::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QRubberBand::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI11QRubberBand)
+464 QRubberBand::_ZThn16_N11QRubberBandD1Ev
+472 QRubberBand::_ZThn16_N11QRubberBandD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QRubberBand
+ size=40 align=8
+ base size=40 base align=8
+QRubberBand (0x7f0a6d26c2a0) 0
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 16u)
+ QWidget (0x7f0a6d267980) 0
+ primary-for QRubberBand (0x7f0a6d26c2a0)
+ QObject (0x7f0a6d26c310) 0
+ primary-for QWidget (0x7f0a6d267980)
+ QPaintDevice (0x7f0a6d26c380) 16
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 464u)
+
+Class QStyleOption
+ size=56 align=8
+ base size=56 base align=8
+QStyleOption (0x7f0a6d28d5b0) 0
+
+Class QStyleOptionFocusRect
+ size=72 align=8
+ base size=72 base align=8
+QStyleOptionFocusRect (0x7f0a6d29d310) 0
+ QStyleOption (0x7f0a6d29d380) 0
+
+Class QStyleOptionFrame
+ size=64 align=8
+ base size=64 base align=8
+QStyleOptionFrame (0x7f0a6d2a7310) 0
+ QStyleOption (0x7f0a6d2a7380) 0
+
+Class QStyleOptionFrameV2
+ size=72 align=8
+ base size=68 base align=8
+QStyleOptionFrameV2 (0x7f0a6d2b32a0) 0
+ QStyleOptionFrame (0x7f0a6d2b3310) 0
+ QStyleOption (0x7f0a6d2b3380) 0
+
+Class QStyleOptionFrameV3
+ size=72 align=8
+ base size=72 base align=8
+QStyleOptionFrameV3 (0x7f0a6d2e6b60) 0
+ QStyleOptionFrameV2 (0x7f0a6d2e6bd0) 0
+ QStyleOptionFrame (0x7f0a6d2e6c40) 0
+ QStyleOption (0x7f0a6d2e6cb0) 0
+
+Class QStyleOptionTabWidgetFrame
+ size=96 align=8
+ base size=92 base align=8
+QStyleOptionTabWidgetFrame (0x7f0a6d109460) 0
+ QStyleOption (0x7f0a6d1094d0) 0
+
+Class QStyleOptionTabBarBase
+ size=96 align=8
+ base size=92 base align=8
+QStyleOptionTabBarBase (0x7f0a6d116bd0) 0
+ QStyleOption (0x7f0a6d116c40) 0
+
+Class QStyleOptionTabBarBaseV2
+ size=96 align=8
+ base size=93 base align=8
+QStyleOptionTabBarBaseV2 (0x7f0a6d11d3f0) 0
+ QStyleOptionTabBarBase (0x7f0a6d128000) 0
+ QStyleOption (0x7f0a6d128070) 0
+
+Class QStyleOptionHeader
+ size=112 align=8
+ base size=108 base align=8
+QStyleOptionHeader (0x7f0a6d134620) 0
+ QStyleOption (0x7f0a6d134690) 0
+
+Class QStyleOptionButton
+ size=88 align=8
+ base size=88 base align=8
+QStyleOptionButton (0x7f0a6d14c7e0) 0
+ QStyleOption (0x7f0a6d14c850) 0
+
+Class QStyleOptionTab
+ size=96 align=8
+ base size=96 base align=8
+QStyleOptionTab (0x7f0a6d19a1c0) 0
+ QStyleOption (0x7f0a6d19a230) 0
+
+Class QStyleOptionTabV2
+ size=104 align=8
+ base size=104 base align=8
+QStyleOptionTabV2 (0x7f0a6d1e6150) 0
+ QStyleOptionTab (0x7f0a6d1e61c0) 0
+ QStyleOption (0x7f0a6d1e6230) 0
+
+Class QStyleOptionTabV3
+ size=128 align=8
+ base size=124 base align=8
+QStyleOptionTabV3 (0x7f0a6cff1b60) 0
+ QStyleOptionTabV2 (0x7f0a6cff1bd0) 0
+ QStyleOptionTab (0x7f0a6cff1c40) 0
+ QStyleOption (0x7f0a6cff1cb0) 0
+
+Class QStyleOptionToolBar
+ size=80 align=8
+ base size=80 base align=8
+QStyleOptionToolBar (0x7f0a6d00e1c0) 0
+ QStyleOption (0x7f0a6d00e230) 0
+
+Class QStyleOptionProgressBar
+ size=88 align=8
+ base size=85 base align=8
+QStyleOptionProgressBar (0x7f0a6d0419a0) 0
+ QStyleOption (0x7f0a6d041a10) 0
+
+Class QStyleOptionProgressBarV2
+ size=96 align=8
+ base size=94 base align=8
+QStyleOptionProgressBarV2 (0x7f0a6d066150) 0
+ QStyleOptionProgressBar (0x7f0a6d0661c0) 0
+ QStyleOption (0x7f0a6d066230) 0
+
+Class QStyleOptionMenuItem
+ size=128 align=8
+ base size=128 base align=8
+QStyleOptionMenuItem (0x7f0a6d066a10) 0
+ QStyleOption (0x7f0a6d066a80) 0
+
+Class QStyleOptionQ3ListViewItem
+ size=80 align=8
+ base size=76 base align=8
+QStyleOptionQ3ListViewItem (0x7f0a6d083c40) 0
+ QStyleOption (0x7f0a6d083cb0) 0
+
+Class QStyleOptionQ3DockWindow
+ size=64 align=8
+ base size=58 base align=8
+QStyleOptionQ3DockWindow (0x7f0a6d0d00e0) 0
+ QStyleOption (0x7f0a6d0d0150) 0
+
+Class QStyleOptionDockWidget
+ size=72 align=8
+ base size=67 base align=8
+QStyleOptionDockWidget (0x7f0a6d0dc070) 0
+ QStyleOption (0x7f0a6d0dc0e0) 0
+
+Class QStyleOptionDockWidgetV2
+ size=72 align=8
+ base size=68 base align=8
+QStyleOptionDockWidgetV2 (0x7f0a6d0e9460) 0
+ QStyleOptionDockWidget (0x7f0a6d0e94d0) 0
+ QStyleOption (0x7f0a6d0e9540) 0
+
+Class QStyleOptionViewItem
+ size=104 align=8
+ base size=97 base align=8
+QStyleOptionViewItem (0x7f0a6cef2c40) 0
+ QStyleOption (0x7f0a6cef2cb0) 0
+
+Class QStyleOptionViewItemV2
+ size=104 align=8
+ base size=104 base align=8
+QStyleOptionViewItemV2 (0x7f0a6cf0c7e0) 0
+ QStyleOptionViewItem (0x7f0a6cf0c850) 0
+ QStyleOption (0x7f0a6cf0c8c0) 0
+
+Class QStyleOptionViewItemV3
+ size=120 align=8
+ base size=120 base align=8
+QStyleOptionViewItemV3 (0x7f0a6cf56230) 0
+ QStyleOptionViewItemV2 (0x7f0a6cf562a0) 0
+ QStyleOptionViewItem (0x7f0a6cf56310) 0
+ QStyleOption (0x7f0a6cf56380) 0
+
+Class QStyleOptionViewItemV4
+ size=184 align=8
+ base size=184 base align=8
+QStyleOptionViewItemV4 (0x7f0a6cf63af0) 0
+ QStyleOptionViewItemV3 (0x7f0a6cf63b60) 0
+ QStyleOptionViewItemV2 (0x7f0a6cf63bd0) 0
+ QStyleOptionViewItem (0x7f0a6cf63c40) 0
+ QStyleOption (0x7f0a6cf63cb0) 0
+
+Class QStyleOptionToolBox
+ size=72 align=8
+ base size=72 base align=8
+QStyleOptionToolBox (0x7f0a6cf84230) 0
+ QStyleOption (0x7f0a6cf842a0) 0
+
+Class QStyleOptionToolBoxV2
+ size=80 align=8
+ base size=80 base align=8
+QStyleOptionToolBoxV2 (0x7f0a6cf90700) 0
+ QStyleOptionToolBox (0x7f0a6cf90770) 0
+ QStyleOption (0x7f0a6cf907e0) 0
+
+Class QStyleOptionRubberBand
+ size=64 align=8
+ base size=61 base align=8
+QStyleOptionRubberBand (0x7f0a6cfa63f0) 0
+ QStyleOption (0x7f0a6cfa6460) 0
+
+Class QStyleOptionComplex
+ size=64 align=8
+ base size=64 base align=8
+QStyleOptionComplex (0x7f0a6cfb24d0) 0
+ QStyleOption (0x7f0a6cfb2540) 0
+
+Class QStyleOptionSlider
+ size=120 align=8
+ base size=113 base align=8
+QStyleOptionSlider (0x7f0a6cfbacb0) 0
+ QStyleOptionComplex (0x7f0a6cfbad20) 0
+ QStyleOption (0x7f0a6cfbad90) 0
+
+Class QStyleOptionSpinBox
+ size=80 align=8
+ base size=73 base align=8
+QStyleOptionSpinBox (0x7f0a6cfd2a80) 0
+ QStyleOptionComplex (0x7f0a6cfd2af0) 0
+ QStyleOption (0x7f0a6cfd2b60) 0
+
+Class QStyleOptionQ3ListView
+ size=112 align=8
+ base size=105 base align=8
+QStyleOptionQ3ListView (0x7f0a6cfda460) 0
+ QStyleOptionComplex (0x7f0a6cfe4000) 0
+ QStyleOption (0x7f0a6cfe4070) 0
+
+Class QStyleOptionToolButton
+ size=128 align=8
+ base size=128 base align=8
+QStyleOptionToolButton (0x7f0a6ce13bd0) 0
+ QStyleOptionComplex (0x7f0a6ce13c40) 0
+ QStyleOption (0x7f0a6ce13cb0) 0
+
+Class QStyleOptionComboBox
+ size=112 align=8
+ base size=112 base align=8
+QStyleOptionComboBox (0x7f0a6ce57e00) 0
+ QStyleOptionComplex (0x7f0a6ce57e70) 0
+ QStyleOption (0x7f0a6ce57ee0) 0
+
+Class QStyleOptionTitleBar
+ size=88 align=8
+ base size=88 base align=8
+QStyleOptionTitleBar (0x7f0a6ce7d930) 0
+ QStyleOptionComplex (0x7f0a6ce7d9a0) 0
+ QStyleOption (0x7f0a6ce7da10) 0
+
+Class QStyleOptionGroupBox
+ size=112 align=8
+ base size=108 base align=8
+QStyleOptionGroupBox (0x7f0a6ce941c0) 0
+ QStyleOptionComplex (0x7f0a6ce94230) 0
+ QStyleOption (0x7f0a6ce942a0) 0
+
+Class QStyleOptionSizeGrip
+ size=72 align=8
+ base size=68 base align=8
+QStyleOptionSizeGrip (0x7f0a6cea1d90) 0
+ QStyleOptionComplex (0x7f0a6cea1e00) 0
+ QStyleOption (0x7f0a6cea1e70) 0
+
+Class QStyleOptionGraphicsItem
+ size=144 align=8
+ base size=144 base align=8
+QStyleOptionGraphicsItem (0x7f0a6ceadd20) 0
+ QStyleOption (0x7f0a6ceadd90) 0
+
+Class QStyleHintReturn
+ size=8 align=4
+ base size=8 base align=4
+QStyleHintReturn (0x7f0a6cecc070) 0
+
+Class QStyleHintReturnMask
+ size=16 align=8
+ base size=16 base align=8
+QStyleHintReturnMask (0x7f0a6cecc4d0) 0
+ QStyleHintReturn (0x7f0a6cecc540) 0
+
+Class QStyleHintReturnVariant
+ size=24 align=8
+ base size=24 base align=8
+QStyleHintReturnVariant (0x7f0a6cecc700) 0
+ QStyleHintReturn (0x7f0a6cecc770) 0
+
+Vtable for QAbstractItemDelegate
+QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 21u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QAbstractItemDelegate)
+16 QAbstractItemDelegate::metaObject
+24 QAbstractItemDelegate::qt_metacast
+32 QAbstractItemDelegate::qt_metacall
+40 QAbstractItemDelegate::~QAbstractItemDelegate
+48 QAbstractItemDelegate::~QAbstractItemDelegate
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 QAbstractItemDelegate::createEditor
+136 QAbstractItemDelegate::setEditorData
+144 QAbstractItemDelegate::setModelData
+152 QAbstractItemDelegate::updateEditorGeometry
+160 QAbstractItemDelegate::editorEvent
+
+Class QAbstractItemDelegate
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemDelegate (0x7f0a6ceccbd0) 0
+ vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 16u)
+ QObject (0x7f0a6ceccc40) 0
+ primary-for QAbstractItemDelegate (0x7f0a6ceccbd0)
+
+Vtable for QAbstractItemView
+QAbstractItemView::_ZTV17QAbstractItemView: 103u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAbstractItemView)
+16 QAbstractItemView::metaObject
+24 QAbstractItemView::qt_metacast
+32 QAbstractItemView::qt_metacall
+40 QAbstractItemView::~QAbstractItemView
+48 QAbstractItemView::~QAbstractItemView
+56 QAbstractItemView::event
+64 QObject::eventFilter
+72 QAbstractItemView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractItemView::mousePressEvent
+168 QAbstractItemView::mouseReleaseEvent
+176 QAbstractItemView::mouseDoubleClickEvent
+184 QAbstractItemView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QAbstractItemView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QAbstractScrollArea::paintEvent
+256 QWidget::moveEvent
+264 QAbstractItemView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QAbstractItemView::dragMoveEvent
+320 QAbstractItemView::dragLeaveEvent
+328 QAbstractItemView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractItemView::viewportEvent
+456 QAbstractScrollArea::scrollContentsBy
+464 QAbstractItemView::setModel
+472 QAbstractItemView::setSelectionModel
+480 QAbstractItemView::keyboardSearch
+488 __cxa_pure_virtual
+496 __cxa_pure_virtual
+504 __cxa_pure_virtual
+512 QAbstractItemView::sizeHintForRow
+520 QAbstractItemView::sizeHintForColumn
+528 QAbstractItemView::reset
+536 QAbstractItemView::setRootIndex
+544 QAbstractItemView::doItemsLayout
+552 QAbstractItemView::selectAll
+560 QAbstractItemView::dataChanged
+568 QAbstractItemView::rowsInserted
+576 QAbstractItemView::rowsAboutToBeRemoved
+584 QAbstractItemView::selectionChanged
+592 QAbstractItemView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QAbstractItemView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QAbstractItemView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 __cxa_pure_virtual
+688 __cxa_pure_virtual
+696 __cxa_pure_virtual
+704 __cxa_pure_virtual
+712 __cxa_pure_virtual
+720 __cxa_pure_virtual
+728 QAbstractItemView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QAbstractItemView::startDrag
+760 QAbstractItemView::viewOptions
+768 (int (*)(...))-0x00000000000000010
+776 (int (*)(...))(& _ZTI17QAbstractItemView)
+784 QAbstractItemView::_ZThn16_N17QAbstractItemViewD1Ev
+792 QAbstractItemView::_ZThn16_N17QAbstractItemViewD0Ev
+800 QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractItemView
+ size=40 align=8
+ base size=40 base align=8
+QAbstractItemView (0x7f0a6cd052a0) 0
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 16u)
+ QAbstractScrollArea (0x7f0a6cd05310) 0
+ primary-for QAbstractItemView (0x7f0a6cd052a0)
+ QFrame (0x7f0a6cd05380) 0
+ primary-for QAbstractScrollArea (0x7f0a6cd05310)
+ QWidget (0x7f0a6ccf2780) 0
+ primary-for QFrame (0x7f0a6cd05380)
+ QObject (0x7f0a6cd053f0) 0
+ primary-for QWidget (0x7f0a6ccf2780)
+ QPaintDevice (0x7f0a6cd05460) 16
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 784u)
+
+Vtable for QTreeView
+QTreeView::_ZTV9QTreeView: 105u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTreeView)
+16 QTreeView::metaObject
+24 QTreeView::qt_metacast
+32 QTreeView::qt_metacall
+40 QTreeView::~QTreeView
+48 QTreeView::~QTreeView
+56 QAbstractItemView::event
+64 QObject::eventFilter
+72 QTreeView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QTreeView::mousePressEvent
+168 QTreeView::mouseReleaseEvent
+176 QTreeView::mouseDoubleClickEvent
+184 QTreeView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QTreeView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QTreeView::paintEvent
+256 QWidget::moveEvent
+264 QAbstractItemView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QTreeView::dragMoveEvent
+320 QAbstractItemView::dragLeaveEvent
+328 QAbstractItemView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QTreeView::viewportEvent
+456 QTreeView::scrollContentsBy
+464 QTreeView::setModel
+472 QTreeView::setSelectionModel
+480 QTreeView::keyboardSearch
+488 QTreeView::visualRect
+496 QTreeView::scrollTo
+504 QTreeView::indexAt
+512 QAbstractItemView::sizeHintForRow
+520 QTreeView::sizeHintForColumn
+528 QTreeView::reset
+536 QTreeView::setRootIndex
+544 QTreeView::doItemsLayout
+552 QTreeView::selectAll
+560 QTreeView::dataChanged
+568 QTreeView::rowsInserted
+576 QTreeView::rowsAboutToBeRemoved
+584 QTreeView::selectionChanged
+592 QTreeView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QTreeView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QTreeView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 QTreeView::moveCursor
+688 QTreeView::horizontalOffset
+696 QTreeView::verticalOffset
+704 QTreeView::isIndexHidden
+712 QTreeView::setSelection
+720 QTreeView::visualRegionForSelection
+728 QTreeView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QAbstractItemView::startDrag
+760 QAbstractItemView::viewOptions
+768 QTreeView::drawRow
+776 QTreeView::drawBranches
+784 (int (*)(...))-0x00000000000000010
+792 (int (*)(...))(& _ZTI9QTreeView)
+800 QTreeView::_ZThn16_N9QTreeViewD1Ev
+808 QTreeView::_ZThn16_N9QTreeViewD0Ev
+816 QWidget::_ZThn16_NK7QWidget7devTypeEv
+824 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+832 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTreeView
+ size=40 align=8
+ base size=40 base align=8
+QTreeView (0x7f0a6cd7da80) 0
+ vptr=((& QTreeView::_ZTV9QTreeView) + 16u)
+ QAbstractItemView (0x7f0a6cd7daf0) 0
+ primary-for QTreeView (0x7f0a6cd7da80)
+ QAbstractScrollArea (0x7f0a6cd7db60) 0
+ primary-for QAbstractItemView (0x7f0a6cd7daf0)
+ QFrame (0x7f0a6cd7dbd0) 0
+ primary-for QAbstractScrollArea (0x7f0a6cd7db60)
+ QWidget (0x7f0a6cd42e00) 0
+ primary-for QFrame (0x7f0a6cd7dbd0)
+ QObject (0x7f0a6cd7dc40) 0
+ primary-for QWidget (0x7f0a6cd42e00)
+ QPaintDevice (0x7f0a6cd7dcb0) 16
+ vptr=((& QTreeView::_ZTV9QTreeView) + 800u)
+
+Class QHelpContentItem
+ size=8 align=8
+ base size=8 base align=8
+QHelpContentItem (0x7f0a6cdc6850) 0
+
+Vtable for QHelpContentModel
+QHelpContentModel::_ZTV17QHelpContentModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QHelpContentModel)
+16 QHelpContentModel::metaObject
+24 QHelpContentModel::qt_metacast
+32 QHelpContentModel::qt_metacall
+40 QHelpContentModel::~QHelpContentModel
+48 QHelpContentModel::~QHelpContentModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QHelpContentModel::index
+120 QHelpContentModel::parent
+128 QHelpContentModel::rowCount
+136 QHelpContentModel::columnCount
+144 QAbstractItemModel::hasChildren
+152 QHelpContentModel::data
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractItemModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QHelpContentModel
+ size=24 align=8
+ base size=24 base align=8
+QHelpContentModel (0x7f0a6cdc6d90) 0
+ vptr=((& QHelpContentModel::_ZTV17QHelpContentModel) + 16u)
+ QAbstractItemModel (0x7f0a6cdc6e00) 0
+ primary-for QHelpContentModel (0x7f0a6cdc6d90)
+ QObject (0x7f0a6cdc6e70) 0
+ primary-for QAbstractItemModel (0x7f0a6cdc6e00)
+
+Vtable for QHelpContentWidget
+QHelpContentWidget::_ZTV18QHelpContentWidget: 105u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QHelpContentWidget)
+16 QHelpContentWidget::metaObject
+24 QHelpContentWidget::qt_metacast
+32 QHelpContentWidget::qt_metacall
+40 QHelpContentWidget::~QHelpContentWidget
+48 QHelpContentWidget::~QHelpContentWidget
+56 QAbstractItemView::event
+64 QObject::eventFilter
+72 QTreeView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QTreeView::mousePressEvent
+168 QTreeView::mouseReleaseEvent
+176 QTreeView::mouseDoubleClickEvent
+184 QTreeView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QTreeView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QTreeView::paintEvent
+256 QWidget::moveEvent
+264 QAbstractItemView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QTreeView::dragMoveEvent
+320 QAbstractItemView::dragLeaveEvent
+328 QAbstractItemView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QTreeView::viewportEvent
+456 QTreeView::scrollContentsBy
+464 QTreeView::setModel
+472 QTreeView::setSelectionModel
+480 QTreeView::keyboardSearch
+488 QTreeView::visualRect
+496 QTreeView::scrollTo
+504 QTreeView::indexAt
+512 QAbstractItemView::sizeHintForRow
+520 QTreeView::sizeHintForColumn
+528 QTreeView::reset
+536 QTreeView::setRootIndex
+544 QTreeView::doItemsLayout
+552 QTreeView::selectAll
+560 QTreeView::dataChanged
+568 QTreeView::rowsInserted
+576 QTreeView::rowsAboutToBeRemoved
+584 QTreeView::selectionChanged
+592 QTreeView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QTreeView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QTreeView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 QTreeView::moveCursor
+688 QTreeView::horizontalOffset
+696 QTreeView::verticalOffset
+704 QTreeView::isIndexHidden
+712 QTreeView::setSelection
+720 QTreeView::visualRegionForSelection
+728 QTreeView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QAbstractItemView::startDrag
+760 QAbstractItemView::viewOptions
+768 QTreeView::drawRow
+776 QTreeView::drawBranches
+784 (int (*)(...))-0x00000000000000010
+792 (int (*)(...))(& _ZTI18QHelpContentWidget)
+800 QHelpContentWidget::_ZThn16_N18QHelpContentWidgetD1Ev
+808 QHelpContentWidget::_ZThn16_N18QHelpContentWidgetD0Ev
+816 QWidget::_ZThn16_NK7QWidget7devTypeEv
+824 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+832 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpContentWidget
+ size=64 align=8
+ base size=64 base align=8
+QHelpContentWidget (0x7f0a6cddae00) 0
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 16u)
+ QTreeView (0x7f0a6cddae70) 0
+ primary-for QHelpContentWidget (0x7f0a6cddae00)
+ QAbstractItemView (0x7f0a6cddaee0) 0
+ primary-for QTreeView (0x7f0a6cddae70)
+ QAbstractScrollArea (0x7f0a6cddaf50) 0
+ primary-for QAbstractItemView (0x7f0a6cddaee0)
+ QFrame (0x7f0a6cdda070) 0
+ primary-for QAbstractScrollArea (0x7f0a6cddaf50)
+ QWidget (0x7f0a6cdbfe00) 0
+ primary-for QFrame (0x7f0a6cdda070)
+ QObject (0x7f0a6cde6000) 0
+ primary-for QWidget (0x7f0a6cdbfe00)
+ QPaintDevice (0x7f0a6cde6070) 16
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 800u)
+
+Class QHelpSearchQuery
+ size=16 align=8
+ base size=16 base align=8
+QHelpSearchQuery (0x7f0a6cde6e00) 0
+
+Vtable for QHelpSearchEngine
+QHelpSearchEngine::_ZTV17QHelpSearchEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QHelpSearchEngine)
+16 QHelpSearchEngine::metaObject
+24 QHelpSearchEngine::qt_metacast
+32 QHelpSearchEngine::qt_metacall
+40 QHelpSearchEngine::~QHelpSearchEngine
+48 QHelpSearchEngine::~QHelpSearchEngine
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QHelpSearchEngine
+ size=24 align=8
+ base size=24 base align=8
+QHelpSearchEngine (0x7f0a6cc05380) 0
+ vptr=((& QHelpSearchEngine::_ZTV17QHelpSearchEngine) + 16u)
+ QObject (0x7f0a6cc053f0) 0
+ primary-for QHelpSearchEngine (0x7f0a6cc05380)
+
+Vtable for QHelpSearchResultWidget
+QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+16 QHelpSearchResultWidget::metaObject
+24 QHelpSearchResultWidget::qt_metacast
+32 QHelpSearchResultWidget::qt_metacall
+40 QHelpSearchResultWidget::~QHelpSearchResultWidget
+48 QHelpSearchResultWidget::~QHelpSearchResultWidget
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+464 QHelpSearchResultWidget::_ZThn16_N23QHelpSearchResultWidgetD1Ev
+472 QHelpSearchResultWidget::_ZThn16_N23QHelpSearchResultWidgetD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchResultWidget
+ size=48 align=8
+ base size=48 base align=8
+QHelpSearchResultWidget (0x7f0a6cc13700) 0
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 16u)
+ QWidget (0x7f0a6cc01c80) 0
+ primary-for QHelpSearchResultWidget (0x7f0a6cc13700)
+ QObject (0x7f0a6cc13770) 0
+ primary-for QWidget (0x7f0a6cc01c80)
+ QPaintDevice (0x7f0a6cc137e0) 16
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 464u)
+
+Vtable for QHelpEngineCore
+QHelpEngineCore::_ZTV15QHelpEngineCore: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QHelpEngineCore)
+16 QHelpEngineCore::metaObject
+24 QHelpEngineCore::qt_metacast
+32 QHelpEngineCore::qt_metacall
+40 QHelpEngineCore::~QHelpEngineCore
+48 QHelpEngineCore::~QHelpEngineCore
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QHelpEngineCore
+ size=24 align=8
+ base size=24 base align=8
+QHelpEngineCore (0x7f0a6cc2b5b0) 0
+ vptr=((& QHelpEngineCore::_ZTV15QHelpEngineCore) + 16u)
+ QObject (0x7f0a6cc2b620) 0
+ primary-for QHelpEngineCore (0x7f0a6cc2b5b0)
+
+Vtable for QHelpEngine
+QHelpEngine::_ZTV11QHelpEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHelpEngine)
+16 QHelpEngine::metaObject
+24 QHelpEngine::qt_metacast
+32 QHelpEngine::qt_metacall
+40 QHelpEngine::~QHelpEngine
+48 QHelpEngine::~QHelpEngine
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QHelpEngine
+ size=32 align=8
+ base size=32 base align=8
+QHelpEngine (0x7f0a6cc48620) 0
+ vptr=((& QHelpEngine::_ZTV11QHelpEngine) + 16u)
+ QHelpEngineCore (0x7f0a6cc48690) 0
+ primary-for QHelpEngine (0x7f0a6cc48620)
+ QObject (0x7f0a6cc48700) 0
+ primary-for QHelpEngineCore (0x7f0a6cc48690)
+
+Vtable for QHelpSearchQueryWidget
+QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+16 QHelpSearchQueryWidget::metaObject
+24 QHelpSearchQueryWidget::qt_metacast
+32 QHelpSearchQueryWidget::qt_metacall
+40 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+48 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QHelpSearchQueryWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+464 QHelpSearchQueryWidget::_ZThn16_N22QHelpSearchQueryWidgetD1Ev
+472 QHelpSearchQueryWidget::_ZThn16_N22QHelpSearchQueryWidgetD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchQueryWidget
+ size=48 align=8
+ base size=48 base align=8
+QHelpSearchQueryWidget (0x7f0a6cc58540) 0
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 16u)
+ QWidget (0x7f0a6cc5a080) 0
+ primary-for QHelpSearchQueryWidget (0x7f0a6cc58540)
+ QObject (0x7f0a6cc585b0) 0
+ primary-for QWidget (0x7f0a6cc5a080)
+ QPaintDevice (0x7f0a6cc58620) 16
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 464u)
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QStringListModel)
+16 QStringListModel::metaObject
+24 QStringListModel::qt_metacast
+32 QStringListModel::qt_metacall
+40 QStringListModel::~QStringListModel
+48 QStringListModel::~QStringListModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractListModel::index
+120 QAbstractListModel::parent
+128 QStringListModel::rowCount
+136 QAbstractListModel::columnCount
+144 QAbstractListModel::hasChildren
+152 QStringListModel::data
+160 QStringListModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractListModel::dropMimeData
+224 QStringListModel::supportedDropActions
+232 QStringListModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QStringListModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QStringListModel::flags
+288 QStringListModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QStringListModel
+ size=24 align=8
+ base size=24 base align=8
+QStringListModel (0x7f0a6cc6d4d0) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u)
+ QAbstractListModel (0x7f0a6cc6d540) 0
+ primary-for QStringListModel (0x7f0a6cc6d4d0)
+ QAbstractItemModel (0x7f0a6cc6d5b0) 0
+ primary-for QAbstractListModel (0x7f0a6cc6d540)
+ QObject (0x7f0a6cc6d620) 0
+ primary-for QAbstractItemModel (0x7f0a6cc6d5b0)
+
+Vtable for QListView
+QListView::_ZTV9QListView: 103u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QListView)
+16 QListView::metaObject
+24 QListView::qt_metacast
+32 QListView::qt_metacall
+40 QListView::~QListView
+48 QListView::~QListView
+56 QListView::event
+64 QObject::eventFilter
+72 QListView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractItemView::mousePressEvent
+168 QListView::mouseReleaseEvent
+176 QAbstractItemView::mouseDoubleClickEvent
+184 QListView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QAbstractItemView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QListView::paintEvent
+256 QWidget::moveEvent
+264 QListView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QListView::dragMoveEvent
+320 QListView::dragLeaveEvent
+328 QListView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractItemView::viewportEvent
+456 QListView::scrollContentsBy
+464 QAbstractItemView::setModel
+472 QAbstractItemView::setSelectionModel
+480 QAbstractItemView::keyboardSearch
+488 QListView::visualRect
+496 QListView::scrollTo
+504 QListView::indexAt
+512 QAbstractItemView::sizeHintForRow
+520 QAbstractItemView::sizeHintForColumn
+528 QListView::reset
+536 QListView::setRootIndex
+544 QListView::doItemsLayout
+552 QAbstractItemView::selectAll
+560 QListView::dataChanged
+568 QListView::rowsInserted
+576 QListView::rowsAboutToBeRemoved
+584 QListView::selectionChanged
+592 QListView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QListView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QAbstractItemView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 QListView::moveCursor
+688 QListView::horizontalOffset
+696 QListView::verticalOffset
+704 QListView::isIndexHidden
+712 QListView::setSelection
+720 QListView::visualRegionForSelection
+728 QListView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QListView::startDrag
+760 QListView::viewOptions
+768 (int (*)(...))-0x00000000000000010
+776 (int (*)(...))(& _ZTI9QListView)
+784 QListView::_ZThn16_N9QListViewD1Ev
+792 QListView::_ZThn16_N9QListViewD0Ev
+800 QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QListView
+ size=40 align=8
+ base size=40 base align=8
+QListView (0x7f0a6cc83af0) 0
+ vptr=((& QListView::_ZTV9QListView) + 16u)
+ QAbstractItemView (0x7f0a6cc83b60) 0
+ primary-for QListView (0x7f0a6cc83af0)
+ QAbstractScrollArea (0x7f0a6cc83bd0) 0
+ primary-for QAbstractItemView (0x7f0a6cc83b60)
+ QFrame (0x7f0a6cc83c40) 0
+ primary-for QAbstractScrollArea (0x7f0a6cc83bd0)
+ QWidget (0x7f0a6cc5ae00) 0
+ primary-for QFrame (0x7f0a6cc83c40)
+ QObject (0x7f0a6cc83cb0) 0
+ primary-for QWidget (0x7f0a6cc5ae00)
+ QPaintDevice (0x7f0a6cc83d20) 16
+ vptr=((& QListView::_ZTV9QListView) + 784u)
+
+Vtable for QHelpIndexModel
+QHelpIndexModel::_ZTV15QHelpIndexModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QHelpIndexModel)
+16 QHelpIndexModel::metaObject
+24 QHelpIndexModel::qt_metacast
+32 QHelpIndexModel::qt_metacall
+40 QHelpIndexModel::~QHelpIndexModel
+48 QHelpIndexModel::~QHelpIndexModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractListModel::index
+120 QAbstractListModel::parent
+128 QStringListModel::rowCount
+136 QAbstractListModel::columnCount
+144 QAbstractListModel::hasChildren
+152 QStringListModel::data
+160 QStringListModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractListModel::dropMimeData
+224 QStringListModel::supportedDropActions
+232 QStringListModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QStringListModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QStringListModel::flags
+288 QStringListModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QHelpIndexModel
+ size=32 align=8
+ base size=32 base align=8
+QHelpIndexModel (0x7f0a6ccc11c0) 0
+ vptr=((& QHelpIndexModel::_ZTV15QHelpIndexModel) + 16u)
+ QStringListModel (0x7f0a6ccc1230) 0
+ primary-for QHelpIndexModel (0x7f0a6ccc11c0)
+ QAbstractListModel (0x7f0a6ccc12a0) 0
+ primary-for QStringListModel (0x7f0a6ccc1230)
+ QAbstractItemModel (0x7f0a6ccc1310) 0
+ primary-for QAbstractListModel (0x7f0a6ccc12a0)
+ QObject (0x7f0a6ccc1380) 0
+ primary-for QAbstractItemModel (0x7f0a6ccc1310)
+
+Vtable for QHelpIndexWidget
+QHelpIndexWidget::_ZTV16QHelpIndexWidget: 103u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+16 QHelpIndexWidget::metaObject
+24 QHelpIndexWidget::qt_metacast
+32 QHelpIndexWidget::qt_metacall
+40 QHelpIndexWidget::~QHelpIndexWidget
+48 QHelpIndexWidget::~QHelpIndexWidget
+56 QListView::event
+64 QObject::eventFilter
+72 QListView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractItemView::mousePressEvent
+168 QListView::mouseReleaseEvent
+176 QAbstractItemView::mouseDoubleClickEvent
+184 QListView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QAbstractItemView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QListView::paintEvent
+256 QWidget::moveEvent
+264 QListView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QListView::dragMoveEvent
+320 QListView::dragLeaveEvent
+328 QListView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractItemView::viewportEvent
+456 QListView::scrollContentsBy
+464 QAbstractItemView::setModel
+472 QAbstractItemView::setSelectionModel
+480 QAbstractItemView::keyboardSearch
+488 QListView::visualRect
+496 QListView::scrollTo
+504 QListView::indexAt
+512 QAbstractItemView::sizeHintForRow
+520 QAbstractItemView::sizeHintForColumn
+528 QListView::reset
+536 QListView::setRootIndex
+544 QListView::doItemsLayout
+552 QAbstractItemView::selectAll
+560 QListView::dataChanged
+568 QListView::rowsInserted
+576 QListView::rowsAboutToBeRemoved
+584 QListView::selectionChanged
+592 QListView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QListView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QAbstractItemView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 QListView::moveCursor
+688 QListView::horizontalOffset
+696 QListView::verticalOffset
+704 QListView::isIndexHidden
+712 QListView::setSelection
+720 QListView::visualRegionForSelection
+728 QListView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QListView::startDrag
+760 QListView::viewOptions
+768 (int (*)(...))-0x00000000000000010
+776 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+784 QHelpIndexWidget::_ZThn16_N16QHelpIndexWidgetD1Ev
+792 QHelpIndexWidget::_ZThn16_N16QHelpIndexWidgetD0Ev
+800 QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpIndexWidget
+ size=40 align=8
+ base size=40 base align=8
+QHelpIndexWidget (0x7f0a6ccd51c0) 0
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 16u)
+ QListView (0x7f0a6ccd5230) 0
+ primary-for QHelpIndexWidget (0x7f0a6ccd51c0)
+ QAbstractItemView (0x7f0a6ccd52a0) 0
+ primary-for QListView (0x7f0a6ccd5230)
+ QAbstractScrollArea (0x7f0a6ccd5310) 0
+ primary-for QAbstractItemView (0x7f0a6ccd52a0)
+ QFrame (0x7f0a6ccd5380) 0
+ primary-for QAbstractScrollArea (0x7f0a6ccd5310)
+ QWidget (0x7f0a6ccd0380) 0
+ primary-for QFrame (0x7f0a6ccd5380)
+ QObject (0x7f0a6ccd53f0) 0
+ primary-for QWidget (0x7f0a6ccd0380)
+ QPaintDevice (0x7f0a6ccd5460) 16
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 784u)
+
diff --git a/tests/auto/bic/data/QtHelp.4.5.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtHelp.4.5.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..8f7662362
--- /dev/null
+++ b/tests/auto/bic/data/QtHelp.4.5.0.linux-gcc-ia32.txt
@@ -0,0 +1,6357 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb6e96bb8) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb6e96d5c) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb64dd438) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb64dd4ec) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb64ddd20) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0xb64dde4c) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb651cce4) 0 empty
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb651cd20) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb5babe00) 0
+ QGenericArgument (0xb651cf3c) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb5c280b4) 0
+
+Class QMetaObjectExtraData
+ size=8 align=4
+ base size=8 base align=4
+QMetaObjectExtraData (0xb5c281e0) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb5c283c0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb5c285a0) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0xb5c71ce4) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0xb5ca1400) 0
+ QBasicAtomicInt (0xb5c8f3fc) 0
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb5c8f8e8) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb5c8fd5c) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb5c8fd20) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb5b14c30) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb5b5f4ec) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb5b5f528) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb5b5f4b0) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb5a2a078) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb5a6fd5c) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb58f3cc0) 0
+ QString (0xb592d4b0) 0
+
+Class QStringRef
+ size=12 align=4
+ base size=12 base align=4
+QStringRef (0xb592d8e8) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb597099c) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::bad_exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb57a8b00) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb5970a8c) 0 nearly-empty
+ primary-for std::bad_exception (0xb57a8b00)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb57a8c80) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb5970ce4) 0 nearly-empty
+ primary-for std::bad_alloc (0xb57a8c80)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb5970f3c) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb57c403c) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb57c4000) 0
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=24 align=4
+ base size=24 base align=4
+QObjectData (0xb57c47bc) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb57c4870) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb589a0b4) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb589c240) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb589a1e0) 0
+ primary-for QIODevice (0xb589c240)
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb589af3c) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb56e9ac8) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb56e9a8c) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb5726168) 0 empty
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb57268ac) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb5726870) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSystemLocale)
+8 QSystemLocale::~QSystemLocale
+12 QSystemLocale::~QSystemLocale
+16 QSystemLocale::query
+20 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=4 align=4
+ base size=4 base align=4
+QSystemLocale (0xb5726bb8) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 8u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0xb5726c30) 0
+
+Class QLocale
+ size=4 align=4
+ base size=4 base align=4
+QLocale (0xb5726bf4) 0
+
+Class QTextCodec::ConverterState
+ size=28 align=4
+ base size=28 base align=4
+QTextCodec::ConverterState (0xb549c294) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTextCodec)
+8 __cxa_pure_virtual
+12 QTextCodec::aliases
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QTextCodec::~QTextCodec
+32 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=4 align=4
+ base size=4 base align=4
+QTextCodec (0xb549c258) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 8u)
+
+Class QTextEncoder
+ size=32 align=4
+ base size=32 base align=4
+QTextEncoder (0xb549ce88) 0
+
+Class QTextDecoder
+ size=32 align=4
+ base size=32 base align=4
+QTextDecoder (0xb54e90f0) 0
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb54e9474) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb54e94b0) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTextStream)
+8 QTextStream::~QTextStream
+12 QTextStream::~QTextStream
+
+Class QTextStream
+ size=8 align=4
+ base size=8 base align=4
+QTextStream (0xb54e9528) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 8u)
+
+Class QTextStreamManipulator
+ size=24 align=4
+ base size=22 base align=4
+QTextStreamManipulator (0xb54e9b04) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextIStream)
+8 QTextIStream::~QTextIStream
+12 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=8 align=4
+ base size=8 base align=4
+QTextIStream (0xb553b780) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 8u)
+ QTextStream (0xb554dc30) 0
+ primary-for QTextIStream (0xb553b780)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextOStream)
+8 QTextOStream::~QTextOStream
+12 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=8 align=4
+ base size=8 base align=4
+QTextOStream (0xb553ba40) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 8u)
+ QTextStream (0xb555f2d0) 0
+ primary-for QTextOStream (0xb553ba40)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb555f960) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb555fb04) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb555fb40) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb555fbf4) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb555ff00) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb555ff3c) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb555ff78) 0
+
+Class QDebug::Stream
+ size=24 align=4
+ base size=22 base align=4
+QDebug::Stream (0xb55942d0) 0
+
+Class QDebug
+ size=4 align=4
+ base size=4 base align=4
+QDebug (0xb5594294) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0xb5470d98) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb52a5180) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb52a51c0) 0
+ primary-for QFile (0xb52a5180)
+ QObject (0xb52aa03c) 0
+ primary-for QIODevice (0xb52a51c0)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QTemporaryFile)
+8 QTemporaryFile::metaObject
+12 QTemporaryFile::qt_metacast
+16 QTemporaryFile::qt_metacall
+20 QTemporaryFile::~QTemporaryFile
+24 QTemporaryFile::~QTemporaryFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QTemporaryFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=8 align=4
+ base size=8 base align=4
+QTemporaryFile (0xb52a5780) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 8u)
+ QFile (0xb52a57c0) 0
+ primary-for QTemporaryFile (0xb52a5780)
+ QIODevice (0xb52a5800) 0
+ primary-for QFile (0xb52a57c0)
+ QObject (0xb52aa4b0) 0
+ primary-for QIODevice (0xb52a5800)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb52aa7bc) 0
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb52aad5c) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb5341708) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb5309900) 0
+ QList<QString> (0xb5341870) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb5371dd4) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0xb51bf4b0) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0xb51bf4ec) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=20 align=4
+ base size=20 base align=4
+QAbstractFileEngine::MapExtensionOption (0xb51db1c0) 0
+ QAbstractFileEngine::ExtensionOption (0xb51bf528) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::MapExtensionReturn (0xb51db240) 0
+ QAbstractFileEngine::ExtensionReturn (0xb51bf564) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::UnMapExtensionOption (0xb51db2c0) 0
+ QAbstractFileEngine::ExtensionOption (0xb51bf5a0) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+8 QAbstractFileEngine::~QAbstractFileEngine
+12 QAbstractFileEngine::~QAbstractFileEngine
+16 QAbstractFileEngine::open
+20 QAbstractFileEngine::close
+24 QAbstractFileEngine::flush
+28 QAbstractFileEngine::size
+32 QAbstractFileEngine::pos
+36 QAbstractFileEngine::seek
+40 QAbstractFileEngine::isSequential
+44 QAbstractFileEngine::remove
+48 QAbstractFileEngine::copy
+52 QAbstractFileEngine::rename
+56 QAbstractFileEngine::link
+60 QAbstractFileEngine::mkdir
+64 QAbstractFileEngine::rmdir
+68 QAbstractFileEngine::setSize
+72 QAbstractFileEngine::caseSensitive
+76 QAbstractFileEngine::isRelativePath
+80 QAbstractFileEngine::entryList
+84 QAbstractFileEngine::fileFlags
+88 QAbstractFileEngine::setPermissions
+92 QAbstractFileEngine::fileName
+96 QAbstractFileEngine::ownerId
+100 QAbstractFileEngine::owner
+104 QAbstractFileEngine::fileTime
+108 QAbstractFileEngine::setFileName
+112 QAbstractFileEngine::handle
+116 QAbstractFileEngine::beginEntryList
+120 QAbstractFileEngine::endEntryList
+124 QAbstractFileEngine::read
+128 QAbstractFileEngine::readLine
+132 QAbstractFileEngine::write
+136 QAbstractFileEngine::extension
+140 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngine (0xb51bf474) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 8u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+8 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+12 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+16 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngineHandler (0xb51bf744) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 8u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+8 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+12 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QAbstractFileEngineIterator::currentFileInfo
+32 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngineIterator (0xb51bf780) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 8u)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QFSFileEngine)
+8 QFSFileEngine::~QFSFileEngine
+12 QFSFileEngine::~QFSFileEngine
+16 QFSFileEngine::open
+20 QFSFileEngine::close
+24 QFSFileEngine::flush
+28 QFSFileEngine::size
+32 QFSFileEngine::pos
+36 QFSFileEngine::seek
+40 QFSFileEngine::isSequential
+44 QFSFileEngine::remove
+48 QFSFileEngine::copy
+52 QFSFileEngine::rename
+56 QFSFileEngine::link
+60 QFSFileEngine::mkdir
+64 QFSFileEngine::rmdir
+68 QFSFileEngine::setSize
+72 QFSFileEngine::caseSensitive
+76 QFSFileEngine::isRelativePath
+80 QFSFileEngine::entryList
+84 QFSFileEngine::fileFlags
+88 QFSFileEngine::setPermissions
+92 QFSFileEngine::fileName
+96 QFSFileEngine::ownerId
+100 QFSFileEngine::owner
+104 QFSFileEngine::fileTime
+108 QFSFileEngine::setFileName
+112 QFSFileEngine::handle
+116 QFSFileEngine::beginEntryList
+120 QFSFileEngine::endEntryList
+124 QFSFileEngine::read
+128 QFSFileEngine::readLine
+132 QFSFileEngine::write
+136 QFSFileEngine::extension
+140 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QFSFileEngine (0xb51db5c0) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 8u)
+ QAbstractFileEngine (0xb51bf7bc) 0
+ primary-for QFSFileEngine (0xb51db5c0)
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QProcess)
+8 QProcess::metaObject
+12 QProcess::qt_metacast
+16 QProcess::qt_metacall
+20 QProcess::~QProcess
+24 QProcess::~QProcess
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QProcess::isSequential
+60 QIODevice::open
+64 QProcess::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QProcess::atEnd
+84 QIODevice::reset
+88 QProcess::bytesAvailable
+92 QProcess::bytesToWrite
+96 QProcess::canReadLine
+100 QProcess::waitForReadyRead
+104 QProcess::waitForBytesWritten
+108 QProcess::readData
+112 QIODevice::readLineData
+116 QProcess::writeData
+120 QProcess::setupChildProcess
+
+Class QProcess
+ size=8 align=4
+ base size=8 base align=4
+QProcess (0xb51db6c0) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 8u)
+ QIODevice (0xb51db700) 0
+ primary-for QProcess (0xb51db6c0)
+ QObject (0xb51bf8e8) 0
+ primary-for QIODevice (0xb51db700)
+
+Class QResource
+ size=4 align=4
+ base size=4 base align=4
+QResource (0xb51bfb04) 0
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QDirIterator)
+8 QDirIterator::~QDirIterator
+12 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=8 align=4
+ base size=8 base align=4
+QDirIterator (0xb51bfbf4) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 8u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QBuffer)
+8 QBuffer::metaObject
+12 QBuffer::qt_metacast
+16 QBuffer::qt_metacall
+20 QBuffer::~QBuffer
+24 QBuffer::~QBuffer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QBuffer::connectNotify
+52 QBuffer::disconnectNotify
+56 QIODevice::isSequential
+60 QBuffer::open
+64 QBuffer::close
+68 QBuffer::pos
+72 QBuffer::size
+76 QBuffer::seek
+80 QBuffer::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QBuffer::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QBuffer::readData
+112 QIODevice::readLineData
+116 QBuffer::writeData
+
+Class QBuffer
+ size=8 align=4
+ base size=8 base align=4
+QBuffer (0xb51dbc80) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 8u)
+ QIODevice (0xb51dbcc0) 0
+ primary-for QBuffer (0xb51dbc80)
+ QObject (0xb51bfd20) 0
+ primary-for QIODevice (0xb51dbcc0)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+8 QFileSystemWatcher::metaObject
+12 QFileSystemWatcher::qt_metacast
+16 QFileSystemWatcher::qt_metacall
+20 QFileSystemWatcher::~QFileSystemWatcher
+24 QFileSystemWatcher::~QFileSystemWatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=8 align=4
+ base size=8 base align=4
+QFileSystemWatcher (0xb51dbfc0) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 8u)
+ QObject (0xb51bff3c) 0
+ primary-for QFileSystemWatcher (0xb51dbfc0)
+
+Class QUrl
+ size=4 align=4
+ base size=4 base align=4
+QUrl (0xb5276168) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb5276744) 0 empty
+
+Class QVariant::PrivateShared
+ size=8 align=4
+ base size=8 base align=4
+QVariant::PrivateShared (0xb51171a4) 0
+
+Class QVariant::Private::Data
+ size=8 align=4
+ base size=8 base align=4
+QVariant::Private::Data (0xb511721c) 0
+
+Class QVariant::Private
+ size=12 align=4
+ base size=12 base align=4
+QVariant::Private (0xb51171e0) 0
+
+Class QVariant::Handler
+ size=36 align=4
+ base size=36 base align=4
+QVariant::Handler (0xb5117258) 0
+
+Class QVariant
+ size=12 align=4
+ base size=12 base align=4
+QVariant (0xb5117168) 0
+
+Class QVariantComparisonHelper
+ size=4 align=4
+ base size=4 base align=4
+QVariantComparisonHelper (0xb5159834) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QSettings)
+8 QSettings::metaObject
+12 QSettings::qt_metacast
+16 QSettings::qt_metacall
+20 QSettings::~QSettings
+24 QSettings::~QSettings
+28 QSettings::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSettings
+ size=8 align=4
+ base size=8 base align=4
+QSettings (0xb4f96ac0) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 8u)
+ QObject (0xb5159ce4) 0
+ primary-for QSettings (0xb4f96ac0)
+
+Class QXmlStreamStringRef
+ size=12 align=4
+ base size=12 base align=4
+QXmlStreamStringRef (0xb4fd77f8) 0
+
+Class QXmlStreamAttribute
+ size=56 align=4
+ base size=53 base align=4
+QXmlStreamAttribute (0xb4ffc4b0) 0
+
+Class QXmlStreamAttributes
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamAttributes (0xb4fddfc0) 0
+ QVector<QXmlStreamAttribute> (0xb4ffcf00) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=28 align=4
+ base size=28 base align=4
+QXmlStreamNamespaceDeclaration (0xb502e000) 0
+
+Class QXmlStreamNotationDeclaration
+ size=40 align=4
+ base size=40 base align=4
+QXmlStreamNotationDeclaration (0xb502e474) 0
+
+Class QXmlStreamEntityDeclaration
+ size=64 align=4
+ base size=64 base align=4
+QXmlStreamEntityDeclaration (0xb502ea50) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+8 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+12 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+16 QXmlStreamEntityResolver::resolveEntity
+20 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamEntityResolver (0xb505830c) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 8u)
+
+Class QXmlStreamReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamReader (0xb5058348) 0
+
+Class QXmlStreamWriter
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamWriter (0xb50583fc) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb5058528) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb4eaeac8) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb4ed81e0) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb4ed8f00) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb4f27000) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb4f41a8c) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb4f6a690) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb4dd42d0) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0xb4e2d03c) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+8 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+12 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+16 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=12 align=4
+ base size=12 base align=4
+QtSharedPointer::ExternalRefCountData (0xb4e2d30c) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 8u)
+
+Class QLinkedListData
+ size=20 align=4
+ base size=20 base align=4
+QLinkedListData (0xb4e2dc30) 0
+
+Class QBitArray
+ size=4 align=4
+ base size=4 base align=4
+QBitArray (0xb4e2de4c) 0
+
+Class QBitRef
+ size=8 align=4
+ base size=8 base align=4
+QBitRef (0xb4d36384) 0
+
+Class QByteArrayMatcher
+ size=1032 align=4
+ base size=1032 base align=4
+QByteArrayMatcher (0xb4d36a50) 0
+
+Class QCryptographicHash
+ size=4 align=4
+ base size=4 base align=4
+QCryptographicHash (0xb4d36c30) 0
+
+Class QTextBoundaryFinder
+ size=28 align=4
+ base size=28 base align=4
+QTextBoundaryFinder (0xb4d36ca8) 0
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0xb4d36d5c) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0xb4d88384) 0
+
+Class QDateTime
+ size=4 align=4
+ base size=4 base align=4
+QDateTime (0xb4d888e8) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTimeLine)
+8 QTimeLine::metaObject
+12 QTimeLine::qt_metacast
+16 QTimeLine::qt_metacall
+20 QTimeLine::~QTimeLine
+24 QTimeLine::~QTimeLine
+28 QObject::event
+32 QObject::eventFilter
+36 QTimeLine::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=8 align=4
+ base size=8 base align=4
+QTimeLine (0xb4bbb000) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 8u)
+ QObject (0xb4d88b7c) 0
+ primary-for QTimeLine (0xb4bbb000)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QRunnable)
+8 __cxa_pure_virtual
+12 QRunnable::~QRunnable
+16 QRunnable::~QRunnable
+
+Class QRunnable
+ size=8 align=4
+ base size=8 base align=4
+QRunnable (0xb4d88d98) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 8u)
+
+Class QMutex
+ size=4 align=4
+ base size=4 base align=4
+QMutex (0xb4bd021c) 0
+
+Class QMutexLocker
+ size=4 align=4
+ base size=4 base align=4
+QMutexLocker (0xb4bd08ac) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+8 QtConcurrent::Exception::~Exception
+12 QtConcurrent::Exception::~Exception
+16 std::exception::what
+20 QtConcurrent::Exception::raise
+24 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::Exception (0xb4bbbf80) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 8u)
+ std::exception (0xb4bd0d98) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb4bbbf80)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+8 QtConcurrent::UnhandledException::~UnhandledException
+12 QtConcurrent::UnhandledException::~UnhandledException
+16 std::exception::what
+20 QtConcurrent::UnhandledException::raise
+24 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::UnhandledException (0xb4be6080) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 8u)
+ QtConcurrent::Exception (0xb4be60c0) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0xb4be6080)
+ std::exception (0xb4bd0dd4) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb4be60c0)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionHolder (0xb4bd0e10) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionStore (0xb4bd0e4c) 0
+
+Class QtConcurrent::ResultItem
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultItem (0xb4bd0e88) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultIteratorBase (0xb4bf1474) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+8 QtConcurrent::ResultStoreBase::~ResultStoreBase
+12 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=28 align=4
+ base size=28 base align=4
+QtConcurrent::ResultStoreBase (0xb4bf15a0) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 8u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+8 QFutureInterfaceBase::~QFutureInterfaceBase
+12 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureInterfaceBase (0xb4bf19d8) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 8u)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QThread)
+8 QThread::metaObject
+12 QThread::qt_metacast
+16 QThread::qt_metacall
+20 QThread::~QThread
+24 QThread::~QThread
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QThread::run
+
+Class QThread
+ size=8 align=4
+ base size=8 base align=4
+QThread (0xb4a9c0c0) 0
+ vptr=((& QThread::_ZTV7QThread) + 8u)
+ QObject (0xb4c8a6cc) 0
+ primary-for QThread (0xb4a9c0c0)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QThreadPool)
+8 QThreadPool::metaObject
+12 QThreadPool::qt_metacast
+16 QThreadPool::qt_metacall
+20 QThreadPool::~QThreadPool
+24 QThreadPool::~QThreadPool
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QThreadPool
+ size=8 align=4
+ base size=8 base align=4
+QThreadPool (0xb4a9c400) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 8u)
+ QObject (0xb4c8a960) 0
+ primary-for QThreadPool (0xb4a9c400)
+
+Class QWaitCondition
+ size=4 align=4
+ base size=4 base align=4
+QWaitCondition (0xb4c8abb8) 0
+
+Class QtConcurrent::ThreadEngineSemaphore
+ size=12 align=4
+ base size=12 base align=4
+QtConcurrent::ThreadEngineSemaphore (0xb4c8abf4) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+8 QtConcurrent::ThreadEngineBase::run
+12 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+16 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+20 QtConcurrent::ThreadEngineBase::start
+24 QtConcurrent::ThreadEngineBase::finish
+28 QtConcurrent::ThreadEngineBase::threadFunction
+32 QtConcurrent::ThreadEngineBase::shouldStartThread
+36 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+40 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=32 align=4
+ base size=32 base align=4
+QtConcurrent::ThreadEngineBase (0xb4a9cf40) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 8u)
+ QRunnable (0xb4ac4474) 0
+ primary-for QtConcurrent::ThreadEngineBase (0xb4a9cf40)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 12u)
+4 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 68u)
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0xb4ae6a50) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0xb4ae6a8c) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0xb4ae8500) 0 empty
+ std::input_iterator_tag (0xb4ae6ac8) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0xb4ae8580) 0 empty
+ std::forward_iterator_tag (0xb4ae85c0) 0 empty
+ std::input_iterator_tag (0xb4ae6b04) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0xb4ae8640) 0 empty
+ std::bidirectional_iterator_tag (0xb4ae8680) 0 empty
+ std::forward_iterator_tag (0xb4ae86c0) 0 empty
+ std::input_iterator_tag (0xb4ae6b40) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0xb4ae6c6c) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0xb4ae6ca8) 0 empty
+
+Class lconv
+ size=56 align=4
+ base size=56 base align=4
+lconv (0xb49a5e88) 0
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0xb49fd03c) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0xb49fd078) 0
+
+Class tm
+ size=44 align=4
+ base size=44 base align=4
+tm (0xb49fd0f0) 0
+
+Class itimerspec
+ size=16 align=4
+ base size=16 base align=4
+itimerspec (0xb49fd12c) 0
+
+Class _pthread_cleanup_buffer
+ size=16 align=4
+ base size=16 base align=4
+_pthread_cleanup_buffer (0xb49fd168) 0
+
+Class __pthread_cleanup_frame
+ size=16 align=4
+ base size=16 base align=4
+__pthread_cleanup_frame (0xb49fd21c) 0
+
+Class __pthread_cleanup_class
+ size=16 align=4
+ base size=16 base align=4
+__pthread_cleanup_class (0xb49fd258) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+8 __cxxabiv1::__forced_unwind::~__forced_unwind
+12 __cxxabiv1::__forced_unwind::~__forced_unwind
+16 __cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=4 align=4
+ base size=4 base align=4
+__cxxabiv1::__forced_unwind (0xb4a7d564) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 8u)
+
+Class std::locale
+ size=4 align=4
+ base size=4 base align=4
+std::locale (0xb48e399c) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTINSt6locale5facetE)
+8 std::locale::facet::~facet
+12 std::locale::facet::~facet
+
+Class std::locale::facet
+ size=8 align=4
+ base size=8 base align=4
+std::locale::facet (0xb48e3a14) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 8u)
+
+Class std::locale::id
+ size=4 align=4
+ base size=4 base align=4
+std::locale::id (0xb48e3e10) 0
+
+Class std::locale::_Impl
+ size=20 align=4
+ base size=20 base align=4
+std::locale::_Impl (0xb48e3e4c) 0
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTINSt8ios_base7failureE)
+8 std::ios_base::failure::~failure
+12 std::ios_base::failure::~failure
+16 std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=8 align=4
+ base size=8 base align=4
+std::ios_base::failure (0xb4696a00) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureE) + 8u)
+ std::exception (0xb46ab1a4) 0 nearly-empty
+ primary-for std::ios_base::failure (0xb4696a00)
+
+Class std::ios_base::_Callback_list
+ size=16 align=4
+ base size=16 base align=4
+std::ios_base::_Callback_list (0xb46ab1e0) 0
+
+Class std::ios_base::_Words
+ size=8 align=4
+ base size=8 base align=4
+std::ios_base::_Words (0xb46ab21c) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0xb46ab258) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt8ios_base)
+8 std::ios_base::~ios_base
+12 std::ios_base::~ios_base
+
+Class std::ios_base
+ size=112 align=4
+ base size=112 base align=4
+std::ios_base (0xb46ab168) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 8u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0xb46ce5a0) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0xb4590078) 0 empty
+
+VTT for std::basic_ostream<char, std::char_traits<char> >
+std::basic_ostream<char, std::char_traits<char> >::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 12u)
+4 ((& std::basic_ostream<char, std::char_traits<char> >::_ZTVSo) + 32u)
+
+VTT for std::basic_ostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 32u)
+
+VTT for std::basic_istream<char, std::char_traits<char> >
+std::basic_istream<char, std::char_traits<char> >::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 12u)
+4 ((& std::basic_istream<char, std::char_traits<char> >::_ZTVSi) + 32u)
+
+VTT for std::basic_istream<wchar_t, std::char_traits<wchar_t> >
+std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 32u)
+
+Construction vtable for std::basic_istream<char, std::char_traits<char> > (0xb454f440 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si: 10u entries
+0 12u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISi)
+12 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+16 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = char, _Traits = std::char_traits<char>]
+20 -12u
+24 (int (*)(...))-0x00000000c
+28 (int (*)(...))(& _ZTISi)
+32 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n12_NSiD1Ev
+36 std::basic_istream<char, std::char_traits<char> >::_ZTv0_n12_NSiD0Ev
+
+Construction vtable for std::basic_ostream<char, std::char_traits<char> > (0xb454f4c0 instance) in std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So: 10u entries
+0 4u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISo)
+12 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+16 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = char, _Traits = std::char_traits<char>]
+20 -4u
+24 (int (*)(...))-0x000000004
+28 (int (*)(...))(& _ZTISo)
+32 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n12_NSoD1Ev
+36 std::basic_ostream<char, std::char_traits<char> >::_ZTv0_n12_NSoD0Ev
+
+VTT for std::basic_iostream<char, std::char_traits<char> >
+std::basic_iostream<char, std::char_traits<char> >::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 12u)
+4 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 12u)
+8 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd0_Si) + 32u)
+12 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So) + 12u)
+16 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTCSd8_So) + 32u)
+20 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 52u)
+24 ((& std::basic_iostream<char, std::char_traits<char> >::_ZTVSd) + 32u)
+
+Construction vtable for std::basic_istream<wchar_t, std::char_traits<wchar_t> > (0xb454f7c0 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 12u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+12 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+16 std::basic_istream<_CharT, _Traits>::~basic_istream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+20 -12u
+24 (int (*)(...))-0x00000000c
+28 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+32 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED1Ev
+36 std::basic_istream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_istreamIwSt11char_traitsIwEED0Ev
+
+Construction vtable for std::basic_ostream<wchar_t, std::char_traits<wchar_t> > (0xb454f840 instance) in std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E: 10u entries
+0 4u
+4 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+12 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+16 std::basic_ostream<_CharT, _Traits>::~basic_ostream [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>]
+20 -4u
+24 (int (*)(...))-0x000000004
+28 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+32 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev
+36 std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::_ZTv0_n12_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev
+
+VTT for std::basic_iostream<wchar_t, std::char_traits<wchar_t> >
+std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 12u)
+4 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 12u)
+8 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 32u)
+12 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E) + 12u)
+16 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE8_St13basic_ostreamIwS1_E) + 32u)
+20 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 52u)
+24 ((& std::basic_iostream<wchar_t, std::char_traits<wchar_t> >::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 32u)
+
+Class QtConcurrent::BlockSizeManager
+ size=72 align=4
+ base size=72 base align=4
+QtConcurrent::BlockSizeManager (0xb456012c) 0
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+8 QFutureWatcherBase::metaObject
+12 QFutureWatcherBase::qt_metacast
+16 QFutureWatcherBase::qt_metacall
+20 QFutureWatcherBase::~QFutureWatcherBase
+24 QFutureWatcherBase::~QFutureWatcherBase
+28 QFutureWatcherBase::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QFutureWatcherBase::connectNotify
+52 QFutureWatcherBase::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureWatcherBase (0xb416ea00) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 8u)
+ QObject (0xb431b924) 0
+ primary-for QFutureWatcherBase (0xb416ea00)
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QFactoryInterface)
+8 QFactoryInterface::~QFactoryInterface
+12 QFactoryInterface::~QFactoryInterface
+16 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QFactoryInterface (0xb41e0744) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 8u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+8 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+12 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QTextCodecFactoryInterface (0xb420dc00) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 8u)
+ QFactoryInterface (0xb41e0c30) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb420dc00)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+8 QTextCodecPlugin::metaObject
+12 QTextCodecPlugin::qt_metacast
+16 QTextCodecPlugin::qt_metacall
+20 QTextCodecPlugin::~QTextCodecPlugin
+24 QTextCodecPlugin::~QTextCodecPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 QTextCodecPlugin::keys
+80 QTextCodecPlugin::create
+84 (int (*)(...))-0x000000008
+88 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+92 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD1Ev
+96 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD0Ev
+100 QTextCodecPlugin::_ZThn8_NK16QTextCodecPlugin4keysEv
+104 QTextCodecPlugin::_ZThn8_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=12 align=4
+ base size=12 base align=4
+QTextCodecPlugin (0xb421aa50) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 8u)
+ QObject (0xb41e0ec4) 0
+ primary-for QTextCodecPlugin (0xb421aa50)
+ QTextCodecFactoryInterface (0xb420de00) 8 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 92u)
+ QFactoryInterface (0xb41e0f00) 8 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb420de00)
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0xb422c03c) 0 empty
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTranslator)
+8 QTranslator::metaObject
+12 QTranslator::qt_metacast
+16 QTranslator::qt_metacall
+20 QTranslator::~QTranslator
+24 QTranslator::~QTranslator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTranslator::translate
+60 QTranslator::isEmpty
+
+Class QTranslator
+ size=8 align=4
+ base size=8 base align=4
+QTranslator (0xb42459c0) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 8u)
+ QObject (0xb42403fc) 0
+ primary-for QTranslator (0xb42459c0)
+
+Class __exception
+ size=32 align=4
+ base size=32 base align=4
+__exception (0xb42406cc) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QMimeData)
+8 QMimeData::metaObject
+12 QMimeData::qt_metacast
+16 QMimeData::qt_metacall
+20 QMimeData::~QMimeData
+24 QMimeData::~QMimeData
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QMimeData::hasFormat
+60 QMimeData::formats
+64 QMimeData::retrieveData
+
+Class QMimeData
+ size=8 align=4
+ base size=8 base align=4
+QMimeData (0xb408d340) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 8u)
+ QObject (0xb4240c6c) 0
+ primary-for QMimeData (0xb408d340)
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QEventLoop)
+8 QEventLoop::metaObject
+12 QEventLoop::qt_metacast
+16 QEventLoop::qt_metacall
+20 QEventLoop::~QEventLoop
+24 QEventLoop::~QEventLoop
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QEventLoop
+ size=8 align=4
+ base size=8 base align=4
+QEventLoop (0xb408d600) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 8u)
+ QObject (0xb4240e88) 0
+ primary-for QEventLoop (0xb408d600)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QEvent)
+8 QEvent::~QEvent
+12 QEvent::~QEvent
+
+Class QEvent
+ size=12 align=4
+ base size=12 base align=4
+QEvent (0xb40b31a4) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 8u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTimerEvent)
+8 QTimerEvent::~QTimerEvent
+12 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=16 align=4
+ base size=16 base align=4
+QTimerEvent (0xb408dcc0) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 8u)
+ QEvent (0xb40b3384) 0
+ primary-for QTimerEvent (0xb408dcc0)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QChildEvent)
+8 QChildEvent::~QChildEvent
+12 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=16 align=4
+ base size=16 base align=4
+QChildEvent (0xb408dd80) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 8u)
+ QEvent (0xb40b33fc) 0
+ primary-for QChildEvent (0xb408dd80)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QCustomEvent)
+8 QCustomEvent::~QCustomEvent
+12 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=12 align=4
+ base size=12 base align=4
+QCustomEvent (0xb40e1040) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 8u)
+ QEvent (0xb40b3564) 0
+ primary-for QCustomEvent (0xb40e1040)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+8 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+12 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=16 align=4
+ base size=16 base align=4
+QDynamicPropertyChangeEvent (0xb40e1140) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 8u)
+ QEvent (0xb40b3654) 0
+ primary-for QDynamicPropertyChangeEvent (0xb40e1140)
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QCoreApplication)
+8 QCoreApplication::metaObject
+12 QCoreApplication::qt_metacast
+16 QCoreApplication::qt_metacall
+20 QCoreApplication::~QCoreApplication
+24 QCoreApplication::~QCoreApplication
+28 QCoreApplication::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QCoreApplication::notify
+60 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=8 align=4
+ base size=8 base align=4
+QCoreApplication (0xb40e1200) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 8u)
+ QObject (0xb40b3708) 0
+ primary-for QCoreApplication (0xb40e1200)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSharedMemory)
+8 QSharedMemory::metaObject
+12 QSharedMemory::qt_metacast
+16 QSharedMemory::qt_metacall
+20 QSharedMemory::~QSharedMemory
+24 QSharedMemory::~QSharedMemory
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=8 align=4
+ base size=8 base align=4
+QSharedMemory (0xb40e1800) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 8u)
+ QObject (0xb40b3ca8) 0
+ primary-for QSharedMemory (0xb40e1800)
+
+Class QModelIndex
+ size=16 align=4
+ base size=16 base align=4
+QModelIndex (0xb40b3ec4) 0
+
+Class QPersistentModelIndex
+ size=4 align=4
+ base size=4 base align=4
+QPersistentModelIndex (0xb411e384) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractItemModel)
+8 QAbstractItemModel::metaObject
+12 QAbstractItemModel::qt_metacast
+16 QAbstractItemModel::qt_metacall
+20 QAbstractItemModel::~QAbstractItemModel
+24 QAbstractItemModel::~QAbstractItemModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractItemModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemModel (0xb411c440) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 8u)
+ QObject (0xb411e4ec) 0
+ primary-for QAbstractItemModel (0xb411c440)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTableModel)
+8 QAbstractTableModel::metaObject
+12 QAbstractTableModel::qt_metacast
+16 QAbstractTableModel::qt_metacall
+20 QAbstractTableModel::~QAbstractTableModel
+24 QAbstractTableModel::~QAbstractTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractTableModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTableModel (0xb411ca80) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 8u)
+ QAbstractItemModel (0xb411cac0) 0
+ primary-for QAbstractTableModel (0xb411ca80)
+ QObject (0xb411ee4c) 0
+ primary-for QAbstractItemModel (0xb411cac0)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractListModel)
+8 QAbstractListModel::metaObject
+12 QAbstractListModel::qt_metacast
+16 QAbstractListModel::qt_metacall
+20 QAbstractListModel::~QAbstractListModel
+24 QAbstractListModel::~QAbstractListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 __cxa_pure_virtual
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractListModel (0xb411cd00) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 8u)
+ QAbstractItemModel (0xb411cd40) 0
+ primary-for QAbstractListModel (0xb411cd00)
+ QObject (0xb411ef78) 0
+ primary-for QAbstractItemModel (0xb411cd40)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSignalMapper)
+8 QSignalMapper::metaObject
+12 QSignalMapper::qt_metacast
+16 QSignalMapper::qt_metacall
+20 QSignalMapper::~QSignalMapper
+24 QSignalMapper::~QSignalMapper
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=8 align=4
+ base size=8 base align=4
+QSignalMapper (0xb3f6e440) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 8u)
+ QObject (0xb3f6be4c) 0
+ primary-for QSignalMapper (0xb3f6e440)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+8 QObjectCleanupHandler::metaObject
+12 QObjectCleanupHandler::qt_metacast
+16 QObjectCleanupHandler::qt_metacall
+20 QObjectCleanupHandler::~QObjectCleanupHandler
+24 QObjectCleanupHandler::~QObjectCleanupHandler
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=12 align=4
+ base size=12 base align=4
+QObjectCleanupHandler (0xb3f6e700) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 8u)
+ QObject (0xb3f89078) 0
+ primary-for QObjectCleanupHandler (0xb3f6e700)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0xb3f891a4) 0
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QSocketNotifier)
+8 QSocketNotifier::metaObject
+12 QSocketNotifier::qt_metacast
+16 QSocketNotifier::qt_metacall
+20 QSocketNotifier::~QSocketNotifier
+24 QSocketNotifier::~QSocketNotifier
+28 QSocketNotifier::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=20 align=4
+ base size=17 base align=4
+QSocketNotifier (0xb3f6ed00) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 8u)
+ QObject (0xb3f89438) 0
+ primary-for QSocketNotifier (0xb3f6ed00)
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QTimer)
+8 QTimer::metaObject
+12 QTimer::qt_metacast
+16 QTimer::qt_metacall
+20 QTimer::~QTimer
+24 QTimer::~QTimer
+28 QObject::event
+32 QObject::eventFilter
+36 QTimer::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QTimer
+ size=24 align=4
+ base size=21 base align=4
+QTimer (0xb3faa080) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 8u)
+ QObject (0xb3f89708) 0
+ primary-for QTimer (0xb3faa080)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+8 QAbstractEventDispatcher::metaObject
+12 QAbstractEventDispatcher::qt_metacast
+16 QAbstractEventDispatcher::qt_metacall
+20 QAbstractEventDispatcher::~QAbstractEventDispatcher
+24 QAbstractEventDispatcher::~QAbstractEventDispatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 QAbstractEventDispatcher::startingUp
+104 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=8 align=4
+ base size=8 base align=4
+QAbstractEventDispatcher (0xb3faa580) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 8u)
+ QObject (0xb3f8999c) 0
+ primary-for QAbstractEventDispatcher (0xb3faa580)
+
+Class QMetaMethod
+ size=8 align=4
+ base size=8 base align=4
+QMetaMethod (0xb3f89bb8) 0
+
+Class QMetaEnum
+ size=8 align=4
+ base size=8 base align=4
+QMetaEnum (0xb3f89ec4) 0
+
+Class QMetaProperty
+ size=20 align=4
+ base size=20 base align=4
+QMetaProperty (0xb3fdd12c) 0
+
+Class QMetaClassInfo
+ size=8 align=4
+ base size=8 base align=4
+QMetaClassInfo (0xb3fdd1e0) 0
+
+Class QSystemSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSystemSemaphore (0xb3fdd438) 0
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QLibrary)
+8 QLibrary::metaObject
+12 QLibrary::qt_metacast
+16 QLibrary::qt_metacall
+20 QLibrary::~QLibrary
+24 QLibrary::~QLibrary
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QLibrary
+ size=16 align=4
+ base size=13 base align=4
+QLibrary (0xb3feb080) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 8u)
+ QObject (0xb3fdd4b0) 0
+ primary-for QLibrary (0xb3feb080)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QPluginLoader)
+8 QPluginLoader::metaObject
+12 QPluginLoader::qt_metacast
+16 QPluginLoader::qt_metacall
+20 QPluginLoader::~QPluginLoader
+24 QPluginLoader::~QPluginLoader
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=16 align=4
+ base size=13 base align=4
+QPluginLoader (0xb3feb480) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 8u)
+ QObject (0xb3fdd708) 0
+ primary-for QPluginLoader (0xb3feb480)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0xb3fdd834) 0
+
+Class QSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSemaphore (0xb402e834) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0xb402e870) 0
+
+Class QReadWriteLock
+ size=4 align=4
+ base size=4 base align=4
+QReadWriteLock (0xb402e8e8) 0
+
+Class QReadLocker
+ size=4 align=4
+ base size=4 base align=4
+QReadLocker (0xb402e924) 0
+
+Class QWriteLocker
+ size=4 align=4
+ base size=4 base align=4
+QWriteLocker (0xb402ee10) 0
+
+Class QSqlRecord
+ size=4 align=4
+ base size=4 base align=4
+QSqlRecord (0xb405a30c) 0
+
+Class QSqlIndex
+ size=16 align=4
+ base size=16 base align=4
+QSqlIndex (0xb4059500) 0
+ QSqlRecord (0xb405a3c0) 0
+
+Vtable for QSqlResult
+QSqlResult::_ZTV10QSqlResult: 29u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QSqlResult)
+8 QSqlResult::~QSqlResult
+12 QSqlResult::~QSqlResult
+16 QSqlResult::handle
+20 QSqlResult::setAt
+24 QSqlResult::setActive
+28 QSqlResult::setLastError
+32 QSqlResult::setQuery
+36 QSqlResult::setSelect
+40 QSqlResult::setForwardOnly
+44 QSqlResult::exec
+48 QSqlResult::prepare
+52 QSqlResult::savePrepare
+56 QSqlResult::bindValue
+60 QSqlResult::bindValue
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QSqlResult::fetchNext
+84 QSqlResult::fetchPrevious
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 QSqlResult::record
+108 QSqlResult::lastInsertId
+112 QSqlResult::virtual_hook
+
+Class QSqlResult
+ size=8 align=4
+ base size=8 base align=4
+QSqlResult (0xb405a654) 0
+ vptr=((& QSqlResult::_ZTV10QSqlResult) + 8u)
+
+Vtable for QSqlDriverCreatorBase
+QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QSqlDriverCreatorBase)
+8 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+12 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+16 __cxa_pure_virtual
+
+Class QSqlDriverCreatorBase
+ size=4 align=4
+ base size=4 base align=4
+QSqlDriverCreatorBase (0xb405a6cc) 0 nearly-empty
+ vptr=((& QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase) + 8u)
+
+Class QSqlDatabase
+ size=4 align=4
+ base size=4 base align=4
+QSqlDatabase (0xb405a924) 0
+
+Class QSqlQuery
+ size=4 align=4
+ base size=4 base align=4
+QSqlQuery (0xb405a99c) 0
+
+Vtable for QSqlDriverFactoryInterface
+QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QSqlDriverFactoryInterface)
+8 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+12 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QSqlDriverFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QSqlDriverFactoryInterface (0xb4059c80) 0 nearly-empty
+ vptr=((& QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface) + 8u)
+ QFactoryInterface (0xb405aa14) 0 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0xb4059c80)
+
+Vtable for QSqlDriverPlugin
+QSqlDriverPlugin::_ZTV16QSqlDriverPlugin: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+8 QSqlDriverPlugin::metaObject
+12 QSqlDriverPlugin::qt_metacast
+16 QSqlDriverPlugin::qt_metacall
+20 QSqlDriverPlugin::~QSqlDriverPlugin
+24 QSqlDriverPlugin::~QSqlDriverPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 (int (*)(...))-0x000000008
+68 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+72 QSqlDriverPlugin::_ZThn8_N16QSqlDriverPluginD1Ev
+76 QSqlDriverPlugin::_ZThn8_N16QSqlDriverPluginD0Ev
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+
+Class QSqlDriverPlugin
+ size=12 align=4
+ base size=12 base align=4
+QSqlDriverPlugin (0xb3eca320) 0
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 8u)
+ QObject (0xb405aca8) 0
+ primary-for QSqlDriverPlugin (0xb3eca320)
+ QSqlDriverFactoryInterface (0xb4059e80) 8 nearly-empty
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 72u)
+ QFactoryInterface (0xb405ace4) 8 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0xb4059e80)
+
+Vtable for QSqlDriver
+QSqlDriver::_ZTV10QSqlDriver: 32u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QSqlDriver)
+8 QSqlDriver::metaObject
+12 QSqlDriver::qt_metacast
+16 QSqlDriver::qt_metacall
+20 QSqlDriver::~QSqlDriver
+24 QSqlDriver::~QSqlDriver
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSqlDriver::isOpen
+60 QSqlDriver::beginTransaction
+64 QSqlDriver::commitTransaction
+68 QSqlDriver::rollbackTransaction
+72 QSqlDriver::tables
+76 QSqlDriver::primaryIndex
+80 QSqlDriver::record
+84 QSqlDriver::formatValue
+88 QSqlDriver::escapeIdentifier
+92 QSqlDriver::sqlStatement
+96 QSqlDriver::handle
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 QSqlDriver::setOpen
+120 QSqlDriver::setOpenError
+124 QSqlDriver::setLastError
+
+Class QSqlDriver
+ size=8 align=4
+ base size=8 base align=4
+QSqlDriver (0xb3ed00c0) 0
+ vptr=((& QSqlDriver::_ZTV10QSqlDriver) + 8u)
+ QObject (0xb405ae10) 0
+ primary-for QSqlDriver (0xb3ed00c0)
+
+Class QSqlError
+ size=16 align=4
+ base size=16 base align=4
+QSqlError (0xb3eea294) 0
+
+Class QSqlField
+ size=16 align=4
+ base size=16 base align=4
+QSqlField (0xb3eea2d0) 0
+
+Vtable for QSqlQueryModel
+QSqlQueryModel::_ZTV14QSqlQueryModel: 44u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QSqlQueryModel)
+8 QSqlQueryModel::metaObject
+12 QSqlQueryModel::qt_metacast
+16 QSqlQueryModel::qt_metacall
+20 QSqlQueryModel::~QSqlQueryModel
+24 QSqlQueryModel::~QSqlQueryModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlQueryModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlQueryModel::data
+80 QAbstractItemModel::setData
+84 QSqlQueryModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QSqlQueryModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+168 QSqlQueryModel::clear
+172 QSqlQueryModel::queryChange
+
+Class QSqlQueryModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlQueryModel (0xb3ed06c0) 0
+ vptr=((& QSqlQueryModel::_ZTV14QSqlQueryModel) + 8u)
+ QAbstractTableModel (0xb3ed0700) 0
+ primary-for QSqlQueryModel (0xb3ed06c0)
+ QAbstractItemModel (0xb3ed0740) 0
+ primary-for QAbstractTableModel (0xb3ed0700)
+ QObject (0xb3eea438) 0
+ primary-for QAbstractItemModel (0xb3ed0740)
+
+Vtable for QSqlTableModel
+QSqlTableModel::_ZTV14QSqlTableModel: 55u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QSqlTableModel)
+8 QSqlTableModel::metaObject
+12 QSqlTableModel::qt_metacast
+16 QSqlTableModel::qt_metacall
+20 QSqlTableModel::~QSqlTableModel
+24 QSqlTableModel::~QSqlTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlTableModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlTableModel::data
+80 QSqlTableModel::setData
+84 QSqlTableModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QSqlTableModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QSqlTableModel::removeRows
+128 QSqlTableModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QSqlTableModel::flags
+144 QSqlTableModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QSqlTableModel::submit
+164 QSqlTableModel::revert
+168 QSqlTableModel::clear
+172 QSqlQueryModel::queryChange
+176 QSqlTableModel::select
+180 QSqlTableModel::setTable
+184 QSqlTableModel::setEditStrategy
+188 QSqlTableModel::setSort
+192 QSqlTableModel::setFilter
+196 QSqlTableModel::revertRow
+200 QSqlTableModel::updateRowInTable
+204 QSqlTableModel::insertRowIntoTable
+208 QSqlTableModel::deleteRowFromTable
+212 QSqlTableModel::orderByClause
+216 QSqlTableModel::selectStatement
+
+Class QSqlTableModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlTableModel (0xb3ed0a00) 0
+ vptr=((& QSqlTableModel::_ZTV14QSqlTableModel) + 8u)
+ QSqlQueryModel (0xb3ed0a40) 0
+ primary-for QSqlTableModel (0xb3ed0a00)
+ QAbstractTableModel (0xb3ed0a80) 0
+ primary-for QSqlQueryModel (0xb3ed0a40)
+ QAbstractItemModel (0xb3ed0ac0) 0
+ primary-for QAbstractTableModel (0xb3ed0a80)
+ QObject (0xb3eea654) 0
+ primary-for QAbstractItemModel (0xb3ed0ac0)
+
+Class QSqlRelation
+ size=12 align=4
+ base size=12 base align=4
+QSqlRelation (0xb3eea870) 0
+
+Vtable for QSqlRelationalTableModel
+QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel: 57u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QSqlRelationalTableModel)
+8 QSqlRelationalTableModel::metaObject
+12 QSqlRelationalTableModel::qt_metacast
+16 QSqlRelationalTableModel::qt_metacall
+20 QSqlRelationalTableModel::~QSqlRelationalTableModel
+24 QSqlRelationalTableModel::~QSqlRelationalTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlTableModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlRelationalTableModel::data
+80 QSqlRelationalTableModel::setData
+84 QSqlTableModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QSqlTableModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QSqlTableModel::removeRows
+128 QSqlRelationalTableModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QSqlTableModel::flags
+144 QSqlTableModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QSqlTableModel::submit
+164 QSqlTableModel::revert
+168 QSqlRelationalTableModel::clear
+172 QSqlQueryModel::queryChange
+176 QSqlRelationalTableModel::select
+180 QSqlRelationalTableModel::setTable
+184 QSqlTableModel::setEditStrategy
+188 QSqlTableModel::setSort
+192 QSqlTableModel::setFilter
+196 QSqlRelationalTableModel::revertRow
+200 QSqlRelationalTableModel::updateRowInTable
+204 QSqlRelationalTableModel::insertRowIntoTable
+208 QSqlTableModel::deleteRowFromTable
+212 QSqlRelationalTableModel::orderByClause
+216 QSqlRelationalTableModel::selectStatement
+220 QSqlRelationalTableModel::setRelation
+224 QSqlRelationalTableModel::relationModel
+
+Class QSqlRelationalTableModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlRelationalTableModel (0xb3f32040) 0
+ vptr=((& QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel) + 8u)
+ QSqlTableModel (0xb3f32080) 0
+ primary-for QSqlRelationalTableModel (0xb3f32040)
+ QSqlQueryModel (0xb3f320c0) 0
+ primary-for QSqlTableModel (0xb3f32080)
+ QAbstractTableModel (0xb3f32100) 0
+ primary-for QSqlQueryModel (0xb3f320c0)
+ QAbstractItemModel (0xb3f32140) 0
+ primary-for QAbstractTableModel (0xb3f32100)
+ QObject (0xb3f2c4b0) 0
+ primary-for QAbstractItemModel (0xb3f32140)
+
+Class QDomImplementation
+ size=4 align=4
+ base size=4 base align=4
+QDomImplementation (0xb3f2c6cc) 0
+
+Class QDomNode
+ size=4 align=4
+ base size=4 base align=4
+QDomNode (0xb3f2c708) 0
+
+Class QDomNodeList
+ size=4 align=4
+ base size=4 base align=4
+QDomNodeList (0xb3f2c744) 0
+
+Class QDomDocumentType
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentType (0xb3f32600) 0
+ QDomNode (0xb3f2c834) 0
+
+Class QDomDocument
+ size=4 align=4
+ base size=4 base align=4
+QDomDocument (0xb3f326c0) 0
+ QDomNode (0xb3f2c8ac) 0
+
+Class QDomNamedNodeMap
+ size=4 align=4
+ base size=4 base align=4
+QDomNamedNodeMap (0xb3f2c924) 0
+
+Class QDomDocumentFragment
+ size=4 align=4
+ base size=4 base align=4
+QDomDocumentFragment (0xb3f328c0) 0
+ QDomNode (0xb3f2c9d8) 0
+
+Class QDomCharacterData
+ size=4 align=4
+ base size=4 base align=4
+QDomCharacterData (0xb3f32980) 0
+ QDomNode (0xb3f2ca50) 0
+
+Class QDomAttr
+ size=4 align=4
+ base size=4 base align=4
+QDomAttr (0xb3f32a00) 0
+ QDomNode (0xb3f2ca8c) 0
+
+Class QDomElement
+ size=4 align=4
+ base size=4 base align=4
+QDomElement (0xb3f32ac0) 0
+ QDomNode (0xb3f2cb04) 0
+
+Class QDomText
+ size=4 align=4
+ base size=4 base align=4
+QDomText (0xb3f32c80) 0
+ QDomCharacterData (0xb3f32cc0) 0
+ QDomNode (0xb3f2cc6c) 0
+
+Class QDomComment
+ size=4 align=4
+ base size=4 base align=4
+QDomComment (0xb3f32d80) 0
+ QDomCharacterData (0xb3f32dc0) 0
+ QDomNode (0xb3f2cce4) 0
+
+Class QDomCDATASection
+ size=4 align=4
+ base size=4 base align=4
+QDomCDATASection (0xb3f32e80) 0
+ QDomText (0xb3f32ec0) 0
+ QDomCharacterData (0xb3f32f00) 0
+ QDomNode (0xb3f2cd5c) 0
+
+Class QDomNotation
+ size=4 align=4
+ base size=4 base align=4
+QDomNotation (0xb3f32fc0) 0
+ QDomNode (0xb3f2cdd4) 0
+
+Class QDomEntity
+ size=4 align=4
+ base size=4 base align=4
+QDomEntity (0xb3d8a080) 0
+ QDomNode (0xb3f2ce4c) 0
+
+Class QDomEntityReference
+ size=4 align=4
+ base size=4 base align=4
+QDomEntityReference (0xb3d8a140) 0
+ QDomNode (0xb3f2cec4) 0
+
+Class QDomProcessingInstruction
+ size=4 align=4
+ base size=4 base align=4
+QDomProcessingInstruction (0xb3d8a200) 0
+ QDomNode (0xb3f2cf3c) 0
+
+Class QXmlNamespaceSupport
+ size=4 align=4
+ base size=4 base align=4
+QXmlNamespaceSupport (0xb3f2cfb4) 0
+
+Class QXmlAttributes::Attribute
+ size=16 align=4
+ base size=16 base align=4
+QXmlAttributes::Attribute (0xb3d9a03c) 0
+
+Vtable for QXmlAttributes
+QXmlAttributes::_ZTV14QXmlAttributes: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlAttributes)
+8 QXmlAttributes::~QXmlAttributes
+12 QXmlAttributes::~QXmlAttributes
+
+Class QXmlAttributes
+ size=12 align=4
+ base size=12 base align=4
+QXmlAttributes (0xb3d9a000) 0
+ vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 8u)
+
+Vtable for QXmlInputSource
+QXmlInputSource::_ZTV15QXmlInputSource: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlInputSource)
+8 QXmlInputSource::~QXmlInputSource
+12 QXmlInputSource::~QXmlInputSource
+16 QXmlInputSource::setData
+20 QXmlInputSource::setData
+24 QXmlInputSource::fetchData
+28 QXmlInputSource::data
+32 QXmlInputSource::next
+36 QXmlInputSource::reset
+40 QXmlInputSource::fromRawData
+
+Class QXmlInputSource
+ size=8 align=4
+ base size=8 base align=4
+QXmlInputSource (0xb3d9a5dc) 0
+ vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 8u)
+
+Class QXmlParseException
+ size=4 align=4
+ base size=4 base align=4
+QXmlParseException (0xb3d9a618) 0
+
+Vtable for QXmlReader
+QXmlReader::_ZTV10QXmlReader: 24u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QXmlReader)
+8 QXmlReader::~QXmlReader
+12 QXmlReader::~QXmlReader
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+
+Class QXmlReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlReader (0xb3d9a654) 0 nearly-empty
+ vptr=((& QXmlReader::_ZTV10QXmlReader) + 8u)
+
+Vtable for QXmlSimpleReader
+QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlSimpleReader)
+8 QXmlSimpleReader::~QXmlSimpleReader
+12 QXmlSimpleReader::~QXmlSimpleReader
+16 QXmlSimpleReader::feature
+20 QXmlSimpleReader::setFeature
+24 QXmlSimpleReader::hasFeature
+28 QXmlSimpleReader::property
+32 QXmlSimpleReader::setProperty
+36 QXmlSimpleReader::hasProperty
+40 QXmlSimpleReader::setEntityResolver
+44 QXmlSimpleReader::entityResolver
+48 QXmlSimpleReader::setDTDHandler
+52 QXmlSimpleReader::DTDHandler
+56 QXmlSimpleReader::setContentHandler
+60 QXmlSimpleReader::contentHandler
+64 QXmlSimpleReader::setErrorHandler
+68 QXmlSimpleReader::errorHandler
+72 QXmlSimpleReader::setLexicalHandler
+76 QXmlSimpleReader::lexicalHandler
+80 QXmlSimpleReader::setDeclHandler
+84 QXmlSimpleReader::declHandler
+88 QXmlSimpleReader::parse
+92 QXmlSimpleReader::parse
+96 QXmlSimpleReader::parse
+100 QXmlSimpleReader::parseContinue
+
+Class QXmlSimpleReader
+ size=8 align=4
+ base size=8 base align=4
+QXmlSimpleReader (0xb3d8a940) 0
+ vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 8u)
+ QXmlReader (0xb3d9a870) 0 nearly-empty
+ primary-for QXmlSimpleReader (0xb3d8a940)
+
+Vtable for QXmlLocator
+QXmlLocator::_ZTV11QXmlLocator: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QXmlLocator)
+8 QXmlLocator::~QXmlLocator
+12 QXmlLocator::~QXmlLocator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlLocator
+ size=4 align=4
+ base size=4 base align=4
+QXmlLocator (0xb3d9a924) 0 nearly-empty
+ vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 8u)
+
+Vtable for QXmlContentHandler
+QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlContentHandler)
+8 QXmlContentHandler::~QXmlContentHandler
+12 QXmlContentHandler::~QXmlContentHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+48 __cxa_pure_virtual
+52 __cxa_pure_virtual
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QXmlContentHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlContentHandler (0xb3d9a960) 0 nearly-empty
+ vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 8u)
+
+Vtable for QXmlErrorHandler
+QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QXmlErrorHandler)
+8 QXmlErrorHandler::~QXmlErrorHandler
+12 QXmlErrorHandler::~QXmlErrorHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlErrorHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlErrorHandler (0xb3d9ab7c) 0 nearly-empty
+ vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 8u)
+
+Vtable for QXmlDTDHandler
+QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QXmlDTDHandler)
+8 QXmlDTDHandler::~QXmlDTDHandler
+12 QXmlDTDHandler::~QXmlDTDHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QXmlDTDHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDTDHandler (0xb3d9ad98) 0 nearly-empty
+ vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 8u)
+
+Vtable for QXmlEntityResolver
+QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlEntityResolver)
+8 QXmlEntityResolver::~QXmlEntityResolver
+12 QXmlEntityResolver::~QXmlEntityResolver
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QXmlEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlEntityResolver (0xb3d9afb4) 0 nearly-empty
+ vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 8u)
+
+Vtable for QXmlLexicalHandler
+QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlLexicalHandler)
+8 QXmlLexicalHandler::~QXmlLexicalHandler
+12 QXmlLexicalHandler::~QXmlLexicalHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+32 __cxa_pure_virtual
+36 __cxa_pure_virtual
+40 __cxa_pure_virtual
+44 __cxa_pure_virtual
+
+Class QXmlLexicalHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlLexicalHandler (0xb3de11e0) 0 nearly-empty
+ vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 8u)
+
+Vtable for QXmlDeclHandler
+QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QXmlDeclHandler)
+8 QXmlDeclHandler::~QXmlDeclHandler
+12 QXmlDeclHandler::~QXmlDeclHandler
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 __cxa_pure_virtual
+
+Class QXmlDeclHandler
+ size=4 align=4
+ base size=4 base align=4
+QXmlDeclHandler (0xb3de13fc) 0 nearly-empty
+ vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 8u)
+
+Vtable for QXmlDefaultHandler
+QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+8 QXmlDefaultHandler::~QXmlDefaultHandler
+12 QXmlDefaultHandler::~QXmlDefaultHandler
+16 QXmlDefaultHandler::setDocumentLocator
+20 QXmlDefaultHandler::startDocument
+24 QXmlDefaultHandler::endDocument
+28 QXmlDefaultHandler::startPrefixMapping
+32 QXmlDefaultHandler::endPrefixMapping
+36 QXmlDefaultHandler::startElement
+40 QXmlDefaultHandler::endElement
+44 QXmlDefaultHandler::characters
+48 QXmlDefaultHandler::ignorableWhitespace
+52 QXmlDefaultHandler::processingInstruction
+56 QXmlDefaultHandler::skippedEntity
+60 QXmlDefaultHandler::errorString
+64 QXmlDefaultHandler::warning
+68 QXmlDefaultHandler::error
+72 QXmlDefaultHandler::fatalError
+76 QXmlDefaultHandler::notationDecl
+80 QXmlDefaultHandler::unparsedEntityDecl
+84 QXmlDefaultHandler::resolveEntity
+88 QXmlDefaultHandler::startDTD
+92 QXmlDefaultHandler::endDTD
+96 QXmlDefaultHandler::startEntity
+100 QXmlDefaultHandler::endEntity
+104 QXmlDefaultHandler::startCDATA
+108 QXmlDefaultHandler::endCDATA
+112 QXmlDefaultHandler::comment
+116 QXmlDefaultHandler::attributeDecl
+120 QXmlDefaultHandler::internalEntityDecl
+124 QXmlDefaultHandler::externalEntityDecl
+128 (int (*)(...))-0x000000004
+132 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+136 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD1Ev
+140 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandlerD0Ev
+144 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler7warningERK18QXmlParseException
+148 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler5errorERK18QXmlParseException
+152 QXmlDefaultHandler::_ZThn4_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException
+156 QXmlDefaultHandler::_ZThn4_NK18QXmlDefaultHandler11errorStringEv
+160 (int (*)(...))-0x000000008
+164 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+168 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev
+172 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev
+176 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_
+180 QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_
+184 QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv
+188 (int (*)(...))-0x00000000c
+192 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+196 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD1Ev
+200 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandlerD0Ev
+204 QXmlDefaultHandler::_ZThn12_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource
+208 QXmlDefaultHandler::_ZThn12_NK18QXmlDefaultHandler11errorStringEv
+212 (int (*)(...))-0x000000010
+216 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+220 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev
+224 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev
+228 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_
+232 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler6endDTDEv
+236 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler11startEntityERK7QString
+240 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler9endEntityERK7QString
+244 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler10startCDATAEv
+248 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler8endCDATAEv
+252 QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler7commentERK7QString
+256 QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv
+260 (int (*)(...))-0x000000014
+264 (int (*)(...))(& _ZTI18QXmlDefaultHandler)
+268 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD1Ev
+272 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandlerD0Ev
+276 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_
+280 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_
+284 QXmlDefaultHandler::_ZThn20_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_
+288 QXmlDefaultHandler::_ZThn20_NK18QXmlDefaultHandler11errorStringEv
+
+Class QXmlDefaultHandler
+ size=28 align=4
+ base size=28 base align=4
+QXmlDefaultHandler (0xb3de72a0) 0
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 8u)
+ QXmlContentHandler (0xb3de1618) 0 nearly-empty
+ primary-for QXmlDefaultHandler (0xb3de72a0)
+ QXmlErrorHandler (0xb3de1654) 4 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 136u)
+ QXmlDTDHandler (0xb3de1690) 8 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 168u)
+ QXmlEntityResolver (0xb3de16cc) 12 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 196u)
+ QXmlLexicalHandler (0xb3de1708) 16 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 220u)
+ QXmlDeclHandler (0xb3de1744) 20 nearly-empty
+ vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 268u)
+
+Class QSslCertificate
+ size=4 align=4
+ base size=4 base align=4
+QSslCertificate (0xb3e145a0) 0
+
+Class QSslError
+ size=4 align=4
+ base size=4 base align=4
+QSslError (0xb3e14618) 0
+
+Class QSslCipher
+ size=4 align=4
+ base size=4 base align=4
+QSslCipher (0xb3e14690) 0
+
+Vtable for QAbstractSocket
+QAbstractSocket::_ZTV15QAbstractSocket: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QAbstractSocket)
+8 QAbstractSocket::metaObject
+12 QAbstractSocket::qt_metacast
+16 QAbstractSocket::qt_metacall
+20 QAbstractSocket::~QAbstractSocket
+24 QAbstractSocket::~QAbstractSocket
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractSocket::isSequential
+60 QIODevice::open
+64 QAbstractSocket::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QAbstractSocket::atEnd
+84 QIODevice::reset
+88 QAbstractSocket::bytesAvailable
+92 QAbstractSocket::bytesToWrite
+96 QAbstractSocket::canReadLine
+100 QAbstractSocket::waitForReadyRead
+104 QAbstractSocket::waitForBytesWritten
+108 QAbstractSocket::readData
+112 QAbstractSocket::readLineData
+116 QAbstractSocket::writeData
+
+Class QAbstractSocket
+ size=8 align=4
+ base size=8 base align=4
+QAbstractSocket (0xb3e0ac80) 0
+ vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 8u)
+ QIODevice (0xb3e0acc0) 0
+ primary-for QAbstractSocket (0xb3e0ac80)
+ QObject (0xb3e14708) 0
+ primary-for QIODevice (0xb3e0acc0)
+
+Vtable for QTcpSocket
+QTcpSocket::_ZTV10QTcpSocket: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTcpSocket)
+8 QTcpSocket::metaObject
+12 QTcpSocket::qt_metacast
+16 QTcpSocket::qt_metacall
+20 QTcpSocket::~QTcpSocket
+24 QTcpSocket::~QTcpSocket
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractSocket::isSequential
+60 QIODevice::open
+64 QAbstractSocket::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QAbstractSocket::atEnd
+84 QIODevice::reset
+88 QAbstractSocket::bytesAvailable
+92 QAbstractSocket::bytesToWrite
+96 QAbstractSocket::canReadLine
+100 QAbstractSocket::waitForReadyRead
+104 QAbstractSocket::waitForBytesWritten
+108 QAbstractSocket::readData
+112 QAbstractSocket::readLineData
+116 QAbstractSocket::writeData
+
+Class QTcpSocket
+ size=8 align=4
+ base size=8 base align=4
+QTcpSocket (0xb3e4e1c0) 0
+ vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 8u)
+ QAbstractSocket (0xb3e4e200) 0
+ primary-for QTcpSocket (0xb3e4e1c0)
+ QIODevice (0xb3e4e240) 0
+ primary-for QAbstractSocket (0xb3e4e200)
+ QObject (0xb3e14c6c) 0
+ primary-for QIODevice (0xb3e4e240)
+
+Vtable for QSslSocket
+QSslSocket::_ZTV10QSslSocket: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QSslSocket)
+8 QSslSocket::metaObject
+12 QSslSocket::qt_metacast
+16 QSslSocket::qt_metacall
+20 QSslSocket::~QSslSocket
+24 QSslSocket::~QSslSocket
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractSocket::isSequential
+60 QIODevice::open
+64 QSslSocket::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QSslSocket::atEnd
+84 QIODevice::reset
+88 QSslSocket::bytesAvailable
+92 QSslSocket::bytesToWrite
+96 QSslSocket::canReadLine
+100 QSslSocket::waitForReadyRead
+104 QSslSocket::waitForBytesWritten
+108 QSslSocket::readData
+112 QAbstractSocket::readLineData
+116 QSslSocket::writeData
+
+Class QSslSocket
+ size=8 align=4
+ base size=8 base align=4
+QSslSocket (0xb3e4e500) 0
+ vptr=((& QSslSocket::_ZTV10QSslSocket) + 8u)
+ QTcpSocket (0xb3e4e540) 0
+ primary-for QSslSocket (0xb3e4e500)
+ QAbstractSocket (0xb3e4e580) 0
+ primary-for QTcpSocket (0xb3e4e540)
+ QIODevice (0xb3e4e5c0) 0
+ primary-for QAbstractSocket (0xb3e4e580)
+ QObject (0xb3e14e88) 0
+ primary-for QIODevice (0xb3e4e5c0)
+
+Class QSslConfiguration
+ size=4 align=4
+ base size=4 base align=4
+QSslConfiguration (0xb3c77168) 0
+
+Class QSslKey
+ size=4 align=4
+ base size=4 base align=4
+QSslKey (0xb3c7721c) 0
+
+Vtable for QHttpHeader
+QHttpHeader::_ZTV11QHttpHeader: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QHttpHeader)
+8 QHttpHeader::~QHttpHeader
+12 QHttpHeader::~QHttpHeader
+16 QHttpHeader::toString
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QHttpHeader::parseLine
+
+Class QHttpHeader
+ size=8 align=4
+ base size=8 base align=4
+QHttpHeader (0xb3c77294) 0
+ vptr=((& QHttpHeader::_ZTV11QHttpHeader) + 8u)
+
+Vtable for QHttpResponseHeader
+QHttpResponseHeader::_ZTV19QHttpResponseHeader: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QHttpResponseHeader)
+8 QHttpResponseHeader::~QHttpResponseHeader
+12 QHttpResponseHeader::~QHttpResponseHeader
+16 QHttpResponseHeader::toString
+20 QHttpResponseHeader::majorVersion
+24 QHttpResponseHeader::minorVersion
+28 QHttpResponseHeader::parseLine
+
+Class QHttpResponseHeader
+ size=8 align=4
+ base size=8 base align=4
+QHttpResponseHeader (0xb3e4ebc0) 0
+ vptr=((& QHttpResponseHeader::_ZTV19QHttpResponseHeader) + 8u)
+ QHttpHeader (0xb3c77348) 0
+ primary-for QHttpResponseHeader (0xb3e4ebc0)
+
+Vtable for QHttpRequestHeader
+QHttpRequestHeader::_ZTV18QHttpRequestHeader: 8u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QHttpRequestHeader)
+8 QHttpRequestHeader::~QHttpRequestHeader
+12 QHttpRequestHeader::~QHttpRequestHeader
+16 QHttpRequestHeader::toString
+20 QHttpRequestHeader::majorVersion
+24 QHttpRequestHeader::minorVersion
+28 QHttpRequestHeader::parseLine
+
+Class QHttpRequestHeader
+ size=8 align=4
+ base size=8 base align=4
+QHttpRequestHeader (0xb3e4ecc0) 0
+ vptr=((& QHttpRequestHeader::_ZTV18QHttpRequestHeader) + 8u)
+ QHttpHeader (0xb3c77474) 0
+ primary-for QHttpRequestHeader (0xb3e4ecc0)
+
+Vtable for QHttp
+QHttp::_ZTV5QHttp: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QHttp)
+8 QHttp::metaObject
+12 QHttp::qt_metacast
+16 QHttp::qt_metacall
+20 QHttp::~QHttp
+24 QHttp::~QHttp
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHttp
+ size=8 align=4
+ base size=8 base align=4
+QHttp (0xb3e4edc0) 0
+ vptr=((& QHttp::_ZTV5QHttp) + 8u)
+ QObject (0xb3c775a0) 0
+ primary-for QHttp (0xb3e4edc0)
+
+Class QNetworkRequest
+ size=4 align=4
+ base size=4 base align=4
+QNetworkRequest (0xb3c77834) 0
+
+Vtable for QNetworkAccessManager
+QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QNetworkAccessManager)
+8 QNetworkAccessManager::metaObject
+12 QNetworkAccessManager::qt_metacast
+16 QNetworkAccessManager::qt_metacall
+20 QNetworkAccessManager::~QNetworkAccessManager
+24 QNetworkAccessManager::~QNetworkAccessManager
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QNetworkAccessManager::createRequest
+
+Class QNetworkAccessManager
+ size=8 align=4
+ base size=8 base align=4
+QNetworkAccessManager (0xb3cbc2c0) 0
+ vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 8u)
+ QObject (0xb3c7799c) 0
+ primary-for QNetworkAccessManager (0xb3cbc2c0)
+
+Class QNetworkCookie
+ size=4 align=4
+ base size=4 base align=4
+QNetworkCookie (0xb3c77bb8) 0
+
+Vtable for QNetworkCookieJar
+QNetworkCookieJar::_ZTV17QNetworkCookieJar: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QNetworkCookieJar)
+8 QNetworkCookieJar::metaObject
+12 QNetworkCookieJar::qt_metacast
+16 QNetworkCookieJar::qt_metacall
+20 QNetworkCookieJar::~QNetworkCookieJar
+24 QNetworkCookieJar::~QNetworkCookieJar
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QNetworkCookieJar::cookiesForUrl
+60 QNetworkCookieJar::setCookiesFromUrl
+
+Class QNetworkCookieJar
+ size=8 align=4
+ base size=8 base align=4
+QNetworkCookieJar (0xb3cbc700) 0
+ vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 8u)
+ QObject (0xb3c77ce4) 0
+ primary-for QNetworkCookieJar (0xb3cbc700)
+
+Vtable for QNetworkReply
+QNetworkReply::_ZTV13QNetworkReply: 33u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QNetworkReply)
+8 QNetworkReply::metaObject
+12 QNetworkReply::qt_metacast
+16 QNetworkReply::qt_metacall
+20 QNetworkReply::~QNetworkReply
+24 QNetworkReply::~QNetworkReply
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QNetworkReply::isSequential
+60 QIODevice::open
+64 QNetworkReply::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 QNetworkReply::writeData
+120 __cxa_pure_virtual
+124 QNetworkReply::setReadBufferSize
+128 QNetworkReply::ignoreSslErrors
+
+Class QNetworkReply
+ size=8 align=4
+ base size=8 base align=4
+QNetworkReply (0xb3cbcc40) 0
+ vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 8u)
+ QIODevice (0xb3cbcc80) 0
+ primary-for QNetworkReply (0xb3cbcc40)
+ QObject (0xb3cfd078) 0
+ primary-for QIODevice (0xb3cbcc80)
+
+Vtable for QUrlInfo
+QUrlInfo::_ZTV8QUrlInfo: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QUrlInfo)
+8 QUrlInfo::~QUrlInfo
+12 QUrlInfo::~QUrlInfo
+16 QUrlInfo::setName
+20 QUrlInfo::setDir
+24 QUrlInfo::setFile
+28 QUrlInfo::setSymLink
+32 QUrlInfo::setOwner
+36 QUrlInfo::setGroup
+40 QUrlInfo::setSize
+44 QUrlInfo::setWritable
+48 QUrlInfo::setReadable
+52 QUrlInfo::setPermissions
+56 QUrlInfo::setLastModified
+
+Class QUrlInfo
+ size=8 align=4
+ base size=8 base align=4
+QUrlInfo (0xb3cfd294) 0
+ vptr=((& QUrlInfo::_ZTV8QUrlInfo) + 8u)
+
+Vtable for QFtp
+QFtp::_ZTV4QFtp: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI4QFtp)
+8 QFtp::metaObject
+12 QFtp::qt_metacast
+16 QFtp::qt_metacall
+20 QFtp::~QFtp
+24 QFtp::~QFtp
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QFtp
+ size=8 align=4
+ base size=8 base align=4
+QFtp (0xb3cbcfc0) 0
+ vptr=((& QFtp::_ZTV4QFtp) + 8u)
+ QObject (0xb3cfd348) 0
+ primary-for QFtp (0xb3cbcfc0)
+
+Class QNetworkCacheMetaData
+ size=4 align=4
+ base size=4 base align=4
+QNetworkCacheMetaData (0xb3cfd5dc) 0
+
+Vtable for QAbstractNetworkCache
+QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QAbstractNetworkCache)
+8 QAbstractNetworkCache::metaObject
+12 QAbstractNetworkCache::qt_metacast
+16 QAbstractNetworkCache::qt_metacall
+20 QAbstractNetworkCache::~QAbstractNetworkCache
+24 QAbstractNetworkCache::~QAbstractNetworkCache
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+
+Class QAbstractNetworkCache
+ size=8 align=4
+ base size=8 base align=4
+QAbstractNetworkCache (0xb3d1d3c0) 0
+ vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 8u)
+ QObject (0xb3cfd690) 0
+ primary-for QAbstractNetworkCache (0xb3d1d3c0)
+
+Vtable for QNetworkDiskCache
+QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QNetworkDiskCache)
+8 QNetworkDiskCache::metaObject
+12 QNetworkDiskCache::qt_metacast
+16 QNetworkDiskCache::qt_metacall
+20 QNetworkDiskCache::~QNetworkDiskCache
+24 QNetworkDiskCache::~QNetworkDiskCache
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QNetworkDiskCache::metaData
+60 QNetworkDiskCache::updateMetaData
+64 QNetworkDiskCache::data
+68 QNetworkDiskCache::remove
+72 QNetworkDiskCache::cacheSize
+76 QNetworkDiskCache::prepare
+80 QNetworkDiskCache::insert
+84 QNetworkDiskCache::clear
+88 QNetworkDiskCache::expire
+
+Class QNetworkDiskCache
+ size=8 align=4
+ base size=8 base align=4
+QNetworkDiskCache (0xb3d1d680) 0
+ vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 8u)
+ QAbstractNetworkCache (0xb3d1d6c0) 0
+ primary-for QNetworkDiskCache (0xb3d1d680)
+ QObject (0xb3cfd8ac) 0
+ primary-for QAbstractNetworkCache (0xb3d1d6c0)
+
+Class QIPv6Address
+ size=16 align=1
+ base size=16 base align=1
+QIPv6Address (0xb3cfdac8) 0
+
+Class QHostAddress
+ size=4 align=4
+ base size=4 base align=4
+QHostAddress (0xb3cfdbf4) 0
+
+Class QNetworkAddressEntry
+ size=4 align=4
+ base size=4 base align=4
+QNetworkAddressEntry (0xb3cfdfb4) 0
+
+Class QNetworkInterface
+ size=4 align=4
+ base size=4 base align=4
+QNetworkInterface (0xb3b7903c) 0
+
+Class QAuthenticator
+ size=4 align=4
+ base size=4 base align=4
+QAuthenticator (0xb3b791a4) 0
+
+Class QHostInfo
+ size=4 align=4
+ base size=4 base align=4
+QHostInfo (0xb3b7921c) 0
+
+Class QNetworkProxyQuery
+ size=4 align=4
+ base size=4 base align=4
+QNetworkProxyQuery (0xb3b79258) 0
+
+Class QNetworkProxy
+ size=4 align=4
+ base size=4 base align=4
+QNetworkProxy (0xb3b79384) 0
+
+Vtable for QNetworkProxyFactory
+QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QNetworkProxyFactory)
+8 QNetworkProxyFactory::~QNetworkProxyFactory
+12 QNetworkProxyFactory::~QNetworkProxyFactory
+16 __cxa_pure_virtual
+
+Class QNetworkProxyFactory
+ size=4 align=4
+ base size=4 base align=4
+QNetworkProxyFactory (0xb3b79528) 0 nearly-empty
+ vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 8u)
+
+Vtable for QLocalServer
+QLocalServer::_ZTV12QLocalServer: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QLocalServer)
+8 QLocalServer::metaObject
+12 QLocalServer::qt_metacast
+16 QLocalServer::qt_metacall
+20 QLocalServer::~QLocalServer
+24 QLocalServer::~QLocalServer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QLocalServer::hasPendingConnections
+60 QLocalServer::nextPendingConnection
+64 QLocalServer::incomingConnection
+
+Class QLocalServer
+ size=8 align=4
+ base size=8 base align=4
+QLocalServer (0xb3bb0340) 0
+ vptr=((& QLocalServer::_ZTV12QLocalServer) + 8u)
+ QObject (0xb3b79564) 0
+ primary-for QLocalServer (0xb3bb0340)
+
+Vtable for QLocalSocket
+QLocalSocket::_ZTV12QLocalSocket: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QLocalSocket)
+8 QLocalSocket::metaObject
+12 QLocalSocket::qt_metacast
+16 QLocalSocket::qt_metacall
+20 QLocalSocket::~QLocalSocket
+24 QLocalSocket::~QLocalSocket
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QLocalSocket::isSequential
+60 QIODevice::open
+64 QLocalSocket::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QLocalSocket::bytesAvailable
+92 QLocalSocket::bytesToWrite
+96 QLocalSocket::canReadLine
+100 QLocalSocket::waitForReadyRead
+104 QLocalSocket::waitForBytesWritten
+108 QLocalSocket::readData
+112 QIODevice::readLineData
+116 QLocalSocket::writeData
+
+Class QLocalSocket
+ size=8 align=4
+ base size=8 base align=4
+QLocalSocket (0xb3bb0600) 0
+ vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 8u)
+ QIODevice (0xb3bb0640) 0
+ primary-for QLocalSocket (0xb3bb0600)
+ QObject (0xb3b79780) 0
+ primary-for QIODevice (0xb3bb0640)
+
+Vtable for QTcpServer
+QTcpServer::_ZTV10QTcpServer: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTcpServer)
+8 QTcpServer::metaObject
+12 QTcpServer::qt_metacast
+16 QTcpServer::qt_metacall
+20 QTcpServer::~QTcpServer
+24 QTcpServer::~QTcpServer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTcpServer::hasPendingConnections
+60 QTcpServer::nextPendingConnection
+64 QTcpServer::incomingConnection
+
+Class QTcpServer
+ size=8 align=4
+ base size=8 base align=4
+QTcpServer (0xb3bb0900) 0
+ vptr=((& QTcpServer::_ZTV10QTcpServer) + 8u)
+ QObject (0xb3b7999c) 0
+ primary-for QTcpServer (0xb3bb0900)
+
+Vtable for QUdpSocket
+QUdpSocket::_ZTV10QUdpSocket: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QUdpSocket)
+8 QUdpSocket::metaObject
+12 QUdpSocket::qt_metacast
+16 QUdpSocket::qt_metacall
+20 QUdpSocket::~QUdpSocket
+24 QUdpSocket::~QUdpSocket
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractSocket::isSequential
+60 QIODevice::open
+64 QAbstractSocket::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QAbstractSocket::atEnd
+84 QIODevice::reset
+88 QAbstractSocket::bytesAvailable
+92 QAbstractSocket::bytesToWrite
+96 QAbstractSocket::canReadLine
+100 QAbstractSocket::waitForReadyRead
+104 QAbstractSocket::waitForBytesWritten
+108 QAbstractSocket::readData
+112 QAbstractSocket::readLineData
+116 QAbstractSocket::writeData
+
+Class QUdpSocket
+ size=8 align=4
+ base size=8 base align=4
+QUdpSocket (0xb3bb0bc0) 0
+ vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 8u)
+ QAbstractSocket (0xb3bb0c00) 0
+ primary-for QUdpSocket (0xb3bb0bc0)
+ QIODevice (0xb3bb0c40) 0
+ primary-for QAbstractSocket (0xb3bb0c00)
+ QObject (0xb3b79bb8) 0
+ primary-for QIODevice (0xb3bb0c40)
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb3c34000) 0
+
+Vtable for QAbstractUndoItem
+QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QAbstractUndoItem)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QAbstractUndoItem
+ size=4 align=4
+ base size=4 base align=4
+QAbstractUndoItem (0xb3c341e0) 0 nearly-empty
+ vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 8u)
+
+Vtable for QTextDocument
+QTextDocument::_ZTV13QTextDocument: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QTextDocument)
+8 QTextDocument::metaObject
+12 QTextDocument::qt_metacast
+16 QTextDocument::qt_metacall
+20 QTextDocument::~QTextDocument
+24 QTextDocument::~QTextDocument
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTextDocument::clear
+60 QTextDocument::createObject
+64 QTextDocument::loadResource
+
+Class QTextDocument
+ size=8 align=4
+ base size=8 base align=4
+QTextDocument (0xb3c2f580) 0
+ vptr=((& QTextDocument::_ZTV13QTextDocument) + 8u)
+ QObject (0xb3c343fc) 0
+ primary-for QTextDocument (0xb3c2f580)
+
+Class QHelpGlobal
+ size=1 align=1
+ base size=0 base align=1
+QHelpGlobal (0xb3c34708) 0 empty
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb3c34fb4) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb3ab5ac8) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb3ac2a40) 0
+ QVector<QPoint> (0xb3aee12c) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb3b12040) 0
+ QVector<QPointF> (0xb3aeeac8) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb3b2d3fc) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb3b2d3c0) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb3b2d744) 0
+
+Class QPainterPath::Element
+ size=20 align=4
+ base size=20 base align=4
+QPainterPath::Element (0xb3b2dec4) 0
+
+Class QPainterPath
+ size=4 align=4
+ base size=4 base align=4
+QPainterPath (0xb3b2de88) 0
+
+Class QPainterPathPrivate
+ size=8 align=4
+ base size=8 base align=4
+QPainterPathPrivate (0xb398d348) 0
+
+Class QPainterPathStroker
+ size=4 align=4
+ base size=4 base align=4
+QPainterPathStroker (0xb398d474) 0
+
+Class QTransform
+ size=80 align=4
+ base size=80 base align=4
+QTransform (0xb39bf30c) 0
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb3a05924) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb39f1dc0) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb3a2130c) 0
+ primary-for QImage (0xb39f1dc0)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb3a66700) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb3a21fb4) 0
+ primary-for QPixmap (0xb3a66700)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb3898618) 0
+
+Class QBrushData
+ size=104 align=4
+ base size=104 base align=4
+QBrushData (0xb3898870) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb3898c30) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb38b7540) 0
+ QGradient (0xb3898ec4) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb38b7640) 0
+ QGradient (0xb3898f00) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb38b7740) 0
+ QGradient (0xb3898f3c) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb3898f78) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb390c180) 0
+ QPalette (0xb38fd870) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb39219d8) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb3921c30) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb3921ce4) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb3921d20) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb3796bf4) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb3796c30) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb3796f3c) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb37e89b0) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb3796f78) 0
+ primary-for QWidget (0xb37e89b0)
+ QPaintDevice (0xb3796fb4) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Vtable for QFrame
+QFrame::_ZTV6QFrame: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QFrame)
+8 QFrame::metaObject
+12 QFrame::qt_metacast
+16 QFrame::qt_metacall
+20 QFrame::~QFrame
+24 QFrame::~QFrame
+28 QFrame::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QFrame::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QFrame::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI6QFrame)
+232 QFrame::_ZThn8_N6QFrameD1Ev
+236 QFrame::_ZThn8_N6QFrameD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QFrame
+ size=20 align=4
+ base size=20 base align=4
+QFrame (0xb3687c40) 0
+ vptr=((& QFrame::_ZTV6QFrame) + 8u)
+ QWidget (0xb36a99b0) 0
+ primary-for QFrame (0xb3687c40)
+ QObject (0xb36955dc) 0
+ primary-for QWidget (0xb36a99b0)
+ QPaintDevice (0xb3695618) 8
+ vptr=((& QFrame::_ZTV6QFrame) + 232u)
+
+Vtable for QAbstractScrollArea
+QAbstractScrollArea::_ZTV19QAbstractScrollArea: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+8 QAbstractScrollArea::metaObject
+12 QAbstractScrollArea::qt_metacast
+16 QAbstractScrollArea::qt_metacall
+20 QAbstractScrollArea::~QAbstractScrollArea
+24 QAbstractScrollArea::~QAbstractScrollArea
+28 QAbstractScrollArea::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractScrollArea::mousePressEvent
+84 QAbstractScrollArea::mouseReleaseEvent
+88 QAbstractScrollArea::mouseDoubleClickEvent
+92 QAbstractScrollArea::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractScrollArea::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractScrollArea::paintEvent
+128 QWidget::moveEvent
+132 QAbstractScrollArea::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractScrollArea::dragEnterEvent
+156 QAbstractScrollArea::dragMoveEvent
+160 QAbstractScrollArea::dragLeaveEvent
+164 QAbstractScrollArea::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractScrollArea::viewportEvent
+228 QAbstractScrollArea::scrollContentsBy
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+240 QAbstractScrollArea::_ZThn8_N19QAbstractScrollAreaD1Ev
+244 QAbstractScrollArea::_ZThn8_N19QAbstractScrollAreaD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractScrollArea
+ size=20 align=4
+ base size=20 base align=4
+QAbstractScrollArea (0xb3687f00) 0
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 8u)
+ QFrame (0xb3687f40) 0
+ primary-for QAbstractScrollArea (0xb3687f00)
+ QWidget (0xb36be500) 0
+ primary-for QFrame (0xb3687f40)
+ QObject (0xb3695834) 0
+ primary-for QWidget (0xb36be500)
+ QPaintDevice (0xb3695870) 8
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 240u)
+
+Class QItemSelectionRange
+ size=8 align=4
+ base size=8 base align=4
+QItemSelectionRange (0xb3695a8c) 0
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QItemSelectionModel)
+8 QItemSelectionModel::metaObject
+12 QItemSelectionModel::qt_metacast
+16 QItemSelectionModel::qt_metacall
+20 QItemSelectionModel::~QItemSelectionModel
+24 QItemSelectionModel::~QItemSelectionModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QItemSelectionModel::select
+60 QItemSelectionModel::select
+64 QItemSelectionModel::clear
+68 QItemSelectionModel::reset
+
+Class QItemSelectionModel
+ size=8 align=4
+ base size=8 base align=4
+QItemSelectionModel (0xb36d0cc0) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 8u)
+ QObject (0xb36f5b04) 0
+ primary-for QItemSelectionModel (0xb36d0cc0)
+
+Class QItemSelection
+ size=4 align=4
+ base size=4 base align=4
+QItemSelection (0xb372f180) 0
+ QList<QItemSelectionRange> (0xb36f5ec4) 0
+
+Vtable for QValidator
+QValidator::_ZTV10QValidator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QValidator)
+8 QValidator::metaObject
+12 QValidator::qt_metacast
+16 QValidator::qt_metacall
+20 QValidator::~QValidator
+24 QValidator::~QValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 QValidator::fixup
+
+Class QValidator
+ size=8 align=4
+ base size=8 base align=4
+QValidator (0xb372f300) 0
+ vptr=((& QValidator::_ZTV10QValidator) + 8u)
+ QObject (0xb3751078) 0
+ primary-for QValidator (0xb372f300)
+
+Vtable for QIntValidator
+QIntValidator::_ZTV13QIntValidator: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QIntValidator)
+8 QIntValidator::metaObject
+12 QIntValidator::qt_metacast
+16 QIntValidator::qt_metacall
+20 QIntValidator::~QIntValidator
+24 QIntValidator::~QIntValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIntValidator::validate
+60 QValidator::fixup
+64 QIntValidator::setRange
+
+Class QIntValidator
+ size=16 align=4
+ base size=16 base align=4
+QIntValidator (0xb372f5c0) 0
+ vptr=((& QIntValidator::_ZTV13QIntValidator) + 8u)
+ QValidator (0xb372f600) 0
+ primary-for QIntValidator (0xb372f5c0)
+ QObject (0xb3751294) 0
+ primary-for QValidator (0xb372f600)
+
+Vtable for QDoubleValidator
+QDoubleValidator::_ZTV16QDoubleValidator: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QDoubleValidator)
+8 QDoubleValidator::metaObject
+12 QDoubleValidator::qt_metacast
+16 QDoubleValidator::qt_metacall
+20 QDoubleValidator::~QDoubleValidator
+24 QDoubleValidator::~QDoubleValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDoubleValidator::validate
+60 QValidator::fixup
+64 QDoubleValidator::setRange
+
+Class QDoubleValidator
+ size=28 align=4
+ base size=28 base align=4
+QDoubleValidator (0xb372f8c0) 0
+ vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 8u)
+ QValidator (0xb372f900) 0
+ primary-for QDoubleValidator (0xb372f8c0)
+ QObject (0xb3751438) 0
+ primary-for QValidator (0xb372f900)
+
+Vtable for QRegExpValidator
+QRegExpValidator::_ZTV16QRegExpValidator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QRegExpValidator)
+8 QRegExpValidator::metaObject
+12 QRegExpValidator::qt_metacast
+16 QRegExpValidator::qt_metacall
+20 QRegExpValidator::~QRegExpValidator
+24 QRegExpValidator::~QRegExpValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QRegExpValidator::validate
+60 QValidator::fixup
+
+Class QRegExpValidator
+ size=12 align=4
+ base size=12 base align=4
+QRegExpValidator (0xb372fc80) 0
+ vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 8u)
+ QValidator (0xb372fcc0) 0
+ primary-for QRegExpValidator (0xb372fc80)
+ QObject (0xb3751708) 0
+ primary-for QValidator (0xb372fcc0)
+
+Vtable for QAbstractSpinBox
+QAbstractSpinBox::_ZTV16QAbstractSpinBox: 68u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+8 QAbstractSpinBox::metaObject
+12 QAbstractSpinBox::qt_metacast
+16 QAbstractSpinBox::qt_metacall
+20 QAbstractSpinBox::~QAbstractSpinBox
+24 QAbstractSpinBox::~QAbstractSpinBox
+28 QAbstractSpinBox::event
+32 QObject::eventFilter
+36 QAbstractSpinBox::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractSpinBox::sizeHint
+68 QAbstractSpinBox::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractSpinBox::mousePressEvent
+84 QAbstractSpinBox::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QAbstractSpinBox::mouseMoveEvent
+96 QAbstractSpinBox::wheelEvent
+100 QAbstractSpinBox::keyPressEvent
+104 QAbstractSpinBox::keyReleaseEvent
+108 QAbstractSpinBox::focusInEvent
+112 QAbstractSpinBox::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractSpinBox::paintEvent
+128 QWidget::moveEvent
+132 QAbstractSpinBox::resizeEvent
+136 QAbstractSpinBox::closeEvent
+140 QAbstractSpinBox::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QAbstractSpinBox::showEvent
+172 QAbstractSpinBox::hideEvent
+176 QWidget::x11Event
+180 QAbstractSpinBox::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSpinBox::validate
+228 QAbstractSpinBox::fixup
+232 QAbstractSpinBox::stepBy
+236 QAbstractSpinBox::clear
+240 QAbstractSpinBox::stepEnabled
+244 (int (*)(...))-0x000000008
+248 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+252 QAbstractSpinBox::_ZThn8_N16QAbstractSpinBoxD1Ev
+256 QAbstractSpinBox::_ZThn8_N16QAbstractSpinBoxD0Ev
+260 QWidget::_ZThn8_NK7QWidget7devTypeEv
+264 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+268 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSpinBox
+ size=20 align=4
+ base size=20 base align=4
+QAbstractSpinBox (0xb372ff40) 0
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 8u)
+ QWidget (0xb3576a00) 0
+ primary-for QAbstractSpinBox (0xb372ff40)
+ QObject (0xb3751870) 0
+ primary-for QWidget (0xb3576a00)
+ QPaintDevice (0xb37518ac) 8
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 252u)
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb3751bb8) 0
+
+Vtable for QAbstractSlider
+QAbstractSlider::_ZTV15QAbstractSlider: 64u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QAbstractSlider)
+8 QAbstractSlider::metaObject
+12 QAbstractSlider::qt_metacast
+16 QAbstractSlider::qt_metacall
+20 QAbstractSlider::~QAbstractSlider
+24 QAbstractSlider::~QAbstractSlider
+28 QAbstractSlider::event
+32 QObject::eventFilter
+36 QAbstractSlider::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QAbstractSlider::wheelEvent
+100 QAbstractSlider::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QAbstractSlider::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSlider::sliderChange
+228 (int (*)(...))-0x000000008
+232 (int (*)(...))(& _ZTI15QAbstractSlider)
+236 QAbstractSlider::_ZThn8_N15QAbstractSliderD1Ev
+240 QAbstractSlider::_ZThn8_N15QAbstractSliderD0Ev
+244 QWidget::_ZThn8_NK7QWidget7devTypeEv
+248 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+252 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSlider
+ size=20 align=4
+ base size=20 base align=4
+QAbstractSlider (0xb3590780) 0
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 8u)
+ QWidget (0xb35cb3c0) 0
+ primary-for QAbstractSlider (0xb3590780)
+ QObject (0xb3751f00) 0
+ primary-for QWidget (0xb35cb3c0)
+ QPaintDevice (0xb3751f3c) 8
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 236u)
+
+Vtable for QSlider
+QSlider::_ZTV7QSlider: 64u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QSlider)
+8 QSlider::metaObject
+12 QSlider::qt_metacast
+16 QSlider::qt_metacall
+20 QSlider::~QSlider
+24 QSlider::~QSlider
+28 QSlider::event
+32 QObject::eventFilter
+36 QAbstractSlider::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QSlider::sizeHint
+68 QSlider::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QSlider::mousePressEvent
+84 QSlider::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QSlider::mouseMoveEvent
+96 QAbstractSlider::wheelEvent
+100 QAbstractSlider::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QSlider::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QAbstractSlider::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSlider::sliderChange
+228 (int (*)(...))-0x000000008
+232 (int (*)(...))(& _ZTI7QSlider)
+236 QSlider::_ZThn8_N7QSliderD1Ev
+240 QSlider::_ZThn8_N7QSliderD0Ev
+244 QWidget::_ZThn8_NK7QWidget7devTypeEv
+248 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+252 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QSlider
+ size=20 align=4
+ base size=20 base align=4
+QSlider (0xb3590d00) 0
+ vptr=((& QSlider::_ZTV7QSlider) + 8u)
+ QAbstractSlider (0xb3590d40) 0
+ primary-for QSlider (0xb3590d00)
+ QWidget (0xb35dafa0) 0
+ primary-for QAbstractSlider (0xb3590d40)
+ QObject (0xb35e221c) 0
+ primary-for QWidget (0xb35dafa0)
+ QPaintDevice (0xb35e2258) 8
+ vptr=((& QSlider::_ZTV7QSlider) + 236u)
+
+Vtable for QStyle
+QStyle::_ZTV6QStyle: 35u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QStyle)
+8 QStyle::metaObject
+12 QStyle::qt_metacast
+16 QStyle::qt_metacall
+20 QStyle::~QStyle
+24 QStyle::~QStyle
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QStyle::polish
+60 QStyle::unpolish
+64 QStyle::polish
+68 QStyle::unpolish
+72 QStyle::polish
+76 QStyle::itemTextRect
+80 QStyle::itemPixmapRect
+84 QStyle::drawItemText
+88 QStyle::drawItemPixmap
+92 QStyle::standardPalette
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+120 __cxa_pure_virtual
+124 __cxa_pure_virtual
+128 __cxa_pure_virtual
+132 __cxa_pure_virtual
+136 __cxa_pure_virtual
+
+Class QStyle
+ size=8 align=4
+ base size=8 base align=4
+QStyle (0xb35fb100) 0
+ vptr=((& QStyle::_ZTV6QStyle) + 8u)
+ QObject (0xb35e2528) 0
+ primary-for QStyle (0xb35fb100)
+
+Vtable for QTabBar
+QTabBar::_ZTV7QTabBar: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QTabBar)
+8 QTabBar::metaObject
+12 QTabBar::qt_metacast
+16 QTabBar::qt_metacall
+20 QTabBar::~QTabBar
+24 QTabBar::~QTabBar
+28 QTabBar::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QTabBar::sizeHint
+68 QTabBar::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTabBar::mousePressEvent
+84 QTabBar::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QTabBar::mouseMoveEvent
+96 QTabBar::wheelEvent
+100 QTabBar::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTabBar::paintEvent
+128 QWidget::moveEvent
+132 QTabBar::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QTabBar::showEvent
+172 QTabBar::hideEvent
+176 QWidget::x11Event
+180 QTabBar::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTabBar::tabSizeHint
+228 QTabBar::tabInserted
+232 QTabBar::tabRemoved
+236 QTabBar::tabLayoutChange
+240 (int (*)(...))-0x000000008
+244 (int (*)(...))(& _ZTI7QTabBar)
+248 QTabBar::_ZThn8_N7QTabBarD1Ev
+252 QTabBar::_ZThn8_N7QTabBarD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabBar
+ size=20 align=4
+ base size=20 base align=4
+QTabBar (0xb35fb680) 0
+ vptr=((& QTabBar::_ZTV7QTabBar) + 8u)
+ QWidget (0xb364beb0) 0
+ primary-for QTabBar (0xb35fb680)
+ QObject (0xb35e2924) 0
+ primary-for QWidget (0xb364beb0)
+ QPaintDevice (0xb35e2960) 8
+ vptr=((& QTabBar::_ZTV7QTabBar) + 248u)
+
+Vtable for QTabWidget
+QTabWidget::_ZTV10QTabWidget: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTabWidget)
+8 QTabWidget::metaObject
+12 QTabWidget::qt_metacast
+16 QTabWidget::qt_metacall
+20 QTabWidget::~QTabWidget
+24 QTabWidget::~QTabWidget
+28 QTabWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QTabWidget::sizeHint
+68 QTabWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QTabWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTabWidget::paintEvent
+128 QWidget::moveEvent
+132 QTabWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QTabWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QTabWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTabWidget::tabInserted
+228 QTabWidget::tabRemoved
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI10QTabWidget)
+240 QTabWidget::_ZThn8_N10QTabWidgetD1Ev
+244 QTabWidget::_ZThn8_N10QTabWidgetD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabWidget
+ size=20 align=4
+ base size=20 base align=4
+QTabWidget (0xb35fb980) 0
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 8u)
+ QWidget (0xb347b550) 0
+ primary-for QTabWidget (0xb35fb980)
+ QObject (0xb35e2b7c) 0
+ primary-for QWidget (0xb347b550)
+ QPaintDevice (0xb35e2bb8) 8
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 240u)
+
+Vtable for QRubberBand
+QRubberBand::_ZTV11QRubberBand: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QRubberBand)
+8 QRubberBand::metaObject
+12 QRubberBand::qt_metacast
+16 QRubberBand::qt_metacall
+20 QRubberBand::~QRubberBand
+24 QRubberBand::~QRubberBand
+28 QRubberBand::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QRubberBand::paintEvent
+128 QRubberBand::moveEvent
+132 QRubberBand::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QRubberBand::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QRubberBand::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI11QRubberBand)
+232 QRubberBand::_ZThn8_N11QRubberBandD1Ev
+236 QRubberBand::_ZThn8_N11QRubberBandD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QRubberBand
+ size=20 align=4
+ base size=20 base align=4
+QRubberBand (0xb34a81c0) 0
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 8u)
+ QWidget (0xb34a5820) 0
+ primary-for QRubberBand (0xb34a81c0)
+ QObject (0xb34ab0f0) 0
+ primary-for QWidget (0xb34a5820)
+ QPaintDevice (0xb34ab12c) 8
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 232u)
+
+Class QStyleOption
+ size=44 align=4
+ base size=44 base align=4
+QStyleOption (0xb34ab564) 0
+
+Class QStyleOptionFocusRect
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionFocusRect (0xb34a8640) 0
+ QStyleOption (0xb34ab5a0) 0
+
+Class QStyleOptionFrame
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionFrame (0xb34a8840) 0
+ QStyleOption (0xb34ab924) 0
+
+Class QStyleOptionFrameV2
+ size=56 align=4
+ base size=56 base align=4
+QStyleOptionFrameV2 (0xb34a8a40) 0
+ QStyleOptionFrame (0xb34a8a80) 0
+ QStyleOption (0xb34abc6c) 0
+
+Class QStyleOptionFrameV3
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionFrameV3 (0xb34a8f40) 0
+ QStyleOptionFrameV2 (0xb34a8f80) 0
+ QStyleOptionFrame (0xb34a8fc0) 0
+ QStyleOption (0xb34dd1a4) 0
+
+Class QStyleOptionTabWidgetFrame
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabWidgetFrame (0xb34f6300) 0
+ QStyleOption (0xb34dd5a0) 0
+
+Class QStyleOptionTabBarBase
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabBarBase (0xb34f6500) 0
+ QStyleOption (0xb34ddc30) 0
+
+Class QStyleOptionTabBarBaseV2
+ size=84 align=4
+ base size=81 base align=4
+QStyleOptionTabBarBaseV2 (0xb34f6700) 0
+ QStyleOptionTabBarBase (0xb34f6740) 0
+ QStyleOption (0xb350c0f0) 0
+
+Class QStyleOptionHeader
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionHeader (0xb34f6a80) 0
+ QStyleOption (0xb350c474) 0
+
+Class QStyleOptionButton
+ size=64 align=4
+ base size=64 base align=4
+QStyleOptionButton (0xb34f6d40) 0
+ QStyleOption (0xb350cf3c) 0
+
+Class QStyleOptionTab
+ size=72 align=4
+ base size=72 base align=4
+QStyleOptionTab (0xb353e0c0) 0
+ QStyleOption (0xb352e870) 0
+
+Class QStyleOptionTabV2
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabV2 (0xb353e480) 0
+ QStyleOptionTab (0xb353e4c0) 0
+ QStyleOption (0xb335c294) 0
+
+Class QStyleOptionTabV3
+ size=100 align=4
+ base size=100 base align=4
+QStyleOptionTabV3 (0xb353e800) 0
+ QStyleOptionTabV2 (0xb353e840) 0
+ QStyleOptionTab (0xb353e880) 0
+ QStyleOption (0xb335c7f8) 0
+
+Class QStyleOptionToolBar
+ size=68 align=4
+ base size=68 base align=4
+QStyleOptionToolBar (0xb353ec80) 0
+ QStyleOption (0xb33880f0) 0
+
+Class QStyleOptionProgressBar
+ size=68 align=4
+ base size=65 base align=4
+QStyleOptionProgressBar (0xb33ae000) 0
+ QStyleOption (0xb33887bc) 0
+
+Class QStyleOptionProgressBarV2
+ size=76 align=4
+ base size=74 base align=4
+QStyleOptionProgressBarV2 (0xb33ae240) 0
+ QStyleOptionProgressBar (0xb33ae280) 0
+ QStyleOption (0xb3388f00) 0
+
+Class QStyleOptionMenuItem
+ size=96 align=4
+ base size=96 base align=4
+QStyleOptionMenuItem (0xb33ae300) 0
+ QStyleOption (0xb3388f3c) 0
+
+Class QStyleOptionQ3ListViewItem
+ size=64 align=4
+ base size=64 base align=4
+QStyleOptionQ3ListViewItem (0xb33ae500) 0
+ QStyleOption (0xb33c2b04) 0
+
+Class QStyleOptionQ3DockWindow
+ size=48 align=4
+ base size=46 base align=4
+QStyleOptionQ3DockWindow (0xb33ae880) 0
+ QStyleOption (0xb33d6168) 0
+
+Class QStyleOptionDockWidget
+ size=52 align=4
+ base size=51 base align=4
+QStyleOptionDockWidget (0xb33aea80) 0
+ QStyleOption (0xb33d64b0) 0
+
+Class QStyleOptionDockWidgetV2
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionDockWidgetV2 (0xb33aec80) 0
+ QStyleOptionDockWidget (0xb33aecc0) 0
+ QStyleOption (0xb33d6a50) 0
+
+Class QStyleOptionViewItem
+ size=80 align=4
+ base size=77 base align=4
+QStyleOptionViewItem (0xb3405000) 0
+ QStyleOption (0xb33d6e88) 0
+
+Class QStyleOptionViewItemV2
+ size=84 align=4
+ base size=84 base align=4
+QStyleOptionViewItemV2 (0xb3405280) 0
+ QStyleOptionViewItem (0xb34052c0) 0
+ QStyleOption (0xb340c780) 0
+
+Class QStyleOptionViewItemV3
+ size=92 align=4
+ base size=92 base align=4
+QStyleOptionViewItemV3 (0xb3405780) 0
+ QStyleOptionViewItemV2 (0xb34057c0) 0
+ QStyleOptionViewItem (0xb3405800) 0
+ QStyleOption (0xb340cd98) 0
+
+Class QStyleOptionViewItemV4
+ size=128 align=4
+ base size=128 base align=4
+QStyleOptionViewItemV4 (0xb3405b40) 0
+ QStyleOptionViewItemV3 (0xb3405b80) 0
+ QStyleOptionViewItemV2 (0xb3405bc0) 0
+ QStyleOptionViewItem (0xb3405c00) 0
+ QStyleOption (0xb3440258) 0
+
+Class QStyleOptionToolBox
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionToolBox (0xb3405f40) 0
+ QStyleOption (0xb3440d98) 0
+
+Class QStyleOptionToolBoxV2
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionToolBoxV2 (0xb3451140) 0
+ QStyleOptionToolBox (0xb3451180) 0
+ QStyleOption (0xb34573c0) 0
+
+Class QStyleOptionRubberBand
+ size=52 align=4
+ base size=49 base align=4
+QStyleOptionRubberBand (0xb34514c0) 0
+ QStyleOption (0xb3457924) 0
+
+Class QStyleOptionComplex
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionComplex (0xb34516c0) 0
+ QStyleOption (0xb3457c6c) 0
+
+Class QStyleOptionSlider
+ size=104 align=4
+ base size=101 base align=4
+QStyleOptionSlider (0xb3451940) 0
+ QStyleOptionComplex (0xb3451980) 0
+ QStyleOption (0xb326e12c) 0
+
+Class QStyleOptionSpinBox
+ size=64 align=4
+ base size=61 base align=4
+QStyleOptionSpinBox (0xb3451cc0) 0
+ QStyleOptionComplex (0xb3451d00) 0
+ QStyleOption (0xb326e9d8) 0
+
+Class QStyleOptionQ3ListView
+ size=84 align=4
+ base size=81 base align=4
+QStyleOptionQ3ListView (0xb3451f40) 0
+ QStyleOptionComplex (0xb3451f80) 0
+ QStyleOption (0xb326ee4c) 0
+
+Class QStyleOptionToolButton
+ size=96 align=4
+ base size=96 base align=4
+QStyleOptionToolButton (0xb3280240) 0
+ QStyleOptionComplex (0xb3280280) 0
+ QStyleOption (0xb3298780) 0
+
+Class QStyleOptionComboBox
+ size=92 align=4
+ base size=92 base align=4
+QStyleOptionComboBox (0xb3280600) 0
+ QStyleOptionComplex (0xb3280640) 0
+ QStyleOption (0xb32af474) 0
+
+Class QStyleOptionTitleBar
+ size=68 align=4
+ base size=68 base align=4
+QStyleOptionTitleBar (0xb3280840) 0
+ QStyleOptionComplex (0xb3280880) 0
+ QStyleOption (0xb32afd5c) 0
+
+Class QStyleOptionGroupBox
+ size=88 align=4
+ base size=88 base align=4
+QStyleOptionGroupBox (0xb3280ac0) 0
+ QStyleOptionComplex (0xb3280b00) 0
+ QStyleOption (0xb32d9528) 0
+
+Class QStyleOptionSizeGrip
+ size=56 align=4
+ base size=56 base align=4
+QStyleOptionSizeGrip (0xb3280d80) 0
+ QStyleOptionComplex (0xb3280dc0) 0
+ QStyleOption (0xb32d9dd4) 0
+
+Class QStyleOptionGraphicsItem
+ size=132 align=4
+ base size=132 base align=4
+QStyleOptionGraphicsItem (0xb3280fc0) 0
+ QStyleOption (0xb32ed0b4) 0
+
+Class QStyleHintReturn
+ size=8 align=4
+ base size=8 base align=4
+QStyleHintReturn (0xb32ed5a0) 0
+
+Class QStyleHintReturnMask
+ size=12 align=4
+ base size=12 base align=4
+QStyleHintReturnMask (0xb32ef400) 0
+ QStyleHintReturn (0xb32ed5dc) 0
+
+Class QStyleHintReturnVariant
+ size=20 align=4
+ base size=20 base align=4
+QStyleHintReturnVariant (0xb32ef480) 0
+ QStyleHintReturn (0xb32ed618) 0
+
+Vtable for QAbstractItemDelegate
+QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QAbstractItemDelegate)
+8 QAbstractItemDelegate::metaObject
+12 QAbstractItemDelegate::qt_metacast
+16 QAbstractItemDelegate::qt_metacall
+20 QAbstractItemDelegate::~QAbstractItemDelegate
+24 QAbstractItemDelegate::~QAbstractItemDelegate
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractItemDelegate::createEditor
+68 QAbstractItemDelegate::setEditorData
+72 QAbstractItemDelegate::setModelData
+76 QAbstractItemDelegate::updateEditorGeometry
+80 QAbstractItemDelegate::editorEvent
+
+Class QAbstractItemDelegate
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemDelegate (0xb32ef700) 0
+ vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 8u)
+ QObject (0xb32ed654) 0
+ primary-for QAbstractItemDelegate (0xb32ef700)
+
+Vtable for QAbstractItemView
+QAbstractItemView::_ZTV17QAbstractItemView: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QAbstractItemView)
+8 QAbstractItemView::metaObject
+12 QAbstractItemView::qt_metacast
+16 QAbstractItemView::qt_metacall
+20 QAbstractItemView::~QAbstractItemView
+24 QAbstractItemView::~QAbstractItemView
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QAbstractItemView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QAbstractItemView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QAbstractItemView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractScrollArea::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QAbstractItemView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QAbstractScrollArea::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QAbstractItemView::reset
+268 QAbstractItemView::setRootIndex
+272 QAbstractItemView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QAbstractItemView::dataChanged
+284 QAbstractItemView::rowsInserted
+288 QAbstractItemView::rowsAboutToBeRemoved
+292 QAbstractItemView::selectionChanged
+296 QAbstractItemView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QAbstractItemView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 QAbstractItemView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI17QAbstractItemView)
+392 QAbstractItemView::_ZThn8_N17QAbstractItemViewD1Ev
+396 QAbstractItemView::_ZThn8_N17QAbstractItemViewD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractItemView
+ size=20 align=4
+ base size=20 base align=4
+QAbstractItemView (0xb32ef940) 0
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 8u)
+ QAbstractScrollArea (0xb32ef980) 0
+ primary-for QAbstractItemView (0xb32ef940)
+ QFrame (0xb32ef9c0) 0
+ primary-for QAbstractScrollArea (0xb32ef980)
+ QWidget (0xb3315460) 0
+ primary-for QFrame (0xb32ef9c0)
+ QObject (0xb32ed780) 0
+ primary-for QWidget (0xb3315460)
+ QPaintDevice (0xb32ed7bc) 8
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 392u)
+
+Vtable for QTreeView
+QTreeView::_ZTV9QTreeView: 105u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTreeView)
+8 QTreeView::metaObject
+12 QTreeView::qt_metacast
+16 QTreeView::qt_metacall
+20 QTreeView::~QTreeView
+24 QTreeView::~QTreeView
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QTreeView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTreeView::mousePressEvent
+84 QTreeView::mouseReleaseEvent
+88 QTreeView::mouseDoubleClickEvent
+92 QTreeView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QTreeView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTreeView::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QTreeView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTreeView::viewportEvent
+228 QTreeView::scrollContentsBy
+232 QTreeView::setModel
+236 QTreeView::setSelectionModel
+240 QTreeView::keyboardSearch
+244 QTreeView::visualRect
+248 QTreeView::scrollTo
+252 QTreeView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QTreeView::sizeHintForColumn
+264 QTreeView::reset
+268 QTreeView::setRootIndex
+272 QTreeView::doItemsLayout
+276 QTreeView::selectAll
+280 QTreeView::dataChanged
+284 QTreeView::rowsInserted
+288 QTreeView::rowsAboutToBeRemoved
+292 QTreeView::selectionChanged
+296 QTreeView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QTreeView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QTreeView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QTreeView::moveCursor
+344 QTreeView::horizontalOffset
+348 QTreeView::verticalOffset
+352 QTreeView::isIndexHidden
+356 QTreeView::setSelection
+360 QTreeView::visualRegionForSelection
+364 QTreeView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 QTreeView::drawRow
+388 QTreeView::drawBranches
+392 (int (*)(...))-0x000000008
+396 (int (*)(...))(& _ZTI9QTreeView)
+400 QTreeView::_ZThn8_N9QTreeViewD1Ev
+404 QTreeView::_ZThn8_N9QTreeViewD0Ev
+408 QWidget::_ZThn8_NK7QWidget7devTypeEv
+412 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+416 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTreeView
+ size=20 align=4
+ base size=20 base align=4
+QTreeView (0xb32efe00) 0
+ vptr=((& QTreeView::_ZTV9QTreeView) + 8u)
+ QAbstractItemView (0xb32efe40) 0
+ primary-for QTreeView (0xb32efe00)
+ QAbstractScrollArea (0xb32efe80) 0
+ primary-for QAbstractItemView (0xb32efe40)
+ QFrame (0xb32efec0) 0
+ primary-for QAbstractScrollArea (0xb32efe80)
+ QWidget (0xb334ab40) 0
+ primary-for QFrame (0xb32efec0)
+ QObject (0xb32edac8) 0
+ primary-for QWidget (0xb334ab40)
+ QPaintDevice (0xb32edb04) 8
+ vptr=((& QTreeView::_ZTV9QTreeView) + 400u)
+
+Class QHelpContentItem
+ size=4 align=4
+ base size=4 base align=4
+QHelpContentItem (0xb32edd20) 0
+
+Vtable for QHelpContentModel
+QHelpContentModel::_ZTV17QHelpContentModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QHelpContentModel)
+8 QHelpContentModel::metaObject
+12 QHelpContentModel::qt_metacast
+16 QHelpContentModel::qt_metacall
+20 QHelpContentModel::~QHelpContentModel
+24 QHelpContentModel::~QHelpContentModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QHelpContentModel::index
+60 QHelpContentModel::parent
+64 QHelpContentModel::rowCount
+68 QHelpContentModel::columnCount
+72 QAbstractItemModel::hasChildren
+76 QHelpContentModel::data
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QHelpContentModel
+ size=12 align=4
+ base size=12 base align=4
+QHelpContentModel (0xb317e1c0) 0
+ vptr=((& QHelpContentModel::_ZTV17QHelpContentModel) + 8u)
+ QAbstractItemModel (0xb317e200) 0
+ primary-for QHelpContentModel (0xb317e1c0)
+ QObject (0xb32edd5c) 0
+ primary-for QAbstractItemModel (0xb317e200)
+
+Vtable for QHelpContentWidget
+QHelpContentWidget::_ZTV18QHelpContentWidget: 105u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QHelpContentWidget)
+8 QHelpContentWidget::metaObject
+12 QHelpContentWidget::qt_metacast
+16 QHelpContentWidget::qt_metacall
+20 QHelpContentWidget::~QHelpContentWidget
+24 QHelpContentWidget::~QHelpContentWidget
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QTreeView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTreeView::mousePressEvent
+84 QTreeView::mouseReleaseEvent
+88 QTreeView::mouseDoubleClickEvent
+92 QTreeView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QTreeView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTreeView::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QTreeView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTreeView::viewportEvent
+228 QTreeView::scrollContentsBy
+232 QTreeView::setModel
+236 QTreeView::setSelectionModel
+240 QTreeView::keyboardSearch
+244 QTreeView::visualRect
+248 QTreeView::scrollTo
+252 QTreeView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QTreeView::sizeHintForColumn
+264 QTreeView::reset
+268 QTreeView::setRootIndex
+272 QTreeView::doItemsLayout
+276 QTreeView::selectAll
+280 QTreeView::dataChanged
+284 QTreeView::rowsInserted
+288 QTreeView::rowsAboutToBeRemoved
+292 QTreeView::selectionChanged
+296 QTreeView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QTreeView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QTreeView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QTreeView::moveCursor
+344 QTreeView::horizontalOffset
+348 QTreeView::verticalOffset
+352 QTreeView::isIndexHidden
+356 QTreeView::setSelection
+360 QTreeView::visualRegionForSelection
+364 QTreeView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 QTreeView::drawRow
+388 QTreeView::drawBranches
+392 (int (*)(...))-0x000000008
+396 (int (*)(...))(& _ZTI18QHelpContentWidget)
+400 QHelpContentWidget::_ZThn8_N18QHelpContentWidgetD1Ev
+404 QHelpContentWidget::_ZThn8_N18QHelpContentWidgetD0Ev
+408 QWidget::_ZThn8_NK7QWidget7devTypeEv
+412 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+416 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpContentWidget
+ size=36 align=4
+ base size=36 base align=4
+QHelpContentWidget (0xb317e440) 0
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 8u)
+ QTreeView (0xb317e480) 0
+ primary-for QHelpContentWidget (0xb317e440)
+ QAbstractItemView (0xb317e4c0) 0
+ primary-for QTreeView (0xb317e480)
+ QAbstractScrollArea (0xb317e500) 0
+ primary-for QAbstractItemView (0xb317e4c0)
+ QFrame (0xb317e540) 0
+ primary-for QAbstractScrollArea (0xb317e500)
+ QWidget (0xb3190320) 0
+ primary-for QFrame (0xb317e540)
+ QObject (0xb32ede88) 0
+ primary-for QWidget (0xb3190320)
+ QPaintDevice (0xb32edec4) 8
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 400u)
+
+Class QHelpSearchQuery
+ size=8 align=4
+ base size=8 base align=4
+QHelpSearchQuery (0xb31a0000) 0
+
+Vtable for QHelpSearchEngine
+QHelpSearchEngine::_ZTV17QHelpSearchEngine: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QHelpSearchEngine)
+8 QHelpSearchEngine::metaObject
+12 QHelpSearchEngine::qt_metacast
+16 QHelpSearchEngine::qt_metacall
+20 QHelpSearchEngine::~QHelpSearchEngine
+24 QHelpSearchEngine::~QHelpSearchEngine
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpSearchEngine
+ size=12 align=4
+ base size=12 base align=4
+QHelpSearchEngine (0xb317e940) 0
+ vptr=((& QHelpSearchEngine::_ZTV17QHelpSearchEngine) + 8u)
+ QObject (0xb31a0528) 0
+ primary-for QHelpSearchEngine (0xb317e940)
+
+Vtable for QHelpSearchResultWidget
+QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+8 QHelpSearchResultWidget::metaObject
+12 QHelpSearchResultWidget::qt_metacast
+16 QHelpSearchResultWidget::qt_metacall
+20 QHelpSearchResultWidget::~QHelpSearchResultWidget
+24 QHelpSearchResultWidget::~QHelpSearchResultWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+232 QHelpSearchResultWidget::_ZThn8_N23QHelpSearchResultWidgetD1Ev
+236 QHelpSearchResultWidget::_ZThn8_N23QHelpSearchResultWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchResultWidget
+ size=24 align=4
+ base size=24 base align=4
+QHelpSearchResultWidget (0xb317eb80) 0
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 8u)
+ QWidget (0xb31aa960) 0
+ primary-for QHelpSearchResultWidget (0xb317eb80)
+ QObject (0xb31a0654) 0
+ primary-for QWidget (0xb31aa960)
+ QPaintDevice (0xb31a0690) 8
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 232u)
+
+Vtable for QHelpEngineCore
+QHelpEngineCore::_ZTV15QHelpEngineCore: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QHelpEngineCore)
+8 QHelpEngineCore::metaObject
+12 QHelpEngineCore::qt_metacast
+16 QHelpEngineCore::qt_metacall
+20 QHelpEngineCore::~QHelpEngineCore
+24 QHelpEngineCore::~QHelpEngineCore
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpEngineCore
+ size=12 align=4
+ base size=12 base align=4
+QHelpEngineCore (0xb317edc0) 0
+ vptr=((& QHelpEngineCore::_ZTV15QHelpEngineCore) + 8u)
+ QObject (0xb31a07bc) 0
+ primary-for QHelpEngineCore (0xb317edc0)
+
+Vtable for QHelpEngine
+QHelpEngine::_ZTV11QHelpEngine: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QHelpEngine)
+8 QHelpEngine::metaObject
+12 QHelpEngine::qt_metacast
+16 QHelpEngine::qt_metacall
+20 QHelpEngine::~QHelpEngine
+24 QHelpEngine::~QHelpEngine
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpEngine
+ size=16 align=4
+ base size=16 base align=4
+QHelpEngine (0xb31c9000) 0
+ vptr=((& QHelpEngine::_ZTV11QHelpEngine) + 8u)
+ QHelpEngineCore (0xb31c9040) 0
+ primary-for QHelpEngine (0xb31c9000)
+ QObject (0xb31a08e8) 0
+ primary-for QHelpEngineCore (0xb31c9040)
+
+Vtable for QHelpSearchQueryWidget
+QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+8 QHelpSearchQueryWidget::metaObject
+12 QHelpSearchQueryWidget::qt_metacast
+16 QHelpSearchQueryWidget::qt_metacall
+20 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+24 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QHelpSearchQueryWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+232 QHelpSearchQueryWidget::_ZThn8_N22QHelpSearchQueryWidgetD1Ev
+236 QHelpSearchQueryWidget::_ZThn8_N22QHelpSearchQueryWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchQueryWidget
+ size=24 align=4
+ base size=24 base align=4
+QHelpSearchQueryWidget (0xb31c9280) 0
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 8u)
+ QWidget (0xb31d1190) 0
+ primary-for QHelpSearchQueryWidget (0xb31c9280)
+ QObject (0xb31a0a14) 0
+ primary-for QWidget (0xb31d1190)
+ QPaintDevice (0xb31a0a50) 8
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 232u)
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QStringListModel)
+8 QStringListModel::metaObject
+12 QStringListModel::qt_metacast
+16 QStringListModel::qt_metacall
+20 QStringListModel::~QStringListModel
+24 QStringListModel::~QStringListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 QStringListModel::rowCount
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 QStringListModel::data
+80 QStringListModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QStringListModel::supportedDropActions
+116 QStringListModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QStringListModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QStringListModel::flags
+144 QStringListModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QStringListModel
+ size=12 align=4
+ base size=12 base align=4
+QStringListModel (0xb31c94c0) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 8u)
+ QAbstractListModel (0xb31c9500) 0
+ primary-for QStringListModel (0xb31c94c0)
+ QAbstractItemModel (0xb31c9540) 0
+ primary-for QAbstractListModel (0xb31c9500)
+ QObject (0xb31a0b7c) 0
+ primary-for QAbstractItemModel (0xb31c9540)
+
+Vtable for QListView
+QListView::_ZTV9QListView: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QListView)
+8 QListView::metaObject
+12 QListView::qt_metacast
+16 QListView::qt_metacall
+20 QListView::~QListView
+24 QListView::~QListView
+28 QListView::event
+32 QObject::eventFilter
+36 QListView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QListView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QListView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QListView::paintEvent
+128 QWidget::moveEvent
+132 QListView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QListView::dragMoveEvent
+160 QListView::dragLeaveEvent
+164 QListView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QListView::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 QListView::visualRect
+248 QListView::scrollTo
+252 QListView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QListView::reset
+268 QListView::setRootIndex
+272 QListView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QListView::dataChanged
+284 QListView::rowsInserted
+288 QListView::rowsAboutToBeRemoved
+292 QListView::selectionChanged
+296 QListView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QListView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QListView::moveCursor
+344 QListView::horizontalOffset
+348 QListView::verticalOffset
+352 QListView::isIndexHidden
+356 QListView::setSelection
+360 QListView::visualRegionForSelection
+364 QListView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QListView::startDrag
+380 QListView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI9QListView)
+392 QListView::_ZThn8_N9QListViewD1Ev
+396 QListView::_ZThn8_N9QListViewD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QListView
+ size=20 align=4
+ base size=20 base align=4
+QListView (0xb31c9780) 0
+ vptr=((& QListView::_ZTV9QListView) + 8u)
+ QAbstractItemView (0xb31c97c0) 0
+ primary-for QListView (0xb31c9780)
+ QAbstractScrollArea (0xb31c9800) 0
+ primary-for QAbstractItemView (0xb31c97c0)
+ QFrame (0xb31c9840) 0
+ primary-for QAbstractScrollArea (0xb31c9800)
+ QWidget (0xb31e2af0) 0
+ primary-for QFrame (0xb31c9840)
+ QObject (0xb31a0ca8) 0
+ primary-for QWidget (0xb31e2af0)
+ QPaintDevice (0xb31a0ce4) 8
+ vptr=((& QListView::_ZTV9QListView) + 392u)
+
+Vtable for QHelpIndexModel
+QHelpIndexModel::_ZTV15QHelpIndexModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QHelpIndexModel)
+8 QHelpIndexModel::metaObject
+12 QHelpIndexModel::qt_metacast
+16 QHelpIndexModel::qt_metacall
+20 QHelpIndexModel::~QHelpIndexModel
+24 QHelpIndexModel::~QHelpIndexModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 QStringListModel::rowCount
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 QStringListModel::data
+80 QStringListModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QStringListModel::supportedDropActions
+116 QStringListModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QStringListModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QStringListModel::flags
+144 QStringListModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QHelpIndexModel
+ size=16 align=4
+ base size=16 base align=4
+QHelpIndexModel (0xb31c9b40) 0
+ vptr=((& QHelpIndexModel::_ZTV15QHelpIndexModel) + 8u)
+ QStringListModel (0xb31c9b80) 0
+ primary-for QHelpIndexModel (0xb31c9b40)
+ QAbstractListModel (0xb31c9bc0) 0
+ primary-for QStringListModel (0xb31c9b80)
+ QAbstractItemModel (0xb31c9c00) 0
+ primary-for QAbstractListModel (0xb31c9bc0)
+ QObject (0xb31a0f00) 0
+ primary-for QAbstractItemModel (0xb31c9c00)
+
+Vtable for QHelpIndexWidget
+QHelpIndexWidget::_ZTV16QHelpIndexWidget: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+8 QHelpIndexWidget::metaObject
+12 QHelpIndexWidget::qt_metacast
+16 QHelpIndexWidget::qt_metacall
+20 QHelpIndexWidget::~QHelpIndexWidget
+24 QHelpIndexWidget::~QHelpIndexWidget
+28 QListView::event
+32 QObject::eventFilter
+36 QListView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QListView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QListView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QListView::paintEvent
+128 QWidget::moveEvent
+132 QListView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QListView::dragMoveEvent
+160 QListView::dragLeaveEvent
+164 QListView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QListView::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 QListView::visualRect
+248 QListView::scrollTo
+252 QListView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QListView::reset
+268 QListView::setRootIndex
+272 QListView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QListView::dataChanged
+284 QListView::rowsInserted
+288 QListView::rowsAboutToBeRemoved
+292 QListView::selectionChanged
+296 QListView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QListView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QListView::moveCursor
+344 QListView::horizontalOffset
+348 QListView::verticalOffset
+352 QListView::isIndexHidden
+356 QListView::setSelection
+360 QListView::visualRegionForSelection
+364 QListView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QListView::startDrag
+380 QListView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+392 QHelpIndexWidget::_ZThn8_N16QHelpIndexWidgetD1Ev
+396 QHelpIndexWidget::_ZThn8_N16QHelpIndexWidgetD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpIndexWidget
+ size=20 align=4
+ base size=20 base align=4
+QHelpIndexWidget (0xb31c9e40) 0
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 8u)
+ QListView (0xb31c9e80) 0
+ primary-for QHelpIndexWidget (0xb31c9e40)
+ QAbstractItemView (0xb31c9ec0) 0
+ primary-for QListView (0xb31c9e80)
+ QAbstractScrollArea (0xb31c9f00) 0
+ primary-for QAbstractItemView (0xb31c9ec0)
+ QFrame (0xb31c9f40) 0
+ primary-for QAbstractScrollArea (0xb31c9f00)
+ QWidget (0xb320f3c0) 0
+ primary-for QFrame (0xb31c9f40)
+ QObject (0xb321403c) 0
+ primary-for QWidget (0xb320f3c0)
+ QPaintDevice (0xb3214078) 8
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 392u)
+
diff --git a/tests/auto/bic/data/QtHelp.4.6.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtHelp.4.6.0.linux-gcc-amd64.txt
new file mode 100644
index 000000000..26d6d9c6a
--- /dev/null
+++ b/tests/auto/bic/data/QtHelp.4.6.0.linux-gcc-amd64.txt
@@ -0,0 +1,5492 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0x7f4f37146230) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0x7f4f37146e70) 0
+
+Class qIsNull(double)::U
+ size=8 align=8
+ base size=8 base align=8
+qIsNull(double)::U (0x7f4f37175540) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0x7f4f371757e0) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0x7f4f371ad690) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0x7f4f371ade70) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0x7f4f371dc5b0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0x7f4f367e0150) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0x7f4f3684a310) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0x7f4f36888cb0) 0
+ QBasicAtomicInt (0x7f4f36888d20) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0x7f4f364d74d0) 0 empty
+
+Class __locale_struct
+ size=232 align=8
+ base size=232 base align=8
+__locale_struct (0x7f4f364d7700) 0
+
+Class QByteArray::Data
+ size=32 align=8
+ base size=32 base align=8
+QByteArray::Data (0x7f4f36513af0) 0
+
+Class QByteArray
+ size=8 align=8
+ base size=8 base align=8
+QByteArray (0x7f4f36513a80) 0
+
+Class QByteRef
+ size=16 align=8
+ base size=12 base align=8
+QByteRef (0x7f4f365b7380) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0x7f4f364b7d20) 0 empty
+
+Class QString::Data
+ size=32 align=8
+ base size=32 base align=8
+QString::Data (0x7f4f364cf5b0) 0
+
+Class QString
+ size=8 align=8
+ base size=8 base align=8
+QString (0x7f4f36430bd0) 0
+
+Class QLatin1String
+ size=8 align=8
+ base size=8 base align=8
+QLatin1String (0x7f4f363a79a0) 0
+
+Class QCharRef
+ size=16 align=8
+ base size=12 base align=8
+QCharRef (0x7f4f36245000) 0
+
+Class QConstString
+ size=8 align=8
+ base size=8 base align=8
+QConstString (0x7f4f361908c0) 0
+ QString (0x7f4f36190930) 0
+
+Class QStringRef
+ size=16 align=8
+ base size=16 base align=8
+QStringRef (0x7f4f361b6310) 0
+
+Class QGenericArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericArgument (0x7f4f3602e700) 0
+
+Class QGenericReturnArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericReturnArgument (0x7f4f360382a0) 0
+ QGenericArgument (0x7f4f36038310) 0
+
+Class QMetaObject
+ size=32 align=8
+ base size=32 base align=8
+QMetaObject (0x7f4f36038b60) 0
+
+Class QMetaObjectExtraData
+ size=16 align=8
+ base size=16 base align=8
+QMetaObjectExtraData (0x7f4f36061bd0) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9exception)
+16 std::exception::~exception
+24 std::exception::~exception
+32 std::exception::what
+
+Class std::exception
+ size=8 align=8
+ base size=8 base align=8
+std::exception (0x7f4f360b61c0) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 16u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13bad_exception)
+16 std::bad_exception::~bad_exception
+24 std::bad_exception::~bad_exception
+32 std::bad_exception::what
+
+Class std::bad_exception
+ size=8 align=8
+ base size=8 base align=8
+std::bad_exception (0x7f4f360b6770) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u)
+ std::exception (0x7f4f360b67e0) 0 nearly-empty
+ primary-for std::bad_exception (0x7f4f360b6770)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9bad_alloc)
+16 std::bad_alloc::~bad_alloc
+24 std::bad_alloc::~bad_alloc
+32 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=8 align=8
+ base size=8 base align=8
+std::bad_alloc (0x7f4f360b6930) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u)
+ std::exception (0x7f4f360cc000) 0 nearly-empty
+ primary-for std::bad_alloc (0x7f4f360b6930)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0x7f4f360cc850) 0 empty
+
+Class QListData::Data
+ size=32 align=8
+ base size=32 base align=8
+QListData::Data (0x7f4f360ccd90) 0
+
+Class QListData
+ size=8 align=8
+ base size=8 base align=8
+QListData (0x7f4f360ccd20) 0
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0x7f4f35df4850) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QObjectData)
+16 __cxa_pure_virtual
+24 __cxa_pure_virtual
+
+Class QObjectData
+ size=48 align=8
+ base size=48 base align=8
+QObjectData (0x7f4f35e162a0) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 16u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QObject)
+16 QObject::metaObject
+24 QObject::qt_metacast
+32 QObject::qt_metacall
+40 QObject::~QObject
+48 QObject::~QObject
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QObject
+ size=16 align=8
+ base size=16 base align=8
+QObject (0x7f4f35e165b0) 0
+ vptr=((& QObject::_ZTV7QObject) + 16u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QObjectUserData)
+16 QObjectUserData::~QObjectUserData
+24 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=8 align=8
+ base size=8 base align=8
+QObjectUserData (0x7f4f35e9ab60) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QIODevice)
+16 QIODevice::metaObject
+24 QIODevice::qt_metacast
+32 QIODevice::qt_metacall
+40 QIODevice::~QIODevice
+48 QIODevice::~QIODevice
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QIODevice::isSequential
+120 QIODevice::open
+128 QIODevice::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QIODevice::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 __cxa_pure_virtual
+224 QIODevice::readLineData
+232 __cxa_pure_virtual
+
+Class QIODevice
+ size=16 align=8
+ base size=16 base align=8
+QIODevice (0x7f4f35eac150) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 16u)
+ QObject (0x7f4f35eac1c0) 0
+ primary-for QIODevice (0x7f4f35eac150)
+
+Class _IO_marker
+ size=24 align=8
+ base size=24 base align=8
+_IO_marker (0x7f4f35d0ccb0) 0
+
+Class _IO_FILE
+ size=216 align=8
+ base size=216 base align=8
+_IO_FILE (0x7f4f35d0cd20) 0
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QFile)
+16 QFile::metaObject
+24 QFile::qt_metacast
+32 QFile::qt_metacall
+40 QFile::~QFile
+48 QFile::~QFile
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFile::isSequential
+120 QFile::open
+128 QFile::close
+136 QFile::pos
+144 QFile::size
+152 QFile::seek
+160 QFile::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QFile::readData
+224 QFile::readLineData
+232 QFile::writeData
+240 QFile::fileEngine
+
+Class QFile
+ size=16 align=8
+ base size=16 base align=8
+QFile (0x7f4f35d0ce00) 0
+ vptr=((& QFile::_ZTV5QFile) + 16u)
+ QIODevice (0x7f4f35d0ce70) 0
+ primary-for QFile (0x7f4f35d0ce00)
+ QObject (0x7f4f35d0cee0) 0
+ primary-for QIODevice (0x7f4f35d0ce70)
+
+Class QFileInfo
+ size=8 align=8
+ base size=8 base align=8
+QFileInfo (0x7f4f35db0070) 0
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QDataStream)
+16 QDataStream::~QDataStream
+24 QDataStream::~QDataStream
+
+Class QDataStream
+ size=40 align=8
+ base size=40 base align=8
+QDataStream (0x7f4f35c04a10) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 16u)
+
+Class QRegExp
+ size=8 align=8
+ base size=8 base align=8
+QRegExp (0x7f4f35c6ce70) 0
+
+Class QStringMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QStringMatcher::Data (0x7f4f35ad52a0) 0
+
+Class QStringMatcher
+ size=1048 align=8
+ base size=1048 base align=8
+QStringMatcher (0x7f4f35cc9c40) 0
+
+Class QStringList
+ size=8 align=8
+ base size=8 base align=8
+QStringList (0x7f4f35ad5850) 0
+ QList<QString> (0x7f4f35ad58c0) 0
+
+Class QDir
+ size=8 align=8
+ base size=8 base align=8
+QDir (0x7f4f35b734d0) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0x7f4f35a1a8c0) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0x7f4f35a1a930) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=24 align=8
+ base size=20 base align=8
+QAbstractFileEngine::MapExtensionOption (0x7f4f35a1a9a0) 0
+ QAbstractFileEngine::ExtensionOption (0x7f4f35a1aa10) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngine::MapExtensionReturn (0x7f4f35a1abd0) 0
+ QAbstractFileEngine::ExtensionReturn (0x7f4f35a1ac40) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngine::UnMapExtensionOption (0x7f4f35a1acb0) 0
+ QAbstractFileEngine::ExtensionOption (0x7f4f35a1ad20) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+16 QAbstractFileEngine::~QAbstractFileEngine
+24 QAbstractFileEngine::~QAbstractFileEngine
+32 QAbstractFileEngine::open
+40 QAbstractFileEngine::close
+48 QAbstractFileEngine::flush
+56 QAbstractFileEngine::size
+64 QAbstractFileEngine::pos
+72 QAbstractFileEngine::seek
+80 QAbstractFileEngine::isSequential
+88 QAbstractFileEngine::remove
+96 QAbstractFileEngine::copy
+104 QAbstractFileEngine::rename
+112 QAbstractFileEngine::link
+120 QAbstractFileEngine::mkdir
+128 QAbstractFileEngine::rmdir
+136 QAbstractFileEngine::setSize
+144 QAbstractFileEngine::caseSensitive
+152 QAbstractFileEngine::isRelativePath
+160 QAbstractFileEngine::entryList
+168 QAbstractFileEngine::fileFlags
+176 QAbstractFileEngine::setPermissions
+184 QAbstractFileEngine::fileName
+192 QAbstractFileEngine::ownerId
+200 QAbstractFileEngine::owner
+208 QAbstractFileEngine::fileTime
+216 QAbstractFileEngine::setFileName
+224 QAbstractFileEngine::handle
+232 QAbstractFileEngine::beginEntryList
+240 QAbstractFileEngine::endEntryList
+248 QAbstractFileEngine::read
+256 QAbstractFileEngine::readLine
+264 QAbstractFileEngine::write
+272 QAbstractFileEngine::extension
+280 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=16 align=8
+ base size=16 base align=8
+QAbstractFileEngine (0x7f4f35a00850) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 16u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+16 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+24 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+32 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=8 align=8
+ base size=8 base align=8
+QAbstractFileEngineHandler (0x7f4f35a52bd0) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 16u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+16 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+24 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QAbstractFileEngineIterator::currentFileInfo
+64 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=16 align=8
+ base size=16 base align=8
+QAbstractFileEngineIterator (0x7f4f35a52d90) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 16u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBuffer)
+16 QBuffer::metaObject
+24 QBuffer::qt_metacast
+32 QBuffer::qt_metacall
+40 QBuffer::~QBuffer
+48 QBuffer::~QBuffer
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QBuffer::connectNotify
+104 QBuffer::disconnectNotify
+112 QIODevice::isSequential
+120 QBuffer::open
+128 QBuffer::close
+136 QBuffer::pos
+144 QBuffer::size
+152 QBuffer::seek
+160 QBuffer::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QBuffer::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QBuffer::readData
+224 QIODevice::readLineData
+232 QBuffer::writeData
+
+Class QBuffer
+ size=16 align=8
+ base size=16 base align=8
+QBuffer (0x7f4f35a65690) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 16u)
+ QIODevice (0x7f4f35a65700) 0
+ primary-for QBuffer (0x7f4f35a65690)
+ QObject (0x7f4f35a65770) 0
+ primary-for QIODevice (0x7f4f35a65700)
+
+Class QHashData::Node
+ size=16 align=8
+ base size=16 base align=8
+QHashData::Node (0x7f4f35aa6e00) 0
+
+Class QHashData
+ size=40 align=8
+ base size=40 base align=8
+QHashData (0x7f4f35aa6d90) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0x7f4f35acb150) 0 empty
+
+Class QMapData::Node
+ size=16 align=8
+ base size=16 base align=8
+QMapData::Node (0x7f4f359c8a80) 0
+
+Class QMapData
+ size=128 align=8
+ base size=128 base align=8
+QMapData (0x7f4f359c8a10) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSystemLocale)
+16 QSystemLocale::~QSystemLocale
+24 QSystemLocale::~QSystemLocale
+32 QSystemLocale::query
+40 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=8 align=8
+ base size=8 base align=8
+QSystemLocale (0x7f4f35706690) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 16u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0x7f4f35753d90) 0
+
+Class QLocale
+ size=8 align=8
+ base size=8 base align=8
+QLocale (0x7f4f35706af0) 0
+
+Class QTextCodec::ConverterState
+ size=32 align=8
+ base size=32 base align=8
+QTextCodec::ConverterState (0x7f4f357abbd0) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextCodec)
+16 __cxa_pure_virtual
+24 QTextCodec::aliases
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+48 __cxa_pure_virtual
+56 QTextCodec::~QTextCodec
+64 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=8 align=8
+ base size=8 base align=8
+QTextCodec (0x7f4f3579b460) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u)
+
+Class QTextEncoder
+ size=40 align=8
+ base size=40 base align=8
+QTextEncoder (0x7f4f35618150) 0
+
+Class QTextDecoder
+ size=40 align=8
+ base size=40 base align=8
+QTextDecoder (0x7f4f35618f50) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextStream)
+16 QTextStream::~QTextStream
+24 QTextStream::~QTextStream
+
+Class QTextStream
+ size=16 align=8
+ base size=16 base align=8
+QTextStream (0x7f4f35621d90) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 16u)
+
+Class QTextStreamManipulator
+ size=40 align=8
+ base size=38 base align=8
+QTextStreamManipulator (0x7f4f35698a80) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextIStream)
+16 QTextIStream::~QTextIStream
+24 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=16 align=8
+ base size=16 base align=8
+QTextIStream (0x7f4f354ca070) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 16u)
+ QTextStream (0x7f4f354ca0e0) 0
+ primary-for QTextIStream (0x7f4f354ca070)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextOStream)
+16 QTextOStream::~QTextOStream
+24 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=16 align=8
+ base size=16 base align=8
+QTextOStream (0x7f4f354d6ee0) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 16u)
+ QTextStream (0x7f4f354d6f50) 0
+ primary-for QTextOStream (0x7f4f354d6ee0)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0x7f4f354ecd90) 0
+
+Class timespec
+ size=16 align=8
+ base size=16 base align=8
+timespec (0x7f4f354f90e0) 0
+
+Class timeval
+ size=16 align=8
+ base size=16 base align=8
+timeval (0x7f4f354f9150) 0
+
+Class __pthread_internal_list
+ size=16 align=8
+ base size=16 base align=8
+__pthread_internal_list (0x7f4f354f92a0) 0
+
+Class random_data
+ size=48 align=8
+ base size=48 base align=8
+random_data (0x7f4f354f9850) 0
+
+Class drand48_data
+ size=24 align=8
+ base size=24 base align=8
+drand48_data (0x7f4f354f98c0) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0x7f4f354f9930) 0
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0x7f4f354b5620) 0
+
+Class QDebug::Stream
+ size=40 align=8
+ base size=34 base align=8
+QDebug::Stream (0x7f4f35317150) 0
+
+Class QDebug
+ size=8 align=8
+ base size=8 base align=8
+QDebug (0x7f4f353170e0) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0x7f4f351c60e0) 0 empty
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QDirIterator)
+16 QDirIterator::~QDirIterator
+24 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=16 align=8
+ base size=16 base align=8
+QDirIterator (0x7f4f351d7700) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 16u)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+16 QFileSystemWatcher::metaObject
+24 QFileSystemWatcher::qt_metacast
+32 QFileSystemWatcher::qt_metacall
+40 QFileSystemWatcher::~QFileSystemWatcher
+48 QFileSystemWatcher::~QFileSystemWatcher
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemWatcher (0x7f4f35231540) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u)
+ QObject (0x7f4f352315b0) 0
+ primary-for QFileSystemWatcher (0x7f4f35231540)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFSFileEngine)
+16 QFSFileEngine::~QFSFileEngine
+24 QFSFileEngine::~QFSFileEngine
+32 QFSFileEngine::open
+40 QFSFileEngine::close
+48 QFSFileEngine::flush
+56 QFSFileEngine::size
+64 QFSFileEngine::pos
+72 QFSFileEngine::seek
+80 QFSFileEngine::isSequential
+88 QFSFileEngine::remove
+96 QFSFileEngine::copy
+104 QFSFileEngine::rename
+112 QFSFileEngine::link
+120 QFSFileEngine::mkdir
+128 QFSFileEngine::rmdir
+136 QFSFileEngine::setSize
+144 QFSFileEngine::caseSensitive
+152 QFSFileEngine::isRelativePath
+160 QFSFileEngine::entryList
+168 QFSFileEngine::fileFlags
+176 QFSFileEngine::setPermissions
+184 QFSFileEngine::fileName
+192 QFSFileEngine::ownerId
+200 QFSFileEngine::owner
+208 QFSFileEngine::fileTime
+216 QFSFileEngine::setFileName
+224 QFSFileEngine::handle
+232 QFSFileEngine::beginEntryList
+240 QFSFileEngine::endEntryList
+248 QFSFileEngine::read
+256 QFSFileEngine::readLine
+264 QFSFileEngine::write
+272 QFSFileEngine::extension
+280 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=16 align=8
+ base size=16 base align=8
+QFSFileEngine (0x7f4f35244a80) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 16u)
+ QAbstractFileEngine (0x7f4f35244af0) 0
+ primary-for QFSFileEngine (0x7f4f35244a80)
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0x7f4f35253e70) 0
+
+Class QProcessEnvironment
+ size=8 align=8
+ base size=8 base align=8
+QProcessEnvironment (0x7f4f3529e1c0) 0
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QProcess)
+16 QProcess::metaObject
+24 QProcess::qt_metacast
+32 QProcess::qt_metacall
+40 QProcess::~QProcess
+48 QProcess::~QProcess
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QProcess::isSequential
+120 QIODevice::open
+128 QProcess::close
+136 QIODevice::pos
+144 QIODevice::size
+152 QIODevice::seek
+160 QProcess::atEnd
+168 QIODevice::reset
+176 QProcess::bytesAvailable
+184 QProcess::bytesToWrite
+192 QProcess::canReadLine
+200 QProcess::waitForReadyRead
+208 QProcess::waitForBytesWritten
+216 QProcess::readData
+224 QIODevice::readLineData
+232 QProcess::writeData
+240 QProcess::setupChildProcess
+
+Class QProcess
+ size=16 align=8
+ base size=16 base align=8
+QProcess (0x7f4f3529ecb0) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 16u)
+ QIODevice (0x7f4f3529ed20) 0
+ primary-for QProcess (0x7f4f3529ecb0)
+ QObject (0x7f4f3529ed90) 0
+ primary-for QIODevice (0x7f4f3529ed20)
+
+Class QResource
+ size=8 align=8
+ base size=8 base align=8
+QResource (0x7f4f350e41c0) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0x7f4f350e4e70) 0 empty
+
+Class QVariant::PrivateShared
+ size=16 align=8
+ base size=12 base align=8
+QVariant::PrivateShared (0x7f4f34fe2700) 0
+
+Class QVariant::Private::Data
+ size=8 align=8
+ base size=8 base align=8
+QVariant::Private::Data (0x7f4f34fe2a10) 0
+
+Class QVariant::Private
+ size=16 align=8
+ base size=12 base align=8
+QVariant::Private (0x7f4f34fe27e0) 0
+
+Class QVariant::Handler
+ size=72 align=8
+ base size=72 base align=8
+QVariant::Handler (0x7f4f34ff1700) 0
+
+Class QVariant
+ size=16 align=8
+ base size=16 base align=8
+QVariant (0x7f4f34fb27e0) 0
+
+Class QVariantComparisonHelper
+ size=8 align=8
+ base size=8 base align=8
+QVariantComparisonHelper (0x7f4f34ea19a0) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSettings)
+16 QSettings::metaObject
+24 QSettings::qt_metacast
+32 QSettings::qt_metacall
+40 QSettings::~QSettings
+48 QSettings::~QSettings
+56 QSettings::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSettings
+ size=16 align=8
+ base size=16 base align=8
+QSettings (0x7f4f34ec7ee0) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 16u)
+ QObject (0x7f4f34ec7f50) 0
+ primary-for QSettings (0x7f4f34ec7ee0)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTemporaryFile)
+16 QTemporaryFile::metaObject
+24 QTemporaryFile::qt_metacast
+32 QTemporaryFile::qt_metacall
+40 QTemporaryFile::~QTemporaryFile
+48 QTemporaryFile::~QTemporaryFile
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFile::isSequential
+120 QTemporaryFile::open
+128 QFile::close
+136 QFile::pos
+144 QFile::size
+152 QFile::seek
+160 QFile::atEnd
+168 QIODevice::reset
+176 QIODevice::bytesAvailable
+184 QIODevice::bytesToWrite
+192 QIODevice::canReadLine
+200 QIODevice::waitForReadyRead
+208 QIODevice::waitForBytesWritten
+216 QFile::readData
+224 QFile::readLineData
+232 QFile::writeData
+240 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=16 align=8
+ base size=16 base align=8
+QTemporaryFile (0x7f4f34f4c2a0) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u)
+ QFile (0x7f4f34f4c310) 0
+ primary-for QTemporaryFile (0x7f4f34f4c2a0)
+ QIODevice (0x7f4f34f4c380) 0
+ primary-for QFile (0x7f4f34f4c310)
+ QObject (0x7f4f34f4c3f0) 0
+ primary-for QIODevice (0x7f4f34f4c380)
+
+Class QUrl
+ size=8 align=8
+ base size=8 base align=8
+QUrl (0x7f4f34f669a0) 0
+
+Class QXmlStreamStringRef
+ size=16 align=8
+ base size=16 base align=8
+QXmlStreamStringRef (0x7f4f34def070) 0
+
+Class QXmlStreamAttribute
+ size=80 align=8
+ base size=73 base align=8
+QXmlStreamAttribute (0x7f4f34e0f850) 0
+
+Class QXmlStreamAttributes
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamAttributes (0x7f4f34e37310) 0
+ QVector<QXmlStreamAttribute> (0x7f4f34e37380) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=40 align=8
+ base size=40 base align=8
+QXmlStreamNamespaceDeclaration (0x7f4f34e377e0) 0
+
+Class QXmlStreamNotationDeclaration
+ size=56 align=8
+ base size=56 base align=8
+QXmlStreamNotationDeclaration (0x7f4f34e7a1c0) 0
+
+Class QXmlStreamEntityDeclaration
+ size=88 align=8
+ base size=88 base align=8
+QXmlStreamEntityDeclaration (0x7f4f34e98070) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+16 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+24 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+32 QXmlStreamEntityResolver::resolveEntity
+40 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamEntityResolver (0x7f4f34cb49a0) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u)
+
+Class QXmlStreamReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamReader (0x7f4f34cb4b60) 0
+
+Class QXmlStreamWriter
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamWriter (0x7f4f34cfbc40) 0
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QAbstractState)
+16 QAbstractState::metaObject
+24 QAbstractState::qt_metacast
+32 QAbstractState::qt_metacall
+40 QAbstractState::~QAbstractState
+48 QAbstractState::~QAbstractState
+56 QAbstractState::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QAbstractState
+ size=16 align=8
+ base size=16 base align=8
+QAbstractState (0x7f4f34d11a80) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u)
+ QObject (0x7f4f34d11af0) 0
+ primary-for QAbstractState (0x7f4f34d11a80)
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTransition)
+16 QAbstractTransition::metaObject
+24 QAbstractTransition::qt_metacast
+32 QAbstractTransition::qt_metacall
+40 QAbstractTransition::~QAbstractTransition
+48 QAbstractTransition::~QAbstractTransition
+56 QAbstractTransition::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QAbstractTransition
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTransition (0x7f4f34d372a0) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u)
+ QObject (0x7f4f34d37310) 0
+ primary-for QAbstractTransition (0x7f4f34d372a0)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QEvent)
+16 QEvent::~QEvent
+24 QEvent::~QEvent
+
+Class QEvent
+ size=24 align=8
+ base size=20 base align=8
+QEvent (0x7f4f34d4caf0) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 16u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTimerEvent)
+16 QTimerEvent::~QTimerEvent
+24 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=24 align=8
+ base size=24 base align=8
+QTimerEvent (0x7f4f34d6e700) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u)
+ QEvent (0x7f4f34d6e770) 0
+ primary-for QTimerEvent (0x7f4f34d6e700)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QChildEvent)
+16 QChildEvent::~QChildEvent
+24 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=32 align=8
+ base size=32 base align=8
+QChildEvent (0x7f4f34d6eb60) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u)
+ QEvent (0x7f4f34d6ebd0) 0
+ primary-for QChildEvent (0x7f4f34d6eb60)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QCustomEvent)
+16 QCustomEvent::~QCustomEvent
+24 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=24 align=8
+ base size=20 base align=8
+QCustomEvent (0x7f4f34d77e00) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 16u)
+ QEvent (0x7f4f34d77e70) 0
+ primary-for QCustomEvent (0x7f4f34d77e00)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+16 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+24 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=32 align=8
+ base size=32 base align=8
+QDynamicPropertyChangeEvent (0x7f4f34d89620) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u)
+ QEvent (0x7f4f34d89690) 0
+ primary-for QDynamicPropertyChangeEvent (0x7f4f34d89620)
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QEventTransition)
+16 QEventTransition::metaObject
+24 QEventTransition::qt_metacast
+32 QEventTransition::qt_metacall
+40 QEventTransition::~QEventTransition
+48 QEventTransition::~QEventTransition
+56 QEventTransition::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QEventTransition::eventTest
+120 QEventTransition::onTransition
+
+Class QEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QEventTransition (0x7f4f34d89af0) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u)
+ QAbstractTransition (0x7f4f34d89b60) 0
+ primary-for QEventTransition (0x7f4f34d89af0)
+ QObject (0x7f4f34d89bd0) 0
+ primary-for QAbstractTransition (0x7f4f34d89b60)
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFinalState)
+16 QFinalState::metaObject
+24 QFinalState::qt_metacast
+32 QFinalState::qt_metacall
+40 QFinalState::~QFinalState
+48 QFinalState::~QFinalState
+56 QFinalState::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QFinalState::onEntry
+120 QFinalState::onExit
+
+Class QFinalState
+ size=16 align=8
+ base size=16 base align=8
+QFinalState (0x7f4f34ba59a0) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 16u)
+ QAbstractState (0x7f4f34ba5a10) 0
+ primary-for QFinalState (0x7f4f34ba59a0)
+ QObject (0x7f4f34ba5a80) 0
+ primary-for QAbstractState (0x7f4f34ba5a10)
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QHistoryState)
+16 QHistoryState::metaObject
+24 QHistoryState::qt_metacast
+32 QHistoryState::qt_metacall
+40 QHistoryState::~QHistoryState
+48 QHistoryState::~QHistoryState
+56 QHistoryState::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QHistoryState::onEntry
+120 QHistoryState::onExit
+
+Class QHistoryState
+ size=16 align=8
+ base size=16 base align=8
+QHistoryState (0x7f4f34bbd230) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u)
+ QAbstractState (0x7f4f34bbd2a0) 0
+ primary-for QHistoryState (0x7f4f34bbd230)
+ QObject (0x7f4f34bbd310) 0
+ primary-for QAbstractState (0x7f4f34bbd2a0)
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSignalTransition)
+16 QSignalTransition::metaObject
+24 QSignalTransition::qt_metacast
+32 QSignalTransition::qt_metacall
+40 QSignalTransition::~QSignalTransition
+48 QSignalTransition::~QSignalTransition
+56 QSignalTransition::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QSignalTransition::eventTest
+120 QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=16 align=8
+ base size=16 base align=8
+QSignalTransition (0x7f4f34bcef50) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u)
+ QAbstractTransition (0x7f4f34bd7000) 0
+ primary-for QSignalTransition (0x7f4f34bcef50)
+ QObject (0x7f4f34bd7070) 0
+ primary-for QAbstractTransition (0x7f4f34bd7000)
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QState)
+16 QState::metaObject
+24 QState::qt_metacast
+32 QState::qt_metacall
+40 QState::~QState
+48 QState::~QState
+56 QState::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QState::onEntry
+120 QState::onExit
+
+Class QState
+ size=16 align=8
+ base size=16 base align=8
+QState (0x7f4f34be9af0) 0
+ vptr=((& QState::_ZTV6QState) + 16u)
+ QAbstractState (0x7f4f34be9b60) 0
+ primary-for QState (0x7f4f34be9af0)
+ QObject (0x7f4f34be9bd0) 0
+ primary-for QAbstractState (0x7f4f34be9b60)
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+16 QStateMachine::SignalEvent::~SignalEvent
+24 QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=48 align=8
+ base size=48 base align=8
+QStateMachine::SignalEvent (0x7f4f34c0e150) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u)
+ QEvent (0x7f4f34c0e1c0) 0
+ primary-for QStateMachine::SignalEvent (0x7f4f34c0e150)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+16 QStateMachine::WrappedEvent::~WrappedEvent
+24 QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=40 align=8
+ base size=40 base align=8
+QStateMachine::WrappedEvent (0x7f4f34c0e700) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u)
+ QEvent (0x7f4f34c0e770) 0
+ primary-for QStateMachine::WrappedEvent (0x7f4f34c0e700)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStateMachine)
+16 QStateMachine::metaObject
+24 QStateMachine::qt_metacast
+32 QStateMachine::qt_metacall
+40 QStateMachine::~QStateMachine
+48 QStateMachine::~QStateMachine
+56 QStateMachine::event
+64 QStateMachine::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QStateMachine::onEntry
+120 QStateMachine::onExit
+128 QStateMachine::beginSelectTransitions
+136 QStateMachine::endSelectTransitions
+144 QStateMachine::beginMicrostep
+152 QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=16 align=8
+ base size=16 base align=8
+QStateMachine (0x7f4f34c05ee0) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u)
+ QState (0x7f4f34c05f50) 0
+ primary-for QStateMachine (0x7f4f34c05ee0)
+ QAbstractState (0x7f4f34c0e000) 0
+ primary-for QState (0x7f4f34c05f50)
+ QObject (0x7f4f34c0e070) 0
+ primary-for QAbstractState (0x7f4f34c0e000)
+
+Class QBitArray
+ size=8 align=8
+ base size=8 base align=8
+QBitArray (0x7f4f34c3e150) 0
+
+Class QBitRef
+ size=16 align=8
+ base size=12 base align=8
+QBitRef (0x7f4f34c94e00) 0
+
+Class QByteArrayMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QByteArrayMatcher::Data (0x7f4f34aa8af0) 0
+
+Class QByteArrayMatcher
+ size=1040 align=8
+ base size=1040 base align=8
+QByteArrayMatcher (0x7f4f34aa84d0) 0
+
+Class QCryptographicHash
+ size=8 align=8
+ base size=8 base align=8
+QCryptographicHash (0x7f4f34ade150) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+16 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+24 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+32 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=16 align=8
+ base size=16 base align=8
+QtSharedPointer::ExternalRefCountData (0x7f4f34b0b070) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 16u)
+
+Vtable for QtSharedPointer::ExternalRefCountWithDestroyFn
+QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN15QtSharedPointer29ExternalRefCountWithDestroyFnE)
+16 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+24 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+32 QtSharedPointer::ExternalRefCountWithDestroyFn::destroy
+
+Class QtSharedPointer::ExternalRefCountWithDestroyFn
+ size=24 align=8
+ base size=24 base align=8
+QtSharedPointer::ExternalRefCountWithDestroyFn (0x7f4f34b22930) 0
+ vptr=((& QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE) + 16u)
+ QtSharedPointer::ExternalRefCountData (0x7f4f34b229a0) 0
+ primary-for QtSharedPointer::ExternalRefCountWithDestroyFn (0x7f4f34b22930)
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0x7f4f349a65b0) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0x7f4f349d9540) 0
+
+Class QDateTime
+ size=8 align=8
+ base size=8 base align=8
+QDateTime (0x7f4f349f3af0) 0
+
+Class QEasingCurve
+ size=8 align=8
+ base size=8 base align=8
+QEasingCurve (0x7f4f34a3b000) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0x7f4f34a3bee0) 0
+
+Class QPointF
+ size=16 align=8
+ base size=16 base align=8
+QPointF (0x7f4f34a7eaf0) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0x7f4f348b3af0) 0
+
+Class QLineF
+ size=32 align=8
+ base size=32 base align=8
+QLineF (0x7f4f348ee9a0) 0
+
+Class QLinkedListData
+ size=32 align=8
+ base size=32 base align=8
+QLinkedListData (0x7f4f3494b460) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0x7f4f3480a380) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0x7f4f34839150) 0
+
+Class QSizeF
+ size=16 align=8
+ base size=16 base align=8
+QSizeF (0x7f4f34879e00) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0x7f4f346cd380) 0
+
+Class QRectF
+ size=32 align=8
+ base size=32 base align=8
+QRectF (0x7f4f3477ad20) 0
+
+Class QLatin1Literal
+ size=16 align=8
+ base size=16 base align=8
+QLatin1Literal (0x7f4f34629ee0) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0x7f4f346393f0) 0 empty
+
+Class QTextBoundaryFinder
+ size=48 align=8
+ base size=48 base align=8
+QTextBoundaryFinder (0x7f4f34672380) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeLine)
+16 QTimeLine::metaObject
+24 QTimeLine::qt_metacast
+32 QTimeLine::qt_metacall
+40 QTimeLine::~QTimeLine
+48 QTimeLine::~QTimeLine
+56 QObject::event
+64 QObject::eventFilter
+72 QTimeLine::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=16 align=8
+ base size=16 base align=8
+QTimeLine (0x7f4f34681700) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u)
+ QObject (0x7f4f34681770) 0
+ primary-for QTimeLine (0x7f4f34681700)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QRunnable)
+16 __cxa_pure_virtual
+24 QRunnable::~QRunnable
+32 QRunnable::~QRunnable
+
+Class QRunnable
+ size=16 align=8
+ base size=12 base align=8
+QRunnable (0x7f4f344a9f50) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 16u)
+
+Class QMutex
+ size=8 align=8
+ base size=8 base align=8
+QMutex (0x7f4f344e1620) 0
+
+Class QMutexLocker
+ size=8 align=8
+ base size=8 base align=8
+QMutexLocker (0x7f4f344ee1c0) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+16 QtConcurrent::Exception::~Exception
+24 QtConcurrent::Exception::~Exception
+32 std::exception::what
+40 QtConcurrent::Exception::raise
+48 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::Exception (0x7f4f345054d0) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 16u)
+ std::exception (0x7f4f34505540) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0x7f4f345054d0)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+16 QtConcurrent::UnhandledException::~UnhandledException
+24 QtConcurrent::UnhandledException::~UnhandledException
+32 std::exception::what
+40 QtConcurrent::UnhandledException::raise
+48 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::UnhandledException (0x7f4f34505770) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 16u)
+ QtConcurrent::Exception (0x7f4f345057e0) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0x7f4f34505770)
+ std::exception (0x7f4f34505850) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0x7f4f345057e0)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::internal::ExceptionHolder (0x7f4f34505a80) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=8 align=8
+ base size=8 base align=8
+QtConcurrent::internal::ExceptionStore (0x7f4f34505e00) 0
+
+Class QtConcurrent::ResultItem
+ size=16 align=8
+ base size=16 base align=8
+QtConcurrent::ResultItem (0x7f4f34505e70) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=16 align=8
+ base size=12 base align=8
+QtConcurrent::ResultIteratorBase (0x7f4f3451ed90) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+16 QtConcurrent::ResultStoreBase::~ResultStoreBase
+24 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=48 align=8
+ base size=44 base align=8
+QtConcurrent::ResultStoreBase (0x7f4f34522930) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 16u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+16 QFutureInterfaceBase::~QFutureInterfaceBase
+24 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureInterfaceBase (0x7f4f34560d90) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u)
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+16 QFutureWatcherBase::metaObject
+24 QFutureWatcherBase::qt_metacast
+32 QFutureWatcherBase::qt_metacall
+40 QFutureWatcherBase::~QFutureWatcherBase
+48 QFutureWatcherBase::~QFutureWatcherBase
+56 QFutureWatcherBase::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QFutureWatcherBase::connectNotify
+104 QFutureWatcherBase::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureWatcherBase (0x7f4f34446690) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u)
+ QObject (0x7f4f34446700) 0
+ primary-for QFutureWatcherBase (0x7f4f34446690)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QThread)
+16 QThread::metaObject
+24 QThread::qt_metacast
+32 QThread::qt_metacall
+40 QThread::~QThread
+48 QThread::~QThread
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QThread::run
+
+Class QThread
+ size=16 align=8
+ base size=16 base align=8
+QThread (0x7f4f34297a80) 0
+ vptr=((& QThread::_ZTV7QThread) + 16u)
+ QObject (0x7f4f34297af0) 0
+ primary-for QThread (0x7f4f34297a80)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QThreadPool)
+16 QThreadPool::metaObject
+24 QThreadPool::qt_metacast
+32 QThreadPool::qt_metacall
+40 QThreadPool::~QThreadPool
+48 QThreadPool::~QThreadPool
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QThreadPool
+ size=16 align=8
+ base size=16 base align=8
+QThreadPool (0x7f4f342be930) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u)
+ QObject (0x7f4f342be9a0) 0
+ primary-for QThreadPool (0x7f4f342be930)
+
+Class QWaitCondition
+ size=8 align=8
+ base size=8 base align=8
+QWaitCondition (0x7f4f342d0ee0) 0
+
+Class QSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSemaphore (0x7f4f342d7460) 0
+
+Class QtConcurrent::ThreadEngineBarrier
+ size=24 align=8
+ base size=24 base align=8
+QtConcurrent::ThreadEngineBarrier (0x7f4f342d79a0) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+16 QtConcurrent::ThreadEngineBase::run
+24 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+32 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+40 QtConcurrent::ThreadEngineBase::start
+48 QtConcurrent::ThreadEngineBase::finish
+56 QtConcurrent::ThreadEngineBase::threadFunction
+64 QtConcurrent::ThreadEngineBase::shouldStartThread
+72 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+80 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=64 align=8
+ base size=64 base align=8
+QtConcurrent::ThreadEngineBase (0x7f4f342d7a80) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 16u)
+ QRunnable (0x7f4f342d7af0) 0
+ primary-for QtConcurrent::ThreadEngineBase (0x7f4f342d7a80)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 24u)
+8 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 136u)
+
+Class QtConcurrent::BlockSizeManager
+ size=96 align=8
+ base size=92 base align=8
+QtConcurrent::BlockSizeManager (0x7f4f34324ee0) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFactoryInterface)
+16 QFactoryInterface::~QFactoryInterface
+24 QFactoryInterface::~QFactoryInterface
+32 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QFactoryInterface (0x7f4f33dc8d20) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+16 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+24 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QTextCodecFactoryInterface (0x7f4f33dfa000) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 16u)
+ QFactoryInterface (0x7f4f33dfa070) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0x7f4f33dfa000)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+16 QTextCodecPlugin::metaObject
+24 QTextCodecPlugin::qt_metacast
+32 QTextCodecPlugin::qt_metacall
+40 QTextCodecPlugin::~QTextCodecPlugin
+48 QTextCodecPlugin::~QTextCodecPlugin
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 QTextCodecPlugin::keys
+160 QTextCodecPlugin::create
+168 (int (*)(...))-0x00000000000000010
+176 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+184 QTextCodecPlugin::_ZThn16_N16QTextCodecPluginD1Ev
+192 QTextCodecPlugin::_ZThn16_N16QTextCodecPluginD0Ev
+200 QTextCodecPlugin::_ZThn16_NK16QTextCodecPlugin4keysEv
+208 QTextCodecPlugin::_ZThn16_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=24 align=8
+ base size=24 base align=8
+QTextCodecPlugin (0x7f4f33e02580) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 16u)
+ QObject (0x7f4f33dfaa80) 0
+ primary-for QTextCodecPlugin (0x7f4f33e02580)
+ QTextCodecFactoryInterface (0x7f4f33dfaaf0) 16 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 184u)
+ QFactoryInterface (0x7f4f33dfab60) 16 nearly-empty
+ primary-for QTextCodecFactoryInterface (0x7f4f33dfaaf0)
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0x7f4f33e52150) 0 empty
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QEventLoop)
+16 QEventLoop::metaObject
+24 QEventLoop::qt_metacast
+32 QEventLoop::qt_metacall
+40 QEventLoop::~QEventLoop
+48 QEventLoop::~QEventLoop
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QEventLoop
+ size=16 align=8
+ base size=16 base align=8
+QEventLoop (0x7f4f33e522a0) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u)
+ QObject (0x7f4f33e52310) 0
+ primary-for QEventLoop (0x7f4f33e522a0)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+16 QAbstractEventDispatcher::metaObject
+24 QAbstractEventDispatcher::qt_metacast
+32 QAbstractEventDispatcher::qt_metacall
+40 QAbstractEventDispatcher::~QAbstractEventDispatcher
+48 QAbstractEventDispatcher::~QAbstractEventDispatcher
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+192 __cxa_pure_virtual
+200 QAbstractEventDispatcher::startingUp
+208 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=16 align=8
+ base size=16 base align=8
+QAbstractEventDispatcher (0x7f4f33c8cbd0) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u)
+ QObject (0x7f4f33c8cc40) 0
+ primary-for QAbstractEventDispatcher (0x7f4f33c8cbd0)
+
+Class QModelIndex
+ size=24 align=8
+ base size=24 base align=8
+QModelIndex (0x7f4f33cb1a80) 0
+
+Class QPersistentModelIndex
+ size=8 align=8
+ base size=8 base align=8
+QPersistentModelIndex (0x7f4f33cdc540) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractItemModel)
+16 QAbstractItemModel::metaObject
+24 QAbstractItemModel::qt_metacast
+32 QAbstractItemModel::qt_metacall
+40 QAbstractItemModel::~QAbstractItemModel
+48 QAbstractItemModel::~QAbstractItemModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 QAbstractItemModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractItemModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemModel (0x7f4f33ce4850) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u)
+ QObject (0x7f4f33ce48c0) 0
+ primary-for QAbstractItemModel (0x7f4f33ce4850)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTableModel)
+16 QAbstractTableModel::metaObject
+24 QAbstractTableModel::qt_metacast
+32 QAbstractTableModel::qt_metacall
+40 QAbstractTableModel::~QAbstractTableModel
+48 QAbstractTableModel::~QAbstractTableModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 QAbstractTableModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTableModel (0x7f4f33d41b60) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u)
+ QAbstractItemModel (0x7f4f33d41bd0) 0
+ primary-for QAbstractTableModel (0x7f4f33d41b60)
+ QObject (0x7f4f33d41c40) 0
+ primary-for QAbstractItemModel (0x7f4f33d41bd0)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractListModel)
+16 QAbstractListModel::metaObject
+24 QAbstractListModel::qt_metacast
+32 QAbstractListModel::qt_metacall
+40 QAbstractListModel::~QAbstractListModel
+48 QAbstractListModel::~QAbstractListModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractListModel::index
+120 QAbstractListModel::parent
+128 __cxa_pure_virtual
+136 QAbstractListModel::columnCount
+144 QAbstractListModel::hasChildren
+152 __cxa_pure_virtual
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractListModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractListModel (0x7f4f33d5e0e0) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u)
+ QAbstractItemModel (0x7f4f33d5e150) 0
+ primary-for QAbstractListModel (0x7f4f33d5e0e0)
+ QObject (0x7f4f33d5e1c0) 0
+ primary-for QAbstractItemModel (0x7f4f33d5e150)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0x7f4f33b90230) 0
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QCoreApplication)
+16 QCoreApplication::metaObject
+24 QCoreApplication::qt_metacast
+32 QCoreApplication::qt_metacall
+40 QCoreApplication::~QCoreApplication
+48 QCoreApplication::~QCoreApplication
+56 QCoreApplication::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QCoreApplication::notify
+120 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=16 align=8
+ base size=16 base align=8
+QCoreApplication (0x7f4f33b9c620) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u)
+ QObject (0x7f4f33b9c690) 0
+ primary-for QCoreApplication (0x7f4f33b9c620)
+
+Class __exception
+ size=40 align=8
+ base size=40 base align=8
+__exception (0x7f4f33bce310) 0
+
+Class QMetaMethod
+ size=16 align=8
+ base size=12 base align=8
+QMetaMethod (0x7f4f33c3b770) 0
+
+Class QMetaEnum
+ size=16 align=8
+ base size=12 base align=8
+QMetaEnum (0x7f4f33c55bd0) 0
+
+Class QMetaProperty
+ size=32 align=8
+ base size=32 base align=8
+QMetaProperty (0x7f4f33c64930) 0
+
+Class QMetaClassInfo
+ size=16 align=8
+ base size=12 base align=8
+QMetaClassInfo (0x7f4f33c75000) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QMimeData)
+16 QMimeData::metaObject
+24 QMimeData::qt_metacast
+32 QMimeData::qt_metacall
+40 QMimeData::~QMimeData
+48 QMimeData::~QMimeData
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QMimeData::hasFormat
+120 QMimeData::formats
+128 QMimeData::retrieveData
+
+Class QMimeData
+ size=16 align=8
+ base size=16 base align=8
+QMimeData (0x7f4f33c75af0) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 16u)
+ QObject (0x7f4f33c75b60) 0
+ primary-for QMimeData (0x7f4f33c75af0)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+16 QObjectCleanupHandler::metaObject
+24 QObjectCleanupHandler::qt_metacast
+32 QObjectCleanupHandler::qt_metacall
+40 QObjectCleanupHandler::~QObjectCleanupHandler
+48 QObjectCleanupHandler::~QObjectCleanupHandler
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=24 align=8
+ base size=24 base align=8
+QObjectCleanupHandler (0x7f4f33a99380) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u)
+ QObject (0x7f4f33a993f0) 0
+ primary-for QObjectCleanupHandler (0x7f4f33a99380)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSharedMemory)
+16 QSharedMemory::metaObject
+24 QSharedMemory::qt_metacast
+32 QSharedMemory::qt_metacall
+40 QSharedMemory::~QSharedMemory
+48 QSharedMemory::~QSharedMemory
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=16 align=8
+ base size=16 base align=8
+QSharedMemory (0x7f4f33aaa4d0) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u)
+ QObject (0x7f4f33aaa540) 0
+ primary-for QSharedMemory (0x7f4f33aaa4d0)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSignalMapper)
+16 QSignalMapper::metaObject
+24 QSignalMapper::qt_metacast
+32 QSignalMapper::qt_metacall
+40 QSignalMapper::~QSignalMapper
+48 QSignalMapper::~QSignalMapper
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=16 align=8
+ base size=16 base align=8
+QSignalMapper (0x7f4f33ac62a0) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u)
+ QObject (0x7f4f33ac6310) 0
+ primary-for QSignalMapper (0x7f4f33ac62a0)
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSocketNotifier)
+16 QSocketNotifier::metaObject
+24 QSocketNotifier::qt_metacast
+32 QSocketNotifier::qt_metacall
+40 QSocketNotifier::~QSocketNotifier
+48 QSocketNotifier::~QSocketNotifier
+56 QSocketNotifier::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=32 align=8
+ base size=25 base align=8
+QSocketNotifier (0x7f4f33ae1690) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u)
+ QObject (0x7f4f33ae1700) 0
+ primary-for QSocketNotifier (0x7f4f33ae1690)
+
+Class QSystemSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSystemSemaphore (0x7f4f33afca10) 0
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QTimer)
+16 QTimer::metaObject
+24 QTimer::qt_metacast
+32 QTimer::qt_metacall
+40 QTimer::~QTimer
+48 QTimer::~QTimer
+56 QObject::event
+64 QObject::eventFilter
+72 QTimer::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QTimer
+ size=32 align=8
+ base size=29 base align=8
+QTimer (0x7f4f33b04460) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 16u)
+ QObject (0x7f4f33b044d0) 0
+ primary-for QTimer (0x7f4f33b04460)
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTranslator)
+16 QTranslator::metaObject
+24 QTranslator::qt_metacast
+32 QTranslator::qt_metacall
+40 QTranslator::~QTranslator
+48 QTranslator::~QTranslator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QTranslator::translate
+120 QTranslator::isEmpty
+
+Class QTranslator
+ size=16 align=8
+ base size=16 base align=8
+QTranslator (0x7f4f33b2a9a0) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 16u)
+ QObject (0x7f4f33b2aa10) 0
+ primary-for QTranslator (0x7f4f33b2a9a0)
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QLibrary)
+16 QLibrary::metaObject
+24 QLibrary::qt_metacast
+32 QLibrary::qt_metacall
+40 QLibrary::~QLibrary
+48 QLibrary::~QLibrary
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QLibrary
+ size=32 align=8
+ base size=25 base align=8
+QLibrary (0x7f4f33b45930) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 16u)
+ QObject (0x7f4f33b459a0) 0
+ primary-for QLibrary (0x7f4f33b45930)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPluginLoader)
+16 QPluginLoader::metaObject
+24 QPluginLoader::qt_metacast
+32 QPluginLoader::qt_metacall
+40 QPluginLoader::~QPluginLoader
+48 QPluginLoader::~QPluginLoader
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=32 align=8
+ base size=25 base align=8
+QPluginLoader (0x7f4f339923f0) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u)
+ QObject (0x7f4f33992460) 0
+ primary-for QPluginLoader (0x7f4f339923f0)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0x7f4f339a0b60) 0
+
+Class QReadWriteLock
+ size=8 align=8
+ base size=8 base align=8
+QReadWriteLock (0x7f4f339c74d0) 0
+
+Class QReadLocker
+ size=8 align=8
+ base size=8 base align=8
+QReadLocker (0x7f4f339c7b60) 0
+
+Class QWriteLocker
+ size=8 align=8
+ base size=8 base align=8
+QWriteLocker (0x7f4f339e6ee0) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0x7f4f33a002a0) 0
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractAnimation)
+16 QAbstractAnimation::metaObject
+24 QAbstractAnimation::qt_metacast
+32 QAbstractAnimation::qt_metacall
+40 QAbstractAnimation::~QAbstractAnimation
+48 QAbstractAnimation::~QAbstractAnimation
+56 QAbstractAnimation::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 QAbstractAnimation::updateState
+136 QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=16 align=8
+ base size=16 base align=8
+QAbstractAnimation (0x7f4f33a00a10) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u)
+ QObject (0x7f4f33a00a80) 0
+ primary-for QAbstractAnimation (0x7f4f33a00a10)
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAnimationGroup)
+16 QAnimationGroup::metaObject
+24 QAnimationGroup::qt_metacast
+32 QAnimationGroup::qt_metacall
+40 QAnimationGroup::~QAnimationGroup
+48 QAnimationGroup::~QAnimationGroup
+56 QAnimationGroup::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 QAbstractAnimation::updateState
+136 QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QAnimationGroup (0x7f4f33a37150) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u)
+ QAbstractAnimation (0x7f4f33a371c0) 0
+ primary-for QAnimationGroup (0x7f4f33a37150)
+ QObject (0x7f4f33a37230) 0
+ primary-for QAbstractAnimation (0x7f4f33a371c0)
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+16 QParallelAnimationGroup::metaObject
+24 QParallelAnimationGroup::qt_metacast
+32 QParallelAnimationGroup::qt_metacall
+40 QParallelAnimationGroup::~QParallelAnimationGroup
+48 QParallelAnimationGroup::~QParallelAnimationGroup
+56 QParallelAnimationGroup::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QParallelAnimationGroup::duration
+120 QParallelAnimationGroup::updateCurrentTime
+128 QParallelAnimationGroup::updateState
+136 QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QParallelAnimationGroup (0x7f4f33a51000) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u)
+ QAnimationGroup (0x7f4f33a51070) 0
+ primary-for QParallelAnimationGroup (0x7f4f33a51000)
+ QAbstractAnimation (0x7f4f33a510e0) 0
+ primary-for QAnimationGroup (0x7f4f33a51070)
+ QObject (0x7f4f33a51150) 0
+ primary-for QAbstractAnimation (0x7f4f33a510e0)
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QPauseAnimation)
+16 QPauseAnimation::metaObject
+24 QPauseAnimation::qt_metacast
+32 QPauseAnimation::qt_metacall
+40 QPauseAnimation::~QPauseAnimation
+48 QPauseAnimation::~QPauseAnimation
+56 QPauseAnimation::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QPauseAnimation::duration
+120 QPauseAnimation::updateCurrentTime
+128 QAbstractAnimation::updateState
+136 QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPauseAnimation (0x7f4f33a5fe70) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u)
+ QAbstractAnimation (0x7f4f33a5fee0) 0
+ primary-for QPauseAnimation (0x7f4f33a5fe70)
+ QObject (0x7f4f33a5ff50) 0
+ primary-for QAbstractAnimation (0x7f4f33a5fee0)
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QVariantAnimation)
+16 QVariantAnimation::metaObject
+24 QVariantAnimation::qt_metacast
+32 QVariantAnimation::qt_metacall
+40 QVariantAnimation::~QVariantAnimation
+48 QVariantAnimation::~QVariantAnimation
+56 QVariantAnimation::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QVariantAnimation::duration
+120 QVariantAnimation::updateCurrentTime
+128 QVariantAnimation::updateState
+136 QAbstractAnimation::updateDirection
+144 __cxa_pure_virtual
+152 QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=16 align=8
+ base size=16 base align=8
+QVariantAnimation (0x7f4f33a7c8c0) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u)
+ QAbstractAnimation (0x7f4f33a7c930) 0
+ primary-for QVariantAnimation (0x7f4f33a7c8c0)
+ QObject (0x7f4f33a7c9a0) 0
+ primary-for QAbstractAnimation (0x7f4f33a7c930)
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPropertyAnimation)
+16 QPropertyAnimation::metaObject
+24 QPropertyAnimation::qt_metacast
+32 QPropertyAnimation::qt_metacall
+40 QPropertyAnimation::~QPropertyAnimation
+48 QPropertyAnimation::~QPropertyAnimation
+56 QPropertyAnimation::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QVariantAnimation::duration
+120 QVariantAnimation::updateCurrentTime
+128 QPropertyAnimation::updateState
+136 QAbstractAnimation::updateDirection
+144 QPropertyAnimation::updateCurrentValue
+152 QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPropertyAnimation (0x7f4f33899b60) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u)
+ QVariantAnimation (0x7f4f33899bd0) 0
+ primary-for QPropertyAnimation (0x7f4f33899b60)
+ QAbstractAnimation (0x7f4f33899c40) 0
+ primary-for QVariantAnimation (0x7f4f33899bd0)
+ QObject (0x7f4f33899cb0) 0
+ primary-for QAbstractAnimation (0x7f4f33899c40)
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+16 QSequentialAnimationGroup::metaObject
+24 QSequentialAnimationGroup::qt_metacast
+32 QSequentialAnimationGroup::qt_metacall
+40 QSequentialAnimationGroup::~QSequentialAnimationGroup
+48 QSequentialAnimationGroup::~QSequentialAnimationGroup
+56 QSequentialAnimationGroup::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QSequentialAnimationGroup::duration
+120 QSequentialAnimationGroup::updateCurrentTime
+128 QSequentialAnimationGroup::updateState
+136 QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QSequentialAnimationGroup (0x7f4f338b3b60) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u)
+ QAnimationGroup (0x7f4f338b3bd0) 0
+ primary-for QSequentialAnimationGroup (0x7f4f338b3b60)
+ QAbstractAnimation (0x7f4f338b3c40) 0
+ primary-for QAnimationGroup (0x7f4f338b3bd0)
+ QObject (0x7f4f338b3cb0) 0
+ primary-for QAbstractAnimation (0x7f4f338b3c40)
+
+Class QSqlRecord
+ size=8 align=8
+ base size=8 base align=8
+QSqlRecord (0x7f4f33907230) 0
+
+Vtable for QSqlDriverCreatorBase
+QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QSqlDriverCreatorBase)
+16 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+24 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+32 __cxa_pure_virtual
+
+Class QSqlDriverCreatorBase
+ size=8 align=8
+ base size=8 base align=8
+QSqlDriverCreatorBase (0x7f4f33907e70) 0 nearly-empty
+ vptr=((& QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase) + 16u)
+
+Class QSqlDatabase
+ size=8 align=8
+ base size=8 base align=8
+QSqlDatabase (0x7f4f3391c9a0) 0
+
+Class QSqlQuery
+ size=8 align=8
+ base size=8 base align=8
+QSqlQuery (0x7f4f3392ed90) 0
+
+Vtable for QSqlDriver
+QSqlDriver::_ZTV10QSqlDriver: 32u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSqlDriver)
+16 QSqlDriver::metaObject
+24 QSqlDriver::qt_metacast
+32 QSqlDriver::qt_metacall
+40 QSqlDriver::~QSqlDriver
+48 QSqlDriver::~QSqlDriver
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QSqlDriver::isOpen
+120 QSqlDriver::beginTransaction
+128 QSqlDriver::commitTransaction
+136 QSqlDriver::rollbackTransaction
+144 QSqlDriver::tables
+152 QSqlDriver::primaryIndex
+160 QSqlDriver::record
+168 QSqlDriver::formatValue
+176 QSqlDriver::escapeIdentifier
+184 QSqlDriver::sqlStatement
+192 QSqlDriver::handle
+200 __cxa_pure_virtual
+208 __cxa_pure_virtual
+216 __cxa_pure_virtual
+224 __cxa_pure_virtual
+232 QSqlDriver::setOpen
+240 QSqlDriver::setOpenError
+248 QSqlDriver::setLastError
+
+Class QSqlDriver
+ size=16 align=8
+ base size=16 base align=8
+QSqlDriver (0x7f4f3393b850) 0
+ vptr=((& QSqlDriver::_ZTV10QSqlDriver) + 16u)
+ QObject (0x7f4f3393b8c0) 0
+ primary-for QSqlDriver (0x7f4f3393b850)
+
+Vtable for QSqlDriverFactoryInterface
+QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QSqlDriverFactoryInterface)
+16 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+24 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+32 __cxa_pure_virtual
+40 __cxa_pure_virtual
+
+Class QSqlDriverFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QSqlDriverFactoryInterface (0x7f4f3397e0e0) 0 nearly-empty
+ vptr=((& QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface) + 16u)
+ QFactoryInterface (0x7f4f3397e150) 0 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0x7f4f3397e0e0)
+
+Vtable for QSqlDriverPlugin
+QSqlDriverPlugin::_ZTV16QSqlDriverPlugin: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+16 QSqlDriverPlugin::metaObject
+24 QSqlDriverPlugin::qt_metacast
+32 QSqlDriverPlugin::qt_metacall
+40 QSqlDriverPlugin::~QSqlDriverPlugin
+48 QSqlDriverPlugin::~QSqlDriverPlugin
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 (int (*)(...))-0x00000000000000010
+136 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+144 QSqlDriverPlugin::_ZThn16_N16QSqlDriverPluginD1Ev
+152 QSqlDriverPlugin::_ZThn16_N16QSqlDriverPluginD0Ev
+160 __cxa_pure_virtual
+168 __cxa_pure_virtual
+
+Class QSqlDriverPlugin
+ size=24 align=8
+ base size=24 base align=8
+QSqlDriverPlugin (0x7f4f33979c00) 0
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 16u)
+ QObject (0x7f4f3397eb60) 0
+ primary-for QSqlDriverPlugin (0x7f4f33979c00)
+ QSqlDriverFactoryInterface (0x7f4f3397ebd0) 16 nearly-empty
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 144u)
+ QFactoryInterface (0x7f4f3397ec40) 16 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0x7f4f3397ebd0)
+
+Class QSqlError
+ size=24 align=8
+ base size=24 base align=8
+QSqlError (0x7f4f33790a80) 0
+
+Class QSqlField
+ size=24 align=8
+ base size=24 base align=8
+QSqlField (0x7f4f337989a0) 0
+
+Class QSqlIndex
+ size=32 align=8
+ base size=32 base align=8
+QSqlIndex (0x7f4f337b52a0) 0
+ QSqlRecord (0x7f4f337b5310) 0
+
+Vtable for QSqlResult
+QSqlResult::_ZTV10QSqlResult: 29u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSqlResult)
+16 QSqlResult::~QSqlResult
+24 QSqlResult::~QSqlResult
+32 QSqlResult::handle
+40 QSqlResult::setAt
+48 QSqlResult::setActive
+56 QSqlResult::setLastError
+64 QSqlResult::setQuery
+72 QSqlResult::setSelect
+80 QSqlResult::setForwardOnly
+88 QSqlResult::exec
+96 QSqlResult::prepare
+104 QSqlResult::savePrepare
+112 QSqlResult::bindValue
+120 QSqlResult::bindValue
+128 __cxa_pure_virtual
+136 __cxa_pure_virtual
+144 __cxa_pure_virtual
+152 __cxa_pure_virtual
+160 QSqlResult::fetchNext
+168 QSqlResult::fetchPrevious
+176 __cxa_pure_virtual
+184 __cxa_pure_virtual
+192 __cxa_pure_virtual
+200 __cxa_pure_virtual
+208 QSqlResult::record
+216 QSqlResult::lastInsertId
+224 QSqlResult::virtual_hook
+
+Class QSqlResult
+ size=16 align=8
+ base size=16 base align=8
+QSqlResult (0x7f4f337e81c0) 0
+ vptr=((& QSqlResult::_ZTV10QSqlResult) + 16u)
+
+Vtable for QSqlQueryModel
+QSqlQueryModel::_ZTV14QSqlQueryModel: 44u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QSqlQueryModel)
+16 QSqlQueryModel::metaObject
+24 QSqlQueryModel::qt_metacast
+32 QSqlQueryModel::qt_metacall
+40 QSqlQueryModel::~QSqlQueryModel
+48 QSqlQueryModel::~QSqlQueryModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 QSqlQueryModel::rowCount
+136 QSqlQueryModel::columnCount
+144 QAbstractTableModel::hasChildren
+152 QSqlQueryModel::data
+160 QAbstractItemModel::setData
+168 QSqlQueryModel::headerData
+176 QSqlQueryModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QSqlQueryModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QSqlQueryModel::removeColumns
+264 QSqlQueryModel::fetchMore
+272 QSqlQueryModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+336 QSqlQueryModel::clear
+344 QSqlQueryModel::queryChange
+
+Class QSqlQueryModel
+ size=16 align=8
+ base size=16 base align=8
+QSqlQueryModel (0x7f4f337e8a80) 0
+ vptr=((& QSqlQueryModel::_ZTV14QSqlQueryModel) + 16u)
+ QAbstractTableModel (0x7f4f337e8af0) 0
+ primary-for QSqlQueryModel (0x7f4f337e8a80)
+ QAbstractItemModel (0x7f4f337e8b60) 0
+ primary-for QAbstractTableModel (0x7f4f337e8af0)
+ QObject (0x7f4f337e8bd0) 0
+ primary-for QAbstractItemModel (0x7f4f337e8b60)
+
+Vtable for QSqlTableModel
+QSqlTableModel::_ZTV14QSqlTableModel: 55u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QSqlTableModel)
+16 QSqlTableModel::metaObject
+24 QSqlTableModel::qt_metacast
+32 QSqlTableModel::qt_metacall
+40 QSqlTableModel::~QSqlTableModel
+48 QSqlTableModel::~QSqlTableModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 QSqlTableModel::rowCount
+136 QSqlQueryModel::columnCount
+144 QAbstractTableModel::hasChildren
+152 QSqlTableModel::data
+160 QSqlTableModel::setData
+168 QSqlTableModel::headerData
+176 QSqlQueryModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QSqlTableModel::insertRows
+240 QSqlQueryModel::insertColumns
+248 QSqlTableModel::removeRows
+256 QSqlTableModel::removeColumns
+264 QSqlQueryModel::fetchMore
+272 QSqlQueryModel::canFetchMore
+280 QSqlTableModel::flags
+288 QSqlTableModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QSqlTableModel::submit
+328 QSqlTableModel::revert
+336 QSqlTableModel::clear
+344 QSqlQueryModel::queryChange
+352 QSqlTableModel::select
+360 QSqlTableModel::setTable
+368 QSqlTableModel::setEditStrategy
+376 QSqlTableModel::setSort
+384 QSqlTableModel::setFilter
+392 QSqlTableModel::revertRow
+400 QSqlTableModel::updateRowInTable
+408 QSqlTableModel::insertRowIntoTable
+416 QSqlTableModel::deleteRowFromTable
+424 QSqlTableModel::orderByClause
+432 QSqlTableModel::selectStatement
+
+Class QSqlTableModel
+ size=16 align=8
+ base size=16 base align=8
+QSqlTableModel (0x7f4f3381e380) 0
+ vptr=((& QSqlTableModel::_ZTV14QSqlTableModel) + 16u)
+ QSqlQueryModel (0x7f4f3381e3f0) 0
+ primary-for QSqlTableModel (0x7f4f3381e380)
+ QAbstractTableModel (0x7f4f3381e460) 0
+ primary-for QSqlQueryModel (0x7f4f3381e3f0)
+ QAbstractItemModel (0x7f4f3381e4d0) 0
+ primary-for QAbstractTableModel (0x7f4f3381e460)
+ QObject (0x7f4f3381e540) 0
+ primary-for QAbstractItemModel (0x7f4f3381e4d0)
+
+Class QSqlRelation
+ size=24 align=8
+ base size=24 base align=8
+QSqlRelation (0x7f4f33842e70) 0
+
+Vtable for QSqlRelationalTableModel
+QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel: 57u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QSqlRelationalTableModel)
+16 QSqlRelationalTableModel::metaObject
+24 QSqlRelationalTableModel::qt_metacast
+32 QSqlRelationalTableModel::qt_metacall
+40 QSqlRelationalTableModel::~QSqlRelationalTableModel
+48 QSqlRelationalTableModel::~QSqlRelationalTableModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractTableModel::index
+120 QAbstractTableModel::parent
+128 QSqlTableModel::rowCount
+136 QSqlQueryModel::columnCount
+144 QAbstractTableModel::hasChildren
+152 QSqlRelationalTableModel::data
+160 QSqlRelationalTableModel::setData
+168 QSqlTableModel::headerData
+176 QSqlQueryModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractTableModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QSqlTableModel::insertRows
+240 QSqlQueryModel::insertColumns
+248 QSqlTableModel::removeRows
+256 QSqlRelationalTableModel::removeColumns
+264 QSqlQueryModel::fetchMore
+272 QSqlQueryModel::canFetchMore
+280 QSqlTableModel::flags
+288 QSqlTableModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QSqlTableModel::submit
+328 QSqlTableModel::revert
+336 QSqlRelationalTableModel::clear
+344 QSqlQueryModel::queryChange
+352 QSqlRelationalTableModel::select
+360 QSqlRelationalTableModel::setTable
+368 QSqlTableModel::setEditStrategy
+376 QSqlTableModel::setSort
+384 QSqlTableModel::setFilter
+392 QSqlRelationalTableModel::revertRow
+400 QSqlRelationalTableModel::updateRowInTable
+408 QSqlRelationalTableModel::insertRowIntoTable
+416 QSqlTableModel::deleteRowFromTable
+424 QSqlRelationalTableModel::orderByClause
+432 QSqlRelationalTableModel::selectStatement
+440 QSqlRelationalTableModel::setRelation
+448 QSqlRelationalTableModel::relationModel
+
+Class QSqlRelationalTableModel
+ size=16 align=8
+ base size=16 base align=8
+QSqlRelationalTableModel (0x7f4f338667e0) 0
+ vptr=((& QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel) + 16u)
+ QSqlTableModel (0x7f4f33866850) 0
+ primary-for QSqlRelationalTableModel (0x7f4f338667e0)
+ QSqlQueryModel (0x7f4f338668c0) 0
+ primary-for QSqlTableModel (0x7f4f33866850)
+ QAbstractTableModel (0x7f4f33866930) 0
+ primary-for QSqlQueryModel (0x7f4f338668c0)
+ QAbstractItemModel (0x7f4f338669a0) 0
+ primary-for QAbstractTableModel (0x7f4f33866930)
+ QObject (0x7f4f33866a10) 0
+ primary-for QAbstractItemModel (0x7f4f338669a0)
+
+Class QHelpGlobal
+ size=1 align=1
+ base size=0 base align=1
+QHelpGlobal (0x7f4f33883070) 0 empty
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintDevice)
+16 QPaintDevice::~QPaintDevice
+24 QPaintDevice::~QPaintDevice
+32 QPaintDevice::devType
+40 __cxa_pure_virtual
+48 QPaintDevice::metric
+
+Class QPaintDevice
+ size=16 align=8
+ base size=10 base align=8
+QPaintDevice (0x7f4f338830e0) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0x7f4f336b5a10) 0
+
+Class QPolygon
+ size=8 align=8
+ base size=8 base align=8
+QPolygon (0x7f4f33716230) 0
+ QVector<QPoint> (0x7f4f337162a0) 0
+
+Class QPolygonF
+ size=8 align=8
+ base size=8 base align=8
+QPolygonF (0x7f4f33757770) 0
+ QVector<QPointF> (0x7f4f337577e0) 0
+
+Class QRegion::QRegionData
+ size=32 align=8
+ base size=32 base align=8
+QRegion::QRegionData (0x7f4f335bd0e0) 0
+
+Class QRegion
+ size=8 align=8
+ base size=8 base align=8
+QRegion (0x7f4f335998c0) 0
+
+Class QMatrix
+ size=48 align=8
+ base size=48 base align=8
+QMatrix (0x7f4f335d0a10) 0
+
+Class QPainterPath::Element
+ size=24 align=8
+ base size=24 base align=8
+QPainterPath::Element (0x7f4f33611b60) 0
+
+Class QPainterPath
+ size=8 align=8
+ base size=8 base align=8
+QPainterPath (0x7f4f33611af0) 0
+
+Class QPainterPathPrivate
+ size=16 align=8
+ base size=16 base align=8
+QPainterPathPrivate (0x7f4f3366e2a0) 0
+
+Class QPainterPathStroker
+ size=8 align=8
+ base size=8 base align=8
+QPainterPathStroker (0x7f4f3366ed90) 0
+
+Class QTransform
+ size=88 align=8
+ base size=88 base align=8
+QTransform (0x7f4f334d7d90) 0
+
+Class QImageTextKeyLang
+ size=16 align=8
+ base size=16 base align=8
+QImageTextKeyLang (0x7f4f335833f0) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QImage)
+16 QImage::~QImage
+24 QImage::~QImage
+32 QImage::devType
+40 QImage::paintEngine
+48 QImage::metric
+
+Class QImage
+ size=24 align=8
+ base size=24 base align=8
+QImage (0x7f4f333aac40) 0
+ vptr=((& QImage::_ZTV6QImage) + 16u)
+ QPaintDevice (0x7f4f333aacb0) 0
+ primary-for QImage (0x7f4f333aac40)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QPixmap)
+16 QPixmap::~QPixmap
+24 QPixmap::~QPixmap
+32 QPixmap::devType
+40 QPixmap::paintEngine
+48 QPixmap::metric
+
+Class QPixmap
+ size=24 align=8
+ base size=24 base align=8
+QPixmap (0x7f4f334533f0) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 16u)
+ QPaintDevice (0x7f4f33453460) 0
+ primary-for QPixmap (0x7f4f334533f0)
+
+Class QBrush
+ size=8 align=8
+ base size=8 base align=8
+QBrush (0x7f4f332b4700) 0
+
+Class QBrushData
+ size=112 align=8
+ base size=112 base align=8
+QBrushData (0x7f4f332e0150) 0
+
+Class QGradient
+ size=64 align=8
+ base size=64 base align=8
+QGradient (0x7f4f332f7310) 0
+
+Class QLinearGradient
+ size=64 align=8
+ base size=64 base align=8
+QLinearGradient (0x7f4f33303e00) 0
+ QGradient (0x7f4f33303e70) 0
+
+Class QRadialGradient
+ size=64 align=8
+ base size=64 base align=8
+QRadialGradient (0x7f4f3332e2a0) 0
+ QGradient (0x7f4f3332e310) 0
+
+Class QConicalGradient
+ size=64 align=8
+ base size=64 base align=8
+QConicalGradient (0x7f4f3332e850) 0
+ QGradient (0x7f4f3332e8c0) 0
+
+Class QPalette
+ size=16 align=8
+ base size=12 base align=8
+QPalette (0x7f4f3332ebd0) 0
+
+Class QColorGroup
+ size=16 align=8
+ base size=12 base align=8
+QColorGroup (0x7f4f3318f540) 0
+ QPalette (0x7f4f3318f5b0) 0
+
+Class QFont
+ size=16 align=8
+ base size=12 base align=8
+QFont (0x7f4f331c6850) 0
+
+Class QFontMetrics
+ size=8 align=8
+ base size=8 base align=8
+QFontMetrics (0x7f4f3320f540) 0
+
+Class QFontMetricsF
+ size=8 align=8
+ base size=8 base align=8
+QFontMetricsF (0x7f4f332239a0) 0
+
+Class QFontInfo
+ size=8 align=8
+ base size=8 base align=8
+QFontInfo (0x7f4f3322e8c0) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0x7f4f332433f0) 0
+
+Class QCursor
+ size=8 align=8
+ base size=8 base align=8
+QCursor (0x7f4f3310c3f0) 0
+
+Class QKeySequence
+ size=8 align=8
+ base size=8 base align=8
+QKeySequence (0x7f4f3310cbd0) 0
+
+Class QWidgetData
+ size=88 align=8
+ base size=88 base align=8
+QWidgetData (0x7f4f3314e540) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWidget)
+16 QWidget::metaObject
+24 QWidget::qt_metacast
+32 QWidget::qt_metacall
+40 QWidget::~QWidget
+48 QWidget::~QWidget
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI7QWidget)
+464 QWidget::_ZThn16_N7QWidgetD1Ev
+472 QWidget::_ZThn16_N7QWidgetD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=40 align=8
+ base size=40 base align=8
+QWidget (0x7f4f33150980) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 16u)
+ QObject (0x7f4f3314e5b0) 0
+ primary-for QWidget (0x7f4f33150980)
+ QPaintDevice (0x7f4f3314e620) 16
+ vptr=((& QWidget::_ZTV7QWidget) + 464u)
+
+Vtable for QFrame
+QFrame::_ZTV6QFrame: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QFrame)
+16 QFrame::metaObject
+24 QFrame::qt_metacast
+32 QFrame::qt_metacall
+40 QFrame::~QFrame
+48 QFrame::~QFrame
+56 QFrame::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QFrame::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QFrame::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI6QFrame)
+464 QFrame::_ZThn16_N6QFrameD1Ev
+472 QFrame::_ZThn16_N6QFrameD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QFrame
+ size=40 align=8
+ base size=40 base align=8
+QFrame (0x7f4f32ecf620) 0
+ vptr=((& QFrame::_ZTV6QFrame) + 16u)
+ QWidget (0x7f4f32ecd600) 0
+ primary-for QFrame (0x7f4f32ecf620)
+ QObject (0x7f4f32ecf690) 0
+ primary-for QWidget (0x7f4f32ecd600)
+ QPaintDevice (0x7f4f32ecf700) 16
+ vptr=((& QFrame::_ZTV6QFrame) + 464u)
+
+Vtable for QAbstractScrollArea
+QAbstractScrollArea::_ZTV19QAbstractScrollArea: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+16 QAbstractScrollArea::metaObject
+24 QAbstractScrollArea::qt_metacast
+32 QAbstractScrollArea::qt_metacall
+40 QAbstractScrollArea::~QAbstractScrollArea
+48 QAbstractScrollArea::~QAbstractScrollArea
+56 QAbstractScrollArea::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractScrollArea::mousePressEvent
+168 QAbstractScrollArea::mouseReleaseEvent
+176 QAbstractScrollArea::mouseDoubleClickEvent
+184 QAbstractScrollArea::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QAbstractScrollArea::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QAbstractScrollArea::paintEvent
+256 QWidget::moveEvent
+264 QAbstractScrollArea::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractScrollArea::dragEnterEvent
+312 QAbstractScrollArea::dragMoveEvent
+320 QAbstractScrollArea::dragLeaveEvent
+328 QAbstractScrollArea::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractScrollArea::viewportEvent
+456 QAbstractScrollArea::scrollContentsBy
+464 (int (*)(...))-0x00000000000000010
+472 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+480 QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD1Ev
+488 QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD0Ev
+496 QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractScrollArea
+ size=40 align=8
+ base size=40 base align=8
+QAbstractScrollArea (0x7f4f32ef2c40) 0
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 16u)
+ QFrame (0x7f4f32ef2cb0) 0
+ primary-for QAbstractScrollArea (0x7f4f32ef2c40)
+ QWidget (0x7f4f32edba00) 0
+ primary-for QFrame (0x7f4f32ef2cb0)
+ QObject (0x7f4f32ef2d20) 0
+ primary-for QWidget (0x7f4f32edba00)
+ QPaintDevice (0x7f4f32ef2d90) 16
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 480u)
+
+Class QItemSelectionRange
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionRange (0x7f4f32f16b60) 0
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QItemSelectionModel)
+16 QItemSelectionModel::metaObject
+24 QItemSelectionModel::qt_metacast
+32 QItemSelectionModel::qt_metacall
+40 QItemSelectionModel::~QItemSelectionModel
+48 QItemSelectionModel::~QItemSelectionModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QItemSelectionModel::select
+120 QItemSelectionModel::select
+128 QItemSelectionModel::clear
+136 QItemSelectionModel::reset
+
+Class QItemSelectionModel
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionModel (0x7f4f32d8a070) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u)
+ QObject (0x7f4f32d8a0e0) 0
+ primary-for QItemSelectionModel (0x7f4f32d8a070)
+
+Class QItemSelection
+ size=8 align=8
+ base size=8 base align=8
+QItemSelection (0x7f4f32dd6540) 0
+ QList<QItemSelectionRange> (0x7f4f32dd65b0) 0
+
+Vtable for QValidator
+QValidator::_ZTV10QValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QValidator)
+16 QValidator::metaObject
+24 QValidator::qt_metacast
+32 QValidator::qt_metacall
+40 QValidator::~QValidator
+48 QValidator::~QValidator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 QValidator::fixup
+
+Class QValidator
+ size=16 align=8
+ base size=16 base align=8
+QValidator (0x7f4f32dd6e00) 0
+ vptr=((& QValidator::_ZTV10QValidator) + 16u)
+ QObject (0x7f4f32dd6e70) 0
+ primary-for QValidator (0x7f4f32dd6e00)
+
+Vtable for QIntValidator
+QIntValidator::_ZTV13QIntValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QIntValidator)
+16 QIntValidator::metaObject
+24 QIntValidator::qt_metacast
+32 QIntValidator::qt_metacall
+40 QIntValidator::~QIntValidator
+48 QIntValidator::~QIntValidator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QIntValidator::validate
+120 QValidator::fixup
+128 QIntValidator::setRange
+
+Class QIntValidator
+ size=24 align=8
+ base size=24 base align=8
+QIntValidator (0x7f4f32e17c40) 0
+ vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u)
+ QValidator (0x7f4f32e17cb0) 0
+ primary-for QIntValidator (0x7f4f32e17c40)
+ QObject (0x7f4f32e17d20) 0
+ primary-for QValidator (0x7f4f32e17cb0)
+
+Vtable for QDoubleValidator
+QDoubleValidator::_ZTV16QDoubleValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QDoubleValidator)
+16 QDoubleValidator::metaObject
+24 QDoubleValidator::qt_metacast
+32 QDoubleValidator::qt_metacall
+40 QDoubleValidator::~QDoubleValidator
+48 QDoubleValidator::~QDoubleValidator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QDoubleValidator::validate
+120 QValidator::fixup
+128 QDoubleValidator::setRange
+
+Class QDoubleValidator
+ size=40 align=8
+ base size=36 base align=8
+QDoubleValidator (0x7f4f32e30bd0) 0
+ vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u)
+ QValidator (0x7f4f32e30c40) 0
+ primary-for QDoubleValidator (0x7f4f32e30bd0)
+ QObject (0x7f4f32e30cb0) 0
+ primary-for QValidator (0x7f4f32e30c40)
+
+Vtable for QRegExpValidator
+QRegExpValidator::_ZTV16QRegExpValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QRegExpValidator)
+16 QRegExpValidator::metaObject
+24 QRegExpValidator::qt_metacast
+32 QRegExpValidator::qt_metacall
+40 QRegExpValidator::~QRegExpValidator
+48 QRegExpValidator::~QRegExpValidator
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QRegExpValidator::validate
+120 QValidator::fixup
+
+Class QRegExpValidator
+ size=24 align=8
+ base size=24 base align=8
+QRegExpValidator (0x7f4f32e524d0) 0
+ vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u)
+ QValidator (0x7f4f32e52540) 0
+ primary-for QRegExpValidator (0x7f4f32e524d0)
+ QObject (0x7f4f32e525b0) 0
+ primary-for QValidator (0x7f4f32e52540)
+
+Vtable for QAbstractSpinBox
+QAbstractSpinBox::_ZTV16QAbstractSpinBox: 68u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+16 QAbstractSpinBox::metaObject
+24 QAbstractSpinBox::qt_metacast
+32 QAbstractSpinBox::qt_metacall
+40 QAbstractSpinBox::~QAbstractSpinBox
+48 QAbstractSpinBox::~QAbstractSpinBox
+56 QAbstractSpinBox::event
+64 QObject::eventFilter
+72 QAbstractSpinBox::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractSpinBox::sizeHint
+136 QAbstractSpinBox::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractSpinBox::mousePressEvent
+168 QAbstractSpinBox::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QAbstractSpinBox::mouseMoveEvent
+192 QAbstractSpinBox::wheelEvent
+200 QAbstractSpinBox::keyPressEvent
+208 QAbstractSpinBox::keyReleaseEvent
+216 QAbstractSpinBox::focusInEvent
+224 QAbstractSpinBox::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QAbstractSpinBox::paintEvent
+256 QWidget::moveEvent
+264 QAbstractSpinBox::resizeEvent
+272 QAbstractSpinBox::closeEvent
+280 QAbstractSpinBox::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QAbstractSpinBox::showEvent
+344 QAbstractSpinBox::hideEvent
+352 QWidget::x11Event
+360 QAbstractSpinBox::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QAbstractSpinBox::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractSpinBox::validate
+456 QAbstractSpinBox::fixup
+464 QAbstractSpinBox::stepBy
+472 QAbstractSpinBox::clear
+480 QAbstractSpinBox::stepEnabled
+488 (int (*)(...))-0x00000000000000010
+496 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+504 QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD1Ev
+512 QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD0Ev
+520 QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSpinBox
+ size=40 align=8
+ base size=40 base align=8
+QAbstractSpinBox (0x7f4f32e6a150) 0
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 16u)
+ QWidget (0x7f4f32e4ee00) 0
+ primary-for QAbstractSpinBox (0x7f4f32e6a150)
+ QObject (0x7f4f32e6a1c0) 0
+ primary-for QWidget (0x7f4f32e4ee00)
+ QPaintDevice (0x7f4f32e6a230) 16
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 504u)
+
+Class QIcon
+ size=8 align=8
+ base size=8 base align=8
+QIcon (0x7f4f32cc4150) 0
+
+Vtable for QAbstractSlider
+QAbstractSlider::_ZTV15QAbstractSlider: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractSlider)
+16 QAbstractSlider::metaObject
+24 QAbstractSlider::qt_metacast
+32 QAbstractSlider::qt_metacall
+40 QAbstractSlider::~QAbstractSlider
+48 QAbstractSlider::~QAbstractSlider
+56 QAbstractSlider::event
+64 QObject::eventFilter
+72 QAbstractSlider::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QAbstractSlider::wheelEvent
+200 QAbstractSlider::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QAbstractSlider::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractSlider::sliderChange
+456 (int (*)(...))-0x00000000000000010
+464 (int (*)(...))(& _ZTI15QAbstractSlider)
+472 QAbstractSlider::_ZThn16_N15QAbstractSliderD1Ev
+480 QAbstractSlider::_ZThn16_N15QAbstractSliderD0Ev
+488 QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSlider
+ size=40 align=8
+ base size=40 base align=8
+QAbstractSlider (0x7f4f32cecd20) 0
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 16u)
+ QWidget (0x7f4f32cf0a80) 0
+ primary-for QAbstractSlider (0x7f4f32cecd20)
+ QObject (0x7f4f32cecd90) 0
+ primary-for QWidget (0x7f4f32cf0a80)
+ QPaintDevice (0x7f4f32cece00) 16
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 472u)
+
+Vtable for QSlider
+QSlider::_ZTV7QSlider: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QSlider)
+16 QSlider::metaObject
+24 QSlider::qt_metacast
+32 QSlider::qt_metacall
+40 QSlider::~QSlider
+48 QSlider::~QSlider
+56 QSlider::event
+64 QObject::eventFilter
+72 QAbstractSlider::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QSlider::sizeHint
+136 QSlider::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QSlider::mousePressEvent
+168 QSlider::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QSlider::mouseMoveEvent
+192 QAbstractSlider::wheelEvent
+200 QAbstractSlider::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QSlider::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QAbstractSlider::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractSlider::sliderChange
+456 (int (*)(...))-0x00000000000000010
+464 (int (*)(...))(& _ZTI7QSlider)
+472 QSlider::_ZThn16_N7QSliderD1Ev
+480 QSlider::_ZThn16_N7QSliderD0Ev
+488 QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QSlider
+ size=40 align=8
+ base size=40 base align=8
+QSlider (0x7f4f32d26b60) 0
+ vptr=((& QSlider::_ZTV7QSlider) + 16u)
+ QAbstractSlider (0x7f4f32d26bd0) 0
+ primary-for QSlider (0x7f4f32d26b60)
+ QWidget (0x7f4f32d25b80) 0
+ primary-for QAbstractSlider (0x7f4f32d26bd0)
+ QObject (0x7f4f32d26c40) 0
+ primary-for QWidget (0x7f4f32d25b80)
+ QPaintDevice (0x7f4f32d26cb0) 16
+ vptr=((& QSlider::_ZTV7QSlider) + 472u)
+
+Vtable for QStyle
+QStyle::_ZTV6QStyle: 35u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QStyle)
+16 QStyle::metaObject
+24 QStyle::qt_metacast
+32 QStyle::qt_metacall
+40 QStyle::~QStyle
+48 QStyle::~QStyle
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QStyle::polish
+120 QStyle::unpolish
+128 QStyle::polish
+136 QStyle::unpolish
+144 QStyle::polish
+152 QStyle::itemTextRect
+160 QStyle::itemPixmapRect
+168 QStyle::drawItemText
+176 QStyle::drawItemPixmap
+184 QStyle::standardPalette
+192 __cxa_pure_virtual
+200 __cxa_pure_virtual
+208 __cxa_pure_virtual
+216 __cxa_pure_virtual
+224 __cxa_pure_virtual
+232 __cxa_pure_virtual
+240 __cxa_pure_virtual
+248 __cxa_pure_virtual
+256 __cxa_pure_virtual
+264 __cxa_pure_virtual
+272 __cxa_pure_virtual
+
+Class QStyle
+ size=16 align=8
+ base size=16 base align=8
+QStyle (0x7f4f32d56150) 0
+ vptr=((& QStyle::_ZTV6QStyle) + 16u)
+ QObject (0x7f4f32d561c0) 0
+ primary-for QStyle (0x7f4f32d56150)
+
+Vtable for QTabBar
+QTabBar::_ZTV7QTabBar: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QTabBar)
+16 QTabBar::metaObject
+24 QTabBar::qt_metacast
+32 QTabBar::qt_metacall
+40 QTabBar::~QTabBar
+48 QTabBar::~QTabBar
+56 QTabBar::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QTabBar::sizeHint
+136 QTabBar::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QTabBar::mousePressEvent
+168 QTabBar::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QTabBar::mouseMoveEvent
+192 QTabBar::wheelEvent
+200 QTabBar::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QTabBar::paintEvent
+256 QWidget::moveEvent
+264 QTabBar::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QTabBar::showEvent
+344 QTabBar::hideEvent
+352 QWidget::x11Event
+360 QTabBar::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QTabBar::tabSizeHint
+456 QTabBar::tabInserted
+464 QTabBar::tabRemoved
+472 QTabBar::tabLayoutChange
+480 (int (*)(...))-0x00000000000000010
+488 (int (*)(...))(& _ZTI7QTabBar)
+496 QTabBar::_ZThn16_N7QTabBarD1Ev
+504 QTabBar::_ZThn16_N7QTabBarD0Ev
+512 QWidget::_ZThn16_NK7QWidget7devTypeEv
+520 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+528 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabBar
+ size=40 align=8
+ base size=40 base align=8
+QTabBar (0x7f4f32b7d000) 0
+ vptr=((& QTabBar::_ZTV7QTabBar) + 16u)
+ QWidget (0x7f4f32b1cb80) 0
+ primary-for QTabBar (0x7f4f32b7d000)
+ QObject (0x7f4f32b7d070) 0
+ primary-for QWidget (0x7f4f32b1cb80)
+ QPaintDevice (0x7f4f32b7d0e0) 16
+ vptr=((& QTabBar::_ZTV7QTabBar) + 496u)
+
+Vtable for QTabWidget
+QTabWidget::_ZTV10QTabWidget: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTabWidget)
+16 QTabWidget::metaObject
+24 QTabWidget::qt_metacast
+32 QTabWidget::qt_metacall
+40 QTabWidget::~QTabWidget
+48 QTabWidget::~QTabWidget
+56 QTabWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QTabWidget::sizeHint
+136 QTabWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QTabWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QTabWidget::paintEvent
+256 QWidget::moveEvent
+264 QTabWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QTabWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QTabWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QTabWidget::tabInserted
+456 QTabWidget::tabRemoved
+464 (int (*)(...))-0x00000000000000010
+472 (int (*)(...))(& _ZTI10QTabWidget)
+480 QTabWidget::_ZThn16_N10QTabWidgetD1Ev
+488 QTabWidget::_ZThn16_N10QTabWidgetD0Ev
+496 QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabWidget
+ size=40 align=8
+ base size=40 base align=8
+QTabWidget (0x7f4f32bae620) 0
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 16u)
+ QWidget (0x7f4f32b83f80) 0
+ primary-for QTabWidget (0x7f4f32bae620)
+ QObject (0x7f4f32bae690) 0
+ primary-for QWidget (0x7f4f32b83f80)
+ QPaintDevice (0x7f4f32bae700) 16
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 480u)
+
+Vtable for QRubberBand
+QRubberBand::_ZTV11QRubberBand: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QRubberBand)
+16 QRubberBand::metaObject
+24 QRubberBand::qt_metacast
+32 QRubberBand::qt_metacall
+40 QRubberBand::~QRubberBand
+48 QRubberBand::~QRubberBand
+56 QRubberBand::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QRubberBand::paintEvent
+256 QRubberBand::moveEvent
+264 QRubberBand::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QRubberBand::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QRubberBand::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI11QRubberBand)
+464 QRubberBand::_ZThn16_N11QRubberBandD1Ev
+472 QRubberBand::_ZThn16_N11QRubberBandD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QRubberBand
+ size=40 align=8
+ base size=40 base align=8
+QRubberBand (0x7f4f329f2000) 0
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 16u)
+ QWidget (0x7f4f329ef100) 0
+ primary-for QRubberBand (0x7f4f329f2000)
+ QObject (0x7f4f329f2070) 0
+ primary-for QWidget (0x7f4f329ef100)
+ QPaintDevice (0x7f4f329f20e0) 16
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 464u)
+
+Class QStyleOption
+ size=56 align=8
+ base size=56 base align=8
+QStyleOption (0x7f4f32a14310) 0
+
+Class QStyleOptionFocusRect
+ size=72 align=8
+ base size=72 base align=8
+QStyleOptionFocusRect (0x7f4f32a22070) 0
+ QStyleOption (0x7f4f32a220e0) 0
+
+Class QStyleOptionFrame
+ size=64 align=8
+ base size=64 base align=8
+QStyleOptionFrame (0x7f4f32a2e070) 0
+ QStyleOption (0x7f4f32a2e0e0) 0
+
+Class QStyleOptionFrameV2
+ size=72 align=8
+ base size=68 base align=8
+QStyleOptionFrameV2 (0x7f4f32a3b000) 0
+ QStyleOptionFrame (0x7f4f32a3b070) 0
+ QStyleOption (0x7f4f32a3b0e0) 0
+
+Class QStyleOptionFrameV3
+ size=72 align=8
+ base size=72 base align=8
+QStyleOptionFrameV3 (0x7f4f32a688c0) 0
+ QStyleOptionFrameV2 (0x7f4f32a68930) 0
+ QStyleOptionFrame (0x7f4f32a689a0) 0
+ QStyleOption (0x7f4f32a68a10) 0
+
+Class QStyleOptionTabWidgetFrame
+ size=96 align=8
+ base size=92 base align=8
+QStyleOptionTabWidgetFrame (0x7f4f32a8d1c0) 0
+ QStyleOption (0x7f4f32a8d230) 0
+
+Class QStyleOptionTabWidgetFrameV2
+ size=128 align=8
+ base size=124 base align=8
+QStyleOptionTabWidgetFrameV2 (0x7f4f32a98930) 0
+ QStyleOptionTabWidgetFrame (0x7f4f32a989a0) 0
+ QStyleOption (0x7f4f32a98a10) 0
+
+Class QStyleOptionTabBarBase
+ size=96 align=8
+ base size=92 base align=8
+QStyleOptionTabBarBase (0x7f4f32aae2a0) 0
+ QStyleOption (0x7f4f32aae310) 0
+
+Class QStyleOptionTabBarBaseV2
+ size=96 align=8
+ base size=93 base align=8
+QStyleOptionTabBarBaseV2 (0x7f4f32ab8620) 0
+ QStyleOptionTabBarBase (0x7f4f32ab8690) 0
+ QStyleOption (0x7f4f32ab8700) 0
+
+Class QStyleOptionHeader
+ size=112 align=8
+ base size=108 base align=8
+QStyleOptionHeader (0x7f4f32ac3cb0) 0
+ QStyleOption (0x7f4f32ac3d20) 0
+
+Class QStyleOptionButton
+ size=88 align=8
+ base size=88 base align=8
+QStyleOptionButton (0x7f4f328dee70) 0
+ QStyleOption (0x7f4f328deee0) 0
+
+Class QStyleOptionTab
+ size=96 align=8
+ base size=96 base align=8
+QStyleOptionTab (0x7f4f3291b850) 0
+ QStyleOption (0x7f4f3291b8c0) 0
+
+Class QStyleOptionTabV2
+ size=104 align=8
+ base size=104 base align=8
+QStyleOptionTabV2 (0x7f4f329687e0) 0
+ QStyleOptionTab (0x7f4f32968850) 0
+ QStyleOption (0x7f4f329688c0) 0
+
+Class QStyleOptionTabV3
+ size=128 align=8
+ base size=124 base align=8
+QStyleOptionTabV3 (0x7f4f3298c230) 0
+ QStyleOptionTabV2 (0x7f4f3298c2a0) 0
+ QStyleOptionTab (0x7f4f3298c310) 0
+ QStyleOption (0x7f4f3298c380) 0
+
+Class QStyleOptionToolBar
+ size=80 align=8
+ base size=80 base align=8
+QStyleOptionToolBar (0x7f4f3299f850) 0
+ QStyleOption (0x7f4f3299f8c0) 0
+
+Class QStyleOptionProgressBar
+ size=88 align=8
+ base size=85 base align=8
+QStyleOptionProgressBar (0x7f4f327eb070) 0
+ QStyleOption (0x7f4f327eb0e0) 0
+
+Class QStyleOptionProgressBarV2
+ size=96 align=8
+ base size=94 base align=8
+QStyleOptionProgressBarV2 (0x7f4f327f67e0) 0
+ QStyleOptionProgressBar (0x7f4f327f6850) 0
+ QStyleOption (0x7f4f327f68c0) 0
+
+Class QStyleOptionMenuItem
+ size=128 align=8
+ base size=128 base align=8
+QStyleOptionMenuItem (0x7f4f328010e0) 0
+ QStyleOption (0x7f4f32801150) 0
+
+Class QStyleOptionQ3ListViewItem
+ size=80 align=8
+ base size=76 base align=8
+QStyleOptionQ3ListViewItem (0x7f4f3281b310) 0
+ QStyleOption (0x7f4f3281b380) 0
+
+Class QStyleOptionQ3DockWindow
+ size=64 align=8
+ base size=58 base align=8
+QStyleOptionQ3DockWindow (0x7f4f3284d770) 0
+ QStyleOption (0x7f4f3284d7e0) 0
+
+Class QStyleOptionDockWidget
+ size=72 align=8
+ base size=67 base align=8
+QStyleOptionDockWidget (0x7f4f3286a700) 0
+ QStyleOption (0x7f4f3286a770) 0
+
+Class QStyleOptionDockWidgetV2
+ size=72 align=8
+ base size=68 base align=8
+QStyleOptionDockWidgetV2 (0x7f4f32878af0) 0
+ QStyleOptionDockWidget (0x7f4f32878b60) 0
+ QStyleOption (0x7f4f32878bd0) 0
+
+Class QStyleOptionViewItem
+ size=104 align=8
+ base size=97 base align=8
+QStyleOptionViewItem (0x7f4f32889310) 0
+ QStyleOption (0x7f4f32889380) 0
+
+Class QStyleOptionViewItemV2
+ size=104 align=8
+ base size=104 base align=8
+QStyleOptionViewItemV2 (0x7f4f32898e70) 0
+ QStyleOptionViewItem (0x7f4f32898ee0) 0
+ QStyleOption (0x7f4f32898f50) 0
+
+Class QStyleOptionViewItemV3
+ size=120 align=8
+ base size=120 base align=8
+QStyleOptionViewItemV3 (0x7f4f326d48c0) 0
+ QStyleOptionViewItemV2 (0x7f4f326d4930) 0
+ QStyleOptionViewItem (0x7f4f326d49a0) 0
+ QStyleOption (0x7f4f326d4a10) 0
+
+Class QStyleOptionViewItemV4
+ size=184 align=8
+ base size=184 base align=8
+QStyleOptionViewItemV4 (0x7f4f326fa1c0) 0
+ QStyleOptionViewItemV3 (0x7f4f326fa230) 0
+ QStyleOptionViewItemV2 (0x7f4f326fa2a0) 0
+ QStyleOptionViewItem (0x7f4f326fa310) 0
+ QStyleOption (0x7f4f326fa380) 0
+
+Class QStyleOptionToolBox
+ size=72 align=8
+ base size=72 base align=8
+QStyleOptionToolBox (0x7f4f327118c0) 0
+ QStyleOption (0x7f4f32711930) 0
+
+Class QStyleOptionToolBoxV2
+ size=80 align=8
+ base size=80 base align=8
+QStyleOptionToolBoxV2 (0x7f4f32721d90) 0
+ QStyleOptionToolBox (0x7f4f32721e00) 0
+ QStyleOption (0x7f4f32721e70) 0
+
+Class QStyleOptionRubberBand
+ size=64 align=8
+ base size=61 base align=8
+QStyleOptionRubberBand (0x7f4f32735a80) 0
+ QStyleOption (0x7f4f32735af0) 0
+
+Class QStyleOptionComplex
+ size=64 align=8
+ base size=64 base align=8
+QStyleOptionComplex (0x7f4f32740bd0) 0
+ QStyleOption (0x7f4f32740c40) 0
+
+Class QStyleOptionSlider
+ size=120 align=8
+ base size=113 base align=8
+QStyleOptionSlider (0x7f4f32753310) 0
+ QStyleOptionComplex (0x7f4f32753380) 0
+ QStyleOption (0x7f4f327533f0) 0
+
+Class QStyleOptionSpinBox
+ size=80 align=8
+ base size=73 base align=8
+QStyleOptionSpinBox (0x7f4f32766150) 0
+ QStyleOptionComplex (0x7f4f327661c0) 0
+ QStyleOption (0x7f4f32766230) 0
+
+Class QStyleOptionQ3ListView
+ size=112 align=8
+ base size=105 base align=8
+QStyleOptionQ3ListView (0x7f4f32772620) 0
+ QStyleOptionComplex (0x7f4f32772690) 0
+ QStyleOption (0x7f4f32772700) 0
+
+Class QStyleOptionToolButton
+ size=128 align=8
+ base size=128 base align=8
+QStyleOptionToolButton (0x7f4f327aa2a0) 0
+ QStyleOptionComplex (0x7f4f327aa310) 0
+ QStyleOption (0x7f4f327aa380) 0
+
+Class QStyleOptionComboBox
+ size=112 align=8
+ base size=112 base align=8
+QStyleOptionComboBox (0x7f4f325fb4d0) 0
+ QStyleOptionComplex (0x7f4f325fb540) 0
+ QStyleOption (0x7f4f325fb5b0) 0
+
+Class QStyleOptionTitleBar
+ size=88 align=8
+ base size=88 base align=8
+QStyleOptionTitleBar (0x7f4f32612000) 0
+ QStyleOptionComplex (0x7f4f32612070) 0
+ QStyleOption (0x7f4f326120e0) 0
+
+Class QStyleOptionGroupBox
+ size=112 align=8
+ base size=108 base align=8
+QStyleOptionGroupBox (0x7f4f32620850) 0
+ QStyleOptionComplex (0x7f4f326208c0) 0
+ QStyleOption (0x7f4f32620930) 0
+
+Class QStyleOptionSizeGrip
+ size=72 align=8
+ base size=68 base align=8
+QStyleOptionSizeGrip (0x7f4f32636460) 0
+ QStyleOptionComplex (0x7f4f326364d0) 0
+ QStyleOption (0x7f4f32636540) 0
+
+Class QStyleOptionGraphicsItem
+ size=144 align=8
+ base size=144 base align=8
+QStyleOptionGraphicsItem (0x7f4f32643380) 0
+ QStyleOption (0x7f4f326433f0) 0
+
+Class QStyleHintReturn
+ size=8 align=4
+ base size=8 base align=4
+QStyleHintReturn (0x7f4f3264e700) 0
+
+Class QStyleHintReturnMask
+ size=16 align=8
+ base size=16 base align=8
+QStyleHintReturnMask (0x7f4f3264eb60) 0
+ QStyleHintReturn (0x7f4f3264ebd0) 0
+
+Class QStyleHintReturnVariant
+ size=24 align=8
+ base size=24 base align=8
+QStyleHintReturnVariant (0x7f4f3264ed90) 0
+ QStyleHintReturn (0x7f4f3264ee00) 0
+
+Vtable for QAbstractItemDelegate
+QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 21u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QAbstractItemDelegate)
+16 QAbstractItemDelegate::metaObject
+24 QAbstractItemDelegate::qt_metacast
+32 QAbstractItemDelegate::qt_metacall
+40 QAbstractItemDelegate::~QAbstractItemDelegate
+48 QAbstractItemDelegate::~QAbstractItemDelegate
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 __cxa_pure_virtual
+120 __cxa_pure_virtual
+128 QAbstractItemDelegate::createEditor
+136 QAbstractItemDelegate::setEditorData
+144 QAbstractItemDelegate::setModelData
+152 QAbstractItemDelegate::updateEditorGeometry
+160 QAbstractItemDelegate::editorEvent
+
+Class QAbstractItemDelegate
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemDelegate (0x7f4f326742a0) 0
+ vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 16u)
+ QObject (0x7f4f32674310) 0
+ primary-for QAbstractItemDelegate (0x7f4f326742a0)
+
+Vtable for QAbstractItemView
+QAbstractItemView::_ZTV17QAbstractItemView: 103u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAbstractItemView)
+16 QAbstractItemView::metaObject
+24 QAbstractItemView::qt_metacast
+32 QAbstractItemView::qt_metacall
+40 QAbstractItemView::~QAbstractItemView
+48 QAbstractItemView::~QAbstractItemView
+56 QAbstractItemView::event
+64 QObject::eventFilter
+72 QAbstractItemView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractItemView::mousePressEvent
+168 QAbstractItemView::mouseReleaseEvent
+176 QAbstractItemView::mouseDoubleClickEvent
+184 QAbstractItemView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QAbstractItemView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QAbstractScrollArea::paintEvent
+256 QWidget::moveEvent
+264 QAbstractItemView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QAbstractItemView::dragMoveEvent
+320 QAbstractItemView::dragLeaveEvent
+328 QAbstractItemView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractItemView::viewportEvent
+456 QAbstractScrollArea::scrollContentsBy
+464 QAbstractItemView::setModel
+472 QAbstractItemView::setSelectionModel
+480 QAbstractItemView::keyboardSearch
+488 __cxa_pure_virtual
+496 __cxa_pure_virtual
+504 __cxa_pure_virtual
+512 QAbstractItemView::sizeHintForRow
+520 QAbstractItemView::sizeHintForColumn
+528 QAbstractItemView::reset
+536 QAbstractItemView::setRootIndex
+544 QAbstractItemView::doItemsLayout
+552 QAbstractItemView::selectAll
+560 QAbstractItemView::dataChanged
+568 QAbstractItemView::rowsInserted
+576 QAbstractItemView::rowsAboutToBeRemoved
+584 QAbstractItemView::selectionChanged
+592 QAbstractItemView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QAbstractItemView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QAbstractItemView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 __cxa_pure_virtual
+688 __cxa_pure_virtual
+696 __cxa_pure_virtual
+704 __cxa_pure_virtual
+712 __cxa_pure_virtual
+720 __cxa_pure_virtual
+728 QAbstractItemView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QAbstractItemView::startDrag
+760 QAbstractItemView::viewOptions
+768 (int (*)(...))-0x00000000000000010
+776 (int (*)(...))(& _ZTI17QAbstractItemView)
+784 QAbstractItemView::_ZThn16_N17QAbstractItemViewD1Ev
+792 QAbstractItemView::_ZThn16_N17QAbstractItemViewD0Ev
+800 QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractItemView
+ size=40 align=8
+ base size=40 base align=8
+QAbstractItemView (0x7f4f32695930) 0
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 16u)
+ QAbstractScrollArea (0x7f4f326959a0) 0
+ primary-for QAbstractItemView (0x7f4f32695930)
+ QFrame (0x7f4f32695a10) 0
+ primary-for QAbstractScrollArea (0x7f4f326959a0)
+ QWidget (0x7f4f32685600) 0
+ primary-for QFrame (0x7f4f32695a10)
+ QObject (0x7f4f32695a80) 0
+ primary-for QWidget (0x7f4f32685600)
+ QPaintDevice (0x7f4f32695af0) 16
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 784u)
+
+Vtable for QTreeView
+QTreeView::_ZTV9QTreeView: 105u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTreeView)
+16 QTreeView::metaObject
+24 QTreeView::qt_metacast
+32 QTreeView::qt_metacall
+40 QTreeView::~QTreeView
+48 QTreeView::~QTreeView
+56 QAbstractItemView::event
+64 QObject::eventFilter
+72 QTreeView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QTreeView::mousePressEvent
+168 QTreeView::mouseReleaseEvent
+176 QTreeView::mouseDoubleClickEvent
+184 QTreeView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QTreeView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QTreeView::paintEvent
+256 QWidget::moveEvent
+264 QAbstractItemView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QTreeView::dragMoveEvent
+320 QAbstractItemView::dragLeaveEvent
+328 QAbstractItemView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QTreeView::viewportEvent
+456 QTreeView::scrollContentsBy
+464 QTreeView::setModel
+472 QTreeView::setSelectionModel
+480 QTreeView::keyboardSearch
+488 QTreeView::visualRect
+496 QTreeView::scrollTo
+504 QTreeView::indexAt
+512 QAbstractItemView::sizeHintForRow
+520 QTreeView::sizeHintForColumn
+528 QTreeView::reset
+536 QTreeView::setRootIndex
+544 QTreeView::doItemsLayout
+552 QTreeView::selectAll
+560 QTreeView::dataChanged
+568 QTreeView::rowsInserted
+576 QTreeView::rowsAboutToBeRemoved
+584 QTreeView::selectionChanged
+592 QTreeView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QTreeView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QTreeView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 QTreeView::moveCursor
+688 QTreeView::horizontalOffset
+696 QTreeView::verticalOffset
+704 QTreeView::isIndexHidden
+712 QTreeView::setSelection
+720 QTreeView::visualRegionForSelection
+728 QTreeView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QAbstractItemView::startDrag
+760 QAbstractItemView::viewOptions
+768 QTreeView::drawRow
+776 QTreeView::drawBranches
+784 (int (*)(...))-0x00000000000000010
+792 (int (*)(...))(& _ZTI9QTreeView)
+800 QTreeView::_ZThn16_N9QTreeViewD1Ev
+808 QTreeView::_ZThn16_N9QTreeViewD0Ev
+816 QWidget::_ZThn16_NK7QWidget7devTypeEv
+824 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+832 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTreeView
+ size=40 align=8
+ base size=40 base align=8
+QTreeView (0x7f4f32522150) 0
+ vptr=((& QTreeView::_ZTV9QTreeView) + 16u)
+ QAbstractItemView (0x7f4f325221c0) 0
+ primary-for QTreeView (0x7f4f32522150)
+ QAbstractScrollArea (0x7f4f32522230) 0
+ primary-for QAbstractItemView (0x7f4f325221c0)
+ QFrame (0x7f4f325222a0) 0
+ primary-for QAbstractScrollArea (0x7f4f32522230)
+ QWidget (0x7f4f324e2d80) 0
+ primary-for QFrame (0x7f4f325222a0)
+ QObject (0x7f4f32522310) 0
+ primary-for QWidget (0x7f4f324e2d80)
+ QPaintDevice (0x7f4f32522380) 16
+ vptr=((& QTreeView::_ZTV9QTreeView) + 800u)
+
+Class QHelpContentItem
+ size=8 align=8
+ base size=8 base align=8
+QHelpContentItem (0x7f4f32557ee0) 0
+
+Vtable for QHelpContentModel
+QHelpContentModel::_ZTV17QHelpContentModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QHelpContentModel)
+16 QHelpContentModel::metaObject
+24 QHelpContentModel::qt_metacast
+32 QHelpContentModel::qt_metacall
+40 QHelpContentModel::~QHelpContentModel
+48 QHelpContentModel::~QHelpContentModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QHelpContentModel::index
+120 QHelpContentModel::parent
+128 QHelpContentModel::rowCount
+136 QHelpContentModel::columnCount
+144 QAbstractItemModel::hasChildren
+152 QHelpContentModel::data
+160 QAbstractItemModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractItemModel::dropMimeData
+224 QAbstractItemModel::supportedDropActions
+232 QAbstractItemModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QAbstractItemModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QAbstractItemModel::flags
+288 QAbstractItemModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QHelpContentModel
+ size=24 align=8
+ base size=24 base align=8
+QHelpContentModel (0x7f4f3255f460) 0
+ vptr=((& QHelpContentModel::_ZTV17QHelpContentModel) + 16u)
+ QAbstractItemModel (0x7f4f3255f4d0) 0
+ primary-for QHelpContentModel (0x7f4f3255f460)
+ QObject (0x7f4f3255f540) 0
+ primary-for QAbstractItemModel (0x7f4f3255f4d0)
+
+Vtable for QHelpContentWidget
+QHelpContentWidget::_ZTV18QHelpContentWidget: 105u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QHelpContentWidget)
+16 QHelpContentWidget::metaObject
+24 QHelpContentWidget::qt_metacast
+32 QHelpContentWidget::qt_metacall
+40 QHelpContentWidget::~QHelpContentWidget
+48 QHelpContentWidget::~QHelpContentWidget
+56 QAbstractItemView::event
+64 QObject::eventFilter
+72 QTreeView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QTreeView::mousePressEvent
+168 QTreeView::mouseReleaseEvent
+176 QTreeView::mouseDoubleClickEvent
+184 QTreeView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QTreeView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QTreeView::paintEvent
+256 QWidget::moveEvent
+264 QAbstractItemView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QTreeView::dragMoveEvent
+320 QAbstractItemView::dragLeaveEvent
+328 QAbstractItemView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QTreeView::viewportEvent
+456 QTreeView::scrollContentsBy
+464 QTreeView::setModel
+472 QTreeView::setSelectionModel
+480 QTreeView::keyboardSearch
+488 QTreeView::visualRect
+496 QTreeView::scrollTo
+504 QTreeView::indexAt
+512 QAbstractItemView::sizeHintForRow
+520 QTreeView::sizeHintForColumn
+528 QTreeView::reset
+536 QTreeView::setRootIndex
+544 QTreeView::doItemsLayout
+552 QTreeView::selectAll
+560 QTreeView::dataChanged
+568 QTreeView::rowsInserted
+576 QTreeView::rowsAboutToBeRemoved
+584 QTreeView::selectionChanged
+592 QTreeView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QTreeView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QTreeView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 QTreeView::moveCursor
+688 QTreeView::horizontalOffset
+696 QTreeView::verticalOffset
+704 QTreeView::isIndexHidden
+712 QTreeView::setSelection
+720 QTreeView::visualRegionForSelection
+728 QTreeView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QAbstractItemView::startDrag
+760 QAbstractItemView::viewOptions
+768 QTreeView::drawRow
+776 QTreeView::drawBranches
+784 (int (*)(...))-0x00000000000000010
+792 (int (*)(...))(& _ZTI18QHelpContentWidget)
+800 QHelpContentWidget::_ZThn16_N18QHelpContentWidgetD1Ev
+808 QHelpContentWidget::_ZThn16_N18QHelpContentWidgetD0Ev
+816 QWidget::_ZThn16_NK7QWidget7devTypeEv
+824 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+832 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpContentWidget
+ size=64 align=8
+ base size=64 base align=8
+QHelpContentWidget (0x7f4f3257a460) 0
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 16u)
+ QTreeView (0x7f4f3257a4d0) 0
+ primary-for QHelpContentWidget (0x7f4f3257a460)
+ QAbstractItemView (0x7f4f3257a540) 0
+ primary-for QTreeView (0x7f4f3257a4d0)
+ QAbstractScrollArea (0x7f4f3257a5b0) 0
+ primary-for QAbstractItemView (0x7f4f3257a540)
+ QFrame (0x7f4f3257a620) 0
+ primary-for QAbstractScrollArea (0x7f4f3257a5b0)
+ QWidget (0x7f4f32554e80) 0
+ primary-for QFrame (0x7f4f3257a620)
+ QObject (0x7f4f3257a690) 0
+ primary-for QWidget (0x7f4f32554e80)
+ QPaintDevice (0x7f4f3257a700) 16
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 800u)
+
+Vtable for QHelpEngineCore
+QHelpEngineCore::_ZTV15QHelpEngineCore: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QHelpEngineCore)
+16 QHelpEngineCore::metaObject
+24 QHelpEngineCore::qt_metacast
+32 QHelpEngineCore::qt_metacall
+40 QHelpEngineCore::~QHelpEngineCore
+48 QHelpEngineCore::~QHelpEngineCore
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QHelpEngineCore
+ size=24 align=8
+ base size=24 base align=8
+QHelpEngineCore (0x7f4f32590460) 0
+ vptr=((& QHelpEngineCore::_ZTV15QHelpEngineCore) + 16u)
+ QObject (0x7f4f325904d0) 0
+ primary-for QHelpEngineCore (0x7f4f32590460)
+
+Vtable for QHelpEngine
+QHelpEngine::_ZTV11QHelpEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHelpEngine)
+16 QHelpEngine::metaObject
+24 QHelpEngine::qt_metacast
+32 QHelpEngine::qt_metacall
+40 QHelpEngine::~QHelpEngine
+48 QHelpEngine::~QHelpEngine
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QHelpEngine
+ size=32 align=8
+ base size=32 base align=8
+QHelpEngine (0x7f4f325ab4d0) 0
+ vptr=((& QHelpEngine::_ZTV11QHelpEngine) + 16u)
+ QHelpEngineCore (0x7f4f325ab540) 0
+ primary-for QHelpEngine (0x7f4f325ab4d0)
+ QObject (0x7f4f325ab5b0) 0
+ primary-for QHelpEngineCore (0x7f4f325ab540)
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QStringListModel)
+16 QStringListModel::metaObject
+24 QStringListModel::qt_metacast
+32 QStringListModel::qt_metacall
+40 QStringListModel::~QStringListModel
+48 QStringListModel::~QStringListModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractListModel::index
+120 QAbstractListModel::parent
+128 QStringListModel::rowCount
+136 QAbstractListModel::columnCount
+144 QAbstractListModel::hasChildren
+152 QStringListModel::data
+160 QStringListModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractListModel::dropMimeData
+224 QStringListModel::supportedDropActions
+232 QStringListModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QStringListModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QStringListModel::flags
+288 QStringListModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QStringListModel
+ size=24 align=8
+ base size=24 base align=8
+QStringListModel (0x7f4f325bd3f0) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u)
+ QAbstractListModel (0x7f4f325bd460) 0
+ primary-for QStringListModel (0x7f4f325bd3f0)
+ QAbstractItemModel (0x7f4f325bd4d0) 0
+ primary-for QAbstractListModel (0x7f4f325bd460)
+ QObject (0x7f4f325bd540) 0
+ primary-for QAbstractItemModel (0x7f4f325bd4d0)
+
+Vtable for QListView
+QListView::_ZTV9QListView: 103u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QListView)
+16 QListView::metaObject
+24 QListView::qt_metacast
+32 QListView::qt_metacall
+40 QListView::~QListView
+48 QListView::~QListView
+56 QListView::event
+64 QObject::eventFilter
+72 QListView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractItemView::mousePressEvent
+168 QListView::mouseReleaseEvent
+176 QAbstractItemView::mouseDoubleClickEvent
+184 QListView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QAbstractItemView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QListView::paintEvent
+256 QWidget::moveEvent
+264 QListView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QListView::dragMoveEvent
+320 QListView::dragLeaveEvent
+328 QListView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractItemView::viewportEvent
+456 QListView::scrollContentsBy
+464 QAbstractItemView::setModel
+472 QAbstractItemView::setSelectionModel
+480 QAbstractItemView::keyboardSearch
+488 QListView::visualRect
+496 QListView::scrollTo
+504 QListView::indexAt
+512 QAbstractItemView::sizeHintForRow
+520 QAbstractItemView::sizeHintForColumn
+528 QListView::reset
+536 QListView::setRootIndex
+544 QListView::doItemsLayout
+552 QAbstractItemView::selectAll
+560 QListView::dataChanged
+568 QListView::rowsInserted
+576 QListView::rowsAboutToBeRemoved
+584 QListView::selectionChanged
+592 QListView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QListView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QAbstractItemView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 QListView::moveCursor
+688 QListView::horizontalOffset
+696 QListView::verticalOffset
+704 QListView::isIndexHidden
+712 QListView::setSelection
+720 QListView::visualRegionForSelection
+728 QListView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QListView::startDrag
+760 QListView::viewOptions
+768 (int (*)(...))-0x00000000000000010
+776 (int (*)(...))(& _ZTI9QListView)
+784 QListView::_ZThn16_N9QListViewD1Ev
+792 QListView::_ZThn16_N9QListViewD0Ev
+800 QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QListView
+ size=40 align=8
+ base size=40 base align=8
+QListView (0x7f4f323d2a10) 0
+ vptr=((& QListView::_ZTV9QListView) + 16u)
+ QAbstractItemView (0x7f4f323d2a80) 0
+ primary-for QListView (0x7f4f323d2a10)
+ QAbstractScrollArea (0x7f4f323d2af0) 0
+ primary-for QAbstractItemView (0x7f4f323d2a80)
+ QFrame (0x7f4f323d2b60) 0
+ primary-for QAbstractScrollArea (0x7f4f323d2af0)
+ QWidget (0x7f4f325b9900) 0
+ primary-for QFrame (0x7f4f323d2b60)
+ QObject (0x7f4f323d2bd0) 0
+ primary-for QWidget (0x7f4f325b9900)
+ QPaintDevice (0x7f4f323d2c40) 16
+ vptr=((& QListView::_ZTV9QListView) + 784u)
+
+Vtable for QHelpIndexModel
+QHelpIndexModel::_ZTV15QHelpIndexModel: 42u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QHelpIndexModel)
+16 QHelpIndexModel::metaObject
+24 QHelpIndexModel::qt_metacast
+32 QHelpIndexModel::qt_metacall
+40 QHelpIndexModel::~QHelpIndexModel
+48 QHelpIndexModel::~QHelpIndexModel
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QAbstractListModel::index
+120 QAbstractListModel::parent
+128 QStringListModel::rowCount
+136 QAbstractListModel::columnCount
+144 QAbstractListModel::hasChildren
+152 QStringListModel::data
+160 QStringListModel::setData
+168 QAbstractItemModel::headerData
+176 QAbstractItemModel::setHeaderData
+184 QAbstractItemModel::itemData
+192 QAbstractItemModel::setItemData
+200 QAbstractItemModel::mimeTypes
+208 QAbstractItemModel::mimeData
+216 QAbstractListModel::dropMimeData
+224 QStringListModel::supportedDropActions
+232 QStringListModel::insertRows
+240 QAbstractItemModel::insertColumns
+248 QStringListModel::removeRows
+256 QAbstractItemModel::removeColumns
+264 QAbstractItemModel::fetchMore
+272 QAbstractItemModel::canFetchMore
+280 QStringListModel::flags
+288 QStringListModel::sort
+296 QAbstractItemModel::buddy
+304 QAbstractItemModel::match
+312 QAbstractItemModel::span
+320 QAbstractItemModel::submit
+328 QAbstractItemModel::revert
+
+Class QHelpIndexModel
+ size=32 align=8
+ base size=32 base align=8
+QHelpIndexModel (0x7f4f3240f0e0) 0
+ vptr=((& QHelpIndexModel::_ZTV15QHelpIndexModel) + 16u)
+ QStringListModel (0x7f4f3240f150) 0
+ primary-for QHelpIndexModel (0x7f4f3240f0e0)
+ QAbstractListModel (0x7f4f3240f1c0) 0
+ primary-for QStringListModel (0x7f4f3240f150)
+ QAbstractItemModel (0x7f4f3240f230) 0
+ primary-for QAbstractListModel (0x7f4f3240f1c0)
+ QObject (0x7f4f3240f2a0) 0
+ primary-for QAbstractItemModel (0x7f4f3240f230)
+
+Vtable for QHelpIndexWidget
+QHelpIndexWidget::_ZTV16QHelpIndexWidget: 103u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+16 QHelpIndexWidget::metaObject
+24 QHelpIndexWidget::qt_metacast
+32 QHelpIndexWidget::qt_metacall
+40 QHelpIndexWidget::~QHelpIndexWidget
+48 QHelpIndexWidget::~QHelpIndexWidget
+56 QListView::event
+64 QObject::eventFilter
+72 QListView::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QAbstractScrollArea::sizeHint
+136 QAbstractScrollArea::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QAbstractItemView::mousePressEvent
+168 QListView::mouseReleaseEvent
+176 QAbstractItemView::mouseDoubleClickEvent
+184 QListView::mouseMoveEvent
+192 QAbstractScrollArea::wheelEvent
+200 QAbstractItemView::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QAbstractItemView::focusInEvent
+224 QAbstractItemView::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QListView::paintEvent
+256 QWidget::moveEvent
+264 QListView::resizeEvent
+272 QWidget::closeEvent
+280 QAbstractScrollArea::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QAbstractItemView::dragEnterEvent
+312 QListView::dragMoveEvent
+320 QListView::dragLeaveEvent
+328 QListView::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QFrame::changeEvent
+368 QWidget::metric
+376 QAbstractItemView::inputMethodEvent
+384 QAbstractItemView::inputMethodQuery
+392 QAbstractItemView::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 QAbstractItemView::viewportEvent
+456 QListView::scrollContentsBy
+464 QAbstractItemView::setModel
+472 QAbstractItemView::setSelectionModel
+480 QAbstractItemView::keyboardSearch
+488 QListView::visualRect
+496 QListView::scrollTo
+504 QListView::indexAt
+512 QAbstractItemView::sizeHintForRow
+520 QAbstractItemView::sizeHintForColumn
+528 QListView::reset
+536 QListView::setRootIndex
+544 QListView::doItemsLayout
+552 QAbstractItemView::selectAll
+560 QListView::dataChanged
+568 QListView::rowsInserted
+576 QListView::rowsAboutToBeRemoved
+584 QListView::selectionChanged
+592 QListView::currentChanged
+600 QAbstractItemView::updateEditorData
+608 QAbstractItemView::updateEditorGeometries
+616 QListView::updateGeometries
+624 QAbstractItemView::verticalScrollbarAction
+632 QAbstractItemView::horizontalScrollbarAction
+640 QAbstractItemView::verticalScrollbarValueChanged
+648 QAbstractItemView::horizontalScrollbarValueChanged
+656 QAbstractItemView::closeEditor
+664 QAbstractItemView::commitData
+672 QAbstractItemView::editorDestroyed
+680 QListView::moveCursor
+688 QListView::horizontalOffset
+696 QListView::verticalOffset
+704 QListView::isIndexHidden
+712 QListView::setSelection
+720 QListView::visualRegionForSelection
+728 QListView::selectedIndexes
+736 QAbstractItemView::edit
+744 QAbstractItemView::selectionCommand
+752 QListView::startDrag
+760 QListView::viewOptions
+768 (int (*)(...))-0x00000000000000010
+776 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+784 QHelpIndexWidget::_ZThn16_N16QHelpIndexWidgetD1Ev
+792 QHelpIndexWidget::_ZThn16_N16QHelpIndexWidgetD0Ev
+800 QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpIndexWidget
+ size=40 align=8
+ base size=40 base align=8
+QHelpIndexWidget (0x7f4f324250e0) 0
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 16u)
+ QListView (0x7f4f32425150) 0
+ primary-for QHelpIndexWidget (0x7f4f324250e0)
+ QAbstractItemView (0x7f4f324251c0) 0
+ primary-for QListView (0x7f4f32425150)
+ QAbstractScrollArea (0x7f4f32425230) 0
+ primary-for QAbstractItemView (0x7f4f324251c0)
+ QFrame (0x7f4f324252a0) 0
+ primary-for QAbstractScrollArea (0x7f4f32425230)
+ QWidget (0x7f4f323e2f80) 0
+ primary-for QFrame (0x7f4f324252a0)
+ QObject (0x7f4f32425310) 0
+ primary-for QWidget (0x7f4f323e2f80)
+ QPaintDevice (0x7f4f32425380) 16
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 784u)
+
+Class QHelpSearchQuery
+ size=16 align=8
+ base size=16 base align=8
+QHelpSearchQuery (0x7f4f3243b150) 0
+
+Vtable for QHelpSearchEngine
+QHelpSearchEngine::_ZTV17QHelpSearchEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QHelpSearchEngine)
+16 QHelpSearchEngine::metaObject
+24 QHelpSearchEngine::qt_metacast
+32 QHelpSearchEngine::qt_metacall
+40 QHelpSearchEngine::~QHelpSearchEngine
+48 QHelpSearchEngine::~QHelpSearchEngine
+56 QObject::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+
+Class QHelpSearchEngine
+ size=24 align=8
+ base size=24 base align=8
+QHelpSearchEngine (0x7f4f32445700) 0
+ vptr=((& QHelpSearchEngine::_ZTV17QHelpSearchEngine) + 16u)
+ QObject (0x7f4f32445770) 0
+ primary-for QHelpSearchEngine (0x7f4f32445700)
+
+Vtable for QHelpSearchQueryWidget
+QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+16 QHelpSearchQueryWidget::metaObject
+24 QHelpSearchQueryWidget::qt_metacast
+32 QHelpSearchQueryWidget::qt_metacall
+40 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+48 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QHelpSearchQueryWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+464 QHelpSearchQueryWidget::_ZThn16_N22QHelpSearchQueryWidgetD1Ev
+472 QHelpSearchQueryWidget::_ZThn16_N22QHelpSearchQueryWidgetD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchQueryWidget
+ size=48 align=8
+ base size=48 base align=8
+QHelpSearchQueryWidget (0x7f4f32454a80) 0
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 16u)
+ QWidget (0x7f4f32444e00) 0
+ primary-for QHelpSearchQueryWidget (0x7f4f32454a80)
+ QObject (0x7f4f32454af0) 0
+ primary-for QWidget (0x7f4f32444e00)
+ QPaintDevice (0x7f4f32454b60) 16
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 464u)
+
+Vtable for QHelpSearchResultWidget
+QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget: 63u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+16 QHelpSearchResultWidget::metaObject
+24 QHelpSearchResultWidget::qt_metacast
+32 QHelpSearchResultWidget::qt_metacall
+40 QHelpSearchResultWidget::~QHelpSearchResultWidget
+48 QHelpSearchResultWidget::~QHelpSearchResultWidget
+56 QWidget::event
+64 QObject::eventFilter
+72 QObject::timerEvent
+80 QObject::childEvent
+88 QObject::customEvent
+96 QObject::connectNotify
+104 QObject::disconnectNotify
+112 QWidget::devType
+120 QWidget::setVisible
+128 QWidget::sizeHint
+136 QWidget::minimumSizeHint
+144 QWidget::heightForWidth
+152 QWidget::paintEngine
+160 QWidget::mousePressEvent
+168 QWidget::mouseReleaseEvent
+176 QWidget::mouseDoubleClickEvent
+184 QWidget::mouseMoveEvent
+192 QWidget::wheelEvent
+200 QWidget::keyPressEvent
+208 QWidget::keyReleaseEvent
+216 QWidget::focusInEvent
+224 QWidget::focusOutEvent
+232 QWidget::enterEvent
+240 QWidget::leaveEvent
+248 QWidget::paintEvent
+256 QWidget::moveEvent
+264 QWidget::resizeEvent
+272 QWidget::closeEvent
+280 QWidget::contextMenuEvent
+288 QWidget::tabletEvent
+296 QWidget::actionEvent
+304 QWidget::dragEnterEvent
+312 QWidget::dragMoveEvent
+320 QWidget::dragLeaveEvent
+328 QWidget::dropEvent
+336 QWidget::showEvent
+344 QWidget::hideEvent
+352 QWidget::x11Event
+360 QWidget::changeEvent
+368 QWidget::metric
+376 QWidget::inputMethodEvent
+384 QWidget::inputMethodQuery
+392 QWidget::focusNextPrevChild
+400 QWidget::styleChange
+408 QWidget::enabledChange
+416 QWidget::paletteChange
+424 QWidget::fontChange
+432 QWidget::windowActivationChange
+440 QWidget::languageChange
+448 (int (*)(...))-0x00000000000000010
+456 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+464 QHelpSearchResultWidget::_ZThn16_N23QHelpSearchResultWidgetD1Ev
+472 QHelpSearchResultWidget::_ZThn16_N23QHelpSearchResultWidgetD0Ev
+480 QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchResultWidget
+ size=48 align=8
+ base size=48 base align=8
+QHelpSearchResultWidget (0x7f4f3246ba10) 0
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 16u)
+ QWidget (0x7f4f32467500) 0
+ primary-for QHelpSearchResultWidget (0x7f4f3246ba10)
+ QObject (0x7f4f3246ba80) 0
+ primary-for QWidget (0x7f4f32467500)
+ QPaintDevice (0x7f4f3246baf0) 16
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 464u)
+
diff --git a/tests/auto/bic/data/QtHelp.4.6.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtHelp.4.6.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..fd930af7e
--- /dev/null
+++ b/tests/auto/bic/data/QtHelp.4.6.0.linux-gcc-ia32.txt
@@ -0,0 +1,5492 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb6f1ba8c) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb6f1bc30) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb6ed930c) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb6ed93c0) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb6ed9bf4) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0xb6ed9d20) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb6ed9f78) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb6556168) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0xb65828ac) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0xb65a1b40) 0
+ QBasicAtomicInt (0xb6582fb4) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb64b23c0) 0 empty
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb64b23fc) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb64b2870) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb64b2834) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb6361780) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb637ef3c) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb637ef78) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb637ef00) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb625ebf4) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb62c28e8) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb6148880) 0
+ QString (0xb617e03c) 0
+
+Class QStringRef
+ size=12 align=4
+ base size=12 base align=4
+QStringRef (0xb617e384) 0
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb61c92d0) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb61d7140) 0
+ QGenericArgument (0xb61c94ec) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb61c9654) 0
+
+Class QMetaObjectExtraData
+ size=8 align=4
+ base size=8 base align=4
+QMetaObjectExtraData (0xb61c9780) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb61c9ac8) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::bad_exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb600edc0) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb61c9bb8) 0 nearly-empty
+ primary-for std::bad_exception (0xb600edc0)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb600ef40) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb61c9e10) 0 nearly-empty
+ primary-for std::bad_alloc (0xb600ef40)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb6029078) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb6029168) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb602912c) 0
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0xb602999c) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=28 align=4
+ base size=28 base align=4
+QObjectData (0xb6029a50) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb6029b04) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb5f13384) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb5f15600) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb5f134b0) 0
+ primary-for QIODevice (0xb5f15600)
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb5f4f348) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb5f4f384) 0
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb5f5d280) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb5f5d2c0) 0
+ primary-for QFile (0xb5f5d280)
+ QObject (0xb5f4f3fc) 0
+ primary-for QIODevice (0xb5f5d2c0)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb5f4f870) 0
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb5f4fec4) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb5e105dc) 0
+
+Class QStringMatcher::Data
+ size=264 align=4
+ base size=264 base align=4
+QStringMatcher::Data (0xb5e4e000) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb5e10fb4) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb5e29980) 0
+ QList<QString> (0xb5e4e12c) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb5e94690) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0xb5e94e10) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0xb5e94e4c) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=20 align=4
+ base size=20 base align=4
+QAbstractFileEngine::MapExtensionOption (0xb5edf280) 0
+ QAbstractFileEngine::ExtensionOption (0xb5e94e88) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::MapExtensionReturn (0xb5edf300) 0
+ QAbstractFileEngine::ExtensionReturn (0xb5e94ec4) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::UnMapExtensionOption (0xb5edf380) 0
+ QAbstractFileEngine::ExtensionOption (0xb5e94f00) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+8 QAbstractFileEngine::~QAbstractFileEngine
+12 QAbstractFileEngine::~QAbstractFileEngine
+16 QAbstractFileEngine::open
+20 QAbstractFileEngine::close
+24 QAbstractFileEngine::flush
+28 QAbstractFileEngine::size
+32 QAbstractFileEngine::pos
+36 QAbstractFileEngine::seek
+40 QAbstractFileEngine::isSequential
+44 QAbstractFileEngine::remove
+48 QAbstractFileEngine::copy
+52 QAbstractFileEngine::rename
+56 QAbstractFileEngine::link
+60 QAbstractFileEngine::mkdir
+64 QAbstractFileEngine::rmdir
+68 QAbstractFileEngine::setSize
+72 QAbstractFileEngine::caseSensitive
+76 QAbstractFileEngine::isRelativePath
+80 QAbstractFileEngine::entryList
+84 QAbstractFileEngine::fileFlags
+88 QAbstractFileEngine::setPermissions
+92 QAbstractFileEngine::fileName
+96 QAbstractFileEngine::ownerId
+100 QAbstractFileEngine::owner
+104 QAbstractFileEngine::fileTime
+108 QAbstractFileEngine::setFileName
+112 QAbstractFileEngine::handle
+116 QAbstractFileEngine::beginEntryList
+120 QAbstractFileEngine::endEntryList
+124 QAbstractFileEngine::read
+128 QAbstractFileEngine::readLine
+132 QAbstractFileEngine::write
+136 QAbstractFileEngine::extension
+140 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngine (0xb5e94dd4) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 8u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+8 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+12 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+16 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngineHandler (0xb5d12168) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 8u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+8 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+12 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QAbstractFileEngineIterator::currentFileInfo
+32 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngineIterator (0xb5d121a4) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 8u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QBuffer)
+8 QBuffer::metaObject
+12 QBuffer::qt_metacast
+16 QBuffer::qt_metacall
+20 QBuffer::~QBuffer
+24 QBuffer::~QBuffer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QBuffer::connectNotify
+52 QBuffer::disconnectNotify
+56 QIODevice::isSequential
+60 QBuffer::open
+64 QBuffer::close
+68 QBuffer::pos
+72 QBuffer::size
+76 QBuffer::seek
+80 QBuffer::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QBuffer::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QBuffer::readData
+112 QIODevice::readLineData
+116 QBuffer::writeData
+
+Class QBuffer
+ size=8 align=4
+ base size=8 base align=4
+QBuffer (0xb5edf6c0) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 8u)
+ QIODevice (0xb5edf700) 0
+ primary-for QBuffer (0xb5edf6c0)
+ QObject (0xb5d1221c) 0
+ primary-for QIODevice (0xb5edf700)
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb5d128e8) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb5d128ac) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb5d5b000) 0 empty
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb5d5b744) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb5d5b708) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSystemLocale)
+8 QSystemLocale::~QSystemLocale
+12 QSystemLocale::~QSystemLocale
+16 QSystemLocale::query
+20 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=4 align=4
+ base size=4 base align=4
+QSystemLocale (0xb5d5ba50) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 8u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0xb5d5bac8) 0
+
+Class QLocale
+ size=4 align=4
+ base size=4 base align=4
+QLocale (0xb5d5ba8c) 0
+
+Class QTextCodec::ConverterState
+ size=28 align=4
+ base size=28 base align=4
+QTextCodec::ConverterState (0xb5cdd12c) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTextCodec)
+8 __cxa_pure_virtual
+12 QTextCodec::aliases
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QTextCodec::~QTextCodec
+32 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=4 align=4
+ base size=4 base align=4
+QTextCodec (0xb5cdd0f0) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 8u)
+
+Class QTextEncoder
+ size=32 align=4
+ base size=32 base align=4
+QTextEncoder (0xb5cdde10) 0
+
+Class QTextDecoder
+ size=32 align=4
+ base size=32 base align=4
+QTextDecoder (0xb5b27078) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTextStream)
+8 QTextStream::~QTextStream
+12 QTextStream::~QTextStream
+
+Class QTextStream
+ size=8 align=4
+ base size=8 base align=4
+QTextStream (0xb5b272d0) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 8u)
+
+Class QTextStreamManipulator
+ size=24 align=4
+ base size=22 base align=4
+QTextStreamManipulator (0xb5b27960) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextIStream)
+8 QTextIStream::~QTextIStream
+12 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=8 align=4
+ base size=8 base align=4
+QTextIStream (0xb5b79400) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 8u)
+ QTextStream (0xb5b76b40) 0
+ primary-for QTextIStream (0xb5b79400)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextOStream)
+8 QTextOStream::~QTextOStream
+12 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=8 align=4
+ base size=8 base align=4
+QTextOStream (0xb5b796c0) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 8u)
+ QTextStream (0xb5b8d1e0) 0
+ primary-for QTextOStream (0xb5b796c0)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb5b8d870) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb5b8da14) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb5b8da50) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb5b8db04) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb5b8de10) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb5b8de4c) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb5b8de88) 0
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0xb5a3a1a4) 0
+
+Class QDebug::Stream
+ size=24 align=4
+ base size=22 base align=4
+QDebug::Stream (0xb5a3a384) 0
+
+Class QDebug
+ size=4 align=4
+ base size=4 base align=4
+QDebug (0xb5a3a348) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0xb5906fb4) 0 empty
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QDirIterator)
+8 QDirIterator::~QDirIterator
+12 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=8 align=4
+ base size=8 base align=4
+QDirIterator (0xb5930258) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 8u)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+8 QFileSystemWatcher::metaObject
+12 QFileSystemWatcher::qt_metacast
+16 QFileSystemWatcher::qt_metacall
+20 QFileSystemWatcher::~QFileSystemWatcher
+24 QFileSystemWatcher::~QFileSystemWatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=8 align=4
+ base size=8 base align=4
+QFileSystemWatcher (0xb5931bc0) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 8u)
+ QObject (0xb59303c0) 0
+ primary-for QFileSystemWatcher (0xb5931bc0)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QFSFileEngine)
+8 QFSFileEngine::~QFSFileEngine
+12 QFSFileEngine::~QFSFileEngine
+16 QFSFileEngine::open
+20 QFSFileEngine::close
+24 QFSFileEngine::flush
+28 QFSFileEngine::size
+32 QFSFileEngine::pos
+36 QFSFileEngine::seek
+40 QFSFileEngine::isSequential
+44 QFSFileEngine::remove
+48 QFSFileEngine::copy
+52 QFSFileEngine::rename
+56 QFSFileEngine::link
+60 QFSFileEngine::mkdir
+64 QFSFileEngine::rmdir
+68 QFSFileEngine::setSize
+72 QFSFileEngine::caseSensitive
+76 QFSFileEngine::isRelativePath
+80 QFSFileEngine::entryList
+84 QFSFileEngine::fileFlags
+88 QFSFileEngine::setPermissions
+92 QFSFileEngine::fileName
+96 QFSFileEngine::ownerId
+100 QFSFileEngine::owner
+104 QFSFileEngine::fileTime
+108 QFSFileEngine::setFileName
+112 QFSFileEngine::handle
+116 QFSFileEngine::beginEntryList
+120 QFSFileEngine::endEntryList
+124 QFSFileEngine::read
+128 QFSFileEngine::readLine
+132 QFSFileEngine::write
+136 QFSFileEngine::extension
+140 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QFSFileEngine (0xb5931e80) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 8u)
+ QAbstractFileEngine (0xb59305dc) 0
+ primary-for QFSFileEngine (0xb5931e80)
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0xb5930708) 0
+
+Class QProcessEnvironment
+ size=4 align=4
+ base size=4 base align=4
+QProcessEnvironment (0xb5930924) 0
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QProcess)
+8 QProcess::metaObject
+12 QProcess::qt_metacast
+16 QProcess::qt_metacall
+20 QProcess::~QProcess
+24 QProcess::~QProcess
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QProcess::isSequential
+60 QIODevice::open
+64 QProcess::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QProcess::atEnd
+84 QIODevice::reset
+88 QProcess::bytesAvailable
+92 QProcess::bytesToWrite
+96 QProcess::canReadLine
+100 QProcess::waitForReadyRead
+104 QProcess::waitForBytesWritten
+108 QProcess::readData
+112 QIODevice::readLineData
+116 QProcess::writeData
+120 QProcess::setupChildProcess
+
+Class QProcess
+ size=8 align=4
+ base size=8 base align=4
+QProcess (0xb5998f00) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 8u)
+ QIODevice (0xb5998f40) 0
+ primary-for QProcess (0xb5998f00)
+ QObject (0xb59309d8) 0
+ primary-for QIODevice (0xb5998f40)
+
+Class QResource
+ size=4 align=4
+ base size=4 base align=4
+QResource (0xb5930bf4) 0
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb5930d98) 0 empty
+
+Class QVariant::PrivateShared
+ size=8 align=4
+ base size=8 base align=4
+QVariant::PrivateShared (0xb5819a50) 0
+
+Class QVariant::Private::Data
+ size=8 align=4
+ base size=8 base align=4
+QVariant::Private::Data (0xb5819ac8) 0
+
+Class QVariant::Private
+ size=12 align=4
+ base size=12 base align=4
+QVariant::Private (0xb5819a8c) 0
+
+Class QVariant::Handler
+ size=36 align=4
+ base size=36 base align=4
+QVariant::Handler (0xb5819b40) 0
+
+Class QVariant
+ size=12 align=4
+ base size=12 base align=4
+QVariant (0xb5819a14) 0
+
+Class QVariantComparisonHelper
+ size=4 align=4
+ base size=4 base align=4
+QVariantComparisonHelper (0xb58b43fc) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QSettings)
+8 QSettings::metaObject
+12 QSettings::qt_metacast
+16 QSettings::qt_metacall
+20 QSettings::~QSettings
+24 QSettings::~QSettings
+28 QSettings::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSettings
+ size=8 align=4
+ base size=8 base align=4
+QSettings (0xb58c1a00) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 8u)
+ QObject (0xb58b4a14) 0
+ primary-for QSettings (0xb58c1a00)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QTemporaryFile)
+8 QTemporaryFile::metaObject
+12 QTemporaryFile::qt_metacast
+16 QTemporaryFile::qt_metacall
+20 QTemporaryFile::~QTemporaryFile
+24 QTemporaryFile::~QTemporaryFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QTemporaryFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=8 align=4
+ base size=8 base align=4
+QTemporaryFile (0xb5705600) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 8u)
+ QFile (0xb5705640) 0
+ primary-for QTemporaryFile (0xb5705600)
+ QIODevice (0xb5705680) 0
+ primary-for QFile (0xb5705640)
+ QObject (0xb570b528) 0
+ primary-for QIODevice (0xb5705680)
+
+Class QUrl
+ size=4 align=4
+ base size=4 base align=4
+QUrl (0xb570b834) 0
+
+Class QXmlStreamStringRef
+ size=12 align=4
+ base size=12 base align=4
+QXmlStreamStringRef (0xb570bd20) 0
+
+Class QXmlStreamAttribute
+ size=56 align=4
+ base size=53 base align=4
+QXmlStreamAttribute (0xb57759d8) 0
+
+Class QXmlStreamAttributes
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamAttributes (0xb575ac40) 0
+ QVector<QXmlStreamAttribute> (0xb5796438) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=28 align=4
+ base size=28 base align=4
+QXmlStreamNamespaceDeclaration (0xb5796528) 0
+
+Class QXmlStreamNotationDeclaration
+ size=40 align=4
+ base size=40 base align=4
+QXmlStreamNotationDeclaration (0xb579699c) 0
+
+Class QXmlStreamEntityDeclaration
+ size=64 align=4
+ base size=64 base align=4
+QXmlStreamEntityDeclaration (0xb5796f78) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+8 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+12 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+16 QXmlStreamEntityResolver::resolveEntity
+20 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamEntityResolver (0xb57cd834) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 8u)
+
+Class QXmlStreamReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamReader (0xb57cd870) 0
+
+Class QXmlStreamWriter
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamWriter (0xb57cd9d8) 0
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QAbstractState)
+8 QAbstractState::metaObject
+12 QAbstractState::qt_metacast
+16 QAbstractState::qt_metacall
+20 QAbstractState::~QAbstractState
+24 QAbstractState::~QAbstractState
+28 QAbstractState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QAbstractState
+ size=8 align=4
+ base size=8 base align=4
+QAbstractState (0xb57c0c00) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 8u)
+ QObject (0xb57cdb40) 0
+ primary-for QAbstractState (0xb57c0c00)
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTransition)
+8 QAbstractTransition::metaObject
+12 QAbstractTransition::qt_metacast
+16 QAbstractTransition::qt_metacall
+20 QAbstractTransition::~QAbstractTransition
+24 QAbstractTransition::~QAbstractTransition
+28 QAbstractTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QAbstractTransition
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTransition (0xb57c0ec0) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 8u)
+ QObject (0xb57cdd5c) 0
+ primary-for QAbstractTransition (0xb57c0ec0)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QEvent)
+8 QEvent::~QEvent
+12 QEvent::~QEvent
+
+Class QEvent
+ size=12 align=4
+ base size=12 base align=4
+QEvent (0xb57cdf78) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 8u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTimerEvent)
+8 QTimerEvent::~QTimerEvent
+12 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=16 align=4
+ base size=16 base align=4
+QTimerEvent (0xb5627440) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 8u)
+ QEvent (0xb5639168) 0
+ primary-for QTimerEvent (0xb5627440)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QChildEvent)
+8 QChildEvent::~QChildEvent
+12 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=16 align=4
+ base size=16 base align=4
+QChildEvent (0xb5627500) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 8u)
+ QEvent (0xb56391e0) 0
+ primary-for QChildEvent (0xb5627500)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QCustomEvent)
+8 QCustomEvent::~QCustomEvent
+12 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=12 align=4
+ base size=12 base align=4
+QCustomEvent (0xb56277c0) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 8u)
+ QEvent (0xb5639348) 0
+ primary-for QCustomEvent (0xb56277c0)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+8 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+12 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=16 align=4
+ base size=16 base align=4
+QDynamicPropertyChangeEvent (0xb56278c0) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 8u)
+ QEvent (0xb5639438) 0
+ primary-for QDynamicPropertyChangeEvent (0xb56278c0)
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QEventTransition)
+8 QEventTransition::metaObject
+12 QEventTransition::qt_metacast
+16 QEventTransition::qt_metacall
+20 QEventTransition::~QEventTransition
+24 QEventTransition::~QEventTransition
+28 QEventTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QEventTransition::eventTest
+60 QEventTransition::onTransition
+
+Class QEventTransition
+ size=8 align=4
+ base size=8 base align=4
+QEventTransition (0xb5627980) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 8u)
+ QAbstractTransition (0xb56279c0) 0
+ primary-for QEventTransition (0xb5627980)
+ QObject (0xb56394ec) 0
+ primary-for QAbstractTransition (0xb56279c0)
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QFinalState)
+8 QFinalState::metaObject
+12 QFinalState::qt_metacast
+16 QFinalState::qt_metacall
+20 QFinalState::~QFinalState
+24 QFinalState::~QFinalState
+28 QFinalState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFinalState::onEntry
+60 QFinalState::onExit
+
+Class QFinalState
+ size=8 align=4
+ base size=8 base align=4
+QFinalState (0xb5627c80) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 8u)
+ QAbstractState (0xb5627cc0) 0
+ primary-for QFinalState (0xb5627c80)
+ QObject (0xb5639708) 0
+ primary-for QAbstractState (0xb5627cc0)
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QHistoryState)
+8 QHistoryState::metaObject
+12 QHistoryState::qt_metacast
+16 QHistoryState::qt_metacall
+20 QHistoryState::~QHistoryState
+24 QHistoryState::~QHistoryState
+28 QHistoryState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QHistoryState::onEntry
+60 QHistoryState::onExit
+
+Class QHistoryState
+ size=8 align=4
+ base size=8 base align=4
+QHistoryState (0xb5627f80) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 8u)
+ QAbstractState (0xb5627fc0) 0
+ primary-for QHistoryState (0xb5627f80)
+ QObject (0xb5639924) 0
+ primary-for QAbstractState (0xb5627fc0)
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QSignalTransition)
+8 QSignalTransition::metaObject
+12 QSignalTransition::qt_metacast
+16 QSignalTransition::qt_metacall
+20 QSignalTransition::~QSignalTransition
+24 QSignalTransition::~QSignalTransition
+28 QSignalTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSignalTransition::eventTest
+60 QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=8 align=4
+ base size=8 base align=4
+QSignalTransition (0xb5664280) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 8u)
+ QAbstractTransition (0xb56642c0) 0
+ primary-for QSignalTransition (0xb5664280)
+ QObject (0xb5639b40) 0
+ primary-for QAbstractTransition (0xb56642c0)
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QState)
+8 QState::metaObject
+12 QState::qt_metacast
+16 QState::qt_metacall
+20 QState::~QState
+24 QState::~QState
+28 QState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QState::onEntry
+60 QState::onExit
+
+Class QState
+ size=8 align=4
+ base size=8 base align=4
+QState (0xb5664580) 0
+ vptr=((& QState::_ZTV6QState) + 8u)
+ QAbstractState (0xb56645c0) 0
+ primary-for QState (0xb5664580)
+ QObject (0xb5639d5c) 0
+ primary-for QAbstractState (0xb56645c0)
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+8 QStateMachine::SignalEvent::~SignalEvent
+12 QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=24 align=4
+ base size=24 base align=4
+QStateMachine::SignalEvent (0xb56649c0) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 8u)
+ QEvent (0xb5639fb4) 0
+ primary-for QStateMachine::SignalEvent (0xb56649c0)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+8 QStateMachine::WrappedEvent::~WrappedEvent
+12 QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=20 align=4
+ base size=20 base align=4
+QStateMachine::WrappedEvent (0xb5664a40) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 8u)
+ QEvent (0xb5697000) 0
+ primary-for QStateMachine::WrappedEvent (0xb5664a40)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QStateMachine)
+8 QStateMachine::metaObject
+12 QStateMachine::qt_metacast
+16 QStateMachine::qt_metacall
+20 QStateMachine::~QStateMachine
+24 QStateMachine::~QStateMachine
+28 QStateMachine::event
+32 QStateMachine::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QStateMachine::onEntry
+60 QStateMachine::onExit
+64 QStateMachine::beginSelectTransitions
+68 QStateMachine::endSelectTransitions
+72 QStateMachine::beginMicrostep
+76 QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=8 align=4
+ base size=8 base align=4
+QStateMachine (0xb5664880) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 8u)
+ QState (0xb56648c0) 0
+ primary-for QStateMachine (0xb5664880)
+ QAbstractState (0xb5664900) 0
+ primary-for QState (0xb56648c0)
+ QObject (0xb5639f78) 0
+ primary-for QAbstractState (0xb5664900)
+
+Class QBitArray
+ size=4 align=4
+ base size=4 base align=4
+QBitArray (0xb5697384) 0
+
+Class QBitRef
+ size=8 align=4
+ base size=8 base align=4
+QBitRef (0xb56d0834) 0
+
+Class QByteArrayMatcher::Data
+ size=264 align=4
+ base size=264 base align=4
+QByteArrayMatcher::Data (0xb56d0e4c) 0
+
+Class QByteArrayMatcher
+ size=1032 align=4
+ base size=1032 base align=4
+QByteArrayMatcher (0xb56d0e10) 0
+
+Class QCryptographicHash
+ size=4 align=4
+ base size=4 base align=4
+QCryptographicHash (0xb56eb12c) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+8 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+12 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+16 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=12 align=4
+ base size=12 base align=4
+QtSharedPointer::ExternalRefCountData (0xb56eb2d0) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 8u)
+
+Vtable for QtSharedPointer::ExternalRefCountWithDestroyFn
+QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer29ExternalRefCountWithDestroyFnE)
+8 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+12 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+16 QtSharedPointer::ExternalRefCountWithDestroyFn::destroy
+
+Class QtSharedPointer::ExternalRefCountWithDestroyFn
+ size=16 align=4
+ base size=16 base align=4
+QtSharedPointer::ExternalRefCountWithDestroyFn (0xb5516800) 0
+ vptr=((& QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE) + 8u)
+ QtSharedPointer::ExternalRefCountData (0xb56ebac8) 0
+ primary-for QtSharedPointer::ExternalRefCountWithDestroyFn (0xb5516800)
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0xb5578000) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0xb5578618) 0
+
+Class QDateTime
+ size=4 align=4
+ base size=4 base align=4
+QDateTime (0xb5578b7c) 0
+
+Class QEasingCurve
+ size=4 align=4
+ base size=4 base align=4
+QEasingCurve (0xb5578e4c) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb5578ec4) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb55de474) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb55f6b7c) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb540a8ac) 0
+
+Class QLinkedListData
+ size=20 align=4
+ base size=20 base align=4
+QLinkedListData (0xb543599c) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0xb5435bb8) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb54bdd20) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb54e67bc) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb53123c0) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb5373000) 0
+
+Class QLatin1Literal
+ size=8 align=4
+ base size=8 base align=4
+QLatin1Literal (0xb53bcd98) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0xb53bce4c) 0 empty
+
+Class QTextBoundaryFinder
+ size=28 align=4
+ base size=28 base align=4
+QTextBoundaryFinder (0xb53f30f0) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTimeLine)
+8 QTimeLine::metaObject
+12 QTimeLine::qt_metacast
+16 QTimeLine::qt_metacall
+20 QTimeLine::~QTimeLine
+24 QTimeLine::~QTimeLine
+28 QObject::event
+32 QObject::eventFilter
+36 QTimeLine::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=8 align=4
+ base size=8 base align=4
+QTimeLine (0xb53e4f00) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 8u)
+ QObject (0xb53f31a4) 0
+ primary-for QTimeLine (0xb53e4f00)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QRunnable)
+8 __cxa_pure_virtual
+12 QRunnable::~QRunnable
+16 QRunnable::~QRunnable
+
+Class QRunnable
+ size=8 align=4
+ base size=8 base align=4
+QRunnable (0xb53f3438) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 8u)
+
+Class QMutex
+ size=4 align=4
+ base size=4 base align=4
+QMutex (0xb53f38ac) 0
+
+Class QMutexLocker
+ size=4 align=4
+ base size=4 base align=4
+QMutexLocker (0xb53f3f3c) 0
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+8 QtConcurrent::Exception::~Exception
+12 QtConcurrent::Exception::~Exception
+16 std::exception::what
+20 QtConcurrent::Exception::raise
+24 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::Exception (0xb5243080) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 8u)
+ std::exception (0xb523b438) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb5243080)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+8 QtConcurrent::UnhandledException::~UnhandledException
+12 QtConcurrent::UnhandledException::~UnhandledException
+16 std::exception::what
+20 QtConcurrent::UnhandledException::raise
+24 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::UnhandledException (0xb5243180) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 8u)
+ QtConcurrent::Exception (0xb52431c0) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0xb5243180)
+ std::exception (0xb523b474) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb52431c0)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionHolder (0xb523b4b0) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionStore (0xb523b4ec) 0
+
+Class QtConcurrent::ResultItem
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultItem (0xb523b528) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultIteratorBase (0xb523bb04) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+8 QtConcurrent::ResultStoreBase::~ResultStoreBase
+12 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=28 align=4
+ base size=28 base align=4
+QtConcurrent::ResultStoreBase (0xb523bc30) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 8u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+8 QFutureInterfaceBase::~QFutureInterfaceBase
+12 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureInterfaceBase (0xb5272078) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 8u)
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+8 QFutureWatcherBase::metaObject
+12 QFutureWatcherBase::qt_metacast
+16 QFutureWatcherBase::qt_metacall
+20 QFutureWatcherBase::~QFutureWatcherBase
+24 QFutureWatcherBase::~QFutureWatcherBase
+28 QFutureWatcherBase::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QFutureWatcherBase::connectNotify
+52 QFutureWatcherBase::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureWatcherBase (0xb52d5fc0) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 8u)
+ QObject (0xb52dca50) 0
+ primary-for QFutureWatcherBase (0xb52d5fc0)
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QThread)
+8 QThread::metaObject
+12 QThread::qt_metacast
+16 QThread::qt_metacall
+20 QThread::~QThread
+24 QThread::~QThread
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QThread::run
+
+Class QThread
+ size=8 align=4
+ base size=8 base align=4
+QThread (0xb511d180) 0
+ vptr=((& QThread::_ZTV7QThread) + 8u)
+ QObject (0xb510fa50) 0
+ primary-for QThread (0xb511d180)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QThreadPool)
+8 QThreadPool::metaObject
+12 QThreadPool::qt_metacast
+16 QThreadPool::qt_metacall
+20 QThreadPool::~QThreadPool
+24 QThreadPool::~QThreadPool
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QThreadPool
+ size=8 align=4
+ base size=8 base align=4
+QThreadPool (0xb511d4c0) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 8u)
+ QObject (0xb510fce4) 0
+ primary-for QThreadPool (0xb511d4c0)
+
+Class QWaitCondition
+ size=4 align=4
+ base size=4 base align=4
+QWaitCondition (0xb510ff00) 0
+
+Class QSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSemaphore (0xb510ff3c) 0
+
+Class QtConcurrent::ThreadEngineBarrier
+ size=12 align=4
+ base size=12 base align=4
+QtConcurrent::ThreadEngineBarrier (0xb510ff78) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+8 QtConcurrent::ThreadEngineBase::run
+12 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+16 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+20 QtConcurrent::ThreadEngineBase::start
+24 QtConcurrent::ThreadEngineBase::finish
+28 QtConcurrent::ThreadEngineBase::threadFunction
+32 QtConcurrent::ThreadEngineBase::shouldStartThread
+36 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+40 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=32 align=4
+ base size=32 base align=4
+QtConcurrent::ThreadEngineBase (0xb511d840) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 8u)
+ QRunnable (0xb510ffb4) 0
+ primary-for QtConcurrent::ThreadEngineBase (0xb511d840)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 12u)
+4 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 68u)
+
+Class QtConcurrent::BlockSizeManager
+ size=72 align=4
+ base size=72 base align=4
+QtConcurrent::BlockSizeManager (0xb51625a0) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QFactoryInterface)
+8 QFactoryInterface::~QFactoryInterface
+12 QFactoryInterface::~QFactoryInterface
+16 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QFactoryInterface (0xb4f73e88) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 8u)
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+8 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+12 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QTextCodecFactoryInterface (0xb4df6c40) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 8u)
+ QFactoryInterface (0xb4dff438) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4df6c40)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+8 QTextCodecPlugin::metaObject
+12 QTextCodecPlugin::qt_metacast
+16 QTextCodecPlugin::qt_metacall
+20 QTextCodecPlugin::~QTextCodecPlugin
+24 QTextCodecPlugin::~QTextCodecPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 QTextCodecPlugin::keys
+80 QTextCodecPlugin::create
+84 (int (*)(...))-0x000000008
+88 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+92 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD1Ev
+96 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD0Ev
+100 QTextCodecPlugin::_ZThn8_NK16QTextCodecPlugin4keysEv
+104 QTextCodecPlugin::_ZThn8_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=12 align=4
+ base size=12 base align=4
+QTextCodecPlugin (0xb4e05a00) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 8u)
+ QObject (0xb4dff744) 0
+ primary-for QTextCodecPlugin (0xb4e05a00)
+ QTextCodecFactoryInterface (0xb4df6f00) 8 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 92u)
+ QFactoryInterface (0xb4dff780) 8 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4df6f00)
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0xb4e1fbf4) 0 empty
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QEventLoop)
+8 QEventLoop::metaObject
+12 QEventLoop::qt_metacast
+16 QEventLoop::qt_metacall
+20 QEventLoop::~QEventLoop
+24 QEventLoop::~QEventLoop
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QEventLoop
+ size=8 align=4
+ base size=8 base align=4
+QEventLoop (0xb4e2aac0) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 8u)
+ QObject (0xb4e1fc6c) 0
+ primary-for QEventLoop (0xb4e2aac0)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+8 QAbstractEventDispatcher::metaObject
+12 QAbstractEventDispatcher::qt_metacast
+16 QAbstractEventDispatcher::qt_metacall
+20 QAbstractEventDispatcher::~QAbstractEventDispatcher
+24 QAbstractEventDispatcher::~QAbstractEventDispatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 QAbstractEventDispatcher::startingUp
+104 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=8 align=4
+ base size=8 base align=4
+QAbstractEventDispatcher (0xb4e2aec0) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 8u)
+ QObject (0xb4e1ff78) 0
+ primary-for QAbstractEventDispatcher (0xb4e2aec0)
+
+Class QModelIndex
+ size=16 align=4
+ base size=16 base align=4
+QModelIndex (0xb4e671a4) 0
+
+Class QPersistentModelIndex
+ size=4 align=4
+ base size=4 base align=4
+QPersistentModelIndex (0xb4e7a654) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractItemModel)
+8 QAbstractItemModel::metaObject
+12 QAbstractItemModel::qt_metacast
+16 QAbstractItemModel::qt_metacall
+20 QAbstractItemModel::~QAbstractItemModel
+24 QAbstractItemModel::~QAbstractItemModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractItemModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemModel (0xb4e64b00) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 8u)
+ QObject (0xb4e7a7bc) 0
+ primary-for QAbstractItemModel (0xb4e64b00)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTableModel)
+8 QAbstractTableModel::metaObject
+12 QAbstractTableModel::qt_metacast
+16 QAbstractTableModel::qt_metacall
+20 QAbstractTableModel::~QAbstractTableModel
+24 QAbstractTableModel::~QAbstractTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractTableModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTableModel (0xb4eb3140) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 8u)
+ QAbstractItemModel (0xb4eb3180) 0
+ primary-for QAbstractTableModel (0xb4eb3140)
+ QObject (0xb4eb712c) 0
+ primary-for QAbstractItemModel (0xb4eb3180)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractListModel)
+8 QAbstractListModel::metaObject
+12 QAbstractListModel::qt_metacast
+16 QAbstractListModel::qt_metacall
+20 QAbstractListModel::~QAbstractListModel
+24 QAbstractListModel::~QAbstractListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 __cxa_pure_virtual
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractListModel (0xb4eb33c0) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 8u)
+ QAbstractItemModel (0xb4eb3400) 0
+ primary-for QAbstractListModel (0xb4eb33c0)
+ QObject (0xb4eb7258) 0
+ primary-for QAbstractItemModel (0xb4eb3400)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0xb4edb12c) 0
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QCoreApplication)
+8 QCoreApplication::metaObject
+12 QCoreApplication::qt_metacast
+16 QCoreApplication::qt_metacall
+20 QCoreApplication::~QCoreApplication
+24 QCoreApplication::~QCoreApplication
+28 QCoreApplication::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QCoreApplication::notify
+60 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=8 align=4
+ base size=8 base align=4
+QCoreApplication (0xb4eb3ec0) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 8u)
+ QObject (0xb4edb3c0) 0
+ primary-for QCoreApplication (0xb4eb3ec0)
+
+Class __exception
+ size=32 align=4
+ base size=32 base align=4
+__exception (0xb4edb960) 0
+
+Class QMetaMethod
+ size=8 align=4
+ base size=8 base align=4
+QMetaMethod (0xb4d37690) 0
+
+Class QMetaEnum
+ size=8 align=4
+ base size=8 base align=4
+QMetaEnum (0xb4d3799c) 0
+
+Class QMetaProperty
+ size=20 align=4
+ base size=20 base align=4
+QMetaProperty (0xb4d37bf4) 0
+
+Class QMetaClassInfo
+ size=8 align=4
+ base size=8 base align=4
+QMetaClassInfo (0xb4d37ca8) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QMimeData)
+8 QMimeData::metaObject
+12 QMimeData::qt_metacast
+16 QMimeData::qt_metacall
+20 QMimeData::~QMimeData
+24 QMimeData::~QMimeData
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QMimeData::hasFormat
+60 QMimeData::formats
+64 QMimeData::retrieveData
+
+Class QMimeData
+ size=8 align=4
+ base size=8 base align=4
+QMimeData (0xb4d3dd00) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 8u)
+ QObject (0xb4d37f00) 0
+ primary-for QMimeData (0xb4d3dd00)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+8 QObjectCleanupHandler::metaObject
+12 QObjectCleanupHandler::qt_metacast
+16 QObjectCleanupHandler::qt_metacall
+20 QObjectCleanupHandler::~QObjectCleanupHandler
+24 QObjectCleanupHandler::~QObjectCleanupHandler
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=12 align=4
+ base size=12 base align=4
+QObjectCleanupHandler (0xb4d3dfc0) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 8u)
+ QObject (0xb4d6f12c) 0
+ primary-for QObjectCleanupHandler (0xb4d3dfc0)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSharedMemory)
+8 QSharedMemory::metaObject
+12 QSharedMemory::qt_metacast
+16 QSharedMemory::qt_metacall
+20 QSharedMemory::~QSharedMemory
+24 QSharedMemory::~QSharedMemory
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=8 align=4
+ base size=8 base align=4
+QSharedMemory (0xb4d71200) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 8u)
+ QObject (0xb4d6f258) 0
+ primary-for QSharedMemory (0xb4d71200)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSignalMapper)
+8 QSignalMapper::metaObject
+12 QSignalMapper::qt_metacast
+16 QSignalMapper::qt_metacall
+20 QSignalMapper::~QSignalMapper
+24 QSignalMapper::~QSignalMapper
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=8 align=4
+ base size=8 base align=4
+QSignalMapper (0xb4d714c0) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 8u)
+ QObject (0xb4d6f474) 0
+ primary-for QSignalMapper (0xb4d714c0)
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QSocketNotifier)
+8 QSocketNotifier::metaObject
+12 QSocketNotifier::qt_metacast
+16 QSocketNotifier::qt_metacall
+20 QSocketNotifier::~QSocketNotifier
+24 QSocketNotifier::~QSocketNotifier
+28 QSocketNotifier::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=20 align=4
+ base size=17 base align=4
+QSocketNotifier (0xb4d71780) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 8u)
+ QObject (0xb4d6f690) 0
+ primary-for QSocketNotifier (0xb4d71780)
+
+Class QSystemSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSystemSemaphore (0xb4d6f960) 0
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QTimer)
+8 QTimer::metaObject
+12 QTimer::qt_metacast
+16 QTimer::qt_metacall
+20 QTimer::~QTimer
+24 QTimer::~QTimer
+28 QObject::event
+32 QObject::eventFilter
+36 QTimer::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QTimer
+ size=24 align=4
+ base size=21 base align=4
+QTimer (0xb4d71b40) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 8u)
+ QObject (0xb4d6fa14) 0
+ primary-for QTimer (0xb4d71b40)
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTranslator)
+8 QTranslator::metaObject
+12 QTranslator::qt_metacast
+16 QTranslator::qt_metacall
+20 QTranslator::~QTranslator
+24 QTranslator::~QTranslator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTranslator::translate
+60 QTranslator::isEmpty
+
+Class QTranslator
+ size=8 align=4
+ base size=8 base align=4
+QTranslator (0xb4dc0080) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 8u)
+ QObject (0xb4d6fca8) 0
+ primary-for QTranslator (0xb4dc0080)
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QLibrary)
+8 QLibrary::metaObject
+12 QLibrary::qt_metacast
+16 QLibrary::qt_metacall
+20 QLibrary::~QLibrary
+24 QLibrary::~QLibrary
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QLibrary
+ size=16 align=4
+ base size=13 base align=4
+QLibrary (0xb4dc03c0) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 8u)
+ QObject (0xb4d6ff78) 0
+ primary-for QLibrary (0xb4dc03c0)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QPluginLoader)
+8 QPluginLoader::metaObject
+12 QPluginLoader::qt_metacast
+16 QPluginLoader::qt_metacall
+20 QPluginLoader::~QPluginLoader
+24 QPluginLoader::~QPluginLoader
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=16 align=4
+ base size=13 base align=4
+QPluginLoader (0xb4dc07c0) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 8u)
+ QObject (0xb4ddc1e0) 0
+ primary-for QPluginLoader (0xb4dc07c0)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0xb4ddc30c) 0
+
+Class QReadWriteLock
+ size=4 align=4
+ base size=4 base align=4
+QReadWriteLock (0xb4c1330c) 0
+
+Class QReadLocker
+ size=4 align=4
+ base size=4 base align=4
+QReadLocker (0xb4c13348) 0
+
+Class QWriteLocker
+ size=4 align=4
+ base size=4 base align=4
+QWriteLocker (0xb4c13834) 0
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0xb4c13d20) 0
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractAnimation)
+8 QAbstractAnimation::metaObject
+12 QAbstractAnimation::qt_metacast
+16 QAbstractAnimation::qt_metacall
+20 QAbstractAnimation::~QAbstractAnimation
+24 QAbstractAnimation::~QAbstractAnimation
+28 QAbstractAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=8 align=4
+ base size=8 base align=4
+QAbstractAnimation (0xb4c346c0) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 8u)
+ QObject (0xb4c13d98) 0
+ primary-for QAbstractAnimation (0xb4c346c0)
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QAnimationGroup)
+8 QAnimationGroup::metaObject
+12 QAnimationGroup::qt_metacast
+16 QAnimationGroup::qt_metacall
+20 QAnimationGroup::~QAnimationGroup
+24 QAnimationGroup::~QAnimationGroup
+28 QAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QAnimationGroup (0xb4c34980) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 8u)
+ QAbstractAnimation (0xb4c349c0) 0
+ primary-for QAnimationGroup (0xb4c34980)
+ QObject (0xb4c4f000) 0
+ primary-for QAbstractAnimation (0xb4c349c0)
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+8 QParallelAnimationGroup::metaObject
+12 QParallelAnimationGroup::qt_metacast
+16 QParallelAnimationGroup::qt_metacall
+20 QParallelAnimationGroup::~QParallelAnimationGroup
+24 QParallelAnimationGroup::~QParallelAnimationGroup
+28 QParallelAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QParallelAnimationGroup::duration
+60 QParallelAnimationGroup::updateCurrentTime
+64 QParallelAnimationGroup::updateState
+68 QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QParallelAnimationGroup (0xb4c34c80) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 8u)
+ QAnimationGroup (0xb4c34cc0) 0
+ primary-for QParallelAnimationGroup (0xb4c34c80)
+ QAbstractAnimation (0xb4c34d00) 0
+ primary-for QAnimationGroup (0xb4c34cc0)
+ QObject (0xb4c4f21c) 0
+ primary-for QAbstractAnimation (0xb4c34d00)
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QPauseAnimation)
+8 QPauseAnimation::metaObject
+12 QPauseAnimation::qt_metacast
+16 QPauseAnimation::qt_metacall
+20 QPauseAnimation::~QPauseAnimation
+24 QPauseAnimation::~QPauseAnimation
+28 QPauseAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QPauseAnimation::duration
+60 QPauseAnimation::updateCurrentTime
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=8 align=4
+ base size=8 base align=4
+QPauseAnimation (0xb4c34fc0) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 8u)
+ QAbstractAnimation (0xb4c68000) 0
+ primary-for QPauseAnimation (0xb4c34fc0)
+ QObject (0xb4c4f438) 0
+ primary-for QAbstractAnimation (0xb4c68000)
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QVariantAnimation)
+8 QVariantAnimation::metaObject
+12 QVariantAnimation::qt_metacast
+16 QVariantAnimation::qt_metacall
+20 QVariantAnimation::~QVariantAnimation
+24 QVariantAnimation::~QVariantAnimation
+28 QVariantAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QVariantAnimation::duration
+60 QVariantAnimation::updateCurrentTime
+64 QVariantAnimation::updateState
+68 QAbstractAnimation::updateDirection
+72 __cxa_pure_virtual
+76 QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=8 align=4
+ base size=8 base align=4
+QVariantAnimation (0xb4c682c0) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 8u)
+ QAbstractAnimation (0xb4c68300) 0
+ primary-for QVariantAnimation (0xb4c682c0)
+ QObject (0xb4c4f654) 0
+ primary-for QAbstractAnimation (0xb4c68300)
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QPropertyAnimation)
+8 QPropertyAnimation::metaObject
+12 QPropertyAnimation::qt_metacast
+16 QPropertyAnimation::qt_metacall
+20 QPropertyAnimation::~QPropertyAnimation
+24 QPropertyAnimation::~QPropertyAnimation
+28 QPropertyAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QVariantAnimation::duration
+60 QVariantAnimation::updateCurrentTime
+64 QPropertyAnimation::updateState
+68 QAbstractAnimation::updateDirection
+72 QPropertyAnimation::updateCurrentValue
+76 QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=8 align=4
+ base size=8 base align=4
+QPropertyAnimation (0xb4c68700) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 8u)
+ QVariantAnimation (0xb4c68740) 0
+ primary-for QPropertyAnimation (0xb4c68700)
+ QAbstractAnimation (0xb4c68780) 0
+ primary-for QVariantAnimation (0xb4c68740)
+ QObject (0xb4c4f870) 0
+ primary-for QAbstractAnimation (0xb4c68780)
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+8 QSequentialAnimationGroup::metaObject
+12 QSequentialAnimationGroup::qt_metacast
+16 QSequentialAnimationGroup::qt_metacall
+20 QSequentialAnimationGroup::~QSequentialAnimationGroup
+24 QSequentialAnimationGroup::~QSequentialAnimationGroup
+28 QSequentialAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSequentialAnimationGroup::duration
+60 QSequentialAnimationGroup::updateCurrentTime
+64 QSequentialAnimationGroup::updateState
+68 QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QSequentialAnimationGroup (0xb4c68a40) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 8u)
+ QAnimationGroup (0xb4c68a80) 0
+ primary-for QSequentialAnimationGroup (0xb4c68a40)
+ QAbstractAnimation (0xb4c68ac0) 0
+ primary-for QAnimationGroup (0xb4c68a80)
+ QObject (0xb4c4fa8c) 0
+ primary-for QAbstractAnimation (0xb4c68ac0)
+
+Class QSqlRecord
+ size=4 align=4
+ base size=4 base align=4
+QSqlRecord (0xb4c4fd98) 0
+
+Vtable for QSqlDriverCreatorBase
+QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QSqlDriverCreatorBase)
+8 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+12 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+16 __cxa_pure_virtual
+
+Class QSqlDriverCreatorBase
+ size=4 align=4
+ base size=4 base align=4
+QSqlDriverCreatorBase (0xb4c4fe4c) 0 nearly-empty
+ vptr=((& QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase) + 8u)
+
+Class QSqlDatabase
+ size=4 align=4
+ base size=4 base align=4
+QSqlDatabase (0xb4ccb0b4) 0
+
+Class QSqlQuery
+ size=4 align=4
+ base size=4 base align=4
+QSqlQuery (0xb4ccb12c) 0
+
+Vtable for QSqlDriver
+QSqlDriver::_ZTV10QSqlDriver: 32u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QSqlDriver)
+8 QSqlDriver::metaObject
+12 QSqlDriver::qt_metacast
+16 QSqlDriver::qt_metacall
+20 QSqlDriver::~QSqlDriver
+24 QSqlDriver::~QSqlDriver
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSqlDriver::isOpen
+60 QSqlDriver::beginTransaction
+64 QSqlDriver::commitTransaction
+68 QSqlDriver::rollbackTransaction
+72 QSqlDriver::tables
+76 QSqlDriver::primaryIndex
+80 QSqlDriver::record
+84 QSqlDriver::formatValue
+88 QSqlDriver::escapeIdentifier
+92 QSqlDriver::sqlStatement
+96 QSqlDriver::handle
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 QSqlDriver::setOpen
+120 QSqlDriver::setOpenError
+124 QSqlDriver::setLastError
+
+Class QSqlDriver
+ size=8 align=4
+ base size=8 base align=4
+QSqlDriver (0xb4cca3c0) 0
+ vptr=((& QSqlDriver::_ZTV10QSqlDriver) + 8u)
+ QObject (0xb4ccb1a4) 0
+ primary-for QSqlDriver (0xb4cca3c0)
+
+Vtable for QSqlDriverFactoryInterface
+QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QSqlDriverFactoryInterface)
+8 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+12 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QSqlDriverFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QSqlDriverFactoryInterface (0xb4cca840) 0 nearly-empty
+ vptr=((& QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface) + 8u)
+ QFactoryInterface (0xb4ccb618) 0 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0xb4cca840)
+
+Vtable for QSqlDriverPlugin
+QSqlDriverPlugin::_ZTV16QSqlDriverPlugin: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+8 QSqlDriverPlugin::metaObject
+12 QSqlDriverPlugin::qt_metacast
+16 QSqlDriverPlugin::qt_metacall
+20 QSqlDriverPlugin::~QSqlDriverPlugin
+24 QSqlDriverPlugin::~QSqlDriverPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 (int (*)(...))-0x000000008
+68 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+72 QSqlDriverPlugin::_ZThn8_N16QSqlDriverPluginD1Ev
+76 QSqlDriverPlugin::_ZThn8_N16QSqlDriverPluginD0Ev
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+
+Class QSqlDriverPlugin
+ size=12 align=4
+ base size=12 base align=4
+QSqlDriverPlugin (0xb4ae4000) 0
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 8u)
+ QObject (0xb4ccb924) 0
+ primary-for QSqlDriverPlugin (0xb4ae4000)
+ QSqlDriverFactoryInterface (0xb4ccab00) 8 nearly-empty
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 72u)
+ QFactoryInterface (0xb4ccb960) 8 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0xb4ccab00)
+
+Class QSqlError
+ size=16 align=4
+ base size=16 base align=4
+QSqlError (0xb4ccba8c) 0
+
+Class QSqlField
+ size=16 align=4
+ base size=16 base align=4
+QSqlField (0xb4ccbac8) 0
+
+Class QSqlIndex
+ size=16 align=4
+ base size=16 base align=4
+QSqlIndex (0xb4ccaec0) 0
+ QSqlRecord (0xb4ccbc30) 0
+
+Vtable for QSqlResult
+QSqlResult::_ZTV10QSqlResult: 29u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QSqlResult)
+8 QSqlResult::~QSqlResult
+12 QSqlResult::~QSqlResult
+16 QSqlResult::handle
+20 QSqlResult::setAt
+24 QSqlResult::setActive
+28 QSqlResult::setLastError
+32 QSqlResult::setQuery
+36 QSqlResult::setSelect
+40 QSqlResult::setForwardOnly
+44 QSqlResult::exec
+48 QSqlResult::prepare
+52 QSqlResult::savePrepare
+56 QSqlResult::bindValue
+60 QSqlResult::bindValue
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QSqlResult::fetchNext
+84 QSqlResult::fetchPrevious
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 QSqlResult::record
+108 QSqlResult::lastInsertId
+112 QSqlResult::virtual_hook
+
+Class QSqlResult
+ size=8 align=4
+ base size=8 base align=4
+QSqlResult (0xb4ccbdd4) 0
+ vptr=((& QSqlResult::_ZTV10QSqlResult) + 8u)
+
+Vtable for QSqlQueryModel
+QSqlQueryModel::_ZTV14QSqlQueryModel: 44u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QSqlQueryModel)
+8 QSqlQueryModel::metaObject
+12 QSqlQueryModel::qt_metacast
+16 QSqlQueryModel::qt_metacall
+20 QSqlQueryModel::~QSqlQueryModel
+24 QSqlQueryModel::~QSqlQueryModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlQueryModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlQueryModel::data
+80 QAbstractItemModel::setData
+84 QSqlQueryModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QSqlQueryModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+168 QSqlQueryModel::clear
+172 QSqlQueryModel::queryChange
+
+Class QSqlQueryModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlQueryModel (0xb4b150c0) 0
+ vptr=((& QSqlQueryModel::_ZTV14QSqlQueryModel) + 8u)
+ QAbstractTableModel (0xb4b15100) 0
+ primary-for QSqlQueryModel (0xb4b150c0)
+ QAbstractItemModel (0xb4b15140) 0
+ primary-for QAbstractTableModel (0xb4b15100)
+ QObject (0xb4ccbe4c) 0
+ primary-for QAbstractItemModel (0xb4b15140)
+
+Vtable for QSqlTableModel
+QSqlTableModel::_ZTV14QSqlTableModel: 55u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QSqlTableModel)
+8 QSqlTableModel::metaObject
+12 QSqlTableModel::qt_metacast
+16 QSqlTableModel::qt_metacall
+20 QSqlTableModel::~QSqlTableModel
+24 QSqlTableModel::~QSqlTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlTableModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlTableModel::data
+80 QSqlTableModel::setData
+84 QSqlTableModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QSqlTableModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QSqlTableModel::removeRows
+128 QSqlTableModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QSqlTableModel::flags
+144 QSqlTableModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QSqlTableModel::submit
+164 QSqlTableModel::revert
+168 QSqlTableModel::clear
+172 QSqlQueryModel::queryChange
+176 QSqlTableModel::select
+180 QSqlTableModel::setTable
+184 QSqlTableModel::setEditStrategy
+188 QSqlTableModel::setSort
+192 QSqlTableModel::setFilter
+196 QSqlTableModel::revertRow
+200 QSqlTableModel::updateRowInTable
+204 QSqlTableModel::insertRowIntoTable
+208 QSqlTableModel::deleteRowFromTable
+212 QSqlTableModel::orderByClause
+216 QSqlTableModel::selectStatement
+
+Class QSqlTableModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlTableModel (0xb4b15400) 0
+ vptr=((& QSqlTableModel::_ZTV14QSqlTableModel) + 8u)
+ QSqlQueryModel (0xb4b15440) 0
+ primary-for QSqlTableModel (0xb4b15400)
+ QAbstractTableModel (0xb4b15480) 0
+ primary-for QSqlQueryModel (0xb4b15440)
+ QAbstractItemModel (0xb4b154c0) 0
+ primary-for QAbstractTableModel (0xb4b15480)
+ QObject (0xb4b34078) 0
+ primary-for QAbstractItemModel (0xb4b154c0)
+
+Class QSqlRelation
+ size=12 align=4
+ base size=12 base align=4
+QSqlRelation (0xb4b34294) 0
+
+Vtable for QSqlRelationalTableModel
+QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel: 57u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QSqlRelationalTableModel)
+8 QSqlRelationalTableModel::metaObject
+12 QSqlRelationalTableModel::qt_metacast
+16 QSqlRelationalTableModel::qt_metacall
+20 QSqlRelationalTableModel::~QSqlRelationalTableModel
+24 QSqlRelationalTableModel::~QSqlRelationalTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlTableModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlRelationalTableModel::data
+80 QSqlRelationalTableModel::setData
+84 QSqlTableModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QSqlTableModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QSqlTableModel::removeRows
+128 QSqlRelationalTableModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QSqlTableModel::flags
+144 QSqlTableModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QSqlTableModel::submit
+164 QSqlTableModel::revert
+168 QSqlRelationalTableModel::clear
+172 QSqlQueryModel::queryChange
+176 QSqlRelationalTableModel::select
+180 QSqlRelationalTableModel::setTable
+184 QSqlTableModel::setEditStrategy
+188 QSqlTableModel::setSort
+192 QSqlTableModel::setFilter
+196 QSqlRelationalTableModel::revertRow
+200 QSqlRelationalTableModel::updateRowInTable
+204 QSqlRelationalTableModel::insertRowIntoTable
+208 QSqlTableModel::deleteRowFromTable
+212 QSqlRelationalTableModel::orderByClause
+216 QSqlRelationalTableModel::selectStatement
+220 QSqlRelationalTableModel::setRelation
+224 QSqlRelationalTableModel::relationModel
+
+Class QSqlRelationalTableModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlRelationalTableModel (0xb4b15a40) 0
+ vptr=((& QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel) + 8u)
+ QSqlTableModel (0xb4b15a80) 0
+ primary-for QSqlRelationalTableModel (0xb4b15a40)
+ QSqlQueryModel (0xb4b15ac0) 0
+ primary-for QSqlTableModel (0xb4b15a80)
+ QAbstractTableModel (0xb4b15b00) 0
+ primary-for QSqlQueryModel (0xb4b15ac0)
+ QAbstractItemModel (0xb4b15b40) 0
+ primary-for QAbstractTableModel (0xb4b15b00)
+ QObject (0xb4b34ec4) 0
+ primary-for QAbstractItemModel (0xb4b15b40)
+
+Class QHelpGlobal
+ size=1 align=1
+ base size=0 base align=1
+QHelpGlobal (0xb4b690f0) 0 empty
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb4b6912c) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb4b69ce4) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb4ba3800) 0
+ QVector<QPoint> (0xb4bae384) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb4ba3e40) 0
+ QVector<QPointF> (0xb4baed5c) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb49f76cc) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb49f7690) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb49f7a14) 0
+
+Class QPainterPath::Element
+ size=20 align=4
+ base size=20 base align=4
+QPainterPath::Element (0xb4a32bb8) 0
+
+Class QPainterPath
+ size=4 align=4
+ base size=4 base align=4
+QPainterPath (0xb4a32b7c) 0
+
+Class QPainterPathPrivate
+ size=8 align=4
+ base size=8 base align=4
+QPainterPathPrivate (0xb4a6f0b4) 0
+
+Class QPainterPathStroker
+ size=4 align=4
+ base size=4 base align=4
+QPainterPathStroker (0xb4a6f1e0) 0
+
+Class QTransform
+ size=80 align=4
+ base size=80 base align=4
+QTransform (0xb4aaa168) 0
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb49010b4) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb48fc480) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb4901a8c) 0
+ primary-for QImage (0xb48fc480)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb48fcd80) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb4965654) 0
+ primary-for QPixmap (0xb48fcd80)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb4965ce4) 0
+
+Class QBrushData
+ size=104 align=4
+ base size=104 base align=4
+QBrushData (0xb4965e88) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb49c3258) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb499bc00) 0
+ QGradient (0xb49c34ec) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb499bd00) 0
+ QGradient (0xb49c3528) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb499be00) 0
+ QGradient (0xb49c3564) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb49c35a0) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb4806840) 0
+ QPalette (0xb49c3e88) 0
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb4838000) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb483821c) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb4838474) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb4838528) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb4838564) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb46d0438) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb46d0474) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb46d0690) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb4717230) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb46d06cc) 0
+ primary-for QWidget (0xb4717230)
+ QPaintDevice (0xb46d0708) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Vtable for QFrame
+QFrame::_ZTV6QFrame: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QFrame)
+8 QFrame::metaObject
+12 QFrame::qt_metacast
+16 QFrame::qt_metacall
+20 QFrame::~QFrame
+24 QFrame::~QFrame
+28 QFrame::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QFrame::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QFrame::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI6QFrame)
+232 QFrame::_ZThn8_N6QFrameD1Ev
+236 QFrame::_ZThn8_N6QFrameD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QFrame
+ size=20 align=4
+ base size=20 base align=4
+QFrame (0xb47cb6c0) 0
+ vptr=((& QFrame::_ZTV6QFrame) + 8u)
+ QWidget (0xb45db9b0) 0
+ primary-for QFrame (0xb47cb6c0)
+ QObject (0xb47bee4c) 0
+ primary-for QWidget (0xb45db9b0)
+ QPaintDevice (0xb47bee88) 8
+ vptr=((& QFrame::_ZTV6QFrame) + 232u)
+
+Vtable for QAbstractScrollArea
+QAbstractScrollArea::_ZTV19QAbstractScrollArea: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+8 QAbstractScrollArea::metaObject
+12 QAbstractScrollArea::qt_metacast
+16 QAbstractScrollArea::qt_metacall
+20 QAbstractScrollArea::~QAbstractScrollArea
+24 QAbstractScrollArea::~QAbstractScrollArea
+28 QAbstractScrollArea::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractScrollArea::mousePressEvent
+84 QAbstractScrollArea::mouseReleaseEvent
+88 QAbstractScrollArea::mouseDoubleClickEvent
+92 QAbstractScrollArea::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractScrollArea::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractScrollArea::paintEvent
+128 QWidget::moveEvent
+132 QAbstractScrollArea::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractScrollArea::dragEnterEvent
+156 QAbstractScrollArea::dragMoveEvent
+160 QAbstractScrollArea::dragLeaveEvent
+164 QAbstractScrollArea::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractScrollArea::viewportEvent
+228 QAbstractScrollArea::scrollContentsBy
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+240 QAbstractScrollArea::_ZThn8_N19QAbstractScrollAreaD1Ev
+244 QAbstractScrollArea::_ZThn8_N19QAbstractScrollAreaD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractScrollArea
+ size=20 align=4
+ base size=20 base align=4
+QAbstractScrollArea (0xb47cb980) 0
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 8u)
+ QFrame (0xb47cb9c0) 0
+ primary-for QAbstractScrollArea (0xb47cb980)
+ QWidget (0xb45ee5a0) 0
+ primary-for QFrame (0xb47cb9c0)
+ QObject (0xb45f30b4) 0
+ primary-for QWidget (0xb45ee5a0)
+ QPaintDevice (0xb45f30f0) 8
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 240u)
+
+Class QItemSelectionRange
+ size=8 align=4
+ base size=8 base align=4
+QItemSelectionRange (0xb45f330c) 0
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QItemSelectionModel)
+8 QItemSelectionModel::metaObject
+12 QItemSelectionModel::qt_metacast
+16 QItemSelectionModel::qt_metacall
+20 QItemSelectionModel::~QItemSelectionModel
+24 QItemSelectionModel::~QItemSelectionModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QItemSelectionModel::select
+60 QItemSelectionModel::select
+64 QItemSelectionModel::clear
+68 QItemSelectionModel::reset
+
+Class QItemSelectionModel
+ size=8 align=4
+ base size=8 base align=4
+QItemSelectionModel (0xb461a740) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 8u)
+ QObject (0xb463f384) 0
+ primary-for QItemSelectionModel (0xb461a740)
+
+Class QItemSelection
+ size=4 align=4
+ base size=4 base align=4
+QItemSelection (0xb461ac00) 0
+ QList<QItemSelectionRange> (0xb463f744) 0
+
+Vtable for QValidator
+QValidator::_ZTV10QValidator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QValidator)
+8 QValidator::metaObject
+12 QValidator::qt_metacast
+16 QValidator::qt_metacall
+20 QValidator::~QValidator
+24 QValidator::~QValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 QValidator::fixup
+
+Class QValidator
+ size=8 align=4
+ base size=8 base align=4
+QValidator (0xb461ad80) 0
+ vptr=((& QValidator::_ZTV10QValidator) + 8u)
+ QObject (0xb463f8e8) 0
+ primary-for QValidator (0xb461ad80)
+
+Vtable for QIntValidator
+QIntValidator::_ZTV13QIntValidator: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QIntValidator)
+8 QIntValidator::metaObject
+12 QIntValidator::qt_metacast
+16 QIntValidator::qt_metacall
+20 QIntValidator::~QIntValidator
+24 QIntValidator::~QIntValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIntValidator::validate
+60 QValidator::fixup
+64 QIntValidator::setRange
+
+Class QIntValidator
+ size=16 align=4
+ base size=16 base align=4
+QIntValidator (0xb4690040) 0
+ vptr=((& QIntValidator::_ZTV13QIntValidator) + 8u)
+ QValidator (0xb4690080) 0
+ primary-for QIntValidator (0xb4690040)
+ QObject (0xb463fb04) 0
+ primary-for QValidator (0xb4690080)
+
+Vtable for QDoubleValidator
+QDoubleValidator::_ZTV16QDoubleValidator: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QDoubleValidator)
+8 QDoubleValidator::metaObject
+12 QDoubleValidator::qt_metacast
+16 QDoubleValidator::qt_metacall
+20 QDoubleValidator::~QDoubleValidator
+24 QDoubleValidator::~QDoubleValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDoubleValidator::validate
+60 QValidator::fixup
+64 QDoubleValidator::setRange
+
+Class QDoubleValidator
+ size=28 align=4
+ base size=28 base align=4
+QDoubleValidator (0xb4690340) 0
+ vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 8u)
+ QValidator (0xb4690380) 0
+ primary-for QDoubleValidator (0xb4690340)
+ QObject (0xb463fca8) 0
+ primary-for QValidator (0xb4690380)
+
+Vtable for QRegExpValidator
+QRegExpValidator::_ZTV16QRegExpValidator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QRegExpValidator)
+8 QRegExpValidator::metaObject
+12 QRegExpValidator::qt_metacast
+16 QRegExpValidator::qt_metacall
+20 QRegExpValidator::~QRegExpValidator
+24 QRegExpValidator::~QRegExpValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QRegExpValidator::validate
+60 QValidator::fixup
+
+Class QRegExpValidator
+ size=12 align=4
+ base size=12 base align=4
+QRegExpValidator (0xb4690700) 0
+ vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 8u)
+ QValidator (0xb4690740) 0
+ primary-for QRegExpValidator (0xb4690700)
+ QObject (0xb463ff78) 0
+ primary-for QValidator (0xb4690740)
+
+Vtable for QAbstractSpinBox
+QAbstractSpinBox::_ZTV16QAbstractSpinBox: 68u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+8 QAbstractSpinBox::metaObject
+12 QAbstractSpinBox::qt_metacast
+16 QAbstractSpinBox::qt_metacall
+20 QAbstractSpinBox::~QAbstractSpinBox
+24 QAbstractSpinBox::~QAbstractSpinBox
+28 QAbstractSpinBox::event
+32 QObject::eventFilter
+36 QAbstractSpinBox::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractSpinBox::sizeHint
+68 QAbstractSpinBox::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractSpinBox::mousePressEvent
+84 QAbstractSpinBox::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QAbstractSpinBox::mouseMoveEvent
+96 QAbstractSpinBox::wheelEvent
+100 QAbstractSpinBox::keyPressEvent
+104 QAbstractSpinBox::keyReleaseEvent
+108 QAbstractSpinBox::focusInEvent
+112 QAbstractSpinBox::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractSpinBox::paintEvent
+128 QWidget::moveEvent
+132 QAbstractSpinBox::resizeEvent
+136 QAbstractSpinBox::closeEvent
+140 QAbstractSpinBox::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QAbstractSpinBox::showEvent
+172 QAbstractSpinBox::hideEvent
+176 QWidget::x11Event
+180 QAbstractSpinBox::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QAbstractSpinBox::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSpinBox::validate
+228 QAbstractSpinBox::fixup
+232 QAbstractSpinBox::stepBy
+236 QAbstractSpinBox::clear
+240 QAbstractSpinBox::stepEnabled
+244 (int (*)(...))-0x000000008
+248 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+252 QAbstractSpinBox::_ZThn8_N16QAbstractSpinBoxD1Ev
+256 QAbstractSpinBox::_ZThn8_N16QAbstractSpinBoxD0Ev
+260 QWidget::_ZThn8_NK7QWidget7devTypeEv
+264 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+268 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSpinBox
+ size=20 align=4
+ base size=20 base align=4
+QAbstractSpinBox (0xb46909c0) 0
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 8u)
+ QWidget (0xb46ba370) 0
+ primary-for QAbstractSpinBox (0xb46909c0)
+ QObject (0xb46b90f0) 0
+ primary-for QWidget (0xb46ba370)
+ QPaintDevice (0xb46b912c) 8
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 252u)
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb46b9438) 0
+
+Vtable for QAbstractSlider
+QAbstractSlider::_ZTV15QAbstractSlider: 64u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QAbstractSlider)
+8 QAbstractSlider::metaObject
+12 QAbstractSlider::qt_metacast
+16 QAbstractSlider::qt_metacall
+20 QAbstractSlider::~QAbstractSlider
+24 QAbstractSlider::~QAbstractSlider
+28 QAbstractSlider::event
+32 QObject::eventFilter
+36 QAbstractSlider::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QAbstractSlider::wheelEvent
+100 QAbstractSlider::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QAbstractSlider::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSlider::sliderChange
+228 (int (*)(...))-0x000000008
+232 (int (*)(...))(& _ZTI15QAbstractSlider)
+236 QAbstractSlider::_ZThn8_N15QAbstractSliderD1Ev
+240 QAbstractSlider::_ZThn8_N15QAbstractSliderD0Ev
+244 QWidget::_ZThn8_NK7QWidget7devTypeEv
+248 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+252 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSlider
+ size=20 align=4
+ base size=20 base align=4
+QAbstractSlider (0xb45041c0) 0
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 8u)
+ QWidget (0xb4503be0) 0
+ primary-for QAbstractSlider (0xb45041c0)
+ QObject (0xb46b9690) 0
+ primary-for QWidget (0xb4503be0)
+ QPaintDevice (0xb46b96cc) 8
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 236u)
+
+Vtable for QSlider
+QSlider::_ZTV7QSlider: 64u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QSlider)
+8 QSlider::metaObject
+12 QSlider::qt_metacast
+16 QSlider::qt_metacall
+20 QSlider::~QSlider
+24 QSlider::~QSlider
+28 QSlider::event
+32 QObject::eventFilter
+36 QAbstractSlider::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QSlider::sizeHint
+68 QSlider::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QSlider::mousePressEvent
+84 QSlider::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QSlider::mouseMoveEvent
+96 QAbstractSlider::wheelEvent
+100 QAbstractSlider::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QSlider::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QAbstractSlider::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSlider::sliderChange
+228 (int (*)(...))-0x000000008
+232 (int (*)(...))(& _ZTI7QSlider)
+236 QSlider::_ZThn8_N7QSliderD1Ev
+240 QSlider::_ZThn8_N7QSliderD0Ev
+244 QWidget::_ZThn8_NK7QWidget7devTypeEv
+248 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+252 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QSlider
+ size=20 align=4
+ base size=20 base align=4
+QSlider (0xb4504740) 0
+ vptr=((& QSlider::_ZTV7QSlider) + 8u)
+ QAbstractSlider (0xb4504780) 0
+ primary-for QSlider (0xb4504740)
+ QWidget (0xb4521820) 0
+ primary-for QAbstractSlider (0xb4504780)
+ QObject (0xb46b999c) 0
+ primary-for QWidget (0xb4521820)
+ QPaintDevice (0xb46b99d8) 8
+ vptr=((& QSlider::_ZTV7QSlider) + 236u)
+
+Vtable for QStyle
+QStyle::_ZTV6QStyle: 35u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QStyle)
+8 QStyle::metaObject
+12 QStyle::qt_metacast
+16 QStyle::qt_metacall
+20 QStyle::~QStyle
+24 QStyle::~QStyle
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QStyle::polish
+60 QStyle::unpolish
+64 QStyle::polish
+68 QStyle::unpolish
+72 QStyle::polish
+76 QStyle::itemTextRect
+80 QStyle::itemPixmapRect
+84 QStyle::drawItemText
+88 QStyle::drawItemPixmap
+92 QStyle::standardPalette
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+120 __cxa_pure_virtual
+124 __cxa_pure_virtual
+128 __cxa_pure_virtual
+132 __cxa_pure_virtual
+136 __cxa_pure_virtual
+
+Class QStyle
+ size=8 align=4
+ base size=8 base align=4
+QStyle (0xb4504b40) 0
+ vptr=((& QStyle::_ZTV6QStyle) + 8u)
+ QObject (0xb46b9ca8) 0
+ primary-for QStyle (0xb4504b40)
+
+Vtable for QTabBar
+QTabBar::_ZTV7QTabBar: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QTabBar)
+8 QTabBar::metaObject
+12 QTabBar::qt_metacast
+16 QTabBar::qt_metacall
+20 QTabBar::~QTabBar
+24 QTabBar::~QTabBar
+28 QTabBar::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QTabBar::sizeHint
+68 QTabBar::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTabBar::mousePressEvent
+84 QTabBar::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QTabBar::mouseMoveEvent
+96 QTabBar::wheelEvent
+100 QTabBar::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTabBar::paintEvent
+128 QWidget::moveEvent
+132 QTabBar::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QTabBar::showEvent
+172 QTabBar::hideEvent
+176 QWidget::x11Event
+180 QTabBar::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTabBar::tabSizeHint
+228 QTabBar::tabInserted
+232 QTabBar::tabRemoved
+236 QTabBar::tabLayoutChange
+240 (int (*)(...))-0x000000008
+244 (int (*)(...))(& _ZTI7QTabBar)
+248 QTabBar::_ZThn8_N7QTabBarD1Ev
+252 QTabBar::_ZThn8_N7QTabBarD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabBar
+ size=20 align=4
+ base size=20 base align=4
+QTabBar (0xb459b0c0) 0
+ vptr=((& QTabBar::_ZTV7QTabBar) + 8u)
+ QWidget (0xb458ec30) 0
+ primary-for QTabBar (0xb459b0c0)
+ QObject (0xb459a0b4) 0
+ primary-for QWidget (0xb458ec30)
+ QPaintDevice (0xb459a0f0) 8
+ vptr=((& QTabBar::_ZTV7QTabBar) + 248u)
+
+Vtable for QTabWidget
+QTabWidget::_ZTV10QTabWidget: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTabWidget)
+8 QTabWidget::metaObject
+12 QTabWidget::qt_metacast
+16 QTabWidget::qt_metacall
+20 QTabWidget::~QTabWidget
+24 QTabWidget::~QTabWidget
+28 QTabWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QTabWidget::sizeHint
+68 QTabWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QTabWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTabWidget::paintEvent
+128 QWidget::moveEvent
+132 QTabWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QTabWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QTabWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTabWidget::tabInserted
+228 QTabWidget::tabRemoved
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI10QTabWidget)
+240 QTabWidget::_ZThn8_N10QTabWidgetD1Ev
+244 QTabWidget::_ZThn8_N10QTabWidgetD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabWidget
+ size=20 align=4
+ base size=20 base align=4
+QTabWidget (0xb459b3c0) 0
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 8u)
+ QWidget (0xb45c0370) 0
+ primary-for QTabWidget (0xb459b3c0)
+ QObject (0xb459a30c) 0
+ primary-for QWidget (0xb45c0370)
+ QPaintDevice (0xb459a348) 8
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 240u)
+
+Vtable for QRubberBand
+QRubberBand::_ZTV11QRubberBand: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QRubberBand)
+8 QRubberBand::metaObject
+12 QRubberBand::qt_metacast
+16 QRubberBand::qt_metacall
+20 QRubberBand::~QRubberBand
+24 QRubberBand::~QRubberBand
+28 QRubberBand::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QRubberBand::paintEvent
+128 QRubberBand::moveEvent
+132 QRubberBand::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QRubberBand::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QRubberBand::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI11QRubberBand)
+232 QRubberBand::_ZThn8_N11QRubberBandD1Ev
+236 QRubberBand::_ZThn8_N11QRubberBandD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QRubberBand
+ size=20 align=4
+ base size=20 base align=4
+QRubberBand (0xb459bc00) 0
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 8u)
+ QWidget (0xb43d46e0) 0
+ primary-for QRubberBand (0xb459bc00)
+ QObject (0xb459a870) 0
+ primary-for QWidget (0xb43d46e0)
+ QPaintDevice (0xb459a8ac) 8
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 232u)
+
+Class QStyleOption
+ size=44 align=4
+ base size=44 base align=4
+QStyleOption (0xb459ace4) 0
+
+Class QStyleOptionFocusRect
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionFocusRect (0xb43f1080) 0
+ QStyleOption (0xb459ad20) 0
+
+Class QStyleOptionFrame
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionFrame (0xb43f1280) 0
+ QStyleOption (0xb43fa0b4) 0
+
+Class QStyleOptionFrameV2
+ size=56 align=4
+ base size=56 base align=4
+QStyleOptionFrameV2 (0xb43f1480) 0
+ QStyleOptionFrame (0xb43f14c0) 0
+ QStyleOption (0xb43fa3fc) 0
+
+Class QStyleOptionFrameV3
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionFrameV3 (0xb43f1980) 0
+ QStyleOptionFrameV2 (0xb43f19c0) 0
+ QStyleOptionFrame (0xb43f1a00) 0
+ QStyleOption (0xb43fa924) 0
+
+Class QStyleOptionTabWidgetFrame
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabWidgetFrame (0xb43f1d40) 0
+ QStyleOption (0xb43fad20) 0
+
+Class QStyleOptionTabWidgetFrameV2
+ size=112 align=4
+ base size=112 base align=4
+QStyleOptionTabWidgetFrameV2 (0xb43f1f40) 0
+ QStyleOptionTabWidgetFrame (0xb43f1f80) 0
+ QStyleOption (0xb44343c0) 0
+
+Class QStyleOptionTabBarBase
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabBarBase (0xb443b2c0) 0
+ QStyleOption (0xb44348ac) 0
+
+Class QStyleOptionTabBarBaseV2
+ size=84 align=4
+ base size=81 base align=4
+QStyleOptionTabBarBaseV2 (0xb443b4c0) 0
+ QStyleOptionTabBarBase (0xb443b500) 0
+ QStyleOption (0xb4434d5c) 0
+
+Class QStyleOptionHeader
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionHeader (0xb443b840) 0
+ QStyleOption (0xb444c0f0) 0
+
+Class QStyleOptionButton
+ size=64 align=4
+ base size=64 base align=4
+QStyleOptionButton (0xb443bb00) 0
+ QStyleOption (0xb444cbb8) 0
+
+Class QStyleOptionTab
+ size=72 align=4
+ base size=72 base align=4
+QStyleOptionTab (0xb443be80) 0
+ QStyleOption (0xb446b4ec) 0
+
+Class QStyleOptionTabV2
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabV2 (0xb448e240) 0
+ QStyleOptionTab (0xb448e280) 0
+ QStyleOption (0xb446bf00) 0
+
+Class QStyleOptionTabV3
+ size=100 align=4
+ base size=100 base align=4
+QStyleOptionTabV3 (0xb448e5c0) 0
+ QStyleOptionTabV2 (0xb448e600) 0
+ QStyleOptionTab (0xb448e640) 0
+ QStyleOption (0xb44b1474) 0
+
+Class QStyleOptionToolBar
+ size=68 align=4
+ base size=68 base align=4
+QStyleOptionToolBar (0xb448ea40) 0
+ QStyleOption (0xb44b1d5c) 0
+
+Class QStyleOptionProgressBar
+ size=68 align=4
+ base size=65 base align=4
+QStyleOptionProgressBar (0xb448edc0) 0
+ QStyleOption (0xb42ce438) 0
+
+Class QStyleOptionProgressBarV2
+ size=76 align=4
+ base size=74 base align=4
+QStyleOptionProgressBarV2 (0xb42ef000) 0
+ QStyleOptionProgressBar (0xb42ef040) 0
+ QStyleOption (0xb42ceb7c) 0
+
+Class QStyleOptionMenuItem
+ size=96 align=4
+ base size=96 base align=4
+QStyleOptionMenuItem (0xb42ef0c0) 0
+ QStyleOption (0xb42cebb8) 0
+
+Class QStyleOptionQ3ListViewItem
+ size=64 align=4
+ base size=64 base align=4
+QStyleOptionQ3ListViewItem (0xb42ef2c0) 0
+ QStyleOption (0xb42fc780) 0
+
+Class QStyleOptionQ3DockWindow
+ size=48 align=4
+ base size=46 base align=4
+QStyleOptionQ3DockWindow (0xb42ef640) 0
+ QStyleOption (0xb42fcdd4) 0
+
+Class QStyleOptionDockWidget
+ size=52 align=4
+ base size=51 base align=4
+QStyleOptionDockWidget (0xb42ef840) 0
+ QStyleOption (0xb432a12c) 0
+
+Class QStyleOptionDockWidgetV2
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionDockWidgetV2 (0xb42efa40) 0
+ QStyleOptionDockWidget (0xb42efa80) 0
+ QStyleOption (0xb432a6cc) 0
+
+Class QStyleOptionViewItem
+ size=80 align=4
+ base size=77 base align=4
+QStyleOptionViewItem (0xb42efdc0) 0
+ QStyleOption (0xb432ab04) 0
+
+Class QStyleOptionViewItemV2
+ size=84 align=4
+ base size=84 base align=4
+QStyleOptionViewItemV2 (0xb4346040) 0
+ QStyleOptionViewItem (0xb4346080) 0
+ QStyleOption (0xb43443fc) 0
+
+Class QStyleOptionViewItemV3
+ size=92 align=4
+ base size=92 base align=4
+QStyleOptionViewItemV3 (0xb4346540) 0
+ QStyleOptionViewItemV2 (0xb4346580) 0
+ QStyleOptionViewItem (0xb43465c0) 0
+ QStyleOption (0xb4344a14) 0
+
+Class QStyleOptionViewItemV4
+ size=128 align=4
+ base size=128 base align=4
+QStyleOptionViewItemV4 (0xb4346900) 0
+ QStyleOptionViewItemV3 (0xb4346940) 0
+ QStyleOptionViewItemV2 (0xb4346980) 0
+ QStyleOptionViewItem (0xb43469c0) 0
+ QStyleOption (0xb4344ec4) 0
+
+Class QStyleOptionToolBox
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionToolBox (0xb4346d00) 0
+ QStyleOption (0xb4380a14) 0
+
+Class QStyleOptionToolBoxV2
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionToolBoxV2 (0xb4346f00) 0
+ QStyleOptionToolBox (0xb4346f40) 0
+ QStyleOption (0xb438d03c) 0
+
+Class QStyleOptionRubberBand
+ size=52 align=4
+ base size=49 base align=4
+QStyleOptionRubberBand (0xb4394280) 0
+ QStyleOption (0xb438d5a0) 0
+
+Class QStyleOptionComplex
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionComplex (0xb4394480) 0
+ QStyleOption (0xb438d8e8) 0
+
+Class QStyleOptionSlider
+ size=104 align=4
+ base size=101 base align=4
+QStyleOptionSlider (0xb4394700) 0
+ QStyleOptionComplex (0xb4394740) 0
+ QStyleOption (0xb438dd98) 0
+
+Class QStyleOptionSpinBox
+ size=64 align=4
+ base size=61 base align=4
+QStyleOptionSpinBox (0xb4394a80) 0
+ QStyleOptionComplex (0xb4394ac0) 0
+ QStyleOption (0xb43ad654) 0
+
+Class QStyleOptionQ3ListView
+ size=84 align=4
+ base size=81 base align=4
+QStyleOptionQ3ListView (0xb4394d00) 0
+ QStyleOptionComplex (0xb4394d40) 0
+ QStyleOption (0xb43adac8) 0
+
+Class QStyleOptionToolButton
+ size=96 align=4
+ base size=96 base align=4
+QStyleOptionToolButton (0xb41d5000) 0
+ QStyleOptionComplex (0xb41d5040) 0
+ QStyleOption (0xb41d13fc) 0
+
+Class QStyleOptionComboBox
+ size=92 align=4
+ base size=92 base align=4
+QStyleOptionComboBox (0xb41d53c0) 0
+ QStyleOptionComplex (0xb41d5400) 0
+ QStyleOption (0xb41e70f0) 0
+
+Class QStyleOptionTitleBar
+ size=68 align=4
+ base size=68 base align=4
+QStyleOptionTitleBar (0xb41d5600) 0
+ QStyleOptionComplex (0xb41d5640) 0
+ QStyleOption (0xb41e79d8) 0
+
+Class QStyleOptionGroupBox
+ size=88 align=4
+ base size=88 base align=4
+QStyleOptionGroupBox (0xb41d5880) 0
+ QStyleOptionComplex (0xb41d58c0) 0
+ QStyleOption (0xb42101a4) 0
+
+Class QStyleOptionSizeGrip
+ size=56 align=4
+ base size=56 base align=4
+QStyleOptionSizeGrip (0xb41d5b40) 0
+ QStyleOptionComplex (0xb41d5b80) 0
+ QStyleOption (0xb4210a50) 0
+
+Class QStyleOptionGraphicsItem
+ size=132 align=4
+ base size=132 base align=4
+QStyleOptionGraphicsItem (0xb41d5d80) 0
+ QStyleOption (0xb4210d20) 0
+
+Class QStyleHintReturn
+ size=8 align=4
+ base size=8 base align=4
+QStyleHintReturn (0xb422721c) 0
+
+Class QStyleHintReturnMask
+ size=12 align=4
+ base size=12 base align=4
+QStyleHintReturnMask (0xb422c1c0) 0
+ QStyleHintReturn (0xb4227258) 0
+
+Class QStyleHintReturnVariant
+ size=20 align=4
+ base size=20 base align=4
+QStyleHintReturnVariant (0xb422c240) 0
+ QStyleHintReturn (0xb4227294) 0
+
+Vtable for QAbstractItemDelegate
+QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QAbstractItemDelegate)
+8 QAbstractItemDelegate::metaObject
+12 QAbstractItemDelegate::qt_metacast
+16 QAbstractItemDelegate::qt_metacall
+20 QAbstractItemDelegate::~QAbstractItemDelegate
+24 QAbstractItemDelegate::~QAbstractItemDelegate
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractItemDelegate::createEditor
+68 QAbstractItemDelegate::setEditorData
+72 QAbstractItemDelegate::setModelData
+76 QAbstractItemDelegate::updateEditorGeometry
+80 QAbstractItemDelegate::editorEvent
+
+Class QAbstractItemDelegate
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemDelegate (0xb422c4c0) 0
+ vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 8u)
+ QObject (0xb42272d0) 0
+ primary-for QAbstractItemDelegate (0xb422c4c0)
+
+Vtable for QAbstractItemView
+QAbstractItemView::_ZTV17QAbstractItemView: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QAbstractItemView)
+8 QAbstractItemView::metaObject
+12 QAbstractItemView::qt_metacast
+16 QAbstractItemView::qt_metacall
+20 QAbstractItemView::~QAbstractItemView
+24 QAbstractItemView::~QAbstractItemView
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QAbstractItemView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QAbstractItemView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QAbstractItemView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractScrollArea::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QAbstractItemView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QAbstractScrollArea::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QAbstractItemView::reset
+268 QAbstractItemView::setRootIndex
+272 QAbstractItemView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QAbstractItemView::dataChanged
+284 QAbstractItemView::rowsInserted
+288 QAbstractItemView::rowsAboutToBeRemoved
+292 QAbstractItemView::selectionChanged
+296 QAbstractItemView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QAbstractItemView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 QAbstractItemView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI17QAbstractItemView)
+392 QAbstractItemView::_ZThn8_N17QAbstractItemViewD1Ev
+396 QAbstractItemView::_ZThn8_N17QAbstractItemViewD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractItemView
+ size=20 align=4
+ base size=20 base align=4
+QAbstractItemView (0xb422c700) 0
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 8u)
+ QAbstractScrollArea (0xb422c740) 0
+ primary-for QAbstractItemView (0xb422c700)
+ QFrame (0xb422c780) 0
+ primary-for QAbstractScrollArea (0xb422c740)
+ QWidget (0xb424ca00) 0
+ primary-for QFrame (0xb422c780)
+ QObject (0xb42273fc) 0
+ primary-for QWidget (0xb424ca00)
+ QPaintDevice (0xb4227438) 8
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 392u)
+
+Vtable for QTreeView
+QTreeView::_ZTV9QTreeView: 105u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTreeView)
+8 QTreeView::metaObject
+12 QTreeView::qt_metacast
+16 QTreeView::qt_metacall
+20 QTreeView::~QTreeView
+24 QTreeView::~QTreeView
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QTreeView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTreeView::mousePressEvent
+84 QTreeView::mouseReleaseEvent
+88 QTreeView::mouseDoubleClickEvent
+92 QTreeView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QTreeView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTreeView::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QTreeView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTreeView::viewportEvent
+228 QTreeView::scrollContentsBy
+232 QTreeView::setModel
+236 QTreeView::setSelectionModel
+240 QTreeView::keyboardSearch
+244 QTreeView::visualRect
+248 QTreeView::scrollTo
+252 QTreeView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QTreeView::sizeHintForColumn
+264 QTreeView::reset
+268 QTreeView::setRootIndex
+272 QTreeView::doItemsLayout
+276 QTreeView::selectAll
+280 QTreeView::dataChanged
+284 QTreeView::rowsInserted
+288 QTreeView::rowsAboutToBeRemoved
+292 QTreeView::selectionChanged
+296 QTreeView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QTreeView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QTreeView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QTreeView::moveCursor
+344 QTreeView::horizontalOffset
+348 QTreeView::verticalOffset
+352 QTreeView::isIndexHidden
+356 QTreeView::setSelection
+360 QTreeView::visualRegionForSelection
+364 QTreeView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 QTreeView::drawRow
+388 QTreeView::drawBranches
+392 (int (*)(...))-0x000000008
+396 (int (*)(...))(& _ZTI9QTreeView)
+400 QTreeView::_ZThn8_N9QTreeViewD1Ev
+404 QTreeView::_ZThn8_N9QTreeViewD0Ev
+408 QWidget::_ZThn8_NK7QWidget7devTypeEv
+412 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+416 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTreeView
+ size=20 align=4
+ base size=20 base align=4
+QTreeView (0xb422cbc0) 0
+ vptr=((& QTreeView::_ZTV9QTreeView) + 8u)
+ QAbstractItemView (0xb422cc00) 0
+ primary-for QTreeView (0xb422cbc0)
+ QAbstractScrollArea (0xb422cc40) 0
+ primary-for QAbstractItemView (0xb422cc00)
+ QFrame (0xb422cc80) 0
+ primary-for QAbstractScrollArea (0xb422cc40)
+ QWidget (0xb429a2d0) 0
+ primary-for QFrame (0xb422cc80)
+ QObject (0xb4227744) 0
+ primary-for QWidget (0xb429a2d0)
+ QPaintDevice (0xb4227780) 8
+ vptr=((& QTreeView::_ZTV9QTreeView) + 400u)
+
+Class QHelpContentItem
+ size=4 align=4
+ base size=4 base align=4
+QHelpContentItem (0xb422799c) 0
+
+Vtable for QHelpContentModel
+QHelpContentModel::_ZTV17QHelpContentModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QHelpContentModel)
+8 QHelpContentModel::metaObject
+12 QHelpContentModel::qt_metacast
+16 QHelpContentModel::qt_metacall
+20 QHelpContentModel::~QHelpContentModel
+24 QHelpContentModel::~QHelpContentModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QHelpContentModel::index
+60 QHelpContentModel::parent
+64 QHelpContentModel::rowCount
+68 QHelpContentModel::columnCount
+72 QAbstractItemModel::hasChildren
+76 QHelpContentModel::data
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QHelpContentModel
+ size=12 align=4
+ base size=12 base align=4
+QHelpContentModel (0xb422cf80) 0
+ vptr=((& QHelpContentModel::_ZTV17QHelpContentModel) + 8u)
+ QAbstractItemModel (0xb422cfc0) 0
+ primary-for QHelpContentModel (0xb422cf80)
+ QObject (0xb42279d8) 0
+ primary-for QAbstractItemModel (0xb422cfc0)
+
+Vtable for QHelpContentWidget
+QHelpContentWidget::_ZTV18QHelpContentWidget: 105u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QHelpContentWidget)
+8 QHelpContentWidget::metaObject
+12 QHelpContentWidget::qt_metacast
+16 QHelpContentWidget::qt_metacall
+20 QHelpContentWidget::~QHelpContentWidget
+24 QHelpContentWidget::~QHelpContentWidget
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QTreeView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTreeView::mousePressEvent
+84 QTreeView::mouseReleaseEvent
+88 QTreeView::mouseDoubleClickEvent
+92 QTreeView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QTreeView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTreeView::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QTreeView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTreeView::viewportEvent
+228 QTreeView::scrollContentsBy
+232 QTreeView::setModel
+236 QTreeView::setSelectionModel
+240 QTreeView::keyboardSearch
+244 QTreeView::visualRect
+248 QTreeView::scrollTo
+252 QTreeView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QTreeView::sizeHintForColumn
+264 QTreeView::reset
+268 QTreeView::setRootIndex
+272 QTreeView::doItemsLayout
+276 QTreeView::selectAll
+280 QTreeView::dataChanged
+284 QTreeView::rowsInserted
+288 QTreeView::rowsAboutToBeRemoved
+292 QTreeView::selectionChanged
+296 QTreeView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QTreeView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QTreeView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QTreeView::moveCursor
+344 QTreeView::horizontalOffset
+348 QTreeView::verticalOffset
+352 QTreeView::isIndexHidden
+356 QTreeView::setSelection
+360 QTreeView::visualRegionForSelection
+364 QTreeView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 QTreeView::drawRow
+388 QTreeView::drawBranches
+392 (int (*)(...))-0x000000008
+396 (int (*)(...))(& _ZTI18QHelpContentWidget)
+400 QHelpContentWidget::_ZThn8_N18QHelpContentWidgetD1Ev
+404 QHelpContentWidget::_ZThn8_N18QHelpContentWidgetD0Ev
+408 QWidget::_ZThn8_NK7QWidget7devTypeEv
+412 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+416 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpContentWidget
+ size=36 align=4
+ base size=36 base align=4
+QHelpContentWidget (0xb40be200) 0
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 8u)
+ QTreeView (0xb40be240) 0
+ primary-for QHelpContentWidget (0xb40be200)
+ QAbstractItemView (0xb40be280) 0
+ primary-for QTreeView (0xb40be240)
+ QAbstractScrollArea (0xb40be2c0) 0
+ primary-for QAbstractItemView (0xb40be280)
+ QFrame (0xb40be300) 0
+ primary-for QAbstractScrollArea (0xb40be2c0)
+ QWidget (0xb40c1be0) 0
+ primary-for QFrame (0xb40be300)
+ QObject (0xb4227b04) 0
+ primary-for QWidget (0xb40c1be0)
+ QPaintDevice (0xb4227b40) 8
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 400u)
+
+Vtable for QHelpEngineCore
+QHelpEngineCore::_ZTV15QHelpEngineCore: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QHelpEngineCore)
+8 QHelpEngineCore::metaObject
+12 QHelpEngineCore::qt_metacast
+16 QHelpEngineCore::qt_metacall
+20 QHelpEngineCore::~QHelpEngineCore
+24 QHelpEngineCore::~QHelpEngineCore
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpEngineCore
+ size=12 align=4
+ base size=12 base align=4
+QHelpEngineCore (0xb40be540) 0
+ vptr=((& QHelpEngineCore::_ZTV15QHelpEngineCore) + 8u)
+ QObject (0xb4227c6c) 0
+ primary-for QHelpEngineCore (0xb40be540)
+
+Vtable for QHelpEngine
+QHelpEngine::_ZTV11QHelpEngine: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QHelpEngine)
+8 QHelpEngine::metaObject
+12 QHelpEngine::qt_metacast
+16 QHelpEngine::qt_metacall
+20 QHelpEngine::~QHelpEngine
+24 QHelpEngine::~QHelpEngine
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpEngine
+ size=16 align=4
+ base size=16 base align=4
+QHelpEngine (0xb40be780) 0
+ vptr=((& QHelpEngine::_ZTV11QHelpEngine) + 8u)
+ QHelpEngineCore (0xb40be7c0) 0
+ primary-for QHelpEngine (0xb40be780)
+ QObject (0xb4227d98) 0
+ primary-for QHelpEngineCore (0xb40be7c0)
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QStringListModel)
+8 QStringListModel::metaObject
+12 QStringListModel::qt_metacast
+16 QStringListModel::qt_metacall
+20 QStringListModel::~QStringListModel
+24 QStringListModel::~QStringListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 QStringListModel::rowCount
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 QStringListModel::data
+80 QStringListModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QStringListModel::supportedDropActions
+116 QStringListModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QStringListModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QStringListModel::flags
+144 QStringListModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QStringListModel
+ size=12 align=4
+ base size=12 base align=4
+QStringListModel (0xb40bea00) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 8u)
+ QAbstractListModel (0xb40bea40) 0
+ primary-for QStringListModel (0xb40bea00)
+ QAbstractItemModel (0xb40bea80) 0
+ primary-for QAbstractListModel (0xb40bea40)
+ QObject (0xb4227ec4) 0
+ primary-for QAbstractItemModel (0xb40bea80)
+
+Vtable for QListView
+QListView::_ZTV9QListView: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QListView)
+8 QListView::metaObject
+12 QListView::qt_metacast
+16 QListView::qt_metacall
+20 QListView::~QListView
+24 QListView::~QListView
+28 QListView::event
+32 QObject::eventFilter
+36 QListView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QListView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QListView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QListView::paintEvent
+128 QWidget::moveEvent
+132 QListView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QListView::dragMoveEvent
+160 QListView::dragLeaveEvent
+164 QListView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QListView::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 QListView::visualRect
+248 QListView::scrollTo
+252 QListView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QListView::reset
+268 QListView::setRootIndex
+272 QListView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QListView::dataChanged
+284 QListView::rowsInserted
+288 QListView::rowsAboutToBeRemoved
+292 QListView::selectionChanged
+296 QListView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QListView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QListView::moveCursor
+344 QListView::horizontalOffset
+348 QListView::verticalOffset
+352 QListView::isIndexHidden
+356 QListView::setSelection
+360 QListView::visualRegionForSelection
+364 QListView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QListView::startDrag
+380 QListView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI9QListView)
+392 QListView::_ZThn8_N9QListViewD1Ev
+396 QListView::_ZThn8_N9QListViewD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QListView
+ size=20 align=4
+ base size=20 base align=4
+QListView (0xb40becc0) 0
+ vptr=((& QListView::_ZTV9QListView) + 8u)
+ QAbstractItemView (0xb40bed00) 0
+ primary-for QListView (0xb40becc0)
+ QAbstractScrollArea (0xb40bed40) 0
+ primary-for QAbstractItemView (0xb40bed00)
+ QFrame (0xb40bed80) 0
+ primary-for QAbstractScrollArea (0xb40bed40)
+ QWidget (0xb40fb190) 0
+ primary-for QFrame (0xb40bed80)
+ QObject (0xb40fe000) 0
+ primary-for QWidget (0xb40fb190)
+ QPaintDevice (0xb40fe03c) 8
+ vptr=((& QListView::_ZTV9QListView) + 392u)
+
+Vtable for QHelpIndexModel
+QHelpIndexModel::_ZTV15QHelpIndexModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QHelpIndexModel)
+8 QHelpIndexModel::metaObject
+12 QHelpIndexModel::qt_metacast
+16 QHelpIndexModel::qt_metacall
+20 QHelpIndexModel::~QHelpIndexModel
+24 QHelpIndexModel::~QHelpIndexModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 QStringListModel::rowCount
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 QStringListModel::data
+80 QStringListModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QStringListModel::supportedDropActions
+116 QStringListModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QStringListModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QStringListModel::flags
+144 QStringListModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QHelpIndexModel
+ size=16 align=4
+ base size=16 base align=4
+QHelpIndexModel (0xb411c080) 0
+ vptr=((& QHelpIndexModel::_ZTV15QHelpIndexModel) + 8u)
+ QStringListModel (0xb411c0c0) 0
+ primary-for QHelpIndexModel (0xb411c080)
+ QAbstractListModel (0xb411c100) 0
+ primary-for QStringListModel (0xb411c0c0)
+ QAbstractItemModel (0xb411c140) 0
+ primary-for QAbstractListModel (0xb411c100)
+ QObject (0xb40fe258) 0
+ primary-for QAbstractItemModel (0xb411c140)
+
+Vtable for QHelpIndexWidget
+QHelpIndexWidget::_ZTV16QHelpIndexWidget: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+8 QHelpIndexWidget::metaObject
+12 QHelpIndexWidget::qt_metacast
+16 QHelpIndexWidget::qt_metacall
+20 QHelpIndexWidget::~QHelpIndexWidget
+24 QHelpIndexWidget::~QHelpIndexWidget
+28 QListView::event
+32 QObject::eventFilter
+36 QListView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QListView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QListView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QListView::paintEvent
+128 QWidget::moveEvent
+132 QListView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QListView::dragMoveEvent
+160 QListView::dragLeaveEvent
+164 QListView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QListView::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 QListView::visualRect
+248 QListView::scrollTo
+252 QListView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QListView::reset
+268 QListView::setRootIndex
+272 QListView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QListView::dataChanged
+284 QListView::rowsInserted
+288 QListView::rowsAboutToBeRemoved
+292 QListView::selectionChanged
+296 QListView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QListView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QListView::moveCursor
+344 QListView::horizontalOffset
+348 QListView::verticalOffset
+352 QListView::isIndexHidden
+356 QListView::setSelection
+360 QListView::visualRegionForSelection
+364 QListView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QListView::startDrag
+380 QListView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+392 QHelpIndexWidget::_ZThn8_N16QHelpIndexWidgetD1Ev
+396 QHelpIndexWidget::_ZThn8_N16QHelpIndexWidgetD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpIndexWidget
+ size=20 align=4
+ base size=20 base align=4
+QHelpIndexWidget (0xb411c380) 0
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 8u)
+ QListView (0xb411c3c0) 0
+ primary-for QHelpIndexWidget (0xb411c380)
+ QAbstractItemView (0xb411c400) 0
+ primary-for QListView (0xb411c3c0)
+ QAbstractScrollArea (0xb411c440) 0
+ primary-for QAbstractItemView (0xb411c400)
+ QFrame (0xb411c480) 0
+ primary-for QAbstractScrollArea (0xb411c440)
+ QWidget (0xb41236e0) 0
+ primary-for QFrame (0xb411c480)
+ QObject (0xb40fe384) 0
+ primary-for QWidget (0xb41236e0)
+ QPaintDevice (0xb40fe3c0) 8
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 392u)
+
+Class QHelpSearchQuery
+ size=8 align=4
+ base size=8 base align=4
+QHelpSearchQuery (0xb40fe4ec) 0
+
+Vtable for QHelpSearchEngine
+QHelpSearchEngine::_ZTV17QHelpSearchEngine: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QHelpSearchEngine)
+8 QHelpSearchEngine::metaObject
+12 QHelpSearchEngine::qt_metacast
+16 QHelpSearchEngine::qt_metacall
+20 QHelpSearchEngine::~QHelpSearchEngine
+24 QHelpSearchEngine::~QHelpSearchEngine
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpSearchEngine
+ size=12 align=4
+ base size=12 base align=4
+QHelpSearchEngine (0xb411c880) 0
+ vptr=((& QHelpSearchEngine::_ZTV17QHelpSearchEngine) + 8u)
+ QObject (0xb40fea14) 0
+ primary-for QHelpSearchEngine (0xb411c880)
+
+Vtable for QHelpSearchQueryWidget
+QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+8 QHelpSearchQueryWidget::metaObject
+12 QHelpSearchQueryWidget::qt_metacast
+16 QHelpSearchQueryWidget::qt_metacall
+20 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+24 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QHelpSearchQueryWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QHelpSearchQueryWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+232 QHelpSearchQueryWidget::_ZThn8_N22QHelpSearchQueryWidgetD1Ev
+236 QHelpSearchQueryWidget::_ZThn8_N22QHelpSearchQueryWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchQueryWidget
+ size=24 align=4
+ base size=24 base align=4
+QHelpSearchQueryWidget (0xb411cac0) 0
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 8u)
+ QWidget (0xb4141d70) 0
+ primary-for QHelpSearchQueryWidget (0xb411cac0)
+ QObject (0xb40feb40) 0
+ primary-for QWidget (0xb4141d70)
+ QPaintDevice (0xb40feb7c) 8
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 232u)
+
+Vtable for QHelpSearchResultWidget
+QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+8 QHelpSearchResultWidget::metaObject
+12 QHelpSearchResultWidget::qt_metacast
+16 QHelpSearchResultWidget::qt_metacall
+20 QHelpSearchResultWidget::~QHelpSearchResultWidget
+24 QHelpSearchResultWidget::~QHelpSearchResultWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QHelpSearchResultWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+232 QHelpSearchResultWidget::_ZThn8_N23QHelpSearchResultWidgetD1Ev
+236 QHelpSearchResultWidget::_ZThn8_N23QHelpSearchResultWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchResultWidget
+ size=24 align=4
+ base size=24 base align=4
+QHelpSearchResultWidget (0xb411cd00) 0
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 8u)
+ QWidget (0xb4148eb0) 0
+ primary-for QHelpSearchResultWidget (0xb411cd00)
+ QObject (0xb40feca8) 0
+ primary-for QWidget (0xb4148eb0)
+ QPaintDevice (0xb40fece4) 8
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 232u)
+
diff --git a/tests/auto/bic/data/QtHelp.4.7.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtHelp.4.7.0.linux-gcc-ia32.txt
new file mode 100644
index 000000000..8c55e2f57
--- /dev/null
+++ b/tests/auto/bic/data/QtHelp.4.7.0.linux-gcc-ia32.txt
@@ -0,0 +1,5497 @@
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0xb6e0ba8c) 0 empty
+
+Class QBool
+ size=1 align=1
+ base size=1 base align=1
+QBool (0xb6e0bc30) 0
+
+Class qIsNull(double)::U
+ size=8 align=4
+ base size=8 base align=4
+qIsNull(double)::U (0xb6dbf30c) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0xb6dbf3c0) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0xb6dbfbf4) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0xb6dbfd20) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0xb6498e88) 0 empty
+
+Class QGenericArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericArgument (0xb6498ec4) 0
+
+Class QGenericReturnArgument
+ size=8 align=4
+ base size=8 base align=4
+QGenericReturnArgument (0xb6353400) 0
+ QGenericArgument (0xb63660f0) 0
+
+Class QMetaObject
+ size=16 align=4
+ base size=16 base align=4
+QMetaObject (0xb6366294) 0
+
+Class QMetaObjectExtraData
+ size=8 align=4
+ base size=8 base align=4
+QMetaObjectExtraData (0xb63663c0) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0xb63665a0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0xb6366780) 0
+
+Class QBasicAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QBasicAtomicInt (0xb63b4ec4) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0xb63d4d40) 0
+ QBasicAtomicInt (0xb63c75dc) 0
+
+Class __locale_struct
+ size=116 align=4
+ base size=116 base align=4
+__locale_struct (0xb63c7ac8) 0
+
+Class QByteArray::Data
+ size=20 align=4
+ base size=20 base align=4
+QByteArray::Data (0xb63c7f3c) 0
+
+Class QByteArray
+ size=4 align=4
+ base size=4 base align=4
+QByteArray (0xb63c7f00) 0
+
+Class QByteRef
+ size=8 align=4
+ base size=8 base align=4
+QByteRef (0xb6259e4c) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0xb62a2618) 0 empty
+
+Class QString::Data
+ size=20 align=4
+ base size=20 base align=4
+QString::Data (0xb62a2654) 0
+
+Class QString
+ size=4 align=4
+ base size=4 base align=4
+QString (0xb62a25dc) 0
+
+Class QLatin1String
+ size=4 align=4
+ base size=4 base align=4
+QLatin1String (0xb616e258) 0
+
+Class QCharRef
+ size=8 align=4
+ base size=8 base align=4
+QCharRef (0xb61b2f3c) 0
+
+Class QConstString
+ size=4 align=4
+ base size=4 base align=4
+QConstString (0xb605f500) 0
+ QString (0xb6070690) 0
+
+Class QStringRef
+ size=12 align=4
+ base size=12 base align=4
+QStringRef (0xb60709d8) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9exception)
+8 std::exception::~exception
+12 std::exception::~exception
+16 std::exception::what
+
+Class std::exception
+ size=4 align=4
+ base size=4 base align=4
+std::exception (0xb60b3a8c) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 8u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt13bad_exception)
+8 std::bad_exception::~bad_exception
+12 std::bad_exception::~bad_exception
+16 std::bad_exception::what
+
+Class std::bad_exception
+ size=4 align=4
+ base size=4 base align=4
+std::bad_exception (0xb5efa100) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 8u)
+ std::exception (0xb60b3b7c) 0 nearly-empty
+ primary-for std::bad_exception (0xb5efa100)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTISt9bad_alloc)
+8 std::bad_alloc::~bad_alloc
+12 std::bad_alloc::~bad_alloc
+16 std::bad_alloc::what
+
+Class std::bad_alloc
+ size=4 align=4
+ base size=4 base align=4
+std::bad_alloc (0xb5efa280) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 8u)
+ std::exception (0xb60b3dd4) 0 nearly-empty
+ primary-for std::bad_alloc (0xb5efa280)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0xb5f0603c) 0 empty
+
+Class QListData::Data
+ size=24 align=4
+ base size=24 base align=4
+QListData::Data (0xb5f0612c) 0
+
+Class QListData
+ size=4 align=4
+ base size=4 base align=4
+QListData (0xb5f060f0) 0
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0xb5f06960) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QObjectData)
+8 __cxa_pure_virtual
+12 __cxa_pure_virtual
+
+Class QObjectData
+ size=28 align=4
+ base size=28 base align=4
+QObjectData (0xb5f06a14) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 8u)
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QObject)
+8 QObject::metaObject
+12 QObject::qt_metacast
+16 QObject::qt_metacall
+20 QObject::~QObject
+24 QObject::~QObject
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObject
+ size=8 align=4
+ base size=8 base align=4
+QObject (0xb5f06ac8) 0
+ vptr=((& QObject::_ZTV7QObject) + 8u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QObjectUserData)
+8 QObjectUserData::~QObjectUserData
+12 QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=4 align=4
+ base size=4 base align=4
+QObjectUserData (0xb5e07348) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 8u)
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QIODevice)
+8 QIODevice::metaObject
+12 QIODevice::qt_metacast
+16 QIODevice::qt_metacall
+20 QIODevice::~QIODevice
+24 QIODevice::~QIODevice
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIODevice::isSequential
+60 QIODevice::open
+64 QIODevice::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QIODevice::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 __cxa_pure_virtual
+112 QIODevice::readLineData
+116 __cxa_pure_virtual
+
+Class QIODevice
+ size=8 align=4
+ base size=8 base align=4
+QIODevice (0xb5e18000) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 8u)
+ QObject (0xb5e07474) 0
+ primary-for QIODevice (0xb5e18000)
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0xb5e451e0) 0
+
+Class timespec
+ size=8 align=4
+ base size=8 base align=4
+timespec (0xb5e453c0) 0
+
+Class timeval
+ size=8 align=4
+ base size=8 base align=4
+timeval (0xb5e453fc) 0
+
+Class __pthread_internal_slist
+ size=4 align=4
+ base size=4 base align=4
+__pthread_internal_slist (0xb5e454b0) 0
+
+Class random_data
+ size=28 align=4
+ base size=28 base align=4
+random_data (0xb5e457bc) 0
+
+Class drand48_data
+ size=24 align=4
+ base size=24 base align=4
+drand48_data (0xb5e457f8) 0
+
+Class QVectorData
+ size=16 align=4
+ base size=16 base align=4
+QVectorData (0xb5e45834) 0
+
+Class QXmlStreamStringRef
+ size=12 align=4
+ base size=12 base align=4
+QXmlStreamStringRef (0xb5e45a14) 0
+
+Class QXmlStreamAttribute
+ size=56 align=4
+ base size=53 base align=4
+QXmlStreamAttribute (0xb5d146cc) 0
+
+Class QXmlStreamAttributes
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamAttributes (0xb5d15700) 0
+ QVector<QXmlStreamAttribute> (0xb5d2f12c) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=28 align=4
+ base size=28 base align=4
+QXmlStreamNamespaceDeclaration (0xb5d2f21c) 0
+
+Class QXmlStreamNotationDeclaration
+ size=40 align=4
+ base size=40 base align=4
+QXmlStreamNotationDeclaration (0xb5d2f690) 0
+
+Class QXmlStreamEntityDeclaration
+ size=64 align=4
+ base size=64 base align=4
+QXmlStreamEntityDeclaration (0xb5d2fc6c) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+8 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+12 QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+16 QXmlStreamEntityResolver::resolveEntity
+20 QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamEntityResolver (0xb5d6f528) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 8u)
+
+Class QXmlStreamReader
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamReader (0xb5d6f564) 0
+
+Class QXmlStreamWriter
+ size=4 align=4
+ base size=4 base align=4
+QXmlStreamWriter (0xb5d6f6cc) 0
+
+Class QBitArray
+ size=4 align=4
+ base size=4 base align=4
+QBitArray (0xb5d6f834) 0
+
+Class QBitRef
+ size=8 align=4
+ base size=8 base align=4
+QBitRef (0xb5dbace4) 0
+
+Class QByteArrayMatcher::Data
+ size=264 align=4
+ base size=264 base align=4
+QByteArrayMatcher::Data (0xb5bdc30c) 0
+
+Class QByteArrayMatcher
+ size=1032 align=4
+ base size=1032 base align=4
+QByteArrayMatcher (0xb5bdc2d0) 0
+
+Vtable for QDataStream
+QDataStream::_ZTV11QDataStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QDataStream)
+8 QDataStream::~QDataStream
+12 QDataStream::~QDataStream
+
+Class QDataStream
+ size=28 align=4
+ base size=28 base align=4
+QDataStream (0xb5bdc564) 0
+ vptr=((& QDataStream::_ZTV11QDataStream) + 8u)
+
+Class QHashData::Node
+ size=8 align=4
+ base size=8 base align=4
+QHashData::Node (0xb5c3912c) 0
+
+Class QHashData
+ size=32 align=4
+ base size=32 base align=4
+QHashData (0xb5c390f0) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0xb5c39834) 0 empty
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0xb5c39fb4) 0
+
+Class QCryptographicHash
+ size=4 align=4
+ base size=4 base align=4
+QCryptographicHash (0xb5af9168) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0xb5af91a4) 0
+
+Vtable for QtSharedPointer::ExternalRefCountData
+QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer20ExternalRefCountDataE)
+8 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+12 QtSharedPointer::ExternalRefCountData::~ExternalRefCountData
+16 QtSharedPointer::ExternalRefCountData::destroy
+
+Class QtSharedPointer::ExternalRefCountData
+ size=12 align=4
+ base size=12 base align=4
+QtSharedPointer::ExternalRefCountData (0xb5af9528) 0
+ vptr=((& QtSharedPointer::ExternalRefCountData::_ZTVN15QtSharedPointer20ExternalRefCountDataE) + 8u)
+
+Vtable for QtSharedPointer::ExternalRefCountWithDestroyFn
+QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN15QtSharedPointer29ExternalRefCountWithDestroyFnE)
+8 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+12 QtSharedPointer::ExternalRefCountWithDestroyFn::~ExternalRefCountWithDestroyFn
+16 QtSharedPointer::ExternalRefCountWithDestroyFn::destroy
+
+Class QtSharedPointer::ExternalRefCountWithDestroyFn
+ size=16 align=4
+ base size=16 base align=4
+QtSharedPointer::ExternalRefCountWithDestroyFn (0xb5b76280) 0
+ vptr=((& QtSharedPointer::ExternalRefCountWithDestroyFn::_ZTVN15QtSharedPointer29ExternalRefCountWithDestroyFnE) + 8u)
+ QtSharedPointer::ExternalRefCountData (0xb5af9d20) 0
+ primary-for QtSharedPointer::ExternalRefCountWithDestroyFn (0xb5b76280)
+
+Class QDate
+ size=4 align=4
+ base size=4 base align=4
+QDate (0xb5b7d258) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0xb5b7d870) 0
+
+Class QDateTime
+ size=4 align=4
+ base size=4 base align=4
+QDateTime (0xb5b7ddd4) 0
+
+Class QEasingCurve
+ size=4 align=4
+ base size=4 base align=4
+QEasingCurve (0xb5a0b0b4) 0
+
+Class QElapsedTimer
+ size=16 align=4
+ base size=16 base align=4
+QElapsedTimer (0xb5a0b12c) 0
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0xb5a0b348) 0
+
+Class QPointF
+ size=16 align=4
+ base size=16 base align=4
+QPointF (0xb5a398e8) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0xb5a60000) 0
+
+Class QLineF
+ size=32 align=4
+ base size=32 base align=4
+QLineF (0xb5a60d20) 0
+
+Class QLinkedListData
+ size=20 align=4
+ base size=20 base align=4
+QLinkedListData (0xb5a90e10) 0
+
+Vtable for QSystemLocale
+QSystemLocale::_ZTV13QSystemLocale: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSystemLocale)
+8 QSystemLocale::~QSystemLocale
+12 QSystemLocale::~QSystemLocale
+16 QSystemLocale::query
+20 QSystemLocale::fallbackLocale
+
+Class QSystemLocale
+ size=4 align=4
+ base size=4 base align=4
+QSystemLocale (0xb590c03c) 0 nearly-empty
+ vptr=((& QSystemLocale::_ZTV13QSystemLocale) + 8u)
+
+Class QLocale::Data
+ size=4 align=2
+ base size=4 base align=2
+QLocale::Data (0xb590c0b4) 0
+
+Class QLocale
+ size=4 align=4
+ base size=4 base align=4
+QLocale (0xb590c078) 0
+
+Class QMapData::Node
+ size=8 align=4
+ base size=8 base align=4
+QMapData::Node (0xb590c708) 0
+
+Class QMapData
+ size=72 align=4
+ base size=72 base align=4
+QMapData (0xb590c6cc) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0xb590ca14) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0xb5816b7c) 0
+
+Class QSizeF
+ size=16 align=4
+ base size=16 base align=4
+QSizeF (0xb5841618) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0xb586921c) 0
+
+Class QRectF
+ size=32 align=4
+ base size=32 base align=4
+QRectF (0xb58b9e4c) 0
+
+Class QRegExp
+ size=4 align=4
+ base size=4 base align=4
+QRegExp (0xb5717bb8) 0
+
+Class QLatin1Literal
+ size=8 align=4
+ base size=8 base align=4
+QLatin1Literal (0xb573c708) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0xb573c7bc) 0 empty
+
+Class QStringMatcher::Data
+ size=264 align=4
+ base size=264 base align=4
+QStringMatcher::Data (0xb579cd98) 0
+
+Class QStringMatcher
+ size=1036 align=4
+ base size=1036 base align=4
+QStringMatcher (0xb579cd5c) 0
+
+Class QStringList
+ size=4 align=4
+ base size=4 base align=4
+QStringList (0xb57ba1c0) 0
+ QList<QString> (0xb579cec4) 0
+
+Class QTextBoundaryFinder
+ size=28 align=4
+ base size=28 base align=4
+QTextBoundaryFinder (0xb560d438) 0
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTimeLine)
+8 QTimeLine::metaObject
+12 QTimeLine::qt_metacast
+16 QTimeLine::qt_metacall
+20 QTimeLine::~QTimeLine
+24 QTimeLine::~QTimeLine
+28 QObject::event
+32 QObject::eventFilter
+36 QTimeLine::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTimeLine::valueForTime
+
+Class QTimeLine
+ size=8 align=4
+ base size=8 base align=4
+QTimeLine (0xb5612140) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 8u)
+ QObject (0xb560d4ec) 0
+ primary-for QTimeLine (0xb5612140)
+
+Class QMutex
+ size=4 align=4
+ base size=4 base align=4
+QMutex (0xb560d780) 0
+
+Class QMutexLocker
+ size=4 align=4
+ base size=4 base align=4
+QMutexLocker (0xb560de10) 0
+
+Class QReadWriteLock
+ size=4 align=4
+ base size=4 base align=4
+QReadWriteLock (0xb5656384) 0
+
+Class QReadLocker
+ size=4 align=4
+ base size=4 base align=4
+QReadLocker (0xb56563c0) 0
+
+Class QWriteLocker
+ size=4 align=4
+ base size=4 base align=4
+QWriteLocker (0xb56568ac) 0
+
+Class QSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSemaphore (0xb5656d98) 0
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QThread)
+8 QThread::metaObject
+12 QThread::qt_metacast
+16 QThread::qt_metacall
+20 QThread::~QThread
+24 QThread::~QThread
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QThread::run
+
+Class QThread
+ size=8 align=4
+ base size=8 base align=4
+QThread (0xb5675100) 0
+ vptr=((& QThread::_ZTV7QThread) + 8u)
+ QObject (0xb5656dd4) 0
+ primary-for QThread (0xb5675100)
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0xb568a078) 0
+
+Class QWaitCondition
+ size=4 align=4
+ base size=4 base align=4
+QWaitCondition (0xb568a0f0) 0
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QAbstractState)
+8 QAbstractState::metaObject
+12 QAbstractState::qt_metacast
+16 QAbstractState::qt_metacall
+20 QAbstractState::~QAbstractState
+24 QAbstractState::~QAbstractState
+28 QAbstractState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QAbstractState
+ size=8 align=4
+ base size=8 base align=4
+QAbstractState (0xb5675bc0) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 8u)
+ QObject (0xb568a12c) 0
+ primary-for QAbstractState (0xb5675bc0)
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTransition)
+8 QAbstractTransition::metaObject
+12 QAbstractTransition::qt_metacast
+16 QAbstractTransition::qt_metacall
+20 QAbstractTransition::~QAbstractTransition
+24 QAbstractTransition::~QAbstractTransition
+28 QAbstractTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QAbstractTransition
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTransition (0xb5675e80) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 8u)
+ QObject (0xb568a348) 0
+ primary-for QAbstractTransition (0xb5675e80)
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QEvent)
+8 QEvent::~QEvent
+12 QEvent::~QEvent
+
+Class QEvent
+ size=12 align=4
+ base size=12 base align=4
+QEvent (0xb568a564) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 8u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTimerEvent)
+8 QTimerEvent::~QTimerEvent
+12 QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=16 align=4
+ base size=16 base align=4
+QTimerEvent (0xb56ad400) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 8u)
+ QEvent (0xb568a744) 0
+ primary-for QTimerEvent (0xb56ad400)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QChildEvent)
+8 QChildEvent::~QChildEvent
+12 QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=16 align=4
+ base size=16 base align=4
+QChildEvent (0xb56ad4c0) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 8u)
+ QEvent (0xb568a7bc) 0
+ primary-for QChildEvent (0xb56ad4c0)
+
+Vtable for QCustomEvent
+QCustomEvent::_ZTV12QCustomEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QCustomEvent)
+8 QCustomEvent::~QCustomEvent
+12 QCustomEvent::~QCustomEvent
+
+Class QCustomEvent
+ size=12 align=4
+ base size=12 base align=4
+QCustomEvent (0xb56ad780) 0
+ vptr=((& QCustomEvent::_ZTV12QCustomEvent) + 8u)
+ QEvent (0xb568a924) 0
+ primary-for QCustomEvent (0xb56ad780)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+8 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+12 QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=16 align=4
+ base size=16 base align=4
+QDynamicPropertyChangeEvent (0xb56ad880) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 8u)
+ QEvent (0xb568aa14) 0
+ primary-for QDynamicPropertyChangeEvent (0xb56ad880)
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QEventTransition)
+8 QEventTransition::metaObject
+12 QEventTransition::qt_metacast
+16 QEventTransition::qt_metacall
+20 QEventTransition::~QEventTransition
+24 QEventTransition::~QEventTransition
+28 QEventTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QEventTransition::eventTest
+60 QEventTransition::onTransition
+
+Class QEventTransition
+ size=8 align=4
+ base size=8 base align=4
+QEventTransition (0xb56ad940) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 8u)
+ QAbstractTransition (0xb56ad980) 0
+ primary-for QEventTransition (0xb56ad940)
+ QObject (0xb568aac8) 0
+ primary-for QAbstractTransition (0xb56ad980)
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QFinalState)
+8 QFinalState::metaObject
+12 QFinalState::qt_metacast
+16 QFinalState::qt_metacall
+20 QFinalState::~QFinalState
+24 QFinalState::~QFinalState
+28 QFinalState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFinalState::onEntry
+60 QFinalState::onExit
+
+Class QFinalState
+ size=8 align=4
+ base size=8 base align=4
+QFinalState (0xb56adc40) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 8u)
+ QAbstractState (0xb56adc80) 0
+ primary-for QFinalState (0xb56adc40)
+ QObject (0xb568ace4) 0
+ primary-for QAbstractState (0xb56adc80)
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QHistoryState)
+8 QHistoryState::metaObject
+12 QHistoryState::qt_metacast
+16 QHistoryState::qt_metacall
+20 QHistoryState::~QHistoryState
+24 QHistoryState::~QHistoryState
+28 QHistoryState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QHistoryState::onEntry
+60 QHistoryState::onExit
+
+Class QHistoryState
+ size=8 align=4
+ base size=8 base align=4
+QHistoryState (0xb56adf40) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 8u)
+ QAbstractState (0xb56adf80) 0
+ primary-for QHistoryState (0xb56adf40)
+ QObject (0xb568af00) 0
+ primary-for QAbstractState (0xb56adf80)
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QSignalTransition)
+8 QSignalTransition::metaObject
+12 QSignalTransition::qt_metacast
+16 QSignalTransition::qt_metacall
+20 QSignalTransition::~QSignalTransition
+24 QSignalTransition::~QSignalTransition
+28 QSignalTransition::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSignalTransition::eventTest
+60 QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=8 align=4
+ base size=8 base align=4
+QSignalTransition (0xb54ec240) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 8u)
+ QAbstractTransition (0xb54ec280) 0
+ primary-for QSignalTransition (0xb54ec240)
+ QObject (0xb54f812c) 0
+ primary-for QAbstractTransition (0xb54ec280)
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QState)
+8 QState::metaObject
+12 QState::qt_metacast
+16 QState::qt_metacall
+20 QState::~QState
+24 QState::~QState
+28 QState::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QState::onEntry
+60 QState::onExit
+
+Class QState
+ size=8 align=4
+ base size=8 base align=4
+QState (0xb54ec540) 0
+ vptr=((& QState::_ZTV6QState) + 8u)
+ QAbstractState (0xb54ec580) 0
+ primary-for QState (0xb54ec540)
+ QObject (0xb54f8348) 0
+ primary-for QAbstractState (0xb54ec580)
+
+Class QMetaType
+ size=1 align=1
+ base size=0 base align=1
+QMetaType (0xb54f8564) 0 empty
+
+Class QVariant::PrivateShared
+ size=8 align=4
+ base size=8 base align=4
+QVariant::PrivateShared (0xb5576384) 0
+
+Class QVariant::Private::Data
+ size=8 align=4
+ base size=8 base align=4
+QVariant::Private::Data (0xb55763fc) 0
+
+Class QVariant::Private
+ size=12 align=4
+ base size=12 base align=4
+QVariant::Private (0xb55763c0) 0
+
+Class QVariant::Handler
+ size=36 align=4
+ base size=36 base align=4
+QVariant::Handler (0xb5576474) 0
+
+Class QVariant
+ size=12 align=4
+ base size=12 base align=4
+QVariant (0xb5576348) 0
+
+Class QVariantComparisonHelper
+ size=4 align=4
+ base size=4 base align=4
+QVariantComparisonHelper (0xb55bed20) 0
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+8 QStateMachine::SignalEvent::~SignalEvent
+12 QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=24 align=4
+ base size=24 base align=4
+QStateMachine::SignalEvent (0xb541c380) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 8u)
+ QEvent (0xb541b1e0) 0
+ primary-for QStateMachine::SignalEvent (0xb541c380)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+8 QStateMachine::WrappedEvent::~WrappedEvent
+12 QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=20 align=4
+ base size=20 base align=4
+QStateMachine::WrappedEvent (0xb541c400) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 8u)
+ QEvent (0xb541b21c) 0
+ primary-for QStateMachine::WrappedEvent (0xb541c400)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QStateMachine)
+8 QStateMachine::metaObject
+12 QStateMachine::qt_metacast
+16 QStateMachine::qt_metacall
+20 QStateMachine::~QStateMachine
+24 QStateMachine::~QStateMachine
+28 QStateMachine::event
+32 QStateMachine::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QStateMachine::onEntry
+60 QStateMachine::onExit
+64 QStateMachine::beginSelectTransitions
+68 QStateMachine::endSelectTransitions
+72 QStateMachine::beginMicrostep
+76 QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=8 align=4
+ base size=8 base align=4
+QStateMachine (0xb541c240) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 8u)
+ QState (0xb541c280) 0
+ primary-for QStateMachine (0xb541c240)
+ QAbstractState (0xb541c2c0) 0
+ primary-for QState (0xb541c280)
+ QObject (0xb541b1a4) 0
+ primary-for QAbstractState (0xb541c2c0)
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QFactoryInterface)
+8 QFactoryInterface::~QFactoryInterface
+12 QFactoryInterface::~QFactoryInterface
+16 __cxa_pure_virtual
+
+Class QFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QFactoryInterface (0xb541b5a0) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 8u)
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QLibrary)
+8 QLibrary::metaObject
+12 QLibrary::qt_metacast
+16 QLibrary::qt_metacall
+20 QLibrary::~QLibrary
+24 QLibrary::~QLibrary
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QLibrary
+ size=16 align=4
+ base size=13 base align=4
+QLibrary (0xb541cd80) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 8u)
+ QObject (0xb541bb40) 0
+ primary-for QLibrary (0xb541cd80)
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QPluginLoader)
+8 QPluginLoader::metaObject
+12 QPluginLoader::qt_metacast
+16 QPluginLoader::qt_metacall
+20 QPluginLoader::~QPluginLoader
+24 QPluginLoader::~QPluginLoader
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QPluginLoader
+ size=16 align=4
+ base size=13 base align=4
+QPluginLoader (0xb5455bc0) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 8u)
+ QObject (0xb541bdd4) 0
+ primary-for QPluginLoader (0xb5455bc0)
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0xb541bf00) 0
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QEventLoop)
+8 QEventLoop::metaObject
+12 QEventLoop::qt_metacast
+16 QEventLoop::qt_metacall
+20 QEventLoop::~QEventLoop
+24 QEventLoop::~QEventLoop
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QEventLoop
+ size=8 align=4
+ base size=8 base align=4
+QEventLoop (0xb5489440) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 8u)
+ QObject (0xb5488f00) 0
+ primary-for QEventLoop (0xb5489440)
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+8 QAbstractEventDispatcher::metaObject
+12 QAbstractEventDispatcher::qt_metacast
+16 QAbstractEventDispatcher::qt_metacall
+20 QAbstractEventDispatcher::~QAbstractEventDispatcher
+24 QAbstractEventDispatcher::~QAbstractEventDispatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 QAbstractEventDispatcher::startingUp
+104 QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=8 align=4
+ base size=8 base align=4
+QAbstractEventDispatcher (0xb5489840) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 8u)
+ QObject (0xb54a521c) 0
+ primary-for QAbstractEventDispatcher (0xb5489840)
+
+Class QModelIndex
+ size=16 align=4
+ base size=16 base align=4
+QModelIndex (0xb54a5438) 0
+
+Class QPersistentModelIndex
+ size=4 align=4
+ base size=4 base align=4
+QPersistentModelIndex (0xb52d28e8) 0
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractItemModel)
+8 QAbstractItemModel::metaObject
+12 QAbstractItemModel::qt_metacast
+16 QAbstractItemModel::qt_metacall
+20 QAbstractItemModel::~QAbstractItemModel
+24 QAbstractItemModel::~QAbstractItemModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractItemModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemModel (0xb52d6480) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 8u)
+ QObject (0xb52d2a50) 0
+ primary-for QAbstractItemModel (0xb52d6480)
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractTableModel)
+8 QAbstractTableModel::metaObject
+12 QAbstractTableModel::qt_metacast
+16 QAbstractTableModel::qt_metacall
+20 QAbstractTableModel::~QAbstractTableModel
+24 QAbstractTableModel::~QAbstractTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 QAbstractTableModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractTableModel (0xb52d6ac0) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 8u)
+ QAbstractItemModel (0xb52d6b00) 0
+ primary-for QAbstractTableModel (0xb52d6ac0)
+ QObject (0xb530f3c0) 0
+ primary-for QAbstractItemModel (0xb52d6b00)
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractListModel)
+8 QAbstractListModel::metaObject
+12 QAbstractListModel::qt_metacast
+16 QAbstractListModel::qt_metacall
+20 QAbstractListModel::~QAbstractListModel
+24 QAbstractListModel::~QAbstractListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 __cxa_pure_virtual
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 __cxa_pure_virtual
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=8 align=4
+ base size=8 base align=4
+QAbstractListModel (0xb52d6d40) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 8u)
+ QAbstractItemModel (0xb52d6d80) 0
+ primary-for QAbstractListModel (0xb52d6d40)
+ QObject (0xb530f4ec) 0
+ primary-for QAbstractItemModel (0xb52d6d80)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0xb53353c0) 0
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QCoreApplication)
+8 QCoreApplication::metaObject
+12 QCoreApplication::qt_metacast
+16 QCoreApplication::qt_metacall
+20 QCoreApplication::~QCoreApplication
+24 QCoreApplication::~QCoreApplication
+28 QCoreApplication::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QCoreApplication::notify
+60 QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=8 align=4
+ base size=8 base align=4
+QCoreApplication (0xb532b840) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 8u)
+ QObject (0xb5335654) 0
+ primary-for QCoreApplication (0xb532b840)
+
+Class __exception
+ size=32 align=4
+ base size=32 base align=4
+__exception (0xb5335bf4) 0
+
+Class QMetaMethod
+ size=8 align=4
+ base size=8 base align=4
+QMetaMethod (0xb538f924) 0
+
+Class QMetaEnum
+ size=8 align=4
+ base size=8 base align=4
+QMetaEnum (0xb538fc30) 0
+
+Class QMetaProperty
+ size=20 align=4
+ base size=20 base align=4
+QMetaProperty (0xb538fe88) 0
+
+Class QMetaClassInfo
+ size=8 align=4
+ base size=8 base align=4
+QMetaClassInfo (0xb538ff3c) 0
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QMimeData)
+8 QMimeData::metaObject
+12 QMimeData::qt_metacast
+16 QMimeData::qt_metacall
+20 QMimeData::~QMimeData
+24 QMimeData::~QMimeData
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QMimeData::hasFormat
+60 QMimeData::formats
+64 QMimeData::retrieveData
+
+Class QMimeData
+ size=8 align=4
+ base size=8 base align=4
+QMimeData (0xb53a7680) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 8u)
+ QObject (0xb53b91a4) 0
+ primary-for QMimeData (0xb53a7680)
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+8 QObjectCleanupHandler::metaObject
+12 QObjectCleanupHandler::qt_metacast
+16 QObjectCleanupHandler::qt_metacall
+20 QObjectCleanupHandler::~QObjectCleanupHandler
+24 QObjectCleanupHandler::~QObjectCleanupHandler
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=12 align=4
+ base size=12 base align=4
+QObjectCleanupHandler (0xb53a7940) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 8u)
+ QObject (0xb53b93c0) 0
+ primary-for QObjectCleanupHandler (0xb53a7940)
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSharedMemory)
+8 QSharedMemory::metaObject
+12 QSharedMemory::qt_metacast
+16 QSharedMemory::qt_metacall
+20 QSharedMemory::~QSharedMemory
+24 QSharedMemory::~QSharedMemory
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSharedMemory
+ size=8 align=4
+ base size=8 base align=4
+QSharedMemory (0xb53a7b80) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 8u)
+ QObject (0xb53b94ec) 0
+ primary-for QSharedMemory (0xb53a7b80)
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QSignalMapper)
+8 QSignalMapper::metaObject
+12 QSignalMapper::qt_metacast
+16 QSignalMapper::qt_metacall
+20 QSignalMapper::~QSignalMapper
+24 QSignalMapper::~QSignalMapper
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSignalMapper
+ size=8 align=4
+ base size=8 base align=4
+QSignalMapper (0xb53a7e40) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 8u)
+ QObject (0xb53b9708) 0
+ primary-for QSignalMapper (0xb53a7e40)
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QSocketNotifier)
+8 QSocketNotifier::metaObject
+12 QSocketNotifier::qt_metacast
+16 QSocketNotifier::qt_metacall
+20 QSocketNotifier::~QSocketNotifier
+24 QSocketNotifier::~QSocketNotifier
+28 QSocketNotifier::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=20 align=4
+ base size=17 base align=4
+QSocketNotifier (0xb51ef100) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 8u)
+ QObject (0xb53b9924) 0
+ primary-for QSocketNotifier (0xb51ef100)
+
+Class QSystemSemaphore
+ size=4 align=4
+ base size=4 base align=4
+QSystemSemaphore (0xb53b9bf4) 0
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QTimer)
+8 QTimer::metaObject
+12 QTimer::qt_metacast
+16 QTimer::qt_metacall
+20 QTimer::~QTimer
+24 QTimer::~QTimer
+28 QObject::event
+32 QObject::eventFilter
+36 QTimer::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QTimer
+ size=24 align=4
+ base size=21 base align=4
+QTimer (0xb51ef4c0) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 8u)
+ QObject (0xb53b9ca8) 0
+ primary-for QTimer (0xb51ef4c0)
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTranslator)
+8 QTranslator::metaObject
+12 QTranslator::qt_metacast
+16 QTranslator::qt_metacall
+20 QTranslator::~QTranslator
+24 QTranslator::~QTranslator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QTranslator::translate
+60 QTranslator::isEmpty
+
+Class QTranslator
+ size=8 align=4
+ base size=8 base align=4
+QTranslator (0xb51efa00) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 8u)
+ QObject (0xb53b9f3c) 0
+ primary-for QTranslator (0xb51efa00)
+
+Class _IO_marker
+ size=12 align=4
+ base size=12 base align=4
+_IO_marker (0xb522630c) 0
+
+Class _IO_FILE
+ size=148 align=4
+ base size=148 base align=4
+_IO_FILE (0xb5226348) 0
+
+Vtable for QFile
+QFile::_ZTV5QFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI5QFile)
+8 QFile::metaObject
+12 QFile::qt_metacast
+16 QFile::qt_metacall
+20 QFile::~QFile
+24 QFile::~QFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QFile::fileEngine
+
+Class QFile
+ size=8 align=4
+ base size=8 base align=4
+QFile (0xb51eff00) 0
+ vptr=((& QFile::_ZTV5QFile) + 8u)
+ QIODevice (0xb51eff40) 0
+ primary-for QFile (0xb51eff00)
+ QObject (0xb52263c0) 0
+ primary-for QIODevice (0xb51eff40)
+
+Class QFileInfo
+ size=4 align=4
+ base size=4 base align=4
+QFileInfo (0xb5226834) 0
+
+Class QDir
+ size=4 align=4
+ base size=4 base align=4
+QDir (0xb5226e88) 0
+
+Class QAbstractFileEngine::ExtensionOption
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionOption (0xb50e3618) 0 empty
+
+Class QAbstractFileEngine::ExtensionReturn
+ size=1 align=1
+ base size=0 base align=1
+QAbstractFileEngine::ExtensionReturn (0xb50e3654) 0 empty
+
+Class QAbstractFileEngine::MapExtensionOption
+ size=20 align=4
+ base size=20 base align=4
+QAbstractFileEngine::MapExtensionOption (0xb50e8740) 0
+ QAbstractFileEngine::ExtensionOption (0xb50e3690) 0 empty
+
+Class QAbstractFileEngine::MapExtensionReturn
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::MapExtensionReturn (0xb50e87c0) 0
+ QAbstractFileEngine::ExtensionReturn (0xb50e36cc) 0 empty
+
+Class QAbstractFileEngine::UnMapExtensionOption
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngine::UnMapExtensionOption (0xb50e8840) 0
+ QAbstractFileEngine::ExtensionOption (0xb50e3708) 0 empty
+
+Vtable for QAbstractFileEngine
+QAbstractFileEngine::_ZTV19QAbstractFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractFileEngine)
+8 QAbstractFileEngine::~QAbstractFileEngine
+12 QAbstractFileEngine::~QAbstractFileEngine
+16 QAbstractFileEngine::open
+20 QAbstractFileEngine::close
+24 QAbstractFileEngine::flush
+28 QAbstractFileEngine::size
+32 QAbstractFileEngine::pos
+36 QAbstractFileEngine::seek
+40 QAbstractFileEngine::isSequential
+44 QAbstractFileEngine::remove
+48 QAbstractFileEngine::copy
+52 QAbstractFileEngine::rename
+56 QAbstractFileEngine::link
+60 QAbstractFileEngine::mkdir
+64 QAbstractFileEngine::rmdir
+68 QAbstractFileEngine::setSize
+72 QAbstractFileEngine::caseSensitive
+76 QAbstractFileEngine::isRelativePath
+80 QAbstractFileEngine::entryList
+84 QAbstractFileEngine::fileFlags
+88 QAbstractFileEngine::setPermissions
+92 QAbstractFileEngine::fileName
+96 QAbstractFileEngine::ownerId
+100 QAbstractFileEngine::owner
+104 QAbstractFileEngine::fileTime
+108 QAbstractFileEngine::setFileName
+112 QAbstractFileEngine::handle
+116 QAbstractFileEngine::beginEntryList
+120 QAbstractFileEngine::endEntryList
+124 QAbstractFileEngine::read
+128 QAbstractFileEngine::readLine
+132 QAbstractFileEngine::write
+136 QAbstractFileEngine::extension
+140 QAbstractFileEngine::supportsExtension
+
+Class QAbstractFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngine (0xb50e35dc) 0
+ vptr=((& QAbstractFileEngine::_ZTV19QAbstractFileEngine) + 8u)
+
+Vtable for QAbstractFileEngineHandler
+QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QAbstractFileEngineHandler)
+8 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+12 QAbstractFileEngineHandler::~QAbstractFileEngineHandler
+16 __cxa_pure_virtual
+
+Class QAbstractFileEngineHandler
+ size=4 align=4
+ base size=4 base align=4
+QAbstractFileEngineHandler (0xb50e3960) 0 nearly-empty
+ vptr=((& QAbstractFileEngineHandler::_ZTV26QAbstractFileEngineHandler) + 8u)
+
+Vtable for QAbstractFileEngineIterator
+QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI27QAbstractFileEngineIterator)
+8 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+12 QAbstractFileEngineIterator::~QAbstractFileEngineIterator
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QAbstractFileEngineIterator::currentFileInfo
+32 QAbstractFileEngineIterator::entryInfo
+
+Class QAbstractFileEngineIterator
+ size=8 align=4
+ base size=8 base align=4
+QAbstractFileEngineIterator (0xb50e399c) 0
+ vptr=((& QAbstractFileEngineIterator::_ZTV27QAbstractFileEngineIterator) + 8u)
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QBuffer)
+8 QBuffer::metaObject
+12 QBuffer::qt_metacast
+16 QBuffer::qt_metacall
+20 QBuffer::~QBuffer
+24 QBuffer::~QBuffer
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QBuffer::connectNotify
+52 QBuffer::disconnectNotify
+56 QIODevice::isSequential
+60 QBuffer::open
+64 QBuffer::close
+68 QBuffer::pos
+72 QBuffer::size
+76 QBuffer::seek
+80 QBuffer::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QBuffer::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QBuffer::readData
+112 QIODevice::readLineData
+116 QBuffer::writeData
+
+Class QBuffer
+ size=8 align=4
+ base size=8 base align=4
+QBuffer (0xb50e8b80) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 8u)
+ QIODevice (0xb50e8bc0) 0
+ primary-for QBuffer (0xb50e8b80)
+ QObject (0xb50e3a14) 0
+ primary-for QIODevice (0xb50e8bc0)
+
+Class QTextCodec::ConverterState
+ size=28 align=4
+ base size=28 base align=4
+QTextCodec::ConverterState (0xb50e3c6c) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTextCodec)
+8 __cxa_pure_virtual
+12 QTextCodec::aliases
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+24 __cxa_pure_virtual
+28 QTextCodec::~QTextCodec
+32 QTextCodec::~QTextCodec
+
+Class QTextCodec
+ size=4 align=4
+ base size=4 base align=4
+QTextCodec (0xb50e3c30) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 8u)
+
+Class QTextEncoder
+ size=32 align=4
+ base size=32 base align=4
+QTextEncoder (0xb5171960) 0
+
+Class QTextDecoder
+ size=32 align=4
+ base size=32 base align=4
+QTextDecoder (0xb5171bb8) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QTextStream)
+8 QTextStream::~QTextStream
+12 QTextStream::~QTextStream
+
+Class QTextStream
+ size=8 align=4
+ base size=8 base align=4
+QTextStream (0xb5171e10) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 8u)
+
+Class QTextStreamManipulator
+ size=24 align=4
+ base size=22 base align=4
+QTextStreamManipulator (0xb4fd24b0) 0
+
+Vtable for QTextIStream
+QTextIStream::_ZTV12QTextIStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextIStream)
+8 QTextIStream::~QTextIStream
+12 QTextIStream::~QTextIStream
+
+Class QTextIStream
+ size=8 align=4
+ base size=8 base align=4
+QTextIStream (0xb4ff45c0) 0
+ vptr=((& QTextIStream::_ZTV12QTextIStream) + 8u)
+ QTextStream (0xb4ff7690) 0
+ primary-for QTextIStream (0xb4ff45c0)
+
+Vtable for QTextOStream
+QTextOStream::_ZTV12QTextOStream: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QTextOStream)
+8 QTextOStream::~QTextOStream
+12 QTextOStream::~QTextOStream
+
+Class QTextOStream
+ size=8 align=4
+ base size=8 base align=4
+QTextOStream (0xb4ff4880) 0
+ vptr=((& QTextOStream::_ZTV12QTextOStream) + 8u)
+ QTextStream (0xb4ff7d20) 0
+ primary-for QTextOStream (0xb4ff4880)
+
+Class QDebug::Stream
+ size=24 align=4
+ base size=22 base align=4
+QDebug::Stream (0xb50143fc) 0
+
+Class QDebug
+ size=4 align=4
+ base size=4 base align=4
+QDebug (0xb50143c0) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0xb508f03c) 0 empty
+
+Vtable for QDirIterator
+QDirIterator::_ZTV12QDirIterator: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QDirIterator)
+8 QDirIterator::~QDirIterator
+12 QDirIterator::~QDirIterator
+
+Class QDirIterator
+ size=8 align=4
+ base size=8 base align=4
+QDirIterator (0xb508f2d0) 0
+ vptr=((& QDirIterator::_ZTV12QDirIterator) + 8u)
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+8 QFileSystemWatcher::metaObject
+12 QFileSystemWatcher::qt_metacast
+16 QFileSystemWatcher::qt_metacall
+20 QFileSystemWatcher::~QFileSystemWatcher
+24 QFileSystemWatcher::~QFileSystemWatcher
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=8 align=4
+ base size=8 base align=4
+QFileSystemWatcher (0xb50c1240) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 8u)
+ QObject (0xb508f438) 0
+ primary-for QFileSystemWatcher (0xb50c1240)
+
+Vtable for QFSFileEngine
+QFSFileEngine::_ZTV13QFSFileEngine: 36u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QFSFileEngine)
+8 QFSFileEngine::~QFSFileEngine
+12 QFSFileEngine::~QFSFileEngine
+16 QFSFileEngine::open
+20 QFSFileEngine::close
+24 QFSFileEngine::flush
+28 QFSFileEngine::size
+32 QFSFileEngine::pos
+36 QFSFileEngine::seek
+40 QFSFileEngine::isSequential
+44 QFSFileEngine::remove
+48 QFSFileEngine::copy
+52 QFSFileEngine::rename
+56 QFSFileEngine::link
+60 QFSFileEngine::mkdir
+64 QFSFileEngine::rmdir
+68 QFSFileEngine::setSize
+72 QFSFileEngine::caseSensitive
+76 QFSFileEngine::isRelativePath
+80 QFSFileEngine::entryList
+84 QFSFileEngine::fileFlags
+88 QFSFileEngine::setPermissions
+92 QFSFileEngine::fileName
+96 QFSFileEngine::ownerId
+100 QFSFileEngine::owner
+104 QFSFileEngine::fileTime
+108 QFSFileEngine::setFileName
+112 QFSFileEngine::handle
+116 QFSFileEngine::beginEntryList
+120 QFSFileEngine::endEntryList
+124 QFSFileEngine::read
+128 QFSFileEngine::readLine
+132 QFSFileEngine::write
+136 QFSFileEngine::extension
+140 QFSFileEngine::supportsExtension
+
+Class QFSFileEngine
+ size=8 align=4
+ base size=8 base align=4
+QFSFileEngine (0xb50c1500) 0
+ vptr=((& QFSFileEngine::_ZTV13QFSFileEngine) + 8u)
+ QAbstractFileEngine (0xb508f654) 0
+ primary-for QFSFileEngine (0xb50c1500)
+
+Class QProcessEnvironment
+ size=4 align=4
+ base size=4 base align=4
+QProcessEnvironment (0xb508f780) 0
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI8QProcess)
+8 QProcess::metaObject
+12 QProcess::qt_metacast
+16 QProcess::qt_metacall
+20 QProcess::~QProcess
+24 QProcess::~QProcess
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QProcess::isSequential
+60 QIODevice::open
+64 QProcess::close
+68 QIODevice::pos
+72 QIODevice::size
+76 QIODevice::seek
+80 QProcess::atEnd
+84 QIODevice::reset
+88 QProcess::bytesAvailable
+92 QProcess::bytesToWrite
+96 QProcess::canReadLine
+100 QProcess::waitForReadyRead
+104 QProcess::waitForBytesWritten
+108 QProcess::readData
+112 QIODevice::readLineData
+116 QProcess::writeData
+120 QProcess::setupChildProcess
+
+Class QProcess
+ size=8 align=4
+ base size=8 base align=4
+QProcess (0xb50c16c0) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 8u)
+ QIODevice (0xb50c1700) 0
+ primary-for QProcess (0xb50c16c0)
+ QObject (0xb508f834) 0
+ primary-for QIODevice (0xb50c1700)
+
+Class QResource
+ size=4 align=4
+ base size=4 base align=4
+QResource (0xb508fa50) 0
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QSettings)
+8 QSettings::metaObject
+12 QSettings::qt_metacast
+16 QSettings::qt_metacall
+20 QSettings::~QSettings
+24 QSettings::~QSettings
+28 QSettings::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QSettings
+ size=8 align=4
+ base size=8 base align=4
+QSettings (0xb50c1b40) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 8u)
+ QObject (0xb508fbf4) 0
+ primary-for QSettings (0xb50c1b40)
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 31u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QTemporaryFile)
+8 QTemporaryFile::metaObject
+12 QTemporaryFile::qt_metacast
+16 QTemporaryFile::qt_metacall
+20 QTemporaryFile::~QTemporaryFile
+24 QTemporaryFile::~QTemporaryFile
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QFile::isSequential
+60 QTemporaryFile::open
+64 QFile::close
+68 QFile::pos
+72 QFile::size
+76 QFile::seek
+80 QFile::atEnd
+84 QIODevice::reset
+88 QIODevice::bytesAvailable
+92 QIODevice::bytesToWrite
+96 QIODevice::canReadLine
+100 QIODevice::waitForReadyRead
+104 QIODevice::waitForBytesWritten
+108 QFile::readData
+112 QFile::readLineData
+116 QFile::writeData
+120 QTemporaryFile::fileEngine
+
+Class QTemporaryFile
+ size=8 align=4
+ base size=8 base align=4
+QTemporaryFile (0xb4f5c740) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 8u)
+ QFile (0xb4f5c780) 0
+ primary-for QTemporaryFile (0xb4f5c740)
+ QIODevice (0xb4f5c7c0) 0
+ primary-for QFile (0xb4f5c780)
+ QObject (0xb4f5e708) 0
+ primary-for QIODevice (0xb4f5c7c0)
+
+Class QUrl
+ size=4 align=4
+ base size=4 base align=4
+QUrl (0xb4f5ea14) 0
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0xb4de65dc) 0 empty
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QRunnable)
+8 __cxa_pure_virtual
+12 QRunnable::~QRunnable
+16 QRunnable::~QRunnable
+
+Class QRunnable
+ size=8 align=4
+ base size=8 base align=4
+QRunnable (0xb4de6618) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 8u)
+
+Vtable for QtConcurrent::Exception
+QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent9ExceptionE)
+8 QtConcurrent::Exception::~Exception
+12 QtConcurrent::Exception::~Exception
+16 std::exception::what
+20 QtConcurrent::Exception::raise
+24 QtConcurrent::Exception::clone
+
+Class QtConcurrent::Exception
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::Exception (0xb4deeb00) 0 nearly-empty
+ vptr=((& QtConcurrent::Exception::_ZTVN12QtConcurrent9ExceptionE) + 8u)
+ std::exception (0xb4de6a8c) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb4deeb00)
+
+Vtable for QtConcurrent::UnhandledException
+QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent18UnhandledExceptionE)
+8 QtConcurrent::UnhandledException::~UnhandledException
+12 QtConcurrent::UnhandledException::~UnhandledException
+16 std::exception::what
+20 QtConcurrent::UnhandledException::raise
+24 QtConcurrent::UnhandledException::clone
+
+Class QtConcurrent::UnhandledException
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::UnhandledException (0xb4deec00) 0 nearly-empty
+ vptr=((& QtConcurrent::UnhandledException::_ZTVN12QtConcurrent18UnhandledExceptionE) + 8u)
+ QtConcurrent::Exception (0xb4deec40) 0 nearly-empty
+ primary-for QtConcurrent::UnhandledException (0xb4deec00)
+ std::exception (0xb4de6ac8) 0 nearly-empty
+ primary-for QtConcurrent::Exception (0xb4deec40)
+
+Class QtConcurrent::internal::ExceptionHolder
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionHolder (0xb4de6b04) 0
+
+Class QtConcurrent::internal::ExceptionStore
+ size=4 align=4
+ base size=4 base align=4
+QtConcurrent::internal::ExceptionStore (0xb4de6b40) 0
+
+Class QtConcurrent::ResultItem
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultItem (0xb4de6b7c) 0
+
+Class QtConcurrent::ResultIteratorBase
+ size=8 align=4
+ base size=8 base align=4
+QtConcurrent::ResultIteratorBase (0xb4e0a168) 0
+
+Vtable for QtConcurrent::ResultStoreBase
+QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent15ResultStoreBaseE)
+8 QtConcurrent::ResultStoreBase::~ResultStoreBase
+12 QtConcurrent::ResultStoreBase::~ResultStoreBase
+
+Class QtConcurrent::ResultStoreBase
+ size=28 align=4
+ base size=28 base align=4
+QtConcurrent::ResultStoreBase (0xb4e0a294) 0
+ vptr=((& QtConcurrent::ResultStoreBase::_ZTVN12QtConcurrent15ResultStoreBaseE) + 8u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+8 QFutureInterfaceBase::~QFutureInterfaceBase
+12 QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureInterfaceBase (0xb4e0a6cc) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 8u)
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+8 QFutureWatcherBase::metaObject
+12 QFutureWatcherBase::qt_metacast
+16 QFutureWatcherBase::qt_metacall
+20 QFutureWatcherBase::~QFutureWatcherBase
+24 QFutureWatcherBase::~QFutureWatcherBase
+28 QFutureWatcherBase::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QFutureWatcherBase::connectNotify
+52 QFutureWatcherBase::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=8 align=4
+ base size=8 base align=4
+QFutureWatcherBase (0xb4e9fa40) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 8u)
+ QObject (0xb4ea90b4) 0
+ primary-for QFutureWatcherBase (0xb4e9fa40)
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QThreadPool)
+8 QThreadPool::metaObject
+12 QThreadPool::qt_metacast
+16 QThreadPool::qt_metacall
+20 QThreadPool::~QThreadPool
+24 QThreadPool::~QThreadPool
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QThreadPool
+ size=8 align=4
+ base size=8 base align=4
+QThreadPool (0xb4ec0c00) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 8u)
+ QObject (0xb4cd50b4) 0
+ primary-for QThreadPool (0xb4ec0c00)
+
+Class QtConcurrent::ThreadEngineBarrier
+ size=12 align=4
+ base size=12 base align=4
+QtConcurrent::ThreadEngineBarrier (0xb4cd52d0) 0
+
+Vtable for QtConcurrent::ThreadEngineBase
+QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE)
+8 QtConcurrent::ThreadEngineBase::run
+12 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+16 QtConcurrent::ThreadEngineBase::~ThreadEngineBase
+20 QtConcurrent::ThreadEngineBase::start
+24 QtConcurrent::ThreadEngineBase::finish
+28 QtConcurrent::ThreadEngineBase::threadFunction
+32 QtConcurrent::ThreadEngineBase::shouldStartThread
+36 QtConcurrent::ThreadEngineBase::shouldThrottleThread
+40 __cxa_pure_virtual
+
+Class QtConcurrent::ThreadEngineBase
+ size=32 align=4
+ base size=32 base align=4
+QtConcurrent::ThreadEngineBase (0xb4ec0f00) 0
+ vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 8u)
+ QRunnable (0xb4cd530c) 0
+ primary-for QtConcurrent::ThreadEngineBase (0xb4ec0f00)
+
+VTT for QtConcurrent::ThreadEngine<void>
+QtConcurrent::ThreadEngine<void>::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries
+0 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 12u)
+4 ((& QtConcurrent::ThreadEngine<void>::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 68u)
+
+Class QtConcurrent::BlockSizeManager
+ size=72 align=4
+ base size=72 base align=4
+QtConcurrent::BlockSizeManager (0xb4d088e8) 0
+
+Vtable for QTextCodecFactoryInterface
+QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QTextCodecFactoryInterface)
+8 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+12 QTextCodecFactoryInterface::~QTextCodecFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QTextCodecFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QTextCodecFactoryInterface (0xb4b91480) 0 nearly-empty
+ vptr=((& QTextCodecFactoryInterface::_ZTV26QTextCodecFactoryInterface) + 8u)
+ QFactoryInterface (0xb4b8f1a4) 0 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4b91480)
+
+Vtable for QTextCodecPlugin
+QTextCodecPlugin::_ZTV16QTextCodecPlugin: 27u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+8 QTextCodecPlugin::metaObject
+12 QTextCodecPlugin::qt_metacast
+16 QTextCodecPlugin::qt_metacall
+20 QTextCodecPlugin::~QTextCodecPlugin
+24 QTextCodecPlugin::~QTextCodecPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 QTextCodecPlugin::keys
+80 QTextCodecPlugin::create
+84 (int (*)(...))-0x000000008
+88 (int (*)(...))(& _ZTI16QTextCodecPlugin)
+92 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD1Ev
+96 QTextCodecPlugin::_ZThn8_N16QTextCodecPluginD0Ev
+100 QTextCodecPlugin::_ZThn8_NK16QTextCodecPlugin4keysEv
+104 QTextCodecPlugin::_ZThn8_N16QTextCodecPlugin6createERK7QString
+
+Class QTextCodecPlugin
+ size=12 align=4
+ base size=12 base align=4
+QTextCodecPlugin (0xb4b9ca50) 0
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 8u)
+ QObject (0xb4b8f4b0) 0
+ primary-for QTextCodecPlugin (0xb4b9ca50)
+ QTextCodecFactoryInterface (0xb4b91740) 8 nearly-empty
+ vptr=((& QTextCodecPlugin::_ZTV16QTextCodecPlugin) + 92u)
+ QFactoryInterface (0xb4b8f4ec) 8 nearly-empty
+ primary-for QTextCodecFactoryInterface (0xb4b91740)
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QAbstractAnimation)
+8 QAbstractAnimation::metaObject
+12 QAbstractAnimation::qt_metacast
+16 QAbstractAnimation::qt_metacall
+20 QAbstractAnimation::~QAbstractAnimation
+24 QAbstractAnimation::~QAbstractAnimation
+28 QAbstractAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=8 align=4
+ base size=8 base align=4
+QAbstractAnimation (0xb4b91980) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 8u)
+ QObject (0xb4b8f618) 0
+ primary-for QAbstractAnimation (0xb4b91980)
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QAnimationGroup)
+8 QAnimationGroup::metaObject
+12 QAnimationGroup::qt_metacast
+16 QAnimationGroup::qt_metacall
+20 QAnimationGroup::~QAnimationGroup
+24 QAnimationGroup::~QAnimationGroup
+28 QAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QAnimationGroup (0xb4b91c40) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 8u)
+ QAbstractAnimation (0xb4b91c80) 0
+ primary-for QAnimationGroup (0xb4b91c40)
+ QObject (0xb4b8f870) 0
+ primary-for QAbstractAnimation (0xb4b91c80)
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+8 QParallelAnimationGroup::metaObject
+12 QParallelAnimationGroup::qt_metacast
+16 QParallelAnimationGroup::qt_metacall
+20 QParallelAnimationGroup::~QParallelAnimationGroup
+24 QParallelAnimationGroup::~QParallelAnimationGroup
+28 QParallelAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QParallelAnimationGroup::duration
+60 QParallelAnimationGroup::updateCurrentTime
+64 QParallelAnimationGroup::updateState
+68 QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QParallelAnimationGroup (0xb4b91f40) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 8u)
+ QAnimationGroup (0xb4b91f80) 0
+ primary-for QParallelAnimationGroup (0xb4b91f40)
+ QAbstractAnimation (0xb4b91fc0) 0
+ primary-for QAnimationGroup (0xb4b91f80)
+ QObject (0xb4b8fa8c) 0
+ primary-for QAbstractAnimation (0xb4b91fc0)
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QPauseAnimation)
+8 QPauseAnimation::metaObject
+12 QPauseAnimation::qt_metacast
+16 QPauseAnimation::qt_metacall
+20 QPauseAnimation::~QPauseAnimation
+24 QPauseAnimation::~QPauseAnimation
+28 QPauseAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QPauseAnimation::duration
+60 QPauseAnimation::updateCurrentTime
+64 QAbstractAnimation::updateState
+68 QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=8 align=4
+ base size=8 base align=4
+QPauseAnimation (0xb4bc9280) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 8u)
+ QAbstractAnimation (0xb4bc92c0) 0
+ primary-for QPauseAnimation (0xb4bc9280)
+ QObject (0xb4b8fca8) 0
+ primary-for QAbstractAnimation (0xb4bc92c0)
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QVariantAnimation)
+8 QVariantAnimation::metaObject
+12 QVariantAnimation::qt_metacast
+16 QVariantAnimation::qt_metacall
+20 QVariantAnimation::~QVariantAnimation
+24 QVariantAnimation::~QVariantAnimation
+28 QVariantAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QVariantAnimation::duration
+60 QVariantAnimation::updateCurrentTime
+64 QVariantAnimation::updateState
+68 QAbstractAnimation::updateDirection
+72 __cxa_pure_virtual
+76 QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=8 align=4
+ base size=8 base align=4
+QVariantAnimation (0xb4bc9580) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 8u)
+ QAbstractAnimation (0xb4bc95c0) 0
+ primary-for QVariantAnimation (0xb4bc9580)
+ QObject (0xb4b8fec4) 0
+ primary-for QAbstractAnimation (0xb4bc95c0)
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QPropertyAnimation)
+8 QPropertyAnimation::metaObject
+12 QPropertyAnimation::qt_metacast
+16 QPropertyAnimation::qt_metacall
+20 QPropertyAnimation::~QPropertyAnimation
+24 QPropertyAnimation::~QPropertyAnimation
+28 QPropertyAnimation::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QVariantAnimation::duration
+60 QVariantAnimation::updateCurrentTime
+64 QPropertyAnimation::updateState
+68 QAbstractAnimation::updateDirection
+72 QPropertyAnimation::updateCurrentValue
+76 QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=8 align=4
+ base size=8 base align=4
+QPropertyAnimation (0xb4bc99c0) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 8u)
+ QVariantAnimation (0xb4bc9a00) 0
+ primary-for QPropertyAnimation (0xb4bc99c0)
+ QAbstractAnimation (0xb4bc9a40) 0
+ primary-for QVariantAnimation (0xb4bc9a00)
+ QObject (0xb49f40f0) 0
+ primary-for QAbstractAnimation (0xb4bc9a40)
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+8 QSequentialAnimationGroup::metaObject
+12 QSequentialAnimationGroup::qt_metacast
+16 QSequentialAnimationGroup::qt_metacall
+20 QSequentialAnimationGroup::~QSequentialAnimationGroup
+24 QSequentialAnimationGroup::~QSequentialAnimationGroup
+28 QSequentialAnimationGroup::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSequentialAnimationGroup::duration
+60 QSequentialAnimationGroup::updateCurrentTime
+64 QSequentialAnimationGroup::updateState
+68 QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=8 align=4
+ base size=8 base align=4
+QSequentialAnimationGroup (0xb4bc9d00) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 8u)
+ QAnimationGroup (0xb4bc9d40) 0
+ primary-for QSequentialAnimationGroup (0xb4bc9d00)
+ QAbstractAnimation (0xb4bc9d80) 0
+ primary-for QAnimationGroup (0xb4bc9d40)
+ QObject (0xb49f430c) 0
+ primary-for QAbstractAnimation (0xb4bc9d80)
+
+Class QSqlRecord
+ size=4 align=4
+ base size=4 base align=4
+QSqlRecord (0xb49f4618) 0
+
+Vtable for QSqlDriverCreatorBase
+QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase: 5u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QSqlDriverCreatorBase)
+8 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+12 QSqlDriverCreatorBase::~QSqlDriverCreatorBase
+16 __cxa_pure_virtual
+
+Class QSqlDriverCreatorBase
+ size=4 align=4
+ base size=4 base align=4
+QSqlDriverCreatorBase (0xb49f46cc) 0 nearly-empty
+ vptr=((& QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase) + 8u)
+
+Class QSqlDatabase
+ size=4 align=4
+ base size=4 base align=4
+QSqlDatabase (0xb49f4924) 0
+
+Vtable for QSqlQueryModel
+QSqlQueryModel::_ZTV14QSqlQueryModel: 44u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QSqlQueryModel)
+8 QSqlQueryModel::metaObject
+12 QSqlQueryModel::qt_metacast
+16 QSqlQueryModel::qt_metacall
+20 QSqlQueryModel::~QSqlQueryModel
+24 QSqlQueryModel::~QSqlQueryModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlQueryModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlQueryModel::data
+80 QAbstractItemModel::setData
+84 QSqlQueryModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QSqlQueryModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+168 QSqlQueryModel::clear
+172 QSqlQueryModel::queryChange
+
+Class QSqlQueryModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlQueryModel (0xb4a11600) 0
+ vptr=((& QSqlQueryModel::_ZTV14QSqlQueryModel) + 8u)
+ QAbstractTableModel (0xb4a11640) 0
+ primary-for QSqlQueryModel (0xb4a11600)
+ QAbstractItemModel (0xb4a11680) 0
+ primary-for QAbstractTableModel (0xb4a11640)
+ QObject (0xb49f499c) 0
+ primary-for QAbstractItemModel (0xb4a11680)
+
+Vtable for QSqlTableModel
+QSqlTableModel::_ZTV14QSqlTableModel: 55u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI14QSqlTableModel)
+8 QSqlTableModel::metaObject
+12 QSqlTableModel::qt_metacast
+16 QSqlTableModel::qt_metacall
+20 QSqlTableModel::~QSqlTableModel
+24 QSqlTableModel::~QSqlTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlTableModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlTableModel::data
+80 QSqlTableModel::setData
+84 QSqlTableModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QSqlTableModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QSqlTableModel::removeRows
+128 QSqlTableModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QSqlTableModel::flags
+144 QSqlTableModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QSqlTableModel::submit
+164 QSqlTableModel::revert
+168 QSqlTableModel::clear
+172 QSqlQueryModel::queryChange
+176 QSqlTableModel::select
+180 QSqlTableModel::setTable
+184 QSqlTableModel::setEditStrategy
+188 QSqlTableModel::setSort
+192 QSqlTableModel::setFilter
+196 QSqlTableModel::revertRow
+200 QSqlTableModel::updateRowInTable
+204 QSqlTableModel::insertRowIntoTable
+208 QSqlTableModel::deleteRowFromTable
+212 QSqlTableModel::orderByClause
+216 QSqlTableModel::selectStatement
+
+Class QSqlTableModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlTableModel (0xb4a11940) 0
+ vptr=((& QSqlTableModel::_ZTV14QSqlTableModel) + 8u)
+ QSqlQueryModel (0xb4a11980) 0
+ primary-for QSqlTableModel (0xb4a11940)
+ QAbstractTableModel (0xb4a119c0) 0
+ primary-for QSqlQueryModel (0xb4a11980)
+ QAbstractItemModel (0xb4a11a00) 0
+ primary-for QAbstractTableModel (0xb4a119c0)
+ QObject (0xb49f4bb8) 0
+ primary-for QAbstractItemModel (0xb4a11a00)
+
+Class QSqlRelation
+ size=12 align=4
+ base size=12 base align=4
+QSqlRelation (0xb49f4dd4) 0
+
+Vtable for QSqlRelationalTableModel
+QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel: 57u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI24QSqlRelationalTableModel)
+8 QSqlRelationalTableModel::metaObject
+12 QSqlRelationalTableModel::qt_metacast
+16 QSqlRelationalTableModel::qt_metacall
+20 QSqlRelationalTableModel::~QSqlRelationalTableModel
+24 QSqlRelationalTableModel::~QSqlRelationalTableModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractTableModel::index
+60 QAbstractTableModel::parent
+64 QSqlTableModel::rowCount
+68 QSqlQueryModel::columnCount
+72 QAbstractTableModel::hasChildren
+76 QSqlRelationalTableModel::data
+80 QSqlRelationalTableModel::setData
+84 QSqlTableModel::headerData
+88 QSqlQueryModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractTableModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QSqlTableModel::insertRows
+120 QSqlQueryModel::insertColumns
+124 QSqlTableModel::removeRows
+128 QSqlRelationalTableModel::removeColumns
+132 QSqlQueryModel::fetchMore
+136 QSqlQueryModel::canFetchMore
+140 QSqlTableModel::flags
+144 QSqlTableModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QSqlTableModel::submit
+164 QSqlTableModel::revert
+168 QSqlRelationalTableModel::clear
+172 QSqlQueryModel::queryChange
+176 QSqlRelationalTableModel::select
+180 QSqlRelationalTableModel::setTable
+184 QSqlTableModel::setEditStrategy
+188 QSqlTableModel::setSort
+192 QSqlTableModel::setFilter
+196 QSqlRelationalTableModel::revertRow
+200 QSqlRelationalTableModel::updateRowInTable
+204 QSqlRelationalTableModel::insertRowIntoTable
+208 QSqlTableModel::deleteRowFromTable
+212 QSqlRelationalTableModel::orderByClause
+216 QSqlRelationalTableModel::selectStatement
+220 QSqlRelationalTableModel::setRelation
+224 QSqlRelationalTableModel::relationModel
+
+Class QSqlRelationalTableModel
+ size=8 align=4
+ base size=8 base align=4
+QSqlRelationalTableModel (0xb4a11f80) 0
+ vptr=((& QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel) + 8u)
+ QSqlTableModel (0xb4a11fc0) 0
+ primary-for QSqlRelationalTableModel (0xb4a11f80)
+ QSqlQueryModel (0xb4a7d000) 0
+ primary-for QSqlTableModel (0xb4a11fc0)
+ QAbstractTableModel (0xb4a7d040) 0
+ primary-for QSqlQueryModel (0xb4a7d000)
+ QAbstractItemModel (0xb4a7d080) 0
+ primary-for QAbstractTableModel (0xb4a7d040)
+ QObject (0xb4a71a14) 0
+ primary-for QAbstractItemModel (0xb4a7d080)
+
+Class QSqlQuery
+ size=4 align=4
+ base size=4 base align=4
+QSqlQuery (0xb4a71c30) 0
+
+Vtable for QSqlDriver
+QSqlDriver::_ZTV10QSqlDriver: 32u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QSqlDriver)
+8 QSqlDriver::metaObject
+12 QSqlDriver::qt_metacast
+16 QSqlDriver::qt_metacall
+20 QSqlDriver::~QSqlDriver
+24 QSqlDriver::~QSqlDriver
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QSqlDriver::isOpen
+60 QSqlDriver::beginTransaction
+64 QSqlDriver::commitTransaction
+68 QSqlDriver::rollbackTransaction
+72 QSqlDriver::tables
+76 QSqlDriver::primaryIndex
+80 QSqlDriver::record
+84 QSqlDriver::formatValue
+88 QSqlDriver::escapeIdentifier
+92 QSqlDriver::sqlStatement
+96 QSqlDriver::handle
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 QSqlDriver::setOpen
+120 QSqlDriver::setOpenError
+124 QSqlDriver::setLastError
+
+Class QSqlDriver
+ size=8 align=4
+ base size=8 base align=4
+QSqlDriver (0xb4a7d3c0) 0
+ vptr=((& QSqlDriver::_ZTV10QSqlDriver) + 8u)
+ QObject (0xb4a71ca8) 0
+ primary-for QSqlDriver (0xb4a7d3c0)
+
+Vtable for QSqlDriverFactoryInterface
+QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface: 6u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI26QSqlDriverFactoryInterface)
+8 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+12 QSqlDriverFactoryInterface::~QSqlDriverFactoryInterface
+16 __cxa_pure_virtual
+20 __cxa_pure_virtual
+
+Class QSqlDriverFactoryInterface
+ size=4 align=4
+ base size=4 base align=4
+QSqlDriverFactoryInterface (0xb4a7d840) 0 nearly-empty
+ vptr=((& QSqlDriverFactoryInterface::_ZTV26QSqlDriverFactoryInterface) + 8u)
+ QFactoryInterface (0xb4aaf12c) 0 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0xb4a7d840)
+
+Vtable for QSqlDriverPlugin
+QSqlDriverPlugin::_ZTV16QSqlDriverPlugin: 22u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+8 QSqlDriverPlugin::metaObject
+12 QSqlDriverPlugin::qt_metacast
+16 QSqlDriverPlugin::qt_metacall
+20 QSqlDriverPlugin::~QSqlDriverPlugin
+24 QSqlDriverPlugin::~QSqlDriverPlugin
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 (int (*)(...))-0x000000008
+68 (int (*)(...))(& _ZTI16QSqlDriverPlugin)
+72 QSqlDriverPlugin::_ZThn8_N16QSqlDriverPluginD1Ev
+76 QSqlDriverPlugin::_ZThn8_N16QSqlDriverPluginD0Ev
+80 __cxa_pure_virtual
+84 __cxa_pure_virtual
+
+Class QSqlDriverPlugin
+ size=12 align=4
+ base size=12 base align=4
+QSqlDriverPlugin (0xb4ab63c0) 0
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 8u)
+ QObject (0xb4aaf438) 0
+ primary-for QSqlDriverPlugin (0xb4ab63c0)
+ QSqlDriverFactoryInterface (0xb4a7db00) 8 nearly-empty
+ vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 72u)
+ QFactoryInterface (0xb4aaf474) 8 nearly-empty
+ primary-for QSqlDriverFactoryInterface (0xb4a7db00)
+
+Class QSqlError
+ size=16 align=4
+ base size=16 base align=4
+QSqlError (0xb4aaf5a0) 0
+
+Class QSqlField
+ size=16 align=4
+ base size=16 base align=4
+QSqlField (0xb4aaf5dc) 0
+
+Class QSqlIndex
+ size=16 align=4
+ base size=16 base align=4
+QSqlIndex (0xb4a7dec0) 0
+ QSqlRecord (0xb4aaf744) 0
+
+Vtable for QSqlResult
+QSqlResult::_ZTV10QSqlResult: 29u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QSqlResult)
+8 QSqlResult::~QSqlResult
+12 QSqlResult::~QSqlResult
+16 QSqlResult::handle
+20 QSqlResult::setAt
+24 QSqlResult::setActive
+28 QSqlResult::setLastError
+32 QSqlResult::setQuery
+36 QSqlResult::setSelect
+40 QSqlResult::setForwardOnly
+44 QSqlResult::exec
+48 QSqlResult::prepare
+52 QSqlResult::savePrepare
+56 QSqlResult::bindValue
+60 QSqlResult::bindValue
+64 __cxa_pure_virtual
+68 __cxa_pure_virtual
+72 __cxa_pure_virtual
+76 __cxa_pure_virtual
+80 QSqlResult::fetchNext
+84 QSqlResult::fetchPrevious
+88 __cxa_pure_virtual
+92 __cxa_pure_virtual
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 QSqlResult::record
+108 QSqlResult::lastInsertId
+112 QSqlResult::virtual_hook
+
+Class QSqlResult
+ size=8 align=4
+ base size=8 base align=4
+QSqlResult (0xb4aaf8e8) 0
+ vptr=((& QSqlResult::_ZTV10QSqlResult) + 8u)
+
+Class QHelpGlobal
+ size=1 align=1
+ base size=0 base align=1
+QHelpGlobal (0xb4aaf960) 0 empty
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI12QPaintDevice)
+8 QPaintDevice::~QPaintDevice
+12 QPaintDevice::~QPaintDevice
+16 QPaintDevice::devType
+20 __cxa_pure_virtual
+24 QPaintDevice::metric
+
+Class QPaintDevice
+ size=8 align=4
+ base size=6 base align=4
+QPaintDevice (0xb4aaf99c) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 8u)
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0xb48ec564) 0
+
+Class QPolygon
+ size=4 align=4
+ base size=4 base align=4
+QPolygon (0xb48f7ac0) 0
+ QVector<QPoint> (0xb48ecbf4) 0
+
+Class QPolygonF
+ size=4 align=4
+ base size=4 base align=4
+QPolygonF (0xb494c100) 0
+ QVector<QPointF> (0xb49455dc) 0
+
+Class QRegion::QRegionData
+ size=16 align=4
+ base size=16 base align=4
+QRegion::QRegionData (0xb4945f3c) 0
+
+Class QRegion
+ size=4 align=4
+ base size=4 base align=4
+QRegion (0xb4945f00) 0
+
+Class QMatrix
+ size=48 align=4
+ base size=48 base align=4
+QMatrix (0xb4989294) 0
+
+Class QPainterPath::Element
+ size=20 align=4
+ base size=20 base align=4
+QPainterPath::Element (0xb49a5438) 0
+
+Class QPainterPath
+ size=4 align=4
+ base size=4 base align=4
+QPainterPath (0xb49a53fc) 0
+
+Class QPainterPathPrivate
+ size=8 align=4
+ base size=8 base align=4
+QPainterPathPrivate (0xb49a5924) 0
+
+Class QPainterPathStroker
+ size=4 align=4
+ base size=4 base align=4
+QPainterPathStroker (0xb49a5a50) 0
+
+Class QTransform
+ size=80 align=4
+ base size=80 base align=4
+QTransform (0xb480b9d8) 0
+
+Class QImageTextKeyLang
+ size=8 align=4
+ base size=8 base align=4
+QImageTextKeyLang (0xb486f924) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QImage)
+8 QImage::~QImage
+12 QImage::~QImage
+16 QImage::devType
+20 QImage::paintEngine
+24 QImage::metric
+
+Class QImage
+ size=12 align=4
+ base size=12 base align=4
+QImage (0xb4864740) 0
+ vptr=((& QImage::_ZTV6QImage) + 8u)
+ QPaintDevice (0xb488c30c) 0
+ primary-for QImage (0xb4864740)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 7u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QPixmap)
+8 QPixmap::~QPixmap
+12 QPixmap::~QPixmap
+16 QPixmap::devType
+20 QPixmap::paintEngine
+24 QPixmap::metric
+
+Class QPixmap
+ size=12 align=4
+ base size=12 base align=4
+QPixmap (0xb46e5040) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 8u)
+ QPaintDevice (0xb488cec4) 0
+ primary-for QPixmap (0xb46e5040)
+
+Class QBrush
+ size=4 align=4
+ base size=4 base align=4
+QBrush (0xb470c528) 0
+
+Class QBrushData
+ size=104 align=4
+ base size=104 base align=4
+QBrushData (0xb470c6cc) 0
+
+Class QGradient
+ size=56 align=4
+ base size=56 base align=4
+QGradient (0xb470ca8c) 0
+
+Class QLinearGradient
+ size=56 align=4
+ base size=56 base align=4
+QLinearGradient (0xb46e5e80) 0
+ QGradient (0xb470cd20) 0
+
+Class QRadialGradient
+ size=56 align=4
+ base size=56 base align=4
+QRadialGradient (0xb46e5f80) 0
+ QGradient (0xb470cd5c) 0
+
+Class QConicalGradient
+ size=56 align=4
+ base size=56 base align=4
+QConicalGradient (0xb475d080) 0
+ QGradient (0xb470cd98) 0
+
+Class QPalette
+ size=8 align=4
+ base size=8 base align=4
+QPalette (0xb470cdd4) 0
+
+Class QColorGroup
+ size=8 align=4
+ base size=8 base align=4
+QColorGroup (0xb475dac0) 0
+ QPalette (0xb47796cc) 0
+
+Class QFont
+ size=8 align=4
+ base size=8 base align=4
+QFont (0xb479d834) 0
+
+Class QFontMetrics
+ size=4 align=4
+ base size=4 base align=4
+QFontMetrics (0xb479da50) 0
+
+Class QFontMetricsF
+ size=4 align=4
+ base size=4 base align=4
+QFontMetricsF (0xb479dca8) 0
+
+Class QFontInfo
+ size=4 align=4
+ base size=4 base align=4
+QFontInfo (0xb479dd5c) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0xb479dd98) 0
+
+Class QCursor
+ size=4 align=4
+ base size=4 base align=4
+QCursor (0xb4631c6c) 0
+
+Class QKeySequence
+ size=4 align=4
+ base size=4 base align=4
+QKeySequence (0xb4631ca8) 0
+
+Class QWidgetData
+ size=64 align=4
+ base size=64 base align=4
+QWidgetData (0xb4631ec4) 0
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QWidget)
+8 QWidget::metaObject
+12 QWidget::qt_metacast
+16 QWidget::qt_metacall
+20 QWidget::~QWidget
+24 QWidget::~QWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI7QWidget)
+232 QWidget::_ZThn8_N7QWidgetD1Ev
+236 QWidget::_ZThn8_N7QWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QWidget
+ size=20 align=4
+ base size=20 base align=4
+QWidget (0xb4685be0) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 8u)
+ QObject (0xb4631f00) 0
+ primary-for QWidget (0xb4685be0)
+ QPaintDevice (0xb4631f3c) 8
+ vptr=((& QWidget::_ZTV7QWidget) + 232u)
+
+Vtable for QFrame
+QFrame::_ZTV6QFrame: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QFrame)
+8 QFrame::metaObject
+12 QFrame::qt_metacast
+16 QFrame::qt_metacall
+20 QFrame::~QFrame
+24 QFrame::~QFrame
+28 QFrame::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QFrame::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QFrame::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI6QFrame)
+232 QFrame::_ZThn8_N6QFrameD1Ev
+236 QFrame::_ZThn8_N6QFrameD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QFrame
+ size=20 align=4
+ base size=20 base align=4
+QFrame (0xb4538940) 0
+ vptr=((& QFrame::_ZTV6QFrame) + 8u)
+ QWidget (0xb4557410) 0
+ primary-for QFrame (0xb4538940)
+ QObject (0xb4540690) 0
+ primary-for QWidget (0xb4557410)
+ QPaintDevice (0xb45406cc) 8
+ vptr=((& QFrame::_ZTV6QFrame) + 232u)
+
+Vtable for QAbstractScrollArea
+QAbstractScrollArea::_ZTV19QAbstractScrollArea: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+8 QAbstractScrollArea::metaObject
+12 QAbstractScrollArea::qt_metacast
+16 QAbstractScrollArea::qt_metacall
+20 QAbstractScrollArea::~QAbstractScrollArea
+24 QAbstractScrollArea::~QAbstractScrollArea
+28 QAbstractScrollArea::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractScrollArea::mousePressEvent
+84 QAbstractScrollArea::mouseReleaseEvent
+88 QAbstractScrollArea::mouseDoubleClickEvent
+92 QAbstractScrollArea::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractScrollArea::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractScrollArea::paintEvent
+128 QWidget::moveEvent
+132 QAbstractScrollArea::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractScrollArea::dragEnterEvent
+156 QAbstractScrollArea::dragMoveEvent
+160 QAbstractScrollArea::dragLeaveEvent
+164 QAbstractScrollArea::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractScrollArea::viewportEvent
+228 QAbstractScrollArea::scrollContentsBy
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+240 QAbstractScrollArea::_ZThn8_N19QAbstractScrollAreaD1Ev
+244 QAbstractScrollArea::_ZThn8_N19QAbstractScrollAreaD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractScrollArea
+ size=20 align=4
+ base size=20 base align=4
+QAbstractScrollArea (0xb4538c00) 0
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 8u)
+ QFrame (0xb4538c40) 0
+ primary-for QAbstractScrollArea (0xb4538c00)
+ QWidget (0xb456e000) 0
+ primary-for QFrame (0xb4538c40)
+ QObject (0xb45408e8) 0
+ primary-for QWidget (0xb456e000)
+ QPaintDevice (0xb4540924) 8
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 240u)
+
+Class QItemSelectionRange
+ size=8 align=4
+ base size=8 base align=4
+QItemSelectionRange (0xb4540b40) 0
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 18u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI19QItemSelectionModel)
+8 QItemSelectionModel::metaObject
+12 QItemSelectionModel::qt_metacast
+16 QItemSelectionModel::qt_metacall
+20 QItemSelectionModel::~QItemSelectionModel
+24 QItemSelectionModel::~QItemSelectionModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QItemSelectionModel::select
+60 QItemSelectionModel::select
+64 QItemSelectionModel::clear
+68 QItemSelectionModel::reset
+
+Class QItemSelectionModel
+ size=8 align=4
+ base size=8 base align=4
+QItemSelectionModel (0xb45899c0) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 8u)
+ QObject (0xb45a1bb8) 0
+ primary-for QItemSelectionModel (0xb45899c0)
+
+Class QItemSelection
+ size=4 align=4
+ base size=4 base align=4
+QItemSelection (0xb4589e80) 0
+ QList<QItemSelectionRange> (0xb45a1f78) 0
+
+Vtable for QValidator
+QValidator::_ZTV10QValidator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QValidator)
+8 QValidator::metaObject
+12 QValidator::qt_metacast
+16 QValidator::qt_metacall
+20 QValidator::~QValidator
+24 QValidator::~QValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 QValidator::fixup
+
+Class QValidator
+ size=8 align=4
+ base size=8 base align=4
+QValidator (0xb43f7000) 0
+ vptr=((& QValidator::_ZTV10QValidator) + 8u)
+ QObject (0xb43f312c) 0
+ primary-for QValidator (0xb43f7000)
+
+Vtable for QIntValidator
+QIntValidator::_ZTV13QIntValidator: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI13QIntValidator)
+8 QIntValidator::metaObject
+12 QIntValidator::qt_metacast
+16 QIntValidator::qt_metacall
+20 QIntValidator::~QIntValidator
+24 QIntValidator::~QIntValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QIntValidator::validate
+60 QIntValidator::fixup
+64 QIntValidator::setRange
+
+Class QIntValidator
+ size=16 align=4
+ base size=16 base align=4
+QIntValidator (0xb43f72c0) 0
+ vptr=((& QIntValidator::_ZTV13QIntValidator) + 8u)
+ QValidator (0xb43f7300) 0
+ primary-for QIntValidator (0xb43f72c0)
+ QObject (0xb43f3348) 0
+ primary-for QValidator (0xb43f7300)
+
+Vtable for QDoubleValidator
+QDoubleValidator::_ZTV16QDoubleValidator: 17u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QDoubleValidator)
+8 QDoubleValidator::metaObject
+12 QDoubleValidator::qt_metacast
+16 QDoubleValidator::qt_metacall
+20 QDoubleValidator::~QDoubleValidator
+24 QDoubleValidator::~QDoubleValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QDoubleValidator::validate
+60 QValidator::fixup
+64 QDoubleValidator::setRange
+
+Class QDoubleValidator
+ size=28 align=4
+ base size=28 base align=4
+QDoubleValidator (0xb43f75c0) 0
+ vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 8u)
+ QValidator (0xb43f7600) 0
+ primary-for QDoubleValidator (0xb43f75c0)
+ QObject (0xb43f34ec) 0
+ primary-for QValidator (0xb43f7600)
+
+Vtable for QRegExpValidator
+QRegExpValidator::_ZTV16QRegExpValidator: 16u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QRegExpValidator)
+8 QRegExpValidator::metaObject
+12 QRegExpValidator::qt_metacast
+16 QRegExpValidator::qt_metacall
+20 QRegExpValidator::~QRegExpValidator
+24 QRegExpValidator::~QRegExpValidator
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QRegExpValidator::validate
+60 QValidator::fixup
+
+Class QRegExpValidator
+ size=12 align=4
+ base size=12 base align=4
+QRegExpValidator (0xb43f7980) 0
+ vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 8u)
+ QValidator (0xb43f79c0) 0
+ primary-for QRegExpValidator (0xb43f7980)
+ QObject (0xb43f37bc) 0
+ primary-for QValidator (0xb43f79c0)
+
+Vtable for QAbstractSpinBox
+QAbstractSpinBox::_ZTV16QAbstractSpinBox: 68u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+8 QAbstractSpinBox::metaObject
+12 QAbstractSpinBox::qt_metacast
+16 QAbstractSpinBox::qt_metacall
+20 QAbstractSpinBox::~QAbstractSpinBox
+24 QAbstractSpinBox::~QAbstractSpinBox
+28 QAbstractSpinBox::event
+32 QObject::eventFilter
+36 QAbstractSpinBox::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractSpinBox::sizeHint
+68 QAbstractSpinBox::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractSpinBox::mousePressEvent
+84 QAbstractSpinBox::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QAbstractSpinBox::mouseMoveEvent
+96 QAbstractSpinBox::wheelEvent
+100 QAbstractSpinBox::keyPressEvent
+104 QAbstractSpinBox::keyReleaseEvent
+108 QAbstractSpinBox::focusInEvent
+112 QAbstractSpinBox::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractSpinBox::paintEvent
+128 QWidget::moveEvent
+132 QAbstractSpinBox::resizeEvent
+136 QAbstractSpinBox::closeEvent
+140 QAbstractSpinBox::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QAbstractSpinBox::showEvent
+172 QAbstractSpinBox::hideEvent
+176 QWidget::x11Event
+180 QAbstractSpinBox::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QAbstractSpinBox::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSpinBox::validate
+228 QAbstractSpinBox::fixup
+232 QAbstractSpinBox::stepBy
+236 QAbstractSpinBox::clear
+240 QAbstractSpinBox::stepEnabled
+244 (int (*)(...))-0x000000008
+248 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+252 QAbstractSpinBox::_ZThn8_N16QAbstractSpinBoxD1Ev
+256 QAbstractSpinBox::_ZThn8_N16QAbstractSpinBoxD0Ev
+260 QWidget::_ZThn8_NK7QWidget7devTypeEv
+264 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+268 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSpinBox
+ size=20 align=4
+ base size=20 base align=4
+QAbstractSpinBox (0xb43f7c40) 0
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 8u)
+ QWidget (0xb442b190) 0
+ primary-for QAbstractSpinBox (0xb43f7c40)
+ QObject (0xb43f3924) 0
+ primary-for QWidget (0xb442b190)
+ QPaintDevice (0xb43f3960) 8
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 252u)
+
+Class QIcon
+ size=4 align=4
+ base size=4 base align=4
+QIcon (0xb43f3c6c) 0
+
+Vtable for QAbstractSlider
+QAbstractSlider::_ZTV15QAbstractSlider: 64u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QAbstractSlider)
+8 QAbstractSlider::metaObject
+12 QAbstractSlider::qt_metacast
+16 QAbstractSlider::qt_metacall
+20 QAbstractSlider::~QAbstractSlider
+24 QAbstractSlider::~QAbstractSlider
+28 QAbstractSlider::event
+32 QObject::eventFilter
+36 QAbstractSlider::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QAbstractSlider::wheelEvent
+100 QAbstractSlider::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QAbstractSlider::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSlider::sliderChange
+228 (int (*)(...))-0x000000008
+232 (int (*)(...))(& _ZTI15QAbstractSlider)
+236 QAbstractSlider::_ZThn8_N15QAbstractSliderD1Ev
+240 QAbstractSlider::_ZThn8_N15QAbstractSliderD0Ev
+244 QWidget::_ZThn8_NK7QWidget7devTypeEv
+248 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+252 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractSlider
+ size=20 align=4
+ base size=20 base align=4
+QAbstractSlider (0xb445b440) 0
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 8u)
+ QWidget (0xb4477a50) 0
+ primary-for QAbstractSlider (0xb445b440)
+ QObject (0xb43f3ec4) 0
+ primary-for QWidget (0xb4477a50)
+ QPaintDevice (0xb43f3f00) 8
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 236u)
+
+Vtable for QSlider
+QSlider::_ZTV7QSlider: 64u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QSlider)
+8 QSlider::metaObject
+12 QSlider::qt_metacast
+16 QSlider::qt_metacall
+20 QSlider::~QSlider
+24 QSlider::~QSlider
+28 QSlider::event
+32 QObject::eventFilter
+36 QAbstractSlider::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QSlider::sizeHint
+68 QSlider::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QSlider::mousePressEvent
+84 QSlider::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QSlider::mouseMoveEvent
+96 QAbstractSlider::wheelEvent
+100 QAbstractSlider::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QSlider::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QAbstractSlider::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractSlider::sliderChange
+228 (int (*)(...))-0x000000008
+232 (int (*)(...))(& _ZTI7QSlider)
+236 QSlider::_ZThn8_N7QSliderD1Ev
+240 QSlider::_ZThn8_N7QSliderD0Ev
+244 QWidget::_ZThn8_NK7QWidget7devTypeEv
+248 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+252 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QSlider
+ size=20 align=4
+ base size=20 base align=4
+QSlider (0xb445b9c0) 0
+ vptr=((& QSlider::_ZTV7QSlider) + 8u)
+ QAbstractSlider (0xb445ba00) 0
+ primary-for QSlider (0xb445b9c0)
+ QWidget (0xb4492690) 0
+ primary-for QAbstractSlider (0xb445ba00)
+ QObject (0xb44901e0) 0
+ primary-for QWidget (0xb4492690)
+ QPaintDevice (0xb449021c) 8
+ vptr=((& QSlider::_ZTV7QSlider) + 236u)
+
+Vtable for QStyle
+QStyle::_ZTV6QStyle: 35u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI6QStyle)
+8 QStyle::metaObject
+12 QStyle::qt_metacast
+16 QStyle::qt_metacall
+20 QStyle::~QStyle
+24 QStyle::~QStyle
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QStyle::polish
+60 QStyle::unpolish
+64 QStyle::polish
+68 QStyle::unpolish
+72 QStyle::polish
+76 QStyle::itemTextRect
+80 QStyle::itemPixmapRect
+84 QStyle::drawItemText
+88 QStyle::drawItemPixmap
+92 QStyle::standardPalette
+96 __cxa_pure_virtual
+100 __cxa_pure_virtual
+104 __cxa_pure_virtual
+108 __cxa_pure_virtual
+112 __cxa_pure_virtual
+116 __cxa_pure_virtual
+120 __cxa_pure_virtual
+124 __cxa_pure_virtual
+128 __cxa_pure_virtual
+132 __cxa_pure_virtual
+136 __cxa_pure_virtual
+
+Class QStyle
+ size=8 align=4
+ base size=8 base align=4
+QStyle (0xb445bdc0) 0
+ vptr=((& QStyle::_ZTV6QStyle) + 8u)
+ QObject (0xb44904ec) 0
+ primary-for QStyle (0xb445bdc0)
+
+Vtable for QTabBar
+QTabBar::_ZTV7QTabBar: 67u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI7QTabBar)
+8 QTabBar::metaObject
+12 QTabBar::qt_metacast
+16 QTabBar::qt_metacall
+20 QTabBar::~QTabBar
+24 QTabBar::~QTabBar
+28 QTabBar::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QTabBar::sizeHint
+68 QTabBar::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTabBar::mousePressEvent
+84 QTabBar::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QTabBar::mouseMoveEvent
+96 QTabBar::wheelEvent
+100 QTabBar::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTabBar::paintEvent
+128 QWidget::moveEvent
+132 QTabBar::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QTabBar::showEvent
+172 QTabBar::hideEvent
+176 QWidget::x11Event
+180 QTabBar::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTabBar::tabSizeHint
+228 QTabBar::tabInserted
+232 QTabBar::tabRemoved
+236 QTabBar::tabLayoutChange
+240 (int (*)(...))-0x000000008
+244 (int (*)(...))(& _ZTI7QTabBar)
+248 QTabBar::_ZThn8_N7QTabBarD1Ev
+252 QTabBar::_ZThn8_N7QTabBarD0Ev
+256 QWidget::_ZThn8_NK7QWidget7devTypeEv
+260 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+264 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabBar
+ size=20 align=4
+ base size=20 base align=4
+QTabBar (0xb42d7340) 0
+ vptr=((& QTabBar::_ZTV7QTabBar) + 8u)
+ QWidget (0xb42f9aa0) 0
+ primary-for QTabBar (0xb42d7340)
+ QObject (0xb44908e8) 0
+ primary-for QWidget (0xb42f9aa0)
+ QPaintDevice (0xb4490924) 8
+ vptr=((& QTabBar::_ZTV7QTabBar) + 248u)
+
+Vtable for QTabWidget
+QTabWidget::_ZTV10QTabWidget: 65u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI10QTabWidget)
+8 QTabWidget::metaObject
+12 QTabWidget::qt_metacast
+16 QTabWidget::qt_metacall
+20 QTabWidget::~QTabWidget
+24 QTabWidget::~QTabWidget
+28 QTabWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QTabWidget::sizeHint
+68 QTabWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QTabWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTabWidget::paintEvent
+128 QWidget::moveEvent
+132 QTabWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QTabWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QTabWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTabWidget::tabInserted
+228 QTabWidget::tabRemoved
+232 (int (*)(...))-0x000000008
+236 (int (*)(...))(& _ZTI10QTabWidget)
+240 QTabWidget::_ZThn8_N10QTabWidgetD1Ev
+244 QTabWidget::_ZThn8_N10QTabWidgetD0Ev
+248 QWidget::_ZThn8_NK7QWidget7devTypeEv
+252 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+256 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTabWidget
+ size=20 align=4
+ base size=20 base align=4
+QTabWidget (0xb42d7640) 0
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 8u)
+ QWidget (0xb43281e0) 0
+ primary-for QTabWidget (0xb42d7640)
+ QObject (0xb4490b40) 0
+ primary-for QWidget (0xb43281e0)
+ QPaintDevice (0xb4490b7c) 8
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 240u)
+
+Vtable for QRubberBand
+QRubberBand::_ZTV11QRubberBand: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QRubberBand)
+8 QRubberBand::metaObject
+12 QRubberBand::qt_metacast
+16 QRubberBand::qt_metacall
+20 QRubberBand::~QRubberBand
+24 QRubberBand::~QRubberBand
+28 QRubberBand::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QRubberBand::paintEvent
+128 QRubberBand::moveEvent
+132 QRubberBand::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QRubberBand::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QRubberBand::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI11QRubberBand)
+232 QRubberBand::_ZThn8_N11QRubberBandD1Ev
+236 QRubberBand::_ZThn8_N11QRubberBandD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QRubberBand
+ size=20 align=4
+ base size=20 base align=4
+QRubberBand (0xb42d7e80) 0
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 8u)
+ QWidget (0xb4351550) 0
+ primary-for QRubberBand (0xb42d7e80)
+ QObject (0xb43560b4) 0
+ primary-for QWidget (0xb4351550)
+ QPaintDevice (0xb43560f0) 8
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 232u)
+
+Class QStyleOption
+ size=44 align=4
+ base size=44 base align=4
+QStyleOption (0xb4356528) 0
+
+Class QStyleOptionFocusRect
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionFocusRect (0xb4362300) 0
+ QStyleOption (0xb4356564) 0
+
+Class QStyleOptionFrame
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionFrame (0xb4362500) 0
+ QStyleOption (0xb43568e8) 0
+
+Class QStyleOptionFrameV2
+ size=56 align=4
+ base size=56 base align=4
+QStyleOptionFrameV2 (0xb4362700) 0
+ QStyleOptionFrame (0xb4362740) 0
+ QStyleOption (0xb4356c30) 0
+
+Class QStyleOptionFrameV3
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionFrameV3 (0xb4362c00) 0
+ QStyleOptionFrameV2 (0xb4362c40) 0
+ QStyleOptionFrame (0xb4362c80) 0
+ QStyleOption (0xb438b168) 0
+
+Class QStyleOptionTabWidgetFrame
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabWidgetFrame (0xb4362fc0) 0
+ QStyleOption (0xb438b564) 0
+
+Class QStyleOptionTabWidgetFrameV2
+ size=112 align=4
+ base size=112 base align=4
+QStyleOptionTabWidgetFrameV2 (0xb41a01c0) 0
+ QStyleOptionTabWidgetFrame (0xb41a0200) 0
+ QStyleOption (0xb438bbf4) 0
+
+Class QStyleOptionTabBarBase
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabBarBase (0xb41a0540) 0
+ QStyleOption (0xb41b00f0) 0
+
+Class QStyleOptionTabBarBaseV2
+ size=84 align=4
+ base size=81 base align=4
+QStyleOptionTabBarBaseV2 (0xb41a0740) 0
+ QStyleOptionTabBarBase (0xb41a0780) 0
+ QStyleOption (0xb41b05a0) 0
+
+Class QStyleOptionHeader
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionHeader (0xb41a0ac0) 0
+ QStyleOption (0xb41b0924) 0
+
+Class QStyleOptionButton
+ size=64 align=4
+ base size=64 base align=4
+QStyleOptionButton (0xb41a0d80) 0
+ QStyleOption (0xb41ca3fc) 0
+
+Class QStyleOptionTab
+ size=72 align=4
+ base size=72 base align=4
+QStyleOptionTab (0xb41dc100) 0
+ QStyleOption (0xb41cad20) 0
+
+Class QStyleOptionTabV2
+ size=80 align=4
+ base size=80 base align=4
+QStyleOptionTabV2 (0xb41dc4c0) 0
+ QStyleOptionTab (0xb41dc500) 0
+ QStyleOption (0xb4203744) 0
+
+Class QStyleOptionTabV3
+ size=100 align=4
+ base size=100 base align=4
+QStyleOptionTabV3 (0xb41dc840) 0
+ QStyleOptionTabV2 (0xb41dc880) 0
+ QStyleOptionTab (0xb41dc8c0) 0
+ QStyleOption (0xb4203ca8) 0
+
+Class QStyleOptionToolBar
+ size=68 align=4
+ base size=68 base align=4
+QStyleOptionToolBar (0xb41dccc0) 0
+ QStyleOption (0xb422f5a0) 0
+
+Class QStyleOptionProgressBar
+ size=68 align=4
+ base size=65 base align=4
+QStyleOptionProgressBar (0xb4258040) 0
+ QStyleOption (0xb422fc6c) 0
+
+Class QStyleOptionProgressBarV2
+ size=76 align=4
+ base size=74 base align=4
+QStyleOptionProgressBarV2 (0xb4258280) 0
+ QStyleOptionProgressBar (0xb42582c0) 0
+ QStyleOption (0xb425e3c0) 0
+
+Class QStyleOptionMenuItem
+ size=96 align=4
+ base size=96 base align=4
+QStyleOptionMenuItem (0xb4258340) 0
+ QStyleOption (0xb425e3fc) 0
+
+Class QStyleOptionQ3ListViewItem
+ size=64 align=4
+ base size=64 base align=4
+QStyleOptionQ3ListViewItem (0xb4258540) 0
+ QStyleOption (0xb425efb4) 0
+
+Class QStyleOptionQ3DockWindow
+ size=48 align=4
+ base size=46 base align=4
+QStyleOptionQ3DockWindow (0xb42588c0) 0
+ QStyleOption (0xb4277618) 0
+
+Class QStyleOptionDockWidget
+ size=52 align=4
+ base size=51 base align=4
+QStyleOptionDockWidget (0xb4258ac0) 0
+ QStyleOption (0xb4277960) 0
+
+Class QStyleOptionDockWidgetV2
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionDockWidgetV2 (0xb4258cc0) 0
+ QStyleOptionDockWidget (0xb4258d00) 0
+ QStyleOption (0xb4277f00) 0
+
+Class QStyleOptionViewItem
+ size=80 align=4
+ base size=77 base align=4
+QStyleOptionViewItem (0xb40ab040) 0
+ QStyleOption (0xb40aa348) 0
+
+Class QStyleOptionViewItemV2
+ size=84 align=4
+ base size=84 base align=4
+QStyleOptionViewItemV2 (0xb40ab2c0) 0
+ QStyleOptionViewItem (0xb40ab300) 0
+ QStyleOption (0xb40aac30) 0
+
+Class QStyleOptionViewItemV3
+ size=92 align=4
+ base size=92 base align=4
+QStyleOptionViewItemV3 (0xb40ab7c0) 0
+ QStyleOptionViewItemV2 (0xb40ab800) 0
+ QStyleOptionViewItem (0xb40ab840) 0
+ QStyleOption (0xb40c6258) 0
+
+Class QStyleOptionViewItemV4
+ size=128 align=4
+ base size=128 base align=4
+QStyleOptionViewItemV4 (0xb40abb80) 0
+ QStyleOptionViewItemV3 (0xb40abbc0) 0
+ QStyleOptionViewItemV2 (0xb40abc00) 0
+ QStyleOptionViewItem (0xb40abc40) 0
+ QStyleOption (0xb40c6708) 0
+
+Class QStyleOptionToolBox
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionToolBox (0xb40abf80) 0
+ QStyleOption (0xb40f5258) 0
+
+Class QStyleOptionToolBoxV2
+ size=60 align=4
+ base size=60 base align=4
+QStyleOptionToolBoxV2 (0xb40f9180) 0
+ QStyleOptionToolBox (0xb40f91c0) 0
+ QStyleOption (0xb40f5870) 0
+
+Class QStyleOptionRubberBand
+ size=52 align=4
+ base size=49 base align=4
+QStyleOptionRubberBand (0xb40f9500) 0
+ QStyleOption (0xb40f5dd4) 0
+
+Class QStyleOptionComplex
+ size=52 align=4
+ base size=52 base align=4
+QStyleOptionComplex (0xb40f9700) 0
+ QStyleOption (0xb410d12c) 0
+
+Class QStyleOptionSlider
+ size=104 align=4
+ base size=101 base align=4
+QStyleOptionSlider (0xb40f9980) 0
+ QStyleOptionComplex (0xb40f99c0) 0
+ QStyleOption (0xb410d5dc) 0
+
+Class QStyleOptionSpinBox
+ size=64 align=4
+ base size=61 base align=4
+QStyleOptionSpinBox (0xb40f9d00) 0
+ QStyleOptionComplex (0xb40f9d40) 0
+ QStyleOption (0xb410de88) 0
+
+Class QStyleOptionQ3ListView
+ size=84 align=4
+ base size=81 base align=4
+QStyleOptionQ3ListView (0xb40f9f80) 0
+ QStyleOptionComplex (0xb40f9fc0) 0
+ QStyleOption (0xb412330c) 0
+
+Class QStyleOptionToolButton
+ size=96 align=4
+ base size=96 base align=4
+QStyleOptionToolButton (0xb4128280) 0
+ QStyleOptionComplex (0xb41282c0) 0
+ QStyleOption (0xb4123c30) 0
+
+Class QStyleOptionComboBox
+ size=92 align=4
+ base size=92 base align=4
+QStyleOptionComboBox (0xb4128640) 0
+ QStyleOptionComplex (0xb4128680) 0
+ QStyleOption (0xb4154924) 0
+
+Class QStyleOptionTitleBar
+ size=68 align=4
+ base size=68 base align=4
+QStyleOptionTitleBar (0xb4128880) 0
+ QStyleOptionComplex (0xb41288c0) 0
+ QStyleOption (0xb417b21c) 0
+
+Class QStyleOptionGroupBox
+ size=88 align=4
+ base size=88 base align=4
+QStyleOptionGroupBox (0xb4128b00) 0
+ QStyleOptionComplex (0xb4128b40) 0
+ QStyleOption (0xb417b9d8) 0
+
+Class QStyleOptionSizeGrip
+ size=56 align=4
+ base size=56 base align=4
+QStyleOptionSizeGrip (0xb4128dc0) 0
+ QStyleOptionComplex (0xb4128e00) 0
+ QStyleOption (0xb418d294) 0
+
+Class QStyleOptionGraphicsItem
+ size=132 align=4
+ base size=132 base align=4
+QStyleOptionGraphicsItem (0xb3f93000) 0
+ QStyleOption (0xb418d564) 0
+
+Class QStyleHintReturn
+ size=8 align=4
+ base size=8 base align=4
+QStyleHintReturn (0xb418da50) 0
+
+Class QStyleHintReturnMask
+ size=12 align=4
+ base size=12 base align=4
+QStyleHintReturnMask (0xb3f93440) 0
+ QStyleHintReturn (0xb418da8c) 0
+
+Class QStyleHintReturnVariant
+ size=20 align=4
+ base size=20 base align=4
+QStyleHintReturnVariant (0xb3f934c0) 0
+ QStyleHintReturn (0xb418dac8) 0
+
+Vtable for QAbstractItemDelegate
+QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 21u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI21QAbstractItemDelegate)
+8 QAbstractItemDelegate::metaObject
+12 QAbstractItemDelegate::qt_metacast
+16 QAbstractItemDelegate::qt_metacall
+20 QAbstractItemDelegate::~QAbstractItemDelegate
+24 QAbstractItemDelegate::~QAbstractItemDelegate
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 __cxa_pure_virtual
+60 __cxa_pure_virtual
+64 QAbstractItemDelegate::createEditor
+68 QAbstractItemDelegate::setEditorData
+72 QAbstractItemDelegate::setModelData
+76 QAbstractItemDelegate::updateEditorGeometry
+80 QAbstractItemDelegate::editorEvent
+
+Class QAbstractItemDelegate
+ size=8 align=4
+ base size=8 base align=4
+QAbstractItemDelegate (0xb3f93740) 0
+ vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 8u)
+ QObject (0xb418db04) 0
+ primary-for QAbstractItemDelegate (0xb3f93740)
+
+Vtable for QAbstractItemView
+QAbstractItemView::_ZTV17QAbstractItemView: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QAbstractItemView)
+8 QAbstractItemView::metaObject
+12 QAbstractItemView::qt_metacast
+16 QAbstractItemView::qt_metacall
+20 QAbstractItemView::~QAbstractItemView
+24 QAbstractItemView::~QAbstractItemView
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QAbstractItemView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QAbstractItemView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QAbstractItemView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QAbstractScrollArea::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QAbstractItemView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QAbstractScrollArea::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 __cxa_pure_virtual
+248 __cxa_pure_virtual
+252 __cxa_pure_virtual
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QAbstractItemView::reset
+268 QAbstractItemView::setRootIndex
+272 QAbstractItemView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QAbstractItemView::dataChanged
+284 QAbstractItemView::rowsInserted
+288 QAbstractItemView::rowsAboutToBeRemoved
+292 QAbstractItemView::selectionChanged
+296 QAbstractItemView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QAbstractItemView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 __cxa_pure_virtual
+344 __cxa_pure_virtual
+348 __cxa_pure_virtual
+352 __cxa_pure_virtual
+356 __cxa_pure_virtual
+360 __cxa_pure_virtual
+364 QAbstractItemView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI17QAbstractItemView)
+392 QAbstractItemView::_ZThn8_N17QAbstractItemViewD1Ev
+396 QAbstractItemView::_ZThn8_N17QAbstractItemViewD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QAbstractItemView
+ size=20 align=4
+ base size=20 base align=4
+QAbstractItemView (0xb3f93980) 0
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 8u)
+ QAbstractScrollArea (0xb3f939c0) 0
+ primary-for QAbstractItemView (0xb3f93980)
+ QFrame (0xb3f93a00) 0
+ primary-for QAbstractScrollArea (0xb3f939c0)
+ QWidget (0xb3fbdb40) 0
+ primary-for QFrame (0xb3f93a00)
+ QObject (0xb418dc30) 0
+ primary-for QWidget (0xb3fbdb40)
+ QPaintDevice (0xb418dc6c) 8
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 392u)
+
+Vtable for QTreeView
+QTreeView::_ZTV9QTreeView: 105u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QTreeView)
+8 QTreeView::metaObject
+12 QTreeView::qt_metacast
+16 QTreeView::qt_metacall
+20 QTreeView::~QTreeView
+24 QTreeView::~QTreeView
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QTreeView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTreeView::mousePressEvent
+84 QTreeView::mouseReleaseEvent
+88 QTreeView::mouseDoubleClickEvent
+92 QTreeView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QTreeView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTreeView::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QTreeView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTreeView::viewportEvent
+228 QTreeView::scrollContentsBy
+232 QTreeView::setModel
+236 QTreeView::setSelectionModel
+240 QTreeView::keyboardSearch
+244 QTreeView::visualRect
+248 QTreeView::scrollTo
+252 QTreeView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QTreeView::sizeHintForColumn
+264 QTreeView::reset
+268 QTreeView::setRootIndex
+272 QTreeView::doItemsLayout
+276 QTreeView::selectAll
+280 QTreeView::dataChanged
+284 QTreeView::rowsInserted
+288 QTreeView::rowsAboutToBeRemoved
+292 QTreeView::selectionChanged
+296 QTreeView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QTreeView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QTreeView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QTreeView::moveCursor
+344 QTreeView::horizontalOffset
+348 QTreeView::verticalOffset
+352 QTreeView::isIndexHidden
+356 QTreeView::setSelection
+360 QTreeView::visualRegionForSelection
+364 QTreeView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 QTreeView::drawRow
+388 QTreeView::drawBranches
+392 (int (*)(...))-0x000000008
+396 (int (*)(...))(& _ZTI9QTreeView)
+400 QTreeView::_ZThn8_N9QTreeViewD1Ev
+404 QTreeView::_ZThn8_N9QTreeViewD0Ev
+408 QWidget::_ZThn8_NK7QWidget7devTypeEv
+412 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+416 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QTreeView
+ size=20 align=4
+ base size=20 base align=4
+QTreeView (0xb3f93e40) 0
+ vptr=((& QTreeView::_ZTV9QTreeView) + 8u)
+ QAbstractItemView (0xb3f93e80) 0
+ primary-for QTreeView (0xb3f93e40)
+ QAbstractScrollArea (0xb3f93ec0) 0
+ primary-for QAbstractItemView (0xb3f93e80)
+ QFrame (0xb3f93f00) 0
+ primary-for QAbstractScrollArea (0xb3f93ec0)
+ QWidget (0xb4002410) 0
+ primary-for QFrame (0xb3f93f00)
+ QObject (0xb418df78) 0
+ primary-for QWidget (0xb4002410)
+ QPaintDevice (0xb418dfb4) 8
+ vptr=((& QTreeView::_ZTV9QTreeView) + 400u)
+
+Class QHelpContentItem
+ size=4 align=4
+ base size=4 base align=4
+QHelpContentItem (0xb402d1e0) 0
+
+Vtable for QHelpContentModel
+QHelpContentModel::_ZTV17QHelpContentModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QHelpContentModel)
+8 QHelpContentModel::metaObject
+12 QHelpContentModel::qt_metacast
+16 QHelpContentModel::qt_metacall
+20 QHelpContentModel::~QHelpContentModel
+24 QHelpContentModel::~QHelpContentModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QHelpContentModel::index
+60 QHelpContentModel::parent
+64 QHelpContentModel::rowCount
+68 QHelpContentModel::columnCount
+72 QAbstractItemModel::hasChildren
+76 QHelpContentModel::data
+80 QAbstractItemModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractItemModel::dropMimeData
+112 QAbstractItemModel::supportedDropActions
+116 QAbstractItemModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QAbstractItemModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QAbstractItemModel::flags
+144 QAbstractItemModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QHelpContentModel
+ size=12 align=4
+ base size=12 base align=4
+QHelpContentModel (0xb402b200) 0
+ vptr=((& QHelpContentModel::_ZTV17QHelpContentModel) + 8u)
+ QAbstractItemModel (0xb402b240) 0
+ primary-for QHelpContentModel (0xb402b200)
+ QObject (0xb402d21c) 0
+ primary-for QAbstractItemModel (0xb402b240)
+
+Vtable for QHelpContentWidget
+QHelpContentWidget::_ZTV18QHelpContentWidget: 105u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI18QHelpContentWidget)
+8 QHelpContentWidget::metaObject
+12 QHelpContentWidget::qt_metacast
+16 QHelpContentWidget::qt_metacall
+20 QHelpContentWidget::~QHelpContentWidget
+24 QHelpContentWidget::~QHelpContentWidget
+28 QAbstractItemView::event
+32 QObject::eventFilter
+36 QTreeView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QTreeView::mousePressEvent
+84 QTreeView::mouseReleaseEvent
+88 QTreeView::mouseDoubleClickEvent
+92 QTreeView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QTreeView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QTreeView::paintEvent
+128 QWidget::moveEvent
+132 QAbstractItemView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QTreeView::dragMoveEvent
+160 QAbstractItemView::dragLeaveEvent
+164 QAbstractItemView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QTreeView::viewportEvent
+228 QTreeView::scrollContentsBy
+232 QTreeView::setModel
+236 QTreeView::setSelectionModel
+240 QTreeView::keyboardSearch
+244 QTreeView::visualRect
+248 QTreeView::scrollTo
+252 QTreeView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QTreeView::sizeHintForColumn
+264 QTreeView::reset
+268 QTreeView::setRootIndex
+272 QTreeView::doItemsLayout
+276 QTreeView::selectAll
+280 QTreeView::dataChanged
+284 QTreeView::rowsInserted
+288 QTreeView::rowsAboutToBeRemoved
+292 QTreeView::selectionChanged
+296 QTreeView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QTreeView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QTreeView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QTreeView::moveCursor
+344 QTreeView::horizontalOffset
+348 QTreeView::verticalOffset
+352 QTreeView::isIndexHidden
+356 QTreeView::setSelection
+360 QTreeView::visualRegionForSelection
+364 QTreeView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QAbstractItemView::startDrag
+380 QAbstractItemView::viewOptions
+384 QTreeView::drawRow
+388 QTreeView::drawBranches
+392 (int (*)(...))-0x000000008
+396 (int (*)(...))(& _ZTI18QHelpContentWidget)
+400 QHelpContentWidget::_ZThn8_N18QHelpContentWidgetD1Ev
+404 QHelpContentWidget::_ZThn8_N18QHelpContentWidgetD0Ev
+408 QWidget::_ZThn8_NK7QWidget7devTypeEv
+412 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+416 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpContentWidget
+ size=36 align=4
+ base size=36 base align=4
+QHelpContentWidget (0xb402b480) 0
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 8u)
+ QTreeView (0xb402b4c0) 0
+ primary-for QHelpContentWidget (0xb402b480)
+ QAbstractItemView (0xb402b500) 0
+ primary-for QTreeView (0xb402b4c0)
+ QAbstractScrollArea (0xb402b540) 0
+ primary-for QAbstractItemView (0xb402b500)
+ QFrame (0xb402b580) 0
+ primary-for QAbstractScrollArea (0xb402b540)
+ QWidget (0xb4037d20) 0
+ primary-for QFrame (0xb402b580)
+ QObject (0xb402d348) 0
+ primary-for QWidget (0xb4037d20)
+ QPaintDevice (0xb402d384) 8
+ vptr=((& QHelpContentWidget::_ZTV18QHelpContentWidget) + 400u)
+
+Vtable for QHelpEngineCore
+QHelpEngineCore::_ZTV15QHelpEngineCore: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QHelpEngineCore)
+8 QHelpEngineCore::metaObject
+12 QHelpEngineCore::qt_metacast
+16 QHelpEngineCore::qt_metacall
+20 QHelpEngineCore::~QHelpEngineCore
+24 QHelpEngineCore::~QHelpEngineCore
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpEngineCore
+ size=12 align=4
+ base size=12 base align=4
+QHelpEngineCore (0xb402b7c0) 0
+ vptr=((& QHelpEngineCore::_ZTV15QHelpEngineCore) + 8u)
+ QObject (0xb402d4b0) 0
+ primary-for QHelpEngineCore (0xb402b7c0)
+
+Vtable for QHelpEngine
+QHelpEngine::_ZTV11QHelpEngine: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI11QHelpEngine)
+8 QHelpEngine::metaObject
+12 QHelpEngine::qt_metacast
+16 QHelpEngine::qt_metacall
+20 QHelpEngine::~QHelpEngine
+24 QHelpEngine::~QHelpEngine
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpEngine
+ size=16 align=4
+ base size=16 base align=4
+QHelpEngine (0xb402ba00) 0
+ vptr=((& QHelpEngine::_ZTV11QHelpEngine) + 8u)
+ QHelpEngineCore (0xb402ba40) 0
+ primary-for QHelpEngine (0xb402ba00)
+ QObject (0xb402d5dc) 0
+ primary-for QHelpEngineCore (0xb402ba40)
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QStringListModel)
+8 QStringListModel::metaObject
+12 QStringListModel::qt_metacast
+16 QStringListModel::qt_metacall
+20 QStringListModel::~QStringListModel
+24 QStringListModel::~QStringListModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 QStringListModel::rowCount
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 QStringListModel::data
+80 QStringListModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QStringListModel::supportedDropActions
+116 QStringListModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QStringListModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QStringListModel::flags
+144 QStringListModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QStringListModel
+ size=12 align=4
+ base size=12 base align=4
+QStringListModel (0xb402bc80) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 8u)
+ QAbstractListModel (0xb402bcc0) 0
+ primary-for QStringListModel (0xb402bc80)
+ QAbstractItemModel (0xb402bd00) 0
+ primary-for QAbstractListModel (0xb402bcc0)
+ QObject (0xb402d708) 0
+ primary-for QAbstractItemModel (0xb402bd00)
+
+Vtable for QListView
+QListView::_ZTV9QListView: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI9QListView)
+8 QListView::metaObject
+12 QListView::qt_metacast
+16 QListView::qt_metacall
+20 QListView::~QListView
+24 QListView::~QListView
+28 QListView::event
+32 QObject::eventFilter
+36 QListView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QListView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QListView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QListView::paintEvent
+128 QWidget::moveEvent
+132 QListView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QListView::dragMoveEvent
+160 QListView::dragLeaveEvent
+164 QListView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QListView::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 QListView::visualRect
+248 QListView::scrollTo
+252 QListView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QListView::reset
+268 QListView::setRootIndex
+272 QListView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QListView::dataChanged
+284 QListView::rowsInserted
+288 QListView::rowsAboutToBeRemoved
+292 QListView::selectionChanged
+296 QListView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QListView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QListView::moveCursor
+344 QListView::horizontalOffset
+348 QListView::verticalOffset
+352 QListView::isIndexHidden
+356 QListView::setSelection
+360 QListView::visualRegionForSelection
+364 QListView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QListView::startDrag
+380 QListView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI9QListView)
+392 QListView::_ZThn8_N9QListViewD1Ev
+396 QListView::_ZThn8_N9QListViewD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QListView
+ size=20 align=4
+ base size=20 base align=4
+QListView (0xb402bf40) 0
+ vptr=((& QListView::_ZTV9QListView) + 8u)
+ QAbstractItemView (0xb402bf80) 0
+ primary-for QListView (0xb402bf40)
+ QAbstractScrollArea (0xb402bfc0) 0
+ primary-for QAbstractItemView (0xb402bf80)
+ QFrame (0xb4071000) 0
+ primary-for QAbstractScrollArea (0xb402bfc0)
+ QWidget (0xb406e2d0) 0
+ primary-for QFrame (0xb4071000)
+ QObject (0xb402d834) 0
+ primary-for QWidget (0xb406e2d0)
+ QPaintDevice (0xb402d870) 8
+ vptr=((& QListView::_ZTV9QListView) + 392u)
+
+Vtable for QHelpIndexModel
+QHelpIndexModel::_ZTV15QHelpIndexModel: 42u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI15QHelpIndexModel)
+8 QHelpIndexModel::metaObject
+12 QHelpIndexModel::qt_metacast
+16 QHelpIndexModel::qt_metacall
+20 QHelpIndexModel::~QHelpIndexModel
+24 QHelpIndexModel::~QHelpIndexModel
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QAbstractListModel::index
+60 QAbstractListModel::parent
+64 QStringListModel::rowCount
+68 QAbstractListModel::columnCount
+72 QAbstractListModel::hasChildren
+76 QStringListModel::data
+80 QStringListModel::setData
+84 QAbstractItemModel::headerData
+88 QAbstractItemModel::setHeaderData
+92 QAbstractItemModel::itemData
+96 QAbstractItemModel::setItemData
+100 QAbstractItemModel::mimeTypes
+104 QAbstractItemModel::mimeData
+108 QAbstractListModel::dropMimeData
+112 QStringListModel::supportedDropActions
+116 QStringListModel::insertRows
+120 QAbstractItemModel::insertColumns
+124 QStringListModel::removeRows
+128 QAbstractItemModel::removeColumns
+132 QAbstractItemModel::fetchMore
+136 QAbstractItemModel::canFetchMore
+140 QStringListModel::flags
+144 QStringListModel::sort
+148 QAbstractItemModel::buddy
+152 QAbstractItemModel::match
+156 QAbstractItemModel::span
+160 QAbstractItemModel::submit
+164 QAbstractItemModel::revert
+
+Class QHelpIndexModel
+ size=16 align=4
+ base size=16 base align=4
+QHelpIndexModel (0xb4071300) 0
+ vptr=((& QHelpIndexModel::_ZTV15QHelpIndexModel) + 8u)
+ QStringListModel (0xb4071340) 0
+ primary-for QHelpIndexModel (0xb4071300)
+ QAbstractListModel (0xb4071380) 0
+ primary-for QStringListModel (0xb4071340)
+ QAbstractItemModel (0xb40713c0) 0
+ primary-for QAbstractListModel (0xb4071380)
+ QObject (0xb402da8c) 0
+ primary-for QAbstractItemModel (0xb40713c0)
+
+Vtable for QHelpIndexWidget
+QHelpIndexWidget::_ZTV16QHelpIndexWidget: 103u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+8 QHelpIndexWidget::metaObject
+12 QHelpIndexWidget::qt_metacast
+16 QHelpIndexWidget::qt_metacall
+20 QHelpIndexWidget::~QHelpIndexWidget
+24 QHelpIndexWidget::~QHelpIndexWidget
+28 QListView::event
+32 QObject::eventFilter
+36 QListView::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QAbstractScrollArea::sizeHint
+68 QAbstractScrollArea::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QAbstractItemView::mousePressEvent
+84 QListView::mouseReleaseEvent
+88 QAbstractItemView::mouseDoubleClickEvent
+92 QListView::mouseMoveEvent
+96 QAbstractScrollArea::wheelEvent
+100 QAbstractItemView::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QAbstractItemView::focusInEvent
+112 QAbstractItemView::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QListView::paintEvent
+128 QWidget::moveEvent
+132 QListView::resizeEvent
+136 QWidget::closeEvent
+140 QAbstractScrollArea::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QAbstractItemView::dragEnterEvent
+156 QListView::dragMoveEvent
+160 QListView::dragLeaveEvent
+164 QListView::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QFrame::changeEvent
+184 QWidget::metric
+188 QAbstractItemView::inputMethodEvent
+192 QAbstractItemView::inputMethodQuery
+196 QAbstractItemView::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 QAbstractItemView::viewportEvent
+228 QListView::scrollContentsBy
+232 QAbstractItemView::setModel
+236 QAbstractItemView::setSelectionModel
+240 QAbstractItemView::keyboardSearch
+244 QListView::visualRect
+248 QListView::scrollTo
+252 QListView::indexAt
+256 QAbstractItemView::sizeHintForRow
+260 QAbstractItemView::sizeHintForColumn
+264 QListView::reset
+268 QListView::setRootIndex
+272 QListView::doItemsLayout
+276 QAbstractItemView::selectAll
+280 QListView::dataChanged
+284 QListView::rowsInserted
+288 QListView::rowsAboutToBeRemoved
+292 QListView::selectionChanged
+296 QListView::currentChanged
+300 QAbstractItemView::updateEditorData
+304 QAbstractItemView::updateEditorGeometries
+308 QListView::updateGeometries
+312 QAbstractItemView::verticalScrollbarAction
+316 QAbstractItemView::horizontalScrollbarAction
+320 QAbstractItemView::verticalScrollbarValueChanged
+324 QAbstractItemView::horizontalScrollbarValueChanged
+328 QAbstractItemView::closeEditor
+332 QAbstractItemView::commitData
+336 QAbstractItemView::editorDestroyed
+340 QListView::moveCursor
+344 QListView::horizontalOffset
+348 QListView::verticalOffset
+352 QListView::isIndexHidden
+356 QListView::setSelection
+360 QListView::visualRegionForSelection
+364 QListView::selectedIndexes
+368 QAbstractItemView::edit
+372 QAbstractItemView::selectionCommand
+376 QListView::startDrag
+380 QListView::viewOptions
+384 (int (*)(...))-0x000000008
+388 (int (*)(...))(& _ZTI16QHelpIndexWidget)
+392 QHelpIndexWidget::_ZThn8_N16QHelpIndexWidgetD1Ev
+396 QHelpIndexWidget::_ZThn8_N16QHelpIndexWidgetD0Ev
+400 QWidget::_ZThn8_NK7QWidget7devTypeEv
+404 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+408 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpIndexWidget
+ size=20 align=4
+ base size=20 base align=4
+QHelpIndexWidget (0xb4071600) 0
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 8u)
+ QListView (0xb4071640) 0
+ primary-for QHelpIndexWidget (0xb4071600)
+ QAbstractItemView (0xb4071680) 0
+ primary-for QListView (0xb4071640)
+ QAbstractScrollArea (0xb40716c0) 0
+ primary-for QAbstractItemView (0xb4071680)
+ QFrame (0xb4071700) 0
+ primary-for QAbstractScrollArea (0xb40716c0)
+ QWidget (0xb3e94870) 0
+ primary-for QFrame (0xb4071700)
+ QObject (0xb402dbb8) 0
+ primary-for QWidget (0xb3e94870)
+ QPaintDevice (0xb402dbf4) 8
+ vptr=((& QHelpIndexWidget::_ZTV16QHelpIndexWidget) + 392u)
+
+Class QHelpSearchQuery
+ size=8 align=4
+ base size=8 base align=4
+QHelpSearchQuery (0xb402dd20) 0
+
+Vtable for QHelpSearchEngine
+QHelpSearchEngine::_ZTV17QHelpSearchEngine: 14u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI17QHelpSearchEngine)
+8 QHelpSearchEngine::metaObject
+12 QHelpSearchEngine::qt_metacast
+16 QHelpSearchEngine::qt_metacall
+20 QHelpSearchEngine::~QHelpSearchEngine
+24 QHelpSearchEngine::~QHelpSearchEngine
+28 QObject::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+
+Class QHelpSearchEngine
+ size=12 align=4
+ base size=12 base align=4
+QHelpSearchEngine (0xb4071b00) 0
+ vptr=((& QHelpSearchEngine::_ZTV17QHelpSearchEngine) + 8u)
+ QObject (0xb3eac258) 0
+ primary-for QHelpSearchEngine (0xb4071b00)
+
+Vtable for QHelpSearchQueryWidget
+QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+8 QHelpSearchQueryWidget::metaObject
+12 QHelpSearchQueryWidget::qt_metacast
+16 QHelpSearchQueryWidget::qt_metacall
+20 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+24 QHelpSearchQueryWidget::~QHelpSearchQueryWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QHelpSearchQueryWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QHelpSearchQueryWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI22QHelpSearchQueryWidget)
+232 QHelpSearchQueryWidget::_ZThn8_N22QHelpSearchQueryWidgetD1Ev
+236 QHelpSearchQueryWidget::_ZThn8_N22QHelpSearchQueryWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchQueryWidget
+ size=24 align=4
+ base size=24 base align=4
+QHelpSearchQueryWidget (0xb4071d40) 0
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 8u)
+ QWidget (0xb3eb2eb0) 0
+ primary-for QHelpSearchQueryWidget (0xb4071d40)
+ QObject (0xb3eac384) 0
+ primary-for QWidget (0xb3eb2eb0)
+ QPaintDevice (0xb3eac3c0) 8
+ vptr=((& QHelpSearchQueryWidget::_ZTV22QHelpSearchQueryWidget) + 232u)
+
+Vtable for QHelpSearchResultWidget
+QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget: 63u entries
+0 (int (*)(...))0
+4 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+8 QHelpSearchResultWidget::metaObject
+12 QHelpSearchResultWidget::qt_metacast
+16 QHelpSearchResultWidget::qt_metacall
+20 QHelpSearchResultWidget::~QHelpSearchResultWidget
+24 QHelpSearchResultWidget::~QHelpSearchResultWidget
+28 QWidget::event
+32 QObject::eventFilter
+36 QObject::timerEvent
+40 QObject::childEvent
+44 QObject::customEvent
+48 QObject::connectNotify
+52 QObject::disconnectNotify
+56 QWidget::devType
+60 QWidget::setVisible
+64 QWidget::sizeHint
+68 QWidget::minimumSizeHint
+72 QWidget::heightForWidth
+76 QWidget::paintEngine
+80 QWidget::mousePressEvent
+84 QWidget::mouseReleaseEvent
+88 QWidget::mouseDoubleClickEvent
+92 QWidget::mouseMoveEvent
+96 QWidget::wheelEvent
+100 QWidget::keyPressEvent
+104 QWidget::keyReleaseEvent
+108 QWidget::focusInEvent
+112 QWidget::focusOutEvent
+116 QWidget::enterEvent
+120 QWidget::leaveEvent
+124 QWidget::paintEvent
+128 QWidget::moveEvent
+132 QWidget::resizeEvent
+136 QWidget::closeEvent
+140 QWidget::contextMenuEvent
+144 QWidget::tabletEvent
+148 QWidget::actionEvent
+152 QWidget::dragEnterEvent
+156 QWidget::dragMoveEvent
+160 QWidget::dragLeaveEvent
+164 QWidget::dropEvent
+168 QWidget::showEvent
+172 QWidget::hideEvent
+176 QWidget::x11Event
+180 QHelpSearchResultWidget::changeEvent
+184 QWidget::metric
+188 QWidget::inputMethodEvent
+192 QWidget::inputMethodQuery
+196 QWidget::focusNextPrevChild
+200 QWidget::styleChange
+204 QWidget::enabledChange
+208 QWidget::paletteChange
+212 QWidget::fontChange
+216 QWidget::windowActivationChange
+220 QWidget::languageChange
+224 (int (*)(...))-0x000000008
+228 (int (*)(...))(& _ZTI23QHelpSearchResultWidget)
+232 QHelpSearchResultWidget::_ZThn8_N23QHelpSearchResultWidgetD1Ev
+236 QHelpSearchResultWidget::_ZThn8_N23QHelpSearchResultWidgetD0Ev
+240 QWidget::_ZThn8_NK7QWidget7devTypeEv
+244 QWidget::_ZThn8_NK7QWidget11paintEngineEv
+248 QWidget::_ZThn8_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+
+Class QHelpSearchResultWidget
+ size=24 align=4
+ base size=24 base align=4
+QHelpSearchResultWidget (0xb4071f80) 0
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 8u)
+ QWidget (0xb3eba5f0) 0
+ primary-for QHelpSearchResultWidget (0xb4071f80)
+ QObject (0xb3eac4ec) 0
+ primary-for QWidget (0xb3eba5f0)
+ QPaintDevice (0xb3eac528) 8
+ vptr=((& QHelpSearchResultWidget::_ZTV23QHelpSearchResultWidget) + 232u)
+
diff --git a/tests/auto/linguist/lconvert/.gitignore b/tests/auto/linguist/lconvert/.gitignore
new file mode 100644
index 000000000..042d7ac30
--- /dev/null
+++ b/tests/auto/linguist/lconvert/.gitignore
@@ -0,0 +1,2 @@
+tst_lconvert
+data/plural-?.po
diff --git a/tests/auto/linguist/lconvert/data/codec-cp1252.ts b/tests/auto/linguist/lconvert/data/codec-cp1252.ts
new file mode 100644
index 000000000..5ffa2f3d6
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/codec-cp1252.ts
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>windows-1252</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>random ascii only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut ü &amp;uuml;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>random ascii only in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message utf8="true">
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut ü &amp;uuml; in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/codec-utf8.ts b/tests/auto/linguist/lconvert/data/codec-utf8.ts
new file mode 100644
index 000000000..0ebdbfdd6
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/codec-utf8.ts
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>random ascii only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut ü &amp;uuml;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>random ascii only in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut ü &amp;uuml; in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/dual-encoding.ts b/tests/auto/linguist/lconvert/data/dual-encoding.ts
new file mode 100644
index 000000000..5023a04d9
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/dual-encoding.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message utf8="both">
+ <source>Mühsam</source>
+ <translation>tedious</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/endless-po-loop.ts b/tests/auto/linguist/lconvert/data/endless-po-loop.ts
new file mode 100644
index 000000000..8aa7215d1
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/endless-po-loop.ts
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de">
+<context>
+ <name>Assistant</name>
+ <message>
+ <source>This is some text which introduces the DonauDampfSchifffahrtsKapitaensMuetzeMitKomischenUltraViolettenFransenUndEinemKnopf</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="this/is/a/really/really/absurdly/no,/grotesquely/long/path/supposed/to/blow/up.cpp" line="20"/>
+ <source>%n document(s) found.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/makeplurals.pl b/tests/auto/linguist/lconvert/data/makeplurals.pl
new file mode 100755
index 000000000..3a29bac21
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/makeplurals.pl
@@ -0,0 +1,86 @@
+#!/usr/bin/env perl
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+sub makeit2($$$)
+{
+ for (my $i = 0; $i < (1 << $_[0]); $i++) {
+ print OUTFILE "\n";
+ print OUTFILE "$_[2]\n" unless $3 eq "";
+ print OUTFILE "msgid \"singular $_[1] $i\"\n";
+ print OUTFILE "msgid_plural \"plural $_[1] $i\"\n";
+ for (my $j = 0; $j < $_[0]; $j++) {
+ my $tr;
+ if (($i & (1 << $j)) == 0) {
+ $tr = "translated $_[1] $i $j";
+ }
+ print OUTFILE "msgstr[$j] \"$tr\"\n";
+ }
+ }
+}
+
+sub makeit($$$)
+{
+ open OUTFILE, ">${OUTDIR}plural-$_[0].po" || die "cannot write file in $OUTDIR";
+ print OUTFILE <<EOF;
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\\n"
+"Content-Type: text/plain; charset=UTF-8\\n"
+"Content-Transfer-Encoding: 8bit\\n"
+"X-FooBar: yup\\n"
+"X-Language: $_[1]\\n"
+"Plural-Forms: $_[2]\\n"
+EOF
+ makeit2($_[0], "one", "");
+ makeit2($_[0], "two", "#, fuzzy
+#| msgid \"old untranslated one\"");
+ makeit2($_[0], "three", "#, fuzzy
+#| msgid \"old untranslated two\"
+#| msgid_plural \"old untranslated plural two\"");
+ makeit2($_[0], "four", "#, fuzzy
+#| msgid_plural \"old untranslated only plural three\"");
+}
+
+$OUTDIR = $ARGV[0];
+makeit(1, "zh_CN", "nplurals=1; plural=0;");
+makeit(2, "de_DE", "nplurals=2; plural=(n != 1);");
+makeit(3, "pl_PL", "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/tests/auto/linguist/lconvert/data/msgid.ts b/tests/auto/linguist/lconvert/data/msgid.ts
new file mode 100644
index 000000000..39401d884
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/msgid.ts
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Dialog2</name>
+ <message numerus="yes">
+ <source>%n files</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message id="this_is_some_id" numerus="yes">
+ <source>%n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Age: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="this_is_another_id">
+ <source>func3</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/phrasebook.qph b/tests/auto/linguist/lconvert/data/phrasebook.qph
new file mode 100644
index 000000000..847a53b50
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/phrasebook.qph
@@ -0,0 +1,21 @@
+<!DOCTYPE QPH>
+<QPH language="de" sourcelanguage="en_US">
+<phrase>
+ <source>About</source>
+ <target>Info</target>
+</phrase>
+<phrase>
+ <source>adornment</source>
+ <target>Zubehör</target>
+</phrase>
+<phrase>
+ <source>barrel button</source>
+ <target>Pen-Knopf</target>
+ <definition>pen</definition>
+</phrase>
+<phrase>
+ <source>foo &amp; bar</source>
+ <target>Foo &amp; bar</target>
+ <definition>&lt;test&gt;übergroß</definition>
+</phrase>
+</QPH>
diff --git a/tests/auto/linguist/lconvert/data/plurals-cn.ts b/tests/auto/linguist/lconvert/data/plurals-cn.ts
new file mode 100644
index 000000000..966ec7720
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/plurals-cn.ts
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="cn">
+<context>
+ <name>Assistant</name>
+ <message>
+ <source>Source</source>
+ <translation>Translation</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n document(s) found.</source>
+ <translation>
+ <numerusform>1 Dokument gefunden.</numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/plurals-de.ts b/tests/auto/linguist/lconvert/data/plurals-de.ts
new file mode 100644
index 000000000..6cbadff44
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/plurals-de.ts
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de">
+<context>
+ <name>Assistant</name>
+ <message>
+ <source>Not plural</source>
+ <translation>Kein plural</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n document(s) found.</source>
+ <translation>
+ <numerusform>1 Dokument gefunden.</numerusform>
+ <numerusform>%n Dokumente gefunden.</numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/relative.ts b/tests/auto/linguist/lconvert/data/relative.ts
new file mode 100644
index 000000000..b8eaaca96
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/relative.ts
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="foo.cpp" line="+13"/>
+ <source>This is the first entry.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>And a second one on the same line.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>This tr is new.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location line="+16"/>
+ <source>This one moved in from another file.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="-2"/>
+ <source>Just as this one.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location filename="bar.cpp" line="+100"/>
+ <source>Another alien.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>They are coming!</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>They are everywhere!</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="bar.cpp" line="+20"/>
+ <source>An earthling again.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="-5"/>
+ <source>This is from the bottom, too.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Third string from the bottom.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Fourth one!</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="-9"/>
+ <source>This string did move from the bottom.</source>
+ <translation></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/singular.po b/tests/auto/linguist/lconvert/data/singular.po
new file mode 100644
index 000000000..9a2c91c8f
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/singular.po
@@ -0,0 +1,42 @@
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "untranslated one"
+msgstr "translated"
+
+#, fuzzy
+#| msgid "old untranslated"
+msgid "untranslated two"
+msgstr "translated"
+
+#| msgid "old untranslated"
+msgid "untranslated two b"
+msgstr ""
+
+#, fuzzy
+#| msgid "old untranslated"
+#| msgid_plural "old untranslated plural"
+msgid "untranslated three"
+msgstr "translated"
+
+#| msgid "old untranslated"
+#| msgid_plural "old untranslated plural"
+msgid "untranslated three b"
+msgstr ""
+
+#, fuzzy
+#| msgid_plural "old untranslated only plural"
+msgid "untranslated four"
+msgstr "translated"
+
+#| msgid_plural "old untranslated only plural"
+msgid "untranslated four b"
+msgstr ""
+
+#, fuzzy
+#| msgctxt "old context"
+msgid "untranslated five"
+msgstr "translated"
diff --git a/tests/auto/linguist/lconvert/data/test-broken-utf8.po b/tests/auto/linguist/lconvert/data/test-broken-utf8.po
new file mode 100644
index 000000000..20b58a016
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-broken-utf8.po
@@ -0,0 +1,9 @@
+# no comment
+msgid ""
+msgstr ""
+
+msgid "this works"
+msgstr "das geht: ä"
+
+msgid "this is broken"
+msgstr "das ist kaputt: Ãi"
diff --git a/tests/auto/linguist/lconvert/data/test-broken-utf8.po.out b/tests/auto/linguist/lconvert/data/test-broken-utf8.po.out
new file mode 100644
index 000000000..20fee3315
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-broken-utf8.po.out
@@ -0,0 +1,12 @@
+# no comment
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "this works"
+msgstr "das geht: ä"
+
+msgid "this is broken"
+msgstr "das ist kaputt: �i"
diff --git a/tests/auto/linguist/lconvert/data/test-developer-comment.po b/tests/auto/linguist/lconvert/data/test-developer-comment.po
new file mode 100644
index 000000000..787f312ae
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-developer-comment.po
@@ -0,0 +1,23 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. I'm a clever developer. Right? Uhm ...
+msgid "User %u will log in in %t"
+msgstr "用户 %u 将在 %t 秒åŽç™»å½•"
diff --git a/tests/auto/linguist/lconvert/data/test-empty-comment.po b/tests/auto/linguist/lconvert/data/test-empty-comment.po
new file mode 100644
index 000000000..ce74c46ca
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-empty-comment.po
@@ -0,0 +1,24 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#
+#: themer/kdmlabel.cpp:236
+msgid "User %u will log in in %t"
+msgstr "用户 %u 将在 %t 秒åŽç™»å½•"
diff --git a/tests/auto/linguist/lconvert/data/test-escapes.po b/tests/auto/linguist/lconvert/data/test-escapes.po
new file mode 100644
index 000000000..059dc587c
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-escapes.po
@@ -0,0 +1,11 @@
+msgid ""
+msgstr ""
+
+msgid "this comes\non a new line"
+msgstr "yup"
+
+msgid "come to \"quote\" me"
+msgstr "sure?"
+
+msgid "\x1a\45\r\t\v\a\b"
+msgstr "yup"
diff --git a/tests/auto/linguist/lconvert/data/test-escapes.po.out b/tests/auto/linguist/lconvert/data/test-escapes.po.out
new file mode 100644
index 000000000..055fa7901
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-escapes.po.out
@@ -0,0 +1,16 @@
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid ""
+"this comes\n"
+"on a new line"
+msgstr "yup"
+
+msgid "come to \"quote\" me"
+msgstr "sure?"
+
+msgid "\x1a%\r\t\v\a\b"
+msgstr "yup"
diff --git a/tests/auto/linguist/lconvert/data/test-kde-ctxt.po b/tests/auto/linguist/lconvert/data/test-kde-ctxt.po
new file mode 100644
index 000000000..b51053895
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-kde-ctxt.po
@@ -0,0 +1,25 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: kgdialog.cpp:231
+#, kde-format
+msgctxt "session (location)"
+msgid "%1 (%2)"
+msgstr "%1(%2)"
diff --git a/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po b/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po
new file mode 100644
index 000000000..fc9ae7700
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po
@@ -0,0 +1,31 @@
+# translation of kdmgreet.po to German
+# Ãœbersetzung von kdmgreet.po ins Deutsche
+# Copyright (C)
+# Thomas Diehl <thd@kde.org>, 2002, 2003, 2004.
+# Stephan Johach <hunsum@gmx.de>, 2005.
+# Thomas Reitelbach <tr@erdfunkstelle.de>, 2005, 2006, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2007-12-06 20:50+0100\n"
+"Last-Translator: Thomas Reitelbach <tr@erdfunkstelle.de>\n"
+"Language-Team: German <kde-i18n-de@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: kgverify.cpp:459
+#, fuzzy, kde-format
+#| msgid ""
+#| "Logging in %1 ...\n"
+#| "\n"
+msgid ""
+"Logging in %1...\n"
+"\n"
+msgstr ""
+"%1 wird angemeldet ...\n"
+"\n"
diff --git a/tests/auto/linguist/lconvert/data/test-kde-multiline.po b/tests/auto/linguist/lconvert/data/test-kde-multiline.po
new file mode 100644
index 000000000..662c02e25
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-kde-multiline.po
@@ -0,0 +1,32 @@
+# translation of kdmgreet.po to German
+# Ãœbersetzung von kdmgreet.po ins Deutsche
+# Copyright (C)
+# Thomas Diehl <thd@kde.org>, 2002, 2003, 2004.
+# Stephan Johach <hunsum@gmx.de>, 2005.
+# Thomas Reitelbach <tr@erdfunkstelle.de>, 2005, 2006, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2007-12-06 20:50+0100\n"
+"Last-Translator: Thomas Reitelbach <tr@erdfunkstelle.de>\n"
+"Language-Team: German <kde-i18n-de@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: kdmshutdown.cpp:706
+#, kde-format
+msgid ""
+"Owner: %1\n"
+"Type: %2%5\n"
+"Start: %3\n"
+"Timeout: %4"
+msgstr ""
+"Eigentümer: %1\n"
+"Typ: %2%5\n"
+"Start: %3\n"
+"Zeitlimit: %4"
diff --git a/tests/auto/linguist/lconvert/data/test-kde-plurals.po b/tests/auto/linguist/lconvert/data/test-kde-plurals.po
new file mode 100644
index 000000000..9f74de0a1
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-kde-plurals.po
@@ -0,0 +1,27 @@
+# translation of kdmgreet.po to German
+# Ãœbersetzung von kdmgreet.po ins Deutsche
+# Copyright (C)
+# Thomas Diehl <thd@kde.org>, 2002, 2003, 2004.
+# Stephan Johach <hunsum@gmx.de>, 2005.
+# Thomas Reitelbach <tr@erdfunkstelle.de>, 2005, 2006, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2007-12-06 20:50+0100\n"
+"Last-Translator: Thomas Reitelbach <tr@erdfunkstelle.de>\n"
+"Language-Team: German <kde-i18n-de@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Language: de_DE\n"
+
+#: kgverify.cpp:505
+#, kde-format
+msgid "Your account expires tomorrow."
+msgid_plural "Your account expires in %1 days."
+msgstr[0] "Ihre Zugangsberechtigung läuft morgen ab."
+msgstr[1] "Ihre Zugangsberechtigung läuft in %1 Tagen ab."
diff --git a/tests/auto/linguist/lconvert/data/test-refs.po b/tests/auto/linguist/lconvert/data/test-refs.po
new file mode 100644
index 000000000..e149a38e3
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-refs.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Language: de_DE\n"
+
+#: themer/kdmlabel.cpp:285
+#, no-c-format
+msgctxt "date format"
+msgid "%a %d %B"
+msgstr "%a %d %B"
+
+#: foo.bar.baz
+#, no-c-format
+msgid "full java class name"
+msgstr ""
+
+#: foo.car:123 monks:here file/gar.c:17:19 no:monks:here
+#, no-c-format
+msgid "some excessive locations"
+msgstr ""
diff --git a/tests/auto/linguist/lconvert/data/test-slurp.po b/tests/auto/linguist/lconvert/data/test-slurp.po
new file mode 100644
index 000000000..67bc2390d
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-slurp.po
@@ -0,0 +1,19 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+
+msgid "just a line"
+msgstr "indeed"
+
+msgid ""
+"another "
+"line"
+msgstr "certainly"
+
+msgid "a somewhat longer line that will certainly require re-wrapping, and will be re-wrapped if our algorithm is not completely broken.\n"
+"this comes on a new line.\n"
+msgstr "whatever ..."
+
+msgid "bi-""segmented"
+msgstr "aye"
diff --git a/tests/auto/linguist/lconvert/data/test-slurp.po.out b/tests/auto/linguist/lconvert/data/test-slurp.po.out
new file mode 100644
index 000000000..11a874ee5
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-slurp.po.out
@@ -0,0 +1,22 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "just a line"
+msgstr "indeed"
+
+msgid "another line"
+msgstr "certainly"
+
+msgid ""
+"a somewhat longer line that will certainly require re-wrapping, and will be "
+"re-wrapped if our algorithm is not completely broken.\n"
+"this comes on a new line.\n"
+msgstr "whatever ..."
+
+msgid "bi-segmented"
+msgstr "aye"
diff --git a/tests/auto/linguist/lconvert/data/test-translator-comment.po b/tests/auto/linguist/lconvert/data/test-translator-comment.po
new file mode 100644
index 000000000..bc4df5cfb
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-translator-comment.po
@@ -0,0 +1,41 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgid "no comment"
+msgstr "indeed"
+
+#
+msgid "just empty"
+msgstr "indeed"
+
+#
+# This is some comment.
+#
+# This is another comment.
+#
+msgid "User %u will log in in %t"
+msgstr "用户 %u 将在 %t 秒åŽç™»å½•"
+
+# A fooish bar.
+# Hey-ho, sucker.
+#
+# Babbling gully.
+msgid "Foo"
+msgstr "Bar"
diff --git a/tests/auto/linguist/lconvert/data/test1-cn.po b/tests/auto/linguist/lconvert/data/test1-cn.po
new file mode 100644
index 000000000..529eca30a
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test1-cn.po
@@ -0,0 +1,67 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Language: zh_CN\n"
+
+#: kdmconfig.cpp:147
+msgid "[fix kdmrc]"
+msgstr "[ä¿®å¤ kdmrc]"
+
+#: krootimage.cpp:39
+msgid "Fancy desktop background for kdm"
+msgstr "kdm 的梦幻桌é¢èƒŒæ™¯"
+
+#: kgreeter.cpp:558
+#, kde-format
+msgid ""
+"Your saved session type '%1' is not valid any more.\n"
+"Please select a new one, otherwise 'default' will be used."
+msgstr ""
+"ä½ ä¿å­˜çš„“%1â€ä¼šè¯ç±»åž‹ä¸å†æœ‰æ•ˆã€‚\n"
+"请选择一个新的类型,å¦åˆ™å°†ä½¿ç”¨â€œé»˜è®¤â€ã€‚"
+
+#: kgdialog.cpp:231
+#, kde-format
+msgctxt "session (location)"
+msgid "%1 (%2)"
+msgstr "%1(%2)"
+
+#: kgverify.cpp:505
+#, kde-format
+msgid "Your account expires tomorrow."
+msgid_plural "Your account expires in %1 days."
+msgstr[0] "您的账户将于 %1 天åŽè¿‡æœŸã€‚"
+
+#: kdmshutdown.cpp:510
+#, kde-format
+msgctxt "current option in boot loader"
+msgid "%1 (current)"
+msgstr "%1 (当å‰)"
+
+#: themer/kdmlabel.cpp:285
+#, no-c-format
+msgctxt "date format"
+msgid "%a %d %B"
+msgstr "%B月%d日,%a"
+
+#~ msgid "_Suspend"
+#~ msgstr "挂起(_S)"
+
+#~ msgid "Confi_gure"
+#~ msgstr "é…ç½®(_G)"
diff --git a/tests/auto/linguist/lconvert/data/test1-de.po b/tests/auto/linguist/lconvert/data/test1-de.po
new file mode 100644
index 000000000..a4523bb2c
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test1-de.po
@@ -0,0 +1,75 @@
+# translation of kdmgreet.po to German
+# translation of kdmgreet.po to
+# Ãœbersetzung von kdmgreet.po ins Deutsche
+# Copyright (C)
+# Thomas Diehl <thd@kde.org>, 2002, 2003, 2004.
+# Stephan Johach <hunsum@gmx.de>, 2005.
+# Thomas Reitelbach <tr@erdfunkstelle.de>, 2005, 2006, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2007-12-06 20:50+0100\n"
+"Last-Translator: Thomas Reitelbach <tr@erdfunkstelle.de>\n"
+"Language-Team: German <kde-i18n-de@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Language: de_DE\n"
+
+#: lib/acl.c:107 lib/acl.c:121 lib/acl.c:138 lib/acl.c:165 lib/acl.c:174
+#: src/copy.c:695 src/copy.c:2017
+#, c-format
+msgid "preserving permissions for %s"
+msgstr "a preservar as permissões de %s"
+
+#: kdmconfig.cpp:147
+msgid "[fix kdmrc]"
+msgstr "[fix kdmrc]"
+
+#: krootimage.cpp:39
+msgid "Fancy desktop background for kdm"
+msgstr "Schicker Arbeitsflächenhintergrund für KDM"
+
+#: kgreeter.cpp:558
+#, kde-format
+msgid ""
+"Your saved session type '%1' is not valid any more.\n"
+"Please select a new one, otherwise 'default' will be used."
+msgstr ""
+"Der gespeicherte Sitzungstyp „%1“ ist nicht mehr gültig.\n"
+"Bitte wählen Sie einen neuen. Sonst wird die Voreinstellung verwendet."
+
+#: kgdialog.cpp:231
+#, kde-format
+msgctxt "session (location)"
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+#: kgverify.cpp:505
+#, kde-format
+msgid "Your account expires tomorrow."
+msgid_plural "Your account expires in %1 days."
+msgstr[0] "Ihre Zugangsberechtigung läuft morgen ab."
+msgstr[1] "Ihre Zugangsberechtigung läuft in %1 Tagen ab."
+
+#: kdmshutdown.cpp:510
+#, kde-format
+msgctxt "current option in boot loader"
+msgid "%1 (current)"
+msgstr "%1 (Aktuelle)"
+
+#: themer/kdmlabel.cpp:285
+#, no-c-format
+msgctxt "date format"
+msgid "%a %d %B"
+msgstr "%a %d %B"
+
+#~ msgid "_Suspend"
+#~ msgstr "_Ruhezustand"
+
+#~ msgid "Confi_gure"
+#~ msgstr "Ein_richten"
diff --git a/tests/auto/linguist/lconvert/data/test11.ts b/tests/auto/linguist/lconvert/data/test11.ts
new file mode 100644
index 000000000..aeb46af9f
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test11.ts
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="1.1" language="de_DE">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="57"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="107"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="122"/>
+ <source>Should be obsolete</source>
+ <translation type="unfinished">SHOULD BE OBSOLETE</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/test20.ts b/tests/auto/linguist/lconvert/data/test20.ts
new file mode 100644
index 000000000..0e38b4b46
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test20.ts
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Dialog2</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="29"/>
+ <source>%n files</source>
+ <comment>plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="30"/>
+ <source>%n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="31"/>
+ <source>&amp;Find %n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="32"/>
+ <source>Search in %n items?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="33"/>
+ <source>%1. Search in %n items?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="34"/>
+ <source>Age: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="35"/>
+ <source>There are %n house(s)</source>
+ <comment>Plurals and function call</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="53"/>
+ <source>QTranslator</source>
+ <comment>Simple</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="54"/>
+ <source>QTranslator</source>
+ <comment>Simple with comment</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="55"/>
+ <source>QTranslator</source>
+ <comment>Plural without comment</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="57"/>
+ <source>QTranslator</source>
+ <comment>Plural with comment</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="102"/>
+ <source>func3</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source>QT_LAYOUT_DIRECTION</source>
+ <comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QCoreApplication</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="40"/>
+ <source>Plurals, QCoreApplication</source>
+ <comment>%n house(s)</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="41"/>
+ <source>Plurals, QCoreApplication</source>
+ <comment>%n car(s)</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="42"/>
+ <source>Plurals, QCoreApplication</source>
+ <comment>%n horse(s)</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>TestClass</name>
+ <message>
+ <location filename="main.cpp" line="116"/>
+ <source>inline function</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="120"/>
+ <source>inline function 2</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="124"/>
+ <source>static inline function</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Bizarre ~ and | context~</name>
+ <message>
+ <source>just something</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>something else</source>
+ <comment>comment with | and ~ and so~</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>just something obsolete</source>
+ <translation type="obsolete">translated obsoletion</translation>
+ </message>
+ <message>
+ <source>something else obsolete</source>
+ <comment>comment with | and ~ and so~</comment>
+ <translation type="obsolete">another translated obsoletion</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/variants.ts b/tests/auto/linguist/lconvert/data/variants.ts
new file mode 100644
index 000000000..52bb2d49c
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/variants.ts
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de">
+<context>
+ <name>Assistant</name>
+ <message>
+ <source>Source</source>
+ <translation variants="yes">
+ <lengthvariant>A really very long translation</lengthvariant>
+ <lengthvariant>Short translation</lengthvariant>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n document(s) found.</source>
+ <translation>
+ <numerusform>1 Dokument gefunden.</numerusform>
+ <numerusform variants="yes">
+ <lengthvariant>%n Dokumente gefunden.</lengthvariant>
+ <lengthvariant>%n Dok. gefunden.</lengthvariant>
+ </numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/wrapping.po b/tests/auto/linguist/lconvert/data/wrapping.po
new file mode 100644
index 000000000..9feb4a0ac
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/wrapping.po
@@ -0,0 +1,57 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-05-14 14:01+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, no-wrap
+msgid "one two three four five six seven eight nine ten eleven twelve thirteen a 12 foo bar\n"
+msgstr ""
+
+#, no-wrap
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve thirteen a 13 foo bar\n"
+"second line"
+msgstr ""
+
+#: gettxt.c:3
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve thirteen a 14 "
+"foo bar\n"
+msgstr ""
+
+#: gettxt.c:4
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve thirteen a "
+"15\n"
+msgstr ""
+
+#: gettxt.c:5
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve thirteen a "
+"123 foo bar\n"
+msgstr ""
+
+#: gettxt.c:6
+msgid "one two three four five six seven eight nine ten eleven twelve thirteen"
+msgstr ""
+
+#: gettxt.c:7
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve th1rt33n\n"
+msgstr ""
+
+#: gettxt.c:8
+msgid "one two three four five six\n"
+msgstr ""
diff --git a/tests/auto/linguist/lconvert/lconvert.pro b/tests/auto/linguist/lconvert/lconvert.pro
new file mode 100644
index 000000000..517dacd25
--- /dev/null
+++ b/tests/auto/linguist/lconvert/lconvert.pro
@@ -0,0 +1,8 @@
+CONFIG += qttest_p4
+
+TARGET = tst_lconvert
+
+#HEADERS += testlupdate.h
+SOURCES += tst_lconvert.cpp
+# testlupdate.cpp
+
diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp
new file mode 100644
index 000000000..6ab396cde
--- /dev/null
+++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp
@@ -0,0 +1,347 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtCore/QFile>
+
+class tst_lconvert : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_lconvert() : dataDir("data/"), binDir(QLibraryInfo::location(QLibraryInfo::BinariesPath)) {}
+
+private slots:
+ void initTestCase();
+ void readverifies_data();
+ void readverifies();
+ void converts_data();
+ void converts();
+ void roundtrips_data();
+ void roundtrips();
+#if 0
+ void chains_data();
+ void chains();
+#endif
+
+private:
+ void doWait(QProcess *cvt, int stage);
+ void doCompare(QIODevice *actual, const QString &expectedFn);
+ void verifyReadFail(const QString &fn);
+ // args can be empty or have one element less than stations
+ void convertChain(const QString &inFileName, const QString &outFileName,
+ const QStringList &stations, const QList<QStringList> &args);
+ void convertRoundtrip(const QString &fileName, const QStringList &stations,
+ const QList<QStringList> &args);
+
+ QString dataDir;
+ QString binDir;
+};
+
+void tst_lconvert::initTestCase()
+{
+ if (!QFile::exists(QLatin1String("data/plural-1.po")))
+ QProcess::execute(QLatin1String("perl"), QStringList() << QLatin1String("data/makeplurals.pl") << QLatin1String("data/"));
+ QVERIFY(QFile::exists(QLatin1String("data/plural-1.po")));
+}
+
+void tst_lconvert::doWait(QProcess *cvt, int stage)
+{
+ if (QTest::currentTestFailed()) {
+ cvt->kill();
+ cvt->waitForFinished();
+ } else {
+ QVERIFY2(cvt->waitForFinished(3000),
+ qPrintable(QString("Process %1 hung").arg(stage)));
+ QVERIFY2(cvt->exitStatus() == QProcess::NormalExit,
+ qPrintable(QString("Process %1 crashed").arg(stage)));
+ QVERIFY2(cvt->exitCode() == 0,
+ qPrintable(QString("Process %1 exited with status %2. Errors:\n%3")
+ .arg(stage).arg(cvt->exitCode())
+ .arg(QString::fromUtf8(cvt->readAllStandardError()))));
+ }
+}
+
+void tst_lconvert::doCompare(QIODevice *actualDev, const QString &expectedFn)
+{
+ QList<QByteArray> actual = actualDev->readAll().split('\n');
+
+ QFile file(expectedFn);
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+ QList<QByteArray> expected = file.readAll().split('\n');
+
+ int i = 0, ei = expected.size(), gi = actual.size();
+ for (; ; i++) {
+ if (i == gi) {
+ if (i == ei)
+ return;
+ gi = 0;
+ break;
+ } else if (i == ei) {
+ ei = 0;
+ break;
+ } else if (actual.at(i) != expected.at(i)) {
+ while ((ei - 1) >= i && (gi - 1) >= i && actual.at(gi - 1) == expected.at(ei - 1))
+ ei--, gi--;
+ break;
+ }
+ }
+ QByteArray diff;
+ for (int j = qMax(0, i - 3); j < i; j++)
+ diff += expected.at(j) + '\n';
+ diff += "<<<<<<< got\n";
+ for (int j = i; j < gi; j++) {
+ diff += actual.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += "=========\n";
+ for (int j = i; j < ei; j++) {
+ diff += expected.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += ">>>>>>> expected\n";
+ for (int j = ei; j < qMin(ei + 3, expected.size()); j++)
+ diff += expected.at(j) + '\n';
+ QFAIL(qPrintable("Output for " + expectedFn + " does not meet expectations:\n" + diff));
+}
+
+void tst_lconvert::verifyReadFail(const QString &fn)
+{
+ QProcess cvt;
+ cvt.start(binDir + "/lconvert", QStringList() << (dataDir + fn));
+ QVERIFY(cvt.waitForFinished(10000));
+ QVERIFY(cvt.exitStatus() == QProcess::NormalExit);
+ QVERIFY2(cvt.exitCode() == 2, "Accepted invalid input");
+}
+
+void tst_lconvert::convertChain(const QString &_inFileName, const QString &_outFileName,
+ const QStringList &stations, const QList<QStringList> &argList)
+{
+ QList<QProcess *> cvts;
+
+ QString fileName = dataDir + _inFileName;
+ QString outFileName = dataDir + _outFileName;
+
+ for (int i = 0; i < stations.size() - 1; i++) {
+ QProcess *cvt = new QProcess(this);
+ if (cvts.isEmpty())
+ cvt->setStandardInputFile(fileName);
+ else
+ cvts.last()->setStandardOutputProcess(cvt);
+ cvts.append(cvt);
+ }
+ for (int i = 0; i < stations.size() - 1; i++) {
+ QStringList args;
+ if (!argList.isEmpty())
+ args += argList[i];
+ args << "-if" << stations[i] << "-i" << "-" << "-of" << stations[i + 1];
+ cvts.at(i)->start(binDir + "/lconvert", args, QIODevice::ReadWrite | QIODevice::Text);
+ }
+ int st = 0;
+ foreach (QProcess *cvt, cvts)
+ doWait(cvt, ++st);
+
+ if (!QTest::currentTestFailed())
+ doCompare(cvts.last(), outFileName);
+
+ qDeleteAll(cvts);
+}
+
+void tst_lconvert::convertRoundtrip(const QString &_fileName, const QStringList &stations,
+ const QList<QStringList> &argList)
+{
+ convertChain(_fileName, _fileName, stations, argList);
+}
+
+void tst_lconvert::readverifies_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("empty comment") << "test-empty-comment.po" << "po";
+ QTest::newRow("translator comment") << "test-translator-comment.po" << "po";
+ QTest::newRow("developer comment") << "test-developer-comment.po" << "po";
+ QTest::newRow("kde context") << "test-kde-ctxt.po" << "po";
+ QTest::newRow("kde fuzzy") << "test-kde-fuzzy.po" << "po";
+ QTest::newRow("kde plurals") << "test-kde-plurals.po" << "po";
+ QTest::newRow("kde multiline") << "test-kde-multiline.po" << "po";
+ QTest::newRow("po linewrapping") << "wrapping.po" << "po";
+ QTest::newRow("relative locations") << "relative.ts" << "ts";
+ QTest::newRow("message ids") << "msgid.ts" << "ts";
+ QTest::newRow("length variants") << "variants.ts" << "ts";
+ QTest::newRow("qph") << "phrasebook.qph" << "qph";
+}
+
+void tst_lconvert::readverifies()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QString, format);
+
+ convertRoundtrip(fileName, QStringList() << format << format, QList<QStringList>());
+}
+
+void tst_lconvert::converts_data()
+{
+ QTest::addColumn<QString>("inFileName");
+ QTest::addColumn<QString>("outFileName");
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("broken utf8") << "test-broken-utf8.po" << "test-broken-utf8.po.out" << "po";
+ QTest::newRow("line joins") << "test-slurp.po" << "test-slurp.po.out" << "po";
+ QTest::newRow("escapes") << "test-escapes.po" << "test-escapes.po.out" << "po";
+}
+
+void tst_lconvert::converts()
+{
+ QFETCH(QString, inFileName);
+ QFETCH(QString, outFileName);
+ QFETCH(QString, format);
+
+ QString outFileNameFq = dataDir + outFileName;
+
+ QProcess cvt;
+ cvt.start(binDir + "/lconvert",
+ QStringList() << "-i" << (dataDir + inFileName) << "-of" << format,
+ QIODevice::ReadWrite | QIODevice::Text);
+ doWait(&cvt, 0);
+ if (QTest::currentTestFailed())
+ return;
+
+ doCompare(&cvt, outFileNameFq);
+}
+
+Q_DECLARE_METATYPE(QList<QStringList>);
+
+#if 0
+void tst_lconvert::chains_data()
+{
+ QTest::addColumn<QString>("inFileName");
+ QTest::addColumn<QString>("outFileName");
+ QTest::addColumn<QStringList>("stations");
+ QTest::addColumn<QList<QStringList> >("args");
+
+}
+
+void tst_lconvert::chains()
+{
+ QFETCH(QString, inFileName);
+ QFETCH(QString, outFileName);
+ QFETCH(QStringList, stations);
+ QFETCH(QList<QStringList>, args);
+
+ convertChain(inFileName, outFileName, stations, args);
+}
+#endif
+
+void tst_lconvert::roundtrips_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QStringList>("stations");
+ QTest::addColumn<QList<QStringList> >("args");
+
+ QStringList poTsPo; poTsPo << "po" << "ts" << "po";
+ QStringList poXlfPo; poXlfPo << "po" << "xlf" << "po";
+ QStringList tsTs11Ts; tsTs11Ts << "ts" << "ts11" << "ts";
+ QStringList tsPoTs; tsPoTs << "ts" << "po" << "ts";
+ QStringList ts11PoTs11; ts11PoTs11 << "ts11" << "po" << "ts11";
+ QStringList tsXlfTs; tsXlfTs << "ts" << "xlf" << "ts";
+ QStringList tsQmTs; tsQmTs << "ts" << "qm" << "ts";
+
+ QList<QStringList> noArgs;
+ QList<QStringList> filterPoArgs; filterPoArgs << QStringList() << (QStringList() << "-drop-tag" << "po:*");
+ QList<QStringList> outDeArgs; outDeArgs << QStringList() << (QStringList() << "-target-language" << "de");
+ QList<QStringList> outCnArgs; outCnArgs << QStringList() << (QStringList() << "-target-language" << "cn");
+
+ QTest::newRow("po-ts-po (translator comment)") << "test-translator-comment.po" << poTsPo << noArgs;
+ QTest::newRow("po-xliff-po (translator comment)") << "test-translator-comment.po" << poXlfPo << noArgs;
+ QTest::newRow("po-ts-po (developer comment)") << "test-developer-comment.po" << poTsPo << noArgs;
+ QTest::newRow("po-xliff-po (developer comment)") << "test-developer-comment.po" << poXlfPo << noArgs;
+
+ QTest::newRow("ts11-po-ts11") << "test11.ts" << ts11PoTs11 << filterPoArgs;
+ QTest::newRow("ts20-po-ts20") << "test20.ts" << tsPoTs << filterPoArgs;
+ QTest::newRow("po-ts-po (de)") << "test1-de.po" << poTsPo << noArgs;
+ QTest::newRow("po-ts-po (cn)") << "test1-cn.po" << poTsPo << noArgs;
+ QTest::newRow("po-xliff-po (de)") << "test1-de.po" << poXlfPo << noArgs;
+ QTest::newRow("po-xliff-po (cn)") << "test1-cn.po" << poXlfPo << noArgs;
+
+ QTest::newRow("po-ts-po (singular)") << "singular.po" << poTsPo << noArgs;
+ QTest::newRow("po-ts-po (plural-1)") << "plural-1.po" << poTsPo << noArgs;
+ QTest::newRow("po-ts-po (plural-2)") << "plural-2.po" << poTsPo << noArgs;
+ QTest::newRow("po-ts-po (plural-3)") << "plural-3.po" << poTsPo << noArgs;
+ QTest::newRow("po-xliff-po (singular)") << "singular.po" << poXlfPo << noArgs;
+ QTest::newRow("po-xliff-po (plural-1)") << "plural-1.po" << poXlfPo << noArgs;
+ QTest::newRow("po-xliff-po (plural-2)") << "plural-2.po" << poXlfPo << noArgs;
+ QTest::newRow("po-xliff-po (plural-3)") << "plural-3.po" << poXlfPo << noArgs;
+
+ QTest::newRow("po-ts-po (references)") << "test-refs.po" << poTsPo << noArgs;
+
+ QTest::newRow("ts20-ts11-ts20 (utf8)") << "codec-utf8.ts" << tsTs11Ts << noArgs;
+ QTest::newRow("ts20-ts11-ts20 (cp1252)") << "codec-cp1252.ts" << tsTs11Ts << noArgs;
+ QTest::newRow("ts20-ts11-ts20 (dual-encoding)") << "dual-encoding.ts" << tsTs11Ts << noArgs;
+
+ QTest::newRow("ts-qm-ts (dual-encoding)") << "dual-encoding.ts" << tsQmTs << noArgs;
+ QTest::newRow("ts-qm-ts (plurals-de)") << "plurals-de.ts" << tsQmTs << outDeArgs;
+ QTest::newRow("ts-qm-ts (plurals-cn)") << "plurals-cn.ts" << tsQmTs << outCnArgs;
+ QTest::newRow("ts-qm-ts (variants)") << "variants.ts" << tsQmTs << outDeArgs;
+ QTest::newRow("ts-po-ts (msgid)") << "msgid.ts" << tsPoTs << noArgs;
+ QTest::newRow("ts-xliff-ts (msgid)") << "msgid.ts" << tsXlfTs << noArgs;
+
+ QTest::newRow("ts-po-ts (endless loop)") << "endless-po-loop.ts" << tsPoTs << noArgs;
+}
+
+void tst_lconvert::roundtrips()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QStringList, stations);
+ QFETCH(QList<QStringList>, args);
+
+ convertRoundtrip(fileName, stations, args);
+}
+
+QTEST_APPLESS_MAIN(tst_lconvert)
+
+#include "tst_lconvert.moc"
diff --git a/tests/auto/linguist/linguist.pro b/tests/auto/linguist/linguist.pro
new file mode 100644
index 000000000..90e2d367d
--- /dev/null
+++ b/tests/auto/linguist/linguist.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = lrelease lconvert lupdate
diff --git a/tests/auto/linguist/lrelease/.gitignore b/tests/auto/linguist/lrelease/.gitignore
new file mode 100644
index 000000000..cf7059c4b
--- /dev/null
+++ b/tests/auto/linguist/lrelease/.gitignore
@@ -0,0 +1,2 @@
+tst_lrelease
+testdata/*.qm
diff --git a/tests/auto/linguist/lrelease/lrelease.pro b/tests/auto/linguist/lrelease/lrelease.pro
new file mode 100644
index 000000000..8006042c3
--- /dev/null
+++ b/tests/auto/linguist/lrelease/lrelease.pro
@@ -0,0 +1,5 @@
+CONFIG += qttest_p4
+CONFIG -= gui
+TARGET = tst_lrelease
+
+SOURCES += tst_lrelease.cpp
diff --git a/tests/auto/linguist/lrelease/testdata/compressed.ts b/tests/auto/linguist/lrelease/testdata/compressed.ts
new file mode 100644
index 000000000..957926995
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/compressed.ts
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Context1</name>
+ <message>
+ <source>Foo</source>
+ <translation>in first context</translation>
+ </message>
+</context>
+<context>
+ <name>Context2</name>
+ <message>
+ <source>Bar</source>
+ <translation>in second context</translation>
+ </message>
+</context>
+<context>
+ <name>Action1</name>
+ <message>
+ <location filename="main.cpp" line="14"/>
+ <source>Component Name</source>
+ <translation>translation in first context</translation>
+ </message>
+ <message>
+ <source>Fooish bar</source>
+ <translation>the bar is fooish</translation>
+ </message>
+</context>
+<context>
+ <name>Action2</name>
+ <message>
+ <location filename="main.cpp" line="20"/>
+ <source>Component Name</source>
+ <translation>translation in second context</translation>
+ </message>
+</context>
+<context>
+ <name>Action3</name>
+ <message>
+ <location filename="main.cpp" line="26"/>
+ <source>Component Name</source>
+ <translation>translation in third context</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/dupes.errors b/tests/auto/linguist/lrelease/testdata/dupes.errors
new file mode 100644
index 000000000..74fcbbb43
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/dupes.errors
@@ -0,0 +1,4 @@
+Warning: dropping duplicate messages in 'testdata/dupes\.qm':
+
+\* Context: FindDialog
+\* Source: Text not found
diff --git a/tests/auto/linguist/lrelease/testdata/dupes.ts b/tests/auto/linguist/lrelease/testdata/dupes.ts
new file mode 100644
index 000000000..ec368c327
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/dupes.ts
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS>
+<TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message utf8="true">
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Text not found</source>
+ <translation type="obsolete"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/idbased.ts b/tests/auto/linguist/lrelease/testdata/idbased.ts
new file mode 100644
index 000000000..c7555c846
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/idbased.ts
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message id="test_id">
+ <source>Completely irrelevant source text</source>
+ <translation>This is a test string.</translation>
+ </message>
+ <message id="untranslated_id">
+ <source>This has no translation.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="this_another_id">
+ <source>Foo bar.</source>
+ <comment>Warn me!</comment>
+ </message>
+ <message>
+ <source>Drop me!</source>
+ </message>
+ <message id="one_id">
+ <source></source>
+ </message>
+ <message id="two_id">
+ <source></source>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts11.ts b/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts11.ts
new file mode 100644
index 000000000..991f35432
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts11.ts
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="1.1">
+<defaultcodec>windows-1252</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut &#xfc; &amp;uuml;</source>
+ <translation>random stuff with umlaut</translation>
+ </message>
+ <message encoding="UTF-8">
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut ü &amp;uuml; in utf8</source>
+ <translation>more random stuff with umlaut</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts20.ts b/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts20.ts
new file mode 100644
index 000000000..8bb56d43f
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts20.ts
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>windows-1252</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut ü &amp;uuml;</source>
+ <translation>random stuff with umlaut</translation>
+ </message>
+ <message utf8="true">
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut ü &amp;uuml; in utf8</source>
+ <translation>more random stuff with umlaut</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/translate.ts b/tests/auto/linguist/lrelease/testdata/translate.ts
new file mode 100644
index 000000000..ad3015d32
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/translate.ts
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="1.1" language="en">
+<context>
+ <name></name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="32"/>
+ <source>Test</source>
+ <translation>AAAA</translation>
+ <comment>Empty context</comment>
+ </message>
+</context>
+<context>
+ <name>CubeForm</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="31"/>
+ <source>Test</source>
+ <translation>BBBB</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="22"/>
+ <source>
+newline at the start</source>
+ <translation>
+NEWLINE AT THE START</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="23"/>
+ <source>newline at the end
+</source>
+ <translation>NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="24"/>
+ <source>newline and space at the end
+ </source>
+ <translation>NEWLINE AND SPACE AT THE END
+ </translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="25"/>
+ <source>space and newline at the end
+</source>
+ <translation>SPACE AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="26"/>
+ <source><byte value="x9"/>tab at the start and newline at the end
+</source>
+ <translation><byte value="x9"/>TAB AT THE START AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="27"/>
+ <source>
+<byte value="x9"/>newline and tab at the start</source>
+ <translation>
+<byte value="x9"/>NEWLINE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="28"/>
+ <source> <byte value="x9"/>space and tab at the start</source>
+ <translation> <byte value="x9"/>SPACE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="29"/>
+ <source> space first</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="29"/>
+ <source> string that does not exist</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Plurals</name>
+ <message numerus="yes">
+ <location filename="tst_lrelease.cpp" line="35"/>
+ <source>There are %n houses</source>
+ <translation>
+ <numerusform>There is %n house</numerusform>
+ <numerusform>There are %n houses</numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>tst_lrelease</name>
+ <message numerus="yes">
+ <location filename="tst_lrelease.cpp" line="43"/>
+ <source>There are %n cars</source>
+ <comment>More Plurals</comment>
+ <translation>
+ <numerusform>There is %n car</numerusform>
+ <numerusform>There are %n cars</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Completely random string</source>
+ <translation variants="yes">
+ <lengthvariant>Super-lange Uebersetzung mit Schikanen</lengthvariant>
+ <lengthvariant>Mittlere Uebersetung</lengthvariant>
+ <lengthvariant>Kurze Uebers.</lengthvariant>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>no_en</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="49"/>
+ <source>Kj&#xf8;r K&#xe5;re, kj&#xe6;re</source>
+ <translation>Drive K&#xe5;re, dear</translation>
+ </message>
+</context>
+<context>
+ <name>en_no</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="50"/>
+ <source>Drive K&#xe5;re, dear</source>
+ <translation>Kj&#xf8;r K&#xe5;re, kj&#xe6;re</translation>
+ </message>
+</context>
+<context>
+ <name>en_ch</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="51"/>
+ <source>Chinese symbol:</source>
+ <translation>Chinese symbol:&#x7c1f;</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp
new file mode 100644
index 000000000..8ec90571d
--- /dev/null
+++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QByteArray>
+
+#include <QtTest/QtTest>
+
+class tst_lrelease : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_lrelease() : binDir(QLibraryInfo::location(QLibraryInfo::BinariesPath)) {}
+
+private:
+
+private slots:
+ void translate();
+ void mixedcodecs();
+ void compressed();
+ void idbased();
+ void markuntranslated();
+ void dupes();
+
+private:
+ void doCompare(const QStringList &actual, const QString &expectedFn);
+
+ QString binDir;
+};
+
+void tst_lrelease::doCompare(const QStringList &actual, const QString &expectedFn)
+{
+ QFile file(expectedFn);
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+ QStringList expected = QString(file.readAll()).trimmed().split('\n');
+
+ int i = 0, ei = expected.size(), gi = actual.size();
+ for (; ; i++) {
+ if (i == gi) {
+ if (i == ei)
+ return;
+ gi = 0;
+ break;
+ } else if (i == ei) {
+ ei = 0;
+ break;
+ } else if (!QRegExp(expected.at(i)).exactMatch(actual.at(i))) {
+ while ((ei - 1) >= i && (gi - 1) >= i &&
+ (QRegExp(expected.at(ei - 1)).exactMatch(actual.at(gi - 1))))
+ ei--, gi--;
+ break;
+ }
+ }
+ QByteArray diff;
+ for (int j = qMax(0, i - 3); j < i; j++)
+ diff += expected.at(j) + '\n';
+ diff += "<<<<<<< got\n";
+ for (int j = i; j < gi; j++) {
+ diff += actual.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += "=========\n";
+ for (int j = i; j < ei; j++) {
+ diff += expected.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += ">>>>>>> expected\n";
+ for (int j = ei; j < qMin(ei + 3, expected.size()); j++)
+ diff += expected.at(j) + '\n';
+ QFAIL(qPrintable("Output for " + expectedFn + " does not meet expectations:\n" + diff));
+}
+
+void tst_lrelease::translate()
+{
+ QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/translate.ts"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/translate.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(QObject::tr("\nnewline at the start"), QString("\nNEWLINE AT THE START"));
+ QCOMPARE(QObject::tr("newline at the end\n"), QString("NEWLINE AT THE END\n"));
+ QCOMPARE(QObject::tr("newline and space at the end\n "), QString("NEWLINE AND SPACE AT THE END\n "));
+ QCOMPARE(QObject::tr("space and newline at the end \n"), QString("SPACE AND NEWLINE AT THE END \n"));
+ QCOMPARE(QObject::tr("\ttab at the start and newline at the end\n"), QString("\tTAB AT THE START AND NEWLINE AT THE END\n"));
+ QCOMPARE(QObject::tr("\n\tnewline and tab at the start"), QString("\n\tNEWLINE AND TAB AT THE START"));
+ QCOMPARE(QObject::tr(" \tspace and tab at the start"), QString(" \tSPACE AND TAB AT THE START"));
+ QCOMPARE(QObject::tr(" string that does not exist"), QString(" string that does not exist"));
+
+ QCOMPARE(QCoreApplication::translate("CubeForm", "Test"), QString::fromAscii("BBBB"));
+ QCOMPARE(QCoreApplication::translate("", "Test", "Empty context"), QString("AAAA"));
+
+ // Test plurals
+ QString txed = QCoreApplication::translate("Plurals", "There are %n houses", 0, QCoreApplication::UnicodeUTF8, 0);
+ QCOMPARE(QString::fromAscii("[%1]").arg(txed), QString("[There are 0 houses]"));
+ QCOMPARE(QCoreApplication::translate("Plurals", "There are %n houses", 0, QCoreApplication::UnicodeUTF8, 1), QString("There is 1 house"));
+ QCOMPARE(QCoreApplication::translate("Plurals", "There are %n houses", 0, QCoreApplication::UnicodeUTF8, 2), QString("There are 2 houses"));
+ QCOMPARE(QCoreApplication::translate("Plurals", "There are %n houses", 0, QCoreApplication::UnicodeUTF8, 3), QString("There are 3 houses"));
+
+
+ // More plurals
+ QCOMPARE(tr("There are %n cars", "More Plurals", 0) , QString("There are 0 cars"));
+ QCOMPARE(tr("There are %n cars", "More Plurals", 1) , QString("There is 1 car"));
+ QCOMPARE(tr("There are %n cars", "More Plurals", 2) , QString("There are 2 cars"));
+ QCOMPARE(tr("There are %n cars", "More Plurals", 3) , QString("There are 3 cars"));
+
+
+ QCOMPARE(QCoreApplication::translate("no_en", "Kj\370r K\345re, kj\346re"), QString::fromAscii("Drive K\345re, dear"));
+ QCOMPARE(QCoreApplication::translate("en_no", "Drive K\345re, dear"), QString::fromAscii("Kj\370r K\345re, kj\346re"));
+ QCOMPARE(QCoreApplication::translate("en_ch", "Chinese symbol:"), QString::fromAscii("Chinese symbol:%1").arg(QChar(0x7c1f)));
+
+// printf("halo\r\nhallo");
+ // QCOMPARE(tr("This\r\nwill fail"), QString("THIS\nWILL FAIL")); // \r\n = 0d 0a
+
+ QCOMPARE(tr("Completely random string"),
+ QString::fromLatin1("Super-lange Uebersetzung mit Schikanen\x9c"
+ "Mittlere Uebersetung\x9c"
+ "Kurze Uebers."));
+
+ qApp->removeTranslator(&translator);
+}
+
+void tst_lrelease::mixedcodecs()
+{
+ QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/mixedcodecs-ts11.ts"));
+ QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/mixedcodecs-ts20.ts"));
+#ifdef Q_OS_WIN
+ QVERIFY(!QProcess::execute("fc /b testdata\\mixedcodecs-ts11.qm testdata\\mixedcodecs-ts20.qm"));
+#else
+ QVERIFY(!QProcess::execute("cmp testdata/mixedcodecs-ts11.qm testdata/mixedcodecs-ts20.qm"));
+#endif
+
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/mixedcodecs-ts11.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(QCoreApplication::translate("FooBar", "this contains an umlaut \xfc &uuml;"),
+ QString::fromAscii("random stuff with umlaut"));
+ QCOMPARE(QCoreApplication::translate("FooBar", "umlaut \xc3\xbc &uuml; in utf8"),
+ QString::fromAscii("more random stuff with umlaut"));
+}
+
+void tst_lrelease::compressed()
+{
+ QVERIFY(!QProcess::execute(binDir + "/lrelease -compress testdata/compressed.ts"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/compressed.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(QCoreApplication::translate("Context1", "Foo"), QString::fromAscii("in first context"));
+ QCOMPARE(QCoreApplication::translate("Context2", "Bar"), QString::fromAscii("in second context"));
+
+ QCOMPARE(QCoreApplication::translate("Action1", "Component Name"), QString::fromAscii("translation in first context"));
+ QCOMPARE(QCoreApplication::translate("Action2", "Component Name"), QString::fromAscii("translation in second context"));
+ QCOMPARE(QCoreApplication::translate("Action3", "Component Name"), QString::fromAscii("translation in third context"));
+
+}
+
+void tst_lrelease::idbased()
+{
+ QVERIFY(!QProcess::execute(binDir + "/lrelease -idbased testdata/idbased.ts"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/idbased.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(qtTrId("test_id"), QString::fromAscii("This is a test string."));
+ QCOMPARE(qtTrId("untranslated_id"), QString::fromAscii("This has no translation."));
+}
+
+void tst_lrelease::markuntranslated()
+{
+ QVERIFY(!QProcess::execute(binDir + "/lrelease -markuntranslated # -idbased testdata/idbased.ts"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/idbased.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(qtTrId("test_id"), QString::fromAscii("This is a test string."));
+ QCOMPARE(qtTrId("untranslated_id"), QString::fromAscii("#This has no translation."));
+}
+
+void tst_lrelease::dupes()
+{
+ QProcess proc;
+ proc.start(binDir + "/lrelease testdata/dupes.ts", QIODevice::ReadWrite | QIODevice::Text);
+ QVERIFY(proc.waitForFinished());
+ QVERIFY(proc.exitStatus() == QProcess::NormalExit);
+ doCompare(QString(proc.readAllStandardError()).trimmed().split('\n'), "testdata/dupes.errors");
+}
+
+QTEST_MAIN(tst_lrelease)
+#include "tst_lrelease.moc"
diff --git a/tests/auto/linguist/lupdate/.gitignore b/tests/auto/linguist/lupdate/.gitignore
new file mode 100644
index 000000000..a11e8d146
--- /dev/null
+++ b/tests/auto/linguist/lupdate/.gitignore
@@ -0,0 +1,4 @@
+tst_lupdate
+testdata/*/*.ts
+testdata/*/*/*.ts
+testdata/*/*/*/*.ts
diff --git a/tests/auto/linguist/lupdate/lupdate.pro b/tests/auto/linguist/lupdate/lupdate.pro
new file mode 100644
index 000000000..bcaaf6686
--- /dev/null
+++ b/tests/auto/linguist/lupdate/lupdate.pro
@@ -0,0 +1,6 @@
+CONFIG += qttest_p4
+
+TARGET = tst_lupdate
+
+SOURCES += tst_lupdate.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/backslashes/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/backslashes/lupdatecmd
new file mode 100644
index 000000000..f0e1ab200
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/backslashes/lupdatecmd
@@ -0,0 +1 @@
+TRANSLATION: ts\project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/backslashes/project.pro b/tests/auto/linguist/lupdate/testdata/good/backslashes/project.pro
new file mode 100644
index 000000000..d4dcda880
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/backslashes/project.pro
@@ -0,0 +1,3 @@
+SOURCES += src\\main.cpp
+
+TRANSLATIONS = ts\\project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/backslashes/src/main.cpp b/tests/auto/linguist/lupdate/testdata/good/backslashes/src/main.cpp
new file mode 100644
index 000000000..d95b710c1
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/backslashes/src/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+//
+//
+//
+//
+
+QString qt_detectRTLLanguage()
+{
+ return QApplication::tr("QT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget layout.") == QLatin1String("RTL");
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/backslashes/ts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/backslashes/ts/project.ts.result
new file mode 100644
index 000000000..d3a5fdf9e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/backslashes/ts/project.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="../src/main.cpp" line="51"/>
+ <source>QT_LAYOUT_DIRECTION</source>
+ <comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_deeppath/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/cmdline_deeppath/lupdatecmd
new file mode 100644
index 000000000..301d839a7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_deeppath/lupdatecmd
@@ -0,0 +1,2 @@
+cd ../../recursivescan
+lupdate sub/finddialog.cpp -ts project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_deeppath/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/cmdline_deeppath/project.ts.result
new file mode 100644
index 000000000..5c3c21c34
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_deeppath/project.ts.result
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="sub/finddialog.cpp" line="57"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="66"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="68"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="70"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_order/a.h b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/a.h
new file mode 100644
index 000000000..c153962ff
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/a.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define XX QT_TRANSLATE_NOOP("aaa", "some text")
diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_order/b.h b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/b.h
new file mode 100644
index 000000000..7ab2d6f95
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/b.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "a.h"
+
+#define YY QT_TRANSLATE_NOOP("bbb", "some text")
diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_order/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/lupdatecmd
new file mode 100644
index 000000000..edd91f7e3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/lupdatecmd
@@ -0,0 +1 @@
+lupdate b.h a.h -ts project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_order/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/project.ts.result
new file mode 100644
index 000000000..6028cbbe0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/project.ts.result
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>aaa</name>
+ <message>
+ <location filename="a.h" line="42"/>
+ <source>some text</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>bbb</name>
+ <message>
+ <location filename="b.h" line="44"/>
+ <source>some text</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_recurse/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/cmdline_recurse/lupdatecmd
new file mode 100644
index 000000000..1814e67ca
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_recurse/lupdatecmd
@@ -0,0 +1,2 @@
+cd ../../recursivescan
+lupdate . -ts project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_recurse/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/cmdline_recurse/project.ts.result
new file mode 100644
index 000000000..95a34fa80
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_recurse/project.ts.result
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="57"/>
+ <source>Qt Assistant - Finn text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="60"/>
+ <source>Finn tekst</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="57"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="66"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="68"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="70"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="53"/>
+ <source>
+newline at the start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source>newline at the end
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="55"/>
+ <source>newline and space at the end
+ </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="56"/>
+ <source>space and newline at the end
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="57"/>
+ <source> Tab at the start and newline at the end
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="58"/>
+ <source>
+ newline and tab at the start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="59"/>
+ <source> space and tab at the start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="60"/>
+ <source> space_first</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="61"/>
+ <source>space_last </source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>text/c++</name>
+ <message>
+ <location filename="sub/filetypes/main.c++" line="47"/>
+ <source>test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>text/cpp</name>
+ <message>
+ <location filename="sub/filetypes/main.cpp" line="47"/>
+ <source>test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>text/cxx</name>
+ <message>
+ <location filename="sub/filetypes/main.cxx" line="47"/>
+ <source>test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecforsrc/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/main.cpp
new file mode 100644
index 000000000..c9e37a09f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/main.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QtGui>
+#include <QtCore>
+#include <QTextCodec>
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+ QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
+
+ QWidget w;
+ QLabel label1(QObject::tr("abc", "ascii"), &w);
+ QLabel label2(QObject::tr("æøå", "utf-8"), &w);
+ QLabel label2a(QObject::tr("\303\246\303\270\303\245", "utf-8 oct"), &w);
+ QLabel label3(QObject::trUtf8("Für Élise", "trUtf8"), &w);
+ QLabel label3a(QObject::trUtf8("F\303\274r \303\211lise", "trUtf8 oct"), &w);
+
+ QBoxLayout *ly = new QVBoxLayout(&w);
+ ly->addWidget(&label1);
+ ly->addWidget(&label2);
+ ly->addWidget(&label2a);
+ ly->addWidget(&label3);
+ ly->addWidget(&label3a);
+
+ w.show();
+ return a.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.pro
new file mode 100644
index 000000000..7225608b8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.pro
@@ -0,0 +1,7 @@
+SOURCES += main.cpp
+CONFIG+= console
+
+TRANSLATIONS = project.ts
+
+CODECFORTR = utf-8
+CODECFORSRC = utf-8
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.ts.result
new file mode 100644
index 000000000..711bf025a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.ts.result
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="53"/>
+ <source>abc</source>
+ <comment>ascii</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source>æøå</source>
+ <comment>utf-8</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="55"/>
+ <source>æøå</source>
+ <comment>utf-8 oct</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="56"/>
+ <source>Für Élise</source>
+ <comment>trUtf8</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="57"/>
+ <source>Für Élise</source>
+ <comment>trUtf8 oct</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecfortr/main.cpp
new file mode 100644
index 000000000..fad7f4013
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr/main.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QtGui>
+#include <QtCore>
+#include <QTextCodec>
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+ QTranslator trans(0);
+
+ trans.load("t1_en", ".");
+
+ a.installTranslator(&trans);
+ QWidget w;
+/*
+ QLabel label1(QObject::tr("\33"), &w);
+ QLabel label2(QObject::tr("\32"), &w);
+ QLabel label3(QObject::tr("\176"), &w);
+*/
+ QLabel label4(QObject::tr("\301"), &w);
+
+ w.show();
+ return a.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.pro
new file mode 100644
index 000000000..64f3c8590
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.pro
@@ -0,0 +1,6 @@
+SOURCES += main.cpp
+CONFIG+= console
+
+TRANSLATIONS = project.ts
+
+CODECFORTR = CP1251
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.ts.result
new file mode 100644
index 000000000..6ee369a78
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>windows-1251</defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="61"/>
+ <source>Б</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr1/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/main.cpp
new file mode 100644
index 000000000..c2ed5cbcb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+
+class FooBar : QObject
+{
+ Q_OBJECT
+
+public:
+ void doFoo()
+ {
+ tr("random ascii only");
+ tr("this contains an umlaut ü &uuml; literally");
+ tr("this contains an umlaut \xfc &uuml; escaped");
+ trUtf8("random ascii only in utf8");
+ trUtf8("umlaut ü &uuml; in literal utf8");
+ trUtf8("umlaut \303\274 &uuml; in escaped utf8");
+ }
+};
+
+int main(int argc, char **argv)
+{
+ return 0;
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.pro
new file mode 100644
index 000000000..d5697ebb9
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.pro
@@ -0,0 +1,6 @@
+SOURCES += main.cpp
+CONFIG += console
+
+TRANSLATIONS = project.ts
+
+CODECFORTR = CP1252
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.ts.result
new file mode 100644
index 000000000..d548e2465
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.ts.result
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>windows-1252</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="51"/>
+ <source>random ascii only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="52"/>
+ <source>this contains an umlaut ü &amp;uuml; literally</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="53"/>
+ <source>this contains an umlaut ü &amp;uuml; escaped</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source>random ascii only in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message utf8="true">
+ <location filename="main.cpp" line="55"/>
+ <source>umlaut ü &amp;uuml; in literal utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message utf8="true">
+ <location filename="main.cpp" line="56"/>
+ <source>umlaut ü &amp;uuml; in escaped utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr2/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/main.cpp
new file mode 100644
index 000000000..2800eebfe
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/main.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+
+class FooBar : QObject
+{
+ Q_OBJECT
+
+public:
+ void doFoo()
+ {
+ tr("random ascii only");
+ tr("this contains an umlaut ü &uuml; literally");
+ tr("this contains an umlaut \303\274 &uuml; escaped, really in utf-8");
+ trUtf8("random ascii only in utf8");
+ trUtf8("umlaut \303\274 &uuml; in escaped utf8");
+ }
+};
+
+int main(int argc, char **argv)
+{
+ return 0;
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.pro
new file mode 100644
index 000000000..c95939c3b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.pro
@@ -0,0 +1,7 @@
+SOURCES += main.cpp
+CONFIG += console
+
+TRANSLATIONS = project.ts
+
+CODECFORSRC = CP1252
+CODECFORTR = UTF-8
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.ts.result
new file mode 100644
index 000000000..6728a256b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.ts.result
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="51"/>
+ <source>random ascii only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="52"/>
+ <source>this contains an umlaut ü &amp;uuml; literally</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="53"/>
+ <source>this contains an umlaut ü &amp;uuml; escaped, really in utf-8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source>random ascii only in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="55"/>
+ <source>umlaut ü &amp;uuml; in escaped utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr3/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/expectedoutput.txt
new file mode 100644
index 000000000..feecddace
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/expectedoutput.txt
@@ -0,0 +1 @@
+lupdate warning: Codec for tr\(\) 'ISO-8859-1' disagrees with existing file's codec 'UTF-8'\. Expect trouble\.
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr3/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/main.cpp
new file mode 100644
index 000000000..b59af2b00
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/main.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+int main(int argc, char **argv)
+{
+ QObject::tr("hi");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.pro
new file mode 100644
index 000000000..00a4dc488
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.pro
@@ -0,0 +1,4 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
+CODECFORTR = latin1
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.ts.before
new file mode 100644
index 000000000..07ad79b82
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.ts.before
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="44"/>
+ <source>hi</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.ts.result
new file mode 100644
index 000000000..b6899c162
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr3/project.ts.result
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="44"/>
+ <source>hi</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr4/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/expectedoutput.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/expectedoutput.txt
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr4/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/main.cpp
new file mode 100644
index 000000000..b59af2b00
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/main.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+int main(int argc, char **argv)
+{
+ QObject::tr("hi");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.pro
new file mode 100644
index 000000000..4fddb0242
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.pro
@@ -0,0 +1,4 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
+CODECFORTR = latin2
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.ts.before
new file mode 100644
index 000000000..e18e34e0e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.ts.before
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>ISO-8859-2</defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="44"/>
+ <source>hi</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.ts.result
new file mode 100644
index 000000000..e18e34e0e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr4/project.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>ISO-8859-2</defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="44"/>
+ <source>hi</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/from_subdir/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/from_subdir/lupdatecmd
new file mode 100644
index 000000000..8a5b4ada3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/from_subdir/lupdatecmd
@@ -0,0 +1 @@
+lupdate translations/translations.pro
diff --git a/tests/auto/linguist/lupdate/testdata/good/from_subdir/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/from_subdir/project.ts.result
new file mode 100644
index 000000000..7167cf33c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/from_subdir/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="src/main.cpp" line="49"/>
+ <source>string in main.cpp</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="src/main.h" line="45"/>
+ <source>string in main.h</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/from_subdir/src/main.cpp b/tests/auto/linguist/lupdate/testdata/good/from_subdir/src/main.cpp
new file mode 100644
index 000000000..26eeee237
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/from_subdir/src/main.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+#include "main.h"
+
+int main(char **argv, int argc)
+{
+ return QApplication::tr("string in main.cpp");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/from_subdir/src/main.h b/tests/auto/linguist/lupdate/testdata/good/from_subdir/src/main.h
new file mode 100644
index 000000000..0918b5153
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/from_subdir/src/main.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+QT_TRANSLATE_NOOP("QApplication", "string in main.h")
diff --git a/tests/auto/linguist/lupdate/testdata/good/from_subdir/translations/translations.pro b/tests/auto/linguist/lupdate/testdata/good/from_subdir/translations/translations.pro
new file mode 100644
index 000000000..1815c37dc
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/from_subdir/translations/translations.pro
@@ -0,0 +1,7 @@
+VPATH = ../src
+INCLUDEPATH = ../src
+
+SOURCES += main.cpp
+HEADERS += main.h
+
+TRANSLATIONS += ../project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt
new file mode 100644
index 000000000..1eed403b7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt
@@ -0,0 +1,5 @@
+Updating 'project\.ts'\.\.\.
+ Found 3 source text\(s\) \(3 new and 0 already existing\)
+ Removed 5 obsolete entries
+ Number heuristic provided 1 translation\(s\)
+ Same-text heuristic provided 1 translation\(s\)
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/heuristics/lupdatecmd
new file mode 100644
index 000000000..6bda26175
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/lupdatecmd
@@ -0,0 +1,2 @@
+TRANSLATION: project.ts
+lupdate -verbose -disable-heuristic similartext -no-obsolete project.pro
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp b/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp
new file mode 100644
index 000000000..4da14736c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+#define QTCORE <QtCore>
+#include QTCORE // Hidden from lupdate, but compiles
+
+class A: public QObject {
+ Q_OBJECT
+ void foo()
+ {
+ // number Heuristics
+ tr("version 2.0 now");
+
+ // same text match
+ tr("this is the matched same text");
+
+ // failed same text
+ tr("this is the non-matched same text");
+ }
+};
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.pro b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.pro
new file mode 100644
index 000000000..759bea068
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.pro
@@ -0,0 +1,3 @@
+SOURCES = main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before
new file mode 100644
index 000000000..ce8281033
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>A</name>
+ <message>
+ <location filename="main.cpp" line="53"/>
+ <source>version 1.0 now</source>
+ <translation>teraz wersja 1.0</translation>
+ </message>
+</context>
+<context>
+ <name>B</name>
+ <message>
+ <location filename="main.cpp" line="56"/>
+ <source>this is the matched same text</source>
+ <translation>der same-text-treffer</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="59"/>
+ <source>this is the non-matched same text</source>
+ <translation>same-text-reinfall variante eins</translation>
+ </message>
+</context>
+<context>
+ <name>C</name>
+ <message>
+ <location filename="main.cpp" line="56"/>
+ <source>this is the matched same text</source>
+ <translation>der same-text-treffer</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="59"/>
+ <source>this is the non-matched same text</source>
+ <translation>völlig andere variante des reinfalls mit same-text</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result
new file mode 100644
index 000000000..402ad9a9b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>A</name>
+ <message>
+ <location filename="main.cpp" line="53"/>
+ <source>version 2.0 now</source>
+ <translation type="unfinished">teraz wersja 1.0 {2.0 ?}</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="56"/>
+ <source>this is the matched same text</source>
+ <translation type="unfinished">der same-text-treffer</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="59"/>
+ <source>this is the non-matched same text</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt
new file mode 100644
index 000000000..f6fc40036
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt
@@ -0,0 +1,4 @@
+.*/lupdate/testdata/good/lacksqobject/main.cpp:58: Class 'B' lacks Q_OBJECT macro
+.*/lupdate/testdata/good/lacksqobject/main.cpp:65: Class 'C' lacks Q_OBJECT macro
+.*/lupdate/testdata/good/lacksqobject/main.cpp:78: Class 'nsB::B' lacks Q_OBJECT macro
+.*/lupdate/testdata/good/lacksqobject/main.cpp:84: Class 'nsB::C' lacks Q_OBJECT macro
diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/main.cpp b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/main.cpp
new file mode 100644
index 000000000..42e81deb2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/main.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+#define QTCORE <QtCore>
+#include QTCORE // Hidden from lupdate, but compiles
+
+//
+// Test 'lacks Q_OBJECT' reporting on namespace scopes
+//
+
+class B : public QObject {
+ //Q_OBJECT
+ void foo();
+};
+
+void B::foo() {
+ tr("Bla", "::B");
+}
+
+
+class C : public QObject {
+ //Q_OBJECT
+ void foo() {
+ tr("Bla", "::C");
+ }
+};
+
+
+namespace nsB {
+
+ class B : public QObject {
+ //Q_OBJECT
+ void foo();
+ };
+
+ void B::foo() {
+ tr("Bla", "nsB::B");
+ }
+
+ class C : public QObject {
+ //Q_OBJECT
+ void foo() {
+ tr("Bla", "nsB::C");
+ }
+ };
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.pro b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.pro
new file mode 100644
index 000000000..759bea068
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.pro
@@ -0,0 +1,3 @@
+SOURCES = main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.ts.result
new file mode 100644
index 000000000..bc876cdb1
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.ts.result
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>B</name>
+ <message>
+ <location filename="main.cpp" line="58"/>
+ <source>Bla</source>
+ <comment>::B</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>C</name>
+ <message>
+ <location filename="main.cpp" line="65"/>
+ <source>Bla</source>
+ <comment>::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>nsB::B</name>
+ <message>
+ <location filename="main.cpp" line="78"/>
+ <source>Bla</source>
+ <comment>nsB::B</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>nsB::C</name>
+ <message>
+ <location filename="main.cpp" line="84"/>
+ <source>Bla</source>
+ <comment>nsB::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp
new file mode 100644
index 000000000..838f305d2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp
@@ -0,0 +1,69 @@
+
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// The first line in this file should always be empty, its part of the test!!
+class Foo : public QObject
+{
+ Q_OBJECT
+public:
+ Foo();
+};
+
+Foo::Foo(MainWindow *parent)
+ : QObject(parent)
+{
+ tr("This is the first entry.");
+ tr("A second message."); tr("And a second one on the same line.");
+ tr("This string did move from the bottom.");
+ tr("This tr is new.");
+ tr("This one moved in from another file.");
+ tr("Now again one which is just where it was.");
+
+ tr("Just as this one.");
+ tr("Another alien.");
+ tr("This is from the bottom, too.");
+ tr("Third string from the bottom.");
+ tr("Fourth one!");
+ tr("They are coming!");
+ tr("They are everywhere!");
+ tr("An earthling again.");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/lupdatecmd
new file mode 100644
index 000000000..82b4b0d6f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/lupdatecmd
@@ -0,0 +1 @@
+lupdate -locations relative project.pro
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.pro b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.pro
new file mode 100644
index 000000000..614985830
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.pro
@@ -0,0 +1,3 @@
+SOURCES += foo.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.before
new file mode 100644
index 000000000..1762cc7b4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.before
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="2.0">
+<context>
+ <name>Bar</name>
+ <message>
+ <location filename="bar1.cpp" line="54"/>
+ <source>Another alien.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="bar1.cpp" line="55"/>
+ <source>They are coming!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="bar1.cpp" line="57"/>
+ <source>They are everywhere!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="bar1.cpp" line="59"/>
+ <source>This one moved in from another file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="foo1.cpp" line="54"/>
+ <source>This is the first entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="55"/>
+ <source>A second message.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="56"/>
+ <source>Now again one which is just where it was.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="57"/>
+ <source>Just as this one.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="58"/>
+ <source>An earthling again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="59"/>
+ <source>This is from the bottom, too.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="60"/>
+ <source>Third string from the bottom.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="61"/>
+ <source>Fourth one!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="62"/>
+ <source>This string did move from the bottom.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.result
new file mode 100644
index 000000000..5104860c3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.result
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="foo.cpp" line="+54"/>
+ <source>This is the first entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A second message.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>And a second one on the same line.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>This tr is new.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>This one moved in from another file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Now again one which is just where it was.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Just as this one.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Another alien.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>They are coming!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>They are everywhere!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>An earthling again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-5"/>
+ <source>This is from the bottom, too.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Third string from the bottom.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Fourth one!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-9"/>
+ <source>This string did move from the bottom.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.pro b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.pro
new file mode 100644
index 000000000..fa56972dd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.pro
@@ -0,0 +1,3 @@
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.before
new file mode 100644
index 000000000..fdc2a9980
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.before
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Qt Assistant - Finn text</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Finn tekst</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.result
new file mode 100644
index 000000000..f9d26df2a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.result
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Qt Assistant - Finn text</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Finn tekst</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ui b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ui
new file mode 100644
index 000000000..d8c35ccc1
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ui
@@ -0,0 +1,72 @@
+<ui version="4.0" >
+ <author></author>
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant - Finn text</string><!-- changed to uppercase -->
+ </property>
+ <property name="height" >
+ <string>Finn tekst</string>
+ </property>
+ </widget>
+ <tabstops>
+ <tabstop>comboFind</tabstop>
+ <tabstop>checkWords</tabstop>
+ <tabstop>checkCase</tabstop>
+ <tabstop>radioForward</tabstop>
+ <tabstop>radioBackward</tabstop>
+ <tabstop>findButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/main.cpp b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/main.cpp
new file mode 100644
index 000000000..fb12bc0d9
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/main.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QDebug>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QTranslator translator;
+ translator.load("whitespace");
+ app.installTranslator(&translator);
+
+ QObject::tr("\nnewline at the start");
+ QObject::tr("newline at the end\n");
+ QObject::tr("newline and space at the end\n ");
+ QObject::tr("space and newline at the end \n");
+ QObject::tr("\tTab at the start and newline at the end\n");
+ QObject::tr("\n\tnewline and tab at the start");
+ QObject::tr(" \tspace and tab at the start");
+ QObject::tr(" space_first");
+ QObject::tr("space_last ");
+ QObject::tr("carriage return and line feed last\r\n");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.pro b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.pro
new file mode 100644
index 000000000..759bea068
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.pro
@@ -0,0 +1,3 @@
+SOURCES = main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.before
new file mode 100644
index 000000000..0f84fedb8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.before
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="7"/>
+ <source>
+newline at the start</source>
+ <translation>
+NEWLINE AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="49"/>
+ <source>newline at the end
+</source>
+ <translation>NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="50"/>
+ <source>newline and space at the end
+ </source>
+ <translation>NEWLINE AND SPACE AT THE END
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="51"/>
+ <source>space and newline at the end
+</source>
+ <translation>SPACE AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="52"/>
+ <source><byte value="x9"/>Tab at the start and newline at the end
+</source>
+ <translation><byte value="x9"/>TAB AT THE START AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="53"/>
+ <source>
+<byte value="x9"/>newline and tab at the start</source>
+ <translation>
+<byte value="x9"/>NEWLINE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source> <byte value="x9"/>space and tab at the start</source>
+ <translation> <byte value="x9"/>SPACE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="55"/>
+ <source> space_first</source>
+ <translation> SPACE_FIRST</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="56"/>
+ <source>space_last </source>
+ <translation>SPACE_LAST </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="62"/>
+ <source>carriage return and line feed last<byte value="xd"/>
+</source>
+ <translation type="unfinished">CARRIAGE RETURN AND LINE FEED LAST<byte value="xd"/>
+</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.result
new file mode 100644
index 000000000..776238db8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.result
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="53"/>
+ <source>
+newline at the start</source>
+ <translation>
+NEWLINE AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source>newline at the end
+</source>
+ <translation>NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="55"/>
+ <source>newline and space at the end
+ </source>
+ <translation>NEWLINE AND SPACE AT THE END
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="56"/>
+ <source>space and newline at the end
+</source>
+ <translation>SPACE AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="57"/>
+ <source> Tab at the start and newline at the end
+</source>
+ <translation> TAB AT THE START AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="58"/>
+ <source>
+ newline and tab at the start</source>
+ <translation>
+ NEWLINE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="59"/>
+ <source> space and tab at the start</source>
+ <translation> SPACE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="60"/>
+ <source> space_first</source>
+ <translation> SPACE_FIRST</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="61"/>
+ <source>space_last </source>
+ <translation>SPACE_LAST </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="62"/>
+ <source>carriage return and line feed last
+</source>
+ <translation type="unfinished">CARRIAGE RETURN AND LINE FEED LAST
+</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp
new file mode 100644
index 000000000..5f2f686a3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp
@@ -0,0 +1,82 @@
+
+// The first line in this file should always be empty, its part of the test!!
+
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+class FindDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ FindDialog(MainWindow *parent);
+ void reset();
+};
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ QString trans = tr("Enter the text you want to find.");
+ trans = tr("Search reached end of the document");
+ trans = tr("Search reached start of the document");
+ trans = tr( "Text not found" );
+}
+
+void FindDialog::reset()
+{
+ tr("%n item(s)", "merge from singular to plural form", 4);
+ tr("%n item(s)", "merge from a finished singular form to an unfinished plural form", 4);
+
+
+
+ //% "Hello"
+ qtTrId("xx_hello");
+
+ //% "New world"
+ qtTrId("xx_world");
+
+
+ //= new_id
+ tr("this is just some text");
+
+
+ //: A message without source string
+ qtTrId("qtn_virtual");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.pro
new file mode 100644
index 000000000..63f5d66e2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.pro
@@ -0,0 +1,3 @@
+SOURCES += finddialog.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.before
new file mode 100644
index 000000000..379cce465
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.before
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="zh_CN">
+<context>
+ <name></name>
+ <message id="xx_hello">
+ <location filename="finddialog.cpp" line="70"/>
+ <source>Hello</source>
+ <translation>Hallo</translation>
+ </message>
+ <message id="xx_world">
+ <location filename="finddialog.cpp" line="73"/>
+ <source>World</source>
+ <translation>Welt</translation>
+ </message>
+ <message id="qtn_virtual">
+ <location filename="finddialog.cpp" line="79"/>
+ <extracomment>A message without source string</extracomment>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source></source>
+ <comment>magic context comment</comment>
+ <translatorcomment>random translator comment</translatorcomment>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="56"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="57"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="58"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="59"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="finddialog.cpp" line="64"/>
+ <source>%n item(s)</source>
+ <comment>merge from singular to plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="finddialog.cpp" line="65"/>
+ <source>%n item(s)</source>
+ <comment>merge from a finished singular form to an unfinished plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="59"/>
+ <source>this is just some text</source>
+ <translation type="unfinished">Unfertige Uebersetzung</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.result
new file mode 100644
index 000000000..de43266d2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.result
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="zh_CN">
+<context>
+ <name></name>
+ <message id="xx_hello">
+ <location filename="finddialog.cpp" line="70"/>
+ <source>Hello</source>
+ <translation>Hallo</translation>
+ </message>
+ <message id="xx_world">
+ <location filename="finddialog.cpp" line="73"/>
+ <source>New world</source>
+ <oldsource>World</oldsource>
+ <translation type="unfinished">Welt</translation>
+ </message>
+ <message id="qtn_virtual">
+ <location filename="finddialog.cpp" line="81"/>
+ <source></source>
+ <extracomment>A message without source string</extracomment>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source></source>
+ <comment>magic context comment</comment>
+ <translatorcomment>random translator comment</translatorcomment>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="56"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="57"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="58"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="59"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="finddialog.cpp" line="64"/>
+ <source>%n item(s)</source>
+ <comment>merge from singular to plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="finddialog.cpp" line="65"/>
+ <source>%n item(s)</source>
+ <comment>merge from a finished singular form to an unfinished plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message id="new_id">
+ <location filename="finddialog.cpp" line="77"/>
+ <source>this is just some text</source>
+ <translation type="unfinished">Unfertige Uebersetzung</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/finddialog.cpp
new file mode 100644
index 000000000..ab9b6fd68
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/finddialog.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "finddialog.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpwindow.h"
+
+#include <QTextBrowser>
+#include <QTextCursor>
+#include <QStatusBar>
+#include <QLineEdit>
+#include <QDateTime>
+#include <QGridLayout>
+
+CaseSensitiveModel::CaseSensitiveModel(int rows, int columns, QObject *parent)
+ : QStandardItemModel(rows, columns, parent)
+{}
+QModelIndexList CaseSensitiveModel::match(const QModelIndex &start, int role, const QVariant &value,
+ int hits, Qt::MatchFlags flags) const
+{
+ if (flags == Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap))
+ flags |= Qt::MatchCaseSensitive;
+
+ return QStandardItemModel::match(start, role, value, hits, flags);
+}
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ contentsWidget = new QWidget(this);
+ ui.setupUi(contentsWidget);
+ ui.comboFind->setModel(new CaseSensitiveModel(0, 1, ui.comboFind));
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+ l->addWidget(contentsWidget);
+
+ lastBrowser = 0;
+ onceFound = false;
+ findExpr.clear();
+
+ sb = new QStatusBar(this);
+ l->addWidget(sb);
+
+ sb->showMessage(tr("Enter the text you want to find."));
+
+ connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findButtonClicked()));
+ connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+FindDialog::~FindDialog()
+{
+}
+
+void FindDialog::findButtonClicked()
+{
+ doFind(ui.radioForward->isChecked());
+}
+
+void FindDialog::doFind(bool forward)
+{
+ QTextBrowser *browser = static_cast<QTextBrowser*>(mainWindow()->browsers()->currentBrowser());
+ sb->clearMessage();
+
+ if (ui.comboFind->currentText() != findExpr || lastBrowser != browser)
+ onceFound = false;
+ findExpr = ui.comboFind->currentText();
+
+ QTextDocument::FindFlags flags = 0;
+
+ if (ui.checkCase->isChecked())
+ flags |= QTextDocument::FindCaseSensitively;
+
+ if (ui.checkWords->isChecked())
+ flags |= QTextDocument::FindWholeWords;
+
+ QTextCursor c = browser->textCursor();
+ if (!c.hasSelection()) {
+ if (forward)
+ c.movePosition(QTextCursor::Start);
+ else
+ c.movePosition(QTextCursor::End);
+
+ browser->setTextCursor(c);
+ }
+
+ QTextDocument::FindFlags options;
+ if (forward == false)
+ flags |= QTextDocument::FindBackward;
+
+ QTextCursor found = browser->document()->find(findExpr, c, flags);
+ if (found.isNull()) {
+ if (onceFound) {
+ if (forward)
+ statusMessage(tr("Search reached end of the document"));
+ else
+ statusMessage(tr("Search reached start of the document"));
+ } else {
+ statusMessage(tr( "Text not found" ));
+ }
+ } else {
+ browser->setTextCursor(found);
+ }
+ onceFound |= !found.isNull();
+ lastBrowser = browser;
+}
+
+bool FindDialog::hasFindExpression() const
+{
+ // statusMessage(tr( "Should be obsolete" ));
+
+ //% "This is some random text"
+ qtTrId("keep_id")
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/lupdatecmd
new file mode 100644
index 000000000..500a82247
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/lupdatecmd
@@ -0,0 +1 @@
+lupdate -noobsolete project.pro
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.pro
new file mode 100644
index 000000000..63f5d66e2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.pro
@@ -0,0 +1,3 @@
+SOURCES += finddialog.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.before
new file mode 100644
index 000000000..feab1694d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.before
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name></name>
+ <message id="keep_id">
+ <location filename="finddialog.cpp" line="153"/>
+ <source>This is some random text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="obsolete_id">
+ <location filename="finddialog.cpp" line="155"/>
+ <source>Should be obsolete, too</source>
+ <translation type="unfinished">SHOULD BE OBSOLETE AS WELL</translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="85"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="135"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="137"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="139"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="150"/>
+ <source>Should be obsolete</source>
+ <translation type="unfinished">SHOULD BE OBSOLETE</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.result
new file mode 100644
index 000000000..ee3d0f69b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.result
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message id="keep_id">
+ <location filename="finddialog.cpp" line="153"/>
+ <source>This is some random text</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="85"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="135"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="137"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="139"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/finddialog.cpp
new file mode 100644
index 000000000..b712e0cb8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/finddialog.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "finddialog.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpwindow.h"
+
+#include <QTextBrowser>
+#include <QTextCursor>
+#include <QStatusBar>
+#include <QLineEdit>
+#include <QDateTime>
+#include <QGridLayout>
+
+CaseSensitiveModel::CaseSensitiveModel(int rows, int columns, QObject *parent)
+ : QStandardItemModel(rows, columns, parent)
+{}
+QModelIndexList CaseSensitiveModel::match(const QModelIndex &start, int role, const QVariant &value,
+ int hits, Qt::MatchFlags flags) const
+{
+ if (flags == Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap))
+ flags |= Qt::MatchCaseSensitive;
+
+ return QStandardItemModel::match(start, role, value, hits, flags);
+}
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ contentsWidget = new QWidget(this);
+ ui.setupUi(contentsWidget);
+ ui.comboFind->setModel(new CaseSensitiveModel(0, 1, ui.comboFind));
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+ l->addWidget(contentsWidget);
+
+ lastBrowser = 0;
+ onceFound = false;
+ findExpr.clear();
+
+ sb = new QStatusBar(this);
+ l->addWidget(sb);
+
+
+ // Move it to another line and change the text,
+ // then lupdate should add this one as a new one, and mark the old one as obsolete.
+ sb->showMessage(tr("Enter the text you want to find."));
+
+ connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findButtonClicked()));
+ connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+FindDialog::~FindDialog()
+{
+}
+
+void FindDialog::findButtonClicked()
+{
+ doFind(ui.radioForward->isChecked());
+}
+
+void FindDialog::doFind(bool forward)
+{
+ QTextBrowser *browser = static_cast<QTextBrowser*>(mainWindow()->browsers()->currentBrowser());
+ sb->clearMessage();
+
+ if (ui.comboFind->currentText() != findExpr || lastBrowser != browser)
+ onceFound = false;
+ findExpr = ui.comboFind->currentText();
+
+ QTextDocument::FindFlags flags = 0;
+
+ if (ui.checkCase->isChecked())
+ flags |= QTextDocument::FindCaseSensitively;
+
+ if (ui.checkWords->isChecked())
+ flags |= QTextDocument::FindWholeWords;
+
+ QTextCursor c = browser->textCursor();
+ if (!c.hasSelection()) {
+ if (forward)
+ c.movePosition(QTextCursor::Start);
+ else
+ c.movePosition(QTextCursor::End);
+
+ browser->setTextCursor(c);
+ }
+
+ QTextDocument::FindFlags options;
+ if (forward == false)
+ flags |= QTextDocument::FindBackward;
+
+ QTextCursor found = browser->document()->find(findExpr, c, flags);
+ if (found.isNull()) {
+ if (onceFound) {
+ if (forward)
+ statusMessage(tr("Search reached end of the document"));
+ else
+ statusMessage(tr("Search reached start of the document"));
+ } else {
+ statusMessage(tr( "Text not found" ));
+ }
+ } else {
+ browser->setTextCursor(found);
+ }
+ onceFound |= !found.isNull();
+ lastBrowser = browser;
+}
+
+bool FindDialog::hasFindExpression() const
+{
+ //% "This is some random text"
+ qtTrId("keep_id")
+
+ return !findExpr.isEmpty();
+}
+
+void FindDialog::statusMessage(const QString &message)
+{
+ if (isVisible())
+ sb->showMessage(message);
+ else
+ static_cast<MainWindow*>(parent())->statusBar()->showMessage(message, 2000);
+}
+
+MainWindow *FindDialog::mainWindow() const
+{
+ return static_cast<MainWindow*>(parentWidget());
+}
+
+void FindDialog::reset()
+{
+ ui.comboFind->setFocus();
+ ui.comboFind->lineEdit()->setSelection(
+ 0, ui.comboFind->lineEdit()->text().length());
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.pro
new file mode 100644
index 000000000..63f5d66e2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.pro
@@ -0,0 +1,3 @@
+SOURCES += finddialog.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.before
new file mode 100644
index 000000000..2bc60491c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.before
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name></name>
+ <message id="keep_id">
+ <location filename="finddialog.cpp" line="154"/>
+ <source>This is some random text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="obsolete_id">
+ <location filename="finddialog.cpp" line="155"/>
+ <source>Should be obsolete, too</source>
+ <translation type="unfinished">SHOULD BE OBSOLETE AS WELL</translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="85"/>
+ <source>Enter the text you are looking for.</source>
+ <translation type="unfinished">Skriv inn teksten du soker etter</translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="135"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="137"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="139"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.result
new file mode 100644
index 000000000..f442cbcc9
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.result
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message id="keep_id">
+ <location filename="finddialog.cpp" line="154"/>
+ <source>This is some random text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="obsolete_id">
+ <source>Should be obsolete, too</source>
+ <translation type="obsolete">SHOULD BE OBSOLETE AS WELL</translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Enter the text you are looking for.</source>
+ <translation type="obsolete">Skriv inn teksten du soker etter</translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="88"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="138"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="140"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="142"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.pro
new file mode 100644
index 000000000..fa56972dd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.pro
@@ -0,0 +1,3 @@
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before
new file mode 100644
index 000000000..6a1f62542
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="57"/>
+ <source>Qt Assistant - Find text</source>
+ <!--should be changed to unfinished, since we are changing the sourcetext in the UI file-->
+ <translation>Qt Assistant - Finn tekst</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="60"/>
+ <source>300px</source>
+ <translation>300px</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="63"/>
+ <source>400px</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.result
new file mode 100644
index 000000000..1a2244b1f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.result
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="57"/>
+ <source>Qt Assistant - Find Text</source>
+ <oldsource>Qt Assistant - Find text</oldsource>
+ <translation type="unfinished">Qt Assistant - Finn tekst</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="60"/>
+ <source>300px</source>
+ <translation>300px</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="63"/>
+ <source>401 pixels</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ui b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ui
new file mode 100644
index 000000000..aeabcaa95
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ui
@@ -0,0 +1,77 @@
+<ui version="4.0" >
+ <author></author>
+ <comment>
+*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************
+</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant - Find Text</string><!-- changed to uppercase, marked as finished -->
+ </property>
+ <property name="height" >
+ <string>300px</string>
+ </property>
+ <property name="width" >
+ <string>401 pixels</string><!-- Changed from 400px to 401 pixels, but this is marked as unfinished -->
+ </property>
+ </widget>
+ <tabstops>
+ <tabstop>comboFind</tabstop>
+ <tabstop>checkWords</tabstop>
+ <tabstop>checkCase</tabstop>
+ <tabstop>radioForward</tabstop>
+ <tabstop>radioBackward</tabstop>
+ <tabstop>findButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.pro
new file mode 100644
index 000000000..fa56972dd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.pro
@@ -0,0 +1,3 @@
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.before
new file mode 100644
index 000000000..f06c22ca8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.before
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="20"/>
+ <source>Test similarity</source>
+ <translation type="unfinished">Test likhet (test1)</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="23"/>
+ <source>Similarity should have kicked in here!</source>
+ <translation type="unfinished">Test likhet (test2)</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result
new file mode 100644
index 000000000..6bc565c1e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Test similarity</source>
+ <translation type="obsolete">Test likhet (test1)</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="20"/>
+ <source>This should not be considered to be more or less equal to the corresponding one in the TS file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="23"/>
+ <source>Here, similarity should kick in!</source>
+ <oldsource>Similarity should have kicked in here!</oldsource>
+ <translation type="unfinished">Test likhet (test2)</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui
new file mode 100644
index 000000000..a5f8e9f79
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui
@@ -0,0 +1,26 @@
+<ui version="4.0" >
+ <author></author>
+ <comment><!--
+*********************************************************************
+**
+** Do not change the location (linenumber) of the <string> elements in this file!
+** That will make the test break!
+**
+** If you need to add some tests, please add them to the end of the file!
+**
+**
+*********************************************************************
+-->
+</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="test1">
+ <!-- If the sourcetext is not similar to the vernacular sourcetext, mark the old one as obsolete and the new one as unfinished -->
+ <string>This should not be considered to be more or less equal to the corresponding one in the TS file.</string>
+ </property>
+ <property name="test2">
+ <string>Here, similarity should kick in!</string>
+ </property>
+ </widget>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/good/multiple_locations/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/finddialog.cpp
new file mode 100644
index 000000000..9458bc322
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/finddialog.cpp
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QT_TRANSLATE_NOOP("context", "just a message")
+
+
+
+//: This is one comment
+QT_TRANSLATE_NOOP("context", "just a message")
diff --git a/tests/auto/linguist/lupdate/testdata/good/multiple_locations/main.cpp b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/main.cpp
new file mode 100644
index 000000000..8200191a4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+
+//: This is a comment, too.
+QT_TRANSLATE_NOOP("context", "just a message")
+
+
+
+
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.pro b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.pro
new file mode 100644
index 000000000..bbabdfba2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.pro
@@ -0,0 +1,4 @@
+SOURCES += main.cpp
+SOURCES += finddialog.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.ts.result
new file mode 100644
index 000000000..a7ae15520
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>context</name>
+ <message>
+ <location filename="finddialog.cpp" line="42"/>
+ <location filename="finddialog.cpp" line="47"/>
+ <location filename="main.cpp" line="46"/>
+ <source>just a message</source>
+ <extracomment>This is one comment
+----------
+This is a comment, too.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/namespaces/main.cpp b/tests/auto/linguist/lupdate/testdata/good/namespaces/main.cpp
new file mode 100644
index 000000000..e99171f16
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/namespaces/main.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+
+class Class : public QObject
+{
+ Q_OBJECT
+
+ class SubClass
+ {
+ void f()
+ {
+ tr("nested class context");
+ }
+ };
+
+ void f()
+ {
+ tr("just class context");
+ }
+};
+
+namespace Outer {
+
+class Class : public QObject { Q_OBJECT };
+
+namespace Middle1 {
+
+class Class : public QObject { Q_OBJECT };
+
+namespace Inner1 {
+
+class Class : public QObject { Q_OBJECT };
+
+}
+
+namespace I = Inner1;
+
+class Something;
+class Different;
+
+}
+
+namespace Middle2 {
+
+class Class : public QObject { Q_OBJECT };
+
+namespace Inner2 {
+
+class Class : public QObject { Q_OBJECT };
+
+namespace IO = Middle2;
+
+}
+
+namespace I = Inner2;
+
+}
+
+namespace MI = Middle1::Inner1;
+
+namespace O = ::Outer;
+
+class Middle1::Different : QObject {
+Q_OBJECT
+ void f() {
+ tr("different namespaced class def");
+ }
+};
+
+}
+
+namespace O = Outer;
+namespace OM = Outer::Middle1;
+namespace OMI = Outer::Middle1::I;
+
+int main()
+{
+ Class::tr("outestmost class");
+ Outer::Class::tr("outer class");
+ Outer::MI::Class::tr("innermost one");
+ OMI::Class::tr("innermost two");
+ O::Middle1::I::Class::tr("innermost three");
+ O::Middle2::I::Class::tr("innermost three b");
+ OM::I::Class::tr("innermost four");
+ return 0;
+}
+
+class OM::Something : QObject {
+Q_OBJECT
+ void f() {
+ tr("namespaced class def");
+ }
+ void g() {
+ tr("namespaced class def 2");
+ }
+};
+
+// QTBUG-8360
+namespace A {
+
+void foo()
+{
+ using namespace A;
+}
+
+void goo()
+{
+ return QObject::tr("Bla");
+}
+
+}
+
+
+namespace AA {
+namespace B {
+
+using namespace AA;
+
+namespace C {
+
+class Test : public QObject {
+ Q_OBJECT
+};
+
+}
+
+}
+
+using namespace B;
+using namespace C;
+
+void goo()
+{
+ AA::Test::tr("howdy?");
+}
+
+}
+
+
+namespace A1 {
+namespace B {
+
+class Test : public QObject {
+ Q_OBJECT
+};
+
+using namespace A1;
+
+void foo()
+{
+ B::B::B::Test::tr("yeeee-ha!");
+}
+
+}
+}
+
+
+#include "main.moc"
diff --git a/tests/auto/linguist/lupdate/testdata/good/namespaces/project.pro b/tests/auto/linguist/lupdate/testdata/good/namespaces/project.pro
new file mode 100644
index 000000000..c96859bdb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/namespaces/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/namespaces/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/namespaces/project.ts.result
new file mode 100644
index 000000000..94df9d3f8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/namespaces/project.ts.result
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>A1::B::Test</name>
+ <message>
+ <location filename="main.cpp" line="191"/>
+ <source>yeeee-ha!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AA::B::C::Test</name>
+ <message>
+ <location filename="main.cpp" line="174"/>
+ <source>howdy?</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Class</name>
+ <message>
+ <location filename="main.cpp" line="52"/>
+ <source>nested class context</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="58"/>
+ <source>just class context</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="118"/>
+ <source>outestmost class</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Class</name>
+ <message>
+ <location filename="main.cpp" line="119"/>
+ <source>outer class</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Middle1::Different</name>
+ <message>
+ <location filename="main.cpp" line="106"/>
+ <source>different namespaced class def</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Middle1::Inner1::Class</name>
+ <message>
+ <location filename="main.cpp" line="120"/>
+ <source>innermost one</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="121"/>
+ <source>innermost two</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="122"/>
+ <source>innermost three</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="124"/>
+ <source>innermost four</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Middle1::Something</name>
+ <message>
+ <location filename="main.cpp" line="131"/>
+ <source>namespaced class def</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="134"/>
+ <source>namespaced class def 2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Middle2::Inner2::Class</name>
+ <message>
+ <location filename="main.cpp" line="123"/>
+ <source>innermost three b</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="148"/>
+ <source>Bla</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/main.cpp
new file mode 100644
index 000000000..86d93ff96
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+class Dialog2 : public QDialog
+{
+ Q_OBJECT
+ void func();
+
+};
+
+void Dialog2::func()
+{
+ tr("cat\351gorie");
+
+ tr("F\374r \310lise")
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.pro b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.pro
new file mode 100644
index 000000000..c96859bdb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.ts.result
new file mode 100644
index 000000000..0394bea0e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Dialog2</name>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source>catégorie</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="56"/>
+ <source>Für Èlise</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp
new file mode 100644
index 000000000..8de7cd444
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp
@@ -0,0 +1,279 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+#include <QtCore>
+#include <QtGui>
+
+//
+// Test namespace scoping
+//
+
+class D : public QObject {
+ Q_OBJECT
+ public:
+ QString foo() {
+ return tr("test", "D");
+ }
+
+};
+
+namespace A {
+
+ class C : public QObject {
+ Q_OBJECT
+ public:
+ void foo();
+ };
+
+ void C::foo() {
+ tr("Bla", "A::C");
+ }
+
+ void goo() {
+ C::tr("Bla", "A::C"); // Is identical to the previous tr(), (same context, sourcetext and comment,
+ // so it should not add another entry to the list of messages)
+ }
+
+ void goo2() {
+ C::tr("Bla 2", "A::C"); //Should be in the same namespace as the previous tr()
+ }
+
+}
+
+
+namespace X {
+
+ class D : public QObject {
+ Q_OBJECT
+ public:
+
+ };
+
+ class E : public QObject {
+ Q_OBJECT
+ public:
+ void foo() { D::tr("foo", "D"); } // Note that this is X::D from 440 on
+ };
+
+
+ namespace Y {
+ class E : public QObject {
+ Q_OBJECT
+
+ };
+
+ class C : public QObject {
+ Q_OBJECT
+ void foo();
+ };
+
+ void C::foo() {
+ tr("Bla", "X::Y::C");
+ }
+
+ void goo() {
+ D::tr("Bla", "X::D"); //This should be assigned to the X::D context
+ }
+
+ void goo2() {
+ E::tr("Bla", "X::Y::E"); //This should be assigned to the X::Y::E context
+ Y::E::tr("Bla", "X::Y::E"); //This should be assigned to the X::Y::E context
+ }
+
+ }; // namespace Y
+
+ class F : public QObject {
+ Q_OBJECT
+ inline void inlinefunc() {
+ tr("inline function", "X::F");
+ }
+ };
+} // namespace X
+
+namespace ico {
+ namespace foo {
+ class A : public QObject {
+ A();
+ };
+
+ A::A() {
+ tr("myfoo", "ico::foo::A");
+ QObject::tr("task 161186", "QObject");
+ }
+ }
+}
+
+namespace AA {
+class C {};
+}
+
+/**
+ * the context of a message should not be affected by any inherited classes
+ *
+ * Keep this disabled for now, but at a long-term range it should work.
+ */
+namespace Gui {
+ class MainWindow : public QMainWindow,
+ public AA::C
+ {
+ Q_OBJECT
+public:
+ MainWindow()
+ {
+ tr("More bla", "Gui::MainWindow");
+ }
+
+ };
+} //namespace Gui
+
+
+namespace A1 {
+ class AB : public QObject {
+ Q_OBJECT
+ public:
+
+ friend class OtherClass;
+
+ QString inlineFuncAfterFriendDeclaration() const {
+ return tr("inlineFuncAfterFriendDeclaration", "A1::AB");
+ }
+ };
+ class B : AB {
+ Q_OBJECT
+ public:
+ QString foo() const { return tr("foo", "A1::B"); }
+ };
+
+ // This is valid C++ too....
+ class V : virtual AB {
+ Q_OBJECT
+ public:
+ QString bar() const { return tr("bar", "A1::V"); }
+ };
+
+ class W : virtual public AB {
+ Q_OBJECT
+ public:
+ QString baz() const { return tr("baz", "A1::W"); }
+ };
+}
+
+class ForwardDecl;
+
+
+class B1 : public QObject {
+};
+
+class C1 : public QObject {
+};
+
+namespace A1 {
+
+class B2 : public QObject {
+};
+
+}
+
+void func1()
+{
+ B1::tr("test TRANSLATOR comment (1)", "B1");
+
+}
+
+using namespace A1;
+/*
+ TRANSLATOR A1::B2
+*/
+void func2()
+{
+ B2::tr("test TRANSLATOR comment (2)", "A1::B2");
+ C1::tr("test TRANSLATOR comment (3)", "C1");
+}
+
+void func3()
+{
+ B2::tr("test TRANSLATOR comment (4)", "A1::B2");
+}
+
+/*
+ TRANSLATOR B2
+ This is a comment to the translator.
+*/
+void func4()
+{
+ B2::tr("test TRANSLATOR comment (5)", "A1::B2");
+}
+
+namespace A1 {
+namespace B3 {
+class C2 : public QObject {
+QString foo();
+};
+}
+}
+
+namespace D1 = A1::B3;
+using namespace D1;
+
+// TRANSLATOR A1::B3::C2
+QString C2::foo()
+{
+ return tr("test TRANSLATOR comment (6)", "A1::B3::C2"); // 4.4 screws up
+}
+
+
+namespace Fooish {
+ Q_DECLARE_TR_FUNCTIONS(Bears::And::Spiders)
+}
+
+void Fooish::bar()
+{
+ return tr("whatever the context", "Bears::And::Spiders");
+}
+
+
+int main(int /*argc*/, char ** /*argv*/) {
+ return 0;
+}
+
+#include "main.moc"
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.pro
new file mode 100644
index 000000000..759bea068
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.pro
@@ -0,0 +1,3 @@
+SOURCES = main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result
new file mode 100644
index 000000000..53d7a2581
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>A1::AB</name>
+ <message>
+ <location filename="main.cpp" line="178"/>
+ <source>inlineFuncAfterFriendDeclaration</source>
+ <comment>A1::AB</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::B</name>
+ <message>
+ <location filename="main.cpp" line="184"/>
+ <source>foo</source>
+ <comment>A1::B</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::B2</name>
+ <message>
+ <location filename="main.cpp" line="229"/>
+ <source>test TRANSLATOR comment (2)</source>
+ <comment>A1::B2</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="235"/>
+ <source>test TRANSLATOR comment (4)</source>
+ <comment>A1::B2</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="244"/>
+ <source>test TRANSLATOR comment (5)</source>
+ <comment>A1::B2</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::B3::C2</name>
+ <message>
+ <location filename="main.cpp" line="261"/>
+ <source>test TRANSLATOR comment (6)</source>
+ <comment>A1::B3::C2</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::V</name>
+ <message>
+ <location filename="main.cpp" line="191"/>
+ <source>bar</source>
+ <comment>A1::V</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::W</name>
+ <message>
+ <location filename="main.cpp" line="197"/>
+ <source>baz</source>
+ <comment>A1::W</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A::C</name>
+ <message>
+ <location filename="main.cpp" line="69"/>
+ <location filename="main.cpp" line="73"/>
+ <source>Bla</source>
+ <comment>A::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="78"/>
+ <source>Bla 2</source>
+ <comment>A::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>B1</name>
+ <message>
+ <location filename="main.cpp" line="219"/>
+ <source>test TRANSLATOR comment (1)</source>
+ <comment>B1</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>B2</name>
+ <message>
+ <location filename="main.cpp" line="238"/>
+ <source></source>
+ <comment>This is a comment to the translator.</comment>
+ <translation></translation>
+ </message>
+</context>
+<context>
+ <name>Bears::And::Spiders</name>
+ <message>
+ <location filename="main.cpp" line="271"/>
+ <source>whatever the context</source>
+ <comment>Bears::And::Spiders</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>C1</name>
+ <message>
+ <location filename="main.cpp" line="230"/>
+ <source>test TRANSLATOR comment (3)</source>
+ <comment>C1</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>D</name>
+ <message>
+ <location filename="main.cpp" line="55"/>
+ <source>test</source>
+ <comment>D</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Gui::MainWindow</name>
+ <message>
+ <location filename="main.cpp" line="163"/>
+ <source>More bla</source>
+ <comment>Gui::MainWindow</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="141"/>
+ <source>task 161186</source>
+ <comment>QObject</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>X::D</name>
+ <message>
+ <location filename="main.cpp" line="95"/>
+ <source>foo</source>
+ <comment>D</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="115"/>
+ <source>Bla</source>
+ <comment>X::D</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>X::F</name>
+ <message>
+ <location filename="main.cpp" line="128"/>
+ <source>inline function</source>
+ <comment>X::F</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>X::Y::C</name>
+ <message>
+ <location filename="main.cpp" line="111"/>
+ <source>Bla</source>
+ <comment>X::Y::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>X::Y::E</name>
+ <message>
+ <location filename="main.cpp" line="119"/>
+ <location filename="main.cpp" line="120"/>
+ <source>Bla</source>
+ <comment>X::Y::E</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ico::foo::A</name>
+ <message>
+ <location filename="main.cpp" line="140"/>
+ <source>myfoo</source>
+ <comment>ico::foo::A</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/finddialog.cpp
new file mode 100644
index 000000000..9f6bc5b56
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/finddialog.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the autotests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "finddialog.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpwindow.h"
+
+#include <QTextBrowser>
+#include <QTextCursor>
+#include <QStatusBar>
+#include <QLineEdit>
+#include <QDateTime>
+#include <QGridLayout>
+
+CaseSensitiveModel::CaseSensitiveModel(int rows, int columns, QObject *parent)
+ : QStandardItemModel(rows, columns, parent)
+{}
+QModelIndexList CaseSensitiveModel::match(const QModelIndex &start, int role, const QVariant &value,
+ int hits, Qt::MatchFlags flags) const
+{
+ if (flags == Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap))
+ flags |= Qt::MatchCaseSensitive;
+
+ return QStandardItemModel::match(start, role, value, hits, flags);
+}
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ contentsWidget = new QWidget(this);
+ ui.setupUi(contentsWidget);
+ ui.comboFind->setModel(new CaseSensitiveModel(0, 1, ui.comboFind));
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+ l->addWidget(contentsWidget);
+
+ lastBrowser = 0;
+ onceFound = false;
+ findExpr.clear();
+
+ sb = new QStatusBar(this);
+ l->addWidget(sb);
+
+ sb->showMessage(tr("Enter the text you are looking for."));
+
+ connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findButtonClicked()));
+ connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+FindDialog::~FindDialog()
+{
+}
+
+void FindDialog::findButtonClicked()
+{
+ doFind(ui.radioForward->isChecked());
+}
+
+void FindDialog::doFind(bool forward)
+{
+ QTextBrowser *browser = static_cast<QTextBrowser*>(mainWindow()->browsers()->currentBrowser());
+ sb->clearMessage();
+
+ if (ui.comboFind->currentText() != findExpr || lastBrowser != browser)
+ onceFound = false;
+ findExpr = ui.comboFind->currentText();
+
+ QTextDocument::FindFlags flags = 0;
+
+ if (ui.checkCase->isChecked())
+ flags |= QTextDocument::FindCaseSensitively;
+
+ if (ui.checkWords->isChecked())
+ flags |= QTextDocument::FindWholeWords;
+
+ QTextCursor c = browser->textCursor();
+ if (!c.hasSelection()) {
+ if (forward)
+ c.movePosition(QTextCursor::Start);
+ else
+ c.movePosition(QTextCursor::End);
+
+ browser->setTextCursor(c);
+ }
+
+ QTextDocument::FindFlags options;
+ if (forward == false)
+ flags |= QTextDocument::FindBackward;
+
+ QTextCursor found = browser->document()->find(findExpr, c, flags);
+ if (found.isNull()) {
+ if (onceFound) {
+ if (forward)
+ statusMessage(tr("Search reached end of the document"));
+ else
+ statusMessage(tr("Search reached start of the document"));
+ } else {
+ statusMessage(tr( "Text not found" ));
+ }
+ } else {
+ browser->setTextCursor(found);
+ }
+ onceFound |= !found.isNull();
+ lastBrowser = browser;
+}
+
+bool FindDialog::hasFindExpression() const
+{
+ return !findExpr.isEmpty();
+}
+
+void FindDialog::statusMessage(const QString &message)
+{
+ if (isVisible())
+ sb->showMessage(message);
+ else
+ static_cast<MainWindow*>(parent())->statusBar()->showMessage(message, 2000);
+}
+
+MainWindow *FindDialog::mainWindow() const
+{
+ return static_cast<MainWindow*>(parentWidget());
+}
+
+void FindDialog::reset()
+{
+ ui.comboFind->setFocus();
+ ui.comboFind->lineEdit()->setSelection(
+ 0, ui.comboFind->lineEdit()->text().length());
+
+ QString s = QApplication::translate("QCoreApplication", "with comment", "comment");
+ QString s = QApplication::translate("QCoreApplication", "empty comment", "");
+ QString s = QApplication::translate("QCoreApplication", "null comment", 0);
+ QString s = tr("null comment");
+
+ QString s = QApplication::translate("QCoreApplication", "encoding, using QCoreApplication", 0, QCoreApplication::UnicodeUTF8);
+ QString s = QApplication::translate("QCoreApplication", "encoding, using QApplication", 0, QApplication::UnicodeUTF8);
+
+ QString s = QApplication::translate("KÃ¥ntekst", "encoding, using QApplication", 0, QApplication::UnicodeUTF8);
+
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
new file mode 100644
index 000000000..6f9220cd1
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
@@ -0,0 +1,345 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+int main(char **argv, int argc)
+{
+ Size size = QSize(1,1);
+}
+
+QString qt_detectRTLLanguage()
+{
+ return QApplication::tr("QT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget layout.") == QLatin1String("RTL");
+}
+
+
+class Dialog2 : public QDialog
+{
+ Q_OBJECT
+ void func();
+ void func3();
+ int getCount() const { return 2; }
+
+};
+
+void Dialog2::func()
+{
+ int n = getCount();
+ tr("%n files", "plural form", n);
+ tr("%n cars", 0, n);
+ tr("&Find %n cars", 0, n);
+ tr("Search in %n items?", 0, n);
+ tr("%1. Search in %n items?", 0, n);
+ tr("Age: %1");
+ tr("There are %n house(s)", "Plurals and function call", getCount());
+
+
+
+
+ QCoreApplication::translate("Plurals, QCoreApplication", "%n house(s)", "Plurals and identifier", QCoreApplication::UnicodeUTF8, n);
+ QCoreApplication::translate("Plurals, QCoreApplication", "%n car(s)", "Plurals and literal number", QCoreApplication::UnicodeUTF8, 1);
+ QCoreApplication::translate("Plurals, QCoreApplication", "%n horse(s)", "Plurals and function call", QCoreApplication::UnicodeUTF8, getCount());
+
+
+
+
+
+
+
+
+ QTranslator trans;
+ trans.translate("QTranslator", "Simple");
+ trans.translate("QTranslator", "Simple", 0);
+ trans.translate("QTranslator", "Simple with comment", "with comment");
+ trans.translate("QTranslator", "Plural without comment", 0, 1);
+ trans.translate("QTranslator", "Plural with comment", "comment 1", n);
+ trans.translate("QTranslator", "Plural with comment", "comment 2", getCount());
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+
+
+
+/* This is actually a test of how many alternative ways a struct/class can be found in a source file.
+ * Due to the simple parser in lupdate, it will actually not treat the remaining lines in the define
+ * as a macro, which is a case the 'Tok_Class' parser block might not consider, and it might loop infinite
+ * if it just tries to fetch the next token until it gets a '{' or a ';'. Another pitfall is that the
+ * context of tr("func3") might not be parsed, it won't resume normal evaluation until the '{' after the function
+ * signature.
+ *
+ */
+typedef struct S_
+{
+int a;
+} S, *SPtr;
+class ForwardDecl;
+
+
+#define FT_DEFINE_SERVICE( name ) \
+ typedef struct FT_Service_ ## name ## Rec_ \
+ FT_Service_ ## name ## Rec ; \
+ typedef struct FT_Service_ ## name ## Rec_ \
+ const * FT_Service_ ## name ; \
+ struct FT_Service_ ## name ## Rec_
+
+
+/* removing this comment will break this test */
+
+void Dialog2::func3()
+{
+ tr("func3");
+}
+
+
+
+
+namespace Gui { class BaseClass {}; }
+
+
+class TestClass : QObject {
+ Q_OBJECT
+
+
+ inline QString inlineFunc1() {
+ return tr("inline function", "TestClass");
+ }
+
+ QString inlineFunc2() {
+ return tr("inline function 2", "TestClass");
+ }
+
+ static inline QString staticInlineFunc() {
+ return tr("static inline function", "TestClass");
+ }
+
+ class NoQObject : public Gui::BaseClass {
+ public:
+ inline QString hello() { return QString("hello"); }
+
+ };
+
+};
+
+
+class Testing : QObject {
+ Q_OBJECT
+
+ inline QString f1() {
+ //: this is an extra comment for the translator
+ return tr("extra-commented string");
+ return tr("not extra-commented string");
+ /*: another extra-comment */
+ return tr("another extra-commented string");
+ /*: blah! */
+ return QApplication::translate("scope", "works in translate, too", "blabb", 0);
+ }
+
+};
+
+//: extra comment for NOOP
+//: which spans multiple lines
+QT_TRANSLATE_NOOP("scope", "string") // 4.4 says the line of this is at the next statement
+//: extra comment for NOOP3
+QT_TRANSLATE_NOOP3_UTF8("scope", "string", "comment") // 4.4 doesn't see this
+
+QT_TRANSLATE_NOOP("scope", "string " // this is an interleaved comment
+ "continuation on next line")
+
+
+class TestingTake17 : QObject {
+ Q_OBJECT
+
+ int function(void)
+ {
+ //: random comment
+ //= this_is_an_id
+ //~ loc-layout_id fooish_bar
+ //~ po-ignore_me totally foo-barred nonsense
+ tr("something cool");
+
+ tr("less cool");
+
+ //= another_id
+ tr("even more cool");
+ }
+};
+
+
+
+
+//: again an extra comment, this time for id-based NOOP
+//% "This is supposed\tto be quoted \" newline\n"
+//% "backslashed \\ stuff."
+QT_TRID_NOOP("this_a_id")
+
+//~ some thing
+//% "This needs to be here. Really."
+QString test = qtTrId("this_another_id", n);
+
+
+
+class YetAnotherTest : QObject {
+ Q_OBJECT
+
+ int function(void)
+ {
+ //
+ //:
+ //=
+ //~
+ //#
+ //=============
+ //~~~~~~~~~~~~~
+ //:::::::::::::
+ tr("nothing");
+ }
+};
+
+
+
+//: This is a message without a source string
+QString test = qtTrId("yet_another_id");
+
+
+
+// QTBUG-9276: context in static initializers
+class Bogus : QObject {
+ Q_OBJECT
+
+ static const char * const s_strings[];
+};
+
+const char * const Bogus::s_strings[] = {
+ QT_TR_NOOP("this should be in Bogus")
+};
+
+const char * const Bogus::s_strings[SIZE] = {
+ QT_TR_NOOP("this should be in Bogus")
+};
+
+void bogosity()
+{
+ // no spaces here. test collateral damage from ignoring equal sign
+ Class::member=QObject::tr("just QObject");
+}
+
+
+
+namespace Internal {
+
+class Message : public QObject
+{
+ Q_OBJECT
+public:
+ Message(QObject *parent = 0);
+};
+
+} // The temporary closing of the namespace triggers the problem
+
+namespace Internal {
+
+static inline QString message1()
+{
+ return Message::tr("message1"); // Had no namespace
+}
+
+static inline QString message2()
+{
+ return Message::tr("message2"); // Already had namespace
+}
+
+}
+
+
+
+// QTBUG-11426: operator overloads
+class LotsaFun : public QObject
+{
+ Q_OBJECT
+public:
+ int operator<<(int left, int right);
+};
+
+int LotsaFun::operator<<(int left, int right)
+{
+ tr("this is inside operator<<");
+ return left << right;
+}
+
+
+
+// QTBUG-12683: define in re-opened namespace
+namespace NameSchpace {
+
+class YetMoreFun : public QObject
+{
+ Q_OBJECT
+public:
+ void funStuff();
+};
+
+}
+
+namespace NameSchpace {
+
+#define somevar 1
+
+void YetMoreFun::funStuff()
+{
+ tr("funStuff!");
+}
+
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.pro
new file mode 100644
index 000000000..bbabdfba2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.pro
@@ -0,0 +1,4 @@
+SOURCES += main.cpp
+SOURCES += finddialog.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
new file mode 100644
index 000000000..f73fc6477
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
@@ -0,0 +1,370 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message id="this_a_id">
+ <location filename="main.cpp" line="226"/>
+ <source>This is supposed to be quoted &quot; newline
+backslashed \ stuff.</source>
+ <extracomment>again an extra comment, this time for id-based NOOP</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="this_another_id" numerus="yes">
+ <location filename="main.cpp" line="230"/>
+ <source>This needs to be here. Really.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ <extra-some>thing</extra-some>
+ </message>
+ <message id="yet_another_id">
+ <location filename="main.cpp" line="254"/>
+ <source></source>
+ <extracomment>This is a message without a source string</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Bogus</name>
+ <message>
+ <location filename="main.cpp" line="266"/>
+ <location filename="main.cpp" line="270"/>
+ <source>this should be in Bogus</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Dialog2</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="70"/>
+ <source>%n files</source>
+ <comment>plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="71"/>
+ <source>%n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="72"/>
+ <source>&amp;Find %n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="73"/>
+ <source>Search in %n items?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="74"/>
+ <source>%1. Search in %n items?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="75"/>
+ <source>Age: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="76"/>
+ <source>There are %n house(s)</source>
+ <comment>Plurals and function call</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="143"/>
+ <source>func3</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="85"/>
+ <source>Enter the text you are looking for.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="135"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="137"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="139"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="175"/>
+ <source>null comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Internal::Message</name>
+ <message>
+ <location filename="main.cpp" line="296"/>
+ <source>message1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="301"/>
+ <source>message2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>KÃ¥ntekst</name>
+ <message utf8="true">
+ <location filename="finddialog.cpp" line="180"/>
+ <source>encoding, using QApplication</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LotsaFun</name>
+ <message>
+ <location filename="main.cpp" line="318"/>
+ <source>this is inside operator&lt;&lt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>NameSchpace::YetMoreFun</name>
+ <message>
+ <location filename="main.cpp" line="342"/>
+ <source>funStuff!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Plurals, QCoreApplication</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="81"/>
+ <source>%n house(s)</source>
+ <comment>Plurals and identifier</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="82"/>
+ <source>%n car(s)</source>
+ <comment>Plurals and literal number</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="83"/>
+ <source>%n horse(s)</source>
+ <comment>Plurals and function call</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="51"/>
+ <source>QT_LAYOUT_DIRECTION</source>
+ <comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QCoreApplication</name>
+ <message>
+ <location filename="finddialog.cpp" line="172"/>
+ <source>with comment</source>
+ <comment>comment</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="173"/>
+ <source>empty comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="174"/>
+ <source>null comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="177"/>
+ <source>encoding, using QCoreApplication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="178"/>
+ <source>encoding, using QApplication</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="276"/>
+ <source>just QObject</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QTranslator</name>
+ <message>
+ <location filename="main.cpp" line="93"/>
+ <location filename="main.cpp" line="94"/>
+ <source>Simple</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="95"/>
+ <source>Simple with comment</source>
+ <comment>with comment</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="96"/>
+ <source>Plural without comment</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="97"/>
+ <source>Plural with comment</source>
+ <comment>comment 1</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="98"/>
+ <source>Plural with comment</source>
+ <comment>comment 2</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>TestClass</name>
+ <message>
+ <location filename="main.cpp" line="157"/>
+ <source>inline function</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="161"/>
+ <source>inline function 2</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="165"/>
+ <source>static inline function</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Testing</name>
+ <message>
+ <location filename="main.cpp" line="182"/>
+ <source>extra-commented string</source>
+ <extracomment>this is an extra comment for the translator</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="183"/>
+ <source>not extra-commented string</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="185"/>
+ <source>another extra-commented string</source>
+ <extracomment>another extra-comment</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TestingTake17</name>
+ <message id="this_is_an_id">
+ <location filename="main.cpp" line="211"/>
+ <source>something cool</source>
+ <extracomment>random comment</extracomment>
+ <translation type="unfinished"></translation>
+ <extra-po-ignore_me>totally foo-barred nonsense</extra-po-ignore_me>
+ <extra-loc-layout_id>fooish_bar</extra-loc-layout_id>
+ </message>
+ <message>
+ <location filename="main.cpp" line="213"/>
+ <source>less cool</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="another_id">
+ <location filename="main.cpp" line="216"/>
+ <source>even more cool</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>YetAnotherTest</name>
+ <message>
+ <location filename="main.cpp" line="247"/>
+ <source>nothing</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>scope</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="187"/>
+ <source>works in translate, too</source>
+ <comment>blabb</comment>
+ <extracomment>blah!</extracomment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="194"/>
+ <source>string</source>
+ <extracomment>extra comment for NOOP which spans multiple lines</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="196"/>
+ <source>string</source>
+ <comment>comment</comment>
+ <extracomment>extra comment for NOOP3</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="198"/>
+ <source>string continuation on next line</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt
new file mode 100644
index 000000000..d4ebe4992
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt
@@ -0,0 +1,7 @@
+.*/lupdate/testdata/good/parsecpp2/main.cpp:51: Excess closing brace .*
+.*/lupdate/testdata/good/parsecpp2/main.cpp:55: Excess closing brace .*
+.*/lupdate/testdata/good/parsecpp2/main.cpp:61: Excess closing brace .*
+.*/lupdate/testdata/good/parsecpp2/main.cpp:65: Excess closing brace .*
+.*/lupdate/testdata/good/parsecpp2/main.cpp:120: //% cannot be used with tr\(\) / QT_TR_NOOP\(\)\. Ignoring
+.*/lupdate/testdata/good/parsecpp2/main.cpp:123: //% cannot be used with translate\(\) / QT_TRANSLATE_NOOP\(\)\. Ignoring
+.*/lupdate/testdata/good/parsecpp2/main.cpp:126: Discarding unconsumed meta data
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
new file mode 100644
index 000000000..cf39ef354
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+// nothing here
+
+// sickness: multi-\
+line c++ comment } (with brace)
+
+#define This is a closing brace } which was ignored
+} // complain here
+
+#define This is another \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another /* comment in } define */\
+ something /* comment )
+ spanning {multiple} lines */ \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another // comment in } define \
+ something } comment
+} // complain here
+
+
+
+// Nested class in same file
+class TopLevel {
+ Q_OBJECT
+
+ class Nested;
+};
+
+class TopLevel::Nested {
+ void foo();
+};
+
+TopLevel::Nested::foo()
+{
+ TopLevel::tr("TopLevel");
+}
+
+// Nested class in other file
+#include "main.h"
+
+class TopLevel2::Nested {
+ void foo();
+};
+
+TopLevel2::Nested::foo()
+{
+ TopLevel2::tr("TopLevel2");
+}
+
+
+
+namespace NameSpace {
+class ToBeUsed;
+}
+
+// using statement before class definition
+using NameSpace::ToBeUsed;
+
+class NameSpace::ToBeUsed {
+ Q_OBJECT
+ void caller();
+};
+
+void ToBeUsed::caller()
+{
+ tr("NameSpace::ToBeUsed");
+}
+
+
+
+// QTBUG-11818
+//% "Foo"
+QObject::tr("Hello World");
+QObject::tr("Hello World");
+//% "Bar"
+QApplication::translate("QObject", "Hello World");
+QApplication::translate("QObject", "Hello World");
+//% "Baz"
+clear = me;
+QObject::tr("Hello World");
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.h b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.h
new file mode 100644
index 000000000..ee41232cf
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+class TopLevel2 {
+ Q_OBJECT
+
+ class Nested;
+};
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp
new file mode 100644
index 000000000..a9290608a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+// nothing here
+
+// sickness: multi-\
+line c++ comment } (with brace)
+
+#define This is a closing brace } which was ignored
+} // complain here
+
+#define This is another \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another /* comment in } define */\
+ something /* comment )
+ spanning {multiple} lines */ \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another // comment in } define \
+ something } comment
+} // complain here
+
+char somestring[] = "\
+ continued\n\
+ here and \"quoted\" to activate\n";
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp
new file mode 100644
index 000000000..d08af6205
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+// nothing here
+
+// sickness: multi-\
+line c++ comment } (with brace)
+
+#define This is a closing brace } which was ignored
+} // complain here
+
+#define This is another \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another /* comment in } define */\
+ something /* comment )
+ spanning {multiple} lines */ \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another // comment in } define \
+ something } comment
+} // complain here
+
+char somestring[] = "\
+ continued\n\
+ here and \"quoted\" to activate\n";
+
+ NSString *scriptSource = @"\
+ on SetupNewMail(theRecipientAddress, theSubject, theContent, theAttachmentPath)\n\
+ tell application \"Mail\" to activate\n\
+ tell application \"Mail\"\n\
+ set theMessage to make new outgoing message with properties {visible:true, subject:theSubject, content:theContent}\n\
+ tell theMessage\n\
+ make new to recipient at end of to recipients with properties {address:theRecipientAddress}\n\
+ end tell\n\
+ tell content of theMessage\n\
+ make new attachment with properties {file name:theAttachmentPath} at after last paragraph\n\
+ end tell\n\
+ end tell\n\
+ end SetupNewMail\n";
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro
new file mode 100644
index 000000000..759bea068
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro
@@ -0,0 +1,3 @@
+SOURCES = main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
new file mode 100644
index 000000000..806f56f99
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>NameSpace::ToBeUsed</name>
+ <message>
+ <location filename="main.cpp" line="113"/>
+ <source>NameSpace::ToBeUsed</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="120"/>
+ <location filename="main.cpp" line="121"/>
+ <location filename="main.cpp" line="123"/>
+ <location filename="main.cpp" line="124"/>
+ <location filename="main.cpp" line="127"/>
+ <source>Hello World</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TopLevel</name>
+ <message>
+ <location filename="main.cpp" line="82"/>
+ <source>TopLevel</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TopLevel2</name>
+ <message>
+ <location filename="main.cpp" line="94"/>
+ <source>TopLevel2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejava/main.java b/tests/auto/linguist/lupdate/testdata/good/parsejava/main.java
new file mode 100644
index 000000000..710588986
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejava/main.java
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+package com.trolltech.examples;
+
+public class I18N extends QDialog {
+
+ private class MainWindow extends QMainWindow {
+ private String foo = tr("pack class class");
+
+ //: extra comment for t-tor
+ private String bar = tr("pack class class extra");
+
+ public MainWindow(QWidget parent) {
+ super(parent);
+
+ listWidget = new QListWidget();
+ listWidget.addItem(tr("pack class class method"));
+
+ }
+ }
+
+ public I18N(QWidget parent) {
+ super(parent, new Qt.WindowFlags(Qt.WindowType.WindowStaysOnTopHint));
+
+ tr("pack class method");
+
+ tr("QT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right" +
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew" +
+ " and Arabic) to get proper widget layout.");
+
+ tr("%n files", "plural form", n);
+ tr("%n cars", null, n);
+ tr("Age: %1");
+ tr("There are %n house(s)", "Plurals and function call", getCount());
+
+ QTranslator trans;
+ trans.translate("QTranslator", "Simple");
+ trans.translate("QTranslator", "Simple", null);
+ trans.translate("QTranslator", "Simple with comment", "with comment");
+ trans.translate("QTranslator", "Plural without comment", null, 1);
+ trans.translate("QTranslator", "Plural with comment", "comment 1", n);
+ trans.translate("QTranslator", "Plural with comment", "comment 2", getCount());
+
+ /*: with extra comment! */
+ QCoreApplication.translate("Plurals, QCoreApplication", "%n house(s)", "Plurals and identifier", n);
+
+ // FIXME: This will fail.
+ //QApplication.tr("QT_LAYOUT_DIRECTION", "scoped to qapp");
+
+ }
+
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejava/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejava/project.pro
new file mode 100644
index 000000000..657b535e2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejava/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.java
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejava/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejava/project.ts.result
new file mode 100644
index 000000000..0ce600c1b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejava/project.ts.result
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Plurals, QCoreApplication</name>
+ <message numerus="yes">
+ <location filename="main.java" line="88"/>
+ <source>%n house(s)</source>
+ <comment>Plurals and identifier</comment>
+ <extracomment>with extra comment!</extracomment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>QTranslator</name>
+ <message>
+ <location filename="main.java" line="80"/>
+ <location filename="main.java" line="81"/>
+ <source>Simple</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.java" line="82"/>
+ <source>Simple with comment</source>
+ <comment>with comment</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="83"/>
+ <source>Plural without comment</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="84"/>
+ <source>Plural with comment</source>
+ <comment>comment 1</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="85"/>
+ <source>Plural with comment</source>
+ <comment>comment 2</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>com.trolltech.examples.I18N</name>
+ <message>
+ <location filename="main.java" line="67"/>
+ <source>pack class method</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.java" line="72"/>
+ <source>QT_LAYOUT_DIRECTION</source>
+ <comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="74"/>
+ <source>%n files</source>
+ <comment>plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="75"/>
+ <source>%n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.java" line="76"/>
+ <source>Age: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="77"/>
+ <source>There are %n house(s)</source>
+ <comment>Plurals and function call</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>com.trolltech.examples.I18N$MainWindow</name>
+ <message>
+ <location filename="main.java" line="50"/>
+ <source>pack class class</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.java" line="53"/>
+ <source>pack class class extra</source>
+ <extracomment>extra comment for t-tor</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.java" line="59"/>
+ <source>pack class class method</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs/main.js b/tests/auto/linguist/lupdate/testdata/good/parsejs/main.js
new file mode 100644
index 000000000..9f61cea8f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejs/main.js
@@ -0,0 +1,91 @@
+qsTr("One");
+qsTranslate("FooContext", "Two");
+
+var greeting_strings = [
+ QT_TR_NOOP("Hello"),
+ QT_TRANSLATE_NOOP("FooContext", "Goodbye")
+];
+
+qsTr("One", "not the same one");
+
+//: My first comment.
+qsTr("See comment");
+
+//: My second comment.
+qsTranslate("BarContext", "See other comment");
+
+//: My third comment
+//: spans two lines.
+qsTr("The comment explains it all");
+
+//: My fourth comment
+//: spans a whopping
+//: three lines.
+qsTranslate("BazContext", "It should be clear by now");
+
+/*: C-style comment. */
+qsTr("I love C++");
+
+/*: Another C-style comment. */
+qsTranslate("FooContext", "I really love C++");
+
+/*: C-style comment, followed by */
+/*: another one. */
+qsTr("Qt is the best");
+
+/*: Another C-style comment, followed by */
+/*: yet another one. */
+qsTranslate("BarContext", "Qt is the very best");
+
+// This comment doesn't have any effect.
+qsTr("The comment had no effect");
+
+// This comment doesn't have any effect either.
+qsTranslate("BazContext", "The comment had no effect, really");
+
+/* This C-style comment doesn't have any effect. */
+qsTr("No comment to your comment");
+
+/* This C-style comment doesn't have any effect either. */
+qsTranslate("FooContext", "I refuse to comment on that");
+
+//= id_foo
+qsTr("This string has an identifier");
+
+//= id_bar
+qsTranslate("BarContext", "This string also has an identifier");
+
+//~ loc-blank False
+qsTr("This string has meta-data");
+
+//~ loc-layout_id foo_dialog
+qsTranslate("BazContext", "This string also has meta-data");
+
+// This comment is to be ignored.
+//: This is a comment for the translator.
+//= id_baz
+//~ foo 123
+//~ magic-stuff This means something special.
+qsTr("This string has a lot of information");
+
+// This comment is also to be ignored.
+//: This is another comment for the translator.
+//= id_babar
+//~ foo-bar Important stuff
+//~ needle-in-haystack Found
+//~ overflow True
+qsTranslate("FooContext", "This string has even more information");
+
+qsTr("This string has disambiguation", "Disambiguation");
+
+qsTranslate("BarContext", "This string also has disambiguation", "Another disambiguation");
+
+qsTr("This string contains plurals", "", 10);
+
+qsTrId("qtn_foo_bar");
+
+var more_greeting_strings = [ QT_TRID_NOOP("qtn_needle"), QT_TRID_NOOP("qtn_haystack") ];
+
+//: qsTrId() with comment, meta-data and plurals.
+//~ well-tested True
+qsTrId("qtn_bar_baz", 10);
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejs/project.pro
new file mode 100644
index 000000000..d549039c4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejs/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.js
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejs/project.ts.result
new file mode 100644
index 000000000..d03c7135e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejs/project.ts.result
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message id="qtn_foo_bar">
+ <location filename="main.js" line="85"/>
+ <source></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="qtn_needle">
+ <location filename="main.js" line="87"/>
+ <source></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="qtn_haystack">
+ <location filename="main.js" line="87"/>
+ <source></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="qtn_bar_baz" numerus="yes">
+ <location filename="main.js" line="91"/>
+ <source></source>
+ <extracomment>qsTrId() with comment, meta-data and plurals.</extracomment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ <extra-well-tested>True</extra-well-tested>
+ </message>
+</context>
+<context>
+ <name>BarContext</name>
+ <message>
+ <location filename="main.js" line="15"/>
+ <source>See other comment</source>
+ <extracomment>My second comment.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="38"/>
+ <source>Qt is the very best</source>
+ <extracomment>Another C-style comment, followed by yet another one.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="id_bar">
+ <location filename="main.js" line="56"/>
+ <source>This string also has an identifier</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="81"/>
+ <source>This string also has disambiguation</source>
+ <comment>Another disambiguation</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>BazContext</name>
+ <message>
+ <location filename="main.js" line="24"/>
+ <source>It should be clear by now</source>
+ <extracomment>My fourth comment spans a whopping three lines.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="44"/>
+ <source>The comment had no effect, really</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="62"/>
+ <source>This string also has meta-data</source>
+ <translation type="unfinished"></translation>
+ <extra-loc-layout_id>foo_dialog</extra-loc-layout_id>
+ </message>
+</context>
+<context>
+ <name>FooContext</name>
+ <message>
+ <location filename="main.js" line="2"/>
+ <source>Two</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="6"/>
+ <source>Goodbye</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="30"/>
+ <source>I really love C++</source>
+ <extracomment>Another C-style comment.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="50"/>
+ <source>I refuse to comment on that</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="id_babar">
+ <location filename="main.js" line="77"/>
+ <source>This string has even more information</source>
+ <extracomment>This is another comment for the translator.</extracomment>
+ <translation type="unfinished"></translation>
+ <extra-needle-in-haystack>Found</extra-needle-in-haystack>
+ <extra-overflow>True</extra-overflow>
+ <extra-foo-bar>Important stuff</extra-foo-bar>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
+ <location filename="main.js" line="1"/>
+ <source>One</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="5"/>
+ <source>Hello</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="9"/>
+ <source>One</source>
+ <comment>not the same one</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="12"/>
+ <source>See comment</source>
+ <extracomment>My first comment.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="19"/>
+ <source>The comment explains it all</source>
+ <extracomment>My third comment spans two lines.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="27"/>
+ <source>I love C++</source>
+ <extracomment>C-style comment.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="34"/>
+ <source>Qt is the best</source>
+ <extracomment>C-style comment, followed by another one.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="41"/>
+ <source>The comment had no effect</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="47"/>
+ <source>No comment to your comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="id_foo">
+ <location filename="main.js" line="53"/>
+ <source>This string has an identifier</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="59"/>
+ <source>This string has meta-data</source>
+ <translation type="unfinished"></translation>
+ <extra-loc-blank>False</extra-loc-blank>
+ </message>
+ <message id="id_baz">
+ <location filename="main.js" line="69"/>
+ <source>This string has a lot of information</source>
+ <extracomment>This is a comment for the translator.</extracomment>
+ <translation type="unfinished"></translation>
+ <extra-foo>123</extra-foo>
+ <extra-magic-stuff>This means something special.</extra-magic-stuff>
+ </message>
+ <message>
+ <location filename="main.js" line="79"/>
+ <source>This string has disambiguation</source>
+ <comment>Disambiguation</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.js" line="83"/>
+ <source>This string contains plurals</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs2/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/parsejs2/expectedoutput.txt
new file mode 100644
index 000000000..d6c977fa7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejs2/expectedoutput.txt
@@ -0,0 +1,29 @@
+.*/lupdate/testdata/good/parsejs2/main.js:3: qsTranslate\(\) requires at least two arguments.
+.*/lupdate/testdata/good/parsejs2/main.js:4: qsTranslate\(\) requires at least two arguments.
+.*/lupdate/testdata/good/parsejs2/main.js:5: qsTranslate\(\): both arguments must be literal strings.
+.*/lupdate/testdata/good/parsejs2/main.js:6: qsTranslate\(\): both arguments must be literal strings.
+.*/lupdate/testdata/good/parsejs2/main.js:7: qsTranslate\(\): both arguments must be literal strings.
+.*/lupdate/testdata/good/parsejs2/main.js:9: QT_TRANSLATE_NOOP\(\) requires at least two arguments.
+.*/lupdate/testdata/good/parsejs2/main.js:10: QT_TRANSLATE_NOOP\(\) requires at least two arguments.
+.*/lupdate/testdata/good/parsejs2/main.js:11: QT_TRANSLATE_NOOP\(\): both arguments must be literal strings.
+.*/lupdate/testdata/good/parsejs2/main.js:12: QT_TRANSLATE_NOOP\(\): both arguments must be literal strings.
+.*/lupdate/testdata/good/parsejs2/main.js:13: QT_TRANSLATE_NOOP\(\): both arguments must be literal strings.
+.*/lupdate/testdata/good/parsejs2/main.js:15: qsTr\(\) requires at least one argument.
+.*/lupdate/testdata/good/parsejs2/main.js:16: qsTr\(\): text to translate must be a literal string.
+.*/lupdate/testdata/good/parsejs2/main.js:18: QT_TR_NOOP\(\) requires at least one argument.
+.*/lupdate/testdata/good/parsejs2/main.js:19: QT_TR_NOOP\(\): text to translate must be a literal string.
+.*/lupdate/testdata/good/parsejs2/main.js:21: qsTrId\(\) requires at least one argument.
+.*/lupdate/testdata/good/parsejs2/main.js:22: qsTrId\(\): identifier must be a literal string.
+.*/lupdate/testdata/good/parsejs2/main.js:24: QT_TRID_NOOP\(\) requires at least one argument.
+.*/lupdate/testdata/good/parsejs2/main.js:25: QT_TRID_NOOP\(\): identifier must be a literal string.
+.*/lupdate/testdata/good/parsejs2/main.js:27: Unexpected character in meta string
+.*/lupdate/testdata/good/parsejs2/main.js:28: Unexpected character in meta string
+.*/lupdate/testdata/good/parsejs2/main.js:29: Unterminated meta string
+.*/lupdate/testdata/good/parsejs2/main.js:30: Unterminated meta string
+.*/lupdate/testdata/good/parsejs2/main.js:33: //% cannot be used with qsTranslate\(\). Ignoring
+.*/lupdate/testdata/good/parsejs2/main.js:35: //% cannot be used with QT_TRANSLATE_NOOP\(\). Ignoring
+.*/lupdate/testdata/good/parsejs2/main.js:37: //% cannot be used with qsTr\(\). Ignoring
+.*/lupdate/testdata/good/parsejs2/main.js:39: //% cannot be used with QT_TR_NOOP\(\). Ignoring
+.*/lupdate/testdata/good/parsejs2/main.js:42: Discarding unconsumed meta data
+.*/lupdate/testdata/good/parsejs2/main.js:44: Discarding unconsumed meta data
+.*/lupdate/testdata/good/parsejs2/main.js:46: Discarding unconsumed meta data
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs2/main.js b/tests/auto/linguist/lupdate/testdata/good/parsejs2/main.js
new file mode 100644
index 000000000..ea0295772
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejs2/main.js
@@ -0,0 +1,56 @@
+// This script exercises lupdate errors and warnings.
+
+qsTranslate();
+qsTranslate(10);
+qsTranslate(10, 20);
+qsTranslate("10", 20);
+qsTranslate(10, "20");
+
+QT_TRANSLATE_NOOP();
+QT_TRANSLATE_NOOP(10);
+QT_TRANSLATE_NOOP(10, 20);
+QT_TRANSLATE_NOOP("10", 20);
+QT_TRANSLATE_NOOP(10, "20");
+
+qsTr();
+qsTr(10);
+
+QT_TR_NOOP();
+QT_TR_NOOP(10);
+
+qsTrId();
+qsTrId(10);
+
+QT_TRID_NOOP();
+QT_TRID_NOOP(10);
+
+//% This is wrong
+//% "This is not wrong" This is wrong
+//% "I forgot to close the meta string
+//% "Being evil \
+
+//% "Should cause a warning"
+qsTranslate("FooContext", "Hello");
+//% "Should cause a warning"
+QT_TRANSLATE_NOOP("FooContext", "World");
+//% "Should cause a warning"
+qsTr("Hello");
+//% "Should cause a warning"
+QT_TR_NOOP("World");
+
+//: This comment will be discarded.
+Math.sin(1);
+//= id_foobar
+Math.cos(2);
+//~ underflow False
+Math.tan(3);
+
+/*
+Not tested for now, because these should perhaps not cause
+translation entries to be generated at all; see QTBUG-11843.
+
+//= qtn_foo
+qsTrId("qtn_foo");
+//= qtn_bar
+QT_TRID_NOOP("qtn_bar");
+*/
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.pro
new file mode 100644
index 000000000..d549039c4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.js
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.ts.result
new file mode 100644
index 000000000..bfa1b3d61
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.ts.result
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FooContext</name>
+ <message>
+ <location filename="main.js" line="33"/>
+ <source>Hello</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="35"/>
+ <source>World</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
+ <location filename="main.js" line="37"/>
+ <source>Hello</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="39"/>
+ <source>World</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js
new file mode 100644
index 000000000..aa510c1ae
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js
@@ -0,0 +1,29 @@
+// No context specified, default should be used.
+qsTr("One");
+QT_TR_NOOP("Two");
+
+// TRANSLATOR Foo
+qsTr("Three");
+QT_TR_NOOP("Four");
+
+// TRANSLATOR Bar
+qsTr("Five");
+
+/*
+ TRANSLATOR Baz
+ This is a comment to the translator.
+*/
+QT_TR_NOOP("Six");
+
+// TRANSLATOR Foo.Bar
+qsTr("Seven");
+
+/* TRANSLATOR Bar::Baz */
+QT_TR_NOOP("Eight");
+
+// qsTranslate() context is not affected.
+qsTranslate("Foo", "Nine");
+
+// Empty context.
+// TRANSLATOR
+qsTr("Ten");
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro
new file mode 100644
index 000000000..d549039c4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.js
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result
new file mode 100644
index 000000000..18407b2f8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message>
+ <location filename="main.js" line="29"/>
+ <source>Ten</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Bar</name>
+ <message>
+ <location filename="main.js" line="10"/>
+ <source>Five</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Bar::Baz</name>
+ <message>
+ <location filename="main.js" line="22"/>
+ <source>Eight</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Baz</name>
+ <message>
+ <location filename="main.js" line="12"/>
+ <source></source>
+ <comment>This is a comment to the translator.</comment>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="16"/>
+ <source>Six</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="main.js" line="6"/>
+ <source>Three</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="7"/>
+ <source>Four</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="25"/>
+ <source>Nine</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Foo.Bar</name>
+ <message>
+ <location filename="main.js" line="19"/>
+ <source>Seven</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
+ <location filename="main.js" line="2"/>
+ <source>One</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.js" line="3"/>
+ <source>Two</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqml/main.qml b/tests/auto/linguist/lupdate/testdata/good/parseqml/main.qml
new file mode 100644
index 000000000..c966fa112
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqml/main.qml
@@ -0,0 +1,100 @@
+import QtQuick 1.0
+
+QtObject {
+ function translate() {
+ qsTr("One");
+ qsTranslate("FooContext", "Two");
+
+ var greeting_strings = [
+ QT_TR_NOOP("Hello"),
+ QT_TRANSLATE_NOOP("FooContext", "Goodbye")
+ ];
+
+ qsTr("One", "not the same one");
+
+ //: My first comment.
+ qsTr("See comment");
+
+ //: My second comment.
+ qsTranslate("BarContext", "See other comment");
+
+ //: My third comment
+ //: spans two lines.
+ qsTr("The comment explains it all");
+
+ //: My fourth comment
+ //: spans a whopping
+ //: three lines.
+ qsTranslate("BazContext", "It should be clear by now");
+
+ /*: C-style comment. */
+ qsTr("I love C++");
+
+ /*: Another C-style comment. */
+ qsTranslate("FooContext", "I really love C++");
+
+ /*: C-style comment, followed by */
+ /*: another one. */
+ qsTr("Qt is the best");
+
+ /*: Another C-style comment, followed by */
+ /*: yet another one. */
+ qsTranslate("BarContext", "Qt is the very best");
+
+ // This comment doesn't have any effect.
+ qsTr("The comment had no effect");
+
+ // This comment doesn't have any effect either.
+ qsTranslate("BazContext", "The comment had no effect, really");
+
+ /* This C-style comment doesn't have any effect. */
+ qsTr("No comment to your comment");
+
+ /* This C-style comment doesn't have any effect either. */
+ qsTranslate("FooContext", "I refuse to comment on that");
+
+ //= id_foo
+ qsTr("This string has an identifier");
+
+ //= id_bar
+ qsTranslate("BarContext", "This string also has an identifier");
+
+ //~ loc-blank False
+ qsTr("This string has meta-data");
+
+ //~ loc-layout_id foo_dialog
+ qsTranslate("BazContext", "This string also has meta-data");
+
+ // This comment is to be ignored.
+ //: This is a comment for the translator.
+ //= id_baz
+ //~ foo 123
+ //~ magic-stuff This means something special.
+ qsTr("This string has a lot of information");
+
+ // This comment is also to be ignored.
+ //: This is another comment for the translator.
+ //= id_babar
+ //~ foo-bar Important stuff
+ //~ needle-in-haystack Found
+ //~ overflow True
+ qsTranslate("FooContext", "This string has even more information");
+
+ qsTr("This string has disambiguation", "Disambiguation");
+
+ qsTranslate("BarContext", "This string also has disambiguation", "Another disambiguation");
+
+ qsTr("This string contains plurals", "", 10);
+
+ qsTrId("qtn_foo_bar");
+
+ var more_greeting_strings = [ QT_TRID_NOOP("qtn_needle"), QT_TRID_NOOP("qtn_haystack") ];
+
+ //: qsTrId() with comment, meta-data and plurals.
+ //~ well-tested True
+ qsTrId("qtn_bar_baz", 10);
+
+ //% "Source text"
+ qsTrId("qtn_baz_biz");
+ }
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqml/project.pro b/tests/auto/linguist/lupdate/testdata/good/parseqml/project.pro
new file mode 100644
index 000000000..1040e2227
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqml/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.qml
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqml/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parseqml/project.ts.result
new file mode 100644
index 000000000..484390298
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseqml/project.ts.result
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message id="qtn_foo_bar">
+ <location filename="main.qml" line="89"/>
+ <source></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="qtn_needle">
+ <location filename="main.qml" line="91"/>
+ <source></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="qtn_haystack">
+ <location filename="main.qml" line="91"/>
+ <source></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="qtn_bar_baz" numerus="yes">
+ <location filename="main.qml" line="95"/>
+ <source></source>
+ <extracomment>qsTrId() with comment, meta-data and plurals.</extracomment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ <extra-well-tested>True</extra-well-tested>
+ </message>
+ <message id="qtn_baz_biz">
+ <location filename="main.qml" line="98"/>
+ <source>Source text</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>BarContext</name>
+ <message>
+ <location filename="main.qml" line="19"/>
+ <source>See other comment</source>
+ <extracomment>My second comment.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="42"/>
+ <source>Qt is the very best</source>
+ <extracomment>Another C-style comment, followed by yet another one.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="id_bar">
+ <location filename="main.qml" line="60"/>
+ <source>This string also has an identifier</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="85"/>
+ <source>This string also has disambiguation</source>
+ <comment>Another disambiguation</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>BazContext</name>
+ <message>
+ <location filename="main.qml" line="28"/>
+ <source>It should be clear by now</source>
+ <extracomment>My fourth comment spans a whopping three lines.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="48"/>
+ <source>The comment had no effect, really</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="66"/>
+ <source>This string also has meta-data</source>
+ <translation type="unfinished"></translation>
+ <extra-loc-layout_id>foo_dialog</extra-loc-layout_id>
+ </message>
+</context>
+<context>
+ <name>FooContext</name>
+ <message>
+ <location filename="main.qml" line="6"/>
+ <source>Two</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="10"/>
+ <source>Goodbye</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="34"/>
+ <source>I really love C++</source>
+ <extracomment>Another C-style comment.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="54"/>
+ <source>I refuse to comment on that</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="id_babar">
+ <location filename="main.qml" line="81"/>
+ <source>This string has even more information</source>
+ <extracomment>This is another comment for the translator.</extracomment>
+ <translation type="unfinished"></translation>
+ <extra-needle-in-haystack>Found</extra-needle-in-haystack>
+ <extra-overflow>True</extra-overflow>
+ <extra-foo-bar>Important stuff</extra-foo-bar>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
+ <location filename="main.qml" line="5"/>
+ <source>One</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="9"/>
+ <source>Hello</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="13"/>
+ <source>One</source>
+ <comment>not the same one</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="16"/>
+ <source>See comment</source>
+ <extracomment>My first comment.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="23"/>
+ <source>The comment explains it all</source>
+ <extracomment>My third comment spans two lines.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="31"/>
+ <source>I love C++</source>
+ <extracomment>C-style comment.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="38"/>
+ <source>Qt is the best</source>
+ <extracomment>C-style comment, followed by another one.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="45"/>
+ <source>The comment had no effect</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="51"/>
+ <source>No comment to your comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="id_foo">
+ <location filename="main.qml" line="57"/>
+ <source>This string has an identifier</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.qml" line="63"/>
+ <source>This string has meta-data</source>
+ <translation type="unfinished"></translation>
+ <extra-loc-blank>False</extra-loc-blank>
+ </message>
+ <message id="id_baz">
+ <location filename="main.qml" line="73"/>
+ <source>This string has a lot of information</source>
+ <extracomment>This is a comment for the translator.</extracomment>
+ <translation type="unfinished"></translation>
+ <extra-foo>123</extra-foo>
+ <extra-magic-stuff>This means something special.</extra-magic-stuff>
+ </message>
+ <message>
+ <location filename="main.qml" line="83"/>
+ <source>This string has disambiguation</source>
+ <comment>Disambiguation</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.qml" line="87"/>
+ <source>This string contains plurals</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseui/project.pro b/tests/auto/linguist/lupdate/testdata/good/parseui/project.pro
new file mode 100644
index 000000000..fa56972dd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseui/project.pro
@@ -0,0 +1,3 @@
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseui/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parseui/project.ts.result
new file mode 100644
index 000000000..b27d23991
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseui/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="55"/>
+ <source>Qt Assistant - Finn text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message utf8="true">
+ <location filename="project.ui" line="58"/>
+ <source>Finn tekst - Der Bjørn möchte auch mal.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseui/project.ui b/tests/auto/linguist/lupdate/testdata/good/parseui/project.ui
new file mode 100644
index 000000000..55c1c3a0a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseui/project.ui
@@ -0,0 +1,72 @@
+<ui version="4.0" >
+ <author></author>
+<comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant - Finn text</string>
+ </property>
+ <property name="height" >
+ <string>Finn tekst - Der Bjørn möchte auch mal.</string>
+ </property>
+ </widget>
+ <tabstops>
+ <tabstop>comboFind</tabstop>
+ <tabstop>checkWords</tabstop>
+ <tabstop>checkCase</tabstop>
+ <tabstop>radioForward</tabstop>
+ <tabstop>radioBackward</tabstop>
+ <tabstop>findButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp b/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp
new file mode 100644
index 000000000..91d0c81dd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+QString foo()
+{
+ QCoreApplication::translate("Foo","XXX","YYY");
+}
+
+Foo::Foo()
+{
+ tr("CTOR");
+}
+
+void Foo::bar()
+{
+ tr("BAR");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/prefix/project.pro b/tests/auto/linguist/lupdate/testdata/good/prefix/project.pro
new file mode 100644
index 000000000..759bea068
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/prefix/project.pro
@@ -0,0 +1,3 @@
+SOURCES = main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result
new file mode 100644
index 000000000..e3569218e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="main.cpp" line="45"/>
+ <source>XXX</source>
+ <comment>YYY</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="50"/>
+ <source>CTOR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="55"/>
+ <source>BAR</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/preprocess/main.cpp b/tests/auto/linguist/lupdate/testdata/good/preprocess/main.cpp
new file mode 100644
index 000000000..4f388bd97
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/preprocess/main.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
+
+
+void func2() {
+#ifdef Q_OS_WIN
+ QApplication::tr("Kind", "Windows only, see Type");
+#else
+ QApplication::tr("Type", "Not used on windows, see Kind");
+#endif
+
+}
+
+
+
+void stringconcatenation()
+{
+ QApplication::tr("One string,"
+ " three"
+ " lines");
+
+ QApplication::tr("a backslash followed by newline \
+should be ignored \
+and the next line should be syntactically considered to be \
+on the same line");
+
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/preprocess/project.pro b/tests/auto/linguist/lupdate/testdata/good/preprocess/project.pro
new file mode 100644
index 000000000..c96859bdb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/preprocess/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/preprocess/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/preprocess/project.ts.result
new file mode 100644
index 000000000..4d695e84c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/preprocess/project.ts.result
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="55"/>
+ <source>Kind</source>
+ <comment>Windows only, see Type</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="57"/>
+ <source>Type</source>
+ <comment>Not used on windows, see Kind</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="66"/>
+ <source>One string, three lines</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="70"/>
+ <source>a backslash followed by newline should be ignored and the next line should be syntactically considered to be on the same line</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/main.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/main.cpp
new file mode 100644
index 000000000..e99f1e241
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/main.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/main_mac.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_mac.cpp
new file mode 100644
index 000000000..a9321fdd0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_mac.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello macworld", "mac-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/main_unix.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_unix.cpp
new file mode 100644
index 000000000..e7b465807
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_unix.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello unixworld", "unix-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/main_win.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_win.cpp
new file mode 100644
index 000000000..052137194
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_win.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello windowsworld", "Windows-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsing/project.pro
new file mode 100644
index 000000000..0e920f99d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/project.pro
@@ -0,0 +1,31 @@
+# Try to reference a variable that does not exist:
+MYVAR=$$THIS_VARIABLE_IS_NOT_DEFINED
+
+SOURCES += main.cpp
+
+win32 {
+ SOURCES += main_win.cpp
+}
+
+unix {
+ SOURCES += main_unix.cpp
+}
+
+mac {
+ SOURCES += main_mac.cpp
+}
+
+SOURCES += wildcard/main*.cpp \
+# yadiyada it should also parse the next line
+ wildcard*.cpp
+
+
+DEPENDPATH = vpaths/dependpath
+
+# The purpose of this test is to test expansion of environment variables,
+# and to test if the DEPENDPATH variable is considered correctly.
+if (exists($$member($$(PATH), 0))) {
+ SOURCES += main_dependpath.cpp
+}
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsing/project.ts.result
new file mode 100644
index 000000000..556ca073d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/project.ts.result
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main_mac.cpp" line="47"/>
+ <source>Hello macworld</source>
+ <comment>mac-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main_unix.cpp" line="47"/>
+ <source>Hello unixworld</source>
+ <comment>unix-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main_win.cpp" line="47"/>
+ <source>Hello windowsworld</source>
+ <comment>Windows-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="wildcard/main1.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>wildcard/main1.cpp</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="wildcard/mainfile.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>wildcard/main2.cpp</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="wildcard1.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>wildcard1.cpp</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="wildcard99.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>wildcard99.cpp</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QCoreApplication</name>
+ <message>
+ <location filename="vpaths/dependpath/main_dependpath.cpp" line="48"/>
+ <source>Hello from a DEPENDPATH</source>
+ <comment>See if the DEPENDPATH thing works</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/vpaths/dependpath/main_dependpath.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/vpaths/dependpath/main_dependpath.cpp
new file mode 100644
index 000000000..577b6d9df
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/vpaths/dependpath/main_dependpath.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+int main(int argc, char **argv)
+{
+ QCoreApplication::tr("Hello from a DEPENDPATH", "See if the DEPENDPATH thing works");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/main1.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/main1.cpp
new file mode 100644
index 000000000..5673da5b6
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/main1.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "wildcard/main1.cpp");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/mainfile.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/mainfile.cpp
new file mode 100644
index 000000000..4327db448
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/mainfile.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "wildcard/main2.cpp");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard1.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard1.cpp
new file mode 100644
index 000000000..1545f823a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard1.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "wildcard1.cpp");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard99.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard99.cpp
new file mode 100644
index 000000000..3c8b1ed7e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard99.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "wildcard99.cpp");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/a b/tests/auto/linguist/lupdate/testdata/good/proparsing2/a
new file mode 100644
index 000000000..64f00c9e4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/a
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("a");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/a.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing2/a.cpp
new file mode 100644
index 000000000..a43623e0a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/a.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("a.cpp");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/b b/tests/auto/linguist/lupdate/testdata/good/proparsing2/b
new file mode 100644
index 000000000..e53e4a6a8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/b
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("b");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/b.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing2/b.cpp
new file mode 100644
index 000000000..8927f2a80
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/b.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("b.cpp");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/e b/tests/auto/linguist/lupdate/testdata/good/proparsing2/e
new file mode 100644
index 000000000..453d10075
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/e
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("e");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/f/g.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing2/f/g.cpp
new file mode 100644
index 000000000..eff872475
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/f/g.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("f/g.cpp");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/files-cc.txt b/tests/auto/linguist/lupdate/testdata/good/proparsing2/files-cc.txt
new file mode 100644
index 000000000..5bd8d03dd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/files-cc.txt
@@ -0,0 +1 @@
+a.cpp b.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.pro
new file mode 100644
index 000000000..3dc420858
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.pro
@@ -0,0 +1,33 @@
+# This is to test if quoted elements with spaces are treated as elements (and not splitted up due
+# to the spaces.)
+# It also tries to verify the behaviour of combining quoted and non-quoted elements with literals.
+#
+
+QUOTED = $$quote(variable with spaces)
+VERSIONAB = "a.b"
+VAB = $$split(VERSIONAB, ".")
+V += $$VAB
+V += $$QUOTED
+
+# this is just to make p4 happy with no spaces in filename
+SOURCES += $$member(V,0,1)
+V2 = $$member(V,2)
+V2S = $$split(V2, " ")
+SOURCES += $$join(V2S,"_")
+message($$SOURCES)
+# SOURCES += [a, b, variable_with_spaces]
+
+LIST = d e f
+L2 = x/$$LIST/g.cpp
+SOURCES += $$L2
+# SOURCES += [x/d, e, f/g.cpp]
+
+QUOTEDEXTRA = x/$$QUOTED/z
+Q3 = $$split(QUOTEDEXTRA, " ")
+SOURCES += $$Q3
+# SOURCES += [x/variable, with, spaces/z]
+
+win32: SOURCES += $$system(type files-cc.txt)
+unix: SOURCES += $$system(cat files-cc.txt)
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.ts.result
new file mode 100644
index 000000000..3714d9bd8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.ts.result
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QLineEdit</name>
+ <message>
+ <location filename="a" line="44"/>
+ <source>a</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="a.cpp" line="44"/>
+ <source>a.cpp</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="b" line="44"/>
+ <source>b</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="b.cpp" line="44"/>
+ <source>b.cpp</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="e" line="44"/>
+ <source>e</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="f/g.cpp" line="44"/>
+ <source>f/g.cpp</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="spaces/z" line="44"/>
+ <source>spaces/z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="variable_with_spaces" line="44"/>
+ <source>variable with spaces</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="with" line="44"/>
+ <source>with</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="x/d" line="44"/>
+ <source>x/d</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="x/variable" line="44"/>
+ <source>x/variable</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/spaces/z b/tests/auto/linguist/lupdate/testdata/good/proparsing2/spaces/z
new file mode 100644
index 000000000..94255b1d4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/spaces/z
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("spaces/z");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/variable_with_spaces b/tests/auto/linguist/lupdate/testdata/good/proparsing2/variable_with_spaces
new file mode 100644
index 000000000..99259ab1d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/variable_with_spaces
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("variable with spaces");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/with b/tests/auto/linguist/lupdate/testdata/good/proparsing2/with
new file mode 100644
index 000000000..2b23f4a7c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/with
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("with");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/d b/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/d
new file mode 100644
index 000000000..672901c07
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/d
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("x/d");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/variable b/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/variable
new file mode 100644
index 000000000..f7c7ed052
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/variable
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QString func()
+{
+ return QLineEdit::tr("x/variable");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/file1.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/file1.cpp
new file mode 100644
index 000000000..3a95835ce
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/file1.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "top-level wildcard");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/filter.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/filter.cpp
new file mode 100644
index 000000000..f9ee8f449
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/filter.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "top-level direct");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.pro
new file mode 100644
index 000000000..6bfe751f4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.pro
@@ -0,0 +1,5 @@
+SOURCES += file*.cpp filter.cpp non-existing.cpp
+
+include(sub/sub.pri)
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.ts.result
new file mode 100644
index 000000000..edc2fcb81
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.ts.result
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="file1.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>top-level wildcard</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="filter.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>top-level direct</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/subfile1.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>nested wildcard</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/subfilter.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>nested direct</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/sub.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/sub.pri
new file mode 100644
index 000000000..a6079f93e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/sub.pri
@@ -0,0 +1,3 @@
+VPATH += $$PWD
+
+SOURCES += sub/subfile?.cpp subfilter.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfile1.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfile1.cpp
new file mode 100644
index 000000000..a4d4b7d15
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfile1.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "nested wildcard");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfilter.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfilter.cpp
new file mode 100644
index 000000000..686175f29
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfilter.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "nested direct");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/common.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/common.pri
new file mode 100644
index 000000000..ba3169dd9
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/common.pri
@@ -0,0 +1 @@
+include(main.pri)
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.cpp
new file mode 100644
index 000000000..e99f1e241
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.pri
new file mode 100644
index 000000000..a8d4a2ba2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.pri
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += $$PWD/main.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/mac.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/mac.pri
new file mode 100644
index 000000000..549eab5e4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/mac.pri
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += $$PWD/main_mac.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/main_mac.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/main_mac.cpp
new file mode 100644
index 000000000..a9321fdd0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/main_mac.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello macworld", "mac-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro
new file mode 100644
index 000000000..5e23538b9
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro
@@ -0,0 +1,9 @@
+include(win/win.pri)
+include(mac/mac.pri)
+include(unix/unix.pri)
+include (common/common.pri) # Important: keep the space before the '('
+include(relativity/relativity.pri)
+
+message($$SOURCES)
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.ts.result
new file mode 100644
index 000000000..e01c53310
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.ts.result
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="common/main.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mac/main_mac.cpp" line="47"/>
+ <source>Hello macworld</source>
+ <comment>mac-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="relativity/relativity.cpp" line="47"/>
+ <source>relativity.pri</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="unix/main_unix.cpp" line="47"/>
+ <source>Hello unixworld</source>
+ <comment>unix-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="win/main_win.cpp" line="47"/>
+ <source>Hello windowsworld</source>
+ <comment>Windows-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.cpp
new file mode 100644
index 000000000..747105c49
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("relativity.pri", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.pri
new file mode 100644
index 000000000..42658f0c6
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.pri
@@ -0,0 +1,3 @@
+# Lets test how well the proparser can walk the tree of includes...
+
+include(sub/sub.pri)
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub/sub.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub/sub.pri
new file mode 100644
index 000000000..17055a7e7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub/sub.pri
@@ -0,0 +1 @@
+include(../sub2/sub2.pri)
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub2/sub2.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub2/sub2.pri
new file mode 100644
index 000000000..e2876b10f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub2/sub2.pri
@@ -0,0 +1,2 @@
+SOURCES += $$PWD/../relativity.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/main_unix.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/main_unix.cpp
new file mode 100644
index 000000000..e7b465807
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/main_unix.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello unixworld", "unix-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/unix.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/unix.pri
new file mode 100644
index 000000000..99777d7c9
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/unix.pri
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += $$PWD/main_unix.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/main_win.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/main_win.cpp
new file mode 100644
index 000000000..052137194
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/main_win.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello windowsworld", "Windows-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/win.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/win.pri
new file mode 100644
index 000000000..742417cb0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/win.pri
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += $$PWD/main_win.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.pro
new file mode 100644
index 000000000..88f243571
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = sub1
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.ts.result
new file mode 100644
index 000000000..a6972bd03
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="sub1/main.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/main.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/main.cpp
new file mode 100644
index 000000000..e99f1e241
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/main.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/sub1.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/sub1.pro
new file mode 100644
index 000000000..df18c5a69
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/sub1.pro
@@ -0,0 +1,3 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = ../project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/common.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/common.pro
new file mode 100644
index 000000000..3f6c64360
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/common.pro
@@ -0,0 +1,2 @@
+SOURCES += main.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/main.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/main.cpp
new file mode 100644
index 000000000..e99f1e241
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/main.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/lupdatecmd
new file mode 100644
index 000000000..b7e12cc45
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/lupdatecmd
@@ -0,0 +1 @@
+lupdate project.pro -ts project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/mac.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/mac.pro
new file mode 100644
index 000000000..a1863b665
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/mac.pro
@@ -0,0 +1 @@
+SOURCES += main_mac.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/main_mac.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/main_mac.cpp
new file mode 100644
index 000000000..a9321fdd0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/main_mac.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello macworld", "mac-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.pro
new file mode 100644
index 000000000..f75a46276
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = win mac unix common
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.ts.result
new file mode 100644
index 000000000..6621de99c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.ts.result
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="win/main_win.cpp" line="47"/>
+ <source>Hello windowsworld</source>
+ <comment>Windows-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mac/main_mac.cpp" line="47"/>
+ <source>Hello macworld</source>
+ <comment>mac-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="unix/main_unix.cpp" line="47"/>
+ <source>Hello unixworld</source>
+ <comment>unix-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="common/main.cpp" line="47"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/main_unix.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/main_unix.cpp
new file mode 100644
index 000000000..e7b465807
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/main_unix.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello unixworld", "unix-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/unix.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/unix.pro
new file mode 100644
index 000000000..71b1a2252
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/unix.pro
@@ -0,0 +1 @@
+SOURCES += main_unix.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/main_win.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/main_win.cpp
new file mode 100644
index 000000000..052137194
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/main_win.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello windowsworld", "Windows-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/win.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/win.pro
new file mode 100644
index 000000000..afd719711
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/win.pro
@@ -0,0 +1 @@
+SOURCES += main_win.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/recurse_full/expectedoutput.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full/expectedoutput.txt
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/recurse_full/lupdatecmd
new file mode 100644
index 000000000..40987e2db
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full/lupdatecmd
@@ -0,0 +1,2 @@
+TRANSLATION: project.ts project_sub.ts
+cd ../../subdirs_full
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_full/project.ts.result
new file mode 100644
index 000000000..7d9a6f484
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full/project.ts.result
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>subdir1</name>
+ <message>
+ <location filename="subdir1/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>subsub1</name>
+ <message>
+ <location filename="subdir2/subsub1/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full/project_sub.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_full/project_sub.ts.result
new file mode 100644
index 000000000..cddb9632f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full/project_sub.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>ISO-8859-2</defaultcodec>
+<context>
+ <name>subsub2</name>
+ <message>
+ <location filename="subdir2/subsub2/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/expectedoutput.txt
new file mode 100644
index 000000000..fd7a158d3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/expectedoutput.txt
@@ -0,0 +1,2 @@
+lupdate warning: TS files from command line will override TRANSLATIONS in project\.pro\.
+lupdate warning: TS files from command line prevent recursing into .*/subdir2/subsub2/subsub2\.pro\.
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/lupdatecmd
new file mode 100644
index 000000000..33296c3a2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/lupdatecmd
@@ -0,0 +1,3 @@
+TRANSLATION: project.ts project_sub.ts
+cd ../../subdirs_full
+lupdate project.pro -ts project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project.ts.result
new file mode 100644
index 000000000..7d9a6f484
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project.ts.result
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>subdir1</name>
+ <message>
+ <location filename="subdir1/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>subsub1</name>
+ <message>
+ <location filename="subdir2/subsub1/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project_sub.ts.before b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project_sub.ts.before
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project_sub.ts.before
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project_sub.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project_sub.ts.result
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts/project_sub.ts.result
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/expectedoutput.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/expectedoutput.txt
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/lupdatecmd
new file mode 100644
index 000000000..628acc0dc
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/lupdatecmd
@@ -0,0 +1,2 @@
+cd ../../subdirs_full
+lupdate subdir1/subdir1.pro subdir2/subsub1/subsub1.pro -ts project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/project.ts.result
new file mode 100644
index 000000000..7d9a6f484
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_full_ts_join/project.ts.result
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>subdir1</name>
+ <message>
+ <location filename="subdir1/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>subsub1</name>
+ <message>
+ <location filename="subdir2/subsub1/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/recurse_part/expectedoutput.txt
new file mode 100644
index 000000000..808db1838
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part/expectedoutput.txt
@@ -0,0 +1 @@
+lupdate warning: no TS files specified\. Only diagnostics will be produced for 'project\.pro'\.
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/recurse_part/lupdatecmd
new file mode 100644
index 000000000..3e15bc7f6
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part/lupdatecmd
@@ -0,0 +1,2 @@
+TRANSLATION: project.ts project_sub.ts
+cd ../../subdirs_part
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/recurse_part/project.ts.before
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part/project.ts.before
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_part/project.ts.result
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part/project.ts.result
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part/project_sub.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_part/project_sub.ts.result
new file mode 100644
index 000000000..cddb9632f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part/project_sub.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>ISO-8859-2</defaultcodec>
+<context>
+ <name>subsub2</name>
+ <message>
+ <location filename="subdir2/subsub2/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/expectedoutput.txt
new file mode 100644
index 000000000..b90439003
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/expectedoutput.txt
@@ -0,0 +1 @@
+lupdate warning: TS files from command line prevent recursing into .*/subdir2/subsub2/subsub2\.pro\.
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/lupdatecmd
new file mode 100644
index 000000000..41bfcecf3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/lupdatecmd
@@ -0,0 +1,3 @@
+TRANSLATION: project.ts project_sub.ts
+cd ../../subdirs_part
+lupdate project.pro -ts project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project.ts.result
new file mode 100644
index 000000000..7d9a6f484
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project.ts.result
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>subdir1</name>
+ <message>
+ <location filename="subdir1/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>subsub1</name>
+ <message>
+ <location filename="subdir2/subsub1/main.cpp" line="45"/>
+ <source>minimal test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project_sub.ts.before b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project_sub.ts.before
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project_sub.ts.before
diff --git a/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project_sub.ts.result b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project_sub.ts.result
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/recurse_part_ts/project_sub.ts.result
diff --git a/tests/auto/linguist/lupdate/testdata/good/reloutput/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/reloutput/lupdatecmd
new file mode 100644
index 000000000..90f609bd8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/reloutput/lupdatecmd
@@ -0,0 +1 @@
+TRANSLATION: translations/project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/reloutput/main.cpp b/tests/auto/linguist/lupdate/testdata/good/reloutput/main.cpp
new file mode 100644
index 000000000..d8320bfd2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/reloutput/main.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/reloutput/project.pro b/tests/auto/linguist/lupdate/testdata/good/reloutput/project.pro
new file mode 100644
index 000000000..4e2e6ada7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/reloutput/project.pro
@@ -0,0 +1,3 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = translations/project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/reloutput/translations/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/reloutput/translations/project.ts.result
new file mode 100644
index 000000000..e398701c9
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/reloutput/translations/project.ts.result
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="../main.cpp" line="47"/>
+ <source>Hello world</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/respfile/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/respfile/lupdatecmd
new file mode 100644
index 000000000..6f198ab83
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/respfile/lupdatecmd
@@ -0,0 +1,2 @@
+# Add the command that lupdate should run here. If it can't find anything it will default to
+lupdate -silent @sources.lst -ts @tsfiles.lst
diff --git a/tests/auto/linguist/lupdate/testdata/good/respfile/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/respfile/project.ts.result
new file mode 100644
index 000000000..3a864a214
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/respfile/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Dialog2</name>
+ <message>
+ <location filename="source1.cpp" line="47"/>
+ <source>func1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="source2.cpp" line="47"/>
+ <source>func2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/respfile/source1.cpp b/tests/auto/linguist/lupdate/testdata/good/respfile/source1.cpp
new file mode 100644
index 000000000..a91d3b4b8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/respfile/source1.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+void Dialog2::func3()
+{
+ tr("func1");
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/respfile/source2.cpp b/tests/auto/linguist/lupdate/testdata/good/respfile/source2.cpp
new file mode 100644
index 000000000..677cc4ca1
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/respfile/source2.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+void Dialog2::func3()
+{
+ tr("func2");
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/respfile/sources.lst b/tests/auto/linguist/lupdate/testdata/good/respfile/sources.lst
new file mode 100644
index 000000000..430937e49
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/respfile/sources.lst
@@ -0,0 +1,2 @@
+source1.cpp
+source2.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/good/respfile/tsfiles.lst b/tests/auto/linguist/lupdate/testdata/good/respfile/tsfiles.lst
new file mode 100644
index 000000000..f3eb71f1c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/respfile/tsfiles.lst
@@ -0,0 +1 @@
+project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.pro b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.pro
new file mode 100644
index 000000000..fa56972dd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.pro
@@ -0,0 +1,3 @@
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.before
new file mode 100644
index 000000000..f06c22ca8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.before
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="20"/>
+ <source>Test similarity</source>
+ <translation type="unfinished">Test likhet (test1)</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="23"/>
+ <source>Similarity should have kicked in here!</source>
+ <translation type="unfinished">Test likhet (test2)</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result
new file mode 100644
index 000000000..6bc565c1e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Test similarity</source>
+ <translation type="obsolete">Test likhet (test1)</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="20"/>
+ <source>This should not be considered to be more or less equal to the corresponding one in the TS file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="23"/>
+ <source>Here, similarity should kick in!</source>
+ <oldsource>Similarity should have kicked in here!</oldsource>
+ <translation type="unfinished">Test likhet (test2)</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui
new file mode 100644
index 000000000..a5f8e9f79
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui
@@ -0,0 +1,26 @@
+<ui version="4.0" >
+ <author></author>
+ <comment><!--
+*********************************************************************
+**
+** Do not change the location (linenumber) of the <string> elements in this file!
+** That will make the test break!
+**
+** If you need to add some tests, please add them to the end of the file!
+**
+**
+*********************************************************************
+-->
+</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="test1">
+ <!-- If the sourcetext is not similar to the vernacular sourcetext, mark the old one as obsolete and the new one as unfinished -->
+ <string>This should not be considered to be more or less equal to the corresponding one in the TS file.</string>
+ </property>
+ <property name="test2">
+ <string>Here, similarity should kick in!</string>
+ </property>
+ </widget>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/main.cpp b/tests/auto/linguist/lupdate/testdata/recursivescan/main.cpp
new file mode 100644
index 000000000..0a193bc9a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QDebug>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QTranslator translator;
+ translator.load("whitespace");
+ app.installTranslator(&translator);
+
+ QObject::tr("\nnewline at the start");
+ QObject::tr("newline at the end\n");
+ QObject::tr("newline and space at the end\n ");
+ QObject::tr("space and newline at the end \n");
+ QObject::tr("\tTab at the start and newline at the end\n");
+ QObject::tr("\n\tnewline and tab at the start");
+ QObject::tr(" \tspace and tab at the start");
+ QObject::tr(" space_first");
+ QObject::tr("space_last ");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/project.ui b/tests/auto/linguist/lupdate/testdata/recursivescan/project.ui
new file mode 100644
index 000000000..5135dfed0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/project.ui
@@ -0,0 +1,74 @@
+<ui version="4.0" >
+ <author></author>
+<comment>
+*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************
+</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant - Finn text</string>
+ </property>
+ <property name="height" >
+ <string>Finn tekst</string>
+ </property>
+ </widget>
+ <tabstops>
+ <tabstop>comboFind</tabstop>
+ <tabstop>checkWords</tabstop>
+ <tabstop>checkCase</tabstop>
+ <tabstop>radioForward</tabstop>
+ <tabstop>radioBackward</tabstop>
+ <tabstop>findButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.c++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.c++
new file mode 100644
index 000000000..8a5ce148f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.c++
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QApplication::translate("text/c++", "test");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cpp b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cpp
new file mode 100644
index 000000000..c774af13f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QApplication::translate("text/cpp", "test");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cxx b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cxx
new file mode 100644
index 000000000..a4d144f02
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cxx
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QApplication::translate("text/cxx", "test");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/sub/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/finddialog.cpp
new file mode 100644
index 000000000..b5a9ca8d2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/finddialog.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "finddialog.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpwindow.h"
+
+#include <QTextBrowser>
+#include <QTextCursor>
+#include <QStatusBar>
+#include <QLineEdit>
+#include <QDateTime>
+#include <QGridLayout>
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ sb->showMessage(tr("Enter the text you want to find."));
+}
+
+void FindDialog::doFind(bool forward)
+{
+ QTextCursor found = browser->document()->find(findExpr, c, flags);
+ if (found.isNull()) {
+ if (onceFound) {
+ if (forward)
+ statusMessage(tr("Search reached end of the document"));
+ else
+ statusMessage(tr("Search reached start of the document"));
+ } else {
+ statusMessage(tr( "Text not found" ));
+ }
+ }
+}
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_full/project.pro b/tests/auto/linguist/lupdate/testdata/subdirs_full/project.pro
new file mode 100644
index 000000000..1f744a722
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_full/project.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = subdir1 subdir2/subdir2.pro
+
+TRANSLATIONS = project.ts
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir1/main.cpp b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir1/main.cpp
new file mode 100644
index 000000000..97b646ffb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir1/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+QString foo()
+{
+ QCoreApplication::translate("subdir1","minimal test");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir1/subdir1.pro b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir1/subdir1.pro
new file mode 100644
index 000000000..28dcadcbf
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir1/subdir1.pro
@@ -0,0 +1 @@
+SOURCES += main.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subdir2.pro b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subdir2.pro
new file mode 100644
index 000000000..f8d03df4b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subdir2.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = subsub1 subsub2
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub1/main.cpp b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub1/main.cpp
new file mode 100644
index 000000000..cc78f8a5d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub1/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+QString foo()
+{
+ QCoreApplication::translate("subsub1","minimal test");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub1/subsub1.pro b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub1/subsub1.pro
new file mode 100644
index 000000000..28dcadcbf
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub1/subsub1.pro
@@ -0,0 +1 @@
+SOURCES += main.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub2/main.cpp b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub2/main.cpp
new file mode 100644
index 000000000..ff061beba
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub2/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+QString foo()
+{
+ QCoreApplication::translate("subsub2","minimal test");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub2/subsub2.pro b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub2/subsub2.pro
new file mode 100644
index 000000000..349922287
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_full/subdir2/subsub2/subsub2.pro
@@ -0,0 +1,4 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = ../../project_sub.ts
+CODECFORTR = ISO-8859-2
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_part/project.pro b/tests/auto/linguist/lupdate/testdata/subdirs_part/project.pro
new file mode 100644
index 000000000..d803c37bb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_part/project.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = subdir1 subdir2/subdir2.pro
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir1/main.cpp b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir1/main.cpp
new file mode 100644
index 000000000..97b646ffb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir1/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+QString foo()
+{
+ QCoreApplication::translate("subdir1","minimal test");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir1/subdir1.pro b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir1/subdir1.pro
new file mode 100644
index 000000000..28dcadcbf
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir1/subdir1.pro
@@ -0,0 +1 @@
+SOURCES += main.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subdir2.pro b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subdir2.pro
new file mode 100644
index 000000000..f8d03df4b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subdir2.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = subsub1 subsub2
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub1/main.cpp b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub1/main.cpp
new file mode 100644
index 000000000..cc78f8a5d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub1/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+QString foo()
+{
+ QCoreApplication::translate("subsub1","minimal test");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub1/subsub1.pro b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub1/subsub1.pro
new file mode 100644
index 000000000..28dcadcbf
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub1/subsub1.pro
@@ -0,0 +1 @@
+SOURCES += main.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub2/main.cpp b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub2/main.cpp
new file mode 100644
index 000000000..ff061beba
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub2/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+QString foo()
+{
+ QCoreApplication::translate("subsub2","minimal test");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub2/subsub2.pro b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub2/subsub2.pro
new file mode 100644
index 000000000..349922287
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/subdirs_part/subdir2/subsub2/subsub2.pro
@@ -0,0 +1,4 @@
+SOURCES += main.cpp
+
+TRANSLATIONS = ../../project_sub.ts
+CODECFORTR = ISO-8859-2
diff --git a/tests/auto/linguist/lupdate/tst_lupdate.cpp b/tests/auto/linguist/lupdate/tst_lupdate.cpp
new file mode 100644
index 000000000..19feeae3a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/tst_lupdate.cpp
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if CHECK_SIMTEXTH
+#include "../shared/simtexth.h"
+#endif
+
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QByteArray>
+
+#include <QtTest/QtTest>
+
+class tst_lupdate : public QObject
+{
+ Q_OBJECT
+public:
+ tst_lupdate();
+
+private slots:
+ void good_data();
+ void good();
+#if CHECK_SIMTEXTH
+ void simtexth();
+ void simtexth_data();
+#endif
+
+private:
+ QString m_cmdLupdate;
+ QString m_basePath;
+
+ void doCompare(const QStringList &actual, const QString &expectedFn, bool err);
+ void doCompare(const QString &actualFn, const QString &expectedFn, bool err);
+};
+
+
+tst_lupdate::tst_lupdate()
+{
+ QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath);
+ m_cmdLupdate = binPath + QLatin1String("/lupdate");
+ m_basePath = QDir::currentPath() + QLatin1String("/testdata/");
+}
+
+static bool prepareMatch(const QString &expect, QString *tmpl, int *require, int *accept)
+{
+ if (expect.startsWith(QLatin1Char('\\'))) {
+ *tmpl = expect.mid(1);
+ *require = *accept = 1;
+ } else if (expect.startsWith(QLatin1Char('?'))) {
+ *tmpl = expect.mid(1);
+ *require = 0;
+ *accept = 1;
+ } else if (expect.startsWith(QLatin1Char('*'))) {
+ *tmpl = expect.mid(1);
+ *require = 0;
+ *accept = INT_MAX;
+ } else if (expect.startsWith(QLatin1Char('+'))) {
+ *tmpl = expect.mid(1);
+ *require = 1;
+ *accept = INT_MAX;
+ } else if (expect.startsWith(QLatin1Char('{'))) {
+ int brc = expect.indexOf(QLatin1Char('}'), 1);
+ if (brc < 0)
+ return false;
+ *tmpl = expect.mid(brc + 1);
+ QString sub = expect.mid(1, brc - 1);
+ int com = sub.indexOf(QLatin1Char(','));
+ bool ok;
+ if (com < 0) {
+ *require = *accept = sub.toInt(&ok);
+ return ok;
+ } else {
+ *require = sub.left(com).toInt();
+ *accept = sub.mid(com + 1).toInt(&ok);
+ if (!ok)
+ *accept = INT_MAX;
+ return *accept >= *require;
+ }
+ } else {
+ *tmpl = expect;
+ *require = *accept = 1;
+ }
+ return true;
+}
+
+void tst_lupdate::doCompare(const QStringList &_actual, const QString &expectedFn, bool err)
+{
+ QFile file(expectedFn);
+ QVERIFY2(file.open(QIODevice::ReadOnly | QIODevice::Text), qPrintable(expectedFn));
+ QStringList expected = QString(file.readAll()).split('\n');
+
+ QStringList actual;
+ actual.reserve(_actual.size());
+ QRegExp niRx(".*:Function '\\w+' is not implemented");
+ foreach (const QString &a, _actual)
+ if (!niRx.exactMatch(a))
+ actual << a;
+
+ int ei = 0, ai = 0, em = expected.size(), am = actual.size();
+ int oei = 0, oai = 0, oem = em, oam = am;
+ int require = 0, accept = 0;
+ QString tmpl;
+ forever {
+ if (!accept) {
+ oei = ei, oai = ai;
+ if (ei == em) {
+ if (ai == am)
+ return;
+ break;
+ }
+ if (!prepareMatch(expected.at(ei++), &tmpl, &require, &accept))
+ QFAIL(qPrintable(QString("Malformed expected %1 at %3:%2")
+ .arg(err ? "output" : "result").arg(ei).arg(expectedFn)));
+ }
+ if (ai == am) {
+ if (require <= 0) {
+ accept = 0;
+ continue;
+ }
+ break;
+ }
+ if (err ? !QRegExp(tmpl).exactMatch(actual.at(ai)) : (actual.at(ai) != tmpl)) {
+ if (require <= 0) {
+ accept = 0;
+ continue;
+ }
+ ei--;
+ require = accept = 0;
+ forever {
+ if (!accept) {
+ oem = em, oam = am;
+ if (ei == em)
+ break;
+ if (!prepareMatch(expected.at(--em), &tmpl, &require, &accept))
+ QFAIL(qPrintable(QString("Malformed expected %1 at %3:%2")
+ .arg(err ? "output" : "result")
+ .arg(em + 1).arg(expectedFn)));
+ }
+ if (ai == am || (err ? !QRegExp(tmpl).exactMatch(actual.at(am - 1)) :
+ (actual.at(am - 1) != tmpl))) {
+ if (require <= 0) {
+ accept = 0;
+ continue;
+ }
+ break;
+ }
+ accept--;
+ require--;
+ am--;
+ }
+ break;
+ }
+ accept--;
+ require--;
+ ai++;
+ }
+ QByteArray diff;
+ for (int j = qMax(0, oai - 3); j < oai; j++)
+ diff += actual.at(j) + '\n';
+ diff += "<<<<<<< got\n";
+ for (int j = oai; j < oam; j++) {
+ diff += actual.at(j) + '\n';
+ if (j >= oai + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += "=========\n";
+ for (int j = oei; j < oem; j++) {
+ diff += expected.at(j) + '\n';
+ if (j >= oei + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += ">>>>>>> expected\n";
+ for (int j = oam; j < qMin(oam + 3, actual.size()); j++)
+ diff += actual.at(j) + '\n';
+ QFAIL(qPrintable((err ? "Output for " : "Result for ") + expectedFn + " does not meet expectations:\n" + diff));
+}
+
+void tst_lupdate::doCompare(const QString &actualFn, const QString &expectedFn, bool err)
+{
+ QFile afile(actualFn);
+ QVERIFY2(afile.open(QIODevice::ReadOnly | QIODevice::Text), qPrintable(actualFn));
+ QStringList actual = QString(afile.readAll()).split('\n');
+
+ doCompare(actual, expectedFn, err);
+}
+
+void tst_lupdate::good_data()
+{
+ QTest::addColumn<QString>("directory");
+
+ QDir parsingDir(m_basePath + "good");
+ QStringList dirs = parsingDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
+
+#ifndef Q_OS_WIN
+ dirs.removeAll(QLatin1String("backslashes"));
+#endif
+
+ foreach (const QString &dir, dirs)
+ QTest::newRow(dir.toLocal8Bit()) << dir;
+}
+
+void tst_lupdate::good()
+{
+ QFETCH(QString, directory);
+
+ QString dir = m_basePath + "good/" + directory;
+
+ qDebug() << "Checking...";
+
+ QString workDir = dir;
+ QStringList generatedtsfiles(QLatin1String("project.ts"));
+ QString lupdatecmd;
+
+ QFile file(dir + "/lupdatecmd");
+ if (file.exists()) {
+ QVERIFY2(file.open(QIODevice::ReadOnly | QIODevice::Text), qPrintable(file.fileName()));
+ while (!file.atEnd()) {
+ QByteArray cmdstring = file.readLine().simplified();
+ if (cmdstring.startsWith('#'))
+ continue;
+ if (cmdstring.startsWith("lupdate")) {
+ cmdstring.remove(0, 8);
+ lupdatecmd.append(cmdstring);
+ break;
+ } else if (cmdstring.startsWith("TRANSLATION:")) {
+ cmdstring.remove(0, 12);
+ generatedtsfiles.clear();
+ foreach (const QByteArray &s, cmdstring.split(' '))
+ if (!s.isEmpty())
+ generatedtsfiles << s;
+ } else if (cmdstring.startsWith("cd ")) {
+ cmdstring.remove(0, 3);
+ workDir = QDir::cleanPath(dir + QLatin1Char('/') + cmdstring);
+ }
+ }
+ file.close();
+ }
+
+ foreach (const QString &ts, generatedtsfiles) {
+ QString genTs = workDir + QLatin1Char('/') + ts;
+ QFile::remove(genTs);
+ QString beforetsfile = dir + QLatin1Char('/') + ts + QLatin1String(".before");
+ if (QFile::exists(beforetsfile))
+ QVERIFY2(QFile::copy(beforetsfile, genTs), qPrintable(beforetsfile));
+ }
+
+ if (lupdatecmd.isEmpty())
+ lupdatecmd = QLatin1String("project.pro");
+ lupdatecmd.prepend("-silent ");
+
+ QProcess proc;
+ proc.setWorkingDirectory(workDir);
+ proc.setProcessChannelMode(QProcess::MergedChannels);
+ proc.start(m_cmdLupdate + ' ' + lupdatecmd, QIODevice::ReadWrite | QIODevice::Text);
+ QVERIFY2(proc.waitForFinished(30000), qPrintable(lupdatecmd));
+ QByteArray output = proc.readAll();
+ QVERIFY2(proc.exitStatus() == QProcess::NormalExit,
+ "\"lupdate " + lupdatecmd.toLatin1() + "\" crashed\n" + output);
+ QVERIFY2(!proc.exitCode(),
+ "\"lupdate " + lupdatecmd.toLatin1() + "\" exited with code " +
+ QByteArray::number(proc.exitCode()) + "\n" + output);
+
+ // If the file expectedoutput.txt exists, compare the
+ // console output with the content of that file
+ QFile outfile(dir + "/expectedoutput.txt");
+ if (outfile.exists()) {
+ QStringList errslist = QString::fromLatin1(output).split(QLatin1Char('\n'));
+ doCompare(errslist, outfile.fileName(), true);
+ if (QTest::currentTestFailed())
+ return;
+ }
+
+ foreach (const QString &ts, generatedtsfiles)
+ doCompare(workDir + QLatin1Char('/') + ts,
+ dir + QLatin1Char('/') + ts + QLatin1String(".result"), false);
+}
+
+#if CHECK_SIMTEXTH
+void tst_lupdate::simtexth()
+{
+ QFETCH(QString, one);
+ QFETCH(QString, two);
+ QFETCH(int, expected);
+
+ int measured = getSimilarityScore(one, two.toLatin1());
+ QCOMPARE(measured, expected);
+}
+
+
+void tst_lupdate::simtexth_data()
+{
+ using namespace QTest;
+
+ addColumn<QString>("one");
+ addColumn<QString>("two");
+ addColumn<int>("expected");
+
+ newRow("00") << "" << "" << 1024;
+ newRow("01") << "a" << "a" << 1024;
+ newRow("02") << "ab" << "ab" << 1024;
+ newRow("03") << "abc" << "abc" << 1024;
+ newRow("04") << "abcd" << "abcd" << 1024;
+}
+#endif
+
+QTEST_MAIN(tst_lupdate)
+#include "tst_lupdate.moc"
diff --git a/tests/auto/qhelpcontentmodel/.gitignore b/tests/auto/qhelpcontentmodel/.gitignore
new file mode 100644
index 000000000..0602f2fb5
--- /dev/null
+++ b/tests/auto/qhelpcontentmodel/.gitignore
@@ -0,0 +1,2 @@
+tst_qhelpcontentmodel
+data/col.qhc
diff --git a/tests/auto/qhelpcontentmodel/data/collection.qhc b/tests/auto/qhelpcontentmodel/data/collection.qhc
new file mode 100644
index 000000000..6fb8abb68
--- /dev/null
+++ b/tests/auto/qhelpcontentmodel/data/collection.qhc
Binary files differ
diff --git a/tests/auto/qhelpcontentmodel/data/qmake-3.3.8.qch b/tests/auto/qhelpcontentmodel/data/qmake-3.3.8.qch
new file mode 100644
index 000000000..a3ca18ad7
--- /dev/null
+++ b/tests/auto/qhelpcontentmodel/data/qmake-3.3.8.qch
Binary files differ
diff --git a/tests/auto/qhelpcontentmodel/data/qmake-4.3.0.qch b/tests/auto/qhelpcontentmodel/data/qmake-4.3.0.qch
new file mode 100644
index 000000000..8f76134e6
--- /dev/null
+++ b/tests/auto/qhelpcontentmodel/data/qmake-4.3.0.qch
Binary files differ
diff --git a/tests/auto/qhelpcontentmodel/data/test.qch b/tests/auto/qhelpcontentmodel/data/test.qch
new file mode 100644
index 000000000..1d6c1a801
--- /dev/null
+++ b/tests/auto/qhelpcontentmodel/data/test.qch
Binary files differ
diff --git a/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro b/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro
new file mode 100644
index 000000000..a9a8ed944
--- /dev/null
+++ b/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro
@@ -0,0 +1,22 @@
+load(qttest_p4)
+SOURCES += tst_qhelpcontentmodel.cpp
+
+CONFIG += help
+
+DEFINES += QT_USE_USING_NAMESPACE
+!contains(QT_BUILD_PARTS, tools): DEFINES += QT_NO_BUILD_TOOLS
+
+wince*: {
+ DEFINES += SRCDIR=\\\"./\\\"
+ QT += network
+ addFiles.files = $$PWD/data/*.*
+ addFiles.path = data
+ clucene.files = $$QT_BUILD_TREE/lib/QtCLucene*.dll
+
+ DEPLOYMENT += addFiles
+ DEPLOYMENT += clucene
+
+ DEPLOYMENT_PLUGIN += qsqlite
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+} \ No newline at end of file
diff --git a/tests/auto/qhelpcontentmodel/tst_qhelpcontentmodel.cpp b/tests/auto/qhelpcontentmodel/tst_qhelpcontentmodel.cpp
new file mode 100644
index 000000000..fc6886add
--- /dev/null
+++ b/tests/auto/qhelpcontentmodel/tst_qhelpcontentmodel.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+
+#ifndef QT_NO_BUILD_TOOLS
+
+#include <QtCore/QThread>
+#include <QtCore/QUrl>
+#include <QtCore/QFileInfo>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpContentWidget>
+
+class SignalWaiter : public QThread
+{
+ Q_OBJECT
+
+public:
+ SignalWaiter();
+ void run();
+
+public slots:
+ void stopWaiting();
+
+private:
+ bool stop;
+};
+
+SignalWaiter::SignalWaiter()
+{
+ stop = false;
+}
+
+void SignalWaiter::run()
+{
+ while (!stop)
+ msleep(500);
+ stop = false;
+}
+
+void SignalWaiter::stopWaiting()
+{
+ stop = true;
+}
+
+
+class tst_QHelpContentModel : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void init();
+
+ void setupContents();
+ void contentItemAt();
+
+private:
+ QString m_colFile;
+};
+
+void tst_QHelpContentModel::init()
+{
+ // defined in profile
+ QString path = QLatin1String(SRCDIR);
+
+ m_colFile = path + QLatin1String("/data/col.qhc");
+ if (QFile::exists(m_colFile))
+ QDir::current().remove(m_colFile);
+ if (!QFile::copy(path + "/data/collection.qhc", m_colFile))
+ QFAIL("Cannot copy file!");
+ QFile f(m_colFile);
+ f.setPermissions(QFile::WriteUser|QFile::ReadUser);
+}
+
+void tst_QHelpContentModel::setupContents()
+{
+ QHelpEngine h(m_colFile, 0);
+ QHelpContentModel *m = h.contentModel();
+ SignalWaiter w;
+ connect(m, SIGNAL(contentsCreated()),
+ &w, SLOT(stopWaiting()));
+ w.start();
+ h.setupData();
+ int i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ QCOMPARE(h.currentFilter(), QString("unfiltered"));
+ QCOMPARE(m->rowCount(), 4);
+
+ w.start();
+ h.setCurrentFilter("Custom Filter 1");
+ i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ QCOMPARE(m->rowCount(), 1);
+}
+
+void tst_QHelpContentModel::contentItemAt()
+{
+ QHelpEngine h(m_colFile, 0);
+ QHelpContentModel *m = h.contentModel();
+ SignalWaiter w;
+ connect(m, SIGNAL(contentsCreated()),
+ &w, SLOT(stopWaiting()));
+ w.start();
+ h.setupData();
+ int i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ QCOMPARE(h.currentFilter(), QString("unfiltered"));
+
+ QModelIndex root = m->index(0, 0);
+ if (!root.isValid())
+ QFAIL("Cannot retrieve root item!");
+ QHelpContentItem *item = m->contentItemAt(root);
+ if (!item)
+ QFAIL("Cannot retrieve content item!");
+ QCOMPARE(item->title(), QString("qmake Manual"));
+
+ item = m->contentItemAt(m->index(4, 0, root));
+ QCOMPARE(item->title(), QString("qmake Concepts"));
+
+ item = m->contentItemAt(m->index(3, 0));
+ QCOMPARE(item->title(), QString("Fancy Manual"));
+
+ w.start();
+ h.setCurrentFilter("Custom Filter 1");
+ i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ item = m->contentItemAt(m->index(0, 0));
+ QCOMPARE(item->title(), QString("Test Manual"));
+}
+
+QTEST_MAIN(tst_QHelpContentModel)
+#include "tst_qhelpcontentmodel.moc"
+
+#else // QT_NO_BUILD_TOOLS
+QTEST_NOOP_MAIN
+#endif
diff --git a/tests/auto/qhelpenginecore/.gitignore b/tests/auto/qhelpenginecore/.gitignore
new file mode 100644
index 000000000..e317dd732
--- /dev/null
+++ b/tests/auto/qhelpenginecore/.gitignore
@@ -0,0 +1,3 @@
+tst_qhelpenginecore
+collectionCopy.qhc
+data/col.qhc
diff --git a/tests/auto/qhelpenginecore/data/collection.qhc b/tests/auto/qhelpenginecore/data/collection.qhc
new file mode 100644
index 000000000..bd2f37c17
--- /dev/null
+++ b/tests/auto/qhelpenginecore/data/collection.qhc
Binary files differ
diff --git a/tests/auto/qhelpenginecore/data/collection1.qhc b/tests/auto/qhelpenginecore/data/collection1.qhc
new file mode 100644
index 000000000..de310ea24
--- /dev/null
+++ b/tests/auto/qhelpenginecore/data/collection1.qhc
Binary files differ
diff --git a/tests/auto/qhelpenginecore/data/linguist-3.3.8.qch b/tests/auto/qhelpenginecore/data/linguist-3.3.8.qch
new file mode 100644
index 000000000..ed9a89c6c
--- /dev/null
+++ b/tests/auto/qhelpenginecore/data/linguist-3.3.8.qch
Binary files differ
diff --git a/tests/auto/qhelpenginecore/data/qmake-3.3.8.qch b/tests/auto/qhelpenginecore/data/qmake-3.3.8.qch
new file mode 100644
index 000000000..0e95c142c
--- /dev/null
+++ b/tests/auto/qhelpenginecore/data/qmake-3.3.8.qch
Binary files differ
diff --git a/tests/auto/qhelpenginecore/data/qmake-4.3.0.qch b/tests/auto/qhelpenginecore/data/qmake-4.3.0.qch
new file mode 100644
index 000000000..337d7a110
--- /dev/null
+++ b/tests/auto/qhelpenginecore/data/qmake-4.3.0.qch
Binary files differ
diff --git a/tests/auto/qhelpenginecore/data/test.html b/tests/auto/qhelpenginecore/data/test.html
new file mode 100644
index 000000000..bf0e5055c
--- /dev/null
+++ b/tests/auto/qhelpenginecore/data/test.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>Test Manual</title>
+ <link href="classic.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/auto/qhelpenginecore/data/test.qch b/tests/auto/qhelpenginecore/data/test.qch
new file mode 100644
index 000000000..06b789a0e
--- /dev/null
+++ b/tests/auto/qhelpenginecore/data/test.qch
Binary files differ
diff --git a/tests/auto/qhelpenginecore/qhelpenginecore.pro b/tests/auto/qhelpenginecore/qhelpenginecore.pro
new file mode 100644
index 000000000..4166fe228
--- /dev/null
+++ b/tests/auto/qhelpenginecore/qhelpenginecore.pro
@@ -0,0 +1,23 @@
+load(qttest_p4)
+SOURCES += tst_qhelpenginecore.cpp
+CONFIG += help
+QT += sql
+
+
+DEFINES += QT_USE_USING_NAMESPACE
+!contains(QT_BUILD_PARTS, tools): DEFINES += QT_NO_BUILD_TOOLS
+
+wince*: {
+ DEFINES += SRCDIR=\\\"./\\\"
+ QT += network
+ addFiles.files = $$PWD/data/*.*
+ addFiles.path = data
+ clucene.files = $$QT_BUILD_TREE/lib/QtCLucene*.dll
+
+ DEPLOYMENT += addFiles
+ DEPLOYMENT += clucene
+
+ DEPLOYMENT_PLUGIN += qsqlite
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
diff --git a/tests/auto/qhelpenginecore/tst_qhelpenginecore.cpp b/tests/auto/qhelpenginecore/tst_qhelpenginecore.cpp
new file mode 100644
index 000000000..8aa55bd2a
--- /dev/null
+++ b/tests/auto/qhelpenginecore/tst_qhelpenginecore.cpp
@@ -0,0 +1,462 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+
+#ifndef QT_NO_BUILD_TOOLS
+
+#include <QtCore/QUrl>
+#include <QtCore/QFileInfo>
+#include <QtSql/QSqlDatabase>
+#include <QtSql/QSqlQuery>
+
+#include <QtHelp/QHelpEngineCore>
+
+class tst_QHelpEngineCore : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void init();
+
+ void setupData();
+ void collectionFile();
+ void setCollectionFile();
+ void copyCollectionFile();
+
+ void namespaceName();
+ void registeredDocumentations();
+ void registerDocumentation();
+ void unregisterDocumentation();
+ void documentationFileName();
+
+ void customFilters();
+ void removeCustomFilter();
+ void addCustomFilter();
+ void filterAttributes();
+ void currentFilter();
+ void setCurrentFilter();
+
+ void filterAttributeSets();
+ void files();
+ void fileData();
+
+ void linksForIdentifier();
+
+ void customValue();
+ void setCustomValue();
+ void removeCustomValue();
+
+ void setAutoSaveFilter();
+
+ void metaData();
+
+private:
+ QString m_path;
+ QString m_colFile;
+};
+
+void tst_QHelpEngineCore::init()
+{
+ // defined in profile
+ m_path = QLatin1String(SRCDIR);
+
+ m_path = QFileInfo(m_path).absoluteFilePath();
+
+ m_colFile = m_path + QLatin1String("/data/col.qhc");
+ if (QFile::exists(m_colFile))
+ QDir::current().remove(m_colFile);
+ if (!QFile::copy(m_path + "/data/collection.qhc", m_colFile))
+ QFAIL("Cannot copy file!");
+ QFile f(m_colFile);
+ f.setPermissions(QFile::WriteUser|QFile::ReadUser);
+}
+
+void tst_QHelpEngineCore::setupData()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+}
+
+void tst_QHelpEngineCore::collectionFile()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.collectionFile(), QFileInfo(m_colFile).absoluteFilePath());
+}
+
+void tst_QHelpEngineCore::setCollectionFile()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.collectionFile(), QFileInfo(m_colFile).absoluteFilePath());
+
+ QString col1File = m_path + QLatin1String("/data/collection1.qhc");
+ help.setCollectionFile(col1File);
+ QCOMPARE(help.collectionFile(), QFileInfo(col1File).absoluteFilePath());
+
+ QStringList docs = help.registeredDocumentations();
+ QCOMPARE(docs.count(), 1);
+ QCOMPARE(docs.first(), QLatin1String("trolltech.com.1-0-0.test"));
+}
+
+void tst_QHelpEngineCore::copyCollectionFile()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.collectionFile(), QFileInfo(m_colFile).absoluteFilePath());
+
+ QString copiedFile = m_path + QLatin1String("/collectionCopy.qhc");
+ if (QFile::exists(copiedFile))
+ QDir::current().remove(copiedFile);
+
+ QCOMPARE(help.copyCollectionFile(copiedFile), true);
+
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "testdb");
+ db.setDatabaseName(copiedFile);
+ if (!db.open()) {
+ QSqlDatabase::removeDatabase("testdb");
+ QFAIL("Created database seems to be corrupt!");
+ }
+ QSqlQuery *m_query = new QSqlQuery(db);
+
+ m_query->exec("SELECT Key, Value FROM SettingsTable");
+ if (m_query->next()) {
+ QCOMPARE(m_query->value(0).toString(), QString("CurrentFilter"));
+ QCOMPARE(m_query->value(1).toString(), QString("unfiltered"));
+ } else {
+ QFAIL("Settingstable is corrupt!");
+ }
+
+ m_query->exec("SELECT NameId, FilterAttributeId FROM FilterTable");
+ int i = 0;
+ while (m_query->next()) {
+ if (i == 3) {
+ QCOMPARE(m_query->value(0).toInt(), 2);
+ QCOMPARE(m_query->value(1).toInt(), 6);
+ }
+ ++i;
+ }
+ QCOMPARE(i, 7);
+ m_query->clear();
+
+ m_query->exec("SELECT Name, FilePath FROM NamespaceTable");
+ i = 0;
+ while (m_query->next()) {
+ if (i == 0) {
+ QCOMPARE(m_query->value(0).toString(), QString("trolltech.com.3-3-8.qmake"));
+ QCOMPARE(m_query->value(1).toString(), QString("data/qmake-3.3.8.qch"));
+ }
+ ++i;
+ }
+ QCOMPARE(i, 3);
+
+ m_query->clear();
+ delete m_query;
+ }
+ QSqlDatabase::removeDatabase("testdb");
+}
+
+void tst_QHelpEngineCore::namespaceName()
+{
+ QCOMPARE(QHelpEngineCore::namespaceName(m_path + "/data/qmake-3.3.8.qch"),
+ QString("trolltech.com.3-3-8.qmake"));
+ QCOMPARE(QHelpEngineCore::namespaceName(m_path + "/data/linguist-3.3.8.qch"),
+ QString("trolltech.com.3-3-8.linguist"));
+}
+
+void tst_QHelpEngineCore::registeredDocumentations()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QStringList docs = help.registeredDocumentations();
+ QCOMPARE(docs.count(), 3);
+ QStringList lst;
+ lst << "trolltech.com.3-3-8.qmake" << "trolltech.com.4-3-0.qmake"
+ << "trolltech.com.1-0-0.test";
+ foreach (QString s, docs)
+ lst.removeAll(s);
+ QCOMPARE(lst.isEmpty(), true);
+}
+
+void tst_QHelpEngineCore::registerDocumentation()
+{
+ if (QFile::exists(m_colFile))
+ QDir::current().remove(m_colFile);
+ {
+ QHelpEngineCore c(m_colFile);
+ QCOMPARE(c.setupData(), true);
+ c.registerDocumentation(m_path + "/data/qmake-3.3.8.qch");
+ QCOMPARE(c.registeredDocumentations().count(), 1);
+ c.registerDocumentation(m_path + "/data/qmake-3.3.8.qch");
+ QCOMPARE(c.registeredDocumentations().count(), 1);
+ c.registerDocumentation(m_path + "/data/linguist-3.3.8.qch");
+ QCOMPARE(c.registeredDocumentations().count(), 2);
+ }
+
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "testdb");
+ db.setDatabaseName(m_colFile);
+ if (!db.open()) {
+ QSqlDatabase::removeDatabase("testdb");
+ QFAIL("Created database seems to be corrupt!");
+ }
+ QSqlQuery query(db);
+ query.exec("SELECT FilePath FROM NamespaceTable WHERE "
+ "Name=\'trolltech.com.3-3-8.linguist\'");
+ if (query.next())
+ QCOMPARE(query.value(0).toString(),
+ QString("linguist-3.3.8.qch"));
+ else
+ QFAIL("Query error!");
+ }
+ QSqlDatabase::removeDatabase("testdb");
+}
+
+void tst_QHelpEngineCore::unregisterDocumentation()
+{
+ QHelpEngineCore c(m_colFile);
+ QCOMPARE(c.setupData(), true);
+ QCOMPARE(c.registeredDocumentations().count(), 3);
+ c.unregisterDocumentation("trolltech.com.3-3-8.qmake");
+ QCOMPARE(c.registeredDocumentations().count(), 2);
+ QCOMPARE(c.unregisterDocumentation("noexisting"), false);
+}
+
+void tst_QHelpEngineCore::documentationFileName()
+{
+ QHelpEngineCore c(m_colFile);
+ QCOMPARE(c.setupData(), true);
+ QCOMPARE(c.documentationFileName(QLatin1String("trolltech.com.3-3-8.qmake")),
+ QString(m_path + "/data/qmake-3.3.8.qch"));
+ QCOMPARE(c.documentationFileName(QLatin1String("trolltech.com.1-0-0.test")),
+ QString(m_path + "/data/test.qch"));
+ QCOMPARE(c.documentationFileName(QLatin1String("trolltech.com.empty")),
+ QString());
+}
+
+void tst_QHelpEngineCore::customFilters()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QStringList custom = help.customFilters();
+ QCOMPARE(custom.count(), 4);
+ QStringList lst;
+ lst << "qmake Manual" << "Custom Filter 1"
+ << "Custom Filter 2" << "unfiltered";
+ foreach (QString s, custom)
+ lst.removeAll(s);
+ QCOMPARE(lst.count(), 0);
+}
+
+void tst_QHelpEngineCore::removeCustomFilter()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ help.removeCustomFilter("Custom Filter 1");
+ QStringList custom = help.customFilters();
+ QCOMPARE(custom.count(), 3);
+ QCOMPARE((bool)custom.contains("Custom Filter 1"), false);
+}
+
+void tst_QHelpEngineCore::addCustomFilter()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ help.addCustomFilter("Qt Tools", QStringList() << "tools" << "qt");
+ QStringList custom = help.customFilters();
+ QCOMPARE(custom.count(), 5);
+ QCOMPARE((bool)custom.contains("Qt Tools"), true);
+}
+
+void tst_QHelpEngineCore::filterAttributes()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QStringList atts = help.filterAttributes("qmake Manual");
+ QCOMPARE(atts.count(), 3);
+ QStringList lst;
+ lst << "qmake" << "tools" << "qt";
+ foreach (QString s, atts)
+ lst.removeAll(s);
+ QCOMPARE(lst.count(), 0);
+}
+
+void tst_QHelpEngineCore::currentFilter()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QCOMPARE(help.currentFilter(), QString("unfiltered"));
+}
+
+void tst_QHelpEngineCore::setCurrentFilter()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QCOMPARE(help.currentFilter(), QString("unfiltered"));
+ help.setCurrentFilter("qmake Manual");
+ QCOMPARE(help.currentFilter(), QString("qmake Manual"));
+ QCOMPARE(help.customValue("CurrentFilter").toString(),
+ QString("qmake Manual"));
+}
+
+void tst_QHelpEngineCore::filterAttributeSets()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QList<QStringList> lst = help.filterAttributeSets("trolltech.com.1-0-0.test");
+ QCOMPARE(lst.count(), 2);
+ QCOMPARE(lst.first().count(), 2);
+ QCOMPARE((bool)lst.first().contains("filter1"), true);
+ QCOMPARE((bool)lst.last().contains("filter2"), true);
+}
+
+void tst_QHelpEngineCore::files()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QList<QUrl> lst = help.files("trolltech.com.4-3-0.qmake",
+ QStringList());
+ QCOMPARE(lst.count(), 16);
+ lst = help.files("trolltech.com.4-3-0.qmake",
+ QStringList(), "png");
+ QCOMPARE(lst.count(), 2);
+ lst = help.files("trolltech.com.4-3-0.qmake",
+ QStringList() << "qt", "html");
+ QCOMPARE(lst.count(), 13);
+ lst = help.files("trolltech.com.4-3-0.qmake",
+ QStringList() << "qt" << "qmake", "html");
+ QCOMPARE(lst.count(), 13);
+ lst = help.files("trolltech.com.4-3-0.qmake",
+ QStringList() << "qt" << "qmake" << "bla", "html");
+ QCOMPARE(lst.count(), 0);
+ lst = help.files("trolltech.com.4-3-0.qmake",
+ QStringList() << "qt" << "qmake", "foo");
+ QCOMPARE(lst.count(), 0);
+
+ foreach (QUrl url, lst)
+ qDebug() << url;
+
+}
+
+void tst_QHelpEngineCore::fileData()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QByteArray ba = help.fileData(QUrl("NotExisting"));
+ QCOMPARE(ba.size(), 0);
+ ba = help.fileData(QUrl("qthelp://trolltech.com.1-0-0.test/testFolder/test.html"));
+ QTextStream s(ba, QIODevice::ReadOnly|QIODevice::Text);
+ QFile f(m_path + "/data/test.html");
+ if (!f.open(QIODevice::ReadOnly|QIODevice::Text))
+ QFAIL("Cannot open original file!");
+ QTextStream ts(&f);
+ QCOMPARE(s.readAll(), ts.readAll());
+}
+
+void tst_QHelpEngineCore::linksForIdentifier()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QMap<QString, QUrl> map;
+ map = help.linksForIdentifier("Test::foo");
+ QCOMPARE(map.contains("Test Manual"), true);
+ QCOMPARE(map.count(), 1);
+ QCOMPARE(map.value("Test Manual"),
+ QUrl("qthelp://trolltech.com.1-0-0.test/testFolder/test.html#foo"));
+
+ help.setCurrentFilter("Custom Filter 2");
+ map = help.linksForIdentifier("People::newton");
+ QCOMPARE(map.isEmpty(), true);
+ map = help.linksForIdentifier("Fancy::foobar");
+ QCOMPARE(map.contains("Fancy"), true);
+ QCOMPARE(map.count(), 1);
+ QCOMPARE(map.value("Fancy"),
+ QUrl("qthelp://trolltech.com.1-0-0.test/testFolder/fancy.html#foobar"));
+}
+
+void tst_QHelpEngineCore::customValue()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QCOMPARE(help.customValue("CurrentFilter").toString(),
+ QString("unfiltered"));
+}
+
+void tst_QHelpEngineCore::setCustomValue()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QCOMPARE(help.setCustomValue("Test", 3), true);
+ QCOMPARE(help.customValue("Test").toInt(), 3);
+ QCOMPARE(help.removeCustomValue("Test"), true);
+ QCOMPARE(help.customValue("Test"), QVariant());
+}
+
+void tst_QHelpEngineCore::removeCustomValue()
+{
+ setCustomValue();
+}
+
+void tst_QHelpEngineCore::setAutoSaveFilter()
+{
+ QHelpEngineCore help(m_colFile, 0);
+ QCOMPARE(help.setupData(), true);
+ QCOMPARE(help.currentFilter(), QString("unfiltered"));
+
+ help.setAutoSaveFilter(false);
+ help.setCurrentFilter("qmake Manual");
+ QCOMPARE(help.currentFilter(), QString("qmake Manual"));
+ QCOMPARE(help.customValue("CurrentFilter").toString(),
+ QString("unfiltered"));
+}
+
+void tst_QHelpEngineCore::metaData()
+{
+ QCOMPARE(QHelpEngineCore::metaData(m_path + "/data/test.qch", "author").toString(),
+ QString("Nokia Corporation and/or its subsidiary(-ies)"));
+ QCOMPARE(QHelpEngineCore::metaData(m_path + "/data/test.qch", "notExisting").isValid(),
+ false);
+}
+
+QTEST_MAIN(tst_QHelpEngineCore)
+#include "tst_qhelpenginecore.moc"
+
+#else // QT_NO_BUILD_TOOLS
+QTEST_NOOP_MAIN
+#endif
diff --git a/tests/auto/qhelpgenerator/.gitignore b/tests/auto/qhelpgenerator/.gitignore
new file mode 100644
index 000000000..5accdd5d2
--- /dev/null
+++ b/tests/auto/qhelpgenerator/.gitignore
@@ -0,0 +1 @@
+tst_qhelpgenerator
diff --git a/tests/auto/qhelpgenerator/data/cars.html b/tests/auto/qhelpgenerator/data/cars.html
new file mode 100644
index 000000000..385723c98
--- /dev/null
+++ b/tests/auto/qhelpgenerator/data/cars.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>Cars</title>
+ <link href="classic.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/auto/qhelpgenerator/data/classic.css b/tests/auto/qhelpgenerator/data/classic.css
new file mode 100644
index 000000000..911354035
--- /dev/null
+++ b/tests/auto/qhelpgenerator/data/classic.css
@@ -0,0 +1,92 @@
+h3.fn,span.fn
+{
+ margin-left: 1cm;
+ text-indent: -1cm;
+}
+
+a:link
+{
+ color: #004faf;
+ text-decoration: none
+}
+
+a:visited
+{
+ color: #672967;
+ text-decoration: none
+}
+
+td.postheader
+{
+ font-family: sans-serif
+}
+
+tr.address
+{
+ font-family: sans-serif
+}
+
+body
+{
+ background: #ffffff;
+ color: black
+}
+
+table tr.odd {
+ background: #f0f0f0;
+ color: black;
+}
+
+table tr.even {
+ background: #e4e4e4;
+ color: black;
+}
+
+table.annotated th {
+ padding: 3px;
+ text-align: left
+}
+
+table.annotated td {
+ padding: 3px;
+}
+
+table tr pre
+{
+ padding-top: none;
+ padding-bottom: none;
+ padding-left: none;
+ padding-right: none;
+ border: none;
+ background: none
+}
+
+tr.qt-style
+{
+ background: #a2c511;
+ color: black
+}
+
+body pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+span.preprocessor, span.preprocessor a
+{
+ color: darkblue;
+}
+
+span.comment
+{
+ color: darkred;
+ font-style: italic
+}
+
+span.string,span.char
+{
+ color: darkgreen;
+}
diff --git a/tests/auto/qhelpgenerator/data/fancy.html b/tests/auto/qhelpgenerator/data/fancy.html
new file mode 100644
index 000000000..7715e4914
--- /dev/null
+++ b/tests/auto/qhelpgenerator/data/fancy.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>Fancy</title>
+ <link href="classic.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/auto/qhelpgenerator/data/people.html b/tests/auto/qhelpgenerator/data/people.html
new file mode 100644
index 000000000..c745dc81f
--- /dev/null
+++ b/tests/auto/qhelpgenerator/data/people.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>People</title>
+ <link href="classic.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/auto/qhelpgenerator/data/sub/about.html b/tests/auto/qhelpgenerator/data/sub/about.html
new file mode 100644
index 000000000..0bc0a3d47
--- /dev/null
+++ b/tests/auto/qhelpgenerator/data/sub/about.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>About</title>
+ <link href="classic.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/auto/qhelpgenerator/data/test.html b/tests/auto/qhelpgenerator/data/test.html
new file mode 100644
index 000000000..bf0e5055c
--- /dev/null
+++ b/tests/auto/qhelpgenerator/data/test.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>Test Manual</title>
+ <link href="classic.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/auto/qhelpgenerator/data/test.qhp b/tests/auto/qhelpgenerator/data/test.qhp
new file mode 100644
index 000000000..2c3f128ec
--- /dev/null
+++ b/tests/auto/qhelpgenerator/data/test.qhp
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<QtHelpProject version="1.0">
+ <metaData name="author" value="Nokia Corporation and/or its subsidiary(-ies)" />
+ <metaData name="language" value="en" />
+ <virtualFolder>testFolder</virtualFolder>
+ <namespace>trolltech.com.1.0.0.test</namespace>
+ <customFilter name="Custom Filter 1">
+ <filterAttribute>test</filterAttribute>
+ <filterAttribute>filter1</filterAttribute>
+ </customFilter>
+ <customFilter name="Custom Filter 2">
+ <filterAttribute>test</filterAttribute>
+ <filterAttribute>filter2</filterAttribute>
+ </customFilter>
+ <filterSection>
+ <filterAttribute>test</filterAttribute>
+ <filterAttribute>filter1</filterAttribute>
+ <toc>
+ <section title="Test Manual" ref="test.html">
+ <section title="Section 1" ref="test.html#section1">
+ </section>
+ <section title="Section 2" ref="test.html#section2">
+ </section>
+ <section title="Section 3" ref="test.html#section3">
+ </section>
+ <section title="People" ref="people.html">
+ </section>
+ <section title="About" ref="./sub/about.html">
+ </section>
+ </section>
+ </toc>
+ <keywords>
+ <keyword name="foo" id="Test::foo" ref="test.html#foo"/>
+ <keyword name="bar" id="Test::bar" ref="test.html#bar"/>
+ <keyword name="bla" id="Test::bla" ref="test.html#bla"/>
+ <keyword name="einstein" id="People::einstein" ref="people.html#einstein"/>
+ <keyword name="newton" id="People::newton" ref="people.html#newton"/>
+ </keywords>
+ <files>
+ <file>classic.css</file>
+ <file>[pt]*.html</file>
+ <file>./sub/abou?.html</file>
+ </files>
+ </filterSection>
+ <filterSection>
+ <filterAttribute>test</filterAttribute>
+ <filterAttribute>filter2</filterAttribute>
+ <toc>
+ <section title="Fancy Manual" ref="fancy.html">
+ <section title="Section 1" ref="fancy.html#section1">
+ </section>
+ <section title="Section 2" ref="fancy.html#section2">
+ </section>
+ <section title="Section 3" ref="fancy.html#section3">
+ </section>
+ <section title="Cars" ref="cars.html">
+ </section>
+ </section>
+ </toc>
+ <keywords>
+ <keyword name="foo" id="Fancy::foo" ref="fancy.html#foo"/>
+ <keyword name="foobar" id="Fancy::foobar" ref="fancy.html#foobar"/>
+ <keyword name="audi" id="Cars::newton" ref="cars.html#audi"/>
+ </keywords>
+ <files>
+ <file>classic.css</file>
+ <file>fancy.html</file>
+ <file>cars.html</file>
+ </files>
+ </filterSection>
+</QtHelpProject>
diff --git a/tests/auto/qhelpgenerator/qhelpgenerator.pro b/tests/auto/qhelpgenerator/qhelpgenerator.pro
new file mode 100644
index 000000000..b4b07dd41
--- /dev/null
+++ b/tests/auto/qhelpgenerator/qhelpgenerator.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+
+SOURCES += tst_qhelpgenerator.cpp
+CONFIG += help
+QT += sql
+
+DEFINES += SRCDIR=\\\"$$PWD\\\"
+DEFINES += QT_USE_USING_NAMESPACE
+!contains(QT_BUILD_PARTS, tools): DEFINES += QT_NO_BUILD_TOOLS
diff --git a/tests/auto/qhelpgenerator/tst_qhelpgenerator.cpp b/tests/auto/qhelpgenerator/tst_qhelpgenerator.cpp
new file mode 100644
index 000000000..bb7d101a9
--- /dev/null
+++ b/tests/auto/qhelpgenerator/tst_qhelpgenerator.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+
+#ifndef QT_NO_BUILD_TOOLS
+
+#include <QtCore/QFileInfo>
+#include <QtSql/QSqlDatabase>
+#include <QtSql/QSqlQuery>
+
+#include <QtHelp/private/qhelpgenerator_p.h>
+#include <QtHelp/private/qhelpprojectdata_p.h>
+
+class tst_QHelpGenerator : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void generateHelp();
+
+private:
+ void checkNamespace();
+ void checkFilters();
+ void checkIndices();
+ void checkFiles();
+ void checkMetaData();
+
+ QString m_outputFile;
+ QSqlQuery *m_query;
+};
+
+void tst_QHelpGenerator::initTestCase()
+{
+ QString path = QLatin1String(SRCDIR);
+ m_outputFile = path + QLatin1String("/data/test.qch");
+ if (QFile::exists(m_outputFile)) {
+ QDir d;
+ if (!d.remove(m_outputFile))
+ QFAIL("Cannot remove old output file!");
+ }
+}
+
+void tst_QHelpGenerator::generateHelp()
+{
+ // defined in profile
+ QString path = QLatin1String(SRCDIR);
+
+ QString inputFile(path + "/data/test.qhp");
+ QHelpProjectData data;
+ if (!data.readData(inputFile))
+ QFAIL("Cannot read qthp file!");
+
+ QHelpGenerator generator;
+ QCOMPARE(generator.generate(&data, m_outputFile), true);
+
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "testdb");
+ db.setDatabaseName(m_outputFile);
+ if (!db.open()) {
+ QSqlDatabase::removeDatabase("testdb");
+ QFAIL("Created database seems to be corrupt!");
+ }
+ m_query = new QSqlQuery(db);
+ checkNamespace();
+ checkFilters();
+ checkIndices();
+ checkFiles();
+ checkMetaData();
+
+ m_query->clear();
+ delete m_query;
+ }
+ QSqlDatabase::removeDatabase("testdb");
+
+ // check if db is still in use...
+ initTestCase();
+}
+
+void tst_QHelpGenerator::checkNamespace()
+{
+ m_query->exec("SELECT Id, Name FROM NamespaceTable");
+ if (m_query->next()
+ && m_query->value(1).toString() == QLatin1String("trolltech.com.1.0.0.test"))
+ return;
+ QFAIL("Namespace Error!");
+}
+
+void tst_QHelpGenerator::checkFilters()
+{
+ m_query->exec("SELECT COUNT(Id) FROM FilterAttributeTable");
+ if (!m_query->next() || m_query->value(0).toInt() != 3)
+ QFAIL("FilterAttribute Error!");
+
+ m_query->exec("SELECT a.Name FROM FilterAttributeTable a, FilterTable b, "
+ "FilterNameTable c WHERE c.Id=b.NameId AND b.FilterAttributeID=a.Id "
+ "AND c.Name=\'Custom Filter 2\'");
+ QStringList lst;
+ while (m_query->next())
+ lst.append(m_query->value(0).toString());
+ if (!lst.contains("test") || !lst.contains("filter2"))
+ QFAIL("FilterAttribute Error!");
+}
+
+void tst_QHelpGenerator::checkIndices()
+{
+ m_query->exec("SELECT a.Name, b.Anchor FROM FileNameTable a, "
+ "IndexTable b, IndexFilterTable c, FilterAttributeTable d "
+ "WHERE a.FileID=b.FileId AND b.Id=c.IndexId "
+ "AND c.FilterAttributeId=d.Id AND d.Name=\'filter1\' AND b.Name=\'foo\'");
+ if (!m_query->next() || m_query->value(0).toString() != QLatin1String("test.html")
+ || m_query->value(1).toString() != QLatin1String("foo"))
+ QFAIL("Index Error!");
+
+ /*
+ m_query->exec("SELECT COUNT(DISTINCT Id) FROM IndexItemTable");
+ if (!m_query->next() || m_query->value(0).toInt() != 7)
+ QFAIL("Index Error!");
+ */
+
+ m_query->exec("SELECT COUNT(a.Id) FROM IndexTable a, "
+ "IndexFilterTable b, FilterAttributeTable c WHERE a.Id=b.IndexId "
+ "AND b.FilterAttributeId=c.Id AND c.Name=\'filter2\'");
+ if (!m_query->next() || m_query->value(0).toInt() != 3)
+ QFAIL("Index Error!");
+}
+
+void tst_QHelpGenerator::checkFiles()
+{
+ m_query->exec("SELECT COUNT(a.FileId) FROM FileNameTable a, FolderTable b "
+ "WHERE a.FolderId=b.Id AND b.Name=\'testFolder\'");
+ if (!m_query->next() || m_query->value(0).toInt() != 6)
+ QFAIL("File Error!");
+
+ QStringList lst;
+ lst << "classic.css" << "test.html" << "people.html" << "sub/about.html";
+ m_query->exec("SELECT a.Name FROM FileNameTable a, FileFilterTable b, "
+ "FilterAttributeTable c WHERE c.Id=b.FilterAttributeId "
+ "AND b.FileId=a.FileID AND c.Name=\'filter1\'");
+ while (m_query->next())
+ lst.removeAll(m_query->value(0).toString());
+ QCOMPARE(lst.count(), 0);
+
+ QMap<int, QStringList> fileAtts;
+ m_query->exec("SELECT a.Id, b.Name FROM FileAttributeSetTable a, "
+ "FilterAttributeTable b WHERE a.FilterAttributeId=b.Id");
+ while (m_query->next()) {
+ int id = m_query->value(0).toInt();
+ if (!fileAtts.contains(id))
+ fileAtts.insert(id, QStringList());
+ fileAtts[id].append(m_query->value(1).toString());
+ }
+ QCOMPARE(fileAtts.count(), 2);
+ QCOMPARE((bool)fileAtts.value(1).contains("test"), true);
+ QCOMPARE((bool)fileAtts.value(1).contains("filter1"), true);
+ QCOMPARE((bool)fileAtts.value(1).contains("filter2"), false);
+ QCOMPARE((bool)fileAtts.value(2).contains("test"), true);
+ QCOMPARE((bool)fileAtts.value(2).contains("filter2"), true);
+}
+
+void tst_QHelpGenerator::checkMetaData()
+{
+ m_query->exec("SELECT COUNT(Value) FROM MetaDataTable");
+ if (!m_query->next())
+ QFAIL("Meta Data Error");
+ QCOMPARE(m_query->value(0).toInt(), 4);
+
+ m_query->exec("SELECT Value FROM MetaDataTable WHERE Name=\'author\'");
+ if (!m_query->next())
+ QFAIL("Meta Data Error");
+ QCOMPARE(m_query->value(0).toString(), QString("Nokia Corporation and/or its subsidiary(-ies)"));
+}
+
+QTEST_MAIN(tst_QHelpGenerator)
+#include "tst_qhelpgenerator.moc"
+
+#else // QT_NO_BUILD_TOOLS
+QTEST_NOOP_MAIN
+#endif
+
diff --git a/tests/auto/qhelpindexmodel/.gitignore b/tests/auto/qhelpindexmodel/.gitignore
new file mode 100644
index 000000000..bd4c0bd6f
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/.gitignore
@@ -0,0 +1,2 @@
+tst_qhelpindexmodel
+data/col.qhc
diff --git a/tests/auto/qhelpindexmodel/data/collection.qhc b/tests/auto/qhelpindexmodel/data/collection.qhc
new file mode 100644
index 000000000..bd2f37c17
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/data/collection.qhc
Binary files differ
diff --git a/tests/auto/qhelpindexmodel/data/collection1.qhc b/tests/auto/qhelpindexmodel/data/collection1.qhc
new file mode 100644
index 000000000..de310ea24
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/data/collection1.qhc
Binary files differ
diff --git a/tests/auto/qhelpindexmodel/data/linguist-3.3.8.qch b/tests/auto/qhelpindexmodel/data/linguist-3.3.8.qch
new file mode 100644
index 000000000..ed9a89c6c
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/data/linguist-3.3.8.qch
Binary files differ
diff --git a/tests/auto/qhelpindexmodel/data/qmake-3.3.8.qch b/tests/auto/qhelpindexmodel/data/qmake-3.3.8.qch
new file mode 100644
index 000000000..0e95c142c
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/data/qmake-3.3.8.qch
Binary files differ
diff --git a/tests/auto/qhelpindexmodel/data/qmake-4.3.0.qch b/tests/auto/qhelpindexmodel/data/qmake-4.3.0.qch
new file mode 100644
index 000000000..337d7a110
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/data/qmake-4.3.0.qch
Binary files differ
diff --git a/tests/auto/qhelpindexmodel/data/test.html b/tests/auto/qhelpindexmodel/data/test.html
new file mode 100644
index 000000000..bf0e5055c
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/data/test.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>Test Manual</title>
+ <link href="classic.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/auto/qhelpindexmodel/data/test.qch b/tests/auto/qhelpindexmodel/data/test.qch
new file mode 100644
index 000000000..4ea9847a6
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/data/test.qch
Binary files differ
diff --git a/tests/auto/qhelpindexmodel/qhelpindexmodel.pro b/tests/auto/qhelpindexmodel/qhelpindexmodel.pro
new file mode 100644
index 000000000..927c2e19e
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/qhelpindexmodel.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+
+SOURCES += tst_qhelpindexmodel.cpp
+CONFIG += help
+QT += sql
+
+DEFINES += SRCDIR=\\\"$$PWD\\\"
+DEFINES += QT_USE_USING_NAMESPACE
+!contains(QT_BUILD_PARTS, tools): DEFINES += QT_NO_BUILD_TOOLS
diff --git a/tests/auto/qhelpindexmodel/tst_qhelpindexmodel.cpp b/tests/auto/qhelpindexmodel/tst_qhelpindexmodel.cpp
new file mode 100644
index 000000000..8a3e8d12e
--- /dev/null
+++ b/tests/auto/qhelpindexmodel/tst_qhelpindexmodel.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+
+#ifndef QT_NO_BUILD_TOOLS
+
+#include <QtCore/QThread>
+#include <QtCore/QUrl>
+#include <QtCore/QFileInfo>
+
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpIndexWidget>
+
+class SignalWaiter : public QThread
+{
+ Q_OBJECT
+
+public:
+ SignalWaiter();
+ void run();
+
+public slots:
+ void stopWaiting();
+
+private:
+ bool stop;
+};
+
+SignalWaiter::SignalWaiter()
+{
+ stop = false;
+}
+
+void SignalWaiter::run()
+{
+ while (!stop)
+ msleep(500);
+ stop = false;
+}
+
+void SignalWaiter::stopWaiting()
+{
+ stop = true;
+}
+
+
+class tst_QHelpIndexModel : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void init();
+
+ void setupIndex();
+ void filter();
+ void linksForIndex();
+
+private:
+ QString m_colFile;
+};
+
+void tst_QHelpIndexModel::init()
+{
+ QString path = QLatin1String(SRCDIR);
+
+ m_colFile = path + QLatin1String("/data/col.qhc");
+ if (QFile::exists(m_colFile))
+ QDir::current().remove(m_colFile);
+ if (!QFile::copy(path + "/data/collection.qhc", m_colFile))
+ QFAIL("Cannot copy file!");
+ QFile f(m_colFile);
+ f.setPermissions(QFile::WriteUser|QFile::ReadUser);
+}
+
+void tst_QHelpIndexModel::setupIndex()
+{
+ QHelpEngine h(m_colFile, 0);
+ QHelpIndexModel *m = h.indexModel();
+ SignalWaiter w;
+ connect(m, SIGNAL(indexCreated()),
+ &w, SLOT(stopWaiting()));
+ w.start();
+ h.setupData();
+ int i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ QCOMPARE(h.currentFilter(), QString("unfiltered"));
+ QCOMPARE(m->stringList().count(), 19);
+
+ w.start();
+ h.setCurrentFilter("Custom Filter 1");
+ i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ QStringList lst;
+ lst << "foo" << "bar" << "bla" << "einstein" << "newton";
+ QCOMPARE(m->stringList().count(), 5);
+ foreach (QString s, m->stringList())
+ lst.removeAll(s);
+ QCOMPARE(lst.isEmpty(), true);
+}
+
+void tst_QHelpIndexModel::filter()
+{
+ QHelpEngine h(m_colFile, 0);
+ QHelpIndexModel *m = h.indexModel();
+ SignalWaiter w;
+ connect(m, SIGNAL(indexCreated()),
+ &w, SLOT(stopWaiting()));
+ w.start();
+ h.setupData();
+ int i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ QCOMPARE(h.currentFilter(), QString("unfiltered"));
+ QCOMPARE(m->stringList().count(), 19);
+
+ m->filter("foo");
+ QCOMPARE(m->stringList().count(), 2);
+
+ m->filter("fo");
+ QCOMPARE(m->stringList().count(), 3);
+
+ m->filter("qmake");
+ QCOMPARE(m->stringList().count(), 11);
+}
+
+void tst_QHelpIndexModel::linksForIndex()
+{
+ QHelpEngine h(m_colFile, 0);
+ QHelpIndexModel *m = h.indexModel();
+ SignalWaiter w;
+ connect(m, SIGNAL(indexCreated()),
+ &w, SLOT(stopWaiting()));
+ w.start();
+ h.setupData();
+ int i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ QCOMPARE(h.currentFilter(), QString("unfiltered"));
+ QMap<QString, QUrl> map;
+ map = m->linksForKeyword("foo");
+ QCOMPARE(map.count(), 2);
+ QCOMPARE(map.contains("Test Manual"), true);
+ QCOMPARE(map.value("Test Manual"),
+ QUrl("qthelp://trolltech.com.1-0-0.test/testFolder/test.html#foo"));
+
+ QCOMPARE(map.contains("Fancy"), true);
+ QCOMPARE(map.value("Fancy"),
+ QUrl("qthelp://trolltech.com.1-0-0.test/testFolder/fancy.html#foo"));
+
+ map = m->linksForKeyword("foobar");
+ QCOMPARE(map.count(), 1);
+ QCOMPARE(map.contains("Fancy"), true);
+
+ map = m->linksForKeyword("notexisting");
+ QCOMPARE(map.count(), 0);
+
+ w.start();
+ h.setCurrentFilter("Custom Filter 1");
+ i = 0;
+ while (w.isRunning() && i++ < 10)
+ QTest::qWait(500);
+
+ map = m->linksForKeyword("foo");
+ QCOMPARE(map.count(), 1);
+ QCOMPARE(map.contains("Test Manual"), true);
+ QCOMPARE(map.value("Test Manual"),
+ QUrl("qthelp://trolltech.com.1-0-0.test/testFolder/test.html#foo"));
+}
+
+QTEST_MAIN(tst_QHelpIndexModel)
+#include "tst_qhelpindexmodel.moc"
+
+#else // QT_NO_BUILD_TOOLS
+QTEST_NOOP_MAIN
+#endif
diff --git a/tests/auto/qhelpprojectdata/.gitignore b/tests/auto/qhelpprojectdata/.gitignore
new file mode 100644
index 000000000..5296fc660
--- /dev/null
+++ b/tests/auto/qhelpprojectdata/.gitignore
@@ -0,0 +1 @@
+tst_qhelpprojectdata
diff --git a/tests/auto/qhelpprojectdata/data/test.qhp b/tests/auto/qhelpprojectdata/data/test.qhp
new file mode 100644
index 000000000..1e9074a15
--- /dev/null
+++ b/tests/auto/qhelpprojectdata/data/test.qhp
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<QtHelpProject version="1.0">
+ <metaData name="author" value="Nokia Corporation and/or its subsidiary(-ies)" />
+ <metaData name="language" value="en" />
+ <virtualFolder>testFolder</virtualFolder>
+ <namespace>trolltech.com.1.0.0.test</namespace>
+ <customFilter name="Custom Filter 1">
+ <filterAttribute>test</filterAttribute>
+ <filterAttribute>filter1</filterAttribute>
+ </customFilter>
+ <customFilter name="Custom Filter 2">
+ <filterAttribute>test</filterAttribute>
+ <filterAttribute>filter2</filterAttribute>
+ </customFilter>
+ <filterSection>
+ <filterAttribute>test</filterAttribute>
+ <filterAttribute>filter1</filterAttribute>
+ <toc>
+ <section title="Test Manual" ref="test.html">
+ <section title="Section 1" ref="test.html#section1">
+ </section>
+ <section title="Section 2" ref="test.html#section2">
+ </section>
+ <section title="Section 3" ref="test.html#section3">
+ </section>
+ <section title="People" ref="people.html">
+ </section>
+ <section title="About" ref="./sub/about.html">
+ </section>
+ </section>
+ </toc>
+ <keywords>
+ <keyword name="foo" id="Test::foo" ref="test.html#foo"/>
+ <keyword name="bar" id="Test::bar" ref="test.html#bar"/>
+ <keyword name="bla" id="Test::bla" ref="test.html#bla"/>
+ <keyword name="einstein" id="People::einstein" ref="people.html#einstein"/>
+ <keyword name="newton" id="People::newton" ref="people.html#newton"/>
+ </keywords>
+ <files>
+ <file>classic.css</file>
+ <file>test.html</file>
+ <file>people.html</file>
+ <file>./sub/about.html</file>
+ </files>
+ </filterSection>
+ <filterSection>
+ <filterAttribute>test</filterAttribute>
+ <filterAttribute>filter2</filterAttribute>
+ <toc>
+ <section title="Fancy Manual" ref="fancy.html">
+ <section title="Section 1" ref="fancy.html#section1">
+ </section>
+ <section title="Section 2" ref="fancy.html#section2">
+ </section>
+ <section title="Section 3" ref="fancy.html#section3">
+ </section>
+ <section title="Cars" ref="cars.html">
+ </section>
+ </section>
+ </toc>
+ <keywords>
+ <keyword name="foo" id="Fancy::foo" ref="fancy.html#foo"/>
+ <keyword name="foobar" id="Fancy::foobar" ref="fancy.html#foobar"/>
+ <keyword name="audi" id="Cars::newton" ref="cars.html#audi"/>
+ </keywords>
+ <files>
+ <file>classic.css</file>
+ <file>fancy.html</file>
+ <file>cars.html</file>
+ </files>
+ </filterSection>
+</QtHelpProject>
diff --git a/tests/auto/qhelpprojectdata/qhelpprojectdata.pro b/tests/auto/qhelpprojectdata/qhelpprojectdata.pro
new file mode 100644
index 000000000..92dc620e1
--- /dev/null
+++ b/tests/auto/qhelpprojectdata/qhelpprojectdata.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+
+SOURCES += tst_qhelpprojectdata.cpp
+CONFIG += help
+
+DEFINES += SRCDIR=\\\"$$PWD\\\"
+DEFINES += QT_USE_USING_NAMESPACE
+!contains(QT_BUILD_PARTS, tools): DEFINES += QT_NO_BUILD_TOOLS
+
diff --git a/tests/auto/qhelpprojectdata/tst_qhelpprojectdata.cpp b/tests/auto/qhelpprojectdata/tst_qhelpprojectdata.cpp
new file mode 100644
index 000000000..03d1842fb
--- /dev/null
+++ b/tests/auto/qhelpprojectdata/tst_qhelpprojectdata.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+
+#ifndef QT_NO_BUILD_TOOLS
+
+#include <QtCore/QFileInfo>
+
+#include <QtHelp/private/qhelpprojectdata_p.h>
+
+class tst_QHelpProjectData : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+
+ void readData();
+ void namespaceName();
+ void virtualFolder();
+ void customFilters();
+ void filterSections();
+ void metaData();
+ void rootPath();
+
+private:
+ QString m_inputFile;
+};
+
+void tst_QHelpProjectData::initTestCase()
+{
+ const QString path = QLatin1String(SRCDIR);
+ m_inputFile = path + QLatin1String("/data/test.qhp");
+}
+
+void tst_QHelpProjectData::readData()
+{
+ QHelpProjectData data;
+ if (!data.readData(m_inputFile))
+ QFAIL("Cannot parse qhp file!");
+}
+
+void tst_QHelpProjectData::namespaceName()
+{
+ QHelpProjectData data;
+ if (!data.readData(m_inputFile))
+ QFAIL("Cannot read qhp file!");
+ QCOMPARE(data.namespaceName(), QString("trolltech.com.1.0.0.test"));
+}
+
+void tst_QHelpProjectData::virtualFolder()
+{
+ QHelpProjectData data;
+ if (!data.readData(m_inputFile))
+ QFAIL("Cannot read qhp file!");
+ QCOMPARE(data.virtualFolder(), QString("testFolder"));
+}
+
+void tst_QHelpProjectData::customFilters()
+{
+ QHelpProjectData data;
+ if (!data.readData(m_inputFile))
+ QFAIL("Cannot read qhp file!");
+
+ QList<QHelpDataCustomFilter> filters = data.customFilters();
+ QCOMPARE(filters.count(), 2);
+
+ foreach (QHelpDataCustomFilter f, filters) {
+ if (f.name == QLatin1String("Custom Filter 1")) {
+ foreach (QString id, f.filterAttributes) {
+ if (id != QLatin1String("test")
+ && id != QLatin1String("filter1"))
+ QFAIL("Wrong filter attribute!");
+ }
+ } else if (f.name == QLatin1String("Custom Filter 2")) {
+ foreach (QString id, f.filterAttributes) {
+ if (id != QLatin1String("test")
+ && id != QLatin1String("filter2"))
+ QFAIL("Wrong filter attribute!");
+ }
+ } else {
+ QFAIL("Unexpected filter name!");
+ }
+ }
+}
+
+void tst_QHelpProjectData::filterSections()
+{
+ QHelpProjectData data;
+ if (!data.readData(m_inputFile))
+ QFAIL("Cannot read qhp file!");
+
+ QList<QHelpDataFilterSection> sections = data.filterSections();
+ QCOMPARE(sections.count(), 2);
+
+ foreach (QHelpDataFilterSection s, sections) {
+ if (s.filterAttributes().contains("filter1")) {
+ QCOMPARE(s.indices().count(), 5);
+ foreach (QHelpDataIndexItem idx, s.indices()) {
+ if (idx.name == QLatin1String("foo")) {
+ QCOMPARE(idx.identifier, QString("Test::foo"));
+ } else if (idx.name == QLatin1String("bar")) {
+ QCOMPARE(idx.reference, QString("test.html#bar"));
+ } else if (idx.name == QLatin1String("bla")) {
+ QCOMPARE(idx.identifier, QString("Test::bla"));
+ } else if (idx.name == QLatin1String("einstein")) {
+ QCOMPARE(idx.reference, QString("people.html#einstein"));
+ } else if (idx.name == QLatin1String("newton")) {
+ QCOMPARE(idx.identifier, QString("People::newton"));
+ } else {
+ QFAIL("Unexpected index!");
+ }
+ }
+ QCOMPARE(s.contents().count(), 1);
+ QCOMPARE(s.contents().first()->children().count(), 5);
+ } else if (s.filterAttributes().contains("filter2")) {
+ QCOMPARE(s.contents().count(), 1);
+ QStringList lst;
+ lst << "classic.css" << "fancy.html" << "cars.html";
+ foreach (QString f, s.files())
+ lst.removeAll(f);
+ QCOMPARE(lst.count(), 0);
+ } else {
+ QFAIL("Unexpected filter attribute!");
+ }
+ }
+}
+
+void tst_QHelpProjectData::metaData()
+{
+ QHelpProjectData data;
+ if (!data.readData(m_inputFile))
+ QFAIL("Cannot read qhp file!");
+
+ QCOMPARE(data.metaData().count(), 2);
+ QCOMPARE(data.metaData().value("author").toString(),
+ QString("Nokia Corporation and/or its subsidiary(-ies)"));
+}
+
+void tst_QHelpProjectData::rootPath()
+{
+ QHelpProjectData data;
+ if (!data.readData(m_inputFile))
+ QFAIL("Cannot read qhp file!");
+
+ QFileInfo fi(m_inputFile);
+ QCOMPARE(data.rootPath(), fi.absolutePath());
+}
+
+QTEST_MAIN(tst_QHelpProjectData)
+#include "tst_qhelpprojectdata.moc"
+
+#else // QT_NO_BUILD_TOOLS
+QTEST_NOOP_MAIN
+#endif
diff --git a/tests/global/.gitignore b/tests/global/.gitignore
new file mode 100644
index 000000000..1e49c6005
--- /dev/null
+++ b/tests/global/.gitignore
@@ -0,0 +1,2 @@
+Makefile
+global.pro
diff --git a/tests/tests.pro b/tests/tests.pro
new file mode 100644
index 000000000..85e4f3a53
--- /dev/null
+++ b/tests/tests.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += auto